aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins')
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp2764
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h176
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp3270
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h185
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp1573
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h188
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp2995
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.h176
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp3222
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h183
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp1630
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h197
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp1432
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.h204
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp1523
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.h136
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp1877
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h199
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp1631
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h190
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp1640
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h192
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp1172
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h131
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp2798
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h192
-rw-r--r--source/Plugins/CMakeLists.txt1
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp2104
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h231
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp2612
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h550
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp1035
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h229
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp572
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h412
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt1
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp1914
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h430
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp522
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h117
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp2035
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h303
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp142
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h129
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp979
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h399
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp1145
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h248
-rw-r--r--source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp230
-rw-r--r--source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h76
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp102
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h35
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTDumper.cpp162
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTDumper.h33
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp795
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h357
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp277
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h246
-rw-r--r--source/Plugins/ExpressionParser/Clang/CMakeLists.txt7
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp3145
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.h934
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h58
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp3649
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h1225
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h77
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp1638
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h254
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp81
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h359
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp319
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h195
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp1217
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h197
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp106
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h127
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp1093
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.h302
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp209
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h152
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.cpp3298
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.h1221
-rw-r--r--source/Plugins/ExpressionParser/Go/GoAST.h4405
-rw-r--r--source/Plugins/ExpressionParser/Go/GoLexer.cpp650
-rw-r--r--source/Plugins/ExpressionParser/Go/GoLexer.h322
-rw-r--r--source/Plugins/ExpressionParser/Go/GoParser.cpp1717
-rw-r--r--source/Plugins/ExpressionParser/Go/GoParser.h272
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.cpp1151
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.h108
-rw-r--r--source/Plugins/ExpressionParser/Go/gen_go_ast.py150
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp22758
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.h1695
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.cpp669
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.h130
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp1896
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h418
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp4990
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h342
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp3811
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h284
-rw-r--r--source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp494
-rw-r--r--source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h117
-rw-r--r--source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp1395
-rw-r--r--source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h152
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp753
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.h107
-rw-r--r--source/Plugins/Language/CMakeLists.txt1
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp316
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.h13
-rw-r--r--source/Plugins/Language/CPlusPlus/CMakeLists.txt2
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp1755
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h282
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp353
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.h47
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp1083
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.h250
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp154
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxAtomic.h20
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp179
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxList.cpp651
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp772
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp258
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVector.cpp206
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcpp.cpp695
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcpp.h48
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp109
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp151
-rw-r--r--source/Plugins/Language/Go/GoFormatterFunctions.cpp247
-rw-r--r--source/Plugins/Language/Go/GoFormatterFunctions.h12
-rw-r--r--source/Plugins/Language/Go/GoLanguage.cpp164
-rw-r--r--source/Plugins/Language/Go/GoLanguage.h51
-rw-r--r--source/Plugins/Language/Java/JavaFormatterFunctions.cpp281
-rw-r--r--source/Plugins/Language/Java/JavaFormatterFunctions.h19
-rw-r--r--source/Plugins/Language/Java/JavaLanguage.cpp114
-rw-r--r--source/Plugins/Language/Java/JavaLanguage.h38
-rw-r--r--source/Plugins/Language/OCaml/CMakeLists.txt4
-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.cpp539
-rw-r--r--source/Plugins/Language/ObjC/CF.h27
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.cpp1688
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.h176
-rw-r--r--source/Plugins/Language/ObjC/CoreMedia.cpp142
-rw-r--r--source/Plugins/Language/ObjC/CoreMedia.h14
-rw-r--r--source/Plugins/Language/ObjC/NSArray.cpp1295
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.cpp1337
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.h97
-rw-r--r--source/Plugins/Language/ObjC/NSError.cpp347
-rw-r--r--source/Plugins/Language/ObjC/NSException.cpp341
-rw-r--r--source/Plugins/Language/ObjC/NSIndexPath.cpp610
-rw-r--r--source/Plugins/Language/ObjC/NSSet.cpp1086
-rw-r--r--source/Plugins/Language/ObjC/NSSet.h38
-rw-r--r--source/Plugins/Language/ObjC/NSString.cpp716
-rw-r--r--source/Plugins/Language/ObjC/NSString.h44
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.cpp1751
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.h312
-rw-r--r--source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp56
-rw-r--r--source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h68
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp975
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h192
-rw-r--r--source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp310
-rw-r--r--source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h133
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp237
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h80
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp1010
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h665
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp1175
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h46
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp826
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h217
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp711
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h308
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp3872
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h629
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp1648
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h295
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp659
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h112
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp334
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h118
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt11
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp200
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h57
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp8059
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h705
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp162
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h18
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp297
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h23
-rw-r--r--source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp276
-rw-r--r--source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h57
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp945
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h355
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp421
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h141
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.cpp607
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.h645
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp5918
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h766
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp429
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.h201
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp11217
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h396
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp1748
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h540
-rw-r--r--source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp63
-rw-r--r--source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h9
-rw-r--r--source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp825
-rw-r--r--source/Plugins/OperatingSystem/Go/OperatingSystemGo.h83
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp678
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.h139
-rw-r--r--source/Plugins/Platform/Android/AdbClient.cpp998
-rw-r--r--source/Plugins/Platform/Android/AdbClient.h170
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.cpp604
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.h152
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp371
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h50
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp1031
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h192
-rw-r--r--source/Plugins/Platform/Kalimba/PlatformKalimba.cpp433
-rw-r--r--source/Plugins/Platform/Kalimba/PlatformKalimba.h99
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.cpp1148
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.h158
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp376
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h95
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp659
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h168
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp662
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h167
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.cpp3237
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.h256
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp1567
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h334
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp544
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformMacOSX.h147
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp1652
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h248
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp1758
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h250
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp1562
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h256
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp729
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h163
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h474
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm1163
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp948
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.h187
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp1578
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.h349
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.cpp1036
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.h177
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp1619
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h403
-rw-r--r--source/Plugins/Process/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Darwin/CFBundle.cpp79
-rw-r--r--source/Plugins/Process/Darwin/CFBundle.h38
-rw-r--r--source/Plugins/Process/Darwin/CFString.cpp163
-rw-r--r--source/Plugins/Process/Darwin/CFString.h43
-rw-r--r--source/Plugins/Process/Darwin/CFUtils.h78
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp653
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.h48
-rw-r--r--source/Plugins/Process/Darwin/LaunchFlavor.h33
-rw-r--r--source/Plugins/Process/Darwin/MachException.cpp543
-rw-r--r--source/Plugins/Process/Darwin/MachException.h140
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.cpp1576
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.h384
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadDarwin.cpp284
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadDarwin.h178
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp698
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadListDarwin.h139
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp1089
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.h163
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp69
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.h68
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp1476
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.h286
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp2144
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h460
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h73
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp428
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h89
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp423
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h90
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp413
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h90
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp452
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h102
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp1037
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h93
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp4619
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h297
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp315
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.h105
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp1626
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h219
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp1635
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h220
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp2144
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h166
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp1050
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h131
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp2096
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h191
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp758
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.h145
-rw-r--r--source/Plugins/Process/Linux/ProcFileReader.cpp139
-rw-r--r--source/Plugins/Process/Linux/ProcFileReader.h24
-rw-r--r--source/Plugins/Process/Linux/Procfs.h14
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.cpp249
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.h35
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp2403
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h547
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp1834
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h417
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp302
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h55
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp224
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h53
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp227
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h56
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp170
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h48
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp171
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h49
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp268
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h101
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.cpp577
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.h74
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.cpp103
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.h299
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp311
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIXLog.h169
-rw-r--r--source/Plugins/Process/Utility/ARMDefines.h255
-rw-r--r--source/Plugins/Process/Utility/ARMUtils.h567
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp1379
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.h115
-rw-r--r--source/Plugins/Process/Utility/FreeBSDSignals.cpp146
-rw-r--r--source/Plugins/Process/Utility/FreeBSDSignals.h8
-rw-r--r--source/Plugins/Process/Utility/GDBRemoteSignals.cpp16
-rw-r--r--source/Plugins/Process/Utility/GDBRemoteSignals.h10
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.cpp106
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.h158
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.cpp86
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h31
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp386
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.h8
-rw-r--r--source/Plugins/Process/Utility/InstructionUtils.h138
-rw-r--r--source/Plugins/Process/Utility/LinuxSignals.cpp153
-rw-r--r--source/Plugins/Process/Utility/LinuxSignals.h8
-rw-r--r--source/Plugins/Process/Utility/MipsLinuxSignals.cpp156
-rw-r--r--source/Plugins/Process/Utility/MipsLinuxSignals.h11
-rw-r--r--source/Plugins/Process/Utility/NetBSDSignals.cpp22
-rw-r--r--source/Plugins/Process/Utility/NetBSDSignals.h8
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp2654
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.h447
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp1673
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h428
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp1582
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.h393
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp1756
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h434
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDummy.cpp148
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDummy.h76
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp100
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h98
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp86
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h78
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp102
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h15
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp120
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h16
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp406
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h55
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp222
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h20
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.cpp151
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.h80
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp3704
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.h437
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp100
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm.h99
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp89
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm64.h80
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp200
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.h24
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp62
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips.h23
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp139
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips64.h29
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp95
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_s390x.h29
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp304
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h31
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp252
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h59
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.cpp72
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.h49
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.cpp57
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.h45
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp60
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.h48
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.cpp204
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.h107
-rw-r--r--source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp570
-rw-r--r--source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h20
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp385
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h158
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp376
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h157
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp265
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h83
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp368
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h330
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp291
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h111
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp1032
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h323
-rw-r--r--source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp390
-rw-r--r--source/Plugins/Process/Utility/RegisterContextThreadMemory.h163
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_mips.h702
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_powerpc.h219
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_s390x.h148
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_x86.h553
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoInterface.h99
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp99
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h70
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm.h2027
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm64.h956
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_i386.h385
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips.h59
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips64.h198
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_powerpc.h329
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_s390x.h93
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_x86_64.h728
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp1019
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.h71
-rw-r--r--source/Plugins/Process/Utility/ThreadMemory.cpp171
-rw-r--r--source/Plugins/Process/Utility/ThreadMemory.h201
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp879
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.h248
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp443
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h68
-rw-r--r--source/Plugins/Process/Utility/lldb-arm-register-enums.h363
-rw-r--r--source/Plugins/Process/Utility/lldb-arm64-register-enums.h397
-rw-r--r--source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h106
-rw-r--r--source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h522
-rw-r--r--source/Plugins/Process/Utility/lldb-s390x-register-enums.h139
-rw-r--r--source/Plugins/Process/Utility/lldb-x86-register-enums.h558
-rw-r--r--source/Plugins/Process/Windows/Common/CMakeLists.txt4
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.cpp549
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.h106
-rw-r--r--source/Plugins/Process/Windows/Common/ExceptionRecord.h105
-rw-r--r--source/Plugins/Process/Windows/Common/ForwardDecl.h (renamed from source/Plugins/Process/Windows/Live/ForwardDecl.h)19
-rw-r--r--source/Plugins/Process/Windows/Common/IDebugDelegate.h (renamed from source/Plugins/Process/Windows/Live/IDebugDelegate.h)30
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp73
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.h (renamed from source/Plugins/Process/Windows/Live/LocalDebugDelegate.h)51
-rw-r--r--source/Plugins/Process/Windows/Common/NtStructures.h23
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.cpp1067
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.h117
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp260
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.h151
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp168
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.h64
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp143
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.h53
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp437
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h40
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp361
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h45
-rw-r--r--source/Plugins/Process/Windows/Live/CMakeLists.txt24
-rw-r--r--source/Plugins/Process/Windows/Live/DebuggerThread.cpp549
-rw-r--r--source/Plugins/Process/Windows/Live/DebuggerThread.h100
-rw-r--r--source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp91
-rw-r--r--source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp1069
-rw-r--r--source/Plugins/Process/Windows/Live/ProcessWindowsLive.h125
-rw-r--r--source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp147
-rw-r--r--source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h55
-rw-r--r--source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp171
-rw-r--r--source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h40
-rw-r--r--source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp100
-rw-r--r--source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h36
-rw-r--r--source/Plugins/Process/Windows/MiniDump/CMakeLists.txt21
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp710
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h104
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp104
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h49
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp47
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h36
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp47
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h36
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp1077
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.h229
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp102
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h55
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp102
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h55
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp102
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h55
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp169
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h70
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp138
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h54
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp127
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h51
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp496
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h296
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt1
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp376
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h144
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp2469
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h538
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp7509
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h1188
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp154
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h61
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp2074
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h205
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp5426
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h364
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp896
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h128
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp1926
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h181
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp9096
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h711
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp342
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h58
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp569
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.h154
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp1009
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.h258
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp139
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.h87
-rw-r--r--source/Plugins/Process/minidump/CMakeLists.txt10
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.cpp458
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h102
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.cpp235
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.h470
-rw-r--r--source/Plugins/Process/minidump/NtStructures.h37
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.cpp301
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h105
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp99
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h138
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp113
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h183
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.cpp114
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.h52
-rw-r--r--source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp80
-rw-r--r--source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h55
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp1661
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h721
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp268
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h55
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp5618
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h1058
-rw-r--r--source/Plugins/ScriptInterpreter/Python/lldb-python.h14
-rw-r--r--source/Plugins/StructuredData/CMakeLists.txt2
-rw-r--r--source/Plugins/StructuredData/DarwinLog/CMakeLists.txt5
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp2018
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h138
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt1
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.cpp113
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.h60
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParser.h45
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp7609
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h246
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp1391
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h88
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp932
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h93
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp209
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h60
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp139
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h101
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp108
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAttribute.h106
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp2003
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h440
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp784
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h350
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp34
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h36
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp19
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h31
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp209
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h84
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp472
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h100
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp204
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h108
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp942
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h116
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp3300
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h629
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp1903
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h398
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp43
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h17
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp179
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h47
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp187
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h60
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp436
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h32
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp234
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h123
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp222
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h38
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp152
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h143
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp940
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.h126
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp1067
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h154
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp1252
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h350
-rw-r--r--source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp350
-rw-r--r--source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h89
-rw-r--r--source/Plugins/SymbolFile/DWARF/NameToDIE.cpp102
-rw-r--r--source/Plugins/SymbolFile/DWARF/NameToDIE.h51
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp7823
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h890
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp2577
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h713
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp149
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h74
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp118
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h182
-rw-r--r--source/Plugins/SymbolFile/PDB/CMakeLists.txt2
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp367
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.h30
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp1167
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h244
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp445
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h142
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp249
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h52
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp407
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h55
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp519
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h134
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp523
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h141
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp508
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h126
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp523
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h135
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp1681
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h506
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp1181
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h292
-rw-r--r--source/Plugins/UnwindAssembly/x86/CMakeLists.txt1
-rw-r--r--source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp1667
-rw-r--r--source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h101
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp1203
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h181
656 files changed, 206666 insertions, 200852 deletions
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index ea906f613890..969c7d3c071e 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -32,710 +32,1831 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
-#include "Plugins/Process/Utility/ARMDefines.h"
using namespace lldb;
using namespace lldb_private;
-static RegisterInfo g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
- // ========== ======= == === ============= ============ ======================= =================== =========================== ======================= ====================== ========== ===============
- { "r0", "arg1", 4, 0, eEncodingUint , eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r1", "arg2", 4, 0, eEncodingUint , eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r2", "arg3", 4, 0, eEncodingUint , eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r3", "arg4", 4, 0, eEncodingUint , eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r4", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r5", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r6", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r7", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "sp", "r13", 4, 0, eEncodingUint , eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "lr", "r14", 4, 0, eEncodingUint , eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "pc", "r15", 4, 0, eEncodingUint , eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fpscr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_usr", "sp_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_usr", "lr_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_fiq", "sp_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_fiq", "lr_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_irq", "sp_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_irq", "lr_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_abt", "sp_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_abt", "lr_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_und", "sp_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_und", "lr_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_svc", "sp_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_svc", "lr_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
+ // DWARF GENERIC PROCESS PLUGIN
+ // LLDB NATIVE
+ // ========== ======= == === ============= ============
+ // ======================= =================== ===========================
+ // ======================= ======================
+ {"r0",
+ "arg1",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ "arg2",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ "arg3",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ "arg4",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "r13",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r14",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "r15",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s0",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s1",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s2",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s3",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s4",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s5",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s6",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s7",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s8",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s9",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s10",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s11",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s12",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s13",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s14",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s15",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s16",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s17",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s18",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s19",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s20",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s21",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s22",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s23",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s24",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s25",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s26",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s27",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s28",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s29",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s30",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s31",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpscr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d0",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d1",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d2",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d3",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d4",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d5",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d6",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d7",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d8",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d9",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d16",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d17",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d18",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d19",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d20",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d21",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d22",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d23",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d24",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d25",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d26",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d27",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d28",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d29",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d30",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d31",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_usr",
+ "sp_usr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_usr",
+ "lr_usr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_fiq",
+ "sp_fiq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_fiq",
+ "lr_fiq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_irq",
+ "sp_irq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_irq",
+ "lr_irq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_abt",
+ "sp_abt",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_abt",
+ "lr_abt",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_und",
+ "sp_und",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_und",
+ "lr_und",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_svc",
+ "sp_svc",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_svc",
+ "lr_svc",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABIMacOSX_arm::GetRegisterInfoArray (uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABIMacOSX_arm::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABIMacOSX_arm::GetRedZoneSize () const
-{
- return 0;
-}
+size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABIMacOSX_arm::CreateInstance (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);
- return g_abi_sp;
- }
+ABIMacOSX_arm::CreateInstance(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);
+ return g_abi_sp;
}
+ }
- return ABISP();
+ return ABISP();
}
-bool
-ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t function_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
-
- const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
-
- RegisterValue reg_value;
-
- const char *reg_names[] = { "r0", "r1", "r2", "r3" };
-
- llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
-
- for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i)
- {
- if (ai == ae)
- break;
-
- reg_value.SetUInt32(*ai);
- if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]), reg_value))
- return false;
-
- ++ai;
- }
-
- if (ai != ae)
- {
- // Spill onto the stack
- size_t num_stack_regs = ae - ai;
-
- sp -= (num_stack_regs * 4);
- // Keep the stack 16 byte aligned
- sp &= ~(16ull-1ull);
-
- // just using arg1 to get the right size
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
-
- addr_t arg_pos = sp;
-
- for (; ai != ae; ++ai)
- {
- reg_value.SetUInt32(*ai);
- if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
- return false;
- arg_pos += reg_info->byte_size;
- }
- }
-
- TargetSP target_sp (thread.CalculateTarget());
- Address so_addr;
-
- // Figure out if our return address is ARM or Thumb by using the
- // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
- // thumb-ness and set the correct address bits for us.
- so_addr.SetLoadAddress (return_addr, target_sp.get());
- return_addr = so_addr.GetCallableLoadAddress (target_sp.get());
-
- // Set "lr" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
- return false;
+bool ABIMacOSX_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t function_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
- return false;
-
- // If bit zero or 1 is set, this must be a thumb function, no need to figure
- // this out from the symbols.
- so_addr.SetLoadAddress (function_addr, target_sp.get());
- function_addr = so_addr.GetCallableLoadAddress (target_sp.get());
-
- const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
- const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
-
- // Make a new CPSR and mask out any Thumb IT (if/then) bits
- uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
- // If bit zero or 1 is set, this must be thumb...
- if (function_addr & 1ull)
- new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
- else
- new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
+ const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
- if (new_cpsr != curr_cpsr)
- {
- if (!reg_ctx->WriteRegisterFromUnsigned (cpsr_reg_info, new_cpsr))
- return false;
- }
+ RegisterValue reg_value;
+
+ const char *reg_names[] = {"r0", "r1", "r2", "r3"};
+
+ llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
+
+ for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
+ if (ai == ae)
+ break;
+
+ reg_value.SetUInt32(*ai);
+ if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]),
+ reg_value))
+ return false;
+
+ ++ai;
+ }
+
+ if (ai != ae) {
+ // Spill onto the stack
+ size_t num_stack_regs = ae - ai;
+
+ sp -= (num_stack_regs * 4);
+ // Keep the stack 16 byte aligned
+ sp &= ~(16ull - 1ull);
- function_addr &= ~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))
+ // just using arg1 to get the right size
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+
+ addr_t arg_pos = sp;
+
+ for (; ai != ae; ++ai) {
+ reg_value.SetUInt32(*ai);
+ if (reg_ctx
+ ->WriteRegisterValueToMemory(reg_info, arg_pos,
+ reg_info->byte_size, reg_value)
+ .Fail())
return false;
+ arg_pos += reg_info->byte_size;
+ }
+ }
+
+ TargetSP target_sp(thread.CalculateTarget());
+ Address so_addr;
+
+ // Figure out if our return address is ARM or Thumb by using the
+ // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
+ // thumb-ness and set the correct address bits for us.
+ so_addr.SetLoadAddress(return_addr, target_sp.get());
+ return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
+
+ // Set "lr" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
+ return false;
+
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
+ return false;
- return true;
+ // If bit zero or 1 is set, this must be a thumb function, no need to figure
+ // this out from the symbols.
+ so_addr.SetLoadAddress(function_addr, target_sp.get());
+ function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
+
+ const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
+ const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
+
+ // Make a new CPSR and mask out any Thumb IT (if/then) bits
+ uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
+ // If bit zero or 1 is set, this must be thumb...
+ if (function_addr & 1ull)
+ new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
+ else
+ new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
+
+ if (new_cpsr != curr_cpsr) {
+ if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
+ return false;
+ }
+
+ function_addr &=
+ ~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;
}
-bool
-ABIMacOSX_arm::GetArgumentValues (Thread &thread,
- ValueList &values) const
-{
- uint32_t num_values = values.GetSize();
-
- ExecutionContext exe_ctx (thread.shared_from_this());
- // For now, assume that the types in the AST values come from the Target's
- // scratch AST.
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
+bool ABIMacOSX_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
+ uint32_t num_values = values.GetSize();
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ // For now, assume that the types in the AST values come from the Target's
+ // scratch AST.
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ addr_t sp = 0;
+
+ for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ Value *value = values.GetValueAtIndex(value_idx);
+
+ if (!value)
+ return false;
+
+ CompilerType compiler_type = value->GetCompilerType();
+ 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 {
+ // We only handle integer, pointer and reference types currently...
return false;
-
- addr_t sp = 0;
-
- for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
- {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- Value *value = values.GetValueAtIndex(value_idx);
-
- if (!value)
- return false;
-
- CompilerType compiler_type = value->GetCompilerType();
- 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 (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
+ if (value_idx < 4) {
+ // Arguments 1-4 are in r0-r3...
+ const RegisterInfo *arg_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) {
+ arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
+ } else {
+ switch (value_idx) {
+ case 0:
+ arg_reg_info = reg_ctx->GetRegisterInfoByName("r0");
+ break;
+ case 1:
+ arg_reg_info = reg_ctx->GetRegisterInfoByName("r1");
+ break;
+ case 2:
+ arg_reg_info = reg_ctx->GetRegisterInfoByName("r2");
+ break;
+ case 3:
+ arg_reg_info = reg_ctx->GetRegisterInfoByName("r3");
+ break;
}
- else
- {
- // We only handle integer, pointer and reference types currently...
+ }
+
+ if (arg_reg_info) {
+ RegisterValue reg_value;
+
+ if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
+ if (is_signed)
+ reg_value.SignExtend(bit_width);
+ if (!reg_value.GetScalarValue(value->GetScalar()))
return false;
+ continue;
}
-
- if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
- {
- if (value_idx < 4)
- {
- // Arguments 1-4 are in r0-r3...
- const RegisterInfo *arg_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)
- {
- arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
- }
- else
- {
- switch (value_idx)
- {
- case 0: arg_reg_info = reg_ctx->GetRegisterInfoByName("r0"); break;
- case 1: arg_reg_info = reg_ctx->GetRegisterInfoByName("r1"); break;
- case 2: arg_reg_info = reg_ctx->GetRegisterInfoByName("r2"); break;
- case 3: arg_reg_info = reg_ctx->GetRegisterInfoByName("r3"); break;
- }
- }
-
- if (arg_reg_info)
- {
- RegisterValue reg_value;
-
- if (reg_ctx->ReadRegister(arg_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 it already hasn't been read
- sp = reg_ctx->GetSP(0);
- if (sp == 0)
- return false;
- }
-
- // Arguments 5 on up are on the stack
- const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
- Error error;
- if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
- return false;
-
- sp += arg_byte_size;
- }
- }
+ }
+ return false;
+ } else {
+ if (sp == 0) {
+ // Read the stack pointer if it already hasn't been read
+ sp = reg_ctx->GetSP(0);
+ if (sp == 0)
+ return false;
+ }
+
+ // Arguments 5 on up are on the stack
+ const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
+ sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ return false;
+
+ sp += arg_byte_size;
}
+ }
}
- return true;
+ }
+ return true;
}
-bool
-ABIMacOSX_arm::IsArmv7kProcess (Thread *thread) const
-{
- bool is_armv7k = false;
- if (thread)
- {
- ProcessSP process_sp (thread->GetProcess());
- if (process_sp)
- {
- const ArchSpec &arch (process_sp->GetTarget().GetArchitecture());
- const ArchSpec::Core system_core = arch.GetCore();
- if (system_core == ArchSpec::eCore_arm_armv7k)
- {
- is_armv7k = true;
- }
- }
+bool ABIMacOSX_arm::IsArmv7kProcess(Thread *thread) const {
+ bool is_armv7k = false;
+ if (thread) {
+ ProcessSP process_sp(thread->GetProcess());
+ if (process_sp) {
+ const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
+ const ArchSpec::Core system_core = arch.GetCore();
+ if (system_core == ArchSpec::eCore_arm_armv7k) {
+ is_armv7k = true;
+ }
}
- return is_armv7k;
+ }
+ return is_armv7k;
}
-ValueObjectSP
-ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
- lldb_private::CompilerType &compiler_type) const
-{
- Value value;
- ValueObjectSP return_valobj_sp;
-
- if (!compiler_type)
- return return_valobj_sp;
+ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl(
+ Thread &thread, lldb_private::CompilerType &compiler_type) const {
+ Value value;
+ ValueObjectSP return_valobj_sp;
- value.SetCompilerType (compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- bool is_signed;
-
- // Get the pointer to the first stack argument so we have a place to start
- // when reading data
-
- const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
- if (compiler_type.IsIntegerOrEnumerationType (is_signed))
- {
- size_t bit_width = compiler_type.GetBitSize(&thread);
-
- switch (bit_width)
+ if (!compiler_type)
+ return return_valobj_sp;
+
+ value.SetCompilerType(compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ bool is_signed;
+
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
+
+ const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
+ size_t bit_width = compiler_type.GetBitSize(&thread);
+
+ switch (bit_width) {
+ default:
+ return return_valobj_sp;
+ case 128:
+ if (IsArmv7kProcess(&thread)) {
+ // "A composite type not larger than 16 bytes is returned in r0-r3. The
+ // format is
+ // as if the result had been stored in memory at a word-aligned address
+ // and then
+ // loaded into r0-r3 with an ldm instruction"
{
- default:
- return return_valobj_sp;
- case 128:
- if (IsArmv7kProcess (&thread))
- {
- // "A composite type not larger than 16 bytes is returned in r0-r3. The format is
- // as if the result had been stored in memory at a word-aligned address and then
- // loaded into r0-r3 with an ldm instruction"
- {
- const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
- const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
- 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);
- 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
- && process_sp)
- {
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue r0_reg_value;
- RegisterValue r1_reg_value;
- RegisterValue r2_reg_value;
- RegisterValue r3_reg_value;
- if (reg_ctx->ReadRegister(r0_reg_info, r0_reg_value)
- && reg_ctx->ReadRegister(r1_reg_info, r1_reg_value)
- && reg_ctx->ReadRegister(r2_reg_info, r2_reg_value)
- && reg_ctx->ReadRegister(r3_reg_info, r3_reg_value))
- {
- Error error;
- if (r0_reg_value.GetAsMemoryData (r0_reg_info, heap_data_ap->GetBytes()+0, 4, byte_order, error)
- && r1_reg_value.GetAsMemoryData (r1_reg_info, heap_data_ap->GetBytes()+4, 4, byte_order, error)
- && r2_reg_value.GetAsMemoryData (r2_reg_info, heap_data_ap->GetBytes()+8, 4, byte_order, error)
- && r3_reg_value.GetAsMemoryData (r3_reg_info, heap_data_ap->GetBytes()+12, 4, byte_order, error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- process_sp->GetAddressByteSize());
-
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- compiler_type,
- ConstString(""),
- data);
- return return_valobj_sp;
- }
- }
- }
- }
- }
- }
- else
- {
- return return_valobj_sp;
+ const RegisterInfo *r1_reg_info =
+ reg_ctx->GetRegisterInfoByName("r1", 0);
+ const RegisterInfo *r2_reg_info =
+ reg_ctx->GetRegisterInfoByName("r2", 0);
+ 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);
+ 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 &&
+ process_sp) {
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue r0_reg_value;
+ RegisterValue r1_reg_value;
+ RegisterValue r2_reg_value;
+ RegisterValue r3_reg_value;
+ if (reg_ctx->ReadRegister(r0_reg_info, r0_reg_value) &&
+ reg_ctx->ReadRegister(r1_reg_info, r1_reg_value) &&
+ reg_ctx->ReadRegister(r2_reg_info, r2_reg_value) &&
+ reg_ctx->ReadRegister(r3_reg_info, r3_reg_value)) {
+ Error error;
+ if (r0_reg_value.GetAsMemoryData(r0_reg_info,
+ heap_data_ap->GetBytes() + 0,
+ 4, byte_order, error) &&
+ r1_reg_value.GetAsMemoryData(r1_reg_info,
+ heap_data_ap->GetBytes() + 4,
+ 4, byte_order, error) &&
+ r2_reg_value.GetAsMemoryData(r2_reg_info,
+ heap_data_ap->GetBytes() + 8,
+ 4, byte_order, error) &&
+ r3_reg_value.GetAsMemoryData(r3_reg_info,
+ heap_data_ap->GetBytes() + 12,
+ 4, byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order,
+ process_sp->GetAddressByteSize());
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, compiler_type, ConstString(""), data);
+ return return_valobj_sp;
}
- break;
- case 64:
- {
- const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
- uint64_t raw_value;
- raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
- if (is_signed)
- value.GetScalar() = (int64_t)raw_value;
- else
- value.GetScalar() = (uint64_t)raw_value;
+ }
}
- break;
- case 32:
- if (is_signed)
- value.GetScalar() = (int32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
- break;
- case 16:
- if (is_signed)
- value.GetScalar() = (int16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
- break;
- case 8:
- if (is_signed)
- value.GetScalar() = (int8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
- break;
+ }
}
- }
- else if (compiler_type.IsPointerType ())
- {
- uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- value.GetScalar() = ptr;
- }
- else
- {
- // not handled yet
+ } else {
return return_valobj_sp;
+ }
+ break;
+ case 64: {
+ const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
+ uint64_t raw_value;
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
+ raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
+ UINT32_MAX))
+ << 32;
+ if (is_signed)
+ value.GetScalar() = (int64_t)raw_value;
+ else
+ value.GetScalar() = (uint64_t)raw_value;
+ } break;
+ case 32:
+ if (is_signed)
+ value.GetScalar() = (int32_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
+ break;
+ case 16:
+ if (is_signed)
+ value.GetScalar() = (int16_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
+ break;
+ case 8:
+ if (is_signed)
+ value.GetScalar() = (int8_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
+ break;
}
-
- // If we get here, we have a valid Value, so make our ValueObject out of it:
-
- return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ } else if (compiler_type.IsPointerType()) {
+ uint32_t ptr =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
+ UINT32_MAX;
+ value.GetScalar() = ptr;
+ } else {
+ // not handled yet
return return_valobj_sp;
+ }
+
+ // If we get here, we have a valid Value, so make our ValueObject out of it:
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ return return_valobj_sp;
}
-Error
-ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
-
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
+Error ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
}
-
- Thread *thread = frame_sp->GetThread().get();
-
- bool is_signed;
- uint32_t count;
- bool is_complex;
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
-
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
- {
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
- if (num_bytes <= 4)
- {
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- uint32_t raw_value = data.GetMaxU32(&offset, 4);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
- {
- const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value))
- set_it_simple = true;
- }
- }
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
+ if (num_bytes <= 4) {
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
+ set_it_simple = true;
+ } else {
+ uint32_t raw_value = data.GetMaxU32(&offset, 4);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
+ const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
+ set_it_simple = true;
}
- else if (num_bytes <= 16 && IsArmv7kProcess (frame_sp->GetThread().get()))
- {
- // "A composite type not larger than 16 bytes is returned in r0-r3. The format is
- // as if the result had been stored in memory at a word-aligned address and then
- // loaded into r0-r3 with an ldm instruction"
-
- const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
- const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
- const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
- const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
- lldb::offset_t offset = 0;
- uint32_t bytes_written = 4;
- uint32_t raw_value = data.GetMaxU64(&offset, 4);
- if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value) && bytes_written <= num_bytes)
- {
- bytes_written += 4;
- raw_value = data.GetMaxU64(&offset, 4);
- if (bytes_written <= num_bytes && reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value))
- {
- bytes_written += 4;
- raw_value = data.GetMaxU64(&offset, 4);
- if (bytes_written <= num_bytes && reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value))
- {
- bytes_written += 4;
- raw_value = data.GetMaxU64(&offset, 4);
- if (bytes_written <= num_bytes && reg_ctx->WriteRegisterFromUnsigned (r3_info, raw_value))
- {
- set_it_simple = true;
- }
- }
- }
+ }
+ } else if (num_bytes <= 16 &&
+ IsArmv7kProcess(frame_sp->GetThread().get())) {
+ // "A composite type not larger than 16 bytes is returned in r0-r3. The
+ // format is
+ // as if the result had been stored in memory at a word-aligned address
+ // and then
+ // loaded into r0-r3 with an ldm instruction"
+
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
+ const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
+ const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ lldb::offset_t offset = 0;
+ uint32_t bytes_written = 4;
+ uint32_t raw_value = data.GetMaxU64(&offset, 4);
+ if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value) &&
+ bytes_written <= num_bytes) {
+ bytes_written += 4;
+ raw_value = data.GetMaxU64(&offset, 4);
+ if (bytes_written <= num_bytes &&
+ reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) {
+ bytes_written += 4;
+ raw_value = data.GetMaxU64(&offset, 4);
+ if (bytes_written <= num_bytes &&
+ reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
+ bytes_written += 4;
+ raw_value = data.GetMaxU64(&offset, 4);
+ if (bytes_written <= num_bytes &&
+ reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) {
+ set_it_simple = true;
}
+ }
}
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
- }
- }
- else if (compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (is_complex)
- error.SetErrorString ("We don't support returning complex values at present");
- else
- error.SetErrorString ("We don't support returning float values at present");
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
}
-
- if (!set_it_simple)
- error.SetErrorString ("We only support setting simple integer return types at present.");
-
- return error;
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ error.SetErrorString(
+ "We don't support returning complex values at present");
+ else
+ error.SetErrorString(
+ "We don't support returning float values at present");
+ }
+
+ if (!set_it_simple)
+ error.SetErrorString(
+ "We only support setting simple integer return types at present.");
+
+ return error;
}
-bool
-ABIMacOSX_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t lr_reg_num = dwarf_lr;
- uint32_t sp_reg_num = dwarf_sp;
- uint32_t pc_reg_num = dwarf_pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our Call Frame Address is the stack pointer value
- row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
-
- // The previous PC is in the LR
- row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
- unwind_plan.AppendRow (row);
-
- // All other registers are the same.
-
- unwind_plan.SetSourceName ("arm at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
-
- return true;
+bool ABIMacOSX_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t lr_reg_num = dwarf_lr;
+ uint32_t sp_reg_num = dwarf_sp;
+ uint32_t pc_reg_num = dwarf_pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our Call Frame Address is the stack pointer value
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ // The previous PC is in the LR
+ row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+ unwind_plan.AppendRow(row);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName("arm at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
}
-bool
-ABIMacOSX_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear ();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t fp_reg_num = dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
- uint32_t pc_reg_num = dwarf_pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 4;
-
- row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
- row->SetOffset (0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("arm-apple-ios default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
-
- return true;
+bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num =
+ dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
+ uint32_t pc_reg_num = dwarf_pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 4;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+
+ return true;
}
// cf. "ARMv6 Function Calling Conventions"
@@ -748,7 +1869,8 @@ ABIMacOSX_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
// r4-r6 preserved
// r7 preserved (frame pointer)
// r8 preserved
-// r9 not preserved (usable as volatile scratch register with iOS 3.x and later)
+// r9 not preserved (usable as volatile scratch register with iOS 3.x and
+// later)
// r10-r11 preserved
// r12 not presrved
// r13 preserved (stack pointer)
@@ -761,211 +1883,181 @@ ABIMacOSX_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
// d8-d15 preserved (aka s16-s31, q4-q7)
// d16-d31 not preserved (aka q8-q15)
-bool
-ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
- const char *name = reg_info->name;
- if (name[0] == 'r')
- {
- switch (name[1])
- {
- case '0': return name[2] == '\0'; // r0
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // r1
- case '2':
- case '3':
- return name[3] == '\0'; // r12, r13 (sp)
- default:
- break;
- }
- break;
-
- case '2': return name[2] == '\0'; // r2
- case '3': return name[2] == '\0'; // r3
- case '9': return name[2] == '\0'; // r9 (apple-ios only...)
-
- break;
- }
+bool ABIMacOSX_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
+ const char *name = reg_info->name;
+ if (name[0] == 'r') {
+ switch (name[1]) {
+ case '0':
+ return name[2] == '\0'; // r0
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // r1
+ case '2':
+ case '3':
+ return name[3] == '\0'; // r12, r13 (sp)
+ default:
+ break;
}
- else if (name[0] == 'd')
- {
- switch (name[1])
- {
- case '0':
- return name[2] == '\0'; // d0 is volatile
-
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // d1 is volatile
- case '6':
- case '7':
- case '8':
- case '9':
- return name[3] == '\0'; // d16 - d19 are volatile
- default:
- break;
- }
- break;
-
- case '2':
- switch (name[2])
- {
- case '\0':
- return true; // d2 is volatile
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return name[3] == '\0'; // d20 - d29 are volatile
- default:
- break;
- }
- break;
-
- case '3':
- switch (name[2])
- {
- case '\0':
- return true; // d3 is volatile
- case '0':
- case '1':
- return name[3] == '\0'; // d30 - d31 are volatile
- default:
- break;
- }
- break;
- case '4':
- case '5':
- case '6':
- case '7':
- return name[2] == '\0'; // d4 - d7 are volatile
-
- default:
- break;
- }
+ break;
+
+ case '2':
+ return name[2] == '\0'; // r2
+ case '3':
+ return name[2] == '\0'; // r3
+ case '9':
+ return name[2] == '\0'; // r9 (apple-ios only...)
+
+ break;
+ }
+ } else if (name[0] == 'd') {
+ switch (name[1]) {
+ case '0':
+ return name[2] == '\0'; // d0 is volatile
+
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // d1 is volatile
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d16 - d19 are volatile
+ default:
+ break;
}
- else if (name[0] == 's')
- {
- switch (name[1])
- {
- case '0':
- return name[2] == '\0'; // s0 is volatile
-
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // s1 is volatile
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return name[3] == '\0'; // s10 - s15 are volatile
- default:
- break;
- }
- break;
-
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return name[2] == '\0'; // s2 - s9 are volatile
-
- default:
- break;
- }
+ break;
+
+ case '2':
+ switch (name[2]) {
+ case '\0':
+ return true; // d2 is volatile
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d20 - d29 are volatile
+ default:
+ break;
}
- else if (name[0] == 'q')
- {
- switch (name[1])
- {
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // q1 is volatile
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return true; // q10-q15 are volatile
- default:
- break;
- };
- break;
- case '0':
- case '2':
- case '3':
- return name[2] == '\0'; // q0-q3 are volatile
- case '8':
- case '9':
- return name[2] == '\0'; // q8-q9 are volatile
- default:
- break;
- }
+ break;
+
+ case '3':
+ switch (name[2]) {
+ case '\0':
+ return true; // d3 is volatile
+ case '0':
+ case '1':
+ return name[3] == '\0'; // d30 - d31 are volatile
+ default:
+ break;
}
- else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
- return true;
- }
- return false;
+ break;
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return name[2] == '\0'; // d4 - d7 are volatile
+
+ default:
+ break;
+ }
+ } else if (name[0] == 's') {
+ switch (name[1]) {
+ case '0':
+ return name[2] == '\0'; // s0 is volatile
+
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // s1 is volatile
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return name[3] == '\0'; // s10 - s15 are volatile
+ default:
+ break;
+ }
+ break;
+
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[2] == '\0'; // s2 - s9 are volatile
+
+ default:
+ break;
+ }
+ } else if (name[0] == 'q') {
+ switch (name[1]) {
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // q1 is volatile
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return true; // q10-q15 are volatile
+ default:
+ break;
+ };
+ break;
+ case '0':
+ case '2':
+ case '3':
+ return name[2] == '\0'; // q0-q3 are volatile
+ case '8':
+ case '9':
+ return name[2] == '\0'; // q8-q9 are volatile
+ default:
+ break;
+ }
+ } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
+ return true;
+ }
+ return false;
}
-void
-ABIMacOSX_arm::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Mac OS X ABI for arm targets",
- CreateInstance);
+void ABIMacOSX_arm::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "Mac OS X ABI for arm targets", CreateInstance);
}
-void
-ABIMacOSX_arm::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABIMacOSX_arm::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABIMacOSX_arm::GetPluginNameStatic()
-{
- static ConstString g_name("macosx-arm");
- return g_name;
+lldb_private::ConstString ABIMacOSX_arm::GetPluginNameStatic() {
+ static ConstString g_name("macosx-arm");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABIMacOSX_arm::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABIMacOSX_arm::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABIMacOSX_arm::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABIMacOSX_arm::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
index a4e9dead7794..39f57a0c5ee2 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
@@ -14,111 +14,89 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABIMacOSX_arm : public lldb_private::ABI
-{
+class ABIMacOSX_arm : public lldb_private::ABI {
public:
- ~ABIMacOSX_arm() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t func_addr,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are are 4 byte aligned
- if (cfa & (4ull - 1ull))
- return false; // Not 4 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // Just make sure the address is a valid 32 bit address. Bit zero
- // might be set due to Thumb function calls, so don't enforce 2 byte
- // alignment
- return pc <= UINT32_MAX;
- }
-
- lldb::addr_t
- FixCodeAddress(lldb::addr_t pc) override
- {
- // ARM uses bit zero to signify a code address is thumb, so we must
- // strip bit zero in any code addresses.
- return pc & ~(lldb::addr_t)1;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- bool
- IsArmv7kProcess (lldb_private::Thread *thread) const;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
+ ~ABIMacOSX_arm() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t func_addr, lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are are 4 byte aligned
+ if (cfa & (4ull - 1ull))
+ return false; // Not 4 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Just make sure the address is a valid 32 bit address. Bit zero
+ // might be set due to Thumb function calls, so don't enforce 2 byte
+ // alignment
+ return pc <= UINT32_MAX;
+ }
+
+ lldb::addr_t FixCodeAddress(lldb::addr_t pc) override {
+ // ARM uses bit zero to signify a code address is thumb, so we must
+ // strip bit zero in any code addresses.
+ return pc & ~(lldb::addr_t)1;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ bool IsArmv7kProcess(lldb_private::Thread *thread) const;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
protected:
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const override;
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABIMacOSX_arm() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABIMacOSX_arm_h_
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index ad3d8cb03b86..ee27a7e8d9b3 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -40,1062 +40,2414 @@ using namespace lldb_private;
static const char *pluginDesc = "Mac OS X ABI for arm64 targets";
-static RegisterInfo g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE
- // ========== ======= == === ============= =================== =================== ====================== =========================== ======================= ======================
- { "x0", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x1", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x2", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x3", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x4", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x5", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x6", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x7", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x8", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x9", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x10", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x11", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x12", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x13", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x14", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x15", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x16", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x17", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x18", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x19", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x20", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x21", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x22", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x23", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x24", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x25", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x26", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x27", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x28", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fp", "x29", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "lr", "x30", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "sp", "x31", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "pc", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "v0", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v1", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v2", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v3", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v4", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v5", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v6", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v7", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v8", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v9", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v10", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v11", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v12", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v13", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v14", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v15", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v16", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v17", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v18", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v19", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v20", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v21", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v22", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v23", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v24", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v25", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v26", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v27", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v28", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v29", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v30", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v31", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "fpsr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fpcr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT
+ // EH_FRAME DWARF GENERIC
+ // PROCESS PLUGIN LLDB NATIVE
+ // ========== ======= == === ============= ===================
+ // =================== ====================== ===========================
+ // ======================= ======================
+ {"x0",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x1",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x2",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x3",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x4",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x5",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x6",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x7",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x8",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x9",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x16",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x17",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x18",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x19",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x20",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x21",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x22",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x23",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x24",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x25",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x26",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x27",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x28",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fp",
+ "x29",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "x30",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "x31",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"v0",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v1",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v2",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v3",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v4",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v5",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v6",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v7",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v8",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v9",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v10",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v11",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v12",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v13",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v14",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v15",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v16",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v17",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v18",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v19",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v20",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v21",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v22",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v23",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v24",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v25",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v26",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v27",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v28",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v29",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v30",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v31",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"fpsr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpcr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"s0",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s1",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s2",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s3",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s4",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s5",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s6",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s7",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s8",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s9",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s10",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s11",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s12",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s13",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s14",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s15",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s16",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s17",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s18",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s19",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s20",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s21",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s22",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s23",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s24",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s25",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s26",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s27",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s28",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s29",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s30",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s31",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"d0",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d1",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d2",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d3",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d4",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d5",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d6",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d7",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d8",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d9",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d16",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d17",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d18",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d19",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d20",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d21",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d22",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d23",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d24",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d25",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d26",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d27",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d28",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d29",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d30",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d31",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABIMacOSX_arm64::GetRegisterInfoArray (uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABIMacOSX_arm64::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABIMacOSX_arm64::GetRedZoneSize () const
-{
- return 128;
-}
+size_t ABIMacOSX_arm64::GetRedZoneSize() const { return 128; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABIMacOSX_arm64::CreateInstance (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);
- return g_abi_sp;
- }
+ABIMacOSX_arm64::CreateInstance(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);
+ return g_abi_sp;
}
+ }
- return ABISP();
+ return ABISP();
}
-bool
-ABIMacOSX_arm64::PrepareTrivialCall (Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t func_addr,
- lldb::addr_t return_addr,
- llvm::ArrayRef<lldb::addr_t> args) const
-{
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
+bool ABIMacOSX_arm64::PrepareTrivialCall(
+ Thread &thread, lldb::addr_t sp, lldb::addr_t func_addr,
+ lldb::addr_t return_addr, llvm::ArrayRef<lldb::addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+
+ // x0 - x7 contain first 8 simple args
+ if (args.size() > 8) // TODO handle more than 6 arguments
+ return false;
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
if (log)
- {
- StreamString s;
- s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(),
- (uint64_t)sp,
- (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf (", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
- s.PutCString (")");
- log->PutCString(s.GetString().c_str());
- }
+ log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
+ static_cast<int>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
+
+ // Set "lr" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfoAtIndex(ra_reg_num), return_addr))
+ return false;
+
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfoAtIndex(sp_reg_num), sp))
+ return false;
+
+ // Set "pc" to the address requested
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfoAtIndex(pc_reg_num), func_addr))
+ return false;
+
+ return true;
+}
- const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread,
+ ValueList &values) const {
+ uint32_t num_values = values.GetSize();
- // x0 - x7 contain first 8 simple args
- if (args.size() > 8) // TODO handle more than 6 arguments
- return false;
+ ExecutionContext exe_ctx(thread.shared_from_this());
- for (size_t i = 0; i < args.size(); ++i)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
+ // Extract the register context so we can read arguments from registers
- // Set "lr" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (ra_reg_num), return_addr))
- return false;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (sp_reg_num), sp))
- return false;
+ if (!reg_ctx)
+ return false;
- // Set "pc" to the address requested
- if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (pc_reg_num), func_addr))
- return false;
+ addr_t sp = 0;
- return true;
-}
+ for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ Value *value = values.GetValueAtIndex(value_idx);
+
+ if (!value)
+ return false;
-bool
-ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
-{
- uint32_t num_values = values.GetSize();
-
- ExecutionContext exe_ctx (thread.shared_from_this());
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
+ 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;
-
- addr_t sp = 0;
-
- for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
- {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- Value *value = values.GetValueAtIndex(value_idx);
-
- if (!value)
- 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);
+ }
+
+ 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;
}
- else
- {
- // We only handle integer, pointer and reference types currently...
+ }
+
+ 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;
}
-
- 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_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)
- return false;
- }
+ }
+ 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;
+ }
+
+ // Arguments 5 on up are on the stack
+ const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
+ sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ return false;
- // Arguments 5 on up are on the stack
- const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
- Error 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;
- }
- }
- }
+ sp += arg_byte_size;
+ // Align up to the next 8 byte boundary if needed
+ if (sp % 8) {
+ sp >>= 3;
+ sp += 1;
+ sp <<= 3;
+ }
}
+ }
}
- return true;
+ }
+ return true;
}
-Error
-ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
-
- CompilerType return_value_type = new_value_sp->GetCompilerType();
- if (!return_value_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
+Error ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- Thread *thread = frame_sp->GetThread().get();
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
-
- if (reg_ctx)
- {
- DataExtractor data;
- Error data_error;
- const uint64_t byte_size = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
+ CompilerType return_value_type = new_value_sp->GetCompilerType();
+ if (!return_value_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
- const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar ||
- type_flags & eTypeIsPointer)
- {
- if (type_flags & eTypeIsInteger ||
- type_flags & eTypeIsPointer )
- {
- // Extract the register context so we can read arguments from registers
- lldb::offset_t offset = 0;
- if (byte_size <= 16)
- {
- const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0);
- if (byte_size <= 8)
- {
- uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
-
- if (!reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
- error.SetErrorString ("failed to write register x0");
- }
- else
- {
- uint64_t raw_value = data.GetMaxU64(&offset, 8);
-
- if (reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
- {
- const RegisterInfo *x1_info = reg_ctx->GetRegisterInfoByName("x1", 0);
- raw_value = data.GetMaxU64(&offset, byte_size - offset);
-
- if (!reg_ctx->WriteRegisterFromUnsigned (x1_info, raw_value))
- error.SetErrorString ("failed to write register x1");
- }
- }
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 128 bit integer values at present.");
- }
+ Thread *thread = frame_sp->GetThread().get();
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ if (reg_ctx) {
+ DataExtractor data;
+ Error data_error;
+ const uint64_t byte_size = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+
+ const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ // Extract the register context so we can read arguments from registers
+ lldb::offset_t offset = 0;
+ if (byte_size <= 16) {
+ const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0);
+ if (byte_size <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value))
+ error.SetErrorString("failed to write register x0");
+ } else {
+ uint64_t raw_value = data.GetMaxU64(&offset, 8);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) {
+ const RegisterInfo *x1_info =
+ reg_ctx->GetRegisterInfoByName("x1", 0);
+ raw_value = data.GetMaxU64(&offset, byte_size - offset);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value))
+ error.SetErrorString("failed to write register x1");
}
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- error.SetErrorString ("returning complex float values are not supported");
- }
- else
- {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info)
- {
- if (byte_size <= 16)
- {
- if (byte_size <= RegisterValue::GetMaxByteSize())
- {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData (v0_info, data, 0, true);
- if (error.Success())
- {
- if (!reg_ctx->WriteRegister (v0_info, reg_value))
- error.SetErrorString ("failed to write register v0");
- }
- }
- else
- {
- error.SetErrorStringWithFormat ("returning float values with a byte size of %" PRIu64 " are not supported", byte_size);
- }
- }
- else
- {
- error.SetErrorString("returning float values longer than 128 bits are not supported");
- }
- }
- else
- {
- error.SetErrorString("v0 register is not available on this target");
- }
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 128 bit "
+ "integer values at present.");
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ error.SetErrorString(
+ "returning complex float values are not supported");
+ } else {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= 16) {
+ if (byte_size <= RegisterValue::GetMaxByteSize()) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
}
+ } else {
+ error.SetErrorStringWithFormat(
+ "returning float values with a byte size of %" PRIu64
+ " are not supported",
+ byte_size);
+ }
+ } else {
+ error.SetErrorString("returning float values longer than 128 "
+ "bits are not supported");
}
+ } else {
+ error.SetErrorString("v0 register is not available on this target");
+ }
}
- else if (type_flags & eTypeIsVector)
- {
- if (byte_size > 0)
- {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info)
- {
- if (byte_size <= v0_info->byte_size)
- {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData (v0_info, data, 0, true);
- if (error.Success())
- {
- if (!reg_ctx->WriteRegister (v0_info, reg_value))
- error.SetErrorString ("failed to write register v0");
- }
- }
- }
+ }
+ } else if (type_flags & eTypeIsVector) {
+ if (byte_size > 0) {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= v0_info->byte_size) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
}
+ }
}
+ }
}
- else
- {
- error.SetErrorString("no registers are available");
- }
-
- return error;
+ } else {
+ error.SetErrorString("no registers are available");
+ }
+
+ return error;
}
-bool
-ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t lr_reg_num = arm64_dwarf::lr;
- uint32_t sp_reg_num = arm64_dwarf::sp;
- uint32_t pc_reg_num = arm64_dwarf::pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
-
- // Our previous PC is in the LR
- row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
-
- unwind_plan.AppendRow (row);
-
- // All other registers are the same.
-
- unwind_plan.SetSourceName ("arm64 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
-
- return true;
+bool ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t lr_reg_num = arm64_dwarf::lr;
+ uint32_t sp_reg_num = arm64_dwarf::sp;
+ uint32_t pc_reg_num = arm64_dwarf::pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ // Our previous PC is in the LR
+ row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+
+ unwind_plan.AppendRow(row);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName("arm64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
}
-bool
-ABIMacOSX_arm64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t fp_reg_num = arm64_dwarf::fp;
- uint32_t pc_reg_num = arm64_dwarf::pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 8;
-
- row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
- row->SetOffset (0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("arm64-apple-darwin default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
+bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num = arm64_dwarf::fp;
+ uint32_t pc_reg_num = arm64_dwarf::pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 8;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
}
-// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
-// registers x19 through x28 and sp are callee preserved.
-// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these regs),
+// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
+// registers x19 through x28 and sp are callee preserved.
+// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these
+// regs),
// the rest of the fp/SIMD registers are volatile.
// We treat x29 as callee preserved also, else the unwinder won't try to
// retrieve fp saves.
-bool
-ABIMacOSX_arm64::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- const char *name = reg_info->name;
-
- // Sometimes we'll be called with the "alternate" name for these registers;
- // recognize them as non-volatile.
-
- if (name[0] == 'p' && name[1] == 'c') // pc
- return false;
- if (name[0] == 'f' && name[1] == 'p') // fp
- return false;
- if (name[0] == 's' && name[1] == 'p') // sp
- return false;
- if (name[0] == 'l' && name[1] == 'r') // lr
- return false;
-
- if (name[0] == 'x')
- {
- // Volatile registers: x0-x18, x30 (lr)
- // Return false for the non-volatile gpr regs, true for everything else
- switch (name[1])
- {
- case '1':
- switch (name[2])
- {
- case '9':
- return false; // x19 is non-volatile
- default:
- return true;
- }
- break;
- case '2':
- switch (name[2])
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- return false; // x20 - 28 are non-volatile
- case '9':
- return false; // x29 aka fp treat as non-volatile on Darwin
- default:
- return true;
- }
- case '3': // x30 aka lr treat as non-volatile
- if (name[2] == '0')
- return false;
- break;
- default:
- return true;
- }
+bool ABIMacOSX_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ const char *name = reg_info->name;
+
+ // Sometimes we'll be called with the "alternate" name for these registers;
+ // recognize them as non-volatile.
+
+ if (name[0] == 'p' && name[1] == 'c') // pc
+ return false;
+ if (name[0] == 'f' && name[1] == 'p') // fp
+ return false;
+ if (name[0] == 's' && name[1] == 'p') // sp
+ return false;
+ if (name[0] == 'l' && name[1] == 'r') // lr
+ return false;
+
+ if (name[0] == 'x') {
+ // Volatile registers: x0-x18, x30 (lr)
+ // Return false for the non-volatile gpr regs, true for everything else
+ switch (name[1]) {
+ case '1':
+ switch (name[2]) {
+ case '9':
+ return false; // x19 is non-volatile
+ default:
+ return true;
}
- else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd')
- {
- // Volatile registers: v0-7, v16-v31
- // Return false for non-volatile fp/SIMD regs, true for everything else
- switch (name[1])
- {
- case '8':
- case '9':
- return false; // v8-v9 are non-volatile
- case '1':
- switch (name[2])
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return false; // v10-v15 are non-volatile
- default:
- return true;
- }
- default:
- return true;
- }
+ break;
+ case '2':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ return false; // x20 - 28 are non-volatile
+ case '9':
+ return false; // x29 aka fp treat as non-volatile on Darwin
+ default:
+ return true;
+ }
+ case '3': // x30 aka lr treat as non-volatile
+ if (name[2] == '0')
+ return false;
+ break;
+ default:
+ return true;
+ }
+ } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') {
+ // Volatile registers: v0-7, v16-v31
+ // Return false for non-volatile fp/SIMD regs, true for everything else
+ switch (name[1]) {
+ case '8':
+ case '9':
+ return false; // v8-v9 are non-volatile
+ case '1':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return false; // v10-v15 are non-volatile
+ default:
+ return true;
}
+ default:
+ return true;
+ }
}
- return true;
+ }
+ return true;
}
-static bool
-LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
- RegisterContext *reg_ctx,
- const CompilerType &value_type,
- bool is_return_value, // false => parameter, true => return value
- 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)
+static bool LoadValueFromConsecutiveGPRRegisters(
+ ExecutionContext &exe_ctx, RegisterContext *reg_ctx,
+ const CompilerType &value_type,
+ bool is_return_value, // false => parameter, true => return value
+ 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)
+ return false;
+
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ Error error;
+
+ CompilerType base_type;
+ const uint32_t homogeneous_count =
+ value_type.IsHomogeneousAggregate(&base_type);
+ if (homogeneous_count > 0 && homogeneous_count <= 8) {
+ // Make sure we have enough registers
+ if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
+ if (!base_type)
return false;
+ const size_t base_byte_size = base_type.GetByteSize(nullptr);
+ uint32_t data_offset = 0;
+
+ for (uint32_t i = 0; i < homogeneous_count; ++i) {
+ char v_name[8];
+ ::snprintf(v_name, sizeof(v_name), "v%u", NSRN);
+ const RegisterInfo *reg_info =
+ reg_ctx->GetRegisterInfoByName(v_name, 0);
+ if (reg_info == nullptr)
+ return false;
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- Error error;
-
- CompilerType base_type;
- const uint32_t homogeneous_count = value_type.IsHomogeneousAggregate (&base_type);
- if (homogeneous_count > 0 && homogeneous_count <= 8)
- {
- // Make sure we have enough registers
- if (NSRN < 8 && (8-NSRN) >= homogeneous_count)
- {
- if (!base_type)
- return false;
- const size_t base_byte_size = base_type.GetByteSize(nullptr);
- uint32_t data_offset = 0;
+ if (base_byte_size > reg_info->byte_size)
+ return false;
- for (uint32_t i = 0; i < homogeneous_count; ++i)
- {
- char v_name[8];
- ::snprintf (v_name, sizeof(v_name), "v%u", NSRN);
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(v_name, 0);
- if (reg_info == nullptr)
- return false;
-
- if (base_byte_size > reg_info->byte_size)
- return false;
-
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- // Make sure we have enough room in "heap_data_ap"
- 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,
- byte_order,
- error);
- if (bytes_copied != base_byte_size)
- return false;
- data_offset += bytes_copied;
- ++NSRN;
- }
- else
- return false;
- }
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP (heap_data_ap.release()));
- return true;
- }
+ RegisterValue reg_value;
+
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ // Make sure we have enough room in "heap_data_ap"
+ 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,
+ byte_order, error);
+ if (bytes_copied != base_byte_size)
+ return false;
+ data_offset += bytes_copied;
+ ++NSRN;
+ } else
+ return false;
+ }
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_ap.release()));
+ return true;
}
+ }
+
+ const size_t max_reg_byte_size = 16;
+ if (byte_size <= max_reg_byte_size) {
+ size_t bytes_left = byte_size;
+ uint32_t data_offset = 0;
+ while (data_offset < byte_size) {
+ if (NGRN >= 8)
+ return false;
- const size_t max_reg_byte_size = 16;
- if (byte_size <= max_reg_byte_size)
- {
- size_t bytes_left = byte_size;
- uint32_t data_offset = 0;
- while (data_offset < byte_size)
- {
- if (NGRN >= 8)
- return false;
-
- uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_num == LLDB_INVALID_REGNUM)
- return false;
-
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
- if (reg_info == nullptr)
- return false;
+ uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return false;
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- const size_t curr_byte_size = std::min<size_t>(8,bytes_left);
- const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info, heap_data_ap->GetBytes()+data_offset, curr_byte_size, byte_order, error);
- if (bytes_copied == 0)
- return false;
- if (bytes_copied >= bytes_left)
- break;
- data_offset += bytes_copied;
- bytes_left -= bytes_copied;
- ++NGRN;
- }
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+ if (reg_info == nullptr)
+ return false;
+
+ RegisterValue reg_value;
+
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, heap_data_ap->GetBytes() + data_offset, curr_byte_size,
+ byte_order, error);
+ if (bytes_copied == 0)
+ return false;
+ if (bytes_copied >= bytes_left)
+ break;
+ data_offset += bytes_copied;
+ bytes_left -= bytes_copied;
+ ++NGRN;
}
- else
- {
- const RegisterInfo *reg_info = nullptr;
- if (is_return_value)
- {
- // We are assuming we are decoding this immediately after returning
- // from a function call and that the address of the structure is in x8
- reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
- }
- else
- {
- // We are assuming we are stopped at the first instruction in a function
- // and that the ABI is being respected so all parameters appear where they
- // should be (functions with no external linkage can legally violate the ABI).
- if (NGRN >= 8)
- return false;
-
- uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_num == LLDB_INVALID_REGNUM)
- return false;
- reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
- if (reg_info == nullptr)
- return false;
- ++NGRN;
- }
+ } else {
+ const RegisterInfo *reg_info = nullptr;
+ if (is_return_value) {
+ // We are assuming we are decoding this immediately after returning
+ // from a function call and that the address of the structure is in x8
+ reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
+ } else {
+ // We are assuming we are stopped at the first instruction in a function
+ // and that the ABI is being respected so all parameters appear where they
+ // should be (functions with no external linkage can legally violate the
+ // ABI).
+ if (NGRN >= 8)
+ return false;
- if (reg_info == nullptr)
- return false;
+ uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return false;
+ reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+ if (reg_info == nullptr)
+ return false;
+ ++NGRN;
+ }
- const lldb::addr_t value_addr = reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
+ if (reg_info == nullptr)
+ return false;
- if (value_addr == LLDB_INVALID_ADDRESS)
- return false;
+ const lldb::addr_t value_addr =
+ reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
- if (exe_ctx.GetProcessRef().ReadMemory (value_addr,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- error) != heap_data_ap->GetByteSize())
- {
- return false;
- }
+ if (value_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ if (exe_ctx.GetProcessRef().ReadMemory(
+ value_addr, heap_data_ap->GetBytes(), heap_data_ap->GetByteSize(),
+ error) != heap_data_ap->GetByteSize()) {
+ return false;
}
+ }
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP (heap_data_ap.release()));
- return true;
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_ap.release()));
+ return true;
}
-ValueObjectSP
-ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
-
- ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
- return return_valobj_sp;
-
- //value.SetContext (Value::eContextTypeClangType, return_compiler_type);
- value.SetCompilerType(return_compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
-
- const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar ||
- type_flags & eTypeIsPointer)
- {
- value.SetValueType(Value::eValueTypeScalar);
-
- 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)
+ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType, return_compiler_type);
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ 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) {
+ const RegisterInfo *x0_reg_info =
+ reg_ctx->GetRegisterInfoByName("x0", 0);
+ if (x0_reg_info) {
+ uint64_t raw_value =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
+ 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size) {
+ default:
+ break;
+ case 16: // uint128_t
+ // In register x0 and x1
{
- const RegisterInfo *x0_reg_info = reg_ctx->GetRegisterInfoByName("x0", 0);
- if (x0_reg_info)
- {
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size)
- {
- default:
- break;
- case 16: // uint128_t
- // In register x0 and x1
- {
- const RegisterInfo *x1_reg_info = reg_ctx->GetRegisterInfoByName("x1", 0);
-
- if (x1_reg_info)
- {
- 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));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue x0_reg_value;
- RegisterValue x1_reg_value;
- if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
- reg_ctx->ReadRegister(x1_reg_info, x1_reg_value))
- {
- Error error;
- if (x0_reg_value.GetAsMemoryData (x0_reg_info, heap_data_ap->GetBytes()+0, 8, byte_order, error) &&
- x1_reg_value.GetAsMemoryData (x1_reg_info, heap_data_ap->GetBytes()+8, 8, byte_order, error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
-
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- return return_valobj_sp;
- }
- }
- }
- }
- }
- break;
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
-
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
-
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
-
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
+ const RegisterInfo *x1_reg_info =
+ reg_ctx->GetRegisterInfoByName("x1", 0);
+
+ if (x1_reg_info) {
+ 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));
+ const ByteOrder byte_order =
+ exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue x0_reg_value;
+ RegisterValue x1_reg_value;
+ if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
+ reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) {
+ Error error;
+ if (x0_reg_value.GetAsMemoryData(
+ x0_reg_info, heap_data_ap->GetBytes() + 0, 8,
+ byte_order, error) &&
+ x1_reg_value.GetAsMemoryData(
+ x1_reg_info, heap_data_ap->GetBytes() + 8, 8,
+ byte_order, error)) {
+ DataExtractor data(
+ DataBufferSP(heap_data_ap.release()), byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ return return_valobj_sp;
}
+ }
}
+ }
}
- }
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- }
+ break;
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
else
- {
- if (byte_size <= sizeof(long double))
- {
- const RegisterInfo *v0_reg_info = reg_ctx->GetRegisterInfoByName("v0", 0);
- RegisterValue v0_value;
- if (reg_ctx->ReadRegister (v0_reg_info, v0_value))
- {
- DataExtractor data;
- if (v0_value.GetData(data))
- {
- lldb::offset_t offset = 0;
- if (byte_size == sizeof(float))
- {
- value.GetScalar() = data.GetFloat(&offset);
- success = true;
- }
- else if (byte_size == sizeof(double))
- {
- value.GetScalar() = data.GetDouble(&offset);
- success = true;
- }
- else if (byte_size == sizeof(long double))
- {
- value.GetScalar() = data.GetLongDouble(&offset);
- success = true;
- }
- }
- }
- }
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ if (byte_size <= sizeof(long double)) {
+ const RegisterInfo *v0_reg_info =
+ reg_ctx->GetRegisterInfoByName("v0", 0);
+ RegisterValue v0_value;
+ if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) {
+ DataExtractor data;
+ if (v0_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float)) {
+ value.GetScalar() = data.GetFloat(&offset);
+ success = true;
+ } else if (byte_size == sizeof(double)) {
+ value.GetScalar() = data.GetDouble(&offset);
+ success = true;
+ } else if (byte_size == sizeof(long double)) {
+ value.GetScalar() = data.GetLongDouble(&offset);
+ success = true;
+ }
}
+ }
}
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ }
}
- else if (type_flags & eTypeIsVector)
- {
- if (byte_size > 0)
- {
-
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info)
- {
- if (byte_size <= v0_info->byte_size)
- {
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(v0_info, reg_value))
- {
- Error error;
- if (reg_value.GetAsMemoryData (v0_info,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ if (byte_size > 0) {
+
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= v0_info->byte_size) {
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(v0_info, reg_value)) {
+ Error error;
+ if (reg_value.GetAsMemoryData(v0_info, heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(),
+ byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
}
+ }
}
+ }
}
- else if (type_flags & eTypeIsStructUnion ||
- type_flags & eTypeIsClass)
- {
- DataExtractor data;
-
- uint32_t NGRN = 0; // Search ABI docs for NGRN
- uint32_t NSRN = 0; // Search ABI docs for NSRN
- const bool is_return_value = true;
- if (LoadValueFromConsecutiveGPRRegisters (exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN, data))
- {
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
+ } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
+ DataExtractor data;
+
+ uint32_t NGRN = 0; // Search ABI docs for NGRN
+ uint32_t NSRN = 0; // Search ABI docs for NSRN
+ const bool is_return_value = true;
+ if (LoadValueFromConsecutiveGPRRegisters(
+ exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
+ data)) {
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
}
- return return_valobj_sp;
+ }
+ return return_valobj_sp;
}
-void
-ABIMacOSX_arm64::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- pluginDesc,
- CreateInstance);
+void ABIMacOSX_arm64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
+ CreateInstance);
}
-void
-ABIMacOSX_arm64::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABIMacOSX_arm64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-ABIMacOSX_arm64::GetPluginNameStatic()
-{
- static ConstString g_plugin_name("ABIMacOSX_arm64");
- return g_plugin_name;
+ConstString ABIMacOSX_arm64::GetPluginNameStatic() {
+ static ConstString g_plugin_name("ABIMacOSX_arm64");
+ return g_plugin_name;
}
-uint32_t
-ABIMacOSX_arm64::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABIMacOSX_arm64::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
index 1bc94f61c2f1..e0978116a730 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
@@ -14,116 +14,97 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABIMacOSX_arm64 :
- public lldb_private::ABI
-{
+class ABIMacOSX_arm64 : public lldb_private::ABI {
public:
- ~ABIMacOSX_arm64() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- // The arm64 ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- if (pc & (4ull - 1ull))
- return false; // Not 4 byte aligned
-
- // Anything else if fair game..
- return true;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- uint32_t
- GetPluginVersion() override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
+ ~ABIMacOSX_arm64() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ // The arm64 ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (8-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ if (pc & (4ull - 1ull))
+ return false; // Not 4 byte aligned
+
+ // Anything else if fair game..
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ uint32_t GetPluginVersion() override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
protected:
- lldb::ValueObjectSP
- GetReturnValueObjectImpl (lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const override;
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm64() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABIMacOSX_arm64() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABIMacOSX_arm64_h_
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 70c7adb8e5b5..6eead6f35e3b 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -34,491 +34,1010 @@
using namespace lldb;
using namespace lldb_private;
-enum
-{
- ehframe_eax = 0,
- ehframe_ecx,
- ehframe_edx,
- ehframe_ebx,
- ehframe_ebp, // Different from DWARF the regnums - eh_frame esp/ebp had their regnums switched on i386 darwin
- ehframe_esp, // Different from DWARF the regnums - eh_frame esp/ebp had their regnums switched on i386 darwin
- ehframe_esi,
- ehframe_edi,
- ehframe_eip,
- ehframe_eflags
+enum {
+ ehframe_eax = 0,
+ ehframe_ecx,
+ ehframe_edx,
+ ehframe_ebx,
+ ehframe_ebp, // Different from DWARF the regnums - eh_frame esp/ebp had their
+ // regnums switched on i386 darwin
+ ehframe_esp, // Different from DWARF the regnums - eh_frame esp/ebp had their
+ // regnums switched on i386 darwin
+ ehframe_esi,
+ ehframe_edi,
+ ehframe_eip,
+ ehframe_eflags
};
-enum
-{
- dwarf_eax = 0,
- dwarf_ecx,
- dwarf_edx,
- dwarf_ebx,
- dwarf_esp,
- dwarf_ebp,
- dwarf_esi,
- dwarf_edi,
- dwarf_eip,
- dwarf_eflags,
- dwarf_stmm0 = 11,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7,
- dwarf_ymm0 = dwarf_xmm0,
- dwarf_ymm1 = dwarf_xmm1,
- dwarf_ymm2 = dwarf_xmm2,
- dwarf_ymm3 = dwarf_xmm3,
- dwarf_ymm4 = dwarf_xmm4,
- dwarf_ymm5 = dwarf_xmm5,
- dwarf_ymm6 = dwarf_xmm6,
- dwarf_ymm7 = dwarf_xmm7
+enum {
+ dwarf_eax = 0,
+ dwarf_ecx,
+ dwarf_edx,
+ dwarf_ebx,
+ dwarf_esp,
+ dwarf_ebp,
+ dwarf_esi,
+ dwarf_edi,
+ dwarf_eip,
+ dwarf_eflags,
+ dwarf_stmm0 = 11,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_xmm0 = 21,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7,
+ dwarf_ymm0 = dwarf_xmm0,
+ dwarf_ymm1 = dwarf_xmm1,
+ dwarf_ymm2 = dwarf_xmm2,
+ dwarf_ymm3 = dwarf_xmm3,
+ dwarf_ymm4 = dwarf_xmm4,
+ dwarf_ymm5 = dwarf_xmm5,
+ dwarf_ymm6 = dwarf_xmm6,
+ dwarf_ymm7 = dwarf_xmm7
};
-static RegisterInfo g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
- // ====== ======= == === ============= ============ ===================== ===================== ============================ ==================== ====================== ========== ===============
- { "eax", nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_eax , dwarf_eax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ebx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ecx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_ecx , dwarf_ecx , LLDB_REGNUM_GENERIC_ARG4 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "edx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_edx , dwarf_edx , LLDB_REGNUM_GENERIC_ARG3 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "esi" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_esi , dwarf_esi , LLDB_REGNUM_GENERIC_ARG2 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "edi" , nullptr, 4, 0, eEncodingUint , eFormatHex , { ehframe_edi , dwarf_edi , LLDB_REGNUM_GENERIC_ARG1 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ebp" , "fp", 4, 0, eEncodingUint , eFormatHex , { ehframe_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "esp" , "sp", 4, 0, eEncodingUint , eFormatHex , { ehframe_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "eip" , "pc", 4, 0, eEncodingUint , eFormatHex , { ehframe_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "eflags", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ss" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ds" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "es" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "gs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm0" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm1" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm2" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm3" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm4" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm5" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm6" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm7" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_stmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fctrl" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fstat" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ftag" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fiseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fioff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "foseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fooff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fop" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm0" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm1" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm2" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm3" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm4" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm5" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm6" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm7" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "mxcsr" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm0" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm1" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm2" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm3" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm4" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm5" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm6" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm7" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
-};
+static RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT
+ // EH_FRAME DWARF GENERIC
+ // PROCESS PLUGIN LLDB NATIVE
+ // ====== ======= == === ============= ============
+ // ===================== ===================== ============================
+ // ==================== ======================
+ {"eax",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ebx",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ecx",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_ecx, dwarf_ecx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"edx",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_edx, dwarf_edx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"esi",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_esi, dwarf_esi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"edi",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_edi, dwarf_edi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ebp",
+ "fp",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"esp",
+ "sp",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"eip",
+ "pc",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"eflags",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ss",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ds",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"es",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"gs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm0",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm0, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm1",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm2",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm3",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm4",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm5",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm5, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm6",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm6, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm7",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_stmm7, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fctrl",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fstat",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ftag",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fiseg",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fioff",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"foseg",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fooff",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fop",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm0",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm1",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm2",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm3",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm4",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm5",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm6",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm7",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"mxcsr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm0",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm1",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm2",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm3",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm4",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm5",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm6",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm7",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABIMacOSX_i386::GetRegisterInfoArray (uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABIMacOSX_i386::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABIMacOSX_i386::GetRedZoneSize () const
-{
- return 0;
-}
+size_t ABIMacOSX_i386::GetRedZoneSize() const { return 0; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABIMacOSX_i386::CreateInstance (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);
- return g_abi_sp;
- }
- return ABISP();
+ABIMacOSX_i386::CreateInstance(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);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABIMacOSX_i386::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
- uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
-
- // When writing a register value down to memory, the register info used
- // to write memory just needs to have the correct size of a 32 bit register,
- // the actual register it pertains to is not important, just the size needs
- // to be correct. Here we use "eax"...
- const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
- if (!reg_info_32)
- return false; // TODO this should actually never happen
-
- // Make room for the argument(s) on the stack
-
- Error error;
- RegisterValue reg_value;
-
- // Write any arguments onto the stack
- sp -= 4 * args.size();
-
- // Align the SP
- sp &= ~(16ull-1ull); // 16-byte alignment
-
- addr_t arg_pos = sp;
-
- for (addr_t arg : args)
- {
- reg_value.SetUInt32(arg);
- error = reg_ctx->WriteRegisterValueToMemory (reg_info_32,
- arg_pos,
- reg_info_32->byte_size,
- reg_value);
- if (error.Fail())
- return false;
- arg_pos += 4;
- }
-
- // The return address is pushed onto the stack (yes after we just set the
- // alignment above!).
- sp -= 4;
- reg_value.SetUInt32(return_addr);
- error = reg_ctx->WriteRegisterValueToMemory (reg_info_32,
- sp,
- reg_info_32->byte_size,
- reg_value);
+bool ABIMacOSX_i386::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+ uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+
+ // When writing a register value down to memory, the register info used
+ // to write memory just needs to have the correct size of a 32 bit register,
+ // the actual register it pertains to is not important, just the size needs
+ // to be correct. Here we use "eax"...
+ const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
+ if (!reg_info_32)
+ return false; // TODO this should actually never happen
+
+ // Make room for the argument(s) on the stack
+
+ Error error;
+ RegisterValue reg_value;
+
+ // Write any arguments onto the stack
+ sp -= 4 * args.size();
+
+ // Align the SP
+ sp &= ~(16ull - 1ull); // 16-byte alignment
+
+ addr_t arg_pos = sp;
+
+ for (addr_t arg : args) {
+ reg_value.SetUInt32(arg);
+ error = reg_ctx->WriteRegisterValueToMemory(
+ reg_info_32, arg_pos, reg_info_32->byte_size, reg_value);
if (error.Fail())
- return false;
-
- // %esp is set to the actual stack value.
-
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
- return false;
-
- // %eip is set to the address of the called function.
-
- if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, func_addr))
- return false;
-
- return true;
-}
+ return false;
+ arg_pos += 4;
+ }
-static bool
-ReadIntegerArgument (Scalar &scalar,
- unsigned int bit_width,
- bool is_signed,
- Process *process,
- addr_t &current_stack_argument)
-{
-
- uint32_t byte_size = (bit_width + (8-1))/8;
- Error error;
- if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
- {
- current_stack_argument += byte_size;
- return true;
- }
+ // The return address is pushed onto the stack (yes after we just set the
+ // alignment above!).
+ sp -= 4;
+ reg_value.SetUInt32(return_addr);
+ error = reg_ctx->WriteRegisterValueToMemory(
+ reg_info_32, sp, reg_info_32->byte_size, reg_value);
+ if (error.Fail())
+ return false;
+
+ // %esp is set to the actual stack value.
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
+ return false;
+
+ // %eip is set to the address of the called function.
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr))
return false;
+
+ return true;
}
-bool
-ABIMacOSX_i386::GetArgumentValues (Thread &thread,
- ValueList &values) const
-{
- unsigned int num_values = values.GetSize();
- unsigned int value_index;
-
- // Get the pointer to the first stack argument so we have a place to start
- // when reading data
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
- return false;
-
- addr_t sp = reg_ctx->GetSP(0);
-
- if (!sp)
- return false;
-
- addr_t current_stack_argument = sp + 4; // jump over return address
-
- for (value_index = 0;
- value_index < num_values;
- ++value_index)
- {
- Value *value = values.GetValueAtIndex(value_index);
-
- if (!value)
- return false;
-
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- CompilerType compiler_type (value->GetCompilerType());
- if (compiler_type)
- {
- bool is_signed;
-
- if (compiler_type.IsIntegerOrEnumerationType (is_signed))
- {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread),
- is_signed,
- thread.GetProcess().get(),
- current_stack_argument);
- }
- else if (compiler_type.IsPointerType())
- {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread),
- false,
- thread.GetProcess().get(),
- current_stack_argument);
- }
- }
- }
-
+static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
+ bool is_signed, Process *process,
+ addr_t &current_stack_argument) {
+
+ uint32_t byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size,
+ is_signed, scalar, error)) {
+ current_stack_argument += byte_size;
return true;
+ }
+ return false;
}
-Error
-ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
+bool ABIMacOSX_i386::GetArgumentValues(Thread &thread,
+ ValueList &values) const {
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
+
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ addr_t sp = reg_ctx->GetSP(0);
+
+ if (!sp)
+ return false;
+
+ addr_t current_stack_argument = sp + 4; // jump over return address
+
+ for (value_index = 0; value_index < num_values; ++value_index) {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ CompilerType compiler_type(value->GetCompilerType());
+ if (compiler_type) {
+ bool is_signed;
+
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
+ ReadIntegerArgument(value->GetScalar(),
+ compiler_type.GetBitSize(&thread), is_signed,
+ thread.GetProcess().get(), current_stack_argument);
+ } else if (compiler_type.IsPointerType()) {
+ ReadIntegerArgument(value->GetScalar(),
+ compiler_type.GetBitSize(&thread), false,
+ thread.GetProcess().get(), current_stack_argument);
+ }
}
-
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
+ }
+
+ return true;
+}
+
+Error ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
}
-
- Thread *thread = frame_sp->GetThread().get();
-
- bool is_signed;
- uint32_t count;
- bool is_complex;
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
-
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
- {
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
- if (num_bytes <= 4)
- {
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
-
- if (reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- uint32_t raw_value = data.GetMaxU32(&offset, 4);
-
- if (reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value))
- {
- const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
-
- if (reg_ctx->WriteRegisterFromUnsigned (edx_info, raw_value))
- set_it_simple = true;
- }
- }
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
+ if (num_bytes <= 4) {
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value))
+ set_it_simple = true;
+ } else {
+ uint32_t raw_value = data.GetMaxU32(&offset, 4);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value)) {
+ const RegisterInfo *edx_info =
+ reg_ctx->GetRegisterInfoByName("edx", 0);
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value))
+ set_it_simple = true;
}
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
}
- else if (compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (is_complex)
- error.SetErrorString ("We don't support returning complex values at present");
- else
- error.SetErrorString ("We don't support returning float values at present");
- }
-
- if (!set_it_simple)
- error.SetErrorString ("We only support setting simple integer return types at present.");
-
- return error;
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ error.SetErrorString(
+ "We don't support returning complex values at present");
+ else
+ error.SetErrorString(
+ "We don't support returning float values at present");
+ }
+
+ if (!set_it_simple)
+ error.SetErrorString(
+ "We only support setting simple integer return types at present.");
+
+ return error;
}
ValueObjectSP
-ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
- CompilerType &compiler_type) const
-{
- Value value;
- ValueObjectSP return_valobj_sp;
-
- if (!compiler_type)
- return return_valobj_sp;
-
- //value.SetContext (Value::eContextTypeClangType, compiler_type.GetOpaqueQualType());
- value.SetCompilerType (compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- bool is_signed;
-
- if (compiler_type.IsIntegerOrEnumerationType (is_signed))
- {
- size_t bit_width = compiler_type.GetBitSize(&thread);
-
- unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
- unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
-
- switch (bit_width)
- {
- default:
- case 128:
- // Scalar can't hold 128-bit literals, so we don't handle this
- return return_valobj_sp;
- case 64:
- uint64_t raw_value;
- raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
- raw_value |= (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 0xffffffff) << 32;
- if (is_signed)
- value.GetScalar() = (int64_t)raw_value;
- else
- value.GetScalar() = (uint64_t)raw_value;
- break;
- case 32:
- if (is_signed)
- value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
- else
- value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
- break;
- case 16:
- if (is_signed)
- value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
- else
- value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
- break;
- case 8:
- if (is_signed)
- value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
- else
- value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
- break;
- }
- }
- else if (compiler_type.IsPointerType ())
- {
- unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
- uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
- value.GetScalar() = ptr;
- }
- else
- {
- // not handled yet
- return return_valobj_sp;
+ABIMacOSX_i386::GetReturnValueObjectImpl(Thread &thread,
+ CompilerType &compiler_type) const {
+ Value value;
+ ValueObjectSP return_valobj_sp;
+
+ if (!compiler_type)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType,
+ // compiler_type.GetOpaqueQualType());
+ value.SetCompilerType(compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ bool is_signed;
+
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
+ size_t bit_width = compiler_type.GetBitSize(&thread);
+
+ unsigned eax_id =
+ reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+ unsigned edx_id =
+ reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
+
+ switch (bit_width) {
+ default:
+ case 128:
+ // Scalar can't hold 128-bit literals, so we don't handle this
+ return return_valobj_sp;
+ case 64:
+ uint64_t raw_value;
+ raw_value =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff;
+ raw_value |=
+ (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) &
+ 0xffffffff)
+ << 32;
+ if (is_signed)
+ value.GetScalar() = (int64_t)raw_value;
+ else
+ value.GetScalar() = (uint64_t)raw_value;
+ break;
+ case 32:
+ if (is_signed)
+ value.GetScalar() = (int32_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff);
+ else
+ value.GetScalar() = (uint32_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff);
+ break;
+ case 16:
+ if (is_signed)
+ value.GetScalar() = (int16_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffff);
+ else
+ value.GetScalar() = (uint16_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffff);
+ break;
+ case 8:
+ if (is_signed)
+ value.GetScalar() = (int8_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xff);
+ else
+ value.GetScalar() = (uint8_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xff);
+ break;
}
-
- // If we get here, we have a valid Value, so make our ValueObject out of it:
-
- return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ } else if (compiler_type.IsPointerType()) {
+ unsigned eax_id =
+ reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+ uint32_t ptr =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff;
+ value.GetScalar() = ptr;
+ } else {
+ // not handled yet
return return_valobj_sp;
+ }
+
+ // If we get here, we have a valid Value, so make our ValueObject out of it:
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ return return_valobj_sp;
}
// This defines the CFA as esp+4
// the saved pc is at CFA-4 (i.e. esp+0)
// The saved esp is CFA+0
-bool
-ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t sp_reg_num = dwarf_esp;
- uint32_t pc_reg_num = dwarf_eip;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 4);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("i386 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- return true;
+bool ABIMacOSX_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t sp_reg_num = dwarf_esp;
+ uint32_t pc_reg_num = dwarf_eip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("i386 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
}
// This defines the CFA as ebp+8
@@ -526,119 +1045,99 @@ ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
// The saved ebp is at CFA-8 (i.e. ebp+0)
// The saved esp is CFA+0
-bool
-ABIMacOSX_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear ();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t fp_reg_num = dwarf_ebp;
- uint32_t sp_reg_num = dwarf_esp;
- uint32_t pc_reg_num = dwarf_eip;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 4;
-
- row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
- row->SetOffset (0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("i386 default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
+bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num = dwarf_ebp;
+ uint32_t sp_reg_num = dwarf_esp;
+ uint32_t pc_reg_num = dwarf_eip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 4;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("i386 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
}
-bool
-ABIMacOSX_i386::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- return !RegisterIsCalleeSaved (reg_info);
+bool ABIMacOSX_i386::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
-// v. http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
+// v.
+// http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
+//
+// This document ("OS X ABI Function Call Guide", chapter "IA-32 Function
+// Calling Conventions")
+// says that the following registers on i386 are preserved aka non-volatile aka
+// callee-saved:
//
-// This document ("OS X ABI Function Call Guide", chapter "IA-32 Function Calling Conventions")
-// says that the following registers on i386 are preserved aka non-volatile aka callee-saved:
-//
// ebx, ebp, esi, edi, esp
-bool
-ABIMacOSX_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Saved registers are ebx, ebp, esi, edi, esp, eip
- const char *name = reg_info->name;
- if (name[0] == 'e')
- {
- switch (name[1])
- {
- case 'b':
- if (name[2] == 'x' || name[2] == 'p')
- return name[3] == '\0';
- break;
- case 'd':
- if (name[2] == 'i')
- return name[3] == '\0';
- break;
- case 'i':
- if (name[2] == 'p')
- return name[3] == '\0';
- break;
- case 's':
- if (name[2] == 'i' || name[2] == 'p')
- return name[3] == '\0';
- break;
- }
- }
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
- if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
- return true;
+bool ABIMacOSX_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Saved registers are ebx, ebp, esi, edi, esp, eip
+ const char *name = reg_info->name;
+ if (name[0] == 'e') {
+ switch (name[1]) {
+ case 'b':
+ if (name[2] == 'x' || name[2] == 'p')
+ return name[3] == '\0';
+ break;
+ case 'd':
+ if (name[2] == 'i')
+ return name[3] == '\0';
+ break;
+ case 'i':
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+ case 's':
+ if (name[2] == 'i' || name[2] == 'p')
+ return name[3] == '\0';
+ break;
+ }
}
- return false;
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
+ }
+ return false;
}
-void
-ABIMacOSX_i386::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Mac OS X ABI for i386 targets",
- CreateInstance);
+void ABIMacOSX_i386::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "Mac OS X ABI for i386 targets", CreateInstance);
}
-void
-ABIMacOSX_i386::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABIMacOSX_i386::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABIMacOSX_i386::GetPluginNameStatic ()
-{
- static ConstString g_short_name("abi.macosx-i386");
- return g_short_name;
-
+lldb_private::ConstString ABIMacOSX_i386::GetPluginNameStatic() {
+ static ConstString g_short_name("abi.macosx-i386");
+ return g_short_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABIMacOSX_i386::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABIMacOSX_i386::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABIMacOSX_i386::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABIMacOSX_i386::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
index 6a82fce35bf7..4a2555ac61a2 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
@@ -14,116 +14,96 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/ABI.h"
#include "lldb/Core/Value.h"
-
-class ABIMacOSX_i386 :
- public lldb_private::ABI
-{
+#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
+
+class ABIMacOSX_i386 : public lldb_private::ABI {
public:
- ~ABIMacOSX_i386() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t func_addr,
- lldb::addr_t return_addr,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- // The Darwin i386 ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (4-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
- //
- // If we were to enforce 16-byte alignment, we also need to relax to 4-byte
- // alignment for non-darwin i386 targets.
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are are 4 byte aligned
- if (cfa & (4ull - 1ull))
- return false; // Not 4 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // Just make sure the address is a valid 32 bit address.
- return pc <= UINT32_MAX;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
+ ~ABIMacOSX_i386() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t func_addr, lldb::addr_t return_addr,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ // The Darwin i386 ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (4-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+ //
+ // If we were to enforce 16-byte alignment, we also need to relax to 4-byte
+ // alignment for non-darwin i386 targets.
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are are 4 byte aligned
+ if (cfa & (4ull - 1ull))
+ return false; // Not 4 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Just make sure the address is a valid 32 bit address.
+ return pc <= UINT32_MAX;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
protected:
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const override;
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const override;
- bool
- RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABIMacOSX_i386() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABIMacOSX_i386() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABIMacOSX_i386_h_
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index c23b41c11ccb..ebd0d17cf8ab 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -32,855 +32,1943 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
-#include "Plugins/Process/Utility/ARMDefines.h"
using namespace lldb;
using namespace lldb_private;
-static RegisterInfo g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
- // ========== ======= == === ============= ============ ======================= =================== =========================== ======================= ====================== ========== ===============
- { "r0", "arg1", 4, 0, eEncodingUint , eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r1", "arg2", 4, 0, eEncodingUint , eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r2", "arg3", 4, 0, eEncodingUint , eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r3", "arg4", 4, 0, eEncodingUint , eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r4", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r5", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r6", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r7", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12", nullptr, 4, 0, eEncodingUint , eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "sp", "r13", 4, 0, eEncodingUint , eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "lr", "r14", 4, 0, eEncodingUint , eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "pc", "r15", 4, 0, eEncodingUint , eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fpscr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12_usr", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_usr", "sp_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_usr", "lr_usr", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12_fiq", nullptr, 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_fiq", "sp_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_fiq", "lr_fiq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_irq", "sp_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_irq", "lr_irq", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_abt", "sp_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_abt", "lr_abt", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_und", "sp_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_und", "lr_und", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13_svc", "sp_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14_svc", "lr_svc", 4, 0, eEncodingUint , eFormatHex, { LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
+ // DWARF GENERIC PROCESS PLUGIN
+ // LLDB NATIVE VALUE REGS INVALIDATE REGS
+ // ========== ======= == === ============= ============
+ // ======================= =================== ===========================
+ // ======================= ====================== ==========
+ // ===============
+ {"r0",
+ "arg1",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ "arg2",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ "arg3",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ "arg4",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "r13",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r14",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "r15",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s0",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s1",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s2",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s3",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s4",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s5",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s6",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s7",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s8",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s9",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s10",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s11",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s12",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s13",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s14",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s15",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s16",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s17",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s18",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s19",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s20",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s21",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s22",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s23",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s24",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s25",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s26",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s27",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s28",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s29",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s30",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s31",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpscr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d0",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d1",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d2",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d3",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d4",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d5",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d6",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d7",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d8",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d9",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d16",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d17",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d18",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d19",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d20",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d21",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d22",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d23",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d24",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d25",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d26",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d27",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d28",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d29",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d30",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d31",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12_usr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_usr",
+ "sp_usr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_usr",
+ "lr_usr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12_fiq",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_fiq",
+ "sp_fiq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_fiq",
+ "lr_fiq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_irq",
+ "sp_irq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_irq",
+ "lr_irq",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_abt",
+ "sp_abt",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_abt",
+ "lr_abt",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_und",
+ "sp_und",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_und",
+ "lr_und",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13_svc",
+ "sp_svc",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14_svc",
+ "lr_svc",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABISysV_arm::GetRegisterInfoArray (uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABISysV_arm::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABISysV_arm::GetRedZoneSize () const
-{
- return 0;
-}
+size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_arm::CreateInstance (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);
- return g_abi_sp;
- }
+ABISysV_arm::CreateInstance(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);
+ return g_abi_sp;
}
+ }
- return ABISP();
+ return ABISP();
}
-bool
-ABISysV_arm::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t function_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
-
- const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
-
- RegisterValue reg_value;
-
- const uint8_t reg_names[] = { LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2, LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4 };
-
- llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
-
- for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i)
- {
- if (ai == ae)
- break;
-
- reg_value.SetUInt32(*ai);
- if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]), reg_value))
- return false;
-
- ++ai;
- }
-
- if (ai != ae)
- {
- // Spill onto the stack
- size_t num_stack_regs = ae - ai;
-
- sp -= (num_stack_regs * 4);
- // Keep the stack 8 byte aligned, not that we need to
- sp &= ~(8ull-1ull);
-
- // just using arg1 to get the right size
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
-
- addr_t arg_pos = sp;
-
- for (; ai != ae; ++ai)
- {
- reg_value.SetUInt32(*ai);
- if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
- return false;
- arg_pos += reg_info->byte_size;
- }
- }
-
- TargetSP target_sp (thread.CalculateTarget());
- Address so_addr;
-
- // Figure out if our return address is ARM or Thumb by using the
- // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
- // thumb-ness and set the correct address bits for us.
- so_addr.SetLoadAddress (return_addr, target_sp.get());
- return_addr = so_addr.GetCallableLoadAddress (target_sp.get());
-
- // Set "lr" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
- return false;
+bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t function_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
- return false;
-
- // If bit zero or 1 is set, this must be a thumb function, no need to figure
- // this out from the symbols.
- so_addr.SetLoadAddress (function_addr, target_sp.get());
- function_addr = so_addr.GetCallableLoadAddress (target_sp.get());
-
- const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
-
- // Make a new CPSR and mask out any Thumb IT (if/then) bits
- uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
- // If bit zero or 1 is set, this must be thumb...
- if (function_addr & 1ull)
- new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
- else
- new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
+ const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
- if (new_cpsr != curr_cpsr)
- {
- if (!reg_ctx->WriteRegisterFromUnsigned (cpsr_reg_info, new_cpsr))
- return false;
- }
+ RegisterValue reg_value;
+
+ const uint8_t reg_names[] = {
+ LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2,
+ LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4};
+
+ llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
- function_addr &= ~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))
+ for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
+ if (ai == ae)
+ break;
+
+ reg_value.SetUInt32(*ai);
+ if (!reg_ctx->WriteRegister(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
+ reg_value))
+ return false;
+
+ ++ai;
+ }
+
+ if (ai != ae) {
+ // Spill onto the stack
+ size_t num_stack_regs = ae - ai;
+
+ sp -= (num_stack_regs * 4);
+ // Keep the stack 8 byte aligned, not that we need to
+ sp &= ~(8ull - 1ull);
+
+ // just using arg1 to get the right size
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+
+ addr_t arg_pos = sp;
+
+ for (; ai != ae; ++ai) {
+ reg_value.SetUInt32(*ai);
+ if (reg_ctx
+ ->WriteRegisterValueToMemory(reg_info, arg_pos,
+ reg_info->byte_size, reg_value)
+ .Fail())
return false;
+ arg_pos += reg_info->byte_size;
+ }
+ }
+
+ TargetSP target_sp(thread.CalculateTarget());
+ Address so_addr;
- return true;
+ // Figure out if our return address is ARM or Thumb by using the
+ // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
+ // thumb-ness and set the correct address bits for us.
+ so_addr.SetLoadAddress(return_addr, target_sp.get());
+ return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
+
+ // Set "lr" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
+ return false;
+
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
+ return false;
+
+ // If bit zero or 1 is set, this must be a thumb function, no need to figure
+ // this out from the symbols.
+ so_addr.SetLoadAddress(function_addr, target_sp.get());
+ function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
+
+ const RegisterInfo *cpsr_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
+
+ // Make a new CPSR and mask out any Thumb IT (if/then) bits
+ uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
+ // If bit zero or 1 is set, this must be thumb...
+ if (function_addr & 1ull)
+ new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
+ else
+ new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
+
+ if (new_cpsr != curr_cpsr) {
+ if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
+ return false;
+ }
+
+ function_addr &=
+ ~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;
}
-bool
-ABISysV_arm::GetArgumentValues (Thread &thread,
- ValueList &values) const
-{
- uint32_t num_values = values.GetSize();
-
- ExecutionContext exe_ctx (thread.shared_from_this());
- // For now, assume that the types in the AST values come from the Target's
- // scratch AST.
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
+bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
+ uint32_t num_values = values.GetSize();
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ // For now, assume that the types in the AST values come from the Target's
+ // scratch AST.
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ addr_t sp = 0;
+
+ for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ Value *value = values.GetValueAtIndex(value_idx);
+
+ if (!value)
+ return false;
+
+ CompilerType compiler_type = value->GetCompilerType();
+ 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 {
+ // We only handle integer, pointer and reference types currently...
return false;
-
- addr_t sp = 0;
-
- for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
- {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- Value *value = values.GetValueAtIndex(value_idx);
-
- if (!value)
- return false;
-
- CompilerType compiler_type = value->GetCompilerType();
- 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
- {
- // We only handle integer, pointer and reference types currently...
+ }
+
+ if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
+ if (value_idx < 4) {
+ // Arguments 1-4 are in r0-r3...
+ const RegisterInfo *arg_reg_info = nullptr;
+ arg_reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
+ if (arg_reg_info) {
+ RegisterValue reg_value;
+
+ if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
+ if (is_signed)
+ reg_value.SignExtend(bit_width);
+ if (!reg_value.GetScalarValue(value->GetScalar()))
return false;
+ continue;
}
-
- if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
- {
- if (value_idx < 4)
- {
- // Arguments 1-4 are in r0-r3...
- const RegisterInfo *arg_reg_info = nullptr;
- arg_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
- if (arg_reg_info)
- {
- RegisterValue reg_value;
-
- if (reg_ctx->ReadRegister(arg_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 it already hasn't been read
- sp = reg_ctx->GetSP(0);
- if (sp == 0)
- return false;
- }
-
- // Arguments 5 on up are on the stack
- const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
- Error error;
- if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
- return false;
-
- sp += arg_byte_size;
- }
- }
+ }
+ return false;
+ } else {
+ if (sp == 0) {
+ // Read the stack pointer if it already hasn't been read
+ sp = reg_ctx->GetSP(0);
+ if (sp == 0)
+ return false;
+ }
+
+ // Arguments 5 on up are on the stack
+ const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
+ sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ return false;
+
+ sp += arg_byte_size;
}
+ }
}
- return true;
+ }
+ return true;
}
-static bool
-GetReturnValuePassedInMemory(Thread &thread, RegisterContext* reg_ctx, size_t byte_size, Value& value)
-{
- Error error;
- DataBufferHeap buffer(byte_size, 0);
+static bool GetReturnValuePassedInMemory(Thread &thread,
+ RegisterContext *reg_ctx,
+ size_t byte_size, Value &value) {
+ Error error;
+ DataBufferHeap buffer(byte_size, 0);
- const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
- uint32_t address = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- thread.GetProcess()->ReadMemory(address, buffer.GetBytes(), buffer.GetByteSize(), error);
+ const RegisterInfo *r0_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+ uint32_t address =
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
+ thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
+ buffer.GetByteSize(), error);
- if (error.Fail())
- return false;
+ if (error.Fail())
+ return false;
- value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
- return true;
+ value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
+ return true;
}
-bool
-ABISysV_arm::IsArmHardFloat (Thread &thread) const
-{
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- const ArchSpec &arch (process_sp->GetTarget().GetArchitecture());
+bool ABISysV_arm::IsArmHardFloat(Thread &thread) const {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
- return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
- }
+ return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
+ }
- return false;
+ return false;
}
-ValueObjectSP
-ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
- lldb_private::CompilerType &compiler_type) const
-{
- Value value;
- ValueObjectSP return_valobj_sp;
-
- if (!compiler_type)
+ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
+ Thread &thread, lldb_private::CompilerType &compiler_type) const {
+ Value value;
+ ValueObjectSP return_valobj_sp;
+
+ if (!compiler_type)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType,
+ // compiler_type.GetOpaqueQualType());
+ value.SetCompilerType(compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ bool is_signed;
+ bool is_complex;
+ uint32_t float_count;
+ bool is_vfp_candidate = false;
+ uint8_t vfp_count = 0;
+ uint8_t vfp_byte_size = 0;
+
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
+
+ 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);
+
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
+ switch (bit_width) {
+ default:
+ return return_valobj_sp;
+ case 64: {
+ const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ uint64_t raw_value;
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
+ raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
+ UINT32_MAX))
+ << 32;
+ if (is_signed)
+ value.GetScalar() = (int64_t)raw_value;
+ else
+ value.GetScalar() = (uint64_t)raw_value;
+ } break;
+ case 32:
+ if (is_signed)
+ value.GetScalar() = (int32_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
+ break;
+ case 16:
+ if (is_signed)
+ value.GetScalar() = (int16_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
+ break;
+ case 8:
+ if (is_signed)
+ value.GetScalar() = (int8_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
+ break;
+ }
+ } else if (compiler_type.IsPointerType()) {
+ uint32_t ptr =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
+ UINT32_MAX;
+ value.GetScalar() = ptr;
+ } else if (compiler_type.IsVectorType(nullptr, nullptr)) {
+ 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) {
+ DataBufferHeap buffer(16, 0);
+ uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
+
+ 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);
+ } else {
+ if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
return return_valobj_sp;
-
- //value.SetContext (Value::eContextTypeClangType, compiler_type.GetOpaqueQualType());
- value.SetCompilerType (compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
+ }
+ } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
+ if (float_count == 1 && !is_complex) {
+ switch (bit_width) {
+ default:
return return_valobj_sp;
-
- bool is_signed;
- bool is_complex;
- uint32_t float_count;
- bool is_vfp_candidate = false;
- uint8_t vfp_count = 0;
- uint8_t vfp_byte_size = 0;
-
- // Get the pointer to the first stack argument so we have a place to start
- // when reading data
-
- 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);
-
- if (compiler_type.IsIntegerOrEnumerationType (is_signed))
- {
- switch (bit_width)
- {
- default:
- return return_valobj_sp;
- case 64:
- {
- const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
- uint64_t raw_value;
- raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
- if (is_signed)
- value.GetScalar() = (int64_t)raw_value;
- else
- value.GetScalar() = (uint64_t)raw_value;
- }
- break;
- case 32:
- if (is_signed)
- value.GetScalar() = (int32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
- break;
- case 16:
- if (is_signed)
- value.GetScalar() = (int16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
- break;
- case 8:
- if (is_signed)
- value.GetScalar() = (int8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
- break;
+ case 64: {
+ static_assert(sizeof(double) == sizeof(uint64_t), "");
+
+ if (IsArmHardFloat(thread)) {
+ RegisterValue reg_value;
+ const RegisterInfo *d0_reg_info =
+ reg_ctx->GetRegisterInfoByName("d0", 0);
+ reg_ctx->ReadRegister(d0_reg_info, reg_value);
+ value.GetScalar() = reg_value.GetAsDouble();
+ } else {
+ uint64_t raw_value;
+ const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ raw_value =
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
+ raw_value |=
+ ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
+ UINT32_MAX))
+ << 32;
+ value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
}
- }
- else if (compiler_type.IsPointerType ())
- {
- uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- value.GetScalar() = ptr;
- }
- else if (compiler_type.IsVectorType(nullptr, nullptr))
- {
- if (IsArmHardFloat(thread) && (byte_size == 8 || byte_size == 16))
- {
+ break;
+ }
+ case 16: // Half precision returned after a conversion to single precision
+ case 32: {
+ static_assert(sizeof(float) == sizeof(uint32_t), "");
+
+ if (IsArmHardFloat(thread)) {
+ RegisterValue reg_value;
+ const RegisterInfo *s0_reg_info =
+ reg_ctx->GetRegisterInfoByName("s0", 0);
+ reg_ctx->ReadRegister(s0_reg_info, reg_value);
+ value.GetScalar() = reg_value.GetAsFloat();
+ } else {
+ uint32_t raw_value;
+ raw_value =
+ reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
+ value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
+ }
+ break;
+ }
+ }
+ } else if (is_complex && float_count == 2) {
+ if (IsArmHardFloat(thread)) {
+ is_vfp_candidate = true;
+ vfp_byte_size = byte_size / 2;
+ vfp_count = 2;
+ } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, bit_width / 8,
+ value))
+ return return_valobj_sp;
+ } else
+ // not handled yet
+ return return_valobj_sp;
+ } else if (compiler_type.IsAggregateType()) {
+ if (IsArmHardFloat(thread)) {
+ CompilerType base_type;
+ const uint32_t homogeneous_count =
+ compiler_type.IsHomogeneousAggregate(&base_type);
+
+ if (homogeneous_count > 0 && homogeneous_count <= 4) {
+ if (base_type.IsVectorType(nullptr, nullptr)) {
+ uint64_t base_byte_size = base_type.GetByteSize(nullptr);
+ if (base_byte_size == 8 || base_byte_size == 16) {
is_vfp_candidate = true;
vfp_byte_size = 8;
- 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)
- {
- 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);
- }
- else
- {
- 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)
- {
- default:
- return return_valobj_sp;
- case 64:
- {
- static_assert(sizeof(double) == sizeof(uint64_t), "");
-
- if (IsArmHardFloat(thread))
- {
- RegisterValue reg_value;
- const RegisterInfo *d0_reg_info = reg_ctx->GetRegisterInfoByName("d0", 0);
- reg_ctx->ReadRegister(d0_reg_info, reg_value);
- value.GetScalar() = reg_value.GetAsDouble();
- }
- else
- {
- uint64_t raw_value;
- const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
- raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
- value.GetScalar() = *reinterpret_cast<double*>(&raw_value);
- }
- break;
- }
- case 16: // Half precision returned after a conversion to single precision
- case 32:
- {
- static_assert(sizeof(float) == sizeof(uint32_t), "");
-
- if (IsArmHardFloat(thread))
- {
- RegisterValue reg_value;
- const RegisterInfo *s0_reg_info = reg_ctx->GetRegisterInfoByName("s0", 0);
- reg_ctx->ReadRegister(s0_reg_info, reg_value);
- value.GetScalar() = reg_value.GetAsFloat();
- }
- else
- {
- uint32_t raw_value;
- raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- value.GetScalar() = *reinterpret_cast<float*>(&raw_value);
- }
- break;
- }
- }
- }
- else if (is_complex && float_count == 2)
- {
- if (IsArmHardFloat(thread))
- {
- is_vfp_candidate = true;
- vfp_byte_size = byte_size / 2;
- vfp_count = 2;
- }
- else if (!GetReturnValuePassedInMemory(thread, reg_ctx, bit_width / 8, value))
- return return_valobj_sp;
- }
- else
- // not handled yet
- return return_valobj_sp;
- }
- else if (compiler_type.IsAggregateType())
- {
- if (IsArmHardFloat(thread))
- {
- CompilerType base_type;
- const uint32_t homogeneous_count = compiler_type.IsHomogeneousAggregate (&base_type);
-
- if (homogeneous_count > 0 && homogeneous_count <= 4)
- {
- if (base_type.IsVectorType(nullptr, nullptr))
- {
- uint64_t base_byte_size = base_type.GetByteSize(nullptr);
- if (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);
- }
- }
- 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);
- vfp_count = homogeneous_count;
- }
- }
- }
- else if (homogeneous_count == 0)
- {
- const uint32_t num_children = compiler_type.GetNumFields ();
-
- if (num_children > 0 && num_children <=2)
- {
- uint32_t index = 0;
- for (index = 0; index < num_children; index++)
- {
- std::string name;
- base_type = compiler_type.GetFieldAtIndex (index, name, NULL, NULL, NULL);
-
- if (base_type.IsFloatingPointType(float_count, is_complex))
- {
- if (float_count == 2 && is_complex)
- {
- if (index != 0 && vfp_byte_size != base_type.GetByteSize(nullptr))
- break;
- else
- vfp_byte_size = base_type.GetByteSize(nullptr);
- }
- else
- break;
- }
- else
- break;
- }
-
- if (index == num_children)
- {
- is_vfp_candidate = true;
- vfp_byte_size = (vfp_byte_size >> 1);
- vfp_count = (num_children << 1);
- }
- }
- }
+ vfp_count =
+ (base_type.GetByteSize(nullptr) == 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);
+ vfp_count = homogeneous_count;
+ }
}
+ } else if (homogeneous_count == 0) {
+ const uint32_t num_children = compiler_type.GetNumFields();
+
+ if (num_children > 0 && num_children <= 2) {
+ uint32_t index = 0;
+ for (index = 0; index < num_children; index++) {
+ std::string name;
+ base_type =
+ compiler_type.GetFieldAtIndex(index, name, NULL, NULL, NULL);
+
+ if (base_type.IsFloatingPointType(float_count, is_complex)) {
+ if (float_count == 2 && is_complex) {
+ if (index != 0 &&
+ vfp_byte_size != base_type.GetByteSize(nullptr))
+ break;
+ else
+ vfp_byte_size = base_type.GetByteSize(nullptr);
+ } else
+ break;
+ } else
+ break;
+ }
- 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);
- }
- else if (!is_vfp_candidate)
- {
- if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
- return return_valobj_sp;
+ if (index == num_children) {
+ is_vfp_candidate = true;
+ vfp_byte_size = (vfp_byte_size >> 1);
+ vfp_count = (num_children << 1);
+ }
}
+ }
}
- else
- {
- // not handled yet
+
+ 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);
+ } else if (!is_vfp_candidate) {
+ if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
return return_valobj_sp;
}
-
- if (is_vfp_candidate)
- {
- ProcessSP process_sp (thread.GetProcess());
- ByteOrder byte_order = process_sp->GetByteOrder();
-
- 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++)
- {
- uint32_t regnum = 0;
-
- if (vfp_byte_size == 4)
- regnum = dwarf_s0 + reg_index;
- else if (vfp_byte_size == 8)
- regnum = dwarf_d0 + reg_index;
- else
- break;
-
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo (eRegisterKindDWARF, regnum);
- if (reg_info == NULL)
- break;
-
- RegisterValue reg_value;
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- break;
-
- // Make sure we have enough room in "data_sp"
- if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize())
- {
- Error error;
- const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
- data_sp->GetBytes() + data_offset,
- vfp_byte_size,
- byte_order,
- error);
- if (bytes_copied != vfp_byte_size)
- break;
-
- data_offset += bytes_copied;
- }
- }
+ } else {
+ // not handled yet
+ return return_valobj_sp;
+ }
+
+ if (is_vfp_candidate) {
+ ProcessSP process_sp(thread.GetProcess());
+ ByteOrder byte_order = process_sp->GetByteOrder();
+
+ 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++) {
+ uint32_t regnum = 0;
+
+ if (vfp_byte_size == 4)
+ regnum = dwarf_s0 + reg_index;
+ else if (vfp_byte_size == 8)
+ regnum = dwarf_d0 + reg_index;
+ else
+ break;
+
+ const RegisterInfo *reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
+ if (reg_info == NULL)
+ break;
+
+ RegisterValue reg_value;
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ break;
+
+ // Make sure we have enough room in "data_sp"
+ if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
+ Error error;
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
+ byte_order, error);
+ if (bytes_copied != vfp_byte_size)
+ break;
+
+ data_offset += bytes_copied;
+ }
+ }
- if (data_offset == byte_size)
- {
- DataExtractor data;
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(process_sp->GetAddressByteSize());
- data.SetData(data_sp);
+ if (data_offset == byte_size) {
+ DataExtractor data;
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(process_sp->GetAddressByteSize());
+ data.SetData(data_sp);
- return ValueObjectConstResult::Create (&thread, compiler_type, ConstString(""), data);
- }
- else
- { // Some error occurred while getting values from registers
- return return_valobj_sp;
- }
+ return ValueObjectConstResult::Create(&thread, compiler_type,
+ ConstString(""), data);
+ } else { // Some error occurred while getting values from registers
+ return return_valobj_sp;
}
+ }
- // If we get here, we have a valid Value, so make our ValueObject out of it:
-
- return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- return return_valobj_sp;
+ // If we get here, we have a valid Value, so make our ValueObject out of it:
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ return return_valobj_sp;
}
-Error
-ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
-
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
+Error ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
}
-
- Thread *thread = frame_sp->GetThread().get();
-
- bool is_signed;
- uint32_t count;
- bool is_complex;
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
-
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
- {
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+ if (num_bytes <= 4) {
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
+ set_it_simple = true;
+ } else {
+ uint32_t raw_value = data.GetMaxU32(&offset, 4);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
+ const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
+ set_it_simple = true;
}
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
- if (num_bytes <= 4)
- {
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- uint32_t raw_value = data.GetMaxU32(&offset, 4);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
- {
- const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value))
- set_it_simple = true;
- }
- }
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
- }
- }
- else if (compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (is_complex)
- error.SetErrorString ("We don't support returning complex values at present");
- else
- error.SetErrorString ("We don't support returning float values at present");
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
}
-
- if (!set_it_simple)
- error.SetErrorString ("We only support setting simple integer return types at present.");
-
- return error;
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ error.SetErrorString(
+ "We don't support returning complex values at present");
+ else
+ error.SetErrorString(
+ "We don't support returning float values at present");
+ }
+
+ if (!set_it_simple)
+ error.SetErrorString(
+ "We only support setting simple integer return types at present.");
+
+ return error;
}
-bool
-ABISysV_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t lr_reg_num = dwarf_lr;
- uint32_t sp_reg_num = dwarf_sp;
- uint32_t pc_reg_num = dwarf_pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our Call Frame Address is the stack pointer value
- row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
-
- // The previous PC is in the LR
- row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
- unwind_plan.AppendRow (row);
-
- // All other registers are the same.
-
- unwind_plan.SetSourceName ("arm at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
-
- return true;
+bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t lr_reg_num = dwarf_lr;
+ uint32_t sp_reg_num = dwarf_sp;
+ uint32_t pc_reg_num = dwarf_pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our Call Frame Address is the stack pointer value
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ // The previous PC is in the LR
+ row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+ unwind_plan.AppendRow(row);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName("arm at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
}
-bool
-ABISysV_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear ();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- //TODO: Handle thumb
- uint32_t fp_reg_num = dwarf_r11;
- uint32_t pc_reg_num = dwarf_pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 4;
-
- row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
- row->SetOffset (0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("arm default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
-
- return true;
+bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ // TODO: Handle thumb
+ uint32_t fp_reg_num = dwarf_r11;
+ uint32_t pc_reg_num = dwarf_pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 4;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("arm default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+
+ return true;
}
// cf. "ARMv6 Function Calling Conventions"
@@ -899,210 +1987,179 @@ ABISysV_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
// d8-d15 preserved (aka s16-s31, q4-q7)
// d16-d31 not preserved (aka q8-q15)
-bool
-ABISysV_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
- const char *name = reg_info->name;
- if (name[0] == 'r')
- {
- switch (name[1])
- {
- case '0': return name[2] == '\0'; // r0
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // r1
- case '2':
- return name[3] == '\0'; // r12
- default:
- break;
- }
- break;
-
- case '2': return name[2] == '\0'; // r2
- case '3': return name[2] == '\0'; // r3
- default:
- break;
- }
+bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
+ const char *name = reg_info->name;
+ if (name[0] == 'r') {
+ switch (name[1]) {
+ case '0':
+ return name[2] == '\0'; // r0
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // r1
+ case '2':
+ return name[3] == '\0'; // r12
+ default:
+ break;
}
- else if (name[0] == 'd')
- {
- switch (name[1])
- {
- case '0':
- return name[2] == '\0'; // d0 is volatile
-
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // d1 is volatile
- case '6':
- case '7':
- case '8':
- case '9':
- return name[3] == '\0'; // d16 - d19 are volatile
- default:
- break;
- }
- break;
-
- case '2':
- switch (name[2])
- {
- case '\0':
- return true; // d2 is volatile
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return name[3] == '\0'; // d20 - d29 are volatile
- default:
- break;
- }
- break;
-
- case '3':
- switch (name[2])
- {
- case '\0':
- return true; // d3 is volatile
- case '0':
- case '1':
- return name[3] == '\0'; // d30 - d31 are volatile
- default:
- break;
- }
- break;
- case '4':
- case '5':
- case '6':
- case '7':
- return name[2] == '\0'; // d4 - d7 are volatile
-
- default:
- break;
- }
+ break;
+
+ case '2':
+ return name[2] == '\0'; // r2
+ case '3':
+ return name[2] == '\0'; // r3
+ default:
+ break;
+ }
+ } else if (name[0] == 'd') {
+ switch (name[1]) {
+ case '0':
+ return name[2] == '\0'; // d0 is volatile
+
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // d1 is volatile
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d16 - d19 are volatile
+ default:
+ break;
}
- else if (name[0] == 's')
- {
- switch (name[1])
- {
- case '0':
- return name[2] == '\0'; // s0 is volatile
-
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // s1 is volatile
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return name[3] == '\0'; // s10 - s15 are volatile
- default:
- break;
- }
- break;
-
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return name[2] == '\0'; // s2 - s9 are volatile
-
- default:
- break;
- }
+ break;
+
+ case '2':
+ switch (name[2]) {
+ case '\0':
+ return true; // d2 is volatile
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d20 - d29 are volatile
+ default:
+ break;
}
- else if (name[0] == 'q')
- {
- switch (name[1])
- {
- case '1':
- switch (name[2])
- {
- case '\0':
- return true; // q1 is volatile
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return true; // q10-q15 are volatile
- default:
- return false;
- }
- break;
-
- case '0':
- case '2':
- case '3':
- return name[2] == '\0'; // q0-q3 are volatile
- case '8':
- case '9':
- return name[2] == '\0'; // q8-q9 are volatile
- default:
- break;
- }
+ break;
+
+ case '3':
+ switch (name[2]) {
+ case '\0':
+ return true; // d3 is volatile
+ case '0':
+ case '1':
+ return name[3] == '\0'; // d30 - d31 are volatile
+ default:
+ break;
}
- else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
- return true;
- }
- return false;
+ break;
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return name[2] == '\0'; // d4 - d7 are volatile
+
+ default:
+ break;
+ }
+ } else if (name[0] == 's') {
+ switch (name[1]) {
+ case '0':
+ return name[2] == '\0'; // s0 is volatile
+
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // s1 is volatile
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return name[3] == '\0'; // s10 - s15 are volatile
+ default:
+ break;
+ }
+ break;
+
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[2] == '\0'; // s2 - s9 are volatile
+
+ default:
+ break;
+ }
+ } else if (name[0] == 'q') {
+ switch (name[1]) {
+ case '1':
+ switch (name[2]) {
+ case '\0':
+ return true; // q1 is volatile
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return true; // q10-q15 are volatile
+ default:
+ return false;
+ }
+ break;
+
+ case '0':
+ case '2':
+ case '3':
+ return name[2] == '\0'; // q0-q3 are volatile
+ case '8':
+ case '9':
+ return name[2] == '\0'; // q8-q9 are volatile
+ default:
+ break;
+ }
+ } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
+ return true;
+ }
+ return false;
}
-void
-ABISysV_arm::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "SysV ABI for arm targets",
- CreateInstance);
+void ABISysV_arm::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "SysV ABI for arm targets", CreateInstance);
}
-void
-ABISysV_arm::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_arm::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_arm::GetPluginNameStatic()
-{
- static ConstString g_name("SysV-arm");
- return g_name;
+lldb_private::ConstString ABISysV_arm::GetPluginNameStatic() {
+ static ConstString g_name("SysV-arm");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_arm::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_arm::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_arm::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_arm::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
index 11a2601501e4..d85b3dff0ca5 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
@@ -14,111 +14,89 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_arm : public lldb_private::ABI
-{
+class ABISysV_arm : public lldb_private::ABI {
public:
- ~ABISysV_arm() override = default;
-
- size_t
- GetRedZoneSize () const override;
-
- bool
- PrepareTrivialCall (lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t func_addr,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues (lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- bool
- CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info) override;
-
- bool
- CallFrameAddressIsValid (lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are are 4 byte aligned
- if (cfa & (4ull - 1ull))
- return false; // Not 4 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid (lldb::addr_t pc) override
- {
- // Just make sure the address is a valid 32 bit address. Bit zero
- // might be set due to Thumb function calls, so don't enforce 2 byte
- // alignment
- return pc <= UINT32_MAX;
- }
-
- lldb::addr_t
- FixCodeAddress (lldb::addr_t pc) override
- {
- // ARM uses bit zero to signify a code address is thumb, so we must
- // strip bit zero in any code addresses.
- return pc & ~(lldb::addr_t)1;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray (uint32_t &count) override;
-
- bool
- IsArmHardFloat (lldb_private::Thread &thread) const;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
+ ~ABISysV_arm() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t func_addr, lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are are 4 byte aligned
+ if (cfa & (4ull - 1ull))
+ return false; // Not 4 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Just make sure the address is a valid 32 bit address. Bit zero
+ // might be set due to Thumb function calls, so don't enforce 2 byte
+ // alignment
+ return pc <= UINT32_MAX;
+ }
+
+ lldb::addr_t FixCodeAddress(lldb::addr_t pc) override {
+ // ARM uses bit zero to signify a code address is thumb, so we must
+ // strip bit zero in any code addresses.
+ return pc & ~(lldb::addr_t)1;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ bool IsArmHardFloat(lldb_private::Thread &thread) const;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
protected:
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const override;
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_arm() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_arm_h_
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index e4ed523b9d0a..5e2179212be9 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -38,1045 +38,2389 @@
using namespace lldb;
using namespace lldb_private;
-static RegisterInfo g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE
- // ========== ======= == === ============= =================== =================== ====================== =========================== ======================= ======================
- { "x0", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x1", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x2", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x3", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x4", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x5", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x6", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x7", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x8", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x9", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x10", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x11", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x12", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x13", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x14", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x15", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x16", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x17", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x18", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x19", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x20", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x21", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x22", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x23", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x24", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x25", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x26", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x27", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "x28", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fp", "x29", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "lr", "x30", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "sp", "x31", 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "pc", nullptr, 8, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cpsr", "psr", 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "v0", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v1", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v2", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v3", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v4", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v5", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v6", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v7", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v8", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v9", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v10", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v11", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v12", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v13", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v14", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v15", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v16", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v17", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v18", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v19", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v20", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v21", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v22", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v23", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v24", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v25", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v26", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v27", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v28", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v29", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v30", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "v31", nullptr, 16, 0, eEncodingVector , eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "fpsr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fpcr", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "s0", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s1", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s2", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s3", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s4", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s5", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s6", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s7", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s8", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s9", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s10", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s11", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s12", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s13", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s14", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s15", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s16", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s17", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s18", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s19", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s20", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s21", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s22", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s23", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s24", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s25", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s26", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s27", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s28", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s29", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s30", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "s31", nullptr, 4, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
-
- { "d0", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d1", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d2", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d3", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d4", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d5", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d6", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d7", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d8", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d9", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d10", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d11", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d12", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d13", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d14", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d15", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d16", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d17", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d18", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d19", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d20", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d21", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d22", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d23", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d24", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d25", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d26", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d27", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d28", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d29", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d30", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "d31", nullptr, 8, 0, eEncodingIEEE754 , eFormatFloat , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT
+ // EH_FRAME DWARF GENERIC
+ // PROCESS PLUGIN LLDB NATIVE
+ // ========== ======= == === ============= ===================
+ // =================== ====================== ===========================
+ // ======================= ======================
+ {"x0",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x1",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x2",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x3",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x4",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x5",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x6",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x7",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x8",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x9",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x16",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x17",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x18",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x19",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x20",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x21",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x22",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x23",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x24",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x25",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x26",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x27",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"x28",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fp",
+ "x29",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "x30",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "x31",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"v0",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v1",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v2",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v3",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v4",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v5",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v6",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v7",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v8",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v9",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v10",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v11",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v12",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v13",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v14",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v15",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v16",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v17",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v18",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v19",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v20",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v21",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v22",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v23",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v24",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v25",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v26",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v27",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v28",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v29",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v30",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"v31",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"fpsr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpcr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"s0",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s1",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s2",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s3",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s4",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s5",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s6",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s7",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s8",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s9",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s10",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s11",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s12",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s13",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s14",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s15",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s16",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s17",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s18",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s19",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s20",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s21",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s22",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s23",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s24",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s25",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s26",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s27",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s28",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s29",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s30",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s31",
+ nullptr,
+ 4,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"d0",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d1",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d2",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d3",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d4",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d5",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d6",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d7",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d8",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d9",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d16",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d17",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d18",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d19",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d20",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d21",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d22",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d23",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d24",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d25",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d26",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d27",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d28",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d29",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d30",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"d31",
+ nullptr,
+ 8,
+ 0,
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABISysV_arm64::GetRegisterInfoArray (uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABISysV_arm64::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABISysV_arm64::GetRedZoneSize () const
-{
- return 128;
+bool ABISysV_arm64::GetPointerReturnRegister(const char *&name) {
+ name = "x0";
+ return true;
}
+size_t ABISysV_arm64::GetRedZoneSize() const { return 128; }
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_arm64::CreateInstance (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);
- return g_abi_sp;
- }
+ABISysV_arm64::CreateInstance(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);
+ return g_abi_sp;
}
+ }
- return ABISP();
+ return ABISP();
}
-bool
-ABISysV_arm64::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
+bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ // x0 - x7 contain first 8 simple args
+ if (args.size() > 8)
+ return false;
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
if (log)
- {
- StreamString s;
- s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(),
- (uint64_t)sp,
- (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf (", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
- s.PutCString (")");
- log->PutCString(s.GetString().c_str());
- }
+ log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
+ static_cast<int>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
+
+ // Set "lr" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA),
+ return_addr))
+ return false;
+
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP),
+ sp))
+ return false;
+
+ // Set "pc" to the address requested
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC),
+ func_addr))
+ return false;
+
+ return true;
+}
- // x0 - x7 contain first 8 simple args
- if (args.size() > 8)
- return false;
+// TODO: We dont support fp/SIMD arguments in v0-v7
+bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const {
+ uint32_t num_values = values.GetSize();
- for (size_t i = 0; i < args.size(); ++i)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
+ ExecutionContext exe_ctx(thread.shared_from_this());
- // Set "lr" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA), return_addr))
- return false;
+ // Extract the register context so we can read arguments from registers
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP), sp))
- return false;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- // Set "pc" to the address requested
- if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC), func_addr))
- return false;
+ if (!reg_ctx)
+ return false;
- return true;
-}
+ addr_t sp = 0;
+
+ for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ Value *value = values.GetValueAtIndex(value_idx);
+
+ if (!value)
+ return false;
-//TODO: We dont support fp/SIMD arguments in v0-v7
-bool
-ABISysV_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
-{
- uint32_t num_values = values.GetSize();
-
- ExecutionContext exe_ctx (thread.shared_from_this());
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
+ 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;
+ }
- addr_t sp = 0;
+ if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
+ if (value_idx < 8) {
+ // Arguments 1-8 are in x0-x7...
+ const RegisterInfo *reg_info = nullptr;
+ reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
- for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
- {
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- Value *value = values.GetValueAtIndex(value_idx);
-
- if (!value)
- 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...
+ 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;
}
-
- if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
- {
- if (value_idx < 8)
- {
- // Arguments 1-8 are in x0-x7...
- const RegisterInfo *reg_info = nullptr;
- reg_info= reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
-
- 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
- {
- //TODO: Verify for stack layout for SysV
- if (sp == 0)
- {
- // Read the stack pointer if we already haven't read it
- sp = reg_ctx->GetSP(0);
- if (sp == 0)
- return false;
- }
+ }
+ return false;
+ } else {
+ // TODO: Verify for stack layout for SysV
+ if (sp == 0) {
+ // Read the stack pointer if we already haven't read it
+ sp = reg_ctx->GetSP(0);
+ if (sp == 0)
+ return false;
+ }
+
+ // Arguments 5 on up are on the stack
+ const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
+ sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ return false;
- // Arguments 5 on up are on the stack
- const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
- Error 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;
- }
- }
- }
+ sp += arg_byte_size;
+ // Align up to the next 8 byte boundary if needed
+ if (sp % 8) {
+ sp >>= 3;
+ sp += 1;
+ sp <<= 3;
+ }
}
+ }
}
- return true;
+ }
+ return true;
}
-Error
-ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
-
- CompilerType return_value_type = new_value_sp->GetCompilerType();
- if (!return_value_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
+Error ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- Thread *thread = frame_sp->GetThread().get();
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
-
- if (reg_ctx)
- {
- DataExtractor data;
- Error data_error;
- const uint64_t byte_size = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
+ CompilerType return_value_type = new_value_sp->GetCompilerType();
+ if (!return_value_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
- const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar ||
- type_flags & eTypeIsPointer)
- {
- if (type_flags & eTypeIsInteger ||
- type_flags & eTypeIsPointer )
- {
- // Extract the register context so we can read arguments from registers
- lldb::offset_t offset = 0;
- if (byte_size <= 16)
- {
- const RegisterInfo *x0_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
- if (byte_size <= 8)
- {
- uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
-
- if (!reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
- error.SetErrorString ("failed to write register x0");
- }
- else
- {
- uint64_t raw_value = data.GetMaxU64(&offset, 8);
-
- if (reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
- {
- const RegisterInfo *x1_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
- raw_value = data.GetMaxU64(&offset, byte_size - offset);
-
- if (!reg_ctx->WriteRegisterFromUnsigned (x1_info, raw_value))
- error.SetErrorString ("failed to write register x1");
- }
- }
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 128 bit integer values at present.");
- }
+ Thread *thread = frame_sp->GetThread().get();
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ if (reg_ctx) {
+ DataExtractor data;
+ Error data_error;
+ const uint64_t byte_size = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+
+ const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ // Extract the register context so we can read arguments from registers
+ lldb::offset_t offset = 0;
+ if (byte_size <= 16) {
+ const RegisterInfo *x0_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+ if (byte_size <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value))
+ error.SetErrorString("failed to write register x0");
+ } else {
+ uint64_t raw_value = data.GetMaxU64(&offset, 8);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) {
+ const RegisterInfo *x1_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ raw_value = data.GetMaxU64(&offset, byte_size - offset);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value))
+ error.SetErrorString("failed to write register x1");
}
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- error.SetErrorString ("returning complex float values are not supported");
- }
- else
- {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info)
- {
- if (byte_size <= 16)
- {
- if (byte_size <= RegisterValue::GetMaxByteSize())
- {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData (v0_info, data, 0, true);
- if (error.Success())
- {
- if (!reg_ctx->WriteRegister (v0_info, reg_value))
- error.SetErrorString ("failed to write register v0");
- }
- }
- else
- {
- error.SetErrorStringWithFormat ("returning float values with a byte size of %" PRIu64 " are not supported", byte_size);
- }
- }
- else
- {
- error.SetErrorString("returning float values longer than 128 bits are not supported");
- }
- }
- else
- {
- error.SetErrorString("v0 register is not available on this target");
- }
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 128 bit "
+ "integer values at present.");
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ error.SetErrorString(
+ "returning complex float values are not supported");
+ } else {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= 16) {
+ if (byte_size <= RegisterValue::GetMaxByteSize()) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
}
+ } else {
+ error.SetErrorStringWithFormat(
+ "returning float values with a byte size of %" PRIu64
+ " are not supported",
+ byte_size);
+ }
+ } else {
+ error.SetErrorString("returning float values longer than 128 "
+ "bits are not supported");
}
+ } else {
+ error.SetErrorString("v0 register is not available on this target");
+ }
}
- else if (type_flags & eTypeIsVector)
- {
- if (byte_size > 0)
- {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info)
- {
- if (byte_size <= v0_info->byte_size)
- {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData (v0_info, data, 0, true);
- if (error.Success())
- {
- if (!reg_ctx->WriteRegister (v0_info, reg_value))
- error.SetErrorString ("failed to write register v0");
- }
- }
- }
+ }
+ } else if (type_flags & eTypeIsVector) {
+ if (byte_size > 0) {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= v0_info->byte_size) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
}
+ }
}
+ }
}
- else
- {
- error.SetErrorString("no registers are available");
- }
-
- return error;
+ } else {
+ error.SetErrorString("no registers are available");
+ }
+
+ return error;
}
-bool
-ABISysV_arm64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t lr_reg_num = arm64_dwarf::lr;
- uint32_t sp_reg_num = arm64_dwarf::sp;
- uint32_t pc_reg_num = arm64_dwarf::pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
-
- // Our previous PC is in the LR
- row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
-
- unwind_plan.AppendRow (row);
-
- // All other registers are the same.
-
- unwind_plan.SetSourceName ("arm64 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
-
- return true;
+bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t lr_reg_num = arm64_dwarf::lr;
+ uint32_t sp_reg_num = arm64_dwarf::sp;
+ uint32_t pc_reg_num = arm64_dwarf::pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ // Our previous PC is in the LR
+ row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+
+ unwind_plan.AppendRow(row);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName("arm64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
}
-bool
-ABISysV_arm64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t fp_reg_num = arm64_dwarf::fp;
- uint32_t pc_reg_num = arm64_dwarf::pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 8;
-
- row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
- row->SetOffset (0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("arm64 default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
-
- return true;
+bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num = arm64_dwarf::fp;
+ uint32_t pc_reg_num = arm64_dwarf::pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 8;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("arm64 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+
+ return true;
}
-// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
-// registers x19 through x28 and sp are callee preserved.
-// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these regs),
+// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
+// registers x19 through x28 and sp are callee preserved.
+// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these
+// regs),
// the rest of the fp/SIMD registers are volatile.
// We treat x29 as callee preserved also, else the unwinder won't try to
// retrieve fp saves.
-bool
-ABISysV_arm64::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- const char *name = reg_info->name;
-
- // Sometimes we'll be called with the "alternate" name for these registers;
- // recognize them as non-volatile.
-
- if (name[0] == 'p' && name[1] == 'c') // pc
- return false;
- if (name[0] == 'f' && name[1] == 'p') // fp
- return false;
- if (name[0] == 's' && name[1] == 'p') // sp
- return false;
- if (name[0] == 'l' && name[1] == 'r') // lr
- return false;
-
- if (name[0] == 'x')
- {
- // Volatile registers: x0-x18
- // Although documentation says only x19-28 + sp are callee saved
- // We ll also have to treat x30 as non-volatile.
- // Each dwarf frame has its own value of lr.
- // Return false for the non-volatile gpr regs, true for everything else
- switch (name[1])
- {
- case '1':
- switch (name[2])
- {
- case '9':
- return false; // x19 is non-volatile
- default:
- return true;
- }
- break;
- case '2':
- switch (name[2])
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- return false; // x20 - 28 are non-volatile
- case '9':
- return false; // x29 aka fp treat as non-volatile
- default:
- return true;
- }
- case '3': // x30 (lr) and x31 (sp) treat as non-volatile
- if (name[2] == '0' || name[2] == '1')
- return false;
- break;
- default:
- return true; // all volatile cases not handled above fall here.
- }
+bool ABISysV_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ const char *name = reg_info->name;
+
+ // Sometimes we'll be called with the "alternate" name for these registers;
+ // recognize them as non-volatile.
+
+ if (name[0] == 'p' && name[1] == 'c') // pc
+ return false;
+ if (name[0] == 'f' && name[1] == 'p') // fp
+ return false;
+ if (name[0] == 's' && name[1] == 'p') // sp
+ return false;
+ if (name[0] == 'l' && name[1] == 'r') // lr
+ return false;
+
+ if (name[0] == 'x') {
+ // Volatile registers: x0-x18
+ // Although documentation says only x19-28 + sp are callee saved
+ // We ll also have to treat x30 as non-volatile.
+ // Each dwarf frame has its own value of lr.
+ // Return false for the non-volatile gpr regs, true for everything else
+ switch (name[1]) {
+ case '1':
+ switch (name[2]) {
+ case '9':
+ return false; // x19 is non-volatile
+ default:
+ return true;
}
- else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd')
- {
- // Volatile registers: v0-7, v16-v31
- // Return false for non-volatile fp/SIMD regs, true for everything else
- switch (name[1])
- {
- case '8':
- case '9':
- return false; // v8-v9 are non-volatile
- case '1':
- switch (name[2])
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return false; // v10-v15 are non-volatile
- default:
- return true;
- }
- default:
- return true;
- }
+ break;
+ case '2':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ return false; // x20 - 28 are non-volatile
+ case '9':
+ return false; // x29 aka fp treat as non-volatile
+ default:
+ return true;
+ }
+ case '3': // x30 (lr) and x31 (sp) treat as non-volatile
+ if (name[2] == '0' || name[2] == '1')
+ return false;
+ break;
+ default:
+ return true; // all volatile cases not handled above fall here.
+ }
+ } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') {
+ // Volatile registers: v0-7, v16-v31
+ // Return false for non-volatile fp/SIMD regs, true for everything else
+ switch (name[1]) {
+ case '8':
+ case '9':
+ return false; // v8-v9 are non-volatile
+ case '1':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return false; // v10-v15 are non-volatile
+ default:
+ return true;
}
+ default:
+ return true;
+ }
}
- return true;
+ }
+ return true;
}
-static bool
-LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
- RegisterContext *reg_ctx,
- const CompilerType &value_type,
- bool is_return_value, // false => parameter, true => return value
- 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)
+static bool LoadValueFromConsecutiveGPRRegisters(
+ ExecutionContext &exe_ctx, RegisterContext *reg_ctx,
+ const CompilerType &value_type,
+ bool is_return_value, // false => parameter, true => return value
+ 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)
+ return false;
+
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ Error error;
+
+ CompilerType base_type;
+ const uint32_t homogeneous_count =
+ value_type.IsHomogeneousAggregate(&base_type);
+ if (homogeneous_count > 0 && homogeneous_count <= 8) {
+ // Make sure we have enough registers
+ if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
+ if (!base_type)
return false;
+ const size_t base_byte_size = base_type.GetByteSize(nullptr);
+ uint32_t data_offset = 0;
+
+ for (uint32_t i = 0; i < homogeneous_count; ++i) {
+ char v_name[8];
+ ::snprintf(v_name, sizeof(v_name), "v%u", NSRN);
+ const RegisterInfo *reg_info =
+ reg_ctx->GetRegisterInfoByName(v_name, 0);
+ if (reg_info == nullptr)
+ return false;
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- Error error;
-
- CompilerType base_type;
- const uint32_t homogeneous_count = value_type.IsHomogeneousAggregate (&base_type);
- if (homogeneous_count > 0 && homogeneous_count <= 8)
- {
- // Make sure we have enough registers
- if (NSRN < 8 && (8-NSRN) >= homogeneous_count)
- {
- if (!base_type)
- return false;
- const size_t base_byte_size = base_type.GetByteSize(nullptr);
- uint32_t data_offset = 0;
+ if (base_byte_size > reg_info->byte_size)
+ return false;
- for (uint32_t i=0; i<homogeneous_count; ++i)
- {
- char v_name[8];
- ::snprintf (v_name, sizeof(v_name), "v%u", NSRN);
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(v_name, 0);
- if (reg_info == nullptr)
- return false;
-
- if (base_byte_size > reg_info->byte_size)
- return false;
-
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- // Make sure we have enough room in "heap_data_ap"
- 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,
- byte_order,
- error);
- if (bytes_copied != base_byte_size)
- return false;
- data_offset += bytes_copied;
- ++NSRN;
- }
- else
- return false;
- }
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP (heap_data_ap.release()));
- return true;
- }
+ RegisterValue reg_value;
+
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ // Make sure we have enough room in "heap_data_ap"
+ 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,
+ byte_order, error);
+ if (bytes_copied != base_byte_size)
+ return false;
+ data_offset += bytes_copied;
+ ++NSRN;
+ } else
+ return false;
+ }
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_ap.release()));
+ return true;
}
+ }
+
+ const size_t max_reg_byte_size = 16;
+ if (byte_size <= max_reg_byte_size) {
+ size_t bytes_left = byte_size;
+ uint32_t data_offset = 0;
+ while (data_offset < byte_size) {
+ if (NGRN >= 8)
+ return false;
- const size_t max_reg_byte_size = 16;
- if (byte_size <= max_reg_byte_size)
- {
- size_t bytes_left = byte_size;
- uint32_t data_offset = 0;
- while (data_offset < byte_size)
- {
- if (NGRN >= 8)
- return false;
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_info == nullptr)
+ return false;
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_info == nullptr)
- return false;
+ RegisterValue reg_value;
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- const size_t curr_byte_size = std::min<size_t>(8,bytes_left);
- const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info, heap_data_ap->GetBytes()+data_offset, curr_byte_size, byte_order, error);
- if (bytes_copied == 0)
- return false;
- if (bytes_copied >= bytes_left)
- break;
- data_offset += bytes_copied;
- bytes_left -= bytes_copied;
- ++NGRN;
- }
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, heap_data_ap->GetBytes() + data_offset, curr_byte_size,
+ byte_order, error);
+ if (bytes_copied == 0)
+ return false;
+ if (bytes_copied >= bytes_left)
+ break;
+ data_offset += bytes_copied;
+ bytes_left -= bytes_copied;
+ ++NGRN;
}
- else
- {
- const RegisterInfo *reg_info = nullptr;
- if (is_return_value)
- {
- // We are assuming we are decoding this immediately after returning
- // from a function call and that the address of the structure is in x8
- reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
- }
- else
- {
- // We are assuming we are stopped at the first instruction in a function
- // and that the ABI is being respected so all parameters appear where they
- // should be (functions with no external linkage can legally violate the ABI).
- if (NGRN >= 8)
- return false;
-
- reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_info == nullptr)
- return false;
- ++NGRN;
- }
+ } else {
+ const RegisterInfo *reg_info = nullptr;
+ if (is_return_value) {
+ // We are assuming we are decoding this immediately after returning
+ // from a function call and that the address of the structure is in x8
+ reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
+ } else {
+ // We are assuming we are stopped at the first instruction in a function
+ // and that the ABI is being respected so all parameters appear where they
+ // should be (functions with no external linkage can legally violate the
+ // ABI).
+ if (NGRN >= 8)
+ return false;
- if (reg_info == nullptr)
- return false;
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_info == nullptr)
+ return false;
+ ++NGRN;
+ }
- const lldb::addr_t value_addr = reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
+ if (reg_info == nullptr)
+ return false;
- if (value_addr == LLDB_INVALID_ADDRESS)
- return false;
+ const lldb::addr_t value_addr =
+ reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
- if (exe_ctx.GetProcessRef().ReadMemory (value_addr,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- error) != heap_data_ap->GetByteSize())
- {
- return false;
- }
+ if (value_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ if (exe_ctx.GetProcessRef().ReadMemory(
+ value_addr, heap_data_ap->GetBytes(), heap_data_ap->GetByteSize(),
+ error) != heap_data_ap->GetByteSize()) {
+ return false;
}
+ }
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP (heap_data_ap.release()));
- return true;
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_ap.release()));
+ return true;
}
-ValueObjectSP
-ABISysV_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
-
- ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
- return return_valobj_sp;
-
- //value.SetContext (Value::eContextTypeClangType, return_compiler_type);
- value.SetCompilerType(return_compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
-
- const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar ||
- type_flags & eTypeIsPointer)
- {
- value.SetValueType(Value::eValueTypeScalar);
-
- 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)
+ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType, return_compiler_type);
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ 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) {
+ const RegisterInfo *x0_reg_info = nullptr;
+ x0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ if (x0_reg_info) {
+ uint64_t raw_value =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
+ 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size) {
+ default:
+ break;
+ case 16: // uint128_t
+ // In register x0 and x1
{
- const RegisterInfo *x0_reg_info = nullptr;
- x0_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
- if (x0_reg_info)
- {
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size)
- {
- default:
- break;
- case 16: // uint128_t
- // In register x0 and x1
- {
- const RegisterInfo *x1_reg_info = nullptr;
- x1_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
-
- if (x1_reg_info)
- {
- 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));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue x0_reg_value;
- RegisterValue x1_reg_value;
- if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
- reg_ctx->ReadRegister(x1_reg_info, x1_reg_value))
- {
- Error error;
- if (x0_reg_value.GetAsMemoryData (x0_reg_info, heap_data_ap->GetBytes()+0, 8, byte_order, error) &&
- x1_reg_value.GetAsMemoryData (x1_reg_info, heap_data_ap->GetBytes()+8, 8, byte_order, error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
-
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- return return_valobj_sp;
- }
- }
- }
- }
- }
- break;
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
-
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
-
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
-
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
+ const RegisterInfo *x1_reg_info = nullptr;
+ x1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG2);
+
+ if (x1_reg_info) {
+ 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));
+ const ByteOrder byte_order =
+ exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue x0_reg_value;
+ RegisterValue x1_reg_value;
+ if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
+ reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) {
+ Error error;
+ if (x0_reg_value.GetAsMemoryData(
+ x0_reg_info, heap_data_ap->GetBytes() + 0, 8,
+ byte_order, error) &&
+ x1_reg_value.GetAsMemoryData(
+ x1_reg_info, heap_data_ap->GetBytes() + 8, 8,
+ byte_order, error)) {
+ DataExtractor data(
+ DataBufferSP(heap_data_ap.release()), byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ return return_valobj_sp;
}
+ }
}
+ }
}
- }
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- }
+ break;
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
else
- {
- if (byte_size <= sizeof(long double))
- {
- const RegisterInfo *v0_reg_info = reg_ctx->GetRegisterInfoByName("v0", 0);
- RegisterValue v0_value;
- if (reg_ctx->ReadRegister (v0_reg_info, v0_value))
- {
- DataExtractor data;
- if (v0_value.GetData(data))
- {
- lldb::offset_t offset = 0;
- if (byte_size == sizeof(float))
- {
- value.GetScalar() = data.GetFloat(&offset);
- success = true;
- }
- else if (byte_size == sizeof(double))
- {
- value.GetScalar() = data.GetDouble(&offset);
- success = true;
- }
- else if (byte_size == sizeof(long double))
- {
- value.GetScalar() = data.GetLongDouble(&offset);
- success = true;
- }
- }
- }
- }
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ if (byte_size <= sizeof(long double)) {
+ const RegisterInfo *v0_reg_info =
+ reg_ctx->GetRegisterInfoByName("v0", 0);
+ RegisterValue v0_value;
+ if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) {
+ DataExtractor data;
+ if (v0_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float)) {
+ value.GetScalar() = data.GetFloat(&offset);
+ success = true;
+ } else if (byte_size == sizeof(double)) {
+ value.GetScalar() = data.GetDouble(&offset);
+ success = true;
+ } else if (byte_size == sizeof(long double)) {
+ value.GetScalar() = data.GetLongDouble(&offset);
+ success = true;
+ }
}
+ }
}
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ }
}
- else if (type_flags & eTypeIsVector)
- {
- if (byte_size > 0)
- {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info)
- {
- if (byte_size <= v0_info->byte_size)
- {
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(v0_info, reg_value))
- {
- Error error;
- if (reg_value.GetAsMemoryData (v0_info,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ if (byte_size > 0) {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= v0_info->byte_size) {
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(v0_info, reg_value)) {
+ Error error;
+ if (reg_value.GetAsMemoryData(v0_info, heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(),
+ byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
}
+ }
}
+ }
}
- else if (type_flags & eTypeIsStructUnion ||
- type_flags & eTypeIsClass)
- {
- DataExtractor data;
-
- uint32_t NGRN = 0; // Search ABI docs for NGRN
- uint32_t NSRN = 0; // Search ABI docs for NSRN
- const bool is_return_value = true;
- if (LoadValueFromConsecutiveGPRRegisters (exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN, data))
- {
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
+ } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
+ DataExtractor data;
+
+ uint32_t NGRN = 0; // Search ABI docs for NGRN
+ uint32_t NSRN = 0; // Search ABI docs for NSRN
+ const bool is_return_value = true;
+ if (LoadValueFromConsecutiveGPRRegisters(
+ exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
+ data)) {
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
}
- return return_valobj_sp;
+ }
+ return return_valobj_sp;
}
-void
-ABISysV_arm64::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "SysV ABI for AArch64 targets",
- CreateInstance);
+void ABISysV_arm64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "SysV ABI for AArch64 targets", CreateInstance);
}
-void
-ABISysV_arm64::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_arm64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_arm64::GetPluginNameStatic()
-{
- static ConstString g_name("SysV-arm64");
- return g_name;
+lldb_private::ConstString ABISysV_arm64::GetPluginNameStatic() {
+ static ConstString g_name("SysV-arm64");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-ABISysV_arm64::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+ConstString ABISysV_arm64::GetPluginName() { return GetPluginNameStatic(); }
-uint32_t
-ABISysV_arm64::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_arm64::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
index e36f87e744f4..68c300c0909d 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
@@ -14,111 +14,96 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_arm64 : public lldb_private::ABI
-{
+class ABISysV_arm64 : public lldb_private::ABI {
public:
- ~ABISysV_arm64() override = default;
-
- size_t
- GetRedZoneSize () const override;
-
- bool
- PrepareTrivialCall (lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues (lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- bool
- CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info) override;
-
- // The arm64 ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
- bool
- CallFrameAddressIsValid (lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid (lldb::addr_t pc) override
- {
- if (pc & (4ull - 1ull))
- return false; // Not 4 byte aligned
-
- // Anything else if fair game..
- return true;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray (uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
+ ~ABISysV_arm64() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ // The arm64 ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (8-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ if (pc & (4ull - 1ull))
+ return false; // Not 4 byte aligned
+
+ // Anything else if fair game..
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ bool GetPointerReturnRegister(const char *&name) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
protected:
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const override;
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm64() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_arm64() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_arm64_h_
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
index 596f3dc1166a..649f19b0b831 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
@@ -25,190 +25,1023 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-static RegisterInfo g_register_infos[] =
-{
+static RegisterInfo g_register_infos[] = {
// hexagon-core.xml
- { "r00" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 0, 0, LLDB_INVALID_REGNUM, 0, 0 }, nullptr, nullptr },
- { "r01" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 1, 1, LLDB_INVALID_REGNUM, 1, 1 }, nullptr, nullptr },
- { "r02" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 2, 2, LLDB_INVALID_REGNUM, 2, 2 }, nullptr, nullptr },
- { "r03" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 3, 3, LLDB_INVALID_REGNUM, 3, 3 }, nullptr, nullptr },
- { "r04" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 4, 4, LLDB_INVALID_REGNUM, 4, 4 }, nullptr, nullptr },
- { "r05" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 5, 5, LLDB_INVALID_REGNUM, 5, 5 }, nullptr, nullptr },
- { "r06" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 6, 6, LLDB_INVALID_REGNUM, 6, 6 }, nullptr, nullptr },
- { "r07" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 7, 7, LLDB_INVALID_REGNUM, 7, 7 }, nullptr, nullptr },
- { "r08" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 8, 8, LLDB_INVALID_REGNUM, 8, 8 }, nullptr, nullptr },
- { "r09" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 9, 9, LLDB_INVALID_REGNUM, 9, 9 }, nullptr, nullptr },
- { "r10" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 10, 10, LLDB_INVALID_REGNUM, 10, 10 }, nullptr, nullptr },
- { "r11" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 11, 11, LLDB_INVALID_REGNUM, 11, 11 }, nullptr, nullptr },
- { "r12" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 12, 12, LLDB_INVALID_REGNUM, 12, 12 }, nullptr, nullptr },
- { "r13" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 13, 13, LLDB_INVALID_REGNUM, 13, 13 }, nullptr, nullptr },
- { "r14" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 14, 14, LLDB_INVALID_REGNUM, 14, 14 }, nullptr, nullptr },
- { "r15" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 15, 15, LLDB_INVALID_REGNUM, 15, 15 }, nullptr, nullptr },
- { "r16" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 16, 16, LLDB_INVALID_REGNUM, 16, 16 }, nullptr, nullptr },
- { "r17" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 17, 17, LLDB_INVALID_REGNUM, 17, 17 }, nullptr, nullptr },
- { "r18" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 18, 18, LLDB_INVALID_REGNUM, 18, 18 }, nullptr, nullptr },
- { "r19" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 19, 19, LLDB_INVALID_REGNUM, 19, 19 }, nullptr, nullptr },
- { "r20" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 20, 20, LLDB_INVALID_REGNUM, 20, 20 }, nullptr, nullptr },
- { "r21" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 21, 21, LLDB_INVALID_REGNUM, 21, 21 }, nullptr, nullptr },
- { "r22" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 22, 22, LLDB_INVALID_REGNUM, 22, 22 }, nullptr, nullptr },
- { "r23" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 23, 23, LLDB_INVALID_REGNUM, 23, 23 }, nullptr, nullptr },
- { "r24" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 24, 24, LLDB_INVALID_REGNUM, 24, 24 }, nullptr, nullptr },
- { "r25" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 25, 25, LLDB_INVALID_REGNUM, 25, 25 }, nullptr, nullptr },
- { "r26" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 26, 26, LLDB_INVALID_REGNUM, 26, 26 }, nullptr, nullptr },
- { "r27" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 27, 27, LLDB_INVALID_REGNUM, 27, 27 }, nullptr, nullptr },
- { "r28" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 28, 28, LLDB_INVALID_REGNUM, 28, 28 }, nullptr, nullptr },
- { "sp" ,"r29", 4, 0, eEncodingUint, eFormatAddressInfo, { 29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29 }, nullptr, nullptr },
- { "fp" ,"r30", 4, 0, eEncodingUint, eFormatAddressInfo, { 30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30 }, nullptr, nullptr },
- { "lr" ,"r31", 4, 0, eEncodingUint, eFormatAddressInfo, { 31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31 }, nullptr, nullptr },
- { "sa0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 32, 32, LLDB_INVALID_REGNUM, 32, 32 }, nullptr, nullptr },
- { "lc0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 33, 33, LLDB_INVALID_REGNUM, 33, 33 }, nullptr, nullptr },
- { "sa1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 34, 34, LLDB_INVALID_REGNUM, 34, 34 }, nullptr, nullptr },
- { "lc1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 35, 35, LLDB_INVALID_REGNUM, 35, 35 }, nullptr, nullptr },
+ {"r00",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {0, 0, LLDB_INVALID_REGNUM, 0, 0},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r01",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {1, 1, LLDB_INVALID_REGNUM, 1, 1},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r02",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {2, 2, LLDB_INVALID_REGNUM, 2, 2},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r03",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {3, 3, LLDB_INVALID_REGNUM, 3, 3},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r04",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {4, 4, LLDB_INVALID_REGNUM, 4, 4},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r05",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {5, 5, LLDB_INVALID_REGNUM, 5, 5},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r06",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {6, 6, LLDB_INVALID_REGNUM, 6, 6},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r07",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {7, 7, LLDB_INVALID_REGNUM, 7, 7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r08",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {8, 8, LLDB_INVALID_REGNUM, 8, 8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r09",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {9, 9, LLDB_INVALID_REGNUM, 9, 9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {10, 10, LLDB_INVALID_REGNUM, 10, 10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {11, 11, LLDB_INVALID_REGNUM, 11, 11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {12, 12, LLDB_INVALID_REGNUM, 12, 12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {13, 13, LLDB_INVALID_REGNUM, 13, 13},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {14, 14, LLDB_INVALID_REGNUM, 14, 14},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r15",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {15, 15, LLDB_INVALID_REGNUM, 15, 15},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r16",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {16, 16, LLDB_INVALID_REGNUM, 16, 16},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r17",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {17, 17, LLDB_INVALID_REGNUM, 17, 17},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r18",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {18, 18, LLDB_INVALID_REGNUM, 18, 18},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r19",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {19, 19, LLDB_INVALID_REGNUM, 19, 19},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r20",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {20, 20, LLDB_INVALID_REGNUM, 20, 20},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r21",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {21, 21, LLDB_INVALID_REGNUM, 21, 21},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r22",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {22, 22, LLDB_INVALID_REGNUM, 22, 22},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r23",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {23, 23, LLDB_INVALID_REGNUM, 23, 23},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r24",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {24, 24, LLDB_INVALID_REGNUM, 24, 24},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r25",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {25, 25, LLDB_INVALID_REGNUM, 25, 25},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r26",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {26, 26, LLDB_INVALID_REGNUM, 26, 26},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r27",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {27, 27, LLDB_INVALID_REGNUM, 27, 27},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r28",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {28, 28, LLDB_INVALID_REGNUM, 28, 28},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "r29",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fp",
+ "r30",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r31",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sa0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {32, 32, LLDB_INVALID_REGNUM, 32, 32},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lc0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {33, 33, LLDB_INVALID_REGNUM, 33, 33},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sa1",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {34, 34, LLDB_INVALID_REGNUM, 34, 34},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lc1",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {35, 35, LLDB_INVALID_REGNUM, 35, 35},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
// --> hexagon-v4/5/55/56-sim.xml
- { "p3_0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 36, 36, LLDB_INVALID_REGNUM, 36, 36 }, nullptr, nullptr },
-// PADDING {
- { "p00" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 37, 37, LLDB_INVALID_REGNUM, 37, 37 }, nullptr, nullptr },
-// }
- { "m0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 38, 38, LLDB_INVALID_REGNUM, 38, 38 }, nullptr, nullptr },
- { "m1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 39, 39, LLDB_INVALID_REGNUM, 39, 39 }, nullptr, nullptr },
- { "usr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 40, 40, LLDB_INVALID_REGNUM, 40, 40 }, nullptr, nullptr },
- { "pc" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41 }, nullptr, nullptr },
- { "ugp" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 42, 42, LLDB_INVALID_REGNUM, 42, 42 }, nullptr, nullptr },
- { "gp" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 43, 43, LLDB_INVALID_REGNUM, 43, 43 }, nullptr, nullptr },
- { "cs0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 44, 44, LLDB_INVALID_REGNUM, 44, 44 }, nullptr, nullptr },
- { "cs1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 45, 45, LLDB_INVALID_REGNUM, 45, 45 }, nullptr, nullptr },
-// PADDING {
- { "p01" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 46, 46, LLDB_INVALID_REGNUM, 46, 46 }, nullptr, nullptr },
- { "p02" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 47, 47, LLDB_INVALID_REGNUM, 47, 47 }, nullptr, nullptr },
- { "p03" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 48, 48, LLDB_INVALID_REGNUM, 48, 48 }, nullptr, nullptr },
- { "p04" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 49, 49, LLDB_INVALID_REGNUM, 49, 49 }, nullptr, nullptr },
- { "p05" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 50, 50, LLDB_INVALID_REGNUM, 50, 50 }, nullptr, nullptr },
- { "p06" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 51, 51, LLDB_INVALID_REGNUM, 51, 51 }, nullptr, nullptr },
- { "p07" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 52, 52, LLDB_INVALID_REGNUM, 52, 52 }, nullptr, nullptr },
- { "p08" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 53, 53, LLDB_INVALID_REGNUM, 53, 53 }, nullptr, nullptr },
- { "p09" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 54, 54, LLDB_INVALID_REGNUM, 54, 54 }, nullptr, nullptr },
- { "p10" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 55, 55, LLDB_INVALID_REGNUM, 55, 55 }, nullptr, nullptr },
- { "p11" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 56, 56, LLDB_INVALID_REGNUM, 56, 56 }, nullptr, nullptr },
- { "p12" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 57, 57, LLDB_INVALID_REGNUM, 57, 57 }, nullptr, nullptr },
- { "p13" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 58, 58, LLDB_INVALID_REGNUM, 58, 58 }, nullptr, nullptr },
- { "p14" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 59, 59, LLDB_INVALID_REGNUM, 59, 59 }, nullptr, nullptr },
- { "p15" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 60, 60, LLDB_INVALID_REGNUM, 60, 60 }, nullptr, nullptr },
- { "p16" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 61, 61, LLDB_INVALID_REGNUM, 61, 61 }, nullptr, nullptr },
- { "p17" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 62, 62, LLDB_INVALID_REGNUM, 62, 62 }, nullptr, nullptr },
- { "p18" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 63, 63, LLDB_INVALID_REGNUM, 63, 63 }, nullptr, nullptr },
-// }
- { "sgp0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 64, 64, LLDB_INVALID_REGNUM, 64, 64 }, nullptr, nullptr },
-// PADDING {
- { "p19" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 65, 65, LLDB_INVALID_REGNUM, 65, 65 }, nullptr, nullptr },
-// }
- { "stid" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 66, 66, LLDB_INVALID_REGNUM, 66, 66 }, nullptr, nullptr },
- { "elr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 67, 67, LLDB_INVALID_REGNUM, 67, 67 }, nullptr, nullptr },
- { "badva0", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 68, 68, LLDB_INVALID_REGNUM, 68, 68 }, nullptr, nullptr },
- { "badva1", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 69, 69, LLDB_INVALID_REGNUM, 69, 69 }, nullptr, nullptr },
- { "ssr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 70, 70, LLDB_INVALID_REGNUM, 70, 70 }, nullptr, nullptr },
- { "ccr" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 71, 71, LLDB_INVALID_REGNUM, 71, 71 }, nullptr, nullptr },
- { "htid" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 72, 72, LLDB_INVALID_REGNUM, 72, 72 }, nullptr, nullptr },
-// PADDING {
- { "p20" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 73, 73, LLDB_INVALID_REGNUM, 73, 73 }, nullptr, nullptr },
-// }
- { "imask" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 74, 74, LLDB_INVALID_REGNUM, 74, 74 }, nullptr, nullptr },
-// PADDING {
- { "p21" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 75, 75, LLDB_INVALID_REGNUM, 75, 75 }, nullptr, nullptr },
- { "p22" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 76, 76, LLDB_INVALID_REGNUM, 76, 76 }, nullptr, nullptr },
- { "p23" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 77, 77, LLDB_INVALID_REGNUM, 77, 77 }, nullptr, nullptr },
- { "p24" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 78, 78, LLDB_INVALID_REGNUM, 78, 78 }, nullptr, nullptr },
- { "p25" , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 79, 79, LLDB_INVALID_REGNUM, 79, 79 }, nullptr, nullptr },
- // }
- { "g0" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 80, 80, LLDB_INVALID_REGNUM, 80, 80 }, nullptr, nullptr },
- { "g1" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 81, 81, LLDB_INVALID_REGNUM, 81, 81 }, nullptr, nullptr },
- { "g2" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 82, 82, LLDB_INVALID_REGNUM, 82, 82 }, nullptr, nullptr },
- { "g3" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 83, 83, LLDB_INVALID_REGNUM, 83, 83 }, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = sizeof(g_register_infos)/sizeof(RegisterInfo);
+ {"p3_0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {36, 36, LLDB_INVALID_REGNUM, 36, 36},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // PADDING {
+ {"p00",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {37, 37, LLDB_INVALID_REGNUM, 37, 37},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // }
+ {"m0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {38, 38, LLDB_INVALID_REGNUM, 38, 38},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"m1",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {39, 39, LLDB_INVALID_REGNUM, 39, 39},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"usr",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {40, 40, LLDB_INVALID_REGNUM, 40, 40},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ugp",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {42, 42, LLDB_INVALID_REGNUM, 42, 42},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"gp",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {43, 43, LLDB_INVALID_REGNUM, 43, 43},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cs0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {44, 44, LLDB_INVALID_REGNUM, 44, 44},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cs1",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {45, 45, LLDB_INVALID_REGNUM, 45, 45},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // PADDING {
+ {"p01",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {46, 46, LLDB_INVALID_REGNUM, 46, 46},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p02",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {47, 47, LLDB_INVALID_REGNUM, 47, 47},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p03",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {48, 48, LLDB_INVALID_REGNUM, 48, 48},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p04",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {49, 49, LLDB_INVALID_REGNUM, 49, 49},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p05",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {50, 50, LLDB_INVALID_REGNUM, 50, 50},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p06",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {51, 51, LLDB_INVALID_REGNUM, 51, 51},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p07",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {52, 52, LLDB_INVALID_REGNUM, 52, 52},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p08",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {53, 53, LLDB_INVALID_REGNUM, 53, 53},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p09",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {54, 54, LLDB_INVALID_REGNUM, 54, 54},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p10",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {55, 55, LLDB_INVALID_REGNUM, 55, 55},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p11",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {56, 56, LLDB_INVALID_REGNUM, 56, 56},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p12",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {57, 57, LLDB_INVALID_REGNUM, 57, 57},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p13",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {58, 58, LLDB_INVALID_REGNUM, 58, 58},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p14",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {59, 59, LLDB_INVALID_REGNUM, 59, 59},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p15",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {60, 60, LLDB_INVALID_REGNUM, 60, 60},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p16",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {61, 61, LLDB_INVALID_REGNUM, 61, 61},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p17",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {62, 62, LLDB_INVALID_REGNUM, 62, 62},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p18",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {63, 63, LLDB_INVALID_REGNUM, 63, 63},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // }
+ {"sgp0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {64, 64, LLDB_INVALID_REGNUM, 64, 64},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // PADDING {
+ {"p19",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {65, 65, LLDB_INVALID_REGNUM, 65, 65},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // }
+ {"stid",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {66, 66, LLDB_INVALID_REGNUM, 66, 66},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"elr",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {67, 67, LLDB_INVALID_REGNUM, 67, 67},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"badva0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {68, 68, LLDB_INVALID_REGNUM, 68, 68},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"badva1",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {69, 69, LLDB_INVALID_REGNUM, 69, 69},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ssr",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {70, 70, LLDB_INVALID_REGNUM, 70, 70},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ccr",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {71, 71, LLDB_INVALID_REGNUM, 71, 71},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"htid",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {72, 72, LLDB_INVALID_REGNUM, 72, 72},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // PADDING {
+ {"p20",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {73, 73, LLDB_INVALID_REGNUM, 73, 73},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // }
+ {"imask",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {74, 74, LLDB_INVALID_REGNUM, 74, 74},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // PADDING {
+ {"p21",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {75, 75, LLDB_INVALID_REGNUM, 75, 75},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p22",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {76, 76, LLDB_INVALID_REGNUM, 76, 76},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p23",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {77, 77, LLDB_INVALID_REGNUM, 77, 77},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p24",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {78, 78, LLDB_INVALID_REGNUM, 78, 78},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"p25",
+ "",
+ 4,
+ 0,
+ eEncodingInvalid,
+ eFormatInvalid,
+ {79, 79, LLDB_INVALID_REGNUM, 79, 79},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // }
+ {"g0",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {80, 80, LLDB_INVALID_REGNUM, 80, 80},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"g1",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {81, 81, LLDB_INVALID_REGNUM, 81, 81},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"g2",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {82, 82, LLDB_INVALID_REGNUM, 82, 82},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"g3",
+ "",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatAddressInfo,
+ {83, 83, LLDB_INVALID_REGNUM, 83, 83},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ sizeof(g_register_infos) / sizeof(RegisterInfo);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABISysV_hexagon::GetRegisterInfoArray ( uint32_t &count )
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
/*
http://en.wikipedia.org/wiki/Red_zone_%28computing%29
- In computing, a red zone is a fixed size area in memory beyond the stack pointer that has not been
- "allocated". This region of memory is not to be modified by interrupt/exception/signal handlers.
- This allows the space to be used for temporary data without the extra overhead of modifying the
- stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC toolchain assumes a
+ In computing, a red zone is a fixed size area in memory beyond the stack
+ pointer that has not been
+ "allocated". This region of memory is not to be modified by
+ interrupt/exception/signal handlers.
+ This allows the space to be used for temporary data without the extra
+ overhead of modifying the
+ stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
+ toolchain assumes a
128 byte red zone though it is not documented.
*/
-size_t
-ABISysV_hexagon::GetRedZoneSize () const
-{
- return 0;
-}
+size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_hexagon::CreateInstance ( 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);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_hexagon::CreateInstance(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);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_hexagon::PrepareTrivialCall ( Thread &thread,
- lldb::addr_t sp ,
- lldb::addr_t pc ,
- lldb::addr_t ra ,
- llvm::ArrayRef<addr_t> args ) const
-{
- // we don't use the traditional trivial call specialized for jit
- return false;
+bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
+ lldb::addr_t pc, lldb::addr_t ra,
+ llvm::ArrayRef<addr_t> args) const {
+ // we don't use the traditional trivial call specialized for jit
+ return false;
}
/*
// AD:
// . safeguard the current stack
-// . how can we know that the called function will create its own frame properly?
+// . how can we know that the called function will create its own frame
+properly?
// . we could manually make a new stack first:
// 2. push RA
// 3. push FP
@@ -216,11 +1049,15 @@ ABISysV_hexagon::PrepareTrivialCall ( Thread &thread,
// 5. SP = SP ( since no locals in our temp frame )
// AD 6/05/2014
-// . variable argument list parameters are not passed via registers, they are passed on
-// the stack. This presents us with a problem, since we need to know when the valist
+// . variable argument list parameters are not passed via registers, they are
+passed on
+// the stack. This presents us with a problem, since we need to know when
+the valist
// starts. Currently I can find out if a function is varg, but not how many
-// real parameters it takes. Thus I don't know when to start spilling the vargs. For
-// the time being, to progress, I will assume that it takes on real parameter before
+// real parameters it takes. Thus I don't know when to start spilling the
+vargs. For
+// the time being, to progress, I will assume that it takes on real parameter
+before
// the vargs list starts.
// AD 06/05/2014
@@ -231,208 +1068,195 @@ ABISysV_hexagon::PrepareTrivialCall ( Thread &thread,
*/
#define HEX_ABI_DEBUG 0
-bool
-ABISysV_hexagon::PrepareTrivialCall ( Thread &thread,
- lldb::addr_t sp ,
- lldb::addr_t pc ,
- lldb::addr_t ra ,
- llvm::Type &prototype,
- llvm::ArrayRef<ABI::CallArgument> args) const
-{
- // default number of register passed arguments for varg functions
- const int nVArgRegParams = 1;
- Error error;
-
- // grab the process so we have access to the memory for spilling
- lldb::ProcessSP proc = thread.GetProcess( );
-
- // get the register context for modifying all of the registers
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
-
- uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- if (pc_reg == LLDB_INVALID_REGNUM)
- return false;
-
- uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
- if (ra_reg == LLDB_INVALID_REGNUM)
- return false;
-
- uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- if (sp_reg == LLDB_INVALID_REGNUM)
- return false;
-
- // push host data onto target
- for ( size_t i = 0; i < args.size( ); i++ )
- {
- const ABI::CallArgument &arg = args[i];
- // skip over target values
- if ( arg.type == ABI::CallArgument::TargetValue )
- continue;
- // round up to 8 byte multiple
- size_t argSize = ( arg.size | 0x7 ) + 1;
-
- // create space on the stack for this data
- sp -= argSize;
-
- // write this argument onto the stack of the host process
- proc->WriteMemory( sp, arg.data_ap.get(), arg.size, error );
- if ( error.Fail( ) )
- return false;
-
- // update the argument with the target pointer
- //XXX: This is a gross hack for getting around the const
- *const_cast<lldb::addr_t*>(&arg.value) = sp;
- }
+bool ABISysV_hexagon::PrepareTrivialCall(
+ Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
+ llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
+ // default number of register passed arguments for varg functions
+ const int nVArgRegParams = 1;
+ Error error;
+
+ // grab the process so we have access to the memory for spilling
+ lldb::ProcessSP proc = thread.GetProcess();
+
+ // get the register context for modifying all of the registers
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
-#if HEX_ABI_DEBUG
- // print the original stack pointer
- printf( "sp : %04" PRIx64 " \n", sp );
-#endif
+ uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ if (pc_reg == LLDB_INVALID_REGNUM)
+ return false;
- // make sure number of parameters matches prototype
- assert( prototype.getFunctionNumParams( ) == args.size( ) );
+ uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+ if (ra_reg == LLDB_INVALID_REGNUM)
+ return false;
- // check if this is a variable argument function
- bool isVArg = prototype.isFunctionVarArg();
+ uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ if (sp_reg == LLDB_INVALID_REGNUM)
+ return false;
- // number of arguments passed by register
- int nRegArgs = nVArgRegParams;
- if (! isVArg )
- {
- // number of arguments is limited by [R0 : R5] space
- nRegArgs = args.size( );
- if ( nRegArgs > 6 )
- nRegArgs = 6;
- }
+ // push host data onto target
+ for (size_t i = 0; i < args.size(); i++) {
+ const ABI::CallArgument &arg = args[i];
+ // skip over target values
+ if (arg.type == ABI::CallArgument::TargetValue)
+ continue;
+ // round up to 8 byte multiple
+ size_t argSize = (arg.size | 0x7) + 1;
- // pass arguments that are passed via registers
- for ( int i = 0; i < nRegArgs; i++ )
- {
- // get the parameter as a u32
- uint32_t param = (uint32_t)args[i].value;
- // write argument into register
- if (!reg_ctx->WriteRegisterFromUnsigned( i, param ))
- return false;
- }
+ // create space on the stack for this data
+ sp -= argSize;
- // number of arguments to spill onto stack
- int nSpillArgs = args.size( ) - nRegArgs;
- // make space on the stack for arguments
- sp -= 4 * nSpillArgs;
- // align stack on an 8 byte boundary
- if ( sp & 7 )
- sp -= 4;
-
- // arguments that are passed on the stack
- for ( size_t i = nRegArgs, offs=0; i < args.size( ); i++ )
- {
- // get the parameter as a u32
- uint32_t param = (uint32_t)args[i].value;
- // write argument to stack
- proc->WriteMemory( sp + offs, (void*)&param, sizeof( param ), error );
- if ( !error.Success( ) )
- return false;
- //
- offs += 4;
- }
+ // write this argument onto the stack of the host process
+ proc->WriteMemory(sp, arg.data_ap.get(), arg.size, error);
+ if (error.Fail())
+ return false;
- // update registers with current function call state
- reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
- reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
- reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
+ // update the argument with the target pointer
+ // XXX: This is a gross hack for getting around the const
+ *const_cast<lldb::addr_t *>(&arg.value) = sp;
+ }
#if HEX_ABI_DEBUG
- // quick and dirty stack dumper for debugging
- for ( int i = -8; i < 8; i++ )
- {
- uint32_t data = 0;
- lldb::addr_t addr = sp + i * 4;
- proc->ReadMemory( addr, (void*)&data, sizeof( data ), error );
- printf( "\n0x%04" PRIx64 " 0x%08x ", addr, data );
- if ( i == 0 ) printf( "<<-- sp" );
- }
- printf( "\n" );
-#endif
-
- return true;
+ // print the original stack pointer
+ printf("sp : %04" PRIx64 " \n", sp);
+#endif
+
+ // make sure number of parameters matches prototype
+ assert(prototype.getFunctionNumParams() == args.size());
+
+ // check if this is a variable argument function
+ bool isVArg = prototype.isFunctionVarArg();
+
+ // number of arguments passed by register
+ int nRegArgs = nVArgRegParams;
+ if (!isVArg) {
+ // number of arguments is limited by [R0 : R5] space
+ nRegArgs = args.size();
+ if (nRegArgs > 6)
+ nRegArgs = 6;
+ }
+
+ // pass arguments that are passed via registers
+ for (int i = 0; i < nRegArgs; i++) {
+ // get the parameter as a u32
+ uint32_t param = (uint32_t)args[i].value;
+ // write argument into register
+ if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
+ return false;
+ }
+
+ // number of arguments to spill onto stack
+ int nSpillArgs = args.size() - nRegArgs;
+ // make space on the stack for arguments
+ sp -= 4 * nSpillArgs;
+ // align stack on an 8 byte boundary
+ if (sp & 7)
+ sp -= 4;
+
+ // arguments that are passed on the stack
+ for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
+ // get the parameter as a u32
+ uint32_t param = (uint32_t)args[i].value;
+ // write argument to stack
+ proc->WriteMemory(sp + offs, (void *)&param, sizeof(param), error);
+ if (!error.Success())
+ return false;
+ //
+ offs += 4;
+ }
+
+ // update registers with current function call state
+ reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
+ reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
+ reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
+
+#if HEX_ABI_DEBUG
+ // quick and dirty stack dumper for debugging
+ for (int i = -8; i < 8; i++) {
+ uint32_t data = 0;
+ lldb::addr_t addr = sp + i * 4;
+ proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
+ printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
+ if (i == 0)
+ printf("<<-- sp");
+ }
+ printf("\n");
+#endif
+
+ return true;
}
-bool
-ABISysV_hexagon::GetArgumentValues ( Thread &thread, ValueList &values ) const
-{
- return false;
+bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
+ ValueList &values) const {
+ return false;
}
-Error
-ABISysV_hexagon::SetReturnValueObject ( lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp )
-{
- Error error;
- return error;
+Error ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ return error;
}
-ValueObjectSP
-ABISysV_hexagon::GetReturnValueObjectSimple ( Thread &thread, CompilerType &return_compiler_type ) const
-{
- ValueObjectSP return_valobj_sp;
- return return_valobj_sp;
+ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_hexagon::GetReturnValueObjectImpl ( Thread &thread, CompilerType &return_compiler_type ) const
-{
- ValueObjectSP return_valobj_sp;
- return return_valobj_sp;
+ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ return return_valobj_sp;
}
// called when we are on the first instruction of a new function
// for hexagon the return address is in RA (R31)
-bool
-ABISysV_hexagon::CreateFunctionEntryUnwindPlan ( UnwindPlan &unwind_plan )
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindGeneric);
- unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our Call Frame Address is the stack pointer value
- row->GetCFAValue().SetIsRegisterPlusOffset (LLDB_REGNUM_GENERIC_SP, 4);
- row->SetOffset(0);
-
- // The previous PC is in the LR
- row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_RA, true);
- unwind_plan.AppendRow(row);
-
- unwind_plan.SetSourceName("hexagon at-func-entry default");
- unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- return true;
+bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindGeneric);
+ unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our Call Frame Address is the stack pointer value
+ row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
+ row->SetOffset(0);
+
+ // The previous PC is in the LR
+ row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
+ LLDB_REGNUM_GENERIC_RA, true);
+ unwind_plan.AppendRow(row);
+
+ unwind_plan.SetSourceName("hexagon at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
}
-bool
-ABISysV_hexagon::CreateDefaultUnwindPlan ( UnwindPlan &unwind_plan )
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindGeneric);
+bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindGeneric);
- uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
- uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
- uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+ uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- row->GetCFAValue().SetIsRegisterPlusOffset (LLDB_REGNUM_GENERIC_FP, 8);
+ row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num,-8, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num,-4, true);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- unwind_plan.AppendRow(row);
- unwind_plan.SetSourceName("hexagon default unwind plan");
- unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
- return true;
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("hexagon default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
}
/*
@@ -449,118 +1273,92 @@ ABISysV_hexagon::CreateDefaultUnwindPlan ( UnwindPlan &unwind_plan )
b = R14 - R15 and R28 are used by the procedure linkage table
c = R29 - R31 are saved and restored by allocframe() and deallocframe()
*/
-bool
-ABISysV_hexagon::RegisterIsVolatile ( const RegisterInfo *reg_info )
-{
- return !RegisterIsCalleeSaved( reg_info );
+bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
-bool
-ABISysV_hexagon::RegisterIsCalleeSaved ( const RegisterInfo *reg_info )
-{
- int reg = ((reg_info->byte_offset) / 4);
+bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ int reg = ((reg_info->byte_offset) / 4);
- bool save = (reg >= 16) && (reg <= 27);
- save |= (reg >= 29) && (reg <= 32);
+ bool save = (reg >= 16) && (reg <= 27);
+ save |= (reg >= 29) && (reg <= 32);
- return save;
+ return save;
}
-void
-ABISysV_hexagon::Initialize()
-{
- PluginManager::RegisterPlugin
- (
- GetPluginNameStatic(),
- "System V ABI for hexagon targets",
- CreateInstance
- );
+void ABISysV_hexagon::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "System V ABI for hexagon targets",
+ CreateInstance);
}
-void
-ABISysV_hexagon::Terminate()
-{
- PluginManager::UnregisterPlugin( CreateInstance );
+void ABISysV_hexagon::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_hexagon::GetPluginNameStatic()
-{
- static ConstString g_name( "sysv-hexagon" );
- return g_name;
+lldb_private::ConstString ABISysV_hexagon::GetPluginNameStatic() {
+ static ConstString g_name("sysv-hexagon");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_hexagon::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_hexagon::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_hexagon::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_hexagon::GetPluginVersion() { return 1; }
// get value object specialized to work with llvm IR types
lldb::ValueObjectSP
-ABISysV_hexagon::GetReturnValueObjectImpl( lldb_private::Thread &thread, llvm::Type &retType ) const
-{
- Value value;
- ValueObjectSP vObjSP;
-
- // get the current register context
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return vObjSP;
-
- // for now just pop R0 to find the return value
- const lldb_private::RegisterInfo *r0_info = reg_ctx->GetRegisterInfoAtIndex( 0 );
- if ( r0_info == nullptr )
- return vObjSP;
-
- // void return type
- if ( retType.isVoidTy( ) )
- {
- value.GetScalar( ) = 0;
- }
- // integer / pointer return type
- else
- if ( retType.isIntegerTy( ) || retType.isPointerTy( ) )
- {
- // read r0 register value
- lldb_private::RegisterValue r0_value;
- if ( !reg_ctx->ReadRegister( r0_info, r0_value ) )
- return vObjSP;
-
- // push r0 into value
- uint32_t r0_u32 = r0_value.GetAsUInt32( );
-
- // account for integer size
- if ( retType.isIntegerTy() && retType.isSized() )
- {
- uint64_t size = retType.getScalarSizeInBits( );
- uint64_t mask = ( 1ull << size ) - 1;
- // mask out higher order bits then the type we expect
- r0_u32 &= mask;
- }
-
- value.GetScalar( ) = r0_u32;
+ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ llvm::Type &retType) const {
+ Value value;
+ ValueObjectSP vObjSP;
+
+ // get the current register context
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return vObjSP;
+
+ // for now just pop R0 to find the return value
+ const lldb_private::RegisterInfo *r0_info =
+ reg_ctx->GetRegisterInfoAtIndex(0);
+ if (r0_info == nullptr)
+ return vObjSP;
+
+ // void return type
+ if (retType.isVoidTy()) {
+ value.GetScalar() = 0;
+ }
+ // integer / pointer return type
+ else if (retType.isIntegerTy() || retType.isPointerTy()) {
+ // read r0 register value
+ lldb_private::RegisterValue r0_value;
+ if (!reg_ctx->ReadRegister(r0_info, r0_value))
+ return vObjSP;
+
+ // push r0 into value
+ uint32_t r0_u32 = r0_value.GetAsUInt32();
+
+ // account for integer size
+ if (retType.isIntegerTy() && retType.isSized()) {
+ uint64_t size = retType.getScalarSizeInBits();
+ uint64_t mask = (1ull << size) - 1;
+ // mask out higher order bits then the type we expect
+ r0_u32 &= mask;
}
- // unsupported return type
- else
- return vObjSP;
-
- // pack the value into a ValueObjectSP
- vObjSP = ValueObjectConstResult::Create
- (
- thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString("")
- );
+
+ value.GetScalar() = r0_u32;
+ }
+ // unsupported return type
+ else
return vObjSP;
+
+ // pack the value into a ValueObjectSP
+ vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+ return vObjSP;
}
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
index 337e3fdcf7b5..aed3dd71b69a 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
@@ -1,4 +1,5 @@
-//===-- ABISysV_hexagon.h ----------------------------------------*- C++ -*-===//
+//===-- ABISysV_hexagon.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,124 +15,100 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_hexagon :
- public lldb_private::ABI
-{
+class ABISysV_hexagon : public lldb_private::ABI {
public:
- ~ABISysV_hexagon() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- // special thread plan for GDB style non-jit function calls
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::Type &prototype,
- llvm::ArrayRef<ABI::CallArgument> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp,
- lldb::ValueObjectSP &new_value) override;
-
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &type) const override;
-
- // specialized to work with llvm IR types
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread, llvm::Type &type) const override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 8 byte aligned
- if (cfa & 0x07)
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // We have a 64 bit address space, so anything is valid as opcodes
- // aren't fixed width...
- return true;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance ( const lldb_private::ArchSpec &arch );
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ~ABISysV_hexagon() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ // special thread plan for GDB style non-jit function calls
+ bool
+ PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress, lldb::addr_t returnAddress,
+ llvm::Type &prototype,
+ llvm::ArrayRef<ABI::CallArgument> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ // specialized to work with llvm IR types
+ lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ llvm::Type &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & 0x07)
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // We have a 64 bit address space, so anything is valid as opcodes
+ // aren't fixed width...
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- void
- CreateRegisterMapIfNeeded();
+ void CreateRegisterMapIfNeeded();
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const;
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- bool
- RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_hexagon() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_hexagon() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_hexagon_h_
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index d23afe9956ba..701db184dfce 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -2,7 +2,8 @@
//
// The LLVM Compiler Infrastructure
//
-// This file is distributed under the University of Illinois Open Source License.
+// This file is distributed under the University of Illinois Open Source
+// License.
// See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
@@ -24,13 +25,13 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
@@ -58,132 +59,143 @@ using namespace lldb_private;
// Comment: Table 2.14 is followed till 'mm' entries.
// After that, all entries are ignored here.
-enum dwarf_regnums
-{
- dwarf_eax = 0,
- dwarf_ecx,
- dwarf_edx,
- dwarf_ebx,
- dwarf_esp,
- dwarf_ebp,
- dwarf_esi,
- dwarf_edi,
- dwarf_eip,
- dwarf_eflags,
-
- dwarf_st0 = 11,
- dwarf_st1,
- dwarf_st2,
- dwarf_st3,
- dwarf_st4,
- dwarf_st5,
- dwarf_st6,
- dwarf_st7,
-
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7,
- dwarf_ymm0 = dwarf_xmm0,
- dwarf_ymm1 = dwarf_xmm1,
- dwarf_ymm2 = dwarf_xmm2,
- dwarf_ymm3 = dwarf_xmm3,
- dwarf_ymm4 = dwarf_xmm4,
- dwarf_ymm5 = dwarf_xmm5,
- dwarf_ymm6 = dwarf_xmm6,
- dwarf_ymm7 = dwarf_xmm7,
-
- dwarf_mm0 = 29,
- dwarf_mm1,
- dwarf_mm2,
- dwarf_mm3,
- dwarf_mm4,
- dwarf_mm5,
- dwarf_mm6,
- dwarf_mm7
+enum dwarf_regnums {
+ dwarf_eax = 0,
+ dwarf_ecx,
+ dwarf_edx,
+ dwarf_ebx,
+ dwarf_esp,
+ dwarf_ebp,
+ dwarf_esi,
+ dwarf_edi,
+ dwarf_eip,
+ dwarf_eflags,
+
+ dwarf_st0 = 11,
+ dwarf_st1,
+ dwarf_st2,
+ dwarf_st3,
+ dwarf_st4,
+ dwarf_st5,
+ dwarf_st6,
+ dwarf_st7,
+
+ dwarf_xmm0 = 21,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7,
+ dwarf_ymm0 = dwarf_xmm0,
+ dwarf_ymm1 = dwarf_xmm1,
+ dwarf_ymm2 = dwarf_xmm2,
+ dwarf_ymm3 = dwarf_xmm3,
+ dwarf_ymm4 = dwarf_xmm4,
+ dwarf_ymm5 = dwarf_xmm5,
+ dwarf_ymm6 = dwarf_xmm6,
+ dwarf_ymm7 = dwarf_xmm7,
+
+ dwarf_mm0 = 29,
+ dwarf_mm1,
+ dwarf_mm2,
+ dwarf_mm3,
+ dwarf_mm4,
+ dwarf_mm5,
+ dwarf_mm6,
+ dwarf_mm7,
+
+ dwarf_bnd0 = 101,
+ dwarf_bnd1,
+ dwarf_bnd2,
+ dwarf_bnd3
};
-static RegisterInfo g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
- // ====== ======= == === ============= ============ ===================== ===================== ============================ ==================== ====================== ========== ===============
- { "eax", nullptr, 4, 0, eEncodingUint , eFormatHex , { dwarf_eax , dwarf_eax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ebx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { dwarf_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ecx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { dwarf_ecx , dwarf_ecx , LLDB_REGNUM_GENERIC_ARG4 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "edx" , nullptr, 4, 0, eEncodingUint , eFormatHex , { dwarf_edx , dwarf_edx , LLDB_REGNUM_GENERIC_ARG3 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "esi" , nullptr, 4, 0, eEncodingUint , eFormatHex , { dwarf_esi , dwarf_esi , LLDB_REGNUM_GENERIC_ARG2 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "edi" , nullptr, 4, 0, eEncodingUint , eFormatHex , { dwarf_edi , dwarf_edi , LLDB_REGNUM_GENERIC_ARG1 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ebp" , "fp", 4, 0, eEncodingUint , eFormatHex , { dwarf_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "esp" , "sp", 4, 0, eEncodingUint , eFormatHex , { dwarf_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "eip" , "pc", 4, 0, eEncodingUint , eFormatHex , { dwarf_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "eflags", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "cs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ss" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ds" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "es" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "fs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "gs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st0" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st1" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st2" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st3" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st4" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st5" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st6" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "st7" , nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_st7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "fctrl" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "fstat" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ftag" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "fiseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "fioff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "foseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "fooff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "fop" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm0" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm1" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm2" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm3" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm4" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm5" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm6" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "xmm7" , nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_xmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "mxcsr" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm0" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm1" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm2" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm3" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm4" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm5" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm6" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr},
- { "ymm7" , nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM , dwarf_ymm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr}
+static RegisterInfo g_register_infos[] = {
+ // clang-format off
+ //NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE INVAL DYN EXPR SZ
+ //========== ======= == === ============= ==================== =================== =================== ========================= =================== =================== ======= ======= ======== ==
+ {"eax", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ebx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ecx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ecx, dwarf_ecx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"edx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edx, dwarf_edx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"esi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_esi, dwarf_esi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"edi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edi, dwarf_edi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ebp", "fp", 4, 0, eEncodingUint, eFormatHex, {dwarf_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"esp", "sp", 4, 0, eEncodingUint, eFormatHex, {dwarf_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"eip", "pc", 4, 0, eEncodingUint, eFormatHex, {dwarf_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"eflags", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"cs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ss", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ds", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"es", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"fs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"gs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st0", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st1", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st2", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st3", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st4", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st5", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st6", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"st7", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"fctrl", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"fstat", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ftag", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"fiseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"fioff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"foseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"fooff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"fop", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"xmm7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"mxcsr", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm0", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm1", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm2", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm3", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm4", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm5", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm6", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"ymm7", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"bnd0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"bnd1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"bnd2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"bnd3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"bndcfgu", nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
+ {"bndstatus",nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}
+ // clang-format on
};
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABISysV_i386::GetRegisterInfoArray (uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABISysV_i386::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
//------------------------------------------------------------------
@@ -191,614 +203,567 @@ ABISysV_i386::GetRegisterInfoArray (uint32_t &count)
//------------------------------------------------------------------
ABISP
-ABISysV_i386::CreateInstance (const ArchSpec &arch)
-{
- static ABISP g_abi_sp;
- if ((arch.GetTriple().getArch() == llvm::Triple::x86) &&
- arch.GetTriple().isOSLinux())
- {
- if (!g_abi_sp)
- g_abi_sp.reset (new ABISysV_i386);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_i386::CreateInstance(const ArchSpec &arch) {
+ static ABISP g_abi_sp;
+ if ((arch.GetTriple().getArch() == llvm::Triple::x86) &&
+ arch.GetTriple().isOSLinux()) {
+ if (!g_abi_sp)
+ g_abi_sp.reset(new ABISysV_i386);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_i386::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
- return false;
-
- uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
-
- // While using register info to write a register value to memory, the register info
- // just needs to have the correct size of a 32 bit register, the actual register it
- // pertains to is not important, just the size needs to be correct.
- // "eax" is used here for this purpose.
- const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
- if (!reg_info_32)
- return false; // TODO this should actually never happen
-
- Error error;
- RegisterValue reg_value;
-
- // Make room for the argument(s) on the stack
- sp -= 4 * args.size();
-
- // SP Alignment
- sp &= ~(16ull-1ull); // 16-byte alignment
-
- // Write arguments onto the stack
- addr_t arg_pos = sp;
- for (addr_t arg : args)
- {
- reg_value.SetUInt32(arg);
- error = reg_ctx->WriteRegisterValueToMemory (reg_info_32,
- arg_pos,
- reg_info_32->byte_size,
- reg_value);
- if (error.Fail())
- return false;
- arg_pos += 4;
- }
+bool ABISysV_i386::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- // The return address is pushed onto the stack
- sp -= 4;
- reg_value.SetUInt32(return_addr);
- error = reg_ctx->WriteRegisterValueToMemory (reg_info_32,
- sp,
- reg_info_32->byte_size,
- reg_value);
+ if (!reg_ctx)
+ return false;
+
+ uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+
+ // While using register info to write a register value to memory, the register
+ // info
+ // just needs to have the correct size of a 32 bit register, the actual
+ // register it
+ // pertains to is not important, just the size needs to be correct.
+ // "eax" is used here for this purpose.
+ const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
+ if (!reg_info_32)
+ return false; // TODO this should actually never happen
+
+ Error error;
+ RegisterValue reg_value;
+
+ // Make room for the argument(s) on the stack
+ sp -= 4 * args.size();
+
+ // SP Alignment
+ sp &= ~(16ull - 1ull); // 16-byte alignment
+
+ // Write arguments onto the stack
+ addr_t arg_pos = sp;
+ for (addr_t arg : args) {
+ reg_value.SetUInt32(arg);
+ error = reg_ctx->WriteRegisterValueToMemory(
+ reg_info_32, arg_pos, reg_info_32->byte_size, reg_value);
if (error.Fail())
- return false;
+ return false;
+ arg_pos += 4;
+ }
+
+ // The return address is pushed onto the stack
+ sp -= 4;
+ reg_value.SetUInt32(return_addr);
+ error = reg_ctx->WriteRegisterValueToMemory(
+ reg_info_32, sp, reg_info_32->byte_size, reg_value);
+ if (error.Fail())
+ return false;
- // Setting %esp to the actual stack value.
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
- return false;
+ // Setting %esp to the actual stack value.
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
+ return false;
- // Setting %eip to the address of the called function.
- if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, func_addr))
- return false;
+ // Setting %eip to the address of the called function.
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr))
+ return false;
- return true;
+ return true;
}
-static bool
-ReadIntegerArgument (Scalar &scalar,
- unsigned int bit_width,
- bool is_signed,
- Process *process,
- addr_t &current_stack_argument)
-{
- uint32_t byte_size = (bit_width + (8-1))/8;
- Error error;
+static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
+ bool is_signed, Process *process,
+ addr_t &current_stack_argument) {
+ uint32_t byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
- if (!process)
- return false;
-
- if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
- {
- current_stack_argument += byte_size;
- return true;
- }
+ if (!process)
return false;
-}
-
-bool
-ABISysV_i386::GetArgumentValues (Thread &thread,
- ValueList &values) const
-{
- unsigned int num_values = values.GetSize();
- unsigned int value_index;
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
- return false;
+ if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size,
+ is_signed, scalar, error)) {
+ current_stack_argument += byte_size;
+ return true;
+ }
+ return false;
+}
- // Get pointer to the first stack argument
- addr_t sp = reg_ctx->GetSP(0);
- if (!sp)
- return false;
+bool ABISysV_i386::GetArgumentValues(Thread &thread, ValueList &values) const {
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
- addr_t current_stack_argument = sp + 4; // jump over return address
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- for (value_index = 0;
- value_index < num_values;
- ++value_index)
- {
- Value *value = values.GetValueAtIndex(value_index);
+ if (!reg_ctx)
+ return false;
- if (!value)
- return false;
+ // Get pointer to the first stack argument
+ addr_t sp = reg_ctx->GetSP(0);
+ if (!sp)
+ return false;
- // Currently: Support for extracting values with Clang QualTypes only.
- CompilerType compiler_type (value->GetCompilerType());
- if (compiler_type)
- {
- bool is_signed;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed))
- {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread),
- is_signed,
- thread.GetProcess().get(),
- current_stack_argument);
- }
- else if (compiler_type.IsPointerType())
- {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread),
- false,
- thread.GetProcess().get(),
- current_stack_argument);
- }
- }
+ addr_t current_stack_argument = sp + 4; // jump over return address
+
+ for (value_index = 0; value_index < num_values; ++value_index) {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ // Currently: Support for extracting values with Clang QualTypes only.
+ CompilerType compiler_type(value->GetCompilerType());
+ if (compiler_type) {
+ bool is_signed;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
+ ReadIntegerArgument(value->GetScalar(),
+ compiler_type.GetBitSize(&thread), is_signed,
+ thread.GetProcess().get(), current_stack_argument);
+ } else if (compiler_type.IsPointerType()) {
+ ReadIntegerArgument(value->GetScalar(),
+ compiler_type.GetBitSize(&thread), false,
+ thread.GetProcess().get(), current_stack_argument);
+ }
}
- return true;
+ }
+ return true;
}
-Error
-ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
+Error ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ const uint32_t type_flags = compiler_type.GetTypeInfo();
+ Thread *thread = frame_sp->GetThread().get();
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ bool register_write_successful = true;
+
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
- const uint32_t type_flags = compiler_type.GetTypeInfo ();
- Thread *thread = frame_sp->GetThread().get();
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- bool register_write_successful = true;
+ // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
+ // The terminology 'Fundamental Data Types' used here is adopted from
+ // Table 2.1 of the reference document (specified on top of this file)
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
+ if (type_flags & eTypeIsPointer) // 'Pointer'
+ {
+ if (num_bytes != sizeof(uint32_t)) {
+ error.SetErrorString("Pointer to be returned is not 4 bytes wide");
+ return error;
}
-
- // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
- // The terminology 'Fundamental Data Types' used here is adopted from
- // Table 2.1 of the reference document (specified on top of this file)
-
- if (type_flags & eTypeIsPointer) // 'Pointer'
+ lldb::offset_t offset = 0;
+ const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+ register_write_successful =
+ reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
+ } else if ((type_flags & eTypeIsScalar) ||
+ (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
+ {
+ lldb::offset_t offset = 0;
+ const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
+
+ if (type_flags & eTypeIsInteger) // 'Integral' except enum
{
- if(num_bytes != sizeof(uint32_t))
- {
- error.SetErrorString("Pointer to be returned is not 4 bytes wide");
- return error;
- }
- lldb::offset_t offset = 0;
- const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
+ switch (num_bytes) {
+ default:
+ break;
+ case 16:
+ // For clang::BuiltinType::UInt128 & Int128
+ // ToDo: Need to decide how to handle it
+ break;
+ case 8: {
+ uint32_t raw_value_low = data.GetMaxU32(&offset, 4);
+ const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
+ uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset);
+ register_write_successful =
+ (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value_low) &&
+ reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value_high));
+ break;
+ }
+ case 4:
+ case 2:
+ case 1: {
uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
- register_write_successful = reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value);
- }
- else if ((type_flags & eTypeIsScalar) || (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
+ register_write_successful =
+ reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
+ break;
+ }
+ }
+ } else if (type_flags & eTypeIsEnumeration) // handles enum
{
- lldb::offset_t offset = 0;
- const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
-
- if (type_flags & eTypeIsInteger) // 'Integral' except enum
- {
- switch (num_bytes)
- {
- default:
- break;
- case 16:
- // For clang::BuiltinType::UInt128 & Int128
- // ToDo: Need to decide how to handle it
- break;
- case 8:
- {
- uint32_t raw_value_low = data.GetMaxU32(&offset, 4);
- const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
- uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset);
- register_write_successful = (reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value_low) &&
- reg_ctx->WriteRegisterFromUnsigned (edx_info, raw_value_high));
- break;
- }
- case 4:
- case 2:
- case 1:
- {
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
- register_write_successful = reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value);
- break;
- }
- }
- }
- else if (type_flags & eTypeIsEnumeration) // handles enum
- {
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
- register_write_successful = reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value);
- }
- else if (type_flags & eTypeIsFloat) // 'Floating Point'
- {
- RegisterValue st0_value, fstat_value, ftag_value;
- const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
- const RegisterInfo *fstat_info = reg_ctx->GetRegisterInfoByName("fstat", 0);
- const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0);
-
- /* According to Page 3-12 of document
- System V Application Binary Interface, Intel386 Architecture Processor Supplement, Fourth Edition
- To return Floating Point values, all st% registers except st0 should be empty after exiting from
- a function. This requires setting fstat and ftag registers to specific values.
- fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't specify the specific
- value of TOP in case of function return. Hence, we set the TOP field to 7 by our choice. */
- uint32_t value_fstat_u32 = 0x00003800;
-
- /* ftag: Implication of setting TOP to 7 and indicating all st% registers empty except st0 is to set
- 7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to 0. This is in accordance
- with the document Intel 64 and IA-32 Architectures Software Developer's Manual, January 2015 */
- uint32_t value_ftag_u32 = 0x00000080;
-
- if (num_bytes <= 12) // handles float, double, long double, __float80
- {
- long double value_long_dbl = 0.0;
- if (num_bytes == 4)
- value_long_dbl = data.GetFloat(&offset);
- else if (num_bytes == 8)
- value_long_dbl = data.GetDouble(&offset);
- else if (num_bytes == 12)
- value_long_dbl = data.GetLongDouble(&offset);
- else
- {
- error.SetErrorString ("Invalid number of bytes for this return type");
- return error;
- }
- st0_value.SetLongDouble(value_long_dbl);
- fstat_value.SetUInt32(value_fstat_u32);
- ftag_value.SetUInt32(value_ftag_u32);
- register_write_successful = reg_ctx->WriteRegister(st0_info, st0_value) &&
- reg_ctx->WriteRegister(fstat_info, fstat_value) &&
- reg_ctx->WriteRegister(ftag_info, ftag_value);
- }
- else if(num_bytes == 16) // handles __float128
- {
- error.SetErrorString ("Implementation is missing for this clang type.");
- }
- }
- else
- {
- // Neither 'Integral' nor 'Floating Point'. If flow reaches here
- // then check type_flags. This type_flags is not a valid type.
- error.SetErrorString ("Invalid clang type");
- }
- }
- else
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+ register_write_successful =
+ reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
+ } else if (type_flags & eTypeIsFloat) // 'Floating Point'
{
- /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and 'Aggregate' data types
- are yet to be implemented */
- error.SetErrorString ("Currently only Integral and Floating Point clang types are supported.");
+ RegisterValue st0_value, fstat_value, ftag_value;
+ const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
+ const RegisterInfo *fstat_info =
+ reg_ctx->GetRegisterInfoByName("fstat", 0);
+ const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0);
+
+ /* According to Page 3-12 of document
+ System V Application Binary Interface, Intel386 Architecture Processor
+ Supplement, Fourth Edition
+ To return Floating Point values, all st% registers except st0 should be
+ empty after exiting from
+ a function. This requires setting fstat and ftag registers to specific
+ values.
+ fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't
+ specify the specific
+ value of TOP in case of function return. Hence, we set the TOP field to 7
+ by our choice. */
+ uint32_t value_fstat_u32 = 0x00003800;
+
+ /* ftag: Implication of setting TOP to 7 and indicating all st% registers
+ empty except st0 is to set
+ 7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to
+ 0. This is in accordance
+ with the document Intel 64 and IA-32 Architectures Software Developer's
+ Manual, January 2015 */
+ uint32_t value_ftag_u32 = 0x00000080;
+
+ if (num_bytes <= 12) // handles float, double, long double, __float80
+ {
+ long double value_long_dbl = 0.0;
+ if (num_bytes == 4)
+ value_long_dbl = data.GetFloat(&offset);
+ else if (num_bytes == 8)
+ value_long_dbl = data.GetDouble(&offset);
+ else if (num_bytes == 12)
+ value_long_dbl = data.GetLongDouble(&offset);
+ else {
+ error.SetErrorString("Invalid number of bytes for this return type");
+ return error;
+ }
+ st0_value.SetLongDouble(value_long_dbl);
+ fstat_value.SetUInt32(value_fstat_u32);
+ ftag_value.SetUInt32(value_ftag_u32);
+ register_write_successful =
+ reg_ctx->WriteRegister(st0_info, st0_value) &&
+ reg_ctx->WriteRegister(fstat_info, fstat_value) &&
+ reg_ctx->WriteRegister(ftag_info, ftag_value);
+ } else if (num_bytes == 16) // handles __float128
+ {
+ error.SetErrorString("Implementation is missing for this clang type.");
+ }
+ } else {
+ // Neither 'Integral' nor 'Floating Point'. If flow reaches here
+ // then check type_flags. This type_flags is not a valid type.
+ error.SetErrorString("Invalid clang type");
}
- if (!register_write_successful)
- error.SetErrorString ("Register writing failed");
- return error;
+ } else {
+ /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and
+ 'Aggregate' data types
+ are yet to be implemented */
+ error.SetErrorString("Currently only Integral and Floating Point clang "
+ "types are supported.");
+ }
+ if (!register_write_successful)
+ error.SetErrorString("Register writing failed");
+ return error;
}
-ValueObjectSP
-ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
- CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
+ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
- if (!return_compiler_type)
- return return_valobj_sp;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- value.SetCompilerType (return_compiler_type);
+ value.SetCompilerType(return_compiler_type);
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
- const uint32_t type_flags = return_compiler_type.GetTypeInfo ();
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo();
+
+ unsigned eax_id =
+ reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+ unsigned edx_id =
+ reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
+
+ // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
+ // The terminology 'Fundamental Data Types' used here is adopted from
+ // Table 2.1 of the reference document (specified on top of this file)
+
+ if (type_flags & eTypeIsPointer) // 'Pointer'
+ {
+ uint32_t ptr =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff;
+ value.SetValueType(Value::eValueTypeScalar);
+ value.GetScalar() = ptr;
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if ((type_flags & eTypeIsScalar) ||
+ (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
+ {
+ value.SetValueType(Value::eValueTypeScalar);
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ bool success = false;
+
+ if (type_flags & eTypeIsInteger) // 'Integral' except enum
+ {
+ const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
+ uint64_t raw_value =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff;
+ raw_value |=
+ (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) &
+ 0xffffffff)
+ << 32;
+
+ switch (byte_size) {
+ default:
+ break;
+
+ case 16:
+ // For clang::BuiltinType::UInt128 & Int128
+ // ToDo: Need to decide how to handle it
+ break;
+
+ case 8:
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
- unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
- unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
+ case 4:
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
- // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
- // The terminology 'Fundamental Data Types' used here is adopted from
- // Table 2.1 of the reference document (specified on top of this file)
+ case 2:
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
- if (type_flags & eTypeIsPointer) // 'Pointer'
+ case 1:
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsEnumeration) // handles enum
{
- uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
- value.SetValueType(Value::eValueTypeScalar);
- value.GetScalar() = ptr;
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- }
- else if ((type_flags & eTypeIsScalar) || (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
+ uint32_t enm =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff;
+ value.SetValueType(Value::eValueTypeScalar);
+ value.GetScalar() = enm;
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsFloat) // 'Floating Point'
{
- value.SetValueType(Value::eValueTypeScalar);
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- bool success = false;
-
- if (type_flags & eTypeIsInteger) // 'Integral' except enum
- {
- const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
- raw_value |= (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 0xffffffff) << 32;
-
- switch (byte_size)
+ if (byte_size <= 12) // handles float, double, long double, __float80
+ {
+ const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
+ RegisterValue st0_value;
+
+ if (reg_ctx->ReadRegister(st0_info, st0_value)) {
+ DataExtractor data;
+ if (st0_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ long double value_long_double = data.GetLongDouble(&offset);
+
+ if (byte_size == 4) // float is 4 bytes
{
- default:
- break;
-
- case 16:
- // For clang::BuiltinType::UInt128 & Int128
- // ToDo: Need to decide how to handle it
- break;
-
- case 8:
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
-
- case 4:
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
-
- case 2:
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
-
- case 1:
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
- }
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- }
- else if (type_flags & eTypeIsEnumeration) // handles enum
- {
- uint32_t enm = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
- value.SetValueType(Value::eValueTypeScalar);
- value.GetScalar() = enm;
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- }
- else if (type_flags & eTypeIsFloat) // 'Floating Point'
- {
- if (byte_size <= 12) // handles float, double, long double, __float80
+ float value_float = (float)value_long_double;
+ value.GetScalar() = value_float;
+ success = true;
+ } else if (byte_size == 8) // double is 8 bytes
{
- const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
- RegisterValue st0_value;
-
- if (reg_ctx->ReadRegister (st0_info, st0_value))
- {
- DataExtractor data;
- if (st0_value.GetData(data))
- {
- lldb::offset_t offset = 0;
- long double value_long_double = data.GetLongDouble(&offset);
-
- if (byte_size == 4) // float is 4 bytes
- {
- float value_float = (float)value_long_double;
- value.GetScalar() = value_float;
- success = true;
- }
- else if (byte_size == 8) // double is 8 bytes
- {
- // On Android Platform: long double is also 8 bytes
- // It will be handled here only.
- 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
- {
- value.GetScalar() = value_long_double;
- success = true;
- }
- }
- }
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- }
- else if(byte_size == 16) // handles __float128
+ // 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
{
- lldb::addr_t storage_addr = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
- return_valobj_sp = ValueObjectMemory::Create (&thread,
- "",
- Address (storage_addr, nullptr),
- return_compiler_type);
+ value.GetScalar() = value_long_double;
+ success = true;
}
+ }
}
- else // Neither 'Integral' nor 'Floating Point'
- {
- // If flow reaches here then check type_flags
- // This type_flags is unhandled
- }
- }
- else if (type_flags & eTypeIsComplex) // 'Complex Floating Point'
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (byte_size == 16) // handles __float128
+ {
+ lldb::addr_t storage_addr = (uint32_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff);
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(storage_addr, nullptr), return_compiler_type);
+ }
+ } else // Neither 'Integral' nor 'Floating Point'
{
- // ToDo: Yet to be implemented
+ // If flow reaches here then check type_flags
+ // This type_flags is unhandled
}
- else if (type_flags & eTypeIsVector) // 'Packed'
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (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)
- {
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(vec_reg, reg_value))
- {
- Error error;
- if (reg_value.GetAsMemoryData (vec_reg,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
- }
- 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));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue reg_value;
- RegisterValue reg_value2;
- if (reg_ctx->ReadRegister(vec_reg, reg_value) && reg_ctx->ReadRegister(vec_reg2, reg_value2))
- {
-
- Error error;
- if (reg_value.GetAsMemoryData (vec_reg,
- heap_data_ap->GetBytes(),
- vec_reg->byte_size,
- byte_order,
- error) &&
- reg_value2.GetAsMemoryData (vec_reg2,
- heap_data_ap->GetBytes() + vec_reg->byte_size,
- heap_data_ap->GetByteSize() - vec_reg->byte_size,
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
- }
+ } else if (type_flags & eTypeIsComplex) // 'Complex Floating Point'
+ {
+ // 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) {
+ 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) {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(vec_reg, reg_value)) {
+ Error error;
+ if (reg_value.GetAsMemoryData(vec_reg, heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(),
+ byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order, process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
+ }
+ }
+ } 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));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ RegisterValue reg_value2;
+ if (reg_ctx->ReadRegister(vec_reg, reg_value) &&
+ reg_ctx->ReadRegister(vec_reg2, reg_value2)) {
+
+ Error error;
+ if (reg_value.GetAsMemoryData(vec_reg, heap_data_ap->GetBytes(),
+ vec_reg->byte_size, byte_order,
+ error) &&
+ reg_value2.GetAsMemoryData(
+ vec_reg2, heap_data_ap->GetBytes() + vec_reg->byte_size,
+ heap_data_ap->GetByteSize() - vec_reg->byte_size,
+ byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order, process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
}
+ }
}
+ }
}
+ }
}
- else // 'Decimal Floating Point'
- {
- //ToDo: Yet to be implemented
- }
- return return_valobj_sp;
+ } else // 'Decimal Floating Point'
+ {
+ // ToDo: Yet to be implemented
+ }
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_i386::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
-
- if (!return_compiler_type)
- return return_valobj_sp;
+ValueObjectSP ABISysV_i386::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
- ExecutionContext exe_ctx (thread.shared_from_this());
- return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
- if (return_valobj_sp)
- return return_valobj_sp;
-
- RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return return_valobj_sp;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- if (return_compiler_type.IsAggregateType())
- {
- unsigned eax_id = reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
- lldb::addr_t storage_addr = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
- return_valobj_sp = ValueObjectMemory::Create (&thread,
- "",
- Address (storage_addr, nullptr),
- return_compiler_type);
- }
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
+ if (return_valobj_sp)
+ return return_valobj_sp;
+ RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
return return_valobj_sp;
+
+ if (return_compiler_type.IsAggregateType()) {
+ unsigned eax_id =
+ reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+ lldb::addr_t storage_addr = (uint32_t)(
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
+ 0xffffffff);
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(storage_addr, nullptr), return_compiler_type);
+ }
+
+ return return_valobj_sp;
}
// This defines CFA as esp+4
// The saved pc is at CFA-4 (i.e. esp+0)
// The saved esp is CFA+0
-bool
-ABISysV_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t sp_reg_num = dwarf_esp;
- uint32_t pc_reg_num = dwarf_eip;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("i386 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- return true;
+bool ABISysV_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t sp_reg_num = dwarf_esp;
+ uint32_t pc_reg_num = dwarf_eip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("i386 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
}
// This defines CFA as ebp+8
@@ -806,104 +771,89 @@ ABISysV_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
// The saved ebp is at CFA-8 (i.e. ebp+0)
// The saved esp is CFA+0
-bool
-ABISysV_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- uint32_t fp_reg_num = dwarf_ebp;
- uint32_t sp_reg_num = dwarf_esp;
- uint32_t pc_reg_num = dwarf_eip;
+ uint32_t fp_reg_num = dwarf_ebp;
+ uint32_t sp_reg_num = dwarf_esp;
+ uint32_t pc_reg_num = dwarf_eip;
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 4;
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 4;
- row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
- row->SetOffset (0);
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("i386 default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("i386 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
}
// According to "Register Usage" in reference document (specified on top
// of this source file) ebx, ebp, esi, edi and esp registers are preserved
// i.e. non-volatile i.e. callee-saved on i386
-bool
-ABISysV_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
-{
- if (!reg_info)
- return false;
-
- // Saved registers are ebx, ebp, esi, edi, esp, eip
- const char *name = reg_info->name;
- if (name[0] == 'e')
- {
- switch (name[1])
- {
- case 'b':
- if (name[2] == 'x' || name[2] == 'p')
- return name[3] == '\0';
- break;
- case 'd':
- if (name[2] == 'i')
- return name[3] == '\0';
- break;
- case 'i':
- if (name[2] == 'p')
- return name[3] == '\0';
- break;
- case 's':
- if (name[2] == 'i' || name[2] == 'p')
- return name[3] == '\0';
- break;
- }
+bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (!reg_info)
+ return false;
+
+ // Saved registers are ebx, ebp, esi, edi, esp, eip
+ const char *name = reg_info->name;
+ if (name[0] == 'e') {
+ switch (name[1]) {
+ case 'b':
+ if (name[2] == 'x' || name[2] == 'p')
+ return name[3] == '\0';
+ break;
+ case 'd':
+ if (name[2] == 'i')
+ return name[3] == '\0';
+ break;
+ case 'i':
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+ case 's':
+ if (name[2] == 'i' || name[2] == 'p')
+ return name[3] == '\0';
+ break;
}
+ }
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
- if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
- return true;
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
- return false;
+ return false;
}
-void
-ABISysV_i386::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "System V ABI for i386 targets",
- CreateInstance);
+void ABISysV_i386::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance);
}
-void
-ABISysV_i386::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_i386::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_i386::GetPluginNameStatic()
-{
- static ConstString g_name("sysv-i386");
- return g_name;
+lldb_private::ConstString ABISysV_i386::GetPluginNameStatic() {
+ static ConstString g_name("sysv-i386");
+ return g_name;
}
-lldb_private::ConstString
-ABISysV_i386::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_i386::GetPluginName() {
+ return GetPluginNameStatic();
}
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
index 2d0f097c328e..8d1d76b5dfd9 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
@@ -14,128 +14,104 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_i386 :
- public lldb_private::ABI
-{
+class ABISysV_i386 : public lldb_private::ABI {
public:
- ~ABISysV_i386() override = default;
-
- size_t
- GetRedZoneSize () const override
- {
- return 0; // There is no red zone for i386 Architecture
- }
-
- bool
- PrepareTrivialCall (lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues (lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- lldb::ValueObjectSP
- GetReturnValueObjectImpl (lldb_private::Thread &thread,
- lldb_private::CompilerType &type) const override;
-
- bool
- CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info) override
- {
- return !RegisterIsCalleeSaved (reg_info);
- }
-
- // The SysV i386 ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (4-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
-
- // ToDo: When __m256 arguments are passed then stack frames should be
- // 32 byte aligned. Decide what to do for 32 byte alignment checking
- bool
- CallFrameAddressIsValid (lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 4 byte aligned
- if (cfa & (4ull - 1ull))
- return false; // Not 4 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid (lldb::addr_t pc) override
- {
- // Check whether the address is a valid 32 bit address
- return (pc <= UINT32_MAX);
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray (uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ ~ABISysV_i386() override = default;
+
+ size_t GetRedZoneSize() const override {
+ return 0; // There is no red zone for i386 Architecture
+ }
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override {
+ return !RegisterIsCalleeSaved(reg_info);
+ }
+
+ // The SysV i386 ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (4-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+
+ // ToDo: When __m256 arguments are passed then stack frames should be
+ // 32 byte aligned. Decide what to do for 32 byte alignment checking
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 4 byte aligned
+ if (cfa & (4ull - 1ull))
+ return false; // Not 4 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Check whether the address is a valid 32 bit address
+ return (pc <= UINT32_MAX);
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
protected:
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const;
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- bool
- RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_i386() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_i386() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_i386_h_
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index d6b57f9f3939..b97fffe3efa3 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -25,696 +25,1055 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-enum dwarf_regnums
-{
- dwarf_r0 = 0,
- dwarf_r1,
- dwarf_r2,
- dwarf_r3,
- dwarf_r4,
- dwarf_r5,
- dwarf_r6,
- dwarf_r7,
- dwarf_r8,
- dwarf_r9,
- dwarf_r10,
- dwarf_r11,
- dwarf_r12,
- dwarf_r13,
- dwarf_r14,
- dwarf_r15,
- dwarf_r16,
- dwarf_r17,
- dwarf_r18,
- dwarf_r19,
- dwarf_r20,
- dwarf_r21,
- dwarf_r22,
- dwarf_r23,
- dwarf_r24,
- dwarf_r25,
- dwarf_r26,
- dwarf_r27,
- dwarf_r28,
- dwarf_r29,
- dwarf_r30,
- dwarf_r31,
- dwarf_sr,
- dwarf_lo,
- dwarf_hi,
- dwarf_bad,
- dwarf_cause,
- dwarf_pc
+enum dwarf_regnums {
+ dwarf_r0 = 0,
+ dwarf_r1,
+ dwarf_r2,
+ dwarf_r3,
+ dwarf_r4,
+ dwarf_r5,
+ dwarf_r6,
+ dwarf_r7,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_r13,
+ dwarf_r14,
+ dwarf_r15,
+ dwarf_r16,
+ dwarf_r17,
+ dwarf_r18,
+ dwarf_r19,
+ dwarf_r20,
+ dwarf_r21,
+ dwarf_r22,
+ dwarf_r23,
+ dwarf_r24,
+ dwarf_r25,
+ dwarf_r26,
+ dwarf_r27,
+ dwarf_r28,
+ dwarf_r29,
+ dwarf_r30,
+ dwarf_r31,
+ dwarf_sr,
+ dwarf_lo,
+ dwarf_hi,
+ dwarf_bad,
+ dwarf_cause,
+ dwarf_pc
};
-static const RegisterInfo
-g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGINS LLDB NATIVE VALUE REGS INVALIDATE REGS
- // ======== ====== == === ============= =========== ============ ============== ============ ================= =================== ========== =================
- { "r0" , "zero", 4, 0, eEncodingUint, eFormatHex, { dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r1" , "AT", 4, 0, eEncodingUint, eFormatHex, { dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r2" , "v0", 4, 0, eEncodingUint, eFormatHex, { dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r3" , "v1", 4, 0, eEncodingUint, eFormatHex, { dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r4" , "arg1", 4, 0, eEncodingUint, eFormatHex, { dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r5" , "arg2", 4, 0, eEncodingUint, eFormatHex, { dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r6" , "arg3", 4, 0, eEncodingUint, eFormatHex, { dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r7" , "arg4", 4, 0, eEncodingUint, eFormatHex, { dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8" , "arg5", 4, 0, eEncodingUint, eFormatHex, { dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9" , "arg6", 4, 0, eEncodingUint, eFormatHex, { dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10" , "arg7", 4, 0, eEncodingUint, eFormatHex, { dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11" , "arg8", 4, 0, eEncodingUint, eFormatHex, { dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r15" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r16" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r17" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r18" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r19" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r20" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r21" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r22" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r23" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r24" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r25" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r26" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r27" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r28" , "gp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r29" , "sp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r30" , "fp", 4, 0, eEncodingUint, eFormatHex, { dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r31" , "ra", 4, 0, eEncodingUint, eFormatHex, { dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "sr" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "lo" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "hi" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "bad" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cause" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "pc" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+static const RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
+ // DWARF GENERIC PROCESS PLUGINS
+ // LLDB NATIVE VALUE REGS INVALIDATE REGS
+ // ======== ====== == === ============= =========== ============
+ // ============== ============ =================
+ // =================== ========== =================
+ {"r0",
+ "zero",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ "AT",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ "v0",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ "v1",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ "arg1",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ "arg2",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ "arg3",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ "arg4",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ "arg5",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ "arg6",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ "arg7",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ "arg8",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r15",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r16",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r17",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r18",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r19",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r20",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r21",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r22",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r23",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r24",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r25",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r26",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r27",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r28",
+ "gp",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r29",
+ "sp",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r30",
+ "fp",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r31",
+ "ra",
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lo",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"hi",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bad",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cause",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
};
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
const lldb_private::RegisterInfo *
-ABISysV_mips::GetRegisterInfoArray (uint32_t &count)
-{
- count = k_num_register_infos;
- return g_register_infos;
+ABISysV_mips::GetRegisterInfoArray(uint32_t &count) {
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABISysV_mips::GetRedZoneSize () const
-{
- return 0;
-}
+size_t ABISysV_mips::GetRedZoneSize() const { return 0; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_mips::CreateInstance (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);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_mips::CreateInstance(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);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_mips::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
+
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
- if (log)
- {
- StreamString s;
- s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(),
- (uint64_t)sp,
- (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
- s.PutCString (")");
- log->PutCString(s.GetString().c_str());
- }
+ const RegisterInfo *reg_info = nullptr;
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
+ RegisterValue reg_value;
- const RegisterInfo *reg_info = nullptr;
+ // Argument registers
+ const char *reg_names[] = {"r4", "r5", "r6", "r7"};
- RegisterValue reg_value;
+ llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
- // Argument registers
- const char *reg_names[] = { "r4", "r5", "r6", "r7" };
+ // Write arguments to registers
+ for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
+ if (ai == ae)
+ break;
- llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + i);
+ if (log)
+ log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
+ args[i], reg_info->name);
- // Write arguments to registers
- for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i)
- {
- if (ai == ae)
- break;
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
- reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
+ ++ai;
+ }
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
+ // If we have more than 4 arguments --Spill onto the stack
+ if (ai != ae) {
+ // No of arguments to go on stack
+ size_t num_stack_regs = args.size();
- ++ai;
- }
+ // Allocate needed space for args on the stack
+ sp -= (num_stack_regs * 4);
- // If we have more than 4 arguments --Spill onto the stack
- if (ai != ae)
- {
- // No of arguments to go on stack
- size_t num_stack_regs = args.size();
-
- // Allocate needed space for args on the stack
- sp -= (num_stack_regs * 4);
-
- // Keep the stack 8 byte aligned
- sp &= ~(8ull-1ull);
-
- // just using arg1 to get the right size
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
-
- addr_t arg_pos = sp+16;
-
- size_t i = 4;
- for (; ai != ae; ++ai)
- {
- reg_value.SetUInt32(*ai);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "", i+1, args[i], arg_pos);
-
- if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
- return false;
- arg_pos += reg_info->byte_size;
- i++;
- }
- }
+ // Keep the stack 8 byte aligned
+ sp &= ~(8ull - 1ull);
- Error error;
- const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
- const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
- const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
+ // just using arg1 to get the right size
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
- if (log)
- log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+ addr_t arg_pos = sp + 16;
+
+ size_t i = 4;
+ for (; ai != ae; ++ai) {
+ reg_value.SetUInt32(*ai);
+ if (log)
+ log->Printf("About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "",
+ i + 1, args[i], arg_pos);
- /* Write r0 with 0, in case we are stopped in syscall,
- * such setting prevents automatic decrement of the PC.
- * This clears the bug 23659 for MIPS.
- */
- if (!reg_ctx->WriteRegisterFromUnsigned (r0_info, (uint64_t)0))
+ if (reg_ctx
+ ->WriteRegisterValueToMemory(reg_info, arg_pos,
+ reg_info->byte_size, reg_value)
+ .Fail())
return false;
+ arg_pos += reg_info->byte_size;
+ i++;
+ }
+ }
+
+ Error error;
+ const RegisterInfo *pc_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const RegisterInfo *ra_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+ const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
+
+ if (log)
+ log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+
+ /* Write r0 with 0, in case we are stopped in syscall,
+ * such setting prevents automatic decrement of the PC.
+ * This clears the bug 23659 for MIPS.
+ */
+ if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
+ return false;
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
- return false;
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
+ return false;
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ if (log)
+ log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
- // Set "ra" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
- return false;
+ // Set "ra" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
+ return false;
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ if (log)
+ log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
- // Set pc to the address of the called function.
- if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
- return false;
-
- if (log)
- log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
-
- // All callers of position independent functions must place the address of the called function in t9 (r25)
- if (!reg_ctx->WriteRegisterFromUnsigned (r25_info, func_addr))
- return false;
-
- return true;
-}
+ // Set pc to the address of the called function.
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
+
+ if (log)
+ log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
-bool
-ABISysV_mips::GetArgumentValues (Thread &thread, ValueList &values) const
-{
+ // All callers of position independent functions must place the address of the
+ // called function in t9 (r25)
+ if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
return false;
+
+ return true;
}
-Error
-ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
+bool ABISysV_mips::GetArgumentValues(Thread &thread, ValueList &values) const {
+ return false;
+}
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
+Error ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- Thread *thread = frame_sp->GetThread().get();
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
- bool is_signed;
- uint32_t count;
- bool is_complex;
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ if (num_bytes <= 4) {
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+ if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
+ set_it_simple = true;
+ } else {
+ uint32_t raw_value = data.GetMaxU32(&offset, 4);
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
- {
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
+ if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
+ const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
- if (num_bytes <= 4)
- {
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- uint32_t raw_value = data.GetMaxU32(&offset, 4);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value))
- {
- const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
- uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
-
- if (reg_ctx->WriteRegisterFromUnsigned (r3_info, raw_value))
- set_it_simple = true;
- }
- }
+ if (reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
+ set_it_simple = true;
}
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
- }
- }
- else if (compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (is_complex)
- error.SetErrorString ("We don't support returning complex values at present");
- else
- error.SetErrorString ("We don't support returning float values at present");
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
}
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ error.SetErrorString(
+ "We don't support returning complex values at present");
+ else
+ error.SetErrorString(
+ "We don't support returning float values at present");
+ }
- if (!set_it_simple)
- error.SetErrorString ("We only support setting simple integer return types at present.");
+ if (!set_it_simple)
+ error.SetErrorString(
+ "We only support setting simple integer return types at present.");
- return error;
+ return error;
}
-ValueObjectSP
-ABISysV_mips::GetReturnValueObjectSimple (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- return return_valobj_sp;
+ValueObjectSP ABISysV_mips::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_mips::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
+ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
- if (!return_compiler_type)
- return return_valobj_sp;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
- return return_valobj_sp;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
+ return return_valobj_sp;
- Target *target = exe_ctx.GetTargetPtr();
- const ArchSpec target_arch = target->GetArchitecture();
- ByteOrder target_byte_order = target_arch.GetByteOrder();
- value.SetCompilerType(return_compiler_type);
- uint32_t fp_flag = target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
+ Target *target = exe_ctx.GetTargetPtr();
+ const ArchSpec target_arch = target->GetArchitecture();
+ ByteOrder target_byte_order = target_arch.GetByteOrder();
+ value.SetCompilerType(return_compiler_type);
+ uint32_t fp_flag =
+ target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- bool is_signed = false;
- bool is_complex = false;
- uint32_t count = 0;
-
- // 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);
- if (return_compiler_type.IsIntegerOrEnumerationType (is_signed))
- {
- switch (bit_width)
- {
- default:
- return return_valobj_sp;
- case 64:
- {
- const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
- uint64_t raw_value;
- raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX;
- raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) & UINT32_MAX)) << 32;
- if (is_signed)
- value.GetScalar() = (int64_t)raw_value;
- else
- value.GetScalar() = (uint64_t)raw_value;
- }
- break;
- case 32:
- if (is_signed)
- value.GetScalar() = (int32_t)(reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
- break;
- case 16:
- if (is_signed)
- value.GetScalar() = (int16_t)(reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
- break;
- case 8:
- if (is_signed)
- value.GetScalar() = (int8_t)(reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
- break;
- }
- }
- else if (return_compiler_type.IsPointerType ())
- {
- uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX;
- value.GetScalar() = ptr;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ bool is_signed = false;
+ bool is_complex = false;
+ uint32_t count = 0;
+
+ // 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);
+ if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) {
+ switch (bit_width) {
+ default:
+ return return_valobj_sp;
+ case 64: {
+ const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ uint64_t raw_value;
+ raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX;
+ raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) &
+ UINT32_MAX))
+ << 32;
+ if (is_signed)
+ value.GetScalar() = (int64_t)raw_value;
+ else
+ value.GetScalar() = (uint64_t)raw_value;
+ } break;
+ case 32:
+ if (is_signed)
+ value.GetScalar() = (int32_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
+ break;
+ case 16:
+ if (is_signed)
+ value.GetScalar() = (int16_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
+ break;
+ case 8:
+ if (is_signed)
+ value.GetScalar() = (int8_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(
+ reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
+ break;
}
- else if (return_compiler_type.IsAggregateType ())
- {
- // Structure/Vector is always passed in memory and pointer to that memory is passed in r2.
- uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);
- // We have got the address. Create a memory object out of it
- return_valobj_sp = ValueObjectMemory::Create(&thread,
- "",
- Address(mem_address, nullptr),
- return_compiler_type);
+ } else if (return_compiler_type.IsPointerType()) {
+ uint32_t ptr =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) &
+ UINT32_MAX;
+ value.GetScalar() = ptr;
+ } else if (return_compiler_type.IsAggregateType()) {
+ // Structure/Vector is always passed in memory and pointer to that memory is
+ // passed in r2.
+ uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfoByName("r2", 0), 0);
+ // We have got the address. Create a memory object out of it
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(mem_address, nullptr), return_compiler_type);
+ return return_valobj_sp;
+ } else if (return_compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (IsSoftFloat(fp_flag)) {
+ uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
+ if (count != 1 && is_complex)
return return_valobj_sp;
+ switch (bit_width) {
+ default:
+ return return_valobj_sp;
+ case 32:
+ static_assert(sizeof(float) == sizeof(uint32_t), "");
+ value.GetScalar() = *((float *)(&raw_value));
+ break;
+ case 64:
+ static_assert(sizeof(double) == sizeof(uint64_t), "");
+ const RegisterInfo *r3_reg_info =
+ reg_ctx->GetRegisterInfoByName("r3", 0);
+ if (target_byte_order == eByteOrderLittle)
+ raw_value =
+ ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) |
+ raw_value;
+ else
+ raw_value = (raw_value << 32) |
+ reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0);
+ value.GetScalar() = *((double *)(&raw_value));
+ break;
+ }
}
- else if (return_compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (IsSoftFloat (fp_flag))
- {
- uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
- if (count != 1 && is_complex)
- return return_valobj_sp;
- switch (bit_width)
- {
- default:
- return return_valobj_sp;
- case 32:
- static_assert(sizeof(float) == sizeof(uint32_t), "");
- value.GetScalar() = *((float *)(&raw_value));
- break;
- case 64:
- static_assert(sizeof(double) == sizeof(uint64_t), "");
- const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
- if (target_byte_order == eByteOrderLittle)
- raw_value = ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) | raw_value;
- else
- raw_value = (raw_value << 32) | reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0);
- value.GetScalar() = *((double *)(&raw_value));
- break;
- }
+
+ else {
+ const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
+ RegisterValue f0_value;
+ DataExtractor f0_data;
+ reg_ctx->ReadRegister(f0_info, f0_value);
+ f0_value.GetData(f0_data);
+ lldb::offset_t offset = 0;
+
+ if (count == 1 && !is_complex) {
+ switch (bit_width) {
+ default:
+ return return_valobj_sp;
+ case 64: {
+ static_assert(sizeof(double) == sizeof(uint64_t), "");
+ const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
+ RegisterValue f1_value;
+ DataExtractor f1_data;
+ reg_ctx->ReadRegister(f1_info, f1_value);
+ DataExtractor *copy_from_extractor = nullptr;
+ DataBufferSP data_sp(new DataBufferHeap(8, 0));
+ DataExtractor return_ext(
+ data_sp, target_byte_order,
+ target->GetArchitecture().GetAddressByteSize());
+
+ if (target_byte_order == eByteOrderLittle) {
+ copy_from_extractor = &f0_data;
+ copy_from_extractor->CopyByteOrderedData(
+ offset, 4, data_sp->GetBytes(), 4, target_byte_order);
+ f1_value.GetData(f1_data);
+ copy_from_extractor = &f1_data;
+ copy_from_extractor->CopyByteOrderedData(
+ offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
+ } else {
+ copy_from_extractor = &f0_data;
+ copy_from_extractor->CopyByteOrderedData(
+ offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
+ f1_value.GetData(f1_data);
+ copy_from_extractor = &f1_data;
+ copy_from_extractor->CopyByteOrderedData(
+ offset, 4, data_sp->GetBytes(), 4, target_byte_order);
+ }
+ value.GetScalar() = (double)return_ext.GetDouble(&offset);
+ break;
}
-
- else
- {
- const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
- RegisterValue f0_value;
- DataExtractor f0_data;
- reg_ctx->ReadRegister (f0_info, f0_value);
- f0_value.GetData(f0_data);
- lldb::offset_t offset = 0;
-
- if (count == 1 && !is_complex)
- {
- switch (bit_width)
- {
- default:
- return return_valobj_sp;
- case 64:
- {
- static_assert(sizeof(double) == sizeof(uint64_t), "");
- const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
- RegisterValue f1_value;
- DataExtractor f1_data;
- reg_ctx->ReadRegister (f1_info, f1_value);
- DataExtractor *copy_from_extractor = nullptr;
- DataBufferSP data_sp (new DataBufferHeap(8, 0));
- DataExtractor return_ext (data_sp,
- target_byte_order,
- target->GetArchitecture().GetAddressByteSize());
-
- if (target_byte_order == eByteOrderLittle)
- {
- copy_from_extractor = &f0_data;
- copy_from_extractor->CopyByteOrderedData (offset,
- 4,
- data_sp->GetBytes(),
- 4,
- target_byte_order);
- f1_value.GetData(f1_data);
- copy_from_extractor = &f1_data;
- copy_from_extractor->CopyByteOrderedData (offset,
- 4,
- data_sp->GetBytes() + 4,
- 4,
- target_byte_order);
- }
- else
- {
- copy_from_extractor = &f0_data;
- copy_from_extractor->CopyByteOrderedData (offset,
- 4,
- data_sp->GetBytes() + 4,
- 4,
- target_byte_order);
- f1_value.GetData(f1_data);
- copy_from_extractor = &f1_data;
- copy_from_extractor->CopyByteOrderedData (offset,
- 4,
- data_sp->GetBytes(),
- 4,
- target_byte_order);
- }
- value.GetScalar() = (double) return_ext.GetDouble(&offset);
- break;
- }
- case 32:
- {
- static_assert(sizeof(float) == sizeof(uint32_t), "");
- value.GetScalar() = (float) f0_data.GetFloat(&offset);
- break;
- }
- }
- }
- else
- {
- // not handled yet
- return return_valobj_sp;
- }
+ case 32: {
+ static_assert(sizeof(float) == sizeof(uint32_t), "");
+ value.GetScalar() = (float)f0_data.GetFloat(&offset);
+ break;
}
- }
- else
- {
+ }
+ } else {
// not handled yet
return return_valobj_sp;
+ }
}
-
- // If we get here, we have a valid Value, so make our ValueObject out of it:
-
- return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ } else {
+ // not handled yet
return return_valobj_sp;
+ }
+
+ // If we get here, we have a valid Value, so make our ValueObject out of it:
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ return return_valobj_sp;
}
-bool
-ABISysV_mips::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_mips::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- // Our Call Frame Address is the stack pointer value
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
+ // Our Call Frame Address is the stack pointer value
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
- // The previous PC is in the RA
- row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
- unwind_plan.AppendRow (row);
+ // The previous PC is in the RA
+ row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
+ // All other registers are the same.
- unwind_plan.SetSourceName ("mips at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetReturnAddressRegister(dwarf_r31);
- return true;
+ unwind_plan.SetSourceName("mips at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetReturnAddressRegister(dwarf_r31);
+ return true;
}
-bool
-ABISysV_mips::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
- row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("mips default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
+ row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("mips default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
}
-bool
-ABISysV_mips::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- return !RegisterIsCalleeSaved (reg_info);
+bool ABISysV_mips::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
-bool
-ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const
-{
- return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
+bool ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const {
+ return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
}
-bool
-ABISysV_mips::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Preserved registers are :
- // r16-r23, r28, r29, r30, r31
- const char *name = reg_info->name;
-
- if (name[0] == 'r')
- {
- switch (name[1])
- {
- case '1':
- if (name[2] == '6' || name[2] == '7' || name[2] == '8' || name[2] == '9') // r16-r19
- return name[3] == '\0';
- break;
- case '2':
- if (name[2] == '0' || name[2] == '1' || name[2] == '2' || name[2] == '3' // r20-r23
- || name[2] == '8' || name[2] == '9') // r28 and r29
- return name[3] == '\0';
- break;
- case '3':
- if (name[2] == '0' || name[2] == '1') // r30 and r31
- return name[3] == '\0';
- break;
- }
-
- if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28)
- return true;
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29)
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30)
- return true;
- if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31)
- return true;
- }
+bool ABISysV_mips::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Preserved registers are :
+ // r16-r23, r28, r29, r30, r31
+ const char *name = reg_info->name;
+
+ if (name[0] == 'r') {
+ switch (name[1]) {
+ case '1':
+ if (name[2] == '6' || name[2] == '7' || name[2] == '8' ||
+ name[2] == '9') // r16-r19
+ return name[3] == '\0';
+ break;
+ case '2':
+ if (name[2] == '0' || name[2] == '1' || name[2] == '2' ||
+ name[2] == '3' // r20-r23
+ || name[2] == '8' || name[2] == '9') // r28 and r29
+ return name[3] == '\0';
+ break;
+ case '3':
+ if (name[2] == '0' || name[2] == '1') // r30 and r31
+ return name[3] == '\0';
+ break;
+ }
+
+ if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28)
+ return true;
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29)
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30)
+ return true;
+ if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31)
+ return true;
}
- return false;
+ }
+ return false;
}
-void
-ABISysV_mips::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "System V ABI for mips targets",
- CreateInstance);
+void ABISysV_mips::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for mips targets", CreateInstance);
}
-void
-ABISysV_mips::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_mips::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_mips::GetPluginNameStatic()
-{
- static ConstString g_name("sysv-mips");
- return g_name;
+lldb_private::ConstString ABISysV_mips::GetPluginNameStatic() {
+ static ConstString g_name("sysv-mips");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_mips::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_mips::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_mips::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_mips::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
index 388009d0fa00..7ac51463e6eb 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
@@ -14,113 +14,91 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_mips :
- public lldb_private::ABI
-{
+class ABISysV_mips : public lldb_private::ABI {
public:
- ~ABISysV_mips() override = default;
+ ~ABISysV_mips() override = default;
+
+ size_t GetRedZoneSize() const override;
- size_t
- GetRedZoneSize() const override;
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &type) const override;
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+ bool IsSoftFloat(uint32_t fp_flag) const;
- bool
- IsSoftFloat(uint32_t fp_flag) const;
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Just make sure the address is a valid 32 bit address. Bit zero
+ // might be set due to MicroMIPS function calls, so don't enforce alignment.
+ return (pc <= UINT32_MAX);
+ }
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // Just make sure the address is a valid 32 bit address. Bit zero
- // might be set due to MicroMIPS function calls, so don't enforce alignment.
- return (pc <= UINT32_MAX);
- }
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
+ static void Initialize();
- static void
- Initialize();
+ static void Terminate();
- static void
- Terminate();
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
+ static lldb_private::ConstString GetPluginNameStatic();
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- void
- CreateRegisterMapIfNeeded ();
+ void CreateRegisterMapIfNeeded();
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const;
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- bool
- RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_mips() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_mips_h_
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index bf8ab3a658b3..bb83dec5d9df 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -25,899 +25,1204 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-enum dwarf_regnums
-{
- dwarf_r0 = 0,
- dwarf_r1,
- dwarf_r2,
- dwarf_r3,
- dwarf_r4,
- dwarf_r5,
- dwarf_r6,
- dwarf_r7,
- dwarf_r8,
- dwarf_r9,
- dwarf_r10,
- dwarf_r11,
- dwarf_r12,
- dwarf_r13,
- dwarf_r14,
- dwarf_r15,
- dwarf_r16,
- dwarf_r17,
- dwarf_r18,
- dwarf_r19,
- dwarf_r20,
- dwarf_r21,
- dwarf_r22,
- dwarf_r23,
- dwarf_r24,
- dwarf_r25,
- dwarf_r26,
- dwarf_r27,
- dwarf_r28,
- dwarf_r29,
- dwarf_r30,
- dwarf_r31,
- dwarf_sr,
- dwarf_lo,
- dwarf_hi,
- dwarf_bad,
- dwarf_cause,
- dwarf_pc
+enum dwarf_regnums {
+ dwarf_r0 = 0,
+ dwarf_r1,
+ dwarf_r2,
+ dwarf_r3,
+ dwarf_r4,
+ dwarf_r5,
+ dwarf_r6,
+ dwarf_r7,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_r13,
+ dwarf_r14,
+ dwarf_r15,
+ dwarf_r16,
+ dwarf_r17,
+ dwarf_r18,
+ dwarf_r19,
+ dwarf_r20,
+ dwarf_r21,
+ dwarf_r22,
+ dwarf_r23,
+ dwarf_r24,
+ dwarf_r25,
+ dwarf_r26,
+ dwarf_r27,
+ dwarf_r28,
+ dwarf_r29,
+ dwarf_r30,
+ dwarf_r31,
+ dwarf_sr,
+ dwarf_lo,
+ dwarf_hi,
+ dwarf_bad,
+ dwarf_cause,
+ dwarf_pc
};
-static const RegisterInfo
-g_register_infos_mips64[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
- // ======== ====== == === ============= ========== ============= ================= ==================== ================= ==================== ========== ===============
- { "r0" , "zero", 8, 0, eEncodingUint, eFormatHex, { dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r1" , "AT", 8, 0, eEncodingUint, eFormatHex, { dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r2" , "v0", 8, 0, eEncodingUint, eFormatHex, { dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r3" , "v1", 8, 0, eEncodingUint, eFormatHex, { dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r4" , "arg1", 8, 0, eEncodingUint, eFormatHex, { dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r5" , "arg2", 8, 0, eEncodingUint, eFormatHex, { dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r6" , "arg3", 8, 0, eEncodingUint, eFormatHex, { dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r7" , "arg4", 8, 0, eEncodingUint, eFormatHex, { dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8" , "arg5", 8, 0, eEncodingUint, eFormatHex, { dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9" , "arg6", 8, 0, eEncodingUint, eFormatHex, { dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10" , "arg7", 8, 0, eEncodingUint, eFormatHex, { dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11" , "arg8", 8, 0, eEncodingUint, eFormatHex, { dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r15" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r16" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r17" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r18" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r19" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r20" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r21" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r22" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r23" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r24" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r25" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r26" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r27" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r28" , "gp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r29" , "sp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r30" , "fp", 8, 0, eEncodingUint, eFormatHex, { dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r31" , "ra", 8, 0, eEncodingUint, eFormatHex, { dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "sr" , nullptr,4, 0, eEncodingUint, eFormatHex, { dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "lo" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "hi" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "bad" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cause" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "pc" , nullptr,8, 0, eEncodingUint, eFormatHex, { dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
+static const RegisterInfo g_register_infos_mips64[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
+ // DWARF GENERIC PROCESS PLUGIN
+ // LLDB NATIVE
+ // ======== ====== == === ============= ========== =============
+ // ================= ==================== =================
+ // ====================
+ {"r0",
+ "zero",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ "AT",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ "v0",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ "v1",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ "arg1",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ "arg2",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ "arg3",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ "arg4",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ "arg5",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ "arg6",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ "arg7",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ "arg8",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r16",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r17",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r18",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r19",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r20",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r21",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r22",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r23",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r24",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r25",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r26",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r27",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r28",
+ "gp",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r29",
+ "sp",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r30",
+ "fp",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r31",
+ "ra",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lo",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"hi",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bad",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cause",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
};
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos_mips64);
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos_mips64);
const lldb_private::RegisterInfo *
-ABISysV_mips64::GetRegisterInfoArray (uint32_t &count)
-{
- count = k_num_register_infos;
- return g_register_infos_mips64;
+ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) {
+ count = k_num_register_infos;
+ return g_register_infos_mips64;
}
-size_t
-ABISysV_mips64::GetRedZoneSize () const
-{
- return 0;
-}
+size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_mips64::CreateInstance (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);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_mips64::CreateInstance(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);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_mips64::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (log)
- {
- StreamString s;
- s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(),
- (uint64_t)sp,
- (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
- s.PutCString (")");
- log->PutCString(s.GetString().c_str());
- }
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
+bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- const RegisterInfo *reg_info = nullptr;
-
- if (args.size() > 8) // TODO handle more than 8 arguments
- return false;
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
for (size_t i = 0; i < args.size(); ++i)
- {
- reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
-
- // First, align the SP
+ s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
- sp &= ~(0xfull); // 16-byte alignment
+ const RegisterInfo *reg_info = nullptr;
- Error error;
- const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
- const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
- const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
+ if (args.size() > 8) // TODO handle more than 8 arguments
+ return false;
+ for (size_t i = 0; i < args.size(); ++i) {
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + i);
if (log)
- log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
-
- /* Write r0 with 0, in case we are stopped in syscall,
- * such setting prevents automatic decrement of the PC.
- * This clears the bug 23659 for MIPS.
- */
- if (!reg_ctx->WriteRegisterFromUnsigned (r0_info, (uint64_t)0))
- return false;
+ log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
+ args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
+
+ // First, align the SP
+
+ if (log)
+ log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+
+ sp &= ~(0xfull); // 16-byte alignment
+
+ Error error;
+ const RegisterInfo *pc_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const RegisterInfo *ra_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+ const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
+
+ if (log)
+ log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+
+ /* Write r0 with 0, in case we are stopped in syscall,
+ * such setting prevents automatic decrement of the PC.
+ * This clears the bug 23659 for MIPS.
+ */
+ if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
+ return false;
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
- return false;
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
+ return false;
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ if (log)
+ log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
- // Set "ra" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
- return false;
+ // Set "ra" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
+ return false;
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ if (log)
+ log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
- // Set pc to the address of the called function.
- if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
- return false;
+ // Set pc to the address of the called function.
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
- if (log)
- log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
+ if (log)
+ log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
- // All callers of position independent functions must place the address of the called function in t9 (r25)
- if (!reg_ctx->WriteRegisterFromUnsigned (r25_info, func_addr))
- return false;
+ // All callers of position independent functions must place the address of the
+ // called function in t9 (r25)
+ if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
+ return false;
- return true;
+ return true;
}
-bool
-ABISysV_mips64::GetArgumentValues (Thread &thread, ValueList &values) const
-{
- return false;
+bool ABISysV_mips64::GetArgumentValues(Thread &thread,
+ ValueList &values) const {
+ return false;
}
-Error
-ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
+Error ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
- Thread *thread = frame_sp->GetThread().get();
+ Thread *thread = frame_sp->GetThread().get();
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- if (!reg_ctx)
- error.SetErrorString("no registers are available");
-
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
+ if (!reg_ctx)
+ error.SetErrorString("no registers are available");
- const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr);
-
- if (type_flags & eTypeIsScalar ||
- type_flags & eTypeIsPointer)
- {
- if (type_flags & eTypeIsInteger ||
- type_flags & eTypeIsPointer )
- {
- lldb::offset_t offset = 0;
-
- if (num_bytes <= 16)
- {
- const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
- if (num_bytes <= 8)
- {
- uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
-
- if (!reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value))
- error.SetErrorString ("failed to write register r2");
- }
- else
- {
- uint64_t raw_value = data.GetMaxU64(&offset, 8);
- if (reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value))
- {
- const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
- raw_value = data.GetMaxU64(&offset, num_bytes - offset);
-
- if (!reg_ctx->WriteRegisterFromUnsigned (r3_info, raw_value))
- error.SetErrorString ("failed to write register r3");
- }
- else
- error.SetErrorString ("failed to write register r2");
- }
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 128 bit integer values at present.");
- }
- }
- else if (type_flags & eTypeIsFloat)
- {
- error.SetErrorString("TODO: Handle Float Types.");
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+
+ const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr);
+
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ lldb::offset_t offset = 0;
+
+ if (num_bytes <= 16) {
+ const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ if (num_bytes <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
+ error.SetErrorString("failed to write register r2");
+ } else {
+ uint64_t raw_value = data.GetMaxU64(&offset, 8);
+ if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
+ const RegisterInfo *r3_info =
+ reg_ctx->GetRegisterInfoByName("r3", 0);
+ raw_value = data.GetMaxU64(&offset, num_bytes - offset);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
+ error.SetErrorString("failed to write register r3");
+ } else
+ error.SetErrorString("failed to write register r2");
}
+ } else {
+ error.SetErrorString("We don't support returning longer than 128 bit "
+ "integer values at present.");
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ error.SetErrorString("TODO: Handle Float Types.");
}
- else if (type_flags & eTypeIsVector)
- {
- error.SetErrorString("returning vector values are not supported");
- }
+ } else if (type_flags & eTypeIsVector) {
+ error.SetErrorString("returning vector values are not supported");
+ }
- return error;
+ return error;
}
-ValueObjectSP
-ABISysV_mips64::GetReturnValueObjectSimple (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- return return_valobj_sp;
+ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
- Error error;
-
- ExecutionContext exe_ctx (thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
- return return_valobj_sp;
-
- value.SetCompilerType(return_compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- 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);
- const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
- uint32_t fp_flag = target_arch.GetFlags () & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
-
- const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
- const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
-
- if (type_flags & eTypeIsScalar ||
- type_flags & eTypeIsPointer)
- {
- value.SetValueType(Value::eValueTypeScalar);
-
- bool success = false;
- if (type_flags & eTypeIsInteger ||
- type_flags & eTypeIsPointer)
- {
- // Extract the register context so we can read arguments from registers
- // In MIPS register "r2" (v0) holds the integer function return values
-
- uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
-
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size)
- {
- default:
- break;
-
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
-
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
-
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
-
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
- }
+ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
+ Error error;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
+ return return_valobj_sp;
+
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ 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);
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
+ uint32_t fp_flag =
+ target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
+
+ const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ // Extract the register context so we can read arguments from registers
+ // In MIPS register "r2" (v0) holds the integer function return values
+
+ uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
+
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size) {
+ default:
+ break;
+
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else if (IsSoftFloat(fp_flag)) {
+ uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
+ switch (byte_size) {
+ case 4:
+ value.GetScalar() = *((float *)(&raw_value));
+ success = true;
+ break;
+ case 8:
+ value.GetScalar() = *((double *)(&raw_value));
+ success = true;
+ break;
+ case 16:
+ uint64_t result[2];
+ if (target_byte_order == eByteOrderLittle) {
+ result[0] = raw_value;
+ result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
+ value.GetScalar() = *((long double *)(result));
+ } else {
+ result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
+ result[1] = raw_value;
+ value.GetScalar() = *((long double *)(result));
+ }
+ success = true;
+ break;
}
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- }
- else if (IsSoftFloat(fp_flag))
- {
- uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
- switch (byte_size)
- {
- case 4:
- value.GetScalar() = *((float *)(&raw_value));
- success = true;
- break;
- case 8:
- value.GetScalar() = *((double *)(&raw_value));
- success = true;
- break;
- case 16:
- uint64_t result[2];
- if (target_byte_order == eByteOrderLittle)
- {
- result[0] = raw_value;
- result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
- value.GetScalar() = *((long double *)(result));
- }
- else
- {
- result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
- result[1] = raw_value;
- value.GetScalar() = *((long double *)(result));
- }
- success = true;
- break;
- }
+ } else {
+ if (byte_size <= sizeof(long double)) {
+ const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
+
+ RegisterValue f0_value;
+ DataExtractor f0_data;
+
+ reg_ctx->ReadRegister(f0_info, f0_value);
+
+ f0_value.GetData(f0_data);
+
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float)) {
+ value.GetScalar() = (float)f0_data.GetFloat(&offset);
+ success = true;
+ } else if (byte_size == sizeof(double)) {
+ value.GetScalar() = (double)f0_data.GetDouble(&offset);
+ success = true;
+ } else if (byte_size == sizeof(long double)) {
+ const RegisterInfo *f2_info =
+ reg_ctx->GetRegisterInfoByName("f2", 0);
+ RegisterValue f2_value;
+ DataExtractor f2_data;
+ reg_ctx->ReadRegister(f2_info, f2_value);
+ DataExtractor *copy_from_extractor = nullptr;
+ DataBufferSP data_sp(new DataBufferHeap(16, 0));
+ DataExtractor return_ext(
+ data_sp, target_byte_order,
+ target->GetArchitecture().GetAddressByteSize());
+
+ 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);
+ f2_value.GetData(f2_data);
+ copy_from_extractor = &f2_data;
+ copy_from_extractor->CopyByteOrderedData(
+ 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,
+ 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);
}
- else
- {
- if (byte_size <= sizeof(long double))
- {
- const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
-
- RegisterValue f0_value;
- DataExtractor f0_data;
-
- reg_ctx->ReadRegister (f0_info, f0_value);
-
-
- f0_value.GetData(f0_data);
-
-
- lldb::offset_t offset = 0;
- if (byte_size == sizeof(float))
- {
- value.GetScalar() = (float) f0_data.GetFloat(&offset);
- success = true;
- }
- else if (byte_size == sizeof(double))
- {
- value.GetScalar() = (double) f0_data.GetDouble(&offset);
- success = true;
- }
- else if (byte_size == sizeof(long double))
- {
- const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
- RegisterValue f2_value;
- DataExtractor f2_data;
- reg_ctx->ReadRegister (f2_info, f2_value);
- DataExtractor *copy_from_extractor = nullptr;
- DataBufferSP data_sp (new DataBufferHeap(16, 0));
- DataExtractor return_ext (data_sp,
- target_byte_order,
- target->GetArchitecture().GetAddressByteSize());
-
- 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);
- f2_value.GetData(f2_data);
- copy_from_extractor = &f2_data;
- copy_from_extractor->CopyByteOrderedData (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,
- 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);
- }
-
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- return_ext);
- return return_valobj_sp;
- }
- }
- }
- }
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), return_ext);
+ return return_valobj_sp;
+ }
+ }
+ }
}
- 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)
- {
- DataBufferSP data_sp(new DataBufferHeap(16, 0));
- DataExtractor return_ext(data_sp, target_byte_order,
- target->GetArchitecture().GetAddressByteSize());
-
- RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value;
- // Tracks how much bytes of r2 and r3 registers we've consumed so far
- uint32_t integer_bytes = 0;
-
- // True if return values are in FP return registers.
- bool use_fp_regs = 0;
- // True if we found any non floating point field in structure.
- bool found_non_fp_field = 0;
- // True if return values are in r2 register.
- bool use_r2 = 0;
- // True if return values are in r3 register.
- bool use_r3 = 0;
- // True if the result is copied into our data buffer
- bool sucess = 0;
- std::string name;
- bool is_complex;
- uint32_t count;
- const uint32_t num_children = return_compiler_type.GetNumFields();
-
- // A structure consisting of one or two FP values (and nothing else) will
- // be returned in the two FP return-value registers i.e fp0 and fp2.
-
- if (num_children <= 2)
- {
- uint64_t field_bit_offset = 0;
-
- // Check if this structure contains only floating point fields
- for (uint32_t idx = 0; idx < num_children; idx++)
- {
- CompilerType field_compiler_type =
- return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset,
- nullptr, nullptr);
-
- if (field_compiler_type.IsFloatingPointType(count, is_complex))
- use_fp_regs = 1;
- else
- found_non_fp_field = 1;
- }
-
- if (use_fp_regs && !found_non_fp_field)
- {
- // We have one or two FP-only values in this structure. Get it from
- // f0/f2 registers.
- DataExtractor f0_data, f1_data, f2_data;
- const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
- const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
- const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
-
- reg_ctx->ReadRegister(f0_info, f0_value);
- reg_ctx->ReadRegister(f2_info, f2_value);
-
- f0_value.GetData(f0_data);
-
-
- for (uint32_t idx = 0; idx < num_children; idx++)
- {
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name,
- &field_bit_offset,
- nullptr, nullptr);
- const size_t field_byte_width = field_compiler_type.GetByteSize(nullptr);
-
- DataExtractor *copy_from_extractor = nullptr;
- uint64_t return_value[2];
- offset_t offset = 0;
-
- if (idx == 0)
- {
- // This case is for long double type.
- if (field_byte_width == 16)
- {
-
- // If structure contains long double type, then it is returned
- // in fp0/fp1 registers.
-
-
-
- if (target_byte_order == eByteOrderLittle)
- {
- return_value[0] = f0_data.GetU64(&offset);
- reg_ctx->ReadRegister(f1_info, f1_value);
- f1_value.GetData(f1_data);
- offset = 0;
- return_value[1] = f1_data.GetU64(&offset);
- }
- else
- {
- return_value[1] = f0_data.GetU64(&offset);
- reg_ctx->ReadRegister(f1_info, f1_value);
- f1_value.GetData(f1_data);
- offset = 0;
- return_value[0] = f1_data.GetU64(&offset);
- }
-
- f0_data.SetData(return_value, field_byte_width,
- target_byte_order);
- }
- copy_from_extractor = &f0_data; // This is in f0, copy from
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } 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) {
+ DataBufferSP data_sp(new DataBufferHeap(16, 0));
+ DataExtractor return_ext(data_sp, target_byte_order,
+ target->GetArchitecture().GetAddressByteSize());
+
+ RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value;
+ // Tracks how much bytes of r2 and r3 registers we've consumed so far
+ uint32_t integer_bytes = 0;
+
+ // True if return values are in FP return registers.
+ bool use_fp_regs = 0;
+ // True if we found any non floating point field in structure.
+ bool found_non_fp_field = 0;
+ // True if return values are in r2 register.
+ bool use_r2 = 0;
+ // True if return values are in r3 register.
+ bool use_r3 = 0;
+ // True if the result is copied into our data buffer
+ bool sucess = 0;
+ std::string name;
+ bool is_complex;
+ uint32_t count;
+ const uint32_t num_children = return_compiler_type.GetNumFields();
+
+ // A structure consisting of one or two FP values (and nothing else) will
+ // be returned in the two FP return-value registers i.e fp0 and fp2.
+ if (num_children <= 2) {
+ uint64_t field_bit_offset = 0;
+
+ // Check if this structure contains only floating point fields
+ for (uint32_t idx = 0; idx < num_children; idx++) {
+ CompilerType field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset,
+ nullptr, nullptr);
+
+ if (field_compiler_type.IsFloatingPointType(count, is_complex))
+ use_fp_regs = 1;
+ else
+ found_non_fp_field = 1;
+ }
+
+ if (use_fp_regs && !found_non_fp_field) {
+ // We have one or two FP-only values in this structure. Get it from
+ // f0/f2 registers.
+ DataExtractor f0_data, f1_data, f2_data;
+ const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
+ const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
+ const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
+
+ reg_ctx->ReadRegister(f0_info, f0_value);
+ reg_ctx->ReadRegister(f2_info, f2_value);
+
+ f0_value.GetData(f0_data);
+
+ for (uint32_t idx = 0; idx < num_children; idx++) {
+ CompilerType field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(
+ idx, name, &field_bit_offset, nullptr, nullptr);
+ const size_t field_byte_width =
+ field_compiler_type.GetByteSize(nullptr);
+
+ DataExtractor *copy_from_extractor = nullptr;
+ uint64_t return_value[2];
+ offset_t offset = 0;
+
+ if (idx == 0) {
+ // This case is for long double type.
+ if (field_byte_width == 16) {
+
+ // If structure contains long double type, then it is returned
+ // in fp0/fp1 registers.
+ if (target_byte_order == eByteOrderLittle) {
+ return_value[0] = f0_data.GetU64(&offset);
+ reg_ctx->ReadRegister(f1_info, f1_value);
+ f1_value.GetData(f1_data);
+ offset = 0;
+ return_value[1] = f1_data.GetU64(&offset);
+ } else {
+ return_value[1] = f0_data.GetU64(&offset);
+ reg_ctx->ReadRegister(f1_info, f1_value);
+ f1_value.GetData(f1_data);
+ offset = 0;
+ return_value[0] = f1_data.GetU64(&offset);
+ }
+
+ f0_data.SetData(return_value, field_byte_width,
+ target_byte_order);
+ }
+ copy_from_extractor = &f0_data; // This is in f0, copy from
// register to our result
// structure
- }
- else
- {
- f2_value.GetData(f2_data);
- // This is in f2, copy from register to our result structure
- copy_from_extractor = &f2_data;
- }
-
- // Sanity check to avoid crash
- if (!copy_from_extractor || 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, target_byte_order);
- }
-
- // The result is in our data buffer. Create a variable object out of
- // it
- return_valobj_sp = ValueObjectConstResult::Create(&thread, return_compiler_type, ConstString(""),
- return_ext);
-
- return return_valobj_sp;
- }
- }
-
-
- // If we reach here, it means this structure either contains more than two fields or
- // it contains at least one non floating point type.
- // In that case, all fields are returned in GP return registers.
- for (uint32_t idx = 0; idx < num_children; idx++)
- {
- uint64_t field_bit_offset = 0;
- bool is_signed;
- uint32_t padding;
-
- CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, nullptr, nullptr);
- const size_t field_byte_width = field_compiler_type.GetByteSize(nullptr);
-
- // if we don't know the size of the field (e.g. invalid type), just bail out
- if (field_byte_width == 0)
- break;
-
- uint32_t field_byte_offset = field_bit_offset/8;
-
- if (field_compiler_type.IsIntegerOrEnumerationType (is_signed)
- || field_compiler_type.IsPointerType ()
- || field_compiler_type.IsFloatingPointType (count, is_complex))
- {
- padding = field_byte_offset - integer_bytes;
-
- if (integer_bytes < 8)
- {
- // We have not yet consumed r2 completely.
- 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 + 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 + 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;
- use_r3 = 1;
- }
- else
- {
- // There isn't any space left for this field, this should not happen as we have already checked
- // the overall size is not greater than 16 bytes. For now, return a nullptr return value object.
- return return_valobj_sp;
- }
- }
- }
- // Vector types upto 16 bytes are returned in GP return registers
- if (type_flags & eTypeIsVector)
- {
- if (byte_size <= 8)
- use_r2 = 1;
- else
- {
- use_r2 = 1;
- use_r3 = 1;
- }
+ } else {
+ f2_value.GetData(f2_data);
+ // This is in f2, copy from register to our result structure
+ copy_from_extractor = &f2_data;
}
- if (use_r2)
- {
- reg_ctx->ReadRegister (r2_info, r2_value);
-
- const size_t bytes_copied = r2_value.GetAsMemoryData (r2_info,
- data_sp->GetBytes(),
- r2_info->byte_size,
- target_byte_order,
- error);
- if (bytes_copied != r2_info->byte_size)
- return return_valobj_sp;
- sucess = 1;
- }
- if (use_r3)
- {
- reg_ctx->ReadRegister (r3_info, r3_value);
- const size_t bytes_copied = r3_value.GetAsMemoryData (r3_info,
- data_sp->GetBytes() + r2_info->byte_size,
- r3_info->byte_size,
- target_byte_order,
- error);
-
- if (bytes_copied != r3_info->byte_size)
- return return_valobj_sp;
- sucess = 1;
- }
- if (sucess)
- {
- // The result is in our data buffer. Create a variable object out of it
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- return_ext);
+ // Sanity check to avoid crash
+ if (!copy_from_extractor ||
+ 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,
+ target_byte_order);
+ }
+
+ // The result is in our data buffer. Create a variable object out of
+ // it
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), return_ext);
+
+ return return_valobj_sp;
+ }
+ }
+
+ // If we reach here, it means this structure either contains more than two
+ // fields or
+ // it contains at least one non floating point type.
+ // In that case, all fields are returned in GP return registers.
+ for (uint32_t idx = 0; idx < num_children; idx++) {
+ uint64_t field_bit_offset = 0;
+ bool is_signed;
+ uint32_t padding;
+
+ CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
+ idx, name, &field_bit_offset, nullptr, nullptr);
+ const size_t field_byte_width =
+ field_compiler_type.GetByteSize(nullptr);
+
+ // if we don't know the size of the field (e.g. invalid type), just bail
+ // out
+ if (field_byte_width == 0)
+ break;
+
+ uint32_t field_byte_offset = field_bit_offset / 8;
+
+ if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ field_compiler_type.IsPointerType() ||
+ field_compiler_type.IsFloatingPointType(count, is_complex)) {
+ padding = field_byte_offset - integer_bytes;
+
+ if (integer_bytes < 8) {
+ // We have not yet consumed r2 completely.
+ 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 +
+ 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 +
+ 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;
+ use_r3 = 1;
+ } else {
+ // There isn't any space left for this field, this should not happen
+ // as we have already checked
+ // the overall size is not greater than 16 bytes. For now, return a
+ // nullptr return value object.
return return_valobj_sp;
+ }
+ }
+ }
+ // Vector types up to 16 bytes are returned in GP return registers
+ if (type_flags & eTypeIsVector) {
+ if (byte_size <= 8)
+ use_r2 = 1;
+ else {
+ use_r2 = 1;
+ use_r3 = 1;
}
+ }
+
+ if (use_r2) {
+ reg_ctx->ReadRegister(r2_info, r2_value);
+
+ const size_t bytes_copied = r2_value.GetAsMemoryData(
+ r2_info, data_sp->GetBytes(), r2_info->byte_size, target_byte_order,
+ error);
+ if (bytes_copied != r2_info->byte_size)
+ return return_valobj_sp;
+ sucess = 1;
+ }
+ if (use_r3) {
+ reg_ctx->ReadRegister(r3_info, r3_value);
+ const size_t bytes_copied = r3_value.GetAsMemoryData(
+ r3_info, data_sp->GetBytes() + r2_info->byte_size,
+ r3_info->byte_size, target_byte_order, error);
+
+ if (bytes_copied != r3_info->byte_size)
+ return return_valobj_sp;
+ sucess = 1;
+ }
+ if (sucess) {
+ // The result is in our data buffer. Create a variable object out of it
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), return_ext);
+ }
+ return return_valobj_sp;
+ }
- // Any structure/vector greater than 16 bytes in size is returned in memory.
- // The pointer to that memory is returned in r2.
- uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);
+ // Any structure/vector greater than 16 bytes in size is returned in memory.
+ // The pointer to that memory is returned in r2.
+ uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfoByName("r2", 0), 0);
- // We have got the address. Create a memory object out of it
- return_valobj_sp = ValueObjectMemory::Create(&thread,
- "",
- Address(mem_address, nullptr),
- return_compiler_type);
- }
- return return_valobj_sp;
+ // We have got the address. Create a memory object out of it
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(mem_address, nullptr), return_compiler_type);
+ }
+ return return_valobj_sp;
}
-bool
-ABISysV_mips64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_mips64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- // Our Call Frame Address is the stack pointer value
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
+ // Our Call Frame Address is the stack pointer value
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
- // The previous PC is in the RA
- row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
- unwind_plan.AppendRow (row);
+ // The previous PC is in the RA
+ row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
+ // All other registers are the same.
- unwind_plan.SetSourceName ("mips64 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetReturnAddressRegister(dwarf_r31);
- return true;
+ unwind_plan.SetSourceName("mips64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetReturnAddressRegister(dwarf_r31);
+ return true;
}
-bool
-ABISysV_mips64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
- row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
+ row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("mips64 default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("mips64 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
}
-bool
-ABISysV_mips64::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- return !RegisterIsCalleeSaved (reg_info);
+bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
-bool
-ABISysV_mips64::IsSoftFloat (uint32_t fp_flag) const
-{
- return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
+bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const {
+ return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
}
-bool
-ABISysV_mips64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Preserved registers are :
- // r16-r23, r28, r29, r30, r31
+bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Preserved registers are :
+ // r16-r23, r28, r29, r30, r31
- int reg = ((reg_info->byte_offset) / 8);
+ int reg = ((reg_info->byte_offset) / 8);
- bool save = (reg >= 16) && (reg <= 23);
- save |= (reg >= 28) && (reg <= 31);
+ bool save = (reg >= 16) && (reg <= 23);
+ save |= (reg >= 28) && (reg <= 31);
- return save;
- }
- return false;
+ return save;
+ }
+ return false;
}
-void
-ABISysV_mips64::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "System V ABI for mips64 targets",
- CreateInstance);
+void ABISysV_mips64::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance);
}
-void
-ABISysV_mips64::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_mips64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_mips64::GetPluginNameStatic()
-{
- static ConstString g_name("sysv-mips64");
- return g_name;
+lldb_private::ConstString ABISysV_mips64::GetPluginNameStatic() {
+ static ConstString g_name("sysv-mips64");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_mips64::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_mips64::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_mips64::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_mips64::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
index 9f1ea0922db3..672a43825625 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
@@ -14,125 +14,104 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_mips64 :
- public lldb_private::ABI
-{
+class ABISysV_mips64 : public lldb_private::ABI {
public:
- ~ABISysV_mips64() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &type) const override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- bool
- IsSoftFloat(uint32_t fp_flag) const;
-
- // The SysV mips ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- if (pc & (4ull - 1ull))
- return false; // Not 4 byte aligned
-
- // Anything else if fair game..
- return true;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ~ABISysV_mips64() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ bool IsSoftFloat(uint32_t fp_flag) const;
+
+ // The SysV mips ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (8-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ if (pc & (4ull - 1ull))
+ return false; // Not 4 byte aligned
+
+ // Anything else if fair game..
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- void
- CreateRegisterMapIfNeeded ();
+ void CreateRegisterMapIfNeeded();
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const;
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- bool
- RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips64() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_mips64() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_mips64_h_
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index 20ff17d0b763..3e563c2b5d9c 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -25,231 +25,271 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-enum dwarf_regnums
-{
- dwarf_r0 = 0,
- dwarf_r1,
- dwarf_r2,
- dwarf_r3,
- dwarf_r4,
- dwarf_r5,
- dwarf_r6,
- dwarf_r7,
- dwarf_r8,
- dwarf_r9,
- dwarf_r10,
- dwarf_r11,
- dwarf_r12,
- dwarf_r13,
- dwarf_r14,
- dwarf_r15,
- dwarf_r16,
- dwarf_r17,
- dwarf_r18,
- dwarf_r19,
- dwarf_r20,
- dwarf_r21,
- dwarf_r22,
- dwarf_r23,
- dwarf_r24,
- dwarf_r25,
- dwarf_r26,
- dwarf_r27,
- dwarf_r28,
- dwarf_r29,
- dwarf_r30,
- dwarf_r31,
- dwarf_f0,
- dwarf_f1,
- dwarf_f2,
- dwarf_f3,
- dwarf_f4,
- dwarf_f5,
- dwarf_f6,
- dwarf_f7,
- dwarf_f8,
- dwarf_f9,
- dwarf_f10,
- dwarf_f11,
- dwarf_f12,
- dwarf_f13,
- dwarf_f14,
- dwarf_f15,
- dwarf_f16,
- dwarf_f17,
- dwarf_f18,
- dwarf_f19,
- dwarf_f20,
- dwarf_f21,
- dwarf_f22,
- dwarf_f23,
- dwarf_f24,
- dwarf_f25,
- dwarf_f26,
- dwarf_f27,
- dwarf_f28,
- dwarf_f29,
- dwarf_f30,
- dwarf_f31,
- dwarf_cr,
- dwarf_fpscr,
- dwarf_xer = 101,
- dwarf_lr = 108,
- dwarf_ctr,
- dwarf_pc,
- dwarf_cfa,
+enum dwarf_regnums {
+ dwarf_r0 = 0,
+ dwarf_r1,
+ dwarf_r2,
+ dwarf_r3,
+ dwarf_r4,
+ dwarf_r5,
+ dwarf_r6,
+ dwarf_r7,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_r13,
+ dwarf_r14,
+ dwarf_r15,
+ dwarf_r16,
+ dwarf_r17,
+ dwarf_r18,
+ dwarf_r19,
+ dwarf_r20,
+ dwarf_r21,
+ dwarf_r22,
+ dwarf_r23,
+ dwarf_r24,
+ dwarf_r25,
+ dwarf_r26,
+ dwarf_r27,
+ dwarf_r28,
+ dwarf_r29,
+ dwarf_r30,
+ dwarf_r31,
+ dwarf_f0,
+ dwarf_f1,
+ dwarf_f2,
+ dwarf_f3,
+ dwarf_f4,
+ dwarf_f5,
+ dwarf_f6,
+ dwarf_f7,
+ dwarf_f8,
+ dwarf_f9,
+ dwarf_f10,
+ dwarf_f11,
+ dwarf_f12,
+ dwarf_f13,
+ dwarf_f14,
+ dwarf_f15,
+ dwarf_f16,
+ dwarf_f17,
+ dwarf_f18,
+ dwarf_f19,
+ dwarf_f20,
+ dwarf_f21,
+ dwarf_f22,
+ dwarf_f23,
+ dwarf_f24,
+ dwarf_f25,
+ dwarf_f26,
+ dwarf_f27,
+ dwarf_f28,
+ dwarf_f29,
+ dwarf_f30,
+ dwarf_f31,
+ dwarf_cr,
+ dwarf_fpscr,
+ dwarf_xer = 101,
+ dwarf_lr = 108,
+ dwarf_ctr,
+ dwarf_pc,
+ dwarf_cfa,
};
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, 8, 0, eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4}, nullptr, nullptr }
-
-static const RegisterInfo
-g_register_infos[] =
-{
- // General purpose registers. eh_frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2 ,LLDB_INVALID_REGNUM),
- DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- { nullptr, nullptr, 8, 0, eEncodingUint, eFormatHex, { dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, 8, 0, eEncodingUint, eFormatHex, {kind1, kind2, kind3, kind4 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+static const RegisterInfo g_register_infos[] = {
+ // General purpose registers. eh_frame, DWARF,
+ // Generic, Process Plugin
+ DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM),
+ {nullptr,
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
const lldb_private::RegisterInfo *
-ABISysV_ppc::GetRegisterInfoArray (uint32_t &count)
-{
- count = k_num_register_infos;
- return g_register_infos;
+ABISysV_ppc::GetRegisterInfoArray(uint32_t &count) {
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABISysV_ppc::GetRedZoneSize () const
-{
- return 224;
-}
+size_t ABISysV_ppc::GetRedZoneSize() const { return 224; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_ppc::CreateInstance (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);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_ppc::CreateInstance(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);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_ppc::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- {
- StreamString s;
- s.Printf("ABISysV_ppc::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(),
- (uint64_t)sp,
- (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf (", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1), args[i]);
- s.PutCString (")");
- log->PutCString(s.GetString().c_str());
- }
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_ppc::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
+ args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
- const RegisterInfo *reg_info = nullptr;
+ const RegisterInfo *reg_info = nullptr;
- if (args.size() > 8) // TODO handle more than 8 arguments
- return false;
+ if (args.size() > 8) // TODO handle more than 8 arguments
+ return false;
- for (size_t i = 0; i < args.size(); ++i)
- {
- reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", static_cast<uint64_t>(i + 1), args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
+ for (size_t i = 0; i < args.size(); ++i) {
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + i);
+ if (log)
+ log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
- // First, align the SP
+ // First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ if (log)
+ log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
- sp &= ~(0xfull); // 16-byte alignment
+ sp &= ~(0xfull); // 16-byte alignment
- sp -= 8;
+ sp -= 8;
- Error error;
- const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- ProcessSP process_sp (thread.GetProcess());
+ Error error;
+ const RegisterInfo *pc_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ ProcessSP process_sp(thread.GetProcess());
- RegisterValue reg_value;
+ RegisterValue reg_value;
#if 0
// This code adds an extra frame so that we don't lose the function that we came from
@@ -292,775 +332,692 @@ ABISysV_ppc::PrepareTrivialCall (Thread &thread,
}
#endif
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
+ if (log)
+ log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
- // Save return address onto the stack
- if (!process_sp->WritePointerToMemory(sp, return_addr, error))
- return false;
+ // Save return address onto the stack
+ if (!process_sp->WritePointerToMemory(sp, return_addr, error))
+ return false;
- // %r1 is set to the actual stack value.
+ // %r1 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
+ return false;
- // %pc is set to the address of the called function.
+ // %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ if (log)
+ log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
- if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
- return true;
+ return true;
}
-static bool ReadIntegerArgument(Scalar &scalar,
- unsigned int bit_width,
- bool is_signed,
- Thread &thread,
- uint32_t *argument_register_ids,
- unsigned int &current_argument_register,
- addr_t &current_stack_argument)
-{
- if (bit_width > 64)
- return false; // Scalar can't hold large integer arguments
-
- if (current_argument_register < 6)
- {
- scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
- current_argument_register++;
- if (is_signed)
- scalar.SignExtend (bit_width);
- }
- else
- {
- uint32_t byte_size = (bit_width + (8-1))/8;
- Error error;
- if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
- {
- current_stack_argument += byte_size;
- return true;
- }
- return false;
+static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
+ bool is_signed, Thread &thread,
+ uint32_t *argument_register_ids,
+ unsigned int &current_argument_register,
+ addr_t &current_stack_argument) {
+ if (bit_width > 64)
+ return false; // Scalar can't hold large integer arguments
+
+ if (current_argument_register < 6) {
+ scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ argument_register_ids[current_argument_register], 0);
+ current_argument_register++;
+ if (is_signed)
+ scalar.SignExtend(bit_width);
+ } else {
+ uint32_t byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (thread.GetProcess()->ReadScalarIntegerFromMemory(
+ current_stack_argument, byte_size, is_signed, scalar, error)) {
+ current_stack_argument += byte_size;
+ return true;
}
- return true;
+ return false;
+ }
+ return true;
}
-bool
-ABISysV_ppc::GetArgumentValues (Thread &thread,
- ValueList &values) const
-{
- unsigned int num_values = values.GetSize();
- unsigned int value_index;
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
- return false;
-
- // Get the pointer to the first stack argument so we have a place to start
- // when reading data
+bool ABISysV_ppc::GetArgumentValues(Thread &thread, ValueList &values) const {
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
- addr_t sp = reg_ctx->GetSP(0);
+ // Extract the register context so we can read arguments from registers
- if (!sp)
- return false;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- addr_t current_stack_argument = sp + 48; // jump over return address
-
- uint32_t argument_register_ids[8];
-
- argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
- argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
- argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
- argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
- argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
- argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
- argument_register_ids[6] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)->kinds[eRegisterKindLLDB];
- argument_register_ids[7] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)->kinds[eRegisterKindLLDB];
+ if (!reg_ctx)
+ return false;
- unsigned int current_argument_register = 0;
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
- for (value_index = 0;
- value_index < num_values;
- ++value_index)
- {
- Value *value = values.GetValueAtIndex(value_index);
+ addr_t sp = reg_ctx->GetSP(0);
- if (!value)
- return false;
+ if (!sp)
+ return false;
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
- return false;
- bool is_signed;
+ addr_t current_stack_argument = sp + 48; // jump over return address
+
+ uint32_t argument_register_ids[8];
+
+ argument_register_ids[0] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[1] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[2] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[3] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[4] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[5] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[6] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[7] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)
+ ->kinds[eRegisterKindLLDB];
+
+ unsigned int current_argument_register = 0;
+
+ for (value_index = 0; value_index < num_values; ++value_index) {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ CompilerType compiler_type = value->GetCompilerType();
+ if (!compiler_type)
+ 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(), 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);
}
+ }
- return true;
+ return true;
}
-Error
-ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
+Error ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
- Thread *thread = frame_sp->GetThread().get();
+ Thread *thread = frame_sp->GetThread().get();
- bool is_signed;
- uint32_t count;
- bool is_complex;
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
+ set_it_simple = true;
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
+ }
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ 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) {
DataExtractor data;
Error data_error;
size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
}
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
- if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
- }
- }
- else if (compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (is_complex)
- 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)
- {
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
-
- unsigned char buffer[16];
- ByteOrder byte_order = data.GetByteOrder();
+ unsigned char buffer[16];
+ ByteOrder byte_order = data.GetByteOrder();
- data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
- set_it_simple = true;
- }
- else
- {
- // FIXME - don't know how to do 80 bit long doubles yet.
- error.SetErrorString ("We don't support returning float values > 64 bits at present");
- }
- }
+ data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
+ set_it_simple = true;
+ } else {
+ // FIXME - don't know how to do 80 bit long doubles yet.
+ error.SetErrorString(
+ "We don't support returning float values > 64 bits at present");
+ }
}
+ }
- if (!set_it_simple)
- {
- // Okay we've got a structure or something that doesn't fit in a simple register.
- // We should figure out where it really goes, but we don't support this yet.
- error.SetErrorString ("We only support setting simple integer and float return types at present.");
- }
+ if (!set_it_simple) {
+ // Okay we've got a structure or something that doesn't fit in a simple
+ // register.
+ // We should figure out where it really goes, but we don't support this yet.
+ error.SetErrorString("We only support setting simple integer and float "
+ "return types at present.");
+ }
- return error;
+ return error;
}
-ValueObjectSP
-ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
- CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
+ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
- if (!return_compiler_type)
- return return_valobj_sp;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- //value.SetContext (Value::eContextTypeClangType, return_value_type);
- value.SetCompilerType (return_compiler_type);
+ // value.SetContext (Value::eContextTypeClangType, return_value_type);
+ value.SetCompilerType(return_compiler_type);
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
- const uint32_t type_flags = return_compiler_type.GetTypeInfo ();
- if (type_flags & eTypeIsScalar)
- {
- value.SetValueType(Value::eValueTypeScalar);
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo();
+ if (type_flags & eTypeIsScalar) {
+ value.SetValueType(Value::eValueTypeScalar);
- 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);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size)
- {
- default:
- break;
-
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
+ bool success = false;
+ if (type_flags & eTypeIsInteger) {
+ // Extract the register context so we can read arguments from registers
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfoByName("r3", 0), 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size) {
+ default:
+ break;
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size <= sizeof(long double)) {
+ const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
+ RegisterValue f1_value;
+ if (reg_ctx->ReadRegister(f1_info, f1_value)) {
+ DataExtractor data;
+ if (f1_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float)) {
+ value.GetScalar() = (float)data.GetFloat(&offset);
success = true;
- break;
- }
- }
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- }
- else
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double))
- {
- const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
- RegisterValue f1_value;
- if (reg_ctx->ReadRegister (f1_info, f1_value))
- {
- DataExtractor data;
- if (f1_value.GetData(data))
- {
- lldb::offset_t offset = 0;
- if (byte_size == sizeof(float))
- {
- value.GetScalar() = (float) data.GetFloat(&offset);
- success = true;
- }
- else if (byte_size == sizeof(double))
- {
- value.GetScalar() = (double) data.GetDouble(&offset);
- success = true;
- }
- }
- }
- }
+ } else if (byte_size == sizeof(double)) {
+ value.GetScalar() = (double)data.GetDouble(&offset);
+ success = true;
+ }
}
+ }
}
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ }
}
- else if (type_flags & eTypeIsPointer)
- {
- unsigned r3_id = reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
- value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- value.SetValueType(Value::eValueTypeScalar);
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- }
- else if (type_flags & eTypeIsVector)
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size > 0)
- {
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
- if (altivec_reg)
- {
- if (byte_size <= altivec_reg->byte_size)
- {
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(altivec_reg, reg_value))
- {
- Error error;
- if (reg_value.GetAsMemoryData (altivec_reg,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
- }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsPointer) {
+ unsigned r3_id =
+ reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+ value.GetScalar() =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size > 0) {
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
+ if (altivec_reg) {
+ if (byte_size <= altivec_reg->byte_size) {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
+ Error error;
+ if (reg_value.GetAsMemoryData(
+ altivec_reg, heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(), byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order, process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
}
+ }
}
+ }
}
+ }
- return return_valobj_sp;
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
+ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
- if (!return_compiler_type)
- return return_valobj_sp;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- ExecutionContext exe_ctx (thread.shared_from_this());
- return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
- if (return_valobj_sp)
- return return_valobj_sp;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
+ if (return_valobj_sp)
+ return return_valobj_sp;
- RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return return_valobj_sp;
+ RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
+ return return_valobj_sp;
- const size_t bit_width = return_compiler_type.GetBitSize(&thread);
- if (return_compiler_type.IsAggregateType())
- {
- Target *target = exe_ctx.GetTargetPtr();
- bool is_memory = true;
- if (bit_width <= 128)
- {
- ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
- DataBufferSP data_sp (new DataBufferHeap(16, 0));
- DataExtractor return_ext (data_sp,
- target_byte_order,
- target->GetArchitecture().GetAddressByteSize());
+ const size_t bit_width = return_compiler_type.GetBitSize(&thread);
+ if (return_compiler_type.IsAggregateType()) {
+ Target *target = exe_ctx.GetTargetPtr();
+ bool is_memory = true;
+ if (bit_width <= 128) {
+ ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
+ DataBufferSP data_sp(new DataBufferHeap(16, 0));
+ DataExtractor return_ext(data_sp, target_byte_order,
+ target->GetArchitecture().GetAddressByteSize());
- const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
- const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
+ const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
+ const RegisterInfo *rdx_info =
+ reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
- RegisterValue r3_value, rdx_value;
- reg_ctx_sp->ReadRegister (r3_info, r3_value);
- reg_ctx_sp->ReadRegister (rdx_info, rdx_value);
+ RegisterValue r3_value, rdx_value;
+ reg_ctx_sp->ReadRegister(r3_info, r3_value);
+ reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
- DataExtractor r3_data, rdx_data;
+ DataExtractor r3_data, rdx_data;
- r3_value.GetData(r3_data);
- rdx_value.GetData(rdx_data);
+ r3_value.GetData(r3_data);
+ rdx_value.GetData(rdx_data);
- uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far
- uint32_t integer_bytes = 0; // Tracks how much of the r3/rds registers we've consumed so far
+ uint32_t fp_bytes =
+ 0; // Tracks how much of the xmm registers we've consumed so far
+ uint32_t integer_bytes =
+ 0; // Tracks how much of the r3/rds registers we've consumed so far
- const uint32_t num_children = return_compiler_type.GetNumFields ();
+ const uint32_t num_children = return_compiler_type.GetNumFields();
- // Since we are in the small struct regime, assume we are not in memory.
- is_memory = false;
+ // Since we are in the small struct regime, assume we are not in memory.
+ is_memory = false;
- for (uint32_t idx = 0; idx < num_children; idx++)
- {
- std::string name;
- uint64_t field_bit_offset = 0;
- bool is_signed;
- bool is_complex;
- uint32_t count;
+ for (uint32_t idx = 0; idx < num_children; idx++) {
+ std::string name;
+ uint64_t field_bit_offset = 0;
+ bool is_signed;
+ bool is_complex;
+ uint32_t count;
- 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);
+ 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);
- // If there are any unaligned fields, this is stored in memory.
- if (field_bit_offset % field_bit_width != 0)
- {
- is_memory = true;
- break;
- }
+ // If there are any unaligned fields, this is stored in memory.
+ 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_offset = field_bit_offset/8;
-
- DataExtractor *copy_from_extractor = nullptr;
- uint32_t copy_from_offset = 0;
-
- if (field_compiler_type.IsIntegerOrEnumerationType (is_signed) || field_compiler_type.IsPointerType ())
- {
- if (integer_bytes < 8)
- {
- if (integer_bytes + field_byte_width <= 8)
- {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &r3_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- }
- else
- {
- // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
- copy_from_extractor = &rdx_data;
- copy_from_offset = 0;
- integer_bytes = 8 + field_byte_width;
- }
- }
- else if (integer_bytes + field_byte_width <= 16)
- {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- }
- else
- {
- // The last field didn't fit. I can't see how that would happen w/o the overall size being
- // greater than 16 bytes. For now, return a nullptr return value object.
- return return_valobj_sp;
- }
+ uint32_t field_byte_width = field_bit_width / 8;
+ uint32_t field_byte_offset = field_bit_offset / 8;
+
+ DataExtractor *copy_from_extractor = nullptr;
+ uint32_t copy_from_offset = 0;
+
+ if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ field_compiler_type.IsPointerType()) {
+ if (integer_bytes < 8) {
+ if (integer_bytes + field_byte_width <= 8) {
+ // This is in RAX, copy from register to our result structure:
+ copy_from_extractor = &r3_data;
+ copy_from_offset = integer_bytes;
+ integer_bytes += field_byte_width;
+ } else {
+ // The next field wouldn't fit in the remaining space, so we
+ // pushed it to rdx.
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = 0;
+ integer_bytes = 8 + field_byte_width;
+ }
+ } else if (integer_bytes + field_byte_width <= 16) {
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = integer_bytes - 8;
+ integer_bytes += field_byte_width;
+ } else {
+ // The last field didn't fit. I can't see how that would happen w/o
+ // the overall size being
+ // greater than 16 bytes. For now, return a nullptr return value
+ // object.
+ return return_valobj_sp;
+ }
+ } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
+ // Structs with long doubles are always passed in memory.
+ if (field_bit_width == 128) {
+ is_memory = true;
+ break;
+ } else if (field_bit_width == 64) {
+ copy_from_offset = 0;
+ fp_bytes += field_byte_width;
+ } else if (field_bit_width == 32) {
+ // This one is kind of complicated. If we are in an "eightbyte"
+ // with another float, we'll
+ // be stuffed into an xmm register with it. If we are in an
+ // "eightbyte" with one or more ints,
+ // then we will be stuffed into the appropriate GPR with them.
+ bool in_gpr;
+ if (field_byte_offset % 8 == 0) {
+ // We are at the beginning of one of the eightbytes, so check the
+ // next element (if any)
+ if (idx == num_children - 1)
+ in_gpr = false;
+ else {
+ uint64_t next_field_bit_offset = 0;
+ CompilerType next_field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(idx + 1, name,
+ &next_field_bit_offset,
+ nullptr, nullptr);
+ if (next_field_compiler_type.IsIntegerOrEnumerationType(
+ is_signed))
+ in_gpr = true;
+ else {
+ copy_from_offset = 0;
+ in_gpr = false;
}
- else if (field_compiler_type.IsFloatingPointType (count, is_complex))
- {
- // Structs with long doubles are always passed in memory.
- if (field_bit_width == 128)
- {
- is_memory = true;
- break;
- }
- else if (field_bit_width == 64)
- {
- copy_from_offset = 0;
- fp_bytes += field_byte_width;
- }
- else if (field_bit_width == 32)
- {
- // This one is kind of complicated. If we are in an "eightbyte" with another float, we'll
- // be stuffed into an xmm register with it. If we are in an "eightbyte" with one or more ints,
- // then we will be stuffed into the appropriate GPR with them.
- bool in_gpr;
- if (field_byte_offset % 8 == 0)
- {
- // We are at the beginning of one of the eightbytes, so check the next element (if any)
- if (idx == num_children - 1)
- in_gpr = false;
- else
- {
- uint64_t next_field_bit_offset = 0;
- CompilerType next_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx + 1,
- name,
- &next_field_bit_offset,
- nullptr,
- nullptr);
- if (next_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
- in_gpr = true;
- else
- {
- copy_from_offset = 0;
- in_gpr = false;
- }
- }
- }
- else if (field_byte_offset % 4 == 0)
- {
- // We are inside of an eightbyte, so see if the field before us is floating point:
- // This could happen if somebody put padding in the structure.
- if (idx == 0)
- in_gpr = false;
- else
- {
- uint64_t prev_field_bit_offset = 0;
- CompilerType prev_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx - 1,
- name,
- &prev_field_bit_offset,
- nullptr,
- nullptr);
- if (prev_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
- in_gpr = true;
- else
- {
- copy_from_offset = 4;
- in_gpr = false;
- }
- }
- }
- else
- {
- is_memory = true;
- continue;
- }
-
- // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
- if (in_gpr)
- {
- if (integer_bytes < 8)
- {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &r3_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- }
- else
- {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- }
- }
- else
- {
- fp_bytes += field_byte_width;
- }
- }
+ }
+ } else if (field_byte_offset % 4 == 0) {
+ // We are inside of an eightbyte, so see if the field before us is
+ // floating point:
+ // This could happen if somebody put padding in the structure.
+ if (idx == 0)
+ in_gpr = false;
+ else {
+ uint64_t prev_field_bit_offset = 0;
+ CompilerType prev_field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(idx - 1, name,
+ &prev_field_bit_offset,
+ nullptr, nullptr);
+ if (prev_field_compiler_type.IsIntegerOrEnumerationType(
+ is_signed))
+ in_gpr = true;
+ else {
+ copy_from_offset = 4;
+ in_gpr = false;
}
-
- // These two tests are just sanity checks. If I somehow get the
- // type calculation wrong above it is better to just return nothing
- // than to assert or crash.
- if (!copy_from_extractor)
- return return_valobj_sp;
- if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
- return return_valobj_sp;
-
- copy_from_extractor->CopyByteOrderedData (copy_from_offset,
- field_byte_width,
- data_sp->GetBytes() + field_byte_offset,
- field_byte_width,
- target_byte_order);
+ }
+ } else {
+ is_memory = true;
+ continue;
}
- if (!is_memory)
- {
- // The result is in our data buffer. Let's make a variable object out of it:
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- return_ext);
+ // Okay, we've figured out whether we are in GPR or XMM, now figure
+ // out which one.
+ if (in_gpr) {
+ if (integer_bytes < 8) {
+ // This is in RAX, copy from register to our result structure:
+ copy_from_extractor = &r3_data;
+ copy_from_offset = integer_bytes;
+ integer_bytes += field_byte_width;
+ } else {
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = integer_bytes - 8;
+ integer_bytes += field_byte_width;
+ }
+ } else {
+ fp_bytes += field_byte_width;
}
+ }
}
- // FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location.
- // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the return location. Then we would
- // only return the memory return value if we know it is valid.
+ // These two tests are just sanity checks. If I somehow get the
+ // type calculation wrong above it is better to just return nothing
+ // than to assert or crash.
+ if (!copy_from_extractor)
+ return return_valobj_sp;
+ if (copy_from_offset + field_byte_width >
+ copy_from_extractor->GetByteSize())
+ return return_valobj_sp;
+
+ copy_from_extractor->CopyByteOrderedData(
+ copy_from_offset, field_byte_width,
+ data_sp->GetBytes() + field_byte_offset, field_byte_width,
+ target_byte_order);
+ }
+
+ if (!is_memory) {
+ // The result is in our data buffer. Let's make a variable object out
+ // of it:
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), return_ext);
+ }
+ }
- if (is_memory)
- {
- unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
- lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- return_valobj_sp = ValueObjectMemory::Create(&thread,
- "",
- Address(storage_addr, nullptr),
- return_compiler_type);
- }
+ // FIXME: This is just taking a guess, r3 may very well no longer hold the
+ // return storage location.
+ // If we are going to do this right, when we make a new frame we should
+ // check to see if it uses a memory
+ // return, and if we are at the first instruction and if so stash away the
+ // return location. Then we would
+ // only return the memory return value if we know it is valid.
+
+ if (is_memory) {
+ unsigned r3_id =
+ reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+ lldb::addr_t storage_addr =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id,
+ 0);
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(storage_addr, nullptr), return_compiler_type);
}
+ }
- return return_valobj_sp;
+ return return_valobj_sp;
}
-bool
-ABISysV_ppc::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_ppc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- uint32_t lr_reg_num = dwarf_lr;
- uint32_t sp_reg_num = dwarf_r1;
- uint32_t pc_reg_num = dwarf_pc;
+ uint32_t lr_reg_num = dwarf_lr;
+ uint32_t sp_reg_num = dwarf_r1;
+ uint32_t pc_reg_num = dwarf_pc;
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- // Our Call Frame Address is the stack pointer value
- row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
+ // Our Call Frame Address is the stack pointer value
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
- // The previous PC is in the LR
- row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
- unwind_plan.AppendRow (row);
+ // The previous PC is in the LR
+ row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
+ // All other registers are the same.
- unwind_plan.SetSourceName ("ppc at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetSourceName("ppc at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- return true;
+ return true;
}
-bool
-ABISysV_ppc::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_ppc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- uint32_t sp_reg_num = dwarf_r1;
- uint32_t pc_reg_num = dwarf_lr;
+ uint32_t sp_reg_num = dwarf_r1;
+ uint32_t pc_reg_num = dwarf_lr;
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 4;
- row->GetCFAValue().SetIsRegisterDereferenced (sp_reg_num);
+ const int32_t ptr_size = 4;
+ row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("ppc default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- unwind_plan.SetReturnAddressRegister(dwarf_lr);
- return true;
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("ppc default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetReturnAddressRegister(dwarf_lr);
+ return true;
}
-bool
-ABISysV_ppc::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- return !RegisterIsCalleeSaved (reg_info);
+bool ABISysV_ppc::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
// See "Register Usage" in the
// "System V Application Binary Interface"
// "64-bit PowerPC ELF Application Binary Interface Supplement"
-// current version is 1.9 released 2004 at http://refspecs.linuxfoundation.org/ELF/ppc/PPC-elf64abi-1.9.pdf
-
-bool
-ABISysV_ppc::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Preserved registers are :
- // r1,r2,r13-r31
- // f14-f31 (not yet)
- // v20-v31 (not yet)
- // vrsave (not yet)
-
- const char *name = reg_info->name;
- if (name[0] == 'r')
- {
- if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
- return true;
- if (name[1] == '1' && name[2] > '2')
- return true;
- if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
- return true;
- }
-
- if (name[0] == 'f' && name[1] >= '0' && name[1] <= '9')
- {
- if (name[3] == '1' && name[4] >= '4')
- return true;
- if ((name[3] == '2' || name[3] == '3') && name[4] != '\0')
- return true;
- }
+// current version is 1.9 released 2004 at
+// http://refspecs.linuxfoundation.org/ELF/ppc/PPC-elf64abi-1.9.pdf
+
+bool ABISysV_ppc::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Preserved registers are :
+ // r1,r2,r13-r31
+ // f14-f31 (not yet)
+ // v20-v31 (not yet)
+ // vrsave (not yet)
+
+ const char *name = reg_info->name;
+ if (name[0] == 'r') {
+ if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
+ return true;
+ if (name[1] == '1' && name[2] > '2')
+ return true;
+ if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
+ return true;
+ }
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
- if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
- return true;
+ if (name[0] == 'f' && name[1] >= '0' && name[1] <= '9') {
+ if (name[3] == '1' && name[4] >= '4')
+ return true;
+ if ((name[3] == '2' || name[3] == '3') && name[4] != '\0')
+ return true;
}
- return false;
+
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
+ }
+ return false;
}
-void
-ABISysV_ppc::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "System V ABI for ppc targets",
- CreateInstance);
+void ABISysV_ppc::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "System V ABI for ppc targets", CreateInstance);
}
-void
-ABISysV_ppc::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_ppc::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_ppc::GetPluginNameStatic()
-{
- static ConstString g_name("sysv-ppc");
- return g_name;
+lldb_private::ConstString ABISysV_ppc::GetPluginNameStatic() {
+ static ConstString g_name("sysv-ppc");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_ppc::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_ppc::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_ppc::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_ppc::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
index 99ee755631c2..c9c1c985f679 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
@@ -14,120 +14,100 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_ppc :
- public lldb_private::ABI
-{
+class ABISysV_ppc : public lldb_private::ABI {
public:
- ~ABISysV_ppc() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &type) const override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- // The SysV ppc ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // We have a 64 bit address space, so anything is valid as opcodes
- // aren't fixed width...
- return true;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ~ABISysV_ppc() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ // The SysV ppc ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (8-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // We have a 64 bit address space, so anything is valid as opcodes
+ // aren't fixed width...
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- void
- CreateRegisterMapIfNeeded ();
+ void CreateRegisterMapIfNeeded();
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const;
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- bool
- RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_ppc() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_ppc_h_
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index fea847dd17ee..4ffcba377345 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -25,231 +25,271 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-enum dwarf_regnums
-{
- dwarf_r0 = 0,
- dwarf_r1,
- dwarf_r2,
- dwarf_r3,
- dwarf_r4,
- dwarf_r5,
- dwarf_r6,
- dwarf_r7,
- dwarf_r8,
- dwarf_r9,
- dwarf_r10,
- dwarf_r11,
- dwarf_r12,
- dwarf_r13,
- dwarf_r14,
- dwarf_r15,
- dwarf_r16,
- dwarf_r17,
- dwarf_r18,
- dwarf_r19,
- dwarf_r20,
- dwarf_r21,
- dwarf_r22,
- dwarf_r23,
- dwarf_r24,
- dwarf_r25,
- dwarf_r26,
- dwarf_r27,
- dwarf_r28,
- dwarf_r29,
- dwarf_r30,
- dwarf_r31,
- dwarf_f0,
- dwarf_f1,
- dwarf_f2,
- dwarf_f3,
- dwarf_f4,
- dwarf_f5,
- dwarf_f6,
- dwarf_f7,
- dwarf_f8,
- dwarf_f9,
- dwarf_f10,
- dwarf_f11,
- dwarf_f12,
- dwarf_f13,
- dwarf_f14,
- dwarf_f15,
- dwarf_f16,
- dwarf_f17,
- dwarf_f18,
- dwarf_f19,
- dwarf_f20,
- dwarf_f21,
- dwarf_f22,
- dwarf_f23,
- dwarf_f24,
- dwarf_f25,
- dwarf_f26,
- dwarf_f27,
- dwarf_f28,
- dwarf_f29,
- dwarf_f30,
- dwarf_f31,
- dwarf_cr,
- dwarf_fpscr,
- dwarf_xer = 101,
- dwarf_lr = 108,
- dwarf_ctr,
- dwarf_pc,
- dwarf_cfa,
+enum dwarf_regnums {
+ dwarf_r0 = 0,
+ dwarf_r1,
+ dwarf_r2,
+ dwarf_r3,
+ dwarf_r4,
+ dwarf_r5,
+ dwarf_r6,
+ dwarf_r7,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_r13,
+ dwarf_r14,
+ dwarf_r15,
+ dwarf_r16,
+ dwarf_r17,
+ dwarf_r18,
+ dwarf_r19,
+ dwarf_r20,
+ dwarf_r21,
+ dwarf_r22,
+ dwarf_r23,
+ dwarf_r24,
+ dwarf_r25,
+ dwarf_r26,
+ dwarf_r27,
+ dwarf_r28,
+ dwarf_r29,
+ dwarf_r30,
+ dwarf_r31,
+ dwarf_f0,
+ dwarf_f1,
+ dwarf_f2,
+ dwarf_f3,
+ dwarf_f4,
+ dwarf_f5,
+ dwarf_f6,
+ dwarf_f7,
+ dwarf_f8,
+ dwarf_f9,
+ dwarf_f10,
+ dwarf_f11,
+ dwarf_f12,
+ dwarf_f13,
+ dwarf_f14,
+ dwarf_f15,
+ dwarf_f16,
+ dwarf_f17,
+ dwarf_f18,
+ dwarf_f19,
+ dwarf_f20,
+ dwarf_f21,
+ dwarf_f22,
+ dwarf_f23,
+ dwarf_f24,
+ dwarf_f25,
+ dwarf_f26,
+ dwarf_f27,
+ dwarf_f28,
+ dwarf_f29,
+ dwarf_f30,
+ dwarf_f31,
+ dwarf_cr,
+ dwarf_fpscr,
+ dwarf_xer = 101,
+ dwarf_lr = 108,
+ dwarf_ctr,
+ dwarf_pc,
+ dwarf_cfa,
};
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, 8, 0, eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4}, nullptr, nullptr }
-
-static const RegisterInfo
-g_register_infos[] =
-{
- // General purpose registers. eh_frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2 ,LLDB_INVALID_REGNUM),
- DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- { nullptr, nullptr, 8, 0, eEncodingUint, eFormatHex, { dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, 8, 0, eEncodingUint, eFormatHex, {kind1, kind2, kind3, kind4 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+static const RegisterInfo g_register_infos[] = {
+ // General purpose registers. eh_frame, DWARF,
+ // Generic, Process Plugin
+ DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM),
+ {nullptr,
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
const lldb_private::RegisterInfo *
-ABISysV_ppc64::GetRegisterInfoArray (uint32_t &count)
-{
- count = k_num_register_infos;
- return g_register_infos;
+ABISysV_ppc64::GetRegisterInfoArray(uint32_t &count) {
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABISysV_ppc64::GetRedZoneSize () const
-{
- return 224;
-}
+size_t ABISysV_ppc64::GetRedZoneSize() const { return 224; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_ppc64::CreateInstance (const ArchSpec &arch)
-{
- static ABISP g_abi_sp;
- if (arch.GetTriple().getArch() == llvm::Triple::ppc64)
- {
- if (!g_abi_sp)
- g_abi_sp.reset (new ABISysV_ppc64);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_ppc64::CreateInstance(const ArchSpec &arch) {
+ static ABISP g_abi_sp;
+ if (arch.GetTriple().getArch() == llvm::Triple::ppc64) {
+ if (!g_abi_sp)
+ g_abi_sp.reset(new ABISysV_ppc64);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_ppc64::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- {
- StreamString s;
- s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(),
- (uint64_t)sp,
- (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf (", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1), args[i]);
- s.PutCString (")");
- log->PutCString(s.GetString().c_str());
- }
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
+ args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
- const RegisterInfo *reg_info = nullptr;
+ const RegisterInfo *reg_info = nullptr;
- if (args.size() > 8) // TODO handle more than 8 arguments
- return false;
+ if (args.size() > 8) // TODO handle more than 8 arguments
+ return false;
- for (size_t i = 0; i < args.size(); ++i)
- {
- reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", static_cast<uint64_t>(i + 1), args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
+ for (size_t i = 0; i < args.size(); ++i) {
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + i);
+ if (log)
+ log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
- // First, align the SP
+ // First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ if (log)
+ log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
- sp &= ~(0xfull); // 16-byte alignment
+ sp &= ~(0xfull); // 16-byte alignment
- sp -= 8;
+ sp -= 8;
- Error error;
- const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- ProcessSP process_sp (thread.GetProcess());
+ Error error;
+ const RegisterInfo *pc_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ ProcessSP process_sp(thread.GetProcess());
- RegisterValue reg_value;
+ RegisterValue reg_value;
#if 0
// This code adds an extra frame so that we don't lose the function that we came from
@@ -292,780 +332,696 @@ ABISysV_ppc64::PrepareTrivialCall (Thread &thread,
}
#endif
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
+ if (log)
+ log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
- // Save return address onto the stack
- if (!process_sp->WritePointerToMemory(sp, return_addr, error))
- return false;
+ // Save return address onto the stack
+ if (!process_sp->WritePointerToMemory(sp, return_addr, error))
+ return false;
- // %r1 is set to the actual stack value.
+ // %r1 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
+ return false;
- // %pc is set to the address of the called function.
+ // %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ if (log)
+ log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
- if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
- return true;
+ return true;
}
-static bool ReadIntegerArgument(Scalar &scalar,
- unsigned int bit_width,
- bool is_signed,
- Thread &thread,
- uint32_t *argument_register_ids,
- unsigned int &current_argument_register,
- addr_t &current_stack_argument)
-{
- if (bit_width > 64)
- return false; // Scalar can't hold large integer arguments
-
- if (current_argument_register < 6)
- {
- scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
- current_argument_register++;
- if (is_signed)
- scalar.SignExtend (bit_width);
- }
- else
- {
- uint32_t byte_size = (bit_width + (8-1))/8;
- Error error;
- if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
- {
- current_stack_argument += byte_size;
- return true;
- }
- return false;
+static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
+ bool is_signed, Thread &thread,
+ uint32_t *argument_register_ids,
+ unsigned int &current_argument_register,
+ addr_t &current_stack_argument) {
+ if (bit_width > 64)
+ return false; // Scalar can't hold large integer arguments
+
+ if (current_argument_register < 6) {
+ scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ argument_register_ids[current_argument_register], 0);
+ current_argument_register++;
+ if (is_signed)
+ scalar.SignExtend(bit_width);
+ } else {
+ uint32_t byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (thread.GetProcess()->ReadScalarIntegerFromMemory(
+ current_stack_argument, byte_size, is_signed, scalar, error)) {
+ current_stack_argument += byte_size;
+ return true;
}
- return true;
+ return false;
+ }
+ return true;
}
-bool
-ABISysV_ppc64::GetArgumentValues (Thread &thread,
- ValueList &values) const
-{
- unsigned int num_values = values.GetSize();
- unsigned int value_index;
-
- // Extract the register context so we can read arguments from registers
+bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const {
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ // Extract the register context so we can read arguments from registers
- if (!reg_ctx)
- return false;
-
- // Get the pointer to the first stack argument so we have a place to start
- // when reading data
-
- addr_t sp = reg_ctx->GetSP(0);
-
- if (!sp)
- return false;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- addr_t current_stack_argument = sp + 48; // jump over return address
-
- uint32_t argument_register_ids[8];
+ if (!reg_ctx)
+ return false;
- argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
- argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
- argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
- argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
- argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
- argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
- argument_register_ids[6] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)->kinds[eRegisterKindLLDB];
- argument_register_ids[7] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)->kinds[eRegisterKindLLDB];
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
- unsigned int current_argument_register = 0;
+ addr_t sp = reg_ctx->GetSP(0);
- for (value_index = 0;
- value_index < num_values;
- ++value_index)
- {
- Value *value = values.GetValueAtIndex(value_index);
-
- if (!value)
- return false;
+ if (!sp)
+ return false;
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
- return false;
- bool is_signed;
+ addr_t current_stack_argument = sp + 48; // jump over return address
+
+ uint32_t argument_register_ids[8];
+
+ argument_register_ids[0] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[1] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[2] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[3] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[4] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[5] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[6] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[7] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)
+ ->kinds[eRegisterKindLLDB];
+
+ unsigned int current_argument_register = 0;
+
+ for (value_index = 0; value_index < num_values; ++value_index) {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ CompilerType compiler_type = value->GetCompilerType();
+ if (!compiler_type)
+ 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(), 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);
}
+ }
- return true;
+ return true;
}
-Error
-ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
+Error ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
- Thread *thread = frame_sp->GetThread().get();
+ Thread *thread = frame_sp->GetThread().get();
- bool is_signed;
- uint32_t count;
- bool is_complex;
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
+ set_it_simple = true;
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
+ }
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ 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) {
DataExtractor data;
Error data_error;
size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
}
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
- if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
- }
- }
- else if (compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (is_complex)
- 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)
- {
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
-
- unsigned char buffer[16];
- ByteOrder byte_order = data.GetByteOrder();
+ unsigned char buffer[16];
+ ByteOrder byte_order = data.GetByteOrder();
- data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
- set_it_simple = true;
- }
- else
- {
- // FIXME - don't know how to do 80 bit long doubles yet.
- error.SetErrorString ("We don't support returning float values > 64 bits at present");
- }
- }
+ data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
+ set_it_simple = true;
+ } else {
+ // FIXME - don't know how to do 80 bit long doubles yet.
+ error.SetErrorString(
+ "We don't support returning float values > 64 bits at present");
+ }
}
+ }
- if (!set_it_simple)
- {
- // Okay we've got a structure or something that doesn't fit in a simple register.
- // We should figure out where it really goes, but we don't support this yet.
- error.SetErrorString ("We only support setting simple integer and float return types at present.");
- }
+ if (!set_it_simple) {
+ // Okay we've got a structure or something that doesn't fit in a simple
+ // register.
+ // We should figure out where it really goes, but we don't support this yet.
+ error.SetErrorString("We only support setting simple integer and float "
+ "return types at present.");
+ }
- return error;
+ return error;
}
-ValueObjectSP
-ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
- CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
+ValueObjectSP ABISysV_ppc64::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
- if (!return_compiler_type)
- return return_valobj_sp;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- //value.SetContext (Value::eContextTypeClangType, return_value_type);
- value.SetCompilerType (return_compiler_type);
+ // value.SetContext (Value::eContextTypeClangType, return_value_type);
+ value.SetCompilerType(return_compiler_type);
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
- const uint32_t type_flags = return_compiler_type.GetTypeInfo ();
- if (type_flags & eTypeIsScalar)
- {
- value.SetValueType(Value::eValueTypeScalar);
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo();
+ if (type_flags & eTypeIsScalar) {
+ value.SetValueType(Value::eValueTypeScalar);
- 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);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size)
- {
- default:
- break;
-
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
+ bool success = false;
+ if (type_flags & eTypeIsInteger) {
+ // Extract the register context so we can read arguments from registers
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfoByName("r3", 0), 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size) {
+ default:
+ break;
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size <= sizeof(long double)) {
+ const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
+ RegisterValue f1_value;
+ if (reg_ctx->ReadRegister(f1_info, f1_value)) {
+ DataExtractor data;
+ if (f1_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float)) {
+ value.GetScalar() = (float)data.GetFloat(&offset);
success = true;
- break;
- }
- }
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- }
- else
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double))
- {
- const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
- RegisterValue f1_value;
- if (reg_ctx->ReadRegister (f1_info, f1_value))
- {
- DataExtractor data;
- if (f1_value.GetData(data))
- {
- lldb::offset_t offset = 0;
- if (byte_size == sizeof(float))
- {
- value.GetScalar() = (float) data.GetFloat(&offset);
- success = true;
- }
- else if (byte_size == sizeof(double))
- {
- value.GetScalar() = (double) data.GetDouble(&offset);
- success = true;
- }
- }
- }
- }
+ } else if (byte_size == sizeof(double)) {
+ value.GetScalar() = (double)data.GetDouble(&offset);
+ success = true;
+ }
}
+ }
}
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- }
- else if (type_flags & eTypeIsPointer)
- {
- unsigned r3_id = reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
- value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- value.SetValueType(Value::eValueTypeScalar);
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ }
}
- else if (type_flags & eTypeIsVector)
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size > 0)
- {
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
- if (altivec_reg)
- {
- if (byte_size <= altivec_reg->byte_size)
- {
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(altivec_reg, reg_value))
- {
- Error error;
- if (reg_value.GetAsMemoryData (altivec_reg,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
- }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsPointer) {
+ unsigned r3_id =
+ reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+ value.GetScalar() =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size > 0) {
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
+ if (altivec_reg) {
+ if (byte_size <= altivec_reg->byte_size) {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
+ Error error;
+ if (reg_value.GetAsMemoryData(
+ altivec_reg, heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(), byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order, process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
}
+ }
}
+ }
}
+ }
- return return_valobj_sp;
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
+ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
- if (!return_compiler_type)
- return return_valobj_sp;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- ExecutionContext exe_ctx (thread.shared_from_this());
- return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
- if (return_valobj_sp)
- return return_valobj_sp;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
+ if (return_valobj_sp)
+ return return_valobj_sp;
- RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return return_valobj_sp;
+ RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
+ return return_valobj_sp;
- const size_t bit_width = return_compiler_type.GetBitSize(&thread);
- if (return_compiler_type.IsAggregateType())
- {
- Target *target = exe_ctx.GetTargetPtr();
- bool is_memory = true;
- if (bit_width <= 128)
- {
- ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
- DataBufferSP data_sp (new DataBufferHeap(16, 0));
- DataExtractor return_ext (data_sp,
- target_byte_order,
- target->GetArchitecture().GetAddressByteSize());
+ const size_t bit_width = return_compiler_type.GetBitSize(&thread);
+ if (return_compiler_type.IsAggregateType()) {
+ Target *target = exe_ctx.GetTargetPtr();
+ bool is_memory = true;
+ if (bit_width <= 128) {
+ ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
+ DataBufferSP data_sp(new DataBufferHeap(16, 0));
+ DataExtractor return_ext(data_sp, target_byte_order,
+ target->GetArchitecture().GetAddressByteSize());
- const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
- const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
+ const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
+ const RegisterInfo *rdx_info =
+ reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
- RegisterValue r3_value, rdx_value;
- reg_ctx_sp->ReadRegister (r3_info, r3_value);
- reg_ctx_sp->ReadRegister (rdx_info, rdx_value);
+ RegisterValue r3_value, rdx_value;
+ reg_ctx_sp->ReadRegister(r3_info, r3_value);
+ reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
- DataExtractor r3_data, rdx_data;
+ DataExtractor r3_data, rdx_data;
- r3_value.GetData(r3_data);
- rdx_value.GetData(rdx_data);
+ r3_value.GetData(r3_data);
+ rdx_value.GetData(rdx_data);
- uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far
- uint32_t integer_bytes = 0; // Tracks how much of the r3/rds registers we've consumed so far
+ uint32_t fp_bytes =
+ 0; // Tracks how much of the xmm registers we've consumed so far
+ uint32_t integer_bytes =
+ 0; // Tracks how much of the r3/rds registers we've consumed so far
- const uint32_t num_children = return_compiler_type.GetNumFields ();
+ const uint32_t num_children = return_compiler_type.GetNumFields();
- // Since we are in the small struct regime, assume we are not in memory.
- is_memory = false;
+ // Since we are in the small struct regime, assume we are not in memory.
+ is_memory = false;
- for (uint32_t idx = 0; idx < num_children; idx++)
- {
- std::string name;
- uint64_t field_bit_offset = 0;
- bool is_signed;
- bool is_complex;
- uint32_t count;
+ for (uint32_t idx = 0; idx < num_children; idx++) {
+ std::string name;
+ uint64_t field_bit_offset = 0;
+ bool is_signed;
+ bool is_complex;
+ uint32_t count;
- 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);
+ 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);
- // If there are any unaligned fields, this is stored in memory.
- if (field_bit_offset % field_bit_width != 0)
- {
- is_memory = true;
- break;
- }
+ // If there are any unaligned fields, this is stored in memory.
+ 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_offset = field_bit_offset/8;
-
- DataExtractor *copy_from_extractor = nullptr;
- uint32_t copy_from_offset = 0;
-
- if (field_compiler_type.IsIntegerOrEnumerationType (is_signed) || field_compiler_type.IsPointerType ())
- {
- if (integer_bytes < 8)
- {
- if (integer_bytes + field_byte_width <= 8)
- {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &r3_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- }
- else
- {
- // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
- copy_from_extractor = &rdx_data;
- copy_from_offset = 0;
- integer_bytes = 8 + field_byte_width;
-
- }
- }
- else if (integer_bytes + field_byte_width <= 16)
- {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- }
- else
- {
- // The last field didn't fit. I can't see how that would happen w/o the overall size being
- // greater than 16 bytes. For now, return a nullptr return value object.
- return return_valobj_sp;
- }
+ uint32_t field_byte_width = field_bit_width / 8;
+ uint32_t field_byte_offset = field_bit_offset / 8;
+
+ DataExtractor *copy_from_extractor = nullptr;
+ uint32_t copy_from_offset = 0;
+
+ if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ field_compiler_type.IsPointerType()) {
+ if (integer_bytes < 8) {
+ if (integer_bytes + field_byte_width <= 8) {
+ // This is in RAX, copy from register to our result structure:
+ copy_from_extractor = &r3_data;
+ copy_from_offset = integer_bytes;
+ integer_bytes += field_byte_width;
+ } else {
+ // The next field wouldn't fit in the remaining space, so we
+ // pushed it to rdx.
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = 0;
+ integer_bytes = 8 + field_byte_width;
+ }
+ } else if (integer_bytes + field_byte_width <= 16) {
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = integer_bytes - 8;
+ integer_bytes += field_byte_width;
+ } else {
+ // The last field didn't fit. I can't see how that would happen w/o
+ // the overall size being
+ // greater than 16 bytes. For now, return a nullptr return value
+ // object.
+ return return_valobj_sp;
+ }
+ } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
+ // Structs with long doubles are always passed in memory.
+ if (field_bit_width == 128) {
+ is_memory = true;
+ break;
+ } else if (field_bit_width == 64) {
+ copy_from_offset = 0;
+ fp_bytes += field_byte_width;
+ } else if (field_bit_width == 32) {
+ // This one is kind of complicated. If we are in an "eightbyte"
+ // with another float, we'll
+ // be stuffed into an xmm register with it. If we are in an
+ // "eightbyte" with one or more ints,
+ // then we will be stuffed into the appropriate GPR with them.
+ bool in_gpr;
+ if (field_byte_offset % 8 == 0) {
+ // We are at the beginning of one of the eightbytes, so check the
+ // next element (if any)
+ if (idx == num_children - 1)
+ in_gpr = false;
+ else {
+ uint64_t next_field_bit_offset = 0;
+ CompilerType next_field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(idx + 1, name,
+ &next_field_bit_offset,
+ nullptr, nullptr);
+ if (next_field_compiler_type.IsIntegerOrEnumerationType(
+ is_signed))
+ in_gpr = true;
+ else {
+ copy_from_offset = 0;
+ in_gpr = false;
}
- else if (field_compiler_type.IsFloatingPointType (count, is_complex))
- {
- // Structs with long doubles are always passed in memory.
- if (field_bit_width == 128)
- {
- is_memory = true;
- break;
- }
- else if (field_bit_width == 64)
- {
- copy_from_offset = 0;
- fp_bytes += field_byte_width;
- }
- else if (field_bit_width == 32)
- {
- // This one is kind of complicated. If we are in an "eightbyte" with another float, we'll
- // be stuffed into an xmm register with it. If we are in an "eightbyte" with one or more ints,
- // then we will be stuffed into the appropriate GPR with them.
- bool in_gpr;
- if (field_byte_offset % 8 == 0)
- {
- // We are at the beginning of one of the eightbytes, so check the next element (if any)
- if (idx == num_children - 1)
- in_gpr = false;
- else
- {
- uint64_t next_field_bit_offset = 0;
- CompilerType next_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx + 1,
- name,
- &next_field_bit_offset,
- nullptr,
- nullptr);
- if (next_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
- in_gpr = true;
- else
- {
- copy_from_offset = 0;
- in_gpr = false;
- }
- }
- }
- else if (field_byte_offset % 4 == 0)
- {
- // We are inside of an eightbyte, so see if the field before us is floating point:
- // This could happen if somebody put padding in the structure.
- if (idx == 0)
- in_gpr = false;
- else
- {
- uint64_t prev_field_bit_offset = 0;
- CompilerType prev_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx - 1,
- name,
- &prev_field_bit_offset,
- nullptr,
- nullptr);
- if (prev_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
- in_gpr = true;
- else
- {
- copy_from_offset = 4;
- in_gpr = false;
- }
- }
- }
- else
- {
- is_memory = true;
- continue;
- }
-
- // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
- if (in_gpr)
- {
- if (integer_bytes < 8)
- {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &r3_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- }
- else
- {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- }
- }
- else
- {
- fp_bytes += field_byte_width;
- }
- }
+ }
+ } else if (field_byte_offset % 4 == 0) {
+ // We are inside of an eightbyte, so see if the field before us is
+ // floating point:
+ // This could happen if somebody put padding in the structure.
+ if (idx == 0)
+ in_gpr = false;
+ else {
+ uint64_t prev_field_bit_offset = 0;
+ CompilerType prev_field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(idx - 1, name,
+ &prev_field_bit_offset,
+ nullptr, nullptr);
+ if (prev_field_compiler_type.IsIntegerOrEnumerationType(
+ is_signed))
+ in_gpr = true;
+ else {
+ copy_from_offset = 4;
+ in_gpr = false;
}
-
- // These two tests are just sanity checks. If I somehow get the
- // type calculation wrong above it is better to just return nothing
- // than to assert or crash.
- if (!copy_from_extractor)
- return return_valobj_sp;
- if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
- return return_valobj_sp;
-
- copy_from_extractor->CopyByteOrderedData (copy_from_offset,
- field_byte_width,
- data_sp->GetBytes() + field_byte_offset,
- field_byte_width,
- target_byte_order);
+ }
+ } else {
+ is_memory = true;
+ continue;
}
- if (!is_memory)
- {
- // The result is in our data buffer. Let's make a variable object out of it:
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- return_ext);
+ // Okay, we've figured out whether we are in GPR or XMM, now figure
+ // out which one.
+ if (in_gpr) {
+ if (integer_bytes < 8) {
+ // This is in RAX, copy from register to our result structure:
+ copy_from_extractor = &r3_data;
+ copy_from_offset = integer_bytes;
+ integer_bytes += field_byte_width;
+ } else {
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = integer_bytes - 8;
+ integer_bytes += field_byte_width;
+ }
+ } else {
+ fp_bytes += field_byte_width;
}
+ }
}
- // FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location.
- // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the return location. Then we would
- // only return the memory return value if we know it is valid.
+ // These two tests are just sanity checks. If I somehow get the
+ // type calculation wrong above it is better to just return nothing
+ // than to assert or crash.
+ if (!copy_from_extractor)
+ return return_valobj_sp;
+ if (copy_from_offset + field_byte_width >
+ copy_from_extractor->GetByteSize())
+ return return_valobj_sp;
+
+ copy_from_extractor->CopyByteOrderedData(
+ copy_from_offset, field_byte_width,
+ data_sp->GetBytes() + field_byte_offset, field_byte_width,
+ target_byte_order);
+ }
+
+ if (!is_memory) {
+ // The result is in our data buffer. Let's make a variable object out
+ // of it:
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), return_ext);
+ }
+ }
- if (is_memory)
- {
- unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
- lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
- return_valobj_sp = ValueObjectMemory::Create(&thread,
- "",
- Address(storage_addr, nullptr),
- return_compiler_type);
- }
+ // FIXME: This is just taking a guess, r3 may very well no longer hold the
+ // return storage location.
+ // If we are going to do this right, when we make a new frame we should
+ // check to see if it uses a memory
+ // return, and if we are at the first instruction and if so stash away the
+ // return location. Then we would
+ // only return the memory return value if we know it is valid.
+
+ if (is_memory) {
+ unsigned r3_id =
+ reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+ lldb::addr_t storage_addr =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id,
+ 0);
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(storage_addr, nullptr), return_compiler_type);
}
+ }
- return return_valobj_sp;
+ return return_valobj_sp;
}
-bool
-ABISysV_ppc64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_ppc64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- uint32_t lr_reg_num = dwarf_lr;
- uint32_t sp_reg_num = dwarf_r1;
- uint32_t pc_reg_num = dwarf_pc;
+ uint32_t lr_reg_num = dwarf_lr;
+ uint32_t sp_reg_num = dwarf_r1;
+ uint32_t pc_reg_num = dwarf_pc;
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- // Our Call Frame Address is the stack pointer value
- row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+ // Our Call Frame Address is the stack pointer value
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
- // The previous PC is in the LR
- row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
- unwind_plan.AppendRow (row);
+ // The previous PC is in the LR
+ row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
+ // All other registers are the same.
- unwind_plan.SetSourceName ("ppc64 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetSourceName("ppc64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- return true;
+ return true;
}
-bool
-ABISysV_ppc64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- uint32_t sp_reg_num = dwarf_r1;
- uint32_t pc_reg_num = dwarf_lr;
+ uint32_t sp_reg_num = dwarf_r1;
+ uint32_t pc_reg_num = dwarf_lr;
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 8;
- row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
+ const int32_t ptr_size = 8;
+ row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- row->SetRegisterLocationToAtCFAPlusOffset(dwarf_cr, ptr_size, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(dwarf_cr, ptr_size, true);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("ppc64 default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- unwind_plan.SetReturnAddressRegister(dwarf_lr);
- return true;
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("ppc64 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetReturnAddressRegister(dwarf_lr);
+ return true;
}
-bool
-ABISysV_ppc64::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- return !RegisterIsCalleeSaved (reg_info);
+bool ABISysV_ppc64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
// See "Register Usage" in the
// "System V Application Binary Interface"
// "64-bit PowerPC ELF Application Binary Interface Supplement"
-// current version is 1.9 released 2004 at http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.pdf
-
-bool
-ABISysV_ppc64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Preserved registers are :
- // r1,r2,r13-r31
- // cr2-cr4 (partially preserved)
- // f14-f31 (not yet)
- // v20-v31 (not yet)
- // vrsave (not yet)
-
- const char *name = reg_info->name;
- if (name[0] == 'r')
- {
- if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
- return true;
- if (name[1] == '1' && name[2] > '2')
- return true;
- if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
- return true;
- }
-
- if (name[0] == 'f' && name[1] >= '0' && name[2] <= '9')
- {
- if (name[2] == '\0')
- return false;
- if (name[1] == '1' && name[2] >= '4')
- return true;
- if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
- return true;
- }
+// current version is 1.9 released 2004 at
+// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.pdf
+
+bool ABISysV_ppc64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Preserved registers are :
+ // r1,r2,r13-r31
+ // cr2-cr4 (partially preserved)
+ // f14-f31 (not yet)
+ // v20-v31 (not yet)
+ // vrsave (not yet)
+
+ const char *name = reg_info->name;
+ if (name[0] == 'r') {
+ if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
+ return true;
+ if (name[1] == '1' && name[2] > '2')
+ return true;
+ if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
+ return true;
+ }
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
- if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
- return true;
+ if (name[0] == 'f' && name[1] >= '0' && name[2] <= '9') {
+ if (name[2] == '\0')
+ return false;
+ if (name[1] == '1' && name[2] >= '4')
+ return true;
+ if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
+ return true;
}
- return false;
+
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
+ }
+ return false;
}
-void
-ABISysV_ppc64::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "System V ABI for ppc64 targets",
- CreateInstance);
+void ABISysV_ppc64::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for ppc64 targets", CreateInstance);
}
-void
-ABISysV_ppc64::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_ppc64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_ppc64::GetPluginNameStatic()
-{
- static ConstString g_name("sysv-ppc64");
- return g_name;
+lldb_private::ConstString ABISysV_ppc64::GetPluginNameStatic() {
+ static ConstString g_name("sysv-ppc64");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_ppc64::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_ppc64::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_ppc64::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_ppc64::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
index b87f7938d544..7f321dff49c1 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
@@ -14,120 +14,100 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_ppc64 :
- public lldb_private::ABI
-{
+class ABISysV_ppc64 : public lldb_private::ABI {
public:
- ~ABISysV_ppc64() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &type) const override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- // The SysV ppc64 ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // We have a 64 bit address space, so anything is valid as opcodes
- // aren't fixed width...
- return true;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ~ABISysV_ppc64() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ // The SysV ppc64 ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (8-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // We have a 64 bit address space, so anything is valid as opcodes
+ // aren't fixed width...
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- void
- CreateRegisterMapIfNeeded ();
+ void CreateRegisterMapIfNeeded();
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const;
-
- bool
- RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc64() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_ppc64() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_ppc64_h_
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
index 055905523f81..7e6506bb1f44 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
@@ -37,92 +37,91 @@
using namespace lldb;
using namespace lldb_private;
-enum dwarf_regnums
-{
- // General Purpose Registers
- dwarf_r0_s390x = 0,
- dwarf_r1_s390x,
- dwarf_r2_s390x,
- dwarf_r3_s390x,
- dwarf_r4_s390x,
- dwarf_r5_s390x,
- dwarf_r6_s390x,
- dwarf_r7_s390x,
- dwarf_r8_s390x,
- dwarf_r9_s390x,
- dwarf_r10_s390x,
- dwarf_r11_s390x,
- dwarf_r12_s390x,
- dwarf_r13_s390x,
- dwarf_r14_s390x,
- dwarf_r15_s390x,
- // Floating Point Registers / Vector Registers 0-15
- dwarf_f0_s390x = 16,
- dwarf_f2_s390x,
- dwarf_f4_s390x,
- dwarf_f6_s390x,
- dwarf_f1_s390x,
- dwarf_f3_s390x,
- dwarf_f5_s390x,
- dwarf_f7_s390x,
- dwarf_f8_s390x,
- dwarf_f10_s390x,
- dwarf_f12_s390x,
- dwarf_f14_s390x,
- dwarf_f9_s390x,
- dwarf_f11_s390x,
- dwarf_f13_s390x,
- dwarf_f15_s390x,
- // Access Registers
- dwarf_acr0_s390x = 48,
- dwarf_acr1_s390x,
- dwarf_acr2_s390x,
- dwarf_acr3_s390x,
- dwarf_acr4_s390x,
- dwarf_acr5_s390x,
- dwarf_acr6_s390x,
- dwarf_acr7_s390x,
- dwarf_acr8_s390x,
- dwarf_acr9_s390x,
- dwarf_acr10_s390x,
- dwarf_acr11_s390x,
- dwarf_acr12_s390x,
- dwarf_acr13_s390x,
- dwarf_acr14_s390x,
- dwarf_acr15_s390x,
- // Program Status Word
- dwarf_pswm_s390x = 64,
- dwarf_pswa_s390x,
- // Vector Registers 16-31
- dwarf_v16_s390x = 68,
- dwarf_v18_s390x,
- dwarf_v20_s390x,
- dwarf_v22_s390x,
- dwarf_v17_s390x,
- dwarf_v19_s390x,
- dwarf_v21_s390x,
- dwarf_v23_s390x,
- dwarf_v24_s390x,
- dwarf_v26_s390x,
- dwarf_v28_s390x,
- dwarf_v30_s390x,
- dwarf_v25_s390x,
- dwarf_v27_s390x,
- dwarf_v29_s390x,
- dwarf_v31_s390x,
+enum dwarf_regnums {
+ // General Purpose Registers
+ dwarf_r0_s390x = 0,
+ dwarf_r1_s390x,
+ dwarf_r2_s390x,
+ dwarf_r3_s390x,
+ dwarf_r4_s390x,
+ dwarf_r5_s390x,
+ dwarf_r6_s390x,
+ dwarf_r7_s390x,
+ dwarf_r8_s390x,
+ dwarf_r9_s390x,
+ dwarf_r10_s390x,
+ dwarf_r11_s390x,
+ dwarf_r12_s390x,
+ dwarf_r13_s390x,
+ dwarf_r14_s390x,
+ dwarf_r15_s390x,
+ // Floating Point Registers / Vector Registers 0-15
+ dwarf_f0_s390x = 16,
+ dwarf_f2_s390x,
+ dwarf_f4_s390x,
+ dwarf_f6_s390x,
+ dwarf_f1_s390x,
+ dwarf_f3_s390x,
+ dwarf_f5_s390x,
+ dwarf_f7_s390x,
+ dwarf_f8_s390x,
+ dwarf_f10_s390x,
+ dwarf_f12_s390x,
+ dwarf_f14_s390x,
+ dwarf_f9_s390x,
+ dwarf_f11_s390x,
+ dwarf_f13_s390x,
+ dwarf_f15_s390x,
+ // Access Registers
+ dwarf_acr0_s390x = 48,
+ dwarf_acr1_s390x,
+ dwarf_acr2_s390x,
+ dwarf_acr3_s390x,
+ dwarf_acr4_s390x,
+ dwarf_acr5_s390x,
+ dwarf_acr6_s390x,
+ dwarf_acr7_s390x,
+ dwarf_acr8_s390x,
+ dwarf_acr9_s390x,
+ dwarf_acr10_s390x,
+ dwarf_acr11_s390x,
+ dwarf_acr12_s390x,
+ dwarf_acr13_s390x,
+ dwarf_acr14_s390x,
+ dwarf_acr15_s390x,
+ // Program Status Word
+ dwarf_pswm_s390x = 64,
+ dwarf_pswa_s390x,
+ // Vector Registers 16-31
+ dwarf_v16_s390x = 68,
+ dwarf_v18_s390x,
+ dwarf_v20_s390x,
+ dwarf_v22_s390x,
+ dwarf_v17_s390x,
+ dwarf_v19_s390x,
+ dwarf_v21_s390x,
+ dwarf_v23_s390x,
+ dwarf_v24_s390x,
+ dwarf_v26_s390x,
+ dwarf_v28_s390x,
+ dwarf_v30_s390x,
+ dwarf_v25_s390x,
+ dwarf_v27_s390x,
+ dwarf_v29_s390x,
+ dwarf_v31_s390x,
};
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
-#define DEFINE_REG(name, size, alt, generic) \
- { \
- #name, alt, size, 0, eEncodingUint, eFormatHex, \
- { dwarf_##name##_s390x, dwarf_##name##_s390x, generic, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, \
- NULL, NULL, \
- }
+#define DEFINE_REG(name, size, alt, generic) \
+ { \
+ #name, alt, size, 0, eEncodingUint, eFormatHex, \
+ {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
-static RegisterInfo g_register_infos[] =
-{
+static RegisterInfo g_register_infos[] = {
DEFINE_REG(r0, 8, nullptr, LLDB_INVALID_REGNUM),
DEFINE_REG(r1, 8, nullptr, LLDB_INVALID_REGNUM),
DEFINE_REG(r2, 8, "arg1", LLDB_REGNUM_GENERIC_ARG1),
@@ -175,633 +174,580 @@ static RegisterInfo g_register_infos[] =
DEFINE_REG(f15, 8, nullptr, LLDB_INVALID_REGNUM),
};
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABISysV_s390x::GetRegisterInfoArray(uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABISysV_s390x::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABISysV_s390x::GetRedZoneSize() const
-{
- return 0;
-}
+size_t ABISysV_s390x::GetRedZoneSize() const { return 0; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_s390x::CreateInstance(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);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_s390x::CreateInstance(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);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- if (log)
- {
- StreamString s;
- s.Printf("ABISysV_s390x::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64
- ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1), args[i]);
- s.PutCString(")");
- log->PutCString(s.GetString().c_str());
- }
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
-
- const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0);
- ProcessSP process_sp(thread.GetProcess());
-
- // Allocate a new stack frame and space for stack arguments if necessary
-
- addr_t arg_pos = 0;
- if (args.size() > 5)
- {
- sp -= 8 * (args.size() - 5);
- arg_pos = sp;
- }
+bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- sp -= 160;
-
- // Process arguments
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_s390x::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
for (size_t i = 0; i < args.size(); ++i)
- {
- if (i < 5)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", static_cast<uint64_t>(i + 1),
- args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
- else
- {
- Error error;
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack", static_cast<uint64_t>(i + 1),
- args[i]);
- if (!process_sp->WritePointerToMemory(arg_pos, args[i], error))
- return false;
- arg_pos += 8;
- }
+ s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
+ args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+
+ const RegisterInfo *pc_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0);
+ ProcessSP process_sp(thread.GetProcess());
+
+ // Allocate a new stack frame and space for stack arguments if necessary
+
+ addr_t arg_pos = 0;
+ if (args.size() > 5) {
+ sp -= 8 * (args.size() - 5);
+ arg_pos = sp;
+ }
+
+ sp -= 160;
+
+ // Process arguments
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ if (i < 5) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
+ if (log)
+ log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ } else {
+ Error error;
+ if (log)
+ log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
+ static_cast<uint64_t>(i + 1), args[i]);
+ if (!process_sp->WritePointerToMemory(arg_pos, args[i], error))
+ return false;
+ arg_pos += 8;
}
+ }
- // %r14 is set to the return address
+ // %r14 is set to the return address
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ if (log)
+ log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
- if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
+ return false;
- // %r15 is set to the actual stack value.
+ // %r15 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
- if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
+ return false;
- // %pc is set to the address of the called function.
+ // %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ if (log)
+ log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
- if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
- return true;
+ return true;
}
-static bool
-ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Thread &thread,
- uint32_t *argument_register_ids, unsigned int &current_argument_register,
- addr_t &current_stack_argument)
-{
- if (bit_width > 64)
- return false; // Scalar can't hold large integer arguments
-
- if (current_argument_register < 5)
- {
- scalar =
- thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
- current_argument_register++;
- if (is_signed)
- scalar.SignExtend(bit_width);
- }
- else
- {
- uint32_t byte_size = (bit_width + (8 - 1)) / 8;
- Error error;
- if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument + 8 - byte_size, byte_size,
- is_signed, scalar, error))
- {
- current_stack_argument += 8;
- return true;
- }
- return false;
+static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
+ bool is_signed, Thread &thread,
+ uint32_t *argument_register_ids,
+ unsigned int &current_argument_register,
+ addr_t &current_stack_argument) {
+ if (bit_width > 64)
+ return false; // Scalar can't hold large integer arguments
+
+ if (current_argument_register < 5) {
+ scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ argument_register_ids[current_argument_register], 0);
+ current_argument_register++;
+ if (is_signed)
+ scalar.SignExtend(bit_width);
+ } else {
+ uint32_t byte_size = (bit_width + (8 - 1)) / 8;
+ Error error;
+ if (thread.GetProcess()->ReadScalarIntegerFromMemory(
+ current_stack_argument + 8 - byte_size, byte_size, is_signed,
+ scalar, error)) {
+ current_stack_argument += 8;
+ return true;
}
- return true;
+ return false;
+ }
+ return true;
}
-bool
-ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const
-{
- unsigned int num_values = values.GetSize();
- unsigned int value_index;
+bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const {
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
- // Extract the register context so we can read arguments from registers
+ // Extract the register context so we can read arguments from registers
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
+ if (!reg_ctx)
+ return false;
- // Get the pointer to the first stack argument so we have a place to start
- // when reading data
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
- addr_t sp = reg_ctx->GetSP(0);
+ addr_t sp = reg_ctx->GetSP(0);
- if (!sp)
- return false;
+ if (!sp)
+ return false;
- addr_t current_stack_argument = sp + 160;
-
- uint32_t argument_register_ids[5];
-
- argument_register_ids[0] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
- argument_register_ids[1] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
- argument_register_ids[2] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
- argument_register_ids[3] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
- argument_register_ids[4] =
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
-
- unsigned int current_argument_register = 0;
-
- for (value_index = 0; value_index < num_values; ++value_index)
- {
- Value *value = values.GetValueAtIndex(value_index);
-
- if (!value)
- return false;
-
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
- 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);
- }
+ addr_t current_stack_argument = sp + 160;
+
+ uint32_t argument_register_ids[5];
+
+ argument_register_ids[0] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[1] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[2] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[3] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[4] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
+ ->kinds[eRegisterKindLLDB];
+
+ unsigned int current_argument_register = 0;
+
+ for (value_index = 0; value_index < num_values; ++value_index) {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ CompilerType compiler_type = value->GetCompilerType();
+ if (!compiler_type)
+ 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);
}
+ }
- return true;
+ return true;
}
-Error
-ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
- Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
+Error ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
- CompilerType compiler_type = new_value_sp->GetCompilerType();
- if (!compiler_type)
- {
- error.SetErrorString("Null clang type for return value.");
- return error;
- }
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
- Thread *thread = frame_sp->GetThread().get();
+ Thread *thread = frame_sp->GetThread().get();
- bool is_signed;
- uint32_t count;
- bool is_complex;
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType(is_signed) || compiler_type.IsPointerType())
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
+ set_it_simple = true;
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
+ }
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ 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) {
+ const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
+ RegisterValue f0_value;
DataExtractor data;
Error data_error;
size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
}
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
- if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
- }
- }
- else if (compiler_type.IsFloatingPointType(count, is_complex))
- {
- if (is_complex)
- 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)
- {
- const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
- RegisterValue f0_value;
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s",
- data_error.AsCString());
- return error;
- }
-
- unsigned char buffer[8];
- ByteOrder byte_order = data.GetByteOrder();
-
- data.CopyByteOrderedData(0, num_bytes, buffer, 8, byte_order);
- f0_value.SetBytes(buffer, 8, byte_order);
- reg_ctx->WriteRegister(f0_info, f0_value);
- set_it_simple = true;
- }
- else
- {
- // FIXME - don't know how to do long doubles yet.
- error.SetErrorString("We don't support returning float values > 64 bits at present");
- }
- }
+ unsigned char buffer[8];
+ ByteOrder byte_order = data.GetByteOrder();
+
+ data.CopyByteOrderedData(0, num_bytes, buffer, 8, byte_order);
+ f0_value.SetBytes(buffer, 8, byte_order);
+ reg_ctx->WriteRegister(f0_info, f0_value);
+ set_it_simple = true;
+ } else {
+ // FIXME - don't know how to do long doubles yet.
+ error.SetErrorString(
+ "We don't support returning float values > 64 bits at present");
+ }
}
+ }
- if (!set_it_simple)
- {
- // Okay we've got a structure or something that doesn't fit in a simple register.
- // We should figure out where it really goes, but we don't support this yet.
- error.SetErrorString("We only support setting simple integer and float return types at present.");
- }
+ if (!set_it_simple) {
+ // Okay we've got a structure or something that doesn't fit in a simple
+ // register.
+ // We should figure out where it really goes, but we don't support this yet.
+ error.SetErrorString("We only support setting simple integer and float "
+ "return types at present.");
+ }
- return error;
+ return error;
}
-ValueObjectSP
-ABISysV_s390x::GetReturnValueObjectSimple(Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
-
- if (!return_compiler_type)
- return return_valobj_sp;
-
- // value.SetContext (Value::eContextTypeClangType, return_value_type);
- value.SetCompilerType(return_compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- const uint32_t type_flags = return_compiler_type.GetTypeInfo();
- if (type_flags & eTypeIsScalar)
- {
- value.SetValueType(Value::eValueTypeScalar);
-
- 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);
- uint64_t raw_value =
- thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size)
- {
- default:
- break;
-
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
-
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
-
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
-
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
- }
- }
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- }
- else
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double))
- {
- const RegisterInfo *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))
- {
- value.GetScalar() = (float)data.GetFloat(&offset);
- success = true;
- }
- else if (byte_size == sizeof(double))
- {
- value.GetScalar() = (double)data.GetDouble(&offset);
- success = true;
- }
- else if (byte_size == sizeof(long double))
- {
- // Don't handle long double yet.
- }
- }
- }
- }
+ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
+
+ if (!return_compiler_type)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType, return_value_type);
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo();
+ if (type_flags & eTypeIsScalar) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ 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);
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfoByName("r2", 0), 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size) {
+ default:
+ break;
+
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size <= sizeof(long double)) {
+ const RegisterInfo *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)) {
+ value.GetScalar() = (float)data.GetFloat(&offset);
+ success = true;
+ } else if (byte_size == sizeof(double)) {
+ value.GetScalar() = (double)data.GetDouble(&offset);
+ success = true;
+ } else if (byte_size == sizeof(long double)) {
+ // Don't handle long double yet.
+ }
}
+ }
}
-
- if (success)
- return_valobj_sp =
- ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- }
- else if (type_flags & eTypeIsPointer)
- {
- unsigned r2_id = reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
- value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
- value.SetValueType(Value::eValueTypeScalar);
- return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ }
}
- return return_valobj_sp;
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsPointer) {
+ unsigned r2_id =
+ reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
+ value.GetScalar() =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ }
+
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_s390x::GetReturnValueObjectImpl(Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
-
- if (!return_compiler_type)
- return return_valobj_sp;
-
- ExecutionContext exe_ctx(thread.shared_from_this());
- return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
- if (return_valobj_sp)
- return return_valobj_sp;
-
- RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return return_valobj_sp;
-
- if (return_compiler_type.IsAggregateType())
- {
- // FIXME: This is just taking a guess, r2 may very well no longer hold the return storage location.
- // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the return location. Then we would
- // only return the memory return value if we know it is valid.
-
- unsigned r2_id = reg_ctx_sp->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
- lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
- return_valobj_sp = ValueObjectMemory::Create(&thread, "", Address(storage_addr, nullptr), return_compiler_type);
- }
+ValueObjectSP ABISysV_s390x::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+
+ if (!return_compiler_type)
+ return return_valobj_sp;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
+ if (return_valobj_sp)
return return_valobj_sp;
+
+ RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
+ return return_valobj_sp;
+
+ if (return_compiler_type.IsAggregateType()) {
+ // FIXME: This is just taking a guess, r2 may very well no longer hold the
+ // return storage location.
+ // If we are going to do this right, when we make a new frame we should
+ // check to see if it uses a memory
+ // return, and if we are at the first instruction and if so stash away the
+ // return location. Then we would
+ // only return the memory return value if we know it is valid.
+
+ unsigned r2_id =
+ reg_ctx_sp->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
+ lldb::addr_t storage_addr =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(storage_addr, nullptr), return_compiler_type);
+ }
+
+ return return_valobj_sp;
}
-bool
-ABISysV_s390x::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+bool ABISysV_s390x::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- // Our Call Frame Address is the stack pointer value + 160
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r15_s390x, 160);
+ // Our Call Frame Address is the stack pointer value + 160
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r15_s390x, 160);
- // The previous PC is in r14
- row->SetRegisterLocationToRegister(dwarf_pswa_s390x, dwarf_r14_s390x, true);
+ // The previous PC is in r14
+ row->SetRegisterLocationToRegister(dwarf_pswa_s390x, dwarf_r14_s390x, true);
- // All other registers are the same.
- unwind_plan.AppendRow(row);
- unwind_plan.SetSourceName("s390x at-func-entry default");
- unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- return true;
+ // All other registers are the same.
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("s390x at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
}
-bool
-ABISysV_s390x::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan)
-{
- // There's really no default way to unwind on s390x.
- // Trust the .eh_frame CFI, which should always be good.
- return false;
+bool ABISysV_s390x::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ // There's really no default way to unwind on s390x.
+ // Trust the .eh_frame CFI, which should always be good.
+ return false;
}
-bool
-ABISysV_s390x::GetFallbackRegisterLocation (const RegisterInfo *reg_info,
- UnwindPlan::Row::RegisterLocation &unwind_regloc)
-{
- // If a volatile register is being requested, we don't want to forward the next frame's register contents
- // up the stack -- the register is not retrievable at this frame.
- if (RegisterIsVolatile(reg_info))
- {
- unwind_regloc.SetUndefined();
- return true;
- }
+bool ABISysV_s390x::GetFallbackRegisterLocation(
+ const RegisterInfo *reg_info,
+ UnwindPlan::Row::RegisterLocation &unwind_regloc) {
+ // If a volatile register is being requested, we don't want to forward the
+ // next frame's register contents
+ // up the stack -- the register is not retrievable at this frame.
+ if (RegisterIsVolatile(reg_info)) {
+ unwind_regloc.SetUndefined();
+ return true;
+ }
- return false;
+ return false;
}
-bool
-ABISysV_s390x::RegisterIsVolatile(const RegisterInfo *reg_info)
-{
- return !RegisterIsCalleeSaved(reg_info);
+bool ABISysV_s390x::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
-bool
-ABISysV_s390x::RegisterIsCalleeSaved(const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Preserved registers are :
- // r6-r13, r15
- // f8-f15
-
- const char *name = reg_info->name;
- if (name[0] == 'r')
- {
- switch (name[1])
- {
- case '6': // r6
- case '7': // r7
- case '8': // r8
- case '9': // r9
- return name[2] == '\0';
-
- case '1': // r10, r11, r12, r13, r15
- if ((name[2] >= '0' && name[2] <= '3') || name[2] == '5')
- return name[3] == '\0';
- break;
-
- default:
- break;
- }
- }
- if (name[0] == 'f')
- {
- switch (name[1])
- {
- case '8': // r8
- case '9': // r9
- return name[2] == '\0';
-
- case '1': // r10, r11, r12, r13, r14, r15
- if (name[2] >= '0' && name[2] <= '5')
- return name[3] == '\0';
- break;
-
- default:
- break;
- }
- }
-
- // Accept shorter-variant versions
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
- if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
- return true;
+bool ABISysV_s390x::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Preserved registers are :
+ // r6-r13, r15
+ // f8-f15
+
+ const char *name = reg_info->name;
+ if (name[0] == 'r') {
+ switch (name[1]) {
+ case '6': // r6
+ case '7': // r7
+ case '8': // r8
+ case '9': // r9
+ return name[2] == '\0';
+
+ case '1': // r10, r11, r12, r13, r15
+ if ((name[2] >= '0' && name[2] <= '3') || name[2] == '5')
+ return name[3] == '\0';
+ break;
+
+ default:
+ break;
+ }
}
- return false;
+ if (name[0] == 'f') {
+ switch (name[1]) {
+ case '8': // r8
+ case '9': // r9
+ return name[2] == '\0';
+
+ case '1': // r10, r11, r12, r13, r14, r15
+ if (name[2] >= '0' && name[2] <= '5')
+ return name[3] == '\0';
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Accept shorter-variant versions
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
+ }
+ return false;
}
-void
-ABISysV_s390x::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "System V ABI for s390x targets", CreateInstance);
+void ABISysV_s390x::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for s390x targets", CreateInstance);
}
-void
-ABISysV_s390x::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
+void ABISysV_s390x::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_s390x::GetPluginNameStatic()
-{
- static ConstString g_name("sysv-s390x");
- return g_name;
+lldb_private::ConstString ABISysV_s390x::GetPluginNameStatic() {
+ static ConstString g_name("sysv-s390x");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_s390x::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_s390x::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_s390x::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_s390x::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
index 3aba9c1917c6..6ccabd6f75ec 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
@@ -14,107 +14,94 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_s390x : public lldb_private::ABI
-{
+class ABISysV_s390x : public lldb_private::ABI {
public:
- ~ABISysV_s390x() override = default;
+ ~ABISysV_s390x() override = default;
- size_t
- GetRedZoneSize() const override;
+ size_t GetRedZoneSize() const override;
- bool
- PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress,
- lldb::addr_t returnAddress, llvm::ArrayRef<lldb::addr_t> args) const override;
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
- bool
- GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override;
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override;
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
- bool
- GetFallbackRegisterLocation (const lldb_private::RegisterInfo *reg_info,
- lldb_private::UnwindPlan::Row::RegisterLocation &unwind_regloc) override;
+ bool GetFallbackRegisterLocation(
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::UnwindPlan::Row::RegisterLocation &unwind_regloc) override;
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // Code addressed must be 2 byte aligned
- if (pc & 1ull)
- return false;
- return true;
- }
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Code addressed must be 2 byte aligned
+ if (pc & 1ull)
+ return false;
+ return true;
+ }
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb::ABISP
- CreateInstance(const lldb_private::ArchSpec &arch);
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- void
- CreateRegisterMapIfNeeded();
+ void CreateRegisterMapIfNeeded();
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const;
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- bool
- RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_s390x() : lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_s390x() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_s390x_h_
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 136f46a1d259..2019db2bfd17 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -25,262 +25,1141 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-enum dwarf_regnums
-{
- dwarf_rax = 0,
- dwarf_rdx,
- dwarf_rcx,
- dwarf_rbx,
- dwarf_rsi,
- dwarf_rdi,
- dwarf_rbp,
- dwarf_rsp,
- dwarf_r8,
- dwarf_r9,
- dwarf_r10,
- dwarf_r11,
- dwarf_r12,
- dwarf_r13,
- dwarf_r14,
- dwarf_r15,
- dwarf_rip,
- dwarf_xmm0,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7,
- dwarf_xmm8,
- dwarf_xmm9,
- dwarf_xmm10,
- dwarf_xmm11,
- dwarf_xmm12,
- dwarf_xmm13,
- dwarf_xmm14,
- dwarf_xmm15,
- dwarf_stmm0,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_ymm0,
- dwarf_ymm1,
- dwarf_ymm2,
- dwarf_ymm3,
- dwarf_ymm4,
- dwarf_ymm5,
- dwarf_ymm6,
- dwarf_ymm7,
- dwarf_ymm8,
- dwarf_ymm9,
- dwarf_ymm10,
- dwarf_ymm11,
- dwarf_ymm12,
- dwarf_ymm13,
- dwarf_ymm14,
- dwarf_ymm15
+enum dwarf_regnums {
+ dwarf_rax = 0,
+ dwarf_rdx,
+ dwarf_rcx,
+ dwarf_rbx,
+ dwarf_rsi,
+ dwarf_rdi,
+ dwarf_rbp,
+ dwarf_rsp,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_r13,
+ dwarf_r14,
+ dwarf_r15,
+ dwarf_rip,
+ dwarf_xmm0,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7,
+ dwarf_xmm8,
+ dwarf_xmm9,
+ dwarf_xmm10,
+ dwarf_xmm11,
+ dwarf_xmm12,
+ dwarf_xmm13,
+ dwarf_xmm14,
+ dwarf_xmm15,
+ dwarf_stmm0,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_ymm0,
+ dwarf_ymm1,
+ dwarf_ymm2,
+ dwarf_ymm3,
+ dwarf_ymm4,
+ dwarf_ymm5,
+ dwarf_ymm6,
+ dwarf_ymm7,
+ dwarf_ymm8,
+ dwarf_ymm9,
+ dwarf_ymm10,
+ dwarf_ymm11,
+ dwarf_ymm12,
+ dwarf_ymm13,
+ dwarf_ymm14,
+ dwarf_ymm15,
+ dwarf_bnd0 = 126,
+ dwarf_bnd1,
+ dwarf_bnd2,
+ dwarf_bnd3
};
-static RegisterInfo g_register_infos[] =
-{
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
- // ======== ======= == === ============= =================== ======================= ===================== =========================== ===================== ====================== ========== ===============
- { "rax" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_rax , dwarf_rax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rbx" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_rbx , dwarf_rbx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rcx" , "arg4", 8, 0, eEncodingUint , eFormatHex , { dwarf_rcx , dwarf_rcx , LLDB_REGNUM_GENERIC_ARG4 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rdx" , "arg3", 8, 0, eEncodingUint , eFormatHex , { dwarf_rdx , dwarf_rdx , LLDB_REGNUM_GENERIC_ARG3 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rsi" , "arg2", 8, 0, eEncodingUint , eFormatHex , { dwarf_rsi , dwarf_rsi , LLDB_REGNUM_GENERIC_ARG2 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rdi" , "arg1", 8, 0, eEncodingUint , eFormatHex , { dwarf_rdi , dwarf_rdi , LLDB_REGNUM_GENERIC_ARG1 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rbp" , "fp", 8, 0, eEncodingUint , eFormatHex , { dwarf_rbp , dwarf_rbp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rsp" , "sp", 8, 0, eEncodingUint , eFormatHex , { dwarf_rsp , dwarf_rsp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r8" , "arg5", 8, 0, eEncodingUint , eFormatHex , { dwarf_r8 , dwarf_r8 , LLDB_REGNUM_GENERIC_ARG5 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r9" , "arg6", 8, 0, eEncodingUint , eFormatHex , { dwarf_r9 , dwarf_r9 , LLDB_REGNUM_GENERIC_ARG6 , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r10" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r10 , dwarf_r10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r11" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r11 , dwarf_r11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r12" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r12 , dwarf_r12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r13" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r13 , dwarf_r13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r14" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r14 , dwarf_r14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "r15" , nullptr, 8, 0, eEncodingUint , eFormatHex , { dwarf_r15 , dwarf_r15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rip" , "pc", 8, 0, eEncodingUint , eFormatHex , { dwarf_rip , dwarf_rip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "rflags", nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "cs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ss" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ds" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "es" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "gs" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm0" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm0 , dwarf_stmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm1" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm1 , dwarf_stmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm2" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm2 , dwarf_stmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm3" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm3 , dwarf_stmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm4" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm4 , dwarf_stmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm5" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm5 , dwarf_stmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm6" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm6 , dwarf_stmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "stmm7" , nullptr,10, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_stmm7 , dwarf_stmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fctrl" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fstat" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ftag" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fiseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fioff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "foseg" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fooff" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "fop" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm0" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm0 , dwarf_xmm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm1" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm1 , dwarf_xmm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm2" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm2 , dwarf_xmm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm3" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm3 , dwarf_xmm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm4" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm4 , dwarf_xmm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm5" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm5 , dwarf_xmm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm6" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm6 , dwarf_xmm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm7" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm7 , dwarf_xmm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm8" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm8 , dwarf_xmm8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm9" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm9 , dwarf_xmm9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm10" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm10 , dwarf_xmm10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm11" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm11 , dwarf_xmm11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm12" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm12 , dwarf_xmm12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm13" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm13 , dwarf_xmm13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm14" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm14 , dwarf_xmm14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "xmm15" , nullptr,16, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_xmm15 , dwarf_xmm15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "mxcsr" , nullptr, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm0" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm0 , dwarf_ymm0 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm1" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm1 , dwarf_ymm1 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm2" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm2 , dwarf_ymm2 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm3" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm3 , dwarf_ymm3 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm4" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm4 , dwarf_ymm4 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm5" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm5 , dwarf_ymm5 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm6" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm6 , dwarf_ymm6 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm7" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm7 , dwarf_ymm7 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm8" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm8 , dwarf_ymm8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm9" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm9 , dwarf_ymm9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm10" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm10 , dwarf_ymm10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm11" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm11 , dwarf_ymm11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm12" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm12 , dwarf_ymm12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm13" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm13 , dwarf_ymm13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm14" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm14 , dwarf_ymm14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr },
- { "ymm15" , nullptr,32, 0, eEncodingVector, eFormatVectorOfUInt8, { dwarf_ymm15 , dwarf_ymm15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, nullptr, nullptr }
-};
-
-static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+static RegisterInfo g_register_infos[] = {
+ // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
+ // DWARF GENERIC PROCESS PLUGIN
+ // LLDB NATIVE
+ // ======== ======= == === ============= ===================
+ // ======================= =====================
+ // =========================== ===================== ======================
+ {"rax",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rbx",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rcx",
+ "arg4",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rdx",
+ "arg3",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rsi",
+ "arg2",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rsi, dwarf_rsi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rdi",
+ "arg1",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rdi, dwarf_rdi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rbp",
+ "fp",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rsp",
+ "sp",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ "arg5",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ "arg6",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r13",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r14",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r15",
+ nullptr,
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rip",
+ "pc",
+ 8,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"rflags",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ss",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ds",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"es",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"gs",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm0",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm1",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm2",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm3",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm4",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm5",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm6",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"stmm7",
+ nullptr,
+ 10,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fctrl",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fstat",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ftag",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fiseg",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fioff",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"foseg",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fooff",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fop",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm0",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm1",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm2",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm3",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm4",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm5",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm6",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm7",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm8",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm9",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm10",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm11",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm12",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm13",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm14",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"xmm15",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"mxcsr",
+ nullptr,
+ 4,
+ 0,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm0",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm1",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm2",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm3",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm4",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm5",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm6",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm7",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm8",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm9",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm10",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm11",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm12",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm13",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm14",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"ymm15",
+ nullptr,
+ 32,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd0",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd1",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd2",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bnd3",
+ nullptr,
+ 16,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt64,
+ {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bndcfgu",
+ nullptr,
+ 8,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"bndstatus",
+ nullptr,
+ 8,
+ 0,
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
+
+static const uint32_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos);
static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
-ABISysV_x86_64::GetRegisterInfoArray (uint32_t &count)
-{
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified)
- {
- g_register_info_names_constified = true;
- for (uint32_t i=0; i<k_num_register_infos; ++i)
- {
- if (g_register_infos[i].name)
- g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
- }
+ABISysV_x86_64::GetRegisterInfoArray(uint32_t &count) {
+ // Make the C-string names and alt_names for the register infos into const
+ // C-string values by having the ConstString unique the names in the global
+ // constant C-string pool.
+ if (!g_register_info_names_constified) {
+ g_register_info_names_constified = true;
+ for (uint32_t i = 0; i < k_num_register_infos; ++i) {
+ if (g_register_infos[i].name)
+ g_register_infos[i].name =
+ ConstString(g_register_infos[i].name).GetCString();
+ if (g_register_infos[i].alt_name)
+ g_register_infos[i].alt_name =
+ ConstString(g_register_infos[i].alt_name).GetCString();
}
- count = k_num_register_infos;
- return g_register_infos;
+ }
+ count = k_num_register_infos;
+ return g_register_infos;
}
-size_t
-ABISysV_x86_64::GetRedZoneSize () const
-{
- return 128;
+bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) {
+ name = "rax";
+ return true;
}
+size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; }
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ABISP
-ABISysV_x86_64::CreateInstance (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);
- return g_abi_sp;
- }
- return ABISP();
+ABISysV_x86_64::CreateInstance(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);
+ return g_abi_sp;
+ }
+ return ABISP();
}
-bool
-ABISysV_x86_64::PrepareTrivialCall (Thread &thread,
- addr_t sp,
- addr_t func_addr,
- addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (log)
- {
- StreamString s;
- s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
- thread.GetID(),
- (uint64_t)sp,
- (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf (", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1), args[i]);
- s.PutCString (")");
- log->PutCString(s.GetString().c_str());
- }
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
-
- const RegisterInfo *reg_info = nullptr;
-
- if (args.size() > 6) // TODO handle more than 6 arguments
- return false;
-
+bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
+
for (size_t i = 0; i < args.size(); ++i)
- {
- reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", static_cast<uint64_t>(i + 1), args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
+ s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
+ args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
- // First, align the SP
+ const RegisterInfo *reg_info = nullptr;
+ if (args.size() > 6) // TODO handle more than 6 arguments
+ return false;
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + i);
if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
- sp &= ~(0xfull); // 16-byte alignment
+ // First, align the SP
- sp -= 8;
+ if (log)
+ log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
- Error error;
- const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- ProcessSP process_sp (thread.GetProcess());
+ sp &= ~(0xfull); // 16-byte alignment
- RegisterValue reg_value;
+ sp -= 8;
+
+ Error error;
+ const RegisterInfo *pc_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *sp_reg_info =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ ProcessSP process_sp(thread.GetProcess());
+
+ RegisterValue reg_value;
#if 0
// This code adds an extra frame so that we don't lose the function that we came from
@@ -321,731 +1200,667 @@ ABISysV_x86_64::PrepareTrivialCall (Thread &thread,
sp -= 8;
}
-#endif
-
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
+#endif
- // Save return address onto the stack
- if (!process_sp->WritePointerToMemory(sp, return_addr, error))
- return false;
+ if (log)
+ log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
- // %rsp is set to the actual stack value.
+ // Save return address onto the stack
+ if (!process_sp->WritePointerToMemory(sp, return_addr, error))
+ return false;
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
-
- if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
- return false;
+ // %rsp is set to the actual stack value.
- // %rip is set to the address of the called function.
-
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
- if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
- return false;
+ if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
+ return false;
- return true;
-}
+ // %rip is set to the address of the called function.
-static bool ReadIntegerArgument(Scalar &scalar,
- unsigned int bit_width,
- bool is_signed,
- Thread &thread,
- uint32_t *argument_register_ids,
- unsigned int &current_argument_register,
- addr_t &current_stack_argument)
-{
- if (bit_width > 64)
- return false; // Scalar can't hold large integer arguments
-
- if (current_argument_register < 6)
- {
- scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
- current_argument_register++;
- if (is_signed)
- scalar.SignExtend (bit_width);
- }
- else
- {
- uint32_t byte_size = (bit_width + (8-1))/8;
- Error error;
- if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
- {
- current_stack_argument += byte_size;
- return true;
- }
- return false;
- }
- return true;
-}
+ if (log)
+ log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
-bool
-ABISysV_x86_64::GetArgumentValues (Thread &thread,
- ValueList &values) const
-{
- unsigned int num_values = values.GetSize();
- unsigned int value_index;
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
- return false;
-
- // Get the pointer to the first stack argument so we have a place to start
- // when reading data
-
- addr_t sp = reg_ctx->GetSP(0);
-
- if (!sp)
- return false;
-
- addr_t current_stack_argument = sp + 8; // jump over return address
-
- uint32_t argument_register_ids[6];
-
- argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
- argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
- argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
- argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
- argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
- argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
-
- unsigned int current_argument_register = 0;
-
- for (value_index = 0;
- value_index < num_values;
- ++value_index)
- {
- Value *value = values.GetValueAtIndex(value_index);
-
- if (!value)
- return false;
-
- // We currently only support extracting values with Clang QualTypes.
- // Do we care about others?
- CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
- 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);
- }
- }
-
- return true;
+ if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
+ return false;
+
+ return true;
}
-Error
-ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
-{
+static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
+ bool is_signed, Thread &thread,
+ uint32_t *argument_register_ids,
+ unsigned int &current_argument_register,
+ addr_t &current_stack_argument) {
+ if (bit_width > 64)
+ return false; // Scalar can't hold large integer arguments
+
+ if (current_argument_register < 6) {
+ scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ argument_register_ids[current_argument_register], 0);
+ current_argument_register++;
+ if (is_signed)
+ scalar.SignExtend(bit_width);
+ } else {
+ uint32_t byte_size = (bit_width + (8 - 1)) / 8;
Error error;
- if (!new_value_sp)
- {
- error.SetErrorString("Empty value object for return value.");
- return error;
+ if (thread.GetProcess()->ReadScalarIntegerFromMemory(
+ current_stack_argument, byte_size, is_signed, scalar, error)) {
+ current_stack_argument += byte_size;
+ return true;
}
-
- CompilerType compiler_type = new_value_sp->GetCompilerType();
+ return false;
+ }
+ return true;
+}
+
+bool ABISysV_x86_64::GetArgumentValues(Thread &thread,
+ ValueList &values) const {
+ unsigned int num_values = values.GetSize();
+ unsigned int value_index;
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ // Get the pointer to the first stack argument so we have a place to start
+ // when reading data
+
+ addr_t sp = reg_ctx->GetSP(0);
+
+ if (!sp)
+ return false;
+
+ addr_t current_stack_argument = sp + 8; // jump over return address
+
+ uint32_t argument_register_ids[6];
+
+ argument_register_ids[0] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[1] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[2] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[3] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[4] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
+ ->kinds[eRegisterKindLLDB];
+ argument_register_ids[5] =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
+ ->kinds[eRegisterKindLLDB];
+
+ unsigned int current_argument_register = 0;
+
+ for (value_index = 0; value_index < num_values; ++value_index) {
+ Value *value = values.GetValueAtIndex(value_index);
+
+ if (!value)
+ return false;
+
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ CompilerType compiler_type = value->GetCompilerType();
if (!compiler_type)
- {
- error.SetErrorString ("Null clang type for return value.");
- return error;
- }
-
- Thread *thread = frame_sp->GetThread().get();
-
+ return false;
bool is_signed;
- uint32_t count;
- bool is_complex;
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- bool set_it_simple = false;
- if (compiler_type.IsIntegerOrEnumerationType (is_signed) || compiler_type.IsPointerType())
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
+ 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);
+ }
+ }
+
+ return true;
+}
+
+Error ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Error error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+ bool is_signed;
+ uint32_t count;
+ bool is_complex;
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ bool set_it_simple = false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
+
+ DataExtractor data;
+ Error data_error;
+ size_t num_bytes = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+ lldb::offset_t offset = 0;
+ if (num_bytes <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
+ set_it_simple = true;
+ } else {
+ error.SetErrorString("We don't support returning longer than 64 bit "
+ "integer values at present.");
+ }
+ } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
+ if (is_complex)
+ 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) {
+ const RegisterInfo *xmm0_info =
+ reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ RegisterValue xmm0_value;
DataExtractor data;
Error data_error;
size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
- lldb::offset_t offset = 0;
- if (num_bytes <= 8)
- {
- uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
-
- if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
- set_it_simple = true;
- }
- else
- {
- error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
- }
- }
- else if (compiler_type.IsFloatingPointType (count, is_complex))
- {
- if (is_complex)
- 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)
- {
- const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
- RegisterValue xmm0_value;
- DataExtractor data;
- Error data_error;
- size_t num_bytes = new_value_sp->GetData(data, data_error);
- if (data_error.Fail())
- {
- error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
- return error;
- }
-
- unsigned char buffer[16];
- ByteOrder byte_order = data.GetByteOrder();
-
- data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
- xmm0_value.SetBytes(buffer, 16, byte_order);
- reg_ctx->WriteRegister(xmm0_info, xmm0_value);
- set_it_simple = true;
- }
- else
- {
- // FIXME - don't know how to do 80 bit long doubles yet.
- error.SetErrorString ("We don't support returning float values > 64 bits at present");
- }
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
}
+
+ unsigned char buffer[16];
+ ByteOrder byte_order = data.GetByteOrder();
+
+ data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
+ xmm0_value.SetBytes(buffer, 16, byte_order);
+ reg_ctx->WriteRegister(xmm0_info, xmm0_value);
+ set_it_simple = true;
+ } else {
+ // FIXME - don't know how to do 80 bit long doubles yet.
+ error.SetErrorString(
+ "We don't support returning float values > 64 bits at present");
+ }
}
-
- if (!set_it_simple)
- {
- // Okay we've got a structure or something that doesn't fit in a simple register.
- // We should figure out where it really goes, but we don't support this yet.
- error.SetErrorString ("We only support setting simple integer and float return types at present.");
- }
-
- return error;
+ }
+
+ if (!set_it_simple) {
+ // Okay we've got a structure or something that doesn't fit in a simple
+ // register.
+ // We should figure out where it really goes, but we don't support this yet.
+ error.SetErrorString("We only support setting simple integer and float "
+ "return types at present.");
+ }
+
+ return error;
}
-ValueObjectSP
-ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
- CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
- Value value;
-
- if (!return_compiler_type)
- return return_valobj_sp;
-
- //value.SetContext (Value::eContextTypeClangType, return_value_type);
- value.SetCompilerType (return_compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- const uint32_t type_flags = return_compiler_type.GetTypeInfo ();
- if (type_flags & eTypeIsScalar)
- {
- value.SetValueType(Value::eValueTypeScalar);
+ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
- 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);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size)
- {
- default:
- break;
-
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
+ if (!return_compiler_type)
+ return return_valobj_sp;
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
+ // value.SetContext (Value::eContextTypeClangType, return_value_type);
+ value.SetCompilerType(return_compiler_type);
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo();
+ if (type_flags & eTypeIsScalar) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & eTypeIsInteger) {
+ // Extract the register context so we can read arguments from registers
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfoByName("rax", 0), 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (byte_size) {
+ default:
+ break;
+
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size <= sizeof(long double)) {
+ const RegisterInfo *xmm0_info =
+ reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ RegisterValue xmm0_value;
+ if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
+ DataExtractor data;
+ if (xmm0_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float)) {
+ value.GetScalar() = (float)data.GetFloat(&offset);
success = true;
- break;
- }
- }
- else if (type_flags & eTypeIsFloat)
- {
- if (type_flags & eTypeIsComplex)
- {
- // Don't handle complex yet.
- }
- else
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double))
- {
- const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
- RegisterValue xmm0_value;
- if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
- {
- DataExtractor data;
- if (xmm0_value.GetData(data))
- {
- lldb::offset_t offset = 0;
- if (byte_size == sizeof(float))
- {
- value.GetScalar() = (float) data.GetFloat(&offset);
- success = true;
- }
- else if (byte_size == sizeof(double))
- {
- value.GetScalar() = (double) data.GetDouble(&offset);
- success = true;
- }
- else if (byte_size == sizeof(long double))
- {
- // Don't handle long double since that can be encoded as 80 bit floats...
- }
- }
- }
- }
+ } else if (byte_size == sizeof(double)) {
+ value.GetScalar() = (double)data.GetDouble(&offset);
+ success = true;
+ } else if (byte_size == sizeof(long double)) {
+ // Don't handle long double since that can be encoded as 80 bit
+ // floats...
+ }
}
+ }
}
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
+ }
}
- else if (type_flags & eTypeIsPointer)
- {
- unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
- value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
- value.SetValueType(Value::eValueTypeScalar);
- return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- value,
- ConstString(""));
- }
- else if (type_flags & eTypeIsVector)
- {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size > 0)
- {
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
- if (altivec_reg == nullptr)
- altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
-
- if (altivec_reg)
- {
- if (byte_size <= altivec_reg->byte_size)
- {
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(altivec_reg, reg_value))
- {
- Error error;
- if (reg_value.GetAsMemoryData (altivec_reg,
- heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
- }
- 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));
- const ByteOrder byte_order = process_sp->GetByteOrder();
- RegisterValue reg_value;
- RegisterValue reg_value2;
- if (reg_ctx->ReadRegister(altivec_reg, reg_value) && reg_ctx->ReadRegister(altivec_reg2, reg_value2))
- {
-
- Error error;
- if (reg_value.GetAsMemoryData (altivec_reg,
- heap_data_ap->GetBytes(),
- altivec_reg->byte_size,
- byte_order,
- error) &&
- reg_value2.GetAsMemoryData (altivec_reg2,
- heap_data_ap->GetBytes() + altivec_reg->byte_size,
- heap_data_ap->GetByteSize() - altivec_reg->byte_size,
- byte_order,
- error))
- {
- DataExtractor data (DataBufferSP (heap_data_ap.release()),
- byte_order,
- process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- data);
- }
- }
- }
- }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsPointer) {
+ unsigned rax_id =
+ reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
+ value.GetScalar() =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
+ 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ if (byte_size > 0) {
+ const RegisterInfo *altivec_reg =
+ reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ if (altivec_reg == nullptr)
+ altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+
+ if (altivec_reg) {
+ if (byte_size <= altivec_reg->byte_size) {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
+ Error error;
+ if (reg_value.GetAsMemoryData(
+ altivec_reg, heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(), byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order, process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
+ }
+ }
+ } 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));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ RegisterValue reg_value2;
+ if (reg_ctx->ReadRegister(altivec_reg, reg_value) &&
+ reg_ctx->ReadRegister(altivec_reg2, reg_value2)) {
+
+ Error error;
+ if (reg_value.GetAsMemoryData(
+ altivec_reg, heap_data_ap->GetBytes(),
+ altivec_reg->byte_size, byte_order, error) &&
+ reg_value2.GetAsMemoryData(
+ altivec_reg2,
+ heap_data_ap->GetBytes() + altivec_reg->byte_size,
+ heap_data_ap->GetByteSize() - altivec_reg->byte_size,
+ byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()),
+ byte_order, process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
}
+ }
}
+ }
}
+ }
}
-
- return return_valobj_sp;
+ }
+
+ return return_valobj_sp;
}
-ValueObjectSP
-ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
-{
- ValueObjectSP return_valobj_sp;
-
- if (!return_compiler_type)
- return return_valobj_sp;
-
- ExecutionContext exe_ctx (thread.shared_from_this());
- return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
- if (return_valobj_sp)
- return return_valobj_sp;
-
- RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return return_valobj_sp;
-
- const size_t bit_width = return_compiler_type.GetBitSize(&thread);
- if (return_compiler_type.IsAggregateType())
- {
- Target *target = exe_ctx.GetTargetPtr();
- bool is_memory = true;
- if (bit_width <= 128)
- {
- ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
- DataBufferSP data_sp (new DataBufferHeap(16, 0));
- DataExtractor return_ext (data_sp,
- target_byte_order,
- target->GetArchitecture().GetAddressByteSize());
-
- const RegisterInfo *rax_info = reg_ctx_sp->GetRegisterInfoByName("rax", 0);
- const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
- const RegisterInfo *xmm0_info = reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
- const RegisterInfo *xmm1_info = reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
-
- RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
- reg_ctx_sp->ReadRegister (rax_info, rax_value);
- reg_ctx_sp->ReadRegister (rdx_info, rdx_value);
- reg_ctx_sp->ReadRegister (xmm0_info, xmm0_value);
- reg_ctx_sp->ReadRegister (xmm1_info, xmm1_value);
+ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
- DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
-
- rax_value.GetData(rax_data);
- rdx_value.GetData(rdx_data);
- xmm0_value.GetData(xmm0_data);
- xmm1_value.GetData(xmm1_data);
-
- uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far
- uint32_t integer_bytes = 0; // Tracks how much of the rax/rds registers we've consumed so far
-
- const uint32_t num_children = return_compiler_type.GetNumFields ();
-
- // Since we are in the small struct regime, assume we are not in memory.
- is_memory = false;
-
- for (uint32_t idx = 0; idx < num_children; idx++)
- {
- std::string name;
- uint64_t field_bit_offset = 0;
- bool is_signed;
- bool is_complex;
- uint32_t count;
-
- 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);
-
- // if we don't know the size of the field (e.g. invalid type), just bail out
- if (field_bit_width == 0)
- break;
-
- // If there are any unaligned fields, this is stored in memory.
- 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_offset = field_bit_offset/8;
-
- DataExtractor *copy_from_extractor = nullptr;
- uint32_t copy_from_offset = 0;
-
- if (field_compiler_type.IsIntegerOrEnumerationType (is_signed) || field_compiler_type.IsPointerType ())
- {
- if (integer_bytes < 8)
- {
- if (integer_bytes + field_byte_width <= 8)
- {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &rax_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- }
- else
- {
- // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
- copy_from_extractor = &rdx_data;
- copy_from_offset = 0;
- integer_bytes = 8 + field_byte_width;
- }
- }
- else if (integer_bytes + field_byte_width <= 16)
- {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- }
- else
- {
- // The last field didn't fit. I can't see how that would happen w/o the overall size being
- // greater than 16 bytes. For now, return a nullptr return value object.
- return return_valobj_sp;
- }
+ if (!return_compiler_type)
+ return return_valobj_sp;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
+ if (return_valobj_sp)
+ return return_valobj_sp;
+
+ RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
+ return return_valobj_sp;
+
+ const size_t bit_width = return_compiler_type.GetBitSize(&thread);
+ if (return_compiler_type.IsAggregateType()) {
+ Target *target = exe_ctx.GetTargetPtr();
+ bool is_memory = true;
+ if (bit_width <= 128) {
+ ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
+ DataBufferSP data_sp(new DataBufferHeap(16, 0));
+ DataExtractor return_ext(data_sp, target_byte_order,
+ target->GetArchitecture().GetAddressByteSize());
+
+ const RegisterInfo *rax_info =
+ reg_ctx_sp->GetRegisterInfoByName("rax", 0);
+ const RegisterInfo *rdx_info =
+ reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
+ const RegisterInfo *xmm0_info =
+ reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
+ const RegisterInfo *xmm1_info =
+ reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
+
+ RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
+ reg_ctx_sp->ReadRegister(rax_info, rax_value);
+ reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
+ reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value);
+ reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value);
+
+ DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
+
+ rax_value.GetData(rax_data);
+ rdx_value.GetData(rdx_data);
+ xmm0_value.GetData(xmm0_data);
+ xmm1_value.GetData(xmm1_data);
+
+ uint32_t fp_bytes =
+ 0; // Tracks how much of the xmm registers we've consumed so far
+ uint32_t integer_bytes =
+ 0; // Tracks how much of the rax/rds registers we've consumed so far
+
+ const uint32_t num_children = return_compiler_type.GetNumFields();
+
+ // Since we are in the small struct regime, assume we are not in memory.
+ is_memory = false;
+
+ for (uint32_t idx = 0; idx < num_children; idx++) {
+ std::string name;
+ uint64_t field_bit_offset = 0;
+ bool is_signed;
+ bool is_complex;
+ uint32_t count;
+
+ 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);
+
+ // if we don't know the size of the field (e.g. invalid type), just bail
+ // out
+ if (field_bit_width == 0)
+ break;
+
+ // If there are any unaligned fields, this is stored in memory.
+ 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_offset = field_bit_offset / 8;
+
+ DataExtractor *copy_from_extractor = nullptr;
+ uint32_t copy_from_offset = 0;
+
+ if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ field_compiler_type.IsPointerType()) {
+ if (integer_bytes < 8) {
+ if (integer_bytes + field_byte_width <= 8) {
+ // This is in RAX, copy from register to our result structure:
+ copy_from_extractor = &rax_data;
+ copy_from_offset = integer_bytes;
+ integer_bytes += field_byte_width;
+ } else {
+ // The next field wouldn't fit in the remaining space, so we
+ // pushed it to rdx.
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = 0;
+ integer_bytes = 8 + field_byte_width;
+ }
+ } else if (integer_bytes + field_byte_width <= 16) {
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = integer_bytes - 8;
+ integer_bytes += field_byte_width;
+ } else {
+ // The last field didn't fit. I can't see how that would happen w/o
+ // the overall size being
+ // greater than 16 bytes. For now, return a nullptr return value
+ // object.
+ return return_valobj_sp;
+ }
+ } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
+ // Structs with long doubles are always passed in memory.
+ if (field_bit_width == 128) {
+ is_memory = true;
+ break;
+ } else if (field_bit_width == 64) {
+ // These have to be in a single xmm register.
+ if (fp_bytes == 0)
+ copy_from_extractor = &xmm0_data;
+ else
+ copy_from_extractor = &xmm1_data;
+
+ copy_from_offset = 0;
+ fp_bytes += field_byte_width;
+ } else if (field_bit_width == 32) {
+ // This one is kind of complicated. If we are in an "eightbyte"
+ // with another float, we'll
+ // be stuffed into an xmm register with it. If we are in an
+ // "eightbyte" with one or more ints,
+ // then we will be stuffed into the appropriate GPR with them.
+ bool in_gpr;
+ if (field_byte_offset % 8 == 0) {
+ // We are at the beginning of one of the eightbytes, so check the
+ // next element (if any)
+ if (idx == num_children - 1)
+ in_gpr = false;
+ else {
+ uint64_t next_field_bit_offset = 0;
+ CompilerType next_field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(idx + 1, name,
+ &next_field_bit_offset,
+ nullptr, nullptr);
+ if (next_field_compiler_type.IsIntegerOrEnumerationType(
+ is_signed))
+ in_gpr = true;
+ else {
+ copy_from_offset = 0;
+ in_gpr = false;
}
- else if (field_compiler_type.IsFloatingPointType (count, is_complex))
- {
- // Structs with long doubles are always passed in memory.
- if (field_bit_width == 128)
- {
- is_memory = true;
- break;
- }
- else if (field_bit_width == 64)
- {
- // These have to be in a single xmm register.
- if (fp_bytes == 0)
- copy_from_extractor = &xmm0_data;
- else
- copy_from_extractor = &xmm1_data;
-
- copy_from_offset = 0;
- fp_bytes += field_byte_width;
- }
- else if (field_bit_width == 32)
- {
- // This one is kind of complicated. If we are in an "eightbyte" with another float, we'll
- // be stuffed into an xmm register with it. If we are in an "eightbyte" with one or more ints,
- // then we will be stuffed into the appropriate GPR with them.
- bool in_gpr;
- if (field_byte_offset % 8 == 0)
- {
- // We are at the beginning of one of the eightbytes, so check the next element (if any)
- if (idx == num_children - 1)
- in_gpr = false;
- else
- {
- uint64_t next_field_bit_offset = 0;
- CompilerType next_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx + 1,
- name,
- &next_field_bit_offset,
- nullptr,
- nullptr);
- if (next_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
- in_gpr = true;
- else
- {
- copy_from_offset = 0;
- in_gpr = false;
- }
- }
- }
- else if (field_byte_offset % 4 == 0)
- {
- // We are inside of an eightbyte, so see if the field before us is floating point:
- // This could happen if somebody put padding in the structure.
- if (idx == 0)
- in_gpr = false;
- else
- {
- uint64_t prev_field_bit_offset = 0;
- CompilerType prev_field_compiler_type = return_compiler_type.GetFieldAtIndex (idx - 1,
- name,
- &prev_field_bit_offset,
- nullptr,
- nullptr);
- if (prev_field_compiler_type.IsIntegerOrEnumerationType (is_signed))
- in_gpr = true;
- else
- {
- copy_from_offset = 4;
- in_gpr = false;
- }
- }
- }
- else
- {
- is_memory = true;
- continue;
- }
-
- // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
- if (in_gpr)
- {
- if (integer_bytes < 8)
- {
- // This is in RAX, copy from register to our result structure:
- copy_from_extractor = &rax_data;
- copy_from_offset = integer_bytes;
- integer_bytes += field_byte_width;
- }
- else
- {
- copy_from_extractor = &rdx_data;
- copy_from_offset = integer_bytes - 8;
- integer_bytes += field_byte_width;
- }
- }
- else
- {
- if (fp_bytes < 8)
- copy_from_extractor = &xmm0_data;
- else
- copy_from_extractor = &xmm1_data;
-
- fp_bytes += field_byte_width;
- }
- }
+ }
+ } else if (field_byte_offset % 4 == 0) {
+ // We are inside of an eightbyte, so see if the field before us is
+ // floating point:
+ // This could happen if somebody put padding in the structure.
+ if (idx == 0)
+ in_gpr = false;
+ else {
+ uint64_t prev_field_bit_offset = 0;
+ CompilerType prev_field_compiler_type =
+ return_compiler_type.GetFieldAtIndex(idx - 1, name,
+ &prev_field_bit_offset,
+ nullptr, nullptr);
+ if (prev_field_compiler_type.IsIntegerOrEnumerationType(
+ is_signed))
+ in_gpr = true;
+ else {
+ copy_from_offset = 4;
+ in_gpr = false;
}
-
- // These two tests are just sanity checks. If I somehow get the
- // type calculation wrong above it is better to just return nothing
- // than to assert or crash.
- if (!copy_from_extractor)
- return return_valobj_sp;
- if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
- return return_valobj_sp;
-
- copy_from_extractor->CopyByteOrderedData (copy_from_offset,
- field_byte_width,
- data_sp->GetBytes() + field_byte_offset,
- field_byte_width,
- target_byte_order);
+ }
+ } else {
+ is_memory = true;
+ continue;
}
-
- if (!is_memory)
- {
- // The result is in our data buffer. Let's make a variable object out of it:
- return_valobj_sp = ValueObjectConstResult::Create (&thread,
- return_compiler_type,
- ConstString(""),
- return_ext);
+
+ // Okay, we've figured out whether we are in GPR or XMM, now figure
+ // out which one.
+ if (in_gpr) {
+ if (integer_bytes < 8) {
+ // This is in RAX, copy from register to our result structure:
+ copy_from_extractor = &rax_data;
+ copy_from_offset = integer_bytes;
+ integer_bytes += field_byte_width;
+ } else {
+ copy_from_extractor = &rdx_data;
+ copy_from_offset = integer_bytes - 8;
+ integer_bytes += field_byte_width;
+ }
+ } else {
+ if (fp_bytes < 8)
+ copy_from_extractor = &xmm0_data;
+ else
+ copy_from_extractor = &xmm1_data;
+
+ fp_bytes += field_byte_width;
}
+ }
}
- // FIXME: This is just taking a guess, rax may very well no longer hold the return storage location.
- // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
- // return, and if we are at the first instruction and if so stash away the return location. Then we would
- // only return the memory return value if we know it is valid.
-
- if (is_memory)
- {
- unsigned rax_id = reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
- lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
- return_valobj_sp = ValueObjectMemory::Create(&thread,
- "",
- Address(storage_addr, nullptr),
- return_compiler_type);
- }
+ // These two tests are just sanity checks. If I somehow get the
+ // type calculation wrong above it is better to just return nothing
+ // than to assert or crash.
+ if (!copy_from_extractor)
+ return return_valobj_sp;
+ if (copy_from_offset + field_byte_width >
+ copy_from_extractor->GetByteSize())
+ return return_valobj_sp;
+
+ copy_from_extractor->CopyByteOrderedData(
+ copy_from_offset, field_byte_width,
+ data_sp->GetBytes() + field_byte_offset, field_byte_width,
+ target_byte_order);
+ }
+
+ if (!is_memory) {
+ // The result is in our data buffer. Let's make a variable object out
+ // of it:
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), return_ext);
+ }
}
-
- return return_valobj_sp;
+
+ // FIXME: This is just taking a guess, rax may very well no longer hold the
+ // return storage location.
+ // If we are going to do this right, when we make a new frame we should
+ // check to see if it uses a memory
+ // return, and if we are at the first instruction and if so stash away the
+ // return location. Then we would
+ // only return the memory return value if we know it is valid.
+
+ if (is_memory) {
+ unsigned rax_id =
+ reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
+ lldb::addr_t storage_addr =
+ (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
+ 0);
+ return_valobj_sp = ValueObjectMemory::Create(
+ &thread, "", Address(storage_addr, nullptr), return_compiler_type);
+ }
+ }
+
+ return return_valobj_sp;
}
// This defines the CFA as rsp+8
// the saved pc is at CFA-8 (i.e. rsp+0)
// The saved rsp is CFA+0
-bool
-ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t sp_reg_num = dwarf_rsp;
- uint32_t pc_reg_num = dwarf_rip;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("x86_64 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- return true;
+bool ABISysV_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t sp_reg_num = dwarf_rsp;
+ uint32_t pc_reg_num = dwarf_rip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("x86_64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
}
// This defines the CFA as rbp+16
@@ -1053,137 +1868,114 @@ ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
// The saved rbp is at CFA-16 (i.e. rbp+0)
// The saved rsp is CFA+0
-bool
-ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- uint32_t fp_reg_num = dwarf_rbp;
- uint32_t sp_reg_num = dwarf_rsp;
- uint32_t pc_reg_num = dwarf_rip;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- const int32_t ptr_size = 8;
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
- row->SetOffset (0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
- row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("x86_64 default unwind plan");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
+bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num = dwarf_rbp;
+ uint32_t sp_reg_num = dwarf_rsp;
+ uint32_t pc_reg_num = dwarf_rip;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ const int32_t ptr_size = 8;
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("x86_64 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
}
-bool
-ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
-{
- return !RegisterIsCalleeSaved (reg_info);
+bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
}
-// See "Register Usage" in the
+// See "Register Usage" in the
// "System V Application Binary Interface"
-// "AMD64 Architecture Processor Supplement"
+// "AMD64 Architecture Processor Supplement"
// (or "x86-64(tm) Architecture Processor Supplement" in earlier revisions)
// (this doc is also commonly referred to as the x86-64/AMD64 psABI)
// Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
-// current version is 0.99.6 released 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
+// current version is 0.99.6 released 2012-07-02 at
+// http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
-bool
-ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
-{
- if (reg_info)
- {
- // Preserved registers are :
- // rbx, rsp, rbp, r12, r13, r14, r15
- // mxcsr (partially preserved)
- // x87 control word
-
- const char *name = reg_info->name;
- if (name[0] == 'r')
- {
- switch (name[1])
- {
- case '1': // r12, r13, r14, r15
- if (name[2] >= '2' && name[2] <= '5')
- return name[3] == '\0';
- break;
-
- default:
- break;
- }
- }
+bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ // Preserved registers are :
+ // rbx, rsp, rbp, r12, r13, r14, r15
+ // mxcsr (partially preserved)
+ // x87 control word
+
+ const char *name = reg_info->name;
+ if (name[0] == 'r') {
+ switch (name[1]) {
+ case '1': // r12, r13, r14, r15
+ if (name[2] >= '2' && name[2] <= '5')
+ return name[3] == '\0';
+ break;
+
+ default:
+ break;
+ }
+ }
- // Accept shorter-variant versions, rbx/ebx, rip/ eip, etc.
- if (name[0] == 'r' || name[0] == 'e')
- {
- switch (name[1])
- {
- case 'b': // rbp, rbx
- if (name[2] == 'p' || name[2] == 'x')
- return name[3] == '\0';
- break;
-
- case 'i': // rip
- if (name[2] == 'p')
- return name[3] == '\0';
- break;
-
- case 's': // rsp
- if (name[2] == 'p')
- return name[3] == '\0';
- break;
- }
- }
- if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
- return true;
- if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
- return true;
- if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
- return true;
+ // Accept shorter-variant versions, rbx/ebx, rip/ eip, etc.
+ if (name[0] == 'r' || name[0] == 'e') {
+ switch (name[1]) {
+ case 'b': // rbp, rbx
+ if (name[2] == 'p' || name[2] == 'x')
+ return name[3] == '\0';
+ break;
+
+ case 'i': // rip
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+
+ case 's': // rsp
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+ }
}
- return false;
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
+ }
+ return false;
}
-void
-ABISysV_x86_64::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "System V ABI for x86_64 targets",
- CreateInstance);
+void ABISysV_x86_64::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance);
}
-void
-ABISysV_x86_64::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ABISysV_x86_64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ABISysV_x86_64::GetPluginNameStatic()
-{
- static ConstString g_name("sysv-x86_64");
- return g_name;
+lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() {
+ static ConstString g_name("sysv-x86_64");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ABISysV_x86_64::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ABISysV_x86_64::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ABISysV_x86_64::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; }
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 07b57abaf57c..29f2ce133d42 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
@@ -14,120 +14,102 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
-class ABISysV_x86_64 :
- public lldb_private::ABI
-{
+class ABISysV_x86_64 : public lldb_private::ABI {
public:
- ~ABISysV_x86_64() override = default;
-
- size_t
- GetRedZoneSize() const override;
-
- bool
- PrepareTrivialCall(lldb_private::Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const override;
-
- bool
- GetArgumentValues(lldb_private::Thread &thread,
- lldb_private::ValueList &values) const override;
-
- lldb_private::Error
- SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override;
-
- lldb::ValueObjectSP
- GetReturnValueObjectImpl(lldb_private::Thread &thread,
- lldb_private::CompilerType &type) const override;
-
- bool
- CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
-
- bool
- RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
-
- // The SysV x86_64 ABI requires that stack frames be 16 byte aligned.
- // When there is a trap handler on the stack, e.g. _sigtramp in userland
- // code, we've seen that the stack pointer is often not aligned properly
- // before the handler is invoked. This means that lldb will stop the unwind
- // early -- before the function which caused the trap.
- //
- // To work around this, we relax that alignment to be just word-size (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
- // in other environments there can be a large number of different functions
- // involved in async traps.
- bool
- CallFrameAddressIsValid(lldb::addr_t cfa) override
- {
- // Make sure the stack call frame addresses are 8 byte aligned
- if (cfa & (8ull - 1ull))
- return false; // Not 8 byte aligned
- if (cfa == 0)
- return false; // Zero is not a valid stack address
- return true;
- }
-
- bool
- CodeAddressIsValid(lldb::addr_t pc) override
- {
- // We have a 64 bit address space, so anything is valid as opcodes
- // aren't fixed width...
- return true;
- }
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ABISP
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ~ABISysV_x86_64() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ // The SysV x86_64 ABI requires that stack frames be 16 byte aligned.
+ // When there is a trap handler on the stack, e.g. _sigtramp in userland
+ // code, we've seen that the stack pointer is often not aligned properly
+ // before the handler is invoked. This means that lldb will stop the unwind
+ // early -- before the function which caused the trap.
+ //
+ // To work around this, we relax that alignment to be just word-size
+ // (8-bytes).
+ // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // in other environments there can be a large number of different functions
+ // involved in async traps.
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Make sure the stack call frame addresses are 8 byte aligned
+ if (cfa & (8ull - 1ull))
+ return false; // Not 8 byte aligned
+ if (cfa == 0)
+ return false; // Zero is not a valid stack address
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // We have a 64 bit address space, so anything is valid as opcodes
+ // aren't fixed width...
+ return true;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ bool GetPointerReturnRegister(const char *&name) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- void
- CreateRegisterMapIfNeeded ();
+ void CreateRegisterMapIfNeeded();
- lldb::ValueObjectSP
- GetReturnValueObjectSimple(lldb_private::Thread &thread,
- lldb_private::CompilerType &ast_type) const;
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
- bool
- RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_x86_64() :
- lldb_private::ABI()
- {
- // Call CreateInstance instead.
- }
+ ABISysV_x86_64() : lldb_private::ABI() {
+ // Call CreateInstance instead.
+ }
};
#endif // liblldb_ABISysV_x86_64_h_
diff --git a/source/Plugins/CMakeLists.txt b/source/Plugins/CMakeLists.txt
index 928332fb6ba4..ac1afcbc331e 100644
--- a/source/Plugins/CMakeLists.txt
+++ b/source/Plugins/CMakeLists.txt
@@ -14,6 +14,7 @@ add_subdirectory(OperatingSystem)
add_subdirectory(Platform)
add_subdirectory(Process)
add_subdirectory(ScriptInterpreter)
+add_subdirectory(StructuredData)
add_subdirectory(SymbolFile)
add_subdirectory(SystemRuntime)
add_subdirectory(SymbolVendor)
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 4d24cf1ab6de..b7415b42c60e 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -23,6 +23,7 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
@@ -31,6 +32,7 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -38,986 +40,1336 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Core/RegularExpression.h"
using namespace lldb;
using namespace lldb_private;
-class InstructionLLVMC : public lldb_private::Instruction
-{
+class InstructionLLVMC : public lldb_private::Instruction {
public:
- InstructionLLVMC (DisassemblerLLVMC &disasm,
- const lldb_private::Address &address,
- AddressClass addr_class) :
- Instruction (address, addr_class),
- m_disasm_wp (std::static_pointer_cast<DisassemblerLLVMC>(disasm.shared_from_this())),
- m_does_branch (eLazyBoolCalculate),
- m_has_delay_slot (eLazyBoolCalculate),
- m_is_valid (false),
- m_using_file_addr (false)
- {
- }
-
- ~InstructionLLVMC() override = default;
-
- bool
- DoesBranch() override
- {
- if (m_does_branch == eLazyBoolCalculate)
- {
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp)
- {
- disasm_sp->Lock(this, NULL);
- DataExtractor data;
- if (m_opcode.GetData(data))
- {
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
- // Be conservative, if we didn't understand the instruction, say it might branch...
- if (inst_size == 0)
- m_does_branch = eLazyBoolYes;
- else
- {
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
- m_does_branch = eLazyBoolYes;
- else
- m_does_branch = eLazyBoolNo;
- }
- }
- disasm_sp->Unlock();
- }
+ InstructionLLVMC(DisassemblerLLVMC &disasm,
+ const lldb_private::Address &address,
+ AddressClass addr_class)
+ : Instruction(address, addr_class),
+ m_disasm_wp(std::static_pointer_cast<DisassemblerLLVMC>(
+ disasm.shared_from_this())),
+ m_does_branch(eLazyBoolCalculate), m_has_delay_slot(eLazyBoolCalculate),
+ m_is_call(eLazyBoolCalculate), m_is_valid(false),
+ m_using_file_addr(false) {}
+
+ ~InstructionLLVMC() override = default;
+
+ bool DoesBranch() override {
+ if (m_does_branch == eLazyBoolCalculate) {
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp) {
+ disasm_sp->Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data)) {
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ GetDisasmToUse(is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size =
+ mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
+ // Be conservative, if we didn't understand the instruction, say it
+ // might branch...
+ if (inst_size == 0)
+ m_does_branch = eLazyBoolYes;
+ else {
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
}
- return m_does_branch == eLazyBoolYes;
- }
-
- bool
- HasDelaySlot() override
- {
- if (m_has_delay_slot == eLazyBoolCalculate)
- {
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp)
- {
- disasm_sp->Lock(this, NULL);
- DataExtractor data;
- if (m_opcode.GetData(data))
- {
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
- // if we didn't understand the instruction, say it doesn't have a delay slot...
- if (inst_size == 0)
- m_has_delay_slot = eLazyBoolNo;
- else
- {
- const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
- if (has_delay_slot)
- m_has_delay_slot = eLazyBoolYes;
- else
- m_has_delay_slot = eLazyBoolNo;
- }
- }
- disasm_sp->Unlock();
- }
+ disasm_sp->Unlock();
+ }
+ }
+ return m_does_branch == eLazyBoolYes;
+ }
+
+ bool HasDelaySlot() override {
+ if (m_has_delay_slot == eLazyBoolCalculate) {
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp) {
+ disasm_sp->Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data)) {
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ GetDisasmToUse(is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size =
+ mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
+ // if we didn't understand the instruction, say it doesn't have a
+ // delay slot...
+ if (inst_size == 0)
+ m_has_delay_slot = eLazyBoolNo;
+ else {
+ const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
+ if (has_delay_slot)
+ m_has_delay_slot = eLazyBoolYes;
+ else
+ m_has_delay_slot = eLazyBoolNo;
+ }
}
- return m_has_delay_slot == eLazyBoolYes;
- }
-
- DisassemblerLLVMC::LLVMCDisassembler *
- GetDisasmToUse (bool &is_alternate_isa)
- {
- is_alternate_isa = false;
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp)
- {
- if (disasm_sp->m_alternate_disasm_ap.get() != NULL)
- {
- const AddressClass address_class = GetAddressClass ();
-
- if (address_class == eAddressClassCodeAlternateISA)
- {
- is_alternate_isa = true;
- return disasm_sp->m_alternate_disasm_ap.get();
- }
+ disasm_sp->Unlock();
+ }
+ }
+ return m_has_delay_slot == eLazyBoolYes;
+ }
+
+ DisassemblerLLVMC::LLVMCDisassembler *GetDisasmToUse(bool &is_alternate_isa) {
+ is_alternate_isa = false;
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp) {
+ if (disasm_sp->m_alternate_disasm_ap.get() != NULL) {
+ const AddressClass address_class = GetAddressClass();
+
+ if (address_class == eAddressClassCodeAlternateISA) {
+ is_alternate_isa = true;
+ return disasm_sp->m_alternate_disasm_ap.get();
+ }
+ }
+ return disasm_sp->m_disasm_ap.get();
+ }
+ return nullptr;
+ }
+
+ size_t Decode(const lldb_private::Disassembler &disassembler,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t data_offset) override {
+ // 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();
+ const lldb::ByteOrder byte_order = data.GetByteOrder();
+
+ const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
+ const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
+ if (min_op_byte_size == max_op_byte_size) {
+ // Fixed size instructions, just read that amount of data.
+ if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
+ return false;
+
+ switch (min_op_byte_size) {
+ case 1:
+ m_opcode.SetOpcode8(data.GetU8(&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 2:
+ m_opcode.SetOpcode16(data.GetU16(&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 4:
+ m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 8:
+ m_opcode.SetOpcode64(data.GetU64(&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ default:
+ m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size),
+ min_op_byte_size);
+ got_op = true;
+ break;
+ }
+ }
+ if (!got_op) {
+ bool is_alternate_isa = false;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ GetDisasmToUse(is_alternate_isa);
+
+ const llvm::Triple::ArchType machine = arch.GetMachine();
+ if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) {
+ if (machine == llvm::Triple::thumb || is_alternate_isa) {
+ uint32_t thumb_opcode = data.GetU16(&data_offset);
+ if ((thumb_opcode & 0xe000) != 0xe000 ||
+ ((thumb_opcode & 0x1800u) == 0)) {
+ m_opcode.SetOpcode16(thumb_opcode, byte_order);
+ m_is_valid = true;
+ } else {
+ thumb_opcode <<= 16;
+ thumb_opcode |= data.GetU16(&data_offset);
+ m_opcode.SetOpcode16_2(thumb_opcode, byte_order);
+ m_is_valid = true;
}
- return disasm_sp->m_disasm_ap.get();
+ } else {
+ m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order);
+ m_is_valid = true;
+ }
+ } else {
+ // The opcode isn't evenly sized, so we need to actually use the llvm
+ // disassembler to parse it and get the size.
+ uint8_t *opcode_data =
+ const_cast<uint8_t *>(data.PeekData(data_offset, 1));
+ const size_t opcode_data_len = data.BytesLeft(data_offset);
+ 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 {
+ m_opcode.SetOpcodeBytes(opcode_data, inst_size);
+ m_is_valid = true;
+ }
}
- return nullptr;
- }
-
- size_t
- Decode(const lldb_private::Disassembler &disassembler,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_offset) override
- {
- // 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();
- const lldb::ByteOrder byte_order = data.GetByteOrder();
-
- const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
- const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
- if (min_op_byte_size == max_op_byte_size)
- {
- // Fixed size instructions, just read that amount of data.
- if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
- return false;
-
- switch (min_op_byte_size)
- {
- case 1:
- m_opcode.SetOpcode8 (data.GetU8 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 2:
- m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 4:
- m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 8:
- m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order);
- got_op = true;
- break;
-
- default:
- m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
- got_op = true;
- break;
- }
+ }
+ return m_opcode.GetByteSize();
+ }
+ return 0;
+ }
+
+ void AppendComment(std::string &description) {
+ if (m_comment.empty())
+ m_comment.swap(description);
+ else {
+ m_comment.append(", ");
+ m_comment.append(description);
+ }
+ }
+
+ void CalculateMnemonicOperandsAndComment(
+ const lldb_private::ExecutionContext *exe_ctx) override {
+ DataExtractor data;
+ const AddressClass address_class = GetAddressClass();
+
+ if (m_opcode.GetData(data)) {
+ std::string out_string;
+ std::string comment_string;
+
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp) {
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
+
+ if (address_class == eAddressClassCodeAlternateISA)
+ mc_disasm_ptr = disasm_sp->m_alternate_disasm_ap.get();
+ else
+ mc_disasm_ptr = disasm_sp->m_disasm_ap.get();
+
+ lldb::addr_t pc = m_address.GetFileAddress();
+ m_using_file_addr = true;
+
+ const bool data_from_file = disasm_sp->m_data_from_file;
+ bool use_hex_immediates = true;
+ Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
+
+ if (exe_ctx) {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target) {
+ use_hex_immediates = target->GetUseHexImmediates();
+ hex_style = target->GetHexImmediateStyle();
+
+ if (!data_from_file) {
+ const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ pc = load_addr;
+ m_using_file_addr = false;
+ }
}
- if (!got_op)
- {
- bool is_alternate_isa = false;
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
-
- const llvm::Triple::ArchType machine = arch.GetMachine();
- if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
- {
- if (machine == llvm::Triple::thumb || is_alternate_isa)
- {
- uint32_t thumb_opcode = data.GetU16(&data_offset);
- if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
- {
- m_opcode.SetOpcode16 (thumb_opcode, byte_order);
- m_is_valid = true;
- }
- else
- {
- thumb_opcode <<= 16;
- thumb_opcode |= data.GetU16(&data_offset);
- m_opcode.SetOpcode16_2 (thumb_opcode, byte_order);
- m_is_valid = true;
- }
- }
- else
- {
- m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order);
- m_is_valid = true;
- }
- }
- else
- {
- // The opcode isn't evenly sized, so we need to actually use the llvm
- // disassembler to parse it and get the size.
- uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
- const size_t opcode_data_len = data.BytesLeft(data_offset);
- 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
- {
- m_opcode.SetOpcodeBytes(opcode_data, inst_size);
- m_is_valid = true;
- }
- }
+ }
+ }
+
+ disasm_sp->Lock(this, exe_ctx);
+
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ size_t inst_size =
+ mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
+
+ if (inst_size > 0) {
+ mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
+ mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
+
+ if (!comment_string.empty()) {
+ AppendComment(comment_string);
+ }
+ }
+
+ disasm_sp->Unlock();
+
+ if (inst_size == 0) {
+ m_comment.assign("unknown opcode");
+ inst_size = m_opcode.GetByteSize();
+ StreamString mnemonic_strm;
+ lldb::offset_t offset = 0;
+ lldb::ByteOrder byte_order = data.GetByteOrder();
+ switch (inst_size) {
+ case 1: {
+ const uint8_t uval8 = data.GetU8(&offset);
+ m_opcode.SetOpcode8(uval8, byte_order);
+ m_opcode_name.assign(".byte");
+ mnemonic_strm.Printf("0x%2.2x", uval8);
+ } break;
+ case 2: {
+ const uint16_t uval16 = data.GetU16(&offset);
+ m_opcode.SetOpcode16(uval16, byte_order);
+ m_opcode_name.assign(".short");
+ mnemonic_strm.Printf("0x%4.4x", uval16);
+ } break;
+ case 4: {
+ const uint32_t uval32 = data.GetU32(&offset);
+ m_opcode.SetOpcode32(uval32, byte_order);
+ m_opcode_name.assign(".long");
+ mnemonic_strm.Printf("0x%8.8x", uval32);
+ } break;
+ case 8: {
+ const uint64_t uval64 = data.GetU64(&offset);
+ m_opcode.SetOpcode64(uval64, byte_order);
+ m_opcode_name.assign(".quad");
+ mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
+ } break;
+ default:
+ if (inst_size == 0)
+ return;
+ else {
+ const uint8_t *bytes = data.PeekData(offset, inst_size);
+ if (bytes == NULL)
+ return;
+ m_opcode_name.assign(".byte");
+ m_opcode.SetOpcodeBytes(bytes, inst_size);
+ mnemonic_strm.Printf("0x%2.2x", bytes[0]);
+ for (uint32_t i = 1; i < inst_size; ++i)
+ mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
}
- return m_opcode.GetByteSize();
+ break;
+ }
+ m_mnemonics = mnemonic_strm.GetString();
+ return;
+ } else {
+ if (m_does_branch == eLazyBoolCalculate) {
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
+ }
+
+ static RegularExpression s_regex(
+ llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?"));
+
+ RegularExpression::Match matches(3);
+
+ if (s_regex.Execute(out_string, &matches)) {
+ matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
+ matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
}
- return 0;
+ }
+ }
+ }
+
+ bool IsValid() const { return m_is_valid; }
+
+ 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();
+ }
+
+ static llvm::StringRef::const_iterator
+ ConsumeWhitespace(llvm::StringRef::const_iterator osi,
+ llvm::StringRef::const_iterator ose) {
+ while (osi != ose) {
+ switch (*osi) {
+ default:
+ return osi;
+ case ' ':
+ case '\t':
+ break;
+ }
+ ++osi;
}
- void
- AppendComment (std::string &description)
- {
- if (m_comment.empty())
- m_comment.swap (description);
- else
- {
- m_comment.append(", ");
- m_comment.append(description);
+ return osi;
+ }
+
+ static std::pair<bool, llvm::StringRef::const_iterator>
+ ConsumeChar(llvm::StringRef::const_iterator osi, const char c,
+ llvm::StringRef::const_iterator ose) {
+ bool found = false;
+
+ osi = ConsumeWhitespace(osi, ose);
+ if (osi != ose && *osi == c) {
+ found = true;
+ ++osi;
+ }
+
+ return std::make_pair(found, osi);
+ }
+
+ static std::pair<Operand, llvm::StringRef::const_iterator>
+ ParseRegisterName(llvm::StringRef::const_iterator osi,
+ llvm::StringRef::const_iterator ose) {
+ Operand ret;
+ ret.m_type = Operand::Type::Register;
+ std::string str;
+
+ osi = ConsumeWhitespace(osi, ose);
+
+ while (osi != ose) {
+ if (*osi >= '0' && *osi <= '9') {
+ if (str.empty()) {
+ return std::make_pair(Operand(), osi);
+ } else {
+ str.push_back(*osi);
+ }
+ } else if (*osi >= 'a' && *osi <= 'z') {
+ str.push_back(*osi);
+ } else {
+ switch (*osi) {
+ default:
+ if (str.empty()) {
+ return std::make_pair(Operand(), osi);
+ } else {
+ ret.m_register = ConstString(str);
+ return std::make_pair(ret, osi);
+ }
+ case '%':
+ if (!str.empty()) {
+ return std::make_pair(Operand(), osi);
+ }
+ break;
}
+ }
+ ++osi;
}
- void
- CalculateMnemonicOperandsAndComment(const lldb_private::ExecutionContext *exe_ctx) override
- {
- DataExtractor data;
- const AddressClass address_class = GetAddressClass ();
-
- if (m_opcode.GetData(data))
- {
- std::string out_string;
- std::string comment_string;
-
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp)
- {
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
-
- if (address_class == eAddressClassCodeAlternateISA)
- mc_disasm_ptr = disasm_sp->m_alternate_disasm_ap.get();
- else
- mc_disasm_ptr = disasm_sp->m_disasm_ap.get();
-
- lldb::addr_t pc = m_address.GetFileAddress();
- m_using_file_addr = true;
-
- const bool data_from_file = disasm_sp->m_data_from_file;
- bool use_hex_immediates = true;
- Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
-
- if (exe_ctx)
- {
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
- {
- use_hex_immediates = target->GetUseHexImmediates();
- hex_style = target->GetHexImmediateStyle();
-
- if (!data_from_file)
- {
- const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- pc = load_addr;
- m_using_file_addr = false;
- }
- }
- }
- }
-
- disasm_sp->Lock(this, exe_ctx);
-
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
-
- if (inst_size > 0)
- {
- mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
- mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
-
- if (!comment_string.empty())
- {
- AppendComment(comment_string);
- }
- }
-
- disasm_sp->Unlock();
-
- if (inst_size == 0)
- {
- m_comment.assign ("unknown opcode");
- inst_size = m_opcode.GetByteSize();
- StreamString mnemonic_strm;
- lldb::offset_t offset = 0;
- lldb::ByteOrder byte_order = data.GetByteOrder();
- switch (inst_size)
- {
- case 1:
- {
- const uint8_t uval8 = data.GetU8 (&offset);
- m_opcode.SetOpcode8 (uval8, byte_order);
- m_opcode_name.assign (".byte");
- mnemonic_strm.Printf("0x%2.2x", uval8);
- }
- break;
- case 2:
- {
- const uint16_t uval16 = data.GetU16(&offset);
- m_opcode.SetOpcode16(uval16, byte_order);
- m_opcode_name.assign (".short");
- mnemonic_strm.Printf("0x%4.4x", uval16);
- }
- break;
- case 4:
- {
- const uint32_t uval32 = data.GetU32(&offset);
- m_opcode.SetOpcode32(uval32, byte_order);
- m_opcode_name.assign (".long");
- mnemonic_strm.Printf("0x%8.8x", uval32);
- }
- break;
- case 8:
- {
- const uint64_t uval64 = data.GetU64(&offset);
- m_opcode.SetOpcode64(uval64, byte_order);
- m_opcode_name.assign (".quad");
- mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
- }
- break;
- default:
- if (inst_size == 0)
- return;
- else
- {
- const uint8_t *bytes = data.PeekData(offset, inst_size);
- if (bytes == NULL)
- return;
- m_opcode_name.assign (".byte");
- m_opcode.SetOpcodeBytes(bytes, inst_size);
- mnemonic_strm.Printf("0x%2.2x", bytes[0]);
- for (uint32_t i=1; i<inst_size; ++i)
- mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
- }
- break;
- }
- m_mnemonics.swap(mnemonic_strm.GetString());
- return;
- }
- else
- {
- if (m_does_branch == eLazyBoolCalculate)
- {
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
- m_does_branch = eLazyBoolYes;
- else
- m_does_branch = eLazyBoolNo;
-
- }
- }
-
- static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?");
-
- RegularExpression::Match matches(3);
-
- if (s_regex.Execute(out_string.c_str(), &matches))
- {
- matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
- matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
- }
- }
+ ret.m_register = ConstString(str);
+ return std::make_pair(ret, osi);
+ }
+
+ static std::pair<Operand, llvm::StringRef::const_iterator>
+ ParseImmediate(llvm::StringRef::const_iterator osi,
+ llvm::StringRef::const_iterator ose) {
+ Operand ret;
+ ret.m_type = Operand::Type::Immediate;
+ std::string str;
+ bool is_hex = false;
+
+ osi = ConsumeWhitespace(osi, ose);
+
+ while (osi != ose) {
+ if (*osi >= '0' && *osi <= '9') {
+ str.push_back(*osi);
+ } else if (*osi >= 'a' && *osi <= 'f') {
+ if (is_hex) {
+ str.push_back(*osi);
+ } else {
+ return std::make_pair(Operand(), osi);
}
+ } else {
+ switch (*osi) {
+ default:
+ if (str.empty()) {
+ return std::make_pair(Operand(), osi);
+ } else {
+ ret.m_immediate = strtoull(str.c_str(), nullptr, 0);
+ return std::make_pair(ret, osi);
+ }
+ case 'x':
+ if (!str.compare("0")) {
+ is_hex = true;
+ str.push_back(*osi);
+ } else {
+ return std::make_pair(Operand(), osi);
+ }
+ break;
+ case '#':
+ case '$':
+ if (!str.empty()) {
+ return std::make_pair(Operand(), osi);
+ }
+ break;
+ case '-':
+ if (str.empty()) {
+ ret.m_negative = true;
+ } else {
+ return std::make_pair(Operand(), osi);
+ }
+ }
+ }
+ ++osi;
}
- bool
- IsValid () const
- {
- return m_is_valid;
+ ret.m_immediate = strtoull(str.c_str(), nullptr, 0);
+ return std::make_pair(ret, osi);
+ }
+
+ // -0x5(%rax,%rax,2)
+ static std::pair<Operand, llvm::StringRef::const_iterator>
+ ParseIntelIndexedAccess(llvm::StringRef::const_iterator osi,
+ llvm::StringRef::const_iterator ose) {
+ std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
+ ParseImmediate(osi, ose);
+ if (offset_and_iterator.first.IsValid()) {
+ osi = offset_and_iterator.second;
}
- bool
- UsingFileAddress() const
- {
- return m_using_file_addr;
+ bool found = false;
+ std::tie(found, osi) = ConsumeChar(osi, '(', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
}
- size_t
- GetByteSize () const
- {
- return m_opcode.GetByteSize();
+
+ std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
+ ParseRegisterName(osi, ose);
+ if (base_and_iterator.first.IsValid()) {
+ osi = base_and_iterator.second;
+ } else {
+ return std::make_pair(Operand(), osi);
}
- std::shared_ptr<DisassemblerLLVMC>
- GetDisassembler ()
- {
- return m_disasm_wp.lock();
+ std::tie(found, osi) = ConsumeChar(osi, ',', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
}
-protected:
- std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;
- LazyBool m_does_branch;
- LazyBool m_has_delay_slot;
- bool m_is_valid;
- bool m_using_file_addr;
-};
+ std::pair<Operand, llvm::StringRef::const_iterator> index_and_iterator =
+ ParseRegisterName(osi, ose);
+ if (index_and_iterator.first.IsValid()) {
+ osi = index_and_iterator.second;
+ } else {
+ return std::make_pair(Operand(), osi);
+ }
-DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner):
- m_is_valid(true)
-{
- std::string Error;
- const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
- if (!curr_target)
- {
- m_is_valid = false;
- return;
+ std::tie(found, osi) = ConsumeChar(osi, ',', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
}
- m_instr_info_ap.reset(curr_target->createMCInstrInfo());
- m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
+ std::pair<Operand, llvm::StringRef::const_iterator>
+ multiplier_and_iterator = ParseImmediate(osi, ose);
+ if (index_and_iterator.first.IsValid()) {
+ osi = index_and_iterator.second;
+ } else {
+ return std::make_pair(Operand(), osi);
+ }
- m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, cpu,
- features_str));
+ std::tie(found, osi) = ConsumeChar(osi, ')', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
+ }
- std::unique_ptr<llvm::MCRegisterInfo> reg_info(curr_target->createMCRegInfo(triple));
- m_asm_info_ap.reset(curr_target->createMCAsmInfo(*reg_info, triple));
+ Operand product;
+ product.m_type = Operand::Type::Product;
+ product.m_children.push_back(index_and_iterator.first);
+ product.m_children.push_back(multiplier_and_iterator.first);
+
+ Operand index;
+ index.m_type = Operand::Type::Sum;
+ index.m_children.push_back(base_and_iterator.first);
+ index.m_children.push_back(product);
+
+ if (offset_and_iterator.first.IsValid()) {
+ Operand offset;
+ offset.m_type = Operand::Type::Sum;
+ offset.m_children.push_back(offset_and_iterator.first);
+ offset.m_children.push_back(index);
+
+ Operand deref;
+ deref.m_type = Operand::Type::Dereference;
+ deref.m_children.push_back(offset);
+ return std::make_pair(deref, osi);
+ } else {
+ Operand deref;
+ deref.m_type = Operand::Type::Dereference;
+ deref.m_children.push_back(index);
+ return std::make_pair(deref, osi);
+ }
+ }
+
+ // -0x10(%rbp)
+ static std::pair<Operand, llvm::StringRef::const_iterator>
+ ParseIntelDerefAccess(llvm::StringRef::const_iterator osi,
+ llvm::StringRef::const_iterator ose) {
+ std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
+ ParseImmediate(osi, ose);
+ if (offset_and_iterator.first.IsValid()) {
+ osi = offset_and_iterator.second;
+ }
- if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
- {
- m_is_valid = false;
- return;
+ bool found = false;
+ std::tie(found, osi) = ConsumeChar(osi, '(', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
}
- m_context_ap.reset(new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));
+ std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
+ ParseRegisterName(osi, ose);
+ if (base_and_iterator.first.IsValid()) {
+ osi = base_and_iterator.second;
+ } else {
+ return std::make_pair(Operand(), osi);
+ }
- m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get(), *m_context_ap.get()));
- if (m_disasm_ap.get() && m_context_ap.get())
- {
- std::unique_ptr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
- if (!RelInfo)
- {
- m_is_valid = false;
- return;
- }
- std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(curr_target->createMCSymbolizer(triple, NULL,
- DisassemblerLLVMC::SymbolLookupCallback,
- (void *) &owner,
- m_context_ap.get(), std::move(RelInfo)));
- m_disasm_ap->setSymbolizer(std::move(symbolizer_up));
+ std::tie(found, osi) = ConsumeChar(osi, ')', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
+ }
+ if (offset_and_iterator.first.IsValid()) {
+ Operand offset;
+ offset.m_type = Operand::Type::Sum;
+ offset.m_children.push_back(offset_and_iterator.first);
+ offset.m_children.push_back(base_and_iterator.first);
+
+ Operand deref;
+ deref.m_type = Operand::Type::Dereference;
+ deref.m_children.push_back(offset);
+ return std::make_pair(deref, osi);
+ } else {
+ Operand deref;
+ deref.m_type = Operand::Type::Dereference;
+ deref.m_children.push_back(base_and_iterator.first);
+ return std::make_pair(deref, osi);
+ }
+ }
+
+ // [sp, #8]!
+ static std::pair<Operand, llvm::StringRef::const_iterator>
+ ParseARMOffsetAccess(llvm::StringRef::const_iterator osi,
+ llvm::StringRef::const_iterator ose) {
+ bool found = false;
+ std::tie(found, osi) = ConsumeChar(osi, '[', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
+ }
- unsigned asm_printer_variant;
- if (flavor == ~0U)
- asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
- else
- {
- asm_printer_variant = flavor;
- }
+ std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
+ ParseRegisterName(osi, ose);
+ if (base_and_iterator.first.IsValid()) {
+ osi = base_and_iterator.second;
+ } else {
+ return std::make_pair(Operand(), osi);
+ }
+
+ std::tie(found, osi) = ConsumeChar(osi, ',', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
+ }
+
+ std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
+ ParseImmediate(osi, ose);
+ if (offset_and_iterator.first.IsValid()) {
+ osi = offset_and_iterator.second;
+ }
+
+ std::tie(found, osi) = ConsumeChar(osi, ']', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
+ }
+
+ Operand offset;
+ offset.m_type = Operand::Type::Sum;
+ offset.m_children.push_back(offset_and_iterator.first);
+ offset.m_children.push_back(base_and_iterator.first);
+
+ Operand deref;
+ deref.m_type = Operand::Type::Dereference;
+ deref.m_children.push_back(offset);
+ return std::make_pair(deref, osi);
+ }
+
+ // [sp]
+ static std::pair<Operand, llvm::StringRef::const_iterator>
+ ParseARMDerefAccess(llvm::StringRef::const_iterator osi,
+ llvm::StringRef::const_iterator ose) {
+ bool found = false;
+ std::tie(found, osi) = ConsumeChar(osi, '[', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
+ }
+
+ std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
+ ParseRegisterName(osi, ose);
+ if (base_and_iterator.first.IsValid()) {
+ osi = base_and_iterator.second;
+ } else {
+ return std::make_pair(Operand(), osi);
+ }
+
+ std::tie(found, osi) = ConsumeChar(osi, ']', ose);
+ if (!found) {
+ return std::make_pair(Operand(), osi);
+ }
+
+ Operand deref;
+ deref.m_type = Operand::Type::Dereference;
+ deref.m_children.push_back(base_and_iterator.first);
+ return std::make_pair(deref, osi);
+ }
+
+ static void DumpOperand(const Operand &op, Stream &s) {
+ switch (op.m_type) {
+ case Operand::Type::Dereference:
+ s.PutCString("*");
+ DumpOperand(op.m_children[0], s);
+ break;
+ case Operand::Type::Immediate:
+ if (op.m_negative) {
+ s.PutCString("-");
+ }
+ s.PutCString(llvm::to_string(op.m_immediate));
+ break;
+ case Operand::Type::Invalid:
+ s.PutCString("Invalid");
+ break;
+ case Operand::Type::Product:
+ s.PutCString("(");
+ DumpOperand(op.m_children[0], s);
+ s.PutCString("*");
+ DumpOperand(op.m_children[1], s);
+ s.PutCString(")");
+ break;
+ case Operand::Type::Register:
+ s.PutCString(op.m_register.AsCString());
+ break;
+ case Operand::Type::Sum:
+ s.PutCString("(");
+ DumpOperand(op.m_children[0], s);
+ s.PutCString("+");
+ DumpOperand(op.m_children[1], s);
+ s.PutCString(")");
+ break;
+ }
+ }
+
+ bool ParseOperands(
+ llvm::SmallVectorImpl<Instruction::Operand> &operands) override {
+ const char *operands_string = GetOperands(nullptr);
+
+ if (!operands_string) {
+ return false;
+ }
+
+ llvm::StringRef operands_ref(operands_string);
+
+ llvm::StringRef::const_iterator osi = operands_ref.begin();
+ llvm::StringRef::const_iterator ose = operands_ref.end();
+
+ while (osi != ose) {
+ Operand operand;
+ llvm::StringRef::const_iterator iter;
+
+ if ((std::tie(operand, iter) = ParseIntelIndexedAccess(osi, ose),
+ operand.IsValid()) ||
+ (std::tie(operand, iter) = ParseIntelDerefAccess(osi, ose),
+ operand.IsValid()) ||
+ (std::tie(operand, iter) = ParseARMOffsetAccess(osi, ose),
+ operand.IsValid()) ||
+ (std::tie(operand, iter) = ParseARMDerefAccess(osi, ose),
+ operand.IsValid()) ||
+ (std::tie(operand, iter) = ParseRegisterName(osi, ose),
+ operand.IsValid()) ||
+ (std::tie(operand, iter) = ParseImmediate(osi, ose),
+ operand.IsValid())) {
+ osi = iter;
+ operands.push_back(operand);
+ } else {
+ return false;
+ }
+
+ std::pair<bool, llvm::StringRef::const_iterator> found_and_iter =
+ ConsumeChar(osi, ',', ose);
+ if (found_and_iter.first) {
+ osi = found_and_iter.second;
+ }
+
+ osi = ConsumeWhitespace(osi, ose);
+ }
+
+ DisassemblerSP disasm_sp = m_disasm_wp.lock();
+
+ if (disasm_sp && operands.size() > 1) {
+ // TODO tie this into the MC Disassembler's notion of clobbers.
+ switch (disasm_sp->GetArchitecture().GetMachine()) {
+ default:
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ operands[operands.size() - 1].m_clobbered = true;
+ break;
+ case llvm::Triple::arm:
+ operands[0].m_clobbered = true;
+ break;
+ }
+ }
- m_instr_printer_ap.reset(curr_target->createMCInstPrinter(llvm::Triple{triple},
- asm_printer_variant,
- *m_asm_info_ap.get(),
- *m_instr_info_ap.get(),
- *m_reg_info_ap.get()));
- if (m_instr_printer_ap.get() == NULL)
- {
- m_disasm_ap.reset();
- m_is_valid = false;
+ if (Log *log =
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)) {
+ StreamString ss;
+
+ ss.Printf("[%s] expands to %zu operands:\n", operands_string,
+ operands.size());
+ for (const Operand &operand : operands) {
+ ss.PutCString(" ");
+ DumpOperand(operand, ss);
+ ss.PutCString("\n");
+ }
+
+ log->PutString(ss.GetString());
+ }
+
+ return true;
+ }
+
+ bool IsCall() override {
+ if (m_is_call == eLazyBoolCalculate) {
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp) {
+ disasm_sp->Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data)) {
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr =
+ GetDisasmToUse(is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size =
+ mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
+ if (inst_size == 0) {
+ m_is_call = eLazyBoolNo;
+ } else {
+ if (mc_disasm_ptr->IsCall(inst))
+ m_is_call = eLazyBoolYes;
+ else
+ m_is_call = eLazyBoolNo;
+ }
}
+ disasm_sp->Unlock();
+ }
}
- else
- m_is_valid = false;
+ return m_is_call == eLazyBoolYes;
+ }
+
+protected:
+ std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;
+ LazyBool m_does_branch;
+ LazyBool m_has_delay_slot;
+ LazyBool m_is_call;
+ bool m_is_valid;
+ bool m_using_file_addr;
+};
+
+DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler(
+ const char *triple, const char *cpu, const char *features_str,
+ unsigned flavor, DisassemblerLLVMC &owner)
+ : m_is_valid(true) {
+ std::string Error;
+ const llvm::Target *curr_target =
+ llvm::TargetRegistry::lookupTarget(triple, Error);
+ if (!curr_target) {
+ m_is_valid = false;
+ return;
+ }
+
+ m_instr_info_ap.reset(curr_target->createMCInstrInfo());
+ m_reg_info_ap.reset(curr_target->createMCRegInfo(triple));
+
+ m_subtarget_info_ap.reset(
+ curr_target->createMCSubtargetInfo(triple, cpu, features_str));
+
+ std::unique_ptr<llvm::MCRegisterInfo> reg_info(
+ curr_target->createMCRegInfo(triple));
+ m_asm_info_ap.reset(curr_target->createMCAsmInfo(*reg_info, triple));
+
+ if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL ||
+ m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL) {
+ m_is_valid = false;
+ return;
+ }
+
+ m_context_ap.reset(
+ new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));
+
+ m_disasm_ap.reset(curr_target->createMCDisassembler(
+ *m_subtarget_info_ap.get(), *m_context_ap.get()));
+ if (m_disasm_ap.get() && m_context_ap.get()) {
+ std::unique_ptr<llvm::MCRelocationInfo> RelInfo(
+ curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
+ if (!RelInfo) {
+ m_is_valid = false;
+ return;
+ }
+ std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(
+ curr_target->createMCSymbolizer(
+ triple, NULL, DisassemblerLLVMC::SymbolLookupCallback,
+ (void *)&owner, m_context_ap.get(), std::move(RelInfo)));
+ m_disasm_ap->setSymbolizer(std::move(symbolizer_up));
+
+ unsigned asm_printer_variant;
+ if (flavor == ~0U)
+ asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
+ else {
+ asm_printer_variant = flavor;
+ }
+
+ m_instr_printer_ap.reset(curr_target->createMCInstPrinter(
+ llvm::Triple{triple}, asm_printer_variant, *m_asm_info_ap.get(),
+ *m_instr_info_ap.get(), *m_reg_info_ap.get()));
+ if (m_instr_printer_ap.get() == NULL) {
+ m_disasm_ap.reset();
+ m_is_valid = false;
+ }
+ } else
+ m_is_valid = false;
}
DisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler() = default;
-uint64_t
-DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
- size_t opcode_data_len,
- lldb::addr_t pc,
- llvm::MCInst &mc_inst)
-{
- llvm::ArrayRef<uint8_t> data(opcode_data, opcode_data_len);
- llvm::MCDisassembler::DecodeStatus status;
-
- uint64_t new_inst_size;
- status = m_disasm_ap->getInstruction(mc_inst,
- new_inst_size,
- data,
- pc,
- llvm::nulls(),
- llvm::nulls());
- if (status == llvm::MCDisassembler::Success)
- return new_inst_size;
- else
- return 0;
+uint64_t DisassemblerLLVMC::LLVMCDisassembler::GetMCInst(
+ const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc,
+ llvm::MCInst &mc_inst) {
+ llvm::ArrayRef<uint8_t> data(opcode_data, opcode_data_len);
+ llvm::MCDisassembler::DecodeStatus status;
+
+ uint64_t new_inst_size;
+ status = m_disasm_ap->getInstruction(mc_inst, new_inst_size, data, pc,
+ llvm::nulls(), llvm::nulls());
+ if (status == llvm::MCDisassembler::Success)
+ return new_inst_size;
+ else
+ return 0;
}
-void
-DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst,
- std::string &inst_string,
- std::string &comments_string)
-{
- llvm::raw_string_ostream inst_stream(inst_string);
- llvm::raw_string_ostream comments_stream(comments_string);
-
- m_instr_printer_ap->setCommentStream(comments_stream);
- m_instr_printer_ap->printInst (&mc_inst, inst_stream, llvm::StringRef(), *m_subtarget_info_ap);
- m_instr_printer_ap->setCommentStream(llvm::nulls());
- comments_stream.flush();
-
- static std::string g_newlines("\r\n");
-
- for (size_t newline_pos = 0; (newline_pos = comments_string.find_first_of(g_newlines, newline_pos)) != comments_string.npos; /**/)
- {
- comments_string.replace(comments_string.begin() + newline_pos, comments_string.begin() + newline_pos + 1, 1, ' ');
- }
+void DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst(
+ llvm::MCInst &mc_inst, std::string &inst_string,
+ std::string &comments_string) {
+ llvm::raw_string_ostream inst_stream(inst_string);
+ llvm::raw_string_ostream comments_stream(comments_string);
+
+ m_instr_printer_ap->setCommentStream(comments_stream);
+ m_instr_printer_ap->printInst(&mc_inst, inst_stream, llvm::StringRef(),
+ *m_subtarget_info_ap);
+ m_instr_printer_ap->setCommentStream(llvm::nulls());
+ comments_stream.flush();
+
+ static std::string g_newlines("\r\n");
+
+ for (size_t newline_pos = 0;
+ (newline_pos = comments_string.find_first_of(g_newlines, newline_pos)) !=
+ comments_string.npos;
+ /**/) {
+ comments_string.replace(comments_string.begin() + newline_pos,
+ comments_string.begin() + newline_pos + 1, 1, ' ');
+ }
}
-void
-DisassemblerLLVMC::LLVMCDisassembler::SetStyle (bool use_hex_immed, HexImmediateStyle hex_style)
-{
- m_instr_printer_ap->setPrintImmHex(use_hex_immed);
- switch(hex_style)
- {
- case eHexStyleC: m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::C); break;
- case eHexStyleAsm: m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::Asm); break;
- }
+void DisassemblerLLVMC::LLVMCDisassembler::SetStyle(
+ bool use_hex_immed, HexImmediateStyle hex_style) {
+ m_instr_printer_ap->setPrintImmHex(use_hex_immed);
+ switch (hex_style) {
+ case eHexStyleC:
+ m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::C);
+ break;
+ case eHexStyleAsm:
+ m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::Asm);
+ break;
+ }
}
-bool
-DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
-{
- return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
+bool DisassemblerLLVMC::LLVMCDisassembler::CanBranch(llvm::MCInst &mc_inst) {
+ return m_instr_info_ap->get(mc_inst.getOpcode())
+ .mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
}
-bool
-DisassemblerLLVMC::LLVMCDisassembler::HasDelaySlot (llvm::MCInst &mc_inst)
-{
- return m_instr_info_ap->get(mc_inst.getOpcode()).hasDelaySlot();
+bool DisassemblerLLVMC::LLVMCDisassembler::HasDelaySlot(llvm::MCInst &mc_inst) {
+ return m_instr_info_ap->get(mc_inst.getOpcode()).hasDelaySlot();
}
-DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
- Disassembler(arch, flavor_string),
- m_exe_ctx (NULL),
- m_inst (NULL),
- m_data_from_file (false)
-{
- if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
- {
- m_flavor.assign("default");
- }
-
- unsigned flavor = ~0U;
- llvm::Triple triple = arch.GetTriple();
-
- // So far the only supported flavor is "intel" on x86. The base class will set this
- // correctly coming in.
- if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
- {
- if (m_flavor == "intel")
- {
- flavor = 1;
- }
- else if (m_flavor == "att")
- {
- flavor = 0;
- }
- }
+bool DisassemblerLLVMC::LLVMCDisassembler::IsCall(llvm::MCInst &mc_inst) {
+ return m_instr_info_ap->get(mc_inst.getOpcode()).isCall();
+}
- ArchSpec thumb_arch(arch);
- if (triple.getArch() == llvm::Triple::arm)
- {
- std::string thumb_arch_name (thumb_arch.GetTriple().getArchName().str());
- // Replace "arm" with "thumb" so we get all thumb variants correct
- if (thumb_arch_name.size() > 3)
- {
- thumb_arch_name.erase(0,3);
- thumb_arch_name.insert(0, "thumb");
- }
- else
- {
- thumb_arch_name = "thumbv8.2a";
- }
- thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
- }
-
- // If no sub architecture specified then use the most recent arm architecture so the
- // disassembler will return all instruction. Without it we will see a lot of unknow opcode
- // in case the code uses instructions which are not available in the oldest arm version
- // (used when no sub architecture is specified)
- if (triple.getArch() == llvm::Triple::arm && triple.getSubArch() == llvm::Triple::NoSubArch)
- triple.setArchName("armv8.2a");
-
- 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();
- }
-
- const char *cpu = "";
-
- switch (arch.GetCore())
- {
- case ArchSpec::eCore_mips32:
- case ArchSpec::eCore_mips32el:
- cpu = "mips32"; break;
- case ArchSpec::eCore_mips32r2:
- case ArchSpec::eCore_mips32r2el:
- cpu = "mips32r2"; break;
- case ArchSpec::eCore_mips32r3:
- case ArchSpec::eCore_mips32r3el:
- cpu = "mips32r3"; break;
- case ArchSpec::eCore_mips32r5:
- case ArchSpec::eCore_mips32r5el:
- cpu = "mips32r5"; break;
- case ArchSpec::eCore_mips32r6:
- case ArchSpec::eCore_mips32r6el:
- cpu = "mips32r6"; break;
- case ArchSpec::eCore_mips64:
- case ArchSpec::eCore_mips64el:
- cpu = "mips64"; break;
- case ArchSpec::eCore_mips64r2:
- case ArchSpec::eCore_mips64r2el:
- cpu = "mips64r2"; break;
- case ArchSpec::eCore_mips64r3:
- case ArchSpec::eCore_mips64r3el:
- cpu = "mips64r3"; break;
- case ArchSpec::eCore_mips64r5:
- case ArchSpec::eCore_mips64r5el:
- cpu = "mips64r5"; break;
- case ArchSpec::eCore_mips64r6:
- case ArchSpec::eCore_mips64r6el:
- cpu = "mips64r6"; break;
- default:
- cpu = ""; break;
- }
-
- std::string features_str = "";
- if (triple.getArch() == llvm::Triple::mips || triple.getArch() == llvm::Triple::mipsel
- || triple.getArch() == llvm::Triple::mips64 || triple.getArch() == llvm::Triple::mips64el)
- {
- uint32_t arch_flags = arch.GetFlags ();
- if (arch_flags & ArchSpec::eMIPSAse_msa)
- features_str += "+msa,";
- if (arch_flags & ArchSpec::eMIPSAse_dsp)
- features_str += "+dsp,";
- if (arch_flags & ArchSpec::eMIPSAse_dspr2)
- features_str += "+dspr2,";
- }
-
- m_disasm_ap.reset (new LLVMCDisassembler(triple_str, cpu, features_str.c_str(), flavor, *this));
- if (!m_disasm_ap->IsValid())
- {
- // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
- // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
- m_disasm_ap.reset();
- }
-
- llvm::Triple::ArchType llvm_arch = triple.getArch();
-
- // For arm CPUs that can execute arm or thumb instructions, also create a thumb instruction disassembler.
- if (llvm_arch == llvm::Triple::arm)
- {
- std::string thumb_triple(thumb_arch.GetTriple().getTriple());
- m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), "", "", flavor, *this));
- if (!m_alternate_disasm_ap->IsValid())
- {
- m_disasm_ap.reset();
- m_alternate_disasm_ap.reset();
- }
+DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
+ const char *flavor_string)
+ : Disassembler(arch, flavor_string), m_exe_ctx(NULL), m_inst(NULL),
+ m_data_from_file(false) {
+ if (!FlavorValidForArchSpec(arch, m_flavor.c_str())) {
+ m_flavor.assign("default");
+ }
+
+ unsigned flavor = ~0U;
+ llvm::Triple triple = arch.GetTriple();
+
+ // So far the only supported flavor is "intel" on x86. The base class will
+ // set this
+ // correctly coming in.
+ if (triple.getArch() == llvm::Triple::x86 ||
+ triple.getArch() == llvm::Triple::x86_64) {
+ if (m_flavor == "intel") {
+ flavor = 1;
+ } else if (m_flavor == "att") {
+ flavor = 0;
}
- else if (llvm_arch == llvm::Triple::mips
- || llvm_arch == llvm::Triple::mipsel
- || llvm_arch == llvm::Triple::mips64
- || llvm_arch == llvm::Triple::mips64el)
- {
- /* Create alternate disassembler for MIPS16 and microMIPS */
- uint32_t arch_flags = arch.GetFlags ();
- if (arch_flags & ArchSpec::eMIPSAse_mips16)
- features_str += "+mips16,";
- else if (arch_flags & ArchSpec::eMIPSAse_micromips)
- features_str += "+micromips,";
-
- m_alternate_disasm_ap.reset(new LLVMCDisassembler (triple_str, cpu, features_str.c_str(), flavor, *this));
- if (!m_alternate_disasm_ap->IsValid())
- {
- m_disasm_ap.reset();
- m_alternate_disasm_ap.reset();
- }
+ }
+
+ ArchSpec thumb_arch(arch);
+ if (triple.getArch() == llvm::Triple::arm) {
+ std::string thumb_arch_name(thumb_arch.GetTriple().getArchName().str());
+ // Replace "arm" with "thumb" so we get all thumb variants correct
+ if (thumb_arch_name.size() > 3) {
+ thumb_arch_name.erase(0, 3);
+ thumb_arch_name.insert(0, "thumb");
+ } else {
+ thumb_arch_name = "thumbv8.2a";
+ }
+ thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name));
+ }
+
+ // If no sub architecture specified then use the most recent arm architecture
+ // so the
+ // disassembler will return all instruction. Without it we will see a lot of
+ // unknow opcode
+ // in case the code uses instructions which are not available in the oldest
+ // arm version
+ // (used when no sub architecture is specified)
+ if (triple.getArch() == llvm::Triple::arm &&
+ triple.getSubArch() == llvm::Triple::NoSubArch)
+ triple.setArchName("armv8.2a");
+
+ 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();
+ }
+
+ const char *cpu = "";
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_mips32:
+ case ArchSpec::eCore_mips32el:
+ cpu = "mips32";
+ break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r2el:
+ cpu = "mips32r2";
+ break;
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r3el:
+ cpu = "mips32r3";
+ break;
+ case ArchSpec::eCore_mips32r5:
+ case ArchSpec::eCore_mips32r5el:
+ cpu = "mips32r5";
+ break;
+ case ArchSpec::eCore_mips32r6:
+ case ArchSpec::eCore_mips32r6el:
+ cpu = "mips32r6";
+ break;
+ case ArchSpec::eCore_mips64:
+ case ArchSpec::eCore_mips64el:
+ cpu = "mips64";
+ break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r2el:
+ cpu = "mips64r2";
+ break;
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r3el:
+ cpu = "mips64r3";
+ break;
+ case ArchSpec::eCore_mips64r5:
+ case ArchSpec::eCore_mips64r5el:
+ cpu = "mips64r5";
+ break;
+ case ArchSpec::eCore_mips64r6:
+ case ArchSpec::eCore_mips64r6el:
+ cpu = "mips64r6";
+ break;
+ default:
+ cpu = "";
+ break;
+ }
+
+ std::string features_str = "";
+ if (triple.getArch() == llvm::Triple::mips ||
+ triple.getArch() == llvm::Triple::mipsel ||
+ triple.getArch() == llvm::Triple::mips64 ||
+ triple.getArch() == llvm::Triple::mips64el) {
+ uint32_t arch_flags = arch.GetFlags();
+ if (arch_flags & ArchSpec::eMIPSAse_msa)
+ features_str += "+msa,";
+ if (arch_flags & ArchSpec::eMIPSAse_dsp)
+ features_str += "+dsp,";
+ if (arch_flags & ArchSpec::eMIPSAse_dspr2)
+ features_str += "+dspr2,";
+ }
+
+ m_disasm_ap.reset(new LLVMCDisassembler(triple_str, cpu, features_str.c_str(),
+ flavor, *this));
+ if (!m_disasm_ap->IsValid()) {
+ // We use m_disasm_ap.get() to tell whether we are valid or not, so if this
+ // isn't good for some reason,
+ // we reset it, and then we won't be valid and FindPlugin will fail and we
+ // won't get used.
+ m_disasm_ap.reset();
+ }
+
+ llvm::Triple::ArchType llvm_arch = triple.getArch();
+
+ // For arm CPUs that can execute arm or thumb instructions, also create a
+ // thumb instruction disassembler.
+ if (llvm_arch == llvm::Triple::arm) {
+ std::string thumb_triple(thumb_arch.GetTriple().getTriple());
+ m_alternate_disasm_ap.reset(
+ new LLVMCDisassembler(thumb_triple.c_str(), "", "", flavor, *this));
+ if (!m_alternate_disasm_ap->IsValid()) {
+ m_disasm_ap.reset();
+ m_alternate_disasm_ap.reset();
+ }
+ } else if (llvm_arch == llvm::Triple::mips ||
+ llvm_arch == llvm::Triple::mipsel ||
+ llvm_arch == llvm::Triple::mips64 ||
+ llvm_arch == llvm::Triple::mips64el) {
+ /* Create alternate disassembler for MIPS16 and microMIPS */
+ uint32_t arch_flags = arch.GetFlags();
+ if (arch_flags & ArchSpec::eMIPSAse_mips16)
+ features_str += "+mips16,";
+ else if (arch_flags & ArchSpec::eMIPSAse_micromips)
+ features_str += "+micromips,";
+
+ m_alternate_disasm_ap.reset(new LLVMCDisassembler(
+ triple_str, cpu, features_str.c_str(), flavor, *this));
+ if (!m_alternate_disasm_ap->IsValid()) {
+ m_disasm_ap.reset();
+ m_alternate_disasm_ap.reset();
}
+ }
}
DisassemblerLLVMC::~DisassemblerLLVMC() = default;
-Disassembler *
-DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
-{
- if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
- {
- std::unique_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
+Disassembler *DisassemblerLLVMC::CreateInstance(const ArchSpec &arch,
+ const char *flavor) {
+ if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) {
+ std::unique_ptr<DisassemblerLLVMC> disasm_ap(
+ new DisassemblerLLVMC(arch, flavor));
- if (disasm_ap.get() && disasm_ap->IsValid())
- return disasm_ap.release();
- }
- return NULL;
+ if (disasm_ap.get() && disasm_ap->IsValid())
+ return disasm_ap.release();
+ }
+ return NULL;
}
-size_t
-DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
- const DataExtractor& data,
- lldb::offset_t data_offset,
- size_t num_instructions,
- bool append,
- bool data_from_file)
-{
- if (!append)
- m_instruction_list.Clear();
+size_t DisassemblerLLVMC::DecodeInstructions(const Address &base_addr,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t num_instructions,
+ bool append, bool data_from_file) {
+ if (!append)
+ m_instruction_list.Clear();
- if (!IsValid())
- return 0;
+ if (!IsValid())
+ return 0;
- m_data_from_file = data_from_file;
- uint32_t data_cursor = data_offset;
- const size_t data_byte_size = data.GetByteSize();
- uint32_t instructions_parsed = 0;
- Address inst_addr(base_addr);
+ m_data_from_file = data_from_file;
+ uint32_t data_cursor = data_offset;
+ const size_t data_byte_size = data.GetByteSize();
+ uint32_t instructions_parsed = 0;
+ Address inst_addr(base_addr);
- while (data_cursor < data_byte_size && instructions_parsed < num_instructions)
- {
+ while (data_cursor < data_byte_size &&
+ instructions_parsed < num_instructions) {
- AddressClass address_class = eAddressClassCode;
+ AddressClass address_class = eAddressClassCode;
- if (m_alternate_disasm_ap.get() != NULL)
- address_class = inst_addr.GetAddressClass ();
+ if (m_alternate_disasm_ap.get() != NULL)
+ address_class = inst_addr.GetAddressClass();
- InstructionSP inst_sp(new InstructionLLVMC(*this,
- inst_addr,
- address_class));
+ InstructionSP inst_sp(
+ new InstructionLLVMC(*this, inst_addr, address_class));
- if (!inst_sp)
- break;
+ if (!inst_sp)
+ break;
- uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
+ uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
- if (inst_size == 0)
- break;
+ if (inst_size == 0)
+ break;
- m_instruction_list.Append(inst_sp);
- data_cursor += inst_size;
- inst_addr.Slide(inst_size);
- instructions_parsed++;
- }
+ m_instruction_list.Append(inst_sp);
+ data_cursor += inst_size;
+ inst_addr.Slide(inst_size);
+ instructions_parsed++;
+ }
- return data_cursor - data_offset;
+ return data_cursor - data_offset;
}
-void
-DisassemblerLLVMC::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Disassembler that uses LLVM MC to disassemble i386, x86_64, ARM, and ARM64.",
- CreateInstance);
-
- llvm::InitializeAllTargetInfos();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllAsmParsers();
- llvm::InitializeAllDisassemblers();
-}
+void DisassemblerLLVMC::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "Disassembler that uses LLVM MC to disassemble "
+ "i386, x86_64, ARM, and ARM64.",
+ CreateInstance);
-void
-DisassemblerLLVMC::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllDisassemblers();
}
+void DisassemblerLLVMC::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
-ConstString
-DisassemblerLLVMC::GetPluginNameStatic()
-{
- static ConstString g_name("llvm-mc");
- return g_name;
+ConstString DisassemblerLLVMC::GetPluginNameStatic() {
+ static ConstString g_name("llvm-mc");
+ return g_name;
}
-int DisassemblerLLVMC::OpInfoCallback (void *disassembler,
- uint64_t pc,
- uint64_t offset,
- uint64_t size,
- int tag_type,
- void *tag_bug)
-{
- return static_cast<DisassemblerLLVMC*>(disassembler)->OpInfo (pc,
- offset,
- size,
- tag_type,
- tag_bug);
+int DisassemblerLLVMC::OpInfoCallback(void *disassembler, uint64_t pc,
+ uint64_t offset, uint64_t size,
+ int tag_type, void *tag_bug) {
+ return static_cast<DisassemblerLLVMC *>(disassembler)
+ ->OpInfo(pc, offset, size, tag_type, tag_bug);
}
-const char *DisassemblerLLVMC::SymbolLookupCallback (void *disassembler,
- uint64_t value,
- uint64_t *type,
- uint64_t pc,
- const char **name)
-{
- return static_cast<DisassemblerLLVMC*>(disassembler)->SymbolLookup(value,
- type,
- pc,
- name);
+const char *DisassemblerLLVMC::SymbolLookupCallback(void *disassembler,
+ uint64_t value,
+ uint64_t *type, uint64_t pc,
+ const char **name) {
+ return static_cast<DisassemblerLLVMC *>(disassembler)
+ ->SymbolLookup(value, type, pc, name);
}
-bool
-DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
-{
- llvm::Triple triple = arch.GetTriple();
- if (flavor == NULL || strcmp (flavor, "default") == 0)
- return true;
-
- 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;
- }
+bool DisassemblerLLVMC::FlavorValidForArchSpec(
+ const lldb_private::ArchSpec &arch, const char *flavor) {
+ llvm::Triple triple = arch.GetTriple();
+ if (flavor == NULL || strcmp(flavor, "default") == 0)
+ return true;
+
+ 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 false;
+ } else
+ return false;
}
-int DisassemblerLLVMC::OpInfo (uint64_t PC,
- uint64_t Offset,
- uint64_t Size,
- int tag_type,
- void *tag_bug)
-{
- switch (tag_type)
- {
- default:
- break;
- case 1:
- memset (tag_bug, 0, sizeof(::LLVMOpInfo1));
- break;
- }
- return 0;
+int DisassemblerLLVMC::OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size,
+ int tag_type, void *tag_bug) {
+ switch (tag_type) {
+ default:
+ break;
+ case 1:
+ memset(tag_bug, 0, sizeof(::LLVMOpInfo1));
+ break;
+ }
+ return 0;
}
-const char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
- uint64_t *type_ptr,
- uint64_t pc,
- const char **name)
-{
- if (*type_ptr)
- {
- if (m_exe_ctx && m_inst)
- {
- //std::string remove_this_prior_to_checkin;
- Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
- Address value_so_addr;
- Address pc_so_addr;
- if (m_inst->UsingFileAddress())
- {
- ModuleSP module_sp(m_inst->GetAddress().GetModule());
- if (module_sp)
- {
- module_sp->ResolveFileAddress(value, value_so_addr);
- module_sp->ResolveFileAddress(pc, pc_so_addr);
- }
- }
- else if (target && !target->GetSectionLoadList().IsEmpty())
- {
- target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
- target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr);
- }
+const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr,
+ uint64_t pc, const char **name) {
+ if (*type_ptr) {
+ if (m_exe_ctx && m_inst) {
+ // std::string remove_this_prior_to_checkin;
+ Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
+ Address value_so_addr;
+ Address pc_so_addr;
+ if (m_inst->UsingFileAddress()) {
+ ModuleSP module_sp(m_inst->GetAddress().GetModule());
+ if (module_sp) {
+ module_sp->ResolveFileAddress(value, value_so_addr);
+ module_sp->ResolveFileAddress(pc, pc_so_addr);
+ }
+ } else if (target && !target->GetSectionLoadList().IsEmpty()) {
+ target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
+ target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr);
+ }
+
+ SymbolContext sym_ctx;
+ const uint32_t resolve_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+ if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) {
+ pc_so_addr.GetModule()->ResolveSymbolContextForAddress(
+ pc_so_addr, resolve_scope, sym_ctx);
+ }
+
+ if (value_so_addr.IsValid() && value_so_addr.GetSection()) {
+ StreamString ss;
+
+ bool format_omitting_current_func_name = false;
+ if (sym_ctx.symbol || sym_ctx.function) {
+ AddressRange range;
+ if (sym_ctx.GetAddressRange(resolve_scope, 0, false, range) &&
+ range.GetBaseAddress().IsValid() &&
+ range.ContainsLoadAddress(value_so_addr, target)) {
+ format_omitting_current_func_name = true;
+ }
+ }
- SymbolContext sym_ctx;
- const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
- if (pc_so_addr.IsValid() && pc_so_addr.GetModule())
- {
- pc_so_addr.GetModule()->ResolveSymbolContextForAddress (pc_so_addr, resolve_scope, sym_ctx);
- }
+ // If the "value" address (the target address we're symbolicating)
+ // is inside the same SymbolContext as the current instruction pc
+ // (pc_so_addr), don't print the full function name - just print it
+ // with DumpStyleNoFunctionName style, e.g. "<+36>".
+ if (format_omitting_current_func_name) {
+ value_so_addr.Dump(&ss, target, Address::DumpStyleNoFunctionName,
+ Address::DumpStyleSectionNameOffset);
+ } else {
+ value_so_addr.Dump(
+ &ss, target,
+ Address::DumpStyleResolvedDescriptionNoFunctionArguments,
+ Address::DumpStyleSectionNameOffset);
+ }
- if (value_so_addr.IsValid() && value_so_addr.GetSection())
- {
- StreamString ss;
-
- bool format_omitting_current_func_name = false;
- if (sym_ctx.symbol || sym_ctx.function)
- {
- AddressRange range;
- if (sym_ctx.GetAddressRange (resolve_scope, 0, false, range)
- && range.GetBaseAddress().IsValid()
- && range.ContainsLoadAddress (value_so_addr, target))
- {
- format_omitting_current_func_name = true;
- }
- }
-
- // If the "value" address (the target address we're symbolicating)
- // is inside the same SymbolContext as the current instruction pc
- // (pc_so_addr), don't print the full function name - just print it
- // with DumpStyleNoFunctionName style, e.g. "<+36>".
- if (format_omitting_current_func_name)
- {
- value_so_addr.Dump (&ss,
- target,
- Address::DumpStyleNoFunctionName,
- Address::DumpStyleSectionNameOffset);
- }
- else
- {
- value_so_addr.Dump (&ss,
- target,
- Address::DumpStyleResolvedDescriptionNoFunctionArguments,
- Address::DumpStyleSectionNameOffset);
- }
-
- if (!ss.GetString().empty())
- {
- // If Address::Dump returned a multi-line description, most commonly seen when we
- // have multiple levels of inlined functions at an address, only show the first line.
- std::string &str(ss.GetString());
- size_t first_eol_char = str.find_first_of ("\r\n");
- if (first_eol_char != std::string::npos)
- {
- str.erase (first_eol_char);
- }
- m_inst->AppendComment(ss.GetString());
- }
- }
+ if (!ss.GetString().empty()) {
+ // If Address::Dump returned a multi-line description, most commonly
+ // seen when we
+ // have multiple levels of inlined functions at an address, only show
+ // the first line.
+ std::string str = ss.GetString();
+ size_t first_eol_char = str.find_first_of("\r\n");
+ if (first_eol_char != std::string::npos) {
+ str.erase(first_eol_char);
+ }
+ m_inst->AppendComment(str);
}
+ }
}
+ }
- *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
- *name = NULL;
- return NULL;
+ *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
+ *name = NULL;
+ return NULL;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-DisassemblerLLVMC::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+ConstString DisassemblerLLVMC::GetPluginName() { return GetPluginNameStatic(); }
-uint32_t
-DisassemblerLLVMC::GetPluginVersion()
-{
- return 1;
-}
+uint32_t DisassemblerLLVMC::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
index e8f09a4d3abb..26bed7ee0d7b 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
@@ -25,147 +25,128 @@
#include "lldb/Core/PluginManager.h"
// Opaque references to C++ Objects in LLVM's MC.
-namespace llvm
-{
- class MCContext;
- class MCInst;
- class MCInstrInfo;
- class MCRegisterInfo;
- class MCDisassembler;
- class MCInstPrinter;
- class MCAsmInfo;
- class MCSubtargetInfo;
+namespace llvm {
+class MCContext;
+class MCInst;
+class MCInstrInfo;
+class MCRegisterInfo;
+class MCDisassembler;
+class MCInstPrinter;
+class MCAsmInfo;
+class MCSubtargetInfo;
} // namespace llvm
class InstructionLLVMC;
-class DisassemblerLLVMC : public lldb_private::Disassembler
-{
- // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), and there's a bit of goo to set up and own
- // in the MC disassembler world, I added this class to manage the actual disassemblers.
- class LLVMCDisassembler
- {
- public:
- LLVMCDisassembler (const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner);
-
- ~LLVMCDisassembler();
-
- uint64_t GetMCInst (const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
- void PrintMCInst (llvm::MCInst &mc_inst, std::string &inst_string, std::string &comments_string);
- void SetStyle (bool use_hex_immed, HexImmediateStyle hex_style);
- bool CanBranch (llvm::MCInst &mc_inst);
- bool HasDelaySlot (llvm::MCInst &mc_inst);
- bool IsValid()
- {
- return m_is_valid;
- }
-
- private:
- bool m_is_valid;
- std::unique_ptr<llvm::MCContext> m_context_ap;
- std::unique_ptr<llvm::MCAsmInfo> m_asm_info_ap;
- std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
- std::unique_ptr<llvm::MCInstrInfo> m_instr_info_ap;
- std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
- std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
- std::unique_ptr<llvm::MCDisassembler> m_disasm_ap;
- };
+class DisassemblerLLVMC : public lldb_private::Disassembler {
+ // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB),
+ // and there's a bit of goo to set up and own
+ // in the MC disassembler world, I added this class to manage the actual
+ // disassemblers.
+ class LLVMCDisassembler {
+ public:
+ LLVMCDisassembler(const char *triple, const char *cpu,
+ const char *features_str, unsigned flavor,
+ DisassemblerLLVMC &owner);
+
+ ~LLVMCDisassembler();
+
+ uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len,
+ lldb::addr_t pc, llvm::MCInst &mc_inst);
+ void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string,
+ std::string &comments_string);
+ void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style);
+ bool CanBranch(llvm::MCInst &mc_inst);
+ bool HasDelaySlot(llvm::MCInst &mc_inst);
+ bool IsCall(llvm::MCInst &mc_inst);
+ bool IsValid() { return m_is_valid; }
+
+ private:
+ bool m_is_valid;
+ std::unique_ptr<llvm::MCContext> m_context_ap;
+ std::unique_ptr<llvm::MCAsmInfo> m_asm_info_ap;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
+ std::unique_ptr<llvm::MCInstrInfo> m_instr_info_ap;
+ std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
+ std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
+ std::unique_ptr<llvm::MCDisassembler> m_disasm_ap;
+ };
public:
- DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
+ DisassemblerLLVMC(const lldb_private::ArchSpec &arch,
+ const char *flavor /* = NULL */);
- ~DisassemblerLLVMC() override;
+ ~DisassemblerLLVMC() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static lldb_private::Disassembler *
- CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
+ static lldb_private::Disassembler *
+ CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
- size_t
- DecodeInstructions(const lldb_private::Address &base_addr,
- const lldb_private::DataExtractor& data,
- lldb::offset_t data_offset,
- size_t num_instructions,
- bool append,
- bool data_from_file) override;
+ size_t DecodeInstructions(const lldb_private::Address &base_addr,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t data_offset, size_t num_instructions,
+ bool append, bool data_from_file) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- friend class InstructionLLVMC;
-
- bool
- FlavorValidForArchSpec(const lldb_private::ArchSpec &arch, const char *flavor) override;
-
- bool
- IsValid()
- {
- return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
- }
-
- int OpInfo(uint64_t PC,
- uint64_t Offset,
- uint64_t Size,
- int TagType,
- void *TagBug);
-
- const char *SymbolLookup (uint64_t ReferenceValue,
- uint64_t *ReferenceType,
- uint64_t ReferencePC,
- const char **ReferenceName);
-
- static int OpInfoCallback (void *DisInfo,
- uint64_t PC,
- uint64_t Offset,
- uint64_t Size,
- int TagType,
- void *TagBug);
-
- static const char *SymbolLookupCallback(void *DisInfo,
- uint64_t ReferenceValue,
- uint64_t *ReferenceType,
- 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;
- bool m_data_from_file;
-
- std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
- std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
+ friend class InstructionLLVMC;
+
+ bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch,
+ const char *flavor) override;
+
+ bool IsValid() {
+ return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
+ }
+
+ int OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, int TagType,
+ void *TagBug);
+
+ const char *SymbolLookup(uint64_t ReferenceValue, uint64_t *ReferenceType,
+ uint64_t ReferencePC, const char **ReferenceName);
+
+ static int OpInfoCallback(void *DisInfo, uint64_t PC, uint64_t Offset,
+ uint64_t Size, int TagType, void *TagBug);
+
+ static const char *SymbolLookupCallback(void *DisInfo,
+ uint64_t ReferenceValue,
+ uint64_t *ReferenceType,
+ 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;
+ bool m_data_from_file;
+
+ std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
+ std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
};
#endif // liblldb_DisassemblerLLVM_h_
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 4021b44c96a9..b7010303bcaa 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -1,4 +1,5 @@
-//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++ -*-===//
+//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +10,7 @@
#include "lldb/Utility/SafeMachO.h"
+#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -28,14 +30,13 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "DynamicLoaderDarwinKernel.h"
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif
@@ -44,89 +45,79 @@ using namespace lldb;
using namespace lldb_private;
// Progressively greater amounts of scanning we will allow
-// For some targets very early in startup, we can't do any random reads of memory or we can crash the device
+// For some targets very early in startup, we can't do any random reads of
+// memory or we can crash the device
// so a setting is needed that can completely disable the KASLR scans.
-enum KASLRScanType
-{
- eKASLRScanNone = 0, // No reading into the inferior at all
- eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel addr, then see if a kernel is there
- eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel; checking at 96 locations total
- eKASLRScanExhaustiveScan // Scan through the entire possible kernel address range looking for a kernel
-};
-
-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 addr in the lowglo page (boot-args=debug) only." },
- { eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find 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 }
-};
-
-static PropertyDefinition
-g_properties[] =
-{
- { "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, 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 }
-};
-
-enum {
- ePropertyLoadKexts,
- ePropertyScanType
+enum KASLRScanType {
+ eKASLRScanNone = 0, // No reading into the inferior at all
+ eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel
+ // addr, then see if a kernel is there
+ eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel;
+ // checking at 96 locations total
+ eKASLRScanExhaustiveScan // Scan through the entire possible kernel address
+ // range looking for a kernel
};
-class DynamicLoaderDarwinKernelProperties : public Properties
-{
+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 "
+ "addr in the lowglo page "
+ "(boot-args=debug) only."},
+ {eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find "
+ "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}};
+
+static PropertyDefinition g_properties[] = {
+ {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, 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}};
+
+enum { ePropertyLoadKexts, ePropertyScanType };
+
+class DynamicLoaderDarwinKernelProperties : public Properties {
public:
-
- static ConstString &
- GetSettingName ()
- {
- static ConstString g_setting_name("darwin-kernel");
- return g_setting_name;
- }
-
- DynamicLoaderDarwinKernelProperties() :
- Properties ()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual
- ~DynamicLoaderDarwinKernelProperties()
- {
- }
-
- bool
- GetLoadKexts() const
- {
- const uint32_t idx = ePropertyLoadKexts;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
- }
-
- KASLRScanType
- GetScanType() const
- {
- const uint32_t idx = ePropertyScanType;
- return (KASLRScanType) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
- }
-
-
+ static ConstString &GetSettingName() {
+ static ConstString g_setting_name("darwin-kernel");
+ return g_setting_name;
+ }
+
+ DynamicLoaderDarwinKernelProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~DynamicLoaderDarwinKernelProperties() {}
+
+ bool GetLoadKexts() const {
+ const uint32_t idx = ePropertyLoadKexts;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ NULL, idx, g_properties[idx].default_uint_value != 0);
+ }
+
+ KASLRScanType GetScanType() const {
+ const uint32_t idx = ePropertyScanType;
+ return (KASLRScanType)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ NULL, idx, g_properties[idx].default_uint_value);
+ }
};
-typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties> DynamicLoaderDarwinKernelPropertiesSP;
+typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties>
+ DynamicLoaderDarwinKernelPropertiesSP;
-static const DynamicLoaderDarwinKernelPropertiesSP &
-GetGlobalProperties()
-{
- static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new DynamicLoaderDarwinKernelProperties ());
- return g_settings_sp;
+static const DynamicLoaderDarwinKernelPropertiesSP &GetGlobalProperties() {
+ static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new DynamicLoaderDarwinKernelProperties());
+ return g_settings_sp;
}
//----------------------------------------------------------------------
@@ -134,359 +125,382 @@ GetGlobalProperties()
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-DynamicLoader *
-DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
-{
- if (!force)
- {
- // If the user provided an executable binary and it is not a kernel,
- // this plugin should not create an instance.
- Module* exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- if (object_file->GetStrata() != ObjectFile::eStrataKernel)
- {
- return NULL;
- }
- }
- }
-
- // If the target's architecture does not look like an Apple environment,
- // this plugin should not create an instance.
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- if (triple_ref.getVendor() != llvm::Triple::Apple)
- {
- return NULL;
- }
- break;
- // If we have triple like armv7-unknown-unknown, we should try looking for a Darwin kernel.
- case llvm::Triple::UnknownOS:
- break;
- default:
- return NULL;
- break;
+DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
+ bool force) {
+ if (!force) {
+ // If the user provided an executable binary and it is not a kernel,
+ // this plugin should not create an instance.
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ if (object_file->GetStrata() != ObjectFile::eStrataKernel) {
+ return NULL;
}
+ }
}
- // At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.
- // If the Process hasn't provided the kernel load address, we need to look around in memory to find it.
-
- const addr_t kernel_load_address = SearchForDarwinKernel (process);
- if (CheckForKernelImageAtAddress (kernel_load_address, process).IsValid())
- {
- process->SetCanRunCode(false);
- return new DynamicLoaderDarwinKernel (process, kernel_load_address);
+ // If the target's architecture does not look like an Apple environment,
+ // this plugin should not create an instance.
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ if (triple_ref.getVendor() != llvm::Triple::Apple) {
+ return NULL;
+ }
+ break;
+ // If we have triple like armv7-unknown-unknown, we should try looking for a
+ // Darwin kernel.
+ case llvm::Triple::UnknownOS:
+ break;
+ default:
+ return NULL;
+ break;
}
- return NULL;
+ }
+
+ // At this point if there is an ExecutableModule, it is a kernel and the
+ // Target is some variant of an Apple system.
+ // If the Process hasn't provided the kernel load address, we need to look
+ // around in memory to find it.
+
+ const addr_t kernel_load_address = SearchForDarwinKernel(process);
+ if (CheckForKernelImageAtAddress(kernel_load_address, process).IsValid()) {
+ process->SetCanRunCode(false);
+ return new DynamicLoaderDarwinKernel(process, kernel_load_address);
+ }
+ return NULL;
}
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForDarwinKernel (Process *process)
-{
- addr_t kernel_load_address = process->GetImageInfoAddress();
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelAtSameLoadAddr (process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelWithDebugHints (process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelNearPC (process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelViaExhaustiveSearch (process);
- }
- }
+DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
+ addr_t kernel_load_address = process->GetImageInfoAddress();
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelAtSameLoadAddr(process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelWithDebugHints(process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelNearPC(process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelViaExhaustiveSearch(process);
}
+ }
}
- return kernel_load_address;
+ }
+ return kernel_load_address;
}
//----------------------------------------------------------------------
// Check if the kernel binary is loaded in memory without a slide.
// First verify that the ExecutableModule is a kernel before we proceed.
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr (Process *process)
-{
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module == NULL)
- return LLDB_INVALID_ADDRESS;
+DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module == NULL)
+ return LLDB_INVALID_ADDRESS;
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- if (exe_objfile == NULL)
- return LLDB_INVALID_ADDRESS;
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ if (exe_objfile == NULL)
+ return LLDB_INVALID_ADDRESS;
- if (exe_objfile->GetType() != ObjectFile::eTypeExecutable || exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
- return LLDB_INVALID_ADDRESS;
+ if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
+ exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
+ return LLDB_INVALID_ADDRESS;
- if (!exe_objfile->GetHeaderAddress().IsValid())
- return LLDB_INVALID_ADDRESS;
+ if (!exe_objfile->GetHeaderAddress().IsValid())
+ return LLDB_INVALID_ADDRESS;
- if (CheckForKernelImageAtAddress (exe_objfile->GetHeaderAddress().GetFileAddress(), process) == exe_module->GetUUID())
- return exe_objfile->GetHeaderAddress().GetFileAddress();
+ if (CheckForKernelImageAtAddress(
+ exe_objfile->GetHeaderAddress().GetFileAddress(), process) ==
+ exe_module->GetUUID())
+ return exe_objfile->GetHeaderAddress().GetFileAddress();
- return LLDB_INVALID_ADDRESS;
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
-// If the debug flag is included in the boot-args nvram setting, the kernel's load address
+// If the debug flag is included in the boot-args nvram setting, the kernel's
+// load address
// will be noted in the lowglo page at a fixed address
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
-{
- if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
- return LLDB_INVALID_ADDRESS;
-
- Error read_err;
- addr_t addr = LLDB_INVALID_ADDRESS;
- addr_t kernel_addresses_64[] = { 0xffffff8000002010ULL, 0xffffff8000004010ULL,
- 0xfffffff000002010ULL, 0xfffffff000004010ULL,
- LLDB_INVALID_ADDRESS };
- addr_t kernel_addresses_32[] = { 0xffff0110,
- LLDB_INVALID_ADDRESS };
- for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++)
- {
- addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_64[i], 8, LLDB_INVALID_ADDRESS, read_err);
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- {
- return addr;
- }
- }
-
- for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++)
- {
- addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_32[i], 4, LLDB_INVALID_ADDRESS, read_err);
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- {
- return addr;
- }
- }
-
+DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
return LLDB_INVALID_ADDRESS;
+
+ Error read_err;
+ addr_t kernel_addresses_64[] = {
+ 0xfffffff000004010ULL, // newest arm64 devices
+ 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
+ 0xffffff8000002010ULL, // oldest arm64 devices
+ LLDB_INVALID_ADDRESS};
+ addr_t kernel_addresses_32[] = {0xffff0110, // 2016 and earlier armv7 devices
+ 0xffff1010,
+ LLDB_INVALID_ADDRESS};
+
+ uint8_t uval[8];
+ if (process->GetAddressByteSize() == 8) {
+ for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
+ if (process->ReadMemoryFromInferior (kernel_addresses_64[i], uval, 8, read_err) == 8)
+ {
+ DataExtractor data (&uval, 8, process->GetByteOrder(), process->GetAddressByteSize());
+ offset_t offset = 0;
+ uint64_t addr = data.GetU64 (&offset);
+ if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
+ return addr;
+ }
+ }
+ }
+ }
+
+ if (process->GetAddressByteSize() == 4) {
+ for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
+ if (process->ReadMemoryFromInferior (kernel_addresses_32[i], uval, 4, read_err) == 4)
+ {
+ DataExtractor data (&uval, 4, process->GetByteOrder(), process->GetAddressByteSize());
+ offset_t offset = 0;
+ uint32_t addr = data.GetU32 (&offset);
+ if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
+ return addr;
+ }
+ }
+ }
+ }
+
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
// If the kernel is currently executing when lldb attaches, and we don't have
// a better way of finding the kernel's load address, try searching backwards
// from the current pc value looking for the kernel's Mach header in memory.
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
-{
- if (GetGlobalProperties()->GetScanType() == eKASLRScanNone
- || GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses)
- {
- return LLDB_INVALID_ADDRESS;
- }
+DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone ||
+ GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses) {
+ return LLDB_INVALID_ADDRESS;
+ }
- ThreadSP thread = process->GetThreadList().GetSelectedThread ();
- if (thread.get() == NULL)
- return LLDB_INVALID_ADDRESS;
- addr_t pc = thread->GetRegisterContext ()->GetPC(LLDB_INVALID_ADDRESS);
-
- if (pc == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus
- // an offset of one page (0x1000) or two, or four (0x4000), depending on the device.
-
- // Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
- addr_t addr = pc & ~0xfffff;
-
- // 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)
- {
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- return addr;
- if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
- return addr + 0x1000;
- if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
- return addr + 0x2000;
- if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
- return addr + 0x4000;
- }
+ ThreadSP thread = process->GetThreadList().GetSelectedThread();
+ if (thread.get() == NULL)
+ return LLDB_INVALID_ADDRESS;
+ addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
+ if (pc == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
+
+ // The kernel will load at at one megabyte boundary (0x100000), or at that
+ // boundary plus
+ // an offset of one page (0x1000) or two, or four (0x4000), depending on the
+ // device.
+
+ // Round the current pc down to the nearest one megabyte boundary - the place
+ // where we will start searching.
+ addr_t addr = pc & ~0xfffff;
+
+ // 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) {
+ if (CheckForKernelImageAtAddress(addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
+ return addr + 0x4000;
+ }
+
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
// Scan through the valid address range for a kernel binary.
// This is uselessly slow in 64-bit environments so we don't even try it.
// This scan is not enabled by default even for 32-bit targets.
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
-lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
-{
- if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan)
- {
- return LLDB_INVALID_ADDRESS;
- }
-
- addr_t kernel_range_low, kernel_range_high;
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
- {
- kernel_range_low = 1ULL << 63;
- kernel_range_high = UINT64_MAX;
- }
- else
- {
- kernel_range_low = 1ULL << 31;
- kernel_range_high = UINT32_MAX;
- }
-
- // Stepping through memory at one-megabyte resolution looking for a kernel
- // rarely works (fast enough) with a 64-bit address space -- for now, let's
- // not even bother. We may be attaching to something which *isn't* a kernel
- // and we don't want to spin for minutes on-end looking for a kernel.
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
- return LLDB_INVALID_ADDRESS;
-
- addr_t addr = kernel_range_low;
-
- while (addr >= kernel_range_low && addr < kernel_range_high)
- {
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- return addr;
- if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
- return addr + 0x1000;
- if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
- return addr + 0x2000;
- if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
- return addr + 0x4000;
- addr += 0x100000;
- }
+lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
+ Process *process) {
+ if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan) {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ addr_t kernel_range_low, kernel_range_high;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
+ kernel_range_low = 1ULL << 63;
+ kernel_range_high = UINT64_MAX;
+ } else {
+ kernel_range_low = 1ULL << 31;
+ kernel_range_high = UINT32_MAX;
+ }
+
+ // Stepping through memory at one-megabyte resolution looking for a kernel
+ // rarely works (fast enough) with a 64-bit address space -- for now, let's
+ // not even bother. We may be attaching to something which *isn't* a kernel
+ // and we don't want to spin for minutes on-end looking for a kernel.
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
return LLDB_INVALID_ADDRESS;
+
+ addr_t addr = kernel_range_low;
+
+ while (addr >= kernel_range_low && addr < kernel_range_high) {
+ if (CheckForKernelImageAtAddress(addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
+ return addr + 0x4000;
+ addr += 0x100000;
+ }
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
// Given an address in memory, look to see if there is a kernel image at that
-// address.
-// Returns a UUID; if a kernel was not found at that address, UUID.IsValid() will be false.
+// address.
+// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
+// will be false.
//----------------------------------------------------------------------
lldb_private::UUID
-DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (addr == LLDB_INVALID_ADDRESS)
- return UUID();
+DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
+ Process *process) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (addr == LLDB_INVALID_ADDRESS)
+ return UUID();
- if (log)
- log->Printf ("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: looking for kernel binary at 0x%" PRIx64, addr);
-
- // First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
- // (the first field of the mach_header/mach_header_64 struct).
-
- Error read_error;
- uint64_t result = process->ReadUnsignedIntegerFromMemory (addr, 4, LLDB_INVALID_ADDRESS, read_error);
- if (result != llvm::MachO::MH_MAGIC_64
- && result != llvm::MachO::MH_MAGIC
- && result != llvm::MachO::MH_CIGAM
- && result != llvm::MachO::MH_CIGAM_64)
- {
- return UUID();
- }
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
+ "looking for kernel binary at 0x%" PRIx64,
+ addr);
+
+ // First try a quick test -- read the first 4 bytes and see if there is a
+ // valid Mach-O magic field there
+ // (the first field of the mach_header/mach_header_64 struct).
- // Read the mach header and see whether it looks like a kernel
- llvm::MachO::mach_header header;
- if (process->DoReadMemory (addr, &header, sizeof (header), read_error) != sizeof (header))
- return UUID();
-
- if (header.magic == llvm::MachO::MH_CIGAM ||
- header.magic == llvm::MachO::MH_CIGAM_64)
- {
- header.magic = llvm::ByteSwap_32 (header.magic);
- header.cputype = llvm::ByteSwap_32 (header.cputype);
- header.cpusubtype = llvm::ByteSwap_32 (header.cpusubtype);
- header.filetype = llvm::ByteSwap_32 (header.filetype);
- header.ncmds = llvm::ByteSwap_32 (header.ncmds);
- header.sizeofcmds = llvm::ByteSwap_32 (header.sizeofcmds);
- header.flags = llvm::ByteSwap_32 (header.flags);
+ Error read_error;
+ uint8_t magicbuf[4];
+ if (process->ReadMemoryFromInferior (addr, magicbuf, sizeof (magicbuf), read_error) != sizeof (magicbuf))
+ return UUID();
+
+ const uint32_t magicks[] = { llvm::MachO::MH_MAGIC_64, llvm::MachO::MH_MAGIC, llvm::MachO::MH_CIGAM, llvm::MachO::MH_CIGAM_64};
+
+ bool found_matching_pattern = false;
+ for (size_t i = 0; i < llvm::array_lengthof (magicks); i++)
+ if (::memcmp (magicbuf, &magicks[i], sizeof (magicbuf)) == 0)
+ found_matching_pattern = true;
+
+ if (found_matching_pattern == false)
+ return UUID();
+
+ // Read the mach header and see whether it looks like a kernel
+ llvm::MachO::mach_header header;
+ if (process->DoReadMemory(addr, &header, sizeof(header), read_error) !=
+ sizeof(header))
+ return UUID();
+
+ if (header.magic == llvm::MachO::MH_CIGAM ||
+ header.magic == llvm::MachO::MH_CIGAM_64) {
+ header.magic = llvm::ByteSwap_32(header.magic);
+ header.cputype = llvm::ByteSwap_32(header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32(header.filetype);
+ header.ncmds = llvm::ByteSwap_32(header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32(header.flags);
+ }
+
+ // A kernel is an executable which does not have the dynamic link object flag
+ // set.
+ 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);
+ if (!memory_module_sp.get())
+ return UUID();
+
+ ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
+ if (exe_objfile == NULL) {
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress "
+ "found a binary at 0x%" PRIx64
+ " but could not create an object file from memory",
+ addr);
+ return UUID();
}
- // A kernel is an executable which does not have the dynamic link object flag set.
- 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);
- if (!memory_module_sp.get())
- return UUID();
-
- ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
- if (exe_objfile == NULL)
- return UUID();
-
- if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
- {
- ArchSpec kernel_arch (eArchTypeMachO, header.cputype, header.cpusubtype);
- if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
- {
- process->GetTarget().SetArchitecture (kernel_arch);
- }
- if (log)
- log->Printf ("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: kernel binary image found at 0x%" PRIx64, addr);
- return memory_module_sp->GetUUID();
+ if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
+ exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
+ ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
+ if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
+ kernel_arch)) {
+ process->GetTarget().SetArchitecture(kernel_arch);
+ }
+ if (log) {
+ std::string uuid_str;
+ if (memory_module_sp->GetUUID().IsValid()) {
+ uuid_str = "with UUID ";
+ uuid_str += memory_module_sp->GetUUID().GetAsString();
+ } else {
+ uuid_str = "and no LC_UUID found in load commands ";
}
+ log->Printf(
+ "DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
+ "kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",
+ addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());
+ }
+ return memory_module_sp->GetUUID();
}
+ }
- return UUID();
+ return UUID();
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process, lldb::addr_t kernel_addr)
- : DynamicLoader(process),
- m_kernel_load_address(kernel_addr),
- m_kernel(),
- m_kext_summary_header_ptr_addr(),
- m_kext_summary_header_addr(),
- m_kext_summary_header(),
- m_known_kexts(),
- m_mutex(),
- m_break_id(LLDB_INVALID_BREAK_ID)
-{
- Error error;
- PlatformSP platform_sp(Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
- // Only select the darwin-kernel Platform if we've been asked to load kexts.
- // It can take some time to scan over all of the kext info.plists and that
- // shouldn't be done if kext loading is explicitly disabled.
- if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts())
- {
- process->GetTarget().SetPlatform(platform_sp);
- }
+DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
+ lldb::addr_t kernel_addr)
+ : DynamicLoader(process), m_kernel_load_address(kernel_addr), m_kernel(),
+ m_kext_summary_header_ptr_addr(), m_kext_summary_header_addr(),
+ m_kext_summary_header(), m_known_kexts(), m_mutex(),
+ m_break_id(LLDB_INVALID_BREAK_ID) {
+ Error error;
+ PlatformSP platform_sp(
+ Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
+ // Only select the darwin-kernel Platform if we've been asked to load kexts.
+ // It can take some time to scan over all of the kext info.plists and that
+ // shouldn't be done if kext loading is explicitly disabled.
+ if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
+ process->GetTarget().SetPlatform(platform_sp);
+ }
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
-{
- Clear(true);
-}
+DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() { Clear(true); }
-void
-DynamicLoaderDarwinKernel::UpdateIfNeeded()
-{
- LoadKernelModuleIfNeeded();
- SetNotificationBreakpointIfNeeded ();
+void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
+ LoadKernelModuleIfNeeded();
+ SetNotificationBreakpointIfNeeded();
}
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -494,11 +508,9 @@ DynamicLoaderDarwinKernel::UpdateIfNeeded()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::DidAttach ()
-{
- PrivateInitialize(m_process);
- UpdateIfNeeded();
+void DynamicLoaderDarwinKernel::DidAttach() {
+ PrivateInitialize(m_process);
+ UpdateIfNeeded();
}
//------------------------------------------------------------------
@@ -507,592 +519,528 @@ DynamicLoaderDarwinKernel::DidAttach ()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::DidLaunch ()
-{
- PrivateInitialize(m_process);
- UpdateIfNeeded();
+void DynamicLoaderDarwinKernel::DidLaunch() {
+ PrivateInitialize(m_process);
+ UpdateIfNeeded();
}
-
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::Clear (bool clear_process)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
-
- if (clear_process)
- m_process = NULL;
- m_kernel.Clear();
- m_known_kexts.clear();
- m_kext_summary_header_ptr_addr.Clear();
- m_kext_summary_header_addr.Clear();
- m_break_id = LLDB_INVALID_BREAK_ID;
+void DynamicLoaderDarwinKernel::Clear(bool clear_process) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->ClearBreakpointSiteByID(m_break_id);
+
+ if (clear_process)
+ m_process = NULL;
+ m_kernel.Clear();
+ m_known_kexts.clear();
+ m_kext_summary_header_ptr_addr.Clear();
+ m_kext_summary_header_addr.Clear();
+ m_break_id = LLDB_INVALID_BREAK_ID;
}
+bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
+ Process *process) {
+ if (IsLoaded())
+ return true;
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress (Process *process)
-{
- if (IsLoaded())
- return true;
-
- if (m_module_sp)
- {
- bool changed = false;
- if (m_module_sp->SetLoadAddress (process->GetTarget(), 0, true, changed))
- m_load_process_stop_id = process->GetStopID();
- }
- return false;
+ if (m_module_sp) {
+ bool changed = false;
+ if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
+ m_load_process_stop_id = process->GetStopID();
+ }
+ return false;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetModule (ModuleSP module_sp)
-{
- m_module_sp = module_sp;
- if (module_sp.get() && module_sp->GetObjectFile())
- {
- if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
- && module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
- {
- m_kernel_image = true;
- }
- else
- {
- m_kernel_image = false;
- }
+void DynamicLoaderDarwinKernel::KextImageInfo::SetModule(ModuleSP module_sp) {
+ m_module_sp = module_sp;
+ if (module_sp.get() && module_sp->GetObjectFile()) {
+ if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable &&
+ module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) {
+ m_kernel_image = true;
+ } else {
+ m_kernel_image = false;
}
+ }
}
-ModuleSP
-DynamicLoaderDarwinKernel::KextImageInfo::GetModule ()
-{
- return m_module_sp;
+ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
+ return m_module_sp;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress (addr_t load_addr)
-{
- m_load_address = load_addr;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress(
+ addr_t load_addr) {
+ m_load_address = load_addr;
}
-addr_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress () const
-{
- return m_load_address;
+addr_t DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress() const {
+ return m_load_address;
}
-uint64_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetSize () const
-{
- return m_size;
+uint64_t DynamicLoaderDarwinKernel::KextImageInfo::GetSize() const {
+ return m_size;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetSize (uint64_t size)
-{
- m_size = size;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetSize(uint64_t size) {
+ m_size = size;
}
-uint32_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId () const
-{
- return m_load_process_stop_id;
+uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId() const {
+ return m_load_process_stop_id;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId (uint32_t stop_id)
-{
- m_load_process_stop_id = stop_id;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
+ uint32_t stop_id) {
+ m_load_process_stop_id = stop_id;
}
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::operator== (const KextImageInfo &rhs)
-{
- if (m_uuid.IsValid() || rhs.GetUUID().IsValid())
- {
- if (m_uuid == rhs.GetUUID())
- {
- return true;
- }
- return false;
+bool DynamicLoaderDarwinKernel::KextImageInfo::
+operator==(const KextImageInfo &rhs) {
+ if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
+ if (m_uuid == rhs.GetUUID()) {
+ return true;
}
+ return false;
+ }
- if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
- return true;
+ if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
+ return true;
- return false;
+ return false;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetName (const char *name)
-{
- m_name = name;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
+ m_name = name;
}
-std::string
-DynamicLoaderDarwinKernel::KextImageInfo::GetName () const
-{
- return m_name;
+std::string DynamicLoaderDarwinKernel::KextImageInfo::GetName() const {
+ return m_name;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetUUID (const UUID &uuid)
-{
- m_uuid = uuid;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetUUID(const UUID &uuid) {
+ m_uuid = uuid;
}
-UUID
-DynamicLoaderDarwinKernel::KextImageInfo::GetUUID () const
-{
- return m_uuid;
+UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
+ return m_uuid;
}
-// Given the m_load_address from the kext summaries, and a UUID, try to create an in-memory
-// Module at that address. Require that the MemoryModule have a matching UUID and detect
+// Given the m_load_address from the kext summaries, and a UUID, try to create
+// an in-memory
+// Module at that address. Require that the MemoryModule have a matching UUID
+// and detect
// if this MemoryModule is a kernel or a kext.
//
-// Returns true if m_memory_module_sp is now set to a valid Module.
-
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (m_memory_module_sp.get() != NULL)
- return true;
- if (m_load_address == LLDB_INVALID_ADDRESS)
- return false;
-
- FileSpec file_spec;
- file_spec.SetFile (m_name.c_str(), false);
-
- ModuleSP memory_module_sp = process->ReadModuleFromMemory (file_spec, m_load_address);
-
- if (memory_module_sp.get() == NULL)
- return false;
-
- bool is_kernel = false;
- if (memory_module_sp->GetObjectFile())
- {
- if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
- && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
- {
- is_kernel = true;
- }
- else if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeSharedLibrary)
- {
- is_kernel = false;
- }
- }
+// Returns true if m_memory_module_sp is now set to a valid Module.
- // If this is a kext, and the kernel specified what UUID we should find at this
- // load address, require that the memory module have a matching UUID or something
- // has gone wrong and we should discard it.
- if (m_uuid.IsValid())
- {
- if (m_uuid != memory_module_sp->GetUUID())
- {
- if (log)
- {
- log->Printf ("KextImageInfo::ReadMemoryModule the kernel said to find uuid %s at 0x%" PRIx64 " but instead we found uuid %s, throwing it away", m_uuid.GetAsString().c_str(), m_load_address, memory_module_sp->GetUUID().GetAsString().c_str());
- }
- return false;
- }
- }
+bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
+ Process *process) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (m_memory_module_sp.get() != NULL)
+ return true;
+ if (m_load_address == LLDB_INVALID_ADDRESS)
+ return false;
- // If the in-memory Module has a UUID, let's use that.
- if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
- {
- m_uuid = memory_module_sp->GetUUID();
- }
+ FileSpec file_spec;
+ file_spec.SetFile(m_name.c_str(), false);
- m_memory_module_sp = memory_module_sp;
- m_kernel_image = is_kernel;
- if (is_kernel)
- {
- if (log)
- {
- // This is unusual and probably not intended
- log->Printf ("KextImageInfo::ReadMemoryModule read the kernel binary out of memory");
- }
- if (memory_module_sp->GetArchitecture().IsValid())
- {
- process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
- }
- if (m_uuid.IsValid())
- {
- ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
- if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid())
- {
- if (m_uuid != exe_module_sp->GetUUID())
- {
- // The user specified a kernel binary that has a different UUID than
- // the kernel actually running in memory. This never ends well;
- // clear the user specified kernel binary from the Target.
-
- m_module_sp.reset();
-
- ModuleList user_specified_kernel_list;
- user_specified_kernel_list.Append (exe_module_sp);
- process->GetTarget().GetImages().Remove (user_specified_kernel_list);
- }
- }
+ ModuleSP memory_module_sp =
+ process->ReadModuleFromMemory(file_spec, m_load_address);
+
+ if (memory_module_sp.get() == NULL)
+ return false;
+
+ bool is_kernel = false;
+ if (memory_module_sp->GetObjectFile()) {
+ if (memory_module_sp->GetObjectFile()->GetType() ==
+ ObjectFile::eTypeExecutable &&
+ memory_module_sp->GetObjectFile()->GetStrata() ==
+ ObjectFile::eStrataKernel) {
+ is_kernel = true;
+ } else if (memory_module_sp->GetObjectFile()->GetType() ==
+ ObjectFile::eTypeSharedLibrary) {
+ is_kernel = false;
+ }
+ }
+
+ // If this is a kext, and the kernel specified what UUID we should find at
+ // this
+ // load address, require that the memory module have a matching UUID or
+ // something
+ // has gone wrong and we should discard it.
+ if (m_uuid.IsValid()) {
+ if (m_uuid != memory_module_sp->GetUUID()) {
+ if (log) {
+ log->Printf("KextImageInfo::ReadMemoryModule the kernel said to find "
+ "uuid %s at 0x%" PRIx64
+ " but instead we found uuid %s, throwing it away",
+ m_uuid.GetAsString().c_str(), m_load_address,
+ memory_module_sp->GetUUID().GetAsString().c_str());
+ }
+ return false;
+ }
+ }
+
+ // If the in-memory Module has a UUID, let's use that.
+ if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) {
+ m_uuid = memory_module_sp->GetUUID();
+ }
+
+ m_memory_module_sp = memory_module_sp;
+ m_kernel_image = is_kernel;
+ if (is_kernel) {
+ if (log) {
+ // This is unusual and probably not intended
+ log->Printf("KextImageInfo::ReadMemoryModule read the kernel binary out "
+ "of memory");
+ }
+ if (memory_module_sp->GetArchitecture().IsValid()) {
+ process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
+ }
+ if (m_uuid.IsValid()) {
+ ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
+ if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid()) {
+ if (m_uuid != exe_module_sp->GetUUID()) {
+ // The user specified a kernel binary that has a different UUID than
+ // the kernel actually running in memory. This never ends well;
+ // clear the user specified kernel binary from the Target.
+
+ m_module_sp.reset();
+
+ ModuleList user_specified_kernel_list;
+ user_specified_kernel_list.Append(exe_module_sp);
+ process->GetTarget().GetImages().Remove(user_specified_kernel_list);
}
+ }
}
+ }
- return true;
+ return true;
}
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::IsKernel () const
-{
- return m_kernel_image == true;
+bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
+ return m_kernel_image == true;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel (bool is_kernel)
-{
- m_kernel_image = is_kernel;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
+ m_kernel_image = is_kernel;
}
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *process)
-{
- if (IsLoaded())
- return true;
-
+bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
+ Process *process) {
+ if (IsLoaded())
+ return true;
- Target &target = process->GetTarget();
+ Target &target = process->GetTarget();
- // If we don't have / can't create a memory module for this kext, don't try to load it - we won't
- // have the correct segment load addresses.
- if (!ReadMemoryModule (process))
- {
- return false;
- }
+ // If we don't have / can't create a memory module for this kext, don't try to
+ // load it - we won't
+ // have the correct segment load addresses.
+ if (!ReadMemoryModule(process)) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64
+ " to get the segment load addresses.",
+ m_name.c_str(), m_load_address);
+ return false;
+ }
- bool uuid_is_valid = m_uuid.IsValid();
+ bool uuid_is_valid = m_uuid.IsValid();
- if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
- {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsString().c_str());
- s->Printf ("Load Address: 0x%" PRIx64 "\n", m_load_address);
- }
+ if (IsKernel() && uuid_is_valid && m_memory_module_sp.get()) {
+ Stream *s = target.GetDebugger().GetOutputFile().get();
+ if (s) {
+ s->Printf("Kernel UUID: %s\n",
+ m_memory_module_sp->GetUUID().GetAsString().c_str());
+ s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
}
-
- if (!m_module_sp)
- {
- // See if the kext has already been loaded into the target, probably by the user doing target modules add.
- const ModuleList &target_images = target.GetImages();
- m_module_sp = target_images.FindModule(m_uuid);
-
- // Search for the kext on the local filesystem via the UUID
- if (!m_module_sp && uuid_is_valid)
- {
- ModuleSpec module_spec;
- module_spec.GetUUID() = m_uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
-
- // For the kernel, we really do need an on-disk file copy of the binary to do anything useful.
- // This will force a clal to
- if (IsKernel())
- {
- if (Symbols::DownloadObjectAndSymbolFile (module_spec, true))
- {
- if (module_spec.GetFileSpec().Exists())
- {
- m_module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
- if (m_module_sp.get() && m_module_sp->MatchesModuleSpec (module_spec))
- {
- ModuleList loaded_module_list;
- loaded_module_list.Append (m_module_sp);
- target.ModulesDidLoad (loaded_module_list);
- }
- }
- }
- }
-
- // If the current platform is PlatformDarwinKernel, create a ModuleSpec with the filename set
- // to be the bundle ID for this kext, e.g. "com.apple.filesystems.msdosfs", and ask the platform
- // to find it.
- PlatformSP platform_sp (target.GetPlatform());
- if (!m_module_sp && platform_sp)
- {
- ConstString platform_name (platform_sp->GetPluginName());
- static ConstString g_platform_name (PlatformDarwinKernel::GetPluginNameStatic());
- if (platform_name == g_platform_name)
- {
- ModuleSpec kext_bundle_module_spec(module_spec);
- FileSpec kext_filespec(m_name.c_str(), false);
- kext_bundle_module_spec.GetFileSpec() = kext_filespec;
- platform_sp->GetSharedModule (kext_bundle_module_spec, process, m_module_sp, &target.GetExecutableSearchPaths(), NULL, NULL);
- }
- }
-
- // Ask the Target to find this file on the local system, if possible.
- // This will search in the list of currently-loaded files, look in the
- // standard search paths on the system, and on a Mac it will try calling
- // the DebugSymbols framework with the UUID to find the binary via its
- // search methods.
- if (!m_module_sp)
- {
- m_module_sp = target.GetSharedModule (module_spec);
- }
-
- if (IsKernel() && !m_module_sp)
- {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- s->Printf ("WARNING: Unable to locate kernel binary on the debugger system.\n");
- }
+ }
+
+ if (!m_module_sp) {
+ // See if the kext has already been loaded into the target, probably by the
+ // user doing target modules add.
+ const ModuleList &target_images = target.GetImages();
+ m_module_sp = target_images.FindModule(m_uuid);
+
+ // Search for the kext on the local filesystem via the UUID
+ if (!m_module_sp && uuid_is_valid) {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = m_uuid;
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ // For the kernel, we really do need an on-disk file copy of the binary to
+ // do anything useful.
+ // This will force a clal to
+ if (IsKernel()) {
+ if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
+ if (module_spec.GetFileSpec().Exists()) {
+ m_module_sp.reset(new Module(module_spec.GetFileSpec(),
+ target.GetArchitecture()));
+ if (m_module_sp.get() &&
+ m_module_sp->MatchesModuleSpec(module_spec)) {
+ ModuleList loaded_module_list;
+ loaded_module_list.Append(m_module_sp);
+ target.ModulesDidLoad(loaded_module_list);
}
+ }
}
-
- // If we managed to find a module, append it to the target's list of images.
- // If we also have a memory module, require that they have matching UUIDs
- if (m_module_sp)
- {
- bool uuid_match_ok = true;
- if (m_memory_module_sp)
- {
- if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID())
- {
- uuid_match_ok = false;
- }
- }
- if (uuid_match_ok)
- {
- target.GetImages().AppendIfNeeded(m_module_sp);
- if (IsKernel() && target.GetExecutableModulePointer() != m_module_sp.get())
- {
- target.SetExecutableModule (m_module_sp, false);
- }
- }
+ }
+
+ // If the current platform is PlatformDarwinKernel, create a ModuleSpec
+ // with the filename set
+ // to be the bundle ID for this kext, e.g.
+ // "com.apple.filesystems.msdosfs", and ask the platform
+ // to find it.
+ PlatformSP platform_sp(target.GetPlatform());
+ if (!m_module_sp && platform_sp) {
+ ConstString platform_name(platform_sp->GetPluginName());
+ static ConstString g_platform_name(
+ PlatformDarwinKernel::GetPluginNameStatic());
+ if (platform_name == g_platform_name) {
+ ModuleSpec kext_bundle_module_spec(module_spec);
+ FileSpec kext_filespec(m_name.c_str(), false);
+ kext_bundle_module_spec.GetFileSpec() = kext_filespec;
+ platform_sp->GetSharedModule(
+ kext_bundle_module_spec, process, m_module_sp,
+ &target.GetExecutableSearchPaths(), NULL, NULL);
}
- }
-
- if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
- {
+ }
+
+ // Ask the Target to find this file on the local system, if possible.
+ // This will search in the list of currently-loaded files, look in the
+ // standard search paths on the system, and on a Mac it will try calling
+ // the DebugSymbols framework with the UUID to find the binary via its
+ // search methods.
+ if (!m_module_sp) {
+ m_module_sp = target.GetSharedModule(module_spec);
+ }
+
+ if (IsKernel() && !m_module_sp) {
Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n",
- m_name.c_str(), m_uuid.GetAsString().c_str());
+ if (s) {
+ s->Printf("WARNING: Unable to locate kernel binary on the debugger "
+ "system.\n");
}
+ }
}
- static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
-
- if (m_memory_module_sp && m_module_sp)
- {
- if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID())
- {
- ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
- ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
-
- if (memory_object_file && ondisk_object_file)
- {
- // The memory_module for kexts may have an invalid __LINKEDIT seg; skip it.
- const bool ignore_linkedit = !IsKernel ();
-
- SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
- SectionList *memory_section_list = memory_object_file->GetSectionList ();
- if (memory_section_list && ondisk_section_list)
- {
- const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
- // There may be CTF sections in the memory image so we can't
- // always just compare the number of sections (which are actually
- // segments in mach-o parlance)
- uint32_t sect_idx = 0;
-
- // Use the memory_module's addresses for each section to set the
- // file module's load address as appropriate. We don't want to use
- // a single slide value for the entire kext - different segments may
- // be slid different amounts by the kext loader.
-
- uint32_t num_sections_loaded = 0;
- for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
- {
- SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
- if (ondisk_section_sp)
- {
- // Don't ever load __LINKEDIT as it may or may not be actually
- // mapped into memory and there is no current way to tell.
- // I filed rdar://problem/12851706 to track being able to tell
- // if the __LINKEDIT is actually mapped, but until then, we need
- // to not load the __LINKEDIT
- if (ignore_linkedit && ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
- continue;
-
- const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
- if (memory_section)
- {
- target.SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
- ++num_sections_loaded;
- }
- }
- }
- if (num_sections_loaded > 0)
- m_load_process_stop_id = process->GetStopID();
- else
- m_module_sp.reset(); // No sections were loaded
- }
- else
- m_module_sp.reset(); // One or both section lists
- }
- else
- m_module_sp.reset(); // One or both object files missing
+ // If we managed to find a module, append it to the target's list of images.
+ // If we also have a memory module, require that they have matching UUIDs
+ if (m_module_sp) {
+ bool uuid_match_ok = true;
+ if (m_memory_module_sp) {
+ if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID()) {
+ uuid_match_ok = false;
}
- else
- m_module_sp.reset(); // UUID mismatch
+ }
+ if (uuid_match_ok) {
+ target.GetImages().AppendIfNeeded(m_module_sp);
+ if (IsKernel() &&
+ target.GetExecutableModulePointer() != m_module_sp.get()) {
+ target.SetExecutableModule(m_module_sp, false);
+ }
+ }
}
+ }
- bool is_loaded = IsLoaded();
-
- if (is_loaded && m_module_sp && IsKernel())
- {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
- if (kernel_object_file)
- {
- addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
- if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS)
- {
- s->Printf ("Kernel slid 0x%" PRIx64 " in memory.\n", m_load_address - file_address);
- }
- }
- {
- s->Printf ("Loaded kernel file %s\n",
- m_module_sp->GetFileSpec().GetPath().c_str());
+ if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty()) {
+ Stream *s = target.GetDebugger().GetOutputFile().get();
+ if (s) {
+ s->Printf("warning: Can't find binary/dSYM for %s (%s)\n", m_name.c_str(),
+ m_uuid.GetAsString().c_str());
+ }
+ }
+
+ static ConstString g_section_name_LINKEDIT("__LINKEDIT");
+
+ if (m_memory_module_sp && m_module_sp) {
+ if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID()) {
+ ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
+ ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
+
+ if (memory_object_file && ondisk_object_file) {
+ // The memory_module for kexts may have an invalid __LINKEDIT seg; skip
+ // it.
+ const bool ignore_linkedit = !IsKernel();
+
+ SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
+ SectionList *memory_section_list = memory_object_file->GetSectionList();
+ if (memory_section_list && ondisk_section_list) {
+ const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
+ // There may be CTF sections in the memory image so we can't
+ // always just compare the number of sections (which are actually
+ // segments in mach-o parlance)
+ uint32_t sect_idx = 0;
+
+ // Use the memory_module's addresses for each section to set the
+ // file module's load address as appropriate. We don't want to use
+ // a single slide value for the entire kext - different segments may
+ // be slid different amounts by the kext loader.
+
+ uint32_t num_sections_loaded = 0;
+ for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
+ SectionSP ondisk_section_sp(
+ ondisk_section_list->GetSectionAtIndex(sect_idx));
+ if (ondisk_section_sp) {
+ // Don't ever load __LINKEDIT as it may or may not be actually
+ // mapped into memory and there is no current way to tell.
+ // I filed rdar://problem/12851706 to track being able to tell
+ // if the __LINKEDIT is actually mapped, but until then, we need
+ // to not load the __LINKEDIT
+ if (ignore_linkedit &&
+ ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
+ continue;
+
+ const Section *memory_section =
+ memory_section_list
+ ->FindSectionByName(ondisk_section_sp->GetName())
+ .get();
+ if (memory_section) {
+ target.SetSectionLoadAddress(ondisk_section_sp,
+ memory_section->GetFileAddress());
+ ++num_sections_loaded;
+ }
}
- s->Flush ();
+ }
+ if (num_sections_loaded > 0)
+ m_load_process_stop_id = process->GetStopID();
+ else
+ m_module_sp.reset(); // No sections were loaded
+ } else
+ m_module_sp.reset(); // One or both section lists
+ } else
+ m_module_sp.reset(); // One or both object files missing
+ } else
+ m_module_sp.reset(); // UUID mismatch
+ }
+
+ bool is_loaded = IsLoaded();
+
+ if (is_loaded && m_module_sp && IsKernel()) {
+ Stream *s = target.GetDebugger().GetOutputFile().get();
+ if (s) {
+ ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
+ if (kernel_object_file) {
+ addr_t file_address =
+ kernel_object_file->GetHeaderAddress().GetFileAddress();
+ if (m_load_address != LLDB_INVALID_ADDRESS &&
+ file_address != LLDB_INVALID_ADDRESS) {
+ s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
+ m_load_address - file_address);
}
+ }
+ {
+ s->Printf("Loaded kernel file %s\n",
+ m_module_sp->GetFileSpec().GetPath().c_str());
+ }
+ s->Flush();
}
- return is_loaded;
+ }
+ return is_loaded;
}
-uint32_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize ()
-{
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
- if (m_module_sp)
- return m_module_sp->GetArchitecture().GetAddressByteSize();
- return 0;
+uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize() {
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetAddressByteSize();
+ return 0;
}
-lldb::ByteOrder
-DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder()
-{
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture().GetByteOrder();
- if (m_module_sp)
- return m_module_sp->GetArchitecture().GetByteOrder();
- return endian::InlHostByteOrder();
+lldb::ByteOrder DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder() {
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetByteOrder();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetByteOrder();
+ return endian::InlHostByteOrder();
}
lldb_private::ArchSpec
-DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture () const
-{
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture();
- if (m_module_sp)
- return m_module_sp->GetArchitecture();
- return lldb_private::ArchSpec ();
+DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture();
+ return lldb_private::ArchSpec();
}
-
//----------------------------------------------------------------------
// Load the kernel module and initialize the "m_kernel" member. Return
// true _only_ if the kernel is loaded the first time through (subsequent
// calls to this function should return false after the kernel has been
// already loaded).
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
-{
- if (!m_kext_summary_header_ptr_addr.IsValid())
- {
- m_kernel.Clear();
- m_kernel.SetModule (m_process->GetTarget().GetExecutableModule());
- m_kernel.SetIsKernel(true);
-
- ConstString kernel_name("mach_kernel");
- if (m_kernel.GetModule().get()
- && m_kernel.GetModule()->GetObjectFile()
- && !m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
- {
- kernel_name = m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
- }
- m_kernel.SetName (kernel_name.AsCString());
-
- if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS)
- {
- m_kernel.SetLoadAddress(m_kernel_load_address);
- if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS && m_kernel.GetModule())
- {
- // We didn't get a hint from the process, so we will
- // try the kernel at the address that it exists at in
- // the file if we have one
- ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
- if (kernel_object_file)
- {
- addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
- addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
- if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
- {
- m_kernel.SetLoadAddress (load_address);
- if (load_address != file_address)
- {
- // Don't accidentally relocate the kernel to the File address --
- // the Load address has already been set to its actual in-memory address.
- // Mark it as IsLoaded.
- m_kernel.SetProcessStopId (m_process->GetStopID());
- }
- }
- else
- {
- m_kernel.SetLoadAddress(file_address);
- }
- }
- }
- }
-
- if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
- {
- if (!m_kernel.LoadImageUsingMemoryModule (m_process))
- {
- m_kernel.LoadImageAtFileAddress (m_process);
+void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
+ if (!m_kext_summary_header_ptr_addr.IsValid()) {
+ m_kernel.Clear();
+ m_kernel.SetModule(m_process->GetTarget().GetExecutableModule());
+ m_kernel.SetIsKernel(true);
+
+ ConstString kernel_name("mach_kernel");
+ if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
+ !m_kernel.GetModule()
+ ->GetObjectFile()
+ ->GetFileSpec()
+ .GetFilename()
+ .IsEmpty()) {
+ kernel_name =
+ m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
+ }
+ m_kernel.SetName(kernel_name.AsCString());
+
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
+ m_kernel.SetLoadAddress(m_kernel_load_address);
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
+ m_kernel.GetModule()) {
+ // We didn't get a hint from the process, so we will
+ // try the kernel at the address that it exists at in
+ // the file if we have one
+ ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
+ if (kernel_object_file) {
+ addr_t load_address =
+ kernel_object_file->GetHeaderAddress().GetLoadAddress(
+ &m_process->GetTarget());
+ addr_t file_address =
+ kernel_object_file->GetHeaderAddress().GetFileAddress();
+ if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
+ m_kernel.SetLoadAddress(load_address);
+ if (load_address != file_address) {
+ // Don't accidentally relocate the kernel to the File address --
+ // the Load address has already been set to its actual in-memory
+ // address.
+ // Mark it as IsLoaded.
+ m_kernel.SetProcessStopId(m_process->GetStopID());
}
+ } else {
+ m_kernel.SetLoadAddress(file_address);
+ }
}
+ }
+ }
- if (m_kernel.IsLoaded() && m_kernel.GetModule())
- {
- static ConstString kext_summary_symbol ("gLoadedKextSummaries");
- const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
- if (symbol)
- {
- m_kext_summary_header_ptr_addr = symbol->GetAddress();
- // Update all image infos
- ReadAllKextSummaries ();
- }
- }
- else
- {
- m_kernel.Clear();
- }
+ if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+ if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+ m_kernel.LoadImageAtFileAddress(m_process);
+ }
}
+
+ if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
+ static ConstString kext_summary_symbol("gLoadedKextSummaries");
+ const Symbol *symbol =
+ m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
+ kext_summary_symbol, eSymbolTypeData);
+ if (symbol) {
+ m_kext_summary_header_ptr_addr = symbol->GetAddress();
+ // Update all image infos
+ ReadAllKextSummaries();
+ }
+ } else {
+ m_kernel.Clear();
+ }
+ }
}
//----------------------------------------------------------------------
@@ -1101,591 +1049,531 @@ DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
+bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ return static_cast<DynamicLoaderDarwinKernel *>(baton)->BreakpointHit(
+ context, break_id, break_loc_id);
}
-bool
-DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
+bool DynamicLoaderDarwinKernel::BreakpointHit(StoppointCallbackContext *context,
+ user_id_t break_id,
+ user_id_t break_loc_id) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
- ReadAllKextSummaries ();
-
- if (log)
- PutToLog(log);
+ ReadAllKextSummaries();
- return GetStopWhenImagesChange();
+ if (log)
+ PutToLog(log);
+
+ return GetStopWhenImagesChange();
}
+bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ // the all image infos is already valid for this process stop ID
-bool
-DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // the all image infos is already valid for this process stop ID
-
- if (m_kext_summary_header_ptr_addr.IsValid())
- {
- const uint32_t addr_size = m_kernel.GetAddressByteSize ();
- const ByteOrder byte_order = m_kernel.GetByteOrder();
- Error error;
- // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
- // which is currently 4 uint32_t and a pointer.
- uint8_t buf[24];
- DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
- const size_t count = 4 * sizeof(uint32_t) + addr_size;
- const bool prefer_file_cache = false;
- if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
- prefer_file_cache,
- error,
- m_kext_summary_header_addr))
- {
- // We got a valid address for our kext summary header and make sure it isn't NULL
- if (m_kext_summary_header_addr.IsValid() &&
- m_kext_summary_header_addr.GetFileAddress() != 0)
- {
- const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
- if (bytes_read == count)
- {
- lldb::offset_t offset = 0;
- m_kext_summary_header.version = data.GetU32(&offset);
- if (m_kext_summary_header.version > 128)
- {
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf ("WARNING: Unable to read kext summary header, got improbable version number %u\n", m_kext_summary_header.version);
- // If we get an improbably large version number, we're probably getting bad memory.
- m_kext_summary_header_addr.Clear();
- return false;
- }
- if (m_kext_summary_header.version >= 2)
- {
- m_kext_summary_header.entry_size = data.GetU32(&offset);
- if (m_kext_summary_header.entry_size > 4096)
- {
- // If we get an improbably large entry_size, we're probably getting bad memory.
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf ("WARNING: Unable to read kext summary header, got improbable entry_size %u\n", m_kext_summary_header.entry_size);
- m_kext_summary_header_addr.Clear();
- return false;
- }
- }
- else
- {
- // Versions less than 2 didn't have an entry size, it was hard coded
- m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
- }
- m_kext_summary_header.entry_count = data.GetU32(&offset);
- if (m_kext_summary_header.entry_count > 10000)
- {
- // If we get an improbably large number of kexts, we're probably getting bad memory.
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf ("WARNING: Unable to read kext summary header, got improbable number of kexts %u\n", m_kext_summary_header.entry_count);
- m_kext_summary_header_addr.Clear();
- return false;
- }
- return true;
- }
+ if (m_kext_summary_header_ptr_addr.IsValid()) {
+ const uint32_t addr_size = m_kernel.GetAddressByteSize();
+ const ByteOrder byte_order = m_kernel.GetByteOrder();
+ Error error;
+ // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
+ // which is currently 4 uint32_t and a pointer.
+ uint8_t buf[24];
+ DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+ const size_t count = 4 * sizeof(uint32_t) + addr_size;
+ const bool prefer_file_cache = false;
+ if (m_process->GetTarget().ReadPointerFromMemory(
+ m_kext_summary_header_ptr_addr, prefer_file_cache, error,
+ m_kext_summary_header_addr)) {
+ // We got a valid address for our kext summary header and make sure it
+ // isn't NULL
+ if (m_kext_summary_header_addr.IsValid() &&
+ m_kext_summary_header_addr.GetFileAddress() != 0) {
+ const size_t bytes_read = m_process->GetTarget().ReadMemory(
+ m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
+ if (bytes_read == count) {
+ lldb::offset_t offset = 0;
+ m_kext_summary_header.version = data.GetU32(&offset);
+ if (m_kext_summary_header.version > 128) {
+ Stream *s =
+ m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ s->Printf("WARNING: Unable to read kext summary header, got "
+ "improbable version number %u\n",
+ m_kext_summary_header.version);
+ // If we get an improbably large version number, we're probably
+ // getting bad memory.
+ m_kext_summary_header_addr.Clear();
+ return false;
+ }
+ if (m_kext_summary_header.version >= 2) {
+ m_kext_summary_header.entry_size = data.GetU32(&offset);
+ if (m_kext_summary_header.entry_size > 4096) {
+ // If we get an improbably large entry_size, we're probably
+ // getting bad memory.
+ Stream *s =
+ m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ s->Printf("WARNING: Unable to read kext summary header, got "
+ "improbable entry_size %u\n",
+ m_kext_summary_header.entry_size);
+ m_kext_summary_header_addr.Clear();
+ return false;
}
+ } else {
+ // Versions less than 2 didn't have an entry size, it was hard coded
+ m_kext_summary_header.entry_size =
+ KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
+ }
+ m_kext_summary_header.entry_count = data.GetU32(&offset);
+ if (m_kext_summary_header.entry_count > 10000) {
+ // If we get an improbably large number of kexts, we're probably
+ // getting bad memory.
+ Stream *s =
+ m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ s->Printf("WARNING: Unable to read kext summary header, got "
+ "improbable number of kexts %u\n",
+ m_kext_summary_header.entry_count);
+ m_kext_summary_header_addr.Clear();
+ return false;
+ }
+ return true;
}
+ }
}
- m_kext_summary_header_addr.Clear();
- return false;
+ }
+ m_kext_summary_header_addr.Clear();
+ return false;
}
-// We've either (a) just attached to a new kernel, or (b) the kexts-changed breakpoint was hit
+// We've either (a) just attached to a new kernel, or (b) the kexts-changed
+// breakpoint was hit
// and we need to figure out what kexts have been added or removed.
-// Read the kext summaries from the inferior kernel memory, compare them against the
-// m_known_kexts vector and update the m_known_kexts vector as needed to keep in sync with the
+// Read the kext summaries from the inferior kernel memory, compare them against
+// the
+// m_known_kexts vector and update the m_known_kexts vector as needed to keep in
+// sync with the
// inferior.
-bool
-DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, uint32_t count)
-{
- KextImageInfo::collection kext_summaries;
- Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+bool DynamicLoaderDarwinKernel::ParseKextSummaries(
+ const Address &kext_summary_addr, uint32_t count) {
+ KextImageInfo::collection kext_summaries;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("Kexts-changed breakpoint hit, there are %d kexts currently.\n",
+ count);
- if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
- return false;
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the user requested no
- // kext loading, don't print any messages about kexts & don't try to read them.
- const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
-
- // By default, all kexts we've loaded in the past are marked as "remove" and all of the kexts
- // we just found out about from ReadKextSummaries are marked as "add".
- std::vector<bool> to_be_removed(m_known_kexts.size(), true);
- std::vector<bool> to_be_added(count, true);
-
- int number_of_new_kexts_being_added = 0;
- int number_of_old_kexts_being_removed = m_known_kexts.size();
-
- const uint32_t new_kexts_size = kext_summaries.size();
- const uint32_t old_kexts_size = m_known_kexts.size();
-
- // The m_known_kexts vector may have entries that have been Cleared,
- // or are a kernel.
- for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
- {
- bool ignore = false;
- KextImageInfo &image_info = m_known_kexts[old_kext];
- if (image_info.IsKernel())
- {
- ignore = true;
- }
- else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS && !image_info.GetModule())
- {
- ignore = true;
- }
+ if (!ReadKextSummaries(kext_summary_addr, count, kext_summaries))
+ return false;
- if (ignore)
- {
- number_of_old_kexts_being_removed--;
- to_be_removed[old_kext] = false;
- }
+ // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the
+ // user requested no
+ // kext loading, don't print any messages about kexts & don't try to read
+ // them.
+ const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
+
+ // By default, all kexts we've loaded in the past are marked as "remove" and
+ // all of the kexts
+ // we just found out about from ReadKextSummaries are marked as "add".
+ std::vector<bool> to_be_removed(m_known_kexts.size(), true);
+ std::vector<bool> to_be_added(count, true);
+
+ int number_of_new_kexts_being_added = 0;
+ int number_of_old_kexts_being_removed = m_known_kexts.size();
+
+ const uint32_t new_kexts_size = kext_summaries.size();
+ const uint32_t old_kexts_size = m_known_kexts.size();
+
+ // The m_known_kexts vector may have entries that have been Cleared,
+ // or are a kernel.
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
+ bool ignore = false;
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ if (image_info.IsKernel()) {
+ ignore = true;
+ } else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
+ !image_info.GetModule()) {
+ ignore = true;
}
- // Scan over the list of kexts we just read from the kernel, note those that
- // need to be added and those already loaded.
- for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++)
- {
- bool add_this_one = true;
- for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
- {
- if (m_known_kexts[old_kext] == kext_summaries[new_kext])
- {
- // We already have this kext, don't re-load it.
- to_be_added[new_kext] = false;
- // This kext is still present, do not remove it.
- to_be_removed[old_kext] = false;
-
- number_of_old_kexts_being_removed--;
- add_this_one = false;
- break;
- }
- }
- if (add_this_one)
- {
- number_of_new_kexts_being_added++;
- }
+ if (ignore) {
+ number_of_old_kexts_being_removed--;
+ to_be_removed[old_kext] = false;
}
-
- if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
- return true;
-
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- if (s && load_kexts)
- {
- if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
- {
- s->Printf ("Loading %d kext modules and unloading %d kext modules ", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
- }
- else if (number_of_new_kexts_being_added > 0)
- {
- s->Printf ("Loading %d kext modules ", number_of_new_kexts_being_added);
- }
- else if (number_of_old_kexts_being_removed > 0)
- {
- s->Printf ("Unloading %d kext modules ", number_of_old_kexts_being_removed);
- }
+ }
+
+ // Scan over the list of kexts we just read from the kernel, note those that
+ // need to be added and those already loaded.
+ for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++) {
+ bool add_this_one = true;
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
+ if (m_known_kexts[old_kext] == kext_summaries[new_kext]) {
+ // We already have this kext, don't re-load it.
+ to_be_added[new_kext] = false;
+ // This kext is still present, do not remove it.
+ to_be_removed[old_kext] = false;
+
+ number_of_old_kexts_being_removed--;
+ add_this_one = false;
+ break;
+ }
}
-
- if (log)
- {
- if (load_kexts)
- {
- log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
- }
- else
- {
- log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is disabled, else would have %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
- }
+ if (add_this_one) {
+ number_of_new_kexts_being_added++;
}
+ }
+ if (number_of_new_kexts_being_added == 0 &&
+ number_of_old_kexts_being_removed == 0)
+ return true;
- if (number_of_new_kexts_being_added > 0)
- {
- ModuleList loaded_module_list;
-
- 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)
- {
- KextImageInfo &image_info = kext_summaries[new_kext];
- if (load_kexts)
- {
- if (!image_info.LoadImageUsingMemoryModule (m_process))
- {
- image_info.LoadImageAtFileAddress (m_process);
- }
- }
+ Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ if (s && load_kexts) {
+ if (number_of_new_kexts_being_added > 0 &&
+ number_of_old_kexts_being_removed > 0) {
+ s->Printf("Loading %d kext modules and unloading %d kext modules ",
+ number_of_new_kexts_being_added,
+ number_of_old_kexts_being_removed);
+ } else if (number_of_new_kexts_being_added > 0) {
+ s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added);
+ } else if (number_of_old_kexts_being_removed > 0) {
+ s->Printf("Unloading %d kext modules ",
+ number_of_old_kexts_being_removed);
+ }
+ }
+
+ if (log) {
+ if (load_kexts) {
+ log->Printf("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts "
+ "added, %d kexts removed",
+ number_of_new_kexts_being_added,
+ number_of_old_kexts_being_removed);
+ } else {
+ log->Printf(
+ "DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is "
+ "disabled, else would have %d kexts added, %d kexts removed",
+ number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
+ }
+
+ if (number_of_new_kexts_being_added > 0) {
+ ModuleList loaded_module_list;
+
+ 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) {
+ KextImageInfo &image_info = kext_summaries[new_kext];
+ if (load_kexts) {
+ if (!image_info.LoadImageUsingMemoryModule(m_process)) {
+ image_info.LoadImageAtFileAddress(m_process);
+ }
+ }
- m_known_kexts.push_back(image_info);
+ m_known_kexts.push_back(image_info);
- if (image_info.GetModule() && m_process->GetStopID() == image_info.GetProcessStopId())
- loaded_module_list.AppendIfNeeded (image_info.GetModule());
+ if (image_info.GetModule() &&
+ m_process->GetStopID() == image_info.GetProcessStopId())
+ loaded_module_list.AppendIfNeeded(image_info.GetModule());
- if (s && load_kexts)
- s->Printf (".");
+ if (s && load_kexts)
+ s->Printf(".");
- if (log)
- kext_summaries[new_kext].PutToLog (log);
- }
- }
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+ if (log)
+ kext_summaries[new_kext].PutToLog(log);
+ }
}
-
- if (number_of_old_kexts_being_removed > 0)
- {
- ModuleList loaded_module_list;
- const uint32_t num_of_old_kexts = m_known_kexts.size();
- for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++)
- {
- ModuleList unloaded_module_list;
- if (to_be_removed[old_kext])
- {
- KextImageInfo &image_info = m_known_kexts[old_kext];
- // You can't unload the kernel.
- if (!image_info.IsKernel())
- {
- if (image_info.GetModule())
- {
- unloaded_module_list.AppendIfNeeded (image_info.GetModule());
- }
- if (s)
- s->Printf (".");
- image_info.Clear();
- // should pull it out of the KextImageInfos vector but that would mutate the list and invalidate
- // the to_be_removed bool vector; leaving it in place once Cleared() is relatively harmless.
- }
- }
- m_process->GetTarget().ModulesDidUnload (unloaded_module_list, false);
+ m_process->GetTarget().ModulesDidLoad(loaded_module_list);
+ }
+
+ if (number_of_old_kexts_being_removed > 0) {
+ ModuleList loaded_module_list;
+ const uint32_t num_of_old_kexts = m_known_kexts.size();
+ for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++) {
+ ModuleList unloaded_module_list;
+ if (to_be_removed[old_kext]) {
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ // You can't unload the kernel.
+ if (!image_info.IsKernel()) {
+ if (image_info.GetModule()) {
+ unloaded_module_list.AppendIfNeeded(image_info.GetModule());
+ }
+ if (s)
+ s->Printf(".");
+ image_info.Clear();
+ // should pull it out of the KextImageInfos vector but that would
+ // mutate the list and invalidate
+ // the to_be_removed bool vector; leaving it in place once Cleared()
+ // is relatively harmless.
}
+ }
+ m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
}
+ }
- if (s && load_kexts)
- {
- s->Printf (" done.\n");
- s->Flush ();
- }
+ if (s && load_kexts) {
+ s->Printf(" done.\n");
+ s->Flush();
+ }
- return true;
+ return true;
}
-uint32_t
-DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
- uint32_t image_infos_count,
- KextImageInfo::collection &image_infos)
-{
- const ByteOrder endian = m_kernel.GetByteOrder();
- const uint32_t addr_size = m_kernel.GetAddressByteSize();
-
- image_infos.resize(image_infos_count);
- const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
- DataBufferHeap data(count, 0);
- Error error;
-
- const bool prefer_file_cache = false;
- const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
- prefer_file_cache,
- data.GetBytes(),
- data.GetByteSize(),
- error);
- if (bytes_read == count)
- {
-
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
- uint32_t i=0;
- for (uint32_t kext_summary_offset = 0;
- i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
- ++i, kext_summary_offset += m_kext_summary_header.entry_size)
- {
- lldb::offset_t offset = kext_summary_offset;
- const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
- if (name_data == NULL)
- break;
- image_infos[i].SetName ((const char *) name_data);
- UUID uuid (extractor.GetData (&offset, 16), 16);
- image_infos[i].SetUUID (uuid);
- image_infos[i].SetLoadAddress (extractor.GetU64(&offset));
- image_infos[i].SetSize (extractor.GetU64(&offset));
- }
- if (i < image_infos.size())
- image_infos.resize(i);
- }
- else
- {
- image_infos.clear();
+uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
+ const Address &kext_summary_addr, uint32_t image_infos_count,
+ KextImageInfo::collection &image_infos) {
+ const ByteOrder endian = m_kernel.GetByteOrder();
+ const uint32_t addr_size = m_kernel.GetAddressByteSize();
+
+ image_infos.resize(image_infos_count);
+ const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
+ DataBufferHeap data(count, 0);
+ Error error;
+
+ const bool prefer_file_cache = false;
+ const size_t bytes_read = m_process->GetTarget().ReadMemory(
+ kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
+ error);
+ if (bytes_read == count) {
+
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
+ addr_size);
+ uint32_t i = 0;
+ for (uint32_t kext_summary_offset = 0;
+ i < image_infos.size() &&
+ extractor.ValidOffsetForDataOfSize(kext_summary_offset,
+ m_kext_summary_header.entry_size);
+ ++i, kext_summary_offset += m_kext_summary_header.entry_size) {
+ lldb::offset_t offset = kext_summary_offset;
+ const void *name_data =
+ extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
+ if (name_data == NULL)
+ break;
+ image_infos[i].SetName((const char *)name_data);
+ UUID uuid(extractor.GetData(&offset, 16), 16);
+ image_infos[i].SetUUID(uuid);
+ image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
+ image_infos[i].SetSize(extractor.GetU64(&offset));
}
- return image_infos.size();
+ if (i < image_infos.size())
+ image_infos.resize(i);
+ } else {
+ image_infos.clear();
+ }
+ return image_infos.size();
}
-bool
-DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (ReadKextSummaryHeader ())
- {
- if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
- {
- Address summary_addr (m_kext_summary_header_addr);
- summary_addr.Slide(m_kext_summary_header.GetSize());
- if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
- {
- m_known_kexts.clear();
- }
- return true;
- }
+bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ if (ReadKextSummaryHeader()) {
+ if (m_kext_summary_header.entry_count > 0 &&
+ m_kext_summary_header_addr.IsValid()) {
+ Address summary_addr(m_kext_summary_header_addr);
+ summary_addr.Slide(m_kext_summary_header.GetSize());
+ if (!ParseKextSummaries(summary_addr,
+ m_kext_summary_header.entry_count)) {
+ m_known_kexts.clear();
+ }
+ return true;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::KextImageInfo::PutToLog (Log *log) const
-{
- if (log == NULL)
- return;
- const uint8_t *u = (uint8_t *) m_uuid.GetBytes();
-
- if (m_load_address == LLDB_INVALID_ADDRESS)
- {
- if (u)
- {
- log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- m_name.c_str());
- }
- else
- log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
- }
- else
- {
- if (u)
- {
- log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
- m_load_address, m_size,
- u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
- m_name.c_str());
- }
- else
- {
- log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
- m_load_address, m_load_address+m_size, m_name.c_str());
- }
+void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
+ const uint8_t *u = (uint8_t *)m_uuid.GetBytes();
+
+ if (m_load_address == LLDB_INVALID_ADDRESS) {
+ if (u) {
+ log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2."
+ "2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
+ u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9],
+ u[10], u[11], u[12], u[13], u[14], u[15], m_name.c_str());
+ } else
+ log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
+ } else {
+ if (u) {
+ log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64
+ " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
+ "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
+ m_load_address, m_size, u[0], u[1], u[2], u[3], u[4], u[5],
+ u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14],
+ u[15], m_name.c_str());
+ } else {
+ log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
+ m_load_address, m_load_address + m_size, m_name.c_str());
}
+ }
}
//----------------------------------------------------------------------
// Dump the _dyld_all_image_infos members and all current image infos
// that we have parsed to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::PutToLog(Log *log) const
-{
- if (log == NULL)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64 " { version=%u, entry_size=%u, entry_count=%u }",
- m_kext_summary_header_addr.GetFileAddress(),
- m_kext_summary_header.version,
- m_kext_summary_header.entry_size,
- m_kext_summary_header.entry_count);
-
- size_t i;
- const size_t count = m_known_kexts.size();
- if (count > 0)
- {
- log->PutCString("Loaded:");
- for (i = 0; i<count; i++)
- m_known_kexts[i].PutToLog(log);
- }
+void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64
+ " { version=%u, entry_size=%u, entry_count=%u }",
+ m_kext_summary_header_addr.GetFileAddress(),
+ m_kext_summary_header.version, m_kext_summary_header.entry_size,
+ m_kext_summary_header.entry_count);
+
+ size_t i;
+ const size_t count = m_known_kexts.size();
+ if (count > 0) {
+ log->PutCString("Loaded:");
+ for (i = 0; i < count; i++)
+ m_known_kexts[i].PutToLog(log);
+ }
}
-void
-DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
-{
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
- Clear(true);
- m_process = process;
+void DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) {
+ DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
+ __FUNCTION__, StateAsCString(m_process->GetState()));
+ Clear(true);
+ m_process = process;
}
-void
-DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
-{
- if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule())
- {
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
-
-
- const bool internal_bp = true;
- const bool hardware = false;
- const LazyBool skip_prologue = eLazyBoolNo;
- FileSpecList module_spec_list;
- module_spec_list.Append (m_kernel.GetModule()->GetFileSpec());
- Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
- NULL,
- "OSKextLoadedKextSummariesUpdated",
- eFunctionNameTypeFull,
- eLanguageTypeUnknown,
- 0,
- skip_prologue,
- internal_bp,
- hardware).get();
-
- bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
- m_break_id = bp->GetID();
- }
+void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded() {
+ if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule()) {
+ DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
+ __FUNCTION__, StateAsCString(m_process->GetState()));
+
+ const bool internal_bp = true;
+ const bool hardware = false;
+ const LazyBool skip_prologue = eLazyBoolNo;
+ FileSpecList module_spec_list;
+ module_spec_list.Append(m_kernel.GetModule()->GetFileSpec());
+ Breakpoint *bp =
+ m_process->GetTarget()
+ .CreateBreakpoint(&module_spec_list, NULL,
+ "OSKextLoadedKextSummariesUpdated",
+ eFunctionNameTypeFull, eLanguageTypeUnknown, 0,
+ skip_prologue, internal_bp, hardware)
+ .get();
+
+ bp->SetCallback(DynamicLoaderDarwinKernel::BreakpointHitCallback, this,
+ true);
+ m_break_id = bp->GetID();
+ }
}
//----------------------------------------------------------------------
// Member function that gets called when the process state changes.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
-{
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
- switch (state)
- {
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear(false);
- break;
-
- case eStateStopped:
- UpdateIfNeeded();
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
- }
+void DynamicLoaderDarwinKernel::PrivateProcessStateChanged(Process *process,
+ StateType state) {
+ DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__,
+ StateAsCString(state));
+ switch (state) {
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateDetached:
+ Clear(false);
+ break;
+
+ case eStateStopped:
+ UpdateIfNeeded();
+ break;
+
+ case eStateRunning:
+ case eStateStepping:
+ case eStateCrashed:
+ case eStateSuspended:
+ break;
+ }
}
ThreadPlanSP
-DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- ThreadPlanSP thread_plan_sp;
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- log->Printf ("Could not find symbol for step through.");
- return thread_plan_sp;
+DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) {
+ ThreadPlanSP thread_plan_sp;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf("Could not find symbol for step through.");
+ return thread_plan_sp;
}
-Error
-DynamicLoaderDarwinKernel::CanLoadImage ()
-{
- Error error;
- error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
- return error;
+Error DynamicLoaderDarwinKernel::CanLoadImage() {
+ Error error;
+ error.SetErrorString(
+ "always unsafe to load or unload shared libraries in the darwin kernel");
+ return error;
}
-void
-DynamicLoaderDarwinKernel::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
+void DynamicLoaderDarwinKernel::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
}
-void
-DynamicLoaderDarwinKernel::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void DynamicLoaderDarwinKernel::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-void
-DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
-{
- if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForDynamicLoaderPlugin (debugger,
- GetGlobalProperties()->GetValueProperties(),
- ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."),
- is_global_setting);
- }
+void DynamicLoaderDarwinKernel::DebuggerInitialize(
+ lldb_private::Debugger &debugger) {
+ if (!PluginManager::GetSettingForDynamicLoaderPlugin(
+ debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForDynamicLoaderPlugin(
+ debugger, GetGlobalProperties()->GetValueProperties(),
+ ConstString("Properties for the DynamicLoaderDarwinKernel plug-in."),
+ is_global_setting);
+ }
}
-lldb_private::ConstString
-DynamicLoaderDarwinKernel::GetPluginNameStatic()
-{
- static ConstString g_name("darwin-kernel");
- return g_name;
+lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginNameStatic() {
+ static ConstString g_name("darwin-kernel");
+ return g_name;
}
-const char *
-DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
+const char *DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library loads/unloads "
+ "in the MacOSX kernel.";
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-DynamicLoaderDarwinKernel::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-DynamicLoaderDarwinKernel::GetPluginVersion()
-{
- return 1;
-}
+uint32_t DynamicLoaderDarwinKernel::GetPluginVersion() { return 1; }
lldb::ByteOrder
-DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
-{
- switch (magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- return endian::InlHostByteOrder();
-
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- return lldb::eByteOrderLittle;
- else
- return lldb::eByteOrderBig;
-
- default:
- break;
- }
- return lldb::eByteOrderInvalid;
-}
+DynamicLoaderDarwinKernel::GetByteOrderFromMagic(uint32_t magic) {
+ switch (magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_MAGIC_64:
+ return endian::InlHostByteOrder();
+ case llvm::MachO::MH_CIGAM:
+ case llvm::MachO::MH_CIGAM_64:
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ return lldb::eByteOrderLittle;
+ else
+ return lldb::eByteOrderBig;
+
+ default:
+ break;
+ }
+ return lldb::eByteOrderInvalid;
+}
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index 47fba086a4a9..695a4eaf881a 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -18,354 +18,288 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
-class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
-{
+class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
public:
- DynamicLoaderDarwinKernel(lldb_private::Process *process, lldb::addr_t kernel_addr);
+ DynamicLoaderDarwinKernel(lldb_private::Process *process,
+ lldb::addr_t kernel_addr);
- ~DynamicLoaderDarwinKernel() override;
+ ~DynamicLoaderDarwinKernel() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- static void
- DebuggerInitialize (lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- static lldb::addr_t
- SearchForDarwinKernel (lldb_private::Process *process);
+ static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void
- DidAttach() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- void
- PrivateInitialize (lldb_private::Process *process);
+ void PrivateInitialize(lldb_private::Process *process);
+
+ void PrivateProcessStateChanged(lldb_private::Process *process,
+ lldb::StateType state);
+
+ void UpdateIfNeeded();
+
+ void LoadKernelModuleIfNeeded();
+
+ void Clear(bool clear_process);
+
+ void PutToLog(lldb_private::Log *log) const;
+
+ static bool
+ BreakpointHitCallback(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+ uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
+
+ static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
+
+ enum {
+ KERNEL_MODULE_MAX_NAME = 64u,
+ // Versions less than 2 didn't have an entry size,
+ // they had a 64 bit name, 16 byte UUID, 8 byte addr,
+ // 8 byte size, 8 byte version, 4 byte load tag, and
+ // 4 byte flags
+ KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
+ };
+
+ // class KextImageInfo represents a single kext or kernel binary image.
+ // The class was designed to hold the information from the
+ // OSKextLoadedKextSummary
+ // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel
+ // maintains
+ // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
+ // structure,
+ // which points to an array of OSKextLoadedKextSummary's).
+ //
+ // A KextImageInfos may have -
+ //
+ // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
+ // (read straight out of the kernel's list-of-kexts loaded)
+ // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
+ // (very unlikely to have any symbolic information)
+ // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
+ // info
+ // or a dSYM
+ //
+ // For performance reasons, the developer may prefer that lldb not load the
+ // kexts out
+ // of memory at the start of a kernel session. But we should build up /
+ // maintain a
+ // list of kexts that the kernel has told us about so we can relocate a kext
+ // module
+ // later if the user explicitly adds it to the target.
+
+ class KextImageInfo {
+ public:
+ KextImageInfo()
+ : m_name(), m_module_sp(), m_memory_module_sp(),
+ m_load_process_stop_id(UINT32_MAX), m_uuid(),
+ m_load_address(LLDB_INVALID_ADDRESS), m_size(0),
+ m_kernel_image(false) {}
+
+ void Clear() {
+ m_load_address = LLDB_INVALID_ADDRESS;
+ m_size = 0;
+ m_name.clear();
+ m_uuid.Clear();
+ m_module_sp.reset();
+ m_memory_module_sp.reset();
+ m_load_process_stop_id = UINT32_MAX;
+ }
+
+ bool LoadImageAtFileAddress(lldb_private::Process *process);
+
+ bool LoadImageUsingMemoryModule(lldb_private::Process *process);
+
+ bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
+
+ void SetLoadAddress(
+ lldb::addr_t load_addr); // Address of the Mach-O header for this binary
+
+ lldb::addr_t
+ GetLoadAddress() const; // Address of the Mach-O header for this binary
+
+ lldb_private::UUID GetUUID() const;
+
+ void SetUUID(const lldb_private::UUID &uuid);
- void
- PrivateProcessStateChanged (lldb_private::Process *process,
- lldb::StateType state);
+ void SetName(const char *);
- void
- UpdateIfNeeded();
+ std::string GetName() const;
- void
- LoadKernelModuleIfNeeded ();
+ void SetModule(lldb::ModuleSP module);
- void
- Clear (bool clear_process);
+ lldb::ModuleSP GetModule();
- void
- PutToLog (lldb_private::Log *log) const;
+ // try to fill in m_memory_module_sp from memory based on the m_load_address
+ bool ReadMemoryModule(lldb_private::Process *process);
- static bool
- BreakpointHitCallback (void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
+ bool IsKernel()
+ const; // true if this is the mach_kernel; false if this is a kext
+
+ void SetIsKernel(bool is_kernel);
+
+ uint64_t GetSize() const;
+
+ void SetSize(uint64_t size);
- bool
- BreakpointHit (lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
uint32_t
- GetAddrByteSize()
- {
- return m_kernel.GetAddressByteSize();
+ GetProcessStopId() const; // the stop-id when this binary was first noticed
+
+ void SetProcessStopId(uint32_t stop_id);
+
+ bool operator==(const KextImageInfo &rhs);
+
+ uint32_t GetAddressByteSize(); // as determined by Mach-O header
+
+ lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
+
+ lldb_private::ArchSpec
+ GetArchitecture() const; // as determined by Mach-O header
+
+ void PutToLog(lldb_private::Log *log) const;
+
+ typedef std::vector<KextImageInfo> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ private:
+ std::string m_name;
+ lldb::ModuleSP m_module_sp;
+ lldb::ModuleSP m_memory_module_sp;
+ uint32_t m_load_process_stop_id; // the stop-id when this module was added
+ // to the Target
+ lldb_private::UUID
+ m_uuid; // UUID for this dylib if it has one, else all zeros
+ lldb::addr_t m_load_address;
+ uint64_t m_size;
+ bool m_kernel_image; // true if this is the kernel, false if this is a kext
+ };
+
+ struct OSKextLoadedKextSummaryHeader {
+ uint32_t version;
+ uint32_t entry_size;
+ uint32_t entry_count;
+ lldb::addr_t image_infos_addr;
+
+ OSKextLoadedKextSummaryHeader()
+ : version(0), entry_size(0), entry_count(0),
+ image_infos_addr(LLDB_INVALID_ADDRESS) {}
+
+ uint32_t GetSize() {
+ switch (version) {
+ case 0:
+ return 0; // Can't know the size without a valid version
+ case 1:
+ return 8; // Version 1 only had a version + entry_count
+ default:
+ break;
+ }
+ // Version 2 and above has version, entry_size, entry_count, and reserved
+ return 16;
}
- static lldb::ByteOrder
- GetByteOrderFromMagic (uint32_t magic);
-
- enum
- {
- KERNEL_MODULE_MAX_NAME = 64u,
- // Versions less than 2 didn't have an entry size,
- // they had a 64 bit name, 16 byte UUID, 8 byte addr,
- // 8 byte size, 8 byte version, 4 byte load tag, and
- // 4 byte flags
- KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
- };
-
- // class KextImageInfo represents a single kext or kernel binary image.
- // The class was designed to hold the information from the OSKextLoadedKextSummary
- // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel maintains
- // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader structure,
- // which points to an array of OSKextLoadedKextSummary's).
- //
- // A KextImageInfos may have -
- //
- // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
- // (read straight out of the kernel's list-of-kexts loaded)
- // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
- // (very unlikely to have any symbolic information)
- // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug info
- // or a dSYM
- //
- // For performance reasons, the developer may prefer that lldb not load the kexts out
- // of memory at the start of a kernel session. But we should build up / maintain a
- // list of kexts that the kernel has told us about so we can relocate a kext module
- // later if the user explicitly adds it to the target.
-
- class KextImageInfo
- {
- public:
- KextImageInfo () :
- m_name (),
- m_module_sp (),
- m_memory_module_sp (),
- m_load_process_stop_id (UINT32_MAX),
- m_uuid (),
- m_load_address (LLDB_INVALID_ADDRESS),
- m_size (0),
- m_kernel_image (false)
- { }
-
- void
- Clear ()
- {
- m_load_address = LLDB_INVALID_ADDRESS;
- m_size = 0;
- m_name.clear ();
- m_uuid.Clear();
- m_module_sp.reset();
- m_memory_module_sp.reset();
- m_load_process_stop_id = UINT32_MAX;
- }
-
- bool
- LoadImageAtFileAddress (lldb_private::Process *process);
-
- bool
- LoadImageUsingMemoryModule (lldb_private::Process *process);
-
- bool
- IsLoaded ()
- {
- return m_load_process_stop_id != UINT32_MAX;
- }
-
- void
- SetLoadAddress (lldb::addr_t load_addr); // Address of the Mach-O header for this binary
-
- lldb::addr_t
- GetLoadAddress () const; // Address of the Mach-O header for this binary
-
- lldb_private::UUID
- GetUUID () const;
-
- void
- SetUUID (const lldb_private::UUID &uuid);
-
- void
- SetName (const char *);
-
- std::string
- GetName () const;
-
- void
- SetModule (lldb::ModuleSP module);
-
- lldb::ModuleSP
- GetModule ();
-
- // try to fill in m_memory_module_sp from memory based on the m_load_address
- bool
- ReadMemoryModule (lldb_private::Process *process);
-
- bool
- IsKernel () const; // true if this is the mach_kernel; false if this is a kext
-
- void
- SetIsKernel (bool is_kernel);
-
- uint64_t
- GetSize () const;
-
- void
- SetSize (uint64_t size);
-
- uint32_t
- GetProcessStopId () const; // the stop-id when this binary was first noticed
-
- void
- SetProcessStopId (uint32_t stop_id);
-
- bool
- operator== (const KextImageInfo &rhs);
-
- uint32_t
- GetAddressByteSize (); // as determined by Mach-O header
-
- lldb::ByteOrder
- GetByteOrder(); // as determined by Mach-O header
-
- lldb_private::ArchSpec
- GetArchitecture () const; // as determined by Mach-O header
-
- void
- PutToLog (lldb_private::Log *log) const;
-
- typedef std::vector<KextImageInfo> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- private:
- std::string m_name;
- lldb::ModuleSP m_module_sp;
- lldb::ModuleSP m_memory_module_sp;
- uint32_t m_load_process_stop_id; // the stop-id when this module was added to the Target
- lldb_private::UUID m_uuid; // UUID for this dylib if it has one, else all zeros
- lldb::addr_t m_load_address;
- uint64_t m_size;
- bool m_kernel_image; // true if this is the kernel, false if this is a kext
- };
-
- struct OSKextLoadedKextSummaryHeader
- {
- uint32_t version;
- uint32_t entry_size;
- uint32_t entry_count;
- lldb::addr_t image_infos_addr;
-
- OSKextLoadedKextSummaryHeader() :
- version (0),
- entry_size (0),
- entry_count (0),
- image_infos_addr (LLDB_INVALID_ADDRESS)
- {
- }
-
- uint32_t
- GetSize()
- {
- switch (version)
- {
- case 0: return 0; // Can't know the size without a valid version
- case 1: return 8; // Version 1 only had a version + entry_count
- default: break;
- }
- // Version 2 and above has version, entry_size, entry_count, and reserved
- return 16;
- }
-
- void
- Clear()
- {
- version = 0;
- entry_size = 0;
- entry_count = 0;
- image_infos_addr = LLDB_INVALID_ADDRESS;
- }
-
- bool
- IsValid() const
- {
- return version >= 1 || version <= 2;
- }
- };
-
- void
- RegisterNotificationCallbacks();
-
- void
- UnregisterNotificationCallbacks();
-
- void
- SetNotificationBreakpointIfNeeded ();
-
- bool
- ReadAllKextSummaries ();
-
- bool
- ReadKextSummaryHeader ();
-
- bool
- ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
- uint32_t count);
-
- void
- UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
+ void Clear() {
+ version = 0;
+ entry_size = 0;
+ entry_count = 0;
+ image_infos_addr = LLDB_INVALID_ADDRESS;
+ }
- uint32_t
- ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
- uint32_t image_infos_count,
- KextImageInfo::collection &image_infos);
+ bool IsValid() const { return version >= 1 || version <= 2; }
+ };
+
+ void RegisterNotificationCallbacks();
+
+ void UnregisterNotificationCallbacks();
+
+ void SetNotificationBreakpointIfNeeded();
+
+ bool ReadAllKextSummaries();
+
+ bool ReadKextSummaryHeader();
+
+ bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
+ uint32_t count);
+
+ void
+ UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
+ uint32_t infos_count,
+ bool update_executable);
+
+ uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
+ uint32_t image_infos_count,
+ KextImageInfo::collection &image_infos);
- static lldb::addr_t
- SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
+ static lldb::addr_t
+ SearchForKernelAtSameLoadAddr(lldb_private::Process *process);
- static lldb::addr_t
- SearchForKernelWithDebugHints (lldb_private::Process *process);
+ static lldb::addr_t
+ SearchForKernelWithDebugHints(lldb_private::Process *process);
- static lldb::addr_t
- SearchForKernelNearPC (lldb_private::Process *process);
+ static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);
- static lldb::addr_t
- SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
+ static lldb::addr_t
+ SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
- static lldb_private::UUID
- CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
+ static lldb_private::UUID
+ CheckForKernelImageAtAddress(lldb::addr_t addr,
+ lldb_private::Process *process);
- lldb::addr_t m_kernel_load_address;
- KextImageInfo m_kernel; // Info about the current kernel image being used
+ lldb::addr_t m_kernel_load_address;
+ KextImageInfo m_kernel; // Info about the current kernel image being used
- lldb_private::Address m_kext_summary_header_ptr_addr;
- lldb_private::Address m_kext_summary_header_addr;
- OSKextLoadedKextSummaryHeader m_kext_summary_header;
- KextImageInfo::collection m_known_kexts;
- mutable std::recursive_mutex m_mutex;
- lldb::user_id_t m_break_id;
+ lldb_private::Address m_kext_summary_header_ptr_addr;
+ lldb_private::Address m_kext_summary_header_addr;
+ OSKextLoadedKextSummaryHeader m_kext_summary_header;
+ KextImageInfo::collection m_known_kexts;
+ mutable std::recursive_mutex m_mutex;
+ lldb::user_id_t m_break_id;
private:
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel);
};
#endif // liblldb_DynamicLoaderDarwinKernel_h_
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 1f77539ca8df..3c64b2ffed3c 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -1,4 +1,4 @@
-//===-- DynamicLoaderHexagon.h ----------------------------------*- C++ -*-===//
+//===-- DynamicLoaderHexagonDYLD.cpp ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,17 +10,17 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "lldb/Core/PluginManager.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
#include "DynamicLoaderHexagonDYLD.h"
@@ -31,562 +31,490 @@ using namespace lldb_private;
//
// Notes about hexagon dynamic loading:
//
-// When we connect to a target we find the dyld breakpoint address. We put a
+// When we connect to a target we find the dyld breakpoint address. We put
+// a
// breakpoint there with a callback 'RendezvousBreakpointHit()'.
//
-// It is possible to find the dyld structure address from the ELF symbol table,
-// but in the case of the simulator it has not been initialized before the
+// It is possible to find the dyld structure address from the ELF symbol
+// table,
+// but in the case of the simulator it has not been initialized before the
// target calls dlinit().
//
-// We can only safely parse the dyld structure after we hit the dyld breakpoint
+// We can only safely parse the dyld structure after we hit the dyld
+// breakpoint
// since at that time we know dlinit() must have been called.
//
// Find the load address of a symbol
-static lldb::addr_t findSymbolAddress( Process *proc, ConstString findName )
-{
- assert( proc != nullptr );
-
- ModuleSP module = proc->GetTarget().GetExecutableModule();
- assert( module.get() != nullptr );
-
- ObjectFile *exe = module->GetObjectFile();
- assert( exe != nullptr );
-
- lldb_private::Symtab *symtab = exe->GetSymtab( );
- assert( symtab != nullptr );
-
- for ( size_t i = 0; i < symtab->GetNumSymbols( ); i++ )
- {
- const Symbol* sym = symtab->SymbolAtIndex( i );
- assert( sym != nullptr );
- const ConstString &symName = sym->GetName( );
-
- if ( ConstString::Compare( findName, symName ) == 0 )
- {
- Address addr = sym->GetAddress();
- return addr.GetLoadAddress( & proc->GetTarget() );
- }
- }
- return LLDB_INVALID_ADDRESS;
-}
+static lldb::addr_t findSymbolAddress(Process *proc, ConstString findName) {
+ assert(proc != nullptr);
-void
-DynamicLoaderHexagonDYLD::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
+ ModuleSP module = proc->GetTarget().GetExecutableModule();
+ assert(module.get() != nullptr);
+
+ ObjectFile *exe = module->GetObjectFile();
+ assert(exe != nullptr);
+
+ lldb_private::Symtab *symtab = exe->GetSymtab();
+ assert(symtab != nullptr);
+
+ for (size_t i = 0; i < symtab->GetNumSymbols(); i++) {
+ const Symbol *sym = symtab->SymbolAtIndex(i);
+ assert(sym != nullptr);
+ const ConstString &symName = sym->GetName();
-void
-DynamicLoaderHexagonDYLD::Terminate()
-{
+ if (ConstString::Compare(findName, symName) == 0) {
+ Address addr = sym->GetAddress();
+ return addr.GetLoadAddress(&proc->GetTarget());
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
}
-lldb_private::ConstString
-DynamicLoaderHexagonDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
+void DynamicLoaderHexagonDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-lldb_private::ConstString
-DynamicLoaderHexagonDYLD::GetPluginNameStatic()
-{
- static ConstString g_name("hexagon-dyld");
- return g_name;
+void DynamicLoaderHexagonDYLD::Terminate() {}
+
+lldb_private::ConstString DynamicLoaderHexagonDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
-const char *
-DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library "
- "loads/unloads in Hexagon processes.";
+lldb_private::ConstString DynamicLoaderHexagonDYLD::GetPluginNameStatic() {
+ static ConstString g_name("hexagon-dyld");
+ return g_name;
}
-uint32_t
-DynamicLoaderHexagonDYLD::GetPluginVersion()
-{
- return 1;
+const char *DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library "
+ "loads/unloads in Hexagon processes.";
}
-DynamicLoader *
-DynamicLoaderHexagonDYLD::CreateInstance(Process *process, bool force)
-{
- bool create = force;
- if (!create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- if (triple_ref.getArch() == llvm::Triple::hexagon)
- create = true;
- }
-
- if (create)
- return new DynamicLoaderHexagonDYLD(process);
- return NULL;
+uint32_t DynamicLoaderHexagonDYLD::GetPluginVersion() { return 1; }
+
+DynamicLoader *DynamicLoaderHexagonDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ if (triple_ref.getArch() == llvm::Triple::hexagon)
+ create = true;
+ }
+
+ if (create)
+ return new DynamicLoaderHexagonDYLD(process);
+ return NULL;
}
DynamicLoaderHexagonDYLD::DynamicLoaderHexagonDYLD(Process *process)
- : DynamicLoader(process)
- , m_rendezvous (process)
- , m_load_offset(LLDB_INVALID_ADDRESS)
- , m_entry_point(LLDB_INVALID_ADDRESS)
- , m_dyld_bid (LLDB_INVALID_BREAK_ID)
-{
+ : DynamicLoader(process), m_rendezvous(process),
+ m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
+ m_dyld_bid(LLDB_INVALID_BREAK_ID) {}
+
+DynamicLoaderHexagonDYLD::~DynamicLoaderHexagonDYLD() {
+ if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
+ m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid);
+ m_dyld_bid = LLDB_INVALID_BREAK_ID;
+ }
}
-DynamicLoaderHexagonDYLD::~DynamicLoaderHexagonDYLD()
-{
- if (m_dyld_bid != LLDB_INVALID_BREAK_ID)
- {
- m_process->GetTarget().RemoveBreakpointByID (m_dyld_bid);
- m_dyld_bid = LLDB_INVALID_BREAK_ID;
- }
-}
+void DynamicLoaderHexagonDYLD::DidAttach() {
+ ModuleSP executable;
+ addr_t load_offset;
-void
-DynamicLoaderHexagonDYLD::DidAttach()
-{
- ModuleSP executable;
- addr_t load_offset;
-
- executable = GetTargetExecutable();
-
- // Find the difference between the desired load address in the elf file
- // and the real load address in memory
- load_offset = ComputeLoadOffset();
-
- // Check that there is a valid executable
- if ( executable.get( ) == nullptr )
- return;
-
- // Disable JIT for hexagon targets because its not supported
- m_process->SetCanJIT(false);
-
- // Enable Interpreting of function call expressions
- m_process->SetCanInterpretFunctionCalls(true);
-
- // Add the current executable to the module list
- ModuleList module_list;
- module_list.Append(executable);
-
- // Map the loaded sections of this executable
- if ( load_offset != LLDB_INVALID_ADDRESS )
- UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
-
- // AD: confirm this?
- // Load into LLDB all of the currently loaded executables in the stub
- LoadAllCurrentModules();
-
- // AD: confirm this?
- // Callback for the target to give it the loaded module list
- m_process->GetTarget().ModulesDidLoad(module_list);
-
- // Try to set a breakpoint at the rendezvous breakpoint.
- // DidLaunch uses ProbeEntry() instead. That sets a breakpoint,
- // at the dyld breakpoint address, with a callback so that when hit,
- // the dyld structure can be parsed.
- if (! SetRendezvousBreakpoint() )
- {
- // fail
- }
-}
+ executable = GetTargetExecutable();
+
+ // Find the difference between the desired load address in the elf file
+ // and the real load address in memory
+ load_offset = ComputeLoadOffset();
+
+ // Check that there is a valid executable
+ if (executable.get() == nullptr)
+ return;
+
+ // Disable JIT for hexagon targets because its not supported
+ m_process->SetCanJIT(false);
+
+ // Enable Interpreting of function call expressions
+ m_process->SetCanInterpretFunctionCalls(true);
-void
-DynamicLoaderHexagonDYLD::DidLaunch()
-{
+ // Add the current executable to the module list
+ ModuleList module_list;
+ module_list.Append(executable);
+
+ // Map the loaded sections of this executable
+ if (load_offset != LLDB_INVALID_ADDRESS)
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
+
+ // AD: confirm this?
+ // Load into LLDB all of the currently loaded executables in the stub
+ LoadAllCurrentModules();
+
+ // AD: confirm this?
+ // Callback for the target to give it the loaded module list
+ m_process->GetTarget().ModulesDidLoad(module_list);
+
+ // Try to set a breakpoint at the rendezvous breakpoint.
+ // DidLaunch uses ProbeEntry() instead. That sets a breakpoint,
+ // at the dyld breakpoint address, with a callback so that when hit,
+ // the dyld structure can be parsed.
+ if (!SetRendezvousBreakpoint()) {
+ // fail
+ }
}
+void DynamicLoaderHexagonDYLD::DidLaunch() {}
+
/// Checks to see if the target module has changed, updates the target
/// accordingly and returns the target executable module.
-ModuleSP
-DynamicLoaderHexagonDYLD::GetTargetExecutable()
-{
- Target &target = m_process->GetTarget();
- ModuleSP executable = target.GetExecutableModule();
-
- // There is no executable
- if (! executable.get())
- return executable;
-
- // The target executable file does not exits
- if (! executable->GetFileSpec().Exists())
- return executable;
-
- // Prep module for loading
- ModuleSpec module_spec(executable->GetFileSpec(), executable->GetArchitecture());
- ModuleSP module_sp (new Module (module_spec));
-
- // Check if the executable has changed and set it to the target executable if they differ.
- if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
- {
- // if the executable has changed ??
- if (module_sp->GetUUID() != executable->GetUUID())
- executable.reset();
- }
- else if (executable->FileHasChanged())
- executable.reset();
-
- if ( executable.get( ) )
- return executable;
-
- // TODO: What case is this code used?
- executable = target.GetSharedModule(module_spec);
- if (executable.get() != target.GetExecutableModulePointer())
- {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded
- const bool get_dependent_images = false;
- target.SetExecutableModule(executable, get_dependent_images);
- }
-
+ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() {
+ Target &target = m_process->GetTarget();
+ ModuleSP executable = target.GetExecutableModule();
+
+ // There is no executable
+ if (!executable.get())
+ return executable;
+
+ // The target executable file does not exits
+ if (!executable->GetFileSpec().Exists())
return executable;
-}
-//AD: Needs to be updated?
-Error
-DynamicLoaderHexagonDYLD::CanLoadImage()
-{
- return Error();
+ // Prep module for loading
+ ModuleSpec module_spec(executable->GetFileSpec(),
+ executable->GetArchitecture());
+ ModuleSP module_sp(new Module(module_spec));
+
+ // Check if the executable has changed and set it to the target executable if
+ // they differ.
+ if (module_sp.get() && module_sp->GetUUID().IsValid() &&
+ executable->GetUUID().IsValid()) {
+ // if the executable has changed ??
+ if (module_sp->GetUUID() != executable->GetUUID())
+ executable.reset();
+ } else if (executable->FileHasChanged())
+ executable.reset();
+
+ if (executable.get())
+ return executable;
+
+ // TODO: What case is this code used?
+ executable = target.GetSharedModule(module_spec);
+ if (executable.get() != target.GetExecutableModulePointer()) {
+ // Don't load dependent images since we are in dyld where we will know
+ // and find out about all images that are loaded
+ const bool get_dependent_images = false;
+ target.SetExecutableModule(executable, get_dependent_images);
+ }
+
+ return executable;
}
-void
-DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module,
- addr_t link_map_addr,
- addr_t base_addr,
- bool base_addr_is_offset)
-{
- Target &target = m_process->GetTarget();
- const SectionList *sections = GetSectionListFromModule(module);
+// AD: Needs to be updated?
+Error DynamicLoaderHexagonDYLD::CanLoadImage() { return Error(); }
- assert(sections && "SectionList missing from loaded module.");
+void DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module,
+ addr_t link_map_addr,
+ addr_t base_addr,
+ bool base_addr_is_offset) {
+ Target &target = m_process->GetTarget();
+ const SectionList *sections = GetSectionListFromModule(module);
- m_loaded_modules[module] = link_map_addr;
+ assert(sections && "SectionList missing from loaded module.");
- const size_t num_sections = sections->GetSize();
+ m_loaded_modules[module] = link_map_addr;
- for (unsigned i = 0; i < num_sections; ++i)
- {
- SectionSP section_sp (sections->GetSectionAtIndex(i));
- lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr;
+ const size_t num_sections = sections->GetSize();
- // AD: 02/05/14
- // since our memory map starts from address 0, we must not ignore
- // sections that load to address 0. This violates the reference
- // ELF spec, however is used for Hexagon.
+ for (unsigned i = 0; i < num_sections; ++i) {
+ SectionSP section_sp(sections->GetSectionAtIndex(i));
+ lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr;
- // If the file address of the section is zero then this is not an
- // allocatable/loadable section (property of ELF sh_addr). Skip it.
-// if (new_load_addr == base_addr)
-// continue;
+ // AD: 02/05/14
+ // since our memory map starts from address 0, we must not ignore
+ // sections that load to address 0. This violates the reference
+ // ELF spec, however is used for Hexagon.
- target.SetSectionLoadAddress(section_sp, new_load_addr);
- }
+ // If the file address of the section is zero then this is not an
+ // allocatable/loadable section (property of ELF sh_addr). Skip it.
+ // if (new_load_addr == base_addr)
+ // continue;
+
+ target.SetSectionLoadAddress(section_sp, new_load_addr);
+ }
}
/// Removes the loaded sections from the target in @p module.
///
/// @param module The module to traverse.
-void
-DynamicLoaderHexagonDYLD::UnloadSections(const ModuleSP module)
-{
- Target &target = m_process->GetTarget();
- const SectionList *sections = GetSectionListFromModule(module);
+void DynamicLoaderHexagonDYLD::UnloadSections(const ModuleSP module) {
+ Target &target = m_process->GetTarget();
+ const SectionList *sections = GetSectionListFromModule(module);
- assert(sections && "SectionList missing from unloaded module.");
+ assert(sections && "SectionList missing from unloaded module.");
- m_loaded_modules.erase(module);
+ m_loaded_modules.erase(module);
- const size_t num_sections = sections->GetSize();
- for (size_t i = 0; i < num_sections; ++i)
- {
- SectionSP section_sp (sections->GetSectionAtIndex(i));
- target.SetSectionUnloaded(section_sp);
- }
+ const size_t num_sections = sections->GetSize();
+ for (size_t i = 0; i < num_sections; ++i) {
+ SectionSP section_sp(sections->GetSectionAtIndex(i));
+ target.SetSectionUnloaded(section_sp);
+ }
}
// Place a breakpoint on <_rtld_debug_state>
-bool
-DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- // This is the original code, which want to look in the rendezvous structure
- // to find the breakpoint address. Its backwards for us, since we can easily
- // find the breakpoint address, since it is exported in our executable.
- // We however know that we cant read the Rendezvous structure until we have hit
- // the breakpoint once.
- const ConstString dyldBpName( "_rtld_debug_state" );
- addr_t break_addr = findSymbolAddress( m_process, dyldBpName );
-
- Target &target = m_process->GetTarget();
-
- // Do not try to set the breakpoint if we don't know where to put it
- if ( break_addr == LLDB_INVALID_ADDRESS )
- {
- if ( log )
- log->Printf( "Unable to locate _rtld_debug_state breakpoint address" );
-
- return false;
- }
-
- // Save the address of the rendezvous structure
- m_rendezvous.SetBreakAddress( break_addr );
-
- // If we haven't set the breakpoint before then set it
- if (m_dyld_bid == LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *dyld_break = target.CreateBreakpoint (break_addr, true, false).get();
- dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
- dyld_break->SetBreakpointKind ("shared-library-event");
- m_dyld_bid = dyld_break->GetID();
-
- // Make sure our breakpoint is at the right address.
- assert
- (
- target.GetBreakpointByID(m_dyld_bid)->
- FindLocationByAddress(break_addr)->
- GetBreakpoint().GetID()
- == m_dyld_bid
- );
-
- if ( log && dyld_break == nullptr )
- log->Printf( "Failed to create _rtld_debug_state breakpoint" );
-
- // check we have successfully set bp
- return (dyld_break != nullptr);
- }
- else
- // rendezvous already set
- return true;
+bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ // This is the original code, which want to look in the rendezvous structure
+ // to find the breakpoint address. Its backwards for us, since we can easily
+ // find the breakpoint address, since it is exported in our executable.
+ // We however know that we cant read the Rendezvous structure until we have
+ // hit
+ // the breakpoint once.
+ const ConstString dyldBpName("_rtld_debug_state");
+ addr_t break_addr = findSymbolAddress(m_process, dyldBpName);
+
+ Target &target = m_process->GetTarget();
+
+ // Do not try to set the breakpoint if we don't know where to put it
+ if (break_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Unable to locate _rtld_debug_state breakpoint address");
+
+ return false;
+ }
+
+ // Save the address of the rendezvous structure
+ m_rendezvous.SetBreakAddress(break_addr);
+
+ // If we haven't set the breakpoint before then set it
+ if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
+ Breakpoint *dyld_break =
+ target.CreateBreakpoint(break_addr, true, false).get();
+ dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_dyld_bid = dyld_break->GetID();
+
+ // Make sure our breakpoint is at the right address.
+ assert(target.GetBreakpointByID(m_dyld_bid)
+ ->FindLocationByAddress(break_addr)
+ ->GetBreakpoint()
+ .GetID() == m_dyld_bid);
+
+ if (log && dyld_break == nullptr)
+ log->Printf("Failed to create _rtld_debug_state breakpoint");
+
+ // check we have successfully set bp
+ return (dyld_break != nullptr);
+ } else
+ // rendezvous already set
+ return true;
}
// We have just hit our breakpoint at <_rtld_debug_state>
-bool
-DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if ( log )
- log->Printf( "Rendezvous breakpoint hit!" );
+ if (log)
+ log->Printf("Rendezvous breakpoint hit!");
- DynamicLoaderHexagonDYLD* dyld_instance = nullptr;
- dyld_instance = static_cast<DynamicLoaderHexagonDYLD*>(baton);
+ DynamicLoaderHexagonDYLD *dyld_instance = nullptr;
+ dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton);
- // if the dyld_instance is still not valid then
- // try to locate it on the symbol table
- if ( !dyld_instance->m_rendezvous.IsValid( ) )
- {
- Process *proc = dyld_instance->m_process;
+ // if the dyld_instance is still not valid then
+ // try to locate it on the symbol table
+ if (!dyld_instance->m_rendezvous.IsValid()) {
+ Process *proc = dyld_instance->m_process;
- const ConstString dyldStructName( "_rtld_debug" );
- addr_t structAddr = findSymbolAddress( proc, dyldStructName );
+ const ConstString dyldStructName("_rtld_debug");
+ addr_t structAddr = findSymbolAddress(proc, dyldStructName);
- if ( structAddr != LLDB_INVALID_ADDRESS )
- {
- dyld_instance->m_rendezvous.SetRendezvousAddress( structAddr );
+ if (structAddr != LLDB_INVALID_ADDRESS) {
+ dyld_instance->m_rendezvous.SetRendezvousAddress(structAddr);
- if ( log )
- log->Printf( "Found _rtld_debug structure @ 0x%08" PRIx64, structAddr );
- }
- else
- {
- if ( log )
- log->Printf( "Unable to resolve the _rtld_debug structure" );
- }
+ if (log)
+ log->Printf("Found _rtld_debug structure @ 0x%08" PRIx64, structAddr);
+ } else {
+ if (log)
+ log->Printf("Unable to resolve the _rtld_debug structure");
}
+ }
- dyld_instance->RefreshModules();
+ dyld_instance->RefreshModules();
- // Return true to stop the target, false to just let the target run.
- return dyld_instance->GetStopWhenImagesChange();
+ // Return true to stop the target, false to just let the target run.
+ return dyld_instance->GetStopWhenImagesChange();
}
/// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
/// of loaded modules.
-void
-DynamicLoaderHexagonDYLD::RefreshModules()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- if (!m_rendezvous.Resolve())
- return;
-
- HexagonDYLDRendezvous::iterator I;
- HexagonDYLDRendezvous::iterator E;
-
- ModuleList &loaded_modules = m_process->GetTarget().GetImages();
-
- if (m_rendezvous.ModulesDidLoad())
- {
- ModuleList new_modules;
-
- E = m_rendezvous.loaded_end();
- for (I = m_rendezvous.loaded_begin(); I != E; ++I)
- {
- FileSpec file(I->path.c_str(), true);
- ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- loaded_modules.AppendIfNeeded( module_sp );
- new_modules.Append(module_sp);
- }
-
- if (log)
- {
- log->Printf( "Target is loading '%s'", I->path.c_str() );
- if (! module_sp.get() )
- log->Printf( "LLDB failed to load '%s'", I->path.c_str() );
- else
- log->Printf( "LLDB successfully loaded '%s'", I->path.c_str() );
- }
-
- }
- m_process->GetTarget().ModulesDidLoad(new_modules);
+void DynamicLoaderHexagonDYLD::RefreshModules() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ if (!m_rendezvous.Resolve())
+ return;
+
+ HexagonDYLDRendezvous::iterator I;
+ HexagonDYLDRendezvous::iterator E;
+
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+ if (m_rendezvous.ModulesDidLoad()) {
+ ModuleList new_modules;
+
+ E = m_rendezvous.loaded_end();
+ for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
+ FileSpec file(I->path, true);
+ ModuleSP module_sp =
+ LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ loaded_modules.AppendIfNeeded(module_sp);
+ new_modules.Append(module_sp);
+ }
+
+ if (log) {
+ log->Printf("Target is loading '%s'", I->path.c_str());
+ if (!module_sp.get())
+ log->Printf("LLDB failed to load '%s'", I->path.c_str());
+ else
+ log->Printf("LLDB successfully loaded '%s'", I->path.c_str());
+ }
}
-
- if (m_rendezvous.ModulesDidUnload())
- {
- ModuleList old_modules;
-
- E = m_rendezvous.unloaded_end();
- for (I = m_rendezvous.unloaded_begin(); I != E; ++I)
- {
- FileSpec file(I->path.c_str(), true);
- ModuleSpec module_spec(file);
- ModuleSP module_sp = loaded_modules.FindFirstModule (module_spec);
-
- if (module_sp.get())
- {
- old_modules.Append(module_sp);
- UnloadSections(module_sp);
- }
-
- if (log)
- log->Printf( "Target is unloading '%s'", I->path.c_str() );
-
- }
- loaded_modules.Remove(old_modules);
- m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ m_process->GetTarget().ModulesDidLoad(new_modules);
+ }
+
+ if (m_rendezvous.ModulesDidUnload()) {
+ ModuleList old_modules;
+
+ E = m_rendezvous.unloaded_end();
+ for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
+ FileSpec file(I->path, true);
+ ModuleSpec module_spec(file);
+ ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
+
+ if (module_sp.get()) {
+ old_modules.Append(module_sp);
+ UnloadSections(module_sp);
+ }
+
+ if (log)
+ log->Printf("Target is unloading '%s'", I->path.c_str());
}
+ loaded_modules.Remove(old_modules);
+ m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ }
}
-//AD: This is very different to the Static Loader code.
+// AD: This is very different to the Static Loader code.
// It may be wise to look over this and its relation to stack
// unwinding.
ThreadPlanSP
-DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
-{
- ThreadPlanSP thread_plan_sp;
-
- StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *sym = context.symbol;
-
- if (sym == NULL || !sym->IsTrampoline())
- return thread_plan_sp;
-
- const ConstString sym_name = sym->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
- if (!sym_name)
- return thread_plan_sp;
-
- SymbolContextList target_symbols;
- Target &target = thread.GetProcess()->GetTarget();
- const ModuleList &images = target.GetImages();
-
- images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
- size_t num_targets = target_symbols.GetSize();
- if (!num_targets)
- return thread_plan_sp;
-
- typedef std::vector<lldb::addr_t> AddressVector;
- AddressVector addrs;
- for (size_t i = 0; i < num_targets; ++i)
- {
- SymbolContext context;
- AddressRange range;
- if (target_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange(eSymbolContextEverything, 0, false, range);
- lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
- if (addr != LLDB_INVALID_ADDRESS)
- addrs.push_back(addr);
- }
- }
+DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) {
+ ThreadPlanSP thread_plan_sp;
- if (addrs.size() > 0)
- {
- AddressVector::iterator start = addrs.begin();
- AddressVector::iterator end = addrs.end();
+ StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
+ const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
+ Symbol *sym = context.symbol;
- std::sort(start, end);
- addrs.erase(std::unique(start, end), end);
- thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
- }
+ if (sym == NULL || !sym->IsTrampoline())
+ return thread_plan_sp;
+
+ const ConstString sym_name = sym->GetMangled().GetName(
+ lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
+ if (!sym_name)
+ return thread_plan_sp;
+
+ SymbolContextList target_symbols;
+ Target &target = thread.GetProcess()->GetTarget();
+ const ModuleList &images = target.GetImages();
+ images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
+ size_t num_targets = target_symbols.GetSize();
+ if (!num_targets)
return thread_plan_sp;
+
+ typedef std::vector<lldb::addr_t> AddressVector;
+ AddressVector addrs;
+ for (size_t i = 0; i < num_targets; ++i) {
+ SymbolContext context;
+ AddressRange range;
+ if (target_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false, range);
+ lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
+ if (addr != LLDB_INVALID_ADDRESS)
+ addrs.push_back(addr);
+ }
+ }
+
+ if (addrs.size() > 0) {
+ AddressVector::iterator start = addrs.begin();
+ AddressVector::iterator end = addrs.end();
+
+ std::sort(start, end);
+ addrs.erase(std::unique(start, end), end);
+ thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
+ }
+
+ return thread_plan_sp;
}
/// Helper for the entry breakpoint callback. Resolves the load addresses
/// of all dependent modules.
-void
-DynamicLoaderHexagonDYLD::LoadAllCurrentModules()
-{
- HexagonDYLDRendezvous::iterator I;
- HexagonDYLDRendezvous::iterator E;
- ModuleList module_list;
-
- if (!m_rendezvous.Resolve())
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address", __FUNCTION__);
- return;
- }
+void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
+ HexagonDYLDRendezvous::iterator I;
+ HexagonDYLDRendezvous::iterator E;
+ ModuleList module_list;
- // The rendezvous class doesn't enumerate the main module, so track
- // that ourselves here.
- ModuleSP executable = GetTargetExecutable();
- m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
-
-
- 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);
- ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- module_list.Append(module_sp);
- }
- else
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::%s failed loading module %s at 0x%" PRIx64,
- __FUNCTION__, module_path, I->base_addr);
- }
+ if (!m_rendezvous.Resolve()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf(
+ "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address",
+ __FUNCTION__);
+ return;
+ }
+
+ // The rendezvous class doesn't enumerate the main module, so track
+ // that ourselves here.
+ ModuleSP executable = GetTargetExecutable();
+ m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
+
+ 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);
+ ModuleSP module_sp =
+ LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ module_list.Append(module_sp);
+ } else {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderHexagonDYLD::%s failed loading module %s at "
+ "0x%" PRIx64,
+ __FUNCTION__, module_path, I->base_addr);
}
+ }
- m_process->GetTarget().ModulesDidLoad(module_list);
+ m_process->GetTarget().ModulesDidLoad(module_list);
}
/// Computes a value for m_load_offset returning the computed address on
/// success and LLDB_INVALID_ADDRESS on failure.
-addr_t
-DynamicLoaderHexagonDYLD::ComputeLoadOffset()
-{
- // Here we could send a GDB packet to know the load offset
- //
- // send: $qOffsets#4b
- // get: Text=0;Data=0;Bss=0
- //
- // Currently qOffsets is not supported by pluginProcessGDBRemote
- //
- return 0;
+addr_t DynamicLoaderHexagonDYLD::ComputeLoadOffset() {
+ // Here we could send a GDB packet to know the load offset
+ //
+ // send: $qOffsets#4b
+ // get: Text=0;Data=0;Bss=0
+ //
+ // Currently qOffsets is not supported by pluginProcessGDBRemote
+ //
+ return 0;
}
// Here we must try to read the entry point directly from
@@ -596,100 +524,97 @@ DynamicLoaderHexagonDYLD::ComputeLoadOffset()
// an alternative is to look at the PC if we can be sure
// that we have connected when the process is at the entry point.
// I dont think that is reliable for us.
-addr_t
-DynamicLoaderHexagonDYLD::GetEntryPoint()
-{
- if (m_entry_point != LLDB_INVALID_ADDRESS)
- return m_entry_point;
- // check we have a valid process
- if ( m_process == nullptr )
- return LLDB_INVALID_ADDRESS;
- // Get the current executable module
- Module & module = *( m_process->GetTarget( ).GetExecutableModule( ).get( ) );
- // Get the object file (elf file) for this module
- lldb_private::ObjectFile &object = *( module.GetObjectFile( ) );
- // Check if the file is executable (ie, not shared object or relocatable)
- if ( object.IsExecutable() )
- {
- // Get the entry point address for this object
- lldb_private::Address entry = object.GetEntryPointAddress( );
- // Return the entry point address
- return entry.GetFileAddress( );
- }
- // No idea so back out
+addr_t DynamicLoaderHexagonDYLD::GetEntryPoint() {
+ if (m_entry_point != LLDB_INVALID_ADDRESS)
+ return m_entry_point;
+ // check we have a valid process
+ if (m_process == nullptr)
return LLDB_INVALID_ADDRESS;
+ // Get the current executable module
+ Module &module = *(m_process->GetTarget().GetExecutableModule().get());
+ // Get the object file (elf file) for this module
+ lldb_private::ObjectFile &object = *(module.GetObjectFile());
+ // Check if the file is executable (ie, not shared object or relocatable)
+ if (object.IsExecutable()) {
+ // Get the entry point address for this object
+ lldb_private::Address entry = object.GetEntryPointAddress();
+ // Return the entry point address
+ return entry.GetFileAddress();
+ }
+ // No idea so back out
+ return LLDB_INVALID_ADDRESS;
}
-const SectionList *
-DynamicLoaderHexagonDYLD::GetSectionListFromModule(const ModuleSP module) const
-{
- SectionList *sections = nullptr;
- if (module.get())
- {
- ObjectFile *obj_file = module->GetObjectFile();
- if (obj_file)
- {
- sections = obj_file->GetSectionList();
- }
+const SectionList *DynamicLoaderHexagonDYLD::GetSectionListFromModule(
+ const ModuleSP module) const {
+ SectionList *sections = nullptr;
+ if (module.get()) {
+ ObjectFile *obj_file = module->GetObjectFile();
+ if (obj_file) {
+ sections = obj_file->GetSectionList();
}
- return sections;
+ }
+ return sections;
}
-static int ReadInt(Process *process, addr_t addr)
-{
- Error error;
- int value = (int)process->ReadUnsignedIntegerFromMemory(addr, sizeof(uint32_t), 0, error);
- if (error.Fail())
- return -1;
- else
- return value;
+static int ReadInt(Process *process, addr_t addr) {
+ Error error;
+ int value = (int)process->ReadUnsignedIntegerFromMemory(
+ addr, sizeof(uint32_t), 0, error);
+ if (error.Fail())
+ return -1;
+ else
+ return value;
}
lldb::addr_t
-DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread,
- lldb::addr_t tls_file_addr)
-{
- auto it = m_loaded_modules.find (module);
- if (it == m_loaded_modules.end())
- return LLDB_INVALID_ADDRESS;
-
- addr_t link_map = it->second;
- if (link_map == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- const HexagonDYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
- if (!metadata.valid)
- return LLDB_INVALID_ADDRESS;
-
- // Get the thread pointer.
- addr_t tp = thread->GetThreadPointer ();
- if (tp == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the module's modid.
- int modid = ReadInt (m_process, link_map + metadata.modid_offset);
- if (modid == -1)
- return LLDB_INVALID_ADDRESS;
-
- // Lookup the DTV stucture for this thread.
- addr_t dtv_ptr = tp + metadata.dtv_offset;
- addr_t dtv = ReadPointer (dtv_ptr);
- if (dtv == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the TLS block for this module.
- addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid;
- addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset);
-
- Module *mod = module.get();
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%i, tls_block=0x%" PRIx64,
- mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block);
-
- if (tls_block == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
- else
- return tls_block + tls_file_addr;
+DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) {
+ auto it = m_loaded_modules.find(module);
+ if (it == m_loaded_modules.end())
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t link_map = it->second;
+ if (link_map == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ const HexagonDYLDRendezvous::ThreadInfo &metadata =
+ m_rendezvous.GetThreadInfo();
+ if (!metadata.valid)
+ return LLDB_INVALID_ADDRESS;
+
+ // Get the thread pointer.
+ addr_t tp = thread->GetThreadPointer();
+ if (tp == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the module's modid.
+ int modid = ReadInt(m_process, link_map + metadata.modid_offset);
+ if (modid == -1)
+ return LLDB_INVALID_ADDRESS;
+
+ // Lookup the DTV structure for this thread.
+ addr_t dtv_ptr = tp + metadata.dtv_offset;
+ addr_t dtv = ReadPointer(dtv_ptr);
+ if (dtv == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the TLS block for this module.
+ addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
+ addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
+
+ Module *mod = module.get();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderHexagonDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%i, tls_block=0x%" PRIx64,
+ mod->GetObjectName().AsCString(""), link_map, tp, modid,
+ tls_block);
+
+ if (tls_block == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ else
+ return tls_block + tls_file_addr;
}
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
index 67c32887d091..05709d07fd67 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
@@ -1,4 +1,4 @@
-//===-- DynamicLoaderHexagon.h ----------------------------------*- C++ -*-===//
+//===-- DynamicLoaderHexagonDYLD.h ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,150 +19,129 @@
#include "HexagonDYLDRendezvous.h"
-class DynamicLoaderHexagonDYLD : public lldb_private::DynamicLoader
-{
+class DynamicLoaderHexagonDYLD : public lldb_private::DynamicLoader {
public:
- DynamicLoaderHexagonDYLD(lldb_private::Process *process);
+ DynamicLoaderHexagonDYLD(lldb_private::Process *process);
- ~DynamicLoaderHexagonDYLD() override;
+ ~DynamicLoaderHexagonDYLD() override;
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance(lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- // DynamicLoader protocol
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // DynamicLoader protocol
+ //------------------------------------------------------------------
- void
- DidAttach() override;
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+ lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- /// Runtime linker rendezvous structure.
- HexagonDYLDRendezvous m_rendezvous;
-
- /// Virtual load address of the inferior process.
- lldb::addr_t m_load_offset;
-
- /// Virtual entry address of the inferior process.
- lldb::addr_t m_entry_point;
-
- /// Rendezvous breakpoint.
- lldb::break_id_t m_dyld_bid;
-
- /// Loaded module list. (link map for each module)
- std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>> m_loaded_modules;
-
- /// Enables a breakpoint on a function called by the runtime
- /// linker each time a module is loaded or unloaded.
- bool
- SetRendezvousBreakpoint();
-
- /// Callback routine which updates the current list of loaded modules based
- /// on the information supplied by the runtime linker.
- static bool
- RendezvousBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
- /// of loaded modules.
- void
- RefreshModules();
-
- /// Updates the load address of every allocatable section in @p module.
- ///
- /// @param module The module to traverse.
- ///
- /// @param link_map_addr The virtual address of the link map for the @p module.
- ///
- /// @param base_addr The virtual base address @p module is loaded at.
- void
- UpdateLoadedSections(lldb::ModuleSP module,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset) override;
-
- /// Removes the loaded sections from the target in @p module.
- ///
- /// @param module The module to traverse.
- void
- UnloadSections(const lldb::ModuleSP module) override;
-
- /// Callback routine invoked when we hit the breakpoint on process entry.
- ///
- /// This routine is responsible for resolving the load addresses of all
- /// dependent modules required by the inferior and setting up the rendezvous
- /// breakpoint.
- static bool
- EntryBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper for the entry breakpoint callback. Resolves the load addresses
- /// of all dependent modules.
- void
- LoadAllCurrentModules();
-
- /// Computes a value for m_load_offset returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- ComputeLoadOffset();
-
- /// Computes a value for m_entry_point returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- GetEntryPoint();
-
- /// Checks to see if the target module has changed, updates the target
- /// accordingly and returns the target executable module.
- lldb::ModuleSP
- GetTargetExecutable();
-
- /// return the address of the Rendezvous breakpoint
- lldb::addr_t
- FindRendezvousBreakpointAddress( );
+ /// Runtime linker rendezvous structure.
+ HexagonDYLDRendezvous m_rendezvous;
+
+ /// Virtual load address of the inferior process.
+ lldb::addr_t m_load_offset;
+
+ /// Virtual entry address of the inferior process.
+ lldb::addr_t m_entry_point;
+
+ /// Rendezvous breakpoint.
+ lldb::break_id_t m_dyld_bid;
+
+ /// Loaded module list. (link map for each module)
+ std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
+ m_loaded_modules;
+
+ /// Enables a breakpoint on a function called by the runtime
+ /// linker each time a module is loaded or unloaded.
+ bool SetRendezvousBreakpoint();
+
+ /// Callback routine which updates the current list of loaded modules based
+ /// on the information supplied by the runtime linker.
+ static bool RendezvousBreakpointHit(
+ void *baton, lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
+ /// of loaded modules.
+ void RefreshModules();
+
+ /// Updates the load address of every allocatable section in @p module.
+ ///
+ /// @param module The module to traverse.
+ ///
+ /// @param link_map_addr The virtual address of the link map for the @p
+ /// module.
+ ///
+ /// @param base_addr The virtual base address @p module is loaded at.
+ void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr,
+ lldb::addr_t base_addr,
+ bool base_addr_is_offset) override;
+
+ /// Removes the loaded sections from the target in @p module.
+ ///
+ /// @param module The module to traverse.
+ void UnloadSections(const lldb::ModuleSP module) override;
+
+ /// Callback routine invoked when we hit the breakpoint on process entry.
+ ///
+ /// This routine is responsible for resolving the load addresses of all
+ /// dependent modules required by the inferior and setting up the rendezvous
+ /// breakpoint.
+ static bool
+ EntryBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper for the entry breakpoint callback. Resolves the load addresses
+ /// of all dependent modules.
+ void LoadAllCurrentModules();
+
+ /// Computes a value for m_load_offset returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t ComputeLoadOffset();
+
+ /// Computes a value for m_entry_point returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t GetEntryPoint();
+
+ /// Checks to see if the target module has changed, updates the target
+ /// accordingly and returns the target executable module.
+ lldb::ModuleSP GetTargetExecutable();
+
+ /// return the address of the Rendezvous breakpoint
+ lldb::addr_t FindRendezvousBreakpointAddress();
private:
- const lldb_private::SectionList *
- GetSectionListFromModule(const lldb::ModuleSP module) const;
+ const lldb_private::SectionList *
+ GetSectionListFromModule(const lldb::ModuleSP module) const;
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderHexagonDYLD);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderHexagonDYLD);
};
#endif // liblldb_DynamicLoaderHexagonDYLD_h_
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index 61f9b3d441ce..da0edc870f86 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -30,375 +30,343 @@ using namespace lldb_private;
/// Locates the address of the rendezvous structure. Returns the address on
/// success and LLDB_INVALID_ADDRESS on failure.
-static addr_t
-ResolveRendezvousAddress(Process *process)
-{
- addr_t info_location;
- addr_t info_addr;
- Error error;
+static addr_t ResolveRendezvousAddress(Process *process) {
+ addr_t info_location;
+ addr_t info_addr;
+ Error error;
- info_location = process->GetImageInfoAddress();
+ info_location = process->GetImageInfoAddress();
- if (info_location == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
+ if (info_location == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
- info_addr = process->ReadPointerFromMemory(info_location, error);
- if (error.Fail())
- return LLDB_INVALID_ADDRESS;
+ info_addr = process->ReadPointerFromMemory(info_location, error);
+ if (error.Fail())
+ return LLDB_INVALID_ADDRESS;
- if (info_addr == 0)
- return LLDB_INVALID_ADDRESS;
+ if (info_addr == 0)
+ return LLDB_INVALID_ADDRESS;
- return info_addr;
+ return info_addr;
}
HexagonDYLDRendezvous::HexagonDYLDRendezvous(Process *process)
- : m_process(process),
- m_rendezvous_addr(LLDB_INVALID_ADDRESS),
- m_current(),
- m_previous(),
- m_soentries(),
- m_added_soentries(),
- m_removed_soentries()
-{
- m_thread_info.valid = false;
-
- // Cache a copy of the executable path
- if (m_process)
- {
- Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
- if (exe_mod)
- exe_mod->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
- }
+ : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(),
+ m_previous(), m_soentries(), m_added_soentries(), m_removed_soentries() {
+ m_thread_info.valid = false;
+
+ // Cache a copy of the executable path
+ if (m_process) {
+ Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
+ if (exe_mod)
+ exe_mod->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
+ }
}
-bool
-HexagonDYLDRendezvous::Resolve()
-{
- const size_t word_size = 4;
- Rendezvous info;
- size_t address_size;
- size_t padding;
- addr_t info_addr;
- addr_t cursor;
+bool HexagonDYLDRendezvous::Resolve() {
+ const size_t word_size = 4;
+ Rendezvous info;
+ size_t address_size;
+ size_t padding;
+ addr_t info_addr;
+ addr_t cursor;
- address_size = m_process->GetAddressByteSize();
- padding = address_size - word_size;
+ address_size = m_process->GetAddressByteSize();
+ padding = address_size - word_size;
- if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
- cursor = info_addr = ResolveRendezvousAddress(m_process);
- else
- cursor = info_addr = m_rendezvous_addr;
-
- if (cursor == LLDB_INVALID_ADDRESS)
- return false;
+ if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
+ cursor = info_addr = ResolveRendezvousAddress(m_process);
+ else
+ cursor = info_addr = m_rendezvous_addr;
- if (!(cursor = ReadWord(cursor, &info.version, word_size)))
- return false;
+ if (cursor == LLDB_INVALID_ADDRESS)
+ return false;
- if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
- return false;
+ if (!(cursor = ReadWord(cursor, &info.version, word_size)))
+ return false;
+
+ if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
+ return false;
- if (!(cursor = ReadPointer(cursor, &info.brk)))
- return false;
+ if (!(cursor = ReadPointer(cursor, &info.brk)))
+ return false;
- if (!(cursor = ReadWord(cursor, &info.state, word_size)))
- return false;
+ if (!(cursor = ReadWord(cursor, &info.state, word_size)))
+ return false;
- if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
- return false;
+ if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
+ return false;
- // The rendezvous was successfully read. Update our internal state.
- m_rendezvous_addr = info_addr;
- m_previous = m_current;
- m_current = info;
+ // The rendezvous was successfully read. Update our internal state.
+ m_rendezvous_addr = info_addr;
+ m_previous = m_current;
+ m_current = info;
- return UpdateSOEntries();
+ return UpdateSOEntries();
}
-void
-HexagonDYLDRendezvous::SetRendezvousAddress( lldb::addr_t addr )
-{
- m_rendezvous_addr = addr;
+void HexagonDYLDRendezvous::SetRendezvousAddress(lldb::addr_t addr) {
+ m_rendezvous_addr = addr;
}
-bool
-HexagonDYLDRendezvous::IsValid()
-{
- return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+bool HexagonDYLDRendezvous::IsValid() {
+ return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
}
-bool
-HexagonDYLDRendezvous::UpdateSOEntries()
-{
- SOEntry entry;
-
- if (m_current.map_addr == 0)
- return false;
-
- // When the previous and current states are consistent this is the first
- // time we have been asked to update. Just take a snapshot of the currently
- // loaded modules.
- if (m_previous.state == eConsistent && m_current.state == eConsistent)
- return TakeSnapshot(m_soentries);
-
- // If we are about to add or remove a shared object clear out the current
- // state and take a snapshot of the currently loaded images.
- if (m_current.state == eAdd || m_current.state == eDelete)
- {
- // this is a fudge so that we can clear the assert below.
- m_previous.state = eConsistent;
- // We hit this assert on the 2nd run of this function after running the calc example
- assert(m_previous.state == eConsistent);
- m_soentries.clear();
- m_added_soentries.clear();
- m_removed_soentries.clear();
- return TakeSnapshot(m_soentries);
- }
- assert(m_current.state == eConsistent);
-
- // Otherwise check the previous state to determine what to expect and update
- // accordingly.
- if (m_previous.state == eAdd)
- return UpdateSOEntriesForAddition();
- else if (m_previous.state == eDelete)
- return UpdateSOEntriesForDeletion();
+bool HexagonDYLDRendezvous::UpdateSOEntries() {
+ SOEntry entry;
+ if (m_current.map_addr == 0)
return false;
+
+ // When the previous and current states are consistent this is the first
+ // time we have been asked to update. Just take a snapshot of the currently
+ // loaded modules.
+ if (m_previous.state == eConsistent && m_current.state == eConsistent)
+ return TakeSnapshot(m_soentries);
+
+ // If we are about to add or remove a shared object clear out the current
+ // state and take a snapshot of the currently loaded images.
+ if (m_current.state == eAdd || m_current.state == eDelete) {
+ // this is a fudge so that we can clear the assert below.
+ m_previous.state = eConsistent;
+ // We hit this assert on the 2nd run of this function after running the calc
+ // example
+ assert(m_previous.state == eConsistent);
+ m_soentries.clear();
+ m_added_soentries.clear();
+ m_removed_soentries.clear();
+ return TakeSnapshot(m_soentries);
+ }
+ assert(m_current.state == eConsistent);
+
+ // Otherwise check the previous state to determine what to expect and update
+ // accordingly.
+ if (m_previous.state == eAdd)
+ return UpdateSOEntriesForAddition();
+ else if (m_previous.state == eDelete)
+ return UpdateSOEntriesForDeletion();
+
+ return false;
}
-
-bool
-HexagonDYLDRendezvous::UpdateSOEntriesForAddition()
-{
- SOEntry entry;
- iterator pos;
-
- assert(m_previous.state == eAdd);
-
- if (m_current.map_addr == 0)
- return false;
-
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
- continue;
-
- pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- {
- m_soentries.push_back(entry);
- m_added_soentries.push_back(entry);
- }
+
+bool HexagonDYLDRendezvous::UpdateSOEntriesForAddition() {
+ SOEntry entry;
+ iterator pos;
+
+ assert(m_previous.state == eAdd);
+
+ if (m_current.map_addr == 0)
+ return false;
+
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ // On Linux this is indicated by an empty path in the entry.
+ // On FreeBSD it is the name of the executable.
+ if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ continue;
+
+ pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end()) {
+ m_soentries.push_back(entry);
+ m_added_soentries.push_back(entry);
}
+ }
- return true;
+ return true;
}
-bool
-HexagonDYLDRendezvous::UpdateSOEntriesForDeletion()
-{
- SOEntryList entry_list;
- iterator pos;
+bool HexagonDYLDRendezvous::UpdateSOEntriesForDeletion() {
+ SOEntryList entry_list;
+ iterator pos;
- assert(m_previous.state == eDelete);
+ assert(m_previous.state == eDelete);
- if (!TakeSnapshot(entry_list))
- return false;
+ if (!TakeSnapshot(entry_list))
+ return false;
- for (iterator I = begin(); I != end(); ++I)
- {
- pos = std::find(entry_list.begin(), entry_list.end(), *I);
- if (pos == entry_list.end())
- m_removed_soentries.push_back(*I);
- }
+ for (iterator I = begin(); I != end(); ++I) {
+ pos = std::find(entry_list.begin(), entry_list.end(), *I);
+ if (pos == entry_list.end())
+ m_removed_soentries.push_back(*I);
+ }
- m_soentries = entry_list;
- return true;
+ m_soentries = entry_list;
+ return true;
}
-bool
-HexagonDYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
-{
- SOEntry entry;
+bool HexagonDYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) {
+ SOEntry entry;
- if (m_current.map_addr == 0)
- return false;
+ if (m_current.map_addr == 0)
+ return false;
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- // Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
- continue;
+ // Only add shared libraries and not the executable.
+ // On Linux this is indicated by an empty path in the entry.
+ // On FreeBSD it is the name of the executable.
+ if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ continue;
- entry_list.push_back(entry);
- }
+ entry_list.push_back(entry);
+ }
- return true;
+ return true;
}
-addr_t
-HexagonDYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size)
-{
- Error error;
+addr_t HexagonDYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst,
+ size_t size) {
+ Error error;
- *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
- if (error.Fail())
- return 0;
+ *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
+ if (error.Fail())
+ return 0;
- return addr + size;
+ return addr + size;
}
-addr_t
-HexagonDYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst)
-{
- Error error;
-
- *dst = m_process->ReadPointerFromMemory(addr, error);
- if (error.Fail())
- return 0;
+addr_t HexagonDYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) {
+ Error error;
+
+ *dst = m_process->ReadPointerFromMemory(addr, error);
+ if (error.Fail())
+ return 0;
- return addr + m_process->GetAddressByteSize();
+ return addr + m_process->GetAddressByteSize();
}
-std::string
-HexagonDYLDRendezvous::ReadStringFromMemory(addr_t addr)
-{
- std::string str;
- Error error;
- size_t size;
- char c;
-
- if (addr == LLDB_INVALID_ADDRESS)
- return std::string();
-
- for (;;) {
- size = m_process->DoReadMemory(addr, &c, 1, error);
- if (size != 1 || error.Fail())
- return std::string();
- if (c == 0)
- break;
- else {
- str.push_back(c);
- addr++;
- }
+std::string HexagonDYLDRendezvous::ReadStringFromMemory(addr_t addr) {
+ std::string str;
+ Error error;
+ size_t size;
+ char c;
+
+ if (addr == LLDB_INVALID_ADDRESS)
+ return std::string();
+
+ for (;;) {
+ size = m_process->DoReadMemory(addr, &c, 1, error);
+ if (size != 1 || error.Fail())
+ return std::string();
+ if (c == 0)
+ break;
+ else {
+ str.push_back(c);
+ addr++;
}
+ }
- return str;
+ return str;
}
-bool
-HexagonDYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
-{
- entry.clear();
- entry.link_addr = addr;
-
- if (!(addr = ReadPointer(addr, &entry.base_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.path_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.next)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.prev)))
- return false;
-
- entry.path = ReadStringFromMemory(entry.path_addr);
-
- return true;
-}
+bool HexagonDYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr,
+ SOEntry &entry) {
+ entry.clear();
+ entry.link_addr = addr;
+
+ if (!(addr = ReadPointer(addr, &entry.base_addr)))
+ return false;
-bool
-HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field, uint32_t& value)
-{
- Target& target = m_process->GetTarget();
+ if (!(addr = ReadPointer(addr, &entry.path_addr)))
+ return false;
- SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType (ConstString(name), eSymbolTypeAny, list))
- return false;
+ if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
+ return false;
- Address address = list[0].symbol->GetAddress();
- addr_t addr = address.GetLoadAddress (&target);
- if (addr == LLDB_INVALID_ADDRESS)
- return false;
+ if (!(addr = ReadPointer(addr, &entry.next)))
+ return false;
- Error error;
- value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(addr + field*sizeof(uint32_t), sizeof(uint32_t), 0, error);
- if (error.Fail())
- return false;
+ if (!(addr = ReadPointer(addr, &entry.prev)))
+ return false;
- if (field == eSize)
- value /= 8; // convert bits to bytes
+ entry.path = ReadStringFromMemory(entry.path_addr);
- return true;
+ return true;
}
-const HexagonDYLDRendezvous::ThreadInfo&
-HexagonDYLDRendezvous::GetThreadInfo()
-{
- if (!m_thread_info.valid)
- {
- bool ok = true;
+bool HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field,
+ uint32_t &value) {
+ Target &target = m_process->GetTarget();
- ok &= FindMetadata ("_thread_db_pthread_dtvp", eOffset, m_thread_info.dtv_offset);
- ok &= FindMetadata ("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
- ok &= FindMetadata ("_thread_db_link_map_l_tls_modid", eOffset, m_thread_info.modid_offset);
- ok &= FindMetadata ("_thread_db_dtv_t_pointer_val", eOffset, m_thread_info.tls_offset);
+ SymbolContextList list;
+ if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list))
+ return false;
- if (ok)
- m_thread_info.valid = true;
- }
+ Address address = list[0].symbol->GetAddress();
+ addr_t addr = address.GetLoadAddress(&target);
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Error error;
+ value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(
+ addr + field * sizeof(uint32_t), sizeof(uint32_t), 0, error);
+ if (error.Fail())
+ return false;
- return m_thread_info;
+ if (field == eSize)
+ value /= 8; // convert bits to bytes
+
+ return true;
}
-void
-HexagonDYLDRendezvous::DumpToLog(Log *log) const
-{
- int state = GetState();
-
- if (!log)
- return;
-
- log->PutCString("HexagonDYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent) ? "consistent" :
- (state == eAdd) ? "add" :
- (state == eDelete) ? "delete" : "unknown");
-
- iterator I = begin();
- iterator E = end();
-
- if (I != E)
- log->PutCString("HexagonDYLDRendezvous SOEntries:");
-
- for (int i = 1; I != E; ++I, ++i)
- {
- log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
- }
+const HexagonDYLDRendezvous::ThreadInfo &
+HexagonDYLDRendezvous::GetThreadInfo() {
+ if (!m_thread_info.valid) {
+ bool ok = true;
+
+ ok &= FindMetadata("_thread_db_pthread_dtvp", eOffset,
+ m_thread_info.dtv_offset);
+ ok &=
+ FindMetadata("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
+ ok &= FindMetadata("_thread_db_link_map_l_tls_modid", eOffset,
+ m_thread_info.modid_offset);
+ ok &= FindMetadata("_thread_db_dtv_t_pointer_val", eOffset,
+ m_thread_info.tls_offset);
+
+ if (ok)
+ m_thread_info.valid = true;
+ }
+
+ return m_thread_info;
+}
+
+void HexagonDYLDRendezvous::DumpToLog(Log *log) const {
+ int state = GetState();
+
+ if (!log)
+ return;
+
+ log->PutCString("HexagonDYLDRendezvous:");
+ log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
+ log->Printf(" Version: %" PRIu64, GetVersion());
+ log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
+ log->Printf(" Break : %" PRIx64, GetBreakAddress());
+ log->Printf(" LDBase : %" PRIx64, GetLDBase());
+ log->Printf(" State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
+ : "unknown");
+
+ iterator I = begin();
+ iterator E = end();
+
+ if (I != E)
+ log->PutCString("HexagonDYLDRendezvous SOEntries:");
+
+ for (int i = 1; I != E; ++I, ++i) {
+ log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
+ log->Printf(" Base : %" PRIx64, I->base_addr);
+ log->Printf(" Path : %" PRIx64, I->path_addr);
+ log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
+ log->Printf(" Next : %" PRIx64, I->next);
+ log->Printf(" Prev : %" PRIx64, I->prev);
+ }
}
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
index cd5121330457..b68f89b9ce83 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
@@ -19,9 +19,8 @@
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
-namespace lldb_private
-{
- class Process;
+namespace lldb_private {
+class Process;
}
/// @class HexagonDYLDRendezvous
@@ -31,249 +30,218 @@ namespace lldb_private
/// runtime liker each time a module is loaded or unloaded. This class provides
/// an interface to this structure and maintains a consistent snapshot of the
/// currently loaded modules.
-class HexagonDYLDRendezvous
-{
-
- // This structure is used to hold the contents of the debug rendezvous
- // information (struct r_debug) as found in the inferiors memory. Note that
- // the layout of this struct is not binary compatible, it is simply large
- // enough to hold the information on both 32 and 64 bit platforms.
- struct Rendezvous {
- uint64_t version;
- lldb::addr_t map_addr;
- lldb::addr_t brk;
- uint64_t state;
- lldb::addr_t ldbase;
-
- Rendezvous()
- : version (0)
- , map_addr(LLDB_INVALID_ADDRESS)
- , brk (LLDB_INVALID_ADDRESS)
- , state (0)
- , ldbase (0)
- { }
-
- };
+class HexagonDYLDRendezvous {
+
+ // This structure is used to hold the contents of the debug rendezvous
+ // information (struct r_debug) as found in the inferiors memory. Note that
+ // the layout of this struct is not binary compatible, it is simply large
+ // enough to hold the information on both 32 and 64 bit platforms.
+ struct Rendezvous {
+ uint64_t version;
+ lldb::addr_t map_addr;
+ lldb::addr_t brk;
+ uint64_t state;
+ lldb::addr_t ldbase;
+
+ Rendezvous()
+ : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
+ state(0), ldbase(0) {}
+ };
public:
- // Various metadata supplied by the inferior's threading library to describe
- // the per-thread state.
- struct ThreadInfo {
- bool valid; // whether we read valid metadata
- uint32_t dtv_offset; // offset of DTV pointer within pthread
- uint32_t dtv_slot_size; // size of one DTV slot
- uint32_t modid_offset; // offset of module ID within link_map
- uint32_t tls_offset; // offset of TLS pointer within DTV slot
- };
-
- HexagonDYLDRendezvous(lldb_private::Process *process);
-
- /// Update the internal snapshot of runtime linker rendezvous and recompute
- /// the currently loaded modules.
- ///
- /// This method should be called once one start up, then once each time the
- /// runtime linker enters the function given by GetBreakAddress().
- ///
- /// @returns true on success and false on failure.
- ///
- /// @see GetBreakAddress().
- bool
- Resolve();
-
- /// @returns true if this rendezvous has been located in the inferiors
- /// address space and false otherwise.
- bool
- IsValid();
-
- /// @returns the address of the rendezvous structure in the inferiors
- /// address space.
- lldb::addr_t
- GetRendezvousAddress() const { return m_rendezvous_addr; }
-
- /// Provide the dyld structure address
- void
- SetRendezvousAddress( lldb::addr_t );
-
- /// @returns the version of the rendezvous protocol being used.
- uint64_t
- GetVersion() const { return m_current.version; }
-
- /// @returns address in the inferiors address space containing the linked
- /// list of shared object descriptors.
- lldb::addr_t
- GetLinkMapAddress() const { return m_current.map_addr; }
-
- /// A breakpoint should be set at this address and Resolve called on each
- /// hit.
- ///
- /// @returns the address of a function called by the runtime linker each
- /// time a module is loaded/unloaded, or about to be loaded/unloaded.
- ///
- /// @see Resolve()
- lldb::addr_t
- GetBreakAddress() const { return m_current.brk; }
-
- /// In hexagon it is possible that we can know the dyld breakpoint without
- /// having to find it from the rendezvous structure
- ///
- void
- SetBreakAddress( lldb::addr_t addr ) { m_current.brk = addr; }
-
- /// Returns the current state of the rendezvous structure.
- uint64_t
- GetState() const { return m_current.state; }
-
- /// @returns the base address of the runtime linker in the inferiors address
- /// space.
- lldb::addr_t
- GetLDBase() const { return m_current.ldbase; }
-
- /// @returns the thread layout metadata from the inferiors thread library.
- const ThreadInfo&
- GetThreadInfo();
-
- /// @returns true if modules have been loaded into the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidLoad() const { return !m_added_soentries.empty(); }
-
- /// @returns true if modules have been unloaded from the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidUnload() const { return !m_removed_soentries.empty(); }
-
- void
- DumpToLog(lldb_private::Log *log) const;
-
- /// @brief Constants describing the state of the rendezvous.
- ///
- /// @see GetState().
- enum RendezvousState
- {
- eConsistent = 0,
- eAdd ,
- eDelete ,
- };
-
- /// @brief Structure representing the shared objects currently loaded into
- /// the inferior process.
- ///
- /// This object is a rough analogue to the struct link_map object which
- /// actually lives in the inferiors memory.
- struct SOEntry {
- lldb::addr_t link_addr; ///< Address of this link_map.
- lldb::addr_t base_addr; ///< Base address of the loaded object.
- lldb::addr_t path_addr; ///< String naming the shared object.
- lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
- lldb::addr_t next; ///< Address of next so_entry.
- lldb::addr_t prev; ///< Address of previous so_entry.
- std::string path; ///< File name of shared object.
-
- SOEntry() { clear(); }
-
- bool operator ==(const SOEntry &entry) {
- return this->path == entry.path;
- }
-
- void clear() {
- link_addr = 0;
- base_addr = 0;
- path_addr = 0;
- dyn_addr = 0;
- next = 0;
- prev = 0;
- path.clear();
- }
- };
+ // Various metadata supplied by the inferior's threading library to describe
+ // the per-thread state.
+ struct ThreadInfo {
+ bool valid; // whether we read valid metadata
+ uint32_t dtv_offset; // offset of DTV pointer within pthread
+ uint32_t dtv_slot_size; // size of one DTV slot
+ uint32_t modid_offset; // offset of module ID within link_map
+ uint32_t tls_offset; // offset of TLS pointer within DTV slot
+ };
+
+ HexagonDYLDRendezvous(lldb_private::Process *process);
+
+ /// Update the internal snapshot of runtime linker rendezvous and recompute
+ /// the currently loaded modules.
+ ///
+ /// This method should be called once one start up, then once each time the
+ /// runtime linker enters the function given by GetBreakAddress().
+ ///
+ /// @returns true on success and false on failure.
+ ///
+ /// @see GetBreakAddress().
+ bool Resolve();
+
+ /// @returns true if this rendezvous has been located in the inferiors
+ /// address space and false otherwise.
+ bool IsValid();
+
+ /// @returns the address of the rendezvous structure in the inferiors
+ /// address space.
+ lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
+
+ /// Provide the dyld structure address
+ void SetRendezvousAddress(lldb::addr_t);
+
+ /// @returns the version of the rendezvous protocol being used.
+ uint64_t GetVersion() const { return m_current.version; }
+
+ /// @returns address in the inferiors address space containing the linked
+ /// list of shared object descriptors.
+ lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
+
+ /// A breakpoint should be set at this address and Resolve called on each
+ /// hit.
+ ///
+ /// @returns the address of a function called by the runtime linker each
+ /// time a module is loaded/unloaded, or about to be loaded/unloaded.
+ ///
+ /// @see Resolve()
+ lldb::addr_t GetBreakAddress() const { return m_current.brk; }
+
+ /// In hexagon it is possible that we can know the dyld breakpoint without
+ /// having to find it from the rendezvous structure
+ ///
+ void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }
+
+ /// Returns the current state of the rendezvous structure.
+ uint64_t GetState() const { return m_current.state; }
+
+ /// @returns the base address of the runtime linker in the inferiors address
+ /// space.
+ lldb::addr_t GetLDBase() const { return m_current.ldbase; }
+
+ /// @returns the thread layout metadata from the inferiors thread library.
+ const ThreadInfo &GetThreadInfo();
+
+ /// @returns true if modules have been loaded into the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
+
+ /// @returns true if modules have been unloaded from the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
+
+ void DumpToLog(lldb_private::Log *log) const;
+
+ /// @brief Constants describing the state of the rendezvous.
+ ///
+ /// @see GetState().
+ enum RendezvousState {
+ eConsistent = 0,
+ eAdd,
+ eDelete,
+ };
+
+ /// @brief Structure representing the shared objects currently loaded into
+ /// the inferior process.
+ ///
+ /// This object is a rough analogue to the struct link_map object which
+ /// actually lives in the inferiors memory.
+ struct SOEntry {
+ lldb::addr_t link_addr; ///< Address of this link_map.
+ lldb::addr_t base_addr; ///< Base address of the loaded object.
+ lldb::addr_t path_addr; ///< String naming the shared object.
+ lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
+ lldb::addr_t next; ///< Address of next so_entry.
+ lldb::addr_t prev; ///< Address of previous so_entry.
+ std::string path; ///< File name of shared object.
+
+ SOEntry() { clear(); }
+
+ bool operator==(const SOEntry &entry) { return this->path == entry.path; }
+
+ void clear() {
+ link_addr = 0;
+ base_addr = 0;
+ path_addr = 0;
+ dyn_addr = 0;
+ next = 0;
+ prev = 0;
+ path.clear();
+ }
+ };
protected:
- typedef std::list<SOEntry> SOEntryList;
+ typedef std::list<SOEntry> SOEntryList;
public:
- typedef SOEntryList::const_iterator iterator;
-
- /// Iterators over all currently loaded modules.
- iterator begin() const { return m_soentries.begin(); }
- iterator end() const { return m_soentries.end(); }
-
- /// Iterators over all modules loaded into the inferior since the last call
- /// to Resolve().
- iterator loaded_begin() const { return m_added_soentries.begin(); }
- iterator loaded_end() const { return m_added_soentries.end(); }
-
- /// Iterators over all modules unloaded from the inferior since the last
- /// call to Resolve().
- iterator unloaded_begin() const { return m_removed_soentries.begin(); }
- iterator unloaded_end() const { return m_removed_soentries.end(); }
-
+ typedef SOEntryList::const_iterator iterator;
+
+ /// Iterators over all currently loaded modules.
+ iterator begin() const { return m_soentries.begin(); }
+ iterator end() const { return m_soentries.end(); }
+
+ /// Iterators over all modules loaded into the inferior since the last call
+ /// to Resolve().
+ iterator loaded_begin() const { return m_added_soentries.begin(); }
+ iterator loaded_end() const { return m_added_soentries.end(); }
+
+ /// Iterators over all modules unloaded from the inferior since the last
+ /// call to Resolve().
+ iterator unloaded_begin() const { return m_removed_soentries.begin(); }
+ iterator unloaded_end() const { return m_removed_soentries.end(); }
+
protected:
- lldb_private::Process *m_process;
+ lldb_private::Process *m_process;
- // Cached copy of executable pathname
- char m_exe_path[PATH_MAX];
+ // Cached copy of executable pathname
+ char m_exe_path[PATH_MAX];
- /// Location of the r_debug structure in the inferiors address space.
- lldb::addr_t m_rendezvous_addr;
+ /// Location of the r_debug structure in the inferiors address space.
+ lldb::addr_t m_rendezvous_addr;
- /// Current and previous snapshots of the rendezvous structure.
- Rendezvous m_current;
- Rendezvous m_previous;
+ /// Current and previous snapshots of the rendezvous structure.
+ Rendezvous m_current;
+ Rendezvous m_previous;
- /// List of SOEntry objects corresponding to the current link map state.
- SOEntryList m_soentries;
+ /// List of SOEntry objects corresponding to the current link map state.
+ SOEntryList m_soentries;
- /// List of SOEntry's added to the link map since the last call to Resolve().
- SOEntryList m_added_soentries;
+ /// List of SOEntry's added to the link map since the last call to Resolve().
+ SOEntryList m_added_soentries;
- /// List of SOEntry's removed from the link map since the last call to
- /// Resolve().
- SOEntryList m_removed_soentries;
+ /// List of SOEntry's removed from the link map since the last call to
+ /// Resolve().
+ SOEntryList m_removed_soentries;
- /// Threading metadata read from the inferior.
- ThreadInfo m_thread_info;
+ /// Threading metadata read from the inferior.
+ ThreadInfo m_thread_info;
- /// Reads an unsigned integer of @p size bytes from the inferior's address
- /// space starting at @p addr.
- ///
- /// @returns addr + size if the read was successful and false otherwise.
- lldb::addr_t
- ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
+ /// Reads an unsigned integer of @p size bytes from the inferior's address
+ /// space starting at @p addr.
+ ///
+ /// @returns addr + size if the read was successful and false otherwise.
+ lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
- /// Reads an address from the inferior's address space starting at @p addr.
- ///
- /// @returns addr + target address size if the read was successful and
- /// 0 otherwise.
- lldb::addr_t
- ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
+ /// Reads an address from the inferior's address space starting at @p addr.
+ ///
+ /// @returns addr + target address size if the read was successful and
+ /// 0 otherwise.
+ lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
- /// Reads a null-terminated C string from the memory location starting at @p
- /// addr.
- std::string
- ReadStringFromMemory(lldb::addr_t addr);
+ /// Reads a null-terminated C string from the memory location starting at @p
+ /// addr.
+ std::string ReadStringFromMemory(lldb::addr_t addr);
- /// Reads an SOEntry starting at @p addr.
- bool
- ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
+ /// Reads an SOEntry starting at @p addr.
+ bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
- /// Updates the current set of SOEntries, the set of added entries, and the
- /// set of removed entries.
- bool
- UpdateSOEntries();
+ /// Updates the current set of SOEntries, the set of added entries, and the
+ /// set of removed entries.
+ bool UpdateSOEntries();
- bool
- UpdateSOEntriesForAddition();
+ bool UpdateSOEntriesForAddition();
- bool
- UpdateSOEntriesForDeletion();
+ bool UpdateSOEntriesForDeletion();
- /// Reads the current list of shared objects according to the link map
- /// supplied by the runtime linker.
- bool
- TakeSnapshot(SOEntryList &entry_list);
+ /// Reads the current list of shared objects according to the link map
+ /// supplied by the runtime linker.
+ bool TakeSnapshot(SOEntryList &entry_list);
- enum PThreadField { eSize, eNElem, eOffset };
+ enum PThreadField { eSize, eNElem, eOffset };
- bool FindMetadata(const char *name, PThreadField field, uint32_t& value);
+ bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
};
#endif // liblldb_HexagonDYLDRendezvous_H_
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt b/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
index 4d916b15f761..7dc3e98e6a57 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
@@ -1,4 +1,5 @@
add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD
DynamicLoaderMacOSXDYLD.cpp
+ DynamicLoaderMacOS.cpp
DynamicLoaderDarwin.cpp
)
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index efca1bea4ad6..bd0e772f7783 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "DynamicLoaderDarwin.h"
+
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -18,6 +20,7 @@
#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"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -30,12 +33,10 @@
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "DynamicLoaderDarwin.h"
-
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif
@@ -49,29 +50,18 @@
using namespace lldb;
using namespace lldb_private;
-
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderDarwin::DynamicLoaderDarwin (Process* process)
- : DynamicLoader(process),
- m_dyld_module_wp(),
- m_libpthread_module_wp(),
- m_pthread_getspecific_addr(),
- m_tid_to_tls_map(),
- m_dyld_image_infos(),
- m_dyld_image_infos_stop_id(UINT32_MAX),
- m_dyld(),
- m_mutex()
-{
-}
+DynamicLoaderDarwin::DynamicLoaderDarwin(Process *process)
+ : DynamicLoader(process), m_dyld_module_wp(), m_libpthread_module_wp(),
+ m_pthread_getspecific_addr(), m_tid_to_tls_map(), m_dyld_image_infos(),
+ m_dyld_image_infos_stop_id(UINT32_MAX), m_dyld(), m_mutex() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderDarwin::~DynamicLoaderDarwin()
-{
-}
+DynamicLoaderDarwin::~DynamicLoaderDarwin() {}
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -79,12 +69,10 @@ DynamicLoaderDarwin::~DynamicLoaderDarwin()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwin::DidAttach ()
-{
- PrivateInitialize(m_process);
- DoInitialImageFetch ();
- SetNotificationBreakpoint ();
+void DynamicLoaderDarwin::DidAttach() {
+ PrivateInitialize(m_process);
+ DoInitialImageFetch();
+ SetNotificationBreakpoint();
}
//------------------------------------------------------------------
@@ -93,570 +81,617 @@ DynamicLoaderDarwin::DidAttach ()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwin::DidLaunch ()
-{
- PrivateInitialize(m_process);
- DoInitialImageFetch ();
- SetNotificationBreakpoint ();
+void DynamicLoaderDarwin::DidLaunch() {
+ PrivateInitialize(m_process);
+ DoInitialImageFetch();
+ SetNotificationBreakpoint();
}
-
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::Clear (bool clear_process)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (clear_process)
- m_process = NULL;
- m_dyld_image_infos.clear();
- m_dyld_image_infos_stop_id = UINT32_MAX;
- m_dyld.Clear(false);
+void DynamicLoaderDarwin::Clear(bool clear_process) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (clear_process)
+ m_process = NULL;
+ m_dyld_image_infos.clear();
+ m_dyld_image_infos_stop_id = UINT32_MAX;
+ m_dyld.Clear(false);
}
-ModuleSP
-DynamicLoaderDarwin::FindTargetModuleForImageInfo (ImageInfo &image_info, bool can_create, bool *did_create_ptr)
-{
- if (did_create_ptr)
- *did_create_ptr = false;
-
- Target &target = m_process->GetTarget();
- const ModuleList &target_images = target.GetImages();
- ModuleSpec module_spec (image_info.file_spec);
- module_spec.GetUUID() = image_info.uuid;
- ModuleSP module_sp (target_images.FindFirstModule (module_spec));
-
- if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
- {
- // No UUID, we must rely upon the cached module modification
- // time and the modification time of the file on disk
- if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
- module_sp.reset();
+ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
+ ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
+ if (did_create_ptr)
+ *did_create_ptr = false;
+
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_images = target.GetImages();
+ ModuleSpec module_spec(image_info.file_spec);
+ module_spec.GetUUID() = image_info.uuid;
+ ModuleSP module_sp(target_images.FindFirstModule(module_spec));
+
+ if (module_sp && !module_spec.GetUUID().IsValid() &&
+ !module_sp->GetUUID().IsValid()) {
+ // No UUID, we must rely upon the cached module modification
+ // time and the modification time of the file on disk
+ if (module_sp->GetModificationTime() !=
+ FileSystem::GetModificationTime(module_sp->GetFileSpec()))
+ module_sp.reset();
+ }
+
+ if (!module_sp) {
+ if (can_create) {
+ module_sp = target.GetSharedModule(module_spec);
+ if (!module_sp || module_sp->GetObjectFile() == NULL)
+ module_sp = m_process->ReadModuleFromMemory(image_info.file_spec,
+ image_info.address);
+
+ if (did_create_ptr)
+ *did_create_ptr = (bool)module_sp;
}
+ }
+ return module_sp;
+}
- if (!module_sp)
- {
- if (can_create)
- {
- module_sp = target.GetSharedModule (module_spec);
- if (!module_sp || module_sp->GetObjectFile() == NULL)
- module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
-
- if (did_create_ptr)
- *did_create_ptr = (bool) module_sp;
+void DynamicLoaderDarwin::UnloadImages(
+ const std::vector<lldb::addr_t> &solib_addresses) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ return;
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ if (log)
+ log->Printf("Removing %" PRId64 " modules.",
+ (uint64_t)solib_addresses.size());
+
+ ModuleList unloaded_module_list;
+
+ for (addr_t solib_addr : solib_addresses) {
+ Address header;
+ if (header.SetLoadAddress(solib_addr, &target)) {
+ if (header.GetOffset() == 0) {
+ ModuleSP module_to_remove(header.GetModule());
+ if (module_to_remove.get()) {
+ if (log)
+ log->Printf("Removing module at address 0x%" PRIx64, solib_addr);
+ // remove the sections from the Target
+ UnloadSections(module_to_remove);
+ // add this to the list of modules to remove
+ unloaded_module_list.AppendIfNeeded(module_to_remove);
+ // remove the entry from the m_dyld_image_infos
+ ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+ for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
+ if (solib_addr == (*pos).address) {
+ m_dyld_image_infos.erase(pos);
+ break;
+ }
+ }
}
+ }
}
- return module_sp;
-}
+ }
-DynamicLoaderDarwin::ImageInfo *
-DynamicLoaderDarwin::FindImageInfoForAddress (addr_t load_address)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- const size_t image_count = m_dyld_image_infos.size();
- for (size_t i = 0; i < image_count; i++)
- {
- if (load_address == m_dyld_image_infos[i].address)
- {
- return &m_dyld_image_infos[i];
- }
+ if (unloaded_module_list.GetSize() > 0) {
+ if (log) {
+ log->PutCString("Unloaded:");
+ unloaded_module_list.LogUUIDAndPaths(
+ log, "DynamicLoaderDarwin::UnloadModules");
}
- return NULL;
+ m_process->GetTarget().GetImages().Remove(unloaded_module_list);
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ }
}
-void
-DynamicLoaderDarwin::UnloadImages (const std::vector<lldb::addr_t> &solib_addresses)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return;
+void DynamicLoaderDarwin::UnloadAllImages() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ ModuleList unloaded_modules_list;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- Target &target = m_process->GetTarget();
- if (log)
- log->Printf ("Removing %" PRId64 " modules.", (uint64_t) solib_addresses.size());
-
- ModuleList unloaded_module_list;
-
- for (addr_t solib_addr : solib_addresses)
- {
- Address header;
- if (header.SetLoadAddress (solib_addr, &target))
- {
- if (header.GetOffset() == 0)
- {
- ModuleSP module_to_remove (header.GetModule());
- if (module_to_remove.get())
- {
- if (log)
- log->Printf ("Removing module at address 0x%" PRIx64, solib_addr);
- // remove the sections from the Target
- UnloadSections (module_to_remove);
- // add this to the list of modules to remove
- unloaded_module_list.AppendIfNeeded (module_to_remove);
- // remove the entry from the m_dyld_image_infos
- ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
- for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
- {
- if (solib_addr == (*pos).address)
- {
- m_dyld_image_infos.erase(pos);
- break;
- }
- }
- }
- }
- }
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_modules = target.GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
+ size_t num_modules = target_modules.GetSize();
+ ModuleSP dyld_sp(GetDYLDModule());
+
+ for (size_t i = 0; i < num_modules; i++) {
+ ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+
+ // Don't remove dyld - else we'll lose our breakpoint notifying us about
+ // libraries
+ // being re-loaded...
+ if (module_sp.get() != nullptr && module_sp.get() != dyld_sp.get()) {
+ UnloadSections(module_sp);
+ unloaded_modules_list.Append(module_sp);
}
+ }
- if (unloaded_module_list.GetSize() > 0)
- {
- if (log)
- {
- log->PutCString("Unloaded:");
- unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::UnloadModules");
- }
- m_process->GetTarget().GetImages().Remove (unloaded_module_list);
- m_dyld_image_infos_stop_id = m_process->GetStopID();
+ if (unloaded_modules_list.GetSize() != 0) {
+ if (log) {
+ log->PutCString("Unloaded:");
+ unloaded_modules_list.LogUUIDAndPaths(
+ log, "DynamicLoaderDarwin::UnloadAllImages");
}
+ target.GetImages().Remove(unloaded_modules_list);
+ m_dyld_image_infos.clear();
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ }
}
//----------------------------------------------------------------------
// Update the load addresses for all segments in MODULE using the
// updated INFO that is passed in.
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwin::UpdateImageLoadAddress (Module *module, ImageInfo& info)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- std::vector<uint32_t> inaccessible_segment_indexes;
- // We now know the slide amount, so go through all sections
- // and update the load addresses with the correct values.
- const size_t num_segments = info.segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- // Only load a segment if it has protections. Things like
- // __PAGEZERO don't have any protections, and they shouldn't
- // be slid
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
-
- if (info.segments[i].maxprot == 0)
- {
- inaccessible_segment_indexes.push_back(i);
- }
- else
- {
- const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
- static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
-
- if (section_sp)
- {
- // __LINKEDIT sections from files in the shared cache
- // can overlap so check to see what the segment name is
- // and pass "false" so we don't warn of overlapping
- // "Section" objects, and "true" for all other sections.
- const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
-
- changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple);
- }
- else
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- (uint64_t)new_section_load_addr,
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
-
- // If the loaded the file (it changed) and we have segments that
- // are not readable or writeable, add them to the invalid memory
- // region cache for the process. This will typically only be
- // the __PAGEZERO segment in the main executable. We might be able
- // to apply this more generally to more sections that have no
- // protections in the future, but for now we are going to just
- // do __PAGEZERO.
- if (changed && !inaccessible_segment_indexes.empty())
- {
- for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
- {
- const uint32_t seg_idx = inaccessible_segment_indexes[i];
- SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
-
- if (section_sp)
- {
- static ConstString g_pagezero_section_name("__PAGEZERO");
- if (g_pagezero_section_name == section_sp->GetName())
- {
- // __PAGEZERO never slides...
- const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
- const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
- Process::LoadRange pagezero_range (vmaddr, vmsize);
- m_process->AddInvalidMemoryRegion(pagezero_range);
- }
- }
- }
- }
+bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
+ ImageInfo &info) {
+ bool changed = false;
+ if (module) {
+ ObjectFile *image_object_file = module->GetObjectFile();
+ if (image_object_file) {
+ SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ std::vector<uint32_t> inaccessible_segment_indexes;
+ // We now know the slide amount, so go through all sections
+ // and update the load addresses with the correct values.
+ const size_t num_segments = info.segments.size();
+ for (size_t i = 0; i < num_segments; ++i) {
+ // Only load a segment if it has protections. Things like
+ // __PAGEZERO don't have any protections, and they shouldn't
+ // be slid
+ SectionSP section_sp(
+ section_list->FindSectionByName(info.segments[i].name));
+
+ if (info.segments[i].maxprot == 0) {
+ inaccessible_segment_indexes.push_back(i);
+ } else {
+ const addr_t new_section_load_addr =
+ info.segments[i].vmaddr + info.slide;
+ static ConstString g_section_name_LINKEDIT("__LINKEDIT");
+
+ if (section_sp) {
+ // __LINKEDIT sections from files in the shared cache
+ // can overlap so check to see what the segment name is
+ // and pass "false" so we don't warn of overlapping
+ // "Section" objects, and "true" for all other sections.
+ const bool warn_multiple =
+ section_sp->GetName() != g_section_name_LINKEDIT;
+
+ changed = m_process->GetTarget().SetSectionLoadAddress(
+ section_sp, new_section_load_addr, warn_multiple);
+ } else {
+ Host::SystemLog(
+ Host::eSystemLogWarning,
+ "warning: unable to find and load segment named '%s' at "
+ "0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
+ info.segments[i].name.AsCString("<invalid>"),
+ (uint64_t)new_section_load_addr,
+ image_object_file->GetFileSpec().GetPath().c_str());
}
+ }
}
+
+ // If the loaded the file (it changed) and we have segments that
+ // are not readable or writeable, add them to the invalid memory
+ // region cache for the process. This will typically only be
+ // the __PAGEZERO segment in the main executable. We might be able
+ // to apply this more generally to more sections that have no
+ // protections in the future, but for now we are going to just
+ // do __PAGEZERO.
+ if (changed && !inaccessible_segment_indexes.empty()) {
+ for (uint32_t i = 0; i < inaccessible_segment_indexes.size(); ++i) {
+ const uint32_t seg_idx = inaccessible_segment_indexes[i];
+ SectionSP section_sp(
+ section_list->FindSectionByName(info.segments[seg_idx].name));
+
+ if (section_sp) {
+ static ConstString g_pagezero_section_name("__PAGEZERO");
+ if (g_pagezero_section_name == section_sp->GetName()) {
+ // __PAGEZERO never slides...
+ const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
+ const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
+ Process::LoadRange pagezero_range(vmaddr, vmsize);
+ m_process->AddInvalidMemoryRegion(pagezero_range);
+ }
+ }
+ }
+ }
+ }
}
- // We might have an in memory image that was loaded as soon as it was created
- if (info.load_stop_id == m_process->GetStopID())
- changed = true;
- else if (changed)
- {
- // Update the stop ID when this library was updated
- info.load_stop_id = m_process->GetStopID();
- }
- return changed;
+ }
+ // We might have an in memory image that was loaded as soon as it was created
+ if (info.load_stop_id == m_process->GetStopID())
+ changed = true;
+ else if (changed) {
+ // Update the stop ID when this library was updated
+ info.load_stop_id = m_process->GetStopID();
+ }
+ return changed;
}
//----------------------------------------------------------------------
// Unload the segments in MODULE using the INFO that is passed in.
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwin::UnloadModuleSections (Module *module, ImageInfo& info)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- const size_t num_segments = info.segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
- if (section_sp)
- {
- const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
- if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr))
- changed = true;
- }
- else
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
+bool DynamicLoaderDarwin::UnloadModuleSections(Module *module,
+ ImageInfo &info) {
+ bool changed = false;
+ if (module) {
+ ObjectFile *image_object_file = module->GetObjectFile();
+ if (image_object_file) {
+ SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ const size_t num_segments = info.segments.size();
+ for (size_t i = 0; i < num_segments; ++i) {
+ SectionSP section_sp(
+ section_list->FindSectionByName(info.segments[i].name));
+ if (section_sp) {
+ const addr_t old_section_load_addr =
+ info.segments[i].vmaddr + info.slide;
+ if (m_process->GetTarget().SetSectionUnloaded(
+ section_sp, old_section_load_addr))
+ changed = true;
+ } else {
+ Host::SystemLog(Host::eSystemLogWarning,
+ "warning: unable to find and unload segment named "
+ "'%s' in '%s' in macosx dynamic loader plug-in.\n",
+ info.segments[i].name.AsCString("<invalid>"),
+ image_object_file->GetFileSpec().GetPath().c_str());
+ }
}
+ }
}
- return changed;
+ }
+ return changed;
}
-
-// Given a JSON dictionary (from debugserver, most likely) of binary images loaded in the inferior
+// Given a JSON dictionary (from debugserver, most likely) of binary images
+// loaded in the inferior
// process, add the images to the ImageInfo collection.
-bool
-DynamicLoaderDarwin::JSONImageInformationIntoImageInfo (StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos)
-{
- StructuredData::ObjectSP images_sp = image_details->GetAsDictionary()->GetValueForKey("images");
- if (images_sp.get() == nullptr)
- return false;
-
- image_infos.resize (images_sp->GetAsArray()->GetSize());
-
- for (size_t i = 0; i < image_infos.size(); i++)
- {
- StructuredData::ObjectSP image_sp = images_sp->GetAsArray()->GetItemAtIndex(i);
- 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
- || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr
- || image->HasKey("segments") == false
- || image->GetValueForKey("segments")->GetAsArray() == nullptr
- || image->HasKey("uuid") == false )
- {
- return false;
- }
- 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().c_str(), false);
-
- StructuredData::Dictionary *mh = image->GetValueForKey("mach_header")->GetAsDictionary();
- image_infos[i].header.magic = mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
- image_infos[i].header.cputype = mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
- image_infos[i].header.cpusubtype = mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
- image_infos[i].header.filetype = mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
-
- // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
- // in the reply.
-
- if (mh->HasKey("flags"))
- image_infos[i].header.flags = mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.flags = 0;
-
- if (mh->HasKey("ncmds"))
- image_infos[i].header.ncmds = mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.ncmds = 0;
-
- if (mh->HasKey("sizeofcmds"))
- image_infos[i].header.sizeofcmds = mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.sizeofcmds = 0;
-
- StructuredData::Array *segments = image->GetValueForKey("segments")->GetAsArray();
- uint32_t segcount = segments->GetSize();
- for (size_t j = 0; j < segcount; j++)
- {
- Segment segment;
- StructuredData::Dictionary *seg = segments->GetItemAtIndex(j)->GetAsDictionary();
- segment.name = ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
- segment.vmaddr = seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
- segment.vmsize = seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
- segment.fileoff = seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
- segment.filesize = seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
- segment.maxprot = seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
-
- // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
- // in the reply.
-
- if (seg->HasKey("initprot"))
- segment.initprot = seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
- else
- segment.initprot = 0;
-
- if (seg->HasKey("flags"))
- segment.flags = seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- segment.flags = 0;
-
- if (seg->HasKey("nsects"))
- segment.nsects = seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
- else
- segment.nsects = 0;
-
- image_infos[i].segments.push_back (segment);
- }
+bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
+ StructuredData::ObjectSP image_details,
+ ImageInfo::collection &image_infos) {
+ StructuredData::ObjectSP images_sp =
+ image_details->GetAsDictionary()->GetValueForKey("images");
+ if (images_sp.get() == nullptr)
+ return false;
- image_infos[i].uuid.SetFromCString (image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
-
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = image_infos[i].segments.size();
- for (size_t k = 0; k < num_sections; ++k)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- if ((image_infos[i].segments[k].fileoff == 0 && image_infos[i].segments[k].filesize > 0)
- || (image_infos[i].segments[k].name == ConstString("__TEXT")))
- {
- image_infos[i].slide = image_infos[i].address - image_infos[i].segments[k].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
- break;
- }
- }
+ image_infos.resize(images_sp->GetAsArray()->GetSize());
+
+ for (size_t i = 0; i < image_infos.size(); i++) {
+ StructuredData::ObjectSP image_sp =
+ images_sp->GetAsArray()->GetItemAtIndex(i);
+ 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 ||
+ image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr ||
+ image->HasKey("segments") == false ||
+ image->GetValueForKey("segments")->GetAsArray() == nullptr ||
+ image->HasKey("uuid") == false) {
+ return false;
+ }
+ 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);
+
+ StructuredData::Dictionary *mh =
+ image->GetValueForKey("mach_header")->GetAsDictionary();
+ image_infos[i].header.magic =
+ mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
+ image_infos[i].header.cputype =
+ mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
+ image_infos[i].header.cpusubtype =
+ mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
+ image_infos[i].header.filetype =
+ mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
+
+ if (image->HasKey("min_version_os_name")) {
+ std::string os_name = image->GetValueForKey("min_version_os_name")
+ ->GetAsString()
+ ->GetValue();
+ if (os_name == "macosx")
+ image_infos[i].os_type = llvm::Triple::MacOSX;
+ else if (os_name == "ios" || os_name == "iphoneos")
+ image_infos[i].os_type = llvm::Triple::IOS;
+ else if (os_name == "tvos")
+ image_infos[i].os_type = llvm::Triple::TvOS;
+ else if (os_name == "watchos")
+ image_infos[i].os_type = llvm::Triple::WatchOS;
+ }
+ if (image->HasKey("min_version_os_sdk")) {
+ image_infos[i].min_version_os_sdk =
+ image->GetValueForKey("min_version_os_sdk")
+ ->GetAsString()
+ ->GetValue();
}
- return true;
-}
+ // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
+ // currently send them
+ // in the reply.
-void
-DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfos (ImageInfo::collection &image_infos)
-{
- 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)
- {
- UpdateDYLDImageInfoFromNewImageInfo (image_infos[i]);
- break; // FIXME simulator debugging w/ multiple dylds
- }
+ if (mh->HasKey("flags"))
+ image_infos[i].header.flags =
+ mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.flags = 0;
+
+ if (mh->HasKey("ncmds"))
+ image_infos[i].header.ncmds =
+ mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.ncmds = 0;
+
+ if (mh->HasKey("sizeofcmds"))
+ image_infos[i].header.sizeofcmds =
+ mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.sizeofcmds = 0;
+
+ StructuredData::Array *segments =
+ image->GetValueForKey("segments")->GetAsArray();
+ uint32_t segcount = segments->GetSize();
+ for (size_t j = 0; j < segcount; j++) {
+ Segment segment;
+ StructuredData::Dictionary *seg =
+ segments->GetItemAtIndex(j)->GetAsDictionary();
+ segment.name = ConstString(
+ seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
+ segment.vmaddr =
+ seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
+ segment.vmsize =
+ seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
+ segment.fileoff =
+ seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
+ segment.filesize =
+ seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
+ segment.maxprot =
+ seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
+
+ // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
+ // currently send them
+ // in the reply.
+
+ if (seg->HasKey("initprot"))
+ segment.initprot =
+ seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
+ else
+ segment.initprot = 0;
+
+ if (seg->HasKey("flags"))
+ segment.flags =
+ seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
+ else
+ segment.flags = 0;
+
+ if (seg->HasKey("nsects"))
+ segment.nsects =
+ seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
+ else
+ segment.nsects = 0;
+
+ image_infos[i].segments.push_back(segment);
+ }
+
+ image_infos[i].uuid.SetFromCString(
+ image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
+
+ // All sections listed in the dyld image info structure will all
+ // either be fixed up already, or they will all be off by a single
+ // slide amount that is determined by finding the first segment
+ // that is at file offset zero which also has bytes (a file size
+ // that is greater than zero) in the object file.
+
+ // Determine the slide amount (if any)
+ const size_t num_sections = image_infos[i].segments.size();
+ for (size_t k = 0; k < num_sections; ++k) {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ if ((image_infos[i].segments[k].fileoff == 0 &&
+ image_infos[i].segments[k].filesize > 0) ||
+ (image_infos[i].segments[k].name == ConstString("__TEXT"))) {
+ image_infos[i].slide =
+ image_infos[i].address - image_infos[i].segments[k].vmaddr;
+ // We have found the slide amount, so we can exit
+ // this for loop.
+ break;
+ }
}
+ }
+
+ return true;
}
-void
-DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info)
-{
- // FIXME simulator debugging w/ multiple dylds
- if (image_info.header.filetype == llvm::MachO::MH_DYLINKER)
- {
- const bool can_create = true;
- ModuleSP dyld_sp = FindTargetModuleForImageInfo (image_info, can_create, NULL);
- if (dyld_sp.get())
- {
- Target &target = m_process->GetTarget();
- target.GetImages().AppendIfNeeded (dyld_sp);
- UpdateImageLoadAddress (dyld_sp.get(), image_info);
- SetDYLDModule (dyld_sp);
+void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
+ ImageInfo::collection &image_infos) {
+ uint32_t exe_idx = UINT32_MAX;
+ uint32_t dyld_idx = UINT32_MAX;
+ Target &target = m_process->GetTarget();
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ ConstString g_dyld_sim_filename("dyld_sim");
+
+ ArchSpec target_arch = target.GetArchitecture();
+ 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.
+
+ // debugserver has only recently (late 2016) started sending up the
+ // os type for each binary it sees -- so if we don't have an os
+ // type, use a filename check as our next best guess.
+ if (image_infos[i].os_type == llvm::Triple::OSType::UnknownOS) {
+ if (image_infos[i].file_spec.GetFilename() != g_dyld_sim_filename) {
+ dyld_idx = i;
+ }
+ } else if (target_arch.GetTriple().getArch() == llvm::Triple::x86 ||
+ target_arch.GetTriple().getArch() == llvm::Triple::x86_64) {
+ 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) {
+ dyld_idx = i;
}
+ }
+ } else if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) {
+ exe_idx = i;
+ }
+ }
+
+ if (exe_idx != UINT32_MAX) {
+ const bool can_create = true;
+ ModuleSP exe_module_sp(
+ FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL));
+ if (exe_module_sp) {
+ if (log)
+ log->Printf("Found executable module: %s",
+ exe_module_sp->GetFileSpec().GetPath().c_str());
+ 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);
+ }
}
+ }
+
+ if (dyld_idx != UINT32_MAX) {
+ const bool can_create = true;
+ ModuleSP dyld_sp =
+ FindTargetModuleForImageInfo(image_infos[dyld_idx], can_create, NULL);
+ if (dyld_sp.get()) {
+ if (log)
+ log->Printf("Found dyld module: %s",
+ dyld_sp->GetFileSpec().GetPath().c_str());
+ target.GetImages().AppendIfNeeded(dyld_sp);
+ UpdateImageLoadAddress(dyld_sp.get(), image_infos[dyld_idx]);
+ SetDYLDModule(dyld_sp);
+ }
+ }
}
-void
-DynamicLoaderDarwin::AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos)
-{
- 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_EXECUTE)
- {
- Target &target = m_process->GetTarget();
- const bool can_create = true;
- ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[i], can_create, NULL));
-
- if (exe_module_sp)
- {
- UpdateImageLoadAddress (exe_module_sp.get(), image_infos[i]);
-
- if (exe_module_sp.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. Also when setting the
- // executable module, it will clear the targets module list, and if we
- // have an in memory dyld module, it will get removed from the list
- // so we will need to add it back after setting the executable module,
- // so we first try and see if we already have a weak pointer to the
- // dyld module, make it into a shared pointer, then add the executable,
- // then re-add it back to make sure it is always in the list.
-
- const bool get_dependent_images = false;
- m_process->GetTarget().SetExecutableModule (exe_module_sp,
- get_dependent_images);
-
- UpdateDYLDImageInfoFromNewImageInfos (image_infos);
- }
- }
- }
+void DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo(
+ ImageInfo &image_info) {
+ if (image_info.header.filetype == llvm::MachO::MH_DYLINKER) {
+ const bool can_create = true;
+ ModuleSP dyld_sp =
+ FindTargetModuleForImageInfo(image_info, can_create, NULL);
+ if (dyld_sp.get()) {
+ Target &target = m_process->GetTarget();
+ target.GetImages().AppendIfNeeded(dyld_sp);
+ UpdateImageLoadAddress(dyld_sp.get(), image_info);
+ SetDYLDModule(dyld_sp);
}
+ }
}
-void
-DynamicLoaderDarwin::SetDYLDModule (lldb::ModuleSP &dyld_module_sp)
-{
- m_dyld_module_wp = dyld_module_sp;
+void DynamicLoaderDarwin::SetDYLDModule(lldb::ModuleSP &dyld_module_sp) {
+ m_dyld_module_wp = dyld_module_sp;
}
-ModuleSP
-DynamicLoaderDarwin::GetDYLDModule ()
-{
- ModuleSP dyld_sp (m_dyld_module_wp.lock());
- return dyld_sp;
+ModuleSP DynamicLoaderDarwin::GetDYLDModule() {
+ ModuleSP dyld_sp(m_dyld_module_wp.lock());
+ return dyld_sp;
}
-bool
-DynamicLoaderDarwin::AddModulesUsingImageInfos (ImageInfo::collection &image_infos)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // Now add these images to the main list.
- ModuleList loaded_module_list;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- Target &target = m_process->GetTarget();
- ModuleList& target_images = target.GetImages();
-
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
- {
- if (log)
- {
- log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
- image_infos[idx].PutToLog (log);
- }
-
- m_dyld_image_infos.push_back(image_infos[idx]);
-
- ModuleSP image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], true, NULL));
-
- if (image_module_sp)
- {
- ObjectFile *objfile = image_module_sp->GetObjectFile ();
- if (objfile)
- {
- SectionList *sections = objfile->GetSectionList();
- if (sections)
- {
- ConstString commpage_dbstr("__commpage");
- Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
- if (commpage_section)
- {
- ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
- module_spec.GetObjectName() = commpage_dbstr;
- ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
- if (!commpage_image_module_sp)
- {
- module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
- module_spec.SetObjectSize (objfile->GetByteSize());
- commpage_image_module_sp = target.GetSharedModule (module_spec);
- if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
- {
- commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
- image_infos[idx].address);
- // Always load a memory image right away in the target in case
- // we end up trying to read the symbol table from memory... The
- // __LINKEDIT will need to be mapped so we can figure out where
- // the symbol table bits are...
- bool changed = false;
- UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
- target.GetImages().Append(commpage_image_module_sp);
- if (changed)
- {
- image_infos[idx].load_stop_id = m_process->GetStopID();
- loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
- }
- }
- }
- }
- }
- }
+bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
+ ImageInfo::collection &image_infos) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ // Now add these images to the main list.
+ ModuleList loaded_module_list;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ ModuleList &target_images = target.GetImages();
+
+ for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
+ if (log) {
+ log->Printf("Adding new image at address=0x%16.16" PRIx64 ".",
+ image_infos[idx].address);
+ image_infos[idx].PutToLog(log);
+ }
- // UpdateImageLoadAddress will return true if any segments
- // change load address. We need to check this so we don't
- // mention that all loaded shared libraries are newly loaded
- // each time we hit out dyld breakpoint since dyld will list all
- // shared libraries each time.
- if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
- {
- target_images.AppendIfNeeded(image_module_sp);
- loaded_module_list.AppendIfNeeded (image_module_sp);
+ m_dyld_image_infos.push_back(image_infos[idx]);
+
+ ModuleSP image_module_sp(
+ FindTargetModuleForImageInfo(image_infos[idx], true, NULL));
+
+ if (image_module_sp) {
+ ObjectFile *objfile = image_module_sp->GetObjectFile();
+ if (objfile) {
+ SectionList *sections = objfile->GetSectionList();
+ if (sections) {
+ ConstString commpage_dbstr("__commpage");
+ Section *commpage_section =
+ sections->FindSectionByName(commpage_dbstr).get();
+ if (commpage_section) {
+ ModuleSpec module_spec(objfile->GetFileSpec(),
+ image_infos[idx].GetArchitecture());
+ module_spec.GetObjectName() = commpage_dbstr;
+ ModuleSP commpage_image_module_sp(
+ target_images.FindFirstModule(module_spec));
+ if (!commpage_image_module_sp) {
+ module_spec.SetObjectOffset(objfile->GetFileOffset() +
+ commpage_section->GetFileOffset());
+ module_spec.SetObjectSize(objfile->GetByteSize());
+ commpage_image_module_sp = target.GetSharedModule(module_spec);
+ if (!commpage_image_module_sp ||
+ commpage_image_module_sp->GetObjectFile() == NULL) {
+ commpage_image_module_sp = m_process->ReadModuleFromMemory(
+ image_infos[idx].file_spec, image_infos[idx].address);
+ // Always load a memory image right away in the target in case
+ // we end up trying to read the symbol table from memory... The
+ // __LINKEDIT will need to be mapped so we can figure out where
+ // the symbol table bits are...
+ bool changed = false;
+ UpdateImageLoadAddress(commpage_image_module_sp.get(),
+ image_infos[idx]);
+ target.GetImages().Append(commpage_image_module_sp);
+ if (changed) {
+ image_infos[idx].load_stop_id = m_process->GetStopID();
+ loaded_module_list.AppendIfNeeded(commpage_image_module_sp);
+ }
+ }
}
+ }
}
+ }
+
+ // UpdateImageLoadAddress will return true if any segments
+ // change load address. We need to check this so we don't
+ // mention that all loaded shared libraries are newly loaded
+ // each time we hit out dyld breakpoint since dyld will list all
+ // shared libraries each time.
+ if (UpdateImageLoadAddress(image_module_sp.get(), image_infos[idx])) {
+ target_images.AppendIfNeeded(image_module_sp);
+ loaded_module_list.AppendIfNeeded(image_module_sp);
+ }
}
-
- if (loaded_module_list.GetSize() > 0)
- {
- if (log)
- loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::ModulesDidLoad");
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
- }
- return true;
-}
+ }
+ if (loaded_module_list.GetSize() > 0) {
+ if (log)
+ loaded_module_list.LogUUIDAndPaths(log,
+ "DynamicLoaderDarwin::ModulesDidLoad");
+ m_process->GetTarget().ModulesDidLoad(loaded_module_list);
+ }
+ return true;
+}
//----------------------------------------------------------------------
// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
// functions written in hand-written assembly, and also have hand-written unwind
-// information in the eh_frame section. Normally we prefer analyzing the
-// assembly instructions of a currently executing frame to unwind from that frame --
+// information in the eh_frame section. Normally we prefer analyzing the
+// assembly instructions of a currently executing frame to unwind from that
+// frame --
// but on hand-written functions this profiling can fail. We should use the
// eh_frame instructions for these functions all the time.
//
@@ -666,478 +701,469 @@ DynamicLoaderDarwin::AddModulesUsingImageInfos (ImageInfo::collection &image_inf
// of our normal default assumption that they are not.
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
-{
- ModuleSP module_sp;
- if (sym_ctx.symbol)
- {
- module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
- }
- if (module_sp.get() == NULL && sym_ctx.function)
- {
- module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
- }
- if (module_sp.get() == NULL)
- return false;
-
- ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
- {
- return true;
- }
-
+bool DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo(SymbolContext &sym_ctx) {
+ ModuleSP module_sp;
+ if (sym_ctx.symbol) {
+ module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
+ }
+ if (module_sp.get() == NULL && sym_ctx.function) {
+ module_sp =
+ sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
+ }
+ if (module_sp.get() == NULL)
return false;
-}
+ ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
+ if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary(module_sp)) {
+ return true;
+ }
+ return false;
+}
//----------------------------------------------------------------------
// Dump a Segment to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::Segment::PutToLog (Log *log, lldb::addr_t slide) const
-{
- if (log)
- {
- if (slide == 0)
- log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize);
- else
- log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize,
- slide);
- }
+void DynamicLoaderDarwin::Segment::PutToLog(Log *log,
+ lldb::addr_t slide) const {
+ if (log) {
+ if (slide == 0)
+ log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
+ name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize);
+ else
+ log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
+ ") slide = 0x%" PRIx64,
+ name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize,
+ slide);
+ }
}
const DynamicLoaderDarwin::Segment *
-DynamicLoaderDarwin::ImageInfo::FindSegment (const ConstString &name) const
-{
- const size_t num_segments = segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- if (segments[i].name == name)
- return &segments[i];
- }
- return NULL;
+DynamicLoaderDarwin::ImageInfo::FindSegment(const ConstString &name) const {
+ const size_t num_segments = segments.size();
+ for (size_t i = 0; i < num_segments; ++i) {
+ if (segments[i].name == name)
+ return &segments[i];
+ }
+ return NULL;
}
-
//----------------------------------------------------------------------
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::ImageInfo::PutToLog (Log *log) const
-{
- if (log == NULL)
- return;
- const uint8_t *u = (const uint8_t *)uuid.GetBytes();
-
- if (address == LLDB_INVALID_ADDRESS)
- {
- if (u)
- {
- log->Printf("\t modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
- mod_date,
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- }
- else
- log->Printf("\t modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)",
- mod_date,
- file_spec.GetPath().c_str());
- }
- else
- {
- if (u)
- {
- log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
- address,
- mod_date,
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- }
- else
- {
- log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'",
- address,
- mod_date,
- file_spec.GetPath().c_str());
-
- }
- for (uint32_t i=0; i<segments.size(); ++i)
- segments[i].PutToLog(log, slide);
+void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
+ const uint8_t *u = (const uint8_t *)uuid.GetBytes();
+
+ if (address == LLDB_INVALID_ADDRESS) {
+ if (u) {
+ log->Printf("\t modtime=0x%8.8" PRIx64
+ " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
+ "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
+ mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7],
+ u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15],
+ file_spec.GetPath().c_str());
+ } else
+ log->Printf("\t modtime=0x%8.8" PRIx64
+ " path='%s' (UNLOADED)",
+ mod_date, file_spec.GetPath().c_str());
+ } else {
+ if (u) {
+ log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64
+ " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
+ "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
+ address, mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6],
+ u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15],
+ file_spec.GetPath().c_str());
+ } else {
+ log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64
+ " path='%s'",
+ address, mod_date, file_spec.GetPath().c_str());
}
+ for (uint32_t i = 0; i < segments.size(); ++i)
+ segments[i].PutToLog(log, slide);
+ }
}
-void
-DynamicLoaderDarwin::PrivateInitialize(Process *process)
-{
- DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
- Clear(true);
- m_process = process;
- m_process->GetTarget().ClearAllLoadedSections();
+void DynamicLoaderDarwin::PrivateInitialize(Process *process) {
+ DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__,
+ StateAsCString(m_process->GetState()));
+ Clear(true);
+ m_process = process;
+ m_process->GetTarget().ClearAllLoadedSections();
}
//----------------------------------------------------------------------
// Member function that gets called when the process state changes.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::PrivateProcessStateChanged (Process *process, StateType state)
-{
- DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__, StateAsCString(state));
- switch (state)
- {
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear(false);
- break;
-
- case eStateStopped:
- // Keep trying find dyld and set our notification breakpoint each time
- // we stop until we succeed
- if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
- {
- if (NeedToDoInitialImageFetch ())
- DoInitialImageFetch ();
-
- SetNotificationBreakpoint ();
- }
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
+void DynamicLoaderDarwin::PrivateProcessStateChanged(Process *process,
+ StateType state) {
+ DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__,
+ StateAsCString(state));
+ switch (state) {
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateDetached:
+ Clear(false);
+ break;
+
+ case eStateStopped:
+ // Keep trying find dyld and set our notification breakpoint each time
+ // we stop until we succeed
+ if (!DidSetNotificationBreakpoint() && m_process->IsAlive()) {
+ if (NeedToDoInitialImageFetch())
+ DoInitialImageFetch();
+
+ SetNotificationBreakpoint();
}
+ break;
+
+ case eStateRunning:
+ case eStateStepping:
+ case eStateCrashed:
+ case eStateSuspended:
+ break;
+ }
}
ThreadPlanSP
-DynamicLoaderDarwin::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- ThreadPlanSP thread_plan_sp;
- StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *current_symbol = current_context.symbol;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- TargetSP target_sp (thread.CalculateTarget());
-
- if (current_symbol != NULL)
- {
- std::vector<Address> addresses;
-
- if (current_symbol->IsTrampoline())
- {
- const ConstString &trampoline_name = current_symbol->GetMangled().GetName(current_symbol->GetLanguage(), Mangled::ePreferMangled);
-
- if (trampoline_name)
- {
- const ModuleList &images = target_sp->GetImages();
-
- SymbolContextList code_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
- size_t num_code_symbols = code_symbols.GetSize();
-
- if (num_code_symbols > 0)
- {
- for (uint32_t i = 0; i < num_code_symbols; i++)
- {
- SymbolContext context;
- AddressRange addr_range;
- if (code_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log)
- {
- addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr);
- }
- }
- }
- }
-
- SymbolContextList reexported_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
- size_t num_reexported_symbols = reexported_symbols.GetSize();
- if (num_reexported_symbols > 0)
- {
- for (uint32_t i = 0; i < num_reexported_symbols; i++)
- {
- SymbolContext context;
- if (reexported_symbols.GetContextAtIndex(i, context))
- {
- if (context.symbol)
- {
- Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
- if (actual_symbol)
- {
- const Address actual_symbol_addr = actual_symbol->GetAddress();
- if (actual_symbol_addr.IsValid())
- {
- addresses.push_back(actual_symbol_addr);
- if (log)
- {
- lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get());
- log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
- actual_symbol->GetName().GetCString(), load_addr);
- }
- }
- }
- }
- }
- }
- }
-
- SymbolContextList indirect_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, indirect_symbols);
- size_t num_indirect_symbols = indirect_symbols.GetSize();
- if (num_indirect_symbols > 0)
- {
- for (uint32_t i = 0; i < num_indirect_symbols; i++)
- {
- SymbolContext context;
- AddressRange addr_range;
- if (indirect_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log)
- {
- addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf ("Found an indirect target symbol at 0x%" PRIx64 ".", load_addr);
- }
- }
- }
- }
+DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) {
+ ThreadPlanSP thread_plan_sp;
+ StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
+ const SymbolContext &current_context =
+ current_frame->GetSymbolContext(eSymbolContextSymbol);
+ Symbol *current_symbol = current_context.symbol;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ TargetSP target_sp(thread.CalculateTarget());
+
+ if (current_symbol != NULL) {
+ std::vector<Address> addresses;
+
+ if (current_symbol->IsTrampoline()) {
+ const ConstString &trampoline_name = current_symbol->GetMangled().GetName(
+ current_symbol->GetLanguage(), Mangled::ePreferMangled);
+
+ if (trampoline_name) {
+ const ModuleList &images = target_sp->GetImages();
+
+ SymbolContextList code_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode,
+ code_symbols);
+ size_t num_code_symbols = code_symbols.GetSize();
+
+ if (num_code_symbols > 0) {
+ for (uint32_t i = 0; i < num_code_symbols; i++) {
+ SymbolContext context;
+ AddressRange addr_range;
+ if (code_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false,
+ addr_range);
+ addresses.push_back(addr_range.GetBaseAddress());
+ if (log) {
+ addr_t load_addr =
+ addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+ log->Printf("Found a trampoline target symbol at 0x%" PRIx64
+ ".",
+ load_addr);
+ }
}
+ }
}
- else if (current_symbol->GetType() == eSymbolTypeReExported)
- {
- // I am not sure we could ever end up stopped AT a re-exported symbol. But just in case:
-
- const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
- if (actual_symbol)
- {
- Address target_addr(actual_symbol->GetAddress());
- if (target_addr.IsValid())
- {
- if (log)
- log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
- current_symbol->GetName().GetCString(),
- actual_symbol->GetName().GetCString(),
- target_addr.GetLoadAddress(target_sp.get()));
- addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
-
+
+ SymbolContextList reexported_symbols;
+ images.FindSymbolsWithNameAndType(
+ trampoline_name, eSymbolTypeReExported, reexported_symbols);
+ size_t num_reexported_symbols = reexported_symbols.GetSize();
+ if (num_reexported_symbols > 0) {
+ for (uint32_t i = 0; i < num_reexported_symbols; i++) {
+ SymbolContext context;
+ if (reexported_symbols.GetContextAtIndex(i, context)) {
+ if (context.symbol) {
+ Symbol *actual_symbol =
+ context.symbol->ResolveReExportedSymbol(*target_sp.get());
+ if (actual_symbol) {
+ const Address actual_symbol_addr =
+ actual_symbol->GetAddress();
+ if (actual_symbol_addr.IsValid()) {
+ addresses.push_back(actual_symbol_addr);
+ if (log) {
+ lldb::addr_t load_addr =
+ actual_symbol_addr.GetLoadAddress(target_sp.get());
+ log->Printf(
+ "Found a re-exported symbol: %s at 0x%" PRIx64 ".",
+ actual_symbol->GetName().GetCString(), load_addr);
+ }
+ }
}
+ }
}
+ }
}
-
- if (addresses.size() > 0)
- {
- // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
- std::vector<lldb::addr_t> load_addrs;
- for (Address address : addresses)
- {
- Symbol *symbol = address.CalculateSymbolContextSymbol();
- if (symbol && symbol->IsIndirect())
- {
- Error error;
- Address symbol_address = symbol->GetAddress();
- addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error);
- if (error.Success())
- {
- load_addrs.push_back(resolved_addr);
- if (log)
- log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
- symbol->GetName().GetCString(), resolved_addr);
- }
- }
- else
- {
- load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
- }
-
+
+ SymbolContextList indirect_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver,
+ indirect_symbols);
+ size_t num_indirect_symbols = indirect_symbols.GetSize();
+ if (num_indirect_symbols > 0) {
+ for (uint32_t i = 0; i < num_indirect_symbols; i++) {
+ SymbolContext context;
+ AddressRange addr_range;
+ if (indirect_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false,
+ addr_range);
+ addresses.push_back(addr_range.GetBaseAddress());
+ if (log) {
+ addr_t load_addr =
+ addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+ log->Printf("Found an indirect target symbol at 0x%" PRIx64 ".",
+ load_addr);
+ }
}
- thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
+ }
}
+ }
+ } else if (current_symbol->GetType() == eSymbolTypeReExported) {
+ // I am not sure we could ever end up stopped AT a re-exported symbol.
+ // But just in case:
+
+ const Symbol *actual_symbol =
+ current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
+ if (actual_symbol) {
+ Address target_addr(actual_symbol->GetAddress());
+ if (target_addr.IsValid()) {
+ if (log)
+ log->Printf(
+ "Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64
+ ".",
+ current_symbol->GetName().GetCString(),
+ actual_symbol->GetName().GetCString(),
+ target_addr.GetLoadAddress(target_sp.get()));
+ addresses.push_back(target_addr.GetLoadAddress(target_sp.get()));
+ }
+ }
}
- else
- {
- if (log)
- log->Printf ("Could not find symbol for step through.");
+
+ if (addresses.size() > 0) {
+ // First check whether any of the addresses point to Indirect symbols, and
+ // if they do, resolve them:
+ std::vector<lldb::addr_t> load_addrs;
+ for (Address address : addresses) {
+ Symbol *symbol = address.CalculateSymbolContextSymbol();
+ if (symbol && symbol->IsIndirect()) {
+ Error error;
+ Address symbol_address = symbol->GetAddress();
+ addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(
+ &symbol_address, error);
+ if (error.Success()) {
+ load_addrs.push_back(resolved_addr);
+ if (log)
+ log->Printf("ResolveIndirectFunction found resolved target for "
+ "%s at 0x%" PRIx64 ".",
+ symbol->GetName().GetCString(), resolved_addr);
+ }
+ } else {
+ load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
+ }
+ }
+ thread_plan_sp.reset(
+ new ThreadPlanRunToAddress(thread, load_addrs, stop_others));
}
+ } else {
+ if (log)
+ log->Printf("Could not find symbol for step through.");
+ }
- return thread_plan_sp;
+ return thread_plan_sp;
}
-size_t
-DynamicLoaderDarwin::FindEquivalentSymbols (lldb_private::Symbol *original_symbol,
- lldb_private::ModuleList &images,
- lldb_private::SymbolContextList &equivalent_symbols)
-{
- const ConstString &trampoline_name = original_symbol->GetMangled().GetName(original_symbol->GetLanguage(), Mangled::ePreferMangled);
- if (!trampoline_name)
- return 0;
-
- size_t initial_size = equivalent_symbols.GetSize();
-
- static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
- std::string equivalent_regex_buf("^");
- equivalent_regex_buf.append (trampoline_name.GetCString());
- equivalent_regex_buf.append (resolver_name_regex);
-
- RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
- const bool append = true;
- images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
-
- return equivalent_symbols.GetSize() - initial_size;
+size_t DynamicLoaderDarwin::FindEquivalentSymbols(
+ lldb_private::Symbol *original_symbol, lldb_private::ModuleList &images,
+ lldb_private::SymbolContextList &equivalent_symbols) {
+ const ConstString &trampoline_name = original_symbol->GetMangled().GetName(
+ original_symbol->GetLanguage(), Mangled::ePreferMangled);
+ if (!trampoline_name)
+ return 0;
+
+ size_t initial_size = equivalent_symbols.GetSize();
+
+ static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
+ std::string equivalent_regex_buf("^");
+ equivalent_regex_buf.append(trampoline_name.GetCString());
+ equivalent_regex_buf.append(resolver_name_regex);
+
+ RegularExpression equivalent_name_regex(equivalent_regex_buf);
+ const bool append = true;
+ images.FindSymbolsMatchingRegExAndType(equivalent_name_regex, eSymbolTypeCode,
+ equivalent_symbols, append);
+
+ return equivalent_symbols.GetSize() - initial_size;
}
-lldb::ModuleSP
-DynamicLoaderDarwin::GetPThreadLibraryModule()
-{
- ModuleSP module_sp = m_libpthread_module_wp.lock();
- if (!module_sp)
- {
- SymbolContextList sc_list;
- ModuleSpec module_spec;
- module_spec.GetFileSpec().GetFilename().SetCString("libsystem_pthread.dylib");
- ModuleList module_list;
- if (m_process->GetTarget().GetImages().FindModules(module_spec, module_list))
- {
- if (module_list.GetSize() == 1)
- {
- module_sp = module_list.GetModuleAtIndex(0);
- if (module_sp)
- m_libpthread_module_wp = module_sp;
- }
- }
+lldb::ModuleSP DynamicLoaderDarwin::GetPThreadLibraryModule() {
+ ModuleSP module_sp = m_libpthread_module_wp.lock();
+ if (!module_sp) {
+ SymbolContextList sc_list;
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec().GetFilename().SetCString(
+ "libsystem_pthread.dylib");
+ ModuleList module_list;
+ if (m_process->GetTarget().GetImages().FindModules(module_spec,
+ module_list)) {
+ if (module_list.GetSize() == 1) {
+ module_sp = module_list.GetModuleAtIndex(0);
+ if (module_sp)
+ m_libpthread_module_wp = module_sp;
+ }
}
- return module_sp;
+ }
+ return module_sp;
}
-Address
-DynamicLoaderDarwin::GetPthreadSetSpecificAddress()
-{
- if (!m_pthread_getspecific_addr.IsValid())
- {
- ModuleSP module_sp = GetPThreadLibraryModule();
- if (module_sp)
- {
- lldb_private::SymbolContextList sc_list;
- module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"), eSymbolTypeCode, sc_list);
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
- {
- if (sc.symbol)
- m_pthread_getspecific_addr = sc.symbol->GetAddress();
- }
- }
+Address DynamicLoaderDarwin::GetPthreadSetSpecificAddress() {
+ if (!m_pthread_getspecific_addr.IsValid()) {
+ ModuleSP module_sp = GetPThreadLibraryModule();
+ if (module_sp) {
+ lldb_private::SymbolContextList sc_list;
+ module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"),
+ eSymbolTypeCode, sc_list);
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc)) {
+ if (sc.symbol)
+ m_pthread_getspecific_addr = sc.symbol->GetAddress();
+ }
}
- return m_pthread_getspecific_addr;
+ }
+ return m_pthread_getspecific_addr;
}
lldb::addr_t
-DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread_sp,
- lldb::addr_t tls_file_addr)
-{
- if (!thread_sp || !module_sp)
- return LLDB_INVALID_ADDRESS;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- const uint32_t addr_size = m_process->GetAddressByteSize();
- uint8_t buf[sizeof(lldb::addr_t) * 3];
-
- lldb_private::Address tls_addr;
- if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr))
- {
- Error error;
- const size_t tsl_data_size = addr_size * 3;
- Target &target = m_process->GetTarget();
- if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) == tsl_data_size)
- {
- const ByteOrder byte_order = m_process->GetByteOrder();
- DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
- lldb::offset_t offset = addr_size; // Skip the first pointer
- const lldb::addr_t pthread_key = data.GetAddress(&offset);
- const lldb::addr_t tls_offset = data.GetAddress(&offset);
- if (pthread_key != 0)
- {
- // First check to see if we have already figured out the location
- // of TLS data for the pthread_key on a specific thread yet. If we
- // have we can re-use it since its location will not change unless
- // the process execs.
- const tid_t tid = thread_sp->GetID();
- auto tid_pos = m_tid_to_tls_map.find(tid);
- if (tid_pos != m_tid_to_tls_map.end())
- {
- auto tls_pos = tid_pos->second.find(pthread_key);
- if (tls_pos != tid_pos->second.end())
- {
- return tls_pos->second + tls_offset;
- }
- }
- StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
- if (frame_sp)
- {
- ClangASTContext *clang_ast_context = target.GetScratchClangASTContext();
-
- if (!clang_ast_context)
- return LLDB_INVALID_ADDRESS;
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
- if (pthread_getspecific_addr.IsValid())
- {
- EvaluateExpressionOptions options;
-
- lldb::ThreadPlanSP thread_plan_sp(
- new ThreadPlanCallFunction(*thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
- llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
-
- DiagnosticManager execution_errors;
- ExecutionContext exe_ctx(thread_sp);
- lldb::ExpressionResults results =
- m_process->RunThreadPlan(exe_ctx, thread_plan_sp, options, execution_errors);
-
- if (results == lldb::eExpressionCompleted)
- {
- lldb::ValueObjectSP result_valobj_sp = thread_plan_sp->GetReturnValueObject();
- if (result_valobj_sp)
- {
- const lldb::addr_t pthread_key_data = result_valobj_sp->GetValueAsUnsigned(0);
- if (pthread_key_data)
- {
- m_tid_to_tls_map[tid].insert(std::make_pair(pthread_key, pthread_key_data));
- return pthread_key_data + tls_offset;
- }
- }
- }
- }
+DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp,
+ const lldb::ThreadSP thread_sp,
+ lldb::addr_t tls_file_addr) {
+ if (!thread_sp || !module_sp)
+ return LLDB_INVALID_ADDRESS;
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ const uint32_t addr_size = m_process->GetAddressByteSize();
+ uint8_t buf[sizeof(lldb::addr_t) * 3];
+
+ lldb_private::Address tls_addr;
+ if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr)) {
+ Error error;
+ const size_t tsl_data_size = addr_size * 3;
+ Target &target = m_process->GetTarget();
+ if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) ==
+ tsl_data_size) {
+ const ByteOrder byte_order = m_process->GetByteOrder();
+ DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+ lldb::offset_t offset = addr_size; // Skip the first pointer
+ const lldb::addr_t pthread_key = data.GetAddress(&offset);
+ const lldb::addr_t tls_offset = data.GetAddress(&offset);
+ if (pthread_key != 0) {
+ // First check to see if we have already figured out the location
+ // of TLS data for the pthread_key on a specific thread yet. If we
+ // have we can re-use it since its location will not change unless
+ // the process execs.
+ const tid_t tid = thread_sp->GetID();
+ auto tid_pos = m_tid_to_tls_map.find(tid);
+ if (tid_pos != m_tid_to_tls_map.end()) {
+ auto tls_pos = tid_pos->second.find(pthread_key);
+ if (tls_pos != tid_pos->second.end()) {
+ return tls_pos->second + tls_offset;
+ }
+ }
+ StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
+ if (frame_sp) {
+ ClangASTContext *clang_ast_context =
+ target.GetScratchClangASTContext();
+
+ if (!clang_ast_context)
+ return LLDB_INVALID_ADDRESS;
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
+ if (pthread_getspecific_addr.IsValid()) {
+ EvaluateExpressionOptions options;
+
+ lldb::ThreadPlanSP thread_plan_sp(new ThreadPlanCallFunction(
+ *thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
+ llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
+
+ DiagnosticManager execution_errors;
+ ExecutionContext exe_ctx(thread_sp);
+ lldb::ExpressionResults results = m_process->RunThreadPlan(
+ exe_ctx, thread_plan_sp, options, execution_errors);
+
+ if (results == lldb::eExpressionCompleted) {
+ lldb::ValueObjectSP result_valobj_sp =
+ thread_plan_sp->GetReturnValueObject();
+ if (result_valobj_sp) {
+ const lldb::addr_t pthread_key_data =
+ result_valobj_sp->GetValueAsUnsigned(0);
+ if (pthread_key_data) {
+ m_tid_to_tls_map[tid].insert(
+ std::make_pair(pthread_key, pthread_key_data));
+ return pthread_key_data + tls_offset;
}
+ }
}
+ }
}
+ }
}
- return LLDB_INVALID_ADDRESS;
+ }
+ return LLDB_INVALID_ADDRESS;
}
+bool DynamicLoaderDarwin::UseDYLDSPI(Process *process) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ uint32_t major, minor, update;
+
+ bool use_new_spi_interface = false;
+
+ if (process->GetHostOSVersion(major, minor, update)) {
+ const llvm::Triple::OSType os_type =
+ process->GetTarget().GetArchitecture().GetTriple().getOS();
+
+ // macOS 10.12 and newer
+ if (os_type == llvm::Triple::MacOSX &&
+ (major > 10 || (major == 10 && minor >= 12))) {
+ use_new_spi_interface = true;
+ }
+
+ // iOS 10 and newer
+ if (os_type == llvm::Triple::IOS && major >= 10) {
+ use_new_spi_interface = true;
+ }
+
+ // tvOS 10 and newer
+ if (os_type == llvm::Triple::TvOS && major >= 10) {
+ use_new_spi_interface = true;
+ }
+
+ // watchOS 3 and newer
+ if (os_type == llvm::Triple::WatchOS && major >= 3) {
+ use_new_spi_interface = true;
+ }
+ }
+
+ if (log) {
+ if (use_new_spi_interface)
+ log->Printf(
+ "DynamicLoaderDarwin::UseDYLDSPI: Use new DynamicLoader plugin");
+ else
+ log->Printf(
+ "DynamicLoaderDarwin::UseDYLDSPI: Use old DynamicLoader plugin");
+ }
+ return use_new_spi_interface;
+}
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
index b7dd51d288df..2daa58de0cf6 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
@@ -18,274 +18,226 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UUID.h"
-#include "lldb/Host/Mutex.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/SafeMachO.h"
+#include "llvm/ADT/Triple.h"
+
namespace lldb_private {
-class DynamicLoaderDarwin : public lldb_private::DynamicLoader
-{
+class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
public:
- DynamicLoaderDarwin(lldb_private::Process *process);
+ DynamicLoaderDarwin(lldb_private::Process *process);
- virtual ~DynamicLoaderDarwin() override;
+ virtual ~DynamicLoaderDarwin() override;
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void
- DidAttach() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- size_t
- FindEquivalentSymbols(lldb_private::Symbol *original_symbol,
- lldb_private::ModuleList &module_list,
- lldb_private::SymbolContextList &equivalent_symbols) override;
-
- lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+ size_t FindEquivalentSymbols(
+ lldb_private::Symbol *original_symbol,
+ lldb_private::ModuleList &module_list,
+ lldb_private::SymbolContextList &equivalent_symbols) override;
- bool
- AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
+ lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) override;
- virtual void
- DoInitialImageFetch () = 0;
+ bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
- virtual bool
- NeedToDoInitialImageFetch () = 0;
+ virtual void DoInitialImageFetch() = 0;
+
+ virtual bool NeedToDoInitialImageFetch() = 0;
protected:
- void
- PrivateInitialize (lldb_private::Process *process);
-
- void
- PrivateProcessStateChanged (lldb_private::Process *process,
- lldb::StateType state);
-
- void
- Clear (bool clear_process);
-
- // Clear method for classes derived from this one
- virtual void
- DoClear () = 0;
-
- void
- SetDYLDModule (lldb::ModuleSP &dyld_module_sp);
-
- lldb::ModuleSP
- GetDYLDModule ();
-
- class Segment
- {
- public:
- Segment() :
- name(),
- vmaddr(LLDB_INVALID_ADDRESS),
- vmsize(0),
- fileoff(0),
- filesize(0),
- maxprot(0),
- initprot(0),
- nsects(0),
- flags(0)
- {
- }
-
- lldb_private::ConstString name;
- lldb::addr_t vmaddr;
- lldb::addr_t vmsize;
- lldb::addr_t fileoff;
- lldb::addr_t filesize;
- uint32_t maxprot;
- uint32_t initprot;
- uint32_t nsects;
- uint32_t flags;
-
- bool
- operator==(const Segment& rhs) const
- {
- return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
- }
-
- void
- PutToLog (lldb_private::Log *log,
- lldb::addr_t slide) const;
-
- };
-
- struct ImageInfo
- {
- lldb::addr_t address; // Address of mach header for this dylib
- lldb::addr_t slide; // The amount to slide all segments by if there is a global slide.
- lldb::addr_t mod_date; // Modification date for this dylib
- lldb_private::FileSpec file_spec; // Resolved path for this dylib
- lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
- llvm::MachO::mach_header header; // The mach header for this image
- std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
- uint32_t load_stop_id; // The process stop ID that the sections for this image were loaded
-
- ImageInfo() :
- address(LLDB_INVALID_ADDRESS),
- slide(0),
- mod_date(0),
- file_spec(),
- uuid(),
- header(),
- segments(),
- load_stop_id(0)
- {
- }
-
- void
- Clear(bool load_cmd_data_only)
- {
- if (!load_cmd_data_only)
- {
- address = LLDB_INVALID_ADDRESS;
- slide = 0;
- mod_date = 0;
- file_spec.Clear();
- ::memset (&header, 0, sizeof(header));
- }
- uuid.Clear();
- segments.clear();
- load_stop_id = 0;
- }
-
- bool
- operator == (const ImageInfo& rhs) const
- {
- return address == rhs.address
- && slide == rhs.slide
- && mod_date == rhs.mod_date
- && file_spec == rhs.file_spec
- && uuid == rhs.uuid
- && memcmp(&header, &rhs.header, sizeof(header)) == 0
- && segments == rhs.segments;
- }
-
- bool
- UUIDValid() const
- {
- return uuid.IsValid();
- }
-
- uint32_t
- GetAddressByteSize ()
- {
- if (header.cputype)
- {
- if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
- return 8;
- else
- return 4;
- }
- return 0;
- }
-
- lldb_private::ArchSpec
- GetArchitecture () const
- {
- return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
- }
-
- const Segment *
- FindSegment (const lldb_private::ConstString &name) const;
-
- void
- PutToLog (lldb_private::Log *log) const;
-
- typedef std::vector<ImageInfo> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- };
-
- bool
- UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo& info);
-
- bool
- UnloadModuleSections (lldb_private::Module *module, ImageInfo& info);
-
- ImageInfo *
- FindImageInfoForAddress (lldb::addr_t load_address);
-
- lldb::ModuleSP
- FindTargetModuleForImageInfo (ImageInfo &image_info,
- bool can_create,
- bool *did_create_ptr);
-
- void
- UnloadImages (const std::vector<lldb::addr_t> &solib_addresses);
-
- virtual bool
- SetNotificationBreakpoint () = 0;
-
- virtual void
- ClearNotificationBreakpoint () = 0;
-
- virtual bool
- DidSetNotificationBreakpoint () = 0;
-
- typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
- typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
-
- std::recursive_mutex &
- GetMutex () const
- {
- return m_mutex;
+ void PrivateInitialize(lldb_private::Process *process);
+
+ void PrivateProcessStateChanged(lldb_private::Process *process,
+ lldb::StateType state);
+
+ void Clear(bool clear_process);
+
+ // Clear method for classes derived from this one
+ virtual void DoClear() = 0;
+
+ void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
+
+ lldb::ModuleSP GetDYLDModule();
+
+ class Segment {
+ public:
+ Segment()
+ : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
+ filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
+
+ lldb_private::ConstString name;
+ lldb::addr_t vmaddr;
+ lldb::addr_t vmsize;
+ lldb::addr_t fileoff;
+ lldb::addr_t filesize;
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+
+ bool operator==(const Segment &rhs) const {
+ return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
}
- lldb::ModuleSP
- GetPThreadLibraryModule();
+ void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
+ };
+
+ struct ImageInfo {
+ lldb::addr_t address; // Address of mach header for this dylib
+ lldb::addr_t slide; // The amount to slide all segments by if there is a
+ // global slide.
+ lldb::addr_t mod_date; // Modification date for this dylib
+ lldb_private::FileSpec file_spec; // Resolved path for this dylib
+ lldb_private::UUID
+ uuid; // UUID for this dylib if it has one, else all zeros
+ llvm::MachO::mach_header header; // The mach header for this image
+ std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for
+ // this executable (from memory of inferior)
+ uint32_t load_stop_id; // The process stop ID that the sections for this
+ // image were loaded
+ llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
+ std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
+
+ ImageInfo()
+ : address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
+ uuid(), header(), segments(), load_stop_id(0),
+ os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
+
+ void Clear(bool load_cmd_data_only) {
+ if (!load_cmd_data_only) {
+ address = LLDB_INVALID_ADDRESS;
+ slide = 0;
+ mod_date = 0;
+ file_spec.Clear();
+ ::memset(&header, 0, sizeof(header));
+ }
+ uuid.Clear();
+ segments.clear();
+ load_stop_id = 0;
+ os_type = llvm::Triple::OSType::UnknownOS;
+ min_version_os_sdk.clear();
+ }
+
+ bool operator==(const ImageInfo &rhs) const {
+ return address == rhs.address && slide == rhs.slide &&
+ mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
+ uuid == rhs.uuid &&
+ memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
+ segments == rhs.segments && os_type == rhs.os_type;
+ }
+
+ bool UUIDValid() const { return uuid.IsValid(); }
+
+ uint32_t GetAddressByteSize() {
+ if (header.cputype) {
+ if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
+ return 8;
+ else
+ return 4;
+ }
+ return 0;
+ }
+
+ lldb_private::ArchSpec GetArchitecture() const {
+ return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
+ header.cputype, header.cpusubtype);
+ }
+
+ const Segment *FindSegment(const lldb_private::ConstString &name) const;
+
+ void PutToLog(lldb_private::Log *log) const;
+
+ typedef std::vector<ImageInfo> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ };
+
+ bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
+
+ bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
+
+ lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
+ bool can_create,
+ bool *did_create_ptr);
+
+ void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
+
+ void UnloadAllImages();
+
+ virtual bool SetNotificationBreakpoint() = 0;
+
+ virtual void ClearNotificationBreakpoint() = 0;
+
+ virtual bool DidSetNotificationBreakpoint() = 0;
+
+ typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
+ typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
+
+ std::recursive_mutex &GetMutex() const { return m_mutex; }
+
+ lldb::ModuleSP GetPThreadLibraryModule();
+
+ lldb_private::Address GetPthreadSetSpecificAddress();
- lldb_private::Address
- GetPthreadSetSpecificAddress();
+ bool JSONImageInformationIntoImageInfo(
+ lldb_private::StructuredData::ObjectSP image_details,
+ ImageInfo::collection &image_infos);
- bool
- JSONImageInformationIntoImageInfo (lldb_private::StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos);
+ // If image_infos contains / may contain dyld or executable image, call this
+ // method
+ // to keep our internal record keeping of the special binaries up-to-date.
+ void
+ UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
- // If image_infos contains / may contain dyld image, call this method
- // to keep our internal record keeping of the special dyld binary up-to-date.
- void
- UpdateDYLDImageInfoFromNewImageInfos (ImageInfo::collection &image_infos);
+ // if image_info is a dyld binary, call this method
+ void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
- // if image_info is a dyld binary, call this method
- void
- UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info);
+ // If image_infos contains / may contain executable image, call this method
+ // to keep our internal record keeping of the special dyld binary up-to-date.
+ void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
- // If image_infos contains / may contain executable image, call this method
- // to keep our internal record keeping of the special dyld binary up-to-date.
- void
- AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos);
+ bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
- bool
- AddModulesUsingImageInfos (ImageInfo::collection &image_infos);
+ // Whether we should use the new dyld SPI to get shared library information,
+ // or read
+ // it directly out of the dyld_all_image_infos. Whether we use the (newer)
+ // DynamicLoaderMacOS
+ // plugin or the (older) DynamicLoaderMacOSX plugin.
+ static bool UseDYLDSPI(lldb_private::Process *process);
- lldb::ModuleWP m_dyld_module_wp;
- lldb::ModuleWP m_libpthread_module_wp;
- lldb_private::Address m_pthread_getspecific_addr;
- ThreadIDToTLSMap m_tid_to_tls_map;
- ImageInfo::collection m_dyld_image_infos; // Current shared libraries information
- uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for
- ImageInfo m_dyld;
- mutable std::recursive_mutex m_mutex;
+ lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
+ // matches the process
+ lldb::ModuleWP m_libpthread_module_wp;
+ lldb_private::Address m_pthread_getspecific_addr;
+ ThreadIDToTLSMap m_tid_to_tls_map;
+ ImageInfo::collection
+ m_dyld_image_infos; // Current shared libraries information
+ uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
+ // "m_dyld_image_infos" is valid for
+ ImageInfo m_dyld;
+ mutable std::recursive_mutex m_mutex;
private:
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwin);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin);
};
} // namespace lldb_private
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
new file mode 100644
index 000000000000..7b027de783ed
--- /dev/null
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -0,0 +1,522 @@
+//===-- DynamicLoaderMacOS.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Log.h"
+#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"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+#include "DynamicLoaderDarwin.h"
+#include "DynamicLoaderMacOS.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Create an instance of this class. This function is filled into
+// the plugin info class that gets handed out by the plugin factory and
+// allows the lldb to instantiate an instance of this class.
+//----------------------------------------------------------------------
+DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ create = true;
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataUser);
+ }
+ }
+
+ if (create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ create = triple_ref.getVendor() == llvm::Triple::Apple;
+ break;
+ default:
+ create = false;
+ break;
+ }
+ }
+ }
+
+ if (UseDYLDSPI(process) == false) {
+ create = false;
+ }
+
+ if (create)
+ return new DynamicLoaderMacOS(process);
+ return NULL;
+}
+
+//----------------------------------------------------------------------
+// Constructor
+//----------------------------------------------------------------------
+DynamicLoaderMacOS::DynamicLoaderMacOS(Process *process)
+ : DynamicLoaderDarwin(process), m_image_infos_stop_id(UINT32_MAX),
+ m_break_id(LLDB_INVALID_BREAK_ID), m_mutex() {}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+DynamicLoaderMacOS::~DynamicLoaderMacOS() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+}
+
+bool DynamicLoaderMacOS::ProcessDidExec() {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ bool did_exec = false;
+ 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;
+ }
+ }
+ }
+ }
+ }
+
+ if (did_exec) {
+ m_libpthread_module_wp.reset();
+ m_pthread_getspecific_addr.Clear();
+ }
+ return did_exec;
+}
+
+//----------------------------------------------------------------------
+// Clear out the state of this class.
+//----------------------------------------------------------------------
+void DynamicLoaderMacOS::DoClear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+
+ m_break_id = LLDB_INVALID_BREAK_ID;
+}
+
+//----------------------------------------------------------------------
+// Check if we have found DYLD yet
+//----------------------------------------------------------------------
+bool DynamicLoaderMacOS::DidSetNotificationBreakpoint() {
+ return LLDB_BREAK_ID_IS_VALID(m_break_id);
+}
+
+void DynamicLoaderMacOS::ClearNotificationBreakpoint() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+ }
+}
+
+//----------------------------------------------------------------------
+// Try and figure out where dyld is by first asking the Process
+// if it knows (which currently calls down in the lldb::Process
+// to get the DYLD info (available on SnowLeopard only). If that fails,
+// then check in the default addresses.
+//----------------------------------------------------------------------
+void DynamicLoaderMacOS::DoInitialImageFetch() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ StructuredData::ObjectSP all_image_info_json_sp(
+ m_process->GetLoadedDynamicLibrariesInfos());
+ ImageInfo::collection image_infos;
+ if (all_image_info_json_sp.get() &&
+ all_image_info_json_sp->GetAsDictionary() &&
+ all_image_info_json_sp->GetAsDictionary()->HasKey("images") &&
+ all_image_info_json_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray()) {
+ if (JSONImageInformationIntoImageInfo(all_image_info_json_sp,
+ image_infos)) {
+ if (log)
+ log->Printf("Initial module fetch: Adding %" PRId64 " modules.\n",
+ (uint64_t)image_infos.size());
+
+ UpdateSpecialBinariesFromNewImageInfos(image_infos);
+ AddModulesUsingImageInfos(image_infos);
+ }
+ }
+
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+}
+
+bool DynamicLoaderMacOS::NeedToDoInitialImageFetch() { return true; }
+
+//----------------------------------------------------------------------
+// Static callback function that gets called when our DYLD notification
+// breakpoint gets hit. We update all of our image infos and then
+// let our super class DynamicLoader class decide if we should stop
+// or not (based on global preference).
+//----------------------------------------------------------------------
+bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ // Let the event know that the images have changed
+ // DYLD passes three arguments to the notification breakpoint.
+ // Arg1: enum dyld_notify_mode mode - 0 = adding, 1 = removing, 2 = remove all
+ // Arg2: unsigned long icount - Number of shared libraries
+ // added/removed
+ // Arg3: uint64_t mach_headers[] - Array of load addresses of binaries
+ // added/removed
+
+ DynamicLoaderMacOS *dyld_instance = (DynamicLoaderMacOS *)baton;
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Process *process = exe_ctx.GetProcessPtr();
+
+ // This is a sanity check just in case this dyld_instance is an old dyld
+ // plugin's breakpoint still lying around.
+ if (process != dyld_instance->m_process)
+ return false;
+
+ if (dyld_instance->m_image_infos_stop_id != UINT32_MAX &&
+ process->GetStopID() < dyld_instance->m_image_infos_stop_id) {
+ return false;
+ }
+
+ const lldb::ABISP &abi = process->GetABI();
+ if (abi) {
+ // Build up the value array to store the three arguments given above, then
+ // get the values from the ABI:
+
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ ValueList argument_values;
+
+ Value mode_value; // enum dyld_notify_mode { dyld_notify_adding=0,
+ // dyld_notify_removing=1, dyld_notify_remove_all=2 };
+ Value count_value; // unsigned long count
+ Value headers_value; // uint64_t machHeaders[] (aka void*)
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ CompilerType clang_uint32_type =
+ clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
+ lldb::eEncodingUint, 32);
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
+ lldb::eEncodingUint, 32);
+
+ mode_value.SetValueType(Value::eValueTypeScalar);
+ mode_value.SetCompilerType(clang_uint32_type);
+
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 4) {
+ count_value.SetValueType(Value::eValueTypeScalar);
+ count_value.SetCompilerType(clang_uint32_type);
+ } else {
+ count_value.SetValueType(Value::eValueTypeScalar);
+ count_value.SetCompilerType(clang_uint64_type);
+ }
+
+ headers_value.SetValueType(Value::eValueTypeScalar);
+ headers_value.SetCompilerType(clang_void_ptr_type);
+
+ argument_values.PushValue(mode_value);
+ argument_values.PushValue(count_value);
+ argument_values.PushValue(headers_value);
+
+ if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
+ uint32_t dyld_mode =
+ argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
+ if (dyld_mode != static_cast<uint32_t>(-1)) {
+ // Okay the mode was right, now get the number of elements, and the
+ // array of new elements...
+ uint32_t image_infos_count =
+ argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
+ if (image_infos_count != static_cast<uint32_t>(-1)) {
+ addr_t header_array =
+ argument_values.GetValueAtIndex(2)->GetScalar().ULongLong(-1);
+ if (header_array != static_cast<uint64_t>(-1)) {
+ std::vector<addr_t> image_load_addresses;
+ for (uint64_t i = 0; i < image_infos_count; i++) {
+ Error error;
+ addr_t addr = process->ReadUnsignedIntegerFromMemory(
+ header_array + (8 * i), 8, LLDB_INVALID_ADDRESS, error);
+ if (addr != LLDB_INVALID_ADDRESS) {
+ image_load_addresses.push_back(addr);
+ }
+ }
+ if (dyld_mode == 0) {
+ // dyld_notify_adding
+ dyld_instance->AddBinaries(image_load_addresses);
+ } else if (dyld_mode == 1) {
+ // dyld_notify_removing
+ dyld_instance->UnloadImages(image_load_addresses);
+ } else if (dyld_mode == 2) {
+ // dyld_notify_remove_all
+ dyld_instance->UnloadAllImages();
+ }
+ }
+ }
+ }
+ }
+ } else {
+ process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
+ "No ABI plugin located for triple %s -- shared libraries will not be "
+ "registered!\n",
+ process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+ }
+
+ // Return true to stop the target, false to just let the target run
+ return dyld_instance->GetStopWhenImagesChange();
+}
+
+void DynamicLoaderMacOS::AddBinaries(
+ const std::vector<lldb::addr_t> &load_addresses) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ ImageInfo::collection image_infos;
+
+ if (log)
+ log->Printf("Adding %" PRId64 " modules.", (uint64_t)load_addresses.size());
+ StructuredData::ObjectSP binaries_info_sp =
+ m_process->GetLoadedDynamicLibrariesInfos(load_addresses);
+ if (binaries_info_sp.get() && binaries_info_sp->GetAsDictionary() &&
+ binaries_info_sp->GetAsDictionary()->HasKey("images") &&
+ binaries_info_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray() &&
+ binaries_info_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray()
+ ->GetSize() == load_addresses.size()) {
+ if (JSONImageInformationIntoImageInfo(binaries_info_sp, image_infos)) {
+ UpdateSpecialBinariesFromNewImageInfos(image_infos);
+ AddModulesUsingImageInfos(image_infos);
+ }
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ }
+}
+
+// Dump the _dyld_all_image_infos members and all current image infos
+// that we have parsed to the file handle provided.
+//----------------------------------------------------------------------
+void DynamicLoaderMacOS::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
+}
+
+bool DynamicLoaderMacOS::SetNotificationBreakpoint() {
+ if (m_break_id == LLDB_INVALID_BREAK_ID) {
+ ConstString g_symbol_name("_dyld_debugger_notification");
+ const Symbol *symbol = nullptr;
+ ModuleSP dyld_sp(GetDYLDModule());
+ if (dyld_sp) {
+ symbol = dyld_sp->FindFirstSymbolWithNameAndType(g_symbol_name,
+ eSymbolTypeCode);
+ }
+ if (symbol &&
+ (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
+ addr_t symbol_address =
+ symbol->GetAddressRef().GetOpcodeLoadAddress(&m_process->GetTarget());
+ if (symbol_address != LLDB_INVALID_ADDRESS) {
+ bool internal = true;
+ bool hardware = false;
+ Breakpoint *breakpoint =
+ m_process->GetTarget()
+ .CreateBreakpoint(symbol_address, internal, hardware)
+ .get();
+ breakpoint->SetCallback(DynamicLoaderMacOS::NotifyBreakpointHit, this,
+ true);
+ breakpoint->SetBreakpointKind("shared-library-event");
+ m_break_id = breakpoint->GetID();
+ }
+ }
+ }
+ return m_break_id != LLDB_INVALID_BREAK_ID;
+}
+
+addr_t
+DynamicLoaderMacOS::GetDyldLockVariableAddressFromModule(Module *module) {
+ SymbolContext sc;
+ SymbolVendor *sym_vendor = module->GetSymbolVendor();
+ Target &target = m_process->GetTarget();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab) {
+ std::vector<uint32_t> match_indexes;
+ ConstString g_symbol_name("_dyld_global_lock_held");
+ uint32_t num_matches = 0;
+ num_matches =
+ symtab->AppendSymbolIndexesWithName(g_symbol_name, match_indexes);
+ if (num_matches == 1) {
+ Symbol *symbol = symtab->SymbolAtIndex(match_indexes[0]);
+ if (symbol &&
+ (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
+ return symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
+ }
+ }
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+// Look for this symbol:
+//
+// int __attribute__((visibility("hidden"))) _dyld_global_lock_held =
+// 0;
+//
+// in libdyld.dylib.
+Error DynamicLoaderMacOS::CanLoadImage() {
+ Error error;
+ addr_t symbol_address = LLDB_INVALID_ADDRESS;
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_modules = target.GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ ConstString g_libdyld_name("libdyld.dylib");
+
+ // Find any modules named "libdyld.dylib" and look for the symbol there first
+ for (size_t i = 0; i < num_modules; i++) {
+ Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
+ if (module_pointer) {
+ if (module_pointer->GetFileSpec().GetFilename() == g_libdyld_name) {
+ symbol_address = GetDyldLockVariableAddressFromModule(module_pointer);
+ if (symbol_address != LLDB_INVALID_ADDRESS)
+ break;
+ }
+ }
+ }
+
+ // Search through all modules looking for the symbol in them
+ if (symbol_address == LLDB_INVALID_ADDRESS) {
+ for (size_t i = 0; i < num_modules; i++) {
+ Module *module_pointer =
+ target_modules.GetModulePointerAtIndexUnlocked(i);
+ if (module_pointer) {
+ addr_t symbol_address =
+ GetDyldLockVariableAddressFromModule(module_pointer);
+ if (symbol_address != LLDB_INVALID_ADDRESS)
+ break;
+ }
+ }
+ }
+
+ // Default assumption is that it is OK to load images.
+ // Only say that we cannot load images if we find the symbol in libdyld and it
+ // indicates that
+ // we cannot.
+
+ if (symbol_address != LLDB_INVALID_ADDRESS) {
+ {
+ int lock_held =
+ m_process->ReadUnsignedIntegerFromMemory(symbol_address, 4, 0, error);
+ if (lock_held != 0) {
+ error.SetErrorToGenericError();
+ }
+ }
+ } else {
+ // If we were unable to find _dyld_global_lock_held in any modules, or it is
+ // not loaded into
+ // memory yet, we may be at process startup (sitting at _dyld_start) - so we
+ // should not allow
+ // dlopen calls.
+ error.SetErrorToGenericError();
+ }
+ return error;
+}
+
+bool DynamicLoaderMacOS::GetSharedCacheInformation(
+ lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
+ LazyBool &private_shared_cache) {
+ base_address = LLDB_INVALID_ADDRESS;
+ uuid.Clear();
+ using_shared_cache = eLazyBoolCalculate;
+ private_shared_cache = eLazyBoolCalculate;
+
+ if (m_process) {
+ StructuredData::ObjectSP info = m_process->GetSharedCacheInfo();
+ StructuredData::Dictionary *info_dict = nullptr;
+ if (info.get() && info->GetAsDictionary()) {
+ info_dict = info->GetAsDictionary();
+ }
+
+ // {"shared_cache_base_address":140735683125248,"shared_cache_uuid":"DDB8D70C-C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false}
+
+ if (info_dict && info_dict->HasKey("shared_cache_uuid") &&
+ info_dict->HasKey("no_shared_cache") &&
+ info_dict->HasKey("shared_cache_base_address")) {
+ base_address = info_dict->GetValueForKey("shared_cache_base_address")
+ ->GetIntegerValue(LLDB_INVALID_ADDRESS);
+ std::string uuid_str =
+ info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue();
+ if (!uuid_str.empty())
+ uuid.SetFromCString(uuid_str.c_str());
+ if (info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue() ==
+ false)
+ using_shared_cache = eLazyBoolYes;
+ else
+ using_shared_cache = eLazyBoolNo;
+ if (info_dict->GetValueForKey("shared_cache_private_cache")
+ ->GetBooleanValue())
+ private_shared_cache = eLazyBoolYes;
+ else
+ private_shared_cache = eLazyBoolNo;
+
+ return true;
+ }
+ }
+ return false;
+}
+
+void DynamicLoaderMacOS::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void DynamicLoaderMacOS::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString DynamicLoaderMacOS::GetPluginNameStatic() {
+ static ConstString g_name("macos-dyld");
+ return g_name;
+}
+
+const char *DynamicLoaderMacOS::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library loads/unloads "
+ "in MacOSX user processes.";
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+lldb_private::ConstString DynamicLoaderMacOS::GetPluginName() {
+ return GetPluginNameStatic();
+}
+
+uint32_t DynamicLoaderMacOS::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
new file mode 100644
index 000000000000..93273b13bb73
--- /dev/null
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
@@ -0,0 +1,117 @@
+//===-- DynamicLoaderMacOS.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
+// watchOS)
+// 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
+// array of load addresses for solibs loaded and unloaded. The SPI will tell us
+// about both dyld and the executable, in addition to all of the usual solibs.
+
+#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/Core/StructuredData.h"
+#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/SafeMachO.h"
+
+#include "DynamicLoaderDarwin.h"
+
+class DynamicLoaderMacOS : public lldb_private::DynamicLoaderDarwin {
+public:
+ DynamicLoaderMacOS(lldb_private::Process *process);
+
+ virtual ~DynamicLoaderMacOS() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
+
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ bool ProcessDidExec() override;
+
+ lldb_private::Error CanLoadImage() override;
+
+ bool GetSharedCacheInformation(
+ lldb::addr_t &base_address, lldb_private::UUID &uuid,
+ lldb_private::LazyBool &using_shared_cache,
+ lldb_private::LazyBool &private_shared_cache) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+protected:
+ void PutToLog(lldb_private::Log *log) const;
+
+ void DoInitialImageFetch() override;
+
+ bool NeedToDoInitialImageFetch() override;
+
+ bool DidSetNotificationBreakpoint() override;
+
+ void AddBinaries(const std::vector<lldb::addr_t> &load_addresses);
+
+ void DoClear() override;
+
+ static bool
+ NotifyBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ bool SetNotificationBreakpoint() override;
+
+ void ClearNotificationBreakpoint() override;
+
+ void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
+ uint32_t infos_count,
+ bool update_executable);
+
+ lldb::addr_t
+ GetDyldLockVariableAddressFromModule(lldb_private::Module *module);
+
+ uint32_t m_image_infos_stop_id; // The Stop ID the last time we
+ // loaded/unloaded images
+ lldb::user_id_t m_break_id;
+ mutable std::recursive_mutex m_mutex;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOS);
+};
+
+#endif // liblldb_DynamicLoaderMacOS_h_
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index a8bc216fb17e..9c5f1bce3bd3 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -20,21 +20,21 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Target/StackFrame.h"
-#include "DynamicLoaderMacOSXDYLD.h"
#include "DynamicLoaderDarwin.h"
+#include "DynamicLoaderMacOSXDYLD.h"
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif
@@ -48,164 +48,140 @@
using namespace lldb;
using namespace lldb_private;
-
//----------------------------------------------------------------------
// Create an instance of this class. This function is filled into
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-DynamicLoader *
-DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
-{
- bool create = force;
- if (!create)
- {
- create = true;
- Module* exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
+DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ create = true;
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataUser);
+ }
}
-
- if (create)
- return new DynamicLoaderMacOSXDYLD (process);
- return NULL;
+
+ if (create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ create = triple_ref.getVendor() == llvm::Triple::Apple;
+ break;
+ default:
+ create = false;
+ break;
+ }
+ }
+ }
+
+ if (UseDYLDSPI(process) == true) {
+ create = false;
+ }
+
+ if (create)
+ return new DynamicLoaderMacOSXDYLD(process);
+ return NULL;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
- DynamicLoaderDarwin(process),
- m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
- m_dyld_all_image_infos(),
- m_dyld_all_image_infos_stop_id (UINT32_MAX),
- m_break_id(LLDB_INVALID_BREAK_ID),
- m_mutex(),
- m_process_image_addr_is_all_images_infos (false)
-{
-}
+DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD(Process *process)
+ : DynamicLoaderDarwin(process),
+ m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
+ m_dyld_all_image_infos(), m_dyld_all_image_infos_stop_id(UINT32_MAX),
+ m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
+ m_process_image_addr_is_all_images_infos(false) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
-{
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
}
-bool
-DynamicLoaderMacOSXDYLD::ProcessDidExec ()
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- bool did_exec = false;
- if (m_process)
- {
- // If we are stopped after an exec, we will have only one thread...
- if (m_process->GetThreadList().GetSize() == 1)
- {
- // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
- // 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 && 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 && shlib_addr == m_dyld.address)
- {
- // The image info address from the process is the mach_header
- // address for dyld and it has changed.
+bool DynamicLoaderMacOSXDYLD::ProcessDidExec() {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ bool did_exec = false;
+ if (m_process) {
+ // If we are stopped after an exec, we will have only one thread...
+ if (m_process->GetThreadList().GetSize() == 1) {
+ // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
+ // 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 &&
+ 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 &&
+ shlib_addr == m_dyld.address) {
+ // The image info address from the process is the mach_header
+ // address for dyld and it has changed.
+ did_exec = true;
+ } else {
+ // ASLR might be disabled and dyld could have ended up in the same
+ // location. We should try and detect if we are stopped at '_dyld_start'
+ 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;
}
- else
- {
- // ASLR might be disabled and dyld could have ended up in the same
- // location. We should try and detect if we are stopped at '_dyld_start'
- 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;
- }
- }
- }
- }
-
- if (did_exec)
- {
- m_libpthread_module_wp.reset();
- m_pthread_getspecific_addr.Clear();
- }
+ }
}
+ }
+
+ if (did_exec) {
+ m_libpthread_module_wp.reset();
+ m_pthread_getspecific_addr.Clear();
+ }
}
- return did_exec;
+ }
+ return did_exec;
}
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DoClear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+void DynamicLoaderMacOSXDYLD::DoClear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
- m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
- m_dyld_all_image_infos.Clear();
- m_break_id = LLDB_INVALID_BREAK_ID;
+ m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
+ m_dyld_all_image_infos.Clear();
+ m_break_id = LLDB_INVALID_BREAK_ID;
}
//----------------------------------------------------------------------
// Check if we have found DYLD yet
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint()
-{
- return LLDB_BREAK_ID_IS_VALID (m_break_id);
+bool DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() {
+ return LLDB_BREAK_ID_IS_VALID(m_break_id);
}
-void
-DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint ()
-{
- if (LLDB_BREAK_ID_IS_VALID (m_break_id))
- {
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
- }
+void DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+ }
}
//----------------------------------------------------------------------
@@ -214,142 +190,127 @@ DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint ()
// to get the DYLD info (available on SnowLeopard only). If that fails,
// then check in the default addresses.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DoInitialImageFetch()
-{
- if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
- {
- // Check the image info addr as it might point to the
- // mach header for dyld, or it might point to the
- // dyld_all_image_infos struct
- const addr_t shlib_addr = m_process->GetImageInfoAddress ();
- if (shlib_addr != LLDB_INVALID_ADDRESS)
- {
- ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint8_t buf[4];
- DataExtractor data (buf, sizeof(buf), byte_order, 4);
- Error error;
- if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
- {
- lldb::offset_t offset = 0;
- uint32_t magic = data.GetU32 (&offset);
- switch (magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- m_process_image_addr_is_all_images_infos = false;
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
- return;
-
- default:
- break;
- }
- }
- // Maybe it points to the all image infos?
- m_dyld_all_image_infos_addr = shlib_addr;
- m_process_image_addr_is_all_images_infos = true;
- }
- }
+void DynamicLoaderMacOSXDYLD::DoInitialImageFetch() {
+ if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) {
+ // Check the image info addr as it might point to the
+ // mach header for dyld, or it might point to the
+ // dyld_all_image_infos struct
+ const addr_t shlib_addr = m_process->GetImageInfoAddress();
+ if (shlib_addr != LLDB_INVALID_ADDRESS) {
+ ByteOrder byte_order =
+ m_process->GetTarget().GetArchitecture().GetByteOrder();
+ uint8_t buf[4];
+ DataExtractor data(buf, sizeof(buf), byte_order, 4);
+ Error error;
+ if (m_process->ReadMemory(shlib_addr, buf, 4, error) == 4) {
+ lldb::offset_t offset = 0;
+ uint32_t magic = data.GetU32(&offset);
+ switch (magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_MAGIC_64:
+ case llvm::MachO::MH_CIGAM:
+ case llvm::MachO::MH_CIGAM_64:
+ m_process_image_addr_is_all_images_infos = false;
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+ return;
- if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
- {
- if (ReadAllImageInfosStructure ())
- {
- if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
- ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
- else
- ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
- return;
+ default:
+ break;
}
+ }
+ // Maybe it points to the all image infos?
+ m_dyld_all_image_infos_addr = shlib_addr;
+ m_process_image_addr_is_all_images_infos = true;
}
-
- // Check some default values
- Module *executable = m_process->GetTarget().GetExecutableModulePointer();
-
- if (executable)
- {
- const ArchSpec &exe_arch = executable->GetArchitecture();
- if (exe_arch.GetAddressByteSize() == 8)
- {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
- }
- else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb || exe_arch.GetMachine() == llvm::Triple::aarch64)
- {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
- }
- else
- {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
- }
+ }
+
+ if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
+ if (ReadAllImageInfosStructure()) {
+ if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(
+ m_dyld_all_image_infos.dyldImageLoadAddress);
+ else
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(
+ m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
+ return;
}
- return;
+ }
+
+ // Check some default values
+ Module *executable = m_process->GetTarget().GetExecutableModulePointer();
+
+ if (executable) {
+ const ArchSpec &exe_arch = executable->GetArchitecture();
+ if (exe_arch.GetAddressByteSize() == 8) {
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
+ } else if (exe_arch.GetMachine() == llvm::Triple::arm ||
+ exe_arch.GetMachine() == llvm::Triple::thumb ||
+ exe_arch.GetMachine() == llvm::Triple::aarch64) {
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
+ } else {
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
+ }
+ }
+ return;
}
//----------------------------------------------------------------------
// Assume that dyld is in memory at ADDR and try to parse it's load
// commands
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- DataExtractor data; // Load command data
- if (ReadMachHeader (addr, &m_dyld.header, &data))
- {
- if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER)
- {
- m_dyld.address = addr;
- ModuleSP dyld_module_sp;
- if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
- {
- if (m_dyld.file_spec)
- {
- UpdateDYLDImageInfoFromNewImageInfo (m_dyld);
-
- }
- }
- dyld_module_sp = GetDYLDModule();
-
- Target &target = m_process->GetTarget();
-
- if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
- {
- static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
- const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
- if (symbol)
- m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target);
- }
-
- // Update all image infos
- InitializeFromAllImageInfos ();
-
- // If we didn't have an executable before, but now we do, then the
- // dyld module shared pointer might be unique and we may need to add
- // it again (since Target::SetExecutableModule() will clear the
- // images). So append the dyld module back to the list if it is
- /// unique!
- if (dyld_module_sp)
- {
- target.GetImages().AppendIfNeeded (dyld_module_sp);
-
- // At this point we should have read in dyld's module, and so we should set breakpoints in it:
- ModuleList modules;
- modules.Append(dyld_module_sp);
- target.ModulesDidLoad(modules);
- SetDYLDModule (dyld_module_sp);
- }
- return true;
+bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(
+ lldb::addr_t addr) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ DataExtractor data; // Load command data
+ static ConstString g_dyld_all_image_infos("dyld_all_image_infos");
+ if (ReadMachHeader(addr, &m_dyld.header, &data)) {
+ if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER) {
+ m_dyld.address = addr;
+ ModuleSP dyld_module_sp;
+ if (ParseLoadCommands(data, m_dyld, &m_dyld.file_spec)) {
+ if (m_dyld.file_spec) {
+ UpdateDYLDImageInfoFromNewImageInfo(m_dyld);
}
+ }
+ dyld_module_sp = GetDYLDModule();
+
+ Target &target = m_process->GetTarget();
+
+ if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS &&
+ dyld_module_sp.get()) {
+ const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType(
+ g_dyld_all_image_infos, eSymbolTypeData);
+ if (symbol)
+ m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target);
+ }
+
+ // Update all image infos
+ InitializeFromAllImageInfos();
+
+ // If we didn't have an executable before, but now we do, then the
+ // dyld module shared pointer might be unique and we may need to add
+ // it again (since Target::SetExecutableModule() will clear the
+ // images). So append the dyld module back to the list if it is
+ /// unique!
+ if (dyld_module_sp) {
+ target.GetImages().AppendIfNeeded(dyld_module_sp);
+
+ // At this point we should have read in dyld's module, and so we should
+ // set breakpoints in it:
+ ModuleList modules;
+ modules.Append(dyld_module_sp);
+ target.ModulesDidLoad(modules);
+ SetDYLDModule(dyld_module_sp);
+ }
+
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch ()
-{
- return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
+bool DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch() {
+ return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
@@ -358,392 +319,397 @@ DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch ()
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
-{
- // Let the event know that the images have changed
- // DYLD passes three arguments to the notification breakpoint.
- // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
- // Arg2: uint32_t infoCount - Number of shared libraries added
- // Arg3: dyld_image_info info[] - Array of structs of the form:
- // const struct mach_header *imageLoadAddress
- // const char *imageFilePath
- // uintptr_t imageFileModDate (a time_t)
-
- DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
-
- // First step is to see if we've already initialized the all image infos. If we haven't then this function
- // will do so and return true. In the course of initializing the all_image_infos it will read the complete
- // current state, so we don't need to figure out what has changed from the data passed in to us.
-
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Process *process = exe_ctx.GetProcessPtr();
-
- // This is a sanity check just in case this dyld_instance is an old dyld plugin's breakpoint still lying around.
- if (process != dyld_instance->m_process)
- return false;
-
- if (dyld_instance->InitializeFromAllImageInfos())
- return dyld_instance->GetStopWhenImagesChange();
-
- const lldb::ABISP &abi = process->GetABI();
- if (abi)
- {
- // Build up the value array to store the three arguments given above, then get the values from the ABI:
-
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- ValueList argument_values;
- Value input_value;
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- CompilerType clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
- input_value.SetValueType (Value::eValueTypeScalar);
- input_value.SetCompilerType (clang_uint32_type);
-// input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
- argument_values.PushValue (input_value);
- argument_values.PushValue (input_value);
- input_value.SetCompilerType (clang_void_ptr_type);
- // input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
- argument_values.PushValue (input_value);
-
- if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
- {
- uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
- if (dyld_mode != static_cast<uint32_t>(-1))
- {
- // Okay the mode was right, now get the number of elements, and the array of new elements...
- uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
- if (image_infos_count != static_cast<uint32_t>(-1))
- {
- // Got the number added, now go through the array of added elements, putting out the mach header
- // address, and adding the image.
- // Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do
- // all the logging internally.
-
- lldb::addr_t image_infos_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
- if (dyld_mode == 0)
- {
- // This is add:
- dyld_instance->AddModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
- }
- else
- {
- // This is remove:
- dyld_instance->RemoveModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
- }
-
- }
- }
+bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
+ void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ // Let the event know that the images have changed
+ // DYLD passes three arguments to the notification breakpoint.
+ // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
+ // Arg2: uint32_t infoCount - Number of shared libraries added
+ // Arg3: dyld_image_info info[] - Array of structs of the form:
+ // const struct mach_header
+ // *imageLoadAddress
+ // const char *imageFilePath
+ // uintptr_t imageFileModDate (a time_t)
+
+ DynamicLoaderMacOSXDYLD *dyld_instance = (DynamicLoaderMacOSXDYLD *)baton;
+
+ // First step is to see if we've already initialized the all image infos. If
+ // we haven't then this function
+ // will do so and return true. In the course of initializing the
+ // all_image_infos it will read the complete
+ // current state, so we don't need to figure out what has changed from the
+ // data passed in to us.
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Process *process = exe_ctx.GetProcessPtr();
+
+ // This is a sanity check just in case this dyld_instance is an old dyld
+ // plugin's breakpoint still lying around.
+ if (process != dyld_instance->m_process)
+ return false;
+
+ if (dyld_instance->InitializeFromAllImageInfos())
+ return dyld_instance->GetStopWhenImagesChange();
+
+ const lldb::ABISP &abi = process->GetABI();
+ if (abi) {
+ // Build up the value array to store the three arguments given above, then
+ // get the values from the ABI:
+
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ ValueList argument_values;
+ Value input_value;
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ CompilerType clang_uint32_type =
+ clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
+ lldb::eEncodingUint, 32);
+ input_value.SetValueType(Value::eValueTypeScalar);
+ input_value.SetCompilerType(clang_uint32_type);
+ // input_value.SetContext (Value::eContextTypeClangType,
+ // clang_uint32_type);
+ argument_values.PushValue(input_value);
+ argument_values.PushValue(input_value);
+ input_value.SetCompilerType(clang_void_ptr_type);
+ // input_value.SetContext (Value::eContextTypeClangType,
+ // clang_void_ptr_type);
+ argument_values.PushValue(input_value);
+
+ if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
+ uint32_t dyld_mode =
+ argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
+ if (dyld_mode != static_cast<uint32_t>(-1)) {
+ // Okay the mode was right, now get the number of elements, and the
+ // array of new elements...
+ uint32_t image_infos_count =
+ argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
+ if (image_infos_count != static_cast<uint32_t>(-1)) {
+ // Got the number added, now go through the array of added elements,
+ // putting out the mach header
+ // address, and adding the image.
+ // Note, I'm not putting in logging here, since the AddModules &
+ // RemoveModules functions do
+ // all the logging internally.
+
+ lldb::addr_t image_infos_addr =
+ argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
+ if (dyld_mode == 0) {
+ // This is add:
+ dyld_instance->AddModulesUsingImageInfosAddress(image_infos_addr,
+ image_infos_count);
+ } else {
+ // This is remove:
+ dyld_instance->RemoveModulesUsingImageInfosAddress(
+ image_infos_addr, image_infos_count);
+ }
}
+ }
}
- else
- {
- process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf("No ABI plugin located for triple %s -- shared libraries will not be registered!\n", process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
- }
-
- // Return true to stop the target, false to just let the target run
- return dyld_instance->GetStopWhenImagesChange();
+ } else {
+ process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
+ "No ABI plugin located for triple %s -- shared libraries will not be "
+ "registered!\n",
+ process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+ }
+
+ // Return true to stop the target, false to just let the target run
+ return dyld_instance->GetStopWhenImagesChange();
}
-bool
-DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // the all image infos is already valid for this process stop ID
- if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
- return true;
+ // the all image infos is already valid for this process stop ID
+ if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
+ return true;
- m_dyld_all_image_infos.Clear();
- if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
- {
- ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint32_t addr_size = 4;
- if (m_dyld_all_image_infos_addr > UINT32_MAX)
- addr_size = 8;
+ m_dyld_all_image_infos.Clear();
+ if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
+ ByteOrder byte_order =
+ m_process->GetTarget().GetArchitecture().GetByteOrder();
+ uint32_t addr_size =
+ m_process->GetTarget().GetArchitecture().GetAddressByteSize();
- uint8_t buf[256];
- DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
- lldb::offset_t offset = 0;
+ uint8_t buf[256];
+ DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+ lldb::offset_t offset = 0;
- const size_t count_v2 = sizeof (uint32_t) + // version
- sizeof (uint32_t) + // infoArrayCount
- addr_size + // infoArray
- addr_size + // notification
- addr_size + // processDetachedFromSharedRegion + libSystemInitialized + pad
- addr_size; // dyldImageLoadAddress
- const size_t count_v11 = count_v2 +
- addr_size + // jitInfo
- addr_size + // dyldVersion
- addr_size + // errorMessage
- addr_size + // terminationFlags
- addr_size + // coreSymbolicationShmPage
- addr_size + // systemOrderFlag
- addr_size + // uuidArrayCount
- addr_size + // uuidArray
- addr_size + // dyldAllImageInfosAddress
- addr_size + // initialImageCount
- addr_size + // errorKind
- addr_size + // errorClientOfDylibPath
- addr_size + // errorTargetDylibPath
- addr_size; // errorSymbol
- const size_t count_v13 = count_v11 +
- addr_size + // sharedCacheSlide
- sizeof (uuid_t); // sharedCacheUUID
- UNUSED_IF_ASSERT_DISABLED(count_v13);
- assert (sizeof (buf) >= count_v13);
-
- Error error;
- if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
- {
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- // If anything in the high byte is set, we probably got the byte
- // order incorrect (the process might not have it set correctly
- // yet due to attaching to a program without a specified file).
- if (m_dyld_all_image_infos.version & 0xff000000)
- {
- // We have guessed the wrong byte order. Swap it and try
- // reading the version again.
- if (byte_order == eByteOrderLittle)
- byte_order = eByteOrderBig;
- else
- byte_order = eByteOrderLittle;
-
- data.SetByteOrder (byte_order);
- offset = 0;
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- }
- }
+ const size_t count_v2 = sizeof(uint32_t) + // version
+ sizeof(uint32_t) + // infoArrayCount
+ addr_size + // infoArray
+ addr_size + // notification
+ addr_size + // processDetachedFromSharedRegion +
+ // libSystemInitialized + pad
+ addr_size; // dyldImageLoadAddress
+ const size_t count_v11 = count_v2 + addr_size + // jitInfo
+ addr_size + // dyldVersion
+ addr_size + // errorMessage
+ addr_size + // terminationFlags
+ addr_size + // coreSymbolicationShmPage
+ addr_size + // systemOrderFlag
+ addr_size + // uuidArrayCount
+ addr_size + // uuidArray
+ addr_size + // dyldAllImageInfosAddress
+ addr_size + // initialImageCount
+ addr_size + // errorKind
+ addr_size + // errorClientOfDylibPath
+ addr_size + // errorTargetDylibPath
+ addr_size; // errorSymbol
+ const size_t count_v13 = count_v11 + addr_size + // sharedCacheSlide
+ sizeof(uuid_t); // sharedCacheUUID
+ UNUSED_IF_ASSERT_DISABLED(count_v13);
+ assert(sizeof(buf) >= count_v13);
+
+ Error error;
+ if (m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, 4, error) ==
+ 4) {
+ m_dyld_all_image_infos.version = data.GetU32(&offset);
+ // If anything in the high byte is set, we probably got the byte
+ // order incorrect (the process might not have it set correctly
+ // yet due to attaching to a program without a specified file).
+ if (m_dyld_all_image_infos.version & 0xff000000) {
+ // We have guessed the wrong byte order. Swap it and try
+ // reading the version again.
+ if (byte_order == eByteOrderLittle)
+ byte_order = eByteOrderBig;
else
- {
- return false;
- }
+ byte_order = eByteOrderLittle;
+
+ data.SetByteOrder(byte_order);
+ offset = 0;
+ m_dyld_all_image_infos.version = data.GetU32(&offset);
+ }
+ } else {
+ return false;
+ }
- const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
-
- const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
- if (bytes_read == count)
- {
- offset = 0;
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
- m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
- m_dyld_all_image_infos.notification = data.GetPointer(&offset);
- m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
- m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
- // Adjust for padding.
- offset += addr_size - 2;
- m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
- if (m_dyld_all_image_infos.version >= 11)
- {
- offset += addr_size * 8;
- uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
-
- // When we started, we were given the actual address of the all_image_infos
- // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
- // m_dyld_all_image_infos_addr and is the most accurate address we have.
-
- // We read the dyld_all_image_infos struct from memory; it contains its own address.
- // If the address in the struct does not match the actual address,
- // the dyld we're looking at has been loaded at a different location (slid) from
- // where it intended to load. The addresses in the dyld_all_image_infos struct
- // are the original, non-slid addresses, and need to be adjusted. Most importantly
- // the address of dyld and the notification address need to be adjusted.
-
- if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
- {
- uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
- uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
- m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
- m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
- }
- }
- m_dyld_all_image_infos_stop_id = m_process->GetStopID();
- return true;
+ const size_t count =
+ (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
+
+ const size_t bytes_read =
+ m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, count, error);
+ if (bytes_read == count) {
+ offset = 0;
+ m_dyld_all_image_infos.version = data.GetU32(&offset);
+ m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
+ m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
+ m_dyld_all_image_infos.notification = data.GetPointer(&offset);
+ m_dyld_all_image_infos.processDetachedFromSharedRegion =
+ data.GetU8(&offset);
+ m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
+ // Adjust for padding.
+ offset += addr_size - 2;
+ m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
+ if (m_dyld_all_image_infos.version >= 11) {
+ offset += addr_size * 8;
+ uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
+
+ // When we started, we were given the actual address of the
+ // all_image_infos
+ // struct (probably via TASK_DYLD_INFO) in memory - this address is
+ // stored in
+ // m_dyld_all_image_infos_addr and is the most accurate address we have.
+
+ // We read the dyld_all_image_infos struct from memory; it contains its
+ // own address.
+ // If the address in the struct does not match the actual address,
+ // the dyld we're looking at has been loaded at a different location
+ // (slid) from
+ // where it intended to load. The addresses in the dyld_all_image_infos
+ // struct
+ // are the original, non-slid addresses, and need to be adjusted. Most
+ // importantly
+ // the address of dyld and the notification address need to be adjusted.
+
+ if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) {
+ uint64_t image_infos_offset =
+ dyld_all_image_infos_addr -
+ m_dyld_all_image_infos.dyldImageLoadAddress;
+ uint64_t notification_offset =
+ m_dyld_all_image_infos.notification -
+ m_dyld_all_image_infos.dyldImageLoadAddress;
+ m_dyld_all_image_infos.dyldImageLoadAddress =
+ m_dyld_all_image_infos_addr - image_infos_offset;
+ m_dyld_all_image_infos.notification =
+ m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
}
+ }
+ m_dyld_all_image_infos_stop_id = m_process->GetStopID();
+ return true;
}
- return false;
+ }
+ return false;
}
+bool DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress(
+ lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
+ ImageInfo::collection image_infos;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("Adding %d modules.\n", image_infos_count);
-bool
-DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
-{
- ImageInfo::collection image_infos;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("Adding %d modules.\n", image_infos_count);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return true;
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ return true;
- StructuredData::ObjectSP image_infos_json_sp = m_process->GetLoadedDynamicLibrariesInfos (image_infos_addr, image_infos_count);
- if (image_infos_json_sp.get()
- && image_infos_json_sp->GetAsDictionary()
- && image_infos_json_sp->GetAsDictionary()->HasKey("images")
- && image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()
- && image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()->GetSize() == image_infos_count)
- {
- bool return_value = false;
- if (JSONImageInformationIntoImageInfo (image_infos_json_sp, image_infos))
- {
- AddExecutableModuleIfInImageInfos (image_infos);
- return_value = AddModulesUsingImageInfos (image_infos);
- }
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- return return_value;
+ StructuredData::ObjectSP image_infos_json_sp =
+ m_process->GetLoadedDynamicLibrariesInfos(image_infos_addr,
+ image_infos_count);
+ if (image_infos_json_sp.get() && image_infos_json_sp->GetAsDictionary() &&
+ image_infos_json_sp->GetAsDictionary()->HasKey("images") &&
+ image_infos_json_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray() &&
+ image_infos_json_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray()
+ ->GetSize() == image_infos_count) {
+ bool return_value = false;
+ if (JSONImageInformationIntoImageInfo(image_infos_json_sp, image_infos)) {
+ UpdateSpecialBinariesFromNewImageInfos(image_infos);
+ return_value = AddModulesUsingImageInfos(image_infos);
}
-
- if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
- return false;
-
- UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false);
- bool return_value = AddModulesUsingImageInfos (image_infos);
m_dyld_image_infos_stop_id = m_process->GetStopID();
return return_value;
+ }
+
+ if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos))
+ return false;
+
+ UpdateImageInfosHeaderAndLoadCommands(image_infos, image_infos_count, false);
+ bool return_value = AddModulesUsingImageInfos(image_infos);
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ return return_value;
}
-bool
-DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
-{
- ImageInfo::collection image_infos;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return true;
+bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress(
+ lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
+ ImageInfo::collection image_infos;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- // First read in the image_infos for the removed modules, and their headers & load commands.
- if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
- {
- if (log)
- log->PutCString ("Failed reading image infos array.");
- return false;
- }
-
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ return true;
+
+ // First read in the image_infos for the removed modules, and their headers &
+ // load commands.
+ if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) {
if (log)
- log->Printf ("Removing %d modules.", image_infos_count);
-
- ModuleList unloaded_module_list;
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
- {
- if (log)
- {
- log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
- image_infos[idx].PutToLog (log);
- }
-
- // Remove this image_infos from the m_all_image_infos. We do the comparison by address
- // rather than by file spec because we can have many modules with the same "file spec" in the
- // case that they are modules loaded from memory.
- //
- // Also copy over the uuid from the old entry to the removed entry so we can
- // use it to lookup the module in the module list.
-
- ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
- for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
- {
- if (image_infos[idx].address == (*pos).address)
- {
- image_infos[idx].uuid = (*pos).uuid;
-
- // Add the module from this image_info to the "unloaded_module_list". We'll remove them all at
- // one go later on.
-
- ModuleSP unload_image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], false, NULL));
- if (unload_image_module_sp.get())
- {
- // When we unload, be sure to use the image info from the old list,
- // since that has sections correctly filled in.
- UnloadModuleSections (unload_image_module_sp.get(), *pos);
- unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
- }
- else
- {
- if (log)
- {
- log->Printf ("Could not find module for unloading info entry:");
- image_infos[idx].PutToLog(log);
- }
- }
-
- // Then remove it from the m_dyld_image_infos:
-
- m_dyld_image_infos.erase(pos);
- break;
- }
- }
-
- if (pos == end)
- {
- if (log)
- {
- log->Printf ("Could not find image_info entry for unloading image:");
- image_infos[idx].PutToLog(log);
- }
- }
+ log->PutCString("Failed reading image infos array.");
+ return false;
+ }
+
+ if (log)
+ log->Printf("Removing %d modules.", image_infos_count);
+
+ ModuleList unloaded_module_list;
+ for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
+ if (log) {
+ log->Printf("Removing module at address=0x%16.16" PRIx64 ".",
+ image_infos[idx].address);
+ image_infos[idx].PutToLog(log);
}
- if (unloaded_module_list.GetSize() > 0)
- {
- if (log)
- {
- log->PutCString("Unloaded:");
- unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
+
+ // Remove this image_infos from the m_all_image_infos. We do the comparison
+ // by address
+ // rather than by file spec because we can have many modules with the same
+ // "file spec" in the
+ // case that they are modules loaded from memory.
+ //
+ // Also copy over the uuid from the old entry to the removed entry so we can
+ // use it to lookup the module in the module list.
+
+ ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+ for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
+ if (image_infos[idx].address == (*pos).address) {
+ image_infos[idx].uuid = (*pos).uuid;
+
+ // Add the module from this image_info to the "unloaded_module_list".
+ // We'll remove them all at
+ // one go later on.
+
+ ModuleSP unload_image_module_sp(
+ FindTargetModuleForImageInfo(image_infos[idx], false, NULL));
+ if (unload_image_module_sp.get()) {
+ // When we unload, be sure to use the image info from the old list,
+ // since that has sections correctly filled in.
+ UnloadModuleSections(unload_image_module_sp.get(), *pos);
+ unloaded_module_list.AppendIfNeeded(unload_image_module_sp);
+ } else {
+ if (log) {
+ log->Printf("Could not find module for unloading info entry:");
+ image_infos[idx].PutToLog(log);
+ }
}
- m_process->GetTarget().GetImages().Remove (unloaded_module_list);
+
+ // Then remove it from the m_dyld_image_infos:
+
+ m_dyld_image_infos.erase(pos);
+ break;
+ }
}
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- return true;
-}
-bool
-DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
- uint32_t image_infos_count,
- ImageInfo::collection &image_infos)
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- const ByteOrder endian = GetByteOrderFromMagic (m_dyld.header.magic);
- const uint32_t addr_size = m_dyld.GetAddressByteSize();
-
- image_infos.resize(image_infos_count);
- const size_t count = image_infos.size() * 3 * addr_size;
- DataBufferHeap info_data(count, 0);
- Error error;
- const size_t bytes_read = m_process->ReadMemory (image_infos_addr,
- info_data.GetBytes(),
- info_data.GetByteSize(),
- error);
- if (bytes_read == count)
- {
- lldb::offset_t info_data_offset = 0;
- DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
- for (size_t i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
- {
- image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
- lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
- image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
-
- char raw_path[PATH_MAX];
- m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error);
- // don't resolve the path
- if (error.Success())
- {
- const bool resolve_path = false;
- image_infos[i].file_spec.SetFile(raw_path, resolve_path);
- }
- }
- return true;
+ if (pos == end) {
+ if (log) {
+ log->Printf("Could not find image_info entry for unloading image:");
+ image_infos[idx].PutToLog(log);
+ }
}
- else
- {
- return false;
+ }
+ if (unloaded_module_list.GetSize() > 0) {
+ if (log) {
+ log->PutCString("Unloaded:");
+ unloaded_module_list.LogUUIDAndPaths(
+ log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
+ }
+ m_process->GetTarget().GetImages().Remove(unloaded_module_list);
+ }
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ return true;
+}
+
+bool DynamicLoaderMacOSXDYLD::ReadImageInfos(
+ lldb::addr_t image_infos_addr, uint32_t image_infos_count,
+ ImageInfo::collection &image_infos) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ const ByteOrder endian = GetByteOrderFromMagic(m_dyld.header.magic);
+ const uint32_t addr_size = m_dyld.GetAddressByteSize();
+
+ image_infos.resize(image_infos_count);
+ const size_t count = image_infos.size() * 3 * addr_size;
+ DataBufferHeap info_data(count, 0);
+ Error error;
+ const size_t bytes_read = m_process->ReadMemory(
+ image_infos_addr, info_data.GetBytes(), info_data.GetByteSize(), error);
+ if (bytes_read == count) {
+ lldb::offset_t info_data_offset = 0;
+ DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(),
+ endian, addr_size);
+ for (size_t i = 0;
+ i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset);
+ i++) {
+ image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
+ lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
+ image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
+
+ char raw_path[PATH_MAX];
+ m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path),
+ error);
+ // don't resolve the path
+ if (error.Success()) {
+ const bool resolve_path = false;
+ image_infos[i].file_spec.SetFile(raw_path, resolve_path);
+ }
}
+ return true;
+ } else {
+ return false;
+ }
}
//----------------------------------------------------------------------
@@ -753,74 +719,68 @@ DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
// we're reading the dyld infos. Return true if we actually read anything,
// and false otherwise.
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id
- || m_dyld_image_infos.size() != 0)
- return false;
-
- if (ReadAllImageInfosStructure ())
- {
- // Nothing to load or unload?
- if (m_dyld_all_image_infos.dylib_info_count == 0)
- return true;
-
- if (m_dyld_all_image_infos.dylib_info_addr == 0)
- {
- // DYLD is updating the images now. So we should say we have no images, and then we'll
- // figure it out when we hit the added breakpoint.
- return false;
- }
- else
- {
- if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr,
- m_dyld_all_image_infos.dylib_info_count))
- {
- DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
- m_dyld_image_infos.clear();
- }
- }
+bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- // Now we have one more bit of business. If there is a library left in the images for our target that
- // doesn't have a load address, then it must be something that we were expecting to load (for instance we
- // read a load command for it) but it didn't in fact load - probably because DYLD_*_PATH pointed
- // to an equivalent version. We don't want it to stay in the target's module list or it will confuse
- // us, so unload it here.
- Target &target = m_process->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- ModuleList not_loaded_modules;
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
-
- size_t num_modules = target_modules.GetSize();
- for (size_t i = 0; i < num_modules; i++)
- {
- ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i);
- if (!module_sp->IsLoadedInTarget (&target))
- {
- if (log)
- {
- StreamString s;
- module_sp->GetDescription (&s);
- log->Printf ("Unloading pre-run module: %s.", s.GetData ());
- }
- not_loaded_modules.Append (module_sp);
- }
- }
-
- if (not_loaded_modules.GetSize() != 0)
- {
- target.GetImages().Remove(not_loaded_modules);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id ||
+ m_dyld_image_infos.size() != 0)
+ return false;
+
+ if (ReadAllImageInfosStructure()) {
+ // Nothing to load or unload?
+ if (m_dyld_all_image_infos.dylib_info_count == 0)
+ return true;
+
+ if (m_dyld_all_image_infos.dylib_info_addr == 0) {
+ // DYLD is updating the images now. So we should say we have no images,
+ // and then we'll
+ // figure it out when we hit the added breakpoint.
+ return false;
+ } else {
+ if (!AddModulesUsingImageInfosAddress(
+ m_dyld_all_image_infos.dylib_info_addr,
+ m_dyld_all_image_infos.dylib_info_count)) {
+ DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
+ m_dyld_image_infos.clear();
+ }
+ }
+
+ // Now we have one more bit of business. If there is a library left in the
+ // images for our target that
+ // doesn't have a load address, then it must be something that we were
+ // expecting to load (for instance we
+ // read a load command for it) but it didn't in fact load - probably because
+ // DYLD_*_PATH pointed
+ // to an equivalent version. We don't want it to stay in the target's
+ // module list or it will confuse
+ // us, so unload it here.
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_modules = target.GetImages();
+ ModuleList not_loaded_modules;
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
+ size_t num_modules = target_modules.GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+ if (!module_sp->IsLoadedInTarget(&target)) {
+ if (log) {
+ StreamString s;
+ module_sp->GetDescription(&s);
+ log->Printf("Unloading pre-run module: %s.", s.GetData());
}
+ not_loaded_modules.Append(module_sp);
+ }
+ }
- return true;
+ if (not_loaded_modules.GetSize() != 0) {
+ target.GetImages().Remove(not_loaded_modules);
}
- else
- return false;
+
+ return true;
+ } else
+ return false;
}
//----------------------------------------------------------------------
@@ -829,166 +789,161 @@ DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
//
// Returns true if we succeed, false if we fail for any reason.
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
-{
- DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
- Error error;
- size_t bytes_read = m_process->ReadMemory (addr,
- header_bytes.GetBytes(),
- header_bytes.GetByteSize(),
- error);
- if (bytes_read == sizeof(llvm::MachO::mach_header))
- {
- lldb::offset_t offset = 0;
- ::memset (header, 0, sizeof(llvm::MachO::mach_header));
-
- // Get the magic byte unswapped so we can figure out what we are dealing with
- DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), endian::InlHostByteOrder(), 4);
- header->magic = data.GetU32(&offset);
- lldb::addr_t load_cmd_addr = addr;
- data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
- switch (header->magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_CIGAM:
- data.SetAddressByteSize(4);
- load_cmd_addr += sizeof(llvm::MachO::mach_header);
- break;
-
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM_64:
- data.SetAddressByteSize(8);
- load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
- break;
-
- default:
- return false;
- }
-
- // Read the rest of dyld's mach header
- if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
- {
- if (load_command_data == NULL)
- return true; // We were able to read the mach_header and weren't asked to read the load command bytes
-
- DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
-
- size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
- load_cmd_data_sp->GetBytes(),
- load_cmd_data_sp->GetByteSize(),
- error);
-
- if (load_cmd_bytes_read == header->sizeofcmds)
- {
- // Set the load command data and also set the correct endian
- // swap settings and the correct address size
- load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
- load_command_data->SetByteOrder(data.GetByteOrder());
- load_command_data->SetAddressByteSize(data.GetAddressByteSize());
- return true; // We successfully read the mach_header and the load command data
- }
+bool DynamicLoaderMacOSXDYLD::ReadMachHeader(lldb::addr_t addr,
+ llvm::MachO::mach_header *header,
+ DataExtractor *load_command_data) {
+ DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
+ Error error;
+ size_t bytes_read = m_process->ReadMemory(addr, header_bytes.GetBytes(),
+ header_bytes.GetByteSize(), error);
+ if (bytes_read == sizeof(llvm::MachO::mach_header)) {
+ lldb::offset_t offset = 0;
+ ::memset(header, 0, sizeof(llvm::MachO::mach_header));
+
+ // Get the magic byte unswapped so we can figure out what we are dealing
+ // with
+ DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(),
+ endian::InlHostByteOrder(), 4);
+ header->magic = data.GetU32(&offset);
+ lldb::addr_t load_cmd_addr = addr;
+ data.SetByteOrder(
+ DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
+ switch (header->magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_CIGAM:
+ data.SetAddressByteSize(4);
+ load_cmd_addr += sizeof(llvm::MachO::mach_header);
+ break;
+
+ case llvm::MachO::MH_MAGIC_64:
+ case llvm::MachO::MH_CIGAM_64:
+ data.SetAddressByteSize(8);
+ load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
+ break;
+
+ default:
+ return false;
+ }
- return false; // We weren't able to read the load command data
- }
+ // Read the rest of dyld's mach header
+ if (data.GetU32(&offset, &header->cputype,
+ (sizeof(llvm::MachO::mach_header) / sizeof(uint32_t)) -
+ 1)) {
+ if (load_command_data == NULL)
+ return true; // We were able to read the mach_header and weren't asked
+ // to read the load command bytes
+
+ DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
+
+ size_t load_cmd_bytes_read =
+ m_process->ReadMemory(load_cmd_addr, load_cmd_data_sp->GetBytes(),
+ load_cmd_data_sp->GetByteSize(), error);
+
+ if (load_cmd_bytes_read == header->sizeofcmds) {
+ // Set the load command data and also set the correct endian
+ // swap settings and the correct address size
+ load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
+ load_command_data->SetByteOrder(data.GetByteOrder());
+ load_command_data->SetAddressByteSize(data.GetAddressByteSize());
+ return true; // We successfully read the mach_header and the load
+ // command data
+ }
+
+ return false; // We weren't able to read the load command data
}
- return false; // We failed the read the mach_header
+ }
+ return false; // We failed the read the mach_header
}
-
//----------------------------------------------------------------------
// Parse the load commands for an image
//----------------------------------------------------------------------
-uint32_t
-DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, ImageInfo& dylib_info, FileSpec *lc_id_dylinker)
-{
- lldb::offset_t offset = 0;
- uint32_t cmd_idx;
- Segment segment;
- dylib_info.Clear (true);
-
- for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
- {
- // Clear out any load command specific data from DYLIB_INFO since
- // we are about to read it.
-
- if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
- {
- llvm::MachO::load_command load_cmd;
- lldb::offset_t load_cmd_offset = offset;
- load_cmd.cmd = data.GetU32 (&offset);
- load_cmd.cmdsize = data.GetU32 (&offset);
- switch (load_cmd.cmd)
- {
- case llvm::MachO::LC_SEGMENT:
- {
- segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
- // We are putting 4 uint32_t values 4 uint64_t values so
- // we have to use multiple 32 bit gets below.
- segment.vmaddr = data.GetU32 (&offset);
- segment.vmsize = data.GetU32 (&offset);
- segment.fileoff = data.GetU32 (&offset);
- segment.filesize = data.GetU32 (&offset);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- dylib_info.segments.push_back (segment);
- }
- break;
-
- case llvm::MachO::LC_SEGMENT_64:
- {
- segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
- // Extract vmaddr, vmsize, fileoff, and filesize all at once
- data.GetU64(&offset, &segment.vmaddr, 4);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- dylib_info.segments.push_back (segment);
- }
- break;
-
- case llvm::MachO::LC_ID_DYLINKER:
- if (lc_id_dylinker)
- {
- 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);
- }
- break;
-
- case llvm::MachO::LC_UUID:
- dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
- break;
-
- default:
- break;
- }
- // Set offset to be the beginning of the next load command.
- offset = load_cmd_offset + load_cmd.cmdsize;
+uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
+ ImageInfo &dylib_info,
+ FileSpec *lc_id_dylinker) {
+ lldb::offset_t offset = 0;
+ uint32_t cmd_idx;
+ Segment segment;
+ dylib_info.Clear(true);
+
+ for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) {
+ // Clear out any load command specific data from DYLIB_INFO since
+ // we are about to read it.
+
+ if (data.ValidOffsetForDataOfSize(offset,
+ sizeof(llvm::MachO::load_command))) {
+ llvm::MachO::load_command load_cmd;
+ lldb::offset_t load_cmd_offset = offset;
+ load_cmd.cmd = data.GetU32(&offset);
+ load_cmd.cmdsize = data.GetU32(&offset);
+ switch (load_cmd.cmd) {
+ case llvm::MachO::LC_SEGMENT: {
+ segment.name.SetTrimmedCStringWithLength(
+ (const char *)data.GetData(&offset, 16), 16);
+ // We are putting 4 uint32_t values 4 uint64_t values so
+ // we have to use multiple 32 bit gets below.
+ segment.vmaddr = data.GetU32(&offset);
+ segment.vmsize = data.GetU32(&offset);
+ segment.fileoff = data.GetU32(&offset);
+ segment.filesize = data.GetU32(&offset);
+ // Extract maxprot, initprot, nsects and flags all at once
+ data.GetU32(&offset, &segment.maxprot, 4);
+ dylib_info.segments.push_back(segment);
+ } break;
+
+ case llvm::MachO::LC_SEGMENT_64: {
+ segment.name.SetTrimmedCStringWithLength(
+ (const char *)data.GetData(&offset, 16), 16);
+ // Extract vmaddr, vmsize, fileoff, and filesize all at once
+ data.GetU64(&offset, &segment.vmaddr, 4);
+ // Extract maxprot, initprot, nsects and flags all at once
+ data.GetU32(&offset, &segment.maxprot, 4);
+ dylib_info.segments.push_back(segment);
+ } break;
+
+ case llvm::MachO::LC_ID_DYLINKER:
+ if (lc_id_dylinker) {
+ 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);
}
+ break;
+
+ case llvm::MachO::LC_UUID:
+ dylib_info.uuid.SetBytes(data.GetData(&offset, 16));
+ break;
+
+ default:
+ break;
+ }
+ // Set offset to be the beginning of the next load command.
+ offset = load_cmd_offset + load_cmd.cmdsize;
}
-
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = dylib_info.segments.size();
- for (size_t i = 0; i < num_sections; ++i)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- if ((dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0) || (dylib_info.segments[i].name == ConstString("__TEXT")))
- {
- dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
- break;
- }
+ }
+
+ // All sections listed in the dyld image info structure will all
+ // either be fixed up already, or they will all be off by a single
+ // slide amount that is determined by finding the first segment
+ // that is at file offset zero which also has bytes (a file size
+ // that is greater than zero) in the object file.
+
+ // Determine the slide amount (if any)
+ const size_t num_sections = dylib_info.segments.size();
+ for (size_t i = 0; i < num_sections; ++i) {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ if ((dylib_info.segments[i].fileoff == 0 &&
+ dylib_info.segments[i].filesize > 0) ||
+ (dylib_info.segments[i].name == ConstString("__TEXT"))) {
+ dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
+ // We have found the slide amount, so we can exit
+ // this for loop.
+ break;
}
- return cmd_idx;
+ }
+ return cmd_idx;
}
//----------------------------------------------------------------------
@@ -996,240 +951,278 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, ImageInfo
// _dyld_all_image_infos structure points to and cache the results.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable)
-{
- uint32_t exe_idx = UINT32_MAX;
- // Read any UUID values that we can get
- for (uint32_t i = 0; i < infos_count; i++)
- {
- if (!image_infos[i].UUIDValid())
- {
- DataExtractor data; // Load command data
- if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data))
- continue;
-
- ParseLoadCommands (data, image_infos[i], NULL);
-
- if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
- exe_idx = i;
-
- }
+void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(
+ ImageInfo::collection &image_infos, uint32_t infos_count,
+ bool update_executable) {
+ uint32_t exe_idx = UINT32_MAX;
+ // Read any UUID values that we can get
+ for (uint32_t i = 0; i < infos_count; i++) {
+ if (!image_infos[i].UUIDValid()) {
+ DataExtractor data; // Load command data
+ if (!ReadMachHeader(image_infos[i].address, &image_infos[i].header,
+ &data))
+ continue;
+
+ ParseLoadCommands(data, image_infos[i], NULL);
+
+ if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
+ exe_idx = i;
}
-
- Target &target = m_process->GetTarget();
-
- if (exe_idx < image_infos.size())
- {
- const bool can_create = true;
- ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[exe_idx], can_create, NULL));
-
- if (exe_module_sp)
- {
- UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
-
- if (exe_module_sp.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. Also when setting the
- // executable module, it will clear the targets module list, and if we
- // have an in memory dyld module, it will get removed from the list
- // so we will need to add it back after setting the executable module,
- // so we first try and see if we already have a weak pointer to the
- // dyld module, make it into a shared pointer, then add the executable,
- // then re-add it back to make sure it is always in the list.
- ModuleSP dyld_module_sp(GetDYLDModule ());
-
- const bool get_dependent_images = false;
- m_process->GetTarget().SetExecutableModule (exe_module_sp,
- get_dependent_images);
-
- if (dyld_module_sp)
- {
- if(target.GetImages().AppendIfNeeded (dyld_module_sp))
- {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
-
- // Also add it to the section list.
- UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
- }
- }
- }
+ }
+
+ Target &target = m_process->GetTarget();
+
+ if (exe_idx < image_infos.size()) {
+ const bool can_create = true;
+ ModuleSP exe_module_sp(
+ FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL));
+
+ if (exe_module_sp) {
+ UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);
+
+ if (exe_module_sp.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. Also when setting the
+ // executable module, it will clear the targets module list, and if we
+ // have an in memory dyld module, it will get removed from the list
+ // so we will need to add it back after setting the executable module,
+ // so we first try and see if we already have a weak pointer to the
+ // dyld module, make it into a shared pointer, then add the executable,
+ // then re-add it back to make sure it is always in the list.
+ ModuleSP dyld_module_sp(GetDYLDModule());
+
+ const bool get_dependent_images = false;
+ m_process->GetTarget().SetExecutableModule(exe_module_sp,
+ get_dependent_images);
+
+ if (dyld_module_sp) {
+ if (target.GetImages().AppendIfNeeded(dyld_module_sp)) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
+ // Also add it to the section list.
+ UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
+ }
}
+ }
}
+ }
}
-
//----------------------------------------------------------------------
// Dump the _dyld_all_image_infos members and all current image infos
// that we have parsed to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
-{
- if (log == NULL)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
- m_dyld_all_image_infos.version,
- m_dyld_all_image_infos.dylib_info_count,
- (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
- (uint64_t)m_dyld_all_image_infos.notification);
- size_t i;
- const size_t count = m_dyld_image_infos.size();
- if (count > 0)
- {
- log->PutCString("Loaded:");
- for (i = 0; i<count; i++)
- m_dyld_image_infos[i].PutToLog(log);
- }
-}
+void DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
-bool
-DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
-{
- DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
- if (m_break_id == LLDB_INVALID_BREAK_ID)
- {
- if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
- {
- Address so_addr;
- // Set the notification breakpoint and install a breakpoint
- // callback function that will get called each time the
- // breakpoint gets hit. We will use this to track when shared
- // libraries get loaded/unloaded.
- bool resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr);
- if (!resolved)
- {
- ModuleSP dyld_module_sp = m_dyld_module_wp.lock();
- if (dyld_module_sp)
- {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
-
- UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
- resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr);
- }
- }
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ log->Printf(
+ "dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64
+ ", notify=0x%8.8" PRIx64 " }",
+ m_dyld_all_image_infos.version, m_dyld_all_image_infos.dylib_info_count,
+ (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
+ (uint64_t)m_dyld_all_image_infos.notification);
+ size_t i;
+ const size_t count = m_dyld_image_infos.size();
+ if (count > 0) {
+ log->PutCString("Loaded:");
+ for (i = 0; i < count; i++)
+ m_dyld_image_infos[i].PutToLog(log);
+ }
+}
- if (resolved)
- {
- Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true, false).get();
- dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
- dyld_break->SetBreakpointKind ("shared-library-event");
- m_break_id = dyld_break->GetID();
- }
+bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() {
+ DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n",
+ __FUNCTION__, StateAsCString(m_process->GetState()));
+ if (m_break_id == LLDB_INVALID_BREAK_ID) {
+ if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) {
+ Address so_addr;
+ // Set the notification breakpoint and install a breakpoint
+ // callback function that will get called each time the
+ // breakpoint gets hit. We will use this to track when shared
+ // libraries get loaded/unloaded.
+ bool resolved = m_process->GetTarget().ResolveLoadAddress(
+ m_dyld_all_image_infos.notification, so_addr);
+ if (!resolved) {
+ ModuleSP dyld_module_sp = GetDYLDModule();
+ if (dyld_module_sp) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
+ UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
+ resolved = m_process->GetTarget().ResolveLoadAddress(
+ m_dyld_all_image_infos.notification, so_addr);
}
+ }
+
+ if (resolved) {
+ Breakpoint *dyld_break =
+ m_process->GetTarget().CreateBreakpoint(so_addr, true, false).get();
+ dyld_break->SetCallback(DynamicLoaderMacOSXDYLD::NotifyBreakpointHit,
+ this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_break_id = dyld_break->GetID();
+ }
}
- return m_break_id != LLDB_INVALID_BREAK_ID;
+ }
+ return m_break_id != LLDB_INVALID_BREAK_ID;
}
-Error
-DynamicLoaderMacOSXDYLD::CanLoadImage ()
-{
- Error error;
- // In order for us to tell if we can load a shared library we verify that
- // the dylib_info_addr isn't zero (which means no shared libraries have
- // been set yet, or dyld is currently mucking with the shared library list).
- if (ReadAllImageInfosStructure ())
- {
- // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
- // TODO: check the malloc lock?
- // TODO: check the objective C lock?
- if (m_dyld_all_image_infos.dylib_info_addr != 0)
- return error; // Success
- }
-
- error.SetErrorString("unsafe to load or unload shared libraries");
- return error;
+Error DynamicLoaderMacOSXDYLD::CanLoadImage() {
+ Error error;
+ // In order for us to tell if we can load a shared library we verify that
+ // the dylib_info_addr isn't zero (which means no shared libraries have
+ // been set yet, or dyld is currently mucking with the shared library list).
+ if (ReadAllImageInfosStructure()) {
+ // TODO: also check the _dyld_global_lock_held variable in
+ // libSystem.B.dylib?
+ // TODO: check the malloc lock?
+ // TODO: check the objective C lock?
+ if (m_dyld_all_image_infos.dylib_info_addr != 0)
+ return error; // Success
+ }
+
+ error.SetErrorString("unsafe to load or unload shared libraries");
+ return error;
}
-void
-DynamicLoaderMacOSXDYLD::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
+bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
+ lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
+ LazyBool &private_shared_cache) {
+ base_address = LLDB_INVALID_ADDRESS;
+ uuid.Clear();
+ using_shared_cache = eLazyBoolCalculate;
+ private_shared_cache = eLazyBoolCalculate;
+
+ if (m_process) {
+ addr_t all_image_infos = m_process->GetImageInfoAddress();
+
+ // The address returned by GetImageInfoAddress may be the address of dyld
+ // (don't want)
+ // or it may be the address of the dyld_all_image_infos structure (want).
+ // The first four
+ // bytes will be either the version field (all_image_infos) or a Mach-O file
+ // magic constant.
+ // Version 13 and higher of dyld_all_image_infos is required to get the
+ // sharedCacheUUID field.
+
+ Error err;
+ uint32_t version_or_magic =
+ m_process->ReadUnsignedIntegerFromMemory(all_image_infos, 4, -1, err);
+ if (version_or_magic != static_cast<uint32_t>(-1) &&
+ version_or_magic != llvm::MachO::MH_MAGIC &&
+ version_or_magic != llvm::MachO::MH_CIGAM &&
+ version_or_magic != llvm::MachO::MH_MAGIC_64 &&
+ version_or_magic != llvm::MachO::MH_CIGAM_64 &&
+ version_or_magic >= 13) {
+ addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
+ int wordsize = m_process->GetAddressByteSize();
+ if (wordsize == 8) {
+ sharedCacheUUID_address =
+ all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
+ }
+ if (wordsize == 4) {
+ sharedCacheUUID_address =
+ all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
+ }
+ if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS) {
+ uuid_t shared_cache_uuid;
+ if (m_process->ReadMemory(sharedCacheUUID_address, shared_cache_uuid,
+ sizeof(uuid_t), err) == sizeof(uuid_t)) {
+ uuid.SetBytes(shared_cache_uuid);
+ if (uuid.IsValid()) {
+ using_shared_cache = eLazyBoolYes;
+ }
+ }
+
+ if (version_or_magic >= 15) {
+ // The sharedCacheBaseAddress field is the next one in the
+ // dyld_all_image_infos struct.
+ addr_t sharedCacheBaseAddr_address = sharedCacheUUID_address + 16;
+ Error error;
+ base_address = m_process->ReadUnsignedIntegerFromMemory(
+ sharedCacheBaseAddr_address, wordsize, LLDB_INVALID_ADDRESS,
+ error);
+ if (error.Fail())
+ base_address = LLDB_INVALID_ADDRESS;
+ }
-void
-DynamicLoaderMacOSXDYLD::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+ return true;
+ }
+
+ //
+ // add
+ // NB: sharedCacheBaseAddress is the next field in dyld_all_image_infos
+ // after
+ // sharedCacheUUID -- that is, 16 bytes after it, if we wanted to fetch
+ // it.
+ }
+ }
+ return false;
}
+void DynamicLoaderMacOSXDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
-lldb_private::ConstString
-DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
-{
- static ConstString g_name("macosx-dyld");
- return g_name;
+void DynamicLoaderMacOSXDYLD::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-const char *
-DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
+lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginNameStatic() {
+ static ConstString g_name("macosx-dyld");
+ return g_name;
}
+const char *DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library loads/unloads "
+ "in MacOSX user processes.";
+}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-DynamicLoaderMacOSXDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-DynamicLoaderMacOSXDYLD::GetPluginVersion()
-{
- return 1;
-}
+uint32_t DynamicLoaderMacOSXDYLD::GetPluginVersion() { return 1; }
-uint32_t
-DynamicLoaderMacOSXDYLD::AddrByteSize()
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+uint32_t DynamicLoaderMacOSXDYLD::AddrByteSize() {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- switch (m_dyld.header.magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_CIGAM:
- return 4;
-
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM_64:
- return 8;
-
- default:
- break;
- }
- return 0;
+ switch (m_dyld.header.magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_CIGAM:
+ return 4;
+
+ case llvm::MachO::MH_MAGIC_64:
+ case llvm::MachO::MH_CIGAM_64:
+ return 8;
+
+ default:
+ break;
+ }
+ return 0;
}
-lldb::ByteOrder
-DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic)
-{
- switch (magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- return endian::InlHostByteOrder();
-
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- return lldb::eByteOrderLittle;
- else
- return lldb::eByteOrderBig;
-
- default:
- break;
- }
- return lldb::eByteOrderInvalid;
+lldb::ByteOrder DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic) {
+ switch (magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_MAGIC_64:
+ return endian::InlHostByteOrder();
+
+ case llvm::MachO::MH_CIGAM:
+ case llvm::MachO::MH_CIGAM_64:
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ return lldb::eByteOrderLittle;
+ else
+ return lldb::eByteOrderBig;
+
+ default:
+ break;
+ }
+ return lldb::eByteOrderInvalid;
}
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index 637bd8640d24..25ccf702e965 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -7,197 +7,180 @@
//
//===----------------------------------------------------------------------===//
+// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
+// watchOS)
+// 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
+// an array of (load address, mod time, file path) tuples.
+//
+// As of late 2016, the new DynamicLoaderMacOS plugin should be used, which uses
+// dyld SPI functions to get the same information without reading internal dyld
+// data structures.
+
#ifndef liblldb_DynamicLoaderMacOSXDYLD_h_
#define liblldb_DynamicLoaderMacOSXDYLD_h_
// C Includes
// C++ Includes
-#include <vector>
#include <mutex>
+#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/SafeMachO.h"
#include "DynamicLoaderDarwin.h"
-class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin
-{
+class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin {
public:
- DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
+ DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
- virtual ~DynamicLoaderMacOSXDYLD() override;
+ virtual ~DynamicLoaderMacOSXDYLD() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- bool
- ProcessDidExec() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ bool ProcessDidExec() override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ bool GetSharedCacheInformation(
+ lldb::addr_t &base_address, lldb_private::UUID &uuid,
+ lldb_private::LazyBool &using_shared_cache,
+ lldb_private::LazyBool &private_shared_cache) override;
- uint32_t
- GetPluginVersion() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- void
- PutToLog(lldb_private::Log *log) const;
-
- void
- DoInitialImageFetch () override;
-
- bool
- NeedToDoInitialImageFetch () override;
-
- bool
- DidSetNotificationBreakpoint () override;
-
- void
- DoClear () override;
-
- bool
- ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
-
- static bool
- NotifyBreakpointHit (void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- uint32_t
- AddrByteSize();
-
- bool
- ReadMachHeader (lldb::addr_t addr,
- llvm::MachO::mach_header *header,
- lldb_private::DataExtractor *load_command_data);
-
- uint32_t
- ParseLoadCommands (const lldb_private::DataExtractor& data,
- ImageInfo& dylib_info,
- lldb_private::FileSpec *lc_id_dylinker);
-
- struct DYLDAllImageInfos
- {
- uint32_t version;
- uint32_t dylib_info_count; // Version >= 1
- lldb::addr_t dylib_info_addr; // Version >= 1
- lldb::addr_t notification; // Version >= 1
- bool processDetachedFromSharedRegion; // Version >= 1
- bool libSystemInitialized; // Version >= 2
- lldb::addr_t dyldImageLoadAddress; // Version >= 2
-
- DYLDAllImageInfos() :
- version (0),
- dylib_info_count (0),
- dylib_info_addr (LLDB_INVALID_ADDRESS),
- notification (LLDB_INVALID_ADDRESS),
- processDetachedFromSharedRegion (false),
- libSystemInitialized (false),
- dyldImageLoadAddress (LLDB_INVALID_ADDRESS)
- {
- }
-
- void
- Clear()
- {
- version = 0;
- dylib_info_count = 0;
- dylib_info_addr = LLDB_INVALID_ADDRESS;
- notification = LLDB_INVALID_ADDRESS;
- processDetachedFromSharedRegion = false;
- libSystemInitialized = false;
- dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
- }
-
- bool
- IsValid() const
- {
- return version >= 1 || version <= 6;
- }
- };
-
- static lldb::ByteOrder
- GetByteOrderFromMagic(uint32_t magic);
-
- bool
- SetNotificationBreakpoint () override;
-
- void
- ClearNotificationBreakpoint () override;
-
- // There is a little tricky bit where you might initially attach while dyld is updating
- // the all_image_infos, and you can't read the infos, so you have to continue and pick it
- // up when you hit the update breakpoint. At that point, you need to run this initialize
- // function, but when you do it that way you DON'T need to do the extra work you would at
- // the breakpoint.
- // So this function will only do actual work if the image infos haven't been read yet.
- // If it does do any work, then it will return true, and false otherwise. That way you can
- // call it in the breakpoint action, and if it returns true you're done.
- bool
- InitializeFromAllImageInfos ();
-
- bool
- ReadAllImageInfosStructure ();
-
- bool
- AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
-
- bool
- RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
-
- void
- UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
-
- bool
- ReadImageInfos (lldb::addr_t image_infos_addr,
- uint32_t image_infos_count,
- ImageInfo::collection &image_infos);
-
- lldb::addr_t m_dyld_all_image_infos_addr;
- DYLDAllImageInfos m_dyld_all_image_infos;
- uint32_t m_dyld_all_image_infos_stop_id;
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
- bool m_process_image_addr_is_all_images_infos;
+ void PutToLog(lldb_private::Log *log) const;
+
+ void DoInitialImageFetch() override;
+
+ bool NeedToDoInitialImageFetch() override;
+
+ bool DidSetNotificationBreakpoint() override;
+
+ void DoClear() override;
+
+ bool ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr);
+
+ static bool
+ NotifyBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ uint32_t AddrByteSize();
+
+ bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header,
+ lldb_private::DataExtractor *load_command_data);
+
+ uint32_t ParseLoadCommands(const lldb_private::DataExtractor &data,
+ ImageInfo &dylib_info,
+ lldb_private::FileSpec *lc_id_dylinker);
+
+ struct DYLDAllImageInfos {
+ uint32_t version;
+ uint32_t dylib_info_count; // Version >= 1
+ lldb::addr_t dylib_info_addr; // Version >= 1
+ lldb::addr_t notification; // Version >= 1
+ bool processDetachedFromSharedRegion; // Version >= 1
+ bool libSystemInitialized; // Version >= 2
+ lldb::addr_t dyldImageLoadAddress; // Version >= 2
+
+ DYLDAllImageInfos()
+ : version(0), dylib_info_count(0),
+ dylib_info_addr(LLDB_INVALID_ADDRESS),
+ notification(LLDB_INVALID_ADDRESS),
+ processDetachedFromSharedRegion(false), libSystemInitialized(false),
+ dyldImageLoadAddress(LLDB_INVALID_ADDRESS) {}
+
+ void Clear() {
+ version = 0;
+ dylib_info_count = 0;
+ dylib_info_addr = LLDB_INVALID_ADDRESS;
+ notification = LLDB_INVALID_ADDRESS;
+ processDetachedFromSharedRegion = false;
+ libSystemInitialized = false;
+ dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
+ }
+
+ bool IsValid() const { return version >= 1 || version <= 6; }
+ };
+
+ static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
+
+ bool SetNotificationBreakpoint() override;
+
+ void ClearNotificationBreakpoint() override;
+
+ // There is a little tricky bit where you might initially attach while dyld is
+ // updating
+ // the all_image_infos, and you can't read the infos, so you have to continue
+ // and pick it
+ // up when you hit the update breakpoint. At that point, you need to run this
+ // initialize
+ // function, but when you do it that way you DON'T need to do the extra work
+ // you would at
+ // the breakpoint.
+ // So this function will only do actual work if the image infos haven't been
+ // read yet.
+ // If it does do any work, then it will return true, and false otherwise.
+ // That way you can
+ // call it in the breakpoint action, and if it returns true you're done.
+ bool InitializeFromAllImageInfos();
+
+ bool ReadAllImageInfosStructure();
+
+ bool AddModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
+ uint32_t image_infos_count);
+
+ bool RemoveModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
+ uint32_t image_infos_count);
+
+ void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
+ uint32_t infos_count,
+ bool update_executable);
+
+ bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count,
+ ImageInfo::collection &image_infos);
+
+ lldb::addr_t m_dyld_all_image_infos_addr;
+ DYLDAllImageInfos m_dyld_all_image_infos;
+ uint32_t m_dyld_all_image_infos_stop_id;
+ lldb::user_id_t m_break_id;
+ mutable std::recursive_mutex m_mutex;
+ bool m_process_image_addr_is_all_images_infos;
private:
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOSXDYLD);
};
#endif // liblldb_DynamicLoaderMacOSXDYLD_h_
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
index 04a6792fbf01..ec655c6f9b32 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
@@ -28,113 +28,92 @@
using namespace lldb;
using namespace lldb_private;
-static bool
-GetMaxU64(DataExtractor &data,
- lldb::offset_t *offset_ptr,
- uint64_t *value,
- unsigned int byte_size)
-{
- lldb::offset_t saved_offset = *offset_ptr;
- *value = data.GetMaxU64(offset_ptr, byte_size);
- return *offset_ptr != saved_offset;
+static bool GetMaxU64(DataExtractor &data, lldb::offset_t *offset_ptr,
+ uint64_t *value, unsigned int byte_size) {
+ lldb::offset_t saved_offset = *offset_ptr;
+ *value = data.GetMaxU64(offset_ptr, byte_size);
+ return *offset_ptr != saved_offset;
}
-static bool
-ParseAuxvEntry(DataExtractor &data,
- AuxVector::Entry &entry,
- lldb::offset_t *offset_ptr,
- unsigned int byte_size)
-{
- if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
- return false;
+static bool ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
+ lldb::offset_t *offset_ptr, unsigned int byte_size) {
+ if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
+ return false;
- if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
- return false;
+ if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
+ return false;
- return true;
+ return true;
}
-DataBufferSP
-AuxVector::GetAuxvData()
-{
- if (m_process)
- return m_process->GetAuxvData ();
- else
- return DataBufferSP ();
+DataBufferSP AuxVector::GetAuxvData() {
+ if (m_process)
+ return m_process->GetAuxvData();
+ else
+ return DataBufferSP();
}
-void
-AuxVector::ParseAuxv(DataExtractor &data)
-{
- const unsigned int byte_size = m_process->GetAddressByteSize();
- lldb::offset_t offset = 0;
+void AuxVector::ParseAuxv(DataExtractor &data) {
+ const unsigned int byte_size = m_process->GetAddressByteSize();
+ lldb::offset_t offset = 0;
- for (;;)
- {
- Entry entry;
+ for (;;) {
+ Entry entry;
- if (!ParseAuxvEntry(data, entry, &offset, byte_size))
- break;
+ if (!ParseAuxvEntry(data, entry, &offset, byte_size))
+ break;
- if (entry.type == AT_NULL)
- break;
+ if (entry.type == AT_NULL)
+ break;
- if (entry.type == AT_IGNORE)
- continue;
+ if (entry.type == AT_IGNORE)
+ continue;
- m_auxv.push_back(entry);
- }
+ m_auxv.push_back(entry);
+ }
}
-AuxVector::AuxVector(Process *process)
- : m_process(process)
-{
- DataExtractor data;
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+AuxVector::AuxVector(Process *process) : m_process(process) {
+ DataExtractor data;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ data.SetData(GetAuxvData());
+ data.SetByteOrder(m_process->GetByteOrder());
+ data.SetAddressByteSize(m_process->GetAddressByteSize());
- data.SetData(GetAuxvData());
- data.SetByteOrder(m_process->GetByteOrder());
- data.SetAddressByteSize(m_process->GetAddressByteSize());
-
- ParseAuxv(data);
+ ParseAuxv(data);
- if (log)
- DumpToLog(log);
+ if (log)
+ DumpToLog(log);
}
-AuxVector::iterator
-AuxVector::FindEntry(EntryType type) const
-{
- for (iterator I = begin(); I != end(); ++I)
- {
- if (I->type == static_cast<uint64_t>(type))
- return I;
- }
+AuxVector::iterator AuxVector::FindEntry(EntryType type) const {
+ for (iterator I = begin(); I != end(); ++I) {
+ if (I->type == static_cast<uint64_t>(type))
+ return I;
+ }
- return end();
+ return end();
}
-void
-AuxVector::DumpToLog(Log *log) const
-{
- if (!log)
- return;
+void AuxVector::DumpToLog(Log *log) const {
+ if (!log)
+ return;
- log->PutCString("AuxVector: ");
- for (iterator I = begin(); I != end(); ++I)
- {
- log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value);
- }
+ log->PutCString("AuxVector: ");
+ for (iterator I = begin(); I != end(); ++I) {
+ log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type,
+ I->value);
+ }
}
-const char *
-AuxVector::GetEntryName(EntryType type)
-{
- const char *name = "AT_???";
+const char *AuxVector::GetEntryName(EntryType type) {
+ const char *name = "AT_???";
-#define ENTRY_NAME(_type) _type: name = #_type
- switch (type)
- {
+#define ENTRY_NAME(_type) \
+ _type: \
+ name = #_type
+ switch (type) {
case ENTRY_NAME(AT_NULL); break;
case ENTRY_NAME(AT_IGNORE); break;
case ENTRY_NAME(AT_EXECFD); break;
@@ -173,4 +152,3 @@ AuxVector::GetEntryName(EntryType type)
return name;
}
-
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
index 2d39eddcacc6..9c3e1b002a24 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
@@ -19,7 +19,7 @@
namespace lldb_private {
class DataExtractor;
-}
+}
/// @class AuxVector
/// @brief Represents a processes auxiliary vector.
@@ -31,85 +31,80 @@ class DataExtractor;
class AuxVector {
public:
- AuxVector(lldb_private::Process *process);
-
- struct Entry {
- uint64_t type;
- uint64_t value;
-
- Entry() : type(0), value(0) { }
- };
-
- /// Constants describing the type of entry.
- /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX information.
- enum EntryType {
- AT_NULL = 0, ///< End of auxv.
- AT_IGNORE = 1, ///< Ignore entry.
- AT_EXECFD = 2, ///< File descriptor of program.
- AT_PHDR = 3, ///< Program headers.
- AT_PHENT = 4, ///< Size of program header.
- AT_PHNUM = 5, ///< Number of program headers.
- AT_PAGESZ = 6, ///< Page size.
- AT_BASE = 7, ///< Interpreter base address.
- AT_FLAGS = 8, ///< Flags.
- AT_ENTRY = 9, ///< Program entry point.
- AT_NOTELF = 10, ///< Set if program is not an ELF.
- AT_UID = 11, ///< UID.
- AT_EUID = 12, ///< Effective UID.
- AT_GID = 13, ///< GID.
- AT_EGID = 14, ///< Effective GID.
- AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)).
- AT_PLATFORM = 15, ///< String identifying platform.
- AT_HWCAP = 16, ///< Machine dependent hints about processor capabilities.
- AT_FPUCW = 18, ///< Used FPU control word.
- AT_DCACHEBSIZE = 19, ///< Data cache block size.
- AT_ICACHEBSIZE = 20, ///< Instruction cache block size.
- AT_UCACHEBSIZE = 21, ///< Unified cache block size.
- AT_IGNOREPPC = 22, ///< Entry should be ignored.
- AT_SECURE = 23, ///< Boolean, was exec setuid-like?
- AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
- AT_RANDOM = 25, ///< Address of 16 random bytes.
- AT_EXECFN = 31, ///< Filename of executable.
- AT_SYSINFO = 32, ///< Pointer to the global system page used for system calls and other nice things.
- AT_SYSINFO_EHDR = 33,
- AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches.
- AT_L1D_CACHESHAPE = 35,
- AT_L2_CACHESHAPE = 36,
- AT_L3_CACHESHAPE = 37,
- };
+ AuxVector(lldb_private::Process *process);
+
+ struct Entry {
+ uint64_t type;
+ uint64_t value;
+
+ Entry() : type(0), value(0) {}
+ };
+
+ /// Constants describing the type of entry.
+ /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX information.
+ enum EntryType {
+ AT_NULL = 0, ///< End of auxv.
+ AT_IGNORE = 1, ///< Ignore entry.
+ AT_EXECFD = 2, ///< File descriptor of program.
+ AT_PHDR = 3, ///< Program headers.
+ AT_PHENT = 4, ///< Size of program header.
+ AT_PHNUM = 5, ///< Number of program headers.
+ AT_PAGESZ = 6, ///< Page size.
+ AT_BASE = 7, ///< Interpreter base address.
+ AT_FLAGS = 8, ///< Flags.
+ AT_ENTRY = 9, ///< Program entry point.
+ AT_NOTELF = 10, ///< Set if program is not an ELF.
+ AT_UID = 11, ///< UID.
+ AT_EUID = 12, ///< Effective UID.
+ AT_GID = 13, ///< GID.
+ AT_EGID = 14, ///< Effective GID.
+ AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)).
+ AT_PLATFORM = 15, ///< String identifying platform.
+ AT_HWCAP = 16, ///< Machine dependent hints about processor capabilities.
+ AT_FPUCW = 18, ///< Used FPU control word.
+ AT_DCACHEBSIZE = 19, ///< Data cache block size.
+ AT_ICACHEBSIZE = 20, ///< Instruction cache block size.
+ AT_UCACHEBSIZE = 21, ///< Unified cache block size.
+ AT_IGNOREPPC = 22, ///< Entry should be ignored.
+ AT_SECURE = 23, ///< Boolean, was exec setuid-like?
+ AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
+ AT_RANDOM = 25, ///< Address of 16 random bytes.
+ AT_EXECFN = 31, ///< Filename of executable.
+ AT_SYSINFO = 32, ///< Pointer to the global system page used for system
+ ///calls and other nice things.
+ AT_SYSINFO_EHDR = 33,
+ AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches.
+ AT_L1D_CACHESHAPE = 35,
+ AT_L2_CACHESHAPE = 36,
+ AT_L3_CACHESHAPE = 37,
+ };
private:
- typedef std::vector<Entry> EntryVector;
+ typedef std::vector<Entry> EntryVector;
public:
- typedef EntryVector::const_iterator iterator;
+ typedef EntryVector::const_iterator iterator;
- iterator begin() const { return m_auxv.begin(); }
- iterator end() const { return m_auxv.end(); }
+ iterator begin() const { return m_auxv.begin(); }
+ iterator end() const { return m_auxv.end(); }
- iterator
- FindEntry(EntryType type) const;
+ iterator FindEntry(EntryType type) const;
- static const char *
- GetEntryName(const Entry &entry) {
- return GetEntryName(static_cast<EntryType>(entry.type));
- }
+ static const char *GetEntryName(const Entry &entry) {
+ return GetEntryName(static_cast<EntryType>(entry.type));
+ }
- static const char *
- GetEntryName(EntryType type);
+ static const char *GetEntryName(EntryType type);
- void
- DumpToLog(lldb_private::Log *log) const;
+ void DumpToLog(lldb_private::Log *log) const;
private:
- lldb_private::Process *m_process;
- EntryVector m_auxv;
+ lldb_private::Process *m_process;
+ EntryVector m_auxv;
- lldb::DataBufferSP
- GetAuxvData();
+ lldb::DataBufferSP GetAuxvData();
- void
- ParseAuxv(lldb_private::DataExtractor &data);
+ void ParseAuxv(lldb_private::DataExtractor &data);
};
#endif
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 443f97ed0ba1..136bf6561a21 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -30,631 +30,582 @@ using namespace lldb_private;
/// Locates the address of the rendezvous structure. Returns the address on
/// success and LLDB_INVALID_ADDRESS on failure.
-static addr_t
-ResolveRendezvousAddress(Process *process)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- addr_t info_location;
- addr_t info_addr;
- Error error;
-
- if (!process)
- {
- if (log)
- log->Printf ("%s null process provided", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
- }
+static addr_t ResolveRendezvousAddress(Process *process) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ addr_t info_location;
+ addr_t info_addr;
+ Error error;
- // Try to get it from our process. This might be a remote process and might
- // grab it via some remote-specific mechanism.
- info_location = process->GetImageInfoAddress();
+ if (!process) {
if (log)
- log->Printf ("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
-
- // If the process fails to return an address, fall back to seeing if the local object file can help us find it.
- if (info_location == LLDB_INVALID_ADDRESS)
- {
- Target *target = &process->GetTarget();
- if (target)
- {
- ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(target);
-
- if (addr.IsValid())
- {
- info_location = addr.GetLoadAddress(target);
- if (log)
- log->Printf ("%s resolved via direct object file approach to 0x%" PRIx64, __FUNCTION__, info_location);
- }
- else
- {
- if (log)
- log->Printf ("%s FAILED - direct object file approach did not yield a valid address", __FUNCTION__);
- }
- }
- }
-
- if (info_location == LLDB_INVALID_ADDRESS)
- {
+ log->Printf("%s null process provided", __FUNCTION__);
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Try to get it from our process. This might be a remote process and might
+ // grab it via some remote-specific mechanism.
+ info_location = process->GetImageInfoAddress();
+ if (log)
+ log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
+
+ // If the process fails to return an address, fall back to seeing if the local
+ // object file can help us find it.
+ if (info_location == LLDB_INVALID_ADDRESS) {
+ Target *target = &process->GetTarget();
+ if (target) {
+ ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(target);
+
+ if (addr.IsValid()) {
+ info_location = addr.GetLoadAddress(target);
if (log)
- log->Printf ("%s FAILED - invalid info address", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
+ log->Printf(
+ "%s resolved via direct object file approach to 0x%" PRIx64,
+ __FUNCTION__, info_location);
+ } else {
+ if (log)
+ log->Printf("%s FAILED - direct object file approach did not yield a "
+ "valid address",
+ __FUNCTION__);
+ }
}
+ }
+ if (info_location == LLDB_INVALID_ADDRESS) {
if (log)
- log->Printf ("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, __FUNCTION__, process->GetAddressByteSize(), info_location);
+ log->Printf("%s FAILED - invalid info address", __FUNCTION__);
+ return LLDB_INVALID_ADDRESS;
+ }
- info_addr = process->ReadPointerFromMemory(info_location, error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("%s FAILED - could not read from the info location: %s", __FUNCTION__, error.AsCString ());
- return LLDB_INVALID_ADDRESS;
- }
+ if (log)
+ log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
+ __FUNCTION__, process->GetAddressByteSize(), info_location);
- if (info_addr == 0)
- {
- if (log)
- log->Printf ("%s FAILED - the rendezvous address contained at 0x%" PRIx64 " returned a null value", __FUNCTION__, info_location);
- return LLDB_INVALID_ADDRESS;
- }
+ info_addr = process->ReadPointerFromMemory(info_location, error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("%s FAILED - could not read from the info location: %s",
+ __FUNCTION__, error.AsCString());
+ return LLDB_INVALID_ADDRESS;
+ }
- return info_addr;
+ if (info_addr == 0) {
+ if (log)
+ log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64
+ " returned a null value",
+ __FUNCTION__, info_location);
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ return info_addr;
}
DYLDRendezvous::DYLDRendezvous(Process *process)
- : m_process(process),
- m_rendezvous_addr(LLDB_INVALID_ADDRESS),
- m_current(),
- m_previous(),
- m_loaded_modules(),
- m_soentries(),
- m_added_soentries(),
- m_removed_soentries()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- m_thread_info.valid = false;
-
- // Cache a copy of the executable path
- if (m_process)
- {
- Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
- if (exe_mod)
- {
- m_exe_file_spec = exe_mod->GetPlatformFileSpec();
- if (log)
- log->Printf ("DYLDRendezvous::%s exe module executable path set: '%s'",
- __FUNCTION__, m_exe_file_spec.GetCString());
- }
- else
- {
- if (log)
- log->Printf ("DYLDRendezvous::%s cannot cache exe module path: null executable module pointer", __FUNCTION__);
- }
+ : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(),
+ m_previous(), m_loaded_modules(), m_soentries(), m_added_soentries(),
+ m_removed_soentries() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ m_thread_info.valid = false;
+
+ // Cache a copy of the executable path
+ if (m_process) {
+ Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
+ if (exe_mod) {
+ m_exe_file_spec = exe_mod->GetPlatformFileSpec();
+ if (log)
+ log->Printf("DYLDRendezvous::%s exe module executable path set: '%s'",
+ __FUNCTION__, m_exe_file_spec.GetCString());
+ } else {
+ if (log)
+ log->Printf("DYLDRendezvous::%s cannot cache exe module path: null "
+ "executable module pointer",
+ __FUNCTION__);
}
+ }
}
-bool
-DYLDRendezvous::Resolve()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+bool DYLDRendezvous::Resolve() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ const size_t word_size = 4;
+ Rendezvous info;
+ size_t address_size;
+ size_t padding;
+ addr_t info_addr;
+ addr_t cursor;
+
+ address_size = m_process->GetAddressByteSize();
+ padding = address_size - word_size;
+ if (log)
+ log->Printf("DYLDRendezvous::%s address size: %" PRIu64
+ ", padding %" PRIu64,
+ __FUNCTION__, uint64_t(address_size), uint64_t(padding));
+
+ if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
+ cursor = info_addr = ResolveRendezvousAddress(m_process);
+ else
+ cursor = info_addr = m_rendezvous_addr;
+ if (log)
+ log->Printf("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor);
+
+ if (cursor == LLDB_INVALID_ADDRESS)
+ return false;
- const size_t word_size = 4;
- Rendezvous info;
- size_t address_size;
- size_t padding;
- addr_t info_addr;
- addr_t cursor;
+ if (!(cursor = ReadWord(cursor, &info.version, word_size)))
+ return false;
- address_size = m_process->GetAddressByteSize();
- padding = address_size - word_size;
- if (log)
- log->Printf ("DYLDRendezvous::%s address size: %" PRIu64 ", padding %" PRIu64, __FUNCTION__, uint64_t(address_size), uint64_t(padding));
+ if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
+ return false;
- if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
- cursor = info_addr = ResolveRendezvousAddress(m_process);
- else
- cursor = info_addr = m_rendezvous_addr;
- if (log)
- log->Printf ("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor);
+ if (!(cursor = ReadPointer(cursor, &info.brk)))
+ return false;
- if (cursor == LLDB_INVALID_ADDRESS)
- return false;
+ if (!(cursor = ReadWord(cursor, &info.state, word_size)))
+ return false;
- if (!(cursor = ReadWord(cursor, &info.version, word_size)))
- return false;
+ if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
+ return false;
- if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
- return false;
+ // The rendezvous was successfully read. Update our internal state.
+ m_rendezvous_addr = info_addr;
+ m_previous = m_current;
+ m_current = info;
- if (!(cursor = ReadPointer(cursor, &info.brk)))
- return false;
+ if (UpdateSOEntries(true))
+ return true;
- if (!(cursor = ReadWord(cursor, &info.state, word_size)))
- return false;
+ return UpdateSOEntries();
+}
- if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
- return false;
+bool DYLDRendezvous::IsValid() {
+ return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+}
- // The rendezvous was successfully read. Update our internal state.
- m_rendezvous_addr = info_addr;
- m_previous = m_current;
- m_current = info;
+bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
+ SOEntry entry;
+ LoadedModuleInfoList module_list;
- if (UpdateSOEntries (true))
- return true;
+ // If we can't get the SO info from the remote, return failure.
+ if (fromRemote && m_process->LoadModules(module_list) == 0)
+ return false;
- return UpdateSOEntries();
-}
+ if (!fromRemote && m_current.map_addr == 0)
+ return false;
-bool
-DYLDRendezvous::IsValid()
-{
- return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+ // When the previous and current states are consistent this is the first
+ // time we have been asked to update. Just take a snapshot of the currently
+ // loaded modules.
+ if (m_previous.state == eConsistent && m_current.state == eConsistent)
+ return fromRemote ? SaveSOEntriesFromRemote(module_list)
+ : TakeSnapshot(m_soentries);
+
+ // If we are about to add or remove a shared object clear out the current
+ // state and take a snapshot of the currently loaded images.
+ if (m_current.state == eAdd || m_current.state == eDelete) {
+ // Some versions of the android dynamic linker might send two
+ // notifications with state == eAdd back to back. Ignore them
+ // until we get an eConsistent notification.
+ if (!(m_previous.state == eConsistent ||
+ (m_previous.state == eAdd && m_current.state == eDelete)))
+ return false;
+
+ m_soentries.clear();
+ if (fromRemote)
+ return SaveSOEntriesFromRemote(module_list);
+
+ m_added_soentries.clear();
+ m_removed_soentries.clear();
+ return TakeSnapshot(m_soentries);
+ }
+ assert(m_current.state == eConsistent);
+
+ // Otherwise check the previous state to determine what to expect and update
+ // accordingly.
+ if (m_previous.state == eAdd)
+ return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries();
+ else if (m_previous.state == eDelete)
+ return fromRemote ? RemoveSOEntriesFromRemote(module_list)
+ : RemoveSOEntries();
+
+ return false;
}
-bool
-DYLDRendezvous::UpdateSOEntries(bool fromRemote)
-{
- SOEntry entry;
- LoadedModuleInfoList module_list;
+bool DYLDRendezvous::FillSOEntryFromModuleInfo(
+ LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry) {
+ addr_t link_map_addr;
+ addr_t base_addr;
+ addr_t dyn_addr;
+ std::string name;
- // If we can't get the SO info from the remote, return failure.
- if (fromRemote && m_process->LoadModules (module_list) == 0)
- return false;
+ if (!modInfo.get_link_map(link_map_addr) || !modInfo.get_base(base_addr) ||
+ !modInfo.get_dynamic(dyn_addr) || !modInfo.get_name(name))
+ return false;
- if (!fromRemote && m_current.map_addr == 0)
- return false;
+ entry.link_addr = link_map_addr;
+ entry.base_addr = base_addr;
+ entry.dyn_addr = dyn_addr;
- // When the previous and current states are consistent this is the first
- // time we have been asked to update. Just take a snapshot of the currently
- // loaded modules.
- if (m_previous.state == eConsistent && m_current.state == eConsistent)
- return fromRemote ? SaveSOEntriesFromRemote(module_list) : TakeSnapshot(m_soentries);
-
- // If we are about to add or remove a shared object clear out the current
- // state and take a snapshot of the currently loaded images.
- if (m_current.state == eAdd || m_current.state == eDelete)
- {
- // Some versions of the android dynamic linker might send two
- // notifications with state == eAdd back to back. Ignore them
- // until we get an eConsistent notification.
- if (!(m_previous.state == eConsistent || (m_previous.state == eAdd && m_current.state == eDelete)))
- return false;
-
- m_soentries.clear();
- if (fromRemote)
- return SaveSOEntriesFromRemote(module_list);
-
- m_added_soentries.clear();
- m_removed_soentries.clear();
- return TakeSnapshot(m_soentries);
- }
- assert(m_current.state == eConsistent);
+ entry.file_spec.SetFile(name, false);
- // Otherwise check the previous state to determine what to expect and update
- // accordingly.
- if (m_previous.state == eAdd)
- return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries();
- else if (m_previous.state == eDelete)
- return fromRemote ? RemoveSOEntriesFromRemote(module_list) : RemoveSOEntries();
+ UpdateBaseAddrIfNecessary(entry, name);
- return false;
+ // not needed if we're using ModuleInfos
+ entry.next = 0;
+ entry.prev = 0;
+ entry.path_addr = 0;
+
+ return true;
}
-bool
-DYLDRendezvous::FillSOEntryFromModuleInfo (LoadedModuleInfoList::LoadedModuleInfo const & modInfo,
- SOEntry &entry)
-{
- addr_t link_map_addr;
- addr_t base_addr;
- addr_t dyn_addr;
- std::string name;
-
- if (!modInfo.get_link_map (link_map_addr) ||
- !modInfo.get_base (base_addr) ||
- !modInfo.get_dynamic (dyn_addr) ||
- !modInfo.get_name (name))
- return false;
+bool DYLDRendezvous::SaveSOEntriesFromRemote(
+ LoadedModuleInfoList &module_list) {
+ for (auto const &modInfo : module_list.m_list) {
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(modInfo, entry))
+ return false;
- entry.link_addr = link_map_addr;
- entry.base_addr = base_addr;
- entry.dyn_addr = dyn_addr;
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry))
+ m_soentries.push_back(entry);
+ }
- entry.file_spec.SetFile(name, false);
+ m_loaded_modules = module_list;
+ return true;
+}
- UpdateBaseAddrIfNecessary(entry, name);
+bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
+ for (auto const &modInfo : module_list.m_list) {
+ bool found = false;
+ for (auto const &existing : m_loaded_modules.m_list) {
+ if (modInfo == existing) {
+ found = true;
+ break;
+ }
+ }
- // not needed if we're using ModuleInfos
- entry.next = 0;
- entry.prev = 0;
- entry.path_addr = 0;
+ if (found)
+ continue;
- return true;
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(modInfo, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry))
+ m_soentries.push_back(entry);
+ }
+
+ m_loaded_modules = module_list;
+ return true;
}
-bool
-DYLDRendezvous::SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & modInfo : module_list.m_list)
- {
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(modInfo, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- m_soentries.push_back(entry);
+bool DYLDRendezvous::RemoveSOEntriesFromRemote(
+ LoadedModuleInfoList &module_list) {
+ for (auto const &existing : m_loaded_modules.m_list) {
+ bool found = false;
+ for (auto const &modInfo : module_list.m_list) {
+ if (modInfo == existing) {
+ found = true;
+ break;
+ }
}
- m_loaded_modules = module_list;
- return true;
+ if (found)
+ continue;
-}
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(existing, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry)) {
+ auto pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end())
+ return false;
-bool
-DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & modInfo : module_list.m_list)
- {
- bool found = false;
- for (auto const & existing : m_loaded_modules.m_list)
- {
- if (modInfo == existing)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
-
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(modInfo, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- m_soentries.push_back(entry);
+ m_soentries.erase(pos);
}
+ }
- m_loaded_modules = module_list;
- return true;
+ m_loaded_modules = module_list;
+ return true;
}
-bool
-DYLDRendezvous::RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & existing : m_loaded_modules.m_list)
- {
- bool found = false;
- for (auto const & modInfo : module_list.m_list)
- {
- if (modInfo == existing)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
-
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(existing, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- {
- auto pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- return false;
-
- m_soentries.erase(pos);
- }
- }
+bool DYLDRendezvous::AddSOEntries() {
+ SOEntry entry;
+ iterator pos;
- m_loaded_modules = module_list;
- return true;
-}
+ assert(m_previous.state == eAdd);
-bool
-DYLDRendezvous::AddSOEntries()
-{
- SOEntry entry;
- iterator pos;
+ if (m_current.map_addr == 0)
+ return false;
- assert(m_previous.state == eAdd);
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- if (m_current.map_addr == 0)
- return false;
+ // Only add shared libraries and not the executable.
+ if (SOEntryIsMainExecutable(entry))
+ continue;
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (SOEntryIsMainExecutable(entry))
- continue;
-
- pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- {
- m_soentries.push_back(entry);
- m_added_soentries.push_back(entry);
- }
+ pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end()) {
+ m_soentries.push_back(entry);
+ m_added_soentries.push_back(entry);
}
+ }
- return true;
+ return true;
}
-bool
-DYLDRendezvous::RemoveSOEntries()
-{
- SOEntryList entry_list;
- iterator pos;
+bool DYLDRendezvous::RemoveSOEntries() {
+ SOEntryList entry_list;
+ iterator pos;
- assert(m_previous.state == eDelete);
+ assert(m_previous.state == eDelete);
- if (!TakeSnapshot(entry_list))
- return false;
+ if (!TakeSnapshot(entry_list))
+ return false;
- for (iterator I = begin(); I != end(); ++I)
- {
- pos = std::find(entry_list.begin(), entry_list.end(), *I);
- if (pos == entry_list.end())
- m_removed_soentries.push_back(*I);
- }
+ for (iterator I = begin(); I != end(); ++I) {
+ pos = std::find(entry_list.begin(), entry_list.end(), *I);
+ if (pos == entry_list.end())
+ m_removed_soentries.push_back(*I);
+ }
- m_soentries = entry_list;
- return true;
+ m_soentries = entry_list;
+ return true;
}
-bool
-DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry)
-{
- // On Linux the executable is indicated by an empty path in the entry. On
- // FreeBSD and on Android it is the full path to the executable.
-
- auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
- switch (triple.getOS())
- {
- case llvm::Triple::FreeBSD:
- return entry.file_spec == m_exe_file_spec;
- case llvm::Triple::Linux:
- if (triple.isAndroid())
- return entry.file_spec == m_exe_file_spec;
- return !entry.file_spec;
- default:
- return false;
- }
+bool DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry) {
+ // On Linux the executable is indicated by an empty path in the entry. On
+ // FreeBSD and on Android it is the full path to the executable.
+
+ auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple.getOS()) {
+ case llvm::Triple::FreeBSD:
+ return entry.file_spec == m_exe_file_spec;
+ case llvm::Triple::Linux:
+ if (triple.isAndroid())
+ return entry.file_spec == m_exe_file_spec;
+ return !entry.file_spec;
+ default:
+ return false;
+ }
}
-bool
-DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
-{
- SOEntry entry;
+bool DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) {
+ SOEntry entry;
- if (m_current.map_addr == 0)
- return false;
+ if (m_current.map_addr == 0)
+ return false;
- // Clear previous entries since we are about to obtain an up to date list.
- entry_list.clear();
+ // Clear previous entries since we are about to obtain an up to date list.
+ entry_list.clear();
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- // Only add shared libraries and not the executable.
- if (SOEntryIsMainExecutable(entry))
- continue;
+ // Only add shared libraries and not the executable.
+ if (SOEntryIsMainExecutable(entry))
+ continue;
- entry_list.push_back(entry);
- }
+ entry_list.push_back(entry);
+ }
- return true;
+ return true;
}
-addr_t
-DYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size)
-{
- Error error;
+addr_t DYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size) {
+ Error error;
- *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
- if (error.Fail())
- return 0;
+ *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
+ if (error.Fail())
+ return 0;
- return addr + size;
+ return addr + size;
}
-addr_t
-DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst)
-{
- Error error;
-
- *dst = m_process->ReadPointerFromMemory(addr, error);
- if (error.Fail())
- return 0;
+addr_t DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) {
+ Error error;
- return addr + m_process->GetAddressByteSize();
+ *dst = m_process->ReadPointerFromMemory(addr, error);
+ if (error.Fail())
+ return 0;
+
+ return addr + m_process->GetAddressByteSize();
}
-std::string
-DYLDRendezvous::ReadStringFromMemory(addr_t addr)
-{
- std::string str;
- Error error;
+std::string DYLDRendezvous::ReadStringFromMemory(addr_t addr) {
+ std::string str;
+ Error error;
- if (addr == LLDB_INVALID_ADDRESS)
- return std::string();
+ if (addr == LLDB_INVALID_ADDRESS)
+ return std::string();
- m_process->ReadCStringFromMemory(addr, str, error);
+ m_process->ReadCStringFromMemory(addr, str, error);
- return str;
+ return str;
}
-// Returns true if the load bias reported by the linker is incorrect for the given entry. This
-// function is used to handle cases where we want to work around a bug in the system linker.
-static bool
-isLoadBiasIncorrect(Target& target, const std::string& file_path)
-{
- // On Android L (API 21, 22) the load address of the "/system/bin/linker" isn't filled in
- // correctly.
- uint32_t os_major = 0, os_minor = 0, os_update = 0;
- if (target.GetArchitecture().GetTriple().isAndroid() &&
- target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
- (os_major == 21 || os_major == 22) &&
- (file_path == "/system/bin/linker" || file_path == "/system/bin/linker64"))
- {
- return true;
- }
+// Returns true if the load bias reported by the linker is incorrect for the
+// given entry. This
+// function is used to handle cases where we want to work around a bug in the
+// system linker.
+static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) {
+ // On Android L (API 21, 22) the load address of the "/system/bin/linker"
+ // isn't filled in
+ // correctly.
+ uint32_t os_major = 0, os_minor = 0, os_update = 0;
+ if (target.GetArchitecture().GetTriple().isAndroid() &&
+ target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
+ (os_major == 21 || os_major == 22) &&
+ (file_path == "/system/bin/linker" ||
+ file_path == "/system/bin/linker64")) {
+ return true;
+ }
- return false;
+ return false;
}
-void
-DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path)
-{
- // If the load bias reported by the linker is incorrect then fetch the load address of the file
- // from the proc file system.
- if (isLoadBiasIncorrect(m_process->GetTarget(), file_path))
- {
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
- bool is_loaded = false;
- Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
- if (error.Success() && is_loaded)
- entry.base_addr = load_addr;
- }
+void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry,
+ std::string const &file_path) {
+ // If the load bias reported by the linker is incorrect then fetch the load
+ // address of the file
+ // from the proc file system.
+ if (isLoadBiasIncorrect(m_process->GetTarget(), file_path)) {
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ bool is_loaded = false;
+ Error error =
+ m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
+ if (error.Success() && is_loaded)
+ entry.base_addr = load_addr;
+ }
}
-bool
-DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
-{
- entry.clear();
+bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
+ entry.clear();
- entry.link_addr = addr;
-
- if (!(addr = ReadPointer(addr, &entry.base_addr)))
- return false;
+ entry.link_addr = addr;
- // mips adds an extra load offset field to the link map struct on
- // FreeBSD and NetBSD (need to validate other OSes).
- // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
- const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
- if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD
- || arch.GetTriple().getOS() == llvm::Triple::NetBSD) &&
- (arch.GetMachine() == llvm::Triple::mips || arch.GetMachine() == llvm::Triple::mipsel
- || arch.GetMachine() == llvm::Triple::mips64 || arch.GetMachine() == llvm::Triple::mips64el))
- {
- addr_t mips_l_offs;
- if (!(addr = ReadPointer(addr, &mips_l_offs)))
- return false;
- if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
- return false;
- }
-
- if (!(addr = ReadPointer(addr, &entry.path_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.next)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.prev)))
- return false;
+ if (!(addr = ReadPointer(addr, &entry.base_addr)))
+ return false;
- std::string file_path = ReadStringFromMemory(entry.path_addr);
- entry.file_spec.SetFile(file_path, false);
+ // mips adds an extra load offset field to the link map struct on
+ // FreeBSD and NetBSD (need to validate other OSes).
+ // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
+ const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
+ if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD ||
+ arch.GetTriple().getOS() == llvm::Triple::NetBSD) &&
+ (arch.GetMachine() == llvm::Triple::mips ||
+ arch.GetMachine() == llvm::Triple::mipsel ||
+ arch.GetMachine() == llvm::Triple::mips64 ||
+ arch.GetMachine() == llvm::Triple::mips64el)) {
+ addr_t mips_l_offs;
+ if (!(addr = ReadPointer(addr, &mips_l_offs)))
+ return false;
+ if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
+ return false;
+ }
+
+ if (!(addr = ReadPointer(addr, &entry.path_addr)))
+ return false;
- UpdateBaseAddrIfNecessary(entry, file_path);
+ if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
+ return false;
- return true;
-}
+ if (!(addr = ReadPointer(addr, &entry.next)))
+ return false;
+ if (!(addr = ReadPointer(addr, &entry.prev)))
+ return false;
-bool
-DYLDRendezvous::FindMetadata(const char *name, PThreadField field, uint32_t& value)
-{
- Target& target = m_process->GetTarget();
+ std::string file_path = ReadStringFromMemory(entry.path_addr);
+ entry.file_spec.SetFile(file_path, false);
- SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType (ConstString(name), eSymbolTypeAny, list))
- return false;
+ UpdateBaseAddrIfNecessary(entry, file_path);
- Address address = list[0].symbol->GetAddress();
- addr_t addr = address.GetLoadAddress (&target);
- if (addr == LLDB_INVALID_ADDRESS)
- return false;
+ return true;
+}
- Error error;
- value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(addr + field*sizeof(uint32_t), sizeof(uint32_t), 0, error);
- if (error.Fail())
- return false;
+bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field,
+ uint32_t &value) {
+ Target &target = m_process->GetTarget();
- if (field == eSize)
- value /= 8; // convert bits to bytes
+ SymbolContextList list;
+ if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list))
+ return false;
- return true;
+ Address address = list[0].symbol->GetAddress();
+ addr_t addr = address.GetLoadAddress(&target);
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Error error;
+ value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(
+ addr + field * sizeof(uint32_t), sizeof(uint32_t), 0, error);
+ if (error.Fail())
+ return false;
+
+ if (field == eSize)
+ value /= 8; // convert bits to bytes
+
+ return true;
}
-const DYLDRendezvous::ThreadInfo&
-DYLDRendezvous::GetThreadInfo()
-{
- if (!m_thread_info.valid)
- {
- bool ok = true;
+const DYLDRendezvous::ThreadInfo &DYLDRendezvous::GetThreadInfo() {
+ if (!m_thread_info.valid) {
+ bool ok = true;
- ok &= FindMetadata ("_thread_db_pthread_dtvp", eOffset, m_thread_info.dtv_offset);
- ok &= FindMetadata ("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
- ok &= FindMetadata ("_thread_db_link_map_l_tls_modid", eOffset, m_thread_info.modid_offset);
- ok &= FindMetadata ("_thread_db_dtv_t_pointer_val", eOffset, m_thread_info.tls_offset);
+ ok &= FindMetadata("_thread_db_pthread_dtvp", eOffset,
+ m_thread_info.dtv_offset);
+ ok &=
+ FindMetadata("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
+ ok &= FindMetadata("_thread_db_link_map_l_tls_modid", eOffset,
+ m_thread_info.modid_offset);
+ ok &= FindMetadata("_thread_db_dtv_t_pointer_val", eOffset,
+ m_thread_info.tls_offset);
- if (ok)
- m_thread_info.valid = true;
- }
+ if (ok)
+ m_thread_info.valid = true;
+ }
- return m_thread_info;
+ return m_thread_info;
}
-void
-DYLDRendezvous::DumpToLog(Log *log) const
-{
- int state = GetState();
-
- if (!log)
- return;
-
- log->PutCString("DYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent) ? "consistent" :
- (state == eAdd) ? "add" :
- (state == eDelete) ? "delete" : "unknown");
-
- iterator I = begin();
- iterator E = end();
-
- if (I != E)
- log->PutCString("DYLDRendezvous SOEntries:");
-
- for (int i = 1; I != E; ++I, ++i)
- {
- log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
- }
+void DYLDRendezvous::DumpToLog(Log *log) const {
+ int state = GetState();
+
+ if (!log)
+ return;
+
+ log->PutCString("DYLDRendezvous:");
+ log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
+ log->Printf(" Version: %" PRIu64, GetVersion());
+ log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
+ log->Printf(" Break : %" PRIx64, GetBreakAddress());
+ log->Printf(" LDBase : %" PRIx64, GetLDBase());
+ log->Printf(" State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
+ : "unknown");
+
+ iterator I = begin();
+ iterator E = end();
+
+ if (I != E)
+ log->PutCString("DYLDRendezvous SOEntries:");
+
+ for (int i = 1; I != E; ++I, ++i) {
+ log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString());
+ log->Printf(" Base : %" PRIx64, I->base_addr);
+ log->Printf(" Path : %" PRIx64, I->path_addr);
+ log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
+ log->Printf(" Next : %" PRIx64, I->next);
+ log->Printf(" Prev : %" PRIx64, I->prev);
+ }
}
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 8498116c808f..55b8bd7fb49e 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -16,9 +16,9 @@
#include <string>
// Other libraries and framework includes
+#include "lldb/Host/FileSpec.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/LoadedModuleInfoList.h"
@@ -37,251 +37,220 @@ class Process;
/// currently loaded modules.
class DYLDRendezvous {
- // This structure is used to hold the contents of the debug rendezvous
- // information (struct r_debug) as found in the inferiors memory. Note that
- // the layout of this struct is not binary compatible, it is simply large
- // enough to hold the information on both 32 and 64 bit platforms.
- struct Rendezvous {
- uint64_t version;
- lldb::addr_t map_addr;
- lldb::addr_t brk;
- uint64_t state;
- lldb::addr_t ldbase;
-
- Rendezvous()
- : version(0), map_addr(0), brk(0), state(0), ldbase(0) { }
- };
+ // This structure is used to hold the contents of the debug rendezvous
+ // information (struct r_debug) as found in the inferiors memory. Note that
+ // the layout of this struct is not binary compatible, it is simply large
+ // enough to hold the information on both 32 and 64 bit platforms.
+ struct Rendezvous {
+ uint64_t version;
+ lldb::addr_t map_addr;
+ lldb::addr_t brk;
+ uint64_t state;
+ lldb::addr_t ldbase;
+
+ Rendezvous() : version(0), map_addr(0), brk(0), state(0), ldbase(0) {}
+ };
public:
- // Various metadata supplied by the inferior's threading library to describe
- // the per-thread state.
- struct ThreadInfo {
- bool valid; // whether we read valid metadata
- uint32_t dtv_offset; // offset of DTV pointer within pthread
- uint32_t dtv_slot_size; // size of one DTV slot
- uint32_t modid_offset; // offset of module ID within link_map
- uint32_t tls_offset; // offset of TLS pointer within DTV slot
- };
-
- DYLDRendezvous(lldb_private::Process *process);
-
- /// Update the internal snapshot of runtime linker rendezvous and recompute
- /// the currently loaded modules.
- ///
- /// This method should be called once one start up, then once each time the
- /// runtime linker enters the function given by GetBreakAddress().
- ///
- /// @returns true on success and false on failure.
- ///
- /// @see GetBreakAddress().
- bool
- Resolve();
-
- /// @returns true if this rendezvous has been located in the inferiors
- /// address space and false otherwise.
- bool
- IsValid();
-
- /// @returns the address of the rendezvous structure in the inferiors
- /// address space.
- lldb::addr_t
- GetRendezvousAddress() const { return m_rendezvous_addr; }
-
- /// @returns the version of the rendezvous protocol being used.
- uint64_t
- GetVersion() const { return m_current.version; }
-
- /// @returns address in the inferiors address space containing the linked
- /// list of shared object descriptors.
- lldb::addr_t
- GetLinkMapAddress() const { return m_current.map_addr; }
-
- /// A breakpoint should be set at this address and Resolve called on each
- /// hit.
- ///
- /// @returns the address of a function called by the runtime linker each
- /// time a module is loaded/unloaded, or about to be loaded/unloaded.
- ///
- /// @see Resolve()
- lldb::addr_t
- GetBreakAddress() const { return m_current.brk; }
-
- /// Returns the current state of the rendezvous structure.
- uint64_t
- GetState() const { return m_current.state; }
-
- /// @returns the base address of the runtime linker in the inferiors address
- /// space.
- lldb::addr_t
- GetLDBase() const { return m_current.ldbase; }
-
- /// @returns the thread layout metadata from the inferiors thread library.
- const ThreadInfo&
- GetThreadInfo();
-
- /// @returns true if modules have been loaded into the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidLoad() const { return !m_added_soentries.empty(); }
-
- /// @returns true if modules have been unloaded from the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidUnload() const { return !m_removed_soentries.empty(); }
-
- void
- DumpToLog(lldb_private::Log *log) const;
-
- /// @brief Constants describing the state of the rendezvous.
- ///
- /// @see GetState().
- enum RendezvousState {
- eConsistent,
- eAdd,
- eDelete
- };
-
- /// @brief Structure representing the shared objects currently loaded into
- /// the inferior process.
- ///
- /// This object is a rough analogue to the struct link_map object which
- /// actually lives in the inferiors memory.
- struct SOEntry {
- lldb::addr_t link_addr; ///< Address of this link_map.
- lldb::addr_t base_addr; ///< Base address of the loaded object.
- lldb::addr_t path_addr; ///< String naming the shared object.
- lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
- lldb::addr_t next; ///< Address of next so_entry.
- lldb::addr_t prev; ///< Address of previous so_entry.
- lldb_private::FileSpec file_spec; ///< File spec of shared object.
-
- SOEntry() { clear(); }
-
- bool operator ==(const SOEntry &entry) {
- return file_spec == entry.file_spec;
- }
-
- void clear() {
- link_addr = 0;
- base_addr = 0;
- path_addr = 0;
- dyn_addr = 0;
- next = 0;
- prev = 0;
- file_spec.Clear();
- }
- };
+ // Various metadata supplied by the inferior's threading library to describe
+ // the per-thread state.
+ struct ThreadInfo {
+ bool valid; // whether we read valid metadata
+ uint32_t dtv_offset; // offset of DTV pointer within pthread
+ uint32_t dtv_slot_size; // size of one DTV slot
+ uint32_t modid_offset; // offset of module ID within link_map
+ uint32_t tls_offset; // offset of TLS pointer within DTV slot
+ };
+
+ DYLDRendezvous(lldb_private::Process *process);
+
+ /// Update the internal snapshot of runtime linker rendezvous and recompute
+ /// the currently loaded modules.
+ ///
+ /// This method should be called once one start up, then once each time the
+ /// runtime linker enters the function given by GetBreakAddress().
+ ///
+ /// @returns true on success and false on failure.
+ ///
+ /// @see GetBreakAddress().
+ bool Resolve();
+
+ /// @returns true if this rendezvous has been located in the inferiors
+ /// address space and false otherwise.
+ bool IsValid();
+
+ /// @returns the address of the rendezvous structure in the inferiors
+ /// address space.
+ lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
+
+ /// @returns the version of the rendezvous protocol being used.
+ uint64_t GetVersion() const { return m_current.version; }
+
+ /// @returns address in the inferiors address space containing the linked
+ /// list of shared object descriptors.
+ lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
+
+ /// A breakpoint should be set at this address and Resolve called on each
+ /// hit.
+ ///
+ /// @returns the address of a function called by the runtime linker each
+ /// time a module is loaded/unloaded, or about to be loaded/unloaded.
+ ///
+ /// @see Resolve()
+ lldb::addr_t GetBreakAddress() const { return m_current.brk; }
+
+ /// Returns the current state of the rendezvous structure.
+ uint64_t GetState() const { return m_current.state; }
+
+ /// @returns the base address of the runtime linker in the inferiors address
+ /// space.
+ lldb::addr_t GetLDBase() const { return m_current.ldbase; }
+
+ /// @returns the thread layout metadata from the inferiors thread library.
+ const ThreadInfo &GetThreadInfo();
+
+ /// @returns true if modules have been loaded into the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
+
+ /// @returns true if modules have been unloaded from the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
+
+ void DumpToLog(lldb_private::Log *log) const;
+
+ /// @brief Constants describing the state of the rendezvous.
+ ///
+ /// @see GetState().
+ enum RendezvousState { eConsistent, eAdd, eDelete };
+
+ /// @brief Structure representing the shared objects currently loaded into
+ /// the inferior process.
+ ///
+ /// This object is a rough analogue to the struct link_map object which
+ /// actually lives in the inferiors memory.
+ struct SOEntry {
+ lldb::addr_t link_addr; ///< Address of this link_map.
+ lldb::addr_t base_addr; ///< Base address of the loaded object.
+ lldb::addr_t path_addr; ///< String naming the shared object.
+ lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
+ lldb::addr_t next; ///< Address of next so_entry.
+ lldb::addr_t prev; ///< Address of previous so_entry.
+ lldb_private::FileSpec file_spec; ///< File spec of shared object.
+
+ SOEntry() { clear(); }
+
+ bool operator==(const SOEntry &entry) {
+ return file_spec == entry.file_spec;
+ }
+
+ void clear() {
+ link_addr = 0;
+ base_addr = 0;
+ path_addr = 0;
+ dyn_addr = 0;
+ next = 0;
+ prev = 0;
+ file_spec.Clear();
+ }
+ };
protected:
- typedef std::list<SOEntry> SOEntryList;
+ typedef std::list<SOEntry> SOEntryList;
public:
- typedef SOEntryList::const_iterator iterator;
-
- /// Iterators over all currently loaded modules.
- iterator begin() const { return m_soentries.begin(); }
- iterator end() const { return m_soentries.end(); }
-
- /// Iterators over all modules loaded into the inferior since the last call
- /// to Resolve().
- iterator loaded_begin() const { return m_added_soentries.begin(); }
- iterator loaded_end() const { return m_added_soentries.end(); }
-
- /// Iterators over all modules unloaded from the inferior since the last
- /// call to Resolve().
- iterator unloaded_begin() const { return m_removed_soentries.begin(); }
- iterator unloaded_end() const { return m_removed_soentries.end(); }
-
+ typedef SOEntryList::const_iterator iterator;
+
+ /// Iterators over all currently loaded modules.
+ iterator begin() const { return m_soentries.begin(); }
+ iterator end() const { return m_soentries.end(); }
+
+ /// Iterators over all modules loaded into the inferior since the last call
+ /// to Resolve().
+ iterator loaded_begin() const { return m_added_soentries.begin(); }
+ iterator loaded_end() const { return m_added_soentries.end(); }
+
+ /// Iterators over all modules unloaded from the inferior since the last
+ /// call to Resolve().
+ iterator unloaded_begin() const { return m_removed_soentries.begin(); }
+ iterator unloaded_end() const { return m_removed_soentries.end(); }
+
protected:
- lldb_private::Process *m_process;
+ lldb_private::Process *m_process;
- // Cached copy of executable file spec
- lldb_private::FileSpec m_exe_file_spec;
+ // Cached copy of executable file spec
+ lldb_private::FileSpec m_exe_file_spec;
- /// Location of the r_debug structure in the inferiors address space.
- lldb::addr_t m_rendezvous_addr;
+ /// Location of the r_debug structure in the inferiors address space.
+ lldb::addr_t m_rendezvous_addr;
- /// Current and previous snapshots of the rendezvous structure.
- Rendezvous m_current;
- Rendezvous m_previous;
+ /// Current and previous snapshots of the rendezvous structure.
+ Rendezvous m_current;
+ Rendezvous m_previous;
- /// List of currently loaded SO modules
- LoadedModuleInfoList m_loaded_modules;
+ /// List of currently loaded SO modules
+ LoadedModuleInfoList m_loaded_modules;
- /// List of SOEntry objects corresponding to the current link map state.
- SOEntryList m_soentries;
+ /// List of SOEntry objects corresponding to the current link map state.
+ SOEntryList m_soentries;
- /// List of SOEntry's added to the link map since the last call to Resolve().
- SOEntryList m_added_soentries;
+ /// List of SOEntry's added to the link map since the last call to Resolve().
+ SOEntryList m_added_soentries;
- /// List of SOEntry's removed from the link map since the last call to
- /// Resolve().
- SOEntryList m_removed_soentries;
+ /// List of SOEntry's removed from the link map since the last call to
+ /// Resolve().
+ SOEntryList m_removed_soentries;
- /// Threading metadata read from the inferior.
- ThreadInfo m_thread_info;
+ /// Threading metadata read from the inferior.
+ ThreadInfo m_thread_info;
- /// Reads an unsigned integer of @p size bytes from the inferior's address
- /// space starting at @p addr.
- ///
- /// @returns addr + size if the read was successful and false otherwise.
- lldb::addr_t
- ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
+ /// Reads an unsigned integer of @p size bytes from the inferior's address
+ /// space starting at @p addr.
+ ///
+ /// @returns addr + size if the read was successful and false otherwise.
+ lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
- /// Reads an address from the inferior's address space starting at @p addr.
- ///
- /// @returns addr + target address size if the read was successful and
- /// 0 otherwise.
- lldb::addr_t
- ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
+ /// Reads an address from the inferior's address space starting at @p addr.
+ ///
+ /// @returns addr + target address size if the read was successful and
+ /// 0 otherwise.
+ lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
- /// Reads a null-terminated C string from the memory location starting at @p
- /// addr.
- std::string
- ReadStringFromMemory(lldb::addr_t addr);
+ /// Reads a null-terminated C string from the memory location starting at @p
+ /// addr.
+ std::string ReadStringFromMemory(lldb::addr_t addr);
- /// Reads an SOEntry starting at @p addr.
- bool
- ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
+ /// Reads an SOEntry starting at @p addr.
+ bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
- /// Updates the current set of SOEntries, the set of added entries, and the
- /// set of removed entries.
- bool
- UpdateSOEntries(bool fromRemote = false);
+ /// Updates the current set of SOEntries, the set of added entries, and the
+ /// set of removed entries.
+ bool UpdateSOEntries(bool fromRemote = false);
- bool
- FillSOEntryFromModuleInfo (LoadedModuleInfoList::LoadedModuleInfo const & modInfo,
- SOEntry &entry);
+ bool FillSOEntryFromModuleInfo(
+ LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry);
- bool
- SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
- bool
- AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
- bool
- RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
- bool
- AddSOEntries();
+ bool AddSOEntries();
- bool
- RemoveSOEntries();
+ bool RemoveSOEntries();
- void
- UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
+ void UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
- bool
- SOEntryIsMainExecutable(const SOEntry &entry);
+ bool SOEntryIsMainExecutable(const SOEntry &entry);
- /// Reads the current list of shared objects according to the link map
- /// supplied by the runtime linker.
- bool
- TakeSnapshot(SOEntryList &entry_list);
+ /// Reads the current list of shared objects according to the link map
+ /// supplied by the runtime linker.
+ bool TakeSnapshot(SOEntryList &entry_list);
- enum PThreadField { eSize, eNElem, eOffset };
+ enum PThreadField { eSize, eNElem, eOffset };
- bool FindMetadata(const char *name, PThreadField field, uint32_t& value);
+ bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
};
#endif
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 6515c02f37e0..fc225eebe605 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -1,4 +1,4 @@
-//===-- DynamicLoaderPOSIX.h ------------------------------------*- C++ -*-===//
+//===-- DynamicLoaderPOSIXDYLD.cpp ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,280 +7,267 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
+// Main header include
+#include "DynamicLoaderPOSIXDYLD.h"
+
+// Project includes
+#include "AuxVector.h"
+
// Other libraries and framework includes
-#include "lldb/Core/PluginManager.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Target/Platform.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "AuxVector.h"
-#include "DynamicLoaderPOSIXDYLD.h"
+// C++ Includes
+// C Includes
using namespace lldb;
using namespace lldb_private;
-void
-DynamicLoaderPOSIXDYLD::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void DynamicLoaderPOSIXDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-DynamicLoaderPOSIXDYLD::Terminate()
-{
-}
+void DynamicLoaderPOSIXDYLD::Terminate() {}
-lldb_private::ConstString
-DynamicLoaderPOSIXDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
-lldb_private::ConstString
-DynamicLoaderPOSIXDYLD::GetPluginNameStatic()
-{
- static ConstString g_name("linux-dyld");
- return g_name;
+lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() {
+ static ConstString g_name("linux-dyld");
+ return g_name;
}
-const char *
-DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library "
- "loads/unloads in POSIX processes.";
+const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library "
+ "loads/unloads in POSIX processes.";
}
-uint32_t
-DynamicLoaderPOSIXDYLD::GetPluginVersion()
-{
- return 1;
-}
-
-DynamicLoader *
-DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, bool force)
-{
- bool create = force;
- if (!create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- if (triple_ref.getOS() == llvm::Triple::Linux ||
- triple_ref.getOS() == llvm::Triple::FreeBSD)
- create = true;
- }
-
- if (create)
- return new DynamicLoaderPOSIXDYLD (process);
- return NULL;
+uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; }
+
+DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ if (triple_ref.getOS() == llvm::Triple::Linux ||
+ triple_ref.getOS() == llvm::Triple::FreeBSD)
+ create = true;
+ }
+
+ if (create)
+ return new DynamicLoaderPOSIXDYLD(process);
+ return NULL;
}
DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
- : DynamicLoader(process),
- m_rendezvous(process),
- m_load_offset(LLDB_INVALID_ADDRESS),
- m_entry_point(LLDB_INVALID_ADDRESS),
- m_auxv(),
- m_dyld_bid(LLDB_INVALID_BREAK_ID),
- m_vdso_base(LLDB_INVALID_ADDRESS)
-{
+ : DynamicLoader(process), m_rendezvous(process),
+ m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
+ m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
+ m_vdso_base(LLDB_INVALID_ADDRESS) {}
+
+DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
+ if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
+ m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid);
+ m_dyld_bid = LLDB_INVALID_BREAK_ID;
+ }
}
-DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD()
-{
- if (m_dyld_bid != LLDB_INVALID_BREAK_ID)
- {
- m_process->GetTarget().RemoveBreakpointByID (m_dyld_bid);
- m_dyld_bid = LLDB_INVALID_BREAK_ID;
+void DynamicLoaderPOSIXDYLD::DidAttach() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ m_auxv.reset(new AuxVector(m_process));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ // ask the process if it can load any of its own modules
+ m_process->LoadModules();
+
+ ModuleSP executable_sp = GetTargetExecutable();
+ ResolveExecutableModule(executable_sp);
+
+ // find the main process load offset
+ addr_t load_offset = ComputeLoadOffset();
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " executable '%s', load_offset 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
+ : "<null executable>",
+ load_offset);
+
+ EvalVdsoStatus();
+
+ // if we dont have a load address we cant re-base
+ bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
+
+ // if we have a valid executable
+ if (executable_sp.get()) {
+ lldb_private::ObjectFile *obj = executable_sp->GetObjectFile();
+ if (obj) {
+ // don't rebase if the module already has a load address
+ Target &target = m_process->GetTarget();
+ Address addr = obj->GetImageInfoAddress(&target);
+ if (addr.GetLoadAddress(&target) != LLDB_INVALID_ADDRESS)
+ rebase_exec = false;
}
-}
+ } else {
+ // no executable, nothing to re-base
+ rebase_exec = false;
+ }
-void
-DynamicLoaderPOSIXDYLD::DidAttach()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
-
- m_auxv.reset(new AuxVector(m_process));
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
-
- // ask the process if it can load any of its own modules
- m_process->LoadModules ();
-
- ModuleSP executable_sp = GetTargetExecutable ();
- ResolveExecutableModule (executable_sp);
+ // if the target executable should be re-based
+ if (rebase_exec) {
+ ModuleList module_list;
- // find the main process load offset
- addr_t load_offset = ComputeLoadOffset ();
+ module_list.Append(executable_sp);
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " executable '%s', load_offset 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, executable_sp ? executable_sp->GetFileSpec().GetPath().c_str () : "<null executable>", load_offset);
-
- EvalVdsoStatus();
-
- // if we dont have a load address we cant re-base
- bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
-
- // if we have a valid executable
- if (executable_sp.get())
- {
- lldb_private::ObjectFile * obj = executable_sp->GetObjectFile();
- if (obj)
- {
- // don't rebase if the module already has a load address
- Target & target = m_process->GetTarget ();
- Address addr = obj->GetImageInfoAddress (&target);
- if (addr.GetLoadAddress (&target) != LLDB_INVALID_ADDRESS)
- rebase_exec = false;
- }
- }
- else
- {
- // no executable, nothing to re-base
- rebase_exec = false;
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " added executable '%s' to module load list",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp->GetFileSpec().GetPath().c_str());
+
+ UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
+ true);
+
+ // When attaching to a target, there are two possible states:
+ // (1) We already crossed the entry point and therefore the rendezvous
+ // structure is ready to be used and we can load the list of modules
+ // and place the rendezvous breakpoint.
+ // (2) We didn't cross the entry point yet, so these structures are not
+ // ready; we should behave as if we just launched the target and
+ // call ProbeEntry(). This will place a breakpoint on the entry
+ // point which itself will be hit after the rendezvous structure is
+ // set up and will perform actions described in (1).
+ if (m_rendezvous.Resolve()) {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
+ " rendezvous could resolve: attach assuming dynamic loader "
+ "info is available now",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LoadAllCurrentModules();
+ SetRendezvousBreakpoint();
+ } else {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
+ " rendezvous could not yet resolve: adding breakpoint to "
+ "catch future rendezvous setup",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ ProbeEntry();
}
- // if the target executable should be re-based
- if (rebase_exec)
- {
- ModuleList module_list;
-
- module_list.Append(executable_sp);
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " added executable '%s' to module load list",
- __FUNCTION__,
- m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID,
- executable_sp->GetFileSpec().GetPath().c_str ());
-
- UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset, true);
-
- // When attaching to a target, there are two possible states:
- // (1) We already crossed the entry point and therefore the rendezvous
- // structure is ready to be used and we can load the list of modules
- // and place the rendezvous breakpoint.
- // (2) We didn't cross the entry point yet, so these structures are not
- // ready; we should behave as if we just launched the target and
- // call ProbeEntry(). This will place a breakpoint on the entry
- // point which itself will be hit after the rendezvous structure is
- // set up and will perform actions described in (1).
- if (m_rendezvous.Resolve())
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64 " rendezvous could resolve: attach assuming dynamic loader info is available now", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- LoadAllCurrentModules();
- SetRendezvousBreakpoint();
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64 " rendezvous could not yet resolve: adding breakpoint to catch future rendezvous setup", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- ProbeEntry();
- }
-
- m_process->GetTarget().ModulesDidLoad(module_list);
- if (log)
- {
- log->Printf ("DynamicLoaderPOSIXDYLD::%s told the target about the modules that loaded:", __FUNCTION__);
- for (auto module_sp : module_list.Modules ())
- {
- log->Printf ("-- [module] %s (pid %" PRIu64 ")",
- module_sp ? module_sp->GetFileSpec().GetPath().c_str () : "<null>",
- m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- }
- }
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ if (log) {
+ log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the "
+ "modules that loaded:",
+ __FUNCTION__);
+ for (auto module_sp : module_list.Modules()) {
+ log->Printf("-- [module] %s (pid %" PRIu64 ")",
+ module_sp ? module_sp->GetFileSpec().GetPath().c_str()
+ : "<null>",
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ }
}
+ }
}
-void
-DynamicLoaderPOSIXDYLD::DidLaunch()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
+void DynamicLoaderPOSIXDYLD::DidLaunch() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
- ModuleSP executable;
- addr_t load_offset;
+ ModuleSP executable;
+ addr_t load_offset;
- m_auxv.reset(new AuxVector(m_process));
+ m_auxv.reset(new AuxVector(m_process));
- executable = GetTargetExecutable();
- load_offset = ComputeLoadOffset();
- EvalVdsoStatus();
+ executable = GetTargetExecutable();
+ load_offset = ComputeLoadOffset();
+ EvalVdsoStatus();
- if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
- {
- ModuleList module_list;
- module_list.Append(executable);
- UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
+ if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
+ ModuleList module_list;
+ module_list.Append(executable);
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", __FUNCTION__);
- ProbeEntry();
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
+ __FUNCTION__);
+ ProbeEntry();
- m_process->GetTarget().ModulesDidLoad(module_list);
- }
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ }
}
-Error
-DynamicLoaderPOSIXDYLD::CanLoadImage()
-{
- return Error();
-}
+Error DynamicLoaderPOSIXDYLD::CanLoadImage() { return Error(); }
-void
-DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module,
- addr_t link_map_addr,
- addr_t base_addr,
- bool base_addr_is_offset)
-{
- m_loaded_modules[module] = link_map_addr;
- UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
+void DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module,
+ addr_t link_map_addr,
+ addr_t base_addr,
+ bool base_addr_is_offset) {
+ m_loaded_modules[module] = link_map_addr;
+ UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
}
-void
-DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module)
-{
- m_loaded_modules.erase(module);
+void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
+ m_loaded_modules.erase(module);
- UnloadSectionsCommon(module);
+ UnloadSectionsCommon(module);
}
-void
-DynamicLoaderPOSIXDYLD::ProbeEntry()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- const addr_t entry = GetEntryPoint();
- if (entry == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " GetEntryPoint() returned no address, not setting entry breakpoint", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- return;
- }
+void DynamicLoaderPOSIXDYLD::ProbeEntry() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ const addr_t entry = GetEntryPoint();
+ if (entry == LLDB_INVALID_ADDRESS) {
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " GetEntryPoint() returned address 0x%" PRIx64 ", setting entry breakpoint", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, entry);
-
- if (m_process)
- {
- Breakpoint *const entry_break = m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
- entry_break->SetCallback(EntryBreakpointHit, this, true);
- entry_break->SetBreakpointKind("shared-library-event");
-
- // Shoudn't hit this more than once.
- entry_break->SetOneShot (true);
- }
+ log->Printf(
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned no address, not setting entry breakpoint",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ return;
+ }
+
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned address 0x%" PRIx64
+ ", setting entry breakpoint",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ entry);
+
+ if (m_process) {
+ Breakpoint *const entry_break =
+ m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
+ entry_break->SetCallback(EntryBreakpointHit, this, true);
+ entry_break->SetBreakpointKind("shared-library-event");
+
+ // Shoudn't hit this more than once.
+ entry_break->SetOneShot(true);
+ }
}
// The runtime linker has run and initialized the rendezvous structure once the
@@ -289,405 +276,429 @@ DynamicLoaderPOSIXDYLD::ProbeEntry()
// dependent modules for the process. Similarly, we can discover the runtime
// linker function and setup a breakpoint to notify us of any dynamically loaded
// modules (via dlopen).
-bool
-DynamicLoaderPOSIXDYLD::EntryBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- assert(baton && "null baton");
- if (!baton)
- return false;
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, __FUNCTION__, dyld_instance->m_process ? dyld_instance->m_process->GetID () : LLDB_INVALID_PROCESS_ID);
-
- // Disable the breakpoint --- if a stop happens right after this, which we've seen on occasion, we don't
- // want the breakpoint stepping thread-plan logic to show a breakpoint instruction at the disassembled
- // entry point to the program. Disabling it prevents it. (One-shot is not enough - one-shot removal logic
- // only happens after the breakpoint goes public, which wasn't happening in our scenario).
- if (dyld_instance->m_process)
- {
- BreakpointSP breakpoint_sp = dyld_instance->m_process->GetTarget().GetBreakpointByID (break_id);
- if (breakpoint_sp)
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " disabling breakpoint id %" PRIu64, __FUNCTION__, dyld_instance->m_process->GetID (), break_id);
- breakpoint_sp->SetEnabled (false);
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " failed to find breakpoint for breakpoint id %" PRIu64, __FUNCTION__, dyld_instance->m_process->GetID (), break_id);
- }
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64 " no Process instance! Cannot disable breakpoint", __FUNCTION__, break_id);
+bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(baton && "null baton");
+ if (!baton)
+ return false;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ DynamicLoaderPOSIXDYLD *const dyld_instance =
+ static_cast<DynamicLoaderPOSIXDYLD *>(baton);
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
+
+ // Disable the breakpoint --- if a stop happens right after this, which we've
+ // seen on occasion, we don't
+ // want the breakpoint stepping thread-plan logic to show a breakpoint
+ // instruction at the disassembled
+ // entry point to the program. Disabling it prevents it. (One-shot is not
+ // enough - one-shot removal logic
+ // only happens after the breakpoint goes public, which wasn't happening in
+ // our scenario).
+ if (dyld_instance->m_process) {
+ BreakpointSP breakpoint_sp =
+ dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
+ if (breakpoint_sp) {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " disabling breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
+ breakpoint_sp->SetEnabled(false);
+ } else {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " failed to find breakpoint for breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
}
-
- dyld_instance->LoadAllCurrentModules();
- dyld_instance->SetRendezvousBreakpoint();
- return false; // Continue running.
+ } else {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
+ " no Process instance! Cannot disable breakpoint",
+ __FUNCTION__, break_id);
+ }
+
+ dyld_instance->LoadAllCurrentModules();
+ dyld_instance->SetRendezvousBreakpoint();
+ return false; // Continue running.
}
-void
-DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- addr_t break_addr = m_rendezvous.GetBreakAddress();
- Target &target = m_process->GetTarget();
-
- if (m_dyld_bid == LLDB_INVALID_BREAK_ID)
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " setting rendezvous break address at 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, break_addr);
- Breakpoint *dyld_break = target.CreateBreakpoint (break_addr, true, false).get();
- dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
- dyld_break->SetBreakpointKind ("shared-library-event");
- m_dyld_bid = dyld_break->GetID();
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reusing break id %" PRIu32 ", address at 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, m_dyld_bid, break_addr);
- }
+void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- // Make sure our breakpoint is at the right address.
- assert (target.GetBreakpointByID(m_dyld_bid)->FindLocationByAddress(break_addr)->GetBreakpoint().GetID() == m_dyld_bid);
-}
+ addr_t break_addr = m_rendezvous.GetBreakAddress();
+ Target &target = m_process->GetTarget();
-bool
-DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- assert (baton && "null baton");
- if (!baton)
- return false;
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
+ if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, __FUNCTION__, dyld_instance->m_process ? dyld_instance->m_process->GetID () : LLDB_INVALID_PROCESS_ID);
-
- dyld_instance->RefreshModules();
-
- // Return true to stop the target, false to just let the target run.
- const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " setting rendezvous break address at 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ break_addr);
+ Breakpoint *dyld_break =
+ target.CreateBreakpoint(break_addr, true, false).get();
+ dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_dyld_bid = dyld_break->GetID();
+ } else {
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " stop_when_images_change=%s", __FUNCTION__, dyld_instance->m_process ? dyld_instance->m_process->GetID () : LLDB_INVALID_PROCESS_ID, stop_when_images_change ? "true" : "false");
- return stop_when_images_change;
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " reusing break id %" PRIu32 ", address at 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ m_dyld_bid, break_addr);
+ }
+
+ // Make sure our breakpoint is at the right address.
+ assert(target.GetBreakpointByID(m_dyld_bid)
+ ->FindLocationByAddress(break_addr)
+ ->GetBreakpoint()
+ .GetID() == m_dyld_bid);
+}
+
+bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(baton && "null baton");
+ if (!baton)
+ return false;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ DynamicLoaderPOSIXDYLD *const dyld_instance =
+ static_cast<DynamicLoaderPOSIXDYLD *>(baton);
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
+
+ dyld_instance->RefreshModules();
+
+ // Return true to stop the target, false to just let the target run.
+ const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " stop_when_images_change=%s",
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID,
+ stop_when_images_change ? "true" : "false");
+ return stop_when_images_change;
}
-void
-DynamicLoaderPOSIXDYLD::RefreshModules()
-{
- if (!m_rendezvous.Resolve())
- return;
-
- DYLDRendezvous::iterator I;
- DYLDRendezvous::iterator E;
-
- ModuleList &loaded_modules = m_process->GetTarget().GetImages();
-
- if (m_rendezvous.ModulesDidLoad())
- {
- ModuleList new_modules;
-
- E = m_rendezvous.loaded_end();
- for (I = m_rendezvous.loaded_begin(); I != E; ++I)
- {
- ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- loaded_modules.AppendIfNeeded(module_sp);
- new_modules.Append(module_sp);
- }
- }
- m_process->GetTarget().ModulesDidLoad(new_modules);
+void DynamicLoaderPOSIXDYLD::RefreshModules() {
+ if (!m_rendezvous.Resolve())
+ return;
+
+ DYLDRendezvous::iterator I;
+ DYLDRendezvous::iterator E;
+
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+ if (m_rendezvous.ModulesDidLoad()) {
+ ModuleList new_modules;
+
+ E = m_rendezvous.loaded_end();
+ for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
+ ModuleSP module_sp =
+ LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ loaded_modules.AppendIfNeeded(module_sp);
+ new_modules.Append(module_sp);
+ }
}
-
- if (m_rendezvous.ModulesDidUnload())
- {
- ModuleList old_modules;
-
- E = m_rendezvous.unloaded_end();
- for (I = m_rendezvous.unloaded_begin(); I != E; ++I)
- {
- ModuleSpec module_spec{I->file_spec};
- ModuleSP module_sp = loaded_modules.FindFirstModule (module_spec);
-
- if (module_sp.get())
- {
- old_modules.Append(module_sp);
- UnloadSections(module_sp);
- }
- }
- loaded_modules.Remove(old_modules);
- m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ m_process->GetTarget().ModulesDidLoad(new_modules);
+ }
+
+ if (m_rendezvous.ModulesDidUnload()) {
+ ModuleList old_modules;
+
+ E = m_rendezvous.unloaded_end();
+ for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
+ ModuleSpec module_spec{I->file_spec};
+ ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
+
+ if (module_sp.get()) {
+ old_modules.Append(module_sp);
+ UnloadSections(module_sp);
+ }
}
+ loaded_modules.Remove(old_modules);
+ m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ }
}
ThreadPlanSP
-DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
-{
- ThreadPlanSP thread_plan_sp;
-
- StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *sym = context.symbol;
-
- if (sym == NULL || !sym->IsTrampoline())
- return thread_plan_sp;
-
- ConstString sym_name = sym->GetName();
- if (!sym_name)
- return thread_plan_sp;
-
- SymbolContextList target_symbols;
- Target &target = thread.GetProcess()->GetTarget();
- const ModuleList &images = target.GetImages();
-
- images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
- size_t num_targets = target_symbols.GetSize();
- if (!num_targets)
- return thread_plan_sp;
-
- typedef std::vector<lldb::addr_t> AddressVector;
- AddressVector addrs;
- for (size_t i = 0; i < num_targets; ++i)
- {
- SymbolContext context;
- AddressRange range;
- if (target_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange(eSymbolContextEverything, 0, false, range);
- lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
- if (addr != LLDB_INVALID_ADDRESS)
- addrs.push_back(addr);
- }
- }
+DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) {
+ ThreadPlanSP thread_plan_sp;
- if (addrs.size() > 0)
- {
- AddressVector::iterator start = addrs.begin();
- AddressVector::iterator end = addrs.end();
+ StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
+ const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
+ Symbol *sym = context.symbol;
- std::sort(start, end);
- addrs.erase(std::unique(start, end), end);
- thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
- }
+ if (sym == NULL || !sym->IsTrampoline())
+ return thread_plan_sp;
+ ConstString sym_name = sym->GetName();
+ if (!sym_name)
return thread_plan_sp;
-}
-void
-DynamicLoaderPOSIXDYLD::LoadAllCurrentModules()
-{
- DYLDRendezvous::iterator I;
- DYLDRendezvous::iterator E;
- ModuleList module_list;
-
- if (!m_rendezvous.Resolve())
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD rendezvous address",
- __FUNCTION__);
- return;
+ SymbolContextList target_symbols;
+ Target &target = thread.GetProcess()->GetTarget();
+ const ModuleList &images = target.GetImages();
+
+ images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
+ size_t num_targets = target_symbols.GetSize();
+ if (!num_targets)
+ return thread_plan_sp;
+
+ typedef std::vector<lldb::addr_t> AddressVector;
+ AddressVector addrs;
+ for (size_t i = 0; i < num_targets; ++i) {
+ SymbolContext context;
+ AddressRange range;
+ if (target_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false, range);
+ lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
+ if (addr != LLDB_INVALID_ADDRESS)
+ addrs.push_back(addr);
}
+ }
+
+ if (addrs.size() > 0) {
+ AddressVector::iterator start = addrs.begin();
+ AddressVector::iterator end = addrs.end();
- // The rendezvous class doesn't enumerate the main module, so track
- // that ourselves here.
- ModuleSP executable = GetTargetExecutable();
- m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
- if (m_vdso_base != LLDB_INVALID_ADDRESS)
- {
- FileSpec file_spec("[vdso]", false);
- ModuleSP module_sp = LoadModuleAtAddress(file_spec, LLDB_INVALID_ADDRESS, m_vdso_base, false);
- if (module_sp.get())
- {
- module_list.Append(module_sp);
- }
+ std::sort(start, end);
+ addrs.erase(std::unique(start, end), end);
+ thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
+ }
+
+ return thread_plan_sp;
+}
+
+void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
+ DYLDRendezvous::iterator I;
+ DYLDRendezvous::iterator E;
+ ModuleList module_list;
+
+ if (!m_rendezvous.Resolve()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
+ "rendezvous address",
+ __FUNCTION__);
+ return;
+ }
+
+ // The rendezvous class doesn't enumerate the main module, so track
+ // that ourselves here.
+ ModuleSP executable = GetTargetExecutable();
+ m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
+ if (m_vdso_base != LLDB_INVALID_ADDRESS) {
+ FileSpec file_spec("[vdso]", false);
+ ModuleSP module_sp = LoadModuleAtAddress(file_spec, LLDB_INVALID_ADDRESS,
+ m_vdso_base, false);
+ if (module_sp.get()) {
+ module_list.Append(module_sp);
}
- for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
- {
- ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- module_list.Append(module_sp);
- }
- else
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
- __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
- }
+ }
+
+ std::vector<FileSpec> module_names;
+ for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
+ module_names.push_back(I->file_spec);
+ m_process->PrefetchModuleSpecs(
+ module_names, m_process->GetTarget().GetArchitecture().GetTriple());
+
+ for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
+ ModuleSP module_sp =
+ LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ module_list.Append(module_sp);
+ } else {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf(
+ "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
+ __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
}
+ }
- m_process->GetTarget().ModulesDidLoad(module_list);
+ m_process->GetTarget().ModulesDidLoad(module_list);
}
-addr_t
-DynamicLoaderPOSIXDYLD::ComputeLoadOffset()
-{
- addr_t virt_entry;
+addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() {
+ addr_t virt_entry;
- if (m_load_offset != LLDB_INVALID_ADDRESS)
- return m_load_offset;
+ if (m_load_offset != LLDB_INVALID_ADDRESS)
+ return m_load_offset;
- if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
+ if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
- ModuleSP module = m_process->GetTarget().GetExecutableModule();
- if (!module)
- return LLDB_INVALID_ADDRESS;
+ ModuleSP module = m_process->GetTarget().GetExecutableModule();
+ if (!module)
+ return LLDB_INVALID_ADDRESS;
- ObjectFile *exe = module->GetObjectFile();
- if (!exe)
- return LLDB_INVALID_ADDRESS;
+ ObjectFile *exe = module->GetObjectFile();
+ if (!exe)
+ return LLDB_INVALID_ADDRESS;
- Address file_entry = exe->GetEntryPointAddress();
+ Address file_entry = exe->GetEntryPointAddress();
- if (!file_entry.IsValid())
- return LLDB_INVALID_ADDRESS;
-
- m_load_offset = virt_entry - file_entry.GetFileAddress();
- return m_load_offset;
-}
+ if (!file_entry.IsValid())
+ return LLDB_INVALID_ADDRESS;
-void
-DynamicLoaderPOSIXDYLD::EvalVdsoStatus()
-{
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_SYSINFO_EHDR);
+ m_load_offset = virt_entry - file_entry.GetFileAddress();
+ return m_load_offset;
+}
- if (I != m_auxv->end())
- m_vdso_base = I->value;
+void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() {
+ AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_SYSINFO_EHDR);
+ if (I != m_auxv->end())
+ m_vdso_base = I->value;
}
-addr_t
-DynamicLoaderPOSIXDYLD::GetEntryPoint()
-{
- if (m_entry_point != LLDB_INVALID_ADDRESS)
- return m_entry_point;
+addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
+ if (m_entry_point != LLDB_INVALID_ADDRESS)
+ return m_entry_point;
- if (m_auxv.get() == NULL)
- return LLDB_INVALID_ADDRESS;
+ if (m_auxv.get() == NULL)
+ return LLDB_INVALID_ADDRESS;
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
+ AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
- if (I == m_auxv->end())
- return LLDB_INVALID_ADDRESS;
+ if (I == m_auxv->end())
+ return LLDB_INVALID_ADDRESS;
- m_entry_point = static_cast<addr_t>(I->value);
+ m_entry_point = static_cast<addr_t>(I->value);
- const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
+ const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
- // On ppc64, the entry point is actually a descriptor. Dereference it.
- if (arch.GetMachine() == llvm::Triple::ppc64)
- m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
+ // On ppc64, the entry point is actually a descriptor. Dereference it.
+ if (arch.GetMachine() == llvm::Triple::ppc64)
+ m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
- return m_entry_point;
+ return m_entry_point;
}
lldb::addr_t
-DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread,
- lldb::addr_t tls_file_addr)
-{
- auto it = m_loaded_modules.find (module_sp);
- if (it == m_loaded_modules.end())
- return LLDB_INVALID_ADDRESS;
-
- addr_t link_map = it->second;
- if (link_map == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
- if (!metadata.valid)
- return LLDB_INVALID_ADDRESS;
-
- // Get the thread pointer.
- addr_t tp = thread->GetThreadPointer ();
- if (tp == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the module's modid.
- int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
- int64_t modid = ReadUnsignedIntWithSizeInBytes (link_map + metadata.modid_offset, modid_size);
- if (modid == -1)
- return LLDB_INVALID_ADDRESS;
-
- // Lookup the DTV structure for this thread.
- addr_t dtv_ptr = tp + metadata.dtv_offset;
- addr_t dtv = ReadPointer (dtv_ptr);
- if (dtv == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the TLS block for this module.
- addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid;
- addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset);
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
- module_sp->GetObjectName().AsCString(""), link_map, tp, (int64_t)modid, tls_block);
-
- if (tls_block == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
- else
- return tls_block + tls_file_addr;
+DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) {
+ auto it = m_loaded_modules.find(module_sp);
+ if (it == m_loaded_modules.end())
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t link_map = it->second;
+ if (link_map == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
+ if (!metadata.valid)
+ return LLDB_INVALID_ADDRESS;
+
+ // Get the thread pointer.
+ addr_t tp = thread->GetThreadPointer();
+ if (tp == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the module's modid.
+ int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
+ int64_t modid = ReadUnsignedIntWithSizeInBytes(
+ link_map + metadata.modid_offset, modid_size);
+ if (modid == -1)
+ return LLDB_INVALID_ADDRESS;
+
+ // Lookup the DTV structure for this thread.
+ addr_t dtv_ptr = tp + metadata.dtv_offset;
+ addr_t dtv = ReadPointer(dtv_ptr);
+ if (dtv == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the TLS block for this module.
+ addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
+ addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
+ module_sp->GetObjectName().AsCString(""), link_map, tp,
+ (int64_t)modid, tls_block);
+
+ if (tls_block == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ else
+ return tls_block + tls_file_addr;
}
-void
-DynamicLoaderPOSIXDYLD::ResolveExecutableModule (lldb::ModuleSP &module_sp)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
+ lldb::ModuleSP &module_sp) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (m_process == nullptr)
- return;
+ if (m_process == nullptr)
+ return;
- auto &target = m_process->GetTarget ();
- const auto platform_sp = target.GetPlatform ();
+ auto &target = m_process->GetTarget();
+ const auto platform_sp = target.GetPlatform();
- ProcessInstanceInfo process_info;
- if (!m_process->GetProcessInfo(process_info))
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to get process info for pid %" PRIu64,
- __FUNCTION__, m_process->GetID ());
- return;
- }
+ ProcessInstanceInfo process_info;
+ if (!m_process->GetProcessInfo(process_info)) {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
+ "pid %" PRIu64,
+ __FUNCTION__, m_process->GetID());
+ return;
+ }
+
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64
+ ": %s",
+ __FUNCTION__, m_process->GetID(),
+ process_info.GetExecutableFile().GetPath().c_str());
+
+ ModuleSpec module_spec(process_info.GetExecutableFile(),
+ process_info.GetArchitecture());
+ if (module_sp && module_sp->MatchesModuleSpec(module_spec))
+ return;
+
+ const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
+ auto error = platform_sp->ResolveExecutable(
+ module_spec, module_sp,
+ !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
+ if (error.Fail()) {
+ StreamString stream;
+ module_spec.Dump(stream);
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
- __FUNCTION__, m_process->GetID (), process_info.GetExecutableFile ().GetPath ().c_str ());
-
- ModuleSpec module_spec (process_info.GetExecutableFile (), process_info.GetArchitecture ());
- if (module_sp && module_sp->MatchesModuleSpec (module_spec))
- return;
-
- const auto executable_search_paths (Target::GetDefaultExecutableSearchPaths());
- auto error = platform_sp->ResolveExecutable (
- module_spec, module_sp, !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
- if (error.Fail ())
- {
- StreamString stream;
- module_spec.Dump (stream);
-
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable with module spec \"%s\": %s",
- __FUNCTION__, stream.GetString ().c_str (), error.AsCString ());
- return;
- }
+ log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
+ "with module spec \"%s\": %s",
+ __FUNCTION__, stream.GetData(), error.AsCString());
+ return;
+ }
+
+ target.SetExecutableModule(module_sp, false);
+}
- target.SetExecutableModule (module_sp, false);
+bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
+ lldb_private::SymbolContext &sym_ctx) {
+ ModuleSP module_sp;
+ if (sym_ctx.symbol)
+ module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
+ if (!module_sp && sym_ctx.function)
+ module_sp =
+ sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
+ if (!module_sp)
+ return false;
+
+ return module_sp->GetFileSpec().GetPath() == "[vdso]";
}
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
index 890808c5179c..1e8333fb099a 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -21,159 +21,139 @@
class AuxVector;
-class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader
-{
+class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader {
public:
- DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
+ DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
- ~DynamicLoaderPOSIXDYLD() override;
+ ~DynamicLoaderPOSIXDYLD() override;
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance(lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- // DynamicLoader protocol
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // DynamicLoader protocol
+ //------------------------------------------------------------------
- void
- DidAttach() override;
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+ lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- /// Runtime linker rendezvous structure.
- DYLDRendezvous m_rendezvous;
-
- /// Virtual load address of the inferior process.
- lldb::addr_t m_load_offset;
-
- /// Virtual entry address of the inferior process.
- lldb::addr_t m_entry_point;
-
- /// Auxiliary vector of the inferior process.
- std::unique_ptr<AuxVector> m_auxv;
-
- /// Rendezvous breakpoint.
- lldb::break_id_t m_dyld_bid;
-
- /// Contains AT_SYSINFO_EHDR, which means a vDSO has been
- /// mapped to the address space
- lldb::addr_t m_vdso_base;
-
- /// Loaded module list. (link map for each module)
- std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>> m_loaded_modules;
-
- /// Enables a breakpoint on a function called by the runtime
- /// linker each time a module is loaded or unloaded.
- virtual void
- SetRendezvousBreakpoint();
-
- /// Callback routine which updates the current list of loaded modules based
- /// on the information supplied by the runtime linker.
- static bool
- RendezvousBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
- /// of loaded modules.
- void
- RefreshModules();
-
- /// Updates the load address of every allocatable section in @p module.
- ///
- /// @param module The module to traverse.
- ///
- /// @param link_map_addr The virtual address of the link map for the @p module.
- ///
- /// @param base_addr The virtual base address @p module is loaded at.
- void
- UpdateLoadedSections(lldb::ModuleSP module,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset) override;
-
- /// Removes the loaded sections from the target in @p module.
- ///
- /// @param module The module to traverse.
- void
- UnloadSections(const lldb::ModuleSP module) override;
-
- /// Resolves the entry point for the current inferior process and sets a
- /// breakpoint at that address.
- void
- ProbeEntry();
-
- /// Callback routine invoked when we hit the breakpoint on process entry.
- ///
- /// This routine is responsible for resolving the load addresses of all
- /// dependent modules required by the inferior and setting up the rendezvous
- /// breakpoint.
- static bool
- EntryBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper for the entry breakpoint callback. Resolves the load addresses
- /// of all dependent modules.
- virtual void
- LoadAllCurrentModules();
-
- /// Computes a value for m_load_offset returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- ComputeLoadOffset();
-
- /// Computes a value for m_entry_point returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- GetEntryPoint();
-
- /// Evaluate if Aux vectors contain vDSO information
- /// in case they do, read and assign the address to m_vdso_base
- void
- EvalVdsoStatus();
-
- /// Loads Module from inferior process.
- void
- ResolveExecutableModule(lldb::ModuleSP &module_sp);
+ /// Runtime linker rendezvous structure.
+ DYLDRendezvous m_rendezvous;
+
+ /// Virtual load address of the inferior process.
+ lldb::addr_t m_load_offset;
+
+ /// Virtual entry address of the inferior process.
+ lldb::addr_t m_entry_point;
+
+ /// Auxiliary vector of the inferior process.
+ std::unique_ptr<AuxVector> m_auxv;
+
+ /// Rendezvous breakpoint.
+ lldb::break_id_t m_dyld_bid;
+
+ /// Contains AT_SYSINFO_EHDR, which means a vDSO has been
+ /// mapped to the address space
+ lldb::addr_t m_vdso_base;
+
+ /// Loaded module list. (link map for each module)
+ std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
+ m_loaded_modules;
+
+ /// Enables a breakpoint on a function called by the runtime
+ /// linker each time a module is loaded or unloaded.
+ virtual void SetRendezvousBreakpoint();
+
+ /// Callback routine which updates the current list of loaded modules based
+ /// on the information supplied by the runtime linker.
+ static bool RendezvousBreakpointHit(
+ void *baton, lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
+ /// of loaded modules.
+ void RefreshModules();
+
+ /// Updates the load address of every allocatable section in @p module.
+ ///
+ /// @param module The module to traverse.
+ ///
+ /// @param link_map_addr The virtual address of the link map for the @p
+ /// module.
+ ///
+ /// @param base_addr The virtual base address @p module is loaded at.
+ void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr,
+ lldb::addr_t base_addr,
+ bool base_addr_is_offset) override;
+
+ /// Removes the loaded sections from the target in @p module.
+ ///
+ /// @param module The module to traverse.
+ void UnloadSections(const lldb::ModuleSP module) override;
+
+ /// Resolves the entry point for the current inferior process and sets a
+ /// breakpoint at that address.
+ void ProbeEntry();
+
+ /// Callback routine invoked when we hit the breakpoint on process entry.
+ ///
+ /// This routine is responsible for resolving the load addresses of all
+ /// dependent modules required by the inferior and setting up the rendezvous
+ /// breakpoint.
+ static bool
+ EntryBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper for the entry breakpoint callback. Resolves the load addresses
+ /// of all dependent modules.
+ virtual void LoadAllCurrentModules();
+
+ /// Computes a value for m_load_offset returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t ComputeLoadOffset();
+
+ /// Computes a value for m_entry_point returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t GetEntryPoint();
+
+ /// Evaluate if Aux vectors contain vDSO information
+ /// in case they do, read and assign the address to m_vdso_base
+ void EvalVdsoStatus();
+
+ /// Loads Module from inferior process.
+ void ResolveExecutableModule(lldb::ModuleSP &module_sp);
+
+ bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
private:
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
};
#endif // liblldb_DynamicLoaderPOSIXDYLD_h_
diff --git a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index daa21adf3a95..04f1f3390570 100644
--- a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -23,50 +23,42 @@ using namespace lldb_private;
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-DynamicLoader *
-DynamicLoaderStatic::CreateInstance (Process* process, bool force)
-{
- bool create = force;
- if (!create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- const llvm::Triple::OSType os_type = triple_ref.getOS();
- if ((os_type == llvm::Triple::UnknownOS))
- create = true;
+DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ const llvm::Triple::OSType os_type = triple_ref.getOS();
+ if ((os_type == llvm::Triple::UnknownOS))
+ create = true;
+ }
+
+ if (!create) {
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
+ }
}
-
- if (!create)
- {
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
- }
- }
- }
-
- if (create)
- return new DynamicLoaderStatic (process);
- return NULL;
+ }
+
+ if (create)
+ return new DynamicLoaderStatic(process);
+ return NULL;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderStatic::DynamicLoaderStatic (Process* process) :
- DynamicLoader(process)
-{
-}
+DynamicLoaderStatic::DynamicLoaderStatic(Process *process)
+ : DynamicLoader(process) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderStatic::~DynamicLoaderStatic()
-{
-}
+DynamicLoaderStatic::~DynamicLoaderStatic() {}
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -74,11 +66,7 @@ DynamicLoaderStatic::~DynamicLoaderStatic()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderStatic::DidAttach ()
-{
- LoadAllImagesAtFileAddresses();
-}
+void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); }
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -86,124 +74,94 @@ DynamicLoaderStatic::DidAttach ()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderStatic::DidLaunch ()
-{
- LoadAllImagesAtFileAddresses();
-}
-
-void
-DynamicLoaderStatic::LoadAllImagesAtFileAddresses ()
-{
- const ModuleList &module_list = m_process->GetTarget().GetImages();
-
- ModuleList loaded_module_list;
-
- // Disable JIT for static dynamic loader targets
- m_process->SetCanJIT(false);
-
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
-
- const size_t num_modules = module_list.GetSize();
- for (uint32_t idx = 0; idx < num_modules; ++idx)
- {
- ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (idx));
- if (module_sp)
- {
- bool changed = false;
- ObjectFile *image_object_file = module_sp->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = section_list->GetSize();
- size_t sect_idx = 0;
- for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- if (section_sp)
- {
- if (m_process->GetTarget().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress()))
- changed = true;
- }
- }
- }
+void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); }
+
+void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
+ const ModuleList &module_list = m_process->GetTarget().GetImages();
+
+ ModuleList loaded_module_list;
+
+ // Disable JIT for static dynamic loader targets
+ m_process->SetCanJIT(false);
+
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+
+ const size_t num_modules = module_list.GetSize();
+ for (uint32_t idx = 0; idx < num_modules; ++idx) {
+ ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(idx));
+ if (module_sp) {
+ bool changed = false;
+ ObjectFile *image_object_file = module_sp->GetObjectFile();
+ if (image_object_file) {
+ SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ // All sections listed in the dyld image info structure will all
+ // either be fixed up already, or they will all be off by a single
+ // slide amount that is determined by finding the first segment
+ // that is at file offset zero which also has bytes (a file size
+ // that is greater than zero) in the object file.
+
+ // Determine the slide amount (if any)
+ const size_t num_sections = section_list->GetSize();
+ size_t sect_idx = 0;
+ for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+ if (section_sp) {
+ if (m_process->GetTarget().SetSectionLoadAddress(
+ section_sp, section_sp->GetFileAddress()))
+ changed = true;
}
-
- if (changed)
- loaded_module_list.AppendIfNeeded (module_sp);
+ }
}
+ }
+
+ if (changed)
+ loaded_module_list.AppendIfNeeded(module_sp);
}
+ }
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+ m_process->GetTarget().ModulesDidLoad(loaded_module_list);
}
ThreadPlanSP
-DynamicLoaderStatic::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- return ThreadPlanSP();
+DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) {
+ return ThreadPlanSP();
}
-Error
-DynamicLoaderStatic::CanLoadImage ()
-{
- Error error;
- error.SetErrorString ("can't load images on with a static debug session");
- return error;
+Error DynamicLoaderStatic::CanLoadImage() {
+ Error error;
+ error.SetErrorString("can't load images on with a static debug session");
+ return error;
}
-void
-DynamicLoaderStatic::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void DynamicLoaderStatic::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-DynamicLoaderStatic::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void DynamicLoaderStatic::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-DynamicLoaderStatic::GetPluginNameStatic()
-{
- static ConstString g_name("static");
- return g_name;
+lldb_private::ConstString DynamicLoaderStatic::GetPluginNameStatic() {
+ static ConstString g_name("static");
+ return g_name;
}
-const char *
-DynamicLoaderStatic::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that will load any images at the static addresses contained in each image.";
+const char *DynamicLoaderStatic::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that will load any images at the static "
+ "addresses contained in each image.";
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-DynamicLoaderStatic::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-DynamicLoaderStatic::GetPluginVersion()
-{
- return 1;
+lldb_private::ConstString DynamicLoaderStatic::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t DynamicLoaderStatic::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
index 67694c96025c..c6122edf50cf 100644
--- a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
+++ b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
@@ -14,69 +14,57 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
-class DynamicLoaderStatic : public lldb_private::DynamicLoader
-{
+class DynamicLoaderStatic : public lldb_private::DynamicLoader {
public:
- DynamicLoaderStatic(lldb_private::Process *process);
+ DynamicLoaderStatic(lldb_private::Process *process);
- ~DynamicLoaderStatic() override;
+ ~DynamicLoaderStatic() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void
- DidAttach() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
private:
- void
- LoadAllImagesAtFileAddresses ();
+ void LoadAllImagesAtFileAddresses();
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderStatic);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderStatic);
};
#endif // liblldb_DynamicLoaderStatic_h_
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index dd391b4ca4d2..20bf3609f46f 100644
--- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -1,4 +1,5 @@
-//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ -*-===//
+//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,86 +20,57 @@ using namespace lldb;
using namespace lldb_private;
DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process)
- : DynamicLoader(process)
-{
-}
+ : DynamicLoader(process) {}
-DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD()
-{
-}
+DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {}
-void
-DynamicLoaderWindowsDYLD::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
+void DynamicLoaderWindowsDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-DynamicLoaderWindowsDYLD::Terminate()
-{
-}
+void DynamicLoaderWindowsDYLD::Terminate() {}
-ConstString
-DynamicLoaderWindowsDYLD::GetPluginNameStatic()
-{
- static ConstString g_plugin_name("windows-dyld");
- return g_plugin_name;
+ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() {
+ static ConstString g_plugin_name("windows-dyld");
+ return g_plugin_name;
}
-const char *
-DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library "
- "loads/unloads in Windows processes.";
+const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library "
+ "loads/unloads in Windows processes.";
}
-DynamicLoader *
-DynamicLoaderWindowsDYLD::CreateInstance(Process *process, bool force)
-{
- bool should_create = force;
- if (!should_create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- if (triple_ref.getOS() == llvm::Triple::Win32)
- should_create = true;
- }
-
- if (should_create)
- return new DynamicLoaderWindowsDYLD(process);
-
- return nullptr;
-}
+DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool should_create = force;
+ if (!should_create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ if (triple_ref.getOS() == llvm::Triple::Win32)
+ should_create = true;
+ }
-void
-DynamicLoaderWindowsDYLD::DidAttach()
-{
-}
+ if (should_create)
+ return new DynamicLoaderWindowsDYLD(process);
-void
-DynamicLoaderWindowsDYLD::DidLaunch()
-{
+ return nullptr;
}
-Error
-DynamicLoaderWindowsDYLD::CanLoadImage()
-{
- return Error();
-}
+void DynamicLoaderWindowsDYLD::DidAttach() {}
-ConstString
-DynamicLoaderWindowsDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+void DynamicLoaderWindowsDYLD::DidLaunch() {}
-uint32_t
-DynamicLoaderWindowsDYLD::GetPluginVersion()
-{
- return 1;
+Error DynamicLoaderWindowsDYLD::CanLoadImage() { return Error(); }
+
+ConstString DynamicLoaderWindowsDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; }
+
ThreadPlanSP
-DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
-{
- return ThreadPlanSP();
+DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) {
+ return ThreadPlanSP();
}
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index 8c479819c535..3494082eea8d 100644
--- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -14,33 +14,32 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-forward.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class DynamicLoaderWindowsDYLD : public DynamicLoader
-{
+class DynamicLoaderWindowsDYLD : public DynamicLoader {
public:
- DynamicLoaderWindowsDYLD(Process *process);
+ DynamicLoaderWindowsDYLD(Process *process);
- ~DynamicLoaderWindowsDYLD() override;
+ ~DynamicLoaderWindowsDYLD() override;
- static void Initialize();
- static void Terminate();
- static ConstString GetPluginNameStatic();
- static const char *GetPluginDescriptionStatic();
+ static void Initialize();
+ static void Terminate();
+ static ConstString GetPluginNameStatic();
+ static const char *GetPluginDescriptionStatic();
- static DynamicLoader *CreateInstance(Process *process, bool force);
+ static DynamicLoader *CreateInstance(Process *process, bool force);
- void DidAttach() override;
- void DidLaunch() override;
- Error CanLoadImage() override;
- lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop) override;
+ void DidAttach() override;
+ void DidLaunch() override;
+ Error CanLoadImage() override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) override;
- ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
index 0b8199481158..c74f1474e7be 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
@@ -18,118 +18,92 @@
using namespace lldb_private;
-ASTDumper::ASTDumper (clang::Decl *decl)
-{
- clang::DeclContext *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl);
-
- bool has_external_lexical_storage;
- bool has_external_visible_storage;
-
- if (decl_ctx)
- {
- has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
- has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
- decl_ctx->setHasExternalLexicalStorage(false);
- decl_ctx->setHasExternalVisibleStorage(false);
- }
-
- llvm::raw_string_ostream os(m_dump);
- decl->print (os);
- os.flush();
-
- if (decl_ctx)
- {
- decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
- decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
- }
-}
+ASTDumper::ASTDumper(clang::Decl *decl) {
+ clang::DeclContext *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl);
+
+ bool has_external_lexical_storage;
+ bool has_external_visible_storage;
-ASTDumper::ASTDumper (clang::DeclContext *decl_ctx)
-{
- bool has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
- bool has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
-
+ if (decl_ctx) {
+ has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
+ has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
decl_ctx->setHasExternalLexicalStorage(false);
decl_ctx->setHasExternalVisibleStorage(false);
-
- if (clang::Decl *decl = llvm::dyn_cast<clang::Decl>(decl_ctx))
- {
- llvm::raw_string_ostream os(m_dump);
- decl->print (os);
- os.flush();
- }
- else
- {
- m_dump.assign("<DeclContext is not a Decl>");
- }
-
+ }
+
+ llvm::raw_string_ostream os(m_dump);
+ decl->print(os);
+ os.flush();
+
+ if (decl_ctx) {
decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
+ }
}
-ASTDumper::ASTDumper (const clang::Type *type)
-{
- m_dump = clang::QualType(type, 0).getAsString();
-}
+ASTDumper::ASTDumper(clang::DeclContext *decl_ctx) {
+ bool has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
+ bool has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
-ASTDumper::ASTDumper (clang::QualType type)
-{
- m_dump = type.getAsString();
-}
+ decl_ctx->setHasExternalLexicalStorage(false);
+ decl_ctx->setHasExternalVisibleStorage(false);
+
+ if (clang::Decl *decl = llvm::dyn_cast<clang::Decl>(decl_ctx)) {
+ llvm::raw_string_ostream os(m_dump);
+ decl->print(os);
+ os.flush();
+ } else {
+ m_dump.assign("<DeclContext is not a Decl>");
+ }
-ASTDumper::ASTDumper (lldb::opaque_compiler_type_t type)
-{
- m_dump = clang::QualType::getFromOpaquePtr(type).getAsString();
+ decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
+ decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
}
-ASTDumper::ASTDumper (const CompilerType &compiler_type)
-{
- m_dump = ClangUtil::GetQualType(compiler_type).getAsString();
+ASTDumper::ASTDumper(const clang::Type *type) {
+ m_dump = clang::QualType(type, 0).getAsString();
}
+ASTDumper::ASTDumper(clang::QualType type) { m_dump = type.getAsString(); }
-const char *
-ASTDumper::GetCString()
-{
- return m_dump.c_str();
+ASTDumper::ASTDumper(lldb::opaque_compiler_type_t type) {
+ m_dump = clang::QualType::getFromOpaquePtr(type).getAsString();
}
-void ASTDumper::ToSTDERR()
-{
- fprintf(stderr, "%s\n", m_dump.c_str());
+ASTDumper::ASTDumper(const CompilerType &compiler_type) {
+ m_dump = ClangUtil::GetQualType(compiler_type).getAsString();
}
-void ASTDumper::ToLog(Log *log, const char *prefix)
-{
- size_t len = m_dump.length() + 1;
-
- char *alloc = (char*)malloc(len);
- char *str = alloc;
-
- memcpy(str, m_dump.c_str(), len);
-
- char *end = NULL;
-
- end = strchr(str, '\n');
-
- while (end)
- {
- *end = '\0';
-
- log->Printf("%s%s", prefix, str);
-
- *end = '\n';
-
- str = end + 1;
- end = strchr(str, '\n');
- }
-
+const char *ASTDumper::GetCString() { return m_dump.c_str(); }
+
+void ASTDumper::ToSTDERR() { fprintf(stderr, "%s\n", m_dump.c_str()); }
+
+void ASTDumper::ToLog(Log *log, const char *prefix) {
+ size_t len = m_dump.length() + 1;
+
+ char *alloc = (char *)malloc(len);
+ char *str = alloc;
+
+ memcpy(str, m_dump.c_str(), len);
+
+ char *end = NULL;
+
+ end = strchr(str, '\n');
+
+ while (end) {
+ *end = '\0';
+
log->Printf("%s%s", prefix, str);
-
- free(alloc);
-}
-void ASTDumper::ToStream(lldb::StreamSP &stream)
-{
- stream->PutCString(m_dump.c_str());
+ *end = '\n';
+
+ str = end + 1;
+ end = strchr(str, '\n');
+ }
+
+ log->Printf("%s%s", prefix, str);
+
+ free(alloc);
}
+
+void ASTDumper::ToStream(lldb::StreamSP &stream) { stream->PutCString(m_dump); }
diff --git a/source/Plugins/ExpressionParser/Clang/ASTDumper.h b/source/Plugins/ExpressionParser/Clang/ASTDumper.h
index c8dc6847d6c2..9a72fb64e537 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTDumper.h
+++ b/source/Plugins/ExpressionParser/Clang/ASTDumper.h
@@ -16,25 +16,24 @@
#include "lldb/Core/Stream.h"
#include "llvm/ADT/DenseSet.h"
-namespace lldb_private
-{
-
-class ASTDumper
-{
+namespace lldb_private {
+
+class ASTDumper {
public:
- ASTDumper (clang::Decl *decl);
- ASTDumper (clang::DeclContext *decl_ctx);
- ASTDumper (const clang::Type *type);
- ASTDumper (clang::QualType type);
- ASTDumper (lldb::opaque_compiler_type_t type);
- ASTDumper (const CompilerType &compiler_type);
-
- const char *GetCString();
- void ToSTDERR();
- void ToLog(Log *log, const char *prefix);
- void ToStream(lldb::StreamSP &stream);
+ ASTDumper(clang::Decl *decl);
+ ASTDumper(clang::DeclContext *decl_ctx);
+ ASTDumper(const clang::Type *type);
+ ASTDumper(clang::QualType type);
+ ASTDumper(lldb::opaque_compiler_type_t type);
+ ASTDumper(const CompilerType &compiler_type);
+
+ const char *GetCString();
+ void ToSTDERR();
+ void ToLog(Log *log, const char *prefix);
+ void ToStream(lldb::StreamSP &stream);
+
private:
- std::string m_dump;
+ std::string m_dump;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index f1231572e263..f8539379f7da 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -33,542 +33,485 @@ using namespace llvm;
using namespace clang;
using namespace lldb_private;
-ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough, bool top_level, Target &target)
- : m_ast_context(NULL),
- m_passthrough(passthrough),
- m_passthrough_sema(NULL),
- m_target(target),
- m_sema(NULL),
- m_top_level(top_level)
-{
- if (!m_passthrough)
- return;
-
- m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
+ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
+ bool top_level, Target &target)
+ : m_ast_context(NULL), m_passthrough(passthrough), m_passthrough_sema(NULL),
+ m_target(target), m_sema(NULL), m_top_level(top_level) {
+ if (!m_passthrough)
+ return;
+
+ m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
-ASTResultSynthesizer::~ASTResultSynthesizer()
-{
-}
+ASTResultSynthesizer::~ASTResultSynthesizer() {}
-void
-ASTResultSynthesizer::Initialize(ASTContext &Context)
-{
- m_ast_context = &Context;
+void ASTResultSynthesizer::Initialize(ASTContext &Context) {
+ m_ast_context = &Context;
- if (m_passthrough)
- m_passthrough->Initialize(Context);
+ if (m_passthrough)
+ m_passthrough->Initialize(Context);
}
-void
-ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D))
- {
- if (log && log->GetVerbose())
- {
- if (named_decl->getIdentifier())
- log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart());
- else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
- log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str());
- else
- log->Printf("TransformTopLevelDecl(<complex>)");
- }
-
- if (m_top_level)
- {
- RecordPersistentDecl(named_decl);
- }
+void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) {
+ if (log && log->GetVerbose()) {
+ if (named_decl->getIdentifier())
+ log->Printf("TransformTopLevelDecl(%s)",
+ named_decl->getIdentifier()->getNameStart());
+ else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
+ log->Printf("TransformTopLevelDecl(%s)",
+ method_decl->getSelector().getAsString().c_str());
+ else
+ log->Printf("TransformTopLevelDecl(<complex>)");
+ }
+
+ if (m_top_level) {
+ RecordPersistentDecl(named_decl);
}
+ }
- if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
- {
- RecordDecl::decl_iterator decl_iterator;
+ if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D)) {
+ RecordDecl::decl_iterator decl_iterator;
- for (decl_iterator = linkage_spec_decl->decls_begin();
- decl_iterator != linkage_spec_decl->decls_end();
- ++decl_iterator)
- {
- TransformTopLevelDecl(*decl_iterator);
- }
+ for (decl_iterator = linkage_spec_decl->decls_begin();
+ decl_iterator != linkage_spec_decl->decls_end(); ++decl_iterator) {
+ TransformTopLevelDecl(*decl_iterator);
}
- else if (!m_top_level)
- {
- if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
- {
- if (m_ast_context && !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
- {
- RecordPersistentTypes(method_decl);
- SynthesizeObjCMethodResult(method_decl);
- }
- }
- else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
- {
- if (m_ast_context && !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
- {
- RecordPersistentTypes(function_decl);
- SynthesizeFunctionResult(function_decl);
- }
- }
+ } else if (!m_top_level) {
+ if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) {
+ if (m_ast_context &&
+ !method_decl->getSelector().getAsString().compare("$__lldb_expr:")) {
+ RecordPersistentTypes(method_decl);
+ SynthesizeObjCMethodResult(method_decl);
+ }
+ } else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D)) {
+ if (m_ast_context &&
+ !function_decl->getNameInfo().getAsString().compare("$__lldb_expr")) {
+ RecordPersistentTypes(function_decl);
+ SynthesizeFunctionResult(function_decl);
+ }
}
+ }
}
-bool
-ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D)
-{
- DeclGroupRef::iterator decl_iterator;
+bool ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) {
+ DeclGroupRef::iterator decl_iterator;
- for (decl_iterator = D.begin();
- decl_iterator != D.end();
- ++decl_iterator)
- {
- Decl *decl = *decl_iterator;
+ for (decl_iterator = D.begin(); decl_iterator != D.end(); ++decl_iterator) {
+ Decl *decl = *decl_iterator;
- TransformTopLevelDecl(decl);
- }
+ TransformTopLevelDecl(decl);
+ }
- if (m_passthrough)
- return m_passthrough->HandleTopLevelDecl(D);
- return true;
+ if (m_passthrough)
+ return m_passthrough->HandleTopLevelDecl(D);
+ return true;
}
-bool
-ASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!m_sema)
- return false;
+ if (!m_sema)
+ return false;
- FunctionDecl *function_decl = FunDecl;
+ FunctionDecl *function_decl = FunDecl;
- if (!function_decl)
- return false;
+ if (!function_decl)
+ return false;
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- function_decl->print(os);
+ function_decl->print(os);
- os.flush();
+ os.flush();
- log->Printf ("Untransformed function AST:\n%s", s.c_str());
- }
+ log->Printf("Untransformed function AST:\n%s", s.c_str());
+ }
- Stmt *function_body = function_decl->getBody();
- CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
+ Stmt *function_body = function_decl->getBody();
+ CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
- bool ret = SynthesizeBodyResult (compound_stmt,
- function_decl);
+ bool ret = SynthesizeBodyResult(compound_stmt, function_decl);
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- function_decl->print(os);
+ function_decl->print(os);
- os.flush();
+ os.flush();
- log->Printf ("Transformed function AST:\n%s", s.c_str());
- }
+ log->Printf("Transformed function AST:\n%s", s.c_str());
+ }
- return ret;
+ return ret;
}
-bool
-ASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ASTResultSynthesizer::SynthesizeObjCMethodResult(
+ ObjCMethodDecl *MethodDecl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!m_sema)
- return false;
+ if (!m_sema)
+ return false;
- if (!MethodDecl)
- return false;
+ if (!MethodDecl)
+ return false;
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- MethodDecl->print(os);
+ MethodDecl->print(os);
- os.flush();
+ os.flush();
- log->Printf ("Untransformed method AST:\n%s", s.c_str());
- }
+ log->Printf("Untransformed method AST:\n%s", s.c_str());
+ }
- Stmt *method_body = MethodDecl->getBody();
+ Stmt *method_body = MethodDecl->getBody();
- if (!method_body)
- return false;
+ if (!method_body)
+ return false;
- CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
+ CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
- bool ret = SynthesizeBodyResult (compound_stmt,
- MethodDecl);
+ bool ret = SynthesizeBodyResult(compound_stmt, MethodDecl);
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- MethodDecl->print(os);
+ MethodDecl->print(os);
- os.flush();
+ os.flush();
- log->Printf("Transformed method AST:\n%s", s.c_str());
- }
+ log->Printf("Transformed method AST:\n%s", s.c_str());
+ }
- return ret;
+ return ret;
}
-bool
-ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
- DeclContext *DC)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- ASTContext &Ctx(*m_ast_context);
-
- if (!Body)
- return false;
-
- if (Body->body_empty())
- return false;
-
- Stmt **last_stmt_ptr = Body->body_end() - 1;
- Stmt *last_stmt = *last_stmt_ptr;
-
- while (dyn_cast<NullStmt>(last_stmt))
- {
- if (last_stmt_ptr != Body->body_begin())
- {
- last_stmt_ptr--;
- last_stmt = *last_stmt_ptr;
- }
- else
- {
- return false;
- }
- }
+bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
+ DeclContext *DC) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ ASTContext &Ctx(*m_ast_context);
+
+ if (!Body)
+ return false;
+
+ if (Body->body_empty())
+ return false;
+
+ Stmt **last_stmt_ptr = Body->body_end() - 1;
+ Stmt *last_stmt = *last_stmt_ptr;
- Expr *last_expr = dyn_cast<Expr>(last_stmt);
-
- if (!last_expr)
- // No auxiliary variable necessary; expression returns void
- return true;
-
- // In C++11, last_expr can be a LValueToRvalue implicit cast. Strip that off if that's the
- // case.
-
- do {
- ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
-
- if (!implicit_cast)
- break;
-
- if (implicit_cast->getCastKind() != CK_LValueToRValue)
- break;
-
- last_expr = implicit_cast->getSubExpr();
- } while (0);
-
- // is_lvalue is used to record whether the expression returns an assignable Lvalue or an
- // Rvalue. This is relevant because they are handled differently.
- //
- // For Lvalues
- //
- // - In AST result synthesis (here!) the expression E is transformed into an initialization
- // T *$__lldb_expr_result_ptr = &E.
- //
- // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
- // passed into the expression.
- //
- // - In IR transformations, reads and writes to $__lldb_expr_result_ptr are redirected at
- // an entry in the struct ($__lldb_arg) passed into the expression. (Other persistent
- // variables are treated similarly, having been materialized as references, but in those
- // cases the value of the reference itself is never modified.)
- //
- // - During materialization, $0 (the result persistent variable) is ignored.
- //
- // - During dematerialization, $0 is marked up as a load address with value equal to the
- // contents of the structure entry.
- //
- // For Rvalues
- //
- // - In AST result synthesis the expression E is transformed into an initialization
- // static T $__lldb_expr_result = E.
- //
- // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
- // passed into the expression.
- //
- // - In IR transformations, an instruction is inserted at the beginning of the function to
- // dereference the pointer resident in the slot. Reads and writes to $__lldb_expr_result
- // are redirected at that dereferenced version. Guard variables for the static variable
- // are excised.
- //
- // - During materialization, $0 (the result persistent variable) is populated with the location
- // of a newly-allocated area of memory.
- //
- // - During dematerialization, $0 is ignored.
-
- bool is_lvalue =
- (last_expr->getValueKind() == VK_LValue || last_expr->getValueKind() == VK_XValue) &&
- (last_expr->getObjectKind() == OK_Ordinary);
-
- QualType expr_qual_type = last_expr->getType();
- const clang::Type *expr_type = expr_qual_type.getTypePtr();
-
- if (!expr_type)
- return false;
-
- if (expr_type->isVoidType())
- return true;
-
- if (log)
- {
- std::string s = expr_qual_type.getAsString();
-
- log->Printf("Last statement is an %s with type: %s", (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
+ while (dyn_cast<NullStmt>(last_stmt)) {
+ if (last_stmt_ptr != Body->body_begin()) {
+ last_stmt_ptr--;
+ last_stmt = *last_stmt_ptr;
+ } else {
+ return false;
}
+ }
- clang::VarDecl *result_decl = NULL;
+ Expr *last_expr = dyn_cast<Expr>(last_stmt);
- if (is_lvalue)
- {
- IdentifierInfo *result_ptr_id;
+ if (!last_expr)
+ // No auxiliary variable necessary; expression returns void
+ return true;
- if (expr_type->isFunctionType())
- result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should be treated like function pointers
- else
- result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
+ // In C++11, last_expr can be a LValueToRvalue implicit cast. Strip that off
+ // if that's the
+ // case.
+
+ do {
+ ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
+
+ if (!implicit_cast)
+ break;
+
+ if (implicit_cast->getCastKind() != CK_LValueToRValue)
+ break;
+
+ last_expr = implicit_cast->getSubExpr();
+ } while (0);
+
+ // is_lvalue is used to record whether the expression returns an assignable
+ // Lvalue or an
+ // Rvalue. This is relevant because they are handled differently.
+ //
+ // For Lvalues
+ //
+ // - In AST result synthesis (here!) the expression E is transformed into an
+ // initialization
+ // T *$__lldb_expr_result_ptr = &E.
+ //
+ // - In structure allocation, a pointer-sized slot is allocated in the
+ // struct that is to be
+ // passed into the expression.
+ //
+ // - In IR transformations, reads and writes to $__lldb_expr_result_ptr are
+ // redirected at
+ // an entry in the struct ($__lldb_arg) passed into the expression.
+ // (Other persistent
+ // variables are treated similarly, having been materialized as
+ // references, but in those
+ // cases the value of the reference itself is never modified.)
+ //
+ // - During materialization, $0 (the result persistent variable) is ignored.
+ //
+ // - During dematerialization, $0 is marked up as a load address with value
+ // equal to the
+ // contents of the structure entry.
+ //
+ // For Rvalues
+ //
+ // - In AST result synthesis the expression E is transformed into an
+ // initialization
+ // static T $__lldb_expr_result = E.
+ //
+ // - In structure allocation, a pointer-sized slot is allocated in the
+ // struct that is to be
+ // passed into the expression.
+ //
+ // - In IR transformations, an instruction is inserted at the beginning of
+ // the function to
+ // dereference the pointer resident in the slot. Reads and writes to
+ // $__lldb_expr_result
+ // are redirected at that dereferenced version. Guard variables for the
+ // static variable
+ // are excised.
+ //
+ // - During materialization, $0 (the result persistent variable) is
+ // populated with the location
+ // of a newly-allocated area of memory.
+ //
+ // - During dematerialization, $0 is ignored.
+
+ bool is_lvalue = (last_expr->getValueKind() == VK_LValue ||
+ last_expr->getValueKind() == VK_XValue) &&
+ (last_expr->getObjectKind() == OK_Ordinary);
+
+ QualType expr_qual_type = last_expr->getType();
+ const clang::Type *expr_type = expr_qual_type.getTypePtr();
+
+ if (!expr_type)
+ return false;
+
+ if (expr_type->isVoidType())
+ return true;
- m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type);
+ if (log) {
+ std::string s = expr_qual_type.getAsString();
- QualType ptr_qual_type;
+ log->Printf("Last statement is an %s with type: %s",
+ (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
+ }
- if (expr_qual_type->getAs<ObjCObjectType>() != NULL)
- ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
- else
- ptr_qual_type = Ctx.getPointerType(expr_qual_type);
+ clang::VarDecl *result_decl = NULL;
- result_decl = VarDecl::Create(Ctx,
- DC,
- SourceLocation(),
- SourceLocation(),
- result_ptr_id,
- ptr_qual_type,
- NULL,
- SC_Static);
+ if (is_lvalue) {
+ IdentifierInfo *result_ptr_id;
- if (!result_decl)
- return false;
+ if (expr_type->isFunctionType())
+ result_ptr_id =
+ &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should
+ // be treated like function
+ // pointers
+ else
+ result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
- ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
- if (address_of_expr.get())
- m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
- else
- return false;
- }
+ m_sema->RequireCompleteType(SourceLocation(), expr_qual_type,
+ clang::diag::err_incomplete_type);
+
+ QualType ptr_qual_type;
+
+ if (expr_qual_type->getAs<ObjCObjectType>() != NULL)
+ ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
else
- {
- IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
-
- result_decl = VarDecl::Create(Ctx,
- DC,
- SourceLocation(),
- SourceLocation(),
- &result_id,
- expr_qual_type,
- NULL,
- SC_Static);
-
- if (!result_decl)
- return false;
-
- m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
- }
+ ptr_qual_type = Ctx.getPointerType(expr_qual_type);
+
+ result_decl =
+ VarDecl::Create(Ctx, DC, SourceLocation(), SourceLocation(),
+ result_ptr_id, ptr_qual_type, NULL, SC_Static);
- DC->addDecl(result_decl);
+ if (!result_decl)
+ return false;
- ///////////////////////////////
- // call AddInitializerToDecl
- //
+ ExprResult address_of_expr =
+ m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
+ if (address_of_expr.get())
+ m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true,
+ false);
+ else
+ return false;
+ } else {
+ IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
- //m_sema->AddInitializerToDecl(result_decl, last_expr);
+ result_decl = VarDecl::Create(Ctx, DC, SourceLocation(), SourceLocation(),
+ &result_id, expr_qual_type, NULL, SC_Static);
- /////////////////////////////////
- // call ConvertDeclToDeclGroup
- //
+ if (!result_decl)
+ return false;
- Sema::DeclGroupPtrTy result_decl_group_ptr;
+ m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
+ }
- result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
+ DC->addDecl(result_decl);
- ////////////////////////
- // call ActOnDeclStmt
- //
+ ///////////////////////////////
+ // call AddInitializerToDecl
+ //
- StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr,
- SourceLocation(),
- SourceLocation()));
+ // m_sema->AddInitializerToDecl(result_decl, last_expr);
- ////////////////////////////////////////////////
- // replace the old statement with the new one
- //
+ /////////////////////////////////
+ // call ConvertDeclToDeclGroup
+ //
- *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.get());
+ Sema::DeclGroupPtrTy result_decl_group_ptr;
- return true;
+ result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
+
+ ////////////////////////
+ // call ActOnDeclStmt
+ //
+
+ StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(
+ result_decl_group_ptr, SourceLocation(), SourceLocation()));
+
+ ////////////////////////////////////////////////
+ // replace the old statement with the new one
+ //
+
+ *last_stmt_ptr =
+ reinterpret_cast<Stmt *>(result_initialization_stmt_result.get());
+
+ return true;
}
-void
-ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx)
-{
- if (m_passthrough)
- m_passthrough->HandleTranslationUnit(Ctx);
+void ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) {
+ if (m_passthrough)
+ m_passthrough->HandleTranslationUnit(Ctx);
}
-void
-ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
-{
- typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
-
- for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
- e = TypeDeclIterator(FunDeclCtx->decls_end());
- i != e;
- ++i)
- {
- MaybeRecordPersistentType(*i);
- }
+void ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx) {
+ typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
+
+ for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
+ e = TypeDeclIterator(FunDeclCtx->decls_end());
+ i != e; ++i) {
+ MaybeRecordPersistentType(*i);
+ }
}
-void
-ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
-{
- if (!D->getIdentifier())
- return;
+void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) {
+ if (!D->getIdentifier())
+ return;
- StringRef name = D->getName();
+ StringRef name = D->getName();
- if (name.size() == 0 || name[0] != '$')
- return;
+ if (name.size() == 0 || name[0] != '$')
+ return;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- ConstString name_cs(name.str().c_str());
+ ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent type %s\n", name_cs.GetCString());
+ if (log)
+ log->Printf("Recording persistent type %s\n", name_cs.GetCString());
- m_decls.push_back(D);
+ m_decls.push_back(D);
}
-void
-ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D)
-{
- lldbassert(m_top_level);
+void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) {
+ lldbassert(m_top_level);
- if (!D->getIdentifier())
- return;
+ if (!D->getIdentifier())
+ return;
- StringRef name = D->getName();
+ StringRef name = D->getName();
- if (name.size() == 0)
- return;
+ if (name.size() == 0)
+ return;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- ConstString name_cs(name.str().c_str());
+ ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
+ if (log)
+ log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
- m_decls.push_back(D);
+ m_decls.push_back(D);
}
-void
-ASTResultSynthesizer::CommitPersistentDecls()
-{
- for (clang::NamedDecl *decl : m_decls)
- {
- StringRef name = decl->getName();
- ConstString name_cs(name.str().c_str());
-
- Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
- m_target.GetScratchClangASTContext()->getASTContext(), m_ast_context, decl);
-
- if (!D_scratch)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- if (log)
- {
- std::string s;
- llvm::raw_string_ostream ss(s);
- decl->dump(ss);
- ss.flush();
-
- log->Printf("Couldn't commit persistent decl: %s\n", s.c_str());
- }
-
- continue;
- }
-
- if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch))
- llvm::cast<ClangPersistentVariables>(m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
- ->RegisterPersistentDecl(name_cs, NamedDecl_scratch);
+void ASTResultSynthesizer::CommitPersistentDecls() {
+ for (clang::NamedDecl *decl : m_decls) {
+ StringRef name = decl->getName();
+ ConstString name_cs(name.str().c_str());
+
+ Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
+ m_target.GetScratchClangASTContext()->getASTContext(), m_ast_context,
+ decl);
+
+ if (!D_scratch) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ std::string s;
+ llvm::raw_string_ostream ss(s);
+ decl->dump(ss);
+ ss.flush();
+
+ log->Printf("Couldn't commit persistent decl: %s\n", s.c_str());
+ }
+
+ continue;
}
+
+ if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch))
+ llvm::cast<ClangPersistentVariables>(
+ m_target.GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC))
+ ->RegisterPersistentDecl(name_cs, NamedDecl_scratch);
+ }
}
-void
-ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
-{
- if (m_passthrough)
- m_passthrough->HandleTagDeclDefinition(D);
+void ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) {
+ if (m_passthrough)
+ m_passthrough->HandleTagDeclDefinition(D);
}
-void
-ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
-{
- if (m_passthrough)
- m_passthrough->CompleteTentativeDefinition(D);
+void ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) {
+ if (m_passthrough)
+ m_passthrough->CompleteTentativeDefinition(D);
}
-void
-ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD)
-{
- if (m_passthrough)
- m_passthrough->HandleVTable(RD);
+void ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD) {
+ if (m_passthrough)
+ m_passthrough->HandleVTable(RD);
}
-void
-ASTResultSynthesizer::PrintStats()
-{
- if (m_passthrough)
- m_passthrough->PrintStats();
+void ASTResultSynthesizer::PrintStats() {
+ if (m_passthrough)
+ m_passthrough->PrintStats();
}
-void
-ASTResultSynthesizer::InitializeSema(Sema &S)
-{
- m_sema = &S;
+void ASTResultSynthesizer::InitializeSema(Sema &S) {
+ m_sema = &S;
- if (m_passthrough_sema)
- m_passthrough_sema->InitializeSema(S);
+ if (m_passthrough_sema)
+ m_passthrough_sema->InitializeSema(S);
}
-void
-ASTResultSynthesizer::ForgetSema()
-{
- m_sema = NULL;
+void ASTResultSynthesizer::ForgetSema() {
+ m_sema = NULL;
- if (m_passthrough_sema)
- m_passthrough_sema->ForgetSema();
+ if (m_passthrough_sema)
+ m_passthrough_sema->ForgetSema();
}
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
index 4556713e9933..c0e6c0358a23 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
@@ -10,201 +10,204 @@
#ifndef liblldb_ASTResultSynthesizer_h_
#define liblldb_ASTResultSynthesizer_h_
-#include "clang/Sema/SemaConsumer.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Target/Target.h"
+#include "clang/Sema/SemaConsumer.h"
namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ASTResultSynthesizer ASTResultSynthesizer.h "lldb/Expression/ASTResultSynthesizer.h"
+/// @class ASTResultSynthesizer ASTResultSynthesizer.h
+/// "lldb/Expression/ASTResultSynthesizer.h"
/// @brief Adds a result variable declaration to the ASTs for an expression.
///
/// Users expect the expression "i + 3" to return a result, even if a result
-/// variable wasn't specifically declared. To fulfil this requirement, LLDB adds
-/// a result variable to the expression, transforming it to
+/// variable wasn't specifically declared. To fulfil this requirement, LLDB
+/// adds
+/// a result variable to the expression, transforming it to
/// "int $__lldb_expr_result = i + 3." The IR transformers ensure that the
/// resulting variable is mapped to the right piece of memory.
/// ASTResultSynthesizer's job is to add the variable and its initialization to
/// the ASTs for the expression, and it does so by acting as a SemaConsumer for
/// Clang.
//----------------------------------------------------------------------
-class ASTResultSynthesizer : public clang::SemaConsumer
-{
+class ASTResultSynthesizer : public clang::SemaConsumer {
public:
- //----------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] passthrough
- /// Since the ASTs must typically go through to the Clang code generator
- /// in order to produce LLVM IR, this SemaConsumer must allow them to
- /// pass to the next step in the chain after processing. Passthrough is
- /// the next ASTConsumer, or NULL if none is required.
- ///
- /// @param[in] top_level
- /// If true, register all top-level Decls and don't try to handle the
- /// main function.
- ///
- /// @param[in] target
- /// The target, which contains the persistent variable store and the
- /// AST importer.
- //----------------------------------------------------------------------
- ASTResultSynthesizer(clang::ASTConsumer *passthrough, bool top_level, Target &target);
-
- //----------------------------------------------------------------------
- /// Destructor
- //----------------------------------------------------------------------
- ~ASTResultSynthesizer() override;
-
- //----------------------------------------------------------------------
- /// Link this consumer with a particular AST context
- ///
- /// @param[in] Context
- /// This AST context will be used for types and identifiers, and also
- /// forwarded to the passthrough consumer, if one exists.
- //----------------------------------------------------------------------
- void Initialize(clang::ASTContext &Context) override;
-
- //----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
- ///
- /// @param[in] D
- /// The list of Decls to search. These may contain LinkageSpecDecls,
- /// which need to be searched recursively. That job falls to
- /// TransformTopLevelDecl.
- //----------------------------------------------------------------------
- bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTranslationUnit(clang::ASTContext &Ctx) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTagDeclDefinition(clang::TagDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void CompleteTentativeDefinition(clang::VarDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void PrintStats() override;
-
- //----------------------------------------------------------------------
- /// Set the Sema object to use when performing transforms, and pass it on
- ///
- /// @param[in] S
- /// The Sema to use. Because Sema isn't externally visible, this class
- /// casts it to an Action for actual use.
- //----------------------------------------------------------------------
- void InitializeSema(clang::Sema &S) override;
-
- //----------------------------------------------------------------------
- /// Reset the Sema to NULL now that transformations are done
- //----------------------------------------------------------------------
- void
- ForgetSema() override;
-
- //----------------------------------------------------------------------
- /// The parse has succeeded, so record its persistent decls
- //----------------------------------------------------------------------
- void
- CommitPersistentDecls();
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] top_level
+ /// If true, register all top-level Decls and don't try to handle the
+ /// main function.
+ ///
+ /// @param[in] target
+ /// The target, which contains the persistent variable store and the
+ /// AST importer.
+ //----------------------------------------------------------------------
+ ASTResultSynthesizer(clang::ASTConsumer *passthrough, bool top_level,
+ Target &target);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ ~ASTResultSynthesizer() override;
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context) override;
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats() override;
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S) override;
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema() override;
+
+ //----------------------------------------------------------------------
+ /// The parse has succeeded, so record its persistent decls
+ //----------------------------------------------------------------------
+ void CommitPersistentDecls();
private:
- //----------------------------------------------------------------------
- /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
- /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
- /// anything that was found
- ///
- /// @param[in] D
- /// The Decl to hunt.
- //----------------------------------------------------------------------
- void TransformTopLevelDecl(clang::Decl *D);
-
- //----------------------------------------------------------------------
- /// Process an Objective-C method and produce the result variable and
- /// initialization
- ///
- /// @param[in] MethodDecl
- /// The method to process.
- //----------------------------------------------------------------------
- bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
-
- //----------------------------------------------------------------------
- /// Process a function and produce the result variable and initialization
- ///
- /// @param[in] FunDecl
- /// The function to process.
- //----------------------------------------------------------------------
- bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
-
- //----------------------------------------------------------------------
- /// Process a function body and produce the result variable and
- /// initialization
- ///
- /// @param[in] Body
- /// The body of the function.
- ///
- /// @param[in] DC
- /// The DeclContext of the function, into which the result variable
- /// is inserted.
- //----------------------------------------------------------------------
- bool SynthesizeBodyResult(clang::CompoundStmt *Body,
- clang::DeclContext *DC);
-
- //----------------------------------------------------------------------
- /// Given a DeclContext for a function or method, find all types
- /// declared in the context and record any persistent types found.
- ///
- /// @param[in] FunDeclCtx
- /// The context for the function to process.
- //----------------------------------------------------------------------
- void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
-
- //----------------------------------------------------------------------
- /// Given a TypeDecl, if it declares a type whose name starts with a
- /// dollar sign, register it as a pointer type in the target's scratch
- /// AST context.
- ///
- /// @param[in] Body
- /// The body of the function.
- //----------------------------------------------------------------------
- void
- MaybeRecordPersistentType(clang::TypeDecl *D);
-
- //----------------------------------------------------------------------
- /// Given a NamedDecl, register it as a pointer type in the target's scratch
- /// AST context.
- ///
- /// @param[in] Body
- /// The body of the function.
- //----------------------------------------------------------------------
- void
- RecordPersistentDecl(clang::NamedDecl *D);
-
- clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
- clang::ASTConsumer
- *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
- clang::SemaConsumer
- *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
-
- std::vector<clang::NamedDecl *> m_decls; ///< Persistent declarations to register assuming the expression succeeds.
-
- Target &m_target; ///< The target, which contains the persistent variable store and the
- clang::Sema *m_sema; ///< The Sema to use.
- bool m_top_level;
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
+ /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
+ /// anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void TransformTopLevelDecl(clang::Decl *D);
+
+ //----------------------------------------------------------------------
+ /// Process an Objective-C method and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] MethodDecl
+ /// The method to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function and produce the result variable and initialization
+ ///
+ /// @param[in] FunDecl
+ /// The function to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function body and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ ///
+ /// @param[in] DC
+ /// The DeclContext of the function, into which the result variable
+ /// is inserted.
+ //----------------------------------------------------------------------
+ bool SynthesizeBodyResult(clang::CompoundStmt *Body, clang::DeclContext *DC);
+
+ //----------------------------------------------------------------------
+ /// Given a DeclContext for a function or method, find all types
+ /// declared in the context and record any persistent types found.
+ ///
+ /// @param[in] FunDeclCtx
+ /// The context for the function to process.
+ //----------------------------------------------------------------------
+ void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
+
+ //----------------------------------------------------------------------
+ /// Given a TypeDecl, if it declares a type whose name starts with a
+ /// dollar sign, register it as a pointer type in the target's scratch
+ /// AST context.
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ //----------------------------------------------------------------------
+ void MaybeRecordPersistentType(clang::TypeDecl *D);
+
+ //----------------------------------------------------------------------
+ /// Given a NamedDecl, register it as a pointer type in the target's scratch
+ /// AST context.
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ //----------------------------------------------------------------------
+ void RecordPersistentDecl(clang::NamedDecl *D);
+
+ clang::ASTContext
+ *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for
+ ///passthrough. NULL if it's a
+ ///SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain,
+ ///for passthrough. NULL if it's an
+ ///ASTConsumer.
+
+ std::vector<clang::NamedDecl *> m_decls; ///< Persistent declarations to
+ ///register assuming the expression
+ ///succeeds.
+
+ Target &m_target; ///< The target, which contains the persistent variable
+ ///store and the
+ clang::Sema *m_sema; ///< The Sema to use.
+ bool m_top_level;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
index 38a2b6b33a8a..7bb784e8f9ad 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
@@ -9,6 +9,7 @@
#include "ASTStructExtractor.h"
+#include "lldb/Core/Log.h"
#include "stdlib.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -21,7 +22,6 @@
#include "clang/Sema/Sema.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
-#include "lldb/Core/Log.h"
using namespace llvm;
using namespace clang;
@@ -29,193 +29,158 @@ using namespace lldb_private;
ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,
const char *struct_name,
- ClangFunctionCaller &function) :
- m_ast_context (NULL),
- m_passthrough (passthrough),
- m_passthrough_sema (NULL),
- m_sema (NULL),
- m_action (NULL),
- m_function (function),
- m_struct_name (struct_name)
-{
- if (!m_passthrough)
- return;
-
- m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
+ ClangFunctionCaller &function)
+ : m_ast_context(NULL), m_passthrough(passthrough), m_passthrough_sema(NULL),
+ m_sema(NULL), m_action(NULL), m_function(function),
+ m_struct_name(struct_name) {
+ if (!m_passthrough)
+ return;
+
+ m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
-ASTStructExtractor::~ASTStructExtractor()
-{
-}
+ASTStructExtractor::~ASTStructExtractor() {}
-void
-ASTStructExtractor::Initialize(ASTContext &Context)
-{
- m_ast_context = &Context;
+void ASTStructExtractor::Initialize(ASTContext &Context) {
+ m_ast_context = &Context;
- if (m_passthrough)
- m_passthrough->Initialize(Context);
+ if (m_passthrough)
+ m_passthrough->Initialize(Context);
}
-void
-ASTStructExtractor::ExtractFromFunctionDecl(FunctionDecl *F)
-{
- if (!F->hasBody())
- return;
-
- Stmt *body_stmt = F->getBody();
- CompoundStmt *body_compound_stmt = dyn_cast<CompoundStmt>(body_stmt);
-
- if (!body_compound_stmt)
- return; // do we have to handle this?
-
- RecordDecl *struct_decl = NULL;
-
- StringRef desired_name(m_struct_name.c_str());
-
- for (CompoundStmt::const_body_iterator bi = body_compound_stmt->body_begin(), be = body_compound_stmt->body_end();
- bi != be;
- ++bi)
- {
- Stmt *curr_stmt = *bi;
- DeclStmt *curr_decl_stmt = dyn_cast<DeclStmt>(curr_stmt);
- if (!curr_decl_stmt)
- continue;
- DeclGroupRef decl_group = curr_decl_stmt->getDeclGroup();
- for (Decl *candidate_decl : decl_group)
- {
- RecordDecl *candidate_record_decl = dyn_cast<RecordDecl>(candidate_decl);
- if (!candidate_record_decl)
- continue;
- if (candidate_record_decl->getName() == desired_name)
- {
- struct_decl = candidate_record_decl;
- break;
- }
- }
- if (struct_decl)
- break;
+void ASTStructExtractor::ExtractFromFunctionDecl(FunctionDecl *F) {
+ if (!F->hasBody())
+ return;
+
+ Stmt *body_stmt = F->getBody();
+ CompoundStmt *body_compound_stmt = dyn_cast<CompoundStmt>(body_stmt);
+
+ if (!body_compound_stmt)
+ return; // do we have to handle this?
+
+ RecordDecl *struct_decl = NULL;
+
+ StringRef desired_name(m_struct_name);
+
+ for (CompoundStmt::const_body_iterator bi = body_compound_stmt->body_begin(),
+ be = body_compound_stmt->body_end();
+ bi != be; ++bi) {
+ Stmt *curr_stmt = *bi;
+ DeclStmt *curr_decl_stmt = dyn_cast<DeclStmt>(curr_stmt);
+ if (!curr_decl_stmt)
+ continue;
+ DeclGroupRef decl_group = curr_decl_stmt->getDeclGroup();
+ for (Decl *candidate_decl : decl_group) {
+ RecordDecl *candidate_record_decl = dyn_cast<RecordDecl>(candidate_decl);
+ if (!candidate_record_decl)
+ continue;
+ if (candidate_record_decl->getName() == desired_name) {
+ struct_decl = candidate_record_decl;
+ break;
+ }
}
+ if (struct_decl)
+ break;
+ }
+
+ if (!struct_decl)
+ return;
+
+ const ASTRecordLayout *struct_layout(
+ &m_ast_context->getASTRecordLayout(struct_decl));
+
+ if (!struct_layout)
+ return;
+
+ m_function.m_struct_size =
+ struct_layout->getSize()
+ .getQuantity(); // TODO Store m_struct_size as CharUnits
+ m_function.m_return_offset =
+ struct_layout->getFieldOffset(struct_layout->getFieldCount() - 1) / 8;
+ m_function.m_return_size =
+ struct_layout->getDataSize().getQuantity() - m_function.m_return_offset;
+
+ for (unsigned field_index = 0, num_fields = struct_layout->getFieldCount();
+ field_index < num_fields; ++field_index) {
+ m_function.m_member_offsets.push_back(
+ struct_layout->getFieldOffset(field_index) / 8);
+ }
+
+ m_function.m_struct_valid = true;
+}
- if (!struct_decl)
- return;
-
- const ASTRecordLayout* struct_layout(&m_ast_context->getASTRecordLayout (struct_decl));
-
- if (!struct_layout)
- return;
-
- m_function.m_struct_size = struct_layout->getSize().getQuantity(); // TODO Store m_struct_size as CharUnits
- m_function.m_return_offset = struct_layout->getFieldOffset(struct_layout->getFieldCount() - 1) / 8;
- m_function.m_return_size = struct_layout->getDataSize().getQuantity() - m_function.m_return_offset;
-
- for (unsigned field_index = 0, num_fields = struct_layout->getFieldCount();
- field_index < num_fields;
- ++field_index)
- {
- m_function.m_member_offsets.push_back(struct_layout->getFieldOffset(field_index) / 8);
- }
+void ASTStructExtractor::ExtractFromTopLevelDecl(Decl *D) {
+ LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D);
- m_function.m_struct_valid = true;
-}
+ if (linkage_spec_decl) {
+ RecordDecl::decl_iterator decl_iterator;
-void
-ASTStructExtractor::ExtractFromTopLevelDecl(Decl* D)
-{
- LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D);
-
- if (linkage_spec_decl)
- {
- RecordDecl::decl_iterator decl_iterator;
-
- for (decl_iterator = linkage_spec_decl->decls_begin();
- decl_iterator != linkage_spec_decl->decls_end();
- ++decl_iterator)
- {
- ExtractFromTopLevelDecl(*decl_iterator);
- }
+ for (decl_iterator = linkage_spec_decl->decls_begin();
+ decl_iterator != linkage_spec_decl->decls_end(); ++decl_iterator) {
+ ExtractFromTopLevelDecl(*decl_iterator);
}
+ }
- FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);
+ FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);
- if (m_ast_context &&
- function_decl &&
- !m_function.m_wrapper_function_name.compare(function_decl->getNameAsString().c_str()))
- {
- ExtractFromFunctionDecl(function_decl);
- }
+ if (m_ast_context && function_decl &&
+ !m_function.m_wrapper_function_name.compare(
+ function_decl->getNameAsString())) {
+ ExtractFromFunctionDecl(function_decl);
+ }
}
-bool
-ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D)
-{
- DeclGroupRef::iterator decl_iterator;
+bool ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D) {
+ DeclGroupRef::iterator decl_iterator;
- for (decl_iterator = D.begin();
- decl_iterator != D.end();
- ++decl_iterator)
- {
- Decl *decl = *decl_iterator;
+ for (decl_iterator = D.begin(); decl_iterator != D.end(); ++decl_iterator) {
+ Decl *decl = *decl_iterator;
- ExtractFromTopLevelDecl(decl);
- }
+ ExtractFromTopLevelDecl(decl);
+ }
- if (m_passthrough)
- return m_passthrough->HandleTopLevelDecl(D);
- return true;
+ if (m_passthrough)
+ return m_passthrough->HandleTopLevelDecl(D);
+ return true;
}
-void
-ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx)
-{
- if (m_passthrough)
- m_passthrough->HandleTranslationUnit(Ctx);
+void ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx) {
+ if (m_passthrough)
+ m_passthrough->HandleTranslationUnit(Ctx);
}
-void
-ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D)
-{
- if (m_passthrough)
- m_passthrough->HandleTagDeclDefinition(D);
+void ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D) {
+ if (m_passthrough)
+ m_passthrough->HandleTagDeclDefinition(D);
}
-void
-ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D)
-{
- if (m_passthrough)
- m_passthrough->CompleteTentativeDefinition(D);
+void ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D) {
+ if (m_passthrough)
+ m_passthrough->CompleteTentativeDefinition(D);
}
-void
-ASTStructExtractor::HandleVTable(CXXRecordDecl *RD)
-{
- if (m_passthrough)
- m_passthrough->HandleVTable(RD);
+void ASTStructExtractor::HandleVTable(CXXRecordDecl *RD) {
+ if (m_passthrough)
+ m_passthrough->HandleVTable(RD);
}
-void
-ASTStructExtractor::PrintStats()
-{
- if (m_passthrough)
- m_passthrough->PrintStats();
+void ASTStructExtractor::PrintStats() {
+ if (m_passthrough)
+ m_passthrough->PrintStats();
}
-void
-ASTStructExtractor::InitializeSema(Sema &S)
-{
- m_sema = &S;
- m_action = reinterpret_cast<Action*>(m_sema);
+void ASTStructExtractor::InitializeSema(Sema &S) {
+ m_sema = &S;
+ m_action = reinterpret_cast<Action *>(m_sema);
- if (m_passthrough_sema)
- m_passthrough_sema->InitializeSema(S);
+ if (m_passthrough_sema)
+ m_passthrough_sema->InitializeSema(S);
}
-void
-ASTStructExtractor::ForgetSema()
-{
- m_sema = NULL;
- m_action = NULL;
+void ASTStructExtractor::ForgetSema() {
+ m_sema = NULL;
+ m_action = NULL;
- if (m_passthrough_sema)
- m_passthrough_sema->ForgetSema();
+ if (m_passthrough_sema)
+ m_passthrough_sema->ForgetSema();
}
diff --git a/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h b/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
index 2152cff911ff..63e3161cae85 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
+++ b/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
@@ -13,16 +13,18 @@
#include "ClangExpressionVariable.h"
#include "ClangFunctionCaller.h"
-#include "clang/Sema/SemaConsumer.h"
#include "lldb/Core/ClangForward.h"
+#include "clang/Sema/SemaConsumer.h"
namespace lldb_private {
-
+
//----------------------------------------------------------------------
-/// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
+/// @class ASTStructExtractor ASTStructExtractor.h
+/// "lldb/Expression/ASTStructExtractor.h"
/// @brief Extracts and describes the argument structure for a wrapped function.
///
-/// This pass integrates with ClangFunctionCaller, which calls functions with custom
+/// This pass integrates with ClangFunctionCaller, which calls functions with
+/// custom
/// sets of arguments. To avoid having to implement the full calling convention
/// for the target's architecture, ClangFunctionCaller writes a simple wrapper
/// function that takes a pointer to an argument structure that contains room
@@ -33,126 +35,130 @@ namespace lldb_private {
/// so Clang does the structure layout itself. ASTStructExtractor reads through
/// the AST for the wrapper function and finds the struct.
//----------------------------------------------------------------------
-class ASTStructExtractor : public clang::SemaConsumer
-{
+class ASTStructExtractor : public clang::SemaConsumer {
public:
- //----------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] passthrough
- /// Since the ASTs must typically go through to the Clang code generator
- /// in order to produce LLVM IR, this SemaConsumer must allow them to
- /// pass to the next step in the chain after processing. Passthrough is
- /// the next ASTConsumer, or NULL if none is required.
- ///
- /// @param[in] struct_name
- /// The name of the structure to extract from the wrapper function.
- ///
- /// @param[in] function
- /// The caller object whose members should be populated with information
- /// about the argument struct. ClangFunctionCaller friends ASTStructExtractor
- /// for this purpose.
- //----------------------------------------------------------------------
- ASTStructExtractor(clang::ASTConsumer *passthrough,
- const char *struct_name,
- ClangFunctionCaller &function);
-
- //----------------------------------------------------------------------
- /// Destructor
- //----------------------------------------------------------------------
- ~ASTStructExtractor() override;
-
- //----------------------------------------------------------------------
- /// Link this consumer with a particular AST context
- ///
- /// @param[in] Context
- /// This AST context will be used for types and identifiers, and also
- /// forwarded to the passthrough consumer, if one exists.
- //----------------------------------------------------------------------
- void Initialize(clang::ASTContext &Context) override;
-
- //----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
- ///
- /// @param[in] D
- /// The list of Decls to search. These may contain LinkageSpecDecls,
- /// which need to be searched recursively. That job falls to
- /// TransformTopLevelDecl.
- //----------------------------------------------------------------------
- bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTranslationUnit(clang::ASTContext &Ctx) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTagDeclDefinition(clang::TagDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void CompleteTentativeDefinition(clang::VarDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void PrintStats() override;
-
- //----------------------------------------------------------------------
- /// Set the Sema object to use when performing transforms, and pass it on
- ///
- /// @param[in] S
- /// The Sema to use. Because Sema isn't externally visible, this class
- /// casts it to an Action for actual use.
- //----------------------------------------------------------------------
- void InitializeSema(clang::Sema &S) override;
-
- //----------------------------------------------------------------------
- /// Reset the Sema to NULL now that transformations are done
- //----------------------------------------------------------------------
- void ForgetSema() override;
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] struct_name
+ /// The name of the structure to extract from the wrapper function.
+ ///
+ /// @param[in] function
+ /// The caller object whose members should be populated with information
+ /// about the argument struct. ClangFunctionCaller friends
+ /// ASTStructExtractor
+ /// for this purpose.
+ //----------------------------------------------------------------------
+ ASTStructExtractor(clang::ASTConsumer *passthrough, const char *struct_name,
+ ClangFunctionCaller &function);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ ~ASTStructExtractor() override;
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context) override;
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats() override;
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S) override;
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema() override;
private:
- //----------------------------------------------------------------------
- /// Hunt the given FunctionDecl for the argument struct and place
- /// information about it into m_function
- ///
- /// @param[in] F
- /// The FunctionDecl to hunt.
- //----------------------------------------------------------------------
- void
- ExtractFromFunctionDecl(clang::FunctionDecl* F);
-
- //----------------------------------------------------------------------
- /// Hunt the given Decl for FunctionDecls named the same as the wrapper
- /// function name, recursing as necessary through LinkageSpecDecls, and
- /// calling ExtractFromFunctionDecl on anything that was found
- ///
- /// @param[in] D
- /// The Decl to hunt.
- //----------------------------------------------------------------------
- void
- ExtractFromTopLevelDecl(clang::Decl* D);
-
- clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
- clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
- clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
- clang::Sema *m_sema; ///< The Sema to use.
- clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable.
-
- ClangFunctionCaller &m_function; ///< The function to populate with information about the argument structure.
- std::string m_struct_name; ///< The name of the structure to extract.
+ //----------------------------------------------------------------------
+ /// Hunt the given FunctionDecl for the argument struct and place
+ /// information about it into m_function
+ ///
+ /// @param[in] F
+ /// The FunctionDecl to hunt.
+ //----------------------------------------------------------------------
+ void ExtractFromFunctionDecl(clang::FunctionDecl *F);
+
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named the same as the wrapper
+ /// function name, recursing as necessary through LinkageSpecDecls, and
+ /// calling ExtractFromFunctionDecl on anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void ExtractFromTopLevelDecl(clang::Decl *D);
+
+ clang::ASTContext
+ *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for
+ ///passthrough. NULL if it's a
+ ///SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain,
+ ///for passthrough. NULL if it's an
+ ///ASTConsumer.
+ clang::Sema *m_sema; ///< The Sema to use.
+ clang::Action
+ *m_action; ///< The Sema to use, cast to an Action so it's usable.
+
+ ClangFunctionCaller &m_function; ///< The function to populate with
+ ///information about the argument structure.
+ std::string m_struct_name; ///< The name of the structure to extract.
};
-
+
} // namespace lldb_private
#endif // liblldb_ASTStructExtractor_h_
diff --git a/source/Plugins/ExpressionParser/Clang/CMakeLists.txt b/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
index e18dde6b700e..64559d20bb4e 100644
--- a/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
+++ b/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
@@ -1,3 +1,7 @@
+if(NOT LLDB_BUILT_STANDALONE)
+ set(tablegen_deps intrinsics_gen)
+endif()
+
add_lldb_library(lldbPluginExpressionParserClang
ASTDumper.cpp
ASTResultSynthesizer.cpp
@@ -12,4 +16,7 @@ add_lldb_library(lldbPluginExpressionParserClang
ClangUserExpression.cpp
ClangUtilityFunction.cpp
IRForTarget.cpp
+
+ DEPENDS
+ ${tablegen_deps}
)
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index def0d42d32dd..0f08dd330e90 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -1,4 +1,4 @@
-//===-- ClangASTSource.cpp ---------------------------------------*- C++ -*-===//
+//===-- ClangASTSource.cpp ---------------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -37,884 +37,833 @@ using namespace lldb_private;
// when it goes out of scope.
//------------------------------------------------------------------
namespace {
- class ScopedLexicalDeclEraser
- {
- public:
- ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls,
- const clang::Decl *decl)
- : m_active_lexical_decls(decls), m_decl(decl)
- {
- }
+class ScopedLexicalDeclEraser {
+public:
+ ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls,
+ const clang::Decl *decl)
+ : m_active_lexical_decls(decls), m_decl(decl) {}
- ~ScopedLexicalDeclEraser()
- {
- m_active_lexical_decls.erase(m_decl);
- }
+ ~ScopedLexicalDeclEraser() { m_active_lexical_decls.erase(m_decl); }
- private:
- std::set<const clang::Decl *> &m_active_lexical_decls;
- const clang::Decl *m_decl;
- };
+private:
+ std::set<const clang::Decl *> &m_active_lexical_decls;
+ const clang::Decl *m_decl;
+};
}
-ClangASTSource::~ClangASTSource()
-{
- m_ast_importer_sp->ForgetDestination(m_ast_context);
+ClangASTSource::~ClangASTSource() {
+ m_ast_importer_sp->ForgetDestination(m_ast_context);
- // We are in the process of destruction, don't create clang ast context on demand
- // by passing false to Target::GetScratchClangASTContext(create_on_demand).
- ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false);
+ // We are in the process of destruction, don't create clang ast context on
+ // demand
+ // by passing false to Target::GetScratchClangASTContext(create_on_demand).
+ ClangASTContext *scratch_clang_ast_context =
+ m_target->GetScratchClangASTContext(false);
- if (!scratch_clang_ast_context)
- return;
+ if (!scratch_clang_ast_context)
+ return;
- clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
+ clang::ASTContext *scratch_ast_context =
+ scratch_clang_ast_context->getASTContext();
- if (!scratch_ast_context)
- return;
+ if (!scratch_ast_context)
+ return;
- if (m_ast_context != scratch_ast_context)
- m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
+ if (m_ast_context != scratch_ast_context)
+ m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
}
-void
-ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
-{
- if (!m_ast_context)
- return;
+void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) {
+ if (!m_ast_context)
+ return;
- m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
- m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
+ m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
+ m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
}
// The core lookup interface.
-bool
-ClangASTSource::FindExternalVisibleDeclsByName
-(
- const DeclContext *decl_ctx,
- DeclarationName clang_decl_name
-)
-{
- if (!m_ast_context)
- {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
+bool ClangASTSource::FindExternalVisibleDeclsByName(
+ const DeclContext *decl_ctx, DeclarationName clang_decl_name) {
+ if (!m_ast_context) {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
+
+ if (GetImportInProgress()) {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
+
+ std::string decl_name(clang_decl_name.getAsString());
+
+ // if (m_decl_map.DoingASTImport ())
+ // return DeclContext::lookup_result();
+ //
+ switch (clang_decl_name.getNameKind()) {
+ // Normal identifiers.
+ case DeclarationName::Identifier: {
+ clang::IdentifierInfo *identifier_info =
+ clang_decl_name.getAsIdentifierInfo();
+
+ if (!identifier_info || identifier_info->getBuiltinID() != 0) {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
-
- if (GetImportInProgress())
- {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
+ } break;
+
+ // Operator names.
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ break;
+
+ // Using directives found in this context.
+ // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
+ case DeclarationName::CXXUsingDirective:
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector: {
+ llvm::SmallVector<NamedDecl *, 1> method_decls;
+
+ NameSearchContext method_search_context(*this, method_decls,
+ clang_decl_name, decl_ctx);
+
+ FindObjCMethodDecls(method_search_context);
+
+ SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, method_decls);
+ return (method_decls.size() > 0);
+ }
+ // These aren't possible in the global context.
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
+
+ if (!GetLookupsEnabled()) {
+ // Wait until we see a '$' at the start of a name before we start doing
+ // any lookups so we can avoid lookup up all of the builtin types.
+ if (!decl_name.empty() && decl_name[0] == '$') {
+ SetLookupsEnabled(true);
+ } else {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
+ }
+
+ ConstString const_decl_name(decl_name.c_str());
+
+ const char *uniqued_const_decl_name = const_decl_name.GetCString();
+ if (m_active_lookups.find(uniqued_const_decl_name) !=
+ m_active_lookups.end()) {
+ // We are currently looking up this name...
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
+ m_active_lookups.insert(uniqued_const_decl_name);
+ // static uint32_t g_depth = 0;
+ // ++g_depth;
+ // printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth,
+ // uniqued_const_decl_name);
+ llvm::SmallVector<NamedDecl *, 4> name_decls;
+ NameSearchContext name_search_context(*this, name_decls, clang_decl_name,
+ decl_ctx);
+ FindExternalVisibleDecls(name_search_context);
+ SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls);
+ // --g_depth;
+ m_active_lookups.erase(uniqued_const_decl_name);
+ return (name_decls.size() != 0);
+}
- std::string decl_name (clang_decl_name.getAsString());
+void ClangASTSource::CompleteType(TagDecl *tag_decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-// if (m_decl_map.DoingASTImport ())
-// return DeclContext::lookup_result();
-//
- switch (clang_decl_name.getNameKind()) {
- // Normal identifiers.
- case DeclarationName::Identifier:
- {
- clang::IdentifierInfo *identifier_info = clang_decl_name.getAsIdentifierInfo();
-
- if (!identifier_info ||
- identifier_info->getBuiltinID() != 0)
- {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
- }
- break;
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- // Operator names.
- case DeclarationName::CXXOperatorName:
- case DeclarationName::CXXLiteralOperatorName:
- break;
+ if (log) {
+ log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing "
+ "(TagDecl*)%p named %s",
+ current_id, static_cast<void *>(m_ast_context),
+ static_cast<void *>(tag_decl),
+ tag_decl->getName().str().c_str());
- // Using directives found in this context.
- // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
- case DeclarationName::CXXUsingDirective:
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
+ log->Printf(" CTD[%u] Before:", current_id);
+ ASTDumper dumper((Decl *)tag_decl);
+ dumper.ToLog(log, " [CTD] ");
+ }
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- {
- llvm::SmallVector<NamedDecl*, 1> method_decls;
+ auto iter = m_active_lexical_decls.find(tag_decl);
+ if (iter != m_active_lexical_decls.end())
+ return;
+ m_active_lexical_decls.insert(tag_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
- NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx);
+ if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
+ // We couldn't complete the type. Maybe there's a definition
+ // somewhere else that can be completed.
- FindObjCMethodDecls(method_search_context);
+ if (log)
+ log->Printf(" CTD[%u] Type could not be completed in the module in "
+ "which it was first found.",
+ current_id);
- SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
- return (method_decls.size() > 0);
- }
- // These aren't possible in the global context.
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
+ bool found = false;
+ DeclContext *decl_ctx = tag_decl->getDeclContext();
- if (!GetLookupsEnabled())
- {
- // Wait until we see a '$' at the start of a name before we start doing
- // any lookups so we can avoid lookup up all of the builtin types.
- if (!decl_name.empty() && decl_name[0] == '$')
- {
- SetLookupsEnabled (true);
- }
- else
- {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
- }
+ if (const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(decl_ctx)) {
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
- ConstString const_decl_name(decl_name.c_str());
+ if (log && log->GetVerbose())
+ log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
+ current_id, static_cast<void *>(namespace_map.get()),
+ static_cast<int>(namespace_map->size()));
- const char *uniqued_const_decl_name = const_decl_name.GetCString();
- if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
- {
- // We are currently looking up this name...
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
- m_active_lookups.insert(uniqued_const_decl_name);
-// static uint32_t g_depth = 0;
-// ++g_depth;
-// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name);
- llvm::SmallVector<NamedDecl*, 4> name_decls;
- NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
- FindExternalVisibleDecls(name_search_context);
- SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls);
-// --g_depth;
- m_active_lookups.erase (uniqued_const_decl_name);
- return (name_decls.size() != 0);
-}
+ if (!namespace_map)
+ return;
-void
-ClangASTSource::CompleteType (TagDecl *tag_decl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
+ e = namespace_map->end();
+ i != e && !found; ++i) {
+ if (log)
+ log->Printf(" CTD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ TypeList types;
- if (log)
- {
- log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s",
- current_id, static_cast<void*>(m_ast_context),
- static_cast<void*>(tag_decl),
- tag_decl->getName().str().c_str());
-
- log->Printf(" CTD[%u] Before:", current_id);
- ASTDumper dumper((Decl*)tag_decl);
- dumper.ToLog(log, " [CTD] ");
- }
+ SymbolContext null_sc;
+ ConstString name(tag_decl->getName().str().c_str());
- auto iter = m_active_lexical_decls.find(tag_decl);
- if (iter != m_active_lexical_decls.end())
- return;
- m_active_lexical_decls.insert(tag_decl);
- ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
+ i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX,
+ types);
- if (!m_ast_importer_sp->CompleteTagDecl (tag_decl))
- {
- // We couldn't complete the type. Maybe there's a definition
- // somewhere else that can be completed.
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- if (log)
- log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id);
+ if (!type)
+ continue;
- bool found = false;
+ CompilerType clang_type(type->GetFullCompilerType());
- DeclContext *decl_ctx = tag_decl->getDeclContext();
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
- {
- ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- if (log && log->GetVerbose())
- log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void*>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
+ if (!tag_type)
+ continue;
- if (!namespace_map)
- return;
+ TagDecl *candidate_tag_decl =
+ const_cast<TagDecl *>(tag_type->getDecl());
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
- i != e && !found;
- ++i)
- {
- if (log)
- log->Printf(" CTD[%u] Searching namespace %s in module %s",
- current_id,
- i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
+ candidate_tag_decl))
+ found = true;
+ }
+ }
+ } else {
+ TypeList types;
- TypeList types;
+ SymbolContext null_sc;
+ ConstString name(tag_decl->getName().str().c_str());
+ CompilerDeclContext namespace_decl;
- SymbolContext null_sc;
- ConstString name(tag_decl->getName().str().c_str());
+ const ModuleList &module_list = m_target->GetImages();
- i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types);
+ bool exact_match = false;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ module_list.FindTypes(null_sc, name, exact_match, UINT32_MAX,
+ searched_symbol_files, types);
- for (uint32_t ti = 0, te = types.GetSize();
- ti != te && !found;
- ++ti)
- {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- if (!type)
- continue;
+ if (!type)
+ continue;
- CompilerType clang_type (type->GetFullCompilerType ());
+ CompilerType clang_type(type->GetFullCompilerType());
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- if (!tag_type)
- continue;
+ if (!tag_type)
+ continue;
- TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
+ TagDecl *candidate_tag_decl =
+ const_cast<TagDecl *>(tag_type->getDecl());
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
- found = true;
- }
- }
- }
- else
- {
- TypeList types;
+ // We have found a type by basename and we need to make sure the decl
+ // contexts
+ // are the same before we can try to complete this type with another
+ if (!ClangASTContext::DeclsAreEquivalent(tag_decl, candidate_tag_decl))
+ continue;
- SymbolContext null_sc;
- ConstString name(tag_decl->getName().str().c_str());
- CompilerDeclContext namespace_decl;
+ if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
+ candidate_tag_decl))
+ found = true;
+ }
+ }
+ }
- const ModuleList &module_list = m_target->GetImages();
+ if (log) {
+ log->Printf(" [CTD] After:");
+ ASTDumper dumper((Decl *)tag_decl);
+ dumper.ToLog(log, " [CTD] ");
+ }
+}
- bool exact_match = false;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, searched_symbol_files, types);
+void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing "
+ "an ObjCInterfaceDecl named %s",
+ static_cast<void *>(m_ast_context),
+ interface_decl->getName().str().c_str());
+ log->Printf(" [COID] Before:");
+ ASTDumper dumper((Decl *)interface_decl);
+ dumper.ToLog(log, " [COID] ");
+ }
+
+ Decl *original_decl = NULL;
+ ASTContext *original_ctx = NULL;
+
+ if (m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl,
+ &original_ctx)) {
+ if (ObjCInterfaceDecl *original_iface_decl =
+ dyn_cast<ObjCInterfaceDecl>(original_decl)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(original_iface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) {
+ m_ast_importer_sp->SetDeclOrigin(interface_decl, original_iface_decl);
+ }
+ }
+ }
- for (uint32_t ti = 0, te = types.GetSize();
- ti != te && !found;
- ++ti)
- {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ m_ast_importer_sp->CompleteObjCInterfaceDecl(interface_decl);
- if (!type)
- continue;
+ if (interface_decl->getSuperClass() &&
+ interface_decl->getSuperClass() != interface_decl)
+ CompleteType(interface_decl->getSuperClass());
- CompilerType clang_type (type->GetFullCompilerType ());
+ if (log) {
+ log->Printf(" [COID] After:");
+ ASTDumper dumper((Decl *)interface_decl);
+ dumper.ToLog(log, " [COID] ");
+ }
+}
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
+ clang::ObjCInterfaceDecl *interface_decl) {
+ lldb::ProcessSP process(m_target->GetProcessSP());
- const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+ if (!process)
+ return NULL;
- if (!tag_type)
- continue;
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
- TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
+ if (!language_runtime)
+ return NULL;
- // We have found a type by basename and we need to make sure the decl contexts
- // are the same before we can try to complete this type with another
- if (!ClangASTContext::DeclsAreEquivalent (tag_decl, candidate_tag_decl))
- continue;
+ ConstString class_name(interface_decl->getNameAsString().c_str());
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
- found = true;
- }
- }
- }
+ lldb::TypeSP complete_type_sp(
+ language_runtime->LookupInCompleteClassCache(class_name));
- if (log)
- {
- log->Printf(" [CTD] After:");
- ASTDumper dumper((Decl*)tag_decl);
- dumper.ToLog(log, " [CTD] ");
- }
-}
+ if (!complete_type_sp)
+ return NULL;
-void
-ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ TypeFromUser complete_type =
+ TypeFromUser(complete_type_sp->GetFullCompilerType());
+ lldb::opaque_compiler_type_t complete_opaque_type =
+ complete_type.GetOpaqueQualType();
- if (log)
- {
- log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s",
- static_cast<void*>(m_ast_context),
- interface_decl->getName().str().c_str());
- log->Printf(" [COID] Before:");
- ASTDumper dumper((Decl*)interface_decl);
- dumper.ToLog(log, " [COID] ");
- }
+ if (!complete_opaque_type)
+ return NULL;
- Decl *original_decl = NULL;
- ASTContext *original_ctx = NULL;
+ const clang::Type *complete_clang_type =
+ QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
+ const ObjCInterfaceType *complete_interface_type =
+ dyn_cast<ObjCInterfaceType>(complete_clang_type);
- if (m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx))
- {
- if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
- {
- ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
+ if (!complete_interface_type)
+ return NULL;
- if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
- {
- m_ast_importer_sp->SetDeclOrigin(interface_decl, original_iface_decl);
- }
- }
- }
+ ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
- m_ast_importer_sp->CompleteObjCInterfaceDecl (interface_decl);
+ return complete_iface_decl;
+}
- if (interface_decl->getSuperClass() &&
- interface_decl->getSuperClass() != interface_decl)
- CompleteType(interface_decl->getSuperClass());
+void ClangASTSource::FindExternalLexicalDecls(
+ const DeclContext *decl_context,
+ llvm::function_ref<bool(Decl::Kind)> predicate,
+ llvm::SmallVectorImpl<Decl *> &decls) {
+ ClangASTMetrics::RegisterLexicalQuery();
- if (log)
- {
- log->Printf(" [COID] After:");
- ASTDumper dumper((Decl*)interface_decl);
- dumper.ToLog(log, " [COID] ");
- }
-}
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-clang::ObjCInterfaceDecl *
-ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl)
-{
- lldb::ProcessSP process(m_target->GetProcessSP());
+ const Decl *context_decl = dyn_cast<Decl>(decl_context);
- if (!process)
- return NULL;
+ if (!context_decl)
+ return;
- ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+ auto iter = m_active_lexical_decls.find(context_decl);
+ if (iter != m_active_lexical_decls.end())
+ return;
+ m_active_lexical_decls.insert(context_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
+
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
+
+ if (log) {
+ if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
+ log->Printf(
+ "FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p",
+ current_id, static_cast<void *>(m_ast_context),
+ context_named_decl->getNameAsString().c_str(),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
+ else if (context_decl)
+ log->Printf(
+ "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
+ current_id, static_cast<void *>(m_ast_context),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
+ else
+ log->Printf(
+ "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
+ current_id, static_cast<const void *>(m_ast_context));
+ }
- if (!language_runtime)
- return NULL;
+ Decl *original_decl = NULL;
+ ASTContext *original_ctx = NULL;
- ConstString class_name(interface_decl->getNameAsString().c_str());
+ if (!m_ast_importer_sp->ResolveDeclOrigin(context_decl, &original_decl,
+ &original_ctx))
+ return;
- lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
+ if (log) {
+ log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:",
+ current_id, static_cast<void *>(original_ctx),
+ static_cast<void *>(original_decl));
+ ASTDumper(original_decl).ToLog(log, " ");
+ }
- if (!complete_type_sp)
- return NULL;
+ if (ObjCInterfaceDecl *original_iface_decl =
+ dyn_cast<ObjCInterfaceDecl>(original_decl)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(original_iface_decl);
- TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetFullCompilerType ());
- lldb::opaque_compiler_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
+ if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) {
+ original_decl = complete_iface_decl;
+ original_ctx = &complete_iface_decl->getASTContext();
- if (!complete_opaque_type)
- return NULL;
+ m_ast_importer_sp->SetDeclOrigin(context_decl, original_iface_decl);
+ }
+ }
- const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
- const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
+ if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
+ ExternalASTSource *external_source = original_ctx->getExternalSource();
- if (!complete_interface_type)
- return NULL;
+ if (external_source)
+ external_source->CompleteType(original_tag_decl);
+ }
- ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
+ const DeclContext *original_decl_context =
+ dyn_cast<DeclContext>(original_decl);
- return complete_iface_decl;
-}
+ if (!original_decl_context)
+ return;
+
+ for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
+ iter != original_decl_context->decls_end(); ++iter) {
+ Decl *decl = *iter;
+
+ if (predicate(decl->getKind())) {
+ if (log) {
+ ASTDumper ast_dumper(decl);
+ if (const NamedDecl *context_named_decl =
+ dyn_cast<NamedDecl>(context_decl))
+ log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s",
+ current_id, context_named_decl->getDeclKindName(),
+ context_named_decl->getNameAsString().c_str(),
+ decl->getDeclKindName(), ast_dumper.GetCString());
+ else
+ log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id,
+ decl->getDeclKindName(), ast_dumper.GetCString());
+ }
-void
-ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
- llvm::function_ref<bool(Decl::Kind)> predicate,
- llvm::SmallVectorImpl<Decl*> &decls)
-{
- ClangASTMetrics::RegisterLexicalQuery();
+ Decl *copied_decl =
+ m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!copied_decl)
+ continue;
- const Decl *context_decl = dyn_cast<Decl>(decl_context);
+ if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) {
+ QualType copied_field_type = copied_field->getType();
- if (!context_decl)
- return;
+ m_ast_importer_sp->RequireCompleteType(copied_field_type);
+ }
- auto iter = m_active_lexical_decls.find(context_decl);
- if (iter != m_active_lexical_decls.end())
- return;
- m_active_lexical_decls.insert(context_decl);
- ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
+ DeclContext *decl_context_non_const =
+ const_cast<DeclContext *>(decl_context);
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (copied_decl->getDeclContext() != decl_context) {
+ if (copied_decl->getDeclContext()->containsDecl(copied_decl))
+ copied_decl->getDeclContext()->removeDecl(copied_decl);
+ copied_decl->setDeclContext(decl_context_non_const);
+ }
- if (log)
- {
- if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p",
- current_id, static_cast<void*>(m_ast_context),
- context_named_decl->getNameAsString().c_str(),
- context_decl->getDeclKindName(),
- static_cast<const void*>(context_decl));
- else if(context_decl)
- log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
- current_id, static_cast<void*>(m_ast_context),
- context_decl->getDeclKindName(),
- static_cast<const void*>(context_decl));
- else
- log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
- current_id, static_cast<const void*>(m_ast_context));
+ if (!decl_context_non_const->containsDecl(copied_decl))
+ decl_context_non_const->addDeclInternal(copied_decl);
}
+ }
- Decl *original_decl = NULL;
- ASTContext *original_ctx = NULL;
+ return;
+}
- if (!m_ast_importer_sp->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
- return;
+void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
+ assert(m_ast_context);
- if (log)
- {
- log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:",
- current_id, static_cast<void*>(original_ctx),
- static_cast<void*>(original_decl));
- ASTDumper(original_decl).ToLog(log, " ");
- }
+ ClangASTMetrics::RegisterVisibleQuery();
- if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
- {
- ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
+ const ConstString name(context.m_decl_name.getAsString().c_str());
- if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
- {
- original_decl = complete_iface_decl;
- original_ctx = &complete_iface_decl->getASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- m_ast_importer_sp->SetDeclOrigin(context_decl, original_iface_decl);
- }
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
+
+ if (log) {
+ if (!context.m_decl_context)
+ log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on "
+ "(ASTContext*)%p for '%s' in a NULL DeclContext",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString());
+ else if (const NamedDecl *context_named_decl =
+ dyn_cast<NamedDecl>(context.m_decl_context))
+ log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on "
+ "(ASTContext*)%p for '%s' in '%s'",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString(),
+ context_named_decl->getNameAsString().c_str());
+ else
+ log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on "
+ "(ASTContext*)%p for '%s' in a '%s'",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString(), context.m_decl_context->getDeclKindName());
+ }
+
+ context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
+
+ if (const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(context.m_decl_context)) {
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
+
+ if (log && log->GetVerbose())
+ log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
+ current_id, static_cast<void *>(namespace_map.get()),
+ static_cast<int>(namespace_map->size()));
+
+ if (!namespace_map)
+ return;
+
+ for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
+ e = namespace_map->end();
+ i != e; ++i) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
+
+ FindExternalVisibleDecls(context, i->first, i->second, current_id);
}
+ } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
+ FindObjCPropertyAndIvarDecls(context);
+ } else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
+ // we shouldn't be getting FindExternalVisibleDecls calls for these
+ return;
+ } else {
+ CompilerDeclContext namespace_decl;
- if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
- {
- ExternalASTSource *external_source = original_ctx->getExternalSource();
+ if (log)
+ log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
- if (external_source)
- external_source->CompleteType (original_tag_decl);
- }
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
+ current_id);
+ }
- const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
+ if (!context.m_namespace_map->empty()) {
+ if (log && log->GetVerbose())
+ log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
+ current_id,
+ static_cast<void *>(context.m_namespace_map.get()),
+ static_cast<int>(context.m_namespace_map->size()));
- if (!original_decl_context)
- return;
+ NamespaceDecl *clang_namespace_decl =
+ AddNamespace(context, context.m_namespace_map);
- for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
- iter != original_decl_context->decls_end();
- ++iter)
- {
- Decl *decl = *iter;
-
- if (predicate(decl->getKind()))
- {
- if (log)
- {
- ASTDumper ast_dumper(decl);
- if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", current_id, context_named_decl->getDeclKindName(), context_named_decl->getNameAsString().c_str(), decl->getDeclKindName(), ast_dumper.GetCString());
- else
- log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString());
- }
-
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
+ if (clang_namespace_decl)
+ clang_namespace_decl->setHasExternalVisibleStorage();
+ }
+}
- if (!copied_decl)
- continue;
+void ClangASTSource::FindExternalVisibleDecls(
+ NameSearchContext &context, lldb::ModuleSP module_sp,
+ CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ assert(m_ast_context);
- if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl))
- {
- QualType copied_field_type = copied_field->getType();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- m_ast_importer_sp->RequireCompleteType(copied_field_type);
- }
+ SymbolContextList sc_list;
- DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context);
+ const ConstString name(context.m_decl_name.getAsString().c_str());
- if (copied_decl->getDeclContext() != decl_context)
- {
- if (copied_decl->getDeclContext()->containsDecl(copied_decl))
- copied_decl->getDeclContext()->removeDecl(copied_decl);
- copied_decl->setDeclContext(decl_context_non_const);
- }
+ const char *name_unique_cstr = name.GetCString();
- if (!decl_context_non_const->containsDecl(copied_decl))
- decl_context_non_const->addDeclInternal(copied_decl);
- }
- }
+ static ConstString id_name("id");
+ static ConstString Class_name("Class");
+ if (name == id_name || name == Class_name)
return;
-}
-void
-ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
-{
- assert (m_ast_context);
+ if (name_unique_cstr == NULL)
+ return;
- ClangASTMetrics::RegisterVisibleQuery();
+ // The ClangASTSource is not responsible for finding $-names.
+ if (name_unique_cstr[0] == '$')
+ return;
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ if (module_sp && namespace_decl) {
+ CompilerDeclContext found_namespace_decl;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (symbol_vendor) {
+ SymbolContext null_sc;
- if (log)
- {
- if (!context.m_decl_context)
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext",
- current_id, static_cast<void*>(m_ast_context),
- name.GetCString());
- else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in '%s'",
- current_id, static_cast<void*>(m_ast_context),
- name.GetCString(),
- context_named_decl->getNameAsString().c_str());
- else
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a '%s'",
- current_id, static_cast<void*>(m_ast_context),
- name.GetCString(),
- context.m_decl_context->getDeclKindName());
- }
+ found_namespace_decl =
+ symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
- context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
-
- if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
- {
- ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
-
- if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void*>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
-
- if (!namespace_map)
- return;
-
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
- i != e;
- ++i)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
- current_id,
- i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
-
- FindExternalVisibleDecls(context,
- i->first,
- i->second,
- current_id);
- }
- }
- else if (isa<ObjCInterfaceDecl>(context.m_decl_context))
- {
- FindObjCPropertyAndIvarDecls(context);
- }
- else if (!isa<TranslationUnitDecl>(context.m_decl_context))
- {
- // we shouldn't be getting FindExternalVisibleDecls calls for these
- return;
- }
- else
- {
- CompilerDeclContext namespace_decl;
+ if (found_namespace_decl) {
+ context.m_namespace_map->push_back(
+ std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ module_sp, found_namespace_decl));
if (log)
- log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
-
- FindExternalVisibleDecls(context,
- lldb::ModuleSP(),
- namespace_decl,
- current_id);
+ log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
+ }
}
+ } else {
+ const ModuleList &target_images = m_target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+
+ for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
+ lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
+
+ if (!image)
+ continue;
+
+ CompilerDeclContext found_namespace_decl;
- if (!context.m_namespace_map->empty())
- {
- if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
- current_id,
- static_cast<void*>(context.m_namespace_map.get()),
- static_cast<int>(context.m_namespace_map->size()));
+ SymbolVendor *symbol_vendor = image->GetSymbolVendor();
- NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map);
+ if (!symbol_vendor)
+ continue;
- if (clang_namespace_decl)
- clang_namespace_decl->setHasExternalVisibleStorage();
+ SymbolContext null_sc;
+
+ found_namespace_decl =
+ symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
+
+ if (found_namespace_decl) {
+ context.m_namespace_map->push_back(
+ std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ image, found_namespace_decl));
+
+ if (log)
+ log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
+ }
}
-}
+ }
-void
-ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id)
-{
- assert (m_ast_context);
+ do {
+ if (context.m_found.type)
+ break;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ TypeList types;
+ SymbolContext null_sc;
+ const bool exact_match = false;
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ if (module_sp && namespace_decl)
+ module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
+ else
+ m_target->GetImages().FindTypes(null_sc, name, exact_match, 1,
+ searched_symbol_files, types);
- SymbolContextList sc_list;
+ if (size_t num_types = types.GetSize()) {
+ for (size_t ti = 0; ti < num_types; ++ti) {
+ lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ if (log) {
+ const char *name_string = type_sp->GetName().GetCString();
- const char *name_unique_cstr = name.GetCString();
+ log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
+ current_id, name.GetCString(),
+ (name_string ? name_string : "<anonymous>"));
+ }
- static ConstString id_name("id");
- static ConstString Class_name("Class");
+ CompilerType full_type = type_sp->GetFullCompilerType();
- if (name == id_name || name == Class_name)
- return;
+ CompilerType copied_clang_type(GuardedCopyType(full_type));
- if (name_unique_cstr == NULL)
- return;
+ if (!copied_clang_type) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a type", current_id);
- // The ClangASTSource is not responsible for finding $-names.
- if (name_unique_cstr[0] == '$')
- return;
+ continue;
+ }
- if (module_sp && namespace_decl)
- {
- CompilerDeclContext found_namespace_decl;
+ context.AddTypeDecl(copied_clang_type);
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
+ context.m_found.type = true;
+ break;
+ }
+ }
- if (symbol_vendor)
- {
- SymbolContext null_sc;
+ if (!context.m_found.type) {
+ // Try the modules next.
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
+ do {
+ if (ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (found_namespace_decl)
- {
- context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(module_sp, found_namespace_decl));
+ if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
+ break;
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in "
+ "the modules",
+ current_id, name.GetCString());
+ }
+
+ clang::NamedDecl *const decl_from_modules = decls[0];
+
+ if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
+ llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
+ llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ if (log)
+ log->Printf(
+ " CAS::FEVD[%u] - Couldn't export a type from the modules",
+ current_id);
+
+ break;
}
+
+ context.AddNamedDecl(copied_named_decl);
+
+ context.m_found.type = true;
+ }
}
+ } while (0);
}
- else
- {
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
- {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
+ if (!context.m_found.type) {
+ do {
+ // Couldn't find any types elsewhere. Try the Objective-C runtime if
+ // one exists.
- if (!image)
- continue;
+ lldb::ProcessSP process(m_target->GetProcessSP());
- CompilerDeclContext found_namespace_decl;
+ if (!process)
+ break;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ ObjCLanguageRuntime *language_runtime(
+ process->GetObjCLanguageRuntime());
- if (!symbol_vendor)
- continue;
+ if (!language_runtime)
+ break;
- SymbolContext null_sc;
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
+ if (!decl_vendor)
+ break;
- if (found_namespace_decl)
- {
- context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(image, found_namespace_decl));
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
- }
- }
- }
+ if (!decl_vendor->FindDecls(name, append, max_matches, decls))
+ break;
- do
- {
- if (context.m_found.type)
- break;
-
- TypeList types;
- SymbolContext null_sc;
- const bool exact_match = false;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- if (module_sp && namespace_decl)
- module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
- else
- m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, searched_symbol_files, types);
-
- if (size_t num_types = types.GetSize())
- {
- for (size_t ti = 0; ti < num_types; ++ti)
- {
- lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
-
- if (log)
- {
- const char *name_string = type_sp->GetName().GetCString();
-
- log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
- current_id,
- name.GetCString(),
- (name_string ? name_string : "<anonymous>"));
- }
-
- CompilerType full_type = type_sp->GetFullCompilerType();
-
- CompilerType copied_clang_type (GuardedCopyType(full_type));
-
- if (!copied_clang_type)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type",
- current_id);
-
- continue;
- }
-
- context.AddTypeDecl(copied_clang_type);
-
- context.m_found.type = true;
- break;
- }
+ if (log) {
+ log->Printf(
+ " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
+ current_id, name.GetCString());
}
- if (!context.m_found.type)
- {
- // Try the modules next.
-
- do
- {
- if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(name,
- append,
- max_matches,
- decls))
- break;
-
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in the modules",
- current_id,
- name.GetCString());
- }
-
- clang::NamedDecl *const decl_from_modules = decls[0];
-
- if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
- llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
- llvm::isa<clang::EnumConstantDecl>(decl_from_modules))
- {
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
- clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
-
- if (!copied_named_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the modules",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_named_decl);
-
- context.m_found.type = true;
- }
- }
- } while (0);
- }
-
- if (!context.m_found.type)
- {
- do
- {
- // Couldn't find any types elsewhere. Try the Objective-C runtime if one exists.
-
- lldb::ProcessSP process(m_target->GetProcessSP());
-
- if (!process)
- break;
-
- ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
-
- if (!language_runtime)
- break;
-
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
-
- if (!decl_vendor)
- break;
-
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!decl_vendor->FindDecls(name,
- append,
- max_matches,
- decls))
- break;
-
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
- current_id,
- name.GetCString());
- }
-
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decls[0]->getASTContext(), decls[0]);
- clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
-
- if (!copied_named_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_named_decl);
- }
- while(0);
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decls[0]->getASTContext(), decls[0]);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ if (log)
+ log->Printf(
+ " CAS::FEVD[%u] - Couldn't export a type from the runtime",
+ current_id);
+
+ break;
}
- } while(0);
+ context.AddNamedDecl(copied_named_decl);
+ } while (0);
+ }
+
+ } while (0);
}
template <class D> class TaggedASTDecl {
public:
- TaggedASTDecl() : decl(NULL) { }
- TaggedASTDecl(D *_decl) : decl(_decl) { }
- bool IsValid() const { return (decl != NULL); }
- bool IsInvalid() const { return !IsValid(); }
- D *operator->() const { return decl; }
- D *decl;
+ TaggedASTDecl() : decl(NULL) {}
+ TaggedASTDecl(D *_decl) : decl(_decl) {}
+ bool IsValid() const { return (decl != NULL); }
+ bool IsInvalid() const { return !IsValid(); }
+ D *operator->() const { return decl; }
+ D *decl;
};
template <class D2, template <class D> class TD, class D1>
-TD<D2>
-DynCast(TD<D1> source)
-{
- return TD<D2> (dyn_cast<D2>(source.decl));
+TD<D2> DynCast(TD<D1> source) {
+ return TD<D2>(dyn_cast<D2>(source.decl));
}
template <class D = Decl> class DeclFromParser;
@@ -922,1179 +871,1141 @@ template <class D = Decl> class DeclFromUser;
template <class D> class DeclFromParser : public TaggedASTDecl<D> {
public:
- DeclFromParser() : TaggedASTDecl<D>() { }
- DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
+ DeclFromParser() : TaggedASTDecl<D>() {}
+ DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
+ DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
};
template <class D> class DeclFromUser : public TaggedASTDecl<D> {
public:
- DeclFromUser() : TaggedASTDecl<D>() { }
- DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
+ DeclFromUser() : TaggedASTDecl<D>() {}
+ DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
+ DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
};
template <class D>
-DeclFromUser<D>
-DeclFromParser<D>::GetOrigin(ClangASTImporter *importer)
-{
- DeclFromUser <> origin_decl;
- importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
- if (origin_decl.IsInvalid())
- return DeclFromUser<D>();
- return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
+DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) {
+ DeclFromUser<> origin_decl;
+ importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
+ if (origin_decl.IsInvalid())
+ return DeclFromUser<D>();
+ return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
}
template <class D>
-DeclFromParser<D>
-DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx)
-{
- DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
- if (parser_generic_decl.IsInvalid())
- return DeclFromParser<D>();
- return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
+DeclFromParser<D> DeclFromUser<D>::Import(ClangASTImporter *importer,
+ ASTContext &dest_ctx) {
+ DeclFromParser<> parser_generic_decl(
+ importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
+ if (parser_generic_decl.IsInvalid())
+ return DeclFromParser<D>();
+ return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
}
-static bool
-FindObjCMethodDeclsWithOrigin (unsigned int current_id,
- NameSearchContext &context,
- ObjCInterfaceDecl *original_interface_decl,
- clang::ASTContext *ast_context,
- ClangASTImporter *ast_importer,
- const char *log_info)
-{
- const DeclarationName &decl_name(context.m_decl_name);
- clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
-
- Selector original_selector;
-
- if (decl_name.isObjCZeroArgSelector())
- {
- IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
- original_selector = original_ctx->Selectors.getSelector(0, &ident);
- }
- else if (decl_name.isObjCOneArgSelector())
- {
- const std::string &decl_name_string = decl_name.getAsString();
- std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
- IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
- original_selector = original_ctx->Selectors.getSelector(1, &ident);
+static bool FindObjCMethodDeclsWithOrigin(
+ unsigned int current_id, NameSearchContext &context,
+ ObjCInterfaceDecl *original_interface_decl, clang::ASTContext *ast_context,
+ ClangASTImporter *ast_importer, const char *log_info) {
+ const DeclarationName &decl_name(context.m_decl_name);
+ clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
+
+ Selector original_selector;
+
+ if (decl_name.isObjCZeroArgSelector()) {
+ IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
+ original_selector = original_ctx->Selectors.getSelector(0, &ident);
+ } else if (decl_name.isObjCOneArgSelector()) {
+ const std::string &decl_name_string = decl_name.getAsString();
+ std::string decl_name_string_without_colon(decl_name_string.c_str(),
+ decl_name_string.length() - 1);
+ IdentifierInfo *ident =
+ &original_ctx->Idents.get(decl_name_string_without_colon);
+ original_selector = original_ctx->Selectors.getSelector(1, &ident);
+ } else {
+ SmallVector<IdentifierInfo *, 4> idents;
+
+ clang::Selector sel = decl_name.getObjCSelector();
+
+ unsigned num_args = sel.getNumArgs();
+
+ for (unsigned i = 0; i != num_args; ++i) {
+ idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
}
- else
- {
- SmallVector<IdentifierInfo *, 4> idents;
- clang::Selector sel = decl_name.getObjCSelector();
+ original_selector =
+ original_ctx->Selectors.getSelector(num_args, idents.data());
+ }
- unsigned num_args = sel.getNumArgs();
+ DeclarationName original_decl_name(original_selector);
- for (unsigned i = 0;
- i != num_args;
- ++i)
- {
- idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
- }
+ llvm::SmallVector<NamedDecl *, 1> methods;
- original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
- }
+ ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl);
- DeclarationName original_decl_name(original_selector);
-
- llvm::SmallVector<NamedDecl *, 1> methods;
-
- ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl);
-
- if (ObjCMethodDecl *instance_method_decl = original_interface_decl->lookupInstanceMethod(original_selector))
- {
- methods.push_back(instance_method_decl);
- }
- else if (ObjCMethodDecl *class_method_decl = original_interface_decl->lookupClassMethod(original_selector))
- {
- methods.push_back(class_method_decl);
- }
-
- if (methods.empty())
- {
- return false;
- }
-
- for (NamedDecl *named_decl : methods)
- {
- if (!named_decl)
- continue;
-
- ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
+ if (ObjCMethodDecl *instance_method_decl =
+ original_interface_decl->lookupInstanceMethod(original_selector)) {
+ methods.push_back(instance_method_decl);
+ } else if (ObjCMethodDecl *class_method_decl =
+ original_interface_decl->lookupClassMethod(
+ original_selector)) {
+ methods.push_back(class_method_decl);
+ }
- if (!result_method)
- continue;
+ if (methods.empty()) {
+ return false;
+ }
- Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
+ for (NamedDecl *named_decl : methods) {
+ if (!named_decl)
+ continue;
- if (!copied_decl)
- continue;
+ ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
- ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+ if (!result_method)
+ continue;
- if (!copied_method_decl)
- continue;
+ Decl *copied_decl = ast_importer->CopyDecl(
+ ast_context, &result_method->getASTContext(), result_method);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!copied_decl)
+ continue;
- if (log)
- {
- ASTDumper dumper((Decl*)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString());
- }
+ ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
- context.AddNamedDecl(copied_method_decl);
+ if (!copied_method_decl)
+ continue;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ ASTDumper dumper((Decl *)copied_method_decl);
+ log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info,
+ dumper.GetCString());
}
- return true;
+ context.AddNamedDecl(copied_method_decl);
+ }
+
+ return true;
}
-void
-ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- const DeclarationName &decl_name(context.m_decl_name);
- const DeclContext *decl_ctx(context.m_decl_context);
+ const DeclarationName &decl_name(context.m_decl_name);
+ const DeclContext *decl_ctx(context.m_decl_context);
- const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx);
+ const ObjCInterfaceDecl *interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(decl_ctx);
- if (!interface_decl)
- return;
+ if (!interface_decl)
+ return;
- do
- {
- Decl *original_decl = NULL;
- ASTContext *original_ctx = NULL;
+ do {
+ Decl *original_decl = NULL;
+ ASTContext *original_ctx = NULL;
- m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
+ m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl,
+ &original_ctx);
- if (!original_decl)
- break;
+ if (!original_decl)
+ break;
- ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
+ ObjCInterfaceDecl *original_interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(original_decl);
- if (FindObjCMethodDeclsWithOrigin(current_id,
- context,
- original_interface_decl,
- m_ast_context,
- m_ast_importer_sp.get(),
- "at origin"))
- return; // found it, no need to look any further
- } while (0);
+ if (FindObjCMethodDeclsWithOrigin(current_id, context,
+ original_interface_decl, m_ast_context,
+ m_ast_importer_sp.get(), "at origin"))
+ return; // found it, no need to look any further
+ } while (0);
- StreamString ss;
+ StreamString ss;
- if (decl_name.isObjCZeroArgSelector())
- {
- ss.Printf("%s", decl_name.getAsString().c_str());
- }
- else if (decl_name.isObjCOneArgSelector())
- {
- ss.Printf("%s", decl_name.getAsString().c_str());
- }
- else
- {
- clang::Selector sel = decl_name.getObjCSelector();
-
- for (unsigned i = 0, e = sel.getNumArgs();
- i != e;
- ++i)
- {
- llvm::StringRef r = sel.getNameForSlot(i);
- ss.Printf("%s:", r.str().c_str());
- }
+ if (decl_name.isObjCZeroArgSelector()) {
+ ss.Printf("%s", decl_name.getAsString().c_str());
+ } else if (decl_name.isObjCOneArgSelector()) {
+ ss.Printf("%s", decl_name.getAsString().c_str());
+ } else {
+ clang::Selector sel = decl_name.getObjCSelector();
+
+ for (unsigned i = 0, e = sel.getNumArgs(); i != e; ++i) {
+ llvm::StringRef r = sel.getNameForSlot(i);
+ ss.Printf("%s:", r.str().c_str());
}
- ss.Flush();
+ }
+ ss.Flush();
- if (strstr(ss.GetData(), "$__lldb"))
- return; // we don't need any results
+ if (ss.GetString().contains("$__lldb"))
+ return; // we don't need any results
- ConstString selector_name(ss.GetData());
+ ConstString selector_name(ss.GetString());
- if (log)
- log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]",
- current_id, static_cast<void*>(m_ast_context),
- interface_decl->getNameAsString().c_str(),
- selector_name.AsCString());
- SymbolContextList sc_list;
+ if (log)
+ log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p "
+ "for selector [%s %s]",
+ current_id, static_cast<void *>(m_ast_context),
+ interface_decl->getNameAsString().c_str(),
+ selector_name.AsCString());
+ SymbolContextList sc_list;
- const bool include_symbols = false;
- const bool include_inlines = false;
- const bool append = false;
+ const bool include_symbols = false;
+ const bool include_inlines = false;
+ const bool append = false;
- std::string interface_name = interface_decl->getNameAsString();
+ std::string interface_name = interface_decl->getNameAsString();
- do
- {
- StreamString ms;
- ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
- ms.Flush();
- ConstString instance_method_name(ms.GetData());
+ do {
+ StreamString ms;
+ ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
+ ms.Flush();
+ ConstString instance_method_name(ms.GetString());
- m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
+ m_target->GetImages().FindFunctions(
+ instance_method_name, lldb::eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
- if (sc_list.GetSize())
- break;
+ if (sc_list.GetSize())
+ break;
- ms.Clear();
- ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
- ms.Flush();
- ConstString class_method_name(ms.GetData());
+ ms.Clear();
+ ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
+ ms.Flush();
+ ConstString class_method_name(ms.GetString());
- m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
+ m_target->GetImages().FindFunctions(
+ class_method_name, lldb::eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
- if (sc_list.GetSize())
- break;
+ if (sc_list.GetSize())
+ break;
- // Fall back and check for methods in categories. If we find methods this way, we need to check that they're actually in
- // categories on the desired class.
+ // Fall back and check for methods in categories. If we find methods this
+ // way, we need to check that they're actually in
+ // categories on the desired class.
- SymbolContextList candidate_sc_list;
+ SymbolContextList candidate_sc_list;
- m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, candidate_sc_list);
+ m_target->GetImages().FindFunctions(
+ selector_name, lldb::eFunctionNameTypeSelector, include_symbols,
+ include_inlines, append, candidate_sc_list);
- for (uint32_t ci = 0, ce = candidate_sc_list.GetSize();
- ci != ce;
- ++ci)
- {
- SymbolContext candidate_sc;
+ for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) {
+ SymbolContext candidate_sc;
- if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
- continue;
+ if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
+ continue;
- if (!candidate_sc.function)
- continue;
+ if (!candidate_sc.function)
+ continue;
- const char *candidate_name = candidate_sc.function->GetName().AsCString();
+ const char *candidate_name = candidate_sc.function->GetName().AsCString();
- const char *cursor = candidate_name;
+ const char *cursor = candidate_name;
- if (*cursor != '+' && *cursor != '-')
- continue;
+ if (*cursor != '+' && *cursor != '-')
+ continue;
- ++cursor;
+ ++cursor;
- if (*cursor != '[')
- continue;
+ if (*cursor != '[')
+ continue;
- ++cursor;
+ ++cursor;
- size_t interface_len = interface_name.length();
+ size_t interface_len = interface_name.length();
- if (strncmp(cursor, interface_name.c_str(), interface_len))
- continue;
+ if (strncmp(cursor, interface_name.c_str(), interface_len))
+ continue;
- cursor += interface_len;
+ cursor += interface_len;
- if (*cursor == ' ' || *cursor == '(')
- sc_list.Append(candidate_sc);
- }
+ if (*cursor == ' ' || *cursor == '(')
+ sc_list.Append(candidate_sc);
}
- while (0);
-
- if (sc_list.GetSize())
- {
- // We found a good function symbol. Use that.
+ } while (0);
- for (uint32_t i = 0, e = sc_list.GetSize();
- i != e;
- ++i)
- {
- SymbolContext sc;
+ if (sc_list.GetSize()) {
+ // We found a good function symbol. Use that.
- if (!sc_list.GetContextAtIndex(i, sc))
- continue;
+ for (uint32_t i = 0, e = sc_list.GetSize(); i != e; ++i) {
+ SymbolContext sc;
- if (!sc.function)
- continue;
+ if (!sc_list.GetContextAtIndex(i, sc))
+ continue;
- CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext();
- if (!function_decl_ctx)
- continue;
+ if (!sc.function)
+ continue;
- ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext();
+ if (!function_decl_ctx)
+ continue;
- if (!method_decl)
- continue;
+ ObjCMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
- ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
+ if (!method_decl)
+ continue;
- if (!found_interface_decl)
- continue;
+ ObjCInterfaceDecl *found_interface_decl =
+ method_decl->getClassInterface();
- if (found_interface_decl->getName() == interface_decl->getName())
- {
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
+ if (!found_interface_decl)
+ continue;
- if (!copied_decl)
- continue;
+ if (found_interface_decl->getName() == interface_decl->getName()) {
+ Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &method_decl->getASTContext(), method_decl);
- ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+ if (!copied_decl)
+ continue;
- if (!copied_method_decl)
- continue;
+ ObjCMethodDecl *copied_method_decl =
+ dyn_cast<ObjCMethodDecl>(copied_decl);
- if (log)
- {
- ASTDumper dumper((Decl*)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString());
- }
+ if (!copied_method_decl)
+ continue;
- context.AddNamedDecl(copied_method_decl);
- }
+ if (log) {
+ ASTDumper dumper((Decl *)copied_method_decl);
+ log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id,
+ dumper.GetCString());
}
- return;
+ context.AddNamedDecl(copied_method_decl);
+ }
}
- // Try the debug information.
+ return;
+ }
- do
- {
- ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(interface_decl));
+ // Try the debug information.
- if (!complete_interface_decl)
- break;
+ do {
+ ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
+ const_cast<ObjCInterfaceDecl *>(interface_decl));
- // We found the complete interface. The runtime never needs to be queried in this scenario.
+ if (!complete_interface_decl)
+ break;
- DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
+ // We found the complete interface. The runtime never needs to be queried
+ // in this scenario.
- if (complete_interface_decl == interface_decl)
- break; // already checked this one
+ DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
+ complete_interface_decl);
- if (log)
- log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<void*>(complete_interface_decl),
- static_cast<void*>(&complete_iface_decl->getASTContext()));
+ if (complete_interface_decl == interface_decl)
+ break; // already checked this one
+
+ if (log)
+ log->Printf("CAS::FOPD[%d] trying origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id, static_cast<void *>(complete_interface_decl),
+ static_cast<void *>(&complete_iface_decl->getASTContext()));
+
+ FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
+ m_ast_context, m_ast_importer_sp.get(),
+ "in debug info");
+
+ return;
+ } while (0);
+
+ do {
+ // Check the modules only if the debug information didn't have a complete
+ // interface.
+
+ if (ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ ConstString interface_name(interface_decl->getNameAsString().c_str());
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ if (!modules_decl_vendor->FindDecls(interface_name, append, max_matches,
+ decls))
+ break;
+
+ ObjCInterfaceDecl *interface_decl_from_modules =
+ dyn_cast<ObjCInterfaceDecl>(decls[0]);
- FindObjCMethodDeclsWithOrigin(current_id,
- context,
- complete_interface_decl,
- m_ast_context,
- m_ast_importer_sp.get(),
- "in debug info");
+ if (!interface_decl_from_modules)
+ break;
+ if (FindObjCMethodDeclsWithOrigin(
+ current_id, context, interface_decl_from_modules, m_ast_context,
+ m_ast_importer_sp.get(), "in modules"))
return;
}
- while (0);
-
- do
- {
- // Check the modules only if the debug information didn't have a complete interface.
-
- if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- ConstString interface_name(interface_decl->getNameAsString().c_str());
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(interface_name,
- append,
- max_matches,
- decls))
- break;
-
- ObjCInterfaceDecl *interface_decl_from_modules = dyn_cast<ObjCInterfaceDecl>(decls[0]);
-
- if (!interface_decl_from_modules)
- break;
-
- if (FindObjCMethodDeclsWithOrigin(current_id,
- context,
- interface_decl_from_modules,
- m_ast_context,
- m_ast_importer_sp.get(),
- "in modules"))
- return;
- }
- }
- while (0);
+ } while (0);
- do
- {
- // Check the runtime only if the debug information didn't have a complete interface and the modules don't get us anywhere.
+ do {
+ // Check the runtime only if the debug information didn't have a complete
+ // interface and the modules don't get us anywhere.
- lldb::ProcessSP process(m_target->GetProcessSP());
+ lldb::ProcessSP process(m_target->GetProcessSP());
- if (!process)
- break;
+ if (!process)
+ break;
- ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
- if (!language_runtime)
- break;
+ if (!language_runtime)
+ break;
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
- if (!decl_vendor)
- break;
+ if (!decl_vendor)
+ break;
- ConstString interface_name(interface_decl->getNameAsString().c_str());
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
+ ConstString interface_name(interface_decl->getNameAsString().c_str());
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(interface_name,
- append,
- max_matches,
- decls))
- break;
+ if (!decl_vendor->FindDecls(interface_name, append, max_matches, decls))
+ break;
- ObjCInterfaceDecl *runtime_interface_decl = dyn_cast<ObjCInterfaceDecl>(decls[0]);
-
- if (!runtime_interface_decl)
- break;
+ ObjCInterfaceDecl *runtime_interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(decls[0]);
- FindObjCMethodDeclsWithOrigin(current_id,
- context,
- runtime_interface_decl,
- m_ast_context,
- m_ast_importer_sp.get(),
- "in runtime");
- }
- while(0);
+ if (!runtime_interface_decl)
+ break;
+
+ FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl,
+ m_ast_context, m_ast_importer_sp.get(),
+ "in runtime");
+ } while (0);
}
-static bool
-FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
- NameSearchContext &context,
- clang::ASTContext &ast_context,
- ClangASTImporter *ast_importer,
- DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+static bool FindObjCPropertyAndIvarDeclsWithOrigin(
+ unsigned int current_id, NameSearchContext &context,
+ clang::ASTContext &ast_context, ClangASTImporter *ast_importer,
+ DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (origin_iface_decl.IsInvalid())
+ return false;
+
+ std::string name_str = context.m_decl_name.getAsString();
+ StringRef name(name_str);
+ IdentifierInfo &name_identifier(
+ origin_iface_decl->getASTContext().Idents.get(name));
+
+ DeclFromUser<ObjCPropertyDecl> origin_property_decl(
+ origin_iface_decl->FindPropertyDeclaration(
+ &name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance));
+
+ bool found = false;
+
+ if (origin_property_decl.IsValid()) {
+ DeclFromParser<ObjCPropertyDecl> parser_property_decl(
+ origin_property_decl.Import(ast_importer, ast_context));
+ if (parser_property_decl.IsValid()) {
+ if (log) {
+ ASTDumper dumper((Decl *)parser_property_decl.decl);
+ log->Printf(" CAS::FOPD[%d] found %s", current_id,
+ dumper.GetCString());
+ }
+
+ context.AddNamedDecl(parser_property_decl.decl);
+ found = true;
+ }
+ }
+
+ DeclFromUser<ObjCIvarDecl> origin_ivar_decl(
+ origin_iface_decl->getIvarDecl(&name_identifier));
+
+ if (origin_ivar_decl.IsValid()) {
+ DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
+ origin_ivar_decl.Import(ast_importer, ast_context));
+ if (parser_ivar_decl.IsValid()) {
+ if (log) {
+ ASTDumper dumper((Decl *)parser_ivar_decl.decl);
+ log->Printf(" CAS::FOPD[%d] found %s", current_id,
+ dumper.GetCString());
+ }
+
+ context.AddNamedDecl(parser_ivar_decl.decl);
+ found = true;
+ }
+ }
- if (origin_iface_decl.IsInvalid())
- return false;
+ return found;
+}
- std::string name_str = context.m_decl_name.getAsString();
- StringRef name(name_str.c_str());
- IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
+void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance));
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- bool found = false;
+ DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
+ cast<ObjCInterfaceDecl>(context.m_decl_context));
+ DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
+ parser_iface_decl.GetOrigin(m_ast_importer_sp.get()));
- if (origin_property_decl.IsValid())
- {
- DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context));
- if (parser_property_decl.IsValid())
- {
- if (log)
- {
- ASTDumper dumper((Decl*)parser_property_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
- }
+ ConstString class_name(parser_iface_decl->getNameAsString().c_str());
- context.AddNamedDecl(parser_property_decl.decl);
- found = true;
- }
- }
+ if (log)
+ log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on "
+ "(ASTContext*)%p for '%s.%s'",
+ current_id, static_cast<void *>(m_ast_context),
+ parser_iface_decl->getNameAsString().c_str(),
+ context.m_decl_name.getAsString().c_str());
- DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier));
-
- if (origin_ivar_decl.IsValid())
- {
- DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context));
- if (parser_ivar_decl.IsValid())
- {
- if (log)
- {
- ASTDumper dumper((Decl*)parser_ivar_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
- }
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(
+ current_id, context, *m_ast_context, m_ast_importer_sp.get(),
+ origin_iface_decl))
+ return;
- context.AddNamedDecl(parser_ivar_decl.decl);
- found = true;
- }
- }
+ if (log)
+ log->Printf("CAS::FOPD[%d] couldn't find the property on origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching "
+ "elsewhere...",
+ current_id, static_cast<const void *>(origin_iface_decl.decl),
+ static_cast<void *>(&origin_iface_decl->getASTContext()));
- return found;
-}
+ SymbolContext null_sc;
+ TypeList type_list;
-void
-ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ do {
+ ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
+ const_cast<ObjCInterfaceDecl *>(parser_iface_decl.decl));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (!complete_interface_decl)
+ break;
- DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
- DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer_sp.get()));
+ // We found the complete interface. The runtime never needs to be queried
+ // in this scenario.
- ConstString class_name(parser_iface_decl->getNameAsString().c_str());
+ DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
+ complete_interface_decl);
- if (log)
- log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
- current_id, static_cast<void*>(m_ast_context),
- parser_iface_decl->getNameAsString().c_str(),
- context.m_decl_name.getAsString().c_str());
-
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer_sp.get(),
- origin_iface_decl))
- return;
+ if (complete_iface_decl.decl == origin_iface_decl.decl)
+ break; // already checked this one
if (log)
- log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...",
- current_id, static_cast<const void*>(origin_iface_decl.decl),
- static_cast<void*>(&origin_iface_decl->getASTContext()));
+ log->Printf("CAS::FOPD[%d] trying origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ static_cast<const void *>(complete_iface_decl.decl),
+ static_cast<void *>(&complete_iface_decl->getASTContext()));
- SymbolContext null_sc;
- TypeList type_list;
+ FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context,
+ m_ast_importer_sp.get(),
+ complete_iface_decl);
- do
- {
- ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl));
+ return;
+ } while (0);
- if (!complete_interface_decl)
- break;
+ do {
+ // Check the modules only if the debug information didn't have a complete
+ // interface.
- // We found the complete interface. The runtime never needs to be queried in this scenario.
+ ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor();
- DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
+ if (!modules_decl_vendor)
+ break;
- if (complete_iface_decl.decl == origin_iface_decl.decl)
- break; // already checked this one
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (log)
- log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void*>(complete_iface_decl.decl),
- static_cast<void*>(&complete_iface_decl->getASTContext()));
+ if (!modules_decl_vendor->FindDecls(class_name, append, max_matches, decls))
+ break;
- FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer_sp.get(),
- complete_iface_decl);
+ DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(
+ dyn_cast<ObjCInterfaceDecl>(decls[0]));
- return;
- }
- while(0);
-
- do
- {
- // Check the modules only if the debug information didn't have a complete interface.
-
- ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor();
-
- if (!modules_decl_vendor)
- break;
-
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(class_name,
- append,
- max_matches,
- decls))
- break;
-
- DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(dyn_cast<ObjCInterfaceDecl>(decls[0]));
-
- if (!interface_decl_from_modules.IsValid())
- break;
-
- if (log)
- log->Printf("CAS::FOPD[%d] trying module (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void*>(interface_decl_from_modules.decl),
- static_cast<void*>(&interface_decl_from_modules->getASTContext()));
-
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer_sp.get(),
- interface_decl_from_modules))
- return;
- }
- while(0);
+ if (!interface_decl_from_modules.IsValid())
+ break;
- do
- {
- // Check the runtime only if the debug information didn't have a complete interface
- // and nothing was in the modules.
+ if (log)
+ log->Printf(
+ "CAS::FOPD[%d] trying module "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ static_cast<const void *>(interface_decl_from_modules.decl),
+ static_cast<void *>(&interface_decl_from_modules->getASTContext()));
+
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(
+ current_id, context, *m_ast_context, m_ast_importer_sp.get(),
+ interface_decl_from_modules))
+ return;
+ } while (0);
+
+ do {
+ // Check the runtime only if the debug information didn't have a complete
+ // interface
+ // and nothing was in the modules.
- lldb::ProcessSP process(m_target->GetProcessSP());
+ lldb::ProcessSP process(m_target->GetProcessSP());
- if (!process)
- return;
+ if (!process)
+ return;
- ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
- if (!language_runtime)
- return;
+ if (!language_runtime)
+ return;
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
- if (!decl_vendor)
- break;
+ if (!decl_vendor)
+ break;
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(class_name,
- append,
- max_matches,
- decls))
- break;
+ if (!decl_vendor->FindDecls(class_name, append, max_matches, decls))
+ break;
- DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(dyn_cast<ObjCInterfaceDecl>(decls[0]));
-
- if (!interface_decl_from_runtime.IsValid())
- break;
+ DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(
+ dyn_cast<ObjCInterfaceDecl>(decls[0]));
- if (log)
- log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void*>(interface_decl_from_runtime.decl),
- static_cast<void*>(&interface_decl_from_runtime->getASTContext()));
-
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer_sp.get(),
- interface_decl_from_runtime))
- return;
- }
- while(0);
+ if (!interface_decl_from_runtime.IsValid())
+ break;
+
+ if (log)
+ log->Printf(
+ "CAS::FOPD[%d] trying runtime "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ static_cast<const void *>(interface_decl_from_runtime.decl),
+ static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
+
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(
+ current_id, context, *m_ast_context, m_ast_importer_sp.get(),
+ interface_decl_from_runtime))
+ return;
+ } while (0);
}
typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap;
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap;
template <class D, class O>
-static bool
-ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, llvm::DenseMap<const D *, O> &source_map,
- ClangASTImporter *importer, ASTContext &dest_ctx)
-{
- // When importing fields into a new record, clang has a hard requirement that
- // fields be imported in field offset order. Since they are stored in a DenseMap
- // with a pointer as the key type, this means we cannot simply iterate over the
- // map, as the order will be non-deterministic. Instead we have to sort by the offset
- // and then insert in sorted order.
- typedef llvm::DenseMap<const D *, O> MapType;
- typedef typename MapType::value_type PairType;
- 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;
- });
-
- for (const auto &item : sorted_items)
- {
- DeclFromUser<D> user_decl(const_cast<D *>(item.first));
- DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx));
- if (parser_decl.IsInvalid())
- return false;
- destination_map.insert(std::pair<const D *, O>(parser_decl.decl, item.second));
- }
+static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
+ llvm::DenseMap<const D *, O> &source_map,
+ ClangASTImporter *importer, ASTContext &dest_ctx) {
+ // When importing fields into a new record, clang has a hard requirement that
+ // fields be imported in field offset order. Since they are stored in a
+ // DenseMap
+ // with a pointer as the key type, this means we cannot simply iterate over
+ // the
+ // map, as the order will be non-deterministic. Instead we have to sort by
+ // the offset
+ // and then insert in sorted order.
+ typedef llvm::DenseMap<const D *, O> MapType;
+ typedef typename MapType::value_type PairType;
+ 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;
+ });
+
+ for (const auto &item : sorted_items) {
+ DeclFromUser<D> user_decl(const_cast<D *>(item.first));
+ DeclFromParser<D> parser_decl(user_decl.Import(importer, dest_ctx));
+ if (parser_decl.IsInvalid())
+ return false;
+ destination_map.insert(
+ std::pair<const D *, O>(parser_decl.decl, item.second));
+ }
- return true;
+ return true;
}
template <bool IsVirtual>
-bool
-ExtractBaseOffsets(const ASTRecordLayout &record_layout, DeclFromUser<const CXXRecordDecl> &record,
- BaseOffsetMap &base_offsets)
-{
- for (CXXRecordDecl::base_class_const_iterator bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
- be = (IsVirtual ? record->vbases_end() : record->bases_end());
- bi != be; ++bi)
- {
- if (!IsVirtual && bi->isVirtual())
- continue;
+bool ExtractBaseOffsets(const ASTRecordLayout &record_layout,
+ DeclFromUser<const CXXRecordDecl> &record,
+ BaseOffsetMap &base_offsets) {
+ for (CXXRecordDecl::base_class_const_iterator
+ bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
+ be = (IsVirtual ? record->vbases_end() : record->bases_end());
+ bi != be; ++bi) {
+ if (!IsVirtual && bi->isVirtual())
+ continue;
+
+ const clang::Type *origin_base_type = bi->getType().getTypePtr();
+ const clang::RecordType *origin_base_record_type =
+ origin_base_type->getAs<RecordType>();
+
+ if (!origin_base_record_type)
+ return false;
- const clang::Type *origin_base_type = bi->getType().getTypePtr();
- const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
+ DeclFromUser<RecordDecl> origin_base_record(
+ origin_base_record_type->getDecl());
- if (!origin_base_record_type)
- return false;
+ if (origin_base_record.IsInvalid())
+ return false;
- DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
+ DeclFromUser<CXXRecordDecl> origin_base_cxx_record(
+ DynCast<CXXRecordDecl>(origin_base_record));
- if (origin_base_record.IsInvalid())
- return false;
+ if (origin_base_cxx_record.IsInvalid())
+ return false;
- DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
+ CharUnits base_offset;
- if (origin_base_cxx_record.IsInvalid())
- return false;
+ if (IsVirtual)
+ base_offset =
+ record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
+ else
+ base_offset =
+ record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
- CharUnits base_offset;
+ base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(
+ origin_base_cxx_record.decl, base_offset));
+ }
- if (IsVirtual)
- base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
- else
- base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
+ return true;
+}
- base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
- }
+bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
+ uint64_t &alignment,
+ FieldOffsetMap &field_offsets,
+ BaseOffsetMap &base_offsets,
+ BaseOffsetMap &virtual_base_offsets) {
+ ClangASTMetrics::RegisterRecordLayout();
- return true;
-}
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
-bool
-ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint64_t &alignment,
- FieldOffsetMap &field_offsets, BaseOffsetMap &base_offsets,
- BaseOffsetMap &virtual_base_offsets)
-{
- ClangASTMetrics::RegisterRecordLayout();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (log)
+ log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p "
+ "[name = '%s']",
+ current_id, static_cast<void *>(m_ast_context),
+ static_cast<const void *>(record),
+ record->getNameAsString().c_str());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ DeclFromParser<const RecordDecl> parser_record(record);
+ DeclFromUser<const RecordDecl> origin_record(
+ parser_record.GetOrigin(m_ast_importer_sp.get()));
- if (log)
- log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']",
- current_id, static_cast<void*>(m_ast_context),
- static_cast<const void*>(record),
- record->getNameAsString().c_str());
+ if (origin_record.IsInvalid())
+ return false;
+
+ FieldOffsetMap origin_field_offsets;
+ BaseOffsetMap origin_base_offsets;
+ BaseOffsetMap origin_virtual_base_offsets;
- DeclFromParser <const RecordDecl> parser_record(record);
- DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer_sp.get()));
+ ClangASTContext::GetCompleteDecl(
+ &origin_record->getASTContext(),
+ const_cast<RecordDecl *>(origin_record.decl));
- if (origin_record.IsInvalid())
- return false;
+ clang::RecordDecl *definition = origin_record.decl->getDefinition();
+ if (!definition || !definition->isCompleteDefinition())
+ return false;
- FieldOffsetMap origin_field_offsets;
- BaseOffsetMap origin_base_offsets;
- BaseOffsetMap origin_virtual_base_offsets;
+ const ASTRecordLayout &record_layout(
+ origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
- ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl));
+ int field_idx = 0, field_count = record_layout.getFieldCount();
- clang::RecordDecl* definition = origin_record.decl->getDefinition();
- if (!definition || !definition->isCompleteDefinition())
- return false;
+ for (RecordDecl::field_iterator fi = origin_record->field_begin(),
+ fe = origin_record->field_end();
+ fi != fe; ++fi) {
+ if (field_idx >= field_count)
+ return false; // Layout didn't go well. Bail out.
- const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
+ uint64_t field_offset = record_layout.getFieldOffset(field_idx);
- int field_idx = 0, field_count = record_layout.getFieldCount();
+ origin_field_offsets.insert(
+ std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
- for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end(); fi != fe; ++fi)
- {
- if (field_idx >= field_count)
- return false; // Layout didn't go well. Bail out.
+ field_idx++;
+ }
- uint64_t field_offset = record_layout.getFieldOffset(field_idx);
+ ASTContext &parser_ast_context(record->getASTContext());
- origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
+ DeclFromUser<const CXXRecordDecl> origin_cxx_record(
+ DynCast<const CXXRecordDecl>(origin_record));
- field_idx++;
+ if (origin_cxx_record.IsValid()) {
+ if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record,
+ origin_base_offsets) ||
+ !ExtractBaseOffsets<true>(record_layout, origin_cxx_record,
+ origin_virtual_base_offsets))
+ return false;
+ }
+
+ if (!ImportOffsetMap(field_offsets, origin_field_offsets,
+ m_ast_importer_sp.get(), parser_ast_context) ||
+ !ImportOffsetMap(base_offsets, origin_base_offsets,
+ m_ast_importer_sp.get(), parser_ast_context) ||
+ !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets,
+ m_ast_importer_sp.get(), parser_ast_context))
+ return false;
+
+ size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
+ alignment = record_layout.getAlignment().getQuantity() *
+ m_ast_context->getCharWidth();
+
+ if (log) {
+ log->Printf("LRT[%u] returned:", current_id);
+ log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id,
+ static_cast<const void *>(origin_record.decl));
+ log->Printf("LRT[%u] Size = %" PRId64, current_id, size);
+ log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment);
+ log->Printf("LRT[%u] Fields:", current_id);
+ for (RecordDecl::field_iterator fi = record->field_begin(),
+ fe = record->field_end();
+ fi != fe; ++fi) {
+ log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64
+ " bits",
+ current_id, static_cast<void *>(*fi),
+ fi->getNameAsString().c_str(), field_offsets[*fi]);
}
+ DeclFromParser<const CXXRecordDecl> parser_cxx_record =
+ DynCast<const CXXRecordDecl>(parser_record);
+ if (parser_cxx_record.IsValid()) {
+ log->Printf("LRT[%u] Bases:", current_id);
+ for (CXXRecordDecl::base_class_const_iterator
+ bi = parser_cxx_record->bases_begin(),
+ be = parser_cxx_record->bases_end();
+ bi != be; ++bi) {
+ bool is_virtual = bi->isVirtual();
+
+ QualType base_type = bi->getType();
+ const RecordType *base_record_type = base_type->getAs<RecordType>();
+ DeclFromParser<RecordDecl> base_record(base_record_type->getDecl());
+ DeclFromParser<CXXRecordDecl> base_cxx_record =
+ DynCast<CXXRecordDecl>(base_record);
+
+ log->Printf(
+ "LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64
+ " chars",
+ current_id, (is_virtual ? "Virtual " : ""),
+ static_cast<void *>(base_cxx_record.decl),
+ base_cxx_record.decl->getNameAsString().c_str(),
+ (is_virtual
+ ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
+ : base_offsets[base_cxx_record.decl].getQuantity()));
+ }
+ } else {
+ log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
+ }
+ }
- ASTContext &parser_ast_context(record->getASTContext());
+ return true;
+}
- DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
+void ClangASTSource::CompleteNamespaceMap(
+ ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
+ ClangASTImporter::NamespaceMapSP &parent_map) const {
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ if (parent_map && parent_map->size())
+ log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
+ "namespace %s in namespace %s",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString(),
+ parent_map->begin()->second.GetName().AsCString());
+ else
+ log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
+ "namespace %s",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString());
+ }
- if (origin_cxx_record.IsValid())
- {
- if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) ||
- !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets))
- return false;
- }
+ if (parent_map) {
+ for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(),
+ e = parent_map->end();
+ i != e; ++i) {
+ CompilerDeclContext found_namespace_decl;
- if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer_sp.get(), parser_ast_context) ||
- !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer_sp.get(), parser_ast_context) ||
- !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer_sp.get(), parser_ast_context))
- return false;
+ lldb::ModuleSP module_sp = i->first;
+ CompilerDeclContext module_parent_namespace_decl = i->second;
- size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
- alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
+ SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
- if (log)
- {
- log->Printf("LRT[%u] returned:", current_id);
- log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id,
- static_cast<const void*>(origin_record.decl));
- log->Printf("LRT[%u] Size = %" PRId64, current_id, size);
- log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment);
- log->Printf("LRT[%u] Fields:", current_id);
- for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
- fi != fe;
- ++fi)
- {
- log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits", current_id,
- static_cast<void *>(*fi), fi->getNameAsString().c_str(), field_offsets[*fi]);
- }
- DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record);
- if (parser_cxx_record.IsValid())
- {
- log->Printf("LRT[%u] Bases:", current_id);
- for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end();
- bi != be;
- ++bi)
- {
- bool is_virtual = bi->isVirtual();
-
- QualType base_type = bi->getType();
- const RecordType *base_record_type = base_type->getAs<RecordType>();
- DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
- DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
-
- log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", current_id,
- (is_virtual ? "Virtual " : ""), static_cast<void *>(base_cxx_record.decl),
- base_cxx_record.decl->getNameAsString().c_str(),
- (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
- : base_offsets[base_cxx_record.decl].getQuantity()));
- }
- }
- else
- {
- log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
- }
- }
+ if (!symbol_vendor)
+ continue;
- return true;
-}
+ SymbolContext null_sc;
-void
-ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
- const ConstString &name,
- ClangASTImporter::NamespaceMapSP &parent_map) const
-{
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ found_namespace_decl = symbol_vendor->FindNamespace(
+ null_sc, name, &module_parent_namespace_decl);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!found_namespace_decl)
+ continue;
- if (log)
- {
- if (parent_map && parent_map->size())
- log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s",
- current_id, static_cast<void*>(m_ast_context),
- name.GetCString(),
- parent_map->begin()->second.GetName().AsCString());
- else
- log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s",
- current_id, static_cast<void*>(m_ast_context),
- name.GetCString());
+ namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ module_sp, found_namespace_decl));
+
+ if (log)
+ log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
}
+ } else {
+ const ModuleList &target_images = m_target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
- if (parent_map)
- {
- for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end();
- i != e;
- ++i)
- {
- CompilerDeclContext found_namespace_decl;
+ CompilerDeclContext null_namespace_decl;
- lldb::ModuleSP module_sp = i->first;
- CompilerDeclContext module_parent_namespace_decl = i->second;
+ for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
+ lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
+ if (!image)
+ continue;
- if (!symbol_vendor)
- continue;
+ CompilerDeclContext found_namespace_decl;
- SymbolContext null_sc;
+ SymbolVendor *symbol_vendor = image->GetSymbolVendor();
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl);
+ if (!symbol_vendor)
+ continue;
- if (!found_namespace_decl)
- continue;
+ SymbolContext null_sc;
- namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(module_sp, found_namespace_decl));
+ found_namespace_decl =
+ symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
- }
+ if (!found_namespace_decl)
+ continue;
+
+ namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ image, found_namespace_decl));
+
+ if (log)
+ log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
}
- else
- {
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+ }
+}
- CompilerDeclContext null_namespace_decl;
+NamespaceDecl *ClangASTSource::AddNamespace(
+ NameSearchContext &context,
+ ClangASTImporter::NamespaceMapSP &namespace_decls) {
+ if (!namespace_decls)
+ return nullptr;
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
- {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
+ const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
- if (!image)
- continue;
+ clang::ASTContext *src_ast =
+ ClangASTContext::DeclContextGetClangASTContext(namespace_decl);
+ if (!src_ast)
+ return nullptr;
+ clang::NamespaceDecl *src_namespace_decl =
+ ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl);
- CompilerDeclContext found_namespace_decl;
+ if (!src_namespace_decl)
+ return nullptr;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ Decl *copied_decl =
+ m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
- if (!symbol_vendor)
- continue;
+ if (!copied_decl)
+ return nullptr;
- SymbolContext null_sc;
+ NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
+ if (!copied_namespace_decl)
+ return nullptr;
- if (!found_namespace_decl)
- continue;
+ context.m_decls.push_back(copied_namespace_decl);
- namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(image, found_namespace_decl));
+ m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl,
+ namespace_decls);
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
- }
- }
+ return dyn_cast<NamespaceDecl>(copied_decl);
}
-NamespaceDecl *
-ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
-{
- if (!namespace_decls)
- return nullptr;
+CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
+ ClangASTContext *src_ast =
+ llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
+ if (src_ast == nullptr)
+ return CompilerType();
- const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
+ ClangASTMetrics::RegisterLLDBImport();
- clang::ASTContext *src_ast = ClangASTContext::DeclContextGetClangASTContext(namespace_decl);
- if (!src_ast)
- return nullptr;
- clang::NamespaceDecl *src_namespace_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl);
+ SetImportInProgress(true);
- if (!src_namespace_decl)
- return nullptr;
+ QualType copied_qual_type =
+ m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
+ ClangUtil::GetQualType(src_type));
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
+ SetImportInProgress(false);
- if (!copied_decl)
- return nullptr;
+ if (copied_qual_type.getAsOpaquePtr() &&
+ copied_qual_type->getCanonicalTypeInternal().isNull())
+ // this shouldn't happen, but we're hardening because the AST importer seems
+ // to be generating bad types
+ // on occasion.
+ return CompilerType();
- NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
+ return CompilerType(m_ast_context, copied_qual_type);
+}
+
+clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
+ assert(type && "Type for variable must be valid!");
- if (!copied_namespace_decl)
- return nullptr;
+ if (!type.IsValid())
+ return NULL;
+
+ ClangASTContext *lldb_ast =
+ llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return NULL;
- context.m_decls.push_back(copied_namespace_decl);
+ IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
- m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
+ clang::ASTContext *ast = lldb_ast->getASTContext();
- return dyn_cast<NamespaceDecl>(copied_decl);
+ clang::NamedDecl *Decl = VarDecl::Create(
+ *ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
+ SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static);
+ m_decls.push_back(Decl);
+
+ return Decl;
}
-CompilerType
-ClangASTSource::GuardedCopyType (const CompilerType &src_type)
-{
- ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
- if (src_ast == nullptr)
- return CompilerType();
+clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
+ bool extern_c) {
+ assert(type && "Type for variable must be valid!");
- ClangASTMetrics::RegisterLLDBImport();
+ if (!type.IsValid())
+ return NULL;
- SetImportInProgress(true);
+ if (m_function_types.count(type))
+ return NULL;
- QualType copied_qual_type =
- m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), ClangUtil::GetQualType(src_type));
+ ClangASTContext *lldb_ast =
+ llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return NULL;
- SetImportInProgress(false);
+ m_function_types.insert(type);
- if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull())
- // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types
- // on occasion.
- return CompilerType();
+ QualType qual_type(ClangUtil::GetQualType(type));
- return CompilerType(m_ast_context, copied_qual_type);
-}
+ clang::ASTContext *ast = lldb_ast->getASTContext();
-clang::NamedDecl *
-NameSearchContext::AddVarDecl(const CompilerType &type)
-{
- assert (type && "Type for variable must be valid!");
+ const bool isInlineSpecified = false;
+ const bool hasWrittenPrototype = true;
+ const bool isConstexprSpecified = false;
- if (!type.IsValid())
- return NULL;
+ clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
- ClangASTContext* lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return NULL;
-
- IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
+ if (extern_c) {
+ context = LinkageSpecDecl::Create(
+ *ast, context, SourceLocation(), SourceLocation(),
+ clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
+ }
- clang::ASTContext *ast = lldb_ast->getASTContext();
+ // Pass the identifier info for functions the decl_name is needed for
+ // operators
+ clang::DeclarationName decl_name =
+ m_decl_name.getNameKind() == DeclarationName::Identifier
+ ? m_decl_name.getAsIdentifierInfo()
+ : m_decl_name;
- clang::NamedDecl *Decl = VarDecl::Create(*ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
- SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static);
- m_decls.push_back(Decl);
+ clang::FunctionDecl *func_decl = FunctionDecl::Create(
+ *ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
+ NULL, SC_Extern, isInlineSpecified, hasWrittenPrototype,
+ isConstexprSpecified);
- return Decl;
-}
+ // We have to do more than just synthesize the FunctionDecl. We have to
+ // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
+ // this, we raid the function's FunctionProtoType for types.
-clang::NamedDecl *
-NameSearchContext::AddFunDecl (const CompilerType &type, bool extern_c)
-{
- assert (type && "Type for variable must be valid!");
-
- if (!type.IsValid())
- return NULL;
-
- if (m_function_types.count(type))
- return NULL;
-
- ClangASTContext* lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return NULL;
-
- m_function_types.insert(type);
-
- QualType qual_type(ClangUtil::GetQualType(type));
-
- clang::ASTContext *ast = lldb_ast->getASTContext();
-
- const bool isInlineSpecified = false;
- const bool hasWrittenPrototype = true;
- const bool isConstexprSpecified = false;
-
- clang::DeclContext *context = const_cast<DeclContext*>(m_decl_context);
-
- if (extern_c) {
- context = LinkageSpecDecl::Create(*ast,
- context,
- SourceLocation(),
- SourceLocation(),
- clang::LinkageSpecDecl::LanguageIDs::lang_c,
- false);
- }
+ const FunctionProtoType *func_proto_type =
+ qual_type.getTypePtr()->getAs<FunctionProtoType>();
- // Pass the identifier info for functions the decl_name is needed for operators
- clang::DeclarationName decl_name = m_decl_name.getNameKind() == DeclarationName::Identifier ? m_decl_name.getAsIdentifierInfo() : m_decl_name;
-
- clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast,
- context,
- SourceLocation(),
- SourceLocation(),
- decl_name,
- qual_type,
- NULL,
- SC_Extern,
- isInlineSpecified,
- hasWrittenPrototype,
- isConstexprSpecified);
-
- // We have to do more than just synthesize the FunctionDecl. We have to
- // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
- // this, we raid the function's FunctionProtoType for types.
-
- const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>();
-
- if (func_proto_type)
- {
- unsigned NumArgs = func_proto_type->getNumParams();
- unsigned ArgIndex;
-
- SmallVector<ParmVarDecl *, 5> parm_var_decls;
-
- for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex)
- {
- QualType arg_qual_type (func_proto_type->getParamType(ArgIndex));
-
- parm_var_decls.push_back(ParmVarDecl::Create (*ast,
- const_cast<DeclContext*>(context),
- SourceLocation(),
- SourceLocation(),
- NULL,
- arg_qual_type,
- NULL,
- SC_Static,
- NULL));
- }
+ if (func_proto_type) {
+ unsigned NumArgs = func_proto_type->getNumParams();
+ unsigned ArgIndex;
- func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls));
- }
- else
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ SmallVector<ParmVarDecl *, 5> parm_var_decls;
- if (log)
- log->Printf("Function type wasn't a FunctionProtoType");
+ for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
+ QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
+
+ parm_var_decls.push_back(ParmVarDecl::Create(
+ *ast, const_cast<DeclContext *>(context), SourceLocation(),
+ SourceLocation(), NULL, arg_qual_type, NULL, SC_Static, NULL));
}
- m_decls.push_back(func_decl);
+ func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
+ } else {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("Function type wasn't a FunctionProtoType");
+ }
+
+ m_decls.push_back(func_decl);
- return func_decl;
+ return func_decl;
}
-clang::NamedDecl *
-NameSearchContext::AddGenericFunDecl()
-{
- FunctionProtoType::ExtProtoInfo proto_info;
+clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
+ FunctionProtoType::ExtProtoInfo proto_info;
- proto_info.Variadic = true;
+ proto_info.Variadic = true;
- QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy, // result
- ArrayRef<QualType>(), // argument types
- proto_info));
+ QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType(
+ m_ast_source.m_ast_context->UnknownAnyTy, // result
+ ArrayRef<QualType>(), // argument types
+ proto_info));
- return AddFunDecl(CompilerType (m_ast_source.m_ast_context, generic_function_type), true);
+ return AddFunDecl(
+ CompilerType(m_ast_source.m_ast_context, generic_function_type), true);
}
clang::NamedDecl *
-NameSearchContext::AddTypeDecl(const CompilerType &clang_type)
-{
- if (ClangUtil::IsClangType(clang_type))
- {
- QualType qual_type = ClangUtil::GetQualType(clang_type);
+NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
+ if (ClangUtil::IsClangType(clang_type)) {
+ QualType qual_type = ClangUtil::GetQualType(clang_type);
- if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
- {
- TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
+ if (const TypedefType *typedef_type =
+ llvm::dyn_cast<TypedefType>(qual_type)) {
+ TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
- m_decls.push_back(typedef_name_decl);
+ m_decls.push_back(typedef_name_decl);
- return (NamedDecl*)typedef_name_decl;
- }
- else if (const TagType *tag_type = qual_type->getAs<TagType>())
- {
- TagDecl *tag_decl = tag_type->getDecl();
+ return (NamedDecl *)typedef_name_decl;
+ } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
+ TagDecl *tag_decl = tag_type->getDecl();
- m_decls.push_back(tag_decl);
+ m_decls.push_back(tag_decl);
- return tag_decl;
- }
- else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>())
- {
- ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
+ return tag_decl;
+ } else if (const ObjCObjectType *objc_object_type =
+ qual_type->getAs<ObjCObjectType>()) {
+ ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
- m_decls.push_back((NamedDecl*)interface_decl);
+ m_decls.push_back((NamedDecl *)interface_decl);
- return (NamedDecl*)interface_decl;
- }
+ return (NamedDecl *)interface_decl;
}
- return NULL;
+ }
+ return NULL;
}
-void
-NameSearchContext::AddLookupResult (clang::DeclContextLookupResult result)
-{
- for (clang::NamedDecl *decl : result)
- m_decls.push_back (decl);
+void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
+ for (clang::NamedDecl *decl : result)
+ m_decls.push_back(decl);
}
-void
-NameSearchContext::AddNamedDecl (clang::NamedDecl *decl)
-{
- m_decls.push_back (decl);
+void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
+ m_decls.push_back(decl);
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 13791d7e627f..6362f04cf488 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -12,16 +12,16 @@
#include <set>
-#include "clang/Basic/IdentifierTable.h"
-#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
+#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/SmallSet.h"
namespace lldb_private {
-
+
//----------------------------------------------------------------------
/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
/// @brief Provider for named objects defined in the debug info for Clang
@@ -33,494 +33,476 @@ namespace lldb_private {
/// to Clang for these names, consulting the ClangExpressionDeclMap to do
/// the actual lookups.
//----------------------------------------------------------------------
-class ClangASTSource :
- public ClangExternalASTSourceCommon,
- public ClangASTImporter::MapCompleter
-{
+class ClangASTSource : public ClangExternalASTSourceCommon,
+ public ClangASTImporter::MapCompleter {
public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] declMap
- /// A reference to the LLDB object that handles entity lookup.
- //------------------------------------------------------------------
- ClangASTSource (const lldb::TargetSP &target) :
- m_import_in_progress (false),
- m_lookups_enabled (false),
- m_target (target),
- m_ast_context (NULL),
- m_active_lexical_decls (),
- m_active_lookups ()
- {
- m_ast_importer_sp = m_target->GetClangASTImporter();
- }
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangASTSource() override;
-
- //------------------------------------------------------------------
- /// Interface stubs.
- //------------------------------------------------------------------
- clang::Decl *GetExternalDecl (uint32_t) override { return NULL; }
- clang::Stmt *GetExternalDeclStmt (uint64_t) override { return NULL; }
- clang::Selector GetExternalSelector (uint32_t) override { return clang::Selector(); }
- uint32_t GetNumExternalSelectors () override { return 0; }
- clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) override
- { return NULL; }
- void MaterializeVisibleDecls (const clang::DeclContext *DC)
- { return; }
-
- void InstallASTContext (clang::ASTContext *ast_context)
- {
- m_ast_context = ast_context;
- m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] declMap
+ /// A reference to the LLDB object that handles entity lookup.
+ //------------------------------------------------------------------
+ ClangASTSource(const lldb::TargetSP &target)
+ : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
+ m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
+ m_ast_importer_sp = m_target->GetClangASTImporter();
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangASTSource() override;
+
+ //------------------------------------------------------------------
+ /// Interface stubs.
+ //------------------------------------------------------------------
+ clang::Decl *GetExternalDecl(uint32_t) override { return NULL; }
+ clang::Stmt *GetExternalDeclStmt(uint64_t) override { return NULL; }
+ clang::Selector GetExternalSelector(uint32_t) override {
+ return clang::Selector();
+ }
+ uint32_t GetNumExternalSelectors() override { return 0; }
+ clang::CXXBaseSpecifier *
+ GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
+ return NULL;
+ }
+ void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
+
+ void InstallASTContext(clang::ASTContext *ast_context) {
+ m_ast_context = ast_context;
+ m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
+ }
+
+ //
+ // APIs for ExternalASTSource
+ //
+
+ //------------------------------------------------------------------
+ /// Look up all Decls that match a particular name. Only handles
+ /// Identifiers and DeclContexts that are either NamespaceDecls or
+ /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
+ /// the result.
+ ///
+ /// The work for this function is done by
+ /// void FindExternalVisibleDecls (NameSearchContext &);
+ ///
+ /// @param[in] DC
+ /// The DeclContext to register the found Decls in.
+ ///
+ /// @param[in] Name
+ /// The name to find entries for.
+ ///
+ /// @return
+ /// Whatever SetExternalVisibleDeclsForName returns.
+ //------------------------------------------------------------------
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override;
+
+ //------------------------------------------------------------------
+ /// Enumerate all Decls in a given lexical context.
+ ///
+ /// @param[in] DC
+ /// The DeclContext being searched.
+ ///
+ /// @param[in] isKindWeWant
+ /// A callback function that returns true given the
+ /// DeclKinds of desired Decls, and false otherwise.
+ ///
+ /// @param[in] Decls
+ /// A vector that is filled in with matching Decls.
+ //------------------------------------------------------------------
+ void FindExternalLexicalDecls(
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
+
+ //------------------------------------------------------------------
+ /// Specify the layout of the contents of a RecordDecl.
+ ///
+ /// @param[in] Record
+ /// The record (in the parser's AST context) that needs to be
+ /// laid out.
+ ///
+ /// @param[out] Size
+ /// The total size of the record in bits.
+ ///
+ /// @param[out] Alignment
+ /// The alignment of the record in bits.
+ ///
+ /// @param[in] FieldOffsets
+ /// A map that must be populated with pairs of the record's
+ /// fields (in the parser's AST context) and their offsets
+ /// (measured in bits).
+ ///
+ /// @param[in] BaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ concrete base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @param[in] VirtualBaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ virtual base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @return
+ /// True <=> the layout is valid.
+ //-----------------------------------------------------------------
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override;
+
+ //------------------------------------------------------------------
+ /// Complete a TagDecl.
+ ///
+ /// @param[in] Tag
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ void CompleteType(clang::TagDecl *Tag) override;
+
+ //------------------------------------------------------------------
+ /// Complete an ObjCInterfaceDecl.
+ ///
+ /// @param[in] Class
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ void CompleteType(clang::ObjCInterfaceDecl *Class) override;
+
+ //------------------------------------------------------------------
+ /// Called on entering a translation unit. Tells Clang by calling
+ /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
+ /// that this object has something to say about undefined names.
+ ///
+ /// @param[in] ASTConsumer
+ /// Unused.
+ //------------------------------------------------------------------
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
+
+ //
+ // APIs for NamespaceMapCompleter
+ //
+
+ //------------------------------------------------------------------
+ /// Look up the modules containing a given namespace and put the
+ /// appropriate entries in the namespace map.
+ ///
+ /// @param[in] namespace_map
+ /// The map to be completed.
+ ///
+ /// @param[in] name
+ /// The name of the namespace to be found.
+ ///
+ /// @param[in] parent_map
+ /// The map for the namespace's parent namespace, if there is
+ /// one.
+ //------------------------------------------------------------------
+ void CompleteNamespaceMap(
+ ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
+ ClangASTImporter::NamespaceMapSP &parent_map) const override;
+
+ //
+ // Helper APIs
+ //
+
+ clang::NamespaceDecl *
+ AddNamespace(NameSearchContext &context,
+ ClangASTImporter::NamespaceMapSP &namespace_decls);
+
+ //------------------------------------------------------------------
+ /// The worker function for FindExternalVisibleDeclsByName.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when filing results.
+ //------------------------------------------------------------------
+ virtual void FindExternalVisibleDecls(NameSearchContext &context);
+
+ void SetImportInProgress(bool import_in_progress) {
+ m_import_in_progress = import_in_progress;
+ }
+ bool GetImportInProgress() { return m_import_in_progress; }
+
+ void SetLookupsEnabled(bool lookups_enabled) {
+ m_lookups_enabled = lookups_enabled;
+ }
+ bool GetLookupsEnabled() { return m_lookups_enabled; }
+
+ //----------------------------------------------------------------------
+ /// @class ClangASTSourceProxy ClangASTSource.h
+ /// "lldb/Expression/ClangASTSource.h"
+ /// @brief Proxy for ClangASTSource
+ ///
+ /// Clang AST contexts like to own their AST sources, so this is a
+ /// state-free proxy object.
+ //----------------------------------------------------------------------
+ class ClangASTSourceProxy : public ClangExternalASTSourceCommon {
+ public:
+ ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
+
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override {
+ return m_original.FindExternalVisibleDeclsByName(DC, Name);
}
-
- //
- // APIs for ExternalASTSource
- //
-
- //------------------------------------------------------------------
- /// Look up all Decls that match a particular name. Only handles
- /// Identifiers and DeclContexts that are either NamespaceDecls or
- /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
- /// the result.
- ///
- /// The work for this function is done by
- /// void FindExternalVisibleDecls (NameSearchContext &);
- ///
- /// @param[in] DC
- /// The DeclContext to register the found Decls in.
- ///
- /// @param[in] Name
- /// The name to find entries for.
- ///
- /// @return
- /// Whatever SetExternalVisibleDeclsForName returns.
- //------------------------------------------------------------------
- bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override;
-
- //------------------------------------------------------------------
- /// Enumerate all Decls in a given lexical context.
- ///
- /// @param[in] DC
- /// The DeclContext being searched.
- ///
- /// @param[in] isKindWeWant
- /// A callback function that returns true given the
- /// DeclKinds of desired Decls, and false otherwise.
- ///
- /// @param[in] Decls
- /// A vector that is filled in with matching Decls.
- //------------------------------------------------------------------
+
void FindExternalLexicalDecls(
- const clang::DeclContext *DC, llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
- llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
-
- //------------------------------------------------------------------
- /// Specify the layout of the contents of a RecordDecl.
- ///
- /// @param[in] Record
- /// The record (in the parser's AST context) that needs to be
- /// laid out.
- ///
- /// @param[out] Size
- /// The total size of the record in bits.
- ///
- /// @param[out] Alignment
- /// The alignment of the record in bits.
- ///
- /// @param[in] FieldOffsets
- /// A map that must be populated with pairs of the record's
- /// fields (in the parser's AST context) and their offsets
- /// (measured in bits).
- ///
- /// @param[in] BaseOffsets
- /// A map that must be populated with pairs of the record's
- /// C++ concrete base classes (in the parser's AST context,
- /// and only if the record is a CXXRecordDecl and has base
- /// classes) and their offsets (measured in bytes).
- ///
- /// @param[in] VirtualBaseOffsets
- /// A map that must be populated with pairs of the record's
- /// C++ virtual base classes (in the parser's AST context,
- /// and only if the record is a CXXRecordDecl and has base
- /// classes) and their offsets (measured in bytes).
- ///
- /// @return
- /// True <=> the layout is valid.
- //-----------------------------------------------------------------
- bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override;
-
- //------------------------------------------------------------------
- /// Complete a TagDecl.
- ///
- /// @param[in] Tag
- /// The Decl to be completed in place.
- //------------------------------------------------------------------
- void CompleteType(clang::TagDecl *Tag) override;
-
- //------------------------------------------------------------------
- /// Complete an ObjCInterfaceDecl.
- ///
- /// @param[in] Class
- /// The Decl to be completed in place.
- //------------------------------------------------------------------
- void CompleteType(clang::ObjCInterfaceDecl *Class) override;
-
- //------------------------------------------------------------------
- /// Called on entering a translation unit. Tells Clang by calling
- /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
- /// that this object has something to say about undefined names.
- ///
- /// @param[in] ASTConsumer
- /// Unused.
- //------------------------------------------------------------------
- void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
-
- //
- // APIs for NamespaceMapCompleter
- //
-
- //------------------------------------------------------------------
- /// Look up the modules containing a given namespace and put the
- /// appropriate entries in the namespace map.
- ///
- /// @param[in] namespace_map
- /// The map to be completed.
- ///
- /// @param[in] name
- /// The name of the namespace to be found.
- ///
- /// @param[in] parent_map
- /// The map for the namespace's parent namespace, if there is
- /// one.
- //------------------------------------------------------------------
- void CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
- ClangASTImporter::NamespaceMapSP &parent_map) const override;
-
- //
- // Helper APIs
- //
-
- clang::NamespaceDecl *
- AddNamespace (NameSearchContext &context,
- ClangASTImporter::NamespaceMapSP &namespace_decls);
-
- //------------------------------------------------------------------
- /// The worker function for FindExternalVisibleDeclsByName.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when filing results.
- //------------------------------------------------------------------
- virtual void FindExternalVisibleDecls (NameSearchContext &context);
-
- void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
- bool GetImportInProgress () { return m_import_in_progress; }
-
- void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
- bool GetLookupsEnabled () { return m_lookups_enabled; }
-
- //----------------------------------------------------------------------
- /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
- /// @brief Proxy for ClangASTSource
- ///
- /// Clang AST contexts like to own their AST sources, so this is a
- /// state-free proxy object.
- //----------------------------------------------------------------------
- class ClangASTSourceProxy : public ClangExternalASTSourceCommon
- {
- public:
- ClangASTSourceProxy (ClangASTSource &original) :
- m_original(original)
- {
- }
-
- bool
- FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override
- {
- return m_original.FindExternalVisibleDeclsByName(DC, Name);
- }
-
- void
- FindExternalLexicalDecls(const clang::DeclContext *DC,
- llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
- llvm::SmallVectorImpl<clang::Decl *> &Decls) override
- {
- return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
- }
-
- void
- CompleteType(clang::TagDecl *Tag) override
- {
- return m_original.CompleteType(Tag);
- }
-
- void
- CompleteType(clang::ObjCInterfaceDecl *Class) override
- {
- return m_original.CompleteType(Class);
- }
-
- bool
- layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override
- {
- return m_original.layoutRecordType(Record,
- Size,
- Alignment,
- FieldOffsets,
- BaseOffsets,
- VirtualBaseOffsets);
- }
-
- void
- StartTranslationUnit(clang::ASTConsumer *Consumer) override
- {
- return m_original.StartTranslationUnit(Consumer);
- }
-
- ClangASTMetadata *
- GetMetadata(const void * object)
- {
- return m_original.GetMetadata(object);
- }
-
- void
- SetMetadata(const void * object, ClangASTMetadata &metadata)
- {
- return m_original.SetMetadata(object, metadata);
- }
-
- bool
- HasMetadata(const void * object)
- {
- return m_original.HasMetadata(object);
- }
- private:
- ClangASTSource &m_original;
- };
-
- clang::ExternalASTSource *CreateProxy()
- {
- return new ClangASTSourceProxy(*this);
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
+ return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
+ }
+
+ void CompleteType(clang::TagDecl *Tag) override {
+ return m_original.CompleteType(Tag);
+ }
+
+ void CompleteType(clang::ObjCInterfaceDecl *Class) override {
+ return m_original.CompleteType(Class);
}
-
+
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override {
+ return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
+ BaseOffsets, VirtualBaseOffsets);
+ }
+
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
+ return m_original.StartTranslationUnit(Consumer);
+ }
+
+ ClangASTMetadata *GetMetadata(const void *object) {
+ return m_original.GetMetadata(object);
+ }
+
+ void SetMetadata(const void *object, ClangASTMetadata &metadata) {
+ return m_original.SetMetadata(object, metadata);
+ }
+
+ bool HasMetadata(const void *object) {
+ return m_original.HasMetadata(object);
+ }
+
+ private:
+ ClangASTSource &m_original;
+ };
+
+ clang::ExternalASTSource *CreateProxy() {
+ return new ClangASTSourceProxy(*this);
+ }
+
protected:
- //------------------------------------------------------------------
- /// Look for the complete version of an Objective-C interface, and
- /// return it if found.
- ///
- /// @param[in] interface_decl
- /// An ObjCInterfaceDecl that may not be the complete one.
- ///
- /// @return
- /// NULL if the complete interface couldn't be found;
- /// the complete interface otherwise.
- //------------------------------------------------------------------
- clang::ObjCInterfaceDecl *
- GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
-
- //------------------------------------------------------------------
- /// Find all entities matching a given name in a given module,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @param[in] module
- /// If non-NULL, the module to query.
- ///
- /// @param[in] namespace_decl
- /// If valid and module is non-NULL, the parent namespace.
- ///
- /// @param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Find all Objective-C methods matching a given selector.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- /// Its m_decl_name contains the selector and its m_decl_context
- /// is the containing object.
- //------------------------------------------------------------------
- void
- FindObjCMethodDecls (NameSearchContext &context);
-
- //------------------------------------------------------------------
- /// Find all Objective-C properties and ivars with a given name.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- /// Its m_decl_name contains the name and its m_decl_context
- /// is the containing object.
- //------------------------------------------------------------------
- void
- FindObjCPropertyAndIvarDecls (NameSearchContext &context);
-
- //------------------------------------------------------------------
- /// A wrapper for ClangASTContext::CopyType that sets a flag that
- /// indicates that we should not respond to queries during import.
- ///
- /// @param[in] dest_context
- /// The target AST context, typically the parser's AST context.
- ///
- /// @param[in] source_context
- /// The source AST context, typically the AST context of whatever
- /// symbol file the type was found in.
- ///
- /// @param[in] src_type
- /// The source type.
- ///
- /// @return
- /// The imported type.
- //------------------------------------------------------------------
- CompilerType
- GuardedCopyType (const CompilerType &src_type);
-
- friend struct NameSearchContext;
-
- bool m_import_in_progress;
- bool m_lookups_enabled;
-
- const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
- clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
- lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
- std::set<const clang::Decl *> m_active_lexical_decls;
- std::set<const char *> m_active_lookups;
+ //------------------------------------------------------------------
+ /// Look for the complete version of an Objective-C interface, and
+ /// return it if found.
+ ///
+ /// @param[in] interface_decl
+ /// An ObjCInterfaceDecl that may not be the complete one.
+ ///
+ /// @return
+ /// NULL if the complete interface couldn't be found;
+ /// the complete interface otherwise.
+ //------------------------------------------------------------------
+ clang::ObjCInterfaceDecl *
+ GetCompleteObjCInterface(clang::ObjCInterfaceDecl *interface_decl);
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] current_id
+ /// The ID for the current FindExternalVisibleDecls invocation,
+ /// for logging purposes.
+ //------------------------------------------------------------------
+ void FindExternalVisibleDecls(NameSearchContext &context,
+ lldb::ModuleSP module,
+ CompilerDeclContext &namespace_decl,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C methods matching a given selector.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the selector and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void FindObjCMethodDecls(NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C properties and ivars with a given name.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the name and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// A wrapper for ClangASTContext::CopyType that sets a flag that
+ /// indicates that we should not respond to queries during import.
+ ///
+ /// @param[in] dest_context
+ /// The target AST context, typically the parser's AST context.
+ ///
+ /// @param[in] source_context
+ /// The source AST context, typically the AST context of whatever
+ /// symbol file the type was found in.
+ ///
+ /// @param[in] src_type
+ /// The source type.
+ ///
+ /// @return
+ /// The imported type.
+ //------------------------------------------------------------------
+ CompilerType GuardedCopyType(const CompilerType &src_type);
+
+ friend struct NameSearchContext;
+
+ bool m_import_in_progress;
+ bool m_lookups_enabled;
+
+ const lldb::TargetSP
+ m_target; ///< The target to use in finding variables and types.
+ clang::ASTContext
+ *m_ast_context; ///< The AST context requests are coming in for.
+ lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
+ std::set<const clang::Decl *> m_active_lexical_decls;
+ std::set<const char *> m_active_lookups;
};
//----------------------------------------------------------------------
/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
/// @brief Container for all objects relevant to a single name lookup
-///
+///
/// LLDB needs to create Decls for entities it finds. This class communicates
/// what name is being searched for and provides helper functions to construct
/// Decls given appropriate type information.
//----------------------------------------------------------------------
struct NameSearchContext {
- ClangASTSource &m_ast_source; ///< The AST source making the request
- llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed
- ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules
- const clang::DeclarationName &m_decl_name; ///< The name being looked for
- const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into
- llvm::SmallSet <CompilerType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts
-
- struct {
- bool variable : 1;
- bool function_with_type_info : 1;
- bool function : 1;
- bool local_vars_nsp : 1;
- bool type : 1;
- } m_found;
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] astSource
- /// A reference to the AST source making a request.
- ///
- /// @param[in] decls
- /// A reference to a list into which new Decls will be placed. This
- /// list is typically empty when the function is called.
- ///
- /// @param[in] name
- /// The name being searched for (always an Identifier).
- ///
- /// @param[in] dc
- /// The DeclContext to register Decls in.
- //------------------------------------------------------------------
- NameSearchContext (ClangASTSource &astSource,
- llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
- clang::DeclarationName &name,
- const clang::DeclContext *dc) :
- m_ast_source(astSource),
- m_decls(decls),
- m_decl_name(name),
- m_decl_context(dc)
- {
- memset(&m_found, 0, sizeof(m_found));
- }
-
- //------------------------------------------------------------------
- /// Create a VarDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] type
- /// The opaque QualType for the VarDecl being registered.
- //------------------------------------------------------------------
- clang::NamedDecl *AddVarDecl(const CompilerType &type);
-
- //------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] type
- /// The opaque QualType for the FunDecl being registered.
- ///
- /// @param[in] extern_c
- /// If true, build an extern "C" linkage specification for this.
- //------------------------------------------------------------------
- clang::NamedDecl *AddFunDecl(const CompilerType &type,
- bool extern_c = false);
-
- //------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and generic
- /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
- /// right places.
- //------------------------------------------------------------------
- clang::NamedDecl *AddGenericFunDecl();
-
- //------------------------------------------------------------------
- /// Create a TypeDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] compiler_type
- /// The opaque QualType for the TypeDecl being registered.
- //------------------------------------------------------------------
- clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
-
-
- //------------------------------------------------------------------
- /// Add Decls from the provided DeclContextLookupResult to the list
- /// of results.
- ///
- /// @param[in] result
- /// The DeclContextLookupResult, usually returned as the result
- /// of querying a DeclContext.
- //------------------------------------------------------------------
- void AddLookupResult (clang::DeclContextLookupResult result);
-
- //------------------------------------------------------------------
- /// Add a NamedDecl to the list of results.
- ///
- /// @param[in] decl
- /// The NamedDecl, usually returned as the result
- /// of querying a DeclContext.
- //------------------------------------------------------------------
- void AddNamedDecl (clang::NamedDecl *decl);
+ ClangASTSource &m_ast_source; ///< The AST source making the request
+ llvm::SmallVectorImpl<clang::NamedDecl *>
+ &m_decls; ///< The list of declarations already constructed
+ ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all
+ ///namespaces found for this
+ ///request back to their
+ ///modules
+ const clang::DeclarationName &m_decl_name; ///< The name being looked for
+ const clang::DeclContext
+ *m_decl_context; ///< The DeclContext to put declarations into
+ llvm::SmallSet<CompilerType, 5> m_function_types; ///< All the types of
+ ///functions that have been
+ ///reported, so we don't
+ ///report conflicts
+
+ struct {
+ bool variable : 1;
+ bool function_with_type_info : 1;
+ bool function : 1;
+ bool local_vars_nsp : 1;
+ bool type : 1;
+ } m_found;
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] astSource
+ /// A reference to the AST source making a request.
+ ///
+ /// @param[in] decls
+ /// A reference to a list into which new Decls will be placed. This
+ /// list is typically empty when the function is called.
+ ///
+ /// @param[in] name
+ /// The name being searched for (always an Identifier).
+ ///
+ /// @param[in] dc
+ /// The DeclContext to register Decls in.
+ //------------------------------------------------------------------
+ NameSearchContext(ClangASTSource &astSource,
+ llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
+ clang::DeclarationName &name, const clang::DeclContext *dc)
+ : m_ast_source(astSource), m_decls(decls), m_decl_name(name),
+ m_decl_context(dc) {
+ memset(&m_found, 0, sizeof(m_found));
+ }
+
+ //------------------------------------------------------------------
+ /// Create a VarDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the VarDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddVarDecl(const CompilerType &type);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the FunDecl being registered.
+ ///
+ /// @param[in] extern_c
+ /// If true, build an extern "C" linkage specification for this.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and generic
+ /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
+ /// right places.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddGenericFunDecl();
+
+ //------------------------------------------------------------------
+ /// Create a TypeDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] compiler_type
+ /// The opaque QualType for the TypeDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
+
+ //------------------------------------------------------------------
+ /// Add Decls from the provided DeclContextLookupResult to the list
+ /// of results.
+ ///
+ /// @param[in] result
+ /// The DeclContextLookupResult, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddLookupResult(clang::DeclContextLookupResult result);
+
+ //------------------------------------------------------------------
+ /// Add a NamedDecl to the list of results.
+ ///
+ /// @param[in] decl
+ /// The NamedDecl, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddNamedDecl(clang::NamedDecl *decl);
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
index 8273bca105cc..9ea4e3aa7dab 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
@@ -19,42 +19,32 @@
#include "lldb/Expression/DiagnosticManager.h"
-namespace lldb_private
-{
+namespace lldb_private {
-
-class ClangDiagnostic : public Diagnostic
-{
+class ClangDiagnostic : public Diagnostic {
public:
- typedef std::vector<clang::FixItHint> FixItList;
-
- static inline bool classof(const ClangDiagnostic *) { return true; }
- static inline bool classof(const Diagnostic *diag) {
- return diag->getKind() == eDiagnosticOriginClang;
- }
-
- ClangDiagnostic(const char *message, DiagnosticSeverity severity, uint32_t compiler_id) :
- Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id)
- {
- }
-
- virtual ~ClangDiagnostic() = default;
-
- bool HasFixIts () const override { return !m_fixit_vec.empty(); }
-
- void
- AddFixitHint (const clang::FixItHint &fixit)
- {
- m_fixit_vec.push_back(fixit);
- }
-
- const FixItList &
- FixIts() const
- {
- return m_fixit_vec;
- }
- FixItList m_fixit_vec;
+ typedef std::vector<clang::FixItHint> FixItList;
+
+ static inline bool classof(const ClangDiagnostic *) { return true; }
+ static inline bool classof(const Diagnostic *diag) {
+ return diag->getKind() == eDiagnosticOriginClang;
+ }
+
+ ClangDiagnostic(const char *message, DiagnosticSeverity severity,
+ uint32_t compiler_id)
+ : Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id) {}
+
+ virtual ~ClangDiagnostic() = default;
+
+ bool HasFixIts() const override { return !m_fixit_vec.empty(); }
+
+ void AddFixitHint(const clang::FixItHint &fixit) {
+ m_fixit_vec.push_back(fixit);
+ }
+
+ const FixItList &FixIts() const { return m_fixit_vec; }
+ FixItList m_fixit_vec;
};
-} // namespace lldb_private
+} // namespace lldb_private
#endif /* lldb_ClangDiagnostic_h */
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 7aeff6e964fe..c1470c5aeb28 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -14,11 +14,6 @@
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Decl.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
@@ -30,9 +25,9 @@
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
-#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -50,6 +45,11 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
@@ -57,1586 +57,1501 @@ using namespace lldb;
using namespace lldb_private;
using namespace clang;
-namespace
-{
- const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
+namespace {
+const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
} // anonymous namespace
-ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory,
- Materializer::PersistentVariableDelegate *result_delegate,
- ExecutionContext &exe_ctx) :
- ClangASTSource (exe_ctx.GetTargetSP()),
- m_found_entities (),
- m_struct_members (),
- m_keep_result_in_memory (keep_result_in_memory),
- m_result_delegate (result_delegate),
- m_parser_vars (),
- m_struct_vars ()
-{
- EnableStructVars();
+ClangExpressionDeclMap::ClangExpressionDeclMap(
+ bool keep_result_in_memory,
+ Materializer::PersistentVariableDelegate *result_delegate,
+ ExecutionContext &exe_ctx)
+ : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(),
+ m_struct_members(), m_keep_result_in_memory(keep_result_in_memory),
+ m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars() {
+ EnableStructVars();
}
-ClangExpressionDeclMap::~ClangExpressionDeclMap()
-{
- // Note: The model is now that the parser's AST context and all associated
- // data does not vanish until the expression has been executed. This means
- // that valuable lookup data (like namespaces) doesn't vanish, but
+ClangExpressionDeclMap::~ClangExpressionDeclMap() {
+ // Note: The model is now that the parser's AST context and all associated
+ // data does not vanish until the expression has been executed. This means
+ // that valuable lookup data (like namespaces) doesn't vanish, but
- DidParse();
- DisableStructVars();
+ DidParse();
+ DisableStructVars();
}
-bool
-ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
- Materializer *materializer)
-{
- ClangASTMetrics::ClearLocalCounters();
-
- EnableParserVars();
- m_parser_vars->m_exe_ctx = exe_ctx;
-
- Target *target = exe_ctx.GetTargetPtr();
- if (exe_ctx.GetFramePtr())
- m_parser_vars->m_sym_ctx = exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
- else if (exe_ctx.GetThreadPtr() && exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
- m_parser_vars->m_sym_ctx = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
- else if (exe_ctx.GetProcessPtr())
- {
- m_parser_vars->m_sym_ctx.Clear(true);
- m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
- }
- else if (target)
- {
- m_parser_vars->m_sym_ctx.Clear(true);
- m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
- }
-
- if (target)
- {
- m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
-
- if (!target->GetScratchClangASTContext())
- return false;
- }
-
- m_parser_vars->m_target_info = GetTargetInfo();
- m_parser_vars->m_materializer = materializer;
-
- return true;
+bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
+ Materializer *materializer) {
+ ClangASTMetrics::ClearLocalCounters();
+
+ EnableParserVars();
+ m_parser_vars->m_exe_ctx = exe_ctx;
+
+ Target *target = exe_ctx.GetTargetPtr();
+ if (exe_ctx.GetFramePtr())
+ m_parser_vars->m_sym_ctx =
+ exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
+ else if (exe_ctx.GetThreadPtr() &&
+ exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
+ m_parser_vars->m_sym_ctx =
+ exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(
+ lldb::eSymbolContextEverything);
+ else if (exe_ctx.GetProcessPtr()) {
+ m_parser_vars->m_sym_ctx.Clear(true);
+ m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
+ } else if (target) {
+ m_parser_vars->m_sym_ctx.Clear(true);
+ m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
+ }
+
+ if (target) {
+ m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
+ target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
+
+ if (!target->GetScratchClangASTContext())
+ return false;
+ }
+
+ m_parser_vars->m_target_info = GetTargetInfo();
+ m_parser_vars->m_materializer = materializer;
+
+ return true;
}
-void
-ClangExpressionDeclMap::InstallCodeGenerator (clang::ASTConsumer *code_gen)
-{
- assert(m_parser_vars);
- m_parser_vars->m_code_gen = code_gen;
+void ClangExpressionDeclMap::InstallCodeGenerator(
+ clang::ASTConsumer *code_gen) {
+ assert(m_parser_vars);
+ m_parser_vars->m_code_gen = code_gen;
}
-void
-ClangExpressionDeclMap::DidParse()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+void ClangExpressionDeclMap::DidParse() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- ClangASTMetrics::DumpCounters(log);
-
- if (m_parser_vars.get())
- {
- for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
- entity_index < num_entities;
- ++entity_index)
- {
- ExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index));
- if (var_sp)
- llvm::cast<ClangExpressionVariable>(var_sp.get())->DisableParserVars(GetParserID());
- }
+ if (log)
+ ClangASTMetrics::DumpCounters(log);
- for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize();
- pvar_index < num_pvars;
- ++pvar_index)
- {
- ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
- if (ClangExpressionVariable *clang_var = llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
- clang_var->DisableParserVars(GetParserID());
- }
+ if (m_parser_vars.get()) {
+ for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
+ entity_index < num_entities; ++entity_index) {
+ ExpressionVariableSP var_sp(
+ m_found_entities.GetVariableAtIndex(entity_index));
+ if (var_sp)
+ llvm::cast<ClangExpressionVariable>(var_sp.get())
+ ->DisableParserVars(GetParserID());
+ }
- DisableParserVars();
+ for (size_t pvar_index = 0,
+ num_pvars = m_parser_vars->m_persistent_vars->GetSize();
+ pvar_index < num_pvars; ++pvar_index) {
+ ExpressionVariableSP pvar_sp(
+ m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
+ if (ClangExpressionVariable *clang_var =
+ llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
+ clang_var->DisableParserVars(GetParserID());
}
+
+ DisableParserVars();
+ }
}
// Interface for IRForTarget
-ClangExpressionDeclMap::TargetInfo
-ClangExpressionDeclMap::GetTargetInfo()
-{
- assert (m_parser_vars.get());
+ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
+ assert(m_parser_vars.get());
- TargetInfo ret;
+ TargetInfo ret;
- ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
+ ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- ret.byte_order = process->GetByteOrder();
- ret.address_byte_size = process->GetAddressByteSize();
- }
- else
- {
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- ret.byte_order = target->GetArchitecture().GetByteOrder();
- ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
- }
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ ret.byte_order = process->GetByteOrder();
+ ret.address_byte_size = process->GetAddressByteSize();
+ } else {
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ ret.byte_order = target->GetArchitecture().GetByteOrder();
+ ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
}
+ }
- return ret;
+ return ret;
}
-bool
-ClangExpressionDeclMap::AddPersistentVariable
-(
- const NamedDecl *decl,
- const ConstString &name,
- TypeFromParser parser_type,
- bool is_result,
- bool is_lvalue
-)
-{
- assert (m_parser_vars.get());
-
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
- if (ast == nullptr)
- return false;
+bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
+ const ConstString &name,
+ TypeFromParser parser_type,
+ bool is_result,
+ bool is_lvalue) {
+ assert(m_parser_vars.get());
- if (m_parser_vars->m_materializer && is_result)
- {
- Error err;
+ ClangASTContext *ast =
+ llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
+ if (ast == nullptr)
+ return false;
- ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
- Target *target = exe_ctx.GetTargetPtr();
- if (target == nullptr)
- return false;
+ if (m_parser_vars->m_materializer && is_result) {
+ Error err;
- ClangASTContext *context(target->GetScratchClangASTContext());
+ ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target == nullptr)
+ return false;
- TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
- ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
-
- uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(user_type,
- is_lvalue,
- m_keep_result_in_memory,
- m_result_delegate,
- err);
+ ClangASTContext *context(target->GetScratchClangASTContext());
- ClangExpressionVariable *var = new ClangExpressionVariable(exe_ctx.GetBestExecutionContextScope(),
- name,
- user_type,
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size);
+ TypeFromUser user_type(m_ast_importer_sp->DeportType(
+ context->getASTContext(), ast->getASTContext(),
+ parser_type.GetOpaqueQualType()),
+ context);
- m_found_entities.AddNewlyConstructedVariable(var);
-
- var->EnableParserVars(GetParserID());
+ uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
+ user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
- ClangExpressionVariable::ParserVars *parser_vars = var->GetParserVars(GetParserID());
+ ClangExpressionVariable *var = new ClangExpressionVariable(
+ exe_ctx.GetBestExecutionContextScope(), name, user_type,
+ m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size);
- parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
+ m_found_entities.AddNewlyConstructedVariable(var);
- var->EnableJITVars(GetParserID());
+ var->EnableParserVars(GetParserID());
- ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ var->GetParserVars(GetParserID());
- jit_vars->m_offset = offset;
+ parser_vars->m_named_decl = decl;
+ parser_vars->m_parser_type = parser_type;
- return true;
- }
+ var->EnableJITVars(GetParserID());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
- Target *target = exe_ctx.GetTargetPtr();
- if (target == NULL)
- return false;
+ ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
- ClangASTContext *context(target->GetScratchClangASTContext());
+ jit_vars->m_offset = offset;
- TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
- ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
+ return true;
+ }
- if (!user_type.GetOpaqueQualType())
- {
- if (log)
- log->Printf("Persistent variable's type wasn't copied successfully");
- return false;
- }
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target == NULL)
+ return false;
- if (!m_parser_vars->m_target_info.IsValid())
- return false;
+ ClangASTContext *context(target->GetScratchClangASTContext());
- ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx.GetBestExecutionContextScope (),
- name,
- user_type,
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size).get());
+ TypeFromUser user_type(m_ast_importer_sp->DeportType(
+ context->getASTContext(), ast->getASTContext(),
+ parser_type.GetOpaqueQualType()),
+ context);
- if (!var)
- return false;
+ if (!user_type.GetOpaqueQualType()) {
+ if (log)
+ log->Printf("Persistent variable's type wasn't copied successfully");
+ return false;
+ }
- var->m_frozen_sp->SetHasCompleteType();
+ if (!m_parser_vars->m_target_info.IsValid())
+ return false;
- if (is_result)
- var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
- else
- var->m_flags |= ClangExpressionVariable::EVKeepInTarget; // explicitly-declared persistent variables should persist
+ ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(
+ m_parser_vars->m_persistent_vars
+ ->CreatePersistentVariable(
+ exe_ctx.GetBestExecutionContextScope(), name, user_type,
+ m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size)
+ .get());
- if (is_lvalue)
- {
- var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
- }
- else
- {
- var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
- var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
- }
+ if (!var)
+ return false;
- if (m_keep_result_in_memory)
- {
- var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
- }
+ var->m_frozen_sp->SetHasCompleteType();
- if (log)
- log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
+ if (is_result)
+ var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
+ else
+ var->m_flags |=
+ ClangExpressionVariable::EVKeepInTarget; // explicitly-declared
+ // persistent variables should
+ // persist
- var->EnableParserVars(GetParserID());
+ if (is_lvalue) {
+ var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
+ } else {
+ var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
+ var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
+ }
- ClangExpressionVariable::ParserVars *parser_vars = var->GetParserVars(GetParserID());
+ if (m_keep_result_in_memory) {
+ var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
+ }
- parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
+ if (log)
+ log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
- return true;
-}
+ var->EnableParserVars(GetParserID());
-bool
-ClangExpressionDeclMap::AddValueToStruct
-(
- const NamedDecl *decl,
- const ConstString &name,
- llvm::Value *value,
- size_t size,
- lldb::offset_t alignment
-)
-{
- assert (m_struct_vars.get());
- assert (m_parser_vars.get());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ var->GetParserVars(GetParserID());
- bool is_persistent_variable = false;
+ parser_vars->m_named_decl = decl;
+ parser_vars->m_parser_type = parser_type;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ return true;
+}
- m_struct_vars->m_struct_laid_out = false;
+bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
+ const ConstString &name,
+ llvm::Value *value, size_t size,
+ lldb::offset_t alignment) {
+ assert(m_struct_vars.get());
+ assert(m_parser_vars.get());
- if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl, GetParserID()))
- return true;
+ bool is_persistent_variable = false;
- ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(m_found_entities, decl, GetParserID()));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!var)
- {
- var = ClangExpressionVariable::FindVariableInList(*m_parser_vars->m_persistent_vars, decl, GetParserID());
- is_persistent_variable = true;
- }
+ m_struct_vars->m_struct_laid_out = false;
- if (!var)
- return false;
+ if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,
+ GetParserID()))
+ return true;
- if (log)
- log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
- static_cast<const void*>(decl), name.GetCString(),
- var->GetName().GetCString());
+ ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(
+ m_found_entities, decl, GetParserID()));
- // We know entity->m_parser_vars is valid because we used a parser variable
- // to find it
+ if (!var) {
+ var = ClangExpressionVariable::FindVariableInList(
+ *m_parser_vars->m_persistent_vars, decl, GetParserID());
+ is_persistent_variable = true;
+ }
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
+ if (!var)
+ return false;
- parser_vars->m_llvm_value = value;
+ if (log)
+ log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+ static_cast<const void *>(decl), name.GetCString(),
+ var->GetName().GetCString());
- if (ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID()))
- {
- // We already laid this out; do not touch
+ // We know entity->m_parser_vars is valid because we used a parser variable
+ // to find it
- if (log)
- log->Printf("Already placed at 0x%llx", (unsigned long long)jit_vars->m_offset);
- }
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
- llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
+ parser_vars->m_llvm_value = value;
- ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
+ if (ClangExpressionVariable::JITVars *jit_vars =
+ llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
+ // We already laid this out; do not touch
- jit_vars->m_alignment = alignment;
- jit_vars->m_size = size;
+ if (log)
+ log->Printf("Already placed at 0x%llx",
+ (unsigned long long)jit_vars->m_offset);
+ }
- m_struct_members.AddVariable(var->shared_from_this());
+ llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
- if (m_parser_vars->m_materializer)
- {
- uint32_t offset = 0;
+ ClangExpressionVariable::JITVars *jit_vars =
+ llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
- Error err;
+ jit_vars->m_alignment = alignment;
+ jit_vars->m_size = size;
- if (is_persistent_variable)
- {
- ExpressionVariableSP var_sp(var->shared_from_this());
- offset = m_parser_vars->m_materializer->AddPersistentVariable(var_sp, nullptr, err);
- }
- else
- {
- if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
- offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
- else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
- offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
- else if (parser_vars->m_lldb_var)
- offset = m_parser_vars->m_materializer->AddVariable(parser_vars->m_lldb_var, err);
- }
+ m_struct_members.AddVariable(var->shared_from_this());
- if (!err.Success())
- return false;
+ if (m_parser_vars->m_materializer) {
+ uint32_t offset = 0;
- if (log)
- log->Printf("Placed at 0x%llx", (unsigned long long)offset);
+ Error err;
- jit_vars->m_offset = offset; // TODO DoStructLayout() should not change this.
+ if (is_persistent_variable) {
+ ExpressionVariableSP var_sp(var->shared_from_this());
+ offset = m_parser_vars->m_materializer->AddPersistentVariable(
+ var_sp, nullptr, err);
+ } else {
+ if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
+ offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
+ else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
+ offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
+ else if (parser_vars->m_lldb_var)
+ offset = m_parser_vars->m_materializer->AddVariable(
+ parser_vars->m_lldb_var, err);
}
- return true;
-}
-
-bool
-ClangExpressionDeclMap::DoStructLayout ()
-{
- assert (m_struct_vars.get());
+ if (!err.Success())
+ return false;
- if (m_struct_vars->m_struct_laid_out)
- return true;
+ if (log)
+ log->Printf("Placed at 0x%llx", (unsigned long long)offset);
- if (!m_parser_vars->m_materializer)
- return false;
+ jit_vars->m_offset =
+ offset; // TODO DoStructLayout() should not change this.
+ }
- m_struct_vars->m_struct_alignment = m_parser_vars->m_materializer->GetStructAlignment();
- m_struct_vars->m_struct_size = m_parser_vars->m_materializer->GetStructByteSize();
- m_struct_vars->m_struct_laid_out = true;
- return true;
+ return true;
}
-bool ClangExpressionDeclMap::GetStructInfo
-(
- uint32_t &num_elements,
- size_t &size,
- lldb::offset_t &alignment
-)
-{
- assert (m_struct_vars.get());
+bool ClangExpressionDeclMap::DoStructLayout() {
+ assert(m_struct_vars.get());
- if (!m_struct_vars->m_struct_laid_out)
- return false;
+ if (m_struct_vars->m_struct_laid_out)
+ return true;
- num_elements = m_struct_members.GetSize();
- size = m_struct_vars->m_struct_size;
- alignment = m_struct_vars->m_struct_alignment;
+ if (!m_parser_vars->m_materializer)
+ return false;
- return true;
+ m_struct_vars->m_struct_alignment =
+ m_parser_vars->m_materializer->GetStructAlignment();
+ m_struct_vars->m_struct_size =
+ m_parser_vars->m_materializer->GetStructByteSize();
+ m_struct_vars->m_struct_laid_out = true;
+ return true;
}
-bool
-ClangExpressionDeclMap::GetStructElement
-(
- const NamedDecl *&decl,
- llvm::Value *&value,
- lldb::offset_t &offset,
- ConstString &name,
- uint32_t index
-)
-{
- assert (m_struct_vars.get());
-
- if (!m_struct_vars->m_struct_laid_out)
- return false;
+bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,
+ lldb::offset_t &alignment) {
+ assert(m_struct_vars.get());
- if (index >= m_struct_members.GetSize())
- return false;
+ if (!m_struct_vars->m_struct_laid_out)
+ return false;
- ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
+ num_elements = m_struct_members.GetSize();
+ size = m_struct_vars->m_struct_size;
+ alignment = m_struct_vars->m_struct_alignment;
- if (!member_sp)
- return false;
-
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(member_sp.get())->GetParserVars(GetParserID());
- ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(member_sp.get())->GetJITVars(GetParserID());
+ return true;
+}
- if (!parser_vars ||
- !jit_vars ||
- !member_sp->GetValueObject())
- return false;
+bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,
+ llvm::Value *&value,
+ lldb::offset_t &offset,
+ ConstString &name,
+ uint32_t index) {
+ assert(m_struct_vars.get());
- decl = parser_vars->m_named_decl;
- value = parser_vars->m_llvm_value;
- offset = jit_vars->m_offset;
- name = member_sp->GetName();
+ if (!m_struct_vars->m_struct_laid_out)
+ return false;
- return true;
-}
+ if (index >= m_struct_members.GetSize())
+ return false;
-bool
-ClangExpressionDeclMap::GetFunctionInfo
-(
- const NamedDecl *decl,
- uint64_t &ptr
-)
-{
- ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(m_found_entities, decl, GetParserID()));
+ ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
- if (!entity)
- return false;
+ if (!member_sp)
+ return false;
- // We know m_parser_vars is valid since we searched for the variable by
- // its NamedDecl
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(member_sp.get())
+ ->GetParserVars(GetParserID());
+ ClangExpressionVariable::JITVars *jit_vars =
+ llvm::cast<ClangExpressionVariable>(member_sp.get())
+ ->GetJITVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ if (!parser_vars || !jit_vars || !member_sp->GetValueObject())
+ return false;
- ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
+ decl = parser_vars->m_named_decl;
+ value = parser_vars->m_llvm_value;
+ offset = jit_vars->m_offset;
+ name = member_sp->GetName();
- return true;
+ return true;
}
-addr_t
-ClangExpressionDeclMap::GetSymbolAddress (Target &target,
- Process *process,
- const ConstString &name,
- lldb::SymbolType symbol_type,
- lldb_private::Module *module)
-{
- SymbolContextList sc_list;
-
- if (module)
- module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
- else
- target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
-
- const uint32_t num_matches = sc_list.GetSize();
- addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
+bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
+ uint64_t &ptr) {
+ ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(
+ m_found_entities, decl, GetParserID()));
- for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
- {
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(i, sym_ctx);
+ if (!entity)
+ return false;
- const Address sym_address = sym_ctx.symbol->GetAddress();
+ // We know m_parser_vars is valid since we searched for the variable by
+ // its NamedDecl
- if (!sym_address.IsValid())
- continue;
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
- switch (sym_ctx.symbol->GetType())
- {
- case eSymbolTypeCode:
- case eSymbolTypeTrampoline:
- symbol_load_addr = sym_address.GetCallableLoadAddress (&target);
- break;
-
- case eSymbolTypeResolver:
- symbol_load_addr = sym_address.GetCallableLoadAddress (&target, true);
- break;
+ ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
- case eSymbolTypeReExported:
- {
- ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
- if (reexport_name)
- {
- ModuleSP reexport_module_sp;
- ModuleSpec reexport_module_spec;
- reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
- if (reexport_module_spec.GetPlatformFileSpec())
- {
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- if (!reexport_module_sp)
- {
- reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- }
- }
- symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get());
- }
- }
- break;
+ return true;
+}
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeVariable:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeInvalid:
- case eSymbolTypeAbsolute:
- case eSymbolTypeException:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeUndefined:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- symbol_load_addr = sym_address.GetLoadAddress (&target);
- break;
+addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,
+ Process *process,
+ const ConstString &name,
+ lldb::SymbolType symbol_type,
+ lldb_private::Module *module) {
+ SymbolContextList sc_list;
+
+ if (module)
+ module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
+ else
+ target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
+
+ const uint32_t num_matches = sc_list.GetSize();
+ addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
+
+ for (uint32_t i = 0;
+ i < num_matches &&
+ (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS);
+ i++) {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(i, sym_ctx);
+
+ const Address sym_address = sym_ctx.symbol->GetAddress();
+
+ if (!sym_address.IsValid())
+ continue;
+
+ switch (sym_ctx.symbol->GetType()) {
+ case eSymbolTypeCode:
+ case eSymbolTypeTrampoline:
+ symbol_load_addr = sym_address.GetCallableLoadAddress(&target);
+ break;
+
+ case eSymbolTypeResolver:
+ symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);
+ break;
+
+ case eSymbolTypeReExported: {
+ ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
+ if (reexport_name) {
+ ModuleSP reexport_module_sp;
+ ModuleSpec reexport_module_spec;
+ reexport_module_spec.GetPlatformFileSpec() =
+ sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
+ if (reexport_module_spec.GetPlatformFileSpec()) {
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ if (!reexport_module_sp) {
+ reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ }
}
+ symbol_load_addr = GetSymbolAddress(
+ target, process, sym_ctx.symbol->GetReExportedSymbolName(),
+ symbol_type, reexport_module_sp.get());
+ }
+ } break;
+
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeVariable:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeInvalid:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeException:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ symbol_load_addr = sym_address.GetLoadAddress(&target);
+ break;
}
+ }
- if (symbol_load_addr == LLDB_INVALID_ADDRESS && process)
- {
- ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
+ if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {
+ ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
- if (runtime)
- {
- symbol_load_addr = runtime->LookupRuntimeSymbol(name);
- }
+ if (runtime) {
+ symbol_load_addr = runtime->LookupRuntimeSymbol(name);
}
+ }
- return symbol_load_addr;
+ return symbol_load_addr;
}
-addr_t
-ClangExpressionDeclMap::GetSymbolAddress (const ConstString &name, lldb::SymbolType symbol_type)
-{
- assert (m_parser_vars.get());
+addr_t ClangExpressionDeclMap::GetSymbolAddress(const ConstString &name,
+ lldb::SymbolType symbol_type) {
+ assert(m_parser_vars.get());
- if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
- return false;
+ if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
+ return false;
- return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), m_parser_vars->m_exe_ctx.GetProcessPtr(), name, symbol_type);
+ return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),
+ m_parser_vars->m_exe_ctx.GetProcessPtr(), name,
+ symbol_type);
}
-const Symbol *
-ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
- const ConstString &name,
- lldb_private::Module *module)
-{
- SymbolContextList sc_list;
+const Symbol *ClangExpressionDeclMap::FindGlobalDataSymbol(
+ Target &target, const ConstString &name, lldb_private::Module *module) {
+ SymbolContextList sc_list;
- if (module)
- module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
- else
- target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
-
- const uint32_t matches = sc_list.GetSize();
- for (uint32_t i=0; i<matches; ++i)
- {
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(i, sym_ctx);
- if (sym_ctx.symbol)
- {
- const Symbol *symbol = sym_ctx.symbol;
- const Address sym_address = symbol->GetAddress();
-
- if (sym_address.IsValid())
- {
- switch (symbol->GetType())
- {
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeAbsolute:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- if (symbol->GetDemangledNameIsSynthesized())
- {
- // If the demangled name was synthesized, then don't use it
- // for expressions. Only let the symbol match if the mangled
- // named matches for these symbols.
- if (symbol->GetMangled().GetMangledName() != name)
- break;
- }
- return symbol;
-
- case eSymbolTypeReExported:
- {
- ConstString reexport_name = symbol->GetReExportedSymbolName();
- if (reexport_name)
- {
- ModuleSP reexport_module_sp;
- ModuleSpec reexport_module_spec;
- reexport_module_spec.GetPlatformFileSpec() = symbol->GetReExportedSymbolSharedLibrary();
- if (reexport_module_spec.GetPlatformFileSpec())
- {
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- if (!reexport_module_sp)
- {
- reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- }
- }
- // Don't allow us to try and resolve a re-exported symbol if it is the same
- // as the current symbol
- if (name == symbol->GetReExportedSymbolName() && module == reexport_module_sp.get())
- return NULL;
-
- return FindGlobalDataSymbol(target, symbol->GetReExportedSymbolName(), reexport_module_sp.get());
- }
- }
- break;
-
- case eSymbolTypeCode: // We already lookup functions elsewhere
- case eSymbolTypeVariable:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeTrampoline:
- case eSymbolTypeInvalid:
- case eSymbolTypeException:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeUndefined:
- case eSymbolTypeResolver:
- break;
- }
+ if (module)
+ module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
+ else
+ target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny,
+ sc_list);
+
+ const uint32_t matches = sc_list.GetSize();
+ for (uint32_t i = 0; i < matches; ++i) {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(i, sym_ctx);
+ if (sym_ctx.symbol) {
+ const Symbol *symbol = sym_ctx.symbol;
+ const Address sym_address = symbol->GetAddress();
+
+ if (sym_address.IsValid()) {
+ switch (symbol->GetType()) {
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ if (symbol->GetDemangledNameIsSynthesized()) {
+ // If the demangled name was synthesized, then don't use it
+ // for expressions. Only let the symbol match if the mangled
+ // named matches for these symbols.
+ if (symbol->GetMangled().GetMangledName() != name)
+ break;
+ }
+ return symbol;
+
+ case eSymbolTypeReExported: {
+ ConstString reexport_name = symbol->GetReExportedSymbolName();
+ if (reexport_name) {
+ ModuleSP reexport_module_sp;
+ ModuleSpec reexport_module_spec;
+ reexport_module_spec.GetPlatformFileSpec() =
+ symbol->GetReExportedSymbolSharedLibrary();
+ if (reexport_module_spec.GetPlatformFileSpec()) {
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ if (!reexport_module_sp) {
+ reexport_module_spec.GetPlatformFileSpec()
+ .GetDirectory()
+ .Clear();
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ }
}
+ // Don't allow us to try and resolve a re-exported symbol if it is
+ // the same
+ // as the current symbol
+ if (name == symbol->GetReExportedSymbolName() &&
+ module == reexport_module_sp.get())
+ return NULL;
+
+ return FindGlobalDataSymbol(target,
+ symbol->GetReExportedSymbolName(),
+ reexport_module_sp.get());
+ }
+ } break;
+
+ case eSymbolTypeCode: // We already lookup functions elsewhere
+ case eSymbolTypeVariable:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeTrampoline:
+ case eSymbolTypeInvalid:
+ case eSymbolTypeException:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeResolver:
+ break;
}
+ }
}
+ }
- return NULL;
+ return NULL;
}
-lldb::VariableSP
-ClangExpressionDeclMap::FindGlobalVariable
-(
- Target &target,
- ModuleSP &module,
- const ConstString &name,
- CompilerDeclContext *namespace_decl,
- TypeFromUser *type
-)
-{
- VariableList vars;
-
- if (module && namespace_decl)
- module->FindGlobalVariables (name, namespace_decl, true, -1, vars);
- else
- target.GetImages().FindGlobalVariables(name, true, -1, vars);
-
- if (vars.GetSize())
- {
- if (type)
- {
- for (size_t i = 0; i < vars.GetSize(); ++i)
- {
- VariableSP var_sp = vars.GetVariableAtIndex(i);
-
- if (ClangASTContext::AreTypesSame(*type, var_sp->GetType()->GetFullCompilerType ()))
- return var_sp;
- }
- }
- else
- {
- return vars.GetVariableAtIndex(0);
- }
+lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
+ Target &target, ModuleSP &module, const ConstString &name,
+ CompilerDeclContext *namespace_decl, TypeFromUser *type) {
+ VariableList vars;
+
+ if (module && namespace_decl)
+ module->FindGlobalVariables(name, namespace_decl, true, -1, vars);
+ else
+ target.GetImages().FindGlobalVariables(name, true, -1, vars);
+
+ if (vars.GetSize()) {
+ if (type) {
+ for (size_t i = 0; i < vars.GetSize(); ++i) {
+ VariableSP var_sp = vars.GetVariableAtIndex(i);
+
+ if (ClangASTContext::AreTypesSame(
+ *type, var_sp->GetType()->GetFullCompilerType()))
+ return var_sp;
+ }
+ } else {
+ return vars.GetVariableAtIndex(0);
}
+ }
- return VariableSP();
+ return VariableSP();
}
-ClangASTContext *
-ClangExpressionDeclMap::GetClangASTContext ()
-{
- StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
- if (frame == nullptr)
- return nullptr;
+ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
+ StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+ if (frame == nullptr)
+ return nullptr;
- SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
- if (sym_ctx.block == nullptr)
- return nullptr;
+ SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
+ if (sym_ctx.block == nullptr)
+ return nullptr;
- CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
- if (!frame_decl_context)
- return nullptr;
+ CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
+ if (!frame_decl_context)
+ return nullptr;
- return llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
+ return llvm::dyn_cast_or_null<ClangASTContext>(
+ frame_decl_context.GetTypeSystem());
}
// Interface for ClangASTSource
-void
-ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
-{
- assert (m_ast_context);
+void ClangExpressionDeclMap::FindExternalVisibleDecls(
+ NameSearchContext &context) {
+ assert(m_ast_context);
- ClangASTMetrics::RegisterVisibleQuery();
+ ClangASTMetrics::RegisterVisibleQuery();
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ const ConstString name(context.m_decl_name.getAsString().c_str());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (GetImportInProgress())
- {
- if (log && log->GetVerbose())
- log->Printf("Ignoring a query during an import");
- return;
+ if (GetImportInProgress()) {
+ if (log && log->GetVerbose())
+ log->Printf("Ignoring a query during an import");
+ return;
+ }
+
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
+
+ if (log) {
+ if (!context.m_decl_context)
+ log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in a NULL DeclContext",
+ current_id, name.GetCString());
+ else if (const NamedDecl *context_named_decl =
+ dyn_cast<NamedDecl>(context.m_decl_context))
+ log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in '%s'",
+ current_id, name.GetCString(),
+ context_named_decl->getNameAsString().c_str());
+ else
+ log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in a '%s'",
+ current_id, name.GetCString(),
+ context.m_decl_context->getDeclKindName());
+ }
+
+ if (const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(context.m_decl_context)) {
+ if (namespace_context->getName().str() ==
+ std::string(g_lldb_local_vars_namespace_cstr)) {
+ CompilerDeclContext compiler_decl_ctx(
+ GetClangASTContext(), const_cast<void *>(static_cast<const void *>(
+ context.m_decl_context)));
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx,
+ current_id);
+ return;
}
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
- if (log)
- {
- if (!context.m_decl_context)
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext", current_id, name.GetCString());
- else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s'", current_id, name.GetCString(), context_named_decl->getNameAsString().c_str());
- else
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s'", current_id, name.GetCString(), context.m_decl_context->getDeclKindName());
+ if (log && log->GetVerbose())
+ log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
+ current_id, static_cast<void *>(namespace_map.get()),
+ (int)namespace_map->size());
+
+ if (!namespace_map)
+ return;
+
+ for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
+ e = namespace_map->end();
+ i != e; ++i) {
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
+
+ FindExternalVisibleDecls(context, i->first, i->second, current_id);
}
+ } else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
+ CompilerDeclContext namespace_decl;
- if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
- {
- if (namespace_context->getName().str() == std::string(g_lldb_local_vars_namespace_cstr))
- {
- CompilerDeclContext compiler_decl_ctx(GetClangASTContext(), const_cast<void *>(static_cast<const void *>(context.m_decl_context)));
- FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx, current_id);
- return;
- }
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
- ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
+ current_id);
+ }
- if (log && log->GetVerbose())
- log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
- current_id, static_cast<void*>(namespace_map.get()),
- (int)namespace_map->size());
+ if (!context.m_found.variable && !context.m_found.local_vars_nsp)
+ ClangASTSource::FindExternalVisibleDecls(context);
+}
- if (!namespace_map)
- return;
+void ClangExpressionDeclMap::FindExternalVisibleDecls(
+ NameSearchContext &context, lldb::ModuleSP module_sp,
+ CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ assert(m_ast_context);
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
- i != e;
- ++i)
- {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
- current_id,
- i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
-
- FindExternalVisibleDecls(context,
- i->first,
- i->second,
- current_id);
+ std::function<void(clang::FunctionDecl *)> MaybeRegisterFunctionBody =
+ [this](clang::FunctionDecl *copied_function_decl) {
+ if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {
+ DeclGroupRef decl_group_ref(copied_function_decl);
+ m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
}
- }
- else if (isa<TranslationUnitDecl>(context.m_decl_context))
- {
- CompilerDeclContext namespace_decl;
+ };
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- FindExternalVisibleDecls(context,
- lldb::ModuleSP(),
- namespace_decl,
- current_id);
- }
+ SymbolContextList sc_list;
- if (!context.m_found.variable && !context.m_found.local_vars_nsp)
- ClangASTSource::FindExternalVisibleDecls(context);
-}
+ const ConstString name(context.m_decl_name.getAsString().c_str());
-void
-ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id)
-{
- assert (m_ast_context);
-
- std::function<void (clang::FunctionDecl *)> MaybeRegisterFunctionBody =
- [this](clang::FunctionDecl *copied_function_decl)
- {
- if (copied_function_decl->getBody() && m_parser_vars->m_code_gen)
- {
- DeclGroupRef decl_group_ref(copied_function_decl);
- m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
- }
- };
+ const char *name_unique_cstr = name.GetCString();
+
+ if (name_unique_cstr == NULL)
+ return;
+ static ConstString id_name("id");
+ static ConstString Class_name("Class");
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (name == id_name || name == Class_name)
+ return;
- SymbolContextList sc_list;
+ // Only look for functions by name out in our symbols if the function
+ // doesn't start with our phony prefix of '$'
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
+ StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+ SymbolContext sym_ctx;
+ if (frame != nullptr)
+ sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ // Try the persistent decls, which take precedence over all else.
+ if (!namespace_decl) {
+ do {
+ if (!target)
+ break;
- const char *name_unique_cstr = name.GetCString();
+ ClangASTContext *scratch_clang_ast_context =
+ target->GetScratchClangASTContext();
- if (name_unique_cstr == NULL)
- return;
+ if (!scratch_clang_ast_context)
+ break;
- static ConstString id_name("id");
- static ConstString Class_name("Class");
+ ASTContext *scratch_ast_context =
+ scratch_clang_ast_context->getASTContext();
- if (name == id_name || name == Class_name)
- return;
+ if (!scratch_ast_context)
+ break;
- // Only look for functions by name out in our symbols if the function
- // doesn't start with our phony prefix of '$'
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
- SymbolContext sym_ctx;
- if (frame != nullptr)
- sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
-
- // Try the persistent decls, which take precedence over all else.
- if (!namespace_decl)
- {
- do
- {
- if (!target)
- break;
-
- ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext();
-
- if (!scratch_clang_ast_context)
- break;
-
- ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
-
- if (!scratch_ast_context)
- break;
-
- NamedDecl *persistent_decl = m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
-
- if (!persistent_decl)
- break;
-
- Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, persistent_decl);
-
- if (!parser_persistent_decl)
- break;
-
- NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl);
-
- if (!parser_named_decl)
- break;
-
- if (clang::FunctionDecl *parser_function_decl = llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl))
- {
- MaybeRegisterFunctionBody(parser_function_decl);
- }
-
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id, name.GetCString());
-
- context.AddNamedDecl(parser_named_decl);
- } while (0);
- }
-
- if (name_unique_cstr[0] == '$' && !namespace_decl)
- {
- static ConstString g_lldb_class_name ("$__lldb_class");
+ NamedDecl *persistent_decl =
+ m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
- if (name == g_lldb_class_name)
- {
- // Clang is looking for the type of "this"
+ if (!persistent_decl)
+ break;
- if (frame == NULL)
- return;
+ Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, scratch_ast_context, persistent_decl);
+ if (!parser_persistent_decl)
+ break;
- // Find the block that defines the function represented by "sym_ctx"
- Block *function_block = sym_ctx.GetFunctionBlock();
+ NamedDecl *parser_named_decl =
+ dyn_cast<NamedDecl>(parser_persistent_decl);
- if (!function_block)
- return;
+ if (!parser_named_decl)
+ break;
- CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
+ if (clang::FunctionDecl *parser_function_decl =
+ llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {
+ MaybeRegisterFunctionBody(parser_function_decl);
+ }
- if (!function_decl_ctx)
- return;
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id,
+ name.GetCString());
- clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
+ context.AddNamedDecl(parser_named_decl);
+ } while (0);
+ }
- if (method_decl)
- {
- clang::CXXRecordDecl *class_decl = method_decl->getParent();
+ if (name_unique_cstr[0] == '$' && !namespace_decl) {
+ static ConstString g_lldb_class_name("$__lldb_class");
- QualType class_qual_type(class_decl->getTypeForDecl(), 0);
+ if (name == g_lldb_class_name) {
+ // Clang is looking for the type of "this"
- TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&class_decl->getASTContext()));
+ if (frame == NULL)
+ return;
- if (log)
- {
- ASTDumper ast_dumper(class_qual_type);
- log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
- }
+ // Find the block that defines the function represented by "sym_ctx"
+ Block *function_block = sym_ctx.GetFunctionBlock();
- AddThisType(context, class_user_type, current_id);
+ if (!function_block)
+ return;
- if (method_decl->isInstance())
- {
- // self is a pointer to the object
+ CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
- QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type);
+ if (!function_decl_ctx)
+ return;
- TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+ clang::CXXMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
- m_struct_vars->m_object_pointer_type = self_user_type;
- }
- }
- else
- {
- // This branch will get hit if we are executing code in the context of a function that
- // claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
- // method of the class. In that case, just look up the "this" variable in the current
- // scope and use its type.
- // FIXME: This code is formally correct, but clang doesn't currently emit DW_AT_object_pointer
- // for C++ so it hasn't actually been tested.
-
- VariableList *vars = frame->GetVariableList(false);
-
- lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
-
- if (this_var &&
- this_var->IsInScope(frame) &&
- this_var->LocationIsValidForFrame (frame))
- {
- Type *this_type = this_var->GetType();
-
- if (!this_type)
- return;
-
- TypeFromUser pointee_type = this_type->GetForwardCompilerType ().GetPointeeType();
-
- if (pointee_type.IsValid())
- {
- if (log)
- {
- ASTDumper ast_dumper(pointee_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
- }
-
- AddThisType(context, pointee_type, current_id);
- TypeFromUser this_user_type(this_type->GetFullCompilerType ());
- m_struct_vars->m_object_pointer_type = this_user_type;
- return;
- }
- }
+ if (method_decl) {
+ clang::CXXRecordDecl *class_decl = method_decl->getParent();
+
+ QualType class_qual_type(class_decl->getTypeForDecl(), 0);
+
+ TypeFromUser class_user_type(
+ class_qual_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&class_decl->getASTContext()));
+
+ if (log) {
+ ASTDumper ast_dumper(class_qual_type);
+ log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
+ current_id, ast_dumper.GetCString());
+ }
+
+ AddThisType(context, class_user_type, current_id);
+
+ if (method_decl->isInstance()) {
+ // self is a pointer to the object
+
+ QualType class_pointer_type =
+ method_decl->getASTContext().getPointerType(class_qual_type);
+
+ TypeFromUser self_user_type(
+ class_pointer_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+
+ m_struct_vars->m_object_pointer_type = self_user_type;
+ }
+ } else {
+ // This branch will get hit if we are executing code in the context of a
+ // function that
+ // claims to have an object pointer (through DW_AT_object_pointer?) but
+ // is not formally a
+ // method of the class. In that case, just look up the "this" variable
+ // in the current
+ // scope and use its type.
+ // FIXME: This code is formally correct, but clang doesn't currently
+ // emit DW_AT_object_pointer
+ // for C++ so it hasn't actually been tested.
+
+ VariableList *vars = frame->GetVariableList(false);
+
+ lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
+
+ if (this_var && this_var->IsInScope(frame) &&
+ this_var->LocationIsValidForFrame(frame)) {
+ Type *this_type = this_var->GetType();
+
+ if (!this_type)
+ return;
+
+ TypeFromUser pointee_type =
+ this_type->GetForwardCompilerType().GetPointeeType();
+
+ if (pointee_type.IsValid()) {
+ if (log) {
+ ASTDumper ast_dumper(pointee_type);
+ log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s",
+ current_id, ast_dumper.GetCString());
}
+ AddThisType(context, pointee_type, current_id);
+ TypeFromUser this_user_type(this_type->GetFullCompilerType());
+ m_struct_vars->m_object_pointer_type = this_user_type;
return;
+ }
}
+ }
- static ConstString g_lldb_objc_class_name ("$__lldb_objc_class");
- if (name == g_lldb_objc_class_name)
- {
- // Clang is looking for the type of "*self"
+ return;
+ }
- if (!frame)
- return;
+ static ConstString g_lldb_objc_class_name("$__lldb_objc_class");
+ if (name == g_lldb_objc_class_name) {
+ // Clang is looking for the type of "*self"
- SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
+ if (!frame)
+ return;
- // Find the block that defines the function represented by "sym_ctx"
- Block *function_block = sym_ctx.GetFunctionBlock();
+ SymbolContext sym_ctx = frame->GetSymbolContext(
+ lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
- if (!function_block)
- return;
+ // Find the block that defines the function represented by "sym_ctx"
+ Block *function_block = sym_ctx.GetFunctionBlock();
- CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
+ if (!function_block)
+ return;
- if (!function_decl_ctx)
- return;
+ CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
- clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ if (!function_decl_ctx)
+ return;
- if (method_decl)
- {
- ObjCInterfaceDecl* self_interface = method_decl->getClassInterface();
+ clang::ObjCMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
- if (!self_interface)
- return;
+ if (method_decl) {
+ ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
- const clang::Type *interface_type = self_interface->getTypeForDecl();
+ if (!self_interface)
+ return;
- if (!interface_type)
- return; // This is unlikely, but we have seen crashes where this occurred
+ const clang::Type *interface_type = self_interface->getTypeForDecl();
- TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+ if (!interface_type)
+ return; // This is unlikely, but we have seen crashes where this
+ // occurred
- if (log)
- {
- ASTDumper ast_dumper(interface_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
- }
+ TypeFromUser class_user_type(
+ QualType(interface_type, 0).getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
- AddOneType(context, class_user_type, current_id);
+ if (log) {
+ ASTDumper ast_dumper(interface_type);
+ log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
+ }
- if (method_decl->isInstanceMethod())
- {
- // self is a pointer to the object
+ AddOneType(context, class_user_type, current_id);
- QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0));
+ if (method_decl->isInstanceMethod()) {
+ // self is a pointer to the object
- TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+ QualType class_pointer_type =
+ method_decl->getASTContext().getObjCObjectPointerType(
+ QualType(interface_type, 0));
- m_struct_vars->m_object_pointer_type = self_user_type;
- }
- else
- {
- // self is a Class pointer
- QualType class_type = method_decl->getASTContext().getObjCClassType();
+ TypeFromUser self_user_type(
+ class_pointer_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
- TypeFromUser self_user_type(class_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+ m_struct_vars->m_object_pointer_type = self_user_type;
+ } else {
+ // self is a Class pointer
+ QualType class_type = method_decl->getASTContext().getObjCClassType();
- m_struct_vars->m_object_pointer_type = self_user_type;
- }
+ TypeFromUser self_user_type(
+ class_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
- return;
- }
- else
- {
- // This branch will get hit if we are executing code in the context of a function that
- // claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
- // method of the class. In that case, just look up the "self" variable in the current
- // scope and use its type.
+ m_struct_vars->m_object_pointer_type = self_user_type;
+ }
- VariableList *vars = frame->GetVariableList(false);
+ return;
+ } else {
+ // This branch will get hit if we are executing code in the context of a
+ // function that
+ // claims to have an object pointer (through DW_AT_object_pointer?) but
+ // is not formally a
+ // method of the class. In that case, just look up the "self" variable
+ // in the current
+ // scope and use its type.
- lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
+ VariableList *vars = frame->GetVariableList(false);
- if (self_var &&
- self_var->IsInScope(frame) &&
- self_var->LocationIsValidForFrame (frame))
- {
- Type *self_type = self_var->GetType();
+ lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
- if (!self_type)
- return;
+ if (self_var && self_var->IsInScope(frame) &&
+ self_var->LocationIsValidForFrame(frame)) {
+ Type *self_type = self_var->GetType();
- CompilerType self_clang_type = self_type->GetFullCompilerType ();
+ if (!self_type)
+ return;
- if (ClangASTContext::IsObjCClassType(self_clang_type))
- {
- return;
- }
- else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
- {
- self_clang_type = self_clang_type.GetPointeeType();
+ CompilerType self_clang_type = self_type->GetFullCompilerType();
- if (!self_clang_type)
- return;
+ if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ return;
+ } else if (ClangASTContext::IsObjCObjectPointerType(
+ self_clang_type)) {
+ self_clang_type = self_clang_type.GetPointeeType();
- if (log)
- {
- ASTDumper ast_dumper(self_type->GetFullCompilerType ());
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
- }
+ if (!self_clang_type)
+ return;
- TypeFromUser class_user_type (self_clang_type);
+ if (log) {
+ ASTDumper ast_dumper(self_type->GetFullCompilerType());
+ log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
+ }
- AddOneType(context, class_user_type, current_id);
+ TypeFromUser class_user_type(self_clang_type);
- TypeFromUser self_user_type(self_type->GetFullCompilerType ());
+ AddOneType(context, class_user_type, current_id);
- m_struct_vars->m_object_pointer_type = self_user_type;
- return;
- }
- }
- }
+ TypeFromUser self_user_type(self_type->GetFullCompilerType());
+ m_struct_vars->m_object_pointer_type = self_user_type;
return;
+ }
}
+ }
- if (name == ConstString(g_lldb_local_vars_namespace_cstr))
- {
- CompilerDeclContext frame_decl_context = sym_ctx.block != nullptr ?
- sym_ctx.block->GetDeclContext() :
- CompilerDeclContext();
-
- if (frame_decl_context)
- {
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
-
- if (ast)
- {
- clang::NamespaceDecl *namespace_decl = ClangASTContext::GetUniqueNamespaceDeclaration(
- m_ast_context, name_unique_cstr, nullptr);
- if (namespace_decl)
- {
- context.AddNamedDecl(namespace_decl);
- clang::DeclContext *clang_decl_ctx = clang::Decl::castToDeclContext(namespace_decl);
- clang_decl_ctx->setHasExternalVisibleStorage(true);
- context.m_found.local_vars_nsp = true;
- }
- }
- }
+ return;
+ }
- return;
+ if (name == ConstString(g_lldb_local_vars_namespace_cstr)) {
+ CompilerDeclContext frame_decl_context =
+ sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
+ : CompilerDeclContext();
+
+ if (frame_decl_context) {
+ ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ frame_decl_context.GetTypeSystem());
+
+ if (ast) {
+ clang::NamespaceDecl *namespace_decl =
+ ClangASTContext::GetUniqueNamespaceDeclaration(
+ m_ast_context, name_unique_cstr, nullptr);
+ if (namespace_decl) {
+ context.AddNamedDecl(namespace_decl);
+ clang::DeclContext *clang_decl_ctx =
+ clang::Decl::castToDeclContext(namespace_decl);
+ clang_decl_ctx->setHasExternalVisibleStorage(true);
+ context.m_found.local_vars_nsp = true;
+ }
}
+ }
- // any other $__lldb names should be weeded out now
- if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
- return;
+ return;
+ }
- ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name));
+ // any other $__lldb names should be weeded out now
+ if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
+ return;
- if (pvar_sp)
- {
- AddOneVariable(context, pvar_sp, current_id);
- return;
- }
+ ExpressionVariableSP pvar_sp(
+ m_parser_vars->m_persistent_vars->GetVariable(name));
- const char *reg_name(&name.GetCString()[1]);
+ if (pvar_sp) {
+ AddOneVariable(context, pvar_sp, current_id);
+ return;
+ }
- if (m_parser_vars->m_exe_ctx.GetRegisterContext())
- {
- const RegisterInfo *reg_info(m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name));
+ const char *reg_name(&name.GetCString()[1]);
- if (reg_info)
- {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found register %s", current_id, reg_info->name);
+ if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
+ const RegisterInfo *reg_info(
+ m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
+ reg_name));
- AddOneRegister(context, reg_info, current_id);
- }
- }
+ if (reg_info) {
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Found register %s", current_id,
+ reg_info->name);
+
+ AddOneRegister(context, reg_info, current_id);
+ }
}
- else
- {
- ValueObjectSP valobj;
- VariableSP var;
-
- bool local_var_lookup = !namespace_decl ||
- (namespace_decl.GetName() == ConstString(g_lldb_local_vars_namespace_cstr));
- if (frame && local_var_lookup)
- {
- CompilerDeclContext compiler_decl_context = sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext() : CompilerDeclContext();
-
- if (compiler_decl_context)
- {
- // Make sure that the variables are parsed so that we have the declarations.
- VariableListSP vars = frame->GetInScopeVariableList(true);
- for (size_t i = 0; i < vars->GetSize(); i++)
- vars->GetVariableAtIndex(i)->GetDecl();
-
- // Search for declarations matching the name. Do not include imported decls
- // in the search if we are looking for decls in the artificial namespace
- // $__lldb_local_vars.
- std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name, namespace_decl.IsValid());
-
- bool variable_found = false;
- for (CompilerDecl decl : found_decls)
- {
- for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi)
- {
- VariableSP candidate_var = vars->GetVariableAtIndex(vi);
- if (candidate_var->GetDecl() == decl)
- {
- var = candidate_var;
- break;
- }
- }
-
- if (var)
- {
- variable_found = true;
- valobj = ValueObjectVariable::Create(frame, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
- }
- }
- if (variable_found)
- return;
+ } else {
+ ValueObjectSP valobj;
+ VariableSP var;
+
+ bool local_var_lookup =
+ !namespace_decl || (namespace_decl.GetName() ==
+ ConstString(g_lldb_local_vars_namespace_cstr));
+ if (frame && local_var_lookup) {
+ CompilerDeclContext compiler_decl_context =
+ sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
+ : CompilerDeclContext();
+
+ if (compiler_decl_context) {
+ // Make sure that the variables are parsed so that we have the
+ // declarations.
+ VariableListSP vars = frame->GetInScopeVariableList(true);
+ for (size_t i = 0; i < vars->GetSize(); i++)
+ vars->GetVariableAtIndex(i)->GetDecl();
+
+ // Search for declarations matching the name. Do not include imported
+ // decls
+ // in the search if we are looking for decls in the artificial namespace
+ // $__lldb_local_vars.
+ std::vector<CompilerDecl> found_decls =
+ compiler_decl_context.FindDeclByName(name,
+ namespace_decl.IsValid());
+
+ bool variable_found = false;
+ for (CompilerDecl decl : found_decls) {
+ for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
+ VariableSP candidate_var = vars->GetVariableAtIndex(vi);
+ if (candidate_var->GetDecl() == decl) {
+ var = candidate_var;
+ break;
}
+ }
+
+ if (var) {
+ variable_found = true;
+ valobj = ValueObjectVariable::Create(frame, var);
+ AddOneVariable(context, var, valobj, current_id);
+ context.m_found.variable = true;
+ }
}
- if (target)
- {
- var = FindGlobalVariable (*target,
- module_sp,
- name,
- &namespace_decl,
- NULL);
-
- if (var)
- {
- valobj = ValueObjectVariable::Create(target, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
- return;
+ if (variable_found)
+ return;
+ }
+ }
+ if (target) {
+ var = FindGlobalVariable(*target, module_sp, name, &namespace_decl, NULL);
+
+ if (var) {
+ valobj = ValueObjectVariable::Create(target, var);
+ AddOneVariable(context, var, valobj, current_id);
+ context.m_found.variable = true;
+ return;
+ }
+ }
+
+ std::vector<clang::NamedDecl *> decls_from_modules;
+
+ if (target) {
+ if (ClangModulesDeclVendor *decl_vendor =
+ target->GetClangModulesDeclVendor()) {
+ decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
+ }
+ }
+
+ if (!context.m_found.variable) {
+ const bool include_inlines = false;
+ const bool append = false;
+
+ if (namespace_decl && module_sp) {
+ const bool include_symbols = false;
+
+ module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
+ include_symbols, include_inlines, append,
+ sc_list);
+ } else if (target && !namespace_decl) {
+ const bool include_symbols = true;
+
+ // TODO Fix FindFunctions so that it doesn't return
+ // instance methods for eFunctionNameTypeBase.
+
+ target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
+ include_symbols, include_inlines,
+ append, sc_list);
+ }
+
+ // If we found more than one function, see if we can use the
+ // frame's decl context to remove functions that are shadowed
+ // by other functions which match in type but are nearer in scope.
+ //
+ // AddOneFunction will not add a function whose type has already been
+ // added, so if there's another function in the list with a matching
+ // type, check to see if their decl context is a parent of the current
+ // frame's or was imported via a and using statement, and pick the
+ // best match according to lookup rules.
+ if (sc_list.GetSize() > 1) {
+ // Collect some info about our frame's context.
+ StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+ SymbolContext frame_sym_ctx;
+ if (frame != nullptr)
+ frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
+ CompilerDeclContext frame_decl_context =
+ frame_sym_ctx.block != nullptr
+ ? frame_sym_ctx.block->GetDeclContext()
+ : CompilerDeclContext();
+
+ // We can't do this without a compiler decl context for our frame.
+ if (frame_decl_context) {
+ clang::DeclContext *frame_decl_ctx =
+ (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
+ ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ frame_decl_context.GetTypeSystem());
+
+ // Structure to hold the info needed when comparing function
+ // declarations.
+ struct FuncDeclInfo {
+ ConstString m_name;
+ CompilerType m_copied_type;
+ uint32_t m_decl_lvl;
+ SymbolContext m_sym_ctx;
+ };
+
+ // First, symplify things by looping through the symbol contexts
+ // to remove unwanted functions and separate out the functions we
+ // want to compare and prune into a separate list.
+ // Cache the info needed about the function declarations in a
+ // vector for efficiency.
+ SymbolContextList sc_sym_list;
+ uint32_t num_indices = sc_list.GetSize();
+ std::vector<FuncDeclInfo> fdi_cache;
+ fdi_cache.reserve(num_indices);
+ for (uint32_t index = 0; index < num_indices; ++index) {
+ FuncDeclInfo fdi;
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(index, sym_ctx);
+
+ // We don't know enough about symbols to compare them,
+ // but we should keep them in the list.
+ Function *function = sym_ctx.function;
+ if (!function) {
+ sc_sym_list.Append(sym_ctx);
+ continue;
}
- }
-
- std::vector<clang::NamedDecl *> decls_from_modules;
-
- if (target)
- {
- if (ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor())
- {
- decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
+ // Filter out functions without declaration contexts, as well as
+ // class/instance methods, since they'll be skipped in the
+ // code that follows anyway.
+ CompilerDeclContext func_decl_context = function->GetDeclContext();
+ if (!func_decl_context ||
+ func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
+ continue;
+ // We can only prune functions for which we can copy the type.
+ CompilerType func_clang_type =
+ function->GetType()->GetFullCompilerType();
+ CompilerType copied_func_type = GuardedCopyType(func_clang_type);
+ if (!copied_func_type) {
+ sc_sym_list.Append(sym_ctx);
+ continue;
}
- }
- if (!context.m_found.variable)
- {
- const bool include_inlines = false;
- const bool append = false;
-
- if (namespace_decl && module_sp)
- {
- const bool include_symbols = false;
-
- module_sp->FindFunctions(name,
- &namespace_decl,
- eFunctionNameTypeBase,
- include_symbols,
- include_inlines,
- append,
- sc_list);
+ fdi.m_sym_ctx = sym_ctx;
+ fdi.m_name = function->GetName();
+ fdi.m_copied_type = copied_func_type;
+ fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
+ if (fdi.m_copied_type && func_decl_context) {
+ // Call CountDeclLevels to get the number of parent scopes we
+ // have to look through before we find the function declaration.
+ // When comparing functions of the same type, the one with a
+ // lower count will be closer to us in the lookup scope and
+ // shadows the other.
+ clang::DeclContext *func_decl_ctx =
+ (clang::DeclContext *)
+ func_decl_context.GetOpaqueDeclContext();
+ fdi.m_decl_lvl =
+ ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
+ &fdi.m_name, &fdi.m_copied_type);
}
- else if (target && !namespace_decl)
- {
- const bool include_symbols = true;
-
- // TODO Fix FindFunctions so that it doesn't return
- // instance methods for eFunctionNameTypeBase.
-
- target->GetImages().FindFunctions(name,
- eFunctionNameTypeFull,
- include_symbols,
- include_inlines,
- append,
- sc_list);
+ fdi_cache.emplace_back(fdi);
+ }
+
+ // Loop through the functions in our cache looking for matching types,
+ // then compare their scope levels to see which is closer.
+ std::multimap<CompilerType, const FuncDeclInfo *> matches;
+ for (const FuncDeclInfo &fdi : fdi_cache) {
+ const CompilerType t = fdi.m_copied_type;
+ auto q = matches.find(t);
+ if (q != matches.end()) {
+ if (q->second->m_decl_lvl > fdi.m_decl_lvl)
+ // This function is closer; remove the old set.
+ matches.erase(t);
+ else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
+ // The functions in our set are closer - skip this one.
+ continue;
}
+ matches.insert(std::make_pair(t, &fdi));
+ }
- // If we found more than one function, see if we can use the
- // frame's decl context to remove functions that are shadowed
- // by other functions which match in type but are nearer in scope.
- //
- // AddOneFunction will not add a function whose type has already been
- // added, so if there's another function in the list with a matching
- // type, check to see if their decl context is a parent of the current
- // frame's or was imported via a and using statement, and pick the
- // best match according to lookup rules.
- if (sc_list.GetSize() > 1)
- {
- // Collect some info about our frame's context.
- StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
- SymbolContext frame_sym_ctx;
- if (frame != nullptr)
- frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
- CompilerDeclContext frame_decl_context = frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext() : CompilerDeclContext();
-
- // We can't do this without a compiler decl context for our frame.
- if (frame_decl_context)
- {
- clang::DeclContext *frame_decl_ctx = (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
-
- // Structure to hold the info needed when comparing function
- // declarations.
- struct FuncDeclInfo
- {
- ConstString m_name;
- CompilerType m_copied_type;
- uint32_t m_decl_lvl;
- SymbolContext m_sym_ctx;
- };
-
- // First, symplify things by looping through the symbol contexts
- // to remove unwanted functions and separate out the functions we
- // want to compare and prune into a separate list.
- // Cache the info needed about the function declarations in a
- // vector for efficiency.
- SymbolContextList sc_sym_list;
- uint32_t num_indices = sc_list.GetSize();
- std::vector<FuncDeclInfo> fdi_cache;
- fdi_cache.reserve(num_indices);
- for (uint32_t index = 0; index < num_indices; ++index)
- {
- FuncDeclInfo fdi;
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(index, sym_ctx);
-
- // We don't know enough about symbols to compare them,
- // but we should keep them in the list.
- Function *function = sym_ctx.function;
- if (!function)
- {
- sc_sym_list.Append(sym_ctx);
- continue;
- }
- // Filter out functions without declaration contexts, as well as
- // class/instance methods, since they'll be skipped in the
- // code that follows anyway.
- CompilerDeclContext func_decl_context = function->GetDeclContext();
- if (!func_decl_context || func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
- continue;
- // We can only prune functions for which we can copy the type.
- CompilerType func_clang_type = function->GetType()->GetFullCompilerType();
- CompilerType copied_func_type = GuardedCopyType(func_clang_type);
- if (!copied_func_type)
- {
- sc_sym_list.Append(sym_ctx);
- continue;
- }
-
- fdi.m_sym_ctx = sym_ctx;
- fdi.m_name = function->GetName();
- fdi.m_copied_type = copied_func_type;
- fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
- if (fdi.m_copied_type && func_decl_context)
- {
- // Call CountDeclLevels to get the number of parent scopes we
- // have to look through before we find the function declaration.
- // When comparing functions of the same type, the one with a
- // lower count will be closer to us in the lookup scope and
- // shadows the other.
- clang::DeclContext *func_decl_ctx = (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
- fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx,
- func_decl_ctx,
- &fdi.m_name,
- &fdi.m_copied_type);
- }
- fdi_cache.emplace_back(fdi);
- }
-
- // Loop through the functions in our cache looking for matching types,
- // then compare their scope levels to see which is closer.
- std::multimap<CompilerType, const FuncDeclInfo*> matches;
- for (const FuncDeclInfo &fdi : fdi_cache)
- {
- const CompilerType t = fdi.m_copied_type;
- auto q = matches.find(t);
- if (q != matches.end())
- {
- if (q->second->m_decl_lvl > fdi.m_decl_lvl)
- // This function is closer; remove the old set.
- matches.erase(t);
- else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
- // The functions in our set are closer - skip this one.
- continue;
- }
- matches.insert(std::make_pair(t, &fdi));
- }
-
- // Loop through our matches and add their symbol contexts to our list.
- SymbolContextList sc_func_list;
- for (const auto &q : matches)
- sc_func_list.Append(q.second->m_sym_ctx);
-
- // Rejoin the lists with the functions in front.
- sc_list = sc_func_list;
- sc_list.Append(sc_sym_list);
- }
- }
+ // Loop through our matches and add their symbol contexts to our list.
+ SymbolContextList sc_func_list;
+ for (const auto &q : matches)
+ sc_func_list.Append(q.second->m_sym_ctx);
- if (sc_list.GetSize())
- {
- Symbol *extern_symbol = NULL;
- Symbol *non_extern_symbol = NULL;
-
- for (uint32_t index = 0, num_indices = sc_list.GetSize();
- index < num_indices;
- ++index)
- {
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(index, sym_ctx);
-
- if (sym_ctx.function)
- {
- CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
-
- if (!decl_ctx)
- continue;
-
- // Filter out class/instance methods.
- if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
- continue;
-
- AddOneFunction(context, sym_ctx.function, NULL, current_id);
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
- }
- else if (sym_ctx.symbol)
- {
- if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target)
- {
- sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
- if (sym_ctx.symbol == NULL)
- continue;
- }
-
- if (sym_ctx.symbol->IsExternal())
- extern_symbol = sym_ctx.symbol;
- else
- non_extern_symbol = sym_ctx.symbol;
- }
- }
-
- if (!context.m_found.function_with_type_info)
- {
- for (clang::NamedDecl *decl : decls_from_modules)
- {
- if (llvm::isa<clang::FunctionDecl>(decl))
- {
- clang::NamedDecl *copied_decl = llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl));
- if (copied_decl)
- {
- context.AddNamedDecl(copied_decl);
- context.m_found.function_with_type_info = true;
- }
- }
- }
- }
-
- if (!context.m_found.function_with_type_info)
- {
- if (extern_symbol)
- {
- AddOneFunction (context, NULL, extern_symbol, current_id);
- context.m_found.function = true;
- }
- else if (non_extern_symbol)
- {
- AddOneFunction (context, NULL, non_extern_symbol, current_id);
- context.m_found.function = true;
- }
- }
+ // Rejoin the lists with the functions in front.
+ sc_list = sc_func_list;
+ sc_list.Append(sc_sym_list);
+ }
+ }
+
+ if (sc_list.GetSize()) {
+ Symbol *extern_symbol = NULL;
+ Symbol *non_extern_symbol = NULL;
+
+ for (uint32_t index = 0, num_indices = sc_list.GetSize();
+ index < num_indices; ++index) {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(index, sym_ctx);
+
+ if (sym_ctx.function) {
+ CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
+
+ if (!decl_ctx)
+ continue;
+
+ // Filter out class/instance methods.
+ if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
+ continue;
+
+ AddOneFunction(context, sym_ctx.function, NULL, current_id);
+ context.m_found.function_with_type_info = true;
+ context.m_found.function = true;
+ } else if (sym_ctx.symbol) {
+ if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
+ sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
+ if (sym_ctx.symbol == NULL)
+ continue;
}
-
- if (!context.m_found.function_with_type_info)
- {
- // Try the modules next.
-
- do
- {
- if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(name,
- append,
- max_matches,
- decls))
- break;
-
- clang::NamedDecl *const decl_from_modules = decls[0];
-
- if (llvm::isa<clang::FunctionDecl>(decl_from_modules))
- {
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching function found for \"%s\" in the modules",
- current_id,
- name.GetCString());
- }
-
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
- clang::FunctionDecl *copied_function_decl = copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) : nullptr;
-
- if (!copied_function_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a function declaration from the modules",
- current_id);
-
- break;
- }
-
- MaybeRegisterFunctionBody(copied_function_decl);
-
- context.AddNamedDecl(copied_function_decl);
-
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
- }
- else if (llvm::isa<clang::VarDecl>(decl_from_modules))
- {
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching variable found for \"%s\" in the modules",
- current_id,
- name.GetCString());
- }
-
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
- clang::VarDecl *copied_var_decl = copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) : nullptr;
-
- if (!copied_var_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a variable declaration from the modules",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_var_decl);
-
- context.m_found.variable = true;
- }
- }
- } while (0);
+
+ if (sym_ctx.symbol->IsExternal())
+ extern_symbol = sym_ctx.symbol;
+ else
+ non_extern_symbol = sym_ctx.symbol;
+ }
+ }
+
+ if (!context.m_found.function_with_type_info) {
+ for (clang::NamedDecl *decl : decls_from_modules) {
+ if (llvm::isa<clang::FunctionDecl>(decl)) {
+ clang::NamedDecl *copied_decl =
+ llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl->getASTContext(), decl));
+ if (copied_decl) {
+ context.AddNamedDecl(copied_decl);
+ context.m_found.function_with_type_info = true;
+ }
}
+ }
+ }
- if (target && !context.m_found.variable && !namespace_decl)
- {
- // We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
- // data symbol, and -- if it is found -- treat it as a variable.
-
- const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
-
- if (data_symbol)
- {
- std::string warning("got name from symbols: ");
- warning.append(name.AsCString());
- const unsigned diag_id = m_ast_context->getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Level::Warning, "%0");
- m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
- AddOneGenericVariable(context, *data_symbol, current_id);
- context.m_found.variable = true;
- }
+ if (!context.m_found.function_with_type_info) {
+ if (extern_symbol) {
+ AddOneFunction(context, NULL, extern_symbol, current_id);
+ context.m_found.function = true;
+ } else if (non_extern_symbol) {
+ AddOneFunction(context, NULL, non_extern_symbol, current_id);
+ context.m_found.function = true;
+ }
+ }
+ }
+
+ if (!context.m_found.function_with_type_info) {
+ // Try the modules next.
+
+ do {
+ if (ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ if (!modules_decl_vendor->FindDecls(name, append, max_matches,
+ decls))
+ break;
+
+ clang::NamedDecl *const decl_from_modules = decls[0];
+
+ if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching function found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
+ }
+
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::FunctionDecl *copied_function_decl =
+ copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
+ : nullptr;
+
+ if (!copied_function_decl) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
+ "declaration from the modules",
+ current_id);
+
+ break;
+ }
+
+ MaybeRegisterFunctionBody(copied_function_decl);
+
+ context.AddNamedDecl(copied_function_decl);
+
+ context.m_found.function_with_type_info = true;
+ context.m_found.function = true;
+ } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching variable found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
+ }
+
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::VarDecl *copied_var_decl =
+ copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
+ : nullptr;
+
+ if (!copied_var_decl) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
+ "declaration from the modules",
+ current_id);
+
+ break;
+ }
+
+ context.AddNamedDecl(copied_var_decl);
+
+ context.m_found.variable = true;
}
+ }
+ } while (0);
+ }
+
+ if (target && !context.m_found.variable && !namespace_decl) {
+ // We couldn't find a non-symbol variable for this. Now we'll hunt for
+ // a generic
+ // data symbol, and -- if it is found -- treat it as a variable.
+
+ const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
+
+ if (data_symbol) {
+ std::string warning("got name from symbols: ");
+ warning.append(name.AsCString());
+ const unsigned diag_id =
+ m_ast_context->getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Level::Warning, "%0");
+ m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
+ AddOneGenericVariable(context, *data_symbol, current_id);
+ context.m_found.variable = true;
}
+ }
}
+ }
}
-//static opaque_compiler_type_t
-//MaybePromoteToBlockPointerType
+// static opaque_compiler_type_t
+// MaybePromoteToBlockPointerType
//(
// ASTContext *ast_context,
// opaque_compiler_type_t candidate_type
@@ -1647,14 +1562,16 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
//
// QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type);
//
-// const PointerType *candidate_pointer_type = dyn_cast<PointerType>(candidate_qual_type);
+// const PointerType *candidate_pointer_type =
+// dyn_cast<PointerType>(candidate_qual_type);
//
// if (!candidate_pointer_type)
// return candidate_type;
//
// QualType pointee_qual_type = candidate_pointer_type->getPointeeType();
//
-// const RecordType *pointee_record_type = dyn_cast<RecordType>(pointee_qual_type);
+// const RecordType *pointee_record_type =
+// dyn_cast<RecordType>(pointee_qual_type);
//
// if (!pointee_record_type)
// return candidate_type;
@@ -1664,662 +1581,640 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
// if (!pointee_record_decl->isRecord())
// return candidate_type;
//
-// if (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
+// if
+// (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
// return candidate_type;
//
-// QualType generic_function_type = ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy);
-// QualType block_pointer_type = ast_context->getBlockPointerType(generic_function_type);
+// QualType generic_function_type =
+// ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy);
+// QualType block_pointer_type =
+// ast_context->getBlockPointerType(generic_function_type);
//
// return block_pointer_type.getAsOpaquePtr();
//}
-bool
-ClangExpressionDeclMap::GetVariableValue (VariableSP &var,
- lldb_private::Value &var_location,
- TypeFromUser *user_type,
- TypeFromParser *parser_type)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- Type *var_type = var->GetType();
-
- if (!var_type)
- {
- if (log)
- log->PutCString("Skipped a definition because it has no type");
- return false;
- }
-
- CompilerType var_clang_type = var_type->GetFullCompilerType ();
+bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
+ lldb_private::Value &var_location,
+ TypeFromUser *user_type,
+ TypeFromParser *parser_type) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!var_clang_type)
- {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang type");
- return false;
- }
-
- ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(var_type->GetForwardCompilerType().GetTypeSystem());
-
- if (!clang_ast)
- {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang AST");
- return false;
- }
+ Type *var_type = var->GetType();
+ if (!var_type) {
+ if (log)
+ log->PutCString("Skipped a definition because it has no type");
+ return false;
+ }
- ASTContext *ast = clang_ast->getASTContext();
+ CompilerType var_clang_type = var_type->GetFullCompilerType();
- if (!ast)
- {
- if (log)
- log->PutCString("There is no AST context for the current execution context");
- return false;
- }
- //var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
+ if (!var_clang_type) {
+ if (log)
+ log->PutCString("Skipped a definition because it has no Clang type");
+ return false;
+ }
- DWARFExpression &var_location_expr = var->LocationExpression();
+ ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ var_type->GetForwardCompilerType().GetTypeSystem());
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- Error err;
+ if (!clang_ast) {
+ if (log)
+ log->PutCString("Skipped a definition because it has no Clang AST");
+ return false;
+ }
- if (var->GetLocationIsConstantValueData())
- {
- DataExtractor const_value_extractor;
+ ASTContext *ast = clang_ast->getASTContext();
- if (var_location_expr.GetExpressionData(const_value_extractor))
- {
- var_location = Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize());
- var_location.SetValueType(Value::eValueTypeHostAddress);
- }
- else
- {
- if (log)
- log->Printf("Error evaluating constant variable: %s", err.AsCString());
- return false;
- }
+ if (!ast) {
+ if (log)
+ log->PutCString(
+ "There is no AST context for the current execution context");
+ return false;
+ }
+ // var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
+
+ DWARFExpression &var_location_expr = var->LocationExpression();
+
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
+ Error err;
+
+ if (var->GetLocationIsConstantValueData()) {
+ DataExtractor const_value_extractor;
+
+ if (var_location_expr.GetExpressionData(const_value_extractor)) {
+ var_location = Value(const_value_extractor.GetDataStart(),
+ const_value_extractor.GetByteSize());
+ var_location.SetValueType(Value::eValueTypeHostAddress);
+ } else {
+ if (log)
+ log->Printf("Error evaluating constant variable: %s", err.AsCString());
+ return false;
}
+ }
- CompilerType type_to_use = GuardedCopyType(var_clang_type);
+ CompilerType type_to_use = GuardedCopyType(var_clang_type);
- if (!type_to_use)
- {
- if (log)
- log->Printf("Couldn't copy a variable's type into the parser's AST context");
+ if (!type_to_use) {
+ if (log)
+ log->Printf(
+ "Couldn't copy a variable's type into the parser's AST context");
- return false;
- }
+ return false;
+ }
- if (parser_type)
- *parser_type = TypeFromParser(type_to_use);
+ if (parser_type)
+ *parser_type = TypeFromParser(type_to_use);
- if (var_location.GetContextType() == Value::eContextTypeInvalid)
- var_location.SetCompilerType(type_to_use);
+ if (var_location.GetContextType() == Value::eContextTypeInvalid)
+ var_location.SetCompilerType(type_to_use);
- if (var_location.GetValueType() == Value::eValueTypeFileAddress)
- {
- SymbolContext var_sc;
- var->CalculateSymbolContext(&var_sc);
+ if (var_location.GetValueType() == Value::eValueTypeFileAddress) {
+ SymbolContext var_sc;
+ var->CalculateSymbolContext(&var_sc);
- if (!var_sc.module_sp)
- return false;
+ if (!var_sc.module_sp)
+ return false;
- Address so_addr(var_location.GetScalar().ULongLong(), var_sc.module_sp->GetSectionList());
+ Address so_addr(var_location.GetScalar().ULongLong(),
+ var_sc.module_sp->GetSectionList());
- lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
+ lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- var_location.GetScalar() = load_addr;
- var_location.SetValueType(Value::eValueTypeLoadAddress);
- }
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ var_location.GetScalar() = load_addr;
+ var_location.SetValueType(Value::eValueTypeLoadAddress);
}
+ }
- if (user_type)
- *user_type = TypeFromUser(var_clang_type);
+ if (user_type)
+ *user_type = TypeFromUser(var_clang_type);
- return true;
+ return true;
}
-void
-ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP var, ValueObjectSP valobj, unsigned int current_id)
-{
- assert (m_parser_vars.get());
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
+ VariableSP var,
+ ValueObjectSP valobj,
+ unsigned int current_id) {
+ assert(m_parser_vars.get());
- TypeFromUser ut;
- TypeFromParser pt;
- Value var_location;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!GetVariableValue (var, var_location, &ut, &pt))
- return;
-
- clang::QualType parser_opaque_type = QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
-
- if (parser_opaque_type.isNull())
- return;
-
- if (const clang::Type *parser_type = parser_opaque_type.getTypePtr())
- {
- if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
- CompleteType(tag_type->getDecl());
- if (const ObjCObjectPointerType *objc_object_ptr_type = dyn_cast<ObjCObjectPointerType>(parser_type))
- CompleteType(objc_object_ptr_type->getInterfaceDecl());
- }
+ TypeFromUser ut;
+ TypeFromParser pt;
+ Value var_location;
+ if (!GetVariableValue(var, var_location, &ut, &pt))
+ return;
- bool is_reference = pt.IsReferenceType();
-
- NamedDecl *var_decl = NULL;
- if (is_reference)
- var_decl = context.AddVarDecl(pt);
- else
- var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
-
- std::string decl_name(context.m_decl_name.getAsString());
- ConstString entity_name(decl_name.c_str());
- ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
- m_found_entities.AddNewlyConstructedVariable(entity);
-
- assert (entity);
- entity->EnableParserVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = pt;
- parser_vars->m_named_decl = var_decl;
- parser_vars->m_llvm_value = NULL;
- parser_vars->m_lldb_value = var_location;
- parser_vars->m_lldb_var = var;
+ clang::QualType parser_opaque_type =
+ QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
- if (is_reference)
- entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
+ if (parser_opaque_type.isNull())
+ return;
- if (log)
- {
- ASTDumper orig_dumper(ut.GetOpaqueQualType());
- ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", current_id, decl_name.c_str(), ast_dumper.GetCString(), orig_dumper.GetCString());
- }
+ if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
+ if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
+ CompleteType(tag_type->getDecl());
+ if (const ObjCObjectPointerType *objc_object_ptr_type =
+ dyn_cast<ObjCObjectPointerType>(parser_type))
+ CompleteType(objc_object_ptr_type->getInterfaceDecl());
+ }
+
+ bool is_reference = pt.IsReferenceType();
+
+ NamedDecl *var_decl = NULL;
+ if (is_reference)
+ var_decl = context.AddVarDecl(pt);
+ else
+ var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
+
+ std::string decl_name(context.m_decl_name.getAsString());
+ ConstString entity_name(decl_name.c_str());
+ ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
+ m_found_entities.AddNewlyConstructedVariable(entity);
+
+ assert(entity);
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = pt;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value = var_location;
+ parser_vars->m_lldb_var = var;
+
+ if (is_reference)
+ entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
+
+ if (log) {
+ ASTDumper orig_dumper(ut.GetOpaqueQualType());
+ ASTDumper ast_dumper(var_decl);
+ log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
+ current_id, decl_name.c_str(), ast_dumper.GetCString(),
+ orig_dumper.GetCString());
+ }
}
-void
-ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
- ExpressionVariableSP &pvar_sp,
- unsigned int current_id)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- TypeFromUser user_type (llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
-
- TypeFromParser parser_type (GuardedCopyType(user_type));
-
- if (!parser_type.GetOpaqueQualType())
- {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s", current_id, pvar_sp->GetName().GetCString());
- return;
- }
+void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
+ ExpressionVariableSP &pvar_sp,
+ unsigned int current_id) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- NamedDecl *var_decl = context.AddVarDecl(parser_type.GetLValueReferenceType());
+ TypeFromUser user_type(
+ llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
- llvm::cast<ClangExpressionVariable>(pvar_sp.get())->EnableParserVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetParserVars(GetParserID());
- parser_vars->m_parser_type = parser_type;
- parser_vars->m_named_decl = var_decl;
- parser_vars->m_llvm_value = NULL;
- parser_vars->m_lldb_value.Clear();
+ TypeFromParser parser_type(GuardedCopyType(user_type));
+ if (!parser_type.GetOpaqueQualType()) {
if (log)
- {
- ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
- }
+ log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s",
+ current_id, pvar_sp->GetName().GetCString());
+ return;
+ }
+
+ NamedDecl *var_decl =
+ context.AddVarDecl(parser_type.GetLValueReferenceType());
+
+ llvm::cast<ClangExpressionVariable>(pvar_sp.get())
+ ->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(pvar_sp.get())
+ ->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = parser_type;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value.Clear();
+
+ if (log) {
+ ASTDumper ast_dumper(var_decl);
+ log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
+ pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
+ }
}
-void
-ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
- const Symbol &symbol,
- unsigned int current_id)
-{
- assert(m_parser_vars.get());
+void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
+ const Symbol &symbol,
+ unsigned int current_id) {
+ assert(m_parser_vars.get());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- if (target == NULL)
- return;
-
- ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
-
- TypeFromUser user_type (ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
- TypeFromParser parser_type (ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
- NamedDecl *var_decl = context.AddVarDecl(parser_type);
-
- std::string decl_name(context.m_decl_name.getAsString());
- ConstString entity_name(decl_name.c_str());
- ClangExpressionVariable *entity(new ClangExpressionVariable(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
- entity_name,
- user_type,
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size));
- m_found_entities.AddNewlyConstructedVariable(entity);
-
- entity->EnableParserVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
-
- const Address symbol_address = symbol.GetAddress();
- lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
-
- //parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
- parser_vars->m_lldb_value.SetCompilerType(user_type);
- parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
-
- parser_vars->m_parser_type = parser_type;
- parser_vars->m_named_decl = var_decl;
- parser_vars->m_llvm_value = NULL;
- parser_vars->m_lldb_sym = &symbol;
-
- if (log)
- {
- ASTDumper ast_dumper(var_decl);
+ if (target == NULL)
+ return;
- log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), ast_dumper.GetCString());
- }
+ ASTContext *scratch_ast_context =
+ target->GetScratchClangASTContext()->getASTContext();
+
+ TypeFromUser user_type(
+ ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid)
+ .GetPointerType()
+ .GetLValueReferenceType());
+ TypeFromParser parser_type(
+ ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid)
+ .GetPointerType()
+ .GetLValueReferenceType());
+ NamedDecl *var_decl = context.AddVarDecl(parser_type);
+
+ std::string decl_name(context.m_decl_name.getAsString());
+ ConstString entity_name(decl_name.c_str());
+ ClangExpressionVariable *entity(new ClangExpressionVariable(
+ m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
+ user_type, m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size));
+ m_found_entities.AddNewlyConstructedVariable(entity);
+
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
+
+ const Address symbol_address = symbol.GetAddress();
+ lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
+
+ // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
+ // user_type.GetOpaqueQualType());
+ parser_vars->m_lldb_value.SetCompilerType(user_type);
+ parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
+ parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+
+ parser_vars->m_parser_type = parser_type;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_sym = &symbol;
+
+ if (log) {
+ ASTDumper ast_dumper(var_decl);
+
+ log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id,
+ decl_name.c_str(), ast_dumper.GetCString());
+ }
}
-bool
-ClangExpressionDeclMap::ResolveUnknownTypes()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
+bool ClangExpressionDeclMap::ResolveUnknownTypes() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
+ ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
- for (size_t index = 0, num_entities = m_found_entities.GetSize();
- index < num_entities;
- ++index)
- {
- ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
+ for (size_t index = 0, num_entities = m_found_entities.GetSize();
+ index < num_entities; ++index) {
+ ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(entity.get())->GetParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(entity.get())
+ ->GetParserVars(GetParserID());
- if (entity->m_flags & ClangExpressionVariable::EVUnknownType)
- {
- const NamedDecl *named_decl = parser_vars->m_named_decl;
- const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
+ if (entity->m_flags & ClangExpressionVariable::EVUnknownType) {
+ const NamedDecl *named_decl = parser_vars->m_named_decl;
+ const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
- if (!var_decl)
- {
- if (log)
- log->Printf("Entity of unknown type does not have a VarDecl");
- return false;
- }
+ if (!var_decl) {
+ if (log)
+ log->Printf("Entity of unknown type does not have a VarDecl");
+ return false;
+ }
- if (log)
- {
- ASTDumper ast_dumper(const_cast<VarDecl*>(var_decl));
- log->Printf("Variable of unknown type now has Decl %s", ast_dumper.GetCString());
- }
+ if (log) {
+ ASTDumper ast_dumper(const_cast<VarDecl *>(var_decl));
+ log->Printf("Variable of unknown type now has Decl %s",
+ ast_dumper.GetCString());
+ }
- QualType var_type = var_decl->getType();
- TypeFromParser parser_type(var_type.getAsOpaquePtr(), ClangASTContext::GetASTContext(&var_decl->getASTContext()));
+ QualType var_type = var_decl->getType();
+ TypeFromParser parser_type(
+ var_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&var_decl->getASTContext()));
- lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(scratch_ast_context->getASTContext(), &var_decl->getASTContext(), var_type.getAsOpaquePtr());
+ lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(
+ scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
+ var_type.getAsOpaquePtr());
- if (!copied_type)
- {
- if (log)
- log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable");
+ if (!copied_type) {
+ if (log)
+ log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
+ "import the type for a variable");
- return (bool) lldb::ExpressionVariableSP();
- }
+ return (bool)lldb::ExpressionVariableSP();
+ }
- TypeFromUser user_type(copied_type, scratch_ast_context);
+ TypeFromUser user_type(copied_type, scratch_ast_context);
-// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
- parser_vars->m_lldb_value.SetCompilerType(user_type);
- parser_vars->m_parser_type = parser_type;
+ // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
+ // user_type.GetOpaqueQualType());
+ parser_vars->m_lldb_value.SetCompilerType(user_type);
+ parser_vars->m_parser_type = parser_type;
- entity->SetCompilerType(user_type);
+ entity->SetCompilerType(user_type);
- entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
- }
+ entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
}
+ }
- return true;
+ return true;
}
-void
-ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
- const RegisterInfo *reg_info,
- unsigned int current_id)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- CompilerType clang_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (m_ast_context,
- reg_info->encoding,
- reg_info->byte_size * 8);
-
- if (!clang_type)
- {
- if (log)
- log->Printf(" Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
- return;
- }
-
- TypeFromParser parser_clang_type (clang_type);
-
- NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
-
- ClangExpressionVariable *entity(new ClangExpressionVariable(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size));
- m_found_entities.AddNewlyConstructedVariable(entity);
+void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
+ const RegisterInfo *reg_info,
+ unsigned int current_id) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- std::string decl_name(context.m_decl_name.getAsString());
- entity->SetName (ConstString (decl_name.c_str()));
- entity->SetRegisterInfo (reg_info);
- entity->EnableParserVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = parser_clang_type;
- parser_vars->m_named_decl = var_decl;
- parser_vars->m_llvm_value = NULL;
- parser_vars->m_lldb_value.Clear();
- entity->m_flags |= ClangExpressionVariable::EVBareRegister;
+ CompilerType clang_type =
+ ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
+ m_ast_context, reg_info->encoding, reg_info->byte_size * 8);
+ if (!clang_type) {
if (log)
- {
- ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id, context.m_decl_name.getAsString().c_str(), ast_dumper.GetCString());
- }
+ log->Printf(" Tried to add a type for %s, but couldn't get one",
+ context.m_decl_name.getAsString().c_str());
+ return;
+ }
+
+ TypeFromParser parser_clang_type(clang_type);
+
+ NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
+
+ ClangExpressionVariable *entity(new ClangExpressionVariable(
+ m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
+ m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size));
+ m_found_entities.AddNewlyConstructedVariable(entity);
+
+ std::string decl_name(context.m_decl_name.getAsString());
+ entity->SetName(ConstString(decl_name.c_str()));
+ entity->SetRegisterInfo(reg_info);
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = parser_clang_type;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value.Clear();
+ entity->m_flags |= ClangExpressionVariable::EVBareRegister;
+
+ if (log) {
+ ASTDumper ast_dumper(var_decl);
+ log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id,
+ context.m_decl_name.getAsString().c_str(),
+ ast_dumper.GetCString());
+ }
}
-void
-ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
- Function* function,
- Symbol* symbol,
- unsigned int current_id)
-{
- assert (m_parser_vars.get());
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- NamedDecl *function_decl = NULL;
- Address fun_address;
- CompilerType function_clang_type;
-
- bool is_indirect_function = false;
-
- if (function)
- {
- Type *function_type = function->GetType();
-
- const lldb::LanguageType comp_unit_language = function->GetCompileUnit()->GetLanguage();
- const bool extern_c = Language::LanguageIsC(comp_unit_language) ||
- (Language::LanguageIsObjC(comp_unit_language) &&
- !Language::LanguageIsCPlusPlus(comp_unit_language));
-
- if (!extern_c)
- {
- TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
- if (ClangASTContext *src_ast = llvm::dyn_cast<ClangASTContext>(type_system))
- {
- clang::DeclContext *src_decl_context = (clang::DeclContext*)function->GetDeclContext().GetOpaqueDeclContext();
- clang::FunctionDecl *src_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
-
- if (src_function_decl)
- {
- if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, src_ast->getASTContext(), src_function_decl)))
- {
- if (log)
- {
- ASTDumper ast_dumper((clang::Decl*)copied_function_decl);
-
- StreamString ss;
-
- function->DumpSymbolContext(&ss);
-
- log->Printf(" CEDM::FEVD[%u] Imported decl for function %s (description %s), returned %s",
- current_id,
- copied_function_decl->getName().str().c_str(),
- ss.GetData(),
- ast_dumper.GetCString());
-
- }
-
- context.AddNamedDecl(copied_function_decl);
- return;
- }
- else
- {
- if (log)
- {
- log->Printf (" Failed to import the function decl for '%s'",
- src_function_decl->getName().str().c_str());
- }
- }
- }
+void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
+ Function *function, Symbol *symbol,
+ unsigned int current_id) {
+ assert(m_parser_vars.get());
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ NamedDecl *function_decl = NULL;
+ Address fun_address;
+ CompilerType function_clang_type;
+
+ bool is_indirect_function = false;
+
+ if (function) {
+ Type *function_type = function->GetType();
+
+ const auto lang = function->GetCompileUnit()->GetLanguage();
+ const auto name = function->GetMangled().GetMangledName().AsCString();
+ const bool extern_c = (Language::LanguageIsC(lang) &&
+ !CPlusPlusLanguage::IsCPPMangledName(name)) ||
+ (Language::LanguageIsObjC(lang) &&
+ !Language::LanguageIsCPlusPlus(lang));
+
+ if (!extern_c) {
+ TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
+ if (ClangASTContext *src_ast =
+ llvm::dyn_cast<ClangASTContext>(type_system)) {
+ clang::DeclContext *src_decl_context =
+ (clang::DeclContext *)function->GetDeclContext()
+ .GetOpaqueDeclContext();
+ clang::FunctionDecl *src_function_decl =
+ llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
+
+ if (src_function_decl) {
+ if (clang::FunctionDecl *copied_function_decl =
+ llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ m_ast_importer_sp->CopyDecl(m_ast_context,
+ src_ast->getASTContext(),
+ src_function_decl))) {
+ if (log) {
+ ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
+
+ StreamString ss;
+
+ function->DumpSymbolContext(&ss);
+
+ log->Printf(" CEDM::FEVD[%u] Imported decl for function %s "
+ "(description %s), returned %s",
+ current_id,
+ copied_function_decl->getNameAsString().c_str(),
+ ss.GetData(), ast_dumper.GetCString());
}
- }
- if (!function_type)
- {
- if (log)
- log->PutCString(" Skipped a function because it has no type");
+ context.AddNamedDecl(copied_function_decl);
return;
+ } else {
+ if (log) {
+ log->Printf(" Failed to import the function decl for '%s'",
+ src_function_decl->getName().str().c_str());
+ }
+ }
}
+ }
+ }
- function_clang_type = function_type->GetFullCompilerType ();
+ if (!function_type) {
+ if (log)
+ log->PutCString(" Skipped a function because it has no type");
+ return;
+ }
- if (!function_clang_type)
- {
- if (log)
- log->PutCString(" Skipped a function because it has no Clang type");
- return;
- }
+ function_clang_type = function_type->GetFullCompilerType();
- fun_address = function->GetAddressRange().GetBaseAddress();
+ if (!function_clang_type) {
+ if (log)
+ log->PutCString(" Skipped a function because it has no Clang type");
+ return;
+ }
- CompilerType copied_function_type = GuardedCopyType(function_clang_type);
- if (copied_function_type)
- {
- function_decl = context.AddFunDecl(copied_function_type, extern_c);
+ fun_address = function->GetAddressRange().GetBaseAddress();
- if (!function_decl)
- {
- if (log)
- {
- log->Printf (" Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
- function_type->GetName().GetCString(),
- function_type->GetID());
- }
+ CompilerType copied_function_type = GuardedCopyType(function_clang_type);
+ if (copied_function_type) {
+ function_decl = context.AddFunDecl(copied_function_type, extern_c);
- return;
- }
+ if (!function_decl) {
+ if (log) {
+ log->Printf(
+ " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
+ function_type->GetName().GetCString(), function_type->GetID());
}
- else
- {
- // We failed to copy the type we found
- if (log)
- {
- log->Printf (" Failed to import the function type '%s' {0x%8.8" PRIx64 "} into the expression parser AST contenxt",
- function_type->GetName().GetCString(),
- function_type->GetID());
- }
- return;
- }
- }
- else if (symbol)
- {
- fun_address = symbol->GetAddress();
- function_decl = context.AddGenericFunDecl();
- is_indirect_function = symbol->IsIndirect();
- }
- else
- {
- if (log)
- log->PutCString(" AddOneFunction called with no function and no symbol");
return;
+ }
+ } else {
+ // We failed to copy the type we found
+ if (log) {
+ log->Printf(" Failed to import the function type '%s' {0x%8.8" PRIx64
+ "} into the expression parser AST contenxt",
+ function_type->GetName().GetCString(),
+ function_type->GetID());
+ }
+
+ return;
}
+ } else if (symbol) {
+ fun_address = symbol->GetAddress();
+ function_decl = context.AddGenericFunDecl();
+ is_indirect_function = symbol->IsIndirect();
+ } else {
+ if (log)
+ log->PutCString(" AddOneFunction called with no function and no symbol");
+ return;
+ }
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
-
- lldb::addr_t load_addr = fun_address.GetCallableLoadAddress(target, is_indirect_function);
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- ClangExpressionVariable *entity(new ClangExpressionVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size));
- m_found_entities.AddNewlyConstructedVariable(entity);
+ lldb::addr_t load_addr =
+ fun_address.GetCallableLoadAddress(target, is_indirect_function);
- std::string decl_name(context.m_decl_name.getAsString());
- entity->SetName(ConstString(decl_name.c_str()));
- entity->SetCompilerType (function_clang_type);
- entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable *entity(new ClangExpressionVariable(
+ m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
+ m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size));
+ m_found_entities.AddNewlyConstructedVariable(entity);
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ std::string decl_name(context.m_decl_name.getAsString());
+ entity->SetName(ConstString(decl_name.c_str()));
+ entity->SetCompilerType(function_clang_type);
+ entity->EnableParserVars(GetParserID());
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
- parser_vars->m_lldb_value.GetScalar() = load_addr;
- }
- else
- {
- // We have to try finding a file address.
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
- lldb::addr_t file_addr = fun_address.GetFileAddress();
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+ parser_vars->m_lldb_value.GetScalar() = load_addr;
+ } else {
+ // We have to try finding a file address.
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
- parser_vars->m_lldb_value.GetScalar() = file_addr;
- }
+ lldb::addr_t file_addr = fun_address.GetFileAddress();
+ parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
+ parser_vars->m_lldb_value.GetScalar() = file_addr;
+ }
- parser_vars->m_named_decl = function_decl;
- parser_vars->m_llvm_value = NULL;
+ parser_vars->m_named_decl = function_decl;
+ parser_vars->m_llvm_value = NULL;
- if (log)
- {
- ASTDumper ast_dumper(function_decl);
+ if (log) {
+ ASTDumper ast_dumper(function_decl);
- StreamString ss;
+ StreamString ss;
- fun_address.Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
+ fun_address.Dump(&ss,
+ m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
+ Address::DumpStyleResolvedDescription);
- log->Printf(" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
- current_id,
- (function ? "specific" : "generic"),
- decl_name.c_str(),
- ss.GetData(),
- ast_dumper.GetCString());
- }
+ log->Printf(
+ " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
+ current_id, (function ? "specific" : "generic"), decl_name.c_str(),
+ ss.GetData(), ast_dumper.GetCString());
+ }
}
-void
-ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
- TypeFromUser &ut,
- unsigned int current_id)
-{
- CompilerType copied_clang_type = GuardedCopyType(ut);
+void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
+ TypeFromUser &ut,
+ unsigned int current_id) {
+ CompilerType copied_clang_type = GuardedCopyType(ut);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!copied_clang_type)
- {
- if (log)
- log->Printf("ClangExpressionDeclMap::AddThisType - Couldn't import the type");
+ if (!copied_clang_type) {
+ if (log)
+ log->Printf(
+ "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
- return;
+ return;
+ }
+
+ if (copied_clang_type.IsAggregateType() &&
+ copied_clang_type.GetCompleteType()) {
+ CompilerType void_clang_type =
+ ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
+ CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
+
+ CompilerType method_type = ClangASTContext::CreateFunctionType(
+ m_ast_context, void_clang_type, &void_ptr_clang_type, 1, false, 0);
+
+ const bool is_virtual = false;
+ const bool is_static = false;
+ const bool is_inline = false;
+ const bool is_explicit = false;
+ const bool is_attr_used = true;
+ const bool is_artificial = false;
+
+ CXXMethodDecl *method_decl =
+ ClangASTContext::GetASTContext(m_ast_context)
+ ->AddMethodToCXXRecordType(
+ copied_clang_type.GetOpaqueQualType(), "$__lldb_expr",
+ method_type, lldb::eAccessPublic, is_virtual, is_static,
+ is_inline, is_explicit, is_attr_used, is_artificial);
+
+ if (log) {
+ ASTDumper method_ast_dumper((clang::Decl *)method_decl);
+ ASTDumper type_ast_dumper(copied_clang_type);
+
+ log->Printf(" CEDM::AddThisType Added function $__lldb_expr "
+ "(description %s) for this type %s",
+ method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
}
+ }
- if (copied_clang_type.IsAggregateType() && copied_clang_type.GetCompleteType ())
- {
- CompilerType void_clang_type = ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
- CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
-
- CompilerType method_type = ClangASTContext::CreateFunctionType (m_ast_context,
- void_clang_type,
- &void_ptr_clang_type,
- 1,
- false,
- 0);
-
- const bool is_virtual = false;
- const bool is_static = false;
- const bool is_inline = false;
- const bool is_explicit = false;
- const bool is_attr_used = true;
- const bool is_artificial = false;
-
- CXXMethodDecl *method_decl = ClangASTContext::GetASTContext(m_ast_context)->
- AddMethodToCXXRecordType (copied_clang_type.GetOpaqueQualType(),
- "$__lldb_expr",
- method_type,
- lldb::eAccessPublic,
- is_virtual,
- is_static,
- is_inline,
- is_explicit,
- is_attr_used,
- is_artificial);
-
- if (log)
- {
- ASTDumper method_ast_dumper((clang::Decl*)method_decl);
- ASTDumper type_ast_dumper(copied_clang_type);
-
- log->Printf(" CEDM::AddThisType Added function $__lldb_expr (description %s) for this type %s",
- method_ast_dumper.GetCString(),
- type_ast_dumper.GetCString());
- }
- }
+ if (!copied_clang_type.IsValid())
+ return;
- if (!copied_clang_type.IsValid())
- return;
-
- TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
-
- if (!type_source_info)
- return;
-
- // Construct a typedef type because if "*this" is a templated type we can't just return ClassTemplateSpecializationDecls in response to name queries.
- // Using a typedef makes this much more robust.
-
- TypedefDecl *typedef_decl = TypedefDecl::Create(*m_ast_context,
- m_ast_context->getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- context.m_decl_name.getAsIdentifierInfo(),
- type_source_info);
-
-
- if (!typedef_decl)
- return;
-
- context.AddNamedDecl(typedef_decl);
+ TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
+ QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
+ if (!type_source_info)
return;
+
+ // Construct a typedef type because if "*this" is a templated type we can't
+ // just return ClassTemplateSpecializationDecls in response to name queries.
+ // Using a typedef makes this much more robust.
+
+ TypedefDecl *typedef_decl = TypedefDecl::Create(
+ *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),
+ SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),
+ type_source_info);
+
+ if (!typedef_decl)
+ return;
+
+ context.AddNamedDecl(typedef_decl);
+
+ return;
}
-void
-ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
- TypeFromUser &ut,
- unsigned int current_id)
-{
- CompilerType copied_clang_type = GuardedCopyType(ut);
+void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
+ TypeFromUser &ut,
+ unsigned int current_id) {
+ CompilerType copied_clang_type = GuardedCopyType(ut);
- if (!copied_clang_type)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!copied_clang_type) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+ if (log)
+ log->Printf(
+ "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
- return;
- }
+ return;
+ }
- context.AddTypeDecl(copied_clang_type);
+ context.AddTypeDecl(copied_clang_type);
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index 537db71cfeb4..ac88c1d6b891 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -17,37 +17,40 @@
// C++ Includes
#include <vector>
-#include "ClangExpressionVariable.h"
#include "ClangASTSource.h"
+#include "ClangExpressionVariable.h"
// Other libraries and framework includes
// Project includes
-#include "llvm/ADT/DenseMap.h"
-#include "clang/AST/Decl.h"
-#include "lldb/lldb-public.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/Materializer.h"
-#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-public.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/DenseMap.h"
namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h"
+/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h
+/// "lldb/Expression/ClangExpressionDeclMap.h"
/// @brief Manages named entities that are defined in LLDB's debug information.
///
/// The Clang parser uses the ClangASTSource as an interface to request named
-/// entities from outside an expression. The ClangASTSource reports back, listing
+/// entities from outside an expression. The ClangASTSource reports back,
+/// listing
/// all possible objects corresponding to a particular name. But it in turn
-/// relies on ClangExpressionDeclMap, which performs several important functions.
+/// relies on ClangExpressionDeclMap, which performs several important
+/// functions.
///
/// First, it records what variables and functions were looked up and what Decls
/// were returned for them.
///
-/// Second, it constructs a struct on behalf of IRForTarget, recording which
-/// variables should be placed where and relaying this information back so that
+/// Second, it constructs a struct on behalf of IRForTarget, recording which
+/// variables should be placed where and relaying this information back so that
/// IRForTarget can generate context-independent code.
///
/// Third, it "materializes" this struct on behalf of the expression command,
@@ -57,642 +60,580 @@ namespace lldb_private {
/// Fourth and finally, it "dematerializes" the struct after the JITted code has
/// has executed, placing the new values back where it found the old ones.
//----------------------------------------------------------------------
-class ClangExpressionDeclMap :
- public ClangASTSource
-{
+class ClangExpressionDeclMap : public ClangASTSource {
public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] keep_result_in_memory
- /// If true, inhibits the normal deallocation of the memory for
- /// the result persistent variable, and instead marks the variable
- /// as persisting.
- ///
- /// @param[in] delegate
- /// If non-NULL, use this delegate to report result values. This
- /// allows the client ClangUserExpression to report a result.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when parsing.
- //------------------------------------------------------------------
- ClangExpressionDeclMap (bool keep_result_in_memory,
- Materializer::PersistentVariableDelegate *result_delegate,
- ExecutionContext &exe_ctx);
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangExpressionDeclMap() override;
-
- //------------------------------------------------------------------
- /// Enable the state needed for parsing and IR transformation.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when finding types for variables.
- /// Also used to find a "scratch" AST context to store result types.
- ///
- /// @param[in] materializer
- /// If non-NULL, the materializer to populate with information about
- /// the variables to use
- ///
- /// @return
- /// True if parsing is possible; false if it is unsafe to continue.
- //------------------------------------------------------------------
- bool
- WillParse (ExecutionContext &exe_ctx,
- Materializer *materializer);
-
- void
- InstallCodeGenerator (clang::ASTConsumer *code_gen);
-
- //------------------------------------------------------------------
- /// [Used by ClangExpressionParser] For each variable that had an unknown
- /// type at the beginning of parsing, determine its final type now.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- ResolveUnknownTypes();
-
- //------------------------------------------------------------------
- /// Disable the state needed for parsing and IR transformation.
- //------------------------------------------------------------------
- void
- DidParse ();
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Add a variable to the list of persistent
- /// variables for the process.
- ///
- /// @param[in] decl
- /// The Clang declaration for the persistent variable, used for
- /// lookup during parsing.
- ///
- /// @param[in] name
- /// The name of the persistent variable, usually $something.
- ///
- /// @param[in] type
- /// The type of the variable, in the Clang parser's context.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- AddPersistentVariable (const clang::NamedDecl *decl,
- const ConstString &name,
- TypeFromParser type,
- bool is_result,
- bool is_lvalue);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Add a variable to the struct that needs to
- /// be materialized each time the expression runs.
- ///
- /// @param[in] decl
- /// The Clang declaration for the variable.
- ///
- /// @param[in] name
- /// The name of the variable.
- ///
- /// @param[in] value
- /// The LLVM IR value for this variable.
- ///
- /// @param[in] size
- /// The size of the variable in bytes.
- ///
- /// @param[in] alignment
- /// The required alignment of the variable in bytes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- AddValueToStruct (const clang::NamedDecl *decl,
- const ConstString &name,
- llvm::Value *value,
- size_t size,
- lldb::offset_t alignment);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Finalize the struct, laying out the position
- /// of each object in it.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- DoStructLayout ();
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get general information about the laid-out
- /// struct after DoStructLayout() has been called.
- ///
- /// @param[out] num_elements
- /// The number of elements in the struct.
- ///
- /// @param[out] size
- /// The size of the struct, in bytes.
- ///
- /// @param[out] alignment
- /// The alignment of the struct, in bytes.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetStructInfo (uint32_t &num_elements,
- size_t &size,
- lldb::offset_t &alignment);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get specific information about one field
- /// of the laid-out struct after DoStructLayout() has been called.
- ///
- /// @param[out] decl
- /// The parsed Decl for the field, as generated by ClangASTSource
- /// on ClangExpressionDeclMap's behalf. In the case of the result
- /// value, this will have the name $__lldb_result even if the
- /// result value ends up having the name $1. This is an
- /// implementation detail of IRForTarget.
- ///
- /// @param[out] value
- /// The IR value for the field (usually a GlobalVariable). In
- /// the case of the result value, this will have the correct
- /// name ($1, for instance). This is an implementation detail
- /// of IRForTarget.
- ///
- /// @param[out] offset
- /// The offset of the field from the beginning of the struct.
- /// As long as the struct is aligned according to its required
- /// alignment, this offset will align the field correctly.
- ///
- /// @param[out] name
- /// The name of the field as used in materialization.
- ///
- /// @param[in] index
- /// The index of the field about which information is requested.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetStructElement (const clang::NamedDecl *&decl,
- llvm::Value *&value,
- lldb::offset_t &offset,
- ConstString &name,
- uint32_t index);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get information about a function given its
- /// Decl.
- ///
- /// @param[in] decl
- /// The parsed Decl for the Function, as generated by ClangASTSource
- /// on ClangExpressionDeclMap's behalf.
- ///
- /// @param[out] ptr
- /// The absolute address of the function in the target.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetFunctionInfo (const clang::NamedDecl *decl,
- uint64_t &ptr);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get the address of a symbol given nothing
- /// but its name.
- ///
- /// @param[in] target
- /// The target to find the symbol in. If not provided,
- /// then the current parsing context's Target.
- ///
- /// @param[in] process
- /// The process to use. For Objective-C symbols, the process's
- /// Objective-C language runtime may be queried if the process
- /// is non-NULL.
- ///
- /// @param[in] name
- /// The name of the symbol.
- ///
- /// @param[in] module
- /// The module to limit the search to. This can be NULL
- ///
- /// @return
- /// Valid load address for the symbol
- //------------------------------------------------------------------
- lldb::addr_t
- GetSymbolAddress (Target &target,
- Process *process,
- const ConstString &name,
- lldb::SymbolType symbol_type,
- Module *module = NULL);
-
- lldb::addr_t
- GetSymbolAddress (const ConstString &name,
- lldb::SymbolType symbol_type);
-
- //------------------------------------------------------------------
- /// [Used by IRInterpreter] Get basic target information.
- ///
- /// @param[out] byte_order
- /// The byte order of the target.
- ///
- /// @param[out] address_byte_size
- /// The size of a pointer in bytes.
- ///
- /// @return
- /// True if the information could be determined; false
- /// otherwise.
- //------------------------------------------------------------------
- struct TargetInfo
- {
- lldb::ByteOrder byte_order;
- size_t address_byte_size;
-
- TargetInfo() :
- byte_order(lldb::eByteOrderInvalid),
- address_byte_size(0)
- {
- }
-
- bool IsValid()
- {
- return (byte_order != lldb::eByteOrderInvalid &&
- address_byte_size != 0);
- }
- };
- TargetInfo GetTargetInfo();
-
- //------------------------------------------------------------------
- /// [Used by ClangASTSource] Find all entities matching a given name,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls(NameSearchContext &context) override;
-
- //------------------------------------------------------------------
- /// Find all entities matching a given name in a given module/namespace,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @param[in] module
- /// If non-NULL, the module to query.
- ///
- /// @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.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
-private:
- ExpressionVariableList m_found_entities; ///< All entities that were looked up for the parser.
- ExpressionVariableList m_struct_members; ///< All entities that need to be placed in the struct.
- bool m_keep_result_in_memory; ///< True if result persistent variables generated by this expression should stay in memory.
- Materializer::PersistentVariableDelegate *m_result_delegate; ///< If non-NULL, used to report expression results to ClangUserExpression.
-
- //----------------------------------------------------------------------
- /// The following values should not live beyond parsing
- //----------------------------------------------------------------------
- class ParserVars
- {
- public:
- ParserVars(ClangExpressionDeclMap &decl_map) :
- m_decl_map(decl_map)
- {
- }
-
- Target *
- GetTarget()
- {
- if (m_exe_ctx.GetTargetPtr())
- return m_exe_ctx.GetTargetPtr();
- else if (m_sym_ctx.target_sp)
- m_sym_ctx.target_sp.get();
- return NULL;
- }
-
- ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.
- SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables and types.
- ClangPersistentVariables *m_persistent_vars = nullptr; ///< The persistent variables for the process.
- bool m_enable_lookups = false; ///< Set to true during parsing if we have found the first "$__lldb" name.
- TargetInfo m_target_info; ///< Basic information about the target.
- Materializer *m_materializer = nullptr; ///< If non-NULL, the materializer to use when reporting used variables.
- clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator that receives new top-level functions.
- private:
- ClangExpressionDeclMap &m_decl_map;
- DISALLOW_COPY_AND_ASSIGN (ParserVars);
- };
-
- std::unique_ptr<ParserVars> m_parser_vars;
-
- //----------------------------------------------------------------------
- /// Activate parser-specific variables
- //----------------------------------------------------------------------
- void
- EnableParserVars()
- {
- if (!m_parser_vars.get())
- m_parser_vars.reset(new ParserVars(*this));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate parser-specific variables
- //----------------------------------------------------------------------
- void
- DisableParserVars()
- {
- m_parser_vars.reset();
- }
-
- //----------------------------------------------------------------------
- /// The following values contain layout information for the materialized
- /// struct, but are not specific to a single materialization
- //----------------------------------------------------------------------
- struct StructVars {
- StructVars() :
- m_struct_alignment(0),
- m_struct_size(0),
- m_struct_laid_out(false),
- m_result_name(),
- m_object_pointer_type(NULL, NULL)
- {
- }
-
- lldb::offset_t m_struct_alignment; ///< The alignment of the struct in bytes.
- size_t m_struct_size; ///< The size of the struct in bytes.
- bool m_struct_laid_out; ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since).
- ConstString m_result_name; ///< The name of the result variable ($1, for example)
- TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if one exists
- };
-
- std::unique_ptr<StructVars> m_struct_vars;
-
- //----------------------------------------------------------------------
- /// Activate struct variables
- //----------------------------------------------------------------------
- void
- EnableStructVars()
- {
- if (!m_struct_vars.get())
- m_struct_vars.reset(new struct StructVars);
- }
-
- //----------------------------------------------------------------------
- /// Deallocate struct variables
- //----------------------------------------------------------------------
- void
- DisableStructVars()
- {
- m_struct_vars.reset();
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// If true, inhibits the normal deallocation of the memory for
+ /// the result persistent variable, and instead marks the variable
+ /// as persisting.
+ ///
+ /// @param[in] delegate
+ /// If non-NULL, use this delegate to report result values. This
+ /// allows the client ClangUserExpression to report a result.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when parsing.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap(
+ bool keep_result_in_memory,
+ Materializer::PersistentVariableDelegate *result_delegate,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionDeclMap() override;
+
+ //------------------------------------------------------------------
+ /// Enable the state needed for parsing and IR transformation.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when finding types for variables.
+ /// Also used to find a "scratch" AST context to store result types.
+ ///
+ /// @param[in] materializer
+ /// If non-NULL, the materializer to populate with information about
+ /// the variables to use
+ ///
+ /// @return
+ /// True if parsing is possible; false if it is unsafe to continue.
+ //------------------------------------------------------------------
+ bool WillParse(ExecutionContext &exe_ctx, Materializer *materializer);
+
+ void InstallCodeGenerator(clang::ASTConsumer *code_gen);
+
+ //------------------------------------------------------------------
+ /// [Used by ClangExpressionParser] For each variable that had an unknown
+ /// type at the beginning of parsing, determine its final type now.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool ResolveUnknownTypes();
+
+ //------------------------------------------------------------------
+ /// Disable the state needed for parsing and IR transformation.
+ //------------------------------------------------------------------
+ void DidParse();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the list of persistent
+ /// variables for the process.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the persistent variable, used for
+ /// lookup during parsing.
+ ///
+ /// @param[in] name
+ /// The name of the persistent variable, usually $something.
+ ///
+ /// @param[in] type
+ /// The type of the variable, in the Clang parser's context.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool AddPersistentVariable(const clang::NamedDecl *decl,
+ const ConstString &name, TypeFromParser type,
+ bool is_result, bool is_lvalue);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the struct that needs to
+ /// be materialized each time the expression runs.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the variable.
+ ///
+ /// @param[in] value
+ /// The LLVM IR value for this variable.
+ ///
+ /// @param[in] size
+ /// The size of the variable in bytes.
+ ///
+ /// @param[in] alignment
+ /// The required alignment of the variable in bytes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool AddValueToStruct(const clang::NamedDecl *decl, const ConstString &name,
+ llvm::Value *value, size_t size,
+ lldb::offset_t alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Finalize the struct, laying out the position
+ /// of each object in it.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool DoStructLayout();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get general information about the laid-out
+ /// struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] num_elements
+ /// The number of elements in the struct.
+ ///
+ /// @param[out] size
+ /// The size of the struct, in bytes.
+ ///
+ /// @param[out] alignment
+ /// The alignment of the struct, in bytes.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool GetStructInfo(uint32_t &num_elements, size_t &size,
+ lldb::offset_t &alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get specific information about one field
+ /// of the laid-out struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] decl
+ /// The parsed Decl for the field, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf. In the case of the result
+ /// value, this will have the name $__lldb_result even if the
+ /// result value ends up having the name $1. This is an
+ /// implementation detail of IRForTarget.
+ ///
+ /// @param[out] value
+ /// The IR value for the field (usually a GlobalVariable). In
+ /// the case of the result value, this will have the correct
+ /// name ($1, for instance). This is an implementation detail
+ /// of IRForTarget.
+ ///
+ /// @param[out] offset
+ /// The offset of the field from the beginning of the struct.
+ /// As long as the struct is aligned according to its required
+ /// alignment, this offset will align the field correctly.
+ ///
+ /// @param[out] name
+ /// The name of the field as used in materialization.
+ ///
+ /// @param[in] index
+ /// The index of the field about which information is requested.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool GetStructElement(const clang::NamedDecl *&decl, llvm::Value *&value,
+ lldb::offset_t &offset, ConstString &name,
+ uint32_t index);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get information about a function given its
+ /// Decl.
+ ///
+ /// @param[in] decl
+ /// The parsed Decl for the Function, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf.
+ ///
+ /// @param[out] ptr
+ /// The absolute address of the function in the target.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool GetFunctionInfo(const clang::NamedDecl *decl, uint64_t &ptr);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get the address of a symbol given nothing
+ /// but its name.
+ ///
+ /// @param[in] target
+ /// The target to find the symbol in. If not provided,
+ /// then the current parsing context's Target.
+ ///
+ /// @param[in] process
+ /// The process to use. For Objective-C symbols, the process's
+ /// Objective-C language runtime may be queried if the process
+ /// is non-NULL.
+ ///
+ /// @param[in] name
+ /// The name of the symbol.
+ ///
+ /// @param[in] module
+ /// The module to limit the search to. This can be NULL
+ ///
+ /// @return
+ /// Valid load address for the symbol
+ //------------------------------------------------------------------
+ lldb::addr_t GetSymbolAddress(Target &target, Process *process,
+ const ConstString &name,
+ lldb::SymbolType symbol_type,
+ Module *module = NULL);
+
+ lldb::addr_t GetSymbolAddress(const ConstString &name,
+ lldb::SymbolType symbol_type);
+
+ //------------------------------------------------------------------
+ /// [Used by IRInterpreter] Get basic target information.
+ ///
+ /// @param[out] byte_order
+ /// The byte order of the target.
+ ///
+ /// @param[out] address_byte_size
+ /// The size of a pointer in bytes.
+ ///
+ /// @return
+ /// True if the information could be determined; false
+ /// otherwise.
+ //------------------------------------------------------------------
+ struct TargetInfo {
+ lldb::ByteOrder byte_order;
+ size_t address_byte_size;
+
+ TargetInfo() : byte_order(lldb::eByteOrderInvalid), address_byte_size(0) {}
+
+ bool IsValid() {
+ return (byte_order != lldb::eByteOrderInvalid && address_byte_size != 0);
}
-
- //----------------------------------------------------------------------
- /// Get this parser's ID for use in extracting parser- and JIT-specific
- /// data from persistent variables.
- //----------------------------------------------------------------------
- uint64_t
- GetParserID()
- {
- return (uint64_t)this;
+ };
+ TargetInfo GetTargetInfo();
+
+ //------------------------------------------------------------------
+ /// [Used by ClangASTSource] Find all entities matching a given name,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void FindExternalVisibleDecls(NameSearchContext &context) override;
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module/namespace,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @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.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void FindExternalVisibleDecls(NameSearchContext &context,
+ lldb::ModuleSP module,
+ CompilerDeclContext &namespace_decl,
+ unsigned int current_id);
+
+private:
+ ExpressionVariableList
+ m_found_entities; ///< All entities that were looked up for the parser.
+ ExpressionVariableList
+ m_struct_members; ///< All entities that need to be placed in the struct.
+ bool m_keep_result_in_memory; ///< True if result persistent variables
+ ///generated by this expression should stay in
+ ///memory.
+ Materializer::PersistentVariableDelegate
+ *m_result_delegate; ///< If non-NULL, used to report expression results to
+ ///ClangUserExpression.
+
+ //----------------------------------------------------------------------
+ /// The following values should not live beyond parsing
+ //----------------------------------------------------------------------
+ class ParserVars {
+ public:
+ ParserVars() {}
+
+ Target *GetTarget() {
+ if (m_exe_ctx.GetTargetPtr())
+ return m_exe_ctx.GetTargetPtr();
+ else if (m_sym_ctx.target_sp)
+ m_sym_ctx.target_sp.get();
+ return NULL;
}
-
- //------------------------------------------------------------------
- /// Given a target, find a data symbol that has the given name.
- ///
- /// @param[in] target
- /// The target to use as the basis for the search.
- ///
- /// @param[in] name
- /// The name as a plain C string.
- ///
- /// @param[in] module
- /// The module to limit the search to. This can be NULL
- ///
- /// @return
- /// The LLDB Symbol found, or NULL if none was found.
- //------------------------------------------------------------------
- const Symbol *
- FindGlobalDataSymbol (Target &target,
- const ConstString &name,
- Module *module = NULL);
-
- //------------------------------------------------------------------
- /// Given a target, find a variable that matches the given name and
- /// type.
- ///
- /// @param[in] target
- /// The target to use as a basis for finding the variable.
- ///
- /// @param[in] module
- /// If non-NULL, the module to search.
- ///
- /// @param[in] name
- /// The name as a plain C string.
- ///
- /// @param[in] namespace_decl
- /// If non-NULL and module is non-NULL, the parent namespace.
- ///
- /// @param[in] type
- /// The required type for the variable. This function may be called
- /// during parsing, in which case we don't know its type; hence the
- /// default.
- ///
- /// @return
- /// The LLDB Variable found, or NULL if none was found.
- //------------------------------------------------------------------
- lldb::VariableSP
- FindGlobalVariable (Target &target,
- lldb::ModuleSP &module,
- const ConstString &name,
- CompilerDeclContext *namespace_decl,
- TypeFromUser *type = NULL);
-
- //------------------------------------------------------------------
- /// Get the value of a variable in a given execution context and return
- /// the associated Types if needed.
- ///
- /// @param[in] var
- /// The variable to evaluate.
- ///
- /// @param[out] var_location
- /// The variable location value to fill in
- ///
- /// @param[out] found_type
- /// The type of the found value, as it was found in the user process.
- /// This is only useful when the variable is being inspected on behalf
- /// of the parser, hence the default.
- ///
- /// @param[out] parser_type
- /// The type of the found value, as it was copied into the parser's
- /// AST context. This is only useful when the variable is being
- /// inspected on behalf of the parser, hence the default.
- ///
- /// @param[in] decl
- /// The Decl to be looked up.
- ///
- /// @return
- /// Return true if the value was successfully filled in.
- //------------------------------------------------------------------
- bool
- GetVariableValue (lldb::VariableSP &var,
- lldb_private::Value &var_location,
- TypeFromUser *found_type = NULL,
- TypeFromParser *parser_type = NULL);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given LLDB
- /// Variable, and put it in the Tuple list.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] var
- /// The LLDB Variable that needs a Decl.
- ///
- /// @param[in] valobj
- /// The LLDB ValueObject for that variable.
- //------------------------------------------------------------------
- void
- AddOneVariable (NameSearchContext &context,
- lldb::VariableSP var,
- lldb::ValueObjectSP valobj,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// persistent variable, and put it in the list of found entities.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] pvar
- /// The persistent variable that needs a Decl.
- ///
- /// @param[in] current_id
- /// The ID of the current invocation of FindExternalVisibleDecls
- /// for logging purposes.
- //------------------------------------------------------------------
- void
- AddOneVariable (NameSearchContext &context,
- lldb::ExpressionVariableSP &pvar_sp,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given LLDB
- /// symbol (treated as a variable), and put it in the list of found
- /// entities.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] var
- /// The LLDB Variable that needs a Decl.
- //------------------------------------------------------------------
- void
- AddOneGenericVariable (NameSearchContext &context,
- const Symbol &symbol,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// function. (Functions are not placed in the Tuple list.) Can
- /// handle both fully typed functions and generic functions.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] fun
- /// The Function that needs to be created. If non-NULL, this is
- /// a fully-typed function.
- ///
- /// @param[in] sym
- /// The Symbol that corresponds to a function that needs to be
- /// created with generic type (unitptr_t foo(...)).
- //------------------------------------------------------------------
- void
- AddOneFunction (NameSearchContext &context,
- Function *fun,
- Symbol *sym,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// register.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] reg_info
- /// The information corresponding to that register.
- //------------------------------------------------------------------
- void
- AddOneRegister (NameSearchContext &context,
- const RegisterInfo *reg_info,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// type. (Types are not placed in the Tuple list.)
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] type
- /// The type that needs to be created.
- //------------------------------------------------------------------
- void
- AddOneType (NameSearchContext &context,
- TypeFromUser &type,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Generate a Decl for "*this" and add a member function declaration
- /// to it for the expression, then report it.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] type
- /// The type for *this.
- //------------------------------------------------------------------
- void
- AddThisType(NameSearchContext &context,
- TypeFromUser &type,
- unsigned int current_id);
-
- ClangASTContext *
- GetClangASTContext();
+
+ ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.
+ SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables
+ ///and types.
+ ClangPersistentVariables *m_persistent_vars =
+ nullptr; ///< The persistent variables for the process.
+ bool m_enable_lookups = false; ///< Set to true during parsing if we have
+ ///found the first "$__lldb" name.
+ TargetInfo m_target_info; ///< Basic information about the target.
+ Materializer *m_materializer = nullptr; ///< If non-NULL, the materializer
+ ///to use when reporting used
+ ///variables.
+ clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator
+ ///that receives new top-level
+ ///functions.
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ParserVars);
+ };
+
+ std::unique_ptr<ParserVars> m_parser_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate parser-specific variables
+ //----------------------------------------------------------------------
+ void EnableParserVars() {
+ if (!m_parser_vars.get())
+ m_parser_vars = llvm::make_unique<ParserVars>();
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate parser-specific variables
+ //----------------------------------------------------------------------
+ void DisableParserVars() { m_parser_vars.reset(); }
+
+ //----------------------------------------------------------------------
+ /// The following values contain layout information for the materialized
+ /// struct, but are not specific to a single materialization
+ //----------------------------------------------------------------------
+ struct StructVars {
+ StructVars()
+ : m_struct_alignment(0), m_struct_size(0), m_struct_laid_out(false),
+ m_result_name(), m_object_pointer_type(NULL, NULL) {}
+
+ lldb::offset_t
+ m_struct_alignment; ///< The alignment of the struct in bytes.
+ size_t m_struct_size; ///< The size of the struct in bytes.
+ bool m_struct_laid_out; ///< True if the struct has been laid out and the
+ ///layout is valid (that is, no new fields have been
+ ///added since).
+ ConstString
+ m_result_name; ///< The name of the result variable ($1, for example)
+ TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if
+ ///one exists
+ };
+
+ std::unique_ptr<StructVars> m_struct_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate struct variables
+ //----------------------------------------------------------------------
+ void EnableStructVars() {
+ if (!m_struct_vars.get())
+ m_struct_vars.reset(new struct StructVars);
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate struct variables
+ //----------------------------------------------------------------------
+ void DisableStructVars() { m_struct_vars.reset(); }
+
+ //----------------------------------------------------------------------
+ /// Get this parser's ID for use in extracting parser- and JIT-specific
+ /// data from persistent variables.
+ //----------------------------------------------------------------------
+ uint64_t GetParserID() { return (uint64_t) this; }
+
+ //------------------------------------------------------------------
+ /// Given a target, find a data symbol that has the given name.
+ ///
+ /// @param[in] target
+ /// The target to use as the basis for the search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @param[in] module
+ /// The module to limit the search to. This can be NULL
+ ///
+ /// @return
+ /// The LLDB Symbol found, or NULL if none was found.
+ //------------------------------------------------------------------
+ const Symbol *FindGlobalDataSymbol(Target &target, const ConstString &name,
+ Module *module = NULL);
+
+ //------------------------------------------------------------------
+ /// Given a target, find a variable that matches the given name and
+ /// type.
+ ///
+ /// @param[in] target
+ /// The target to use as a basis for finding the variable.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @param[in] namespace_decl
+ /// If non-NULL and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] type
+ /// The required type for the variable. This function may be called
+ /// during parsing, in which case we don't know its type; hence the
+ /// default.
+ ///
+ /// @return
+ /// The LLDB Variable found, or NULL if none was found.
+ //------------------------------------------------------------------
+ lldb::VariableSP FindGlobalVariable(Target &target, lldb::ModuleSP &module,
+ const ConstString &name,
+ CompilerDeclContext *namespace_decl,
+ TypeFromUser *type = NULL);
+
+ //------------------------------------------------------------------
+ /// Get the value of a variable in a given execution context and return
+ /// the associated Types if needed.
+ ///
+ /// @param[in] var
+ /// The variable to evaluate.
+ ///
+ /// @param[out] var_location
+ /// The variable location value to fill in
+ ///
+ /// @param[out] found_type
+ /// The type of the found value, as it was found in the user process.
+ /// This is only useful when the variable is being inspected on behalf
+ /// of the parser, hence the default.
+ ///
+ /// @param[out] parser_type
+ /// The type of the found value, as it was copied into the parser's
+ /// AST context. This is only useful when the variable is being
+ /// inspected on behalf of the parser, hence the default.
+ ///
+ /// @param[in] decl
+ /// The Decl to be looked up.
+ ///
+ /// @return
+ /// Return true if the value was successfully filled in.
+ //------------------------------------------------------------------
+ bool GetVariableValue(lldb::VariableSP &var,
+ lldb_private::Value &var_location,
+ TypeFromUser *found_type = NULL,
+ TypeFromParser *parser_type = NULL);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// Variable, and put it in the Tuple list.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ ///
+ /// @param[in] valobj
+ /// The LLDB ValueObject for that variable.
+ //------------------------------------------------------------------
+ void AddOneVariable(NameSearchContext &context, lldb::VariableSP var,
+ lldb::ValueObjectSP valobj, unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// persistent variable, and put it in the list of found entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] pvar
+ /// The persistent variable that needs a Decl.
+ ///
+ /// @param[in] current_id
+ /// The ID of the current invocation of FindExternalVisibleDecls
+ /// for logging purposes.
+ //------------------------------------------------------------------
+ void AddOneVariable(NameSearchContext &context,
+ lldb::ExpressionVariableSP &pvar_sp,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// symbol (treated as a variable), and put it in the list of found
+ /// entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ //------------------------------------------------------------------
+ void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// function. (Functions are not placed in the Tuple list.) Can
+ /// handle both fully typed functions and generic functions.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] fun
+ /// The Function that needs to be created. If non-NULL, this is
+ /// a fully-typed function.
+ ///
+ /// @param[in] sym
+ /// The Symbol that corresponds to a function that needs to be
+ /// created with generic type (unitptr_t foo(...)).
+ //------------------------------------------------------------------
+ void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// register.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] reg_info
+ /// The information corresponding to that register.
+ //------------------------------------------------------------------
+ void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// type. (Types are not placed in the Tuple list.)
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] type
+ /// The type that needs to be created.
+ //------------------------------------------------------------------
+ void AddOneType(NameSearchContext &context, TypeFromUser &type,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Generate a Decl for "*this" and add a member function declaration
+ /// to it for the expression, then report it.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] type
+ /// The type for *this.
+ //------------------------------------------------------------------
+ void AddThisType(NameSearchContext &context, TypeFromUser &type,
+ unsigned int current_id);
+
+ ClangASTContext *GetClangASTContext();
};
-
+
} // namespace lldb_private
#endif // liblldb_ClangExpressionDeclMap_h_
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index bcd30ec4af2e..e0d3ace15bd1 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -1,4 +1,4 @@
-//===-- ClangExpression.h ---------------------------------------*- C++ -*-===//
+//===-- ClangExpressionHelper.h ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,17 +12,17 @@
// C Includes
// C++ Includes
-#include <string>
#include <map>
+#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/ExpressionTypeSystemHelper.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
@@ -31,52 +31,43 @@ class RecordingMemoryManager;
//----------------------------------------------------------------------
// ClangExpressionHelper
//----------------------------------------------------------------------
-class ClangExpressionHelper : public ExpressionTypeSystemHelper
-{
+class ClangExpressionHelper : public ExpressionTypeSystemHelper {
public:
- static bool classof(const ExpressionTypeSystemHelper *ts)
- {
- return ts->getKind() == eKindClangHelper;
- }
+ static bool classof(const ExpressionTypeSystemHelper *ts) {
+ return ts->getKind() == eKindClangHelper;
+ }
+
+ ClangExpressionHelper()
+ : ExpressionTypeSystemHelper(
+ ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper) {}
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual ~ClangExpressionHelper() {}
- ClangExpressionHelper () :
- ExpressionTypeSystemHelper(ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper)
- {
- }
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ virtual ClangExpressionDeclMap *DeclMap() = 0;
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- virtual ~ClangExpressionHelper ()
- {
- }
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- virtual ClangExpressionDeclMap *
- DeclMap () = 0;
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- virtual clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) = 0;
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ virtual clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) = 0;
- virtual void
- CommitPersistentDecls()
- {
- }
+ virtual void CommitPersistentDecls() {}
protected:
};
} // namespace lldb_private
-#endif // liblldb_ClangExpression_h_
+#endif // liblldb_ClangExpression_h_
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index d1a3c0dea825..a75e60ff63c1 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -17,12 +17,12 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Version.h"
+#include "clang/Basic/Version.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Edit/Commit.h"
-#include "clang/Edit/EditsReceiver.h"
#include "clang/Edit/EditedSource.h"
+#include "clang/Edit/EditsReceiver.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
@@ -32,8 +32,8 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
-#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
@@ -50,19 +50,19 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
// Project includes
-#include "ClangExpressionParser.h"
#include "ClangDiagnostic.h"
+#include "ClangExpressionParser.h"
#include "ClangASTSource.h"
-#include "ClangExpressionHelper.h"
#include "ClangExpressionDeclMap.h"
+#include "ClangExpressionHelper.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
#include "IRForTarget.h"
@@ -100,932 +100,888 @@ using namespace lldb_private;
// Utility Methods for Clang
//===----------------------------------------------------------------------===//
-
-class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks
-{
- ClangModulesDeclVendor &m_decl_vendor;
- ClangPersistentVariables &m_persistent_vars;
- StreamString m_error_stream;
- bool m_has_errors = false;
+class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks {
+ ClangModulesDeclVendor &m_decl_vendor;
+ ClangPersistentVariables &m_persistent_vars;
+ StreamString m_error_stream;
+ bool m_has_errors = false;
public:
- LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor,
- ClangPersistentVariables &persistent_vars) :
- m_decl_vendor(decl_vendor),
- m_persistent_vars(persistent_vars)
- {
- }
-
- void
- moduleImport(SourceLocation import_location,
- clang::ModuleIdPath path,
- const clang::Module * /*null*/) override
- {
- std::vector<ConstString> string_path;
-
- for (const std::pair<IdentifierInfo *, SourceLocation> &component : path)
- {
- string_path.push_back(ConstString(component.first->getName()));
- }
-
- StreamString error_stream;
-
- ClangModulesDeclVendor::ModuleVector exported_modules;
-
- if (!m_decl_vendor.AddModule(string_path, &exported_modules, m_error_stream))
- {
- m_has_errors = true;
- }
-
- for (ClangModulesDeclVendor::ModuleID module : exported_modules)
- {
- m_persistent_vars.AddHandLoadedClangModule(module);
- }
- }
-
- bool hasErrors()
- {
- return m_has_errors;
- }
-
- const std::string &getErrorString()
- {
- return m_error_stream.GetString();
- }
-};
+ LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor,
+ ClangPersistentVariables &persistent_vars)
+ : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars) {}
-class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer
-{
-public:
- ClangDiagnosticManagerAdapter() : m_passthrough(new clang::TextDiagnosticBuffer) {}
+ void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
+ const clang::Module * /*null*/) override {
+ std::vector<ConstString> string_path;
- ClangDiagnosticManagerAdapter(const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough)
- : m_passthrough(passthrough)
- {
+ for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) {
+ string_path.push_back(ConstString(component.first->getName()));
}
- void
- ResetManager(DiagnosticManager *manager = nullptr)
- {
- m_manager = manager;
- }
+ StreamString error_stream;
- void
- HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info)
- {
- if (m_manager)
- {
- llvm::SmallVector<char, 32> diag_str;
- Info.FormatDiagnostic(diag_str);
- diag_str.push_back('\0');
- const char *data = diag_str.data();
-
- lldb_private::DiagnosticSeverity severity;
- bool make_new_diagnostic = true;
-
- switch (DiagLevel)
- {
- case DiagnosticsEngine::Level::Fatal:
- case DiagnosticsEngine::Level::Error:
- severity = eDiagnosticSeverityError;
- break;
- case DiagnosticsEngine::Level::Warning:
- severity = eDiagnosticSeverityWarning;
- break;
- case DiagnosticsEngine::Level::Remark:
- case DiagnosticsEngine::Level::Ignored:
- severity = eDiagnosticSeverityRemark;
- break;
- case DiagnosticsEngine::Level::Note:
- m_manager->AppendMessageToDiagnostic(data);
- make_new_diagnostic = false;
- }
- if (make_new_diagnostic)
- {
- ClangDiagnostic *new_diagnostic = new ClangDiagnostic(data, severity, Info.getID());
- m_manager->AddDiagnostic(new_diagnostic);
-
- // Don't store away warning fixits, since the compiler doesn't have enough
- // context in an expression for the warning to be useful.
- // FIXME: Should we try to filter out FixIts that apply to our generated
- // code, and not the user's expression?
- if (severity == eDiagnosticSeverityError)
- {
- size_t num_fixit_hints = Info.getNumFixItHints();
- for (size_t i = 0; i < num_fixit_hints; i++)
- {
- const clang::FixItHint &fixit = Info.getFixItHint(i);
- if (!fixit.isNull())
- new_diagnostic->AddFixitHint(fixit);
- }
- }
- }
- }
-
- m_passthrough->HandleDiagnostic(DiagLevel, Info);
- }
+ ClangModulesDeclVendor::ModuleVector exported_modules;
- void
- FlushDiagnostics(DiagnosticsEngine &Diags)
- {
- m_passthrough->FlushDiagnostics(Diags);
+ if (!m_decl_vendor.AddModule(string_path, &exported_modules,
+ m_error_stream)) {
+ m_has_errors = true;
}
- DiagnosticConsumer *
- clone(DiagnosticsEngine &Diags) const
- {
- return new ClangDiagnosticManagerAdapter(m_passthrough);
+ for (ClangModulesDeclVendor::ModuleID module : exported_modules) {
+ m_persistent_vars.AddHandLoadedClangModule(module);
}
+ }
- clang::TextDiagnosticBuffer *
- GetPassthrough()
- {
- return m_passthrough.get();
- }
+ bool hasErrors() { return m_has_errors; }
-private:
- DiagnosticManager *m_manager = nullptr;
- std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough;
+ llvm::StringRef getErrorString() { return m_error_stream.GetString(); }
};
-//===----------------------------------------------------------------------===//
-// Implementation of ClangExpressionParser
-//===----------------------------------------------------------------------===//
-
-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)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- // We can't compile expressions without a target. So if the exe_scope is null or doesn't have a target,
- // then we just need to get out of here. I'll lldb_assert and not make any of the compiler objects since
- // I can't return errors directly from the constructor. Further calls will check if the compiler was made and
- // bag out if it wasn't.
-
- if (!exe_scope)
- {
- lldb_assert(exe_scope, "Can't make an expression parser with a null scope.", __FUNCTION__, __FILE__, __LINE__);
- return;
- }
-
- lldb::TargetSP target_sp;
- target_sp = exe_scope->CalculateTarget();
- if (!target_sp)
- {
- lldb_assert(exe_scope, "Can't make an expression parser with a null target.", __FUNCTION__, __FILE__, __LINE__);
- return;
- }
-
- // 1. Create a new compiler instance.
- m_compiler.reset(new CompilerInstance());
- lldb::LanguageType frame_lang = expr.Language(); // defaults to lldb::eLanguageTypeUnknown
- bool overridden_target_opts = false;
- lldb_private::LanguageRuntime *lang_rt = nullptr;
-
- std::string abi;
- ArchSpec target_arch;
- target_arch = target_sp->GetArchitecture();
-
- const auto target_machine = target_arch.GetMachine();
-
- // If the expression is being evaluated in the context of an existing
- // stack frame, we introspect to see if the language runtime is available.
-
- lldb::StackFrameSP frame_sp = exe_scope->CalculateStackFrame();
- lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
-
- // Make sure the user hasn't provided a preferred execution language
- // with `expression --language X -- ...`
- if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown)
- frame_lang = frame_sp->GetLanguage();
-
- if (process_sp && frame_lang != lldb::eLanguageTypeUnknown)
- {
- lang_rt = process_sp->GetLanguageRuntime(frame_lang);
- if (log)
- log->Printf("Frame has language of type %s", Language::GetNameForLanguageType(frame_lang));
- }
-
- // 2. Configure the compiler with a set of default options that are appropriate
- // for most situations.
- if (target_arch.IsValid())
- {
- std::string triple = target_arch.GetTriple().str();
- m_compiler->getTargetOpts().Triple = triple;
- if (log)
- log->Printf("Using %s as the target triple", m_compiler->getTargetOpts().Triple.c_str());
- }
- else
- {
- // If we get here we don't have a valid target and just have to guess.
- // Sometimes this will be ok to just use the host target triple (when we evaluate say "2+3", but other
- // expressions like breakpoint conditions and other things that _are_ target specific really shouldn't just be
- // using the host triple. In such a case the language runtime should expose an overridden options set (3),
- // below.
- m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
- if (log)
- log->Printf("Using default target triple of %s", m_compiler->getTargetOpts().Triple.c_str());
- }
- // Now add some special fixes for known architectures:
- // Any arm32 iOS environment, but not on arm64
- if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos &&
- m_compiler->getTargetOpts().Triple.find("arm") != std::string::npos &&
- m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos)
- {
- m_compiler->getTargetOpts().ABI = "apcs-gnu";
- }
- // Supported subsets of x86
- if (target_machine == llvm::Triple::x86 ||
- target_machine == llvm::Triple::x86_64)
- {
- m_compiler->getTargetOpts().Features.push_back("+sse");
- m_compiler->getTargetOpts().Features.push_back("+sse2");
- }
-
- // Set the target CPU to generate code for.
- // This will be empty for any CPU that doesn't really need to make a special CPU string.
- m_compiler->getTargetOpts().CPU = target_arch.GetClangTargetCPU();
-
- // Set the target ABI
- abi = GetClangTargetABI(target_arch);
- if (!abi.empty())
- m_compiler->getTargetOpts().ABI = abi;
-
- // 3. Now allow the runtime to provide custom configuration options for the target.
- // In this case, a specialized language runtime is available and we can query it for extra options.
- // For 99% of use cases, this will not be needed and should be provided when basic platform detection is not enough.
- if (lang_rt)
- overridden_target_opts = lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
-
- if (overridden_target_opts)
- if (log)
- {
- log->Debug("Using overridden target options for the expression evaluation");
-
- auto opts = m_compiler->getTargetOpts();
- log->Debug("Triple: '%s'", opts.Triple.c_str());
- log->Debug("CPU: '%s'", opts.CPU.c_str());
- log->Debug("FPMath: '%s'", opts.FPMath.c_str());
- log->Debug("ABI: '%s'", opts.ABI.c_str());
- log->Debug("LinkerVersion: '%s'", opts.LinkerVersion.c_str());
- StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten");
- StringList::LogDump(log, opts.Features, "Features");
- StringList::LogDump(log, opts.Reciprocals, "Reciprocals");
- }
-
- // 4. Create and install the target on the compiler.
- m_compiler->createDiagnostics();
- auto target_info = TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts);
- if (log)
- {
- log->Printf("Using SIMD alignment: %d", target_info->getSimdDefaultAlign());
- log->Printf("Target datalayout string: '%s'", target_info->getDataLayout().getStringRepresentation().c_str());
- log->Printf("Target ABI: '%s'", target_info->getABI().str().c_str());
- log->Printf("Target vector alignment: %d", target_info->getMaxVectorAlign());
- }
- m_compiler->setTarget(target_info);
-
- assert (m_compiler->hasTarget());
-
- // 5. Set language options.
- lldb::LanguageType language = expr.Language();
-
- switch (language)
- {
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC89:
- case lldb::eLanguageTypeC99:
- case lldb::eLanguageTypeC11:
- // FIXME: the following language option is a temporary workaround,
- // to "ask for C, get C++."
- // For now, the expression parser must use C++ anytime the
- // language is a C family language, because the expression parser
- // uses features of C++ to capture values.
- m_compiler->getLangOpts().CPlusPlus = true;
+class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
+public:
+ ClangDiagnosticManagerAdapter()
+ : m_passthrough(new clang::TextDiagnosticBuffer) {}
+
+ ClangDiagnosticManagerAdapter(
+ const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough)
+ : m_passthrough(passthrough) {}
+
+ void ResetManager(DiagnosticManager *manager = nullptr) {
+ m_manager = manager;
+ }
+
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const clang::Diagnostic &Info) {
+ if (m_manager) {
+ llvm::SmallVector<char, 32> diag_str;
+ Info.FormatDiagnostic(diag_str);
+ diag_str.push_back('\0');
+ const char *data = diag_str.data();
+
+ lldb_private::DiagnosticSeverity severity;
+ bool make_new_diagnostic = true;
+
+ switch (DiagLevel) {
+ case DiagnosticsEngine::Level::Fatal:
+ case DiagnosticsEngine::Level::Error:
+ severity = eDiagnosticSeverityError;
break;
- case lldb::eLanguageTypeObjC:
- m_compiler->getLangOpts().ObjC1 = true;
- m_compiler->getLangOpts().ObjC2 = true;
- // FIXME: the following language option is a temporary workaround,
- // to "ask for ObjC, get ObjC++" (see comment above).
- m_compiler->getLangOpts().CPlusPlus = true;
+ case DiagnosticsEngine::Level::Warning:
+ severity = eDiagnosticSeverityWarning;
break;
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeC_plus_plus_11:
- case lldb::eLanguageTypeC_plus_plus_14:
- m_compiler->getLangOpts().CPlusPlus11 = true;
- m_compiler->getHeaderSearchOpts().UseLibcxx = true;
- 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;
- break;
- case lldb::eLanguageTypeObjC_plus_plus:
- case lldb::eLanguageTypeUnknown:
- default:
- m_compiler->getLangOpts().ObjC1 = true;
- m_compiler->getLangOpts().ObjC2 = true;
- m_compiler->getLangOpts().CPlusPlus = true;
- m_compiler->getLangOpts().CPlusPlus11 = true;
- m_compiler->getHeaderSearchOpts().UseLibcxx = true;
+ case DiagnosticsEngine::Level::Remark:
+ case DiagnosticsEngine::Level::Ignored:
+ severity = eDiagnosticSeverityRemark;
break;
+ case DiagnosticsEngine::Level::Note:
+ m_manager->AppendMessageToDiagnostic(data);
+ make_new_diagnostic = false;
+ }
+ if (make_new_diagnostic) {
+ ClangDiagnostic *new_diagnostic =
+ new ClangDiagnostic(data, severity, Info.getID());
+ m_manager->AddDiagnostic(new_diagnostic);
+
+ // Don't store away warning fixits, since the compiler doesn't have
+ // enough
+ // context in an expression for the warning to be useful.
+ // FIXME: Should we try to filter out FixIts that apply to our generated
+ // code, and not the user's expression?
+ if (severity == eDiagnosticSeverityError) {
+ size_t num_fixit_hints = Info.getNumFixItHints();
+ for (size_t i = 0; i < num_fixit_hints; i++) {
+ const clang::FixItHint &fixit = Info.getFixItHint(i);
+ if (!fixit.isNull())
+ new_diagnostic->AddFixitHint(fixit);
+ }
+ }
+ }
}
- m_compiler->getLangOpts().Bool = true;
- m_compiler->getLangOpts().WChar = true;
- m_compiler->getLangOpts().Blocks = true;
- m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients
- if (expr.DesiredResultType() == Expression::eResultTypeId)
- m_compiler->getLangOpts().DebuggerCastResultToId = true;
-
- m_compiler->getLangOpts().CharIsSigned =
- ArchSpec(m_compiler->getTargetOpts().Triple.c_str()).CharIsSignedByDefault();
-
- // Spell checking is a nice feature, but it ends up completing a
- // lot of types that we didn't strictly speaking need to complete.
- // As a result, we spend a long time parsing and importing debug
- // information.
- m_compiler->getLangOpts().SpellChecking = false;
-
- if (process_sp && m_compiler->getLangOpts().ObjC1)
- {
- if (process_sp->GetObjCLanguageRuntime())
- {
- if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() == ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2)
- m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
- else
- m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::FragileMacOSX, VersionTuple(10, 7));
+ m_passthrough->HandleDiagnostic(DiagLevel, Info);
+ }
- if (process_sp->GetObjCLanguageRuntime()->HasNewLiteralsAndIndexing())
- m_compiler->getLangOpts().DebuggerObjCLiteral = true;
- }
- }
+ void FlushDiagnostics(DiagnosticsEngine &Diags) {
+ m_passthrough->FlushDiagnostics(Diags);
+ }
- m_compiler->getLangOpts().ThreadsafeStatics = false;
- m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access
- m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name
-
- // Set CodeGen options
- m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
- m_compiler->getCodeGenOpts().InstrumentFunctions = false;
- m_compiler->getCodeGenOpts().DisableFPElim = true;
- m_compiler->getCodeGenOpts().OmitLeafFramePointer = false;
- if (generate_debug_info)
- m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
- else
- m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
-
- // Disable some warnings.
- m_compiler->getDiagnostics().setSeverityForGroup(clang::diag::Flavor::WarningOrError,
- "unused-value", clang::diag::Severity::Ignored, SourceLocation());
- m_compiler->getDiagnostics().setSeverityForGroup(clang::diag::Flavor::WarningOrError,
- "odr", clang::diag::Severity::Ignored, SourceLocation());
-
- // Inform the target of the language options
- //
- // FIXME: We shouldn't need to do this, the target should be immutable once
- // created. This complexity should be lifted elsewhere.
- m_compiler->getTarget().adjust(m_compiler->getLangOpts());
-
- // 6. Set up the diagnostic buffer for reporting errors
-
- m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter);
-
- // 7. Set up the source management objects inside the compiler
-
- clang::FileSystemOptions file_system_options;
- m_file_manager.reset(new clang::FileManager(file_system_options));
-
- if (!m_compiler->hasSourceManager())
- m_compiler->createSourceManager(*m_file_manager.get());
-
- m_compiler->createFileManager();
- m_compiler->createPreprocessor(TU_Complete);
-
- if (ClangModulesDeclVendor *decl_vendor = target_sp->GetClangModulesDeclVendor())
- {
- ClangPersistentVariables *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(target_sp->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
- std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars));
- m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks*>(pp_callbacks.get());
- m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
- }
-
- // 8. Most of this we get from the CompilerInstance, but we
- // also want to give the context an ExternalASTSource.
- 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()));
-
- ast_context->InitBuiltinTypes(m_compiler->getTarget());
-
- ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
- ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
-
- if (decl_map)
- {
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(decl_map->CreateProxy());
- decl_map->InstallASTContext(ast_context.get());
- ast_context->setExternalSource(ast_source);
- }
+ DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
+ return new ClangDiagnosticManagerAdapter(m_passthrough);
+ }
- 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());
+ clang::TextDiagnosticBuffer *GetPassthrough() { return m_passthrough.get(); }
- std::string module_name("$__lldb_module");
+private:
+ DiagnosticManager *m_manager = nullptr;
+ std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough;
+};
- m_llvm_context.reset(new LLVMContext());
- m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(),
- module_name,
- m_compiler->getHeaderSearchOpts(),
- m_compiler->getPreprocessorOpts(),
- m_compiler->getCodeGenOpts(),
- *m_llvm_context));
-}
+//===----------------------------------------------------------------------===//
+// Implementation of ClangExpressionParser
+//===----------------------------------------------------------------------===//
-ClangExpressionParser::~ClangExpressionParser()
-{
+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) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ // We can't compile expressions without a target. So if the exe_scope is null
+ // or doesn't have a target,
+ // then we just need to get out of here. I'll lldb_assert and not make any of
+ // the compiler objects since
+ // I can't return errors directly from the constructor. Further calls will
+ // check if the compiler was made and
+ // bag out if it wasn't.
+
+ if (!exe_scope) {
+ lldb_assert(exe_scope, "Can't make an expression parser with a null scope.",
+ __FUNCTION__, __FILE__, __LINE__);
+ return;
+ }
+
+ lldb::TargetSP target_sp;
+ target_sp = exe_scope->CalculateTarget();
+ if (!target_sp) {
+ lldb_assert(target_sp.get(),
+ "Can't make an expression parser with a null target.",
+ __FUNCTION__, __FILE__, __LINE__);
+ return;
+ }
+
+ // 1. Create a new compiler instance.
+ m_compiler.reset(new CompilerInstance());
+ lldb::LanguageType frame_lang =
+ expr.Language(); // defaults to lldb::eLanguageTypeUnknown
+ bool overridden_target_opts = false;
+ lldb_private::LanguageRuntime *lang_rt = nullptr;
+
+ std::string abi;
+ ArchSpec target_arch;
+ target_arch = target_sp->GetArchitecture();
+
+ const auto target_machine = target_arch.GetMachine();
+
+ // If the expression is being evaluated in the context of an existing
+ // stack frame, we introspect to see if the language runtime is available.
+
+ lldb::StackFrameSP frame_sp = exe_scope->CalculateStackFrame();
+ lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
+
+ // Make sure the user hasn't provided a preferred execution language
+ // with `expression --language X -- ...`
+ if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown)
+ frame_lang = frame_sp->GetLanguage();
+
+ if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) {
+ lang_rt = process_sp->GetLanguageRuntime(frame_lang);
+ if (log)
+ log->Printf("Frame has language of type %s",
+ Language::GetNameForLanguageType(frame_lang));
+ }
+
+ // 2. Configure the compiler with a set of default options that are
+ // appropriate
+ // for most situations.
+ if (target_arch.IsValid()) {
+ std::string triple = target_arch.GetTriple().str();
+ m_compiler->getTargetOpts().Triple = triple;
+ if (log)
+ log->Printf("Using %s as the target triple",
+ m_compiler->getTargetOpts().Triple.c_str());
+ } else {
+ // If we get here we don't have a valid target and just have to guess.
+ // Sometimes this will be ok to just use the host target triple (when we
+ // evaluate say "2+3", but other
+ // expressions like breakpoint conditions and other things that _are_ target
+ // specific really shouldn't just be
+ // using the host triple. In such a case the language runtime should expose
+ // an overridden options set (3),
+ // below.
+ m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
+ if (log)
+ log->Printf("Using default target triple of %s",
+ m_compiler->getTargetOpts().Triple.c_str());
+ }
+ // Now add some special fixes for known architectures:
+ // Any arm32 iOS environment, but not on arm64
+ if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos &&
+ m_compiler->getTargetOpts().Triple.find("arm") != std::string::npos &&
+ m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos) {
+ m_compiler->getTargetOpts().ABI = "apcs-gnu";
+ }
+ // Supported subsets of x86
+ if (target_machine == llvm::Triple::x86 ||
+ target_machine == llvm::Triple::x86_64) {
+ m_compiler->getTargetOpts().Features.push_back("+sse");
+ m_compiler->getTargetOpts().Features.push_back("+sse2");
+ }
+
+ // Set the target CPU to generate code for.
+ // This will be empty for any CPU that doesn't really need to make a special
+ // CPU string.
+ m_compiler->getTargetOpts().CPU = target_arch.GetClangTargetCPU();
+
+ // Set the target ABI
+ abi = GetClangTargetABI(target_arch);
+ if (!abi.empty())
+ m_compiler->getTargetOpts().ABI = abi;
+
+ // 3. Now allow the runtime to provide custom configuration options for the
+ // target.
+ // In this case, a specialized language runtime is available and we can query
+ // it for extra options.
+ // For 99% of use cases, this will not be needed and should be provided when
+ // basic platform detection is not enough.
+ if (lang_rt)
+ overridden_target_opts =
+ lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
+
+ if (overridden_target_opts)
+ if (log) {
+ log->Debug(
+ "Using overridden target options for the expression evaluation");
+
+ auto opts = m_compiler->getTargetOpts();
+ log->Debug("Triple: '%s'", opts.Triple.c_str());
+ log->Debug("CPU: '%s'", opts.CPU.c_str());
+ log->Debug("FPMath: '%s'", opts.FPMath.c_str());
+ log->Debug("ABI: '%s'", opts.ABI.c_str());
+ log->Debug("LinkerVersion: '%s'", opts.LinkerVersion.c_str());
+ StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten");
+ StringList::LogDump(log, opts.Features, "Features");
+ StringList::LogDump(log, opts.Reciprocals, "Reciprocals");
+ }
+
+ // 4. Create and install the target on the compiler.
+ m_compiler->createDiagnostics();
+ auto target_info = TargetInfo::CreateTargetInfo(
+ m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts);
+ if (log) {
+ log->Printf("Using SIMD alignment: %d", target_info->getSimdDefaultAlign());
+ log->Printf("Target datalayout string: '%s'",
+ target_info->getDataLayout().getStringRepresentation().c_str());
+ log->Printf("Target ABI: '%s'", target_info->getABI().str().c_str());
+ log->Printf("Target vector alignment: %d",
+ target_info->getMaxVectorAlign());
+ }
+ m_compiler->setTarget(target_info);
+
+ assert(m_compiler->hasTarget());
+
+ // 5. Set language options.
+ lldb::LanguageType language = expr.Language();
+
+ switch (language) {
+ case lldb::eLanguageTypeC:
+ case lldb::eLanguageTypeC89:
+ case lldb::eLanguageTypeC99:
+ case lldb::eLanguageTypeC11:
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for C, get C++."
+ // For now, the expression parser must use C++ anytime the
+ // language is a C family language, because the expression parser
+ // uses features of C++ to capture values.
+ m_compiler->getLangOpts().CPlusPlus = true;
+ break;
+ case lldb::eLanguageTypeObjC:
+ m_compiler->getLangOpts().ObjC1 = true;
+ m_compiler->getLangOpts().ObjC2 = true;
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for ObjC, get ObjC++" (see comment above).
+ m_compiler->getLangOpts().CPlusPlus = true;
+ break;
+ case lldb::eLanguageTypeC_plus_plus:
+ case lldb::eLanguageTypeC_plus_plus_11:
+ case lldb::eLanguageTypeC_plus_plus_14:
+ m_compiler->getLangOpts().CPlusPlus11 = true;
+ m_compiler->getHeaderSearchOpts().UseLibcxx = true;
+ 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;
+ break;
+ case lldb::eLanguageTypeObjC_plus_plus:
+ case lldb::eLanguageTypeUnknown:
+ default:
+ m_compiler->getLangOpts().ObjC1 = true;
+ m_compiler->getLangOpts().ObjC2 = true;
+ m_compiler->getLangOpts().CPlusPlus = true;
+ m_compiler->getLangOpts().CPlusPlus11 = true;
+ m_compiler->getHeaderSearchOpts().UseLibcxx = true;
+ break;
+ }
+
+ m_compiler->getLangOpts().Bool = true;
+ m_compiler->getLangOpts().WChar = true;
+ m_compiler->getLangOpts().Blocks = true;
+ m_compiler->getLangOpts().DebuggerSupport =
+ true; // Features specifically for debugger clients
+ if (expr.DesiredResultType() == Expression::eResultTypeId)
+ m_compiler->getLangOpts().DebuggerCastResultToId = true;
+
+ m_compiler->getLangOpts().CharIsSigned =
+ ArchSpec(m_compiler->getTargetOpts().Triple.c_str())
+ .CharIsSignedByDefault();
+
+ // Spell checking is a nice feature, but it ends up completing a
+ // lot of types that we didn't strictly speaking need to complete.
+ // As a result, we spend a long time parsing and importing debug
+ // information.
+ m_compiler->getLangOpts().SpellChecking = false;
+
+ if (process_sp && m_compiler->getLangOpts().ObjC1) {
+ if (process_sp->GetObjCLanguageRuntime()) {
+ if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() ==
+ ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2)
+ m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::MacOSX,
+ VersionTuple(10, 7));
+ else
+ m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::FragileMacOSX,
+ VersionTuple(10, 7));
+
+ if (process_sp->GetObjCLanguageRuntime()->HasNewLiteralsAndIndexing())
+ m_compiler->getLangOpts().DebuggerObjCLiteral = true;
+ }
+ }
+
+ m_compiler->getLangOpts().ThreadsafeStatics = false;
+ m_compiler->getLangOpts().AccessControl =
+ false; // Debuggers get universal access
+ m_compiler->getLangOpts().DollarIdents =
+ true; // $ indicates a persistent variable name
+
+ // Set CodeGen options
+ m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
+ m_compiler->getCodeGenOpts().InstrumentFunctions = false;
+ m_compiler->getCodeGenOpts().DisableFPElim = true;
+ m_compiler->getCodeGenOpts().OmitLeafFramePointer = false;
+ if (generate_debug_info)
+ m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
+ else
+ m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
+
+ // Disable some warnings.
+ m_compiler->getDiagnostics().setSeverityForGroup(
+ clang::diag::Flavor::WarningOrError, "unused-value",
+ clang::diag::Severity::Ignored, SourceLocation());
+ m_compiler->getDiagnostics().setSeverityForGroup(
+ clang::diag::Flavor::WarningOrError, "odr",
+ clang::diag::Severity::Ignored, SourceLocation());
+
+ // Inform the target of the language options
+ //
+ // FIXME: We shouldn't need to do this, the target should be immutable once
+ // created. This complexity should be lifted elsewhere.
+ m_compiler->getTarget().adjust(m_compiler->getLangOpts());
+
+ // 6. Set up the diagnostic buffer for reporting errors
+
+ m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter);
+
+ // 7. Set up the source management objects inside the compiler
+
+ clang::FileSystemOptions file_system_options;
+ m_file_manager.reset(new clang::FileManager(file_system_options));
+
+ if (!m_compiler->hasSourceManager())
+ m_compiler->createSourceManager(*m_file_manager.get());
+
+ m_compiler->createFileManager();
+ m_compiler->createPreprocessor(TU_Complete);
+
+ if (ClangModulesDeclVendor *decl_vendor =
+ target_sp->GetClangModulesDeclVendor()) {
+ ClangPersistentVariables *clang_persistent_vars =
+ llvm::cast<ClangPersistentVariables>(
+ target_sp->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC));
+ std::unique_ptr<PPCallbacks> pp_callbacks(
+ new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars));
+ m_pp_callbacks =
+ static_cast<LLDBPreprocessorCallbacks *>(pp_callbacks.get());
+ m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
+ }
+
+ // 8. Most of this we get from the CompilerInstance, but we
+ // also want to give the context an ExternalASTSource.
+ 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()));
+
+ ast_context->InitBuiltinTypes(m_compiler->getTarget());
+
+ ClangExpressionHelper *type_system_helper =
+ dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
+
+ if (decl_map) {
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(
+ decl_map->CreateProxy());
+ decl_map->InstallASTContext(ast_context.get());
+ 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());
+
+ std::string module_name("$__lldb_module");
+
+ m_llvm_context.reset(new LLVMContext());
+ m_code_generator.reset(CreateLLVMCodeGen(
+ m_compiler->getDiagnostics(), module_name,
+ m_compiler->getHeaderSearchOpts(), m_compiler->getPreprocessorOpts(),
+ m_compiler->getCodeGenOpts(), *m_llvm_context));
}
-unsigned
-ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager)
-{
- ClangDiagnosticManagerAdapter *adapter =
- static_cast<ClangDiagnosticManagerAdapter *>(m_compiler->getDiagnostics().getClient());
- clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough();
- diag_buf->FlushDiagnostics(m_compiler->getDiagnostics());
-
- adapter->ResetManager(&diagnostic_manager);
-
- const char *expr_text = m_expr.Text();
-
- clang::SourceManager &source_mgr = m_compiler->getSourceManager();
- bool created_main_file = false;
- if (m_compiler->getCodeGenOpts().getDebugInfo() == codegenoptions::FullDebugInfo)
- {
- int temp_fd = -1;
- llvm::SmallString<PATH_MAX> result_path;
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
- {
- tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
- std::string temp_source_path = tmpdir_file_spec.GetPath();
- llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
- }
- else
- {
- llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
- }
-
- if (temp_fd != -1)
- {
- lldb_private::File file(temp_fd, true);
- const size_t expr_text_len = strlen(expr_text);
- size_t bytes_written = expr_text_len;
- if (file.Write(expr_text, bytes_written).Success())
- {
- if (bytes_written == expr_text_len)
- {
- file.Close();
- source_mgr.setMainFileID(source_mgr.createFileID(m_file_manager->getFile(result_path),
- SourceLocation(), SrcMgr::C_User));
- created_main_file = true;
- }
- }
+ClangExpressionParser::~ClangExpressionParser() {}
+
+unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) {
+ ClangDiagnosticManagerAdapter *adapter =
+ static_cast<ClangDiagnosticManagerAdapter *>(
+ m_compiler->getDiagnostics().getClient());
+ clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough();
+ diag_buf->FlushDiagnostics(m_compiler->getDiagnostics());
+
+ adapter->ResetManager(&diagnostic_manager);
+
+ const char *expr_text = m_expr.Text();
+
+ clang::SourceManager &source_mgr = m_compiler->getSourceManager();
+ bool created_main_file = false;
+ if (m_compiler->getCodeGenOpts().getDebugInfo() ==
+ codegenoptions::FullDebugInfo) {
+ int temp_fd = -1;
+ llvm::SmallString<PATH_MAX> result_path;
+ FileSpec tmpdir_file_spec;
+ if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir,
+ tmpdir_file_spec)) {
+ tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
+ std::string temp_source_path = tmpdir_file_spec.GetPath();
+ llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
+ } else {
+ llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
+ }
+
+ if (temp_fd != -1) {
+ lldb_private::File file(temp_fd, true);
+ const size_t expr_text_len = strlen(expr_text);
+ size_t bytes_written = expr_text_len;
+ if (file.Write(expr_text, bytes_written).Success()) {
+ if (bytes_written == expr_text_len) {
+ file.Close();
+ source_mgr.setMainFileID(
+ source_mgr.createFileID(m_file_manager->getFile(result_path),
+ SourceLocation(), SrcMgr::C_User));
+ created_main_file = true;
}
+ }
}
+ }
- if (!created_main_file)
- {
- std::unique_ptr<MemoryBuffer> memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__);
- source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
- }
+ if (!created_main_file) {
+ std::unique_ptr<MemoryBuffer> memory_buffer =
+ MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__);
+ source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
+ }
- diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
+ diag_buf->BeginSourceFile(m_compiler->getLangOpts(),
+ &m_compiler->getPreprocessor());
- ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionHelper *type_system_helper =
+ dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
- ASTConsumer *ast_transformer = type_system_helper->ASTTransformer(m_code_generator.get());
+ ASTConsumer *ast_transformer =
+ type_system_helper->ASTTransformer(m_code_generator.get());
- if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap())
- decl_map->InstallCodeGenerator(m_code_generator.get());
+ if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap())
+ decl_map->InstallCodeGenerator(m_code_generator.get());
- if (ast_transformer)
- {
- ast_transformer->Initialize(m_compiler->getASTContext());
- ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext());
- }
- else
- {
- m_code_generator->Initialize(m_compiler->getASTContext());
- ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext());
- }
+ if (ast_transformer) {
+ ast_transformer->Initialize(m_compiler->getASTContext());
+ ParseAST(m_compiler->getPreprocessor(), ast_transformer,
+ m_compiler->getASTContext());
+ } else {
+ m_code_generator->Initialize(m_compiler->getASTContext());
+ ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(),
+ m_compiler->getASTContext());
+ }
- diag_buf->EndSourceFile();
+ diag_buf->EndSourceFile();
- unsigned num_errors = diag_buf->getNumErrors();
+ unsigned num_errors = diag_buf->getNumErrors();
- if (m_pp_callbacks && m_pp_callbacks->hasErrors())
- {
- num_errors++;
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "while importing modules:");
- diagnostic_manager.AppendMessageToDiagnostic(m_pp_callbacks->getErrorString().c_str());
- }
+ if (m_pp_callbacks && m_pp_callbacks->hasErrors()) {
+ num_errors++;
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "while importing modules:");
+ diagnostic_manager.AppendMessageToDiagnostic(
+ m_pp_callbacks->getErrorString());
+ }
- if (!num_errors)
- {
- if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes())
- {
- diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't infer the type of a variable");
- num_errors++;
- }
+ if (!num_errors) {
+ if (type_system_helper->DeclMap() &&
+ !type_system_helper->DeclMap()->ResolveUnknownTypes()) {
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "Couldn't infer the type of a variable");
+ num_errors++;
}
+ }
- if (!num_errors)
- {
- type_system_helper->CommitPersistentDecls();
- }
+ if (!num_errors) {
+ type_system_helper->CommitPersistentDecls();
+ }
- adapter->ResetManager();
+ adapter->ResetManager();
- return num_errors;
+ return num_errors;
}
std::string
-ClangExpressionParser::GetClangTargetABI (const ArchSpec &target_arch)
-{
- std::string abi;
-
- if(target_arch.IsMIPS())
- {
- switch (target_arch.GetFlags () & ArchSpec::eMIPSABI_mask)
- {
- case ArchSpec::eMIPSABI_N64:
- abi = "n64"; break;
- case ArchSpec::eMIPSABI_N32:
- abi = "n32"; break;
- case ArchSpec::eMIPSABI_O32:
- abi = "o32"; break;
- default:
- break;
- }
+ClangExpressionParser::GetClangTargetABI(const ArchSpec &target_arch) {
+ std::string abi;
+
+ if (target_arch.IsMIPS()) {
+ switch (target_arch.GetFlags() & ArchSpec::eMIPSABI_mask) {
+ case ArchSpec::eMIPSABI_N64:
+ abi = "n64";
+ break;
+ case ArchSpec::eMIPSABI_N32:
+ abi = "n32";
+ break;
+ case ArchSpec::eMIPSABI_O32:
+ abi = "o32";
+ break;
+ default:
+ break;
}
- return abi;
+ }
+ return abi;
}
-bool
-ClangExpressionParser::RewriteExpression(DiagnosticManager &diagnostic_manager)
-{
- clang::SourceManager &source_manager = m_compiler->getSourceManager();
- clang::edit::EditedSource editor(source_manager, m_compiler->getLangOpts(), nullptr);
- clang::edit::Commit commit(editor);
- clang::Rewriter rewriter(source_manager, m_compiler->getLangOpts());
-
- class RewritesReceiver : public edit::EditsReceiver {
- Rewriter &rewrite;
-
- public:
- RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) { }
-
- void insert(SourceLocation loc, StringRef text) override {
- rewrite.InsertText(loc, text);
- }
- void replace(CharSourceRange range, StringRef text) override {
- rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
- }
- };
-
- RewritesReceiver rewrites_receiver(rewriter);
-
- const DiagnosticList &diagnostics = diagnostic_manager.Diagnostics();
- size_t num_diags = diagnostics.size();
- if (num_diags == 0)
- return false;
-
- for (const Diagnostic *diag : diagnostic_manager.Diagnostics())
- {
- const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
- if (diagnostic && diagnostic->HasFixIts())
- {
- for (const FixItHint &fixit : diagnostic->FixIts())
- {
- // This is cobbed from clang::Rewrite::FixItRewriter.
- if (fixit.CodeToInsert.empty())
- {
- if (fixit.InsertFromRange.isValid())
- {
- commit.insertFromRange(fixit.RemoveRange.getBegin(),
- fixit.InsertFromRange, /*afterToken=*/false,
- fixit.BeforePreviousInsertions);
- }
- else
- commit.remove(fixit.RemoveRange);
- }
- else
- {
- if (fixit.RemoveRange.isTokenRange() ||
- fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
- commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
- else
- commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
- /*afterToken=*/false, fixit.BeforePreviousInsertions);
- }
- }
- }
+bool ClangExpressionParser::RewriteExpression(
+ DiagnosticManager &diagnostic_manager) {
+ clang::SourceManager &source_manager = m_compiler->getSourceManager();
+ clang::edit::EditedSource editor(source_manager, m_compiler->getLangOpts(),
+ nullptr);
+ clang::edit::Commit commit(editor);
+ clang::Rewriter rewriter(source_manager, m_compiler->getLangOpts());
+
+ class RewritesReceiver : public edit::EditsReceiver {
+ Rewriter &rewrite;
+
+ public:
+ RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) {}
+
+ void insert(SourceLocation loc, StringRef text) override {
+ rewrite.InsertText(loc, text);
}
-
- // FIXME - do we want to try to propagate specific errors here?
- if (!commit.isCommitable())
- return false;
- else if (!editor.commit(commit))
- return false;
-
- // Now play all the edits, and stash the result in the diagnostic manager.
- editor.applyRewrites(rewrites_receiver);
- RewriteBuffer &main_file_buffer = rewriter.getEditBuffer(source_manager.getMainFileID());
-
- std::string fixed_expression;
- llvm::raw_string_ostream out_stream(fixed_expression);
-
- main_file_buffer.write(out_stream);
- out_stream.flush();
- diagnostic_manager.SetFixedExpression(fixed_expression);
-
- return true;
-}
+ void replace(CharSourceRange range, StringRef text) override {
+ rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
+ }
+ };
-static bool FindFunctionInModule (ConstString &mangled_name,
- llvm::Module *module,
- const char *orig_name)
-{
- for (const auto &func : module->getFunctionList())
- {
- const StringRef &name = func.getName();
- if (name.find(orig_name) != StringRef::npos)
- {
- mangled_name.SetString(name);
- return true;
+ RewritesReceiver rewrites_receiver(rewriter);
+
+ const DiagnosticList &diagnostics = diagnostic_manager.Diagnostics();
+ size_t num_diags = diagnostics.size();
+ if (num_diags == 0)
+ return false;
+
+ for (const Diagnostic *diag : diagnostic_manager.Diagnostics()) {
+ const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
+ if (diagnostic && diagnostic->HasFixIts()) {
+ for (const FixItHint &fixit : diagnostic->FixIts()) {
+ // This is cobbed from clang::Rewrite::FixItRewriter.
+ if (fixit.CodeToInsert.empty()) {
+ if (fixit.InsertFromRange.isValid()) {
+ commit.insertFromRange(fixit.RemoveRange.getBegin(),
+ fixit.InsertFromRange, /*afterToken=*/false,
+ fixit.BeforePreviousInsertions);
+ } else
+ commit.remove(fixit.RemoveRange);
+ } else {
+ if (fixit.RemoveRange.isTokenRange() ||
+ fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
+ commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
+ else
+ commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
+ /*afterToken=*/false, fixit.BeforePreviousInsertions);
}
+ }
}
+ }
+ // FIXME - do we want to try to propagate specific errors here?
+ if (!commit.isCommitable())
+ return false;
+ else if (!editor.commit(commit))
return false;
+
+ // Now play all the edits, and stash the result in the diagnostic manager.
+ editor.applyRewrites(rewrites_receiver);
+ RewriteBuffer &main_file_buffer =
+ rewriter.getEditBuffer(source_manager.getMainFileID());
+
+ std::string fixed_expression;
+ llvm::raw_string_ostream out_stream(fixed_expression);
+
+ main_file_buffer.write(out_stream);
+ out_stream.flush();
+ diagnostic_manager.SetFixedExpression(fixed_expression);
+
+ return true;
}
-lldb_private::Error
-ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
- lldb::addr_t &func_end,
- lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx,
- bool &can_interpret,
- ExecutionPolicy execution_policy)
-{
- func_addr = LLDB_INVALID_ADDRESS;
- func_end = LLDB_INVALID_ADDRESS;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- lldb_private::Error err;
-
- std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());
-
- if (!llvm_module_ap.get())
- {
- err.SetErrorToGenericError();
- err.SetErrorString("IR doesn't contain a module");
- return err;
+static bool FindFunctionInModule(ConstString &mangled_name,
+ llvm::Module *module, const char *orig_name) {
+ for (const auto &func : module->getFunctionList()) {
+ const StringRef &name = func.getName();
+ if (name.find(orig_name) != StringRef::npos) {
+ mangled_name.SetString(name);
+ return true;
}
+ }
- ConstString function_name;
+ return false;
+}
- if (execution_policy != eExecutionPolicyTopLevel)
- {
- // Find the actual name of the function (it's often mangled somehow)
+lldb_private::Error ClangExpressionParser::PrepareForExecution(
+ lldb::addr_t &func_addr, lldb::addr_t &func_end,
+ lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx,
+ bool &can_interpret, ExecutionPolicy execution_policy) {
+ func_addr = LLDB_INVALID_ADDRESS;
+ func_end = LLDB_INVALID_ADDRESS;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
- {
- err.SetErrorToGenericError();
- err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
- return err;
- }
- else
- {
- if (log)
- log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
- }
- }
+ lldb_private::Error err;
- SymbolContext sc;
+ std::unique_ptr<llvm::Module> llvm_module_ap(
+ m_code_generator->ReleaseModule());
- if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP())
- {
- sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
- }
- else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP())
- {
- sc.target_sp = target_sp;
+ if (!llvm_module_ap.get()) {
+ err.SetErrorToGenericError();
+ err.SetErrorString("IR doesn't contain a module");
+ return err;
+ }
+
+ ConstString function_name;
+
+ if (execution_policy != eExecutionPolicyTopLevel) {
+ // Find the actual name of the function (it's often mangled somehow)
+
+ if (!FindFunctionInModule(function_name, llvm_module_ap.get(),
+ m_expr.FunctionName())) {
+ err.SetErrorToGenericError();
+ err.SetErrorStringWithFormat("Couldn't find %s() in the module",
+ m_expr.FunctionName());
+ return err;
+ } else {
+ if (log)
+ log->Printf("Found function %s for %s", function_name.AsCString(),
+ m_expr.FunctionName());
}
+ }
- LLVMUserExpression::IRPasses custom_passes;
- {
- auto lang = m_expr.Language();
- if (log)
- log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__,
- Language::GetNameForLanguageType(lang));
-
- if (lang != lldb::eLanguageTypeUnknown)
- {
- auto runtime = exe_ctx.GetProcessSP()->GetLanguageRuntime(lang);
- if (runtime)
- runtime->GetIRPasses(custom_passes);
- }
+ SymbolContext sc;
+
+ if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP()) {
+ sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
+ } else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP()) {
+ sc.target_sp = target_sp;
+ }
+
+ LLVMUserExpression::IRPasses custom_passes;
+ {
+ auto lang = m_expr.Language();
+ if (log)
+ log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__,
+ Language::GetNameForLanguageType(lang));
+ lldb::ProcessSP process_sp = exe_ctx.GetProcessSP();
+ if (process_sp && lang != lldb::eLanguageTypeUnknown) {
+ auto runtime = process_sp->GetLanguageRuntime(lang);
+ if (runtime)
+ runtime->GetIRPasses(custom_passes);
}
+ }
+
+ if (custom_passes.EarlyPasses) {
+ if (log)
+ log->Printf("%s - Running Early IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
+
+ custom_passes.EarlyPasses->run(*llvm_module_ap);
+ }
+
+ execution_unit_sp.reset(
+ new IRExecutionUnit(m_llvm_context, // handed off here
+ llvm_module_ap, // handed off here
+ function_name, exe_ctx.GetTargetSP(), sc,
+ m_compiler->getTargetOpts().Features));
+
+ ClangExpressionHelper *type_system_helper =
+ dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionDeclMap *decl_map =
+ type_system_helper->DeclMap(); // result can be NULL
- if (custom_passes.EarlyPasses)
- {
- if (log)
- log->Printf("%s - Running Early IR Passes from LanguageRuntime on expression module '%s'", __FUNCTION__,
- m_expr.FunctionName());
+ if (decl_map) {
+ Stream *error_stream = NULL;
+ Target *target = exe_ctx.GetTargetPtr();
+ error_stream = target->GetDebugger().GetErrorFile().get();
- custom_passes.EarlyPasses->run(*llvm_module_ap);
+ IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(),
+ *execution_unit_sp, *error_stream,
+ function_name.AsCString());
+
+ bool ir_can_run =
+ ir_for_target.runOnModule(*execution_unit_sp->GetModule());
+
+ if (!ir_can_run) {
+ err.SetErrorString(
+ "The expression could not be prepared to run in the target");
+ return err;
}
- execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
- llvm_module_ap, // handed off here
- function_name,
- exe_ctx.GetTargetSP(),
- sc,
- m_compiler->getTargetOpts().Features));
+ Process *process = exe_ctx.GetProcessPtr();
- ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
- ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL
+ if (execution_policy != eExecutionPolicyAlways &&
+ execution_policy != eExecutionPolicyTopLevel) {
+ lldb_private::Error interpret_error;
- if (decl_map)
- {
- Stream *error_stream = NULL;
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- error_stream = target->GetDebugger().GetErrorFile().get();
+ bool interpret_function_calls =
+ !process ? false : process->CanInterpretFunctionCalls();
+ can_interpret = IRInterpreter::CanInterpret(
+ *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
+ interpret_error, interpret_function_calls);
- IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream,
- function_name.AsCString());
+ if (!can_interpret && execution_policy == eExecutionPolicyNever) {
+ err.SetErrorStringWithFormat("Can't run the expression locally: %s",
+ interpret_error.AsCString());
+ return err;
+ }
+ }
- bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());
+ if (!process && execution_policy == eExecutionPolicyAlways) {
+ err.SetErrorString("Expression needed to run in the target, but the "
+ "target can't be run");
+ return err;
+ }
- Process *process = exe_ctx.GetProcessPtr();
+ if (!process && execution_policy == eExecutionPolicyTopLevel) {
+ err.SetErrorString("Top-level code needs to be inserted into a runnable "
+ "target, but the target can't be run");
+ return err;
+ }
- if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel)
- {
- lldb_private::Error interpret_error;
+ if (execution_policy == eExecutionPolicyAlways ||
+ (execution_policy != eExecutionPolicyTopLevel && !can_interpret)) {
+ if (m_expr.NeedsValidation() && process) {
+ if (!process->GetDynamicCheckers()) {
+ DynamicCheckerFunctions *dynamic_checkers =
+ new DynamicCheckerFunctions();
- bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls();
- can_interpret =
- IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
- interpret_error, interpret_function_calls);
+ DiagnosticManager install_diagnostics;
- if (!can_interpret && execution_policy == eExecutionPolicyNever)
- {
- err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
- return err;
- }
- }
+ 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());
- if (!ir_can_run)
- {
- err.SetErrorString("The expression could not be prepared to run in the target");
return err;
- }
+ }
- if (!process && execution_policy == eExecutionPolicyAlways)
- {
- err.SetErrorString("Expression needed to run in the target, but the target can't be run");
- return err;
- }
+ process->SetDynamicCheckers(dynamic_checkers);
- if (!process && execution_policy == eExecutionPolicyTopLevel)
- {
- err.SetErrorString(
- "Top-level code needs to be inserted into a runnable target, but the target can't be run");
- return err;
+ if (log)
+ log->Printf("== [ClangUserExpression::Evaluate] Finished "
+ "installing dynamic checkers ==");
}
- if (execution_policy == eExecutionPolicyAlways ||
- (execution_policy != eExecutionPolicyTopLevel && !can_interpret))
- {
- if (m_expr.NeedsValidation() && process)
- {
- if (!process->GetDynamicCheckers())
- {
- DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
-
- DiagnosticManager install_diagnostics;
-
- 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());
-
- return err;
- }
-
- process->SetDynamicCheckers(dynamic_checkers);
-
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
- }
-
- IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());
-
- llvm::Module *module = execution_unit_sp->GetModule();
- if (!module || !ir_dynamic_checks.runOnModule(*module))
- {
- err.SetErrorToGenericError();
- err.SetErrorString("Couldn't add dynamic checks to the expression");
- return err;
- }
-
- if (custom_passes.LatePasses)
- {
- if (log)
- log->Printf("%s - Running Late IR Passes from LanguageRuntime on expression module '%s'",
- __FUNCTION__, m_expr.FunctionName());
-
- custom_passes.LatePasses->run(*module);
- }
- }
+ IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(),
+ function_name.AsCString());
+
+ llvm::Module *module = execution_unit_sp->GetModule();
+ if (!module || !ir_dynamic_checks.runOnModule(*module)) {
+ err.SetErrorToGenericError();
+ err.SetErrorString("Couldn't add dynamic checks to the expression");
+ return err;
}
- if (execution_policy == eExecutionPolicyAlways || execution_policy == eExecutionPolicyTopLevel ||
- !can_interpret)
- {
- execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
+ if (custom_passes.LatePasses) {
+ if (log)
+ log->Printf("%s - Running Late IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
+
+ custom_passes.LatePasses->run(*module);
}
+ }
}
- else
- {
- execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
+
+ if (execution_policy == eExecutionPolicyAlways ||
+ execution_policy == eExecutionPolicyTopLevel || !can_interpret) {
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
}
+ } else {
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
+ }
- return err;
+ return err;
}
-lldb_private::Error
-ClangExpressionParser::RunStaticInitializers (lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx)
-{
- lldb_private::Error err;
-
- lldbassert(execution_unit_sp.get());
- lldbassert(exe_ctx.HasThreadScope());
-
- if (!execution_unit_sp.get())
- {
- err.SetErrorString ("can't run static initializers for a NULL execution unit");
- return err;
- }
-
- if (!exe_ctx.HasThreadScope())
- {
- err.SetErrorString ("can't run static initializers without a thread");
- return err;
- }
-
- std::vector<lldb::addr_t> static_initializers;
-
- execution_unit_sp->GetStaticInitializers(static_initializers);
-
- for (lldb::addr_t static_initializer : static_initializers)
- {
- EvaluateExpressionOptions options;
-
- lldb::ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction(exe_ctx.GetThreadRef(),
- Address(static_initializer),
- CompilerType(),
- llvm::ArrayRef<lldb::addr_t>(),
- options));
-
- DiagnosticManager execution_errors;
- lldb::ExpressionResults results = exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan(exe_ctx, call_static_initializer, options, execution_errors);
-
- if (results != lldb::eExpressionCompleted)
- {
- err.SetErrorStringWithFormat ("couldn't run static initializer: %s", execution_errors.GetString().c_str());
- return err;
- }
- }
-
+lldb_private::Error ClangExpressionParser::RunStaticInitializers(
+ lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) {
+ lldb_private::Error err;
+
+ lldbassert(execution_unit_sp.get());
+ lldbassert(exe_ctx.HasThreadScope());
+
+ if (!execution_unit_sp.get()) {
+ err.SetErrorString(
+ "can't run static initializers for a NULL execution unit");
+ return err;
+ }
+
+ if (!exe_ctx.HasThreadScope()) {
+ err.SetErrorString("can't run static initializers without a thread");
return err;
+ }
+
+ std::vector<lldb::addr_t> static_initializers;
+
+ execution_unit_sp->GetStaticInitializers(static_initializers);
+
+ for (lldb::addr_t static_initializer : static_initializers) {
+ EvaluateExpressionOptions options;
+
+ lldb::ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction(
+ exe_ctx.GetThreadRef(), Address(static_initializer), CompilerType(),
+ llvm::ArrayRef<lldb::addr_t>(), options));
+
+ DiagnosticManager execution_errors;
+ lldb::ExpressionResults results =
+ exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan(
+ exe_ctx, call_static_initializer, options, execution_errors);
+
+ if (results != lldb::eExpressionCompleted) {
+ err.SetErrorStringWithFormat("couldn't run static initializer: %s",
+ execution_errors.GetString().c_str());
+ return err;
+ }
+ }
+
+ return err;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 34c0212b73a4..3f01156c6ded 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -20,13 +20,13 @@
#include <string>
#include <vector>
-namespace lldb_private
-{
+namespace lldb_private {
class IRExecutionUnit;
-
+
//----------------------------------------------------------------------
-/// @class ClangExpressionParser ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
+/// @class ClangExpressionParser ClangExpressionParser.h
+/// "lldb/Expression/ClangExpressionParser.h"
/// @brief Encapsulates an instance of Clang that can parse expressions.
///
/// ClangExpressionParser is responsible for preparing an instance of
@@ -35,134 +35,132 @@ class IRExecutionUnit;
/// conversion to formats (DWARF bytecode, or JIT compiled machine code)
/// that can be executed.
//----------------------------------------------------------------------
-class ClangExpressionParser : public ExpressionParser
-{
+class ClangExpressionParser : public ExpressionParser {
public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] exe_scope,
- /// If non-NULL, an execution context scope that can help to
- /// correctly create an expression with a valid process for
- /// optional tuning Objective-C runtime support. Can be NULL.
- ///
- /// @param[in] expr
- /// The expression to be parsed.
- //------------------------------------------------------------------
- ClangExpressionParser (ExecutionContextScope *exe_scope,
- Expression &expr,
- bool generate_debug_info);
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangExpressionParser () override;
-
- //------------------------------------------------------------------
- /// Parse a single expression and convert it to IR using Clang. Don't
- /// wrap the expression in anything at all.
- ///
- /// @param[in] diagnostic_manager
- /// The diagnostic manager to report errors to.
- ///
- /// @return
- /// The number of errors encountered during parsing. 0 means
- /// success.
- //------------------------------------------------------------------
- unsigned
- Parse(DiagnosticManager &diagnostic_manager) override;
-
- bool
- RewriteExpression(DiagnosticManager &diagnostic_manager) override;
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] exe_scope,
+ /// If non-NULL, an execution context scope that can help to
+ /// correctly create an expression with a valid process for
+ /// optional tuning Objective-C runtime support. Can be NULL.
+ ///
+ /// @param[in] expr
+ /// The expression to be parsed.
+ //------------------------------------------------------------------
+ ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr,
+ bool generate_debug_info);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionParser() override;
+
+ //------------------------------------------------------------------
+ /// Parse a single expression and convert it to IR using Clang. Don't
+ /// wrap the expression in anything at all.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
+ ///
+ /// @return
+ /// The number of errors encountered during parsing. 0 means
+ /// success.
+ //------------------------------------------------------------------
+ unsigned Parse(DiagnosticManager &diagnostic_manager) override;
+
+ bool RewriteExpression(DiagnosticManager &diagnostic_manager) override;
- //------------------------------------------------------------------
- /// Ready an already-parsed expression for execution, possibly
- /// evaluating it statically.
- ///
- /// @param[out] func_addr
- /// The address to which the function has been written.
- ///
- /// @param[out] func_end
- /// The end of the function's allocated memory region. (func_addr
- /// and func_end do not delimit an allocated region; the allocated
- /// region may begin before func_addr.)
- ///
- /// @param[in] execution_unit_sp
- /// After parsing, ownership of the execution unit for
- /// for the expression is handed to this shared pointer.
- ///
- /// @param[in] exe_ctx
- /// The execution context to write the function into.
- ///
- /// @param[out] evaluated_statically
- /// Set to true if the expression could be interpreted statically;
- /// untouched otherwise.
- ///
- /// @param[out] const_result
- /// If the result of the expression is constant, and the
- /// expression has no side effects, this is set to the result of the
- /// expression.
- ///
- /// @param[in] execution_policy
- /// Determines whether the expression must be JIT-compiled, must be
- /// evaluated statically, or whether this decision may be made
- /// opportunistically.
- ///
- /// @return
- /// An error code indicating the success or failure of the operation.
- /// Test with Success().
- //------------------------------------------------------------------
- Error
- PrepareForExecution (lldb::addr_t &func_addr,
- lldb::addr_t &func_end,
- lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx,
- bool &can_interpret,
- lldb_private::ExecutionPolicy execution_policy) override;
-
- //------------------------------------------------------------------
- /// Run all static initializers for an execution unit.
- ///
- /// @param[in] execution_unit_sp
- /// The execution unit.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when running them. Thread can't be null.
- ///
- /// @return
- /// The error code indicating the
- //------------------------------------------------------------------
- Error
- RunStaticInitializers (lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx);
+ //------------------------------------------------------------------
+ /// Ready an already-parsed expression for execution, possibly
+ /// evaluating it statically.
+ ///
+ /// @param[out] func_addr
+ /// The address to which the function has been written.
+ ///
+ /// @param[out] func_end
+ /// The end of the function's allocated memory region. (func_addr
+ /// and func_end do not delimit an allocated region; the allocated
+ /// region may begin before func_addr.)
+ ///
+ /// @param[in] execution_unit_sp
+ /// After parsing, ownership of the execution unit for
+ /// for the expression is handed to this shared pointer.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to write the function into.
+ ///
+ /// @param[out] evaluated_statically
+ /// Set to true if the expression could be interpreted statically;
+ /// untouched otherwise.
+ ///
+ /// @param[out] const_result
+ /// If the result of the expression is constant, and the
+ /// expression has no side effects, this is set to the result of the
+ /// expression.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether the expression must be JIT-compiled, must be
+ /// evaluated statically, or whether this decision may be made
+ /// opportunistically.
+ ///
+ /// @return
+ /// An error code indicating the success or failure of the operation.
+ /// Test with Success().
+ //------------------------------------------------------------------
+ Error
+ PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end,
+ lldb::IRExecutionUnitSP &execution_unit_sp,
+ ExecutionContext &exe_ctx, bool &can_interpret,
+ lldb_private::ExecutionPolicy execution_policy) override;
+
+ //------------------------------------------------------------------
+ /// Run all static initializers for an execution unit.
+ ///
+ /// @param[in] execution_unit_sp
+ /// The execution unit.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when running them. Thread can't be null.
+ ///
+ /// @return
+ /// The error code indicating the
+ //------------------------------------------------------------------
+ Error RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Returns a string representing current ABI.
+ ///
+ /// @param[in] target_arch
+ /// The target architecture.
+ ///
+ /// @return
+ /// A string representing target ABI for the current architecture.
+ //-------------------------------------------------------------------
+ std::string GetClangTargetABI(const ArchSpec &target_arch);
- //------------------------------------------------------------------
- /// Returns a string representing current ABI.
- ///
- /// @param[in] target_arch
- /// The target architecture.
- ///
- /// @return
- /// A string representing target ABI for the current architecture.
- //-------------------------------------------------------------------
- std::string
- GetClangTargetABI (const ArchSpec &target_arch);
-
private:
- 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
-
- class LLDBPreprocessorCallbacks;
- LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor encounters module imports
- std::unique_ptr<ClangASTContext> m_ast_context;
+ 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
+
+ class LLDBPreprocessorCallbacks;
+ LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor
+ ///encounters module imports
+ std::unique_ptr<ClangASTContext> m_ast_context;
};
-
}
-#endif // liblldb_ClangExpressionParser_h_
+#endif // liblldb_ClangExpressionParser_h_
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
index 908546b3ecdb..44594ccebfa3 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
@@ -9,7 +9,6 @@
#include "ClangExpressionVariable.h"
-#include "clang/AST/ASTContext.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Stream.h"
@@ -17,60 +16,52 @@
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include "clang/AST/ASTContext.h"
using namespace lldb_private;
using namespace clang;
-const char *g_clang_expression_variable_kind_name = "ClangExpressionVariable";
-
-ClangExpressionVariable::ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars ()
-{
- m_flags = EVNone;
- m_frozen_sp = ValueObjectConstResult::Create (exe_scope, byte_order, addr_byte_size);
+ClangExpressionVariable::ClangExpressionVariable(
+ ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = EVNone;
+ m_frozen_sp =
+ ValueObjectConstResult::Create(exe_scope, byte_order, addr_byte_size);
}
-ClangExpressionVariable::ClangExpressionVariable (ExecutionContextScope *exe_scope,
- Value &value,
- const ConstString &name,
- uint16_t flags) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars ()
-{
- m_flags = flags;
- m_frozen_sp = ValueObjectConstResult::Create (exe_scope, value, name);
+ClangExpressionVariable::ClangExpressionVariable(
+ ExecutionContextScope *exe_scope, Value &value, const ConstString &name,
+ uint16_t flags)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = flags;
+ m_frozen_sp = ValueObjectConstResult::Create(exe_scope, value, name);
}
-ClangExpressionVariable::ClangExpressionVariable (const lldb::ValueObjectSP &valobj_sp) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars ()
-{
- m_flags = EVNone;
- m_frozen_sp = valobj_sp;
+ClangExpressionVariable::ClangExpressionVariable(
+ const lldb::ValueObjectSP &valobj_sp)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = EVNone;
+ m_frozen_sp = valobj_sp;
}
-ClangExpressionVariable::ClangExpressionVariable(ExecutionContextScope *exe_scope,
- const ConstString &name,
- const TypeFromUser& user_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars()
-{
- m_flags = EVNone;
- m_frozen_sp = ValueObjectConstResult::Create (exe_scope, byte_order, addr_byte_size);
- SetName (name);
- SetCompilerType (user_type);
+ClangExpressionVariable::ClangExpressionVariable(
+ ExecutionContextScope *exe_scope, const ConstString &name,
+ const TypeFromUser &user_type, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = EVNone;
+ m_frozen_sp =
+ ValueObjectConstResult::Create(exe_scope, byte_order, addr_byte_size);
+ SetName(name);
+ SetCompilerType(user_type);
}
-TypeFromUser
-ClangExpressionVariable::GetTypeFromUser()
-{
- TypeFromUser tfu (m_frozen_sp->GetCompilerType());
- return tfu;
+TypeFromUser ClangExpressionVariable::GetTypeFromUser() {
+ TypeFromUser tfu(m_frozen_sp->GetCompilerType());
+ return tfu;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index a4596148f6c7..c894506a227b 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -24,15 +24,15 @@
#include "llvm/Support/Casting.h"
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/lldb-public.h"
namespace llvm {
- class Value;
+class Value;
}
namespace lldb_private {
@@ -40,7 +40,8 @@ namespace lldb_private {
class ValueObjectConstResult;
//----------------------------------------------------------------------
-/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
+/// @class ClangExpressionVariable ClangExpressionVariable.h
+/// "lldb/Expression/ClangExpressionVariable.h"
/// @brief Encapsulates one variable for the expression parser.
///
/// The expression parser uses variables in three different contexts:
@@ -62,204 +63,178 @@ class ValueObjectConstResult;
/// polymorphism, and provides necessary support methods. Its interface
/// is RTTI-neutral.
//----------------------------------------------------------------------
-class ClangExpressionVariable : public ExpressionVariable
-{
+class ClangExpressionVariable : public ExpressionVariable {
public:
- ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size);
-
- ClangExpressionVariable (ExecutionContextScope *exe_scope,
- Value &value,
- const ConstString &name,
- uint16_t flags = EVNone);
-
- ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
-
- ClangExpressionVariable(ExecutionContextScope *exe_scope,
- const ConstString &name,
- const TypeFromUser& user_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size);
-
- //----------------------------------------------------------------------
- /// Utility functions for dealing with ExpressionVariableLists in Clang-specific ways
- //----------------------------------------------------------------------
-
- //----------------------------------------------------------------------
- /// Finds a variable by NamedDecl in the list.
- ///
- /// @param[in] name
- /// The name of the requested variable.
- ///
- /// @return
- /// The variable requested, or NULL if that variable is not in the list.
- //----------------------------------------------------------------------
- static ClangExpressionVariable *
- FindVariableInList (ExpressionVariableList &list, const clang::NamedDecl *decl, uint64_t parser_id)
- {
- lldb::ExpressionVariableSP var_sp;
- for (size_t index = 0, size = list.GetSize(); index < size; ++index)
- {
- var_sp = list.GetVariableAtIndex(index);
-
- if (ClangExpressionVariable *clang_var = llvm::dyn_cast<ClangExpressionVariable>(var_sp.get()))
- {
- ClangExpressionVariable::ParserVars *parser_vars = clang_var->GetParserVars(parser_id);
-
- if (parser_vars && parser_vars->m_named_decl == decl)
- return clang_var;
- }
- }
- return nullptr;
+ ClangExpressionVariable(ExecutionContextScope *exe_scope,
+ lldb::ByteOrder byte_order, uint32_t addr_byte_size);
+
+ ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value,
+ const ConstString &name, uint16_t flags = EVNone);
+
+ ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
+
+ ClangExpressionVariable(ExecutionContextScope *exe_scope,
+ const ConstString &name,
+ const TypeFromUser &user_type,
+ lldb::ByteOrder byte_order, uint32_t addr_byte_size);
+
+ //----------------------------------------------------------------------
+ /// Utility functions for dealing with ExpressionVariableLists in
+ /// Clang-specific ways
+ //----------------------------------------------------------------------
+
+ //----------------------------------------------------------------------
+ /// Finds a variable by NamedDecl in the list.
+ ///
+ /// @param[in] name
+ /// The name of the requested variable.
+ ///
+ /// @return
+ /// The variable requested, or NULL if that variable is not in the list.
+ //----------------------------------------------------------------------
+ static ClangExpressionVariable *
+ FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl,
+ uint64_t parser_id) {
+ lldb::ExpressionVariableSP var_sp;
+ for (size_t index = 0, size = list.GetSize(); index < size; ++index) {
+ var_sp = list.GetVariableAtIndex(index);
+
+ if (ClangExpressionVariable *clang_var =
+ llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) {
+ ClangExpressionVariable::ParserVars *parser_vars =
+ clang_var->GetParserVars(parser_id);
+
+ if (parser_vars && parser_vars->m_named_decl == decl)
+ return clang_var;
+ }
}
+ return nullptr;
+ }
+
+ //----------------------------------------------------------------------
+ /// If the variable contains its own data, make a Value point at it.
+ /// If \a exe_ctx in not NULL, the value will be resolved in with
+ /// that execution context.
+ ///
+ /// @param[in] value
+ /// The value to point at the data.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use to resolve \a value.
+ ///
+ /// @return
+ /// True on success; false otherwise (in particular, if this variable
+ /// does not contain its own data).
+ //----------------------------------------------------------------------
+ bool PointValueAtData(Value &value, ExecutionContext *exe_ctx);
+
+ //----------------------------------------------------------------------
+ /// The following values should not live beyond parsing
+ //----------------------------------------------------------------------
+ class ParserVars {
+ public:
+ ParserVars()
+ : m_parser_type(), m_named_decl(NULL), m_llvm_value(NULL),
+ m_lldb_value(), m_lldb_var(), m_lldb_sym(NULL) {}
+
+ TypeFromParser
+ m_parser_type; ///< The type of the variable according to the parser
+ const clang::NamedDecl
+ *m_named_decl; ///< The Decl corresponding to this variable
+ llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable;
+ ///usually a GlobalValue
+ lldb_private::Value
+ m_lldb_value; ///< The value found in LLDB for this variable
+ lldb::VariableSP m_lldb_var; ///< The original variable for this variable
+ const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this
+ ///variable, if it was a symbol
+ };
- //----------------------------------------------------------------------
- /// If the variable contains its own data, make a Value point at it.
- /// If \a exe_ctx in not NULL, the value will be resolved in with
- /// that execution context.
- ///
- /// @param[in] value
- /// The value to point at the data.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use to resolve \a value.
- ///
- /// @return
- /// True on success; false otherwise (in particular, if this variable
- /// does not contain its own data).
- //----------------------------------------------------------------------
- bool
- PointValueAtData(Value &value, ExecutionContext *exe_ctx);
-
- //----------------------------------------------------------------------
- /// The following values should not live beyond parsing
- //----------------------------------------------------------------------
- class ParserVars
- {
- public:
-
- ParserVars() :
- m_parser_type(),
- m_named_decl (NULL),
- m_llvm_value (NULL),
- m_lldb_value (),
- m_lldb_var (),
- m_lldb_sym (NULL)
- {
- }
-
- TypeFromParser m_parser_type; ///< The type of the variable according to the parser
- const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable
- llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue
- lldb_private::Value m_lldb_value; ///< The value found in LLDB for this variable
- lldb::VariableSP m_lldb_var; ///< The original variable for this variable
- const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
- };
-
private:
- typedef std::map <uint64_t, ParserVars> ParserVarMap;
- ParserVarMap m_parser_vars;
+ typedef std::map<uint64_t, ParserVars> ParserVarMap;
+ ParserVarMap m_parser_vars;
public:
- //----------------------------------------------------------------------
- /// Make this variable usable by the parser by allocating space for
- /// parser-specific variables
- //----------------------------------------------------------------------
- void
- EnableParserVars(uint64_t parser_id)
- {
- m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate parser-specific variables
- //----------------------------------------------------------------------
- void
- DisableParserVars(uint64_t parser_id)
- {
- m_parser_vars.erase(parser_id);
- }
-
- //----------------------------------------------------------------------
- /// Access parser-specific variables
- //----------------------------------------------------------------------
- ParserVars *
- GetParserVars(uint64_t parser_id)
- {
- ParserVarMap::iterator i = m_parser_vars.find(parser_id);
-
- if (i == m_parser_vars.end())
- return NULL;
- else
- return &i->second;
- }
-
- //----------------------------------------------------------------------
- /// The following values are valid if the variable is used by JIT code
- //----------------------------------------------------------------------
- struct JITVars {
- JITVars () :
- m_alignment (0),
- m_size (0),
- m_offset (0)
- {
- }
-
- lldb::offset_t m_alignment; ///< The required alignment of the variable, in bytes
- size_t m_size; ///< The space required for the variable, in bytes
- lldb::offset_t m_offset; ///< The offset of the variable in the struct, in bytes
- };
-
+ //----------------------------------------------------------------------
+ /// Make this variable usable by the parser by allocating space for
+ /// parser-specific variables
+ //----------------------------------------------------------------------
+ void EnableParserVars(uint64_t parser_id) {
+ m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate parser-specific variables
+ //----------------------------------------------------------------------
+ void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); }
+
+ //----------------------------------------------------------------------
+ /// Access parser-specific variables
+ //----------------------------------------------------------------------
+ ParserVars *GetParserVars(uint64_t parser_id) {
+ ParserVarMap::iterator i = m_parser_vars.find(parser_id);
+
+ if (i == m_parser_vars.end())
+ return NULL;
+ else
+ return &i->second;
+ }
+
+ //----------------------------------------------------------------------
+ /// The following values are valid if the variable is used by JIT code
+ //----------------------------------------------------------------------
+ struct JITVars {
+ JITVars() : m_alignment(0), m_size(0), m_offset(0) {}
+
+ lldb::offset_t
+ m_alignment; ///< The required alignment of the variable, in bytes
+ size_t m_size; ///< The space required for the variable, in bytes
+ lldb::offset_t
+ m_offset; ///< The offset of the variable in the struct, in bytes
+ };
+
private:
- typedef std::map <uint64_t, JITVars> JITVarMap;
- JITVarMap m_jit_vars;
-
+ typedef std::map<uint64_t, JITVars> JITVarMap;
+ JITVarMap m_jit_vars;
+
public:
- //----------------------------------------------------------------------
- /// Make this variable usable for materializing for the JIT by allocating
- /// space for JIT-specific variables
- //----------------------------------------------------------------------
- void
- EnableJITVars(uint64_t parser_id)
- {
- m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate JIT-specific variables
- //----------------------------------------------------------------------
- void
- DisableJITVars(uint64_t parser_id)
- {
- m_jit_vars.erase(parser_id);
- }
-
- JITVars *GetJITVars(uint64_t parser_id)
- {
- JITVarMap::iterator i = m_jit_vars.find(parser_id);
-
- if (i == m_jit_vars.end())
- return NULL;
- else
- return &i->second;
- }
-
- TypeFromUser
- GetTypeFromUser ();
-
- //------------------------------------------------------------------
- // llvm casting support
- //------------------------------------------------------------------
- static bool classof(const ExpressionVariable *ev)
- {
- return ev->getKind() == ExpressionVariable::eKindClang;
- }
-
- //----------------------------------------------------------------------
- /// Members
- //----------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
+ //----------------------------------------------------------------------
+ /// Make this variable usable for materializing for the JIT by allocating
+ /// space for JIT-specific variables
+ //----------------------------------------------------------------------
+ void EnableJITVars(uint64_t parser_id) {
+ m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate JIT-specific variables
+ //----------------------------------------------------------------------
+ void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); }
+
+ JITVars *GetJITVars(uint64_t parser_id) {
+ JITVarMap::iterator i = m_jit_vars.find(parser_id);
+
+ if (i == m_jit_vars.end())
+ return NULL;
+ else
+ return &i->second;
+ }
+
+ TypeFromUser GetTypeFromUser();
+
+ //------------------------------------------------------------------
+ // llvm casting support
+ //------------------------------------------------------------------
+ static bool classof(const ExpressionVariable *ev) {
+ return ev->getKind() == ExpressionVariable::eKindClang;
+ }
+
+ //----------------------------------------------------------------------
+ /// Members
+ //----------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(ClangExpressionVariable);
};
} // namespace lldb_private
-#endif // liblldb_ClangExpressionVariable_h_
+#endif // liblldb_ClangExpressionVariable_h_
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 02c0ad5013ec..8151993717de 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -1,4 +1,4 @@
-//===-- ClangFunctionCallerCaller.cpp ---------------------------*- C++ -*-===//
+//===-- ClangFunctionCaller.cpp ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -50,178 +50,177 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// ClangFunctionCaller constructor
//----------------------------------------------------------------------
-ClangFunctionCaller::ClangFunctionCaller
-(
- ExecutionContextScope &exe_scope,
- const CompilerType &return_type,
- const Address& functionAddress,
- const ValueList &arg_value_list,
- const char *name
-) :
- FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, name),
- m_type_system_helper (*this)
-{
- m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
- // Can't make a ClangFunctionCaller without a process.
- assert (m_jit_process_wp.lock());
+ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope,
+ const CompilerType &return_type,
+ const Address &functionAddress,
+ const ValueList &arg_value_list,
+ const char *name)
+ : FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list,
+ name),
+ m_type_system_helper(*this) {
+ m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
+ // Can't make a ClangFunctionCaller without a process.
+ assert(m_jit_process_wp.lock());
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ClangFunctionCaller::~ClangFunctionCaller()
-{
-}
+ClangFunctionCaller::~ClangFunctionCaller() {}
unsigned
-ClangFunctionCaller::CompileFunction (lldb::ThreadSP thread_to_use_sp,
- DiagnosticManager &diagnostic_manager)
-{
- if (m_compiled)
- return 0;
-
- // Compilation might call code, make sure to keep on the thread the caller indicated.
- ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_to_use_sp);
-
- // FIXME: How does clang tell us there's no return value? We need to handle that case.
- unsigned num_errors = 0;
-
- std::string return_type_str (m_function_return_type.GetTypeName().AsCString(""));
-
- // Cons up the function we're going to wrap our call in, then compile it...
- // We declare the function "extern "C"" because the compiler might be in C++
- // mode which would mangle the name and then we couldn't find it again...
- m_wrapper_function_text.clear();
- m_wrapper_function_text.append ("extern \"C\" void ");
- m_wrapper_function_text.append (m_wrapper_function_name);
- m_wrapper_function_text.append (" (void *input)\n{\n struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append (" \n {\n");
- m_wrapper_function_text.append (" ");
- m_wrapper_function_text.append (return_type_str);
- m_wrapper_function_text.append (" (*fn_ptr) (");
-
- // Get the number of arguments. If we have a function type and it is prototyped,
- // trust that, otherwise use the values we were given.
-
- // FIXME: This will need to be extended to handle Variadic functions. We'll need
- // to pull the defined arguments out of the function, then add the types from the
- // arguments list for the variable arguments.
-
- uint32_t num_args = UINT32_MAX;
- bool trust_function = false;
- // GetArgumentCount returns -1 for an unprototyped function.
- CompilerType function_clang_type;
- if (m_function_ptr)
- {
- function_clang_type = m_function_ptr->GetCompilerType();
- if (function_clang_type)
- {
- int num_func_args = function_clang_type.GetFunctionArgumentCount();
- if (num_func_args >= 0)
- {
- trust_function = true;
- num_args = num_func_args;
- }
- }
- }
-
- if (num_args == UINT32_MAX)
- num_args = m_arg_values.GetSize();
-
- std::string args_buffer; // This one stores the definition of all the args in "struct caller".
- std::string args_list_buffer; // This one stores the argument list called from the structure.
- for (size_t i = 0; i < num_args; i++)
- {
- std::string type_name;
-
- if (trust_function)
- {
- type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName().AsCString("");
- }
- else
- {
- CompilerType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetCompilerType ();
- if (clang_qual_type)
- {
- type_name = clang_qual_type.GetTypeName().AsCString("");
- }
- else
- {
- diagnostic_manager.Printf(eDiagnosticSeverityError,
- "Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
- return 1;
- }
- }
-
- m_wrapper_function_text.append (type_name);
- if (i < num_args - 1)
- m_wrapper_function_text.append (", ");
-
- char arg_buf[32];
- args_buffer.append (" ");
- args_buffer.append (type_name);
- snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
- args_buffer.push_back (' ');
- args_buffer.append (arg_buf);
- args_buffer.append (";\n");
-
- args_list_buffer.append ("__lldb_fn_data->");
- args_list_buffer.append (arg_buf);
- if (i < num_args - 1)
- args_list_buffer.append (", ");
-
+ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager) {
+ if (m_compiled)
+ return 0;
+
+ // Compilation might call code, make sure to keep on the thread the caller
+ // indicated.
+ ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(
+ thread_to_use_sp);
+
+ // FIXME: How does clang tell us there's no return value? We need to handle
+ // that case.
+ unsigned num_errors = 0;
+
+ std::string return_type_str(
+ m_function_return_type.GetTypeName().AsCString(""));
+
+ // Cons up the function we're going to wrap our call in, then compile it...
+ // We declare the function "extern "C"" because the compiler might be in C++
+ // mode which would mangle the name and then we couldn't find it again...
+ m_wrapper_function_text.clear();
+ m_wrapper_function_text.append("extern \"C\" void ");
+ m_wrapper_function_text.append(m_wrapper_function_name);
+ m_wrapper_function_text.append(" (void *input)\n{\n struct ");
+ m_wrapper_function_text.append(m_wrapper_struct_name);
+ m_wrapper_function_text.append(" \n {\n");
+ m_wrapper_function_text.append(" ");
+ m_wrapper_function_text.append(return_type_str);
+ m_wrapper_function_text.append(" (*fn_ptr) (");
+
+ // Get the number of arguments. If we have a function type and it is
+ // prototyped,
+ // trust that, otherwise use the values we were given.
+
+ // FIXME: This will need to be extended to handle Variadic functions. We'll
+ // need
+ // to pull the defined arguments out of the function, then add the types from
+ // the
+ // arguments list for the variable arguments.
+
+ uint32_t num_args = UINT32_MAX;
+ bool trust_function = false;
+ // GetArgumentCount returns -1 for an unprototyped function.
+ CompilerType function_clang_type;
+ if (m_function_ptr) {
+ function_clang_type = m_function_ptr->GetCompilerType();
+ if (function_clang_type) {
+ int num_func_args = function_clang_type.GetFunctionArgumentCount();
+ if (num_func_args >= 0) {
+ trust_function = true;
+ num_args = num_func_args;
+ }
}
- m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
-
- m_wrapper_function_text.append (args_buffer);
-
- m_wrapper_function_text.append (" ");
- m_wrapper_function_text.append (return_type_str);
- m_wrapper_function_text.append (" return_value;");
- m_wrapper_function_text.append ("\n };\n struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append (" *) input;\n");
-
- m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
- m_wrapper_function_text.append (args_list_buffer);
- m_wrapper_function_text.append (");\n}\n");
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
-
- // Okay, now compile this expression
-
- lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
- if (jit_process_sp)
- {
- const bool generate_debug_info = true;
- m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info));
-
- num_errors = m_parser->Parse(diagnostic_manager);
+ }
+
+ if (num_args == UINT32_MAX)
+ num_args = m_arg_values.GetSize();
+
+ std::string args_buffer; // This one stores the definition of all the args in
+ // "struct caller".
+ std::string args_list_buffer; // This one stores the argument list called from
+ // the structure.
+ for (size_t i = 0; i < num_args; i++) {
+ std::string type_name;
+
+ if (trust_function) {
+ type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i)
+ .GetTypeName()
+ .AsCString("");
+ } else {
+ CompilerType clang_qual_type =
+ m_arg_values.GetValueAtIndex(i)->GetCompilerType();
+ if (clang_qual_type) {
+ type_name = clang_qual_type.GetTypeName().AsCString("");
+ } else {
+ diagnostic_manager.Printf(
+ eDiagnosticSeverityError,
+ "Could not determine type of input value %" PRIu64 ".",
+ (uint64_t)i);
+ return 1;
+ }
}
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "no process - unable to inject function");
- num_errors = 1;
- }
-
- m_compiled = (num_errors == 0);
-
- if (!m_compiled)
- return num_errors;
+ m_wrapper_function_text.append(type_name);
+ if (i < num_args - 1)
+ m_wrapper_function_text.append(", ");
+
+ char arg_buf[32];
+ args_buffer.append(" ");
+ args_buffer.append(type_name);
+ snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
+ args_buffer.push_back(' ');
+ args_buffer.append(arg_buf);
+ args_buffer.append(";\n");
+
+ args_list_buffer.append("__lldb_fn_data->");
+ args_list_buffer.append(arg_buf);
+ if (i < num_args - 1)
+ args_list_buffer.append(", ");
+ }
+ m_wrapper_function_text.append(
+ ");\n"); // Close off the function calling prototype.
+
+ m_wrapper_function_text.append(args_buffer);
+
+ m_wrapper_function_text.append(" ");
+ m_wrapper_function_text.append(return_type_str);
+ m_wrapper_function_text.append(" return_value;");
+ m_wrapper_function_text.append("\n };\n struct ");
+ m_wrapper_function_text.append(m_wrapper_struct_name);
+ m_wrapper_function_text.append("* __lldb_fn_data = (struct ");
+ m_wrapper_function_text.append(m_wrapper_struct_name);
+ m_wrapper_function_text.append(" *) input;\n");
+
+ m_wrapper_function_text.append(
+ " __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
+ m_wrapper_function_text.append(args_list_buffer);
+ m_wrapper_function_text.append(");\n}\n");
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ if (log)
+ log->Printf("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
+
+ // Okay, now compile this expression
+
+ lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
+ if (jit_process_sp) {
+ const bool generate_debug_info = true;
+ m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this,
+ generate_debug_info));
+
+ num_errors = m_parser->Parse(diagnostic_manager);
+ } else {
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "no process - unable to inject function");
+ num_errors = 1;
+ }
+
+ m_compiled = (num_errors == 0);
+
+ if (!m_compiled)
return num_errors;
+
+ return num_errors;
}
clang::ASTConsumer *
-ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer (clang::ASTConsumer *passthrough)
-{
- m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_owner.GetWrapperStructName(), m_owner));
-
- return m_struct_extractor.get();
+ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer(
+ clang::ASTConsumer *passthrough) {
+ m_struct_extractor.reset(new ASTStructExtractor(
+ passthrough, m_owner.GetWrapperStructName(), m_owner));
+
+ return m_struct_extractor.get();
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 468b9c1c76dc..56d1d8412f78 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -16,23 +16,23 @@
// Project includes
#include "ClangExpressionHelper.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Process.h"
-namespace lldb_private
-{
-
+namespace lldb_private {
+
class ASTStructExtractor;
class ClangExpressionParser;
//----------------------------------------------------------------------
-/// @class ClangFunctionCaller ClangFunctionCaller.h "lldb/Expression/ClangFunctionCaller.h"
+/// @class ClangFunctionCaller ClangFunctionCaller.h
+/// "lldb/Expression/ClangFunctionCaller.h"
/// @brief Encapsulates a function that can be called.
///
/// A given ClangFunctionCaller object can handle a single function signature.
@@ -42,7 +42,7 @@ class ClangExpressionParser;
/// It performs the call by synthesizing a structure that contains the pointer
/// to the function and the arguments that should be passed to that function,
/// and producing a special-purpose JIT-compiled function that accepts a void*
-/// pointing to this struct as its only argument and calls the function in the
+/// pointing to this struct as its only argument and calls the function in the
/// struct with the written arguments. This method lets Clang handle the
/// vagaries of function calling conventions.
///
@@ -54,124 +54,111 @@ class ClangExpressionParser;
/// InsertFunction() followed by WriteFunctionArguments(), which will return
/// the location of the args struct for the wrapper function in args_addr_ref.
///
-/// If you need to call the function on the thread plan stack, you can also
+/// If you need to call the function on the thread plan stack, you can also
/// call InsertFunction() followed by GetThreadPlanToCallFunction().
///
/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed
/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
/// and its address returned in that variable.
-///
+///
/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
/// argument space will be managed for you.
-//----------------------------------------------------------------------
-class ClangFunctionCaller : public FunctionCaller
-{
- friend class ASTStructExtractor;
-
- class ClangFunctionCallerHelper : public ClangExpressionHelper
- {
- public:
- ClangFunctionCallerHelper (ClangFunctionCaller &owner) :
- m_owner(owner)
- {
- }
-
- ~ClangFunctionCallerHelper() override = default;
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap() override
- {
- return NULL;
- }
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) override;
-
- private:
- ClangFunctionCaller &m_owner;
- std::unique_ptr<ASTStructExtractor> m_struct_extractor; ///< The class that generates the argument struct layout.
- };
+//----------------------------------------------------------------------
+class ClangFunctionCaller : public FunctionCaller {
+ friend class ASTStructExtractor;
+
+ class ClangFunctionCallerHelper : public ClangExpressionHelper {
+ public:
+ ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {}
+
+ ~ClangFunctionCallerHelper() override = default;
-public:
//------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] exe_scope
- /// An execution context scope that gets us at least a target and
- /// process.
- ///
- /// @param[in] ast_context
- /// The AST context to evaluate argument types in.
- ///
- /// @param[in] return_qualtype
- /// An opaque Clang QualType for the function result. Should be
- /// defined in ast_context.
- ///
- /// @param[in] function_address
- /// The address of the function to call.
- ///
- /// @param[in] arg_value_list
- /// The default values to use when calling this function. Can
- /// be overridden using WriteFunctionArguments().
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
//------------------------------------------------------------------
- ClangFunctionCaller (ExecutionContextScope &exe_scope,
- const CompilerType &return_type,
- const Address& function_address,
- const ValueList &arg_value_list,
- const char *name);
-
- ~ClangFunctionCaller() override;
+ ClangExpressionDeclMap *DeclMap() override { return NULL; }
//------------------------------------------------------------------
- /// Compile the wrapper function
- ///
- /// @param[in] thread_to_use_sp
- /// Compilation might end up calling functions. Pass in the thread you
- /// want the compilation to use. If you pass in an empty ThreadSP it will
- /// use the currently selected thread.
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
///
- /// @param[in] diagnostic_manager
- /// The diagnostic manager to report parser errors to.
- ///
- /// @return
- /// The number of errors.
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
//------------------------------------------------------------------
- unsigned
- CompileFunction (lldb::ThreadSP thread_to_use_sp,
- DiagnosticManager &diagnostic_manager) override;
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override;
+
+ private:
+ ClangFunctionCaller &m_owner;
+ std::unique_ptr<ASTStructExtractor> m_struct_extractor; ///< The class that
+ ///generates the
+ ///argument struct
+ ///layout.
+ };
- ExpressionTypeSystemHelper *
- GetTypeSystemHelper() override
- {
- return &m_type_system_helper;
- }
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] exe_scope
+ /// An execution context scope that gets us at least a target and
+ /// process.
+ ///
+ /// @param[in] ast_context
+ /// The AST context to evaluate argument types in.
+ ///
+ /// @param[in] return_qualtype
+ /// An opaque Clang QualType for the function result. Should be
+ /// defined in ast_context.
+ ///
+ /// @param[in] function_address
+ /// The address of the function to call.
+ ///
+ /// @param[in] arg_value_list
+ /// The default values to use when calling this function. Can
+ /// be overridden using WriteFunctionArguments().
+ //------------------------------------------------------------------
+ ClangFunctionCaller(ExecutionContextScope &exe_scope,
+ const CompilerType &return_type,
+ const Address &function_address,
+ const ValueList &arg_value_list, const char *name);
+
+ ~ClangFunctionCaller() override;
+
+ //------------------------------------------------------------------
+ /// Compile the wrapper function
+ ///
+ /// @param[in] thread_to_use_sp
+ /// Compilation might end up calling functions. Pass in the thread you
+ /// want the compilation to use. If you pass in an empty ThreadSP it will
+ /// use the currently selected thread.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report parser errors to.
+ ///
+ /// @return
+ /// The number of errors.
+ //------------------------------------------------------------------
+ unsigned CompileFunction(lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager) override;
+
+ ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+ return &m_type_system_helper;
+ }
protected:
- const char *GetWrapperStructName()
- {
- return m_wrapper_struct_name.c_str();
- }
+ const char *GetWrapperStructName() { return m_wrapper_struct_name.c_str(); }
private:
- //------------------------------------------------------------------
- // For ClangFunctionCaller only
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // For ClangFunctionCaller only
+ //------------------------------------------------------------------
- // Note: the parser needs to be destructed before the execution unit, so
- // declare the execution unit first.
- ClangFunctionCallerHelper m_type_system_helper;
+ // Note: the parser needs to be destructed before the execution unit, so
+ // declare the execution unit first.
+ ClangFunctionCallerHelper m_type_system_helper;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 63a3a85bacb4..c542b36b674f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -16,9 +16,11 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Parse/Parser.h"
#include "clang/Sema/Lookup.h"
#include "clang/Serialization/ASTReader.h"
+#include "llvm/Support/Path.h"
// Project includes
#include "ClangModulesDeclVendor.h"
@@ -35,700 +37,643 @@
using namespace lldb_private;
namespace {
- // Any Clang compiler requires a consumer for diagnostics. This one stores them as strings
- // so we can provide them to the user in case a module failed to load.
- class StoringDiagnosticConsumer : public clang::DiagnosticConsumer
- {
- public:
- StoringDiagnosticConsumer ();
-
- void
- HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
- const clang::Diagnostic &info) override;
-
- void
- ClearDiagnostics ();
-
- void
- DumpDiagnostics (Stream &error_stream);
-
- private:
- typedef std::pair<clang::DiagnosticsEngine::Level, std::string> IDAndDiagnostic;
- std::vector<IDAndDiagnostic> m_diagnostics;
- Log * m_log;
- };
-
- // The private implementation of our ClangModulesDeclVendor. Contains all the Clang state required
- // to load modules.
- class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor
- {
- public:
- ClangModulesDeclVendorImpl(llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
- std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
- std::unique_ptr<clang::Parser> &&parser);
-
- ~ClangModulesDeclVendorImpl() override = default;
-
- bool
- AddModule(ModulePath &path,
- ModuleVector *exported_modules,
- Stream &error_stream) override;
-
- bool
- AddModulesForCompileUnit(CompileUnit &cu,
- ModuleVector &exported_modules,
- Stream &error_stream) override;
-
- uint32_t
- FindDecls(const ConstString &name,
- bool append,
- uint32_t max_matches,
- std::vector <clang::NamedDecl*> &decls) override;
-
- void
- ForEachMacro(const ModuleVector &modules,
- std::function<bool (const std::string &)> handler) override;
-
- private:
- void
- ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports,
- clang::Module *module);
-
- void
- ReportModuleExports (ModuleVector &exports,
- clang::Module *module);
-
- clang::ModuleLoadResult
- DoGetModule(clang::ModuleIdPath path, bool make_visible);
-
- bool m_enabled = false;
-
- llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> m_compiler_invocation;
- std::unique_ptr<clang::CompilerInstance> m_compiler_instance;
- std::unique_ptr<clang::Parser> m_parser;
- size_t m_source_location_index = 0; // used to give name components fake SourceLocations
-
- typedef std::vector<ConstString> ImportedModule;
- typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
- typedef std::set<ModuleID> ImportedModuleSet;
- ImportedModuleMap m_imported_modules;
- ImportedModuleSet m_user_imported_modules;
- };
+// Any Clang compiler requires a consumer for diagnostics. This one stores them
+// as strings
+// so we can provide them to the user in case a module failed to load.
+class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
+public:
+ StoringDiagnosticConsumer();
+
+ void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
+ const clang::Diagnostic &info) override;
+
+ void ClearDiagnostics();
+
+ void DumpDiagnostics(Stream &error_stream);
+
+private:
+ typedef std::pair<clang::DiagnosticsEngine::Level, std::string>
+ IDAndDiagnostic;
+ std::vector<IDAndDiagnostic> m_diagnostics;
+ Log *m_log;
+};
+
+// The private implementation of our ClangModulesDeclVendor. Contains all the
+// Clang state required
+// to load modules.
+class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
+public:
+ ClangModulesDeclVendorImpl(
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
+ std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
+ std::unique_ptr<clang::Parser> &&parser);
+
+ ~ClangModulesDeclVendorImpl() override = default;
+
+ bool AddModule(ModulePath &path, ModuleVector *exported_modules,
+ Stream &error_stream) override;
+
+ bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules,
+ Stream &error_stream) override;
+
+ uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) override;
+
+ void ForEachMacro(const ModuleVector &modules,
+ std::function<bool(const std::string &)> handler) override;
+
+private:
+ void
+ ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
+ clang::Module *module);
+
+ void ReportModuleExports(ModuleVector &exports, clang::Module *module);
+
+ clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path,
+ bool make_visible);
+
+ bool m_enabled = false;
+
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> m_compiler_invocation;
+ std::unique_ptr<clang::CompilerInstance> m_compiler_instance;
+ std::unique_ptr<clang::Parser> m_parser;
+ size_t m_source_location_index =
+ 0; // used to give name components fake SourceLocations
+
+ typedef std::vector<ConstString> ImportedModule;
+ typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
+ typedef std::set<ModuleID> ImportedModuleSet;
+ ImportedModuleMap m_imported_modules;
+ ImportedModuleSet m_user_imported_modules;
+};
} // anonymous namespace
-StoringDiagnosticConsumer::StoringDiagnosticConsumer ()
-{
- m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+StoringDiagnosticConsumer::StoringDiagnosticConsumer() {
+ m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
}
-void
-StoringDiagnosticConsumer::HandleDiagnostic (clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info)
-{
- llvm::SmallVector<char, 256> diagnostic_string;
-
- info.FormatDiagnostic(diagnostic_string);
-
- m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(), diagnostic_string.size())));
-}
+void StoringDiagnosticConsumer::HandleDiagnostic(
+ clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {
+ llvm::SmallVector<char, 256> diagnostic_string;
-void
-StoringDiagnosticConsumer::ClearDiagnostics ()
-{
- m_diagnostics.clear();
+ info.FormatDiagnostic(diagnostic_string);
+
+ m_diagnostics.push_back(
+ IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(),
+ diagnostic_string.size())));
}
-void
-StoringDiagnosticConsumer::DumpDiagnostics (Stream &error_stream)
-{
- for (IDAndDiagnostic &diag : m_diagnostics)
- {
- switch (diag.first)
- {
- default:
- error_stream.PutCString(diag.second.c_str());
- error_stream.PutChar('\n');
- break;
- case clang::DiagnosticsEngine::Level::Ignored:
- break;
- }
+void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }
+
+void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
+ for (IDAndDiagnostic &diag : m_diagnostics) {
+ switch (diag.first) {
+ default:
+ error_stream.PutCString(diag.second);
+ error_stream.PutChar('\n');
+ break;
+ case clang::DiagnosticsEngine::Level::Ignored:
+ break;
}
+ }
}
-static FileSpec
-GetResourceDir ()
-{
- static FileSpec g_cached_resource_dir;
-
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, [](){
- HostInfo::GetLLDBPath (lldb::ePathTypeClangDir, g_cached_resource_dir);
- });
-
- return g_cached_resource_dir;
-}
+static FileSpec GetResourceDir() {
+ static FileSpec g_cached_resource_dir;
-ClangModulesDeclVendor::ClangModulesDeclVendor()
-{
-}
+ static std::once_flag g_once_flag;
-ClangModulesDeclVendor::~ClangModulesDeclVendor()
-{
-}
+ std::call_once(g_once_flag, []() {
+ HostInfo::GetLLDBPath(lldb::ePathTypeClangDir, g_cached_resource_dir);
+ });
-ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
- std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
- std::unique_ptr<clang::Parser> &&parser) :
- ClangModulesDeclVendor(),
- m_diagnostics_engine(diagnostics_engine),
- m_compiler_invocation(compiler_invocation),
- m_compiler_instance(std::move(compiler_instance)),
- m_parser(std::move(parser)),
- m_imported_modules()
-{
+ return g_cached_resource_dir;
}
-void
-ClangModulesDeclVendorImpl::ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports,
- clang::Module *module)
-{
- if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
- return;
-
- exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));
-
- llvm::SmallVector<clang::Module*, 2> sub_exports;
-
- module->getExportedModules(sub_exports);
-
- for (clang::Module *module : sub_exports)
- {
- ReportModuleExportsHelper(exports, module);
- }
+ClangModulesDeclVendor::ClangModulesDeclVendor() {}
+
+ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
+
+ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
+ std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
+ std::unique_ptr<clang::Parser> &&parser)
+ : ClangModulesDeclVendor(), m_diagnostics_engine(diagnostics_engine),
+ m_compiler_invocation(compiler_invocation),
+ m_compiler_instance(std::move(compiler_instance)),
+ m_parser(std::move(parser)), m_imported_modules() {}
+
+void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
+ std::set<ClangModulesDeclVendor::ModuleID> &exports,
+ clang::Module *module) {
+ if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
+ return;
+
+ exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));
+
+ llvm::SmallVector<clang::Module *, 2> sub_exports;
+
+ module->getExportedModules(sub_exports);
+
+ for (clang::Module *module : sub_exports) {
+ ReportModuleExportsHelper(exports, module);
+ }
}
-void
-ClangModulesDeclVendorImpl::ReportModuleExports (ClangModulesDeclVendor::ModuleVector &exports,
- clang::Module *module)
-{
- std::set<ClangModulesDeclVendor::ModuleID> exports_set;
-
- ReportModuleExportsHelper(exports_set, module);
-
- for (ModuleID module : exports_set)
- {
- exports.push_back(module);
- }
+void ClangModulesDeclVendorImpl::ReportModuleExports(
+ ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {
+ std::set<ClangModulesDeclVendor::ModuleID> exports_set;
+
+ ReportModuleExportsHelper(exports_set, module);
+
+ for (ModuleID module : exports_set) {
+ exports.push_back(module);
+ }
}
-bool
-ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
- ModuleVector *exported_modules,
- Stream &error_stream)
-{
- // Fail early.
-
- if (m_compiler_instance->hadModuleLoaderFatalFailure())
- {
- error_stream.PutCString("error: Couldn't load a module because the module loader is in a fatal state.\n");
- return false;
- }
-
- // Check if we've already imported this module.
-
- std::vector<ConstString> imported_module;
-
- for (ConstString path_component : path)
- {
- imported_module.push_back(path_component);
- }
-
- {
- ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
-
- if (mi != m_imported_modules.end())
- {
- if (exported_modules)
- {
- ReportModuleExports(*exported_modules, mi->second);
- }
- return true;
- }
- }
-
- if (!m_compiler_instance->getPreprocessor().getHeaderSearchInfo().lookupModule(path[0].GetStringRef()))
- {
- error_stream.Printf("error: Header search couldn't locate module %s\n", path[0].AsCString());
- return false;
- }
-
- llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 4> clang_path;
-
- {
- clang::SourceManager &source_manager = m_compiler_instance->getASTContext().getSourceManager();
-
- for (ConstString path_component : path)
- {
- clang_path.push_back(std::make_pair(&m_compiler_instance->getASTContext().Idents.get(path_component.GetStringRef()),
- source_manager.getLocForStartOfFile(source_manager.getMainFileID()).getLocWithOffset(m_source_location_index++)));
- }
+bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
+ ModuleVector *exported_modules,
+ Stream &error_stream) {
+ // Fail early.
+
+ if (m_compiler_instance->hadModuleLoaderFatalFailure()) {
+ error_stream.PutCString("error: Couldn't load a module because the module "
+ "loader is in a fatal state.\n");
+ return false;
+ }
+
+ // Check if we've already imported this module.
+
+ std::vector<ConstString> imported_module;
+
+ for (ConstString path_component : path) {
+ imported_module.push_back(path_component);
+ }
+
+ {
+ ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
+
+ if (mi != m_imported_modules.end()) {
+ if (exported_modules) {
+ ReportModuleExports(*exported_modules, mi->second);
+ }
+ return true;
}
-
- StoringDiagnosticConsumer *diagnostic_consumer = static_cast<StoringDiagnosticConsumer *>(m_compiler_instance->getDiagnostics().getClient());
-
- diagnostic_consumer->ClearDiagnostics();
-
- clang::Module *top_level_module = DoGetModule(clang_path.front(), false);
-
- if (!top_level_module)
- {
- diagnostic_consumer->DumpDiagnostics(error_stream);
- error_stream.Printf("error: Couldn't load top-level module %s\n", path[0].AsCString());
- return false;
+ }
+
+ if (!m_compiler_instance->getPreprocessor()
+ .getHeaderSearchInfo()
+ .lookupModule(path[0].GetStringRef())) {
+ error_stream.Printf("error: Header search couldn't locate module %s\n",
+ path[0].AsCString());
+ return false;
+ }
+
+ llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>,
+ 4>
+ clang_path;
+
+ {
+ clang::SourceManager &source_manager =
+ m_compiler_instance->getASTContext().getSourceManager();
+
+ for (ConstString path_component : path) {
+ clang_path.push_back(std::make_pair(
+ &m_compiler_instance->getASTContext().Idents.get(
+ path_component.GetStringRef()),
+ source_manager.getLocForStartOfFile(source_manager.getMainFileID())
+ .getLocWithOffset(m_source_location_index++)));
}
-
- clang::Module *submodule = top_level_module;
-
- for (size_t ci = 1; ci < path.size(); ++ci)
- {
- llvm::StringRef component = path[ci].GetStringRef();
- submodule = submodule->findSubmodule(component.str());
- if (!submodule)
- {
- diagnostic_consumer->DumpDiagnostics(error_stream);
- error_stream.Printf("error: Couldn't load submodule %s\n", component.str().c_str());
- return false;
- }
+ }
+
+ StoringDiagnosticConsumer *diagnostic_consumer =
+ static_cast<StoringDiagnosticConsumer *>(
+ m_compiler_instance->getDiagnostics().getClient());
+
+ diagnostic_consumer->ClearDiagnostics();
+
+ clang::Module *top_level_module = DoGetModule(clang_path.front(), false);
+
+ if (!top_level_module) {
+ diagnostic_consumer->DumpDiagnostics(error_stream);
+ error_stream.Printf("error: Couldn't load top-level module %s\n",
+ path[0].AsCString());
+ return false;
+ }
+
+ clang::Module *submodule = top_level_module;
+
+ for (size_t ci = 1; ci < path.size(); ++ci) {
+ llvm::StringRef component = path[ci].GetStringRef();
+ submodule = submodule->findSubmodule(component.str());
+ if (!submodule) {
+ diagnostic_consumer->DumpDiagnostics(error_stream);
+ error_stream.Printf("error: Couldn't load submodule %s\n",
+ component.str().c_str());
+ return false;
}
-
- clang::Module *requested_module = DoGetModule(clang_path, true);
-
- if (requested_module != nullptr)
- {
- if (exported_modules)
- {
- ReportModuleExports(*exported_modules, requested_module);
- }
+ }
+
+ clang::Module *requested_module = DoGetModule(clang_path, true);
- m_imported_modules[imported_module] = requested_module;
-
- m_enabled = true;
-
- return true;
+ if (requested_module != nullptr) {
+ if (exported_modules) {
+ ReportModuleExports(*exported_modules, requested_module);
}
-
- return false;
+
+ m_imported_modules[imported_module] = requested_module;
+
+ m_enabled = true;
+
+ return true;
+ }
+
+ return false;
}
-bool
-ClangModulesDeclVendor::LanguageSupportsClangModules (lldb::LanguageType language)
-{
- switch (language)
- {
- default:
- return false;
- // C++ and friends to be added
- case lldb::LanguageType::eLanguageTypeC:
- case lldb::LanguageType::eLanguageTypeC11:
- case lldb::LanguageType::eLanguageTypeC89:
- case lldb::LanguageType::eLanguageTypeC99:
- case lldb::LanguageType::eLanguageTypeObjC:
- return true;
- }
+bool ClangModulesDeclVendor::LanguageSupportsClangModules(
+ lldb::LanguageType language) {
+ switch (language) {
+ default:
+ return false;
+ // C++ and friends to be added
+ case lldb::LanguageType::eLanguageTypeC:
+ case lldb::LanguageType::eLanguageTypeC11:
+ case lldb::LanguageType::eLanguageTypeC89:
+ case lldb::LanguageType::eLanguageTypeC99:
+ case lldb::LanguageType::eLanguageTypeObjC:
+ return true;
+ }
}
-bool
-ClangModulesDeclVendorImpl::AddModulesForCompileUnit(CompileUnit &cu,
- ClangModulesDeclVendor::ModuleVector &exported_modules,
- Stream &error_stream)
-{
- if (LanguageSupportsClangModules(cu.GetLanguage()))
- {
- std::vector<ConstString> imported_modules = cu.GetImportedModules();
-
- for (ConstString imported_module : imported_modules)
- {
- std::vector<ConstString> path;
-
- path.push_back(imported_module);
-
- if (!AddModule(path, &exported_modules, error_stream))
- {
- return false;
- }
- }
-
- return true;
+bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit(
+ CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules,
+ Stream &error_stream) {
+ if (LanguageSupportsClangModules(cu.GetLanguage())) {
+ std::vector<ConstString> imported_modules = cu.GetImportedModules();
+
+ for (ConstString imported_module : imported_modules) {
+ std::vector<ConstString> path;
+
+ path.push_back(imported_module);
+
+ if (!AddModule(path, &exported_modules, error_stream)) {
+ return false;
+ }
}
return true;
+ }
+
+ return true;
}
// ClangImporter::lookupValue
uint32_t
-ClangModulesDeclVendorImpl::FindDecls (const ConstString &name,
- bool append,
- uint32_t max_matches,
- std::vector <clang::NamedDecl*> &decls)
-{
- if (!m_enabled)
- {
- return 0;
- }
+ClangModulesDeclVendorImpl::FindDecls(const ConstString &name, bool append,
+ uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) {
+ if (!m_enabled) {
+ return 0;
+ }
- if (!append)
- decls.clear();
-
- clang::IdentifierInfo &ident = m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());
-
- clang::LookupResult lookup_result(m_compiler_instance->getSema(),
- clang::DeclarationName(&ident),
- clang::SourceLocation(),
- clang::Sema::LookupOrdinaryName);
-
- m_compiler_instance->getSema().LookupName(lookup_result, m_compiler_instance->getSema().getScopeForContext(m_compiler_instance->getASTContext().getTranslationUnitDecl()));
-
- uint32_t num_matches = 0;
-
- for (clang::NamedDecl *named_decl : lookup_result)
- {
- if (num_matches >= max_matches)
- return num_matches;
-
- decls.push_back(named_decl);
- ++num_matches;
- }
-
- return num_matches;
+ if (!append)
+ decls.clear();
+
+ clang::IdentifierInfo &ident =
+ m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());
+
+ clang::LookupResult lookup_result(
+ m_compiler_instance->getSema(), clang::DeclarationName(&ident),
+ clang::SourceLocation(), clang::Sema::LookupOrdinaryName);
+
+ m_compiler_instance->getSema().LookupName(
+ lookup_result,
+ m_compiler_instance->getSema().getScopeForContext(
+ m_compiler_instance->getASTContext().getTranslationUnitDecl()));
+
+ uint32_t num_matches = 0;
+
+ for (clang::NamedDecl *named_decl : lookup_result) {
+ if (num_matches >= max_matches)
+ return num_matches;
+
+ decls.push_back(named_decl);
+ ++num_matches;
+ }
+
+ return num_matches;
}
-void
-ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVector &modules,
- std::function<bool (const std::string &)> handler)
-{
- if (!m_enabled)
- {
- return;
- }
-
- typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
- ModulePriorityMap module_priorities;
-
- ssize_t priority = 0;
-
- for (ModuleID module : modules)
+void ClangModulesDeclVendorImpl::ForEachMacro(
+ const ClangModulesDeclVendor::ModuleVector &modules,
+ std::function<bool(const std::string &)> handler) {
+ if (!m_enabled) {
+ return;
+ }
+
+ typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
+ ModulePriorityMap module_priorities;
+
+ ssize_t priority = 0;
+
+ for (ModuleID module : modules) {
+ module_priorities[module] = priority++;
+ }
+
+ if (m_compiler_instance->getPreprocessor().getExternalSource()) {
+ m_compiler_instance->getPreprocessor()
+ .getExternalSource()
+ ->ReadDefinedMacros();
+ }
+
+ for (clang::Preprocessor::macro_iterator
+ mi = m_compiler_instance->getPreprocessor().macro_begin(),
+ me = m_compiler_instance->getPreprocessor().macro_end();
+ mi != me; ++mi) {
+ const clang::IdentifierInfo *ii = nullptr;
+
{
- module_priorities[module] = priority++;
+ if (clang::IdentifierInfoLookup *lookup =
+ m_compiler_instance->getPreprocessor()
+ .getIdentifierTable()
+ .getExternalIdentifierLookup()) {
+ lookup->get(mi->first->getName());
+ }
+ if (!ii) {
+ ii = mi->first;
+ }
}
-
- if (m_compiler_instance->getPreprocessor().getExternalSource())
- {
- m_compiler_instance->getPreprocessor().getExternalSource()->ReadDefinedMacros();
+
+ ssize_t found_priority = -1;
+ clang::MacroInfo *macro_info = nullptr;
+
+ for (clang::ModuleMacro *module_macro :
+ m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) {
+ clang::Module *module = module_macro->getOwningModule();
+
+ {
+ ModulePriorityMap::iterator pi =
+ module_priorities.find(reinterpret_cast<ModuleID>(module));
+
+ if (pi != module_priorities.end() && pi->second > found_priority) {
+ macro_info = module_macro->getMacroInfo();
+ found_priority = pi->second;
+ }
+ }
+
+ clang::Module *top_level_module = module->getTopLevelModule();
+
+ if (top_level_module != module) {
+ ModulePriorityMap::iterator pi = module_priorities.find(
+ reinterpret_cast<ModuleID>(top_level_module));
+
+ if ((pi != module_priorities.end()) && pi->second > found_priority) {
+ macro_info = module_macro->getMacroInfo();
+ found_priority = pi->second;
+ }
+ }
}
-
- for (clang::Preprocessor::macro_iterator mi = m_compiler_instance->getPreprocessor().macro_begin(),
- me = m_compiler_instance->getPreprocessor().macro_end();
- mi != me;
- ++mi)
- {
- const clang::IdentifierInfo *ii = nullptr;
-
- {
- if (clang::IdentifierInfoLookup *lookup = m_compiler_instance->getPreprocessor().getIdentifierTable().getExternalIdentifierLookup())
- {
- lookup->get(mi->first->getName());
+
+ if (macro_info) {
+ std::string macro_expansion = "#define ";
+ macro_expansion.append(mi->first->getName().str());
+
+ {
+ if (macro_info->isFunctionLike()) {
+ macro_expansion.append("(");
+
+ bool first_arg = true;
+
+ for (clang::MacroInfo::arg_iterator ai = macro_info->arg_begin(),
+ ae = macro_info->arg_end();
+ ai != ae; ++ai) {
+ if (!first_arg) {
+ macro_expansion.append(", ");
+ } else {
+ first_arg = false;
}
- if (!ii)
- {
- ii = mi->first;
+
+ macro_expansion.append((*ai)->getName().str());
+ }
+
+ if (macro_info->isC99Varargs()) {
+ if (first_arg) {
+ macro_expansion.append("...");
+ } else {
+ macro_expansion.append(", ...");
}
+ } else if (macro_info->isGNUVarargs()) {
+ macro_expansion.append("...");
+ }
+
+ macro_expansion.append(")");
}
-
- ssize_t found_priority = -1;
- clang::MacroInfo *macro_info = nullptr;
-
- for (clang::ModuleMacro *module_macro : m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii))
- {
- clang::Module *module = module_macro->getOwningModule();
-
- {
- ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(module));
-
- if (pi != module_priorities.end() && pi->second > found_priority)
- {
- macro_info = module_macro->getMacroInfo();
- found_priority = pi->second;
- }
+
+ macro_expansion.append(" ");
+
+ bool first_token = true;
+
+ for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
+ te = macro_info->tokens_end();
+ ti != te; ++ti) {
+ if (!first_token) {
+ macro_expansion.append(" ");
+ } else {
+ first_token = false;
+ }
+
+ if (ti->isLiteral()) {
+ if (const char *literal_data = ti->getLiteralData()) {
+ std::string token_str(literal_data, ti->getLength());
+ macro_expansion.append(token_str);
+ } else {
+ bool invalid = false;
+ const char *literal_source =
+ m_compiler_instance->getSourceManager().getCharacterData(
+ ti->getLocation(), &invalid);
+
+ if (invalid) {
+ lldbassert(!"Unhandled token kind");
+ macro_expansion.append("<unknown literal value>");
+ } else {
+ macro_expansion.append(
+ std::string(literal_source, ti->getLength()));
+ }
}
-
- clang::Module *top_level_module = module->getTopLevelModule();
-
- if (top_level_module != module)
- {
- ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(top_level_module));
-
- if ((pi != module_priorities.end()) && pi->second > found_priority)
- {
- macro_info = module_macro->getMacroInfo();
- found_priority = pi->second;
- }
+ } else if (const char *punctuator_spelling =
+ clang::tok::getPunctuatorSpelling(ti->getKind())) {
+ macro_expansion.append(punctuator_spelling);
+ } else if (const char *keyword_spelling =
+ clang::tok::getKeywordSpelling(ti->getKind())) {
+ macro_expansion.append(keyword_spelling);
+ } else {
+ switch (ti->getKind()) {
+ case clang::tok::TokenKind::identifier:
+ macro_expansion.append(ti->getIdentifierInfo()->getName().str());
+ break;
+ case clang::tok::TokenKind::raw_identifier:
+ macro_expansion.append(ti->getRawIdentifier().str());
+ break;
+ default:
+ macro_expansion.append(ti->getName());
+ break;
}
+ }
}
-
- if (macro_info)
- {
- std::string macro_expansion = "#define ";
- macro_expansion.append(mi->first->getName().str().c_str());
-
- {
- if (macro_info->isFunctionLike())
- {
- macro_expansion.append("(");
-
- bool first_arg = true;
-
- for (clang::MacroInfo::arg_iterator ai = macro_info->arg_begin(),
- ae = macro_info->arg_end();
- ai != ae;
- ++ai)
- {
- if (!first_arg)
- {
- macro_expansion.append(", ");
- }
- else
- {
- first_arg = false;
- }
-
- macro_expansion.append((*ai)->getName().str());
- }
-
- if (macro_info->isC99Varargs())
- {
- if (first_arg)
- {
- macro_expansion.append("...");
- }
- else
- {
- macro_expansion.append(", ...");
- }
- }
- else if (macro_info->isGNUVarargs())
- {
- macro_expansion.append("...");
- }
-
- macro_expansion.append(")");
- }
-
- macro_expansion.append(" ");
-
- bool first_token = true;
-
- for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
- te = macro_info->tokens_end();
- ti != te;
- ++ti)
- {
- if (!first_token)
- {
- macro_expansion.append(" ");
- }
- else
- {
- first_token = false;
- }
-
- if (ti->isLiteral())
- {
- if (const char *literal_data = ti->getLiteralData())
- {
- std::string token_str(literal_data, ti->getLength());
- macro_expansion.append(token_str);
- }
- else
- {
- bool invalid = false;
- const char *literal_source = m_compiler_instance->getSourceManager().getCharacterData(ti->getLocation(), &invalid);
-
- if (invalid)
- {
- lldbassert(!"Unhandled token kind");
- macro_expansion.append("<unknown literal value>");
- }
- else
- {
- macro_expansion.append(std::string(literal_source, ti->getLength()));
- }
- }
- }
- else if (const char *punctuator_spelling = clang::tok::getPunctuatorSpelling(ti->getKind()))
- {
- macro_expansion.append(punctuator_spelling);
- }
- else if (const char *keyword_spelling = clang::tok::getKeywordSpelling(ti->getKind()))
- {
- macro_expansion.append(keyword_spelling);
- }
- else
- {
- switch (ti->getKind())
- {
- case clang::tok::TokenKind::identifier:
- macro_expansion.append(ti->getIdentifierInfo()->getName().str());
- break;
- case clang::tok::TokenKind::raw_identifier:
- macro_expansion.append(ti->getRawIdentifier().str());
- break;
- default:
- macro_expansion.append(ti->getName());
- break;
- }
- }
- }
-
- if (handler(macro_expansion))
- {
- return;
- }
- }
+
+ if (handler(macro_expansion)) {
+ return;
}
+ }
}
+ }
}
clang::ModuleLoadResult
ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
- bool make_visible)
-{
- clang::Module::NameVisibilityKind visibility = make_visible ? clang::Module::AllVisible : clang::Module::Hidden;
-
- const bool is_inclusion_directive = false;
-
- return m_compiler_instance->loadModule(path.front().second, path, visibility, is_inclusion_directive);
+ bool make_visible) {
+ clang::Module::NameVisibilityKind visibility =
+ make_visible ? clang::Module::AllVisible : clang::Module::Hidden;
+
+ const bool is_inclusion_directive = false;
+
+ return m_compiler_instance->loadModule(path.front().second, path, visibility,
+ is_inclusion_directive);
}
static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
lldb_private::ClangModulesDeclVendor *
-ClangModulesDeclVendor::Create(Target &target)
-{
- // FIXME we should insure programmatically that the expression parser's compiler and the modules runtime's
- // compiler are both initialized in the same way – preferably by the same code.
-
- if (!target.GetPlatform()->SupportsModules())
- return nullptr;
-
- const ArchSpec &arch = target.GetArchitecture();
-
- std::vector<std::string> compiler_invocation_arguments =
- {
- "clang",
- "-fmodules",
- "-fimplicit-module-maps",
- "-fcxx-modules",
- "-fsyntax-only",
- "-femit-all-decls",
- "-target", arch.GetTriple().str(),
- "-fmodules-validate-system-headers",
- "-Werror=non-modular-include-in-framework-module"
- };
-
- target.GetPlatform()->AddClangModuleCompilationOptions(&target, compiler_invocation_arguments);
-
- compiler_invocation_arguments.push_back(ModuleImportBufferName);
-
- // Add additional search paths with { "-I", path } or { "-F", path } here.
-
- {
- llvm::SmallString<128> DefaultModuleCache;
- const bool erased_on_reboot = false;
- llvm::sys::path::system_temp_directory(erased_on_reboot, DefaultModuleCache);
- llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
- llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
- std::string module_cache_argument("-fmodules-cache-path=");
- module_cache_argument.append(DefaultModuleCache.str().str());
- compiler_invocation_arguments.push_back(module_cache_argument);
+ClangModulesDeclVendor::Create(Target &target) {
+ // FIXME we should insure programmatically that the expression parser's
+ // compiler and the modules runtime's
+ // compiler are both initialized in the same way – preferably by the same
+ // code.
+
+ if (!target.GetPlatform()->SupportsModules())
+ return nullptr;
+
+ const ArchSpec &arch = target.GetArchitecture();
+
+ std::vector<std::string> compiler_invocation_arguments = {
+ "clang",
+ "-fmodules",
+ "-fimplicit-module-maps",
+ "-fcxx-modules",
+ "-fsyntax-only",
+ "-femit-all-decls",
+ "-target",
+ arch.GetTriple().str(),
+ "-fmodules-validate-system-headers",
+ "-Werror=non-modular-include-in-framework-module"};
+
+ target.GetPlatform()->AddClangModuleCompilationOptions(
+ &target, compiler_invocation_arguments);
+
+ compiler_invocation_arguments.push_back(ModuleImportBufferName);
+
+ // Add additional search paths with { "-I", path } or { "-F", path } here.
+
+ {
+ llvm::SmallString<128> DefaultModuleCache;
+ const bool erased_on_reboot = false;
+ llvm::sys::path::system_temp_directory(erased_on_reboot,
+ DefaultModuleCache);
+ llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
+ llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
+ std::string module_cache_argument("-fmodules-cache-path=");
+ module_cache_argument.append(DefaultModuleCache.str().str());
+ compiler_invocation_arguments.push_back(module_cache_argument);
+ }
+
+ FileSpecList &module_search_paths = target.GetClangModuleSearchPaths();
+
+ for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) {
+ const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);
+
+ std::string search_path_argument = "-I";
+ search_path_argument.append(search_path.GetPath());
+
+ compiler_invocation_arguments.push_back(search_path_argument);
+ }
+
+ {
+ FileSpec clang_resource_dir = GetResourceDir();
+
+ if (clang_resource_dir.IsDirectory()) {
+ compiler_invocation_arguments.push_back("-resource-dir");
+ compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());
}
-
- FileSpecList &module_search_paths = target.GetClangModuleSearchPaths();
-
- for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi)
- {
- const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);
-
- std::string search_path_argument = "-I";
- search_path_argument.append(search_path.GetPath());
-
- compiler_invocation_arguments.push_back(search_path_argument);
- }
-
- {
- FileSpec clang_resource_dir = GetResourceDir();
-
- if (clang_resource_dir.IsDirectory())
- {
- compiler_invocation_arguments.push_back("-resource-dir");
- compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());
- }
- }
-
- llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine = clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions,
- new StoringDiagnosticConsumer);
-
- std::vector<const char *> compiler_invocation_argument_cstrs;
-
- for (const std::string &arg : compiler_invocation_arguments) {
- compiler_invocation_argument_cstrs.push_back(arg.c_str());
- }
-
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> invocation(clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs, diagnostics_engine));
-
- if (!invocation)
- return nullptr;
-
- std::unique_ptr<llvm::MemoryBuffer> source_buffer = llvm::MemoryBuffer::getMemBuffer("extern int __lldb __attribute__((unavailable));",
- ModuleImportBufferName);
-
- invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName, source_buffer.release());
-
- std::unique_ptr<clang::CompilerInstance> instance(new clang::CompilerInstance);
-
- instance->setDiagnostics(diagnostics_engine.get());
- instance->setInvocation(invocation.get());
-
- std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
-
- instance->setTarget(clang::TargetInfo::CreateTargetInfo(*diagnostics_engine, instance->getInvocation().TargetOpts));
-
- if (!instance->hasTarget())
- return nullptr;
-
- instance->getTarget().adjust(instance->getLangOpts());
-
- if (!action->BeginSourceFile(*instance, instance->getFrontendOpts().Inputs[0]))
- return nullptr;
-
- instance->getPreprocessor().enableIncrementalProcessing();
-
- instance->createModuleManager();
-
- instance->createSema(action->getTranslationUnitKind(), nullptr);
-
- const bool skipFunctionBodies = false;
- std::unique_ptr<clang::Parser> parser(new clang::Parser(instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));
-
- instance->getPreprocessor().EnterMainSourceFile();
- parser->Initialize();
-
- clang::Parser::DeclGroupPtrTy parsed;
-
- while (!parser->ParseTopLevelDecl(parsed));
-
- return new ClangModulesDeclVendorImpl (diagnostics_engine, invocation, std::move(instance), std::move(parser));
+ }
+
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =
+ clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions,
+ new StoringDiagnosticConsumer);
+
+ std::vector<const char *> compiler_invocation_argument_cstrs;
+
+ for (const std::string &arg : compiler_invocation_arguments) {
+ compiler_invocation_argument_cstrs.push_back(arg.c_str());
+ }
+
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> invocation(
+ clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs,
+ diagnostics_engine));
+
+ if (!invocation)
+ return nullptr;
+
+ std::unique_ptr<llvm::MemoryBuffer> source_buffer =
+ llvm::MemoryBuffer::getMemBuffer(
+ "extern int __lldb __attribute__((unavailable));",
+ ModuleImportBufferName);
+
+ invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName,
+ source_buffer.release());
+
+ std::unique_ptr<clang::CompilerInstance> instance(
+ new clang::CompilerInstance);
+
+ instance->setDiagnostics(diagnostics_engine.get());
+ instance->setInvocation(invocation.get());
+
+ std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
+
+ instance->setTarget(clang::TargetInfo::CreateTargetInfo(
+ *diagnostics_engine, instance->getInvocation().TargetOpts));
+
+ if (!instance->hasTarget())
+ return nullptr;
+
+ instance->getTarget().adjust(instance->getLangOpts());
+
+ if (!action->BeginSourceFile(*instance,
+ instance->getFrontendOpts().Inputs[0]))
+ return nullptr;
+
+ instance->getPreprocessor().enableIncrementalProcessing();
+
+ instance->createModuleManager();
+
+ instance->createSema(action->getTranslationUnitKind(), nullptr);
+
+ const bool skipFunctionBodies = false;
+ std::unique_ptr<clang::Parser> parser(new clang::Parser(
+ instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));
+
+ instance->getPreprocessor().EnterMainSourceFile();
+ parser->Initialize();
+
+ clang::Parser::DeclGroupPtrTy parsed;
+
+ while (!parser->ParseTopLevelDecl(parsed))
+ ;
+
+ return new ClangModulesDeclVendorImpl(diagnostics_engine, invocation,
+ std::move(instance), std::move(parser));
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index df3b20550f9a..fbabcd736865 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -18,111 +18,104 @@
#include <set>
#include <vector>
-namespace lldb_private
-{
-
-class ClangModulesDeclVendor : public DeclVendor
-{
+namespace lldb_private {
+
+class ClangModulesDeclVendor : public DeclVendor {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ClangModulesDeclVendor();
-
- ~ClangModulesDeclVendor() override;
-
- static ClangModulesDeclVendor *
- Create(Target &target);
-
- typedef std::vector<ConstString> ModulePath;
- typedef uintptr_t ModuleID;
- typedef std::vector<ModuleID> ModuleVector;
-
- //------------------------------------------------------------------
- /// Add a module to the list of modules to search.
- ///
- /// @param[in] path
- /// The path to the exact module to be loaded. E.g., if the desired
- /// module is std.io, then this should be { "std", "io" }.
- ///
- /// @param[in] exported_modules
- /// If non-NULL, a pointer to a vector to populate with the ID of every
- /// module that is re-exported by the specified module.
- ///
- /// @param[in] error_stream
- /// A stream to populate with the output of the Clang parser when
- /// it tries to load the module.
- ///
- /// @return
- /// True if the module could be loaded; false if not. If the
- /// compiler encountered a fatal error during a previous module
- /// load, then this will always return false for this ModuleImporter.
- //------------------------------------------------------------------
- virtual bool
- AddModule(ModulePath &path,
- ModuleVector *exported_modules,
- Stream &error_stream) = 0;
-
- //------------------------------------------------------------------
- /// Add all modules referred to in a given compilation unit to the list
- /// of modules to search.
- ///
- /// @param[in] cu
- /// The compilation unit to scan for imported modules.
- ///
- /// @param[in] exported_modules
- /// A vector to populate with the ID of each module loaded (directly
- /// and via re-exports) in this way.
- ///
- /// @param[in] error_stream
- /// A stream to populate with the output of the Clang parser when
- /// it tries to load the modules.
- ///
- /// @return
- /// True if all modules referred to by the compilation unit could be
- /// loaded; false if one could not be loaded. If the compiler
- /// encountered a fatal error during a previous module
- /// load, then this will always return false for this ModuleImporter.
- //------------------------------------------------------------------
- virtual bool
- AddModulesForCompileUnit(CompileUnit &cu,
- ModuleVector &exported_modules,
- Stream &error_stream) = 0;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ClangModulesDeclVendor();
+
+ ~ClangModulesDeclVendor() override;
+
+ static ClangModulesDeclVendor *Create(Target &target);
+
+ typedef std::vector<ConstString> ModulePath;
+ typedef uintptr_t ModuleID;
+ typedef std::vector<ModuleID> ModuleVector;
- //------------------------------------------------------------------
- /// Enumerate all the macros that are defined by a given set of modules
- /// that are already imported.
- ///
- /// @param[in] modules
- /// The unique IDs for all modules to query. Later modules have higher
- /// priority, just as if you @imported them in that order. This matters
- /// if module A #defines a macro and module B #undefs it.
- ///
- /// @param[in] handler
- /// A function to call with the text of each #define (including the
- /// #define directive). #undef directives are not included; we simply
- /// elide any corresponding #define. If this function returns true,
- /// we stop the iteration immediately.
- //------------------------------------------------------------------
- virtual void
- ForEachMacro(const ModuleVector &modules,
- std::function<bool (const std::string &)> handler) = 0;
-
- //------------------------------------------------------------------
- /// Query whether Clang supports modules for a particular language.
- /// LLDB uses this to decide whether to try to find the modules loaded
- /// by a gaiven compile unit.
- ///
- /// @param[in] language
- /// The language to query for.
- ///
- /// @return
- /// True if Clang has modules for the given language.
- //------------------------------------------------------------------
- static bool
- LanguageSupportsClangModules (lldb::LanguageType language);
+ //------------------------------------------------------------------
+ /// Add a module to the list of modules to search.
+ ///
+ /// @param[in] path
+ /// The path to the exact module to be loaded. E.g., if the desired
+ /// module is std.io, then this should be { "std", "io" }.
+ ///
+ /// @param[in] exported_modules
+ /// If non-NULL, a pointer to a vector to populate with the ID of every
+ /// module that is re-exported by the specified module.
+ ///
+ /// @param[in] error_stream
+ /// A stream to populate with the output of the Clang parser when
+ /// it tries to load the module.
+ ///
+ /// @return
+ /// True if the module could be loaded; false if not. If the
+ /// compiler encountered a fatal error during a previous module
+ /// load, then this will always return false for this ModuleImporter.
+ //------------------------------------------------------------------
+ virtual bool AddModule(ModulePath &path, ModuleVector *exported_modules,
+ Stream &error_stream) = 0;
+
+ //------------------------------------------------------------------
+ /// Add all modules referred to in a given compilation unit to the list
+ /// of modules to search.
+ ///
+ /// @param[in] cu
+ /// The compilation unit to scan for imported modules.
+ ///
+ /// @param[in] exported_modules
+ /// A vector to populate with the ID of each module loaded (directly
+ /// and via re-exports) in this way.
+ ///
+ /// @param[in] error_stream
+ /// A stream to populate with the output of the Clang parser when
+ /// it tries to load the modules.
+ ///
+ /// @return
+ /// True if all modules referred to by the compilation unit could be
+ /// loaded; false if one could not be loaded. If the compiler
+ /// encountered a fatal error during a previous module
+ /// load, then this will always return false for this ModuleImporter.
+ //------------------------------------------------------------------
+ virtual bool AddModulesForCompileUnit(CompileUnit &cu,
+ ModuleVector &exported_modules,
+ Stream &error_stream) = 0;
+
+ //------------------------------------------------------------------
+ /// Enumerate all the macros that are defined by a given set of modules
+ /// that are already imported.
+ ///
+ /// @param[in] modules
+ /// The unique IDs for all modules to query. Later modules have higher
+ /// priority, just as if you @imported them in that order. This matters
+ /// if module A #defines a macro and module B #undefs it.
+ ///
+ /// @param[in] handler
+ /// A function to call with the text of each #define (including the
+ /// #define directive). #undef directives are not included; we simply
+ /// elide any corresponding #define. If this function returns true,
+ /// we stop the iteration immediately.
+ //------------------------------------------------------------------
+ virtual void
+ ForEachMacro(const ModuleVector &modules,
+ std::function<bool(const std::string &)> handler) = 0;
+
+ //------------------------------------------------------------------
+ /// Query whether Clang supports modules for a particular language.
+ /// LLDB uses this to decide whether to try to find the modules loaded
+ /// by a gaiven compile unit.
+ ///
+ /// @param[in] language
+ /// The language to query for.
+ ///
+ /// @return
+ /// True if Clang has modules for the given language.
+ //------------------------------------------------------------------
+ static bool LanguageSupportsClangModules(lldb::LanguageType language);
};
-
+
} // namespace lldb_private
#endif // liblldb_ClangModulesDeclVendor_h
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index d1478e49bff5..4d30956177da 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -21,74 +21,66 @@
using namespace lldb;
using namespace lldb_private;
-ClangPersistentVariables::ClangPersistentVariables () :
- lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
- m_next_persistent_variable_id (0)
-{
-}
+ClangPersistentVariables::ClangPersistentVariables()
+ : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
+ m_next_persistent_variable_id(0) {}
-ExpressionVariableSP
-ClangPersistentVariables::CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp)
-{
- return AddNewlyConstructedVariable(new ClangExpressionVariable(valobj_sp));
+ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
+ const lldb::ValueObjectSP &valobj_sp) {
+ return AddNewlyConstructedVariable(new ClangExpressionVariable(valobj_sp));
}
-ExpressionVariableSP
-ClangPersistentVariables::CreatePersistentVariable (ExecutionContextScope *exe_scope,
- const ConstString &name,
- const CompilerType& compiler_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size)
-{
- return AddNewlyConstructedVariable(new ClangExpressionVariable(exe_scope, name, compiler_type, byte_order, addr_byte_size));
+ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
+ ExecutionContextScope *exe_scope, const ConstString &name,
+ const CompilerType &compiler_type, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size) {
+ return AddNewlyConstructedVariable(new ClangExpressionVariable(
+ exe_scope, name, compiler_type, byte_order, addr_byte_size));
}
-void
-ClangPersistentVariables::RemovePersistentVariable (lldb::ExpressionVariableSP variable)
-{
- RemoveVariable(variable);
-
- const char *name = variable->GetName().AsCString();
-
- if (*name != '$')
- return;
- name++;
-
- if (strtoul(name, NULL, 0) == m_next_persistent_variable_id - 1)
- m_next_persistent_variable_id--;
+void ClangPersistentVariables::RemovePersistentVariable(
+ lldb::ExpressionVariableSP variable) {
+ RemoveVariable(variable);
+
+ const char *name = variable->GetName().AsCString();
+
+ if (*name != '$')
+ return;
+ name++;
+
+ if (strtoul(name, NULL, 0) == m_next_persistent_variable_id - 1)
+ m_next_persistent_variable_id--;
}
-ConstString
-ClangPersistentVariables::GetNextPersistentVariableName ()
-{
- char name_cstr[256];
- ::snprintf (name_cstr, sizeof(name_cstr), "$%u", m_next_persistent_variable_id++);
- ConstString name(name_cstr);
- return name;
+ConstString ClangPersistentVariables::GetNextPersistentVariableName() {
+ char name_cstr[256];
+ ::snprintf(name_cstr, sizeof(name_cstr), "$%u",
+ m_next_persistent_variable_id++);
+ ConstString name(name_cstr);
+ return name;
}
-void
-ClangPersistentVariables::RegisterPersistentDecl (const ConstString &name,
- clang::NamedDecl *decl)
-{
- m_persistent_decls.insert(std::pair<const char*, clang::NamedDecl*>(name.GetCString(), decl));
-
- if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl))
- {
- for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators())
- {
- m_persistent_decls.insert(std::pair<const char*, clang::NamedDecl*>(ConstString(enumerator_decl->getNameAsString()).GetCString(), enumerator_decl));
- }
+void ClangPersistentVariables::RegisterPersistentDecl(const ConstString &name,
+ clang::NamedDecl *decl) {
+ m_persistent_decls.insert(
+ std::pair<const char *, clang::NamedDecl *>(name.GetCString(), decl));
+
+ if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl)) {
+ for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators()) {
+ m_persistent_decls.insert(std::pair<const char *, clang::NamedDecl *>(
+ ConstString(enumerator_decl->getNameAsString()).GetCString(),
+ enumerator_decl));
}
+ }
}
clang::NamedDecl *
-ClangPersistentVariables::GetPersistentDecl (const ConstString &name)
-{
- PersistentDeclMap::const_iterator i = m_persistent_decls.find(name.GetCString());
-
- if (i == m_persistent_decls.end())
- return NULL;
- else
- return i->second;
+ClangPersistentVariables::GetPersistentDecl(const ConstString &name) {
+ PersistentDeclMap::const_iterator i =
+ m_persistent_decls.find(name.GetCString());
+
+ if (i == m_persistent_decls.end())
+ return NULL;
+ else
+ return i->second;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index 2928976592d8..16981a7fe14a 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -21,81 +21,74 @@
#include "lldb/Expression/ExpressionVariable.h"
-namespace lldb_private
-{
-
+namespace lldb_private {
+
//----------------------------------------------------------------------
-/// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h"
-/// @brief Manages persistent values that need to be preserved between expression invocations.
+/// @class ClangPersistentVariables ClangPersistentVariables.h
+/// "lldb/Expression/ClangPersistentVariables.h"
+/// @brief Manages persistent values that need to be preserved between
+/// expression invocations.
///
/// A list of variables that can be accessed and updated by any expression. See
/// ClangPersistentVariable for more discussion. Also provides an increasing,
/// 0-based counter for naming result variables.
//----------------------------------------------------------------------
-class ClangPersistentVariables : public PersistentExpressionState
-{
+class ClangPersistentVariables : public PersistentExpressionState {
public:
- ClangPersistentVariables();
-
- ~ClangPersistentVariables() override = default;
-
- //------------------------------------------------------------------
- // llvm casting support
- //------------------------------------------------------------------
- static bool classof(const PersistentExpressionState *pv)
- {
- return pv->getKind() == PersistentExpressionState::eKindClang;
- }
-
- lldb::ExpressionVariableSP
- CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp) override;
-
- lldb::ExpressionVariableSP
- CreatePersistentVariable (ExecutionContextScope *exe_scope,
- const ConstString &name,
- const CompilerType& compiler_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size) override;
-
- //----------------------------------------------------------------------
- /// Return the next entry in the sequence of strings "$0", "$1", ... for
- /// use naming persistent expression convenience variables.
- ///
- /// @return
- /// A string that contains the next persistent variable name.
- //----------------------------------------------------------------------
- ConstString
- GetNextPersistentVariableName () override;
-
- void
- RemovePersistentVariable (lldb::ExpressionVariableSP variable) override;
-
- void
- RegisterPersistentDecl (const ConstString &name,
- clang::NamedDecl *decl);
-
- clang::NamedDecl *
- GetPersistentDecl (const ConstString &name);
-
- void
- AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module)
- {
- m_hand_loaded_clang_modules.push_back(module);
- }
-
- const ClangModulesDeclVendor::ModuleVector &GetHandLoadedClangModules()
- {
- return m_hand_loaded_clang_modules;
- }
-
+ ClangPersistentVariables();
+
+ ~ClangPersistentVariables() override = default;
+
+ //------------------------------------------------------------------
+ // llvm casting support
+ //------------------------------------------------------------------
+ static bool classof(const PersistentExpressionState *pv) {
+ return pv->getKind() == PersistentExpressionState::eKindClang;
+ }
+
+ lldb::ExpressionVariableSP
+ CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override;
+
+ lldb::ExpressionVariableSP CreatePersistentVariable(
+ ExecutionContextScope *exe_scope, const ConstString &name,
+ const CompilerType &compiler_type, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size) override;
+
+ //----------------------------------------------------------------------
+ /// Return the next entry in the sequence of strings "$0", "$1", ... for
+ /// use naming persistent expression convenience variables.
+ ///
+ /// @return
+ /// A string that contains the next persistent variable name.
+ //----------------------------------------------------------------------
+ ConstString GetNextPersistentVariableName() override;
+
+ void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
+
+ void RegisterPersistentDecl(const ConstString &name, clang::NamedDecl *decl);
+
+ clang::NamedDecl *GetPersistentDecl(const ConstString &name);
+
+ void AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module) {
+ m_hand_loaded_clang_modules.push_back(module);
+ }
+
+ const ClangModulesDeclVendor::ModuleVector &GetHandLoadedClangModules() {
+ return m_hand_loaded_clang_modules;
+ }
+
private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
-
- typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap;
- PersistentDeclMap m_persistent_decls; ///< Persistent entities declared by the user.
-
- ClangModulesDeclVendor::ModuleVector m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded; these are the highest-
- ///< priority source for macros.
+ uint32_t m_next_persistent_variable_id; ///< The counter used by
+ ///GetNextResultName().
+
+ typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap;
+ PersistentDeclMap
+ m_persistent_decls; ///< Persistent entities declared by the user.
+
+ ClangModulesDeclVendor::ModuleVector
+ m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded;
+ ///these are the highest-
+ ///< priority source for macros.
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 52d49aecec9a..5abad71b84a7 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -9,21 +9,21 @@
#include <stdio.h>
#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
+#include <sys/types.h>
#endif
#include <cstdlib>
-#include <string>
#include <map>
+#include <string>
#include "ClangUserExpression.h"
#include "ASTResultSynthesizer.h"
+#include "ClangDiagnostic.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
-#include "ClangDiagnostic.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
@@ -39,11 +39,11 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
-#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -57,676 +57,633 @@
using namespace lldb_private;
-ClangUserExpression::ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
- lldb::LanguageType language, ResultType desired_type,
- const EvaluateExpressionOptions &options)
- : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type, options),
- m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
-{
- switch (m_language)
- {
- case lldb::eLanguageTypeC_plus_plus:
- m_allow_cxx = true;
- break;
- case lldb::eLanguageTypeObjC:
- m_allow_objc = true;
- break;
- case lldb::eLanguageTypeObjC_plus_plus:
- default:
- m_allow_cxx = true;
- m_allow_objc = true;
- break;
- }
+ClangUserExpression::ClangUserExpression(
+ ExecutionContextScope &exe_scope, llvm::StringRef expr,
+ llvm::StringRef prefix, lldb::LanguageType language,
+ ResultType desired_type, const EvaluateExpressionOptions &options)
+ : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
+ options),
+ m_type_system_helper(*m_target_wp.lock().get(),
+ options.GetExecutionPolicy() ==
+ eExecutionPolicyTopLevel) {
+ switch (m_language) {
+ case lldb::eLanguageTypeC_plus_plus:
+ m_allow_cxx = true;
+ break;
+ case lldb::eLanguageTypeObjC:
+ m_allow_objc = true;
+ break;
+ case lldb::eLanguageTypeObjC_plus_plus:
+ default:
+ m_allow_cxx = true;
+ m_allow_objc = true;
+ break;
+ }
}
-ClangUserExpression::~ClangUserExpression ()
-{
-}
+ClangUserExpression::~ClangUserExpression() {}
+
+void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("ClangUserExpression::ScanContext()");
-void
-ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ m_target = exe_ctx.GetTargetPtr();
+ if (!(m_allow_cxx || m_allow_objc)) {
if (log)
- log->Printf("ClangUserExpression::ScanContext()");
+ log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
+ return;
+ }
- m_target = exe_ctx.GetTargetPtr();
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame == NULL) {
+ if (log)
+ log->Printf(" [CUE::SC] Null stack frame");
+ return;
+ }
- if (!(m_allow_cxx || m_allow_objc))
- {
- if (log)
- log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
- return;
- }
+ SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame == NULL)
- {
- if (log)
- log->Printf(" [CUE::SC] Null stack frame");
- return;
- }
+ if (!sym_ctx.function) {
+ if (log)
+ log->Printf(" [CUE::SC] Null function");
+ return;
+ }
- SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
+ // Find the block that defines the function represented by "sym_ctx"
+ Block *function_block = sym_ctx.GetFunctionBlock();
- if (!sym_ctx.function)
- {
- if (log)
- log->Printf(" [CUE::SC] Null function");
- return;
- }
+ if (!function_block) {
+ if (log)
+ log->Printf(" [CUE::SC] Null function block");
+ return;
+ }
- // Find the block that defines the function represented by "sym_ctx"
- Block *function_block = sym_ctx.GetFunctionBlock();
+ CompilerDeclContext decl_context = function_block->GetDeclContext();
- if (!function_block)
- {
- if (log)
- log->Printf(" [CUE::SC] Null function block");
- return;
- }
+ if (!decl_context) {
+ if (log)
+ log->Printf(" [CUE::SC] Null decl context");
+ return;
+ }
+
+ if (clang::CXXMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) {
+ if (m_allow_cxx && method_decl->isInstance()) {
+ if (m_enforce_valid_object) {
+ lldb::VariableListSP variable_list_sp(
+ function_block->GetBlockVariableList(true));
+
+ const char *thisErrorString = "Stopped in a C++ method, but 'this' "
+ "isn't available; pretending we are in a "
+ "generic context";
+
+ if (!variable_list_sp) {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
- CompilerDeclContext decl_context = function_block->GetDeclContext();
+ lldb::VariableSP this_var_sp(
+ variable_list_sp->FindVariable(ConstString("this")));
- if (!decl_context)
- {
- if (log)
- log->Printf(" [CUE::SC] Null decl context");
- return;
+ if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
+ !this_var_sp->LocationIsValidForFrame(frame)) {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+ }
+
+ m_in_cplusplus_method = true;
+ m_needs_object_ptr = true;
}
+ } else if (clang::ObjCMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsObjCMethodDecl(
+ decl_context)) {
+ if (m_allow_objc) {
+ if (m_enforce_valid_object) {
+ lldb::VariableListSP variable_list_sp(
+ function_block->GetBlockVariableList(true));
+
+ const char *selfErrorString = "Stopped in an Objective-C method, but "
+ "'self' isn't available; pretending we "
+ "are in a generic context";
+
+ if (!variable_list_sp) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
- if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context))
- {
- if (m_allow_cxx && method_decl->isInstance())
- {
- if (m_enforce_valid_object)
- {
- lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
- const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
-
- if (!variable_list_sp)
- {
- err.SetErrorString(thisErrorString);
- return;
- }
-
- lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
-
- if (!this_var_sp ||
- !this_var_sp->IsInScope(frame) ||
- !this_var_sp->LocationIsValidForFrame (frame))
- {
- err.SetErrorString(thisErrorString);
- return;
- }
- }
-
- m_in_cplusplus_method = true;
- m_needs_object_ptr = true;
+ lldb::VariableSP self_variable_sp =
+ variable_list_sp->FindVariable(ConstString("self"));
+
+ if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
+ !self_variable_sp->LocationIsValidForFrame(frame)) {
+ err.SetErrorString(selfErrorString);
+ return;
}
+ }
+
+ m_in_objectivec_method = true;
+ m_needs_object_ptr = true;
+
+ if (!method_decl->isInstanceMethod())
+ m_in_static_method = true;
}
- else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(decl_context))
- {
- if (m_allow_objc)
- {
- if (m_enforce_valid_object)
- {
- lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
- const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
-
- if (!variable_list_sp)
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
-
- if (!self_variable_sp ||
- !self_variable_sp->IsInScope(frame) ||
- !self_variable_sp->LocationIsValidForFrame (frame))
- {
- err.SetErrorString(selfErrorString);
- return;
- }
- }
+ } else if (clang::FunctionDecl *function_decl =
+ ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) {
+ // We might also have a function that said in the debug information that it
+ // captured an
+ // object pointer. The best way to deal with getting to the ivars at
+ // present is by pretending
+ // that this is a method of a class in whatever runtime the debug info says
+ // the object pointer
+ // belongs to. Do that here.
+
+ ClangASTMetadata *metadata =
+ ClangASTContext::DeclContextGetMetaData(decl_context, function_decl);
+ if (metadata && metadata->HasObjectPtr()) {
+ lldb::LanguageType language = metadata->GetObjectPtrLanguage();
+ if (language == lldb::eLanguageTypeC_plus_plus) {
+ if (m_enforce_valid_object) {
+ lldb::VariableListSP variable_list_sp(
+ function_block->GetBlockVariableList(true));
+
+ const char *thisErrorString = "Stopped in a context claiming to "
+ "capture a C++ object pointer, but "
+ "'this' isn't available; pretending we "
+ "are in a generic context";
+
+ if (!variable_list_sp) {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+
+ lldb::VariableSP this_var_sp(
+ variable_list_sp->FindVariable(ConstString("this")));
+
+ if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
+ !this_var_sp->LocationIsValidForFrame(frame)) {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+ }
+ m_in_cplusplus_method = true;
+ m_needs_object_ptr = true;
+ } else if (language == lldb::eLanguageTypeObjC) {
+ if (m_enforce_valid_object) {
+ lldb::VariableListSP variable_list_sp(
+ function_block->GetBlockVariableList(true));
+
+ const char *selfErrorString =
+ "Stopped in a context claiming to capture an Objective-C object "
+ "pointer, but 'self' isn't available; pretending we are in a "
+ "generic context";
+
+ if (!variable_list_sp) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ lldb::VariableSP self_variable_sp =
+ variable_list_sp->FindVariable(ConstString("self"));
+
+ if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
+ !self_variable_sp->LocationIsValidForFrame(frame)) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ Type *self_type = self_variable_sp->GetType();
+
+ if (!self_type) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ CompilerType self_clang_type = self_type->GetForwardCompilerType();
+
+ if (!self_clang_type) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ return;
+ } else if (ClangASTContext::IsObjCObjectPointerType(
+ self_clang_type)) {
m_in_objectivec_method = true;
m_needs_object_ptr = true;
-
- if (!method_decl->isInstanceMethod())
- m_in_static_method = true;
- }
- }
- else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context))
- {
- // We might also have a function that said in the debug information that it captured an
- // object pointer. The best way to deal with getting to the ivars at present is by pretending
- // that this is a method of a class in whatever runtime the debug info says the object pointer
- // belongs to. Do that here.
-
- ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData (decl_context, function_decl);
- if (metadata && metadata->HasObjectPtr())
- {
- lldb::LanguageType language = metadata->GetObjectPtrLanguage();
- if (language == lldb::eLanguageTypeC_plus_plus)
- {
- if (m_enforce_valid_object)
- {
- lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
- const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
-
- if (!variable_list_sp)
- {
- err.SetErrorString(thisErrorString);
- return;
- }
-
- lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
-
- if (!this_var_sp ||
- !this_var_sp->IsInScope(frame) ||
- !this_var_sp->LocationIsValidForFrame (frame))
- {
- err.SetErrorString(thisErrorString);
- return;
- }
- }
-
- m_in_cplusplus_method = true;
- m_needs_object_ptr = true;
- }
- else if (language == lldb::eLanguageTypeObjC)
- {
- if (m_enforce_valid_object)
- {
- lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
- const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
-
- if (!variable_list_sp)
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
-
- if (!self_variable_sp ||
- !self_variable_sp->IsInScope(frame) ||
- !self_variable_sp->LocationIsValidForFrame (frame))
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- Type *self_type = self_variable_sp->GetType();
-
- if (!self_type)
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- CompilerType self_clang_type = self_type->GetForwardCompilerType ();
-
- if (!self_clang_type)
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- if (ClangASTContext::IsObjCClassType(self_clang_type))
- {
- return;
- }
- else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
- {
- m_in_objectivec_method = true;
- m_needs_object_ptr = true;
- }
- else
- {
- err.SetErrorString(selfErrorString);
- return;
- }
- }
- else
- {
- m_in_objectivec_method = true;
- m_needs_object_ptr = true;
- }
- }
+ } else {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+ } else {
+ m_in_objectivec_method = true;
+ m_needs_object_ptr = true;
}
+ }
}
+ }
}
// This is a really nasty hack, meant to fix Objective-C expressions of the form
// (int)[myArray count]. Right now, because the type information for count is
// not available, [myArray count] returns id, which can't be directly cast to
// int without causing a clang error.
-static void
-ApplyObjcCastHack(std::string &expr)
-{
+static void ApplyObjcCastHack(std::string &expr) {
#define OBJC_CAST_HACK_FROM "(int)["
-#define OBJC_CAST_HACK_TO "(int)(long long)["
+#define OBJC_CAST_HACK_TO "(int)(long long)["
- size_t from_offset;
+ size_t from_offset;
- while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
- expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
+ while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
+ expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1,
+ OBJC_CAST_HACK_TO);
#undef OBJC_CAST_HACK_TO
#undef OBJC_CAST_HACK_FROM
}
-bool
-ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
- bool generate_debug_info)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- Error err;
-
- InstallContext(exe_ctx);
-
- if (Target *target = exe_ctx.GetTargetPtr())
- {
- if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
- {
- m_result_delegate.RegisterPersistentState(persistent_state);
- }
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't start parsing (no persistent data)");
- return false;
- }
+bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory,
+ bool generate_debug_info) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ Error err;
+
+ InstallContext(exe_ctx);
+
+ if (Target *target = exe_ctx.GetTargetPtr()) {
+ if (PersistentExpressionState *persistent_state =
+ target->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC)) {
+ m_result_delegate.RegisterPersistentState(persistent_state);
+ } else {
+ diagnostic_manager.PutString(
+ eDiagnosticSeverityError,
+ "couldn't start parsing (no persistent data)");
+ return false;
}
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "error: couldn't start parsing (no target)");
- return false;
+ } else {
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "error: couldn't start parsing (no target)");
+ return false;
+ }
+
+ ScanContext(exe_ctx, err);
+
+ if (!err.Success()) {
+ diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString());
+ }
+
+ ////////////////////////////////////
+ // Generate the expression
+ //
+
+ ApplyObjcCastHack(m_expr_text);
+ // ApplyUnicharHack(m_expr_text);
+
+ std::string prefix = m_expr_prefix;
+
+ if (ClangModulesDeclVendor *decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
+ llvm::cast<ClangPersistentVariables>(
+ m_target->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC))
+ ->GetHandLoadedClangModules();
+ ClangModulesDeclVendor::ModuleVector modules_for_macros;
+
+ for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
+ modules_for_macros.push_back(module);
}
- ScanContext(exe_ctx, err);
+ if (m_target->GetEnableAutoImportClangModules()) {
+ if (StackFrame *frame = exe_ctx.GetFramePtr()) {
+ if (Block *block = frame->GetFrameBlock()) {
+ SymbolContext sc;
- if (!err.Success())
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString());
- }
+ block->CalculateSymbolContext(&sc);
- ////////////////////////////////////
- // Generate the expression
- //
-
- ApplyObjcCastHack(m_expr_text);
- //ApplyUnicharHack(m_expr_text);
-
- std::string prefix = m_expr_prefix;
-
- if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
- ClangModulesDeclVendor::ModuleVector modules_for_macros;
-
- for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
- {
- modules_for_macros.push_back(module);
- }
+ if (sc.comp_unit) {
+ StreamString error_stream;
- if (m_target->GetEnableAutoImportClangModules())
- {
- if (StackFrame *frame = exe_ctx.GetFramePtr())
- {
- if (Block *block = frame->GetFrameBlock())
- {
- SymbolContext sc;
-
- block->CalculateSymbolContext(&sc);
-
- if (sc.comp_unit)
- {
- StreamString error_stream;
-
- decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
- }
- }
- }
+ decl_vendor->AddModulesForCompileUnit(
+ *sc.comp_unit, modules_for_macros, error_stream);
+ }
}
+ }
}
+ }
- lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
+ lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- {
- m_transformed_text = m_expr_text;
- }
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
+ m_transformed_text = m_expr_text;
+ } else {
+ std::unique_ptr<ExpressionSourceCode> source_code(
+ ExpressionSourceCode::CreateWrapped(prefix.c_str(),
+ m_expr_text.c_str()));
+
+ if (m_in_cplusplus_method)
+ lang_type = lldb::eLanguageTypeC_plus_plus;
+ else if (m_in_objectivec_method)
+ lang_type = lldb::eLanguageTypeObjC;
else
- {
- std::unique_ptr<ExpressionSourceCode> source_code(
- ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
-
- if (m_in_cplusplus_method)
- lang_type = lldb::eLanguageTypeC_plus_plus;
- else if (m_in_objectivec_method)
- lang_type = lldb::eLanguageTypeObjC;
- else
- lang_type = lldb::eLanguageTypeC;
-
- if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method, exe_ctx))
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't construct expression body");
- return false;
- }
+ lang_type = lldb::eLanguageTypeC;
+
+ if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method,
+ exe_ctx)) {
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "couldn't construct expression body");
+ return false;
}
+ }
- if (log)
- log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
+ if (log)
+ log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
- ////////////////////////////////////
- // Set up the target and compiler
- //
+ ////////////////////////////////////
+ // Set up the target and compiler
+ //
- Target *target = exe_ctx.GetTargetPtr();
+ Target *target = exe_ctx.GetTargetPtr();
- if (!target)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
- return false;
- }
+ if (!target) {
+ diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
+ return false;
+ }
- //////////////////////////
- // Parse the expression
- //
+ //////////////////////////
+ // Parse the expression
+ //
- m_materializer_ap.reset(new Materializer());
+ m_materializer_ap.reset(new Materializer());
- ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
+ ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
- class OnExit
- {
- public:
- typedef std::function <void (void)> Callback;
+ class OnExit {
+ public:
+ typedef std::function<void(void)> Callback;
- OnExit (Callback const &callback) :
- m_callback(callback)
- {
- }
+ OnExit(Callback const &callback) : m_callback(callback) {}
- ~OnExit ()
- {
- m_callback();
- }
- private:
- Callback m_callback;
- };
+ ~OnExit() { m_callback(); }
- OnExit on_exit([this]() { ResetDeclMap(); });
+ private:
+ Callback m_callback;
+ };
- if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError,
- "current process state is unsuitable for expression parsing");
+ OnExit on_exit([this]() { ResetDeclMap(); });
- ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
+ if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) {
+ diagnostic_manager.PutString(
+ eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
- return false;
- }
+ ResetDeclMap(); // We are being careful here in the case of breakpoint
+ // conditions.
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- {
- DeclMap()->SetLookupsEnabled(true);
- }
+ return false;
+ }
- Process *process = exe_ctx.GetProcessPtr();
- ExecutionContextScope *exe_scope = process;
-
- if (!exe_scope)
- exe_scope = exe_ctx.GetTargetPtr();
-
- // We use a shared pointer here so we can use the original parser - if it succeeds
- // or the rewrite parser we might make if it fails. But the parser_sp will never be empty.
-
- ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
-
- unsigned num_errors = parser.Parse(diagnostic_manager);
-
- // Check here for FixItHints. If there are any try to apply the fixits and set the fixed text in m_fixed_text
- // before returning an error.
- if (num_errors)
- {
- if (diagnostic_manager.HasFixIts())
- {
- if (parser.RewriteExpression(diagnostic_manager))
- {
- size_t fixed_start;
- size_t fixed_end;
- const std::string &fixed_expression = diagnostic_manager.GetFixedExpression();
- if (ExpressionSourceCode::GetOriginalBodyBounds(fixed_expression, lang_type, fixed_start, fixed_end))
- m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start);
- }
- }
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
+ DeclMap()->SetLookupsEnabled(true);
+ }
- ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
+ Process *process = exe_ctx.GetProcessPtr();
+ ExecutionContextScope *exe_scope = process;
- return false;
- }
+ if (!exe_scope)
+ exe_scope = exe_ctx.GetTargetPtr();
- //////////////////////////////////////////////////////////////////////////////////////////
- // Prepare the output of the parser for execution, evaluating it statically if possible
- //
-
- {
- Error jit_error = parser.PrepareForExecution(m_jit_start_addr,
- m_jit_end_addr,
- m_execution_unit_sp,
- exe_ctx,
- m_can_interpret,
- execution_policy);
-
- if (!jit_error.Success())
- {
- const char *error_cstr = jit_error.AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
- return false;
- }
+ // We use a shared pointer here so we can use the original parser - if it
+ // succeeds
+ // or the rewrite parser we might make if it fails. But the parser_sp will
+ // never be empty.
+
+ ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
+
+ unsigned num_errors = parser.Parse(diagnostic_manager);
+
+ // Check here for FixItHints. If there are any try to apply the fixits and
+ // set the fixed text in m_fixed_text
+ // before returning an error.
+ if (num_errors) {
+ if (diagnostic_manager.HasFixIts()) {
+ if (parser.RewriteExpression(diagnostic_manager)) {
+ size_t fixed_start;
+ size_t fixed_end;
+ const std::string &fixed_expression =
+ diagnostic_manager.GetFixedExpression();
+ if (ExpressionSourceCode::GetOriginalBodyBounds(
+ fixed_expression, lang_type, fixed_start, fixed_end))
+ m_fixed_text =
+ fixed_expression.substr(fixed_start, fixed_end - fixed_start);
+ }
}
- if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel)
- {
- Error static_init_error = parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
-
- if (!static_init_error.Success())
- {
- const char *error_cstr = static_init_error.AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.Printf(eDiagnosticSeverityError, "couldn't run static initializers: %s\n",
- error_cstr);
- else
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't run static initializers\n");
- return false;
- }
+ ResetDeclMap(); // We are being careful here in the case of breakpoint
+ // conditions.
+
+ return false;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // Prepare the output of the parser for execution, evaluating it statically if
+ // possible
+ //
+
+ {
+ Error jit_error = parser.PrepareForExecution(
+ m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
+ m_can_interpret, execution_policy);
+
+ if (!jit_error.Success()) {
+ const char *error_cstr = jit_error.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 false;
+ }
+ }
+
+ if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) {
+ Error static_init_error =
+ parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
+
+ if (!static_init_error.Success()) {
+ const char *error_cstr = static_init_error.AsCString();
+ if (error_cstr && error_cstr[0])
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "couldn't run static initializers: %s\n",
+ error_cstr);
+ else
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "couldn't run static initializers\n");
+ return false;
}
+ }
- if (m_execution_unit_sp)
- {
- bool register_execution_unit = false;
+ if (m_execution_unit_sp) {
+ bool register_execution_unit = false;
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- {
- register_execution_unit = true;
- }
-
- // If there is more than one external function in the execution
- // unit, it needs to keep living even if it's not top level, because
- // the result could refer to that function.
-
- if (m_execution_unit_sp->GetJittedFunctions().size() > 1)
- {
- register_execution_unit = true;
- }
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
+ register_execution_unit = true;
+ }
- if (register_execution_unit)
- {
- llvm::cast<PersistentExpressionState>(
- exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(m_language))
- ->RegisterExecutionUnit(m_execution_unit_sp);
- }
+ // If there is more than one external function in the execution
+ // unit, it needs to keep living even if it's not top level, because
+ // the result could refer to that function.
+
+ if (m_execution_unit_sp->GetJittedFunctions().size() > 1) {
+ register_execution_unit = true;
}
- if (generate_debug_info)
- {
- lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
-
- if (jit_module_sp)
- {
- ConstString const_func_name(FunctionName());
- FileSpec jit_file;
- jit_file.GetFilename() = const_func_name;
- jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
- m_jit_module_wp = jit_module_sp;
- target->GetImages().Append(jit_module_sp);
- }
+ if (register_execution_unit) {
+ llvm::cast<PersistentExpressionState>(
+ exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
+ m_language))
+ ->RegisterExecutionUnit(m_execution_unit_sp);
+ }
+ }
+
+ if (generate_debug_info) {
+ lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
+
+ if (jit_module_sp) {
+ ConstString const_func_name(FunctionName());
+ FileSpec jit_file;
+ jit_file.GetFilename() = const_func_name;
+ jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
+ m_jit_module_wp = jit_module_sp;
+ target->GetImages().Append(jit_module_sp);
}
+ }
- ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any
- // ClangASTImporter::Minions.
+ ResetDeclMap(); // Make this go away since we don't need any of its state
+ // after parsing. This also gets rid of any
+ // ClangASTImporter::Minions.
- if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
- m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
- return true;
+ if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
+ m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
+ return true;
}
-bool
-ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
- lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager)
-{
- lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
- lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
-
- if (m_needs_object_ptr)
- {
- lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
- if (!frame_sp)
- return true;
-
- ConstString object_name;
-
- if (m_in_cplusplus_method)
- {
- object_name.SetCString("this");
- }
- else if (m_in_objectivec_method)
- {
- object_name.SetCString("self");
- }
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "need object pointer but don't know the language");
- return false;
- }
+bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
+ std::vector<lldb::addr_t> &args,
+ lldb::addr_t struct_address,
+ DiagnosticManager &diagnostic_manager) {
+ lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
+
+ if (m_needs_object_ptr) {
+ lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+ if (!frame_sp)
+ return true;
+
+ ConstString object_name;
+
+ if (m_in_cplusplus_method) {
+ object_name.SetCString("this");
+ } else if (m_in_objectivec_method) {
+ object_name.SetCString("self");
+ } else {
+ diagnostic_manager.PutString(
+ eDiagnosticSeverityError,
+ "need object pointer but don't know the language");
+ return false;
+ }
- Error object_ptr_error;
+ Error object_ptr_error;
- object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
+ object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
- if (!object_ptr_error.Success())
- {
- exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf("warning: `%s' is not accessible (subsituting 0)\n", object_name.AsCString());
- object_ptr = 0;
- }
+ if (!object_ptr_error.Success()) {
+ exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf(
+ "warning: `%s' is not accessible (subsituting 0)\n",
+ object_name.AsCString());
+ object_ptr = 0;
+ }
- if (m_in_objectivec_method)
- {
- ConstString cmd_name("_cmd");
+ if (m_in_objectivec_method) {
+ ConstString cmd_name("_cmd");
- cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
+ cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
- if (!object_ptr_error.Success())
- {
- diagnostic_manager.Printf(eDiagnosticSeverityWarning,
- "couldn't get cmd pointer (substituting NULL): %s",
- object_ptr_error.AsCString());
- cmd_ptr = 0;
- }
- }
-
- args.push_back(object_ptr);
+ if (!object_ptr_error.Success()) {
+ diagnostic_manager.Printf(
+ eDiagnosticSeverityWarning,
+ "couldn't get cmd pointer (substituting NULL): %s",
+ object_ptr_error.AsCString());
+ cmd_ptr = 0;
+ }
+ }
- if (m_in_objectivec_method)
- args.push_back(cmd_ptr);
+ args.push_back(object_ptr);
- args.push_back(struct_address);
- }
- else
- {
- args.push_back(struct_address);
- }
- return true;
+ if (m_in_objectivec_method)
+ args.push_back(cmd_ptr);
+
+ args.push_back(struct_address);
+ } else {
+ args.push_back(struct_address);
+ }
+ return true;
}
-lldb::ExpressionVariableSP
-ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
-{
- return m_result_delegate.GetVariable();
+lldb::ExpressionVariableSP ClangUserExpression::GetResultAfterDematerialization(
+ ExecutionContextScope *exe_scope) {
+ return m_result_delegate.GetVariable();
}
-void
-ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
-{
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
+void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
+ ExecutionContext &exe_ctx,
+ Materializer::PersistentVariableDelegate &delegate,
+ bool keep_result_in_memory) {
+ m_expr_decl_map_up.reset(
+ new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
}
clang::ASTConsumer *
-ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(clang::ASTConsumer *passthrough)
-{
- m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, m_top_level, m_target));
+ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(
+ clang::ASTConsumer *passthrough) {
+ m_result_synthesizer_up.reset(
+ new ASTResultSynthesizer(passthrough, m_top_level, m_target));
- return m_result_synthesizer_up.get();
+ return m_result_synthesizer_up.get();
}
-void
-ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls()
-{
- if (m_result_synthesizer_up.get())
- {
- m_result_synthesizer_up->CommitPersistentDecls();
- }
+void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
+ if (m_result_synthesizer_up.get()) {
+ m_result_synthesizer_up->CommitPersistentDecls();
+ }
}
-ClangUserExpression::ResultDelegate::ResultDelegate()
-{
-}
+ClangUserExpression::ResultDelegate::ResultDelegate() {}
-ConstString
-ClangUserExpression::ResultDelegate::GetName()
-{
- return m_persistent_state->GetNextPersistentVariableName();
+ConstString ClangUserExpression::ResultDelegate::GetName() {
+ return m_persistent_state->GetNextPersistentVariableName();
}
-void
-ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
-{
- m_variable = variable;
+void ClangUserExpression::ResultDelegate::DidDematerialize(
+ lldb::ExpressionVariableSP &variable) {
+ m_variable = variable;
}
-void
-ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
-{
- m_persistent_state = persistent_state;
+void ClangUserExpression::ResultDelegate::RegisterPersistentState(
+ PersistentExpressionState *persistent_state) {
+ m_persistent_state = persistent_state;
}
-lldb::ExpressionVariableSP &
-ClangUserExpression::ResultDelegate::GetVariable()
-{
- return m_variable;
+lldb::ExpressionVariableSP &ClangUserExpression::ResultDelegate::GetVariable() {
+ return m_variable;
}
-
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 6077588b0244..155c153b873c 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -16,26 +16,26 @@
// Other libraries and framework includes
// Project includes
-#include "ASTStructExtractor.h"
#include "ASTResultSynthesizer.h"
+#include "ASTStructExtractor.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionHelper.h"
#include "ClangExpressionVariable.h"
#include "IRForTarget.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h"
+/// @class ClangUserExpression ClangUserExpression.h
+/// "lldb/Expression/ClangUserExpression.h"
/// @brief Encapsulates a single expression for use with Clang
///
/// LLDB uses expressions for various purposes, notably to call functions
@@ -43,172 +43,154 @@ namespace lldb_private
/// the objects needed to parse and interpret or JIT an expression. It
/// uses the Clang parser to produce LLVM IR from the expression.
//----------------------------------------------------------------------
-class ClangUserExpression : public LLVMUserExpression
-{
+class ClangUserExpression : public LLVMUserExpression {
public:
- enum { kDefaultTimeout = 500000u };
-
- class ClangUserExpressionHelper : public ClangExpressionHelper
- {
- public:
- ClangUserExpressionHelper(Target &target, bool top_level) : m_target(target), m_top_level(top_level) {}
-
- ~ClangUserExpressionHelper() override = default;
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap() override
- {
- return m_expr_decl_map_up.get();
- }
-
- void
- ResetDeclMap()
- {
- m_expr_decl_map_up.reset();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory);
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) override;
-
- void
- CommitPersistentDecls() override;
-
- private:
- Target &m_target;
- std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
- std::unique_ptr<ASTStructExtractor>
- m_struct_extractor_up; ///< The class that generates the argument struct layout.
- std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
- bool m_top_level;
- };
+ enum { kDefaultTimeout = 500000u };
+
+ class ClangUserExpressionHelper : public ClangExpressionHelper {
+ public:
+ ClangUserExpressionHelper(Target &target, bool top_level)
+ : m_target(target), m_top_level(top_level) {}
+
+ ~ClangUserExpressionHelper() override = default;
//------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] expr
- /// The expression to parse.
- ///
- /// @param[in] expr_prefix
- /// If non-NULL, a C string containing translation-unit level
- /// definitions to be included when the expression is parsed.
- ///
- /// @param[in] language
- /// If not eLanguageTypeUnknown, a language to use when parsing
- /// the expression. Currently restricted to those languages
- /// supported by Clang.
- ///
- /// @param[in] desired_type
- /// If not eResultTypeAny, the type to use for the expression
- /// result.
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
//------------------------------------------------------------------
- ClangUserExpression (ExecutionContextScope &exe_scope,
- const char *expr,
- const char *expr_prefix,
- lldb::LanguageType language,
- ResultType desired_type,
- const EvaluateExpressionOptions &options);
+ ClangExpressionDeclMap *DeclMap() override {
+ return m_expr_decl_map_up.get();
+ }
+
+ void ResetDeclMap() { m_expr_decl_map_up.reset(); }
- ~ClangUserExpression() override;
+ void ResetDeclMap(ExecutionContext &exe_ctx,
+ Materializer::PersistentVariableDelegate &result_delegate,
+ bool keep_result_in_memory);
//------------------------------------------------------------------
- /// Parse the expression
- ///
- /// @param[in] diagnostic_manager
- /// A diagnostic manager to report parse errors and warnings to.
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
///
- /// @param[in] exe_ctx
- /// The execution context to use when looking up entities that
- /// are needed for parsing (locations of functions, types of
- /// variables, persistent variables, etc.)
- ///
- /// @param[in] execution_policy
- /// Determines whether interpretation is possible or mandatory.
- ///
- /// @param[in] keep_result_in_memory
- /// True if the resulting persistent variable should reside in
- /// target memory, if applicable.
- ///
- /// @return
- /// True on success (no errors); false otherwise.
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
//------------------------------------------------------------------
- bool
- Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
- bool generate_debug_info) override;
-
- ExpressionTypeSystemHelper *
- GetTypeSystemHelper () override
- {
- return &m_type_system_helper;
- }
-
- ClangExpressionDeclMap *
- DeclMap ()
- {
- return m_type_system_helper.DeclMap();
- }
-
- void
- ResetDeclMap ()
- {
- m_type_system_helper.ResetDeclMap();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory)
- {
- m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate, keep_result_in_memory);
- }
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override;
+
+ void CommitPersistentDecls() override;
+
+ private:
+ Target &m_target;
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+ std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class
+ ///that generates
+ ///the argument
+ ///struct layout.
+ std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
+ bool m_top_level;
+ };
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] expr
+ /// The expression to parse.
+ ///
+ /// @param[in] expr_prefix
+ /// If non-NULL, a C string containing translation-unit level
+ /// definitions to be included when the expression is parsed.
+ ///
+ /// @param[in] language
+ /// If not eLanguageTypeUnknown, a language to use when parsing
+ /// the expression. Currently restricted to those languages
+ /// supported by Clang.
+ ///
+ /// @param[in] desired_type
+ /// If not eResultTypeAny, the type to use for the expression
+ /// result.
+ //------------------------------------------------------------------
+ ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
+ llvm::StringRef prefix, lldb::LanguageType language,
+ ResultType desired_type,
+ const EvaluateExpressionOptions &options);
+
+ ~ClangUserExpression() override;
+
+ //------------------------------------------------------------------
+ /// Parse the expression
+ ///
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report parse errors and warnings to.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when looking up entities that
+ /// are needed for parsing (locations of functions, types of
+ /// variables, persistent variables, etc.)
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether interpretation is possible or mandatory.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// True if the resulting persistent variable should reside in
+ /// target memory, if applicable.
+ ///
+ /// @return
+ /// True on success (no errors); false otherwise.
+ //------------------------------------------------------------------
+ bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory, bool generate_debug_info) override;
+
+ ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+ return &m_type_system_helper;
+ }
+
+ ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
+
+ void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
+
+ void ResetDeclMap(ExecutionContext &exe_ctx,
+ Materializer::PersistentVariableDelegate &result_delegate,
+ bool keep_result_in_memory) {
+ m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
+ keep_result_in_memory);
+ }
+
+ lldb::ExpressionVariableSP
+ GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
- lldb::ExpressionVariableSP
- GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
-
private:
- //------------------------------------------------------------------
- /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
+ /// environment.
+ //------------------------------------------------------------------
+
+ void ScanContext(ExecutionContext &exe_ctx,
+ lldb_private::Error &err) override;
+
+ bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
+ lldb::addr_t struct_address,
+ DiagnosticManager &diagnostic_manager) override;
+
+ ClangUserExpressionHelper m_type_system_helper;
+
+ class ResultDelegate : public Materializer::PersistentVariableDelegate {
+ public:
+ ResultDelegate();
+ ConstString GetName() override;
+ void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
+
+ void RegisterPersistentState(PersistentExpressionState *persistent_state);
+ lldb::ExpressionVariableSP &GetVariable();
+
+ private:
+ PersistentExpressionState *m_persistent_state;
+ lldb::ExpressionVariableSP m_variable;
+ };
- void
- ScanContext (ExecutionContext &exe_ctx,
- lldb_private::Error &err) override;
-
- bool
- AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address,
- DiagnosticManager &diagnostic_manager) override;
-
- ClangUserExpressionHelper m_type_system_helper;
-
- class ResultDelegate : public Materializer::PersistentVariableDelegate
- {
- public:
- ResultDelegate();
- ConstString GetName() override;
- void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
-
- void RegisterPersistentState(PersistentExpressionState *persistent_state);
- lldb::ExpressionVariableSP &GetVariable();
-
- private:
- PersistentExpressionState *m_persistent_state;
- lldb::ExpressionVariableSP m_variable;
- };
-
- ResultDelegate m_result_delegate;
+ ResultDelegate m_result_delegate;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 727e4b3329b3..73d37516ff77 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -1,4 +1,4 @@
-//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
+//===-- ClangUtilityFunction.cpp ---------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
+#include "ClangUtilityFunction.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
-#include "ClangUtilityFunction.h"
// C Includes
#include <stdio.h>
#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
+#include <sys/types.h>
#endif
// C++ Includes
@@ -41,16 +41,11 @@ using namespace lldb_private;
/// @param[in] name
/// The name of the function, as used in the text.
//------------------------------------------------------------------
-ClangUtilityFunction::ClangUtilityFunction (ExecutionContextScope &exe_scope,
- const char *text,
- const char *name) :
- UtilityFunction (exe_scope, text, name)
-{
-}
+ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
+ const char *text, const char *name)
+ : UtilityFunction(exe_scope, text, name) {}
-ClangUtilityFunction::~ClangUtilityFunction ()
-{
-}
+ClangUtilityFunction::~ClangUtilityFunction() {}
//------------------------------------------------------------------
/// Install the utility function into a process
@@ -64,94 +59,85 @@ ClangUtilityFunction::~ClangUtilityFunction ()
/// @return
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
-bool
-ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx)
-{
- if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityWarning, "already installed");
- return false;
- }
+bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx) {
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+ diagnostic_manager.PutString(eDiagnosticSeverityWarning,
+ "already installed");
+ return false;
+ }
- ////////////////////////////////////
- // Set up the target and compiler
- //
-
- Target *target = exe_ctx.GetTargetPtr();
+ ////////////////////////////////////
+ // Set up the target and compiler
+ //
- if (!target)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
- return false;
- }
+ Target *target = exe_ctx.GetTargetPtr();
- Process *process = exe_ctx.GetProcessPtr();
+ if (!target) {
+ diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
+ return false;
+ }
- if (!process)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid process");
- return false;
- }
+ Process *process = exe_ctx.GetProcessPtr();
- //////////////////////////
- // Parse the expression
- //
-
- bool keep_result_in_memory = false;
-
- ResetDeclMap(exe_ctx, keep_result_in_memory);
-
- if (!DeclMap()->WillParse(exe_ctx, NULL))
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError,
- "current process state is unsuitable for expression parsing");
- return false;
- }
+ if (!process) {
+ diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid process");
+ return false;
+ }
- const bool generate_debug_info = true;
- ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info);
+ //////////////////////////
+ // Parse the expression
+ //
- unsigned num_errors = parser.Parse(diagnostic_manager);
+ bool keep_result_in_memory = false;
- if (num_errors)
- {
- ResetDeclMap();
+ ResetDeclMap(exe_ctx, keep_result_in_memory);
- return false;
- }
-
- //////////////////////////////////
- // JIT the output of the parser
- //
-
- bool can_interpret = false; // should stay that way
-
- Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
- m_jit_end_addr,
- m_execution_unit_sp,
- exe_ctx,
- can_interpret,
- eExecutionPolicyAlways);
-
- if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
- {
- m_jit_process_wp = process->shared_from_this();
- if (parser.GetGenerateDebugInfo())
- {
- lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
-
- if (jit_module_sp)
- {
- ConstString const_func_name(FunctionName());
- FileSpec jit_file;
- jit_file.GetFilename() = const_func_name;
- jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
- m_jit_module_wp = jit_module_sp;
- target->GetImages().Append(jit_module_sp);
- }
- }
+ if (!DeclMap()->WillParse(exe_ctx, NULL)) {
+ diagnostic_manager.PutString(
+ eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
+ return false;
+ }
+
+ const bool generate_debug_info = true;
+ ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
+ generate_debug_info);
+
+ unsigned num_errors = parser.Parse(diagnostic_manager);
+
+ if (num_errors) {
+ ResetDeclMap();
+
+ return false;
+ }
+
+ //////////////////////////////////
+ // JIT the output of the parser
+ //
+
+ bool can_interpret = false; // should stay that way
+
+ Error jit_error = parser.PrepareForExecution(
+ m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
+ can_interpret, eExecutionPolicyAlways);
+
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+ m_jit_process_wp = process->shared_from_this();
+ if (parser.GetGenerateDebugInfo()) {
+ lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
+
+ if (jit_module_sp) {
+ ConstString const_func_name(FunctionName());
+ FileSpec jit_file;
+ jit_file.GetFilename() = const_func_name;
+ jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
+ m_jit_module_wp = jit_module_sp;
+ target->GetImages().Append(jit_module_sp);
+ }
}
-
+ }
+
#if 0
// jingham: look here
StreamFile logfile ("/tmp/exprs.txt", "a");
@@ -161,31 +147,26 @@ ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, ExecutionCo
m_function_text.c_str());
#endif
- DeclMap()->DidParse();
-
- ResetDeclMap();
-
- if (jit_error.Success())
- {
- return true;
- }
- else
- {
- const char *error_cstr = jit_error.AsCString();
- if (error_cstr && error_cstr[0])
- {
- diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
- }
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
- }
- return false;
+ DeclMap()->DidParse();
+
+ ResetDeclMap();
+
+ if (jit_error.Success()) {
+ return true;
+ } else {
+ const char *error_cstr = jit_error.AsCString();
+ if (error_cstr && error_cstr[0]) {
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
+ } else {
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "expression can't be interpreted or run");
}
+ return false;
+ }
}
-void
-ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
-{
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
+void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
+ ExecutionContext &exe_ctx, bool keep_result_in_memory) {
+ m_expr_decl_map_up.reset(
+ new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index d4ed37eee049..80577199b818 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -12,24 +12,24 @@
// C Includes
// C++ Includes
-#include <string>
#include <map>
+#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "ClangExpressionHelper.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/UtilityFunction.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ClangUtilityFunction ClangUtilityFunction.h "lldb/Expression/ClangUtilityFunction.h"
+/// @class ClangUtilityFunction ClangUtilityFunction.h
+/// "lldb/Expression/ClangUtilityFunction.h"
/// @brief Encapsulates a single expression for use with Clang
///
/// LLDB uses expressions for various purposes, notably to call functions
@@ -39,97 +39,75 @@ namespace lldb_private
/// simply provide a way to push a function into the target for the debugger to
/// call later on.
//----------------------------------------------------------------------
-class ClangUtilityFunction : public UtilityFunction
-{
+class ClangUtilityFunction : public UtilityFunction {
public:
- class ClangUtilityFunctionHelper : public ClangExpressionHelper
- {
- public:
- ClangUtilityFunctionHelper ()
- {
- }
-
- ~ClangUtilityFunctionHelper() override {}
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap() override
- {
- return m_expr_decl_map_up.get();
- }
-
- void
- ResetDeclMap()
- {
- m_expr_decl_map_up.reset();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory);
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) override
- {
- return nullptr;
- }
- private:
- std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
- };
+ class ClangUtilityFunctionHelper : public ClangExpressionHelper {
+ public:
+ ClangUtilityFunctionHelper() {}
+
+ ~ClangUtilityFunctionHelper() override {}
+
//------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] text
- /// The text of the function. Must be a full translation unit.
- ///
- /// @param[in] name
- /// The name of the function, as used in the text.
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
//------------------------------------------------------------------
- ClangUtilityFunction (ExecutionContextScope &exe_scope,
- const char *text,
- const char *name);
-
- ~ClangUtilityFunction() override;
-
- ExpressionTypeSystemHelper *
- GetTypeSystemHelper () override
- {
- return &m_type_system_helper;
+ ClangExpressionDeclMap *DeclMap() override {
+ return m_expr_decl_map_up.get();
}
- ClangExpressionDeclMap *
- DeclMap()
- {
- return m_type_system_helper.DeclMap();
- }
+ void ResetDeclMap() { m_expr_decl_map_up.reset(); }
- void
- ResetDeclMap ()
- {
- m_type_system_helper.ResetDeclMap();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory)
- {
- m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+ void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory);
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override {
+ return nullptr;
}
- bool
- Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) override;
+ private:
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+ };
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] text
+ /// The text of the function. Must be a full translation unit.
+ ///
+ /// @param[in] name
+ /// The name of the function, as used in the text.
+ //------------------------------------------------------------------
+ ClangUtilityFunction(ExecutionContextScope &exe_scope, const char *text,
+ const char *name);
+
+ ~ClangUtilityFunction() override;
+
+ ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+ return &m_type_system_helper;
+ }
+
+ ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
+
+ void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
+
+ void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory) {
+ m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+ }
+
+ bool Install(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx) override;
private:
- ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when parsing and materializing the expression.
+ ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when
+ ///parsing and materializing
+ ///the expression.
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 12ba7e3c2ac0..356e2e7eba24 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -11,17 +11,17 @@
#include "ClangExpressionDeclMap.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Transforms/IPO.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO.h"
#include "clang/AST/ASTContext.h"
@@ -44,2143 +44,2233 @@ using namespace llvm;
static char ID;
-IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) :
- m_maker(maker),
- m_values()
-{
-}
+IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
+ : m_maker(maker), m_values() {}
-IRForTarget::FunctionValueCache::~FunctionValueCache()
-{
-}
+IRForTarget::FunctionValueCache::~FunctionValueCache() {}
llvm::Value *
-IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
-{
- if (!m_values.count(function))
- {
- llvm::Value *ret = m_maker(function);
- m_values[function] = ret;
- return ret;
- }
- return m_values[function];
+IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
+ if (!m_values.count(function)) {
+ llvm::Value *ret = m_maker(function);
+ m_values[function] = ret;
+ return ret;
+ }
+ return m_values[function];
}
-static llvm::Value *
-FindEntryInstruction (llvm::Function *function)
-{
- if (function->empty())
- return NULL;
+static llvm::Value *FindEntryInstruction(llvm::Function *function) {
+ if (function->empty())
+ return NULL;
- return function->getEntryBlock().getFirstNonPHIOrDbg();
+ return function->getEntryBlock().getFirstNonPHIOrDbg();
}
-IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
- bool resolve_vars,
- lldb_private::IRExecutionUnit &execution_unit,
- lldb_private::Stream *error_stream,
- const char *func_name) :
- ModulePass(ID),
- m_resolve_vars(resolve_vars),
- m_func_name(func_name),
- m_module(NULL),
- m_decl_map(decl_map),
- m_CFStringCreateWithBytes(NULL),
- m_sel_registerName(NULL),
- m_intptr_ty(NULL),
- m_error_stream(error_stream),
- m_execution_unit(execution_unit),
- m_result_store(NULL),
- m_result_is_pointer(false),
- m_reloc_placeholder(NULL),
- m_entry_instruction_finder (FindEntryInstruction)
-{
-}
+IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
+ bool resolve_vars,
+ lldb_private::IRExecutionUnit &execution_unit,
+ lldb_private::Stream &error_stream,
+ const char *func_name)
+ : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
+ m_module(NULL), m_decl_map(decl_map), m_CFStringCreateWithBytes(NULL),
+ m_sel_registerName(NULL), m_objc_getClass(NULL), m_intptr_ty(NULL),
+ m_error_stream(error_stream),
+ m_execution_unit(execution_unit), m_result_store(NULL),
+ m_result_is_pointer(false), m_reloc_placeholder(NULL),
+ m_entry_instruction_finder(FindEntryInstruction) {}
/* Handy utility functions used at several places in the code */
-static std::string
-PrintValue(const Value *value, bool truncate = false)
-{
- std::string s;
- if (value)
- {
- raw_string_ostream rso(s);
- value->print(rso);
- rso.flush();
- if (truncate)
- s.resize(s.length() - 1);
- }
- return s;
-}
-
-static std::string
-PrintType(const llvm::Type *type, bool truncate = false)
-{
- std::string s;
+static std::string PrintValue(const Value *value, bool truncate = false) {
+ std::string s;
+ if (value) {
raw_string_ostream rso(s);
- type->print(rso);
+ value->print(rso);
rso.flush();
if (truncate)
- s.resize(s.length() - 1);
- return s;
+ s.resize(s.length() - 1);
+ }
+ return s;
}
-IRForTarget::~IRForTarget()
-{
+static std::string PrintType(const llvm::Type *type, bool truncate = false) {
+ std::string s;
+ raw_string_ostream rso(s);
+ type->print(rso);
+ rso.flush();
+ if (truncate)
+ s.resize(s.length() - 1);
+ return s;
}
-bool
-IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
-{
- llvm_function.setLinkage(GlobalValue::ExternalLinkage);
+IRForTarget::~IRForTarget() {}
- return true;
+bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
+ llvm_function.setLinkage(GlobalValue::ExternalLinkage);
+
+ return true;
}
-clang::NamedDecl *
-IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
-{
- NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");
+clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
+ Module *module) {
+ NamedMDNode *named_metadata =
+ module->getNamedMetadata("clang.global.decl.ptrs");
- if (!named_metadata)
- return NULL;
+ if (!named_metadata)
+ return NULL;
- unsigned num_nodes = named_metadata->getNumOperands();
- unsigned node_index;
+ unsigned num_nodes = named_metadata->getNumOperands();
+ unsigned node_index;
- for (node_index = 0;
- node_index < num_nodes;
- ++node_index)
- {
- llvm::MDNode *metadata_node = dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
- if (!metadata_node)
- return NULL;
+ for (node_index = 0; node_index < num_nodes; ++node_index) {
+ llvm::MDNode *metadata_node =
+ dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
+ if (!metadata_node)
+ return NULL;
- if (metadata_node->getNumOperands() != 2)
- continue;
+ if (metadata_node->getNumOperands() != 2)
+ continue;
- if (mdconst::dyn_extract_or_null<GlobalValue>(metadata_node->getOperand(0)) != global_val)
- continue;
+ if (mdconst::dyn_extract_or_null<GlobalValue>(
+ metadata_node->getOperand(0)) != global_val)
+ continue;
- ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
+ ConstantInt *constant_int =
+ mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
- if (!constant_int)
- return NULL;
+ if (!constant_int)
+ return NULL;
- uintptr_t ptr = constant_int->getZExtValue();
+ uintptr_t ptr = constant_int->getZExtValue();
- return reinterpret_cast<clang::NamedDecl *>(ptr);
- }
+ return reinterpret_cast<clang::NamedDecl *>(ptr);
+ }
- return NULL;
+ return NULL;
}
-clang::NamedDecl *
-IRForTarget::DeclForGlobal (GlobalValue *global_val)
-{
- return DeclForGlobal(global_val, m_module);
+clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
+ return DeclForGlobal(global_val, m_module);
}
-bool
-IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!m_resolve_vars)
- return true;
+ if (!m_resolve_vars)
+ return true;
- // Find the result variable. If it doesn't exist, we can give up right here.
+ // Find the result variable. If it doesn't exist, we can give up right here.
- ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
+ ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- std::string result_name_str;
- const char *result_name = NULL;
+ std::string result_name_str;
+ const char *result_name = NULL;
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
- vi != ve;
- ++vi)
- {
- result_name_str = vi->first().str();
- const char *value_name = result_name_str.c_str();
-
- if (strstr(value_name, "$__lldb_expr_result_ptr") &&
- strncmp(value_name, "_ZGV", 4))
- {
- result_name = value_name;
- m_result_is_pointer = true;
- break;
- }
+ for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
+ ve = value_symbol_table.end();
+ vi != ve; ++vi) {
+ result_name_str = vi->first().str();
+ const char *value_name = result_name_str.c_str();
- if (strstr(value_name, "$__lldb_expr_result") &&
- strncmp(value_name, "_ZGV", 4))
- {
- result_name = value_name;
- m_result_is_pointer = false;
- break;
- }
+ if (strstr(value_name, "$__lldb_expr_result_ptr") &&
+ strncmp(value_name, "_ZGV", 4)) {
+ result_name = value_name;
+ m_result_is_pointer = true;
+ break;
}
- if (!result_name)
- {
- if (log)
- log->PutCString("Couldn't find result variable");
-
- return true;
+ if (strstr(value_name, "$__lldb_expr_result") &&
+ strncmp(value_name, "_ZGV", 4)) {
+ result_name = value_name;
+ m_result_is_pointer = false;
+ break;
}
+ }
+ if (!result_name) {
if (log)
- log->Printf("Result name: \"%s\"", result_name);
+ log->PutCString("Couldn't find result variable");
- Value *result_value = m_module->getNamedValue(result_name);
+ return true;
+ }
- if (!result_value)
- {
- if (log)
- log->PutCString("Result variable had no data");
+ if (log)
+ log->Printf("Result name: \"%s\"", result_name);
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Result variable's name (%s) exists, but not its definition\n", result_name);
+ Value *result_value = m_module->getNamedValue(result_name);
- return false;
- }
+ if (!result_value) {
+ if (log)
+ log->PutCString("Result variable had no data");
+
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
+ "name (%s) exists, but not its definition\n",
+ result_name);
+
+ return false;
+ }
+ if (log)
+ log->Printf("Found result in the IR: \"%s\"",
+ PrintValue(result_value, false).c_str());
+
+ GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
+
+ if (!result_global) {
if (log)
- log->Printf("Found result in the IR: \"%s\"", PrintValue(result_value, false).c_str());
+ log->PutCString("Result variable isn't a GlobalVariable");
- GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ "is defined, but is not a global variable\n",
+ result_name);
- if (!result_global)
- {
- if (log)
- log->PutCString("Result variable isn't a GlobalVariable");
+ return false;
+ }
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) is defined, but is not a global variable\n", result_name);
+ clang::NamedDecl *result_decl = DeclForGlobal(result_global);
+ if (!result_decl) {
+ if (log)
+ log->PutCString("Result variable doesn't have a corresponding Decl");
- return false;
- }
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ "does not have a corresponding Clang entity\n",
+ result_name);
- clang::NamedDecl *result_decl = DeclForGlobal (result_global);
- if (!result_decl)
- {
- if (log)
- log->PutCString("Result variable doesn't have a corresponding Decl");
+ return false;
+ }
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name);
+ if (log) {
+ std::string decl_desc_str;
+ raw_string_ostream decl_desc_stream(decl_desc_str);
+ result_decl->print(decl_desc_stream);
+ decl_desc_stream.flush();
- return false;
- }
+ log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
+ }
+ clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
+ if (!result_var) {
if (log)
- {
- std::string decl_desc_str;
- raw_string_ostream decl_desc_stream(decl_desc_str);
- result_decl->print(decl_desc_stream);
- decl_desc_stream.flush();
+ log->PutCString("Result variable Decl isn't a VarDecl");
- log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
+ "(%s)'s corresponding Clang entity isn't a "
+ "variable\n",
+ result_name);
+
+ return false;
+ }
+
+ // Get the next available result name from m_decl_map and create the
+ // persistent
+ // variable for it
+
+ // If the result is an Lvalue, it is emitted as a pointer; see
+ // ASTResultSynthesizer::SynthesizeBodyResult.
+ if (m_result_is_pointer) {
+ clang::QualType pointer_qual_type = result_var->getType();
+ const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
+
+ const clang::PointerType *pointer_pointertype =
+ pointer_type->getAs<clang::PointerType>();
+ const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
+ pointer_type->getAs<clang::ObjCObjectPointerType>();
+
+ if (pointer_pointertype) {
+ clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
+
+ m_result_type = lldb_private::TypeFromParser(
+ element_qual_type.getAsOpaquePtr(),
+ lldb_private::ClangASTContext::GetASTContext(
+ &result_decl->getASTContext()));
+ } else if (pointer_objcobjpointertype) {
+ clang::QualType element_qual_type =
+ clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
+
+ m_result_type = lldb_private::TypeFromParser(
+ element_qual_type.getAsOpaquePtr(),
+ lldb_private::ClangASTContext::GetASTContext(
+ &result_decl->getASTContext()));
+ } else {
+ if (log)
+ log->PutCString("Expected result to have pointer type, but it did not");
+
+ m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
+ "is not a pointer variable\n",
+ result_name);
+
+ return false;
}
+ } else {
+ m_result_type = lldb_private::TypeFromParser(
+ result_var->getType().getAsOpaquePtr(),
+ lldb_private::ClangASTContext::GetASTContext(
+ &result_decl->getASTContext()));
+ }
+
+ 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) {
+ lldb_private::StreamString type_desc_stream;
+ m_result_type.DumpTypeDescription(&type_desc_stream);
- clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
- if (!result_var)
- {
- if (log)
- log->PutCString("Result variable Decl isn't a VarDecl");
+ if (log)
+ log->Printf("Result type has size 0");
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name);
+ m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
+ "couldn't be determined\n",
+ type_desc_stream.GetData());
+ return false;
+ }
- return false;
- }
+ if (log) {
+ lldb_private::StreamString type_desc_stream;
+ m_result_type.DumpTypeDescription(&type_desc_stream);
- // Get the next available result name from m_decl_map and create the persistent
- // variable for it
+ log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
+ }
- // If the result is an Lvalue, it is emitted as a pointer; see
- // ASTResultSynthesizer::SynthesizeBodyResult.
- if (m_result_is_pointer)
- {
- clang::QualType pointer_qual_type = result_var->getType();
- const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
+ m_result_name = lldb_private::ConstString("$RESULT_NAME");
- const clang::PointerType *pointer_pointertype = pointer_type->getAs<clang::PointerType>();
- const clang::ObjCObjectPointerType *pointer_objcobjpointertype = pointer_type->getAs<clang::ObjCObjectPointerType>();
+ if (log)
+ log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
+ m_result_name.GetCString(), m_result_type.GetByteSize(nullptr));
- if (pointer_pointertype)
- {
- clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
+ // Construct a new result global and set up its metadata
- m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
- }
- else if (pointer_objcobjpointertype)
- {
- clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
+ GlobalVariable *new_result_global = new GlobalVariable(
+ (*m_module), result_global->getType()->getElementType(),
+ false, /* not constant */
+ GlobalValue::ExternalLinkage, NULL, /* no initializer */
+ m_result_name.GetCString());
- m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
- }
- else
- {
- if (log)
- log->PutCString("Expected result to have pointer type, but it did not");
+ // It's too late in compilation to create a new VarDecl for this, but we don't
+ // need to. We point the metadata at the old VarDecl. This creates an odd
+ // anomaly: a variable with a Value whose name is something like $0 and a
+ // Decl whose name is $__lldb_expr_result. This condition is handled in
+ // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
+ // fixed up.
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Lvalue result (%s) is not a pointer variable\n", result_name);
+ ConstantInt *new_constant_int =
+ ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
+ reinterpret_cast<uint64_t>(result_decl), false);
- return false;
- }
- }
- else
- {
- m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
- }
+ llvm::Metadata *values[2];
+ values[0] = ConstantAsMetadata::get(new_result_global);
+ values[1] = ConstantAsMetadata::get(new_constant_int);
+ ArrayRef<Metadata *> value_ref(values, 2);
- 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)
- {
- lldb_private::StreamString type_desc_stream;
- m_result_type.DumpTypeDescription(&type_desc_stream);
+ MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
+ NamedMDNode *named_metadata =
+ m_module->getNamedMetadata("clang.global.decl.ptrs");
+ named_metadata->addOperand(persistent_global_md);
- if (log)
- log->Printf("Result type has size 0");
+ if (log)
+ log->Printf("Replacing \"%s\" with \"%s\"",
+ PrintValue(result_global).c_str(),
+ PrintValue(new_result_global).c_str());
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n",
- type_desc_stream.GetData());
- return false;
- }
+ if (result_global->use_empty()) {
+ // We need to synthesize a store for this variable, because otherwise
+ // there's nothing to put into its equivalent persistent variable.
- if (log)
- {
- lldb_private::StreamString type_desc_stream;
- m_result_type.DumpTypeDescription(&type_desc_stream);
+ BasicBlock &entry_block(llvm_function.getEntryBlock());
+ Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
+
+ if (!first_entry_instruction)
+ return false;
- log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
+ if (!result_global->hasInitializer()) {
+ if (log)
+ log->Printf("Couldn't find initializer for unused variable");
+
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
+ "(%s) has no writes and no initializer\n",
+ result_name);
+
+ return false;
}
- m_result_name = lldb_private::ConstString("$RESULT_NAME");
+ Constant *initializer = result_global->getInitializer();
+
+ StoreInst *synthesized_store =
+ new StoreInst(initializer, new_result_global, first_entry_instruction);
if (log)
- log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
- m_result_name.GetCString(),
- m_result_type.GetByteSize(nullptr));
+ log->Printf("Synthesized result store \"%s\"\n",
+ PrintValue(synthesized_store).c_str());
+ } else {
+ result_global->replaceAllUsesWith(new_result_global);
+ }
+
+ if (!m_decl_map->AddPersistentVariable(
+ result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
+ return false;
- // Construct a new result global and set up its metadata
+ result_global->eraseFromParent();
- GlobalVariable *new_result_global = new GlobalVariable((*m_module),
- result_global->getType()->getElementType(),
- false, /* not constant */
- GlobalValue::ExternalLinkage,
- NULL, /* no initializer */
- m_result_name.GetCString ());
+ return true;
+}
+
+bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
+ llvm::GlobalVariable *cstr) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- // It's too late in compilation to create a new VarDecl for this, but we don't
- // need to. We point the metadata at the old VarDecl. This creates an odd
- // anomaly: a variable with a Value whose name is something like $0 and a
- // Decl whose name is $__lldb_expr_result. This condition is handled in
- // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
- // fixed up.
+ Type *ns_str_ty = ns_str->getType();
- ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
- reinterpret_cast<uint64_t>(result_decl),
- false);
+ Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
+ Type *i32_ty = Type::getInt32Ty(m_module->getContext());
+ Type *i8_ty = Type::getInt8Ty(m_module->getContext());
- llvm::Metadata *values[2];
- values[0] = ConstantAsMetadata::get(new_result_global);
- values[1] = ConstantAsMetadata::get(new_constant_int);
+ if (!m_CFStringCreateWithBytes) {
+ lldb::addr_t CFStringCreateWithBytes_addr;
- ArrayRef<Metadata *> value_ref(values, 2);
+ static lldb_private::ConstString g_CFStringCreateWithBytes_str(
+ "CFStringCreateWithBytes");
- MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
- NamedMDNode *named_metadata = m_module->getNamedMetadata("clang.global.decl.ptrs");
- named_metadata->addOperand(persistent_global_md);
+ CFStringCreateWithBytes_addr =
+ m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str);
+ if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
+
+ m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
+ "constant string requires "
+ "CFStringCreateWithBytes\n");
+
+ return false;
+ }
if (log)
- log->Printf("Replacing \"%s\" with \"%s\"",
- PrintValue(result_global).c_str(),
- PrintValue(new_result_global).c_str());
+ log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
+ CFStringCreateWithBytes_addr);
- if (result_global->use_empty())
- {
- // We need to synthesize a store for this variable, because otherwise
- // there's nothing to put into its equivalent persistent variable.
+ // Build the function type:
+ //
+ // CFStringRef CFStringCreateWithBytes (
+ // CFAllocatorRef alloc,
+ // const UInt8 *bytes,
+ // CFIndex numBytes,
+ // CFStringEncoding encoding,
+ // Boolean isExternalRepresentation
+ // );
+ //
+ // We make the following substitutions:
+ //
+ // CFStringRef -> i8*
+ // CFAllocatorRef -> i8*
+ // UInt8 * -> i8*
+ // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
+ // pointer size for now)
+ // CFStringEncoding -> i32
+ // Boolean -> i8
+
+ Type *arg_type_array[5];
+
+ arg_type_array[0] = i8_ptr_ty;
+ arg_type_array[1] = i8_ptr_ty;
+ arg_type_array[2] = m_intptr_ty;
+ arg_type_array[3] = i32_ty;
+ arg_type_array[4] = i8_ty;
+
+ ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
+
+ llvm::Type *CFSCWB_ty =
+ FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
+
+ // Build the constant containing the pointer to the function
+ PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
+ Constant *CFSCWB_addr_int =
+ ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
+ m_CFStringCreateWithBytes =
+ ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
+ }
+
+ ConstantDataSequential *string_array = NULL;
+
+ if (cstr)
+ string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
+
+ Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
+ Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
+ : Constant::getNullValue(i8_ptr_ty);
+ Constant *numBytes_arg = ConstantInt::get(
+ m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
+ int encoding_flags = 0;
+ switch (cstr ? string_array->getElementByteSize() : 1) {
+ case 1:
+ encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
+ break;
+ case 2:
+ encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
+ break;
+ case 4:
+ encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
+ break;
+ default:
+ encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
+ if (log) {
+ log->Format("Encountered an Objective-C constant string with unusual "
+ "element size {0}",
+ string_array->getElementByteSize());
+ }
+ }
+ Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
+ Constant *isExternal_arg =
+ ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
+
+ Value *argument_array[5];
+
+ argument_array[0] = alloc_arg;
+ argument_array[1] = bytes_arg;
+ argument_array[2] = numBytes_arg;
+ argument_array[3] = encoding_arg;
+ argument_array[4] = isExternal_arg;
+
+ ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
+
+ FunctionValueCache CFSCWB_Caller(
+ [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
+ return CallInst::Create(
+ m_CFStringCreateWithBytes, CFSCWB_arguments,
+ "CFStringCreateWithBytes",
+ llvm::cast<Instruction>(
+ m_entry_instruction_finder.GetValue(function)));
+ });
+
+ if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
+ m_error_stream)) {
+ if (log)
+ log->PutCString(
+ "Couldn't replace the NSString with the result of the call");
+
+ m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
+ "Objective-C constant string with a dynamic "
+ "string\n");
+
+ return false;
+ }
+
+ ns_str->eraseFromParent();
+
+ return true;
+}
- BasicBlock &entry_block(llvm_function.getEntryBlock());
- Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
+bool IRForTarget::RewriteObjCConstStrings() {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!first_entry_instruction)
- return false;
+ ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- if (!result_global->hasInitializer())
- {
- if (log)
- log->Printf("Couldn't find initializer for unused variable");
+ for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
+ ve = value_symbol_table.end();
+ vi != ve; ++vi) {
+ std::string value_name = vi->first().str();
+ const char *value_name_cstr = value_name.c_str();
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) has no writes and no initializer\n", result_name);
+ if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
+ Value *nsstring_value = vi->second;
- return false;
- }
+ GlobalVariable *nsstring_global =
+ dyn_cast<GlobalVariable>(nsstring_value);
+
+ if (!nsstring_global) {
+ if (log)
+ log->PutCString("NSString variable is not a GlobalVariable");
- Constant *initializer = result_global->getInitializer();
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string is not a global variable\n");
- StoreInst *synthesized_store = new StoreInst(initializer,
- new_result_global,
- first_entry_instruction);
+ return false;
+ }
+ if (!nsstring_global->hasInitializer()) {
if (log)
- log->Printf("Synthesized result store \"%s\"\n", PrintValue(synthesized_store).c_str());
- }
- else
- {
- result_global->replaceAllUsesWith(new_result_global);
- }
+ log->PutCString("NSString variable does not have an initializer");
+
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string does not have an initializer\n");
- if (!m_decl_map->AddPersistentVariable(result_decl,
- m_result_name,
- m_result_type,
- true,
- m_result_is_pointer))
return false;
+ }
- result_global->eraseFromParent();
+ ConstantStruct *nsstring_struct =
+ dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
- return true;
-}
+ if (!nsstring_struct) {
+ if (log)
+ log->PutCString(
+ "NSString variable's initializer is not a ConstantStruct");
-bool
-IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str,
- llvm::GlobalVariable *cstr)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string is not a structure constant\n");
- Type *ns_str_ty = ns_str->getType();
+ return false;
+ }
+
+ // We expect the following structure:
+ //
+ // struct {
+ // int *isa;
+ // int flags;
+ // char *str;
+ // long length;
+ // };
+
+ if (nsstring_struct->getNumOperands() != 4) {
+ if (log)
+ log->Printf("NSString variable's initializer structure has an "
+ "unexpected number of members. Should be 4, is %d",
+ nsstring_struct->getNumOperands());
- Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
- Type *i32_ty = Type::getInt32Ty(m_module->getContext());
- Type *i8_ty = Type::getInt8Ty(m_module->getContext());
+ m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
+ "Objective-C constant string is not as "
+ "expected\n");
- if (!m_CFStringCreateWithBytes)
- {
- lldb::addr_t CFStringCreateWithBytes_addr;
+ return false;
+ }
- static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes");
+ Constant *nsstring_member = nsstring_struct->getOperand(2);
- CFStringCreateWithBytes_addr = m_execution_unit.FindSymbol (g_CFStringCreateWithBytes_str);
- if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
+ if (!nsstring_member) {
+ if (log)
+ log->PutCString("NSString initializer's str element was empty");
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Rewriting an Objective-C constant string requires CFStringCreateWithBytes\n");
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string does not have a string "
+ "initializer\n");
- return false;
- }
+ return false;
+ }
+ ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
+
+ if (!nsstring_expr) {
if (log)
- log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);
-
- // Build the function type:
- //
- // CFStringRef CFStringCreateWithBytes (
- // CFAllocatorRef alloc,
- // const UInt8 *bytes,
- // CFIndex numBytes,
- // CFStringEncoding encoding,
- // Boolean isExternalRepresentation
- // );
- //
- // We make the following substitutions:
- //
- // CFStringRef -> i8*
- // CFAllocatorRef -> i8*
- // UInt8 * -> i8*
- // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its pointer size for now)
- // CFStringEncoding -> i32
- // Boolean -> i8
-
- Type *arg_type_array[5];
-
- arg_type_array[0] = i8_ptr_ty;
- arg_type_array[1] = i8_ptr_ty;
- arg_type_array[2] = m_intptr_ty;
- arg_type_array[3] = i32_ty;
- arg_type_array[4] = i8_ty;
-
- ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
-
- llvm::Type *CFSCWB_ty = FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
-
- // Build the constant containing the pointer to the function
- PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
- Constant *CFSCWB_addr_int = ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
- m_CFStringCreateWithBytes = ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
- }
+ log->PutCString(
+ "NSString initializer's str element is not a ConstantExpr");
- ConstantDataSequential *string_array = NULL;
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string's string initializer is not "
+ "constant\n");
- if (cstr)
- string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
+ return false;
+ }
- Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
- Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) : Constant::getNullValue(i8_ptr_ty);
- Constant *numBytes_arg = ConstantInt::get(m_intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
- Constant *encoding_arg = ConstantInt::get(i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
- Constant *isExternal_arg = ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
+ GlobalVariable *cstr_global = nullptr;
- Value *argument_array[5];
+ if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
+ Constant *nsstring_cstr = nsstring_expr->getOperand(0);
+ cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
+ } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
+ Constant *nsstring_cstr = nsstring_expr->getOperand(0);
+ cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
+ }
- argument_array[0] = alloc_arg;
- argument_array[1] = bytes_arg;
- argument_array[2] = numBytes_arg;
- argument_array[3] = encoding_arg;
- argument_array[4] = isExternal_arg;
+ if (!cstr_global) {
+ if (log)
+ log->PutCString(
+ "NSString initializer's str element is not a GlobalVariable");
- ArrayRef <Value *> CFSCWB_arguments(argument_array, 5);
+ m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
+ "constant string initializer\n");
- FunctionValueCache CFSCWB_Caller ([this, &CFSCWB_arguments] (llvm::Function *function)->llvm::Value * {
- return CallInst::Create(m_CFStringCreateWithBytes,
- CFSCWB_arguments,
- "CFStringCreateWithBytes",
- llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function)));
- });
+ return false;
+ }
- if (!UnfoldConstant(ns_str, CFSCWB_Caller, m_entry_instruction_finder))
- {
+ if (!cstr_global->hasInitializer()) {
if (log)
- log->PutCString("Couldn't replace the NSString with the result of the call");
+ log->PutCString("NSString initializer's str element does not have an "
+ "initializer");
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Couldn't replace an Objective-C constant string with a dynamic string\n");
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string's string initializer doesn't "
+ "point to initialized data\n");
return false;
- }
+ }
+
+ /*
+ if (!cstr_array)
+ {
+ if (log)
+ log->PutCString("NSString initializer's str element is not a
+ ConstantArray");
+
+ if (m_error_stream)
+ m_error_stream.Printf("Internal error [IRForTarget]: An
+ Objective-C constant string's string initializer doesn't point to an
+ array\n");
+
+ return false;
+ }
+
+ if (!cstr_array->isCString())
+ {
+ if (log)
+ log->PutCString("NSString initializer's str element is not a C
+ string array");
+
+ if (m_error_stream)
+ m_error_stream.Printf("Internal error [IRForTarget]: An
+ Objective-C constant string's string initializer doesn't point to a C
+ string\n");
+
+ return false;
+ }
+ */
+
+ ConstantDataArray *cstr_array =
+ dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
+
+ if (log) {
+ if (cstr_array)
+ log->Printf("Found NSString constant %s, which contains \"%s\"",
+ value_name_cstr, cstr_array->getAsString().str().c_str());
+ else
+ log->Printf("Found NSString constant %s, which contains \"\"",
+ value_name_cstr);
+ }
- ns_str->eraseFromParent();
+ if (!cstr_array)
+ cstr_global = NULL;
- return true;
-}
+ if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
+ if (log)
+ log->PutCString("Error rewriting the constant string");
-bool
-IRForTarget::RewriteObjCConstStrings()
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ // We don't print an error message here because RewriteObjCConstString
+ // has done so for us.
- ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
+ return false;
+ }
+ }
+ }
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
- vi != ve;
- ++vi)
- {
- std::string value_name = vi->first().str();
- const char *value_name_cstr = value_name.c_str();
+ for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
+ ve = value_symbol_table.end();
+ vi != ve; ++vi) {
+ std::string value_name = vi->first().str();
+ const char *value_name_cstr = value_name.c_str();
- if (strstr(value_name_cstr, "_unnamed_cfstring_"))
- {
- Value *nsstring_value = vi->second;
+ if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
+ GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
- GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value);
+ if (!gv) {
+ if (log)
+ log->PutCString(
+ "__CFConstantStringClassReference is not a global variable");
- if (!nsstring_global)
- {
- if (log)
- log->PutCString("NSString variable is not a GlobalVariable");
+ m_error_stream.Printf("Internal error [IRForTarget]: Found a "
+ "CFConstantStringClassReference, but it is not a "
+ "global object\n");
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a global variable\n");
+ return false;
+ }
- return false;
- }
+ gv->eraseFromParent();
- if (!nsstring_global->hasInitializer())
- {
- if (log)
- log->PutCString("NSString variable does not have an initializer");
+ break;
+ }
+ }
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have an initializer\n");
+ return true;
+}
- return false;
- }
+static bool IsObjCSelectorRef(Value *value) {
+ GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
- ConstantStruct *nsstring_struct = dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
+ if (!global_variable || !global_variable->hasName() ||
+ !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
+ return false;
- if (!nsstring_struct)
- {
- if (log)
- log->PutCString("NSString variable's initializer is not a ConstantStruct");
+ return true;
+}
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a structure constant\n");
+// This function does not report errors; its callers are responsible.
+bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- return false;
- }
+ LoadInst *load = dyn_cast<LoadInst>(selector_load);
- // We expect the following structure:
- //
- // struct {
- // int *isa;
- // int flags;
- // char *str;
- // long length;
- // };
+ if (!load)
+ return false;
- if (nsstring_struct->getNumOperands() != 4)
- {
- if (log)
- log->Printf("NSString variable's initializer structure has an unexpected number of members. Should be 4, is %d", nsstring_struct->getNumOperands());
+ // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
+ // gets represented as
+ //
+ // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
+ // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...)
+ // ; <i8*>
+ //
+ // where %obj is the object pointer and %tmp is the selector.
+ //
+ // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
+ // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
+ // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
+
+ // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
+ // and get the string from its target
+
+ GlobalVariable *_objc_selector_references_ =
+ dyn_cast<GlobalVariable>(load->getPointerOperand());
+
+ if (!_objc_selector_references_ ||
+ !_objc_selector_references_->hasInitializer())
+ return false;
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: The struct for an Objective-C constant string is not as expected\n");
+ Constant *osr_initializer = _objc_selector_references_->getInitializer();
- return false;
- }
+ ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
- Constant *nsstring_member = nsstring_struct->getOperand(2);
+ if (!osr_initializer_expr ||
+ osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
+ return false;
- if (!nsstring_member)
- {
- if (log)
- log->PutCString("NSString initializer's str element was empty");
+ Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have a string initializer\n");
+ if (!osr_initializer_base)
+ return false;
- return false;
- }
+ // Find the string's initializer (a ConstantArray) and get the string from it
- ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
+ GlobalVariable *_objc_meth_var_name_ =
+ dyn_cast<GlobalVariable>(osr_initializer_base);
- if (!nsstring_expr)
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a ConstantExpr");
+ if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
+ return false;
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not constant\n");
+ Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
- return false;
- }
+ ConstantDataArray *omvn_initializer_array =
+ dyn_cast<ConstantDataArray>(omvn_initializer);
- if (nsstring_expr->getOpcode() != Instruction::GetElementPtr)
- {
- if (log)
- log->Printf("NSString initializer's str element is not a GetElementPtr expression, it's a %s", nsstring_expr->getOpcodeName());
+ if (!omvn_initializer_array->isString())
+ return false;
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array\n");
+ std::string omvn_initializer_string = omvn_initializer_array->getAsString();
- return false;
- }
+ if (log)
+ log->Printf("Found Objective-C selector reference \"%s\"",
+ omvn_initializer_string.c_str());
- Constant *nsstring_cstr = nsstring_expr->getOperand(0);
+ // Construct a call to sel_registerName
- GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
+ if (!m_sel_registerName) {
+ lldb::addr_t sel_registerName_addr;
- if (!cstr_global)
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a GlobalVariable");
+ static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
+ sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str);
+ if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a global\n");
+ if (log)
+ log->Printf("Found sel_registerName at 0x%" PRIx64,
+ sel_registerName_addr);
- return false;
- }
+ // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
- if (!cstr_global->hasInitializer())
- {
- if (log)
- log->PutCString("NSString initializer's str element does not have an initializer");
+ // The below code would be "more correct," but in actuality what's required
+ // is uint8_t*
+ // Type *sel_type = StructType::get(m_module->getContext());
+ // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
+ Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to initialized data\n");
+ Type *type_array[1];
- return false;
- }
+ type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
- /*
- if (!cstr_array)
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a ConstantArray");
+ ArrayRef<Type *> srN_arg_types(type_array, 1);
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to an array\n");
+ llvm::Type *srN_type =
+ FunctionType::get(sel_ptr_type, srN_arg_types, false);
- return false;
- }
+ // Build the constant containing the pointer to the function
+ PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
+ Constant *srN_addr_int =
+ ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
+ m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
+ }
- if (!cstr_array->isCString())
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a C string array");
+ Value *argument_array[1];
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a C string\n");
+ Constant *omvn_pointer = ConstantExpr::getBitCast(
+ _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
- return false;
- }
- */
+ argument_array[0] = omvn_pointer;
- ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
+ ArrayRef<Value *> srN_arguments(argument_array, 1);
- if (log)
- {
- if (cstr_array)
- log->Printf("Found NSString constant %s, which contains \"%s\"", value_name_cstr, cstr_array->getAsString().str().c_str());
- else
- log->Printf("Found NSString constant %s, which contains \"\"", value_name_cstr);
- }
+ CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
+ "sel_registerName", selector_load);
- if (!cstr_array)
- cstr_global = NULL;
+ // Replace the load with the call in all users
- if (!RewriteObjCConstString(nsstring_global, cstr_global))
- {
- if (log)
- log->PutCString("Error rewriting the constant string");
+ selector_load->replaceAllUsesWith(srN_call);
- // We don't print an error message here because RewriteObjCConstString has done so for us.
+ selector_load->eraseFromParent();
- return false;
- }
- }
- }
+ return true;
+}
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
- vi != ve;
- ++vi)
- {
- std::string value_name = vi->first().str();
- const char *value_name_cstr = value_name.c_str();
+bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!strcmp(value_name_cstr, "__CFConstantStringClassReference"))
- {
- GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
+ BasicBlock::iterator ii;
- if (!gv)
- {
- if (log)
- log->PutCString("__CFConstantStringClassReference is not a global variable");
+ typedef SmallVector<Instruction *, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Found a CFConstantStringClassReference, but it is not a global object\n");
+ InstrList selector_loads;
- return false;
- }
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- gv->eraseFromParent();
+ if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+ if (IsObjCSelectorRef(load->getPointerOperand()))
+ selector_loads.push_back(&inst);
+ }
- break;
- }
+ InstrIterator iter;
+
+ for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
+ if (!RewriteObjCSelector(*iter)) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
+ "static reference to an Objective-C selector to a "
+ "dynamic reference\n");
+
+ if (log)
+ log->PutCString(
+ "Couldn't rewrite a reference to an Objective-C selector");
+
+ return false;
}
+ }
- return true;
+ return true;
}
-static bool IsObjCSelectorRef (Value *value)
-{
- GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
+static bool IsObjCClassReference(Value *value) {
+ GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
- if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
- return false;
+ if (!global_variable || !global_variable->hasName() ||
+ !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"))
+ return false;
- return true;
+ return true;
}
// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::RewriteObjCSelector (Instruction* selector_load)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- LoadInst *load = dyn_cast<LoadInst>(selector_load);
+ LoadInst *load = dyn_cast<LoadInst>(class_load);
- if (!load)
- return false;
-
- // Unpack the message name from the selector. In LLVM IR, an objc_msgSend gets represented as
- //
- // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
- // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
- //
- // where %obj is the object pointer and %tmp is the selector.
- //
- // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
- // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
+ if (!load)
+ return false;
- // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target
+ // Unpack the class name from the reference. In LLVM IR, a reference to an
+ // Objective-C class gets represented as
+ //
+ // %tmp = load %struct._objc_class*,
+ // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
+ //
+ // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
+ // @OBJC_CLASS_NAME_.
+ // @OBJC_CLASS_NAME contains the string.
- GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());
+ // Find the pointer's initializer (a ConstantExpr with opcode BitCast)
+ // and get the string from its target
- if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
- return false;
+ GlobalVariable *_objc_class_references_ =
+ dyn_cast<GlobalVariable>(load->getPointerOperand());
- Constant *osr_initializer = _objc_selector_references_->getInitializer();
+ if (!_objc_class_references_ ||
+ !_objc_class_references_->hasInitializer())
+ return false;
- ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
+ Constant *ocr_initializer = _objc_class_references_->getInitializer();
- if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
- return false;
+ ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);
- Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
+ if (!ocr_initializer_expr ||
+ ocr_initializer_expr->getOpcode() != Instruction::BitCast)
+ return false;
- if (!osr_initializer_base)
- return false;
+ Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);
- // Find the string's initializer (a ConstantArray) and get the string from it
+ if (!ocr_initializer_base)
+ return false;
- GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);
+ // Find the string's initializer (a ConstantArray) and get the string from it
- if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
- return false;
+ GlobalVariable *_objc_class_name_ =
+ dyn_cast<GlobalVariable>(ocr_initializer_base);
- Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
-
- ConstantDataArray *omvn_initializer_array = dyn_cast<ConstantDataArray>(omvn_initializer);
+ if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
+ return false;
- if (!omvn_initializer_array->isString())
- return false;
+ Constant *ocn_initializer = _objc_class_name_->getInitializer();
- std::string omvn_initializer_string = omvn_initializer_array->getAsString();
+ ConstantDataArray *ocn_initializer_array =
+ dyn_cast<ConstantDataArray>(ocn_initializer);
- if (log)
- log->Printf("Found Objective-C selector reference \"%s\"", omvn_initializer_string.c_str());
+ if (!ocn_initializer_array->isString())
+ return false;
- // Construct a call to sel_registerName
+ std::string ocn_initializer_string = ocn_initializer_array->getAsString();
- if (!m_sel_registerName)
- {
- lldb::addr_t sel_registerName_addr;
+ if (log)
+ log->Printf("Found Objective-C class reference \"%s\"",
+ ocn_initializer_string.c_str());
- static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
- sel_registerName_addr = m_execution_unit.FindSymbol (g_sel_registerName_str);
- if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
- return false;
+ // Construct a call to objc_getClass
- if (log)
- log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);
+ if (!m_objc_getClass) {
+ lldb::addr_t objc_getClass_addr;
- // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
+ static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
+ objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str);
+ if (objc_getClass_addr == LLDB_INVALID_ADDRESS)
+ return false;
- // The below code would be "more correct," but in actuality what's required is uint8_t*
- //Type *sel_type = StructType::get(m_module->getContext());
- //Type *sel_ptr_type = PointerType::getUnqual(sel_type);
- Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
+ if (log)
+ log->Printf("Found objc_getClass at 0x%" PRIx64,
+ objc_getClass_addr);
- Type *type_array[1];
+ // Build the function type: %struct._objc_class *objc_getClass(i8*)
- type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
+ Type *class_type = load->getType();
+ Type *type_array[1];
+ type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
- ArrayRef<Type *> srN_arg_types(type_array, 1);
+ ArrayRef<Type *> ogC_arg_types(type_array, 1);
- llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);
+ llvm::Type *ogC_type =
+ FunctionType::get(class_type, ogC_arg_types, false);
- // Build the constant containing the pointer to the function
- PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
- Constant *srN_addr_int = ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
- m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
- }
+ // Build the constant containing the pointer to the function
+ PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
+ Constant *ogC_addr_int =
+ ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
+ m_objc_getClass = ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty);
+ }
- Value *argument_array[1];
+ Value *argument_array[1];
- Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
+ Constant *ocn_pointer = ConstantExpr::getBitCast(
+ _objc_class_name_, Type::getInt8PtrTy(m_module->getContext()));
- argument_array[0] = omvn_pointer;
+ argument_array[0] = ocn_pointer;
- ArrayRef<Value *> srN_arguments(argument_array, 1);
+ ArrayRef<Value *> ogC_arguments(argument_array, 1);
- CallInst *srN_call = CallInst::Create(m_sel_registerName,
- srN_arguments,
- "sel_registerName",
- selector_load);
+ CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
+ "objc_getClass", class_load);
- // Replace the load with the call in all users
+ // Replace the load with the call in all users
- selector_load->replaceAllUsesWith(srN_call);
+ class_load->replaceAllUsesWith(ogC_call);
- selector_load->eraseFromParent();
+ class_load->eraseFromParent();
- return true;
+ return true;
}
-bool
-IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
+ BasicBlock::iterator ii;
- typedef SmallVector <Instruction*, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
+ typedef SmallVector<Instruction *, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
- InstrList selector_loads;
+ InstrList class_loads;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- if (LoadInst *load = dyn_cast<LoadInst>(&inst))
- if (IsObjCSelectorRef(load->getPointerOperand()))
- selector_loads.push_back(&inst);
- }
+ if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+ if (IsObjCClassReference(load->getPointerOperand()))
+ class_loads.push_back(&inst);
+ }
- InstrIterator iter;
+ InstrIterator iter;
- for (iter = selector_loads.begin();
- iter != selector_loads.end();
- ++iter)
- {
- if (!RewriteObjCSelector(*iter))
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't change a static reference to an Objective-C selector to a dynamic reference\n");
+ for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) {
+ if (!RewriteObjCClassReference(*iter)) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
+ "static reference to an Objective-C class to a "
+ "dynamic reference\n");
- if (log)
- log->PutCString("Couldn't rewrite a reference to an Objective-C selector");
+ if (log)
+ log->PutCString(
+ "Couldn't rewrite a reference to an Objective-C class");
- return false;
- }
+ return false;
}
+ }
- return true;
+ return true;
}
// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
+ AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
- MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
+ MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
- if (!alloc_md || !alloc_md->getNumOperands())
- return false;
+ if (!alloc_md || !alloc_md->getNumOperands())
+ return false;
- ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
+ ConstantInt *constant_int =
+ mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
- if (!constant_int)
- return false;
+ if (!constant_int)
+ return false;
- // We attempt to register this as a new persistent variable with the DeclMap.
+ // We attempt to register this as a new persistent variable with the DeclMap.
- uintptr_t ptr = constant_int->getZExtValue();
+ uintptr_t ptr = constant_int->getZExtValue();
- clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
+ clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
- lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
+ lldb_private::TypeFromParser result_decl_type(
+ decl->getType().getAsOpaquePtr(),
+ lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
- StringRef decl_name (decl->getName());
- lldb_private::ConstString persistent_variable_name (decl_name.data(), decl_name.size());
- if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, result_decl_type, false, false))
- return false;
+ StringRef decl_name(decl->getName());
+ lldb_private::ConstString persistent_variable_name(decl_name.data(),
+ decl_name.size());
+ if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
+ result_decl_type, false, false))
+ return false;
- GlobalVariable *persistent_global = new GlobalVariable((*m_module),
- alloc->getType(),
- false, /* not constant */
- GlobalValue::ExternalLinkage,
- NULL, /* no initializer */
- alloc->getName().str().c_str());
+ GlobalVariable *persistent_global = new GlobalVariable(
+ (*m_module), alloc->getType(), false, /* not constant */
+ GlobalValue::ExternalLinkage, NULL, /* no initializer */
+ alloc->getName().str());
- // What we're going to do here is make believe this was a regular old external
- // variable. That means we need to make the metadata valid.
+ // What we're going to do here is make believe this was a regular old external
+ // variable. That means we need to make the metadata valid.
- NamedMDNode *named_metadata = m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
+ NamedMDNode *named_metadata =
+ m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
- llvm::Metadata *values[2];
- values[0] = ConstantAsMetadata::get(persistent_global);
- values[1] = ConstantAsMetadata::get(constant_int);
+ llvm::Metadata *values[2];
+ values[0] = ConstantAsMetadata::get(persistent_global);
+ values[1] = ConstantAsMetadata::get(constant_int);
- ArrayRef<llvm::Metadata *> value_ref(values, 2);
+ ArrayRef<llvm::Metadata *> value_ref(values, 2);
- MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
- named_metadata->addOperand(persistent_global_md);
+ MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
+ named_metadata->addOperand(persistent_global_md);
- // Now, since the variable is a pointer variable, we will drop in a load of that
- // pointer variable.
+ // Now, since the variable is a pointer variable, we will drop in a load of
+ // that
+ // pointer variable.
- LoadInst *persistent_load = new LoadInst (persistent_global, "", alloc);
+ LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
- if (log)
- log->Printf("Replacing \"%s\" with \"%s\"",
- PrintValue(alloc).c_str(),
- PrintValue(persistent_load).c_str());
+ if (log)
+ log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
+ PrintValue(persistent_load).c_str());
- alloc->replaceAllUsesWith(persistent_load);
- alloc->eraseFromParent();
+ alloc->replaceAllUsesWith(persistent_load);
+ alloc->eraseFromParent();
- return true;
+ return true;
}
-bool
-IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
-{
- if (!m_resolve_vars)
- return true;
+bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
+ if (!m_resolve_vars)
+ return true;
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
+ BasicBlock::iterator ii;
- typedef SmallVector <Instruction*, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
+ typedef SmallVector<Instruction *, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
- InstrList pvar_allocs;
+ InstrList pvar_allocs;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst))
- {
- llvm::StringRef alloc_name = alloc->getName();
+ if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
+ llvm::StringRef alloc_name = alloc->getName();
- if (alloc_name.startswith("$") &&
- !alloc_name.startswith("$__lldb"))
- {
- if (alloc_name.find_first_of("0123456789") == 1)
- {
- if (log)
- log->Printf("Rejecting a numeric persistent variable.");
+ if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
+ if (alloc_name.find_first_of("0123456789") == 1) {
+ if (log)
+ log->Printf("Rejecting a numeric persistent variable.");
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Names starting with $0, $1, ... are reserved for use as result names\n");
+ m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
+ "$1, ... are reserved for use as result "
+ "names\n");
- return false;
- }
-
- pvar_allocs.push_back(alloc);
- }
+ return false;
}
+
+ pvar_allocs.push_back(alloc);
+ }
}
+ }
- InstrIterator iter;
+ InstrIterator iter;
- for (iter = pvar_allocs.begin();
- iter != pvar_allocs.end();
- ++iter)
- {
- if (!RewritePersistentAlloc(*iter))
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite the creation of a persistent variable\n");
+ for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
+ if (!RewritePersistentAlloc(*iter)) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+ "the creation of a persistent variable\n");
- if (log)
- log->PutCString("Couldn't rewrite the creation of a persistent variable");
+ if (log)
+ log->PutCString(
+ "Couldn't rewrite the creation of a persistent variable");
- return false;
- }
+ return false;
}
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
-{
- if (!initializer)
- return true;
+bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
+ if (!initializer)
+ return true;
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log && log->GetVerbose())
- log->Printf(" MaterializeInitializer(%p, %s)", (void *)data, PrintValue(initializer).c_str());
+ if (log && log->GetVerbose())
+ log->Printf(" MaterializeInitializer(%p, %s)", (void *)data,
+ PrintValue(initializer).c_str());
- Type *initializer_type = initializer->getType();
+ Type *initializer_type = initializer->getType();
- if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
- {
- size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
- lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8);
+ if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
+ size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
+ lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
+ llvm::NextPowerOf2(constant_size) * 8);
- lldb_private::Error get_data_error;
- if (!scalar.GetAsMemoryData(data, constant_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
- return false;
+ lldb_private::Error get_data_error;
+ if (!scalar.GetAsMemoryData(data, constant_size,
+ lldb_private::endian::InlHostByteOrder(),
+ get_data_error))
+ return false;
- return true;
+ return true;
+ } else if (ConstantDataArray *array_initializer =
+ dyn_cast<ConstantDataArray>(initializer)) {
+ if (array_initializer->isString()) {
+ std::string array_initializer_string = array_initializer->getAsString();
+ memcpy(data, array_initializer_string.c_str(),
+ m_target_data->getTypeStoreSize(initializer_type));
+ } else {
+ ArrayType *array_initializer_type = array_initializer->getType();
+ Type *array_element_type = array_initializer_type->getElementType();
+
+ size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
+
+ for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
+ Value *operand_value = array_initializer->getOperand(i);
+ Constant *operand_constant = dyn_cast<Constant>(operand_value);
+
+ if (!operand_constant)
+ return false;
+
+ if (!MaterializeInitializer(data + (i * element_size),
+ operand_constant))
+ return false;
+ }
}
- else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer))
- {
- if (array_initializer->isString())
- {
- std::string array_initializer_string = array_initializer->getAsString();
- memcpy (data, array_initializer_string.c_str(), m_target_data->getTypeStoreSize(initializer_type));
- }
- else
- {
- ArrayType *array_initializer_type = array_initializer->getType();
- Type *array_element_type = array_initializer_type->getElementType();
+ return true;
+ } else if (ConstantStruct *struct_initializer =
+ dyn_cast<ConstantStruct>(initializer)) {
+ StructType *struct_initializer_type = struct_initializer->getType();
+ const StructLayout *struct_layout =
+ m_target_data->getStructLayout(struct_initializer_type);
+
+ for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
+ if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
+ struct_initializer->getOperand(i)))
+ return false;
+ }
+ return true;
+ } else if (isa<ConstantAggregateZero>(initializer)) {
+ memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
+ return true;
+ }
+ return false;
+}
- size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
+// This function does not report errors; its callers are responsible.
+bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
+
+ if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
+ switch (constant_expr->getOpcode()) {
+ default:
+ break;
+ case Instruction::GetElementPtr:
+ case Instruction::BitCast:
+ Value *s = constant_expr->getOperand(0);
+ if (!MaybeHandleVariable(s))
+ return false;
+ }
+ } else if (GlobalVariable *global_variable =
+ dyn_cast<GlobalVariable>(llvm_value_ptr)) {
+ if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
+ return true;
- for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i)
- {
- Value *operand_value = array_initializer->getOperand(i);
- Constant *operand_constant = dyn_cast<Constant>(operand_value);
+ clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
- if (!operand_constant)
- return false;
+ if (!named_decl) {
+ if (IsObjCSelectorRef(llvm_value_ptr))
+ return true;
- if (!MaterializeInitializer(data + (i * element_size), operand_constant))
- return false;
- }
- }
+ if (!global_variable->hasExternalLinkage())
return true;
+
+ if (log)
+ log->Printf("Found global variable \"%s\" without metadata",
+ global_variable->getName().str().c_str());
+
+ return false;
}
- else if (ConstantStruct *struct_initializer = dyn_cast<ConstantStruct>(initializer))
- {
- StructType *struct_initializer_type = struct_initializer->getType();
- const StructLayout *struct_layout = m_target_data->getStructLayout(struct_initializer_type);
-
- for (unsigned i = 0;
- i < struct_initializer->getNumOperands();
- ++i)
- {
- if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), struct_initializer->getOperand(i)))
- return false;
- }
- return true;
+
+ std::string name(named_decl->getName().str());
+
+ clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
+ if (value_decl == NULL)
+ return false;
+
+ lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
+ value_decl->getType());
+
+ const Type *value_type = NULL;
+
+ if (name[0] == '$') {
+ // The $__lldb_expr_result name indicates the return value has allocated
+ // as
+ // a static variable. Per the comment at
+ // ASTResultSynthesizer::SynthesizeBodyResult,
+ // accesses to this static variable need to be redirected to the result of
+ // dereferencing
+ // a pointer that is passed in as one of the arguments.
+ //
+ // Consequently, when reporting the size of the type, we report a pointer
+ // type pointing
+ // to the type of $__lldb_expr_result, not the type itself.
+ //
+ // We also do this for any user-declared persistent variables.
+ compiler_type = compiler_type.GetPointerType();
+ value_type = PointerType::get(global_variable->getType(), 0);
+ } else {
+ value_type = global_variable->getType();
}
- else if (isa<ConstantAggregateZero>(initializer))
- {
- memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
+
+ const uint64_t value_size = compiler_type.GetByteSize(nullptr);
+ lldb::offset_t value_alignment =
+ (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
+
+ if (log) {
+ log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
+ ", align %" PRIu64 "]",
+ name.c_str(),
+ lldb_private::ClangUtil::GetQualType(compiler_type)
+ .getAsString()
+ .c_str(),
+ 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)) {
+ if (!global_variable->hasExternalLinkage())
+ return true;
+ else
return true;
}
+ } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
+ if (log)
+ log->Printf("Function pointers aren't handled right now");
+
return false;
+ }
+
+ return true;
}
// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::HandleSymbol(Value *symbol) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
+ lldb_private::ConstString name(symbol->getName().str().c_str());
- if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr))
- {
- switch (constant_expr->getOpcode())
- {
- default:
- break;
- case Instruction::GetElementPtr:
- case Instruction::BitCast:
- Value *s = constant_expr->getOperand(0);
- if (!MaybeHandleVariable(s))
- return false;
- }
- }
- else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr))
- {
- if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
- return true;
+ lldb::addr_t symbol_addr =
+ m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
- clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
+ if (symbol_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Symbol \"%s\" had no address", name.GetCString());
- if (!named_decl)
- {
- if (IsObjCSelectorRef(llvm_value_ptr))
- return true;
+ return false;
+ }
- if (!global_variable->hasExternalLinkage())
- return true;
+ if (log)
+ log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
- if (log)
- log->Printf("Found global variable \"%s\" without metadata", global_variable->getName().str().c_str());
+ Type *symbol_type = symbol->getType();
- return false;
- }
+ Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
- std::string name (named_decl->getName().str());
+ Value *symbol_addr_ptr =
+ ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
- clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
- if (value_decl == NULL)
- return false;
+ if (log)
+ log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
+ PrintValue(symbol_addr_ptr).c_str());
- lldb_private::CompilerType compiler_type(&value_decl->getASTContext(), value_decl->getType());
-
- const Type *value_type = NULL;
-
- if (name[0] == '$')
- {
- // The $__lldb_expr_result name indicates the return value has allocated as
- // a static variable. Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
- // accesses to this static variable need to be redirected to the result of dereferencing
- // a pointer that is passed in as one of the arguments.
- //
- // Consequently, when reporting the size of the type, we report a pointer type pointing
- // to the type of $__lldb_expr_result, not the type itself.
- //
- // We also do this for any user-declared persistent variables.
- compiler_type = compiler_type.GetPointerType();
- value_type = PointerType::get(global_variable->getType(), 0);
- }
- else
- {
- value_type = global_variable->getType();
- }
+ symbol->replaceAllUsesWith(symbol_addr_ptr);
- const uint64_t value_size = compiler_type.GetByteSize(nullptr);
- lldb::offset_t value_alignment = (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
+ return true;
+}
- if (log)
- {
- log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
- name.c_str(), lldb_private::ClangUtil::GetQualType(compiler_type).getAsString().c_str(),
- PrintType(value_type).c_str(), value_size, value_alignment);
- }
+bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ if (log)
+ log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
- if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
- lldb_private::ConstString (name.c_str()),
- llvm_value_ptr,
- value_size,
- value_alignment))
- {
- if (!global_variable->hasExternalLinkage())
- return true;
- else
- return true;
- }
- }
- else if (dyn_cast<llvm::Function>(llvm_value_ptr))
+ for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
+ op_index < num_ops; ++op_index)
+ if (!MaybeHandleVariable(Old->getArgOperand(
+ op_index))) // conservatively believe that this is a store
{
- if (log)
- log->Printf("Function pointers aren't handled right now");
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+ "one of the arguments of a function call.\n");
- return false;
+ return false;
}
- return true;
+ return true;
}
-// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::HandleSymbol (Value *symbol)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- lldb_private::ConstString name(symbol->getName().str().c_str());
+bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- lldb::addr_t symbol_addr = m_decl_map->GetSymbolAddress (name, lldb::eSymbolTypeAny);
+ GlobalVariable *global_variable =
+ dyn_cast<GlobalVariable>(classlist_reference);
- if (symbol_addr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Symbol \"%s\" had no address", name.GetCString());
+ if (!global_variable)
+ return false;
- return false;
- }
+ Constant *initializer = global_variable->getInitializer();
- if (log)
- log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
+ if (!initializer)
+ return false;
- Type *symbol_type = symbol->getType();
+ if (!initializer->hasName())
+ return false;
- Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
+ StringRef name(initializer->getName());
+ lldb_private::ConstString name_cstr(name.str().c_str());
+ lldb::addr_t class_ptr =
+ m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
- Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
+ if (log)
+ log->Printf("Found reference to Objective-C class %s (0x%llx)",
+ name_cstr.AsCString(), (unsigned long long)class_ptr);
- if (log)
- log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str());
+ if (class_ptr == LLDB_INVALID_ADDRESS)
+ return false;
- symbol->replaceAllUsesWith(symbol_addr_ptr);
+ if (global_variable->use_empty())
+ return false;
- return true;
-}
+ SmallVector<LoadInst *, 2> load_instructions;
-bool
-IRForTarget::MaybeHandleCallArguments (CallInst *Old)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ for (llvm::User *u : global_variable->users()) {
+ if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
+ load_instructions.push_back(load_instruction);
+ }
- if (log)
- log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
+ if (load_instructions.empty())
+ return false;
- for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
- op_index < num_ops;
- ++op_index)
- if (!MaybeHandleVariable(Old->getArgOperand(op_index))) // conservatively believe that this is a store
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call.\n");
+ Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
- return false;
- }
+ for (LoadInst *load_instruction : load_instructions) {
+ Constant *class_bitcast =
+ ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
- return true;
-}
+ load_instruction->replaceAllUsesWith(class_bitcast);
-bool
-IRForTarget::HandleObjCClass(Value *classlist_reference)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ load_instruction->eraseFromParent();
+ }
- GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);
+ return true;
+}
- if (!global_variable)
- return false;
+bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
+ BasicBlock::iterator ii;
- Constant *initializer = global_variable->getInitializer();
+ std::vector<CallInst *> calls_to_remove;
- if (!initializer)
- return false;
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- if (!initializer->hasName())
- return false;
+ CallInst *call = dyn_cast<CallInst>(&inst);
- StringRef name(initializer->getName());
- lldb_private::ConstString name_cstr(name.str().c_str());
- lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
+ // MaybeHandleCallArguments handles error reporting; we are silent here
+ if (!call)
+ continue;
- if (log)
- log->Printf("Found reference to Objective-C class %s (0x%llx)", name_cstr.AsCString(), (unsigned long long)class_ptr);
+ bool remove = false;
- if (class_ptr == LLDB_INVALID_ADDRESS)
- return false;
+ llvm::Function *func = call->getCalledFunction();
- if (global_variable->use_empty())
- return false;
+ if (func && func->getName() == "__cxa_atexit")
+ remove = true;
- SmallVector<LoadInst *, 2> load_instructions;
+ llvm::Value *val = call->getCalledValue();
- for (llvm::User *u : global_variable->users())
- {
- if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
- load_instructions.push_back(load_instruction);
- }
+ if (val && val->getName() == "__cxa_atexit")
+ remove = true;
- if (load_instructions.empty())
- return false;
-
- Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
+ if (remove)
+ calls_to_remove.push_back(call);
+ }
- for (LoadInst *load_instruction : load_instructions)
- {
- Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
+ for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
+ ce = calls_to_remove.end();
+ ci != ce; ++ci) {
+ (*ci)->eraseFromParent();
+ }
- load_instruction->replaceAllUsesWith(class_bitcast);
+ return true;
+}
- load_instruction->eraseFromParent();
- }
+bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
+ /////////////////////////////////////////////////////////////////////////
+ // Prepare the current basic block for execution in the remote process
+ //
- return true;
-}
+ BasicBlock::iterator ii;
-bool
-IRForTarget::RemoveCXAAtExit (BasicBlock &basic_block)
-{
- BasicBlock::iterator ii;
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- std::vector<CallInst *> calls_to_remove;
+ CallInst *call = dyn_cast<CallInst>(&inst);
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ // MaybeHandleCallArguments handles error reporting; we are silent here
+ if (call && !MaybeHandleCallArguments(call))
+ return false;
+ }
- CallInst *call = dyn_cast<CallInst>(&inst);
+ return true;
+}
- // MaybeHandleCallArguments handles error reporting; we are silent here
- if (!call)
- continue;
+bool IRForTarget::ResolveExternals(Function &llvm_function) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- bool remove = false;
+ for (GlobalVariable &global_var : m_module->globals()) {
+ std::string global_name = global_var.getName().str();
- llvm::Function *func = call->getCalledFunction();
+ if (log)
+ log->Printf("Examining %s, DeclForGlobalValue returns %p",
+ global_name.c_str(),
+ static_cast<void *>(DeclForGlobal(&global_var)));
- if (func && func->getName() == "__cxa_atexit")
- remove = true;
+ if (global_name.find("OBJC_IVAR") == 0) {
+ if (!HandleSymbol(&global_var)) {
+ m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C "
+ "indirect ivar symbol %s\n",
+ global_name.c_str());
- llvm::Value *val = call->getCalledValue();
+ return false;
+ }
+ } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") !=
+ global_name.npos) {
+ if (!HandleObjCClass(&global_var)) {
+ m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
+ "for an Objective-C static method call\n");
- if (val && val->getName() == "__cxa_atexit")
- remove = true;
+ return false;
+ }
+ } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") !=
+ global_name.npos) {
+ if (!HandleObjCClass(&global_var)) {
+ m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
+ "for an Objective-C static method call\n");
- if (remove)
- calls_to_remove.push_back(call);
- }
+ return false;
+ }
+ } else if (DeclForGlobal(&global_var)) {
+ if (!MaybeHandleVariable(&global_var)) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+ "external variable %s\n",
+ global_name.c_str());
- for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), ce = calls_to_remove.end();
- ci != ce;
- ++ci)
- {
- (*ci)->eraseFromParent();
+ return false;
+ }
}
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::ResolveCalls(BasicBlock &basic_block)
-{
- /////////////////////////////////////////////////////////////////////////
- // Prepare the current basic block for execution in the remote process
- //
+static bool isGuardVariableRef(Value *V) {
+ Constant *Old = NULL;
- BasicBlock::iterator ii;
+ if (!(Old = dyn_cast<Constant>(V)))
+ return false;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ ConstantExpr *CE = NULL;
- CallInst *call = dyn_cast<CallInst>(&inst);
+ if ((CE = dyn_cast<ConstantExpr>(V))) {
+ if (CE->getOpcode() != Instruction::BitCast)
+ return false;
- // MaybeHandleCallArguments handles error reporting; we are silent here
- if (call && !MaybeHandleCallArguments(call))
- return false;
- }
+ Old = CE->getOperand(0);
+ }
- return true;
-}
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
-bool
-IRForTarget::ResolveExternals (Function &llvm_function)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!GV || !GV->hasName() ||
+ (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
+ !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
+ {
+ return false;
+ }
- for (GlobalVariable &global_var : m_module->globals())
- {
- std::string global_name = global_var.getName().str();
+ return true;
+}
- if (log)
- log->Printf("Examining %s, DeclForGlobalValue returns %p",
- global_name.c_str(),
- static_cast<void*>(DeclForGlobal(&global_var)));
-
- if (global_name.find("OBJC_IVAR") == 0)
- {
- if (!HandleSymbol(&global_var))
- {
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol %s\n", global_name.c_str());
-
- return false;
- }
- }
- else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != global_name.npos)
- {
- if (!HandleObjCClass(&global_var))
- {
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
-
- return false;
- }
- }
- else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != global_name.npos)
- {
- if (!HandleObjCClass(&global_var))
- {
- if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
-
- return false;
- }
- }
- else if (DeclForGlobal(&global_var))
- {
- if (!MaybeHandleVariable (&global_var))
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite external variable %s\n", global_name.c_str());
-
- return false;
- }
- }
- }
+void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
+ Constant *zero(Constant::getNullValue(guard_load->getType()));
+ guard_load->replaceAllUsesWith(zero);
+ guard_load->eraseFromParent();
+}
- return true;
+static void ExciseGuardStore(Instruction *guard_store) {
+ guard_store->eraseFromParent();
}
-static bool isGuardVariableRef(Value *V)
-{
- Constant *Old = NULL;
+bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
+ ///////////////////////////////////////////////////////
+ // Eliminate any reference to guard variables found.
+ //
- if (!(Old = dyn_cast<Constant>(V)))
- return false;
+ BasicBlock::iterator ii;
- ConstantExpr *CE = NULL;
+ typedef SmallVector<Instruction *, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
- if ((CE = dyn_cast<ConstantExpr>(V)))
- {
- if (CE->getOpcode() != Instruction::BitCast)
- return false;
+ InstrList guard_loads;
+ InstrList guard_stores;
- Old = CE->getOperand(0);
- }
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
+ if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+ if (isGuardVariableRef(load->getPointerOperand()))
+ guard_loads.push_back(&inst);
- if (!GV || !GV->hasName() ||
- (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
- !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
- {
- return false;
- }
+ if (StoreInst *store = dyn_cast<StoreInst>(&inst))
+ if (isGuardVariableRef(store->getPointerOperand()))
+ guard_stores.push_back(&inst);
+ }
- return true;
-}
+ InstrIterator iter;
-void
-IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load)
-{
- Constant *zero(Constant::getNullValue(guard_load->getType()));
- guard_load->replaceAllUsesWith(zero);
- guard_load->eraseFromParent();
-}
+ for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter)
+ TurnGuardLoadIntoZero(*iter);
-static void ExciseGuardStore(Instruction* guard_store)
-{
- guard_store->eraseFromParent();
-}
+ for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
+ ExciseGuardStore(*iter);
-bool
-IRForTarget::RemoveGuards(BasicBlock &basic_block)
-{
- ///////////////////////////////////////////////////////
- // Eliminate any reference to guard variables found.
- //
+ return true;
+}
- BasicBlock::iterator ii;
+// This function does not report errors; its callers are responsible.
+bool IRForTarget::UnfoldConstant(Constant *old_constant,
+ llvm::Function *llvm_function,
+ FunctionValueCache &value_maker,
+ FunctionValueCache &entry_instruction_finder,
+ lldb_private::Stream &error_stream) {
+ SmallVector<User *, 16> users;
+
+ // We do this because the use list might change, invalidating our iterator.
+ // Much better to keep a work list ourselves.
+ for (llvm::User *u : old_constant->users())
+ users.push_back(u);
+
+ for (size_t i = 0; i < users.size(); ++i) {
+ User *user = users[i];
+
+ if (Constant *constant = dyn_cast<Constant>(user)) {
+ // synthesize a new non-constant equivalent of the constant
+
+ if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
+ switch (constant_expr->getOpcode()) {
+ default:
+ error_stream.Printf("error [IRForTarget internal]: Unhandled "
+ "constant expression type: \"%s\"",
+ PrintValue(constant_expr).c_str());
+ return false;
+ case Instruction::BitCast: {
+ FunctionValueCache bit_cast_maker(
+ [&value_maker, &entry_instruction_finder, old_constant,
+ constant_expr](llvm::Function *function) -> llvm::Value * {
+ // UnaryExpr
+ // OperandList[0] is value
+
+ if (constant_expr->getOperand(0) != old_constant)
+ return constant_expr;
+
+ return new BitCastInst(
+ value_maker.GetValue(function), constant_expr->getType(),
+ "", llvm::cast<Instruction>(
+ entry_instruction_finder.GetValue(function)));
+ });
+
+ if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
+ entry_instruction_finder, error_stream))
+ return false;
+ } break;
+ case Instruction::GetElementPtr: {
+ // GetElementPtrConstantExpr
+ // OperandList[0] is base
+ // OperandList[1]... are indices
- typedef SmallVector <Instruction*, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
+ FunctionValueCache get_element_pointer_maker(
+ [&value_maker, &entry_instruction_finder, old_constant,
+ constant_expr](llvm::Function *function) -> llvm::Value * {
+ Value *ptr = constant_expr->getOperand(0);
- InstrList guard_loads;
- InstrList guard_stores;
+ if (ptr == old_constant)
+ ptr = value_maker.GetValue(function);
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ std::vector<Value *> index_vector;
- if (LoadInst *load = dyn_cast<LoadInst>(&inst))
- if (isGuardVariableRef(load->getPointerOperand()))
- guard_loads.push_back(&inst);
+ unsigned operand_index;
+ unsigned num_operands = constant_expr->getNumOperands();
- if (StoreInst *store = dyn_cast<StoreInst>(&inst))
- if (isGuardVariableRef(store->getPointerOperand()))
- guard_stores.push_back(&inst);
- }
+ for (operand_index = 1; operand_index < num_operands;
+ ++operand_index) {
+ Value *operand = constant_expr->getOperand(operand_index);
- InstrIterator iter;
+ if (operand == old_constant)
+ operand = value_maker.GetValue(function);
- for (iter = guard_loads.begin();
- iter != guard_loads.end();
- ++iter)
- TurnGuardLoadIntoZero(*iter);
+ index_vector.push_back(operand);
+ }
- for (iter = guard_stores.begin();
- iter != guard_stores.end();
- ++iter)
- ExciseGuardStore(*iter);
+ ArrayRef<Value *> indices(index_vector);
- return true;
-}
+ return GetElementPtrInst::Create(
+ nullptr, ptr, indices, "",
+ llvm::cast<Instruction>(
+ entry_instruction_finder.GetValue(function)));
+ });
-// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::UnfoldConstant(Constant *old_constant,
- FunctionValueCache &value_maker,
- FunctionValueCache &entry_instruction_finder)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- SmallVector<User*, 16> users;
-
- // We do this because the use list might change, invalidating our iterator.
- // Much better to keep a work list ourselves.
- for (llvm::User *u : old_constant->users())
- users.push_back(u);
-
- for (size_t i = 0;
- i < users.size();
- ++i)
- {
- User *user = users[i];
-
- if (Constant *constant = dyn_cast<Constant>(user))
- {
- // synthesize a new non-constant equivalent of the constant
-
- if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
- {
- switch (constant_expr->getOpcode())
- {
- default:
- if (log)
- log->Printf("Unhandled constant expression type: \"%s\"", PrintValue(constant_expr).c_str());
- return false;
- case Instruction::BitCast:
- {
- FunctionValueCache bit_cast_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
- // UnaryExpr
- // OperandList[0] is value
-
- if (constant_expr->getOperand(0) != old_constant)
- return constant_expr;
-
- return new BitCastInst(value_maker.GetValue(function),
- constant_expr->getType(),
- "",
- llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
- });
-
- if (!UnfoldConstant(constant_expr, bit_cast_maker, entry_instruction_finder))
- return false;
- }
- break;
- case Instruction::GetElementPtr:
- {
- // GetElementPtrConstantExpr
- // OperandList[0] is base
- // OperandList[1]... are indices
-
- FunctionValueCache get_element_pointer_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
- Value *ptr = constant_expr->getOperand(0);
-
- if (ptr == old_constant)
- ptr = value_maker.GetValue(function);
-
- std::vector<Value*> index_vector;
-
- unsigned operand_index;
- unsigned num_operands = constant_expr->getNumOperands();
-
- for (operand_index = 1;
- operand_index < num_operands;
- ++operand_index)
- {
- Value *operand = constant_expr->getOperand(operand_index);
-
- if (operand == old_constant)
- operand = value_maker.GetValue(function);
-
- index_vector.push_back(operand);
- }
-
- ArrayRef <Value*> indices(index_vector);
-
- return GetElementPtrInst::Create(nullptr, ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
- });
-
- if (!UnfoldConstant(constant_expr, get_element_pointer_maker, entry_instruction_finder))
- return false;
- }
- break;
- }
- }
- else
- {
- if (log)
- log->Printf("Unhandled constant type: \"%s\"", PrintValue(constant).c_str());
- return false;
- }
+ if (!UnfoldConstant(constant_expr, llvm_function,
+ get_element_pointer_maker,
+ entry_instruction_finder, error_stream))
+ return false;
+ } break;
}
- else
- {
- if (Instruction *inst = llvm::dyn_cast<Instruction>(user))
- {
- inst->replaceUsesOfWith(old_constant, value_maker.GetValue(inst->getParent()->getParent()));
- }
- else
- {
- if (log)
- log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(user).c_str());
- return false;
- }
+ } else {
+ error_stream.Printf(
+ "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
+ PrintValue(constant).c_str());
+ return false;
+ }
+ } else {
+ if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
+ if (llvm_function && inst->getParent()->getParent() != llvm_function) {
+ error_stream.PutCString("error: Capturing non-local variables in "
+ "expressions is unsupported.\n");
+ return false;
}
+ inst->replaceUsesOfWith(
+ old_constant, value_maker.GetValue(inst->getParent()->getParent()));
+ } else {
+ error_stream.Printf(
+ "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
+ PrintValue(user).c_str());
+ return false;
+ }
}
+ }
- if (!isa<GlobalValue>(old_constant))
- {
- old_constant->destroyConstant();
- }
+ if (!isa<GlobalValue>(old_constant)) {
+ old_constant->destroyConstant();
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::ReplaceVariables (Function &llvm_function)
-{
- if (!m_resolve_vars)
- return true;
-
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::ReplaceVariables(Function &llvm_function) {
+ if (!m_resolve_vars)
+ return true;
- m_decl_map->DoStructLayout();
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Element arrangement:");
+ m_decl_map->DoStructLayout();
- uint32_t num_elements;
- uint32_t element_index;
+ if (log)
+ log->Printf("Element arrangement:");
- size_t size;
- lldb::offset_t alignment;
+ uint32_t num_elements;
+ uint32_t element_index;
- if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
- return false;
+ size_t size;
+ lldb::offset_t alignment;
- Function::arg_iterator iter(llvm_function.getArgumentList().begin());
+ if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
+ return false;
- if (iter == llvm_function.getArgumentList().end())
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes no arguments (should take at least a struct pointer)");
+ Function::arg_iterator iter(llvm_function.getArgumentList().begin());
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
+ "arguments (should take at least a struct pointer)");
- Argument *argument = &*iter;
+ return false;
+ }
- if (argument->getName().equals("this"))
- {
- ++iter;
+ Argument *argument = &*iter;
- if (iter == llvm_function.getArgumentList().end())
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'this' argument (should take a struct pointer too)");
+ if (argument->getName().equals("this")) {
+ ++iter;
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+ "'this' argument (should take a struct pointer "
+ "too)");
- argument = &*iter;
+ return false;
}
- else if (argument->getName().equals("self"))
- {
- ++iter;
- if (iter == llvm_function.getArgumentList().end())
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' argument (should take '_cmd' and a struct pointer too)");
+ argument = &*iter;
+ } else if (argument->getName().equals("self")) {
+ ++iter;
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+ "'self' argument (should take '_cmd' and a struct "
+ "pointer too)");
- if (!iter->getName().equals("_cmd"))
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes '%s' after 'self' argument (should take '_cmd')", iter->getName().str().c_str());
+ return false;
+ }
- return false;
- }
+ if (!iter->getName().equals("_cmd")) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
+ "after 'self' argument (should take '_cmd')",
+ iter->getName().str().c_str());
- ++iter;
+ return false;
+ }
- if (iter == llvm_function.getArgumentList().end())
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' and '_cmd' arguments (should take a struct pointer too)");
+ ++iter;
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+ "'self' and '_cmd' arguments (should take a struct "
+ "pointer too)");
- argument = &*iter;
+ return false;
}
- if (!argument->getName().equals("$__lldb_arg"))
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes an argument named '%s' instead of the struct pointer", argument->getName().str().c_str());
+ argument = &*iter;
+ }
- return false;
- }
+ if (!argument->getName().equals("$__lldb_arg")) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
+ "argument named '%s' instead of the struct pointer",
+ argument->getName().str().c_str());
- if (log)
- log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
+ return false;
+ }
- BasicBlock &entry_block(llvm_function.getEntryBlock());
- Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
+ if (log)
+ log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
- if (!FirstEntryInstruction)
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find the first instruction in the wrapper for use in rewriting");
+ BasicBlock &entry_block(llvm_function.getEntryBlock());
+ Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
- return false;
- }
+ if (!FirstEntryInstruction) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
+ "first instruction in the wrapper for use in "
+ "rewriting");
- LLVMContext &context(m_module->getContext());
- IntegerType *offset_type(Type::getInt32Ty(context));
+ return false;
+ }
- if (!offset_type)
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't produce an offset type");
+ LLVMContext &context(m_module->getContext());
+ IntegerType *offset_type(Type::getInt32Ty(context));
- return false;
- }
+ if (!offset_type) {
+ m_error_stream.Printf(
+ "Internal error [IRForTarget]: Couldn't produce an offset type");
- for (element_index = 0; element_index < num_elements; ++element_index)
- {
- const clang::NamedDecl *decl = NULL;
- Value *value = NULL;
- lldb::offset_t offset;
- lldb_private::ConstString name;
+ return false;
+ }
- if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index))
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Structure information is incomplete");
+ for (element_index = 0; element_index < num_elements; ++element_index) {
+ const clang::NamedDecl *decl = NULL;
+ Value *value = NULL;
+ lldb::offset_t offset;
+ lldb_private::ConstString name;
- return false;
- }
+ if (!m_decl_map->GetStructElement(decl, value, offset, name,
+ element_index)) {
+ m_error_stream.Printf(
+ "Internal error [IRForTarget]: Structure information is incomplete");
- if (log)
- log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64,
- name.GetCString(),
- decl->getNameAsString().c_str(),
- offset);
-
- if (value)
- {
- if (log)
- log->Printf(" Replacing [%s]", PrintValue(value).c_str());
-
- FunctionValueCache body_result_maker ([this, name, offset_type, offset, argument, value] (llvm::Function *function)->llvm::Value * {
- // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result
- // variable is an rvalue, we have to synthesize a dereference of the appropriate structure
- // entry in order to produce the static variable that the AST thinks it is accessing.
-
- llvm::Instruction *entry_instruction = llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function));
-
- ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true));
- GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(nullptr,
- argument,
- offset_int,
- "",
- entry_instruction);
-
- if (name == m_result_name && !m_result_is_pointer)
- {
- BitCastInst *bit_cast = new BitCastInst(get_element_ptr,
- value->getType()->getPointerTo(),
- "",
- entry_instruction);
-
- LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
-
- return load;
- }
- else
- {
- BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", entry_instruction);
-
- return bit_cast;
- }
- });
+ return false;
+ }
- if (Constant *constant = dyn_cast<Constant>(value))
- {
- UnfoldConstant(constant, body_result_maker, m_entry_instruction_finder);
- }
- else if (Instruction *instruction = dyn_cast<Instruction>(value))
- {
- value->replaceAllUsesWith(body_result_maker.GetValue(instruction->getParent()->getParent()));
- }
- else
- {
- if (log)
- log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(value).c_str());
- return false;
+ if (log)
+ log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(),
+ decl->getNameAsString().c_str(), offset);
+
+ if (value) {
+ if (log)
+ log->Printf(" Replacing [%s]", PrintValue(value).c_str());
+
+ FunctionValueCache body_result_maker(
+ [this, name, offset_type, offset, argument,
+ value](llvm::Function *function) -> llvm::Value * {
+ // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in
+ // cases where the result
+ // variable is an rvalue, we have to synthesize a dereference of the
+ // appropriate structure
+ // entry in order to produce the static variable that the AST thinks
+ // it is accessing.
+
+ llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
+ m_entry_instruction_finder.GetValue(function));
+
+ ConstantInt *offset_int(
+ ConstantInt::get(offset_type, offset, true));
+ GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
+ nullptr, argument, offset_int, "", entry_instruction);
+
+ if (name == m_result_name && !m_result_is_pointer) {
+ BitCastInst *bit_cast = new BitCastInst(
+ get_element_ptr, value->getType()->getPointerTo(), "",
+ entry_instruction);
+
+ LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
+
+ return load;
+ } else {
+ BitCastInst *bit_cast = new BitCastInst(
+ get_element_ptr, value->getType(), "", entry_instruction);
+
+ return bit_cast;
}
+ });
- if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
- var->eraseFromParent();
+ if (Constant *constant = dyn_cast<Constant>(value)) {
+ if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
+ m_entry_instruction_finder, m_error_stream)) {
+ return false;
}
+ } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
+ if (instruction->getParent()->getParent() != &llvm_function) {
+ m_error_stream.PutCString("error: Capturing non-local variables in "
+ "expressions is unsupported.\n");
+ return false;
+ }
+ value->replaceAllUsesWith(
+ body_result_maker.GetValue(instruction->getParent()->getParent()));
+ } else {
+ if (log)
+ log->Printf("Unhandled non-constant type: \"%s\"",
+ PrintValue(value).c_str());
+ return false;
+ }
+
+ if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
+ var->eraseFromParent();
}
+ }
- if (log)
- log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]", (int64_t)alignment, (uint64_t)size);
+ if (log)
+ log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
+ (int64_t)alignment, (uint64_t)size);
- return true;
+ return true;
}
-llvm::Constant *
-IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
-{
- llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
+llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
+ uint64_t offset) {
+ llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
- llvm::Constant *offset_array[1];
+ llvm::Constant *offset_array[1];
- offset_array[0] = offset_int;
+ offset_array[0] = offset_int;
- llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
- llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
- llvm::Type *char_pointer_type = char_type->getPointerTo();
+ llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
+ llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
+ llvm::Type *char_pointer_type = char_type->getPointerTo();
- llvm::Constant *reloc_placeholder_bitcast = ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
- llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(char_type, reloc_placeholder_bitcast, offsets);
- llvm::Constant *reloc_bitcast = ConstantExpr::getBitCast(reloc_getelementptr, type);
+ llvm::Constant *reloc_placeholder_bitcast =
+ ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
+ llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
+ char_type, reloc_placeholder_bitcast, offsets);
+ llvm::Constant *reloc_bitcast =
+ ConstantExpr::getBitCast(reloc_getelementptr, type);
- return reloc_bitcast;
+ return reloc_bitcast;
}
-bool
-IRForTarget::runOnModule (Module &llvm_module)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::runOnModule(Module &llvm_module) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- m_module = &llvm_module;
- m_target_data.reset(new DataLayout(m_module));
- m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(), m_target_data->getPointerSizeInBits());
+ m_module = &llvm_module;
+ m_target_data.reset(new DataLayout(m_module));
+ m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
+ m_target_data->getPointerSizeInBits());
- if (log)
- {
- std::string s;
- raw_string_ostream oss(s);
+ if (log) {
+ std::string s;
+ raw_string_ostream oss(s);
- m_module->print(oss, NULL);
+ m_module->print(oss, NULL);
- oss.flush();
+ oss.flush();
- log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
- }
+ log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
+ }
- Function *const main_function = m_func_name.IsEmpty() ? nullptr : m_module->getFunction(m_func_name.GetStringRef());
+ Function *const main_function =
+ m_func_name.IsEmpty() ? nullptr
+ : m_module->getFunction(m_func_name.GetStringRef());
- if (!m_func_name.IsEmpty() && !main_function)
- {
- if (log)
- log->Printf("Couldn't find \"%s()\" in the module", m_func_name.AsCString());
+ if (!m_func_name.IsEmpty() && !main_function) {
+ if (log)
+ log->Printf("Couldn't find \"%s()\" in the module",
+ m_func_name.AsCString());
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module",
- m_func_name.AsCString());
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
+ "'%s' in the module",
+ m_func_name.AsCString());
- return false;
- }
+ return false;
+ }
- if (main_function)
- {
- if (!FixFunctionLinkage(*main_function))
- {
- if (log)
- log->Printf("Couldn't fix the linkage for the function");
+ if (main_function) {
+ if (!FixFunctionLinkage(*main_function)) {
+ if (log)
+ log->Printf("Couldn't fix the linkage for the function");
- return false;
- }
+ return false;
}
+ }
- llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
+ llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
- m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
- int8_ty,
- false /* IsConstant */,
- GlobalVariable::InternalLinkage,
- Constant::getNullValue(int8_ty),
- "reloc_placeholder",
- NULL /* InsertBefore */,
- GlobalVariable::NotThreadLocal /* ThreadLocal */,
- 0 /* AddressSpace */);
+ m_reloc_placeholder = new llvm::GlobalVariable(
+ (*m_module), int8_ty, false /* IsConstant */,
+ GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
+ "reloc_placeholder", NULL /* InsertBefore */,
+ GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
- ////////////////////////////////////////////////////////////
- // Replace $__lldb_expr_result with a persistent variable
- //
+ ////////////////////////////////////////////////////////////
+ // Replace $__lldb_expr_result with a persistent variable
+ //
- if (main_function)
- {
- if (!CreateResultVariable(*main_function))
- {
- if (log)
- log->Printf("CreateResultVariable() failed");
+ if (main_function) {
+ if (!CreateResultVariable(*main_function)) {
+ if (log)
+ log->Printf("CreateResultVariable() failed");
- // CreateResultVariable() reports its own errors, so we don't do so here
+ // CreateResultVariable() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
}
+ }
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream oss(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream oss(s);
- m_module->print(oss, NULL);
+ m_module->print(oss, NULL);
- oss.flush();
+ oss.flush();
- log->Printf("Module after creating the result variable: \n\"%s\"", s.c_str());
- }
+ log->Printf("Module after creating the result variable: \n\"%s\"",
+ s.c_str());
+ }
- for (Module::iterator fi = m_module->begin(), fe = m_module->end();
- fi != fe;
- ++fi)
- {
- llvm::Function *function = &*fi;
+ for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+ ++fi) {
+ llvm::Function *function = &*fi;
- if (function->begin() == function->end())
- continue;
+ if (function->begin() == function->end())
+ continue;
- Function::iterator bbi;
+ Function::iterator bbi;
- for (bbi = function->begin();
- bbi != function->end();
- ++bbi)
- {
- if (!RemoveGuards(*bbi))
- {
- if (log)
- log->Printf("RemoveGuards() failed");
+ for (bbi = function->begin(); bbi != function->end(); ++bbi) {
+ if (!RemoveGuards(*bbi)) {
+ if (log)
+ log->Printf("RemoveGuards() failed");
- // RemoveGuards() reports its own errors, so we don't do so here
+ // RemoveGuards() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
+ }
- if (!RewritePersistentAllocs(*bbi))
- {
- if (log)
- log->Printf("RewritePersistentAllocs() failed");
+ if (!RewritePersistentAllocs(*bbi)) {
+ if (log)
+ log->Printf("RewritePersistentAllocs() failed");
- // RewritePersistentAllocs() reports its own errors, so we don't do so here
+ // RewritePersistentAllocs() reports its own errors, so we don't do so
+ // here
- return false;
- }
+ return false;
+ }
- if (!RemoveCXAAtExit(*bbi))
- {
- if (log)
- log->Printf("RemoveCXAAtExit() failed");
+ if (!RemoveCXAAtExit(*bbi)) {
+ if (log)
+ log->Printf("RemoveCXAAtExit() failed");
- // RemoveCXAAtExit() reports its own errors, so we don't do so here
+ // RemoveCXAAtExit() reports its own errors, so we don't do so here
- return false;
- }
- }
+ return false;
+ }
}
+ }
- ///////////////////////////////////////////////////////////////////////////////
- // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
- //
+ ///////////////////////////////////////////////////////////////////////////////
+ // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
+ //
- if (!RewriteObjCConstStrings())
- {
+ if (!RewriteObjCConstStrings()) {
+ if (log)
+ log->Printf("RewriteObjCConstStrings() failed");
+
+ // RewriteObjCConstStrings() reports its own errors, so we don't do so here
+
+ return false;
+ }
+
+ for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+ ++fi) {
+ llvm::Function *function = &*fi;
+
+ for (llvm::Function::iterator bbi = function->begin(),
+ bbe = function->end();
+ bbi != bbe; ++bbi) {
+ if (!RewriteObjCSelectors(*bbi)) {
if (log)
- log->Printf("RewriteObjCConstStrings() failed");
+ log->Printf("RewriteObjCSelectors() failed");
- // RewriteObjCConstStrings() reports its own errors, so we don't do so here
+ // RewriteObjCSelectors() reports its own errors, so we don't do so here
return false;
- }
+ }
- for (Module::iterator fi = m_module->begin(), fe = m_module->end();
- fi != fe;
- ++fi)
- {
- llvm::Function *function = &*fi;
-
- for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
- bbi != bbe;
- ++bbi)
- {
- if (!RewriteObjCSelectors(*bbi))
- {
- if (log)
- log->Printf("RewriteObjCSelectors() failed");
+ if (!RewriteObjCClassReferences(*bbi)) {
+ if (log)
+ log->Printf("RewriteObjCClassReferences() failed");
- // RewriteObjCSelectors() reports its own errors, so we don't do so here
+ // RewriteObjCClasses() reports its own errors, so we don't do so here
- return false;
- }
- }
+ return false;
+ }
}
+ }
- for (Module::iterator fi = m_module->begin(), fe = m_module->end();
- fi != fe;
- ++fi)
- {
- llvm::Function *function = &*fi;
+ for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+ ++fi) {
+ llvm::Function *function = &*fi;
- for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
- bbi != bbe;
- ++bbi)
- {
- if (!ResolveCalls(*bbi))
- {
- if (log)
- log->Printf("ResolveCalls() failed");
+ for (llvm::Function::iterator bbi = function->begin(),
+ bbe = function->end();
+ bbi != bbe; ++bbi) {
+ if (!ResolveCalls(*bbi)) {
+ if (log)
+ log->Printf("ResolveCalls() failed");
- // ResolveCalls() reports its own errors, so we don't do so here
+ // ResolveCalls() reports its own errors, so we don't do so here
- return false;
- }
- }
+ return false;
+ }
}
+ }
- ////////////////////////////////////////////////////////////////////////
- // Run function-level passes that only make sense on the main function
- //
+ ////////////////////////////////////////////////////////////////////////
+ // Run function-level passes that only make sense on the main function
+ //
- if (main_function)
- {
- if (!ResolveExternals(*main_function))
- {
- if (log)
- log->Printf("ResolveExternals() failed");
+ if (main_function) {
+ if (!ResolveExternals(*main_function)) {
+ if (log)
+ log->Printf("ResolveExternals() failed");
- // ResolveExternals() reports its own errors, so we don't do so here
+ // ResolveExternals() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
+ }
- if (!ReplaceVariables(*main_function))
- {
- if (log)
- log->Printf("ReplaceVariables() failed");
+ if (!ReplaceVariables(*main_function)) {
+ if (log)
+ log->Printf("ReplaceVariables() failed");
- // ReplaceVariables() reports its own errors, so we don't do so here
+ // ReplaceVariables() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
}
+ }
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream oss(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream oss(s);
- m_module->print(oss, NULL);
+ m_module->print(oss, NULL);
- oss.flush();
+ oss.flush();
- log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
- }
+ log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
+ }
- return true;
+ return true;
}
-void
-IRForTarget::assignPassManager (PMStack &pass_mgr_stack, PassManagerType pass_mgr_type)
-{
-}
+void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
+ PassManagerType pass_mgr_type) {}
-PassManagerType
-IRForTarget::getPotentialPassManagerType() const
-{
- return PMT_ModulePassManager;
+PassManagerType IRForTarget::getPotentialPassManagerType() const {
+ return PMT_ModulePassManager;
}
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index 0f95f67babfd..20b1d1a13226 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -1,4 +1,5 @@
-//===-- IRForTarget.h ---------------------------------------------*- C++ -*-===//
+//===-- IRForTarget.h ---------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,38 +11,38 @@
#ifndef liblldb_IRForTarget_h_
#define liblldb_IRForTarget_h_
-#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/lldb-public.h"
#include "llvm/Pass.h"
-#include <map>
#include <functional>
+#include <map>
namespace llvm {
- class BasicBlock;
- class CallInst;
- class Constant;
- class ConstantInt;
- class Function;
- class GlobalValue;
- class GlobalVariable;
- class Instruction;
- class IntegerType;
- class Module;
- class StoreInst;
- class DataLayout;
- class Type;
- class Value;
+class BasicBlock;
+class CallInst;
+class Constant;
+class ConstantInt;
+class Function;
+class GlobalValue;
+class GlobalVariable;
+class Instruction;
+class IntegerType;
+class Module;
+class StoreInst;
+class DataLayout;
+class Type;
+class Value;
}
namespace lldb_private {
- class ClangExpressionDeclMap;
- class IRExecutionUnit;
- class IRMemoryMap;
+class ClangExpressionDeclMap;
+class IRExecutionUnit;
+class IRMemoryMap;
}
//----------------------------------------------------------------------
@@ -58,594 +59,610 @@ namespace lldb_private {
/// transformations are discussed in more detail next to their relevant
/// functions.
//----------------------------------------------------------------------
-class IRForTarget : public llvm::ModulePass
-{
+class IRForTarget : public llvm::ModulePass {
public:
- enum class LookupResult {
- Success,
- Fail,
- Ignore
- };
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] decl_map
- /// The list of externally-referenced variables for the expression,
- /// for use in looking up globals and allocating the argument
- /// struct. See the documentation for ClangExpressionDeclMap.
- ///
- /// @param[in] resolve_vars
- /// True if the external variable references (including persistent
- /// variables) should be resolved. If not, only external functions
- /// are resolved.
- ///
- /// @param[in] execution_policy
- /// Determines whether an IR interpreter can be used to statically
- /// evaluate the expression.
- ///
- /// @param[in] const_result
- /// This variable is populated with the statically-computed result
- /// of the function, if it has no side-effects and the result can
- /// be computed statically.
- ///
- /// @param[in] execution_unit
- /// The holder for raw data associated with the expression.
- ///
- /// @param[in] error_stream
- /// If non-NULL, a stream on which errors can be printed.
- ///
- /// @param[in] func_name
- /// The name of the function to prepare for execution in the target.
- //------------------------------------------------------------------
- IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
- bool resolve_vars,
- lldb_private::IRExecutionUnit &execution_unit,
- lldb_private::Stream *error_stream,
- const char* func_name = "$__lldb_expr");
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~IRForTarget() override;
-
- //------------------------------------------------------------------
- /// Run this IR transformer on a single module
- ///
- /// Implementation of the llvm::ModulePass::runOnModule() function.
- ///
- /// @param[in] llvm_module
- /// The module to run on. This module is searched for the function
- /// $__lldb_expr, and that function is passed to the passes one by
- /// one.
- ///
- /// @param[in] interpreter_error
- /// An error. If the expression fails to be interpreted, this error
- /// is set to a reason why.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- runOnModule(llvm::Module &llvm_module) override;
-
- //------------------------------------------------------------------
- /// Interface stub
- ///
- /// Implementation of the llvm::ModulePass::assignPassManager()
- /// function.
- //------------------------------------------------------------------
- void
- assignPassManager(llvm::PMStack &pass_mgr_stack,
- llvm::PassManagerType pass_mgr_type = llvm::PMT_ModulePassManager) override;
-
- //------------------------------------------------------------------
- /// Returns PMT_ModulePassManager
- ///
- /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
- /// function.
- //------------------------------------------------------------------
- llvm::PassManagerType
- getPotentialPassManagerType() const override;
+ enum class LookupResult { Success, Fail, Ignore };
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] decl_map
+ /// The list of externally-referenced variables for the expression,
+ /// for use in looking up globals and allocating the argument
+ /// struct. See the documentation for ClangExpressionDeclMap.
+ ///
+ /// @param[in] resolve_vars
+ /// True if the external variable references (including persistent
+ /// variables) should be resolved. If not, only external functions
+ /// are resolved.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether an IR interpreter can be used to statically
+ /// evaluate the expression.
+ ///
+ /// @param[in] const_result
+ /// This variable is populated with the statically-computed result
+ /// of the function, if it has no side-effects and the result can
+ /// be computed statically.
+ ///
+ /// @param[in] execution_unit
+ /// The holder for raw data associated with the expression.
+ ///
+ /// @param[in] error_stream
+ /// If non-NULL, a stream on which errors can be printed.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to prepare for execution in the target.
+ //------------------------------------------------------------------
+ IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, bool resolve_vars,
+ lldb_private::IRExecutionUnit &execution_unit,
+ lldb_private::Stream &error_stream,
+ const char *func_name = "$__lldb_expr");
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~IRForTarget() override;
+
+ //------------------------------------------------------------------
+ /// Run this IR transformer on a single module
+ ///
+ /// Implementation of the llvm::ModulePass::runOnModule() function.
+ ///
+ /// @param[in] llvm_module
+ /// The module to run on. This module is searched for the function
+ /// $__lldb_expr, and that function is passed to the passes one by
+ /// one.
+ ///
+ /// @param[in] interpreter_error
+ /// An error. If the expression fails to be interpreted, this error
+ /// is set to a reason why.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool runOnModule(llvm::Module &llvm_module) override;
+
+ //------------------------------------------------------------------
+ /// Interface stub
+ ///
+ /// Implementation of the llvm::ModulePass::assignPassManager()
+ /// function.
+ //------------------------------------------------------------------
+ void assignPassManager(llvm::PMStack &pass_mgr_stack,
+ llvm::PassManagerType pass_mgr_type =
+ llvm::PMT_ModulePassManager) override;
+
+ //------------------------------------------------------------------
+ /// Returns PMT_ModulePassManager
+ ///
+ /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
+ /// function.
+ //------------------------------------------------------------------
+ llvm::PassManagerType getPotentialPassManagerType() const override;
private:
- //------------------------------------------------------------------
- /// Ensures that the current function's linkage is set to external.
- /// Otherwise the JIT may not return an address for it.
- ///
- /// @param[in] llvm_function
- /// The function whose linkage is to be fixed.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- FixFunctionLinkage (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A module-level pass to replace all function pointers with their
- /// integer equivalents.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_module
- /// The module currently being processed.
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- HasSideEffects (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A function-level pass to check whether the function has side
- /// effects.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Get the address of a function, and a location to put the complete
- /// Value of the function if one is available.
- ///
- /// @param[in] function
- /// The function to find the location of.
- ///
- /// @param[out] ptr
- /// The location of the function in the target.
- ///
- /// @param[out] name
- /// The resolved name of the function (matters for intrinsics).
- ///
- /// @param[out] value_ptr
- /// A variable to put the function's completed Value* in, or NULL
- /// if the Value* shouldn't be stored anywhere.
- ///
- /// @return
- /// The pointer.
- //------------------------------------------------------------------
- LookupResult
- GetFunctionAddress (llvm::Function *function,
- uint64_t &ptr,
- lldb_private::ConstString &name,
- llvm::Constant **&value_ptr);
-
- //------------------------------------------------------------------
- /// A function-level pass to take the generated global value
- /// $__lldb_expr_result and make it into a persistent variable.
- /// Also see ASTResultSynthesizer.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Find the NamedDecl corresponding to a Value. This interface is
- /// exposed for the IR interpreter.
- ///
- /// @param[in] module
- /// The module containing metadata to search
- ///
- /// @param[in] global
- /// The global entity to search for
- ///
- /// @return
- /// The corresponding variable declaration
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Ensures that the current function's linkage is set to external.
+ /// Otherwise the JIT may not return an address for it.
+ ///
+ /// @param[in] llvm_function
+ /// The function whose linkage is to be fixed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool FixFunctionLinkage(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to replace all function pointers with their
+ /// integer equivalents.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_module
+ /// The module currently being processed.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool HasSideEffects(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to check whether the function has side
+ /// effects.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Get the address of a function, and a location to put the complete
+ /// Value of the function if one is available.
+ ///
+ /// @param[in] function
+ /// The function to find the location of.
+ ///
+ /// @param[out] ptr
+ /// The location of the function in the target.
+ ///
+ /// @param[out] name
+ /// The resolved name of the function (matters for intrinsics).
+ ///
+ /// @param[out] value_ptr
+ /// A variable to put the function's completed Value* in, or NULL
+ /// if the Value* shouldn't be stored anywhere.
+ ///
+ /// @return
+ /// The pointer.
+ //------------------------------------------------------------------
+ LookupResult GetFunctionAddress(llvm::Function *function, uint64_t &ptr,
+ lldb_private::ConstString &name,
+ llvm::Constant **&value_ptr);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to take the generated global value
+ /// $__lldb_expr_result and make it into a persistent variable.
+ /// Also see ASTResultSynthesizer.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Find the NamedDecl corresponding to a Value. This interface is
+ /// exposed for the IR interpreter.
+ ///
+ /// @param[in] module
+ /// The module containing metadata to search
+ ///
+ /// @param[in] global
+ /// The global entity to search for
+ ///
+ /// @return
+ /// The corresponding variable declaration
+ //------------------------------------------------------------------
public:
- static clang::NamedDecl *
- DeclForGlobal (const llvm::GlobalValue *global_val, llvm::Module *module);
+ static clang::NamedDecl *DeclForGlobal(const llvm::GlobalValue *global_val,
+ llvm::Module *module);
+
private:
- clang::NamedDecl *
- DeclForGlobal (llvm::GlobalValue *global);
-
- //------------------------------------------------------------------
- /// Set the constant result variable m_const_result to the provided
- /// constant, assuming it can be evaluated. The result variable
- /// will be reset to NULL later if the expression has side effects.
- ///
- /// @param[in] initializer
- /// The constant initializer for the variable.
- ///
- /// @param[in] name
- /// The name of the result variable.
- ///
- /// @param[in] type
- /// The Clang type of the result variable.
- //------------------------------------------------------------------
- void
- MaybeSetConstantResult (llvm::Constant *initializer,
- const lldb_private::ConstString &name,
- lldb_private::TypeFromParser type);
-
- //------------------------------------------------------------------
- /// If the IR represents a cast of a variable, set m_const_result
- /// to the result of the cast. The result variable will be reset to
- /// NULL latger if the expression has side effects.
- ///
- /// @param[in] type
- /// The Clang type of the result variable.
- //------------------------------------------------------------------
- void
- MaybeSetCastResult (lldb_private::TypeFromParser type);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- CreateResultVariable (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A module-level pass to find Objective-C constant strings and
- /// transform them to calls to CFStringCreateWithBytes.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Rewrite a single Objective-C constant string.
- ///
- /// @param[in] NSStr
- /// The constant NSString to be transformed
- ///
- /// @param[in] CStr
- /// The constant C string inside the NSString. This will be
- /// passed as the bytes argument to CFStringCreateWithBytes.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCConstString (llvm::GlobalVariable *NSStr,
- llvm::GlobalVariable *CStr);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCConstStrings ();
-
- //------------------------------------------------------------------
- /// A basic block-level pass to find all Objective-C method calls and
- /// rewrite them to use sel_registerName instead of statically allocated
- /// selectors. The reason is that the selectors are created on the
- /// assumption that the Objective-C runtime will scan the appropriate
- /// section and prepare them. This doesn't happen when code is copied
- /// into the target, though, and there's no easy way to induce the
- /// runtime to scan them. So instead we get our selectors from
- /// sel_registerName.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Replace a single selector reference
- ///
- /// @param[in] selector_load
- /// The load of the statically-allocated selector.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCSelector (llvm::Instruction* selector_load);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCSelectors (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// A basic block-level pass to find all newly-declared persistent
- /// variables and register them with the ClangExprDeclMap. This
- /// allows them to be materialized and dematerialized like normal
- /// external variables. Before transformation, these persistent
- /// variables look like normal locals, so they have an allocation.
- /// This pass excises these allocations and makes references look
- /// like external references where they will be resolved -- like all
- /// other external references -- by ResolveExternals().
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Handle a single allocation of a persistent variable
- ///
- /// @param[in] persistent_alloc
- /// The allocation of the persistent variable.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewritePersistentAlloc (llvm::Instruction *persistent_alloc);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- //------------------------------------------------------------------
- bool
- RewritePersistentAllocs (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// A function-level pass to find all external variables and functions
- /// used in the IR. Each found external variable is added to the
- /// struct, and each external function is resolved in place, its call
- /// replaced with a call to a function pointer whose value is the
- /// address of the function in the target process.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Write an initializer to a memory array of assumed sufficient
- /// size.
- ///
- /// @param[in] data
- /// A pointer to the data to write to.
- ///
- /// @param[in] initializer
- /// The initializer itself.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaterializeInitializer (uint8_t *data, llvm::Constant *initializer);
-
- //------------------------------------------------------------------
- /// Move an internal variable into the static allocation section.
- ///
- /// @param[in] global_variable
- /// The variable.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaterializeInternalVariable (llvm::GlobalVariable *global_variable);
-
- //------------------------------------------------------------------
- /// Handle a single externally-defined variable
- ///
- /// @param[in] value
- /// The variable.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaybeHandleVariable (llvm::Value *value);
-
- //------------------------------------------------------------------
- /// Handle a single externally-defined symbol
- ///
- /// @param[in] symbol
- /// The symbol.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- HandleSymbol (llvm::Value *symbol);
-
- //------------------------------------------------------------------
- /// Handle a single externally-defined Objective-C class
- ///
- /// @param[in] classlist_reference
- /// The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
- /// where n (if present) is an index.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- HandleObjCClass(llvm::Value *classlist_reference);
-
- //------------------------------------------------------------------
- /// Handle all the arguments to a function call
- ///
- /// @param[in] C
- /// The call instruction.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaybeHandleCallArguments (llvm::CallInst *call_inst);
-
- //------------------------------------------------------------------
- /// Resolve variable references in calls to external functions
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ResolveCalls (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// Remove calls to __cxa_atexit, which should never be generated by
- /// expressions.
- ///
- /// @param[in] call_inst
- /// The call instruction.
- ///
- /// @return
- /// True if the scan was successful; false if some operation
- /// failed
- //------------------------------------------------------------------
- bool
- RemoveCXAAtExit (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ResolveExternals (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A basic block-level pass to excise guard variables from the code.
- /// The result for the function is passed through Clang as a static
- /// variable. Static variables normally have guard variables to
- /// ensure that they are only initialized once.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Rewrite a load to a guard variable to return constant 0.
- ///
- /// @param[in] guard_load
- /// The load instruction to zero out.
- //------------------------------------------------------------------
- void
- TurnGuardLoadIntoZero(llvm::Instruction* guard_load);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RemoveGuards (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// A function-level pass to make all external variable references
- /// point at the correct offsets from the void* passed into the
- /// function. ClangExpressionDeclMap::DoStructLayout() must be called
- /// beforehand, so that the offsets are valid.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ReplaceVariables(llvm::Function &llvm_function);
-
- /// Flags
- bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
- lldb_private::ConstString m_func_name; ///< The name of the function to translate
- lldb_private::ConstString m_result_name; ///< The name of the result variable ($0, $1, ...)
- lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
- llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
- std::unique_ptr<llvm::DataLayout>
- m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
- lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
- llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the
- ///appropriate function pointer type
- llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate
- ///function pointer type
- llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
- lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed
- lldb_private::IRExecutionUnit &m_execution_unit; ///< The execution unit containing the IR being created.
-
- llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If
- ///m_has_side_effects is true, this is NULL.
- bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in
- ///ASTResultSynthesizer::SynthesizeBodyResult)
-
- llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be replaced by a pointer to the final
- ///location of the static allocation.
-
- //------------------------------------------------------------------
- /// UnfoldConstant operates on a constant [Old] which has just been
- /// replaced with a value [New]. We assume that new_value has
- /// been properly placed early in the function, in front of the
- /// first instruction in the entry basic block
- /// [FirstEntryInstruction].
- ///
- /// UnfoldConstant reads through the uses of Old and replaces Old
- /// in those uses with New. Where those uses are constants, the
- /// function generates new instructions to compute the result of the
- /// new, non-constant expression and places them before
- /// FirstEntryInstruction. These instructions replace the constant
- /// uses, so UnfoldConstant calls itself recursively for those.
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
-
- class FunctionValueCache {
- public:
- typedef std::function <llvm::Value *(llvm::Function *)> Maker;
-
- FunctionValueCache (Maker const &maker);
- ~FunctionValueCache ();
- llvm::Value *GetValue (llvm::Function *function);
- private:
- Maker const m_maker;
- typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
- FunctionValueMap m_values;
- };
-
- FunctionValueCache m_entry_instruction_finder;
-
- static bool
- UnfoldConstant (llvm::Constant *old_constant,
- FunctionValueCache &value_maker,
- FunctionValueCache &entry_instruction_finder);
-
- //------------------------------------------------------------------
- /// Construct a reference to m_reloc_placeholder with a given type
- /// and offset. This typically happens after inserting data into
- /// m_data_allocator.
- ///
- /// @param[in] type
- /// The type of the value being loaded.
- ///
- /// @param[in] offset
- /// The offset of the value from the base of m_data_allocator.
- ///
- /// @return
- /// The Constant for the reference, usually a ConstantExpr.
- //------------------------------------------------------------------
- llvm::Constant *
- BuildRelocation(llvm::Type *type,
- uint64_t offset);
-
- //------------------------------------------------------------------
- /// Commit the allocation in m_data_allocator and use its final
- /// location to replace m_reloc_placeholder.
- ///
- /// @param[in] module
- /// The module that m_data_allocator resides in
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- CompleteDataAllocation ();
+ clang::NamedDecl *DeclForGlobal(llvm::GlobalValue *global);
+
+ //------------------------------------------------------------------
+ /// Set the constant result variable m_const_result to the provided
+ /// constant, assuming it can be evaluated. The result variable
+ /// will be reset to NULL later if the expression has side effects.
+ ///
+ /// @param[in] initializer
+ /// The constant initializer for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the result variable.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void MaybeSetConstantResult(llvm::Constant *initializer,
+ const lldb_private::ConstString &name,
+ lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// If the IR represents a cast of a variable, set m_const_result
+ /// to the result of the cast. The result variable will be reset to
+ /// NULL latger if the expression has side effects.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void MaybeSetCastResult(lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool CreateResultVariable(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to find Objective-C constant strings and
+ /// transform them to calls to CFStringCreateWithBytes.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a single Objective-C constant string.
+ ///
+ /// @param[in] NSStr
+ /// The constant NSString to be transformed
+ ///
+ /// @param[in] CStr
+ /// The constant C string inside the NSString. This will be
+ /// passed as the bytes argument to CFStringCreateWithBytes.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCConstString(llvm::GlobalVariable *NSStr,
+ llvm::GlobalVariable *CStr);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCConstStrings();
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all Objective-C method calls and
+ /// rewrite them to use sel_registerName instead of statically allocated
+ /// selectors. The reason is that the selectors are created on the
+ /// assumption that the Objective-C runtime will scan the appropriate
+ /// section and prepare them. This doesn't happen when code is copied
+ /// into the target, though, and there's no easy way to induce the
+ /// runtime to scan them. So instead we get our selectors from
+ /// sel_registerName.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Replace a single selector reference
+ ///
+ /// @param[in] selector_load
+ /// The load of the statically-allocated selector.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCSelector(llvm::Instruction *selector_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCSelectors(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all Objective-C class references that
+ /// use the old-style Objective-C runtime and rewrite them to use
+ /// class_getClass instead of statically allocated class references.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Replace a single old-style class reference
+ ///
+ /// @param[in] selector_load
+ /// The load of the statically-allocated selector.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCClassReference(llvm::Instruction *class_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCClassReferences(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all newly-declared persistent
+ /// variables and register them with the ClangExprDeclMap. This
+ /// allows them to be materialized and dematerialized like normal
+ /// external variables. Before transformation, these persistent
+ /// variables look like normal locals, so they have an allocation.
+ /// This pass excises these allocations and makes references look
+ /// like external references where they will be resolved -- like all
+ /// other external references -- by ResolveExternals().
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Handle a single allocation of a persistent variable
+ ///
+ /// @param[in] persistent_alloc
+ /// The allocation of the persistent variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ //------------------------------------------------------------------
+ bool RewritePersistentAllocs(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to find all external variables and functions
+ /// used in the IR. Each found external variable is added to the
+ /// struct, and each external function is resolved in place, its call
+ /// replaced with a call to a function pointer whose value is the
+ /// address of the function in the target process.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Write an initializer to a memory array of assumed sufficient
+ /// size.
+ ///
+ /// @param[in] data
+ /// A pointer to the data to write to.
+ ///
+ /// @param[in] initializer
+ /// The initializer itself.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaterializeInitializer(uint8_t *data, llvm::Constant *initializer);
+
+ //------------------------------------------------------------------
+ /// Move an internal variable into the static allocation section.
+ ///
+ /// @param[in] global_variable
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaterializeInternalVariable(llvm::GlobalVariable *global_variable);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined variable
+ ///
+ /// @param[in] value
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaybeHandleVariable(llvm::Value *value);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined symbol
+ ///
+ /// @param[in] symbol
+ /// The symbol.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool HandleSymbol(llvm::Value *symbol);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined Objective-C class
+ ///
+ /// @param[in] classlist_reference
+ /// The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
+ /// where n (if present) is an index.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool HandleObjCClass(llvm::Value *classlist_reference);
+
+ //------------------------------------------------------------------
+ /// Handle all the arguments to a function call
+ ///
+ /// @param[in] C
+ /// The call instruction.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaybeHandleCallArguments(llvm::CallInst *call_inst);
+
+ //------------------------------------------------------------------
+ /// Resolve variable references in calls to external functions
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool ResolveCalls(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// Remove calls to __cxa_atexit, which should never be generated by
+ /// expressions.
+ ///
+ /// @param[in] call_inst
+ /// The call instruction.
+ ///
+ /// @return
+ /// True if the scan was successful; false if some operation
+ /// failed
+ //------------------------------------------------------------------
+ bool RemoveCXAAtExit(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool ResolveExternals(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to excise guard variables from the code.
+ /// The result for the function is passed through Clang as a static
+ /// variable. Static variables normally have guard variables to
+ /// ensure that they are only initialized once.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a load to a guard variable to return constant 0.
+ ///
+ /// @param[in] guard_load
+ /// The load instruction to zero out.
+ //------------------------------------------------------------------
+ void TurnGuardLoadIntoZero(llvm::Instruction *guard_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RemoveGuards(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to make all external variable references
+ /// point at the correct offsets from the void* passed into the
+ /// function. ClangExpressionDeclMap::DoStructLayout() must be called
+ /// beforehand, so that the offsets are valid.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool ReplaceVariables(llvm::Function &llvm_function);
+
+ /// Flags
+ bool m_resolve_vars; ///< True if external variable references and persistent
+ ///variable references should be resolved
+ lldb_private::ConstString
+ m_func_name; ///< The name of the function to translate
+ lldb_private::ConstString
+ m_result_name; ///< The name of the result variable ($0, $1, ...)
+ lldb_private::TypeFromParser
+ m_result_type; ///< The type of the result variable.
+ llvm::Module *m_module; ///< The module being processed, or NULL if that has
+ ///not been determined yet.
+ std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the
+ ///module being processed, or
+ ///NULL if there is no
+ ///module.
+ lldb_private::ClangExpressionDeclMap
+ *m_decl_map; ///< The DeclMap containing the Decls
+ llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function
+ ///CFStringCreateWithBytes, cast to
+ ///the
+ /// appropriate function pointer type
+ llvm::Constant *m_sel_registerName; ///< The address of the function
+ ///sel_registerName, cast to the
+ ///appropriate
+ /// function pointer type
+ llvm::Constant *m_objc_getClass; ///< The address of the function
+ ///objc_getClass, cast to the
+ ///appropriate
+ /// function pointer type
+ llvm::IntegerType
+ *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
+ lldb_private::Stream
+ &m_error_stream; ///< The stream on which errors should be printed
+ lldb_private::IRExecutionUnit &
+ m_execution_unit; ///< The execution unit containing the IR being created.
+
+ llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that
+ ///writes to the result variable. If
+ /// m_has_side_effects is true, this is NULL.
+ bool m_result_is_pointer; ///< True if the function's result in the AST is a
+ ///pointer (see comments in
+ /// ASTResultSynthesizer::SynthesizeBodyResult)
+
+ llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be
+ ///replaced by a pointer to the
+ ///final
+ /// location of the static allocation.
+
+ //------------------------------------------------------------------
+ /// UnfoldConstant operates on a constant [Old] which has just been
+ /// replaced with a value [New]. We assume that new_value has
+ /// been properly placed early in the function, in front of the
+ /// first instruction in the entry basic block
+ /// [FirstEntryInstruction].
+ ///
+ /// UnfoldConstant reads through the uses of Old and replaces Old
+ /// in those uses with New. Where those uses are constants, the
+ /// function generates new instructions to compute the result of the
+ /// new, non-constant expression and places them before
+ /// FirstEntryInstruction. These instructions replace the constant
+ /// uses, so UnfoldConstant calls itself recursively for those.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+
+ class FunctionValueCache {
+ public:
+ typedef std::function<llvm::Value *(llvm::Function *)> Maker;
+
+ FunctionValueCache(Maker const &maker);
+ ~FunctionValueCache();
+ llvm::Value *GetValue(llvm::Function *function);
+
+ private:
+ Maker const m_maker;
+ typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
+ FunctionValueMap m_values;
+ };
+
+ FunctionValueCache m_entry_instruction_finder;
+
+ static bool UnfoldConstant(llvm::Constant *old_constant,
+ llvm::Function *llvm_function,
+ FunctionValueCache &value_maker,
+ FunctionValueCache &entry_instruction_finder,
+ lldb_private::Stream &error_stream);
+
+ //------------------------------------------------------------------
+ /// Construct a reference to m_reloc_placeholder with a given type
+ /// and offset. This typically happens after inserting data into
+ /// m_data_allocator.
+ ///
+ /// @param[in] type
+ /// The type of the value being loaded.
+ ///
+ /// @param[in] offset
+ /// The offset of the value from the base of m_data_allocator.
+ ///
+ /// @return
+ /// The Constant for the reference, usually a ConstantExpr.
+ //------------------------------------------------------------------
+ llvm::Constant *BuildRelocation(llvm::Type *type, uint64_t offset);
+ //------------------------------------------------------------------
+ /// Commit the allocation in m_data_allocator and use its final
+ /// location to replace m_reloc_placeholder.
+ ///
+ /// @param[in] module
+ /// The module that m_data_allocator resides in
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool CompleteDataAllocation();
};
#endif // liblldb_IRForTarget_h_
diff --git a/source/Plugins/ExpressionParser/Go/GoAST.h b/source/Plugins/ExpressionParser/Go/GoAST.h
index 89836a38acb0..d24e6c548718 100644
--- a/source/Plugins/ExpressionParser/Go/GoAST.h
+++ b/source/Plugins/ExpressionParser/Go/GoAST.h
@@ -13,3214 +13,1965 @@
#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"
-#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
- {
- 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;
- }
+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;
+};
- virtual const char *GetKindName() const = 0;
+class GoASTDecl : public GoASTNode {
+public:
+ template <typename R, typename V> R Visit(V *v) const;
- template <typename V> void WalkChildren(V &v);
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eBadDecl && n->GetKind() <= eGenDecl;
+ }
- protected:
- explicit GoASTNode(NodeKind kind) : m_kind(kind) { }
+protected:
+ explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) {}
- private:
- const NodeKind m_kind;
-
- GoASTNode(const GoASTNode &) = delete;
- const GoASTNode &operator=(const GoASTNode &) = delete;
+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;
-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;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eArrayType && n->GetKind() <= eUnaryExpr;
+ }
- protected:
- explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) { }
- private:
+protected:
+ explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) {}
- GoASTDecl(const GoASTDecl &) = delete;
- const GoASTDecl &operator=(const GoASTDecl &) = delete;
+private:
+ GoASTExpr(const GoASTExpr &) = delete;
+ const GoASTExpr &operator=(const GoASTExpr &) = delete;
};
-class GoASTExpr : public GoASTNode
-{
- public:
- template <typename R, typename V> R Visit(V *v) const;
+class GoASTSpec : 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;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eImportSpec && n->GetKind() <= eValueSpec;
+ }
- protected:
- explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) { }
- private:
+protected:
+ explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) {}
- GoASTExpr(const GoASTExpr &) = delete;
- const GoASTExpr &operator=(const GoASTExpr &) = delete;
+private:
+ GoASTSpec(const GoASTSpec &) = delete;
+ const GoASTSpec &operator=(const GoASTSpec &) = delete;
};
-class GoASTSpec : public GoASTNode
-{
- public:
- template <typename R, typename V> R Visit(V *v) const;
+class GoASTStmt : 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;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt;
+ }
- protected:
- explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) { }
- private:
+protected:
+ explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) {}
- GoASTSpec(const GoASTSpec &) = delete;
- const GoASTSpec &operator=(const GoASTSpec &) = delete;
+private:
+ GoASTStmt(const GoASTStmt &) = delete;
+ const GoASTStmt &operator=(const GoASTStmt &) = delete;
};
-class GoASTStmt : public GoASTNode
-{
- public:
- template <typename R, typename V> R Visit(V *v) const;
+class GoASTArrayType : public GoASTExpr {
+public:
+ GoASTArrayType(GoASTExpr *len, GoASTExpr *elt)
+ : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {}
+ ~GoASTArrayType() override = default;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt;
- }
+ const char *GetKindName() const override { return "ArrayType"; }
- protected:
- explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) { }
- private:
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eArrayType; }
- GoASTStmt(const GoASTStmt &) = delete;
- const GoASTStmt &operator=(const GoASTStmt &) = delete;
-};
+ 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); }
-class GoASTArrayType : public GoASTExpr
-{
- public:
- GoASTArrayType(GoASTExpr *len, GoASTExpr *elt) : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {}
- ~GoASTArrayType() override = default;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_len_up;
+ std::unique_ptr<GoASTExpr> m_elt_up;
- const char *
- GetKindName() const override
- {
- return "ArrayType";
- }
+ GoASTArrayType(const GoASTArrayType &) = delete;
+ const GoASTArrayType &operator=(const GoASTArrayType &) = delete;
+};
- 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);
- }
+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;
+};
- const GoASTExpr *
- GetElt() const
- {
- return m_elt_up.get();
- }
- void
- SetElt(GoASTExpr *elt)
- {
- m_elt_up.reset(elt);
- }
+class GoASTBadDecl : public GoASTDecl {
+public:
+ GoASTBadDecl() : GoASTDecl(eBadDecl) {}
+ ~GoASTBadDecl() override = default;
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_len_up;
- std::unique_ptr<GoASTExpr> m_elt_up;
+ const char *GetKindName() const override { return "BadDecl"; }
- GoASTArrayType(const GoASTArrayType &) = delete;
- const GoASTArrayType &operator=(const GoASTArrayType &) = delete;
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBadDecl; }
+
+ GoASTBadDecl(const GoASTBadDecl &) = delete;
+ const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete;
};
-class GoASTAssignStmt : public GoASTStmt
-{
- public:
- explicit GoASTAssignStmt(bool define) : GoASTStmt(eAssignStmt), m_define(define) {}
- ~GoASTAssignStmt() override = default;
+class GoASTBadExpr : public GoASTExpr {
+public:
+ GoASTBadExpr() : GoASTExpr(eBadExpr) {}
+ ~GoASTBadExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "AssignStmt";
- }
+ const char *GetKindName() const override { return "BadExpr"; }
- 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));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBadExpr; }
- 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));
- }
+ GoASTBadExpr(const GoASTBadExpr &) = delete;
+ const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete;
+};
- bool
- GetDefine() const
- {
- return m_define;
- }
- void
- SetDefine(bool define)
- {
- m_define = define;
- }
+class GoASTBadStmt : public GoASTStmt {
+public:
+ GoASTBadStmt() : GoASTStmt(eBadStmt) {}
+ ~GoASTBadStmt() override = default;
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTExpr> > m_lhs;
- std::vector<std::unique_ptr<GoASTExpr> > m_rhs;
- bool m_define;
+ const char *GetKindName() const override { return "BadStmt"; }
- GoASTAssignStmt(const GoASTAssignStmt &) = delete;
- const GoASTAssignStmt &operator=(const GoASTAssignStmt &) = delete;
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBadStmt; }
+
+ GoASTBadStmt(const GoASTBadStmt &) = delete;
+ const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete;
};
-class GoASTBadDecl : public GoASTDecl
-{
- public:
- GoASTBadDecl() : GoASTDecl(eBadDecl) {}
- ~GoASTBadDecl() override = default;
+class GoASTBasicLit : public GoASTExpr {
+public:
+ explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {}
+ ~GoASTBasicLit() override = default;
- const char *
- GetKindName() const override
- {
- return "BadDecl";
- }
+ const char *GetKindName() const override { return "BasicLit"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBadDecl;
- }
-
- GoASTBadDecl(const GoASTBadDecl &) = delete;
- const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete;
-};
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBasicLit; }
-class GoASTBadExpr : public GoASTExpr
-{
- public:
- GoASTBadExpr() : GoASTExpr(eBadExpr) {}
- ~GoASTBadExpr() override = default;
+ Token GetValue() const { return m_value; }
+ void SetValue(Token value) { m_value = value; }
- const char *
- GetKindName() const override
- {
- return "BadExpr";
- }
+private:
+ friend class GoASTNode;
+ Token m_value;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBadExpr;
- }
-
- GoASTBadExpr(const GoASTBadExpr &) = delete;
- const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete;
+ GoASTBasicLit(const GoASTBasicLit &) = delete;
+ const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete;
};
-class GoASTBadStmt : public GoASTStmt
-{
- public:
- GoASTBadStmt() : GoASTStmt(eBadStmt) {}
- ~GoASTBadStmt() override = default;
+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 "BadStmt";
- }
+ const char *GetKindName() const override { return "BinaryExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBadStmt;
- }
-
- GoASTBadStmt(const GoASTBadStmt &) = delete;
- const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete;
-};
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eBinaryExpr;
+ }
-class GoASTBasicLit : public GoASTExpr
-{
- public:
- explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {}
- ~GoASTBasicLit() override = default;
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- const char *
- GetKindName() const override
- {
- return "BasicLit";
- }
+ const GoASTExpr *GetY() const { return m_y_up.get(); }
+ void SetY(GoASTExpr *y) { m_y_up.reset(y); }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBasicLit;
- }
-
- Token
- GetValue() const
- {
- return m_value;
- }
- void
- SetValue(Token value)
- {
- m_value = value;
- }
+ TokenType GetOp() const { return m_op; }
+ void SetOp(TokenType op) { m_op = op; }
- private:
- friend class GoASTNode;
- Token m_value;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ std::unique_ptr<GoASTExpr> m_y_up;
+ TokenType m_op;
- GoASTBasicLit(const GoASTBasicLit &) = delete;
- const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete;
+ GoASTBinaryExpr(const GoASTBinaryExpr &) = delete;
+ const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = 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";
- }
+class GoASTBlockStmt : public GoASTStmt {
+public:
+ GoASTBlockStmt() : GoASTStmt(eBlockStmt) {}
+ ~GoASTBlockStmt() override = default;
- 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 char *GetKindName() const override { return "BlockStmt"; }
- const GoASTExpr *
- GetY() const
- {
- return m_y_up.get();
- }
- void
- SetY(GoASTExpr *y)
- {
- m_y_up.reset(y);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBlockStmt; }
- TokenType
- GetOp() const
- {
- return m_op;
- }
- void
- SetOp(TokenType op)
- {
- m_op = op;
- }
+ 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::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_y_up;
- TokenType m_op;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTStmt>> m_list;
- GoASTBinaryExpr(const GoASTBinaryExpr &) = delete;
- const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = delete;
+ GoASTBlockStmt(const GoASTBlockStmt &) = delete;
+ const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete;
};
-class GoASTBlockStmt : public GoASTStmt
-{
- public:
- GoASTBlockStmt() : GoASTStmt(eBlockStmt) {}
- ~GoASTBlockStmt() override = default;
+class GoASTIdent : public GoASTExpr {
+public:
+ explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {}
+ ~GoASTIdent() override = default;
- const char *
- GetKindName() const override
- {
- return "BlockStmt";
- }
+ const char *GetKindName() const override { return "Ident"; }
- 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));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eIdent; }
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTStmt> > m_list;
+ Token GetName() const { return m_name; }
+ void SetName(Token name) { m_name = name; }
- GoASTBlockStmt(const GoASTBlockStmt &) = delete;
- const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete;
+private:
+ friend class GoASTNode;
+ Token m_name;
+
+ GoASTIdent(const GoASTIdent &) = delete;
+ const GoASTIdent &operator=(const GoASTIdent &) = delete;
};
-class GoASTIdent : public GoASTExpr
-{
- public:
- explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {}
- ~GoASTIdent() override = default;
+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 "Ident";
- }
+ const char *GetKindName() const override { return "BranchStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eIdent;
- }
-
- Token
- GetName() const
- {
- return m_name;
- }
- void
- SetName(Token name)
- {
- m_name = name;
- }
+ 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); }
- private:
- friend class GoASTNode;
- Token m_name;
+ TokenType GetTok() const { return m_tok; }
+ void SetTok(TokenType tok) { m_tok = tok; }
- GoASTIdent(const GoASTIdent &) = delete;
- const GoASTIdent &operator=(const GoASTIdent &) = delete;
+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 GoASTBranchStmt : public GoASTStmt
-{
- public:
- GoASTBranchStmt(GoASTIdent *label, TokenType tok) : GoASTStmt(eBranchStmt), m_label_up(label), m_tok(tok) {}
- ~GoASTBranchStmt() override = default;
+class GoASTCallExpr : public GoASTExpr {
+public:
+ explicit GoASTCallExpr(bool ellipsis)
+ : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {}
+ ~GoASTCallExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "BranchStmt";
- }
+ const char *GetKindName() const override { return "CallExpr"; }
- 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eCallExpr; }
- TokenType
- GetTok() const
- {
- return m_tok;
- }
- void
- SetTok(TokenType tok)
- {
- m_tok = tok;
- }
+ 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<GoASTIdent> m_label_up;
- TokenType m_tok;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_fun_up;
+ std::vector<std::unique_ptr<GoASTExpr>> m_args;
+ bool m_ellipsis;
- GoASTBranchStmt(const GoASTBranchStmt &) = delete;
- const GoASTBranchStmt &operator=(const GoASTBranchStmt &) = delete;
+ GoASTCallExpr(const GoASTCallExpr &) = delete;
+ const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete;
};
-class GoASTCallExpr : public GoASTExpr
-{
- public:
- explicit GoASTCallExpr(bool ellipsis) : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {}
- ~GoASTCallExpr() override = default;
+class GoASTCaseClause : public GoASTStmt {
+public:
+ GoASTCaseClause() : GoASTStmt(eCaseClause) {}
+ ~GoASTCaseClause() override = default;
- const char *
- GetKindName() const override
- {
- return "CallExpr";
- }
+ const char *GetKindName() const override { return "CaseClause"; }
- 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eCaseClause;
+ }
- 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));
- }
+ 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));
+ }
- bool
- GetEllipsis() const
- {
- return m_ellipsis;
- }
- void
- SetEllipsis(bool ellipsis)
- {
- m_ellipsis = ellipsis;
- }
+ 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<GoASTExpr> m_fun_up;
- std::vector<std::unique_ptr<GoASTExpr> > m_args;
- bool m_ellipsis;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTExpr>> m_list;
+ std::vector<std::unique_ptr<GoASTStmt>> m_body;
- GoASTCallExpr(const GoASTCallExpr &) = delete;
- const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete;
+ GoASTCaseClause(const GoASTCaseClause &) = delete;
+ const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete;
};
-class GoASTCaseClause : public GoASTStmt
-{
- public:
- GoASTCaseClause() : GoASTStmt(eCaseClause) {}
- ~GoASTCaseClause() override = default;
+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 "CaseClause";
- }
+ const char *GetKindName() const override { return "ChanType"; }
- 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));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eChanType; }
- 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));
- }
+ 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;
- std::vector<std::unique_ptr<GoASTExpr> > m_list;
- std::vector<std::unique_ptr<GoASTStmt> > m_body;
+private:
+ friend class GoASTNode;
+ ChanDir m_dir;
+ std::unique_ptr<GoASTExpr> m_value_up;
- GoASTCaseClause(const GoASTCaseClause &) = delete;
- const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete;
+ GoASTChanType(const GoASTChanType &) = delete;
+ const GoASTChanType &operator=(const GoASTChanType &) = delete;
};
-class GoASTChanType : public GoASTExpr
-{
- public:
- GoASTChanType(ChanDir dir, GoASTExpr *value) : GoASTExpr(eChanType), m_dir(dir), m_value_up(value) {}
- ~GoASTChanType() override = default;
+class GoASTCommClause : public GoASTStmt {
+public:
+ GoASTCommClause() : GoASTStmt(eCommClause) {}
+ ~GoASTCommClause() override = default;
- const char *
- GetKindName() const override
- {
- return "ChanType";
- }
+ const char *GetKindName() const override { return "CommClause"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eChanType;
- }
-
- ChanDir
- GetDir() const
- {
- return m_dir;
- }
- void
- SetDir(ChanDir dir)
- {
- m_dir = dir;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eCommClause;
+ }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ const GoASTStmt *GetComm() const { return m_comm_up.get(); }
+ void SetComm(GoASTStmt *comm) { m_comm_up.reset(comm); }
- private:
- friend class GoASTNode;
- ChanDir m_dir;
- std::unique_ptr<GoASTExpr> m_value_up;
+ 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));
+ }
- GoASTChanType(const GoASTChanType &) = delete;
- const GoASTChanType &operator=(const GoASTChanType &) = delete;
+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 GoASTCommClause : public GoASTStmt
-{
- public:
- GoASTCommClause() : GoASTStmt(eCommClause) {}
- ~GoASTCommClause() override = default;
+class GoASTCompositeLit : public GoASTExpr {
+public:
+ GoASTCompositeLit() : GoASTExpr(eCompositeLit) {}
+ ~GoASTCompositeLit() override = default;
- const char *
- GetKindName() const override
- {
- return "CommClause";
- }
+ const char *GetKindName() const override { return "CompositeLit"; }
- 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eCompositeLit;
+ }
- 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));
- }
+ 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<GoASTStmt> m_comm_up;
- std::vector<std::unique_ptr<GoASTStmt> > m_body;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_type_up;
+ std::vector<std::unique_ptr<GoASTExpr>> m_elts;
- GoASTCommClause(const GoASTCommClause &) = delete;
- const GoASTCommClause &operator=(const GoASTCommClause &) = delete;
+ GoASTCompositeLit(const GoASTCompositeLit &) = delete;
+ const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete;
};
-class GoASTCompositeLit : public GoASTExpr
-{
- public:
- GoASTCompositeLit() : GoASTExpr(eCompositeLit) {}
- ~GoASTCompositeLit() override = default;
+class GoASTDeclStmt : public GoASTStmt {
+public:
+ explicit GoASTDeclStmt(GoASTDecl *decl)
+ : GoASTStmt(eDeclStmt), m_decl_up(decl) {}
+ ~GoASTDeclStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "CompositeLit";
- }
+ const char *GetKindName() const override { return "DeclStmt"; }
- 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eDeclStmt; }
- 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));
- }
+ 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<GoASTExpr> m_type_up;
- std::vector<std::unique_ptr<GoASTExpr> > m_elts;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTDecl> m_decl_up;
- GoASTCompositeLit(const GoASTCompositeLit &) = delete;
- const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete;
+ GoASTDeclStmt(const GoASTDeclStmt &) = delete;
+ const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete;
};
-class GoASTDeclStmt : public GoASTStmt
-{
- public:
- explicit GoASTDeclStmt(GoASTDecl *decl) : GoASTStmt(eDeclStmt), m_decl_up(decl) {}
- ~GoASTDeclStmt() override = default;
+class GoASTDeferStmt : public GoASTStmt {
+public:
+ explicit GoASTDeferStmt(GoASTCallExpr *call)
+ : GoASTStmt(eDeferStmt), m_call_up(call) {}
+ ~GoASTDeferStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "DeclStmt";
- }
+ const char *GetKindName() const override { return "DeferStmt"; }
- 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);
- }
+ 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<GoASTDecl> m_decl_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTCallExpr> m_call_up;
- GoASTDeclStmt(const GoASTDeclStmt &) = delete;
- const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete;
+ GoASTDeferStmt(const GoASTDeferStmt &) = delete;
+ const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete;
};
-class GoASTDeferStmt : public GoASTStmt
-{
- public:
- explicit GoASTDeferStmt(GoASTCallExpr *call) : GoASTStmt(eDeferStmt), m_call_up(call) {}
- ~GoASTDeferStmt() override = default;
+class GoASTEllipsis : public GoASTExpr {
+public:
+ explicit GoASTEllipsis(GoASTExpr *elt)
+ : GoASTExpr(eEllipsis), m_elt_up(elt) {}
+ ~GoASTEllipsis() override = default;
- const char *
- GetKindName() const override
- {
- return "DeferStmt";
- }
+ const char *GetKindName() const override { return "Ellipsis"; }
- 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eEllipsis; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTCallExpr> m_call_up;
+ const GoASTExpr *GetElt() const { return m_elt_up.get(); }
+ void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); }
- GoASTDeferStmt(const GoASTDeferStmt &) = delete;
- const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete;
-};
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_elt_up;
-class GoASTEllipsis : public GoASTExpr
-{
- public:
- explicit GoASTEllipsis(GoASTExpr *elt) : GoASTExpr(eEllipsis), m_elt_up(elt) {}
- ~GoASTEllipsis() override = default;
+ GoASTEllipsis(const GoASTEllipsis &) = delete;
+ const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete;
+};
- const char *
- GetKindName() const override
- {
- return "Ellipsis";
- }
+class GoASTEmptyStmt : public GoASTStmt {
+public:
+ GoASTEmptyStmt() : GoASTStmt(eEmptyStmt) {}
+ ~GoASTEmptyStmt() override = default;
- 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);
- }
+ const char *GetKindName() const override { return "EmptyStmt"; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_elt_up;
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eEmptyStmt; }
- GoASTEllipsis(const GoASTEllipsis &) = delete;
- const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete;
+ GoASTEmptyStmt(const GoASTEmptyStmt &) = delete;
+ const GoASTEmptyStmt &operator=(const GoASTEmptyStmt &) = 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;
-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"; }
- const char *
- GetKindName() const override
- {
- return "ExprStmt";
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eExprStmt; }
- 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);
- }
+ 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;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
- GoASTExprStmt(const GoASTExprStmt &) = delete;
- const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete;
+ GoASTExprStmt(const GoASTExprStmt &) = delete;
+ const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete;
};
-class GoASTField : public GoASTNode
-{
- public:
- GoASTField() : GoASTNode(eField) {}
- ~GoASTField() override = default;
+class GoASTField : public GoASTNode {
+public:
+ GoASTField() : GoASTNode(eField) {}
+ ~GoASTField() override = default;
- const char *
- GetKindName() const override
- {
- return "Field";
- }
+ 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));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eField; }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ 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 GoASTBasicLit *
- GetTag() const
- {
- return m_tag_up.get();
- }
- void
- SetTag(GoASTBasicLit *tag)
- {
- m_tag_up.reset(tag);
- }
+ 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;
+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;
+ GoASTField(const GoASTField &) = delete;
+ const GoASTField &operator=(const GoASTField &) = delete;
};
-class GoASTFieldList : public GoASTNode
-{
- public:
- GoASTFieldList() : GoASTNode(eFieldList) {}
- ~GoASTFieldList() override = default;
+class GoASTFieldList : public GoASTNode {
+public:
+ GoASTFieldList() : GoASTNode(eFieldList) {}
+ ~GoASTFieldList() override = default;
- const char *
- GetKindName() const override
- {
- return "FieldList";
- }
+ 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));
- }
+ 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;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTField>> m_list;
- GoASTFieldList(const GoASTFieldList &) = delete;
- const GoASTFieldList &operator=(const GoASTFieldList &) = delete;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eForStmt; }
- const GoASTExpr *
- GetCond() const
- {
- return m_cond_up.get();
- }
- void
- SetCond(GoASTExpr *cond)
- {
- m_cond_up.reset(cond);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTStmt *
- GetPost() const
- {
- return m_post_up.get();
- }
- void
- SetPost(GoASTStmt *post)
- {
- m_post_up.reset(post);
- }
+ 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 *GetPost() const { return m_post_up.get(); }
+ void SetPost(GoASTStmt *post) { m_post_up.reset(post); }
- 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;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTForStmt(const GoASTForStmt &) = delete;
- const GoASTForStmt &operator=(const GoASTForStmt &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncType; }
- const GoASTFieldList *
- GetResults() const
- {
- return m_results_up.get();
- }
- void
- SetResults(GoASTFieldList *results)
- {
- m_results_up.reset(results);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncDecl; }
- const GoASTIdent *
- GetName() const
- {
- return m_name_up.get();
- }
- void
- SetName(GoASTIdent *name)
- {
- m_name_up.reset(name);
- }
+ const GoASTFieldList *GetRecv() const { return m_recv_up.get(); }
+ void SetRecv(GoASTFieldList *recv) { m_recv_up.reset(recv); }
- const GoASTFuncType *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTFuncType *type)
- {
- m_type_up.reset(type);
- }
+ const GoASTIdent *GetName() const { return m_name_up.get(); }
+ void SetName(GoASTIdent *name) { m_name_up.reset(name); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTFuncType *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTFuncType *type) { m_type_up.reset(type); }
- 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;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTFuncDecl(const GoASTFuncDecl &) = delete;
- const GoASTFuncDecl &operator=(const GoASTFuncDecl &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncLit; }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ 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;
+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;
+ 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;
+class GoASTGenDecl : public GoASTDecl {
+public:
+ explicit GoASTGenDecl(TokenType tok) : GoASTDecl(eGenDecl), m_tok(tok) {}
+ ~GoASTGenDecl() override = default;
- const char *
- GetKindName() const override
- {
- return "GenDecl";
- }
+ 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;
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eGenDecl; }
- 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));
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eGoStmt; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTCallExpr> m_call_up;
+ const GoASTCallExpr *GetCall() const { return m_call_up.get(); }
+ void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); }
- GoASTGoStmt(const GoASTGoStmt &) = delete;
- const GoASTGoStmt &operator=(const GoASTGoStmt &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eIfStmt; }
- const GoASTExpr *
- GetCond() const
- {
- return m_cond_up.get();
- }
- void
- SetCond(GoASTExpr *cond)
- {
- m_cond_up.reset(cond);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTExpr *GetCond() const { return m_cond_up.get(); }
+ void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); }
- const GoASTStmt *
- GetEls() const
- {
- return m_els_up.get();
- }
- void
- SetEls(GoASTStmt *els)
- {
- m_els_up.reset(els);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eImportSpec;
+ }
- const GoASTBasicLit *
- GetPath() const
- {
- return m_path_up.get();
- }
- void
- SetPath(GoASTBasicLit *path)
- {
- m_path_up.reset(path);
- }
+ const GoASTIdent *GetName() const { return m_name_up.get(); }
+ void SetName(GoASTIdent *name) { m_name_up.reset(name); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTBasicLit> m_path_up;
+ const GoASTBasicLit *GetPath() const { return m_path_up.get(); }
+ void SetPath(GoASTBasicLit *path) { m_path_up.reset(path); }
- GoASTImportSpec(const GoASTImportSpec &) = delete;
- const GoASTImportSpec &operator=(const GoASTImportSpec &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eIncDecStmt;
+ }
- TokenType
- GetTok() const
- {
- return m_tok;
- }
- void
- SetTok(TokenType tok)
- {
- m_tok = tok;
- }
+ 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;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ TokenType m_tok;
- GoASTIncDecStmt(const GoASTIncDecStmt &) = delete;
- const GoASTIncDecStmt &operator=(const GoASTIncDecStmt &) = delete;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eIndexExpr; }
- const GoASTExpr *
- GetIndex() const
- {
- return m_index_up.get();
- }
- void
- SetIndex(GoASTExpr *index)
- {
- m_index_up.reset(index);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ 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;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTFieldList> m_methods_up;
- GoASTInterfaceType(const GoASTInterfaceType &) = delete;
- const GoASTInterfaceType &operator=(const GoASTInterfaceType &) = delete;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eKeyValueExpr;
+ }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eLabeledStmt;
+ }
- const GoASTStmt *
- GetStmt() const
- {
- return m_stmt_up.get();
- }
- void
- SetStmt(GoASTStmt *stmt)
- {
- m_stmt_up.reset(stmt);
- }
+ const GoASTIdent *GetLabel() const { return m_label_up.get(); }
+ void SetLabel(GoASTIdent *label) { m_label_up.reset(label); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_label_up;
- std::unique_ptr<GoASTStmt> m_stmt_up;
+ const GoASTStmt *GetStmt() const { return m_stmt_up.get(); }
+ void SetStmt(GoASTStmt *stmt) { m_stmt_up.reset(stmt); }
- GoASTLabeledStmt(const GoASTLabeledStmt &) = delete;
- const GoASTLabeledStmt &operator=(const GoASTLabeledStmt &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eMapType; }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eParenExpr; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- GoASTParenExpr(const GoASTParenExpr &) = delete;
- const GoASTParenExpr &operator=(const GoASTParenExpr &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eRangeStmt; }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ const GoASTExpr *GetKey() const { return m_key_up.get(); }
+ void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
- bool
- GetDefine() const
- {
- return m_define;
- }
- void
- SetDefine(bool define)
- {
- m_define = define;
- }
+ const GoASTExpr *GetValue() const { return m_value_up.get(); }
+ void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ bool GetDefine() const { return m_define; }
+ void SetDefine(bool define) { m_define = define; }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ 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;
+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;
+ GoASTRangeStmt(const GoASTRangeStmt &) = delete;
+ const GoASTRangeStmt &operator=(const GoASTRangeStmt &) = delete;
};
-class GoASTReturnStmt : public GoASTStmt
-{
- public:
- GoASTReturnStmt() : GoASTStmt(eReturnStmt) {}
- ~GoASTReturnStmt() override = default;
+class GoASTReturnStmt : public GoASTStmt {
+public:
+ GoASTReturnStmt() : GoASTStmt(eReturnStmt) {}
+ ~GoASTReturnStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "ReturnStmt";
- }
+ 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));
- }
+ 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;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTExpr>> m_results;
- GoASTReturnStmt(const GoASTReturnStmt &) = delete;
- const GoASTReturnStmt &operator=(const GoASTReturnStmt &) = delete;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eSelectStmt;
+ }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTSelectStmt(const GoASTSelectStmt &) = delete;
- const GoASTSelectStmt &operator=(const GoASTSelectStmt &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eSelectorExpr;
+ }
- const GoASTIdent *
- GetSel() const
- {
- return m_sel_up.get();
- }
- void
- SetSel(GoASTIdent *sel)
- {
- m_sel_up.reset(sel);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eSendStmt; }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eSliceExpr; }
- const GoASTExpr *
- GetLow() const
- {
- return m_low_up.get();
- }
- void
- SetLow(GoASTExpr *low)
- {
- m_low_up.reset(low);
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- const GoASTExpr *
- GetHigh() const
- {
- return m_high_up.get();
- }
- void
- SetHigh(GoASTExpr *high)
- {
- m_high_up.reset(high);
- }
+ const GoASTExpr *GetLow() const { return m_low_up.get(); }
+ void SetLow(GoASTExpr *low) { m_low_up.reset(low); }
- const GoASTExpr *
- GetMax() const
- {
- return m_max_up.get();
- }
- void
- SetMax(GoASTExpr *max)
- {
- m_max_up.reset(max);
- }
+ const GoASTExpr *GetHigh() const { return m_high_up.get(); }
+ void SetHigh(GoASTExpr *high) { m_high_up.reset(high); }
- bool
- GetSlice3() const
- {
- return m_slice3;
- }
- void
- SetSlice3(bool slice3)
- {
- m_slice3 = slice3;
- }
+ const GoASTExpr *GetMax() const { return m_max_up.get(); }
+ void SetMax(GoASTExpr *max) { m_max_up.reset(max); }
- 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;
+ bool GetSlice3() const { return m_slice3; }
+ void SetSlice3(bool slice3) { m_slice3 = slice3; }
- GoASTSliceExpr(const GoASTSliceExpr &) = delete;
- const GoASTSliceExpr &operator=(const GoASTSliceExpr &) = delete;
+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;
+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";
- }
+ 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);
- }
+ 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;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
- GoASTStarExpr(const GoASTStarExpr &) = delete;
- const GoASTStarExpr &operator=(const GoASTStarExpr &) = delete;
+ 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;
+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";
- }
+ 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);
- }
+ 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;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTFieldList> m_fields_up;
- GoASTStructType(const GoASTStructType &) = delete;
- const GoASTStructType &operator=(const GoASTStructType &) = delete;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eSwitchStmt;
+ }
- const GoASTExpr *
- GetTag() const
- {
- return m_tag_up.get();
- }
- void
- SetTag(GoASTExpr *tag)
- {
- m_tag_up.reset(tag);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eTypeAssertExpr;
+ }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ 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;
+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;
+ 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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eTypeSpec; }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ const GoASTIdent *GetName() const { return m_name_up.get(); }
+ void SetName(GoASTIdent *name) { m_name_up.reset(name); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTExpr> m_type_up;
+ const GoASTExpr *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTExpr *type) { m_type_up.reset(type); }
- GoASTTypeSpec(const GoASTTypeSpec &) = delete;
- const GoASTTypeSpec &operator=(const GoASTTypeSpec &) = delete;
+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;
+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";
- }
+ 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);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eTypeSwitchStmt;
+ }
- const GoASTStmt *
- GetAssign() const
- {
- return m_assign_up.get();
- }
- void
- SetAssign(GoASTStmt *assign)
- {
- m_assign_up.reset(assign);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTStmt *GetAssign() const { return m_assign_up.get(); }
+ void SetAssign(GoASTStmt *assign) { m_assign_up.reset(assign); }
- 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;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTTypeSwitchStmt(const GoASTTypeSwitchStmt &) = delete;
- const GoASTTypeSwitchStmt &operator=(const GoASTTypeSwitchStmt &) = delete;
+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;
+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";
- }
+ 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;
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eUnaryExpr; }
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ 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;
+private:
+ friend class GoASTNode;
+ TokenType m_op;
+ std::unique_ptr<GoASTExpr> m_x_up;
- GoASTUnaryExpr(const GoASTUnaryExpr &) = delete;
- const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete;
+ GoASTUnaryExpr(const GoASTUnaryExpr &) = delete;
+ const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete;
};
-class GoASTValueSpec : public GoASTSpec
-{
- public:
- GoASTValueSpec() : GoASTSpec(eValueSpec) {}
- ~GoASTValueSpec() override = default;
+class GoASTValueSpec : public GoASTSpec {
+public:
+ GoASTValueSpec() : GoASTSpec(eValueSpec) {}
+ ~GoASTValueSpec() override = default;
- const char *
- GetKindName() const override
- {
- return "ValueSpec";
- }
+ 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));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eValueSpec; }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ 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));
+ }
- 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));
- }
+ const GoASTExpr *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTExpr *type) { m_type_up.reset(type); }
- 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;
+ 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));
+ }
- GoASTValueSpec(const GoASTValueSpec &) = delete;
- const GoASTValueSpec &operator=(const GoASTValueSpec &) = delete;
-};
+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 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 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 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 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;
- }
+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
+} // namespace lldb_private
#endif
-
diff --git a/source/Plugins/ExpressionParser/Go/GoLexer.cpp b/source/Plugins/ExpressionParser/Go/GoLexer.cpp
index 6de0f5619ca8..63e267eaadc2 100644
--- a/source/Plugins/ExpressionParser/Go/GoLexer.cpp
+++ b/source/Plugins/ExpressionParser/Go/GoLexer.cpp
@@ -15,388 +15,336 @@ 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, "")
-{
-}
+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::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;
- }
- }
+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;
+ }
}
- 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 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;
+ }
+ 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;
+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;
- }
+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();
+ }
+ 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 TOK_INVALID;
+ }
+ return t;
}
-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::DoIdent()
-{
- const char *start = m_src++;
- while (m_src < m_end && IsLetterOrDigit(*m_src))
- {
+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;
}
- 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::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;
- }
+GoLexer::TokenType GoLexer::DoString() {
+ if (*m_src == '`') {
+ while (++m_src < m_end) {
+ if (*m_src == '`') {
+ ++m_src;
+ return LIT_STRING;
+ }
}
return TOK_INVALID;
-}
-
-GoLexer::TokenType
-GoLexer::DoString()
-{
- if (*m_src == '`')
- {
- while (++m_src < m_end)
- {
- if (*m_src == '`')
- {
- ++m_src;
- return LIT_STRING;
- }
- }
+ }
+ 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;
}
- 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;
+ }
+ 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;
+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::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;
+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
index e8e1635bab77..f0b5b336fbe9 100644
--- a/source/Plugins/ExpressionParser/Go/GoLexer.h
+++ b/source/Plugins/ExpressionParser/Go/GoLexer.h
@@ -10,190 +10,170 @@
#ifndef liblldb_GoLexer_h
#define liblldb_GoLexer_h
-#include "llvm/ADT/StringRef.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;
+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();
+ bool SkipWhitespace();
+ bool SkipComment();
- TokenType InternalLex(bool newline);
+ TokenType InternalLex(bool newline);
- TokenType DoOperator();
+ TokenType DoOperator();
- TokenType DoIdent();
+ TokenType DoIdent();
- TokenType DoNumber();
+ TokenType DoNumber();
- TokenType DoRune();
+ TokenType DoRune();
- TokenType DoString();
+ TokenType DoString();
- static llvm::StringMap<TokenType> *InitKeywords();
+ static llvm::StringMap<TokenType> *InitKeywords();
- static llvm::StringMap<TokenType> *m_keywords;
+ static llvm::StringMap<TokenType> *m_keywords;
- const char *m_src;
- const char *m_end;
- Token m_last_token;
+ const char *m_src;
+ const char *m_end;
+ Token m_last_token;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Go/GoParser.cpp b/source/Plugins/ExpressionParser/Go/GoParser.cpp
index 0f136f7e61dc..327b9df43db3 100644
--- a/source/Plugins/ExpressionParser/Go/GoParser.cpp
+++ b/source/Plugins/ExpressionParser/Go/GoParser.cpp
@@ -11,1025 +11,870 @@
#include "GoParser.h"
+#include "Plugins/ExpressionParser/Go/GoAST.h"
#include "lldb/Core/Error.h"
#include "llvm/ADT/SmallString.h"
-#include "Plugins/ExpressionParser/Go/GoAST.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 {
+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;
+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;
+private:
+ llvm::StringRef m_name;
+ GoParser *m_parser;
+ size_t m_pos;
};
-GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), 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;
- }
+GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), 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;
+ default:
+ break;
+ }
+ GoASTExpr *expr = Expression();
+ if (expr == nullptr)
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();
+ 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;
-}
-
-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();
+ 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);
}
- // 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 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 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 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 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));
+ 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();
}
- if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
- return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));
-
- return nullptr;
+ 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;
}
-GoASTIdent *
-GoParser::Identifier()
-{
- if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
- return new GoASTIdent(*tok);
+GoASTExpr *GoParser::PrimaryExpr() {
+ GoASTExpr *l;
+ GoASTExpr *r;
+ (l = Conversion()) || (l = Operand());
+ if (!l)
return nullptr;
-}
-
-GoASTExpr *
-GoParser::MoreExpressionList()
-{
- if (match(GoLexer::OP_COMMA))
- {
- auto *e = Expression();
- if (!e)
- return syntaxerror();
- return e;
- }
+ 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);
}
-GoASTIdent *
-GoParser::MoreIdentifierList()
-{
- if (match(GoLexer::OP_COMMA))
- {
- auto *i = Identifier();
- if (!i)
- return syntaxerror();
- return i;
- }
+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::Expression()
-{
- Rule r("Expression", this);
- if (GoASTExpr *ret = OrExpr())
- return ret;
+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)
+ return r.error();
+ lit->SetType(type);
+ return lit;
}
-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();
- }
+GoASTCompositeLit *GoParser::LiteralValue() {
+ if (!match(GoLexer::OP_LBRACE))
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();
- }
+ 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::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();
- }
+GoASTExpr *GoParser::Element() {
+ GoASTExpr *key;
+ if (!((key = Expression()) || (key = LiteralValue())))
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)
+ 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;
- while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) || (r = Arguments(l)))
- {
- l = r;
+ return new GoASTTypeAssertExpr(e, t);
}
- return l;
+ return syntaxerror();
+ }
+ return r.error();
}
-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;
+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);
}
- // MethodExpr should be handled by Selector
- if (GoASTExpr *e = CompositeLit())
- return e;
- if (GoASTExpr *n = Name())
- return n;
- return FunctionLit();
-}
+ if (match(GoLexer::OP_DOTS))
+ call->SetEllipsis(true);
-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);
-}
+ // Eat trailing comma
+ match(GoLexer::OP_COMMA);
-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))
+ 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()) {
+ if (match(GoLexer::OP_LPAREN)) {
+ GoASTExpr *v = Expression();
+ if (!v)
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)
+ match(GoLexer::OP_COMMA);
+ if (!mustMatch(GoLexer::OP_RPAREN))
return r.error();
- GoASTCompositeLit *lit = LiteralValue();
- if (!lit)
- return r.error();
- lit->SetType(type);
- return lit;
+ GoASTCallExpr *call = new GoASTCallExpr(false);
+ call->SetFun(t);
+ 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;
+ }
}
-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;
+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 (!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();
+ 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::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::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());
}
-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();
-}
+GoASTField *GoParser::FieldDecl() {
+ std::unique_ptr<GoASTField> f(new GoASTField);
+ GoASTExpr *t = FieldNamesAndType(f.get());
+ if (!t)
+ t = AnonymousFieldType();
+ if (!t)
+ return nullptr;
-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();
+ if (auto *tok = match(GoLexer::LIT_STRING))
+ f->SetTag(new GoASTBasicLit(*tok));
+ if (!Semicolon())
+ return syntaxerror();
+ return f.release();
}
-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();
- }
+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::Conversion()
-{
- Rule r("Conversion", this);
- if (GoASTExpr *t = Type2())
- {
- 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);
- call->AddArgs(v);
- return call;
- }
- }
- 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::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::FunctionType() {
+ if (!match(GoLexer::KEYWORD_FUNC))
+ return nullptr;
+ return Signature();
}
-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);
+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 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());
+ }
+ return new GoASTFuncType(params, result);
}
-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);
+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::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;
+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 (!mustMatch(GoLexer::OP_RPAREN))
- return nullptr;
- return l.release();
-}
-
-GoASTField *
-GoParser::ParamDecl()
-{
- std::unique_ptr<GoASTField> field(new GoASTField);
- GoASTIdent *id = Identifier();
+ if (!Semicolon())
+ return syntaxerror();
+ auto *f = new GoASTField;
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();
- }
+ f->AddNames(id.release());
+ f->SetType(type);
+ methods->AddList(f);
+ }
+ if (!mustMatch(GoLexer::OP_RBRACE))
return nullptr;
+ return new GoASTInterfaceType(methods.release());
}
-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();
- }
+GoASTExpr *GoParser::MapType() {
+ if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
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;
- }
+ 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::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);
- }
+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();
}
-llvm::StringRef
-GoParser::CopyString(llvm::StringRef s)
-{
- return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
+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);
}
-void
-GoParser::GetError(Error &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());
+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(Error &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
index 9ceb670ccd11..bd1285580228 100644
--- a/source/Plugins/ExpressionParser/Go/GoParser.h
+++ b/source/Plugins/ExpressionParser/Go/GoParser.h
@@ -1,4 +1,5 @@
-//===-- GoParser.h -----------------------------------------------*- C++ -*-===//
+//===-- GoParser.h -----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,155 +11,134 @@
#ifndef liblldb_GoParser_h
#define liblldb_GoParser_h
-#include "lldb/lldb-private.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(Error &error);
-
- private:
- class Rule;
- friend class Rule;
-
- std::nullptr_t
- syntaxerror()
- {
- m_failed = true;
- return nullptr;
+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(Error &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());
}
- 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;
+ 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;
};
}
diff --git a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp b/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
index f69c3e23457d..a448da683e36 100644
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
@@ -20,8 +20,8 @@
#include <vector>
// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
// Project includes
#include "GoUserExpression.h"
@@ -57,705 +57,622 @@
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);
- }
- }
- }
+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;
+ }
- void
- set_use_dynamic(DynamicValueType use_dynamic)
- {
- m_use_dynamic = use_dynamic;
- }
+ 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);
- bool Parse();
- lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx);
- lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s);
- lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e);
+ ValueObjectSP VisitTypeAssertExpr(const GoASTTypeAssertExpr *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitBadExpr(const GoASTBadExpr *e)
- {
- m_parser.GetError(m_error);
- return nullptr;
- }
+ ValueObjectSP VisitBinaryExpr(const GoASTBinaryExpr *e) {
+ return NotImplemented(e);
+ }
- 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 VisitArrayType(const GoASTArrayType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitBinaryExpr(const GoASTBinaryExpr *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitChanType(const GoASTChanType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitArrayType(const GoASTArrayType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitCompositeLit(const GoASTCompositeLit *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitChanType(const GoASTChanType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitEllipsis(const GoASTEllipsis *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitCompositeLit(const GoASTCompositeLit *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitFuncType(const GoASTFuncType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitEllipsis(const GoASTEllipsis *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitFuncLit(const GoASTFuncLit *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitFuncType(const GoASTFuncType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitInterfaceType(const GoASTInterfaceType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitFuncLit(const GoASTFuncLit *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitKeyValueExpr(const GoASTKeyValueExpr *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 VisitMapType(const GoASTMapType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitSliceExpr(const GoASTSliceExpr *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitSliceExpr(const GoASTSliceExpr *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitStructType(const GoASTStructType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitStructType(const GoASTStructType *e) {
+ return NotImplemented(e);
+ }
- CompilerType EvaluateType(const GoASTExpr *e);
+ CompilerType EvaluateType(const GoASTExpr *e);
- Error &
- error()
- {
- return m_error;
- }
+ Error &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;
- Error m_error;
- llvm::StringRef m_package;
- std::vector<std::unique_ptr<GoASTStmt>> m_statements;
+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;
+ Error 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;
- const bool append = true;
- if (!target)
- {
- return nullptr;
- }
- const uint32_t match_count = target->GetImages().FindGlobalVariables(fullname, append, 1, variable_list);
- if (match_count == 1)
- {
- return variable_list.GetVariableAtIndex(0);
- }
+VariableSP FindGlobalVariable(TargetSP target, llvm::Twine name) {
+ ConstString fullname(name.str());
+ VariableList variable_list;
+ const bool append = true;
+ if (!target) {
return nullptr;
+ }
+ const uint32_t match_count = target->GetImages().FindGlobalVariables(
+ fullname, append, 1, variable_list);
+ 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();
- }
+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, const char *expr, const char *expr_prefix,
- lldb::LanguageType language, ResultType desired_type,
+GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope,
+ llvm::StringRef expr, llvm::StringRef prefix,
+ lldb::LanguageType language,
+ ResultType desired_type,
const EvaluateExpressionOptions &options)
- : UserExpression(exe_scope, expr, expr_prefix, language, desired_type, 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.PutCString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.Printf(eDiagnosticSeverityError, "expression can't be interpreted or run");
- return false;
+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));
+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;
+ lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
+ lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
- Process *process = exe_ctx.GetProcessPtr();
- Target *target = exe_ctx.GetTargetPtr();
+ 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 ==");
+ 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.PutCString(eDiagnosticSeverityError, "expression needed to run but couldn't");
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "expression needed to run but couldn't");
- return execution_results;
- }
+ return execution_results;
}
+ }
- m_interpreter->set_use_dynamic(options.GetUseDynamic());
- ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
- Error 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.PutCString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.PutCString(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());
- pv->AddVariable(result);
- }
- return lldb::eExpressionCompleted;
-}
+ m_interpreter->set_use_dynamic(options.GetUseDynamic());
+ ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
+ Error err = m_interpreter->error();
+ m_interpreter.reset();
-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);
+ 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());
+ pv->AddVariable(result);
+ }
+ return lldb::eExpressionCompleted;
+}
- return m_error.Success();
+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;
+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::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::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::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("Invaild 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("Invaild 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("Invaild register name");
- return nullptr;
+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;
}
- 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;
- }
- }
+ 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;
}
- 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);
+ 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.SetErrorStringWithFormat("Unknown variable %s", e->GetName().m_value.str().c_str());
- return val;
+ 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);
+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);
- }
- }
+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;
}
- 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);
- }
- }
+ 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;
+ }
+ // 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(nullptr, data, m_exe_ctx, type);
+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");
+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;
+ }
}
- 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);
+ target = target->GetChildMemberWithName(ConstString("array"), true);
+ if (target && m_use_dynamic != eNoDynamicValues) {
+ ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
+ if (dynamic)
+ target = dynamic;
}
- return target->GetChildAtIndex(idx, true);
+ 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(nullptr, 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;
- }
+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();
+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);
+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)
-{
-}
+GoPersistentExpressionState::GoPersistentExpressionState()
+ : PersistentExpressionState(eKindGo) {}
-ConstString
-GoPersistentExpressionState::GetNextPersistentVariableName()
-{
- char name_cstr[256];
- // We can't use the same variable format as clang.
- ::snprintf(name_cstr, sizeof(name_cstr), "$go%u", m_next_persistent_variable_id++);
- ConstString name(name_cstr);
- return name;
+ConstString GoPersistentExpressionState::GetNextPersistentVariableName() {
+ char name_cstr[256];
+ // We can't use the same variable format as clang.
+ ::snprintf(name_cstr, sizeof(name_cstr), "$go%u",
+ m_next_persistent_variable_id++);
+ ConstString name(name_cstr);
+ return name;
}
-void
-GoPersistentExpressionState::RemovePersistentVariable(lldb::ExpressionVariableSP variable)
-{
- RemoveVariable(variable);
+void GoPersistentExpressionState::RemovePersistentVariable(
+ lldb::ExpressionVariableSP variable) {
+ RemoveVariable(variable);
- const char *name = variable->GetName().AsCString();
+ const char *name = variable->GetName().AsCString();
- if (*(name++) != '$')
- return;
- if (*(name++) != 'g')
- return;
- if (*(name++) != 'o')
- return;
+ 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--;
+ 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
index 711a4c46215d..03ceb76b8431 100644
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.h
+++ b/source/Plugins/ExpressionParser/Go/GoUserExpression.h
@@ -16,83 +16,75 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Expression/UserExpression.h"
#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
-{
+namespace lldb_private {
class GoParser;
-class GoPersistentExpressionState : public PersistentExpressionState
-{
- public:
- GoPersistentExpressionState();
+class GoPersistentExpressionState : public PersistentExpressionState {
+public:
+ GoPersistentExpressionState();
- ConstString GetNextPersistentVariableName() override;
+ ConstString GetNextPersistentVariableName() override;
- void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
+ void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
- lldb::addr_t
- LookupSymbol(const ConstString &name) override
- {
- return LLDB_INVALID_ADDRESS;
- }
+ lldb::addr_t LookupSymbol(const ConstString &name) override {
+ return LLDB_INVALID_ADDRESS;
+ }
- static bool
- classof(const PersistentExpressionState *pv)
- {
- return pv->getKind() == PersistentExpressionState::eKindGo;
- }
+ static bool classof(const PersistentExpressionState *pv) {
+ return pv->getKind() == PersistentExpressionState::eKindGo;
+ }
- private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
+private:
+ uint32_t m_next_persistent_variable_id; ///< The counter used by
+ ///GetNextResultName().
};
//----------------------------------------------------------------------
-/// @class GoUserExpression GoUserExpression.h "lldb/Expression/GoUserExpression.h"
+/// @class GoUserExpression GoUserExpression.h
+/// "lldb/Expression/GoUserExpression.h"
/// @brief 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, const char *expr, const char *expr_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;
+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
diff --git a/source/Plugins/ExpressionParser/Go/gen_go_ast.py b/source/Plugins/ExpressionParser/Go/gen_go_ast.py
index 05b589a9976c..3be0e5f506ee 100644
--- a/source/Plugins/ExpressionParser/Go/gen_go_ast.py
+++ b/source/Plugins/ExpressionParser/Go/gen_go_ast.py
@@ -1,8 +1,17 @@
import StringIO
+
def addNodes():
addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr")
- addNode("AssignStmt", "Stmt", "lhs", "[]Expr", "rhs", "[]Expr", "define", "bool")
+ addNode(
+ "AssignStmt",
+ "Stmt",
+ "lhs",
+ "[]Expr",
+ "rhs",
+ "[]Expr",
+ "define",
+ "bool")
addNode("BadDecl", "Decl")
addNode("BadExpr", "Expr")
addNode("BadStmt", "Stmt")
@@ -11,7 +20,15 @@ def addNodes():
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(
+ "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")
@@ -21,15 +38,53 @@ def addNodes():
addNode("Ellipsis", "Expr", "elt", "Expr")
addNode("EmptyStmt", "Stmt")
addNode("ExprStmt", "Stmt", "x", "Expr")
- addNode("Field", "Node", "names", "[]Ident", "type", "Expr", "tag", "BasicLit")
+ 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(
+ "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(
+ "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(
+ "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")
@@ -38,20 +93,68 @@ def addNodes():
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(
+ "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(
+ "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(
+ "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(
+ "TypeSwitchStmt",
+ "Stmt",
+ "init",
+ "Stmt",
+ "assign",
+ "Stmt",
+ "body",
+ "BlockStmt")
addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr")
- addNode("ValueSpec", "Spec", "names", "[]Ident", "type", "Expr", "values", "[]Expr")
+ addNode(
+ "ValueSpec",
+ "Spec",
+ "names",
+ "[]Ident",
+ "type",
+ "Expr",
+ "values",
+ "[]Expr")
addParent("Decl", "Node")
addParent("Expr", "Node")
addParent("Spec", "Node")
@@ -59,6 +162,7 @@ def addNodes():
class Member(object):
+
def __init__(self, name, typename):
self.title = name.title()
self.sname = name
@@ -75,13 +179,14 @@ class Member(object):
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
@@ -89,6 +194,7 @@ class GoAST%s : public GoAST%s
public:
""" % (name, parent))
+
def endClass(name, out):
out.write("""
%(name)s(const %(name)s &) = delete;
@@ -96,6 +202,7 @@ def endClass(name, out):
};
""" % {'name': 'GoAST' + name})
+
def addNode(name, parent, *children):
startClass(name, parent, childClasses)
l = kinds.setdefault(parent, [])
@@ -114,10 +221,11 @@ def addNode(name, parent, *children):
{
return n->GetKind() == e%(name)s;
}
- """ % {'name':name})
+ """ % {'name': name})
addChildren(name, children)
endClass(name, childClasses)
+
def isValueType(typename):
if typename[0].islower():
return True
@@ -161,7 +269,7 @@ def addConstructor(name, parent, children):
~GoAST%s() override = default;
""" % name)
-
+
def addChildren(name, children):
if len(children) == 0:
return
@@ -169,7 +277,7 @@ def addChildren(name, children):
case e%(n)s:
{
GoAST%(n)s *n = llvm::cast<GoAST%(n)s>(this);
- (void)n;""" % {'n':name})
+ (void)n;""" % {'n': name})
for c in children:
if c.is_list:
childClasses.write("""
@@ -217,14 +325,14 @@ def addChildren(name, children):
{
%(set)s;
}
-""" % {'const':const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
+""" % {'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))
-
+ childClasses.write(' %s %s;\n' % (c.mtype, c.mname))
+
def addParent(name, parent):
startClass(name, parent, parentClasses)
@@ -244,7 +352,7 @@ def addParent(name, parent):
private:
""" % (minName, maxName, name))
endClass(name, parentClasses)
-
+
addNodes()
print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
@@ -305,7 +413,7 @@ print """ };
private:
const NodeKind m_kind;
-
+
GoASTNode(const GoASTNode &) = delete;
const GoASTNode &operator=(const GoASTNode &) = delete;
};
@@ -326,7 +434,7 @@ R GoAST%s::Visit(V* v) const
{""" % k
for subtype in l:
print """ case e%(n)s:
- return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n':subtype}
+ return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n': subtype}
print """ default:
assert(false && "Invalid kind");
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 884078b27175..99caca99074b 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -11,11 +11,12 @@
#include "EmulateInstructionARM.h"
#include "EmulationStateARM.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Address.h"
+#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Host/PosixApi.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -45,121 +46,113 @@ using namespace lldb_private;
// A8.6.50
// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
-static uint32_t
-CountITSize (uint32_t ITMask) {
- // First count the trailing zeros of the IT mask.
- uint32_t TZ = llvm::countTrailingZeros(ITMask);
- if (TZ > 3)
- {
+static uint32_t CountITSize(uint32_t ITMask) {
+ // First count the trailing zeros of the IT mask.
+ uint32_t TZ = llvm::countTrailingZeros(ITMask);
+ if (TZ > 3) {
#ifdef LLDB_CONFIGURATION_DEBUG
- printf("Encoding error: IT Mask '0000'\n");
+ printf("Encoding error: IT Mask '0000'\n");
#endif
- return 0;
- }
- return (4 - TZ);
+ return 0;
+ }
+ return (4 - TZ);
}
// Init ITState. Note that at least one bit is always 1 in mask.
-bool ITSession::InitIT(uint32_t bits7_0)
-{
- ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
- if (ITCounter == 0)
- return false;
+bool ITSession::InitIT(uint32_t bits7_0) {
+ ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
+ if (ITCounter == 0)
+ return false;
- // A8.6.50 IT
- unsigned short FirstCond = Bits32(bits7_0, 7, 4);
- if (FirstCond == 0xF)
- {
+ // A8.6.50 IT
+ unsigned short FirstCond = Bits32(bits7_0, 7, 4);
+ if (FirstCond == 0xF) {
#ifdef LLDB_CONFIGURATION_DEBUG
- printf("Encoding error: IT FirstCond '1111'\n");
+ printf("Encoding error: IT FirstCond '1111'\n");
#endif
- return false;
- }
- if (FirstCond == 0xE && ITCounter != 1)
- {
+ return false;
+ }
+ if (FirstCond == 0xE && ITCounter != 1) {
#ifdef LLDB_CONFIGURATION_DEBUG
- printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
+ printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
#endif
- return false;
- }
+ return false;
+ }
- ITState = bits7_0;
- return true;
+ ITState = bits7_0;
+ return true;
}
// Update ITState if necessary.
-void ITSession::ITAdvance()
-{
- //assert(ITCounter);
- --ITCounter;
- if (ITCounter == 0)
- ITState = 0;
- else
- {
- unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
- SetBits32(ITState, 4, 0, NewITState4_0);
- }
+void ITSession::ITAdvance() {
+ // assert(ITCounter);
+ --ITCounter;
+ if (ITCounter == 0)
+ ITState = 0;
+ else {
+ unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
+ SetBits32(ITState, 4, 0, NewITState4_0);
+ }
}
// Return true if we're inside an IT Block.
-bool ITSession::InITBlock()
-{
- return ITCounter != 0;
-}
+bool ITSession::InITBlock() { return ITCounter != 0; }
// Return true if we're the last instruction inside an IT Block.
-bool ITSession::LastInITBlock()
-{
- return ITCounter == 1;
-}
+bool ITSession::LastInITBlock() { return ITCounter == 1; }
// Get condition bits for the current thumb instruction.
-uint32_t ITSession::GetCond()
-{
- if (InITBlock())
- return Bits32(ITState, 7, 4);
- else
- return COND_AL;
+uint32_t ITSession::GetCond() {
+ if (InITBlock())
+ return Bits32(ITState, 7, 4);
+ else
+ return COND_AL;
}
// ARM constants used during decoding
-#define REG_RD 0
-#define LDM_REGLIST 1
-#define SP_REG 13
-#define LR_REG 14
-#define PC_REG 15
-#define PC_REGLIST_BIT 0x8000
-
-#define ARMv4 (1u << 0)
-#define ARMv4T (1u << 1)
-#define ARMv5T (1u << 2)
-#define ARMv5TE (1u << 3)
-#define ARMv5TEJ (1u << 4)
-#define ARMv6 (1u << 5)
-#define ARMv6K (1u << 6)
-#define ARMv6T2 (1u << 7)
-#define ARMv7 (1u << 8)
-#define ARMv7S (1u << 9)
-#define ARMv8 (1u << 10)
-#define ARMvAll (0xffffffffu)
-
-#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
-#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
-#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
-#define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
-#define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
-#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
-#define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8)
-
-#define No_VFP 0
-#define VFPv1 (1u << 1)
-#define VFPv2 (1u << 2)
-#define VFPv3 (1u << 3)
+#define REG_RD 0
+#define LDM_REGLIST 1
+#define SP_REG 13
+#define LR_REG 14
+#define PC_REG 15
+#define PC_REGLIST_BIT 0x8000
+
+#define ARMv4 (1u << 0)
+#define ARMv4T (1u << 1)
+#define ARMv5T (1u << 2)
+#define ARMv5TE (1u << 3)
+#define ARMv5TEJ (1u << 4)
+#define ARMv6 (1u << 5)
+#define ARMv6K (1u << 6)
+#define ARMv6T2 (1u << 7)
+#define ARMv7 (1u << 8)
+#define ARMv7S (1u << 9)
+#define ARMv8 (1u << 10)
+#define ARMvAll (0xffffffffu)
+
+#define ARMV4T_ABOVE \
+ (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \
+ ARMv7S | ARMv8)
+#define ARMV5_ABOVE \
+ (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \
+ ARMv8)
+#define ARMV5TE_ABOVE \
+ (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
+#define ARMV5J_ABOVE \
+ (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
+#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
+#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8)
+#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8)
+
+#define No_VFP 0
+#define VFPv1 (1u << 1)
+#define VFPv2 (1u << 2)
+#define VFPv3 (1u << 3)
#define AdvancedSIMD (1u << 4)
#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
-#define VFPv2v3 (VFPv2 | VFPv3)
+#define VFPv2v3 (VFPv2 | VFPv3)
//----------------------------------------------------------------------
//
@@ -167,200 +160,194 @@ uint32_t ITSession::GetCond()
//
//----------------------------------------------------------------------
-void
-EmulateInstructionARM::Initialize ()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic (),
- GetPluginDescriptionStatic (),
- CreateInstance);
+void EmulateInstructionARM::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-EmulateInstructionARM::Terminate ()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void EmulateInstructionARM::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-ConstString
-EmulateInstructionARM::GetPluginNameStatic ()
-{
- static ConstString g_name("arm");
- return g_name;
+ConstString EmulateInstructionARM::GetPluginNameStatic() {
+ static ConstString g_name("arm");
+ return g_name;
}
-const char *
-EmulateInstructionARM::GetPluginDescriptionStatic ()
-{
- return "Emulate instructions for the ARM architecture.";
+const char *EmulateInstructionARM::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the ARM architecture.";
}
EmulateInstruction *
-EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
-{
- if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
- {
- if (arch.GetTriple().getArch() == llvm::Triple::arm)
- {
- std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
-
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
- else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
- {
- std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
-
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
+EmulateInstructionARM::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::arm) {
+ std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
+ new EmulateInstructionARM(arch));
+
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
+ } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) {
+ std::unique_ptr<EmulateInstructionARM> emulate_insn_ap(
+ new EmulateInstructionARM(arch));
+
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
}
-
- return NULL;
-}
+ }
-bool
-EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
-{
- if (arch.GetTriple().getArch () == llvm::Triple::arm)
- return true;
- else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
- return true;
-
- return false;
+ return NULL;
}
-
-// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions.
-bool
-EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
-{
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
- context.SetNoArgs ();
- uint32_t random_data = rand ();
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- if (!MemAWrite (context, address, random_data, addr_byte_size))
- return false;
-
+bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::arm)
return true;
+ else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
+ return true;
+
+ return false;
}
-// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions.
-bool
-EmulateInstructionARM::WriteBits32Unknown (int n)
-{
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
- context.SetNoArgs ();
+// Write "bits (32) UNKNOWN" to memory address "address". Helper function for
+// many ARM instructions.
+bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
+ context.SetNoArgs();
- bool success;
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
-
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
- return false;
-
- return true;
-}
+ uint32_t random_data = rand();
+ const uint32_t addr_byte_size = GetAddressByteSize();
-bool
-EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
-{
- if (reg_kind == eRegisterKindGeneric)
- {
- switch (reg_num)
- {
- case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
- case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
- case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
- case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
- case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
- default: return false;
- }
- }
-
- if (reg_kind == eRegisterKindDWARF)
- return GetARMDWARFRegisterInfo(reg_num, reg_info);
+ if (!MemAWrite(context, address, random_data, addr_byte_size))
return false;
+
+ return true;
}
-uint32_t
-EmulateInstructionARM::GetFramePointerRegisterNumber () const
-{
- if (m_arch.GetTriple().isAndroid())
- return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
- bool is_apple = false;
- if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
- is_apple = true;
- switch (m_arch.GetTriple().getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- is_apple = true;
- break;
- default:
- break;
+// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM
+// instructions.
+bool EmulateInstructionARM::WriteBits32Unknown(int n) {
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
+ context.SetNoArgs();
+
+ bool success;
+ uint32_t data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data))
+ return false;
+
+ return true;
+}
+
+bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_pc;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sp;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r7;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_lr;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_cpsr;
+ break;
+ default:
+ return false;
}
+ }
- /* On Apple iOS et al, the frame pointer register is always r7.
- * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
- */
+ if (reg_kind == eRegisterKindDWARF)
+ return GetARMDWARFRegisterInfo(reg_num, reg_info);
+ return false;
+}
+
+uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
+ if (m_arch.GetTriple().isAndroid())
+ return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
+ bool is_apple = false;
+ if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ is_apple = true;
+ switch (m_arch.GetTriple().getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ is_apple = true;
+ break;
+ default:
+ break;
+ }
+
+ /* On Apple iOS et al, the frame pointer register is always r7.
+ * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
+ */
- uint32_t fp_regnum = 11;
+ uint32_t fp_regnum = 11;
- if (is_apple)
- fp_regnum = 7;
+ if (is_apple)
+ fp_regnum = 7;
- if (m_opcode_mode == eModeThumb)
- fp_regnum = 7;
+ if (m_opcode_mode == eModeThumb)
+ fp_regnum = 7;
- return fp_regnum;
+ return fp_regnum;
}
-uint32_t
-EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
-{
- bool is_apple = false;
- if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
- is_apple = true;
- switch (m_arch.GetTriple().getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- is_apple = true;
- break;
- default:
- break;
- }
+uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const {
+ bool is_apple = false;
+ if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ is_apple = true;
+ switch (m_arch.GetTriple().getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ is_apple = true;
+ break;
+ default:
+ break;
+ }
- /* On Apple iOS et al, the frame pointer register is always r7.
- * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
- */
+ /* On Apple iOS et al, the frame pointer register is always r7.
+ * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
+ */
- uint32_t fp_regnum = dwarf_r11;
+ uint32_t fp_regnum = dwarf_r11;
- if (is_apple)
- fp_regnum = dwarf_r7;
+ if (is_apple)
+ fp_regnum = dwarf_r7;
- if (m_opcode_mode == eModeThumb)
- fp_regnum = dwarf_r7;
+ if (m_opcode_mode == eModeThumb)
+ fp_regnum = dwarf_r7;
- return fp_regnum;
+ return fp_regnum;
}
// Push Multiple Registers stores multiple registers to the stack, storing to
// consecutive memory locations ending just below the address in SP, and updates
// SP to point to the start of the stored data.
-bool
-EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -388,105 +375,101 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc
}
#endif
- bool success = false;
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- uint32_t registers = 0;
- uint32_t Rt; // the source register
- switch (encoding) {
- case eEncodingT1:
- registers = Bits32(opcode, 7, 0);
- // The M bit represents LR.
- if (Bit32(opcode, 8))
- registers |= (1u << 14);
- // if BitCount(registers) < 1 then UNPREDICTABLE;
- if (BitCount(registers) < 1)
- return false;
- break;
- case eEncodingT2:
- // Ignore bits 15 & 13.
- registers = Bits32(opcode, 15, 0) & ~0xa000;
- // if BitCount(registers) < 2 then UNPREDICTABLE;
- if (BitCount(registers) < 2)
- return false;
- break;
- case eEncodingT3:
- Rt = Bits32(opcode, 15, 12);
- // if BadReg(t) then UNPREDICTABLE;
- if (BadReg(Rt))
- return false;
- registers = (1u << Rt);
- break;
- case eEncodingA1:
- registers = Bits32(opcode, 15, 0);
- // Instead of return false, let's handle the following case as well,
- // which amounts to pushing one reg onto the full descending stacks.
- // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
- break;
- case eEncodingA2:
- Rt = Bits32(opcode, 15, 12);
- // if t == 13 then UNPREDICTABLE;
- if (Rt == dwarf_sp)
- return false;
- registers = (1u << Rt);
- break;
- default:
- return false;
- }
- addr_t sp_offset = addr_byte_size * BitCount (registers);
- addr_t addr = sp - sp_offset;
- uint32_t i;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPushRegisterOnStack;
- RegisterInfo reg_info;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- for (i=0; i<15; ++i)
- {
- if (BitIsSet (registers, i))
- {
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
- context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
- uint32_t reg_value = ReadCoreReg(i, &success);
- if (!success)
- return false;
- if (!MemAWrite (context, addr, reg_value, addr_byte_size))
- return false;
- addr += addr_byte_size;
- }
- }
-
- if (BitIsSet (registers, 15))
- {
- GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
- context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
- if (!MemAWrite (context, addr, pc, addr_byte_size))
- return false;
- }
-
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (-sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
- return false;
+ bool success = false;
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t registers = 0;
+ uint32_t Rt; // the source register
+ switch (encoding) {
+ case eEncodingT1:
+ registers = Bits32(opcode, 7, 0);
+ // The M bit represents LR.
+ if (Bit32(opcode, 8))
+ registers |= (1u << 14);
+ // if BitCount(registers) < 1 then UNPREDICTABLE;
+ if (BitCount(registers) < 1)
+ return false;
+ break;
+ case eEncodingT2:
+ // Ignore bits 15 & 13.
+ registers = Bits32(opcode, 15, 0) & ~0xa000;
+ // if BitCount(registers) < 2 then UNPREDICTABLE;
+ if (BitCount(registers) < 2)
+ return false;
+ break;
+ case eEncodingT3:
+ Rt = Bits32(opcode, 15, 12);
+ // if BadReg(t) then UNPREDICTABLE;
+ if (BadReg(Rt))
+ return false;
+ registers = (1u << Rt);
+ break;
+ case eEncodingA1:
+ registers = Bits32(opcode, 15, 0);
+ // Instead of return false, let's handle the following case as well,
+ // which amounts to pushing one reg onto the full descending stacks.
+ // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
+ break;
+ case eEncodingA2:
+ Rt = Bits32(opcode, 15, 12);
+ // if t == 13 then UNPREDICTABLE;
+ if (Rt == dwarf_sp)
+ return false;
+ registers = (1u << Rt);
+ break;
+ default:
+ return false;
}
- return true;
+ addr_t sp_offset = addr_byte_size * BitCount(registers);
+ addr_t addr = sp - sp_offset;
+ uint32_t i;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextPushRegisterOnStack;
+ RegisterInfo reg_info;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ for (i = 0; i < 15; ++i) {
+ if (BitIsSet(registers, i)) {
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info);
+ context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
+ uint32_t reg_value = ReadCoreReg(i, &success);
+ if (!success)
+ return false;
+ if (!MemAWrite(context, addr, reg_value, addr_byte_size))
+ return false;
+ addr += addr_byte_size;
+ }
+ }
+
+ if (BitIsSet(registers, 15)) {
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info);
+ context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+ if (!MemAWrite(context, addr, pc, addr_byte_size))
+ return false;
+ }
+
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ context.SetImmediateSigned(-sp_offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
+ return false;
+ }
+ return true;
}
// Pop Multiple Registers loads multiple registers from the stack, loading from
// consecutive memory locations staring at the address in SP, and updates
// SP to point just above the loaded data.
-bool
-EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -506,115 +489,115 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadCoreReg (SP_REG, &success);
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t registers = 0;
+ uint32_t Rt; // the destination register
+ switch (encoding) {
+ case eEncodingT1:
+ registers = Bits32(opcode, 7, 0);
+ // The P bit represents PC.
+ if (Bit32(opcode, 8))
+ registers |= (1u << 15);
+ // if BitCount(registers) < 1 then UNPREDICTABLE;
+ if (BitCount(registers) < 1)
+ return false;
+ break;
+ case eEncodingT2:
+ // Ignore bit 13.
+ registers = Bits32(opcode, 15, 0) & ~0x2000;
+ // if BitCount(registers) < 2 || (P == '1' && M == '1') then
+ // UNPREDICTABLE;
+ if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
+ return false;
+ // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
+ // UNPREDICTABLE;
+ if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ case eEncodingT3:
+ Rt = Bits32(opcode, 15, 12);
+ // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then
+ // UNPREDICTABLE;
+ if (Rt == 13)
+ return false;
+ if (Rt == 15 && InITBlock() && !LastInITBlock())
+ return false;
+ registers = (1u << Rt);
+ break;
+ case eEncodingA1:
+ registers = Bits32(opcode, 15, 0);
+ // Instead of return false, let's handle the following case as well,
+ // which amounts to popping one reg from the full descending stacks.
+ // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
+
+ // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
+ if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
+ return false;
+ break;
+ case eEncodingA2:
+ Rt = Bits32(opcode, 15, 12);
+ // if t == 13 then UNPREDICTABLE;
+ if (Rt == dwarf_sp)
+ return false;
+ registers = (1u << Rt);
+ break;
+ default:
+ return false;
+ }
+ addr_t sp_offset = addr_byte_size * BitCount(registers);
+ addr_t addr = sp;
+ uint32_t i, data;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextPopRegisterOffStack;
+
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+
+ for (i = 0; i < 15; ++i) {
+ if (BitIsSet(registers, i)) {
+ context.SetAddress(addr);
+ data = MemARead(context, addr, 4, 0, &success);
if (!success)
- return false;
- uint32_t registers = 0;
- uint32_t Rt; // the destination register
- switch (encoding) {
- case eEncodingT1:
- registers = Bits32(opcode, 7, 0);
- // The P bit represents PC.
- if (Bit32(opcode, 8))
- registers |= (1u << 15);
- // if BitCount(registers) < 1 then UNPREDICTABLE;
- if (BitCount(registers) < 1)
- return false;
- break;
- case eEncodingT2:
- // Ignore bit 13.
- registers = Bits32(opcode, 15, 0) & ~0x2000;
- // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
- if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
- return false;
- // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
- return false;
- break;
- case eEncodingT3:
- Rt = Bits32(opcode, 15, 12);
- // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
- if (Rt == 13)
- return false;
- if (Rt == 15 && InITBlock() && !LastInITBlock())
- return false;
- registers = (1u << Rt);
- break;
- case eEncodingA1:
- registers = Bits32(opcode, 15, 0);
- // Instead of return false, let's handle the following case as well,
- // which amounts to popping one reg from the full descending stacks.
- // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
-
- // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
- if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
- return false;
- break;
- case eEncodingA2:
- Rt = Bits32(opcode, 15, 12);
- // if t == 13 then UNPREDICTABLE;
- if (Rt == dwarf_sp)
- return false;
- registers = (1u << Rt);
- break;
- default:
- return false;
- }
- addr_t sp_offset = addr_byte_size * BitCount (registers);
- addr_t addr = sp;
- uint32_t i, data;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPopRegisterOffStack;
-
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
+ return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
+ data))
+ return false;
+ addr += addr_byte_size;
+ }
+ }
- for (i=0; i<15; ++i)
- {
- if (BitIsSet (registers, i))
- {
- context.SetAddress(addr);
- data = MemARead(context, addr, 4, 0, &success);
- if (!success)
- return false;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
- return false;
- addr += addr_byte_size;
- }
- }
-
- if (BitIsSet (registers, 15))
- {
- context.SetRegisterPlusOffset (sp_reg, addr - sp);
- data = MemARead(context, addr, 4, 0, &success);
- if (!success)
- return false;
- // In ARMv5T and above, this is an interworking branch.
- if (!LoadWritePC(context, data))
- return false;
- //addr += addr_byte_size;
- }
-
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
- return false;
+ if (BitIsSet(registers, 15)) {
+ context.SetRegisterPlusOffset(sp_reg, addr - sp);
+ data = MemARead(context, addr, 4, 0, &success);
+ if (!success)
+ return false;
+ // In ARMv5T and above, this is an interworking branch.
+ if (!LoadWritePC(context, data))
+ return false;
+ // addr += addr_byte_size;
}
- return true;
+
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ context.SetImmediateSigned(sp_offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
+ return false;
+ }
+ return true;
}
// Set r7 or ip to point to saved value residing within the stack.
// ADD (SP plus immediate)
-bool
-EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -633,50 +616,49 @@ EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncodi
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- uint32_t Rd; // the destination register
- uint32_t imm32;
- switch (encoding) {
- case eEncodingT1:
- Rd = 7;
- imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
- break;
- default:
- return false;
- }
- addr_t sp_offset = imm32;
- addr_t addr = sp + sp_offset; // a pointer to the stack area
-
- EmulateInstruction::Context context;
- if (Rd == GetFramePointerRegisterNumber())
- context.type = eContextSetFramePointer;
- else
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- context.SetRegisterPlusOffset (sp_reg, sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
- return false;
+ if (ConditionPassed(opcode)) {
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t Rd; // the destination register
+ uint32_t imm32;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = 7;
+ imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+ break;
+ default:
+ return false;
}
- return true;
+ addr_t sp_offset = imm32;
+ addr_t addr = sp + sp_offset; // a pointer to the stack area
+
+ EmulateInstruction::Context context;
+ if (Rd == GetFramePointerRegisterNumber())
+ context.type = eContextSetFramePointer;
+ else
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ context.SetRegisterPlusOffset(sp_reg, sp_offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd,
+ addr))
+ return false;
+ }
+ return true;
}
// Set r7 or ip to the current stack pointer.
// MOV (register)
-bool
-EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -695,53 +677,50 @@ EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- uint32_t Rd; // the destination register
- switch (encoding) {
- case eEncodingT1:
- Rd = 7;
- break;
- case eEncodingA1:
- Rd = 12;
- break;
- default:
- return false;
- }
-
- EmulateInstruction::Context context;
- if (Rd == GetFramePointerRegisterNumber())
- context.type = EmulateInstruction::eContextSetFramePointer;
- else
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- context.SetRegisterPlusOffset (sp_reg, 0);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
- return false;
+ if (ConditionPassed(opcode)) {
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t Rd; // the destination register
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = 7;
+ break;
+ case eEncodingA1:
+ Rd = 12;
+ break;
+ default:
+ return false;
}
- return true;
+
+ EmulateInstruction::Context context;
+ if (Rd == GetFramePointerRegisterNumber())
+ context.type = EmulateInstruction::eContextSetFramePointer;
+ else
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ context.SetRegisterPlusOffset(sp_reg, 0);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
+ return false;
+ }
+ return true;
}
// Move from high register (r8-r15) to low register (r0-r7).
// MOV (register)
-bool
-EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
-{
- return EmulateMOVRdRm (opcode, encoding);
+bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode,
+ const ARMEncoding encoding) {
+ return EmulateMOVRdRm(opcode, encoding);
}
// Move from register to register.
// MOV (register)
-bool
-EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -760,77 +739,77 @@ EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rm; // the source register
- uint32_t Rd; // the destination register
- bool setflags;
- switch (encoding) {
- case eEncodingT1:
- Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 6, 3);
- setflags = false;
- if (Rd == 15 && InITBlock() && !LastInITBlock())
- return false;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = true;
- if (InITBlock())
- return false;
- break;
- case eEncodingT3:
- Rd = Bits32(opcode, 11, 8);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
- if (setflags && (BadReg(Rd) || BadReg(Rm)))
- return false;
- // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
- if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- uint32_t result = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ if (ConditionPassed(opcode)) {
+ uint32_t Rm; // the source register
+ uint32_t Rd; // the destination register
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 6, 3);
+ setflags = false;
+ if (Rd == 15 && InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = true;
+ if (InITBlock())
+ return false;
+ break;
+ case eEncodingT3:
+ Rd = Bits32(opcode, 11, 8);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
+ if (setflags && (BadReg(Rd) || BadReg(Rm)))
+ return false;
+ // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then
+ // UNPREDICTABLE;
+ if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ uint32_t result = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // The context specifies that Rm is to be moved into Rd.
- EmulateInstruction::Context context;
- if (Rd == 13)
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- else
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, 0);
+ // The context specifies that Rm is to be moved into Rd.
+ EmulateInstruction::Context context;
+ if (Rd == 13)
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ else
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, 0);
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
+ return false;
+ }
+ return true;
}
// Move (immediate) writes an immediate value to the destination register. It
// can optionally update the condition flags based on the value.
// MOV (immediate)
-bool
-EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -849,101 +828,102 @@ EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding
}
#endif
- if (ConditionPassed(opcode))
- {
- uint32_t Rd; // the destination register
- uint32_t imm32; // the immediate value to be written to Rd
- uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
- // for setflags == false, this value is a don't care
- // initialized to 0 to silence the static analyzer
- bool setflags;
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 10, 8);
- setflags = !InITBlock();
- imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
- carry = APSR_C;
-
- break;
-
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
- if (BadReg(Rd))
- return false;
-
- break;
-
- case eEncodingT3:
- {
- // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
- Rd = Bits32 (opcode, 11, 8);
- setflags = false;
- uint32_t imm4 = Bits32 (opcode, 19, 16);
- uint32_t imm3 = Bits32 (opcode, 14, 12);
- uint32_t i = Bit32 (opcode, 26);
- uint32_t imm8 = Bits32 (opcode, 7, 0);
- imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
-
- // if BadReg(d) then UNPREDICTABLE;
- if (BadReg (Rd))
- return false;
- }
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
- Rd = Bits32 (opcode, 15, 12);
- setflags = BitIsSet (opcode, 20);
- imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if ((Rd == 15) && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
-
- break;
-
- case eEncodingA2:
- {
- // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
- Rd = Bits32 (opcode, 15, 12);
- setflags = false;
- uint32_t imm4 = Bits32 (opcode, 19, 16);
- uint32_t imm12 = Bits32 (opcode, 11, 0);
- imm32 = (imm4 << 12) | imm12;
-
- // if d == 15 then UNPREDICTABLE;
- if (Rd == 15)
- return false;
- }
- break;
-
- default:
- return false;
- }
- uint32_t result = imm32;
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd; // the destination register
+ uint32_t imm32; // the immediate value to be written to Rd
+ uint32_t carry =
+ 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
+ // for setflags == false, this value is a don't care
+ // initialized to 0 to silence the static analyzer
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 10, 8);
+ setflags = !InITBlock();
+ imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
+ carry = APSR_C;
- // The context specifies that an immediate is to be moved into Rd.
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ break;
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
+ if (BadReg(Rd))
+ return false;
+
+ break;
+
+ case eEncodingT3: {
+ // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8,
+ // 32);
+ Rd = Bits32(opcode, 11, 8);
+ setflags = false;
+ uint32_t imm4 = Bits32(opcode, 19, 16);
+ uint32_t imm3 = Bits32(opcode, 14, 12);
+ uint32_t i = Bit32(opcode, 26);
+ uint32_t imm8 = Bits32(opcode, 7, 0);
+ imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
+
+ // if BadReg(d) then UNPREDICTABLE;
+ if (BadReg(Rd))
+ return false;
+ } break;
+
+ case eEncodingA1:
+ // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) =
+ // ARMExpandImm_C(imm12, APSR.C);
+ Rd = Bits32(opcode, 15, 12);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if ((Rd == 15) && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+
+ break;
+
+ case eEncodingA2: {
+ // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
+ Rd = Bits32(opcode, 15, 12);
+ setflags = false;
+ uint32_t imm4 = Bits32(opcode, 19, 16);
+ uint32_t imm12 = Bits32(opcode, 11, 0);
+ imm32 = (imm4 << 12) | imm12;
+
+ // if d == 15 then UNPREDICTABLE;
+ if (Rd == 15)
+ return false;
+ } break;
+
+ default:
+ return false;
}
- return true;
+ uint32_t result = imm32;
+
+ // The context specifies that an immediate is to be moved into Rd.
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// MUL multiplies two register values. The least significant 32 bits of the result are written to the destination
-// register. These 32 bits do not depend on whether the source register values are considered to be signed values or
+// MUL multiplies two register values. The least significant 32 bits of the
+// result are written to the destination
+// register. These 32 bits do not depend on whether the source register values
+// are considered to be signed values or
// unsigned values.
//
-// Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is
+// Optionally, it can update the condition flags based on the result. In the
+// Thumb instruction set, this option is
// limited to only a few forms of the instruction.
-bool
-EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -959,118 +939,120 @@ EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding enco
// else APSR.C unchanged
// APSR.V always unchanged
#endif
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t n;
- uint32_t m;
- bool setflags;
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
- d = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 2, 0);
- setflags = !InITBlock();
-
- // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
- if ((ArchVersion() < ARMv6) && (d == n))
- return false;
-
- break;
-
- case eEncodingT2:
- // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
- d = Bits32 (opcode, 11, 8);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
- setflags = false;
-
- // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
- if (BadReg (d) || BadReg (n) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
- d = Bits32 (opcode, 19, 16);
- n = Bits32 (opcode, 3, 0);
- m = Bits32 (opcode, 11, 8);
- setflags = BitIsSet (opcode, 20);
-
- // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
- if ((d == 15) || (n == 15) || (m == 15))
- return false;
-
- // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
- if ((ArchVersion() < ARMv6) && (d == n))
- return false;
-
- break;
-
- default:
- return false;
- }
- bool success = false;
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ bool setflags;
- // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
- uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
- uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- // result = operand1 * operand2;
- uint64_t result = operand1 * operand2;
-
- // R[d] = result<31:0>;
- RegisterInfo op1_reg;
- RegisterInfo op2_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- context.SetRegisterRegisterOperands (op1_reg, op2_reg);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
- return false;
-
- // if setflags then
- if (setflags)
- {
- // APSR.N = result<31>;
- // APSR.Z = IsZeroBit(result);
- m_new_inst_cpsr = m_opcode_cpsr;
- SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
- SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
- if (m_new_inst_cpsr != m_opcode_cpsr)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
- return false;
- }
-
- // if ArchVersion() == 4 then
- // APSR.C = bit UNKNOWN;
- }
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
+ d = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 2, 0);
+ setflags = !InITBlock();
+
+ // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
+ if ((ArchVersion() < ARMv6) && (d == n))
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
+ d = Bits32(opcode, 11, 8);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+ setflags = false;
+
+ // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
+ if (BadReg(d) || BadReg(n) || BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
+ d = Bits32(opcode, 19, 16);
+ n = Bits32(opcode, 3, 0);
+ m = Bits32(opcode, 11, 8);
+ setflags = BitIsSet(opcode, 20);
+
+ // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
+ if ((d == 15) || (n == 15) || (m == 15))
+ return false;
+
+ // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
+ if ((ArchVersion() < ARMv6) && (d == n))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
-}
-
-// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
+
+ bool success = false;
+
+ // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final
+ // results
+ uint64_t operand1 =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final
+ // results
+ uint64_t operand2 =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ // result = operand1 * operand2;
+ uint64_t result = operand1 * operand2;
+
+ // R[d] = result<31:0>;
+ RegisterInfo op1_reg;
+ RegisterInfo op2_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextArithmetic;
+ context.SetRegisterRegisterOperands(op1_reg, op2_reg);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
+ (0x0000ffff & result)))
+ return false;
+
+ // if setflags then
+ if (setflags) {
+ // APSR.N = result<31>;
+ // APSR.Z = IsZeroBit(result);
+ m_new_inst_cpsr = m_opcode_cpsr;
+ SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31));
+ SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
+ if (m_new_inst_cpsr != m_opcode_cpsr) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
+ return false;
+ }
+
+ // if ArchVersion() == 4 then
+ // APSR.C = bit UNKNOWN;
+ }
+ }
+ return true;
+}
+
+// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to
+// the destination register.
// It can optionally update the condition flags based on the value.
-bool
-EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1089,48 +1071,48 @@ EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding e
}
#endif
- if (ConditionPassed(opcode))
- {
- uint32_t Rd; // the destination register
- uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
- uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
- bool setflags;
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- uint32_t result = ~imm32;
-
- // The context specifies that an immediate is to be moved into Rd.
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
-
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd; // the destination register
+ uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
+ uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
}
- return true;
+ uint32_t result = ~imm32;
+
+ // The context specifies that an immediate is to be moved into Rd.
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
+// Bitwise NOT (register) writes the bitwise inverse of a register value to the
+// destination register.
// It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1150,68 +1132,68 @@ EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding e
}
#endif
- if (ConditionPassed(opcode))
- {
- uint32_t Rm; // the source register
- uint32_t Rd; // the destination register
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- bool setflags;
- uint32_t carry; // the carry bit after the shift operation
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- if (InITBlock())
- return false;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
- if (BadReg(Rd) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
- break;
- default:
- return false;
- }
- bool success = false;
- uint32_t value = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ if (ConditionPassed(opcode)) {
+ uint32_t Rm; // the source register
+ uint32_t Rd; // the destination register
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ bool setflags;
+ uint32_t carry; // the carry bit after the shift operation
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ if (InITBlock())
+ return false;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
+ if (BadReg(Rd) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+ break;
+ default:
+ return false;
+ }
+ bool success = false;
+ uint32_t value = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
- if (!success)
- return false;
- uint32_t result = ~shifted;
-
- // The context specifies that an immediate is to be moved into Rd.
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ uint32_t shifted =
+ Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
+ if (!success)
+ return false;
+ uint32_t result = ~shifted;
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ // The context specifies that an immediate is to be moved into Rd.
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// PC relative immediate load into register, possibly followed by ADD (SP plus register).
+// PC relative immediate load into register, possibly followed by ADD (SP plus
+// register).
// LDR (literal)
-bool
-EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1232,82 +1214,74 @@ EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARME
}
#endif
- if (ConditionPassed(opcode))
- {
- bool success = false;
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
-
- // PC relative immediate load context
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo pc_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
- context.SetRegisterPlusOffset (pc_reg, 0);
-
- uint32_t Rt; // the destination register
- uint32_t imm32; // immediate offset from the PC
- bool add; // +imm32 or -imm32?
- addr_t base; // the base address
- addr_t address; // the PC relative address
- uint32_t data; // the literal data value from the PC relative load
- switch (encoding) {
- case eEncodingT1:
- Rt = Bits32(opcode, 10, 8);
- imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
- add = true;
- break;
- case eEncodingT2:
- Rt = Bits32(opcode, 15, 12);
- imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
- add = BitIsSet(opcode, 23);
- if (Rt == 15 && InITBlock() && !LastInITBlock())
- return false;
- break;
- default:
- return false;
- }
-
- base = Align(pc, 4);
- if (add)
- address = base + imm32;
- else
- address = base - imm32;
+ if (ConditionPassed(opcode)) {
+ bool success = false;
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
- context.SetRegisterPlusOffset(pc_reg, address - base);
- data = MemURead(context, address, 4, 0, &success);
- if (!success)
- return false;
+ // PC relative immediate load context
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo pc_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
+ context.SetRegisterPlusOffset(pc_reg, 0);
+
+ uint32_t Rt; // the destination register
+ uint32_t imm32; // immediate offset from the PC
+ bool add; // +imm32 or -imm32?
+ addr_t base; // the base address
+ addr_t address; // the PC relative address
+ uint32_t data; // the literal data value from the PC relative load
+ switch (encoding) {
+ case eEncodingT1:
+ Rt = Bits32(opcode, 10, 8);
+ imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
+ add = true;
+ break;
+ case eEncodingT2:
+ Rt = Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
+ add = BitIsSet(opcode, 23);
+ if (Rt == 15 && InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ default:
+ return false;
+ }
- if (Rt == 15)
- {
- if (Bits32(address, 1, 0) == 0)
- {
- // In ARMv5T and above, this is an interworking branch.
- if (!LoadWritePC(context, data))
- return false;
- }
- else
- return false;
- }
- else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
- return false;
- }
- else // We don't handle ARM for now.
- return false;
+ base = Align(pc, 4);
+ if (add)
+ address = base + imm32;
+ else
+ address = base - imm32;
- }
- return true;
+ context.SetRegisterPlusOffset(pc_reg, address - base);
+ data = MemURead(context, address, 4, 0, &success);
+ if (!success)
+ return false;
+
+ if (Rt == 15) {
+ if (Bits32(address, 1, 0) == 0) {
+ // In ARMv5T and above, this is an interworking branch.
+ if (!LoadWritePC(context, data))
+ return false;
+ } else
+ return false;
+ } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
+ data))
+ return false;
+ } else // We don't handle ARM for now.
+ return false;
+ }
+ return true;
}
// An add operation to adjust the SP.
// ADD (SP plus immediate)
-bool
-EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1326,105 +1300,99 @@ EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- uint32_t imm32; // the immediate operand
- uint32_t d;
- bool setflags;
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
- d = Bits32 (opcode, 10, 8);
- imm32 = (Bits32 (opcode, 7, 0) << 2);
- setflags = false;
- break;
-
- case eEncodingT2:
- // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
- d = 13;
- imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32)
- setflags = false;
- break;
-
- case eEncodingT3:
- // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8);
- d = Bits32 (opcode, 11, 8);
- imm32 = ThumbExpandImm (opcode);
- setflags = Bit32 (opcode, 20);
-
- // if Rd == "1111" && S == "1" then SEE CMN (immediate);
- if (d == 15 && setflags == 1)
- return false; // CMN (immediate) not yet supported
-
- // if d == 15 && S == "0" then UNPREDICTABLE;
- if (d == 15 && setflags == 0)
- return false;
- break;
-
- case eEncodingT4:
- {
- // if Rn == '1111' then SEE ADR;
- // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
- d = Bits32 (opcode, 11, 8);
- setflags = false;
- uint32_t i = Bit32 (opcode, 26);
- uint32_t imm3 = Bits32 (opcode, 14, 12);
- uint32_t imm8 = Bits32 (opcode, 7, 0);
- imm32 = (i << 11) | (imm3 << 8) | imm8;
-
- // if d == 15 then UNPREDICTABLE;
- if (d == 15)
- return false;
- }
- break;
+ if (ConditionPassed(opcode)) {
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t imm32; // the immediate operand
+ uint32_t d;
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
+ d = Bits32(opcode, 10, 8);
+ imm32 = (Bits32(opcode, 7, 0) << 2);
+ setflags = false;
+ break;
- default:
- return false;
- }
- // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
- AddWithCarryResult res = AddWithCarry (sp, imm32, 0);
+ case eEncodingT2:
+ // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
+ d = 13;
+ imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
+ setflags = false;
+ break;
- EmulateInstruction::Context context;
- if (d == 13)
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- else
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ case eEncodingT3:
+ // d = UInt(Rd); setflags = (S == "1"); imm32 =
+ // ThumbExpandImm(i:imm3:imm8);
+ d = Bits32(opcode, 11, 8);
+ imm32 = ThumbExpandImm(opcode);
+ setflags = Bit32(opcode, 20);
+
+ // if Rd == "1111" && S == "1" then SEE CMN (immediate);
+ if (d == 15 && setflags == 1)
+ return false; // CMN (immediate) not yet supported
+
+ // if d == 15 && S == "0" then UNPREDICTABLE;
+ if (d == 15 && setflags == 0)
+ return false;
+ break;
+
+ case eEncodingT4: {
+ // if Rn == '1111' then SEE ADR;
+ // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
+ d = Bits32(opcode, 11, 8);
+ setflags = false;
+ uint32_t i = Bit32(opcode, 26);
+ uint32_t imm3 = Bits32(opcode, 14, 12);
+ uint32_t imm8 = Bits32(opcode, 7, 0);
+ imm32 = (i << 11) | (imm3 << 8) | imm8;
+
+ // if d == 15 then UNPREDICTABLE;
+ if (d == 15)
+ return false;
+ } break;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- context.SetRegisterPlusOffset (sp_reg, res.result - sp);
+ default:
+ return false;
+ }
+ // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
+ AddWithCarryResult res = AddWithCarry(sp, imm32, 0);
- if (d == 15)
- {
- if (!ALUWritePC (context, res.result))
- return false;
- }
- else
- {
- // R[d] = result;
- // if setflags then
- // APSR.N = result<31>;
- // APSR.Z = IsZeroBit(result);
- // APSR.C = carry;
- // APSR.V = overflow;
- if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
- return false;
- }
+ EmulateInstruction::Context context;
+ if (d == 13)
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ else
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ context.SetRegisterPlusOffset(sp_reg, res.result - sp);
+
+ if (d == 15) {
+ if (!ALUWritePC(context, res.result))
+ return false;
+ } else {
+ // R[d] = result;
+ // if setflags then
+ // APSR.N = result<31>;
+ // APSR.Z = IsZeroBit(result);
+ // APSR.C = carry;
+ // APSR.V = overflow;
+ if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
+ res.carry_out, res.overflow))
+ return false;
}
- return true;
+ }
+ return true;
}
// An add operation to adjust the SP.
// ADD (SP plus register)
-bool
-EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1444,49 +1412,48 @@ EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- uint32_t Rm; // the second operand
- switch (encoding) {
- case eEncodingT2:
- Rm = Bits32(opcode, 6, 3);
- break;
- default:
- return false;
- }
- int32_t reg_value = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
-
- addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
-
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
-
- RegisterInfo other_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
- context.SetRegisterRegisterOperands (sp_reg, other_reg);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
- return false;
+ if (ConditionPassed(opcode)) {
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t Rm; // the second operand
+ switch (encoding) {
+ case eEncodingT2:
+ Rm = Bits32(opcode, 6, 3);
+ break;
+ default:
+ return false;
}
- return true;
+ int32_t reg_value = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
+
+ addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
+
+ EmulateInstruction::Context context;
+ context.type = eContextArithmetic;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+
+ RegisterInfo other_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
+ context.SetRegisterRegisterOperands(sp_reg, other_reg);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP, addr))
+ return false;
+ }
+ return true;
}
// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
// at a PC-relative address, and changes instruction set from ARM to Thumb, or
// from Thumb to ARM.
// BLX (immediate)
-bool
-EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1505,91 +1472,92 @@ EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEnco
}
#endif
- bool success = true;
+ bool success = true;
- if (ConditionPassed(opcode))
- {
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
- addr_t lr; // next instruction address
- addr_t target; // target address
- int32_t imm32; // PC-relative offset
- switch (encoding) {
- case eEncodingT1:
- {
- lr = pc | 1u; // return address
- uint32_t S = Bit32(opcode, 26);
- uint32_t imm10 = Bits32(opcode, 25, 16);
- uint32_t J1 = Bit32(opcode, 13);
- uint32_t J2 = Bit32(opcode, 11);
- uint32_t imm11 = Bits32(opcode, 10, 0);
- uint32_t I1 = !(J1 ^ S);
- uint32_t I2 = !(J2 ^ S);
- uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
- imm32 = llvm::SignExtend32<25>(imm25);
- target = pc + imm32;
- SelectInstrSet (eModeThumb);
- context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
- if (InITBlock() && !LastInITBlock())
- return false;
- break;
- }
- case eEncodingT2:
- {
- lr = pc | 1u; // return address
- uint32_t S = Bit32(opcode, 26);
- uint32_t imm10H = Bits32(opcode, 25, 16);
- uint32_t J1 = Bit32(opcode, 13);
- uint32_t J2 = Bit32(opcode, 11);
- uint32_t imm10L = Bits32(opcode, 10, 1);
- uint32_t I1 = !(J1 ^ S);
- uint32_t I2 = !(J2 ^ S);
- uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
- imm32 = llvm::SignExtend32<25>(imm25);
- target = Align(pc, 4) + imm32;
- SelectInstrSet (eModeARM);
- context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
- if (InITBlock() && !LastInITBlock())
- return false;
- break;
- }
- case eEncodingA1:
- lr = pc - 4; // return address
- imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
- target = Align(pc, 4) + imm32;
- SelectInstrSet (eModeARM);
- context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
- break;
- case eEncodingA2:
- lr = pc - 4; // return address
- imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
- target = pc + imm32;
- SelectInstrSet (eModeThumb);
- context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
- break;
- default:
- return false;
- }
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
- return false;
- if (!BranchWritePC(context, target))
- return false;
- if (m_opcode_cpsr != m_new_inst_cpsr)
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
- return false;
+ if (ConditionPassed(opcode)) {
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+ addr_t lr; // next instruction address
+ addr_t target; // target address
+ int32_t imm32; // PC-relative offset
+ switch (encoding) {
+ case eEncodingT1: {
+ lr = pc | 1u; // return address
+ uint32_t S = Bit32(opcode, 26);
+ uint32_t imm10 = Bits32(opcode, 25, 16);
+ uint32_t J1 = Bit32(opcode, 13);
+ uint32_t J2 = Bit32(opcode, 11);
+ uint32_t imm11 = Bits32(opcode, 10, 0);
+ uint32_t I1 = !(J1 ^ S);
+ uint32_t I2 = !(J2 ^ S);
+ uint32_t imm25 =
+ (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
+ imm32 = llvm::SignExtend32<25>(imm25);
+ target = pc + imm32;
+ SelectInstrSet(eModeThumb);
+ context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
+ if (InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ }
+ case eEncodingT2: {
+ lr = pc | 1u; // return address
+ uint32_t S = Bit32(opcode, 26);
+ uint32_t imm10H = Bits32(opcode, 25, 16);
+ uint32_t J1 = Bit32(opcode, 13);
+ uint32_t J2 = Bit32(opcode, 11);
+ uint32_t imm10L = Bits32(opcode, 10, 1);
+ uint32_t I1 = !(J1 ^ S);
+ uint32_t I2 = !(J2 ^ S);
+ uint32_t imm25 =
+ (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
+ imm32 = llvm::SignExtend32<25>(imm25);
+ target = Align(pc, 4) + imm32;
+ SelectInstrSet(eModeARM);
+ context.SetISAAndImmediateSigned(eModeARM, 4 + imm32);
+ if (InITBlock() && !LastInITBlock())
+ return false;
+ break;
}
- return true;
+ case eEncodingA1:
+ lr = pc - 4; // return address
+ imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
+ target = Align(pc, 4) + imm32;
+ SelectInstrSet(eModeARM);
+ context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
+ break;
+ case eEncodingA2:
+ lr = pc - 4; // return address
+ imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 |
+ Bits32(opcode, 24, 24) << 1);
+ target = pc + imm32;
+ SelectInstrSet(eModeThumb);
+ context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32);
+ break;
+ default:
+ return false;
+ }
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA, lr))
+ return false;
+ if (!BranchWritePC(context, target))
+ return false;
+ if (m_opcode_cpsr != m_new_inst_cpsr)
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
+ return false;
+ }
+ return true;
}
// Branch with Link and Exchange (register) calls a subroutine at an address and
// instruction set specified by a register.
// BLX (register)
-bool
-EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1606,55 +1574,55 @@ EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding en
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- addr_t lr; // next instruction address
- if (!success)
- return false;
- uint32_t Rm; // the register with the target address
- switch (encoding) {
- case eEncodingT1:
- lr = (pc - 2) | 1u; // return address
- Rm = Bits32(opcode, 6, 3);
- // if m == 15 then UNPREDICTABLE;
- if (Rm == 15)
- return false;
- if (InITBlock() && !LastInITBlock())
- return false;
- break;
- case eEncodingA1:
- lr = pc - 4; // return address
- Rm = Bits32(opcode, 3, 0);
- // if m == 15 then UNPREDICTABLE;
- if (Rm == 15)
- return false;
- break;
- default:
- return false;
- }
- addr_t target = ReadCoreReg (Rm, &success);
- if (!success)
- return false;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
- context.SetRegister (dwarf_reg);
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
- return false;
- if (!BXWritePC(context, target))
- return false;
+ if (ConditionPassed(opcode)) {
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ addr_t lr; // next instruction address
+ if (!success)
+ return false;
+ uint32_t Rm; // the register with the target address
+ switch (encoding) {
+ case eEncodingT1:
+ lr = (pc - 2) | 1u; // return address
+ Rm = Bits32(opcode, 6, 3);
+ // if m == 15 then UNPREDICTABLE;
+ if (Rm == 15)
+ return false;
+ if (InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ case eEncodingA1:
+ lr = pc - 4; // return address
+ Rm = Bits32(opcode, 3, 0);
+ // if m == 15 then UNPREDICTABLE;
+ if (Rm == 15)
+ return false;
+ break;
+ default:
+ return false;
}
- return true;
-}
-
-// Branch and Exchange causes a branch to an address and instruction set specified by a register.
-bool
-EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
-{
+ addr_t target = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
+ context.SetRegister(dwarf_reg);
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA, lr))
+ return false;
+ if (!BXWritePC(context, target))
+ return false;
+ }
+ return true;
+}
+
+// Branch and Exchange causes a branch to an address and instruction set
+// specified by a register.
+bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1664,45 +1632,46 @@ EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding enc
}
#endif
- if (ConditionPassed(opcode))
- {
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
- uint32_t Rm; // the register with the target address
- switch (encoding) {
- case eEncodingT1:
- Rm = Bits32(opcode, 6, 3);
- if (InITBlock() && !LastInITBlock())
- return false;
- break;
- case eEncodingA1:
- Rm = Bits32(opcode, 3, 0);
- break;
- default:
- return false;
- }
- bool success = false;
- addr_t target = ReadCoreReg (Rm, &success);
- if (!success)
- return false;
-
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
- context.SetRegister (dwarf_reg);
- if (!BXWritePC(context, target))
- return false;
+ if (ConditionPassed(opcode)) {
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
+ uint32_t Rm; // the register with the target address
+ switch (encoding) {
+ case eEncodingT1:
+ Rm = Bits32(opcode, 6, 3);
+ if (InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ case eEncodingA1:
+ Rm = Bits32(opcode, 3, 0);
+ break;
+ default:
+ return false;
}
- return true;
+ bool success = false;
+ addr_t target = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
+ context.SetRegister(dwarf_reg);
+ if (!BXWritePC(context, target))
+ return false;
+ }
+ return true;
}
-// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
-// address and instruction set specified by a register as though it were a BX instruction.
+// Branch and Exchange Jazelle attempts to change to Jazelle state. If the
+// attempt fails, it branches to an
+// address and instruction set specified by a register as though it were a BX
+// instruction.
//
// TODO: Emulate Jazelle architecture?
-// We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
-bool
-EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
-{
+// We currently assume that switching to Jazelle state fails, thus
+// treating BXJ as a BX operation.
+bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1718,46 +1687,44 @@ EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding en
}
#endif
- if (ConditionPassed(opcode))
- {
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
- uint32_t Rm; // the register with the target address
- switch (encoding) {
- case eEncodingT1:
- Rm = Bits32(opcode, 19, 16);
- if (BadReg(Rm))
- return false;
- if (InITBlock() && !LastInITBlock())
- return false;
- break;
- case eEncodingA1:
- Rm = Bits32(opcode, 3, 0);
- if (Rm == 15)
- return false;
- break;
- default:
- return false;
- }
- bool success = false;
- addr_t target = ReadCoreReg (Rm, &success);
- if (!success)
- return false;
-
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
- context.SetRegister (dwarf_reg);
- if (!BXWritePC(context, target))
- return false;
+ if (ConditionPassed(opcode)) {
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
+ uint32_t Rm; // the register with the target address
+ switch (encoding) {
+ case eEncodingT1:
+ Rm = Bits32(opcode, 19, 16);
+ if (BadReg(Rm))
+ return false;
+ if (InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ case eEncodingA1:
+ Rm = Bits32(opcode, 3, 0);
+ if (Rm == 15)
+ return false;
+ break;
+ default:
+ return false;
}
- return true;
+ bool success = false;
+ addr_t target = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
+ context.SetRegister(dwarf_reg);
+ if (!BXWritePC(context, target))
+ return false;
+ }
+ return true;
}
// Set r7 to point to some ip offset.
// SUB (immediate)
-bool
-EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1776,40 +1743,38 @@ EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncodi
}
#endif
- if (ConditionPassed(opcode))
- {
- bool success = false;
- const addr_t ip = ReadCoreReg (12, &success);
- if (!success)
- return false;
- uint32_t imm32;
- switch (encoding) {
- case eEncodingA1:
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
- break;
- default:
- return false;
- }
- addr_t ip_offset = imm32;
- addr_t addr = ip - ip_offset; // the adjusted ip value
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
- return false;
+ if (ConditionPassed(opcode)) {
+ bool success = false;
+ const addr_t ip = ReadCoreReg(12, &success);
+ if (!success)
+ return false;
+ uint32_t imm32;
+ switch (encoding) {
+ case eEncodingA1:
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+ break;
+ default:
+ return false;
}
- return true;
+ addr_t ip_offset = imm32;
+ addr_t addr = ip - ip_offset; // the adjusted ip value
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, -ip_offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr))
+ return false;
+ }
+ return true;
}
// Set ip to point to some stack offset.
// SUB (SP minus immediate)
-bool
-EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1828,42 +1793,41 @@ EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncodi
}
#endif
- if (ConditionPassed(opcode))
- {
- bool success = false;
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- uint32_t imm32;
- switch (encoding) {
- case eEncodingA1:
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
- break;
- default:
- return false;
- }
- addr_t sp_offset = imm32;
- addr_t addr = sp - sp_offset; // the adjusted stack pointer value
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
- return false;
+ if (ConditionPassed(opcode)) {
+ bool success = false;
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t imm32;
+ switch (encoding) {
+ case eEncodingA1:
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+ break;
+ default:
+ return false;
}
- return true;
+ addr_t sp_offset = imm32;
+ addr_t addr = sp - sp_offset; // the adjusted stack pointer value
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, -sp_offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr))
+ return false;
+ }
+ return true;
}
// This instruction subtracts an immediate value from the SP value, and writes
// the result to the destination register.
//
-// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
-bool
-EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local
+// storage.
+bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1882,76 +1846,74 @@ EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding
}
#endif
- bool success = false;
- if (ConditionPassed(opcode))
- {
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
-
- uint32_t Rd;
- bool setflags;
- uint32_t imm32;
- switch (encoding) {
- case eEncodingT1:
- Rd = 13;
- setflags = false;
- imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
- if (Rd == 15 && setflags)
- return EmulateCMPImm(opcode, eEncodingT2);
- if (Rd == 15 && !setflags)
- return false;
- break;
- case eEncodingT3:
- Rd = Bits32(opcode, 11, 8);
- setflags = false;
- imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
- if (Rd == 15)
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
+ bool success = false;
+ if (ConditionPassed(opcode)) {
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
- EmulateInstruction::Context context;
- if (Rd == 13)
- {
- uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong
- // value gets passed down to context.SetImmediateSigned.
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (-imm64); // the stack pointer offset
- }
- else
- {
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
- }
+ uint32_t Rd;
+ bool setflags;
+ uint32_t imm32;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = 13;
+ setflags = false;
+ imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
+ if (Rd == 15 && setflags)
+ return EmulateCMPImm(opcode, eEncodingT2);
+ if (Rd == 15 && !setflags)
+ return false;
+ break;
+ case eEncodingT3:
+ Rd = Bits32(opcode, 11, 8);
+ setflags = false;
+ imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
+ if (Rd == 15)
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ EmulateInstruction::Context context;
+ if (Rd == 13) {
+ uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting
+ // to negate it, or the wrong
+ // value gets passed down to context.SetImmediateSigned.
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ context.SetImmediateSigned(-imm64); // the stack pointer offset
+ } else {
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
}
- return true;
+
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
}
// A store operation to the stack that also updates the SP.
-bool
-EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -1964,93 +1926,88 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding
}
#endif
- bool success = false;
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- uint32_t Rt; // the source register
- uint32_t imm12;
- uint32_t Rn; // This function assumes Rn is the SP, but we should verify that.
-
- bool index;
- bool add;
- bool wback;
- switch (encoding) {
- case eEncodingA1:
- Rt = Bits32(opcode, 15, 12);
- imm12 = Bits32(opcode, 11, 0);
- Rn = Bits32 (opcode, 19, 16);
-
- if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP.
- return false;
-
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- if (wback && ((Rn == 15) || (Rn == Rt)))
- return false;
- break;
- default:
- return false;
- }
- addr_t offset_addr;
- if (add)
- offset_addr = sp + imm12;
- else
- offset_addr = sp - imm12;
-
- addr_t addr;
- if (index)
- addr = offset_addr;
- else
- addr = sp;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPushRegisterOnStack;
- RegisterInfo sp_reg;
- RegisterInfo dwarf_reg;
-
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
- context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
- if (Rt != 15)
- {
- uint32_t reg_value = ReadCoreReg(Rt, &success);
- if (!success)
- return false;
- if (!MemUWrite (context, addr, reg_value, addr_byte_size))
- return false;
- }
- else
- {
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
- if (!MemUWrite (context, addr, pc, addr_byte_size))
- return false;
- }
-
+ bool success = false;
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ uint32_t Rt; // the source register
+ uint32_t imm12;
+ uint32_t
+ Rn; // This function assumes Rn is the SP, but we should verify that.
+
+ bool index;
+ bool add;
+ bool wback;
+ switch (encoding) {
+ case eEncodingA1:
+ Rt = Bits32(opcode, 15, 12);
+ imm12 = Bits32(opcode, 11, 0);
+ Rn = Bits32(opcode, 19, 16);
- if (wback)
- {
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (addr - sp);
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
- return false;
- }
+ if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP.
+ return false;
+
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ if (wback && ((Rn == 15) || (Rn == Rt)))
+ return false;
+ break;
+ default:
+ return false;
}
- return true;
+ addr_t offset_addr;
+ if (add)
+ offset_addr = sp + imm12;
+ else
+ offset_addr = sp - imm12;
+
+ addr_t addr;
+ if (index)
+ addr = offset_addr;
+ else
+ addr = sp;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextPushRegisterOnStack;
+ RegisterInfo sp_reg;
+ RegisterInfo dwarf_reg;
+
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
+ context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
+ if (Rt != 15) {
+ uint32_t reg_value = ReadCoreReg(Rt, &success);
+ if (!success)
+ return false;
+ if (!MemUWrite(context, addr, reg_value, addr_byte_size))
+ return false;
+ } else {
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+ if (!MemUWrite(context, addr, pc, addr_byte_size))
+ return false;
+ }
+
+ if (wback) {
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ context.SetImmediateSigned(addr - sp);
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP, offset_addr))
+ return false;
+ }
+ }
+ return true;
}
// Vector Push stores multiple extension registers to the stack.
// It also updates SP to point to the start of the stored data.
-bool
-EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -2070,81 +2027,79 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en
}
#endif
- bool success = false;
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- bool single_regs;
- uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
- uint32_t imm32; // stack offset
- uint32_t regs; // number of registers
- switch (encoding) {
- case eEncodingT1:
- case eEncodingA1:
- single_regs = false;
- d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
- imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
- // If UInt(imm8) is odd, see "FSTMX".
- regs = Bits32(opcode, 7, 0) / 2;
- // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
- if (regs == 0 || regs > 16 || (d + regs) > 32)
- return false;
- break;
- case eEncodingT2:
- case eEncodingA2:
- single_regs = true;
- d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
- imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
- regs = Bits32(opcode, 7, 0);
- // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
- if (regs == 0 || regs > 16 || (d + regs) > 32)
- return false;
- break;
- default:
- return false;
- }
- uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
- uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
- addr_t sp_offset = imm32;
- addr_t addr = sp - sp_offset;
- uint32_t i;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPushRegisterOnStack;
+ bool success = false;
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ bool single_regs;
+ uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
+ uint32_t imm32; // stack offset
+ uint32_t regs; // number of registers
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1:
+ single_regs = false;
+ d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
+ // If UInt(imm8) is odd, see "FSTMX".
+ regs = Bits32(opcode, 7, 0) / 2;
+ // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
+ if (regs == 0 || regs > 16 || (d + regs) > 32)
+ return false;
+ break;
+ case eEncodingT2:
+ case eEncodingA2:
+ single_regs = true;
+ d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
+ imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
+ regs = Bits32(opcode, 7, 0);
+ // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
+ if (regs == 0 || regs > 16 || (d + regs) > 32)
+ return false;
+ break;
+ default:
+ return false;
+ }
+ uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
+ uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
+ addr_t sp_offset = imm32;
+ addr_t addr = sp - sp_offset;
+ uint32_t i;
- RegisterInfo dwarf_reg;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- for (i=0; i<regs; ++i)
- {
- GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
- context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
- // uint64_t to accommodate 64-bit registers.
- uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
- if (!success)
- return false;
- if (!MemAWrite (context, addr, reg_value, reg_byte_size))
- return false;
- addr += reg_byte_size;
- }
-
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (-sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextPushRegisterOnStack;
+
+ RegisterInfo dwarf_reg;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ for (i = 0; i < regs; ++i) {
+ GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
+ context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp);
+ // uint64_t to accommodate 64-bit registers.
+ uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success);
+ if (!success)
+ return false;
+ if (!MemAWrite(context, addr, reg_value, reg_byte_size))
+ return false;
+ addr += reg_byte_size;
}
- return true;
+
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ context.SetImmediateSigned(-sp_offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
+ return false;
+ }
+ return true;
}
// Vector Pop loads multiple extension registers from the stack.
// It also updates SP to point just above the loaded data.
-bool
-EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -2163,80 +2118,78 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc
}
#endif
- bool success = false;
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
- const addr_t sp = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
- bool single_regs;
- uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
- uint32_t imm32; // stack offset
- uint32_t regs; // number of registers
- switch (encoding) {
- case eEncodingT1:
- case eEncodingA1:
- single_regs = false;
- d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
- imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
- // If UInt(imm8) is odd, see "FLDMX".
- regs = Bits32(opcode, 7, 0) / 2;
- // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
- if (regs == 0 || regs > 16 || (d + regs) > 32)
- return false;
- break;
- case eEncodingT2:
- case eEncodingA2:
- single_regs = true;
- d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
- imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
- regs = Bits32(opcode, 7, 0);
- // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
- if (regs == 0 || regs > 16 || (d + regs) > 32)
- return false;
- break;
- default:
- return false;
- }
- uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
- uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
- addr_t sp_offset = imm32;
- addr_t addr = sp;
- uint32_t i;
- uint64_t data; // uint64_t to accommodate 64-bit registers.
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPopRegisterOffStack;
+ bool success = false;
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ const addr_t sp = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+ bool single_regs;
+ uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register
+ uint32_t imm32; // stack offset
+ uint32_t regs; // number of registers
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1:
+ single_regs = false;
+ d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
+ // If UInt(imm8) is odd, see "FLDMX".
+ regs = Bits32(opcode, 7, 0) / 2;
+ // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
+ if (regs == 0 || regs > 16 || (d + regs) > 32)
+ return false;
+ break;
+ case eEncodingT2:
+ case eEncodingA2:
+ single_regs = true;
+ d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
+ imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
+ regs = Bits32(opcode, 7, 0);
+ // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
+ if (regs == 0 || regs > 16 || (d + regs) > 32)
+ return false;
+ break;
+ default:
+ return false;
+ }
+ uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
+ uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
+ addr_t sp_offset = imm32;
+ addr_t addr = sp;
+ uint32_t i;
+ uint64_t data; // uint64_t to accommodate 64-bit registers.
- RegisterInfo dwarf_reg;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- for (i=0; i<regs; ++i)
- {
- GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
- context.SetAddress(addr);
- data = MemARead(context, addr, reg_byte_size, 0, &success);
- if (!success)
- return false;
- if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
- return false;
- addr += reg_byte_size;
- }
-
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- context.SetImmediateSigned (sp_offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextPopRegisterOffStack;
+
+ RegisterInfo dwarf_reg;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ for (i = 0; i < regs; ++i) {
+ GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
+ context.SetAddress(addr);
+ data = MemARead(context, addr, reg_byte_size, 0, &success);
+ if (!success)
+ return false;
+ if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
+ return false;
+ addr += reg_byte_size;
}
- return true;
+
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ context.SetImmediateSigned(sp_offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
+ return false;
+ }
+ return true;
}
// SVC (previously SWI)
-bool
-EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -2246,65 +2199,62 @@ EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding enco
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- addr_t lr; // next instruction address
- if (!success)
- return false;
- uint32_t imm32; // the immediate constant
- uint32_t mode; // ARM or Thumb mode
- switch (encoding) {
- case eEncodingT1:
- lr = (pc + 2) | 1u; // return address
- imm32 = Bits32(opcode, 7, 0);
- mode = eModeThumb;
- break;
- case eEncodingA1:
- lr = pc + 4; // return address
- imm32 = Bits32(opcode, 23, 0);
- mode = eModeARM;
- break;
- default:
- return false;
- }
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextSupervisorCall;
- context.SetISAAndImmediate (mode, imm32);
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
- return false;
+ if (ConditionPassed(opcode)) {
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ addr_t lr; // next instruction address
+ if (!success)
+ return false;
+ uint32_t imm32; // the immediate constant
+ uint32_t mode; // ARM or Thumb mode
+ switch (encoding) {
+ case eEncodingT1:
+ lr = (pc + 2) | 1u; // return address
+ imm32 = Bits32(opcode, 7, 0);
+ mode = eModeThumb;
+ break;
+ case eEncodingA1:
+ lr = pc + 4; // return address
+ imm32 = Bits32(opcode, 23, 0);
+ mode = eModeARM;
+ break;
+ default:
+ return false;
}
- return true;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextSupervisorCall;
+ context.SetISAAndImmediate(mode, imm32);
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA, lr))
+ return false;
+ }
+ return true;
}
// If Then makes up to four following instructions (the IT block) conditional.
-bool
-EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateIT(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
EncodingSpecificOperations();
ITSTATE.IT<7:0> = firstcond:mask;
#endif
- m_it_session.InitIT(Bits32(opcode, 7, 0));
- return true;
+ m_it_session.InitIT(Bits32(opcode, 7, 0));
+ return true;
}
-bool
-EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
-{
- // NOP, nothing to do...
- return true;
+bool EmulateInstructionARM::EmulateNop(const uint32_t opcode,
+ const ARMEncoding encoding) {
+ // NOP, nothing to do...
+ return true;
}
// Branch causes a branch to a target address.
-bool
-EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -2314,81 +2264,83 @@ EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encodi
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
- addr_t target; // target address
- int32_t imm32; // PC-relative offset
- switch (encoding) {
- case eEncodingT1:
- // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
- imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
- target = pc + imm32;
- context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
- break;
- case eEncodingT2:
- imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
- target = pc + imm32;
- context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
- break;
- case eEncodingT3:
- // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
- {
- if (Bits32(opcode, 25, 23) == 7)
- return false; // See Branches and miscellaneous control on page A6-235.
-
- uint32_t S = Bit32(opcode, 26);
- uint32_t imm6 = Bits32(opcode, 21, 16);
- uint32_t J1 = Bit32(opcode, 13);
- uint32_t J2 = Bit32(opcode, 11);
- uint32_t imm11 = Bits32(opcode, 10, 0);
- uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
- imm32 = llvm::SignExtend32<21>(imm21);
- target = pc + imm32;
- context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
- break;
- }
- case eEncodingT4:
- {
- uint32_t S = Bit32(opcode, 26);
- uint32_t imm10 = Bits32(opcode, 25, 16);
- uint32_t J1 = Bit32(opcode, 13);
- uint32_t J2 = Bit32(opcode, 11);
- uint32_t imm11 = Bits32(opcode, 10, 0);
- uint32_t I1 = !(J1 ^ S);
- uint32_t I2 = !(J2 ^ S);
- uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
- imm32 = llvm::SignExtend32<25>(imm25);
- target = pc + imm32;
- context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
- break;
- }
- case eEncodingA1:
- imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
- target = pc + imm32;
- context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
- break;
- default:
- return false;
- }
- if (!BranchWritePC(context, target))
- return false;
+ if (ConditionPassed(opcode)) {
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+ addr_t target; // target address
+ int32_t imm32; // PC-relative offset
+ switch (encoding) {
+ case eEncodingT1:
+ // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
+ imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
+ target = pc + imm32;
+ context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
+ break;
+ case eEncodingT2:
+ imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
+ target = pc + imm32;
+ context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
+ break;
+ case eEncodingT3:
+ // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
+ {
+ if (Bits32(opcode, 25, 23) == 7)
+ return false; // See Branches and miscellaneous control on page
+ // A6-235.
+
+ uint32_t S = Bit32(opcode, 26);
+ uint32_t imm6 = Bits32(opcode, 21, 16);
+ uint32_t J1 = Bit32(opcode, 13);
+ uint32_t J2 = Bit32(opcode, 11);
+ uint32_t imm11 = Bits32(opcode, 10, 0);
+ uint32_t imm21 =
+ (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
+ imm32 = llvm::SignExtend32<21>(imm21);
+ target = pc + imm32;
+ context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
+ break;
+ }
+ case eEncodingT4: {
+ uint32_t S = Bit32(opcode, 26);
+ uint32_t imm10 = Bits32(opcode, 25, 16);
+ uint32_t J1 = Bit32(opcode, 13);
+ uint32_t J2 = Bit32(opcode, 11);
+ uint32_t imm11 = Bits32(opcode, 10, 0);
+ uint32_t I1 = !(J1 ^ S);
+ uint32_t I2 = !(J2 ^ S);
+ uint32_t imm25 =
+ (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
+ imm32 = llvm::SignExtend32<25>(imm25);
+ target = pc + imm32;
+ context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
+ break;
}
- return true;
+ case eEncodingA1:
+ imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
+ target = pc + imm32;
+ context.SetISAAndImmediateSigned(eModeARM, 8 + imm32);
+ break;
+ default:
+ return false;
+ }
+ if (!BranchWritePC(context, target))
+ return false;
+ }
+ return true;
}
-// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
-// zero and conditionally branch forward a constant value. They do not affect the condition flags.
+// Compare and Branch on Nonzero and Compare and Branch on Zero compare the
+// value in a register with
+// zero and conditionally branch forward a constant value. They do not affect
+// the condition flags.
// CBNZ, CBZ
-bool
-EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateCB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
EncodingSpecificOperations();
@@ -2396,50 +2348,53 @@ EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encod
BranchWritePC(PC + imm32);
#endif
- bool success = false;
+ bool success = false;
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
+ if (!success)
+ return false;
- addr_t target; // target address
- uint32_t imm32; // PC-relative offset to branch forward
- bool nonzero;
- switch (encoding) {
- case eEncodingT1:
- imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
- nonzero = BitIsSet(opcode, 11);
- target = pc + imm32;
- context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
- break;
- default:
- return false;
- }
- if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
- if (!BranchWritePC(context, target))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
- return true;
+ addr_t target; // target address
+ uint32_t imm32; // PC-relative offset to branch forward
+ bool nonzero;
+ switch (encoding) {
+ case eEncodingT1:
+ imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
+ nonzero = BitIsSet(opcode, 11);
+ target = pc + imm32;
+ context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32);
+ break;
+ default:
+ return false;
+ }
+ if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
+ if (!BranchWritePC(context, target))
+ return false;
+
+ return true;
}
-// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
-// A base register provides a pointer to the table, and a second register supplies an index into the table.
+// Table Branch Byte causes a PC-relative forward branch using a table of single
+// byte offsets.
+// A base register provides a pointer to the table, and a second register
+// supplies an index into the table.
// The branch length is twice the value of the byte returned from the table.
//
-// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
-// A base register provides a pointer to the table, and a second register supplies an index into the table.
+// Table Branch Halfword causes a PC-relative forward branch using a table of
+// single halfword offsets.
+// A base register provides a pointer to the table, and a second register
+// supplies an index into the table.
// The branch length is twice the value of the halfword returned from the table.
// TBB, TBH
-bool
-EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateTB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -2450,69 +2405,71 @@ EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encod
BranchWritePC(PC + 2*halfwords);
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rn; // the base register which contains the address of the table of branch lengths
- uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table
- bool is_tbh; // true if table branch halfword
- switch (encoding) {
- case eEncodingT1:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- is_tbh = BitIsSet(opcode, 4);
- if (Rn == 13 || BadReg(Rm))
- return false;
- if (InITBlock() && !LastInITBlock())
- return false;
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rn; // the base register which contains the address of the table of
+ // branch lengths
+ uint32_t Rm; // the index register which contains an integer pointing to a
+ // byte/halfword in the table
+ bool is_tbh; // true if table branch halfword
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ is_tbh = BitIsSet(opcode, 4);
+ if (Rn == 13 || BadReg(Rm))
+ return false;
+ if (InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ default:
+ return false;
+ }
- // Read the address of the table from the operand register Rn.
- // The PC can be used, in which case the table immediately follows this instruction.
- uint32_t base = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the address of the table from the operand register Rn.
+ // The PC can be used, in which case the table immediately follows this
+ // instruction.
+ uint32_t base = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // the table index
- uint32_t index = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // the table index
+ uint32_t index = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // the offsetted table address
- addr_t addr = base + (is_tbh ? index*2 : index);
+ // the offsetted table address
+ addr_t addr = base + (is_tbh ? index * 2 : index);
- // PC-relative offset to branch forward
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextTableBranchReadMemory;
- uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
- if (!success)
- return false;
+ // PC-relative offset to branch forward
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextTableBranchReadMemory;
+ uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
+ if (!success)
+ return false;
- const uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
- // target address
- addr_t target = pc + offset;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
+ // target address
+ addr_t target = pc + offset;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ context.SetISAAndImmediateSigned(eModeThumb, 4 + offset);
- if (!BranchWritePC(context, target))
- return false;
- }
+ if (!BranchWritePC(context, target))
+ return false;
+ }
- return true;
+ return true;
}
-// This instruction adds an immediate value to a register value, and writes the result to the destination register.
+// This instruction adds an immediate value to a register value, and writes the
+// result to the destination register.
// It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -2525,114 +2482,116 @@ EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncod
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t n;
- bool setflags;
- uint32_t imm32;
- uint32_t carry_out;
-
- //EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
- d = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- setflags = !InITBlock();
- imm32 = Bits32 (opcode, 8,6);
-
- break;
-
- case eEncodingT2:
- // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
- d = Bits32 (opcode, 10, 8);
- n = Bits32 (opcode, 10, 8);
- setflags = !InITBlock();
- imm32 = Bits32 (opcode, 7, 0);
-
- break;
-
- case eEncodingT3:
- // if Rd == '1111' && S == '1' then SEE CMN (immediate);
- // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
- d = Bits32 (opcode, 11, 8);
- n = Bits32 (opcode, 19, 16);
- setflags = BitIsSet (opcode, 20);
- imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
-
- // if Rn == '1101' then SEE ADD (SP plus immediate);
- if (n == 13)
- return EmulateADDSPImm(opcode, eEncodingT3);
-
- // if BadReg(d) || n == 15 then UNPREDICTABLE;
- if (BadReg (d) || (n == 15))
- return false;
-
- break;
-
- case eEncodingT4:
- {
- // if Rn == '1111' then SEE ADR;
- // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
- d = Bits32 (opcode, 11, 8);
- n = Bits32 (opcode, 19, 16);
- setflags = false;
- uint32_t i = Bit32 (opcode, 26);
- uint32_t imm3 = Bits32 (opcode, 14, 12);
- uint32_t imm8 = Bits32 (opcode, 7, 0);
- imm32 = (i << 11) | (imm3 << 8) | imm8;
-
- // if Rn == '1101' then SEE ADD (SP plus immediate);
- if (n == 13)
- return EmulateADDSPImm(opcode, eEncodingT4);
-
- // if BadReg(d) then UNPREDICTABLE;
- if (BadReg (d))
- return false;
-
- break;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t n;
+ bool setflags;
+ uint32_t imm32;
+ uint32_t carry_out;
- default:
- return false;
- }
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 =
+ // ZeroExtend(imm3, 32);
+ d = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ imm32 = Bits32(opcode, 8, 6);
- uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
+ break;
+
+ case eEncodingT2:
+ // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 =
+ // ZeroExtend(imm8, 32);
+ d = Bits32(opcode, 10, 8);
+ n = Bits32(opcode, 10, 8);
+ setflags = !InITBlock();
+ imm32 = Bits32(opcode, 7, 0);
- //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
- AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
+ break;
- RegisterInfo reg_n;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
+ case eEncodingT3:
+ // if Rd == '1111' && S == '1' then SEE CMN (immediate);
+ // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 =
+ // ThumbExpandImm(i:imm3:imm8);
+ d = Bits32(opcode, 11, 8);
+ n = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out);
+
+ // if Rn == '1101' then SEE ADD (SP plus immediate);
+ if (n == 13)
+ return EmulateADDSPImm(opcode, eEncodingT3);
+
+ // if BadReg(d) || n == 15 then UNPREDICTABLE;
+ if (BadReg(d) || (n == 15))
+ return false;
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- context.SetRegisterPlusOffset (reg_n, imm32);
+ break;
+
+ case eEncodingT4: {
+ // if Rn == '1111' then SEE ADR;
+ // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 =
+ // ZeroExtend(i:imm3:imm8, 32);
+ d = Bits32(opcode, 11, 8);
+ n = Bits32(opcode, 19, 16);
+ setflags = false;
+ uint32_t i = Bit32(opcode, 26);
+ uint32_t imm3 = Bits32(opcode, 14, 12);
+ uint32_t imm8 = Bits32(opcode, 7, 0);
+ imm32 = (i << 11) | (imm3 << 8) | imm8;
+
+ // if Rn == '1101' then SEE ADD (SP plus immediate);
+ if (n == 13)
+ return EmulateADDSPImm(opcode, eEncodingT4);
+
+ // if BadReg(d) then UNPREDICTABLE;
+ if (BadReg(d))
+ return false;
- //R[d] = result;
- //if setflags then
- //APSR.N = result<31>;
- //APSR.Z = IsZeroBit(result);
- //APSR.C = carry;
- //APSR.V = overflow;
- if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
- return false;
+ break;
+ }
+ default:
+ return false;
}
- return true;
-}
-
-// This instruction adds an immediate value to a register value, and writes the result to the destination
+
+ uint64_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
+ AddWithCarryResult res = AddWithCarry(Rn, imm32, 0);
+
+ RegisterInfo reg_n;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
+
+ EmulateInstruction::Context context;
+ context.type = eContextArithmetic;
+ context.SetRegisterPlusOffset(reg_n, imm32);
+
+ // R[d] = result;
+ // if setflags then
+ // APSR.N = result<31>;
+ // APSR.Z = IsZeroBit(result);
+ // APSR.C = carry;
+ // APSR.V = overflow;
+ if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
+}
+
+// This instruction adds an immediate value to a register value, and writes the
+// result to the destination
// register. It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -2649,55 +2608,56 @@ EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncodin
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn;
- uint32_t imm32; // the immediate value to be added to the value obtained from Rn
- bool setflags;
- switch (encoding)
- {
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn;
+ uint32_t
+ imm32; // the immediate value to be added to the value obtained from Rn
+ bool setflags;
+ switch (encoding) {
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
+ AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
- EmulateInstruction::Context context;
- if (Rd == 13)
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- else if (Rd == GetFramePointerRegisterNumber())
- context.type = EmulateInstruction::eContextSetFramePointer;
- else
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ EmulateInstruction::Context context;
+ if (Rd == 13)
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ else if (Rd == GetFramePointerRegisterNumber())
+ context.type = EmulateInstruction::eContextSetFramePointer;
+ else
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, imm32);
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, imm32);
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
}
-// This instruction adds a register value and an optionally-shifted register value, and writes the result
-// to the destination register. It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+// This instruction adds a register value and an optionally-shifted register
+// value, and writes the result
+// to the destination register. It can optionally update the condition flags
+// based on the result.
+bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -2715,80 +2675,78 @@ EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- bool setflags;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Bits32(opcode, 2, 0);
- Rn = Bits32(opcode, 5, 3);
- Rm = Bits32(opcode, 8, 6);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 6, 3);
- setflags = false;
- shift_t = SRType_LSL;
- shift_n = 0;
- if (Rn == 15 && Rm == 15)
- return false;
- if (Rd == 15 && InITBlock() && !LastInITBlock())
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 2, 0);
+ Rn = Bits32(opcode, 5, 3);
+ Rm = Bits32(opcode, 8, 6);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 6, 3);
+ setflags = false;
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ if (Rn == 15 && Rm == 15)
+ return false;
+ if (Rd == 15 && InITBlock() && !LastInITBlock())
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
+ uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- RegisterInfo op1_reg;
- RegisterInfo op2_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
- context.SetRegisterRegisterOperands (op1_reg, op2_reg);
+ EmulateInstruction::Context context;
+ context.type = eContextArithmetic;
+ RegisterInfo op1_reg;
+ RegisterInfo op2_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
+ context.SetRegisterRegisterOperands(op1_reg, op2_reg);
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
}
// Compare Negative (immediate) adds a register value and an immediate value.
// It updates the condition flags based on the result, and discards the result.
-bool
-EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -2800,45 +2758,45 @@ EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rn; // the first operand
+ uint32_t imm32; // the immediate value to be compared with
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
+ if (Rn == 15)
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rn; // the first operand
- uint32_t imm32; // the immediate value to be compared with
- switch (encoding) {
- case eEncodingT1:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
- if (Rn == 15)
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
- break;
- default:
- return false;
- }
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
+ AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+ if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
-// Compare Negative (register) adds a register value and an optionally-shifted register value.
+// Compare Negative (register) adds a register value and an optionally-shifted
+// register value.
// It updates the condition flags based on the result, and discards the result.
-bool
-EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -2851,64 +2809,63 @@ EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rn; // the first operand
+ uint32_t Rm; // the second operand
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ // if n == 15 || BadReg(m) then UNPREDICTABLE;
+ if (Rn == 15 || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from register Rn.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rn; // the first operand
- uint32_t Rm; // the second operand
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- switch (encoding) {
- case eEncodingT1:
- Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- // if n == 15 || BadReg(m) then UNPREDICTABLE;
- if (Rn == 15 || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
- break;
- default:
- return false;
- }
- // Read the register value from register Rn.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the register value from register Rm.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // Read the register value from register Rm.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
-
- uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
+ uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+ if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
// Compare (immediate) subtracts an immediate value from a register value.
// It updates the condition flags based on the result, and discards the result.
-bool
-EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -2920,49 +2877,49 @@ EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rn; // the first operand
+ uint32_t imm32; // the immediate value to be compared with
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 10, 8);
+ imm32 = Bits32(opcode, 7, 0);
+ break;
+ case eEncodingT2:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
+ if (Rn == 15)
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rn; // the first operand
- uint32_t imm32; // the immediate value to be compared with
- switch (encoding) {
- case eEncodingT1:
- Rn = Bits32(opcode, 10, 8);
- imm32 = Bits32(opcode, 7, 0);
- break;
- case eEncodingT2:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
- if (Rn == 15)
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
- break;
- default:
- return false;
- }
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
+ AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+ if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
-// Compare (register) subtracts an optionally-shifted register value from a register value.
+// Compare (register) subtracts an optionally-shifted register value from a
+// register value.
// It updates the condition flags based on the result, and discards the result.
-bool
-EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -2975,74 +2932,75 @@ EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rn; // the first operand
+ uint32_t Rm; // the second operand
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 6, 3);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ if (Rn < 8 && Rm < 8)
+ return false;
+ if (Rn == 15 || Rm == 15)
+ return false;
+ break;
+ case eEncodingT3:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ if (Rn == 15 || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from register Rn.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rn; // the first operand
- uint32_t Rm; // the second operand
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- switch (encoding) {
- case eEncodingT1:
- Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 6, 3);
- shift_t = SRType_LSL;
- shift_n = 0;
- if (Rn < 8 && Rm < 8)
- return false;
- if (Rn == 15 || Rm == 15)
- return false;
- break;
- case eEncodingT3:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- if (Rn == 15 || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
- break;
- default:
- return false;
- }
- // Read the register value from register Rn.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the register value from register Rm.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // Read the register value from register Rm.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
-
- uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
+ uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+ if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
-// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
-// shifting in copies of its sign bit, and writes the result to the destination register. It can
+// Arithmetic Shift Right (immediate) shifts a register value right by an
+// immediate number of bits,
+// shifting in copies of its sign bit, and writes the result to the destination
+// register. It can
// optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3059,16 +3017,18 @@ EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftImm (opcode, encoding, SRType_ASR);
+ return EmulateShiftImm(opcode, encoding, SRType_ASR);
}
-// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
-// shifting in copies of its sign bit, and writes the result to the destination register.
-// The variable number of bits is read from the bottom byte of a register. It can optionally update
+// Arithmetic Shift Right (register) shifts a register value right by a variable
+// number of bits,
+// shifting in copies of its sign bit, and writes the result to the destination
+// register.
+// The variable number of bits is read from the bottom byte of a register. It
+// can optionally update
// the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3083,15 +3043,16 @@ EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftReg (opcode, encoding, SRType_ASR);
+ return EmulateShiftReg(opcode, encoding, SRType_ASR);
}
-// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
-// shifting in zeros, and writes the result to the destination register. It can optionally
+// Logical Shift Left (immediate) shifts a register value left by an immediate
+// number of bits,
+// shifting in zeros, and writes the result to the destination register. It can
+// optionally
// update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3108,16 +3069,18 @@ EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftImm (opcode, encoding, SRType_LSL);
+ return EmulateShiftImm(opcode, encoding, SRType_LSL);
}
-// Logical Shift Left (register) shifts a register value left by a variable number of bits,
-// shifting in zeros, and writes the result to the destination register. The variable number
-// of bits is read from the bottom byte of a register. It can optionally update the condition
+// Logical Shift Left (register) shifts a register value left by a variable
+// number of bits,
+// shifting in zeros, and writes the result to the destination register. The
+// variable number
+// of bits is read from the bottom byte of a register. It can optionally update
+// the condition
// flags based on the result.
-bool
-EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3132,15 +3095,16 @@ EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftReg (opcode, encoding, SRType_LSL);
+ return EmulateShiftReg(opcode, encoding, SRType_LSL);
}
-// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
-// shifting in zeros, and writes the result to the destination register. It can optionally
+// Logical Shift Right (immediate) shifts a register value right by an immediate
+// number of bits,
+// shifting in zeros, and writes the result to the destination register. It can
+// optionally
// update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3157,16 +3121,18 @@ EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftImm (opcode, encoding, SRType_LSR);
+ return EmulateShiftImm(opcode, encoding, SRType_LSR);
}
-// Logical Shift Right (register) shifts a register value right by a variable number of bits,
-// shifting in zeros, and writes the result to the destination register. The variable number
-// of bits is read from the bottom byte of a register. It can optionally update the condition
+// Logical Shift Right (register) shifts a register value right by a variable
+// number of bits,
+// shifting in zeros, and writes the result to the destination register. The
+// variable number
+// of bits is read from the bottom byte of a register. It can optionally update
+// the condition
// flags based on the result.
-bool
-EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3181,15 +3147,16 @@ EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftReg (opcode, encoding, SRType_LSR);
+ return EmulateShiftReg(opcode, encoding, SRType_LSR);
}
-// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
-// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
+// Rotate Right (immediate) provides the value of the contents of a register
+// rotated by a constant value.
+// The bits that are rotated off the right end are inserted into the vacated bit
+// positions on the left.
// It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3206,16 +3173,18 @@ EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftImm (opcode, encoding, SRType_ROR);
+ return EmulateShiftImm(opcode, encoding, SRType_ROR);
}
-// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
-// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
-// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
+// Rotate Right (register) provides the value of the contents of a register
+// rotated by a variable number of bits.
+// The bits that are rotated off the right end are inserted into the vacated bit
+// positions on the left.
+// The variable number of bits is read from the bottom byte of a register. It
+// can optionally update the condition
// flags based on the result.
-bool
-EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3230,17 +3199,17 @@ EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- return EmulateShiftReg (opcode, encoding, SRType_ROR);
+ return EmulateShiftReg(opcode, encoding, SRType_ROR);
}
-// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
+// Rotate Right with Extend provides the value of the contents of a register
+// shifted right by one place,
// with the carry flag shifted into bit [31].
//
// RRX can optionally update the condition flags based on the result.
// In that case, bit [0] is shifted into the carry flag.
-bool
-EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3257,176 +3226,177 @@ EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding enco
// APSR.V unchanged
#endif
- return EmulateShiftImm (opcode, encoding, SRType_RRX);
+ return EmulateShiftImm(opcode, encoding, SRType_RRX);
}
-bool
-EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
-{
-// assert(shift_type == SRType_ASR
-// || shift_type == SRType_LSL
-// || shift_type == SRType_LSR
-// || shift_type == SRType_ROR
-// || shift_type == SRType_RRX);
+bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode,
+ const ARMEncoding encoding,
+ ARM_ShifterType shift_type) {
+ // assert(shift_type == SRType_ASR
+ // || shift_type == SRType_LSL
+ // || shift_type == SRType_LSR
+ // || shift_type == SRType_ROR
+ // || shift_type == SRType_RRX);
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd; // the destination register
- uint32_t Rm; // the first operand register
- uint32_t imm5; // encoding for the shift amount
- uint32_t carry; // the carry bit after the shift operation
- bool setflags;
-
- // Special case handling!
- // A8.6.139 ROR (immediate) -- Encoding T1
- ARMEncoding use_encoding = encoding;
- if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
- {
- // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
- // have the same decoding of bit fields as the other Thumb2 shift operations.
- use_encoding = eEncodingT2;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd; // the destination register
+ uint32_t Rm; // the first operand register
+ uint32_t imm5; // encoding for the shift amount
+ uint32_t carry; // the carry bit after the shift operation
+ bool setflags;
- switch (use_encoding) {
- case eEncodingT1:
- // Due to the above special case handling!
- if (shift_type == SRType_ROR)
- return false;
+ // Special case handling!
+ // A8.6.139 ROR (immediate) -- Encoding T1
+ ARMEncoding use_encoding = encoding;
+ if (shift_type == SRType_ROR && use_encoding == eEncodingT1) {
+ // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding
+ // to
+ // have the same decoding of bit fields as the other Thumb2 shift
+ // operations.
+ use_encoding = eEncodingT2;
+ }
- Rd = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- imm5 = Bits32(opcode, 10, 6);
- break;
- case eEncodingT2:
- // A8.6.141 RRX
- // There's no imm form of RRX instructions.
- if (shift_type == SRType_RRX)
- return false;
+ switch (use_encoding) {
+ case eEncodingT1:
+ // Due to the above special case handling!
+ if (shift_type == SRType_ROR)
+ return false;
- Rd = Bits32(opcode, 11, 8);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
- if (BadReg(Rd) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- imm5 = Bits32(opcode, 11, 7);
- break;
- default:
- return false;
- }
+ Rd = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ imm5 = Bits32(opcode, 10, 6);
+ break;
+ case eEncodingT2:
+ // A8.6.141 RRX
+ // There's no imm form of RRX instructions.
+ if (shift_type == SRType_RRX)
+ return false;
- // A8.6.139 ROR (immediate)
- if (shift_type == SRType_ROR && imm5 == 0)
- shift_type = SRType_RRX;
+ Rd = Bits32(opcode, 11, 8);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
+ if (BadReg(Rd) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ imm5 = Bits32(opcode, 11, 7);
+ break;
+ default:
+ return false;
+ }
- // Get the first operand.
- uint32_t value = ReadCoreReg (Rm, &success);
- if (!success)
- return false;
+ // A8.6.139 ROR (immediate)
+ if (shift_type == SRType_ROR && imm5 == 0)
+ shift_type = SRType_RRX;
- // Decode the shift amount if not RRX.
- uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
+ // Get the first operand.
+ uint32_t value = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
- if (!success)
- return false;
+ // Decode the shift amount if not RRX.
+ uint32_t amt =
+ (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
- // The context specifies that an immediate is to be moved into Rd.
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
-
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
+ if (!success)
+ return false;
+
+ // The context specifies that an immediate is to be moved into Rd.
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-bool
-EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
-{
- // assert(shift_type == SRType_ASR
- // || shift_type == SRType_LSL
- // || shift_type == SRType_LSR
- // || shift_type == SRType_ROR);
+bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode,
+ const ARMEncoding encoding,
+ ARM_ShifterType shift_type) {
+ // assert(shift_type == SRType_ASR
+ // || shift_type == SRType_LSL
+ // || shift_type == SRType_LSR
+ // || shift_type == SRType_ROR);
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand register
- uint32_t Rm; // the register whose bottom byte contains the amount to shift by
- uint32_t carry; // the carry bit after the shift operation
- bool setflags;
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 2, 0);
- Rn = Rd;
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 3, 0);
- Rm = Bits32(opcode, 11, 8);
- setflags = BitIsSet(opcode, 20);
- if (Rd == 15 || Rn == 15 || Rm == 15)
- return false;
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand register
+ uint32_t
+ Rm; // the register whose bottom byte contains the amount to shift by
+ uint32_t carry; // the carry bit after the shift operation
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 2, 0);
+ Rn = Rd;
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 3, 0);
+ Rm = Bits32(opcode, 11, 8);
+ setflags = BitIsSet(opcode, 20);
+ if (Rd == 15 || Rn == 15 || Rm == 15)
+ return false;
+ break;
+ default:
+ return false;
+ }
- // Get the first operand.
- uint32_t value = ReadCoreReg (Rn, &success);
- if (!success)
- return false;
- // Get the Rm register content.
- uint32_t val = ReadCoreReg (Rm, &success);
- if (!success)
- return false;
+ // Get the first operand.
+ uint32_t value = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
+ // Get the Rm register content.
+ uint32_t val = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // Get the shift amount.
- uint32_t amt = Bits32(val, 7, 0);
+ // Get the shift amount.
+ uint32_t amt = Bits32(val, 7, 0);
- uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
- if (!success)
- return false;
+ uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
+ if (!success)
+ return false;
- // The context specifies that an immediate is to be moved into Rd.
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
-
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ // The context specifies that an immediate is to be moved into Rd.
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
+
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
// LDM loads multiple registers from consecutive memory locations, using an
-// address from a base register. Optionally the address just above the highest of those locations
+// address from a base register. Optionally the address just above the highest
+// of those locations
// can be written back to the base register.
-bool
-EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed()
@@ -3443,133 +3413,133 @@ EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding enco
if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
#endif
-
- bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
- switch (encoding)
+
+ bool success = false;
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ switch (encoding) {
+ case eEncodingT1:
+ // n = UInt(Rn); registers = '00000000':register_list; wback =
+ // (registers<n> == '0');
+ n = Bits32(opcode, 10, 8);
+ registers = Bits32(opcode, 7, 0);
+ registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
+ wback = BitIsClear(registers, n);
+ // if BitCount(registers) < 1 then UNPREDICTABLE;
+ if (BitCount(registers) < 1)
+ return false;
+ break;
+ case eEncodingT2:
+ // if W == '1' && Rn == '1101' then SEE POP;
+ // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ registers = registers & 0xdfff; // Make sure bit 13 is zero.
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
+ // UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 2) ||
+ (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
+ return false;
+
+ // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
+ // UNPREDICTABLE;
+ if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
+ return false;
+
+ // if wback && registers<n> == '1' then UNPREDICTABLE;
+ if (wback && BitIsSet(registers, n))
+ return false;
+ break;
+
+ case eEncodingA1:
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+ if ((n == 15) || (BitCount(registers) < 1))
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ int32_t offset = 0;
+ const addr_t base_address =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+
+ for (int i = 0; i < 14; ++i) {
+ if (BitIsSet(registers, i)) {
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+ if (wback && (n == 13)) // Pop Instruction
{
- case eEncodingT1:
- // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
- n = Bits32 (opcode, 10, 8);
- registers = Bits32 (opcode, 7, 0);
- registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
- wback = BitIsClear (registers, n);
- // if BitCount(registers) < 1 then UNPREDICTABLE;
- if (BitCount(registers) < 1)
- return false;
- break;
- case eEncodingT2:
- // if W == '1' && Rn == '1101' then SEE POP;
- // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- registers = registers & 0xdfff; // Make sure bit 13 is zero.
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
- if ((n == 15)
- || (BitCount (registers) < 2)
- || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
- return false;
-
- // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
- return false;
-
- // if wback && registers<n> == '1' then UNPREDICTABLE;
- if (wback
- && BitIsSet (registers, n))
- return false;
- break;
-
- case eEncodingA1:
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
- if ((n == 15)
- || (BitCount (registers) < 1))
- return false;
- break;
- default:
- return false;
+ context.type = EmulateInstruction::eContextPopRegisterOffStack;
+ context.SetAddress(base_address + offset);
}
-
- int32_t offset = 0;
- const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+
+ // R[i] = MemA [address, 4]; address = address + 4;
+ uint32_t data = MemARead(context, base_address + offset, addr_byte_size,
+ 0, &success);
if (!success)
- return false;
+ return false;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, offset);
-
- for (int i = 0; i < 14; ++i)
- {
- if (BitIsSet (registers, i))
- {
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- context.SetRegisterPlusOffset (dwarf_reg, offset);
- if (wback && (n == 13)) // Pop Instruction
- {
- context.type = EmulateInstruction::eContextPopRegisterOffStack;
- context.SetAddress(base_address + offset);
- }
-
- // R[i] = MemA [address, 4]; address = address + 4;
- uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
+ data))
+ return false;
- offset += addr_byte_size;
- }
- }
-
- if (BitIsSet (registers, 15))
- {
- //LoadWritePC (MemA [address, 4]);
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- context.SetRegisterPlusOffset (dwarf_reg, offset);
- uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
- // In ARMv5T and above, this is an interworking branch.
- if (!LoadWritePC(context, data))
- return false;
- }
-
- if (wback && BitIsClear (registers, n))
- {
- // R[n] = R[n] + 4 * BitCount (registers)
- int32_t offset = addr_byte_size * BitCount (registers);
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetRegisterPlusOffset (dwarf_reg, offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
- return false;
- }
- if (wback && BitIsSet (registers, n))
- // R[n] bits(32) UNKNOWN;
- return WriteBits32Unknown (n);
+ offset += addr_byte_size;
+ }
}
- return true;
+
+ if (BitIsSet(registers, 15)) {
+ // LoadWritePC (MemA [address, 4]);
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+ uint32_t data =
+ MemARead(context, base_address + offset, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+ // In ARMv5T and above, this is an interworking branch.
+ if (!LoadWritePC(context, data))
+ return false;
+ }
+
+ if (wback && BitIsClear(registers, n)) {
+ // R[n] = R[n] + 4 * BitCount (registers)
+ int32_t offset = addr_byte_size * BitCount(registers);
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ base_address + offset))
+ return false;
+ }
+ if (wback && BitIsSet(registers, n))
+ // R[n] bits(32) UNKNOWN;
+ return WriteBits32Unknown(n);
+ }
+ return true;
}
-
-// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
-// The consecutive memory locations end at this address and the address just below the lowest of those locations
+
+// LDMDA loads multiple registers from consecutive memory locations using an
+// address from a base register.
+// The consecutive memory locations end at this address and the address just
+// below the lowest of those locations
// can optionally be written back to the base register.
-bool
-EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3586,107 +3556,107 @@ EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding en
if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingA1:
- // n = UInt(Rn); registers = register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
- if ((n == 15) || (BitCount (registers) < 1))
- return false;
-
- break;
- default:
- return false;
- }
- // address = R[n] - 4*BitCount(registers) + 4;
-
- int32_t offset = 0;
- addr_t Rn = ReadCoreReg (n, &success);
-
- if (!success)
- return false;
-
- addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, offset);
-
- // for i = 0 to 14
- for (int i = 0; i < 14; ++i)
- {
- // if registers<i> == '1' then
- if (BitIsSet (registers, i))
- {
- // R[i] = MemA[address,4]; address = address + 4;
- context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
- uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
- return false;
- offset += addr_byte_size;
- }
- }
-
- // if registers<15> == '1' then
- // LoadWritePC(MemA[address,4]);
- if (BitIsSet (registers, 15))
- {
- context.SetRegisterPlusOffset (dwarf_reg, offset);
- uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
- // In ARMv5T and above, this is an interworking branch.
- if (!LoadWritePC(context, data))
- return false;
- }
-
- // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
- if (wback && BitIsClear (registers, n))
- {
- if (!success)
- return false;
+ bool success = false;
- offset = (addr_byte_size * BitCount (registers)) * -1;
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
- addr_t addr = Rn + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
- return false;
- }
-
- // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
- if (wback && BitIsSet (registers, n))
- return WriteBits32Unknown (n);
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingA1:
+ // n = UInt(Rn); registers = register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 1))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+ // address = R[n] - 4*BitCount(registers) + 4;
+
+ int32_t offset = 0;
+ addr_t Rn = ReadCoreReg(n, &success);
+
+ if (!success)
+ return false;
+
+ addr_t address =
+ Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+
+ // for i = 0 to 14
+ for (int i = 0; i < 14; ++i) {
+ // if registers<i> == '1' then
+ if (BitIsSet(registers, i)) {
+ // R[i] = MemA[address,4]; address = address + 4;
+ context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
+ uint32_t data =
+ MemARead(context, address + offset, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
+ data))
+ return false;
+ offset += addr_byte_size;
+ }
+ }
+
+ // if registers<15> == '1' then
+ // LoadWritePC(MemA[address,4]);
+ if (BitIsSet(registers, 15)) {
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+ uint32_t data =
+ MemARead(context, address + offset, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+ // In ARMv5T and above, this is an interworking branch.
+ if (!LoadWritePC(context, data))
+ return false;
+ }
+
+ // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
+ if (wback && BitIsClear(registers, n)) {
+ if (!success)
+ return false;
+
+ offset = (addr_byte_size * BitCount(registers)) * -1;
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+ addr_t addr = Rn + offset;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ addr))
+ return false;
+ }
+
+ // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
+ if (wback && BitIsSet(registers, n))
+ return WriteBits32Unknown(n);
+ }
+ return true;
}
-
-// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The
-// consecutive memory locations end just below this address, and the address of the lowest of those locations can
+
+// LDMDB loads multiple registers from consecutive memory locations using an
+// address from a base register. The
+// consecutive memory locations end just below this address, and the address of
+// the lowest of those locations can
// be optionally written back to the base register.
-bool
-EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -3702,128 +3672,130 @@ EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding en
if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
- switch (encoding)
- {
- case eEncodingT1:
- // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- registers = registers & 0xdfff; // Make sure bit 13 is a zero.
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
- if ((n == 15)
- || (BitCount (registers) < 2)
- || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
- return false;
-
- // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
- return false;
-
- // if wback && registers<n> == '1' then UNPREDICTABLE;
- if (wback && BitIsSet (registers, n))
- return false;
-
- break;
-
- case eEncodingA1:
- // n = UInt(Rn); registers = register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
- if ((n == 15) || (BitCount (registers) < 1))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- // address = R[n] - 4*BitCount(registers);
-
- int32_t offset = 0;
- addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
-
- if (!success)
- return false;
-
- addr_t address = Rn - (addr_byte_size * BitCount (registers));
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
-
- for (int i = 0; i < 14; ++i)
- {
- if (BitIsSet (registers, i))
- {
- // R[i] = MemA[address,4]; address = address + 4;
- context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
- uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
- return false;
-
- offset += addr_byte_size;
- }
- }
-
- // if registers<15> == '1' then
- // LoadWritePC(MemA[address,4]);
- if (BitIsSet (registers, 15))
- {
- context.SetRegisterPlusOffset (dwarf_reg, offset);
- uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
- // In ARMv5T and above, this is an interworking branch.
- if (!LoadWritePC(context, data))
- return false;
- }
-
- // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
- if (wback && BitIsClear (registers, n))
- {
- if (!success)
- return false;
-
- offset = (addr_byte_size * BitCount (registers)) * -1;
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
- addr_t addr = Rn + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
- return false;
- }
-
- // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
- if (wback && BitIsSet (registers, n))
- return WriteBits32Unknown (n);
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ switch (encoding) {
+ case eEncodingT1:
+ // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ registers = registers & 0xdfff; // Make sure bit 13 is a zero.
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then
+ // UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 2) ||
+ (BitIsSet(opcode, 14) && BitIsSet(opcode, 15)))
+ return false;
+
+ // if registers<15> == '1' && InITBlock() && !LastInITBlock() then
+ // UNPREDICTABLE;
+ if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
+ return false;
+
+ // if wback && registers<n> == '1' then UNPREDICTABLE;
+ if (wback && BitIsSet(registers, n))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // n = UInt(Rn); registers = register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 1))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // address = R[n] - 4*BitCount(registers);
+
+ int32_t offset = 0;
+ addr_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+
+ if (!success)
+ return false;
+
+ addr_t address = Rn - (addr_byte_size * BitCount(registers));
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, Rn - address);
+
+ for (int i = 0; i < 14; ++i) {
+ if (BitIsSet(registers, i)) {
+ // R[i] = MemA[address,4]; address = address + 4;
+ context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset));
+ uint32_t data =
+ MemARead(context, address + offset, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
+ data))
+ return false;
+
+ offset += addr_byte_size;
+ }
+ }
+
+ // if registers<15> == '1' then
+ // LoadWritePC(MemA[address,4]);
+ if (BitIsSet(registers, 15)) {
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+ uint32_t data =
+ MemARead(context, address + offset, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+ // In ARMv5T and above, this is an interworking branch.
+ if (!LoadWritePC(context, data))
+ return false;
+ }
+
+ // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
+ if (wback && BitIsClear(registers, n)) {
+ if (!success)
+ return false;
+
+ offset = (addr_byte_size * BitCount(registers)) * -1;
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+ addr_t addr = Rn + offset;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ addr))
+ return false;
+ }
+
+ // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
+ // possible for encoding A1
+ if (wback && BitIsSet(registers, n))
+ return WriteBits32Unknown(n);
+ }
+ return true;
}
-// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The
-// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
+// LDMIB loads multiple registers from consecutive memory locations using an
+// address from a base register. The
+// consecutive memory locations start just above this address, and thea ddress
+// of the last of those locations can
// optinoally be written back to the base register.
-bool
-EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -3838,105 +3810,105 @@ EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding en
if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
- switch (encoding)
- {
- case eEncodingA1:
- // n = UInt(Rn); registers = register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
- if ((n == 15) || (BitCount (registers) < 1))
- return false;
-
- break;
- default:
- return false;
- }
- // address = R[n] + 4;
-
- int32_t offset = 0;
- addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
-
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ switch (encoding) {
+ case eEncodingA1:
+ // n = UInt(Rn); registers = register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 1))
+ return false;
+
+ break;
+ default:
+ return false;
+ }
+ // address = R[n] + 4;
+
+ int32_t offset = 0;
+ addr_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+
+ if (!success)
+ return false;
+
+ addr_t address = Rn + addr_byte_size;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+
+ for (int i = 0; i < 14; ++i) {
+ if (BitIsSet(registers, i)) {
+ // R[i] = MemA[address,4]; address = address + 4;
+
+ context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size);
+ uint32_t data =
+ MemARead(context, address + offset, addr_byte_size, 0, &success);
if (!success)
- return false;
-
- addr_t address = Rn + addr_byte_size;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
- context.SetRegisterPlusOffset (dwarf_reg, offset);
+ return false;
- for (int i = 0; i < 14; ++i)
- {
- if (BitIsSet (registers, i))
- {
- // R[i] = MemA[address,4]; address = address + 4;
-
- context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
- uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
- return false;
-
- offset += addr_byte_size;
- }
- }
-
- // if registers<15> == '1' then
- // LoadWritePC(MemA[address,4]);
- if (BitIsSet (registers, 15))
- {
- context.SetRegisterPlusOffset (dwarf_reg, offset);
- uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
- if (!success)
- return false;
- // In ARMv5T and above, this is an interworking branch.
- if (!LoadWritePC(context, data))
- return false;
- }
-
- // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
- if (wback && BitIsClear (registers, n))
- {
- if (!success)
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i,
+ data))
+ return false;
- offset = addr_byte_size * BitCount (registers);
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
- addr_t addr = Rn + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
- return false;
- }
-
- // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
- if (wback && BitIsSet (registers, n))
- return WriteBits32Unknown (n);
+ offset += addr_byte_size;
+ }
}
- return true;
+
+ // if registers<15> == '1' then
+ // LoadWritePC(MemA[address,4]);
+ if (BitIsSet(registers, 15)) {
+ context.SetRegisterPlusOffset(dwarf_reg, offset);
+ uint32_t data =
+ MemARead(context, address + offset, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+ // In ARMv5T and above, this is an interworking branch.
+ if (!LoadWritePC(context, data))
+ return false;
+ }
+
+ // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
+ if (wback && BitIsClear(registers, n)) {
+ if (!success)
+ return false;
+
+ offset = addr_byte_size * BitCount(registers);
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+ addr_t addr = Rn + offset;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ addr))
+ return false;
+ }
+
+ // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only
+ // possible for encoding A1
+ if (wback && BitIsSet(registers, n))
+ return WriteBits32Unknown(n);
+ }
+ return true;
}
-
-// Load Register (immediate) calculates an address from a base register value and
+
+// Load Register (immediate) calculates an address from a base register value
+// and
// an immediate offset, loads a word from memory, and writes to a register.
// LDR (immediate, Thumb)
-bool
-EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if (ConditionPassed())
@@ -3954,160 +3926,152 @@ EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncodi
}
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rt; // the destination register
- uint32_t Rn; // the base register
- uint32_t imm32; // the immediate offset used to form the address
- addr_t offset_addr; // the offset address
- addr_t address; // the calculated address
- uint32_t data; // the literal data value from memory load
- bool add, index, wback;
- switch (encoding) {
- case eEncodingT1:
- Rt = Bits32(opcode, 2, 0);
- Rn = Bits32(opcode, 5, 3);
- imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
- // index = TRUE; add = TRUE; wback = FALSE
- add = true;
- index = true;
- wback = false;
-
- break;
-
- case eEncodingT2:
- // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
- Rt = Bits32 (opcode, 10, 8);
- Rn = 13;
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- break;
-
- case eEncodingT3:
- // if Rn == '1111' then SEE LDR (literal);
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- Rt = Bits32 (opcode, 15, 12);
- Rn = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if ((Rt == 15) && InITBlock() && !LastInITBlock())
- return false;
-
- break;
-
- case eEncodingT4:
- // if Rn == '1111' then SEE LDR (literal);
- // if P == '1' && U == '1' && W == '0' then SEE LDRT;
- // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
- // if P == '0' && W == '0' then UNDEFINED;
- if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
- Rt = Bits32 (opcode, 15, 12);
- Rn = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 10);
- add = BitIsSet (opcode, 9);
- wback = BitIsSet (opcode, 8);
-
- // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
- if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
- return false;
-
- break;
-
- default:
- return false;
- }
- uint32_t base = ReadCoreReg (Rn, &success);
- if (!success)
- return false;
- if (add)
- offset_addr = base + imm32;
- else
- offset_addr = base - imm32;
+ if (ConditionPassed(opcode)) {
+ uint32_t Rt; // the destination register
+ uint32_t Rn; // the base register
+ uint32_t imm32; // the immediate offset used to form the address
+ addr_t offset_addr; // the offset address
+ addr_t address; // the calculated address
+ uint32_t data; // the literal data value from memory load
+ bool add, index, wback;
+ switch (encoding) {
+ case eEncodingT1:
+ Rt = Bits32(opcode, 2, 0);
+ Rn = Bits32(opcode, 5, 3);
+ imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
+ // index = TRUE; add = TRUE; wback = FALSE
+ add = true;
+ index = true;
+ wback = false;
- address = (index ? offset_addr : base);
+ break;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
- if (wback)
- {
- EmulateInstruction::Context ctx;
- if (Rn == 13)
- {
- ctx.type = eContextAdjustStackPointer;
- ctx.SetImmediateSigned((int32_t) (offset_addr - base));
- }
- else if (Rn == GetFramePointerRegisterNumber())
- {
- ctx.type = eContextSetFramePointer;
- ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
- }
- else
- {
- ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
- ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
- }
-
+ case eEncodingT2:
+ // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
+ Rt = Bits32(opcode, 10, 8);
+ Rn = 13;
+ imm32 = Bits32(opcode, 7, 0) << 2;
- if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
- return false;
- }
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
- // Prepare to write to the Rt register.
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
+ break;
- // Read memory from the address.
- data = MemURead(context, address, 4, 0, &success);
- if (!success)
- return false;
+ case eEncodingT3:
+ // if Rn == '1111' then SEE LDR (literal);
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ Rt = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if ((Rt == 15) && InITBlock() && !LastInITBlock())
+ return false;
- if (Rt == 15)
- {
- if (Bits32(address, 1, 0) == 0)
- {
- if (!LoadWritePC(context, data))
- return false;
- }
- else
- return false;
- }
- else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
- return false;
- }
- else
- WriteBits32Unknown (Rt);
+ break;
+
+ case eEncodingT4:
+ // if Rn == '1111' then SEE LDR (literal);
+ // if P == '1' && U == '1' && W == '0' then SEE LDRT;
+ // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 ==
+ // '00000100' then SEE POP;
+ // if P == '0' && W == '0' then UNDEFINED;
+ if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+ Rt = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 10);
+ add = BitIsSet(opcode, 9);
+ wback = BitIsSet(opcode, 8);
+
+ // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock())
+ // then UNPREDICTABLE;
+ if ((wback && (Rn == Rt)) ||
+ ((Rt == 15) && InITBlock() && !LastInITBlock()))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+ uint32_t base = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
+ if (add)
+ offset_addr = base + imm32;
+ else
+ offset_addr = base - imm32;
+
+ address = (index ? offset_addr : base);
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
+ if (wback) {
+ EmulateInstruction::Context ctx;
+ if (Rn == 13) {
+ ctx.type = eContextAdjustStackPointer;
+ ctx.SetImmediateSigned((int32_t)(offset_addr - base));
+ } else if (Rn == GetFramePointerRegisterNumber()) {
+ ctx.type = eContextSetFramePointer;
+ ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
+ } else {
+ ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
+ ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
+ }
+
+ if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn,
+ offset_addr))
+ return false;
+ }
+
+ // Prepare to write to the Rt register.
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base));
+
+ // Read memory from the address.
+ data = MemURead(context, address, 4, 0, &success);
+ if (!success)
+ return false;
+
+ if (Rt == 15) {
+ if (Bits32(address, 1, 0) == 0) {
+ if (!LoadWritePC(context, data))
+ return false;
+ } else
+ return false;
+ } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt,
+ data))
+ return false;
+ } else
+ WriteBits32Unknown(Rt);
+ }
+ return true;
}
-// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
-// from a base register. The consecutive memory locations start at this address, and the address just above the last
+// STM (Store Multiple Increment After) stores multiple registers to consecutive
+// memory locations using an address
+// from a base register. The consecutive memory locations start at this
+// address, and the address just above the last
// of those locations can optionally be written back to the base register.
-bool
-EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -4125,143 +4089,141 @@ EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding enco
MemA[address,4] = PCStoreValue();
if wback then R[n] = R[n] + 4*BitCount(registers);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
- n = Bits32 (opcode, 10, 8);
- registers = Bits32 (opcode, 7, 0);
- registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
- wback = true;
-
- // if BitCount(registers) < 1 then UNPREDICTABLE;
- if (BitCount (registers) < 1)
- return false;
-
- break;
-
- case eEncodingT2:
- // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
- if ((n == 15) || (BitCount (registers) < 2))
- return false;
-
- // if wback && registers<n> == '1' then UNPREDICTABLE;
- if (wback && BitIsSet (registers, n))
- return false;
-
- break;
-
- case eEncodingA1:
- // n = UInt(Rn); registers = register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
- if ((n == 15) || (BitCount (registers) < 1))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- // address = R[n];
- int32_t offset = 0;
- const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterStore;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- // for i = 0 to 14
- uint32_t lowest_set_bit = 14;
- for (uint32_t i = 0; i < 14; ++i)
- {
- // if registers<i> == '1' then
- if (BitIsSet (registers, i))
- {
- if (i < lowest_set_bit)
- lowest_set_bit = i;
- // if i == n && wback && i != LowestSetBit(registers) then
- if ((i == n) && wback && (i != lowest_set_bit))
- // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
- WriteBits32UnknownToMemory (address + offset);
- else
- {
- // MemA[address,4] = R[i];
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
- if (!success)
- return false;
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
- if (!MemAWrite (context, address + offset, data, addr_byte_size))
- return false;
- }
-
- // address = address + 4;
- offset += addr_byte_size;
- }
- }
-
- // if registers<15> == '1' then // Only possible for encoding A1
- // MemA[address,4] = PCStoreValue();
- if (BitIsSet (registers, 15))
- {
- RegisterInfo pc_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
- context.SetRegisterPlusOffset (pc_reg, 8);
- const uint32_t pc = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
-
- if (!MemAWrite (context, address + offset, pc, addr_byte_size))
- return false;
- }
-
- // if wback then R[n] = R[n] + 4*BitCount(registers);
- if (wback)
- {
- offset = addr_byte_size * BitCount (registers);
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
- addr_t data = address + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
+ n = Bits32(opcode, 10, 8);
+ registers = Bits32(opcode, 7, 0);
+ registers = registers & 0x00ff; // Make sure the top 8 bits are zeros.
+ wback = true;
+
+ // if BitCount(registers) < 1 then UNPREDICTABLE;
+ if (BitCount(registers) < 1)
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 2))
+ return false;
+
+ // if wback && registers<n> == '1' then UNPREDICTABLE;
+ if (wback && BitIsSet(registers, n))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // n = UInt(Rn); registers = register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 1))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // address = R[n];
+ int32_t offset = 0;
+ const addr_t address =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterStore;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ // for i = 0 to 14
+ uint32_t lowest_set_bit = 14;
+ for (uint32_t i = 0; i < 14; ++i) {
+ // if registers<i> == '1' then
+ if (BitIsSet(registers, i)) {
+ if (i < lowest_set_bit)
+ lowest_set_bit = i;
+ // if i == n && wback && i != LowestSetBit(registers) then
+ if ((i == n) && wback && (i != lowest_set_bit))
+ // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings
+ // T1 and A1
+ WriteBits32UnknownToMemory(address + offset);
+ else {
+ // MemA[address,4] = R[i];
+ uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
+ 0, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
+ if (!MemAWrite(context, address + offset, data, addr_byte_size))
+ return false;
+ }
+
+ // address = address + 4;
+ offset += addr_byte_size;
+ }
+ }
+
+ // if registers<15> == '1' then // Only possible for encoding A1
+ // MemA[address,4] = PCStoreValue();
+ if (BitIsSet(registers, 15)) {
+ RegisterInfo pc_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
+ context.SetRegisterPlusOffset(pc_reg, 8);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ if (!MemAWrite(context, address + offset, pc, addr_byte_size))
+ return false;
+ }
+
+ // if wback then R[n] = R[n] + 4*BitCount(registers);
+ if (wback) {
+ offset = addr_byte_size * BitCount(registers);
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+ addr_t data = address + offset;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ data))
+ return false;
+ }
+ }
+ return true;
}
-// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
-// from a base register. The consecutive memory locations end at this address, and the address just below the lowest
+// STMDA (Store Multiple Decrement After) stores multiple registers to
+// consecutive memory locations using an address
+// from a base register. The consecutive memory locations end at this address,
+// and the address just below the lowest
// of those locations can optionally be written back to the base register.
-bool
-EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -4280,113 +4242,110 @@ EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding en
if wback then R[n] = R[n] - 4*BitCount(registers);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingA1:
- // n = UInt(Rn); registers = register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
- if ((n == 15) || (BitCount (registers) < 1))
- return false;
- break;
- default:
- return false;
- }
-
- // address = R[n] - 4*BitCount(registers) + 4;
- int32_t offset = 0;
- addr_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterStore;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- // for i = 0 to 14
- uint32_t lowest_bit_set = 14;
- for (uint32_t i = 0; i < 14; ++i)
- {
- // if registers<i> == '1' then
- if (BitIsSet (registers, i))
- {
- if (i < lowest_bit_set)
- lowest_bit_set = i;
- //if i == n && wback && i != LowestSetBit(registers) then
- if ((i == n) && wback && (i != lowest_bit_set))
- // MemA[address,4] = bits(32) UNKNOWN;
- WriteBits32UnknownToMemory (address + offset);
- else
- {
- // MemA[address,4] = R[i];
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
- if (!success)
- return false;
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
- if (!MemAWrite (context, address + offset, data, addr_byte_size))
- return false;
- }
-
- // address = address + 4;
- offset += addr_byte_size;
- }
- }
-
- // if registers<15> == '1' then
- // MemA[address,4] = PCStoreValue();
- if (BitIsSet (registers, 15))
- {
- RegisterInfo pc_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
- context.SetRegisterPlusOffset (pc_reg, 8);
- const uint32_t pc = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
-
- if (!MemAWrite (context, address + offset, pc, addr_byte_size))
- return false;
- }
-
- // if wback then R[n] = R[n] - 4*BitCount(registers);
- if (wback)
- {
- offset = (addr_byte_size * BitCount (registers)) * -1;
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
- addr_t data = Rn + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingA1:
+ // n = UInt(Rn); registers = register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
+ if ((n == 15) || (BitCount(registers) < 1))
+ return false;
+ break;
+ default:
+ return false;
}
- return true;
+
+ // address = R[n] - 4*BitCount(registers) + 4;
+ int32_t offset = 0;
+ addr_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterStore;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ // for i = 0 to 14
+ uint32_t lowest_bit_set = 14;
+ for (uint32_t i = 0; i < 14; ++i) {
+ // if registers<i> == '1' then
+ if (BitIsSet(registers, i)) {
+ if (i < lowest_bit_set)
+ lowest_bit_set = i;
+ // if i == n && wback && i != LowestSetBit(registers) then
+ if ((i == n) && wback && (i != lowest_bit_set))
+ // MemA[address,4] = bits(32) UNKNOWN;
+ WriteBits32UnknownToMemory(address + offset);
+ else {
+ // MemA[address,4] = R[i];
+ uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
+ 0, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ Rn - (address + offset));
+ if (!MemAWrite(context, address + offset, data, addr_byte_size))
+ return false;
+ }
+
+ // address = address + 4;
+ offset += addr_byte_size;
+ }
+ }
+
+ // if registers<15> == '1' then
+ // MemA[address,4] = PCStoreValue();
+ if (BitIsSet(registers, 15)) {
+ RegisterInfo pc_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
+ context.SetRegisterPlusOffset(pc_reg, 8);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ if (!MemAWrite(context, address + offset, pc, addr_byte_size))
+ return false;
+ }
+
+ // if wback then R[n] = R[n] - 4*BitCount(registers);
+ if (wback) {
+ offset = (addr_byte_size * BitCount(registers)) * -1;
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+ addr_t data = Rn + offset;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ data))
+ return false;
+ }
+ }
+ return true;
}
-
-// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
-// from a base register. The consecutive memory locations end just below this address, and the address of the first of
+
+// STMDB (Store Multiple Decrement Before) stores multiple registers to
+// consecutive memory locations using an address
+// from a base register. The consecutive memory locations end just below this
+// address, and the address of the first of
// those locations can optionally be written back to the base register.
-bool
-EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -4406,138 +4365,136 @@ EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding en
if wback then R[n] = R[n] - 4*BitCount(registers);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // if W == '1' && Rn == '1101' then SEE PUSH;
- if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
- {
- // See PUSH
- }
- // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
- wback = BitIsSet (opcode, 21);
- // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
- if ((n == 15) || BitCount (registers) < 2)
- return false;
- // if wback && registers<n> == '1' then UNPREDICTABLE;
- if (wback && BitIsSet (registers, n))
- return false;
- break;
-
- case eEncodingA1:
- // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH;
- if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
- {
- // See Push
- }
- // n = UInt(Rn); registers = register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
- // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
- if ((n == 15) || BitCount (registers) < 1)
- return false;
- break;
-
- default:
- return false;
- }
-
- // address = R[n] - 4*BitCount(registers);
-
- int32_t offset = 0;
- addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // if W == '1' && Rn == '1101' then SEE PUSH;
+ if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) {
+ // See PUSH
+ }
+ // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
+ wback = BitIsSet(opcode, 21);
+ // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
+ if ((n == 15) || BitCount(registers) < 2)
return false;
-
- addr_t address = Rn - (addr_byte_size * BitCount (registers));
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterStore;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- // for i = 0 to 14
- uint32_t lowest_set_bit = 14;
- for (uint32_t i = 0; i < 14; ++i)
- {
- // if registers<i> == '1' then
- if (BitIsSet (registers, i))
- {
- if (i < lowest_set_bit)
- lowest_set_bit = i;
- // if i == n && wback && i != LowestSetBit(registers) then
- if ((i == n) && wback && (i != lowest_set_bit))
- // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
- WriteBits32UnknownToMemory (address + offset);
- else
- {
- // MemA[address,4] = R[i];
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
- if (!success)
- return false;
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
- if (!MemAWrite (context, address + offset, data, addr_byte_size))
- return false;
- }
-
- // address = address + 4;
- offset += addr_byte_size;
- }
- }
-
- // if registers<15> == '1' then // Only possible for encoding A1
- // MemA[address,4] = PCStoreValue();
- if (BitIsSet (registers, 15))
- {
- RegisterInfo pc_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
- context.SetRegisterPlusOffset (pc_reg, 8);
- const uint32_t pc = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
-
- if (!MemAWrite (context, address + offset, pc, addr_byte_size))
- return false;
- }
-
- // if wback then R[n] = R[n] - 4*BitCount(registers);
- if (wback)
- {
- offset = (addr_byte_size * BitCount (registers)) * -1;
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
- addr_t data = Rn + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
- return false;
- }
+ // if wback && registers<n> == '1' then UNPREDICTABLE;
+ if (wback && BitIsSet(registers, n))
+ return false;
+ break;
+
+ case eEncodingA1:
+ // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE
+ // PUSH;
+ if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) &&
+ BitCount(Bits32(opcode, 15, 0)) >= 2) {
+ // See Push
+ }
+ // n = UInt(Rn); registers = register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+ // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
+ if ((n == 15) || BitCount(registers) < 1)
+ return false;
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // address = R[n] - 4*BitCount(registers);
+
+ int32_t offset = 0;
+ addr_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t address = Rn - (addr_byte_size * BitCount(registers));
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterStore;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ // for i = 0 to 14
+ uint32_t lowest_set_bit = 14;
+ for (uint32_t i = 0; i < 14; ++i) {
+ // if registers<i> == '1' then
+ if (BitIsSet(registers, i)) {
+ if (i < lowest_set_bit)
+ lowest_set_bit = i;
+ // if i == n && wback && i != LowestSetBit(registers) then
+ if ((i == n) && wback && (i != lowest_set_bit))
+ // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding
+ // A1
+ WriteBits32UnknownToMemory(address + offset);
+ else {
+ // MemA[address,4] = R[i];
+ uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
+ 0, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ Rn - (address + offset));
+ if (!MemAWrite(context, address + offset, data, addr_byte_size))
+ return false;
+ }
+
+ // address = address + 4;
+ offset += addr_byte_size;
+ }
+ }
+
+ // if registers<15> == '1' then // Only possible for encoding A1
+ // MemA[address,4] = PCStoreValue();
+ if (BitIsSet(registers, 15)) {
+ RegisterInfo pc_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
+ context.SetRegisterPlusOffset(pc_reg, 8);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ if (!MemAWrite(context, address + offset, pc, addr_byte_size))
+ return false;
+ }
+
+ // if wback then R[n] = R[n] - 4*BitCount(registers);
+ if (wback) {
+ offset = (addr_byte_size * BitCount(registers)) * -1;
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+ addr_t data = Rn + offset;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ data))
+ return false;
+ }
+ }
+ return true;
}
-
-// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
-// from a base register. The consecutive memory locations start just above this address, and the address of the last
+
+// STMIB (Store Multiple Increment Before) stores multiple registers to
+// consecutive memory locations using an address
+// from a base register. The consecutive memory locations start just above this
+// address, and the address of the last
// of those locations can optionally be written back to the base register.
-bool
-EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -4555,114 +4512,111 @@ EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding en
MemA[address,4] = PCStoreValue();
if wback then R[n] = R[n] + 4*BitCount(registers);
-#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- uint32_t registers = 0;
- bool wback;
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingA1:
- // n = UInt(Rn); registers = register_list; wback = (W == '1');
- n = Bits32 (opcode, 19, 16);
- registers = Bits32 (opcode, 15, 0);
- wback = BitIsSet (opcode, 21);
-
- // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
- if ((n == 15) && (BitCount (registers) < 1))
- return false;
- break;
- default:
- return false;
- }
- // address = R[n] + 4;
-
- int32_t offset = 0;
- addr_t Rn = ReadCoreReg (n, &success);
- if (!success)
+#endif
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t registers = 0;
+ bool wback;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingA1:
+ // n = UInt(Rn); registers = register_list; wback = (W == '1');
+ n = Bits32(opcode, 19, 16);
+ registers = Bits32(opcode, 15, 0);
+ wback = BitIsSet(opcode, 21);
+
+ // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
+ if ((n == 15) && (BitCount(registers) < 1))
+ return false;
+ break;
+ default:
+ return false;
+ }
+ // address = R[n] + 4;
+
+ int32_t offset = 0;
+ addr_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ addr_t address = Rn + addr_byte_size;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRegisterStore;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t lowest_set_bit = 14;
+ // for i = 0 to 14
+ for (uint32_t i = 0; i < 14; ++i) {
+ // if registers<i> == '1' then
+ if (BitIsSet(registers, i)) {
+ if (i < lowest_set_bit)
+ lowest_set_bit = i;
+ // if i == n && wback && i != LowestSetBit(registers) then
+ if ((i == n) && wback && (i != lowest_set_bit))
+ // MemA[address,4] = bits(32) UNKNOWN;
+ WriteBits32UnknownToMemory(address + offset);
+ // else
+ else {
+ // MemA[address,4] = R[i];
+ uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i,
+ 0, &success);
+ if (!success)
return false;
-
- addr_t address = Rn + addr_byte_size;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRegisterStore;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t lowest_set_bit = 14;
- // for i = 0 to 14
- for (uint32_t i = 0; i < 14; ++i)
- {
- // if registers<i> == '1' then
- if (BitIsSet (registers, i))
- {
- if (i < lowest_set_bit)
- lowest_set_bit = i;
- // if i == n && wback && i != LowestSetBit(registers) then
- if ((i == n) && wback && (i != lowest_set_bit))
- // MemA[address,4] = bits(32) UNKNOWN;
- WriteBits32UnknownToMemory (address + offset);
- // else
- else
- {
- // MemA[address,4] = R[i];
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
- if (!success)
- return false;
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
- if (!MemAWrite (context, address + offset, data, addr_byte_size))
- return false;
- }
-
- // address = address + 4;
- offset += addr_byte_size;
- }
- }
-
- // if registers<15> == '1' then
- // MemA[address,4] = PCStoreValue();
- if (BitIsSet (registers, 15))
- {
- RegisterInfo pc_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
- context.SetRegisterPlusOffset (pc_reg, 8);
- const uint32_t pc = ReadCoreReg (PC_REG, &success);
- if (!success)
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg);
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ offset + addr_byte_size);
+ if (!MemAWrite(context, address + offset, data, addr_byte_size))
return false;
-
- if (!MemAWrite (context, address + offset, pc, addr_byte_size))
- return false;
- }
-
- // if wback then R[n] = R[n] + 4*BitCount(registers);
- if (wback)
- {
- offset = addr_byte_size * BitCount (registers);
- context.type = EmulateInstruction::eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
- addr_t data = Rn + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
- return false;
}
+
+ // address = address + 4;
+ offset += addr_byte_size;
+ }
}
- return true;
+
+ // if registers<15> == '1' then
+ // MemA[address,4] = PCStoreValue();
+ if (BitIsSet(registers, 15)) {
+ RegisterInfo pc_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg);
+ context.SetRegisterPlusOffset(pc_reg, 8);
+ const uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ if (!MemAWrite(context, address + offset, pc, addr_byte_size))
+ return false;
+ }
+
+ // if wback then R[n] = R[n] + 4*BitCount(registers);
+ if (wback) {
+ offset = addr_byte_size * BitCount(registers);
+ context.type = EmulateInstruction::eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+ addr_t data = Rn + offset;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ data))
+ return false;
+ }
+ }
+ return true;
}
-// STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
-// from a register to memory. It can use offset, post-indexed, or pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
-{
+// STR (store immediate) calculates an address from a base register value and an
+// immediate offset, and stores a word
+// from a register to memory. It can use offset, post-indexed, or pre-indexed
+// addressing.
+bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -4674,163 +4628,162 @@ EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding
MemU[address,4] = bits(32) UNKNOWN;
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
- // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- imm32 = Bits32 (opcode, 10, 6) << 2;
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = false;
- wback = false;
- break;
-
- case eEncodingT2:
- // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
- t = Bits32 (opcode, 10, 8);
- n = 13;
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
- break;
-
- case eEncodingT3:
- // if Rn == '1111' then UNDEFINED;
- if (Bits32 (opcode, 19, 16) == 15)
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // if t == 15 then UNPREDICTABLE;
- if (t == 15)
- return false;
- break;
-
- case eEncodingT4:
- // if P == '1' && U == '1' && W == '0' then SEE STRT;
- // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
- // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
- if ((Bits32 (opcode, 19, 16) == 15)
- || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 10);
- add = BitIsSet (opcode, 9);
- wback = BitIsSet (opcode, 8);
-
- // if t == 15 || (wback && n == t) then UNPREDICTABLE;
- if ((t == 15) || (wback && (n == t)))
- return false;
- break;
-
- default:
- return false;
- }
-
- addr_t offset_addr;
- addr_t address;
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- uint32_t base_address = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- if (add)
- offset_addr = base_address + imm32;
- else
- offset_addr = base_address - imm32;
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = base_address;
-
- EmulateInstruction::Context context;
- if (n == 13)
- context.type = eContextPushRegisterOnStack;
- else
- context.type = eContextRegisterStore;
+ bool success = false;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- // if UnalignedSupport() || address<1:0> == '00' then
- if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
- {
- // MemU[address,4] = R[t];
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
- if (!success)
- return false;
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
- int32_t offset = address - base_address;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
- if (!MemUWrite (context, address, data, addr_byte_size))
- return false;
- }
- else
- {
- // MemU[address,4] = bits(32) UNKNOWN;
- WriteBits32UnknownToMemory (address);
- }
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- if (n == 13)
- context.type = eContextAdjustStackPointer;
- else
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+ // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ imm32 = Bits32(opcode, 10, 6) << 2;
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = false;
+ wback = false;
+ break;
+
+ case eEncodingT2:
+ // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
+ t = Bits32(opcode, 10, 8);
+ n = 13;
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+ break;
+
+ case eEncodingT3:
+ // if Rn == '1111' then UNDEFINED;
+ if (Bits32(opcode, 19, 16) == 15)
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // if t == 15 then UNPREDICTABLE;
+ if (t == 15)
+ return false;
+ break;
+
+ case eEncodingT4:
+ // if P == '1' && U == '1' && W == '0' then SEE STRT;
+ // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 ==
+ // '00000100' then SEE PUSH;
+ // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
+ if ((Bits32(opcode, 19, 16) == 15) ||
+ (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)))
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 10);
+ add = BitIsSet(opcode, 9);
+ wback = BitIsSet(opcode, 8);
+
+ // if t == 15 || (wback && n == t) then UNPREDICTABLE;
+ if ((t == 15) || (wback && (n == t)))
+ return false;
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ uint32_t base_address = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ if (add)
+ offset_addr = base_address + imm32;
+ else
+ offset_addr = base_address - imm32;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = base_address;
+
+ EmulateInstruction::Context context;
+ if (n == 13)
+ context.type = eContextPushRegisterOnStack;
+ else
+ context.type = eContextRegisterStore;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ // if UnalignedSupport() || address<1:0> == '00' then
+ if (UnalignedSupport() ||
+ (BitIsClear(address, 1) && BitIsClear(address, 0))) {
+ // MemU[address,4] = R[t];
+ uint32_t data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+ int32_t offset = address - base_address;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset);
+ if (!MemUWrite(context, address, data, addr_byte_size))
+ return false;
+ } else {
+ // MemU[address,4] = bits(32) UNKNOWN;
+ WriteBits32UnknownToMemory(address);
+ }
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ if (n == 13)
+ context.type = eContextAdjustStackPointer;
+ else
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
-// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
-// word from a register to memory. The offset register value can optionally be shifted.
-bool
-EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+// STR (Store Register) calculates an address from a base register value and an
+// offset register value, stores a
+// word from a register to memory. The offset register value can optionally be
+// shifted.
+bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -4847,180 +4800,180 @@ EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncod
MemU[address,4] = bits(32) UNKNOWN;
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- uint32_t t;
- uint32_t n;
- uint32_t m;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
- bool index;
- bool add;
- bool wback;
-
- // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
-
- case eEncodingT2:
- // if Rn == '1111' then UNDEFINED;
- if (Bits32 (opcode, 19, 16) == 15)
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
- shift_t = SRType_LSL;
- shift_n = Bits32 (opcode, 5, 4);
-
- // if t == 15 || BadReg(m) then UNPREDICTABLE;
- if ((t == 15) || (BadReg (m)))
- return false;
- break;
-
- case eEncodingA1:
- {
- // if P == '0' && W == '1' then SEE STRT;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm5);
- uint32_t typ = Bits32 (opcode, 6, 5);
- uint32_t imm5 = Bits32 (opcode, 11, 7);
- shift_n = DecodeImmShift(typ, imm5, shift_t);
-
- // if m == 15 then UNPREDICTABLE;
- if (m == 15)
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
-
- break;
- }
- default:
- return false;
- }
-
- addr_t offset_addr;
- addr_t address;
- int32_t offset = 0;
-
- addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- // offset = Shift(R[m], shift_t, shift_n, APSR.C);
- offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
-
- // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
- if (add)
- offset_addr = base_address + offset;
- else
- offset_addr = base_address - offset;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = base_address;
-
- uint32_t data;
- // if t == 15 then // Only possible for encoding A1
- if (t == 15)
- // data = PCStoreValue();
- data = ReadCoreReg (PC_REG, &success);
- else
- // data = R[t];
- data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
-
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
-
- // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
- if (UnalignedSupport ()
- || (BitIsClear (address, 1) && BitIsClear (address, 0))
- || CurrentInstrSet() == eModeARM)
- {
- // MemU[address,4] = data;
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
-
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
- if (!MemUWrite (context, address, data, addr_byte_size))
- return false;
-
- }
- else
- // MemU[address,4] = bits(32) UNKNOWN;
- WriteBits32UnknownToMemory (address);
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextRegisterLoad;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ uint32_t t;
+ uint32_t n;
+ uint32_t m;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+ bool index;
+ bool add;
+ bool wback;
+
+ // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
+ // in ThumbEE";
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+
+ case eEncodingT2:
+ // if Rn == '1111' then UNDEFINED;
+ if (Bits32(opcode, 19, 16) == 15)
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
+ shift_t = SRType_LSL;
+ shift_n = Bits32(opcode, 5, 4);
+
+ // if t == 15 || BadReg(m) then UNPREDICTABLE;
+ if ((t == 15) || (BadReg(m)))
+ return false;
+ break;
+
+ case eEncodingA1: {
+ // if P == '0' && W == '1' then SEE STRT;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm5);
+ uint32_t typ = Bits32(opcode, 6, 5);
+ uint32_t imm5 = Bits32(opcode, 11, 7);
+ shift_n = DecodeImmShift(typ, imm5, shift_t);
+
+ // if m == 15 then UNPREDICTABLE;
+ if (m == 15)
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+
+ break;
}
- return true;
+ default:
+ return false;
+ }
+
+ addr_t offset_addr;
+ addr_t address;
+ int32_t offset = 0;
+
+ addr_t base_address =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ uint32_t Rm_data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C);
+ offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
+ if (add)
+ offset_addr = base_address + offset;
+ else
+ offset_addr = base_address - offset;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = base_address;
+
+ uint32_t data;
+ // if t == 15 then // Only possible for encoding A1
+ if (t == 15)
+ // data = PCStoreValue();
+ data = ReadCoreReg(PC_REG, &success);
+ else
+ // data = R[t];
+ data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
+
+ if (!success)
+ return false;
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+
+ // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() ==
+ // InstrSet_ARM then
+ if (UnalignedSupport() ||
+ (BitIsClear(address, 1) && BitIsClear(address, 0)) ||
+ CurrentInstrSet() == eModeARM) {
+ // MemU[address,4] = data;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ address - base_address);
+ if (!MemUWrite(context, address, data, addr_byte_size))
+ return false;
+
+ } else
+ // MemU[address,4] = bits(32) UNKNOWN;
+ WriteBits32UnknownToMemory(address);
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextRegisterLoad;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
-bool
-EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -5030,134 +4983,134 @@ EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncodin
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- imm32 = Bits32 (opcode, 10, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
- break;
-
- case eEncodingT2:
- // if Rn == '1111' then UNDEFINED;
- if (Bits32 (opcode, 19, 16) == 15)
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // if BadReg(t) then UNPREDICTABLE;
- if (BadReg (t))
- return false;
- break;
-
- case eEncodingT3:
- // if P == '1' && U == '1' && W == '0' then SEE STRBT;
- // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
- if (Bits32 (opcode, 19, 16) == 15)
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 10);
- add = BitIsSet (opcode, 9);
- wback = BitIsSet (opcode, 8);
-
- // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
- if ((BadReg (t)) || (wback && (n == t)))
- return false;
- break;
-
- default:
- return false;
- }
-
- addr_t offset_addr;
- addr_t address;
- addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- if (add)
- offset_addr = base_address + imm32;
- else
- offset_addr = base_address - imm32;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = base_address;
-
- // MemU[address,1] = R[t]<7:0>
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
-
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
- if (!success)
- return false;
-
- data = Bits32 (data, 7, 0);
+ bool success = false;
- if (!MemUWrite (context, address, data, 1))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextRegisterLoad;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
-
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ imm32 = Bits32(opcode, 10, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+ break;
+
+ case eEncodingT2:
+ // if Rn == '1111' then UNDEFINED;
+ if (Bits32(opcode, 19, 16) == 15)
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // if BadReg(t) then UNPREDICTABLE;
+ if (BadReg(t))
+ return false;
+ break;
+
+ case eEncodingT3:
+ // if P == '1' && U == '1' && W == '0' then SEE STRBT;
+ // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
+ if (Bits32(opcode, 19, 16) == 15)
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 10);
+ add = BitIsSet(opcode, 9);
+ wback = BitIsSet(opcode, 8);
+
+ // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
+ if ((BadReg(t)) || (wback && (n == t)))
+ return false;
+ break;
+
+ default:
+ return false;
}
- return true;
+ addr_t offset_addr;
+ addr_t address;
+ addr_t base_address =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ if (add)
+ offset_addr = base_address + imm32;
+ else
+ offset_addr = base_address - imm32;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = base_address;
+
+ // MemU[address,1] = R[t]<7:0>
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ address - base_address);
+
+ uint32_t data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
+ if (!success)
+ return false;
+
+ data = Bits32(data, 7, 0);
+
+ if (!MemUWrite(context, address, data, 1))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextRegisterLoad;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+
+ return true;
}
-// STRH (register) calculates an address from a base register value and an offset register value, and stores a
-// halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits.
-bool
-EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+// STRH (register) calculates an address from a base register value and an
+// offset register value, and stores a
+// halfword from a register to memory. The offset register value can be shifted
+// left by 0, 1, 2, or 3 bits.
+bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -5170,174 +5123,174 @@ EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEnco
MemU[address,2] = bits(16) UNKNOWN;
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
+ // in ThumbEE";
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ break;
+
+ case eEncodingT2:
+ // if Rn == '1111' then UNDEFINED;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+ if (n == 15)
+ return false;
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
+ shift_t = SRType_LSL;
+ shift_n = Bits32(opcode, 5, 4);
+
+ // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
+ if (BadReg(t) || BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // if P == '0' && W == '1' then SEE STRHT;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ // if t == 15 || m == 15 then UNPREDICTABLE;
+ if ((t == 15) || (m == 15))
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C);
+ uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + offset;
+ else
+ offset_addr = Rn - offset;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ RegisterInfo offset_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
+
+ // if UnalignedSupport() || address<0> == '0' then
+ if (UnalignedSupport() || BitIsClear(address, 0)) {
+ // MemU[address,2] = R[t]<15:0>;
+ uint32_t Rt = ReadCoreReg(t, &success);
+ if (!success)
+ return false;
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ RegisterInfo offset_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+ context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
+ data_reg);
+
+ if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2))
+ return false;
+ } else // Can only occur before ARMv7
{
- uint32_t t;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- break;
-
- case eEncodingT2:
- // if Rn == '1111' then UNDEFINED;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
- if (n == 15)
- return false;
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
- shift_t = SRType_LSL;
- shift_n = Bits32 (opcode, 5, 4);
-
- // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
- if (BadReg (t) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // if P == '0' && W == '1' then SEE STRHT;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- // if t == 15 || m == 15 then UNPREDICTABLE;
- if ((t == 15) || (m == 15))
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // offset = Shift(R[m], shift_t, shift_n, APSR.C);
- uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
-
- // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + offset;
- else
- offset_addr = Rn - offset;
-
- // address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- RegisterInfo offset_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
-
- // if UnalignedSupport() || address<0> == '0' then
- if (UnalignedSupport() || BitIsClear (address, 0))
- {
- // MemU[address,2] = R[t]<15:0>;
- uint32_t Rt = ReadCoreReg (t, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- RegisterInfo offset_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
- context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
-
- if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
- return false;
- }
- else // Can only occur before ARMv7
- {
- // MemU[address,2] = bits(16) UNKNOWN;
- }
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+ // MemU[address,2] = bits(16) UNKNOWN;
}
- return true;
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+
+ return true;
}
-
-// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
-// and writes the result to the destination register. It can optionally update the condition flags
+
+// Add with Carry (immediate) adds an immediate value and the carry flag value
+// to a register value,
+// and writes the result to the destination register. It can optionally update
+// the condition flags
// based on the result.
-bool
-EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -5354,59 +5307,60 @@ EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn;
- uint32_t imm32; // the immediate value to be added to the value obtained from Rn
- bool setflags;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
- if (BadReg(Rd) || BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
-
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn;
+ uint32_t
+ imm32; // the immediate value to be added to the value obtained from Rn
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
+ if (BadReg(Rd) || BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- int32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ int32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
+ AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ 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;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
}
-// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
-// register value, and writes the result to the destination register. It can optionally update the
+// Add with Carry (register) adds a register value, the carry flag value, and an
+// optionally-shifted
+// register value, and writes the result to the destination register. It can
+// optionally update the
// condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -5424,76 +5378,75 @@ EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- bool setflags;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ bool setflags;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- int32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ int32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- int32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ int32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
+ uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ 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;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
}
-// This instruction adds an immediate value to the PC value to form a PC-relative address,
+// This instruction adds an immediate value to the PC value to form a
+// PC-relative address,
// and writes the result to the destination register.
-bool
-EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADR(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -5505,60 +5458,59 @@ EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding enco
R[d] = result;
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd;
- uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
- bool add;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Bits32(opcode, 10, 8);
- imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
- add = true;
- break;
- case eEncodingT2:
- case eEncodingT3:
- Rd = Bits32(opcode, 11, 8);
- imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
- add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
- if (BadReg(Rd))
- return false;
- break;
- case eEncodingA1:
- case eEncodingA2:
- Rd = Bits32(opcode, 15, 12);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
- add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd;
+ uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
+ bool add;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 10, 8);
+ imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
+ add = true;
+ break;
+ case eEncodingT2:
+ case eEncodingT3:
+ Rd = Bits32(opcode, 11, 8);
+ imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
+ add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
+ if (BadReg(Rd))
+ return false;
+ break;
+ case eEncodingA1:
+ case eEncodingA2:
+ Rd = Bits32(opcode, 15, 12);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+ add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
+ break;
+ default:
+ return false;
+ }
- // Read the PC value.
- uint32_t pc = ReadCoreReg(PC_REG, &success);
- if (!success)
- return false;
+ // Read the PC value.
+ uint32_t pc = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
- uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
+ uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreReg(context, result, Rd))
- return false;
- }
- return true;
+ if (!WriteCoreReg(context, result, Rd))
+ return false;
+ }
+ return true;
}
-// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
-// to the destination register. It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+// This instruction performs a bitwise AND of a register value and an immediate
+// value, and writes the result
+// to the destination register. It can optionally update the condition flags
+// based on the result.
+bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -5575,63 +5527,67 @@ EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn;
- uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
- bool setflags;
- uint32_t carry; // the carry bit after ARM/Thumb Expand operation
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
- // if Rd == '1111' && S == '1' then SEE TST (immediate);
- if (Rd == 15 && setflags)
- return EmulateTSTImm(opcode, eEncodingT1);
- if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
-
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn;
+ uint32_t
+ imm32; // the immediate value to be ANDed to the value obtained from Rn
+ bool setflags;
+ uint32_t carry; // the carry bit after ARM/Thumb Expand operation
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm_C(
+ opcode, APSR_C,
+ carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
+ // if Rd == '1111' && S == '1' then SEE TST (immediate);
+ if (Rd == 15 && setflags)
+ return EmulateTSTImm(opcode, eEncodingT1);
+ if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 =
+ ARMExpandImm_C(opcode, APSR_C,
+ carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
+
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t result = val1 & imm32;
+ uint32_t result = val1 & imm32;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
-// and writes the result to the destination register. It can optionally update the condition flags
+// This instruction performs a bitwise AND of a register value and an
+// optionally-shifted register value,
+// and writes the result to the destination register. It can optionally update
+// the condition flags
// based on the result.
-bool
-EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -5649,81 +5605,80 @@ EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- bool setflags;
- uint32_t carry;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- // if Rd == '1111' && S == '1' then SEE TST (register);
- if (Rd == 15 && setflags)
- return EmulateTSTReg(opcode, eEncodingT2);
- if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ bool setflags;
+ uint32_t carry;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ // if Rd == '1111' && S == '1' then SEE TST (register);
+ if (Rd == 15 && setflags)
+ return EmulateTSTReg(opcode, eEncodingT2);
+ if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
- if (!success)
- return false;
- uint32_t result = val1 & shifted;
+ uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
+ if (!success)
+ return false;
+ uint32_t result = val1 & shifted;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
-// immediate value, and writes the result to the destination register. It can optionally update the
+// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and
+// the complement of an
+// immediate value, and writes the result to the destination register. It can
+// optionally update the
// condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -5740,61 +5695,66 @@ EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn;
- uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
- bool setflags;
- uint32_t carry; // the carry bit after ARM/Thumb Expand operation
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
- if (BadReg(Rd) || BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn;
+ uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to
+ // the value obtained from Rn
+ bool setflags;
+ uint32_t carry; // the carry bit after ARM/Thumb Expand operation
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm_C(
+ opcode, APSR_C,
+ carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
+ if (BadReg(Rd) || BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 =
+ ARMExpandImm_C(opcode, APSR_C,
+ carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t result = val1 & ~imm32;
+ uint32_t result = val1 & ~imm32;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
-// optionally-shifted register value, and writes the result to the destination register.
+// Bitwise Bit Clear (register) performs a bitwise AND of a register value and
+// the complement of an
+// optionally-shifted register value, and writes the result to the destination
+// register.
// It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -5812,78 +5772,78 @@ EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- bool setflags;
- uint32_t carry;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ bool setflags;
+ uint32_t carry;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
- if (!success)
- return false;
- uint32_t result = val1 & ~shifted;
+ uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
+ if (!success)
+ return false;
+ uint32_t result = val1 & ~shifted;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
-// from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
-{
+// LDR (immediate, ARM) calculates an address from a base register value and an
+// immediate offset, loads a word
+// from memory, and writes it to a register. It can use offset, post-indexed,
+// or pre-indexed addressing.
+bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -5898,131 +5858,129 @@ EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARME
else // Can only apply before ARMv7
R[t] = ROR(data, 8*UInt(address<1:0>));
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- switch (encoding)
- {
- case eEncodingA1:
- // if Rn == '1111' then SEE LDR (literal);
- // if P == '0' && W == '1' then SEE LDRT;
- // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
- // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- // if wback && n == t then UNPREDICTABLE;
- if (wback && (n == t))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- addr_t address;
- addr_t offset_addr;
- addr_t base_address = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- if (add)
- offset_addr = base_address + imm32;
- else
- offset_addr = base_address - imm32;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = base_address;
-
- // data = MemU[address,4];
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - base_address);
-
- uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
-
- // if t == 15 then
- if (t == 15)
- {
- // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
- if (BitIsClear (address, 1) && BitIsClear (address, 0))
- {
- // LoadWritePC (data);
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - base_address);
- LoadWritePC (context, data);
- }
- else
- return false;
- }
- // elsif UnalignedSupport() || address<1:0> = '00' then
- else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
- {
- // R[t] = data;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - base_address);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
- }
- // else // Can only apply before ARMv7
- else
- {
- // R[t] = ROR(data, 8*UInt(address<1:0>));
- data = ROR (data, Bits32 (address, 1, 0), &success);
- if (!success)
- return false;
- context.type = eContextRegisterLoad;
- context.SetImmediate (data);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
- }
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ switch (encoding) {
+ case eEncodingA1:
+ // if Rn == '1111' then SEE LDR (literal);
+ // if P == '0' && W == '1' then SEE LDRT;
+ // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 ==
+ // '000000000100' then SEE POP;
+ // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ // if wback && n == t then UNPREDICTABLE;
+ if (wback && (n == t))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ addr_t address;
+ addr_t offset_addr;
+ addr_t base_address = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ if (add)
+ offset_addr = base_address + imm32;
+ else
+ offset_addr = base_address - imm32;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = base_address;
+
+ // data = MemU[address,4];
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - base_address);
+
+ uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+
+ // if t == 15 then
+ if (t == 15) {
+ // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
+ if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
+ // LoadWritePC (data);
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - base_address);
+ LoadWritePC(context, data);
+ } else
+ return false;
+ }
+ // elsif UnalignedSupport() || address<1:0> = '00' then
+ else if (UnalignedSupport() ||
+ (BitIsClear(address, 1) && BitIsClear(address, 0))) {
+ // R[t] = data;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - base_address);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ data))
+ return false;
+ }
+ // else // Can only apply before ARMv7
+ else {
+ // R[t] = ROR(data, 8*UInt(address<1:0>));
+ data = ROR(data, Bits32(address, 1, 0), &success);
+ if (!success)
+ return false;
+ context.type = eContextRegisterLoad;
+ context.SetImmediate(data);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ data))
+ return false;
+ }
+ }
+ return true;
}
-
-// LDR (register) calculates an address from a base register value and an offset register value, loads a word
-// from memory, and writes it to a register. The offset register value can optionally be shifted.
-bool
-EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+// LDR (register) calculates an address from a base register value and an offset
+// register value, loads a word
+// from memory, and writes it to a register. The offset register value can
+// optionally be shifted.
+bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -6041,200 +5999,195 @@ EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncod
else
R[t] = bits(32) UNKNOWN;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ uint32_t t;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+
+ switch (encoding) {
+ case eEncodingT1:
+ // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
+ // in ThumbEE";
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ break;
+
+ case eEncodingT2:
+ // if Rn == '1111' then SEE LDR (literal);
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
+ shift_t = SRType_LSL;
+ shift_n = Bits32(opcode, 5, 4);
+
+ // if BadReg(m) then UNPREDICTABLE;
+ if (BadReg(m))
+ return false;
+
+ // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if ((t == 15) && InITBlock() && !LastInITBlock())
+ return false;
+
+ break;
+
+ case eEncodingA1: {
+ // if P == '0' && W == '1' then SEE LDRT;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm5);
+ uint32_t type = Bits32(opcode, 6, 5);
+ uint32_t imm5 = Bits32(opcode, 11, 7);
+ shift_n = DecodeImmShift(type, imm5, shift_t);
+
+ // if m == 15 then UNPREDICTABLE;
+ if (m == 15)
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+ } break;
+
+ default:
+ return false;
+ }
+
+ uint32_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ uint32_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an
+ // application level alias for the CPSR".
+ addr_t offset =
+ Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
+ if (add)
+ offset_addr = Rn + offset;
+ else
+ offset_addr = Rn - offset;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // data = MemU[address,4];
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+
+ uint64_t data = MemURead(context, address, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+
+ // if t == 15 then
+ if (t == 15) {
+ // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
+ if (BitIsClear(address, 1) && BitIsClear(address, 0)) {
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+ LoadWritePC(context, data);
+ } else
+ return false;
+ }
+ // elsif UnalignedSupport() || address<1:0> = '00' then
+ else if (UnalignedSupport() ||
+ (BitIsClear(address, 1) && BitIsClear(address, 0))) {
+ // R[t] = data;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ data))
+ return false;
+ } else // Can only apply before ARMv7
{
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- uint32_t t;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
-
- switch (encoding)
- {
- case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- break;
-
- case eEncodingT2:
- // if Rn == '1111' then SEE LDR (literal);
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
- shift_t = SRType_LSL;
- shift_n = Bits32 (opcode, 5, 4);
-
- // if BadReg(m) then UNPREDICTABLE;
- if (BadReg (m))
- return false;
-
- // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if ((t == 15) && InITBlock() && !LastInITBlock())
- return false;
-
- break;
-
- case eEncodingA1:
- {
- // if P == '0' && W == '1' then SEE LDRT;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm5);
- uint32_t type = Bits32 (opcode, 6, 5);
- uint32_t imm5 = Bits32 (opcode, 11, 7);
- shift_n = DecodeImmShift (type, imm5, shift_t);
-
- // if m == 15 then UNPREDICTABLE;
- if (m == 15)
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
- }
- break;
-
-
- default:
- return false;
- }
-
- uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ // if CurrentInstrSet() == InstrSet_ARM then
+ if (CurrentInstrSet() == eModeARM) {
+ // R[t] = ROR(data, 8*UInt(address<1:0>));
+ data = ROR(data, Bits32(address, 1, 0), &success);
if (!success)
- return false;
-
- addr_t offset_addr;
- addr_t address;
-
- // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR".
- addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
- if (!success)
- return false;
-
- // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
- if (add)
- offset_addr = Rn + offset;
- else
- offset_addr = Rn - offset;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // data = MemU[address,4];
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
+ return false;
context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
-
- uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
-
- // if t == 15 then
- if (t == 15)
- {
- // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
- if (BitIsClear (address, 1) && BitIsClear (address, 0))
- {
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
- LoadWritePC (context, data);
- }
- else
- return false;
- }
- // elsif UnalignedSupport() || address<1:0> = '00' then
- else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
- {
- // R[t] = data;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
- }
- else // Can only apply before ARMv7
- {
- // if CurrentInstrSet() == InstrSet_ARM then
- if (CurrentInstrSet () == eModeARM)
- {
- // R[t] = ROR(data, 8*UInt(address<1:0>));
- data = ROR (data, Bits32 (address, 1, 0), &success);
- if (!success)
- return false;
- context.type = eContextRegisterLoad;
- context.SetImmediate (data);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
- }
- else
- {
- // R[t] = bits(32) UNKNOWN;
- WriteBits32Unknown (t);
- }
- }
+ context.SetImmediate(data);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ data))
+ return false;
+ } else {
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
+ }
}
- return true;
+ }
+ return true;
}
// LDRB (immediate, Thumb)
-bool
-EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -6243,146 +6196,145 @@ EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEnc
R[t] = ZeroExtend(MemU[address,1], 32);
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- imm32 = Bits32 (opcode, 10, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback= false;
-
- break;
-
- case eEncodingT2:
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // if Rt == '1111' then SEE PLD;
- if (t == 15)
- return false; // PLD is not implemented yet
-
- // if Rn == '1111' then SEE LDRB (literal);
- if (n == 15)
- return EmulateLDRBLiteral(opcode, eEncodingT1);
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
-
- break;
-
- case eEncodingT3:
- // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
- // if P == '0' && W == '0' then UNDEFINED;
- if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 10);
- add = BitIsSet (opcode, 9);
- wback = BitIsSet (opcode, 8);
-
- // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
- if (t == 15)
- return false; // PLD is not implemented yet
-
- // if Rn == '1111' then SEE LDRB (literal);
- if (n == 15)
- return EmulateLDRBLiteral(opcode, eEncodingT1);
-
- // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
- if (BadReg (t) || (wback && (n == t)))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- addr_t address;
- addr_t offset_addr;
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // R[t] = ZeroExtend(MemU[address,1], 32);
- RegisterInfo base_reg;
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
-
- uint64_t data = MemURead (context, address, 1, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ imm32 = Bits32(opcode, 10, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ break;
+
+ case eEncodingT2:
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // if Rt == '1111' then SEE PLD;
+ if (t == 15)
+ return false; // PLD is not implemented yet
+
+ // if Rn == '1111' then SEE LDRB (literal);
+ if (n == 15)
+ return EmulateLDRBLiteral(opcode, eEncodingT1);
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+
+ break;
+
+ case eEncodingT3:
+ // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
+ // if P == '0' && W == '0' then UNDEFINED;
+ if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 10);
+ add = BitIsSet(opcode, 9);
+ wback = BitIsSet(opcode, 8);
+
+ // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
+ if (t == 15)
+ return false; // PLD is not implemented yet
+
+ // if Rn == '1111' then SEE LDRB (literal);
+ if (n == 15)
+ return EmulateLDRBLiteral(opcode, eEncodingT1);
+
+ // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
+ if (BadReg(t) || (wback && (n == t)))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ uint32_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t address;
+ addr_t offset_addr;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // R[t] = ZeroExtend(MemU[address,1], 32);
+ RegisterInfo base_reg;
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
+
+ uint64_t data = MemURead(context, address, 1, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
-// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
+
+// LDRB (literal) calculates an address from the PC value and an immediate
+// offset, loads a byte from memory,
// zero-extends it to form a 32-bit word and writes it to a register.
-bool
-EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(15);
@@ -6390,82 +6342,81 @@ EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncod
address = if add then (base + imm32) else (base - imm32);
R[t] = ZeroExtend(MemU[address,1], 32);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t imm32;
- bool add;
- switch (encoding)
- {
- case eEncodingT1:
- // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- imm32 = Bits32 (opcode, 11, 0);
- add = BitIsSet (opcode, 23);
-
- // if Rt == '1111' then SEE PLD;
- if (t == 15)
- return false; // PLD is not implemented yet
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
-
- break;
-
- case eEncodingA1:
- // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- imm32 = Bits32 (opcode, 11, 0);
- add = BitIsSet (opcode, 23);
-
- // if t == 15 then UNPREDICTABLE;
- if (t == 15)
- return false;
- break;
-
- default:
- return false;
- }
-
- // base = Align(PC,4);
- uint32_t pc_val = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
-
- uint32_t base = AlignPC (pc_val);
-
- addr_t address;
- // address = if add then (base + imm32) else (base - imm32);
- if (add)
- address = base + imm32;
- else
- address = base - imm32;
-
- // R[t] = ZeroExtend(MemU[address,1], 32);
- EmulateInstruction::Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (address - base);
-
- uint64_t data = MemURead (context, address, 1, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t imm32;
+ bool add;
+ switch (encoding) {
+ case eEncodingT1:
+ // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 11, 0);
+ add = BitIsSet(opcode, 23);
+
+ // if Rt == '1111' then SEE PLD;
+ if (t == 15)
+ return false; // PLD is not implemented yet
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 11, 0);
+ add = BitIsSet(opcode, 23);
+
+ // if t == 15 then UNPREDICTABLE;
+ if (t == 15)
+ return false;
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // base = Align(PC,4);
+ uint32_t pc_val = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ uint32_t base = AlignPC(pc_val);
+
+ addr_t address;
+ // address = if add then (base + imm32) else (base - imm32);
+ if (add)
+ address = base + imm32;
+ else
+ address = base - imm32;
+
+ // R[t] = ZeroExtend(MemU[address,1], 32);
+ EmulateInstruction::Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(address - base);
+
+ uint64_t data = MemURead(context, address, 1, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
+ return false;
+ }
+ return true;
}
-
-// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
-// memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can
+
+// LDRB (register) calculates an address from a base register value and an
+// offset rigister value, loads a byte from
+// memory, zero-extends it to form a 32-bit word, and writes it to a register.
+// The offset register value can
// optionally be shifted.
-bool
-EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -6475,160 +6426,160 @@ EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEnco
R[t] = ZeroExtend(MemU[address,1],32);
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
-
- case eEncodingT2:
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
- shift_t = SRType_LSL;
- shift_n = Bits32 (opcode, 5, 4);
- // if Rt == '1111' then SEE PLD;
- if (t == 15)
- return false; // PLD is not implemented yet
+ bool success = false;
- // if Rn == '1111' then SEE LDRB (literal);
- if (n == 15)
- return EmulateLDRBLiteral(opcode, eEncodingT1);
-
- // if t == 13 || BadReg(m) then UNPREDICTABLE;
- if ((t == 13) || BadReg (m))
- return false;
- break;
-
- case eEncodingA1:
- {
- // if P == '0' && W == '1' then SEE LDRBT;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm5);
- uint32_t type = Bits32 (opcode, 6, 5);
- uint32_t imm5 = Bits32 (opcode, 11, 7);
- shift_n = DecodeImmShift (type, imm5, shift_t);
-
- // if t == 15 || m == 15 then UNPREDICTABLE;
- if ((t == 15) || (m == 15))
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
- }
- break;
-
- default:
- return false;
- }
-
- addr_t offset_addr;
- addr_t address;
-
- // offset = Shift(R[m], shift_t, shift_n, APSR.C);
- uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
-
- // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
- uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- if (add)
- offset_addr = Rn + offset;
- else
- offset_addr = Rn - offset;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // R[t] = ZeroExtend(MemU[address,1],32);
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
-
- uint64_t data = MemURead (context, address, 1, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+
+ case eEncodingT2:
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
+ shift_t = SRType_LSL;
+ shift_n = Bits32(opcode, 5, 4);
+
+ // if Rt == '1111' then SEE PLD;
+ if (t == 15)
+ return false; // PLD is not implemented yet
+
+ // if Rn == '1111' then SEE LDRB (literal);
+ if (n == 15)
+ return EmulateLDRBLiteral(opcode, eEncodingT1);
+
+ // if t == 13 || BadReg(m) then UNPREDICTABLE;
+ if ((t == 13) || BadReg(m))
+ return false;
+ break;
+
+ case eEncodingA1: {
+ // if P == '0' && W == '1' then SEE LDRBT;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm5);
+ uint32_t type = Bits32(opcode, 6, 5);
+ uint32_t imm5 = Bits32(opcode, 11, 7);
+ shift_n = DecodeImmShift(type, imm5, shift_t);
+
+ // if t == 15 || m == 15 then UNPREDICTABLE;
+ if ((t == 15) || (m == 15))
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+ } break;
+
+ default:
+ return false;
}
- return true;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C);
+ uint32_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
+ uint32_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ if (add)
+ offset_addr = Rn + offset;
+ else
+ offset_addr = Rn - offset;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // R[t] = ZeroExtend(MemU[address,1],32);
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+
+ uint64_t data = MemURead(context, address, 1, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
-// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
-// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset,
+
+// LDRH (immediate, Thumb) calculates an address from a base register value and
+// an immediate offset, loads a
+// halfword from memory, zero-extends it to form a 32-bit word, and writes it to
+// a register. It can use offset,
// post-indexed, or pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -6641,143 +6592,141 @@ EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEnc
else // Can only apply before ARMv7
R[t] = bits(32) UNKNOWN;
#endif
-
-
- bool success = false;
-
- if (ConditionPassed(opcode))
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ imm32 = Bits32(opcode, 10, 6) << 1;
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ break;
+
+ case eEncodingT2:
+ // if Rt == '1111' then SEE "Unallocated memory hints";
+ // if Rn == '1111' then SEE LDRH (literal);
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+ break;
+
+ case eEncodingT3:
+ // if Rn == '1111' then SEE LDRH (literal);
+ // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
+ // "Unallocated memory hints";
+ // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
+ // if P == '0' && W == '0' then UNDEFINED;
+ if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 10);
+ add = BitIsSet(opcode, 9);
+ wback = BitIsSet(opcode, 8);
+
+ // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
+ if (BadReg(t) || (wback && (n == t)))
+ return false;
+ break;
+
+ default:
+ return false;
+ }
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ uint32_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // data = MemU[address,2];
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+
+ uint64_t data = MemURead(context, address, 2, 0, &success);
+ if (!success)
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+
+ // if UnalignedSupport() || address<0> = '0' then
+ if (UnalignedSupport() || BitIsClear(address, 0)) {
+ // R[t] = ZeroExtend(data, 32);
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ data))
+ return false;
+ } else // Can only apply before ARMv7
{
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- imm32 = Bits32 (opcode, 10, 6) << 1;
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- break;
-
- case eEncodingT2:
- // if Rt == '1111' then SEE "Unallocated memory hints";
- // if Rn == '1111' then SEE LDRH (literal);
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
- break;
-
- case eEncodingT3:
- // if Rn == '1111' then SEE LDRH (literal);
- // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
- // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
- // if P == '0' && W == '0' then UNDEFINED;
- if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 10);
- add = BitIsSet (opcode, 9);
- wback = BitIsSet (opcode, 8);
-
- // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
- if (BadReg (t) || (wback && (n == t)))
- return false;
- break;
-
- default:
- return false;
- }
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- addr_t address;
-
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // data = MemU[address,2];
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
-
- uint64_t data = MemURead (context, address, 2, 0, &success);
- if (!success)
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
-
- // if UnalignedSupport() || address<0> = '0' then
- if (UnalignedSupport () || BitIsClear (address, 0))
- {
- // R[t] = ZeroExtend(data, 32);
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
- }
- else // Can only apply before ARMv7
- {
- // R[t] = bits(32) UNKNOWN;
- WriteBits32Unknown (t);
- }
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
}
- return true;
+ }
+ return true;
}
-
-// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
-// zero-extends it to form a 32-bit word, and writes it to a register.
-bool
-EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+// LDRH (literal) caculates an address from the PC value and an immediate
+// offset, loads a halfword from memory,
+// zero-extends it to form a 32-bit word, and writes it to a register.
+bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(15);
@@ -6789,103 +6738,99 @@ EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncod
else // Can only apply before ARMv7
R[t] = bits(32) UNKNOWN;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t imm32;
+ bool add;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
+ switch (encoding) {
+ case eEncodingT1:
+ // if Rt == '1111' then SEE "Unallocated memory hints";
+ // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 11, 0);
+ add = BitIsSet(opcode, 23);
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+
+ break;
+
+ case eEncodingA1: {
+ uint32_t imm4H = Bits32(opcode, 11, 8);
+ uint32_t imm4L = Bits32(opcode, 3, 0);
+
+ // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ imm32 = (imm4H << 4) | imm4L;
+ add = BitIsSet(opcode, 23);
+
+ // if t == 15 then UNPREDICTABLE;
+ if (t == 15)
+ return false;
+ break;
+ }
+
+ default:
+ return false;
+ }
+
+ // base = Align(PC,4);
+ uint64_t pc_value = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ addr_t base = AlignPC(pc_value);
+ addr_t address;
+
+ // address = if add then (base + imm32) else (base - imm32);
+ if (add)
+ address = base + imm32;
+ else
+ address = base - imm32;
+
+ // data = MemU[address,2];
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - base);
+
+ uint64_t data = MemURead(context, address, 2, 0, &success);
+ if (!success)
+ return false;
+
+ // if UnalignedSupport() || address<0> = '0' then
+ if (UnalignedSupport() || BitIsClear(address, 0)) {
+ // R[t] = ZeroExtend(data, 32);
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - base);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ data))
+ return false;
+
+ } else // Can only apply before ARMv7
{
- uint32_t t;
- uint32_t imm32;
- bool add;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
- switch (encoding)
- {
- case eEncodingT1:
- // if Rt == '1111' then SEE "Unallocated memory hints";
- // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- imm32 = Bits32 (opcode, 11, 0);
- add = BitIsSet (opcode, 23);
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
-
- break;
-
- case eEncodingA1:
- {
- uint32_t imm4H = Bits32 (opcode, 11, 8);
- uint32_t imm4L = Bits32 (opcode, 3, 0);
-
- // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- imm32 = (imm4H << 4) | imm4L;
- add = BitIsSet (opcode, 23);
-
- // if t == 15 then UNPREDICTABLE;
- if (t == 15)
- return false;
- break;
- }
-
- default:
- return false;
- }
-
- // base = Align(PC,4);
- uint64_t pc_value = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
-
- addr_t base = AlignPC (pc_value);
- addr_t address;
-
- // address = if add then (base + imm32) else (base - imm32);
- if (add)
- address = base + imm32;
- else
- address = base - imm32;
-
- // data = MemU[address,2];
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - base);
-
- uint64_t data = MemURead (context, address, 2, 0, &success);
- if (!success)
- return false;
-
-
- // if UnalignedSupport() || address<0> = '0' then
- if (UnalignedSupport () || BitIsClear (address, 0))
- {
- // R[t] = ZeroExtend(data, 32);
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - base);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
-
- }
- else // Can only apply before ARMv7
- {
- // R[t] = bits(32) UNKNOWN;
- WriteBits32Unknown (t);
- }
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
}
- return true;
+ }
+ return true;
}
-
-// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
-// from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can
+
+// LDRH (literal) calculates an address from a base register value and an offset
+// register value, loads a halfword
+// from memory, zero-extends it to form a 32-bit word, and writes it to a
+// register. The offset register value can
// be shifted left by 0, 1, 2, or 3 bits.
-bool
-EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -6899,168 +6844,170 @@ EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEnco
else // Can only apply before ARMv7
R[t] = bits(32) UNKNOWN;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
+ // in ThumbEE";
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ break;
+
+ case eEncodingT2:
+ // if Rn == '1111' then SEE LDRH (literal);
+ // if Rt == '1111' then SEE "Unallocated memory hints";
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
+ shift_t = SRType_LSL;
+ shift_n = Bits32(opcode, 5, 4);
+
+ // if t == 13 || BadReg(m) then UNPREDICTABLE;
+ if ((t == 13) || BadReg(m))
+ return false;
+ break;
+
+ case eEncodingA1:
+ // if P == '0' && W == '1' then SEE LDRHT;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ // if t == 15 || m == 15 then UNPREDICTABLE;
+ if ((t == 15) || (m == 15))
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C);
+
+ uint64_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
+ uint64_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ if (add)
+ offset_addr = Rn + offset;
+ else
+ offset_addr = Rn - offset;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // data = MemU[address,2];
+ RegisterInfo base_reg;
+ RegisterInfo offset_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
+ uint64_t data = MemURead(context, address, 2, 0, &success);
+ if (!success)
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+
+ // if UnalignedSupport() || address<0> = '0' then
+ if (UnalignedSupport() || BitIsClear(address, 0)) {
+ // R[t] = ZeroExtend(data, 32);
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ data))
+ return false;
+ } else // Can only apply before ARMv7
{
- uint32_t t;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- break;
-
- case eEncodingT2:
- // if Rn == '1111' then SEE LDRH (literal);
- // if Rt == '1111' then SEE "Unallocated memory hints";
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
- shift_t = SRType_LSL;
- shift_n = Bits32 (opcode, 5, 4);
-
- // if t == 13 || BadReg(m) then UNPREDICTABLE;
- if ((t == 13) || BadReg (m))
- return false;
- break;
-
- case eEncodingA1:
- // if P == '0' && W == '1' then SEE LDRHT;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- // if t == 15 || m == 15 then UNPREDICTABLE;
- if ((t == 15) || (m == 15))
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- // offset = Shift(R[m], shift_t, shift_n, APSR.C);
-
- uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- addr_t address;
-
- // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
- uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- if (add)
- offset_addr = Rn + offset;
- else
- offset_addr = Rn - offset;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // data = MemU[address,2];
- RegisterInfo base_reg;
- RegisterInfo offset_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
- uint64_t data = MemURead (context, address, 2, 0, &success);
- if (!success)
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
-
- // if UnalignedSupport() || address<0> = '0' then
- if (UnalignedSupport() || BitIsClear (address, 0))
- {
- // R[t] = ZeroExtend(data, 32);
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
- }
- else // Can only apply before ARMv7
- {
- // R[t] = bits(32) UNKNOWN;
- WriteBits32Unknown (t);
- }
- }
- return true;
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
+ }
+ }
+ return true;
}
-
-// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
-// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed,
+
+// LDRSB (immediate) calculates an address from a base register value and an
+// immediate offset, loads a byte from
+// memory, sign-extends it to form a 32-bit word, and writes it to a register.
+// It can use offset, post-indexed,
// or pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -7069,147 +7016,147 @@ EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEn
R[t] = SignExtend(MemU[address,1], 32);
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // if Rt == '1111' then SEE PLI;
- // if Rn == '1111' then SEE LDRSB (literal);
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
-
- break;
-
- case eEncodingT2:
- // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
- // if Rn == '1111' then SEE LDRSB (literal);
- // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
- // if P == '0' && W == '0' then UNDEFINED;
- if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 10);
- add = BitIsSet (opcode, 9);
- wback = BitIsSet (opcode, 8);
-
- // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
- if (((t == 13) || ((t == 15)
- && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
- || (wback && (n == t)))
- return false;
-
- break;
-
- case eEncodingA1:
- {
- // if Rn == '1111' then SEE LDRSB (literal);
- // if P == '0' && W == '1' then SEE LDRSBT;
- // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
-
- uint32_t imm4H = Bits32 (opcode, 11, 8);
- uint32_t imm4L = Bits32 (opcode, 3, 0);
- imm32 = (imm4H << 4) | imm4L;
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
-
- // if t == 15 || (wback && n == t) then UNPREDICTABLE;
- if ((t == 15) || (wback && (n == t)))
- return false;
-
- break;
- }
-
- default:
- return false;
- }
-
- uint64_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- addr_t address;
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // R[t] = SignExtend(MemU[address,1], 32);
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
-
- uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
- if (!success)
- return false;
-
- int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // if Rt == '1111' then SEE PLI;
+ // if Rn == '1111' then SEE LDRSB (literal);
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
+ // if Rn == '1111' then SEE LDRSB (literal);
+ // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
+ // if P == '0' && W == '0' then UNDEFINED;
+ if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 10);
+ add = BitIsSet(opcode, 9);
+ wback = BitIsSet(opcode, 8);
+
+ // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
+ if (((t == 13) ||
+ ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) ||
+ BitIsSet(opcode, 8)))) ||
+ (wback && (n == t)))
+ return false;
+
+ break;
+
+ case eEncodingA1: {
+ // if Rn == '1111' then SEE LDRSB (literal);
+ // if P == '0' && W == '1' then SEE LDRSBT;
+ // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+
+ uint32_t imm4H = Bits32(opcode, 11, 8);
+ uint32_t imm4L = Bits32(opcode, 3, 0);
+ imm32 = (imm4H << 4) | imm4L;
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21));
+
+ // if t == 15 || (wback && n == t) then UNPREDICTABLE;
+ if ((t == 15) || (wback && (n == t)))
+ return false;
+
+ break;
}
-
- return true;
+
+ default:
+ return false;
+ }
+
+ uint64_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // R[t] = SignExtend(MemU[address,1], 32);
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+
+ uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
+ if (!success)
+ return false;
+
+ int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ (uint64_t)signed_data))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+
+ return true;
}
-
-// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
+
+// LDRSB (literal) calculates an address from the PC value and an immediate
+// offset, loads a byte from memory,
// sign-extends it to form a 32-bit word, and writes tit to a register.
-bool
-EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(15);
@@ -7217,89 +7164,88 @@ EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEnco
address = if add then (base + imm32) else (base - imm32);
R[t] = SignExtend(MemU[address,1], 32);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t imm32;
- bool add;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
- switch (encoding)
- {
- case eEncodingT1:
- // if Rt == '1111' then SEE PLI;
- // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- imm32 = Bits32 (opcode, 11, 0);
- add = BitIsSet (opcode, 23);
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
-
- break;
-
- case eEncodingA1:
- {
- // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- uint32_t imm4H = Bits32 (opcode, 11, 8);
- uint32_t imm4L = Bits32 (opcode, 3, 0);
- imm32 = (imm4H << 4) | imm4L;
- add = BitIsSet (opcode, 23);
-
- // if t == 15 then UNPREDICTABLE;
- if (t == 15)
- return false;
-
- break;
- }
-
- default:
- return false;
- }
-
- // base = Align(PC,4);
- uint64_t pc_value = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
- uint64_t base = AlignPC (pc_value);
- // address = if add then (base + imm32) else (base - imm32);
- addr_t address;
- if (add)
- address = base + imm32;
- else
- address = base - imm32;
-
- // R[t] = SignExtend(MemU[address,1], 32);
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - base);
-
- uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
- if (!success)
- return false;
-
- int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
- return false;
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t imm32;
+ bool add;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
+ switch (encoding) {
+ case eEncodingT1:
+ // if Rt == '1111' then SEE PLI;
+ // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 11, 0);
+ add = BitIsSet(opcode, 23);
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+
+ break;
+
+ case eEncodingA1: {
+ // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ uint32_t imm4H = Bits32(opcode, 11, 8);
+ uint32_t imm4L = Bits32(opcode, 3, 0);
+ imm32 = (imm4H << 4) | imm4L;
+ add = BitIsSet(opcode, 23);
+
+ // if t == 15 then UNPREDICTABLE;
+ if (t == 15)
+ return false;
+
+ break;
}
- return true;
+
+ default:
+ return false;
+ }
+
+ // base = Align(PC,4);
+ uint64_t pc_value = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+ uint64_t base = AlignPC(pc_value);
+
+ // address = if add then (base + imm32) else (base - imm32);
+ addr_t address;
+ if (add)
+ address = base + imm32;
+ else
+ address = base - imm32;
+
+ // R[t] = SignExtend(MemU[address,1], 32);
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - base);
+
+ uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
+ if (!success)
+ return false;
+
+ int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ (uint64_t)signed_data))
+ return false;
+ }
+ return true;
}
-
-// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
-// memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be
+
+// LDRSB (register) calculates an address from a base register value and an
+// offset register value, loadsa byte from
+// memory, sign-extends it to form a 32-bit word, and writes it to a register.
+// The offset register value can be
// shifted left by 0, 1, 2, or 3 bits.
-bool
-EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -7309,155 +7255,158 @@ EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEnc
R[t] = SignExtend(MemU[address,1], 32);
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- break;
-
- case eEncodingT2:
- // if Rt == '1111' then SEE PLI;
- // if Rn == '1111' then SEE LDRSB (literal);
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
- shift_t = SRType_LSL;
- shift_n = Bits32 (opcode, 5, 4);
-
- // if t == 13 || BadReg(m) then UNPREDICTABLE;
- if ((t == 13) || BadReg (m))
- return false;
- break;
-
- case eEncodingA1:
- // if P == '0' && W == '1' then SEE LDRSBT;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- // if t == 15 || m == 15 then UNPREDICTABLE;
- if ((t == 15) || (m == 15))
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
- break;
-
- default:
- return false;
- }
-
- uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- // offset = Shift(R[m], shift_t, shift_n, APSR.C);
- addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- addr_t address;
-
- // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
- uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- if (add)
- offset_addr = Rn + offset;
- else
- offset_addr = Rn - offset;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // R[t] = SignExtend(MemU[address,1], 32);
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- RegisterInfo offset_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
-
- uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
- if (!success)
- return false;
-
- int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ break;
+
+ case eEncodingT2:
+ // if Rt == '1111' then SEE PLI;
+ // if Rn == '1111' then SEE LDRSB (literal);
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
+ shift_t = SRType_LSL;
+ shift_n = Bits32(opcode, 5, 4);
+
+ // if t == 13 || BadReg(m) then UNPREDICTABLE;
+ if ((t == 13) || BadReg(m))
+ return false;
+ break;
+
+ case eEncodingA1:
+ // if P == '0' && W == '1' then SEE LDRSBT;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ // if t == 15 || m == 15 then UNPREDICTABLE;
+ if ((t == 15) || (m == 15))
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ uint64_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C);
+ addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
+ uint64_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ if (add)
+ offset_addr = Rn + offset;
+ else
+ offset_addr = Rn - offset;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // R[t] = SignExtend(MemU[address,1], 32);
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ RegisterInfo offset_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
+
+ uint64_t unsigned_data = MemURead(context, address, 1, 0, &success);
+ if (!success)
+ return false;
+
+ int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ (uint64_t)signed_data))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
-// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
-// memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or
+
+// LDRSH (immediate) calculates an address from a base register value and an
+// immediate offset, loads a halfword from
+// memory, sign-extends it to form a 32-bit word, and writes it to a register.
+// It can use offset, post-indexed, or
// pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -7471,153 +7420,152 @@ EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEn
R[t] = bits(32) UNKNOWN;
#endif
- bool success = false;
-
- if (ConditionPassed(opcode))
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // if Rn == '1111' then SEE LDRSH (literal);
+ // if Rt == '1111' then SEE "Unallocated memory hints";
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ // if Rn == '1111' then SEE LDRSH (literal);
+ // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE
+ // "Unallocated memory hints";
+ // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
+ // if P == '0' && W == '0' then UNDEFINED;
+ if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))
+ return false;
+
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 10);
+ add = BitIsSet(opcode, 9);
+ wback = BitIsSet(opcode, 8);
+
+ // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
+ if (BadReg(t) || (wback && (n == t)))
+ return false;
+
+ break;
+
+ case eEncodingA1: {
+ // if Rn == '1111' then SEE LDRSH (literal);
+ // if P == '0' && W == '1' then SEE LDRSHT;
+ // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ uint32_t imm4H = Bits32(opcode, 11, 8);
+ uint32_t imm4L = Bits32(opcode, 3, 0);
+ imm32 = (imm4H << 4) | imm4L;
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // if t == 15 || (wback && n == t) then UNPREDICTABLE;
+ if ((t == 15) || (wback && (n == t)))
+ return false;
+
+ break;
+ }
+
+ default:
+ return false;
+ }
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ uint64_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // data = MemU[address,2];
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+
+ uint64_t data = MemURead(context, address, 2, 0, &success);
+ if (!success)
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+
+ // if UnalignedSupport() || address<0> = '0' then
+ if (UnalignedSupport() || BitIsClear(address, 0)) {
+ // R[t] = SignExtend(data, 32);
+ int64_t signed_data = llvm::SignExtend64<16>(data);
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ (uint64_t)signed_data))
+ return false;
+ } else // Can only apply before ARMv7
{
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // if Rn == '1111' then SEE LDRSH (literal);
- // if Rt == '1111' then SEE "Unallocated memory hints";
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
-
- break;
-
- case eEncodingT2:
- // if Rn == '1111' then SEE LDRSH (literal);
- // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
- // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
- // if P == '0' && W == '0' then UNDEFINED;
- if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
- return false;
-
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 10);
- add = BitIsSet (opcode, 9);
- wback = BitIsSet (opcode, 8);
-
- // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
- if (BadReg (t) || (wback && (n == t)))
- return false;
-
- break;
-
- case eEncodingA1:
- {
- // if Rn == '1111' then SEE LDRSH (literal);
- // if P == '0' && W == '1' then SEE LDRSHT;
- // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- uint32_t imm4H = Bits32 (opcode, 11,8);
- uint32_t imm4L = Bits32 (opcode, 3, 0);
- imm32 = (imm4H << 4) | imm4L;
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // if t == 15 || (wback && n == t) then UNPREDICTABLE;
- if ((t == 15) || (wback && (n == t)))
- return false;
-
- break;
- }
-
- default:
- return false;
- }
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- // address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // data = MemU[address,2];
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
-
- uint64_t data = MemURead (context, address, 2, 0, &success);
- if (!success)
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
-
- // if UnalignedSupport() || address<0> = '0' then
- if (UnalignedSupport() || BitIsClear (address, 0))
- {
- // R[t] = SignExtend(data, 32);
- int64_t signed_data = llvm::SignExtend64<16>(data);
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
- return false;
- }
- else // Can only apply before ARMv7
- {
- // R[t] = bits(32) UNKNOWN;
- WriteBits32Unknown (t);
- }
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
}
- return true;
+ }
+ return true;
}
-
-// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
+
+// LDRSH (literal) calculates an address from the PC value and an immediate
+// offset, loads a halfword from memory,
// sign-extends it to from a 32-bit word, and writes it to a register.
-bool
-EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(15);
@@ -7629,99 +7577,96 @@ EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEnco
else // Can only apply before ARMv7
R[t] = bits(32) UNKNOWN;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t imm32;
+ bool add;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
+ switch (encoding) {
+ case eEncodingT1:
+ // if Rt == '1111' then SEE "Unallocated memory hints";
+ // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ imm32 = Bits32(opcode, 11, 0);
+ add = BitIsSet(opcode, 23);
+
+ // if t == 13 then UNPREDICTABLE;
+ if (t == 13)
+ return false;
+
+ break;
+
+ case eEncodingA1: {
+ // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
+ t = Bits32(opcode, 15, 12);
+ uint32_t imm4H = Bits32(opcode, 11, 8);
+ uint32_t imm4L = Bits32(opcode, 3, 0);
+ imm32 = (imm4H << 4) | imm4L;
+ add = BitIsSet(opcode, 23);
+
+ // if t == 15 then UNPREDICTABLE;
+ if (t == 15)
+ return false;
+
+ break;
+ }
+ default:
+ return false;
+ }
+
+ // base = Align(PC,4);
+ uint64_t pc_value = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ uint64_t base = AlignPC(pc_value);
+
+ addr_t address;
+ // address = if add then (base + imm32) else (base - imm32);
+ if (add)
+ address = base + imm32;
+ else
+ address = base - imm32;
+
+ // data = MemU[address,2];
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, imm32);
+
+ uint64_t data = MemURead(context, address, 2, 0, &success);
+ if (!success)
+ return false;
+
+ // if UnalignedSupport() || address<0> = '0' then
+ if (UnalignedSupport() || BitIsClear(address, 0)) {
+ // R[t] = SignExtend(data, 32);
+ int64_t signed_data = llvm::SignExtend64<16>(data);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ (uint64_t)signed_data))
+ return false;
+ } else // Can only apply before ARMv7
{
- uint32_t t;
- uint32_t imm32;
- bool add;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
- switch (encoding)
- {
- case eEncodingT1:
- // if Rt == '1111' then SEE "Unallocated memory hints";
- // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- imm32 = Bits32 (opcode, 11, 0);
- add = BitIsSet (opcode, 23);
-
- // if t == 13 then UNPREDICTABLE;
- if (t == 13)
- return false;
-
- break;
-
- case eEncodingA1:
- {
- // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
- t = Bits32 (opcode, 15, 12);
- uint32_t imm4H = Bits32 (opcode, 11, 8);
- uint32_t imm4L = Bits32 (opcode, 3, 0);
- imm32 = (imm4H << 4) | imm4L;
- add = BitIsSet (opcode, 23);
-
- // if t == 15 then UNPREDICTABLE;
- if (t == 15)
- return false;
-
- break;
- }
- default:
- return false;
- }
-
- // base = Align(PC,4);
- uint64_t pc_value = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
-
- uint64_t base = AlignPC (pc_value);
-
- addr_t address;
- // address = if add then (base + imm32) else (base - imm32);
- if (add)
- address = base + imm32;
- else
- address = base - imm32;
-
- // data = MemU[address,2];
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, imm32);
-
- uint64_t data = MemURead (context, address, 2, 0, &success);
- if (!success)
- return false;
-
- // if UnalignedSupport() || address<0> = '0' then
- if (UnalignedSupport() || BitIsClear (address, 0))
- {
- // R[t] = SignExtend(data, 32);
- int64_t signed_data = llvm::SignExtend64<16>(data);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
- return false;
- }
- else // Can only apply before ARMv7
- {
- // R[t] = bits(32) UNKNOWN;
- WriteBits32Unknown (t);
- }
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
}
- return true;
+ }
+ return true;
}
-
-// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
-// from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be
+
+// LDRSH (register) calculates an address from a base register value and an
+// offset register value, loads a halfword
+// from memory, sign-extends it to form a 32-bit word, and writes it to a
+// register. The offset register value can be
// shifted left by 0, 1, 2, or 3 bits.
-bool
-EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -7735,502 +7680,507 @@ EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEnc
else // Can only apply before ARMv7
R[t] = bits(32) UNKNOWN;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+
+ // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
+ switch (encoding) {
+ case eEncodingT1:
+ // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation
+ // in ThumbEE";
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ break;
+
+ case eEncodingT2:
+ // if Rn == '1111' then SEE LDRSH (literal);
+ // if Rt == '1111' then SEE "Unallocated memory hints";
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = TRUE; add = TRUE; wback = FALSE;
+ index = true;
+ add = true;
+ wback = false;
+
+ // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
+ shift_t = SRType_LSL;
+ shift_n = Bits32(opcode, 5, 4);
+
+ // if t == 13 || BadReg(m) then UNPREDICTABLE;
+ if ((t == 13) || BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // if P == '0' && W == '1' then SEE LDRSHT;
+ // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') ||
+ // (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ // if t == 15 || m == 15 then UNPREDICTABLE;
+ if ((t == 15) || (m == 15))
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ uint64_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ uint64_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ // offset = Shift(R[m], shift_t, shift_n, APSR.C);
+ addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ addr_t address;
+
+ // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
+ if (add)
+ offset_addr = Rn + offset;
+ else
+ offset_addr = Rn - offset;
+
+ // address = if index then offset_addr else R[n];
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // data = MemU[address,2];
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ RegisterInfo offset_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
+
+ uint64_t data = MemURead(context, address, 2, 0, &success);
+ if (!success)
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+
+ // if UnalignedSupport() || address<0> = '0' then
+ if (UnalignedSupport() || BitIsClear(address, 0)) {
+ // R[t] = SignExtend(data, 32);
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusIndirectOffset(base_reg, offset_reg);
+
+ int64_t signed_data = llvm::SignExtend64<16>(data);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t,
+ (uint64_t)signed_data))
+ return false;
+ } else // Can only apply before ARMv7
{
- uint32_t t;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
-
- // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
- switch (encoding)
- {
- case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- break;
-
- case eEncodingT2:
- // if Rn == '1111' then SEE LDRSH (literal);
- // if Rt == '1111' then SEE "Unallocated memory hints";
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = TRUE; add = TRUE; wback = FALSE;
- index = true;
- add = true;
- wback = false;
-
- // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
- shift_t = SRType_LSL;
- shift_n = Bits32 (opcode, 5, 4);
-
- // if t == 13 || BadReg(m) then UNPREDICTABLE;
- if ((t == 13) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // if P == '0' && W == '1' then SEE LDRSHT;
- // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- // if t == 15 || m == 15 then UNPREDICTABLE;
- if ((t == 15) || (m == 15))
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- // offset = Shift(R[m], shift_t, shift_n, APSR.C);
- addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- addr_t address;
-
- // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
- if (add)
- offset_addr = Rn + offset;
- else
- offset_addr = Rn - offset;
-
- // address = if index then offset_addr else R[n];
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // data = MemU[address,2];
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- RegisterInfo offset_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
-
- uint64_t data = MemURead (context, address, 2, 0, &success);
- if (!success)
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
-
- // if UnalignedSupport() || address<0> = '0' then
- if (UnalignedSupport() || BitIsClear (address, 0))
- {
- // R[t] = SignExtend(data, 32);
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
-
- int64_t signed_data = llvm::SignExtend64<16>(data);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
- return false;
- }
- else // Can only apply before ARMv7
- {
- // R[t] = bits(32) UNKNOWN;
- WriteBits32Unknown (t);
- }
+ // R[t] = bits(32) UNKNOWN;
+ WriteBits32Unknown(t);
}
- return true;
+ }
+ return true;
}
-
-// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
-// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
-bool
-EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and
+// writes the result to the destination
+// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before
+// extracting the 8-bit value.
+bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
rotated = ROR(R[m], rotation);
R[d] = SignExtend(rotated<7:0>, 32);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t m;
- uint32_t rotation;
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); m = UInt(Rm); rotation = 0;
- d = Bits32 (opcode, 2, 0);
- m = Bits32 (opcode, 5, 3);
- rotation = 0;
-
- break;
-
- case eEncodingT2:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 11, 8);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 5, 4) << 3;
-
- // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
- if (BadReg (d) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 15, 12);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 11, 10) << 3;
-
- // if d == 15 || m == 15 then UNPREDICTABLE;
- if ((d == 15) || (m == 15))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- // rotated = ROR(R[m], rotation);
- uint64_t rotated = ROR (Rm, rotation, &success);
- if (!success)
- return false;
-
- // R[d] = SignExtend(rotated<7:0>, 32);
- int64_t data = llvm::SignExtend64<8>(rotated);
-
- RegisterInfo source_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegister (source_reg);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
- return false;
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t m;
+ uint32_t rotation;
+
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = 0;
+ d = Bits32(opcode, 2, 0);
+ m = Bits32(opcode, 5, 3);
+ rotation = 0;
+
+ break;
+
+ case eEncodingT2:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 11, 8);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 5, 4) << 3;
+
+ // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
+ if (BadReg(d) || BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 15, 12);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 11, 10) << 3;
+
+ // if d == 15 || m == 15 then UNPREDICTABLE;
+ if ((d == 15) || (m == 15))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
-}
-
-// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
-// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
-bool
-EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+ uint64_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ // rotated = ROR(R[m], rotation);
+ uint64_t rotated = ROR(Rm, rotation, &success);
+ if (!success)
+ return false;
+
+ // R[d] = SignExtend(rotated<7:0>, 32);
+ int64_t data = llvm::SignExtend64<8>(rotated);
+
+ RegisterInfo source_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegister(source_reg);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
+ (uint64_t)data))
+ return false;
+ }
+ return true;
+}
+
+// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and
+// writes the result to the destination
+// register. You can specify a rotation by 0, 8, 16, or 24 bits before
+// extracting the 16-bit value.
+bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
rotated = ROR(R[m], rotation);
R[d] = SignExtend(rotated<15:0>, 32);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t m;
- uint32_t rotation;
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); m = UInt(Rm); rotation = 0;
- d = Bits32 (opcode, 2, 0);
- m = Bits32 (opcode, 5, 3);
- rotation = 0;
-
- break;
-
- case eEncodingT2:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 11, 8);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 5, 4) << 3;
-
- // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
- if (BadReg (d) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 15, 12);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 11, 10) << 3;
-
- // if d == 15 || m == 15 then UNPREDICTABLE;
- if ((d == 15) || (m == 15))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- // rotated = ROR(R[m], rotation);
- uint64_t rotated = ROR (Rm, rotation, &success);
- if (!success)
- return false;
-
- // R[d] = SignExtend(rotated<15:0>, 32);
- RegisterInfo source_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegister (source_reg);
-
- int64_t data = llvm::SignExtend64<16> (rotated);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
- return false;
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t m;
+ uint32_t rotation;
+
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = 0;
+ d = Bits32(opcode, 2, 0);
+ m = Bits32(opcode, 5, 3);
+ rotation = 0;
+
+ break;
+
+ case eEncodingT2:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 11, 8);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 5, 4) << 3;
+
+ // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
+ if (BadReg(d) || BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 15, 12);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 11, 10) << 3;
+
+ // if d == 15 || m == 15 then UNPREDICTABLE;
+ if ((d == 15) || (m == 15))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
-
- return true;
+
+ uint64_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ // rotated = ROR(R[m], rotation);
+ uint64_t rotated = ROR(Rm, rotation, &success);
+ if (!success)
+ return false;
+
+ // R[d] = SignExtend(rotated<15:0>, 32);
+ RegisterInfo source_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegister(source_reg);
+
+ int64_t data = llvm::SignExtend64<16>(rotated);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
+ (uint64_t)data))
+ return false;
+ }
+
+ return true;
}
-
-// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
-// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
-bool
-EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
+// writes the result to the destination
+// register. You can specify a rotation by 0, 8, 16, or 24 bits before
+// extracting the 8-bit value.
+bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
rotated = ROR(R[m], rotation);
R[d] = ZeroExtend(rotated<7:0>, 32);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t m;
- uint32_t rotation;
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); m = UInt(Rm); rotation = 0;
- d = Bits32 (opcode, 2, 0);
- m = Bits32 (opcode, 5, 3);
- rotation = 0;
-
- break;
-
- case eEncodingT2:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 11, 8);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 5, 4) << 3;
-
- // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
- if (BadReg (d) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 15, 12);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 11, 10) << 3;
-
- // if d == 15 || m == 15 then UNPREDICTABLE;
- if ((d == 15) || (m == 15))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- // rotated = ROR(R[m], rotation);
- uint64_t rotated = ROR (Rm, rotation, &success);
- if (!success)
- return false;
-
- // R[d] = ZeroExtend(rotated<7:0>, 32);
- RegisterInfo source_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegister (source_reg);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
- return false;
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t m;
+ uint32_t rotation;
+
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = 0;
+ d = Bits32(opcode, 2, 0);
+ m = Bits32(opcode, 5, 3);
+ rotation = 0;
+
+ break;
+
+ case eEncodingT2:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 11, 8);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 5, 4) << 3;
+
+ // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
+ if (BadReg(d) || BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 15, 12);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 11, 10) << 3;
+
+ // if d == 15 || m == 15 then UNPREDICTABLE;
+ if ((d == 15) || (m == 15))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
-}
-
-// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
-// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
-bool
-EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+ uint64_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ // rotated = ROR(R[m], rotation);
+ uint64_t rotated = ROR(Rm, rotation, &success);
+ if (!success)
+ return false;
+
+ // R[d] = ZeroExtend(rotated<7:0>, 32);
+ RegisterInfo source_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegister(source_reg);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
+ Bits32(rotated, 7, 0)))
+ return false;
+ }
+ return true;
+}
+
+// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and
+// writes the result to the destination
+// register. You can specify a rotation by 0, 8, 16, or 24 bits before
+// extracting the 16-bit value.
+bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
rotated = ROR(R[m], rotation);
R[d] = ZeroExtend(rotated<15:0>, 32);
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t m;
- uint32_t rotation;
-
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); m = UInt(Rm); rotation = 0;
- d = Bits32 (opcode, 2, 0);
- m = Bits32 (opcode, 5, 3);
- rotation = 0;
-
- break;
-
- case eEncodingT2:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 11, 8);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 5, 4) << 3;
-
- // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
- if (BadReg (d) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
- d = Bits32 (opcode, 15, 12);
- m = Bits32 (opcode, 3, 0);
- rotation = Bits32 (opcode, 11, 10) << 3;
-
- // if d == 15 || m == 15 then UNPREDICTABLE;
- if ((d == 15) || (m == 15))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
- if (!success)
- return false;
-
- // rotated = ROR(R[m], rotation);
- uint64_t rotated = ROR (Rm, rotation, &success);
- if (!success)
- return false;
-
- // R[d] = ZeroExtend(rotated<15:0>, 32);
- RegisterInfo source_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegister (source_reg);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
- return false;
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t m;
+ uint32_t rotation;
+
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = 0;
+ d = Bits32(opcode, 2, 0);
+ m = Bits32(opcode, 5, 3);
+ rotation = 0;
+
+ break;
+
+ case eEncodingT2:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 11, 8);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 5, 4) << 3;
+
+ // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
+ if (BadReg(d) || BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
+ d = Bits32(opcode, 15, 12);
+ m = Bits32(opcode, 3, 0);
+ rotation = Bits32(opcode, 11, 10) << 3;
+
+ // if d == 15 || m == 15 then UNPREDICTABLE;
+ if ((d == 15) || (m == 15))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ uint64_t Rm =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
+ if (!success)
+ return false;
+
+ // rotated = ROR(R[m], rotation);
+ uint64_t rotated = ROR(Rm, rotation, &success);
+ if (!success)
+ return false;
+
+ // R[d] = ZeroExtend(rotated<15:0>, 32);
+ RegisterInfo source_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegister(source_reg);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
+ Bits32(rotated, 15, 0)))
+ return false;
+ }
+ return true;
}
-
-// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
-// word respectively.
-bool
-EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
-{
+
+// RFE (Return From Exception) loads the PC and the CPSR from the word at the
+// specified address and the following
+// word respectively.
+bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -8243,142 +8193,141 @@ EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding enco
BranchWritePC(MemA[address,4]);
if wback then R[n] = if increment then R[n]+8 else R[n]-8;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t n;
- bool wback;
- bool increment;
- bool wordhigher;
-
- // EncodingSpecificOperations();
- switch (encoding)
- {
- case eEncodingT1:
- // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
- n = Bits32 (opcode, 19, 16);
- wback = BitIsSet (opcode, 21);
- increment = false;
- wordhigher = false;
-
- // if n == 15 then UNPREDICTABLE;
- if (n == 15)
- return false;
-
- // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if (InITBlock() && !LastInITBlock())
- return false;
-
- break;
-
- case eEncodingT2:
- // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
- n = Bits32 (opcode, 19, 16);
- wback = BitIsSet (opcode, 21);
- increment = true;
- wordhigher = false;
-
- // if n == 15 then UNPREDICTABLE;
- if (n == 15)
- return false;
-
- // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if (InITBlock() && !LastInITBlock())
- return false;
-
- break;
-
- case eEncodingA1:
- // n = UInt(Rn);
- n = Bits32 (opcode, 19, 16);
-
- // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
- wback = BitIsSet (opcode, 21);
- increment = BitIsSet (opcode, 23);
- wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
-
- // if n == 15 then UNPREDICTABLE;
- if (n == 15)
- return false;
-
- break;
-
- default:
- return false;
- }
-
- // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
- if (!CurrentModeIsPrivileged ())
- // UNPREDICTABLE;
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ bool wback;
+ bool increment;
+ bool wordhigher;
+
+ // EncodingSpecificOperations();
+ switch (encoding) {
+ case eEncodingT1:
+ // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher =
+ // FALSE;
+ n = Bits32(opcode, 19, 16);
+ wback = BitIsSet(opcode, 21);
+ increment = false;
+ wordhigher = false;
+
+ // if n == 15 then UNPREDICTABLE;
+ if (n == 15)
+ return false;
+
+ // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (InITBlock() && !LastInITBlock())
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
+ n = Bits32(opcode, 19, 16);
+ wback = BitIsSet(opcode, 21);
+ increment = true;
+ wordhigher = false;
+
+ // if n == 15 then UNPREDICTABLE;
+ if (n == 15)
+ return false;
+
+ // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (InITBlock() && !LastInITBlock())
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // n = UInt(Rn);
+ n = Bits32(opcode, 19, 16);
+
+ // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
+ wback = BitIsSet(opcode, 21);
+ increment = BitIsSet(opcode, 23);
+ wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23));
+
+ // if n == 15 then UNPREDICTABLE;
+ if (n == 15)
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE
+ // then
+ if (!CurrentModeIsPrivileged())
+ // UNPREDICTABLE;
+ return false;
+ else {
+ uint64_t Rn =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
+ if (!success)
+ return false;
+
+ addr_t address;
+ // address = if increment then R[n] else R[n]-8;
+ if (increment)
+ address = Rn;
+ else
+ address = Rn - 8;
+
+ // if wordhigher then address = address+4;
+ if (wordhigher)
+ address = address + 4;
+
+ // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ context.type = eContextReturnFromException;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+
+ uint64_t data = MemARead(context, address + 4, 4, 0, &success);
+ if (!success)
+ return false;
+
+ CPSRWriteByInstr(data, 15, true);
+
+ // BranchWritePC(MemA[address,4]);
+ uint64_t data2 = MemARead(context, address, 4, 0, &success);
+ if (!success)
+ return false;
+
+ BranchWritePC(context, data2);
+
+ // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ if (increment) {
+ context.SetOffset(8);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ Rn + 8))
+ return false;
+ } else {
+ context.SetOffset(-8);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ Rn - 8))
return false;
- else
- {
- uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
- if (!success)
- return false;
-
- addr_t address;
- // address = if increment then R[n] else R[n]-8;
- if (increment)
- address = Rn;
- else
- address = Rn - 8;
-
- // if wordhigher then address = address+4;
- if (wordhigher)
- address = address + 4;
-
- // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
- context.type = eContextReturnFromException;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
-
- uint64_t data = MemARead (context, address + 4, 4, 0, &success);
- if (!success)
- return false;
-
- CPSRWriteByInstr (data, 15, true);
-
- // BranchWritePC(MemA[address,4]);
- uint64_t data2 = MemARead (context, address, 4, 0, &success);
- if (!success)
- return false;
-
- BranchWritePC (context, data2);
-
- // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- if (increment)
- {
- context.SetOffset (8);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
- return false;
- }
- else
- {
- context.SetOffset (-8);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
- return false;
- }
- } // if wback
}
- } // if ConditionPassed()
- return true;
+ } // if wback
+ }
+ } // if ConditionPassed()
+ return true;
}
-
-// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
-// and writes the result to the destination register. It can optionally update the condition flags based on
+
+// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a
+// register value and an immediate value,
+// and writes the result to the destination register. It can optionally update
+// the condition flags based on
// the result.
-bool
-EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8395,64 +8344,69 @@ EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn;
- uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
- bool setflags;
- uint32_t carry; // the carry bit after ARM/Thumb Expand operation
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
- // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
- if (Rd == 15 && setflags)
- return EmulateTEQImm (opcode, eEncodingT1);
- if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn;
+ uint32_t
+ imm32; // the immediate value to be ORed to the value obtained from Rn
+ bool setflags;
+ uint32_t carry; // the carry bit after ARM/Thumb Expand operation
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm_C(
+ opcode, APSR_C,
+ carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
+ // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
+ if (Rd == 15 && setflags)
+ return EmulateTEQImm(opcode, eEncodingT1);
+ if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 =
+ ARMExpandImm_C(opcode, APSR_C,
+ carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t result = val1 ^ imm32;
+ uint32_t result = val1 ^ imm32;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
-// optionally-shifted register value, and writes the result to the destination register.
+// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register
+// value and an
+// optionally-shifted register value, and writes the result to the destination
+// register.
// It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8470,82 +8424,82 @@ EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- bool setflags;
- uint32_t carry;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- // if Rd == '1111' && S == '1' then SEE TEQ (register);
- if (Rd == 15 && setflags)
- return EmulateTEQReg (opcode, eEncodingT1);
- if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ bool setflags;
+ uint32_t carry;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ // if Rd == '1111' && S == '1' then SEE TEQ (register);
+ if (Rd == 15 && setflags)
+ return EmulateTEQReg(opcode, eEncodingT1);
+ if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
- if (!success)
- return false;
- uint32_t result = val1 ^ shifted;
+ uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
+ if (!success)
+ return false;
+ uint32_t result = val1 ^ shifted;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
-// writes the result to the destination register. It can optionally update the condition flags based
+// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value
+// and an immediate value, and
+// writes the result to the destination register. It can optionally update the
+// condition flags based
// on the result.
-bool
-EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8562,63 +8516,67 @@ EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn;
- uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
- bool setflags;
- uint32_t carry; // the carry bit after ARM/Thumb Expand operation
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
- // if Rn == '1111' then SEE MOV (immediate);
- if (Rn == 15)
- return EmulateMOVRdImm (opcode, eEncodingT2);
- if (BadReg(Rd) || Rn == 13)
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
-
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn;
+ uint32_t
+ imm32; // the immediate value to be ORed to the value obtained from Rn
+ bool setflags;
+ uint32_t carry; // the carry bit after ARM/Thumb Expand operation
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm_C(
+ opcode, APSR_C,
+ carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
+ // if Rn == '1111' then SEE MOV (immediate);
+ if (Rn == 15)
+ return EmulateMOVRdImm(opcode, eEncodingT2);
+ if (BadReg(Rd) || Rn == 13)
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 =
+ ARMExpandImm_C(opcode, APSR_C,
+ carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
+
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t result = val1 | imm32;
+ uint32_t result = val1 | imm32;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
-// value, and writes the result to the destination register. It can optionally update the condition flags based
+// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value
+// and an optionally-shifted register
+// value, and writes the result to the destination register. It can optionally
+// update the condition flags based
// on the result.
-bool
-EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8636,80 +8594,79 @@ EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rd, Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- bool setflags;
- uint32_t carry;
- switch (encoding)
- {
- case eEncodingT1:
- Rd = Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- // if Rn == '1111' then SEE MOV (register);
- if (Rn == 15)
- return EmulateMOVRdRm (opcode, eEncodingT3);
- if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd, Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ bool setflags;
+ uint32_t carry;
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ // if Rn == '1111' then SEE MOV (register);
+ if (Rn == 15)
+ return EmulateMOVRdRm(opcode, eEncodingT3);
+ if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
- if (!success)
- return false;
- uint32_t result = val1 | shifted;
+ uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
+ if (!success)
+ return false;
+ uint32_t result = val1 | shifted;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
- return false;
- }
- return true;
+ if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
+ return false;
+ }
+ return true;
}
-// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
-// the destination register. It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+// Reverse Subtract (immediate) subtracts a register value from an immediate
+// value, and writes the result to
+// the destination register. It can optionally update the condition flags based
+// on the result.
+bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8726,62 +8683,66 @@ EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ bool setflags;
+ uint32_t
+ imm32; // the immediate value to be added to the value obtained from Rn
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 2, 0);
+ Rn = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ imm32 = 0;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
+ if (BadReg(Rd) || BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- bool setflags;
- uint32_t imm32; // the immediate value to be added to the value obtained from Rn
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 2, 0);
- Rn = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- imm32 = 0;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
- if (BadReg(Rd) || BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
+ AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
-// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
-// result to the destination register. It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+// Reverse Subtract (register) subtracts a register value from an
+// optionally-shifted register value, and writes the
+// result to the destination register. It can optionally update the condition
+// flags based on the result.
+bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8799,69 +8760,72 @@ EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ uint32_t Rm; // the second operand
+ bool setflags;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
+ if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from register Rn.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- uint32_t Rm; // the second operand
- bool setflags;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
- if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- // Read the register value from register Rn.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the register value from register Rm.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // Read the register value from register Rm.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
-
- uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
+ uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ 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 true;
}
-// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
-// an immediate value, and writes the result to the destination register. It can optionally update the condition
+// Reverse Subtract with Carry (immediate) subtracts a register value and the
+// value of NOT (Carry flag) from
+// an immediate value, and writes the result to the destination register. It can
+// optionally update the condition
// flags based on the result.
-bool
-EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8878,49 +8842,53 @@ EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ bool setflags;
+ uint32_t
+ imm32; // the immediate value to be added to the value obtained from Rn
+ switch (encoding) {
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- bool setflags;
- uint32_t imm32; // the immediate value to be added to the value obtained from Rn
- switch (encoding) {
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
+ AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
-// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
-// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
+// Reverse Subtract with Carry (register) subtracts a register value and the
+// value of NOT (Carry flag) from an
+// optionally-shifted register value, and writes the result to the destination
+// register. It can optionally update the
// condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -8938,59 +8906,61 @@ EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ uint32_t Rm; // the second operand
+ bool setflags;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ switch (encoding) {
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from register Rn.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- uint32_t Rm; // the second operand
- bool setflags;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- switch (encoding) {
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- // Read the register value from register Rn.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the register value from register Rm.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // Read the register value from register Rm.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
-
- uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
+ uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ 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 true;
}
// Subtract with Carry (immediate) subtracts an immediate value and the value of
-// NOT (Carry flag) from a register value, and writes the result to the destination register.
+// NOT (Carry flag) from a register value, and writes the result to the
+// destination register.
// It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9007,57 +8977,61 @@ EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ bool setflags;
+ uint32_t
+ imm32; // the immediate value to be added to the value obtained from Rn
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
+ if (BadReg(Rd) || BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- bool setflags;
- uint32_t imm32; // the immediate value to be added to the value obtained from Rn
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
- if (BadReg(Rd) || BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
+ AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
-// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
-// NOT (Carry flag) from a register value, and writes the result to the destination register.
+// Subtract with Carry (register) subtracts an optionally-shifted register value
+// and the value of
+// NOT (Carry flag) from a register value, and writes the result to the
+// destination register.
// It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9075,74 +9049,77 @@ EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding e
APSR.V = overflow;
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ uint32_t Rm; // the second operand
+ bool setflags;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from register Rn.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- uint32_t Rm; // the second operand
- bool setflags;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- switch (encoding) {
- case eEncodingT1:
- Rd = Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- setflags = BitIsSet(opcode, 20);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- // Read the register value from register Rn.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the register value from register Rm.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- // Read the register value from register Rm.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
-
- uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
+ uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ 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 true;
}
-// This instruction subtracts an immediate value from a register value, and writes the result
-// to the destination register. It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
-{
+// This instruction subtracts an immediate value from a register value, and
+// writes the result
+// to the destination register. It can optionally update the condition flags
+// based on the result.
+bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9156,84 +9133,87 @@ EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncod
APSR.V = overflow;
#endif
- bool success = false;
-
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- bool setflags;
- uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
- switch (encoding) {
- case eEncodingT1:
- Rd = Bits32(opcode, 2, 0);
- Rn = Bits32(opcode, 5, 3);
- setflags = !InITBlock();
- imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
- break;
- case eEncodingT2:
- Rd = Rn = Bits32(opcode, 10, 8);
- setflags = !InITBlock();
- imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
- break;
- case eEncodingT3:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
-
- // if Rd == '1111' && S == '1' then SEE CMP (immediate);
- if (Rd == 15 && setflags)
- return EmulateCMPImm (opcode, eEncodingT2);
-
- // if Rn == '1101' then SEE SUB (SP minus immediate);
- if (Rn == 13)
- return EmulateSUBSPImm (opcode, eEncodingT2);
-
- // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
- if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
- return false;
- break;
- case eEncodingT4:
- Rd = Bits32(opcode, 11, 8);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
-
- // if Rn == '1111' then SEE ADR;
- if (Rn == 15)
- return EmulateADR (opcode, eEncodingT2);
-
- // if Rn == '1101' then SEE SUB (SP minus immediate);
- if (Rn == 13)
- return EmulateSUBSPImm (opcode, eEncodingT3);
+ bool success = false;
+
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ bool setflags;
+ uint32_t imm32; // the immediate value to be subtracted from the value
+ // obtained from Rn
+ switch (encoding) {
+ case eEncodingT1:
+ Rd = Bits32(opcode, 2, 0);
+ Rn = Bits32(opcode, 5, 3);
+ setflags = !InITBlock();
+ imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
+ break;
+ case eEncodingT2:
+ Rd = Rn = Bits32(opcode, 10, 8);
+ setflags = !InITBlock();
+ imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
+ break;
+ case eEncodingT3:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
+
+ // if Rd == '1111' && S == '1' then SEE CMP (immediate);
+ if (Rd == 15 && setflags)
+ return EmulateCMPImm(opcode, eEncodingT2);
+
+ // if Rn == '1101' then SEE SUB (SP minus immediate);
+ if (Rn == 13)
+ return EmulateSUBSPImm(opcode, eEncodingT2);
+
+ // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
+ if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
+ return false;
+ break;
+ case eEncodingT4:
+ Rd = Bits32(opcode, 11, 8);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
+
+ // if Rn == '1111' then SEE ADR;
+ if (Rn == 15)
+ return EmulateADR(opcode, eEncodingT2);
+
+ // if Rn == '1101' then SEE SUB (SP minus immediate);
+ if (Rn == 13)
+ return EmulateSUBSPImm(opcode, eEncodingT3);
+
+ if (BadReg(Rd))
+ return false;
+ break;
+ default:
+ return false;
+ }
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- if (BadReg(Rd))
- return false;
- break;
- default:
- return false;
- }
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
+ AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
- return true;
+ return true;
}
-// This instruction subtracts an immediate value from a register value, and writes the result
-// to the destination register. It can optionally update the condition flags based on the result.
-bool
-EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
-{
+// This instruction subtracts an immediate value from a register value, and
+// writes the result
+// to the destination register. It can optionally update the condition flags
+// based on the result.
+bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9250,65 +9230,68 @@ EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncodin
APSR.V = overflow;
#endif
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t Rd; // the destination register
- uint32_t Rn; // the first operand
- bool setflags;
- uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
- switch (encoding) {
- case eEncodingA1:
- Rd = Bits32(opcode, 15, 12);
- Rn = Bits32(opcode, 19, 16);
- setflags = BitIsSet(opcode, 20);
- imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
-
- // if Rn == '1111' && S == '0' then SEE ADR;
- if (Rn == 15 && !setflags)
- return EmulateADR (opcode, eEncodingA2);
-
- // if Rn == '1101' then SEE SUB (SP minus immediate);
- if (Rn == 13)
- return EmulateSUBSPImm (opcode, eEncodingA1);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (Rd == 15 && setflags)
- return EmulateSUBSPcLrEtc (opcode, encoding);
- break;
- default:
- return false;
- }
- // Read the register value from the operand register Rn.
- uint32_t reg_val = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
+ bool success = false;
- EmulateInstruction::Context context;
- if (Rd == 13)
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- else
- context.type = EmulateInstruction::eContextRegisterPlusOffset;
-
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
- int64_t imm32_signed = imm32;
- context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed);
-
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
- return false;
+ if (ConditionPassed(opcode)) {
+ uint32_t Rd; // the destination register
+ uint32_t Rn; // the first operand
+ bool setflags;
+ uint32_t imm32; // the immediate value to be subtracted from the value
+ // obtained from Rn
+ switch (encoding) {
+ case eEncodingA1:
+ Rd = Bits32(opcode, 15, 12);
+ Rn = Bits32(opcode, 19, 16);
+ setflags = BitIsSet(opcode, 20);
+ imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
+
+ // if Rn == '1111' && S == '0' then SEE ADR;
+ if (Rn == 15 && !setflags)
+ return EmulateADR(opcode, eEncodingA2);
+
+ // if Rn == '1101' then SEE SUB (SP minus immediate);
+ if (Rn == 13)
+ return EmulateSUBSPImm(opcode, eEncodingA1);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (Rd == 15 && setflags)
+ return EmulateSUBSPcLrEtc(opcode, encoding);
+ break;
+ default:
+ return false;
}
- return true;
-}
+ // Read the register value from the operand register Rn.
+ uint32_t reg_val = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
-// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
-// immediate value. It updates the condition flags based on the result, and discards the result.
-bool
-EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+ AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
+
+ EmulateInstruction::Context context;
+ if (Rd == 13)
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ else
+ context.type = EmulateInstruction::eContextRegisterPlusOffset;
+
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg);
+ int64_t imm32_signed = imm32;
+ context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed);
+
+ if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
+}
+
+// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a
+// register value and an
+// immediate value. It updates the condition flags based on the result, and
+// discards the result.
+bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9320,52 +9303,56 @@ EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rn;
- uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
- uint32_t carry; // the carry bit after ARM/Thumb Expand operation
- switch (encoding)
- {
- case eEncodingT1:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
- if (BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rn;
+ uint32_t
+ imm32; // the immediate value to be ANDed to the value obtained from Rn
+ uint32_t carry; // the carry bit after ARM/Thumb Expand operation
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = ThumbExpandImm_C(
+ opcode, APSR_C,
+ carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
+ if (BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 =
+ ARMExpandImm_C(opcode, APSR_C,
+ carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t result = val1 ^ imm32;
+ uint32_t result = val1 ^ imm32;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteFlags(context, result, carry))
- return false;
- }
- return true;
+ if (!WriteFlags(context, result, carry))
+ return false;
+ }
+ return true;
}
-// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
-// optionally-shifted register value. It updates the condition flags based on the result, and discards
+// Test Equivalence (register) performs a bitwise exclusive OR operation on a
+// register value and an
+// optionally-shifted register value. It updates the condition flags based on
+// the result, and discards
// the result.
-bool
-EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9378,62 +9365,60 @@ EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- uint32_t carry;
- switch (encoding)
- {
- case eEncodingT1:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- if (BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ uint32_t carry;
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ if (BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
- if (!success)
- return false;
- uint32_t result = val1 ^ shifted;
+ uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
+ if (!success)
+ return false;
+ uint32_t result = val1 ^ shifted;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteFlags(context, result, carry))
- return false;
- }
- return true;
+ if (!WriteFlags(context, result, carry))
+ return false;
+ }
+ return true;
}
-// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
+// Test (immediate) performs a bitwise AND operation on a register value and an
+// immediate value.
// It updates the condition flags based on the result, and discards the result.
-bool
-EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9445,51 +9430,54 @@ EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rn;
- uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
- uint32_t carry; // the carry bit after ARM/Thumb Expand operation
- switch (encoding)
- {
- case eEncodingT1:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
- if (BadReg(Rn))
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rn;
+ uint32_t
+ imm32; // the immediate value to be ANDed to the value obtained from Rn
+ uint32_t carry; // the carry bit after ARM/Thumb Expand operation
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 = ThumbExpandImm_C(
+ opcode, APSR_C,
+ carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
+ if (BadReg(Rn))
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ imm32 =
+ ARMExpandImm_C(opcode, APSR_C,
+ carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- uint32_t result = val1 & imm32;
+ uint32_t result = val1 & imm32;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteFlags(context, result, carry))
- return false;
- }
- return true;
+ if (!WriteFlags(context, result, carry))
+ return false;
+ }
+ return true;
}
-// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
+// Test (register) performs a bitwise AND operation on a register value and an
+// optionally-shifted register value.
// It updates the condition flags based on the result, and discards the result.
-bool
-EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
// ARM pseudo code...
if ConditionPassed() then
@@ -9502,67 +9490,64 @@ EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding e
// APSR.V unchanged
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed(opcode))
- {
- uint32_t Rn, Rm;
- ARM_ShifterType shift_t;
- uint32_t shift_n; // the shift applied to the value read from Rm
- uint32_t carry;
- switch (encoding)
- {
- case eEncodingT1:
- Rn = Bits32(opcode, 2, 0);
- Rm = Bits32(opcode, 5, 3);
- shift_t = SRType_LSL;
- shift_n = 0;
- break;
- case eEncodingT2:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftThumb(opcode, shift_t);
- if (BadReg(Rn) || BadReg(Rm))
- return false;
- break;
- case eEncodingA1:
- Rn = Bits32(opcode, 19, 16);
- Rm = Bits32(opcode, 3, 0);
- shift_n = DecodeImmShiftARM(opcode, shift_t);
- break;
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t Rn, Rm;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n; // the shift applied to the value read from Rm
+ uint32_t carry;
+ switch (encoding) {
+ case eEncodingT1:
+ Rn = Bits32(opcode, 2, 0);
+ Rm = Bits32(opcode, 5, 3);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+ break;
+ case eEncodingT2:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+ if (BadReg(Rn) || BadReg(Rm))
+ return false;
+ break;
+ case eEncodingA1:
+ Rn = Bits32(opcode, 19, 16);
+ Rm = Bits32(opcode, 3, 0);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+ break;
+ default:
+ return false;
+ }
- // Read the first operand.
- uint32_t val1 = ReadCoreReg(Rn, &success);
- if (!success)
- return false;
+ // Read the first operand.
+ uint32_t val1 = ReadCoreReg(Rn, &success);
+ if (!success)
+ return false;
- // Read the second operand.
- uint32_t val2 = ReadCoreReg(Rm, &success);
- if (!success)
- return false;
+ // Read the second operand.
+ uint32_t val2 = ReadCoreReg(Rm, &success);
+ if (!success)
+ return false;
- uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
- if (!success)
- return false;
- uint32_t result = val1 & shifted;
+ uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
+ if (!success)
+ return false;
+ uint32_t result = val1 & shifted;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextImmediate;
- context.SetNoArgs ();
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextImmediate;
+ context.SetNoArgs();
- if (!WriteFlags(context, result, carry))
- return false;
- }
- return true;
+ if (!WriteFlags(context, result, carry))
+ return false;
+ }
+ return true;
}
-
+
// A8.6.216 SUB (SP minus register)
-bool
-EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -9578,90 +9563,89 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding
APSR.C = carry;
APSR.V = overflow;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t m;
- bool setflags;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
- d = Bits32 (opcode, 11, 8);
- m = Bits32 (opcode, 3, 0);
- setflags = BitIsSet (opcode, 20);
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
- shift_n = DecodeImmShiftThumb (opcode, shift_t);
-
- // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
- if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
- return false;
-
- // if d == 15 || BadReg(m) then UNPREDICTABLE;
- if ((d == 15) || BadReg (m))
- return false;
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
- d = Bits32 (opcode, 15, 12);
- m = Bits32 (opcode, 3, 0);
- setflags = BitIsSet (opcode, 20);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if (d == 15 && setflags)
- EmulateSUBSPcLrEtc (opcode, encoding);
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm5);
- shift_n = DecodeImmShiftARM (opcode, shift_t);
- break;
-
- default:
- return false;
- }
+ bool success = false;
- // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t m;
+ bool setflags;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
- uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
+ d = Bits32(opcode, 11, 8);
+ m = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
- // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
- uint32_t sp_val = ReadCoreReg (SP_REG, &success);
- if (!success)
- return false;
+ // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
- AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
+ // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then
+ // UNPREDICTABLE;
+ if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
+ return false;
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- RegisterInfo sp_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
- RegisterInfo dwarf_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
- context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
+ // if d == 15 || BadReg(m) then UNPREDICTABLE;
+ if ((d == 15) || BadReg(m))
+ return false;
+ break;
- if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
- return false;
+ case eEncodingA1:
+ // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
+ d = Bits32(opcode, 15, 12);
+ m = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if (d == 15 && setflags)
+ EmulateSUBSPcLrEtc(opcode, encoding);
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm5);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
+ uint32_t sp_val = ReadCoreReg(SP_REG, &success);
+ if (!success)
+ return false;
+
+ AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1);
+
+ EmulateInstruction::Context context;
+ context.type = eContextArithmetic;
+ RegisterInfo sp_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg);
+ RegisterInfo dwarf_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
+ context.SetRegisterRegisterOperands(sp_reg, dwarf_reg);
+
+ if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
}
-
-
+
// A8.6.7 ADD (register-shifted register)
-bool
-EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -9675,91 +9659,89 @@ EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncod
APSR.C = carry;
APSR.V = overflow;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t n;
- uint32_t m;
- uint32_t s;
- bool setflags;
- ARM_ShifterType shift_t;
-
- switch (encoding)
- {
- case eEncodingA1:
- // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
- d = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
- s = Bits32 (opcode, 11, 8);
-
- // setflags = (S == '1'); shift_t = DecodeRegShift(type);
- setflags = BitIsSet (opcode, 20);
- shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
-
- // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
- if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
- return false;
- break;
-
- default:
- return false;
- }
-
- // shift_n = UInt(R[s]<7:0>);
- uint32_t Rs = ReadCoreReg (s, &success);
- if (!success)
- return false;
-
- uint32_t shift_n = Bits32 (Rs, 7, 0);
-
- // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
-
- // R[d] = result;
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- RegisterInfo reg_n;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
- RegisterInfo reg_m;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
-
- context.SetRegisterRegisterOperands (reg_n, reg_m);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
- return false;
-
- // if setflags then
- // APSR.N = result<31>;
- // APSR.Z = IsZeroBit(result);
- // APSR.C = carry;
- // APSR.V = overflow;
- if (setflags)
- return WriteFlags (context, res.result, res.carry_out, res.overflow);
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ uint32_t s;
+ bool setflags;
+ ARM_ShifterType shift_t;
+
+ switch (encoding) {
+ case eEncodingA1:
+ // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
+ d = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+ s = Bits32(opcode, 11, 8);
+
+ // setflags = (S == '1'); shift_t = DecodeRegShift(type);
+ setflags = BitIsSet(opcode, 20);
+ shift_t = DecodeRegShift(Bits32(opcode, 6, 5));
+
+ // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
+ if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
+ return false;
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // shift_n = UInt(R[s]<7:0>);
+ uint32_t Rs = ReadCoreReg(s, &success);
+ if (!success)
+ return false;
+
+ uint32_t shift_n = Bits32(Rs, 7, 0);
+
+ // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ AddWithCarryResult res = AddWithCarry(Rn, shifted, 0);
+
+ // R[d] = result;
+ EmulateInstruction::Context context;
+ context.type = eContextArithmetic;
+ RegisterInfo reg_n;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
+ RegisterInfo reg_m;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
+
+ context.SetRegisterRegisterOperands(reg_n, reg_m);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
+ res.result))
+ return false;
+
+ // if setflags then
+ // APSR.N = result<31>;
+ // APSR.Z = IsZeroBit(result);
+ // APSR.C = carry;
+ // APSR.V = overflow;
+ if (setflags)
+ return WriteFlags(context, res.result, res.carry_out, res.overflow);
+ }
+ return true;
}
// A8.6.213 SUB (register)
-bool
-EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -9775,124 +9757,127 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e
APSR.C = carry;
APSR.V = overflow;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t n;
- uint32_t m;
- bool setflags;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
-
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
- d = Bits32 (opcode, 2, 0);
- n = Bits32 (opcode, 5, 3);
- m = Bits32 (opcode, 8, 6);
- setflags = !InITBlock();
-
- // (shift_t, shift_n) = (SRType_LSL, 0);
- shift_t = SRType_LSL;
- shift_n = 0;
-
- break;
-
- case eEncodingT2:
- // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
- d = Bits32 (opcode, 11, 8);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
- setflags = BitIsSet (opcode, 20);
-
- // if Rd == "1111" && S == "1" then SEE CMP (register);
- if (d == 15 && setflags == 1)
- return EmulateCMPImm (opcode, eEncodingT3);
-
- // if Rn == "1101" then SEE SUB (SP minus register);
- if (n == 13)
- return EmulateSUBSPReg (opcode, eEncodingT1);
- // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
- shift_n = DecodeImmShiftThumb (opcode, shift_t);
-
- // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
- if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
- return false;
-
- break;
-
- case eEncodingA1:
- // if Rn == '1101' then SEE SUB (SP minus register);
- // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
- d = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
- setflags = BitIsSet (opcode, 20);
-
- // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
- if ((d == 15) && setflags)
- EmulateSUBSPcLrEtc (opcode, encoding);
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm5);
- shift_n = DecodeImmShiftARM (opcode, shift_t);
-
- break;
-
- default:
- return false;
- }
-
- // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
-
- // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
-
- // if d == 15 then // Can only occur for ARM encoding
- // ALUWritePC(result); // setflags is always FALSE here
- // else
- // R[d] = result;
- // if setflags then
- // APSR.N = result<31>;
- // APSR.Z = IsZeroBit(result);
- // APSR.C = carry;
- // APSR.V = overflow;
-
- EmulateInstruction::Context context;
- context.type = eContextArithmetic;
- RegisterInfo reg_n;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
- RegisterInfo reg_m;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
- context.SetRegisterRegisterOperands (reg_n, reg_m);
-
- if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
- return false;
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ bool setflags;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
+ d = Bits32(opcode, 2, 0);
+ n = Bits32(opcode, 5, 3);
+ m = Bits32(opcode, 8, 6);
+ setflags = !InITBlock();
+
+ // (shift_t, shift_n) = (SRType_LSL, 0);
+ shift_t = SRType_LSL;
+ shift_n = 0;
+
+ break;
+
+ case eEncodingT2:
+ // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
+ d = Bits32(opcode, 11, 8);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+
+ // if Rd == "1111" && S == "1" then SEE CMP (register);
+ if (d == 15 && setflags == 1)
+ return EmulateCMPImm(opcode, eEncodingT3);
+
+ // if Rn == "1101" then SEE SUB (SP minus register);
+ if (n == 13)
+ return EmulateSUBSPReg(opcode, eEncodingT1);
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
+ shift_n = DecodeImmShiftThumb(opcode, shift_t);
+
+ // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then
+ // UNPREDICTABLE;
+ if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) ||
+ BadReg(m))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // if Rn == '1101' then SEE SUB (SP minus register);
+ // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
+ d = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+ setflags = BitIsSet(opcode, 20);
+
+ // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related
+ // instructions;
+ if ((d == 15) && setflags)
+ EmulateSUBSPcLrEtc(opcode, encoding);
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm5);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+
+ // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1);
+
+ // if d == 15 then // Can only occur for ARM encoding
+ // ALUWritePC(result); // setflags is always FALSE here
+ // else
+ // R[d] = result;
+ // if setflags then
+ // APSR.N = result<31>;
+ // APSR.Z = IsZeroBit(result);
+ // APSR.C = carry;
+ // APSR.V = overflow;
+
+ EmulateInstruction::Context context;
+ context.type = eContextArithmetic;
+ RegisterInfo reg_n;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n);
+ RegisterInfo reg_m;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m);
+ context.SetRegisterRegisterOperands(reg_n, reg_m);
+
+ if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags,
+ res.carry_out, res.overflow))
+ return false;
+ }
+ return true;
}
-
+
// A8.6.202 STREX
-// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
-// word from a register to memory if the executing processor has exclusive access to the memory addressed.
-bool
-EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
-{
+// Store Register Exclusive calculates an address from a base register value and
+// an immediate offset, and stores a
+// word from a register to memory if the executing processor has exclusive
+// access to the memory addressed.
+bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -9903,90 +9888,92 @@ EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding en
else
R[d] = 1;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t d;
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- switch (encoding)
- {
- case eEncodingT1:
- // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
- d = Bits32 (opcode, 11, 8);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
- if (BadReg (d) || BadReg (t) || (n == 15))
- return false;
-
- // if d == n || d == t then UNPREDICTABLE;
- if ((d == n) || (d == t))
- return false;
-
- break;
-
- case eEncodingA1:
- // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
- d = Bits32 (opcode, 15, 12);
- t = Bits32 (opcode, 3, 0);
- n = Bits32 (opcode, 19, 16);
- imm32 = 0;
-
- // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
- if ((d == 15) || (t == 15) || (n == 15))
- return false;
-
- // if d == n || d == t then UNPREDICTABLE;
- if ((d == n) || (d == t))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- // address = R[n] + imm32;
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- addr_t address = Rn + imm32;
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
-
- // if ExclusiveMonitorsPass(address,4) then
- // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
- // always return true.
- if (true)
- {
- // MemA[address,4] = R[t];
- uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
- if (!success)
- return false;
-
- if (!MemAWrite (context, address, Rt, addr_byte_size))
- return false;
-
- // R[d] = 0;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
- return false;
- }
-#if 0 // unreachable because if true
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t d;
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ switch (encoding) {
+ case eEncodingT1:
+ // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00',
+ // 32);
+ d = Bits32(opcode, 11, 8);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
+ if (BadReg(d) || BadReg(t) || (n == 15))
+ return false;
+
+ // if d == n || d == t then UNPREDICTABLE;
+ if ((d == n) || (d == t))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero
+ // offset
+ d = Bits32(opcode, 15, 12);
+ t = Bits32(opcode, 3, 0);
+ n = Bits32(opcode, 19, 16);
+ imm32 = 0;
+
+ // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
+ if ((d == 15) || (t == 15) || (n == 15))
+ return false;
+
+ // if d == n || d == t then UNPREDICTABLE;
+ if ((d == n) || (d == t))
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ // address = R[n] + imm32;
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ addr_t address = Rn + imm32;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32);
+
+ // if ExclusiveMonitorsPass(address,4) then
+ // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the
+ // sake of emulation, we will say this
+ // always return
+ // true.
+ if (true) {
+ // MemA[address,4] = R[t];
+ uint32_t Rt =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
+ if (!success)
+ return false;
+
+ if (!MemAWrite(context, address, Rt, addr_byte_size))
+ return false;
+
+ // R[d] = 0;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0))
+ return false;
+ }
+#if 0 // unreachable because if true
else
{
// R[d] = 1;
@@ -9994,14 +9981,13 @@ EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding en
return false;
}
#endif // unreachable because if true
- }
- return true;
+ }
+ return true;
}
// A8.6.197 STRB (immediate, ARM)
-bool
-EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -10010,94 +9996,91 @@ EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncodi
MemU[address,1] = R[t]<7:0>;
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- switch (encoding)
- {
- case eEncodingA1:
- // if P == '0' && W == '1' then SEE STRBT;
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // if t == 15 then UNPREDICTABLE;
- if (t == 15)
- return false;
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- // address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- // MemU[address,1] = R[t]<7:0>;
- uint32_t Rt = ReadCoreReg (t, &success);
- if (!success)
- return false;
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
-
- if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ switch (encoding) {
+ case eEncodingA1:
+ // if P == '0' && W == '1' then SEE STRBT;
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // if t == 15 then UNPREDICTABLE;
+ if (t == 15)
+ return false;
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // MemU[address,1] = R[t]<7:0>;
+ uint32_t Rt = ReadCoreReg(t, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
+
+ if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
// A8.6.194 STR (immediate, ARM)
-bool
-EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -10106,110 +10089,107 @@ EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncodin
MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- switch (encoding)
- {
- case eEncodingA1:
- // if P == '0' && W == '1' then SEE STRT;
- // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH;
- // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
- t = Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 11, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // if wback && (n == 15 || n == t) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t)))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- // address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
-
- // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
- uint32_t Rt = ReadCoreReg (t, &success);
- if (!success)
- return false;
-
- if (t == 15)
- {
- uint32_t pc_value = ReadCoreReg (PC_REG, &success);
- if (!success)
- return false;
-
- if (!MemUWrite (context, address, pc_value, addr_byte_size))
- return false;
- }
- else
- {
- if (!MemUWrite (context, address, Rt, addr_byte_size))
- return false;
- }
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetImmediate (offset_addr);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ switch (encoding) {
+ case eEncodingA1:
+ // if P == '0' && W == '1' then SEE STRT;
+ // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 ==
+ // '000000000100' then SEE PUSH;
+ // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
+ t = Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 11, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // if wback && (n == 15 || n == t) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t)))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
+
+ // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
+ uint32_t Rt = ReadCoreReg(t, &success);
+ if (!success)
+ return false;
+
+ if (t == 15) {
+ uint32_t pc_value = ReadCoreReg(PC_REG, &success);
+ if (!success)
+ return false;
+
+ if (!MemUWrite(context, address, pc_value, addr_byte_size))
+ return false;
+ } else {
+ if (!MemUWrite(context, address, Rt, addr_byte_size))
+ return false;
+ }
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetImmediate(offset_addr);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
// A8.6.66 LDRD (immediate)
-// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
-// words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
-{
+// Load Register Dual (immediate) calculates an address from a base register
+// value and an immediate offset, loads two
+// words from memory, and writes them to two registers. It can use offset,
+// post-indexed, or pre-indexed addressing.
+bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -10219,144 +10199,146 @@ EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEnc
R[t2] = MemA[address+4,4];
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t t2;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- switch (encoding)
- {
- case eEncodingT1:
- //if P == '0' && W == '0' then SEE 'Related encodings';
- //if Rn == '1111' then SEE LDRD (literal);
- //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
- t = Bits32 (opcode, 15, 12);
- t2 = Bits32 (opcode, 11, 8);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- //index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsSet (opcode, 21);
-
- //if wback && (n == t || n == t2) then UNPREDICTABLE;
- if (wback && ((n == t) || (n == t2)))
- return false;
-
- //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
- if (BadReg (t) || BadReg (t2) || (t == t2))
- return false;
-
- break;
-
- case eEncodingA1:
- //if Rn == '1111' then SEE LDRD (literal);
- //if Rt<0> == '1' then UNPREDICTABLE;
- //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
- t = Bits32 (opcode, 15, 12);
- if (BitIsSet (t, 0))
- return false;
- t2 = t + 1;
- n = Bits32 (opcode, 19, 16);
- imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
-
- //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- //if P == '0' && W == '1' then UNPREDICTABLE;
- if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
- return false;
-
- //if wback && (n == t || n == t2) then UNPREDICTABLE;
- if (wback && ((n == t) || (n == t2)))
- return false;
-
- //if t2 == 15 then UNPREDICTABLE;
- if (t2 == 15)
- return false;
-
- break;
-
- default:
- return false;
- }
-
- //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- //address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- //R[t] = MemA[address,4];
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- EmulateInstruction::Context context;
- if (n == 13)
- context.type = eContextPopRegisterOffStack;
- else
- context.type = eContextRegisterLoad;
- context.SetAddress(address);
-
- const uint32_t addr_byte_size = GetAddressByteSize();
- uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
-
- //R[t2] = MemA[address+4,4];
- context.SetAddress(address + 4);
- data = MemARead (context, address + 4, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
- return false;
-
- //if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t t2;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ switch (encoding) {
+ case eEncodingT1:
+ // if P == '0' && W == '0' then SEE 'Related encodings';
+ // if Rn == '1111' then SEE LDRD (literal);
+ // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
+ // ZeroExtend(imm8:'00', 32);
+ t = Bits32(opcode, 15, 12);
+ t2 = Bits32(opcode, 11, 8);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsSet(opcode, 21);
+
+ // if wback && (n == t || n == t2) then UNPREDICTABLE;
+ if (wback && ((n == t) || (n == t2)))
+ return false;
+
+ // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
+ if (BadReg(t) || BadReg(t2) || (t == t2))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // if Rn == '1111' then SEE LDRD (literal);
+ // if Rt<0> == '1' then UNPREDICTABLE;
+ // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
+ // 32);
+ t = Bits32(opcode, 15, 12);
+ if (BitIsSet(t, 0))
+ return false;
+ t2 = t + 1;
+ n = Bits32(opcode, 19, 16);
+ imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // if P == '0' && W == '1' then UNPREDICTABLE;
+ if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
+ return false;
+
+ // if wback && (n == t || n == t2) then UNPREDICTABLE;
+ if (wback && ((n == t) || (n == t2)))
+ return false;
+
+ // if t2 == 15 then UNPREDICTABLE;
+ if (t2 == 15)
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // R[t] = MemA[address,4];
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ EmulateInstruction::Context context;
+ if (n == 13)
+ context.type = eContextPopRegisterOffStack;
+ else
+ context.type = eContextRegisterLoad;
+ context.SetAddress(address);
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
+ return false;
+
+ // R[t2] = MemA[address+4,4];
+ context.SetAddress(address + 4);
+ data = MemARead(context, address + 4, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
+ data))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
+
// A8.6.68 LDRD (register)
-// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
-// words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
-{
+// Load Register Dual (register) calculates an address from a base register
+// value and a register offset, loads two
+// words from memory, and writes them to two registers. It can use offset,
+// post-indexed or pre-indexed addressing.
+bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -10366,127 +10348,127 @@ EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEnco
R[t2] = MemA[address+4,4];
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t t2;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
-
- switch (encoding)
- {
- case eEncodingA1:
- // if Rt<0> == '1' then UNPREDICTABLE;
- // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- if (BitIsSet (t, 0))
- return false;
- t2 = t + 1;
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // if P == '0' && W == '1' then UNPREDICTABLE;
- if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
- return false;
-
- // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
- if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
- return false;
-
- // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t) || (n == t2)))
- return false;
-
- // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
- if ((ArchVersion() < 6) && wback && (m == n))
- return false;
- break;
-
- default:
- return false;
- }
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
- RegisterInfo offset_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
-
- // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + Rm;
- else
- offset_addr = Rn - Rm;
-
- // address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- EmulateInstruction::Context context;
- if (n == 13)
- context.type = eContextPopRegisterOffStack;
- else
- context.type = eContextRegisterLoad;
- context.SetAddress(address);
-
- // R[t] = MemA[address,4];
- const uint32_t addr_byte_size = GetAddressByteSize();
- uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
- return false;
-
- // R[t2] = MemA[address+4,4];
-
- data = MemARead (context, address + 4, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t t2;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+
+ switch (encoding) {
+ case eEncodingA1:
+ // if Rt<0> == '1' then UNPREDICTABLE;
+ // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ if (BitIsSet(t, 0))
+ return false;
+ t2 = t + 1;
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // if P == '0' && W == '1' then UNPREDICTABLE;
+ if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
+ return false;
+
+ // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
+ if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
+ return false;
+
+ // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t) || (n == t2)))
+ return false;
+
+ // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
+ if ((ArchVersion() < 6) && wback && (m == n))
+ return false;
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+ RegisterInfo offset_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
+
+ // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + Rm;
+ else
+ offset_addr = Rn - Rm;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ EmulateInstruction::Context context;
+ if (n == 13)
+ context.type = eContextPopRegisterOffStack;
+ else
+ context.type = eContextRegisterLoad;
+ context.SetAddress(address);
+
+ // R[t] = MemA[address,4];
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data))
+ return false;
+
+ // R[t2] = MemA[address+4,4];
+
+ data = MemARead(context, address + 4, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2,
+ data))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
// A8.6.200 STRD (immediate)
-// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
-// stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing.
-bool
-EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
-{
+// Store Register Dual (immediate) calculates an address from a base register
+// value and an immediate offset, and
+// stores two words from two registers to memory. It can use offset,
+// post-indexed, or pre-indexed addressing.
+bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(n);
@@ -10496,151 +10478,150 @@ EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding
MemA[address+4,4] = R[t2];
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t t2;
- uint32_t n;
- uint32_t imm32;
- bool index;
- bool add;
- bool wback;
-
- switch (encoding)
- {
- case eEncodingT1:
- // if P == '0' && W == '0' then SEE 'Related encodings';
- // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
- t = Bits32 (opcode, 15, 12);
- t2 = Bits32 (opcode, 11, 8);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // index = (P == '1'); add = (U == '1'); wback = (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsSet (opcode, 21);
-
- // if wback && (n == t || n == t2) then UNPREDICTABLE;
- if (wback && ((n == t) || (n == t2)))
- return false;
-
- // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
- if ((n == 15) || BadReg (t) || BadReg (t2))
- return false;
-
- break;
-
- case eEncodingA1:
- // if Rt<0> == '1' then UNPREDICTABLE;
- // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
- t = Bits32 (opcode, 15, 12);
- if (BitIsSet (t, 0))
- return false;
-
- t2 = t + 1;
- n = Bits32 (opcode, 19, 16);
- imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // if P == '0' && W == '1' then UNPREDICTABLE;
- if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
- return false;
-
- // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t) || (n == t2)))
- return false;
-
- // if t2 == 15 then UNPREDICTABLE;
- if (t2 == 15)
- return false;
-
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + imm32;
- else
- offset_addr = Rn - imm32;
-
- //address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
-
- //MemA[address,4] = R[t];
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
-
- uint32_t data = ReadCoreReg (t, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- if (n == 13)
- context.type = eContextPushRegisterOnStack;
- else
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
-
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- if (!MemAWrite (context, address, data, addr_byte_size))
- return false;
- //MemA[address+4,4] = R[t2];
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
-
- data = ReadCoreReg (t2, &success);
- if (!success)
- return false;
-
- if (!MemAWrite (context, address + 4, data, addr_byte_size))
- return false;
-
- //if wback then R[n] = offset_addr;
- if (wback)
- {
- if (n == 13)
- context.type = eContextAdjustStackPointer;
- else
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
+ bool success = false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t t2;
+ uint32_t n;
+ uint32_t imm32;
+ bool index;
+ bool add;
+ bool wback;
+
+ switch (encoding) {
+ case eEncodingT1:
+ // if P == '0' && W == '0' then SEE 'Related encodings';
+ // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 =
+ // ZeroExtend(imm8:'00', 32);
+ t = Bits32(opcode, 15, 12);
+ t2 = Bits32(opcode, 11, 8);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // index = (P == '1'); add = (U == '1'); wback = (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsSet(opcode, 21);
+
+ // if wback && (n == t || n == t2) then UNPREDICTABLE;
+ if (wback && ((n == t) || (n == t2)))
+ return false;
+
+ // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
+ if ((n == 15) || BadReg(t) || BadReg(t2))
+ return false;
+
+ break;
+
+ case eEncodingA1:
+ // if Rt<0> == '1' then UNPREDICTABLE;
+ // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L,
+ // 32);
+ t = Bits32(opcode, 15, 12);
+ if (BitIsSet(t, 0))
+ return false;
+
+ t2 = t + 1;
+ n = Bits32(opcode, 19, 16);
+ imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // if P == '0' && W == '1' then UNPREDICTABLE;
+ if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
+ return false;
+
+ // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t) || (n == t2)))
+ return false;
+
+ // if t2 == 15 then UNPREDICTABLE;
+ if (t2 == 15)
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + imm32;
+ else
+ offset_addr = Rn - imm32;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+
+ // MemA[address,4] = R[t];
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+
+ uint32_t data = ReadCoreReg(t, &success);
+ if (!success)
+ return false;
+
+ EmulateInstruction::Context context;
+ if (n == 13)
+ context.type = eContextPushRegisterOnStack;
+ else
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ if (!MemAWrite(context, address, data, addr_byte_size))
+ return false;
+
+ // MemA[address+4,4] = R[t2];
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ (address + 4) - Rn);
+
+ data = ReadCoreReg(t2, &success);
+ if (!success)
+ return false;
+
+ if (!MemAWrite(context, address + 4, data, addr_byte_size))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ if (n == 13)
+ context.type = eContextAdjustStackPointer;
+ else
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
-
+
// A8.6.201 STRD (register)
-bool
-EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -10650,137 +10631,136 @@ EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding
MemA[address+4,4] = R[t2];
if wback then R[n] = offset_addr;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- uint32_t t;
- uint32_t t2;
- uint32_t n;
- uint32_t m;
- bool index;
- bool add;
- bool wback;
-
- switch (encoding)
- {
- case eEncodingA1:
- // if Rt<0> == '1' then UNPREDICTABLE;
- // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
- t = Bits32 (opcode, 15, 12);
- if (BitIsSet (t, 0))
- return false;
-
- t2 = t+1;
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
- index = BitIsSet (opcode, 24);
- add = BitIsSet (opcode, 23);
- wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
-
- // if P == '0' && W == '1' then UNPREDICTABLE;
- if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
- return false;
-
- // if t2 == 15 || m == 15 then UNPREDICTABLE;
- if ((t2 == 15) || (m == 15))
- return false;
-
- // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
- if (wback && ((n == 15) || (n == t) || (n == t2)))
- return false;
-
- // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
- if ((ArchVersion() < 6) && wback && (m == n))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
- RegisterInfo offset_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
- RegisterInfo data_reg;
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
- addr_t offset_addr;
- if (add)
- offset_addr = Rn + Rm;
- else
- offset_addr = Rn - Rm;
-
- // address = if index then offset_addr else R[n];
- addr_t address;
- if (index)
- address = offset_addr;
- else
- address = Rn;
- // MemA[address,4] = R[t];
- uint32_t Rt = ReadCoreReg (t, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- if (t == 13)
- context.type = eContextPushRegisterOnStack;
- else
- context.type = eContextRegisterStore;
-
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
- context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
-
- const uint32_t addr_byte_size = GetAddressByteSize();
-
- if (!MemAWrite (context, address, Rt, addr_byte_size))
- return false;
-
- // MemA[address+4,4] = R[t2];
- uint32_t Rt2 = ReadCoreReg (t2, &success);
- if (!success)
- return false;
-
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
-
- context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
-
- if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
- return false;
-
- // if wback then R[n] = offset_addr;
- if (wback)
- {
- context.type = eContextAdjustBaseRegister;
- context.SetAddress (offset_addr);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
- return false;
-
- }
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t t;
+ uint32_t t2;
+ uint32_t n;
+ uint32_t m;
+ bool index;
+ bool add;
+ bool wback;
+
+ switch (encoding) {
+ case eEncodingA1:
+ // if Rt<0> == '1' then UNPREDICTABLE;
+ // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
+ t = Bits32(opcode, 15, 12);
+ if (BitIsSet(t, 0))
+ return false;
+
+ t2 = t + 1;
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
+ index = BitIsSet(opcode, 24);
+ add = BitIsSet(opcode, 23);
+ wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21);
+
+ // if P == '0' && W == '1' then UNPREDICTABLE;
+ if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21))
+ return false;
+
+ // if t2 == 15 || m == 15 then UNPREDICTABLE;
+ if ((t2 == 15) || (m == 15))
+ return false;
+
+ // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
+ if (wback && ((n == 15) || (n == t) || (n == t2)))
+ return false;
+
+ // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
+ if ((ArchVersion() < 6) && wback && (m == n))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+ RegisterInfo offset_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
+ RegisterInfo data_reg;
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
+ addr_t offset_addr;
+ if (add)
+ offset_addr = Rn + Rm;
+ else
+ offset_addr = Rn - Rm;
+
+ // address = if index then offset_addr else R[n];
+ addr_t address;
+ if (index)
+ address = offset_addr;
+ else
+ address = Rn;
+ // MemA[address,4] = R[t];
+ uint32_t Rt = ReadCoreReg(t, &success);
+ if (!success)
+ return false;
+
+ EmulateInstruction::Context context;
+ if (t == 13)
+ context.type = eContextPushRegisterOnStack;
+ else
+ context.type = eContextRegisterStore;
+
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg);
+ context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
+ data_reg);
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ if (!MemAWrite(context, address, Rt, addr_byte_size))
+ return false;
+
+ // MemA[address+4,4] = R[t2];
+ uint32_t Rt2 = ReadCoreReg(t2, &success);
+ if (!success)
+ return false;
+
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
+
+ context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg,
+ data_reg);
+
+ if (!MemAWrite(context, address + 4, Rt2, addr_byte_size))
+ return false;
+
+ // if wback then R[n] = offset_addr;
+ if (wback) {
+ context.type = eContextAdjustBaseRegister;
+ context.SetAddress(offset_addr);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ offset_addr))
+ return false;
+ }
+ }
+ return true;
}
-
+
// A8.6.319 VLDM
-// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
+// Vector Load Multiple loads multiple extension registers from consecutive
+// memory locations using an address from
// an ARM core register.
-bool
-EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
@@ -10794,184 +10774,185 @@ EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding enc
// Combine the word-aligned words in the correct order for current endianness.
D[d+r] = if BigEndian() then word1:word2 else word2:word1;
#endif
-
- bool success = false;
-
- if (ConditionPassed(opcode))
- {
- bool single_regs;
- bool add;
- bool wback;
- uint32_t d;
- uint32_t n;
- uint32_t imm32;
- uint32_t regs;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
- // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
- // if P == '1' && W == '0' then SEE VLDR;
- // if P == U && W == '1' then UNDEFINED;
- if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
- return false;
-
- // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
- // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
- single_regs = false;
- add = BitIsSet (opcode, 23);
- wback = BitIsSet (opcode, 21);
-
- // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
- regs = Bits32 (opcode, 7, 0) / 2;
-
- // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
- if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
- return false;
-
- // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
- if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
- return false;
-
- break;
-
- case eEncodingT2:
- case eEncodingA2:
- // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
- // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
- // if P == '1' && W == '0' then SEE VLDR;
- // if P == U && W == '1' then UNDEFINED;
- if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
- return false;
-
- // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
- // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
- single_regs = true;
- add = BitIsSet (opcode, 23);
- wback = BitIsSet (opcode, 21);
- d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
- n = Bits32 (opcode, 19, 16);
-
- // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
- imm32 = Bits32 (opcode, 7, 0) << 2;
- regs = Bits32 (opcode, 7, 0);
-
- // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
- if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
- return false;
-
- // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
- if ((regs == 0) || ((d + regs) > 32))
- return false;
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ bool single_regs;
+ bool add;
+ bool wback;
+ uint32_t d;
+ uint32_t n;
+ uint32_t imm32;
+ uint32_t regs;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1:
+ // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
+ // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
+ // if P == '1' && W == '0' then SEE VLDR;
+ // if P == U && W == '1' then UNDEFINED;
+ if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
+ return false;
+
+ // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
+ // !), 101 (DB with !)
+ // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
+ single_regs = false;
+ add = BitIsSet(opcode, 23);
+ wback = BitIsSet(opcode, 21);
+
+ // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
+ regs = Bits32(opcode, 7, 0) / 2;
+
+ // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
+ // UNPREDICTABLE;
+ if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
+ return false;
+
+ // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
+ if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ case eEncodingA2:
+ // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
+ // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
+ // if P == '1' && W == '0' then SEE VLDR;
+ // if P == U && W == '1' then UNDEFINED;
+ if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
+ return false;
+
+ // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
+ // !), 101 (DB with !)
+ // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
+ // UInt(Vd:D); n = UInt(Rn);
+ single_regs = true;
+ add = BitIsSet(opcode, 23);
+ wback = BitIsSet(opcode, 21);
+ d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
+ n = Bits32(opcode, 19, 16);
+
+ // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+ regs = Bits32(opcode, 7, 0);
+
+ // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
+ // UNPREDICTABLE;
+ if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
+ return false;
+
+ // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
+ if ((regs == 0) || ((d + regs) > 32))
+ return false;
+ break;
+
+ default:
+ return false;
+ }
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = if add then R[n] else R[n]-imm32;
+ addr_t address;
+ if (add)
+ address = Rn;
+ else
+ address = Rn - imm32;
+
+ // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
+ EmulateInstruction::Context context;
+
+ if (wback) {
+ uint32_t value;
+ if (add)
+ value = Rn + imm32;
+ else
+ value = Rn - imm32;
+
+ context.type = eContextAdjustBaseRegister;
+ context.SetImmediateSigned(value - Rn);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ value))
+ return false;
+ }
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
+
+ context.type = eContextRegisterLoad;
+
+ // for r = 0 to regs-1
+ for (uint32_t r = 0; r < regs; ++r) {
+ if (single_regs) {
+ // S[d+r] = MemA[address,4]; address = address+4;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+
+ uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
if (!success)
- return false;
-
- // address = if add then R[n] else R[n]-imm32;
- addr_t address;
- if (add)
- address = Rn;
- else
- address = Rn - imm32;
-
- // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
- EmulateInstruction::Context context;
-
- if (wback)
- {
- uint32_t value;
- if (add)
- value = Rn + imm32;
- else
- value = Rn - imm32;
-
- context.type = eContextAdjustBaseRegister;
- context.SetImmediateSigned (value - Rn);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
- return false;
-
- }
-
- const uint32_t addr_byte_size = GetAddressByteSize();
- uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
+ return false;
- context.type = eContextRegisterLoad;
-
- // for r = 0 to regs-1
- for (uint32_t r = 0; r < regs; ++r)
- {
- if (single_regs)
- {
- // S[d+r] = MemA[address,4]; address = address+4;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
-
- uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
- return false;
-
- address = address + 4;
- }
- else
- {
- // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
- uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
- uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- address = address + 8;
- // // Combine the word-aligned words in the correct order for current endianness.
- // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
- uint64_t data;
- if (GetByteOrder() == eByteOrderBig)
- {
- data = word1;
- data = (data << 32) | word2;
- }
- else
- {
- data = word2;
- data = (data << 32) | word1;
- }
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
- return false;
- }
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ start_reg + d + r, data))
+ return false;
+
+ address = address + 4;
+ } else {
+ // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address =
+ // address+8;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+ uint32_t word1 =
+ MemARead(context, address, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn);
+ uint32_t word2 =
+ MemARead(context, address + 4, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ address = address + 8;
+ // // Combine the word-aligned words in the correct order for current
+ // endianness.
+ // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
+ uint64_t data;
+ if (GetByteOrder() == eByteOrderBig) {
+ data = word1;
+ data = (data << 32) | word2;
+ } else {
+ data = word2;
+ data = (data << 32) | word1;
}
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ start_reg + d + r, data))
+ return false;
+ }
}
- return true;
+ }
+ return true;
}
// A8.6.399 VSTM
-// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
+// Vector Store Multiple stores multiple extension registers to consecutive
+// memory locations using an address from an
// ARM core register.
-bool
-EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
@@ -10986,189 +10967,198 @@ EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding enc
MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
address = address+8;
#endif
-
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- bool single_regs;
- bool add;
- bool wback;
- uint32_t d;
- uint32_t n;
- uint32_t imm32;
- uint32_t regs;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
- // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
- // if P == '1' && W == '0' then SEE VSTR;
- // if P == U && W == '1' then UNDEFINED;
- if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
- return false;
-
- // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
- // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
- single_regs = false;
- add = BitIsSet (opcode, 23);
- wback = BitIsSet (opcode, 21);
-
- // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
- regs = Bits32 (opcode, 7, 0) / 2;
-
- // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
- if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
- return false;
-
- // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
- if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
- return false;
-
- break;
-
- case eEncodingT2:
- case eEncodingA2:
- // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
- // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
- // if P == '1' && W == '0' then SEE VSTR;
- // if P == U && W == '1' then UNDEFINED;
- if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
- return false;
-
- // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
- // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
- single_regs = true;
- add = BitIsSet (opcode, 23);
- wback = BitIsSet (opcode, 21);
- d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
- n = Bits32 (opcode, 19, 16);
-
- // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
- imm32 = Bits32 (opcode, 7, 0) << 2;
- regs = Bits32 (opcode, 7, 0);
-
- // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
- if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
- return false;
-
- // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
- if ((regs == 0) || ((d + regs) > 32))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
+
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ bool single_regs;
+ bool add;
+ bool wback;
+ uint32_t d;
+ uint32_t n;
+ uint32_t imm32;
+ uint32_t regs;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1:
+ // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
+ // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
+ // if P == '1' && W == '0' then SEE VSTR;
+ // if P == U && W == '1' then UNDEFINED;
+ if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
+ return false;
+
+ // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
+ // !), 101 (DB with !)
+ // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
+ single_regs = false;
+ add = BitIsSet(opcode, 23);
+ wback = BitIsSet(opcode, 21);
+
+ // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
+ regs = Bits32(opcode, 7, 0) / 2;
+
+ // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
+ // UNPREDICTABLE;
+ if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
+ return false;
+
+ // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
+ if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ case eEncodingA2:
+ // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
+ // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
+ // if P == '1' && W == '0' then SEE VSTR;
+ // if P == U && W == '1' then UNDEFINED;
+ if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21))
+ return false;
+
+ // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with
+ // !), 101 (DB with !)
+ // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d =
+ // UInt(Vd:D); n = UInt(Rn);
+ single_regs = true;
+ add = BitIsSet(opcode, 23);
+ wback = BitIsSet(opcode, 21);
+ d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
+ n = Bits32(opcode, 19, 16);
+
+ // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+ regs = Bits32(opcode, 7, 0);
+
+ // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then
+ // UNPREDICTABLE;
+ if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
+ return false;
+
+ // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
+ if ((regs == 0) || ((d + regs) > 32))
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = if add then R[n] else R[n]-imm32;
+ addr_t address;
+ if (add)
+ address = Rn;
+ else
+ address = Rn - imm32;
+
+ EmulateInstruction::Context context;
+ // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
+ if (wback) {
+ uint32_t value;
+ if (add)
+ value = Rn + imm32;
+ else
+ value = Rn - imm32;
+
+ context.type = eContextAdjustBaseRegister;
+ context.SetRegisterPlusOffset(base_reg, value - Rn);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ value))
+ return false;
+ }
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
+
+ context.type = eContextRegisterStore;
+ // for r = 0 to regs-1
+ for (uint32_t r = 0; r < regs; ++r) {
+
+ if (single_regs) {
+ // MemA[address,4] = S[d+r]; address = address+4;
+ uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
+ start_reg + d + r, 0, &success);
if (!success)
+ return false;
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ address - Rn);
+ if (!MemAWrite(context, address, data, addr_byte_size))
+ return false;
+
+ address = address + 4;
+ } else {
+ // // Store as two word-aligned words in the correct order for current
+ // endianness.
+ // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else
+ // D[d+r]<31:0>;
+ // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else
+ // D[d+r]<63:32>;
+ uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF,
+ start_reg + d + r, 0, &success);
+ if (!success)
+ return false;
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg);
+
+ if (GetByteOrder() == eByteOrderBig) {
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ address - Rn);
+ if (!MemAWrite(context, address, Bits64(data, 63, 32),
+ addr_byte_size))
return false;
-
- // address = if add then R[n] else R[n]-imm32;
- addr_t address;
- if (add)
- address = Rn;
- else
- address = Rn - imm32;
-
- EmulateInstruction::Context context;
- // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
- if (wback)
- {
- uint32_t value;
- if (add)
- value = Rn + imm32;
- else
- value = Rn - imm32;
-
- context.type = eContextAdjustBaseRegister;
- context.SetRegisterPlusOffset (base_reg, value - Rn);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
- return false;
- }
-
- const uint32_t addr_byte_size = GetAddressByteSize();
- uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
- context.type = eContextRegisterStore;
- // for r = 0 to regs-1
- for (uint32_t r = 0; r < regs; ++r)
- {
-
- if (single_regs)
- {
- // MemA[address,4] = S[d+r]; address = address+4;
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
- if (!success)
- return false;
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
- if (!MemAWrite (context, address, data, addr_byte_size))
- return false;
-
- address = address + 4;
- }
- else
- {
- // // Store as two word-aligned words in the correct order for current endianness.
- // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
- // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
- uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
- if (!success)
- return false;
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
-
- if (GetByteOrder() == eByteOrderBig)
- {
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
- if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
- return false;
-
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
- if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
- return false;
- }
- else
- {
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
- if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
- return false;
-
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
- if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
- return false;
- }
- // address = address+8;
- address = address + 8;
- }
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ (address + 4) - Rn);
+ if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
+ addr_byte_size))
+ return false;
+ } else {
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ address - Rn);
+ if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
+ return false;
+
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ (address + 4) - Rn);
+ if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
+ addr_byte_size))
+ return false;
}
+ // address = address+8;
+ address = address + 8;
+ }
}
- return true;
+ }
+ return true;
}
-
+
// A8.6.320
-// This instruction loads a single extension register from memory, using an address from an ARM core register, with
+// This instruction loads a single extension register from memory, using an
+// address from an ARM core register, with
// an optional offset.
-bool
-EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode,
+ ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
@@ -11180,125 +11170,122 @@ EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
word1 = MemA[address,4]; word2 = MemA[address+4,4];
// Combine the word-aligned words in the correct order for current endianness.
D[d] = if BigEndian() then word1:word2 else word2:word1;
-#endif
-
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- bool single_reg;
- bool add;
- uint32_t imm32;
- uint32_t d;
- uint32_t n;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
- single_reg = false;
- add = BitIsSet (opcode, 23);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // d = UInt(D:Vd); n = UInt(Rn);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
-
- break;
-
- case eEncodingT2:
- case eEncodingA2:
- // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
- single_reg = true;
- add = BitIsSet (opcode, 23);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // d = UInt(Vd:D); n = UInt(Rn);
- d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
- n = Bits32 (opcode, 19, 16);
-
- break;
-
- default:
- return false;
- }
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // base = if n == 15 then Align(PC,4) else R[n];
- uint32_t base;
- if (n == 15)
- base = AlignPC (Rn);
- else
- base = Rn;
-
- // address = if add then (base + imm32) else (base - imm32);
- addr_t address;
- if (add)
- address = base + imm32;
- else
- address = base - imm32;
-
- const uint32_t addr_byte_size = GetAddressByteSize();
- uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
+#endif
- EmulateInstruction::Context context;
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - base);
-
- if (single_reg)
- {
- // S[d] = MemA[address,4];
- uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
- return false;
- }
- else
- {
- // word1 = MemA[address,4]; word2 = MemA[address+4,4];
- uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
- if (!success)
- return false;
-
- context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
- uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
- if (!success)
- return false;
- // // Combine the word-aligned words in the correct order for current endianness.
- // D[d] = if BigEndian() then word1:word2 else word2:word1;
- uint64_t data64;
- if (GetByteOrder() == eByteOrderBig)
- {
- data64 = word1;
- data64 = (data64 << 32) | word2;
- }
- else
- {
- data64 = word2;
- data64 = (data64 << 32) | word1;
- }
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
- return false;
- }
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ bool single_reg;
+ bool add;
+ uint32_t imm32;
+ uint32_t d;
+ uint32_t n;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1:
+ // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
+ // 32);
+ single_reg = false;
+ add = BitIsSet(opcode, 23);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // d = UInt(D:Vd); n = UInt(Rn);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+
+ break;
+
+ case eEncodingT2:
+ case eEncodingA2:
+ // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
+ single_reg = true;
+ add = BitIsSet(opcode, 23);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // d = UInt(Vd:D); n = UInt(Rn);
+ d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
+ n = Bits32(opcode, 19, 16);
+
+ break;
+
+ default:
+ return false;
}
- return true;
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // base = if n == 15 then Align(PC,4) else R[n];
+ uint32_t base;
+ if (n == 15)
+ base = AlignPC(Rn);
+ else
+ base = Rn;
+
+ // address = if add then (base + imm32) else (base - imm32);
+ addr_t address;
+ if (add)
+ address = base + imm32;
+ else
+ address = base - imm32;
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
+
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - base);
+
+ if (single_reg) {
+ // S[d] = MemA[address,4];
+ uint32_t data = MemARead(context, address, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
+ data))
+ return false;
+ } else {
+ // word1 = MemA[address,4]; word2 = MemA[address+4,4];
+ uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+
+ context.SetRegisterPlusOffset(base_reg, (address + 4) - base);
+ uint32_t word2 =
+ MemARead(context, address + 4, addr_byte_size, 0, &success);
+ if (!success)
+ return false;
+ // // Combine the word-aligned words in the correct order for current
+ // endianness.
+ // D[d] = if BigEndian() then word1:word2 else word2:word1;
+ uint64_t data64;
+ if (GetByteOrder() == eByteOrderBig) {
+ data64 = word1;
+ data64 = (data64 << 32) | word2;
+ } else {
+ data64 = word2;
+ data64 = (data64 << 32) | word1;
+ }
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d,
+ data64))
+ return false;
+ }
+ }
+ return true;
}
// A8.6.400 VSTR
-// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
+// This instruction stores a signle extension register to memory, using an
+// address from an ARM core register, with an
// optional offset.
-bool
-EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode,
+ ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
@@ -11311,127 +11298,127 @@ EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
#endif
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- bool single_reg;
- bool add;
- uint32_t imm32;
- uint32_t d;
- uint32_t n;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
- single_reg = false;
- add = BitIsSet (opcode, 23);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // d = UInt(D:Vd); n = UInt(Rn);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
-
- // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
- if ((n == 15) && (CurrentInstrSet() != eModeARM))
- return false;
-
- break;
-
- case eEncodingT2:
- case eEncodingA2:
- // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
- single_reg = true;
- add = BitIsSet (opcode, 23);
- imm32 = Bits32 (opcode, 7, 0) << 2;
-
- // d = UInt(Vd:D); n = UInt(Rn);
- d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
- n = Bits32 (opcode, 19, 16);
-
- // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
- if ((n == 15) && (CurrentInstrSet() != eModeARM))
- return false;
-
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // address = if add then (R[n] + imm32) else (R[n] - imm32);
- addr_t address;
- if (add)
- address = Rn + imm32;
- else
- address = Rn - imm32;
-
- const uint32_t addr_byte_size = GetAddressByteSize();
- uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
+ bool success = false;
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
- EmulateInstruction::Context context;
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
-
- if (single_reg)
- {
- // MemA[address,4] = S[d];
- uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
- if (!success)
- return false;
-
- if (!MemAWrite (context, address, data, addr_byte_size))
- return false;
- }
- else
- {
- // // Store as two word-aligned words in the correct order for current endianness.
- // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
- // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
- uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
- if (!success)
- return false;
-
- if (GetByteOrder() == eByteOrderBig)
- {
- if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
- return false;
-
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
- if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
- return false;
- }
- else
- {
- if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
- return false;
-
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
- if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
- return false;
- }
- }
+ if (ConditionPassed(opcode)) {
+ bool single_reg;
+ bool add;
+ uint32_t imm32;
+ uint32_t d;
+ uint32_t n;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1:
+ // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00',
+ // 32);
+ single_reg = false;
+ add = BitIsSet(opcode, 23);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // d = UInt(D:Vd); n = UInt(Rn);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+
+ // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
+ if ((n == 15) && (CurrentInstrSet() != eModeARM))
+ return false;
+
+ break;
+
+ case eEncodingT2:
+ case eEncodingA2:
+ // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
+ single_reg = true;
+ add = BitIsSet(opcode, 23);
+ imm32 = Bits32(opcode, 7, 0) << 2;
+
+ // d = UInt(Vd:D); n = UInt(Rn);
+ d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22);
+ n = Bits32(opcode, 19, 16);
+
+ // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
+ if ((n == 15) && (CurrentInstrSet() != eModeARM))
+ return false;
+
+ break;
+
+ default:
+ return false;
}
- return true;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = if add then (R[n] + imm32) else (R[n] - imm32);
+ addr_t address;
+ if (add)
+ address = Rn + imm32;
+ else
+ address = Rn - imm32;
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+ uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg);
+ EmulateInstruction::Context context;
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
+
+ if (single_reg) {
+ // MemA[address,4] = S[d];
+ uint32_t data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
+ if (!success)
+ return false;
+
+ if (!MemAWrite(context, address, data, addr_byte_size))
+ return false;
+ } else {
+ // // Store as two word-aligned words in the correct order for current
+ // endianness.
+ // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
+ // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
+ uint64_t data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success);
+ if (!success)
+ return false;
+
+ if (GetByteOrder() == eByteOrderBig) {
+ if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size))
+ return false;
+
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ (address + 4) - Rn);
+ if (!MemAWrite(context, address + 4, Bits64(data, 31, 0),
+ addr_byte_size))
+ return false;
+ } else {
+ if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size))
+ return false;
+
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ (address + 4) - Rn);
+ if (!MemAWrite(context, address + 4, Bits64(data, 63, 32),
+ addr_byte_size))
+ return false;
+ }
+ }
+ }
+ return true;
}
// A8.6.307 VLDI1 (multiple single elements)
-// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every
+// This instruction loads elements from memory into one, two, three or four
+// registers, without de-interleaving. Every
// element of each register is loaded.
-bool
-EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode,
+ ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
@@ -11443,161 +11430,153 @@ EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding e
address = address + ebytes;
#endif
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- uint32_t regs;
- uint32_t alignment;
- uint32_t ebytes;
- uint32_t esize;
- uint32_t elements;
- uint32_t d;
- uint32_t n;
- uint32_t m;
- bool wback;
- bool register_index;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- {
- // case type of
- // when '0111'
- // regs = 1; if align<1> == '1' then UNDEFINED;
- // when '1010'
- // regs = 2; if align == '11' then UNDEFINED;
- // when '0110'
- // regs = 3; if align<1> == '1' then UNDEFINED;
- // when '0010'
- // regs = 4;
- // otherwise
- // SEE 'Related encodings';
- uint32_t type = Bits32 (opcode, 11, 8);
- uint32_t align = Bits32 (opcode, 5, 4);
- if (type == 7) // '0111'
- {
- regs = 1;
- if (BitIsSet (align, 1))
- return false;
- }
- else if (type == 10) // '1010'
- {
- regs = 2;
- if (align == 3)
- return false;
-
- }
- else if (type == 6) // '0110'
- {
- regs = 3;
- if (BitIsSet (align, 1))
- return false;
- }
- else if (type == 2) // '0010'
- {
- regs = 4;
- }
- else
- return false;
-
- // alignment = if align == '00' then 1 else 4 << UInt(align);
- if (align == 0)
- alignment = 1;
- else
- alignment = 4 << align;
-
- // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
- ebytes = 1 << Bits32 (opcode, 7, 6);
- esize = 8 * ebytes;
- elements = 8 / ebytes;
-
- // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 15);
- m = Bits32 (opcode, 3, 0);
-
- // wback = (m != 15); register_index = (m != 15 && m != 13);
- wback = (m != 15);
- register_index = ((m != 15) && (m != 13));
-
- // if d+regs > 32 then UNPREDICTABLE;
- if ((d + regs) > 32)
- return false;
- }
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t regs;
+ uint32_t alignment;
+ uint32_t ebytes;
+ uint32_t esize;
+ uint32_t elements;
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ bool wback;
+ bool register_index;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1: {
+ // case type of
+ // when '0111'
+ // regs = 1; if align<1> == '1' then UNDEFINED;
+ // when '1010'
+ // regs = 2; if align == '11' then UNDEFINED;
+ // when '0110'
+ // regs = 3; if align<1> == '1' then UNDEFINED;
+ // when '0010'
+ // regs = 4;
+ // otherwise
+ // SEE 'Related encodings';
+ uint32_t type = Bits32(opcode, 11, 8);
+ uint32_t align = Bits32(opcode, 5, 4);
+ if (type == 7) // '0111'
+ {
+ regs = 1;
+ if (BitIsSet(align, 1))
+ return false;
+ } else if (type == 10) // '1010'
+ {
+ regs = 2;
+ if (align == 3)
+ return false;
+
+ } else if (type == 6) // '0110'
+ {
+ regs = 3;
+ if (BitIsSet(align, 1))
+ return false;
+ } else if (type == 2) // '0010'
+ {
+ regs = 4;
+ } else
+ return false;
+
+ // alignment = if align == '00' then 1 else 4 << UInt(align);
+ if (align == 0)
+ alignment = 1;
+ else
+ alignment = 4 << align;
+
+ // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
+ ebytes = 1 << Bits32(opcode, 7, 6);
+ esize = 8 * ebytes;
+ elements = 8 / ebytes;
+
+ // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 15);
+ m = Bits32(opcode, 3, 0);
+
+ // wback = (m != 15); register_index = (m != 15 && m != 13);
+ wback = (m != 15);
+ register_index = ((m != 15) && (m != 13));
+
+ // if d+regs > 32 then UNPREDICTABLE;
+ if ((d + regs) > 32)
+ return false;
+ } break;
+
+ default:
+ return false;
+ }
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = R[n]; if (address MOD alignment) != 0 then
+ // GenerateAlignmentException();
+ addr_t address = Rn;
+ if ((address % alignment) != 0)
+ return false;
+
+ EmulateInstruction::Context context;
+ // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
+ if (wback) {
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t offset;
+ if (register_index)
+ offset = Rm;
+ else
+ offset = 8 * regs;
+
+ uint32_t value = Rn + offset;
+ context.type = eContextAdjustBaseRegister;
+ context.SetRegisterPlusOffset(base_reg, offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ value))
+ return false;
+ }
+
+ // for r = 0 to regs-1
+ for (uint32_t r = 0; r < regs; ++r) {
+ // for e = 0 to elements-1
+ uint64_t assembled_data = 0;
+ for (uint32_t e = 0; e < elements; ++e) {
+ // Elem[D[d+r],e,esize] = MemU[address,ebytes];
+ context.type = eContextRegisterLoad;
+ context.SetRegisterPlusOffset(base_reg, address - Rn);
+ uint64_t data = MemURead(context, address, ebytes, 0, &success);
if (!success)
- return false;
-
- // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
- addr_t address = Rn;
- if ((address % alignment) != 0)
- return false;
-
- EmulateInstruction::Context context;
- // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
- if (wback)
- {
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t offset;
- if (register_index)
- offset = Rm;
- else
- offset = 8 * regs;
-
- uint32_t value = Rn + offset;
- context.type = eContextAdjustBaseRegister;
- context.SetRegisterPlusOffset (base_reg, offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
- return false;
-
- }
-
- // for r = 0 to regs-1
- for (uint32_t r = 0; r < regs; ++r)
- {
- // for e = 0 to elements-1
- uint64_t assembled_data = 0;
- for (uint32_t e = 0; e < elements; ++e)
- {
- // Elem[D[d+r],e,esize] = MemU[address,ebytes];
- context.type = eContextRegisterLoad;
- context.SetRegisterPlusOffset (base_reg, address - Rn);
- uint64_t data = MemURead (context, address, ebytes, 0, &success);
- if (!success)
- return false;
-
- assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
-
- // address = address + ebytes;
- address = address + ebytes;
- }
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
- return false;
- }
+ return false;
+
+ assembled_data =
+ (data << (e * esize)) |
+ assembled_data; // New data goes to the left of existing data
+
+ // address = address + ebytes;
+ address = address + ebytes;
+ }
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
+ assembled_data))
+ return false;
}
- return true;
+ }
+ return true;
}
// A8.6.308 VLD1 (single element to one lane)
//
-bool
-EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
@@ -11606,174 +11585,177 @@ EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncodi
Elem[D[d],index,esize] = MemU[address,ebytes];
#endif
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- uint32_t ebytes;
- uint32_t esize;
- uint32_t index;
- uint32_t alignment;
- uint32_t d;
- uint32_t n;
- uint32_t m;
- bool wback;
- bool register_index;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- {
- uint32_t size = Bits32 (opcode, 11, 10);
- uint32_t index_align = Bits32 (opcode, 7, 4);
- // if size == '11' then SEE VLD1 (single element to all lanes);
- if (size == 3)
- return EmulateVLD1SingleAll (opcode, encoding);
- // case size of
- if (size == 0) // when '00'
- {
- // if index_align<0> != '0' then UNDEFINED;
- if (BitIsClear (index_align, 0))
- return false;
-
- // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
- ebytes = 1;
- esize = 8;
- index = Bits32 (index_align, 3, 1);
- alignment = 1;
- }
- else if (size == 1) // when '01'
- {
- // if index_align<1> != '0' then UNDEFINED;
- if (BitIsClear (index_align, 1))
- return false;
-
- // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
- ebytes = 2;
- esize = 16;
- index = Bits32 (index_align, 3, 2);
-
- // alignment = if index_align<0> == '0' then 1 else 2;
- if (BitIsClear (index_align, 0))
- alignment = 1;
- else
- alignment = 2;
- }
- else if (size == 2) // when '10'
- {
- // if index_align<2> != '0' then UNDEFINED;
- if (BitIsClear (index_align, 2))
- return false;
-
- // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
- if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
- return false;
-
- // ebytes = 4; esize = 32; index = UInt(index_align<3>);
- ebytes = 4;
- esize = 32;
- index = Bit32 (index_align, 3);
-
- // alignment = if index_align<1:0> == '00' then 1 else 4;
- if (Bits32 (index_align, 1, 0) == 0)
- alignment = 1;
- else
- alignment = 4;
- }
- else
- {
- return false;
- }
- // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
- wback = (m != 15);
- register_index = ((m != 15) && (m != 13));
-
- if (n == 15)
- return false;
-
- }
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
- addr_t address = Rn;
- if ((address % alignment) != 0)
- return false;
-
- EmulateInstruction::Context context;
- // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
- if (wback)
- {
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t offset;
- if (register_index)
- offset = Rm;
- else
- offset = ebytes;
-
- uint32_t value = Rn + offset;
-
- context.type = eContextAdjustBaseRegister;
- context.SetRegisterPlusOffset (base_reg, offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
- return false;
- }
-
- // Elem[D[d],index,esize] = MemU[address,ebytes];
- uint32_t element = MemURead (context, address, esize, 0, &success);
- if (!success)
- return false;
-
- element = element << (index * esize);
-
- uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
- if (!success)
- return false;
-
- uint64_t all_ones = -1;
- uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's
- // at element & to the right of element.
- if (index > 0)
- mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
- // now mask should be 0's where element goes & 1's
- // everywhere else.
-
- uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits
- reg_data = masked_reg & element; // Put 'element' into those bits in reg_data.
-
- context.type = eContextRegisterLoad;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
- return false;
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t ebytes;
+ uint32_t esize;
+ uint32_t index;
+ uint32_t alignment;
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ bool wback;
+ bool register_index;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1: {
+ uint32_t size = Bits32(opcode, 11, 10);
+ uint32_t index_align = Bits32(opcode, 7, 4);
+ // if size == '11' then SEE VLD1 (single element to all lanes);
+ if (size == 3)
+ return EmulateVLD1SingleAll(opcode, encoding);
+ // case size of
+ if (size == 0) // when '00'
+ {
+ // if index_align<0> != '0' then UNDEFINED;
+ if (BitIsClear(index_align, 0))
+ return false;
+
+ // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
+ ebytes = 1;
+ esize = 8;
+ index = Bits32(index_align, 3, 1);
+ alignment = 1;
+ } else if (size == 1) // when '01'
+ {
+ // if index_align<1> != '0' then UNDEFINED;
+ if (BitIsClear(index_align, 1))
+ return false;
+
+ // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
+ ebytes = 2;
+ esize = 16;
+ index = Bits32(index_align, 3, 2);
+
+ // alignment = if index_align<0> == '0' then 1 else 2;
+ if (BitIsClear(index_align, 0))
+ alignment = 1;
+ else
+ alignment = 2;
+ } else if (size == 2) // when '10'
+ {
+ // if index_align<2> != '0' then UNDEFINED;
+ if (BitIsClear(index_align, 2))
+ return false;
+
+ // if index_align<1:0> != '00' && index_align<1:0> != '11' then
+ // UNDEFINED;
+ if ((Bits32(index_align, 1, 0) != 0) &&
+ (Bits32(index_align, 1, 0) != 3))
+ return false;
+
+ // ebytes = 4; esize = 32; index = UInt(index_align<3>);
+ ebytes = 4;
+ esize = 32;
+ index = Bit32(index_align, 3);
+
+ // alignment = if index_align<1:0> == '00' then 1 else 4;
+ if (Bits32(index_align, 1, 0) == 0)
+ alignment = 1;
+ else
+ alignment = 4;
+ } else {
+ return false;
+ }
+ // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
+ // then UNPREDICTABLE;
+ wback = (m != 15);
+ register_index = ((m != 15) && (m != 13));
+
+ if (n == 15)
+ return false;
+
+ } break;
+
+ default:
+ return false;
}
- return true;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = R[n]; if (address MOD alignment) != 0 then
+ // GenerateAlignmentException();
+ addr_t address = Rn;
+ if ((address % alignment) != 0)
+ return false;
+
+ EmulateInstruction::Context context;
+ // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
+ if (wback) {
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t offset;
+ if (register_index)
+ offset = Rm;
+ else
+ offset = ebytes;
+
+ uint32_t value = Rn + offset;
+
+ context.type = eContextAdjustBaseRegister;
+ context.SetRegisterPlusOffset(base_reg, offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ value))
+ return false;
+ }
+
+ // Elem[D[d],index,esize] = MemU[address,ebytes];
+ uint32_t element = MemURead(context, address, esize, 0, &success);
+ if (!success)
+ return false;
+
+ element = element << (index * esize);
+
+ uint64_t reg_data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
+ if (!success)
+ return false;
+
+ uint64_t all_ones = -1;
+ uint64_t mask = all_ones
+ << ((index + 1) * esize); // mask is all 1's to left of
+ // where 'element' goes, & all 0's
+ // at element & to the right of element.
+ if (index > 0)
+ mask = mask | Bits64(all_ones, (index * esize) - 1,
+ 0); // add 1's to the right of where 'element' goes.
+ // now mask should be 0's where element goes & 1's
+ // everywhere else.
+
+ uint64_t masked_reg =
+ reg_data & mask; // Take original reg value & zero out 'element' bits
+ reg_data =
+ masked_reg & element; // Put 'element' into those bits in reg_data.
+
+ context.type = eContextRegisterLoad;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d,
+ reg_data))
+ return false;
+ }
+ return true;
}
// A8.6.391 VST1 (multiple single elements)
-// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
+// Vector Store (multiple single elements) stores elements to memory from one,
+// two, three, or four registers, without
// interleaving. Every element of each register is stored.
-bool
-EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
-{
+bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode,
+ ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
@@ -11784,159 +11766,152 @@ EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding e
MemU[address,ebytes] = Elem[D[d+r],e,esize];
address = address + ebytes;
#endif
-
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- uint32_t regs;
- uint32_t alignment;
- uint32_t ebytes;
- uint32_t esize;
- uint32_t elements;
- uint32_t d;
- uint32_t n;
- uint32_t m;
- bool wback;
- bool register_index;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- {
- uint32_t type = Bits32 (opcode, 11, 8);
- uint32_t align = Bits32 (opcode, 5, 4);
-
- // case type of
- if (type == 7) // when '0111'
- {
- // regs = 1; if align<1> == '1' then UNDEFINED;
- regs = 1;
- if (BitIsSet (align, 1))
- return false;
- }
- else if (type == 10) // when '1010'
- {
- // regs = 2; if align == '11' then UNDEFINED;
- regs = 2;
- if (align == 3)
- return false;
- }
- else if (type == 6) // when '0110'
- {
- // regs = 3; if align<1> == '1' then UNDEFINED;
- regs = 3;
- if (BitIsSet (align, 1))
- return false;
- }
- else if (type == 2) // when '0010'
- // regs = 4;
- regs = 4;
- else // otherwise
- // SEE 'Related encodings';
- return false;
-
- // alignment = if align == '00' then 1 else 4 << UInt(align);
- if (align == 0)
- alignment = 1;
- else
- alignment = 4 << align;
-
- // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
- ebytes = 1 << Bits32 (opcode,7, 6);
- esize = 8 * ebytes;
- elements = 8 / ebytes;
-
- // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // wback = (m != 15); register_index = (m != 15 && m != 13);
- wback = (m != 15);
- register_index = ((m != 15) && (m != 13));
-
- // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
- if ((d + regs) > 32)
- return false;
-
- if (n == 15)
- return false;
-
- }
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
- addr_t address = Rn;
- if ((address % alignment) != 0)
- return false;
-
- EmulateInstruction::Context context;
- // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
- if (wback)
- {
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t offset;
- if (register_index)
- offset = Rm;
- else
- offset = 8 * regs;
-
- context.type = eContextAdjustBaseRegister;
- context.SetRegisterPlusOffset (base_reg, offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
- return false;
- }
-
- RegisterInfo data_reg;
- context.type = eContextRegisterStore;
- // for r = 0 to regs-1
- for (uint32_t r = 0; r < regs; ++r)
- {
- GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
- uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
- if (!success)
- return false;
- // for e = 0 to elements-1
- for (uint32_t e = 0; e < elements; ++e)
- {
- // MemU[address,ebytes] = Elem[D[d+r],e,esize];
- uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
-
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
- if (!MemUWrite (context, address, word, ebytes))
- return false;
-
- // address = address + ebytes;
- address = address + ebytes;
- }
- }
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t regs;
+ uint32_t alignment;
+ uint32_t ebytes;
+ uint32_t esize;
+ uint32_t elements;
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ bool wback;
+ bool register_index;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1: {
+ uint32_t type = Bits32(opcode, 11, 8);
+ uint32_t align = Bits32(opcode, 5, 4);
+
+ // case type of
+ if (type == 7) // when '0111'
+ {
+ // regs = 1; if align<1> == '1' then UNDEFINED;
+ regs = 1;
+ if (BitIsSet(align, 1))
+ return false;
+ } else if (type == 10) // when '1010'
+ {
+ // regs = 2; if align == '11' then UNDEFINED;
+ regs = 2;
+ if (align == 3)
+ return false;
+ } else if (type == 6) // when '0110'
+ {
+ // regs = 3; if align<1> == '1' then UNDEFINED;
+ regs = 3;
+ if (BitIsSet(align, 1))
+ return false;
+ } else if (type == 2) // when '0010'
+ // regs = 4;
+ regs = 4;
+ else // otherwise
+ // SEE 'Related encodings';
+ return false;
+
+ // alignment = if align == '00' then 1 else 4 << UInt(align);
+ if (align == 0)
+ alignment = 1;
+ else
+ alignment = 4 << align;
+
+ // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
+ ebytes = 1 << Bits32(opcode, 7, 6);
+ esize = 8 * ebytes;
+ elements = 8 / ebytes;
+
+ // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // wback = (m != 15); register_index = (m != 15 && m != 13);
+ wback = (m != 15);
+ register_index = ((m != 15) && (m != 13));
+
+ // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
+ if ((d + regs) > 32)
+ return false;
+
+ if (n == 15)
+ return false;
+
+ } break;
+
+ default:
+ return false;
}
- return true;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = R[n]; if (address MOD alignment) != 0 then
+ // GenerateAlignmentException();
+ addr_t address = Rn;
+ if ((address % alignment) != 0)
+ return false;
+
+ EmulateInstruction::Context context;
+ // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
+ if (wback) {
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t offset;
+ if (register_index)
+ offset = Rm;
+ else
+ offset = 8 * regs;
+
+ context.type = eContextAdjustBaseRegister;
+ context.SetRegisterPlusOffset(base_reg, offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ Rn + offset))
+ return false;
+ }
+
+ RegisterInfo data_reg;
+ context.type = eContextRegisterStore;
+ // for r = 0 to regs-1
+ for (uint32_t r = 0; r < regs; ++r) {
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
+ uint64_t register_data = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
+ if (!success)
+ return false;
+
+ // for e = 0 to elements-1
+ for (uint32_t e = 0; e < elements; ++e) {
+ // MemU[address,ebytes] = Elem[D[d+r],e,esize];
+ uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize);
+
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg,
+ address - Rn);
+ if (!MemUWrite(context, address, word, ebytes))
+ return false;
+
+ // address = address + ebytes;
+ address = address + ebytes;
+ }
+ }
+ }
+ return true;
}
// A8.6.392 VST1 (single element from one lane)
-// This instruction stores one element to memory from one element of a register.
-bool
-EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
-{
+// This instruction stores one element to memory from one element of a register.
+bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode,
+ ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
@@ -11945,160 +11920,158 @@ EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding enc
MemU[address,ebytes] = Elem[D[d],index,esize];
#endif
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- uint32_t ebytes;
- uint32_t esize;
- uint32_t index;
- uint32_t alignment;
- uint32_t d;
- uint32_t n;
- uint32_t m;
- bool wback;
- bool register_index;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- {
- uint32_t size = Bits32 (opcode, 11, 10);
- uint32_t index_align = Bits32 (opcode, 7, 4);
-
- // if size == '11' then UNDEFINED;
- if (size == 3)
- return false;
-
- // case size of
- if (size == 0) // when '00'
- {
- // if index_align<0> != '0' then UNDEFINED;
- if (BitIsClear (index_align, 0))
- return false;
- // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
- ebytes = 1;
- esize = 8;
- index = Bits32 (index_align, 3, 1);
- alignment = 1;
- }
- else if (size == 1) // when '01'
- {
- // if index_align<1> != '0' then UNDEFINED;
- if (BitIsClear (index_align, 1))
- return false;
-
- // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
- ebytes = 2;
- esize = 16;
- index = Bits32 (index_align, 3, 2);
-
- // alignment = if index_align<0> == '0' then 1 else 2;
- if (BitIsClear (index_align, 0))
- alignment = 1;
- else
- alignment = 2;
- }
- else if (size == 2) // when '10'
- {
- // if index_align<2> != '0' then UNDEFINED;
- if (BitIsClear (index_align, 2))
- return false;
-
- // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
- if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
- return false;
-
- // ebytes = 4; esize = 32; index = UInt(index_align<3>);
- ebytes = 4;
- esize = 32;
- index = Bit32 (index_align, 3);
-
- // alignment = if index_align<1:0> == '00' then 1 else 4;
- if (Bits32 (index_align, 1, 0) == 0)
- alignment = 1;
- else
- alignment = 4;
- }
- else
- {
- return false;
- }
- // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
- wback = (m != 15);
- register_index = ((m != 15) && (m != 13));
-
- if (n == 15)
- return false;
- }
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
- addr_t address = Rn;
- if ((address % alignment) != 0)
- return false;
-
- EmulateInstruction::Context context;
- // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
- if (wback)
- {
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t offset;
- if (register_index)
- offset = Rm;
- else
- offset = ebytes;
-
- context.type = eContextAdjustBaseRegister;
- context.SetRegisterPlusOffset (base_reg, offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
- return false;
- }
-
- // MemU[address,ebytes] = Elem[D[d],index,esize];
- uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
- if (!success)
- return false;
-
- uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize);
-
- RegisterInfo data_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
-
- if (!MemUWrite (context, address, word, ebytes))
- return false;
+ bool success = false;
+
+ if (ConditionPassed(opcode)) {
+ uint32_t ebytes;
+ uint32_t esize;
+ uint32_t index;
+ uint32_t alignment;
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ bool wback;
+ bool register_index;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1: {
+ uint32_t size = Bits32(opcode, 11, 10);
+ uint32_t index_align = Bits32(opcode, 7, 4);
+
+ // if size == '11' then UNDEFINED;
+ if (size == 3)
+ return false;
+
+ // case size of
+ if (size == 0) // when '00'
+ {
+ // if index_align<0> != '0' then UNDEFINED;
+ if (BitIsClear(index_align, 0))
+ return false;
+ // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
+ ebytes = 1;
+ esize = 8;
+ index = Bits32(index_align, 3, 1);
+ alignment = 1;
+ } else if (size == 1) // when '01'
+ {
+ // if index_align<1> != '0' then UNDEFINED;
+ if (BitIsClear(index_align, 1))
+ return false;
+
+ // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
+ ebytes = 2;
+ esize = 16;
+ index = Bits32(index_align, 3, 2);
+
+ // alignment = if index_align<0> == '0' then 1 else 2;
+ if (BitIsClear(index_align, 0))
+ alignment = 1;
+ else
+ alignment = 2;
+ } else if (size == 2) // when '10'
+ {
+ // if index_align<2> != '0' then UNDEFINED;
+ if (BitIsClear(index_align, 2))
+ return false;
+
+ // if index_align<1:0> != '00' && index_align<1:0> != '11' then
+ // UNDEFINED;
+ if ((Bits32(index_align, 1, 0) != 0) &&
+ (Bits32(index_align, 1, 0) != 3))
+ return false;
+
+ // ebytes = 4; esize = 32; index = UInt(index_align<3>);
+ ebytes = 4;
+ esize = 32;
+ index = Bit32(index_align, 3);
+
+ // alignment = if index_align<1:0> == '00' then 1 else 4;
+ if (Bits32(index_align, 1, 0) == 0)
+ alignment = 1;
+ else
+ alignment = 4;
+ } else {
+ return false;
+ }
+ // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15
+ // then UNPREDICTABLE;
+ wback = (m != 15);
+ register_index = ((m != 15) && (m != 13));
+
+ if (n == 15)
+ return false;
+ } break;
+
+ default:
+ return false;
}
- return true;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = R[n]; if (address MOD alignment) != 0 then
+ // GenerateAlignmentException();
+ addr_t address = Rn;
+ if ((address % alignment) != 0)
+ return false;
+
+ EmulateInstruction::Context context;
+ // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
+ if (wback) {
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t offset;
+ if (register_index)
+ offset = Rm;
+ else
+ offset = ebytes;
+
+ context.type = eContextAdjustBaseRegister;
+ context.SetRegisterPlusOffset(base_reg, offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ Rn + offset))
+ return false;
+ }
+
+ // MemU[address,ebytes] = Elem[D[d],index,esize];
+ uint64_t register_data =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
+ if (!success)
+ return false;
+
+ uint64_t word =
+ Bits64(register_data, ((index + 1) * esize) - 1, index * esize);
+
+ RegisterInfo data_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg);
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn);
+
+ if (!MemUWrite(context, address, word, ebytes))
+ return false;
+ }
+ return true;
}
// A8.6.309 VLD1 (single element to all lanes)
-// This instruction loads one element from memory into every element of one or two vectors.
-bool
-EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
-{
+// This instruction loads one element from memory into every element of one or
+// two vectors.
+bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
@@ -12109,128 +12082,128 @@ EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEnc
D[d+r] = replicated_element;
#endif
- bool success = false;
-
- if (ConditionPassed (opcode))
- {
- uint32_t ebytes;
- uint32_t elements;
- uint32_t regs;
- uint32_t alignment;
- uint32_t d;
- uint32_t n;
- uint32_t m;
- bool wback;
- bool register_index;
-
- switch (encoding)
- {
- case eEncodingT1:
- case eEncodingA1:
- {
- //if size == '11' || (size == '00' && a == '1') then UNDEFINED;
- uint32_t size = Bits32 (opcode, 7, 6);
- if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
- return false;
-
- //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2;
- ebytes = 1 << size;
- elements = 8 / ebytes;
- if (BitIsClear (opcode, 5))
- regs = 1;
- else
- regs = 2;
-
- //alignment = if a == '0' then 1 else ebytes;
- if (BitIsClear (opcode, 4))
- alignment = 1;
- else
- alignment = ebytes;
-
- //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
- d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
-
- //wback = (m != 15); register_index = (m != 15 && m != 13);
- wback = (m != 15);
- register_index = ((m != 15) && (m != 13));
-
- //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
- if ((d + regs) > 32)
- return false;
-
- if (n == 15)
- return false;
- }
- break;
-
- default:
- return false;
- }
-
- RegisterInfo base_reg;
- GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
- addr_t address = Rn;
- if ((address % alignment) != 0)
- return false;
-
- EmulateInstruction::Context context;
- // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
- if (wback)
- {
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- uint32_t offset;
- if (register_index)
- offset = Rm;
- else
- offset = ebytes;
-
- context.type = eContextAdjustBaseRegister;
- context.SetRegisterPlusOffset (base_reg, offset);
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
- return false;
- }
-
- // replicated_element = Replicate(MemU[address,ebytes], elements);
-
- context.type = eContextRegisterLoad;
- uint64_t word = MemURead (context, address, ebytes, 0, &success);
- if (!success)
- return false;
-
- uint64_t replicated_element = 0;
- uint32_t esize = ebytes * 8;
- for (uint32_t e = 0; e < elements; ++e)
- replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
+ bool success = false;
- // for r = 0 to regs-1
- for (uint32_t r = 0; r < regs; ++r)
- {
- // D[d+r] = replicated_element;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t ebytes;
+ uint32_t elements;
+ uint32_t regs;
+ uint32_t alignment;
+ uint32_t d;
+ uint32_t n;
+ uint32_t m;
+ bool wback;
+ bool register_index;
+
+ switch (encoding) {
+ case eEncodingT1:
+ case eEncodingA1: {
+ // if size == '11' || (size == '00' && a == '1') then UNDEFINED;
+ uint32_t size = Bits32(opcode, 7, 6);
+ if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4)))
+ return false;
+
+ // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0'
+ // then 1 else 2;
+ ebytes = 1 << size;
+ elements = 8 / ebytes;
+ if (BitIsClear(opcode, 5))
+ regs = 1;
+ else
+ regs = 2;
+
+ // alignment = if a == '0' then 1 else ebytes;
+ if (BitIsClear(opcode, 4))
+ alignment = 1;
+ else
+ alignment = ebytes;
+
+ // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
+ d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12);
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+
+ // wback = (m != 15); register_index = (m != 15 && m != 13);
+ wback = (m != 15);
+ register_index = ((m != 15) && (m != 13));
+
+ // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
+ if ((d + regs) > 32)
+ return false;
+
+ if (n == 15)
+ return false;
+ } break;
+
+ default:
+ return false;
}
- return true;
+
+ RegisterInfo base_reg;
+ GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg);
+
+ uint32_t Rn = ReadCoreReg(n, &success);
+ if (!success)
+ return false;
+
+ // address = R[n]; if (address MOD alignment) != 0 then
+ // GenerateAlignmentException();
+ addr_t address = Rn;
+ if ((address % alignment) != 0)
+ return false;
+
+ EmulateInstruction::Context context;
+ // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
+ if (wback) {
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
+
+ uint32_t offset;
+ if (register_index)
+ offset = Rm;
+ else
+ offset = ebytes;
+
+ context.type = eContextAdjustBaseRegister;
+ context.SetRegisterPlusOffset(base_reg, offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n,
+ Rn + offset))
+ return false;
+ }
+
+ // replicated_element = Replicate(MemU[address,ebytes], elements);
+
+ context.type = eContextRegisterLoad;
+ uint64_t word = MemURead(context, address, ebytes, 0, &success);
+ if (!success)
+ return false;
+
+ uint64_t replicated_element = 0;
+ uint32_t esize = ebytes * 8;
+ for (uint32_t e = 0; e < elements; ++e)
+ replicated_element =
+ (replicated_element << esize) | Bits64(word, esize - 1, 0);
+
+ // for r = 0 to regs-1
+ for (uint32_t r = 0; r < regs; ++r) {
+ // D[d+r] = replicated_element;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r,
+ replicated_element))
+ return false;
+ }
+ }
+ return true;
}
// B6.2.13 SUBS PC, LR and related instructions
-//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the
-// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
-bool
-EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
-{
+// The SUBS PC, LR, #<const? instruction provides an exception return without
+// the use of the stack. It subtracts the
+// immediate constant from the LR, branches to the resulting address, and also
+// copies the SPSR to the CPSR.
+bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode,
+ const ARMEncoding encoding) {
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
@@ -12254,1240 +12227,1597 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod
BranchWritePC(result);
#endif
- bool success = false;
+ bool success = false;
- if (ConditionPassed (opcode))
- {
- uint32_t n;
- uint32_t m;
- uint32_t imm32;
- bool register_form;
- ARM_ShifterType shift_t;
- uint32_t shift_n;
- uint32_t code;
-
- switch (encoding)
- {
- case eEncodingT1:
- // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
- // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB
- n = 14;
- imm32 = Bits32 (opcode, 7, 0);
- register_form = false;
- code = 2;
-
- // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- if (InITBlock() && !LastInITBlock())
- return false;
-
- break;
-
- case eEncodingA1:
- // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
- n = Bits32 (opcode, 19, 16);
- imm32 = ARMExpandImm (opcode);
- register_form = false;
- code = Bits32 (opcode, 24, 21);
-
- break;
-
- case eEncodingA2:
- // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
- n = Bits32 (opcode, 19, 16);
- m = Bits32 (opcode, 3, 0);
- register_form = true;
-
- // (shift_t, shift_n) = DecodeImmShift(type, imm5);
- shift_n = DecodeImmShiftARM (opcode, shift_t);
-
- break;
-
- default:
- return false;
- }
+ if (ConditionPassed(opcode)) {
+ uint32_t n;
+ uint32_t m;
+ uint32_t imm32;
+ bool register_form;
+ ARM_ShifterType shift_t;
+ uint32_t shift_n;
+ uint32_t code;
- // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
- uint32_t operand2;
- if (register_form)
- {
- uint32_t Rm = ReadCoreReg (m, &success);
- if (!success)
- return false;
-
- operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
- if (!success)
- return false;
- }
- else
- {
- operand2 = imm32;
- }
-
- uint32_t Rn = ReadCoreReg (n, &success);
- if (!success)
- return false;
-
- AddWithCarryResult result;
-
- // case opcode of
- switch (code)
- {
- case 0: // when '0000'
- // result = R[n] AND operand2; // AND
- result.result = Rn & operand2;
- break;
-
- case 1: // when '0001'
- // result = R[n] EOR operand2; // EOR
- result.result = Rn ^ operand2;
- break;
-
- case 2: // when '0010'
- // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
- result = AddWithCarry (Rn, ~(operand2), 1);
- break;
-
- case 3: // when '0011'
- // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
- result = AddWithCarry (~(Rn), operand2, 1);
- break;
-
- case 4: // when '0100'
- // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
- result = AddWithCarry (Rn, operand2, 0);
- break;
-
- case 5: // when '0101'
- // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
- result = AddWithCarry (Rn, operand2, APSR_C);
- break;
-
- case 6: // when '0110'
- // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
- result = AddWithCarry (Rn, ~(operand2), APSR_C);
- break;
-
- case 7: // when '0111'
- // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
- result = AddWithCarry (~(Rn), operand2, APSR_C);
- break;
-
- case 10: // when '1100'
- // result = R[n] OR operand2; // ORR
- result.result = Rn | operand2;
- break;
-
- case 11: // when '1101'
- // result = operand2; // MOV
- result.result = operand2;
- break;
-
- case 12: // when '1110'
- // result = R[n] AND NOT(operand2); // BIC
- result.result = Rn & ~(operand2);
- break;
-
- case 15: // when '1111'
- // result = NOT(operand2); // MVN
- result.result = ~(operand2);
- break;
-
- default:
- return false;
- }
- // CPSRWriteByInstr(SPSR[], '1111', TRUE);
-
- // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
- // the best.
- uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
- if (!success)
- return false;
-
- CPSRWriteByInstr (spsr, 15, true);
-
- // BranchWritePC(result);
- EmulateInstruction::Context context;
- context.type = eContextAdjustPC;
- context.SetImmediate (result.result);
-
- BranchWritePC (context, result.result);
- }
- return true;
-}
-
-EmulateInstructionARM::ARMOpcode*
-EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
-{
- static ARMOpcode
- g_arm_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue instructions
- //----------------------------------------------------------------------
-
- // push register(s)
- { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
- { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
-
- // set r7 to point to a stack offset
- { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
- { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
- // copy the stack pointer to ip
- { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
- { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
- { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
-
- // adjust the stack pointer
- { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
- { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
-
- // push one register
- // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
- { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
-
- // vector push consecutive extension register(s)
- { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
- { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
-
- //----------------------------------------------------------------------
- // Epilogue instructions
- //----------------------------------------------------------------------
-
- { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
- { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
- { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
- { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
-
- //----------------------------------------------------------------------
- // Supervisor Call (previously Software Interrupt)
- //----------------------------------------------------------------------
- { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
- { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
- { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
- { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
- { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
- // for example, "bx lr"
- { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
- // bxj
- { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
-
- //----------------------------------------------------------------------
- // Data-processing instructions
- //----------------------------------------------------------------------
- // adc (immediate)
- { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
- // adc (register)
- { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (immediate)
- { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
- // add (register)
- { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (register-shifted register)
- { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
- // adr
- { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
- { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
- // and (immediate)
- { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
- // and (register)
- { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // bic (immediate)
- { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
- // bic (register)
- { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // eor (immediate)
- { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
- // eor (register)
- { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // orr (immediate)
- { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
- // orr (register)
- { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // rsb (immediate)
- { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
- // rsb (register)
- { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // rsc (immediate)
- { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
- // rsc (register)
- { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // sbc (immediate)
- { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
- // sbc (register)
- { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
- // sub (immediate, ARM)
- { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
- // sub (sp minus immediate)
- { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
- // sub (register)
- { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
- // teq (immediate)
- { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
- // teq (register)
- { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
- // tst (immediate)
- { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
- // tst (register)
- { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
-
- // mov (immediate)
- { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
- { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
- // mov (register)
- { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
- // mvn (immediate)
- { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
- // mvn (register)
- { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
- // cmn (immediate)
- { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
- // cmn (register)
- { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
- // cmp (immediate)
- { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
- // cmp (register)
- { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
- // asr (immediate)
- { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
- // asr (register)
- { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
- // lsl (immediate)
- { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
- // lsl (register)
- { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
- // lsr (immediate)
- { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
- // lsr (register)
- { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
- // rrx is a special case encoding of ror (immediate)
- { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
- // ror (immediate)
- { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
- // ror (register)
- { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
- // mul
- { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
-
- // subs pc, lr and related instructions
- { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
- { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
-
- //----------------------------------------------------------------------
- // Load instructions
- //----------------------------------------------------------------------
- { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
- { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
- { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
- { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
- { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
- { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
- { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
- { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
- { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
- { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
- { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
- { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
- { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
- { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
- { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
- { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
- { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
- { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
- { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Store instructions
- //----------------------------------------------------------------------
- { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
- { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
- { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
- { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
- { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
- { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
- { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
- { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
- { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
- { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
- { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
- { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
- { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Other instructions
- //----------------------------------------------------------------------
- { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
- { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
- { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
- { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
- { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
-
- };
- static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
-
- for (size_t i=0; i<k_num_arm_opcodes; ++i)
- {
- if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
- (g_arm_opcodes[i].variants & arm_isa) != 0)
- return &g_arm_opcodes[i];
- }
- return NULL;
-}
+ switch (encoding) {
+ case eEncodingT1:
+ // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
+ // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode =
+ // '0010'; // = SUB
+ n = 14;
+ imm32 = Bits32(opcode, 7, 0);
+ register_form = false;
+ code = 2;
+
+ // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (InITBlock() && !LastInITBlock())
+ return false;
-
-EmulateInstructionARM::ARMOpcode*
-EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
-{
+ break;
- static ARMOpcode
- g_thumb_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue instructions
- //----------------------------------------------------------------------
-
- // push register(s)
- { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
- { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
- { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
-
- // set r7 to point to a stack offset
- { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
- // copy the stack pointer to r7
- { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
- // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
- { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
-
- // PC-relative load into register (see also EmulateADDSPRm)
- { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
-
- // adjust the stack pointer
- { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
- { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
- { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
- { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
- { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
-
- // vector push consecutive extension register(s)
- { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
- { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
-
- //----------------------------------------------------------------------
- // Epilogue instructions
- //----------------------------------------------------------------------
-
- { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
- { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
- { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
- { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
- { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
- { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
- { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
-
- //----------------------------------------------------------------------
- // Supervisor Call (previously Software Interrupt)
- //----------------------------------------------------------------------
- { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
-
- //----------------------------------------------------------------------
- // If Then makes up to four following instructions conditional.
- //----------------------------------------------------------------------
- // The next 5 opcode _must_ come before the if then instruction
- { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
- { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
- { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
- { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
- { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
- { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
- { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
- { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
- { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
- { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
- // J1 == J2 == 1
- { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
- // J1 == J2 == 1
- { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
- { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
- // for example, "bx lr"
- { 0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
- // bxj
- { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
- // compare and branch
- { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
- // table branch byte
- { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
- // table branch halfword
- { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
-
- //----------------------------------------------------------------------
- // Data-processing instructions
- //----------------------------------------------------------------------
- // adc (immediate)
- { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
- // adc (register)
- { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (register)
- { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
- // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
- { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
- // adr
- { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
- { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
- { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
- // and (immediate)
- { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
- // and (register)
- { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // bic (immediate)
- { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
- // bic (register)
- { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // eor (immediate)
- { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
- // eor (register)
- { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // orr (immediate)
- { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
- // orr (register)
- { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // rsb (immediate)
- { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
- { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
- // rsb (register)
- { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // sbc (immediate)
- { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
- // sbc (register)
- { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
- { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
- // add (immediate, Thumb)
- { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
- { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
- { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
- { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
- // sub (immediate, Thumb)
- { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
- { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
- { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
- { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
- // sub (sp minus immediate)
- { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
- { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
- // sub (register)
- { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
- { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
- // teq (immediate)
- { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
- // teq (register)
- { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
- // tst (immediate)
- { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
- // tst (register)
- { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
- { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
-
-
- // move from high register to high register
- { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
- // move from low register to low register
- { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
- // mov{s}<c>.w <Rd>, <Rm>
- { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
- // move immediate
- { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
- { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
- { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
- // mvn (immediate)
- { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
- // mvn (register)
- { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
- { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
- // cmn (immediate)
- { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
- // cmn (register)
- { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
- { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
- // cmp (immediate)
- { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
- { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
- // cmp (register) (Rn and Rm both from r0-r7)
- { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
- // cmp (register) (Rn and Rm not both from r0-r7)
- { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
- { 0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
- // asr (immediate)
- { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
- { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
- // asr (register)
- { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // lsl (immediate)
- { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
- { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
- // lsl (register)
- { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // lsr (immediate)
- { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
- { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
- // lsr (register)
- { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // rrx is a special case encoding of ror (immediate)
- { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
- // ror (immediate)
- { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
- // ror (register)
- { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
- { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
- // mul
- { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
- // mul
- { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
-
- // subs pc, lr and related instructions
- { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
-
- //----------------------------------------------------------------------
- // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
- // otherwise the wrong instructions will be selected.
- //----------------------------------------------------------------------
-
- { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
- { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
-
- //----------------------------------------------------------------------
- // Load instructions
- //----------------------------------------------------------------------
- { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
- { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
- { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
- { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
- { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
- { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
- { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
- // Thumb2 PC-relative load into register
- { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
- { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
- { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
- { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
- { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
- { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
- { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
- { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" },
- { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
- { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" },
- { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
- { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
- { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
- { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
- { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
- { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
- { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
- { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
- { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
- { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
- { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
- { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
- { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
- { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
- { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Store instructions
- //----------------------------------------------------------------------
- { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
- { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
- { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
- { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
- { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
- { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
- { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
- { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
- { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
- { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
- { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
- { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
- { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
- { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
- { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
- { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
- { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
- { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
- { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
- { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
- { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
- { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
-
- //----------------------------------------------------------------------
- // Other instructions
- //----------------------------------------------------------------------
- { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
- { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
- { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
- { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
- { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
- };
-
- const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
- for (size_t i=0; i<k_num_thumb_opcodes; ++i)
- {
- if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
- (g_thumb_opcodes[i].variants & arm_isa) != 0)
- return &g_thumb_opcodes[i];
- }
- return NULL;
-}
+ case eEncodingA1:
+ // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
+ n = Bits32(opcode, 19, 16);
+ imm32 = ARMExpandImm(opcode);
+ register_form = false;
+ code = Bits32(opcode, 24, 21);
-bool
-EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
-{
- m_arch = arch;
- m_arm_isa = 0;
- const char *arch_cstr = arch.GetArchitectureName ();
- if (arch_cstr)
- {
- if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T;
- else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ;
- else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE;
- else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T;
- else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K;
- else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2;
- else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S;
- else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll;
- else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll;
- else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4;
- else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6;
- else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7;
- else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8;
- }
- return m_arm_isa != 0;
-}
-
-bool
-EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
-{
- if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
- {
- if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || m_arch.IsAlwaysThumbInstructions ())
- m_opcode_mode = eModeThumb;
- else
- {
- AddressClass addr_class = inst_addr.GetAddressClass();
+ break;
- if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
- m_opcode_mode = eModeARM;
- else if (addr_class == eAddressClassCodeAlternateISA)
- m_opcode_mode = eModeThumb;
- else
- return false;
- }
- if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions ())
- m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
- else
- m_opcode_cpsr = CPSR_MODE_USR;
- return true;
+ case eEncodingA2:
+ // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
+ n = Bits32(opcode, 19, 16);
+ m = Bits32(opcode, 3, 0);
+ register_form = true;
+
+ // (shift_t, shift_n) = DecodeImmShift(type, imm5);
+ shift_n = DecodeImmShiftARM(opcode, shift_t);
+
+ break;
+
+ default:
+ return false;
}
- return false;
-}
-bool
-EmulateInstructionARM::ReadInstruction ()
-{
- bool success = false;
- m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
- if (success)
- {
- addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
-
- if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions ())
- {
- m_opcode_mode = eModeThumb;
- uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
-
- if (success)
- {
- if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
- {
- m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
- }
- else
- {
- m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
- }
- }
- }
- else
- {
- m_opcode_mode = eModeARM;
- m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
- }
+ // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C)
+ // else imm32;
+ uint32_t operand2;
+ if (register_form) {
+ uint32_t Rm = ReadCoreReg(m, &success);
+ if (!success)
+ return false;
- if (!m_ignore_conditions)
- {
- // If we are not ignoreing the conditions then init the it session from the current
- // value of cpsr.
- uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | Bits32(m_opcode_cpsr, 26, 25);
- if (it != 0)
- m_it_session.InitIT(it);
- }
- }
+ operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success);
+ if (!success)
+ return false;
+ } else {
+ operand2 = imm32;
}
+
+ uint32_t Rn = ReadCoreReg(n, &success);
if (!success)
- {
- m_opcode_mode = eModeInvalid;
- m_addr = LLDB_INVALID_ADDRESS;
+ return false;
+
+ AddWithCarryResult result;
+
+ // case opcode of
+ switch (code) {
+ case 0: // when '0000'
+ // result = R[n] AND operand2; // AND
+ result.result = Rn & operand2;
+ break;
+
+ case 1: // when '0001'
+ // result = R[n] EOR operand2; // EOR
+ result.result = Rn ^ operand2;
+ break;
+
+ case 2: // when '0010'
+ // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
+ result = AddWithCarry(Rn, ~(operand2), 1);
+ break;
+
+ case 3: // when '0011'
+ // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
+ result = AddWithCarry(~(Rn), operand2, 1);
+ break;
+
+ case 4: // when '0100'
+ // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
+ result = AddWithCarry(Rn, operand2, 0);
+ break;
+
+ case 5: // when '0101'
+ // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
+ result = AddWithCarry(Rn, operand2, APSR_C);
+ break;
+
+ case 6: // when '0110'
+ // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
+ result = AddWithCarry(Rn, ~(operand2), APSR_C);
+ break;
+
+ case 7: // when '0111'
+ // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
+ result = AddWithCarry(~(Rn), operand2, APSR_C);
+ break;
+
+ case 10: // when '1100'
+ // result = R[n] OR operand2; // ORR
+ result.result = Rn | operand2;
+ break;
+
+ case 11: // when '1101'
+ // result = operand2; // MOV
+ result.result = operand2;
+ break;
+
+ case 12: // when '1110'
+ // result = R[n] AND NOT(operand2); // BIC
+ result.result = Rn & ~(operand2);
+ break;
+
+ case 15: // when '1111'
+ // result = NOT(operand2); // MVN
+ result.result = ~(operand2);
+ break;
+
+ default:
+ return false;
}
- return success;
-}
+ // CPSRWriteByInstr(SPSR[], '1111', TRUE);
-uint32_t
-EmulateInstructionARM::ArchVersion ()
-{
- return m_arm_isa;
-}
+ // For now, in emulation mode, we don't have access to the SPSR, so we will
+ // use the CPSR instead, and hope for
+ // the best.
+ uint32_t spsr =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
+ if (!success)
+ return false;
-bool
-EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
-{
- // If we are ignoring conditions, then always return true.
- // this allows us to iterate over disassembly code and still
- // emulate an instruction even if we don't have all the right
- // bits set in the CPSR register...
- if (m_ignore_conditions)
- return true;
+ CPSRWriteByInstr(spsr, 15, true);
- const uint32_t cond = CurrentCond (opcode);
- if (cond == UINT32_MAX)
+ // BranchWritePC(result);
+ EmulateInstruction::Context context;
+ context.type = eContextAdjustPC;
+ context.SetImmediate(result.result);
+
+ BranchWritePC(context, result.result);
+ }
+ return true;
+}
+
+EmulateInstructionARM::ARMOpcode *
+EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode,
+ uint32_t arm_isa) {
+ static ARMOpcode g_arm_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue instructions
+ //----------------------------------------------------------------------
+
+ // push register(s)
+ {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
+ {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push <register>"},
+
+ // set r7 to point to a stack offset
+ {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"},
+ {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
+ // copy the stack pointer to ip
+ {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"},
+ {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"},
+ {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
+
+ // adjust the stack pointer
+ {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
+ {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPReg,
+ "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
+
+ // push one register
+ // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
+ {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"},
+
+ // vector push consecutive extension register(s)
+ {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
+ {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Epilogue instructions
+ //----------------------------------------------------------------------
+
+ {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
+ {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop <register>"},
+ {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
+ {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Supervisor Call (previously Software Interrupt)
+ //----------------------------------------------------------------------
+ {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ // To resolve ambiguity, "blx <label>" should come before "b #imm24" and
+ // "bl <label>".
+ {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
+ {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateB, "b #imm24"},
+ {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
+ {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
+ // for example, "bx lr"
+ {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
+ // bxj
+ {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Data-processing instructions
+ //----------------------------------------------------------------------
+ // adc (immediate)
+ {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
+ // adc (register)
+ {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCReg,
+ "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (immediate)
+ {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDImmARM,
+ "add{s}<c> <Rd>, <Rn>, #const"},
+ // add (register)
+ {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDReg,
+ "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (register-shifted register)
+ {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDRegShift,
+ "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
+ // adr
+ {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
+ {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
+ // and (immediate)
+ {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
+ // and (register)
+ {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDReg,
+ "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // bic (immediate)
+ {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
+ // bic (register)
+ {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICReg,
+ "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // eor (immediate)
+ {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
+ // eor (register)
+ {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORReg,
+ "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // orr (immediate)
+ {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
+ // orr (register)
+ {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRReg,
+ "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // rsb (immediate)
+ {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
+ // rsb (register)
+ {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBReg,
+ "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // rsc (immediate)
+ {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
+ // rsc (register)
+ {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSCReg,
+ "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // sbc (immediate)
+ {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
+ // sbc (register)
+ {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCReg,
+ "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // sub (immediate, ARM)
+ {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBImmARM,
+ "sub{s}<c> <Rd>, <Rn>, #<const>"},
+ // sub (sp minus immediate)
+ {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
+ // sub (register)
+ {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBReg,
+ "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
+ // teq (immediate)
+ {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
+ // teq (register)
+ {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
+ // tst (immediate)
+ {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
+ // tst (register)
+ {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
+
+ // mov (immediate)
+ {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
+ {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"},
+ // mov (register)
+ {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
+ // mvn (immediate)
+ {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
+ // mvn (register)
+ {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNReg,
+ "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
+ // cmn (immediate)
+ {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
+ // cmn (register)
+ {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
+ // cmp (immediate)
+ {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
+ // cmp (register)
+ {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
+ // asr (immediate)
+ {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
+ // asr (register)
+ {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
+ // lsl (immediate)
+ {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
+ // lsl (register)
+ {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
+ // lsr (immediate)
+ {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
+ // lsr (register)
+ {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
+ // rrx is a special case encoding of ror (immediate)
+ {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
+ // ror (immediate)
+ {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
+ // ror (register)
+ {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
+ // mul
+ {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"},
+
+ // subs pc, lr and related instructions
+ {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPcLrEtc,
+ "<opc>S<c> PC,#<const> | <Rn>,#<const>"},
+ {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPcLrEtc,
+ "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"},
+
+ //----------------------------------------------------------------------
+ // Load instructions
+ //----------------------------------------------------------------------
+ {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"},
+ {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRImmediateARM,
+ "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"},
+ {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRegister,
+ "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"},
+ {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
+ {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBRegister,
+ "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"},
+ {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
+ {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHRegister,
+ "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
+ {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBImmediate,
+ "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"},
+ {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"},
+ {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBRegister,
+ "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
+ {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHImmediate,
+ "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
+ {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
+ {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHRegister,
+ "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"},
+ {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRDImmediate,
+ "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
+ {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRDRegister,
+ "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
+ {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
+ {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Multiple,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Single,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1SingleAll,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Store instructions
+ //----------------------------------------------------------------------
+ {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
+ {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"},
+ {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRRegister,
+ "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"},
+ {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRHRegister,
+ "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"},
+ {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
+ {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRBImmARM,
+ "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
+ {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRImmARM,
+ "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
+ {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRDImm,
+ "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
+ {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRDReg,
+ "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
+ {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
+ {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
+ {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
+ {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Multiple,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Single,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Other instructions
+ //----------------------------------------------------------------------
+ {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"},
+ {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"},
+ {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"},
+ {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"},
+ {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"}
+
+ };
+ static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
+
+ for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
+ if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
+ (g_arm_opcodes[i].variants & arm_isa) != 0)
+ return &g_arm_opcodes[i];
+ }
+ return NULL;
+}
+
+EmulateInstructionARM::ARMOpcode *
+EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode,
+ uint32_t arm_isa) {
+
+ static ARMOpcode g_thumb_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue instructions
+ //----------------------------------------------------------------------
+
+ // push register(s)
+ {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulatePUSH, "push <registers>"},
+ {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"},
+ {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePUSH, "push.w <register>"},
+
+ // set r7 to point to a stack offset
+ {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"},
+ // copy the stack pointer to r7
+ {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"},
+ // move from high register to low register (comes after "mov r7, sp" to
+ // resolve ambiguity)
+ {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"},
+
+ // PC-relative load into register (see also EmulateADDSPRm)
+ {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
+
+ // adjust the stack pointer
+ {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
+ {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
+ {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
+ {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
+ {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPReg,
+ "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"},
+
+ // vector push consecutive extension register(s)
+ {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
+ {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Epilogue instructions
+ //----------------------------------------------------------------------
+
+ {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
+ {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
+ {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
+ {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"},
+ {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulatePOP, "pop.w <register>"},
+ {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
+ {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
+
+ //----------------------------------------------------------------------
+ // Supervisor Call (previously Software Interrupt)
+ //----------------------------------------------------------------------
+ {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
+
+ //----------------------------------------------------------------------
+ // If Then makes up to four following instructions conditional.
+ //----------------------------------------------------------------------
+ // The next 5 opcode _must_ come before the if then instruction
+ {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop"},
+ {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
+ {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
+ {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
+ {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
+ {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
+ {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
+ {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
+ {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
+ {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateB,
+ "b<c>.w #imm8 (outside or last in IT)"},
+ // J1 == J2 == 1
+ {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
+ // J1 == J2 == 1
+ {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
+ {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
+ // for example, "bx lr"
+ {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
+ // bxj
+ {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
+ // compare and branch
+ {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
+ // table branch byte
+ {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
+ // table branch halfword
+ {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
+
+ //----------------------------------------------------------------------
+ // Data-processing instructions
+ //----------------------------------------------------------------------
+ // adc (immediate)
+ {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
+ // adc (register)
+ {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADCReg,
+ "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (register)
+ {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
+ // Make sure "add sp, <Rm>" comes before this instruction, so there's no
+ // ambiguity decoding the two.
+ {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
+ // adr
+ {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
+ {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
+ {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
+ // and (immediate)
+ {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
+ // and (register)
+ {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateANDReg,
+ "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // bic (immediate)
+ {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
+ // bic (register)
+ {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateBICReg,
+ "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // eor (immediate)
+ {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
+ // eor (register)
+ {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateEORReg,
+ "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // orr (immediate)
+ {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
+ // orr (register)
+ {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateORRReg,
+ "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // rsb (immediate)
+ {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
+ {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBImm,
+ "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
+ // rsb (register)
+ {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRSBReg,
+ "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // sbc (immediate)
+ {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
+ // sbc (register)
+ {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
+ {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSBCReg,
+ "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
+ // add (immediate, Thumb)
+ {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDImmThumb,
+ "adds|add<c> <Rd>,<Rn>,#<imm3>"},
+ {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"},
+ {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDImmThumb,
+ "add{s}<c>.w <Rd>,<Rn>,#<const>"},
+ {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateADDImmThumb,
+ "addw<c> <Rd>,<Rn>,#<imm12>"},
+ // sub (immediate, Thumb)
+ {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBImmThumb,
+ "subs|sub<c> <Rd>, <Rn> #imm3"},
+ {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
+ {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBImmThumb,
+ "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
+ {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBImmThumb,
+ "subw<c> <Rd>, <Rn>, #imm12"},
+ // sub (sp minus immediate)
+ {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
+ {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
+ // sub (register)
+ {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
+ {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBReg,
+ "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
+ // teq (immediate)
+ {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
+ // teq (register)
+ {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
+ // tst (immediate)
+ {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
+ // tst (register)
+ {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
+ {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
+
+ // move from high register to high register
+ {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
+ // move from low register to low register
+ {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
+ // mov{s}<c>.w <Rd>, <Rm>
+ {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
+ // move immediate
+ {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
+ {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
+ {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
+ // mvn (immediate)
+ {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
+ // mvn (register)
+ {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
+ {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMVNReg,
+ "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
+ // cmn (immediate)
+ {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
+ // cmn (register)
+ {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
+ {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
+ // cmp (immediate)
+ {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
+ {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
+ // cmp (register) (Rn and Rm both from r0-r7)
+ {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
+ // cmp (register) (Rn and Rm not both from r0-r7)
+ {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
+ {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateCMPReg,
+ "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
+ // asr (immediate)
+ {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
+ {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
+ // asr (register)
+ {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // lsl (immediate)
+ {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
+ {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
+ // lsl (register)
+ {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // lsr (immediate)
+ {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
+ {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
+ // lsr (register)
+ {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // rrx is a special case encoding of ror (immediate)
+ {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
+ // ror (immediate)
+ {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
+ // ror (register)
+ {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
+ {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
+ // mul
+ {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"},
+ // mul
+ {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"},
+
+ // subs pc, lr and related instructions
+ {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"},
+
+ //----------------------------------------------------------------------
+ // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE
+ // LDM.. Instructions in this table;
+ // otherwise the wrong instructions will be selected.
+ //----------------------------------------------------------------------
+
+ {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"},
+ {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"},
+
+ //----------------------------------------------------------------------
+ // Load instructions
+ //----------------------------------------------------------------------
+ {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"},
+ {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"},
+ {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"},
+ {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
+ {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
+ {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRtRnImm,
+ "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
+ {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRtRnImm,
+ "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
+ // Thumb2 PC-relative load into register
+ {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRtPCRelative,
+ "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
+ {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"},
+ {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRRegister,
+ "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRBImmediate,
+ "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"},
+ {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBImmediate,
+ "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
+ {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBImmediate,
+ "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"},
+ {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"},
+ {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRBRegister,
+ "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
+ {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRHImmediate,
+ "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"},
+ {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHImmediate,
+ "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"},
+ {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHImmediate,
+ "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"},
+ {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"},
+ {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRHRegister,
+ "ldrh<c> <Rt>, [<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRHRegister,
+ "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBImmediate,
+ "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"},
+ {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBImmediate,
+ "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"},
+ {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"},
+ {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRSBRegister,
+ "ldrsb<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSBRegister,
+ "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"},
+ {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHImmediate,
+ "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"},
+ {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHImmediate,
+ "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"},
+ {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"},
+ {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateLDRSHRegister,
+ "ldrsh<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRSHRegister,
+ "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateLDRDImmediate,
+ "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
+ {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
+ {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
+ {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Multiple,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
+ {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1Single,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
+ {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVLD1SingleAll,
+ "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Store instructions
+ //----------------------------------------------------------------------
+ {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"},
+ {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"},
+ {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"},
+ {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"},
+ {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"},
+ {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRThumb,
+ "str<c>.w <Rt>, [<Rn>,#<imm12>]"},
+ {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRThumb,
+ "str<c> <Rt>, [<Rn>,#+/-<imm8>]"},
+ {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"},
+ {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRRegister,
+ "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"},
+ {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRBThumb,
+ "strb<c> <Rt>, [<Rn>, #<imm5>]"},
+ {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRBThumb,
+ "strb<c>.w <Rt>, [<Rn>, #<imm12>]"},
+ {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRBThumb,
+ "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"},
+ {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"},
+ {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRHRegister,
+ "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"},
+ {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTREX,
+ "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"},
+ {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSTRDImm,
+ "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
+ {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
+ {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
+ {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
+ {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32,
+ &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
+ {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Multiple,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+ {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32,
+ &EmulateInstructionARM::EmulateVST1Single,
+ "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+
+ //----------------------------------------------------------------------
+ // Other instructions
+ //----------------------------------------------------------------------
+ {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
+ {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"},
+ {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"},
+ {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16,
+ &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"},
+ {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32,
+ &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"},
+ };
+
+ const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
+ for (size_t i = 0; i < k_num_thumb_opcodes; ++i) {
+ if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
+ (g_thumb_opcodes[i].variants & arm_isa) != 0)
+ return &g_thumb_opcodes[i];
+ }
+ return NULL;
+}
+
+bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) {
+ m_arch = arch;
+ m_arm_isa = 0;
+ const char *arch_cstr = arch.GetArchitectureName();
+ if (arch_cstr) {
+ if (0 == ::strcasecmp(arch_cstr, "armv4t"))
+ m_arm_isa = ARMv4T;
+ else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))
+ m_arm_isa = ARMv5TEJ;
+ else if (0 == ::strcasecmp(arch_cstr, "armv5te"))
+ m_arm_isa = ARMv5TE;
+ else if (0 == ::strcasecmp(arch_cstr, "armv5t"))
+ m_arm_isa = ARMv5T;
+ else if (0 == ::strcasecmp(arch_cstr, "armv6k"))
+ m_arm_isa = ARMv6K;
+ else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))
+ m_arm_isa = ARMv6T2;
+ else if (0 == ::strcasecmp(arch_cstr, "armv7s"))
+ m_arm_isa = ARMv7S;
+ else if (0 == ::strcasecmp(arch_cstr, "arm"))
+ m_arm_isa = ARMvAll;
+ else if (0 == ::strcasecmp(arch_cstr, "thumb"))
+ m_arm_isa = ARMvAll;
+ else if (0 == ::strncasecmp(arch_cstr, "armv4", 5))
+ m_arm_isa = ARMv4;
+ else if (0 == ::strncasecmp(arch_cstr, "armv6", 5))
+ m_arm_isa = ARMv6;
+ else if (0 == ::strncasecmp(arch_cstr, "armv7", 5))
+ m_arm_isa = ARMv7;
+ else if (0 == ::strncasecmp(arch_cstr, "armv8", 5))
+ m_arm_isa = ARMv8;
+ }
+ return m_arm_isa != 0;
+}
+
+bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode,
+ const Address &inst_addr,
+ Target *target) {
+ if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
+ if (m_arch.GetTriple().getArch() == llvm::Triple::thumb ||
+ m_arch.IsAlwaysThumbInstructions())
+ m_opcode_mode = eModeThumb;
+ else {
+ AddressClass addr_class = inst_addr.GetAddressClass();
+
+ if ((addr_class == eAddressClassCode) ||
+ (addr_class == eAddressClassUnknown))
+ m_opcode_mode = eModeARM;
+ else if (addr_class == eAddressClassCodeAlternateISA)
+ m_opcode_mode = eModeThumb;
+ else
return false;
-
- bool result = false;
- switch (UnsignedBits(cond, 3, 1))
- {
- case 0:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
- break;
- case 1:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
- break;
- case 2:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
- break;
- case 3:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
- break;
- case 4:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
- break;
- case 5:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- {
- bool n = (m_opcode_cpsr & MASK_CPSR_N);
- bool v = (m_opcode_cpsr & MASK_CPSR_V);
- result = n == v;
- }
- break;
- case 6:
- if (m_opcode_cpsr == 0)
- result = true;
- else
- {
- bool n = (m_opcode_cpsr & MASK_CPSR_N);
- bool v = (m_opcode_cpsr & MASK_CPSR_V);
- result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
- }
- break;
- case 7:
- // Always execute (cond == 0b1110, or the special 0b1111 which gives
- // opcodes different meanings, but always means execution happens.
- return true;
}
+ if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions())
+ m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
+ else
+ m_opcode_cpsr = CPSR_MODE_USR;
+ return true;
+ }
+ return false;
+}
+
+bool EmulateInstructionARM::ReadInstruction() {
+ bool success = false;
+ m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
+ if (success) {
+ addr_t pc =
+ ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+
+ if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) {
+ m_opcode_mode = eModeThumb;
+ uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
+
+ if (success) {
+ if ((thumb_opcode & 0xe000) != 0xe000 ||
+ ((thumb_opcode & 0x1800u) == 0)) {
+ m_opcode.SetOpcode16(thumb_opcode, GetByteOrder());
+ } else {
+ m_opcode.SetOpcode32(
+ (thumb_opcode << 16) |
+ MemARead(read_inst_context, pc + 2, 2, 0, &success),
+ GetByteOrder());
+ }
+ }
+ } else {
+ m_opcode_mode = eModeARM;
+ m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success),
+ GetByteOrder());
+ }
+
+ if (!m_ignore_conditions) {
+ // If we are not ignoreing the conditions then init the it session from
+ // the current
+ // value of cpsr.
+ uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) |
+ Bits32(m_opcode_cpsr, 26, 25);
+ if (it != 0)
+ m_it_session.InitIT(it);
+ }
+ }
+ }
+ if (!success) {
+ m_opcode_mode = eModeInvalid;
+ m_addr = LLDB_INVALID_ADDRESS;
+ }
+ return success;
+}
+
+uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; }
+
+bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) {
+ // If we are ignoring conditions, then always return true.
+ // this allows us to iterate over disassembly code and still
+ // emulate an instruction even if we don't have all the right
+ // bits set in the CPSR register...
+ if (m_ignore_conditions)
+ return true;
+
+ const uint32_t cond = CurrentCond(opcode);
+ if (cond == UINT32_MAX)
+ return false;
- if (cond & 1)
- result = !result;
- return result;
+ bool result = false;
+ switch (UnsignedBits(cond, 3, 1)) {
+ case 0:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
+ break;
+ case 1:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
+ break;
+ case 2:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
+ break;
+ case 3:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
+ break;
+ case 4:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) &&
+ ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
+ break;
+ case 5:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else {
+ bool n = (m_opcode_cpsr & MASK_CPSR_N);
+ bool v = (m_opcode_cpsr & MASK_CPSR_V);
+ result = n == v;
+ }
+ break;
+ case 6:
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else {
+ bool n = (m_opcode_cpsr & MASK_CPSR_N);
+ bool v = (m_opcode_cpsr & MASK_CPSR_V);
+ result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
+ }
+ break;
+ case 7:
+ // Always execute (cond == 0b1110, or the special 0b1111 which gives
+ // opcodes different meanings, but always means execution happens.
+ return true;
+ }
+
+ if (cond & 1)
+ result = !result;
+ return result;
}
-uint32_t
-EmulateInstructionARM::CurrentCond (const uint32_t opcode)
-{
- switch (m_opcode_mode)
+uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) {
+ switch (m_opcode_mode) {
+ case eModeInvalid:
+ break;
+
+ case eModeARM:
+ return UnsignedBits(opcode, 31, 28);
+
+ case eModeThumb:
+ // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
+ // 'cond' field of the encoding.
{
- case eModeInvalid:
+ const uint32_t byte_size = m_opcode.GetByteSize();
+ if (byte_size == 2) {
+ if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
+ return Bits32(opcode, 11, 8);
+ } else if (byte_size == 4) {
+ if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 &&
+ Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) {
+ return Bits32(opcode, 25, 22);
+ }
+ } else
+ // We have an invalid thumb instruction, let's bail out.
break;
- case eModeARM:
- return UnsignedBits(opcode, 31, 28);
-
- case eModeThumb:
- // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
- // 'cond' field of the encoding.
- {
- const uint32_t byte_size = m_opcode.GetByteSize();
- if (byte_size == 2)
- {
- if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
- return Bits32(opcode, 11, 8);
- }
- else if (byte_size == 4)
- {
- if (Bits32(opcode, 31, 27) == 0x1e &&
- Bits32(opcode, 15, 14) == 0x02 &&
- Bits32(opcode, 12, 12) == 0x00 &&
- Bits32(opcode, 25, 22) <= 0x0d)
- {
- return Bits32(opcode, 25, 22);
- }
- }
- else
- // We have an invalid thumb instruction, let's bail out.
- break;
-
- return m_it_session.GetCond();
- }
+ return m_it_session.GetCond();
}
- return UINT32_MAX; // Return invalid value
+ }
+ return UINT32_MAX; // Return invalid value
}
-bool
-EmulateInstructionARM::InITBlock()
-{
- return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
+bool EmulateInstructionARM::InITBlock() {
+ return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
}
-bool
-EmulateInstructionARM::LastInITBlock()
-{
- return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
+bool EmulateInstructionARM::LastInITBlock() {
+ return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
}
-bool
-EmulateInstructionARM::BadMode (uint32_t mode)
-{
-
- switch (mode)
- {
- case 16: return false; // '10000'
- case 17: return false; // '10001'
- case 18: return false; // '10010'
- case 19: return false; // '10011'
- case 22: return false; // '10110'
- case 23: return false; // '10111'
- case 27: return false; // '11011'
- case 31: return false; // '11111'
- default: return true;
- }
- return true;
-}
-
-bool
-EmulateInstructionARM::CurrentModeIsPrivileged ()
-{
- uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
-
- if (BadMode (mode))
- return false;
-
- if (mode == 16)
- return false;
-
+bool EmulateInstructionARM::BadMode(uint32_t mode) {
+
+ switch (mode) {
+ case 16:
+ return false; // '10000'
+ case 17:
+ return false; // '10001'
+ case 18:
+ return false; // '10010'
+ case 19:
+ return false; // '10011'
+ case 22:
+ return false; // '10110'
+ case 23:
+ return false; // '10111'
+ case 27:
+ return false; // '11011'
+ case 31:
+ return false; // '11111'
+ default:
return true;
+ }
+ return true;
}
-void
-EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
-{
- bool privileged = CurrentModeIsPrivileged();
+bool EmulateInstructionARM::CurrentModeIsPrivileged() {
+ uint32_t mode = Bits32(m_opcode_cpsr, 4, 0);
- uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
-
- if (BitIsSet (bytemask, 3))
- {
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
- if (affect_execstate)
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
- }
-
- if (BitIsSet (bytemask, 2))
- {
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
- }
-
- if (BitIsSet (bytemask, 1))
- {
- if (affect_execstate)
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
- tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
- if (privileged)
- tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
- }
-
- if (BitIsSet (bytemask, 0))
- {
- if (privileged)
- tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
- if (affect_execstate)
- tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
- if (privileged)
- tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
- }
-
- m_opcode_cpsr = tmp_cpsr;
+ if (BadMode(mode))
+ return false;
+
+ if (mode == 16)
+ return false;
+
+ return true;
}
-
-bool
-EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
-{
- addr_t target;
+void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
+ bool affect_execstate) {
+ bool privileged = CurrentModeIsPrivileged();
- // Check the current instruction set.
- if (CurrentInstrSet() == eModeARM)
- target = addr & 0xfffffffc;
- else
- target = addr & 0xfffffffe;
+ uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20;
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
- return false;
+ if (BitIsSet(bytemask, 3)) {
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27);
+ if (affect_execstate)
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24);
+ }
- return true;
+ if (BitIsSet(bytemask, 2)) {
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16);
+ }
+
+ if (BitIsSet(bytemask, 1)) {
+ if (affect_execstate)
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10);
+ tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9);
+ if (privileged)
+ tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8);
+ }
+
+ if (BitIsSet(bytemask, 0)) {
+ if (privileged)
+ tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6);
+ if (affect_execstate)
+ tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5);
+ if (privileged)
+ tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0);
+ }
+
+ m_opcode_cpsr = tmp_cpsr;
}
-// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
-bool
-EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
-{
- addr_t target;
- // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
- // we want to record it and issue a WriteRegister callback so the clients
- // can track the mode changes accordingly.
- bool cpsr_changed = false;
+bool EmulateInstructionARM::BranchWritePC(const Context &context,
+ uint32_t addr) {
+ addr_t target;
- if (BitIsSet(addr, 0))
- {
- if (CurrentInstrSet() != eModeThumb)
- {
- SelectInstrSet(eModeThumb);
- cpsr_changed = true;
- }
- target = addr & 0xfffffffe;
- context.SetISA (eModeThumb);
- }
- else if (BitIsClear(addr, 1))
- {
- if (CurrentInstrSet() != eModeARM)
- {
- SelectInstrSet(eModeARM);
- cpsr_changed = true;
- }
- target = addr & 0xfffffffc;
- context.SetISA (eModeARM);
- }
- else
- return false; // address<1:0> == '10' => UNPREDICTABLE
+ // Check the current instruction set.
+ if (CurrentInstrSet() == eModeARM)
+ target = addr & 0xfffffffc;
+ else
+ target = addr & 0xfffffffe;
- if (cpsr_changed)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
- return false;
- }
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, target))
+ return false;
- return true;
+ return true;
+}
+
+// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
+// inspecting addr.
+bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
+ addr_t target;
+ // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
+ // we want to record it and issue a WriteRegister callback so the clients
+ // can track the mode changes accordingly.
+ bool cpsr_changed = false;
+
+ if (BitIsSet(addr, 0)) {
+ if (CurrentInstrSet() != eModeThumb) {
+ SelectInstrSet(eModeThumb);
+ cpsr_changed = true;
+ }
+ target = addr & 0xfffffffe;
+ context.SetISA(eModeThumb);
+ } else if (BitIsClear(addr, 1)) {
+ if (CurrentInstrSet() != eModeARM) {
+ SelectInstrSet(eModeARM);
+ cpsr_changed = true;
+ }
+ target = addr & 0xfffffffc;
+ context.SetISA(eModeARM);
+ } else
+ return false; // address<1:0> == '10' => UNPREDICTABLE
+
+ if (cpsr_changed) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
+ return false;
+ }
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, target))
+ return false;
+
+ return true;
}
-// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
-bool
-EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
-{
- if (ArchVersion() >= ARMv5T)
- return BXWritePC(context, addr);
- else
- return BranchWritePC((const Context)context, addr);
+// Dispatches to either BXWritePC or BranchWritePC based on architecture
+// versions.
+bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) {
+ if (ArchVersion() >= ARMv5T)
+ return BXWritePC(context, addr);
+ else
+ return BranchWritePC((const Context)context, addr);
}
-// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
-bool
-EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
-{
- if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
- return BXWritePC(context, addr);
- else
- return BranchWritePC((const Context)context, addr);
+// Dispatches to either BXWritePC or BranchWritePC based on architecture
+// versions and current instruction set.
+bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) {
+ if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
+ return BXWritePC(context, addr);
+ else
+ return BranchWritePC((const Context)context, addr);
}
-EmulateInstructionARM::Mode
-EmulateInstructionARM::CurrentInstrSet ()
-{
- return m_opcode_mode;
+EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() {
+ return m_opcode_mode;
}
// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next
// ReadInstruction() is performed. This function has a side effect of updating
// the m_new_inst_cpsr member variable if necessary.
-bool
-EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
-{
- m_new_inst_cpsr = m_opcode_cpsr;
- switch (arm_or_thumb)
- {
- default:
- return false;
- case eModeARM:
- // Clear the T bit.
- m_new_inst_cpsr &= ~MASK_CPSR_T;
- break;
- case eModeThumb:
- // Set the T bit.
- m_new_inst_cpsr |= MASK_CPSR_T;
- break;
- }
- return true;
+bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) {
+ m_new_inst_cpsr = m_opcode_cpsr;
+ switch (arm_or_thumb) {
+ default:
+ return false;
+ case eModeARM:
+ // Clear the T bit.
+ m_new_inst_cpsr &= ~MASK_CPSR_T;
+ break;
+ case eModeThumb:
+ // Set the T bit.
+ m_new_inst_cpsr |= MASK_CPSR_T;
+ break;
+ }
+ return true;
}
// This function returns TRUE if the processor currently provides support for
// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
-bool
-EmulateInstructionARM::UnalignedSupport()
-{
- return (ArchVersion() >= ARMv7);
+bool EmulateInstructionARM::UnalignedSupport() {
+ return (ArchVersion() >= ARMv7);
}
// The main addition and subtraction instructions can produce status information
// about both unsigned carry and signed overflow conditions. This status
// information can be used to synthesize multi-word additions and subtractions.
EmulateInstructionARM::AddWithCarryResult
-EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
-{
- uint32_t result;
- uint8_t carry_out;
- uint8_t overflow;
-
- uint64_t unsigned_sum = x + y + carry_in;
- int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
-
- result = UnsignedBits(unsigned_sum, 31, 0);
-// carry_out = (result == unsigned_sum ? 0 : 1);
- overflow = ((int32_t)result == signed_sum ? 0 : 1);
-
- if (carry_in)
- carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
+EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) {
+ uint32_t result;
+ uint8_t carry_out;
+ uint8_t overflow;
+
+ uint64_t unsigned_sum = x + y + carry_in;
+ int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
+
+ result = UnsignedBits(unsigned_sum, 31, 0);
+ // carry_out = (result == unsigned_sum ? 0 : 1);
+ overflow = ((int32_t)result == signed_sum ? 0 : 1);
+
+ if (carry_in)
+ carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0;
+ else
+ carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0;
+
+ AddWithCarryResult res = {result, carry_out, overflow};
+ return res;
+}
+
+uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ switch (num) {
+ case SP_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case LR_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_RA;
+ break;
+ case PC_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ default:
+ if (num < SP_REG) {
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r0 + num;
+ } else {
+ // assert(0 && "Invalid register number");
+ *success = false;
+ return UINT32_MAX;
+ }
+ break;
+ }
+
+ // Read our register.
+ uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success);
+
+ // When executing an ARM instruction , PC reads as the address of the current
+ // instruction plus 8.
+ // When executing a Thumb instruction , PC reads as the address of the current
+ // instruction plus 4.
+ if (num == 15) {
+ if (CurrentInstrSet() == eModeARM)
+ val += 8;
else
- carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
-
- AddWithCarryResult res = { result, carry_out, overflow };
- return res;
-}
+ val += 4;
+ }
-uint32_t
-EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
-{
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- switch (num)
- {
- case SP_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_SP;
- break;
- case LR_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_RA;
- break;
- case PC_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_PC;
- break;
- default:
- if (num < SP_REG)
- {
- reg_kind = eRegisterKindDWARF;
- reg_num = dwarf_r0 + num;
- }
- else
- {
- //assert(0 && "Invalid register number");
- *success = false;
- return UINT32_MAX;
- }
- break;
- }
-
- // Read our register.
- uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
-
- // When executing an ARM instruction , PC reads as the address of the current
- // instruction plus 8.
- // When executing a Thumb instruction , PC reads as the address of the current
- // instruction plus 4.
- if (num == 15)
- {
- if (CurrentInstrSet() == eModeARM)
- val += 8;
- else
- val += 4;
- }
-
- return val;
+ return val;
}
// Write the result to the ARM core register Rd, and optionally update the
@@ -13508,43 +13838,34 @@ EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
//
// In the above case, the API client does not pass in the overflow arg, which
// defaults to ~0u.
-bool
-EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
- const uint32_t result,
- const uint32_t Rd,
- bool setflags,
- const uint32_t carry,
- const uint32_t overflow)
-{
- if (Rd == 15)
- {
- if (!ALUWritePC (context, result))
- return false;
- }
- else
- {
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- switch (Rd)
- {
- case SP_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_SP;
- break;
- case LR_REG:
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_RA;
- break;
- default:
- reg_kind = eRegisterKindDWARF;
- reg_num = dwarf_r0 + Rd;
- }
- if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
- return false;
- if (setflags)
- return WriteFlags (context, result, carry, overflow);
+bool EmulateInstructionARM::WriteCoreRegOptionalFlags(
+ Context &context, const uint32_t result, const uint32_t Rd, bool setflags,
+ const uint32_t carry, const uint32_t overflow) {
+ if (Rd == 15) {
+ if (!ALUWritePC(context, result))
+ return false;
+ } else {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ switch (Rd) {
+ case SP_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case LR_REG:
+ reg_kind = eRegisterKindGeneric;
+ reg_num = LLDB_REGNUM_GENERIC_RA;
+ break;
+ default:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r0 + Rd;
}
- return true;
+ if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result))
+ return false;
+ if (setflags)
+ return WriteFlags(context, result, carry, overflow);
+ }
+ return true;
}
// This helper method tries to encapsulate the following pseudocode from the
@@ -13555,203 +13876,192 @@ EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
// APSR.C = carry;
// APSR.V = overflow
//
-// Default arguments can be specified for carry and overflow parameters, which means
+// Default arguments can be specified for carry and overflow parameters, which
+// means
// not to update the respective flags.
-bool
-EmulateInstructionARM::WriteFlags (Context &context,
- const uint32_t result,
- const uint32_t carry,
- const uint32_t overflow)
-{
- m_new_inst_cpsr = m_opcode_cpsr;
- SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
- SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
- if (carry != ~0u)
- SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
- if (overflow != ~0u)
- SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
- if (m_new_inst_cpsr != m_opcode_cpsr)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
- return false;
- }
- return true;
-}
+bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result,
+ const uint32_t carry,
+ const uint32_t overflow) {
+ m_new_inst_cpsr = m_opcode_cpsr;
+ SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
+ SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
+ if (carry != ~0u)
+ SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
+ if (overflow != ~0u)
+ SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
+ if (m_new_inst_cpsr != m_opcode_cpsr) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
+ return false;
+ }
+ return true;
+}
+
+bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
+ ARMOpcode *opcode_data = NULL;
+
+ if (m_opcode_mode == eModeThumb)
+ opcode_data =
+ GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
+ else if (m_opcode_mode == eModeARM)
+ opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa);
+
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ m_ignore_conditions =
+ evaluate_options & eEmulateInstructionOptionIgnoreConditions;
+
+ bool success = false;
+ if (m_opcode_cpsr == 0 || m_ignore_conditions == false) {
+ 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)
+ return false;
-bool
-EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
-{
- ARMOpcode *opcode_data = NULL;
-
- if (m_opcode_mode == eModeThumb)
- opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
- else if (m_opcode_mode == eModeARM)
- opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
+ uint32_t orig_pc_value = 0;
+ if (auto_advance_pc) {
+ orig_pc_value =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
+ if (!success)
+ return false;
+ }
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
-
- bool success = false;
- if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
- {
- m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
- dwarf_cpsr,
- 0,
- &success);
- }
+ // Call the Emulate... function if we managed to decode the opcode.
+ if (opcode_data) {
+ success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(),
+ opcode_data->encoding);
+ if (!success)
+ return false;
+ }
+
+ // Advance the ITSTATE bits to their values for the next instruction if we
+ // haven't just executed
+ // an IT instruction what initialized it.
+ if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
+ (opcode_data == nullptr ||
+ opcode_data->callback != &EmulateInstructionARM::EmulateIT))
+ m_it_session.ITAdvance();
+
+ if (auto_advance_pc) {
+ uint32_t after_pc_value =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success);
+ if (!success)
+ return false;
- // Only return false if we are unable to read the CPSR if we care about conditions
- if (success == false && m_ignore_conditions == false)
+ if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
+ after_pc_value += m_opcode.GetByteSize();
+
+ EmulateInstruction::Context context;
+ context.type = eContextAdvancePC;
+ context.SetNoArgs();
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc,
+ after_pc_value))
return false;
-
- uint32_t orig_pc_value = 0;
- if (auto_advance_pc)
- {
- orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
- if (!success)
- return false;
}
+ }
+ return true;
+}
- // Call the Emulate... function if we managed to decode the opcode.
- if (opcode_data)
- {
- success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
- if (!success)
- return false;
- }
+EmulateInstruction::InstructionCondition
+EmulateInstructionARM::GetInstructionCondition() {
+ const uint32_t cond = CurrentCond(m_opcode.GetOpcode32());
+ if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
+ return EmulateInstruction::UnconditionalCondition;
+ return cond;
+}
- // Advance the ITSTATE bits to their values for the next instruction if we haven't just executed
- // an IT instruction what initialized it.
- if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() &&
- (opcode_data == nullptr || opcode_data->callback != &EmulateInstructionARM::EmulateIT))
- m_it_session.ITAdvance();
+bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch,
+ OptionValueDictionary *test_data) {
+ if (!test_data) {
+ out_stream->Printf("TestEmulation: Missing test data.\n");
+ return false;
+ }
- if (auto_advance_pc)
- {
- uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
- if (!success)
- return false;
+ static ConstString opcode_key("opcode");
+ static ConstString before_key("before_state");
+ static ConstString after_key("after_state");
- if (auto_advance_pc && (after_pc_value == orig_pc_value))
- {
- after_pc_value += m_opcode.GetByteSize();
+ OptionValueSP value_sp = test_data->GetValueForKey(opcode_key);
- EmulateInstruction::Context context;
- context.type = eContextAdvancePC;
- context.SetNoArgs();
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
- return false;
- }
- }
- return true;
-}
+ uint32_t test_opcode;
+ if ((value_sp.get() == NULL) ||
+ (value_sp->GetType() != OptionValue::eTypeUInt64)) {
+ out_stream->Printf("TestEmulation: Error reading opcode from test file.\n");
+ return false;
+ }
+ test_opcode = value_sp->GetUInt64Value();
+
+ if (arch.GetTriple().getArch() == llvm::Triple::thumb ||
+ arch.IsAlwaysThumbInstructions()) {
+ m_opcode_mode = eModeThumb;
+ if (test_opcode < 0x10000)
+ m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder());
+ else
+ m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
+ } else if (arch.GetTriple().getArch() == llvm::Triple::arm) {
+ m_opcode_mode = eModeARM;
+ m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder());
+ } else {
+ out_stream->Printf("TestEmulation: Invalid arch.\n");
+ return false;
+ }
-EmulateInstruction::InstructionCondition
-EmulateInstructionARM::GetInstructionCondition()
-{
- const uint32_t cond = CurrentCond (m_opcode.GetOpcode32());
- if (cond == 0xe || cond == 0xf || cond == UINT32_MAX)
- return EmulateInstruction::UnconditionalCondition;
- return cond;
-}
-
-bool
-EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
-{
- if (!test_data)
- {
- out_stream->Printf ("TestEmulation: Missing test data.\n");
- return false;
- }
-
- static ConstString opcode_key ("opcode");
- static ConstString before_key ("before_state");
- static ConstString after_key ("after_state");
-
- OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
-
- uint32_t test_opcode;
- if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
- {
- out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
- return false;
- }
- test_opcode = value_sp->GetUInt64Value ();
+ EmulationStateARM before_state;
+ EmulationStateARM after_state;
+ value_sp = test_data->GetValueForKey(before_key);
+ if ((value_sp.get() == NULL) ||
+ (value_sp->GetType() != OptionValue::eTypeDictionary)) {
+ out_stream->Printf("TestEmulation: Failed to find 'before' state.\n");
+ return false;
+ }
- if (arch.GetTriple().getArch() == llvm::Triple::thumb || arch.IsAlwaysThumbInstructions ())
- {
- m_opcode_mode = eModeThumb;
- if (test_opcode < 0x10000)
- m_opcode.SetOpcode16 (test_opcode, endian::InlHostByteOrder());
- else
- m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder());
- }
- else if (arch.GetTriple().getArch() == llvm::Triple::arm)
- {
- m_opcode_mode = eModeARM;
- m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder());
- }
- else
- {
- out_stream->Printf ("TestEmulation: Invalid arch.\n");
- return false;
- }
+ OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary();
+ if (!before_state.LoadStateFromDictionary(state_dictionary)) {
+ out_stream->Printf("TestEmulation: Failed loading 'before' state.\n");
+ return false;
+ }
- EmulationStateARM before_state;
- EmulationStateARM after_state;
-
- value_sp = test_data->GetValueForKey (before_key);
- if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
- {
- out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n");
- return false;
- }
-
- OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
- if (!before_state.LoadStateFromDictionary (state_dictionary))
- {
- out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n");
- return false;
- }
+ value_sp = test_data->GetValueForKey(after_key);
+ if ((value_sp.get() == NULL) ||
+ (value_sp->GetType() != OptionValue::eTypeDictionary)) {
+ out_stream->Printf("TestEmulation: Failed to find 'after' state.\n");
+ return false;
+ }
- value_sp = test_data->GetValueForKey (after_key);
- if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
- {
- out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n");
- return false;
- }
+ state_dictionary = value_sp->GetAsDictionary();
+ if (!after_state.LoadStateFromDictionary(state_dictionary)) {
+ out_stream->Printf("TestEmulation: Failed loading 'after' state.\n");
+ return false;
+ }
- state_dictionary = value_sp->GetAsDictionary ();
- if (!after_state.LoadStateFromDictionary (state_dictionary))
- {
- out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
- return false;
- }
+ SetBaton((void *)&before_state);
+ SetCallbacks(&EmulationStateARM::ReadPseudoMemory,
+ &EmulationStateARM::WritePseudoMemory,
+ &EmulationStateARM::ReadPseudoRegister,
+ &EmulationStateARM::WritePseudoRegister);
- SetBaton ((void *) &before_state);
- SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
- &EmulationStateARM::WritePseudoMemory,
- &EmulationStateARM::ReadPseudoRegister,
- &EmulationStateARM::WritePseudoRegister);
-
- bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
- if (!success)
- {
- out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n");
- return false;
- }
-
- success = before_state.CompareState (after_state);
- if (!success)
- out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n");
-
- return success;
+ bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
+ if (!success) {
+ out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n");
+ return false;
+ }
+
+ success = before_state.CompareState(after_state);
+ if (!success)
+ out_stream->Printf(
+ "TestEmulation: 'before' and 'after' states do not match.\n");
+
+ return success;
}
//
-//
-//const char *
-//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
+//
+// const char *
+// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
//{
// if (reg_kind == eRegisterKindGeneric)
// {
@@ -13772,21 +14082,19 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
// return NULL;
//}
//
-bool
-EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
-
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("EmulateInstructionARM");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (dwarf_lr);
- return true;
+bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("EmulateInstructionARM");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(dwarf_lr);
+ return true;
}
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index 6e75a3db2eb5..1bfc4cb398fb 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -10,981 +10,778 @@
#ifndef lldb_EmulateInstructionARM_h_
#define lldb_EmulateInstructionARM_h_
-#include "lldb/Core/EmulateInstruction.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
-#include "Plugins/Process/Utility/ARMDefines.h"
namespace lldb_private {
// ITSession - Keep track of the IT Block progression.
-class ITSession
-{
+class ITSession {
public:
- ITSession() : ITCounter(0), ITState(0) {}
- ~ITSession() {}
+ ITSession() : ITCounter(0), ITState(0) {}
+ ~ITSession() {}
- // InitIT - Initializes ITCounter/ITState.
- bool InitIT(uint32_t bits7_0);
+ // InitIT - Initializes ITCounter/ITState.
+ bool InitIT(uint32_t bits7_0);
- // ITAdvance - Updates ITCounter/ITState as IT Block progresses.
- void ITAdvance();
+ // ITAdvance - Updates ITCounter/ITState as IT Block progresses.
+ void ITAdvance();
- // InITBlock - Returns true if we're inside an IT Block.
- bool InITBlock();
+ // InITBlock - Returns true if we're inside an IT Block.
+ bool InITBlock();
- // LastInITBlock - Returns true if we're the last instruction inside an IT Block.
- bool LastInITBlock();
+ // LastInITBlock - Returns true if we're the last instruction inside an IT
+ // Block.
+ bool LastInITBlock();
- // GetCond - Gets condition bits for the current thumb instruction.
- uint32_t GetCond();
+ // GetCond - Gets condition bits for the current thumb instruction.
+ uint32_t GetCond();
private:
- uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4.
- uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
+ uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4.
+ uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
};
-class EmulateInstructionARM : public EmulateInstruction
-{
-public:
- typedef enum
- {
- eEncodingA1,
- eEncodingA2,
- eEncodingA3,
- eEncodingA4,
- eEncodingA5,
- eEncodingT1,
- eEncodingT2,
- eEncodingT3,
- eEncodingT4,
- eEncodingT5
- } ARMEncoding;
-
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (InstructionType inst_type)
- {
- switch (inst_type)
- {
- case eInstructionTypeAny:
- case eInstructionTypePrologueEpilogue:
- case eInstructionTypePCModifying:
- return true;
-
- case eInstructionTypeAll:
- return false;
- }
- return false;
+class EmulateInstructionARM : public EmulateInstruction {
+public:
+ typedef enum {
+ eEncodingA1,
+ eEncodingA2,
+ eEncodingA3,
+ eEncodingA4,
+ eEncodingA5,
+ eEncodingT1,
+ eEncodingT2,
+ eEncodingT3,
+ eEncodingT4,
+ eEncodingT5
+ } ARMEncoding;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type);
+
+ static bool
+ SupportsEmulatingInstructionsOfTypeStatic(InstructionType inst_type) {
+ switch (inst_type) {
+ case eInstructionTypeAny:
+ case eInstructionTypePrologueEpilogue:
+ case eInstructionTypePCModifying:
+ return true;
+
+ case eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ uint32_t GetPluginVersion() override { return 1; }
- bool
- SetTargetTriple (const ArchSpec &arch) override;
-
- enum Mode
- {
- eModeInvalid = -1,
- eModeARM,
- eModeThumb
- };
-
- EmulateInstructionARM (const ArchSpec &arch) :
- EmulateInstruction (arch),
- m_arm_isa (0),
- m_opcode_mode (eModeInvalid),
- m_opcode_cpsr (0),
- m_it_session (),
- m_ignore_conditions (false)
- {
- SetArchitecture (arch);
- }
+ bool SetTargetTriple(const ArchSpec &arch) override;
-// EmulateInstructionARM (const ArchSpec &arch,
-// bool ignore_conditions,
-// void *baton,
-// ReadMemory read_mem_callback,
-// WriteMemory write_mem_callback,
-// ReadRegister read_reg_callback,
-// WriteRegister write_reg_callback) :
-// EmulateInstruction (arch,
-// ignore_conditions,
-// baton,
-// read_mem_callback,
-// write_mem_callback,
-// read_reg_callback,
-// write_reg_callback),
-// m_arm_isa (0),
-// m_opcode_mode (eModeInvalid),
-// m_opcode_cpsr (0),
-// m_it_session ()
-// {
-// }
-
- bool
- SupportsEmulatingInstructionsOfType (InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ enum Mode { eModeInvalid = -1, eModeARM, eModeThumb };
- virtual bool
- SetArchitecture (const ArchSpec &arch);
-
- bool
- ReadInstruction () override;
-
- bool
- SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) override;
-
- bool
- EvaluateInstruction (uint32_t evaluate_options) override;
-
- InstructionCondition
- GetInstructionCondition() override;
-
- bool
- TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override;
-
- bool
- GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info) override;
-
- bool
- CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) override;
-
- uint32_t
- ArchVersion();
-
- bool
- ConditionPassed (const uint32_t opcode);
-
- uint32_t
- CurrentCond (const uint32_t opcode);
-
- // InITBlock - Returns true if we're in Thumb mode and inside an IT Block.
- bool InITBlock();
-
- // LastInITBlock - Returns true if we're in Thumb mode and the last instruction inside an IT Block.
- bool LastInITBlock();
-
- bool
- BadMode (uint32_t mode);
-
- bool
- CurrentModeIsPrivileged ();
-
- void
- CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate);
-
- bool
- BranchWritePC(const Context &context, uint32_t addr);
-
- bool
- BXWritePC(Context &context, uint32_t addr);
-
- bool
- LoadWritePC(Context &context, uint32_t addr);
-
- bool
- ALUWritePC(Context &context, uint32_t addr);
-
- Mode
- CurrentInstrSet();
-
- bool
- SelectInstrSet(Mode arm_or_thumb);
-
- bool
- WriteBits32Unknown (int n);
-
- bool
- WriteBits32UnknownToMemory (lldb::addr_t address);
-
- bool
- UnalignedSupport();
-
- typedef struct
- {
- uint32_t result;
- uint8_t carry_out;
- uint8_t overflow;
- } AddWithCarryResult;
-
- AddWithCarryResult
- AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in);
-
- // Helper method to read the content of an ARM core register.
- uint32_t
- ReadCoreReg (uint32_t regnum, bool *success);
-
- // See A8.6.96 MOV (immediate) Operation.
- // Default arguments are specified for carry and overflow parameters, which means
- // not to update the respective flags even if setflags is true.
- bool
- WriteCoreRegOptionalFlags (Context &context,
- const uint32_t result,
- const uint32_t Rd,
- bool setflags,
- const uint32_t carry = ~0u,
- const uint32_t overflow = ~0u);
-
- bool
- WriteCoreReg (Context &context,
- const uint32_t result,
- const uint32_t Rd)
- {
- // Don't set the flags.
- return WriteCoreRegOptionalFlags(context, result, Rd, false);
- }
+ EmulateInstructionARM(const ArchSpec &arch)
+ : EmulateInstruction(arch), m_arm_isa(0), m_opcode_mode(eModeInvalid),
+ m_opcode_cpsr(0), m_it_session(), m_ignore_conditions(false) {
+ SetArchitecture(arch);
+ }
- // See A8.6.35 CMP (immediate) Operation.
- // Default arguments are specified for carry and overflow parameters, which means
- // not to update the respective flags.
- bool
- WriteFlags (Context &context,
- const uint32_t result,
- const uint32_t carry = ~0u,
- const uint32_t overflow = ~0u);
-
- inline uint64_t
- MemARead (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint32_t size,
- uint64_t fail_value,
- bool *success_ptr)
- {
- // This is a stub function corresponding to "MemA[]" in the ARM manual pseudocode, for
- // aligned reads from memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // ReadMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return ReadMemoryUnsigned (context, address, size, fail_value, success_ptr);
- }
-
- inline bool
- MemAWrite (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint64_t data_val,
- uint32_t size)
-
- {
- // This is a stub function corresponding to "MemA[]" in the ARM manual pseudocode, for
- // aligned writes to memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // WriteMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return WriteMemoryUnsigned (context, address, data_val, size);
- }
-
-
- inline uint64_t
- MemURead (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint32_t size,
- uint64_t fail_value,
- bool *success_ptr)
- {
- // This is a stub function corresponding to "MemU[]" in the ARM manual pseudocode, for
- // unaligned reads from memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // ReadMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return ReadMemoryUnsigned (context, address, size, fail_value, success_ptr);
- }
-
- inline bool
- MemUWrite (EmulateInstruction::Context &context,
- lldb::addr_t address,
- uint64_t data_val,
- uint32_t size)
-
- {
- // This is a stub function corresponding to "MemU[]" in the ARM manual pseudocode, for
- // unaligned writes to memory. Since we are not trying to write a full hardware simulator, and since
- // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the
- // system registers we would need in order to fully implement this function, we will just call
- // WriteMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of
- // the hardware, we can update this function appropriately.
-
- return WriteMemoryUnsigned (context, address, data_val, size);
- }
+ // EmulateInstructionARM (const ArchSpec &arch,
+ // bool ignore_conditions,
+ // void *baton,
+ // ReadMemory read_mem_callback,
+ // WriteMemory write_mem_callback,
+ // ReadRegister read_reg_callback,
+ // WriteRegister write_reg_callback) :
+ // EmulateInstruction (arch,
+ // ignore_conditions,
+ // baton,
+ // read_mem_callback,
+ // write_mem_callback,
+ // read_reg_callback,
+ // write_reg_callback),
+ // m_arm_isa (0),
+ // m_opcode_mode (eModeInvalid),
+ // m_opcode_cpsr (0),
+ // m_it_session ()
+ // {
+ // }
+
+ bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ virtual bool SetArchitecture(const ArchSpec &arch);
+
+ bool ReadInstruction() override;
+
+ bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr,
+ Target *target) override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ InstructionCondition GetInstructionCondition() override;
+
+ bool TestEmulation(Stream *out_stream, ArchSpec &arch,
+ OptionValueDictionary *test_data) override;
+
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ RegisterInfo &reg_info) override;
+
+ bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override;
+
+ uint32_t ArchVersion();
+
+ bool ConditionPassed(const uint32_t opcode);
+
+ uint32_t CurrentCond(const uint32_t opcode);
+
+ // InITBlock - Returns true if we're in Thumb mode and inside an IT Block.
+ bool InITBlock();
+
+ // LastInITBlock - Returns true if we're in Thumb mode and the last
+ // instruction inside an IT Block.
+ bool LastInITBlock();
+
+ bool BadMode(uint32_t mode);
+
+ bool CurrentModeIsPrivileged();
+
+ void CPSRWriteByInstr(uint32_t value, uint32_t bytemask,
+ bool affect_execstate);
+
+ bool BranchWritePC(const Context &context, uint32_t addr);
+
+ bool BXWritePC(Context &context, uint32_t addr);
+
+ bool LoadWritePC(Context &context, uint32_t addr);
+
+ bool ALUWritePC(Context &context, uint32_t addr);
+
+ Mode CurrentInstrSet();
+
+ bool SelectInstrSet(Mode arm_or_thumb);
+
+ bool WriteBits32Unknown(int n);
+
+ bool WriteBits32UnknownToMemory(lldb::addr_t address);
+
+ bool UnalignedSupport();
+
+ typedef struct {
+ uint32_t result;
+ uint8_t carry_out;
+ uint8_t overflow;
+ } AddWithCarryResult;
+
+ AddWithCarryResult AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in);
+
+ // Helper method to read the content of an ARM core register.
+ uint32_t ReadCoreReg(uint32_t regnum, bool *success);
+
+ // See A8.6.96 MOV (immediate) Operation.
+ // Default arguments are specified for carry and overflow parameters, which
+ // means
+ // not to update the respective flags even if setflags is true.
+ bool WriteCoreRegOptionalFlags(Context &context, const uint32_t result,
+ const uint32_t Rd, bool setflags,
+ const uint32_t carry = ~0u,
+ const uint32_t overflow = ~0u);
+
+ bool WriteCoreReg(Context &context, const uint32_t result,
+ const uint32_t Rd) {
+ // Don't set the flags.
+ return WriteCoreRegOptionalFlags(context, result, Rd, false);
+ }
+
+ // See A8.6.35 CMP (immediate) Operation.
+ // Default arguments are specified for carry and overflow parameters, which
+ // means
+ // not to update the respective flags.
+ bool WriteFlags(Context &context, const uint32_t result,
+ const uint32_t carry = ~0u, const uint32_t overflow = ~0u);
+
+ inline uint64_t MemARead(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint32_t size,
+ uint64_t fail_value, bool *success_ptr) {
+ // This is a stub function corresponding to "MemA[]" in the ARM manual
+ // pseudocode, for
+ // aligned reads from memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // ReadMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr);
+ }
+
+ inline bool MemAWrite(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint64_t data_val, uint32_t size)
+
+ {
+ // This is a stub function corresponding to "MemA[]" in the ARM manual
+ // pseudocode, for
+ // aligned writes to memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // WriteMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return WriteMemoryUnsigned(context, address, data_val, size);
+ }
+
+ inline uint64_t MemURead(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint32_t size,
+ uint64_t fail_value, bool *success_ptr) {
+ // This is a stub function corresponding to "MemU[]" in the ARM manual
+ // pseudocode, for
+ // unaligned reads from memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // ReadMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return ReadMemoryUnsigned(context, address, size, fail_value, success_ptr);
+ }
+
+ inline bool MemUWrite(EmulateInstruction::Context &context,
+ lldb::addr_t address, uint64_t data_val, uint32_t size)
+
+ {
+ // This is a stub function corresponding to "MemU[]" in the ARM manual
+ // pseudocode, for
+ // unaligned writes to memory. Since we are not trying to write a full
+ // hardware simulator, and since
+ // we are running in User mode (rather than Kernel mode) and therefore won't
+ // have access to many of the
+ // system registers we would need in order to fully implement this function,
+ // we will just call
+ // WriteMemoryUnsigned from here. In the future, if we decide we do need to
+ // do more faithful emulation of
+ // the hardware, we can update this function appropriately.
+
+ return WriteMemoryUnsigned(context, address, data_val, size);
+ }
protected:
+ // Typedef for the callback function used during the emulation.
+ // Pass along (ARMEncoding)encoding as the callback data.
+ typedef enum { eSize16, eSize32 } ARMInstrSize;
+
+ typedef struct {
+ uint32_t mask;
+ uint32_t value;
+ uint32_t variants;
+ EmulateInstructionARM::ARMEncoding encoding;
+ uint32_t vfp_variants;
+ ARMInstrSize size;
+ bool (EmulateInstructionARM::*callback)(
+ const uint32_t opcode,
+ const EmulateInstructionARM::ARMEncoding encoding);
+ const char *name;
+ } ARMOpcode;
+
+ uint32_t GetFramePointerRegisterNumber() const;
+
+ uint32_t GetFramePointerDWARFRegisterNumber() const;
+
+ static ARMOpcode *GetARMOpcodeForInstruction(const uint32_t opcode,
+ uint32_t isa_mask);
+
+ static ARMOpcode *GetThumbOpcodeForInstruction(const uint32_t opcode,
+ uint32_t isa_mask);
+
+ // A8.6.123 PUSH
+ bool EmulatePUSH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.122 POP
+ bool EmulatePOP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.8 ADD (SP plus immediate)
+ bool EmulateADDRdSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp
+ bool EmulateMOVRdSP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7
+ bool EmulateMOVLowHigh(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.59 LDR (literal)
+ bool EmulateLDRRtPCRelative(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.8 ADD (SP plus immediate)
+ bool EmulateADDSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.9 ADD (SP plus register)
+ bool EmulateADDSPRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.23 BL, BLX (immediate)
+ bool EmulateBLXImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.24 BLX (register)
+ bool EmulateBLXRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.25 BX
+ bool EmulateBXRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.26 BXJ
+ bool EmulateBXJRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip
+ bool EmulateSUBR7IPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.215 SUB (SP minus immediate) -- Rd == ip
+ bool EmulateSUBIPSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.215 SUB (SP minus immediate)
+ bool EmulateSUBSPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.216 SUB (SP minus register)
+ bool EmulateSUBSPReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.194 STR (immediate, ARM) -- Rn == sp
+ bool EmulateSTRRtSP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.355 VPUSH
+ bool EmulateVPUSH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.354 VPOP
+ bool EmulateVPOP(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.218 SVC (previously SWI)
+ bool EmulateSVC(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.50 IT
+ bool EmulateIT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // NOP
+ bool EmulateNop(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.16 B
+ bool EmulateB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.27 CBNZ, CBZ
+ bool EmulateCB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.226 TBB, TBH
+ bool EmulateTB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.4 ADD (immediate, Thumb)
+ bool EmulateADDImmThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.5 ADD (immediate, ARM)
+ bool EmulateADDImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.6 ADD (register)
+ bool EmulateADDReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.7 ADD (register-shifted register)
+ bool EmulateADDRegShift(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.97 MOV (register)
+ bool EmulateMOVRdRm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.96 MOV (immediate)
+ bool EmulateMOVRdImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.35 CMP (immediate)
+ bool EmulateCMPImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.36 CMP (register)
+ bool EmulateCMPReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.14 ASR (immediate)
+ bool EmulateASRImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.15 ASR (register)
+ bool EmulateASRReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.88 LSL (immediate)
+ bool EmulateLSLImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.89 LSL (register)
+ bool EmulateLSLReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.90 LSR (immediate)
+ bool EmulateLSRImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.91 LSR (register)
+ bool EmulateLSRReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.139 ROR (immediate)
+ bool EmulateRORImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.140 ROR (register)
+ bool EmulateRORReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.141 RRX
+ bool EmulateRRX(const uint32_t opcode, const ARMEncoding encoding);
+
+ // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX
+ bool EmulateShiftImm(const uint32_t opcode, const ARMEncoding encoding,
+ ARM_ShifterType shift_type);
+
+ // Helper method for ASR, LSL, LSR, and ROR (register)
+ bool EmulateShiftReg(const uint32_t opcode, const ARMEncoding encoding,
+ ARM_ShifterType shift_type);
+
+ // LOAD FUNCTIONS
+
+ // A8.6.53 LDM/LDMIA/LDMFD
+ bool EmulateLDM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.54 LDMDA/LDMFA
+ bool EmulateLDMDA(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.55 LDMDB/LDMEA
+ bool EmulateLDMDB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.56 LDMIB/LDMED
+ bool EmulateLDMIB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.57 LDR (immediate, Thumb) -- Encoding T1
+ bool EmulateLDRRtRnImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.58 LDR (immediate, ARM) - Encoding A1
+ bool EmulateLDRImmediateARM(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.59 LDR (literal)
+ bool EmulateLDRLiteral(const uint32_t, const ARMEncoding encoding);
+
+ // A8.6.60 LDR (register) - Encoding T1, T2, A1
+ bool EmulateLDRRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2, T3
+ bool EmulateLDRBImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.62 LDRB (immediate, ARM)
+ bool EmulateLDRBImmediateARM(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.63 LDRB (literal) - Encoding T1, A1
+ bool EmulateLDRBLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.64 LDRB (register) - Encoding T1, T2, A1
+ bool EmulateLDRBRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.65 LDRBT
+ bool EmulateLDRBT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.66 LDRD (immediate)
+ bool EmulateLDRDImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.67
+ bool EmulateLDRDLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.68 LDRD (register)
+ bool EmulateLDRDRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.69 LDREX
+ bool EmulateLDREX(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.70 LDREXB
+ bool EmulateLDREXB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.71 LDREXD
+ bool EmulateLDREXD(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.72 LDREXH
+ bool EmulateLDREXH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2, T3
+ bool EmulateLDRHImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.74 LDRS (immediate, ARM)
+ bool EmulateLDRHImmediateARM(const uint32_t opcode,
+ const ARMEncoding encoding);
+
+ // A8.6.75 LDRH (literal) - Encoding T1, A1
+ bool EmulateLDRHLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.76 LDRH (register) - Encoding T1, T2, A1
+ bool EmulateLDRHRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.77 LDRHT
+ bool EmulateLDRHT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.78 LDRSB (immediate) - Encoding T1, T2, A1
+ bool EmulateLDRSBImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.79 LDRSB (literal) - Encoding T1, A1
+ bool EmulateLDRSBLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.80 LDRSB (register) - Encoding T1, T2, A1
+ bool EmulateLDRSBRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.81 LDRSBT
+ bool EmulateLDRSBT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.82 LDRSH (immediate) - Encoding T1, T2, A1
+ bool EmulateLDRSHImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.83 LDRSH (literal) - Encoding T1, A1
+ bool EmulateLDRSHLiteral(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.84 LDRSH (register) - Encoding T1, T2, A1
+ bool EmulateLDRSHRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.85 LDRSHT
+ bool EmulateLDRSHT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.86
+ bool EmulateLDRT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // STORE FUNCTIONS
+
+ // A8.6.189 STM/STMIA/STMEA
+ bool EmulateSTM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.190 STMDA/STMED
+ bool EmulateSTMDA(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.191 STMDB/STMFD
+ bool EmulateSTMDB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.192 STMIB/STMFA
+ bool EmulateSTMIB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.193 STR (immediate, Thumb)
+ bool EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.194 STR (immediate, ARM)
+ bool EmulateSTRImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.195 STR (register)
+ bool EmulateSTRRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.196 STRB (immediate, Thumb)
+ bool EmulateSTRBThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.197 STRB (immediate, ARM)
+ bool EmulateSTRBImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.198 STRB (register)
+ bool EmulateSTRBReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.199 STRBT
+ bool EmulateSTRBT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.200 STRD (immediate)
+ bool EmulateSTRDImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.201 STRD (register)
+ bool EmulateSTRDReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.202 STREX
+ bool EmulateSTREX(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.203 STREXB
+ bool EmulateSTREXB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.204 STREXD
+ bool EmulateSTREXD(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.205 STREXH
+ bool EmulateSTREXH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.206 STRH (immediate, Thumb)
+ bool EmulateSTRHImmThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.207 STRH (immediate, ARM)
+ bool EmulateSTRHImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.208 STRH (register)
+ bool EmulateSTRHRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.209 STRHT
+ bool EmulateSTRHT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.210 STRT
+ bool EmulateSTRT(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.1 ADC (immediate)
+ bool EmulateADCImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.2 ADC (Register)
+ bool EmulateADCReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.10 ADR
+ bool EmulateADR(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.11 AND (immediate)
+ bool EmulateANDImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.12 AND (register)
+ bool EmulateANDReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.19 BIC (immediate)
+ bool EmulateBICImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.20 BIC (register)
+ bool EmulateBICReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.26 BXJ
+ bool EmulateBXJ(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.32 CMN (immediate)
+ bool EmulateCMNImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.33 CMN (register)
+ bool EmulateCMNReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.44 EOR (immediate)
+ bool EmulateEORImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.45 EOR (register)
+ bool EmulateEORReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.105 MUL
+ bool EmulateMUL(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.106 MVN (immediate)
+ bool EmulateMVNImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.107 MVN (register)
+ bool EmulateMVNReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.113 ORR (immediate)
+ bool EmulateORRImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.114 ORR (register)
+ bool EmulateORRReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1
+ bool EmulatePLDImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.119 PLI (immediate,literal) - Encoding T3, A1
+ bool EmulatePLIImmediate(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.120 PLI (register) - Encoding T1, A1
+ bool EmulatePLIRegister(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.141 RSB (immediate)
+ bool EmulateRSBImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.142 RSB (register)
+ bool EmulateRSBReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.144 RSC (immediate)
+ bool EmulateRSCImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.145 RSC (register)
+ bool EmulateRSCReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.150 SBC (immediate)
+ bool EmulateSBCImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.151 SBC (register)
+ bool EmulateSBCReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.211 SUB (immediate, Thumb)
+ bool EmulateSUBImmThumb(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.212 SUB (immediate, ARM)
+ bool EmulateSUBImmARM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.213 SUB (register)
+ bool EmulateSUBReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.214 SUB (register-shifted register)
+ bool EmulateSUBRegShift(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.222 SXTB - Encoding T1
+ bool EmulateSXTB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.224 SXTH - EncodingT1
+ bool EmulateSXTH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.227 TEQ (immediate) - Encoding A1
+ bool EmulateTEQImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.228 TEQ (register) - Encoding A1
+ bool EmulateTEQReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.230 TST (immediate) - Encoding A1
+ bool EmulateTSTImm(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.231 TST (register) - Encoding T1, A1
+ bool EmulateTSTReg(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.262 UXTB - Encoding T1
+ bool EmulateUXTB(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.264 UXTH - Encoding T1
+ bool EmulateUXTH(const uint32_t opcode, const ARMEncoding encoding);
+
+ // B6.1.8 RFE
+ bool EmulateRFE(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.319 VLDM
+ bool EmulateVLDM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.399 VSTM
+ bool EmulateVSTM(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.307 VLD1 (multiple single elements)
+ bool EmulateVLD1Multiple(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.308 VLD1 (single element to one lane)
+ bool EmulateVLD1Single(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.309 VLD1 (single element to all lanes)
+ bool EmulateVLD1SingleAll(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.391 VST1 (multiple single elements)
+ bool EmulateVST1Multiple(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.392 VST1 (single element from one lane)
+ bool EmulateVST1Single(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.317 VLDR
+ bool EmulateVLDR(const uint32_t opcode, const ARMEncoding encoding);
+
+ // A8.6.400 VSTR
+ bool EmulateVSTR(const uint32_t opcode, const ARMEncoding encoding);
+
+ // B6.2.13 SUBS PC, LR and related instructions
+ bool EmulateSUBSPcLrEtc(const uint32_t opcode, const ARMEncoding encoding);
- // Typedef for the callback function used during the emulation.
- // Pass along (ARMEncoding)encoding as the callback data.
- typedef enum
- {
- eSize16,
- eSize32
- } ARMInstrSize;
-
- typedef struct
- {
- uint32_t mask;
- uint32_t value;
- uint32_t variants;
- EmulateInstructionARM::ARMEncoding encoding;
- uint32_t vfp_variants;
- ARMInstrSize size;
- bool (EmulateInstructionARM::*callback) (const uint32_t opcode, const EmulateInstructionARM::ARMEncoding encoding);
- const char *name;
- } ARMOpcode;
-
- uint32_t
- GetFramePointerRegisterNumber () const;
-
- uint32_t
- GetFramePointerDWARFRegisterNumber () const;
-
- static ARMOpcode*
- GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
-
- static ARMOpcode*
- GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
-
- // A8.6.123 PUSH
- bool
- EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.122 POP
- bool
- EmulatePOP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.8 ADD (SP plus immediate)
- bool
- EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp
- bool
- EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7
- bool
- EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.59 LDR (literal)
- bool
- EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.8 ADD (SP plus immediate)
- bool
- EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.9 ADD (SP plus register)
- bool
- EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.23 BL, BLX (immediate)
- bool
- EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.24 BLX (register)
- bool
- EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.25 BX
- bool
- EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.26 BXJ
- bool
- EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip
- bool
- EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.215 SUB (SP minus immediate) -- Rd == ip
- bool
- EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.215 SUB (SP minus immediate)
- bool
- EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.216 SUB (SP minus register)
- bool
- EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.194 STR (immediate, ARM) -- Rn == sp
- bool
- EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.355 VPUSH
- bool
- EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.354 VPOP
- bool
- EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.218 SVC (previously SWI)
- bool
- EmulateSVC (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.50 IT
- bool
- EmulateIT (const uint32_t opcode, const ARMEncoding encoding);
-
- // NOP
- bool
- EmulateNop (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.16 B
- bool
- EmulateB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.27 CBNZ, CBZ
- bool
- EmulateCB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.226 TBB, TBH
- bool
- EmulateTB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.4 ADD (immediate, Thumb)
- bool
- EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.5 ADD (immediate, ARM)
- bool
- EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.6 ADD (register)
- bool
- EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.7 ADD (register-shifted register)
- bool
- EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.97 MOV (register)
- bool
- EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.96 MOV (immediate)
- bool
- EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.35 CMP (immediate)
- bool
- EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.36 CMP (register)
- bool
- EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.14 ASR (immediate)
- bool
- EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.15 ASR (register)
- bool
- EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.88 LSL (immediate)
- bool
- EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.89 LSL (register)
- bool
- EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.90 LSR (immediate)
- bool
- EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.91 LSR (register)
- bool
- EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.139 ROR (immediate)
- bool
- EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.140 ROR (register)
- bool
- EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.141 RRX
- bool
- EmulateRRX (const uint32_t opcode, const ARMEncoding encoding);
-
- // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX
- bool
- EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type);
-
- // Helper method for ASR, LSL, LSR, and ROR (register)
- bool
- EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type);
-
- // LOAD FUNCTIONS
-
- // A8.6.53 LDM/LDMIA/LDMFD
- bool
- EmulateLDM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.54 LDMDA/LDMFA
- bool
- EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.55 LDMDB/LDMEA
- bool
- EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.56 LDMIB/LDMED
- bool
- EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.57 LDR (immediate, Thumb) -- Encoding T1
- bool
- EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.58 LDR (immediate, ARM) - Encoding A1
- bool
- EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.59 LDR (literal)
- bool
- EmulateLDRLiteral (const uint32_t, const ARMEncoding encoding);
-
- // A8.6.60 LDR (register) - Encoding T1, T2, A1
- bool
- EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2, T3
- bool
- EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.62 LDRB (immediate, ARM)
- bool
- EmulateLDRBImmediateARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.63 LDRB (literal) - Encoding T1, A1
- bool
- EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.64 LDRB (register) - Encoding T1, T2, A1
- bool
- EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.65 LDRBT
- bool
- EmulateLDRBT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.66 LDRD (immediate)
- bool
- EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.67
- bool
- EmulateLDRDLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.68 LDRD (register)
- bool
- EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.69 LDREX
- bool
- EmulateLDREX (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.70 LDREXB
- bool
- EmulateLDREXB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.71 LDREXD
- bool
- EmulateLDREXD (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.72 LDREXH
- bool
- EmulateLDREXH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2, T3
- bool
- EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.74 LDRS (immediate, ARM)
- bool
- EmulateLDRHImmediateARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.75 LDRH (literal) - Encoding T1, A1
- bool
- EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.76 LDRH (register) - Encoding T1, T2, A1
- bool
- EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.77 LDRHT
- bool
- EmulateLDRHT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.78 LDRSB (immediate) - Encoding T1, T2, A1
- bool
- EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.79 LDRSB (literal) - Encoding T1, A1
- bool
- EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.80 LDRSB (register) - Encoding T1, T2, A1
- bool
- EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.81 LDRSBT
- bool
- EmulateLDRSBT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.82 LDRSH (immediate) - Encoding T1, T2, A1
- bool
- EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.83 LDRSH (literal) - Encoding T1, A1
- bool
- EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.84 LDRSH (register) - Encoding T1, T2, A1
- bool
- EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.85 LDRSHT
- bool
- EmulateLDRSHT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.86
- bool
- EmulateLDRT (const uint32_t opcode, const ARMEncoding encoding);
-
-
- // STORE FUNCTIONS
-
- // A8.6.189 STM/STMIA/STMEA
- bool
- EmulateSTM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.190 STMDA/STMED
- bool
- EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.191 STMDB/STMFD
- bool
- EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.192 STMIB/STMFA
- bool
- EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.193 STR (immediate, Thumb)
- bool
- EmulateSTRThumb(const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.194 STR (immediate, ARM)
- bool
- EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.195 STR (register)
- bool
- EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.196 STRB (immediate, Thumb)
- bool
- EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.197 STRB (immediate, ARM)
- bool
- EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.198 STRB (register)
- bool
- EmulateSTRBReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.199 STRBT
- bool
- EmulateSTRBT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.200 STRD (immediate)
- bool
- EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.201 STRD (register)
- bool
- EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.202 STREX
- bool
- EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.203 STREXB
- bool
- EmulateSTREXB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.204 STREXD
- bool
- EmulateSTREXD (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.205 STREXH
- bool
- EmulateSTREXH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.206 STRH (immediate, Thumb)
- bool
- EmulateSTRHImmThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.207 STRH (immediate, ARM)
- bool
- EmulateSTRHImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.208 STRH (register)
- bool
- EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.209 STRHT
- bool
- EmulateSTRHT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.210 STRT
- bool
- EmulateSTRT (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.1 ADC (immediate)
- bool
- EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.2 ADC (Register)
- bool
- EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.10 ADR
- bool
- EmulateADR (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.11 AND (immediate)
- bool
- EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.12 AND (register)
- bool
- EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.19 BIC (immediate)
- bool
- EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.20 BIC (register)
- bool
- EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.26 BXJ
- bool
- EmulateBXJ (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.32 CMN (immediate)
- bool
- EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.33 CMN (register)
- bool
- EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.44 EOR (immediate)
- bool
- EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.45 EOR (register)
- bool
- EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.105 MUL
- bool
- EmulateMUL (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.106 MVN (immediate)
- bool
- EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.107 MVN (register)
- bool
- EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.113 ORR (immediate)
- bool
- EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.114 ORR (register)
- bool
- EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1
- bool
- EmulatePLDImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.119 PLI (immediate,literal) - Encoding T3, A1
- bool
- EmulatePLIImmediate (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.120 PLI (register) - Encoding T1, A1
- bool
- EmulatePLIRegister (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.141 RSB (immediate)
- bool
- EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.142 RSB (register)
- bool
- EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.144 RSC (immediate)
- bool
- EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.145 RSC (register)
- bool
- EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.150 SBC (immediate)
- bool
- EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.151 SBC (register)
- bool
- EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.211 SUB (immediate, Thumb)
- bool
- EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.212 SUB (immediate, ARM)
- bool
- EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.213 SUB (register)
- bool
- EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.214 SUB (register-shifted register)
- bool
- EmulateSUBRegShift (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.222 SXTB - Encoding T1
- bool
- EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.224 SXTH - EncodingT1
- bool
- EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.227 TEQ (immediate) - Encoding A1
- bool
- EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.228 TEQ (register) - Encoding A1
- bool
- EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.230 TST (immediate) - Encoding A1
- bool
- EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.231 TST (register) - Encoding T1, A1
- bool
- EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.262 UXTB - Encoding T1
- bool
- EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.264 UXTH - Encoding T1
- bool
- EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding);
-
- // B6.1.8 RFE
- bool
- EmulateRFE (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.319 VLDM
- bool
- EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.399 VSTM
- bool
- EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.307 VLD1 (multiple single elements)
- bool
- EmulateVLD1Multiple (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.308 VLD1 (single element to one lane)
- bool
- EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.309 VLD1 (single element to all lanes)
- bool
- EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.391 VST1 (multiple single elements)
- bool
- EmulateVST1Multiple (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.392 VST1 (single element from one lane)
- bool
- EmulateVST1Single (const uint32_t opcode, const ARMEncoding encoding);
-
- // A8.6.317 VLDR
- bool
- EmulateVLDR (const uint32_t opcode, const ARMEncoding encoding);
-
-
- // A8.6.400 VSTR
- bool
- EmulateVSTR (const uint32_t opcode, const ARMEncoding encoding);
-
- // B6.2.13 SUBS PC, LR and related instructions
- bool
- EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding);
-
- uint32_t m_arm_isa;
- Mode m_opcode_mode;
- uint32_t m_opcode_cpsr;
- uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
- ITSession m_it_session;
- bool m_ignore_conditions;
+ uint32_t m_arm_isa;
+ Mode m_opcode_mode;
+ uint32_t m_opcode_cpsr;
+ uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
+ ITSession m_it_session;
+ bool m_ignore_conditions;
};
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_EmulateInstructionARM_h_
+#endif // lldb_EmulateInstructionARM_h_
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index 547db44ebfb2..9ceeb76c6f5e 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -13,406 +13,341 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
-#include "lldb/Target/StackFrame.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
#include "Utility/ARM_DWARF_Registers.h"
using namespace lldb;
using namespace lldb_private;
-EmulationStateARM::EmulationStateARM () :
- m_gpr (),
- m_vfp_regs (),
- m_memory ()
-{
- ClearPseudoRegisters();
+EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
+ ClearPseudoRegisters();
}
-EmulationStateARM::~EmulationStateARM ()
-{
-}
+EmulationStateARM::~EmulationStateARM() {}
-bool
-EmulationStateARM::LoadPseudoRegistersFromFrame (StackFrame &frame)
-{
- RegisterContext *reg_ctx = frame.GetRegisterContext().get();
- bool success = true;
- uint32_t reg_num;
-
- for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i)
- {
- reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i);
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister (reg_info, reg_value))
- {
- m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
- }
- else
- success = false;
- }
-
- for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i)
- {
- reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i);
- RegisterValue reg_value;
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
-
- if (reg_ctx->ReadRegister (reg_info, reg_value))
- {
- uint64_t value = reg_value.GetAsUInt64();
- uint32_t idx = i - dwarf_d0;
- if (i < 16)
- {
- m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
- m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
- }
- else
- m_vfp_regs.d_regs[idx - 16] = value;
- }
- else
- success = false;
- }
-
- return success;
+bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
+ RegisterContext *reg_ctx = frame.GetRegisterContext().get();
+ bool success = true;
+ uint32_t reg_num;
+
+ for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
+ reg_num =
+ reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
+ } else
+ success = false;
+ }
+
+ for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
+ reg_num =
+ reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
+ RegisterValue reg_value;
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ uint64_t value = reg_value.GetAsUInt64();
+ uint32_t idx = i - dwarf_d0;
+ if (i < 16) {
+ m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
+ m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
+ } else
+ m_vfp_regs.d_regs[idx - 16] = value;
+ } else
+ success = false;
+ }
+
+ return success;
}
-
-bool
-EmulationStateARM::StorePseudoRegisterValue (uint32_t reg_num, uint64_t value)
-{
- if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
- m_gpr[reg_num - dwarf_r0] = (uint32_t) value;
- else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31))
- {
- uint32_t idx = reg_num - dwarf_s0;
- m_vfp_regs.s_regs[idx] = (uint32_t)value;
- }
- else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31))
- {
- uint32_t idx = reg_num - dwarf_d0;
- if (idx < 16)
- {
- m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
- m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
- }
- else
- m_vfp_regs.d_regs[idx - 16] = value;
- }
- else
- return false;
-
- return true;
+
+bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
+ uint64_t value) {
+ if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
+ m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
+ else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
+ uint32_t idx = reg_num - dwarf_s0;
+ m_vfp_regs.s_regs[idx] = (uint32_t)value;
+ } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
+ uint32_t idx = reg_num - dwarf_d0;
+ if (idx < 16) {
+ m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
+ m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
+ } else
+ m_vfp_regs.d_regs[idx - 16] = value;
+ } else
+ return false;
+
+ return true;
}
-
-uint64_t
-EmulationStateARM::ReadPseudoRegisterValue (uint32_t reg_num, bool &success)
-{
- uint64_t value = 0;
- success = true;
-
- if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
- value = m_gpr[reg_num - dwarf_r0];
- else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31))
- {
- uint32_t idx = reg_num - dwarf_s0;
- value = m_vfp_regs.d_regs[idx];
- }
- else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31))
- {
- uint32_t idx = reg_num - dwarf_d0;
- if (idx < 16)
- value = (uint64_t)m_vfp_regs.s_regs[idx * 2] | ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
- else
- value = m_vfp_regs.d_regs[idx - 16];
- }
+
+uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
+ bool &success) {
+ uint64_t value = 0;
+ success = true;
+
+ if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr))
+ value = m_gpr[reg_num - dwarf_r0];
+ else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
+ uint32_t idx = reg_num - dwarf_s0;
+ value = m_vfp_regs.d_regs[idx];
+ } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
+ uint32_t idx = reg_num - dwarf_d0;
+ if (idx < 16)
+ value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
+ ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
else
- success = false;
-
- return value;
-}
-
-void
-EmulationStateARM::ClearPseudoRegisters ()
-{
- for (int i = 0; i < 17; ++i)
- m_gpr[i] = 0;
-
- for (int i = 0; i < 32; ++i)
- m_vfp_regs.s_regs[i] = 0;
-
- for (int i = 0; i < 16; ++i)
- m_vfp_regs.d_regs[i] = 0;
+ value = m_vfp_regs.d_regs[idx - 16];
+ } else
+ success = false;
+
+ return value;
}
-void
-EmulationStateARM::ClearPseudoMemory ()
-{
- m_memory.clear();
+void EmulationStateARM::ClearPseudoRegisters() {
+ for (int i = 0; i < 17; ++i)
+ m_gpr[i] = 0;
+
+ for (int i = 0; i < 32; ++i)
+ m_vfp_regs.s_regs[i] = 0;
+
+ for (int i = 0; i < 16; ++i)
+ m_vfp_regs.d_regs[i] = 0;
}
-
-bool
-EmulationStateARM::StoreToPseudoAddress (lldb::addr_t p_address, uint32_t value)
-{
- m_memory[p_address] = value;
- return true;
+
+void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
+
+bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
+ uint32_t value) {
+ m_memory[p_address] = value;
+ return true;
}
-
-uint32_t
-EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, bool &success)
-{
- std::map<lldb::addr_t,uint32_t>::iterator pos;
- uint32_t ret_val = 0;
-
- success = true;
- pos = m_memory.find(p_address);
- if (pos != m_memory.end())
- ret_val = pos->second;
- else
- success = false;
-
- return ret_val;
+
+uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address,
+ bool &success) {
+ std::map<lldb::addr_t, uint32_t>::iterator pos;
+ uint32_t ret_val = 0;
+
+ success = true;
+ pos = m_memory.find(p_address);
+ if (pos != m_memory.end())
+ ret_val = pos->second;
+ else
+ success = false;
+
+ return ret_val;
}
-size_t
-EmulationStateARM::ReadPseudoMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length)
-{
- if (!baton)
- return 0;
-
- bool success = true;
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
- if (length <= 4)
- {
- uint32_t value = pseudo_state->ReadFromPseudoAddress (addr, success);
- if (!success)
- return 0;
-
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- value = llvm::ByteSwap_32 (value);
- *((uint32_t *) dst) = value;
- }
- else if (length == 8)
- {
- uint32_t value1 = pseudo_state->ReadFromPseudoAddress (addr, success);
- if (!success)
- return 0;
-
- uint32_t value2 = pseudo_state->ReadFromPseudoAddress (addr + 4, success);
- if (!success)
- return 0;
-
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- {
- value1 = llvm::ByteSwap_32 (value1);
- value2 = llvm::ByteSwap_32 (value2);
- }
- ((uint32_t *) dst)[0] = value1;
- ((uint32_t *) dst)[1] = value2;
- }
- else
- success = false;
-
- if (success)
- return length;
-
+size_t EmulationStateARM::ReadPseudoMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
+ size_t length) {
+ if (!baton)
return 0;
-}
-
-size_t
-EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length)
-{
- if (!baton)
- return 0;
-
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
-
- if (length <= 4)
- {
- uint32_t value = *((const uint32_t *) dst);
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- value = llvm::ByteSwap_32 (value);
-
- pseudo_state->StoreToPseudoAddress (addr, value);
- return length;
- }
- else if (length == 8)
- {
- uint32_t value1 = ((const uint32_t *) dst)[0];
- uint32_t value2 = ((const uint32_t *) dst)[1];
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- {
- value1 = llvm::ByteSwap_32 (value1);
- value2 = llvm::ByteSwap_32 (value2);
- }
-
- pseudo_state->StoreToPseudoAddress (addr, value1);
- pseudo_state->StoreToPseudoAddress (addr + 4, value2);
- return length;
+
+ bool success = true;
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+ if (length <= 4) {
+ uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
+ if (!success)
+ return 0;
+
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ value = llvm::ByteSwap_32(value);
+ *((uint32_t *)dst) = value;
+ } else if (length == 8) {
+ uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
+ if (!success)
+ return 0;
+
+ uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
+ if (!success)
+ return 0;
+
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
+ value1 = llvm::ByteSwap_32(value1);
+ value2 = llvm::ByteSwap_32(value2);
}
+ ((uint32_t *)dst)[0] = value1;
+ ((uint32_t *)dst)[1] = value2;
+ } else
+ success = false;
+
+ if (success)
+ return length;
+
+ return 0;
+}
+size_t EmulationStateARM::WritePseudoMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr,
+ const void *dst, size_t length) {
+ if (!baton)
return 0;
+
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+
+ if (length <= 4) {
+ uint32_t value = *((const uint32_t *)dst);
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ value = llvm::ByteSwap_32(value);
+
+ pseudo_state->StoreToPseudoAddress(addr, value);
+ return length;
+ } else if (length == 8) {
+ uint32_t value1 = ((const uint32_t *)dst)[0];
+ uint32_t value2 = ((const uint32_t *)dst)[1];
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
+ value1 = llvm::ByteSwap_32(value1);
+ value2 = llvm::ByteSwap_32(value2);
+ }
+
+ pseudo_state->StoreToPseudoAddress(addr, value1);
+ pseudo_state->StoreToPseudoAddress(addr + 4, value2);
+ return length;
+ }
+
+ return 0;
}
-
-bool
-EmulationStateARM::ReadPseudoRegister (EmulateInstruction *instruction,
- void *baton,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value)
-{
- if (!baton || !reg_info)
- return false;
-
- bool success = true;
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
- const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
- assert (dwarf_reg_num != LLDB_INVALID_REGNUM);
- uint64_t reg_uval = pseudo_state->ReadPseudoRegisterValue (dwarf_reg_num, success);
-
- if (success)
- success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
- return success;
-
+
+bool EmulationStateARM::ReadPseudoRegister(
+ EmulateInstruction *instruction, void *baton,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) {
+ if (!baton || !reg_info)
+ return false;
+
+ bool success = true;
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+ const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
+ assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
+ uint64_t reg_uval =
+ pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
+
+ if (success)
+ success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
+ return success;
}
-
-bool
-EmulationStateARM::WritePseudoRegister (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value)
-{
- if (!baton || !reg_info)
- return false;
- EmulationStateARM *pseudo_state = (EmulationStateARM *) baton;
- const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
- assert (dwarf_reg_num != LLDB_INVALID_REGNUM);
- return pseudo_state->StorePseudoRegisterValue (dwarf_reg_num, reg_value.GetAsUInt64());
+bool EmulationStateARM::WritePseudoRegister(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) {
+ if (!baton || !reg_info)
+ return false;
+
+ EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
+ const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
+ assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
+ return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
+ reg_value.GetAsUInt64());
}
-
-bool
-EmulationStateARM::CompareState (EmulationStateARM &other_state)
-{
- bool match = true;
-
- for (int i = 0; match && i < 17; ++i)
- {
- if (m_gpr[i] != other_state.m_gpr[i])
- match = false;
- }
-
- for (int i = 0; match && i < 32; ++i)
- {
- if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
- match = false;
- }
-
- for (int i = 0; match && i < 16; ++i)
- {
- if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
- match = false;
- }
-
- return match;
+
+bool EmulationStateARM::CompareState(EmulationStateARM &other_state) {
+ bool match = true;
+
+ for (int i = 0; match && i < 17; ++i) {
+ if (m_gpr[i] != other_state.m_gpr[i])
+ match = false;
+ }
+
+ for (int i = 0; match && i < 32; ++i) {
+ if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
+ match = false;
+ }
+
+ for (int i = 0; match && i < 16; ++i) {
+ if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
+ match = false;
+ }
+
+ return match;
}
-bool
-EmulationStateARM::LoadStateFromDictionary (OptionValueDictionary *test_data)
-{
- static ConstString memory_key ("memory");
- static ConstString registers_key ("registers");
-
- if (!test_data)
+bool EmulationStateARM::LoadStateFromDictionary(
+ OptionValueDictionary *test_data) {
+ static ConstString memory_key("memory");
+ static ConstString registers_key("registers");
+
+ if (!test_data)
+ return false;
+
+ OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
+
+ // Load memory, if present.
+
+ if (value_sp.get() != NULL) {
+ static ConstString address_key("address");
+ static ConstString data_key("data");
+ uint64_t start_address = 0;
+
+ OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
+ value_sp = mem_dict->GetValueForKey(address_key);
+ if (value_sp.get() == NULL)
+ return false;
+ else
+ start_address = value_sp->GetUInt64Value();
+
+ value_sp = mem_dict->GetValueForKey(data_key);
+ OptionValueArray *mem_array = value_sp->GetAsArray();
+ if (!mem_array)
+ return false;
+
+ uint32_t num_elts = mem_array->GetSize();
+ uint32_t address = (uint32_t)start_address;
+
+ for (uint32_t i = 0; i < num_elts; ++i) {
+ value_sp = mem_array->GetValueAtIndex(i);
+ if (value_sp.get() == NULL)
return false;
-
- OptionValueSP value_sp = test_data->GetValueForKey (memory_key);
-
- // Load memory, if present.
-
- if (value_sp.get() != NULL)
- {
- static ConstString address_key ("address");
- static ConstString data_key ("data");
- uint64_t start_address = 0;
-
- OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
- value_sp = mem_dict->GetValueForKey (address_key);
- if (value_sp.get() == NULL)
- return false;
- else
- start_address = value_sp->GetUInt64Value ();
-
- value_sp = mem_dict->GetValueForKey (data_key);
- OptionValueArray *mem_array = value_sp->GetAsArray();
- if (!mem_array)
- return false;
-
- uint32_t num_elts = mem_array->GetSize();
- uint32_t address = (uint32_t) start_address;
-
- for (uint32_t i = 0; i < num_elts; ++i)
- {
- value_sp = mem_array->GetValueAtIndex (i);
- if (value_sp.get() == NULL)
- return false;
- uint64_t value = value_sp->GetUInt64Value();
- StoreToPseudoAddress (address, value);
- address = address + 4;
- }
+ uint64_t value = value_sp->GetUInt64Value();
+ StoreToPseudoAddress(address, value);
+ address = address + 4;
}
-
- value_sp = test_data->GetValueForKey (registers_key);
+ }
+
+ value_sp = test_data->GetValueForKey(registers_key);
+ if (value_sp.get() == NULL)
+ return false;
+
+ // Load General Registers
+
+ OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
+
+ StreamString sstr;
+ for (int i = 0; i < 16; ++i) {
+ sstr.Clear();
+ sstr.Printf("r%d", i);
+ ConstString reg_name(sstr.GetString());
+ value_sp = reg_dict->GetValueForKey(reg_name);
if (value_sp.get() == NULL)
- return false;
+ return false;
+ uint64_t reg_value = value_sp->GetUInt64Value();
+ StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
+ }
-
- // Load General Registers
-
- OptionValueDictionary *reg_dict = value_sp->GetAsDictionary ();
-
- StreamString sstr;
- for (int i = 0; i < 16; ++i)
- {
- sstr.Clear();
- sstr.Printf ("r%d", i);
- ConstString reg_name (sstr.GetData());
- value_sp = reg_dict->GetValueForKey (reg_name);
- if (value_sp.get() == NULL)
- return false;
- uint64_t reg_value = value_sp->GetUInt64Value();
- StorePseudoRegisterValue (dwarf_r0 + i, reg_value);
- }
-
- static ConstString cpsr_name ("cpsr");
- value_sp = reg_dict->GetValueForKey (cpsr_name);
+ static ConstString cpsr_name("cpsr");
+ value_sp = reg_dict->GetValueForKey(cpsr_name);
+ if (value_sp.get() == NULL)
+ return false;
+ StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
+
+ // Load s/d Registers
+ for (int i = 0; i < 32; ++i) {
+ sstr.Clear();
+ sstr.Printf("s%d", i);
+ ConstString reg_name(sstr.GetString());
+ value_sp = reg_dict->GetValueForKey(reg_name);
if (value_sp.get() == NULL)
- return false;
- StorePseudoRegisterValue (dwarf_cpsr, value_sp->GetUInt64Value());
-
- // Load s/d Registers
- for (int i = 0; i < 32; ++i)
- {
- sstr.Clear();
- sstr.Printf ("s%d", i);
- ConstString reg_name (sstr.GetData());
- value_sp = reg_dict->GetValueForKey (reg_name);
- if (value_sp.get() == NULL)
- return false;
- uint64_t reg_value = value_sp->GetUInt64Value();
- StorePseudoRegisterValue (dwarf_s0 + i, reg_value);
- }
+ return false;
+ uint64_t reg_value = value_sp->GetUInt64Value();
+ StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
+ }
- return true;
+ return true;
}
-
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.h b/source/Plugins/Instruction/ARM/EmulationStateARM.h
index e82ef94b5a01..f27f4755a177 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -16,81 +16,65 @@
#include "lldb/Core/Opcode.h"
class EmulationStateARM {
-public:
-
- EmulationStateARM ();
-
- virtual
- ~EmulationStateARM ();
-
- bool
- StorePseudoRegisterValue (uint32_t reg_num, uint64_t value);
-
- uint64_t
- ReadPseudoRegisterValue (uint32_t reg_num, bool &success);
-
- bool
- StoreToPseudoAddress (lldb::addr_t p_address, uint32_t value);
-
- uint32_t
- ReadFromPseudoAddress (lldb::addr_t p_address, bool &success);
-
- void
- ClearPseudoRegisters ();
-
- void
- ClearPseudoMemory ();
-
- bool
- LoadPseudoRegistersFromFrame (lldb_private::StackFrame &frame);
-
- bool
- LoadStateFromDictionary (lldb_private::OptionValueDictionary *test_data);
-
- bool
- CompareState (EmulationStateARM &other_state);
-
- static size_t
- ReadPseudoMemory (lldb_private::EmulateInstruction *instruction,
+public:
+ EmulationStateARM();
+
+ virtual ~EmulationStateARM();
+
+ bool StorePseudoRegisterValue(uint32_t reg_num, uint64_t value);
+
+ uint64_t ReadPseudoRegisterValue(uint32_t reg_num, bool &success);
+
+ bool StoreToPseudoAddress(lldb::addr_t p_address, uint32_t value);
+
+ uint32_t ReadFromPseudoAddress(lldb::addr_t p_address, bool &success);
+
+ void ClearPseudoRegisters();
+
+ void ClearPseudoMemory();
+
+ bool LoadPseudoRegistersFromFrame(lldb_private::StackFrame &frame);
+
+ bool LoadStateFromDictionary(lldb_private::OptionValueDictionary *test_data);
+
+ bool CompareState(EmulationStateARM &other_state);
+
+ static size_t
+ ReadPseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length);
+
+ static size_t
+ WritePseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t length);
+
+ static bool ReadPseudoRegister(lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value);
+
+ static bool
+ WritePseudoRegister(lldb_private::EmulateInstruction *instruction,
void *baton,
const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length);
-
- static size_t
- WritePseudoMemory (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length);
-
- static bool
- ReadPseudoRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value);
-
- static bool
- WritePseudoRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value);
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value);
+
private:
- uint32_t m_gpr[17];
- struct _sd_regs
- {
- uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
-
- uint64_t d_regs[16]; // dregs 16-31
-
- } m_vfp_regs;
-
- std::map<lldb::addr_t, uint32_t> m_memory; // Eventually will want to change uint32_t to a data buffer heap type.
-
- DISALLOW_COPY_AND_ASSIGN (EmulationStateARM);
+ uint32_t m_gpr[17];
+ struct _sd_regs {
+ uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
+
+ uint64_t d_regs[16]; // dregs 16-31
+
+ } m_vfp_regs;
+
+ std::map<lldb::addr_t, uint32_t> m_memory; // Eventually will want to change
+ // uint32_t to a data buffer heap
+ // type.
+
+ DISALLOW_COPY_AND_ASSIGN(EmulationStateARM);
};
-#endif // lldb_EmulationStateARM_h_
+#endif // lldb_EmulationStateARM_h_
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index ea67928280d3..43f23097c0d9 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstructionARM64.cpp -------------------------------*- C++ -*-===//
+//===-- EmulateInstructionARM64.cpp ------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,8 +11,8 @@
#include <stdlib.h>
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Address.h"
+#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
@@ -20,7 +20,24 @@
#include "Plugins/Process/Utility/ARMDefines.h"
#include "Plugins/Process/Utility/ARMUtils.h"
-#include "Utility/ARM64_DWARF_Registers.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+
+#define GPR_OFFSET(idx) ((idx)*8)
+#define GPR_OFFSET_NAME(reg) 0
+#define FPU_OFFSET(idx) ((idx)*16)
+#define FPU_OFFSET_NAME(reg) 0
+#define EXC_OFFSET_NAME(reg) 0
+#define DBG_OFFSET_NAME(reg) 0
+#define DBG_OFFSET_NAME(reg) 0
+#define DEFINE_DBG(re, y) \
+ "na", nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, \
+ nullptr, nullptr, nullptr, 0
+
+#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+#include "Plugins/Process/Utility/RegisterInfos_arm64.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
@@ -31,15 +48,22 @@
using namespace lldb;
using namespace lldb_private;
-#define No_VFP 0
-#define VFPv1 (1u << 1)
-#define VFPv2 (1u << 2)
-#define VFPv3 (1u << 3)
+static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo &reg_info) {
+ if (reg_num >= llvm::array_lengthof(g_register_infos_arm64_le))
+ return false;
+ reg_info = g_register_infos_arm64_le[reg_num];
+ return true;
+}
+
+#define No_VFP 0
+#define VFPv1 (1u << 1)
+#define VFPv2 (1u << 2)
+#define VFPv3 (1u << 3)
#define AdvancedSIMD (1u << 4)
#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
-#define VFPv2v3 (VFPv2 | VFPv3)
+#define VFPv2v3 (VFPv2 | VFPv3)
#define UInt(x) ((uint64_t)x)
#define SInt(x) ((int64_t)x)
@@ -47,17 +71,9 @@ using namespace lldb_private;
#define boolean bool
#define integer int64_t
-static inline bool
-IsZero(uint64_t x)
-{
- return x == 0;
-}
+static inline bool IsZero(uint64_t x) { return x == 0; }
-static inline uint64_t
-NOT(uint64_t x)
-{
- return ~x;
-}
+static inline uint64_t NOT(uint64_t x) { return ~x; }
#if 0
// LSL_C()
@@ -75,354 +91,435 @@ LSL_C (uint64_t x, integer shift, bool &carry_out)
// LSL()
// =====
-static inline uint64_t
-LSL(uint64_t x, integer shift)
-{
- if (shift == 0)
- return x;
- return x << shift;
+static inline uint64_t LSL(uint64_t x, integer shift) {
+ if (shift == 0)
+ return x;
+ return x << shift;
}
// AddWithCarry()
// ===============
static inline uint64_t
-AddWithCarry (uint32_t N, uint64_t x, uint64_t y, bit carry_in, EmulateInstructionARM64::ProcState &proc_state)
-{
- uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
- int64_t signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
- uint64_t result = unsigned_sum;
- if (N < 64)
- result = Bits64 (result, N-1, 0);
- proc_state.N = Bit64(result, N-1);
- proc_state.Z = IsZero(result);
- proc_state.C = UInt(result) == unsigned_sum;
- proc_state.V = SInt(result) == signed_sum;
- return result;
+AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in,
+ EmulateInstructionARM64::ProcState &proc_state) {
+ uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
+ int64_t signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
+ uint64_t result = unsigned_sum;
+ if (N < 64)
+ result = Bits64(result, N - 1, 0);
+ proc_state.N = Bit64(result, N - 1);
+ proc_state.Z = IsZero(result);
+ proc_state.C = UInt(result) == unsigned_sum;
+ proc_state.V = SInt(result) == signed_sum;
+ return result;
}
// ConstrainUnpredictable()
// ========================
EmulateInstructionARM64::ConstraintType
-ConstrainUnpredictable (EmulateInstructionARM64::Unpredictable which)
-{
- EmulateInstructionARM64::ConstraintType result = EmulateInstructionARM64::Constraint_UNKNOWN;
- switch (which)
- {
- case EmulateInstructionARM64::Unpredictable_WBOVERLAP:
- case EmulateInstructionARM64::Unpredictable_LDPOVERLAP:
- // TODO: don't know what to really do here? Pseudo code says:
- // set result to one of above Constraint behaviours or UNDEFINED
- break;
- }
- return result;
+ConstrainUnpredictable(EmulateInstructionARM64::Unpredictable which) {
+ EmulateInstructionARM64::ConstraintType result =
+ EmulateInstructionARM64::Constraint_UNKNOWN;
+ switch (which) {
+ case EmulateInstructionARM64::Unpredictable_WBOVERLAP:
+ case EmulateInstructionARM64::Unpredictable_LDPOVERLAP:
+ // TODO: don't know what to really do here? Pseudo code says:
+ // set result to one of above Constraint behaviours or UNDEFINED
+ break;
+ }
+ return result;
}
-
-
//----------------------------------------------------------------------
//
// EmulateInstructionARM implementation
//
//----------------------------------------------------------------------
-void
-EmulateInstructionARM64::Initialize ()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic (),
- GetPluginDescriptionStatic (),
- CreateInstance);
+void EmulateInstructionARM64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-EmulateInstructionARM64::Terminate ()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void EmulateInstructionARM64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-ConstString
-EmulateInstructionARM64::GetPluginNameStatic ()
-{
- ConstString g_plugin_name ("lldb.emulate-instruction.arm64");
- return g_plugin_name;
+ConstString EmulateInstructionARM64::GetPluginNameStatic() {
+ ConstString g_plugin_name("lldb.emulate-instruction.arm64");
+ return g_plugin_name;
}
-lldb_private::ConstString
-EmulateInstructionARM64::GetPluginName()
-{
- static ConstString g_plugin_name ("EmulateInstructionARM64");
- return g_plugin_name;
+lldb_private::ConstString EmulateInstructionARM64::GetPluginName() {
+ static ConstString g_plugin_name("EmulateInstructionARM64");
+ return g_plugin_name;
}
-const char *
-EmulateInstructionARM64::GetPluginDescriptionStatic ()
-{
- return "Emulate instructions for the ARM64 architecture.";
+const char *EmulateInstructionARM64::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the ARM64 architecture.";
}
EmulateInstruction *
-EmulateInstructionARM64::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
-{
- if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
- {
- if (arch.GetTriple().getArch() == llvm::Triple::aarch64)
- {
- std::auto_ptr<EmulateInstructionARM64> emulate_insn_ap (new EmulateInstructionARM64 (arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
+EmulateInstructionARM64::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ std::auto_ptr<EmulateInstructionARM64> emulate_insn_ap(
+ new EmulateInstructionARM64(arch));
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
}
-
- return NULL;
+ }
+
+ return NULL;
}
-bool
-EmulateInstructionARM64::SetTargetTriple (const ArchSpec &arch)
-{
- if (arch.GetTriple().getArch () == llvm::Triple::arm)
- return true;
- else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
- return true;
+bool EmulateInstructionARM64::SetTargetTriple(const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::arm)
+ return true;
+ else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
+ return true;
- return false;
+ return false;
}
-bool
-EmulateInstructionARM64::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
-{
- if (reg_kind == eRegisterKindGeneric)
- {
- switch (reg_num)
- {
- case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::pc; break;
- case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::sp; break;
- case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::fp; break;
- case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::lr; break;
- case LLDB_REGNUM_GENERIC_FLAGS:
- // There is no DWARF register number for the CPSR right now...
- reg_info.name = "cpsr";
- reg_info.alt_name = NULL;
- reg_info.byte_size = 4;
- reg_info.byte_offset = 0;
- reg_info.encoding = eEncodingUint;
- reg_info.format = eFormatHex;
- for (uint32_t i=0; i<lldb::kNumRegisterKinds; ++i)
- reg_info.kinds[reg_kind] = LLDB_INVALID_REGNUM;
- reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- return true;
-
- default: return false;
- }
+bool EmulateInstructionARM64::GetRegisterInfo(RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_pc_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_sp_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_fp_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_lr_arm64;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindLLDB;
+ reg_num = gpr_cpsr_arm64;
+ break;
+
+ default:
+ return false;
}
-
- if (reg_kind == eRegisterKindDWARF)
- return arm64_dwarf::GetRegisterInfo(reg_num, reg_info);
- return false;
+ }
+
+ if (reg_kind == eRegisterKindLLDB)
+ return LLDBTableGetRegisterInfo(reg_num, reg_info);
+ return false;
}
-EmulateInstructionARM64::Opcode*
-EmulateInstructionARM64::GetOpcodeForInstruction (const uint32_t opcode)
-{
- static EmulateInstructionARM64::Opcode
- g_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue instructions
- //----------------------------------------------------------------------
-
- // push register(s)
- { 0xff000000, 0xd1000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUB <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}" },
- { 0xff000000, 0xf1000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUBS <Xd>, <Xn|SP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x91000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADD <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}" },
- { 0xff000000, 0xb1000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADDS <Xd>, <Xn|SP>, #<imm> {, <shift>}" },
-
- { 0xff000000, 0x51000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUB <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x71000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x11000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADD <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}" },
- { 0xff000000, 0x31000000, No_VFP, &EmulateInstructionARM64::EmulateADDSUBImm, "ADDS <Wd>, <Wn|WSP>, #<imm> {, <shift>}" },
-
- { 0xffc00000, 0x29000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xa9000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x2d000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <St>, <St2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x6d000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xad000000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]" },
-
- { 0xffc00000, 0x29800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa9800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2d800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6d800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xad800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffc00000, 0x28800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa8800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2c800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6c800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xac800000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffc00000, 0x29400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xa9400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x2d400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <St>, <St2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0x6d400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]" },
- { 0xffc00000, 0xad400000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>, "LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]" },
-
- { 0xffc00000, 0x29c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa9c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2dc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6dc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xadc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>, "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffc00000, 0x28c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xa8c00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x2cc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0x6cc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
- { 0xffc00000, 0xacc00000, No_VFP, &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>, "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
-
- { 0xffe00c00, 0xb8000400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "STR <Wt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xf8000400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "STR <Xt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xb8000c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "STR <Wt>, [<Xn|SP>, #<simm>]!" },
- { 0xffe00c00, 0xf8000c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "STR <Xt>, [<Xn|SP>, #<simm>]!" },
- { 0xffc00000, 0xb9000000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "STR <Wt>, [<Xn|SP>{, #<pimm>}]" },
- { 0xffc00000, 0xf9000000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "STR <Xt>, [<Xn|SP>{, #<pimm>}]" },
-
- { 0xffe00c00, 0xb8400400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "LDR <Wt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xf8400400, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>, "LDR <Xt>, [<Xn|SP>], #<simm>" },
- { 0xffe00c00, 0xb8400c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "LDR <Wt>, [<Xn|SP>, #<simm>]!" },
- { 0xffe00c00, 0xf8400c00, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>, "LDR <Xt>, [<Xn|SP>, #<simm>]!" },
- { 0xffc00000, 0xb9400000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "LDR <Wt>, [<Xn|SP>{, #<pimm>}]" },
- { 0xffc00000, 0xf9400000, No_VFP, &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>, "LDR <Xt>, [<Xn|SP>{, #<pimm>}]" },
-
- { 0xfc000000, 0x14000000, No_VFP, &EmulateInstructionARM64::EmulateB, "B <label>" },
- { 0xff000010, 0x54000000, No_VFP, &EmulateInstructionARM64::EmulateBcond, "B.<cond> <label>" },
- { 0x7f000000, 0x34000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ, "CBZ <Wt>, <label>" },
- { 0x7f000000, 0x35000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ, "CBNZ <Wt>, <label>" },
- { 0x7f000000, 0x36000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ, "TBZ <R><t>, #<imm>, <label>" },
- { 0x7f000000, 0x37000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ, "TBNZ <R><t>, #<imm>, <label>" },
-
- };
- static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_opcodes);
-
- for (size_t i=0; i<k_num_arm_opcodes; ++i)
- {
- if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
- return &g_opcodes[i];
- }
- return nullptr;
+EmulateInstructionARM64::Opcode *
+EmulateInstructionARM64::GetOpcodeForInstruction(const uint32_t opcode) {
+ static EmulateInstructionARM64::Opcode g_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue instructions
+ //----------------------------------------------------------------------
+
+ // push register(s)
+ {0xff000000, 0xd1000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUB <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
+ {0xff000000, 0xf1000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUBS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x91000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADD <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
+ {0xff000000, 0xb1000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADDS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
+
+ {0xff000000, 0x51000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUB <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x71000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x11000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADD <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
+ {0xff000000, 0x31000000, No_VFP,
+ &EmulateInstructionARM64::EmulateADDSUBImm,
+ "ADDS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
+
+ {0xffc00000, 0x29000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xa9000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x2d000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x6d000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xad000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
+
+ {0xffc00000, 0x29800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa9800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2d800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6d800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xad800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffc00000, 0x28800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa8800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2c800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6c800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xac800000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffc00000, 0x29400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xa9400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x2d400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0x6d400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
+ {0xffc00000, 0xad400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
+ "LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
+
+ {0xffc00000, 0x29c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa9c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2dc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6dc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xadc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
+ "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffc00000, 0x28c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xa8c00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x2cc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0x6cc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
+ {0xffc00000, 0xacc00000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
+ "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
+
+ {0xffe00c00, 0xb8000400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "STR <Wt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xf8000400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "STR <Xt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xb8000c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "STR <Wt>, [<Xn|SP>, #<simm>]!"},
+ {0xffe00c00, 0xf8000c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "STR <Xt>, [<Xn|SP>, #<simm>]!"},
+ {0xffc00000, 0xb9000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "STR <Wt>, [<Xn|SP>{, #<pimm>}]"},
+ {0xffc00000, 0xf9000000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "STR <Xt>, [<Xn|SP>{, #<pimm>}]"},
+
+ {0xffe00c00, 0xb8400400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "LDR <Wt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xf8400400, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
+ "LDR <Xt>, [<Xn|SP>], #<simm>"},
+ {0xffe00c00, 0xb8400c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "LDR <Wt>, [<Xn|SP>, #<simm>]!"},
+ {0xffe00c00, 0xf8400c00, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
+ "LDR <Xt>, [<Xn|SP>, #<simm>]!"},
+ {0xffc00000, 0xb9400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "LDR <Wt>, [<Xn|SP>{, #<pimm>}]"},
+ {0xffc00000, 0xf9400000, No_VFP,
+ &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
+ "LDR <Xt>, [<Xn|SP>{, #<pimm>}]"},
+
+ {0xfc000000, 0x14000000, No_VFP, &EmulateInstructionARM64::EmulateB,
+ "B <label>"},
+ {0xff000010, 0x54000000, No_VFP, &EmulateInstructionARM64::EmulateBcond,
+ "B.<cond> <label>"},
+ {0x7f000000, 0x34000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
+ "CBZ <Wt>, <label>"},
+ {0x7f000000, 0x35000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
+ "CBNZ <Wt>, <label>"},
+ {0x7f000000, 0x36000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
+ "TBZ <R><t>, #<imm>, <label>"},
+ {0x7f000000, 0x37000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
+ "TBNZ <R><t>, #<imm>, <label>"},
+
+ };
+ static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_opcodes);
+
+ for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
+ if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
+ return &g_opcodes[i];
+ }
+ return nullptr;
}
-bool
-EmulateInstructionARM64::ReadInstruction ()
-{
- bool success = false;
- m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
- m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
- }
- if (!success)
- m_addr = LLDB_INVALID_ADDRESS;
- return success;
+bool EmulateInstructionARM64::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+ m_opcode.SetOpcode32(
+ ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
+ GetByteOrder());
+ }
+ if (!success)
+ m_addr = LLDB_INVALID_ADDRESS;
+ return success;
}
+bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) {
+ const uint32_t opcode = m_opcode.GetOpcode32();
+ Opcode *opcode_data = GetOpcodeForInstruction(opcode);
+ if (opcode_data == NULL)
+ return false;
-bool
-EmulateInstructionARM64::EvaluateInstruction (uint32_t evaluate_options)
-{
- const uint32_t opcode = m_opcode.GetOpcode32();
- Opcode *opcode_data = GetOpcodeForInstruction(opcode);
- if (opcode_data == NULL)
- return false;
-
- //printf ("opcode template for 0x%8.8x: %s\n", opcode, opcode_data->name);
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
-
- bool success = false;
-// if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
-// {
-// m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, // use eRegisterKindDWARF is we ever get a cpsr DWARF register number
-// LLDB_REGNUM_GENERIC_FLAGS, // use arm64_dwarf::cpsr if we ever get one
-// 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)
- return false;
-
- uint32_t orig_pc_value = 0;
- if (auto_advance_pc)
- {
- orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
- if (!success)
- return false;
- }
-
- // Call the Emulate... function.
- success = (this->*opcode_data->callback) (opcode);
+ // printf ("opcode template for 0x%8.8x: %s\n", opcode, opcode_data->name);
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ m_ignore_conditions =
+ evaluate_options & eEmulateInstructionOptionIgnoreConditions;
+
+ bool success = false;
+ // if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
+ // {
+ // m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindLLDB,
+ // gpr_cpsr_arm64,
+ // 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)
+ return false;
+
+ uint32_t orig_pc_value = 0;
+ if (auto_advance_pc) {
+ orig_pc_value =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
if (!success)
+ return false;
+ }
+
+ // Call the Emulate... function.
+ success = (this->*opcode_data->callback)(opcode);
+ if (!success)
+ return false;
+
+ if (auto_advance_pc) {
+ uint32_t new_pc_value =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
+ if (!success)
+ return false;
+
+ if (auto_advance_pc && (new_pc_value == orig_pc_value)) {
+ EmulateInstruction::Context context;
+ context.type = eContextAdvancePC;
+ context.SetNoArgs();
+ if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_pc_arm64,
+ orig_pc_value + 4))
return false;
-
- if (auto_advance_pc)
- {
- uint32_t new_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
- if (!success)
- return false;
-
- if (auto_advance_pc && (new_pc_value == orig_pc_value))
- {
- EmulateInstruction::Context context;
- context.type = eContextAdvancePC;
- context.SetNoArgs();
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::pc, orig_pc_value + 4))
- return false;
- }
}
- return true;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool EmulateInstructionARM64::CreateFunctionEntryUnwind(
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, 0);
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_arm64, 0);
- unwind_plan.AppendRow (row);
- unwind_plan.SetSourceName ("EmulateInstructionARM64");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (arm64_dwarf::lr);
- return true;
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("EmulateInstructionARM64");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(gpr_lr_arm64);
+ return true;
}
-uint32_t
-EmulateInstructionARM64::GetFramePointerRegisterNumber () const
-{
- if (m_arch.GetTriple().isAndroid())
- return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
+uint32_t EmulateInstructionARM64::GetFramePointerRegisterNumber() const {
+ if (m_arch.GetTriple().isAndroid())
+ return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
- return arm64_dwarf::sp;
+ return gpr_fp_arm64;
}
-bool
-EmulateInstructionARM64::UsingAArch32()
-{
- bool aarch32 = m_opcode_pstate.RW == 1;
- // if !HaveAnyAArch32() then assert !aarch32;
- // if HighestELUsingAArch32() then assert aarch32;
- return aarch32;
+bool EmulateInstructionARM64::UsingAArch32() {
+ bool aarch32 = m_opcode_pstate.RW == 1;
+ // if !HaveAnyAArch32() then assert !aarch32;
+ // if HighestELUsingAArch32() then assert aarch32;
+ return aarch32;
}
-bool
-EmulateInstructionARM64::BranchTo (const Context &context, uint32_t N, addr_t target)
-{
+bool EmulateInstructionARM64::BranchTo(const Context &context, uint32_t N,
+ addr_t target) {
#if 0
// Set program counter to a new address, with a branch reason hint
// for possible use by hardware fetching the next instruction.
@@ -450,603 +547,578 @@ EmulateInstructionARM64::BranchTo (const Context &context, uint32_t N, addr_t ta
return;
#endif
- addr_t addr;
+ addr_t addr;
+
+ // Hint_Branch(branch_type);
+ if (N == 32) {
+ if (!UsingAArch32())
+ return false;
+ addr = target;
+ } else if (N == 64) {
+ if (UsingAArch32())
+ return false;
+ // TODO: Remove the tag bits from a tagged target
+ addr = target;
+ } else
+ return false;
- //Hint_Branch(branch_type);
- if (N == 32)
- {
- if (!UsingAArch32())
- return false;
- addr = target;
- }
- else if (N == 64)
- {
- if (UsingAArch32())
- return false;
- // TODO: Remove the tag bits from a tagged target
- addr = target;
- }
- else
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, addr))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, addr))
- return false;
+ return true;
+}
+bool EmulateInstructionARM64::ConditionHolds(const uint32_t cond) {
+ // If we are ignoring conditions, then always return true.
+ // this allows us to iterate over disassembly code and still
+ // emulate an instruction even if we don't have all the right
+ // bits set in the CPSR register...
+ if (m_ignore_conditions)
return true;
-}
-bool
-EmulateInstructionARM64::ConditionHolds (const uint32_t cond)
-{
- // If we are ignoring conditions, then always return true.
- // this allows us to iterate over disassembly code and still
- // emulate an instruction even if we don't have all the right
- // bits set in the CPSR register...
- if (m_ignore_conditions)
- return true;
-
- bool result = false;
- switch (UnsignedBits(cond, 3, 1))
- {
- case 0:
- result = (m_opcode_pstate.Z == 1);
- break;
- case 1:
- result = (m_opcode_pstate.C == 1);
- break;
- case 2:
- result = (m_opcode_pstate.N == 1);
- break;
- case 3:
- result = (m_opcode_pstate.V == 1);
- break;
- case 4:
- result = (m_opcode_pstate.C == 1 && m_opcode_pstate.Z == 0);
- break;
- case 5:
- result = (m_opcode_pstate.N == m_opcode_pstate.V);
- break;
- case 6:
- result = (m_opcode_pstate.N == m_opcode_pstate.V && m_opcode_pstate.Z == 0);
- break;
- case 7:
- // Always execute (cond == 0b1110, or the special 0b1111 which gives
- // opcodes different meanings, but always means execution happens.
- return true;
- }
+ bool result = false;
+ switch (UnsignedBits(cond, 3, 1)) {
+ case 0:
+ result = (m_opcode_pstate.Z == 1);
+ break;
+ case 1:
+ result = (m_opcode_pstate.C == 1);
+ break;
+ case 2:
+ result = (m_opcode_pstate.N == 1);
+ break;
+ case 3:
+ result = (m_opcode_pstate.V == 1);
+ break;
+ case 4:
+ result = (m_opcode_pstate.C == 1 && m_opcode_pstate.Z == 0);
+ break;
+ case 5:
+ result = (m_opcode_pstate.N == m_opcode_pstate.V);
+ break;
+ case 6:
+ result = (m_opcode_pstate.N == m_opcode_pstate.V && m_opcode_pstate.Z == 0);
+ break;
+ case 7:
+ // Always execute (cond == 0b1110, or the special 0b1111 which gives
+ // opcodes different meanings, but always means execution happens.
+ return true;
+ }
- if (cond & 1)
- result = !result;
- return result;
+ if (cond & 1)
+ result = !result;
+ return result;
}
-bool
-EmulateInstructionARM64::EmulateADDSUBImm (const uint32_t opcode)
-{
- // integer d = UInt(Rd);
- // integer n = UInt(Rn);
- // integer datasize = if sf == 1 then 64 else 32;
- // boolean sub_op = (op == 1);
- // boolean setflags = (S == 1);
- // bits(datasize) imm;
- //
- // case shift of
- // when '00' imm = ZeroExtend(imm12, datasize);
- // when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);
- // when '1x' UNDEFINED;
- //
- //
- // bits(datasize) result;
- // bits(datasize) operand1 = if n == 31 then SP[] else X[n];
- // bits(datasize) operand2 = imm;
- // bits(4) nzcv;
- // bit carry_in;
- //
- // if sub_op then
- // operand2 = NOT(operand2);
- // carry_in = 1;
- // else
- // carry_in = 0;
- //
- // (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);
- //
- // if setflags then
- // PSTATE.NZCV = nzcv;
- //
- // if d == 31 && !setflags then
- // SP[] = result;
- // else
- // X[d] = result;
-
- const uint32_t sf = Bit32(opcode, 31);
- const uint32_t op = Bit32(opcode, 30);
- const uint32_t S = Bit32(opcode, 29);
- const uint32_t shift = Bits32(opcode, 23, 22);
- const uint32_t imm12 = Bits32(opcode, 21, 10);
- const uint32_t Rn = Bits32(opcode, 9, 5);
- const uint32_t Rd = Bits32(opcode, 4, 0);
-
- bool success = false;
-
- const uint32_t d = UInt(Rd);
- const uint32_t n = UInt(Rn);
- const uint32_t datasize = (sf == 1) ? 64 : 32;
- boolean sub_op = op == 1;
- boolean setflags = S == 1;
- uint64_t imm;
-
- switch (shift)
- {
- case 0: imm = imm12; break;
- case 1: imm = imm12 << 12; break;
- default: return false; // UNDEFINED;
- }
- uint64_t result;
- uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
- uint64_t operand2 = imm;
- bit carry_in;
-
- if (sub_op)
- {
- operand2 = NOT(operand2);
- carry_in = 1;
- imm = -imm; // For the Register plug offset context below
- }
- else
- {
- carry_in = 0;
- }
-
- ProcState proc_state;
-
- result = AddWithCarry (datasize, operand1, operand2, carry_in, proc_state);
+bool EmulateInstructionARM64::EmulateADDSUBImm(const uint32_t opcode) {
+ // integer d = UInt(Rd);
+ // integer n = UInt(Rn);
+ // integer datasize = if sf == 1 then 64 else 32;
+ // boolean sub_op = (op == 1);
+ // boolean setflags = (S == 1);
+ // bits(datasize) imm;
+ //
+ // case shift of
+ // when '00' imm = ZeroExtend(imm12, datasize);
+ // when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);
+ // when '1x' UNDEFINED;
+ //
+ //
+ // bits(datasize) result;
+ // bits(datasize) operand1 = if n == 31 then SP[] else X[n];
+ // bits(datasize) operand2 = imm;
+ // bits(4) nzcv;
+ // bit carry_in;
+ //
+ // if sub_op then
+ // operand2 = NOT(operand2);
+ // carry_in = 1;
+ // else
+ // carry_in = 0;
+ //
+ // (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);
+ //
+ // if setflags then
+ // PSTATE.NZCV = nzcv;
+ //
+ // if d == 31 && !setflags then
+ // SP[] = result;
+ // else
+ // X[d] = result;
+
+ const uint32_t sf = Bit32(opcode, 31);
+ const uint32_t op = Bit32(opcode, 30);
+ const uint32_t S = Bit32(opcode, 29);
+ const uint32_t shift = Bits32(opcode, 23, 22);
+ const uint32_t imm12 = Bits32(opcode, 21, 10);
+ const uint32_t Rn = Bits32(opcode, 9, 5);
+ const uint32_t Rd = Bits32(opcode, 4, 0);
+
+ bool success = false;
+
+ const uint32_t d = UInt(Rd);
+ const uint32_t n = UInt(Rn);
+ const uint32_t datasize = (sf == 1) ? 64 : 32;
+ boolean sub_op = op == 1;
+ boolean setflags = S == 1;
+ uint64_t imm;
+
+ switch (shift) {
+ case 0:
+ imm = imm12;
+ break;
+ case 1:
+ imm = imm12 << 12;
+ break;
+ default:
+ return false; // UNDEFINED;
+ }
+ uint64_t result;
+ uint64_t operand1 =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
+ uint64_t operand2 = imm;
+ bit carry_in;
+
+ if (sub_op) {
+ operand2 = NOT(operand2);
+ carry_in = 1;
+ imm = -imm; // For the Register plug offset context below
+ } else {
+ carry_in = 0;
+ }
+
+ ProcState proc_state;
+
+ result = AddWithCarry(datasize, operand1, operand2, carry_in, proc_state);
+
+ if (setflags) {
+ m_emulated_pstate.N = proc_state.N;
+ m_emulated_pstate.Z = proc_state.Z;
+ m_emulated_pstate.C = proc_state.C;
+ m_emulated_pstate.V = proc_state.V;
+ }
+
+ Context context;
+ RegisterInfo reg_info_Rn;
+ if (GetRegisterInfo(eRegisterKindLLDB, n, reg_info_Rn))
+ context.SetRegisterPlusOffset(reg_info_Rn, imm);
+
+ if (n == GetFramePointerRegisterNumber() && d == gpr_sp_arm64 && !setflags) {
+ // 'mov sp, fp' - common epilogue instruction, CFA is now in terms
+ // of the stack pointer, instead of frame pointer.
+ context.type = EmulateInstruction::eContextRestoreStackPointer;
+ } else if ((n == gpr_sp_arm64 || n == GetFramePointerRegisterNumber()) &&
+ d == gpr_sp_arm64 && !setflags) {
+ context.type = EmulateInstruction::eContextAdjustStackPointer;
+ } else if (d == GetFramePointerRegisterNumber() && n == gpr_sp_arm64 &&
+ !setflags) {
+ context.type = EmulateInstruction::eContextSetFramePointer;
+ } else {
+ context.type = EmulateInstruction::eContextImmediate;
+ }
+
+ // If setflags && d == gpr_sp_arm64 then d = WZR/XZR. See CMN, CMP
+ if (!setflags || d != gpr_sp_arm64)
+ WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_x0_arm64 + d, result);
+
+ return false;
+}
- if (setflags)
- {
- m_emulated_pstate.N = proc_state.N;
- m_emulated_pstate.Z = proc_state.Z;
- m_emulated_pstate.C = proc_state.C;
- m_emulated_pstate.V = proc_state.V;
+template <EmulateInstructionARM64::AddrMode a_mode>
+bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) {
+ uint32_t opc = Bits32(opcode, 31, 30);
+ uint32_t V = Bit32(opcode, 26);
+ uint32_t L = Bit32(opcode, 22);
+ uint32_t imm7 = Bits32(opcode, 21, 15);
+ uint32_t Rt2 = Bits32(opcode, 14, 10);
+ uint32_t Rn = Bits32(opcode, 9, 5);
+ uint32_t Rt = Bits32(opcode, 4, 0);
+
+ integer n = UInt(Rn);
+ integer t = UInt(Rt);
+ integer t2 = UInt(Rt2);
+ uint64_t idx;
+
+ MemOp memop = L == 1 ? MemOp_LOAD : MemOp_STORE;
+ boolean vector = (V == 1);
+ // AccType acctype = AccType_NORMAL;
+ boolean is_signed = false;
+ boolean wback = a_mode != AddrMode_OFF;
+ boolean wb_unknown = false;
+ boolean rt_unknown = false;
+ integer scale;
+ integer size;
+
+ if (opc == 3)
+ return false; // UNDEFINED
+
+ if (vector) {
+ scale = 2 + UInt(opc);
+ } else {
+ scale = (opc & 2) ? 3 : 2;
+ is_signed = (opc & 1) != 0;
+ if (is_signed && memop == MemOp_STORE)
+ return false; // UNDEFINED
+ }
+
+ if (!vector && wback && ((t == n) || (t2 == n))) {
+ switch (ConstrainUnpredictable(Unpredictable_WBOVERLAP)) {
+ case Constraint_UNKNOWN:
+ wb_unknown = true; // writeback is UNKNOWN
+ break;
+
+ case Constraint_SUPPRESSWB:
+ wback = false; // writeback is suppressed
+ break;
+
+ case Constraint_NOP:
+ memop = MemOp_NOP; // do nothing
+ wback = false;
+ break;
+
+ case Constraint_NONE:
+ break;
}
-
- Context context;
- RegisterInfo reg_info_Rn;
- if (arm64_dwarf::GetRegisterInfo (n, reg_info_Rn))
- context.SetRegisterPlusOffset (reg_info_Rn, imm);
+ }
- if ((n == arm64_dwarf::sp || n == GetFramePointerRegisterNumber()) &&
- d == arm64_dwarf::sp &&
- !setflags)
- {
- context.type = EmulateInstruction::eContextAdjustStackPointer;
- }
- else if (d == GetFramePointerRegisterNumber() &&
- n == arm64_dwarf::sp &&
- !setflags)
- {
- context.type = EmulateInstruction::eContextSetFramePointer;
- }
- else
- {
- context.type = EmulateInstruction::eContextImmediate;
+ if (memop == MemOp_LOAD && t == t2) {
+ switch (ConstrainUnpredictable(Unpredictable_LDPOVERLAP)) {
+ case Constraint_UNKNOWN:
+ rt_unknown = true; // result is UNKNOWN
+ break;
+
+ case Constraint_NOP:
+ memop = MemOp_NOP; // do nothing
+ wback = false;
+ break;
+
+ default:
+ break;
}
+ }
+
+ idx = LSL(llvm::SignExtend64<7>(imm7), scale);
+ size = (integer)1 << scale;
+ uint64_t datasize = size * 8;
+ uint64_t address;
+ uint64_t wb_address;
- // If setflags && d == arm64_dwarf::sp then d = WZR/XZR. See CMN, CMP
- if (!setflags || d != arm64_dwarf::sp)
- WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::x0 + d, result);
+ RegisterValue data_Rt;
+ RegisterValue data_Rt2;
+ // if (vector)
+ // CheckFPEnabled(false);
+
+ RegisterInfo reg_info_base;
+ RegisterInfo reg_info_Rt;
+ RegisterInfo reg_info_Rt2;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
return false;
-}
-template <EmulateInstructionARM64::AddrMode a_mode> bool
-EmulateInstructionARM64::EmulateLDPSTP (const uint32_t opcode)
-{
- uint32_t opc = Bits32(opcode, 31, 30);
- uint32_t V = Bit32(opcode, 26);
- uint32_t L = Bit32(opcode, 22);
- uint32_t imm7 = Bits32(opcode, 21, 15);
- uint32_t Rt2 = Bits32(opcode, 14, 10);
- uint32_t Rn = Bits32(opcode, 9, 5);
- uint32_t Rt = Bits32(opcode, 4, 0);
-
- integer n = UInt(Rn);
- integer t = UInt(Rt);
- integer t2 = UInt(Rt2);
- uint64_t idx;
-
- MemOp memop = L == 1 ? MemOp_LOAD : MemOp_STORE;
- boolean vector = (V == 1);
- //AccType acctype = AccType_NORMAL;
- boolean is_signed = false;
- boolean wback = a_mode != AddrMode_OFF;
- boolean wb_unknown = false;
- boolean rt_unknown = false;
- integer scale;
- integer size;
-
- if (opc == 3)
- return false; // UNDEFINED
-
- if (vector)
- {
- scale = 2 + UInt(opc);
- }
- else
+ if (vector) {
+ if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t, reg_info_Rt))
+ return false;
+ if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t2, reg_info_Rt2))
+ return false;
+ } else {
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
+ return false;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t2, reg_info_Rt2))
+ return false;
+ }
+
+ bool success = false;
+ if (n == 31) {
+ // CheckSPAlignment();
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
+ } else
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
+
+ wb_address = address + idx;
+ if (a_mode != AddrMode_POST)
+ address = wb_address;
+
+ Context context_t;
+ Context context_t2;
+
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
+
+ switch (memop) {
+ case MemOp_STORE: {
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
+ // based off of the sp
+ // or fp register
{
- scale = (opc & 2) ? 3 : 2;
- is_signed = (opc & 1) != 0;
- if (is_signed && memop == MemOp_STORE)
- return false; // UNDEFINED
- }
-
- if (!vector && wback && ((t == n) || (t2 == n)))
- {
- switch (ConstrainUnpredictable(Unpredictable_WBOVERLAP))
- {
- case Constraint_UNKNOWN:
- wb_unknown = true; // writeback is UNKNOWN
- break;
-
- case Constraint_SUPPRESSWB:
- wback = false; // writeback is suppressed
- break;
-
- case Constraint_NOP:
- memop = MemOp_NOP; // do nothing
- wback = false;
- break;
-
- case Constraint_NONE:
- break;
- }
+ context_t.type = eContextPushRegisterOnStack;
+ context_t2.type = eContextPushRegisterOnStack;
+ } else {
+ context_t.type = eContextRegisterStore;
+ context_t2.type = eContextRegisterStore;
}
+ context_t.SetRegisterToRegisterPlusOffset(reg_info_Rt, reg_info_base, 0);
+ context_t2.SetRegisterToRegisterPlusOffset(reg_info_Rt2, reg_info_base,
+ size);
+
+ if (!ReadRegister(&reg_info_Rt, data_Rt))
+ return false;
+
+ if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
+
+ if (!WriteMemory(context_t, address + 0, buffer, reg_info_Rt.byte_size))
+ return false;
+
+ if (!ReadRegister(&reg_info_Rt2, data_Rt2))
+ return false;
+
+ if (data_Rt2.GetAsMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (memop == MemOp_LOAD && t == t2)
+ if (!WriteMemory(context_t2, address + size, buffer,
+ reg_info_Rt2.byte_size))
+ return false;
+ } break;
+
+ case MemOp_LOAD: {
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this load is
+ // based off of the sp
+ // or fp register
{
- switch (ConstrainUnpredictable(Unpredictable_LDPOVERLAP))
- {
- case Constraint_UNKNOWN:
- rt_unknown = true; // result is UNKNOWN
- break;
-
- case Constraint_NOP:
- memop = MemOp_NOP; // do nothing
- wback = false;
- break;
-
- default:
- break;
- }
+ context_t.type = eContextPopRegisterOffStack;
+ context_t2.type = eContextPopRegisterOffStack;
+ } else {
+ context_t.type = eContextRegisterLoad;
+ context_t2.type = eContextRegisterLoad;
}
-
- idx = LSL(llvm::SignExtend64<7>(imm7), scale);
- size = (integer)1 << scale;
- uint64_t datasize = size * 8;
- uint64_t address;
- uint64_t wb_address;
-
- RegisterValue data_Rt;
- RegisterValue data_Rt2;
-
- // if (vector)
- // CheckFPEnabled(false);
-
- RegisterInfo reg_info_base;
- RegisterInfo reg_info_Rt;
- RegisterInfo reg_info_Rt2;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + n, reg_info_base))
+ context_t.SetAddress(address);
+ context_t2.SetAddress(address + size);
+
+ if (rt_unknown)
+ memset(buffer, 'U', reg_info_Rt.byte_size);
+ else {
+ if (!ReadMemory(context_t, address, buffer, reg_info_Rt.byte_size))
return false;
-
- if (vector)
- {
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt))
- return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt2))
- return false;
- }
- else
- {
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t, reg_info_Rt))
- return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t2, reg_info_Rt2))
- return false;
- }
-
- bool success = false;
- if (n == 31)
- {
- //CheckSPAlignment();
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::sp, 0, &success);
}
- else
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
-
- wb_address = address + idx;
- if (a_mode != AddrMode_POST)
- address = wb_address;
-
- Context context_t;
- Context context_t2;
-
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
-
- switch (memop)
- {
- case MemOp_STORE:
- {
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is based off of the sp or fp register
- {
- context_t.type = eContextPushRegisterOnStack;
- context_t2.type = eContextPushRegisterOnStack;
- }
- else
- {
- context_t.type = eContextRegisterStore;
- context_t2.type = eContextRegisterStore;
- }
- context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
- context_t2.SetRegisterToRegisterPlusOffset (reg_info_Rt2, reg_info_base, size);
-
- if (!ReadRegister (&reg_info_Rt, data_Rt))
- return false;
-
- if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteMemory(context_t, address + 0, buffer, reg_info_Rt.byte_size))
- return false;
-
- if (!ReadRegister (&reg_info_Rt2, data_Rt2))
- return false;
-
- if (data_Rt2.GetAsMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteMemory(context_t2, address + size, buffer, reg_info_Rt2.byte_size))
- return false;
- }
- break;
-
- case MemOp_LOAD:
- {
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this load is based off of the sp or fp register
- {
- context_t.type = eContextPopRegisterOffStack;
- context_t2.type = eContextPopRegisterOffStack;
- }
- else
- {
- context_t.type = eContextRegisterLoad;
- context_t2.type = eContextRegisterLoad;
- }
- context_t.SetAddress(address);
- context_t2.SetAddress(address + size);
-
- if (rt_unknown)
- memset (buffer, 'U', reg_info_Rt.byte_size);
- else
- {
- if (!ReadMemory (context_t, address, buffer, reg_info_Rt.byte_size))
- return false;
- }
-
- if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!vector && is_signed && !data_Rt.SignExtend (datasize))
- return false;
-
- if (!WriteRegister (context_t, &reg_info_Rt, data_Rt))
- return false;
-
- if (!rt_unknown)
- {
- if (!ReadMemory (context_t2, address + size, buffer, reg_info_Rt2.byte_size))
- return false;
- }
-
- if (data_Rt2.SetFromMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!vector && is_signed && !data_Rt2.SignExtend (datasize))
- return false;
-
- if (!WriteRegister (context_t2, &reg_info_Rt2, data_Rt2))
- return false;
- }
- break;
-
- default:
- break;
- }
-
- if (wback)
- {
- if (wb_unknown)
- wb_address = LLDB_INVALID_ADDRESS;
- Context context;
- context.SetImmediateSigned (idx);
- if (n == 31)
- context.type = eContextAdjustStackPointer;
- else
- context.type = eContextAdjustBaseRegister;
- WriteRegisterUnsigned (context, &reg_info_base, wb_address);
- }
- return true;
-}
-template <EmulateInstructionARM64::AddrMode a_mode> bool
-EmulateInstructionARM64::EmulateLDRSTRImm (const uint32_t opcode)
-{
- uint32_t size = Bits32(opcode, 31, 30);
- uint32_t opc = Bits32(opcode, 23, 22);
- uint32_t n = Bits32(opcode, 9, 5);
- uint32_t t = Bits32(opcode, 4, 0);
+ if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- bool wback;
- bool postindex;
- uint64_t offset;
+ if (!vector && is_signed && !data_Rt.SignExtend(datasize))
+ return false;
- switch (a_mode)
- {
- case AddrMode_POST:
- wback = true;
- postindex = true;
- offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
- break;
- case AddrMode_PRE:
- wback = true;
- postindex = false;
- offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
- break;
- case AddrMode_OFF:
- wback = false;
- postindex = false;
- offset = LSL(Bits32(opcode, 21, 10), size);
- break;
+ if (!WriteRegister(context_t, &reg_info_Rt, data_Rt))
+ return false;
+
+ if (!rt_unknown) {
+ if (!ReadMemory(context_t2, address + size, buffer,
+ reg_info_Rt2.byte_size))
+ return false;
}
- MemOp memop;
+ if (data_Rt2.SetFromMemoryData(&reg_info_Rt2, buffer,
+ reg_info_Rt2.byte_size, eByteOrderLittle,
+ error) == 0)
+ return false;
- if (Bit32(opc, 1) == 0)
- {
- memop = Bit32(opc, 0) == 1 ? MemOp_LOAD : MemOp_STORE;
- }
- else
- {
- memop = MemOp_LOAD;
- if (size == 2 && Bit32(opc, 0) == 1)
- return false;
- }
+ if (!vector && is_signed && !data_Rt2.SignExtend(datasize))
+ return false;
- Error error;
- bool success = false;
- uint64_t address;
- uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
- RegisterValue data_Rt;
+ if (!WriteRegister(context_t2, &reg_info_Rt2, data_Rt2))
+ return false;
+ } break;
+
+ default:
+ break;
+ }
+ if (wback) {
+ if (wb_unknown)
+ wb_address = LLDB_INVALID_ADDRESS;
+ Context context;
+ context.SetImmediateSigned(idx);
if (n == 31)
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::sp, 0, &success);
+ context.type = eContextAdjustStackPointer;
else
- address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
+ context.type = eContextAdjustBaseRegister;
+ WriteRegisterUnsigned(context, &reg_info_base, wb_address);
+ }
+ return true;
+}
- if (!success)
- return false;
+template <EmulateInstructionARM64::AddrMode a_mode>
+bool EmulateInstructionARM64::EmulateLDRSTRImm(const uint32_t opcode) {
+ uint32_t size = Bits32(opcode, 31, 30);
+ uint32_t opc = Bits32(opcode, 23, 22);
+ uint32_t n = Bits32(opcode, 9, 5);
+ uint32_t t = Bits32(opcode, 4, 0);
+
+ bool wback;
+ bool postindex;
+ uint64_t offset;
+
+ switch (a_mode) {
+ case AddrMode_POST:
+ wback = true;
+ postindex = true;
+ offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
+ break;
+ case AddrMode_PRE:
+ wback = true;
+ postindex = false;
+ offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
+ break;
+ case AddrMode_OFF:
+ wback = false;
+ postindex = false;
+ offset = LSL(Bits32(opcode, 21, 10), size);
+ break;
+ }
+
+ MemOp memop;
+
+ if (Bit32(opc, 1) == 0) {
+ memop = Bit32(opc, 0) == 1 ? MemOp_LOAD : MemOp_STORE;
+ } else {
+ memop = MemOp_LOAD;
+ if (size == 2 && Bit32(opc, 0) == 1)
+ return false;
+ }
+
+ Error error;
+ bool success = false;
+ uint64_t address;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ RegisterValue data_Rt;
+
+ if (n == 31)
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
+ else
+ address =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
+
+ if (!success)
+ return false;
- if (!postindex)
- address += offset;
+ if (!postindex)
+ address += offset;
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + n, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
+ return false;
- RegisterInfo reg_info_Rt;
- if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t, reg_info_Rt))
- return false;
+ RegisterInfo reg_info_Rt;
+ if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
+ return false;
- Context context;
- switch (memop)
- {
- case MemOp_STORE:
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is based off of the sp or fp register
- context.type = eContextPushRegisterOnStack;
- else
- context.type = eContextRegisterStore;
- context.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, postindex ? 0 : offset);
-
- if (!ReadRegister (&reg_info_Rt, data_Rt))
- return false;
-
- if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteMemory(context, address, buffer, reg_info_Rt.byte_size))
- return false;
- break;
-
- case MemOp_LOAD:
- if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is based off of the sp or fp register
- context.type = eContextPopRegisterOffStack;
- else
- context.type = eContextRegisterLoad;
- context.SetAddress(address);
-
- if (!ReadMemory (context, address, buffer, reg_info_Rt.byte_size))
- return false;
-
- if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
- return false;
-
- if (!WriteRegister (context, &reg_info_Rt, data_Rt))
- return false;
- break;
- default:
- return false;
- }
+ Context context;
+ switch (memop) {
+ case MemOp_STORE:
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
+ // based off of the sp
+ // or fp register
+ context.type = eContextPushRegisterOnStack;
+ else
+ context.type = eContextRegisterStore;
+ context.SetRegisterToRegisterPlusOffset(reg_info_Rt, reg_info_base,
+ postindex ? 0 : offset);
+
+ if (!ReadRegister(&reg_info_Rt, data_Rt))
+ return false;
+
+ if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
+
+ if (!WriteMemory(context, address, buffer, reg_info_Rt.byte_size))
+ return false;
+ break;
+
+ case MemOp_LOAD:
+ if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
+ // based off of the sp
+ // or fp register
+ context.type = eContextPopRegisterOffStack;
+ else
+ context.type = eContextRegisterLoad;
+ context.SetAddress(address);
- if (wback)
- {
- if (postindex)
- address += offset;
+ if (!ReadMemory(context, address, buffer, reg_info_Rt.byte_size))
+ return false;
- if (n == 31)
- context.type = eContextAdjustStackPointer;
- else
- context.type = eContextAdjustBaseRegister;
- context.SetImmediateSigned (offset);
+ if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteRegisterUnsigned (context, &reg_info_base, address))
- return false;
- }
- return true;
+ if (!WriteRegister(context, &reg_info_Rt, data_Rt))
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ if (wback) {
+ if (postindex)
+ address += offset;
+
+ if (n == 31)
+ context.type = eContextAdjustStackPointer;
+ else
+ context.type = eContextAdjustBaseRegister;
+ context.SetImmediateSigned(offset);
+
+ if (!WriteRegisterUnsigned(context, &reg_info_base, address))
+ return false;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateB (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateB(const uint32_t opcode) {
#if 0
// ARM64 pseudo code...
if branch_type == BranchType_CALL then X[30] = PC[] + 4;
BranchTo(PC[] + offset, branch_type);
#endif
- bool success = false;
+ bool success = false;
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- int64_t offset = llvm::SignExtend64<28>(Bits32(opcode, 25, 0) << 2);
- BranchType branch_type = Bit32(opcode, 31) ? BranchType_CALL : BranchType_JMP;
- addr_t target = pc + offset;
- context.SetImmediateSigned(offset);
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, 0, &success);
+ if (!success)
+ return false;
- switch (branch_type)
- {
- case BranchType_CALL:
- {
- addr_t x30 = pc + 4;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::x30, x30))
- return false;
- }
- break;
- case BranchType_JMP:
- break;
- default:
- return false;
- }
+ int64_t offset = llvm::SignExtend64<28>(Bits32(opcode, 25, 0) << 2);
+ BranchType branch_type = Bit32(opcode, 31) ? BranchType_CALL : BranchType_JMP;
+ addr_t target = pc + offset;
+ context.SetImmediateSigned(offset);
+
+ switch (branch_type) {
+ case BranchType_CALL: {
+ addr_t x30 = pc + 4;
+ if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_lr_arm64, x30))
+ return false;
+ } break;
+ case BranchType_JMP:
+ break;
+ default:
+ return false;
+ }
- if (!BranchTo(context, 64, target))
- return false;
- return true;
+ if (!BranchTo(context, 64, target))
+ return false;
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateBcond (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateBcond(const uint32_t opcode) {
#if 0
// ARM64 pseudo code...
bits(64) offset = SignExtend(imm19:'00', 64);
@@ -1055,29 +1127,27 @@ EmulateInstructionARM64::EmulateBcond (const uint32_t opcode)
BranchTo(PC[] + offset, BranchType_JMP);
#endif
- if (ConditionHolds(Bits32(opcode, 3, 0)))
- {
- bool success = false;
-
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- int64_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
- addr_t target = pc + offset;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- context.SetImmediateSigned(offset);
- if (!BranchTo(context, 64, target))
- return false;
- }
- return true;
+ if (ConditionHolds(Bits32(opcode, 3, 0))) {
+ bool success = false;
+
+ const uint64_t pc = ReadRegisterUnsigned(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
+ if (!success)
+ return false;
+
+ int64_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
+ addr_t target = pc + offset;
+
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ context.SetImmediateSigned(offset);
+ if (!BranchTo(context, 64, target))
+ return false;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateCBZ (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateCBZ(const uint32_t opcode) {
#if 0
integer t = UInt(Rt);
integer datasize = if sf == '1' then 64 else 32;
@@ -1089,34 +1159,33 @@ EmulateInstructionARM64::EmulateCBZ (const uint32_t opcode)
BranchTo(PC[] + offset, BranchType_JMP);
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t t = Bits32(opcode, 4, 0);
+ bool is_zero = Bit32(opcode, 24) == 0;
+ int32_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
- uint32_t t = Bits32(opcode, 4, 0);
- bool is_zero = Bit32(opcode, 24) == 0;
- int32_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
+ const uint64_t operand =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
+ if (!success)
+ return false;
- const uint64_t operand = ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::x0 + t, 0, &success);
+ if (m_ignore_conditions || ((operand == 0) == is_zero)) {
+ const uint64_t pc = ReadRegisterUnsigned(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
if (!success)
- return false;
+ return false;
- if (m_ignore_conditions || ((operand == 0) == is_zero))
- {
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- context.SetImmediateSigned(offset);
- if (!BranchTo(context, 64, pc + offset))
- return false;
- }
- return true;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ context.SetImmediateSigned(offset);
+ if (!BranchTo(context, 64, pc + offset))
+ return false;
+ }
+ return true;
}
-bool
-EmulateInstructionARM64::EmulateTBZ (const uint32_t opcode)
-{
+bool EmulateInstructionARM64::EmulateTBZ(const uint32_t opcode) {
#if 0
integer t = UInt(Rt);
integer datasize = if b5 == '1' then 64 else 32;
@@ -1125,28 +1194,29 @@ EmulateInstructionARM64::EmulateTBZ (const uint32_t opcode)
bits(64) offset = SignExtend(imm14:'00', 64);
#endif
- bool success = false;
+ bool success = false;
+
+ uint32_t t = Bits32(opcode, 4, 0);
+ uint32_t bit_pos = (Bit32(opcode, 31) << 6) | (Bits32(opcode, 23, 19));
+ uint32_t bit_val = Bit32(opcode, 24);
+ int64_t offset = llvm::SignExtend64<16>(Bits32(opcode, 18, 5) << 2);
- uint32_t t = Bits32(opcode, 4, 0);
- uint32_t bit_pos = (Bit32(opcode, 31) << 6) | (Bits32(opcode, 23, 19));
- uint32_t bit_val = Bit32(opcode, 24);
- int64_t offset = llvm::SignExtend64<16>(Bits32(opcode, 18, 5) << 2);
+ const uint64_t operand =
+ ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
+ if (!success)
+ return false;
- const uint64_t operand = ReadRegisterUnsigned(eRegisterKindDWARF, arm64_dwarf::x0 + t, 0, &success);
+ if (m_ignore_conditions || Bit32(operand, bit_pos) == bit_val) {
+ const uint64_t pc = ReadRegisterUnsigned(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
if (!success)
- return false;
+ return false;
- if (m_ignore_conditions || Bit32(operand, bit_pos) == bit_val)
- {
- const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success);
- if (!success)
- return false;
-
- EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextRelativeBranchImmediate;
- context.SetImmediateSigned(offset);
- if (!BranchTo(context, 64, pc + offset))
- return false;
- }
- return true;
+ EmulateInstruction::Context context;
+ context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+ context.SetImmediateSigned(offset);
+ if (!BranchTo(context, 64, pc + offset))
+ return false;
+ }
+ return true;
}
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
index d9333c2824d2..1da330497b33 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
@@ -14,288 +14,192 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
#include "lldb/Interpreter/OptionValue.h"
-#include "Plugins/Process/Utility/ARMDefines.h"
-class EmulateInstructionARM64 : public lldb_private::EmulateInstruction
-{
-public:
- EmulateInstructionARM64 (const lldb_private::ArchSpec &arch) :
- EmulateInstruction (arch),
- m_opcode_pstate (),
- m_emulated_pstate (),
- m_ignore_conditions (false)
- {
- }
+class EmulateInstructionARM64 : public lldb_private::EmulateInstruction {
+public:
+ EmulateInstructionARM64(const lldb_private::ArchSpec &arch)
+ : EmulateInstruction(arch), m_opcode_pstate(), m_emulated_pstate(),
+ m_ignore_conditions(false) {}
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- lldb_private::InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
- {
- switch (inst_type)
- {
- case lldb_private::eInstructionTypeAny:
- case lldb_private::eInstructionTypePrologueEpilogue:
- return true;
-
- case lldb_private::eInstructionTypePCModifying:
- case lldb_private::eInstructionTypeAll:
- return false;
- }
- return false;
- }
+ static void Initialize();
- lldb_private::ConstString
- GetPluginName() override;
+ static void Terminate();
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ static lldb_private::ConstString GetPluginNameStatic();
- bool
- SetTargetTriple(const lldb_private::ArchSpec &arch) override;
-
- bool
- SupportsEmulatingInstructionsOfType(lldb_private::InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ static const char *GetPluginDescriptionStatic();
- bool
- ReadInstruction() override;
-
- bool
- EvaluateInstruction(uint32_t evaluate_options) override;
-
- bool
- TestEmulation(lldb_private::Stream *out_stream,
- lldb_private::ArchSpec &arch,
- lldb_private::OptionValueDictionary *test_data) override
- {
- return false;
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch,
+ lldb_private::InstructionType inst_type);
+
+ static bool SupportsEmulatingInstructionsOfTypeStatic(
+ lldb_private::InstructionType inst_type) {
+ switch (inst_type) {
+ case lldb_private::eInstructionTypeAny:
+ case lldb_private::eInstructionTypePrologueEpilogue:
+ return true;
+
+ case lldb_private::eInstructionTypePCModifying:
+ case lldb_private::eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
+
+ lldb_private::ConstString GetPluginName() override;
- bool
- GetRegisterInfo(lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- lldb_private::RegisterInfo &reg_info) override;
-
- bool
- CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
-
- typedef enum
- {
- AddrMode_OFF,
- AddrMode_PRE,
- AddrMode_POST
- } AddrMode;
-
- typedef enum
- {
- BranchType_CALL,
- BranchType_ERET,
- BranchType_DRET,
- BranchType_RET,
- BranchType_JMP
- } BranchType;
-
- typedef enum
- {
- CountOp_CLZ,
- CountOp_CLS,
- CountOp_CNT
- } CountOp;
-
- typedef enum
- {
- RevOp_RBIT,
- RevOp_REV16,
- RevOp_REV32,
- RevOp_REV64
- } RevOp;
-
- typedef enum
- {
- BitwiseOp_NOT,
- BitwiseOp_RBIT
- } BitwiseOp;
-
- typedef enum
- {
- EL0 = 0,
- EL1 = 1,
- EL2 = 2,
- EL3 = 3
- } ExceptionLevel;
-
- typedef enum
- {
- ExtendType_SXTB,
- ExtendType_SXTH,
- ExtendType_SXTW,
- ExtendType_SXTX,
- ExtendType_UXTB,
- ExtendType_UXTH,
- ExtendType_UXTW,
- ExtendType_UXTX
- } ExtendType;
-
- typedef enum
- {
- ExtractType_LEFT,
- ExtractType_RIGHT
- } ExtractType;
-
- typedef enum
- {
- LogicalOp_AND,
- LogicalOp_EOR,
- LogicalOp_ORR
- } LogicalOp;
-
- typedef enum
- {
- MemOp_LOAD,
- MemOp_STORE,
- MemOp_PREFETCH,
- MemOp_NOP
- } MemOp;
-
- typedef enum
- {
- MoveWideOp_N,
- MoveWideOp_Z,
- MoveWideOp_K
- } MoveWideOp;
-
- typedef enum {
- ShiftType_LSL,
- ShiftType_LSR,
- ShiftType_ASR,
- ShiftType_ROR
- } ShiftType;
-
- typedef enum
- {
- SP0 = 0,
- SPx = 1
- } StackPointerSelection;
-
- typedef enum
- {
- Unpredictable_WBOVERLAP,
- Unpredictable_LDPOVERLAP
- } Unpredictable;
-
- typedef enum
- {
- Constraint_NONE,
- Constraint_UNKNOWN,
- Constraint_SUPPRESSWB,
- Constraint_NOP
- } ConstraintType;
-
- typedef enum
- {
- AccType_NORMAL,
- AccType_UNPRIV,
- AccType_STREAM,
- AccType_ALIGNED,
- AccType_ORDERED
- } AccType;
-
- typedef struct
- {
- uint32_t
- N:1,
- V:1,
- C:1,
- Z:1, // condition code flags – can also be accessed as PSTATE.[N,Z,C,V]
- Q:1, // AArch32 only – CSPR.Q bit
- IT:8, // AArch32 only – CPSR.IT bits
- J:1, // AArch32 only – CSPR.J bit
- T:1, // AArch32 only – CPSR.T bit
- SS:1, // Single step process state bit
- IL:1, // Illegal state bit
- D:1,
- A:1,
- I:1,
- F:1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]
- E:1, // AArch32 only – CSPR.E bit
- M:5, // AArch32 only – mode encodings
- RW:1, // Current register width – 0 is AArch64, 1 is AArch32
- EL:2, // Current exception level (see ExceptionLevel enum)
- SP:1; // AArch64 only - Stack Pointer selection (see StackPointerSelection enum)
- } ProcState;
+ uint32_t GetPluginVersion() override { return 1; }
+
+ bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
+
+ bool SupportsEmulatingInstructionsOfType(
+ lldb_private::InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ bool ReadInstruction() override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ bool TestEmulation(lldb_private::Stream *out_stream,
+ lldb_private::ArchSpec &arch,
+ lldb_private::OptionValueDictionary *test_data) override {
+ return false;
+ }
+
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ lldb_private::RegisterInfo &reg_info) override;
+
+ bool
+ CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
+
+ typedef enum { AddrMode_OFF, AddrMode_PRE, AddrMode_POST } AddrMode;
+
+ typedef enum {
+ BranchType_CALL,
+ BranchType_ERET,
+ BranchType_DRET,
+ BranchType_RET,
+ BranchType_JMP
+ } BranchType;
+
+ typedef enum { CountOp_CLZ, CountOp_CLS, CountOp_CNT } CountOp;
+
+ typedef enum { RevOp_RBIT, RevOp_REV16, RevOp_REV32, RevOp_REV64 } RevOp;
+
+ typedef enum { BitwiseOp_NOT, BitwiseOp_RBIT } BitwiseOp;
+
+ typedef enum { EL0 = 0, EL1 = 1, EL2 = 2, EL3 = 3 } ExceptionLevel;
+
+ typedef enum {
+ ExtendType_SXTB,
+ ExtendType_SXTH,
+ ExtendType_SXTW,
+ ExtendType_SXTX,
+ ExtendType_UXTB,
+ ExtendType_UXTH,
+ ExtendType_UXTW,
+ ExtendType_UXTX
+ } ExtendType;
+
+ typedef enum { ExtractType_LEFT, ExtractType_RIGHT } ExtractType;
+
+ typedef enum { LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR } LogicalOp;
+
+ typedef enum { MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH, MemOp_NOP } MemOp;
+
+ typedef enum { MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K } MoveWideOp;
+
+ typedef enum {
+ ShiftType_LSL,
+ ShiftType_LSR,
+ ShiftType_ASR,
+ ShiftType_ROR
+ } ShiftType;
+
+ typedef enum { SP0 = 0, SPx = 1 } StackPointerSelection;
+
+ typedef enum {
+ Unpredictable_WBOVERLAP,
+ Unpredictable_LDPOVERLAP
+ } Unpredictable;
+
+ typedef enum {
+ Constraint_NONE,
+ Constraint_UNKNOWN,
+ Constraint_SUPPRESSWB,
+ Constraint_NOP
+ } ConstraintType;
+
+ typedef enum {
+ AccType_NORMAL,
+ AccType_UNPRIV,
+ AccType_STREAM,
+ AccType_ALIGNED,
+ AccType_ORDERED
+ } AccType;
+
+ typedef struct {
+ uint32_t N : 1, V : 1, C : 1,
+ Z : 1, // condition code flags – can also be accessed as
+ // PSTATE.[N,Z,C,V]
+ Q : 1, // AArch32 only – CSPR.Q bit
+ IT : 8, // AArch32 only – CPSR.IT bits
+ J : 1, // AArch32 only – CSPR.J bit
+ T : 1, // AArch32 only – CPSR.T bit
+ SS : 1, // Single step process state bit
+ IL : 1, // Illegal state bit
+ D : 1, A : 1, I : 1,
+ F : 1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]
+ E : 1, // AArch32 only – CSPR.E bit
+ M : 5, // AArch32 only – mode encodings
+ RW : 1, // Current register width – 0 is AArch64, 1 is AArch32
+ EL : 2, // Current exception level (see ExceptionLevel enum)
+ SP : 1; // AArch64 only - Stack Pointer selection (see
+ // StackPointerSelection enum)
+ } ProcState;
protected:
- typedef struct
- {
- uint32_t mask;
- uint32_t value;
- uint32_t vfp_variants;
- bool (EmulateInstructionARM64::*callback) (const uint32_t opcode);
- const char *name;
- } Opcode;
-
- static Opcode*
- GetOpcodeForInstruction (const uint32_t opcode);
+ typedef struct {
+ uint32_t mask;
+ uint32_t value;
+ uint32_t vfp_variants;
+ bool (EmulateInstructionARM64::*callback)(const uint32_t opcode);
+ const char *name;
+ } Opcode;
+
+ static Opcode *GetOpcodeForInstruction(const uint32_t opcode);
- uint32_t
- GetFramePointerRegisterNumber() const;
+ uint32_t GetFramePointerRegisterNumber() const;
- bool
- BranchTo (const Context &context, uint32_t N, lldb::addr_t target);
+ bool BranchTo(const Context &context, uint32_t N, lldb::addr_t target);
- bool
- ConditionHolds (const uint32_t cond);
+ bool ConditionHolds(const uint32_t cond);
- bool
- UsingAArch32 ();
+ bool UsingAArch32();
- bool
- EmulateADDSUBImm (const uint32_t opcode);
+ bool EmulateADDSUBImm(const uint32_t opcode);
- template <AddrMode a_mode> bool
- EmulateLDPSTP (const uint32_t opcode);
+ template <AddrMode a_mode> bool EmulateLDPSTP(const uint32_t opcode);
- template <AddrMode a_mode> bool
- EmulateLDRSTRImm (const uint32_t opcode);
+ template <AddrMode a_mode> bool EmulateLDRSTRImm(const uint32_t opcode);
- bool
- EmulateB (const uint32_t opcode);
+ bool EmulateB(const uint32_t opcode);
- bool
- EmulateBcond (const uint32_t opcode);
+ bool EmulateBcond(const uint32_t opcode);
- bool
- EmulateCBZ (const uint32_t opcode);
+ bool EmulateCBZ(const uint32_t opcode);
- bool
- EmulateTBZ (const uint32_t opcode);
+ bool EmulateTBZ(const uint32_t opcode);
- ProcState m_opcode_pstate;
- ProcState m_emulated_pstate; // This can get updated by the opcode.
- bool m_ignore_conditions;
+ ProcState m_opcode_pstate;
+ ProcState m_emulated_pstate; // This can get updated by the opcode.
+ bool m_ignore_conditions;
};
#endif // EmulateInstructionARM64_h_
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index 47b98ca85b78..8cc34c171c72 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -1,4 +1,5 @@
-//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++ -*-===//
+//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,30 +12,30 @@
#include <stdlib.h>
-#include "llvm-c/Disassembler.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCDisassembler/MCDisassembler.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCContext.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Opcode.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Target.h"
+#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#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" //mips32 has same registers nos as mips64
using namespace lldb;
using namespace lldb_private;
@@ -42,7 +43,6 @@ using namespace lldb_private;
#define UInt(x) ((uint64_t)x)
#define integer int64_t
-
//----------------------------------------------------------------------
//
// EmulateInstructionMIPS implementation
@@ -51,1926 +51,2180 @@ using namespace lldb_private;
#ifdef __mips__
extern "C" {
- void LLVMInitializeMipsTargetInfo ();
- void LLVMInitializeMipsTarget ();
- void LLVMInitializeMipsAsmPrinter ();
- void LLVMInitializeMipsTargetMC ();
- void LLVMInitializeMipsDisassembler ();
+void LLVMInitializeMipsTargetInfo();
+void LLVMInitializeMipsTarget();
+void LLVMInitializeMipsAsmPrinter();
+void LLVMInitializeMipsTargetMC();
+void LLVMInitializeMipsDisassembler();
}
#endif
-EmulateInstructionMIPS::EmulateInstructionMIPS (const lldb_private::ArchSpec &arch) :
- EmulateInstruction (arch)
-{
- /* Create instance of llvm::MCDisassembler */
- std::string Error;
- llvm::Triple triple = arch.GetTriple();
- const llvm::Target *target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
+EmulateInstructionMIPS::EmulateInstructionMIPS(
+ const lldb_private::ArchSpec &arch)
+ : EmulateInstruction(arch) {
+ /* Create instance of llvm::MCDisassembler */
+ std::string Error;
+ llvm::Triple triple = arch.GetTriple();
+ const llvm::Target *target =
+ llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
- /*
- * If we fail to get the target then we haven't registered it. The SystemInitializerCommon
- * does not initialize targets, MCs and disassemblers. However we need the MCDisassembler
- * to decode the instructions so that the decoding complexity stays with LLVM.
- * Initialize the MIPS targets and disassemblers.
- */
+/*
+ * If we fail to get the target then we haven't registered it. The
+ * SystemInitializerCommon
+ * does not initialize targets, MCs and disassemblers. However we need the
+ * MCDisassembler
+ * to decode the instructions so that the decoding complexity stays with LLVM.
+ * Initialize the MIPS targets and disassemblers.
+*/
#ifdef __mips__
- if (!target)
- {
- LLVMInitializeMipsTargetInfo ();
- LLVMInitializeMipsTarget ();
- LLVMInitializeMipsAsmPrinter ();
- LLVMInitializeMipsTargetMC ();
- LLVMInitializeMipsDisassembler ();
- target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
- }
+ if (!target) {
+ LLVMInitializeMipsTargetInfo();
+ LLVMInitializeMipsTarget();
+ LLVMInitializeMipsAsmPrinter();
+ LLVMInitializeMipsTargetMC();
+ LLVMInitializeMipsDisassembler();
+ target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
+ }
#endif
- assert (target);
-
- llvm::StringRef cpu;
-
- switch (arch.GetCore())
- {
- case ArchSpec::eCore_mips32:
- case ArchSpec::eCore_mips32el:
- cpu = "mips32"; break;
- case ArchSpec::eCore_mips32r2:
- case ArchSpec::eCore_mips32r2el:
- cpu = "mips32r2"; break;
- case ArchSpec::eCore_mips32r3:
- case ArchSpec::eCore_mips32r3el:
- cpu = "mips32r3"; break;
- case ArchSpec::eCore_mips32r5:
- case ArchSpec::eCore_mips32r5el:
- cpu = "mips32r5"; break;
- case ArchSpec::eCore_mips32r6:
- case ArchSpec::eCore_mips32r6el:
- cpu = "mips32r6"; break;
- case ArchSpec::eCore_mips64:
- case ArchSpec::eCore_mips64el:
- cpu = "mips64"; break;
- case ArchSpec::eCore_mips64r2:
- case ArchSpec::eCore_mips64r2el:
- cpu = "mips64r2"; break;
- case ArchSpec::eCore_mips64r3:
- case ArchSpec::eCore_mips64r3el:
- cpu = "mips64r3"; break;
- case ArchSpec::eCore_mips64r5:
- case ArchSpec::eCore_mips64r5el:
- cpu = "mips64r5"; break;
- case ArchSpec::eCore_mips64r6:
- case ArchSpec::eCore_mips64r6el:
- cpu = "mips64r6"; break;
- default:
- cpu = "generic"; break;
- }
-
- std::string features = "";
- uint32_t arch_flags = arch.GetFlags ();
- if (arch_flags & ArchSpec::eMIPSAse_msa)
- features += "+msa,";
- if (arch_flags & ArchSpec::eMIPSAse_dsp)
- features += "+dsp,";
- if (arch_flags & ArchSpec::eMIPSAse_dspr2)
- features += "+dspr2,";
-
- m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
- assert (m_reg_info.get());
-
- m_insn_info.reset (target->createMCInstrInfo());
- assert (m_insn_info.get());
-
- m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
- m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
- assert (m_asm_info.get() && m_subtype_info.get());
-
- m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
- assert (m_context.get());
-
- m_disasm.reset (target->createMCDisassembler (*m_subtype_info, *m_context));
- assert (m_disasm.get());
-
- /* Create alternate disassembler for microMIPS */
- if (arch_flags & ArchSpec::eMIPSAse_mips16)
- features += "+mips16,";
- else if (arch_flags & ArchSpec::eMIPSAse_micromips)
- features += "+micromips,";
-
- m_alt_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
- assert (m_alt_subtype_info.get());
-
- m_alt_disasm.reset (target->createMCDisassembler (*m_alt_subtype_info, *m_context));
- assert (m_alt_disasm.get());
-
- m_next_inst_size = 0;
- m_use_alt_disaasm = false;
+ assert(target);
+
+ llvm::StringRef cpu;
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_mips32:
+ case ArchSpec::eCore_mips32el:
+ cpu = "mips32";
+ break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r2el:
+ cpu = "mips32r2";
+ break;
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r3el:
+ cpu = "mips32r3";
+ break;
+ case ArchSpec::eCore_mips32r5:
+ case ArchSpec::eCore_mips32r5el:
+ cpu = "mips32r5";
+ break;
+ case ArchSpec::eCore_mips32r6:
+ case ArchSpec::eCore_mips32r6el:
+ cpu = "mips32r6";
+ break;
+ case ArchSpec::eCore_mips64:
+ case ArchSpec::eCore_mips64el:
+ cpu = "mips64";
+ break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r2el:
+ cpu = "mips64r2";
+ break;
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r3el:
+ cpu = "mips64r3";
+ break;
+ case ArchSpec::eCore_mips64r5:
+ case ArchSpec::eCore_mips64r5el:
+ cpu = "mips64r5";
+ break;
+ case ArchSpec::eCore_mips64r6:
+ case ArchSpec::eCore_mips64r6el:
+ cpu = "mips64r6";
+ break;
+ default:
+ cpu = "generic";
+ break;
+ }
+
+ std::string features = "";
+ uint32_t arch_flags = arch.GetFlags();
+ if (arch_flags & ArchSpec::eMIPSAse_msa)
+ features += "+msa,";
+ if (arch_flags & ArchSpec::eMIPSAse_dsp)
+ features += "+dsp,";
+ if (arch_flags & ArchSpec::eMIPSAse_dspr2)
+ features += "+dspr2,";
+
+ m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
+ assert(m_reg_info.get());
+
+ m_insn_info.reset(target->createMCInstrInfo());
+ assert(m_insn_info.get());
+
+ m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
+ m_subtype_info.reset(
+ target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
+ assert(m_asm_info.get() && m_subtype_info.get());
+
+ m_context.reset(
+ new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
+ assert(m_context.get());
+
+ m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
+ assert(m_disasm.get());
+
+ /* Create alternate disassembler for microMIPS */
+ if (arch_flags & ArchSpec::eMIPSAse_mips16)
+ features += "+mips16,";
+ else if (arch_flags & ArchSpec::eMIPSAse_micromips)
+ features += "+micromips,";
+
+ m_alt_subtype_info.reset(
+ target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
+ assert(m_alt_subtype_info.get());
+
+ m_alt_disasm.reset(
+ target->createMCDisassembler(*m_alt_subtype_info, *m_context));
+ assert(m_alt_disasm.get());
+
+ m_next_inst_size = 0;
+ m_use_alt_disaasm = false;
+}
+
+void EmulateInstructionMIPS::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void EmulateInstructionMIPS::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString EmulateInstructionMIPS::GetPluginNameStatic() {
+ ConstString g_plugin_name("lldb.emulate-instruction.mips32");
+ return g_plugin_name;
+}
+
+lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() {
+ static ConstString g_plugin_name("EmulateInstructionMIPS");
+ return g_plugin_name;
+}
+
+const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the MIPS32 architecture.";
}
-void
-EmulateInstructionMIPS::Initialize ()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic (),
- GetPluginDescriptionStatic (),
- CreateInstance);
-}
-
-void
-EmulateInstructionMIPS::Terminate ()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-ConstString
-EmulateInstructionMIPS::GetPluginNameStatic ()
-{
- ConstString g_plugin_name ("lldb.emulate-instruction.mips32");
- return g_plugin_name;
-}
-
-lldb_private::ConstString
-EmulateInstructionMIPS::GetPluginName()
-{
- static ConstString g_plugin_name ("EmulateInstructionMIPS");
- return g_plugin_name;
-}
+EmulateInstruction *
+EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips ||
+ arch.GetTriple().getArch() == llvm::Triple::mipsel) {
+ std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap(
+ new EmulateInstructionMIPS(arch));
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
+ }
+ }
-const char *
-EmulateInstructionMIPS::GetPluginDescriptionStatic ()
-{
- return "Emulate instructions for the MIPS32 architecture.";
+ return NULL;
}
-EmulateInstruction *
-EmulateInstructionMIPS::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
-{
- if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
- {
- if (arch.GetTriple().getArch() == llvm::Triple::mips
- || arch.GetTriple().getArch() == llvm::Triple::mipsel)
- {
- std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap (new EmulateInstructionMIPS (arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
+bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips ||
+ arch.GetTriple().getArch() == llvm::Triple::mipsel)
+ return true;
+ return false;
+}
+
+const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
+ bool alternate_name) {
+ if (alternate_name) {
+ switch (reg_num) {
+ case dwarf_sp_mips:
+ return "r29";
+ case dwarf_r30_mips:
+ return "r30";
+ case dwarf_ra_mips:
+ return "r31";
+ case dwarf_f0_mips:
+ return "f0";
+ case dwarf_f1_mips:
+ return "f1";
+ case dwarf_f2_mips:
+ return "f2";
+ case dwarf_f3_mips:
+ return "f3";
+ case dwarf_f4_mips:
+ return "f4";
+ case dwarf_f5_mips:
+ return "f5";
+ case dwarf_f6_mips:
+ return "f6";
+ case dwarf_f7_mips:
+ return "f7";
+ case dwarf_f8_mips:
+ return "f8";
+ case dwarf_f9_mips:
+ return "f9";
+ case dwarf_f10_mips:
+ return "f10";
+ case dwarf_f11_mips:
+ return "f11";
+ case dwarf_f12_mips:
+ return "f12";
+ case dwarf_f13_mips:
+ return "f13";
+ case dwarf_f14_mips:
+ return "f14";
+ case dwarf_f15_mips:
+ return "f15";
+ case dwarf_f16_mips:
+ return "f16";
+ case dwarf_f17_mips:
+ return "f17";
+ case dwarf_f18_mips:
+ return "f18";
+ case dwarf_f19_mips:
+ return "f19";
+ case dwarf_f20_mips:
+ return "f20";
+ case dwarf_f21_mips:
+ return "f21";
+ case dwarf_f22_mips:
+ return "f22";
+ case dwarf_f23_mips:
+ return "f23";
+ case dwarf_f24_mips:
+ return "f24";
+ case dwarf_f25_mips:
+ return "f25";
+ case dwarf_f26_mips:
+ return "f26";
+ case dwarf_f27_mips:
+ return "f27";
+ case dwarf_f28_mips:
+ return "f28";
+ case dwarf_f29_mips:
+ return "f29";
+ case dwarf_f30_mips:
+ return "f30";
+ case dwarf_f31_mips:
+ return "f31";
+ case dwarf_w0_mips:
+ return "w0";
+ case dwarf_w1_mips:
+ return "w1";
+ case dwarf_w2_mips:
+ return "w2";
+ case dwarf_w3_mips:
+ return "w3";
+ case dwarf_w4_mips:
+ return "w4";
+ case dwarf_w5_mips:
+ return "w5";
+ case dwarf_w6_mips:
+ return "w6";
+ case dwarf_w7_mips:
+ return "w7";
+ case dwarf_w8_mips:
+ return "w8";
+ case dwarf_w9_mips:
+ return "w9";
+ case dwarf_w10_mips:
+ return "w10";
+ case dwarf_w11_mips:
+ return "w11";
+ case dwarf_w12_mips:
+ return "w12";
+ case dwarf_w13_mips:
+ return "w13";
+ case dwarf_w14_mips:
+ return "w14";
+ case dwarf_w15_mips:
+ return "w15";
+ case dwarf_w16_mips:
+ return "w16";
+ case dwarf_w17_mips:
+ return "w17";
+ case dwarf_w18_mips:
+ return "w18";
+ case dwarf_w19_mips:
+ return "w19";
+ case dwarf_w20_mips:
+ return "w20";
+ case dwarf_w21_mips:
+ return "w21";
+ case dwarf_w22_mips:
+ return "w22";
+ case dwarf_w23_mips:
+ return "w23";
+ case dwarf_w24_mips:
+ return "w24";
+ case dwarf_w25_mips:
+ return "w25";
+ case dwarf_w26_mips:
+ return "w26";
+ case dwarf_w27_mips:
+ return "w27";
+ case dwarf_w28_mips:
+ return "w28";
+ case dwarf_w29_mips:
+ return "w29";
+ case dwarf_w30_mips:
+ return "w30";
+ case dwarf_w31_mips:
+ return "w31";
+ case dwarf_mir_mips:
+ return "mir";
+ case dwarf_mcsr_mips:
+ return "mcsr";
+ case dwarf_config5_mips:
+ return "config5";
+ default:
+ break;
+ }
+ return nullptr;
+ }
+
+ switch (reg_num) {
+ case dwarf_zero_mips:
+ return "r0";
+ case dwarf_r1_mips:
+ return "r1";
+ case dwarf_r2_mips:
+ return "r2";
+ case dwarf_r3_mips:
+ return "r3";
+ case dwarf_r4_mips:
+ return "r4";
+ case dwarf_r5_mips:
+ return "r5";
+ case dwarf_r6_mips:
+ return "r6";
+ case dwarf_r7_mips:
+ return "r7";
+ case dwarf_r8_mips:
+ return "r8";
+ case dwarf_r9_mips:
+ return "r9";
+ case dwarf_r10_mips:
+ return "r10";
+ case dwarf_r11_mips:
+ return "r11";
+ case dwarf_r12_mips:
+ return "r12";
+ case dwarf_r13_mips:
+ return "r13";
+ case dwarf_r14_mips:
+ return "r14";
+ case dwarf_r15_mips:
+ return "r15";
+ case dwarf_r16_mips:
+ return "r16";
+ case dwarf_r17_mips:
+ return "r17";
+ case dwarf_r18_mips:
+ return "r18";
+ case dwarf_r19_mips:
+ return "r19";
+ case dwarf_r20_mips:
+ return "r20";
+ case dwarf_r21_mips:
+ return "r21";
+ case dwarf_r22_mips:
+ return "r22";
+ case dwarf_r23_mips:
+ return "r23";
+ case dwarf_r24_mips:
+ return "r24";
+ case dwarf_r25_mips:
+ return "r25";
+ case dwarf_r26_mips:
+ return "r26";
+ case dwarf_r27_mips:
+ return "r27";
+ case dwarf_gp_mips:
+ return "gp";
+ case dwarf_sp_mips:
+ return "sp";
+ case dwarf_r30_mips:
+ return "fp";
+ case dwarf_ra_mips:
+ return "ra";
+ case dwarf_sr_mips:
+ return "sr";
+ case dwarf_lo_mips:
+ return "lo";
+ case dwarf_hi_mips:
+ return "hi";
+ case dwarf_bad_mips:
+ return "bad";
+ case dwarf_cause_mips:
+ return "cause";
+ case dwarf_pc_mips:
+ return "pc";
+ case dwarf_f0_mips:
+ return "f0";
+ case dwarf_f1_mips:
+ return "f1";
+ case dwarf_f2_mips:
+ return "f2";
+ case dwarf_f3_mips:
+ return "f3";
+ case dwarf_f4_mips:
+ return "f4";
+ case dwarf_f5_mips:
+ return "f5";
+ case dwarf_f6_mips:
+ return "f6";
+ case dwarf_f7_mips:
+ return "f7";
+ case dwarf_f8_mips:
+ return "f8";
+ case dwarf_f9_mips:
+ return "f9";
+ case dwarf_f10_mips:
+ return "f10";
+ case dwarf_f11_mips:
+ return "f11";
+ case dwarf_f12_mips:
+ return "f12";
+ case dwarf_f13_mips:
+ return "f13";
+ case dwarf_f14_mips:
+ return "f14";
+ case dwarf_f15_mips:
+ return "f15";
+ case dwarf_f16_mips:
+ return "f16";
+ case dwarf_f17_mips:
+ return "f17";
+ case dwarf_f18_mips:
+ return "f18";
+ case dwarf_f19_mips:
+ return "f19";
+ case dwarf_f20_mips:
+ return "f20";
+ case dwarf_f21_mips:
+ return "f21";
+ case dwarf_f22_mips:
+ return "f22";
+ case dwarf_f23_mips:
+ return "f23";
+ case dwarf_f24_mips:
+ return "f24";
+ case dwarf_f25_mips:
+ return "f25";
+ case dwarf_f26_mips:
+ return "f26";
+ case dwarf_f27_mips:
+ return "f27";
+ case dwarf_f28_mips:
+ return "f28";
+ case dwarf_f29_mips:
+ return "f29";
+ case dwarf_f30_mips:
+ return "f30";
+ case dwarf_f31_mips:
+ return "f31";
+ case dwarf_fcsr_mips:
+ return "fcsr";
+ case dwarf_fir_mips:
+ return "fir";
+ case dwarf_w0_mips:
+ return "w0";
+ case dwarf_w1_mips:
+ return "w1";
+ case dwarf_w2_mips:
+ return "w2";
+ case dwarf_w3_mips:
+ return "w3";
+ case dwarf_w4_mips:
+ return "w4";
+ case dwarf_w5_mips:
+ return "w5";
+ case dwarf_w6_mips:
+ return "w6";
+ case dwarf_w7_mips:
+ return "w7";
+ case dwarf_w8_mips:
+ return "w8";
+ case dwarf_w9_mips:
+ return "w9";
+ case dwarf_w10_mips:
+ return "w10";
+ case dwarf_w11_mips:
+ return "w11";
+ case dwarf_w12_mips:
+ return "w12";
+ case dwarf_w13_mips:
+ return "w13";
+ case dwarf_w14_mips:
+ return "w14";
+ case dwarf_w15_mips:
+ return "w15";
+ case dwarf_w16_mips:
+ return "w16";
+ case dwarf_w17_mips:
+ return "w17";
+ case dwarf_w18_mips:
+ return "w18";
+ case dwarf_w19_mips:
+ return "w19";
+ case dwarf_w20_mips:
+ return "w20";
+ case dwarf_w21_mips:
+ return "w21";
+ case dwarf_w22_mips:
+ return "w22";
+ case dwarf_w23_mips:
+ return "w23";
+ case dwarf_w24_mips:
+ return "w24";
+ case dwarf_w25_mips:
+ return "w25";
+ case dwarf_w26_mips:
+ return "w26";
+ case dwarf_w27_mips:
+ return "w27";
+ case dwarf_w28_mips:
+ return "w28";
+ case dwarf_w29_mips:
+ return "w29";
+ case dwarf_w30_mips:
+ return "w30";
+ case dwarf_w31_mips:
+ return "w31";
+ case dwarf_mcsr_mips:
+ return "mcsr";
+ case dwarf_mir_mips:
+ return "mir";
+ case dwarf_config5_mips:
+ return "config5";
+ }
+ return nullptr;
+}
+
+bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_pc_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sp_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r30_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_ra_mips;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sr_mips;
+ break;
+ default:
+ return false;
+ }
+ }
+
+ if (reg_kind == eRegisterKindDWARF) {
+ ::memset(&reg_info, 0, sizeof(RegisterInfo));
+ ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+
+ if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips ||
+ reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips ||
+ reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_zero_mips &&
+ (int)reg_num <= dwarf_f31_mips) {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_w0_mips &&
+ (int)reg_num <= dwarf_w31_mips) {
+ reg_info.byte_size = 16;
+ reg_info.format = eFormatVectorOfUInt8;
+ reg_info.encoding = eEncodingVector;
+ } else {
+ return false;
+ }
+
+ reg_info.name = GetRegisterName(reg_num, false);
+ reg_info.alt_name = GetRegisterName(reg_num, true);
+ reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
+ switch (reg_num) {
+ case dwarf_r30_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ break;
+ case dwarf_ra_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ break;
+ case dwarf_sp_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case dwarf_pc_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ break;
+ case dwarf_sr_mips:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ break;
+ default:
+ break;
}
-
- return NULL;
+ return true;
+ }
+ return false;
+}
+
+EmulateInstructionMIPS::MipsOpcode *
+EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) {
+ static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue/Epilogue instructions
+ //----------------------------------------------------------------------
+ {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu,
+ "ADDIU rt, rs, immediate"},
+ {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"},
+ {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"},
+ {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"},
+ {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"},
+ {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"},
+
+ //----------------------------------------------------------------------
+ // MicroMIPS Prologue/Epilogue instructions
+ //----------------------------------------------------------------------
+ {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP,
+ "ADDIU immediate"},
+ {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5,
+ "ADDIUS5 rd,immediate"},
+ {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"},
+ {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
+ "SWM16 reglist,offset(sp)"},
+ {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
+ "SWM32 reglist,offset(base)"},
+ {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32,
+ "SWP rs1,offset(base)"},
+ {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"},
+ {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
+ "LWM16 reglist,offset(sp)"},
+ {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
+ "LWM32 reglist,offset(base)"},
+ {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32,
+ "LWP rd,offset(base)"},
+ {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP,
+ "JRADDIUSP immediate"},
+ //----------------------------------------------------------------------
+
+ // Load/Store instructions
+ //----------------------------------------------------------------------
+ /* Following list of emulated instructions are required by implementation
+ of hardware watchpoint
+ for MIPS in lldb. As we just need the address accessed by instructions,
+ we have generalised
+ all these instructions in 2 functions depending on their addressing
+ modes */
+
+ {"LB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LB rt, offset(base)"},
+ {"LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBE rt, offset(base)"},
+ {"LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBU rt, offset(base)"},
+ {"LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBUE rt, offset(base)"},
+ {"LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDC1 ft, offset(base)"},
+ {"LD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LD rt, offset(base)"},
+ {"LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDL rt, offset(base)"},
+ {"LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDR rt, offset(base)"},
+ {"LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLD rt, offset(base)"},
+ {"LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LDC2 rt, offset(base)"},
+ {"LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "LDXC1 fd, index (base)"},
+ {"LH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LH rt, offset(base)"},
+ {"LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHE rt, offset(base)"},
+ {"LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHU rt, offset(base)"},
+ {"LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHUE rt, offset(base)"},
+ {"LL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LL rt, offset(base)"},
+ {"LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLE rt, offset(base)"},
+ {"LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "LUXC1 fd, index (base)"},
+ {"LW", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LW rt, offset(base)"},
+ {"LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWC1 ft, offset(base)"},
+ {"LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWC2 rt, offset(base)"},
+ {"LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWE rt, offset(base)"},
+ {"LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWL rt, offset(base)"},
+ {"LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWLE rt, offset(base)"},
+ {"LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWR rt, offset(base)"},
+ {"LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWRE rt, offset(base)"},
+ {"LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "LWXC1 fd, index (base)"},
+ {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLX rt, offset(base)"},
+ {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLXE rt, offset(base)"},
+ {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LLDX rt, offset(base)"},
+
+ {"SB", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SB rt, offset(base)"},
+ {"SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SBE rt, offset(base)"},
+ {"SC", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SC rt, offset(base)"},
+ {"SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCE rt, offset(base)"},
+ {"SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCD rt, offset(base)"},
+ {"SD", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SD rt, offset(base)"},
+ {"SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDL rt, offset(base)"},
+ {"SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDR rt, offset(base)"},
+ {"SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDC1 ft, offset(base)"},
+ {"SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SDC2 rt, offset(base)"},
+ {"SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "SDXC1 fs, index(base)"},
+ {"SH", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SH rt, offset(base)"},
+ {"SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SHE rt, offset(base)"},
+ {"SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "SUXC1 fs, index (base)"},
+ {"SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWC1 ft, offset(base)"},
+ {"SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWC2 rt, offset(base)"},
+ {"SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWE rt, offset(base)"},
+ {"SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWL rt, offset(base)"},
+ {"SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWLE rt, offset(base)"},
+ {"SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWR rt, offset(base)"},
+ {"SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWRE rt, offset(base)"},
+ {"SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg,
+ "SWXC1 fs, index (base)"},
+ {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCX rt, offset(base)"},
+ {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCXE rt, offset(base)"},
+ {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SCDX rt, offset(base)"},
+
+ //----------------------------------------------------------------------
+ // MicroMIPS Load/Store instructions
+ //----------------------------------------------------------------------
+ {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LBU16 rt, decoded_offset(base)"},
+ {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LHU16 rt, left_shifted_offset(base)"},
+ {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LW16 rt, left_shifted_offset(base)"},
+ {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "LWGP rt, left_shifted_offset(gp)"},
+ {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SH16 rt, left_shifted_offset(base)"},
+ {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SW16 rt, left_shifted_offset(base)"},
+ {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SWSP rt, left_shifted_offset(base)"},
+ {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm,
+ "SB16 rt, offset(base)"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ {"BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
+ {"BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset"},
+ {"BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset"},
+ {"BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset"},
+ {"BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BGEZALL rt,offset"},
+ {"BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset"},
+ {"BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BGEZAL rs,offset"},
+ {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"},
+ {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset"},
+ {"BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset"},
+ {"BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BLEZALC rs,offset"},
+ {"BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BGEZALC rs,offset"},
+ {"BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BLTZALC rs,offset"},
+ {"BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BGTZALC rs,offset"},
+ {"BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BEQZALC rs,offset"},
+ {"BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,
+ "BNEZALC rs,offset"},
+ {"BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BEQC rs,rt,offset"},
+ {"BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BNEC rs,rt,offset"},
+ {"BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BLTC rs,rt,offset"},
+ {"BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BGEC rs,rt,offset"},
+ {"BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BLTUC rs,rt,offset"},
+ {"BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BGEUC rs,rt,offset"},
+ {"BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset"},
+ {"BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset"},
+ {"BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset"},
+ {"BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset"},
+ {"BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset"},
+ {"BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset"},
+ {"BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset"},
+ {"BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset"},
+ {"BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset"},
+ {"BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset"},
+ {"BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset"},
+ {"BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset"},
+ {"BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BLTZAL rt,offset"},
+ {"BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link,
+ "BLTZALL rt,offset"},
+ {"BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset"},
+ {"BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BOVC rs,rt,offset"},
+ {"BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C,
+ "BNVC rs,rt,offset"},
+ {"J", &EmulateInstructionMIPS::Emulate_J, "J target"},
+ {"JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target"},
+ {"JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target"},
+ {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"},
+ {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"},
+ {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"},
+ {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"},
+ {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"},
+ {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"},
+ {"BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset"},
+ {"BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset"},
+ {"BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset"},
+ {"BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset"},
+ {"BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset"},
+ {"BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset"},
+ {"BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY2F cc, offset"},
+ {"BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY2T cc, offset"},
+ {"BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY4F cc, offset"},
+ {"BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch,
+ "BC1ANY4T cc, offset"},
+ {"BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16"},
+ {"BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16"},
+ {"BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16"},
+ {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"},
+ {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"},
+ {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"},
+ {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"},
+ {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"},
+ {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"},
+ {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"},
+
+ //----------------------------------------------------------------------
+ // MicroMIPS Branch instructions
+ //----------------------------------------------------------------------
+ {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"},
+ {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BEQZ16 rs, offset"},
+ {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BNEZ16 rs, offset"},
+ {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BEQZC rs, offset"},
+ {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BNEZC rs, offset"},
+ {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BGEZALS rs, offset"},
+ {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM,
+ "BLTZALS rs, offset"},
+ {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"},
+ {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"},
+ {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"},
+ {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"},
+ {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"},
+ {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"},
+ {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"},
+ };
+
+ static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
+
+ for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
+ if (!strcasecmp(g_opcodes[i].op_name, op_name))
+ return &g_opcodes[i];
+ }
+
+ return NULL;
}
-bool
-EmulateInstructionMIPS::SetTargetTriple (const ArchSpec &arch)
-{
- if (arch.GetTriple().getArch () == llvm::Triple::mips
- || arch.GetTriple().getArch () == llvm::Triple::mipsel)
- return true;
+uint32_t
+EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data,
+ uint64_t inst_addr) {
+ uint64_t next_inst_size = 0;
+ llvm::MCInst mc_insn;
+ llvm::MCDisassembler::DecodeStatus decode_status;
+ llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
+
+ if (m_use_alt_disaasm)
+ decode_status =
+ m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn,
+ inst_addr, llvm::nulls(), llvm::nulls());
+ else
+ decode_status =
+ m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr,
+ llvm::nulls(), llvm::nulls());
+
+ if (decode_status != llvm::MCDisassembler::Success)
return false;
+
+ return m_insn_info->get(mc_insn.getOpcode()).getSize();
}
-const char *
-EmulateInstructionMIPS::GetRegisterName (unsigned reg_num, bool alternate_name)
-{
- if (alternate_name)
- {
- switch (reg_num)
- {
- case dwarf_sp_mips: return "r29";
- case dwarf_r30_mips: return "r30";
- case dwarf_ra_mips: return "r31";
- case dwarf_f0_mips: return "f0";
- case dwarf_f1_mips: return "f1";
- case dwarf_f2_mips: return "f2";
- case dwarf_f3_mips: return "f3";
- case dwarf_f4_mips: return "f4";
- case dwarf_f5_mips: return "f5";
- case dwarf_f6_mips: return "f6";
- case dwarf_f7_mips: return "f7";
- case dwarf_f8_mips: return "f8";
- case dwarf_f9_mips: return "f9";
- case dwarf_f10_mips: return "f10";
- case dwarf_f11_mips: return "f11";
- case dwarf_f12_mips: return "f12";
- case dwarf_f13_mips: return "f13";
- case dwarf_f14_mips: return "f14";
- case dwarf_f15_mips: return "f15";
- case dwarf_f16_mips: return "f16";
- case dwarf_f17_mips: return "f17";
- case dwarf_f18_mips: return "f18";
- case dwarf_f19_mips: return "f19";
- case dwarf_f20_mips: return "f20";
- case dwarf_f21_mips: return "f21";
- case dwarf_f22_mips: return "f22";
- case dwarf_f23_mips: return "f23";
- case dwarf_f24_mips: return "f24";
- case dwarf_f25_mips: return "f25";
- case dwarf_f26_mips: return "f26";
- case dwarf_f27_mips: return "f27";
- case dwarf_f28_mips: return "f28";
- case dwarf_f29_mips: return "f29";
- case dwarf_f30_mips: return "f30";
- case dwarf_f31_mips: return "f31";
- case dwarf_w0_mips: return "w0";
- case dwarf_w1_mips: return "w1";
- case dwarf_w2_mips: return "w2";
- case dwarf_w3_mips: return "w3";
- case dwarf_w4_mips: return "w4";
- case dwarf_w5_mips: return "w5";
- case dwarf_w6_mips: return "w6";
- case dwarf_w7_mips: return "w7";
- case dwarf_w8_mips: return "w8";
- case dwarf_w9_mips: return "w9";
- case dwarf_w10_mips: return "w10";
- case dwarf_w11_mips: return "w11";
- case dwarf_w12_mips: return "w12";
- case dwarf_w13_mips: return "w13";
- case dwarf_w14_mips: return "w14";
- case dwarf_w15_mips: return "w15";
- case dwarf_w16_mips: return "w16";
- case dwarf_w17_mips: return "w17";
- case dwarf_w18_mips: return "w18";
- case dwarf_w19_mips: return "w19";
- case dwarf_w20_mips: return "w20";
- case dwarf_w21_mips: return "w21";
- case dwarf_w22_mips: return "w22";
- case dwarf_w23_mips: return "w23";
- case dwarf_w24_mips: return "w24";
- case dwarf_w25_mips: return "w25";
- case dwarf_w26_mips: return "w26";
- case dwarf_w27_mips: return "w27";
- case dwarf_w28_mips: return "w28";
- case dwarf_w29_mips: return "w29";
- case dwarf_w30_mips: return "w30";
- case dwarf_w31_mips: return "w31";
- case dwarf_mir_mips: return "mir";
- case dwarf_mcsr_mips: return "mcsr";
- case dwarf_config5_mips: return "config5";
- default:
- break;
- }
- return nullptr;
- }
+bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
+ const Address &inst_addr,
+ Target *target) {
+ m_use_alt_disaasm = false;
- switch (reg_num)
- {
- case dwarf_zero_mips: return "r0";
- case dwarf_r1_mips: return "r1";
- case dwarf_r2_mips: return "r2";
- case dwarf_r3_mips: return "r3";
- case dwarf_r4_mips: return "r4";
- case dwarf_r5_mips: return "r5";
- case dwarf_r6_mips: return "r6";
- case dwarf_r7_mips: return "r7";
- case dwarf_r8_mips: return "r8";
- case dwarf_r9_mips: return "r9";
- case dwarf_r10_mips: return "r10";
- case dwarf_r11_mips: return "r11";
- case dwarf_r12_mips: return "r12";
- case dwarf_r13_mips: return "r13";
- case dwarf_r14_mips: return "r14";
- case dwarf_r15_mips: return "r15";
- case dwarf_r16_mips: return "r16";
- case dwarf_r17_mips: return "r17";
- case dwarf_r18_mips: return "r18";
- case dwarf_r19_mips: return "r19";
- case dwarf_r20_mips: return "r20";
- case dwarf_r21_mips: return "r21";
- case dwarf_r22_mips: return "r22";
- case dwarf_r23_mips: return "r23";
- case dwarf_r24_mips: return "r24";
- case dwarf_r25_mips: return "r25";
- case dwarf_r26_mips: return "r26";
- case dwarf_r27_mips: return "r27";
- case dwarf_gp_mips: return "gp";
- case dwarf_sp_mips: return "sp";
- case dwarf_r30_mips: return "fp";
- case dwarf_ra_mips: return "ra";
- case dwarf_sr_mips: return "sr";
- case dwarf_lo_mips: return "lo";
- case dwarf_hi_mips: return "hi";
- case dwarf_bad_mips: return "bad";
- case dwarf_cause_mips: return "cause";
- case dwarf_pc_mips: return "pc";
- case dwarf_f0_mips: return "f0";
- case dwarf_f1_mips: return "f1";
- case dwarf_f2_mips: return "f2";
- case dwarf_f3_mips: return "f3";
- case dwarf_f4_mips: return "f4";
- case dwarf_f5_mips: return "f5";
- case dwarf_f6_mips: return "f6";
- case dwarf_f7_mips: return "f7";
- case dwarf_f8_mips: return "f8";
- case dwarf_f9_mips: return "f9";
- case dwarf_f10_mips: return "f10";
- case dwarf_f11_mips: return "f11";
- case dwarf_f12_mips: return "f12";
- case dwarf_f13_mips: return "f13";
- case dwarf_f14_mips: return "f14";
- case dwarf_f15_mips: return "f15";
- case dwarf_f16_mips: return "f16";
- case dwarf_f17_mips: return "f17";
- case dwarf_f18_mips: return "f18";
- case dwarf_f19_mips: return "f19";
- case dwarf_f20_mips: return "f20";
- case dwarf_f21_mips: return "f21";
- case dwarf_f22_mips: return "f22";
- case dwarf_f23_mips: return "f23";
- case dwarf_f24_mips: return "f24";
- case dwarf_f25_mips: return "f25";
- case dwarf_f26_mips: return "f26";
- case dwarf_f27_mips: return "f27";
- case dwarf_f28_mips: return "f28";
- case dwarf_f29_mips: return "f29";
- case dwarf_f30_mips: return "f30";
- case dwarf_f31_mips: return "f31";
- case dwarf_fcsr_mips: return "fcsr";
- case dwarf_fir_mips: return "fir";
- case dwarf_w0_mips: return "w0";
- case dwarf_w1_mips: return "w1";
- case dwarf_w2_mips: return "w2";
- case dwarf_w3_mips: return "w3";
- case dwarf_w4_mips: return "w4";
- case dwarf_w5_mips: return "w5";
- case dwarf_w6_mips: return "w6";
- case dwarf_w7_mips: return "w7";
- case dwarf_w8_mips: return "w8";
- case dwarf_w9_mips: return "w9";
- case dwarf_w10_mips: return "w10";
- case dwarf_w11_mips: return "w11";
- case dwarf_w12_mips: return "w12";
- case dwarf_w13_mips: return "w13";
- case dwarf_w14_mips: return "w14";
- case dwarf_w15_mips: return "w15";
- case dwarf_w16_mips: return "w16";
- case dwarf_w17_mips: return "w17";
- case dwarf_w18_mips: return "w18";
- case dwarf_w19_mips: return "w19";
- case dwarf_w20_mips: return "w20";
- case dwarf_w21_mips: return "w21";
- case dwarf_w22_mips: return "w22";
- case dwarf_w23_mips: return "w23";
- case dwarf_w24_mips: return "w24";
- case dwarf_w25_mips: return "w25";
- case dwarf_w26_mips: return "w26";
- case dwarf_w27_mips: return "w27";
- case dwarf_w28_mips: return "w28";
- case dwarf_w29_mips: return "w29";
- case dwarf_w30_mips: return "w30";
- case dwarf_w31_mips: return "w31";
- case dwarf_mcsr_mips: return "mcsr";
- case dwarf_mir_mips: return "mir";
- case dwarf_config5_mips: return "config5";
- }
- return nullptr;
-}
+ if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) {
+ if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) {
+ Error error;
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
-bool
-EmulateInstructionMIPS::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
-{
- if (reg_kind == eRegisterKindGeneric)
- {
- switch (reg_num)
- {
- case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc_mips; break;
- case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp_mips; break;
- case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r30_mips; break;
- case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_ra_mips; break;
- case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sr_mips; break;
- default:
- return false;
- }
- }
+ /*
+ * The address belongs to microMIPS function. To find the size of
+ * next instruction use microMIPS disassembler.
+ */
+ m_use_alt_disaasm = true;
- if (reg_kind == eRegisterKindDWARF)
- {
- ::memset (&reg_info, 0, sizeof(RegisterInfo));
- ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
-
- if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips)
- {
- reg_info.byte_size = 4;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_zero_mips && (int)reg_num <= dwarf_f31_mips)
- {
- reg_info.byte_size = 4;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_w0_mips && (int)reg_num <= dwarf_w31_mips)
- {
- reg_info.byte_size = 16;
- reg_info.format = eFormatVectorOfUInt8;
- reg_info.encoding = eEncodingVector;
- }
- else
- {
- return false;
- }
-
- reg_info.name = GetRegisterName (reg_num, false);
- reg_info.alt_name = GetRegisterName (reg_num, true);
- reg_info.kinds[eRegisterKindDWARF] = reg_num;
-
- switch (reg_num)
- {
- case dwarf_r30_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
- case dwarf_ra_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
- case dwarf_sp_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
- case dwarf_pc_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
- case dwarf_sr_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
- default: break;
- }
- return true;
- }
- return false;
-}
+ uint32_t current_inst_size = insn_opcode.GetByteSize();
+ uint8_t buf[sizeof(uint32_t)];
+ uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
+ Address next_addr(next_inst_addr);
-EmulateInstructionMIPS::MipsOpcode*
-EmulateInstructionMIPS::GetOpcodeForInstruction (const char *op_name)
-{
- static EmulateInstructionMIPS::MipsOpcode
- g_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue/Epilogue instructions
- //----------------------------------------------------------------------
- { "ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu, "ADDIU rt, rs, immediate" },
- { "SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)" },
- { "LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)" },
- { "SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt" },
- { "ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt" },
- { "LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate" },
-
- //----------------------------------------------------------------------
- // MicroMIPS Prologue/Epilogue instructions
- //----------------------------------------------------------------------
- { "ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP, "ADDIU immediate" },
- { "ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5, "ADDIUS5 rd,immediate" },
- { "SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)" },
- { "SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM16 reglist,offset(sp)" },
- { "SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM32 reglist,offset(base)" },
- { "SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWP rs1,offset(base)" },
- { "LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)" },
- { "LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM16 reglist,offset(sp)" },
- { "LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM32 reglist,offset(base)" },
- { "LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWP rd,offset(base)" },
- { "JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP, "JRADDIUSP immediate" },
- //----------------------------------------------------------------------
-
- // Load/Store instructions
- //----------------------------------------------------------------------
- /* Following list of emulated instructions are required by implementation of hardware watchpoint
- for MIPS in lldb. As we just need the address accessed by instructions, we have generalised
- all these instructions in 2 functions depending on their addressing modes */
-
- { "LB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LB rt, offset(base)" },
- { "LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBE rt, offset(base)" },
- { "LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU rt, offset(base)" },
- { "LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBUE rt, offset(base)" },
- { "LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC1 ft, offset(base)" },
- { "LD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LD rt, offset(base)" },
- { "LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDL rt, offset(base)" },
- { "LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDR rt, offset(base)" },
- { "LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLD rt, offset(base)" },
- { "LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC2 rt, offset(base)" },
- { "LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LDXC1 fd, index (base)" },
- { "LH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LH rt, offset(base)" },
- { "LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHE rt, offset(base)" },
- { "LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU rt, offset(base)" },
- { "LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHUE rt, offset(base)" },
- { "LL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LL rt, offset(base)" },
- { "LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLE rt, offset(base)" },
- { "LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LUXC1 fd, index (base)" },
- { "LW", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW rt, offset(base)" },
- { "LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC1 ft, offset(base)" },
- { "LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC2 rt, offset(base)" },
- { "LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWE rt, offset(base)" },
- { "LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWL rt, offset(base)" },
- { "LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWLE rt, offset(base)" },
- { "LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWR rt, offset(base)" },
- { "LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWRE rt, offset(base)" },
- { "LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LWXC1 fd, index (base)" },
- { "LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLX rt, offset(base)" },
- { "LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLXE rt, offset(base)" },
- { "LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLDX rt, offset(base)" },
-
- { "SB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB rt, offset(base)" },
- { "SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SBE rt, offset(base)" },
- { "SC", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SC rt, offset(base)" },
- { "SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCE rt, offset(base)" },
- { "SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCD rt, offset(base)" },
- { "SD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SD rt, offset(base)" },
- { "SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDL rt, offset(base)" },
- { "SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDR rt, offset(base)" },
- { "SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC1 ft, offset(base)" },
- { "SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC2 rt, offset(base)" },
- { "SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SDXC1 fs, index(base)" },
- { "SH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH rt, offset(base)" },
- { "SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SHE rt, offset(base)" },
- { "SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SUXC1 fs, index (base)" },
- { "SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC1 ft, offset(base)" },
- { "SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC2 rt, offset(base)" },
- { "SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWE rt, offset(base)" },
- { "SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWL rt, offset(base)" },
- { "SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWLE rt, offset(base)" },
- { "SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWR rt, offset(base)" },
- { "SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWRE rt, offset(base)" },
- { "SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SWXC1 fs, index (base)" },
- { "SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCX rt, offset(base)" },
- { "SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCXE rt, offset(base)" },
- { "SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCDX rt, offset(base)" },
-
- //----------------------------------------------------------------------
- // MicroMIPS Load/Store instructions
- //----------------------------------------------------------------------
- { "LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU16 rt, decoded_offset(base)" },
- { "LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU16 rt, left_shifted_offset(base)" },
- { "LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW16 rt, left_shifted_offset(base)" },
- { "LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWGP rt, left_shifted_offset(gp)" },
- { "SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH16 rt, left_shifted_offset(base)" },
- { "SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SW16 rt, left_shifted_offset(base)" },
- { "SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWSP rt, left_shifted_offset(base)" },
- { "SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB16 rt, offset(base)" },
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- { "BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset" },
- { "BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset" },
- { "BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset" },
- { "BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset" },
- { "BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BGEZALL rt,offset" },
- { "BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset" },
- { "BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BGEZAL rs,offset" },
- { "BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset" },
- { "BC", &EmulateInstructionMIPS::Emulate_BC, "BC offset" },
- { "BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset" },
- { "BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLEZALC rs,offset" },
- { "BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGEZALC rs,offset" },
- { "BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLTZALC rs,offset" },
- { "BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGTZALC rs,offset" },
- { "BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BEQZALC rs,offset" },
- { "BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BNEZALC rs,offset" },
- { "BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BEQC rs,rt,offset" },
- { "BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNEC rs,rt,offset" },
- { "BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTC rs,rt,offset" },
- { "BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEC rs,rt,offset" },
- { "BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTUC rs,rt,offset" },
- { "BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEUC rs,rt,offset" },
- { "BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset" },
- { "BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset" },
- { "BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset" },
- { "BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset" },
- { "BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset" },
- { "BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset" },
- { "BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset" },
- { "BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset" },
- { "BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset" },
- { "BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset" },
- { "BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset" },
- { "BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset" },
- { "BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZAL rt,offset" },
- { "BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZALL rt,offset" },
- { "BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset" },
- { "BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BOVC rs,rt,offset" },
- { "BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNVC rs,rt,offset" },
- { "J", &EmulateInstructionMIPS::Emulate_J, "J target" },
- { "JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target" },
- { "JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target" },
- { "JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target" },
- { "JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target" },
- { "JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset" },
- { "JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset" },
- { "JR", &EmulateInstructionMIPS::Emulate_JR, "JR target" },
- { "JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target" },
- { "BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset" },
- { "BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset" },
- { "BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset" },
- { "BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1TL cc, offset" },
- { "BC1EQZ", &EmulateInstructionMIPS::Emulate_BC1EQZ, "BC1EQZ ft, offset" },
- { "BC1NEZ", &EmulateInstructionMIPS::Emulate_BC1NEZ, "BC1NEZ ft, offset" },
- { "BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2F cc, offset" },
- { "BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2T cc, offset" },
- { "BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4F cc, offset" },
- { "BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4T cc, offset" },
- { "BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16" },
- { "BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16" },
- { "BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16" },
- { "BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16" },
- { "BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16" },
- { "BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16" },
- { "BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16" },
- { "BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16" },
- { "BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16" },
- { "BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16" },
-
- //----------------------------------------------------------------------
- // MicroMIPS Branch instructions
- //----------------------------------------------------------------------
- { "B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset" },
- { "BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZ16 rs, offset" },
- { "BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZ16 rs, offset" },
- { "BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZC rs, offset" },
- { "BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZC rs, offset" },
- { "BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BGEZALS rs, offset" },
- { "BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BLTZALS rs, offset" },
- { "JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs" },
- { "JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs" },
- { "JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs" },
- { "JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs" },
- { "JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target" },
- { "JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target" },
- { "JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs" },
- };
-
- static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
-
- for (size_t i = 0; i < k_num_mips_opcodes; ++i)
- {
- if (! strcasecmp (g_opcodes[i].op_name, op_name))
- return &g_opcodes[i];
- }
+ const size_t bytes_read =
+ target->ReadMemory(next_addr, /* Address of next instruction */
+ true, /* prefer_file_cache */
+ buf, sizeof(uint32_t), error, &load_addr);
- return NULL;
-}
+ if (bytes_read == 0)
+ return true;
-uint32_t
-EmulateInstructionMIPS::GetSizeOfInstruction (lldb_private::DataExtractor& data, uint64_t inst_addr)
-{
- uint64_t next_inst_size = 0;
- llvm::MCInst mc_insn;
+ DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(),
+ GetAddressByteSize());
+ m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr);
+ return true;
+ } else {
+ /*
+ * If the address class is not eAddressClassCodeAlternateISA then
+ * the function is not microMIPS. In this case instruction size is
+ * always 4 bytes.
+ */
+ m_next_inst_size = 4;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool EmulateInstructionMIPS::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+ m_opcode.SetOpcode32(
+ ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
+ GetByteOrder());
+ }
+ if (!success)
+ m_addr = LLDB_INVALID_ADDRESS;
+ return success;
+}
+
+bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) {
+ bool success = false;
+ llvm::MCInst mc_insn;
+ uint64_t insn_size;
+ DataExtractor data;
+
+ /* Keep the complexity of the decode logic with the llvm::MCDisassembler
+ * class. */
+ if (m_opcode.GetData(data)) {
llvm::MCDisassembler::DecodeStatus decode_status;
- llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
-
+ llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
if (m_use_alt_disaasm)
- decode_status = m_alt_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls());
+ decode_status = m_alt_disasm->getInstruction(
+ mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
else
- decode_status = m_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls());
+ decode_status = m_disasm->getInstruction(
+ mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
if (decode_status != llvm::MCDisassembler::Success)
- return false;
-
- return m_insn_info->get(mc_insn.getOpcode()).getSize();
-}
-
-bool
-EmulateInstructionMIPS::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
-{
- m_use_alt_disaasm = false;
-
- if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
- {
- if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA)
- {
- Error error;
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
-
- /*
- * The address belongs to microMIPS function. To find the size of
- * next instruction use microMIPS disassembler.
- */
- m_use_alt_disaasm = true;
-
- uint32_t current_inst_size = insn_opcode.GetByteSize();
- uint8_t buf[sizeof(uint32_t)];
- uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size;
- Address next_addr (next_inst_addr);
-
- const size_t bytes_read = target->ReadMemory (next_addr, /* Address of next instruction */
- true, /* prefer_file_cache */
- buf,
- sizeof(uint32_t),
- error,
- &load_addr);
-
- if (bytes_read == 0)
- return true;
-
- DataExtractor data (buf, sizeof(uint32_t), GetByteOrder(), GetAddressByteSize());
- m_next_inst_size = GetSizeOfInstruction (data, next_inst_addr);
- return true;
- }
- else
- {
- /*
- * If the address class is not eAddressClassCodeAlternateISA then
- * the function is not microMIPS. In this case instruction size is
- * always 4 bytes.
- */
- m_next_inst_size = 4;
- return true;
- }
- }
- return false;
-}
+ return false;
+ }
-bool
-EmulateInstructionMIPS::ReadInstruction ()
-{
- bool success = false;
- m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
- m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
- }
- if (!success)
- m_addr = LLDB_INVALID_ADDRESS;
- return success;
-}
-
-bool
-EmulateInstructionMIPS::EvaluateInstruction (uint32_t evaluate_options)
-{
- bool success = false;
- llvm::MCInst mc_insn;
- uint64_t insn_size;
- DataExtractor data;
-
- /* Keep the complexity of the decode logic with the llvm::MCDisassembler class. */
- if (m_opcode.GetData (data))
- {
- llvm::MCDisassembler::DecodeStatus decode_status;
- llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
- if (m_use_alt_disaasm)
- decode_status = m_alt_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
- else
- decode_status = m_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
-
- if (decode_status != llvm::MCDisassembler::Success)
- return false;
- }
+ /*
+ * mc_insn.getOpcode() returns decoded opcode. However to make use
+ * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
+ */
+ const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
- /*
- * mc_insn.getOpcode() returns decoded opcode. However to make use
- * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
- */
- const char *op_name = m_insn_info->getName (mc_insn.getOpcode ());
+ if (op_name == NULL)
+ return false;
- if (op_name == NULL)
- return false;
+ /*
+ * Decoding has been done already. Just get the call-back function
+ * and emulate the instruction.
+ */
+ MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
- /*
- * Decoding has been done already. Just get the call-back function
- * and emulate the instruction.
- */
- MipsOpcode *opcode_data = GetOpcodeForInstruction (op_name);
+ if (opcode_data == NULL)
+ return false;
- if (opcode_data == NULL)
- return false;
+ uint64_t old_pc = 0, new_pc = 0;
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- uint64_t old_pc = 0, new_pc = 0;
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ if (auto_advance_pc) {
+ old_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
+ }
- if (auto_advance_pc)
- {
- old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
- }
+ /* emulate instruction */
+ success = (this->*opcode_data->callback)(mc_insn);
+ if (!success)
+ return false;
- /* emulate instruction */
- success = (this->*opcode_data->callback) (mc_insn);
+ if (auto_advance_pc) {
+ new_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
- return false;
+ return false;
- if (auto_advance_pc)
- {
- new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- /* If we haven't changed the PC, change it here */
- if (old_pc == new_pc)
- {
- new_pc += 4;
- Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, new_pc))
- return false;
- }
+ /* If we haven't changed the PC, change it here */
+ if (old_pc == new_pc) {
+ new_pc += 4;
+ Context context;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ new_pc))
+ return false;
}
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const bool can_replace = false;
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const bool can_replace = false;
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0);
- // Our previous PC is in the RA
- row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
+ // Our previous PC is in the RA
+ row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace);
- unwind_plan.AppendRow (row);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
- unwind_plan.SetSourceName ("EmulateInstructionMIPS");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (dwarf_ra_mips);
+ // All other registers are the same.
+ unwind_plan.SetSourceName("EmulateInstructionMIPS");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::nonvolatile_reg_p (uint32_t regnum)
-{
- switch (regnum)
- {
- case dwarf_r16_mips:
- case dwarf_r17_mips:
- case dwarf_r18_mips:
- case dwarf_r19_mips:
- case dwarf_r20_mips:
- case dwarf_r21_mips:
- case dwarf_r22_mips:
- case dwarf_r23_mips:
- case dwarf_gp_mips:
- case dwarf_sp_mips:
- case dwarf_r30_mips:
- case dwarf_ra_mips:
- return true;
- default:
- return false;
- }
+bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) {
+ switch (regnum) {
+ case dwarf_r16_mips:
+ case dwarf_r17_mips:
+ case dwarf_r18_mips:
+ case dwarf_r19_mips:
+ case dwarf_r20_mips:
+ case dwarf_r21_mips:
+ case dwarf_r22_mips:
+ case dwarf_r23_mips:
+ case dwarf_gp_mips:
+ case dwarf_sp_mips:
+ case dwarf_r30_mips:
+ case dwarf_ra_mips:
+ return true;
+ default:
return false;
-}
-
-bool
-EmulateInstructionMIPS::Emulate_ADDiu (llvm::MCInst& insn)
-{
- // ADDIU rt, rs, immediate
- // GPR[rt] <- GPR[rs] + sign_extend(immediate)
-
- uint8_t dst, src;
- bool success = false;
- const uint32_t imm16 = insn.getOperand(2).getImm();
- int64_t imm = SignedBits(imm16, 15, 0);
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- // If immediate value is greater then 2^16 - 1 then clang generate
- // LUI, ADDIU, SUBU instructions in prolog.
- // Example
- // lui $1, 0x2
- // addiu $1, $1, -0x5920
- // subu $sp, $sp, $1
- // In this case, ADDIU dst and src will be same and not equal to sp
- if (dst == src)
- {
- Context context;
+ }
+ return false;
+}
+
+bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) {
+ // ADDIU rt, rs, immediate
+ // GPR[rt] <- GPR[rs] + sign_extend(immediate)
+
+ uint8_t dst, src;
+ bool success = false;
+ const uint32_t imm16 = insn.getOperand(2).getImm();
+ int64_t imm = SignedBits(imm16, 15, 0);
+
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ // If immediate value is greater then 2^16 - 1 then clang generate
+ // LUI, ADDIU, SUBU instructions in prolog.
+ // Example
+ // lui $1, 0x2
+ // addiu $1, $1, -0x5920
+ // subu $sp, $sp, $1
+ // In this case, ADDIU dst and src will be same and not equal to sp
+ if (dst == src) {
+ Context context;
- /* read <src> register */
- const int64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
- if (!success)
- return false;
+ /* read <src> register */
+ const int64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
+ if (!success)
+ return false;
- /* Check if this is daddiu sp, sp, imm16 */
- if (dst == dwarf_sp_mips)
- {
- uint64_t result = src_opd_val + imm;
- RegisterInfo reg_info_sp;
+ /* Check if this is daddiu sp, sp, imm16 */
+ if (dst == dwarf_sp_mips) {
+ uint64_t result = src_opd_val + imm;
+ RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm);
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm);
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
- return true;
- }
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ return true;
+ }
- imm += src_opd_val;
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
+ imm += src_opd_val;
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, imm))
- return false;
- }
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips + dst, imm))
+ return false;
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_SW (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t imm16 = insn.getOperand(2).getImm();
- uint32_t imm = SignedBits(imm16, 15, 0);
- uint32_t src, base;
- int32_t address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t imm16 = insn.getOperand(2).getImm();
+ uint32_t imm = SignedBits(imm16, 15, 0);
+ uint32_t src, base;
+ int32_t address;
+ Context bad_vaddr_context;
- RegisterInfo reg_info_base;
+ RegisterInfo reg_info_base;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- /* We look for sp based non-volatile register stores */
- if (nonvolatile_reg_p (src))
- {
+ /* We look for sp based non-volatile register stores */
+ if (nonvolatile_reg_p(src)) {
- RegisterInfo reg_info_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
- return false;
+ if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-bool
-EmulateInstructionMIPS::Emulate_LW (llvm::MCInst& insn)
-{
- bool success =false;
- uint32_t src, base;
- int32_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src, base;
+ int32_t imm, address;
+ Context bad_vaddr_context;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- imm = insn.getOperand(2).getImm();
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ imm = insn.getOperand(2).getImm();
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- if (nonvolatile_reg_p (src))
- {
- RegisterValue data_src;
- RegisterInfo reg_info_src;
+ if (nonvolatile_reg_p(src)) {
+ RegisterValue data_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- Context context;
- context.type = eContextPopRegisterOffStack;
- context.SetAddress (address);
+ Context context;
+ context.type = eContextPopRegisterOffStack;
+ context.SetAddress(address);
- if (!WriteRegister (context, &reg_info_src, data_src))
- return false;
+ if (!WriteRegister(context, &reg_info_src, data_src))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-bool
-EmulateInstructionMIPS::Emulate_SUBU_ADDU (llvm::MCInst& insn)
-{
- // SUBU sp, <src>, <rt>
- // ADDU sp, <src>, <rt>
- // ADDU dst, sp, <rt>
+bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) {
+ // SUBU sp, <src>, <rt>
+ // ADDU sp, <src>, <rt>
+ // ADDU dst, sp, <rt>
- bool success = false;
- uint64_t result;
- uint8_t src, dst, rt;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ bool success = false;
+ uint64_t result;
+ uint8_t src, dst, rt;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- /* Check if sp is destination register */
- if (dst == dwarf_sp_mips)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
- if (!success)
- return false;
+ /* Check if sp is destination register */
+ if (dst == dwarf_sp_mips) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
- /* read <rt > register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
+ /* read <rt > register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, rt_opd_val);
+ if (!strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
- return true;
- }
- else if (src == dwarf_sp_mips)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
- if (!success)
- return false;
+ return true;
+ } else if (src == dwarf_sp_mips) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
- /* read <rt> register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success);
+ if (!success)
+ return false;
- Context context;
+ /* read <rt> register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
+ Context context;
- context.SetImmediateSigned (result);
- context.type = eContextImmediate;
+ if (!strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, result))
- return false;
- }
+ context.SetImmediateSigned(result);
+ context.type = eContextImmediate;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips + dst, result))
+ return false;
+ }
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LUI (llvm::MCInst& insn)
-{
- // LUI rt, immediate
- // GPR[rt] <- sign_extend(immediate << 16)
+bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
+ // LUI rt, immediate
+ // GPR[rt] <- sign_extend(immediate << 16)
- const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
- int64_t imm = SignedBits(imm32, 31, 0);
- uint8_t rt;
- Context context;
-
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
+ const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
+ int64_t imm = SignedBits(imm32, 31, 0);
+ uint8_t rt;
+ Context context;
- if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, imm))
- return true;
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
- return false;
+ if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
+ imm))
+ return true;
+
+ return false;
}
-bool
-EmulateInstructionMIPS::Emulate_ADDIUSP (llvm::MCInst& insn)
-{
- bool success = false;
- const uint32_t imm9 = insn.getOperand(0).getImm();
- uint64_t result;
+bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
+ bool success = false;
+ const uint32_t imm9 = insn.getOperand(0).getImm();
+ uint64_t result;
- // This instruction operates implicitly on stack pointer, so read <sp> register.
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
- if (!success)
- return false;
+ // This instruction operates implicitly on stack pointer, so read <sp>
+ // register.
+ uint64_t src_opd_val =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
+ if (!success)
+ return false;
- result = src_opd_val + imm9;
+ result = src_opd_val + imm9;
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm9);
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm9);
- // We are adjusting the stack.
- context.type = eContextAdjustStackPointer;
+ // We are adjusting the stack.
+ context.type = eContextAdjustStackPointer;
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
- return true;
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_ADDIUS5 (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base;
- const uint32_t imm4 = insn.getOperand(2).getImm();
- uint64_t result;
+bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base;
+ const uint32_t imm4 = insn.getOperand(2).getImm();
+ uint64_t result;
- // The source and destination register is same for this instruction.
- base = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ // The source and destination register is same for this instruction.
+ base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- // We are looking for stack adjustment only
- if (base == dwarf_sp_mips)
- {
- // Read stack pointer register
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ // We are looking for stack adjustment only
+ if (base == dwarf_sp_mips) {
+ // Read stack pointer register
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- result = src_opd_val + imm4;
+ result = src_opd_val + imm4;
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm4);
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm4);
- // We are adjusting the stack.
- context.type = eContextAdjustStackPointer;
+ // We are adjusting the stack.
+ context.type = eContextAdjustStackPointer;
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result);
- }
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result);
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_SWSP (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t imm5 = insn.getOperand(2).getImm();
- uint32_t src, base;
- Context bad_vaddr_context;
- uint32_t address;
+bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t imm5 = insn.getOperand(2).getImm();
+ uint32_t src, base;
+ Context bad_vaddr_context;
+ uint32_t address;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- RegisterInfo reg_info_base;
+ RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- // read base register
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ // read base register
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
+ &success);
+ if (!success)
+ return false;
- // destination address
- address = address + imm5;
+ // destination address
+ address = address + imm5;
- // We use bad_vaddr_context to store base address which is used by H/W watchpoint
- // Set the bad_vaddr register with base address used in the instruction
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ // We use bad_vaddr_context to store base address which is used by H/W
+ // watchpoint
+ // Set the bad_vaddr register with base address used in the instruction
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- // We look for sp based non-volatile register stores.
- if (base == dwarf_sp_mips && nonvolatile_reg_p (src))
- {
- RegisterInfo reg_info_src = {};
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ // We look for sp based non-volatile register stores.
+ if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
+ RegisterInfo reg_info_src = {};
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
- return false;
+ if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* Emulate SWM16,SWM32 and SWP instruction.
- SWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand).
+ SWM16 always has stack pointer as a base register (but it is still available
+ in MCInst as an operand).
SWM32 and SWP can have base register other than stack pointer.
*/
-bool
-EmulateInstructionMIPS::Emulate_SWM16_32 (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t src, base;
- uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store.
-
- // Base register is second last operand of the instruction.
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
-
- // We are looking for sp based stores so if base is not a stack pointer then don't proceed.
- if (base != dwarf_sp_mips)
- return false;
+bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src, base;
+ uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
+ // no of regs to store.
+
+ // Base register is second last operand of the instruction.
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+
+ // We are looking for sp based stores so if base is not a stack pointer then
+ // don't proceed.
+ if (base != dwarf_sp_mips)
+ return false;
- // offset is always the last operand.
- uint32_t offset = insn.getOperand(num_operands-1).getImm();
+ // offset is always the last operand.
+ uint32_t offset = insn.getOperand(num_operands - 1).getImm();
- RegisterInfo reg_info_base;
- RegisterInfo reg_info_src;
-
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ RegisterInfo reg_info_src;
- // read SP
- uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- // Resulting base addrss
- base_address = base_address + offset;
+ // read SP
+ uint32_t base_address = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- // Total no of registers to be stored are num_operands-2.
- for (uint32_t i = 0; i < num_operands - 2; i++)
- {
- // Get the register number to be stored.
- src = m_reg_info->getEncodingValue (insn.getOperand(i).getReg());
+ // Resulting base addrss
+ base_address = base_address + offset;
- /*
- Record only non-volatile stores.
- This check is required for SWP instruction because source operand could be any register.
- SWM16 and SWM32 instruction always has saved registers as source operands.
- */
- if (!nonvolatile_reg_p (src))
- return false;
+ // Total no of registers to be stored are num_operands-2.
+ for (uint32_t i = 0; i < num_operands - 2; i++) {
+ // Get the register number to be stored.
+ src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ /*
+ Record only non-volatile stores.
+ This check is required for SWP instruction because source operand could
+ be any register.
+ SWM16 and SWM32 instruction always has saved registers as source
+ operands.
+ */
+ if (!nonvolatile_reg_p(src))
+ return false;
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (!WriteMemory (context, base_address, buffer, reg_info_src.byte_size))
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- // Stack address for next register
- base_address = base_address + reg_info_src.byte_size;
- }
- return true;
+ if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size))
+ return false;
+
+ // Stack address for next register
+ base_address = base_address + reg_info_src.byte_size;
+ }
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LWSP (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- uint32_t base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- uint32_t imm5 = insn.getOperand(2).getImm();
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ uint32_t imm5 = insn.getOperand(2).getImm();
+ Context bad_vaddr_context;
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- // read base register
- uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ // read base register
+ uint32_t base_address = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- base_address = base_address + imm5;
+ base_address = base_address + imm5;
- // We use bad_vaddr_context to store base address which is used by H/W watchpoint
- // Set the bad_vaddr register with base address used in the instruction
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, base_address);
+ // We use bad_vaddr_context to store base address which is used by H/W
+ // watchpoint
+ // Set the bad_vaddr register with base address used in the instruction
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ base_address);
- if (base == dwarf_sp_mips && nonvolatile_reg_p (src))
- {
- RegisterValue data_src;
- RegisterInfo reg_info_src;
+ if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) {
+ RegisterValue data_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src,
+ reg_info_src))
+ return false;
- Context context;
- context.type = eContextPopRegisterOffStack;
- context.SetAddress (base_address);
+ Context context;
+ context.type = eContextPopRegisterOffStack;
+ context.SetAddress(base_address);
- if (!WriteRegister (context, &reg_info_src, data_src))
- return false;
+ if (!WriteRegister(context, &reg_info_src, data_src))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* Emulate LWM16, LWM32 and LWP instructions.
- LWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand).
+ LWM16 always has stack pointer as a base register (but it is still available
+ in MCInst as an operand).
LWM32 and LWP can have base register other than stack pointer.
*/
-bool
-EmulateInstructionMIPS::Emulate_LWM16_32 (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t dst, base;
- uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store.
- uint32_t imm = insn.getOperand(num_operands-1).getImm(); // imm is the last operand in the instruction.
-
- // Base register is second last operand of the instruction.
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
-
- // We are looking for sp based loads so if base is not a stack pointer then don't proceed.
- if (base != dwarf_sp_mips)
- return false;
+bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t dst, base;
+ uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on
+ // no of regs to store.
+ uint32_t imm = insn.getOperand(num_operands - 1)
+ .getImm(); // imm is the last operand in the instruction.
+
+ // Base register is second last operand of the instruction.
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+
+ // We are looking for sp based loads so if base is not a stack pointer then
+ // don't proceed.
+ if (base != dwarf_sp_mips)
+ return false;
- uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ uint32_t base_address = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- base_address = base_address + imm;
-
- RegisterValue data_dst;
- RegisterInfo reg_info_dst;
-
- // Total no of registers to be re-stored are num_operands-2.
- for (uint32_t i = 0; i < num_operands - 2; i++)
- {
- // Get the register number to be re-stored.
- dst = m_reg_info->getEncodingValue (insn.getOperand(i).getReg());
-
- /*
- Record only non-volatile loads.
- This check is required for LWP instruction because destination operand could be any register.
- LWM16 and LWM32 instruction always has saved registers as destination operands.
- */
- if (!nonvolatile_reg_p (dst))
- return false;
-
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + dst, reg_info_dst))
- return false;
-
- Context context;
- context.type = eContextPopRegisterOffStack;
- context.SetAddress (base_address + (i*4));
-
- if (!WriteRegister (context, &reg_info_dst, data_dst))
- return false;
- }
+ base_address = base_address + imm;
- return true;
-}
+ RegisterValue data_dst;
+ RegisterInfo reg_info_dst;
-bool
-EmulateInstructionMIPS::Emulate_JRADDIUSP (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t imm5 = insn.getOperand(0).getImm();
+ // Total no of registers to be re-stored are num_operands-2.
+ for (uint32_t i = 0; i < num_operands - 2; i++) {
+ // Get the register number to be re-stored.
+ dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg());
- /* JRADDIUSP immediate
- * PC <- RA
- * SP <- SP + zero_extend(Immediate << 2)
+ /*
+ Record only non-volatile loads.
+ This check is required for LWP instruction because destination operand
+ could be any register.
+ LWM16 and LWM32 instruction always has saved registers as destination
+ operands.
*/
-
- // This instruction operates implicitly on stack pointer, so read <sp> register.
- int32_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
- if (!success)
- return false;
+ if (!nonvolatile_reg_p(dst))
+ return false;
- int32_t ra_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
- if (!success)
- return false;
-
- int32_t result = src_opd_val + imm5;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst,
+ reg_info_dst))
+ return false;
Context context;
+ context.type = eContextPopRegisterOffStack;
+ context.SetAddress(base_address + (i * 4));
- // Update the PC
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, ra_val))
- return false;
-
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm5);
+ if (!WriteRegister(context, &reg_info_dst, data_dst))
+ return false;
+ }
- // We are adjusting stack
- context.type = eContextAdjustStackPointer;
+ return true;
+}
- // update SP
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result))
- return false;
+bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t imm5 = insn.getOperand(0).getImm();
- return true;
+ /* JRADDIUSP immediate
+ * PC <- RA
+ * SP <- SP + zero_extend(Immediate << 2)
+ */
+
+ // This instruction operates implicitly on stack pointer, so read <sp>
+ // register.
+ int32_t src_opd_val =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success);
+ if (!success)
+ return false;
+
+ int32_t ra_val =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success);
+ if (!success)
+ return false;
+
+ int32_t result = src_opd_val + imm5;
+
+ Context context;
+
+ // Update the PC
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ ra_val))
+ return false;
+
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm5);
+
+ // We are adjusting stack
+ context.type = eContextAdjustStackPointer;
+
+ // update SP
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
+ result))
+ return false;
+
+ return true;
}
-static int
-IsAdd64bitOverflow (int32_t a, int32_t b)
-{
- int32_t r = (uint32_t) a + (uint32_t) b;
+static int IsAdd64bitOverflow(int32_t a, int32_t b) {
+ int32_t r = (uint32_t)a + (uint32_t)b;
return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
}
-/*
+/*
Emulate below MIPS branch instructions.
BEQ, BNE : Branch on condition
BEQL, BNEL : Branch likely
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_3ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int32_t offset, pc, target = 0, rs_val, rt_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int32_t offset, pc, target = 0, rs_val, rt_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQ") ||
- !strcasecmp (op_name, "BEQL"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BNE") ||
- !strcasecmp (op_name, "BNEL"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
- BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot
+ BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
+ instructions with no delay slot
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_3ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int32_t offset, pc, target = 0, rs_val, rt_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int32_t offset, pc, target = 0, rs_val, rt_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQC"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEC"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEC"))
- {
- if (rs_val >= rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTUC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEUC"))
- {
- if ((uint32_t)rs_val >= (uint32_t)rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BOVC"))
- {
- if (IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNVC"))
- {
- if (!IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BEQC")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEC")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEC")) {
+ if (rs_val >= rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTUC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEUC")) {
+ if ((uint32_t)rs_val >= (uint32_t)rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BOVC")) {
+ if (IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNVC")) {
+ if (!IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS conditional branch and link instructions.
BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
*/
-bool
-EmulateInstructionMIPS::Emulate_Bcond_Link_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLEZALC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZALC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTZALC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZALC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZALC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZALC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BLEZALC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZALC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTZALC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZALC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZALC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZALC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 4))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS Non-Compact conditional branch and link instructions.
BLTZAL, BGEZAL :
BLTZALL, BGEZALL : Branch likely
*/
-bool
-EmulateInstructionMIPS::Emulate_Bcond_Link (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZAL") ||
- !strcasecmp (op_name, "BLTZALL"))
- {
- if ((int32_t) rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZAL") ||
- !strcasecmp (op_name, "BGEZALL"))
- {
- if ((int32_t) rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
+ if ((int32_t)rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZAL") ||
+ !strcasecmp(op_name, "BGEZALL")) {
+ if ((int32_t)rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_2ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZL") ||
- !strcasecmp (op_name, "BLTZ"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZL") ||
- !strcasecmp (op_name, "BGEZ"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGTZL") ||
- !strcasecmp (op_name, "BGTZ"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BLEZL") ||
- !strcasecmp (op_name, "BLEZ"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
*/
-bool
-EmulateInstructionMIPS::Emulate_BXX_2ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int32_t offset, pc, target = 0;
- int32_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int32_t offset, pc, target = 0;
+ int32_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLEZC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BLTZC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLEZC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
- offset = insn.getOperand(0).getImm();
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- // unconditional branch
- target = pc + offset;
+ // unconditional branch
+ target = pc + offset;
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
/*
@@ -1978,503 +2232,498 @@ EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn)
BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
*/
-bool
-EmulateInstructionMIPS::Emulate_Branch_MM (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t target = 0;
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- bool update_ra = false;
- uint32_t ra_offset = 0;
-
- /*
- * BEQZ16 rs, offset
- * condition <- (GPR[rs] = 0)
- * if condition then
- * PC = PC + sign_ext (offset || 0)
- *
- * BNEZ16 rs, offset
- * condition <- (GPR[rs] != 0)
- * if condition then
- * PC = PC + sign_ext (offset || 0)
- *
- * BEQZC rs, offset (compact instruction: No delay slot)
- * condition <- (GPR[rs] == 0)
- * if condition then
- * PC = PC + 4 + sign_ext (offset || 0)
- */
+bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t target = 0;
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ bool update_ra = false;
+ uint32_t ra_offset = 0;
+
+ /*
+ * BEQZ16 rs, offset
+ * condition <- (GPR[rs] = 0)
+ * if condition then
+ * PC = PC + sign_ext (offset || 0)
+ *
+ * BNEZ16 rs, offset
+ * condition <- (GPR[rs] != 0)
+ * if condition then
+ * PC = PC + sign_ext (offset || 0)
+ *
+ * BEQZC rs, offset (compact instruction: No delay slot)
+ * condition <- (GPR[rs] == 0)
+ * if condition then
+ * PC = PC + 4 + sign_ext (offset || 0)
+ */
+
+ uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int32_t offset = insn.getOperand(1).getImm();
+
+ int32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int32_t offset = insn.getOperand(1).getImm();
+ int32_t rs_val = (int32_t)ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ if (!strcasecmp(op_name, "BEQZ16_MM")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + current_inst_size +
+ m_next_inst_size; // Skip delay slot instruction.
+ } else if (!strcasecmp(op_name, "BNEZ16_MM")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + current_inst_size +
+ m_next_inst_size; // Skip delay slot instruction.
+ } else if (!strcasecmp(op_name, "BEQZC_MM")) {
+ if (rs_val == 0)
+ target = pc + 4 + offset;
+ else
+ target =
+ pc +
+ 4; // 32 bit instruction and does not have delay slot instruction.
+ } else if (!strcasecmp(op_name, "BNEZC_MM")) {
+ if (rs_val != 0)
+ target = pc + 4 + offset;
+ else
+ target =
+ pc +
+ 4; // 32 bit instruction and does not have delay slot instruction.
+ } else if (!strcasecmp(op_name, "BGEZALS_MM")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
- int32_t rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ update_ra = true;
+ ra_offset = 6;
+ } else if (!strcasecmp(op_name, "BLTZALS_MM")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
- if (!strcasecmp (op_name, "BEQZ16_MM"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BNEZ16_MM"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BEQZC_MM"))
- {
- if (rs_val == 0)
- target = pc + 4 + offset;
- else
- target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BNEZC_MM"))
- {
- if (rs_val != 0)
- target = pc + 4 + offset;
- else
- target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
- }
- else if (!strcasecmp (op_name, "BGEZALS_MM"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
-
- update_ra = true;
- ra_offset = 6;
- }
- else if (!strcasecmp (op_name, "BLTZALS_MM"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
-
- update_ra = true;
- ra_offset = 6;
- }
+ update_ra = true;
+ ra_offset = 6;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (update_ra)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
- }
- return true;
+ if (update_ra) {
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + ra_offset))
+ return false;
+ }
+ return true;
}
/* Emulate micromips jump instructions.
JALR16,JALRS16
*/
-bool
-EmulateInstructionMIPS::Emulate_JALRx16_MM (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ra_offset = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
+bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ra_offset = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- uint32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ uint32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- uint32_t rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ uint32_t rs_val = ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "JALR16_MM"))
- ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
- else if (!strcasecmp (op_name, "JALRS16_MM"))
- ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
+ if (!strcasecmp(op_name, "JALR16_MM"))
+ ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
+ else if (!strcasecmp(op_name, "JALRS16_MM"))
+ ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + ra_offset))
+ return false;
- return true;
+ return true;
}
/* Emulate JALS and JALX instructions.
JALS 32 bit instruction with short (2-byte) delay slot.
JALX 32 bit instruction with 4-byte delay slot.
*/
-bool
-EmulateInstructionMIPS::Emulate_JALx (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t offset=0, target=0, pc=0, ra_offset=0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- /*
- * JALS target
- * RA = PC + 6
- * offset = sign_ext (offset << 1)
- * PC = PC[31-27] | offset
- * JALX target
- * RA = PC + 8
- * offset = sign_ext (offset << 2)
- * PC = PC[31-28] | offset
- */
- offset = insn.getOperand(0).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t offset = 0, target = 0, pc = 0, ra_offset = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ /*
+ * JALS target
+ * RA = PC + 6
+ * offset = sign_ext (offset << 1)
+ * PC = PC[31-27] | offset
+ * JALX target
+ * RA = PC + 8
+ * offset = sign_ext (offset << 2)
+ * PC = PC[31-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- // These are PC-region branches and not PC-relative.
- if (!strcasecmp (op_name, "JALS_MM"))
- {
- // target address is in the “current” 128 MB-aligned region
- target = (pc & 0xF8000000UL) | offset;
- ra_offset = 6;
- }
- else if (!strcasecmp (op_name, "JALX_MM"))
- {
- // target address is in the “current” 256 MB-aligned region
- target = (pc & 0xF0000000UL) | offset;
- ra_offset = 8;
- }
+ // These are PC-region branches and not PC-relative.
+ if (!strcasecmp(op_name, "JALS_MM")) {
+ // target address is in the “current” 128 MB-aligned region
+ target = (pc & 0xF8000000UL) | offset;
+ ra_offset = 6;
+ } else if (!strcasecmp(op_name, "JALX_MM")) {
+ // target address is in the “current” 256 MB-aligned region
+ target = (pc & 0xF0000000UL) | offset;
+ ra_offset = 8;
+ }
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + ra_offset))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JALRS (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs=0, rt=0;
- int32_t pc=0, rs_val=0;
-
- /*
- JALRS rt, rs
- GPR[rt] <- PC + 6
- PC <- GPR[rs]
- */
+bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs = 0, rt = 0;
+ int32_t pc = 0, rs_val = 0;
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ /*
+ JALRS rt, rs
+ GPR[rt] <- PC + 6
+ PC <- GPR[rs]
+ */
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- Context context;
+ rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- // This is 4-byte instruction with 2-byte delay slot.
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 6))
- return false;
-
- return true;
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
+
+ // This is 4-byte instruction with 2-byte delay slot.
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
+ pc + 6))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BAL (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
+bool EmulateInstructionMIPS::Emulate_BAL(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
- /*
- * BAL offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 8
- * PC = PC + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BAL offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 8
+ * PC = PC + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BALC (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
+bool EmulateInstructionMIPS::Emulate_BALC(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
- /*
- * BALC offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 4
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BALC offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 4
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 4))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BC (llvm::MCInst& insn)
-{
- bool success = false;
- int32_t offset, pc, target;
+bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
+ bool success = false;
+ int32_t offset, pc, target;
- /*
- * BC offset
- * offset = sign_ext (offset << 2)
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BC offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_J (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t offset, pc;
+bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t offset, pc;
- /*
- * J offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * J offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- pc = (pc & 0xF0000000UL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ pc = (pc & 0xF0000000UL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, pc))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JAL (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t offset, target, pc;
+bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t offset, target, pc;
- /*
- * JAL offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * JAL offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- target = (pc & 0xF0000000UL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ target = (pc & 0xF0000000UL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JALR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- uint32_t pc, rs_val;
+bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ uint32_t pc, rs_val;
- /*
- * JALR rt, rs
- * GPR[rt] = PC + 8
- * PC = GPR[rs]
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ /*
+ * JALR rt, rs
+ * GPR[rt] = PC + 8
+ * PC = GPR[rs]
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JIALC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int32_t target, offset, pc, rt_val;
+bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int32_t target, offset, pc, rt_val;
- /*
- * JIALC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- * RA = PC + 4
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
+ /*
+ * JIALC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ * RA = PC + 4
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips,
+ pc + 4))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JIC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int32_t target, offset, rt_val;
+bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int32_t target, offset, rt_val;
- /*
- * JIC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
+ /*
+ * JIC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- uint32_t rs_val;
+bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ uint32_t rs_val;
- /*
- * JR rs
- * PC = GPR[rs]
- */
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ /*
+ * JR rs
+ * PC = GPR[rs]
+ */
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val))
+ return false;
- return true;
+ return true;
}
/*
@@ -2482,419 +2731,400 @@ EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn)
BC1F, BC1FL : Branch on FP False (L stands for branch likely)
BC1T, BC1TL : Branch on FP True (L stands for branch likely)
*/
-bool
-EmulateInstructionMIPS::Emulate_FP_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int32_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int32_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
- if (!success)
- return false;
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BC1F") ||
- !strcasecmp (op_name, "BC1FL"))
- {
- if ((fcsr & (1 << cc)) == 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1T") ||
- !strcasecmp (op_name, "BC1TL"))
- {
- if ((fcsr & (1 << cc)) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- Context context;
+ fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- return true;
+ if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
+ if ((fcsr & (1 << cc)) == 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
+ if ((fcsr & (1 << cc)) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BC1EQZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint32_t ft_val;
- int32_t target, pc, offset;
-
- /*
- * BC1EQZ ft, offset
- * condition <- (FPR[ft].bit0 == 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint32_t ft_val;
+ int32_t target, pc, offset;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success);
- if (!success)
- return false;
+ /*
+ * BC1EQZ ft, offset
+ * condition <- (FPR[ft].bit0 == 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if ((ft_val & 1) == 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
+ &success);
+ if (!success)
+ return false;
- return true;
+ if ((ft_val & 1) == 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BC1NEZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint32_t ft_val;
- int32_t target, pc, offset;
-
- /*
- * BC1NEZ ft, offset
- * condition <- (FPR[ft].bit0 != 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint32_t ft_val;
+ int32_t target, pc, offset;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success);
- if (!success)
- return false;
+ /*
+ * BC1NEZ ft, offset
+ * condition <- (FPR[ft].bit0 != 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if ((ft_val & 1) != 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0,
+ &success);
+ if (!success)
+ return false;
- return true;
+ if ((ft_val & 1) != 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
/*
Emulate MIPS-3D Branch instructions
- BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes False/True
- BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes False/True
+ BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
+ False/True
+ BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
+ False/True
*/
-bool
-EmulateInstructionMIPS::Emulate_3D_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int32_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int32_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success);
- if (!success)
- return false;
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BC1ANY2F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 3) != 3)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY2T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 3) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 0xf) != 0xf)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 0xf) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- Context context;
+ fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0,
+ &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- return true;
-}
+ if (!strcasecmp(op_name, "BC1ANY2F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 3) != 3)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY2T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 3) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 0xf) != 0xf)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 0xf) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ Context context;
-bool
-EmulateInstructionMIPS::Emulate_BNZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, true);
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BNZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, true);
+bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BNZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, true);
+bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BNZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, true);
+bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, false);
+bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, false);
+bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, false);
}
-bool
-EmulateInstructionMIPS::Emulate_BZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, false);
+bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, false);
}
-bool
-EmulateInstructionMIPS::Emulate_BZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, false);
+bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, false);
}
-bool
-EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz)
-{
- bool success = false, branch_hit = true;
- int32_t target = 0;
- RegisterValue reg_value;
- const uint8_t *ptr = NULL;
+bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, false);
+}
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int32_t offset = insn.getOperand(1).getImm();
+bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
+ int element_byte_size,
+ bool bnz) {
+ bool success = false, branch_hit = true;
+ int32_t target = 0;
+ RegisterValue reg_value;
+ const uint8_t *ptr = NULL;
- int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int32_t offset = insn.getOperand(1).getImm();
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
- ptr = (const uint8_t *)reg_value.GetBytes();
- else
- return false;
+ int32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- for(int i = 0; i < 16 / element_byte_size; i++)
- {
- switch(element_byte_size)
- {
- case 1:
- if((*ptr == 0 && bnz) || (*ptr != 0 && !bnz) )
- branch_hit = false;
- break;
- case 2:
- if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 4:
- if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 8:
- if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- }
- if(!branch_hit)
- break;
- ptr = ptr + element_byte_size;
- }
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
+ ptr = (const uint8_t *)reg_value.GetBytes();
+ else
+ return false;
- if(branch_hit)
- target = pc + offset;
- else
- target = pc + 8;
+ for (int i = 0; i < 16 / element_byte_size; i++) {
+ switch (element_byte_size) {
+ case 1:
+ if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 2:
+ if ((*(const uint16_t *)ptr == 0 && bnz) ||
+ (*(const uint16_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 4:
+ if ((*(const uint32_t *)ptr == 0 && bnz) ||
+ (*(const uint32_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 8:
+ if ((*(const uint64_t *)ptr == 0 && bnz) ||
+ (*(const uint64_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ }
+ if (!branch_hit)
+ break;
+ ptr = ptr + element_byte_size;
+ }
+
+ if (branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_BNZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, true);
+bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, true);
}
-bool
-EmulateInstructionMIPS::Emulate_BZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, false);
+bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, false);
}
-bool
-EmulateInstructionMIPS::Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz)
-{
- bool success = false;
- int32_t target = 0;
- llvm::APInt wr_val = llvm::APInt::getNullValue(128);
- llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
- llvm::APInt zero_value = llvm::APInt::getNullValue(128);
- RegisterValue reg_value;
+bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
+ bool bnz) {
+ bool success = false;
+ int32_t target = 0;
+ llvm::APInt wr_val = llvm::APInt::getNullValue(128);
+ llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
+ llvm::APInt zero_value = llvm::APInt::getNullValue(128);
+ RegisterValue reg_value;
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int32_t offset = insn.getOperand(1).getImm();
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int32_t offset = insn.getOperand(1).getImm();
- int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
+ int32_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ if (!success)
+ return false;
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
- wr_val = reg_value.GetAsUInt128(fail_value);
- else
- return false;
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value))
+ wr_val = reg_value.GetAsUInt128(fail_value);
+ else
+ return false;
- if((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
- target = pc + offset;
- else
- target = pc + 8;
+ if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
+ (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LDST_Imm (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base;
- int32_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base;
+ int32_t imm, address;
+ Context bad_vaddr_context;
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- imm = insn.getOperand(num_operands-1).getImm();
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ imm = insn.getOperand(num_operands - 1).getImm();
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS::Emulate_LDST_Reg (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base, index;
- int32_t address, index_address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS::Emulate_LDST_Reg(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base, index;
+ int32_t address, index_address;
+ Context bad_vaddr_context;
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- index = m_reg_info->getEncodingValue (insn.getOperand(num_operands-1).getReg());
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ index =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
- RegisterInfo reg_info_base, reg_info_index;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base, reg_info_index;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + index, reg_info_index))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
+ reg_info_index))
+ return false;
- /* read base register */
- address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + base, 0, &success);
+ if (!success)
+ return false;
- /* read index register */
- index_address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
- if (!success)
- return false;
+ /* read index register */
+ index_address = (int32_t)ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + index_address;
+ /* destination address */
+ address = address + index_address;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
index f1f92a065956..82c6a0a31e81 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
@@ -1,4 +1,5 @@
-//===-- EmulateInstructionMIPS.h ------------------------------------*- C++ -*-===//
+//===-- EmulateInstructionMIPS.h ------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,286 +11,209 @@
#ifndef EmulateInstructionMIPS_h_
#define EmulateInstructionMIPS_h_
-namespace llvm
-{
- class MCDisassembler;
- class MCSubtargetInfo;
- class MCRegisterInfo;
- class MCAsmInfo;
- class MCContext;
- class MCInstrInfo;
- class MCInst;
+namespace llvm {
+class MCDisassembler;
+class MCSubtargetInfo;
+class MCRegisterInfo;
+class MCAsmInfo;
+class MCContext;
+class MCInstrInfo;
+class MCInst;
}
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
#include "lldb/Interpreter/OptionValue.h"
-class EmulateInstructionMIPS : public lldb_private::EmulateInstruction
-{
-public:
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- lldb_private::InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
- {
- switch (inst_type)
- {
- case lldb_private::eInstructionTypeAny:
- case lldb_private::eInstructionTypePrologueEpilogue:
- case lldb_private::eInstructionTypePCModifying:
- return true;
-
- case lldb_private::eInstructionTypeAll:
- return false;
- }
- return false;
- }
+class EmulateInstructionMIPS : public lldb_private::EmulateInstruction {
+public:
+ static void Initialize();
- lldb_private::ConstString
- GetPluginName() override;
+ static void Terminate();
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ static lldb_private::ConstString GetPluginNameStatic();
- bool
- SetTargetTriple (const lldb_private::ArchSpec &arch) override;
-
- EmulateInstructionMIPS (const lldb_private::ArchSpec &arch);
+ static const char *GetPluginDescriptionStatic();
- bool
- SupportsEmulatingInstructionsOfType (lldb_private::InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch,
+ lldb_private::InstructionType inst_type);
- bool
- ReadInstruction () override;
-
- bool
- EvaluateInstruction (uint32_t evaluate_options) override;
-
- bool
- SetInstruction (const lldb_private::Opcode &insn_opcode,
- const lldb_private::Address &inst_addr,
- lldb_private::Target *target) override;
-
- bool
- TestEmulation (lldb_private::Stream *out_stream,
- lldb_private::ArchSpec &arch,
- lldb_private::OptionValueDictionary *test_data) override
- {
- return false;
+ static bool SupportsEmulatingInstructionsOfTypeStatic(
+ lldb_private::InstructionType inst_type) {
+ switch (inst_type) {
+ case lldb_private::eInstructionTypeAny:
+ case lldb_private::eInstructionTypePrologueEpilogue:
+ case lldb_private::eInstructionTypePCModifying:
+ return true;
+
+ case lldb_private::eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
+
+ EmulateInstructionMIPS(const lldb_private::ArchSpec &arch);
+
+ bool SupportsEmulatingInstructionsOfType(
+ lldb_private::InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ bool ReadInstruction() override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ bool SetInstruction(const lldb_private::Opcode &insn_opcode,
+ const lldb_private::Address &inst_addr,
+ lldb_private::Target *target) override;
- bool
- GetRegisterInfo (lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- lldb_private::RegisterInfo &reg_info) override;
+ bool TestEmulation(lldb_private::Stream *out_stream,
+ lldb_private::ArchSpec &arch,
+ lldb_private::OptionValueDictionary *test_data) override {
+ return false;
+ }
- bool
- CreateFunctionEntryUnwind (lldb_private::UnwindPlan &unwind_plan) override;
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ lldb_private::RegisterInfo &reg_info) override;
+ bool
+ CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
protected:
+ typedef struct {
+ const char *op_name;
+ bool (EmulateInstructionMIPS::*callback)(llvm::MCInst &insn);
+ const char *insn_name;
+ } MipsOpcode;
- typedef struct
- {
- const char *op_name;
- bool (EmulateInstructionMIPS::*callback) (llvm::MCInst& insn);
- const char *insn_name;
- } MipsOpcode;
-
- static MipsOpcode*
- GetOpcodeForInstruction (const char *op_name);
+ static MipsOpcode *GetOpcodeForInstruction(const char *op_name);
- uint32_t
- GetSizeOfInstruction (lldb_private::DataExtractor& data, uint64_t inst_addr);
+ uint32_t GetSizeOfInstruction(lldb_private::DataExtractor &data,
+ uint64_t inst_addr);
- bool
- Emulate_ADDiu (llvm::MCInst& insn);
+ bool Emulate_ADDiu(llvm::MCInst &insn);
- bool
- Emulate_SUBU_ADDU (llvm::MCInst& insn);
+ bool Emulate_SUBU_ADDU(llvm::MCInst &insn);
- bool
- Emulate_LUI (llvm::MCInst& insn);
+ bool Emulate_LUI(llvm::MCInst &insn);
- bool
- Emulate_SW (llvm::MCInst& insn);
+ bool Emulate_SW(llvm::MCInst &insn);
- bool
- Emulate_LW (llvm::MCInst& insn);
+ bool Emulate_LW(llvm::MCInst &insn);
- bool
- Emulate_ADDIUSP (llvm::MCInst& insn);
+ bool Emulate_ADDIUSP(llvm::MCInst &insn);
- bool
- Emulate_ADDIUS5 (llvm::MCInst& insn);
+ bool Emulate_ADDIUS5(llvm::MCInst &insn);
- bool
- Emulate_SWSP (llvm::MCInst& insn);
+ bool Emulate_SWSP(llvm::MCInst &insn);
- bool
- Emulate_SWM16_32 (llvm::MCInst& insn);
+ bool Emulate_SWM16_32(llvm::MCInst &insn);
- bool
- Emulate_LWSP (llvm::MCInst& insn);
+ bool Emulate_LWSP(llvm::MCInst &insn);
- bool
- Emulate_LWM16_32 (llvm::MCInst& insn);
+ bool Emulate_LWM16_32(llvm::MCInst &insn);
- bool
- Emulate_JRADDIUSP (llvm::MCInst& insn);
+ bool Emulate_JRADDIUSP(llvm::MCInst &insn);
- bool
- Emulate_LDST_Imm (llvm::MCInst& insn);
+ bool Emulate_LDST_Imm(llvm::MCInst &insn);
- bool
- Emulate_LDST_Reg (llvm::MCInst& insn);
+ bool Emulate_LDST_Reg(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops_C(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link_C (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link(llvm::MCInst &insn);
- bool
- Emulate_FP_branch (llvm::MCInst& insn);
+ bool Emulate_FP_branch(llvm::MCInst &insn);
- bool
- Emulate_3D_branch (llvm::MCInst& insn);
+ bool Emulate_3D_branch(llvm::MCInst &insn);
- bool
- Emulate_BAL (llvm::MCInst& insn);
+ bool Emulate_BAL(llvm::MCInst &insn);
- bool
- Emulate_BALC (llvm::MCInst& insn);
+ bool Emulate_BALC(llvm::MCInst &insn);
- bool
- Emulate_BC (llvm::MCInst& insn);
+ bool Emulate_BC(llvm::MCInst &insn);
- bool
- Emulate_J (llvm::MCInst& insn);
+ bool Emulate_J(llvm::MCInst &insn);
- bool
- Emulate_JAL (llvm::MCInst& insn);
+ bool Emulate_JAL(llvm::MCInst &insn);
- bool
- Emulate_JALR (llvm::MCInst& insn);
+ bool Emulate_JALR(llvm::MCInst &insn);
- bool
- Emulate_JIALC (llvm::MCInst& insn);
+ bool Emulate_JIALC(llvm::MCInst &insn);
- bool
- Emulate_JIC (llvm::MCInst& insn);
+ bool Emulate_JIC(llvm::MCInst &insn);
- bool
- Emulate_JR (llvm::MCInst& insn);
+ bool Emulate_JR(llvm::MCInst &insn);
- bool
- Emulate_BC1EQZ (llvm::MCInst& insn);
+ bool Emulate_BC1EQZ(llvm::MCInst &insn);
- bool
- Emulate_BC1NEZ (llvm::MCInst& insn);
+ bool Emulate_BC1NEZ(llvm::MCInst &insn);
- bool
- Emulate_BNZB (llvm::MCInst& insn);
+ bool Emulate_BNZB(llvm::MCInst &insn);
- bool
- Emulate_BNZH (llvm::MCInst& insn);
+ bool Emulate_BNZH(llvm::MCInst &insn);
- bool
- Emulate_BNZW (llvm::MCInst& insn);
+ bool Emulate_BNZW(llvm::MCInst &insn);
- bool
- Emulate_BNZD (llvm::MCInst& insn);
+ bool Emulate_BNZD(llvm::MCInst &insn);
- bool
- Emulate_BZB (llvm::MCInst& insn);
+ bool Emulate_BZB(llvm::MCInst &insn);
- bool
- Emulate_BZH (llvm::MCInst& insn);
+ bool Emulate_BZH(llvm::MCInst &insn);
- bool
- Emulate_BZW (llvm::MCInst& insn);
+ bool Emulate_BZW(llvm::MCInst &insn);
- bool
- Emulate_BZD (llvm::MCInst& insn);
+ bool Emulate_BZD(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz);
+ bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size,
+ bool bnz);
- bool
- Emulate_BNZV (llvm::MCInst& insn);
+ bool Emulate_BNZV(llvm::MCInst &insn);
- bool
- Emulate_BZV (llvm::MCInst& insn);
+ bool Emulate_BZV(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz);
+ bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz);
- bool
- Emulate_B16_MM (llvm::MCInst& insn);
+ bool Emulate_B16_MM(llvm::MCInst &insn);
- bool
- Emulate_Branch_MM (llvm::MCInst& insn);
+ bool Emulate_Branch_MM(llvm::MCInst &insn);
- bool
- Emulate_JALRx16_MM (llvm::MCInst& insn);
+ bool Emulate_JALRx16_MM(llvm::MCInst &insn);
- bool
- Emulate_JALx (llvm::MCInst& insn);
+ bool Emulate_JALx(llvm::MCInst &insn);
- bool
- Emulate_JALRS (llvm::MCInst& insn);
+ bool Emulate_JALRS(llvm::MCInst &insn);
- bool
- nonvolatile_reg_p (uint32_t regnum);
+ bool nonvolatile_reg_p(uint32_t regnum);
- const char *
- GetRegisterName (unsigned reg_num, bool altnernate_name);
+ const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
private:
- std::unique_ptr<llvm::MCDisassembler> m_disasm;
- std::unique_ptr<llvm::MCDisassembler> m_alt_disasm;
- std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
- std::unique_ptr<llvm::MCSubtargetInfo> m_alt_subtype_info;
- std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
- std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
- std::unique_ptr<llvm::MCContext> m_context;
- std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
- uint32_t m_next_inst_size;
- bool m_use_alt_disaasm;
+ std::unique_ptr<llvm::MCDisassembler> m_disasm;
+ std::unique_ptr<llvm::MCDisassembler> m_alt_disasm;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_alt_subtype_info;
+ std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
+ std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
+ std::unique_ptr<llvm::MCContext> m_context;
+ std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
+ uint32_t m_next_inst_size;
+ bool m_use_alt_disaasm;
};
-#endif // EmulateInstructionMIPS_h_
+#endif // EmulateInstructionMIPS_h_
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 7b4b6aa0100e..c054760be8a0 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -1,4 +1,5 @@
-//===-- EmulateInstructionMIPS64.cpp -------------------------------*- C++ -*-===//
+//===-- EmulateInstructionMIPS64.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,24 +12,25 @@
#include <stdlib.h>
-#include "llvm-c/Disassembler.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCDisassembler/MCDisassembler.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCContext.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Opcode.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Host/PosixApi.h"
#include "lldb/Symbol/UnwindPlan.h"
+#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/ADT/STLExtras.h"
@@ -41,7 +43,6 @@ using namespace lldb_private;
#define UInt(x) ((uint64_t)x)
#define integer int64_t
-
//----------------------------------------------------------------------
//
// EmulateInstructionMIPS64 implementation
@@ -50,987 +51,1262 @@ using namespace lldb_private;
#ifdef __mips__
extern "C" {
- void LLVMInitializeMipsTargetInfo ();
- void LLVMInitializeMipsTarget ();
- void LLVMInitializeMipsAsmPrinter ();
- void LLVMInitializeMipsTargetMC ();
- void LLVMInitializeMipsDisassembler ();
+void LLVMInitializeMipsTargetInfo();
+void LLVMInitializeMipsTarget();
+void LLVMInitializeMipsAsmPrinter();
+void LLVMInitializeMipsTargetMC();
+void LLVMInitializeMipsDisassembler();
}
#endif
-EmulateInstructionMIPS64::EmulateInstructionMIPS64 (const lldb_private::ArchSpec &arch) :
- EmulateInstruction (arch)
-{
- /* Create instance of llvm::MCDisassembler */
- std::string Error;
- llvm::Triple triple = arch.GetTriple();
- const llvm::Target *target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
-
- /*
- * If we fail to get the target then we haven't registered it. The SystemInitializerCommon
- * does not initialize targets, MCs and disassemblers. However we need the MCDisassembler
- * to decode the instructions so that the decoding complexity stays with LLVM.
- * Initialize the MIPS targets and disassemblers.
- */
+EmulateInstructionMIPS64::EmulateInstructionMIPS64(
+ const lldb_private::ArchSpec &arch)
+ : EmulateInstruction(arch) {
+ /* Create instance of llvm::MCDisassembler */
+ std::string Error;
+ llvm::Triple triple = arch.GetTriple();
+ const llvm::Target *target =
+ llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
+
+/*
+ * If we fail to get the target then we haven't registered it. The
+ * SystemInitializerCommon
+ * does not initialize targets, MCs and disassemblers. However we need the
+ * MCDisassembler
+ * to decode the instructions so that the decoding complexity stays with LLVM.
+ * Initialize the MIPS targets and disassemblers.
+*/
#ifdef __mips__
- if (!target)
- {
- LLVMInitializeMipsTargetInfo ();
- LLVMInitializeMipsTarget ();
- LLVMInitializeMipsAsmPrinter ();
- LLVMInitializeMipsTargetMC ();
- LLVMInitializeMipsDisassembler ();
- target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
- }
+ if (!target) {
+ LLVMInitializeMipsTargetInfo();
+ LLVMInitializeMipsTarget();
+ LLVMInitializeMipsAsmPrinter();
+ LLVMInitializeMipsTargetMC();
+ LLVMInitializeMipsDisassembler();
+ target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error);
+ }
#endif
- assert (target);
-
- llvm::StringRef cpu;
-
- switch (arch.GetCore())
- {
- case ArchSpec::eCore_mips32:
- case ArchSpec::eCore_mips32el:
- cpu = "mips32"; break;
- case ArchSpec::eCore_mips32r2:
- case ArchSpec::eCore_mips32r2el:
- cpu = "mips32r2"; break;
- case ArchSpec::eCore_mips32r3:
- case ArchSpec::eCore_mips32r3el:
- cpu = "mips32r3"; break;
- case ArchSpec::eCore_mips32r5:
- case ArchSpec::eCore_mips32r5el:
- cpu = "mips32r5"; break;
- case ArchSpec::eCore_mips32r6:
- case ArchSpec::eCore_mips32r6el:
- cpu = "mips32r6"; break;
- case ArchSpec::eCore_mips64:
- case ArchSpec::eCore_mips64el:
- cpu = "mips64"; break;
- case ArchSpec::eCore_mips64r2:
- case ArchSpec::eCore_mips64r2el:
- cpu = "mips64r2"; break;
- case ArchSpec::eCore_mips64r3:
- case ArchSpec::eCore_mips64r3el:
- cpu = "mips64r3"; break;
- case ArchSpec::eCore_mips64r5:
- case ArchSpec::eCore_mips64r5el:
- cpu = "mips64r5"; break;
- case ArchSpec::eCore_mips64r6:
- case ArchSpec::eCore_mips64r6el:
- cpu = "mips64r6"; break;
- default:
- cpu = "generic"; break;
- }
-
- std::string features = "";
- uint32_t arch_flags = arch.GetFlags ();
- if (arch_flags & ArchSpec::eMIPSAse_msa)
- features += "+msa,";
- if (arch_flags & ArchSpec::eMIPSAse_dsp)
- features += "+dsp,";
- if (arch_flags & ArchSpec::eMIPSAse_dspr2)
- features += "+dspr2,";
- if (arch_flags & ArchSpec::eMIPSAse_mips16)
- features += "+mips16,";
- if (arch_flags & ArchSpec::eMIPSAse_micromips)
- features += "+micromips,";
-
- m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
- assert (m_reg_info.get());
-
- m_insn_info.reset (target->createMCInstrInfo());
- assert (m_insn_info.get());
-
- m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
- m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
- assert (m_asm_info.get() && m_subtype_info.get());
-
- m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
- assert (m_context.get());
-
- m_disasm.reset (target->createMCDisassembler (*m_subtype_info, *m_context));
- assert (m_disasm.get());
+ assert(target);
+
+ llvm::StringRef cpu;
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_mips32:
+ case ArchSpec::eCore_mips32el:
+ cpu = "mips32";
+ break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r2el:
+ cpu = "mips32r2";
+ break;
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r3el:
+ cpu = "mips32r3";
+ break;
+ case ArchSpec::eCore_mips32r5:
+ case ArchSpec::eCore_mips32r5el:
+ cpu = "mips32r5";
+ break;
+ case ArchSpec::eCore_mips32r6:
+ case ArchSpec::eCore_mips32r6el:
+ cpu = "mips32r6";
+ break;
+ case ArchSpec::eCore_mips64:
+ case ArchSpec::eCore_mips64el:
+ cpu = "mips64";
+ break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r2el:
+ cpu = "mips64r2";
+ break;
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r3el:
+ cpu = "mips64r3";
+ break;
+ case ArchSpec::eCore_mips64r5:
+ case ArchSpec::eCore_mips64r5el:
+ cpu = "mips64r5";
+ break;
+ case ArchSpec::eCore_mips64r6:
+ case ArchSpec::eCore_mips64r6el:
+ cpu = "mips64r6";
+ break;
+ default:
+ cpu = "generic";
+ break;
+ }
+
+ std::string features = "";
+ uint32_t arch_flags = arch.GetFlags();
+ if (arch_flags & ArchSpec::eMIPSAse_msa)
+ features += "+msa,";
+ if (arch_flags & ArchSpec::eMIPSAse_dsp)
+ features += "+dsp,";
+ if (arch_flags & ArchSpec::eMIPSAse_dspr2)
+ features += "+dspr2,";
+ if (arch_flags & ArchSpec::eMIPSAse_mips16)
+ features += "+mips16,";
+ if (arch_flags & ArchSpec::eMIPSAse_micromips)
+ features += "+micromips,";
+
+ m_reg_info.reset(target->createMCRegInfo(triple.getTriple()));
+ assert(m_reg_info.get());
+
+ m_insn_info.reset(target->createMCInstrInfo());
+ assert(m_insn_info.get());
+
+ m_asm_info.reset(target->createMCAsmInfo(*m_reg_info, triple.getTriple()));
+ m_subtype_info.reset(
+ target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
+ assert(m_asm_info.get() && m_subtype_info.get());
+
+ m_context.reset(
+ new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
+ assert(m_context.get());
+
+ m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
+ assert(m_disasm.get());
}
-void
-EmulateInstructionMIPS64::Initialize ()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic (),
- GetPluginDescriptionStatic (),
- CreateInstance);
+void EmulateInstructionMIPS64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-EmulateInstructionMIPS64::Terminate ()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void EmulateInstructionMIPS64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-ConstString
-EmulateInstructionMIPS64::GetPluginNameStatic ()
-{
- ConstString g_plugin_name ("lldb.emulate-instruction.mips64");
- return g_plugin_name;
+ConstString EmulateInstructionMIPS64::GetPluginNameStatic() {
+ ConstString g_plugin_name("lldb.emulate-instruction.mips64");
+ return g_plugin_name;
}
-lldb_private::ConstString
-EmulateInstructionMIPS64::GetPluginName()
-{
- static ConstString g_plugin_name ("EmulateInstructionMIPS64");
- return g_plugin_name;
+lldb_private::ConstString EmulateInstructionMIPS64::GetPluginName() {
+ static ConstString g_plugin_name("EmulateInstructionMIPS64");
+ return g_plugin_name;
}
-const char *
-EmulateInstructionMIPS64::GetPluginDescriptionStatic ()
-{
- return "Emulate instructions for the MIPS64 architecture.";
+const char *EmulateInstructionMIPS64::GetPluginDescriptionStatic() {
+ return "Emulate instructions for the MIPS64 architecture.";
}
EmulateInstruction *
-EmulateInstructionMIPS64::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
-{
- if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
- {
- if (arch.GetTriple().getArch() == llvm::Triple::mips64
- || arch.GetTriple().getArch() == llvm::Triple::mips64el)
- {
- std::auto_ptr<EmulateInstructionMIPS64> emulate_insn_ap (new EmulateInstructionMIPS64 (arch));
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
+EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(
+ inst_type)) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
+ arch.GetTriple().getArch() == llvm::Triple::mips64el) {
+ std::auto_ptr<EmulateInstructionMIPS64> emulate_insn_ap(
+ new EmulateInstructionMIPS64(arch));
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
}
-
- return NULL;
-}
+ }
-bool
-EmulateInstructionMIPS64::SetTargetTriple (const ArchSpec &arch)
-{
- if (arch.GetTriple().getArch () == llvm::Triple::mips64
- || arch.GetTriple().getArch () == llvm::Triple::mips64el)
- return true;
- return false;
+ return NULL;
}
-const char *
-EmulateInstructionMIPS64::GetRegisterName (unsigned reg_num, bool alternate_name)
-{
- if (alternate_name)
- {
- switch (reg_num)
- {
- case dwarf_sp_mips64: return "r29";
- case dwarf_r30_mips64: return "r30";
- case dwarf_ra_mips64: return "r31";
- case dwarf_f0_mips64: return "f0";
- case dwarf_f1_mips64: return "f1";
- case dwarf_f2_mips64: return "f2";
- case dwarf_f3_mips64: return "f3";
- case dwarf_f4_mips64: return "f4";
- case dwarf_f5_mips64: return "f5";
- case dwarf_f6_mips64: return "f6";
- case dwarf_f7_mips64: return "f7";
- case dwarf_f8_mips64: return "f8";
- case dwarf_f9_mips64: return "f9";
- case dwarf_f10_mips64: return "f10";
- case dwarf_f11_mips64: return "f11";
- case dwarf_f12_mips64: return "f12";
- case dwarf_f13_mips64: return "f13";
- case dwarf_f14_mips64: return "f14";
- case dwarf_f15_mips64: return "f15";
- case dwarf_f16_mips64: return "f16";
- case dwarf_f17_mips64: return "f17";
- case dwarf_f18_mips64: return "f18";
- case dwarf_f19_mips64: return "f19";
- case dwarf_f20_mips64: return "f20";
- case dwarf_f21_mips64: return "f21";
- case dwarf_f22_mips64: return "f22";
- case dwarf_f23_mips64: return "f23";
- case dwarf_f24_mips64: return "f24";
- case dwarf_f25_mips64: return "f25";
- case dwarf_f26_mips64: return "f26";
- case dwarf_f27_mips64: return "f27";
- case dwarf_f28_mips64: return "f28";
- case dwarf_f29_mips64: return "f29";
- case dwarf_f30_mips64: return "f30";
- case dwarf_f31_mips64: return "f31";
- case dwarf_w0_mips64: return "w0";
- case dwarf_w1_mips64: return "w1";
- case dwarf_w2_mips64: return "w2";
- case dwarf_w3_mips64: return "w3";
- case dwarf_w4_mips64: return "w4";
- case dwarf_w5_mips64: return "w5";
- case dwarf_w6_mips64: return "w6";
- case dwarf_w7_mips64: return "w7";
- case dwarf_w8_mips64: return "w8";
- case dwarf_w9_mips64: return "w9";
- case dwarf_w10_mips64: return "w10";
- case dwarf_w11_mips64: return "w11";
- case dwarf_w12_mips64: return "w12";
- case dwarf_w13_mips64: return "w13";
- case dwarf_w14_mips64: return "w14";
- case dwarf_w15_mips64: return "w15";
- case dwarf_w16_mips64: return "w16";
- case dwarf_w17_mips64: return "w17";
- case dwarf_w18_mips64: return "w18";
- case dwarf_w19_mips64: return "w19";
- case dwarf_w20_mips64: return "w20";
- case dwarf_w21_mips64: return "w21";
- case dwarf_w22_mips64: return "w22";
- case dwarf_w23_mips64: return "w23";
- case dwarf_w24_mips64: return "w24";
- case dwarf_w25_mips64: return "w25";
- case dwarf_w26_mips64: return "w26";
- case dwarf_w27_mips64: return "w27";
- case dwarf_w28_mips64: return "w28";
- case dwarf_w29_mips64: return "w29";
- case dwarf_w30_mips64: return "w30";
- case dwarf_w31_mips64: return "w31";
- case dwarf_mir_mips64: return "mir";
- case dwarf_mcsr_mips64: return "mcsr";
- case dwarf_config5_mips64: return "config5";
- default:
- break;
- }
- return nullptr;
- }
+bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
+ arch.GetTriple().getArch() == llvm::Triple::mips64el)
+ return true;
+ return false;
+}
- switch (reg_num)
- {
- case dwarf_zero_mips64: return "r0";
- case dwarf_r1_mips64: return "r1";
- case dwarf_r2_mips64: return "r2";
- case dwarf_r3_mips64: return "r3";
- case dwarf_r4_mips64: return "r4";
- case dwarf_r5_mips64: return "r5";
- case dwarf_r6_mips64: return "r6";
- case dwarf_r7_mips64: return "r7";
- case dwarf_r8_mips64: return "r8";
- case dwarf_r9_mips64: return "r9";
- case dwarf_r10_mips64: return "r10";
- case dwarf_r11_mips64: return "r11";
- case dwarf_r12_mips64: return "r12";
- case dwarf_r13_mips64: return "r13";
- case dwarf_r14_mips64: return "r14";
- case dwarf_r15_mips64: return "r15";
- case dwarf_r16_mips64: return "r16";
- case dwarf_r17_mips64: return "r17";
- case dwarf_r18_mips64: return "r18";
- case dwarf_r19_mips64: return "r19";
- case dwarf_r20_mips64: return "r20";
- case dwarf_r21_mips64: return "r21";
- case dwarf_r22_mips64: return "r22";
- case dwarf_r23_mips64: return "r23";
- case dwarf_r24_mips64: return "r24";
- case dwarf_r25_mips64: return "r25";
- case dwarf_r26_mips64: return "r26";
- case dwarf_r27_mips64: return "r27";
- case dwarf_gp_mips64: return "gp";
- case dwarf_sp_mips64: return "sp";
- case dwarf_r30_mips64: return "fp";
- case dwarf_ra_mips64: return "ra";
- case dwarf_sr_mips64: return "sr";
- case dwarf_lo_mips64: return "lo";
- case dwarf_hi_mips64: return "hi";
- case dwarf_bad_mips64: return "bad";
- case dwarf_cause_mips64: return "cause";
- case dwarf_pc_mips64: return "pc";
- case dwarf_f0_mips64: return "f0";
- case dwarf_f1_mips64: return "f1";
- case dwarf_f2_mips64: return "f2";
- case dwarf_f3_mips64: return "f3";
- case dwarf_f4_mips64: return "f4";
- case dwarf_f5_mips64: return "f5";
- case dwarf_f6_mips64: return "f6";
- case dwarf_f7_mips64: return "f7";
- case dwarf_f8_mips64: return "f8";
- case dwarf_f9_mips64: return "f9";
- case dwarf_f10_mips64: return "f10";
- case dwarf_f11_mips64: return "f11";
- case dwarf_f12_mips64: return "f12";
- case dwarf_f13_mips64: return "f13";
- case dwarf_f14_mips64: return "f14";
- case dwarf_f15_mips64: return "f15";
- case dwarf_f16_mips64: return "f16";
- case dwarf_f17_mips64: return "f17";
- case dwarf_f18_mips64: return "f18";
- case dwarf_f19_mips64: return "f19";
- case dwarf_f20_mips64: return "f20";
- case dwarf_f21_mips64: return "f21";
- case dwarf_f22_mips64: return "f22";
- case dwarf_f23_mips64: return "f23";
- case dwarf_f24_mips64: return "f24";
- case dwarf_f25_mips64: return "f25";
- case dwarf_f26_mips64: return "f26";
- case dwarf_f27_mips64: return "f27";
- case dwarf_f28_mips64: return "f28";
- case dwarf_f29_mips64: return "f29";
- case dwarf_f30_mips64: return "f30";
- case dwarf_f31_mips64: return "f31";
- case dwarf_fcsr_mips64: return "fcsr";
- case dwarf_fir_mips64: return "fir";
- case dwarf_w0_mips64: return "w0";
- case dwarf_w1_mips64: return "w1";
- case dwarf_w2_mips64: return "w2";
- case dwarf_w3_mips64: return "w3";
- case dwarf_w4_mips64: return "w4";
- case dwarf_w5_mips64: return "w5";
- case dwarf_w6_mips64: return "w6";
- case dwarf_w7_mips64: return "w7";
- case dwarf_w8_mips64: return "w8";
- case dwarf_w9_mips64: return "w9";
- case dwarf_w10_mips64: return "w10";
- case dwarf_w11_mips64: return "w11";
- case dwarf_w12_mips64: return "w12";
- case dwarf_w13_mips64: return "w13";
- case dwarf_w14_mips64: return "w14";
- case dwarf_w15_mips64: return "w15";
- case dwarf_w16_mips64: return "w16";
- case dwarf_w17_mips64: return "w17";
- case dwarf_w18_mips64: return "w18";
- case dwarf_w19_mips64: return "w19";
- case dwarf_w20_mips64: return "w20";
- case dwarf_w21_mips64: return "w21";
- case dwarf_w22_mips64: return "w22";
- case dwarf_w23_mips64: return "w23";
- case dwarf_w24_mips64: return "w24";
- case dwarf_w25_mips64: return "w25";
- case dwarf_w26_mips64: return "w26";
- case dwarf_w27_mips64: return "w27";
- case dwarf_w28_mips64: return "w28";
- case dwarf_w29_mips64: return "w29";
- case dwarf_w30_mips64: return "w30";
- case dwarf_w31_mips64: return "w31";
- case dwarf_mcsr_mips64: return "mcsr";
- case dwarf_mir_mips64: return "mir";
- case dwarf_config5_mips64: return "config5";
+const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num,
+ bool alternate_name) {
+ if (alternate_name) {
+ switch (reg_num) {
+ case dwarf_sp_mips64:
+ return "r29";
+ case dwarf_r30_mips64:
+ return "r30";
+ case dwarf_ra_mips64:
+ return "r31";
+ case dwarf_f0_mips64:
+ return "f0";
+ case dwarf_f1_mips64:
+ return "f1";
+ case dwarf_f2_mips64:
+ return "f2";
+ case dwarf_f3_mips64:
+ return "f3";
+ case dwarf_f4_mips64:
+ return "f4";
+ case dwarf_f5_mips64:
+ return "f5";
+ case dwarf_f6_mips64:
+ return "f6";
+ case dwarf_f7_mips64:
+ return "f7";
+ case dwarf_f8_mips64:
+ return "f8";
+ case dwarf_f9_mips64:
+ return "f9";
+ case dwarf_f10_mips64:
+ return "f10";
+ case dwarf_f11_mips64:
+ return "f11";
+ case dwarf_f12_mips64:
+ return "f12";
+ case dwarf_f13_mips64:
+ return "f13";
+ case dwarf_f14_mips64:
+ return "f14";
+ case dwarf_f15_mips64:
+ return "f15";
+ case dwarf_f16_mips64:
+ return "f16";
+ case dwarf_f17_mips64:
+ return "f17";
+ case dwarf_f18_mips64:
+ return "f18";
+ case dwarf_f19_mips64:
+ return "f19";
+ case dwarf_f20_mips64:
+ return "f20";
+ case dwarf_f21_mips64:
+ return "f21";
+ case dwarf_f22_mips64:
+ return "f22";
+ case dwarf_f23_mips64:
+ return "f23";
+ case dwarf_f24_mips64:
+ return "f24";
+ case dwarf_f25_mips64:
+ return "f25";
+ case dwarf_f26_mips64:
+ return "f26";
+ case dwarf_f27_mips64:
+ return "f27";
+ case dwarf_f28_mips64:
+ return "f28";
+ case dwarf_f29_mips64:
+ return "f29";
+ case dwarf_f30_mips64:
+ return "f30";
+ case dwarf_f31_mips64:
+ return "f31";
+ case dwarf_w0_mips64:
+ return "w0";
+ case dwarf_w1_mips64:
+ return "w1";
+ case dwarf_w2_mips64:
+ return "w2";
+ case dwarf_w3_mips64:
+ return "w3";
+ case dwarf_w4_mips64:
+ return "w4";
+ case dwarf_w5_mips64:
+ return "w5";
+ case dwarf_w6_mips64:
+ return "w6";
+ case dwarf_w7_mips64:
+ return "w7";
+ case dwarf_w8_mips64:
+ return "w8";
+ case dwarf_w9_mips64:
+ return "w9";
+ case dwarf_w10_mips64:
+ return "w10";
+ case dwarf_w11_mips64:
+ return "w11";
+ case dwarf_w12_mips64:
+ return "w12";
+ case dwarf_w13_mips64:
+ return "w13";
+ case dwarf_w14_mips64:
+ return "w14";
+ case dwarf_w15_mips64:
+ return "w15";
+ case dwarf_w16_mips64:
+ return "w16";
+ case dwarf_w17_mips64:
+ return "w17";
+ case dwarf_w18_mips64:
+ return "w18";
+ case dwarf_w19_mips64:
+ return "w19";
+ case dwarf_w20_mips64:
+ return "w20";
+ case dwarf_w21_mips64:
+ return "w21";
+ case dwarf_w22_mips64:
+ return "w22";
+ case dwarf_w23_mips64:
+ return "w23";
+ case dwarf_w24_mips64:
+ return "w24";
+ case dwarf_w25_mips64:
+ return "w25";
+ case dwarf_w26_mips64:
+ return "w26";
+ case dwarf_w27_mips64:
+ return "w27";
+ case dwarf_w28_mips64:
+ return "w28";
+ case dwarf_w29_mips64:
+ return "w29";
+ case dwarf_w30_mips64:
+ return "w30";
+ case dwarf_w31_mips64:
+ return "w31";
+ case dwarf_mir_mips64:
+ return "mir";
+ case dwarf_mcsr_mips64:
+ return "mcsr";
+ case dwarf_config5_mips64:
+ return "config5";
+ default:
+ break;
}
return nullptr;
+ }
+
+ switch (reg_num) {
+ case dwarf_zero_mips64:
+ return "r0";
+ case dwarf_r1_mips64:
+ return "r1";
+ case dwarf_r2_mips64:
+ return "r2";
+ case dwarf_r3_mips64:
+ return "r3";
+ case dwarf_r4_mips64:
+ return "r4";
+ case dwarf_r5_mips64:
+ return "r5";
+ case dwarf_r6_mips64:
+ return "r6";
+ case dwarf_r7_mips64:
+ return "r7";
+ case dwarf_r8_mips64:
+ return "r8";
+ case dwarf_r9_mips64:
+ return "r9";
+ case dwarf_r10_mips64:
+ return "r10";
+ case dwarf_r11_mips64:
+ return "r11";
+ case dwarf_r12_mips64:
+ return "r12";
+ case dwarf_r13_mips64:
+ return "r13";
+ case dwarf_r14_mips64:
+ return "r14";
+ case dwarf_r15_mips64:
+ return "r15";
+ case dwarf_r16_mips64:
+ return "r16";
+ case dwarf_r17_mips64:
+ return "r17";
+ case dwarf_r18_mips64:
+ return "r18";
+ case dwarf_r19_mips64:
+ return "r19";
+ case dwarf_r20_mips64:
+ return "r20";
+ case dwarf_r21_mips64:
+ return "r21";
+ case dwarf_r22_mips64:
+ return "r22";
+ case dwarf_r23_mips64:
+ return "r23";
+ case dwarf_r24_mips64:
+ return "r24";
+ case dwarf_r25_mips64:
+ return "r25";
+ case dwarf_r26_mips64:
+ return "r26";
+ case dwarf_r27_mips64:
+ return "r27";
+ case dwarf_gp_mips64:
+ return "gp";
+ case dwarf_sp_mips64:
+ return "sp";
+ case dwarf_r30_mips64:
+ return "fp";
+ case dwarf_ra_mips64:
+ return "ra";
+ case dwarf_sr_mips64:
+ return "sr";
+ case dwarf_lo_mips64:
+ return "lo";
+ case dwarf_hi_mips64:
+ return "hi";
+ case dwarf_bad_mips64:
+ return "bad";
+ case dwarf_cause_mips64:
+ return "cause";
+ case dwarf_pc_mips64:
+ return "pc";
+ case dwarf_f0_mips64:
+ return "f0";
+ case dwarf_f1_mips64:
+ return "f1";
+ case dwarf_f2_mips64:
+ return "f2";
+ case dwarf_f3_mips64:
+ return "f3";
+ case dwarf_f4_mips64:
+ return "f4";
+ case dwarf_f5_mips64:
+ return "f5";
+ case dwarf_f6_mips64:
+ return "f6";
+ case dwarf_f7_mips64:
+ return "f7";
+ case dwarf_f8_mips64:
+ return "f8";
+ case dwarf_f9_mips64:
+ return "f9";
+ case dwarf_f10_mips64:
+ return "f10";
+ case dwarf_f11_mips64:
+ return "f11";
+ case dwarf_f12_mips64:
+ return "f12";
+ case dwarf_f13_mips64:
+ return "f13";
+ case dwarf_f14_mips64:
+ return "f14";
+ case dwarf_f15_mips64:
+ return "f15";
+ case dwarf_f16_mips64:
+ return "f16";
+ case dwarf_f17_mips64:
+ return "f17";
+ case dwarf_f18_mips64:
+ return "f18";
+ case dwarf_f19_mips64:
+ return "f19";
+ case dwarf_f20_mips64:
+ return "f20";
+ case dwarf_f21_mips64:
+ return "f21";
+ case dwarf_f22_mips64:
+ return "f22";
+ case dwarf_f23_mips64:
+ return "f23";
+ case dwarf_f24_mips64:
+ return "f24";
+ case dwarf_f25_mips64:
+ return "f25";
+ case dwarf_f26_mips64:
+ return "f26";
+ case dwarf_f27_mips64:
+ return "f27";
+ case dwarf_f28_mips64:
+ return "f28";
+ case dwarf_f29_mips64:
+ return "f29";
+ case dwarf_f30_mips64:
+ return "f30";
+ case dwarf_f31_mips64:
+ return "f31";
+ case dwarf_fcsr_mips64:
+ return "fcsr";
+ case dwarf_fir_mips64:
+ return "fir";
+ case dwarf_w0_mips64:
+ return "w0";
+ case dwarf_w1_mips64:
+ return "w1";
+ case dwarf_w2_mips64:
+ return "w2";
+ case dwarf_w3_mips64:
+ return "w3";
+ case dwarf_w4_mips64:
+ return "w4";
+ case dwarf_w5_mips64:
+ return "w5";
+ case dwarf_w6_mips64:
+ return "w6";
+ case dwarf_w7_mips64:
+ return "w7";
+ case dwarf_w8_mips64:
+ return "w8";
+ case dwarf_w9_mips64:
+ return "w9";
+ case dwarf_w10_mips64:
+ return "w10";
+ case dwarf_w11_mips64:
+ return "w11";
+ case dwarf_w12_mips64:
+ return "w12";
+ case dwarf_w13_mips64:
+ return "w13";
+ case dwarf_w14_mips64:
+ return "w14";
+ case dwarf_w15_mips64:
+ return "w15";
+ case dwarf_w16_mips64:
+ return "w16";
+ case dwarf_w17_mips64:
+ return "w17";
+ case dwarf_w18_mips64:
+ return "w18";
+ case dwarf_w19_mips64:
+ return "w19";
+ case dwarf_w20_mips64:
+ return "w20";
+ case dwarf_w21_mips64:
+ return "w21";
+ case dwarf_w22_mips64:
+ return "w22";
+ case dwarf_w23_mips64:
+ return "w23";
+ case dwarf_w24_mips64:
+ return "w24";
+ case dwarf_w25_mips64:
+ return "w25";
+ case dwarf_w26_mips64:
+ return "w26";
+ case dwarf_w27_mips64:
+ return "w27";
+ case dwarf_w28_mips64:
+ return "w28";
+ case dwarf_w29_mips64:
+ return "w29";
+ case dwarf_w30_mips64:
+ return "w30";
+ case dwarf_w31_mips64:
+ return "w31";
+ case dwarf_mcsr_mips64:
+ return "mcsr";
+ case dwarf_mir_mips64:
+ return "mir";
+ case dwarf_config5_mips64:
+ return "config5";
+ }
+ return nullptr;
}
-bool
-EmulateInstructionMIPS64::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
-{
- if (reg_kind == eRegisterKindGeneric)
- {
- switch (reg_num)
- {
- case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc_mips64; break;
- case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp_mips64; break;
- case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r30_mips64; break;
- case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_ra_mips64; break;
- case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sr_mips64; break;
- default:
- return false;
- }
+bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &reg_info) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_num) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_pc_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sp_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_r30_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_ra_mips64;
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ reg_kind = eRegisterKindDWARF;
+ reg_num = dwarf_sr_mips64;
+ break;
+ default:
+ return false;
}
-
- if (reg_kind == eRegisterKindDWARF)
- {
- ::memset (&reg_info, 0, sizeof(RegisterInfo));
- ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
-
- if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 || reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 || reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64)
- {
- reg_info.byte_size = 4;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_zero_mips64 && (int)reg_num <= dwarf_f31_mips64)
- {
- reg_info.byte_size = 8;
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if ((int)reg_num >= dwarf_w0_mips64 && (int)reg_num <= dwarf_w31_mips64)
- {
- reg_info.byte_size = 16;
- reg_info.format = eFormatVectorOfUInt8;
- reg_info.encoding = eEncodingVector;
- }
- else
- {
- return false;
- }
-
- reg_info.name = GetRegisterName (reg_num, false);
- reg_info.alt_name = GetRegisterName (reg_num, true);
- reg_info.kinds[eRegisterKindDWARF] = reg_num;
-
- switch (reg_num)
- {
- case dwarf_r30_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
- case dwarf_ra_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
- case dwarf_sp_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
- case dwarf_pc_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
- case dwarf_sr_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
- default: break;
- }
- return true;
+ }
+
+ if (reg_kind == eRegisterKindDWARF) {
+ ::memset(&reg_info, 0, sizeof(RegisterInfo));
+ ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+
+ if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 ||
+ reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 ||
+ reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_zero_mips64 &&
+ (int)reg_num <= dwarf_f31_mips64) {
+ reg_info.byte_size = 8;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if ((int)reg_num >= dwarf_w0_mips64 &&
+ (int)reg_num <= dwarf_w31_mips64) {
+ reg_info.byte_size = 16;
+ reg_info.format = eFormatVectorOfUInt8;
+ reg_info.encoding = eEncodingVector;
+ } else {
+ return false;
}
- return false;
-}
-EmulateInstructionMIPS64::MipsOpcode*
-EmulateInstructionMIPS64::GetOpcodeForInstruction (const char *op_name)
-{
- static EmulateInstructionMIPS64::MipsOpcode
- g_opcodes[] =
- {
- //----------------------------------------------------------------------
- // Prologue/Epilogue instructions
- //----------------------------------------------------------------------
- { "DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, "DADDIU rt, rs, immediate" },
- { "ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu, "ADDIU rt, rs, immediate" },
- { "SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)" },
- { "LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)" },
- { "DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "DSUBU rd, rs, rt" },
- { "SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "SUBU rd, rs, rt" },
- { "DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "DADDU rd, rs, rt" },
- { "ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU, "ADDU rd, rs, rt" },
- { "LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate" },
-
-
-
-
- //----------------------------------------------------------------------
- // Load/Store instructions
- //----------------------------------------------------------------------
- /* Following list of emulated instructions are required by implementation of hardware watchpoint
- for MIPS in lldb. As we just need the address accessed by instructions, we have generalised
- all these instructions in 2 functions depending on their addressing modes */
-
- { "LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LB rt, offset(base)" },
- { "LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LBE rt, offset(base)" },
- { "LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LBU rt, offset(base)" },
- { "LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LBUE rt, offset(base)" },
- { "LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDC1 ft, offset(base)" },
- { "LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDL rt, offset(base)" },
- { "LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDR rt, offset(base)" },
- { "LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LLD rt, offset(base)" },
- { "LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LDC2 rt, offset(base)" },
- { "LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "LDXC1 fd, index (base)" },
- { "LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LH rt, offset(base)" },
- { "LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LHE rt, offset(base)" },
- { "LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LHU rt, offset(base)" },
- { "LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LHUE rt, offset(base)" },
- { "LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LL rt, offset(base)" },
- { "LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LLE rt, offset(base)" },
- { "LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "LUXC1 fd, index (base)" },
- { "LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LW rt, offset(rs)" },
- { "LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWC1 ft, offset(base)" },
- { "LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWC2 rt, offset(base)" },
- { "LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWE rt, offset(base)" },
- { "LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWL rt, offset(base)" },
- { "LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWLE rt, offset(base)" },
- { "LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWR rt, offset(base)" },
- { "LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "LWRE rt, offset(base)" },
- { "LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "LWXC1 fd, index (base)" },
-
- { "SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SB rt, offset(base)" },
- { "SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SBE rt, offset(base)" },
- { "SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SC rt, offset(base)" },
- { "SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SCE rt, offset(base)" },
- { "SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SCD rt, offset(base)" },
- { "SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDL rt, offset(base)" },
- { "SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDR rt, offset(base)" },
- { "SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDC1 ft, offset(base)" },
- { "SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SDC2 rt, offset(base)" },
- { "SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "SDXC1 fs, index (base)" },
- { "SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SH rt, offset(base)" },
- { "SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SHE rt, offset(base)" },
- { "SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "SUXC1 fs, index (base)" },
- { "SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SW rt, offset(rs)" },
- { "SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWC1 ft, offset(base)" },
- { "SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWC2 rt, offset(base)" },
- { "SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWE rt, offset(base)" },
- { "SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWL rt, offset(base)" },
- { "SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWLE rt, offset(base)" },
- { "SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWR rt, offset(base)" },
- { "SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm, "SWRE rt, offset(base)" },
- { "SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg, "SWXC1 fs, index (base)" },
-
- //----------------------------------------------------------------------
- // Branch instructions
- //----------------------------------------------------------------------
- { "BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset" },
- { "BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset" },
- { "BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQL rs,rt,offset" },
- { "BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNEL rs,rt,offset" },
- { "BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BGEZALL rt,offset" },
- { "BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset" },
- { "BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BGEZAL rs,offset" },
- { "BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset" },
- { "BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset" },
- { "BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset" },
- { "BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BLEZALC rs,offset" },
- { "BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BGEZALC rs,offset" },
- { "BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BLTZALC rs,offset" },
- { "BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BGTZALC rs,offset" },
- { "BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BEQZALC rs,offset" },
- { "BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,"BNEZALC rs,offset" },
- { "BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BEQC rs,rt,offset" },
- { "BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BNEC rs,rt,offset" },
- { "BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BLTC rs,rt,offset" },
- { "BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BGEC rs,rt,offset" },
- { "BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BLTUC rs,rt,offset" },
- { "BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BGEUC rs,rt,offset" },
- { "BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BLTZC rt,offset" },
- { "BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BLEZC rt,offset" },
- { "BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BGEZC rt,offset" },
- { "BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BGTZC rt,offset" },
- { "BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BEQZC rt,offset" },
- { "BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C, "BNEZC rt,offset" },
- { "BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset" },
- { "BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset" },
- { "BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset" },
- { "BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset" },
- { "BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset" },
- { "BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset" },
- { "BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BLTZAL rt,offset" },
- { "BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link, "BLTZALL rt,offset" },
- { "BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset" },
- { "BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BOVC rs,rt,offset" },
- { "BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C, "BNVC rs,rt,offset" },
- { "J", &EmulateInstructionMIPS64::Emulate_J, "J target" },
- { "JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target" },
- { "JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target" },
- { "JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target" },
- { "JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target" },
- { "JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset" },
- { "JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset" },
- { "JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target" },
- { "JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target" },
- { "BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset" },
- { "BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset" },
- { "BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1FL cc, offset" },
- { "BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1TL cc, offset" },
- { "BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ, "BC1EQZ ft, offset" },
- { "BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ, "BC1NEZ ft, offset" },
- { "BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY2F cc, offset" },
- { "BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY2T cc, offset" },
- { "BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY4F cc, offset" },
- { "BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch, "BC1ANY4T cc, offset" },
- { "BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16" },
- { "BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16" },
- { "BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16" },
- { "BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16" },
- { "BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16" },
- { "BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16" },
- { "BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16" },
- { "BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16" },
- { "BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16" },
- { "BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16" },
- };
-
- static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
-
- for (size_t i = 0; i < k_num_mips_opcodes; ++i)
- {
- if (! strcasecmp (g_opcodes[i].op_name, op_name))
- return &g_opcodes[i];
+ reg_info.name = GetRegisterName(reg_num, false);
+ reg_info.alt_name = GetRegisterName(reg_num, true);
+ reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
+ switch (reg_num) {
+ case dwarf_r30_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ break;
+ case dwarf_ra_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ break;
+ case dwarf_sp_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ break;
+ case dwarf_pc_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ break;
+ case dwarf_sr_mips64:
+ reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ break;
+ default:
+ break;
}
-
- return NULL;
+ return true;
+ }
+ return false;
}
-bool
-EmulateInstructionMIPS64::ReadInstruction ()
-{
- bool success = false;
- m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
- if (success)
- {
- Context read_inst_context;
- read_inst_context.type = eContextReadOpcode;
- read_inst_context.SetNoArgs ();
- m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
- }
- if (!success)
- m_addr = LLDB_INVALID_ADDRESS;
- return success;
+EmulateInstructionMIPS64::MipsOpcode *
+EmulateInstructionMIPS64::GetOpcodeForInstruction(const char *op_name) {
+ static EmulateInstructionMIPS64::MipsOpcode g_opcodes[] = {
+ //----------------------------------------------------------------------
+ // Prologue/Epilogue instructions
+ //----------------------------------------------------------------------
+ {"DADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
+ "DADDIU rt, rs, immediate"},
+ {"ADDiu", &EmulateInstructionMIPS64::Emulate_DADDiu,
+ "ADDIU rt, rs, immediate"},
+ {"SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt, offset(rs)"},
+ {"LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt, offset(base)"},
+ {"DSUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "DSUBU rd, rs, rt"},
+ {"SUBU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "SUBU rd, rs, rt"},
+ {"DADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "DADDU rd, rs, rt"},
+ {"ADDU", &EmulateInstructionMIPS64::Emulate_DSUBU_DADDU,
+ "ADDU rd, rs, rt"},
+ {"LUI", &EmulateInstructionMIPS64::Emulate_LUI, "LUI rt, immediate"},
+
+ //----------------------------------------------------------------------
+ // Load/Store instructions
+ //----------------------------------------------------------------------
+ /* Following list of emulated instructions are required by implementation
+ of hardware watchpoint
+ for MIPS in lldb. As we just need the address accessed by instructions,
+ we have generalised
+ all these instructions in 2 functions depending on their addressing
+ modes */
+
+ {"LB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LB rt, offset(base)"},
+ {"LBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LBE rt, offset(base)"},
+ {"LBU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LBU rt, offset(base)"},
+ {"LBUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LBUE rt, offset(base)"},
+ {"LDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDC1 ft, offset(base)"},
+ {"LDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDL rt, offset(base)"},
+ {"LDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDR rt, offset(base)"},
+ {"LLD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LLD rt, offset(base)"},
+ {"LDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LDC2 rt, offset(base)"},
+ {"LDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "LDXC1 fd, index (base)"},
+ {"LH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LH rt, offset(base)"},
+ {"LHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LHE rt, offset(base)"},
+ {"LHU", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LHU rt, offset(base)"},
+ {"LHUE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LHUE rt, offset(base)"},
+ {"LL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LL rt, offset(base)"},
+ {"LLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LLE rt, offset(base)"},
+ {"LUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "LUXC1 fd, index (base)"},
+ {"LW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LW rt, offset(rs)"},
+ {"LWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWC1 ft, offset(base)"},
+ {"LWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWC2 rt, offset(base)"},
+ {"LWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWE rt, offset(base)"},
+ {"LWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWL rt, offset(base)"},
+ {"LWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWLE rt, offset(base)"},
+ {"LWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWR rt, offset(base)"},
+ {"LWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "LWRE rt, offset(base)"},
+ {"LWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "LWXC1 fd, index (base)"},
+
+ {"SB", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SB rt, offset(base)"},
+ {"SBE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SBE rt, offset(base)"},
+ {"SC", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SC rt, offset(base)"},
+ {"SCE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SCE rt, offset(base)"},
+ {"SCD", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SCD rt, offset(base)"},
+ {"SDL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDL rt, offset(base)"},
+ {"SDR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDR rt, offset(base)"},
+ {"SDC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDC1 ft, offset(base)"},
+ {"SDC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SDC2 rt, offset(base)"},
+ {"SDXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "SDXC1 fs, index (base)"},
+ {"SH", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SH rt, offset(base)"},
+ {"SHE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SHE rt, offset(base)"},
+ {"SUXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "SUXC1 fs, index (base)"},
+ {"SW", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SW rt, offset(rs)"},
+ {"SWC1", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWC1 ft, offset(base)"},
+ {"SWC2", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWC2 rt, offset(base)"},
+ {"SWE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWE rt, offset(base)"},
+ {"SWL", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWL rt, offset(base)"},
+ {"SWLE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWLE rt, offset(base)"},
+ {"SWR", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWR rt, offset(base)"},
+ {"SWRE", &EmulateInstructionMIPS64::Emulate_LDST_Imm,
+ "SWRE rt, offset(base)"},
+ {"SWXC1", &EmulateInstructionMIPS64::Emulate_LDST_Reg,
+ "SWXC1 fs, index (base)"},
+
+ //----------------------------------------------------------------------
+ // Branch instructions
+ //----------------------------------------------------------------------
+ {"BEQ", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BEQ rs,rt,offset"},
+ {"BNE", &EmulateInstructionMIPS64::Emulate_BXX_3ops, "BNE rs,rt,offset"},
+ {"BEQL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
+ "BEQL rs,rt,offset"},
+ {"BNEL", &EmulateInstructionMIPS64::Emulate_BXX_3ops,
+ "BNEL rs,rt,offset"},
+ {"BGEZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BGEZALL rt,offset"},
+ {"BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset"},
+ {"BGEZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BGEZAL rs,offset"},
+ {"BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset"},
+ {"BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset"},
+ {"BGEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZ rs,offset"},
+ {"BLEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BLEZALC rs,offset"},
+ {"BGEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BGEZALC rs,offset"},
+ {"BLTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BLTZALC rs,offset"},
+ {"BGTZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BGTZALC rs,offset"},
+ {"BEQZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BEQZALC rs,offset"},
+ {"BNEZALC", &EmulateInstructionMIPS64::Emulate_Bcond_Link_C,
+ "BNEZALC rs,offset"},
+ {"BEQC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BEQC rs,rt,offset"},
+ {"BNEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BNEC rs,rt,offset"},
+ {"BLTC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BLTC rs,rt,offset"},
+ {"BGEC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BGEC rs,rt,offset"},
+ {"BLTUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BLTUC rs,rt,offset"},
+ {"BGEUC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BGEUC rs,rt,offset"},
+ {"BLTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BLTZC rt,offset"},
+ {"BLEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BLEZC rt,offset"},
+ {"BGEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BGEZC rt,offset"},
+ {"BGTZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BGTZC rt,offset"},
+ {"BEQZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BEQZC rt,offset"},
+ {"BNEZC", &EmulateInstructionMIPS64::Emulate_BXX_2ops_C,
+ "BNEZC rt,offset"},
+ {"BGEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGEZL rt,offset"},
+ {"BGTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZ rt,offset"},
+ {"BGTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BGTZL rt,offset"},
+ {"BLEZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZ rt,offset"},
+ {"BLEZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLEZL rt,offset"},
+ {"BLTZ", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZ rt,offset"},
+ {"BLTZAL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BLTZAL rt,offset"},
+ {"BLTZALL", &EmulateInstructionMIPS64::Emulate_Bcond_Link,
+ "BLTZALL rt,offset"},
+ {"BLTZL", &EmulateInstructionMIPS64::Emulate_BXX_2ops, "BLTZL rt,offset"},
+ {"BOVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BOVC rs,rt,offset"},
+ {"BNVC", &EmulateInstructionMIPS64::Emulate_BXX_3ops_C,
+ "BNVC rs,rt,offset"},
+ {"J", &EmulateInstructionMIPS64::Emulate_J, "J target"},
+ {"JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target"},
+ {"JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target"},
+ {"JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
+ {"JALR64", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target"},
+ {"JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target"},
+ {"JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset"},
+ {"JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset"},
+ {"JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target"},
+ {"JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target"},
+ {"BC1F", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1F cc, offset"},
+ {"BC1T", &EmulateInstructionMIPS64::Emulate_FP_branch, "BC1T cc, offset"},
+ {"BC1FL", &EmulateInstructionMIPS64::Emulate_FP_branch,
+ "BC1FL cc, offset"},
+ {"BC1TL", &EmulateInstructionMIPS64::Emulate_FP_branch,
+ "BC1TL cc, offset"},
+ {"BC1EQZ", &EmulateInstructionMIPS64::Emulate_BC1EQZ,
+ "BC1EQZ ft, offset"},
+ {"BC1NEZ", &EmulateInstructionMIPS64::Emulate_BC1NEZ,
+ "BC1NEZ ft, offset"},
+ {"BC1ANY2F", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY2F cc, offset"},
+ {"BC1ANY2T", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY2T cc, offset"},
+ {"BC1ANY4F", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY4F cc, offset"},
+ {"BC1ANY4T", &EmulateInstructionMIPS64::Emulate_3D_branch,
+ "BC1ANY4T cc, offset"},
+ {"BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16"},
+ {"BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16"},
+ {"BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16"},
+ {"BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16"},
+ {"BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16"},
+ {"BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16"},
+ {"BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16"},
+ {"BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16"},
+ {"BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16"},
+ {"BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16"},
+ };
+
+ static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
+
+ for (size_t i = 0; i < k_num_mips_opcodes; ++i) {
+ if (!strcasecmp(g_opcodes[i].op_name, op_name))
+ return &g_opcodes[i];
+ }
+
+ return NULL;
}
-bool
-EmulateInstructionMIPS64::EvaluateInstruction (uint32_t evaluate_options)
-{
- bool success = false;
- llvm::MCInst mc_insn;
- uint64_t insn_size;
- DataExtractor data;
-
- /* Keep the complexity of the decode logic with the llvm::MCDisassembler class. */
- if (m_opcode.GetData (data))
- {
- llvm::MCDisassembler::DecodeStatus decode_status;
- llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize());
- decode_status = m_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
- if (decode_status != llvm::MCDisassembler::Success)
- return false;
- }
+bool EmulateInstructionMIPS64::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, &success);
+ if (success) {
+ Context read_inst_context;
+ read_inst_context.type = eContextReadOpcode;
+ read_inst_context.SetNoArgs();
+ m_opcode.SetOpcode32(
+ ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
+ GetByteOrder());
+ }
+ if (!success)
+ m_addr = LLDB_INVALID_ADDRESS;
+ return success;
+}
- /*
- * mc_insn.getOpcode() returns decoded opcode. However to make use
- * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
- */
- const char *op_name = m_insn_info->getName (mc_insn.getOpcode ());
+bool EmulateInstructionMIPS64::EvaluateInstruction(uint32_t evaluate_options) {
+ bool success = false;
+ llvm::MCInst mc_insn;
+ uint64_t insn_size;
+ DataExtractor data;
+
+ /* Keep the complexity of the decode logic with the llvm::MCDisassembler
+ * class. */
+ if (m_opcode.GetData(data)) {
+ llvm::MCDisassembler::DecodeStatus decode_status;
+ llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize());
+ decode_status = m_disasm->getInstruction(
+ mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls());
+ if (decode_status != llvm::MCDisassembler::Success)
+ return false;
+ }
+
+ /*
+ * mc_insn.getOpcode() returns decoded opcode. However to make use
+ * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc".
+ */
+ const char *op_name = m_insn_info->getName(mc_insn.getOpcode()).data();
+
+ if (op_name == NULL)
+ return false;
- if (op_name == NULL)
- return false;
+ /*
+ * Decoding has been done already. Just get the call-back function
+ * and emulate the instruction.
+ */
+ MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name);
- /*
- * Decoding has been done already. Just get the call-back function
- * and emulate the instruction.
- */
- MipsOpcode *opcode_data = GetOpcodeForInstruction (op_name);
+ if (opcode_data == NULL)
+ return false;
- if (opcode_data == NULL)
- return false;
+ uint64_t old_pc = 0, new_pc = 0;
+ const bool auto_advance_pc =
+ evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
- uint64_t old_pc = 0, new_pc = 0;
- const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ if (auto_advance_pc) {
+ old_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+ }
- if (auto_advance_pc)
- {
- old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
- }
+ /* emulate instruction */
+ success = (this->*opcode_data->callback)(mc_insn);
+ if (!success)
+ return false;
- /* emulate instruction */
- success = (this->*opcode_data->callback) (mc_insn);
+ if (auto_advance_pc) {
+ new_pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
if (!success)
- return false;
+ return false;
- if (auto_advance_pc)
- {
- new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
-
- /* If we haven't changed the PC, change it here */
- if (old_pc == new_pc)
- {
- new_pc += 4;
- Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, new_pc))
- return false;
- }
+ /* If we haven't changed the PC, change it here */
+ if (old_pc == new_pc) {
+ new_pc += 4;
+ Context context;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ new_pc))
+ return false;
}
+ }
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const bool can_replace = false;
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const bool can_replace = false;
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips64, 0);
- // Our previous PC is in the RA
- row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64, can_replace);
+ // Our previous PC is in the RA
+ row->SetRegisterLocationToRegister(dwarf_pc_mips64, dwarf_ra_mips64,
+ can_replace);
- unwind_plan.AppendRow (row);
+ unwind_plan.AppendRow(row);
- // All other registers are the same.
- unwind_plan.SetSourceName ("EmulateInstructionMIPS64");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- unwind_plan.SetReturnAddressRegister (dwarf_ra_mips64);
+ // All other registers are the same.
+ unwind_plan.SetSourceName("EmulateInstructionMIPS64");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::nonvolatile_reg_p (uint64_t regnum)
-{
- switch (regnum)
- {
- case dwarf_r16_mips64:
- case dwarf_r17_mips64:
- case dwarf_r18_mips64:
- case dwarf_r19_mips64:
- case dwarf_r20_mips64:
- case dwarf_r21_mips64:
- case dwarf_r22_mips64:
- case dwarf_r23_mips64:
- case dwarf_gp_mips64:
- case dwarf_sp_mips64:
- case dwarf_r30_mips64:
- case dwarf_ra_mips64:
- return true;
- default:
- return false;
- }
+bool EmulateInstructionMIPS64::nonvolatile_reg_p(uint64_t regnum) {
+ switch (regnum) {
+ case dwarf_r16_mips64:
+ case dwarf_r17_mips64:
+ case dwarf_r18_mips64:
+ case dwarf_r19_mips64:
+ case dwarf_r20_mips64:
+ case dwarf_r21_mips64:
+ case dwarf_r22_mips64:
+ case dwarf_r23_mips64:
+ case dwarf_gp_mips64:
+ case dwarf_sp_mips64:
+ case dwarf_r30_mips64:
+ case dwarf_ra_mips64:
+ return true;
+ default:
return false;
+ }
+ return false;
}
-bool
-EmulateInstructionMIPS64::Emulate_DADDiu (llvm::MCInst& insn)
-{
- // DADDIU rt, rs, immediate
- // GPR[rt] <- GPR[rs] + sign_extend(immediate)
-
- uint8_t dst, src;
- bool success = false;
- const uint32_t imm16 = insn.getOperand(2).getImm();
- int64_t imm = SignedBits(imm16, 15, 0);
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- // If immediate is greater than 2^16 - 1 then clang generate
- // LUI, (D)ADDIU,(D)SUBU instructions in prolog.
- // Example
- // lui $1, 0x2
- // daddiu $1, $1, -0x5920
- // dsubu $sp, $sp, $1
- // In this case, (D)ADDIU dst and src will be same and not equal to sp
- if (dst == src)
- {
- Context context;
-
- /* read <src> register */
- const int64_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)
- {
- uint64_t result = src_opd_val + imm;
- RegisterInfo reg_info_sp;
-
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, imm);
-
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
-
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips64, result);
- return true;
- }
-
- imm += src_opd_val;
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + dst, imm))
- return false;
+bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
+ // DADDIU rt, rs, immediate
+ // GPR[rt] <- GPR[rs] + sign_extend(immediate)
+
+ uint8_t dst, src;
+ bool success = false;
+ const uint32_t imm16 = insn.getOperand(2).getImm();
+ int64_t imm = SignedBits(imm16, 15, 0);
+
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ // If immediate is greater than 2^16 - 1 then clang generate
+ // LUI, (D)ADDIU,(D)SUBU instructions in prolog.
+ // Example
+ // lui $1, 0x2
+ // daddiu $1, $1, -0x5920
+ // dsubu $sp, $sp, $1
+ // In this case, (D)ADDIU dst and src will be same and not equal to sp
+ if (dst == src) {
+ Context context;
+
+ /* read <src> register */
+ const int64_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) {
+ uint64_t result = src_opd_val + imm;
+ RegisterInfo reg_info_sp;
+
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, imm);
+
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
+
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64,
+ result);
+ return true;
}
- return true;
-}
+ imm += src_opd_val;
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
-bool
-EmulateInstructionMIPS64::Emulate_SD (llvm::MCInst& insn)
-{
- uint64_t address;
- RegisterInfo reg_info_base;
- RegisterInfo reg_info_src;
- bool success = false;
- uint32_t imm16 = insn.getOperand(2).getImm();
- uint64_t imm = SignedBits(imm16, 15, 0);
- uint32_t src, base;
- Context bad_vaddr_context;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips64 + dst, imm))
+ return false;
+ }
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+ return true;
+}
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + base, reg_info_base)
- || !GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + src, reg_info_src))
- return false;
+bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) {
+ uint64_t address;
+ RegisterInfo reg_info_base;
+ RegisterInfo reg_info_src;
+ bool success = false;
+ uint32_t imm16 = insn.getOperand(2).getImm();
+ uint64_t imm = SignedBits(imm16, 15, 0);
+ uint32_t src, base;
+ Context bad_vaddr_context;
+
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ reg_info_base) ||
+ !GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
+ reg_info_src))
+ return false;
- /* read SP */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + base, 0, &success);
- if (!success)
- return false;
+ /* read SP */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* We look for sp based non-volatile register stores */
- if (nonvolatile_reg_p (src))
- {
- Context context;
- RegisterValue data_src;
- context.type = eContextPushRegisterOnStack;
- context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0);
+ /* We look for sp based non-volatile register stores */
+ if (nonvolatile_reg_p(src)) {
+ Context context;
+ RegisterValue data_src;
+ context.type = eContextPushRegisterOnStack;
+ context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0);
- uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
- Error error;
+ uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
+ Error error;
- if (!ReadRegister (&reg_info_base, data_src))
- return false;
+ if (!ReadRegister(&reg_info_base, data_src))
+ return false;
- if (data_src.GetAsMemoryData (&reg_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0)
- return false;
+ if (data_src.GetAsMemoryData(&reg_info_src, buffer, reg_info_src.byte_size,
+ eByteOrderLittle, error) == 0)
+ return false;
- if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
- return false;
- }
+ if (!WriteMemory(context, address, buffer, reg_info_src.byte_size))
+ return false;
+ }
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
+ address);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_LD (llvm::MCInst& insn)
-{
- bool success =false;
- uint32_t src, base;
- int64_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t src, base;
+ int64_t imm, address;
+ Context bad_vaddr_context;
- src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- imm = insn.getOperand(2).getImm();
-
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + base, reg_info_base))
- return false;
+ src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ imm = insn.getOperand(2).getImm();
- /* read base register */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + base, 0, &success);
- if (!success)
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ reg_info_base))
+ return false;
- /* destination address */
- address = address + imm;
+ /* read base register */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + base,
+ 0, &success);
+ if (!success)
+ return false;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64, address);
+ /* destination address */
+ address = address + imm;
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips64,
+ address);
- if (nonvolatile_reg_p (src))
- {
- RegisterValue data_src;
- RegisterInfo reg_info_src;
+ if (nonvolatile_reg_p(src)) {
+ RegisterValue data_src;
+ RegisterInfo reg_info_src;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips64 + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips64 + src,
+ reg_info_src))
+ return false;
- Context context;
- context.type = eContextRegisterLoad;
+ Context context;
+ context.type = eContextRegisterLoad;
- if (!WriteRegister (context, &reg_info_src, data_src))
- return false;
+ if (!WriteRegister(context, &reg_info_src, data_src))
+ return false;
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-bool
-EmulateInstructionMIPS64::Emulate_LUI (llvm::MCInst& insn)
-{
- // LUI rt, immediate
- // GPR[rt] <- sign_extend(immediate << 16)
+bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) {
+ // LUI rt, immediate
+ // GPR[rt] <- sign_extend(immediate << 16)
- const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
- int64_t imm = SignedBits(imm32, 31, 0);
- uint8_t rt;
- Context context;
-
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- context.SetImmediateSigned (imm);
- context.type = eContextImmediate;
+ const uint32_t imm32 = insn.getOperand(1).getImm() << 16;
+ int64_t imm = SignedBits(imm32, 31, 0);
+ uint8_t rt;
+ Context context;
- if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + rt, imm))
- return true;
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ context.SetImmediateSigned(imm);
+ context.type = eContextImmediate;
- return false;
+ if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips64 + rt,
+ imm))
+ return true;
+
+ return false;
}
-bool
-EmulateInstructionMIPS64::Emulate_DSUBU_DADDU (llvm::MCInst& insn)
-{
- // DSUBU sp, <src>, <rt>
- // DADDU sp, <src>, <rt>
- // DADDU dst, sp, <rt>
-
- bool success = false;
- uint64_t result;
- uint8_t src, dst, rt;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- /* Check if sp is destination register */
- if (dst == dwarf_sp_mips64)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
-
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
- if (!success)
- return false;
-
- /* read <rt > register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
-
- if (!strcasecmp (op_name, "DSUBU") || !strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
-
- Context context;
- RegisterInfo reg_info_sp;
- if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
- context.SetRegisterPlusOffset (reg_info_sp, rt_opd_val);
-
- /* We are allocating bytes on stack */
- context.type = eContextAdjustStackPointer;
-
- WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips64, result);
-
- return true;
- }
- else if (src == dwarf_sp_mips64)
- {
- rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg());
+bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) {
+ // DSUBU sp, <src>, <rt>
+ // DADDU sp, <src>, <rt>
+ // DADDU dst, sp, <rt>
- /* read <src> register */
- uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
- if (!success)
- return false;
+ bool success = false;
+ uint64_t result;
+ uint8_t src, dst, rt;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- /* read <rt> register */
- uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
- Context context;
+ /* Check if sp is destination register */
+ if (dst == dwarf_sp_mips64) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
- if (!strcasecmp (op_name, "DSUBU") || !strcasecmp (op_name, "SUBU"))
- result = src_opd_val - rt_opd_val;
- else
- result = src_opd_val + rt_opd_val;
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
+ if (!success)
+ return false;
- context.SetImmediateSigned (result);
- context.type = eContextImmediate;
+ /* read <rt > register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + dst, result))
- return false;
- }
+ if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
+
+ Context context;
+ RegisterInfo reg_info_sp;
+ if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips64, reg_info_sp))
+ context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val);
+
+ /* We are allocating bytes on stack */
+ context.type = eContextAdjustStackPointer;
+
+ WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips64, result);
return true;
+ } else if (src == dwarf_sp_mips64) {
+ rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg());
+
+ /* read <src> register */
+ uint64_t src_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
+ if (!success)
+ return false;
+
+ /* read <rt> register */
+ uint64_t rt_opd_val = ReadRegisterUnsigned(
+ eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
+
+ Context context;
+
+ if (!strcasecmp(op_name, "DSUBU") || !strcasecmp(op_name, "SUBU"))
+ result = src_opd_val - rt_opd_val;
+ else
+ result = src_opd_val + rt_opd_val;
+
+ context.SetImmediateSigned(result);
+ context.type = eContextImmediate;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips64 + dst, result))
+ return false;
+ }
+
+ return true;
}
/*
@@ -1038,706 +1314,651 @@ EmulateInstructionMIPS64::Emulate_DSUBU_DADDU (llvm::MCInst& insn)
BEQ, BNE : Branch on condition
BEQL, BNEL : Branch likely
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_3ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int64_t offset, pc, rs_val, rt_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, rs_val, rt_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQ") ||
- !strcasecmp (op_name, "BEQL"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BNE") ||
- !strcasecmp (op_name, "BNEL"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BEQ") || !strcasecmp(op_name, "BEQL")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BNE") || !strcasecmp(op_name, "BNEL")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS Non-Compact conditional branch and link instructions.
BLTZAL, BGEZAL :
BLTZALL, BGEZALL : Branch likely
*/
-bool
-EmulateInstructionMIPS64::Emulate_Bcond_Link (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, target = 0;
- int64_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_Bcond_Link(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target = 0;
+ int64_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZAL") ||
- !strcasecmp (op_name, "BLTZALL"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZAL") ||
- !strcasecmp (op_name, "BGEZALL"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ if (!strcasecmp(op_name, "BLTZAL") || !strcasecmp(op_name, "BLTZALL")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZAL") ||
+ !strcasecmp(op_name, "BGEZALL")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BAL (llvm::MCInst& insn)
-{
- bool success = false;
- int64_t offset, pc, target;
-
- /*
- * BAL offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 8
- * PC = PC + offset
- */
- offset = insn.getOperand(0).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BAL(llvm::MCInst &insn) {
+ bool success = false;
+ int64_t offset, pc, target;
- target = pc + offset;
+ /*
+ * BAL offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 8
+ * PC = PC + offset
+ */
+ offset = insn.getOperand(0).getImm();
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ target = pc + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 8))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 8))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BALC (llvm::MCInst& insn)
-{
- bool success = false;
- int64_t offset, pc, target;
-
- /*
- * BALC offset
- * offset = sign_ext (offset << 2)
- * RA = PC + 4
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BALC(llvm::MCInst &insn) {
+ bool success = false;
+ int64_t offset, pc, target;
- target = pc + offset;
+ /*
+ * BALC offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 4
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- Context context;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ target = pc + offset;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 4))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 4))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS conditional branch and link instructions.
BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
*/
-bool
-EmulateInstructionMIPS64::Emulate_Bcond_Link_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, rs_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_Bcond_Link_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, rs_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if (!strcasecmp (op_name, "BLEZALC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZALC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTZALC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZALC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZALC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZALC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- Context context;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!strcasecmp(op_name, "BLEZALC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZALC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTZALC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZALC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZALC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZALC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 4))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 4))
+ return false;
+
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_2ops (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, rs_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, rs_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- if (!strcasecmp (op_name, "BLTZL") ||
- !strcasecmp (op_name, "BLTZ"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGEZL") ||
- !strcasecmp (op_name, "BGEZ"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BGTZL") ||
- !strcasecmp (op_name, "BGTZ"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BLEZL") ||
- !strcasecmp (op_name, "BLEZ"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (offset);
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BGTZL") || !strcasecmp(op_name, "BGTZ")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BLEZL") || !strcasecmp(op_name, "BLEZ")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- return true;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(offset);
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BC (llvm::MCInst& insn)
-{
- bool success = false;
- int64_t offset, pc, target;
+bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
+ bool success = false;
+ int64_t offset, pc, target;
- /*
- * BC offset
- * offset = sign_ext (offset << 2)
- * PC = PC + 4 + offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * BC offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- target = pc + offset;
+ target = pc + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-static int
-IsAdd64bitOverflow (int64_t a, int64_t b)
-{
- int64_t r = (uint64_t) a + (uint64_t) b;
+static int IsAdd64bitOverflow(int64_t a, int64_t b) {
+ int64_t r = (uint64_t)a + (uint64_t)b;
return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
}
/*
Emulate below MIPS branch instructions.
- BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot
+ BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch
+ instructions with no delay slot
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_3ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- int64_t offset, pc, rs_val, rt_val, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, rs_val, rt_val, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rt = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+ offset = insn.getOperand(2).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BEQC"))
- {
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEC"))
- {
- if (rs_val != rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEC"))
- {
- if (rs_val >= rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLTUC"))
- {
- if (rs_val < rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEUC"))
- {
- if ((uint32_t)rs_val >= (uint32_t)rt_val)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BOVC"))
- {
- if (IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNVC"))
- {
- if (!IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BEQC")) {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEC")) {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEC")) {
+ if (rs_val >= rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLTUC")) {
+ if (rs_val < rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEUC")) {
+ if ((uint32_t)rs_val >= (uint32_t)rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BOVC")) {
+ if (IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNVC")) {
+ if (!IsAdd64bitOverflow(rs_val, rt_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-/*
+/*
Emulate below MIPS branch instructions.
BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
*/
-bool
-EmulateInstructionMIPS64::Emulate_BXX_2ops_C (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- int64_t offset, pc, target = 0;
- int64_t rs_val;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target = 0;
+ int64_t rs_val;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BLTZC"))
- {
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BLEZC"))
- {
- if (rs_val <= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGEZC"))
- {
- if (rs_val >= 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BGTZC"))
- {
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BEQZC"))
- {
- if (rs_val == 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
- else if (!strcasecmp (op_name, "BNEZC"))
- {
- if (rs_val != 0)
- target = pc + offset;
- else
- target = pc + 4;
- }
+ if (!strcasecmp(op_name, "BLTZC")) {
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BLEZC")) {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGEZC")) {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BGTZC")) {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BEQZC")) {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ } else if (!strcasecmp(op_name, "BNEZC")) {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+ }
- Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_J (llvm::MCInst& insn)
-{
- bool success = false;
- uint64_t offset, pc;
+bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
+ bool success = false;
+ uint64_t offset, pc;
- /*
- * J offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * J offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, pc))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, pc))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JAL (llvm::MCInst& insn)
-{
- bool success = false;
- uint64_t offset, target, pc;
+bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) {
+ bool success = false;
+ uint64_t offset, target, pc;
- /*
- * JAL offset
- * offset = sign_ext (offset << 2)
- * PC = PC[63-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+ /*
+ * JAL offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC[63-28] | offset
+ */
+ offset = insn.getOperand(0).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- /* This is a PC-region branch and not PC-relative */
- target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
+ /* This is a PC-region branch and not PC-relative */
+ target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JALR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs, rt;
- uint64_t pc, rs_val;
-
- /*
- * JALR rt, rs
- * GPR[rt] = PC + 8
- * PC = GPR[rs]
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_JALR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs, rt;
+ uint64_t pc, rs_val;
+
+ /*
+ * JALR rt, rs
+ * GPR[rt] = PC + 8
+ * PC = GPR[rs]
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg());
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ rs_val))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips64 + rt, pc + 8))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, pc + 8))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JIALC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int64_t target, offset, pc, rt_val;
-
- /*
- * JIALC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- * RA = PC + 4
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_JIALC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int64_t target, offset, pc, rt_val;
+
+ /*
+ * JIALC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ * RA = PC + 4
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips64, pc + 4))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips64,
+ pc + 4))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JIC (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rt;
- int64_t target, offset, rt_val;
-
- /*
- * JIC rt, offset
- * offset = sign_ext (offset)
- * PC = GPR[rt] + offset
- */
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rt, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rt;
+ int64_t target, offset, rt_val;
+
+ /*
+ * JIC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
+ */
+ rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ rt_val = (int64_t)ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
- target = rt_val + offset;
+ target = rt_val + offset;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_JR (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs;
- uint64_t rs_val;
+bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t rs;
+ uint64_t rs_val;
- /*
- * JR rs
- * PC = GPR[rs]
- */
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ /*
+ * JR rs
+ * PC = GPR[rs]
+ */
+ rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0, &success);
- if (!success)
- return false;
+ rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + rs, 0,
+ &success);
+ if (!success)
+ return false;
- Context context;
+ Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, rs_val))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ rs_val))
+ return false;
- return true;
+ return true;
}
/*
@@ -1745,428 +1966,410 @@ EmulateInstructionMIPS64::Emulate_JR (llvm::MCInst& insn)
BC1F, BC1FL : Branch on FP False (L stands for branch likely)
BC1T, BC1TL : Branch on FP True (L stands for branch likely)
*/
-bool
-EmulateInstructionMIPS64::Emulate_FP_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int64_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- /*
- * BC1F cc, offset
- * condition <- (FPConditionCode(cc) == 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + offset
- */
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int64_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
+
+ /*
+ * BC1F cc, offset
+ * condition <- (FPConditionCode(cc) == 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + offset
+ */
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
- if (!success)
- return false;
+ fcsr =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
+ if (!success)
+ return false;
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
-
- if (!strcasecmp (op_name, "BC1F") ||
- !strcasecmp (op_name, "BC1FL"))
- {
- if ((fcsr & (1 << cc)) == 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1T") ||
- !strcasecmp (op_name, "BC1TL"))
- {
- if ((fcsr & (1 << cc)) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- Context context;
+ if (!strcasecmp(op_name, "BC1F") || !strcasecmp(op_name, "BC1FL")) {
+ if ((fcsr & (1 << cc)) == 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1T") || !strcasecmp(op_name, "BC1TL")) {
+ if ((fcsr & (1 << cc)) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BC1EQZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint64_t ft_val;
- int64_t target, pc, offset;
-
- /*
- * BC1EQZ ft, offset
- * condition <- (FPR[ft].bit0 == 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint64_t ft_val;
+ int64_t target, pc, offset;
+
+ /*
+ * BC1EQZ ft, offset
+ * condition <- (FPR[ft].bit0 == 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, &success);
- if (!success)
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
+ &success);
+ if (!success)
+ return false;
- if ((ft_val & 1) == 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ if ((ft_val & 1) == 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BC1NEZ (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t ft;
- uint64_t ft_val;
- int64_t target, pc, offset;
-
- /*
- * BC1NEZ ft, offset
- * condition <- (FPR[ft].bit0 != 0)
- * if condition then
- * offset = sign_ext (offset)
- * PC = PC + 4 + offset
- */
- ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t ft;
+ uint64_t ft_val;
+ int64_t target, pc, offset;
+
+ /*
+ * BC1NEZ ft, offset
+ * condition <- (FPR[ft].bit0 != 0)
+ * if condition then
+ * offset = sign_ext (offset)
+ * PC = PC + 4 + offset
+ */
+ ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0, &success);
- if (!success)
- return false;
+ ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips64 + ft, 0,
+ &success);
+ if (!success)
+ return false;
- if ((ft_val & 1) != 0)
- target = pc + 4 + offset;
- else
- target = pc + 8;
-
- Context context;
+ if ((ft_val & 1) != 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 8;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ Context context;
- return true;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
/*
Emulate MIPS-3D Branch instructions
- BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes False/True
- BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes False/True
+ BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes
+ False/True
+ BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes
+ False/True
*/
-bool
-EmulateInstructionMIPS64::Emulate_3D_branch (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t cc, fcsr;
- int64_t pc, offset, target = 0;
- const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t cc, fcsr;
+ int64_t pc, offset, target = 0;
+ const char *op_name = m_insn_info->getName(insn.getOpcode()).data();
- fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips64, 0, &success);
- if (!success)
- return false;
+ cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- /* fcsr[23], fcsr[25-31] are vaild condition bits */
- fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+ pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (!strcasecmp (op_name, "BC1ANY2F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 3) != 3)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY2T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 3) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4F"))
- {
- /* if any one bit is 0 */
- if (((fcsr >> cc) & 0xf) != 0xf)
- target = pc + offset;
- else
- target = pc + 8;
- }
- else if (!strcasecmp (op_name, "BC1ANY4T"))
- {
- /* if any one bit is 1 */
- if (((fcsr >> cc) & 0xf) != 0)
- target = pc + offset;
- else
- target = pc + 8;
- }
+ fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips64,
+ 0, &success);
+ if (!success)
+ return false;
- Context context;
+ /* fcsr[23], fcsr[25-31] are vaild condition bits */
+ fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!strcasecmp(op_name, "BC1ANY2F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 3) != 3)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY2T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 3) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4F")) {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 0xf) != 0xf)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ } else if (!strcasecmp(op_name, "BC1ANY4T")) {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 0xf) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
- return true;
+ Context context;
+
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
+
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, true);
+bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, true);
+bool EmulateInstructionMIPS64::Emulate_BNZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, true);
+bool EmulateInstructionMIPS64::Emulate_BNZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, true);
+bool EmulateInstructionMIPS64::Emulate_BNZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZB (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 1, false);
+bool EmulateInstructionMIPS64::Emulate_BZB(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 1, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZH (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 2, false);
+bool EmulateInstructionMIPS64::Emulate_BZH(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 2, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZW (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 4, false);
+bool EmulateInstructionMIPS64::Emulate_BZW(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 4, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZD (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_DF(insn, 8, false);
+bool EmulateInstructionMIPS64::Emulate_BZD(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_DF(insn, 8, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz)
-{
- bool success = false, branch_hit = true;
- int64_t target = 0;
- RegisterValue reg_value;
- const uint8_t *ptr = NULL;
+bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
+ int element_byte_size,
+ bool bnz) {
+ bool success = false, branch_hit = true;
+ int64_t target = 0;
+ RegisterValue reg_value;
+ const uint8_t *ptr = NULL;
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int64_t offset = insn.getOperand(1).getImm();
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int64_t offset = insn.getOperand(1).getImm();
- int64_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+ int64_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
- ptr = (const uint8_t *)reg_value.GetBytes();
- else
- return false;
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
+ ptr = (const uint8_t *)reg_value.GetBytes();
+ else
+ return false;
- for(int i = 0; i < 16 / element_byte_size; i++)
- {
- switch(element_byte_size)
- {
- case 1:
- if((*ptr == 0 && bnz) || (*ptr != 0 && !bnz) )
- branch_hit = false;
- break;
- case 2:
- if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 4:
- if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- case 8:
- if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz))
- branch_hit = false;
- break;
- }
- if(!branch_hit)
- break;
- ptr = ptr + element_byte_size;
+ for (int i = 0; i < 16 / element_byte_size; i++) {
+ switch (element_byte_size) {
+ case 1:
+ if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 2:
+ if ((*(const uint16_t *)ptr == 0 && bnz) ||
+ (*(const uint16_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 4:
+ if ((*(const uint32_t *)ptr == 0 && bnz) ||
+ (*(const uint32_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
+ case 8:
+ if ((*(const uint64_t *)ptr == 0 && bnz) ||
+ (*(const uint64_t *)ptr != 0 && !bnz))
+ branch_hit = false;
+ break;
}
+ if (!branch_hit)
+ break;
+ ptr = ptr + element_byte_size;
+ }
- if(branch_hit)
- target = pc + offset;
- else
- target = pc + 8;
+ if (branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_BNZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, true);
+bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, true);
}
-bool
-EmulateInstructionMIPS64::Emulate_BZV (llvm::MCInst& insn)
-{
- return Emulate_MSA_Branch_V (insn, false);
+bool EmulateInstructionMIPS64::Emulate_BZV(llvm::MCInst &insn) {
+ return Emulate_MSA_Branch_V(insn, false);
}
-bool
-EmulateInstructionMIPS64::Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz)
-{
- bool success = false;
- int64_t target = 0;
- llvm::APInt wr_val = llvm::APInt::getNullValue(128);
- llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
- llvm::APInt zero_value = llvm::APInt::getNullValue(128);
- RegisterValue reg_value;
-
- uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int64_t offset = insn.getOperand(1).getImm();
-
- int64_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
- if (!success)
- return false;
+bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn,
+ bool bnz) {
+ bool success = false;
+ int64_t target = 0;
+ llvm::APInt wr_val = llvm::APInt::getNullValue(128);
+ llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
+ llvm::APInt zero_value = llvm::APInt::getNullValue(128);
+ RegisterValue reg_value;
+
+ uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg());
+ int64_t offset = insn.getOperand(1).getImm();
+
+ int64_t pc =
+ ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
- if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
- wr_val = reg_value.GetAsUInt128(fail_value);
- else
- return false;
+ if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips64 + wt, reg_value))
+ wr_val = reg_value.GetAsUInt128(fail_value);
+ else
+ return false;
- if((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
- target = pc + offset;
- else
- target = pc + 8;
+ if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) ||
+ (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz))
+ target = pc + offset;
+ else
+ target = pc + 8;
- Context context;
- context.type = eContextRelativeBranchImmediate;
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips64, target))
- return false;
+ if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target))
+ return false;
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_LDST_Imm (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base;
- int64_t imm, address;
- Context bad_vaddr_context;
+bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base;
+ int64_t imm, address;
+ Context bad_vaddr_context;
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- imm = insn.getOperand(num_operands-1).getImm();
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ imm = insn.getOperand(num_operands - 1).getImm();
- RegisterInfo reg_info_base;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+ RegisterInfo reg_info_base;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- /* read base register */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
+ &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
-bool
-EmulateInstructionMIPS64::Emulate_LDST_Reg (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t base, index;
- int64_t address, index_address;
- Context bad_vaddr_context;
-
- uint32_t num_operands = insn.getNumOperands();
- base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
- index = m_reg_info->getEncodingValue (insn.getOperand(num_operands-1).getReg());
-
- RegisterInfo reg_info_base, reg_info_index;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base))
- return false;
+bool EmulateInstructionMIPS64::Emulate_LDST_Reg(llvm::MCInst &insn) {
+ bool success = false;
+ uint32_t base, index;
+ int64_t address, index_address;
+ Context bad_vaddr_context;
+
+ uint32_t num_operands = insn.getNumOperands();
+ base =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg());
+ index =
+ m_reg_info->getEncodingValue(insn.getOperand(num_operands - 1).getReg());
+
+ RegisterInfo reg_info_base, reg_info_index;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base,
+ reg_info_base))
+ return false;
- if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + index, reg_info_index))
- return false;
+ if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index,
+ reg_info_index))
+ return false;
- /* read base register */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success);
- if (!success)
- return false;
+ /* read base register */
+ address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0,
+ &success);
+ if (!success)
+ return false;
- /* read index register */
- index_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success);
- if (!success)
- return false;
+ /* read index register */
+ index_address = ReadRegisterUnsigned(eRegisterKindDWARF,
+ dwarf_zero_mips + index, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + index_address;
+ /* destination address */
+ address = address + index_address;
- /* Set the bad_vaddr register with base address used in the instruction */
- bad_vaddr_context.type = eContextInvalid;
- WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address);
+ /* Set the bad_vaddr register with base address used in the instruction */
+ bad_vaddr_context.type = eContextInvalid;
+ WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips,
+ address);
- return true;
+ return true;
}
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
index 4ee690bbf184..5543615efade 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
@@ -18,232 +18,170 @@
#include "lldb/Core/Error.h"
#include "lldb/Interpreter/OptionValue.h"
-namespace llvm
-{
- class MCDisassembler;
- class MCSubtargetInfo;
- class MCRegisterInfo;
- class MCAsmInfo;
- class MCContext;
- class MCInstrInfo;
- class MCInst;
+namespace llvm {
+class MCDisassembler;
+class MCSubtargetInfo;
+class MCRegisterInfo;
+class MCAsmInfo;
+class MCContext;
+class MCInstrInfo;
+class MCInst;
} // namespace llvm
-class EmulateInstructionMIPS64 : public lldb_private::EmulateInstruction
-{
-public:
- EmulateInstructionMIPS64(const lldb_private::ArchSpec &arch);
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetPluginDescriptionStatic ();
-
- static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch,
- lldb_private::InstructionType inst_type);
-
- static bool
- SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
- {
- switch (inst_type)
- {
- case lldb_private::eInstructionTypeAny:
- case lldb_private::eInstructionTypePrologueEpilogue:
- case lldb_private::eInstructionTypePCModifying:
- return true;
-
- case lldb_private::eInstructionTypeAll:
- return false;
- }
- return false;
- }
+class EmulateInstructionMIPS64 : public lldb_private::EmulateInstruction {
+public:
+ EmulateInstructionMIPS64(const lldb_private::ArchSpec &arch);
- lldb_private::ConstString
- GetPluginName() override;
+ static void Initialize();
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ static void Terminate();
- bool
- SetTargetTriple(const lldb_private::ArchSpec &arch) override;
-
- bool
- SupportsEmulatingInstructionsOfType(lldb_private::InstructionType inst_type) override
- {
- return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
- }
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
- bool
- ReadInstruction() override;
-
- bool
- EvaluateInstruction(uint32_t evaluate_options) override;
-
- bool
- TestEmulation(lldb_private::Stream *out_stream,
- lldb_private::ArchSpec &arch,
- lldb_private::OptionValueDictionary *test_data) override
- {
- return false;
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch,
+ lldb_private::InstructionType inst_type);
+
+ static bool SupportsEmulatingInstructionsOfTypeStatic(
+ lldb_private::InstructionType inst_type) {
+ switch (inst_type) {
+ case lldb_private::eInstructionTypeAny:
+ case lldb_private::eInstructionTypePrologueEpilogue:
+ case lldb_private::eInstructionTypePCModifying:
+ return true;
+
+ case lldb_private::eInstructionTypeAll:
+ return false;
}
+ return false;
+ }
+
+ lldb_private::ConstString GetPluginName() override;
- bool
- GetRegisterInfo(lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- lldb_private::RegisterInfo &reg_info) override;
+ uint32_t GetPluginVersion() override { return 1; }
- bool
- CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
+ bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
+
+ bool SupportsEmulatingInstructionsOfType(
+ lldb_private::InstructionType inst_type) override {
+ return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
+ }
+
+ bool ReadInstruction() override;
+
+ bool EvaluateInstruction(uint32_t evaluate_options) override;
+
+ bool TestEmulation(lldb_private::Stream *out_stream,
+ lldb_private::ArchSpec &arch,
+ lldb_private::OptionValueDictionary *test_data) override {
+ return false;
+ }
+
+ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ lldb_private::RegisterInfo &reg_info) override;
+
+ bool
+ CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
protected:
- typedef struct
- {
- const char *op_name;
- bool (EmulateInstructionMIPS64::*callback) (llvm::MCInst& insn);
- const char *insn_name;
- } MipsOpcode;
-
- static MipsOpcode*
- GetOpcodeForInstruction (const char *op_name);
+ typedef struct {
+ const char *op_name;
+ bool (EmulateInstructionMIPS64::*callback)(llvm::MCInst &insn);
+ const char *insn_name;
+ } MipsOpcode;
+
+ static MipsOpcode *GetOpcodeForInstruction(const char *op_name);
- bool
- Emulate_DADDiu (llvm::MCInst& insn);
+ bool Emulate_DADDiu(llvm::MCInst &insn);
- bool
- Emulate_DSUBU_DADDU (llvm::MCInst& insn);
+ bool Emulate_DSUBU_DADDU(llvm::MCInst &insn);
- bool
- Emulate_LUI (llvm::MCInst& insn);
+ bool Emulate_LUI(llvm::MCInst &insn);
- bool
- Emulate_SD (llvm::MCInst& insn);
+ bool Emulate_SD(llvm::MCInst &insn);
- bool
- Emulate_LD (llvm::MCInst& insn);
+ bool Emulate_LD(llvm::MCInst &insn);
- bool
- Emulate_LDST_Imm (llvm::MCInst& insn);
+ bool Emulate_LDST_Imm(llvm::MCInst &insn);
- bool
- Emulate_LDST_Reg (llvm::MCInst& insn);
+ bool Emulate_LDST_Reg(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_3ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_3ops_C(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops(llvm::MCInst &insn);
- bool
- Emulate_BXX_2ops_C (llvm::MCInst& insn);
+ bool Emulate_BXX_2ops_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link_C (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link_C(llvm::MCInst &insn);
- bool
- Emulate_Bcond_Link (llvm::MCInst& insn);
+ bool Emulate_Bcond_Link(llvm::MCInst &insn);
- bool
- Emulate_FP_branch (llvm::MCInst& insn);
+ bool Emulate_FP_branch(llvm::MCInst &insn);
- bool
- Emulate_3D_branch (llvm::MCInst& insn);
+ bool Emulate_3D_branch(llvm::MCInst &insn);
- bool
- Emulate_BAL (llvm::MCInst& insn);
+ bool Emulate_BAL(llvm::MCInst &insn);
- bool
- Emulate_BALC (llvm::MCInst& insn);
+ bool Emulate_BALC(llvm::MCInst &insn);
- bool
- Emulate_BC (llvm::MCInst& insn);
+ bool Emulate_BC(llvm::MCInst &insn);
- bool
- Emulate_J (llvm::MCInst& insn);
+ bool Emulate_J(llvm::MCInst &insn);
- bool
- Emulate_JAL (llvm::MCInst& insn);
+ bool Emulate_JAL(llvm::MCInst &insn);
- bool
- Emulate_JALR (llvm::MCInst& insn);
+ bool Emulate_JALR(llvm::MCInst &insn);
- bool
- Emulate_JIALC (llvm::MCInst& insn);
+ bool Emulate_JIALC(llvm::MCInst &insn);
- bool
- Emulate_JIC (llvm::MCInst& insn);
+ bool Emulate_JIC(llvm::MCInst &insn);
- bool
- Emulate_JR (llvm::MCInst& insn);
+ bool Emulate_JR(llvm::MCInst &insn);
- bool
- Emulate_BC1EQZ (llvm::MCInst& insn);
+ bool Emulate_BC1EQZ(llvm::MCInst &insn);
- bool
- Emulate_BC1NEZ (llvm::MCInst& insn);
+ bool Emulate_BC1NEZ(llvm::MCInst &insn);
- bool
- Emulate_BNZB (llvm::MCInst& insn);
+ bool Emulate_BNZB(llvm::MCInst &insn);
- bool
- Emulate_BNZH (llvm::MCInst& insn);
+ bool Emulate_BNZH(llvm::MCInst &insn);
- bool
- Emulate_BNZW (llvm::MCInst& insn);
+ bool Emulate_BNZW(llvm::MCInst &insn);
- bool
- Emulate_BNZD (llvm::MCInst& insn);
+ bool Emulate_BNZD(llvm::MCInst &insn);
- bool
- Emulate_BZB (llvm::MCInst& insn);
+ bool Emulate_BZB(llvm::MCInst &insn);
- bool
- Emulate_BZH (llvm::MCInst& insn);
+ bool Emulate_BZH(llvm::MCInst &insn);
- bool
- Emulate_BZW (llvm::MCInst& insn);
+ bool Emulate_BZW(llvm::MCInst &insn);
- bool
- Emulate_BZD (llvm::MCInst& insn);
+ bool Emulate_BZD(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz);
+ bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size,
+ bool bnz);
- bool
- Emulate_BNZV (llvm::MCInst& insn);
+ bool Emulate_BNZV(llvm::MCInst &insn);
- bool
- Emulate_BZV (llvm::MCInst& insn);
+ bool Emulate_BZV(llvm::MCInst &insn);
- bool
- Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz);
+ bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz);
- bool
- nonvolatile_reg_p (uint64_t regnum);
+ bool nonvolatile_reg_p(uint64_t regnum);
- const char *
- GetRegisterName (unsigned reg_num, bool altnernate_name);
+ const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
private:
- std::unique_ptr<llvm::MCDisassembler> m_disasm;
- std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
- std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
- std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
- std::unique_ptr<llvm::MCContext> m_context;
- std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
+ std::unique_ptr<llvm::MCDisassembler> m_disasm;
+ std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
+ std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
+ std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
+ std::unique_ptr<llvm::MCContext> m_context;
+ std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
};
#endif // EmulateInstructionMIPS64_h_
diff --git a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
index 99857cd3d1b0..db626b066152 100644
--- a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
@@ -12,124 +12,68 @@
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Symbol.h"
-#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "llvm/ADT/StringSwitch.h"
+
using namespace lldb;
using namespace lldb_private;
lldb::InstrumentationRuntimeSP
-AddressSanitizerRuntime::CreateInstance (const lldb::ProcessSP &process_sp)
-{
- return InstrumentationRuntimeSP(new AddressSanitizerRuntime(process_sp));
+AddressSanitizerRuntime::CreateInstance(const lldb::ProcessSP &process_sp) {
+ return InstrumentationRuntimeSP(new AddressSanitizerRuntime(process_sp));
}
-void
-AddressSanitizerRuntime::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "AddressSanitizer instrumentation runtime plugin.",
- CreateInstance,
- GetTypeStatic);
+void AddressSanitizerRuntime::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "AddressSanitizer instrumentation runtime plugin.",
+ CreateInstance, GetTypeStatic);
}
-void
-AddressSanitizerRuntime::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void AddressSanitizerRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-AddressSanitizerRuntime::GetPluginNameStatic()
-{
- return ConstString("AddressSanitizer");
+lldb_private::ConstString AddressSanitizerRuntime::GetPluginNameStatic() {
+ return ConstString("AddressSanitizer");
}
-lldb::InstrumentationRuntimeType
-AddressSanitizerRuntime::GetTypeStatic()
-{
- return eInstrumentationRuntimeTypeAddressSanitizer;
+lldb::InstrumentationRuntimeType AddressSanitizerRuntime::GetTypeStatic() {
+ return eInstrumentationRuntimeTypeAddressSanitizer;
}
-AddressSanitizerRuntime::AddressSanitizerRuntime(const ProcessSP &process_sp) :
- m_is_active(false),
- m_runtime_module(),
- m_process_wp(),
- m_breakpoint_id(0)
-{
- if (process_sp)
- m_process_wp = process_sp;
-}
+AddressSanitizerRuntime::~AddressSanitizerRuntime() { Deactivate(); }
-AddressSanitizerRuntime::~AddressSanitizerRuntime()
-{
- Deactivate();
+const RegularExpression &
+AddressSanitizerRuntime::GetPatternForRuntimeLibrary() {
+ // FIXME: This shouldn't include the "dylib" suffix.
+ static RegularExpression regex(
+ llvm::StringRef("libclang_rt.asan_(.*)_dynamic\\.dylib"));
+ return regex;
}
-bool ModuleContainsASanRuntime(Module * module)
-{
- const Symbol* symbol = module->FindFirstSymbolWithNameAndType(
- ConstString("__asan_get_alloc_stack"),
- lldb::eSymbolTypeAny);
+bool AddressSanitizerRuntime::CheckIfRuntimeIsValid(
+ const lldb::ModuleSP module_sp) {
+ const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
+ ConstString("__asan_get_alloc_stack"), lldb::eSymbolTypeAny);
- return symbol != nullptr;
+ return symbol != nullptr;
}
-void
-AddressSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
-{
- if (IsActive())
- return;
-
- if (m_runtime_module) {
- Activate();
- return;
- }
-
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
- const size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; ++i)
- {
- Module *module_pointer = module_list.GetModulePointerAtIndexUnlocked(i);
- const FileSpec & file_spec = module_pointer->GetFileSpec();
- if (! file_spec)
- continue;
-
- static RegularExpression g_asan_runtime_regex("libclang_rt.asan_(.*)_dynamic\\.dylib");
- if (g_asan_runtime_regex.Execute (file_spec.GetFilename().GetCString()) || module_pointer->IsExecutable())
- {
- if (ModuleContainsASanRuntime(module_pointer))
- {
- m_runtime_module = module_pointer->shared_from_this();
- Activate();
- return;
- }
- }
- }
-}
-
-bool
-AddressSanitizerRuntime::IsActive()
-{
- return m_is_active;
-}
-
-#define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000
-const char *
-address_sanitizer_retrieve_report_data_prefix = R"(
+static constexpr std::chrono::seconds g_retrieve_report_data_function_timeout(2);
+const char *address_sanitizer_retrieve_report_data_prefix = R"(
extern "C"
{
int __asan_report_present();
@@ -143,8 +87,7 @@ size_t __asan_get_report_access_size();
}
)";
-const char *
-address_sanitizer_retrieve_report_data_command = R"(
+const char *address_sanitizer_retrieve_report_data_command = R"(
struct {
int present;
int access_type;
@@ -167,194 +110,221 @@ t.description = __asan_get_report_description();
t
)";
-StructuredData::ObjectSP
-AddressSanitizerRuntime::RetrieveReportData()
-{
- ProcessSP process_sp = GetProcessSP();
- if (!process_sp)
- return StructuredData::ObjectSP();
-
- ThreadSP thread_sp = process_sp->GetThreadList().GetExpressionExecutionThread();
- StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
-
- if (!frame_sp)
- return StructuredData::ObjectSP();
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(true);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeoutUsec(RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC);
- options.SetPrefix(address_sanitizer_retrieve_report_data_prefix);
- options.SetAutoApplyFixIts(false);
- options.SetLanguage(eLanguageTypeObjC_plus_plus);
-
- ValueObjectSP return_value_sp;
- ExecutionContext exe_ctx;
- Error eval_error;
- frame_sp->CalculateExecutionContext(exe_ctx);
- ExpressionResults result = UserExpression::Evaluate (exe_ctx,
- options,
- address_sanitizer_retrieve_report_data_command,
- "",
- return_value_sp,
- eval_error);
- if (result != eExpressionCompleted) {
- process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", eval_error.AsCString());
- return StructuredData::ObjectSP();
- }
-
- int present = return_value_sp->GetValueForExpressionPath(".present")->GetValueAsUnsigned(0);
- if (present != 1)
- return StructuredData::ObjectSP();
-
- addr_t pc = return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0);
- /* commented out because rdar://problem/18533301
- addr_t bp = return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0);
- addr_t sp = return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0);
- */
- addr_t address = return_value_sp->GetValueForExpressionPath(".address")->GetValueAsUnsigned(0);
- addr_t access_type = return_value_sp->GetValueForExpressionPath(".access_type")->GetValueAsUnsigned(0);
- addr_t access_size = return_value_sp->GetValueForExpressionPath(".access_size")->GetValueAsUnsigned(0);
- addr_t description_ptr = return_value_sp->GetValueForExpressionPath(".description")->GetValueAsUnsigned(0);
- std::string description;
- Error error;
- process_sp->ReadCStringFromMemory(description_ptr, description, error);
-
- StructuredData::Dictionary *dict = new StructuredData::Dictionary();
- dict->AddStringItem("instrumentation_class", "AddressSanitizer");
- dict->AddStringItem("stop_type", "fatal_error");
- dict->AddIntegerItem("pc", pc);
- /* commented out because rdar://problem/18533301
- dict->AddIntegerItem("bp", bp);
- dict->AddIntegerItem("sp", sp);
- */
- dict->AddIntegerItem("address", address);
- dict->AddIntegerItem("access_type", access_type);
- dict->AddIntegerItem("access_size", access_size);
- dict->AddStringItem("description", description);
-
- return StructuredData::ObjectSP(dict);
+StructuredData::ObjectSP AddressSanitizerRuntime::RetrieveReportData() {
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return StructuredData::ObjectSP();
+
+ ThreadSP thread_sp =
+ process_sp->GetThreadList().GetExpressionExecutionThread();
+ StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
+
+ if (!frame_sp)
+ return StructuredData::ObjectSP();
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(g_retrieve_report_data_function_timeout);
+ options.SetPrefix(address_sanitizer_retrieve_report_data_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeObjC_plus_plus);
+
+ ValueObjectSP return_value_sp;
+ ExecutionContext exe_ctx;
+ Error eval_error;
+ frame_sp->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = UserExpression::Evaluate(
+ exe_ctx, options, address_sanitizer_retrieve_report_data_command, "",
+ return_value_sp, eval_error);
+ if (result != eExpressionCompleted) {
+ process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf(
+ "Warning: Cannot evaluate AddressSanitizer expression:\n%s\n",
+ eval_error.AsCString());
+ return StructuredData::ObjectSP();
+ }
+
+ int present = return_value_sp->GetValueForExpressionPath(".present")
+ ->GetValueAsUnsigned(0);
+ if (present != 1)
+ return StructuredData::ObjectSP();
+
+ addr_t pc =
+ return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0);
+ /* commented out because rdar://problem/18533301
+ addr_t bp =
+ return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0);
+ addr_t sp =
+ return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0);
+ */
+ addr_t address = return_value_sp->GetValueForExpressionPath(".address")
+ ->GetValueAsUnsigned(0);
+ addr_t access_type =
+ return_value_sp->GetValueForExpressionPath(".access_type")
+ ->GetValueAsUnsigned(0);
+ addr_t access_size =
+ return_value_sp->GetValueForExpressionPath(".access_size")
+ ->GetValueAsUnsigned(0);
+ addr_t description_ptr =
+ return_value_sp->GetValueForExpressionPath(".description")
+ ->GetValueAsUnsigned(0);
+ std::string description;
+ Error error;
+ process_sp->ReadCStringFromMemory(description_ptr, description, error);
+
+ StructuredData::Dictionary *dict = new StructuredData::Dictionary();
+ dict->AddStringItem("instrumentation_class", "AddressSanitizer");
+ dict->AddStringItem("stop_type", "fatal_error");
+ dict->AddIntegerItem("pc", pc);
+ /* commented out because rdar://problem/18533301
+ dict->AddIntegerItem("bp", bp);
+ dict->AddIntegerItem("sp", sp);
+ */
+ dict->AddIntegerItem("address", address);
+ dict->AddIntegerItem("access_type", access_type);
+ dict->AddIntegerItem("access_size", access_size);
+ dict->AddStringItem("description", description);
+
+ return StructuredData::ObjectSP(dict);
}
std::string
-AddressSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report)
-{
- std::string description = report->GetAsDictionary()->GetValueForKey("description")->GetAsString()->GetValue();
- if (description == "heap-use-after-free") {
- return "Use of deallocated memory detected";
- } else if (description == "heap-buffer-overflow") {
- return "Heap buffer overflow detected";
- } else if (description == "stack-buffer-underflow") {
- return "Stack buffer underflow detected";
- } else if (description == "initialization-order-fiasco") {
- return "Initialization order problem detected";
- } else if (description == "stack-buffer-overflow") {
- return "Stack buffer overflow detected";
- } else if (description == "stack-use-after-return") {
- return "Use of returned stack memory detected";
- } else if (description == "use-after-poison") {
- return "Use of poisoned memory detected";
- } else if (description == "container-overflow") {
- return "Container overflow detected";
- } else if (description == "stack-use-after-scope") {
- return "Use of out-of-scope stack memory detected";
- } else if (description == "global-buffer-overflow") {
- return "Global buffer overflow detected";
- } else if (description == "unknown-crash") {
- return "Invalid memory access detected";
- }
-
- // for unknown report codes just show the code
- return description;
+AddressSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report) {
+ std::string description = report->GetAsDictionary()
+ ->GetValueForKey("description")
+ ->GetAsString()
+ ->GetValue();
+ return llvm::StringSwitch<std::string>(description)
+ .Case("heap-use-after-free", "Use of deallocated memory")
+ .Case("heap-buffer-overflow", "Heap buffer overflow")
+ .Case("stack-buffer-underflow", "Stack buffer underflow")
+ .Case("initialization-order-fiasco", "Initialization order problem")
+ .Case("stack-buffer-overflow", "Stack buffer overflow")
+ .Case("stack-use-after-return", "Use of stack memory after return")
+ .Case("use-after-poison", "Use of poisoned memory")
+ .Case("container-overflow", "Container overflow")
+ .Case("stack-use-after-scope", "Use of out-of-scope stack memory")
+ .Case("global-buffer-overflow", "Global buffer overflow")
+ .Case("unknown-crash", "Invalid memory access")
+ .Case("stack-overflow", "Stack space exhausted")
+ .Case("null-deref", "Dereference of null pointer")
+ .Case("wild-jump", "Jump to non-executable address")
+ .Case("wild-addr-write", "Write through wild pointer")
+ .Case("wild-addr-read", "Read from wild pointer")
+ .Case("wild-addr", "Access through wild pointer")
+ .Case("signal", "Deadly signal")
+ .Case("double-free", "Deallocation of freed memory")
+ .Case("new-delete-type-mismatch",
+ "Deallocation size different from allocation size")
+ .Case("bad-free", "Deallocation of non-allocated memory")
+ .Case("alloc-dealloc-mismatch",
+ "Mismatch between allocation and deallocation APIs")
+ .Case("bad-malloc_usable_size", "Invalid argument to malloc_usable_size")
+ .Case("bad-__sanitizer_get_allocated_size",
+ "Invalid argument to __sanitizer_get_allocated_size")
+ .Case("param-overlap",
+ "Call to function disallowing overlapping memory ranges")
+ .Case("negative-size-param", "Negative size used when accessing memory")
+ .Case("bad-__sanitizer_annotate_contiguous_container",
+ "Invalid argument to __sanitizer_annotate_contiguous_container")
+ .Case("odr-violation", "Symbol defined in multiple translation units")
+ .Case(
+ "invalid-pointer-pair",
+ "Comparison or arithmetic on pointers from different memory regions")
+ // for unknown report codes just show the code
+ .Default("AddressSanitizer detected: " + description);
}
-bool
-AddressSanitizerRuntime::NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id)
-{
- assert (baton && "null baton");
- if (!baton)
- return false;
+bool AddressSanitizerRuntime::NotifyBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(baton && "null baton");
+ if (!baton)
+ return false;
- AddressSanitizerRuntime *const instance = static_cast<AddressSanitizerRuntime*>(baton);
+ AddressSanitizerRuntime *const instance =
+ static_cast<AddressSanitizerRuntime *>(baton);
- StructuredData::ObjectSP report = instance->RetrieveReportData();
- std::string description;
- if (report) {
- description = instance->FormatDescription(report);
- }
- ProcessSP process_sp = instance->GetProcessSP();
- // Make sure this is the right process
- if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP())
- {
- ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
- if (thread_sp)
- thread_sp->SetStopInfo(InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(*thread_sp, description.c_str(), report));
-
- StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
- if (stream_sp)
- {
- stream_sp->Printf ("AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.\n");
- }
- return true; // Return true to stop the target
+ StructuredData::ObjectSP report = instance->RetrieveReportData();
+ std::string description;
+ if (report) {
+ description = instance->FormatDescription(report);
+ }
+ ProcessSP process_sp = instance->GetProcessSP();
+ // Make sure this is the right process
+ if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
+ ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
+ if (thread_sp)
+ thread_sp->SetStopInfo(InstrumentationRuntimeStopInfo::
+ CreateStopReasonWithInstrumentationData(
+ *thread_sp, description, report));
+
+ StreamFileSP stream_sp(
+ process_sp->GetTarget().GetDebugger().GetOutputFile());
+ if (stream_sp) {
+ stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread "
+ "info -s' to get extended information about the "
+ "report.\n");
}
- else
- return false; // Let target run
+ return true; // Return true to stop the target
+ } else
+ return false; // Let target run
}
-void
-AddressSanitizerRuntime::Activate()
-{
- if (m_is_active)
- return;
+void AddressSanitizerRuntime::Activate() {
+ if (IsActive())
+ return;
- ProcessSP process_sp = GetProcessSP();
- if (!process_sp)
- return;
-
- ConstString symbol_name ("__asan::AsanDie()");
- const Symbol *symbol = m_runtime_module->FindFirstSymbolWithNameAndType (symbol_name, eSymbolTypeCode);
-
- if (symbol == NULL)
- return;
-
- if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
- return;
-
- Target &target = process_sp->GetTarget();
- addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
-
- if (symbol_address == LLDB_INVALID_ADDRESS)
- return;
-
- bool internal = true;
- bool hardware = false;
- Breakpoint *breakpoint = process_sp->GetTarget().CreateBreakpoint(symbol_address, internal, hardware).get();
- breakpoint->SetCallback (AddressSanitizerRuntime::NotifyBreakpointHit, this, true);
- breakpoint->SetBreakpointKind ("address-sanitizer-report");
- m_breakpoint_id = breakpoint->GetID();
-
- StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
- if (stream_sp)
- {
- stream_sp->Printf ("AddressSanitizer debugger support is active. Memory error breakpoint has been installed and you can now use the 'memory history' command.\n");
- }
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return;
+
+ ConstString symbol_name("__asan::AsanDie()");
+ const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType(
+ symbol_name, eSymbolTypeCode);
+
+ if (symbol == NULL)
+ return;
+
+ if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
+ return;
- m_is_active = true;
+ Target &target = process_sp->GetTarget();
+ addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
+
+ if (symbol_address == LLDB_INVALID_ADDRESS)
+ return;
+
+ bool internal = true;
+ bool hardware = false;
+ Breakpoint *breakpoint =
+ process_sp->GetTarget()
+ .CreateBreakpoint(symbol_address, internal, hardware)
+ .get();
+ breakpoint->SetCallback(AddressSanitizerRuntime::NotifyBreakpointHit, this,
+ true);
+ breakpoint->SetBreakpointKind("address-sanitizer-report");
+ SetBreakpointID(breakpoint->GetID());
+
+ StreamFileSP stream_sp(process_sp->GetTarget().GetDebugger().GetOutputFile());
+ if (stream_sp) {
+ stream_sp->Printf("AddressSanitizer debugger support is active. Memory "
+ "error breakpoint has been installed and you can now use "
+ "the 'memory history' command.\n");
+ }
+
+ SetActive(true);
}
-void
-AddressSanitizerRuntime::Deactivate()
-{
- if (m_breakpoint_id != LLDB_INVALID_BREAK_ID)
- {
- ProcessSP process_sp = GetProcessSP();
- if (process_sp)
- {
- process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
- m_breakpoint_id = LLDB_INVALID_BREAK_ID;
- }
+void AddressSanitizerRuntime::Deactivate() {
+ if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ ProcessSP process_sp = GetProcessSP();
+ if (process_sp) {
+ process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
+ SetBreakpointID(LLDB_INVALID_BREAK_ID);
}
- m_is_active = false;
+ }
+ SetActive(false);
}
diff --git a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h
index fe12ab847e76..9fd21c06f30c 100644
--- a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h
+++ b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h
@@ -14,85 +14,58 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/ABI.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/Process.h"
-#include "lldb/Core/StructuredData.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class AddressSanitizerRuntime : public lldb_private::InstrumentationRuntime
-{
+
+class AddressSanitizerRuntime : public lldb_private::InstrumentationRuntime {
public:
- ~AddressSanitizerRuntime() override;
-
- static lldb::InstrumentationRuntimeSP
- CreateInstance (const lldb::ProcessSP &process_sp);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static lldb::InstrumentationRuntimeType
- GetTypeStatic();
-
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- virtual lldb::InstrumentationRuntimeType
- GetType() { return GetTypeStatic(); }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- void
- ModulesDidLoad(lldb_private::ModuleList &module_list) override;
-
- bool
- IsActive() override;
-
+ ~AddressSanitizerRuntime() override;
+
+ static lldb::InstrumentationRuntimeSP
+ CreateInstance(const lldb::ProcessSP &process_sp);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static lldb::InstrumentationRuntimeType GetTypeStatic();
+
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
private:
- AddressSanitizerRuntime(const lldb::ProcessSP &process_sp);
-
- lldb::ProcessSP
- GetProcessSP ()
- {
- return m_process_wp.lock();
- }
-
- void
- Activate();
-
- void
- Deactivate();
-
- static bool
- NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
- StructuredData::ObjectSP
- RetrieveReportData();
-
- std::string
- FormatDescription(StructuredData::ObjectSP report);
-
- bool m_is_active;
- lldb::ModuleSP m_runtime_module;
- lldb::ProcessWP m_process_wp;
- lldb::user_id_t m_breakpoint_id;
+ AddressSanitizerRuntime(const lldb::ProcessSP &process_sp)
+ : lldb_private::InstrumentationRuntime(process_sp) {}
+
+ const RegularExpression &GetPatternForRuntimeLibrary() override;
+
+ bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override;
+
+ void Activate() override;
+
+ void Deactivate();
+
+ static bool NotifyBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ StructuredData::ObjectSP RetrieveReportData();
+
+ std::string FormatDescription(StructuredData::ObjectSP report);
};
-
+
} // namespace lldb_private
#endif // liblldb_AddressSanitizerRuntime_h_
diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
index 62e5ce63a542..3010724306e4 100644
--- a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
@@ -9,13 +9,13 @@
#include "ThreadSanitizerRuntime.h"
+#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
@@ -30,109 +30,38 @@
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "Plugins/Process/Utility/HistoryThread.h"
using namespace lldb;
using namespace lldb_private;
lldb::InstrumentationRuntimeSP
-ThreadSanitizerRuntime::CreateInstance (const lldb::ProcessSP &process_sp)
-{
- return InstrumentationRuntimeSP(new ThreadSanitizerRuntime(process_sp));
-}
-
-void
-ThreadSanitizerRuntime::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "ThreadSanitizer instrumentation runtime plugin.",
- CreateInstance,
- GetTypeStatic);
+ThreadSanitizerRuntime::CreateInstance(const lldb::ProcessSP &process_sp) {
+ return InstrumentationRuntimeSP(new ThreadSanitizerRuntime(process_sp));
}
-void
-ThreadSanitizerRuntime::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ThreadSanitizerRuntime::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "ThreadSanitizer instrumentation runtime plugin.",
+ CreateInstance, GetTypeStatic);
}
-lldb_private::ConstString
-ThreadSanitizerRuntime::GetPluginNameStatic()
-{
- return ConstString("ThreadSanitizer");
+void ThreadSanitizerRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb::InstrumentationRuntimeType
-ThreadSanitizerRuntime::GetTypeStatic()
-{
- return eInstrumentationRuntimeTypeThreadSanitizer;
+lldb_private::ConstString ThreadSanitizerRuntime::GetPluginNameStatic() {
+ return ConstString("ThreadSanitizer");
}
-ThreadSanitizerRuntime::ThreadSanitizerRuntime(const ProcessSP &process_sp) :
-m_is_active(false),
-m_runtime_module_wp(),
-m_process_wp(),
-m_breakpoint_id(0)
-{
- if (process_sp)
- m_process_wp = process_sp;
-}
-
-ThreadSanitizerRuntime::~ThreadSanitizerRuntime()
-{
- Deactivate();
-}
-
-static bool
-ModuleContainsTSanRuntime(ModuleSP module_sp)
-{
- static ConstString g_tsan_get_current_report("__tsan_get_current_report");
- const Symbol* symbol = module_sp->FindFirstSymbolWithNameAndType(g_tsan_get_current_report, lldb::eSymbolTypeAny);
- return symbol != nullptr;
-}
-
-void
-ThreadSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
-{
- if (IsActive())
- return;
-
- if (GetRuntimeModuleSP()) {
- Activate();
- return;
- }
-
- module_list.ForEach ([this](const lldb::ModuleSP module_sp) -> bool
- {
- const FileSpec & file_spec = module_sp->GetFileSpec();
- if (! file_spec)
- return true; // Keep iterating through modules
-
- llvm::StringRef module_basename(file_spec.GetFilename().GetStringRef());
- if (module_sp->IsExecutable() || module_basename.startswith("libclang_rt.tsan_"))
- {
- if (ModuleContainsTSanRuntime(module_sp))
- {
- m_runtime_module_wp = module_sp;
- Activate();
- return false; // Stop iterating
- }
- }
-
- return true; // Keep iterating through modules
- });
+lldb::InstrumentationRuntimeType ThreadSanitizerRuntime::GetTypeStatic() {
+ return eInstrumentationRuntimeTypeThreadSanitizer;
}
-bool
-ThreadSanitizerRuntime::IsActive()
-{
- return m_is_active;
-}
+ThreadSanitizerRuntime::~ThreadSanitizerRuntime() { Deactivate(); }
-#define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000
+static constexpr std::chrono::seconds g_retrieve_data_function_timeout(2);
-const char *
-thread_sanitizer_retrieve_report_data_prefix = R"(
+const char *thread_sanitizer_retrieve_report_data_prefix = R"(
extern "C"
{
void *__tsan_get_current_report();
@@ -226,8 +155,7 @@ struct data {
};
)";
-const char *
-thread_sanitizer_retrieve_report_data_command = R"(
+const char *thread_sanitizer_retrieve_report_data_command = R"(
data t = {0};
t.report = __tsan_get_current_report();
@@ -273,615 +201,820 @@ t;
)";
static StructuredData::Array *
-CreateStackTrace(ValueObjectSP o, std::string trace_item_name = ".trace") {
- StructuredData::Array *trace = new StructuredData::Array();
- ValueObjectSP trace_value_object = o->GetValueForExpressionPath(trace_item_name.c_str());
- for (int j = 0; j < 8; j++) {
- addr_t trace_addr = trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0);
- if (trace_addr == 0)
- break;
- trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(trace_addr)));
- }
- return trace;
-}
+CreateStackTrace(ValueObjectSP o,
+ const std::string &trace_item_name = ".trace") {
+ StructuredData::Array *trace = new StructuredData::Array();
+ ValueObjectSP trace_value_object =
+ o->GetValueForExpressionPath(trace_item_name.c_str());
+ for (int j = 0; j < 8; j++) {
+ addr_t trace_addr =
+ trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0);
+ if (trace_addr == 0)
+ break;
+ trace->AddItem(
+ StructuredData::ObjectSP(new StructuredData::Integer(trace_addr)));
+ }
+ return trace;
+}
+
+static StructuredData::Array *ConvertToStructuredArray(
+ ValueObjectSP return_value_sp, const std::string &items_name,
+ const std::string &count_name,
+ std::function<void(ValueObjectSP o, StructuredData::Dictionary *dict)> const
+ &callback) {
+ StructuredData::Array *array = new StructuredData::Array();
+ unsigned int count =
+ return_value_sp->GetValueForExpressionPath(count_name.c_str())
+ ->GetValueAsUnsigned(0);
+ ValueObjectSP objects =
+ return_value_sp->GetValueForExpressionPath(items_name.c_str());
+ for (unsigned int i = 0; i < count; i++) {
+ ValueObjectSP o = objects->GetChildAtIndex(i, true);
+ StructuredData::Dictionary *dict = new StructuredData::Dictionary();
-static StructuredData::Array *
-ConvertToStructuredArray(ValueObjectSP return_value_sp, std::string items_name, std::string count_name, std::function <void(ValueObjectSP o, StructuredData::Dictionary *dict)> const &callback)
-{
- StructuredData::Array *array = new StructuredData::Array();
- unsigned int count = return_value_sp->GetValueForExpressionPath(count_name.c_str())->GetValueAsUnsigned(0);
- ValueObjectSP objects = return_value_sp->GetValueForExpressionPath(items_name.c_str());
- for (unsigned int i = 0; i < count; i++) {
- ValueObjectSP o = objects->GetChildAtIndex(i, true);
- StructuredData::Dictionary *dict = new StructuredData::Dictionary();
-
- callback(o, dict);
-
- array->AddItem(StructuredData::ObjectSP(dict));
- }
- return array;
+ callback(o, dict);
+
+ array->AddItem(StructuredData::ObjectSP(dict));
+ }
+ return array;
}
-static std::string
-RetrieveString(ValueObjectSP return_value_sp, ProcessSP process_sp, std::string expression_path)
-{
- addr_t ptr = return_value_sp->GetValueForExpressionPath(expression_path.c_str())->GetValueAsUnsigned(0);
- std::string str;
- Error error;
- process_sp->ReadCStringFromMemory(ptr, str, error);
- return str;
+static std::string RetrieveString(ValueObjectSP return_value_sp,
+ ProcessSP process_sp,
+ const std::string &expression_path) {
+ addr_t ptr =
+ return_value_sp->GetValueForExpressionPath(expression_path.c_str())
+ ->GetValueAsUnsigned(0);
+ std::string str;
+ Error error;
+ process_sp->ReadCStringFromMemory(ptr, str, error);
+ return str;
}
static void
-GetRenumberedThreadIds(ProcessSP process_sp, ValueObjectSP data, std::map<uint64_t, user_id_t> &thread_id_map)
-{
- ConvertToStructuredArray(data, ".threads", ".thread_count", [process_sp, &thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
- uint64_t thread_id = o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0);
- uint64_t thread_os_id = o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0);
+GetRenumberedThreadIds(ProcessSP process_sp, ValueObjectSP data,
+ std::map<uint64_t, user_id_t> &thread_id_map) {
+ ConvertToStructuredArray(
+ data, ".threads", ".thread_count",
+ [process_sp, &thread_id_map](ValueObjectSP o,
+ StructuredData::Dictionary *dict) {
+ uint64_t thread_id =
+ o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0);
+ uint64_t thread_os_id =
+ o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0);
user_id_t lldb_user_id = 0;
-
+
bool can_update = true;
- ThreadSP lldb_thread = process_sp->GetThreadList().FindThreadByID(thread_os_id, can_update);
+ ThreadSP lldb_thread = process_sp->GetThreadList().FindThreadByID(
+ thread_os_id, can_update);
if (lldb_thread) {
- lldb_user_id = lldb_thread->GetIndexID();
+ lldb_user_id = lldb_thread->GetIndexID();
} else {
- // This isn't a live thread anymore. Ask process to assign a new Index ID (or return an old one if we've already seen this thread_os_id).
- // It will also make sure that no new threads are assigned this Index ID.
- lldb_user_id = process_sp->AssignIndexIDToThread(thread_os_id);
+ // This isn't a live thread anymore. Ask process to assign a new
+ // Index ID (or return an old one if we've already seen this
+ // thread_os_id).
+ // It will also make sure that no new threads are assigned this Index
+ // ID.
+ lldb_user_id = process_sp->AssignIndexIDToThread(thread_os_id);
}
-
+
thread_id_map[thread_id] = lldb_user_id;
- });
+ });
}
-static user_id_t Renumber(uint64_t id, std::map<uint64_t, user_id_t> &thread_id_map) {
- if (! thread_id_map.count(id))
- return 0;
-
- return thread_id_map[id];
+static user_id_t Renumber(uint64_t id,
+ std::map<uint64_t, user_id_t> &thread_id_map) {
+ auto IT = thread_id_map.find(id);
+ if (IT == thread_id_map.end())
+ return 0;
+
+ return IT->second;
}
StructuredData::ObjectSP
-ThreadSanitizerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref)
-{
- ProcessSP process_sp = GetProcessSP();
- if (!process_sp)
- return StructuredData::ObjectSP();
-
- ThreadSP thread_sp = exe_ctx_ref.GetThreadSP();
- StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
-
- if (!frame_sp)
- return StructuredData::ObjectSP();
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(true);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeoutUsec(RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC);
- options.SetPrefix(thread_sanitizer_retrieve_report_data_prefix);
- options.SetAutoApplyFixIts(false);
- options.SetLanguage(eLanguageTypeObjC_plus_plus);
-
- ValueObjectSP main_value;
- ExecutionContext exe_ctx;
- Error eval_error;
- frame_sp->CalculateExecutionContext(exe_ctx);
- ExpressionResults result = UserExpression::Evaluate (exe_ctx,
- options,
- thread_sanitizer_retrieve_report_data_command,
- "",
- main_value,
- eval_error);
- if (result != eExpressionCompleted) {
- process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: Cannot evaluate ThreadSanitizer expression:\n%s\n", eval_error.AsCString());
- return StructuredData::ObjectSP();
- }
-
- std::map<uint64_t, user_id_t> thread_id_map;
- GetRenumberedThreadIds(process_sp, main_value, thread_id_map);
-
- StructuredData::Dictionary *dict = new StructuredData::Dictionary();
- dict->AddStringItem("instrumentation_class", "ThreadSanitizer");
- dict->AddStringItem("issue_type", RetrieveString(main_value, process_sp, ".description"));
- dict->AddIntegerItem("report_count", main_value->GetValueForExpressionPath(".report_count")->GetValueAsUnsigned(0));
- dict->AddItem("sleep_trace", StructuredData::ObjectSP(CreateStackTrace(main_value, ".sleep_trace")));
-
- StructuredData::Array *stacks = ConvertToStructuredArray(main_value, ".stacks", ".stack_count", [thread_sp] (ValueObjectSP o, StructuredData::Dictionary *dict) {
- dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ThreadSanitizerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref) {
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return StructuredData::ObjectSP();
+
+ ThreadSP thread_sp = exe_ctx_ref.GetThreadSP();
+ StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
+
+ if (!frame_sp)
+ return StructuredData::ObjectSP();
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(g_retrieve_data_function_timeout);
+ options.SetPrefix(thread_sanitizer_retrieve_report_data_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeObjC_plus_plus);
+
+ ValueObjectSP main_value;
+ ExecutionContext exe_ctx;
+ Error eval_error;
+ frame_sp->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = UserExpression::Evaluate(
+ exe_ctx, options, thread_sanitizer_retrieve_report_data_command, "",
+ main_value, eval_error);
+ if (result != eExpressionCompleted) {
+ process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf(
+ "Warning: Cannot evaluate ThreadSanitizer expression:\n%s\n",
+ eval_error.AsCString());
+ return StructuredData::ObjectSP();
+ }
+
+ std::map<uint64_t, user_id_t> thread_id_map;
+ GetRenumberedThreadIds(process_sp, main_value, thread_id_map);
+
+ StructuredData::Dictionary *dict = new StructuredData::Dictionary();
+ dict->AddStringItem("instrumentation_class", "ThreadSanitizer");
+ dict->AddStringItem("issue_type",
+ RetrieveString(main_value, process_sp, ".description"));
+ dict->AddIntegerItem("report_count",
+ main_value->GetValueForExpressionPath(".report_count")
+ ->GetValueAsUnsigned(0));
+ dict->AddItem("sleep_trace", StructuredData::ObjectSP(CreateStackTrace(
+ main_value, ".sleep_trace")));
+
+ StructuredData::Array *stacks = ConvertToStructuredArray(
+ main_value, ".stacks", ".stack_count",
+ [thread_sp](ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem(
+ "index",
+ o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
// "stacks" happen on the current thread
dict->AddIntegerItem("thread_id", thread_sp->GetIndexID());
- });
- dict->AddItem("stacks", StructuredData::ObjectSP(stacks));
-
- StructuredData::Array *mops = ConvertToStructuredArray(main_value, ".mops", ".mop_count", [&thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
- dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("thread_id", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
- dict->AddIntegerItem("size", o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
- dict->AddBooleanItem("is_write", o->GetValueForExpressionPath(".write")->GetValueAsUnsigned(0));
- dict->AddBooleanItem("is_atomic", o->GetValueForExpressionPath(".atomic")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("address", o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
+ });
+ dict->AddItem("stacks", StructuredData::ObjectSP(stacks));
+
+ StructuredData::Array *mops = ConvertToStructuredArray(
+ main_value, ".mops", ".mop_count",
+ [&thread_id_map](ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem(
+ "index",
+ o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "thread_id",
+ Renumber(
+ o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
+ thread_id_map));
+ dict->AddIntegerItem(
+ "size",
+ o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
+ dict->AddBooleanItem(
+ "is_write",
+ o->GetValueForExpressionPath(".write")->GetValueAsUnsigned(0));
+ dict->AddBooleanItem(
+ "is_atomic",
+ o->GetValueForExpressionPath(".atomic")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "address",
+ o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
- });
- dict->AddItem("mops", StructuredData::ObjectSP(mops));
-
- StructuredData::Array *locs = ConvertToStructuredArray(main_value, ".locs", ".loc_count", [process_sp, &thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
- dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ });
+ dict->AddItem("mops", StructuredData::ObjectSP(mops));
+
+ StructuredData::Array *locs = ConvertToStructuredArray(
+ main_value, ".locs", ".loc_count",
+ [process_sp, &thread_id_map](ValueObjectSP o,
+ StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem(
+ "index",
+ o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
dict->AddStringItem("type", RetrieveString(o, process_sp, ".type"));
- dict->AddIntegerItem("address", o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("start", o->GetValueForExpressionPath(".start")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("size", o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("thread_id", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
- dict->AddIntegerItem("file_descriptor", o->GetValueForExpressionPath(".fd")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("suppressable", o->GetValueForExpressionPath(".suppressable")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "address",
+ o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "start",
+ o->GetValueForExpressionPath(".start")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "size",
+ o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "thread_id",
+ Renumber(
+ o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
+ thread_id_map));
+ dict->AddIntegerItem(
+ "file_descriptor",
+ o->GetValueForExpressionPath(".fd")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem("suppressable",
+ o->GetValueForExpressionPath(".suppressable")
+ ->GetValueAsUnsigned(0));
dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
- });
- dict->AddItem("locs", StructuredData::ObjectSP(locs));
-
- StructuredData::Array *mutexes = ConvertToStructuredArray(main_value, ".mutexes", ".mutex_count", [] (ValueObjectSP o, StructuredData::Dictionary *dict) {
- dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("mutex_id", o->GetValueForExpressionPath(".mutex_id")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("address", o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("destroyed", o->GetValueForExpressionPath(".destroyed")->GetValueAsUnsigned(0));
+ });
+ dict->AddItem("locs", StructuredData::ObjectSP(locs));
+
+ StructuredData::Array *mutexes = ConvertToStructuredArray(
+ main_value, ".mutexes", ".mutex_count",
+ [](ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem(
+ "index",
+ o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "mutex_id",
+ o->GetValueForExpressionPath(".mutex_id")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "address",
+ o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "destroyed",
+ o->GetValueForExpressionPath(".destroyed")->GetValueAsUnsigned(0));
dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
- });
- dict->AddItem("mutexes", StructuredData::ObjectSP(mutexes));
-
- StructuredData::Array *threads = ConvertToStructuredArray(main_value, ".threads", ".thread_count", [process_sp, &thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
- dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("thread_id", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
- dict->AddIntegerItem("thread_os_id", o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("running", o->GetValueForExpressionPath(".running")->GetValueAsUnsigned(0));
+ });
+ dict->AddItem("mutexes", StructuredData::ObjectSP(mutexes));
+
+ StructuredData::Array *threads = ConvertToStructuredArray(
+ main_value, ".threads", ".thread_count",
+ [process_sp, &thread_id_map](ValueObjectSP o,
+ StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem(
+ "index",
+ o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "thread_id",
+ Renumber(
+ o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
+ thread_id_map));
+ dict->AddIntegerItem(
+ "thread_os_id",
+ o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "running",
+ o->GetValueForExpressionPath(".running")->GetValueAsUnsigned(0));
dict->AddStringItem("name", RetrieveString(o, process_sp, ".name"));
- dict->AddIntegerItem("parent_thread_id", Renumber(o->GetValueForExpressionPath(".parent_tid")->GetValueAsUnsigned(0), thread_id_map));
+ dict->AddIntegerItem(
+ "parent_thread_id",
+ Renumber(o->GetValueForExpressionPath(".parent_tid")
+ ->GetValueAsUnsigned(0),
+ thread_id_map));
dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
- });
- dict->AddItem("threads", StructuredData::ObjectSP(threads));
-
- StructuredData::Array *unique_tids = ConvertToStructuredArray(main_value, ".unique_tids", ".unique_tid_count", [&thread_id_map] (ValueObjectSP o, StructuredData::Dictionary *dict) {
- dict->AddIntegerItem("index", o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
- dict->AddIntegerItem("tid", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
- });
- dict->AddItem("unique_tids", StructuredData::ObjectSP(unique_tids));
-
- return StructuredData::ObjectSP(dict);
+ });
+ dict->AddItem("threads", StructuredData::ObjectSP(threads));
+
+ StructuredData::Array *unique_tids = ConvertToStructuredArray(
+ main_value, ".unique_tids", ".unique_tid_count",
+ [&thread_id_map](ValueObjectSP o, StructuredData::Dictionary *dict) {
+ dict->AddIntegerItem(
+ "index",
+ o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
+ dict->AddIntegerItem(
+ "tid",
+ Renumber(
+ o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
+ thread_id_map));
+ });
+ dict->AddItem("unique_tids", StructuredData::ObjectSP(unique_tids));
+
+ return StructuredData::ObjectSP(dict);
}
std::string
-ThreadSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report)
-{
- std::string description = report->GetAsDictionary()->GetValueForKey("issue_type")->GetAsString()->GetValue();
-
- if (description == "data-race") {
- return "Data race";
- } else if (description == "data-race-vptr") {
- return "Data race on C++ virtual pointer";
- } else if (description == "heap-use-after-free") {
- return "Use of deallocated memory";
- } else if (description == "heap-use-after-free-vptr") {
- return "Use of deallocated C++ virtual pointer";
- } else if (description == "thread-leak") {
- return "Thread leak";
- } else if (description == "locked-mutex-destroy") {
- return "Destruction of a locked mutex";
- } else if (description == "mutex-double-lock") {
- return "Double lock of a mutex";
- } else if (description == "mutex-invalid-access") {
- return "Use of an uninitialized or destroyed mutex";
- } else if (description == "mutex-bad-unlock") {
- return "Unlock of an unlocked mutex (or by a wrong thread)";
- } else if (description == "mutex-bad-read-lock") {
- return "Read lock of a write locked mutex";
- } else if (description == "mutex-bad-read-unlock") {
- return "Read unlock of a write locked mutex";
- } else if (description == "signal-unsafe-call") {
- return "Signal-unsafe call inside a signal handler";
- } else if (description == "errno-in-signal-handler") {
- return "Overwrite of errno in a signal handler";
- } else if (description == "lock-order-inversion") {
- return "Lock order inversion (potential deadlock)";
- }
-
- // for unknown report codes just show the code
- return description;
-}
-
-static std::string
-Sprintf(const char *format, ...)
-{
- StreamString s;
- va_list args;
- va_start (args, format);
- s.PrintfVarArg(format, args);
- va_end (args);
- return s.GetString();
-}
-
-static std::string
-GetSymbolNameFromAddress(ProcessSP process_sp, addr_t addr)
-{
+ThreadSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report) {
+ std::string description = report->GetAsDictionary()
+ ->GetValueForKey("issue_type")
+ ->GetAsString()
+ ->GetValue();
+
+ if (description == "data-race") {
+ return "Data race";
+ } else if (description == "data-race-vptr") {
+ return "Data race on C++ virtual pointer";
+ } else if (description == "heap-use-after-free") {
+ return "Use of deallocated memory";
+ } else if (description == "heap-use-after-free-vptr") {
+ return "Use of deallocated C++ virtual pointer";
+ } else if (description == "thread-leak") {
+ return "Thread leak";
+ } else if (description == "locked-mutex-destroy") {
+ return "Destruction of a locked mutex";
+ } else if (description == "mutex-double-lock") {
+ return "Double lock of a mutex";
+ } else if (description == "mutex-invalid-access") {
+ return "Use of an uninitialized or destroyed mutex";
+ } else if (description == "mutex-bad-unlock") {
+ return "Unlock of an unlocked mutex (or by a wrong thread)";
+ } else if (description == "mutex-bad-read-lock") {
+ return "Read lock of a write locked mutex";
+ } else if (description == "mutex-bad-read-unlock") {
+ return "Read unlock of a write locked mutex";
+ } else if (description == "signal-unsafe-call") {
+ return "Signal-unsafe call inside a signal handler";
+ } else if (description == "errno-in-signal-handler") {
+ return "Overwrite of errno in a signal handler";
+ } else if (description == "lock-order-inversion") {
+ return "Lock order inversion (potential deadlock)";
+ }
+
+ // for unknown report codes just show the code
+ return description;
+}
+
+static std::string Sprintf(const char *format, ...) {
+ StreamString s;
+ va_list args;
+ va_start(args, format);
+ s.PrintfVarArg(format, args);
+ va_end(args);
+ return s.GetString();
+}
+
+static std::string GetSymbolNameFromAddress(ProcessSP process_sp, addr_t addr) {
+ lldb_private::Address so_addr;
+ if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr,
+ so_addr))
+ return "";
+
+ lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
+ if (!symbol)
+ return "";
+
+ std::string sym_name = symbol->GetName().GetCString();
+ return sym_name;
+}
+
+static void GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr,
+ Declaration &decl) {
+ lldb_private::Address so_addr;
+ if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr,
+ so_addr))
+ return;
+
+ lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
+ if (!symbol)
+ return;
+
+ ConstString sym_name = symbol->GetMangled().GetName(
+ lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
+
+ ModuleSP module = symbol->CalculateSymbolContextModule();
+ if (!module)
+ return;
+
+ VariableList var_list;
+ module->FindGlobalVariables(sym_name, nullptr, true, 1U, var_list);
+ if (var_list.GetSize() < 1)
+ return;
+
+ VariableSP var = var_list.GetVariableAtIndex(0);
+ decl = var->GetDeclaration();
+}
+
+addr_t ThreadSanitizerRuntime::GetFirstNonInternalFramePc(
+ StructuredData::ObjectSP trace) {
+ ProcessSP process_sp = GetProcessSP();
+ ModuleSP runtime_module_sp = GetRuntimeModuleSP();
+
+ addr_t result = 0;
+ trace->GetAsArray()->ForEach([process_sp, runtime_module_sp,
+ &result](StructuredData::Object *o) -> bool {
+ addr_t addr = o->GetIntegerValue();
lldb_private::Address so_addr;
- if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
- return "";
-
- lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
- if (! symbol)
- return "";
-
- std::string sym_name = symbol->GetName().GetCString();
- return sym_name;
-}
+ if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(
+ addr, so_addr))
+ return true;
-static void
-GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr, Declaration &decl)
-{
- lldb_private::Address so_addr;
- if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
- return;
-
- lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
- if (! symbol)
- return;
-
- ConstString sym_name = symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
-
- ModuleSP module = symbol->CalculateSymbolContextModule();
- if (! module)
- return;
-
- VariableList var_list;
- module->FindGlobalVariables(sym_name, nullptr, true, 1U, var_list);
- if (var_list.GetSize() < 1)
- return;
-
- VariableSP var = var_list.GetVariableAtIndex(0);
- decl = var->GetDeclaration();
-}
+ if (so_addr.GetModule() == runtime_module_sp)
+ return true;
-addr_t
-ThreadSanitizerRuntime::GetFirstNonInternalFramePc(StructuredData::ObjectSP trace)
-{
- ProcessSP process_sp = GetProcessSP();
- ModuleSP runtime_module_sp = GetRuntimeModuleSP();
-
- addr_t result = 0;
- trace->GetAsArray()->ForEach([process_sp, runtime_module_sp, &result] (StructuredData::Object *o) -> bool {
- addr_t addr = o->GetIntegerValue();
- lldb_private::Address so_addr;
- if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
- return true;
-
- if (so_addr.GetModule() == runtime_module_sp)
- return true;
-
- result = addr;
- return false;
- });
-
- return result;
+ result = addr;
+ return false;
+ });
+
+ return result;
}
std::string
-ThreadSanitizerRuntime::GenerateSummary(StructuredData::ObjectSP report)
-{
- ProcessSP process_sp = GetProcessSP();
-
- std::string summary = report->GetAsDictionary()->GetValueForKey("description")->GetAsString()->GetValue();
- addr_t pc = 0;
- if (report->GetAsDictionary()->GetValueForKey("mops")->GetAsArray()->GetSize() > 0)
- pc = GetFirstNonInternalFramePc(report->GetAsDictionary()->GetValueForKey("mops")->GetAsArray()->GetItemAtIndex(0)->GetAsDictionary()->GetValueForKey("trace"));
-
- if (report->GetAsDictionary()->GetValueForKey("stacks")->GetAsArray()->GetSize() > 0)
- pc = GetFirstNonInternalFramePc(report->GetAsDictionary()->GetValueForKey("stacks")->GetAsArray()->GetItemAtIndex(0)->GetAsDictionary()->GetValueForKey("trace"));
-
- if (pc != 0) {
- summary = summary + " in " + GetSymbolNameFromAddress(process_sp, pc);
+ThreadSanitizerRuntime::GenerateSummary(StructuredData::ObjectSP report) {
+ ProcessSP process_sp = GetProcessSP();
+
+ std::string summary = report->GetAsDictionary()
+ ->GetValueForKey("description")
+ ->GetAsString()
+ ->GetValue();
+ addr_t pc = 0;
+ if (report->GetAsDictionary()
+ ->GetValueForKey("mops")
+ ->GetAsArray()
+ ->GetSize() > 0)
+ pc = GetFirstNonInternalFramePc(report->GetAsDictionary()
+ ->GetValueForKey("mops")
+ ->GetAsArray()
+ ->GetItemAtIndex(0)
+ ->GetAsDictionary()
+ ->GetValueForKey("trace"));
+
+ if (report->GetAsDictionary()
+ ->GetValueForKey("stacks")
+ ->GetAsArray()
+ ->GetSize() > 0)
+ pc = GetFirstNonInternalFramePc(report->GetAsDictionary()
+ ->GetValueForKey("stacks")
+ ->GetAsArray()
+ ->GetItemAtIndex(0)
+ ->GetAsDictionary()
+ ->GetValueForKey("trace"));
+
+ if (pc != 0) {
+ summary = summary + " in " + GetSymbolNameFromAddress(process_sp, pc);
+ }
+
+ if (report->GetAsDictionary()
+ ->GetValueForKey("locs")
+ ->GetAsArray()
+ ->GetSize() > 0) {
+ StructuredData::ObjectSP loc = report->GetAsDictionary()
+ ->GetValueForKey("locs")
+ ->GetAsArray()
+ ->GetItemAtIndex(0);
+ addr_t addr = loc->GetAsDictionary()
+ ->GetValueForKey("address")
+ ->GetAsInteger()
+ ->GetValue();
+ if (addr == 0)
+ addr = loc->GetAsDictionary()
+ ->GetValueForKey("start")
+ ->GetAsInteger()
+ ->GetValue();
+
+ if (addr != 0) {
+ std::string global_name = GetSymbolNameFromAddress(process_sp, addr);
+ if (!global_name.empty()) {
+ summary = summary + " at " + global_name;
+ } else {
+ summary = summary + " at " + Sprintf("0x%llx", addr);
+ }
+ } else {
+ int fd = loc->GetAsDictionary()
+ ->GetValueForKey("file_descriptor")
+ ->GetAsInteger()
+ ->GetValue();
+ if (fd != 0) {
+ summary = summary + " on file descriptor " + Sprintf("%d", fd);
+ }
}
-
- if (report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetSize() > 0) {
- StructuredData::ObjectSP loc = report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetItemAtIndex(0);
- addr_t addr = loc->GetAsDictionary()->GetValueForKey("address")->GetAsInteger()->GetValue();
- if (addr == 0)
- addr = loc->GetAsDictionary()->GetValueForKey("start")->GetAsInteger()->GetValue();
-
- if (addr != 0) {
- std::string global_name = GetSymbolNameFromAddress(process_sp, addr);
- if (!global_name.empty()) {
- summary = summary + " at " + global_name;
- } else {
- summary = summary + " at " + Sprintf("0x%llx", addr);
- }
- } else {
- int fd = loc->GetAsDictionary()->GetValueForKey("file_descriptor")->GetAsInteger()->GetValue();
- if (fd != 0) {
- summary = summary + " on file descriptor " + Sprintf("%d", fd);
- }
- }
- }
-
- return summary;
+ }
+
+ return summary;
}
addr_t
-ThreadSanitizerRuntime::GetMainRacyAddress(StructuredData::ObjectSP report)
-{
- addr_t result = (addr_t)-1;
-
- report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach([&result] (StructuredData::Object *o) -> bool {
- addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
- if (addr < result) result = addr;
+ThreadSanitizerRuntime::GetMainRacyAddress(StructuredData::ObjectSP report) {
+ addr_t result = (addr_t)-1;
+
+ report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
+ [&result](StructuredData::Object *o) -> bool {
+ addr_t addr =
+ o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+ if (addr < result)
+ result = addr;
return true;
- });
-
- return (result == (addr_t)-1) ? 0 : result;
-}
-
-std::string
-ThreadSanitizerRuntime::GetLocationDescription(StructuredData::ObjectSP report, addr_t &global_addr, std::string &global_name, std::string &filename, uint32_t &line)
-{
- std::string result = "";
-
- ProcessSP process_sp = GetProcessSP();
-
- if (report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetSize() > 0) {
- StructuredData::ObjectSP loc = report->GetAsDictionary()->GetValueForKey("locs")->GetAsArray()->GetItemAtIndex(0);
- std::string type = loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
- if (type == "global") {
- global_addr = loc->GetAsDictionary()->GetValueForKey("address")->GetAsInteger()->GetValue();
- global_name = GetSymbolNameFromAddress(process_sp, global_addr);
- if (!global_name.empty()) {
- result = Sprintf("'%s' is a global variable (0x%llx)", global_name.c_str(), global_addr);
- } else {
- result = Sprintf("0x%llx is a global variable", global_addr);
- }
-
- Declaration decl;
- GetSymbolDeclarationFromAddress(process_sp, global_addr, decl);
- if (decl.GetFile()) {
- filename = decl.GetFile().GetPath();
- line = decl.GetLine();
- }
- } else if (type == "heap") {
- addr_t addr = loc->GetAsDictionary()->GetValueForKey("start")->GetAsInteger()->GetValue();
- long size = loc->GetAsDictionary()->GetValueForKey("size")->GetAsInteger()->GetValue();
- result = Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr);
- } else if (type == "stack") {
- int tid = loc->GetAsDictionary()->GetValueForKey("thread_id")->GetAsInteger()->GetValue();
- result = Sprintf("Location is stack of thread %d", tid);
- } else if (type == "tls") {
- int tid = loc->GetAsDictionary()->GetValueForKey("thread_id")->GetAsInteger()->GetValue();
- result = Sprintf("Location is TLS of thread %d", tid);
- } else if (type == "fd") {
- int fd = loc->GetAsDictionary()->GetValueForKey("file_descriptor")->GetAsInteger()->GetValue();
- result = Sprintf("Location is file descriptor %d", fd);
- }
+ });
+
+ return (result == (addr_t)-1) ? 0 : result;
+}
+
+std::string ThreadSanitizerRuntime::GetLocationDescription(
+ StructuredData::ObjectSP report, addr_t &global_addr,
+ std::string &global_name, std::string &filename, uint32_t &line) {
+ std::string result = "";
+
+ ProcessSP process_sp = GetProcessSP();
+
+ if (report->GetAsDictionary()
+ ->GetValueForKey("locs")
+ ->GetAsArray()
+ ->GetSize() > 0) {
+ StructuredData::ObjectSP loc = report->GetAsDictionary()
+ ->GetValueForKey("locs")
+ ->GetAsArray()
+ ->GetItemAtIndex(0);
+ std::string type =
+ loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
+ if (type == "global") {
+ global_addr = loc->GetAsDictionary()
+ ->GetValueForKey("address")
+ ->GetAsInteger()
+ ->GetValue();
+ global_name = GetSymbolNameFromAddress(process_sp, global_addr);
+ if (!global_name.empty()) {
+ result = Sprintf("'%s' is a global variable (0x%llx)",
+ global_name.c_str(), global_addr);
+ } else {
+ result = Sprintf("0x%llx is a global variable", global_addr);
+ }
+
+ Declaration decl;
+ GetSymbolDeclarationFromAddress(process_sp, global_addr, decl);
+ if (decl.GetFile()) {
+ filename = decl.GetFile().GetPath();
+ line = decl.GetLine();
+ }
+ } else if (type == "heap") {
+ addr_t addr = loc->GetAsDictionary()
+ ->GetValueForKey("start")
+ ->GetAsInteger()
+ ->GetValue();
+ long size = loc->GetAsDictionary()
+ ->GetValueForKey("size")
+ ->GetAsInteger()
+ ->GetValue();
+ result =
+ Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr);
+ } else if (type == "stack") {
+ int tid = loc->GetAsDictionary()
+ ->GetValueForKey("thread_id")
+ ->GetAsInteger()
+ ->GetValue();
+ result = Sprintf("Location is stack of thread %d", tid);
+ } else if (type == "tls") {
+ int tid = loc->GetAsDictionary()
+ ->GetValueForKey("thread_id")
+ ->GetAsInteger()
+ ->GetValue();
+ result = Sprintf("Location is TLS of thread %d", tid);
+ } else if (type == "fd") {
+ int fd = loc->GetAsDictionary()
+ ->GetValueForKey("file_descriptor")
+ ->GetAsInteger()
+ ->GetValue();
+ result = Sprintf("Location is file descriptor %d", fd);
+ }
+ }
+
+ return result;
+}
+
+bool ThreadSanitizerRuntime::NotifyBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(baton && "null baton");
+ if (!baton)
+ return false;
+
+ ThreadSanitizerRuntime *const instance =
+ static_cast<ThreadSanitizerRuntime *>(baton);
+
+ StructuredData::ObjectSP report =
+ instance->RetrieveReportData(context->exe_ctx_ref);
+ std::string stop_reason_description;
+ if (report) {
+ std::string issue_description = instance->FormatDescription(report);
+ report->GetAsDictionary()->AddStringItem("description", issue_description);
+ stop_reason_description = issue_description + " detected";
+ report->GetAsDictionary()->AddStringItem("stop_description",
+ stop_reason_description);
+ std::string summary = instance->GenerateSummary(report);
+ report->GetAsDictionary()->AddStringItem("summary", summary);
+ addr_t main_address = instance->GetMainRacyAddress(report);
+ report->GetAsDictionary()->AddIntegerItem("memory_address", main_address);
+
+ addr_t global_addr = 0;
+ std::string global_name = "";
+ std::string location_filename = "";
+ uint32_t location_line = 0;
+ std::string location_description = instance->GetLocationDescription(
+ report, global_addr, global_name, location_filename, location_line);
+ report->GetAsDictionary()->AddStringItem("location_description",
+ location_description);
+ if (global_addr != 0) {
+ report->GetAsDictionary()->AddIntegerItem("global_address", global_addr);
+ }
+ if (!global_name.empty()) {
+ report->GetAsDictionary()->AddStringItem("global_name", global_name);
+ }
+ if (location_filename != "") {
+ report->GetAsDictionary()->AddStringItem("location_filename",
+ location_filename);
+ report->GetAsDictionary()->AddIntegerItem("location_line", location_line);
}
-
- return result;
-}
-bool
-ThreadSanitizerRuntime::NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id)
-{
- assert (baton && "null baton");
- if (!baton)
- return false;
-
- ThreadSanitizerRuntime *const instance = static_cast<ThreadSanitizerRuntime*>(baton);
-
- StructuredData::ObjectSP report = instance->RetrieveReportData(context->exe_ctx_ref);
- std::string stop_reason_description;
- if (report) {
- std::string issue_description = instance->FormatDescription(report);
- report->GetAsDictionary()->AddStringItem("description", issue_description);
- stop_reason_description = issue_description + " detected";
- report->GetAsDictionary()->AddStringItem("stop_description", stop_reason_description);
- std::string summary = instance->GenerateSummary(report);
- report->GetAsDictionary()->AddStringItem("summary", summary);
- addr_t main_address = instance->GetMainRacyAddress(report);
- report->GetAsDictionary()->AddIntegerItem("memory_address", main_address);
-
- addr_t global_addr = 0;
- std::string global_name = "";
- std::string location_filename = "";
- uint32_t location_line = 0;
- std::string location_description = instance->GetLocationDescription(report, global_addr, global_name, location_filename, location_line);
- report->GetAsDictionary()->AddStringItem("location_description", location_description);
- if (global_addr != 0) {
- report->GetAsDictionary()->AddIntegerItem("global_address", global_addr);
- }
- if (!global_name.empty()) {
- report->GetAsDictionary()->AddStringItem("global_name", global_name);
- }
- if (location_filename != "") {
- report->GetAsDictionary()->AddStringItem("location_filename", location_filename);
- report->GetAsDictionary()->AddIntegerItem("location_line", location_line);
- }
-
- bool all_addresses_are_same = true;
- report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach([&all_addresses_are_same, main_address] (StructuredData::Object *o) -> bool {
- addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
- if (main_address != addr) all_addresses_are_same = false;
- return true;
+ bool all_addresses_are_same = true;
+ report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
+ [&all_addresses_are_same,
+ main_address](StructuredData::Object *o) -> bool {
+ addr_t addr =
+ o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+ if (main_address != addr)
+ all_addresses_are_same = false;
+ return true;
});
- report->GetAsDictionary()->AddBooleanItem("all_addresses_are_same", all_addresses_are_same);
- }
-
- ProcessSP process_sp = instance->GetProcessSP();
- // Make sure this is the right process
- if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP())
- {
- ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
- if (thread_sp)
- thread_sp->SetStopInfo(InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(*thread_sp, stop_reason_description.c_str(), report));
-
- StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
- if (stream_sp)
- {
- stream_sp->Printf ("ThreadSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.\n");
- }
- return true; // Return true to stop the target
+ report->GetAsDictionary()->AddBooleanItem("all_addresses_are_same",
+ all_addresses_are_same);
+ }
+
+ ProcessSP process_sp = instance->GetProcessSP();
+ // Make sure this is the right process
+ if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
+ ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
+ if (thread_sp)
+ thread_sp->SetStopInfo(
+ InstrumentationRuntimeStopInfo::
+ CreateStopReasonWithInstrumentationData(
+ *thread_sp, stop_reason_description, report));
+
+ StreamFileSP stream_sp(
+ process_sp->GetTarget().GetDebugger().GetOutputFile());
+ if (stream_sp) {
+ stream_sp->Printf("ThreadSanitizer report breakpoint hit. Use 'thread "
+ "info -s' to get extended information about the "
+ "report.\n");
}
- else
- return false; // Let target run
+ return true; // Return true to stop the target
+ } else
+ return false; // Let target run
}
-void
-ThreadSanitizerRuntime::Activate()
-{
- if (m_is_active)
- return;
-
- ProcessSP process_sp = GetProcessSP();
- if (!process_sp)
- return;
-
- ConstString symbol_name ("__tsan_on_report");
- const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType (symbol_name, eSymbolTypeCode);
-
- if (symbol == NULL)
- return;
-
- if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
- return;
-
- Target &target = process_sp->GetTarget();
- addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
-
- if (symbol_address == LLDB_INVALID_ADDRESS)
- return;
-
- bool internal = true;
- bool hardware = false;
- Breakpoint *breakpoint = process_sp->GetTarget().CreateBreakpoint(symbol_address, internal, hardware).get();
- breakpoint->SetCallback (ThreadSanitizerRuntime::NotifyBreakpointHit, this, true);
- breakpoint->SetBreakpointKind ("thread-sanitizer-report");
- m_breakpoint_id = breakpoint->GetID();
-
- StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
- if (stream_sp)
- {
- stream_sp->Printf ("ThreadSanitizer debugger support is active.\n");
- }
-
- m_is_active = true;
+const RegularExpression &ThreadSanitizerRuntime::GetPatternForRuntimeLibrary() {
+ static RegularExpression regex(llvm::StringRef("libclang_rt.tsan_"));
+ return regex;
}
-void
-ThreadSanitizerRuntime::Deactivate()
-{
- if (m_breakpoint_id != LLDB_INVALID_BREAK_ID)
- {
- ProcessSP process_sp = GetProcessSP();
- if (process_sp)
- {
- process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
- m_breakpoint_id = LLDB_INVALID_BREAK_ID;
- }
- }
- m_is_active = false;
+bool ThreadSanitizerRuntime::CheckIfRuntimeIsValid(
+ const lldb::ModuleSP module_sp) {
+ static ConstString g_tsan_get_current_report("__tsan_get_current_report");
+ const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
+ g_tsan_get_current_report, lldb::eSymbolTypeAny);
+ return symbol != nullptr;
}
-static std::string
-GenerateThreadName(std::string path, StructuredData::Object *o, StructuredData::ObjectSP main_info) {
- std::string result = "additional information";
-
- if (path == "mops") {
- int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue();
- int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
- bool is_write = o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue();
- bool is_atomic = o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue();
- addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
-
- std::string addr_string = Sprintf(" at 0x%llx", addr);
-
- if (main_info->GetObjectForDotSeparatedPath("all_addresses_are_same")->GetBooleanValue()){
- addr_string = "";
- }
-
- result = Sprintf("%s%s of size %d%s by thread %d", is_atomic ? "atomic " : "", is_write ? "write" : "read", size, addr_string.c_str(), thread_id);
- }
-
- if (path == "threads") {
- int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
- result = Sprintf("Thread %d created", thread_id);
- }
-
- if (path == "locs") {
- std::string type = o->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
- int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
- int fd = o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue();
- if (type == "heap") {
- result = Sprintf("Heap block allocated by thread %d", thread_id);
- } else if (type == "fd") {
- result = Sprintf("File descriptor %d created by thread %t", fd, thread_id);
- }
+void ThreadSanitizerRuntime::Activate() {
+ if (IsActive())
+ return;
+
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return;
+
+ ConstString symbol_name("__tsan_on_report");
+ const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType(
+ symbol_name, eSymbolTypeCode);
+
+ if (symbol == NULL)
+ return;
+
+ if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
+ return;
+
+ Target &target = process_sp->GetTarget();
+ addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
+
+ if (symbol_address == LLDB_INVALID_ADDRESS)
+ return;
+
+ bool internal = true;
+ bool hardware = false;
+ Breakpoint *breakpoint =
+ process_sp->GetTarget()
+ .CreateBreakpoint(symbol_address, internal, hardware)
+ .get();
+ breakpoint->SetCallback(ThreadSanitizerRuntime::NotifyBreakpointHit, this,
+ true);
+ breakpoint->SetBreakpointKind("thread-sanitizer-report");
+ SetBreakpointID(breakpoint->GetID());
+
+ StreamFileSP stream_sp(process_sp->GetTarget().GetDebugger().GetOutputFile());
+ if (stream_sp) {
+ stream_sp->Printf("ThreadSanitizer debugger support is active.\n");
+ }
+
+ SetActive(true);
+}
+
+void ThreadSanitizerRuntime::Deactivate() {
+ if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ ProcessSP process_sp = GetProcessSP();
+ if (process_sp) {
+ process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
+ SetBreakpointID(LLDB_INVALID_BREAK_ID);
}
-
- if (path == "mutexes") {
- int mutex_id = o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue();
-
- result = Sprintf("Mutex M%d created", mutex_id);
+ }
+ SetActive(false);
+}
+static std::string GenerateThreadName(const std::string &path,
+ StructuredData::Object *o,
+ StructuredData::ObjectSP main_info) {
+ std::string result = "additional information";
+
+ if (path == "mops") {
+ int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue();
+ int thread_id =
+ o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ bool is_write =
+ o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue();
+ bool is_atomic =
+ o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue();
+ addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
+
+ std::string addr_string = Sprintf(" at 0x%llx", addr);
+
+ if (main_info->GetObjectForDotSeparatedPath("all_addresses_are_same")
+ ->GetBooleanValue()) {
+ addr_string = "";
}
-
- if (path == "stacks") {
- int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
- result = Sprintf("Thread %d", thread_id);
+
+ result = Sprintf("%s%s of size %d%s by thread %d",
+ is_atomic ? "atomic " : "", is_write ? "write" : "read",
+ size, addr_string.c_str(), thread_id);
+ }
+
+ if (path == "threads") {
+ int thread_id =
+ o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ result = Sprintf("Thread %d created", thread_id);
+ }
+
+ if (path == "locs") {
+ std::string type =
+ o->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
+ int thread_id =
+ o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ int fd =
+ o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue();
+ if (type == "heap") {
+ result = Sprintf("Heap block allocated by thread %d", thread_id);
+ } else if (type == "fd") {
+ result =
+ Sprintf("File descriptor %d created by thread %t", fd, thread_id);
}
-
- result[0] = toupper(result[0]);
-
- return result;
+ }
+
+ if (path == "mutexes") {
+ int mutex_id =
+ o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue();
+
+ result = Sprintf("Mutex M%d created", mutex_id);
+ }
+
+ if (path == "stacks") {
+ int thread_id =
+ o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ result = Sprintf("Thread %d", thread_id);
+ }
+
+ result[0] = toupper(result[0]);
+
+ return result;
}
-static void
-AddThreadsForPath(std::string path, ThreadCollectionSP threads, ProcessSP process_sp, StructuredData::ObjectSP info)
-{
- info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach([process_sp, threads, path, info] (StructuredData::Object *o) -> bool {
+static void AddThreadsForPath(const std::string &path,
+ ThreadCollectionSP threads, ProcessSP process_sp,
+ StructuredData::ObjectSP info) {
+ info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach(
+ [process_sp, threads, path, info](StructuredData::Object *o) -> bool {
std::vector<lldb::addr_t> pcs;
- o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach([&pcs] (StructuredData::Object *pc) -> bool {
- pcs.push_back(pc->GetAsInteger()->GetValue());
- return true;
- });
-
+ o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach(
+ [&pcs](StructuredData::Object *pc) -> bool {
+ pcs.push_back(pc->GetAsInteger()->GetValue());
+ return true;
+ });
+
if (pcs.size() == 0)
- return true;
-
- StructuredData::ObjectSP thread_id_obj = o->GetObjectForDotSeparatedPath("thread_os_id");
+ return true;
+
+ StructuredData::ObjectSP thread_id_obj =
+ o->GetObjectForDotSeparatedPath("thread_os_id");
tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
-
+
uint32_t stop_id = 0;
bool stop_id_is_valid = false;
- HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, stop_id, stop_id_is_valid);
+ HistoryThread *history_thread =
+ new HistoryThread(*process_sp, tid, pcs, stop_id, stop_id_is_valid);
ThreadSP new_thread_sp(history_thread);
new_thread_sp->SetName(GenerateThreadName(path, o, info).c_str());
-
- // Save this in the Process' ExtendedThreadList so a strong pointer retains the object
+
+ // Save this in the Process' ExtendedThreadList so a strong pointer
+ // retains the object
process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
threads->AddThread(new_thread_sp);
-
+
return true;
- });
+ });
}
lldb::ThreadCollectionSP
-ThreadSanitizerRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info)
-{
- ThreadCollectionSP threads;
- threads.reset(new ThreadCollection());
+ThreadSanitizerRuntime::GetBacktracesFromExtendedStopInfo(
+ StructuredData::ObjectSP info) {
+ ThreadCollectionSP threads;
+ threads.reset(new ThreadCollection());
- if (info->GetObjectForDotSeparatedPath("instrumentation_class")->GetStringValue() != "ThreadSanitizer")
- return threads;
-
- ProcessSP process_sp = GetProcessSP();
-
- AddThreadsForPath("stacks", threads, process_sp, info);
- AddThreadsForPath("mops", threads, process_sp, info);
- AddThreadsForPath("locs", threads, process_sp, info);
- AddThreadsForPath("mutexes", threads, process_sp, info);
- AddThreadsForPath("threads", threads, process_sp, info);
-
+ if (info->GetObjectForDotSeparatedPath("instrumentation_class")
+ ->GetStringValue() != "ThreadSanitizer")
return threads;
+
+ ProcessSP process_sp = GetProcessSP();
+
+ AddThreadsForPath("stacks", threads, process_sp, info);
+ AddThreadsForPath("mops", threads, process_sp, info);
+ AddThreadsForPath("locs", threads, process_sp, info);
+ AddThreadsForPath("mutexes", threads, process_sp, info);
+ AddThreadsForPath("threads", threads, process_sp, info);
+
+ return threads;
}
diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h
index ca7af23aa3bd..9b07ca64e32b 100644
--- a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h
+++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h
@@ -14,106 +14,72 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/InstrumentationRuntime.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Core/StructuredData.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class ThreadSanitizerRuntime : public lldb_private::InstrumentationRuntime
-{
+
+class ThreadSanitizerRuntime : public lldb_private::InstrumentationRuntime {
public:
- ~ThreadSanitizerRuntime() override;
-
- static lldb::InstrumentationRuntimeSP
- CreateInstance (const lldb::ProcessSP &process_sp);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static lldb::InstrumentationRuntimeType
- GetTypeStatic();
-
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- virtual lldb::InstrumentationRuntimeType
- GetType() { return GetTypeStatic(); }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- void
- ModulesDidLoad(lldb_private::ModuleList &module_list) override;
-
- bool
- IsActive() override;
-
- lldb::ThreadCollectionSP
- GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
-
+ ~ThreadSanitizerRuntime() override;
+
+ static lldb::InstrumentationRuntimeSP
+ CreateInstance(const lldb::ProcessSP &process_sp);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static lldb::InstrumentationRuntimeType GetTypeStatic();
+
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ lldb::ThreadCollectionSP
+ GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
+
private:
- ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp);
-
- lldb::ProcessSP
- GetProcessSP ()
- {
- return m_process_wp.lock();
- }
-
- lldb::ModuleSP
- GetRuntimeModuleSP ()
- {
- return m_runtime_module_wp.lock();
- }
-
- void
- Activate();
-
- void
- Deactivate();
-
- static bool
- NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
- StructuredData::ObjectSP
- RetrieveReportData(ExecutionContextRef exe_ctx_ref);
-
- std::string
- FormatDescription(StructuredData::ObjectSP report);
-
- std::string
- GenerateSummary(StructuredData::ObjectSP report);
-
- lldb::addr_t
- GetMainRacyAddress(StructuredData::ObjectSP report);
-
- std::string
- GetLocationDescription(StructuredData::ObjectSP report, lldb::addr_t &global_addr, std::string &global_name, std::string &filename, uint32_t &line);
-
- lldb::addr_t
- GetFirstNonInternalFramePc(StructuredData::ObjectSP trace);
-
- bool m_is_active;
- lldb::ModuleWP m_runtime_module_wp;
- lldb::ProcessWP m_process_wp;
- lldb::user_id_t m_breakpoint_id;
+ ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp)
+ : lldb_private::InstrumentationRuntime(process_sp) {}
+
+ const RegularExpression &GetPatternForRuntimeLibrary() override;
+
+ bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override;
+
+ void Activate() override;
+
+ void Deactivate();
+
+ static bool NotifyBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ StructuredData::ObjectSP RetrieveReportData(ExecutionContextRef exe_ctx_ref);
+
+ std::string FormatDescription(StructuredData::ObjectSP report);
+
+ std::string GenerateSummary(StructuredData::ObjectSP report);
+
+ lldb::addr_t GetMainRacyAddress(StructuredData::ObjectSP report);
+
+ std::string GetLocationDescription(StructuredData::ObjectSP report,
+ lldb::addr_t &global_addr,
+ std::string &global_name,
+ std::string &filename, uint32_t &line);
+
+ lldb::addr_t GetFirstNonInternalFramePc(StructuredData::ObjectSP trace);
};
-
+
} // namespace lldb_private
#endif // liblldb_ThreadSanitizerRuntime_h_
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index a126ad026a55..bbb445a1fbc4 100644
--- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -13,10 +13,10 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@@ -35,507 +35,420 @@ using namespace lldb_private;
//------------------------------------------------------------------
// Debug Interface Structures
//------------------------------------------------------------------
-typedef enum
-{
- JIT_NOACTION = 0,
- JIT_REGISTER_FN,
- JIT_UNREGISTER_FN
+typedef enum {
+ JIT_NOACTION = 0,
+ JIT_REGISTER_FN,
+ JIT_UNREGISTER_FN
} jit_actions_t;
-template <typename ptr_t>
-struct jit_code_entry
-{
- ptr_t next_entry; // pointer
- ptr_t prev_entry; // pointer
- ptr_t symfile_addr; // pointer
- uint64_t symfile_size;
+template <typename ptr_t> struct jit_code_entry {
+ ptr_t next_entry; // pointer
+ ptr_t prev_entry; // pointer
+ ptr_t symfile_addr; // pointer
+ uint64_t symfile_size;
};
-template <typename ptr_t>
-struct jit_descriptor
-{
- uint32_t version;
- uint32_t action_flag; // Values are jit_action_t
- ptr_t relevant_entry; // pointer
- ptr_t first_entry; // pointer
+template <typename ptr_t> struct jit_descriptor {
+ uint32_t version;
+ uint32_t action_flag; // Values are jit_action_t
+ ptr_t relevant_entry; // pointer
+ ptr_t first_entry; // pointer
};
namespace {
- 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 }
- };
-
- enum
- {
- ePropertyEnableJITBreakpoint
- };
-
-
- class PluginProperties : public Properties
- {
- public:
- static ConstString
- GetSettingName()
- {
- return JITLoaderGDB::GetPluginNameStatic();
- }
-
- PluginProperties()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- bool
- GetEnableJITBreakpoint() const
- {
- return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr,
- ePropertyEnableJITBreakpoint,
- g_properties[ePropertyEnableJITBreakpoint].default_uint_value != 0);
- }
+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}};
+
+enum { ePropertyEnableJITBreakpoint };
+
+class PluginProperties : public Properties {
+public:
+ static ConstString GetSettingName() {
+ return JITLoaderGDB::GetPluginNameStatic();
+ }
+
+ PluginProperties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ bool GetEnableJITBreakpoint() const {
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, ePropertyEnableJITBreakpoint,
+ g_properties[ePropertyEnableJITBreakpoint].default_uint_value != 0);
+ }
+};
- };
+typedef std::shared_ptr<PluginProperties> JITLoaderGDBPropertiesSP;
- typedef std::shared_ptr<PluginProperties> JITLoaderGDBPropertiesSP;
+static const JITLoaderGDBPropertiesSP &GetGlobalPluginProperties() {
+ static const auto g_settings_sp(std::make_shared<PluginProperties>());
+ return g_settings_sp;
+}
- static const JITLoaderGDBPropertiesSP&
- GetGlobalPluginProperties()
- {
- static const auto g_settings_sp(std::make_shared<PluginProperties>());
- return g_settings_sp;
- }
+template <typename ptr_t>
+bool ReadJITEntry(const addr_t from_addr, Process *process,
+ jit_code_entry<ptr_t> *entry) {
+ lldbassert(from_addr % sizeof(ptr_t) == 0);
+
+ ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore();
+ bool i386_target = ArchSpec::kCore_x86_32_first <= core &&
+ core <= ArchSpec::kCore_x86_32_last;
+ uint8_t uint64_align_bytes = i386_target ? 4 : 8;
+ const size_t data_byte_size =
+ llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t);
+
+ Error error;
+ DataBufferHeap data(data_byte_size, 0);
+ size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(),
+ data.GetByteSize(), error);
+ if (bytes_read != data_byte_size || !error.Success())
+ return false;
+
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ process->GetByteOrder(), sizeof(ptr_t));
+ lldb::offset_t offset = 0;
+ entry->next_entry = extractor.GetPointer(&offset);
+ entry->prev_entry = extractor.GetPointer(&offset);
+ entry->symfile_addr = extractor.GetPointer(&offset);
+ offset = llvm::alignTo(offset, uint64_align_bytes);
+ entry->symfile_size = extractor.GetU64(&offset);
+
+ return true;
+}
- template <typename ptr_t>
- bool ReadJITEntry(const addr_t from_addr, Process *process, jit_code_entry<ptr_t> *entry)
- {
- lldbassert(from_addr % sizeof(ptr_t) == 0);
-
- ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore();
- bool i386_target = ArchSpec::kCore_x86_32_first <= core && core <= ArchSpec::kCore_x86_32_last;
- uint8_t uint64_align_bytes = i386_target ? 4 : 8;
- const size_t data_byte_size = llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t);
-
- Error error;
- DataBufferHeap data(data_byte_size, 0);
- size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(), data.GetByteSize(), error);
- if (bytes_read != data_byte_size || !error.Success())
- return false;
-
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), process->GetByteOrder(), sizeof(ptr_t));
- lldb::offset_t offset = 0;
- entry->next_entry = extractor.GetPointer(&offset);
- entry->prev_entry = extractor.GetPointer(&offset);
- entry->symfile_addr = extractor.GetPointer(&offset);
- offset = llvm::alignTo(offset, uint64_align_bytes);
- entry->symfile_size = extractor.GetU64(&offset);
-
- return true;
- }
+} // anonymous namespace end
-} // anonymous namespace end
+JITLoaderGDB::JITLoaderGDB(lldb_private::Process *process)
+ : JITLoader(process), m_jit_objects(),
+ m_jit_break_id(LLDB_INVALID_BREAK_ID),
+ m_jit_descriptor_addr(LLDB_INVALID_ADDRESS) {}
-JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
- JITLoader(process),
- m_jit_objects(),
- m_jit_break_id(LLDB_INVALID_BREAK_ID),
- m_jit_descriptor_addr(LLDB_INVALID_ADDRESS)
-{
+JITLoaderGDB::~JITLoaderGDB() {
+ if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_jit_break_id);
}
-JITLoaderGDB::~JITLoaderGDB ()
-{
- if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
- m_process->GetTarget().RemoveBreakpointByID (m_jit_break_id);
+void JITLoaderGDB::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForJITLoaderPlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForJITLoaderPlugin(
+ debugger, GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString("Properties for the JIT LoaderGDB plug-in."),
+ is_global_setting);
+ }
}
-void
-JITLoaderGDB::DebuggerInitialize(Debugger &debugger)
-{
- if (!PluginManager::GetSettingForJITLoaderPlugin(debugger, PluginProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForJITLoaderPlugin(debugger,
- GetGlobalPluginProperties()->GetValueProperties(),
- ConstString ("Properties for the JIT LoaderGDB plug-in."),
- is_global_setting);
- }
+void JITLoaderGDB::DidAttach() {
+ Target &target = m_process->GetTarget();
+ ModuleList &module_list = target.GetImages();
+ SetJITBreakpoint(module_list);
}
-void JITLoaderGDB::DidAttach()
-{
- Target &target = m_process->GetTarget();
- ModuleList &module_list = target.GetImages();
- SetJITBreakpoint(module_list);
+void JITLoaderGDB::DidLaunch() {
+ Target &target = m_process->GetTarget();
+ ModuleList &module_list = target.GetImages();
+ SetJITBreakpoint(module_list);
}
-void JITLoaderGDB::DidLaunch()
-{
- Target &target = m_process->GetTarget();
- ModuleList &module_list = target.GetImages();
+void JITLoaderGDB::ModulesDidLoad(ModuleList &module_list) {
+ if (!DidSetJITBreakpoint() && m_process->IsAlive())
SetJITBreakpoint(module_list);
}
-void
-JITLoaderGDB::ModulesDidLoad(ModuleList &module_list)
-{
- if (!DidSetJITBreakpoint() && m_process->IsAlive())
- SetJITBreakpoint(module_list);
-}
-
//------------------------------------------------------------------
// Setup the JIT Breakpoint
//------------------------------------------------------------------
-void
-JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list)
-{
- if (!GetGlobalPluginProperties()->GetEnableJITBreakpoint())
- return;
+void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
+ if (!GetGlobalPluginProperties()->GetEnableJITBreakpoint())
+ return;
- if ( DidSetJITBreakpoint() )
- return;
+ if (DidSetJITBreakpoint())
+ return;
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
- if (log)
- log->Printf("JITLoaderGDB::%s looking for JIT register hook",
- __FUNCTION__);
-
- addr_t jit_addr = GetSymbolAddress(module_list,
- ConstString("__jit_debug_register_code"),
- eSymbolTypeAny);
- if (jit_addr == LLDB_INVALID_ADDRESS)
- return;
-
- m_jit_descriptor_addr = GetSymbolAddress(module_list,
- ConstString("__jit_debug_descriptor"),
- eSymbolTypeData);
- if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf(
- "JITLoaderGDB::%s failed to find JIT descriptor address",
- __FUNCTION__);
- return;
- }
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
+ if (log)
+ log->Printf("JITLoaderGDB::%s looking for JIT register hook", __FUNCTION__);
+
+ addr_t jit_addr = GetSymbolAddress(
+ module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
+ if (jit_addr == LLDB_INVALID_ADDRESS)
+ return;
+ m_jit_descriptor_addr = GetSymbolAddress(
+ module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
+ if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) {
if (log)
- log->Printf("JITLoaderGDB::%s setting JIT breakpoint",
- __FUNCTION__);
+ log->Printf("JITLoaderGDB::%s failed to find JIT descriptor address",
+ __FUNCTION__);
+ return;
+ }
+
+ if (log)
+ log->Printf("JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
- Breakpoint *bp =
- m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
- bp->SetCallback(JITDebugBreakpointHit, this, true);
- bp->SetBreakpointKind("jit-debug-register");
- m_jit_break_id = bp->GetID();
+ Breakpoint *bp =
+ m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
+ bp->SetCallback(JITDebugBreakpointHit, this, true);
+ bp->SetBreakpointKind("jit-debug-register");
+ m_jit_break_id = bp->GetID();
- ReadJITDescriptor(true);
+ ReadJITDescriptor(true);
}
-bool
-JITLoaderGDB::JITDebugBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id, user_id_t break_loc_id)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
- if (log)
- log->Printf("JITLoaderGDB::%s hit JIT breakpoint",
- __FUNCTION__);
- JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
- return instance->ReadJITDescriptor(false);
+bool JITLoaderGDB::JITDebugBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ user_id_t break_id,
+ user_id_t break_loc_id) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
+ if (log)
+ log->Printf("JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
+ JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
+ return instance->ReadJITDescriptor(false);
}
static void updateSectionLoadAddress(const SectionList &section_list,
- Target &target,
- uint64_t symbolfile_addr,
+ Target &target, uint64_t symbolfile_addr,
uint64_t symbolfile_size,
uint64_t &vmaddrheuristic,
- uint64_t &min_addr,
- uint64_t &max_addr)
-{
- const uint32_t num_sections = section_list.GetSize();
- for (uint32_t i = 0; i<num_sections; ++i)
- {
- SectionSP section_sp(section_list.GetSectionAtIndex(i));
- if (section_sp)
- {
- if(section_sp->IsFake()) {
- uint64_t lower = (uint64_t)-1;
- uint64_t upper = 0;
- updateSectionLoadAddress(section_sp->GetChildren(), target, symbolfile_addr, symbolfile_size, vmaddrheuristic,
- lower, upper);
- if (lower < min_addr)
- min_addr = lower;
- if (upper > max_addr)
- max_addr = upper;
- const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress();
- section_sp->Slide(slide_amount, false);
- section_sp->GetChildren().Slide(-slide_amount, false);
- section_sp->SetByteSize (upper - lower);
- } else {
- vmaddrheuristic += 2<<section_sp->GetLog2Align();
- uint64_t lower;
- if (section_sp->GetFileAddress() > vmaddrheuristic)
- lower = section_sp->GetFileAddress();
- else {
- lower = symbolfile_addr+section_sp->GetFileOffset();
- section_sp->SetFileAddress(symbolfile_addr+section_sp->GetFileOffset());
- }
- target.SetSectionLoadAddress(section_sp, lower, true);
- uint64_t upper = lower + section_sp->GetByteSize();
- if (lower < min_addr)
- min_addr = lower;
- if (upper > max_addr)
- max_addr = upper;
- // This is an upper bound, but a good enough heuristic
- vmaddrheuristic += section_sp->GetByteSize();
- }
+ uint64_t &min_addr, uint64_t &max_addr) {
+ const uint32_t num_sections = section_list.GetSize();
+ for (uint32_t i = 0; i < num_sections; ++i) {
+ SectionSP section_sp(section_list.GetSectionAtIndex(i));
+ if (section_sp) {
+ if (section_sp->IsFake()) {
+ uint64_t lower = (uint64_t)-1;
+ uint64_t upper = 0;
+ updateSectionLoadAddress(section_sp->GetChildren(), target,
+ symbolfile_addr, symbolfile_size,
+ vmaddrheuristic, lower, upper);
+ if (lower < min_addr)
+ min_addr = lower;
+ if (upper > max_addr)
+ max_addr = upper;
+ const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress();
+ section_sp->Slide(slide_amount, false);
+ section_sp->GetChildren().Slide(-slide_amount, false);
+ section_sp->SetByteSize(upper - lower);
+ } else {
+ vmaddrheuristic += 2 << section_sp->GetLog2Align();
+ uint64_t lower;
+ if (section_sp->GetFileAddress() > vmaddrheuristic)
+ lower = section_sp->GetFileAddress();
+ else {
+ lower = symbolfile_addr + section_sp->GetFileOffset();
+ section_sp->SetFileAddress(symbolfile_addr +
+ section_sp->GetFileOffset());
}
+ target.SetSectionLoadAddress(section_sp, lower, true);
+ uint64_t upper = lower + section_sp->GetByteSize();
+ if (lower < min_addr)
+ min_addr = lower;
+ if (upper > max_addr)
+ max_addr = upper;
+ // This is an upper bound, but a good enough heuristic
+ vmaddrheuristic += section_sp->GetByteSize();
+ }
}
+ }
}
-bool
-JITLoaderGDB::ReadJITDescriptor(bool all_entries)
-{
- if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
- return ReadJITDescriptorImpl<uint64_t>(all_entries);
- else
- return ReadJITDescriptorImpl<uint32_t>(all_entries);
+bool JITLoaderGDB::ReadJITDescriptor(bool all_entries) {
+ if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ return ReadJITDescriptorImpl<uint64_t>(all_entries);
+ else
+ return ReadJITDescriptorImpl<uint32_t>(all_entries);
}
template <typename ptr_t>
-bool
-JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries)
-{
- if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
- return false;
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
- Target &target = m_process->GetTarget();
- ModuleList &module_list = target.GetImages();
-
- jit_descriptor<ptr_t> jit_desc;
- const size_t jit_desc_size = sizeof(jit_desc);
- Error error;
- size_t bytes_read = m_process->DoReadMemory(
- m_jit_descriptor_addr, &jit_desc, jit_desc_size, error);
- if (bytes_read != jit_desc_size || !error.Success())
- {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to read JIT descriptor",
- __FUNCTION__);
- return false;
- }
-
- jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag;
- addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry;
- if (all_entries)
- {
- jit_action = JIT_REGISTER_FN;
- jit_relevant_entry = (addr_t)jit_desc.first_entry;
- }
-
- while (jit_relevant_entry != 0)
- {
- jit_code_entry<ptr_t> jit_entry;
- if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry))
- {
- if (log)
- log->Printf(
- "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
+bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
+ if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
+ Target &target = m_process->GetTarget();
+ ModuleList &module_list = target.GetImages();
+
+ jit_descriptor<ptr_t> jit_desc;
+ const size_t jit_desc_size = sizeof(jit_desc);
+ Error error;
+ size_t bytes_read = m_process->DoReadMemory(m_jit_descriptor_addr, &jit_desc,
+ jit_desc_size, error);
+ if (bytes_read != jit_desc_size || !error.Success()) {
+ if (log)
+ log->Printf("JITLoaderGDB::%s failed to read JIT descriptor",
+ __FUNCTION__);
+ return false;
+ }
+
+ jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag;
+ addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry;
+ if (all_entries) {
+ jit_action = JIT_REGISTER_FN;
+ jit_relevant_entry = (addr_t)jit_desc.first_entry;
+ }
+
+ while (jit_relevant_entry != 0) {
+ jit_code_entry<ptr_t> jit_entry;
+ if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) {
+ if (log)
+ log->Printf("JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
__FUNCTION__, jit_relevant_entry);
- return false;
- }
+ return false;
+ }
- const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
- const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
- ModuleSP module_sp;
+ const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
+ const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
+ ModuleSP module_sp;
- if (jit_action == JIT_REGISTER_FN)
- {
- if (log)
- log->Printf(
- "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
+ if (jit_action == JIT_REGISTER_FN) {
+ if (log)
+ log->Printf("JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
" (%" PRIu64 " bytes)",
- __FUNCTION__, symbolfile_addr, (uint64_t) symbolfile_size);
-
- 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);
-
- if (module_sp && module_sp->GetObjectFile())
- {
- // load the symbol table right away
- module_sp->GetObjectFile()->GetSymtab();
-
- m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
- if (module_sp->GetObjectFile()->GetPluginName() == ConstString("mach-o"))
- {
- ObjectFile *image_object_file = module_sp->GetObjectFile();
- if (image_object_file)
- {
- const SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- uint64_t vmaddrheuristic = 0;
- uint64_t lower = (uint64_t)-1;
- uint64_t upper = 0;
- updateSectionLoadAddress(*section_list, target, symbolfile_addr, symbolfile_size,
- vmaddrheuristic, lower, upper);
- }
- }
- }
- else
- {
- bool changed = false;
- module_sp->SetLoadAddress(target, 0, true, changed);
- }
-
- module_list.AppendIfNeeded(module_sp);
-
- ModuleList module_list;
- module_list.Append(module_sp);
- target.ModulesDidLoad(module_list);
- }
- else
- {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to load module for "
- "JIT entry at 0x%" PRIx64,
- __FUNCTION__, symbolfile_addr);
+ __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
+
+ 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);
+
+ if (module_sp && module_sp->GetObjectFile()) {
+ // load the symbol table right away
+ module_sp->GetObjectFile()->GetSymtab();
+
+ m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
+ if (module_sp->GetObjectFile()->GetPluginName() ==
+ ConstString("mach-o")) {
+ ObjectFile *image_object_file = module_sp->GetObjectFile();
+ if (image_object_file) {
+ const SectionList *section_list =
+ image_object_file->GetSectionList();
+ if (section_list) {
+ uint64_t vmaddrheuristic = 0;
+ uint64_t lower = (uint64_t)-1;
+ uint64_t upper = 0;
+ updateSectionLoadAddress(*section_list, target, symbolfile_addr,
+ symbolfile_size, vmaddrheuristic, lower,
+ upper);
}
+ }
+ } else {
+ bool changed = false;
+ module_sp->SetLoadAddress(target, 0, true, changed);
}
- else if (jit_action == JIT_UNREGISTER_FN)
- {
- if (log)
- log->Printf(
- "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
+
+ module_list.AppendIfNeeded(module_sp);
+
+ ModuleList module_list;
+ module_list.Append(module_sp);
+ target.ModulesDidLoad(module_list);
+ } else {
+ if (log)
+ log->Printf("JITLoaderGDB::%s failed to load module for "
+ "JIT entry at 0x%" PRIx64,
+ __FUNCTION__, symbolfile_addr);
+ }
+ } else if (jit_action == JIT_UNREGISTER_FN) {
+ if (log)
+ log->Printf("JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
__FUNCTION__, symbolfile_addr);
- JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
- if (it != m_jit_objects.end())
- {
- module_sp = it->second;
- ObjectFile *image_object_file = module_sp->GetObjectFile();
- if (image_object_file)
- {
- const SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- const uint32_t num_sections = section_list->GetSize();
- for (uint32_t i = 0; i<num_sections; ++i)
- {
- SectionSP section_sp(section_list->GetSectionAtIndex(i));
- if (section_sp)
- {
- target.GetSectionLoadList().SetSectionUnloaded (section_sp);
- }
- }
- }
- }
- module_list.Remove(module_sp);
- m_jit_objects.erase(it);
+ JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
+ if (it != m_jit_objects.end()) {
+ module_sp = it->second;
+ ObjectFile *image_object_file = module_sp->GetObjectFile();
+ if (image_object_file) {
+ const SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ const uint32_t num_sections = section_list->GetSize();
+ for (uint32_t i = 0; i < num_sections; ++i) {
+ SectionSP section_sp(section_list->GetSectionAtIndex(i));
+ if (section_sp) {
+ target.GetSectionLoadList().SetSectionUnloaded(section_sp);
+ }
}
+ }
}
- else if (jit_action == JIT_NOACTION)
- {
- // Nothing to do
- }
- else
- {
- assert(false && "Unknown jit action");
- }
-
- if (all_entries)
- jit_relevant_entry = (addr_t)jit_entry.next_entry;
- else
- jit_relevant_entry = 0;
+ module_list.Remove(module_sp);
+ m_jit_objects.erase(it);
+ }
+ } else if (jit_action == JIT_NOACTION) {
+ // Nothing to do
+ } else {
+ assert(false && "Unknown jit action");
}
- return false; // Continue Running.
+ if (all_entries)
+ jit_relevant_entry = (addr_t)jit_entry.next_entry;
+ else
+ jit_relevant_entry = 0;
+ }
+
+ return false; // Continue Running.
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-JITLoaderGDB::GetPluginNameStatic()
-{
- static ConstString g_name("gdb");
- return g_name;
+lldb_private::ConstString JITLoaderGDB::GetPluginNameStatic() {
+ static ConstString g_name("gdb");
+ return g_name;
}
-JITLoaderSP
-JITLoaderGDB::CreateInstance(Process *process, bool force)
-{
- JITLoaderSP jit_loader_sp;
- ArchSpec arch (process->GetTarget().GetArchitecture());
- if (arch.GetTriple().getVendor() != llvm::Triple::Apple)
- jit_loader_sp.reset(new JITLoaderGDB(process));
- return jit_loader_sp;
+JITLoaderSP JITLoaderGDB::CreateInstance(Process *process, bool force) {
+ JITLoaderSP jit_loader_sp;
+ ArchSpec arch(process->GetTarget().GetArchitecture());
+ if (arch.GetTriple().getVendor() != llvm::Triple::Apple)
+ jit_loader_sp.reset(new JITLoaderGDB(process));
+ return jit_loader_sp;
}
-const char *
-JITLoaderGDB::GetPluginDescriptionStatic()
-{
- return "JIT loader plug-in that watches for JIT events using the GDB interface.";
+const char *JITLoaderGDB::GetPluginDescriptionStatic() {
+ return "JIT loader plug-in that watches for JIT events using the GDB "
+ "interface.";
}
-lldb_private::ConstString
-JITLoaderGDB::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString JITLoaderGDB::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-JITLoaderGDB::GetPluginVersion()
-{
- return 1;
-}
+uint32_t JITLoaderGDB::GetPluginVersion() { return 1; }
-void
-JITLoaderGDB::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
+void JITLoaderGDB::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
}
-void
-JITLoaderGDB::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void JITLoaderGDB::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-bool
-JITLoaderGDB::DidSetJITBreakpoint() const
-{
- return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
+bool JITLoaderGDB::DidSetJITBreakpoint() const {
+ return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
}
-addr_t
-JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, const ConstString &name,
- SymbolType symbol_type) const
-{
- SymbolContextList target_symbols;
- Target &target = m_process->GetTarget();
+addr_t JITLoaderGDB::GetSymbolAddress(ModuleList &module_list,
+ const ConstString &name,
+ SymbolType symbol_type) const {
+ SymbolContextList target_symbols;
+ Target &target = m_process->GetTarget();
- if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
- target_symbols))
- return LLDB_INVALID_ADDRESS;
+ if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
+ target_symbols))
+ return LLDB_INVALID_ADDRESS;
- SymbolContext sym_ctx;
- target_symbols.GetContextAtIndex(0, sym_ctx);
+ SymbolContext sym_ctx;
+ target_symbols.GetContextAtIndex(0, sym_ctx);
- const Address jit_descriptor_addr = sym_ctx.symbol->GetAddress();
- if (!jit_descriptor_addr.IsValid())
- return LLDB_INVALID_ADDRESS;
+ const Address jit_descriptor_addr = sym_ctx.symbol->GetAddress();
+ if (!jit_descriptor_addr.IsValid())
+ return LLDB_INVALID_ADDRESS;
- const addr_t jit_addr = jit_descriptor_addr.GetLoadAddress(&target);
- return jit_addr;
+ const addr_t jit_addr = jit_descriptor_addr.GetLoadAddress(&target);
+ return jit_addr;
}
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.h b/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
index 10bd989c328f..6269860825db 100644
--- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
@@ -19,92 +19,73 @@
#include "lldb/Target/JITLoader.h"
#include "lldb/Target/Process.h"
-class JITLoaderGDB : public lldb_private::JITLoader
-{
+class JITLoaderGDB : public lldb_private::JITLoader {
public:
- JITLoaderGDB(lldb_private::Process *process);
+ JITLoaderGDB(lldb_private::Process *process);
- ~JITLoaderGDB() override;
+ ~JITLoaderGDB() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb::JITLoaderSP
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb::JITLoaderSP CreateInstance(lldb_private::Process *process,
+ bool force);
- static void
- DebuggerInitialize(lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- //------------------------------------------------------------------
- // JITLoader interface
- //------------------------------------------------------------------
- void
- DidAttach() override;
+ //------------------------------------------------------------------
+ // JITLoader interface
+ //------------------------------------------------------------------
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- void
- ModulesDidLoad(lldb_private::ModuleList &module_list) override;
+ void ModulesDidLoad(lldb_private::ModuleList &module_list) override;
private:
- lldb::addr_t
- GetSymbolAddress(lldb_private::ModuleList &module_list,
- const lldb_private::ConstString &name,
- lldb::SymbolType symbol_type) const;
+ lldb::addr_t GetSymbolAddress(lldb_private::ModuleList &module_list,
+ const lldb_private::ConstString &name,
+ lldb::SymbolType symbol_type) const;
- void
- SetJITBreakpoint(lldb_private::ModuleList &module_list);
+ void SetJITBreakpoint(lldb_private::ModuleList &module_list);
- bool
- DidSetJITBreakpoint() const;
+ bool DidSetJITBreakpoint() const;
- bool
- ReadJITDescriptor(bool all_entries);
+ bool ReadJITDescriptor(bool all_entries);
- template <typename ptr_t>
- bool
- ReadJITDescriptorImpl(bool all_entries);
+ template <typename ptr_t> bool ReadJITDescriptorImpl(bool all_entries);
- static bool
- JITDebugBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
+ static bool
+ JITDebugBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
- static void
- ProcessStateChangedCallback(void *baton,
- lldb_private::Process *process,
- lldb::StateType state);
+ static void ProcessStateChangedCallback(void *baton,
+ lldb_private::Process *process,
+ lldb::StateType state);
- // A collection of in-memory jitted object addresses and their corresponding modules
- typedef std::map<lldb::addr_t, const lldb::ModuleSP> JITObjectMap;
- JITObjectMap m_jit_objects;
-
- lldb::user_id_t m_jit_break_id;
- lldb::addr_t m_jit_descriptor_addr;
+ // A collection of in-memory jitted object addresses and their corresponding
+ // modules
+ typedef std::map<lldb::addr_t, const lldb::ModuleSP> JITObjectMap;
+ JITObjectMap m_jit_objects;
+ lldb::user_id_t m_jit_break_id;
+ lldb::addr_t m_jit_descriptor_addr;
};
#endif // liblldb_JITLoaderGDB_h_
diff --git a/source/Plugins/Language/CMakeLists.txt b/source/Plugins/Language/CMakeLists.txt
index 725138a56c8e..4b92a8ef866b 100644
--- a/source/Plugins/Language/CMakeLists.txt
+++ b/source/Plugins/Language/CMakeLists.txt
@@ -3,3 +3,4 @@ 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 92e30d54f6e1..db7c24675825 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -27,199 +27,185 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-namespace lldb_private
-{
-namespace formatters
-{
+namespace lldb_private {
+namespace formatters {
-class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp),
- m_block_struct_type()
- {
- CompilerType block_pointer_type(m_backend.GetCompilerType());
- CompilerType function_pointer_type;
- block_pointer_type.IsBlockPointerType(&function_pointer_type);
-
- TargetSP target_sp(m_backend.GetTargetSP());
-
- if (!target_sp)
- {
- return;
- }
-
- Error err;
- TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(&err, lldb::eLanguageTypeC_plus_plus);
-
- if (!err.Success() || !type_system)
- {
- return;
- }
-
- ClangASTContext *clang_ast_context = llvm::dyn_cast<ClangASTContext>(type_system);
-
- if (!clang_ast_context)
- {
- return;
- }
-
- ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter();
-
- if (!clang_ast_importer)
- {
- return;
- }
-
- const char *const isa_name("__isa");
- const CompilerType isa_type = clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
- const char *const flags_name("__flags");
- const CompilerType flags_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
- const char *const reserved_name("__reserved");
- const CompilerType reserved_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
- const char *const FuncPtr_name("__FuncPtr");
- const CompilerType FuncPtr_type = clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
-
- m_block_struct_type = clang_ast_context->CreateStructForIdentifier(ConstString(),
- {
- {isa_name, isa_type},
- {flags_name, flags_type},
- {reserved_name, reserved_type},
- {FuncPtr_name, FuncPtr_type}
- });
+ BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_block_struct_type() {
+ CompilerType block_pointer_type(m_backend.GetCompilerType());
+ CompilerType function_pointer_type;
+ block_pointer_type.IsBlockPointerType(&function_pointer_type);
+ TargetSP target_sp(m_backend.GetTargetSP());
+
+ if (!target_sp) {
+ return;
+ }
+
+ Error err;
+ TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(
+ &err, lldb::eLanguageTypeC_plus_plus);
+
+ if (!err.Success() || !type_system) {
+ return;
+ }
+
+ ClangASTContext *clang_ast_context =
+ llvm::dyn_cast<ClangASTContext>(type_system);
+
+ if (!clang_ast_context) {
+ return;
}
- ~BlockPointerSyntheticFrontEnd() override = default;
+ ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter();
- size_t
- CalculateNumChildren() override
- {
- const bool omit_empty_base_classes = false;
- return m_block_struct_type.GetNumChildren(omit_empty_base_classes);
+ if (!clang_ast_importer) {
+ return;
}
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override
- {
- if (!m_block_struct_type.IsValid())
- {
- return lldb::ValueObjectSP();
- }
-
- if (idx >= CalculateNumChildren())
- {
- return lldb::ValueObjectSP();
- }
-
- const bool thread_and_frame_only_if_stopped = true;
- ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
- const bool transparent_pointers = false;
- const bool omit_empty_base_classes = false;
- const bool ignore_array_bounds = false;
- ValueObject *value_object = nullptr;
-
- std::string child_name;
- uint32_t child_byte_size = 0;
- int32_t child_byte_offset = 0;
- uint32_t child_bitfield_bit_size = 0;
- uint32_t child_bitfield_bit_offset = 0;
- bool child_is_base_class = false;
- bool child_is_deref_of_parent = false;
- uint64_t language_flags = 0;
-
- const CompilerType child_type = m_block_struct_type.GetChildCompilerTypeAtIndex(&exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, value_object, language_flags);
-
- ValueObjectSP struct_pointer_sp = m_backend.Cast(m_block_struct_type.GetPointerType());
-
- if (!struct_pointer_sp)
- {
- return lldb::ValueObjectSP();
- }
-
- Error err;
- ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
-
- if (!struct_sp || !err.Success())
- {
- return lldb::ValueObjectSP();
- }
-
- ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(child_byte_offset,
- child_type,
- true,
- ConstString(child_name.c_str(), child_name.size())));
-
- return child_sp;
+ const char *const isa_name("__isa");
+ const CompilerType isa_type =
+ clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
+ const char *const flags_name("__flags");
+ const CompilerType flags_type =
+ clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
+ const char *const reserved_name("__reserved");
+ const CompilerType reserved_type =
+ clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
+ const char *const FuncPtr_name("__FuncPtr");
+ const CompilerType FuncPtr_type =
+ clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
+
+ m_block_struct_type = clang_ast_context->CreateStructForIdentifier(
+ ConstString(), {{isa_name, isa_type},
+ {flags_name, flags_type},
+ {reserved_name, reserved_type},
+ {FuncPtr_name, FuncPtr_type}});
+ }
+
+ ~BlockPointerSyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override {
+ const bool omit_empty_base_classes = false;
+ return m_block_struct_type.GetNumChildren(omit_empty_base_classes);
+ }
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+ if (!m_block_struct_type.IsValid()) {
+ return lldb::ValueObjectSP();
}
- // return true if this object is now safe to use forever without
- // ever updating again; the typical (and tested) answer here is
- // 'false'
- bool
- Update() override
- {
- return false;
+ if (idx >= CalculateNumChildren()) {
+ return lldb::ValueObjectSP();
}
- // maybe return false if the block pointer is, say, null
- bool
- MightHaveChildren() override
- {
- return true;
+ const bool thread_and_frame_only_if_stopped = true;
+ ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(
+ thread_and_frame_only_if_stopped);
+ const bool transparent_pointers = false;
+ const bool omit_empty_base_classes = false;
+ const bool ignore_array_bounds = false;
+ ValueObject *value_object = nullptr;
+
+ std::string child_name;
+ uint32_t child_byte_size = 0;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size = 0;
+ uint32_t child_bitfield_bit_offset = 0;
+ bool child_is_base_class = false;
+ bool child_is_deref_of_parent = false;
+ uint64_t language_flags = 0;
+
+ const CompilerType child_type =
+ m_block_struct_type.GetChildCompilerTypeAtIndex(
+ &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, child_is_deref_of_parent, value_object,
+ language_flags);
+
+ ValueObjectSP struct_pointer_sp =
+ m_backend.Cast(m_block_struct_type.GetPointerType());
+
+ if (!struct_pointer_sp) {
+ return lldb::ValueObjectSP();
}
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- if (!m_block_struct_type.IsValid())
- return UINT32_MAX;
-
- const bool omit_empty_base_classes = false;
- return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(), omit_empty_base_classes);
+ Error err;
+ ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
+
+ if (!struct_sp || !err.Success()) {
+ return lldb::ValueObjectSP();
}
+ ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(
+ child_byte_offset, child_type, true,
+ ConstString(child_name.c_str(), child_name.size())));
+
+ return child_sp;
+ }
+
+ // return true if this object is now safe to use forever without
+ // ever updating again; the typical (and tested) answer here is
+ // 'false'
+ bool Update() override { return false; }
+
+ // maybe return false if the block pointer is, say, null
+ bool MightHaveChildren() override { return true; }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ if (!m_block_struct_type.IsValid())
+ return UINT32_MAX;
+
+ const bool omit_empty_base_classes = false;
+ return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(),
+ omit_empty_base_classes);
+ }
+
private:
- CompilerType m_block_struct_type;
+ CompilerType m_block_struct_type;
};
} // namespace formatters
} // namespace lldb_private
-bool
-lldb_private::formatters::BlockPointerSummaryProvider(ValueObject &valobj, Stream &s, const TypeSummaryOptions &)
-{
- lldb_private::SyntheticChildrenFrontEnd *synthetic_children = BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
- if (!synthetic_children)
- {
- return false;
- }
+bool lldb_private::formatters::BlockPointerSummaryProvider(
+ ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
+ lldb_private::SyntheticChildrenFrontEnd *synthetic_children =
+ BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
+ if (!synthetic_children) {
+ return false;
+ }
- synthetic_children->Update();
+ synthetic_children->Update();
- static const ConstString s_FuncPtr_name("__FuncPtr");
-
- lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
-
- if (!child_sp)
- {
- return false;
- }
-
- lldb::ValueObjectSP qualified_child_representation_sp = child_sp->GetQualifiedRepresentationIfAvailable(lldb::eDynamicDontRunTarget, true);
+ static const ConstString s_FuncPtr_name("__FuncPtr");
+
+ lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(
+ synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
+
+ if (!child_sp) {
+ return false;
+ }
+
+ lldb::ValueObjectSP qualified_child_representation_sp =
+ child_sp->GetQualifiedRepresentationIfAvailable(
+ lldb::eDynamicDontRunTarget, true);
- const char *child_value = qualified_child_representation_sp->GetValueAsCString();
+ const char *child_value =
+ qualified_child_representation_sp->GetValueAsCString();
- s.Printf("%s", child_value);
+ s.Printf("%s", child_value);
- return true;
+ return true;
}
lldb_private::SyntheticChildrenFrontEnd *
-lldb_private::formatters::BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp)
-{
- if (!valobj_sp)
- return nullptr;
- return new BlockPointerSyntheticFrontEnd(valobj_sp);
+lldb_private::formatters::BlockPointerSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (!valobj_sp)
+ return nullptr;
+ return new BlockPointerSyntheticFrontEnd(valobj_sp);
}
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.h b/source/Plugins/Language/CPlusPlus/BlockPointer.h
index 5e6c748b5dbb..e5008a8f3676 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.h
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.h
@@ -12,15 +12,14 @@
#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
-namespace formatters
-{
-bool
-BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &);
+namespace lldb_private {
+namespace formatters {
+bool BlockPointerSummaryProvider(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
SyntheticChildrenFrontEnd *
-BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
+BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index de0dc99d85dd..5e105aa19b6b 100644
--- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -10,4 +10,6 @@ add_lldb_library(lldbPluginCPlusPlusLanguage
LibCxxUnorderedMap.cpp
LibCxxVector.cpp
LibStdcpp.cpp
+ LibStdcppTuple.cpp
+ LibStdcppUniquePointer.cpp
)
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 33d22bf2e583..b5527edacd13 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -10,17 +10,22 @@
#include "CPlusPlusLanguage.h"
// C Includes
-// C++ Includes
-#include <cstring>
#include <cctype>
+#include <cstring>
+
+// C++ Includes
#include <functional>
+#include <memory>
#include <mutex>
+#include <set>
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
// Project includes
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/FastDemangle.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/UniqueCStringMap.h"
@@ -39,818 +44,1122 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-void
-CPlusPlusLanguage::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "C++ Language",
- CreateInstance);
+void CPlusPlusLanguage::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
+ CreateInstance);
}
-void
-CPlusPlusLanguage::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void CPlusPlusLanguage::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-CPlusPlusLanguage::GetPluginNameStatic()
-{
- static ConstString g_name("cplusplus");
- return g_name;
+lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
+ static ConstString g_name("cplusplus");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-CPlusPlusLanguage::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString CPlusPlusLanguage::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-CPlusPlusLanguage::GetPluginVersion()
-{
- return 1;
-}
+uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-Language *
-CPlusPlusLanguage::CreateInstance (lldb::LanguageType language)
-{
- if (Language::LanguageIsCPlusPlus(language))
- return new CPlusPlusLanguage();
- return nullptr;
+Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
+ if (Language::LanguageIsCPlusPlus(language))
+ return new CPlusPlusLanguage();
+ return nullptr;
}
-void
-CPlusPlusLanguage::MethodName::Clear()
-{
- m_full.Clear();
- m_basename = llvm::StringRef();
- m_context = llvm::StringRef();
- m_arguments = llvm::StringRef();
- m_qualifiers = llvm::StringRef();
- m_type = eTypeInvalid;
- m_parsed = false;
- m_parse_error = false;
+void CPlusPlusLanguage::MethodName::Clear() {
+ m_full.Clear();
+ m_basename = llvm::StringRef();
+ m_context = llvm::StringRef();
+ m_arguments = llvm::StringRef();
+ m_qualifiers = llvm::StringRef();
+ m_type = eTypeInvalid;
+ m_parsed = false;
+ m_parse_error = false;
}
-bool
-ReverseFindMatchingChars (const llvm::StringRef &s,
- const llvm::StringRef &left_right_chars,
- size_t &left_pos,
- size_t &right_pos,
- size_t pos = llvm::StringRef::npos)
-{
- assert (left_right_chars.size() == 2);
- left_pos = llvm::StringRef::npos;
- const char left_char = left_right_chars[0];
- const char right_char = left_right_chars[1];
+bool ReverseFindMatchingChars(const llvm::StringRef &s,
+ const llvm::StringRef &left_right_chars,
+ size_t &left_pos, size_t &right_pos,
+ size_t pos = llvm::StringRef::npos) {
+ assert(left_right_chars.size() == 2);
+ left_pos = llvm::StringRef::npos;
+ const char left_char = left_right_chars[0];
+ const char right_char = left_right_chars[1];
+ pos = s.find_last_of(left_right_chars, pos);
+ if (pos == llvm::StringRef::npos || s[pos] == left_char)
+ return false;
+ right_pos = pos;
+ uint32_t depth = 1;
+ while (pos > 0 && depth > 0) {
pos = s.find_last_of(left_right_chars, pos);
- if (pos == llvm::StringRef::npos || s[pos] == left_char)
- return false;
- right_pos = pos;
- uint32_t depth = 1;
- while (pos > 0 && depth > 0)
- {
- pos = s.find_last_of(left_right_chars, pos);
- if (pos == llvm::StringRef::npos)
- return false;
- if (s[pos] == left_char)
- {
- if (--depth == 0)
- {
- left_pos = pos;
- return left_pos < right_pos;
- }
- }
- else if (s[pos] == right_char)
- {
- ++depth;
- }
+ if (pos == llvm::StringRef::npos)
+ return false;
+ if (s[pos] == left_char) {
+ if (--depth == 0) {
+ left_pos = pos;
+ return left_pos < right_pos;
+ }
+ } else if (s[pos] == right_char) {
+ ++depth;
}
- return false;
+ }
+ return false;
}
-static bool
-IsValidBasename(const llvm::StringRef& basename)
-{
- // Check that the basename matches with the following regular expression or is an operator name:
- // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$"
- // We are using a hand written implementation because it is significantly more efficient then
- // using the general purpose regular expression library.
- size_t idx = 0;
- if (basename.size() > 0 && basename[0] == '~')
- idx = 1;
+static bool IsValidBasename(const llvm::StringRef &basename) {
+ // Check that the basename matches with the following regular expression or is
+ // an operator name:
+ // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$"
+ // We are using a hand written implementation because it is significantly more
+ // efficient then
+ // using the general purpose regular expression library.
+ size_t idx = 0;
+ if (basename.size() > 0 && basename[0] == '~')
+ idx = 1;
- if (basename.size() <= idx)
- return false; // Empty string or "~"
+ if (basename.size() <= idx)
+ return false; // Empty string or "~"
- if (!std::isalpha(basename[idx]) && basename[idx] != '_')
- return false; // First charater (after removing the possible '~'') isn't in [A-Za-z_]
+ if (!std::isalpha(basename[idx]) && basename[idx] != '_')
+ return false; // First charater (after removing the possible '~'') isn't in
+ // [A-Za-z_]
- // Read all characters matching [A-Za-z_0-9]
+ // Read all characters matching [A-Za-z_0-9]
+ ++idx;
+ while (idx < basename.size()) {
+ if (!std::isalnum(basename[idx]) && basename[idx] != '_')
+ break;
++idx;
- while (idx < basename.size())
- {
- if (!std::isalnum(basename[idx]) && basename[idx] != '_')
- break;
- ++idx;
- }
+ }
- // We processed all characters. It is a vaild basename.
- if (idx == basename.size())
- return true;
+ // We processed all characters. It is a vaild basename.
+ if (idx == basename.size())
+ return true;
- // Check for basename with template arguments
- // TODO: Improve the quality of the validation with validating the template arguments
- if (basename[idx] == '<' && basename.back() == '>')
- return true;
+ // Check for basename with template arguments
+ // TODO: Improve the quality of the validation with validating the template
+ // arguments
+ if (basename[idx] == '<' && basename.back() == '>')
+ return true;
- // Check if the basename is a vaild C++ operator name
- if (!basename.startswith("operator"))
- return false;
+ // Check if the basename is a vaild C++ operator name
+ if (!basename.startswith("operator"))
+ return false;
- static RegularExpression g_operator_regex("^(operator)( ?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|\\[\\]|[\\^<>=!\\/*+-]+)(<.*>)?(\\[\\])?$");
- std::string basename_str(basename.str());
- return g_operator_regex.Execute(basename_str.c_str(), nullptr);
+ static RegularExpression g_operator_regex(
+ llvm::StringRef("^(operator)( "
+ "?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|"
+ "\\[\\]|[\\^<>=!\\/"
+ "*+-]+)(<.*>)?(\\[\\])?$"));
+ std::string basename_str(basename.str());
+ return g_operator_regex.Execute(basename_str, nullptr);
}
-void
-CPlusPlusLanguage::MethodName::Parse()
-{
- if (!m_parsed && m_full)
- {
-// ConstString mangled;
-// m_full.GetMangledCounterpart(mangled);
-// printf ("\n parsing = '%s'\n", m_full.GetCString());
-// if (mangled)
-// printf (" mangled = '%s'\n", mangled.GetCString());
- m_parse_error = false;
- m_parsed = true;
- llvm::StringRef full (m_full.GetCString());
-
- size_t arg_start, arg_end;
- llvm::StringRef parens("()", 2);
- if (ReverseFindMatchingChars (full, parens, arg_start, arg_end))
- {
- m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
- if (arg_end + 1 < full.size())
- m_qualifiers = full.substr(arg_end + 1);
- if (arg_start > 0)
- {
- size_t basename_end = arg_start;
- size_t context_start = 0;
- size_t context_end = llvm::StringRef::npos;
- if (basename_end > 0 && full[basename_end-1] == '>')
- {
- // TODO: handle template junk...
- // Templated function
- size_t template_start, template_end;
- llvm::StringRef lt_gt("<>", 2);
- if (ReverseFindMatchingChars (full, lt_gt, template_start, template_end, basename_end))
- {
- // Check for templated functions that include return type like: 'void foo<Int>()'
- context_start = full.rfind(' ', template_start);
- if (context_start == llvm::StringRef::npos)
- context_start = 0;
-
- context_end = full.rfind(':', template_start);
- if (context_end == llvm::StringRef::npos || context_end < context_start)
- context_end = context_start;
- }
- else
- {
- context_end = full.rfind(':', basename_end);
- }
- }
- else if (context_end == llvm::StringRef::npos)
- {
- context_end = full.rfind(':', basename_end);
- }
-
- if (context_end == llvm::StringRef::npos)
- m_basename = full.substr(0, basename_end);
- else
- {
- if (context_start < context_end)
- m_context = full.substr(context_start, context_end - 1);
- const size_t basename_begin = context_end + 1;
- m_basename = full.substr(basename_begin, basename_end - basename_begin);
- }
- m_type = eTypeUnknownMethod;
- }
+void CPlusPlusLanguage::MethodName::Parse() {
+ if (!m_parsed && m_full) {
+ // ConstString mangled;
+ // m_full.GetMangledCounterpart(mangled);
+ // printf ("\n parsing = '%s'\n", m_full.GetCString());
+ // if (mangled)
+ // printf (" mangled = '%s'\n", mangled.GetCString());
+ m_parse_error = false;
+ m_parsed = true;
+ llvm::StringRef full(m_full.GetCString());
+
+ size_t arg_start, arg_end;
+ llvm::StringRef parens("()", 2);
+ if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
+ m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
+ if (arg_end + 1 < full.size())
+ m_qualifiers = full.substr(arg_end + 1);
+ if (arg_start > 0) {
+ size_t basename_end = arg_start;
+ size_t context_start = 0;
+ size_t context_end = llvm::StringRef::npos;
+ if (basename_end > 0 && full[basename_end - 1] == '>') {
+ // TODO: handle template junk...
+ // Templated function
+ size_t template_start, template_end;
+ llvm::StringRef lt_gt("<>", 2);
+ if (ReverseFindMatchingChars(full, lt_gt, template_start,
+ template_end, basename_end)) {
+ // Check for templated functions that include return type like:
+ // 'void foo<Int>()'
+ context_start = full.rfind(' ', template_start);
+ if (context_start == llvm::StringRef::npos)
+ context_start = 0;
else
- {
- m_parse_error = true;
- return;
- }
-
- if (!IsValidBasename(m_basename))
- {
- // The C++ basename doesn't match our regular expressions so this can't
- // be a valid C++ method, clear everything out and indicate an error
- m_context = llvm::StringRef();
- m_basename = llvm::StringRef();
- m_arguments = llvm::StringRef();
- m_qualifiers = llvm::StringRef();
- m_parse_error = true;
- }
+ ++context_start;
+
+ context_end = full.rfind(':', template_start);
+ if (context_end == llvm::StringRef::npos ||
+ context_end < context_start)
+ context_end = context_start;
+ } else {
+ context_end = full.rfind(':', basename_end);
+ }
+ } else if (context_end == llvm::StringRef::npos) {
+ context_end = full.rfind(':', basename_end);
}
- else
- {
- m_parse_error = true;
+
+ if (context_end == llvm::StringRef::npos)
+ m_basename = full.substr(0, basename_end);
+ else {
+ if (context_start < context_end)
+ m_context =
+ full.substr(context_start, context_end - 1 - context_start);
+ const size_t basename_begin = context_end + 1;
+ m_basename =
+ full.substr(basename_begin, basename_end - basename_begin);
}
+ m_type = eTypeUnknownMethod;
+ } else {
+ m_parse_error = true;
+ return;
+ }
+
+ if (!IsValidBasename(m_basename)) {
+ // The C++ basename doesn't match our regular expressions so this can't
+ // be a valid C++ method, clear everything out and indicate an error
+ m_context = llvm::StringRef();
+ m_basename = llvm::StringRef();
+ m_arguments = llvm::StringRef();
+ m_qualifiers = llvm::StringRef();
+ m_parse_error = true;
+ }
+ } else {
+ m_parse_error = true;
}
+ }
}
-llvm::StringRef
-CPlusPlusLanguage::MethodName::GetBasename ()
-{
- if (!m_parsed)
- Parse();
- return m_basename;
+llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() {
+ if (!m_parsed)
+ Parse();
+ return m_basename;
}
-llvm::StringRef
-CPlusPlusLanguage::MethodName::GetContext ()
-{
- if (!m_parsed)
- Parse();
- return m_context;
+llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() {
+ if (!m_parsed)
+ Parse();
+ return m_context;
}
-llvm::StringRef
-CPlusPlusLanguage::MethodName::GetArguments ()
-{
- if (!m_parsed)
- Parse();
- return m_arguments;
+llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() {
+ if (!m_parsed)
+ Parse();
+ return m_arguments;
}
-llvm::StringRef
-CPlusPlusLanguage::MethodName::GetQualifiers ()
-{
- if (!m_parsed)
- Parse();
- return m_qualifiers;
+llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() {
+ if (!m_parsed)
+ Parse();
+ return m_qualifiers;
}
-std::string
-CPlusPlusLanguage::MethodName::GetScopeQualifiedName ()
-{
- if (!m_parsed)
- Parse();
- if (m_basename.empty() || m_context.empty())
- return std::string();
+std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
+ if (!m_parsed)
+ Parse();
+ if (m_basename.empty() || m_context.empty())
+ return std::string();
- std::string res;
- res += m_context;
- res += "::";
- res += m_basename;
+ std::string res;
+ res += m_context;
+ res += "::";
+ res += m_basename;
- return res;
+ return res;
}
-bool
-CPlusPlusLanguage::IsCPPMangledName (const char *name)
-{
- // FIXME, we should really run through all the known C++ Language plugins and ask each one if
- // this is a C++ mangled name, but we can put that off till there is actually more than one
- // we care about.
-
- return (name != nullptr && name[0] == '_' && name[1] == 'Z');
+bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
+ // FIXME, we should really run through all the known C++ Language plugins and
+ // ask each one if
+ // this is a C++ mangled name, but we can put that off till there is actually
+ // more than one
+ // we care about.
+
+ return (name != nullptr && name[0] == '_' && name[1] == 'Z');
}
-bool
-CPlusPlusLanguage::ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier)
-{
- static RegularExpression g_basename_regex("^(([A-Za-z_][A-Za-z_0-9]*::)*)(~?[A-Za-z_~][A-Za-z_0-9]*)$");
- RegularExpression::Match match(4);
- if (g_basename_regex.Execute (name, &match))
- {
- match.GetMatchAtIndex(name, 1, context);
- match.GetMatchAtIndex(name, 3, identifier);
- return true;
- }
- return false;
+bool CPlusPlusLanguage::ExtractContextAndIdentifier(
+ const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
+ static RegularExpression g_basename_regex(llvm::StringRef(
+ "^(([A-Za-z_][A-Za-z_0-9]*::)*)(~?[A-Za-z_~][A-Za-z_0-9]*)$"));
+ RegularExpression::Match match(4);
+ if (g_basename_regex.Execute(llvm::StringRef::withNullAsEmpty(name),
+ &match)) {
+ match.GetMatchAtIndex(name, 1, context);
+ match.GetMatchAtIndex(name, 3, identifier);
+ return true;
+ }
+ return false;
}
-class CPPRuntimeEquivalents
-{
+class CPPRuntimeEquivalents {
public:
- CPPRuntimeEquivalents ()
- {
- m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("basic_string<char>"));
-
- // these two (with a prefixed std::) occur when c++stdlib string class occurs as a template argument in some STL container
- m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("std::basic_string<char>"));
-
- m_impl.Sort();
- }
-
- void
- Add (ConstString& type_name,
- ConstString& type_equivalent)
- {
- m_impl.Insert(type_name.AsCString(), type_equivalent);
- }
-
- uint32_t
- FindExactMatches (ConstString& type_name,
- std::vector<ConstString>& equivalents)
- {
- uint32_t count = 0;
-
- for (ImplData match = m_impl.FindFirstValueForName(type_name.AsCString());
- match != nullptr;
- match = m_impl.FindNextValueForName(match))
- {
- equivalents.push_back(match->value);
- count++;
- }
+ CPPRuntimeEquivalents() {
+ m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, "
+ "std::allocator<char> >")
+ .GetStringRef(),
+ ConstString("basic_string<char>"));
+
+ // these two (with a prefixed std::) occur when c++stdlib string class
+ // occurs as a template argument in some STL container
+ m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, "
+ "std::allocator<char> >")
+ .GetStringRef(),
+ ConstString("std::basic_string<char>"));
+
+ m_impl.Sort();
+ }
+
+ void Add(ConstString &type_name, ConstString &type_equivalent) {
+ m_impl.Insert(type_name.GetStringRef(), type_equivalent);
+ }
- return count;
+ uint32_t FindExactMatches(ConstString &type_name,
+ std::vector<ConstString> &equivalents) {
+ uint32_t count = 0;
+
+ for (ImplData match =
+ m_impl.FindFirstValueForName(type_name.GetStringRef());
+ match != nullptr; match = m_impl.FindNextValueForName(match)) {
+ equivalents.push_back(match->value);
+ count++;
}
-
- // partial matches can occur when a name with equivalents is a template argument.
- // e.g. we may have "class Foo" be a match for "struct Bar". if we have a typename
- // such as "class Templatized<class Foo, Anything>" we want this to be replaced with
- // "class Templatized<struct Bar, Anything>". Since partial matching is time consuming
- // once we get a partial match, we add it to the exact matches list for faster retrieval
- uint32_t
- FindPartialMatches (ConstString& type_name,
- std::vector<ConstString>& equivalents)
- {
- uint32_t count = 0;
-
- const char* type_name_cstr = type_name.AsCString();
-
- size_t items_count = m_impl.GetSize();
-
- for (size_t item = 0; item < items_count; item++)
- {
- const char* key_cstr = m_impl.GetCStringAtIndex(item);
- if ( strstr(type_name_cstr,key_cstr) )
- {
- count += AppendReplacements(type_name_cstr,
- key_cstr,
- equivalents);
- }
- }
-
- return count;
+
+ return count;
+ }
+
+ // partial matches can occur when a name with equivalents is a template
+ // argument.
+ // e.g. we may have "class Foo" be a match for "struct Bar". if we have a
+ // typename
+ // such as "class Templatized<class Foo, Anything>" we want this to be
+ // replaced with
+ // "class Templatized<struct Bar, Anything>". Since partial matching is time
+ // consuming
+ // once we get a partial match, we add it to the exact matches list for faster
+ // retrieval
+ uint32_t FindPartialMatches(ConstString &type_name,
+ std::vector<ConstString> &equivalents) {
+ uint32_t count = 0;
+
+ llvm::StringRef type_name_cstr = type_name.GetStringRef();
+
+ size_t items_count = m_impl.GetSize();
+
+ for (size_t item = 0; item < items_count; item++) {
+ llvm::StringRef key_cstr = m_impl.GetCStringAtIndex(item);
+ if (type_name_cstr.contains(key_cstr)) {
+ count += AppendReplacements(type_name_cstr, key_cstr, equivalents);
+ }
}
-
+
+ return count;
+ }
+
private:
- std::string& replace (std::string& target,
- std::string& pattern,
- std::string& with)
- {
- size_t pos;
- size_t pattern_len = pattern.size();
-
- while ( (pos = target.find(pattern)) != std::string::npos )
- target.replace(pos, pattern_len, with);
-
- return target;
- }
-
- uint32_t
- AppendReplacements (const char* original,
- const char *matching_key,
- std::vector<ConstString>& equivalents)
- {
- std::string matching_key_str(matching_key);
- ConstString original_const(original);
-
- uint32_t count = 0;
-
- for (ImplData match = m_impl.FindFirstValueForName(matching_key);
- match != nullptr;
- match = m_impl.FindNextValueForName(match))
- {
- std::string target(original);
- std::string equiv_class(match->value.AsCString());
-
- replace (target, matching_key_str, equiv_class);
-
- ConstString target_const(target.c_str());
-
-// you will most probably want to leave this off since it might make this map grow indefinitely
+ std::string &replace(std::string &target, std::string &pattern,
+ std::string &with) {
+ size_t pos;
+ size_t pattern_len = pattern.size();
+
+ while ((pos = target.find(pattern)) != std::string::npos)
+ target.replace(pos, pattern_len, with);
+
+ return target;
+ }
+
+ uint32_t AppendReplacements(llvm::StringRef original,
+ llvm::StringRef matching_key,
+ std::vector<ConstString> &equivalents) {
+ std::string matching_key_str(matching_key);
+ ConstString original_const(original);
+
+ uint32_t count = 0;
+
+ for (ImplData match = m_impl.FindFirstValueForName(matching_key);
+ match != nullptr; match = m_impl.FindNextValueForName(match)) {
+ std::string target(original);
+ std::string equiv_class(match->value.AsCString());
+
+ replace(target, matching_key_str, equiv_class);
+
+ ConstString target_const(target.c_str());
+
+// you will most probably want to leave this off since it might make this map
+// grow indefinitely
#ifdef ENABLE_CPP_EQUIVALENTS_MAP_TO_GROW
- Add(original_const, target_const);
+ Add(original_const, target_const);
#endif
- equivalents.push_back(target_const);
-
- count++;
- }
-
- return count;
+ equivalents.push_back(target_const);
+
+ count++;
}
-
- typedef UniqueCStringMap<ConstString> Impl;
- typedef const Impl::Entry* ImplData;
- Impl m_impl;
+
+ return count;
+ }
+
+ typedef UniqueCStringMap<ConstString> Impl;
+ typedef const Impl::Entry *ImplData;
+ Impl m_impl;
};
-static CPPRuntimeEquivalents&
-GetEquivalentsMap ()
-{
- static CPPRuntimeEquivalents g_equivalents_map;
- return g_equivalents_map;
+static CPPRuntimeEquivalents &GetEquivalentsMap() {
+ static CPPRuntimeEquivalents g_equivalents_map;
+ return g_equivalents_map;
}
uint32_t
-CPlusPlusLanguage::FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents)
-{
- uint32_t count = GetEquivalentsMap().FindExactMatches(type_name, equivalents);
-
- bool might_have_partials=
- ( count == 0 ) // if we have a full name match just use it
- && (strchr(type_name.AsCString(), '<') != nullptr // we should only have partial matches when templates are involved, check that we have
- && strchr(type_name.AsCString(), '>') != nullptr); // angle brackets in the type_name before trying to scan for partial matches
-
- if ( might_have_partials )
- count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents);
-
- return count;
+CPlusPlusLanguage::FindEquivalentNames(ConstString type_name,
+ std::vector<ConstString> &equivalents) {
+ uint32_t count = GetEquivalentsMap().FindExactMatches(type_name, equivalents);
+
+ bool might_have_partials =
+ (count == 0) // if we have a full name match just use it
+ && (strchr(type_name.AsCString(), '<') !=
+ nullptr // we should only have partial matches when templates are
+ // involved, check that we have
+ && strchr(type_name.AsCString(), '>') != nullptr); // angle brackets
+ // in the type_name
+ // before trying to
+ // scan for partial
+ // matches
+
+ if (might_have_partials)
+ count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents);
+
+ return count;
}
-static void
-LoadLibCxxFormatters (lldb::TypeCategoryImplSP cpp_category_sp)
-{
- if (!cpp_category_sp)
- return;
-
- TypeSummaryImpl::Flags stl_summary_flags;
- stl_summary_flags.SetCascades(true)
- .SetSkipPointers(false)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(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());
+ }
+ };
+
+ // FastDemangle will call our hook for each instance of a primitive type,
+ // allowing us to perform substitution
+ const char *const demangled =
+ FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook);
+
+ if (log)
+ log->Printf("substituted mangling for %s:{%s} %s:{%s}\n",
+ mangled.str().c_str(), demangled, output_buf.c_str(),
+ FastDemangle(output_buf.c_str()));
+
+ return output_buf == mangled ? ConstString() : ConstString(output_buf);
+}
+
+uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
+ const ConstString mangled_name, std::set<ConstString> &alternates) {
+ const auto start_size = alternates.size();
+ /// Get a basic set of alternative manglings for the given symbol `name`, by
+ /// making a few basic possible substitutions on basic types, storage duration
+ /// and `const`ness for the given symbol. The output parameter `alternates`
+ /// is filled with a best-guess, non-exhaustive set of different manglings
+ /// for the given name.
+
+ // Maybe we're looking for a const symbol but the debug info told us it was
+ // non-const...
+ if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
+ strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
+ std::string fixed_scratch("_ZNK");
+ fixed_scratch.append(mangled_name.GetCString() + 3);
+ alternates.insert(ConstString(fixed_scratch));
+ }
+
+ // Maybe we're looking for a static symbol but we thought it was global...
+ if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
+ strncmp(mangled_name.GetCString(), "_ZL", 3)) {
+ std::string fixed_scratch("_ZL");
+ fixed_scratch.append(mangled_name.GetCString() + 2);
+ alternates.insert(ConstString(fixed_scratch));
+ }
+
+ // `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"))
+ 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"))
+ 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"))
+ alternates.insert(ulong_fixup);
+
+ return alternates.size() - start_size;
+}
+
+static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
+ if (!cpp_category_sp)
+ return;
+
+ TypeSummaryImpl::Flags stl_summary_flags;
+ stl_summary_flags.SetCascades(true)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
#ifndef LLDB_DISABLE_PYTHON
- lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, "std::string summary provider"));
- lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider"));
-
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::string"),
- std_string_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::string"),
- std_string_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"),
- std_string_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >"),
- std_string_summary_sp);
-
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::wstring"),
- std_wstring_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::wstring"),
- std_wstring_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"),
- std_wstring_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<wchar_t, std::__ndk1::char_traits<wchar_t>, std::__ndk1::allocator<wchar_t> >"),
- std_wstring_summary_sp);
-
- SyntheticChildren::Flags stl_synth_flags;
- stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
-
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("^std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__(ndk)?1::map<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<std::__(ndk)?1::allocator<bool> >"), stl_synth_flags);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_synth_flags);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__(ndk)?1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, "libc++ std::initializer_list synthetic children", ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, "libc++ std::atomic synthetic children", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_synth_flags, true);
-
- cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^(std::__(ndk)?1::)deque<.+>(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
-
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", ConstString("^(std::__(ndk)?1::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
-
- stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(false);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector summary provider", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::list summary provider", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::map summary provider", ConstString("^std::__(ndk)?1::map<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::deque summary provider", ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::set summary provider", ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multiset summary provider", ConstString("^std::__(ndk)?1::multiset<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multimap summary provider", ConstString("^std::__(ndk)?1::multimap<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::unordered containers summary provider", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true);
-
- stl_summary_flags.SetSkipPointers(true);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::shared_ptr summary provider", ConstString("^std::__(ndk)?1::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::weak_ptr summary provider", ConstString("^std::__(ndk)?1::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
-
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags, true);
+ lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(
+ stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider,
+ "std::string summary provider"));
+ lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(
+ stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider,
+ "std::wstring summary provider"));
+
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__1::string"), std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__ndk1::string"), std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, "
+ "std::__1::allocator<char> >"),
+ std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__ndk1::basic_string<char, "
+ "std::__ndk1::char_traits<char>, "
+ "std::__ndk1::allocator<char> >"),
+ std_string_summary_sp);
+
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__1::wstring"), std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__ndk1::wstring"), std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__1::basic_string<wchar_t, "
+ "std::__1::char_traits<wchar_t>, "
+ "std::__1::allocator<wchar_t> >"),
+ std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__ndk1::basic_string<wchar_t, "
+ "std::__ndk1::char_traits<wchar_t>, "
+ "std::__ndk1::allocator<wchar_t> >"),
+ std_wstring_summary_sp);
+
+ SyntheticChildren::Flags stl_synth_flags;
+ stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
+ false);
+
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator,
+ "libc++ std::vector<bool> synthetic children",
+ ConstString(
+ "^std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
+ "libc++ std::vector synthetic children",
+ ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
+ "libc++ std::list synthetic children",
+ ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
+ "libc++ std::map synthetic children",
+ ConstString("^std::__(ndk)?1::map<.+> >(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator,
+ "libc++ std::vector<bool> synthetic children",
+ ConstString("std::__(ndk)?1::vector<std::__(ndk)?1::allocator<bool> >"),
+ stl_synth_flags);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator,
+ "libc++ std::vector<bool> synthetic children",
+ ConstString(
+ "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"),
+ stl_synth_flags);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
+ "libc++ std::set synthetic children",
+ ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
+ "libc++ std::multiset synthetic children",
+ ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
+ "libc++ std::multimap synthetic children",
+ ConstString("^std::__(ndk)?1::multimap<.+> >(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,
+ "libc++ std::unordered containers synthetic children",
+ ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator,
+ "libc++ std::initializer_list synthetic children",
+ ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
+ "libc++ std::atomic synthetic children",
+ ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_synth_flags, true);
+
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpressionSP(new RegularExpression(
+ llvm::StringRef("^(std::__(ndk)?1::)deque<.+>(( )?&)?$"))),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_synth_flags,
+ "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
+
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
+ "shared_ptr synthetic children",
+ ConstString("^(std::__(ndk)?1::)shared_ptr<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
+ "weak_ptr synthetic children",
+ ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags,
+ true);
+
+ stl_summary_flags.SetDontShowChildren(false);
+ stl_summary_flags.SetSkipPointers(false);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::vector<bool> summary provider",
+ ConstString(
+ "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::vector summary provider",
+ ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::list summary provider",
+ ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::map summary provider",
+ ConstString("^std::__(ndk)?1::map<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::deque summary provider",
+ ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::set summary provider",
+ ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::multiset summary provider",
+ ConstString("^std::__(ndk)?1::multiset<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::multimap summary provider",
+ ConstString("^std::__(ndk)?1::multimap<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::unordered containers summary provider",
+ ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"),
+ stl_summary_flags, true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider,
+ "libc++ std::atomic summary provider",
+ ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true);
+
+ stl_summary_flags.SetSkipPointers(true);
+
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
+ "libc++ std::shared_ptr summary provider",
+ ConstString("^std::__(ndk)?1::shared_ptr<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
+ "libc++ std::weak_ptr summary provider",
+ ConstString("^std::__(ndk)?1::weak_ptr<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,
+ "std::vector iterator synthetic children",
+ ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true);
+
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::vector<bool> summary provider",
+ ConstString(
+ "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"),
+ stl_summary_flags);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,
+ "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::__1::function<.+>$"), stl_synth_flags, true);
#endif
}
-static void
-LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
-{
- if (!cpp_category_sp)
- return;
-
- TypeSummaryImpl::Flags stl_summary_flags;
- stl_summary_flags.SetCascades(true)
- .SetSkipPointers(false)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
- lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(stl_summary_flags,
- "${var._M_dataplus._M_p}"));
-
- lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags,
- LibStdcppStringSummaryProvider,
- "libstdc++ c++11 std::string summary provider"));
- lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags,
- LibStdcppWStringSummaryProvider,
- "libstdc++ c++11 std::wstring summary provider"));
-
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
- std_string_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char>"),
- std_string_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"),
- std_string_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
- std_string_summary_sp);
-
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::string"),
- cxx11_string_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
- cxx11_string_summary_sp);
-
- // making sure we force-pick the summary for printing wstring (_M_p is a wchar_t*)
- lldb::TypeSummaryImplSP std_wstring_summary_sp(new StringSummaryFormat(stl_summary_flags,
- "${var._M_dataplus._M_p%S}"));
-
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"),
- std_wstring_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t>"),
- std_wstring_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >"),
- std_wstring_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
- std_wstring_summary_sp);
-
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::wstring"),
- cxx11_wstring_summary_sp);
- cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
- cxx11_wstring_summary_sp);
+static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
+ if (!cpp_category_sp)
+ return;
+
+ TypeSummaryImpl::Flags stl_summary_flags;
+ stl_summary_flags.SetCascades(true)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ lldb::TypeSummaryImplSP std_string_summary_sp(
+ new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}"));
+
+ lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(
+ stl_summary_flags, LibStdcppStringSummaryProvider,
+ "libstdc++ c++11 std::string summary provider"));
+ lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(
+ stl_summary_flags, LibStdcppWStringSummaryProvider,
+ "libstdc++ c++11 std::wstring summary provider"));
+
+ cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
+ std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::basic_string<char>"), std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::basic_string<char,std::char_traits<char>,std::"
+ "allocator<char> >"),
+ std_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::basic_string<char, std::char_traits<char>, "
+ "std::allocator<char> >"),
+ std_string_summary_sp);
+
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__cxx11::string"), cxx11_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, "
+ "std::allocator<char> >"),
+ cxx11_string_summary_sp);
+
+ // making sure we force-pick the summary for printing wstring (_M_p is a
+ // wchar_t*)
+ lldb::TypeSummaryImplSP std_wstring_summary_sp(
+ new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
+
+ cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"),
+ std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::basic_string<wchar_t>"), std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::"
+ "allocator<wchar_t> >"),
+ std_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, "
+ "std::allocator<wchar_t> >"),
+ std_wstring_summary_sp);
+
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__cxx11::wstring"), cxx11_wstring_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__cxx11::basic_string<wchar_t, "
+ "std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
+ cxx11_wstring_summary_sp);
#ifndef LLDB_DISABLE_PYTHON
-
- SyntheticChildren::Flags stl_synth_flags;
- stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
-
- cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
- cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
- cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
- stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
- cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
- "size=${svar%#}")));
- cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
- "size=${svar%#}")));
- cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
- "size=${svar%#}")));
-
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
-
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
-
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
- "std::shared_ptr synthetic children", ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags,
- true);
- AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
- "std::weak_ptr synthetic children", ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags,
- true);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
- "libstdc++ std::shared_ptr summary provider", ConstString("^std::shared_ptr<.+>(( )?&)?$"),
- stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
- "libstdc++ std::weak_ptr summary provider", ConstString("^std::weak_ptr<.+>(( )?&)?$"),
- stl_summary_flags, true);
+
+ SyntheticChildren::Flags stl_synth_flags;
+ stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
+ false);
+
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpressionSP(
+ new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpressionSP(
+ new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpressionSP(new RegularExpression(
+ llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
+ stl_summary_flags.SetDontShowChildren(false);
+ stl_summary_flags.SetSkipPointers(true);
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpressionSP(
+ new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpressionSP(
+ new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpressionSP(new RegularExpression(
+ llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,
+ "std::vector iterator synthetic children",
+ ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
+
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,
+ "std::map iterator synthetic children",
+ ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
+
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
+ "std::unique_ptr synthetic children",
+ ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
+ "std::shared_ptr synthetic children",
+ ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
+ "std::weak_ptr synthetic children",
+ ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator,
+ "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
+ "libstdc++ std::unique_ptr summary provider",
+ ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags,
+ true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
+ "libstdc++ std::shared_ptr summary provider",
+ ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags,
+ true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
+ "libstdc++ std::weak_ptr summary provider",
+ ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
+ true);
#endif
}
-static void
-LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
-{
- if (!cpp_category_sp)
- return;
-
- TypeSummaryImpl::Flags string_flags;
- string_flags.SetCascades(true)
- .SetSkipPointers(true)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(false)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
- TypeSummaryImpl::Flags string_array_flags;
- string_array_flags.SetCascades(true)
- .SetSkipPointers(true)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
+static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
+ if (!cpp_category_sp)
+ return;
+
+ TypeSummaryImpl::Flags string_flags;
+ string_flags.SetCascades(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(false)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ TypeSummaryImpl::Flags string_array_flags;
+ string_array_flags.SetCascades(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
#ifndef LLDB_DISABLE_PYTHON
- // FIXME because of a bug in the FormattersContainer we need to add a summary for both X* and const X* (<rdar://problem/12717717>)
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("char16_t *"), string_flags);
- AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::Char16StringSummaryProvider,
- "char16_t [] summary provider",
- ConstString("char16_t \\[[0-9]+\\]"),
- string_array_flags,
- true);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("char32_t *"), string_flags);
- AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::Char32StringSummaryProvider,
- "char32_t [] summary provider",
- ConstString("char32_t \\[[0-9]+\\]"),
- string_array_flags,
- true);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "unichar * summary provider", ConstString("unichar *"), string_flags);
-
- TypeSummaryImpl::Flags widechar_flags;
- widechar_flags.SetDontShowValue(true)
- .SetSkipPointers(true)
- .SetSkipReferences(false)
- .SetCascades(true)
- .SetDontShowChildren(true)
- .SetHideItemNames(true)
- .SetShowMembersOneLiner(false);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, "char16_t summary provider", ConstString("char16_t"), widechar_flags);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32SummaryProvider, "char32_t summary provider", ConstString("char32_t"), widechar_flags);
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider, "wchar_t summary provider", ConstString("wchar_t"), widechar_flags);
-
- AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, "unichar summary provider", ConstString("unichar"), widechar_flags);
+ // FIXME because of a bug in the FormattersContainer we need to add a summary
+ // for both X* and const X* (<rdar://problem/12717717>)
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
+ "char16_t * summary provider", ConstString("char16_t *"), string_flags);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::Char16StringSummaryProvider,
+ "char16_t [] summary provider",
+ ConstString("char16_t \\[[0-9]+\\]"), string_array_flags, true);
+
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider,
+ "char32_t * summary provider", ConstString("char32_t *"), string_flags);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::Char32StringSummaryProvider,
+ "char32_t [] summary provider",
+ ConstString("char32_t \\[[0-9]+\\]"), string_array_flags, true);
+
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider,
+ "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::WCharStringSummaryProvider,
+ "wchar_t * summary provider",
+ ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true);
+
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
+ "unichar * summary provider", ConstString("unichar *"), string_flags);
+
+ TypeSummaryImpl::Flags widechar_flags;
+ widechar_flags.SetDontShowValue(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false)
+ .SetCascades(true)
+ .SetDontShowChildren(true)
+ .SetHideItemNames(true)
+ .SetShowMembersOneLiner(false);
+
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
+ "char16_t summary provider", ConstString("char16_t"), widechar_flags);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char32SummaryProvider,
+ "char32_t summary provider", ConstString("char32_t"), widechar_flags);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,
+ "wchar_t summary provider", ConstString("wchar_t"),
+ widechar_flags);
+
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
+ "unichar summary provider", ConstString("unichar"), widechar_flags);
#endif
}
-lldb::TypeCategoryImplSP
-CPlusPlusLanguage::GetFormatters ()
-{
- static std::once_flag g_initialize;
- static TypeCategoryImplSP g_category;
-
- std::call_once(g_initialize, [this] () -> void {
- DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
- if (g_category)
- {
- LoadLibCxxFormatters(g_category);
- LoadLibStdcppFormatters(g_category);
- LoadSystemFormatters(g_category);
- }
- });
- return g_category;
+std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
+ class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
+ public:
+ virtual CompilerType AdjustForInclusion(CompilerType &candidate) override {
+ LanguageType lang_type(candidate.GetMinimumLanguage());
+ if (!Language::LanguageIsC(lang_type) &&
+ !Language::LanguageIsCPlusPlus(lang_type))
+ return CompilerType();
+ if (candidate.IsTypedefType())
+ return candidate.GetTypedefedType();
+ return candidate;
+ }
+ };
+
+ return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
+}
+
+lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
+ static std::once_flag g_initialize;
+ static TypeCategoryImplSP g_category;
+
+ std::call_once(g_initialize, [this]() -> void {
+ DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
+ if (g_category) {
+ LoadLibCxxFormatters(g_category);
+ LoadLibStdcppFormatters(g_category);
+ LoadSystemFormatters(g_category);
+ }
+ });
+ return g_category;
}
HardcodedFormatters::HardcodedSummaryFinder
-CPlusPlusLanguage::GetHardcodedSummaries ()
-{
- static std::once_flag g_initialize;
- static ConstString g_vectortypes("VectorTypes");
- static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
-
- std::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(), lldb_private::formatters::CXXFunctionPointerSummaryProvider, "Function pointer summary provider"));
- if (valobj.GetCompilerType().IsFunctionPointerType())
- {
- return formatter_sp;
- }
- return nullptr;
- });
- g_formatters.push_back(
- [](lldb_private::ValueObject& valobj,
- lldb::DynamicValueType,
- FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer {
- static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags()
- .SetCascades(true)
- .SetDontShowChildren(true)
- .SetHideItemNames(true)
- .SetShowMembersOneLiner(true)
- .SetSkipPointers(true)
- .SetSkipReferences(false),
- lldb_private::formatters::VectorTypeSummaryProvider,
- "vector_type pointer summary provider"));
- if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr))
- {
- if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
- return formatter_sp;
- }
- return nullptr;
- });
- g_formatters.push_back(
- [](lldb_private::ValueObject& valobj,
- lldb::DynamicValueType,
- FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer {
- static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags()
- .SetCascades(true)
- .SetDontShowChildren(true)
- .SetHideItemNames(true)
- .SetShowMembersOneLiner(true)
- .SetSkipPointers(true)
- .SetSkipReferences(false),
- lldb_private::formatters::BlockPointerSummaryProvider,
- "block pointer summary provider"));
- if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
- {
- return formatter_sp;
- }
- return nullptr;
- });
- });
-
- return g_formatters;
+CPlusPlusLanguage::GetHardcodedSummaries() {
+ static std::once_flag g_initialize;
+ static ConstString g_vectortypes("VectorTypes");
+ static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
+
+ std::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(),
+ lldb_private::formatters::CXXFunctionPointerSummaryProvider,
+ "Function pointer summary provider"));
+ if (valobj.GetCompilerType().IsFunctionPointerType()) {
+ return formatter_sp;
+ }
+ return nullptr;
+ });
+ g_formatters.push_back(
+ [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
+ FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
+ static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
+ new CXXFunctionSummaryFormat(
+ TypeSummaryImpl::Flags()
+ .SetCascades(true)
+ .SetDontShowChildren(true)
+ .SetHideItemNames(true)
+ .SetShowMembersOneLiner(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false),
+ lldb_private::formatters::VectorTypeSummaryProvider,
+ "vector_type pointer summary provider"));
+ if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
+ if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
+ return formatter_sp;
+ }
+ return nullptr;
+ });
+ g_formatters.push_back(
+ [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
+ FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
+ static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
+ new CXXFunctionSummaryFormat(
+ TypeSummaryImpl::Flags()
+ .SetCascades(true)
+ .SetDontShowChildren(true)
+ .SetHideItemNames(true)
+ .SetShowMembersOneLiner(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false),
+ lldb_private::formatters::BlockPointerSummaryProvider,
+ "block pointer summary provider"));
+ if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
+ return formatter_sp;
+ }
+ return nullptr;
+ });
+ });
+
+ return g_formatters;
}
HardcodedFormatters::HardcodedSyntheticFinder
-CPlusPlusLanguage::GetHardcodedSynthetics ()
-{
- static std::once_flag g_initialize;
- static ConstString g_vectortypes("VectorTypes");
- static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
-
- std::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().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true),
- "vector_type synthetic children",
- lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
- if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr))
- {
- if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
- return formatter_sp;
- }
- return nullptr;
- });
- g_formatters.push_back(
- [](lldb_private::ValueObject& valobj,
- lldb::DynamicValueType,
- FormatManager& fmt_mgr) -> SyntheticChildren::SharedPointer {
- static CXXSyntheticChildren::SharedPointer formatter_sp(new CXXSyntheticChildren(SyntheticChildren::Flags().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true),
- "block pointer synthetic children",
- lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
- if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
- {
- return formatter_sp;
- }
- return nullptr;
- });
+CPlusPlusLanguage::GetHardcodedSynthetics() {
+ static std::once_flag g_initialize;
+ static ConstString g_vectortypes("VectorTypes");
+ static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
+ std::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()
+ .SetCascades(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(true)
+ .SetNonCacheable(true),
+ "vector_type synthetic children",
+ lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
+ if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
+ if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
+ return formatter_sp;
+ }
+ return nullptr;
+ });
+ g_formatters.push_back([](lldb_private::ValueObject &valobj,
+ lldb::DynamicValueType,
+ FormatManager &
+ fmt_mgr) -> SyntheticChildren::SharedPointer {
+ static CXXSyntheticChildren::SharedPointer formatter_sp(
+ new CXXSyntheticChildren(
+ SyntheticChildren::Flags()
+ .SetCascades(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(true)
+ .SetNonCacheable(true),
+ "block pointer synthetic children",
+ lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
+ if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
+ return formatter_sp;
+ }
+ return nullptr;
});
-
- return g_formatters;
+
+ });
+
+ return g_formatters;
}
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index f0fc07e20066..be5cbae57de2 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -12,178 +12,150 @@
// C Includes
// C++ Includes
+#include <set>
#include <vector>
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class CPlusPlusLanguage :
- public Language
-{
-public:
- class MethodName
- {
- public:
- enum Type
- {
- eTypeInvalid,
- eTypeUnknownMethod,
- eTypeClassMethod,
- eTypeInstanceMethod
- };
-
- MethodName () :
- m_full(),
- m_basename(),
- m_context(),
- m_arguments(),
- m_qualifiers(),
- m_type (eTypeInvalid),
- m_parsed (false),
- m_parse_error (false)
- {
- }
-
- MethodName (const ConstString &s) :
- m_full(s),
- m_basename(),
- m_context(),
- m_arguments(),
- m_qualifiers(),
- m_type (eTypeInvalid),
- m_parsed (false),
- m_parse_error (false)
- {
- }
-
- void
- Clear();
-
- bool
- IsValid ()
- {
- if (!m_parsed)
- Parse();
- if (m_parse_error)
- return false;
- if (m_type == eTypeInvalid)
- return false;
- return (bool)m_full;
- }
-
- Type
- GetType () const
- {
- return m_type;
- }
-
- const ConstString &
- GetFullName () const
- {
- return m_full;
- }
-
- std::string
- GetScopeQualifiedName ();
-
- llvm::StringRef
- GetBasename ();
-
- llvm::StringRef
- GetContext ();
-
- llvm::StringRef
- GetArguments ();
-
- llvm::StringRef
- GetQualifiers ();
-
- protected:
- void
- Parse();
- ConstString m_full; // Full name: "lldb::SBTarget::GetBreakpointAtIndex(unsigned int) const"
- llvm::StringRef m_basename; // Basename: "GetBreakpointAtIndex"
- llvm::StringRef m_context; // Decl context: "lldb::SBTarget"
- llvm::StringRef m_arguments; // Arguments: "(unsigned int)"
- llvm::StringRef m_qualifiers; // Qualifiers: "const"
- Type m_type;
- bool m_parsed;
- bool m_parse_error;
+class CPlusPlusLanguage : public Language {
+public:
+ class MethodName {
+ public:
+ enum Type {
+ eTypeInvalid,
+ eTypeUnknownMethod,
+ eTypeClassMethod,
+ eTypeInstanceMethod
};
- CPlusPlusLanguage() = default;
+ MethodName()
+ : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers(),
+ m_type(eTypeInvalid), m_parsed(false), m_parse_error(false) {}
- ~CPlusPlusLanguage() override = default;
+ MethodName(const ConstString &s)
+ : m_full(s), m_basename(), m_context(), m_arguments(), m_qualifiers(),
+ m_type(eTypeInvalid), m_parsed(false), m_parse_error(false) {}
- lldb::LanguageType
- GetLanguageType () const override
- {
- return lldb::eLanguageTypeC_plus_plus;
+ void Clear();
+
+ bool IsValid() {
+ if (!m_parsed)
+ Parse();
+ if (m_parse_error)
+ return false;
+ if (m_type == eTypeInvalid)
+ return false;
+ return (bool)m_full;
}
-
- lldb::TypeCategoryImplSP
- GetFormatters () override;
-
- 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();
-
- static bool
- IsCPPMangledName(const char *name);
-
- // Extract C++ context and identifier from a string using heuristic matching (as opposed to
- // CPlusPlusLanguage::MethodName which has to have a fully qualified C++ name with parens and arguments.
- // If the name is a lone C identifier (e.g. C) or a qualified C identifier (e.g. A::B::C) it will return true,
- // and identifier will be the identifier (C and C respectively) and the context will be "" and "A::B::" respectively.
- // If the name fails the heuristic matching for a qualified or unqualified C/C++ identifier, then it will return false
- // and identifier and context will be unchanged.
-
- static bool
- ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier);
-
- // in some cases, compilers will output different names for one same type. when that happens, it might be impossible
- // to construct SBType objects for a valid type, because the name that is available is not the same as the name that
- // can be used as a search key in FindTypes(). the equivalents map here is meant to return possible alternative names
- // for a type through which a search can be conducted. Currently, this is only enabled for C++ but can be extended
- // to ObjC or other languages if necessary
- static uint32_t
- FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+
+ Type GetType() const { return m_type; }
+
+ const ConstString &GetFullName() const { return m_full; }
+
+ std::string GetScopeQualifiedName();
+
+ llvm::StringRef GetBasename();
+
+ llvm::StringRef GetContext();
+
+ llvm::StringRef GetArguments();
+
+ llvm::StringRef GetQualifiers();
+
+ protected:
+ void Parse();
+
+ ConstString m_full; // Full name:
+ // "lldb::SBTarget::GetBreakpointAtIndex(unsigned int)
+ // const"
+ llvm::StringRef m_basename; // Basename: "GetBreakpointAtIndex"
+ llvm::StringRef m_context; // Decl context: "lldb::SBTarget"
+ llvm::StringRef m_arguments; // Arguments: "(unsigned int)"
+ llvm::StringRef m_qualifiers; // Qualifiers: "const"
+ Type m_type;
+ bool m_parsed;
+ bool m_parse_error;
+ };
+
+ CPlusPlusLanguage() = default;
+
+ ~CPlusPlusLanguage() override = default;
+
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+
+ std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
+ lldb::TypeCategoryImplSP GetFormatters() override;
+
+ 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();
+
+ static bool IsCPPMangledName(const char *name);
+
+ // Extract C++ context and identifier from a string using heuristic matching
+ // (as opposed to
+ // CPlusPlusLanguage::MethodName which has to have a fully qualified C++ name
+ // with parens and arguments.
+ // If the name is a lone C identifier (e.g. C) or a qualified C identifier
+ // (e.g. A::B::C) it will return true,
+ // and identifier will be the identifier (C and C respectively) and the
+ // context will be "" and "A::B::" respectively.
+ // If the name fails the heuristic matching for a qualified or unqualified
+ // C/C++ identifier, then it will return false
+ // and identifier and context will be unchanged.
+
+ static bool ExtractContextAndIdentifier(const char *name,
+ llvm::StringRef &context,
+ llvm::StringRef &identifier);
+
+ // in some cases, compilers will output different names for one same type.
+ // when that happens, it might be impossible
+ // to construct SBType objects for a valid type, because the name that is
+ // available is not the same as the name that
+ // can be used as a search key in FindTypes(). the equivalents map here is
+ // meant to return possible alternative names
+ // for a type through which a search can be conducted. Currently, this is only
+ // enabled for C++ but can be extended
+ // to ObjC or other languages if necessary
+ static uint32_t FindEquivalentNames(ConstString type_name,
+ std::vector<ConstString> &equivalents);
+
+ // Given a mangled function name, calculates some alternative manglings since
+ // the compiler mangling may not line up with the symbol we are expecting
+ static uint32_t
+ FindAlternateFunctionManglings(const ConstString mangled,
+ std::set<ConstString> &candidates);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
};
-
+
} // namespace lldb_private
#endif // liblldb_CPlusPlusLanguage_h_
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index a2c45fb99893..346ea0bbd519 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -1,4 +1,4 @@
-//===-- CXXStringTypes.cpp --------------------------------------*- C++ -*-===//
+//===-- CxxStringTypes.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,209 +16,208 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Host/Endian.h"
+#include "lldb/Host/Time.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ProcessStructReader.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
#include <algorithm>
-#if __ANDROID_NDK__
-#include <sys/types.h>
-#endif
-
-#include "lldb/Host/Time.h"
-
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool
-lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
- if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
- return false;
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(valobj_addr);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken("u");
-
- if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options))
- {
- stream.Printf("Summary Unavailable");
- return true;
- }
-
+bool lldb_private::formatters::Char16StringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
+ if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(valobj_addr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u");
+
+ if (!StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options)) {
+ stream.Printf("Summary Unavailable");
return true;
+ }
+
+ return true;
}
-bool
-lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
- if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
- return false;
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(valobj_addr);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken("U");
-
- if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options))
- {
- stream.Printf("Summary Unavailable");
- return true;
- }
-
+bool lldb_private::formatters::Char32StringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
+ if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(valobj_addr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken("U");
+
+ if (!StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF32>(options)) {
+ stream.Printf("Summary Unavailable");
return true;
+ }
+
+ return true;
}
-bool
-lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
- if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
- return false;
-
- // Get a wchar_t basic type from the current type system
- CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
-
- if (!wchar_compiler_type)
- return false;
-
- const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(valobj_addr);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken("L");
-
- switch (wchar_size)
- {
- case 8:
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
- case 16:
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
- case 32:
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
- default:
- stream.Printf("size for wchar_t is not valid");
- return true;
- }
+bool lldb_private::formatters::WCharStringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
+ if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ // Get a wchar_t basic type from the current type system
+ CompilerType wchar_compiler_type =
+ valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
+
+ if (!wchar_compiler_type)
+ return false;
+
+ const uint32_t wchar_size = wchar_compiler_type.GetBitSize(
+ nullptr); // Safe to pass NULL for exe_scope here
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(valobj_addr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken("L");
+
+ switch (wchar_size) {
+ case 8:
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options);
+ case 16:
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options);
+ case 32:
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF32>(options);
+ default:
+ stream.Printf("size for wchar_t is not valid");
return true;
+ }
+ return true;
}
-bool
-lldb_private::formatters::Char16SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
-{
- DataExtractor data;
- Error error;
- valobj.GetData(data, error);
-
- if (error.Fail())
- return false;
-
- std::string value;
- valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
- if (!value.empty())
- stream.Printf("%s ", value.c_str());
-
- StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
- options.SetData(data);
- options.SetStream(&stream);
- options.SetPrefixToken("u");
- options.SetQuote('\'');
- options.SetSourceSize(1);
- options.SetBinaryZeroIsTerminator(false);
-
- return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+bool lldb_private::formatters::Char16SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ DataExtractor data;
+ Error error;
+ valobj.GetData(data, error);
+
+ if (error.Fail())
+ return false;
+
+ std::string value;
+ valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+ options.SetData(data);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u");
+ options.SetQuote('\'');
+ options.SetSourceSize(1);
+ options.SetBinaryZeroIsTerminator(false);
+
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options);
}
-bool
-lldb_private::formatters::Char32SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
-{
- DataExtractor data;
- Error error;
- valobj.GetData(data, error);
-
- if (error.Fail())
- return false;
-
- std::string value;
- valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
- if (!value.empty())
- stream.Printf("%s ", value.c_str());
-
- StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
- options.SetData(data);
- options.SetStream(&stream);
- options.SetPrefixToken("U");
- options.SetQuote('\'');
- options.SetSourceSize(1);
- options.SetBinaryZeroIsTerminator(false);
-
- return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
+bool lldb_private::formatters::Char32SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ DataExtractor data;
+ Error error;
+ valobj.GetData(data, error);
+
+ if (error.Fail())
+ return false;
+
+ std::string value;
+ valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+ options.SetData(data);
+ options.SetStream(&stream);
+ options.SetPrefixToken("U");
+ options.SetQuote('\'');
+ options.SetSourceSize(1);
+ options.SetBinaryZeroIsTerminator(false);
+
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF32>(options);
}
-bool
-lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
-{
- DataExtractor data;
- Error error;
- valobj.GetData(data, error);
-
- if (error.Fail())
- return false;
-
- // Get a wchar_t basic type from the current type system
- CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
-
- if (!wchar_compiler_type)
- return false;
-
- const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
-
- StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
- options.SetData(data);
- options.SetStream(&stream);
- options.SetPrefixToken("L");
- options.SetQuote('\'');
- options.SetSourceSize(1);
- options.SetBinaryZeroIsTerminator(false);
-
- switch (wchar_size)
- {
- case 8:
- return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
- case 16:
- return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
- case 32:
- return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
- default:
- stream.Printf("size for wchar_t is not valid");
- return true;
- }
+bool lldb_private::formatters::WCharSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ DataExtractor data;
+ Error error;
+ valobj.GetData(data, error);
+
+ if (error.Fail())
+ return false;
+
+ // Get a wchar_t basic type from the current type system
+ CompilerType wchar_compiler_type =
+ valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
+
+ if (!wchar_compiler_type)
+ return false;
+
+ const uint32_t wchar_size = wchar_compiler_type.GetBitSize(
+ nullptr); // Safe to pass NULL for exe_scope here
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+ options.SetData(data);
+ options.SetStream(&stream);
+ options.SetPrefixToken("L");
+ options.SetQuote('\'');
+ options.SetSourceSize(1);
+ options.SetBinaryZeroIsTerminator(false);
+
+ switch (wchar_size) {
+ case 8:
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options);
+ case 16:
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options);
+ case 32:
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF32>(options);
+ default:
+ stream.Printf("size for wchar_t is not valid");
return true;
+ }
+ return true;
}
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
index bfb03bda7ee0..0bee3bd3b0f2 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
@@ -1,4 +1,5 @@
-//===-- CxxStringTypes.h ----------------------------------------------*- C++ -*-===//
+//===-- CxxStringTypes.h ----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,27 +16,29 @@
#include "lldb/DataFormatters/TypeSummary.h"
namespace lldb_private {
- namespace formatters
- {
- bool
- Char16StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char16_t* and unichar*
-
- bool
- Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char32_t*
-
- bool
- WCharStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // wchar_t*
-
- bool
- Char16SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char16_t and unichar
-
- bool
- Char32SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char32_t
-
- bool
- WCharSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // wchar_t
-
- } // namespace formatters
+namespace formatters {
+bool Char16StringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char16_t* and unichar*
+
+bool Char32StringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char32_t*
+
+bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // wchar_t*
+
+bool Char16SummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char16_t and unichar
+
+bool Char32SummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char32_t
+
+bool WCharSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // wchar_t
+
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_CxxStringTypes_h_
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index beb89b89c635..82441a69b1d4 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -27,202 +27,211 @@
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ProcessStructReader.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool
-lldb_private::formatters::LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
- if (!valobj_sp)
- return false;
- ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
- ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath( {ConstString("__cntrl_"),ConstString("__shared_owners_")} ));
- ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath( {ConstString("__cntrl_"),ConstString("__shared_weak_owners_")} ));
-
- if (!ptr_sp)
- return false;
-
- if (ptr_sp->GetValueAsUnsigned(0) == 0)
- {
- stream.Printf("nullptr");
- return true;
- }
- else
- {
- bool print_pointee = false;
- Error error;
- ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
- if (pointee_sp && error.Success())
- {
- if (pointee_sp->DumpPrintableRepresentation(stream,
- ValueObject::eValueObjectRepresentationStyleSummary,
- lldb::eFormatInvalid,
- ValueObject::ePrintableRepresentationSpecialCasesDisable,
- false))
- print_pointee = true;
- }
- if (!print_pointee)
- stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
- }
-
- if (count_sp)
- stream.Printf(" strong=%" PRIu64, 1+count_sp->GetValueAsUnsigned(0));
+bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
+ ValueObjectSP ptr_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
+ ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath(
+ {ConstString("__cntrl_"), ConstString("__shared_owners_")}));
+ ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath(
+ {ConstString("__cntrl_"), ConstString("__shared_weak_owners_")}));
+
+ if (!ptr_sp)
+ return false;
- if (weakcount_sp)
- stream.Printf(" weak=%" PRIu64, 1+weakcount_sp->GetValueAsUnsigned(0));
-
+ if (ptr_sp->GetValueAsUnsigned(0) == 0) {
+ stream.Printf("nullptr");
return true;
+ } else {
+ bool print_pointee = false;
+ Error error;
+ ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
+ if (pointee_sp && error.Success()) {
+ if (pointee_sp->DumpPrintableRepresentation(
+ stream, ValueObject::eValueObjectRepresentationStyleSummary,
+ lldb::eFormatInvalid,
+ ValueObject::PrintableRepresentationSpecialCases::eDisable,
+ false))
+ print_pointee = true;
+ }
+ if (!print_pointee)
+ stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
+ }
+
+ if (count_sp)
+ stream.Printf(" strong=%" PRIu64, 1 + count_sp->GetValueAsUnsigned(0));
+
+ if (weakcount_sp)
+ stream.Printf(" weak=%" PRIu64, 1 + weakcount_sp->GetValueAsUnsigned(0));
+
+ return true;
}
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_bool_type(),
- m_exe_ctx_ref(),
- m_count(0),
- m_base_data_address(0),
- m_children()
-{
- if (valobj_sp)
- {
- Update();
- m_bool_type = valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool);
- }
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+ LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_bool_type(), m_exe_ctx_ref(),
+ m_count(0), m_base_data_address(0), m_children() {
+ if (valobj_sp) {
+ Update();
+ m_bool_type =
+ valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool);
+ }
}
-size_t
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::CalculateNumChildren ()
-{
- return m_count;
+size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+ CalculateNumChildren() {
+ return m_count;
}
lldb::ValueObjectSP
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- auto iter = m_children.find(idx),
- end = m_children.end();
- if (iter != end)
- return iter->second;
- if (idx >= m_count)
- return ValueObjectSP();
- if (m_base_data_address == 0 || m_count == 0)
- return ValueObjectSP();
- if (!m_bool_type)
- return ValueObjectSP();
- 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();
- uint8_t byte = 0;
- uint8_t mask = 0;
- Error err;
- size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
- if (err.Fail() || bytes_read == 0)
- return ValueObjectSP();
- switch (bit_index)
- {
- case 0:
- mask = 1; break;
- case 1:
- mask = 2; break;
- case 2:
- mask = 4; break;
- case 3:
- mask = 8; break;
- case 4:
- mask = 16; break;
- case 5:
- mask = 32; break;
- case 6:
- mask = 64; break;
- case 7:
- mask = 128; break;
- default:
- return ValueObjectSP();
- }
- bool bit_set = ((byte & mask) != 0);
- DataBufferSP buffer_sp(new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0));
- if (bit_set && buffer_sp && buffer_sp->GetBytes())
- *(buffer_sp->GetBytes()) = 1; // regardless of endianness, anything non-zero is true
- StreamString name; name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- ValueObjectSP retval_sp(CreateValueObjectFromData(name.GetData(), DataExtractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()), m_exe_ctx_ref, m_bool_type));
- if (retval_sp)
- m_children[idx] = retval_sp;
- return retval_sp;
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ auto iter = m_children.find(idx), end = m_children.end();
+ if (iter != end)
+ return iter->second;
+ if (idx >= m_count)
+ return ValueObjectSP();
+ if (m_base_data_address == 0 || m_count == 0)
+ return ValueObjectSP();
+ if (!m_bool_type)
+ return ValueObjectSP();
+ 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();
+ uint8_t byte = 0;
+ uint8_t mask = 0;
+ Error err;
+ size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
+ if (err.Fail() || bytes_read == 0)
+ return ValueObjectSP();
+ switch (bit_index) {
+ case 0:
+ mask = 1;
+ break;
+ case 1:
+ mask = 2;
+ break;
+ case 2:
+ mask = 4;
+ break;
+ case 3:
+ mask = 8;
+ break;
+ case 4:
+ mask = 16;
+ break;
+ case 5:
+ mask = 32;
+ break;
+ case 6:
+ mask = 64;
+ break;
+ case 7:
+ mask = 128;
+ break;
+ default:
+ return ValueObjectSP();
+ }
+ bool bit_set = ((byte & mask) != 0);
+ DataBufferSP buffer_sp(
+ new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0));
+ if (bit_set && buffer_sp && buffer_sp->GetBytes())
+ *(buffer_sp->GetBytes()) =
+ 1; // regardless of endianness, anything non-zero is true
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ ValueObjectSP retval_sp(CreateValueObjectFromData(
+ name.GetString(), DataExtractor(buffer_sp, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize()),
+ m_exe_ctx_ref, m_bool_type));
+ if (retval_sp)
+ m_children[idx] = retval_sp;
+ return retval_sp;
}
/*(std::__1::vector<std::__1::allocator<bool> >) vBool = {
__begin_ = 0x00000001001000e0
__size_ = 56
__cap_alloc_ = {
- std::__1::__libcpp_compressed_pair_imp<unsigned long, std::__1::allocator<unsigned long> > = {
+ std::__1::__libcpp_compressed_pair_imp<unsigned long,
+ std::__1::allocator<unsigned long> > = {
__first_ = 1
}
}
}*/
-bool
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update()
-{
- m_children.clear();
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- ValueObjectSP size_sp(valobj_sp->GetChildMemberWithName(ConstString("__size_"), true));
- if (!size_sp)
- return false;
- m_count = size_sp->GetValueAsUnsigned(0);
- if (!m_count)
- return true;
- ValueObjectSP begin_sp(valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true));
- if (!begin_sp)
- {
- m_count = 0;
- return false;
- }
- m_base_data_address = begin_sp->GetValueAsUnsigned(0);
- if (!m_base_data_address)
- {
- m_count = 0;
- return false;
- }
+bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() {
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ ValueObjectSP size_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__size_"), true));
+ if (!size_sp)
+ return false;
+ m_count = size_sp->GetValueAsUnsigned(0);
+ if (!m_count)
+ return true;
+ ValueObjectSP begin_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true));
+ if (!begin_sp) {
+ m_count = 0;
+ return false;
+ }
+ m_base_data_address = begin_sp->GetValueAsUnsigned(0);
+ if (!m_base_data_address) {
+ m_count = 0;
+ return false;
+ }
+ return false;
}
-bool
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- if (!m_count || !m_base_data_address)
- return UINT32_MAX;
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ if (!m_count || !m_base_data_address)
+ return UINT32_MAX;
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
}
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::~LibcxxVectorBoolSyntheticFrontEnd() = default;
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+ ~LibcxxVectorBoolSyntheticFrontEnd() = default;
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
/*
(lldb) fr var ibeg --raw --ptr-depth 1
- (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, void *> *, long> >) ibeg = {
+ (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,
+ std::__1::basic_string<char, std::__1::char_traits<char>,
+ std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int,
+ std::__1::basic_string<char, std::__1::char_traits<char>,
+ std::__1::allocator<char> > >, void *> *, long> >) ibeg = {
__i_ = {
__ptr_ = 0x0000000100103870 {
std::__1::__tree_node_base<void *> = {
@@ -238,82 +247,144 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSynthetic
second = { std::string }
*/
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_pair_ptr()
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
+ LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
+ if (valobj_sp)
+ Update();
}
-bool
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update()
-{
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
-
- TargetSP target_sp(valobj_sp->GetTargetSP());
-
- if (!target_sp)
- return false;
+bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
+ m_pair_sp.reset();
+ m_pair_ptr = nullptr;
- if (!valobj_sp)
- return false;
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ TargetSP target_sp(valobj_sp->GetTargetSP());
- // this must be a ValueObject* because it is a child of the ValueObject we are producing children for
- // it if were a ValueObjectSP, we would end up with a loop (iterator -> synthetic -> child -> parent == iterator)
- // and that would in turn leak memory by never allowing the ValueObjects to die and free their memory
- m_pair_ptr = valobj_sp->GetValueForExpressionPath(".__i_.__ptr_->__value_",
- nullptr,
- nullptr,
- nullptr,
- ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().SetSyntheticChildrenTraversal(ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None),
- nullptr).get();
-
+ if (!target_sp)
return false;
+
+ 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 that would in turn leak memory by never allowing the ValueObjects to
+ // die and free their memory
+ m_pair_ptr = valobj_sp
+ ->GetValueForExpressionPath(
+ ".__i_.__ptr_->__value_", nullptr, nullptr,
+ ValueObject::GetValueForExpressionPathOptions()
+ .DontCheckDotVsArrowSyntax()
+ .SetSyntheticChildrenTraversal(
+ ValueObject::GetValueForExpressionPathOptions::
+ SyntheticChildrenTraversal::None),
+ nullptr)
+ .get();
+
+ if (!m_pair_ptr) {
+ m_pair_ptr = valobj_sp
+ ->GetValueForExpressionPath(
+ ".__i_.__ptr_", nullptr, nullptr,
+ ValueObject::GetValueForExpressionPathOptions()
+ .DontCheckDotVsArrowSyntax()
+ .SetSyntheticChildrenTraversal(
+ ValueObject::GetValueForExpressionPathOptions::
+ SyntheticChildrenTraversal::None),
+ nullptr)
+ .get();
+ if (m_pair_ptr) {
+ auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true));
+ lldb::TemplateArgumentKind kind;
+ if (!__i_) {
+ m_pair_ptr = nullptr;
+ return false;
+ }
+ CompilerType pair_type(__i_->GetCompilerType().GetTemplateArgument(0, kind));
+ 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 (!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));
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ Error 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);
+ if (pair_sp)
+ m_pair_sp = pair_sp->GetChildAtIndex(4,true);
+ }
+ }
+ }
+
+ return false;
}
-size_t
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::CalculateNumChildren ()
-{
- return 2;
+size_t lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
+ CalculateNumChildren() {
+ return 2;
}
lldb::ValueObjectSP
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (!m_pair_ptr)
- return lldb::ValueObjectSP();
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (m_pair_ptr)
return m_pair_ptr->GetChildAtIndex(idx, true);
+ if (m_pair_sp)
+ return m_pair_sp->GetChildAtIndex(idx, true);
+ return lldb::ValueObjectSP();
}
-bool
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- if (name == ConstString("first"))
- return 0;
- if (name == ConstString("second"))
- return 1;
- return UINT32_MAX;
+size_t lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ if (name == ConstString("first"))
+ return 0;
+ if (name == ConstString("second"))
+ return 1;
+ return UINT32_MAX;
}
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::~LibCxxMapIteratorSyntheticFrontEnd ()
-{
- // this will be deleted when its parent dies (since it's a child object)
- //delete m_pair_ptr;
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
+ ~LibCxxMapIteratorSyntheticFrontEnd() {
+ // this will be deleted when its parent dies (since it's a child object)
+ // delete m_pair_ptr;
}
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
/*
@@ -325,323 +396,341 @@ lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheti
}
*/
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- static ConstString g_item_name;
- if (!g_item_name)
- g_item_name.SetCString("__i");
- return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ static ConstString g_item_name;
+ if (!g_item_name)
+ g_item_name.SetCString("__i");
+ return (valobj_sp
+ ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name)
+ : nullptr);
}
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_cntrl(nullptr),
- m_count_sp(),
- m_weak_count_sp(),
- m_ptr_size(0),
- m_byte_order(lldb::eByteOrderInvalid)
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
+ LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), m_count_sp(),
+ m_weak_count_sp(), m_ptr_size(0), m_byte_order(lldb::eByteOrderInvalid) {
+ if (valobj_sp)
+ Update();
}
-size_t
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::CalculateNumChildren ()
-{
- return (m_cntrl ? 1 : 0);
+size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
+ CalculateNumChildren() {
+ return (m_cntrl ? 1 : 0);
}
lldb::ValueObjectSP
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (!m_cntrl)
- return lldb::ValueObjectSP();
-
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (!m_cntrl)
+ return lldb::ValueObjectSP();
+
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return lldb::ValueObjectSP();
+
+ if (idx == 0)
+ return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
+
+ if (idx > 2)
+ return lldb::ValueObjectSP();
+
+ if (idx == 1) {
+ if (!m_count_sp) {
+ ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(
+ ConstString("__shared_owners_"), true));
+ if (!shared_owners_sp)
return lldb::ValueObjectSP();
-
- if (idx == 0)
- return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
-
- if (idx > 2)
- return lldb::ValueObjectSP();
-
- if (idx == 1)
- {
- if (!m_count_sp)
- {
- ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_owners_"),true));
- if (!shared_owners_sp)
- return lldb::ValueObjectSP();
- uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
- DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
- m_count_sp = CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_owners_sp->GetCompilerType());
- }
- return m_count_sp;
+ uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
+ DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
+ m_count_sp = CreateValueObjectFromData(
+ "count", data, valobj_sp->GetExecutionContextRef(),
+ shared_owners_sp->GetCompilerType());
}
- else /* if (idx == 2) */
- {
- if (!m_weak_count_sp)
- {
- ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_weak_owners_"),true));
- if (!shared_weak_owners_sp)
- return lldb::ValueObjectSP();
- uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
- DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
- m_weak_count_sp = CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_weak_owners_sp->GetCompilerType());
- }
- return m_weak_count_sp;
+ return m_count_sp;
+ } else /* if (idx == 2) */
+ {
+ if (!m_weak_count_sp) {
+ ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(
+ ConstString("__shared_weak_owners_"), true));
+ if (!shared_weak_owners_sp)
+ return lldb::ValueObjectSP();
+ uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
+ DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
+ m_weak_count_sp = CreateValueObjectFromData(
+ "count", data, valobj_sp->GetExecutionContextRef(),
+ shared_weak_owners_sp->GetCompilerType());
}
+ return m_weak_count_sp;
+ }
}
-bool
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update()
-{
- m_count_sp.reset();
- m_weak_count_sp.reset();
- m_cntrl = nullptr;
-
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
-
- TargetSP target_sp(valobj_sp->GetTargetSP());
- if (!target_sp)
- return false;
-
- m_byte_order = target_sp->GetArchitecture().GetByteOrder();
- m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize();
-
- lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"),true));
-
- m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular dependency
+bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
+ m_count_sp.reset();
+ m_weak_count_sp.reset();
+ m_cntrl = nullptr;
+
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ TargetSP target_sp(valobj_sp->GetTargetSP());
+ if (!target_sp)
return false;
+
+ m_byte_order = target_sp->GetArchitecture().GetByteOrder();
+ m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize();
+
+ lldb::ValueObjectSP cntrl_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true));
+
+ m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular
+ // dependency
+ return false;
}
-bool
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- if (name == ConstString("__ptr_"))
- return 0;
- if (name == ConstString("count"))
- return 1;
- if (name == ConstString("weak_count"))
- return 2;
- return UINT32_MAX;
+size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ if (name == ConstString("__ptr_"))
+ return 0;
+ if (name == ConstString("count"))
+ return 1;
+ if (name == ConstString("weak_count"))
+ return 2;
+ return UINT32_MAX;
}
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::~LibcxxSharedPtrSyntheticFrontEnd() = default;
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
+ ~LibcxxSharedPtrSyntheticFrontEnd() = default;
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
-bool
-lldb_private::formatters::LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- if (valobj.IsPointerType())
- {
- uint64_t value = valobj.GetValueAsUnsigned(0);
- if (!value)
- return false;
- stream.Printf("0x%016" PRIx64 " ", value);
- }
- return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr, nullptr, nullptr, &valobj, false, false);
+bool lldb_private::formatters::LibcxxContainerSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ if (valobj.IsPointerType()) {
+ uint64_t value = valobj.GetValueAsUnsigned(0);
+ if (!value)
+ return false;
+ stream.Printf("0x%016" PRIx64 " ", value);
+ }
+ return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr,
+ nullptr, nullptr, &valobj, false, false);
}
// the field layout in a libc++ string (cap, side, data or data, size, cap)
-enum LibcxxStringLayoutMode
-{
- eLibcxxStringLayoutModeCSD = 0,
- eLibcxxStringLayoutModeDSC = 1,
- eLibcxxStringLayoutModeInvalid = 0xffff
+enum LibcxxStringLayoutMode {
+ eLibcxxStringLayoutModeCSD = 0,
+ eLibcxxStringLayoutModeDSC = 1,
+ eLibcxxStringLayoutModeInvalid = 0xffff
};
// this function abstracts away the layout and mode details of a libc++ string
// and returns the address of the data and the size ready for callers to consume
-static bool
-ExtractLibcxxStringInfo (ValueObject& valobj,
- ValueObjectSP &location_sp,
- uint64_t& size)
-{
- ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0}));
- if (!D)
- return false;
-
- ValueObjectSP layout_decider(D->GetChildAtIndexPath({0,0}));
-
- // this child should exist
- if (!layout_decider)
+static bool ExtractLibcxxStringInfo(ValueObject &valobj,
+ ValueObjectSP &location_sp,
+ uint64_t &size) {
+ ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0}));
+ if (!D)
+ return false;
+
+ ValueObjectSP layout_decider(D->GetChildAtIndexPath({0, 0}));
+
+ // this child should exist
+ if (!layout_decider)
+ return false;
+
+ ConstString g_data_name("__data_");
+ ConstString g_size_name("__size_");
+ bool short_mode = false; // this means the string is in short-mode and the
+ // data is stored inline
+ LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name)
+ ? eLibcxxStringLayoutModeDSC
+ : eLibcxxStringLayoutModeCSD;
+ uint64_t size_mode_value = 0;
+
+ if (layout == eLibcxxStringLayoutModeDSC) {
+ ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0}));
+ if (!size_mode)
+ return false;
+
+ if (size_mode->GetName() != g_size_name) {
+ // we are hitting the padding structure, move along
+ size_mode = D->GetChildAtIndexPath({1, 1, 1});
+ if (!size_mode)
return false;
-
- ConstString g_data_name("__data_");
- ConstString g_size_name("__size_");
- bool short_mode = false; // this means the string is in short-mode and the data is stored inline
- LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name) ? eLibcxxStringLayoutModeDSC : eLibcxxStringLayoutModeCSD;
- uint64_t size_mode_value = 0;
-
- if (layout == eLibcxxStringLayoutModeDSC)
- {
- ValueObjectSP size_mode(D->GetChildAtIndexPath({1,1,0}));
- if (!size_mode)
- return false;
-
- if (size_mode->GetName() != g_size_name)
- {
- // we are hitting the padding structure, move along
- size_mode = D->GetChildAtIndexPath({1,1,1});
- if (!size_mode)
- return false;
- }
-
- size_mode_value = (size_mode->GetValueAsUnsigned(0));
- short_mode = ((size_mode_value & 0x80) == 0);
- }
- else
- {
- ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0}));
- if (!size_mode)
- return false;
-
- size_mode_value = (size_mode->GetValueAsUnsigned(0));
- short_mode = ((size_mode_value & 1) == 0);
- }
-
- if (short_mode)
- {
- ValueObjectSP s(D->GetChildAtIndex(1, true));
- if (!s)
- return false;
- location_sp = s->GetChildAtIndex((layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
- size = (layout == eLibcxxStringLayoutModeDSC) ? size_mode_value : ((size_mode_value >> 1) % 256);
- return (location_sp.get() != nullptr);
- }
- else
- {
- ValueObjectSP l(D->GetChildAtIndex(0, true));
- if (!l)
- return false;
- // we can use the layout_decider object as the data pointer
- location_sp = (layout == eLibcxxStringLayoutModeDSC) ? layout_decider : l->GetChildAtIndex(2, true);
- ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
- if (!size_vo || !location_sp)
- return false;
- size = size_vo->GetValueAsUnsigned(0);
- return true;
}
+
+ size_mode_value = (size_mode->GetValueAsUnsigned(0));
+ short_mode = ((size_mode_value & 0x80) == 0);
+ } else {
+ ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0}));
+ if (!size_mode)
+ return false;
+
+ size_mode_value = (size_mode->GetValueAsUnsigned(0));
+ short_mode = ((size_mode_value & 1) == 0);
+ }
+
+ if (short_mode) {
+ ValueObjectSP s(D->GetChildAtIndex(1, true));
+ if (!s)
+ return false;
+ location_sp = s->GetChildAtIndex(
+ (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
+ size = (layout == eLibcxxStringLayoutModeDSC)
+ ? size_mode_value
+ : ((size_mode_value >> 1) % 256);
+ return (location_sp.get() != nullptr);
+ } else {
+ ValueObjectSP l(D->GetChildAtIndex(0, true));
+ if (!l)
+ return false;
+ // we can use the layout_decider object as the data pointer
+ location_sp = (layout == eLibcxxStringLayoutModeDSC)
+ ? layout_decider
+ : l->GetChildAtIndex(2, true);
+ ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
+ if (!size_vo || !location_sp)
+ return false;
+ size = size_vo->GetValueAsUnsigned(0);
+ return true;
+ }
}
-bool
-lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
-{
- uint64_t size = 0;
- ValueObjectSP location_sp;
- if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
- return false;
- if (size == 0)
- {
- stream.Printf("L\"\"");
- return true;
- }
- if (!location_sp)
- return false;
-
- DataExtractor extractor;
-
- StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
-
- if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped)
- {
- const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
- if (size > max_size)
- {
- size = max_size;
- options.SetIsTruncated(true);
- }
- }
- location_sp->GetPointeeData(extractor, 0, size);
-
- // std::wstring::size() is measured in 'characters', not bytes
- auto wchar_t_size = valobj.GetTargetSP()->GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeWChar).GetByteSize(nullptr);
-
- options.SetData(extractor);
- options.SetStream(&stream);
- options.SetPrefixToken("L");
- options.SetQuote('"');
- options.SetSourceSize(size);
- options.SetBinaryZeroIsTerminator(false);
-
- switch (wchar_t_size)
- {
- case 1:
- StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF8>(options);
- break;
-
- case 2:
- lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF16>(options);
- break;
-
- case 4:
- lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF32>(options);
- break;
-
- default:
- stream.Printf("size for wchar_t is not valid");
- return true;
+bool lldb_private::formatters::LibcxxWStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ uint64_t size = 0;
+ ValueObjectSP location_sp;
+ if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
+ return false;
+ if (size == 0) {
+ stream.Printf("L\"\"");
+ return true;
+ }
+ if (!location_sp)
+ return false;
+
+ DataExtractor extractor;
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+
+ if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
+ const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
+ if (size > max_size) {
+ size = max_size;
+ options.SetIsTruncated(true);
}
-
+ }
+ location_sp->GetPointeeData(extractor, 0, size);
+
+ // std::wstring::size() is measured in 'characters', not bytes
+ auto wchar_t_size = valobj.GetTargetSP()
+ ->GetScratchClangASTContext()
+ ->GetBasicType(lldb::eBasicTypeWChar)
+ .GetByteSize(nullptr);
+
+ options.SetData(extractor);
+ options.SetStream(&stream);
+ options.SetPrefixToken("L");
+ options.SetQuote('"');
+ options.SetSourceSize(size);
+ options.SetBinaryZeroIsTerminator(false);
+
+ switch (wchar_t_size) {
+ case 1:
+ StringPrinter::ReadBufferAndDumpToStream<
+ lldb_private::formatters::StringPrinter::StringElementType::UTF8>(
+ options);
+ break;
+
+ case 2:
+ lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<
+ lldb_private::formatters::StringPrinter::StringElementType::UTF16>(
+ options);
+ break;
+
+ case 4:
+ lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<
+ lldb_private::formatters::StringPrinter::StringElementType::UTF32>(
+ options);
+ break;
+
+ default:
+ stream.Printf("size for wchar_t is not valid");
return true;
+ }
+
+ return true;
}
-bool
-lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
-{
- uint64_t size = 0;
- ValueObjectSP location_sp;
-
- if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
- return false;
-
- if (size == 0)
- {
- stream.Printf("\"\"");
- return true;
- }
-
- if (!location_sp)
- return false;
-
- StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
-
- DataExtractor extractor;
- if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped)
- {
- const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
- if (size > max_size)
- {
- size = max_size;
- options.SetIsTruncated(true);
- }
- }
- location_sp->GetPointeeData(extractor, 0, size);
-
- options.SetData(extractor);
- options.SetStream(&stream);
- options.SetPrefixToken(nullptr);
- options.SetQuote('"');
- options.SetSourceSize(size);
- options.SetBinaryZeroIsTerminator(false);
- StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
-
+bool lldb_private::formatters::LibcxxStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ uint64_t size = 0;
+ ValueObjectSP location_sp;
+
+ if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
+ return false;
+
+ if (size == 0) {
+ stream.Printf("\"\"");
return true;
+ }
+
+ if (!location_sp)
+ return false;
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+
+ DataExtractor extractor;
+ if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
+ const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
+ if (size > max_size) {
+ size = max_size;
+ options.SetIsTruncated(true);
+ }
+ }
+ location_sp->GetPointeeData(extractor, 0, size);
+
+ options.SetData(extractor);
+ options.SetStream(&stream);
+ options.SetPrefixToken(nullptr);
+ options.SetQuote('"');
+ options.SetSourceSize(size);
+ options.SetBinaryZeroIsTerminator(false);
+ StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::ASCII>(options);
+
+ return true;
+}
+
+class LibcxxFunctionFrontEnd : public SyntheticValueProviderFrontEnd {
+public:
+ LibcxxFunctionFrontEnd(ValueObject &backend)
+ : SyntheticValueProviderFrontEnd(backend) {}
+
+ lldb::ValueObjectSP GetSyntheticValue() override {
+ static ConstString g___f_("__f_");
+ return m_backend.GetChildMemberWithName(g___f_, true);
+ }
+};
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxFunctionFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new LibcxxFunctionFrontEnd(*valobj_sp);
+ return nullptr;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h
index ae00bc0ade34..a8638513376c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -1,4 +1,5 @@
-//===-- LibCxx.h ---------------------------------------------------*- C++ -*-===//
+//===-- LibCxx.h ---------------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,126 +17,133 @@
#include "lldb/DataFormatters/TypeSynthetic.h"
namespace lldb_private {
- namespace formatters
- {
-
- bool
- LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::string
-
- bool
- LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::wstring
-
- bool
- LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::shared_ptr<> and std::weak_ptr<>
-
- class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- ~LibcxxVectorBoolSyntheticFrontEnd() override;
-
- private:
- CompilerType m_bool_type;
- ExecutionContextRef m_exe_ctx_ref;
- uint64_t m_count;
- lldb::addr_t m_base_data_address;
- std::map<size_t,lldb::ValueObjectSP> m_children;
- };
-
- SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- bool
- LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- ~LibCxxMapIteratorSyntheticFrontEnd() override;
-
- private:
- ValueObject *m_pair_ptr;
- };
-
- SyntheticChildrenFrontEnd* LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- ~LibcxxSharedPtrSyntheticFrontEnd() override;
-
- private:
- ValueObject* m_cntrl;
- lldb::ValueObjectSP m_count_sp;
- lldb::ValueObjectSP m_weak_count_sp;
- uint8_t m_ptr_size;
- lldb::ByteOrder m_byte_order;
- };
-
- SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- } // namespace formatters
+namespace formatters {
+
+bool LibcxxStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libc++ std::string
+
+bool LibcxxWStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libc++ std::wstring
+
+bool LibcxxSmartPointerSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions
+ &options); // libc++ std::shared_ptr<> and std::weak_ptr<>
+
+class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+ ~LibcxxVectorBoolSyntheticFrontEnd() override;
+
+private:
+ CompilerType m_bool_type;
+ ExecutionContextRef m_exe_ctx_ref;
+ uint64_t m_count;
+ lldb::addr_t m_base_data_address;
+ std::map<size_t, lldb::ValueObjectSP> m_children;
+};
+
+SyntheticChildrenFrontEnd *
+LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+bool LibcxxContainerSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+ ~LibCxxMapIteratorSyntheticFrontEnd() override;
+
+private:
+ ValueObject *m_pair_ptr;
+ lldb::ValueObjectSP m_pair_sp;
+};
+
+SyntheticChildrenFrontEnd *
+LibCxxMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibCxxVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+ ~LibcxxSharedPtrSyntheticFrontEnd() override;
+
+private:
+ ValueObject *m_cntrl;
+ lldb::ValueObjectSP m_count_sp;
+ lldb::ValueObjectSP m_weak_count_sp;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_byte_order;
+};
+
+SyntheticChildrenFrontEnd *
+LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibcxxStdMapSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibcxxStdUnorderedMapSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_LibCxx_h_
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
index a20d7f7d9871..dea52e2f30b6 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
@@ -1,4 +1,5 @@
-//===-- LibCxxAtomic.cpp ------------------------------------------*- C++ -*-===//
+//===-- LibCxxAtomic.cpp ------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,109 +14,92 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool
-lldb_private::formatters::LibCxxAtomicSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- static ConstString g___a_("__a_");
-
- if (ValueObjectSP child = valobj.GetChildMemberWithName(g___a_, true))
- {
- std::string summary;
- if (child->GetSummaryAsCString(summary, options) && summary.size() > 0)
- {
- stream.Printf("%s", summary.c_str());
- return true;
- }
+bool lldb_private::formatters::LibCxxAtomicSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ static ConstString g___a_("__a_");
+
+ if (ValueObjectSP child = valobj.GetChildMemberWithName(g___a_, true)) {
+ std::string summary;
+ if (child->GetSummaryAsCString(summary, options) && summary.size() > 0) {
+ stream.Printf("%s", summary.c_str());
+ return true;
}
-
- return false;
+ }
+
+ return false;
}
namespace lldb_private {
- namespace formatters {
- class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxStdAtomicSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~LibcxxStdAtomicSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- lldb::ValueObjectSP
- GetSyntheticValue () override;
- private:
- ValueObject *m_real_child;
- };
- } // namespace formatters
+namespace formatters {
+class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdAtomicSyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+ lldb::ValueObjectSP GetSyntheticValue() override;
+
+private:
+ ValueObject *m_real_child;
+};
+} // namespace formatters
} // namespace lldb_private
-lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::LibcxxStdAtomicSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_real_child(nullptr)
-{
-}
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_real_child(nullptr) {}
-bool
-lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update()
-{
- static ConstString g___a_("__a_");
+bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() {
+ static ConstString g___a_("__a_");
- m_real_child = m_backend.GetChildMemberWithName(g___a_, true).get();
-
- return false;
+ m_real_child = m_backend.GetChildMemberWithName(g___a_, true).get();
+
+ return false;
}
-bool
-lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::MightHaveChildren()
-{
- return true;
+bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::CalculateNumChildren()
-{
- return m_real_child ? m_real_child->GetNumChildren() : 0;
+size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ CalculateNumChildren() {
+ return m_real_child ? m_real_child->GetNumChildren() : 0;
}
lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(size_t idx)
-{
- return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr;
+lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr;
}
-size_t
-lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name)
-{
- return m_real_child ? m_real_child->GetIndexOfChildWithName(name) : UINT32_MAX;
+size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ return m_real_child ? m_real_child->GetIndexOfChildWithName(name)
+ : UINT32_MAX;
}
-lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetSyntheticValue ()
-{
- if (m_real_child && m_real_child->CanProvideValue())
- return m_real_child->GetSP();
- return nullptr;
+lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
+ GetSyntheticValue() {
+ if (m_real_child && m_real_child->CanProvideValue())
+ return m_real_child->GetSP();
+ return nullptr;
}
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- if (valobj_sp)
- return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
- return nullptr;
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
+ return nullptr;
}
-
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
index 5cf729bfa45f..e2cc01150a2e 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
+++ b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
@@ -1,4 +1,5 @@
-//===-- LibCxxAtomic.h -------------------------------------------*- C++ -*-===//
+//===-- LibCxxAtomic.h -------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,14 +17,15 @@
#include "lldb/DataFormatters/TypeSynthetic.h"
namespace lldb_private {
- namespace formatters
- {
- bool
- LibCxxAtomicSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- SyntheticChildrenFrontEnd* LibcxxAtomicSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- } // namespace formatters
+namespace formatters {
+bool LibCxxAtomicSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd *
+LibcxxAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_LibCxxAtomic_h_
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
index 54fddd15dd0b..b7aa70c0d2e7 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
@@ -22,115 +22,108 @@ using namespace lldb_private;
using namespace lldb_private::formatters;
namespace lldb_private {
- namespace formatters {
- class LibcxxInitializerListSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~LibcxxInitializerListSyntheticFrontEnd() override;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- ValueObject* m_start;
- CompilerType m_element_type;
- uint32_t m_element_size;
- size_t m_num_elements;
- };
- } // namespace formatters
+namespace formatters {
+class LibcxxInitializerListSyntheticFrontEnd
+ : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxInitializerListSyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ ValueObject *m_start;
+ CompilerType m_element_type;
+ uint32_t m_element_size;
+ size_t m_num_elements;
+};
+} // namespace formatters
} // namespace lldb_private
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_start(nullptr),
- m_element_type(),
- m_element_size(0),
- m_num_elements(0)
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
+ LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr), m_element_type(),
+ m_element_size(0), m_num_elements(0) {
+ if (valobj_sp)
+ Update();
}
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::~LibcxxInitializerListSyntheticFrontEnd()
-{
- // this needs to stay around because it's a child object who will follow its parent's life cycle
- // delete m_start;
+lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
+ ~LibcxxInitializerListSyntheticFrontEnd() {
+ // this needs to stay around because it's a child object who will follow its
+ // parent's life cycle
+ // delete m_start;
}
-size_t
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::CalculateNumChildren ()
-{
- static ConstString g___size_("__size_");
- m_num_elements = 0;
- ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true));
- if (size_sp)
- m_num_elements = size_sp->GetValueAsUnsigned(0);
- return m_num_elements;
+size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
+ CalculateNumChildren() {
+ static ConstString g___size_("__size_");
+ m_num_elements = 0;
+ ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true));
+ if (size_sp)
+ m_num_elements = size_sp->GetValueAsUnsigned(0);
+ return m_num_elements;
}
-lldb::ValueObjectSP
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (!m_start)
- return lldb::ValueObjectSP();
-
- uint64_t offset = idx * m_element_size;
- offset = offset + m_start->GetValueAsUnsigned(0);
- StreamString name;
- name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
+lldb::ValueObjectSP lldb_private::formatters::
+ LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ if (!m_start)
+ return lldb::ValueObjectSP();
+
+ uint64_t offset = idx * m_element_size;
+ offset = offset + m_start->GetValueAsUnsigned(0);
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ return CreateValueObjectFromAddress(name.GetString(), offset,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
}
-bool
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::Update()
-{
- static ConstString g___begin_("__begin_");
-
- m_start = nullptr;
- m_num_elements = 0;
- lldb::TemplateArgumentKind kind;
- m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
- if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid())
- 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
+bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
+ Update() {
+ static ConstString g___begin_("__begin_");
+ m_start = nullptr;
+ m_num_elements = 0;
+ lldb::TemplateArgumentKind kind;
+ m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
+ if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid())
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
+
+ return false;
}
-bool
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- if (!m_start)
- return UINT32_MAX;
- return ExtractIndexFromString(name.GetCString());
+size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ if (!m_start)
+ return UINT32_MAX;
+ return ExtractIndexFromString(name.GetCString());
}
-lldb_private::SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibcxxInitializerListSyntheticFrontEnd(valobj_sp) : nullptr);
+lldb_private::SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxInitializerListSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 35cee566a773..16bd631a6c2f 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -29,380 +29,331 @@ using namespace lldb_private::formatters;
namespace {
- class ListEntry
- {
- public:
- ListEntry() = default;
- ListEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
- ListEntry(const ListEntry& rhs) = default;
- ListEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
-
- ListEntry
- next ()
- {
- if (!m_entry_sp)
- return ListEntry();
- return ListEntry(m_entry_sp->GetChildAtIndexPath({0,1}));
- }
-
- ListEntry
- prev ()
- {
- if (!m_entry_sp)
- return ListEntry();
- return ListEntry(m_entry_sp->GetChildAtIndexPath({0,0}));
- }
-
- uint64_t
- value () const
- {
- if (!m_entry_sp)
- return 0;
- return m_entry_sp->GetValueAsUnsigned(0);
- }
-
- bool
- null()
- {
- return (value() == 0);
- }
-
- explicit operator bool ()
- {
- return GetEntry() && !null();
- }
-
- ValueObjectSP
- GetEntry ()
- {
- return m_entry_sp;
- }
-
- void
- SetEntry (ValueObjectSP entry)
- {
- m_entry_sp = entry;
- }
-
- bool
- operator == (const ListEntry& rhs) const
- {
- return value() == rhs.value();
- }
-
- bool
- operator != (const ListEntry& rhs) const
- {
- return !(*this == rhs);
- }
-
- private:
- ValueObjectSP m_entry_sp;
- };
-
- class ListIterator
- {
- public:
- ListIterator() = default;
- ListIterator (ListEntry entry) : m_entry(entry) {}
- ListIterator (ValueObjectSP entry) : m_entry(entry) {}
- ListIterator(const ListIterator& rhs) = default;
- ListIterator (ValueObject* entry) : m_entry(entry) {}
-
- ValueObjectSP
- value ()
- {
- return m_entry.GetEntry();
- }
-
- ValueObjectSP
- advance (size_t count)
- {
- if (count == 0)
- return m_entry.GetEntry();
- if (count == 1)
- {
- next ();
- return m_entry.GetEntry();
- }
- while (count > 0)
- {
- next ();
- count--;
- if (m_entry.null())
- return lldb::ValueObjectSP();
- }
- return m_entry.GetEntry();
- }
-
- bool
- operator == (const ListIterator& rhs) const
- {
- return (rhs.m_entry == m_entry);
- }
-
- protected:
- void
- next ()
- {
- m_entry = m_entry.next();
- }
-
- void
- prev ()
- {
- m_entry = m_entry.prev();
- }
-
- private:
- ListEntry m_entry;
- };
+class ListEntry {
+public:
+ ListEntry() = default;
+ ListEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
+ ListEntry(const ListEntry &rhs) = default;
+ ListEntry(ValueObject *entry)
+ : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
+
+ ListEntry next() {
+ static ConstString g_next("__next_");
+
+ if (!m_entry_sp)
+ return ListEntry();
+ return ListEntry(m_entry_sp->GetChildMemberWithName(g_next, true));
+ }
+
+ ListEntry prev() {
+ static ConstString g_prev("__prev_");
+
+ if (!m_entry_sp)
+ return ListEntry();
+ return ListEntry(m_entry_sp->GetChildMemberWithName(g_prev, true));
+ }
+
+ uint64_t value() const {
+ if (!m_entry_sp)
+ return 0;
+ return m_entry_sp->GetValueAsUnsigned(0);
+ }
+
+ bool null() { return (value() == 0); }
+
+ explicit operator bool() { return GetEntry() && !null(); }
+
+ ValueObjectSP GetEntry() { return m_entry_sp; }
+
+ void SetEntry(ValueObjectSP entry) { m_entry_sp = entry; }
+
+ bool operator==(const ListEntry &rhs) const { return value() == rhs.value(); }
+
+ bool operator!=(const ListEntry &rhs) const { return !(*this == rhs); }
+
+private:
+ ValueObjectSP m_entry_sp;
+};
+
+class ListIterator {
+public:
+ ListIterator() = default;
+ ListIterator(ListEntry entry) : m_entry(entry) {}
+ ListIterator(ValueObjectSP entry) : m_entry(entry) {}
+ ListIterator(const ListIterator &rhs) = default;
+ ListIterator(ValueObject *entry) : m_entry(entry) {}
+
+ ValueObjectSP value() { return m_entry.GetEntry(); }
+
+ ValueObjectSP advance(size_t count) {
+ if (count == 0)
+ return m_entry.GetEntry();
+ if (count == 1) {
+ next();
+ return m_entry.GetEntry();
+ }
+ while (count > 0) {
+ next();
+ count--;
+ if (m_entry.null())
+ return lldb::ValueObjectSP();
+ }
+ return m_entry.GetEntry();
+ }
+
+ bool operator==(const ListIterator &rhs) const {
+ return (rhs.m_entry == m_entry);
+ }
+
+protected:
+ void next() { m_entry = m_entry.next(); }
+
+ void prev() { m_entry = m_entry.prev(); }
+
+private:
+ ListEntry m_entry;
+};
} // end anonymous namespace
namespace lldb_private {
- namespace formatters {
- class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~LibcxxStdListSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- bool
- HasLoop(size_t count);
-
- size_t m_list_capping_size;
- static const bool g_use_loop_detect = true;
-
- size_t m_loop_detected; // The number of elements that have had loop detection run over them.
- ListEntry m_slow_runner; // Used for loop detection
- ListEntry m_fast_runner; // Used for loop detection
-
- lldb::addr_t m_node_address;
- ValueObject* m_head;
- ValueObject* m_tail;
- CompilerType m_element_type;
- size_t m_count;
- std::map<size_t, ListIterator> m_iterators;
- };
- } // namespace formatters
+namespace formatters {
+class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdListSyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ bool HasLoop(size_t count);
+
+ size_t m_list_capping_size;
+ static const bool g_use_loop_detect = true;
+
+ size_t m_loop_detected; // The number of elements that have had loop detection
+ // run over them.
+ ListEntry m_slow_runner; // Used for loop detection
+ ListEntry m_fast_runner; // Used for loop detection
+
+ lldb::addr_t m_node_address;
+ ValueObject *m_head;
+ ValueObject *m_tail;
+ CompilerType m_element_type;
+ size_t m_count;
+ std::map<size_t, ListIterator> m_iterators;
+};
+} // namespace formatters
} // namespace lldb_private
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_list_capping_size(0),
- m_loop_detected(0),
- m_node_address(),
- m_head(nullptr),
- m_tail(nullptr),
- m_element_type(),
- m_count(UINT32_MAX),
- m_iterators()
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
+ LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_list_capping_size(0),
+ m_loop_detected(0), m_node_address(), m_head(nullptr), m_tail(nullptr),
+ m_element_type(), m_count(UINT32_MAX), m_iterators() {
+ if (valobj_sp)
+ Update();
}
-bool
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(size_t count)
-{
- if (!g_use_loop_detect)
- return false;
- // don't bother checking for a loop if we won't actually need to jump nodes
- if (m_count < 2)
- return false;
-
- if (m_loop_detected == 0)
- {
- // This is the first time we are being run (after the last update). Set up the loop
- // invariant for the first element.
- m_slow_runner = ListEntry(m_head).next();
- m_fast_runner = m_slow_runner.next();
- m_loop_detected = 1;
- }
+bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(
+ size_t count) {
+ if (!g_use_loop_detect)
+ return false;
+ // don't bother checking for a loop if we won't actually need to jump nodes
+ if (m_count < 2)
+ return false;
- // Loop invariant:
- // Loop detection has been run over the first m_loop_detected elements. If m_slow_runner ==
- // m_fast_runner then the loop has been detected after m_loop_detected elements.
- const size_t steps_to_run = std::min(count,m_count);
- while (m_loop_detected < steps_to_run
- && m_slow_runner
- && m_fast_runner
- && m_slow_runner != m_fast_runner) {
-
- m_slow_runner = m_slow_runner.next();
- m_fast_runner = m_fast_runner.next().next();
- m_loop_detected++;
- }
- if (count <= m_loop_detected)
- return false; // No loop in the first m_loop_detected elements.
- if (!m_slow_runner || !m_fast_runner)
- return false; // Reached the end of the list. Definitely no loops.
- return m_slow_runner == m_fast_runner;
+ if (m_loop_detected == 0) {
+ // This is the first time we are being run (after the last update). Set up
+ // the loop
+ // invariant for the first element.
+ m_slow_runner = ListEntry(m_head).next();
+ m_fast_runner = m_slow_runner.next();
+ m_loop_detected = 1;
+ }
+
+ // Loop invariant:
+ // Loop detection has been run over the first m_loop_detected elements. If
+ // m_slow_runner ==
+ // m_fast_runner then the loop has been detected after m_loop_detected
+ // elements.
+ const size_t steps_to_run = std::min(count, m_count);
+ while (m_loop_detected < steps_to_run && m_slow_runner && m_fast_runner &&
+ m_slow_runner != m_fast_runner) {
+
+ m_slow_runner = m_slow_runner.next();
+ m_fast_runner = m_fast_runner.next().next();
+ m_loop_detected++;
+ }
+ if (count <= m_loop_detected)
+ return false; // No loop in the first m_loop_detected elements.
+ if (!m_slow_runner || !m_fast_runner)
+ return false; // Reached the end of the list. Definitely no loops.
+ return m_slow_runner == m_fast_runner;
}
-size_t
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (m_count != UINT32_MAX)
- return m_count;
- if (!m_head || !m_tail || m_node_address == 0)
- return 0;
- ValueObjectSP size_alloc(m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
- if (size_alloc)
- {
- ValueObjectSP first(size_alloc->GetChildMemberWithName(ConstString("__first_"), true));
- if (first)
- {
- m_count = first->GetValueAsUnsigned(UINT32_MAX);
- }
+size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
+ CalculateNumChildren() {
+ if (m_count != UINT32_MAX)
+ return m_count;
+ if (!m_head || !m_tail || m_node_address == 0)
+ return 0;
+ ValueObjectSP size_alloc(
+ m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
+ if (size_alloc) {
+ ValueObjectSP first(
+ size_alloc->GetChildMemberWithName(ConstString("__first_"), true));
+ if (first) {
+ m_count = first->GetValueAsUnsigned(UINT32_MAX);
}
- if (m_count != UINT32_MAX)
- {
- return m_count;
- }
- else
- {
- uint64_t next_val = m_head->GetValueAsUnsigned(0);
- uint64_t prev_val = m_tail->GetValueAsUnsigned(0);
- if (next_val == 0 || prev_val == 0)
- return 0;
- if (next_val == m_node_address)
- return 0;
- if (next_val == prev_val)
- return 1;
- uint64_t size = 2;
- ListEntry current(m_head);
- while (current.next() && current.next().value() != m_node_address)
- {
- size++;
- current = current.next();
- if (size > m_list_capping_size)
- break;
- }
- return m_count = (size-1);
+ }
+ if (m_count != UINT32_MAX) {
+ return m_count;
+ } else {
+ uint64_t next_val = m_head->GetValueAsUnsigned(0);
+ uint64_t prev_val = m_tail->GetValueAsUnsigned(0);
+ if (next_val == 0 || prev_val == 0)
+ return 0;
+ if (next_val == m_node_address)
+ return 0;
+ if (next_val == prev_val)
+ return 1;
+ uint64_t size = 2;
+ ListEntry current(m_head);
+ while (current.next() && current.next().value() != m_node_address) {
+ size++;
+ current = current.next();
+ if (size > m_list_capping_size)
+ break;
}
+ return m_count = (size - 1);
+ }
}
lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
-
- if (!m_head || !m_tail || m_node_address == 0)
- return lldb::ValueObjectSP();
-
- if (HasLoop(idx+1))
- return lldb::ValueObjectSP();
-
- size_t actual_advance = idx;
-
- ListIterator current(m_head);
- if (idx > 0)
- {
- auto cached_iterator = m_iterators.find(idx-1);
- if (cached_iterator != m_iterators.end())
- {
- current = cached_iterator->second;
- actual_advance = 1;
- }
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ static ConstString g_value("__value_");
+ static ConstString g_next("__next_");
+
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+
+ if (!m_head || !m_tail || m_node_address == 0)
+ return lldb::ValueObjectSP();
+
+ if (HasLoop(idx + 1))
+ return lldb::ValueObjectSP();
+
+ size_t actual_advance = idx;
+
+ ListIterator current(m_head);
+ if (idx > 0) {
+ auto cached_iterator = m_iterators.find(idx - 1);
+ if (cached_iterator != m_iterators.end()) {
+ current = cached_iterator->second;
+ actual_advance = 1;
}
-
- ValueObjectSP current_sp(current.advance(actual_advance));
- if (!current_sp)
- return lldb::ValueObjectSP();
-
- m_iterators[idx] = current;
-
- current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child
- if (!current_sp)
- return lldb::ValueObjectSP();
- // we need to copy current_sp into a new object otherwise we will end up with all items named __value_
- DataExtractor data;
- Error error;
- current_sp->GetData(data, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
-
- StreamString name;
- name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return CreateValueObjectFromData(name.GetData(),
- data,
- m_backend.GetExecutionContextRef(),
- m_element_type);
+ }
+
+ ValueObjectSP current_sp(current.advance(actual_advance));
+ if (!current_sp)
+ return lldb::ValueObjectSP();
+
+ m_iterators[idx] = current;
+
+ current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child
+ if (!current_sp)
+ return lldb::ValueObjectSP();
+
+ if (current_sp->GetName() == g_next) {
+ ProcessSP process_sp(current_sp->GetProcessSP());
+ if (!process_sp)
+ return nullptr;
+
+ // if we grabbed the __next_ pointer, then the child is one pointer deep-er
+ lldb::addr_t addr = current_sp->GetParent()->GetPointerValue();
+ addr = addr + 2 * process_sp->GetAddressByteSize();
+ ExecutionContext exe_ctx(process_sp);
+ current_sp =
+ CreateValueObjectFromAddress("__value_", addr, exe_ctx, m_element_type);
+ }
+
+ // we need to copy current_sp into a new object otherwise we will end up with
+ // all items named __value_
+ DataExtractor data;
+ Error error;
+ current_sp->GetData(data, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ return CreateValueObjectFromData(name.GetString(), data,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
}
-bool
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update()
-{
- m_iterators.clear();
- m_head = m_tail = nullptr;
- m_node_address = 0;
- m_count = UINT32_MAX;
- m_loop_detected = 0;
- m_slow_runner.SetEntry(nullptr);
- m_fast_runner.SetEntry(nullptr);
-
- Error err;
- ValueObjectSP backend_addr(m_backend.AddressOf(err));
- m_list_capping_size = 0;
- if (m_backend.GetTargetSP())
- m_list_capping_size = m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
- if (m_list_capping_size == 0)
- m_list_capping_size = 255;
- if (err.Fail() || !backend_addr)
- return false;
- m_node_address = backend_addr->GetValueAsUnsigned(0);
- if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS)
- return false;
- ValueObjectSP impl_sp(m_backend.GetChildMemberWithName(ConstString("__end_"),true));
- if (!impl_sp)
- return false;
- CompilerType list_type = m_backend.GetCompilerType();
- if (list_type.IsReferenceType())
- list_type = list_type.GetNonReferenceType();
-
- if (list_type.GetNumTemplateArguments() == 0)
- return false;
- lldb::TemplateArgumentKind kind;
- m_element_type = list_type.GetTemplateArgument(0, kind);
- m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
- m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
+bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() {
+ m_iterators.clear();
+ m_head = m_tail = nullptr;
+ m_node_address = 0;
+ m_count = UINT32_MAX;
+ m_loop_detected = 0;
+ m_slow_runner.SetEntry(nullptr);
+ m_fast_runner.SetEntry(nullptr);
+
+ Error err;
+ ValueObjectSP backend_addr(m_backend.AddressOf(err));
+ m_list_capping_size = 0;
+ if (m_backend.GetTargetSP())
+ m_list_capping_size =
+ m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+ if (m_list_capping_size == 0)
+ m_list_capping_size = 255;
+ if (err.Fail() || !backend_addr)
+ return false;
+ m_node_address = backend_addr->GetValueAsUnsigned(0);
+ if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS)
+ return false;
+ ValueObjectSP impl_sp(
+ m_backend.GetChildMemberWithName(ConstString("__end_"), true));
+ if (!impl_sp)
+ return false;
+ CompilerType list_type = m_backend.GetCompilerType();
+ if (list_type.IsReferenceType())
+ list_type = list_type.GetNonReferenceType();
+
+ if (list_type.GetNumTemplateArguments() == 0)
return false;
+ lldb::TemplateArgumentKind kind;
+ m_element_type = list_type.GetTemplateArgument(0, kind);
+ m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
+ m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
+ return false;
}
-bool
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return ExtractIndexFromString(name.GetCString());
+size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ return ExtractIndexFromString(name.GetCString());
}
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index d89869283cd3..759a7008d3f3 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxList.cpp ------------------------------------------*- C++ -*-===//
+//===-- LibCxxMap.cpp -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -27,442 +27,428 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-class MapEntry
-{
+class MapEntry {
public:
- MapEntry() = default;
- explicit MapEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
- MapEntry(const MapEntry& rhs) = default;
- explicit MapEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
-
- ValueObjectSP
- left () const
- {
- static ConstString g_left("__left_");
- if (!m_entry_sp)
- return m_entry_sp;
- return m_entry_sp->GetChildMemberWithName(g_left, true);
- }
-
- ValueObjectSP
- right () const
- {
- static ConstString g_right("__right_");
- if (!m_entry_sp)
- return m_entry_sp;
- return m_entry_sp->GetChildMemberWithName(g_right, true);
- }
-
- ValueObjectSP
- parent () const
- {
- static ConstString g_parent("__parent_");
- if (!m_entry_sp)
- return m_entry_sp;
- return m_entry_sp->GetChildMemberWithName(g_parent, true);
- }
-
- uint64_t
- value () const
- {
- if (!m_entry_sp)
- return 0;
- return m_entry_sp->GetValueAsUnsigned(0);
- }
-
- bool
- error () const
- {
- if (!m_entry_sp)
- return true;
- return m_entry_sp->GetError().Fail();
- }
-
- bool
- null() const
- {
- return (value() == 0);
- }
-
- ValueObjectSP
- GetEntry () const
- {
- return m_entry_sp;
- }
-
- void
- SetEntry (ValueObjectSP entry)
- {
- m_entry_sp = entry;
- }
-
- bool
- operator == (const MapEntry& rhs) const
- {
- return (rhs.m_entry_sp.get() == m_entry_sp.get());
- }
-
+ MapEntry() = default;
+ explicit MapEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
+ MapEntry(const MapEntry &rhs) = default;
+ explicit MapEntry(ValueObject *entry)
+ : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
+
+ ValueObjectSP left() const {
+ static ConstString g_left("__left_");
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetSyntheticChildAtOffset(
+ 0, m_entry_sp->GetCompilerType(), true);
+ }
+
+ ValueObjectSP right() const {
+ static ConstString g_right("__right_");
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetSyntheticChildAtOffset(
+ m_entry_sp->GetProcessSP()->GetAddressByteSize(),
+ m_entry_sp->GetCompilerType(), true);
+ }
+
+ ValueObjectSP parent() const {
+ static ConstString g_parent("__parent_");
+ if (!m_entry_sp)
+ return m_entry_sp;
+ return m_entry_sp->GetSyntheticChildAtOffset(
+ 2 * m_entry_sp->GetProcessSP()->GetAddressByteSize(),
+ m_entry_sp->GetCompilerType(), true);
+ }
+
+ uint64_t value() const {
+ if (!m_entry_sp)
+ return 0;
+ return m_entry_sp->GetValueAsUnsigned(0);
+ }
+
+ bool error() const {
+ if (!m_entry_sp)
+ return true;
+ return m_entry_sp->GetError().Fail();
+ }
+
+ bool null() const { return (value() == 0); }
+
+ ValueObjectSP GetEntry() const { return m_entry_sp; }
+
+ void SetEntry(ValueObjectSP entry) { m_entry_sp = entry; }
+
+ bool operator==(const MapEntry &rhs) const {
+ return (rhs.m_entry_sp.get() == m_entry_sp.get());
+ }
+
private:
- ValueObjectSP m_entry_sp;
+ ValueObjectSP m_entry_sp;
};
-class MapIterator
-{
+class MapIterator {
public:
- MapIterator() = default;
- MapIterator (MapEntry entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {}
- MapIterator (ValueObjectSP entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {}
- MapIterator (const MapIterator& rhs) : m_entry(rhs.m_entry),m_max_depth(rhs.m_max_depth), m_error(false) {}
- MapIterator (ValueObject* entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {}
-
- ValueObjectSP
- value ()
- {
- return m_entry.GetEntry();
- }
-
- ValueObjectSP
- advance (size_t count)
- {
- ValueObjectSP fail;
- if (m_error)
- return fail;
- size_t steps = 0;
- while (count > 0)
- {
- next();
- count--, steps++;
- if (m_error ||
- m_entry.null() ||
- (steps > m_max_depth))
- return fail;
- }
- return m_entry.GetEntry();
+ MapIterator() = default;
+ MapIterator(MapEntry entry, size_t depth = 0)
+ : m_entry(entry), m_max_depth(depth), m_error(false) {}
+ MapIterator(ValueObjectSP entry, size_t depth = 0)
+ : m_entry(entry), m_max_depth(depth), m_error(false) {}
+ MapIterator(const MapIterator &rhs)
+ : m_entry(rhs.m_entry), m_max_depth(rhs.m_max_depth), m_error(false) {}
+ MapIterator(ValueObject *entry, size_t depth = 0)
+ : m_entry(entry), m_max_depth(depth), m_error(false) {}
+
+ ValueObjectSP value() { return m_entry.GetEntry(); }
+
+ ValueObjectSP advance(size_t count) {
+ ValueObjectSP fail;
+ if (m_error)
+ return fail;
+ size_t steps = 0;
+ while (count > 0) {
+ next();
+ count--, steps++;
+ if (m_error || m_entry.null() || (steps > m_max_depth))
+ return fail;
}
-
+ return m_entry.GetEntry();
+ }
+
protected:
- void
- next ()
- {
- if (m_entry.null())
- return;
- MapEntry right(m_entry.right());
- if (!right.null())
- {
- m_entry = tree_min(std::move(right));
- return;
- }
- size_t steps = 0;
- while (!is_left_child(m_entry))
- {
- if (m_entry.error())
- {
- m_error = true;
- return;
- }
- m_entry.SetEntry(m_entry.parent());
- steps++;
- if (steps > m_max_depth)
- {
- m_entry = MapEntry();
- return;
- }
- }
- m_entry = MapEntry(m_entry.parent());
+ void next() {
+ if (m_entry.null())
+ return;
+ MapEntry right(m_entry.right());
+ if (!right.null()) {
+ m_entry = tree_min(std::move(right));
+ return;
}
-
-private:
- MapEntry
- tree_min (MapEntry&& x)
- {
- if (x.null())
- return MapEntry();
- MapEntry left(x.left());
- size_t steps = 0;
- while (!left.null())
- {
- if (left.error())
- {
- m_error = true;
- return MapEntry();
- }
- x = left;
- left.SetEntry(x.left());
- steps++;
- if (steps > m_max_depth)
- return MapEntry();
- }
- return x;
+ size_t steps = 0;
+ while (!is_left_child(m_entry)) {
+ if (m_entry.error()) {
+ m_error = true;
+ return;
+ }
+ m_entry.SetEntry(m_entry.parent());
+ steps++;
+ if (steps > m_max_depth) {
+ m_entry = MapEntry();
+ return;
+ }
}
-
- bool
- is_left_child (const MapEntry& x)
- {
- if (x.null())
- return false;
- MapEntry rhs(x.parent());
- rhs.SetEntry(rhs.left());
- return x.value() == rhs.value();
+ m_entry = MapEntry(m_entry.parent());
+ }
+
+private:
+ MapEntry tree_min(MapEntry &&x) {
+ if (x.null())
+ return MapEntry();
+ MapEntry left(x.left());
+ size_t steps = 0;
+ while (!left.null()) {
+ if (left.error()) {
+ m_error = true;
+ return MapEntry();
+ }
+ x = left;
+ left.SetEntry(x.left());
+ steps++;
+ if (steps > m_max_depth)
+ return MapEntry();
}
-
- MapEntry m_entry;
- size_t m_max_depth;
- bool m_error;
+ return x;
+ }
+
+ bool is_left_child(const MapEntry &x) {
+ if (x.null())
+ return false;
+ MapEntry rhs(x.parent());
+ rhs.SetEntry(rhs.left());
+ return x.value() == rhs.value();
+ }
+
+ MapEntry m_entry;
+ size_t m_max_depth;
+ bool m_error;
};
namespace lldb_private {
- namespace formatters {
- class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~LibcxxStdMapSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- bool
- GetDataType();
-
- void
- GetValueOffset (const lldb::ValueObjectSP& node);
-
- ValueObject* m_tree;
- ValueObject* m_root_node;
- CompilerType m_element_type;
- uint32_t m_skip_size;
- size_t m_count;
- std::map<size_t, MapIterator> m_iterators;
- };
- } // namespace formatters
+namespace formatters {
+class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdMapSyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ bool GetDataType();
+
+ void GetValueOffset(const lldb::ValueObjectSP &node);
+
+ ValueObject *m_tree;
+ ValueObject *m_root_node;
+ CompilerType m_element_type;
+ uint32_t m_skip_size;
+ size_t m_count;
+ std::map<size_t, MapIterator> m_iterators;
+};
+} // namespace formatters
} // namespace lldb_private
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_tree(nullptr),
- m_root_node(nullptr),
- m_element_type(),
- m_skip_size(UINT32_MAX),
- m_count(UINT32_MAX),
- m_iterators()
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
+ LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_tree(nullptr),
+ m_root_node(nullptr), m_element_type(), m_skip_size(UINT32_MAX),
+ m_count(UINT32_MAX), m_iterators() {
+ if (valobj_sp)
+ Update();
}
-size_t
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::CalculateNumChildren ()
-{
- static ConstString g___pair3_("__pair3_");
- static ConstString g___first_("__first_");
-
- if (m_count != UINT32_MAX)
- return m_count;
- if (m_tree == nullptr)
- return 0;
- ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true));
- if (!m_item)
- return 0;
- m_item = m_item->GetChildMemberWithName(g___first_, true);
- if (!m_item)
- return 0;
- m_count = m_item->GetValueAsUnsigned(0);
+size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
+ CalculateNumChildren() {
+ static ConstString g___pair3_("__pair3_");
+ static ConstString g___first_("__first_");
+
+ if (m_count != UINT32_MAX)
return m_count;
+ if (m_tree == nullptr)
+ return 0;
+ ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true));
+ if (!m_item)
+ return 0;
+ m_item = m_item->GetChildMemberWithName(g___first_, true);
+ if (!m_item)
+ return 0;
+ m_count = m_item->GetValueAsUnsigned(0);
+ return m_count;
}
-bool
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType()
-{
- static ConstString g___value_("__value_");
-
- if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem())
- return true;
- m_element_type.Clear();
- ValueObjectSP deref;
- Error error;
- deref = m_root_node->Dereference(error);
- if (!deref || error.Fail())
- return false;
- deref = deref->GetChildMemberWithName(g___value_, true);
- if (!deref)
- return false;
+bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
+ static ConstString g___value_("__value_");
+ static ConstString g_tree_("__tree_");
+ static ConstString g_pair3("__pair3_");
+
+ if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem())
+ return true;
+ m_element_type.Clear();
+ ValueObjectSP deref;
+ Error error;
+ deref = m_root_node->Dereference(error);
+ if (!deref || error.Fail())
+ return false;
+ deref = deref->GetChildMemberWithName(g___value_, true);
+ if (deref) {
m_element_type = deref->GetCompilerType();
return true;
+ }
+ lldb::TemplateArgumentKind kind;
+ deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3});
+ if (!deref)
+ return false;
+ m_element_type =
+ deref->GetCompilerType().GetTemplateArgument(1, kind).GetTemplateArgument(
+ 1, kind);
+ if (m_element_type) {
+ std::string name;
+ uint64_t bit_offset_ptr;
+ uint32_t bitfield_bit_size_ptr;
+ bool is_bitfield_ptr;
+ m_element_type = m_element_type.GetFieldAtIndex(
+ 0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
+ m_element_type = m_element_type.GetTypedefedType();
+ return m_element_type.IsValid();
+ } else {
+ m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
+ return m_element_type.IsValid();
+ }
}
-void
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset (const lldb::ValueObjectSP& node)
-{
- if (m_skip_size != UINT32_MAX)
- return;
- if (!node)
- return;
- CompilerType node_type(node->GetCompilerType());
- uint64_t bit_offset;
- if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) == UINT32_MAX)
- return;
+void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
+ const lldb::ValueObjectSP &node) {
+ if (m_skip_size != UINT32_MAX)
+ return;
+ if (!node)
+ return;
+ CompilerType node_type(node->GetCompilerType());
+ uint64_t bit_offset;
+ if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) !=
+ UINT32_MAX) {
m_skip_size = bit_offset / 8u;
+ } else {
+ ClangASTContext *ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(node_type.GetTypeSystem());
+ if (!ast_ctx)
+ return;
+ 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", (m_element_type.GetCompleteType(), m_element_type)}});
+ std::string child_name;
+ uint32_t child_byte_size;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size;
+ uint32_t child_bitfield_bit_offset;
+ bool child_is_base_class;
+ bool child_is_deref_of_parent;
+ uint64_t language_flags;
+ if (tree_node_type
+ .GetChildCompilerTypeAtIndex(
+ nullptr, 4, true, true, true, child_name, child_byte_size,
+ child_byte_offset, child_bitfield_bit_size,
+ child_bitfield_bit_offset, child_is_base_class,
+ child_is_deref_of_parent, nullptr, language_flags)
+ .IsValid())
+ m_skip_size = (uint32_t)child_byte_offset;
+ }
}
lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- static ConstString g___cc("__cc");
- static ConstString g___nc("__nc");
- static ConstString g___value_("__value_");
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ static ConstString g___cc("__cc");
+ static ConstString g___nc("__nc");
+ static ConstString g___value_("__value_");
+
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+ if (m_tree == nullptr || m_root_node == nullptr)
+ return lldb::ValueObjectSP();
+
+ MapIterator iterator(m_root_node, CalculateNumChildren());
- if (idx >= CalculateNumChildren())
+ const bool need_to_skip = (idx > 0);
+ size_t actual_advancde = idx;
+ if (need_to_skip) {
+ auto cached_iterator = m_iterators.find(idx - 1);
+ if (cached_iterator != m_iterators.end()) {
+ iterator = cached_iterator->second;
+ actual_advancde = 1;
+ }
+ }
+
+ ValueObjectSP iterated_sp(iterator.advance(actual_advancde));
+ if (!iterated_sp) {
+ // this tree is garbage - stop
+ m_tree =
+ nullptr; // this will stop all future searches until an Update() happens
+ return iterated_sp;
+ }
+ if (GetDataType()) {
+ if (!need_to_skip) {
+ Error error;
+ iterated_sp = iterated_sp->Dereference(error);
+ if (!iterated_sp || error.Fail()) {
+ m_tree = nullptr;
return lldb::ValueObjectSP();
- if (m_tree == nullptr || m_root_node == nullptr)
+ }
+ GetValueOffset(iterated_sp);
+ auto child_sp = iterated_sp->GetChildMemberWithName(g___value_, true);
+ if (child_sp)
+ iterated_sp = child_sp;
+ else
+ iterated_sp = iterated_sp->GetSyntheticChildAtOffset(
+ m_skip_size, m_element_type, true);
+ if (!iterated_sp) {
+ m_tree = nullptr;
return lldb::ValueObjectSP();
-
- MapIterator iterator(m_root_node, CalculateNumChildren());
-
- const bool need_to_skip = (idx > 0);
- size_t actual_advancde = idx;
- if (need_to_skip)
- {
- auto cached_iterator = m_iterators.find(idx-1);
- if (cached_iterator != m_iterators.end())
- {
- iterator = cached_iterator->second;
- actual_advancde = 1;
- }
- }
-
- ValueObjectSP iterated_sp(iterator.advance(actual_advancde));
- if (!iterated_sp)
- {
- // this tree is garbage - stop
- m_tree = nullptr; // this will stop all future searches until an Update() happens
- return iterated_sp;
- }
- if (GetDataType())
- {
- if (!need_to_skip)
- {
- Error error;
- iterated_sp = iterated_sp->Dereference(error);
- if (!iterated_sp || error.Fail())
- {
- m_tree = nullptr;
- return lldb::ValueObjectSP();
- }
- GetValueOffset(iterated_sp);
- iterated_sp = iterated_sp->GetChildMemberWithName(g___value_, true);
- if (!iterated_sp)
- {
- m_tree = nullptr;
- return lldb::ValueObjectSP();
- }
- }
- else
- {
- // because of the way our debug info is made, we need to read item 0 first
- // so that we can cache information used to generate other elements
- if (m_skip_size == UINT32_MAX)
- GetChildAtIndex(0);
- if (m_skip_size == UINT32_MAX)
- {
- m_tree = nullptr;
- return lldb::ValueObjectSP();
- }
- iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, m_element_type, true);
- if (!iterated_sp)
- {
- m_tree = nullptr;
- return lldb::ValueObjectSP();
- }
- }
- }
- else
- {
+ }
+ } else {
+ // because of the way our debug info is made, we need to read item 0 first
+ // so that we can cache information used to generate other elements
+ if (m_skip_size == UINT32_MAX)
+ GetChildAtIndex(0);
+ if (m_skip_size == UINT32_MAX) {
m_tree = nullptr;
return lldb::ValueObjectSP();
- }
- // at this point we have a valid
- // we need to copy current_sp into a new object otherwise we will end up with all items named __value_
- DataExtractor data;
- Error error;
- iterated_sp->GetData(data, error);
- if (error.Fail())
- {
+ }
+ iterated_sp = iterated_sp->GetSyntheticChildAtOffset(
+ m_skip_size, m_element_type, true);
+ if (!iterated_sp) {
m_tree = nullptr;
return lldb::ValueObjectSP();
+ }
}
- StreamString name;
- name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- auto potential_child_sp = CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type);
- if (potential_child_sp)
- {
- switch (potential_child_sp->GetNumChildren())
- {
- case 1:
- {
- auto child0_sp = potential_child_sp->GetChildAtIndex(0, true);
- if (child0_sp && child0_sp->GetName() == g___cc)
- potential_child_sp = child0_sp;
- break;
- }
- case 2:
- {
- auto child0_sp = potential_child_sp->GetChildAtIndex(0, true);
- auto child1_sp = potential_child_sp->GetChildAtIndex(1, true);
- if (child0_sp && child0_sp->GetName() == g___cc &&
- child1_sp && child1_sp->GetName() == g___nc)
- potential_child_sp = child0_sp;
- break;
- }
- }
- potential_child_sp->SetName(ConstString(name.GetData()));
+ } else {
+ m_tree = nullptr;
+ return lldb::ValueObjectSP();
+ }
+ // at this point we have a valid
+ // we need to copy current_sp into a new object otherwise we will end up with
+ // all items named __value_
+ DataExtractor data;
+ Error error;
+ iterated_sp->GetData(data, error);
+ if (error.Fail()) {
+ m_tree = nullptr;
+ return lldb::ValueObjectSP();
+ }
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ auto potential_child_sp = CreateValueObjectFromData(
+ name.GetString(), data, m_backend.GetExecutionContextRef(),
+ m_element_type);
+ if (potential_child_sp) {
+ switch (potential_child_sp->GetNumChildren()) {
+ case 1: {
+ auto child0_sp = potential_child_sp->GetChildAtIndex(0, true);
+ if (child0_sp && child0_sp->GetName() == g___cc)
+ potential_child_sp = child0_sp;
+ break;
}
- m_iterators[idx] = iterator;
- return potential_child_sp;
+ case 2: {
+ auto child0_sp = potential_child_sp->GetChildAtIndex(0, true);
+ auto child1_sp = potential_child_sp->GetChildAtIndex(1, true);
+ if (child0_sp && child0_sp->GetName() == g___cc && child1_sp &&
+ child1_sp->GetName() == g___nc)
+ potential_child_sp = child0_sp;
+ break;
+ }
+ }
+ potential_child_sp->SetName(ConstString(name.GetString()));
+ }
+ m_iterators[idx] = iterator;
+ return potential_child_sp;
}
-bool
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update()
-{
- static ConstString g___tree_("__tree_");
- static ConstString g___begin_node_("__begin_node_");
- m_count = UINT32_MAX;
- m_tree = m_root_node = nullptr;
- m_iterators.clear();
- m_tree = m_backend.GetChildMemberWithName(g___tree_, true).get();
- if (!m_tree)
- return false;
- m_root_node = m_tree->GetChildMemberWithName(g___begin_node_, true).get();
+bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update() {
+ static ConstString g___tree_("__tree_");
+ static ConstString g___begin_node_("__begin_node_");
+ m_count = UINT32_MAX;
+ m_tree = m_root_node = nullptr;
+ m_iterators.clear();
+ m_tree = m_backend.GetChildMemberWithName(g___tree_, true).get();
+ if (!m_tree)
return false;
+ m_root_node = m_tree->GetChildMemberWithName(g___begin_node_, true).get();
+ return false;
}
-bool
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return ExtractIndexFromString(name.GetCString());
+size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ return ExtractIndexFromString(name.GetCString());
}
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibcxxStdMapSyntheticFrontEnd(valobj_sp) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxStdMapSyntheticFrontEnd(valobj_sp) : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index a547695448ce..5fe4b3a9fc9e 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -28,136 +28,162 @@ using namespace lldb_private;
using namespace lldb_private::formatters;
namespace lldb_private {
- namespace formatters {
- class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~LibcxxStdUnorderedMapSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- ValueObject* m_tree;
- size_t m_num_elements;
- ValueObject* m_next_element;
- std::vector<std::pair<ValueObject*, uint64_t> > m_elements_cache;
- };
- } // namespace formatters
+namespace formatters {
+class LibcxxStdUnorderedMapSyntheticFrontEnd
+ : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxStdUnorderedMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdUnorderedMapSyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ CompilerType m_element_type;
+ CompilerType m_node_type;
+ ValueObject *m_tree;
+ size_t m_num_elements;
+ ValueObject *m_next_element;
+ std::vector<std::pair<ValueObject *, uint64_t>> m_elements_cache;
+};
+} // namespace formatters
} // namespace lldb_private
-lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_tree(nullptr),
- m_num_elements(0),
- m_next_element(nullptr),
- m_elements_cache()
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
+ LibcxxStdUnorderedMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type(), m_tree(nullptr),
+ m_num_elements(0), m_next_element(nullptr), m_elements_cache() {
+ if (valobj_sp)
+ Update();
}
-size_t
-lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (m_num_elements != UINT32_MAX)
- return m_num_elements;
- return 0;
+size_t lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
+ CalculateNumChildren() {
+ if (m_num_elements != UINT32_MAX)
+ return m_num_elements;
+ return 0;
}
-lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
- if (m_tree == nullptr)
- return lldb::ValueObjectSP();
-
- while (idx >= m_elements_cache.size())
- {
- if (m_next_element == nullptr)
- return lldb::ValueObjectSP();
-
- Error error;
- ValueObjectSP node_sp = m_next_element->Dereference(error);
- if (!node_sp || error.Fail())
- return lldb::ValueObjectSP();
-
- ValueObjectSP value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true);
- ValueObjectSP hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
- if (!hash_sp || !value_sp)
- return lldb::ValueObjectSP();
- m_elements_cache.push_back({value_sp.get(),hash_sp->GetValueAsUnsigned(0)});
- m_next_element = node_sp->GetChildMemberWithName(ConstString("__next_"),true).get();
- if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0)
- m_next_element = nullptr;
- }
-
- std::pair<ValueObject*, uint64_t> val_hash = m_elements_cache[idx];
- if (!val_hash.first)
- return lldb::ValueObjectSP();
- StreamString stream;
- stream.Printf("[%" PRIu64 "]", (uint64_t)idx);
- DataExtractor data;
+lldb::ValueObjectSP lldb_private::formatters::
+ LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+ if (m_tree == nullptr)
+ return lldb::ValueObjectSP();
+
+ while (idx >= m_elements_cache.size()) {
+ if (m_next_element == nullptr)
+ return lldb::ValueObjectSP();
+
Error error;
- val_hash.first->GetData(data, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
- const bool thread_and_frame_only_if_stopped = true;
- ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
- return CreateValueObjectFromData(stream.GetData(),
- data,
- exe_ctx,
- val_hash.first->GetCompilerType());
+ ValueObjectSP node_sp = m_next_element->Dereference(error);
+ if (!node_sp || error.Fail())
+ return lldb::ValueObjectSP();
+
+ ValueObjectSP value_sp =
+ node_sp->GetChildMemberWithName(ConstString("__value_"), true);
+ ValueObjectSP hash_sp =
+ node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
+ if (!hash_sp || !value_sp) {
+ if (!m_element_type) {
+ auto first_sp = m_backend.GetChildAtNamePath({ConstString("__table_"),
+ ConstString("__p1_"),
+ ConstString("__first_")});
+ if (!first_sp)
+ return nullptr;
+ m_element_type = first_sp->GetCompilerType();
+ lldb::TemplateArgumentKind kind;
+ m_element_type = m_element_type.GetTemplateArgument(0, kind);
+ m_element_type = m_element_type.GetPointeeType();
+ m_node_type = m_element_type;
+ m_element_type = m_element_type.GetTemplateArgument(0, kind);
+ std::string name;
+ m_element_type =
+ m_element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);
+ m_element_type = m_element_type.GetTypedefedType();
+ }
+ if (!m_node_type)
+ return nullptr;
+ node_sp = node_sp->Cast(m_node_type);
+ value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true);
+ hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
+ if (!value_sp || !hash_sp)
+ return nullptr;
+ }
+ m_elements_cache.push_back(
+ {value_sp.get(), hash_sp->GetValueAsUnsigned(0)});
+ m_next_element =
+ node_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
+ if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0)
+ m_next_element = nullptr;
+ }
+
+ std::pair<ValueObject *, uint64_t> val_hash = m_elements_cache[idx];
+ if (!val_hash.first)
+ return lldb::ValueObjectSP();
+ StreamString stream;
+ stream.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ DataExtractor data;
+ Error error;
+ val_hash.first->GetData(data, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+ const bool thread_and_frame_only_if_stopped = true;
+ ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(
+ thread_and_frame_only_if_stopped);
+ return CreateValueObjectFromData(stream.GetString(), data, exe_ctx,
+ val_hash.first->GetCompilerType());
}
-bool
-lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update()
-{
- m_num_elements = UINT32_MAX;
- m_next_element = nullptr;
- m_elements_cache.clear();
- ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true);
- if (!table_sp)
- return false;
- ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath({ConstString("__p2_"),ConstString("__first_")});
- if (!num_elements_sp)
- return false;
- m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
- m_tree = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
- if (m_num_elements > 0)
- m_next_element = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
+bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
+ Update() {
+ m_num_elements = UINT32_MAX;
+ m_next_element = nullptr;
+ m_elements_cache.clear();
+ ValueObjectSP table_sp =
+ m_backend.GetChildMemberWithName(ConstString("__table_"), true);
+ if (!table_sp)
+ return false;
+ ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath(
+ {ConstString("__p2_"), ConstString("__first_")});
+ if (!num_elements_sp)
return false;
+ m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
+ m_tree =
+ table_sp
+ ->GetChildAtNamePath({ConstString("__p1_"), ConstString("__first_"),
+ ConstString("__next_")})
+ .get();
+ if (m_num_elements > 0)
+ m_next_element =
+ table_sp
+ ->GetChildAtNamePath({ConstString("__p1_"), ConstString("__first_"),
+ ConstString("__next_")})
+ .get();
+ return false;
}
-bool
-lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return ExtractIndexFromString(name.GetCString());
+size_t lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ return ExtractIndexFromString(name.GetCString());
}
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
index ed26eaea121c..b5c9b6d0f11e 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
@@ -22,130 +22,120 @@ using namespace lldb_private;
using namespace lldb_private::formatters;
namespace lldb_private {
- namespace formatters {
- class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~LibcxxStdVectorSyntheticFrontEnd() override;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- ValueObject* m_start;
- ValueObject* m_finish;
- CompilerType m_element_type;
- uint32_t m_element_size;
- };
- } // namespace formatters
+namespace formatters {
+class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdVectorSyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ ValueObject *m_start;
+ ValueObject *m_finish;
+ CompilerType m_element_type;
+ uint32_t m_element_size;
+};
+} // namespace formatters
} // namespace lldb_private
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_start(nullptr),
- m_finish(nullptr),
- m_element_type(),
- m_element_size(0)
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
+ LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr),
+ m_finish(nullptr), m_element_type(), m_element_size(0) {
+ if (valobj_sp)
+ Update();
}
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd()
-{
- // these need to stay around because they are child objects who will follow their parent's life cycle
- // delete m_start;
- // delete m_finish;
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
+ ~LibcxxStdVectorSyntheticFrontEnd() {
+ // these need to stay around because they are child objects who will follow
+ // their parent's life cycle
+ // delete m_start;
+ // delete m_finish;
}
-size_t
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (!m_start || !m_finish)
- return 0;
- uint64_t start_val = m_start->GetValueAsUnsigned(0);
- uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
-
- if (start_val == 0 || finish_val == 0)
- return 0;
-
- if (start_val >= finish_val)
- return 0;
-
- size_t num_children = (finish_val - start_val);
- if (num_children % m_element_size)
- return 0;
- return num_children/m_element_size;
+size_t lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
+ CalculateNumChildren() {
+ if (!m_start || !m_finish)
+ return 0;
+ uint64_t start_val = m_start->GetValueAsUnsigned(0);
+ uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
+
+ if (start_val == 0 || finish_val == 0)
+ return 0;
+
+ if (start_val >= finish_val)
+ return 0;
+
+ size_t num_children = (finish_val - start_val);
+ if (num_children % m_element_size)
+ return 0;
+ return num_children / m_element_size;
}
lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (!m_start || !m_finish)
- return lldb::ValueObjectSP();
-
- uint64_t offset = idx * m_element_size;
- offset = offset + m_start->GetValueAsUnsigned(0);
- StreamString name;
- name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return CreateValueObjectFromAddress(name.GetData(),
- offset,
- m_backend.GetExecutionContextRef(),
- m_element_type);
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (!m_start || !m_finish)
+ return lldb::ValueObjectSP();
+
+ uint64_t offset = idx * m_element_size;
+ offset = offset + m_start->GetValueAsUnsigned(0);
+ StreamString name;
+ name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ return CreateValueObjectFromAddress(name.GetString(), offset,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
}
-bool
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
-{
- m_start = m_finish = nullptr;
- ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
- if (!data_type_finder_sp)
- return false;
- data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
- 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();
- }
+bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() {
+ m_start = m_finish = nullptr;
+ ValueObjectSP data_type_finder_sp(
+ m_backend.GetChildMemberWithName(ConstString("__end_cap_"), true));
+ if (!data_type_finder_sp)
+ return false;
+ data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(
+ ConstString("__first_"), true);
+ 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();
+ }
+ return false;
}
-bool
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
-size_t
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- if (!m_start || !m_finish)
- return UINT32_MAX;
- return ExtractIndexFromString(name.GetCString());
+size_t lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ if (!m_start || !m_finish)
+ return UINT32_MAX;
+ return ExtractIndexFromString(name.GetCString());
}
-lldb_private::SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp) : nullptr);
+lldb_private::SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index 6d6f915f68e2..f931a8d6a046 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -28,449 +28,404 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-namespace
-{
-
-class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
- /*
- (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ibeg = {
- (_Base_ptr) _M_node = 0x0000000100103910 {
- (std::_Rb_tree_color) _M_color = _S_black
- (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0
- (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000
- (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000
- }
- }
- */
+namespace {
+
+class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+ /*
+ (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char,
+ std::char_traits<char>, std::allocator<char> > > >) ibeg = {
+ (_Base_ptr) _M_node = 0x0000000100103910 {
+ (std::_Rb_tree_color) _M_color = _S_black
+ (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0
+ (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000
+ (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000
+ }
+ }
+ */
public:
- explicit LibstdcppMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName (const ConstString &name) override;
-
+ explicit LibstdcppMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
private:
- ExecutionContextRef m_exe_ctx_ref;
- lldb::addr_t m_pair_address;
- CompilerType m_pair_type;
- lldb::ValueObjectSP m_pair_sp;
+ ExecutionContextRef m_exe_ctx_ref;
+ lldb::addr_t m_pair_address;
+ CompilerType m_pair_type;
+ lldb::ValueObjectSP m_pair_sp;
};
-class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+ explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
- size_t
- CalculateNumChildren() override;
+ size_t CalculateNumChildren() override;
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
- bool
- Update() override;
+ bool Update() override;
- bool
- MightHaveChildren() override;
+ bool MightHaveChildren() override;
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
};
} // end of anonymous namespace
-LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_exe_ctx_ref(),
- m_pair_address(0),
- m_pair_type(),
- m_pair_sp()
-{
- if (valobj_sp)
- Update();
+LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_address(0),
+ m_pair_type(), m_pair_sp() {
+ if (valobj_sp)
+ Update();
}
-bool
-LibstdcppMapIteratorSyntheticFrontEnd::Update()
-{
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
-
- TargetSP target_sp(valobj_sp->GetTargetSP());
-
- if (!target_sp)
- return false;
-
- bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8);
-
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-
- ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true));
- if (!_M_node_sp)
- return false;
-
- m_pair_address = _M_node_sp->GetValueAsUnsigned(0);
- if (m_pair_address == 0)
- return false;
-
- m_pair_address += (is_64bit ? 32 : 16);
-
- CompilerType my_type(valobj_sp->GetCompilerType());
- if (my_type.GetNumTemplateArguments() >= 1)
- {
- TemplateArgumentKind kind;
- CompilerType pair_type = my_type.GetTemplateArgument(0, kind);
- if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion)
- return false;
- m_pair_type = pair_type;
- }
- else
- return false;
-
- return true;
+bool LibstdcppMapIteratorSyntheticFrontEnd::Update() {
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ TargetSP target_sp(valobj_sp->GetTargetSP());
+
+ if (!target_sp)
+ return false;
+
+ bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8);
+
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+
+ ValueObjectSP _M_node_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true));
+ if (!_M_node_sp)
+ return false;
+
+ m_pair_address = _M_node_sp->GetValueAsUnsigned(0);
+ if (m_pair_address == 0)
+ return false;
+
+ m_pair_address += (is_64bit ? 32 : 16);
+
+ CompilerType my_type(valobj_sp->GetCompilerType());
+ if (my_type.GetNumTemplateArguments() >= 1) {
+ TemplateArgumentKind kind;
+ CompilerType pair_type = my_type.GetTemplateArgument(0, kind);
+ if (kind != eTemplateArgumentKindType &&
+ kind != eTemplateArgumentKindTemplate &&
+ kind != eTemplateArgumentKindTemplateExpansion)
+ return false;
+ m_pair_type = pair_type;
+ } else
+ return false;
+
+ return true;
}
-size_t
-LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren ()
-{
- return 2;
+size_t LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren() {
+ return 2;
}
lldb::ValueObjectSP
-LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (m_pair_address != 0 && m_pair_type)
- {
- if (!m_pair_sp)
- m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type);
- if (m_pair_sp)
- return m_pair_sp->GetChildAtIndex(idx, true);
- }
- return lldb::ValueObjectSP();
+LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ if (m_pair_address != 0 && m_pair_type) {
+ if (!m_pair_sp)
+ m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address,
+ m_exe_ctx_ref, m_pair_type);
+ if (m_pair_sp)
+ return m_pair_sp->GetChildAtIndex(idx, true);
+ }
+ return lldb::ValueObjectSP();
}
-bool
-LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
-}
+bool LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren() { return true; }
-size_t
-LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- if (name == ConstString("first"))
- return 0;
- if (name == ConstString("second"))
- return 1;
- return UINT32_MAX;
+size_t LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ if (name == ConstString("first"))
+ return 0;
+ if (name == ConstString("second"))
+ return 1;
+ return UINT32_MAX;
}
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
/*
(lldb) fr var ibeg --ptr-depth 1
- (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >) ibeg = {
+ (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >)
+ ibeg = {
_M_current = 0x00000001001037a0 {
*_M_current = 1
}
}
*/
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- static ConstString g_item_name;
- if (!g_item_name)
- g_item_name.SetCString("_M_current");
- return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) : nullptr);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ static ConstString g_item_name;
+ if (!g_item_name)
+ g_item_name.SetCString("_M_current");
+ return (valobj_sp
+ ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name)
+ : nullptr);
}
-lldb_private::formatters::VectorIteratorSyntheticFrontEnd::VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp,
- ConstString item_name) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_exe_ctx_ref(),
- m_item_name(item_name),
- m_item_sp()
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::
+ VectorIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp,
+ ConstString item_name)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(),
+ m_item_name(item_name), m_item_sp() {
+ if (valobj_sp)
+ Update();
}
-bool
-VectorIteratorSyntheticFrontEnd::Update()
-{
- m_item_sp.reset();
-
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
-
- if (!valobj_sp)
- return false;
-
- ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name,true));
- if (!item_ptr)
- return false;
- if (item_ptr->GetValueAsUnsigned(0) == 0)
- return false;
- Error err;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- m_item_sp = CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, item_ptr->GetCompilerType().GetPointeeType());
- if (err.Fail())
- m_item_sp.reset();
+bool VectorIteratorSyntheticFrontEnd::Update() {
+ m_item_sp.reset();
+
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
return false;
-}
-size_t
-VectorIteratorSyntheticFrontEnd::CalculateNumChildren()
-{
- return 1;
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name, true));
+ if (!item_ptr)
+ return false;
+ if (item_ptr->GetValueAsUnsigned(0) == 0)
+ return false;
+ Error err;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ m_item_sp = CreateValueObjectFromAddress(
+ "item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref,
+ item_ptr->GetCompilerType().GetPointeeType());
+ if (err.Fail())
+ m_item_sp.reset();
+ return false;
}
+size_t VectorIteratorSyntheticFrontEnd::CalculateNumChildren() { return 1; }
+
lldb::ValueObjectSP
-VectorIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx)
-{
- if (idx == 0)
- return m_item_sp;
- return lldb::ValueObjectSP();
+VectorIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx == 0)
+ return m_item_sp;
+ return lldb::ValueObjectSP();
}
-bool
-VectorIteratorSyntheticFrontEnd::MightHaveChildren()
-{
- return true;
-}
+bool VectorIteratorSyntheticFrontEnd::MightHaveChildren() { return true; }
-size_t
-VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name)
-{
- if (name == ConstString("item"))
- return 0;
- return UINT32_MAX;
+size_t VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ if (name == ConstString("item"))
+ return 0;
+ return UINT32_MAX;
}
-bool
-lldb_private::formatters::LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- const bool scalar_is_load_addr = true;
- AddressType addr_type;
- lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
- if (addr_of_string != LLDB_INVALID_ADDRESS)
- {
- switch (addr_type)
- {
- case eAddressTypeLoad:
- {
- ProcessSP process_sp(valobj.GetProcessSP());
- if (!process_sp)
- return false;
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- Error error;
- lldb::addr_t addr_of_data = process_sp->ReadPointerFromMemory(addr_of_string, error);
- if (error.Fail() || addr_of_data == 0 || addr_of_data == LLDB_INVALID_ADDRESS)
- return false;
- options.SetLocation(addr_of_data);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetNeedsZeroTermination(false);
- options.SetBinaryZeroIsTerminator(true);
- lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(addr_of_string + process_sp->GetAddressByteSize(), error);
- if (error.Fail())
- return false;
- options.SetSourceSize(size_of_data);
-
- if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options))
- {
- stream.Printf("Summary Unavailable");
- return true;
- }
- else
- return true;
- }
- break;
- case eAddressTypeHost:
- break;
- case eAddressTypeInvalid:
- case eAddressTypeFile:
- break;
- }
+bool lldb_private::formatters::LibStdcppStringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ const bool scalar_is_load_addr = true;
+ AddressType addr_type;
+ lldb::addr_t addr_of_string =
+ valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
+ if (addr_of_string != LLDB_INVALID_ADDRESS) {
+ switch (addr_type) {
+ case eAddressTypeLoad: {
+ ProcessSP process_sp(valobj.GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ Error error;
+ lldb::addr_t addr_of_data =
+ process_sp->ReadPointerFromMemory(addr_of_string, error);
+ if (error.Fail() || addr_of_data == 0 ||
+ addr_of_data == LLDB_INVALID_ADDRESS)
+ return false;
+ options.SetLocation(addr_of_data);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetNeedsZeroTermination(false);
+ options.SetBinaryZeroIsTerminator(true);
+ lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(
+ addr_of_string + process_sp->GetAddressByteSize(), error);
+ if (error.Fail())
+ return false;
+ options.SetSourceSize(size_of_data);
+
+ if (!StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options)) {
+ stream.Printf("Summary Unavailable");
+ return true;
+ } else
+ return true;
+ } break;
+ case eAddressTypeHost:
+ break;
+ case eAddressTypeInvalid:
+ case eAddressTypeFile:
+ break;
}
- return false;
+ }
+ return false;
}
-bool
-lldb_private::formatters::LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- const bool scalar_is_load_addr = true;
- AddressType addr_type;
- lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
- if (addr_of_string != LLDB_INVALID_ADDRESS)
- {
- switch (addr_type)
- {
- case eAddressTypeLoad:
- {
- ProcessSP process_sp(valobj.GetProcessSP());
- if (!process_sp)
- return false;
-
- CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
-
- if (!wchar_compiler_type)
- return false;
-
- const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- Error error;
- lldb::addr_t addr_of_data = process_sp->ReadPointerFromMemory(addr_of_string, error);
- if (error.Fail() || addr_of_data == 0 || addr_of_data == LLDB_INVALID_ADDRESS)
- return false;
- options.SetLocation(addr_of_data);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetNeedsZeroTermination(false);
- options.SetBinaryZeroIsTerminator(false);
- lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(addr_of_string + process_sp->GetAddressByteSize(), error);
- if (error.Fail())
- return false;
- options.SetSourceSize(size_of_data);
- options.SetPrefixToken("L");
-
- switch (wchar_size)
- {
- case 8:
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
- case 16:
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
- case 32:
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
- default:
- stream.Printf("size for wchar_t is not valid");
- return true;
- }
- return true;
- }
- break;
- case eAddressTypeHost:
- break;
- case eAddressTypeInvalid:
- case eAddressTypeFile:
- break;
- }
+bool lldb_private::formatters::LibStdcppWStringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ const bool scalar_is_load_addr = true;
+ AddressType addr_type;
+ lldb::addr_t addr_of_string =
+ valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
+ if (addr_of_string != LLDB_INVALID_ADDRESS) {
+ switch (addr_type) {
+ case eAddressTypeLoad: {
+ ProcessSP process_sp(valobj.GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ CompilerType wchar_compiler_type =
+ valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
+
+ if (!wchar_compiler_type)
+ return false;
+
+ const uint32_t wchar_size = wchar_compiler_type.GetBitSize(
+ nullptr); // Safe to pass NULL for exe_scope here
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ Error error;
+ lldb::addr_t addr_of_data =
+ process_sp->ReadPointerFromMemory(addr_of_string, error);
+ if (error.Fail() || addr_of_data == 0 ||
+ addr_of_data == LLDB_INVALID_ADDRESS)
+ return false;
+ options.SetLocation(addr_of_data);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetNeedsZeroTermination(false);
+ options.SetBinaryZeroIsTerminator(false);
+ lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(
+ addr_of_string + process_sp->GetAddressByteSize(), error);
+ if (error.Fail())
+ return false;
+ options.SetSourceSize(size_of_data);
+ options.SetPrefixToken("L");
+
+ switch (wchar_size) {
+ case 8:
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options);
+ case 16:
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options);
+ case 32:
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF32>(options);
+ default:
+ stream.Printf("size for wchar_t is not valid");
+ return true;
+ }
+ return true;
+ } break;
+ case eAddressTypeHost:
+ break;
+ case eAddressTypeInvalid:
+ case eAddressTypeFile:
+ break;
}
- return false;
+ }
+ return false;
}
-LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp)
-{
- if (valobj_sp)
- Update();
+LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp) {
+ if (valobj_sp)
+ Update();
}
-size_t
-LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren()
-{
- return 1;
-}
+size_t LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { return 1; }
lldb::ValueObjectSP
-LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx)
-{
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return lldb::ValueObjectSP();
-
- if (idx == 0)
- return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true);
- else
- return lldb::ValueObjectSP();
-}
+LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return lldb::ValueObjectSP();
-bool
-LibStdcppSharedPtrSyntheticFrontEnd::Update()
-{
- return false;
+ if (idx == 0)
+ return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true);
+ else
+ return lldb::ValueObjectSP();
}
-bool
-LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren()
-{
- return true;
-}
+bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { return false; }
+
+bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; }
-size_t
-LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name)
-{
- if (name == ConstString("_M_ptr"))
- return 0;
- return UINT32_MAX;
+size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ if (name == ConstString("_M_ptr"))
+ return 0;
+ return UINT32_MAX;
}
SyntheticChildrenFrontEnd *
-lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
- lldb::ValueObjectSP valobj_sp)
-{
- return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp) : nullptr);
+lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp)
+ : nullptr);
}
-bool
-lldb_private::formatters::LibStdcppSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &options)
-{
- ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
- if (!valobj_sp)
- return false;
-
- ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true));
- if (!ptr_sp)
- return false;
+bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
- ValueObjectSP usecount_sp(
- valobj_sp->GetChildAtNamePath({ConstString("_M_refcount"), ConstString("_M_pi"), ConstString("_M_use_count")}));
- if (!usecount_sp)
- return false;
+ ValueObjectSP ptr_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true));
+ if (!ptr_sp)
+ return false;
- if (ptr_sp->GetValueAsUnsigned(0) == 0 || usecount_sp->GetValueAsUnsigned(0) == 0)
- {
- stream.Printf("nullptr");
- return true;
- }
+ ValueObjectSP usecount_sp(valobj_sp->GetChildAtNamePath(
+ {ConstString("_M_refcount"), ConstString("_M_pi"),
+ ConstString("_M_use_count")}));
+ if (!usecount_sp)
+ return false;
- Error error;
- ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
- if (pointee_sp && error.Success())
- {
- if (pointee_sp->DumpPrintableRepresentation(stream, ValueObject::eValueObjectRepresentationStyleSummary,
- lldb::eFormatInvalid,
- ValueObject::ePrintableRepresentationSpecialCasesDisable, false))
- {
- return true;
- }
+ if (ptr_sp->GetValueAsUnsigned(0) == 0 ||
+ usecount_sp->GetValueAsUnsigned(0) == 0) {
+ stream.Printf("nullptr");
+ return true;
+ }
+
+ Error error;
+ ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
+ if (pointee_sp && error.Success()) {
+ if (pointee_sp->DumpPrintableRepresentation(
+ stream, ValueObject::eValueObjectRepresentationStyleSummary,
+ lldb::eFormatInvalid,
+ ValueObject::PrintableRepresentationSpecialCases::eDisable,
+ false)) {
+ return true;
}
+ }
- stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
- return true;
+ stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
+ return true;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/source/Plugins/Language/CPlusPlus/LibStdcpp.h
index b84c0ff831eb..72e169f50395 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -1,4 +1,4 @@
-//===-- LibStdCpp.h ---------------------------------------------------*- C++ -*-===//
+//===-- LibStdcpp.h ---------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,23 +16,45 @@
#include "lldb/DataFormatters/TypeSynthetic.h"
namespace lldb_private {
- namespace formatters
- {
- bool
- LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libcstdc++ c++11 std::string
+namespace formatters {
+bool LibStdcppStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libcstdc++ c++11 std::string
- bool
- LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libcstdc++ c++11 std::wstring
+bool LibStdcppWStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libcstdc++ c++11 std::wstring
- bool
- LibStdcppSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libstdc++ std::shared_ptr<> and std::weak_ptr<>
+bool LibStdcppSmartPointerSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions
+ &options); // libstdc++ std::shared_ptr<> and std::weak_ptr<>
- SyntheticChildrenFrontEnd* LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+bool LibStdcppUniquePointerSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libstdc++ std::unique_ptr<>
- SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *
+LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
- SyntheticChildrenFrontEnd* LibStdcppSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
- } // namespace formatters
+SyntheticChildrenFrontEnd *
+LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_LibStdCpp_h_
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
new file mode 100644
index 000000000000..c4a6e3d227b0
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
@@ -0,0 +1,109 @@
+//===-- LibStdcppTuple.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibStdcpp.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+#include <memory>
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace {
+
+class LibStdcppTupleSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ explicit LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ std::vector<ValueObjectSP> m_members;
+};
+
+} // end of anonymous namespace
+
+LibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp) {
+ Update();
+}
+
+bool LibStdcppTupleSyntheticFrontEnd::Update() {
+ m_members.clear();
+
+ ValueObjectSP valobj_backend_sp = m_backend.GetSP();
+ if (!valobj_backend_sp)
+ return false;
+
+ ValueObjectSP next_child_sp = valobj_backend_sp->GetNonSyntheticValue();
+ while (next_child_sp != nullptr) {
+ ValueObjectSP current_child = next_child_sp;
+ next_child_sp = nullptr;
+
+ size_t child_count = current_child->GetNumChildren();
+ for (size_t i = 0; i < child_count; ++i) {
+ ValueObjectSP child_sp = current_child->GetChildAtIndex(i, true);
+ llvm::StringRef name_str = child_sp->GetName().GetStringRef();
+ if (name_str.startswith("std::_Tuple_impl<")) {
+ next_child_sp = child_sp;
+ } else if (name_str.startswith("std::_Head_base<")) {
+ ValueObjectSP value_sp =
+ child_sp->GetChildMemberWithName(ConstString("_M_head_impl"), true);
+ if (value_sp) {
+ StreamString name;
+ name.Printf("[%zd]", m_members.size());
+ value_sp->SetName(ConstString(name.GetString()));
+
+ m_members.push_back(value_sp);
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; }
+
+lldb::ValueObjectSP
+LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx < m_members.size())
+ return m_members[idx];
+ return lldb::ValueObjectSP();
+}
+
+size_t LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() {
+ return m_members.size();
+}
+
+size_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ return ExtractIndexFromString(name.GetCString());
+}
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibStdcppTupleSyntheticFrontEnd(valobj_sp) : nullptr);
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
new file mode 100644
index 000000000000..4eb3b95afb4e
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -0,0 +1,151 @@
+//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibStdcpp.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+#include <memory>
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace {
+
+class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+ bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
+
+private:
+ ValueObjectSP m_ptr_obj;
+ ValueObjectSP m_obj_obj;
+ ValueObjectSP m_del_obj;
+};
+
+} // end of anonymous namespace
+
+LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp) {
+ Update();
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
+ ValueObjectSP valobj_backend_sp = m_backend.GetSP();
+ if (!valobj_backend_sp)
+ return false;
+
+ ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP tuple_sp =
+ valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
+ if (!tuple_sp)
+ return false;
+
+ std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend(
+ LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp));
+
+ m_ptr_obj = tuple_frontend->GetChildAtIndex(0);
+ if (m_ptr_obj)
+ m_ptr_obj->SetName(ConstString("pointer"));
+
+ m_del_obj = tuple_frontend->GetChildAtIndex(1);
+ if (m_del_obj)
+ m_del_obj->SetName(ConstString("deleter"));
+
+ if (m_ptr_obj) {
+ Error error;
+ m_obj_obj = m_ptr_obj->Dereference(error);
+ if (error.Success()) {
+ m_obj_obj->SetName(ConstString("object"));
+ }
+ }
+
+ return false;
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
+
+lldb::ValueObjectSP
+LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx == 0)
+ return m_obj_obj;
+ if (idx == 1)
+ return m_del_obj;
+ if (idx == 2)
+ return m_ptr_obj;
+ return lldb::ValueObjectSP();
+}
+
+size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() {
+ if (m_del_obj)
+ return 2;
+ if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0)
+ return 1;
+ return 0;
+}
+
+size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ if (name == ConstString("obj") || name == ConstString("object"))
+ return 0;
+ if (name == ConstString("del") || name == ConstString("deleter"))
+ return 1;
+ if (name == ConstString("ptr") || name == ConstString("pointer"))
+ return 2;
+ return UINT32_MAX;
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary(
+ Stream &stream, const TypeSummaryOptions &options) {
+ if (!m_ptr_obj)
+ return false;
+
+ bool success;
+ uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success);
+ if (!success)
+ return false;
+ if (ptr_value == 0)
+ stream.Printf("nullptr");
+ else
+ stream.Printf("0x%" PRIx64, ptr_value);
+ return true;
+}
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp)
+ : nullptr);
+}
+
+bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP());
+ return formatter.GetSummary(stream, options);
+}
diff --git a/source/Plugins/Language/Go/GoFormatterFunctions.cpp b/source/Plugins/Language/Go/GoFormatterFunctions.cpp
index 1d7cd76b9739..0f78f643321b 100644
--- a/source/Plugins/Language/Go/GoFormatterFunctions.cpp
+++ b/source/Plugins/Language/Go/GoFormatterFunctions.cpp
@@ -21,153 +21,132 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-namespace
-{
-class GoSliceSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
- public:
- GoSliceSyntheticFrontEnd(ValueObject &valobj)
- : SyntheticChildrenFrontEnd(valobj)
- {
- Update();
+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;
}
-
- ~GoSliceSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override
- {
- return m_len;
+ 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;
}
-
- 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.GetData(), object_at_idx,
- m_backend.GetExecutionContextRef(), m_type);
- }
- return cached;
- }
- return ValueObjectSP();
+ 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();
}
- 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;
- }
+ return old_count == m_len;
+ }
- bool
- MightHaveChildren() override
- {
- return true;
- }
+ bool MightHaveChildren() override { return true; }
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- return ExtractIndexFromString(name.AsCString());
- }
+ 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;
+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())
- {
- Error 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;
- }
-
+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()) {
+ Error 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);
+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
index ae1eda0f0c54..596eb2ae71f6 100644
--- a/source/Plugins/Language/Go/GoFormatterFunctions.h
+++ b/source/Plugins/Language/Go/GoFormatterFunctions.h
@@ -28,14 +28,14 @@
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
-namespace lldb_private
-{
-namespace formatters
-{
+namespace lldb_private {
+namespace formatters {
-bool GoStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
+bool GoStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
-SyntheticChildrenFrontEnd *GoSliceSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *
+GoSliceSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/Go/GoLanguage.cpp b/source/Plugins/Language/Go/GoLanguage.cpp
index ed010ffa4b2e..85c41d1fe917 100644
--- a/source/Plugins/Language/Go/GoLanguage.cpp
+++ b/source/Plugins/Language/Go/GoLanguage.cpp
@@ -18,129 +18,109 @@
// Project includes
#include "GoLanguage.h"
+#include "Plugins/Language/Go/GoFormatterFunctions.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Symbol/GoASTContext.h"
-#include "Plugins/Language/Go/GoFormatterFunctions.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-void
-GoLanguage::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language", CreateInstance);
+void GoLanguage::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language",
+ CreateInstance);
}
-void
-GoLanguage::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
+void GoLanguage::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-GoLanguage::GetPluginNameStatic()
-{
- static ConstString g_name("Go");
- return g_name;
+lldb_private::ConstString GoLanguage::GetPluginNameStatic() {
+ static ConstString g_name("Go");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-GoLanguage::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString GoLanguage::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-GoLanguage::GetPluginVersion()
-{
- return 1;
-}
+uint32_t GoLanguage::GetPluginVersion() { return 1; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-Language *
-GoLanguage::CreateInstance(lldb::LanguageType language)
-{
- if (language == eLanguageTypeGo)
- return new GoLanguage();
- return nullptr;
+Language *GoLanguage::CreateInstance(lldb::LanguageType language) {
+ if (language == eLanguageTypeGo)
+ return new GoLanguage();
+ return nullptr;
}
HardcodedFormatters::HardcodedSummaryFinder
-GoLanguage::GetHardcodedSummaries()
-{
- static std::once_flag g_initialize;
- static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
+GoLanguage::GetHardcodedSummaries() {
+ static std::once_flag g_initialize;
+ static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
- std::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;
+ std::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 std::once_flag g_initialize;
- static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
+GoLanguage::GetHardcodedSynthetics() {
+ static std::once_flag g_initialize;
+ static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
- std::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;
- });
- });
+ std::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;
+ return g_formatters;
}
diff --git a/source/Plugins/Language/Go/GoLanguage.h b/source/Plugins/Language/Go/GoLanguage.h
index 67dd04c2a22e..4dc8ed0745c4 100644
--- a/source/Plugins/Language/Go/GoLanguage.h
+++ b/source/Plugins/Language/Go/GoLanguage.h
@@ -18,47 +18,44 @@
#include "llvm/ADT/StringRef.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class GoLanguage : public Language
-{
- public:
- GoLanguage() = default;
+class GoLanguage : public Language {
+public:
+ GoLanguage() = default;
- ~GoLanguage() override = default;
+ ~GoLanguage() override = default;
- lldb::LanguageType
- GetLanguageType() const override
- {
- return lldb::eLanguageTypeGo;
- }
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeGo;
+ }
- HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override;
+ HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override;
- HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics() override;
+ HardcodedFormatters::HardcodedSyntheticFinder
+ GetHardcodedSynthetics() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void Terminate();
+ static void Terminate();
- static lldb_private::Language *CreateInstance(lldb::LanguageType language);
+ static lldb_private::Language *CreateInstance(lldb::LanguageType language);
- static lldb_private::ConstString GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- ConstString GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Language/Java/JavaFormatterFunctions.cpp b/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
index 29e6ad0ee89f..286651a64409 100644
--- a/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
+++ b/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
@@ -20,167 +20,148 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-namespace
-{
+namespace {
-class JavaArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+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);
-
- Error 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.GetData(), 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());
- }
+ 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);
+
+ Error 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();
-
- Error error;
- return m_backend.Dereference(error);
- }
+ ValueObjectSP GetDereferencedValueObject() {
+ if (!m_backend.IsPointerOrReferenceType())
+ return m_backend.GetSP();
+
+ Error 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())
- {
- Error 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");
+bool lldb_private::formatters::JavaStringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) {
+ if (valobj.IsPointerOrReferenceType()) {
+ Error 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())
- {
- Error 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;
+bool lldb_private::formatters::JavaArraySummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ if (valobj.IsPointerOrReferenceType()) {
+ Error 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;
+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
index f9588c5590ae..d1983429529c 100644
--- a/source/Plugins/Language/Java/JavaFormatterFunctions.h
+++ b/source/Plugins/Language/Java/JavaFormatterFunctions.h
@@ -16,19 +16,18 @@
// Project includes
#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
-namespace formatters
-{
+namespace lldb_private {
+namespace formatters {
-bool
-JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
+bool JavaStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
-bool
-JavaArraySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
+bool JavaArraySummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
-SyntheticChildrenFrontEnd*
-JavaArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp);
+SyntheticChildrenFrontEnd *
+JavaArraySyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/Java/JavaLanguage.cpp b/source/Plugins/Language/Java/JavaLanguage.cpp
index a4f883f68827..f58b51f53e76 100644
--- a/source/Plugins/Language/Java/JavaLanguage.cpp
+++ b/source/Plugins/Language/Java/JavaLanguage.cpp
@@ -29,84 +29,72 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-void
-JavaLanguage::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java Language", CreateInstance);
+void JavaLanguage::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java Language",
+ CreateInstance);
}
-void
-JavaLanguage::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
+void JavaLanguage::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-JavaLanguage::GetPluginNameStatic()
-{
- static ConstString g_name("Java");
- return g_name;
+lldb_private::ConstString JavaLanguage::GetPluginNameStatic() {
+ static ConstString g_name("Java");
+ return g_name;
}
-lldb_private::ConstString
-JavaLanguage::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString JavaLanguage::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-JavaLanguage::GetPluginVersion()
-{
- return 1;
-}
+uint32_t JavaLanguage::GetPluginVersion() { return 1; }
-Language *
-JavaLanguage::CreateInstance(lldb::LanguageType language)
-{
- if (language == eLanguageTypeJava)
- return new JavaLanguage();
- return nullptr;
+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;
+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;
+ // 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 std::once_flag g_initialize;
- static TypeCategoryImplSP g_category;
-
- std::call_once(g_initialize, [this]() -> void {
- DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
- if (g_category)
- {
- const char* 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);
+lldb::TypeCategoryImplSP JavaLanguage::GetFormatters() {
+ static std::once_flag g_initialize;
+ static TypeCategoryImplSP g_category;
+
+ std::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);
+ AddCXXSynthetic(
+ g_category,
+ lldb_private::formatters::JavaArraySyntheticFrontEndCreator,
+ "Java array synthetic children", ConstString(array_regexp),
+ SyntheticChildren::Flags().SetCascades(true), true);
#endif
- }
- });
- return g_category;
+ }
+ });
+ return g_category;
}
diff --git a/source/Plugins/Language/Java/JavaLanguage.h b/source/Plugins/Language/Java/JavaLanguage.h
index 164facd27ab5..6cf27ab5ffa4 100644
--- a/source/Plugins/Language/Java/JavaLanguage.h
+++ b/source/Plugins/Language/Java/JavaLanguage.h
@@ -22,41 +22,29 @@
#include "lldb/Target/Language.h"
#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class JavaLanguage : public Language
-{
+class JavaLanguage : public Language {
public:
- lldb::LanguageType
- GetLanguageType() const override
- {
- return lldb::eLanguageTypeJava;
- }
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeJava;
+ }
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::Language *
- CreateInstance(lldb::LanguageType language);
+ static lldb_private::Language *CreateInstance(lldb::LanguageType language);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- ConstString
- GetPluginName() override;
+ ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- bool
- IsNilReference(ValueObject &valobj) override;
+ bool IsNilReference(ValueObject &valobj) override;
- lldb::TypeCategoryImplSP
- GetFormatters() override;
+ lldb::TypeCategoryImplSP GetFormatters() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Language/OCaml/CMakeLists.txt b/source/Plugins/Language/OCaml/CMakeLists.txt
new file mode 100644
index 000000000000..e969618d5e0c
--- /dev/null
+++ b/source/Plugins/Language/OCaml/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_lldb_library(lldbPluginOCamlLanguage
+ OCamlLanguage.cpp
+)
+
diff --git a/source/Plugins/Language/OCaml/OCamlLanguage.cpp b/source/Plugins/Language/OCaml/OCamlLanguage.cpp
new file mode 100644
index 000000000000..ef9f2b567929
--- /dev/null
+++ b/source/Plugins/Language/OCaml/OCamlLanguage.cpp
@@ -0,0 +1,63 @@
+//===-- 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/ConstString.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/OCamlASTContext.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
new file mode 100644
index 000000000000..f7dc6398eafe
--- /dev/null
+++ b/source/Plugins/Language/OCaml/OCamlLanguage.h
@@ -0,0 +1,51 @@
+//===-- 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/Core/ConstString.h"
+#include "lldb/Target/Language.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 617bb613aa0b..f67db465f72c 100644
--- a/source/Plugins/Language/ObjC/CF.cpp
+++ b/source/Plugins/Language/ObjC/CF.cpp
@@ -1,4 +1,5 @@
-//===-- CF.cpp ----------------------------------------------------*- C++ -*-===//
+//===-- CF.cpp ----------------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -26,293 +27,277 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool
-lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- time_t epoch = GetOSXEpoch();
- epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
- tm *tm_date = localtime(&epoch);
- if (!tm_date)
- return false;
- std::string buffer(1024,0);
- if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
- return false;
- stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
- return true;
+bool lldb_private::formatters::CFAbsoluteTimeSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ time_t epoch = GetOSXEpoch();
+ epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
+ tm *tm_date = localtime(&epoch);
+ if (!tm_date)
+ return false;
+ std::string buffer(1024, 0);
+ if (strftime(&buffer[0], 1023, "%Z", tm_date) == 0)
+ return false;
+ stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year + 1900,
+ tm_date->tm_mon + 1, tm_date->tm_mday, tm_date->tm_hour,
+ tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+ return true;
}
-bool
-lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- static ConstString g_TypeHint("CFBag");
-
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint32_t count = 0;
-
- bool is_type_ok = false; // check to see if this is a CFBag we know about
- if (descriptor->IsCFType())
- {
- ConstString type_name(valobj.GetTypeName());
-
- static ConstString g___CFBag("__CFBag");
- static ConstString g_conststruct__CFBag("const struct __CFBag");
-
- if (type_name == g___CFBag ||
- type_name == g_conststruct__CFBag)
- {
- if (valobj.IsPointerType())
- is_type_ok = true;
- }
- }
-
- if (is_type_ok)
- {
- lldb::addr_t offset = 2*ptr_size+4 + valobj_addr;
- Error error;
- count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
- if (error.Fail())
- return false;
+bool lldb_private::formatters::CFBagSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ static ConstString g_TypeHint("CFBag");
+
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint32_t count = 0;
+
+ bool is_type_ok = false; // check to see if this is a CFBag we know about
+ if (descriptor->IsCFType()) {
+ ConstString type_name(valobj.GetTypeName());
+
+ static ConstString g___CFBag("__CFBag");
+ static ConstString g_conststruct__CFBag("const struct __CFBag");
+
+ if (type_name == g___CFBag || type_name == g_conststruct__CFBag) {
+ if (valobj.IsPointerType())
+ is_type_ok = true;
}
- else
- return false;
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(options.GetLanguage()))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+ }
+
+ if (is_type_ok) {
+ lldb::addr_t offset = 2 * ptr_size + 4 + valobj_addr;
+ Error error;
+ count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
+ if (error.Fail())
+ return false;
+ } else
+ return false;
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s\"%u value%s\"%s",
- prefix.c_str(),
- count,(count == 1 ? "" : "s"),
- suffix.c_str());
- return true;
+ }
+
+ stream.Printf("%s\"%u value%s\"%s", prefix.c_str(), count,
+ (count == 1 ? "" : "s"), suffix.c_str());
+ return true;
}
-bool
-lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint32_t count = 0;
-
- bool is_type_ok = false; // check to see if this is a CFBag we know about
- if (descriptor->IsCFType())
- {
- ConstString type_name(valobj.GetTypeName());
- if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef"))
- {
- if (valobj.IsPointerType())
- is_type_ok = true;
- }
+bool lldb_private::formatters::CFBitVectorSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint32_t count = 0;
+
+ bool is_type_ok = false; // check to see if this is a CFBag we know about
+ if (descriptor->IsCFType()) {
+ ConstString type_name(valobj.GetTypeName());
+ if (type_name == ConstString("__CFMutableBitVector") ||
+ type_name == ConstString("__CFBitVector") ||
+ type_name == ConstString("CFMutableBitVectorRef") ||
+ type_name == ConstString("CFBitVectorRef")) {
+ if (valobj.IsPointerType())
+ is_type_ok = true;
}
-
- if (is_type_ok == false)
- return false;
-
- Error error;
- count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
- addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error);
- if (error.Fail())
- return false;
- // make sure we do not try to read huge amounts of data
- if (num_bytes > 1024)
- num_bytes = 1024;
- DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0));
- num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
- if (error.Fail() || num_bytes == 0)
- return false;
- uint8_t *bytes = buffer_sp->GetBytes();
- for (uint64_t byte_idx = 0; byte_idx < num_bytes-1; byte_idx++)
- {
- uint8_t byte = bytes[byte_idx];
- bool bit0 = (byte & 1) == 1;
- bool bit1 = (byte & 2) == 2;
- bool bit2 = (byte & 4) == 4;
- bool bit3 = (byte & 8) == 8;
- bool bit4 = (byte & 16) == 16;
- bool bit5 = (byte & 32) == 32;
- bool bit6 = (byte & 64) == 64;
- bool bit7 = (byte & 128) == 128;
- stream.Printf("%c%c%c%c %c%c%c%c ",
- (bit7 ? '1' : '0'),
- (bit6 ? '1' : '0'),
- (bit5 ? '1' : '0'),
- (bit4 ? '1' : '0'),
- (bit3 ? '1' : '0'),
- (bit2 ? '1' : '0'),
- (bit1 ? '1' : '0'),
- (bit0 ? '1' : '0'));
- count -= 8;
+ }
+
+ if (is_type_ok == false)
+ return false;
+
+ Error error;
+ count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
+ addr_t data_ptr = process_sp->ReadPointerFromMemory(
+ valobj_addr + 2 * ptr_size + 2 * ptr_size, error);
+ if (error.Fail())
+ return false;
+ // make sure we do not try to read huge amounts of data
+ if (num_bytes > 1024)
+ num_bytes = 1024;
+ DataBufferSP buffer_sp(new DataBufferHeap(num_bytes, 0));
+ num_bytes =
+ process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
+ if (error.Fail() || num_bytes == 0)
+ return false;
+ uint8_t *bytes = buffer_sp->GetBytes();
+ for (uint64_t byte_idx = 0; byte_idx < num_bytes - 1; byte_idx++) {
+ uint8_t byte = bytes[byte_idx];
+ bool bit0 = (byte & 1) == 1;
+ bool bit1 = (byte & 2) == 2;
+ bool bit2 = (byte & 4) == 4;
+ bool bit3 = (byte & 8) == 8;
+ bool bit4 = (byte & 16) == 16;
+ bool bit5 = (byte & 32) == 32;
+ bool bit6 = (byte & 64) == 64;
+ bool bit7 = (byte & 128) == 128;
+ stream.Printf("%c%c%c%c %c%c%c%c ", (bit7 ? '1' : '0'), (bit6 ? '1' : '0'),
+ (bit5 ? '1' : '0'), (bit4 ? '1' : '0'), (bit3 ? '1' : '0'),
+ (bit2 ? '1' : '0'), (bit1 ? '1' : '0'), (bit0 ? '1' : '0'));
+ count -= 8;
+ }
+ {
+ // print the last byte ensuring we do not print spurious bits
+ uint8_t byte = bytes[num_bytes - 1];
+ bool bit0 = (byte & 1) == 1;
+ bool bit1 = (byte & 2) == 2;
+ bool bit2 = (byte & 4) == 4;
+ bool bit3 = (byte & 8) == 8;
+ bool bit4 = (byte & 16) == 16;
+ bool bit5 = (byte & 32) == 32;
+ bool bit6 = (byte & 64) == 64;
+ bool bit7 = (byte & 128) == 128;
+ if (count) {
+ stream.Printf("%c", bit7 ? '1' : '0');
+ count -= 1;
+ }
+ if (count) {
+ stream.Printf("%c", bit6 ? '1' : '0');
+ count -= 1;
+ }
+ if (count) {
+ stream.Printf("%c", bit5 ? '1' : '0');
+ count -= 1;
+ }
+ if (count) {
+ stream.Printf("%c", bit4 ? '1' : '0');
+ count -= 1;
}
- {
- // print the last byte ensuring we do not print spurious bits
- uint8_t byte = bytes[num_bytes-1];
- bool bit0 = (byte & 1) == 1;
- bool bit1 = (byte & 2) == 2;
- bool bit2 = (byte & 4) == 4;
- bool bit3 = (byte & 8) == 8;
- bool bit4 = (byte & 16) == 16;
- bool bit5 = (byte & 32) == 32;
- bool bit6 = (byte & 64) == 64;
- bool bit7 = (byte & 128) == 128;
- if (count)
- {
- stream.Printf("%c",bit7 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit6 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit5 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit4 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit3 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit2 ? '1' : '0');
- count -= 1;
- }
- if (count)
- {
- stream.Printf("%c",bit1 ? '1' : '0');
- count -= 1;
- }
- if (count)
- stream.Printf("%c",bit0 ? '1' : '0');
+ if (count) {
+ stream.Printf("%c", bit3 ? '1' : '0');
+ count -= 1;
}
- return true;
+ if (count) {
+ stream.Printf("%c", bit2 ? '1' : '0');
+ count -= 1;
+ }
+ if (count) {
+ stream.Printf("%c", bit1 ? '1' : '0');
+ count -= 1;
+ }
+ if (count)
+ stream.Printf("%c", bit0 ? '1' : '0');
+ }
+ return true;
}
-bool
-lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- static ConstString g_TypeHint("CFBinaryHeap");
-
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint32_t count = 0;
-
- bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about
- if (descriptor->IsCFType())
- {
- ConstString type_name(valobj.GetTypeName());
-
- static ConstString g___CFBinaryHeap("__CFBinaryHeap");
- static ConstString g_conststruct__CFBinaryHeap("const struct __CFBinaryHeap");
- static ConstString g_CFBinaryHeapRef("CFBinaryHeapRef");
-
- if (type_name == g___CFBinaryHeap ||
- type_name == g_conststruct__CFBinaryHeap ||
- type_name == g_CFBinaryHeapRef)
- {
- if (valobj.IsPointerType())
- is_type_ok = true;
- }
- }
-
- if (is_type_ok)
- {
- lldb::addr_t offset = 2*ptr_size + valobj_addr;
- Error error;
- count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
- if (error.Fail())
- return false;
+bool lldb_private::formatters::CFBinaryHeapSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ static ConstString g_TypeHint("CFBinaryHeap");
+
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint32_t count = 0;
+
+ bool is_type_ok =
+ false; // check to see if this is a CFBinaryHeap we know about
+ if (descriptor->IsCFType()) {
+ ConstString type_name(valobj.GetTypeName());
+
+ static ConstString g___CFBinaryHeap("__CFBinaryHeap");
+ static ConstString g_conststruct__CFBinaryHeap(
+ "const struct __CFBinaryHeap");
+ static ConstString g_CFBinaryHeapRef("CFBinaryHeapRef");
+
+ if (type_name == g___CFBinaryHeap ||
+ type_name == g_conststruct__CFBinaryHeap ||
+ type_name == g_CFBinaryHeapRef) {
+ if (valobj.IsPointerType())
+ is_type_ok = true;
}
- else
- return false;
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(options.GetLanguage()))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+ }
+
+ if (is_type_ok) {
+ lldb::addr_t offset = 2 * ptr_size + valobj_addr;
+ Error error;
+ count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
+ if (error.Fail())
+ return false;
+ } else
+ return false;
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s\"%u item%s\"%s",
- prefix.c_str(),
- count,(count == 1 ? "" : "s"),
- suffix.c_str());
- return true;
+ }
+
+ stream.Printf("%s\"%u item%s\"%s", prefix.c_str(), count,
+ (count == 1 ? "" : "s"), suffix.c_str());
+ return true;
}
diff --git a/source/Plugins/Language/ObjC/CF.h b/source/Plugins/Language/ObjC/CF.h
index 4044f09f585e..ea47267db939 100644
--- a/source/Plugins/Language/ObjC/CF.h
+++ b/source/Plugins/Language/ObjC/CF.h
@@ -15,20 +15,19 @@
#include "lldb/DataFormatters/TypeSummary.h"
namespace lldb_private {
- namespace formatters
- {
- bool
- CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
- } // namespace formatters
+namespace formatters {
+bool CFBagSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool CFBinaryHeapSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool CFBitVectorSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool CFAbsoluteTimeSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_CF_h_
diff --git a/source/Plugins/Language/ObjC/Cocoa.cpp b/source/Plugins/Language/ObjC/Cocoa.cpp
index 017c46ee3bb3..b2ad8c375833 100644
--- a/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -26,940 +26,918 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
#include "lldb/Utility/ProcessStructReader.h"
+#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
+
#include "NSString.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool
-lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSBundle"))
- {
- uint64_t offset = 5 * ptr_size;
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true));
-
- StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
- if (was_nsstring_ok && summary_stream.GetSize() > 0)
- {
- stream.Printf("%s",summary_stream.GetData());
- return true;
- }
- }
-
+bool lldb_private::formatters::NSBundleSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
return false;
-}
-bool
-lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"__NSTimeZone"))
- {
- uint64_t offset = ptr_size;
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType(), true));
- StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
- if (was_nsstring_ok && summary_stream.GetSize() > 0)
- {
- stream.Printf("%s",summary_stream.GetData());
- return true;
- }
- }
-
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
return false;
-}
-bool
-lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSConcreteNotification"))
- {
- uint64_t offset = ptr_size;
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType(), true));
- StreamString summary_stream;
- bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
- if (was_nsstring_ok && summary_stream.GetSize() > 0)
- {
- stream.Printf("%s",summary_stream.GetData());
- return true;
- }
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name, "NSBundle")) {
+ uint64_t offset = 5 * ptr_size;
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
+ offset,
+ valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID),
+ true));
+
+ StreamString summary_stream;
+ bool was_nsstring_ok =
+ NSStringSummaryProvider(*text, summary_stream, options);
+ if (was_nsstring_ok && summary_stream.GetSize() > 0) {
+ stream.Printf("%s", summary_stream.GetData());
+ return true;
}
-
+ }
+
+ return false;
+}
+
+bool lldb_private::formatters::NSTimeZoneSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name, "__NSTimeZone")) {
+ uint64_t offset = ptr_size;
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
+ offset, valobj.GetCompilerType(), true));
+ StreamString summary_stream;
+ bool was_nsstring_ok =
+ NSStringSummaryProvider(*text, summary_stream, options);
+ if (was_nsstring_ok && summary_stream.GetSize() > 0) {
+ stream.Printf("%s", summary_stream.GetData());
+ return true;
+ }
+ }
+
+ return false;
}
-bool
-lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- uint64_t port_number = 0;
-
- if (!strcmp(class_name,"NSMachPort"))
- {
- uint64_t offset = (ptr_size == 4 ? 12 : 20);
- Error error;
- port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
- if (error.Success())
- {
- stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
- return true;
- }
+bool lldb_private::formatters::NSNotificationSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name, "NSConcreteNotification")) {
+ uint64_t offset = ptr_size;
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
+ offset, valobj.GetCompilerType(), true));
+ StreamString summary_stream;
+ bool was_nsstring_ok =
+ NSStringSummaryProvider(*text, summary_stream, options);
+ if (was_nsstring_ok && summary_stream.GetSize() > 0) {
+ stream.Printf("%s", summary_stream.GetData());
+ return true;
}
-
+ }
+
+ return false;
+}
+
+bool lldb_private::formatters::NSMachPortSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ uint64_t port_number = 0;
+
+ if (!strcmp(class_name, "NSMachPort")) {
+ uint64_t offset = (ptr_size == 4 ? 12 : 20);
+ Error error;
+ port_number = process_sp->ReadUnsignedIntegerFromMemory(
+ offset + valobj_addr, 4, 0, error);
+ if (error.Success()) {
+ stream.Printf("mach port: %u",
+ (uint32_t)(port_number & 0x00000000FFFFFFFF));
+ return true;
+ }
+ }
+
+ return false;
}
-bool
-lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- uint64_t count = 0;
-
- do {
- if (!strcmp(class_name,"NSIndexSet") || !strcmp(class_name,"NSMutableIndexSet"))
- {
- Error error;
- uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 4, 0, error);
- if (error.Fail())
- return false;
- // this means the set is empty - count = 0
- if ((mode & 1) == 1)
- {
- count = 0;
- break;
- }
- if ((mode & 2) == 2)
- mode = 1; // this means the set only has one range
- else
- mode = 2; // this means the set has multiple ranges
- if (mode == 1)
- {
- count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+3*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else
- {
- // read a pointer to the data at 2*ptr_size
- count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- // read the data at 2*ptr_size from the first location
- count = process_sp->ReadUnsignedIntegerFromMemory(count+2*ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- }
- else
- return false;
- } while (false);
- stream.Printf("%" PRIu64 " index%s",
- count,
- (count == 1 ? "" : "es"));
- return true;
+bool lldb_private::formatters::NSIndexSetSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ uint64_t count = 0;
+
+ do {
+ if (!strcmp(class_name, "NSIndexSet") ||
+ !strcmp(class_name, "NSMutableIndexSet")) {
+ Error error;
+ uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + ptr_size, 4, 0, error);
+ if (error.Fail())
+ return false;
+ // this means the set is empty - count = 0
+ if ((mode & 1) == 1) {
+ count = 0;
+ break;
+ }
+ if ((mode & 2) == 2)
+ mode = 1; // this means the set only has one range
+ else
+ mode = 2; // this means the set has multiple ranges
+ if (mode == 1) {
+ count = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + 3 * ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ } else {
+ // read a pointer to the data at 2*ptr_size
+ count = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + 2 * ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ // read the data at 2*ptr_size from the first location
+ count = process_sp->ReadUnsignedIntegerFromMemory(count + 2 * ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ } else
+ return false;
+ } while (false);
+ stream.Printf("%" PRIu64 " index%s", count, (count == 1 ? "" : "es"));
+ return true;
}
-static void
-NSNumber_FormatChar (ValueObject& valobj,
- Stream& stream,
- char value,
- lldb::LanguageType lang)
-{
- static ConstString g_TypeHint("NSNumber:char");
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(lang))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+static void NSNumber_FormatChar(ValueObject &valobj, Stream &stream, char value,
+ lldb::LanguageType lang) {
+ static ConstString g_TypeHint("NSNumber:char");
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(lang)) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s%hhd%s",
- prefix.c_str(),
- value,
- suffix.c_str());
+ }
+
+ stream.Printf("%s%hhd%s", prefix.c_str(), value, suffix.c_str());
}
-static void
-NSNumber_FormatShort (ValueObject& valobj,
- Stream& stream,
- short value,
- lldb::LanguageType lang)
-{
- static ConstString g_TypeHint("NSNumber:short");
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(lang))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+static void NSNumber_FormatShort(ValueObject &valobj, Stream &stream,
+ short value, lldb::LanguageType lang) {
+ static ConstString g_TypeHint("NSNumber:short");
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(lang)) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s%hd%s",
- prefix.c_str(),
- value,
- suffix.c_str());
+ }
+
+ stream.Printf("%s%hd%s", prefix.c_str(), value, suffix.c_str());
}
-static void
-NSNumber_FormatInt (ValueObject& valobj,
- Stream& stream,
- int value,
- lldb::LanguageType lang)
-{
- static ConstString g_TypeHint("NSNumber:int");
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(lang))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value,
+ lldb::LanguageType lang) {
+ static ConstString g_TypeHint("NSNumber:int");
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(lang)) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s%d%s",
- prefix.c_str(),
- value,
- suffix.c_str());
+ }
+
+ stream.Printf("%s%d%s", prefix.c_str(), value, suffix.c_str());
}
-static void
-NSNumber_FormatLong (ValueObject& valobj,
- Stream& stream,
- uint64_t value,
- lldb::LanguageType lang)
-{
- static ConstString g_TypeHint("NSNumber:long");
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(lang))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream,
+ uint64_t value, lldb::LanguageType lang) {
+ static ConstString g_TypeHint("NSNumber:long");
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(lang)) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s%" PRId64 "%s",
- prefix.c_str(),
- value,
- suffix.c_str());
+ }
+
+ stream.Printf("%s%" PRId64 "%s", prefix.c_str(), value, suffix.c_str());
}
-static void
-NSNumber_FormatFloat (ValueObject& valobj,
- Stream& stream,
- float value,
- lldb::LanguageType lang)
-{
- static ConstString g_TypeHint("NSNumber:float");
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(lang))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+static void NSNumber_FormatFloat(ValueObject &valobj, Stream &stream,
+ float value, lldb::LanguageType lang) {
+ static ConstString g_TypeHint("NSNumber:float");
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(lang)) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s%f%s",
- prefix.c_str(),
- value,
- suffix.c_str());
+ }
+
+ stream.Printf("%s%f%s", prefix.c_str(), value, suffix.c_str());
}
-static void
-NSNumber_FormatDouble (ValueObject& valobj,
- Stream& stream,
- double value,
- lldb::LanguageType lang)
-{
- static ConstString g_TypeHint("NSNumber:double");
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(lang))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+static void NSNumber_FormatDouble(ValueObject &valobj, Stream &stream,
+ double value, lldb::LanguageType lang) {
+ static ConstString g_TypeHint("NSNumber:double");
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(lang)) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s%g%s",
- prefix.c_str(),
- value,
- suffix.c_str());
+ }
+
+ stream.Printf("%s%g%s", prefix.c_str(), value, suffix.c_str());
}
-bool
-lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
- {
- uint64_t value = 0;
- uint64_t i_bits = 0;
- if (descriptor->GetTaggedPointerInfo(&i_bits,&value))
- {
- switch (i_bits)
- {
- case 0:
- NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
- break;
- case 1:
- case 4:
- NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage());
- break;
- case 2:
- case 8:
- NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
- break;
- case 3:
- case 12:
- NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
- break;
- default:
- return false;
- }
- return true;
- }
- else
- {
- Error error;
- uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
- uint64_t data_location = valobj_addr + 2*ptr_size;
- uint64_t value = 0;
- if (error.Fail())
- return false;
- switch (data_type)
- {
- case 1: // 0B00001
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
- if (error.Fail())
- return false;
- NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
- break;
- case 2: // 0B0010
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
- if (error.Fail())
- return false;
- NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage());
- break;
- case 3: // 0B0011
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
- if (error.Fail())
- return false;
- NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
- break;
- case 17: // 0B10001
- data_location += 8;
- LLVM_FALLTHROUGH;
- case 4: // 0B0100
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
- if (error.Fail())
- return false;
- NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
- break;
- case 5: // 0B0101
- {
- uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
- if (error.Fail())
- return false;
- float flt_value = 0.0f;
- memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
- NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
- break;
- }
- case 6: // 0B0110
- {
- uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
- if (error.Fail())
- return false;
- double dbl_value = 0.0;
- memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
- NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
- break;
- }
- default:
- return false;
- }
- return true;
- }
- }
+bool lldb_private::formatters::NSNumberSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+ if (!runtime)
return false;
-}
-bool
-lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (strcmp(class_name, "NSURL") == 0)
- {
- uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
- uint64_t offset_base = offset_text + ptr_size;
- CompilerType type(valobj.GetCompilerType());
- ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
- ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
- if (!text)
- return false;
- if (text->GetValueAsUnsigned(0) == 0)
- return false;
- StreamString summary;
- if (!NSStringSummaryProvider(*text, summary, options))
- return false;
- if (base && base->GetValueAsUnsigned(0))
- {
- if (summary.GetSize() > 0)
- summary.GetString().resize(summary.GetSize()-1);
- summary.Printf(" -- ");
- StreamString base_summary;
- if (NSURLSummaryProvider(*base, base_summary, options) && base_summary.GetSize() > 0)
- summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
- }
- if (summary.GetSize())
- {
- stream.Printf("%s",summary.GetData());
- return true;
- }
- }
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+ if (!descriptor || !descriptor->IsValid())
return false;
-}
-bool
-lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t date_value_bits = 0;
- double date_value = 0.0;
-
- ConstString class_name = descriptor->GetClassName();
-
- static const ConstString g_NSDate("NSDate");
- static const ConstString g___NSDate("__NSDate");
- static const ConstString g___NSTaggedDate("__NSTaggedDate");
- static const ConstString g_NSCalendarDate("NSCalendarDate");
-
- if (class_name.IsEmpty())
- return false;
-
- 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));
- }
- else
- {
- llvm::Triple triple(process_sp->GetTarget().GetArchitecture().GetTriple());
- uint32_t delta = (triple.isWatchOS() && triple.isWatchABI()) ? 8 : ptr_size;
- Error error;
- date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+delta, 8, 0, error);
- memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
- if (error.Fail())
- return false;
- }
- }
- else if (class_name == g_NSCalendarDate)
- {
- Error error;
- date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
- memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name, "__NSCFBoolean"))
+ return ObjCBooleanSummaryProvider(valobj, stream, options);
+
+ if (!strcmp(class_name, "NSNumber") || !strcmp(class_name, "__NSCFNumber")) {
+ uint64_t value = 0;
+ uint64_t i_bits = 0;
+ if (descriptor->GetTaggedPointerInfo(&i_bits, &value)) {
+ switch (i_bits) {
+ case 0:
+ NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
+ break;
+ case 1:
+ case 4:
+ NSNumber_FormatShort(valobj, stream, (short)value,
+ options.GetLanguage());
+ break;
+ case 2:
+ case 8:
+ NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
+ break;
+ case 3:
+ case 12:
+ NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
+ break;
+ default:
+ return false;
+ }
+ return true;
+ } else {
+ Error error;
+ uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + ptr_size, 1, 0, error) &
+ 0x1F);
+ uint64_t data_location = valobj_addr + 2 * ptr_size;
+ uint64_t value = 0;
+ if (error.Fail())
+ return false;
+ switch (data_type) {
+ case 1: // 0B00001
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0,
+ error);
+ if (error.Fail())
+ return false;
+ NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
+ break;
+ case 2: // 0B0010
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0,
+ error);
+ if (error.Fail())
+ return false;
+ NSNumber_FormatShort(valobj, stream, (short)value,
+ options.GetLanguage());
+ break;
+ case 3: // 0B0011
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0,
+ error);
+ if (error.Fail())
+ return false;
+ NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
+ break;
+ case 17: // 0B10001
+ data_location += 8;
+ LLVM_FALLTHROUGH;
+ case 4: // 0B0100
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0,
+ error);
if (error.Fail())
- return false;
+ return false;
+ NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
+ break;
+ case 5: // 0B0101
+ {
+ uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
+ data_location, 4, 0, error);
+ if (error.Fail())
+ return false;
+ float flt_value = 0.0f;
+ memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
+ NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
+ break;
+ }
+ case 6: // 0B0110
+ {
+ uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
+ data_location, 8, 0, error);
+ if (error.Fail())
+ return false;
+ double dbl_value = 0.0;
+ memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
+ NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
+ break;
+ }
+ default:
+ return false;
+ }
+ return true;
}
- else
- return false;
+ }
- if (date_value == -63114076800)
- {
- stream.Printf("0001-12-30 00:00:00 +0000");
- return true;
+ return false;
+}
+
+bool lldb_private::formatters::NSURLSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ llvm::StringRef class_name = descriptor->GetClassName().GetStringRef();
+
+ if (!class_name.equals("NSURL"))
+ return false;
+
+ uint64_t offset_text = ptr_size + ptr_size +
+ 8; // ISA + pointer + 8 bytes of data (even on 32bit)
+ uint64_t offset_base = offset_text + ptr_size;
+ CompilerType type(valobj.GetCompilerType());
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
+ ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
+ if (!text)
+ return false;
+ if (text->GetValueAsUnsigned(0) == 0)
+ return false;
+ StreamString summary;
+ if (!NSStringSummaryProvider(*text, summary, options))
+ return false;
+ if (base && base->GetValueAsUnsigned(0)) {
+ std::string summary_str = summary.GetString();
+
+ if (!summary_str.empty())
+ summary_str.pop_back();
+ summary_str += " -- ";
+ StreamString base_summary;
+ if (NSURLSummaryProvider(*base, base_summary, options) &&
+ !base_summary.Empty()) {
+ llvm::StringRef base_str = base_summary.GetString();
+ if (base_str.size() > 2)
+ base_str = base_str.drop_front(2);
+ summary_str += base_str;
}
- // this snippet of code assumes that time_t == seconds since Jan-1-1970
- // this is generally true and POSIXly happy, but might break if a library
- // vendor decides to get creative
- time_t epoch = GetOSXEpoch();
- epoch = epoch + (time_t)date_value;
- tm *tm_date = gmtime(&epoch);
- if (!tm_date)
- return false;
- std::string buffer(1024,0);
- if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
- return false;
- stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+ summary.Clear();
+ summary.PutCString(summary_str);
+ }
+ if (!summary.Empty()) {
+ stream.PutCString(summary.GetString());
return true;
+ }
+
+ return false;
}
-bool
-lldb_private::formatters::ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0)));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- ConstString class_name = descriptor->GetClassName();
-
- if (class_name.IsEmpty())
+bool lldb_private::formatters::NSDateSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t date_value_bits = 0;
+ double date_value = 0.0;
+
+ ConstString class_name = descriptor->GetClassName();
+
+ static const ConstString g_NSDate("NSDate");
+ static const ConstString g___NSDate("__NSDate");
+ static const ConstString g___NSTaggedDate("__NSTaggedDate");
+ static const ConstString g_NSCalendarDate("NSCalendarDate");
+
+ if (class_name.IsEmpty())
+ return false;
+
+ 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));
+ } else {
+ llvm::Triple triple(
+ process_sp->GetTarget().GetArchitecture().GetTriple());
+ uint32_t delta =
+ (triple.isWatchOS() && triple.isWatchABI()) ? 8 : ptr_size;
+ Error error;
+ date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + delta, 8, 0, error);
+ memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
+ if (error.Fail())
return false;
-
- if (ConstString cs = Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown))
- class_name = cs;
-
- stream.Printf("%s",class_name.AsCString("<unknown class>"));
+ }
+ } else if (class_name == g_NSCalendarDate) {
+ Error error;
+ date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + 2 * ptr_size, 8, 0, error);
+ memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
+ if (error.Fail())
+ return false;
+ } else
+ return false;
+
+ if (date_value == -63114076800) {
+ stream.Printf("0001-12-30 00:00:00 +0000");
return true;
+ }
+ // this snippet of code assumes that time_t == seconds since Jan-1-1970
+ // this is generally true and POSIXly happy, but might break if a library
+ // vendor decides to get creative
+ time_t epoch = GetOSXEpoch();
+ epoch = epoch + (time_t)date_value;
+ tm *tm_date = gmtime(&epoch);
+ if (!tm_date)
+ return false;
+ std::string buffer(1024, 0);
+ if (strftime(&buffer[0], 1023, "%Z", tm_date) == 0)
+ return false;
+ stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year + 1900,
+ tm_date->tm_mon + 1, tm_date->tm_mday, tm_date->tm_hour,
+ tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+ return true;
+}
+
+bool lldb_private::formatters::ObjCClassSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0)));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ ConstString class_name = descriptor->GetClassName();
+
+ if (class_name.IsEmpty())
+ return false;
+
+ if (ConstString cs =
+ Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown))
+ class_name = cs;
+
+ stream.Printf("%s", class_name.AsCString("<unknown class>"));
+ return true;
}
-class ObjCClassSyntheticChildrenFrontEnd : public SyntheticChildrenFrontEnd
-{
+class ObjCClassSyntheticChildrenFrontEnd : public SyntheticChildrenFrontEnd {
public:
- ObjCClassSyntheticChildrenFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp)
- {
- }
-
- ~ObjCClassSyntheticChildrenFrontEnd() override = default;
+ ObjCClassSyntheticChildrenFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp) {}
- size_t
- CalculateNumChildren() override
- {
- return 0;
- }
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override
- {
- return lldb::ValueObjectSP();
- }
-
- bool
- Update() override
- {
- return false;
- }
-
- bool
- MightHaveChildren() override
- {
- return false;
- }
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- return UINT32_MAX;
- }
+ ~ObjCClassSyntheticChildrenFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override { return 0; }
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+ return lldb::ValueObjectSP();
+ }
+
+ bool Update() override { return false; }
+
+ bool MightHaveChildren() override { return false; }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return UINT32_MAX;
+ }
};
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::ObjCClassSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- return new ObjCClassSyntheticChildrenFrontEnd(valobj_sp);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::ObjCClassSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return new ObjCClassSyntheticChildrenFrontEnd(valobj_sp);
}
-template<bool needs_at>
-bool
-lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- bool is_64bit = (process_sp->GetAddressByteSize() == 8);
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t value = 0;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSConcreteData") ||
- !strcmp(class_name,"NSConcreteMutableData") ||
- !strcmp(class_name,"__NSCFData"))
- {
- uint32_t offset = (is_64bit ? 16 : 8);
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
- if (error.Fail())
- return false;
- }
- else if (!strcmp(class_name, "_NSInlineData"))
- {
- uint32_t offset = (is_64bit ? 8 : 4);
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, 2, 0, error);
- if (error.Fail())
- return false;
- }
- else if (!strcmp(class_name, "_NSZeroData"))
- {
- value = 0;
- }
- else
- return false;
-
- stream.Printf("%s%" PRIu64 " byte%s%s",
- (needs_at ? "@\"" : ""),
- value,
- (value != 1 ? "s" : ""),
- (needs_at ? "\"" : ""));
-
- return true;
+template <bool needs_at>
+bool lldb_private::formatters::NSDataSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ bool is_64bit = (process_sp->GetAddressByteSize() == 8);
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name, "NSConcreteData") ||
+ !strcmp(class_name, "NSConcreteMutableData") ||
+ !strcmp(class_name, "__NSCFData")) {
+ uint32_t offset = (is_64bit ? 16 : 8);
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
+ if (error.Fail())
+ return false;
+ } else if (!strcmp(class_name, "_NSInlineData")) {
+ uint32_t offset = (is_64bit ? 8 : 4);
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, 2,
+ 0, error);
+ if (error.Fail())
+ return false;
+ } else if (!strcmp(class_name, "_NSZeroData")) {
+ value = 0;
+ } else
+ return false;
+
+ stream.Printf("%s%" PRIu64 " byte%s%s", (needs_at ? "@\"" : ""), value,
+ (value != 1 ? "s" : ""), (needs_at ? "\"" : ""));
+
+ return true;
}
-bool
-lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
-
- ValueObjectSP real_guy_sp = valobj.GetSP();
-
- if (type_info & eTypeIsPointer)
- {
- Error err;
- real_guy_sp = valobj.Dereference(err);
- if (err.Fail() || !real_guy_sp)
- return false;
- }
- else if (type_info & eTypeIsReference)
- {
- real_guy_sp = valobj.GetChildAtIndex(0, true);
- if (!real_guy_sp)
- return false;
+bool lldb_private::formatters::ObjCBOOLSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
+
+ ValueObjectSP real_guy_sp = valobj.GetSP();
+
+ if (type_info & eTypeIsPointer) {
+ Error err;
+ real_guy_sp = valobj.Dereference(err);
+ if (err.Fail() || !real_guy_sp)
+ return false;
+ } else if (type_info & eTypeIsReference) {
+ real_guy_sp = valobj.GetChildAtIndex(0, true);
+ if (!real_guy_sp)
+ return false;
+ }
+ uint8_t value = (real_guy_sp->GetValueAsUnsigned(0) & 0xFF);
+ switch (value) {
+ case 0:
+ stream.Printf("NO");
+ break;
+ case 1:
+ stream.Printf("YES");
+ break;
+ default:
+ stream.Printf("%u", value);
+ break;
+ }
+ return true;
+}
+
+bool lldb_private::formatters::ObjCBooleanSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ lldb::addr_t valobj_ptr_value =
+ valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (valobj_ptr_value == LLDB_INVALID_ADDRESS)
+ return false;
+
+ ProcessSP process_sp(valobj.GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ if (AppleObjCRuntime *objc_runtime =
+ (AppleObjCRuntime *)process_sp->GetObjCLanguageRuntime()) {
+ lldb::addr_t cf_true = LLDB_INVALID_ADDRESS,
+ cf_false = LLDB_INVALID_ADDRESS;
+ objc_runtime->GetValuesForGlobalCFBooleans(cf_true, cf_false);
+ if (valobj_ptr_value == cf_true) {
+ stream.PutCString("YES");
+ return true;
}
- uint8_t value = (real_guy_sp->GetValueAsUnsigned(0) & 0xFF);
- switch (value)
- {
- case 0:
- stream.Printf("NO");
- break;
- case 1:
- stream.Printf("YES");
- break;
- default:
- stream.Printf("%u",value);
- break;
+ if (valobj_ptr_value == cf_false) {
+ stream.PutCString("NO");
+ return true;
}
- return true;
+ }
+
+ return false;
}
template <bool is_sel_ptr>
-bool
-lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- lldb::ValueObjectSP valobj_sp;
-
- CompilerType charstar (valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeChar).GetPointerType());
-
- if (!charstar)
- return false;
-
- ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
-
- if (is_sel_ptr)
- {
- lldb::addr_t data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- if (data_address == LLDB_INVALID_ADDRESS)
- return false;
- valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar);
- }
- else
- {
- DataExtractor data;
- Error error;
- valobj.GetData(data, error);
- if (error.Fail())
- return false;
- valobj_sp = ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar);
- }
-
- if (!valobj_sp)
- return false;
-
- stream.Printf("%s",valobj_sp->GetSummaryAsCString());
- return true;
+bool lldb_private::formatters::ObjCSELSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ lldb::ValueObjectSP valobj_sp;
+
+ CompilerType charstar(valobj.GetCompilerType()
+ .GetBasicTypeFromAST(eBasicTypeChar)
+ .GetPointerType());
+
+ if (!charstar)
+ return false;
+
+ ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+
+ if (is_sel_ptr) {
+ lldb::addr_t data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (data_address == LLDB_INVALID_ADDRESS)
+ return false;
+ valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address,
+ exe_ctx, charstar);
+ } else {
+ DataExtractor data;
+ Error error;
+ valobj.GetData(data, error);
+ if (error.Fail())
+ return false;
+ valobj_sp =
+ ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar);
+ }
+
+ if (!valobj_sp)
+ return false;
+
+ stream.Printf("%s", valobj_sp->GetSummaryAsCString());
+ return true;
}
// POSIX has an epoch on Jan-1-1970, but Cocoa prefers Jan-1-2001
// this call gives the POSIX equivalent of the Cocoa epoch
-time_t
-lldb_private::formatters::GetOSXEpoch ()
-{
- static time_t epoch = 0;
- if (!epoch)
- {
+time_t lldb_private::formatters::GetOSXEpoch() {
+ static time_t epoch = 0;
+ if (!epoch) {
#ifndef _WIN32
- tzset();
- tm tm_epoch;
- tm_epoch.tm_sec = 0;
- tm_epoch.tm_hour = 0;
- tm_epoch.tm_min = 0;
- tm_epoch.tm_mon = 0;
- tm_epoch.tm_mday = 1;
- tm_epoch.tm_year = 2001-1900;
- tm_epoch.tm_isdst = -1;
- tm_epoch.tm_gmtoff = 0;
- tm_epoch.tm_zone = nullptr;
- epoch = timegm(&tm_epoch);
+ tzset();
+ tm tm_epoch;
+ tm_epoch.tm_sec = 0;
+ tm_epoch.tm_hour = 0;
+ tm_epoch.tm_min = 0;
+ tm_epoch.tm_mon = 0;
+ tm_epoch.tm_mday = 1;
+ tm_epoch.tm_year = 2001 - 1900;
+ tm_epoch.tm_isdst = -1;
+ tm_epoch.tm_gmtoff = 0;
+ tm_epoch.tm_zone = nullptr;
+ epoch = timegm(&tm_epoch);
#endif
- }
- return epoch;
+ }
+ return epoch;
}
-template bool
-lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDataSummaryProvider<true>(
+ ValueObject &, Stream &, const TypeSummaryOptions &);
-template bool
-lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDataSummaryProvider<false>(
+ ValueObject &, Stream &, const TypeSummaryOptions &);
-template bool
-lldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::ObjCSELSummaryProvider<true>(
+ ValueObject &, Stream &, const TypeSummaryOptions &);
-template bool
-lldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::ObjCSELSummaryProvider<false>(
+ ValueObject &, Stream &, const TypeSummaryOptions &);
diff --git a/source/Plugins/Language/ObjC/Cocoa.h b/source/Plugins/Language/ObjC/Cocoa.h
index f43b1639cb38..491a1196e63d 100644
--- a/source/Plugins/Language/ObjC/Cocoa.h
+++ b/source/Plugins/Language/ObjC/Cocoa.h
@@ -1,4 +1,5 @@
-//===-- Cocoa.h ---------------------------------------------------*- C++ -*-===//
+//===-- Cocoa.h ---------------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,89 +18,96 @@
#include "lldb/Target/ObjCLanguageRuntime.h"
namespace lldb_private {
- namespace formatters
- {
- bool
- NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- template<bool needs_at>
- bool
- NSDataSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSNumberSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSDateSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSURLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- extern template bool
- NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-
- extern template bool
- NSDataSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-
- SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- bool
- ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- SyntheticChildrenFrontEnd* ObjCClassSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- bool
- ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- template <bool is_sel_ptr>
- bool
- ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- extern template bool
- ObjCSELSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
-
- extern template bool
- ObjCSELSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
-
- bool
- NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSException_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- SyntheticChildrenFrontEnd*
- NSErrorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp);
-
- SyntheticChildrenFrontEnd*
- NSExceptionSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp);
-
- class NSArray_Additionals
- {
- public:
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
- GetAdditionalSummaries ();
-
- static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
- GetAdditionalSynthetics ();
- };
- } // namespace formatters
+namespace formatters {
+bool NSIndexSetSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSArraySummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+template <bool needs_at>
+bool NSDataSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSNumberSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSNotificationSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSTimeZoneSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSMachPortSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSDateSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSBundleSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSURLSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+extern template bool NSDataSummaryProvider<true>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+
+extern template bool NSDataSummaryProvider<false>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+
+SyntheticChildrenFrontEnd *
+NSArraySyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+NSIndexPathSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+bool ObjCClassSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd *
+ObjCClassSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
+
+bool ObjCBOOLSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool ObjCBooleanSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+template <bool is_sel_ptr>
+bool ObjCSELSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+extern template bool ObjCSELSummaryProvider<true>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+
+extern template bool ObjCSELSummaryProvider<false>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+
+bool NSError_SummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSException_SummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd *
+NSErrorSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
+
+SyntheticChildrenFrontEnd *
+NSExceptionSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
+
+class NSArray_Additionals {
+public:
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+ GetAdditionalSummaries();
+
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+ GetAdditionalSynthetics();
+};
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_Cocoa_h_
diff --git a/source/Plugins/Language/ObjC/CoreMedia.cpp b/source/Plugins/Language/ObjC/CoreMedia.cpp
index 4103067b8d58..dacbf78755e0 100644
--- a/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -1,4 +1,5 @@
-//===-- CoreMedia.cpp --------------------------------------------*- C++ -*-===//
+//===-- CoreMedia.cpp --------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,72 +19,77 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool
-lldb_private::formatters::CMTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- CompilerType type = valobj.GetCompilerType();
- if (!type.IsValid())
- return false;
+bool lldb_private::formatters::CMTimeSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ CompilerType type = valobj.GetCompilerType();
+ if (!type.IsValid())
+ return false;
- TypeSystem *type_system = valobj.GetExecutionContextRef().GetTargetSP()->GetScratchTypeSystemForLanguage(nullptr, lldb::eLanguageTypeC);
- if (!type_system)
- return false;
-
- // fetch children by offset to compensate for potential lack of debug info
- auto int64_ty = type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
- auto int32_ty = type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
-
- auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
- auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
- auto flags_sp(valobj.GetSyntheticChildAtOffset(12, int32_ty, true));
-
- if (!value_sp || !timescale_sp || !flags_sp)
- return false;
-
- auto value = value_sp->GetValueAsUnsigned(0);
- auto timescale = (int32_t)timescale_sp->GetValueAsUnsigned(0); // the timescale specifies the fraction of a second each unit in the numerator occupies
- auto flags = Flags(flags_sp->GetValueAsUnsigned(0) & 0x00000000000000FF); // the flags I need sit in the LSB
-
- const unsigned int FlagPositiveInf = 4;
- const unsigned int FlagNegativeInf = 8;
- const unsigned int FlagIndefinite = 16;
-
- if (flags.AnySet(FlagIndefinite))
- {
- stream.Printf("indefinite");
- return true;
- }
-
- if (flags.AnySet(FlagPositiveInf))
- {
- stream.Printf("+oo");
- return true;
- }
-
- if (flags.AnySet(FlagNegativeInf))
- {
- stream.Printf("-oo");
- return true;
- }
-
- if (timescale == 0)
- return false;
-
- switch (timescale)
- {
- case 0:
- return false;
- case 1:
- stream.Printf("%" PRId64 " seconds", value);
- return true;
- case 2:
- stream.Printf("%" PRId64 " half seconds", value);
- return true;
- case 3:
- stream.Printf("%" PRId64 " third%sof a second", value, value == 1 ? " " : "s ");
- return true;
- default:
- stream.Printf("%" PRId64 " %" PRId32 "th%sof a second", value, timescale, value == 1 ? " " : "s ");
- return true;
- }
+ TypeSystem *type_system =
+ valobj.GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchTypeSystemForLanguage(nullptr, lldb::eLanguageTypeC);
+ if (!type_system)
+ return false;
+
+ // fetch children by offset to compensate for potential lack of debug info
+ auto int64_ty =
+ type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
+ auto int32_ty =
+ type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
+
+ auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
+ auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
+ auto flags_sp(valobj.GetSyntheticChildAtOffset(12, int32_ty, true));
+
+ if (!value_sp || !timescale_sp || !flags_sp)
+ return false;
+
+ auto value = value_sp->GetValueAsUnsigned(0);
+ auto timescale = (int32_t)timescale_sp->GetValueAsUnsigned(
+ 0); // the timescale specifies the fraction of a second each unit in the
+ // numerator occupies
+ auto flags = Flags(flags_sp->GetValueAsUnsigned(0) &
+ 0x00000000000000FF); // the flags I need sit in the LSB
+
+ const unsigned int FlagPositiveInf = 4;
+ const unsigned int FlagNegativeInf = 8;
+ const unsigned int FlagIndefinite = 16;
+
+ if (flags.AnySet(FlagIndefinite)) {
+ stream.Printf("indefinite");
+ return true;
+ }
+
+ if (flags.AnySet(FlagPositiveInf)) {
+ stream.Printf("+oo");
+ return true;
+ }
+
+ if (flags.AnySet(FlagNegativeInf)) {
+ stream.Printf("-oo");
+ return true;
+ }
+
+ if (timescale == 0)
+ return false;
+
+ switch (timescale) {
+ case 0:
+ return false;
+ case 1:
+ stream.Printf("%" PRId64 " seconds", value);
+ return true;
+ case 2:
+ stream.Printf("%" PRId64 " half seconds", value);
+ return true;
+ case 3:
+ stream.Printf("%" PRId64 " third%sof a second", value,
+ value == 1 ? " " : "s ");
+ return true;
+ default:
+ stream.Printf("%" PRId64 " %" PRId32 "th%sof a second", value, timescale,
+ value == 1 ? " " : "s ");
+ return true;
+ }
}
diff --git a/source/Plugins/Language/ObjC/CoreMedia.h b/source/Plugins/Language/ObjC/CoreMedia.h
index 2ffabaadccf5..20de792fc96c 100644
--- a/source/Plugins/Language/ObjC/CoreMedia.h
+++ b/source/Plugins/Language/ObjC/CoreMedia.h
@@ -1,4 +1,5 @@
-//===-- CoreMedia.h -----------------------------------------------*- C++ -*-===//
+//===-- CoreMedia.h -----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,12 +16,11 @@
#include "lldb/DataFormatters/TypeSummary.h"
namespace lldb_private {
- namespace formatters
- {
-
- bool
- CMTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
- } // namespace formatters
+namespace formatters {
+
+bool CMTimeSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_CF_h_
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index 5de97b6f0257..6ab6d537bb21 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -15,6 +15,7 @@
// Project includes
#include "Cocoa.h"
+#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
@@ -26,801 +27,683 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-namespace lldb_private {
- namespace formatters {
- std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
- NSArray_Additionals::GetAdditionalSummaries ()
- {
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
- return g_map;
- }
-
- std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
- NSArray_Additionals::GetAdditionalSynthetics ()
- {
- static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
- return g_map;
- }
-
- class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayMSyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override = 0;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- protected:
- virtual lldb::addr_t
- GetDataAddress () = 0;
-
- virtual uint64_t
- GetUsedCount () = 0;
-
- virtual uint64_t
- GetOffset () = 0;
-
- virtual uint64_t
- GetSize () = 0;
-
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- CompilerType m_id_type;
- };
-
- class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd
- {
- public:
- NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayMSyntheticFrontEnd_109() override;
-
- bool
- Update() override;
-
- protected:
- lldb::addr_t
- GetDataAddress() override;
-
- uint64_t
- GetUsedCount() override;
-
- uint64_t
- GetOffset() override;
-
- uint64_t
- GetSize() override;
-
- private:
- struct DataDescriptor_32
- {
- uint32_t _used;
- uint32_t _priv1 : 2;
- uint32_t _size : 30;
- uint32_t _priv2 : 2;
- uint32_t _offset : 30;
- uint32_t _priv3;
- uint32_t _data;
- };
-
- struct DataDescriptor_64
- {
- uint64_t _used;
- uint64_t _priv1 : 2;
- uint64_t _size : 62;
- uint64_t _priv2 : 2;
- uint64_t _offset : 62;
- uint32_t _priv3;
- uint64_t _data;
- };
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- };
-
- class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd
- {
- public:
- NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayMSyntheticFrontEnd_1010() override;
-
- bool
- Update() override;
-
- protected:
- lldb::addr_t
- GetDataAddress() override;
-
- uint64_t
- GetUsedCount() override;
-
- uint64_t
- GetOffset() override;
-
- uint64_t
- GetSize() override;
-
- private:
- struct DataDescriptor_32
- {
- uint32_t _used;
- uint32_t _offset;
- uint32_t _size : 28;
- uint64_t _priv1 : 4;
- uint32_t _priv2;
- uint32_t _data;
- };
-
- struct DataDescriptor_64
- {
- uint64_t _used;
- uint64_t _offset;
- uint64_t _size : 60;
- uint64_t _priv1 : 4;
- uint32_t _priv2;
- uint64_t _data;
- };
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- };
-
- class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayISyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- uint64_t m_items;
- lldb::addr_t m_data_ptr;
- CompilerType m_id_type;
- };
-
- class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSArray0SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSArray0SyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
- };
-
- class NSArray1SyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSArray1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSArray1SyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
- };
- } // namespace formatters
-} // namespace lldb_private
-
-bool
-lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- static ConstString g_TypeHint("NSArray");
-
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t value = 0;
-
- ConstString class_name(descriptor->GetClassName());
-
- static const ConstString g_NSArrayI("__NSArrayI");
- static const ConstString g_NSArrayM("__NSArrayM");
- static const ConstString g_NSArray0("__NSArray0");
- static const ConstString g_NSArray1("__NSSingleObjectArrayI");
- static const ConstString g_NSArrayCF("__NSCFArray");
-
- if (class_name.IsEmpty())
- return false;
-
- if (class_name == g_NSArrayI)
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else if (class_name == g_NSArrayM)
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else if (class_name == g_NSArray0)
- {
- value = 0;
- }
- else if (class_name == g_NSArray1)
- {
- value = 1;
- }
- else if (class_name == g_NSArrayCF)
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else
- {
- auto& map(NSArray_Additionals::GetAdditionalSummaries());
- auto iter = map.find(class_name), end = map.end();
- if (iter != end)
- return iter->second(valobj, stream, options);
- else
- return false;
- }
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(options.GetLanguage()))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
- }
-
- stream.Printf("%s%" PRIu64 " %s%s%s",
- prefix.c_str(),
- value,
- "element",
- value == 1 ? "" : "s",
- suffix.c_str());
- return true;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_id_type()
-{
- if (valobj_sp)
- {
- clang::ASTContext *ast = valobj_sp->GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext()->getASTContext();
- if (ast)
- m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy);
- if (valobj_sp->GetProcessSP())
- m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
- }
+namespace lldb_private {
+namespace formatters {
+std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+NSArray_Additionals::GetAdditionalSummaries() {
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp) :
- NSArrayMSyntheticFrontEnd(valobj_sp),
- m_data_32(nullptr),
- m_data_64(nullptr)
-{
+std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+NSArray_Additionals::GetAdditionalSynthetics() {
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
+ g_map;
+ return g_map;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp) :
- NSArrayMSyntheticFrontEnd(valobj_sp),
- m_data_32(nullptr),
- m_data_64(nullptr)
-{
-}
+class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
-size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
-{
- return GetUsedCount();
-}
+ ~NSArrayMSyntheticFrontEnd() override = default;
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = GetDataAddress();
- size_t pyhs_idx = idx;
- pyhs_idx += GetOffset();
- if (GetSize() <= pyhs_idx)
- pyhs_idx -= GetSize();
- object_at_idx += (pyhs_idx * m_ptr_size);
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return CreateValueObjectFromAddress(idx_name.GetData(),
- object_at_idx,
- m_exe_ctx_ref,
- m_id_type);
-}
-
-bool
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update()
-{
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override = 0;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+protected:
+ virtual lldb::addr_t GetDataAddress() = 0;
+
+ virtual uint64_t GetUsedCount() = 0;
+
+ virtual uint64_t GetOffset() = 0;
+
+ virtual uint64_t GetSize() = 0;
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ CompilerType m_id_type;
+};
+
+class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd {
+public:
+ NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp);
+
+ ~NSArrayMSyntheticFrontEnd_109() override;
+
+ bool Update() override;
+
+protected:
+ lldb::addr_t GetDataAddress() override;
+
+ uint64_t GetUsedCount() override;
+
+ uint64_t GetOffset() override;
+
+ uint64_t GetSize() override;
+
+private:
+ struct DataDescriptor_32 {
+ uint32_t _used;
+ uint32_t _priv1 : 2;
+ uint32_t _size : 30;
+ uint32_t _priv2 : 2;
+ uint32_t _offset : 30;
+ uint32_t _priv3;
+ uint32_t _data;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used;
+ uint64_t _priv1 : 2;
+ uint64_t _size : 62;
+ uint64_t _priv2 : 2;
+ uint64_t _offset : 62;
+ uint32_t _priv3;
+ uint64_t _data;
+ };
+
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+};
+
+class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd {
+public:
+ NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp);
+
+ ~NSArrayMSyntheticFrontEnd_1010() override;
+
+ bool Update() override;
+
+protected:
+ lldb::addr_t GetDataAddress() override;
+
+ uint64_t GetUsedCount() override;
+
+ uint64_t GetOffset() override;
+
+ uint64_t GetSize() override;
+
+private:
+ struct DataDescriptor_32 {
+ uint32_t _used;
+ uint32_t _offset;
+ uint32_t _size : 28;
+ uint64_t _priv1 : 4;
+ uint32_t _priv2;
+ uint32_t _data;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used;
+ uint64_t _offset;
+ uint64_t _size : 60;
+ uint64_t _priv1 : 4;
+ uint32_t _priv2;
+ uint64_t _data;
+ };
+
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+};
+
+class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSArrayISyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ uint64_t m_items;
+ lldb::addr_t m_data_ptr;
+ CompilerType m_id_type;
+};
+
+class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSArray0SyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+};
+
+class NSArray1SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSArray1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSArray1SyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+};
+} // namespace formatters
+} // namespace lldb_private
+
+bool lldb_private::formatters::NSArraySummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ static ConstString g_TypeHint("NSArray");
+
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ ConstString class_name(descriptor->GetClassName());
+
+ static const ConstString g_NSArrayI("__NSArrayI");
+ static const ConstString g_NSArrayM("__NSArrayM");
+ static const ConstString g_NSArray0("__NSArray0");
+ static const ConstString g_NSArray1("__NSSingleObjectArrayI");
+ static const ConstString g_NSArrayCF("__NSCFArray");
+
+ if (class_name.IsEmpty())
+ return false;
+
+ if (class_name == g_NSArrayI) {
Error error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ } else if (class_name == g_NSArrayM) {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ } else if (class_name == g_NSArray0) {
+ value = 0;
+ } else if (class_name == g_NSArray1) {
+ value = 1;
+ } else if (class_name == g_NSArrayCF) {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(
+ valobj_addr + 2 * ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ } else {
+ auto &map(NSArray_Additionals::GetAdditionalSummaries());
+ auto iter = map.find(class_name), end = map.end();
+ if (iter != end)
+ return iter->second(valobj, stream, options);
else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+ return false;
+ }
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
- if (error.Fail())
- return false;
+ }
+
+ stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element",
+ value == 1 ? "" : "s", suffix.c_str());
+ return true;
+}
+
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_id_type() {
+ if (valobj_sp) {
+ clang::ASTContext *ast = valobj_sp->GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchClangASTContext()
+ ->getASTContext();
+ if (ast)
+ m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy);
+ if (valobj_sp->GetProcessSP())
+ m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
+ }
+}
+
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
+ NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp)
+ : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
+ m_data_64(nullptr) {}
+
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
+ NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp)
+ : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
+ m_data_64(nullptr) {}
+
+size_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren() {
+ return GetUsedCount();
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+ lldb::addr_t object_at_idx = GetDataAddress();
+ size_t pyhs_idx = idx;
+ pyhs_idx += GetOffset();
+ if (GetSize() <= pyhs_idx)
+ pyhs_idx -= GetSize();
+ object_at_idx += (pyhs_idx * m_ptr_size);
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
+ m_exe_ctx_ref, m_id_type);
+}
+
+bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update() {
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
+ if (!valobj_sp)
return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+ if (m_ptr_size == 4) {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ error);
+ } else {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ error);
+ }
+ if (error.Fail())
+ return false;
+ return false;
}
-bool
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update()
-{
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
+bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update() {
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+ if (m_ptr_size == 4) {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ error);
+ } else {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ error);
+ }
+ if (error.Fail())
+ return false;
+ return false;
}
-bool
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren() {
+ return true;
}
size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::~NSArrayMSyntheticFrontEnd_109()
-{
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
+ ~NSArrayMSyntheticFrontEnd_109() {
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
}
lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress ()
-{
- if (!m_data_32 && !m_data_64)
- return LLDB_INVALID_ADDRESS;
- return m_data_32 ? m_data_32->_data :
- m_data_64->_data;
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress() {
+ if (!m_data_32 && !m_data_64)
+ return LLDB_INVALID_ADDRESS;
+ return m_data_32 ? m_data_32->_data : m_data_64->_data;
}
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_used :
- m_data_64->_used;
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return m_data_32 ? m_data_32->_used : m_data_64->_used;
}
-uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_offset :
- m_data_64->_offset;
+uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
}
-uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_size :
- m_data_64->_size;
+uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return m_data_32 ? m_data_32->_size : m_data_64->_size;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::~NSArrayMSyntheticFrontEnd_1010()
-{
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
+ ~NSArrayMSyntheticFrontEnd_1010() {
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
}
lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetDataAddress ()
-{
- if (!m_data_32 && !m_data_64)
- return LLDB_INVALID_ADDRESS;
- return m_data_32 ? m_data_32->_data :
- m_data_64->_data;
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetDataAddress() {
+ if (!m_data_32 && !m_data_64)
+ return LLDB_INVALID_ADDRESS;
+ return m_data_32 ? m_data_32->_data : m_data_64->_data;
}
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetUsedCount ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_used :
- m_data_64->_used;
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetUsedCount() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return m_data_32 ? m_data_32->_used : m_data_64->_used;
}
-uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_offset :
- m_data_64->_offset;
+uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
}
-uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_size :
- m_data_64->_size;
-}
-
-lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_exe_ctx_ref(),
- m_ptr_size(8),
- m_items(0),
- m_data_ptr(0)
-{
- if (valobj_sp)
- {
- CompilerType type = valobj_sp->GetCompilerType();
- if (type)
- {
- ClangASTContext *ast = valobj_sp->GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext();
- if (ast)
- m_id_type = CompilerType(ast->getASTContext(), ast->getASTContext()->ObjCBuiltinIdTy);
- }
+uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return m_data_32 ? m_data_32->_size : m_data_64->_size;
+}
+
+lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_items(0), m_data_ptr(0) {
+ if (valobj_sp) {
+ CompilerType type = valobj_sp->GetCompilerType();
+ if (type) {
+ ClangASTContext *ast = valobj_sp->GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchClangASTContext();
+ if (ast)
+ m_id_type = CompilerType(ast->getASTContext(),
+ ast->getASTContext()->ObjCBuiltinIdTy);
}
+ }
}
size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
}
size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
-{
- return m_items;
-}
-
-bool
-lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
-{
- m_ptr_size = 0;
- m_items = 0;
- m_data_ptr = 0;
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- m_items = process_sp->ReadPointerFromMemory(data_location, error);
- if (error.Fail())
- return false;
- m_data_ptr = data_location+m_ptr_size;
+lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren() {
+ return m_items;
+}
+
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd::Update() {
+ m_ptr_size = 0;
+ m_items = 0;
+ m_data_ptr = 0;
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+ m_items = process_sp->ReadPointerFromMemory(data_location, error);
+ if (error.Fail())
+ return false;
+ m_data_ptr = data_location + m_ptr_size;
+ return false;
}
-bool
-lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren() {
+ return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = m_data_ptr;
- object_at_idx += (idx * m_ptr_size);
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- if (error.Fail())
- return lldb::ValueObjectSP();
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return CreateValueObjectFromAddress(idx_name.GetData(),
- object_at_idx,
- m_exe_ctx_ref,
- m_id_type);
+lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+ lldb::addr_t object_at_idx = m_data_ptr;
+ object_at_idx += (idx * m_ptr_size);
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+ Error error;
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
+ m_exe_ctx_ref, m_id_type);
}
-lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp)
-{
-}
+lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp) {}
size_t
-lldb_private::formatters::NSArray0SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return UINT32_MAX;
+lldb_private::formatters::NSArray0SyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ return UINT32_MAX;
}
size_t
-lldb_private::formatters::NSArray0SyntheticFrontEnd::CalculateNumChildren ()
-{
- return 0;
+lldb_private::formatters::NSArray0SyntheticFrontEnd::CalculateNumChildren() {
+ return 0;
}
-bool
-lldb_private::formatters::NSArray0SyntheticFrontEnd::Update()
-{
- return false;
+bool lldb_private::formatters::NSArray0SyntheticFrontEnd::Update() {
+ return false;
}
-bool
-lldb_private::formatters::NSArray0SyntheticFrontEnd::MightHaveChildren ()
-{
- return false;
+bool lldb_private::formatters::NSArray0SyntheticFrontEnd::MightHaveChildren() {
+ return false;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSArray0SyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- return lldb::ValueObjectSP();
+lldb_private::formatters::NSArray0SyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ return lldb::ValueObjectSP();
}
-lldb_private::formatters::NSArray1SyntheticFrontEnd::NSArray1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd (*valobj_sp.get())
-{
-}
+lldb_private::formatters::NSArray1SyntheticFrontEnd::NSArray1SyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp.get()) {}
size_t
-lldb_private::formatters::NSArray1SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- static const ConstString g_zero("[0]");
-
- if (name == g_zero)
- return 0;
-
- return UINT32_MAX;
+lldb_private::formatters::NSArray1SyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ static const ConstString g_zero("[0]");
+
+ if (name == g_zero)
+ return 0;
+
+ return UINT32_MAX;
}
size_t
-lldb_private::formatters::NSArray1SyntheticFrontEnd::CalculateNumChildren ()
-{
- return 1;
+lldb_private::formatters::NSArray1SyntheticFrontEnd::CalculateNumChildren() {
+ return 1;
}
-bool
-lldb_private::formatters::NSArray1SyntheticFrontEnd::Update()
-{
- return false;
+bool lldb_private::formatters::NSArray1SyntheticFrontEnd::Update() {
+ return false;
}
-bool
-lldb_private::formatters::NSArray1SyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSArray1SyntheticFrontEnd::MightHaveChildren() {
+ return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- static const ConstString g_zero("[0]");
-
- if (idx == 0)
- {
- CompilerType id_type(m_backend.GetTargetSP()->GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
- return m_backend.GetSyntheticChildAtOffset(m_backend.GetProcessSP()->GetAddressByteSize(), id_type, true, g_zero);
- }
- return lldb::ValueObjectSP();
-}
+lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ static const ConstString g_zero("[0]");
+
+ if (idx == 0) {
+ CompilerType id_type(
+ m_backend.GetTargetSP()->GetScratchClangASTContext()->GetBasicType(
+ lldb::eBasicTypeObjCID));
+ return m_backend.GetSyntheticChildAtOffset(
+ m_backend.GetProcessSP()->GetAddressByteSize(), id_type, true, g_zero);
+ }
+ return lldb::ValueObjectSP();
+}
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSArraySyntheticFrontEndCreator(
+ CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
+ if (!valobj_sp)
+ return nullptr;
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
-{
- if (!valobj_sp)
- return nullptr;
-
- lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
- if (!process_sp)
- return nullptr;
- AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(process_sp->GetObjCLanguageRuntime());
- if (!runtime)
- return nullptr;
-
- CompilerType valobj_type(valobj_sp->GetCompilerType());
- Flags flags(valobj_type.GetTypeInfo());
-
- if (flags.IsClear(eTypeIsPointer))
- {
- Error error;
- valobj_sp = valobj_sp->AddressOf(error);
- if (error.Fail() || !valobj_sp)
- return nullptr;
- }
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp));
-
- if (!descriptor || !descriptor->IsValid())
- return nullptr;
-
- ConstString class_name(descriptor->GetClassName());
-
- static const ConstString g_NSArrayI("__NSArrayI");
- static const ConstString g_NSArrayM("__NSArrayM");
- static const ConstString g_NSArray0("__NSArray0");
- static const ConstString g_NSArray1("__NSSingleObjectArrayI");
-
- if (class_name.IsEmpty())
- return nullptr;
-
- if (class_name == g_NSArrayI)
- {
- return (new NSArrayISyntheticFrontEnd(valobj_sp));
- }
- else if (class_name == g_NSArray0)
- {
- return (new NSArray0SyntheticFrontEnd(valobj_sp));
- }
- else if (class_name == g_NSArray1)
- {
- return (new NSArray1SyntheticFrontEnd(valobj_sp));
- }
- else if (class_name == g_NSArrayM)
- {
- if (runtime->GetFoundationVersion() >= 1100)
- return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
- else
- return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
- }
- else
- {
- auto& map(NSArray_Additionals::GetAdditionalSynthetics());
- auto iter = map.find(class_name), end = map.end();
- if (iter != end)
- return iter->second(synth, valobj_sp);
- }
-
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return nullptr;
+ AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
+ process_sp->GetObjCLanguageRuntime());
+ if (!runtime)
return nullptr;
+
+ CompilerType valobj_type(valobj_sp->GetCompilerType());
+ Flags flags(valobj_type.GetTypeInfo());
+
+ if (flags.IsClear(eTypeIsPointer)) {
+ Error error;
+ valobj_sp = valobj_sp->AddressOf(error);
+ if (error.Fail() || !valobj_sp)
+ return nullptr;
+ }
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(*valobj_sp));
+
+ if (!descriptor || !descriptor->IsValid())
+ return nullptr;
+
+ ConstString class_name(descriptor->GetClassName());
+
+ static const ConstString g_NSArrayI("__NSArrayI");
+ static const ConstString g_NSArrayM("__NSArrayM");
+ static const ConstString g_NSArray0("__NSArray0");
+ static const ConstString g_NSArray1("__NSSingleObjectArrayI");
+
+ if (class_name.IsEmpty())
+ return nullptr;
+
+ if (class_name == g_NSArrayI) {
+ return (new NSArrayISyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSArray0) {
+ return (new NSArray0SyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSArray1) {
+ return (new NSArray1SyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSArrayM) {
+ if (runtime->GetFoundationVersion() >= 1100)
+ return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
+ else
+ return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
+ } else {
+ auto &map(NSArray_Additionals::GetAdditionalSynthetics());
+ auto iter = map.find(class_name), end = map.end();
+ if (iter != end)
+ return iter->second(synth, valobj_sp);
+ }
+
+ return nullptr;
}
diff --git a/source/Plugins/Language/ObjC/NSDictionary.cpp b/source/Plugins/Language/ObjC/NSDictionary.cpp
index cdebd6b3c23c..5cc52c820b65 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -34,768 +34,709 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-NSDictionary_Additionals::GetAdditionalSummaries ()
-{
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
- return g_map;
+NSDictionary_Additionals::AdditionalFormatterMatching::Prefix::Prefix(
+ ConstString p)
+ : m_prefix(p) {}
+
+bool NSDictionary_Additionals::AdditionalFormatterMatching::Prefix::Match(
+ ConstString class_name) {
+ return class_name.GetStringRef().startswith(m_prefix.GetStringRef());
}
-std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
-NSDictionary_Additionals::GetAdditionalSynthetics ()
-{
- static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
- return g_map;
+NSDictionary_Additionals::AdditionalFormatterMatching::Full::Full(ConstString n)
+ : m_name(n) {}
+
+bool NSDictionary_Additionals::AdditionalFormatterMatching::Full::Match(
+ ConstString class_name) {
+ return (class_name == m_name);
}
-static CompilerType
-GetLLDBNSPairType (TargetSP target_sp)
-{
- CompilerType compiler_type;
-
- ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
-
- if (target_ast_context)
- {
- ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair");
-
- compiler_type = target_ast_context->GetTypeForIdentifier<clang::CXXRecordDecl>(g___lldb_autogen_nspair);
-
- if (!compiler_type)
- {
- compiler_type = target_ast_context->CreateRecordType(nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
-
- if (compiler_type)
- {
- ClangASTContext::StartTagDeclarationDefinition(compiler_type);
- CompilerType id_compiler_type = target_ast_context->GetBasicType (eBasicTypeObjCID);
- ClangASTContext::AddFieldToRecordType(compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType(compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0);
- ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
- }
- }
+NSDictionary_Additionals::AdditionalFormatters<
+ CXXFunctionSummaryFormat::Callback> &
+NSDictionary_Additionals::GetAdditionalSummaries() {
+ static AdditionalFormatters<CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
+}
+
+NSDictionary_Additionals::AdditionalFormatters<
+ CXXSyntheticChildren::CreateFrontEndCallback> &
+NSDictionary_Additionals::GetAdditionalSynthetics() {
+ static AdditionalFormatters<CXXSyntheticChildren::CreateFrontEndCallback>
+ g_map;
+ return g_map;
+}
+
+static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
+ CompilerType compiler_type;
+
+ ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
+
+ if (target_ast_context) {
+ ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair");
+
+ compiler_type =
+ target_ast_context->GetTypeForIdentifier<clang::CXXRecordDecl>(
+ g___lldb_autogen_nspair);
+
+ if (!compiler_type) {
+ compiler_type = target_ast_context->CreateRecordType(
+ nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
+ clang::TTK_Struct, lldb::eLanguageTypeC);
+
+ if (compiler_type) {
+ ClangASTContext::StartTagDeclarationDefinition(compiler_type);
+ CompilerType id_compiler_type =
+ target_ast_context->GetBasicType(eBasicTypeObjCID);
+ ClangASTContext::AddFieldToRecordType(
+ compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0);
+ ClangASTContext::AddFieldToRecordType(
+ compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0);
+ ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+ }
}
- return compiler_type;
+ }
+ return compiler_type;
}
namespace lldb_private {
- namespace formatters {
- class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSDictionaryISyntheticFrontEnd() override;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- struct DataDescriptor_32
- {
- uint32_t _used : 26;
- uint32_t _szidx : 6;
- };
-
- struct DataDescriptor_64
- {
- uint64_t _used : 58;
- uint32_t _szidx : 6;
- };
-
- struct DictionaryItemDescriptor
- {
- lldb::addr_t key_ptr;
- lldb::addr_t val_ptr;
- lldb::ValueObjectSP valobj_sp;
- };
-
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- lldb::ByteOrder m_order;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- lldb::addr_t m_data_ptr;
- CompilerType m_pair_type;
- std::vector<DictionaryItemDescriptor> m_children;
- };
-
- class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSDictionary1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSDictionary1SyntheticFrontEnd() override = default;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- ValueObjectSP m_pair;
- };
-
- class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSDictionaryMSyntheticFrontEnd() override;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- struct DataDescriptor_32
- {
- uint32_t _used : 26;
- uint32_t _kvo : 1;
- uint32_t _size;
- uint32_t _mutations;
- uint32_t _objs_addr;
- uint32_t _keys_addr;
- };
-
- struct DataDescriptor_64
- {
- uint64_t _used : 58;
- uint32_t _kvo : 1;
- uint64_t _size;
- uint64_t _mutations;
- uint64_t _objs_addr;
- uint64_t _keys_addr;
- };
-
- struct DictionaryItemDescriptor
- {
- lldb::addr_t key_ptr;
- lldb::addr_t val_ptr;
- lldb::ValueObjectSP valobj_sp;
- };
-
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- lldb::ByteOrder m_order;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- CompilerType m_pair_type;
- std::vector<DictionaryItemDescriptor> m_children;
- };
- } // namespace formatters
+namespace formatters {
+class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSDictionaryISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSDictionaryISyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ struct DataDescriptor_32 {
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used : 58;
+ uint32_t _szidx : 6;
+ };
+
+ struct DictionaryItemDescriptor {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ lldb::addr_t m_data_ptr;
+ CompilerType m_pair_type;
+ std::vector<DictionaryItemDescriptor> m_children;
+};
+
+class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSDictionary1SyntheticFrontEnd() override = default;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ ValueObjectSP m_pair;
+};
+
+class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSDictionaryMSyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ struct DataDescriptor_32 {
+ uint32_t _used : 26;
+ uint32_t _kvo : 1;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ uint32_t _keys_addr;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used : 58;
+ uint32_t _kvo : 1;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ uint64_t _keys_addr;
+ };
+
+ struct DictionaryItemDescriptor {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ CompilerType m_pair_type;
+ std::vector<DictionaryItemDescriptor> m_children;
+};
+} // namespace formatters
} // namespace lldb_private
-template<bool name_entries>
-bool
-lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- static ConstString g_TypeHint("NSDictionary");
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
- bool is_64bit = (ptr_size == 8);
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t value = 0;
-
- ConstString class_name(descriptor->GetClassName());
-
- static const ConstString g_DictionaryI("__NSDictionaryI");
- static const ConstString g_DictionaryM("__NSDictionaryM");
- static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
-
- if (class_name.IsEmpty())
- return false;
-
- if (class_name == g_DictionaryI)
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- }
- else if (class_name == g_DictionaryM)
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- }
- else if (class_name == g_Dictionary1)
- {
- value = 1;
- }
- /*else if (!strcmp(class_name,"__NSCFDictionary"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
- if (error.Fail())
- return false;
- if (is_64bit)
- value &= ~0x0f1f000000000000UL;
- }*/
- else
- {
- auto& map(NSDictionary_Additionals::GetAdditionalSummaries());
- auto iter = map.find(class_name), end = map.end();
- if (iter != end)
- return iter->second(valobj, stream, options);
- else
- return false;
+template <bool name_entries>
+bool lldb_private::formatters::NSDictionarySummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ static ConstString g_TypeHint("NSDictionary");
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+ bool is_64bit = (ptr_size == 8);
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ ConstString class_name(descriptor->GetClassName());
+
+ static const ConstString g_DictionaryI("__NSDictionaryI");
+ static const ConstString g_DictionaryM("__NSDictionaryM");
+ static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
+
+ if (class_name.IsEmpty())
+ return false;
+
+ if (class_name == g_DictionaryI) {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ } else if (class_name == g_DictionaryM) {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ } else if (class_name == g_Dictionary1) {
+ value = 1;
+ }
+ /*else if (!strcmp(class_name,"__NSCFDictionary"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ?
+ 20 : 12), 4, 0, error);
+ if (error.Fail())
+ return false;
+ if (is_64bit)
+ value &= ~0x0f1f000000000000UL;
+ }*/
+ else {
+ auto &map(NSDictionary_Additionals::GetAdditionalSummaries());
+ for (auto &candidate : map) {
+ if (candidate.first && candidate.first->Match(class_name))
+ return candidate.second(valobj, stream, options);
}
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(options.GetLanguage()))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
+ return false;
+ }
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s%" PRIu64 " %s%s%s",
- prefix.c_str(),
- value,
- "key/value pair",
- value == 1 ? "" : "s",
- suffix.c_str());
- return true;
+ }
+
+ stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "key/value pair",
+ value == 1 ? "" : "s", suffix.c_str());
+ return true;
}
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
-{
- lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
- if (!process_sp)
- return nullptr;
- ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
- if (!runtime)
- return nullptr;
-
- CompilerType valobj_type(valobj_sp->GetCompilerType());
- Flags flags(valobj_type.GetTypeInfo());
-
- if (flags.IsClear(eTypeIsPointer))
- {
- Error error;
- valobj_sp = valobj_sp->AddressOf(error);
- if (error.Fail() || !valobj_sp)
- return nullptr;
- }
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp));
-
- if (!descriptor || !descriptor->IsValid())
- return nullptr;
-
- ConstString class_name(descriptor->GetClassName());
-
- static const ConstString g_DictionaryI("__NSDictionaryI");
- static const ConstString g_DictionaryM("__NSDictionaryM");
- static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
-
- if (class_name.IsEmpty())
- return nullptr;
-
- if (class_name == g_DictionaryI)
- {
- return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
- }
- else if (class_name == g_DictionaryM)
- {
- return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
- }
- else if (class_name == g_Dictionary1)
- {
- return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
- }
- else
- {
- auto& map(NSDictionary_Additionals::GetAdditionalSynthetics());
- auto iter = map.find(class_name), end = map.end();
- if (iter != end)
- return iter->second(synth, valobj_sp);
- }
-
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
+ CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
return nullptr;
-}
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+ if (!runtime)
+ return nullptr;
+
+ CompilerType valobj_type(valobj_sp->GetCompilerType());
+ Flags flags(valobj_type.GetTypeInfo());
+
+ if (flags.IsClear(eTypeIsPointer)) {
+ Error error;
+ valobj_sp = valobj_sp->AddressOf(error);
+ if (error.Fail() || !valobj_sp)
+ return nullptr;
+ }
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_exe_ctx_ref(),
- m_ptr_size(8),
- m_order(lldb::eByteOrderInvalid),
- m_data_32(nullptr),
- m_data_64(nullptr),
- m_pair_type()
-{
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(*valobj_sp));
+
+ if (!descriptor || !descriptor->IsValid())
+ return nullptr;
+
+ ConstString class_name(descriptor->GetClassName());
+
+ static const ConstString g_DictionaryI("__NSDictionaryI");
+ static const ConstString g_DictionaryM("__NSDictionaryM");
+ static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
+
+ if (class_name.IsEmpty())
+ return nullptr;
+
+ if (class_name == g_DictionaryI) {
+ return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_DictionaryM) {
+ return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_Dictionary1) {
+ return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
+ } else {
+ auto &map(NSDictionary_Additionals::GetAdditionalSynthetics());
+ for (auto &candidate : map) {
+ if (candidate.first && candidate.first->Match((class_name)))
+ return candidate.second(synth, valobj_sp);
+ }
+ }
+
+ return nullptr;
}
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
-{
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+ NSDictionaryISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
+ m_pair_type() {}
+
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+ ~NSDictionaryISyntheticFrontEnd() {
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
}
-size_t
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+size_t lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
}
-size_t
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+size_t lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+ CalculateNumChildren() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
-{
- m_children.clear();
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- m_ptr_size = 0;
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- m_order = process_sp->GetByteOrder();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
- m_data_ptr = data_location + m_ptr_size;
+bool lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update() {
+ m_children.clear();
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
+ m_ptr_size = 0;
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ m_order = process_sp->GetByteOrder();
+ uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+ if (m_ptr_size == 4) {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ error);
+ } else {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ error);
+ }
+ if (error.Fail())
+ return false;
+ m_data_ptr = data_location + m_ptr_size;
+ return false;
}
-bool
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- uint32_t num_children = CalculateNumChildren();
-
- if (idx >= num_children)
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty()) {
+ // do the scan phase
+ lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while (tries < num_children) {
+ key_at_idx = m_data_ptr + (2 * test_idx * m_ptr_size);
+ val_at_idx = key_at_idx + m_ptr_size;
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
return lldb::ValueObjectSP();
-
- if (m_children.empty())
- {
- // do the scan phase
- lldb::addr_t key_at_idx = 0, val_at_idx = 0;
-
- uint32_t tries = 0;
- uint32_t test_idx = 0;
-
- while(tries < num_children)
- {
- key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
- val_at_idx = key_at_idx + m_ptr_size;
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
- val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
-
- test_idx++;
-
- if (!key_at_idx || !val_at_idx)
- continue;
- tries++;
-
- DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
-
- m_children.push_back(descriptor);
- }
- }
-
- if (idx >= m_children.size()) // should never happen
+ Error error;
+ key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+ if (error.Fail())
return lldb::ValueObjectSP();
-
- DictionaryItemDescriptor &dict_item = m_children[idx];
- if (!dict_item.valobj_sp)
- {
- if (!m_pair_type.IsValid())
- {
- TargetSP target_sp(m_backend.GetTargetSP());
- if (!target_sp)
- return ValueObjectSP();
- m_pair_type = GetLLDBNSPairType(target_sp);
- }
- if (!m_pair_type.IsValid())
- return ValueObjectSP();
-
- DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
-
- if (m_ptr_size == 8)
- {
- uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
- *data_ptr = dict_item.key_ptr;
- *(data_ptr+1) = dict_item.val_ptr;
- }
- else
- {
- uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
- *data_ptr = dict_item.key_ptr;
- *(data_ptr+1) = dict_item.val_ptr;
- }
-
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- DataExtractor data(buffer_sp, m_order, m_ptr_size);
- dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetData(),
- data,
- m_exe_ctx_ref,
- m_pair_type);
+ val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!key_at_idx || !val_at_idx)
+ continue;
+ tries++;
+
+ DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx,
+ lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ DictionaryItemDescriptor &dict_item = m_children[idx];
+ if (!dict_item.valobj_sp) {
+ if (!m_pair_type.IsValid()) {
+ TargetSP target_sp(m_backend.GetTargetSP());
+ if (!target_sp)
+ return ValueObjectSP();
+ m_pair_type = GetLLDBNSPairType(target_sp);
+ }
+ if (!m_pair_type.IsValid())
+ return ValueObjectSP();
+
+ DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0));
+
+ if (m_ptr_size == 8) {
+ uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+ *data_ptr = dict_item.key_ptr;
+ *(data_ptr + 1) = dict_item.val_ptr;
+ } else {
+ uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+ *data_ptr = dict_item.key_ptr;
+ *(data_ptr + 1) = dict_item.val_ptr;
}
- return dict_item.valobj_sp;
-}
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::NSDictionary1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_pair(nullptr)
-{
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ DataExtractor data(buffer_sp, m_order, m_ptr_size);
+ dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetString(), data,
+ m_exe_ctx_ref, m_pair_type);
+ }
+ return dict_item.valobj_sp;
}
-size_t
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- static const ConstString g_zero("[0]");
-
- if (name == g_zero)
- return 0;
-
- return UINT32_MAX;
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+ NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_pair(nullptr) {}
+
+size_t lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ static const ConstString g_zero("[0]");
+
+ if (name == g_zero)
+ return 0;
+
+ return UINT32_MAX;
}
-size_t
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::CalculateNumChildren ()
-{
- return 1;
+size_t lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+ CalculateNumChildren() {
+ return 1;
}
-bool
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::Update()
-{
- m_pair.reset();
- return false;
+bool lldb_private::formatters::NSDictionary1SyntheticFrontEnd::Update() {
+ m_pair.reset();
+ return false;
}
-bool
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- if (idx != 0)
- return lldb::ValueObjectSP();
-
- if (m_pair.get())
- return m_pair;
-
- auto process_sp(m_backend.GetProcessSP());
- if (!process_sp)
- return nullptr;
-
- auto ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t key_ptr = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS) + ptr_size;
- lldb::addr_t value_ptr = key_ptr + ptr_size;
-
- Error error;
-
- lldb::addr_t value_at_idx = process_sp->ReadPointerFromMemory(key_ptr, error);
- if (error.Fail())
- return nullptr;
- lldb::addr_t key_at_idx = process_sp->ReadPointerFromMemory(value_ptr, error);
- if (error.Fail())
- return nullptr;
-
- auto pair_type = GetLLDBNSPairType(process_sp->GetTarget().shared_from_this());
-
- DataBufferSP buffer_sp(new DataBufferHeap(2*ptr_size,0));
-
- if (ptr_size == 8)
- {
- uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
- *data_ptr = key_at_idx;
- *(data_ptr+1) = value_at_idx;
- }
- else
- {
- uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
- *data_ptr = key_ptr;
- *(data_ptr+1) = value_ptr;
- }
-
- DataExtractor data(buffer_sp, process_sp->GetByteOrder(), ptr_size);
- m_pair = CreateValueObjectFromData("[0]",
- data,
- m_backend.GetExecutionContextRef(),
- pair_type);
-
-
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (idx != 0)
+ return lldb::ValueObjectSP();
+
+ if (m_pair.get())
return m_pair;
-}
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_exe_ctx_ref(),
- m_ptr_size(8),
- m_order(lldb::eByteOrderInvalid),
- m_data_32(nullptr),
- m_data_64(nullptr),
- m_pair_type()
-{
+ auto process_sp(m_backend.GetProcessSP());
+ if (!process_sp)
+ return nullptr;
+
+ auto ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t key_ptr =
+ m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS) + ptr_size;
+ lldb::addr_t value_ptr = key_ptr + ptr_size;
+
+ Error error;
+
+ lldb::addr_t value_at_idx = process_sp->ReadPointerFromMemory(key_ptr, error);
+ if (error.Fail())
+ return nullptr;
+ lldb::addr_t key_at_idx = process_sp->ReadPointerFromMemory(value_ptr, error);
+ if (error.Fail())
+ return nullptr;
+
+ auto pair_type =
+ GetLLDBNSPairType(process_sp->GetTarget().shared_from_this());
+
+ DataBufferSP buffer_sp(new DataBufferHeap(2 * ptr_size, 0));
+
+ if (ptr_size == 8) {
+ uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+ *data_ptr = key_at_idx;
+ *(data_ptr + 1) = value_at_idx;
+ } else {
+ uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+ *data_ptr = key_at_idx;
+ *(data_ptr + 1) = value_at_idx;
+ }
+
+ DataExtractor data(buffer_sp, process_sp->GetByteOrder(), ptr_size);
+ m_pair = CreateValueObjectFromData(
+ "[0]", data, m_backend.GetExecutionContextRef(), pair_type);
+
+ return m_pair;
}
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
-{
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+ NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
+ m_pair_type() {}
+
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+ ~NSDictionaryMSyntheticFrontEnd() {
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
}
-size_t
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+ GetIndexOfChildWithName(const ConstString &name) {
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
}
-size_t
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+ CalculateNumChildren() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
-{
- m_children.clear();
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- m_order = process_sp->GetByteOrder();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
+bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ m_order = process_sp->GetByteOrder();
+ uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+ if (m_ptr_size == 4) {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ error);
+ } else {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ error);
+ }
+ if (error.Fail())
+ return false;
+ return false;
}
-bool
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
- lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
-
- uint32_t num_children = CalculateNumChildren();
-
- if (idx >= num_children)
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ lldb::addr_t m_keys_ptr =
+ (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
+ lldb::addr_t m_values_ptr =
+ (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
+
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty()) {
+ // do the scan phase
+ lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while (tries < num_children) {
+ key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
+ val_at_idx = m_values_ptr + (test_idx * m_ptr_size);
+ ;
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
return lldb::ValueObjectSP();
-
- if (m_children.empty())
- {
- // do the scan phase
- lldb::addr_t key_at_idx = 0, val_at_idx = 0;
-
- uint32_t tries = 0;
- uint32_t test_idx = 0;
-
- while(tries < num_children)
- {
- key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
- val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
- val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
-
- test_idx++;
-
- if (!key_at_idx || !val_at_idx)
- continue;
- tries++;
-
- DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
-
- m_children.push_back(descriptor);
- }
- }
-
- if (idx >= m_children.size()) // should never happen
+ Error error;
+ key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+ if (error.Fail())
return lldb::ValueObjectSP();
-
- DictionaryItemDescriptor &dict_item = m_children[idx];
- if (!dict_item.valobj_sp)
- {
- if (!m_pair_type.IsValid())
- {
- TargetSP target_sp(m_backend.GetTargetSP());
- if (!target_sp)
- return ValueObjectSP();
- m_pair_type = GetLLDBNSPairType(target_sp);
- }
- if (!m_pair_type.IsValid())
- return ValueObjectSP();
-
- DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
-
- if (m_ptr_size == 8)
- {
- uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
- *data_ptr = dict_item.key_ptr;
- *(data_ptr+1) = dict_item.val_ptr;
- }
- else
- {
- uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
- *data_ptr = dict_item.key_ptr;
- *(data_ptr+1) = dict_item.val_ptr;
- }
-
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- DataExtractor data(buffer_sp, m_order, m_ptr_size);
- dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetData(),
- data,
- m_exe_ctx_ref,
- m_pair_type);
+ val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!key_at_idx || !val_at_idx)
+ continue;
+ tries++;
+
+ DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx,
+ lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ DictionaryItemDescriptor &dict_item = m_children[idx];
+ if (!dict_item.valobj_sp) {
+ if (!m_pair_type.IsValid()) {
+ TargetSP target_sp(m_backend.GetTargetSP());
+ if (!target_sp)
+ return ValueObjectSP();
+ m_pair_type = GetLLDBNSPairType(target_sp);
}
- return dict_item.valobj_sp;
+ if (!m_pair_type.IsValid())
+ return ValueObjectSP();
+
+ DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0));
+
+ if (m_ptr_size == 8) {
+ uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+ *data_ptr = dict_item.key_ptr;
+ *(data_ptr + 1) = dict_item.val_ptr;
+ } else {
+ uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+ *data_ptr = dict_item.key_ptr;
+ *(data_ptr + 1) = dict_item.val_ptr;
+ }
+
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ DataExtractor data(buffer_sp, m_order, m_ptr_size);
+ dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetString(), data,
+ m_exe_ctx_ref, m_pair_type);
+ }
+ return dict_item.valobj_sp;
}
-template bool
-lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDictionarySummaryProvider<true>(
+ ValueObject &, Stream &, const TypeSummaryOptions &);
-template bool
-lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDictionarySummaryProvider<false>(
+ ValueObject &, Stream &, const TypeSummaryOptions &);
diff --git a/source/Plugins/Language/ObjC/NSDictionary.h b/source/Plugins/Language/ObjC/NSDictionary.h
index e96c25a97b2b..10318a5bf621 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.h
+++ b/source/Plugins/Language/ObjC/NSDictionary.h
@@ -1,4 +1,5 @@
-//===-- NSDictionary.h ---------------------------------------------------*- C++ -*-===//
+//===-- NSDictionary.h ---------------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,32 +18,78 @@
#include "lldb/DataFormatters/TypeSynthetic.h"
#include <map>
+#include <memory>
namespace lldb_private {
- namespace formatters
- {
- template<bool name_entries>
- bool
- NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- extern template bool
- NSDictionarySummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-
- extern template bool
- NSDictionarySummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-
- SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- class NSDictionary_Additionals
- {
- public:
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
- GetAdditionalSummaries ();
-
- static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
- GetAdditionalSynthetics ();
- };
- } // namespace formatters
+namespace formatters {
+template <bool name_entries>
+bool NSDictionarySummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+extern template bool
+NSDictionarySummaryProvider<true>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+
+extern template bool
+NSDictionarySummaryProvider<false>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+
+SyntheticChildrenFrontEnd *
+NSDictionarySyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+class NSDictionary_Additionals {
+public:
+ class AdditionalFormatterMatching {
+ public:
+ class Matcher {
+ public:
+ virtual ~Matcher() = default;
+ virtual bool Match(ConstString class_name) = 0;
+
+ typedef std::unique_ptr<Matcher> UP;
+ };
+ class Prefix : public Matcher {
+ public:
+ Prefix(ConstString p);
+ virtual ~Prefix() = default;
+ virtual bool Match(ConstString class_name) override;
+
+ private:
+ ConstString m_prefix;
+ };
+ class Full : public Matcher {
+ public:
+ Full(ConstString n);
+ virtual ~Full() = default;
+ virtual bool Match(ConstString class_name) override;
+
+ private:
+ ConstString m_name;
+ };
+ typedef Matcher::UP MatcherUP;
+
+ MatcherUP GetFullMatch(ConstString n) { return llvm::make_unique<Full>(n); }
+
+ MatcherUP GetPrefixMatch(ConstString p) {
+ return llvm::make_unique<Prefix>(p);
+ }
+ };
+
+ template <typename FormatterType>
+ using AdditionalFormatter =
+ std::pair<AdditionalFormatterMatching::MatcherUP, FormatterType>;
+
+ template <typename FormatterType>
+ using AdditionalFormatters = std::vector<AdditionalFormatter<FormatterType>>;
+
+ static AdditionalFormatters<CXXFunctionSummaryFormat::Callback> &
+ GetAdditionalSummaries();
+
+ static AdditionalFormatters<CXXSyntheticChildren::CreateFrontEndCallback> &
+ GetAdditionalSynthetics();
+};
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_NSDictionary_h_
diff --git a/source/Plugins/Language/ObjC/NSError.cpp b/source/Plugins/Language/ObjC/NSError.cpp
index 4bfb024206d3..bad22b13a005 100644
--- a/source/Plugins/Language/ObjC/NSError.cpp
+++ b/source/Plugins/Language/ObjC/NSError.cpp
@@ -34,196 +34,187 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-static lldb::addr_t
-DerefToNSErrorPointer (ValueObject& valobj)
-{
- CompilerType valobj_type(valobj.GetCompilerType());
- Flags type_flags(valobj_type.GetTypeInfo());
- if (type_flags.AllClear(eTypeHasValue))
- {
- if (valobj.IsBaseClass() && valobj.GetParent())
- return valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- }
- else
- {
- lldb::addr_t ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- if (type_flags.AllSet(eTypeIsPointer))
- {
- CompilerType pointee_type(valobj_type.GetPointeeType());
- Flags pointee_flags(pointee_type.GetTypeInfo());
- if (pointee_flags.AllSet(eTypeIsPointer))
- {
- if (ProcessSP process_sp = valobj.GetProcessSP())
- {
- Error error;
- ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error);
- }
- }
+static lldb::addr_t DerefToNSErrorPointer(ValueObject &valobj) {
+ CompilerType valobj_type(valobj.GetCompilerType());
+ Flags type_flags(valobj_type.GetTypeInfo());
+ if (type_flags.AllClear(eTypeHasValue)) {
+ if (valobj.IsBaseClass() && valobj.GetParent())
+ return valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ } else {
+ lldb::addr_t ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (type_flags.AllSet(eTypeIsPointer)) {
+ CompilerType pointee_type(valobj_type.GetPointeeType());
+ Flags pointee_flags(pointee_type.GetTypeInfo());
+ if (pointee_flags.AllSet(eTypeIsPointer)) {
+ if (ProcessSP process_sp = valobj.GetProcessSP()) {
+ Error error;
+ ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error);
}
- return ptr_value;
+ }
}
-
- return LLDB_INVALID_ADDRESS;
+ return ptr_value;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool lldb_private::formatters::NSError_SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp(valobj.GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t ptr_value = DerefToNSErrorPointer(valobj);
+ if (ptr_value == LLDB_INVALID_ADDRESS)
+ return false;
+
+ size_t ptr_size = process_sp->GetAddressByteSize();
+ lldb::addr_t code_location = ptr_value + 2 * ptr_size;
+ lldb::addr_t domain_location = ptr_value + 3 * ptr_size;
+
+ Error error;
+ uint64_t code = process_sp->ReadUnsignedIntegerFromMemory(code_location,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+
+ lldb::addr_t domain_str_value =
+ process_sp->ReadPointerFromMemory(domain_location, error);
+ if (error.Fail() || domain_str_value == LLDB_INVALID_ADDRESS)
+ return false;
+
+ if (!domain_str_value) {
+ stream.Printf("domain: nil - code: %" PRIu64, code);
+ return true;
+ }
+
+ InferiorSizedWord isw(domain_str_value, *process_sp);
+
+ ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData(
+ "domain_str", isw.GetAsData(process_sp->GetByteOrder()),
+ valobj.GetExecutionContextRef(), process_sp->GetTarget()
+ .GetScratchClangASTContext()
+ ->GetBasicType(lldb::eBasicTypeVoid)
+ .GetPointerType());
+
+ if (!domain_str_sp)
+ return false;
+
+ StreamString domain_str_summary;
+ if (NSStringSummaryProvider(*domain_str_sp, domain_str_summary, options) &&
+ !domain_str_summary.Empty()) {
+ stream.Printf("domain: %s - code: %" PRIu64, domain_str_summary.GetData(),
+ code);
+ return true;
+ } else {
+ stream.Printf("domain: nil - code: %" PRIu64, code);
+ return true;
+ }
}
-bool
-lldb_private::formatters::NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- ProcessSP process_sp(valobj.GetProcessSP());
+class NSErrorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSErrorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp) {}
+
+ ~NSErrorSyntheticFrontEnd() 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;
+ }
+
+ 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;
+ }
+
+ 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 ptr_value = DerefToNSErrorPointer(valobj);
- if (ptr_value == LLDB_INVALID_ADDRESS)
- return false;
+ return false;
+
+ lldb::addr_t userinfo_location = DerefToNSErrorPointer(m_backend);
+ if (userinfo_location == LLDB_INVALID_ADDRESS)
+ return false;
size_t ptr_size = process_sp->GetAddressByteSize();
- lldb::addr_t code_location = ptr_value + 2 * ptr_size;
- lldb::addr_t domain_location = ptr_value + 3 * ptr_size;
-
+
+ userinfo_location += 4 * ptr_size;
Error error;
- uint64_t code = process_sp->ReadUnsignedIntegerFromMemory(code_location, ptr_size, 0, error);
- if (error.Fail())
- return false;
-
- lldb::addr_t domain_str_value = process_sp->ReadPointerFromMemory(domain_location, error);
- if (error.Fail() || domain_str_value == LLDB_INVALID_ADDRESS)
- return false;
-
- if (!domain_str_value)
- {
- stream.Printf("domain: nil - code: %" PRIu64, code);
- return true;
- }
-
- InferiorSizedWord isw(domain_str_value, *process_sp);
-
- ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData("domain_str", isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeVoid).GetPointerType());
-
- if (!domain_str_sp)
- return false;
-
- StreamString domain_str_summary;
- if (NSStringSummaryProvider(*domain_str_sp, domain_str_summary, options) && !domain_str_summary.Empty())
- {
- stream.Printf("domain: %s - code: %" PRIu64, domain_str_summary.GetData(), code);
- return true;
- }
- else
- {
- stream.Printf("domain: nil - code: %" PRIu64, code);
- return true;
- }
-}
+ 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;
+ }
-class NSErrorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
-public:
- NSErrorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp)
- {}
-
- ~NSErrorSyntheticFrontEnd() 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;
- }
-
- 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;
- }
-
- 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 = DerefToNSErrorPointer(m_backend);
- if (userinfo_location == LLDB_INVALID_ADDRESS)
- return false;
-
- size_t ptr_size = process_sp->GetAddressByteSize();
-
- userinfo_location += 4 * ptr_size;
- Error 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;
- }
-
- bool
- MightHaveChildren() override
- {
- return true;
- }
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- static ConstString g___userInfo("_userInfo");
- if (name == g___userInfo)
- return 0;
- return UINT32_MAX;
- }
+ bool MightHaveChildren() override { return true; }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ static ConstString g___userInfo("_userInfo");
+ if (name == g___userInfo)
+ return 0;
+ 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;
+ // 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;
};
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::NSErrorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
- if (!process_sp)
- return nullptr;
- ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
- if (!runtime)
- return nullptr;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return nullptr;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return nullptr;
-
- if (!strcmp(class_name,"NSError"))
- return (new NSErrorSyntheticFrontEnd(valobj_sp));
- else if (!strcmp(class_name,"__NSCFError"))
- return (new NSErrorSyntheticFrontEnd(valobj_sp));
-
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSErrorSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return nullptr;
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+ if (!runtime)
+ return nullptr;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(*valobj_sp.get()));
+
+ if (!descriptor.get() || !descriptor->IsValid())
return nullptr;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return nullptr;
+
+ if (!strcmp(class_name, "NSError"))
+ return (new NSErrorSyntheticFrontEnd(valobj_sp));
+ else if (!strcmp(class_name, "__NSCFError"))
+ return (new NSErrorSyntheticFrontEnd(valobj_sp));
+
+ return nullptr;
}
diff --git a/source/Plugins/Language/ObjC/NSException.cpp b/source/Plugins/Language/ObjC/NSException.cpp
index f70e7c7356e1..1609048d432c 100644
--- a/source/Plugins/Language/ObjC/NSException.cpp
+++ b/source/Plugins/Language/ObjC/NSException.cpp
@@ -34,186 +34,183 @@ 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)
-{
- ProcessSP process_sp(valobj.GetProcessSP());
+bool lldb_private::formatters::NSException_SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ProcessSP process_sp(valobj.GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t ptr_value = 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);
+
+ if (ptr_value == 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;
+
+ Error error;
+ lldb::addr_t name = process_sp->ReadPointerFromMemory(name_location, error);
+ if (error.Fail() || name == LLDB_INVALID_ADDRESS)
+ return false;
+
+ lldb::addr_t reason =
+ process_sp->ReadPointerFromMemory(reason_location, error);
+ if (error.Fail() || reason == LLDB_INVALID_ADDRESS)
+ return false;
+
+ InferiorSizedWord name_isw(name, *process_sp);
+ InferiorSizedWord reason_isw(reason, *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 || !reason_sp)
+ return false;
+
+ StreamString name_str_summary;
+ StreamString reason_str_summary;
+ if (NSStringSummaryProvider(*name_sp, name_str_summary, options) &&
+ NSStringSummaryProvider(*reason_sp, reason_str_summary, options) &&
+ !name_str_summary.Empty() && !reason_str_summary.Empty()) {
+ stream.Printf("name: %s - reason: %s", name_str_summary.GetData(),
+ reason_str_summary.GetData());
+ return true;
+ } else
+ return false;
+}
+
+class NSExceptionSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSExceptionSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : 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;
+ }
+
+ 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;
+ }
+
+ 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 ptr_value = LLDB_INVALID_ADDRESS;
-
- CompilerType valobj_type(valobj.GetCompilerType());
+ 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 (valobj.IsBaseClass() && valobj.GetParent())
- ptr_value = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- }
- else
- ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-
- if (ptr_value == LLDB_INVALID_ADDRESS)
- return false;
+ 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();
- lldb::addr_t name_location = ptr_value + 1 * ptr_size;
- lldb::addr_t reason_location = ptr_value + 2 * ptr_size;
-
+
+ userinfo_location += 3 * ptr_size;
Error error;
- lldb::addr_t name = process_sp->ReadPointerFromMemory(name_location, error);
- if (error.Fail() || name == LLDB_INVALID_ADDRESS)
- return false;
-
- lldb::addr_t reason = process_sp->ReadPointerFromMemory(reason_location, error);
- if (error.Fail() || reason == LLDB_INVALID_ADDRESS)
- return false;
-
- InferiorSizedWord name_isw(name, *process_sp);
- InferiorSizedWord reason_isw(reason, *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 || !reason_sp)
- return false;
-
- StreamString name_str_summary;
- StreamString reason_str_summary;
- if (NSStringSummaryProvider(*name_sp, name_str_summary, options) &&
- NSStringSummaryProvider(*reason_sp, reason_str_summary, options) &&
- !name_str_summary.Empty() &&
- !reason_str_summary.Empty())
- {
- stream.Printf("name: %s - reason: %s", name_str_summary.GetData(), reason_str_summary.GetData());
- return true;
- }
- else
- return false;
-}
+ 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;
+ }
-class NSExceptionSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
-public:
- NSExceptionSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- 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;
- }
-
- 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;
- }
-
- 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;
- Error 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;
- }
-
- bool
- MightHaveChildren() override
- {
- return true;
- }
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- static ConstString g___userInfo("userInfo");
- if (name == g___userInfo)
- return 0;
- return UINT32_MAX;
- }
+ bool MightHaveChildren() override { return true; }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ static ConstString g___userInfo("userInfo");
+ if (name == g___userInfo)
+ return 0;
+ 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;
+ // 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;
};
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::NSExceptionSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
- if (!process_sp)
- return nullptr;
- ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
- if (!runtime)
- return nullptr;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return nullptr;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return nullptr;
-
- if (!strcmp(class_name,"NSException"))
- return (new NSExceptionSyntheticFrontEnd(valobj_sp));
- else if (!strcmp(class_name,"NSCFException"))
- return (new NSExceptionSyntheticFrontEnd(valobj_sp));
- else if (!strcmp(class_name,"__NSCFException"))
- return (new NSExceptionSyntheticFrontEnd(valobj_sp));
-
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSExceptionSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
return nullptr;
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+ if (!runtime)
+ return nullptr;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(*valobj_sp.get()));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return nullptr;
+
+ const char *class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return nullptr;
+
+ if (!strcmp(class_name, "NSException"))
+ return (new NSExceptionSyntheticFrontEnd(valobj_sp));
+ else if (!strcmp(class_name, "NSCFException"))
+ return (new NSExceptionSyntheticFrontEnd(valobj_sp));
+ else if (!strcmp(class_name, "__NSCFException"))
+ return (new NSExceptionSyntheticFrontEnd(valobj_sp));
+
+ return nullptr;
}
diff --git a/source/Plugins/Language/ObjC/NSIndexPath.cpp b/source/Plugins/Language/ObjC/NSIndexPath.cpp
index 0c8a54d76df1..9533e96004a5 100644
--- a/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -26,353 +26,299 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+static constexpr size_t PACKED_INDEX_SHIFT_64(size_t i) {
+ return (60 - (13 * (4 - i)));
+}
+
+static constexpr size_t PACKED_INDEX_SHIFT_32(size_t i) {
+ return (32 - (13 * (2 - i)));
+}
+
+class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- NSIndexPathSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd (*valobj_sp.get()),
- m_descriptor_sp(nullptr),
- m_impl(),
- m_ptr_size(0),
- m_uint_star_type()
- {
- m_ptr_size = m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize();
- }
+ NSIndexPathSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_descriptor_sp(nullptr),
+ m_impl(), m_ptr_size(0), m_uint_star_type() {
+ m_ptr_size =
+ m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize();
+ }
- ~NSIndexPathSyntheticFrontEnd() override = default;
+ ~NSIndexPathSyntheticFrontEnd() override = default;
- size_t
- CalculateNumChildren() override
- {
- return m_impl.GetNumIndexes();
- }
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override
- {
- return m_impl.GetIndexAtIndex(idx, m_uint_star_type);
- }
-
- bool
- Update() override
- {
- m_impl.Clear();
-
- TypeSystem* type_system = m_backend.GetCompilerType().GetTypeSystem();
- if (!type_system)
- return false;
-
- ClangASTContext *ast = m_backend.GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext();
- if (!ast)
- return false;
-
- m_uint_star_type = ast->GetPointerSizedIntType(false);
-
- static ConstString g__indexes("_indexes");
- static ConstString g__length("_length");
-
- ProcessSP process_sp = m_backend.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(m_backend));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint64_t info_bits(0),value_bits(0),payload(0);
-
- if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits, &payload))
- {
- m_impl.m_inlined.SetIndexes(payload, *process_sp);
- m_impl.m_mode = Mode::Inlined;
+ size_t CalculateNumChildren() override { return m_impl.GetNumIndexes(); }
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+ return m_impl.GetIndexAtIndex(idx, m_uint_star_type);
+ }
+
+ bool Update() override {
+ m_impl.Clear();
+
+ TypeSystem *type_system = m_backend.GetCompilerType().GetTypeSystem();
+ if (!type_system)
+ return false;
+
+ ClangASTContext *ast = m_backend.GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchClangASTContext();
+ if (!ast)
+ return false;
+
+ m_uint_star_type = ast->GetPointerSizedIntType(false);
+
+ static ConstString g__indexes("_indexes");
+ static ConstString g__length("_length");
+
+ ProcessSP process_sp = m_backend.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(m_backend));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint64_t info_bits(0), value_bits(0), payload(0);
+
+ if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits, &payload)) {
+ m_impl.m_inlined.SetIndexes(payload, *process_sp);
+ m_impl.m_mode = Mode::Inlined;
+ } else {
+ ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _indexes_id;
+ ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _length_id;
+
+ bool has_indexes(false), has_length(false);
+
+ for (size_t x = 0; x < descriptor->GetNumIVars(); x++) {
+ const auto &ivar = descriptor->GetIVarAtIndex(x);
+ if (ivar.m_name == g__indexes) {
+ _indexes_id = ivar;
+ has_indexes = true;
+ } else if (ivar.m_name == g__length) {
+ _length_id = ivar;
+ has_length = true;
}
- else
- {
- ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _indexes_id;
- ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _length_id;
-
- bool has_indexes(false),has_length(false);
-
- for (size_t x = 0;
- x < descriptor->GetNumIVars();
- x++)
- {
- const auto& ivar = descriptor->GetIVarAtIndex(x);
- if (ivar.m_name == g__indexes)
- {
- _indexes_id = ivar;
- has_indexes = true;
- }
- else if (ivar.m_name == g__length)
- {
- _length_id = ivar;
- has_length = true;
- }
-
- if (has_length && has_indexes)
- break;
- }
-
- if (has_length && has_indexes)
- {
- m_impl.m_outsourced.m_indexes = m_backend.GetSyntheticChildAtOffset(_indexes_id.m_offset,
- m_uint_star_type.GetPointerType(),
- true).get();
- ValueObjectSP length_sp(m_backend.GetSyntheticChildAtOffset(_length_id.m_offset,
- m_uint_star_type,
- true));
- if (length_sp)
- {
- m_impl.m_outsourced.m_count = length_sp->GetValueAsUnsigned(0);
- if (m_impl.m_outsourced.m_indexes)
- m_impl.m_mode = Mode::Outsourced;
- }
- }
+
+ if (has_length && has_indexes)
+ break;
+ }
+
+ if (has_length && has_indexes) {
+ m_impl.m_outsourced.m_indexes =
+ m_backend
+ .GetSyntheticChildAtOffset(_indexes_id.m_offset,
+ m_uint_star_type.GetPointerType(),
+ true)
+ .get();
+ ValueObjectSP length_sp(m_backend.GetSyntheticChildAtOffset(
+ _length_id.m_offset, m_uint_star_type, true));
+ if (length_sp) {
+ m_impl.m_outsourced.m_count = length_sp->GetValueAsUnsigned(0);
+ if (m_impl.m_outsourced.m_indexes)
+ m_impl.m_mode = Mode::Outsourced;
}
- return false;
+ }
}
-
- bool
- MightHaveChildren() override
- {
- if (m_impl.m_mode == Mode::Invalid)
- return false;
- return true;
- }
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+ return false;
+ }
+
+ bool MightHaveChildren() override {
+ if (m_impl.m_mode == Mode::Invalid)
+ return false;
+ return true;
+ }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+ }
+
+ lldb::ValueObjectSP GetSyntheticValue() override { return nullptr; }
+
+protected:
+ ObjCLanguageRuntime::ClassDescriptorSP m_descriptor_sp;
+
+ enum class Mode { Inlined, Outsourced, Invalid };
+
+ struct Impl {
+ size_t GetNumIndexes() {
+ switch (m_mode) {
+ case Mode::Inlined:
+ return m_inlined.GetNumIndexes();
+ case Mode::Outsourced:
+ return m_outsourced.m_count;
+ default:
+ return 0;
+ }
}
-
- lldb::ValueObjectSP
- GetSyntheticValue() override
- {
+
+ lldb::ValueObjectSP GetIndexAtIndex(size_t idx,
+ const CompilerType &desired_type) {
+ if (idx >= GetNumIndexes())
+ return nullptr;
+ switch (m_mode) {
+ default:
return nullptr;
+ case Mode::Inlined:
+ return m_inlined.GetIndexAtIndex(idx, desired_type);
+ case Mode::Outsourced:
+ return m_outsourced.GetIndexAtIndex(idx);
+ }
}
-protected:
- ObjCLanguageRuntime::ClassDescriptorSP m_descriptor_sp;
-
- enum class Mode {
- Inlined,
- Outsourced,
- Invalid
- };
-
- struct Impl
- {
- size_t
- GetNumIndexes ()
- {
- switch (m_mode)
- {
- case Mode::Inlined:
- return m_inlined.GetNumIndexes();
- case Mode::Outsourced:
- return m_outsourced.m_count;
- default:
- return 0;
- }
- }
-
- lldb::ValueObjectSP
- GetIndexAtIndex (size_t idx, const CompilerType& desired_type)
- {
- if (idx >= GetNumIndexes())
- return nullptr;
- switch (m_mode)
- {
- default: return nullptr;
- case Mode::Inlined:
- return m_inlined.GetIndexAtIndex (idx, desired_type);
- case Mode::Outsourced:
- return m_outsourced.GetIndexAtIndex (idx);
- }
+ struct InlinedIndexes {
+ public:
+ void SetIndexes(uint64_t value, Process &p) {
+ m_indexes = value;
+ _lengthForInlinePayload(p.GetAddressByteSize());
+ m_process = &p;
+ }
+
+ size_t GetNumIndexes() { return m_count; }
+
+ lldb::ValueObjectSP GetIndexAtIndex(size_t idx,
+ const CompilerType &desired_type) {
+ if (!m_process)
+ return nullptr;
+
+ std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx));
+ if (!value.second)
+ return nullptr;
+
+ Value v;
+ if (m_ptr_size == 8) {
+ Scalar scalar((unsigned long long)value.first);
+ v = Value(scalar);
+ } else {
+ Scalar scalar((unsigned int)value.first);
+ v = Value(scalar);
}
-
- struct InlinedIndexes
- {
- public:
- void SetIndexes(uint64_t value, Process& p)
- {
- m_indexes = value;
- _lengthForInlinePayload(p.GetAddressByteSize());
- m_process = &p;
- }
-
- size_t
- GetNumIndexes ()
- {
- return m_count;
- }
-
- lldb::ValueObjectSP
- GetIndexAtIndex (size_t idx, const CompilerType& desired_type)
- {
- if (!m_process)
- return nullptr;
-
- std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx));
- if (!value.second)
- return nullptr;
-
- Value v;
- if (m_ptr_size == 8)
- {
- Scalar scalar( (unsigned long long)value.first );
- v = Value(scalar);
- }
- else
- {
- Scalar scalar( (unsigned int)value.first );
- v = Value(scalar);
- }
-
- v.SetCompilerType(desired_type);
-
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-
- return ValueObjectConstResult::Create(m_process, v, ConstString(idx_name.GetData()));
- }
-
- void
- Clear ()
- {
- m_indexes = 0;
- m_count = 0;
- m_ptr_size = 0;
- m_process = nullptr;
- }
-
- InlinedIndexes () :
- m_indexes(0),
- m_count(0),
- m_ptr_size(0),
- m_process(nullptr)
- {
- }
-
- private:
- uint64_t m_indexes;
- size_t m_count;
- uint32_t m_ptr_size;
- Process *m_process;
-
- // cfr. Foundation for the details of this code
- size_t _lengthForInlinePayload(uint32_t ptr_size) {
- m_ptr_size = ptr_size;
- if (m_ptr_size == 8)
- m_count = ((m_indexes >> 3) & 0x7);
- else
- m_count = ((m_indexes >> 3) & 0x3);
- return m_count;
- }
-
- std::pair<uint64_t, bool>
- _indexAtPositionForInlinePayload(size_t pos)
- {
- if (m_ptr_size == 8)
- {
- switch (pos) {
- case 5: return {((m_indexes >> 51) & 0x1ff),true};
- case 4: return {((m_indexes >> 42) & 0x1ff),true};
- case 3: return {((m_indexes >> 33) & 0x1ff),true};
- case 2: return {((m_indexes >> 24) & 0x1ff),true};
- case 1: return {((m_indexes >> 15) & 0x1ff),true};
- case 0: return {((m_indexes >> 6) & 0x1ff),true};
- }
- }
- else
- {
- switch (pos) {
- case 2: return {((m_indexes >> 23) & 0x1ff),true};
- case 1: return {((m_indexes >> 14) & 0x1ff),true};
- case 0: return {((m_indexes >> 5) & 0x1ff),true};
- }
- }
- return {0,false};
- }
-
- };
-
- struct OutsourcedIndexes
- {
- lldb::ValueObjectSP
- GetIndexAtIndex (size_t idx)
- {
- if (m_indexes)
- {
- ValueObjectSP index_sp(m_indexes->GetSyntheticArrayMember(idx, true));
- return index_sp;
- }
- return nullptr;
- }
-
- void
- Clear ()
- {
- m_indexes = nullptr;
- m_count = 0;
- }
-
- OutsourcedIndexes () :
- m_indexes(nullptr),
- m_count(0)
- {
- }
-
- ValueObject *m_indexes;
- size_t m_count;
- };
-
- union
- {
- struct InlinedIndexes m_inlined;
- struct OutsourcedIndexes m_outsourced;
- };
-
- void
- Clear ()
- {
- m_mode = Mode::Invalid;
- m_inlined.Clear();
- m_outsourced.Clear();
+
+ v.SetCompilerType(desired_type);
+
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+ return ValueObjectConstResult::Create(
+ m_process, v, ConstString(idx_name.GetString()));
+ }
+
+ void Clear() {
+ m_indexes = 0;
+ m_count = 0;
+ m_ptr_size = 0;
+ m_process = nullptr;
+ }
+
+ InlinedIndexes()
+ : m_indexes(0), m_count(0), m_ptr_size(0), m_process(nullptr) {}
+
+ private:
+ uint64_t m_indexes;
+ size_t m_count;
+ uint32_t m_ptr_size;
+ Process *m_process;
+
+ // cfr. Foundation for the details of this code
+ size_t _lengthForInlinePayload(uint32_t ptr_size) {
+ m_ptr_size = ptr_size;
+ if (m_ptr_size == 8)
+ m_count = ((m_indexes >> 3) & 0x7);
+ else
+ m_count = ((m_indexes >> 3) & 0x3);
+ return m_count;
+ }
+
+ std::pair<uint64_t, bool> _indexAtPositionForInlinePayload(size_t pos) {
+ static const uint64_t PACKED_INDEX_MASK = ((1 << 13) - 1);
+ if (m_ptr_size == 8) {
+ switch (pos) {
+ case 3:
+ case 2:
+ case 1:
+ case 0:
+ return {(m_indexes >> PACKED_INDEX_SHIFT_64(pos)) &
+ PACKED_INDEX_MASK,
+ true};
+ default:
+ return {0, false};
+ }
+ } else {
+ switch (pos) {
+ case 0:
+ case 1:
+ return {(m_indexes >> PACKED_INDEX_SHIFT_32(pos)) &
+ PACKED_INDEX_MASK,
+ true};
+ default:
+ return {0, false};
+ }
}
-
- Impl() :
- m_mode(Mode::Invalid)
- {
+ return {0, false};
+ }
+ };
+
+ struct OutsourcedIndexes {
+ lldb::ValueObjectSP GetIndexAtIndex(size_t idx) {
+ if (m_indexes) {
+ ValueObjectSP index_sp(m_indexes->GetSyntheticArrayMember(idx, true));
+ return index_sp;
}
-
- Mode m_mode;
- } m_impl;
-
- uint32_t m_ptr_size;
- CompilerType m_uint_star_type;
+ return nullptr;
+ }
+
+ void Clear() {
+ m_indexes = nullptr;
+ m_count = 0;
+ }
+
+ OutsourcedIndexes() : m_indexes(nullptr), m_count(0) {}
+
+ ValueObject *m_indexes;
+ size_t m_count;
+ };
+
+ union {
+ struct InlinedIndexes m_inlined;
+ struct OutsourcedIndexes m_outsourced;
+ };
+
+ void Clear() {
+ m_mode = Mode::Invalid;
+ m_inlined.Clear();
+ m_outsourced.Clear();
+ }
+
+ Impl() : m_mode(Mode::Invalid) {}
+
+ Mode m_mode;
+ } m_impl;
+
+ uint32_t m_ptr_size;
+ CompilerType m_uint_star_type;
};
namespace lldb_private {
- namespace formatters {
-
- SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
- {
- if (valobj_sp)
- return new NSIndexPathSyntheticFrontEnd(valobj_sp);
- return nullptr;
- }
+namespace formatters {
+
+SyntheticChildrenFrontEnd *
+NSIndexPathSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new NSIndexPathSyntheticFrontEnd(valobj_sp);
+ return nullptr;
+}
- } // namespace formatters
+} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp
index 315771045ba6..9757c5877782 100644
--- a/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/source/Plugins/Language/ObjC/NSSet.cpp
@@ -29,636 +29,572 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-NSSet_Additionals::GetAdditionalSummaries ()
-{
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
- return g_map;
+std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+NSSet_Additionals::GetAdditionalSummaries() {
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
}
-std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
-NSSet_Additionals::GetAdditionalSynthetics ()
-{
- static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
- return g_map;
+std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+NSSet_Additionals::GetAdditionalSynthetics() {
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
+ g_map;
+ return g_map;
}
namespace lldb_private {
- namespace formatters {
- class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSSetISyntheticFrontEnd() override;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- struct DataDescriptor_32
- {
- uint32_t _used : 26;
- uint32_t _szidx : 6;
- };
-
- struct DataDescriptor_64
- {
- uint64_t _used : 58;
- uint32_t _szidx : 6;
- };
-
- struct SetItemDescriptor
- {
- lldb::addr_t item_ptr;
- lldb::ValueObjectSP valobj_sp;
- };
-
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- lldb::addr_t m_data_ptr;
- std::vector<SetItemDescriptor> m_children;
- };
-
- class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSSetMSyntheticFrontEnd() override;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
-
- private:
- struct DataDescriptor_32
- {
- uint32_t _used : 26;
- uint32_t _size;
- uint32_t _mutations;
- uint32_t _objs_addr;
- };
-
- struct DataDescriptor_64
- {
- uint64_t _used : 58;
- uint64_t _size;
- uint64_t _mutations;
- uint64_t _objs_addr;
- };
-
- struct SetItemDescriptor
- {
- lldb::addr_t item_ptr;
- lldb::ValueObjectSP valobj_sp;
- };
-
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- std::vector<SetItemDescriptor> m_children;
- };
-
- class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- ~NSSetCodeRunningSyntheticFrontEnd() override;
-
- size_t
- CalculateNumChildren() override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override;
-
- bool
- Update() override;
-
- bool
- MightHaveChildren() override;
-
- size_t
- GetIndexOfChildWithName(const ConstString &name) override;
- };
- } // namespace formatters
+namespace formatters {
+class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSSetISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSSetISyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ struct DataDescriptor_32 {
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used : 58;
+ uint32_t _szidx : 6;
+ };
+
+ struct SetItemDescriptor {
+ lldb::addr_t item_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ lldb::addr_t m_data_ptr;
+ std::vector<SetItemDescriptor> m_children;
+};
+
+class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSSetMSyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+ struct DataDescriptor_32 {
+ uint32_t _used : 26;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used : 58;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ };
+
+ struct SetItemDescriptor {
+ lldb::addr_t item_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ std::vector<SetItemDescriptor> m_children;
+};
+
+class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSSetCodeRunningSyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+};
+} // namespace formatters
} // namespace lldb_private
-template<bool cf_style>
-bool
-lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- static ConstString g_TypeHint("NSSet");
-
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
- bool is_64bit = (ptr_size == 8);
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t value = 0;
-
- ConstString class_name_cs = descriptor->GetClassName();
- const char* class_name = class_name_cs.GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"__NSSetI"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- }
- else if (!strcmp(class_name,"__NSSetM"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- }
- /*else if (!strcmp(class_name,"__NSCFSet"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
- if (error.Fail())
- return false;
- if (is_64bit)
- value &= ~0x1fff000000000000UL;
- }
- else if (!strcmp(class_name,"NSCountedSet"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error);
- if (error.Fail())
- return false;
- if (is_64bit)
- value &= ~0x1fff000000000000UL;
- }*/
+template <bool cf_style>
+bool lldb_private::formatters::NSSetSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ static ConstString g_TypeHint("NSSet");
+
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+ bool is_64bit = (ptr_size == 8);
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char *class_name = class_name_cs.GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name, "__NSSetI")) {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ } else if (!strcmp(class_name, "__NSSetM")) {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
+ /*else if (!strcmp(class_name,"__NSCFSet"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ?
+ 20 : 12), 4, 0, error);
+ if (error.Fail())
+ return false;
+ if (is_64bit)
+ value &= ~0x1fff000000000000UL;
+ }
+ else if (!strcmp(class_name,"NSCountedSet"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 :
+ 12), 4, 0, error);
+ if (error.Fail())
+ return false;
+ if (is_64bit)
+ value &= ~0x1fff000000000000UL;
+ }*/
+ else {
+ auto &map(NSSet_Additionals::GetAdditionalSummaries());
+ auto iter = map.find(class_name_cs), end = map.end();
+ if (iter != end)
+ return iter->second(valobj, stream, options);
else
- {
- auto& map(NSSet_Additionals::GetAdditionalSummaries());
- auto iter = map.find(class_name_cs), end = map.end();
- if (iter != end)
- return iter->second(valobj, stream, options);
- else
- return false;
+ return false;
+ }
+
+ std::string prefix, suffix;
+ if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(options.GetLanguage()))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
- }
-
- stream.Printf("%s%" PRIu64 " %s%s%s",
- prefix.c_str(),
- value,
- "element",
- value == 1 ? "" : "s",
- suffix.c_str());
- return true;
+ }
+
+ stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element",
+ value == 1 ? "" : "s", suffix.c_str());
+ return true;
}
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
-{
- lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
- if (!process_sp)
- return nullptr;
- ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
- if (!runtime)
- return nullptr;
-
- CompilerType valobj_type(valobj_sp->GetCompilerType());
- Flags flags(valobj_type.GetTypeInfo());
-
- if (flags.IsClear(eTypeIsPointer))
- {
- Error error;
- valobj_sp = valobj_sp->AddressOf(error);
- if (error.Fail() || !valobj_sp)
- return nullptr;
- }
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp));
-
- if (!descriptor || !descriptor->IsValid())
- return nullptr;
-
- ConstString class_name_cs = descriptor->GetClassName();
- const char* class_name = class_name_cs.GetCString();
-
- if (!class_name || !*class_name)
- return nullptr;
-
- if (!strcmp(class_name,"__NSSetI"))
- {
- return (new NSSetISyntheticFrontEnd(valobj_sp));
- }
- else if (!strcmp(class_name,"__NSSetM"))
- {
- return (new NSSetMSyntheticFrontEnd(valobj_sp));
- }
- else
- {
- auto& map(NSSet_Additionals::GetAdditionalSynthetics());
- auto iter = map.find(class_name_cs), end = map.end();
- if (iter != end)
- return iter->second(synth, valobj_sp);
- return nullptr;
- }
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSSetSyntheticFrontEndCreator(
+ CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return nullptr;
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+ if (!runtime)
+ return nullptr;
+
+ CompilerType valobj_type(valobj_sp->GetCompilerType());
+ Flags flags(valobj_type.GetTypeInfo());
+
+ if (flags.IsClear(eTypeIsPointer)) {
+ Error error;
+ valobj_sp = valobj_sp->AddressOf(error);
+ if (error.Fail() || !valobj_sp)
+ return nullptr;
+ }
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(*valobj_sp));
+
+ if (!descriptor || !descriptor->IsValid())
+ return nullptr;
+
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char *class_name = class_name_cs.GetCString();
+
+ if (!class_name || !*class_name)
+ return nullptr;
+
+ if (!strcmp(class_name, "__NSSetI")) {
+ return (new NSSetISyntheticFrontEnd(valobj_sp));
+ } else if (!strcmp(class_name, "__NSSetM")) {
+ return (new NSSetMSyntheticFrontEnd(valobj_sp));
+ } else {
+ auto &map(NSSet_Additionals::GetAdditionalSynthetics());
+ auto iter = map.find(class_name_cs), end = map.end();
+ if (iter != end)
+ return iter->second(synth, valobj_sp);
+ return nullptr;
+ }
}
-lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_exe_ctx_ref(),
- m_ptr_size(8),
- m_data_32(nullptr),
- m_data_64(nullptr)
-{
- if (valobj_sp)
- Update();
+lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_data_32(nullptr), m_data_64(nullptr) {
+ if (valobj_sp)
+ Update();
}
-lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd ()
-{
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
+lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd() {
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
}
size_t
-lldb_private::formatters::NSSetISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+lldb_private::formatters::NSSetISyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
}
size_t
-lldb_private::formatters::NSSetISyntheticFrontEnd::CalculateNumChildren ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+lldb_private::formatters::NSSetISyntheticFrontEnd::CalculateNumChildren() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool
-lldb_private::formatters::NSSetISyntheticFrontEnd::Update()
-{
- m_children.clear();
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- m_ptr_size = 0;
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- if (valobj_sp->IsPointerType())
- {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
- m_data_ptr = data_location + m_ptr_size;
+bool lldb_private::formatters::NSSetISyntheticFrontEnd::Update() {
+ m_children.clear();
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
+ m_ptr_size = 0;
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType()) {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ if (m_ptr_size == 4) {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ error);
+ } else {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ error);
+ }
+ if (error.Fail())
return false;
+ m_data_ptr = data_location + m_ptr_size;
+ return false;
}
-bool
-lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren() {
+ return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- uint32_t num_children = CalculateNumChildren();
-
- if (idx >= num_children)
+lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty()) {
+ // do the scan phase
+ lldb::addr_t obj_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while (tries < num_children) {
+ obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
+ if (!process_sp)
return lldb::ValueObjectSP();
-
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
+ Error error;
+ obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+ if (error.Fail())
return lldb::ValueObjectSP();
-
- if (m_children.empty())
- {
- // do the scan phase
- lldb::addr_t obj_at_idx = 0;
-
- uint32_t tries = 0;
- uint32_t test_idx = 0;
-
- while(tries < num_children)
- {
- obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
-
- test_idx++;
-
- if (!obj_at_idx)
- continue;
- tries++;
-
- SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
-
- m_children.push_back(descriptor);
- }
+
+ test_idx++;
+
+ if (!obj_at_idx)
+ continue;
+ tries++;
+
+ SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
}
-
- if (idx >= m_children.size()) // should never happen
- return lldb::ValueObjectSP();
-
- SetItemDescriptor &set_item = m_children[idx];
- if (!set_item.valobj_sp)
- {
- auto ptr_size = process_sp->GetAddressByteSize();
- DataBufferHeap buffer(ptr_size,0);
- switch (ptr_size)
- {
- case 0: // architecture has no clue?? - fail
- return lldb::ValueObjectSP();
- case 4:
- *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
- break;
- case 8:
- *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
- break;
- default:
- assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
- }
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-
- DataExtractor data(buffer.GetBytes(),
- buffer.GetByteSize(),
- process_sp->GetByteOrder(),
- process_sp->GetAddressByteSize());
-
- set_item.valobj_sp =
- CreateValueObjectFromData(idx_name.GetData(),
- data,
- m_exe_ctx_ref,
- m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ SetItemDescriptor &set_item = m_children[idx];
+ if (!set_item.valobj_sp) {
+ auto ptr_size = process_sp->GetAddressByteSize();
+ DataBufferHeap buffer(ptr_size, 0);
+ switch (ptr_size) {
+ case 0: // architecture has no clue?? - fail
+ return lldb::ValueObjectSP();
+ case 4:
+ *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
+ break;
+ case 8:
+ *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
+ break;
+ default:
+ assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
}
- return set_item.valobj_sp;
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+ DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
+ process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+
+ set_item.valobj_sp = CreateValueObjectFromData(
+ idx_name.GetString(), data, m_exe_ctx_ref,
+ m_backend.GetCompilerType().GetBasicTypeFromAST(
+ lldb::eBasicTypeObjCID));
+ }
+ return set_item.valobj_sp;
}
-lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp),
- m_exe_ctx_ref(),
- m_ptr_size(8),
- m_data_32(nullptr),
- m_data_64(nullptr)
-{
- if (valobj_sp)
- Update ();
+lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_data_32(nullptr), m_data_64(nullptr) {
+ if (valobj_sp)
+ Update();
}
-lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd ()
-{
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
+lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd() {
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
}
size_t
-lldb_private::formatters::NSSetMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
+lldb_private::formatters::NSSetMSyntheticFrontEnd::GetIndexOfChildWithName(
+ const ConstString &name) {
+ const char *item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
}
size_t
-lldb_private::formatters::NSSetMSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+lldb_private::formatters::NSSetMSyntheticFrontEnd::CalculateNumChildren() {
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool
-lldb_private::formatters::NSSetMSyntheticFrontEnd::Update()
-{
- m_children.clear();
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- if (valobj_sp->IsPointerType())
- {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
+bool lldb_private::formatters::NSSetMSyntheticFrontEnd::Update() {
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ delete m_data_32;
+ m_data_32 = nullptr;
+ delete m_data_64;
+ m_data_64 = nullptr;
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType()) {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ if (m_ptr_size == 4) {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ error);
+ } else {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ error);
+ }
+ if (error.Fail())
+ return false;
+ return false;
}
-bool
-lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren ()
-{
- return true;
+bool lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren() {
+ return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
- lldb::addr_t m_objs_addr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
-
- uint32_t num_children = CalculateNumChildren();
-
- if (idx >= num_children)
+lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+ lldb::addr_t m_objs_addr =
+ (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
+
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty()) {
+ // do the scan phase
+ lldb::addr_t obj_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while (tries < num_children) {
+ obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
+ if (!process_sp)
return lldb::ValueObjectSP();
-
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
+ Error error;
+ obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+ if (error.Fail())
return lldb::ValueObjectSP();
-
- if (m_children.empty())
- {
- // do the scan phase
- lldb::addr_t obj_at_idx = 0;
-
- uint32_t tries = 0;
- uint32_t test_idx = 0;
-
- while(tries < num_children)
- {
- obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
-
- test_idx++;
-
- if (!obj_at_idx)
- continue;
- tries++;
-
- SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
-
- m_children.push_back(descriptor);
- }
+
+ test_idx++;
+
+ if (!obj_at_idx)
+ continue;
+ tries++;
+
+ SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
}
-
- if (idx >= m_children.size()) // should never happen
- return lldb::ValueObjectSP();
-
- SetItemDescriptor &set_item = m_children[idx];
- if (!set_item.valobj_sp)
- {
- auto ptr_size = process_sp->GetAddressByteSize();
- DataBufferHeap buffer(ptr_size,0);
- switch (ptr_size)
- {
- case 0: // architecture has no clue?? - fail
- return lldb::ValueObjectSP();
- case 4:
- *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
- break;
- case 8:
- *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
- break;
- default:
- assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
- }
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-
- DataExtractor data(buffer.GetBytes(),
- buffer.GetByteSize(),
- process_sp->GetByteOrder(),
- process_sp->GetAddressByteSize());
-
- set_item.valobj_sp =
- CreateValueObjectFromData(idx_name.GetData(),
- data,
- m_exe_ctx_ref,
- m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ SetItemDescriptor &set_item = m_children[idx];
+ if (!set_item.valobj_sp) {
+ auto ptr_size = process_sp->GetAddressByteSize();
+ DataBufferHeap buffer(ptr_size, 0);
+ switch (ptr_size) {
+ case 0: // architecture has no clue?? - fail
+ return lldb::ValueObjectSP();
+ case 4:
+ *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
+ break;
+ case 8:
+ *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
+ break;
+ default:
+ assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
}
- return set_item.valobj_sp;
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+ DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
+ process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+
+ set_item.valobj_sp = CreateValueObjectFromData(
+ idx_name.GetString(), data, m_exe_ctx_ref,
+ m_backend.GetCompilerType().GetBasicTypeFromAST(
+ lldb::eBasicTypeObjCID));
+ }
+ return set_item.valobj_sp;
}
-template bool
-lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+template bool lldb_private::formatters::NSSetSummaryProvider<true>(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
-template bool
-lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+template bool lldb_private::formatters::NSSetSummaryProvider<false>(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
diff --git a/source/Plugins/Language/ObjC/NSSet.h b/source/Plugins/Language/ObjC/NSSet.h
index c8622706e860..dbc5dfa7e659 100644
--- a/source/Plugins/Language/ObjC/NSSet.h
+++ b/source/Plugins/Language/ObjC/NSSet.h
@@ -1,4 +1,5 @@
-//===-- NSSet.h ---------------------------------------------------*- C++ -*-===//
+//===-- NSSet.h ---------------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,24 +18,23 @@
#include "lldb/DataFormatters/TypeSynthetic.h"
namespace lldb_private {
- namespace formatters
- {
- template<bool cf_style>
- bool
- NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- class NSSet_Additionals
- {
- public:
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
- GetAdditionalSummaries ();
-
- static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
- GetAdditionalSynthetics ();
- };
- } // namespace formatters
+namespace formatters {
+template <bool cf_style>
+bool NSSetSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd *NSSetSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+class NSSet_Additionals {
+public:
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+ GetAdditionalSummaries();
+
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+ GetAdditionalSynthetics();
+};
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_NSSet_h_
diff --git a/source/Plugins/Language/ObjC/NSString.cpp b/source/Plugins/Language/ObjC/NSString.cpp
index 80896631baf3..4f1addccecaa 100644
--- a/source/Plugins/Language/ObjC/NSString.cpp
+++ b/source/Plugins/Language/ObjC/NSString.cpp
@@ -1,4 +1,5 @@
-//===-- NSString.cpp ----------------------------------------------*- C++ -*-===//
+//===-- NSString.cpp ----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -26,380 +27,379 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-NSString_Additionals::GetAdditionalSummaries ()
-{
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
- return g_map;
+std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+NSString_Additionals::GetAdditionalSummaries() {
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
}
-static CompilerType
-GetNSPathStore2Type (Target &target)
-{
- static ConstString g_type_name("__lldb_autogen_nspathstore2");
-
- ClangASTContext *ast_ctx = target.GetScratchClangASTContext();
-
- if (!ast_ctx)
- return CompilerType();
-
- CompilerType voidstar = ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
- CompilerType uint32 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-
- return ast_ctx->GetOrCreateStructForIdentifier(g_type_name, {
- {"isa",voidstar},
- {"lengthAndRef",uint32},
- {"buffer",voidstar}
- });
+static CompilerType GetNSPathStore2Type(Target &target) {
+ static ConstString g_type_name("__lldb_autogen_nspathstore2");
+
+ ClangASTContext *ast_ctx = target.GetScratchClangASTContext();
+
+ if (!ast_ctx)
+ return CompilerType();
+
+ CompilerType voidstar =
+ ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
+ CompilerType uint32 =
+ ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+
+ return ast_ctx->GetOrCreateStructForIdentifier(
+ g_type_name,
+ {{"isa", voidstar}, {"lengthAndRef", uint32}, {"buffer", voidstar}});
}
-bool
-lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
-{
- static ConstString g_TypeHint("NSString");
-
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- ConstString class_name_cs = descriptor->GetClassName();
- const char* class_name = class_name_cs.GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- bool is_tagged_ptr = (0 == strcmp(class_name,"NSTaggedPointerString")) && descriptor->GetTaggedPointerInfo();
- // for a tagged pointer, the descriptor has everything we need
- if (is_tagged_ptr)
- return NSTaggedString_SummaryProvider(valobj, descriptor, stream, summary_options);
-
- auto& additionals_map(NSString_Additionals::GetAdditionalSummaries());
- auto iter = additionals_map.find(class_name_cs), end = additionals_map.end();
- if (iter != end)
- return iter->second(valobj, stream, summary_options);
-
- // if not a tagged pointer that we know about, try the normal route
- uint64_t info_bits_location = valobj_addr + ptr_size;
- if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
- info_bits_location += 3;
-
- Error error;
-
- uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
- if (error.Fail())
- return false;
-
- bool is_mutable = (info_bits & 1) == 1;
- bool is_inline = (info_bits & 0x60) == 0;
- bool has_explicit_length = (info_bits & (1 | 4)) != 4;
- bool is_unicode = (info_bits & 0x10) == 0x10;
- bool is_path_store = strcmp(class_name,"NSPathStore2") == 0;
- bool has_null = (info_bits & 8) == 8;
-
- size_t explicit_length = 0;
- if (!has_null && has_explicit_length && !is_path_store)
- {
- lldb::addr_t explicit_length_offset = 2*ptr_size;
- if (is_mutable && !is_inline)
- explicit_length_offset = explicit_length_offset + ptr_size; // notInlineMutable.length;
- else if (is_inline)
- explicit_length = explicit_length + 0; // inline1.length;
- else if (!is_inline && !is_mutable)
- explicit_length_offset = explicit_length_offset + ptr_size; // notInlineImmutable1.length;
- else
- explicit_length_offset = 0;
-
- if (explicit_length_offset)
- {
- explicit_length_offset = valobj_addr + explicit_length_offset;
- explicit_length = process_sp->ReadUnsignedIntegerFromMemory(explicit_length_offset, 4, 0, error);
- }
- }
-
- if (strcmp(class_name,"NSString") &&
- strcmp(class_name,"CFStringRef") &&
- strcmp(class_name,"CFMutableStringRef") &&
- strcmp(class_name,"__NSCFConstantString") &&
- strcmp(class_name,"__NSCFString") &&
- strcmp(class_name,"NSCFConstantString") &&
- strcmp(class_name,"NSCFString") &&
- strcmp(class_name,"NSPathStore2"))
- {
- // not one of us - but tell me class name
- stream.Printf("class name = %s",class_name);
- return true;
- }
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(summary_options.GetLanguage()))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
- }
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetPrefixToken(prefix);
- options.SetSuffixToken(suffix);
-
- if (is_mutable)
- {
- uint64_t location = 2 * ptr_size + valobj_addr;
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- if (has_explicit_length && is_unicode)
- {
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
- }
- else
- {
- options.SetLocation(location+1);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
- }
+bool lldb_private::formatters::NSStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ static ConstString g_TypeHint("NSString");
+
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime *runtime =
+ (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+ lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+ runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char *class_name = class_name_cs.GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ bool is_tagged_ptr = (0 == strcmp(class_name, "NSTaggedPointerString")) &&
+ descriptor->GetTaggedPointerInfo();
+ // for a tagged pointer, the descriptor has everything we need
+ if (is_tagged_ptr)
+ return NSTaggedString_SummaryProvider(valobj, descriptor, stream,
+ summary_options);
+
+ auto &additionals_map(NSString_Additionals::GetAdditionalSummaries());
+ auto iter = additionals_map.find(class_name_cs), end = additionals_map.end();
+ if (iter != end)
+ return iter->second(valobj, stream, summary_options);
+
+ // if not a tagged pointer that we know about, try the normal route
+ uint64_t info_bits_location = valobj_addr + ptr_size;
+ if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
+ info_bits_location += 3;
+
+ Error error;
+
+ uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(
+ info_bits_location, 1, 0, error);
+ if (error.Fail())
+ return false;
+
+ bool is_mutable = (info_bits & 1) == 1;
+ bool is_inline = (info_bits & 0x60) == 0;
+ bool has_explicit_length = (info_bits & (1 | 4)) != 4;
+ bool is_unicode = (info_bits & 0x10) == 0x10;
+ bool is_path_store = strcmp(class_name, "NSPathStore2") == 0;
+ bool has_null = (info_bits & 8) == 8;
+
+ size_t explicit_length = 0;
+ if (!has_null && has_explicit_length && !is_path_store) {
+ lldb::addr_t explicit_length_offset = 2 * ptr_size;
+ if (is_mutable && !is_inline)
+ explicit_length_offset =
+ explicit_length_offset + ptr_size; // notInlineMutable.length;
+ else if (is_inline)
+ explicit_length = explicit_length + 0; // inline1.length;
+ else if (!is_inline && !is_mutable)
+ explicit_length_offset =
+ explicit_length_offset + ptr_size; // notInlineImmutable1.length;
+ else
+ explicit_length_offset = 0;
+
+ if (explicit_length_offset) {
+ explicit_length_offset = valobj_addr + explicit_length_offset;
+ explicit_length = process_sp->ReadUnsignedIntegerFromMemory(
+ explicit_length_offset, 4, 0, error);
}
- else if (is_inline && has_explicit_length && !is_unicode && !is_path_store && !is_mutable)
- {
- uint64_t location = 3 * ptr_size + valobj_addr;
-
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII> (options);
+ }
+
+ if (strcmp(class_name, "NSString") && strcmp(class_name, "CFStringRef") &&
+ strcmp(class_name, "CFMutableStringRef") &&
+ strcmp(class_name, "__NSCFConstantString") &&
+ strcmp(class_name, "__NSCFString") &&
+ strcmp(class_name, "NSCFConstantString") &&
+ strcmp(class_name, "NSCFString") && strcmp(class_name, "NSPathStore2")) {
+ // not one of us - but tell me class name
+ stream.Printf("class name = %s", class_name);
+ return true;
+ }
+
+ std::string prefix, suffix;
+ if (Language *language =
+ Language::FindPlugin(summary_options.GetLanguage())) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
- else if (is_unicode)
- {
- uint64_t location = valobj_addr + 2*ptr_size;
- if (is_inline)
- {
- if (!has_explicit_length)
- {
- stream.Printf("found new combo");
- return true;
- }
- else
- location += ptr_size;
- }
- else
- {
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- }
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(has_explicit_length == false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(has_explicit_length == false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
+ }
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetPrefixToken(prefix);
+ options.SetSuffixToken(suffix);
+
+ if (is_mutable) {
+ uint64_t location = 2 * ptr_size + valobj_addr;
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ if (has_explicit_length && is_unicode) {
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+ TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options);
+ } else {
+ options.SetLocation(location + 1);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+ TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::ASCII>(options);
}
- else if (is_path_store)
- {
- ProcessStructReader reader(valobj.GetProcessSP().get(), valobj.GetValueAsUnsigned(0), GetNSPathStore2Type(*valobj.GetTargetSP()));
- explicit_length = reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
- lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
-
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(has_explicit_length == false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(has_explicit_length == false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
+ } else if (is_inline && has_explicit_length && !is_unicode &&
+ !is_path_store && !is_mutable) {
+ uint64_t location = 3 * ptr_size + valobj_addr;
+
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+ TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::ASCII>(options);
+ } else if (is_unicode) {
+ uint64_t location = valobj_addr + 2 * ptr_size;
+ if (is_inline) {
+ if (!has_explicit_length) {
+ return false;
+ } else
+ location += ptr_size;
+ } else {
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
}
- else if (is_inline)
- {
- uint64_t location = valobj_addr + 2*ptr_size;
- if (!has_explicit_length)
- {
- // in this kind of string, the byte before the string content is a length byte
- // so let's try and use it to handle the embedded NUL case
- Error 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;
- location++;
- }
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(!has_explicit_length);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(!has_explicit_length);
- options.SetLanguage(summary_options.GetLanguage());
- if (has_explicit_length)
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
- else
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(has_explicit_length == false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+ TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options);
+ } else if (is_path_store) {
+ ProcessStructReader reader(valobj.GetProcessSP().get(),
+ valobj.GetValueAsUnsigned(0),
+ GetNSPathStore2Type(*valobj.GetTargetSP()));
+ explicit_length =
+ reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
+ lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
+
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(has_explicit_length == false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+ TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF16>(options);
+ } else if (is_inline) {
+ uint64_t location = valobj_addr + 2 * ptr_size;
+ if (!has_explicit_length) {
+ // in this kind of string, the byte before the string content is a length
+ // byte
+ // so let's try and use it to handle the embedded NUL case
+ Error 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;
+ location++;
}
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(!has_explicit_length);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+ TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(!has_explicit_length);
+ options.SetLanguage(summary_options.GetLanguage());
+ if (has_explicit_length)
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options);
else
- {
- uint64_t location = valobj_addr + 2*ptr_size;
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- if (has_explicit_length && !has_null)
- explicit_length++; // account for the fact that there is no NULL and we need to have one added
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetSourceSize(explicit_length);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
- }
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::ASCII>(options);
+ } else {
+ uint64_t location = valobj_addr + 2 * ptr_size;
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ if (has_explicit_length && !has_null)
+ explicit_length++; // account for the fact that there is no NULL and we
+ // need to have one added
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetSourceSize(explicit_length);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+ TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::ASCII>(options);
+ }
}
-bool
-lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- TargetSP target_sp(valobj.GetTargetSP());
- if (!target_sp)
- return false;
- uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
- uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
- if (!pointer_value)
- return false;
- pointer_value += addr_size;
- CompilerType type(valobj.GetCompilerType());
- ExecutionContext exe_ctx(target_sp,false);
- ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type));
- if (!child_ptr_sp)
- return false;
- DataExtractor data;
- Error error;
- child_ptr_sp->GetData(data, error);
- if (error.Fail())
- return false;
- ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type));
- child_sp->GetValueAsUnsigned(0);
- if (child_sp)
- return NSStringSummaryProvider(*child_sp, stream, options);
+bool lldb_private::formatters::NSAttributedStringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ TargetSP target_sp(valobj.GetTargetSP());
+ if (!target_sp)
+ return false;
+ uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
+ uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
+ if (!pointer_value)
+ return false;
+ pointer_value += addr_size;
+ CompilerType type(valobj.GetCompilerType());
+ ExecutionContext exe_ctx(target_sp, false);
+ ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress(
+ "string_ptr", pointer_value, exe_ctx, type));
+ if (!child_ptr_sp)
return false;
+ DataExtractor data;
+ Error error;
+ child_ptr_sp->GetData(data, error);
+ if (error.Fail())
+ return false;
+ ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData(
+ "string_data", data, exe_ctx, type));
+ child_sp->GetValueAsUnsigned(0);
+ if (child_sp)
+ return NSStringSummaryProvider(*child_sp, stream, options);
+ return false;
}
-bool
-lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- return NSAttributedStringSummaryProvider(valobj, stream, options);
+bool lldb_private::formatters::NSMutableAttributedStringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ return NSAttributedStringSummaryProvider(valobj, stream, options);
}
-bool
-lldb_private::formatters::NSTaggedString_SummaryProvider (ValueObject& valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream, const TypeSummaryOptions& summary_options)
-{
- static ConstString g_TypeHint("NSString");
-
- if (!descriptor)
- return false;
- uint64_t len_bits = 0, data_bits = 0;
- if (!descriptor->GetTaggedPointerInfo(&len_bits,&data_bits,nullptr))
- return false;
-
- static const int g_MaxNonBitmaskedLen = 7; //TAGGED_STRING_UNPACKED_MAXLEN
- static const int g_SixbitMaxLen = 9;
- static const int g_fiveBitMaxLen = 11;
-
- static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013" "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
-
- if (len_bits > g_fiveBitMaxLen)
- return false;
-
- std::string prefix,suffix;
- if (Language* language = Language::FindPlugin(summary_options.GetLanguage()))
- {
- if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
- {
- prefix.clear();
- suffix.clear();
- }
- }
-
- // this is a fairly ugly trick - pretend that the numeric value is actually a char*
- // this works under a few assumptions:
- // little endian architecture
- // sizeof(uint64_t) > g_MaxNonBitmaskedLen
- if (len_bits <= g_MaxNonBitmaskedLen)
- {
- stream.Printf("%s",prefix.c_str());
- stream.Printf("\"%s\"",(const char*)&data_bits);
- stream.Printf("%s",suffix.c_str());
- return true;
- }
-
- // if the data is bitmasked, we need to actually process the bytes
- uint8_t bitmask = 0;
- uint8_t shift_offset = 0;
-
- if (len_bits <= g_SixbitMaxLen)
- {
- bitmask = 0x03f;
- shift_offset = 6;
- }
- else
- {
- bitmask = 0x01f;
- shift_offset = 5;
- }
-
- std::vector<uint8_t> bytes;
- bytes.resize(len_bits);
- for (; len_bits > 0; data_bits >>= shift_offset, --len_bits)
- {
- uint8_t packed = data_bits & bitmask;
- bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
+bool lldb_private::formatters::NSTaggedString_SummaryProvider(
+ ValueObject &valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor,
+ Stream &stream, const TypeSummaryOptions &summary_options) {
+ static ConstString g_TypeHint("NSString");
+
+ if (!descriptor)
+ return false;
+ uint64_t len_bits = 0, data_bits = 0;
+ if (!descriptor->GetTaggedPointerInfo(&len_bits, &data_bits, nullptr))
+ return false;
+
+ static const int g_MaxNonBitmaskedLen = 7; // TAGGED_STRING_UNPACKED_MAXLEN
+ static const int g_SixbitMaxLen = 9;
+ static const int g_fiveBitMaxLen = 11;
+
+ static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013"
+ "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
+
+ if (len_bits > g_fiveBitMaxLen)
+ return false;
+
+ std::string prefix, suffix;
+ if (Language *language =
+ Language::FindPlugin(summary_options.GetLanguage())) {
+ if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+ suffix)) {
+ prefix.clear();
+ suffix.clear();
}
-
- stream.Printf("%s",prefix.c_str());
- stream.Printf("\"%s\"",&bytes[0]);
- stream.Printf("%s",suffix.c_str());
+ }
+
+ // this is a fairly ugly trick - pretend that the numeric value is actually a
+ // char*
+ // this works under a few assumptions:
+ // little endian architecture
+ // sizeof(uint64_t) > g_MaxNonBitmaskedLen
+ if (len_bits <= g_MaxNonBitmaskedLen) {
+ stream.Printf("%s", prefix.c_str());
+ stream.Printf("\"%s\"", (const char *)&data_bits);
+ stream.Printf("%s", suffix.c_str());
return true;
+ }
+
+ // if the data is bitmasked, we need to actually process the bytes
+ uint8_t bitmask = 0;
+ uint8_t shift_offset = 0;
+
+ if (len_bits <= g_SixbitMaxLen) {
+ bitmask = 0x03f;
+ shift_offset = 6;
+ } else {
+ bitmask = 0x01f;
+ shift_offset = 5;
+ }
+
+ std::vector<uint8_t> bytes;
+ bytes.resize(len_bits);
+ for (; len_bits > 0; data_bits >>= shift_offset, --len_bits) {
+ uint8_t packed = data_bits & bitmask;
+ bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
+ }
+
+ stream.Printf("%s", prefix.c_str());
+ stream.Printf("\"%s\"", &bytes[0]);
+ stream.Printf("%s", suffix.c_str());
+ return true;
}
diff --git a/source/Plugins/Language/ObjC/NSString.h b/source/Plugins/Language/ObjC/NSString.h
index 6a767a55e009..df8480ad6cd8 100644
--- a/source/Plugins/Language/ObjC/NSString.h
+++ b/source/Plugins/Language/ObjC/NSString.h
@@ -1,4 +1,5 @@
-//===-- NSString.h ---------------------------------------------------*- C++ -*-===//
+//===-- NSString.h ---------------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,27 +17,26 @@
#include "lldb/Target/ObjCLanguageRuntime.h"
namespace lldb_private {
- namespace formatters
- {
- bool
- NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSTaggedString_SummaryProvider (ValueObject& valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream, const TypeSummaryOptions& summary_options);
-
- bool
- NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- class NSString_Additionals
- {
- public:
- static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
- GetAdditionalSummaries ();
- };
- } // namespace formatters
+namespace formatters {
+bool NSStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSTaggedString_SummaryProvider(
+ ValueObject &valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor,
+ Stream &stream, const TypeSummaryOptions &summary_options);
+
+bool NSAttributedStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool NSMutableAttributedStringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
+
+class NSString_Additionals {
+public:
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+ GetAdditionalSummaries();
+};
+} // namespace formatters
} // namespace lldb_private
#endif // liblldb_CF_h_
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 0ecbfd35b1a2..6e59a8be3fea 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -21,10 +21,10 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/Target.h"
#include "CF.h"
#include "Cocoa.h"
@@ -37,841 +37,1058 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-void
-ObjCLanguage::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Objective-C Language",
- CreateInstance);
+void ObjCLanguage::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",
+ CreateInstance);
}
-void
-ObjCLanguage::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ObjCLanguage::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ObjCLanguage::GetPluginNameStatic()
-{
- static ConstString g_name("objc");
- return g_name;
+lldb_private::ConstString ObjCLanguage::GetPluginNameStatic() {
+ static ConstString g_name("objc");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ObjCLanguage::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ObjCLanguage::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ObjCLanguage::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ObjCLanguage::GetPluginVersion() { return 1; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-Language *
-ObjCLanguage::CreateInstance (lldb::LanguageType language)
-{
- switch (language)
- {
- case lldb::eLanguageTypeObjC:
- return new ObjCLanguage();
- default:
- return nullptr;
- }
+Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) {
+ switch (language) {
+ case lldb::eLanguageTypeObjC:
+ return new ObjCLanguage();
+ default:
+ return nullptr;
+ }
}
-void
-ObjCLanguage::MethodName::Clear()
-{
- m_full.Clear();
- m_class.Clear();
- m_category.Clear();
- m_selector.Clear();
- m_type = eTypeUnspecified;
- m_category_is_valid = false;
+void ObjCLanguage::MethodName::Clear() {
+ m_full.Clear();
+ m_class.Clear();
+ m_category.Clear();
+ m_selector.Clear();
+ m_type = eTypeUnspecified;
+ m_category_is_valid = false;
}
-bool
-ObjCLanguage::MethodName::SetName (const char *name, bool strict)
-{
- Clear();
- if (name && name[0])
- {
- // If "strict" is true. then the method must be specified with a
- // '+' or '-' at the beginning. If "strict" is false, then the '+'
- // or '-' can be omitted
- bool valid_prefix = false;
-
- if (name[0] == '+' || name[0] == '-')
- {
- valid_prefix = name[1] == '[';
- if (name[0] == '+')
- m_type = eTypeClassMethod;
- else
- m_type = eTypeInstanceMethod;
- }
- else if (!strict)
- {
- // "strict" is false, the name just needs to start with '['
- valid_prefix = name[0] == '[';
- }
-
- if (valid_prefix)
- {
- int name_len = strlen (name);
- // Objective C methods must have at least:
- // "-[" or "+[" prefix
- // One character for a class name
- // One character for the space between the class name
- // One character for the method name
- // "]" suffix
- if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']')
- {
- m_full.SetCStringWithLength(name, name_len);
- }
- }
- }
+bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) {
+ Clear();
+ if (name.empty())
return IsValid(strict);
-}
-const ConstString &
-ObjCLanguage::MethodName::GetClassName ()
-{
- if (!m_class)
- {
- if (IsValid(false))
- {
- const char *full = m_full.GetCString();
- const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
- const char *paren_pos = strchr (class_start, '(');
- if (paren_pos)
- {
- m_class.SetCStringWithLength (class_start, paren_pos - class_start);
- }
- else
- {
- // No '(' was found in the full name, we can definitively say
- // that our category was valid (and empty).
- m_category_is_valid = true;
- const char *space_pos = strchr (full, ' ');
- if (space_pos)
- {
- m_class.SetCStringWithLength (class_start, space_pos - class_start);
- if (!m_class_category)
- {
- // No category in name, so we can also fill in the m_class_category
- m_class_category = m_class;
- }
- }
- }
- }
+ // If "strict" is true. then the method must be specified with a
+ // '+' or '-' at the beginning. If "strict" is false, then the '+'
+ // or '-' can be omitted
+ bool valid_prefix = false;
+
+ if (name[0] == '+' || name[0] == '-') {
+ valid_prefix = name[1] == '[';
+ if (name[0] == '+')
+ m_type = eTypeClassMethod;
+ else
+ m_type = eTypeInstanceMethod;
+ } else if (!strict) {
+ // "strict" is false, the name just needs to start with '['
+ valid_prefix = name[0] == '[';
+ }
+
+ if (valid_prefix) {
+ int name_len = name.size();
+ // Objective C methods must have at least:
+ // "-[" or "+[" prefix
+ // One character for a class name
+ // One character for the space between the class name
+ // One character for the method name
+ // "]" suffix
+ if (name_len >= (5 + (strict ? 1 : 0)) && name.back() == ']') {
+ m_full.SetString(name);
}
- return m_class;
+ }
+ return IsValid(strict);
}
-const ConstString &
-ObjCLanguage::MethodName::GetClassNameWithCategory ()
-{
- if (!m_class_category)
- {
- if (IsValid(false))
- {
- const char *full = m_full.GetCString();
- const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
- const char *space_pos = strchr (full, ' ');
- if (space_pos)
- {
- m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
- // If m_class hasn't been filled in and the class with category doesn't
- // contain a '(', then we can also fill in the m_class
- if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr)
- {
- m_class = m_class_category;
- // No '(' was found in the full name, we can definitively say
- // that our category was valid (and empty).
- m_category_is_valid = true;
+bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) {
+ return SetName(llvm::StringRef(name), strict);
+}
- }
- }
+const ConstString &ObjCLanguage::MethodName::GetClassName() {
+ if (!m_class) {
+ if (IsValid(false)) {
+ const char *full = m_full.GetCString();
+ const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+ const char *paren_pos = strchr(class_start, '(');
+ if (paren_pos) {
+ m_class.SetCStringWithLength(class_start, paren_pos - class_start);
+ } else {
+ // No '(' was found in the full name, we can definitively say
+ // that our category was valid (and empty).
+ m_category_is_valid = true;
+ const char *space_pos = strchr(full, ' ');
+ if (space_pos) {
+ m_class.SetCStringWithLength(class_start, space_pos - class_start);
+ if (!m_class_category) {
+ // No category in name, so we can also fill in the m_class_category
+ m_class_category = m_class;
+ }
}
+ }
}
- return m_class_category;
+ }
+ return m_class;
}
-const ConstString &
-ObjCLanguage::MethodName::GetSelector ()
-{
- if (!m_selector)
- {
- if (IsValid(false))
- {
- const char *full = m_full.GetCString();
- const char *space_pos = strchr (full, ' ');
- if (space_pos)
- {
- ++space_pos; // skip the space
- m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1);
- }
+const ConstString &ObjCLanguage::MethodName::GetClassNameWithCategory() {
+ if (!m_class_category) {
+ if (IsValid(false)) {
+ const char *full = m_full.GetCString();
+ const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+ const char *space_pos = strchr(full, ' ');
+ if (space_pos) {
+ m_class_category.SetCStringWithLength(class_start,
+ space_pos - class_start);
+ // If m_class hasn't been filled in and the class with category doesn't
+ // contain a '(', then we can also fill in the m_class
+ if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr) {
+ m_class = m_class_category;
+ // No '(' was found in the full name, we can definitively say
+ // that our category was valid (and empty).
+ m_category_is_valid = true;
}
+ }
}
- return m_selector;
+ }
+ return m_class_category;
}
-const ConstString &
-ObjCLanguage::MethodName::GetCategory ()
-{
- if (!m_category_is_valid && !m_category)
- {
- if (IsValid(false))
- {
- m_category_is_valid = true;
- const char *full = m_full.GetCString();
- const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
- const char *open_paren_pos = strchr (class_start, '(');
- if (open_paren_pos)
- {
- ++open_paren_pos; // Skip the open paren
- const char *close_paren_pos = strchr (open_paren_pos, ')');
- if (close_paren_pos)
- m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos);
- }
- }
+const ConstString &ObjCLanguage::MethodName::GetSelector() {
+ if (!m_selector) {
+ if (IsValid(false)) {
+ const char *full = m_full.GetCString();
+ const char *space_pos = strchr(full, ' ');
+ if (space_pos) {
+ ++space_pos; // skip the space
+ m_selector.SetCStringWithLength(space_pos, m_full.GetLength() -
+ (space_pos - full) - 1);
+ }
}
- return m_category;
+ }
+ return m_selector;
}
-ConstString
-ObjCLanguage::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category)
-{
- if (IsValid(false))
- {
- if (HasCategory())
- {
- StreamString strm;
- if (m_type == eTypeClassMethod)
- strm.PutChar('+');
- else if (m_type == eTypeInstanceMethod)
- strm.PutChar('-');
- strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString());
- return ConstString(strm.GetString().c_str());
- }
-
- if (!empty_if_no_category)
- {
- // Just return the full name since it doesn't have a category
- return GetFullName();
- }
+const ConstString &ObjCLanguage::MethodName::GetCategory() {
+ if (!m_category_is_valid && !m_category) {
+ if (IsValid(false)) {
+ m_category_is_valid = true;
+ const char *full = m_full.GetCString();
+ const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+ const char *open_paren_pos = strchr(class_start, '(');
+ if (open_paren_pos) {
+ ++open_paren_pos; // Skip the open paren
+ const char *close_paren_pos = strchr(open_paren_pos, ')');
+ if (close_paren_pos)
+ m_category.SetCStringWithLength(open_paren_pos,
+ close_paren_pos - open_paren_pos);
+ }
}
- return ConstString();
+ }
+ return m_category;
}
-size_t
-ObjCLanguage::MethodName::GetFullNames (std::vector<ConstString> &names, bool append)
-{
- if (!append)
- names.clear();
- if (IsValid(false))
- {
- StreamString strm;
- const bool is_class_method = m_type == eTypeClassMethod;
- const bool is_instance_method = m_type == eTypeInstanceMethod;
- const ConstString &category = GetCategory();
- if (is_class_method || is_instance_method)
- {
- names.push_back (m_full);
- if (category)
- {
- strm.Printf("%c[%s %s]",
- is_class_method ? '+' : '-',
- GetClassName().GetCString(),
- GetSelector().GetCString());
- names.push_back(ConstString(strm.GetString().c_str()));
- }
- }
- else
- {
- const ConstString &class_name = GetClassName();
- const ConstString &selector = GetSelector();
- strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
- names.push_back(ConstString(strm.GetString().c_str()));
- strm.Clear();
- strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
- names.push_back(ConstString(strm.GetString().c_str()));
- strm.Clear();
- if (category)
- {
- strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
- names.push_back(ConstString(strm.GetString().c_str()));
- strm.Clear();
- strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
- names.push_back(ConstString(strm.GetString().c_str()));
- }
- }
+ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
+ bool empty_if_no_category) {
+ if (IsValid(false)) {
+ if (HasCategory()) {
+ StreamString strm;
+ if (m_type == eTypeClassMethod)
+ strm.PutChar('+');
+ else if (m_type == eTypeInstanceMethod)
+ strm.PutChar('-');
+ strm.Printf("[%s %s]", GetClassName().GetCString(),
+ GetSelector().GetCString());
+ return ConstString(strm.GetString());
+ }
+
+ if (!empty_if_no_category) {
+ // Just return the full name since it doesn't have a category
+ return GetFullName();
+ }
+ }
+ return ConstString();
+}
+
+size_t ObjCLanguage::MethodName::GetFullNames(std::vector<ConstString> &names,
+ bool append) {
+ if (!append)
+ names.clear();
+ if (IsValid(false)) {
+ StreamString strm;
+ const bool is_class_method = m_type == eTypeClassMethod;
+ const bool is_instance_method = m_type == eTypeInstanceMethod;
+ const ConstString &category = GetCategory();
+ if (is_class_method || is_instance_method) {
+ names.push_back(m_full);
+ if (category) {
+ strm.Printf("%c[%s %s]", is_class_method ? '+' : '-',
+ GetClassName().GetCString(), GetSelector().GetCString());
+ names.emplace_back(strm.GetString());
+ }
+ } else {
+ const ConstString &class_name = GetClassName();
+ const ConstString &selector = GetSelector();
+ strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
+ names.emplace_back(strm.GetString());
+ strm.Clear();
+ strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
+ names.emplace_back(strm.GetString());
+ strm.Clear();
+ if (category) {
+ strm.Printf("+[%s(%s) %s]", class_name.GetCString(),
+ category.GetCString(), selector.GetCString());
+ names.emplace_back(strm.GetString());
+ strm.Clear();
+ strm.Printf("-[%s(%s) %s]", class_name.GetCString(),
+ category.GetCString(), selector.GetCString());
+ names.emplace_back(strm.GetString());
+ }
}
- return names.size();
+ }
+ return names.size();
}
-static void
-LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
-{
- if (!objc_category_sp)
- return;
-
- TypeSummaryImpl::Flags objc_flags;
- objc_flags.SetCascades(false)
- .SetSkipPointers(true)
- .SetSkipReferences(true)
- .SetDontShowChildren(true)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
- lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider,""));
- objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
- ObjC_BOOL_summary);
- objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
- ObjC_BOOL_summary);
- objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
- ObjC_BOOL_summary);
-
+static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
+ if (!objc_category_sp)
+ return;
+
+ TypeSummaryImpl::Flags objc_flags;
+ objc_flags.SetCascades(false)
+ .SetSkipPointers(true)
+ .SetSkipReferences(true)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(
+ objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider, ""));
+ objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
+ ObjC_BOOL_summary);
+ objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
+ ObjC_BOOL_summary);
+ objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
+ ObjC_BOOL_summary);
+
#ifndef LLDB_DISABLE_PYTHON
- // we need to skip pointers here since we are special casing a SEL* when retrieving its value
- objc_flags.SetSkipPointers(true);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("SEL"), objc_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("objc_selector"), objc_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("objc_selector *"), objc_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("SEL *"), objc_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCClassSummaryProvider, "Class summary provider", ConstString("Class"), objc_flags);
-
- SyntheticChildren::Flags class_synth_flags;
- class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
-
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::ObjCClassSyntheticFrontEndCreator, "Class synthetic children", ConstString("Class"), class_synth_flags);
+ // we need to skip pointers here since we are special casing a SEL* when
+ // retrieving its value
+ objc_flags.SetSkipPointers(true);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::ObjCSELSummaryProvider<false>,
+ "SEL summary provider", ConstString("SEL"), objc_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
+ "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
+ "SEL summary provider", ConstString("objc_selector"), objc_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>,
+ "SEL summary provider", ConstString("objc_selector *"), objc_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::ObjCSELSummaryProvider<true>,
+ "SEL summary provider", ConstString("SEL *"), objc_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::ObjCClassSummaryProvider,
+ "Class summary provider", ConstString("Class"), objc_flags);
+
+ SyntheticChildren::Flags class_synth_flags;
+ class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
+ false);
+
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::ObjCClassSyntheticFrontEndCreator,
+ "Class synthetic children", ConstString("Class"),
+ class_synth_flags);
#endif // LLDB_DISABLE_PYTHON
-
- objc_flags.SetSkipPointers(false);
- objc_flags.SetCascades(true);
- objc_flags.SetSkipReferences(false);
-
- AddStringSummary (objc_category_sp,
- "${var.__FuncPtr%A}",
- ConstString("__block_literal_generic"),
- objc_flags);
-
- AddStringSummary(objc_category_sp,
- "${var.years} years, ${var.months} months, ${var.days} days, ${var.hours} hours, ${var.minutes} minutes ${var.seconds} seconds",
- ConstString("CFGregorianUnits"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "location=${var.location} length=${var.length}",
- ConstString("CFRange"),
- objc_flags);
-
- AddStringSummary(objc_category_sp,
- "location=${var.location}, length=${var.length}",
- ConstString("NSRange"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "(${var.origin}, ${var.size}), ...",
- ConstString("NSRectArray"),
- objc_flags);
-
- AddOneLineSummary (objc_category_sp,
- ConstString("NSPoint"),
- objc_flags);
- AddOneLineSummary (objc_category_sp,
- ConstString("NSSize"),
- objc_flags);
- AddOneLineSummary (objc_category_sp,
- ConstString("NSRect"),
- objc_flags);
-
- AddOneLineSummary (objc_category_sp,
- ConstString("CGSize"),
- objc_flags);
- AddOneLineSummary (objc_category_sp,
- ConstString("CGPoint"),
- objc_flags);
- AddOneLineSummary (objc_category_sp,
- ConstString("CGRect"),
- objc_flags);
-
- AddStringSummary(objc_category_sp,
- "red=${var.red} green=${var.green} blue=${var.blue}",
- ConstString("RGBColor"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
- ConstString("Rect"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "{(v=${var.v}, h=${var.h})}",
- ConstString("Point"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "${var.month}/${var.day}/${var.year} ${var.hour} :${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
- ConstString("DateTimeRect *"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "${var.ld.month}/${var.ld.day}/${var.ld.year} ${var.ld.hour} :${var.ld.minute} :${var.ld.second} dayOfWeek:${var.ld.dayOfWeek}",
- ConstString("LongDateRect"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "(x=${var.x}, y=${var.y})",
- ConstString("HIPoint"),
- objc_flags);
- AddStringSummary(objc_category_sp,
- "origin=${var.origin} size=${var.size}",
- ConstString("HIRect"),
- objc_flags);
-
- TypeSummaryImpl::Flags appkit_flags;
- appkit_flags.SetCascades(true)
- .SetSkipPointers(false)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(false)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
- appkit_flags.SetDontShowChildren(false);
-
+
+ objc_flags.SetSkipPointers(false);
+ objc_flags.SetCascades(true);
+ objc_flags.SetSkipReferences(false);
+
+ AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}",
+ ConstString("__block_literal_generic"), objc_flags);
+
+ AddStringSummary(objc_category_sp, "${var.years} years, ${var.months} "
+ "months, ${var.days} days, ${var.hours} "
+ "hours, ${var.minutes} minutes "
+ "${var.seconds} seconds",
+ ConstString("CFGregorianUnits"), objc_flags);
+ AddStringSummary(objc_category_sp,
+ "location=${var.location} length=${var.length}",
+ ConstString("CFRange"), objc_flags);
+
+ AddStringSummary(objc_category_sp,
+ "location=${var.location}, length=${var.length}",
+ ConstString("NSRange"), objc_flags);
+ AddStringSummary(objc_category_sp, "(${var.origin}, ${var.size}), ...",
+ ConstString("NSRectArray"), objc_flags);
+
+ AddOneLineSummary(objc_category_sp, ConstString("NSPoint"), objc_flags);
+ AddOneLineSummary(objc_category_sp, ConstString("NSSize"), objc_flags);
+ AddOneLineSummary(objc_category_sp, ConstString("NSRect"), objc_flags);
+
+ AddOneLineSummary(objc_category_sp, ConstString("CGSize"), objc_flags);
+ AddOneLineSummary(objc_category_sp, ConstString("CGPoint"), objc_flags);
+ AddOneLineSummary(objc_category_sp, ConstString("CGRect"), objc_flags);
+
+ AddStringSummary(objc_category_sp,
+ "red=${var.red} green=${var.green} blue=${var.blue}",
+ ConstString("RGBColor"), objc_flags);
+ AddStringSummary(
+ objc_category_sp,
+ "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
+ ConstString("Rect"), objc_flags);
+ AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}",
+ ConstString("Point"), objc_flags);
+ AddStringSummary(objc_category_sp,
+ "${var.month}/${var.day}/${var.year} ${var.hour} "
+ ":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
+ ConstString("DateTimeRect *"), objc_flags);
+ AddStringSummary(objc_category_sp, "${var.ld.month}/${var.ld.day}/"
+ "${var.ld.year} ${var.ld.hour} "
+ ":${var.ld.minute} :${var.ld.second} "
+ "dayOfWeek:${var.ld.dayOfWeek}",
+ ConstString("LongDateRect"), objc_flags);
+ AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})",
+ ConstString("HIPoint"), objc_flags);
+ AddStringSummary(objc_category_sp, "origin=${var.origin} size=${var.size}",
+ ConstString("HIRect"), objc_flags);
+
+ TypeSummaryImpl::Flags appkit_flags;
+ appkit_flags.SetCascades(true)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(false)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ appkit_flags.SetDontShowChildren(false);
+
#ifndef LLDB_DISABLE_PYTHON
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSSingleObjectArrayI"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), 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, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSSingleEntryDictionaryI"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSSet"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSError_SummaryProvider, "NSError summary provider", ConstString("NSError"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSException_SummaryProvider, "NSException summary provider", ConstString("NSException"), appkit_flags);
-
- // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", ConstString("$_lldb_typegen_nspair"), appkit_flags);
-
- appkit_flags.SetDontShowChildren(true);
-
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArray0"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSSingleObjectArrayI"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("CFMutableArrayRef"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("CFArrayRef"), ScriptedSyntheticChildren::Flags());
-
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryM"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSSingleEntryDictionaryI"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSCFDictionary"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSDictionary"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSMutableDictionary"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFDictionaryRef"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags());
-
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSErrorSyntheticFrontEndCreator, "NSError synthetic children", ConstString("NSError"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSExceptionSyntheticFrontEndCreator, "NSException synthetic children", ConstString("NSException"), ScriptedSyntheticChildren::Flags());
-
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("NSSet"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetI synthetic children", ConstString("__NSSetI"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetM synthetic children", ConstString("__NSSetM"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSMutableSet synthetic children", ConstString("NSMutableSet"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSOrderedSet synthetic children", ConstString("NSOrderedSet"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"), ScriptedSyntheticChildren::Flags());
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), ScriptedSyntheticChildren::Flags());
-
- AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, "NSIndexPath synthetic children", ConstString("NSIndexPath"), ScriptedSyntheticChildren::Flags());
-
- AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
- AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
- AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("const struct __CFBag"), appkit_flags);
- AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
-
- AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"), appkit_flags);
- AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__CFString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSMutableString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSTaggedPointerString"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSAttributedStringSummaryProvider, "NSAttributedString summary provider", ConstString("NSAttributedString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSMutableAttributedString"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSConcreteMutableAttributedString"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider, "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider, "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSNotification"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSConcreteNotification"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("NSURL"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSDate"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("CFTimeZoneRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
-
- // CFAbsoluteTime is actually a double rather than a pointer to an object
- // we do not care about the numeric value, since it is probably meaningless to users
- appkit_flags.SetDontShowValue(true);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::CFAbsoluteTimeSummaryProvider, "CFAbsoluteTime summary provider", ConstString("CFAbsoluteTime"), appkit_flags);
- appkit_flags.SetDontShowValue(false);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, "NSIndexSet summary provider", ConstString("NSMutableIndexSet"), appkit_flags);
-
- AddStringSummary(objc_category_sp,
- "@\"${var.month%d}/${var.day%d}/${var.year%d} ${var.hour%d}:${var.minute%d}:${var.second}\"",
- ConstString("CFGregorianDate"),
- appkit_flags);
-
- AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("CFBitVectorRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("CFMutableBitVectorRef"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("__CFBitVector"), appkit_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("__CFMutableBitVector"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider", ConstString("NSArray"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider",
+ ConstString("__NSSingleObjectArrayI"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider", ConstString("__NSCFArray"), 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,
+ "NSArray summary provider", ConstString("CFMutableArrayRef"),
+ appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<false>,
+ "NSDictionary summary provider", ConstString("NSDictionary"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<false>,
+ "NSDictionary summary provider",
+ ConstString("NSMutableDictionary"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<false>,
+ "NSDictionary summary provider",
+ ConstString("__NSCFDictionary"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<false>,
+ "NSDictionary summary provider", ConstString("__NSDictionaryI"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<false>,
+ "NSDictionary summary provider",
+ ConstString("__NSSingleEntryDictionaryI"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<false>,
+ "NSDictionary summary provider", ConstString("__NSDictionaryM"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<true>,
+ "NSDictionary summary provider", ConstString("CFDictionaryRef"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<true>,
+ "NSDictionary summary provider",
+ ConstString("CFMutableDictionaryRef"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSSetSummaryProvider<false>,
+ "NSSet summary", ConstString("NSSet"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+ "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSSetSummaryProvider<true>,
+ "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>,
+ "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSSetSummaryProvider<false>,
+ "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSSetSummaryProvider<false>,
+ "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSSetSummaryProvider<false>,
+ "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+ "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+ "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+ "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+ "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+ "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSError_SummaryProvider,
+ "NSError summary provider", ConstString("NSError"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSException_SummaryProvider,
+ "NSException summary provider", ConstString("NSException"), appkit_flags);
+
+ // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}",
+ // ConstString("$_lldb_typegen_nspair"), appkit_flags);
+
+ appkit_flags.SetDontShowChildren(true);
+
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("__NSArrayM"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("__NSArrayI"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("__NSArray0"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children",
+ ConstString("__NSSingleObjectArrayI"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("NSArray"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("NSMutableArray"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("__NSCFArray"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children",
+ ConstString("CFMutableArrayRef"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("CFArrayRef"),
+ ScriptedSyntheticChildren::Flags());
+
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("__NSDictionaryM"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("__NSDictionaryI"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children",
+ ConstString("__NSSingleEntryDictionaryI"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("__NSCFDictionary"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("NSDictionary"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("NSMutableDictionary"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("CFDictionaryRef"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"),
+ ScriptedSyntheticChildren::Flags());
+
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSErrorSyntheticFrontEndCreator,
+ "NSError synthetic children", ConstString("NSError"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSExceptionSyntheticFrontEndCreator,
+ "NSException synthetic children", ConstString("NSException"),
+ ScriptedSyntheticChildren::Flags());
+
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "NSSet synthetic children", ConstString("NSSet"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "__NSSetI synthetic children", ConstString("__NSSetI"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "__NSSetM synthetic children", ConstString("__NSSetM"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "NSMutableSet synthetic children", ConstString("NSMutableSet"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "NSOrderedSet synthetic children", ConstString("NSOrderedSet"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"),
+ ScriptedSyntheticChildren::Flags());
+
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator,
+ "NSIndexPath synthetic children", ConstString("NSIndexPath"),
+ ScriptedSyntheticChildren::Flags());
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
+ "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBagSummaryProvider,
+ "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBagSummaryProvider,
+ "CFBag summary provider", ConstString("const struct __CFBag"),
+ appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
+ "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBinaryHeapSummaryProvider,
+ "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBinaryHeapSummaryProvider,
+ "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"),
+ appkit_flags);
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("NSString"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("__CFString"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("CFMutableStringRef"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("NSMutableString"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider",
+ ConstString("__NSCFConstantString"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("NSCFConstantString"),
+ appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("NSCFString"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSStringSummaryProvider,
+ "NSString summary provider",
+ ConstString("NSTaggedPointerString"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSAttributedStringSummaryProvider,
+ "NSAttributedString summary provider",
+ ConstString("NSAttributedString"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp,
+ lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
+ "NSMutableAttributedString summary provider",
+ ConstString("NSMutableAttributedString"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp,
+ lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
+ "NSMutableAttributedString summary provider",
+ ConstString("NSConcreteMutableAttributedString"), appkit_flags);
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider,
+ "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDataSummaryProvider<false>,
+ "NSData summary provider", ConstString("NSData"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+ "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+ "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDataSummaryProvider<false>,
+ "NSData summary provider", ConstString("NSConcreteMutableData"),
+ appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+ "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+ "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
+ "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
+ "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider,
+ "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSNotificationSummaryProvider,
+ "NSNotification summary provider",
+ ConstString("NSNotification"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSNotificationSummaryProvider,
+ "NSNotification summary provider",
+ ConstString("NSConcreteNotification"), appkit_flags);
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+ "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+ "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+ "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+ "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+ "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+ "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSURLSummaryProvider,
+ "NSURL summary provider", ConstString("NSURL"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSURLSummaryProvider,
+ "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDateSummaryProvider,
+ "NSDate summary provider", ConstString("NSDate"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
+ "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
+ "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
+ "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
+ "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSTimeZoneSummaryProvider,
+ "NSTimeZone summary provider", ConstString("CFTimeZoneRef"),
+ appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
+ "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
+
+ // CFAbsoluteTime is actually a double rather than a pointer to an object
+ // we do not care about the numeric value, since it is probably meaningless to
+ // users
+ appkit_flags.SetDontShowValue(true);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFAbsoluteTimeSummaryProvider,
+ "CFAbsoluteTime summary provider",
+ ConstString("CFAbsoluteTime"), appkit_flags);
+ appkit_flags.SetDontShowValue(false);
+
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider,
+ "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSIndexSetSummaryProvider,
+ "NSIndexSet summary provider", ConstString("NSMutableIndexSet"),
+ appkit_flags);
+
+ AddStringSummary(objc_category_sp,
+ "@\"${var.month%d}/${var.day%d}/${var.year%d} "
+ "${var.hour%d}:${var.minute%d}:${var.second}\"",
+ ConstString("CFGregorianDate"), appkit_flags);
+
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBitVectorSummaryProvider,
+ "CFBitVector summary provider", ConstString("CFBitVectorRef"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBitVectorSummaryProvider,
+ "CFBitVector summary provider",
+ ConstString("CFMutableBitVectorRef"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBitVectorSummaryProvider,
+ "CFBitVector summary provider", ConstString("__CFBitVector"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CFBitVectorSummaryProvider,
+ "CFBitVector summary provider",
+ ConstString("__CFMutableBitVector"), appkit_flags);
#endif // LLDB_DISABLE_PYTHON
}
-static void
-LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp)
-{
- if (!objc_category_sp)
- return;
-
- TypeSummaryImpl::Flags cm_flags;
- cm_flags.SetCascades(true)
- .SetDontShowChildren(false)
- .SetDontShowValue(false)
- .SetHideItemNames(false)
- .SetShowMembersOneLiner(false)
- .SetSkipPointers(false)
- .SetSkipReferences(false);
-
+static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) {
+ if (!objc_category_sp)
+ return;
+
+ TypeSummaryImpl::Flags cm_flags;
+ cm_flags.SetCascades(true)
+ .SetDontShowChildren(false)
+ .SetDontShowValue(false)
+ .SetHideItemNames(false)
+ .SetShowMembersOneLiner(false)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false);
+
#ifndef LLDB_DISABLE_PYTHON
- AddCXXSummary(objc_category_sp, lldb_private::formatters::CMTimeSummaryProvider, "CMTime summary provider", ConstString("CMTime"), cm_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::CMTimeSummaryProvider,
+ "CMTime summary provider", ConstString("CMTime"), cm_flags);
#endif // LLDB_DISABLE_PYTHON
}
-lldb::TypeCategoryImplSP
-ObjCLanguage::GetFormatters ()
-{
- static std::once_flag g_initialize;
- static TypeCategoryImplSP g_category;
-
- std::call_once(g_initialize, [this] () -> void {
- DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
- if (g_category)
- {
- LoadCoreMediaFormatters(g_category);
- LoadObjCFormatters(g_category);
- }
- });
- return g_category;
+lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() {
+ static std::once_flag g_initialize;
+ static TypeCategoryImplSP g_category;
+
+ std::call_once(g_initialize, [this]() -> void {
+ DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
+ if (g_category) {
+ LoadCoreMediaFormatters(g_category);
+ LoadObjCFormatters(g_category);
+ }
+ });
+ return g_category;
}
std::vector<ConstString>
-ObjCLanguage::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
-{
- std::vector<ConstString> result;
-
- if (use_dynamic == lldb::eNoDynamicValues)
- return result;
-
- CompilerType compiler_type(valobj.GetCompilerType());
-
- const bool check_cpp = false;
- const bool check_objc = true;
- bool canBeObjCDynamic = compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
-
- if (canBeObjCDynamic)
- {
- do {
- lldb::ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- break;
- ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
- if (runtime == nullptr)
- break;
- ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
- if (!objc_class_sp)
- break;
- if (ConstString name = objc_class_sp->GetClassName())
- result.push_back(name);
- } while (false);
- }
-
+ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj,
+ lldb::DynamicValueType use_dynamic) {
+ std::vector<ConstString> result;
+
+ if (use_dynamic == lldb::eNoDynamicValues)
return result;
-}
-std::unique_ptr<Language::TypeScavenger>
-ObjCLanguage::GetTypeScavenger ()
-{
- class ObjCTypeScavenger : public Language::TypeScavenger
- {
- private:
- class ObjCScavengerResult : public Language::TypeScavenger::Result
- {
- public:
- ObjCScavengerResult (CompilerType type) :
- Language::TypeScavenger::Result(),
- m_compiler_type(type)
- {
- }
-
- bool
- IsValid () override
- {
- return m_compiler_type.IsValid();
- }
-
- bool
- DumpToStream (Stream& stream,
- bool print_help_if_available) override
- {
- if (IsValid())
- {
- m_compiler_type.DumpTypeDescription(&stream);
- stream.EOL();
- return true;
- }
- return false;
- }
+ CompilerType compiler_type(valobj.GetCompilerType());
- ~ObjCScavengerResult() override = default;
-
- private:
- CompilerType m_compiler_type;
- };
-
- protected:
- ObjCTypeScavenger() = default;
-
- ~ObjCTypeScavenger() override = default;
-
- bool
- Find_Impl (ExecutionContextScope *exe_scope,
- const char *key,
- ResultSet &results) override
- {
- bool result = false;
-
- Target* target = exe_scope->CalculateTarget().get();
- if (target)
- {
- if (auto clang_modules_decl_vendor = target->GetClangModulesDeclVendor())
- {
- std::vector <clang::NamedDecl*> decls;
- ConstString key_cs(key);
-
- if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX, decls) > 0 &&
- !decls.empty())
- {
- CompilerType module_type = ClangASTContext::GetTypeForDecl(decls.front());
- result = true;
- std::unique_ptr<Language::TypeScavenger::Result> result(new ObjCScavengerResult(module_type));
- results.insert(std::move(result));
- }
- }
- }
-
- if (!result)
- {
- Process* process = exe_scope->CalculateProcess().get();
- if (process)
- {
- const bool create_on_demand = false;
- auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
- if (objc_runtime)
- {
- auto decl_vendor = objc_runtime->GetDeclVendor();
- if (decl_vendor)
- {
- std::vector<clang::NamedDecl *> decls;
- ConstString name(key);
- decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
- for (auto decl : decls)
- {
- if (decl)
- {
- if (CompilerType candidate = ClangASTContext::GetTypeForDecl(decl))
- {
- result = true;
- std::unique_ptr<Language::TypeScavenger::Result> result(new ObjCScavengerResult(candidate));
- results.insert(std::move(result));
- }
- }
- }
- }
- }
- }
- }
+ const bool check_cpp = false;
+ const bool check_objc = true;
+ bool canBeObjCDynamic =
+ compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
- return result;
- }
+ if (canBeObjCDynamic) {
+ do {
+ lldb::ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ break;
+ ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
+ if (runtime == nullptr)
+ break;
+ ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp(
+ runtime->GetClassDescriptor(valobj));
+ if (!objc_class_sp)
+ break;
+ if (ConstString name = objc_class_sp->GetClassName())
+ result.push_back(name);
+ } while (false);
+ }
- friend class lldb_private::ObjCLanguage;
- };
-
- return std::unique_ptr<TypeScavenger>(new ObjCTypeScavenger());
+ return result;
}
-bool
-ObjCLanguage::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
- std::string& prefix, std::string& suffix)
-{
- static ConstString g_CFBag("CFBag");
- static ConstString g_CFBinaryHeap("CFBinaryHeap");
-
- static ConstString g_NSNumberChar("NSNumber:char");
- static ConstString g_NSNumberShort("NSNumber:short");
- static ConstString g_NSNumberInt("NSNumber:int");
- static ConstString g_NSNumberLong("NSNumber:long");
- static ConstString g_NSNumberFloat("NSNumber:float");
- static ConstString g_NSNumberDouble("NSNumber:double");
-
- static ConstString g_NSData("NSData");
- static ConstString g_NSArray("NSArray");
- static ConstString g_NSString("NSString");
- static ConstString g_NSStringStar("NSString*");
-
- if (type_hint.IsEmpty())
- return false;
-
- prefix.clear();
- suffix.clear();
-
- if (type_hint == g_CFBag ||
- type_hint == g_CFBinaryHeap)
- {
- prefix = "@";
- return true;
- }
-
- if (type_hint == g_NSNumberChar)
- {
- prefix = "(char)";
- return true;
- }
- if (type_hint == g_NSNumberShort)
- {
- prefix = "(short)";
- return true;
- }
- if (type_hint == g_NSNumberInt)
- {
- prefix = "(int)";
- return true;
- }
- if (type_hint == g_NSNumberLong)
- {
- prefix = "(long)";
- return true;
- }
- if (type_hint == g_NSNumberFloat)
- {
- prefix = "(float)";
+std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
+ class ObjCScavengerResult : public Language::TypeScavenger::Result {
+ public:
+ ObjCScavengerResult(CompilerType type)
+ : Language::TypeScavenger::Result(), m_compiler_type(type) {}
+
+ bool IsValid() override { return m_compiler_type.IsValid(); }
+
+ bool DumpToStream(Stream &stream, bool print_help_if_available) override {
+ if (IsValid()) {
+ m_compiler_type.DumpTypeDescription(&stream);
+ stream.EOL();
return true;
+ }
+ return false;
}
- if (type_hint == g_NSNumberDouble)
- {
- prefix = "(double)";
- return true;
+
+ private:
+ CompilerType m_compiler_type;
+ };
+
+ class ObjCRuntimeScavenger : public Language::TypeScavenger {
+ protected:
+ bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+ ResultSet &results) override {
+ bool result = false;
+
+ Process *process = exe_scope->CalculateProcess().get();
+ if (process) {
+ const bool create_on_demand = false;
+ auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
+ if (objc_runtime) {
+ auto decl_vendor = objc_runtime->GetDeclVendor();
+ if (decl_vendor) {
+ std::vector<clang::NamedDecl *> decls;
+ ConstString name(key);
+ decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
+ for (auto decl : decls) {
+ if (decl) {
+ if (CompilerType candidate =
+ ClangASTContext::GetTypeForDecl(decl)) {
+ result = true;
+ std::unique_ptr<Language::TypeScavenger::Result> result(
+ new ObjCScavengerResult(candidate));
+ results.insert(std::move(result));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
}
-
- if (type_hint == g_NSData ||
- type_hint == g_NSArray)
- {
- prefix = "@\"";
- suffix = "\"";
- return true;
+
+ friend class lldb_private::ObjCLanguage;
+ };
+
+ class ObjCModulesScavenger : public Language::TypeScavenger {
+ protected:
+ bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+ ResultSet &results) override {
+ bool result = false;
+
+ Target *target = exe_scope->CalculateTarget().get();
+ if (target) {
+ if (auto clang_modules_decl_vendor =
+ target->GetClangModulesDeclVendor()) {
+ std::vector<clang::NamedDecl *> decls;
+ ConstString key_cs(key);
+
+ if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX,
+ decls) > 0 &&
+ !decls.empty()) {
+ CompilerType module_type =
+ ClangASTContext::GetTypeForDecl(decls.front());
+ result = true;
+ std::unique_ptr<Language::TypeScavenger::Result> result(
+ new ObjCScavengerResult(module_type));
+ results.insert(std::move(result));
+ }
+ }
+ }
+
+ return result;
}
-
- if (type_hint == g_NSString ||
- type_hint == g_NSStringStar)
- {
- prefix = "@";
- return true;
+
+ friend class lldb_private::ObjCLanguage;
+ };
+
+ class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger {
+ public:
+ virtual CompilerType AdjustForInclusion(CompilerType &candidate) override {
+ LanguageType lang_type(candidate.GetMinimumLanguage());
+ if (!Language::LanguageIsObjC(lang_type))
+ return CompilerType();
+ if (candidate.IsTypedefType())
+ return candidate.GetTypedefedType();
+ return candidate;
}
-
+ };
+
+ return std::unique_ptr<TypeScavenger>(
+ new Language::EitherTypeScavenger<ObjCModulesScavenger,
+ ObjCRuntimeScavenger,
+ ObjCDebugInfoScavenger>());
+}
+
+bool ObjCLanguage::GetFormatterPrefixSuffix(ValueObject &valobj,
+ ConstString type_hint,
+ std::string &prefix,
+ std::string &suffix) {
+ static ConstString g_CFBag("CFBag");
+ static ConstString g_CFBinaryHeap("CFBinaryHeap");
+
+ static ConstString g_NSNumberChar("NSNumber:char");
+ static ConstString g_NSNumberShort("NSNumber:short");
+ static ConstString g_NSNumberInt("NSNumber:int");
+ static ConstString g_NSNumberLong("NSNumber:long");
+ static ConstString g_NSNumberFloat("NSNumber:float");
+ static ConstString g_NSNumberDouble("NSNumber:double");
+
+ static ConstString g_NSData("NSData");
+ static ConstString g_NSArray("NSArray");
+ static ConstString g_NSString("NSString");
+ static ConstString g_NSStringStar("NSString*");
+
+ if (type_hint.IsEmpty())
return false;
+
+ prefix.clear();
+ suffix.clear();
+
+ if (type_hint == g_CFBag || type_hint == g_CFBinaryHeap) {
+ prefix = "@";
+ return true;
+ }
+
+ if (type_hint == g_NSNumberChar) {
+ prefix = "(char)";
+ return true;
+ }
+ if (type_hint == g_NSNumberShort) {
+ prefix = "(short)";
+ return true;
+ }
+ if (type_hint == g_NSNumberInt) {
+ prefix = "(int)";
+ return true;
+ }
+ if (type_hint == g_NSNumberLong) {
+ prefix = "(long)";
+ return true;
+ }
+ if (type_hint == g_NSNumberFloat) {
+ prefix = "(float)";
+ return true;
+ }
+ if (type_hint == g_NSNumberDouble) {
+ prefix = "(double)";
+ return true;
+ }
+
+ if (type_hint == g_NSData || type_hint == g_NSArray) {
+ prefix = "@\"";
+ suffix = "\"";
+ return true;
+ }
+
+ if (type_hint == g_NSString || type_hint == g_NSStringStar) {
+ prefix = "@";
+ return true;
+ }
+
+ return false;
}
-bool
-ObjCLanguage::IsNilReference (ValueObject& valobj)
-{
- const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
- bool isObjCpointer = (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
- if (!isObjCpointer)
- return false;
- bool canReadValue = true;
- bool isZero = valobj.GetValueAsUnsigned(0,&canReadValue) == 0;
- return canReadValue && isZero;
+bool ObjCLanguage::IsNilReference(ValueObject &valobj) {
+ const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
+ bool isObjCpointer =
+ (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
+ if (!isObjCpointer)
+ return false;
+ bool canReadValue = true;
+ bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
+ return canReadValue && isZero;
}
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.h b/source/Plugins/Language/ObjC/ObjCLanguage.h
index b1435d26429a..b458b58998b6 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -17,195 +17,149 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class ObjCLanguage :
- public Language
-{
+
+class ObjCLanguage : public Language {
public:
- class MethodName
- {
- public:
- enum Type
- {
- eTypeUnspecified,
- eTypeClassMethod,
- eTypeInstanceMethod
- };
-
- MethodName () :
- m_full(),
- m_class(),
- m_category(),
- m_selector(),
- m_type (eTypeUnspecified),
- m_category_is_valid (false)
- {
- }
-
- MethodName (const char *name, bool strict) :
- m_full(),
- m_class(),
- m_category(),
- m_selector(),
- m_type (eTypeUnspecified),
- m_category_is_valid (false)
- {
- SetName (name, strict);
- }
-
- void
- Clear();
-
- bool
- IsValid (bool strict) const
- {
- // If "strict" is true, the name must have everything specified including
- // the leading "+" or "-" on the method name
- if (strict && m_type == eTypeUnspecified)
- return false;
- // Other than that, m_full will only be filled in if the objective C
- // name is valid.
- return (bool)m_full;
- }
-
- bool
- HasCategory()
- {
- return !GetCategory().IsEmpty();
- }
-
- Type
- GetType () const
- {
- return m_type;
- }
-
- const ConstString &
- GetFullName () const
- {
- return m_full;
- }
-
- ConstString
- GetFullNameWithoutCategory (bool empty_if_no_category);
-
- bool
- SetName (const char *name, bool strict);
-
- const ConstString &
- GetClassName ();
-
- const ConstString &
- GetClassNameWithCategory ();
-
- const ConstString &
- GetCategory ();
-
- const ConstString &
- GetSelector ();
-
- // Get all possible names for a method. Examples:
- // If name is "+[NSString(my_additions) myStringWithCString:]"
- // names[0] => "+[NSString(my_additions) myStringWithCString:]"
- // names[1] => "+[NSString myStringWithCString:]"
- // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]"
- // names[0] => "+[NSString(my_additions) myStringWithCString:]"
- // names[1] => "-[NSString(my_additions) myStringWithCString:]"
- // names[2] => "+[NSString myStringWithCString:]"
- // names[3] => "-[NSString myStringWithCString:]"
- size_t
- GetFullNames (std::vector<ConstString> &names, bool append);
-
- protected:
- ConstString m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]"
- ConstString m_class; // Class name: "NSString"
- ConstString m_class_category; // Class with category: "NSString(my_additions)"
- ConstString m_category; // Category: "my_additions"
- ConstString m_selector; // Selector: "myStringWithCString:"
- Type m_type;
- bool m_category_is_valid;
- };
-
- ObjCLanguage() = default;
-
- ~ObjCLanguage() override = default;
-
- lldb::LanguageType
- GetLanguageType () const override
- {
- return lldb::eLanguageTypeObjC;
+ class MethodName {
+ public:
+ enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
+
+ MethodName()
+ : m_full(), m_class(), m_category(), m_selector(),
+ m_type(eTypeUnspecified), m_category_is_valid(false) {}
+
+ MethodName(const char *name, bool strict)
+ : m_full(), m_class(), m_category(), m_selector(),
+ m_type(eTypeUnspecified), m_category_is_valid(false) {
+ SetName(name, strict);
}
-
- lldb::TypeCategoryImplSP
- GetFormatters () override;
-
- std::vector<ConstString>
- GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic) override;
-
- std::unique_ptr<TypeScavenger>
- GetTypeScavenger () override;
-
- bool
- GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
- std::string& prefix, std::string& suffix) override;
-
- bool
- IsNilReference (ValueObject& valobj) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::Language *
- CreateInstance (lldb::LanguageType language);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static bool
- IsPossibleObjCMethodName (const char *name)
- {
- if (!name)
- return false;
- bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
- bool ends_right = (name[strlen(name) - 1] == ']');
- return (starts_right && ends_right);
+ MethodName(llvm::StringRef name, bool strict)
+ : m_full(), m_class(), m_category(), m_selector(),
+ m_type(eTypeUnspecified), m_category_is_valid(false) {
+ SetName(name, strict);
}
-
- static bool
- IsPossibleObjCSelector (const char *name)
- {
- if (!name)
- return false;
-
- if (strchr(name, ':') == nullptr)
- return true;
- else if (name[strlen(name) - 1] == ':')
- return true;
- else
- return false;
+
+ void Clear();
+
+ bool IsValid(bool strict) const {
+ // If "strict" is true, the name must have everything specified including
+ // the leading "+" or "-" on the method name
+ if (strict && m_type == eTypeUnspecified)
+ return false;
+ // Other than that, m_full will only be filled in if the objective C
+ // name is valid.
+ return (bool)m_full;
}
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
+
+ bool HasCategory() { return !GetCategory().IsEmpty(); }
+
+ Type GetType() const { return m_type; }
+
+ const ConstString &GetFullName() const { return m_full; }
+
+ ConstString GetFullNameWithoutCategory(bool empty_if_no_category);
+
+ bool SetName(const char *name, bool strict);
+ bool SetName(llvm::StringRef name, bool strict);
+
+ const ConstString &GetClassName();
+
+ const ConstString &GetClassNameWithCategory();
+
+ const ConstString &GetCategory();
+
+ const ConstString &GetSelector();
+
+ // Get all possible names for a method. Examples:
+ // If name is "+[NSString(my_additions) myStringWithCString:]"
+ // names[0] => "+[NSString(my_additions) myStringWithCString:]"
+ // names[1] => "+[NSString myStringWithCString:]"
+ // If name is specified without the leading '+' or '-' like
+ // "[NSString(my_additions) myStringWithCString:]"
+ // names[0] => "+[NSString(my_additions) myStringWithCString:]"
+ // names[1] => "-[NSString(my_additions) myStringWithCString:]"
+ // names[2] => "+[NSString myStringWithCString:]"
+ // names[3] => "-[NSString myStringWithCString:]"
+ size_t GetFullNames(std::vector<ConstString> &names, bool append);
+
+ protected:
ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]"
+ ConstString m_class; // Class name: "NSString"
+ ConstString
+ m_class_category; // Class with category: "NSString(my_additions)"
+ ConstString m_category; // Category: "my_additions"
+ ConstString m_selector; // Selector: "myStringWithCString:"
+ Type m_type;
+ bool m_category_is_valid;
+ };
+
+ ObjCLanguage() = default;
+
+ ~ObjCLanguage() override = default;
+
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeObjC;
+ }
+
+ lldb::TypeCategoryImplSP GetFormatters() override;
+
+ std::vector<ConstString>
+ GetPossibleFormattersMatches(ValueObject &valobj,
+ lldb::DynamicValueType use_dynamic) override;
+
+ std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
+
+ bool GetFormatterPrefixSuffix(ValueObject &valobj, ConstString type_hint,
+ std::string &prefix,
+ std::string &suffix) override;
+
+ bool IsNilReference(ValueObject &valobj) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::Language *CreateInstance(lldb::LanguageType language);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static bool IsPossibleObjCMethodName(const char *name) {
+ if (!name)
+ return false;
+ bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
+ bool ends_right = (name[strlen(name) - 1] == ']');
+ return (starts_right && ends_right);
+ }
+
+ static bool IsPossibleObjCSelector(const char *name) {
+ if (!name)
+ return false;
+
+ if (strchr(name, ':') == nullptr)
+ return true;
+ else if (name[strlen(name) - 1] == ':')
+ return true;
+ else
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
};
-
+
} // namespace lldb_private
#endif // liblldb_ObjCLanguage_h_
diff --git a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
index 62ddafefad97..cb73eef54682 100644
--- a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
@@ -1,4 +1,5 @@
-//===-- ObjCPlusPlusLanguage.cpp --------------------------------------*- C++ -*-===//
+//===-- ObjCPlusPlusLanguage.cpp --------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,54 +16,37 @@
using namespace lldb;
using namespace lldb_private;
-void
-ObjCPlusPlusLanguage::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Objective-C++ Language",
- CreateInstance);
+void ObjCPlusPlusLanguage::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C++ Language",
+ CreateInstance);
}
-void
-ObjCPlusPlusLanguage::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ObjCPlusPlusLanguage::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ObjCPlusPlusLanguage::GetPluginNameStatic()
-{
- static ConstString g_name("objcplusplus");
- return g_name;
+lldb_private::ConstString ObjCPlusPlusLanguage::GetPluginNameStatic() {
+ static ConstString g_name("objcplusplus");
+ return g_name;
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ObjCPlusPlusLanguage::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ObjCPlusPlusLanguage::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ObjCPlusPlusLanguage::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ObjCPlusPlusLanguage::GetPluginVersion() { return 1; }
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-Language *
-ObjCPlusPlusLanguage::CreateInstance (lldb::LanguageType language)
-{
- switch (language)
- {
- case lldb::eLanguageTypeObjC_plus_plus:
- return new ObjCPlusPlusLanguage();
- default:
- return nullptr;
- }
+Language *ObjCPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
+ switch (language) {
+ case lldb::eLanguageTypeObjC_plus_plus:
+ return new ObjCPlusPlusLanguage();
+ default:
+ return nullptr;
+ }
}
diff --git a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index 0e1db66b0899..588b52215c10 100644
--- a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -14,50 +14,40 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class ObjCPlusPlusLanguage :
- public Language
-{
+
+class ObjCPlusPlusLanguage : public Language {
public:
- ObjCPlusPlusLanguage() = default;
-
- ~ObjCPlusPlusLanguage() override = default;
-
- lldb::LanguageType
- GetLanguageType() const override
- {
- return lldb::eLanguageTypeObjC_plus_plus;
- }
-
- //------------------------------------------------------------------
- // 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;
+ ObjCPlusPlusLanguage() = default;
+
+ ~ObjCPlusPlusLanguage() override = default;
+
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeObjC_plus_plus;
+ }
+
+ //------------------------------------------------------------------
+ // 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_CPlusPlusLanguage_h_
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index c49feb07200e..ddfbd864e92c 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -1,4 +1,5 @@
-//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*- C++ -*-===//
+//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*-
+//C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -40,579 +41,533 @@ using namespace lldb_private;
static const char *vtable_demangled_prefix = "vtable for ";
-bool
-ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
-{
- const bool check_cxx = true;
- const bool check_objc = false;
- return in_value.GetCompilerType().IsPossibleDynamicType (NULL, check_cxx, check_objc);
+bool ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
+ const bool check_cxx = true;
+ const bool check_objc = false;
+ return in_value.GetCompilerType().IsPossibleDynamicType(NULL, check_cxx,
+ check_objc);
}
-TypeAndOrName
-ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr,
- lldb::addr_t vtable_load_addr)
-{
- if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS)
- {
- // Find the symbol that contains the "vtable_load_addr" address
- Address vtable_addr;
- Target &target = m_process->GetTarget();
- if (!target.GetSectionLoadList().IsEmpty())
- {
- if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr, vtable_addr))
- {
- // See if we have cached info for this type already
- TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
- if (type_info)
- return type_info;
-
- SymbolContext sc;
- target.GetImages().ResolveSymbolContextForAddress(vtable_addr, eSymbolContextSymbol, sc);
- Symbol *symbol = sc.symbol;
- if (symbol != NULL)
- {
- const char *name = symbol->GetMangled().GetDemangledName(lldb::eLanguageTypeC_plus_plus).AsCString();
- if (name && strstr(name, vtable_demangled_prefix) == name)
- {
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n",
- original_ptr,
- in_value.GetTypeName().GetCString(),
- name);
- // We are a C++ class, that's good. Get the class name and look it up:
- const char *class_name = name + strlen(vtable_demangled_prefix);
- type_info.SetName(class_name);
- const bool exact_match = true;
- TypeList class_types;
-
- uint32_t num_matches = 0;
- // First look in the module that the vtable symbol came from
- // and look for a single exact match.
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- if (sc.module_sp)
- {
- num_matches = sc.module_sp->FindTypes (sc,
- ConstString(class_name),
- exact_match,
- 1,
- searched_symbol_files,
- class_types);
- }
-
- // If we didn't find a symbol, then move on to the entire
- // module list in the target and get as many unique matches
- // as possible
- if (num_matches == 0)
- {
- num_matches = target.GetImages().FindTypes(sc, ConstString(class_name), exact_match,
- UINT32_MAX, searched_symbol_files, class_types);
- }
-
- lldb::TypeSP type_sp;
- if (num_matches == 0)
- {
- if (log)
- log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", original_ptr);
- return TypeAndOrName();
- }
- if (num_matches == 1)
- {
- type_sp = class_types.GetTypeAtIndex(0);
- if (type_sp)
- {
- if (ClangASTContext::IsCXXClassType(type_sp->GetForwardCompilerType()))
- {
- if (log)
- log->Printf("0x%16.16" PRIx64
- ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
- "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(), type_sp->GetID(),
- type_sp->GetName().GetCString());
- type_info.SetTypeSP(type_sp);
- }
- }
- }
- else if (num_matches > 1)
- {
- size_t i;
- if (log)
- {
- for (i = 0; i < num_matches; i++)
- {
- type_sp = class_types.GetTypeAtIndex(i);
- if (type_sp)
- {
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr,
- in_value.GetTypeName().AsCString(),
- type_sp->GetID(),
- type_sp->GetName().GetCString());
- }
- }
- }
-
- for (i = 0; i < num_matches; i++)
- {
- type_sp = class_types.GetTypeAtIndex(i);
- if (type_sp)
- {
- if (ClangASTContext::IsCXXClassType(type_sp->GetForwardCompilerType()))
- {
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr,
- in_value.GetTypeName().AsCString(),
- type_sp->GetID(),
- type_sp->GetName().GetCString());
- type_info.SetTypeSP(type_sp);
- }
- }
- }
-
- if (log && i == num_matches)
- {
- log->Printf("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic "
- "types, didn't find a C++ match\n",
- original_ptr, in_value.GetTypeName().AsCString());
- }
- }
- if (type_info)
- SetDynamicTypeInfo(vtable_addr, type_info);
- return type_info;
- }
+TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
+ ValueObject &in_value, lldb::addr_t original_ptr,
+ lldb::addr_t vtable_load_addr) {
+ if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) {
+ // Find the symbol that contains the "vtable_load_addr" address
+ Address vtable_addr;
+ Target &target = m_process->GetTarget();
+ if (!target.GetSectionLoadList().IsEmpty()) {
+ if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr,
+ vtable_addr)) {
+ // See if we have cached info for this type already
+ TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
+ if (type_info)
+ return type_info;
+
+ SymbolContext sc;
+ target.GetImages().ResolveSymbolContextForAddress(
+ vtable_addr, eSymbolContextSymbol, sc);
+ Symbol *symbol = sc.symbol;
+ if (symbol != NULL) {
+ const char *name =
+ symbol->GetMangled()
+ .GetDemangledName(lldb::eLanguageTypeC_plus_plus)
+ .AsCString();
+ if (name && strstr(name, vtable_demangled_prefix) == name) {
+ Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("0x%16.16" PRIx64
+ ": static-type = '%s' has vtable symbol '%s'\n",
+ original_ptr, in_value.GetTypeName().GetCString(),
+ name);
+ // We are a C++ class, that's good. Get the class name and look it
+ // up:
+ const char *class_name = name + strlen(vtable_demangled_prefix);
+ type_info.SetName(class_name);
+ const bool exact_match = true;
+ TypeList class_types;
+
+ uint32_t num_matches = 0;
+ // First look in the module that the vtable symbol came from
+ // and look for a single exact match.
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ if (sc.module_sp) {
+ num_matches = sc.module_sp->FindTypes(
+ sc, ConstString(class_name), exact_match, 1,
+ searched_symbol_files, class_types);
+ }
+
+ // If we didn't find a symbol, then move on to the entire
+ // module list in the target and get as many unique matches
+ // as possible
+ if (num_matches == 0) {
+ num_matches = target.GetImages().FindTypes(
+ sc, ConstString(class_name), exact_match, UINT32_MAX,
+ searched_symbol_files, class_types);
+ }
+
+ lldb::TypeSP type_sp;
+ if (num_matches == 0) {
+ if (log)
+ log->Printf("0x%16.16" PRIx64 ": is not dynamic\n",
+ original_ptr);
+ return TypeAndOrName();
+ }
+ if (num_matches == 1) {
+ type_sp = class_types.GetTypeAtIndex(0);
+ if (type_sp) {
+ if (ClangASTContext::IsCXXClassType(
+ type_sp->GetForwardCompilerType())) {
+ if (log)
+ log->Printf(
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
+ "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ type_info.SetTypeSP(type_sp);
+ }
+ }
+ } else if (num_matches > 1) {
+ size_t i;
+ if (log) {
+ for (i = 0; i < num_matches; i++) {
+ type_sp = class_types.GetTypeAtIndex(i);
+ if (type_sp) {
+ if (log)
+ log->Printf(
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ }
}
+ }
+
+ for (i = 0; i < num_matches; i++) {
+ type_sp = class_types.GetTypeAtIndex(i);
+ if (type_sp) {
+ if (ClangASTContext::IsCXXClassType(
+ type_sp->GetForwardCompilerType())) {
+ if (log)
+ log->Printf(
+ "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
+ "matching dynamic types, picking "
+ "this one: uid={0x%" PRIx64
+ "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ type_info.SetTypeSP(type_sp);
+ }
+ }
+ }
+
+ if (log && i == num_matches) {
+ log->Printf(
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types, didn't find a C++ match\n",
+ original_ptr, in_value.GetTypeName().AsCString());
+ }
}
+ if (type_info)
+ SetDynamicTypeInfo(vtable_addr, type_info);
+ return type_info;
+ }
}
+ }
}
- return TypeAndOrName();
+ }
+ return TypeAndOrName();
}
-bool
-ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &dynamic_address,
- Value::ValueType &value_type)
-{
- // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
- // in the object. That will point to the "address point" within the vtable (not the beginning of the
- // vtable.) We can then look up the symbol containing this "address point" and that symbol's name
- // demangled will contain the full class name.
- // The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
- // start of the value object which holds the dynamic type.
- //
-
- class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
-
- // 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;
-
- ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
-
- Process *process = exe_ctx.GetProcessPtr();
-
- if (process == nullptr)
- return false;
-
- Error error;
- const lldb::addr_t vtable_address_point = process->ReadPointerFromMemory(original_ptr, error);
-
- if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS)
- {
- return false;
- }
+bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address,
+ Value::ValueType &value_type) {
+ // For Itanium, if the type has a vtable pointer in the object, it will be at
+ // offset 0
+ // in the object. That will point to the "address point" within the vtable
+ // (not the beginning of the
+ // vtable.) We can then look up the symbol containing this "address point"
+ // and that symbol's name
+ // demangled will contain the full class name.
+ // The second pointer above the "address point" is the "offset_to_top". We'll
+ // use that to get the
+ // start of the value object which holds the dynamic type.
+ //
+
+ class_type_or_name.Clear();
+ value_type = Value::ValueType::eValueTypeScalar;
+
+ // 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;
+
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (process == nullptr)
+ return false;
+
+ Error error;
+ const lldb::addr_t vtable_address_point =
+ process->ReadPointerFromMemory(original_ptr, error);
+
+ if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) {
+ return false;
+ }
- 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;
- }
+ 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;
+ }
- // 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;
- }
+ // 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;
+ }
}
+ }
- return class_type_or_name.IsEmpty() == false;
+ return class_type_or_name.IsEmpty() == false;
}
-TypeAndOrName
-ItaniumABILanguageRuntime::FixUpDynamicType(const TypeAndOrName& type_and_or_name,
- ValueObject& static_value)
-{
- CompilerType static_type(static_value.GetCompilerType());
- Flags static_type_flags(static_type.GetTypeInfo());
-
- TypeAndOrName ret(type_and_or_name);
- if (type_and_or_name.HasType())
- {
- // The type will always be the type of the dynamic object. If our parent's type was a pointer,
- // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
- // should be okay...
- CompilerType orig_type = type_and_or_name.GetCompilerType();
- CompilerType corrected_type = orig_type;
- if (static_type_flags.AllSet(eTypeIsPointer))
- corrected_type = orig_type.GetPointerType ();
- else if (static_type_flags.AllSet(eTypeIsReference))
- corrected_type = orig_type.GetLValueReferenceType();
- ret.SetCompilerType(corrected_type);
- }
- else
- {
- // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
- std::string corrected_name (type_and_or_name.GetName().GetCString());
- if (static_type_flags.AllSet(eTypeIsPointer))
- corrected_name.append(" *");
- else if (static_type_flags.AllSet(eTypeIsReference))
- corrected_name.append(" &");
- // the parent type should be a correctly pointer'ed or referenc'ed type
- ret.SetCompilerType(static_type);
- ret.SetName(corrected_name.c_str());
- }
- return ret;
+TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType(
+ const TypeAndOrName &type_and_or_name, ValueObject &static_value) {
+ CompilerType static_type(static_value.GetCompilerType());
+ Flags static_type_flags(static_type.GetTypeInfo());
+
+ TypeAndOrName ret(type_and_or_name);
+ if (type_and_or_name.HasType()) {
+ // The type will always be the type of the dynamic object. If our parent's
+ // type was a pointer,
+ // then our type should be a pointer to the type of the dynamic object. If
+ // a reference, then the original type
+ // should be okay...
+ CompilerType orig_type = type_and_or_name.GetCompilerType();
+ CompilerType corrected_type = orig_type;
+ if (static_type_flags.AllSet(eTypeIsPointer))
+ corrected_type = orig_type.GetPointerType();
+ else if (static_type_flags.AllSet(eTypeIsReference))
+ corrected_type = orig_type.GetLValueReferenceType();
+ ret.SetCompilerType(corrected_type);
+ } else {
+ // If we are here we need to adjust our dynamic type name to include the
+ // correct & or * symbol
+ std::string corrected_name(type_and_or_name.GetName().GetCString());
+ if (static_type_flags.AllSet(eTypeIsPointer))
+ corrected_name.append(" *");
+ else if (static_type_flags.AllSet(eTypeIsReference))
+ corrected_name.append(" &");
+ // the parent type should be a correctly pointer'ed or referenc'ed type
+ ret.SetCompilerType(static_type);
+ ret.SetName(corrected_name.c_str());
+ }
+ return ret;
}
-bool
-ItaniumABILanguageRuntime::IsVTableName (const char *name)
-{
- if (name == NULL)
- return false;
-
- // Can we maybe ask Clang about this?
- if (strstr (name, "_vptr$") == name)
- return true;
- else
- return false;
+bool ItaniumABILanguageRuntime::IsVTableName(const char *name) {
+ if (name == NULL)
+ return false;
+
+ // Can we maybe ask Clang about this?
+ if (strstr(name, "_vptr$") == name)
+ return true;
+ else
+ return false;
}
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
LanguageRuntime *
-ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language)
-{
- // FIXME: We have to check the process and make sure we actually know that this process supports
- // the Itanium ABI.
- if (language == eLanguageTypeC_plus_plus ||
- language == eLanguageTypeC_plus_plus_03 ||
- language == eLanguageTypeC_plus_plus_11 ||
- language == eLanguageTypeC_plus_plus_14)
- return new ItaniumABILanguageRuntime (process);
- else
- return NULL;
+ItaniumABILanguageRuntime::CreateInstance(Process *process,
+ lldb::LanguageType language) {
+ // FIXME: We have to check the process and make sure we actually know that
+ // this process supports
+ // the Itanium ABI.
+ if (language == eLanguageTypeC_plus_plus ||
+ language == eLanguageTypeC_plus_plus_03 ||
+ language == eLanguageTypeC_plus_plus_11 ||
+ language == eLanguageTypeC_plus_plus_14)
+ return new ItaniumABILanguageRuntime(process);
+ else
+ return NULL;
}
-class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed
-{
+class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed {
public:
- CommandObjectMultiwordItaniumABI_Demangle (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "demangle",
- "Demangle a C++ mangled name.",
- "language cplusplus demangle")
- {
- CommandArgumentEntry arg;
- CommandArgumentData index_arg;
-
- // Define the first (and only) variant of this arg.
- index_arg.arg_type = eArgTypeSymbol;
- index_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (index_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectMultiwordItaniumABI_Demangle() override = default;
-
+ CommandObjectMultiwordItaniumABI_Demangle(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "demangle",
+ "Demangle a C++ mangled name.",
+ "language cplusplus demangle") {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeSymbol;
+ index_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectMultiwordItaniumABI_Demangle() override = default;
+
protected:
- bool
- DoExecute(Args& command, CommandReturnObject &result) override
- {
- bool demangled_any = false;
- bool error_any = false;
- for (size_t i = 0; i < command.GetArgumentCount(); i++)
- {
- auto arg = command.GetArgumentAtIndex(i);
- if (arg && *arg)
- {
- ConstString mangled_cs(arg);
-
- // the actual Mangled class should be strict about this, but on the command line
- // if you're copying mangled names out of 'nm' on Darwin, they will come out with
- // an extra underscore - be willing to strip this on behalf of the user
- // This is the moral equivalent of the -_/-n options to c++filt
- if (mangled_cs.GetStringRef().startswith("__Z"))
- mangled_cs.SetCString(arg+1);
-
- Mangled mangled(mangled_cs, true);
- if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus)
- {
- ConstString demangled(mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
- demangled_any = true;
- result.AppendMessageWithFormat("%s ---> %s\n", arg, demangled.GetCString());
- }
- else
- {
- error_any = true;
- result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", arg);
- }
- }
- }
-
- result.SetStatus(error_any ? lldb::eReturnStatusFailed :
- (demangled_any ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult));
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ bool demangled_any = false;
+ bool error_any = false;
+ for (auto &entry : command.entries()) {
+ if (entry.ref.empty())
+ continue;
+
+ // the actual Mangled class should be strict about this, but on the
+ // command line if you're copying mangled names out of 'nm' on Darwin,
+ // they will come out with an extra underscore - be willing to strip
+ // this on behalf of the user. This is the moral equivalent of the -_/-n
+ // options to c++filt
+ auto name = entry.ref;
+ if (name.startswith("__Z"))
+ name = name.drop_front();
+
+ Mangled mangled(name, true);
+ if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) {
+ ConstString demangled(
+ mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
+ demangled_any = true;
+ result.AppendMessageWithFormat("%s ---> %s\n", entry.ref.str().c_str(),
+ demangled.GetCString());
+ } else {
+ error_any = true;
+ result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n",
+ entry.ref.str().c_str());
+ }
}
+
+ result.SetStatus(
+ error_any ? lldb::eReturnStatusFailed
+ : (demangled_any ? lldb::eReturnStatusSuccessFinishResult
+ : lldb::eReturnStatusSuccessFinishNoResult));
+ return result.Succeeded();
+ }
};
-class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword
-{
+class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword {
public:
- CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "cplusplus", "Commands for operating on the C++ language runtime.",
- "cplusplus <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("demangle", CommandObjectSP (new CommandObjectMultiwordItaniumABI_Demangle (interpreter)));
- }
-
- ~CommandObjectMultiwordItaniumABI() override = default;
+ CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "cplusplus",
+ "Commands for operating on the C++ language runtime.",
+ "cplusplus <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "demangle",
+ CommandObjectSP(
+ new CommandObjectMultiwordItaniumABI_Demangle(interpreter)));
+ }
+
+ ~CommandObjectMultiwordItaniumABI() override = default;
};
-void
-ItaniumABILanguageRuntime::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Itanium ABI for the C++ language",
- CreateInstance,
- [] (CommandInterpreter& interpreter) -> lldb::CommandObjectSP {
- return CommandObjectSP(new CommandObjectMultiwordItaniumABI(interpreter));
- });
+void ItaniumABILanguageRuntime::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "Itanium ABI for the C++ language", CreateInstance,
+ [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
+ return CommandObjectSP(
+ new CommandObjectMultiwordItaniumABI(interpreter));
+ });
}
-void
-ItaniumABILanguageRuntime::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ItaniumABILanguageRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ItaniumABILanguageRuntime::GetPluginNameStatic()
-{
- static ConstString g_name("itanium");
- return g_name;
+lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginNameStatic() {
+ static ConstString g_name("itanium");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ItaniumABILanguageRuntime::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ItaniumABILanguageRuntime::GetPluginVersion()
-{
- return 1;
+uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; }
+
+BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
+ Breakpoint *bkpt, bool catch_bp, bool throw_bp) {
+ return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false);
}
-BreakpointResolverSP
-ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
-{
- return CreateExceptionResolver (bkpt, catch_bp, throw_bp, false);
+BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
+ Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) {
+ // One complication here is that most users DON'T want to stop at
+ // __cxa_allocate_expression, but until we can do
+ // anything better with predicting unwinding the expression parser does. So
+ // we have two forms of the exception
+ // breakpoints, one for expressions that leaves out __cxa_allocate_exception,
+ // and one that includes it.
+ // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint
+ // in the runtime the former.
+ static const char *g_catch_name = "__cxa_begin_catch";
+ static const char *g_throw_name1 = "__cxa_throw";
+ static const char *g_throw_name2 = "__cxa_rethrow";
+ static const char *g_exception_throw_name = "__cxa_allocate_exception";
+ std::vector<const char *> exception_names;
+ exception_names.reserve(4);
+ if (catch_bp)
+ exception_names.push_back(g_catch_name);
+
+ if (throw_bp) {
+ exception_names.push_back(g_throw_name1);
+ exception_names.push_back(g_throw_name2);
+ }
+
+ if (for_expressions)
+ exception_names.push_back(g_exception_throw_name);
+
+ BreakpointResolverSP resolver_sp(new BreakpointResolverName(
+ bkpt, exception_names.data(), exception_names.size(),
+ eFunctionNameTypeBase, eLanguageTypeUnknown, 0, eLazyBoolNo));
+
+ return resolver_sp;
}
-BreakpointResolverSP
-ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions)
-{
- // One complication here is that most users DON'T want to stop at __cxa_allocate_expression, but until we can do
- // anything better with predicting unwinding the expression parser does. So we have two forms of the exception
- // breakpoints, one for expressions that leaves out __cxa_allocate_exception, and one that includes it.
- // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in the runtime the former.
- static const char *g_catch_name = "__cxa_begin_catch";
- static const char *g_throw_name1 = "__cxa_throw";
- static const char *g_throw_name2 = "__cxa_rethrow";
- static const char *g_exception_throw_name = "__cxa_allocate_exception";
- std::vector<const char *> exception_names;
- exception_names.reserve(4);
- if (catch_bp)
- exception_names.push_back(g_catch_name);
-
- if (throw_bp)
- {
- exception_names.push_back(g_throw_name1);
- exception_names.push_back(g_throw_name2);
- }
+lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() {
+ Target &target = m_process->GetTarget();
- if (for_expressions)
- exception_names.push_back(g_exception_throw_name);
-
- BreakpointResolverSP resolver_sp (new BreakpointResolverName (bkpt,
- exception_names.data(),
- exception_names.size(),
- eFunctionNameTypeBase,
- eLanguageTypeUnknown,
- 0,
- eLazyBoolNo));
-
- return resolver_sp;
+ if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
+ // 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));
+ return target.GetSearchFilterForModuleList(&filter_modules);
+ } else {
+ return LanguageRuntime::CreateExceptionSearchFilter();
+ }
}
+lldb::BreakpointSP ItaniumABILanguageRuntime::CreateExceptionBreakpoint(
+ bool catch_bp, bool throw_bp, bool for_expressions, bool is_internal) {
+ Target &target = m_process->GetTarget();
+ FileSpecList filter_modules;
+ BreakpointResolverSP exception_resolver_sp =
+ CreateExceptionResolver(NULL, catch_bp, throw_bp, for_expressions);
+ SearchFilterSP filter_sp(CreateExceptionSearchFilter());
+ const bool hardware = false;
+ const bool resolve_indirect_functions = false;
+ return target.CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal,
+ hardware, resolve_indirect_functions);
+}
+void ItaniumABILanguageRuntime::SetExceptionBreakpoints() {
+ if (!m_process)
+ return;
-lldb::SearchFilterSP
-ItaniumABILanguageRuntime::CreateExceptionSearchFilter ()
-{
- Target &target = m_process->GetTarget();
+ const bool catch_bp = false;
+ const bool throw_bp = true;
+ const bool is_internal = true;
+ const bool for_expressions = true;
- if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
- {
- // 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));
- return target.GetSearchFilterForModuleList(&filter_modules);
- }
- else
- {
- return LanguageRuntime::CreateExceptionSearchFilter();
- }
-}
-
-lldb::BreakpointSP
-ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp,
- bool throw_bp,
- bool for_expressions,
- bool is_internal)
-{
- Target &target = m_process->GetTarget();
- FileSpecList filter_modules;
- BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
- SearchFilterSP filter_sp (CreateExceptionSearchFilter ());
- const bool hardware = false;
- const bool resolve_indirect_functions = false;
- return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, hardware, resolve_indirect_functions);
-}
+ // For the exception breakpoints set by the Expression parser, we'll be a
+ // little more aggressive and
+ // stop at exception allocation as well.
-void
-ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
-{
- if (!m_process)
- return;
-
- const bool catch_bp = false;
- const bool throw_bp = true;
- const bool is_internal = true;
- const bool for_expressions = true;
-
- // For the exception breakpoints set by the Expression parser, we'll be a little more aggressive and
- // stop at exception allocation as well.
-
+ if (m_cxx_exception_bp_sp) {
+ m_cxx_exception_bp_sp->SetEnabled(true);
+ } else {
+ m_cxx_exception_bp_sp = CreateExceptionBreakpoint(
+ catch_bp, throw_bp, for_expressions, is_internal);
if (m_cxx_exception_bp_sp)
- {
- m_cxx_exception_bp_sp->SetEnabled (true);
- }
- else
- {
- m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, for_expressions, is_internal);
- if (m_cxx_exception_bp_sp)
- m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
- }
-
+ m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
+ }
}
-void
-ItaniumABILanguageRuntime::ClearExceptionBreakpoints ()
-{
- if (!m_process)
- return;
-
- if (m_cxx_exception_bp_sp)
- {
- m_cxx_exception_bp_sp->SetEnabled (false);
- }
+void ItaniumABILanguageRuntime::ClearExceptionBreakpoints() {
+ if (!m_process)
+ return;
+
+ if (m_cxx_exception_bp_sp) {
+ m_cxx_exception_bp_sp->SetEnabled(false);
+ }
}
-bool
-ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet ()
-{
- return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled();
+bool ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet() {
+ return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled();
}
-bool
-ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
-{
- if (!m_process)
- return false;
-
- if (!stop_reason ||
- stop_reason->GetStopReason() != eStopReasonBreakpoint)
- return false;
-
- uint64_t break_site_id = stop_reason->GetValue();
- return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(break_site_id,
- m_cxx_exception_bp_sp->GetID());
-
+bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop(
+ lldb::StopInfoSP stop_reason) {
+ if (!m_process)
+ return false;
+
+ if (!stop_reason || stop_reason->GetStopReason() != eStopReasonBreakpoint)
+ return false;
+
+ uint64_t break_site_id = stop_reason->GetValue();
+ return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(
+ break_site_id, m_cxx_exception_bp_sp->GetID());
}
-TypeAndOrName
-ItaniumABILanguageRuntime::GetDynamicTypeInfo(const lldb_private::Address &vtable_addr)
-{
- std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
- DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
- if (pos == m_dynamic_type_map.end())
- return TypeAndOrName();
- else
- return pos->second;
+TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo(
+ const lldb_private::Address &vtable_addr) {
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
+ if (pos == m_dynamic_type_map.end())
+ return TypeAndOrName();
+ else
+ return pos->second;
}
-void
-ItaniumABILanguageRuntime::SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info)
-{
- std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
- m_dynamic_type_map[vtable_addr] = type_info;
+void ItaniumABILanguageRuntime::SetDynamicTypeInfo(
+ const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info) {
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ m_dynamic_type_map[vtable_addr] = type_info;
}
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index 86bd728d6c6f..480c32691c8b 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -18,116 +18,98 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Core/Value.h"
#include "lldb/Symbol/Type.h"
-#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/CPPLanguageRuntime.h"
-#include "lldb/Core/Value.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
- class ItaniumABILanguageRuntime :
- public lldb_private::CPPLanguageRuntime
- {
- public:
- ~ItaniumABILanguageRuntime() 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();
-
- bool
- IsVTableName(const char *name) override;
-
- bool
- GetDynamicTypeAndAddress(ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
-
- TypeAndOrName
- FixUpDynamicType(const TypeAndOrName& type_and_or_name,
- ValueObject& static_value) override;
-
- bool
- CouldHaveDynamicValue(ValueObject &in_value) override;
-
- void
- SetExceptionBreakpoints() override;
-
- void
- ClearExceptionBreakpoints() override;
-
- bool
- ExceptionBreakpointsAreSet() override;
-
- bool
- ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
-
- lldb::BreakpointResolverSP
- CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
-
- lldb::SearchFilterSP
- CreateExceptionSearchFilter() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- protected:
- lldb::BreakpointResolverSP
- CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions);
-
- lldb::BreakpointSP
- CreateExceptionBreakpoint(bool catch_bp,
- bool throw_bp,
- bool for_expressions,
- bool is_internal);
-
- private:
- typedef std::map<lldb_private::Address, TypeAndOrName> DynamicTypeCache;
-
- ItaniumABILanguageRuntime(Process *process)
- : // Call CreateInstance instead.
- lldb_private::CPPLanguageRuntime(process),
- m_cxx_exception_bp_sp(),
- m_dynamic_type_map(),
- m_dynamic_type_map_mutex()
- {
- }
-
- lldb::BreakpointSP m_cxx_exception_bp_sp;
- DynamicTypeCache m_dynamic_type_map;
- std::mutex m_dynamic_type_map_mutex;
-
- TypeAndOrName
- GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr, lldb::addr_t vtable_addr);
-
- TypeAndOrName
- GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
-
- void
- SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info);
- };
-
+
+class ItaniumABILanguageRuntime : public lldb_private::CPPLanguageRuntime {
+public:
+ ~ItaniumABILanguageRuntime() 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();
+
+ bool IsVTableName(const char *name) override;
+
+ bool GetDynamicTypeAndAddress(ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address,
+ Value::ValueType &value_type) override;
+
+ TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) override;
+
+ bool CouldHaveDynamicValue(ValueObject &in_value) override;
+
+ void SetExceptionBreakpoints() override;
+
+ void ClearExceptionBreakpoints() override;
+
+ bool ExceptionBreakpointsAreSet() override;
+
+ bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
+
+ lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
+ bool catch_bp,
+ bool throw_bp) override;
+
+ lldb::SearchFilterSP CreateExceptionSearchFilter() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+protected:
+ lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
+ bool catch_bp,
+ bool throw_bp,
+ bool for_expressions);
+
+ lldb::BreakpointSP CreateExceptionBreakpoint(bool catch_bp, bool throw_bp,
+ bool for_expressions,
+ bool is_internal);
+
+private:
+ typedef std::map<lldb_private::Address, TypeAndOrName> DynamicTypeCache;
+
+ ItaniumABILanguageRuntime(Process *process)
+ : // Call CreateInstance instead.
+ lldb_private::CPPLanguageRuntime(process),
+ m_cxx_exception_bp_sp(), m_dynamic_type_map(),
+ m_dynamic_type_map_mutex() {}
+
+ lldb::BreakpointSP m_cxx_exception_bp_sp;
+ DynamicTypeCache m_dynamic_type_map;
+ std::mutex m_dynamic_type_map_mutex;
+
+ TypeAndOrName GetTypeInfoFromVTableAddress(ValueObject &in_value,
+ lldb::addr_t original_ptr,
+ lldb::addr_t vtable_addr);
+
+ TypeAndOrName GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
+
+ void SetDynamicTypeInfo(const lldb_private::Address &vtable_addr,
+ const TypeAndOrName &type_info);
+};
+
} // namespace lldb_private
#endif // liblldb_ItaniumABILanguageRuntime_h_
diff --git a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
index c752971e7a09..1450835298e6 100644
--- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
@@ -1,4 +1,5 @@
-//===-- GoLanguageRuntime.cpp --------------------------------------*- C++ -*-===//
+//===-- GoLanguageRuntime.cpp --------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -36,206 +37,179 @@ 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()) {
- Error err;
- result = result->Dereference(err);
- if (err.Fail())
- result.reset();
- }
- return result;
+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()) {
+ Error 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)
- {
- Error 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 ReadString(ValueObject &str, Process *process) {
+ ConstString result;
+ ValueObjectSP data = GetChild(str, "str", false);
+ ValueObjectSP len = GetChild(str, "len");
+ if (len && data) {
+ Error 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());
- }
+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("");
+ }
+ 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();
- Error 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();
- }
+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();
+ Error 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::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))
- {
- Error 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;
+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)) {
+ Error 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;
}
- 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;
+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;
+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::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language Runtime",
+ CreateInstance);
}
-void
-GoLanguageRuntime::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void GoLanguageRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-GoLanguageRuntime::GetPluginNameStatic()
-{
- static ConstString g_name("golang");
- return g_name;
+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;
+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
index 596d2888dc85..9c2ee15cff65 100644
--- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h
@@ -14,80 +14,73 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
-#include "lldb/Target/LanguageRuntime.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.
- };
-
+
+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/JavaLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
index 07312a8af0d6..36c30a99ff87 100644
--- a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
@@ -23,154 +23,135 @@
using namespace lldb;
using namespace lldb_private;
-JavaLanguageRuntime::JavaLanguageRuntime(Process *process) : LanguageRuntime(process)
-{
-}
+JavaLanguageRuntime::JavaLanguageRuntime(Process *process)
+ : LanguageRuntime(process) {}
LanguageRuntime *
-JavaLanguageRuntime::CreateInstance(Process *process, lldb::LanguageType language)
-{
- if (language == eLanguageTypeJava)
- return new JavaLanguageRuntime(process);
- return nullptr;
+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::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java language runtime",
+ CreateInstance);
}
-void
-JavaLanguageRuntime::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
+void JavaLanguageRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-JavaLanguageRuntime::GetPluginNameStatic()
-{
- static ConstString g_name("java");
- return g_name;
+lldb_private::ConstString JavaLanguageRuntime::GetPluginNameStatic() {
+ static ConstString g_name("java");
+ return g_name;
}
-lldb_private::ConstString
-JavaLanguageRuntime::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString JavaLanguageRuntime::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-JavaLanguageRuntime::GetPluginVersion()
-{
- return 1;
-}
+uint32_t JavaLanguageRuntime::GetPluginVersion() { return 1; }
-bool
-JavaLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value)
-{
- return true;
+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);
- }
- }
+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();
+ }
+ 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;
- }
- }
+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;
+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
index 83ed35dbb59d..6eeb4041572a 100644
--- a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
@@ -19,70 +19,58 @@
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class JavaLanguageRuntime : public LanguageRuntime
-{
+class JavaLanguageRuntime : public LanguageRuntime {
public:
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::LanguageRuntime *
- CreateInstance(Process *process, lldb::LanguageType language);
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- lldb::LanguageType
- GetLanguageType() const override
- {
- return lldb::eLanguageTypeJava;
- }
+ lldb::LanguageType GetLanguageType() const override {
+ return lldb::eLanguageTypeJava;
+ }
- bool
- GetObjectDescription(Stream &str, ValueObject &object) override
- {
- return false;
- }
+ bool GetObjectDescription(Stream &str, ValueObject &object) override {
+ return false;
+ }
- bool
- GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) 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;
- }
+ 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;
+ TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) override;
- bool
- CouldHaveDynamicValue(ValueObject &in_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;
+ 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);
+ JavaLanguageRuntime(Process *process);
private:
- DISALLOW_COPY_AND_ASSIGN(JavaLanguageRuntime);
+ DISALLOW_COPY_AND_ASSIGN(JavaLanguageRuntime);
};
} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 5cf99a573d86..131f31f69a9f 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -1,4 +1,5 @@
-//===-- AppleObjCClassDescriptorV2.cpp -----------------------------*- C++ -*-===//
+//===-- AppleObjCClassDescriptorV2.cpp -----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,557 +16,546 @@
using namespace lldb;
using namespace lldb_private;
-bool
-ClassDescriptorV2::Read_objc_class (Process* process, std::unique_ptr<objc_class_t> &objc_class) const
-{
- objc_class.reset(new objc_class_t);
-
- bool ret = objc_class->Read (process, m_objc_class_ptr);
-
- if (!ret)
- objc_class.reset();
-
- return ret;
-}
+bool ClassDescriptorV2::Read_objc_class(
+ Process *process, std::unique_ptr<objc_class_t> &objc_class) const {
+ objc_class.reset(new objc_class_t);
-bool
-ClassDescriptorV2::objc_class_t::Read(Process *process, lldb::addr_t addr)
-{
- size_t ptr_size = process->GetAddressByteSize();
-
- size_t objc_class_size = ptr_size // uintptr_t isa;
- + ptr_size // Class superclass;
- + ptr_size // void *cache;
- + ptr_size // IMP *vtable;
- + ptr_size; // uintptr_t data_NEVER_USE;
-
- DataBufferHeap objc_class_buf (objc_class_size, '\0');
- Error error;
-
- process->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size, error);
- if (error.Fail())
- {
- return false;
- }
-
- DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size, process->GetByteOrder(), process->GetAddressByteSize());
-
- lldb::offset_t cursor = 0;
-
- m_isa = extractor.GetAddress_unchecked(&cursor); // uintptr_t isa;
- m_superclass = extractor.GetAddress_unchecked(&cursor); // Class superclass;
- m_cache_ptr = extractor.GetAddress_unchecked(&cursor); // void *cache;
- m_vtable_ptr = extractor.GetAddress_unchecked(&cursor); // IMP *vtable;
- lldb::addr_t data_NEVER_USE = extractor.GetAddress_unchecked(&cursor); // uintptr_t data_NEVER_USE;
-
- m_flags = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3);
- m_data_ptr = data_NEVER_USE & ~(lldb::addr_t)3;
-
- return true;
+ bool ret = objc_class->Read(process, m_objc_class_ptr);
+
+ if (!ret)
+ objc_class.reset();
+
+ return ret;
}
-bool
-ClassDescriptorV2::class_rw_t::Read(Process *process, lldb::addr_t addr)
-{
- size_t ptr_size = process->GetAddressByteSize();
-
- size_t size = sizeof(uint32_t) // uint32_t flags;
- + sizeof(uint32_t) // uint32_t version;
- + ptr_size // const class_ro_t *ro;
- + ptr_size // union { method_list_t **method_lists; method_list_t *method_list; };
- + ptr_size // struct chained_property_list *properties;
- + ptr_size // const protocol_list_t **protocols;
- + ptr_size // Class firstSubclass;
- + ptr_size; // Class nextSiblingClass;
-
- DataBufferHeap buffer (size, '\0');
- Error error;
-
- process->ReadMemory(addr, buffer.GetBytes(), size, error);
- if (error.Fail())
- {
- return false;
- }
-
- DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
-
- lldb::offset_t cursor = 0;
-
- m_flags = extractor.GetU32_unchecked(&cursor);
- m_version = extractor.GetU32_unchecked(&cursor);
- m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
- m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
- m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
- m_firstSubclass = extractor.GetAddress_unchecked(&cursor);
- m_nextSiblingClass = extractor.GetAddress_unchecked(&cursor);
-
- return true;
+static lldb::addr_t GetClassDataMask(Process *process) {
+ switch (process->GetAddressByteSize()) {
+ case 4:
+ return 0xfffffffcUL;
+ case 8:
+ return 0x00007ffffffffff8UL;
+ default:
+ break;
+ }
+
+ return LLDB_INVALID_ADDRESS;
}
-bool
-ClassDescriptorV2::class_ro_t::Read(Process *process, lldb::addr_t addr)
-{
- size_t ptr_size = process->GetAddressByteSize();
-
- size_t size = sizeof(uint32_t) // uint32_t flags;
- + sizeof(uint32_t) // uint32_t instanceStart;
- + sizeof(uint32_t) // uint32_t instanceSize;
- + (ptr_size == 8 ? sizeof(uint32_t) : 0) // uint32_t reserved; // __LP64__ only
- + ptr_size // const uint8_t *ivarLayout;
- + ptr_size // const char *name;
- + ptr_size // const method_list_t *baseMethods;
- + ptr_size // const protocol_list_t *baseProtocols;
- + ptr_size // const ivar_list_t *ivars;
- + ptr_size // const uint8_t *weakIvarLayout;
- + ptr_size; // const property_list_t *baseProperties;
-
- DataBufferHeap buffer (size, '\0');
- Error error;
-
- process->ReadMemory(addr, buffer.GetBytes(), size, error);
- if (error.Fail())
- {
- return false;
- }
-
- DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
-
- lldb::offset_t cursor = 0;
-
- m_flags = extractor.GetU32_unchecked(&cursor);
- m_instanceStart = extractor.GetU32_unchecked(&cursor);
- m_instanceSize = extractor.GetU32_unchecked(&cursor);
- if (ptr_size == 8)
- m_reserved = extractor.GetU32_unchecked(&cursor);
- else
- m_reserved = 0;
- m_ivarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
- m_name_ptr = extractor.GetAddress_unchecked(&cursor);
- m_baseMethods_ptr = extractor.GetAddress_unchecked(&cursor);
- m_baseProtocols_ptr = extractor.GetAddress_unchecked(&cursor);
- m_ivars_ptr = extractor.GetAddress_unchecked(&cursor);
- m_weakIvarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
- m_baseProperties_ptr = extractor.GetAddress_unchecked(&cursor);
-
- DataBufferHeap name_buf(1024, '\0');
-
- process->ReadCStringFromMemory(m_name_ptr, (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
-
- if (error.Fail())
- {
- return false;
- }
-
- m_name.assign((char*)name_buf.GetBytes());
-
- return true;
+bool ClassDescriptorV2::objc_class_t::Read(Process *process,
+ lldb::addr_t addr) {
+ size_t ptr_size = process->GetAddressByteSize();
+
+ size_t objc_class_size = ptr_size // uintptr_t isa;
+ + ptr_size // Class superclass;
+ + ptr_size // void *cache;
+ + ptr_size // IMP *vtable;
+ + ptr_size; // uintptr_t data_NEVER_USE;
+
+ DataBufferHeap objc_class_buf(objc_class_size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size,
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_isa = extractor.GetAddress_unchecked(&cursor); // uintptr_t isa;
+ m_superclass = extractor.GetAddress_unchecked(&cursor); // Class superclass;
+ m_cache_ptr = extractor.GetAddress_unchecked(&cursor); // void *cache;
+ m_vtable_ptr = extractor.GetAddress_unchecked(&cursor); // IMP *vtable;
+ lldb::addr_t data_NEVER_USE =
+ extractor.GetAddress_unchecked(&cursor); // uintptr_t data_NEVER_USE;
+
+ m_flags = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3);
+ m_data_ptr = data_NEVER_USE & GetClassDataMask(process);
+
+ return true;
}
-bool
-ClassDescriptorV2::Read_class_row (Process* process, const objc_class_t &objc_class, std::unique_ptr<class_ro_t> &class_ro, std::unique_ptr<class_rw_t> &class_rw) const
-{
- class_ro.reset();
- class_rw.reset();
-
- Error error;
- uint32_t class_row_t_flags = process->ReadUnsignedIntegerFromMemory(objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
- if (!error.Success())
- return false;
-
- if (class_row_t_flags & RW_REALIZED)
- {
- class_rw.reset(new class_rw_t);
-
- if (!class_rw->Read(process, objc_class.m_data_ptr))
- {
- class_rw.reset();
- return false;
- }
-
- class_ro.reset(new class_ro_t);
-
- if (!class_ro->Read(process, class_rw->m_ro_ptr))
- {
- class_rw.reset();
- class_ro.reset();
- return false;
- }
- }
- else
- {
- class_ro.reset(new class_ro_t);
-
- if (!class_ro->Read(process, objc_class.m_data_ptr))
- {
- class_ro.reset();
- return false;
- }
- }
-
- return true;
+bool ClassDescriptorV2::class_rw_t::Read(Process *process, lldb::addr_t addr) {
+ size_t ptr_size = process->GetAddressByteSize();
+
+ size_t size = sizeof(uint32_t) // uint32_t flags;
+ + sizeof(uint32_t) // uint32_t version;
+ + ptr_size // const class_ro_t *ro;
+ + ptr_size // union { method_list_t **method_lists;
+ // method_list_t *method_list; };
+ + ptr_size // struct chained_property_list *properties;
+ + ptr_size // const protocol_list_t **protocols;
+ + ptr_size // Class firstSubclass;
+ + ptr_size; // Class nextSiblingClass;
+
+ DataBufferHeap buffer(size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_flags = extractor.GetU32_unchecked(&cursor);
+ m_version = extractor.GetU32_unchecked(&cursor);
+ m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_firstSubclass = extractor.GetAddress_unchecked(&cursor);
+ m_nextSiblingClass = extractor.GetAddress_unchecked(&cursor);
+
+ return true;
}
-bool
-ClassDescriptorV2::method_list_t::Read(Process *process, lldb::addr_t addr)
-{
- size_t size = sizeof(uint32_t) // uint32_t entsize_NEVER_USE;
- + sizeof(uint32_t); // uint32_t count;
-
- DataBufferHeap buffer (size, '\0');
- Error error;
-
- process->ReadMemory(addr, buffer.GetBytes(), size, error);
- if (error.Fail())
- {
- return false;
- }
-
- DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
-
- lldb::offset_t cursor = 0;
-
- m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
- m_count = extractor.GetU32_unchecked(&cursor);
- m_first_ptr = addr + cursor;
-
- return true;
+bool ClassDescriptorV2::class_ro_t::Read(Process *process, lldb::addr_t addr) {
+ size_t ptr_size = process->GetAddressByteSize();
+
+ size_t size = sizeof(uint32_t) // uint32_t flags;
+ + sizeof(uint32_t) // uint32_t instanceStart;
+ + sizeof(uint32_t) // uint32_t instanceSize;
+ + (ptr_size == 8 ? sizeof(uint32_t)
+ : 0) // uint32_t reserved; // __LP64__ only
+ + ptr_size // const uint8_t *ivarLayout;
+ + ptr_size // const char *name;
+ + ptr_size // const method_list_t *baseMethods;
+ + ptr_size // const protocol_list_t *baseProtocols;
+ + ptr_size // const ivar_list_t *ivars;
+ + ptr_size // const uint8_t *weakIvarLayout;
+ + ptr_size; // const property_list_t *baseProperties;
+
+ DataBufferHeap buffer(size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_flags = extractor.GetU32_unchecked(&cursor);
+ m_instanceStart = extractor.GetU32_unchecked(&cursor);
+ m_instanceSize = extractor.GetU32_unchecked(&cursor);
+ if (ptr_size == 8)
+ m_reserved = extractor.GetU32_unchecked(&cursor);
+ else
+ m_reserved = 0;
+ m_ivarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_name_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_baseMethods_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_baseProtocols_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_ivars_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_weakIvarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_baseProperties_ptr = extractor.GetAddress_unchecked(&cursor);
+
+ DataBufferHeap name_buf(1024, '\0');
+
+ process->ReadCStringFromMemory(m_name_ptr, (char *)name_buf.GetBytes(),
+ name_buf.GetByteSize(), error);
+
+ if (error.Fail()) {
+ return false;
+ }
+
+ m_name.assign((char *)name_buf.GetBytes());
+
+ return true;
}
-bool
-ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr)
-{
- size_t size = GetSize(process);
-
- DataBufferHeap buffer (size, '\0');
- Error error;
-
- process->ReadMemory(addr, buffer.GetBytes(), size, error);
- if (error.Fail())
- {
- return false;
+bool ClassDescriptorV2::Read_class_row(
+ Process *process, const objc_class_t &objc_class,
+ std::unique_ptr<class_ro_t> &class_ro,
+ std::unique_ptr<class_rw_t> &class_rw) const {
+ class_ro.reset();
+ class_rw.reset();
+
+ Error error;
+ uint32_t class_row_t_flags = process->ReadUnsignedIntegerFromMemory(
+ objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
+ if (!error.Success())
+ return false;
+
+ if (class_row_t_flags & RW_REALIZED) {
+ class_rw.reset(new class_rw_t);
+
+ if (!class_rw->Read(process, objc_class.m_data_ptr)) {
+ class_rw.reset();
+ return false;
}
-
- DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
-
- lldb::offset_t cursor = 0;
-
- m_name_ptr = extractor.GetAddress_unchecked(&cursor);
- m_types_ptr = extractor.GetAddress_unchecked(&cursor);
- m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
-
- process->ReadCStringFromMemory(m_name_ptr, m_name, error);
- if (error.Fail())
- {
- return false;
+
+ class_ro.reset(new class_ro_t);
+
+ if (!class_ro->Read(process, class_rw->m_ro_ptr)) {
+ class_rw.reset();
+ class_ro.reset();
+ return false;
}
-
- process->ReadCStringFromMemory(m_types_ptr, m_types, error);
- if (error.Fail())
- {
- return false;
+ } else {
+ class_ro.reset(new class_ro_t);
+
+ if (!class_ro->Read(process, objc_class.m_data_ptr)) {
+ class_ro.reset();
+ return false;
}
-
- return true;
+ }
+
+ return true;
}
-bool
-ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr)
-{
- size_t size = sizeof(uint32_t) // uint32_t entsize;
- + sizeof(uint32_t); // uint32_t count;
-
- DataBufferHeap buffer (size, '\0');
- Error error;
-
- process->ReadMemory(addr, buffer.GetBytes(), size, error);
- if (error.Fail())
- {
- return false;
- }
-
- DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
-
- lldb::offset_t cursor = 0;
-
- m_entsize = extractor.GetU32_unchecked(&cursor);
- m_count = extractor.GetU32_unchecked(&cursor);
- m_first_ptr = addr + cursor;
-
- return true;
+bool ClassDescriptorV2::method_list_t::Read(Process *process,
+ lldb::addr_t addr) {
+ size_t size = sizeof(uint32_t) // uint32_t entsize_NEVER_USE;
+ + sizeof(uint32_t); // uint32_t count;
+
+ DataBufferHeap buffer(size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
+ m_count = extractor.GetU32_unchecked(&cursor);
+ m_first_ptr = addr + cursor;
+
+ return true;
}
-bool
-ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr)
-{
- size_t size = GetSize(process);
-
- DataBufferHeap buffer (size, '\0');
- Error error;
-
- process->ReadMemory(addr, buffer.GetBytes(), size, error);
- if (error.Fail())
- {
- return false;
+bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) {
+ size_t size = GetSize(process);
+
+ DataBufferHeap buffer(size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_name_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_types_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
+
+ process->ReadCStringFromMemory(m_name_ptr, m_name, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ process->ReadCStringFromMemory(m_types_ptr, m_types, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ return true;
+}
+
+bool ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr) {
+ size_t size = sizeof(uint32_t) // uint32_t entsize;
+ + sizeof(uint32_t); // uint32_t count;
+
+ DataBufferHeap buffer(size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_entsize = extractor.GetU32_unchecked(&cursor);
+ m_count = extractor.GetU32_unchecked(&cursor);
+ m_first_ptr = addr + cursor;
+
+ return true;
+}
+
+bool ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr) {
+ size_t size = GetSize(process);
+
+ DataBufferHeap buffer(size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
+ process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_name_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_type_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_alignment = extractor.GetU32_unchecked(&cursor);
+ m_size = extractor.GetU32_unchecked(&cursor);
+
+ process->ReadCStringFromMemory(m_name_ptr, m_name, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ process->ReadCStringFromMemory(m_type_ptr, m_type, error);
+ if (error.Fail()) {
+ return false;
+ }
+
+ return true;
+}
+
+bool ClassDescriptorV2::Describe(
+ std::function<void(ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+ std::function<bool(const char *, const char *)> const &instance_method_func,
+ std::function<bool(const char *, const char *)> const &class_method_func,
+ std::function<bool(const char *, const char *, lldb::addr_t,
+ uint64_t)> const &ivar_func) const {
+ lldb_private::Process *process = m_runtime.GetProcess();
+
+ std::unique_ptr<objc_class_t> objc_class;
+ std::unique_ptr<class_ro_t> class_ro;
+ std::unique_ptr<class_rw_t> class_rw;
+
+ if (!Read_objc_class(process, objc_class))
+ return 0;
+ if (!Read_class_row(process, *objc_class, class_ro, class_rw))
+ return 0;
+
+ static ConstString NSObject_name("NSObject");
+
+ if (m_name != NSObject_name && superclass_func)
+ superclass_func(objc_class->m_superclass);
+
+ if (instance_method_func) {
+ std::unique_ptr<method_list_t> base_method_list;
+
+ base_method_list.reset(new method_list_t);
+ if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
+ return false;
+
+ if (base_method_list->m_entsize != method_t::GetSize(process))
+ return false;
+
+ std::unique_ptr<method_t> method;
+ method.reset(new method_t);
+
+ for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) {
+ method->Read(process, base_method_list->m_first_ptr +
+ (i * base_method_list->m_entsize));
+
+ if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
+ break;
}
-
- DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
-
- lldb::offset_t cursor = 0;
-
- m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
- m_name_ptr = extractor.GetAddress_unchecked(&cursor);
- m_type_ptr = extractor.GetAddress_unchecked(&cursor);
- m_alignment = extractor.GetU32_unchecked(&cursor);
- m_size = extractor.GetU32_unchecked(&cursor);
-
- process->ReadCStringFromMemory(m_name_ptr, m_name, error);
- if (error.Fail())
- {
- return false;
+ }
+
+ if (class_method_func) {
+ AppleObjCRuntime::ClassDescriptorSP metaclass(GetMetaclass());
+
+ // We don't care about the metaclass's superclass, or its class methods.
+ // Its instance methods are
+ // our class methods.
+
+ if (metaclass) {
+ metaclass->Describe(
+ std::function<void(ObjCLanguageRuntime::ObjCISA)>(nullptr),
+ class_method_func,
+ std::function<bool(const char *, const char *)>(nullptr),
+ std::function<bool(const char *, const char *, lldb::addr_t,
+ uint64_t)>(nullptr));
}
-
- process->ReadCStringFromMemory(m_type_ptr, m_type, error);
- if (error.Fail())
- {
+ }
+
+ if (ivar_func) {
+ if (class_ro->m_ivars_ptr != 0) {
+ ivar_list_t ivar_list;
+ if (!ivar_list.Read(process, class_ro->m_ivars_ptr))
+ return false;
+
+ if (ivar_list.m_entsize != ivar_t::GetSize(process))
return false;
+
+ ivar_t ivar;
+
+ for (uint32_t i = 0, e = ivar_list.m_count; i < e; ++i) {
+ ivar.Read(process, ivar_list.m_first_ptr + (i * ivar_list.m_entsize));
+
+ if (ivar_func(ivar.m_name.c_str(), ivar.m_type.c_str(),
+ ivar.m_offset_ptr, ivar.m_size))
+ break;
+ }
}
-
- return true;
+ }
+
+ return true;
}
-bool
-ClassDescriptorV2::Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
- std::function <bool (const char *, const char *)> const &instance_method_func,
- std::function <bool (const char *, const char *)> const &class_method_func,
- std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) const
-{
+ConstString ClassDescriptorV2::GetClassName() {
+ if (!m_name) {
lldb_private::Process *process = m_runtime.GetProcess();
-
- std::unique_ptr<objc_class_t> objc_class;
- std::unique_ptr<class_ro_t> class_ro;
- std::unique_ptr<class_rw_t> class_rw;
-
- if (!Read_objc_class(process, objc_class))
- return 0;
- if (!Read_class_row(process, *objc_class, class_ro, class_rw))
- return 0;
-
- static ConstString NSObject_name("NSObject");
-
- if (m_name != NSObject_name && superclass_func)
- superclass_func(objc_class->m_superclass);
-
- if (instance_method_func)
- {
- std::unique_ptr<method_list_t> base_method_list;
-
- base_method_list.reset(new method_list_t);
- if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
- return false;
-
- if (base_method_list->m_entsize != method_t::GetSize(process))
- return false;
-
- std::unique_ptr<method_t> method;
- method.reset(new method_t);
-
- for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
- {
- method->Read(process, base_method_list->m_first_ptr + (i * base_method_list->m_entsize));
-
- if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
- break;
- }
- }
-
- if (class_method_func)
- {
- AppleObjCRuntime::ClassDescriptorSP metaclass(GetMetaclass());
-
- // We don't care about the metaclass's superclass, or its class methods. Its instance methods are
- // our class methods.
-
- if (metaclass) {
- metaclass->Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> (nullptr),
- class_method_func,
- std::function <bool (const char *, const char *)> (nullptr),
- std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> (nullptr));
- }
- }
-
- if (ivar_func)
- {
- if (class_ro->m_ivars_ptr != 0)
- {
- ivar_list_t ivar_list;
- if (!ivar_list.Read(process, class_ro->m_ivars_ptr))
- return false;
-
- if (ivar_list.m_entsize != ivar_t::GetSize(process))
- return false;
-
- ivar_t ivar;
-
- for (uint32_t i = 0, e = ivar_list.m_count; i < e; ++i)
- {
- ivar.Read(process, ivar_list.m_first_ptr + (i * ivar_list.m_entsize));
-
- if (ivar_func(ivar.m_name.c_str(), ivar.m_type.c_str(), ivar.m_offset_ptr, ivar.m_size))
- break;
- }
- }
+
+ if (process) {
+ std::unique_ptr<objc_class_t> objc_class;
+ std::unique_ptr<class_ro_t> class_ro;
+ std::unique_ptr<class_rw_t> class_rw;
+
+ if (!Read_objc_class(process, objc_class))
+ return m_name;
+ if (!Read_class_row(process, *objc_class, class_ro, class_rw))
+ return m_name;
+
+ m_name = ConstString(class_ro->m_name.c_str());
}
-
- return true;
+ }
+ return m_name;
}
-ConstString
-ClassDescriptorV2::GetClassName ()
-{
- if (!m_name)
- {
- lldb_private::Process *process = m_runtime.GetProcess();
-
- if (process)
- {
- std::unique_ptr<objc_class_t> objc_class;
- std::unique_ptr<class_ro_t> class_ro;
- std::unique_ptr<class_rw_t> class_rw;
-
- if (!Read_objc_class(process, objc_class))
- return m_name;
- if (!Read_class_row(process, *objc_class, class_ro, class_rw))
- return m_name;
-
- m_name = ConstString(class_ro->m_name.c_str());
- }
- }
- return m_name;
+ObjCLanguageRuntime::ClassDescriptorSP ClassDescriptorV2::GetSuperclass() {
+ lldb_private::Process *process = m_runtime.GetProcess();
+
+ if (!process)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ std::unique_ptr<objc_class_t> objc_class;
+
+ if (!Read_objc_class(process, objc_class))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ return m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(
+ objc_class->m_superclass);
}
-ObjCLanguageRuntime::ClassDescriptorSP
-ClassDescriptorV2::GetSuperclass ()
-{
- lldb_private::Process *process = m_runtime.GetProcess();
-
- if (!process)
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
- std::unique_ptr<objc_class_t> objc_class;
-
- if (!Read_objc_class(process, objc_class))
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
- return m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(objc_class->m_superclass);
+ObjCLanguageRuntime::ClassDescriptorSP ClassDescriptorV2::GetMetaclass() const {
+ lldb_private::Process *process = m_runtime.GetProcess();
+
+ if (!process)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ std::unique_ptr<objc_class_t> objc_class;
+
+ if (!Read_objc_class(process, objc_class))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ lldb::addr_t candidate_isa = m_runtime.GetPointerISA(objc_class->m_isa);
+
+ return ObjCLanguageRuntime::ClassDescriptorSP(
+ new ClassDescriptorV2(m_runtime, candidate_isa, nullptr));
}
-ObjCLanguageRuntime::ClassDescriptorSP
-ClassDescriptorV2::GetMetaclass () const
-{
- lldb_private::Process *process = m_runtime.GetProcess();
-
- if (!process)
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
+uint64_t ClassDescriptorV2::GetInstanceSize() {
+ lldb_private::Process *process = m_runtime.GetProcess();
+
+ if (process) {
std::unique_ptr<objc_class_t> objc_class;
-
+ std::unique_ptr<class_ro_t> class_ro;
+ std::unique_ptr<class_rw_t> class_rw;
+
if (!Read_objc_class(process, objc_class))
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
- lldb::addr_t candidate_isa = m_runtime.GetPointerISA(objc_class->m_isa);
-
- return ObjCLanguageRuntime::ClassDescriptorSP(new ClassDescriptorV2(m_runtime, candidate_isa, nullptr));
-}
+ return 0;
+ if (!Read_class_row(process, *objc_class, class_ro, class_rw))
+ return 0;
-uint64_t
-ClassDescriptorV2::GetInstanceSize ()
-{
- lldb_private::Process *process = m_runtime.GetProcess();
-
- if (process)
- {
- std::unique_ptr<objc_class_t> objc_class;
- std::unique_ptr<class_ro_t> class_ro;
- std::unique_ptr<class_rw_t> class_rw;
-
- if (!Read_objc_class(process, objc_class))
- return 0;
- if (!Read_class_row(process, *objc_class, class_ro, class_rw))
- return 0;
-
- return class_ro->m_instanceSize;
- }
-
- return 0;
-}
+ return class_ro->m_instanceSize;
+ }
-ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_filled(false), m_ivars(), m_mutex()
-{
+ return 0;
}
-size_t
-ClassDescriptorV2::iVarsStorage::size ()
-{
- return m_ivars.size();
-}
+ClassDescriptorV2::iVarsStorage::iVarsStorage()
+ : m_filled(false), m_ivars(), m_mutex() {}
-ClassDescriptorV2::iVarDescriptor&
-ClassDescriptorV2::iVarsStorage::operator[] (size_t idx)
-{
- return m_ivars[idx];
+size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); }
+
+ClassDescriptorV2::iVarDescriptor &ClassDescriptorV2::iVarsStorage::
+operator[](size_t idx) {
+ return m_ivars[idx];
}
-void
-ClassDescriptorV2::iVarsStorage::fill (AppleObjCRuntimeV2& runtime, ClassDescriptorV2& descriptor)
-{
- if (m_filled)
- return;
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES | LIBLLDB_LOG_VERBOSE));
+void ClassDescriptorV2::iVarsStorage::fill(AppleObjCRuntimeV2 &runtime,
+ ClassDescriptorV2 &descriptor) {
+ if (m_filled)
+ return;
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES | LIBLLDB_LOG_VERBOSE));
+ if (log)
+ log->Printf("[ClassDescriptorV2::iVarsStorage::fill] class_name = %s",
+ descriptor.GetClassName().AsCString("<unknown"));
+ m_filled = true;
+ ObjCLanguageRuntime::EncodingToTypeSP encoding_to_type_sp(
+ runtime.GetEncodingToType());
+ Process *process(runtime.GetProcess());
+ if (!encoding_to_type_sp)
+ return;
+ descriptor.Describe(nullptr, nullptr, nullptr, [this, process,
+ encoding_to_type_sp,
+ log](const char *name,
+ const char *type,
+ lldb::addr_t offset_ptr,
+ uint64_t size) -> bool {
+ const bool for_expression = false;
+ const bool stop_loop = false;
if (log)
- log->Printf("[ClassDescriptorV2::iVarsStorage::fill] class_name = %s", descriptor.GetClassName().AsCString("<unknown"));
- m_filled = true;
- ObjCLanguageRuntime::EncodingToTypeSP encoding_to_type_sp(runtime.GetEncodingToType());
- Process* process(runtime.GetProcess());
- if (!encoding_to_type_sp)
- return;
- descriptor.Describe(nullptr,
- nullptr,
- nullptr,
- [this,process,encoding_to_type_sp,log](const char * name, const char * type, lldb::addr_t offset_ptr, uint64_t size) -> bool {
- const bool for_expression = false;
- const bool stop_loop = false;
- if (log)
- log->Printf("[ClassDescriptorV2::iVarsStorage::fill] name = %s, encoding = %s, offset_ptr = %" PRIx64 ", size = %" PRIu64,
- name,type,offset_ptr,size);
- CompilerType ivar_type = encoding_to_type_sp->RealizeType(type, for_expression);
- if (ivar_type)
- {
- if (log)
- log->Printf("[ClassDescriptorV2::iVarsStorage::fill] name = %s, encoding = %s, offset_ptr = %" PRIx64 ", size = %" PRIu64 " , type_size = %" PRIu64,
- name,type,offset_ptr,size,ivar_type.GetByteSize(nullptr));
- Scalar offset_scalar;
- Error error;
- const int offset_ptr_size = 4;
- const bool is_signed = false;
- size_t read = process->ReadScalarIntegerFromMemory(offset_ptr, offset_ptr_size, is_signed, offset_scalar, error);
- if (error.Success() && 4 == read)
- {
- if (log)
- log->Printf("[ClassDescriptorV2::iVarsStorage::fill] offset_ptr = %" PRIx64 " --> %" PRIu32,
- offset_ptr, offset_scalar.SInt());
- m_ivars.push_back({ ConstString(name), ivar_type, size, offset_scalar.SInt() });
- }
- else if (log)
- log->Printf("[ClassDescriptorV2::iVarsStorage::fill] offset_ptr = %" PRIx64 " --> read fail, read = %zu",
- offset_ptr, read);
- }
- return stop_loop;
- });
+ log->Printf("[ClassDescriptorV2::iVarsStorage::fill] name = %s, encoding "
+ "= %s, offset_ptr = %" PRIx64 ", size = %" PRIu64,
+ name, type, offset_ptr, size);
+ CompilerType ivar_type =
+ encoding_to_type_sp->RealizeType(type, for_expression);
+ if (ivar_type) {
+ if (log)
+ log->Printf("[ClassDescriptorV2::iVarsStorage::fill] name = %s, "
+ "encoding = %s, offset_ptr = %" PRIx64 ", size = %" PRIu64
+ " , type_size = %" PRIu64,
+ name, type, offset_ptr, size,
+ ivar_type.GetByteSize(nullptr));
+ Scalar offset_scalar;
+ Error error;
+ const int offset_ptr_size = 4;
+ const bool is_signed = false;
+ size_t read = process->ReadScalarIntegerFromMemory(
+ offset_ptr, offset_ptr_size, is_signed, offset_scalar, error);
+ if (error.Success() && 4 == read) {
+ if (log)
+ log->Printf(
+ "[ClassDescriptorV2::iVarsStorage::fill] offset_ptr = %" PRIx64
+ " --> %" PRIu32,
+ offset_ptr, offset_scalar.SInt());
+ m_ivars.push_back(
+ {ConstString(name), ivar_type, size, offset_scalar.SInt()});
+ } else if (log)
+ log->Printf(
+ "[ClassDescriptorV2::iVarsStorage::fill] offset_ptr = %" PRIx64
+ " --> read fail, read = %zu",
+ offset_ptr, read);
+ }
+ return stop_loop;
+ });
}
-void
-ClassDescriptorV2::GetIVarInformation ()
-{
- m_ivars_storage.fill(m_runtime, *this);
+void ClassDescriptorV2::GetIVarInformation() {
+ m_ivars_storage.fill(m_runtime, *this);
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index f5fc8bc0644b..787423b54766 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -16,397 +16,320 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "AppleObjCRuntimeV2.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
-{
+class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor {
public:
- friend class lldb_private::AppleObjCRuntimeV2;
-
- ~ClassDescriptorV2() override = default;
-
- ConstString
- GetClassName() override;
-
- ObjCLanguageRuntime::ClassDescriptorSP
- GetSuperclass() override;
-
- ObjCLanguageRuntime::ClassDescriptorSP
- GetMetaclass() const override;
-
- bool
- IsValid() override
- {
- return true; // any Objective-C v2 runtime class descriptor we vend is valid
- }
-
- // a custom descriptor is used for tagged pointers
- bool
- GetTaggedPointerInfo(uint64_t* info_bits = nullptr,
- uint64_t* value_bits = nullptr,
- uint64_t* payload = nullptr) override
- {
- return false;
- }
-
- uint64_t
- GetInstanceSize() override;
-
- ObjCLanguageRuntime::ObjCISA
- GetISA() override
- {
- return m_objc_class_ptr;
- }
-
- bool
- Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
- std::function <bool (const char *, const char *)> const &instance_method_func,
- std::function <bool (const char *, const char *)> const &class_method_func,
- std::function <bool (const char *, const char *,
- lldb::addr_t, uint64_t)> const &ivar_func) const override;
-
- size_t
- GetNumIVars() override
- {
- GetIVarInformation();
- return m_ivars_storage.size();
- }
-
- iVarDescriptor
- GetIVarAtIndex(size_t idx) override
- {
- if (idx >= GetNumIVars())
- return iVarDescriptor();
- return m_ivars_storage[idx];
- }
-
+ friend class lldb_private::AppleObjCRuntimeV2;
+
+ ~ClassDescriptorV2() override = default;
+
+ ConstString GetClassName() override;
+
+ ObjCLanguageRuntime::ClassDescriptorSP GetSuperclass() override;
+
+ ObjCLanguageRuntime::ClassDescriptorSP GetMetaclass() const override;
+
+ bool IsValid() override {
+ return true; // any Objective-C v2 runtime class descriptor we vend is valid
+ }
+
+ // a custom descriptor is used for tagged pointers
+ bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
+ uint64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) override {
+ return false;
+ }
+
+ uint64_t GetInstanceSize() override;
+
+ ObjCLanguageRuntime::ObjCISA GetISA() override { return m_objc_class_ptr; }
+
+ bool Describe(
+ std::function<void(ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+ std::function<bool(const char *, const char *)> const
+ &instance_method_func,
+ std::function<bool(const char *, const char *)> const &class_method_func,
+ std::function<bool(const char *, const char *, lldb::addr_t,
+ uint64_t)> const &ivar_func) const override;
+
+ size_t GetNumIVars() override {
+ GetIVarInformation();
+ return m_ivars_storage.size();
+ }
+
+ iVarDescriptor GetIVarAtIndex(size_t idx) override {
+ if (idx >= GetNumIVars())
+ return iVarDescriptor();
+ return m_ivars_storage[idx];
+ }
+
protected:
- void
- GetIVarInformation ();
-
+ void GetIVarInformation();
+
private:
- static const uint32_t RW_REALIZED = (1 << 31);
-
- struct objc_class_t {
- ObjCLanguageRuntime::ObjCISA m_isa; // The class's metaclass.
- ObjCLanguageRuntime::ObjCISA m_superclass;
- lldb::addr_t m_cache_ptr;
- lldb::addr_t m_vtable_ptr;
- lldb::addr_t m_data_ptr;
- uint8_t m_flags;
-
- objc_class_t () :
- m_isa (0),
- m_superclass (0),
- m_cache_ptr (0),
- m_vtable_ptr (0),
- m_data_ptr (0),
- m_flags (0)
- {
- }
-
- void
- Clear()
- {
- m_isa = 0;
- m_superclass = 0;
- m_cache_ptr = 0;
- m_vtable_ptr = 0;
- m_data_ptr = 0;
- m_flags = 0;
- }
-
- bool
- Read(Process *process, lldb::addr_t addr);
- };
-
- struct class_ro_t {
- uint32_t m_flags;
- uint32_t m_instanceStart;
- uint32_t m_instanceSize;
- uint32_t m_reserved;
-
- lldb::addr_t m_ivarLayout_ptr;
- lldb::addr_t m_name_ptr;
- lldb::addr_t m_baseMethods_ptr;
- lldb::addr_t m_baseProtocols_ptr;
- lldb::addr_t m_ivars_ptr;
-
- lldb::addr_t m_weakIvarLayout_ptr;
- lldb::addr_t m_baseProperties_ptr;
-
- std::string m_name;
-
- bool
- Read(Process *process, lldb::addr_t addr);
- };
-
- struct class_rw_t {
- uint32_t m_flags;
- uint32_t m_version;
-
- lldb::addr_t m_ro_ptr;
- union {
- lldb::addr_t m_method_list_ptr;
- lldb::addr_t m_method_lists_ptr;
- };
- lldb::addr_t m_properties_ptr;
- lldb::addr_t m_protocols_ptr;
-
- ObjCLanguageRuntime::ObjCISA m_firstSubclass;
- ObjCLanguageRuntime::ObjCISA m_nextSiblingClass;
-
- bool
- Read(Process *process, lldb::addr_t addr);
- };
-
- struct method_list_t
- {
- uint32_t m_entsize;
- uint32_t m_count;
- lldb::addr_t m_first_ptr;
-
- bool
- Read(Process *process, lldb::addr_t addr);
- };
-
- struct method_t
- {
- lldb::addr_t m_name_ptr;
- lldb::addr_t m_types_ptr;
- lldb::addr_t m_imp_ptr;
-
- std::string m_name;
- std::string m_types;
-
- static size_t GetSize(Process *process)
- {
- size_t ptr_size = process->GetAddressByteSize();
-
- return ptr_size // SEL name;
- + ptr_size // const char *types;
- + ptr_size; // IMP imp;
- }
-
- bool
- Read(Process *process, lldb::addr_t addr);
- };
-
- struct ivar_list_t
- {
- uint32_t m_entsize;
- uint32_t m_count;
- lldb::addr_t m_first_ptr;
-
- bool Read(Process *process, lldb::addr_t addr);
- };
-
- struct ivar_t
- {
- lldb::addr_t m_offset_ptr;
- lldb::addr_t m_name_ptr;
- lldb::addr_t m_type_ptr;
- uint32_t m_alignment;
- uint32_t m_size;
-
- std::string m_name;
- std::string m_type;
-
- static size_t GetSize(Process *process)
- {
- size_t ptr_size = process->GetAddressByteSize();
-
- return ptr_size // uintptr_t *offset;
- + ptr_size // const char *name;
- + ptr_size // const char *type;
- + sizeof(uint32_t) // uint32_t alignment;
- + sizeof(uint32_t); // uint32_t size;
- }
-
- bool
- Read(Process *process, lldb::addr_t addr);
- };
-
- class iVarsStorage
- {
- public:
- iVarsStorage ();
-
- size_t
- size ();
-
- iVarDescriptor&
- operator[] (size_t idx);
-
- void
- fill (AppleObjCRuntimeV2& runtime, ClassDescriptorV2& descriptor);
-
- private:
- bool m_filled;
- std::vector<iVarDescriptor> m_ivars;
- std::recursive_mutex m_mutex;
+ static const uint32_t RW_REALIZED = (1 << 31);
+
+ struct objc_class_t {
+ ObjCLanguageRuntime::ObjCISA m_isa; // The class's metaclass.
+ ObjCLanguageRuntime::ObjCISA m_superclass;
+ lldb::addr_t m_cache_ptr;
+ lldb::addr_t m_vtable_ptr;
+ lldb::addr_t m_data_ptr;
+ uint8_t m_flags;
+
+ objc_class_t()
+ : m_isa(0), m_superclass(0), m_cache_ptr(0), m_vtable_ptr(0),
+ m_data_ptr(0), m_flags(0) {}
+
+ void Clear() {
+ m_isa = 0;
+ m_superclass = 0;
+ m_cache_ptr = 0;
+ m_vtable_ptr = 0;
+ m_data_ptr = 0;
+ m_flags = 0;
+ }
+
+ bool Read(Process *process, lldb::addr_t addr);
+ };
+
+ struct class_ro_t {
+ uint32_t m_flags;
+ uint32_t m_instanceStart;
+ uint32_t m_instanceSize;
+ uint32_t m_reserved;
+
+ lldb::addr_t m_ivarLayout_ptr;
+ lldb::addr_t m_name_ptr;
+ lldb::addr_t m_baseMethods_ptr;
+ lldb::addr_t m_baseProtocols_ptr;
+ lldb::addr_t m_ivars_ptr;
+
+ lldb::addr_t m_weakIvarLayout_ptr;
+ lldb::addr_t m_baseProperties_ptr;
+
+ std::string m_name;
+
+ bool Read(Process *process, lldb::addr_t addr);
+ };
+
+ struct class_rw_t {
+ uint32_t m_flags;
+ uint32_t m_version;
+
+ lldb::addr_t m_ro_ptr;
+ union {
+ lldb::addr_t m_method_list_ptr;
+ lldb::addr_t m_method_lists_ptr;
};
-
- // The constructor should only be invoked by the runtime as it builds its caches
- // or populates them. A ClassDescriptorV2 should only ever exist in a cache.
- ClassDescriptorV2(AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa, const char *name) :
- m_runtime (runtime),
- m_objc_class_ptr (isa),
- m_name (name),
- m_ivars_storage()
- {
+ lldb::addr_t m_properties_ptr;
+ lldb::addr_t m_protocols_ptr;
+
+ ObjCLanguageRuntime::ObjCISA m_firstSubclass;
+ ObjCLanguageRuntime::ObjCISA m_nextSiblingClass;
+
+ bool Read(Process *process, lldb::addr_t addr);
+ };
+
+ struct method_list_t {
+ uint32_t m_entsize;
+ uint32_t m_count;
+ lldb::addr_t m_first_ptr;
+
+ bool Read(Process *process, lldb::addr_t addr);
+ };
+
+ struct method_t {
+ lldb::addr_t m_name_ptr;
+ lldb::addr_t m_types_ptr;
+ lldb::addr_t m_imp_ptr;
+
+ std::string m_name;
+ std::string m_types;
+
+ static size_t GetSize(Process *process) {
+ size_t ptr_size = process->GetAddressByteSize();
+
+ return ptr_size // SEL name;
+ + ptr_size // const char *types;
+ + ptr_size; // IMP imp;
+ }
+
+ bool Read(Process *process, lldb::addr_t addr);
+ };
+
+ struct ivar_list_t {
+ uint32_t m_entsize;
+ uint32_t m_count;
+ lldb::addr_t m_first_ptr;
+
+ bool Read(Process *process, lldb::addr_t addr);
+ };
+
+ struct ivar_t {
+ lldb::addr_t m_offset_ptr;
+ lldb::addr_t m_name_ptr;
+ lldb::addr_t m_type_ptr;
+ uint32_t m_alignment;
+ uint32_t m_size;
+
+ std::string m_name;
+ std::string m_type;
+
+ static size_t GetSize(Process *process) {
+ size_t ptr_size = process->GetAddressByteSize();
+
+ return ptr_size // uintptr_t *offset;
+ + ptr_size // const char *name;
+ + ptr_size // const char *type;
+ + sizeof(uint32_t) // uint32_t alignment;
+ + sizeof(uint32_t); // uint32_t size;
}
-
- bool
- Read_objc_class (Process* process, std::unique_ptr<objc_class_t> &objc_class) const;
-
- bool
- Read_class_row (Process* process, const objc_class_t &objc_class, std::unique_ptr<class_ro_t> &class_ro, std::unique_ptr<class_rw_t> &class_rw) const;
-
- AppleObjCRuntimeV2 &m_runtime; // The runtime, so we can read information lazily.
- lldb::addr_t m_objc_class_ptr; // The address of the objc_class_t. (I.e., objects of this class type have this as their ISA)
- ConstString m_name; // May be NULL
- iVarsStorage m_ivars_storage;
+
+ bool Read(Process *process, lldb::addr_t addr);
+ };
+
+ class iVarsStorage {
+ public:
+ iVarsStorage();
+
+ size_t size();
+
+ iVarDescriptor &operator[](size_t idx);
+
+ void fill(AppleObjCRuntimeV2 &runtime, ClassDescriptorV2 &descriptor);
+
+ private:
+ bool m_filled;
+ std::vector<iVarDescriptor> m_ivars;
+ std::recursive_mutex m_mutex;
+ };
+
+ // The constructor should only be invoked by the runtime as it builds its
+ // caches
+ // or populates them. A ClassDescriptorV2 should only ever exist in a cache.
+ ClassDescriptorV2(AppleObjCRuntimeV2 &runtime,
+ ObjCLanguageRuntime::ObjCISA isa, const char *name)
+ : m_runtime(runtime), m_objc_class_ptr(isa), m_name(name),
+ m_ivars_storage() {}
+
+ bool Read_objc_class(Process *process,
+ std::unique_ptr<objc_class_t> &objc_class) const;
+
+ bool Read_class_row(Process *process, const objc_class_t &objc_class,
+ std::unique_ptr<class_ro_t> &class_ro,
+ std::unique_ptr<class_rw_t> &class_rw) const;
+
+ AppleObjCRuntimeV2
+ &m_runtime; // The runtime, so we can read information lazily.
+ lldb::addr_t m_objc_class_ptr; // The address of the objc_class_t. (I.e.,
+ // objects of this class type have this as
+ // their ISA)
+ ConstString m_name; // May be NULL
+ iVarsStorage m_ivars_storage;
};
// tagged pointer descriptor
-class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor
-{
+class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor {
public:
- ClassDescriptorV2Tagged (ConstString class_name,
- uint64_t payload)
- {
- m_name = class_name;
- if (!m_name)
- {
- m_valid = false;
- return;
- }
- m_valid = true;
- m_payload = payload;
- m_info_bits = (m_payload & 0xF0ULL) >> 4;
- m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8;
+ ClassDescriptorV2Tagged(ConstString class_name, uint64_t payload) {
+ m_name = class_name;
+ if (!m_name) {
+ m_valid = false;
+ return;
}
-
- ClassDescriptorV2Tagged (ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp,
- uint64_t payload)
- {
- if (!actual_class_sp)
- {
- m_valid = false;
- return;
- }
- m_name = actual_class_sp->GetClassName();
- if (!m_name)
- {
- m_valid = false;
- return;
- }
- m_valid = true;
- m_payload = payload;
- m_info_bits = (m_payload & 0x0FULL);
- m_value_bits = (m_payload & ~0x0FULL) >> 4;
- }
-
- ~ClassDescriptorV2Tagged() override = default;
+ m_valid = true;
+ m_payload = payload;
+ m_info_bits = (m_payload & 0xF0ULL) >> 4;
+ m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8;
+ }
- ConstString
- GetClassName() override
- {
- return m_name;
- }
-
- ObjCLanguageRuntime::ClassDescriptorSP
- GetSuperclass() override
- {
- // tagged pointers can represent a class that has a superclass, but since that information is not
- // stored in the object itself, we would have to query the runtime to discover the hierarchy
- // for the time being, we skip this step in the interest of static discovery
- return ObjCLanguageRuntime::ClassDescriptorSP();
+ ClassDescriptorV2Tagged(
+ ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp,
+ uint64_t payload) {
+ if (!actual_class_sp) {
+ m_valid = false;
+ return;
}
-
- ObjCLanguageRuntime::ClassDescriptorSP
- GetMetaclass() const override
- {
- return ObjCLanguageRuntime::ClassDescriptorSP();
- }
-
- bool
- IsValid() override
- {
- return m_valid;
- }
-
- bool
- IsKVO() override
- {
- return false; // tagged pointers are not KVO'ed
- }
-
- bool
- IsCFType() override
- {
- return false; // tagged pointers are not CF objects
- }
-
- bool
- GetTaggedPointerInfo(uint64_t* info_bits = nullptr,
- uint64_t* value_bits = nullptr,
- uint64_t* payload = nullptr) override
- {
- if (info_bits)
- *info_bits = GetInfoBits();
- if (value_bits)
- *value_bits = GetValueBits();
- if (payload)
- *payload = GetPayload();
- return true;
- }
-
- uint64_t
- GetInstanceSize() override
- {
- return (IsValid() ? m_pointer_size : 0);
- }
-
- ObjCLanguageRuntime::ObjCISA
- GetISA() override
- {
- return 0; // tagged pointers have no ISA
- }
-
- // these calls are not part of any formal tagged pointers specification
- virtual uint64_t
- GetValueBits ()
- {
- return (IsValid() ? m_value_bits : 0);
- }
-
- virtual uint64_t
- GetInfoBits ()
- {
- return (IsValid() ? m_info_bits : 0);
- }
-
- virtual uint64_t
- GetPayload ()
- {
- return (IsValid() ? m_payload : 0);
+ m_name = actual_class_sp->GetClassName();
+ if (!m_name) {
+ m_valid = false;
+ return;
}
+ m_valid = true;
+ m_payload = payload;
+ m_info_bits = (m_payload & 0x0FULL);
+ m_value_bits = (m_payload & ~0x0FULL) >> 4;
+ }
+
+ ~ClassDescriptorV2Tagged() override = default;
+
+ ConstString GetClassName() override { return m_name; }
+
+ ObjCLanguageRuntime::ClassDescriptorSP GetSuperclass() override {
+ // tagged pointers can represent a class that has a superclass, but since
+ // that information is not
+ // stored in the object itself, we would have to query the runtime to
+ // discover the hierarchy
+ // for the time being, we skip this step in the interest of static discovery
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+ }
+
+ ObjCLanguageRuntime::ClassDescriptorSP GetMetaclass() const override {
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+ }
+
+ bool IsValid() override { return m_valid; }
+
+ bool IsKVO() override {
+ return false; // tagged pointers are not KVO'ed
+ }
+
+ bool IsCFType() override {
+ return false; // tagged pointers are not CF objects
+ }
+
+ bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
+ uint64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) override {
+ if (info_bits)
+ *info_bits = GetInfoBits();
+ if (value_bits)
+ *value_bits = GetValueBits();
+ if (payload)
+ *payload = GetPayload();
+ return true;
+ }
+
+ uint64_t GetInstanceSize() override {
+ return (IsValid() ? m_pointer_size : 0);
+ }
+
+ ObjCLanguageRuntime::ObjCISA GetISA() override {
+ return 0; // tagged pointers have no ISA
+ }
+
+ // these calls are not part of any formal tagged pointers specification
+ virtual uint64_t GetValueBits() { return (IsValid() ? m_value_bits : 0); }
+
+ virtual uint64_t GetInfoBits() { return (IsValid() ? m_info_bits : 0); }
+
+ virtual uint64_t GetPayload() { return (IsValid() ? m_payload : 0); }
private:
- ConstString m_name;
- uint8_t m_pointer_size;
- bool m_valid;
- uint64_t m_info_bits;
- uint64_t m_value_bits;
- uint64_t m_payload;
+ ConstString m_name;
+ uint8_t m_pointer_size;
+ bool m_valid;
+ uint64_t m_info_bits;
+ uint64_t m_value_bits;
+ uint64_t m_payload;
};
-
+
} // namespace lldb_private
#endif // liblldb_AppleObjCClassDescriptorV2_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 0c0e4f1ce8cc..922d192c333c 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -23,659 +23,628 @@
using namespace lldb_private;
-class lldb_private::AppleObjCExternalASTSource : public ClangExternalASTSourceCommon
-{
+class lldb_private::AppleObjCExternalASTSource
+ : public ClangExternalASTSourceCommon {
public:
- AppleObjCExternalASTSource (AppleObjCDeclVendor &decl_vendor) :
- m_decl_vendor(decl_vendor)
- {
- }
+ AppleObjCExternalASTSource(AppleObjCDeclVendor &decl_vendor)
+ : m_decl_vendor(decl_vendor) {}
- bool
- FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName name) override
- {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx,
+ clang::DeclarationName name) override {
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ Log *log(GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
- if (log)
- {
- log->Printf("AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
- current_id,
- static_cast<void*>(&decl_ctx->getParentASTContext()),
- name.getAsString().c_str(), decl_ctx->getDeclKindName(),
- static_cast<const void*>(decl_ctx));
- }
+ if (log) {
+ log->Printf("AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%"
+ "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
+ current_id,
+ static_cast<void *>(&decl_ctx->getParentASTContext()),
+ name.getAsString().c_str(), decl_ctx->getDeclKindName(),
+ static_cast<const void *>(decl_ctx));
+ }
- do
- {
- const clang::ObjCInterfaceDecl *interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
+ do {
+ const clang::ObjCInterfaceDecl *interface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
- if (!interface_decl)
- break;
+ if (!interface_decl)
+ break;
- clang::ObjCInterfaceDecl *non_const_interface_decl = const_cast<clang::ObjCInterfaceDecl*>(interface_decl);
+ clang::ObjCInterfaceDecl *non_const_interface_decl =
+ const_cast<clang::ObjCInterfaceDecl *>(interface_decl);
- if (!m_decl_vendor.FinishDecl(non_const_interface_decl))
- break;
+ if (!m_decl_vendor.FinishDecl(non_const_interface_decl))
+ break;
- clang::DeclContext::lookup_result result = non_const_interface_decl->lookup(name);
+ clang::DeclContext::lookup_result result =
+ non_const_interface_decl->lookup(name);
- return (result.size() != 0);
- }
- while(0);
+ return (result.size() != 0);
+ } while (0);
- SetNoExternalVisibleDeclsForName(decl_ctx, name);
- return false;
- }
+ SetNoExternalVisibleDeclsForName(decl_ctx, name);
+ return false;
+ }
- void
- CompleteType(clang::TagDecl *tag_decl) override
- {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ void CompleteType(clang::TagDecl *tag_decl) override {
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ Log *log(GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
- if (log)
- {
- log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s",
- current_id,
- static_cast<void*>(&tag_decl->getASTContext()),
- static_cast<void*>(tag_decl),
- tag_decl->getName().str().c_str());
-
- log->Printf(" AOEAS::CT[%u] Before:", current_id);
- ASTDumper dumper((clang::Decl*)tag_decl);
- dumper.ToLog(log, " [CT] ");
- }
+ if (log) {
+ log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on "
+ "(ASTContext*)%p Completing (TagDecl*)%p named %s",
+ current_id, static_cast<void *>(&tag_decl->getASTContext()),
+ static_cast<void *>(tag_decl),
+ tag_decl->getName().str().c_str());
- if (log)
- {
- log->Printf(" AOEAS::CT[%u] After:", current_id);
- ASTDumper dumper((clang::Decl*)tag_decl);
- dumper.ToLog(log, " [CT] ");
- }
- return;
+ log->Printf(" AOEAS::CT[%u] Before:", current_id);
+ ASTDumper dumper((clang::Decl *)tag_decl);
+ dumper.ToLog(log, " [CT] ");
}
- void
- CompleteType(clang::ObjCInterfaceDecl *interface_decl) override
- {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (log) {
+ log->Printf(" AOEAS::CT[%u] After:", current_id);
+ ASTDumper dumper((clang::Decl *)tag_decl);
+ dumper.ToLog(log, " [CT] ");
+ }
+ return;
+ }
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override {
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- if (log)
- {
- log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on (ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
- current_id,
- static_cast<void*>(&interface_decl->getASTContext()),
- static_cast<void*>(interface_decl),
- interface_decl->getName().str().c_str());
-
- log->Printf(" AOEAS::CT[%u] Before:", current_id);
- ASTDumper dumper((clang::Decl*)interface_decl);
- dumper.ToLog(log, " [CT] ");
- }
+ Log *log(GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
- m_decl_vendor.FinishDecl(interface_decl);
+ if (log) {
+ log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on "
+ "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
+ current_id,
+ static_cast<void *>(&interface_decl->getASTContext()),
+ static_cast<void *>(interface_decl),
+ interface_decl->getName().str().c_str());
- if (log)
- {
- log->Printf(" [CT] After:");
- ASTDumper dumper((clang::Decl*)interface_decl);
- dumper.ToLog(log, " [CT] ");
- }
- return;
+ log->Printf(" AOEAS::CT[%u] Before:", current_id);
+ ASTDumper dumper((clang::Decl *)interface_decl);
+ dumper.ToLog(log, " [CT] ");
}
- bool
- layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override
- {
- return false;
- }
+ m_decl_vendor.FinishDecl(interface_decl);
- void
- StartTranslationUnit(clang::ASTConsumer *Consumer) override
- {
- clang::TranslationUnitDecl *translation_unit_decl = m_decl_vendor.m_ast_ctx.getASTContext()->getTranslationUnitDecl();
- translation_unit_decl->setHasExternalVisibleStorage();
- translation_unit_decl->setHasExternalLexicalStorage();
+ if (log) {
+ log->Printf(" [CT] After:");
+ ASTDumper dumper((clang::Decl *)interface_decl);
+ dumper.ToLog(log, " [CT] ");
}
+ return;
+ }
+
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override {
+ return false;
+ }
+
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
+ clang::TranslationUnitDecl *translation_unit_decl =
+ m_decl_vendor.m_ast_ctx.getASTContext()->getTranslationUnitDecl();
+ translation_unit_decl->setHasExternalVisibleStorage();
+ translation_unit_decl->setHasExternalLexicalStorage();
+ }
+
private:
- AppleObjCDeclVendor &m_decl_vendor;
+ AppleObjCDeclVendor &m_decl_vendor;
};
-AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime) :
- DeclVendor(),
- m_runtime(runtime),
- m_ast_ctx(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().getTriple().c_str()),
- m_type_realizer_sp(m_runtime.GetEncodingToType())
-{
- m_external_source = new AppleObjCExternalASTSource (*this);
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr (m_external_source);
- m_ast_ctx.getASTContext()->setExternalSource(external_source_owning_ptr);
+AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime)
+ : DeclVendor(), m_runtime(runtime), m_ast_ctx(runtime.GetProcess()
+ ->GetTarget()
+ .GetArchitecture()
+ .GetTriple()
+ .getTriple()
+ .c_str()),
+ m_type_realizer_sp(m_runtime.GetEncodingToType()) {
+ m_external_source = new AppleObjCExternalASTSource(*this);
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
+ m_external_source);
+ m_ast_ctx.getASTContext()->setExternalSource(external_source_owning_ptr);
}
-clang::ObjCInterfaceDecl*
-AppleObjCDeclVendor::GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa)
-{
- ISAToInterfaceMap::const_iterator iter = m_isa_to_interface.find(isa);
-
- if (iter != m_isa_to_interface.end())
- return iter->second;
-
- clang::ASTContext *ast_ctx = m_ast_ctx.getASTContext();
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor = m_runtime.GetClassDescriptorFromISA(isa);
-
- if (!descriptor)
- return NULL;
-
- const ConstString &name(descriptor->GetClassName());
-
- clang::IdentifierInfo &identifier_info = ast_ctx->Idents.get(name.GetStringRef());
-
- clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(*ast_ctx,
- ast_ctx->getTranslationUnitDecl(),
- clang::SourceLocation(),
- &identifier_info,
- nullptr,
- nullptr);
-
- ClangASTMetadata meta_data;
- meta_data.SetISAPtr(isa);
- m_external_source->SetMetadata(new_iface_decl, meta_data);
-
- new_iface_decl->setHasExternalVisibleStorage();
- new_iface_decl->setHasExternalLexicalStorage();
-
- ast_ctx->getTranslationUnitDecl()->addDecl(new_iface_decl);
-
- m_isa_to_interface[isa] = new_iface_decl;
-
- return new_iface_decl;
+clang::ObjCInterfaceDecl *
+AppleObjCDeclVendor::GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa) {
+ ISAToInterfaceMap::const_iterator iter = m_isa_to_interface.find(isa);
+
+ if (iter != m_isa_to_interface.end())
+ return iter->second;
+
+ clang::ASTContext *ast_ctx = m_ast_ctx.getASTContext();
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor =
+ m_runtime.GetClassDescriptorFromISA(isa);
+
+ if (!descriptor)
+ return NULL;
+
+ const ConstString &name(descriptor->GetClassName());
+
+ clang::IdentifierInfo &identifier_info =
+ ast_ctx->Idents.get(name.GetStringRef());
+
+ clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(
+ *ast_ctx, ast_ctx->getTranslationUnitDecl(), clang::SourceLocation(),
+ &identifier_info, nullptr, nullptr);
+
+ ClangASTMetadata meta_data;
+ meta_data.SetISAPtr(isa);
+ m_external_source->SetMetadata(new_iface_decl, meta_data);
+
+ new_iface_decl->setHasExternalVisibleStorage();
+ new_iface_decl->setHasExternalLexicalStorage();
+
+ ast_ctx->getTranslationUnitDecl()->addDecl(new_iface_decl);
+
+ m_isa_to_interface[isa] = new_iface_decl;
+
+ return new_iface_decl;
}
-class ObjCRuntimeMethodType
-{
+class ObjCRuntimeMethodType {
public:
- ObjCRuntimeMethodType (const char *types) : m_is_valid(false)
- {
- const char *cursor = types;
- enum ParserState {
- Start = 0,
- InType,
- InPos
- } state = Start;
- const char *type = NULL;
- int brace_depth = 0;
-
- uint32_t stepsLeft = 256;
-
- while (1)
- {
- if (--stepsLeft == 0)
- {
- m_is_valid = false;
- return;
- }
-
- switch (state)
- {
- case Start:
- {
- switch (*cursor)
- {
- default:
- state = InType;
- type = cursor;
- break;
- case '\0':
- m_is_valid = true;
- return;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- m_is_valid = false;
- return;
- }
- }
- break;
- case InType:
- {
- switch (*cursor)
- {
- default:
- ++cursor;
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (!brace_depth)
- {
- state = InPos;
- if (type)
- {
- m_type_vector.push_back(std::string(type, (cursor - type)));
- }
- else
- {
- m_is_valid = false;
- return;
- }
- type = NULL;
- }
- else
- {
- ++cursor;
- }
- break;
- case '[': case '{': case '(':
- ++brace_depth;
- ++cursor;
- break;
- case ']': case '}': case ')':
- if (!brace_depth)
- {
- m_is_valid = false;
- return;
- }
- --brace_depth;
- ++cursor;
- break;
- case '\0':
- m_is_valid = false;
- return;
- }
- }
- break;
- case InPos:
- {
- switch (*cursor)
- {
- default:
- state = InType;
- type = cursor;
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- ++cursor;
- break;
- case '\0':
- m_is_valid = true;
- return;
- }
- }
- break;
- }
+ ObjCRuntimeMethodType(const char *types) : m_is_valid(false) {
+ const char *cursor = types;
+ enum ParserState { Start = 0, InType, InPos } state = Start;
+ const char *type = NULL;
+ int brace_depth = 0;
+
+ uint32_t stepsLeft = 256;
+
+ while (1) {
+ if (--stepsLeft == 0) {
+ m_is_valid = false;
+ return;
+ }
+
+ switch (state) {
+ case Start: {
+ switch (*cursor) {
+ default:
+ state = InType;
+ type = cursor;
+ break;
+ case '\0':
+ m_is_valid = true;
+ return;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ m_is_valid = false;
+ return;
}
- }
-
- clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl *interface_decl, const char *name, bool instance, ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp)
- {
- if (!m_is_valid || m_type_vector.size() < 3)
- return NULL;
-
- clang::ASTContext &ast_ctx(interface_decl->getASTContext());
-
- clang::QualType return_qual_type;
-
- const bool isInstance = instance;
- const bool isVariadic = false;
- const bool isSynthesized = false;
- const bool isImplicitlyDeclared = true;
- const bool isDefined = false;
- const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
- const bool HasRelatedResultType = false;
- const bool for_expression = true;
-
- std::vector <clang::IdentifierInfo *> selector_components;
-
- const char *name_cursor = name;
- bool is_zero_argument = true;
-
-
- while (*name_cursor != '\0')
- {
- const char *colon_loc = strchr(name_cursor, ':');
- if (!colon_loc)
- {
- selector_components.push_back(&ast_ctx.Idents.get(llvm::StringRef(name_cursor)));
- break;
- }
- else
- {
- is_zero_argument = false;
- selector_components.push_back(&ast_ctx.Idents.get(llvm::StringRef(name_cursor, colon_loc - name_cursor)));
- name_cursor = colon_loc + 1;
+ } break;
+ case InType: {
+ switch (*cursor) {
+ default:
+ ++cursor;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (!brace_depth) {
+ state = InPos;
+ if (type) {
+ m_type_vector.push_back(std::string(type, (cursor - type)));
+ } else {
+ m_is_valid = false;
+ return;
}
+ type = NULL;
+ } else {
+ ++cursor;
+ }
+ break;
+ case '[':
+ case '{':
+ case '(':
+ ++brace_depth;
+ ++cursor;
+ break;
+ case ']':
+ case '}':
+ case ')':
+ if (!brace_depth) {
+ m_is_valid = false;
+ return;
+ }
+ --brace_depth;
+ ++cursor;
+ break;
+ case '\0':
+ m_is_valid = false;
+ return;
}
-
- clang::Selector sel = ast_ctx.Selectors.getSelector(is_zero_argument ? 0 : selector_components.size(), selector_components.data());
-
- clang::QualType ret_type = ClangUtil::GetQualType(
- type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
-
- if (ret_type.isNull())
- return NULL;
-
- clang::ObjCMethodDecl *ret = clang::ObjCMethodDecl::Create(ast_ctx,
- clang::SourceLocation(),
- clang::SourceLocation(),
- sel,
- ret_type,
- NULL,
- interface_decl,
- isInstance,
- isVariadic,
- isSynthesized,
- isImplicitlyDeclared,
- isDefined,
- impControl,
- HasRelatedResultType);
-
- std::vector <clang::ParmVarDecl*> parm_vars;
-
- for (size_t ai = 3, ae = m_type_vector.size();
- ai != ae;
- ++ai)
- {
- const bool for_expression = true;
- clang::QualType arg_type = ClangUtil::GetQualType(
- type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression));
-
- if (arg_type.isNull())
- return NULL; // well, we just wasted a bunch of time. Wish we could delete the stuff we'd just made!
-
- parm_vars.push_back(clang::ParmVarDecl::Create(ast_ctx,
- ret,
- clang::SourceLocation(),
- clang::SourceLocation(),
- NULL,
- arg_type,
- NULL,
- clang::SC_None,
- NULL));
+ } break;
+ case InPos: {
+ switch (*cursor) {
+ default:
+ state = InType;
+ type = cursor;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ ++cursor;
+ break;
+ case '\0':
+ m_is_valid = true;
+ return;
}
-
- ret->setMethodParams(ast_ctx, llvm::ArrayRef<clang::ParmVarDecl*>(parm_vars), llvm::ArrayRef<clang::SourceLocation>());
-
- return ret;
- }
-
- explicit operator bool ()
- {
- return m_is_valid;
+ } break;
+ }
}
-
- size_t
- GetNumTypes ()
- {
- return m_type_vector.size();
+ }
+
+ clang::ObjCMethodDecl *
+ BuildMethod(clang::ObjCInterfaceDecl *interface_decl, const char *name,
+ bool instance,
+ ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp) {
+ if (!m_is_valid || m_type_vector.size() < 3)
+ return NULL;
+
+ clang::ASTContext &ast_ctx(interface_decl->getASTContext());
+
+ clang::QualType return_qual_type;
+
+ const bool isInstance = instance;
+ const bool isVariadic = false;
+ const bool isSynthesized = false;
+ const bool isImplicitlyDeclared = true;
+ const bool isDefined = false;
+ const clang::ObjCMethodDecl::ImplementationControl impControl =
+ clang::ObjCMethodDecl::None;
+ const bool HasRelatedResultType = false;
+ const bool for_expression = true;
+
+ std::vector<clang::IdentifierInfo *> selector_components;
+
+ const char *name_cursor = name;
+ bool is_zero_argument = true;
+
+ while (*name_cursor != '\0') {
+ const char *colon_loc = strchr(name_cursor, ':');
+ if (!colon_loc) {
+ selector_components.push_back(
+ &ast_ctx.Idents.get(llvm::StringRef(name_cursor)));
+ break;
+ } else {
+ is_zero_argument = false;
+ selector_components.push_back(&ast_ctx.Idents.get(
+ llvm::StringRef(name_cursor, colon_loc - name_cursor)));
+ name_cursor = colon_loc + 1;
+ }
}
-
- const char*
- GetTypeAtIndex (size_t idx)
- {
- return m_type_vector[idx].c_str();
+
+ clang::Selector sel = ast_ctx.Selectors.getSelector(
+ is_zero_argument ? 0 : selector_components.size(),
+ selector_components.data());
+
+ clang::QualType ret_type =
+ ClangUtil::GetQualType(type_realizer_sp->RealizeType(
+ interface_decl->getASTContext(), m_type_vector[0].c_str(),
+ for_expression));
+
+ if (ret_type.isNull())
+ return NULL;
+
+ clang::ObjCMethodDecl *ret = clang::ObjCMethodDecl::Create(
+ ast_ctx, clang::SourceLocation(), clang::SourceLocation(), sel,
+ ret_type, NULL, interface_decl, isInstance, isVariadic, isSynthesized,
+ isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);
+
+ std::vector<clang::ParmVarDecl *> parm_vars;
+
+ for (size_t ai = 3, ae = m_type_vector.size(); ai != ae; ++ai) {
+ const bool for_expression = true;
+ clang::QualType arg_type =
+ ClangUtil::GetQualType(type_realizer_sp->RealizeType(
+ ast_ctx, m_type_vector[ai].c_str(), for_expression));
+
+ if (arg_type.isNull())
+ return NULL; // well, we just wasted a bunch of time. Wish we could
+ // delete the stuff we'd just made!
+
+ parm_vars.push_back(clang::ParmVarDecl::Create(
+ ast_ctx, ret, clang::SourceLocation(), clang::SourceLocation(), NULL,
+ arg_type, NULL, clang::SC_None, NULL));
}
-
+
+ ret->setMethodParams(ast_ctx,
+ llvm::ArrayRef<clang::ParmVarDecl *>(parm_vars),
+ llvm::ArrayRef<clang::SourceLocation>());
+
+ return ret;
+ }
+
+ explicit operator bool() { return m_is_valid; }
+
+ size_t GetNumTypes() { return m_type_vector.size(); }
+
+ const char *GetTypeAtIndex(size_t idx) { return m_type_vector[idx].c_str(); }
+
private:
- typedef std::vector <std::string> TypeVector;
-
- TypeVector m_type_vector;
- bool m_is_valid;
+ typedef std::vector<std::string> TypeVector;
+
+ TypeVector m_type_vector;
+ bool m_is_valid;
};
-bool
-AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
-
- ClangASTMetadata *metadata = m_external_source->GetMetadata(interface_decl);
- ObjCLanguageRuntime::ObjCISA objc_isa = 0;
- if (metadata)
- objc_isa = metadata->GetISAPtr();
-
- if (!objc_isa)
- return false;
-
- if (!interface_decl->hasExternalVisibleStorage())
- return true;
-
- interface_decl->startDefinition();
-
- interface_decl->setHasExternalVisibleStorage(false);
- interface_decl->setHasExternalLexicalStorage(false);
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor = m_runtime.GetClassDescriptorFromISA(objc_isa);
-
- if (!descriptor)
- return false;
-
- auto superclass_func = [interface_decl, this](ObjCLanguageRuntime::ObjCISA isa)
- {
- clang::ObjCInterfaceDecl *superclass_decl = GetDeclForISA(isa);
-
- if (!superclass_decl)
- return;
-
- FinishDecl(superclass_decl);
- clang::ASTContext *context = m_ast_ctx.getASTContext();
- interface_decl->setSuperClass(
- context->getTrivialTypeSourceInfo(context->getObjCInterfaceType(superclass_decl)));
- };
-
- auto instance_method_func = [log, interface_decl, this](const char *name, const char *types) -> bool
- {
- if (!name || !types)
- return false; // skip this one
-
- ObjCRuntimeMethodType method_type(types);
-
- clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name, true, m_type_realizer_sp);
-
- if (log)
- log->Printf("[ AOTV::FD] Instance method [%s] [%s]", name, types);
-
- if (method_decl)
- interface_decl->addDecl(method_decl);
-
- return false;
- };
-
- auto class_method_func = [log, interface_decl, this](const char *name, const char *types) -> bool
- {
- if (!name || !types)
- return false; // skip this one
-
- ObjCRuntimeMethodType method_type(types);
-
- clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name, false, m_type_realizer_sp);
-
- if (log)
- log->Printf("[ AOTV::FD] Class method [%s] [%s]", name, types);
-
- if (method_decl)
- interface_decl->addDecl(method_decl);
-
- return false;
- };
-
- auto ivar_func = [log, interface_decl, this](const char *name, const char *type, lldb::addr_t offset_ptr, uint64_t size) -> bool
- {
- if (!name || !type)
- return false;
-
- const bool for_expression = false;
-
- if (log)
- log->Printf("[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64, name, type, offset_ptr);
-
- CompilerType ivar_type = m_runtime.GetEncodingToType()->RealizeType(m_ast_ctx, type, for_expression);
-
- if (ivar_type.IsValid())
- {
- clang::TypeSourceInfo * const type_source_info = nullptr;
- const bool is_synthesized = false;
- clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
- *m_ast_ctx.getASTContext(), interface_decl, clang::SourceLocation(), clang::SourceLocation(),
- &m_ast_ctx.getASTContext()->Idents.get(name), ClangUtil::GetQualType(ivar_type),
- type_source_info, // TypeSourceInfo *
- clang::ObjCIvarDecl::Public, 0, is_synthesized);
-
- if (ivar_decl)
- {
- interface_decl->addDecl(ivar_decl);
- }
- }
-
- return false;
- };
-
+bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
+ Log *log(GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+
+ ClangASTMetadata *metadata = m_external_source->GetMetadata(interface_decl);
+ ObjCLanguageRuntime::ObjCISA objc_isa = 0;
+ if (metadata)
+ objc_isa = metadata->GetISAPtr();
+
+ if (!objc_isa)
+ return false;
+
+ if (!interface_decl->hasExternalVisibleStorage())
+ return true;
+
+ interface_decl->startDefinition();
+
+ interface_decl->setHasExternalVisibleStorage(false);
+ interface_decl->setHasExternalLexicalStorage(false);
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor =
+ m_runtime.GetClassDescriptorFromISA(objc_isa);
+
+ if (!descriptor)
+ return false;
+
+ auto superclass_func = [interface_decl,
+ this](ObjCLanguageRuntime::ObjCISA isa) {
+ clang::ObjCInterfaceDecl *superclass_decl = GetDeclForISA(isa);
+
+ if (!superclass_decl)
+ return;
+
+ FinishDecl(superclass_decl);
+ clang::ASTContext *context = m_ast_ctx.getASTContext();
+ interface_decl->setSuperClass(context->getTrivialTypeSourceInfo(
+ context->getObjCInterfaceType(superclass_decl)));
+ };
+
+ auto instance_method_func =
+ [log, interface_decl, this](const char *name, const char *types) -> bool {
+ if (!name || !types)
+ return false; // skip this one
+
+ ObjCRuntimeMethodType method_type(types);
+
+ clang::ObjCMethodDecl *method_decl =
+ method_type.BuildMethod(interface_decl, name, true, m_type_realizer_sp);
+
if (log)
- {
- ASTDumper method_dumper ((clang::Decl*)interface_decl);
-
- log->Printf("[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C interface for %s", descriptor->GetClassName().AsCString());
- }
-
-
- if (!descriptor->Describe(superclass_func,
- instance_method_func,
- class_method_func,
- ivar_func))
- return false;
-
+ log->Printf("[ AOTV::FD] Instance method [%s] [%s]", name, types);
+
+ if (method_decl)
+ interface_decl->addDecl(method_decl);
+
+ return false;
+ };
+
+ auto class_method_func = [log, interface_decl,
+ this](const char *name, const char *types) -> bool {
+ if (!name || !types)
+ return false; // skip this one
+
+ ObjCRuntimeMethodType method_type(types);
+
+ clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(
+ interface_decl, name, false, m_type_realizer_sp);
+
if (log)
- {
- ASTDumper method_dumper ((clang::Decl*)interface_decl);
-
- log->Printf("[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
-
- method_dumper.ToLog(log, " [AOTV::FD] ");
+ log->Printf("[ AOTV::FD] Class method [%s] [%s]", name, types);
+
+ if (method_decl)
+ interface_decl->addDecl(method_decl);
+
+ return false;
+ };
+
+ auto ivar_func = [log, interface_decl,
+ this](const char *name, const char *type,
+ lldb::addr_t offset_ptr, uint64_t size) -> bool {
+ if (!name || !type)
+ return false;
+
+ const bool for_expression = false;
+
+ if (log)
+ log->Printf(
+ "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64, name,
+ type, offset_ptr);
+
+ CompilerType ivar_type = m_runtime.GetEncodingToType()->RealizeType(
+ m_ast_ctx, type, for_expression);
+
+ if (ivar_type.IsValid()) {
+ clang::TypeSourceInfo *const type_source_info = nullptr;
+ const bool is_synthesized = false;
+ clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
+ *m_ast_ctx.getASTContext(), interface_decl, clang::SourceLocation(),
+ clang::SourceLocation(), &m_ast_ctx.getASTContext()->Idents.get(name),
+ ClangUtil::GetQualType(ivar_type),
+ type_source_info, // TypeSourceInfo *
+ clang::ObjCIvarDecl::Public, 0, is_synthesized);
+
+ if (ivar_decl) {
+ interface_decl->addDecl(ivar_decl);
+ }
}
-
- return true;
+
+ return false;
+ };
+
+ if (log) {
+ ASTDumper method_dumper((clang::Decl *)interface_decl);
+
+ log->Printf("[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
+ "interface for %s",
+ descriptor->GetClassName().AsCString());
+ }
+
+ if (!descriptor->Describe(superclass_func, instance_method_func,
+ class_method_func, ivar_func))
+ return false;
+
+ if (log) {
+ ASTDumper method_dumper((clang::Decl *)interface_decl);
+
+ log->Printf(
+ "[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
+
+ method_dumper.ToLog(log, " [AOTV::FD] ");
+ }
+
+ return true;
}
uint32_t
-AppleObjCDeclVendor::FindDecls (const ConstString &name,
- bool append,
- uint32_t max_matches,
- std::vector <clang::NamedDecl *> &decls)
-{
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
-
- if (log)
- log->Printf("AppleObjCDeclVendor::FindTypes [%u] ('%s', %s, %u, )",
- current_id,
- (const char*)name.AsCString(),
- append ? "true" : "false",
- max_matches);
-
- if (!append)
- decls.clear();
-
- uint32_t ret = 0;
-
- do
- {
- // See if the type is already in our ASTContext.
-
- clang::ASTContext *ast_ctx = m_ast_ctx.getASTContext();
-
- clang::IdentifierInfo &identifier_info = ast_ctx->Idents.get(name.GetStringRef());
- clang::DeclarationName decl_name = ast_ctx->DeclarationNames.getIdentifier(&identifier_info);
-
- clang::DeclContext::lookup_result lookup_result = ast_ctx->getTranslationUnitDecl()->lookup(decl_name);
-
- if (!lookup_result.empty())
- {
- if (clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(lookup_result[0]))
- {
- if (log)
- {
- clang::QualType result_iface_type = ast_ctx->getObjCInterfaceType(result_iface_decl);
- ASTDumper dumper(result_iface_type);
-
- uint64_t isa_value = LLDB_INVALID_ADDRESS;
- ClangASTMetadata *metadata = m_external_source->GetMetadata(result_iface_decl);
- if (metadata)
- isa_value = metadata->GetISAPtr();
-
- log->Printf("AOCTV::FT [%u] Found %s (isa 0x%" PRIx64 ") in the ASTContext",
- current_id,
- dumper.GetCString(),
- isa_value);
- }
-
- decls.push_back(result_iface_decl);
- ret++;
- break;
- }
- else
- {
- if (log)
- log->Printf("AOCTV::FT [%u] There's something in the ASTContext, but it's not something we know about",
- current_id);
- break;
- }
- }
- else if(log)
- {
- log->Printf("AOCTV::FT [%u] Couldn't find %s in the ASTContext",
- current_id,
- name.AsCString());
- }
-
- // It's not. If it exists, we have to put it into our ASTContext.
-
- ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
-
- if (!isa)
- {
- if (log)
- log->Printf("AOCTV::FT [%u] Couldn't find the isa",
- current_id);
-
- break;
- }
-
- clang::ObjCInterfaceDecl *iface_decl = GetDeclForISA(isa);
-
- if (!iface_decl)
- {
- if (log)
- log->Printf("AOCTV::FT [%u] Couldn't get the Objective-C interface for isa 0x%" PRIx64,
- current_id,
- (uint64_t)isa);
-
- break;
- }
-
- if (log)
- {
- clang::QualType new_iface_type = ast_ctx->getObjCInterfaceType(iface_decl);
- ASTDumper dumper(new_iface_type);
- log->Printf("AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")",
- current_id,
- dumper.GetCString(),
- (uint64_t)isa);
+AppleObjCDeclVendor::FindDecls(const ConstString &name, bool append,
+ uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) {
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
+
+ Log *log(GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+
+ if (log)
+ log->Printf("AppleObjCDeclVendor::FindTypes [%u] ('%s', %s, %u, )",
+ current_id, (const char *)name.AsCString(),
+ append ? "true" : "false", max_matches);
+
+ if (!append)
+ decls.clear();
+
+ uint32_t ret = 0;
+
+ do {
+ // See if the type is already in our ASTContext.
+
+ clang::ASTContext *ast_ctx = m_ast_ctx.getASTContext();
+
+ clang::IdentifierInfo &identifier_info =
+ ast_ctx->Idents.get(name.GetStringRef());
+ clang::DeclarationName decl_name =
+ ast_ctx->DeclarationNames.getIdentifier(&identifier_info);
+
+ clang::DeclContext::lookup_result lookup_result =
+ ast_ctx->getTranslationUnitDecl()->lookup(decl_name);
+
+ if (!lookup_result.empty()) {
+ if (clang::ObjCInterfaceDecl *result_iface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(lookup_result[0])) {
+ if (log) {
+ clang::QualType result_iface_type =
+ ast_ctx->getObjCInterfaceType(result_iface_decl);
+ ASTDumper dumper(result_iface_type);
+
+ uint64_t isa_value = LLDB_INVALID_ADDRESS;
+ ClangASTMetadata *metadata =
+ m_external_source->GetMetadata(result_iface_decl);
+ if (metadata)
+ isa_value = metadata->GetISAPtr();
+
+ log->Printf("AOCTV::FT [%u] Found %s (isa 0x%" PRIx64
+ ") in the ASTContext",
+ current_id, dumper.GetCString(), isa_value);
}
-
- decls.push_back(iface_decl);
+
+ decls.push_back(result_iface_decl);
ret++;
break;
- } while (0);
-
- return ret;
+ } else {
+ if (log)
+ log->Printf("AOCTV::FT [%u] There's something in the ASTContext, but "
+ "it's not something we know about",
+ current_id);
+ break;
+ }
+ } else if (log) {
+ log->Printf("AOCTV::FT [%u] Couldn't find %s in the ASTContext",
+ current_id, name.AsCString());
+ }
+
+ // It's not. If it exists, we have to put it into our ASTContext.
+
+ ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
+
+ if (!isa) {
+ if (log)
+ log->Printf("AOCTV::FT [%u] Couldn't find the isa", current_id);
+
+ break;
+ }
+
+ clang::ObjCInterfaceDecl *iface_decl = GetDeclForISA(isa);
+
+ if (!iface_decl) {
+ if (log)
+ log->Printf("AOCTV::FT [%u] Couldn't get the Objective-C interface for "
+ "isa 0x%" PRIx64,
+ current_id, (uint64_t)isa);
+
+ break;
+ }
+
+ if (log) {
+ clang::QualType new_iface_type =
+ ast_ctx->getObjCInterfaceType(iface_decl);
+ ASTDumper dumper(new_iface_type);
+ log->Printf("AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")", current_id,
+ dumper.GetCString(), (uint64_t)isa);
+ }
+
+ decls.push_back(iface_decl);
+ ret++;
+ break;
+ } while (0);
+
+ return ret;
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
index 88789c7b5a8d..26824079d945 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
@@ -14,40 +14,38 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
class AppleObjCExternalASTSource;
-
-class AppleObjCDeclVendor : public DeclVendor
-{
+
+class AppleObjCDeclVendor : public DeclVendor {
public:
- AppleObjCDeclVendor(ObjCLanguageRuntime &runtime);
-
- uint32_t
- FindDecls(const ConstString &name,
- bool append,
- uint32_t max_matches,
- std::vector <clang::NamedDecl *> &decls) override;
-
- friend class AppleObjCExternalASTSource;
+ AppleObjCDeclVendor(ObjCLanguageRuntime &runtime);
+
+ uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) override;
+
+ friend class AppleObjCExternalASTSource;
private:
- clang::ObjCInterfaceDecl *GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa);
- bool FinishDecl(clang::ObjCInterfaceDecl *decl);
-
- ObjCLanguageRuntime &m_runtime;
- ClangASTContext m_ast_ctx;
- ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp;
- AppleObjCExternalASTSource *m_external_source;
-
- typedef llvm::DenseMap<ObjCLanguageRuntime::ObjCISA, clang::ObjCInterfaceDecl *> ISAToInterfaceMap;
-
- ISAToInterfaceMap m_isa_to_interface;
+ clang::ObjCInterfaceDecl *GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa);
+ bool FinishDecl(clang::ObjCInterfaceDecl *decl);
+
+ ObjCLanguageRuntime &m_runtime;
+ ClangASTContext m_ast_ctx;
+ ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp;
+ AppleObjCExternalASTSource *m_external_source;
+
+ typedef llvm::DenseMap<ObjCLanguageRuntime::ObjCISA,
+ clang::ObjCInterfaceDecl *>
+ ISAToInterfaceMap;
+
+ ISAToInterfaceMap m_isa_to_interface;
};
} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 6d83f7a7c5e1..4a90f5c16633 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -1,4 +1,5 @@
-//===-- AppleObjCRuntime.cpp -------------------------------------*- C++ -*-===//
+//===-- AppleObjCRuntime.cpp -------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -39,509 +40,450 @@
using namespace lldb;
using namespace lldb_private;
-#define PO_FUNCTION_TIMEOUT_USEC 15*1000*1000
+static constexpr std::chrono::seconds g_po_function_timeout(15);
-AppleObjCRuntime::~AppleObjCRuntime()
-{
-}
+AppleObjCRuntime::~AppleObjCRuntime() {}
-AppleObjCRuntime::AppleObjCRuntime(Process *process) :
- ObjCLanguageRuntime (process),
- m_read_objc_library (false),
- m_objc_trampoline_handler_ap (),
- m_Foundation_major()
-{
- ReadObjCLibraryIfNeeded (process->GetTarget().GetImages());
+AppleObjCRuntime::AppleObjCRuntime(Process *process)
+ : ObjCLanguageRuntime(process), m_read_objc_library(false),
+ m_objc_trampoline_handler_ap(), m_Foundation_major() {
+ ReadObjCLibraryIfNeeded(process->GetTarget().GetImages());
}
-bool
-AppleObjCRuntime::GetObjectDescription (Stream &str, ValueObject &valobj)
-{
- CompilerType compiler_type(valobj.GetCompilerType());
- bool is_signed;
- // ObjC objects can only be pointers (or numbers that actually represents pointers
- // but haven't been typecast, because reasons..)
- if (!compiler_type.IsIntegerType (is_signed) && !compiler_type.IsPointerType ())
- return false;
-
- // Make the argument list: we pass one arg, the address of our pointer, to the print function.
- Value val;
-
- if (!valobj.ResolveValue(val.GetScalar()))
- return false;
-
- // Value Objects may not have a process in their ExecutionContextRef. But we need to have one
- // in the ref we pass down to eventually call description. Get it from the target if it isn't
- // present.
- ExecutionContext exe_ctx;
- if (valobj.GetProcessSP())
- {
- exe_ctx = ExecutionContext(valobj.GetExecutionContextRef());
- }
- else
- {
- exe_ctx.SetContext(valobj.GetTargetSP(), true);
- if (!exe_ctx.HasProcessScope())
- return false;
- }
- return GetObjectDescription(str, val, exe_ctx.GetBestExecutionContextScope());
-
+bool AppleObjCRuntime::GetObjectDescription(Stream &str, ValueObject &valobj) {
+ CompilerType compiler_type(valobj.GetCompilerType());
+ bool is_signed;
+ // ObjC objects can only be pointers (or numbers that actually represents
+ // pointers
+ // but haven't been typecast, because reasons..)
+ if (!compiler_type.IsIntegerType(is_signed) && !compiler_type.IsPointerType())
+ return false;
+
+ // Make the argument list: we pass one arg, the address of our pointer, to the
+ // print function.
+ Value val;
+
+ if (!valobj.ResolveValue(val.GetScalar()))
+ return false;
+
+ // Value Objects may not have a process in their ExecutionContextRef. But we
+ // need to have one
+ // in the ref we pass down to eventually call description. Get it from the
+ // target if it isn't
+ // present.
+ ExecutionContext exe_ctx;
+ if (valobj.GetProcessSP()) {
+ exe_ctx = ExecutionContext(valobj.GetExecutionContextRef());
+ } else {
+ exe_ctx.SetContext(valobj.GetTargetSP(), true);
+ if (!exe_ctx.HasProcessScope())
+ return false;
+ }
+ return GetObjectDescription(str, val, exe_ctx.GetBestExecutionContextScope());
}
-bool
-AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionContextScope *exe_scope)
-{
- if (!m_read_objc_library)
- return false;
-
- ExecutionContext exe_ctx;
- exe_scope->CalculateExecutionContext(exe_ctx);
- Process *process = exe_ctx.GetProcessPtr();
- if (!process)
- return false;
-
- // We need other parts of the exe_ctx, but the processes have to match.
- assert (m_process == process);
-
- // Get the function address for the print function.
- const Address *function_address = GetPrintForDebuggerAddr();
- if (!function_address)
- return false;
-
- Target *target = exe_ctx.GetTargetPtr();
- CompilerType compiler_type = value.GetCompilerType();
- if (compiler_type)
- {
- if (!ClangASTContext::IsObjCObjectPointerType(compiler_type))
- {
- strm.Printf ("Value doesn't point to an ObjC object.\n");
- return false;
- }
- }
- else
- {
- // If it is not a pointer, see if we can make it into a pointer.
- ClangASTContext *ast_context = target->GetScratchClangASTContext();
- CompilerType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID);
- if (!opaque_type)
- opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
- value.SetCompilerType (opaque_type);
- }
+bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
+ ExecutionContextScope *exe_scope) {
+ if (!m_read_objc_library)
+ return false;
- ValueList arg_value_list;
- arg_value_list.PushValue(value);
-
- // This is the return value:
- ClangASTContext *ast_context = target->GetScratchClangASTContext();
-
- CompilerType return_compiler_type = ast_context->GetCStringType(true);
- Value ret;
-// ret.SetContext(Value::eContextTypeClangType, return_compiler_type);
- ret.SetCompilerType (return_compiler_type);
-
- if (exe_ctx.GetFramePtr() == NULL)
- {
- Thread *thread = exe_ctx.GetThreadPtr();
- if (thread == NULL)
- {
- exe_ctx.SetThreadSP(process->GetThreadList().GetSelectedThread());
- thread = exe_ctx.GetThreadPtr();
- }
- if (thread)
- {
- exe_ctx.SetFrameSP(thread->GetSelectedFrame());
- }
- }
+ ExecutionContext exe_ctx;
+ exe_scope->CalculateExecutionContext(exe_ctx);
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!process)
+ return false;
- // Now we're ready to call the function:
-
- DiagnosticManager diagnostics;
- lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
-
- if (!m_print_object_caller_up)
- {
- Error error;
- m_print_object_caller_up.reset(exe_scope->CalculateTarget()->GetFunctionCallerForLanguage (eLanguageTypeObjC,
- return_compiler_type,
- *function_address,
- arg_value_list,
- "objc-object-description",
- error));
- if (error.Fail())
- {
- m_print_object_caller_up.reset();
- strm.Printf("Could not get function runner to call print for debugger function: %s.", error.AsCString());
- return false;
- }
- m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, diagnostics);
+ // We need other parts of the exe_ctx, but the processes have to match.
+ assert(m_process == process);
+
+ // Get the function address for the print function.
+ const Address *function_address = GetPrintForDebuggerAddr();
+ if (!function_address)
+ return false;
+
+ Target *target = exe_ctx.GetTargetPtr();
+ CompilerType compiler_type = value.GetCompilerType();
+ if (compiler_type) {
+ if (!ClangASTContext::IsObjCObjectPointerType(compiler_type)) {
+ strm.Printf("Value doesn't point to an ObjC object.\n");
+ return false;
}
- else
- {
- m_print_object_caller_up->WriteFunctionArguments(exe_ctx, wrapper_struct_addr, arg_value_list, diagnostics);
+ } else {
+ // If it is not a pointer, see if we can make it into a pointer.
+ ClangASTContext *ast_context = target->GetScratchClangASTContext();
+ CompilerType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID);
+ if (!opaque_type)
+ opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ // value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
+ value.SetCompilerType(opaque_type);
+ }
+
+ ValueList arg_value_list;
+ arg_value_list.PushValue(value);
+
+ // This is the return value:
+ ClangASTContext *ast_context = target->GetScratchClangASTContext();
+
+ CompilerType return_compiler_type = ast_context->GetCStringType(true);
+ Value ret;
+ // ret.SetContext(Value::eContextTypeClangType, return_compiler_type);
+ ret.SetCompilerType(return_compiler_type);
+
+ if (exe_ctx.GetFramePtr() == NULL) {
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (thread == NULL) {
+ exe_ctx.SetThreadSP(process->GetThreadList().GetSelectedThread());
+ thread = exe_ctx.GetThreadPtr();
}
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(true);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
-
- ExpressionResults results =
- m_print_object_caller_up->ExecuteFunction(exe_ctx, &wrapper_struct_addr, options, diagnostics, ret);
- if (results != eExpressionCompleted)
- {
- strm.Printf("Error evaluating Print Object function: %d.\n", results);
- return false;
+ if (thread) {
+ exe_ctx.SetFrameSP(thread->GetSelectedFrame());
}
-
- addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
-
- char buf[512];
- size_t cstr_len = 0;
- size_t full_buffer_len = sizeof (buf) - 1;
- size_t curr_len = full_buffer_len;
- while (curr_len == full_buffer_len)
- {
- Error error;
- curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf), error);
- strm.Write (buf, curr_len);
- cstr_len += curr_len;
+ }
+
+ // Now we're ready to call the function:
+
+ DiagnosticManager diagnostics;
+ lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
+
+ if (!m_print_object_caller_up) {
+ Error error;
+ m_print_object_caller_up.reset(
+ exe_scope->CalculateTarget()->GetFunctionCallerForLanguage(
+ eLanguageTypeObjC, return_compiler_type, *function_address,
+ arg_value_list, "objc-object-description", error));
+ if (error.Fail()) {
+ m_print_object_caller_up.reset();
+ strm.Printf("Could not get function runner to call print for debugger "
+ "function: %s.",
+ error.AsCString());
+ return false;
}
- return cstr_len > 0;
+ m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr,
+ diagnostics);
+ } else {
+ m_print_object_caller_up->WriteFunctionArguments(
+ exe_ctx, wrapper_struct_addr, arg_value_list, diagnostics);
+ }
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(g_po_function_timeout);
+
+ ExpressionResults results = m_print_object_caller_up->ExecuteFunction(
+ exe_ctx, &wrapper_struct_addr, options, diagnostics, ret);
+ if (results != eExpressionCompleted) {
+ strm.Printf("Error evaluating Print Object function: %d.\n", results);
+ return false;
+ }
+
+ addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+
+ char buf[512];
+ size_t cstr_len = 0;
+ size_t full_buffer_len = sizeof(buf) - 1;
+ size_t curr_len = full_buffer_len;
+ while (curr_len == full_buffer_len) {
+ Error error;
+ curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf,
+ sizeof(buf), error);
+ strm.Write(buf, curr_len);
+ cstr_len += curr_len;
+ }
+ return cstr_len > 0;
}
-lldb::ModuleSP
-AppleObjCRuntime::GetObjCModule ()
-{
- ModuleSP module_sp (m_objc_module_wp.lock());
- if (module_sp)
+lldb::ModuleSP AppleObjCRuntime::GetObjCModule() {
+ ModuleSP module_sp(m_objc_module_wp.lock());
+ if (module_sp)
+ return module_sp;
+
+ Process *process = GetProcess();
+ if (process) {
+ const ModuleList &modules = process->GetTarget().GetImages();
+ for (uint32_t idx = 0; idx < modules.GetSize(); idx++) {
+ module_sp = modules.GetModuleAtIndex(idx);
+ if (AppleObjCRuntime::AppleIsModuleObjCLibrary(module_sp)) {
+ m_objc_module_wp = module_sp;
return module_sp;
-
- Process *process = GetProcess();
- if (process)
- {
- const ModuleList& modules = process->GetTarget().GetImages();
- for (uint32_t idx = 0; idx < modules.GetSize(); idx++)
- {
- module_sp = modules.GetModuleAtIndex(idx);
- if (AppleObjCRuntime::AppleIsModuleObjCLibrary(module_sp))
- {
- m_objc_module_wp = module_sp;
- return module_sp;
- }
- }
+ }
}
- return ModuleSP();
+ }
+ return ModuleSP();
}
-Address *
-AppleObjCRuntime::GetPrintForDebuggerAddr()
-{
- if (!m_PrintForDebugger_addr.get())
- {
- const ModuleList &modules = m_process->GetTarget().GetImages();
-
- SymbolContextList contexts;
- SymbolContext context;
-
- if ((!modules.FindSymbolsWithNameAndType(ConstString ("_NSPrintForDebugger"), eSymbolTypeCode, contexts)) &&
- (!modules.FindSymbolsWithNameAndType(ConstString ("_CFPrintForDebugger"), eSymbolTypeCode, contexts)))
- return NULL;
-
- contexts.GetContextAtIndex(0, context);
-
- m_PrintForDebugger_addr.reset(new Address(context.symbol->GetAddress()));
- }
-
- return m_PrintForDebugger_addr.get();
+Address *AppleObjCRuntime::GetPrintForDebuggerAddr() {
+ if (!m_PrintForDebugger_addr.get()) {
+ const ModuleList &modules = m_process->GetTarget().GetImages();
+
+ SymbolContextList contexts;
+ SymbolContext context;
+
+ if ((!modules.FindSymbolsWithNameAndType(ConstString("_NSPrintForDebugger"),
+ eSymbolTypeCode, contexts)) &&
+ (!modules.FindSymbolsWithNameAndType(ConstString("_CFPrintForDebugger"),
+ eSymbolTypeCode, contexts)))
+ return NULL;
+
+ contexts.GetContextAtIndex(0, context);
+
+ m_PrintForDebugger_addr.reset(new Address(context.symbol->GetAddress()));
+ }
+
+ return m_PrintForDebugger_addr.get();
}
-bool
-AppleObjCRuntime::CouldHaveDynamicValue (ValueObject &in_value)
-{
- return in_value.GetCompilerType().IsPossibleDynamicType (NULL,
- false, // do not check C++
- true); // check ObjC
+bool AppleObjCRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
+ return in_value.GetCompilerType().IsPossibleDynamicType(
+ NULL,
+ false, // do not check C++
+ true); // check ObjC
}
-bool
-AppleObjCRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type)
-{
- return false;
+bool AppleObjCRuntime::GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) {
+ return false;
}
TypeAndOrName
-AppleObjCRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name,
- ValueObject& static_value)
-{
- CompilerType static_type(static_value.GetCompilerType());
- Flags static_type_flags(static_type.GetTypeInfo());
-
- TypeAndOrName ret(type_and_or_name);
- if (type_and_or_name.HasType())
- {
- // The type will always be the type of the dynamic object. If our parent's type was a pointer,
- // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
- // should be okay...
- CompilerType orig_type = type_and_or_name.GetCompilerType();
- CompilerType corrected_type = orig_type;
- if (static_type_flags.AllSet(eTypeIsPointer))
- corrected_type = orig_type.GetPointerType ();
- ret.SetCompilerType(corrected_type);
- }
- else
- {
- // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
- std::string corrected_name (type_and_or_name.GetName().GetCString());
- if (static_type_flags.AllSet(eTypeIsPointer))
- corrected_name.append(" *");
- // the parent type should be a correctly pointer'ed or referenc'ed type
- ret.SetCompilerType(static_type);
- ret.SetName(corrected_name.c_str());
- }
- return ret;
+AppleObjCRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) {
+ CompilerType static_type(static_value.GetCompilerType());
+ Flags static_type_flags(static_type.GetTypeInfo());
+
+ TypeAndOrName ret(type_and_or_name);
+ if (type_and_or_name.HasType()) {
+ // The type will always be the type of the dynamic object. If our parent's
+ // type was a pointer,
+ // then our type should be a pointer to the type of the dynamic object. If
+ // a reference, then the original type
+ // should be okay...
+ CompilerType orig_type = type_and_or_name.GetCompilerType();
+ CompilerType corrected_type = orig_type;
+ if (static_type_flags.AllSet(eTypeIsPointer))
+ corrected_type = orig_type.GetPointerType();
+ ret.SetCompilerType(corrected_type);
+ } else {
+ // If we are here we need to adjust our dynamic type name to include the
+ // correct & or * symbol
+ std::string corrected_name(type_and_or_name.GetName().GetCString());
+ if (static_type_flags.AllSet(eTypeIsPointer))
+ corrected_name.append(" *");
+ // the parent type should be a correctly pointer'ed or referenc'ed type
+ ret.SetCompilerType(static_type);
+ ret.SetName(corrected_name.c_str());
+ }
+ return ret;
}
-bool
-AppleObjCRuntime::AppleIsModuleObjCLibrary (const ModuleSP &module_sp)
-{
- if (module_sp)
- {
- const FileSpec &module_file_spec = module_sp->GetFileSpec();
- static ConstString ObjCName ("libobjc.A.dylib");
-
- if (module_file_spec)
- {
- if (module_file_spec.GetFilename() == ObjCName)
- return true;
- }
+bool AppleObjCRuntime::AppleIsModuleObjCLibrary(const ModuleSP &module_sp) {
+ if (module_sp) {
+ const FileSpec &module_file_spec = module_sp->GetFileSpec();
+ static ConstString ObjCName("libobjc.A.dylib");
+
+ if (module_file_spec) {
+ if (module_file_spec.GetFilename() == ObjCName)
+ return true;
}
- return false;
+ }
+ return false;
}
-// we use the version of Foundation to make assumptions about the ObjC runtime on a target
-uint32_t
-AppleObjCRuntime::GetFoundationVersion ()
-{
- if (!m_Foundation_major.hasValue())
- {
- const ModuleList& modules = m_process->GetTarget().GetImages();
- uint32_t major = UINT32_MAX;
- for (uint32_t idx = 0; idx < modules.GetSize(); idx++)
- {
- lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx);
- if (!module_sp)
- continue;
- if (strcmp(module_sp->GetFileSpec().GetFilename().AsCString(""),"Foundation") == 0)
- {
- module_sp->GetVersion(&major,1);
- m_Foundation_major = major;
- return major;
- }
- }
- return LLDB_INVALID_MODULE_VERSION;
+// we use the version of Foundation to make assumptions about the ObjC runtime
+// on a target
+uint32_t AppleObjCRuntime::GetFoundationVersion() {
+ if (!m_Foundation_major.hasValue()) {
+ const ModuleList &modules = m_process->GetTarget().GetImages();
+ uint32_t major = UINT32_MAX;
+ for (uint32_t idx = 0; idx < modules.GetSize(); idx++) {
+ lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx);
+ if (!module_sp)
+ continue;
+ if (strcmp(module_sp->GetFileSpec().GetFilename().AsCString(""),
+ "Foundation") == 0) {
+ module_sp->GetVersion(&major, 1);
+ m_Foundation_major = major;
+ return major;
+ }
}
- else
- return m_Foundation_major.getValue();
+ return LLDB_INVALID_MODULE_VERSION;
+ } else
+ return m_Foundation_major.getValue();
}
-bool
-AppleObjCRuntime::IsModuleObjCLibrary (const ModuleSP &module_sp)
-{
- return AppleIsModuleObjCLibrary(module_sp);
+void AppleObjCRuntime::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
+ lldb::addr_t &cf_false) {
+ cf_true = cf_false = LLDB_INVALID_ADDRESS;
}
-bool
-AppleObjCRuntime::ReadObjCLibrary (const ModuleSP &module_sp)
-{
- // Maybe check here and if we have a handler already, and the UUID of this module is the same as the one in the
- // current module, then we don't have to reread it?
- m_objc_trampoline_handler_ap.reset(new AppleObjCTrampolineHandler (m_process->shared_from_this(), module_sp));
- if (m_objc_trampoline_handler_ap.get() != NULL)
- {
- m_read_objc_library = true;
- return true;
- }
- else
- return false;
+bool AppleObjCRuntime::IsModuleObjCLibrary(const ModuleSP &module_sp) {
+ return AppleIsModuleObjCLibrary(module_sp);
}
-ThreadPlanSP
-AppleObjCRuntime::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- ThreadPlanSP thread_plan_sp;
- if (m_objc_trampoline_handler_ap.get())
- thread_plan_sp = m_objc_trampoline_handler_ap->GetStepThroughDispatchPlan (thread, stop_others);
- return thread_plan_sp;
+bool AppleObjCRuntime::ReadObjCLibrary(const ModuleSP &module_sp) {
+ // Maybe check here and if we have a handler already, and the UUID of this
+ // module is the same as the one in the
+ // current module, then we don't have to reread it?
+ m_objc_trampoline_handler_ap.reset(
+ new AppleObjCTrampolineHandler(m_process->shared_from_this(), module_sp));
+ if (m_objc_trampoline_handler_ap.get() != NULL) {
+ m_read_objc_library = true;
+ return true;
+ } else
+ return false;
+}
+
+ThreadPlanSP AppleObjCRuntime::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) {
+ ThreadPlanSP thread_plan_sp;
+ if (m_objc_trampoline_handler_ap.get())
+ thread_plan_sp = m_objc_trampoline_handler_ap->GetStepThroughDispatchPlan(
+ thread, stop_others);
+ return thread_plan_sp;
}
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
ObjCLanguageRuntime::ObjCRuntimeVersions
-AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp)
-{
- if (!process)
- return ObjCRuntimeVersions::eObjC_VersionUnknown;
+AppleObjCRuntime::GetObjCVersion(Process *process, ModuleSP &objc_module_sp) {
+ if (!process)
+ return ObjCRuntimeVersions::eObjC_VersionUnknown;
+
+ Target &target = process->GetTarget();
+ if (target.GetArchitecture().GetTriple().getVendor() !=
+ llvm::Triple::VendorType::Apple)
+ return ObjCRuntimeVersions::eObjC_VersionUnknown;
- Target &target = process->GetTarget();
- if (target.GetArchitecture().GetTriple().getVendor() != llvm::Triple::VendorType::Apple)
+ const ModuleList &target_modules = target.GetImages();
+ std::lock_guard<std::recursive_mutex> gaurd(target_modules.GetMutex());
+
+ size_t num_images = target_modules.GetSize();
+ for (size_t i = 0; i < num_images; i++) {
+ ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+ // One tricky bit here is that we might get called as part of the initial
+ // module loading, but
+ // before all the pre-run libraries get winnowed from the module list. So
+ // there might actually
+ // be an old and incorrect ObjC library sitting around in the list, and we
+ // don't want to look at that.
+ // That's why we call IsLoadedInTarget.
+
+ if (AppleIsModuleObjCLibrary(module_sp) &&
+ module_sp->IsLoadedInTarget(&target)) {
+ objc_module_sp = module_sp;
+ ObjectFile *ofile = module_sp->GetObjectFile();
+ if (!ofile)
return ObjCRuntimeVersions::eObjC_VersionUnknown;
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> gaurd(target_modules.GetMutex());
-
- size_t num_images = target_modules.GetSize();
- for (size_t i = 0; i < num_images; i++)
- {
- ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
- // One tricky bit here is that we might get called as part of the initial module loading, but
- // before all the pre-run libraries get winnowed from the module list. So there might actually
- // be an old and incorrect ObjC library sitting around in the list, and we don't want to look at that.
- // That's why we call IsLoadedInTarget.
-
- if (AppleIsModuleObjCLibrary (module_sp) && module_sp->IsLoadedInTarget(&target))
- {
- objc_module_sp = module_sp;
- ObjectFile *ofile = module_sp->GetObjectFile();
- if (!ofile)
- return ObjCRuntimeVersions::eObjC_VersionUnknown;
-
- SectionList *sections = module_sp->GetSectionList();
- if (!sections)
- return ObjCRuntimeVersions::eObjC_VersionUnknown;
- SectionSP v1_telltale_section_sp = sections->FindSectionByName(ConstString ("__OBJC"));
- if (v1_telltale_section_sp)
- {
- return ObjCRuntimeVersions::eAppleObjC_V1;
- }
- return ObjCRuntimeVersions::eAppleObjC_V2;
- }
+ SectionList *sections = module_sp->GetSectionList();
+ if (!sections)
+ return ObjCRuntimeVersions::eObjC_VersionUnknown;
+ SectionSP v1_telltale_section_sp =
+ sections->FindSectionByName(ConstString("__OBJC"));
+ if (v1_telltale_section_sp) {
+ return ObjCRuntimeVersions::eAppleObjC_V1;
+ }
+ return ObjCRuntimeVersions::eAppleObjC_V2;
}
-
- return ObjCRuntimeVersions::eObjC_VersionUnknown;
+ }
+
+ return ObjCRuntimeVersions::eObjC_VersionUnknown;
}
-void
-AppleObjCRuntime::SetExceptionBreakpoints ()
-{
- const bool catch_bp = false;
- const bool throw_bp = true;
- const bool is_internal = true;
-
- if (!m_objc_exception_bp_sp)
- {
- m_objc_exception_bp_sp = LanguageRuntime::CreateExceptionBreakpoint (m_process->GetTarget(),
- GetLanguageType(),
- catch_bp,
- throw_bp,
- is_internal);
- if (m_objc_exception_bp_sp)
- m_objc_exception_bp_sp->SetBreakpointKind("ObjC exception");
- }
- else
- m_objc_exception_bp_sp->SetEnabled(true);
+void AppleObjCRuntime::SetExceptionBreakpoints() {
+ const bool catch_bp = false;
+ const bool throw_bp = true;
+ const bool is_internal = true;
+
+ if (!m_objc_exception_bp_sp) {
+ m_objc_exception_bp_sp = LanguageRuntime::CreateExceptionBreakpoint(
+ m_process->GetTarget(), GetLanguageType(), catch_bp, throw_bp,
+ is_internal);
+ if (m_objc_exception_bp_sp)
+ m_objc_exception_bp_sp->SetBreakpointKind("ObjC exception");
+ } else
+ m_objc_exception_bp_sp->SetEnabled(true);
}
+void AppleObjCRuntime::ClearExceptionBreakpoints() {
+ if (!m_process)
+ return;
-void
-AppleObjCRuntime::ClearExceptionBreakpoints ()
-{
- if (!m_process)
- return;
-
- if (m_objc_exception_bp_sp.get())
- {
- m_objc_exception_bp_sp->SetEnabled (false);
- }
+ if (m_objc_exception_bp_sp.get()) {
+ m_objc_exception_bp_sp->SetEnabled(false);
+ }
}
-bool
-AppleObjCRuntime::ExceptionBreakpointsAreSet ()
-{
- return m_objc_exception_bp_sp && m_objc_exception_bp_sp->IsEnabled();
+bool AppleObjCRuntime::ExceptionBreakpointsAreSet() {
+ return m_objc_exception_bp_sp && m_objc_exception_bp_sp->IsEnabled();
}
-bool
-AppleObjCRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
-{
- if (!m_process)
- return false;
-
- if (!stop_reason ||
- stop_reason->GetStopReason() != eStopReasonBreakpoint)
- return false;
-
- uint64_t break_site_id = stop_reason->GetValue();
- return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint (break_site_id,
- m_objc_exception_bp_sp->GetID());
+bool AppleObjCRuntime::ExceptionBreakpointsExplainStop(
+ lldb::StopInfoSP stop_reason) {
+ if (!m_process)
+ return false;
+
+ if (!stop_reason || stop_reason->GetStopReason() != eStopReasonBreakpoint)
+ return false;
+
+ uint64_t break_site_id = stop_reason->GetValue();
+ return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(
+ break_site_id, m_objc_exception_bp_sp->GetID());
}
-bool
-AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing()
-{
- if (!m_process)
- return false;
-
- Target &target(m_process->GetTarget());
-
- static ConstString s_method_signature("-[NSDictionary objectForKeyedSubscript:]");
- static ConstString s_arclite_method_signature("__arclite_objectForKeyedSubscript");
-
- 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;
+bool AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing() {
+ if (!m_process)
+ return false;
+
+ Target &target(m_process->GetTarget());
+
+ static ConstString s_method_signature(
+ "-[NSDictionary objectForKeyedSubscript:]");
+ static ConstString s_arclite_method_signature(
+ "__arclite_objectForKeyedSubscript");
+
+ 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;
}
-lldb::SearchFilterSP
-AppleObjCRuntime::CreateExceptionSearchFilter ()
-{
- Target &target = m_process->GetTarget();
-
- if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
- {
- FileSpecList filter_modules;
- filter_modules.Append(FileSpec("libobjc.A.dylib", false));
- return target.GetSearchFilterForModuleList(&filter_modules);
- }
- else
- {
- return LanguageRuntime::CreateExceptionSearchFilter();
- }
+lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() {
+ Target &target = m_process->GetTarget();
+
+ if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
+ FileSpecList filter_modules;
+ filter_modules.Append(FileSpec("libobjc.A.dylib", false));
+ return target.GetSearchFilterForModuleList(&filter_modules);
+ } else {
+ return LanguageRuntime::CreateExceptionSearchFilter();
+ }
}
-void
-AppleObjCRuntime::ReadObjCLibraryIfNeeded (const ModuleList &module_list)
-{
- if (!HasReadObjCLibrary ())
- {
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
-
- size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; i++)
- {
- auto mod = module_list.GetModuleAtIndex (i);
- if (IsModuleObjCLibrary (mod))
- {
- ReadObjCLibrary (mod);
- break;
- }
- }
+void AppleObjCRuntime::ReadObjCLibraryIfNeeded(const ModuleList &module_list) {
+ if (!HasReadObjCLibrary()) {
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+
+ size_t num_modules = module_list.GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ auto mod = module_list.GetModuleAtIndex(i);
+ if (IsModuleObjCLibrary(mod)) {
+ ReadObjCLibrary(mod);
+ break;
+ }
}
+ }
}
-void
-AppleObjCRuntime::ModulesDidLoad (const ModuleList &module_list)
-{
- ReadObjCLibraryIfNeeded (module_list);
+void AppleObjCRuntime::ModulesDidLoad(const ModuleList &module_list) {
+ ReadObjCLibraryIfNeeded(module_list);
}
-
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index 342824e79b1f..57d98fbd7283 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -16,133 +16,112 @@
#include "llvm/ADT/Optional.h"
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "AppleObjCTrampolineHandler.h"
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class AppleObjCRuntime :
- public lldb_private::ObjCLanguageRuntime
-{
+
+class AppleObjCRuntime : public lldb_private::ObjCLanguageRuntime {
public:
- ~AppleObjCRuntime() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- // Note there is no CreateInstance, Initialize & Terminate functions here, because
- // you can't make an instance of this generic runtime.
-
- static bool classof(const ObjCLanguageRuntime* runtime)
- {
- switch (runtime->GetRuntimeVersion())
- {
- case ObjCRuntimeVersions::eAppleObjC_V1:
- case ObjCRuntimeVersions::eAppleObjC_V2:
- return true;
- default:
- return false;
- }
- }
-
- // These are generic runtime functions:
- bool
- GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) override;
-
- bool
- GetObjectDescription (Stream &str, ValueObject &object) 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;
-
- TypeAndOrName
- FixUpDynamicType (const TypeAndOrName& type_and_or_name,
- ValueObject& static_value) override;
-
- // These are the ObjC specific functions.
-
- bool
- IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) override;
-
- bool
- ReadObjCLibrary (const lldb::ModuleSP &module_sp) override;
-
- bool
- HasReadObjCLibrary () override
- {
- return m_read_objc_library;
+ ~AppleObjCRuntime() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ // Note there is no CreateInstance, Initialize & Terminate functions here,
+ // because
+ // you can't make an instance of this generic runtime.
+
+ static bool classof(const ObjCLanguageRuntime *runtime) {
+ switch (runtime->GetRuntimeVersion()) {
+ case ObjCRuntimeVersions::eAppleObjC_V1:
+ case ObjCRuntimeVersions::eAppleObjC_V2:
+ return true;
+ default:
+ return false;
}
-
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) override;
-
- // Get the "libobjc.A.dylib" module from the current target if we can find
- // it, also cache it once it is found to ensure quick lookups.
- lldb::ModuleSP
- GetObjCModule ();
-
- // Sync up with the target
-
- void
- ModulesDidLoad (const ModuleList &module_list) override;
-
- void
- SetExceptionBreakpoints() override;
-
- void
- ClearExceptionBreakpoints() override;
-
- bool
- ExceptionBreakpointsAreSet() override;
-
- bool
- ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
-
- lldb::SearchFilterSP
- CreateExceptionSearchFilter() override;
-
- uint32_t
- GetFoundationVersion();
-
+ }
+
+ // These are generic runtime functions:
+ bool GetObjectDescription(Stream &str, Value &value,
+ ExecutionContextScope *exe_scope) override;
+
+ bool GetObjectDescription(Stream &str, ValueObject &object) 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;
+
+ TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) override;
+
+ // These are the ObjC specific functions.
+
+ bool IsModuleObjCLibrary(const lldb::ModuleSP &module_sp) override;
+
+ bool ReadObjCLibrary(const lldb::ModuleSP &module_sp) override;
+
+ bool HasReadObjCLibrary() override { return m_read_objc_library; }
+
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) override;
+
+ // Get the "libobjc.A.dylib" module from the current target if we can find
+ // it, also cache it once it is found to ensure quick lookups.
+ lldb::ModuleSP GetObjCModule();
+
+ // Sync up with the target
+
+ void ModulesDidLoad(const ModuleList &module_list) override;
+
+ void SetExceptionBreakpoints() override;
+
+ void ClearExceptionBreakpoints() override;
+
+ bool ExceptionBreakpointsAreSet() override;
+
+ bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
+
+ lldb::SearchFilterSP CreateExceptionSearchFilter() override;
+
+ uint32_t GetFoundationVersion();
+
+ virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
+ lldb::addr_t &cf_false);
+
protected:
- // Call CreateInstance instead.
- AppleObjCRuntime(Process *process);
-
- bool
- CalculateHasNewLiteralsAndIndexing() override;
-
- static bool
- AppleIsModuleObjCLibrary(const lldb::ModuleSP &module_sp);
-
- static ObjCRuntimeVersions
- GetObjCVersion(Process *process, lldb::ModuleSP &objc_module_sp);
-
- void
- ReadObjCLibraryIfNeeded(const ModuleList &module_list);
-
- Address *
- GetPrintForDebuggerAddr();
-
- std::unique_ptr<Address> m_PrintForDebugger_addr;
- bool m_read_objc_library;
- std::unique_ptr<lldb_private::AppleObjCTrampolineHandler> m_objc_trampoline_handler_ap;
- lldb::BreakpointSP m_objc_exception_bp_sp;
- lldb::ModuleWP m_objc_module_wp;
- std::unique_ptr<FunctionCaller> m_print_object_caller_up;
-
- llvm::Optional<uint32_t> m_Foundation_major;
+ // Call CreateInstance instead.
+ AppleObjCRuntime(Process *process);
+
+ bool CalculateHasNewLiteralsAndIndexing() override;
+
+ static bool AppleIsModuleObjCLibrary(const lldb::ModuleSP &module_sp);
+
+ static ObjCRuntimeVersions GetObjCVersion(Process *process,
+ lldb::ModuleSP &objc_module_sp);
+
+ void ReadObjCLibraryIfNeeded(const ModuleList &module_list);
+
+ Address *GetPrintForDebuggerAddr();
+
+ std::unique_ptr<Address> m_PrintForDebugger_addr;
+ bool m_read_objc_library;
+ std::unique_ptr<lldb_private::AppleObjCTrampolineHandler>
+ m_objc_trampoline_handler_ap;
+ lldb::BreakpointSP m_objc_exception_bp_sp;
+ lldb::ModuleWP m_objc_module_wp;
+ std::unique_ptr<FunctionCaller> m_print_object_caller_up;
+
+ llvm::Optional<uint32_t> m_Foundation_major;
};
-
+
} // namespace lldb_private
#endif // liblldb_AppleObjCRuntime_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 805fca7a31b9..13bd245a33b4 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -1,4 +1,5 @@
-//===-- AppleObjCRuntimeV1.cpp --------------------------------------*- C++ -*-===//
+//===-- AppleObjCRuntimeV1.cpp --------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,8 +9,8 @@
//===----------------------------------------------------------------------===//
#include "AppleObjCRuntimeV1.h"
-#include "AppleObjCTrampolineHandler.h"
#include "AppleObjCDeclVendor.h"
+#include "AppleObjCTrampolineHandler.h"
#include "clang/AST/Type.h"
@@ -36,425 +37,403 @@
using namespace lldb;
using namespace lldb_private;
-AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process) :
- AppleObjCRuntime (process),
- m_hash_signature (),
- m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS)
-{
-}
+AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process)
+ : AppleObjCRuntime(process), m_hash_signature(),
+ m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS) {}
-// for V1 runtime we just try to return a class name as that is the minimum level of support
+// for V1 runtime we just try to return a class name as that is the minimum
+// level of support
// required for the data formatters to work
-bool
-AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type)
-{
- class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
- if (CouldHaveDynamicValue(in_value))
- {
- auto class_descriptor(GetClassDescriptor(in_value));
- if (class_descriptor && class_descriptor->IsValid() && class_descriptor->GetClassName())
- {
- const addr_t object_ptr = in_value.GetPointerValue();
- address.SetRawAddress(object_ptr);
- class_type_or_name.SetName(class_descriptor->GetClassName());
- }
+bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) {
+ class_type_or_name.Clear();
+ value_type = Value::ValueType::eValueTypeScalar;
+ if (CouldHaveDynamicValue(in_value)) {
+ auto class_descriptor(GetClassDescriptor(in_value));
+ if (class_descriptor && class_descriptor->IsValid() &&
+ class_descriptor->GetClassName()) {
+ const addr_t object_ptr = in_value.GetPointerValue();
+ address.SetRawAddress(object_ptr);
+ class_type_or_name.SetName(class_descriptor->GetClassName());
}
- return class_type_or_name.IsEmpty() == false;
+ }
+ return class_type_or_name.IsEmpty() == false;
}
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
lldb_private::LanguageRuntime *
-AppleObjCRuntimeV1::CreateInstance (Process *process, lldb::LanguageType language)
-{
- // FIXME: This should be a MacOS or iOS process, and we need to look for the OBJC section to make
- // sure we aren't using the V1 runtime.
- if (language == eLanguageTypeObjC)
- {
- ModuleSP objc_module_sp;
-
- if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == ObjCRuntimeVersions::eAppleObjC_V1)
- return new AppleObjCRuntimeV1 (process);
- else
- return NULL;
- }
+AppleObjCRuntimeV1::CreateInstance(Process *process,
+ lldb::LanguageType language) {
+ // FIXME: This should be a MacOS or iOS process, and we need to look for the
+ // OBJC section to make
+ // sure we aren't using the V1 runtime.
+ if (language == eLanguageTypeObjC) {
+ ModuleSP objc_module_sp;
+
+ if (AppleObjCRuntime::GetObjCVersion(process, objc_module_sp) ==
+ ObjCRuntimeVersions::eAppleObjC_V1)
+ return new AppleObjCRuntimeV1(process);
else
- return NULL;
+ return NULL;
+ } else
+ return NULL;
}
-
-void
-AppleObjCRuntimeV1::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Apple Objective C Language Runtime - Version 1",
- CreateInstance);
+void AppleObjCRuntimeV1::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "Apple Objective C Language Runtime - Version 1",
+ CreateInstance);
}
-void
-AppleObjCRuntimeV1::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void AppleObjCRuntimeV1::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-AppleObjCRuntimeV1::GetPluginNameStatic()
-{
- static ConstString g_name("apple-objc-v1");
- return g_name;
+lldb_private::ConstString AppleObjCRuntimeV1::GetPluginNameStatic() {
+ static ConstString g_name("apple-objc-v1");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-AppleObjCRuntimeV1::GetPluginName()
-{
- return GetPluginNameStatic();
+ConstString AppleObjCRuntimeV1::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-AppleObjCRuntimeV1::GetPluginVersion()
-{
- return 1;
-}
+uint32_t AppleObjCRuntimeV1::GetPluginVersion() { return 1; }
BreakpointResolverSP
-AppleObjCRuntimeV1::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
-{
- BreakpointResolverSP resolver_sp;
-
- if (throw_bp)
- resolver_sp.reset (new BreakpointResolverName (bkpt,
- "objc_exception_throw",
- eFunctionNameTypeBase,
- eLanguageTypeUnknown,
- Breakpoint::Exact,
- 0,
- eLazyBoolNo));
- // FIXME: don't do catch yet.
- return resolver_sp;
+AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
+ bool throw_bp) {
+ BreakpointResolverSP resolver_sp;
+
+ if (throw_bp)
+ resolver_sp.reset(new BreakpointResolverName(
+ bkpt, "objc_exception_throw", eFunctionNameTypeBase,
+ eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo));
+ // FIXME: don't do catch yet.
+ return resolver_sp;
}
struct BufStruct {
- char contents[2048];
+ char contents[2048];
};
-UtilityFunction *
-AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
-{
- std::unique_ptr<BufStruct> buf(new BufStruct);
-
- assert(snprintf(&buf->contents[0], sizeof(buf->contents),
- "struct __objc_class \n"
- "{ \n"
- " struct __objc_class *isa; \n"
- " struct __objc_class *super_class; \n"
- " const char *name; \n"
- " // rest of struct elided because unused \n"
- "}; \n"
- " \n"
- "struct __objc_object \n"
- "{ \n"
- " struct __objc_class *isa; \n"
- "}; \n"
- " \n"
- "extern \"C\" void \n"
- "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) \n"
- "{ \n"
- " struct __objc_object *obj = (struct __objc_object*)$__lldb_arg_obj; \n"
- " (int)strlen(obj->isa->name); \n"
- "} \n",
- name) < (int)sizeof(buf->contents));
-
- Error error;
- return GetTargetRef().GetUtilityFunctionForLanguage(buf->contents, eLanguageTypeObjC, name, error);
+UtilityFunction *AppleObjCRuntimeV1::CreateObjectChecker(const char *name) {
+ std::unique_ptr<BufStruct> buf(new BufStruct);
+
+ assert(snprintf(&buf->contents[0], sizeof(buf->contents),
+ "struct __objc_class "
+ " \n"
+ "{ "
+ " \n"
+ " struct __objc_class *isa; "
+ " \n"
+ " struct __objc_class *super_class; "
+ " \n"
+ " const char *name; "
+ " \n"
+ " // rest of struct elided because unused "
+ " \n"
+ "}; "
+ " \n"
+ " "
+ " \n"
+ "struct __objc_object "
+ " \n"
+ "{ "
+ " \n"
+ " struct __objc_class *isa; "
+ " \n"
+ "}; "
+ " \n"
+ " "
+ " \n"
+ "extern \"C\" void "
+ " \n"
+ "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) "
+ " \n"
+ "{ "
+ " \n"
+ " struct __objc_object *obj = (struct "
+ "__objc_object*)$__lldb_arg_obj; \n"
+ " if ($__lldb_arg_obj == (void *)0) "
+ " \n"
+ " return; // nil is ok "
+ " (int)strlen(obj->isa->name); "
+ " \n"
+ "} "
+ " \n",
+ name) < (int)sizeof(buf->contents));
+
+ Error error;
+ return GetTargetRef().GetUtilityFunctionForLanguage(
+ buf->contents, eLanguageTypeObjC, name, error);
}
-AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ValueObject &isa_pointer)
-{
- Initialize (isa_pointer.GetValueAsUnsigned(0),
- isa_pointer.GetProcessSP());
+AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1(
+ ValueObject &isa_pointer) {
+ Initialize(isa_pointer.GetValueAsUnsigned(0), isa_pointer.GetProcessSP());
}
-AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ObjCISA isa, lldb::ProcessSP process_sp)
-{
- Initialize (isa, process_sp);
+AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1(
+ ObjCISA isa, lldb::ProcessSP process_sp) {
+ Initialize(isa, process_sp);
}
-void
-AppleObjCRuntimeV1::ClassDescriptorV1::Initialize (ObjCISA isa, lldb::ProcessSP process_sp)
-{
- if (!isa || !process_sp)
- {
- m_valid = false;
- return;
- }
-
- m_valid = true;
-
- Error error;
-
- m_isa = process_sp->ReadPointerFromMemory(isa, error);
-
- if (error.Fail())
- {
- m_valid = false;
- return;
- }
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- if (!IsPointerValid(m_isa,ptr_size))
- {
- m_valid = false;
- return;
- }
+void AppleObjCRuntimeV1::ClassDescriptorV1::Initialize(
+ ObjCISA isa, lldb::ProcessSP process_sp) {
+ if (!isa || !process_sp) {
+ m_valid = false;
+ return;
+ }
- m_parent_isa = process_sp->ReadPointerFromMemory(m_isa + ptr_size,error);
-
- if (error.Fail())
- {
- m_valid = false;
- return;
- }
-
- if (!IsPointerValid(m_parent_isa,ptr_size,true))
- {
- m_valid = false;
- return;
- }
-
- lldb::addr_t name_ptr = process_sp->ReadPointerFromMemory(m_isa + 2 * ptr_size,error);
-
- if (error.Fail())
- {
- m_valid = false;
- return;
- }
-
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
-
- size_t count = process_sp->ReadCStringFromMemory(name_ptr, (char*)buffer_sp->GetBytes(), 1024, error);
-
- if (error.Fail())
- {
- m_valid = false;
- return;
- }
-
- if (count)
- m_name = ConstString((char*)buffer_sp->GetBytes());
- else
- m_name = ConstString();
-
- m_instance_size = process_sp->ReadUnsignedIntegerFromMemory(m_isa + 5 * ptr_size, ptr_size, 0, error);
-
- if (error.Fail())
- {
- m_valid = false;
- return;
- }
-
- m_process_wp = lldb::ProcessWP(process_sp);
+ m_valid = true;
+
+ Error error;
+
+ m_isa = process_sp->ReadPointerFromMemory(isa, error);
+
+ if (error.Fail()) {
+ m_valid = false;
+ return;
+ }
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ if (!IsPointerValid(m_isa, ptr_size)) {
+ m_valid = false;
+ return;
+ }
+
+ m_parent_isa = process_sp->ReadPointerFromMemory(m_isa + ptr_size, error);
+
+ if (error.Fail()) {
+ m_valid = false;
+ return;
+ }
+
+ if (!IsPointerValid(m_parent_isa, ptr_size, true)) {
+ m_valid = false;
+ return;
+ }
+
+ lldb::addr_t name_ptr =
+ process_sp->ReadPointerFromMemory(m_isa + 2 * ptr_size, error);
+
+ if (error.Fail()) {
+ m_valid = false;
+ return;
+ }
+
+ lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
+
+ size_t count = process_sp->ReadCStringFromMemory(
+ name_ptr, (char *)buffer_sp->GetBytes(), 1024, error);
+
+ if (error.Fail()) {
+ m_valid = false;
+ return;
+ }
+
+ if (count)
+ m_name = ConstString((char *)buffer_sp->GetBytes());
+ else
+ m_name = ConstString();
+
+ m_instance_size = process_sp->ReadUnsignedIntegerFromMemory(
+ m_isa + 5 * ptr_size, ptr_size, 0, error);
+
+ if (error.Fail()) {
+ m_valid = false;
+ return;
+ }
+
+ m_process_wp = lldb::ProcessWP(process_sp);
}
AppleObjCRuntime::ClassDescriptorSP
-AppleObjCRuntimeV1::ClassDescriptorV1::GetSuperclass ()
-{
- if (!m_valid)
- return AppleObjCRuntime::ClassDescriptorSP();
- ProcessSP process_sp = m_process_wp.lock();
- if (!process_sp)
- return AppleObjCRuntime::ClassDescriptorSP();
- return ObjCLanguageRuntime::ClassDescriptorSP(new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa,process_sp));
+AppleObjCRuntimeV1::ClassDescriptorV1::GetSuperclass() {
+ if (!m_valid)
+ return AppleObjCRuntime::ClassDescriptorSP();
+ ProcessSP process_sp = m_process_wp.lock();
+ if (!process_sp)
+ return AppleObjCRuntime::ClassDescriptorSP();
+ return ObjCLanguageRuntime::ClassDescriptorSP(
+ new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa, process_sp));
}
AppleObjCRuntime::ClassDescriptorSP
-AppleObjCRuntimeV1::ClassDescriptorV1::GetMetaclass () const
-{
- return ClassDescriptorSP();
+AppleObjCRuntimeV1::ClassDescriptorV1::GetMetaclass() const {
+ return ClassDescriptorSP();
}
-bool
-AppleObjCRuntimeV1::ClassDescriptorV1::Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
- std::function <bool (const char *, const char *)> const &instance_method_func,
- std::function <bool (const char *, const char *)> const &class_method_func,
- std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) const
-{
- return false;
+bool AppleObjCRuntimeV1::ClassDescriptorV1::Describe(
+ std::function<void(ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+ std::function<bool(const char *, const char *)> const &instance_method_func,
+ std::function<bool(const char *, const char *)> const &class_method_func,
+ std::function<bool(const char *, const char *, lldb::addr_t,
+ uint64_t)> const &ivar_func) const {
+ return false;
}
-lldb::addr_t
-AppleObjCRuntimeV1::GetISAHashTablePointer ()
-{
- if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
- {
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (!objc_module_sp)
- return LLDB_INVALID_ADDRESS;
-
- static ConstString g_objc_debug_class_hash("_objc_debug_class_hash");
-
- const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_objc_debug_class_hash, lldb::eSymbolTypeData);
- if (symbol && symbol->ValueIsAddress())
- {
- Process *process = GetProcess();
- if (process)
- {
-
- lldb::addr_t objc_debug_class_hash_addr = symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
-
- if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS)
- {
- Error error;
- lldb::addr_t objc_debug_class_hash_ptr = process->ReadPointerFromMemory(objc_debug_class_hash_addr, error);
- if (objc_debug_class_hash_ptr != 0 &&
- objc_debug_class_hash_ptr != LLDB_INVALID_ADDRESS)
- {
- m_isa_hash_table_ptr = objc_debug_class_hash_ptr;
- }
- }
- }
+lldb::addr_t AppleObjCRuntimeV1::GetISAHashTablePointer() {
+ if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) {
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (!objc_module_sp)
+ return LLDB_INVALID_ADDRESS;
+
+ static ConstString g_objc_debug_class_hash("_objc_debug_class_hash");
+
+ const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
+ g_objc_debug_class_hash, lldb::eSymbolTypeData);
+ if (symbol && symbol->ValueIsAddress()) {
+ Process *process = GetProcess();
+ if (process) {
+
+ lldb::addr_t objc_debug_class_hash_addr =
+ symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
+
+ if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS) {
+ Error error;
+ lldb::addr_t objc_debug_class_hash_ptr =
+ process->ReadPointerFromMemory(objc_debug_class_hash_addr, error);
+ if (objc_debug_class_hash_ptr != 0 &&
+ objc_debug_class_hash_ptr != LLDB_INVALID_ADDRESS) {
+ m_isa_hash_table_ptr = objc_debug_class_hash_ptr;
+ }
}
+ }
}
- return m_isa_hash_table_ptr;
+ }
+ return m_isa_hash_table_ptr;
}
-void
-AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded()
-{
- // TODO: implement HashTableSignature...
- Process *process = GetProcess();
-
- if (process)
- {
- // Update the process stop ID that indicates the last time we updated the
- // map, whether it was successful or not.
- m_isa_to_descriptor_stop_id = process->GetStopID();
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- ProcessSP process_sp = process->shared_from_this();
-
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (!objc_module_sp)
- return;
-
- uint32_t isa_count = 0;
-
- lldb::addr_t hash_table_ptr = GetISAHashTablePointer ();
- if (hash_table_ptr != LLDB_INVALID_ADDRESS)
- {
- // Read the NXHashTable struct:
- //
- // typedef struct {
- // const NXHashTablePrototype *prototype;
- // unsigned count;
- // unsigned nbBuckets;
- // void *buckets;
- // const void *info;
- // } NXHashTable;
-
- Error error;
- DataBufferHeap buffer(1024, 0);
- if (process->ReadMemory(hash_table_ptr, buffer.GetBytes(), 20, error) == 20)
- {
- const uint32_t addr_size = m_process->GetAddressByteSize();
- const ByteOrder byte_order = m_process->GetByteOrder();
- DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size);
- lldb::offset_t offset = addr_size; // Skip prototype
- const uint32_t count = data.GetU32(&offset);
- const uint32_t num_buckets = data.GetU32(&offset);
- const addr_t buckets_ptr = data.GetPointer(&offset);
- if (m_hash_signature.NeedsUpdate (count, num_buckets, buckets_ptr))
- {
- m_hash_signature.UpdateSignature (count, num_buckets, buckets_ptr);
-
- const uint32_t data_size = num_buckets * 2 * sizeof(uint32_t);
- buffer.SetByteSize(data_size);
-
- if (process->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size, error) == data_size)
- {
- data.SetData(buffer.GetBytes(), buffer.GetByteSize(), byte_order);
- offset = 0;
- for (uint32_t bucket_idx = 0; bucket_idx < num_buckets; ++bucket_idx)
- {
- const uint32_t bucket_isa_count = data.GetU32 (&offset);
- const lldb::addr_t bucket_data = data.GetU32 (&offset);
-
-
- if (bucket_isa_count == 0)
- continue;
-
- isa_count += bucket_isa_count;
-
- ObjCISA isa;
- if (bucket_isa_count == 1)
- {
- // When we only have one entry in the bucket, the bucket data is the "isa"
- isa = bucket_data;
- if (isa)
- {
- if (!ISAIsCached(isa))
- {
- ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
-
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
-
- AddClass (isa, descriptor_sp);
- }
- }
- }
- else
- {
- // When we have more than one entry in the bucket, the bucket data is a pointer
- // to an array of "isa" values
- addr_t isa_addr = bucket_data;
- for (uint32_t isa_idx = 0; isa_idx < bucket_isa_count; ++isa_idx, isa_addr += addr_size)
- {
- isa = m_process->ReadPointerFromMemory(isa_addr, error);
-
- if (isa && isa != LLDB_INVALID_ADDRESS)
- {
- if (!ISAIsCached(isa))
- {
- ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
-
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
-
- AddClass (isa, descriptor_sp);
- }
- }
- }
- }
- }
+void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
+ // TODO: implement HashTableSignature...
+ Process *process = GetProcess();
+
+ if (process) {
+ // Update the process stop ID that indicates the last time we updated the
+ // map, whether it was successful or not.
+ m_isa_to_descriptor_stop_id = process->GetStopID();
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ ProcessSP process_sp = process->shared_from_this();
+
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (!objc_module_sp)
+ return;
+
+ uint32_t isa_count = 0;
+
+ lldb::addr_t hash_table_ptr = GetISAHashTablePointer();
+ if (hash_table_ptr != LLDB_INVALID_ADDRESS) {
+ // Read the NXHashTable struct:
+ //
+ // typedef struct {
+ // const NXHashTablePrototype *prototype;
+ // unsigned count;
+ // unsigned nbBuckets;
+ // void *buckets;
+ // const void *info;
+ // } NXHashTable;
+
+ Error error;
+ DataBufferHeap buffer(1024, 0);
+ if (process->ReadMemory(hash_table_ptr, buffer.GetBytes(), 20, error) ==
+ 20) {
+ const uint32_t addr_size = m_process->GetAddressByteSize();
+ const ByteOrder byte_order = m_process->GetByteOrder();
+ DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(), byte_order,
+ addr_size);
+ lldb::offset_t offset = addr_size; // Skip prototype
+ const uint32_t count = data.GetU32(&offset);
+ const uint32_t num_buckets = data.GetU32(&offset);
+ const addr_t buckets_ptr = data.GetPointer(&offset);
+ if (m_hash_signature.NeedsUpdate(count, num_buckets, buckets_ptr)) {
+ m_hash_signature.UpdateSignature(count, num_buckets, buckets_ptr);
+
+ const uint32_t data_size = num_buckets * 2 * sizeof(uint32_t);
+ buffer.SetByteSize(data_size);
+
+ if (process->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size,
+ error) == data_size) {
+ data.SetData(buffer.GetBytes(), buffer.GetByteSize(), byte_order);
+ offset = 0;
+ for (uint32_t bucket_idx = 0; bucket_idx < num_buckets;
+ ++bucket_idx) {
+ const uint32_t bucket_isa_count = data.GetU32(&offset);
+ const lldb::addr_t bucket_data = data.GetU32(&offset);
+
+ if (bucket_isa_count == 0)
+ continue;
+
+ isa_count += bucket_isa_count;
+
+ ObjCISA isa;
+ if (bucket_isa_count == 1) {
+ // When we only have one entry in the bucket, the bucket data is
+ // the "isa"
+ isa = bucket_data;
+ if (isa) {
+ if (!ISAIsCached(isa)) {
+ ClassDescriptorSP descriptor_sp(
+ new ClassDescriptorV1(isa, process_sp));
+
+ if (log && log->GetVerbose())
+ log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
+ " from _objc_debug_class_hash to "
+ "isa->descriptor cache",
+ isa);
+
+ AddClass(isa, descriptor_sp);
+ }
+ }
+ } else {
+ // When we have more than one entry in the bucket, the bucket
+ // data is a pointer
+ // to an array of "isa" values
+ addr_t isa_addr = bucket_data;
+ for (uint32_t isa_idx = 0; isa_idx < bucket_isa_count;
+ ++isa_idx, isa_addr += addr_size) {
+ isa = m_process->ReadPointerFromMemory(isa_addr, error);
+
+ if (isa && isa != LLDB_INVALID_ADDRESS) {
+ if (!ISAIsCached(isa)) {
+ ClassDescriptorSP descriptor_sp(
+ new ClassDescriptorV1(isa, process_sp));
+
+ if (log && log->GetVerbose())
+ log->Printf(
+ "AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
+ " from _objc_debug_class_hash to isa->descriptor "
+ "cache",
+ isa);
+
+ AddClass(isa, descriptor_sp);
}
+ }
}
+ }
}
- }
- }
- else
- {
- m_isa_to_descriptor_stop_id = UINT32_MAX;
+ }
+ }
+ }
}
+ } else {
+ m_isa_to_descriptor_stop_id = UINT32_MAX;
+ }
}
-DeclVendor *
-AppleObjCRuntimeV1::GetDeclVendor()
-{
- if (!m_decl_vendor_ap.get())
- m_decl_vendor_ap.reset(new AppleObjCDeclVendor(*this));
-
- return m_decl_vendor_ap.get();
+DeclVendor *AppleObjCRuntimeV1::GetDeclVendor() {
+ return nullptr;
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index 9f9fcc69b682..3dddf1b094e1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -14,194 +14,148 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "AppleObjCRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class AppleObjCRuntimeV1 :
- public AppleObjCRuntime
-{
+
+class AppleObjCRuntimeV1 : public AppleObjCRuntime {
public:
- ~AppleObjCRuntimeV1() 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();
-
- static bool classof(const ObjCLanguageRuntime* runtime)
- {
- switch (runtime->GetRuntimeVersion())
- {
- case ObjCRuntimeVersions::eAppleObjC_V1:
- return true;
- default:
- return false;
- }
+ ~AppleObjCRuntimeV1() 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();
+
+ static bool classof(const ObjCLanguageRuntime *runtime) {
+ switch (runtime->GetRuntimeVersion()) {
+ case ObjCRuntimeVersions::eAppleObjC_V1:
+ return true;
+ default:
+ return false;
}
-
- class ClassDescriptorV1 : public ObjCLanguageRuntime::ClassDescriptor
- {
- public:
- ClassDescriptorV1 (ValueObject &isa_pointer);
- ClassDescriptorV1 (ObjCISA isa, lldb::ProcessSP process_sp);
-
- ~ClassDescriptorV1() override = default;
-
- ConstString
- GetClassName() override
- {
- return m_name;
- }
-
- ClassDescriptorSP
- GetSuperclass() override;
-
- ClassDescriptorSP
- GetMetaclass() const override;
-
- bool
- IsValid() override
- {
- return m_valid;
- }
-
- // v1 does not support tagged pointers
- bool
- GetTaggedPointerInfo(uint64_t* info_bits = nullptr,
- uint64_t* value_bits = nullptr,
- uint64_t* payload = nullptr) override
- {
- return false;
- }
-
- uint64_t
- GetInstanceSize() override
- {
- return m_instance_size;
- }
-
- ObjCISA
- GetISA() override
- {
- return m_isa;
- }
-
- bool
- Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
- std::function <bool (const char *, const char *)> const &instance_method_func,
- std::function <bool (const char *, const char *)> const &class_method_func,
- std::function <bool (const char *, const char *,
- lldb::addr_t, uint64_t)> const &ivar_func) const override;
-
- protected:
- void
- Initialize (ObjCISA isa, lldb::ProcessSP process_sp);
-
- private:
- ConstString m_name;
- ObjCISA m_isa;
- ObjCISA m_parent_isa;
- bool m_valid;
- lldb::ProcessWP m_process_wp;
- uint64_t m_instance_size;
- };
-
- // These are generic runtime functions:
- bool
- GetDynamicTypeAndAddress(ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
-
- UtilityFunction *
- CreateObjectChecker(const char *) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- ObjCRuntimeVersions
- GetRuntimeVersion() const override
- {
- return ObjCRuntimeVersions::eAppleObjC_V1;
+ }
+
+ class ClassDescriptorV1 : public ObjCLanguageRuntime::ClassDescriptor {
+ public:
+ ClassDescriptorV1(ValueObject &isa_pointer);
+ ClassDescriptorV1(ObjCISA isa, lldb::ProcessSP process_sp);
+
+ ~ClassDescriptorV1() override = default;
+
+ ConstString GetClassName() override { return m_name; }
+
+ ClassDescriptorSP GetSuperclass() override;
+
+ ClassDescriptorSP GetMetaclass() const override;
+
+ bool IsValid() override { return m_valid; }
+
+ // v1 does not support tagged pointers
+ bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
+ uint64_t *value_bits = nullptr,
+ uint64_t *payload = nullptr) override {
+ return false;
}
-
- void
- UpdateISAToDescriptorMapIfNeeded() override;
-
- DeclVendor *
- GetDeclVendor() override;
+
+ uint64_t GetInstanceSize() override { return m_instance_size; }
+
+ ObjCISA GetISA() override { return m_isa; }
+
+ bool
+ Describe(std::function<void(ObjCLanguageRuntime::ObjCISA)> const
+ &superclass_func,
+ std::function<bool(const char *, const char *)> const
+ &instance_method_func,
+ std::function<bool(const char *, const char *)> const
+ &class_method_func,
+ std::function<bool(const char *, const char *, lldb::addr_t,
+ uint64_t)> const &ivar_func) const override;
+
+ protected:
+ void Initialize(ObjCISA isa, lldb::ProcessSP process_sp);
+
+ private:
+ ConstString m_name;
+ ObjCISA m_isa;
+ ObjCISA m_parent_isa;
+ bool m_valid;
+ lldb::ProcessWP m_process_wp;
+ uint64_t m_instance_size;
+ };
+
+ // These are generic runtime functions:
+ bool GetDynamicTypeAndAddress(ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address,
+ Value::ValueType &value_type) override;
+
+ UtilityFunction *CreateObjectChecker(const char *) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ ObjCRuntimeVersions GetRuntimeVersion() const override {
+ return ObjCRuntimeVersions::eAppleObjC_V1;
+ }
+
+ void UpdateISAToDescriptorMapIfNeeded() override;
+
+ DeclVendor *GetDeclVendor() override;
protected:
- lldb::BreakpointResolverSP
- CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
-
- class HashTableSignature
- {
- public:
- HashTableSignature () :
- m_count (0),
- m_num_buckets (0),
- m_buckets_ptr (LLDB_INVALID_ADDRESS)
- {
- }
-
- bool
- NeedsUpdate (uint32_t count,
- uint32_t num_buckets,
- lldb::addr_t buckets_ptr)
- {
- return m_count != count ||
- m_num_buckets != num_buckets ||
- m_buckets_ptr != buckets_ptr ;
- }
-
- void
- UpdateSignature (uint32_t count,
- uint32_t num_buckets,
- lldb::addr_t buckets_ptr)
- {
- m_count = count;
- m_num_buckets = num_buckets;
- m_buckets_ptr = buckets_ptr;
- }
-
- protected:
- uint32_t m_count;
- uint32_t m_num_buckets;
- lldb::addr_t m_buckets_ptr;
- };
-
- lldb::addr_t
- GetISAHashTablePointer ();
-
- HashTableSignature m_hash_signature;
- lldb::addr_t m_isa_hash_table_ptr;
- std::unique_ptr<DeclVendor> m_decl_vendor_ap;
+ lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
+ bool catch_bp,
+ bool throw_bp) override;
+
+ class HashTableSignature {
+ public:
+ HashTableSignature()
+ : m_count(0), m_num_buckets(0), m_buckets_ptr(LLDB_INVALID_ADDRESS) {}
+
+ bool NeedsUpdate(uint32_t count, uint32_t num_buckets,
+ lldb::addr_t buckets_ptr) {
+ return m_count != count || m_num_buckets != num_buckets ||
+ m_buckets_ptr != buckets_ptr;
+ }
+
+ void UpdateSignature(uint32_t count, uint32_t num_buckets,
+ lldb::addr_t buckets_ptr) {
+ m_count = count;
+ m_num_buckets = num_buckets;
+ m_buckets_ptr = buckets_ptr;
+ }
+
+ protected:
+ uint32_t m_count;
+ uint32_t m_num_buckets;
+ lldb::addr_t m_buckets_ptr;
+ };
+
+ lldb::addr_t GetISAHashTablePointer();
+
+ HashTableSignature m_hash_signature;
+ lldb::addr_t m_isa_hash_table_ptr;
+ std::unique_ptr<DeclVendor> m_decl_vendor_ap;
private:
- AppleObjCRuntimeV1(Process *process);
+ AppleObjCRuntimeV1(Process *process);
};
-
+
} // namespace lldb_private
#endif // liblldb_AppleObjCRuntimeV1_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index e9a799bb3651..e9958a5ef759 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -19,9 +19,9 @@
#include "clang/AST/DeclObjC.h"
// Project includes
-#include "lldb/lldb-enumerations.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-enumerations.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
@@ -56,21 +56,22 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "AppleObjCRuntimeV2.h"
#include "AppleObjCClassDescriptorV2.h"
-#include "AppleObjCTypeEncodingParser.h"
#include "AppleObjCDeclVendor.h"
+#include "AppleObjCRuntimeV2.h"
#include "AppleObjCTrampolineHandler.h"
-
+#include "AppleObjCTypeEncodingParser.h"
using namespace lldb;
using namespace lldb_private;
// 2 second timeout when running utility functions
-#define UTILITY_FUNCTION_TIMEOUT_USEC 2*1000*1000
+static constexpr std::chrono::seconds g_utility_function_timeout(2);
-static const char *g_get_dynamic_class_info_name = "__lldb_apple_objc_v2_get_dynamic_class_info";
-// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+static const char *g_get_dynamic_class_info_name =
+ "__lldb_apple_objc_v2_get_dynamic_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we
+// will
// need to revert to the code above...
static const char *g_get_dynamic_class_info_body = R"(
@@ -152,8 +153,10 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr
)";
-static const char *g_get_shared_cache_class_info_name = "__lldb_apple_objc_v2_get_shared_cache_class_info";
-// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+static const char *g_get_shared_cache_class_info_name =
+ "__lldb_apple_objc_v2_get_shared_cache_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we
+// will
// need to revert to the code above...
static const char *g_get_shared_cache_class_info_body = R"(
@@ -334,2187 +337,2112 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
)";
static uint64_t
-ExtractRuntimeGlobalSymbol (Process* process,
- ConstString name,
- const ModuleSP &module_sp,
- Error& error,
- bool read_value = true,
- uint8_t byte_size = 0,
- uint64_t default_value = LLDB_INVALID_ADDRESS,
- SymbolType sym_type = lldb::eSymbolTypeData)
-{
- if (!process)
- {
- error.SetErrorString("no process");
- return default_value;
- }
- if (!module_sp)
- {
- error.SetErrorString("no module");
- return default_value;
- }
- if (!byte_size)
- byte_size = process->GetAddressByteSize();
- const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
- if (symbol && symbol->ValueIsAddress())
- {
- lldb::addr_t symbol_load_addr = symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
- if (symbol_load_addr != LLDB_INVALID_ADDRESS)
- {
- if (read_value)
- return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size, default_value, error);
- else
- return symbol_load_addr;
- }
- else
- {
- error.SetErrorString("symbol address invalid");
- return default_value;
- }
- }
- else
- {
- error.SetErrorString("no symbol");
- return default_value;
+ExtractRuntimeGlobalSymbol(Process *process, ConstString name,
+ const ModuleSP &module_sp, Error &error,
+ bool read_value = true, uint8_t byte_size = 0,
+ uint64_t default_value = LLDB_INVALID_ADDRESS,
+ SymbolType sym_type = lldb::eSymbolTypeData) {
+ if (!process) {
+ error.SetErrorString("no process");
+ return default_value;
+ }
+ if (!module_sp) {
+ error.SetErrorString("no module");
+ return default_value;
+ }
+ if (!byte_size)
+ byte_size = process->GetAddressByteSize();
+ const Symbol *symbol =
+ module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
+ if (symbol && symbol->ValueIsAddress()) {
+ lldb::addr_t symbol_load_addr =
+ symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
+ if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
+ if (read_value)
+ return process->ReadUnsignedIntegerFromMemory(
+ symbol_load_addr, byte_size, default_value, error);
+ else
+ return symbol_load_addr;
+ } else {
+ error.SetErrorString("symbol address invalid");
+ return default_value;
}
+ } else {
+ error.SetErrorString("no symbol");
+ return default_value;
+ }
}
-AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, const ModuleSP &objc_module_sp)
- : AppleObjCRuntime(process),
- m_get_class_info_code(),
+AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
+ const ModuleSP &objc_module_sp)
+ : AppleObjCRuntime(process), m_get_class_info_code(),
m_get_class_info_args(LLDB_INVALID_ADDRESS),
- m_get_class_info_args_mutex(),
- m_get_shared_cache_class_info_code(),
+ m_get_class_info_args_mutex(), m_get_shared_cache_class_info_code(),
m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
- m_get_shared_cache_class_info_args_mutex(),
- m_decl_vendor_ap(),
- m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
- m_hash_signature(),
- m_has_object_getClass(false),
- m_loaded_objc_opt(false),
- m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this, objc_module_sp)),
- m_tagged_pointer_vendor_ap(TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
- m_encoding_to_type_sp(),
- m_noclasses_warning_emitted(false)
-{
- static const ConstString g_gdb_object_getClass("gdb_object_getClass");
- m_has_object_getClass =
- (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+ m_get_shared_cache_class_info_args_mutex(), m_decl_vendor_ap(),
+ m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS), m_hash_signature(),
+ m_has_object_getClass(false), m_loaded_objc_opt(false),
+ m_non_pointer_isa_cache_ap(
+ NonPointerISACache::CreateInstance(*this, objc_module_sp)),
+ m_tagged_pointer_vendor_ap(
+ TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
+ m_encoding_to_type_sp(), m_noclasses_warning_emitted(false),
+ m_CFBoolean_values() {
+ static const ConstString g_gdb_object_getClass("gdb_object_getClass");
+ m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(
+ g_gdb_object_getClass, eSymbolTypeCode) != NULL);
}
-bool
-AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
- DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type)
-{
- // We should never get here with a null process...
- assert (m_process != NULL);
-
- // The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
- // Note, however, the process might be NULL (e.g. if the value was made with SBTarget::EvaluateExpression...)
- // in which case it is sufficient if the target's match:
-
- Process *process = in_value.GetProcessSP().get();
- if (process)
- assert (process == m_process);
- else
- assert (in_value.GetTargetSP().get() == m_process->CalculateTarget().get());
-
- class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
-
- // Make sure we can have a dynamic value before starting...
- if (CouldHaveDynamicValue (in_value))
- {
- // First job, pull out the address at 0 offset from the object That will be the ISA pointer.
- ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor (in_value));
- if (objc_class_sp)
- {
- const addr_t object_ptr = in_value.GetPointerValue();
- address.SetRawAddress(object_ptr);
-
- ConstString class_name (objc_class_sp->GetClassName());
- class_type_or_name.SetName(class_name);
- TypeSP type_sp (objc_class_sp->GetType());
- if (type_sp)
- class_type_or_name.SetTypeSP (type_sp);
- else
- {
- type_sp = LookupInCompleteClassCache (class_name);
- if (type_sp)
- {
- objc_class_sp->SetType (type_sp);
- class_type_or_name.SetTypeSP (type_sp);
- }
- else
- {
- // try to go for a CompilerType at least
- DeclVendor* vendor = GetDeclVendor();
- if (vendor)
- {
- std::vector<clang::NamedDecl*> decls;
- if (vendor->FindDecls(class_name, false, 1, decls) && decls.size())
- class_type_or_name.SetCompilerType(ClangASTContext::GetTypeForDecl(decls[0]));
- }
- }
- }
+bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
+ ValueObject &in_value, DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) {
+ // We should never get here with a null process...
+ assert(m_process != NULL);
+
+ // The Runtime is attached to a particular process, you shouldn't pass in a
+ // value from another process.
+ // Note, however, the process might be NULL (e.g. if the value was made with
+ // SBTarget::EvaluateExpression...)
+ // in which case it is sufficient if the target's match:
+
+ Process *process = in_value.GetProcessSP().get();
+ if (process)
+ assert(process == m_process);
+ else
+ assert(in_value.GetTargetSP().get() == m_process->CalculateTarget().get());
+
+ class_type_or_name.Clear();
+ value_type = Value::ValueType::eValueTypeScalar;
+
+ // Make sure we can have a dynamic value before starting...
+ if (CouldHaveDynamicValue(in_value)) {
+ // First job, pull out the address at 0 offset from the object That will be
+ // the ISA pointer.
+ ClassDescriptorSP objc_class_sp(GetNonKVOClassDescriptor(in_value));
+ if (objc_class_sp) {
+ const addr_t object_ptr = in_value.GetPointerValue();
+ address.SetRawAddress(object_ptr);
+
+ ConstString class_name(objc_class_sp->GetClassName());
+ class_type_or_name.SetName(class_name);
+ TypeSP type_sp(objc_class_sp->GetType());
+ if (type_sp)
+ class_type_or_name.SetTypeSP(type_sp);
+ else {
+ type_sp = LookupInCompleteClassCache(class_name);
+ if (type_sp) {
+ objc_class_sp->SetType(type_sp);
+ class_type_or_name.SetTypeSP(type_sp);
+ } else {
+ // try to go for a CompilerType at least
+ DeclVendor *vendor = GetDeclVendor();
+ if (vendor) {
+ std::vector<clang::NamedDecl *> decls;
+ if (vendor->FindDecls(class_name, false, 1, decls) && decls.size())
+ class_type_or_name.SetCompilerType(
+ ClangASTContext::GetTypeForDecl(decls[0]));
+ }
}
- }
- return class_type_or_name.IsEmpty() == false;
+ }
+ }
+ }
+ return class_type_or_name.IsEmpty() == false;
}
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-LanguageRuntime *
-AppleObjCRuntimeV2::CreateInstance (Process *process, LanguageType language)
-{
- // FIXME: This should be a MacOS or iOS process, and we need to look for the OBJC section to make
- // sure we aren't using the V1 runtime.
- if (language == eLanguageTypeObjC)
- {
- ModuleSP objc_module_sp;
-
- if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == ObjCRuntimeVersions::eAppleObjC_V2)
- return new AppleObjCRuntimeV2 (process, objc_module_sp);
- else
- return NULL;
- }
+LanguageRuntime *AppleObjCRuntimeV2::CreateInstance(Process *process,
+ LanguageType language) {
+ // FIXME: This should be a MacOS or iOS process, and we need to look for the
+ // OBJC section to make
+ // sure we aren't using the V1 runtime.
+ if (language == eLanguageTypeObjC) {
+ ModuleSP objc_module_sp;
+
+ if (AppleObjCRuntime::GetObjCVersion(process, objc_module_sp) ==
+ ObjCRuntimeVersions::eAppleObjC_V2)
+ return new AppleObjCRuntimeV2(process, objc_module_sp);
else
- return NULL;
+ return NULL;
+ } else
+ return NULL;
}
-class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- m_verbose(false,false)
- {}
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue(uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- switch (short_option)
- {
- case 'v':
- m_verbose.SetCurrentValue(true);
- m_verbose.SetOptionWasSet();
- break;
-
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting() override
- {
- m_verbose.Clear();
- }
-
- const OptionDefinition*
- GetDefinitions() override
- {
- return g_option_table;
- }
+static OptionDefinition g_objc_classtable_dump_options[] = {
+ {LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument,
+ nullptr, nullptr, 0, eArgTypeNone,
+ "Print ivar and method information in detail"}};
- OptionValueBoolean m_verbose;
- static OptionDefinition g_option_table[];
- };
-
- CommandObjectObjC_ClassTable_Dump (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "dump",
- "Dump information on Objective-C classes known to the current process.",
- "language objc class-table dump",
- eCommandRequiresProcess |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options(interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData index_arg;
-
- // Define the first (and only) variant of this arg.
- index_arg.arg_type = eArgTypeRegularExpression;
- index_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (index_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_verbose(false, false) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'v':
+ m_verbose.SetCurrentValue(true);
+ m_verbose.SetOptionWasSet();
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectObjC_ClassTable_Dump() override = default;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose.Clear();
+ }
- Options *
- GetOptions() override
- {
- return &m_options;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_objc_classtable_dump_options);
}
-
+
+ OptionValueBoolean m_verbose;
+ };
+
+ CommandObjectObjC_ClassTable_Dump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "dump", "Dump information on Objective-C classes "
+ "known to the current process.",
+ "language objc class-table dump",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeRegularExpression;
+ index_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectObjC_ClassTable_Dump() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
protected:
- bool
- DoExecute(Args& command, CommandReturnObject &result) override
- {
- std::unique_ptr<RegularExpression> regex_up;
- switch(command.GetArgumentCount())
- {
- case 0:
- break;
- case 1:
- {
- regex_up.reset(new RegularExpression());
- if (!regex_up->Compile(command.GetArgumentAtIndex(0)))
- {
- result.AppendError("invalid argument - please provide a valid regular expression");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- break;
- }
- default:
- {
- result.AppendError("please provide 0 or 1 arguments");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- }
-
- Process *process = m_exe_ctx.GetProcessPtr();
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime)
- {
- auto iterators_pair = objc_runtime->GetDescriptorIteratorPair();
- auto iterator = iterators_pair.first;
- auto &std_out = result.GetOutputStream();
- for(; iterator != iterators_pair.second; iterator++)
- {
- if (iterator->second)
- {
- const char* class_name = iterator->second->GetClassName().AsCString("<unknown>");
- if (regex_up && class_name && !regex_up->Execute(class_name))
- continue;
- std_out.Printf("isa = 0x%" PRIx64, iterator->first);
- std_out.Printf(" name = %s", class_name);
- std_out.Printf(" instance size = %" PRIu64, iterator->second->GetInstanceSize());
- std_out.Printf(" num ivars = %" PRIuPTR, (uintptr_t)iterator->second->GetNumIVars());
- if (auto superclass = iterator->second->GetSuperclass())
- {
- std_out.Printf(" superclass = %s", superclass->GetClassName().AsCString("<unknown>"));
- }
- std_out.Printf("\n");
- if (m_options.m_verbose)
- {
- for(size_t i = 0;
- i < iterator->second->GetNumIVars();
- i++)
- {
- auto ivar = iterator->second->GetIVarAtIndex(i);
- std_out.Printf(" ivar name = %s type = %s size = %" PRIu64 " offset = %" PRId32 "\n",
- ivar.m_name.AsCString("<unknown>"),
- ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
- ivar.m_size,
- ivar.m_offset);
- }
- iterator->second->Describe(nullptr,
- [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
- std_out.Printf(" instance method name = %s type = %s\n",
- name,
- type);
- return false;
- },
- [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
- std_out.Printf(" class method name = %s type = %s\n",
- name,
- type);
- return false;
- },
- nullptr);
- }
- }
- else
- {
- if (regex_up && !regex_up->Execute(""))
- continue;
- std_out.Printf("isa = 0x%" PRIx64 " has no associated class.\n", iterator->first);
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ std::unique_ptr<RegularExpression> regex_up;
+ switch (command.GetArgumentCount()) {
+ case 0:
+ break;
+ case 1: {
+ regex_up.reset(new RegularExpression());
+ if (!regex_up->Compile(llvm::StringRef::withNullAsEmpty(
+ command.GetArgumentAtIndex(0)))) {
+ result.AppendError(
+ "invalid argument - please provide a valid regular expression");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ break;
+ }
+ default: {
+ result.AppendError("please provide 0 or 1 arguments");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ Process *process = m_exe_ctx.GetProcessPtr();
+ ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+ if (objc_runtime) {
+ auto iterators_pair = objc_runtime->GetDescriptorIteratorPair();
+ auto iterator = iterators_pair.first;
+ auto &std_out = result.GetOutputStream();
+ for (; iterator != iterators_pair.second; iterator++) {
+ if (iterator->second) {
+ const char *class_name =
+ iterator->second->GetClassName().AsCString("<unknown>");
+ if (regex_up && class_name &&
+ !regex_up->Execute(llvm::StringRef(class_name)))
+ continue;
+ std_out.Printf("isa = 0x%" PRIx64, iterator->first);
+ std_out.Printf(" name = %s", class_name);
+ std_out.Printf(" instance size = %" PRIu64,
+ iterator->second->GetInstanceSize());
+ std_out.Printf(" num ivars = %" PRIuPTR,
+ (uintptr_t)iterator->second->GetNumIVars());
+ if (auto superclass = iterator->second->GetSuperclass()) {
+ std_out.Printf(" superclass = %s",
+ superclass->GetClassName().AsCString("<unknown>"));
+ }
+ std_out.Printf("\n");
+ if (m_options.m_verbose) {
+ for (size_t i = 0; i < iterator->second->GetNumIVars(); i++) {
+ auto ivar = iterator->second->GetIVarAtIndex(i);
+ std_out.Printf(
+ " ivar name = %s type = %s size = %" PRIu64
+ " offset = %" PRId32 "\n",
+ ivar.m_name.AsCString("<unknown>"),
+ ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
+ ivar.m_size, ivar.m_offset);
}
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
- }
- else
- {
- result.AppendError("current process has no Objective-C runtime loaded");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ iterator->second->Describe(
+ nullptr,
+ [objc_runtime, &std_out](const char *name,
+ const char *type) -> bool {
+ std_out.Printf(" instance method name = %s type = %s\n",
+ name, type);
+ return false;
+ },
+ [objc_runtime, &std_out](const char *name,
+ const char *type) -> bool {
+ std_out.Printf(" class method name = %s type = %s\n", name,
+ type);
+ return false;
+ },
+ nullptr);
+ }
+ } else {
+ if (regex_up && !regex_up->Execute(llvm::StringRef()))
+ continue;
+ std_out.Printf("isa = 0x%" PRIx64 " has no associated class.\n",
+ iterator->first);
}
+ }
+ result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
+ return true;
+ } else {
+ result.AppendError("current process has no Objective-C runtime loaded");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
}
-
- CommandOptions m_options;
-};
+ }
-OptionDefinition
-CommandObjectObjC_ClassTable_Dump::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "verbose" , 'v', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Print ivar and method information in detail"},
- { 0 , false, nullptr , 0, 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
-class CommandObjectMultiwordObjC_TaggedPointer_Info : public CommandObjectParsed
-{
+class CommandObjectMultiwordObjC_TaggedPointer_Info
+ : public CommandObjectParsed {
public:
- CommandObjectMultiwordObjC_TaggedPointer_Info (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "info",
- "Dump information on a tagged pointer.",
- "language objc tagged-pointer info",
- eCommandRequiresProcess |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
- {
- CommandArgumentEntry arg;
- CommandArgumentData index_arg;
-
- // Define the first (and only) variant of this arg.
- index_arg.arg_type = eArgTypeAddress;
- index_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (index_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectMultiwordObjC_TaggedPointer_Info(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "info", "Dump information on a tagged pointer.",
+ "language objc tagged-pointer info",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused) {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
- ~CommandObjectMultiwordObjC_TaggedPointer_Info() override = default;
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeAddress;
+ index_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectMultiwordObjC_TaggedPointer_Info() override = default;
protected:
- bool
- DoExecute(Args& command, CommandReturnObject &result) override
- {
- if (command.GetArgumentCount() == 0)
- {
- result.AppendError("this command requires arguments");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- Process *process = m_exe_ctx.GetProcessPtr();
- ExecutionContext exe_ctx(process);
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime)
- {
- ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor = objc_runtime->GetTaggedPointerVendor();
- if (tagged_ptr_vendor)
- {
- for (size_t i = 0;
- i < command.GetArgumentCount();
- i++)
- {
- const char *arg_str = command.GetArgumentAtIndex(i);
- if (!arg_str)
- continue;
- Error error;
- lldb::addr_t arg_addr = Args::StringToAddress(&exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error);
- if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail())
- continue;
- auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr);
- if (!descriptor_sp)
- continue;
- uint64_t info_bits = 0;
- uint64_t value_bits = 0;
- uint64_t payload = 0;
- if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, &payload))
- {
- result.GetOutputStream().Printf("0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64 "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64 "\n\tclass = %s\n",
- (uint64_t)arg_addr,
- payload,
- value_bits,
- info_bits,
- descriptor_sp->GetClassName().AsCString("<unknown>"));
- }
- else
- {
- result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n", (uint64_t)arg_addr);
- }
- }
- }
- else
- {
- result.AppendError("current process has no tagged pointer support");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
- }
- else
- {
- result.AppendError("current process has no Objective-C runtime loaded");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.GetArgumentCount() == 0) {
+ result.AppendError("this command requires arguments");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+
+ Process *process = m_exe_ctx.GetProcessPtr();
+ ExecutionContext exe_ctx(process);
+ ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+ if (objc_runtime) {
+ ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor =
+ objc_runtime->GetTaggedPointerVendor();
+ if (tagged_ptr_vendor) {
+ for (size_t i = 0; i < command.GetArgumentCount(); i++) {
+ const char *arg_str = command.GetArgumentAtIndex(i);
+ if (!arg_str)
+ continue;
+ Error error;
+ lldb::addr_t arg_addr = Args::StringToAddress(
+ &exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error);
+ if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail())
+ continue;
+ auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr);
+ if (!descriptor_sp)
+ continue;
+ uint64_t info_bits = 0;
+ uint64_t value_bits = 0;
+ uint64_t payload = 0;
+ if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits,
+ &payload)) {
+ result.GetOutputStream().Printf(
+ "0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64
+ "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64
+ "\n\tclass = %s\n",
+ (uint64_t)arg_addr, payload, value_bits, info_bits,
+ descriptor_sp->GetClassName().AsCString("<unknown>"));
+ } else {
+ result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n",
+ (uint64_t)arg_addr);
+ }
}
+ } else {
+ result.AppendError("current process has no tagged pointer support");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
+ return true;
+ } else {
+ result.AppendError("current process has no Objective-C runtime loaded");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
}
+ }
};
-class CommandObjectMultiwordObjC_ClassTable : public CommandObjectMultiword
-{
+class CommandObjectMultiwordObjC_ClassTable : public CommandObjectMultiword {
public:
- CommandObjectMultiwordObjC_ClassTable(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "class-table", "Commands for operating on the Objective-C class table.",
- "class-table <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("dump", CommandObjectSP (new CommandObjectObjC_ClassTable_Dump (interpreter)));
- }
-
- ~CommandObjectMultiwordObjC_ClassTable() override = default;
+ CommandObjectMultiwordObjC_ClassTable(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "class-table",
+ "Commands for operating on the Objective-C class table.",
+ "class-table <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "dump",
+ CommandObjectSP(new CommandObjectObjC_ClassTable_Dump(interpreter)));
+ }
+
+ ~CommandObjectMultiwordObjC_ClassTable() override = default;
};
-class CommandObjectMultiwordObjC_TaggedPointer : public CommandObjectMultiword
-{
+class CommandObjectMultiwordObjC_TaggedPointer : public CommandObjectMultiword {
public:
- CommandObjectMultiwordObjC_TaggedPointer(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "tagged-pointer",
- "Commands for operating on Objective-C tagged pointers.",
- "class-table <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("info", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer_Info (interpreter)));
- }
-
- ~CommandObjectMultiwordObjC_TaggedPointer() override = default;
+ CommandObjectMultiwordObjC_TaggedPointer(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "tagged-pointer",
+ "Commands for operating on Objective-C tagged pointers.",
+ "class-table <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "info",
+ CommandObjectSP(
+ new CommandObjectMultiwordObjC_TaggedPointer_Info(interpreter)));
+ }
+
+ ~CommandObjectMultiwordObjC_TaggedPointer() override = default;
};
-class CommandObjectMultiwordObjC : public CommandObjectMultiword
-{
+class CommandObjectMultiwordObjC : public CommandObjectMultiword {
public:
- CommandObjectMultiwordObjC(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "objc", "Commands for operating on the Objective-C language runtime.",
- "objc <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("class-table", CommandObjectSP (new CommandObjectMultiwordObjC_ClassTable (interpreter)));
- LoadSubCommand ("tagged-pointer", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer (interpreter)));
- }
-
- ~CommandObjectMultiwordObjC() override = default;
+ CommandObjectMultiwordObjC(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "objc",
+ "Commands for operating on the Objective-C language runtime.",
+ "objc <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("class-table",
+ CommandObjectSP(
+ new CommandObjectMultiwordObjC_ClassTable(interpreter)));
+ LoadSubCommand("tagged-pointer",
+ CommandObjectSP(new CommandObjectMultiwordObjC_TaggedPointer(
+ interpreter)));
+ }
+
+ ~CommandObjectMultiwordObjC() override = default;
};
-void
-AppleObjCRuntimeV2::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Apple Objective C Language Runtime - Version 2",
- CreateInstance,
- [] (CommandInterpreter& interpreter) -> lldb::CommandObjectSP {
- return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
- });
+void AppleObjCRuntimeV2::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "Apple Objective C Language Runtime - Version 2",
+ CreateInstance,
+ [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
+ return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
+ });
}
-void
-AppleObjCRuntimeV2::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void AppleObjCRuntimeV2::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-AppleObjCRuntimeV2::GetPluginNameStatic()
-{
- static ConstString g_name("apple-objc-v2");
- return g_name;
+lldb_private::ConstString AppleObjCRuntimeV2::GetPluginNameStatic() {
+ static ConstString g_name("apple-objc-v2");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-AppleObjCRuntimeV2::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString AppleObjCRuntimeV2::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-AppleObjCRuntimeV2::GetPluginVersion()
-{
- return 1;
-}
+uint32_t AppleObjCRuntimeV2::GetPluginVersion() { return 1; }
BreakpointResolverSP
-AppleObjCRuntimeV2::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
-{
- BreakpointResolverSP resolver_sp;
-
- if (throw_bp)
- resolver_sp.reset (new BreakpointResolverName (bkpt,
- "objc_exception_throw",
- 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?
- return resolver_sp;
+AppleObjCRuntimeV2::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
+ bool throw_bp) {
+ BreakpointResolverSP resolver_sp;
+
+ if (throw_bp)
+ resolver_sp.reset(new BreakpointResolverName(
+ bkpt, "objc_exception_throw", 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?
+ return resolver_sp;
}
-UtilityFunction *
-AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
-{
- char check_function_code[2048];
-
- int len = 0;
- if (m_has_object_getClass)
- {
- len = ::snprintf (check_function_code,
- sizeof(check_function_code),
- "extern \"C\" void *gdb_object_getClass(void *); \n"
- "extern \"C\" int printf(const char *format, ...); \n"
- "extern \"C\" void \n"
- "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) \n"
- "{ \n"
- " if ($__lldb_arg_obj == (void *)0) \n"
- " return; // nil is ok \n"
- " if (!gdb_object_getClass($__lldb_arg_obj)) \n"
- " *((volatile int *)0) = 'ocgc'; \n"
- " else if ($__lldb_arg_selector != (void *)0) \n"
- " { \n"
- " signed char responds = (signed char) [(id) $__lldb_arg_obj \n"
- " respondsToSelector: \n"
- " (struct objc_selector *) $__lldb_arg_selector]; \n"
- " if (responds == (signed char) 0) \n"
- " *((volatile int *)0) = 'ocgc'; \n"
- " } \n"
- "} \n",
- name);
- }
- else
- {
- len = ::snprintf (check_function_code,
- sizeof(check_function_code),
- "extern \"C\" void *gdb_class_getClass(void *); \n"
- "extern \"C\" int printf(const char *format, ...); \n"
- "extern \"C\" void \n"
- "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) \n"
- "{ \n"
- " if ($__lldb_arg_obj == (void *)0) \n"
- " return; // nil is ok \n"
- " void **$isa_ptr = (void **)$__lldb_arg_obj; \n"
- " if (*$isa_ptr == (void *)0 || !gdb_class_getClass(*$isa_ptr)) \n"
- " *((volatile int *)0) = 'ocgc'; \n"
- " else if ($__lldb_arg_selector != (void *)0) \n"
- " { \n"
- " signed char responds = (signed char) [(id) $__lldb_arg_obj \n"
- " respondsToSelector: \n"
- " (struct objc_selector *) $__lldb_arg_selector]; \n"
- " if (responds == (signed char) 0) \n"
- " *((volatile int *)0) = 'ocgc'; \n"
- " } \n"
- "} \n",
- name);
- }
-
- assert (len < (int)sizeof(check_function_code));
-
- Error error;
- return GetTargetRef().GetUtilityFunctionForLanguage(check_function_code, eLanguageTypeObjC, name, error);
+UtilityFunction *AppleObjCRuntimeV2::CreateObjectChecker(const char *name) {
+ char check_function_code[2048];
+
+ int len = 0;
+ if (m_has_object_getClass) {
+ len = ::snprintf(check_function_code, sizeof(check_function_code),
+ "extern \"C\" void *gdb_object_getClass(void *); "
+ " \n"
+ "extern \"C\" int printf(const char *format, ...); "
+ " \n"
+ "extern \"C\" void "
+ " \n"
+ "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) "
+ " \n"
+ "{ "
+ " \n"
+ " if ($__lldb_arg_obj == (void *)0) "
+ " \n"
+ " return; // nil is ok "
+ " \n"
+ " if (!gdb_object_getClass($__lldb_arg_obj)) "
+ " \n"
+ " *((volatile int *)0) = 'ocgc'; "
+ " \n"
+ " else if ($__lldb_arg_selector != (void *)0) "
+ " \n"
+ " { "
+ " \n"
+ " signed char responds = (signed char) [(id) "
+ "$__lldb_arg_obj \n"
+ " "
+ "respondsToSelector: \n"
+ " (struct "
+ "objc_selector *) $__lldb_arg_selector]; \n"
+ " if (responds == (signed char) 0) "
+ " \n"
+ " *((volatile int *)0) = 'ocgc'; "
+ " \n"
+ " } "
+ " \n"
+ "} "
+ " \n",
+ name);
+ } else {
+ len = ::snprintf(check_function_code, sizeof(check_function_code),
+ "extern \"C\" void *gdb_class_getClass(void *); "
+ " \n"
+ "extern \"C\" int printf(const char *format, ...); "
+ " \n"
+ "extern \"C\" void "
+ " \n"
+ "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) "
+ " \n"
+ "{ "
+ " \n"
+ " if ($__lldb_arg_obj == (void *)0) "
+ " \n"
+ " return; // nil is ok "
+ " \n"
+ " void **$isa_ptr = (void **)$__lldb_arg_obj; "
+ " \n"
+ " if (*$isa_ptr == (void *)0 || "
+ "!gdb_class_getClass(*$isa_ptr)) \n"
+ " *((volatile int *)0) = 'ocgc'; "
+ " \n"
+ " else if ($__lldb_arg_selector != (void *)0) "
+ " \n"
+ " { "
+ " \n"
+ " signed char responds = (signed char) [(id) "
+ "$__lldb_arg_obj \n"
+ " "
+ "respondsToSelector: \n"
+ " (struct "
+ "objc_selector *) $__lldb_arg_selector]; \n"
+ " if (responds == (signed char) 0) "
+ " \n"
+ " *((volatile int *)0) = 'ocgc'; "
+ " \n"
+ " } "
+ " \n"
+ "} "
+ " \n",
+ name);
+ }
+
+ assert(len < (int)sizeof(check_function_code));
+
+ Error error;
+ return GetTargetRef().GetUtilityFunctionForLanguage(
+ check_function_code, eLanguageTypeObjC, name, error);
}
-size_t
-AppleObjCRuntimeV2::GetByteOffsetForIvar (CompilerType &parent_ast_type, const char *ivar_name)
-{
- uint32_t ivar_offset = LLDB_INVALID_IVAR_OFFSET;
-
- const char *class_name = parent_ast_type.GetConstTypeName().AsCString();
- if (class_name && class_name[0] && ivar_name && ivar_name[0])
- {
- //----------------------------------------------------------------------
- // Make the objective C V2 mangled name for the ivar offset from the
- // class name and ivar name
- //----------------------------------------------------------------------
- std::string buffer("OBJC_IVAR_$_");
- buffer.append (class_name);
- buffer.push_back ('.');
- buffer.append (ivar_name);
- ConstString ivar_const_str (buffer.c_str());
-
- //----------------------------------------------------------------------
- // Try to get the ivar offset address from the symbol table first using
- // the name we created above
- //----------------------------------------------------------------------
- SymbolContextList sc_list;
- Target &target = m_process->GetTarget();
- target.GetImages().FindSymbolsWithNameAndType(ivar_const_str, eSymbolTypeObjCIVar, sc_list);
-
- addr_t ivar_offset_address = LLDB_INVALID_ADDRESS;
-
- Error error;
- SymbolContext ivar_offset_symbol;
- if (sc_list.GetSize() == 1 && sc_list.GetContextAtIndex(0, ivar_offset_symbol))
- {
- if (ivar_offset_symbol.symbol)
- ivar_offset_address = ivar_offset_symbol.symbol->GetLoadAddress (&target);
- }
+size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type,
+ const char *ivar_name) {
+ uint32_t ivar_offset = LLDB_INVALID_IVAR_OFFSET;
+
+ const char *class_name = parent_ast_type.GetConstTypeName().AsCString();
+ if (class_name && class_name[0] && ivar_name && ivar_name[0]) {
+ //----------------------------------------------------------------------
+ // Make the objective C V2 mangled name for the ivar offset from the
+ // class name and ivar name
+ //----------------------------------------------------------------------
+ std::string buffer("OBJC_IVAR_$_");
+ buffer.append(class_name);
+ buffer.push_back('.');
+ buffer.append(ivar_name);
+ ConstString ivar_const_str(buffer.c_str());
+
+ //----------------------------------------------------------------------
+ // Try to get the ivar offset address from the symbol table first using
+ // the name we created above
+ //----------------------------------------------------------------------
+ SymbolContextList sc_list;
+ Target &target = m_process->GetTarget();
+ target.GetImages().FindSymbolsWithNameAndType(ivar_const_str,
+ eSymbolTypeObjCIVar, sc_list);
+
+ addr_t ivar_offset_address = LLDB_INVALID_ADDRESS;
- //----------------------------------------------------------------------
- // If we didn't get the ivar offset address from the symbol table, fall
- // back to getting it from the runtime
- //----------------------------------------------------------------------
- if (ivar_offset_address == LLDB_INVALID_ADDRESS)
- ivar_offset_address = LookupRuntimeSymbol(ivar_const_str);
-
- if (ivar_offset_address != LLDB_INVALID_ADDRESS)
- ivar_offset = m_process->ReadUnsignedIntegerFromMemory (ivar_offset_address,
- 4,
- LLDB_INVALID_IVAR_OFFSET,
- error);
+ Error error;
+ SymbolContext ivar_offset_symbol;
+ if (sc_list.GetSize() == 1 &&
+ sc_list.GetContextAtIndex(0, ivar_offset_symbol)) {
+ if (ivar_offset_symbol.symbol)
+ ivar_offset_address =
+ ivar_offset_symbol.symbol->GetLoadAddress(&target);
}
- return ivar_offset;
+
+ //----------------------------------------------------------------------
+ // If we didn't get the ivar offset address from the symbol table, fall
+ // back to getting it from the runtime
+ //----------------------------------------------------------------------
+ if (ivar_offset_address == LLDB_INVALID_ADDRESS)
+ ivar_offset_address = LookupRuntimeSymbol(ivar_const_str);
+
+ if (ivar_offset_address != LLDB_INVALID_ADDRESS)
+ ivar_offset = m_process->ReadUnsignedIntegerFromMemory(
+ ivar_offset_address, 4, LLDB_INVALID_IVAR_OFFSET, error);
+ }
+ return ivar_offset;
}
-// tagged pointers are special not-a-real-pointer values that contain both type and value information
-// this routine attempts to check with as little computational effort as possible whether something
-// could possibly be a tagged pointer - false positives are possible but false negatives shouldn't
-bool
-AppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr)
-{
- if (!m_tagged_pointer_vendor_ap)
- return false;
- return m_tagged_pointer_vendor_ap->IsPossibleTaggedPointer(ptr);
+// tagged pointers are special not-a-real-pointer values that contain both type
+// and value information
+// this routine attempts to check with as little computational effort as
+// possible whether something
+// could possibly be a tagged pointer - false positives are possible but false
+// negatives shouldn't
+bool AppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr) {
+ if (!m_tagged_pointer_vendor_ap)
+ return false;
+ return m_tagged_pointer_vendor_ap->IsPossibleTaggedPointer(ptr);
}
-class RemoteNXMapTable
-{
+class RemoteNXMapTable {
public:
- RemoteNXMapTable () :
- m_count (0),
- m_num_buckets_minus_one (0),
- m_buckets_ptr (LLDB_INVALID_ADDRESS),
- m_process (NULL),
- m_end_iterator (*this, -1),
- m_load_addr (LLDB_INVALID_ADDRESS),
- m_map_pair_size (0),
- m_invalid_key (0)
- {
+ RemoteNXMapTable()
+ : m_count(0), m_num_buckets_minus_one(0),
+ m_buckets_ptr(LLDB_INVALID_ADDRESS), m_process(NULL),
+ m_end_iterator(*this, -1), m_load_addr(LLDB_INVALID_ADDRESS),
+ m_map_pair_size(0), m_invalid_key(0) {}
+
+ void Dump() {
+ printf("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
+ printf("RemoteNXMapTable.m_count = %u\n", m_count);
+ printf("RemoteNXMapTable.m_num_buckets_minus_one = %u\n",
+ m_num_buckets_minus_one);
+ printf("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
+ }
+
+ bool ParseHeader(Process *process, lldb::addr_t load_addr) {
+ m_process = process;
+ m_load_addr = load_addr;
+ m_map_pair_size = m_process->GetAddressByteSize() * 2;
+ m_invalid_key =
+ m_process->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX;
+ Error err;
+
+ // This currently holds true for all platforms we support, but we might
+ // need to change this to use get the actually byte size of "unsigned"
+ // from the target AST...
+ const uint32_t unsigned_byte_size = sizeof(uint32_t);
+ // Skip the prototype as we don't need it (const struct +NXMapTablePrototype
+ // *prototype)
+
+ bool success = true;
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ success = false;
+ else {
+ lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
+
+ // unsigned count;
+ m_count = m_process->ReadUnsignedIntegerFromMemory(
+ cursor, unsigned_byte_size, 0, err);
+ if (m_count) {
+ cursor += unsigned_byte_size;
+
+ // unsigned nbBucketsMinusOne;
+ m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(
+ cursor, unsigned_byte_size, 0, err);
+ cursor += unsigned_byte_size;
+
+ // void *buckets;
+ m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
+
+ success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
+ }
}
-
- void
- Dump ()
- {
- printf ("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
- printf ("RemoteNXMapTable.m_count = %u\n", m_count);
- printf ("RemoteNXMapTable.m_num_buckets_minus_one = %u\n", m_num_buckets_minus_one);
- printf ("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
+
+ if (!success) {
+ m_count = 0;
+ m_num_buckets_minus_one = 0;
+ m_buckets_ptr = LLDB_INVALID_ADDRESS;
}
-
- bool
- ParseHeader (Process* process, lldb::addr_t load_addr)
- {
- m_process = process;
- m_load_addr = load_addr;
- m_map_pair_size = m_process->GetAddressByteSize() * 2;
- m_invalid_key = m_process->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX;
- Error err;
-
- // This currently holds true for all platforms we support, but we might
- // need to change this to use get the actually byte size of "unsigned"
- // from the target AST...
- const uint32_t unsigned_byte_size = sizeof(uint32_t);
- // Skip the prototype as we don't need it (const struct +NXMapTablePrototype *prototype)
-
- bool success = true;
- if (load_addr == LLDB_INVALID_ADDRESS)
- success = false;
- else
- {
- lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
-
- // unsigned count;
- m_count = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
- if (m_count)
- {
- cursor += unsigned_byte_size;
-
- // unsigned nbBucketsMinusOne;
- m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
- cursor += unsigned_byte_size;
-
- // void *buckets;
- m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
-
- success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
- }
- }
-
- if (!success)
- {
- m_count = 0;
- m_num_buckets_minus_one = 0;
- m_buckets_ptr = LLDB_INVALID_ADDRESS;
- }
- return success;
+ return success;
+ }
+
+ // const_iterator mimics NXMapState and its code comes from NXInitMapState and
+ // NXNextMapState.
+ typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA> element;
+
+ friend class const_iterator;
+ class const_iterator {
+ public:
+ const_iterator(RemoteNXMapTable &parent, int index)
+ : m_parent(parent), m_index(index) {
+ AdvanceToValidIndex();
}
-
- // const_iterator mimics NXMapState and its code comes from NXInitMapState and NXNextMapState.
- typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA> element;
-
- friend class const_iterator;
- class const_iterator
- {
- public:
- const_iterator (RemoteNXMapTable &parent, int index) : m_parent(parent), m_index(index)
- {
- AdvanceToValidIndex();
- }
-
- const_iterator (const const_iterator &rhs) : m_parent(rhs.m_parent), m_index(rhs.m_index)
- {
- // AdvanceToValidIndex() has been called by rhs already.
- }
-
- const_iterator &operator=(const const_iterator &rhs)
- {
- // AdvanceToValidIndex() has been called by rhs already.
- assert (&m_parent == &rhs.m_parent);
- m_index = rhs.m_index;
- return *this;
- }
-
- bool operator==(const const_iterator &rhs) const
- {
- if (&m_parent != &rhs.m_parent)
- return false;
- if (m_index != rhs.m_index)
- return false;
-
- return true;
- }
-
- bool operator!=(const const_iterator &rhs) const
- {
- return !(operator==(rhs));
- }
-
- const_iterator &operator++()
- {
- AdvanceToValidIndex();
- return *this;
- }
-
- const element operator*() const
- {
- if (m_index == -1)
- {
- // TODO find a way to make this an error, but not an assert
- return element();
- }
-
- lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
- size_t map_pair_size = m_parent.m_map_pair_size;
- lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
-
- Error err;
-
- lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
- if (!err.Success())
- return element();
- lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
- if (!err.Success())
- return element();
-
- std::string key_string;
-
- m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
- if (!err.Success())
- return element();
-
- return element(ConstString(key_string.c_str()), (ObjCLanguageRuntime::ObjCISA)value);
- }
- private:
- void AdvanceToValidIndex ()
- {
- if (m_index == -1)
- return;
-
- const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
- const size_t map_pair_size = m_parent.m_map_pair_size;
- const lldb::addr_t invalid_key = m_parent.m_invalid_key;
- Error err;
+ const_iterator(const const_iterator &rhs)
+ : m_parent(rhs.m_parent), m_index(rhs.m_index) {
+ // AdvanceToValidIndex() has been called by rhs already.
+ }
- while (m_index--)
- {
- lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
- lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
-
- if (!err.Success())
- {
- m_index = -1;
- return;
- }
-
- if (key != invalid_key)
- return;
- }
- }
- RemoteNXMapTable &m_parent;
- int m_index;
- };
-
- const_iterator begin ()
- {
- return const_iterator(*this, m_num_buckets_minus_one + 1);
+ const_iterator &operator=(const const_iterator &rhs) {
+ // AdvanceToValidIndex() has been called by rhs already.
+ assert(&m_parent == &rhs.m_parent);
+ m_index = rhs.m_index;
+ return *this;
}
-
- const_iterator end ()
- {
- return m_end_iterator;
+
+ bool operator==(const const_iterator &rhs) const {
+ if (&m_parent != &rhs.m_parent)
+ return false;
+ if (m_index != rhs.m_index)
+ return false;
+
+ return true;
}
-
- uint32_t
- GetCount () const
- {
- return m_count;
+
+ bool operator!=(const const_iterator &rhs) const {
+ return !(operator==(rhs));
}
-
- uint32_t
- GetBucketCount () const
- {
- return m_num_buckets_minus_one;
+
+ const_iterator &operator++() {
+ AdvanceToValidIndex();
+ return *this;
}
-
- lldb::addr_t
- GetBucketDataPointer () const
- {
- return m_buckets_ptr;
+
+ const element operator*() const {
+ if (m_index == -1) {
+ // TODO find a way to make this an error, but not an assert
+ return element();
+ }
+
+ lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
+ size_t map_pair_size = m_parent.m_map_pair_size;
+ lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
+
+ Error err;
+
+ lldb::addr_t key =
+ m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
+ if (!err.Success())
+ return element();
+ lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(
+ pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
+ if (!err.Success())
+ return element();
+
+ std::string key_string;
+
+ m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
+ if (!err.Success())
+ return element();
+
+ return element(ConstString(key_string.c_str()),
+ (ObjCLanguageRuntime::ObjCISA)value);
}
-
- lldb::addr_t
- GetTableLoadAddress() const
- {
- return m_load_addr;
+
+ private:
+ void AdvanceToValidIndex() {
+ if (m_index == -1)
+ return;
+
+ const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
+ const size_t map_pair_size = m_parent.m_map_pair_size;
+ const lldb::addr_t invalid_key = m_parent.m_invalid_key;
+ Error err;
+
+ while (m_index--) {
+ lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
+ lldb::addr_t key =
+ m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
+
+ if (!err.Success()) {
+ m_index = -1;
+ return;
+ }
+
+ if (key != invalid_key)
+ return;
+ }
}
+ RemoteNXMapTable &m_parent;
+ int m_index;
+ };
+
+ const_iterator begin() {
+ return const_iterator(*this, m_num_buckets_minus_one + 1);
+ }
+
+ const_iterator end() { return m_end_iterator; }
+
+ uint32_t GetCount() const { return m_count; }
+
+ uint32_t GetBucketCount() const { return m_num_buckets_minus_one; }
+
+ lldb::addr_t GetBucketDataPointer() const { return m_buckets_ptr; }
+
+ lldb::addr_t GetTableLoadAddress() const { return m_load_addr; }
private:
- // contents of _NXMapTable struct
- uint32_t m_count;
- uint32_t m_num_buckets_minus_one;
- lldb::addr_t m_buckets_ptr;
- lldb_private::Process *m_process;
- const_iterator m_end_iterator;
- lldb::addr_t m_load_addr;
- size_t m_map_pair_size;
- lldb::addr_t m_invalid_key;
+ // contents of _NXMapTable struct
+ uint32_t m_count;
+ uint32_t m_num_buckets_minus_one;
+ lldb::addr_t m_buckets_ptr;
+ lldb_private::Process *m_process;
+ const_iterator m_end_iterator;
+ lldb::addr_t m_load_addr;
+ size_t m_map_pair_size;
+ lldb::addr_t m_invalid_key;
};
-AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() :
- m_count (0),
- m_num_buckets (0),
- m_buckets_ptr (0)
-{
-}
+AppleObjCRuntimeV2::HashTableSignature::HashTableSignature()
+ : m_count(0), m_num_buckets(0), m_buckets_ptr(0) {}
-void
-AppleObjCRuntimeV2::HashTableSignature::UpdateSignature (const RemoteNXMapTable &hash_table)
-{
- m_count = hash_table.GetCount();
- m_num_buckets = hash_table.GetBucketCount();
- m_buckets_ptr = hash_table.GetBucketDataPointer();
+void AppleObjCRuntimeV2::HashTableSignature::UpdateSignature(
+ const RemoteNXMapTable &hash_table) {
+ m_count = hash_table.GetCount();
+ m_num_buckets = hash_table.GetBucketCount();
+ m_buckets_ptr = hash_table.GetBucketDataPointer();
}
-bool
-AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate (Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
-{
- if (!hash_table.ParseHeader(process, runtime->GetISAHashTablePointer ()))
- {
- return false; // Failed to parse the header, no need to update anything
- }
-
- // Check with out current signature and return true if the count,
- // number of buckets or the hash table address changes.
- if (m_count == hash_table.GetCount() &&
- m_num_buckets == hash_table.GetBucketCount() &&
- m_buckets_ptr == hash_table.GetBucketDataPointer())
- {
- // Hash table hasn't changed
- return false;
- }
- // Hash table data has changed, we need to update
- return true;
+bool AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate(
+ Process *process, AppleObjCRuntimeV2 *runtime,
+ RemoteNXMapTable &hash_table) {
+ if (!hash_table.ParseHeader(process, runtime->GetISAHashTablePointer())) {
+ return false; // Failed to parse the header, no need to update anything
+ }
+
+ // Check with out current signature and return true if the count,
+ // number of buckets or the hash table address changes.
+ if (m_count == hash_table.GetCount() &&
+ m_num_buckets == hash_table.GetBucketCount() &&
+ m_buckets_ptr == hash_table.GetBucketDataPointer()) {
+ // Hash table hasn't changed
+ return false;
+ }
+ // Hash table data has changed, we need to update
+ return true;
}
ObjCLanguageRuntime::ClassDescriptorSP
-AppleObjCRuntimeV2::GetClassDescriptorFromISA (ObjCISA isa)
-{
- ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
- if (m_non_pointer_isa_cache_ap.get())
- class_descriptor_sp = m_non_pointer_isa_cache_ap->GetClassDescriptor(isa);
- if (!class_descriptor_sp)
- class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
- return class_descriptor_sp;
+AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) {
+ ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
+ if (m_non_pointer_isa_cache_ap.get())
+ class_descriptor_sp = m_non_pointer_isa_cache_ap->GetClassDescriptor(isa);
+ if (!class_descriptor_sp)
+ class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
+ return class_descriptor_sp;
}
ObjCLanguageRuntime::ClassDescriptorSP
-AppleObjCRuntimeV2::GetClassDescriptor (ValueObject& valobj)
-{
- ClassDescriptorSP objc_class_sp;
- if (valobj.IsBaseClass())
- {
- ValueObject *parent = valobj.GetParent();
- // if I am my own parent, bail out of here fast..
- if (parent && parent != &valobj)
- {
- ClassDescriptorSP parent_descriptor_sp = GetClassDescriptor(*parent);
- if (parent_descriptor_sp)
- return parent_descriptor_sp->GetSuperclass();
- }
- return nullptr;
+AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
+ ClassDescriptorSP objc_class_sp;
+ if (valobj.IsBaseClass()) {
+ ValueObject *parent = valobj.GetParent();
+ // if I am my own parent, bail out of here fast..
+ if (parent && parent != &valobj) {
+ ClassDescriptorSP parent_descriptor_sp = GetClassDescriptor(*parent);
+ if (parent_descriptor_sp)
+ return parent_descriptor_sp->GetSuperclass();
}
- // if we get an invalid VO (which might still happen when playing around
- // with pointers returned by the expression parser, don't consider this
- // a valid ObjC object)
- if (valobj.GetCompilerType().IsValid())
- {
- addr_t isa_pointer = valobj.GetPointerValue();
-
- // tagged pointer
- if (IsTaggedPointer(isa_pointer))
- {
- return m_tagged_pointer_vendor_ap->GetClassDescriptor(isa_pointer);
- }
- else
- {
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
-
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- Error error;
- ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
- if (isa != LLDB_INVALID_ADDRESS)
- {
- objc_class_sp = GetClassDescriptorFromISA (isa);
- if (isa && !objc_class_sp)
- {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%" PRIx64,
- isa_pointer,
- isa);
- }
- }
- }
+ return nullptr;
+ }
+ // if we get an invalid VO (which might still happen when playing around
+ // with pointers returned by the expression parser, don't consider this
+ // a valid ObjC object)
+ if (valobj.GetCompilerType().IsValid()) {
+ addr_t isa_pointer = valobj.GetPointerValue();
+
+ // tagged pointer
+ if (IsTaggedPointer(isa_pointer)) {
+ return m_tagged_pointer_vendor_ap->GetClassDescriptor(isa_pointer);
+ } else {
+ ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ Error error;
+ ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
+ if (isa != LLDB_INVALID_ADDRESS) {
+ objc_class_sp = GetClassDescriptorFromISA(isa);
+ if (isa && !objc_class_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("0x%" PRIx64
+ ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
+ "not in class descriptor cache 0x%" PRIx64,
+ isa_pointer, isa);
+ }
}
+ }
}
- return objc_class_sp;
+ }
+ return objc_class_sp;
}
-lldb::addr_t
-AppleObjCRuntimeV2::GetISAHashTablePointer ()
-{
- if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
- {
- Process *process = GetProcess();
+lldb::addr_t AppleObjCRuntimeV2::GetISAHashTablePointer() {
+ if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) {
+ Process *process = GetProcess();
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (!objc_module_sp)
- return LLDB_INVALID_ADDRESS;
+ ModuleSP objc_module_sp(GetObjCModule());
- static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
-
- const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_objc_realized_classes, lldb::eSymbolTypeAny);
- if (symbol)
- {
- lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetLoadAddress(&process->GetTarget());
-
- if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
- {
- Error error;
- m_isa_hash_table_ptr = process->ReadPointerFromMemory(gdb_objc_realized_classes_ptr, error);
- }
- }
+ if (!objc_module_sp)
+ return LLDB_INVALID_ADDRESS;
+
+ static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
+
+ const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
+ g_gdb_objc_realized_classes, lldb::eSymbolTypeAny);
+ if (symbol) {
+ lldb::addr_t gdb_objc_realized_classes_ptr =
+ symbol->GetLoadAddress(&process->GetTarget());
+
+ if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS) {
+ Error error;
+ m_isa_hash_table_ptr = process->ReadPointerFromMemory(
+ gdb_objc_realized_classes_ptr, error);
+ }
}
- return m_isa_hash_table_ptr;
+ }
+ return m_isa_hash_table_ptr;
}
-bool
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table)
-{
- Process *process = GetProcess();
-
- if (process == NULL)
- return false;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- ExecutionContext exe_ctx;
-
- ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
-
- if (!thread_sp)
- return false;
-
- thread_sp->CalculateExecutionContext(exe_ctx);
- ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
-
- if (!ast)
- return false;
+AppleObjCRuntimeV2::DescriptorMapUpdateResult
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
+ RemoteNXMapTable &hash_table) {
+ Process *process = GetProcess();
- Address function_address;
+ if (process == NULL)
+ return DescriptorMapUpdateResult::Fail();
- DiagnosticManager diagnostics;
+ uint32_t num_class_infos = 0;
- const uint32_t addr_size = process->GetAddressByteSize();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
- Error err;
-
- // Read the total number of classes from the hash table
- const uint32_t num_classes = hash_table.GetCount();
- if (num_classes == 0)
- {
- if (log)
- log->Printf ("No dynamic classes found in gdb_objc_realized_classes.");
- return false;
- }
-
- // Make some types for our arguments
- CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
- CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- ValueList arguments;
- FunctionCaller *get_class_info_function = nullptr;
+ ExecutionContext exe_ctx;
- if (!m_get_class_info_code.get())
- {
- Error error;
- m_get_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_dynamic_class_info_body,
- eLanguageTypeObjC,
- g_get_dynamic_class_info_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get Utility Function for implementation lookup: %s", error.AsCString());
- m_get_class_info_code.reset();
- }
- else
- {
- diagnostics.Clear();
+ ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
- if (!m_get_class_info_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install implementation lookup");
- diagnostics.Dump(log);
- }
- m_get_class_info_code.reset();
- }
- }
- if (!m_get_class_info_code.get())
- return false;
-
- // Next make the runner function for our implementation utility function.
- Value value;
- value.SetValueType (Value::eValueTypeScalar);
- value.SetCompilerType (clang_void_pointer_type);
- arguments.PushValue (value);
- arguments.PushValue (value);
-
- value.SetValueType (Value::eValueTypeScalar);
- value.SetCompilerType (clang_uint32_t_type);
- arguments.PushValue (value);
- arguments.PushValue (value);
-
- get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
- arguments,
- thread_sp,
- error);
-
- if (error.Fail())
- {
- if (log)
- log->Printf("Failed to make function caller for implementation lookup: %s.", error.AsCString());
- return false;
- }
- }
- else
- {
- get_class_info_function = m_get_class_info_code->GetFunctionCaller();
- if (!get_class_info_function)
- {
- if (log)
- {
- log->Printf("Failed to get implementation lookup function caller.");
- diagnostics.Dump(log);
- }
+ if (!thread_sp)
+ return DescriptorMapUpdateResult::Fail();
- return false;
- }
- arguments = get_class_info_function->GetArgumentValues();
- }
+ thread_sp->CalculateExecutionContext(exe_ctx);
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
- diagnostics.Clear();
+ if (!ast)
+ return DescriptorMapUpdateResult::Fail();
- const uint32_t class_info_byte_size = addr_size + 4;
- const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
- lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
- ePermissionsReadable | ePermissionsWritable,
- err);
-
- if (class_infos_addr == LLDB_INVALID_ADDRESS)
- return false;
+ Address function_address;
- std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex);
+ DiagnosticManager diagnostics;
- // Fill in our function argument values
- arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
- arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
- arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
- arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
+ const uint32_t addr_size = process->GetAddressByteSize();
-
- bool success = false;
+ Error err;
- diagnostics.Clear();
+ // Read the total number of classes from the hash table
+ const uint32_t num_classes = hash_table.GetCount();
+ if (num_classes == 0) {
+ if (log)
+ log->Printf("No dynamic classes found in gdb_objc_realized_classes.");
+ return DescriptorMapUpdateResult::Success(0);
+ }
- // Write our function arguments into the process so we can run our function
- if (get_class_info_function->WriteFunctionArguments(exe_ctx, m_get_class_info_args, arguments, diagnostics))
- {
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(false);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeoutUsec(UTILITY_FUNCTION_TIMEOUT_USEC);
-
- Value return_value;
- return_value.SetValueType (Value::eValueTypeScalar);
- //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
- return_value.SetCompilerType(clang_uint32_t_type);
- return_value.GetScalar() = 0;
-
- diagnostics.Clear();
-
- // Run the function
- ExpressionResults results = get_class_info_function->ExecuteFunction(exe_ctx, &m_get_class_info_args, options,
- diagnostics, return_value);
-
- if (results == eExpressionCompleted)
- {
- // The result is the number of ClassInfo structures that were filled in
- uint32_t num_class_infos = return_value.GetScalar().ULong();
- if (log)
- log->Printf("Discovered %u ObjC classes\n",num_class_infos);
- if (num_class_infos > 0)
- {
- // Read the ClassInfo structures
- DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
- if (process->ReadMemory(class_infos_addr, buffer.GetBytes(), buffer.GetByteSize(), err) == buffer.GetByteSize())
- {
- DataExtractor class_infos_data (buffer.GetBytes(),
- buffer.GetByteSize(),
- process->GetByteOrder(),
- addr_size);
- ParseClassInfoArray (class_infos_data, num_class_infos);
- }
- }
- success = true;
- }
- else
- {
- if (log)
- {
- log->Printf("Error evaluating our find class name function.");
- diagnostics.Dump(log);
- }
+ // Make some types for our arguments
+ CompilerType clang_uint32_t_type =
+ ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ CompilerType clang_void_pointer_type =
+ ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ ValueList arguments;
+ FunctionCaller *get_class_info_function = nullptr;
+
+ if (!m_get_class_info_code.get()) {
+ Error error;
+ m_get_class_info_code.reset(GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_dynamic_class_info_body, eLanguageTypeObjC,
+ g_get_dynamic_class_info_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Failed to get Utility Function for implementation lookup: %s",
+ error.AsCString());
+ m_get_class_info_code.reset();
+ } else {
+ diagnostics.Clear();
+
+ if (!m_get_class_info_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install implementation lookup");
+ diagnostics.Dump(log);
}
+ m_get_class_info_code.reset();
+ }
}
- else
- {
- if (log)
- {
- log->Printf("Error writing function arguments.");
- diagnostics.Dump(log);
+ if (!m_get_class_info_code.get())
+ return DescriptorMapUpdateResult::Fail();
+
+ // Next make the runner function for our implementation utility function.
+ Value value;
+ value.SetValueType(Value::eValueTypeScalar);
+ value.SetCompilerType(clang_void_pointer_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ value.SetValueType(Value::eValueTypeScalar);
+ value.SetCompilerType(clang_uint32_t_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ get_class_info_function = m_get_class_info_code->MakeFunctionCaller(
+ clang_uint32_t_type, arguments, thread_sp, error);
+
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Failed to make function caller for implementation lookup: %s.",
+ error.AsCString());
+ return DescriptorMapUpdateResult::Fail();
+ }
+ } else {
+ get_class_info_function = m_get_class_info_code->GetFunctionCaller();
+ if (!get_class_info_function) {
+ if (log) {
+ log->Printf("Failed to get implementation lookup function caller.");
+ diagnostics.Dump(log);
+ }
+
+ return DescriptorMapUpdateResult::Fail();
+ }
+ arguments = get_class_info_function->GetArgumentValues();
+ }
+
+ diagnostics.Clear();
+
+ const uint32_t class_info_byte_size = addr_size + 4;
+ const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+ lldb::addr_t class_infos_addr = process->AllocateMemory(
+ class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
+
+ if (class_infos_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("unable to allocate %" PRIu32
+ " bytes in process for shared cache read",
+ class_infos_byte_size);
+ return DescriptorMapUpdateResult::Fail();
+ }
+
+ std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex);
+
+ // Fill in our function argument values
+ arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
+ arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+ arguments.GetValueAtIndex(3)->GetScalar() =
+ (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
+
+ bool success = false;
+
+ diagnostics.Clear();
+
+ // Write our function arguments into the process so we can run our function
+ if (get_class_info_function->WriteFunctionArguments(
+ exe_ctx, m_get_class_info_args, arguments, diagnostics)) {
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(false);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(g_utility_function_timeout);
+
+ Value return_value;
+ return_value.SetValueType(Value::eValueTypeScalar);
+ // return_value.SetContext (Value::eContextTypeClangType,
+ // clang_uint32_t_type);
+ return_value.SetCompilerType(clang_uint32_t_type);
+ return_value.GetScalar() = 0;
+
+ diagnostics.Clear();
+
+ // Run the function
+ ExpressionResults results = get_class_info_function->ExecuteFunction(
+ exe_ctx, &m_get_class_info_args, options, diagnostics, return_value);
+
+ if (results == eExpressionCompleted) {
+ // The result is the number of ClassInfo structures that were filled in
+ num_class_infos = return_value.GetScalar().ULong();
+ if (log)
+ log->Printf("Discovered %u ObjC classes\n", num_class_infos);
+ if (num_class_infos > 0) {
+ // Read the ClassInfo structures
+ DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
+ if (process->ReadMemory(class_infos_addr, buffer.GetBytes(),
+ buffer.GetByteSize(),
+ err) == buffer.GetByteSize()) {
+ DataExtractor class_infos_data(buffer.GetBytes(),
+ buffer.GetByteSize(),
+ process->GetByteOrder(), addr_size);
+ ParseClassInfoArray(class_infos_data, num_class_infos);
}
+ }
+ success = true;
+ } else {
+ if (log) {
+ log->Printf("Error evaluating our find class name function.");
+ diagnostics.Dump(log);
+ }
}
+ } else {
+ if (log) {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
+ }
- // Deallocate the memory we allocated for the ClassInfo array
- process->DeallocateMemory(class_infos_addr);
-
- return success;
+ // Deallocate the memory we allocated for the ClassInfo array
+ process->DeallocateMemory(class_infos_addr);
+
+ return DescriptorMapUpdateResult(success, num_class_infos);
}
-uint32_t
-AppleObjCRuntimeV2::ParseClassInfoArray (const DataExtractor &data, uint32_t num_class_infos)
-{
- // Parses an array of "num_class_infos" packed ClassInfo structures:
- //
- // struct ClassInfo
- // {
- // Class isa;
- // uint32_t hash;
- // } __attribute__((__packed__));
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- uint32_t num_parsed = 0;
-
- // Iterate through all ClassInfo structures
- lldb::offset_t offset = 0;
- for (uint32_t i=0; i<num_class_infos; ++i)
- {
- ObjCISA isa = data.GetPointer(&offset);
-
- if (isa == 0)
- {
- if (log)
- log->Printf("AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
- continue;
- }
- // Check if we already know about this ISA, if we do, the info will
- // never change, so we can just skip it.
- if (ISAIsCached(isa))
- {
- offset += 4;
- }
- else
- {
- // Read the 32 bit hash for the class name
- const uint32_t name_hash = data.GetU32(&offset);
- ClassDescriptorSP descriptor_sp (new ClassDescriptorV2(*this, isa, NULL));
- AddClass (isa, descriptor_sp, name_hash);
- num_parsed++;
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64 ", hash=0x%8.8x, name=%s", isa, name_hash,descriptor_sp->GetClassName().AsCString("<unknown>"));
- }
+uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
+ uint32_t num_class_infos) {
+ // Parses an array of "num_class_infos" packed ClassInfo structures:
+ //
+ // struct ClassInfo
+ // {
+ // Class isa;
+ // uint32_t hash;
+ // } __attribute__((__packed__));
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+
+ uint32_t num_parsed = 0;
+
+ // Iterate through all ClassInfo structures
+ lldb::offset_t offset = 0;
+ for (uint32_t i = 0; i < num_class_infos; ++i) {
+ ObjCISA isa = data.GetPointer(&offset);
+
+ if (isa == 0) {
+ if (log)
+ log->Printf(
+ "AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
+ continue;
}
- return num_parsed;
+ // Check if we already know about this ISA, if we do, the info will
+ // never change, so we can just skip it.
+ if (ISAIsCached(isa)) {
+ if (log)
+ log->Printf("AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
+ ", ignoring this class info",
+ isa);
+ offset += 4;
+ } else {
+ // Read the 32 bit hash for the class name
+ const uint32_t name_hash = data.GetU32(&offset);
+ ClassDescriptorSP descriptor_sp(new ClassDescriptorV2(*this, isa, NULL));
+ AddClass(isa, descriptor_sp, name_hash);
+ num_parsed++;
+ if (log)
+ log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64
+ ", hash=0x%8.8x, name=%s",
+ isa, name_hash,
+ descriptor_sp->GetClassName().AsCString("<unknown>"));
+ }
+ }
+ if (log)
+ log->Printf("AppleObjCRuntimeV2 parsed %" PRIu32 " class infos",
+ num_parsed);
+ return num_parsed;
}
AppleObjCRuntimeV2::DescriptorMapUpdateResult
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
-{
- Process *process = GetProcess();
-
- if (process == NULL)
- return DescriptorMapUpdateResult::Fail();
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- ExecutionContext exe_ctx;
-
- ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
-
- if (!thread_sp)
- return DescriptorMapUpdateResult::Fail();
-
- thread_sp->CalculateExecutionContext(exe_ctx);
- ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
-
- if (!ast)
- return DescriptorMapUpdateResult::Fail();
-
- Address function_address;
-
- DiagnosticManager diagnostics;
-
- const uint32_t addr_size = process->GetAddressByteSize();
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
+ Process *process = GetProcess();
- Error err;
-
- const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
-
- if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
- return DescriptorMapUpdateResult::Fail();
-
- // Read the total number of classes from the hash table
- const uint32_t num_classes = 128*1024;
- if (num_classes == 0)
- {
- if (log)
- log->Printf ("No dynamic classes found in gdb_objc_realized_classes_addr.");
- return DescriptorMapUpdateResult::Fail();
- }
-
- // Make some types for our arguments
- CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
- CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- ValueList arguments;
- FunctionCaller *get_shared_cache_class_info_function = nullptr;
-
- if (!m_get_shared_cache_class_info_code.get())
- {
- Error error;
- m_get_shared_cache_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_shared_cache_class_info_body,
- eLanguageTypeObjC,
- g_get_shared_cache_class_info_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get Utility function for implementation lookup: %s.", error.AsCString());
- m_get_shared_cache_class_info_code.reset();
- }
- else
- {
- diagnostics.Clear();
+ if (process == NULL)
+ return DescriptorMapUpdateResult::Fail();
- if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install implementation lookup.");
- diagnostics.Dump(log);
- }
- m_get_shared_cache_class_info_code.reset();
- }
- }
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
- if (!m_get_shared_cache_class_info_code.get())
- return DescriptorMapUpdateResult::Fail();
-
- // Next make the function caller for our implementation utility function.
- Value value;
- value.SetValueType (Value::eValueTypeScalar);
- //value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
- value.SetCompilerType (clang_void_pointer_type);
- arguments.PushValue (value);
- arguments.PushValue (value);
-
- value.SetValueType (Value::eValueTypeScalar);
- //value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
- value.SetCompilerType (clang_uint32_t_type);
- arguments.PushValue (value);
- arguments.PushValue (value);
-
- get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
- arguments,
- thread_sp,
- error);
-
- if (get_shared_cache_class_info_function == nullptr)
- return DescriptorMapUpdateResult::Fail();
-
- }
- else
- {
- get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->GetFunctionCaller();
- if (get_shared_cache_class_info_function == nullptr)
- return DescriptorMapUpdateResult::Fail();
- arguments = get_shared_cache_class_info_function->GetArgumentValues();
- }
+ ExecutionContext exe_ctx;
- diagnostics.Clear();
+ ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
+
+ if (!thread_sp)
+ return DescriptorMapUpdateResult::Fail();
+
+ thread_sp->CalculateExecutionContext(exe_ctx);
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+
+ if (!ast)
+ return DescriptorMapUpdateResult::Fail();
+
+ Address function_address;
+
+ DiagnosticManager diagnostics;
- const uint32_t class_info_byte_size = addr_size + 4;
- const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
- lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
- ePermissionsReadable | ePermissionsWritable,
- err);
-
- if (class_infos_addr == LLDB_INVALID_ADDRESS)
- return DescriptorMapUpdateResult::Fail();
+ const uint32_t addr_size = process->GetAddressByteSize();
- std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex);
+ Error err;
- // Fill in our function argument values
- arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
- arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
- arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
- arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
-
+ uint32_t num_class_infos = 0;
- bool success = false;
- bool any_found = false;
+ const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
+
+ if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
+ return DescriptorMapUpdateResult::Fail();
+
+ const uint32_t num_classes = 128 * 1024;
+
+ // Make some types for our arguments
+ CompilerType clang_uint32_t_type =
+ ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ CompilerType clang_void_pointer_type =
+ ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ ValueList arguments;
+ FunctionCaller *get_shared_cache_class_info_function = nullptr;
+
+ if (!m_get_shared_cache_class_info_code.get()) {
+ Error error;
+ m_get_shared_cache_class_info_code.reset(
+ GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_shared_cache_class_info_body, eLanguageTypeObjC,
+ g_get_shared_cache_class_info_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Failed to get Utility function for implementation lookup: %s.",
+ error.AsCString());
+ m_get_shared_cache_class_info_code.reset();
+ } else {
+ diagnostics.Clear();
+
+ if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install implementation lookup.");
+ diagnostics.Dump(log);
+ }
+ m_get_shared_cache_class_info_code.reset();
+ }
+ }
+
+ if (!m_get_shared_cache_class_info_code.get())
+ return DescriptorMapUpdateResult::Fail();
+
+ // Next make the function caller for our implementation utility function.
+ Value value;
+ value.SetValueType(Value::eValueTypeScalar);
+ // value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ value.SetCompilerType(clang_void_pointer_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ value.SetValueType(Value::eValueTypeScalar);
+ // value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ value.SetCompilerType(clang_uint32_t_type);
+ arguments.PushValue(value);
+ arguments.PushValue(value);
+
+ get_shared_cache_class_info_function =
+ m_get_shared_cache_class_info_code->MakeFunctionCaller(
+ clang_uint32_t_type, arguments, thread_sp, error);
+
+ if (get_shared_cache_class_info_function == nullptr)
+ return DescriptorMapUpdateResult::Fail();
+
+ } else {
+ get_shared_cache_class_info_function =
+ m_get_shared_cache_class_info_code->GetFunctionCaller();
+ if (get_shared_cache_class_info_function == nullptr)
+ return DescriptorMapUpdateResult::Fail();
+ arguments = get_shared_cache_class_info_function->GetArgumentValues();
+ }
+
+ diagnostics.Clear();
+
+ const uint32_t class_info_byte_size = addr_size + 4;
+ const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+ lldb::addr_t class_infos_addr = process->AllocateMemory(
+ class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
+
+ if (class_infos_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("unable to allocate %" PRIu32
+ " bytes in process for shared cache read",
+ class_infos_byte_size);
+ return DescriptorMapUpdateResult::Fail();
+ }
+
+ std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex);
+
+ // Fill in our function argument values
+ arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
+ arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+ arguments.GetValueAtIndex(3)->GetScalar() =
+ (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
+
+ bool success = false;
+
+ diagnostics.Clear();
+
+ // Write our function arguments into the process so we can run our function
+ if (get_shared_cache_class_info_function->WriteFunctionArguments(
+ exe_ctx, m_get_shared_cache_class_info_args, arguments,
+ diagnostics)) {
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(false);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(g_utility_function_timeout);
+
+ Value return_value;
+ return_value.SetValueType(Value::eValueTypeScalar);
+ // return_value.SetContext (Value::eContextTypeClangType,
+ // clang_uint32_t_type);
+ return_value.SetCompilerType(clang_uint32_t_type);
+ return_value.GetScalar() = 0;
diagnostics.Clear();
- // Write our function arguments into the process so we can run our function
- if (get_shared_cache_class_info_function->WriteFunctionArguments(exe_ctx, m_get_shared_cache_class_info_args,
- arguments, diagnostics))
- {
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(false);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeoutUsec(UTILITY_FUNCTION_TIMEOUT_USEC);
-
- Value return_value;
- return_value.SetValueType (Value::eValueTypeScalar);
- //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
- return_value.SetCompilerType(clang_uint32_t_type);
- return_value.GetScalar() = 0;
-
- diagnostics.Clear();
-
- // Run the function
- ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction(
- exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics, return_value);
-
- if (results == eExpressionCompleted)
- {
- // The result is the number of ClassInfo structures that were filled in
- uint32_t num_class_infos = return_value.GetScalar().ULong();
- if (log)
- log->Printf("Discovered %u ObjC classes in shared cache\n",num_class_infos);
+ // Run the function
+ ExpressionResults results =
+ get_shared_cache_class_info_function->ExecuteFunction(
+ exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics,
+ return_value);
+
+ if (results == eExpressionCompleted) {
+ // The result is the number of ClassInfo structures that were filled in
+ num_class_infos = return_value.GetScalar().ULong();
+ if (log)
+ log->Printf("Discovered %u ObjC classes in shared cache\n",
+ num_class_infos);
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (num_class_infos <= num_classes);
+ assert(num_class_infos <= num_classes);
#endif
- if (num_class_infos > 0)
- {
- if (num_class_infos > num_classes)
- {
- num_class_infos = num_classes;
-
- success = false;
- }
- else
- {
- success = true;
- }
-
- // Read the ClassInfo structures
- DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
- if (process->ReadMemory(class_infos_addr,
- buffer.GetBytes(),
- buffer.GetByteSize(),
- err) == buffer.GetByteSize())
- {
- DataExtractor class_infos_data (buffer.GetBytes(),
- buffer.GetByteSize(),
- process->GetByteOrder(),
- addr_size);
+ if (num_class_infos > 0) {
+ if (num_class_infos > num_classes) {
+ num_class_infos = num_classes;
- any_found = (ParseClassInfoArray (class_infos_data, num_class_infos) > 0);
- }
- }
- else
- {
- success = true;
- }
+ success = false;
+ } else {
+ success = true;
}
- else
- {
- if (log)
- {
- log->Printf("Error evaluating our find class name function.");
- diagnostics.Dump(log);
- }
+
+ // Read the ClassInfo structures
+ DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
+ if (process->ReadMemory(class_infos_addr, buffer.GetBytes(),
+ buffer.GetByteSize(),
+ err) == buffer.GetByteSize()) {
+ DataExtractor class_infos_data(buffer.GetBytes(),
+ buffer.GetByteSize(),
+ process->GetByteOrder(), addr_size);
+
+ ParseClassInfoArray(class_infos_data, num_class_infos);
}
+ } else {
+ success = true;
+ }
+ } else {
+ if (log) {
+ log->Printf("Error evaluating our find class name function.");
+ diagnostics.Dump(log);
+ }
}
- else
- {
- if (log)
- {
- log->Printf("Error writing function arguments.");
- diagnostics.Dump(log);
- }
+ } else {
+ if (log) {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
}
+ }
- // Deallocate the memory we allocated for the ClassInfo array
- process->DeallocateMemory(class_infos_addr);
-
- return DescriptorMapUpdateResult(success, any_found);
+ // Deallocate the memory we allocated for the ClassInfo array
+ process->DeallocateMemory(class_infos_addr);
+
+ return DescriptorMapUpdateResult(success, num_class_infos);
}
-bool
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- Process *process = GetProcess();
+bool AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory(
+ RemoteNXMapTable &hash_table) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
- if (process == NULL)
- return false;
-
- uint32_t num_map_table_isas = 0;
-
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (objc_module_sp)
- {
- for (RemoteNXMapTable::element elt : hash_table)
- {
- ++num_map_table_isas;
-
- if (ISAIsCached(elt.second))
- continue;
-
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
-
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
-
- AddClass (elt.second, descriptor_sp, elt.first.AsCString());
- }
+ Process *process = GetProcess();
+
+ if (process == NULL)
+ return false;
+
+ uint32_t num_map_table_isas = 0;
+
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (objc_module_sp) {
+ for (RemoteNXMapTable::element elt : hash_table) {
+ ++num_map_table_isas;
+
+ if (ISAIsCached(elt.second))
+ continue;
+
+ ClassDescriptorSP descriptor_sp = ClassDescriptorSP(
+ new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
+
+ if (log && log->GetVerbose())
+ log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64
+ " (%s) from dynamic table to isa->descriptor cache",
+ elt.second, elt.first.AsCString());
+
+ AddClass(elt.second, descriptor_sp, elt.first.AsCString());
}
-
- return num_map_table_isas > 0;
+ }
+
+ return num_map_table_isas > 0;
}
-lldb::addr_t
-AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress()
-{
- Process *process = GetProcess();
-
- if (process)
- {
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (objc_module_sp)
- {
- ObjectFile *objc_object = objc_module_sp->GetObjectFile();
-
- if (objc_object)
- {
- SectionList *section_list = objc_module_sp->GetSectionList();
-
- if (section_list)
- {
- SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
-
- if (text_segment_sp)
- {
- SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
-
- if (objc_opt_section_sp)
- {
- return objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
- }
- }
- }
+lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress() {
+ Process *process = GetProcess();
+
+ if (process) {
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (objc_module_sp) {
+ ObjectFile *objc_object = objc_module_sp->GetObjectFile();
+
+ if (objc_object) {
+ SectionList *section_list = objc_module_sp->GetSectionList();
+
+ if (section_list) {
+ SectionSP text_segment_sp(
+ section_list->FindSectionByName(ConstString("__TEXT")));
+
+ if (text_segment_sp) {
+ SectionSP objc_opt_section_sp(
+ text_segment_sp->GetChildren().FindSectionByName(
+ ConstString("__objc_opt_ro")));
+
+ if (objc_opt_section_sp) {
+ return objc_opt_section_sp->GetLoadBaseAddress(
+ &process->GetTarget());
}
+ }
}
+ }
}
- return LLDB_INVALID_ADDRESS;
+ }
+ return LLDB_INVALID_ADDRESS;
}
-void
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
-{
- Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
-
- // Else we need to check with our process to see when the map was updated.
- Process *process = GetProcess();
+void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
- if (process)
- {
- RemoteNXMapTable hash_table;
-
- // Update the process stop ID that indicates the last time we updated the
- // map, whether it was successful or not.
- m_isa_to_descriptor_stop_id = process->GetStopID();
-
- if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
- return;
-
- m_hash_signature.UpdateSignature (hash_table);
-
- // Grab the dynamically loaded objc classes from the hash table in memory
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION);
+
+ // Else we need to check with our process to see when the map was updated.
+ Process *process = GetProcess();
+
+ if (process) {
+ RemoteNXMapTable hash_table;
+
+ // Update the process stop ID that indicates the last time we updated the
+ // map, whether it was successful or not.
+ m_isa_to_descriptor_stop_id = process->GetStopID();
+
+ if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
+ return;
+
+ m_hash_signature.UpdateSignature(hash_table);
+
+ // Grab the dynamically loaded objc classes from the hash table in memory
+ DescriptorMapUpdateResult dynamic_update_result =
UpdateISAToDescriptorMapDynamic(hash_table);
- // Now get the objc classes that are baked into the Objective C runtime
- // in the shared cache, but only once per process as this data never
- // changes
- if (!m_loaded_objc_opt)
- {
- DescriptorMapUpdateResult shared_cache_update_result = UpdateISAToDescriptorMapSharedCache();
- if (!shared_cache_update_result.any_found)
- WarnIfNoClassesCached ();
- else
- m_loaded_objc_opt = true;
- }
- }
- else
- {
- m_isa_to_descriptor_stop_id = UINT32_MAX;
+ // Now get the objc classes that are baked into the Objective C runtime
+ // in the shared cache, but only once per process as this data never
+ // changes
+ if (!m_loaded_objc_opt) {
+ // it is legitimately possible for the shared cache to be empty - in that
+ // case, the dynamic hash table
+ // will contain all the class information we need; the situation we're
+ // trying to detect is one where
+ // we aren't seeing class information from the runtime - in order to
+ // detect that vs. just the shared cache
+ // being empty or sparsely populated, we set an arbitrary (very low)
+ // threshold for the number of classes
+ // that we want to see in a "good" scenario - anything below that is
+ // suspicious (Foundation alone has thousands
+ // of classes)
+ const uint32_t num_classes_to_warn_at = 500;
+
+ DescriptorMapUpdateResult shared_cache_update_result =
+ UpdateISAToDescriptorMapSharedCache();
+
+ if (log)
+ log->Printf("attempted to read objc class data - results: "
+ "[dynamic_update]: ran: %s, count: %" PRIu32
+ " [shared_cache_update]: ran: %s, count: %" PRIu32,
+ dynamic_update_result.m_update_ran ? "yes" : "no",
+ dynamic_update_result.m_num_found,
+ shared_cache_update_result.m_update_ran ? "yes" : "no",
+ shared_cache_update_result.m_num_found);
+
+ // 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))
+ WarnIfNoClassesCached(
+ SharedCacheWarningReason::eExpressionExecutionFailure);
+ else if (dynamic_update_result.m_num_found +
+ shared_cache_update_result.m_num_found <
+ num_classes_to_warn_at)
+ WarnIfNoClassesCached(SharedCacheWarningReason::eNotEnoughClassesRead);
+ else
+ m_loaded_objc_opt = true;
}
+ } else {
+ m_isa_to_descriptor_stop_id = UINT32_MAX;
+ }
}
-void
-AppleObjCRuntimeV2::WarnIfNoClassesCached ()
-{
- if (m_noclasses_warning_emitted)
- return;
+static bool DoesProcessHaveSharedCache(Process &process) {
+ PlatformSP platform_sp = process.GetTarget().GetPlatform();
+ if (!platform_sp)
+ return true; // this should not happen
- if (m_process &&
- m_process->GetTarget().GetPlatform() &&
- m_process->GetTarget().GetPlatform()->GetPluginName().GetStringRef().endswith("-simulator"))
- {
- // Simulators do not have the objc_opt_ro class table so don't actually complain to the user
- m_noclasses_warning_emitted = true;
- return;
- }
+ ConstString platform_plugin_name = platform_sp->GetPluginName();
+ if (platform_plugin_name) {
+ llvm::StringRef platform_plugin_name_sr =
+ platform_plugin_name.GetStringRef();
+ if (platform_plugin_name_sr.endswith("-simulator"))
+ return false;
+ }
- Debugger &debugger(GetProcess()->GetTarget().GetDebugger());
-
- if (debugger.GetAsyncOutputStream())
- {
- debugger.GetAsyncOutputStream()->PutCString("warning: could not load any Objective-C class information from the dyld shared cache. This will significantly reduce the quality of type information available.\n");
- m_noclasses_warning_emitted = true;
+ return true;
+}
+
+void AppleObjCRuntimeV2::WarnIfNoClassesCached(
+ SharedCacheWarningReason reason) {
+ if (m_noclasses_warning_emitted)
+ return;
+
+ if (GetProcess() && !DoesProcessHaveSharedCache(*GetProcess())) {
+ // Simulators do not have the objc_opt_ro class table so don't actually
+ // complain to the user
+ m_noclasses_warning_emitted = true;
+ return;
+ }
+
+ Debugger &debugger(GetProcess()->GetTarget().GetDebugger());
+ if (auto stream = debugger.GetAsyncOutputStream()) {
+ switch (reason) {
+ case SharedCacheWarningReason::eNotEnoughClassesRead:
+ stream->PutCString("warning: could not find Objective-C class data in "
+ "the process. This may reduce the quality of type "
+ "information available.\n");
+ m_noclasses_warning_emitted = true;
+ break;
+ case SharedCacheWarningReason::eExpressionExecutionFailure:
+ stream->PutCString("warning: could not execute support code to read "
+ "Objective-C class data in the process. This may "
+ "reduce the quality of type information available.\n");
+ m_noclasses_warning_emitted = true;
+ break;
}
+ }
}
-// TODO: should we have a transparent_kvo parameter here to say if we
-// want to replace the KVO swizzled class with the actual user-level type?
ConstString
-AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
-{
- if (isa == g_objc_Tagged_ISA)
- {
- static const ConstString g_objc_tagged_isa_name ("_lldb_Tagged_ObjC_ISA");
- return g_objc_tagged_isa_name;
- }
- if (isa == g_objc_Tagged_ISA_NSAtom)
- {
- static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
- return g_objc_tagged_isa_nsatom_name;
- }
- if (isa == g_objc_Tagged_ISA_NSNumber)
- {
- static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
- return g_objc_tagged_isa_nsnumber_name;
- }
- if (isa == g_objc_Tagged_ISA_NSDateTS)
- {
- static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
- return g_objc_tagged_isa_nsdatets_name;
- }
- if (isa == g_objc_Tagged_ISA_NSManagedObject)
- {
- static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
- return g_objc_tagged_isa_nsmanagedobject_name;
- }
- if (isa == g_objc_Tagged_ISA_NSDate)
- {
- static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
- return g_objc_tagged_isa_nsdate_name;
- }
- return ObjCLanguageRuntime::GetActualTypeName(isa);
+AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) {
+ if (isa == g_objc_Tagged_ISA) {
+ static const ConstString g_objc_tagged_isa_name("_lldb_Tagged_ObjC_ISA");
+ return g_objc_tagged_isa_name;
+ }
+ if (isa == g_objc_Tagged_ISA_NSAtom) {
+ static const ConstString g_objc_tagged_isa_nsatom_name("NSAtom");
+ return g_objc_tagged_isa_nsatom_name;
+ }
+ if (isa == g_objc_Tagged_ISA_NSNumber) {
+ static const ConstString g_objc_tagged_isa_nsnumber_name("NSNumber");
+ return g_objc_tagged_isa_nsnumber_name;
+ }
+ if (isa == g_objc_Tagged_ISA_NSDateTS) {
+ static const ConstString g_objc_tagged_isa_nsdatets_name("NSDateTS");
+ return g_objc_tagged_isa_nsdatets_name;
+ }
+ if (isa == g_objc_Tagged_ISA_NSManagedObject) {
+ static const ConstString g_objc_tagged_isa_nsmanagedobject_name(
+ "NSManagedObject");
+ return g_objc_tagged_isa_nsmanagedobject_name;
+ }
+ if (isa == g_objc_Tagged_ISA_NSDate) {
+ static const ConstString g_objc_tagged_isa_nsdate_name("NSDate");
+ return g_objc_tagged_isa_nsdate_name;
+ }
+ return ObjCLanguageRuntime::GetActualTypeName(isa);
}
-DeclVendor *
-AppleObjCRuntimeV2::GetDeclVendor()
-{
- if (!m_decl_vendor_ap.get())
- m_decl_vendor_ap.reset(new AppleObjCDeclVendor(*this));
-
- return m_decl_vendor_ap.get();
+DeclVendor *AppleObjCRuntimeV2::GetDeclVendor() {
+ if (!m_decl_vendor_ap.get())
+ m_decl_vendor_ap.reset(new AppleObjCDeclVendor(*this));
+
+ return m_decl_vendor_ap.get();
}
-lldb::addr_t
-AppleObjCRuntimeV2::LookupRuntimeSymbol (const ConstString &name)
-{
- lldb::addr_t ret = LLDB_INVALID_ADDRESS;
+lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(const ConstString &name) {
+ lldb::addr_t ret = LLDB_INVALID_ADDRESS;
- const char *name_cstr = name.AsCString();
-
- if (name_cstr)
- {
- llvm::StringRef name_strref(name_cstr);
-
- static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
- static const llvm::StringRef class_prefix("OBJC_CLASS_$_");
-
- if (name_strref.startswith(ivar_prefix))
- {
- llvm::StringRef ivar_skipped_prefix = name_strref.substr(ivar_prefix.size());
- std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar = ivar_skipped_prefix.split('.');
-
- if (class_and_ivar.first.size() && class_and_ivar.second.size())
- {
- const ConstString class_name_cs(class_and_ivar.first);
- ClassDescriptorSP descriptor = ObjCLanguageRuntime::GetClassDescriptorFromClassName(class_name_cs);
-
- if (descriptor)
- {
- const ConstString ivar_name_cs(class_and_ivar.second);
- const char *ivar_name_cstr = ivar_name_cs.AsCString();
-
- auto ivar_func = [&ret, ivar_name_cstr](const char *name, const char *type, lldb::addr_t offset_addr, uint64_t size) -> lldb::addr_t
- {
- if (!strcmp(name, ivar_name_cstr))
- {
- ret = offset_addr;
- return true;
- }
- return false;
- };
-
- descriptor->Describe(std::function<void (ObjCISA)>(nullptr),
- std::function<bool (const char *, const char *)>(nullptr),
- std::function<bool (const char *, const char *)>(nullptr),
- ivar_func);
- }
+ const char *name_cstr = name.AsCString();
+
+ if (name_cstr) {
+ llvm::StringRef name_strref(name_cstr);
+
+ static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
+ static const llvm::StringRef class_prefix("OBJC_CLASS_$_");
+
+ if (name_strref.startswith(ivar_prefix)) {
+ llvm::StringRef ivar_skipped_prefix =
+ name_strref.substr(ivar_prefix.size());
+ std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar =
+ ivar_skipped_prefix.split('.');
+
+ if (class_and_ivar.first.size() && class_and_ivar.second.size()) {
+ const ConstString class_name_cs(class_and_ivar.first);
+ ClassDescriptorSP descriptor =
+ ObjCLanguageRuntime::GetClassDescriptorFromClassName(class_name_cs);
+
+ if (descriptor) {
+ const ConstString ivar_name_cs(class_and_ivar.second);
+ const char *ivar_name_cstr = ivar_name_cs.AsCString();
+
+ auto ivar_func = [&ret, ivar_name_cstr](
+ const char *name, const char *type, lldb::addr_t offset_addr,
+ uint64_t size) -> lldb::addr_t {
+ if (!strcmp(name, ivar_name_cstr)) {
+ ret = offset_addr;
+ return true;
}
+ return false;
+ };
+
+ descriptor->Describe(
+ std::function<void(ObjCISA)>(nullptr),
+ std::function<bool(const char *, const char *)>(nullptr),
+ std::function<bool(const char *, const char *)>(nullptr),
+ ivar_func);
}
- else if (name_strref.startswith(class_prefix))
- {
- llvm::StringRef class_skipped_prefix = name_strref.substr(class_prefix.size());
- const ConstString class_name_cs(class_skipped_prefix);
- ClassDescriptorSP descriptor = GetClassDescriptorFromClassName(class_name_cs);
-
- if (descriptor)
- ret = descriptor->GetISA();
- }
+ }
+ } else if (name_strref.startswith(class_prefix)) {
+ llvm::StringRef class_skipped_prefix =
+ name_strref.substr(class_prefix.size());
+ const ConstString class_name_cs(class_skipped_prefix);
+ ClassDescriptorSP descriptor =
+ GetClassDescriptorFromClassName(class_name_cs);
+
+ if (descriptor)
+ ret = descriptor->GetISA();
}
-
- return ret;
+ }
+
+ return ret;
}
-AppleObjCRuntimeV2::NonPointerISACache*
-AppleObjCRuntimeV2::NonPointerISACache::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
-{
- Process* process(runtime.GetProcess());
-
- Error error;
-
- auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_isa_magic_mask"),
- objc_module_sp,
- error);
- if (error.Fail())
- return NULL;
+AppleObjCRuntimeV2::NonPointerISACache *
+AppleObjCRuntimeV2::NonPointerISACache::CreateInstance(
+ AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp) {
+ Process *process(runtime.GetProcess());
- auto objc_debug_isa_magic_value = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_isa_magic_value"),
- objc_module_sp,
- error);
- if (error.Fail())
- return NULL;
+ Error error;
- auto objc_debug_isa_class_mask = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_isa_class_mask"),
- objc_module_sp,
- error);
- if (error.Fail())
- return NULL;
-
- // we might want to have some rules to outlaw these other values (e.g if the mask is zero but the value is non-zero, ...)
-
- return new NonPointerISACache(runtime,
- objc_debug_isa_class_mask,
- objc_debug_isa_magic_mask,
- objc_debug_isa_magic_value);
+ auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_isa_magic_mask"), objc_module_sp, error);
+ if (error.Fail())
+ return NULL;
+
+ auto objc_debug_isa_magic_value = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_isa_magic_value"), objc_module_sp,
+ error);
+ if (error.Fail())
+ return NULL;
+
+ auto objc_debug_isa_class_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_isa_class_mask"), objc_module_sp, error);
+ if (error.Fail())
+ return NULL;
+
+ // we might want to have some rules to outlaw these other values (e.g if the
+ // mask is zero but the value is non-zero, ...)
+
+ return new NonPointerISACache(runtime, objc_debug_isa_class_mask,
+ objc_debug_isa_magic_mask,
+ objc_debug_isa_magic_value);
}
-AppleObjCRuntimeV2::TaggedPointerVendorV2*
-AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
-{
- Process* process(runtime.GetProcess());
-
- Error error;
-
- auto objc_debug_taggedpointer_mask = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_mask"),
- objc_module_sp,
- error);
- if (error.Fail())
- return new TaggedPointerVendorLegacy(runtime);
-
- auto objc_debug_taggedpointer_slot_shift = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_slot_shift"),
- objc_module_sp,
- error,
- true,
- 4);
+AppleObjCRuntimeV2::TaggedPointerVendorV2 *
+AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance(
+ AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp) {
+ Process *process(runtime.GetProcess());
+
+ Error error;
+
+ auto objc_debug_taggedpointer_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_mask"), objc_module_sp,
+ error);
+ if (error.Fail())
+ return new TaggedPointerVendorLegacy(runtime);
+
+ auto objc_debug_taggedpointer_slot_shift = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_slot_shift"),
+ objc_module_sp, error, true, 4);
+ if (error.Fail())
+ return new TaggedPointerVendorLegacy(runtime);
+
+ auto objc_debug_taggedpointer_slot_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_slot_mask"),
+ objc_module_sp, error, true, 4);
+ if (error.Fail())
+ return new TaggedPointerVendorLegacy(runtime);
+
+ auto objc_debug_taggedpointer_payload_lshift = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_payload_lshift"),
+ objc_module_sp, error, true, 4);
+ if (error.Fail())
+ return new TaggedPointerVendorLegacy(runtime);
+
+ auto objc_debug_taggedpointer_payload_rshift = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_payload_rshift"),
+ objc_module_sp, error, true, 4);
+ if (error.Fail())
+ return new TaggedPointerVendorLegacy(runtime);
+
+ auto objc_debug_taggedpointer_classes = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_classes"), objc_module_sp,
+ error, false);
+ if (error.Fail())
+ return new TaggedPointerVendorLegacy(runtime);
+
+ // try to detect the "extended tagged pointer" variables - if any are missing,
+ // use the non-extended vendor
+ do {
+ auto objc_debug_taggedpointer_ext_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_ext_mask"),
+ objc_module_sp, error);
if (error.Fail())
- return new TaggedPointerVendorLegacy(runtime);
-
- auto objc_debug_taggedpointer_slot_mask = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_slot_mask"),
- objc_module_sp,
- error,
- true,
- 4);
+ break;
+
+ auto objc_debug_taggedpointer_ext_slot_shift = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_ext_slot_shift"),
+ objc_module_sp, error, true, 4);
if (error.Fail())
- return new TaggedPointerVendorLegacy(runtime);
-
- auto objc_debug_taggedpointer_payload_lshift = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_payload_lshift"),
- objc_module_sp,
- error,
- true,
- 4);
+ break;
+
+ auto objc_debug_taggedpointer_ext_slot_mask = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_ext_slot_mask"),
+ objc_module_sp, error, true, 4);
if (error.Fail())
- return new TaggedPointerVendorLegacy(runtime);
-
- auto objc_debug_taggedpointer_payload_rshift = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_payload_rshift"),
- objc_module_sp,
- error,
- true,
- 4);
+ break;
+
+ auto objc_debug_taggedpointer_ext_classes = ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_ext_classes"),
+ objc_module_sp, error, false);
if (error.Fail())
- return new TaggedPointerVendorLegacy(runtime);
-
- auto objc_debug_taggedpointer_classes = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_classes"),
- objc_module_sp,
- error,
- false);
+ break;
+
+ auto objc_debug_taggedpointer_ext_payload_lshift =
+ ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_ext_payload_lshift"),
+ objc_module_sp, error, true, 4);
if (error.Fail())
- return new TaggedPointerVendorLegacy(runtime);
+ break;
- // try to detect the "extended tagged pointer" variables - if any are missing, use the non-extended vendor
- do
- {
- auto objc_debug_taggedpointer_ext_mask = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_ext_mask"),
- objc_module_sp,
- error);
- if (error.Fail())
- break;
-
- auto objc_debug_taggedpointer_ext_slot_shift = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_ext_slot_shift"),
- objc_module_sp,
- error,
- true,
- 4);
- if (error.Fail())
- break;
-
- auto objc_debug_taggedpointer_ext_slot_mask = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_ext_slot_mask"),
- objc_module_sp,
- error,
- true,
- 4);
- if (error.Fail())
- break;
-
- auto objc_debug_taggedpointer_ext_classes = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_ext_classes"),
- objc_module_sp,
- error,
- false);
- if (error.Fail())
- break;
-
- auto objc_debug_taggedpointer_ext_payload_lshift = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_ext_payload_lshift"),
- objc_module_sp,
- error,
- true,
- 4);
- if (error.Fail())
- break;
-
- auto objc_debug_taggedpointer_ext_payload_rshift = ExtractRuntimeGlobalSymbol(process,
- ConstString("objc_debug_taggedpointer_ext_payload_rshift"),
- objc_module_sp,
- error,
- true,
- 4);
- if (error.Fail())
- break;
-
- return new TaggedPointerVendorExtended(runtime,
- objc_debug_taggedpointer_mask,
- objc_debug_taggedpointer_ext_mask,
- objc_debug_taggedpointer_slot_shift,
- objc_debug_taggedpointer_ext_slot_shift,
- objc_debug_taggedpointer_slot_mask,
- objc_debug_taggedpointer_ext_slot_mask,
- objc_debug_taggedpointer_payload_lshift,
- objc_debug_taggedpointer_payload_rshift,
- objc_debug_taggedpointer_ext_payload_lshift,
- objc_debug_taggedpointer_ext_payload_rshift,
- objc_debug_taggedpointer_classes,
- objc_debug_taggedpointer_ext_classes);
- } while(false);
-
- // we might want to have some rules to outlaw these values (e.g if the table's address is zero)
-
- return new TaggedPointerVendorRuntimeAssisted(runtime,
- objc_debug_taggedpointer_mask,
- objc_debug_taggedpointer_slot_shift,
- objc_debug_taggedpointer_slot_mask,
- objc_debug_taggedpointer_payload_lshift,
- objc_debug_taggedpointer_payload_rshift,
- objc_debug_taggedpointer_classes);
+ auto objc_debug_taggedpointer_ext_payload_rshift =
+ ExtractRuntimeGlobalSymbol(
+ process, ConstString("objc_debug_taggedpointer_ext_payload_rshift"),
+ objc_module_sp, error, true, 4);
+ if (error.Fail())
+ break;
+
+ return new TaggedPointerVendorExtended(
+ runtime, objc_debug_taggedpointer_mask,
+ objc_debug_taggedpointer_ext_mask, objc_debug_taggedpointer_slot_shift,
+ objc_debug_taggedpointer_ext_slot_shift,
+ objc_debug_taggedpointer_slot_mask,
+ objc_debug_taggedpointer_ext_slot_mask,
+ objc_debug_taggedpointer_payload_lshift,
+ objc_debug_taggedpointer_payload_rshift,
+ objc_debug_taggedpointer_ext_payload_lshift,
+ objc_debug_taggedpointer_ext_payload_rshift,
+ objc_debug_taggedpointer_classes, objc_debug_taggedpointer_ext_classes);
+ } while (false);
+
+ // we might want to have some rules to outlaw these values (e.g if the table's
+ // address is zero)
+
+ return new TaggedPointerVendorRuntimeAssisted(
+ runtime, objc_debug_taggedpointer_mask,
+ objc_debug_taggedpointer_slot_shift, objc_debug_taggedpointer_slot_mask,
+ objc_debug_taggedpointer_payload_lshift,
+ objc_debug_taggedpointer_payload_rshift,
+ objc_debug_taggedpointer_classes);
}
-bool
-AppleObjCRuntimeV2::TaggedPointerVendorLegacy::IsPossibleTaggedPointer (lldb::addr_t ptr)
-{
- return (ptr & 1);
+bool AppleObjCRuntimeV2::TaggedPointerVendorLegacy::IsPossibleTaggedPointer(
+ lldb::addr_t ptr) {
+ return (ptr & 1);
}
ObjCLanguageRuntime::ClassDescriptorSP
-AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor (lldb::addr_t ptr)
-{
- if (!IsPossibleTaggedPointer(ptr))
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
- uint32_t foundation_version = m_runtime.GetFoundationVersion();
-
- if (foundation_version == LLDB_INVALID_MODULE_VERSION)
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
- uint64_t class_bits = (ptr & 0xE) >> 1;
- ConstString name;
-
- // TODO: make a table
- if (foundation_version >= 900)
- {
- switch (class_bits)
- {
- case 0:
- name = ConstString("NSAtom");
- break;
- case 3:
- name = ConstString("NSNumber");
- break;
- case 4:
- name = ConstString("NSDateTS");
- break;
- case 5:
- name = ConstString("NSManagedObject");
- break;
- case 6:
- name = ConstString("NSDate");
- break;
- default:
- return ObjCLanguageRuntime::ClassDescriptorSP();
- }
+AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor(
+ lldb::addr_t ptr) {
+ if (!IsPossibleTaggedPointer(ptr))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ uint32_t foundation_version = m_runtime.GetFoundationVersion();
+
+ if (foundation_version == LLDB_INVALID_MODULE_VERSION)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ uint64_t class_bits = (ptr & 0xE) >> 1;
+ ConstString name;
+
+ static ConstString g_NSAtom("NSAtom");
+ static ConstString g_NSNumber("NSNumber");
+ static ConstString g_NSDateTS("NSDateTS");
+ static ConstString g_NSManagedObject("NSManagedObject");
+ static ConstString g_NSDate("NSDate");
+
+ if (foundation_version >= 900) {
+ switch (class_bits) {
+ case 0:
+ name = g_NSAtom;
+ break;
+ case 3:
+ name = g_NSNumber;
+ break;
+ case 4:
+ name = g_NSDateTS;
+ break;
+ case 5:
+ name = g_NSManagedObject;
+ break;
+ case 6:
+ name = g_NSDate;
+ break;
+ default:
+ return ObjCLanguageRuntime::ClassDescriptorSP();
}
- else
- {
- switch (class_bits)
- {
- case 1:
- name = ConstString("NSNumber");
- break;
- case 5:
- name = ConstString("NSManagedObject");
- break;
- case 6:
- name = ConstString("NSDate");
- break;
- case 7:
- name = ConstString("NSDateTS");
- break;
- default:
- return ObjCLanguageRuntime::ClassDescriptorSP();
- }
+ } else {
+ switch (class_bits) {
+ case 1:
+ name = g_NSNumber;
+ break;
+ case 5:
+ name = g_NSManagedObject;
+ break;
+ case 6:
+ name = g_NSDate;
+ break;
+ case 7:
+ name = g_NSDateTS;
+ break;
+ default:
+ return ObjCLanguageRuntime::ClassDescriptorSP();
}
- return ClassDescriptorSP(new ClassDescriptorV2Tagged(name,ptr));
+ }
+ return ClassDescriptorSP(new ClassDescriptorV2Tagged(name, ptr));
}
-AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::TaggedPointerVendorRuntimeAssisted (AppleObjCRuntimeV2& runtime,
- uint64_t objc_debug_taggedpointer_mask,
- uint32_t objc_debug_taggedpointer_slot_shift,
- uint32_t objc_debug_taggedpointer_slot_mask,
- uint32_t objc_debug_taggedpointer_payload_lshift,
- uint32_t objc_debug_taggedpointer_payload_rshift,
- lldb::addr_t objc_debug_taggedpointer_classes) :
-TaggedPointerVendorV2(runtime),
-m_cache(),
-m_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask),
-m_objc_debug_taggedpointer_slot_shift(objc_debug_taggedpointer_slot_shift),
-m_objc_debug_taggedpointer_slot_mask(objc_debug_taggedpointer_slot_mask),
-m_objc_debug_taggedpointer_payload_lshift(objc_debug_taggedpointer_payload_lshift),
-m_objc_debug_taggedpointer_payload_rshift(objc_debug_taggedpointer_payload_rshift),
-m_objc_debug_taggedpointer_classes(objc_debug_taggedpointer_classes)
-{
-}
-
-bool
-AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::IsPossibleTaggedPointer (lldb::addr_t ptr)
-{
- return (ptr & m_objc_debug_taggedpointer_mask) != 0;
+AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::
+ TaggedPointerVendorRuntimeAssisted(
+ AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes)
+ : TaggedPointerVendorV2(runtime), m_cache(),
+ m_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask),
+ m_objc_debug_taggedpointer_slot_shift(
+ objc_debug_taggedpointer_slot_shift),
+ m_objc_debug_taggedpointer_slot_mask(objc_debug_taggedpointer_slot_mask),
+ m_objc_debug_taggedpointer_payload_lshift(
+ objc_debug_taggedpointer_payload_lshift),
+ m_objc_debug_taggedpointer_payload_rshift(
+ objc_debug_taggedpointer_payload_rshift),
+ m_objc_debug_taggedpointer_classes(objc_debug_taggedpointer_classes) {}
+
+bool AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::
+ IsPossibleTaggedPointer(lldb::addr_t ptr) {
+ return (ptr & m_objc_debug_taggedpointer_mask) != 0;
}
ObjCLanguageRuntime::ClassDescriptorSP
-AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor (lldb::addr_t ptr)
-{
- ClassDescriptorSP actual_class_descriptor_sp;
- uint64_t data_payload;
-
- if (!IsPossibleTaggedPointer(ptr))
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
- uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) & m_objc_debug_taggedpointer_slot_mask;
-
- CacheIterator iterator = m_cache.find(slot),
- end = m_cache.end();
- if (iterator != end)
- {
- actual_class_descriptor_sp = iterator->second;
- }
- else
- {
- Process* process(m_runtime.GetProcess());
- uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_classes;
- Error error;
- uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
- if (error.Fail() || slot_data == 0 || slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
- return nullptr;
- actual_class_descriptor_sp = m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
- if (!actual_class_descriptor_sp)
- return ObjCLanguageRuntime::ClassDescriptorSP();
- m_cache[slot] = actual_class_descriptor_sp;
- }
-
- data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_payload_lshift) >> m_objc_debug_taggedpointer_payload_rshift);
-
- return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
+AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
+ lldb::addr_t ptr) {
+ ClassDescriptorSP actual_class_descriptor_sp;
+ uint64_t data_payload;
+
+ if (!IsPossibleTaggedPointer(ptr))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) &
+ m_objc_debug_taggedpointer_slot_mask;
+
+ CacheIterator iterator = m_cache.find(slot), end = m_cache.end();
+ if (iterator != end) {
+ actual_class_descriptor_sp = iterator->second;
+ } else {
+ Process *process(m_runtime.GetProcess());
+ uintptr_t slot_ptr = slot * process->GetAddressByteSize() +
+ m_objc_debug_taggedpointer_classes;
+ Error error;
+ uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
+ if (error.Fail() || slot_data == 0 ||
+ slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
+ return nullptr;
+ actual_class_descriptor_sp =
+ m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
+ if (!actual_class_descriptor_sp)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+ m_cache[slot] = actual_class_descriptor_sp;
+ }
+
+ data_payload =
+ (((uint64_t)ptr << m_objc_debug_taggedpointer_payload_lshift) >>
+ m_objc_debug_taggedpointer_payload_rshift);
+
+ return ClassDescriptorSP(
+ new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
}
-AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended (AppleObjCRuntimeV2& runtime,
- uint64_t objc_debug_taggedpointer_mask,
- uint64_t objc_debug_taggedpointer_ext_mask,
- uint32_t objc_debug_taggedpointer_slot_shift,
- uint32_t objc_debug_taggedpointer_ext_slot_shift,
- uint32_t objc_debug_taggedpointer_slot_mask,
- uint32_t objc_debug_taggedpointer_ext_slot_mask,
- uint32_t objc_debug_taggedpointer_payload_lshift,
- uint32_t objc_debug_taggedpointer_payload_rshift,
- uint32_t objc_debug_taggedpointer_ext_payload_lshift,
- uint32_t objc_debug_taggedpointer_ext_payload_rshift,
- lldb::addr_t objc_debug_taggedpointer_classes,
- lldb::addr_t objc_debug_taggedpointer_ext_classes) :
-TaggedPointerVendorRuntimeAssisted(runtime,
- objc_debug_taggedpointer_mask,
- objc_debug_taggedpointer_slot_shift,
- objc_debug_taggedpointer_slot_mask,
- objc_debug_taggedpointer_payload_lshift,
- objc_debug_taggedpointer_payload_rshift,
- objc_debug_taggedpointer_classes),
-m_ext_cache(),
-m_objc_debug_taggedpointer_ext_mask(objc_debug_taggedpointer_ext_mask),
-m_objc_debug_taggedpointer_ext_slot_shift(objc_debug_taggedpointer_ext_slot_shift),
-m_objc_debug_taggedpointer_ext_slot_mask(objc_debug_taggedpointer_ext_slot_mask),
-m_objc_debug_taggedpointer_ext_payload_lshift(objc_debug_taggedpointer_ext_payload_lshift),
-m_objc_debug_taggedpointer_ext_payload_rshift(objc_debug_taggedpointer_ext_payload_rshift),
-m_objc_debug_taggedpointer_ext_classes(objc_debug_taggedpointer_ext_classes)
-{
-}
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended(
+ AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
+ uint64_t objc_debug_taggedpointer_ext_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_ext_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_ext_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_lshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes,
+ lldb::addr_t objc_debug_taggedpointer_ext_classes)
+ : TaggedPointerVendorRuntimeAssisted(
+ runtime, objc_debug_taggedpointer_mask,
+ objc_debug_taggedpointer_slot_shift,
+ objc_debug_taggedpointer_slot_mask,
+ objc_debug_taggedpointer_payload_lshift,
+ objc_debug_taggedpointer_payload_rshift,
+ objc_debug_taggedpointer_classes),
+ m_ext_cache(),
+ m_objc_debug_taggedpointer_ext_mask(objc_debug_taggedpointer_ext_mask),
+ m_objc_debug_taggedpointer_ext_slot_shift(
+ objc_debug_taggedpointer_ext_slot_shift),
+ m_objc_debug_taggedpointer_ext_slot_mask(
+ objc_debug_taggedpointer_ext_slot_mask),
+ m_objc_debug_taggedpointer_ext_payload_lshift(
+ objc_debug_taggedpointer_ext_payload_lshift),
+ m_objc_debug_taggedpointer_ext_payload_rshift(
+ objc_debug_taggedpointer_ext_payload_rshift),
+ m_objc_debug_taggedpointer_ext_classes(
+ objc_debug_taggedpointer_ext_classes) {}
+
+bool AppleObjCRuntimeV2::TaggedPointerVendorExtended::
+ IsPossibleExtendedTaggedPointer(lldb::addr_t ptr) {
+ if (!IsPossibleTaggedPointer(ptr))
+ return false;
-bool
-AppleObjCRuntimeV2::TaggedPointerVendorExtended::IsPossibleExtendedTaggedPointer (lldb::addr_t ptr)
-{
- if (!IsPossibleTaggedPointer(ptr))
- return false;
-
- if (m_objc_debug_taggedpointer_ext_mask == 0)
- return false;
-
- return ((ptr & m_objc_debug_taggedpointer_ext_mask) == m_objc_debug_taggedpointer_ext_mask);
+ if (m_objc_debug_taggedpointer_ext_mask == 0)
+ return false;
+
+ return ((ptr & m_objc_debug_taggedpointer_ext_mask) ==
+ m_objc_debug_taggedpointer_ext_mask);
}
ObjCLanguageRuntime::ClassDescriptorSP
-AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor (lldb::addr_t ptr)
-{
- ClassDescriptorSP actual_class_descriptor_sp;
- uint64_t data_payload;
-
- if (!IsPossibleTaggedPointer(ptr))
- return ObjCLanguageRuntime::ClassDescriptorSP();
-
- if (!IsPossibleExtendedTaggedPointer(ptr))
- return this->TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(ptr);
-
- uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) & m_objc_debug_taggedpointer_ext_slot_mask;
-
- CacheIterator iterator = m_ext_cache.find(slot),
- end = m_ext_cache.end();
- if (iterator != end)
- {
- actual_class_descriptor_sp = iterator->second;
- }
- else
- {
- Process* process(m_runtime.GetProcess());
- uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_ext_classes;
- Error error;
- uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
- if (error.Fail() || slot_data == 0 || slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
- return nullptr;
- actual_class_descriptor_sp = m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
- if (!actual_class_descriptor_sp)
- return ObjCLanguageRuntime::ClassDescriptorSP();
- m_ext_cache[slot] = actual_class_descriptor_sp;
- }
-
- data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift);
-
- return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
+ lldb::addr_t ptr) {
+ ClassDescriptorSP actual_class_descriptor_sp;
+ uint64_t data_payload;
+
+ if (!IsPossibleTaggedPointer(ptr))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ if (!IsPossibleExtendedTaggedPointer(ptr))
+ return this->TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(ptr);
+
+ uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) &
+ m_objc_debug_taggedpointer_ext_slot_mask;
+
+ CacheIterator iterator = m_ext_cache.find(slot), end = m_ext_cache.end();
+ if (iterator != end) {
+ actual_class_descriptor_sp = iterator->second;
+ } else {
+ Process *process(m_runtime.GetProcess());
+ uintptr_t slot_ptr = slot * process->GetAddressByteSize() +
+ m_objc_debug_taggedpointer_ext_classes;
+ Error error;
+ uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
+ if (error.Fail() || slot_data == 0 ||
+ slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
+ return nullptr;
+ actual_class_descriptor_sp =
+ m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
+ if (!actual_class_descriptor_sp)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+ m_ext_cache[slot] = actual_class_descriptor_sp;
+ }
+
+ data_payload =
+ (((uint64_t)ptr << m_objc_debug_taggedpointer_ext_payload_lshift) >>
+ m_objc_debug_taggedpointer_ext_payload_rshift);
+
+ return ClassDescriptorSP(
+ new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
}
-AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache (AppleObjCRuntimeV2& runtime,
- uint64_t objc_debug_isa_class_mask,
- uint64_t objc_debug_isa_magic_mask,
- uint64_t objc_debug_isa_magic_value) :
-m_runtime(runtime),
-m_cache(),
-m_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
-m_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
-m_objc_debug_isa_magic_value(objc_debug_isa_magic_value)
-{
-}
+AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache(
+ AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_isa_class_mask,
+ uint64_t objc_debug_isa_magic_mask, uint64_t objc_debug_isa_magic_value)
+ : m_runtime(runtime), m_cache(),
+ m_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
+ m_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
+ m_objc_debug_isa_magic_value(objc_debug_isa_magic_value) {}
ObjCLanguageRuntime::ClassDescriptorSP
-AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor (ObjCISA isa)
-{
- ObjCISA real_isa = 0;
- if (EvaluateNonPointerISA(isa, real_isa) == false)
- return ObjCLanguageRuntime::ClassDescriptorSP();
- auto cache_iter = m_cache.find(real_isa);
- if (cache_iter != m_cache.end())
- return cache_iter->second;
- auto descriptor_sp = m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(real_isa);
- if (descriptor_sp) // cache only positive matches since the table might grow
- m_cache[real_isa] = descriptor_sp;
- return descriptor_sp;
+AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor(ObjCISA isa) {
+ ObjCISA real_isa = 0;
+ if (EvaluateNonPointerISA(isa, real_isa) == false)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+ auto cache_iter = m_cache.find(real_isa);
+ if (cache_iter != m_cache.end())
+ return cache_iter->second;
+ auto descriptor_sp =
+ m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(real_isa);
+ if (descriptor_sp) // cache only positive matches since the table might grow
+ m_cache[real_isa] = descriptor_sp;
+ return descriptor_sp;
}
-bool
-AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA (ObjCISA isa, ObjCISA& ret_isa)
-{
- if ( (isa & ~m_objc_debug_isa_class_mask) == 0)
- return false;
- if ( (isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value)
- {
- ret_isa = isa & m_objc_debug_isa_class_mask;
- return (ret_isa != 0); // this is a pointer so 0 is not a valid value
- }
+bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
+ ObjCISA isa, ObjCISA &ret_isa) {
+ if ((isa & ~m_objc_debug_isa_class_mask) == 0)
return false;
+ if ((isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value) {
+ ret_isa = isa & m_objc_debug_isa_class_mask;
+ return (ret_isa != 0); // this is a pointer so 0 is not a valid value
+ }
+ return false;
}
-ObjCLanguageRuntime::EncodingToTypeSP
-AppleObjCRuntimeV2::GetEncodingToType ()
-{
- if (!m_encoding_to_type_sp)
- m_encoding_to_type_sp.reset(new AppleObjCTypeEncodingParser(*this));
- return m_encoding_to_type_sp;
+ObjCLanguageRuntime::EncodingToTypeSP AppleObjCRuntimeV2::GetEncodingToType() {
+ if (!m_encoding_to_type_sp)
+ m_encoding_to_type_sp.reset(new AppleObjCTypeEncodingParser(*this));
+ return m_encoding_to_type_sp;
}
lldb_private::AppleObjCRuntime::ObjCISA
-AppleObjCRuntimeV2::GetPointerISA (ObjCISA isa)
-{
- ObjCISA ret = isa;
-
- if (m_non_pointer_isa_cache_ap)
- m_non_pointer_isa_cache_ap->EvaluateNonPointerISA(isa, ret);
-
- return ret;
+AppleObjCRuntimeV2::GetPointerISA(ObjCISA isa) {
+ ObjCISA ret = isa;
+
+ if (m_non_pointer_isa_cache_ap)
+ m_non_pointer_isa_cache_ap->EvaluateNonPointerISA(isa, ret);
+
+ return ret;
+}
+
+bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() {
+ if (m_CFBoolean_values)
+ return true;
+
+ static ConstString g_kCFBooleanFalse("kCFBooleanFalse");
+ static ConstString g_kCFBooleanTrue("kCFBooleanTrue");
+
+ std::function<lldb::addr_t(ConstString)> get_symbol =
+ [this](ConstString sym) -> lldb::addr_t {
+ SymbolContextList sc_list;
+ if (GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ g_kCFBooleanFalse, lldb::eSymbolTypeData, sc_list) == 1) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ if (sc.symbol)
+ return sc.symbol->GetLoadAddress(&GetProcess()->GetTarget());
+ }
+
+ return LLDB_INVALID_ADDRESS;
+ };
+
+ lldb::addr_t false_addr = get_symbol(g_kCFBooleanFalse);
+ lldb::addr_t true_addr = get_symbol(g_kCFBooleanTrue);
+
+ return (m_CFBoolean_values = {false_addr, true_addr}).operator bool();
+}
+
+void AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
+ lldb::addr_t &cf_false) {
+ if (GetCFBooleanValuesIfNeeded()) {
+ cf_true = m_CFBoolean_values->second;
+ cf_false = m_CFBoolean_values->first;
+ } else
+ this->AppleObjCRuntime::GetValuesForGlobalCFBooleans(cf_true, cf_false);
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 4b27c7400481..718073090406 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -18,359 +18,314 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "AppleObjCRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/lldb-private.h"
class RemoteNXMapTable;
namespace lldb_private {
-class AppleObjCRuntimeV2 :
- public AppleObjCRuntime
-{
+class AppleObjCRuntimeV2 : public AppleObjCRuntime {
public:
- ~AppleObjCRuntimeV2() 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();
-
- static bool classof(const ObjCLanguageRuntime* runtime)
- {
- switch (runtime->GetRuntimeVersion())
- {
- case ObjCRuntimeVersions::eAppleObjC_V2:
- return true;
- default:
- return false;
- }
- }
+ ~AppleObjCRuntimeV2() override = default;
- // These are generic runtime functions:
- bool
- GetDynamicTypeAndAddress(ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
-
- UtilityFunction *
- CreateObjectChecker(const char *) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- ObjCRuntimeVersions
- GetRuntimeVersion() const override
- {
- return ObjCRuntimeVersions::eAppleObjC_V2;
- }
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- size_t
- GetByteOffsetForIvar(CompilerType &parent_qual_type, const char *ivar_name) override;
-
- void
- UpdateISAToDescriptorMapIfNeeded() override;
-
- ConstString
- GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) override;
-
- ClassDescriptorSP
- GetClassDescriptor(ValueObject& in_value) override;
-
- ClassDescriptorSP
- GetClassDescriptorFromISA(ObjCISA isa) override;
-
- DeclVendor *
- GetDeclVendor() override;
-
- lldb::addr_t
- LookupRuntimeSymbol(const ConstString &name) override;
-
- EncodingToTypeSP
- GetEncodingToType() override;
-
- TaggedPointerVendor*
- GetTaggedPointerVendor() override
- {
- return m_tagged_pointer_vendor_ap.get();
+ static void Terminate();
+
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static bool classof(const ObjCLanguageRuntime *runtime) {
+ switch (runtime->GetRuntimeVersion()) {
+ case ObjCRuntimeVersions::eAppleObjC_V2:
+ return true;
+ default:
+ return false;
}
-
- // none of these are valid ISAs - we use them to infer the type
- // of tagged pointers - if we have something meaningful to say
- // we report an actual type - otherwise, we just say tagged
- // there is no connection between the values here and the tagged pointers map
- static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
- static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
- static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
- static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
- static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject = 5;
- static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
+ }
+
+ // These are generic runtime functions:
+ bool GetDynamicTypeAndAddress(ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address,
+ Value::ValueType &value_type) override;
+
+ UtilityFunction *CreateObjectChecker(const char *) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ ObjCRuntimeVersions GetRuntimeVersion() const override {
+ return ObjCRuntimeVersions::eAppleObjC_V2;
+ }
+
+ size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
+ const char *ivar_name) override;
+
+ void UpdateISAToDescriptorMapIfNeeded() override;
+
+ ConstString GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) override;
+
+ ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override;
+
+ ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override;
+
+ DeclVendor *GetDeclVendor() override;
+
+ lldb::addr_t LookupRuntimeSymbol(const ConstString &name) override;
+
+ EncodingToTypeSP GetEncodingToType() override;
+
+ TaggedPointerVendor *GetTaggedPointerVendor() override {
+ return m_tagged_pointer_vendor_ap.get();
+ }
+
+ void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
+ lldb::addr_t &cf_false) override;
+
+ // none of these are valid ISAs - we use them to infer the type
+ // of tagged pointers - if we have something meaningful to say
+ // we report an actual type - otherwise, we just say tagged
+ // there is no connection between the values here and the tagged pointers map
+ static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
+ static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
+ static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
+ static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
+ static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject =
+ 5;
+ static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
protected:
- lldb::BreakpointResolverSP
- CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
+ lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
+ bool catch_bp,
+ bool throw_bp) override;
private:
- class HashTableSignature
- {
- public:
- HashTableSignature ();
-
- bool
- NeedsUpdate (Process *process,
- AppleObjCRuntimeV2 *runtime,
+ class HashTableSignature {
+ public:
+ HashTableSignature();
+
+ bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
RemoteNXMapTable &hash_table);
-
- void
- UpdateSignature (const RemoteNXMapTable &hash_table);
-
- protected:
- uint32_t m_count;
- uint32_t m_num_buckets;
- lldb::addr_t m_buckets_ptr;
- };
-
- class NonPointerISACache
- {
- public:
- static NonPointerISACache*
- CreateInstance (AppleObjCRuntimeV2& runtime,
- const lldb::ModuleSP& objc_module_sp);
-
-
- ObjCLanguageRuntime::ClassDescriptorSP
- GetClassDescriptor (ObjCISA isa);
-
- private:
- NonPointerISACache (AppleObjCRuntimeV2& runtime,
- uint64_t objc_debug_isa_class_mask,
- uint64_t objc_debug_isa_magic_mask,
- uint64_t objc_debug_isa_magic_value);
-
- bool
- EvaluateNonPointerISA (ObjCISA isa, ObjCISA& ret_isa);
-
- AppleObjCRuntimeV2& m_runtime;
- std::map<ObjCISA,ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
- uint64_t m_objc_debug_isa_class_mask;
- uint64_t m_objc_debug_isa_magic_mask;
- uint64_t m_objc_debug_isa_magic_value;
-
- friend class AppleObjCRuntimeV2;
-
- DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
- };
-
- class TaggedPointerVendorV2 : public ObjCLanguageRuntime::TaggedPointerVendor
- {
- public:
- ~TaggedPointerVendorV2() override = default;
-
- static TaggedPointerVendorV2*
- CreateInstance (AppleObjCRuntimeV2& runtime,
- const lldb::ModuleSP& objc_module_sp);
-
- protected:
- AppleObjCRuntimeV2& m_runtime;
-
- TaggedPointerVendorV2 (AppleObjCRuntimeV2& runtime) :
- TaggedPointerVendor(),
- m_runtime(runtime)
- {
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
- };
-
- class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2
- {
- public:
- bool
- IsPossibleTaggedPointer(lldb::addr_t ptr) override;
-
- ObjCLanguageRuntime::ClassDescriptorSP
- GetClassDescriptor(lldb::addr_t ptr) override;
-
- protected:
- TaggedPointerVendorRuntimeAssisted (AppleObjCRuntimeV2& runtime,
- uint64_t objc_debug_taggedpointer_mask,
- uint32_t objc_debug_taggedpointer_slot_shift,
- uint32_t objc_debug_taggedpointer_slot_mask,
- uint32_t objc_debug_taggedpointer_payload_lshift,
- uint32_t objc_debug_taggedpointer_payload_rshift,
- lldb::addr_t objc_debug_taggedpointer_classes);
-
- typedef std::map<uint8_t,ObjCLanguageRuntime::ClassDescriptorSP> Cache;
- typedef Cache::iterator CacheIterator;
- Cache m_cache;
- uint64_t m_objc_debug_taggedpointer_mask;
- uint32_t m_objc_debug_taggedpointer_slot_shift;
- uint32_t m_objc_debug_taggedpointer_slot_mask;
- uint32_t m_objc_debug_taggedpointer_payload_lshift;
- uint32_t m_objc_debug_taggedpointer_payload_rshift;
- lldb::addr_t m_objc_debug_taggedpointer_classes;
-
- friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
-
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
- };
-
- class TaggedPointerVendorExtended : public TaggedPointerVendorRuntimeAssisted
- {
- public:
- ObjCLanguageRuntime::ClassDescriptorSP
- GetClassDescriptor(lldb::addr_t ptr) override;
-
- protected:
- TaggedPointerVendorExtended (AppleObjCRuntimeV2& runtime,
- uint64_t objc_debug_taggedpointer_mask,
- uint64_t objc_debug_taggedpointer_ext_mask,
- uint32_t objc_debug_taggedpointer_slot_shift,
- uint32_t objc_debug_taggedpointer_ext_slot_shift,
- uint32_t objc_debug_taggedpointer_slot_mask,
- uint32_t objc_debug_taggedpointer_ext_slot_mask,
- uint32_t objc_debug_taggedpointer_payload_lshift,
- uint32_t objc_debug_taggedpointer_payload_rshift,
- uint32_t objc_debug_taggedpointer_ext_payload_lshift,
- uint32_t objc_debug_taggedpointer_ext_payload_rshift,
- lldb::addr_t objc_debug_taggedpointer_classes,
- lldb::addr_t objc_debug_taggedpointer_ext_classes);
-
- bool
- IsPossibleExtendedTaggedPointer (lldb::addr_t ptr);
-
- typedef std::map<uint8_t,ObjCLanguageRuntime::ClassDescriptorSP> Cache;
- typedef Cache::iterator CacheIterator;
- Cache m_ext_cache;
- uint64_t m_objc_debug_taggedpointer_ext_mask;
- uint32_t m_objc_debug_taggedpointer_ext_slot_shift;
- uint32_t m_objc_debug_taggedpointer_ext_slot_mask;
- uint32_t m_objc_debug_taggedpointer_ext_payload_lshift;
- uint32_t m_objc_debug_taggedpointer_ext_payload_rshift;
- lldb::addr_t m_objc_debug_taggedpointer_ext_classes;
-
- friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
-
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
- };
-
- class TaggedPointerVendorLegacy : public TaggedPointerVendorV2
- {
- public:
- bool
- IsPossibleTaggedPointer(lldb::addr_t ptr) override;
-
- ObjCLanguageRuntime::ClassDescriptorSP
- GetClassDescriptor (lldb::addr_t ptr) override;
-
- protected:
- TaggedPointerVendorLegacy (AppleObjCRuntimeV2& runtime) :
- TaggedPointerVendorV2 (runtime)
- {
- }
-
- friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
-
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
- };
-
- struct DescriptorMapUpdateResult
- {
- bool update_ran;
- bool any_found;
-
- DescriptorMapUpdateResult (bool ran,
- bool found)
- {
- update_ran = ran;
- any_found = found;
- }
-
- static DescriptorMapUpdateResult
- Fail ()
- {
- return {false, false};
- }
-
- static DescriptorMapUpdateResult
- Success ()
- {
- return {true, true};
- }
- };
-
- AppleObjCRuntimeV2 (Process *process,
- const lldb::ModuleSP &objc_module_sp);
-
- ObjCISA
- GetPointerISA (ObjCISA isa);
-
- bool
- IsTaggedPointer(lldb::addr_t ptr);
-
- lldb::addr_t
- GetISAHashTablePointer ();
-
- bool
- UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table);
-
- bool
- UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
-
- uint32_t
- ParseClassInfoArray (const lldb_private::DataExtractor &data,
- uint32_t num_class_infos);
-
- DescriptorMapUpdateResult
- UpdateISAToDescriptorMapSharedCache ();
-
- void
- WarnIfNoClassesCached ();
-
- lldb::addr_t
- GetSharedCacheReadOnlyAddress();
-
- friend class ClassDescriptorV2;
-
- std::unique_ptr<UtilityFunction> m_get_class_info_code;
- lldb::addr_t m_get_class_info_args;
- std::mutex m_get_class_info_args_mutex;
-
- std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
- lldb::addr_t m_get_shared_cache_class_info_args;
- std::mutex m_get_shared_cache_class_info_args_mutex;
-
- std::unique_ptr<DeclVendor> m_decl_vendor_ap;
- lldb::addr_t m_isa_hash_table_ptr;
- HashTableSignature m_hash_signature;
- bool m_has_object_getClass;
- bool m_loaded_objc_opt;
- std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_ap;
- std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_ap;
- EncodingToTypeSP m_encoding_to_type_sp;
- bool m_noclasses_warning_emitted;
+
+ void UpdateSignature(const RemoteNXMapTable &hash_table);
+
+ protected:
+ uint32_t m_count;
+ uint32_t m_num_buckets;
+ lldb::addr_t m_buckets_ptr;
+ };
+
+ class NonPointerISACache {
+ public:
+ static NonPointerISACache *
+ CreateInstance(AppleObjCRuntimeV2 &runtime,
+ const lldb::ModuleSP &objc_module_sp);
+
+ ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa);
+
+ private:
+ NonPointerISACache(AppleObjCRuntimeV2 &runtime,
+ uint64_t objc_debug_isa_class_mask,
+ uint64_t objc_debug_isa_magic_mask,
+ uint64_t objc_debug_isa_magic_value);
+
+ bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
+
+ AppleObjCRuntimeV2 &m_runtime;
+ std::map<ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
+ uint64_t m_objc_debug_isa_class_mask;
+ uint64_t m_objc_debug_isa_magic_mask;
+ uint64_t m_objc_debug_isa_magic_value;
+
+ friend class AppleObjCRuntimeV2;
+
+ DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
+ };
+
+ class TaggedPointerVendorV2
+ : public ObjCLanguageRuntime::TaggedPointerVendor {
+ public:
+ ~TaggedPointerVendorV2() override = default;
+
+ static TaggedPointerVendorV2 *
+ CreateInstance(AppleObjCRuntimeV2 &runtime,
+ const lldb::ModuleSP &objc_module_sp);
+
+ protected:
+ AppleObjCRuntimeV2 &m_runtime;
+
+ TaggedPointerVendorV2(AppleObjCRuntimeV2 &runtime)
+ : TaggedPointerVendor(), m_runtime(runtime) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
+ };
+
+ class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
+ public:
+ bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
+
+ ObjCLanguageRuntime::ClassDescriptorSP
+ GetClassDescriptor(lldb::addr_t ptr) override;
+
+ protected:
+ TaggedPointerVendorRuntimeAssisted(
+ AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes);
+
+ typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
+ typedef Cache::iterator CacheIterator;
+ Cache m_cache;
+ uint64_t m_objc_debug_taggedpointer_mask;
+ uint32_t m_objc_debug_taggedpointer_slot_shift;
+ uint32_t m_objc_debug_taggedpointer_slot_mask;
+ uint32_t m_objc_debug_taggedpointer_payload_lshift;
+ uint32_t m_objc_debug_taggedpointer_payload_rshift;
+ lldb::addr_t m_objc_debug_taggedpointer_classes;
+
+ friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
+
+ DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
+ };
+
+ class TaggedPointerVendorExtended
+ : public TaggedPointerVendorRuntimeAssisted {
+ public:
+ ObjCLanguageRuntime::ClassDescriptorSP
+ GetClassDescriptor(lldb::addr_t ptr) override;
+
+ protected:
+ TaggedPointerVendorExtended(
+ AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
+ uint64_t objc_debug_taggedpointer_ext_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_ext_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_ext_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_lshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes,
+ lldb::addr_t objc_debug_taggedpointer_ext_classes);
+
+ bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr);
+
+ typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
+ typedef Cache::iterator CacheIterator;
+ Cache m_ext_cache;
+ uint64_t m_objc_debug_taggedpointer_ext_mask;
+ uint32_t m_objc_debug_taggedpointer_ext_slot_shift;
+ uint32_t m_objc_debug_taggedpointer_ext_slot_mask;
+ uint32_t m_objc_debug_taggedpointer_ext_payload_lshift;
+ uint32_t m_objc_debug_taggedpointer_ext_payload_rshift;
+ lldb::addr_t m_objc_debug_taggedpointer_ext_classes;
+
+ friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
+
+ DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
+ };
+
+ class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
+ public:
+ bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
+
+ ObjCLanguageRuntime::ClassDescriptorSP
+ GetClassDescriptor(lldb::addr_t ptr) override;
+
+ protected:
+ TaggedPointerVendorLegacy(AppleObjCRuntimeV2 &runtime)
+ : TaggedPointerVendorV2(runtime) {}
+
+ friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
+
+ DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
+ };
+
+ struct DescriptorMapUpdateResult {
+ bool m_update_ran;
+ uint32_t m_num_found;
+
+ DescriptorMapUpdateResult(bool ran, uint32_t found) {
+ m_update_ran = ran;
+ m_num_found = found;
+ }
+
+ static DescriptorMapUpdateResult Fail() { return {false, 0}; }
+
+ static DescriptorMapUpdateResult Success(uint32_t found) {
+ return {true, found};
+ }
+ };
+
+ AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
+
+ ObjCISA GetPointerISA(ObjCISA isa);
+
+ bool IsTaggedPointer(lldb::addr_t ptr);
+
+ lldb::addr_t GetISAHashTablePointer();
+
+ bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
+
+ DescriptorMapUpdateResult
+ UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
+
+ uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
+ uint32_t num_class_infos);
+
+ DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
+
+ enum class SharedCacheWarningReason {
+ eExpressionExecutionFailure,
+ eNotEnoughClassesRead
+ };
+
+ void WarnIfNoClassesCached(SharedCacheWarningReason reason);
+
+ lldb::addr_t GetSharedCacheReadOnlyAddress();
+
+ bool GetCFBooleanValuesIfNeeded();
+
+ friend class ClassDescriptorV2;
+
+ std::unique_ptr<UtilityFunction> m_get_class_info_code;
+ lldb::addr_t m_get_class_info_args;
+ std::mutex m_get_class_info_args_mutex;
+
+ std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
+ lldb::addr_t m_get_shared_cache_class_info_args;
+ std::mutex m_get_shared_cache_class_info_args_mutex;
+
+ std::unique_ptr<DeclVendor> m_decl_vendor_ap;
+ lldb::addr_t m_isa_hash_table_ptr;
+ HashTableSignature m_hash_signature;
+ bool m_has_object_getClass;
+ bool m_loaded_objc_opt;
+ std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_ap;
+ std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_ap;
+ EncodingToTypeSP m_encoding_to_type_sp;
+ bool m_noclasses_warning_emitted;
+ llvm::Optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
};
-
+
} // namespace lldb_private
#endif // liblldb_AppleObjCRuntimeV2_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index 5fedb80e29a6..1dc20c11567e 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -1,4 +1,5 @@
-//===-- AppleObjCTrampolineHandler.cpp ----------------------------*- C++ -*-===//
+//===-- AppleObjCTrampolineHandler.cpp ----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -43,8 +44,11 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector";
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = " \n\
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name =
+ "__lldb_objc_find_implementation_for_selector";
+const char *AppleObjCTrampolineHandler::
+ g_lookup_implementation_with_stret_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
@@ -159,7 +163,9 @@ extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object,
return return_struct.impl_addr; \n\
} \n\
";
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code = " \n\
+const char *
+ AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
@@ -266,887 +272,879 @@ extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object,
} \n\
";
-AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr) :
- m_valid (true),
- m_owner(owner),
- m_header_addr (header_addr),
- m_code_start_addr(0),
- m_code_end_addr (0),
- m_next_region (0)
-{
- SetUpRegion ();
+AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(
+ AppleObjCVTables *owner, lldb::addr_t header_addr)
+ : m_valid(true), m_owner(owner), m_header_addr(header_addr),
+ m_code_start_addr(0), m_code_end_addr(0), m_next_region(0) {
+ SetUpRegion();
}
-AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler()
-{
-}
+AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() {}
-void
-AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion()
-{
- // The header looks like:
- //
- // uint16_t headerSize
- // uint16_t descSize
- // uint32_t descCount
- // void * next
- //
- // First read in the header:
-
- char memory_buffer[16];
- ProcessSP process_sp = m_owner->GetProcessSP();
- if (!process_sp)
- return;
- DataExtractor data(memory_buffer, sizeof(memory_buffer),
- process_sp->GetByteOrder(),
- process_sp->GetAddressByteSize());
- size_t actual_size = 8 + process_sp->GetAddressByteSize();
- Error error;
- size_t bytes_read = process_sp->ReadMemory (m_header_addr, memory_buffer, actual_size, error);
- if (bytes_read != actual_size)
- {
- m_valid = false;
- return;
- }
-
- lldb::offset_t offset = 0;
- const uint16_t header_size = data.GetU16(&offset);
- const uint16_t descriptor_size = data.GetU16(&offset);
- const size_t num_descriptors = data.GetU32(&offset);
-
- m_next_region = data.GetPointer(&offset);
-
- // If the header size is 0, that means we've come in too early before this data is set up.
- // Set ourselves as not valid, and continue.
- if (header_size == 0 || num_descriptors == 0)
- {
- m_valid = false;
- return;
- }
-
- // Now read in all the descriptors:
- // The descriptor looks like:
- //
- // uint32_t offset
- // uint32_t flags
- //
- // Where offset is either 0 - in which case it is unused, or
- // it is the offset of the vtable code from the beginning of the descriptor record.
- // Below, we'll convert that into an absolute code address, since I don't want to have
- // to compute it over and over.
-
- // Ingest the whole descriptor array:
- const lldb::addr_t desc_ptr = m_header_addr + header_size;
- const size_t desc_array_size = num_descriptors * descriptor_size;
- DataBufferSP data_sp(new DataBufferHeap (desc_array_size, '\0'));
- uint8_t* dst = (uint8_t*)data_sp->GetBytes();
-
- DataExtractor desc_extractor (dst, desc_array_size,
- process_sp->GetByteOrder(),
- process_sp->GetAddressByteSize());
- bytes_read = process_sp->ReadMemory(desc_ptr, dst, desc_array_size, error);
- if (bytes_read != desc_array_size)
- {
- m_valid = false;
- return;
- }
-
- // The actual code for the vtables will be laid out consecutively, so I also
- // compute the start and end of the whole code block.
-
- offset = 0;
- m_code_start_addr = 0;
- m_code_end_addr = 0;
-
- for (size_t i = 0; i < num_descriptors; i++)
- {
- lldb::addr_t start_offset = offset;
- uint32_t voffset = desc_extractor.GetU32 (&offset);
- uint32_t flags = desc_extractor.GetU32 (&offset);
- lldb::addr_t code_addr = desc_ptr + start_offset + voffset;
- m_descriptors.push_back (VTableDescriptor(flags, code_addr));
-
- if (m_code_start_addr == 0 || code_addr < m_code_start_addr)
- m_code_start_addr = code_addr;
- if (code_addr > m_code_end_addr)
- m_code_end_addr = code_addr;
-
- offset = start_offset + descriptor_size;
- }
- // Finally, a little bird told me that all the vtable code blocks are the same size.
- // Let's compute the blocks and if they are all the same add the size to the code end address:
- lldb::addr_t code_size = 0;
- bool all_the_same = true;
- for (size_t i = 0; i < num_descriptors - 1; i++)
- {
- lldb::addr_t this_size = m_descriptors[i + 1].code_start - m_descriptors[i].code_start;
- if (code_size == 0)
- code_size = this_size;
- else
- {
- if (this_size != code_size)
- all_the_same = false;
- if (this_size > code_size)
- code_size = this_size;
- }
+void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() {
+ // The header looks like:
+ //
+ // uint16_t headerSize
+ // uint16_t descSize
+ // uint32_t descCount
+ // void * next
+ //
+ // First read in the header:
+
+ char memory_buffer[16];
+ ProcessSP process_sp = m_owner->GetProcessSP();
+ if (!process_sp)
+ return;
+ DataExtractor data(memory_buffer, sizeof(memory_buffer),
+ process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ size_t actual_size = 8 + process_sp->GetAddressByteSize();
+ Error error;
+ size_t bytes_read =
+ process_sp->ReadMemory(m_header_addr, memory_buffer, actual_size, error);
+ if (bytes_read != actual_size) {
+ m_valid = false;
+ return;
+ }
+
+ lldb::offset_t offset = 0;
+ const uint16_t header_size = data.GetU16(&offset);
+ const uint16_t descriptor_size = data.GetU16(&offset);
+ const size_t num_descriptors = data.GetU32(&offset);
+
+ m_next_region = data.GetPointer(&offset);
+
+ // If the header size is 0, that means we've come in too early before this
+ // data is set up.
+ // Set ourselves as not valid, and continue.
+ if (header_size == 0 || num_descriptors == 0) {
+ m_valid = false;
+ return;
+ }
+
+ // Now read in all the descriptors:
+ // The descriptor looks like:
+ //
+ // uint32_t offset
+ // uint32_t flags
+ //
+ // Where offset is either 0 - in which case it is unused, or
+ // it is the offset of the vtable code from the beginning of the descriptor
+ // record.
+ // Below, we'll convert that into an absolute code address, since I don't want
+ // to have
+ // to compute it over and over.
+
+ // Ingest the whole descriptor array:
+ const lldb::addr_t desc_ptr = m_header_addr + header_size;
+ const size_t desc_array_size = num_descriptors * descriptor_size;
+ DataBufferSP data_sp(new DataBufferHeap(desc_array_size, '\0'));
+ uint8_t *dst = (uint8_t *)data_sp->GetBytes();
+
+ DataExtractor desc_extractor(dst, desc_array_size, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ bytes_read = process_sp->ReadMemory(desc_ptr, dst, desc_array_size, error);
+ if (bytes_read != desc_array_size) {
+ m_valid = false;
+ return;
+ }
+
+ // The actual code for the vtables will be laid out consecutively, so I also
+ // compute the start and end of the whole code block.
+
+ offset = 0;
+ m_code_start_addr = 0;
+ m_code_end_addr = 0;
+
+ for (size_t i = 0; i < num_descriptors; i++) {
+ lldb::addr_t start_offset = offset;
+ uint32_t voffset = desc_extractor.GetU32(&offset);
+ uint32_t flags = desc_extractor.GetU32(&offset);
+ lldb::addr_t code_addr = desc_ptr + start_offset + voffset;
+ m_descriptors.push_back(VTableDescriptor(flags, code_addr));
+
+ if (m_code_start_addr == 0 || code_addr < m_code_start_addr)
+ m_code_start_addr = code_addr;
+ if (code_addr > m_code_end_addr)
+ m_code_end_addr = code_addr;
+
+ offset = start_offset + descriptor_size;
+ }
+ // Finally, a little bird told me that all the vtable code blocks are the same
+ // size.
+ // Let's compute the blocks and if they are all the same add the size to the
+ // code end address:
+ lldb::addr_t code_size = 0;
+ bool all_the_same = true;
+ for (size_t i = 0; i < num_descriptors - 1; i++) {
+ lldb::addr_t this_size =
+ m_descriptors[i + 1].code_start - m_descriptors[i].code_start;
+ if (code_size == 0)
+ code_size = this_size;
+ else {
+ if (this_size != code_size)
+ all_the_same = false;
+ if (this_size > code_size)
+ code_size = this_size;
}
- if (all_the_same)
- m_code_end_addr += code_size;
+ }
+ if (all_the_same)
+ m_code_end_addr += code_size;
}
-bool
-AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::AddressInRegion (lldb::addr_t addr, uint32_t &flags)
-{
- if (!IsValid())
- return false;
-
- if (addr < m_code_start_addr || addr > m_code_end_addr)
- return false;
-
- std::vector<VTableDescriptor>::iterator pos, end = m_descriptors.end();
- for (pos = m_descriptors.begin(); pos != end; pos++)
- {
- if (addr <= (*pos).code_start)
- {
- flags = (*pos).flags;
- return true;
- }
- }
+bool AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::
+ AddressInRegion(lldb::addr_t addr, uint32_t &flags) {
+ if (!IsValid())
+ return false;
+
+ if (addr < m_code_start_addr || addr > m_code_end_addr)
return false;
-}
-void
-AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::Dump (Stream &s)
-{
- s.Printf ("Header addr: 0x%" PRIx64 " Code start: 0x%" PRIx64 " Code End: 0x%" PRIx64 " Next: 0x%" PRIx64 "\n",
- m_header_addr, m_code_start_addr, m_code_end_addr, m_next_region);
- size_t num_elements = m_descriptors.size();
- for (size_t i = 0; i < num_elements; i++)
- {
- s.Indent();
- s.Printf ("Code start: 0x%" PRIx64 " Flags: %d\n", m_descriptors[i].code_start, m_descriptors[i].flags);
+ std::vector<VTableDescriptor>::iterator pos, end = m_descriptors.end();
+ for (pos = m_descriptors.begin(); pos != end; pos++) {
+ if (addr <= (*pos).code_start) {
+ flags = (*pos).flags;
+ return true;
}
+ }
+ return false;
}
-
-AppleObjCTrampolineHandler::AppleObjCVTables::AppleObjCVTables (const ProcessSP &process_sp,
- const ModuleSP &objc_module_sp) :
- m_process_wp (),
- m_trampoline_header (LLDB_INVALID_ADDRESS),
- m_trampolines_changed_bp_id (LLDB_INVALID_BREAK_ID),
- m_objc_module_sp (objc_module_sp)
-{
- if (process_sp)
- m_process_wp = process_sp;
+
+void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::Dump(
+ Stream &s) {
+ s.Printf("Header addr: 0x%" PRIx64 " Code start: 0x%" PRIx64
+ " Code End: 0x%" PRIx64 " Next: 0x%" PRIx64 "\n",
+ m_header_addr, m_code_start_addr, m_code_end_addr, m_next_region);
+ size_t num_elements = m_descriptors.size();
+ for (size_t i = 0; i < num_elements; i++) {
+ s.Indent();
+ s.Printf("Code start: 0x%" PRIx64 " Flags: %d\n",
+ m_descriptors[i].code_start, m_descriptors[i].flags);
+ }
}
-AppleObjCTrampolineHandler::AppleObjCVTables::~AppleObjCVTables()
-{
- ProcessSP process_sp = GetProcessSP ();
- if (process_sp)
- {
- if (m_trampolines_changed_bp_id != LLDB_INVALID_BREAK_ID)
- process_sp->GetTarget().RemoveBreakpointByID (m_trampolines_changed_bp_id);
- }
+AppleObjCTrampolineHandler::AppleObjCVTables::AppleObjCVTables(
+ const ProcessSP &process_sp, const ModuleSP &objc_module_sp)
+ : m_process_wp(), m_trampoline_header(LLDB_INVALID_ADDRESS),
+ m_trampolines_changed_bp_id(LLDB_INVALID_BREAK_ID),
+ m_objc_module_sp(objc_module_sp) {
+ if (process_sp)
+ m_process_wp = process_sp;
}
-bool
-AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols ()
-{
- if (m_trampoline_header != LLDB_INVALID_ADDRESS)
- return true;
+AppleObjCTrampolineHandler::AppleObjCVTables::~AppleObjCVTables() {
+ ProcessSP process_sp = GetProcessSP();
+ if (process_sp) {
+ if (m_trampolines_changed_bp_id != LLDB_INVALID_BREAK_ID)
+ process_sp->GetTarget().RemoveBreakpointByID(m_trampolines_changed_bp_id);
+ }
+}
- ProcessSP process_sp = GetProcessSP ();
- if (process_sp)
- {
- Target &target = process_sp->GetTarget();
-
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- size_t num_modules = target_modules.GetSize();
- if (!m_objc_module_sp)
- {
- for (size_t i = 0; i < num_modules; i++)
- {
- if (process_sp->GetObjCLanguageRuntime()->IsModuleObjCLibrary (target_modules.GetModuleAtIndexUnlocked(i)))
- {
- m_objc_module_sp = target_modules.GetModuleAtIndexUnlocked(i);
- break;
- }
- }
- }
-
- if (m_objc_module_sp)
- {
- ConstString trampoline_name ("gdb_objc_trampolines");
- const Symbol *trampoline_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (trampoline_name,
- eSymbolTypeData);
- if (trampoline_symbol != NULL)
- {
- m_trampoline_header = trampoline_symbol->GetLoadAddress(&target);
- if (m_trampoline_header == LLDB_INVALID_ADDRESS)
- return false;
-
- // Next look up the "changed" symbol and set a breakpoint on that...
- ConstString changed_name ("gdb_objc_trampolines_changed");
- const Symbol *changed_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (changed_name,
- eSymbolTypeCode);
- if (changed_symbol != NULL)
- {
- const Address changed_symbol_addr = changed_symbol->GetAddress();
- if (!changed_symbol_addr.IsValid())
- return false;
-
- lldb::addr_t changed_addr = changed_symbol_addr.GetOpcodeLoadAddress (&target);
- if (changed_addr != LLDB_INVALID_ADDRESS)
- {
- BreakpointSP trampolines_changed_bp_sp = target.CreateBreakpoint (changed_addr, true, false);
- if (trampolines_changed_bp_sp)
- {
- m_trampolines_changed_bp_id = trampolines_changed_bp_sp->GetID();
- trampolines_changed_bp_sp->SetCallback (RefreshTrampolines, this, true);
- trampolines_changed_bp_sp->SetBreakpointKind ("objc-trampolines-changed");
- return true;
- }
- }
- }
- }
+bool AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols() {
+ if (m_trampoline_header != LLDB_INVALID_ADDRESS)
+ return true;
+
+ ProcessSP process_sp = GetProcessSP();
+ if (process_sp) {
+ Target &target = process_sp->GetTarget();
+
+ const ModuleList &target_modules = target.GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ size_t num_modules = target_modules.GetSize();
+ if (!m_objc_module_sp) {
+ for (size_t i = 0; i < num_modules; i++) {
+ if (process_sp->GetObjCLanguageRuntime()->IsModuleObjCLibrary(
+ target_modules.GetModuleAtIndexUnlocked(i))) {
+ m_objc_module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+ break;
}
+ }
}
- return false;
-}
-
-bool
-AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
-{
- AppleObjCVTables *vtable_handler = (AppleObjCVTables *) baton;
- if (vtable_handler->InitializeVTableSymbols())
- {
- // The Update function is called with the address of an added region. So we grab that address, and
- // feed it into ReadRegions. Of course, our friend the ABI will get the values for us.
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Process *process = exe_ctx.GetProcessPtr();
- const ABI *abi = process->GetABI().get();
-
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- ValueList argument_values;
- Value input_value;
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- input_value.SetValueType (Value::eValueTypeScalar);
- //input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
- input_value.SetCompilerType (clang_void_ptr_type);
- argument_values.PushValue(input_value);
-
- bool success = abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values);
- if (!success)
+
+ if (m_objc_module_sp) {
+ ConstString trampoline_name("gdb_objc_trampolines");
+ const Symbol *trampoline_symbol =
+ m_objc_module_sp->FindFirstSymbolWithNameAndType(trampoline_name,
+ eSymbolTypeData);
+ if (trampoline_symbol != NULL) {
+ m_trampoline_header = trampoline_symbol->GetLoadAddress(&target);
+ if (m_trampoline_header == LLDB_INVALID_ADDRESS)
+ return false;
+
+ // Next look up the "changed" symbol and set a breakpoint on that...
+ ConstString changed_name("gdb_objc_trampolines_changed");
+ const Symbol *changed_symbol =
+ m_objc_module_sp->FindFirstSymbolWithNameAndType(changed_name,
+ eSymbolTypeCode);
+ if (changed_symbol != NULL) {
+ const Address changed_symbol_addr = changed_symbol->GetAddress();
+ if (!changed_symbol_addr.IsValid())
return false;
-
- // Now get a pointer value from the zeroth argument.
- Error error;
- DataExtractor data;
- error = argument_values.GetValueAtIndex(0)->GetValueAsData (&exe_ctx,
- data,
- 0,
- NULL);
- lldb::offset_t offset = 0;
- lldb::addr_t region_addr = data.GetPointer(&offset);
-
- if (region_addr != 0)
- vtable_handler->ReadRegions(region_addr);
+
+ lldb::addr_t changed_addr =
+ changed_symbol_addr.GetOpcodeLoadAddress(&target);
+ if (changed_addr != LLDB_INVALID_ADDRESS) {
+ BreakpointSP trampolines_changed_bp_sp =
+ target.CreateBreakpoint(changed_addr, true, false);
+ if (trampolines_changed_bp_sp) {
+ m_trampolines_changed_bp_id = trampolines_changed_bp_sp->GetID();
+ trampolines_changed_bp_sp->SetCallback(RefreshTrampolines, this,
+ true);
+ trampolines_changed_bp_sp->SetBreakpointKind(
+ "objc-trampolines-changed");
+ return true;
+ }
+ }
+ }
+ }
}
- return false;
+ }
+ return false;
}
-bool
-AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions ()
-{
- // The no argument version reads the start region from the value of the gdb_regions_header, and
- // gets started from there.
-
- m_regions.clear();
- if (!InitializeVTableSymbols())
- return false;
+bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
+ void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ AppleObjCVTables *vtable_handler = (AppleObjCVTables *)baton;
+ if (vtable_handler->InitializeVTableSymbols()) {
+ // The Update function is called with the address of an added region. So we
+ // grab that address, and
+ // feed it into ReadRegions. Of course, our friend the ABI will get the
+ // values for us.
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Process *process = exe_ctx.GetProcessPtr();
+ const ABI *abi = process->GetABI().get();
+
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ ValueList argument_values;
+ Value input_value;
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ input_value.SetValueType(Value::eValueTypeScalar);
+ // input_value.SetContext (Value::eContextTypeClangType,
+ // clang_void_ptr_type);
+ input_value.SetCompilerType(clang_void_ptr_type);
+ argument_values.PushValue(input_value);
+
+ bool success =
+ abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values);
+ if (!success)
+ return false;
+
+ // Now get a pointer value from the zeroth argument.
Error error;
- ProcessSP process_sp = GetProcessSP ();
- if (process_sp)
- {
- lldb::addr_t region_addr = process_sp->ReadPointerFromMemory (m_trampoline_header, error);
- if (error.Success())
- return ReadRegions (region_addr);
- }
+ DataExtractor data;
+ error = argument_values.GetValueAtIndex(0)->GetValueAsData(&exe_ctx, data,
+ 0, NULL);
+ lldb::offset_t offset = 0;
+ lldb::addr_t region_addr = data.GetPointer(&offset);
+
+ if (region_addr != 0)
+ vtable_handler->ReadRegions(region_addr);
+ }
+ return false;
+}
+
+bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions() {
+ // The no argument version reads the start region from the value of the
+ // gdb_regions_header, and
+ // gets started from there.
+
+ m_regions.clear();
+ if (!InitializeVTableSymbols())
return false;
+ Error error;
+ ProcessSP process_sp = GetProcessSP();
+ if (process_sp) {
+ lldb::addr_t region_addr =
+ process_sp->ReadPointerFromMemory(m_trampoline_header, error);
+ if (error.Success())
+ return ReadRegions(region_addr);
+ }
+ return false;
}
-bool
-AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions (lldb::addr_t region_addr)
-{
- ProcessSP process_sp = GetProcessSP ();
- if (!process_sp)
- return false;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
- // We aren't starting at the trampoline symbol.
- InitializeVTableSymbols ();
- lldb::addr_t next_region = region_addr;
-
- // Read in the sizes of the headers.
- while (next_region != 0)
- {
- m_regions.push_back (VTableRegion(this, next_region));
- if (!m_regions.back().IsValid())
- {
- m_regions.clear();
- return false;
- }
- if (log)
- {
- StreamString s;
- m_regions.back().Dump(s);
- log->Printf("Read vtable region: \n%s", s.GetData());
- }
-
- next_region = m_regions.back().GetNextRegionAddr();
+bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions(
+ lldb::addr_t region_addr) {
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
+ // We aren't starting at the trampoline symbol.
+ InitializeVTableSymbols();
+ lldb::addr_t next_region = region_addr;
+
+ // Read in the sizes of the headers.
+ while (next_region != 0) {
+ m_regions.push_back(VTableRegion(this, next_region));
+ if (!m_regions.back().IsValid()) {
+ m_regions.clear();
+ return false;
}
-
- return true;
-}
-
-bool
-AppleObjCTrampolineHandler::AppleObjCVTables::IsAddressInVTables (lldb::addr_t addr, uint32_t &flags)
-{
- region_collection::iterator pos, end = m_regions.end();
- for (pos = m_regions.begin(); pos != end; pos++)
- {
- if ((*pos).AddressInRegion (addr, flags))
- return true;
+ if (log) {
+ StreamString s;
+ m_regions.back().Dump(s);
+ log->Printf("Read vtable region: \n%s", s.GetData());
}
- return false;
+
+ next_region = m_regions.back().GetNextRegionAddr();
+ }
+
+ return true;
+}
+
+bool AppleObjCTrampolineHandler::AppleObjCVTables::IsAddressInVTables(
+ lldb::addr_t addr, uint32_t &flags) {
+ region_collection::iterator pos, end = m_regions.end();
+ for (pos = m_regions.begin(); pos != end; pos++) {
+ if ((*pos).AddressInRegion(addr, flags))
+ return true;
+ }
+ return false;
}
const AppleObjCTrampolineHandler::DispatchFunction
-AppleObjCTrampolineHandler::g_dispatch_functions[] =
-{
- // NAME STRET SUPER SUPER2 FIXUP TYPE
- {"objc_msgSend", false, false, false, DispatchFunction::eFixUpNone },
- {"objc_msgSend_fixup", false, false, false, DispatchFunction::eFixUpToFix },
- {"objc_msgSend_fixedup", false, false, false, DispatchFunction::eFixUpFixed },
- {"objc_msgSend_stret", true, false, false, DispatchFunction::eFixUpNone },
- {"objc_msgSend_stret_fixup", true, false, false, DispatchFunction::eFixUpToFix },
- {"objc_msgSend_stret_fixedup", true, false, false, DispatchFunction::eFixUpFixed },
- {"objc_msgSend_fpret", false, false, false, DispatchFunction::eFixUpNone },
- {"objc_msgSend_fpret_fixup", false, false, false, DispatchFunction::eFixUpToFix },
- {"objc_msgSend_fpret_fixedup", false, false, false, DispatchFunction::eFixUpFixed },
- {"objc_msgSend_fp2ret", false, false, true, DispatchFunction::eFixUpNone },
- {"objc_msgSend_fp2ret_fixup", false, false, true, DispatchFunction::eFixUpToFix },
- {"objc_msgSend_fp2ret_fixedup", false, false, true, DispatchFunction::eFixUpFixed },
- {"objc_msgSendSuper", false, true, false, DispatchFunction::eFixUpNone },
- {"objc_msgSendSuper_stret", true, true, false, DispatchFunction::eFixUpNone },
- {"objc_msgSendSuper2", false, true, true, DispatchFunction::eFixUpNone },
- {"objc_msgSendSuper2_fixup", false, true, true, DispatchFunction::eFixUpToFix },
- {"objc_msgSendSuper2_fixedup", false, true, true, DispatchFunction::eFixUpFixed },
- {"objc_msgSendSuper2_stret", true, true, true, DispatchFunction::eFixUpNone },
- {"objc_msgSendSuper2_stret_fixup", true, true, true, DispatchFunction::eFixUpToFix },
- {"objc_msgSendSuper2_stret_fixedup", true, true, true, DispatchFunction::eFixUpFixed },
+ AppleObjCTrampolineHandler::g_dispatch_functions[] = {
+ // NAME STRET SUPER SUPER2 FIXUP TYPE
+ {"objc_msgSend", false, false, false, DispatchFunction::eFixUpNone},
+ {"objc_msgSend_fixup", false, false, false,
+ DispatchFunction::eFixUpToFix},
+ {"objc_msgSend_fixedup", false, false, false,
+ DispatchFunction::eFixUpFixed},
+ {"objc_msgSend_stret", true, false, false,
+ DispatchFunction::eFixUpNone},
+ {"objc_msgSend_stret_fixup", true, false, false,
+ DispatchFunction::eFixUpToFix},
+ {"objc_msgSend_stret_fixedup", true, false, false,
+ DispatchFunction::eFixUpFixed},
+ {"objc_msgSend_fpret", false, false, false,
+ DispatchFunction::eFixUpNone},
+ {"objc_msgSend_fpret_fixup", false, false, false,
+ DispatchFunction::eFixUpToFix},
+ {"objc_msgSend_fpret_fixedup", false, false, false,
+ DispatchFunction::eFixUpFixed},
+ {"objc_msgSend_fp2ret", false, false, true,
+ DispatchFunction::eFixUpNone},
+ {"objc_msgSend_fp2ret_fixup", false, false, true,
+ DispatchFunction::eFixUpToFix},
+ {"objc_msgSend_fp2ret_fixedup", false, false, true,
+ DispatchFunction::eFixUpFixed},
+ {"objc_msgSendSuper", false, true, false, DispatchFunction::eFixUpNone},
+ {"objc_msgSendSuper_stret", true, true, false,
+ DispatchFunction::eFixUpNone},
+ {"objc_msgSendSuper2", false, true, true, DispatchFunction::eFixUpNone},
+ {"objc_msgSendSuper2_fixup", false, true, true,
+ DispatchFunction::eFixUpToFix},
+ {"objc_msgSendSuper2_fixedup", false, true, true,
+ DispatchFunction::eFixUpFixed},
+ {"objc_msgSendSuper2_stret", true, true, true,
+ DispatchFunction::eFixUpNone},
+ {"objc_msgSendSuper2_stret_fixup", true, true, true,
+ DispatchFunction::eFixUpToFix},
+ {"objc_msgSendSuper2_stret_fixedup", true, true, true,
+ DispatchFunction::eFixUpFixed},
};
-AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process_sp,
- const ModuleSP &objc_module_sp) :
- m_process_wp (),
- m_objc_module_sp (objc_module_sp),
- m_lookup_implementation_function_code(nullptr),
- m_impl_fn_addr (LLDB_INVALID_ADDRESS),
- m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS),
- m_msg_forward_addr (LLDB_INVALID_ADDRESS)
-{
- if (process_sp)
- m_process_wp = process_sp;
- // Look up the known resolution functions:
-
- ConstString get_impl_name("class_getMethodImplementation");
- ConstString get_impl_stret_name("class_getMethodImplementation_stret");
- ConstString msg_forward_name("_objc_msgForward");
- ConstString msg_forward_stret_name("_objc_msgForward_stret");
-
- Target *target = process_sp ? &process_sp->GetTarget() : NULL;
- const Symbol *class_getMethodImplementation = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_name, eSymbolTypeCode);
- const Symbol *class_getMethodImplementation_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_stret_name, eSymbolTypeCode);
- const Symbol *msg_forward = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_name, eSymbolTypeCode);
- const Symbol *msg_forward_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_stret_name, eSymbolTypeCode);
-
- if (class_getMethodImplementation)
- m_impl_fn_addr = class_getMethodImplementation->GetAddress().GetOpcodeLoadAddress (target);
- if (class_getMethodImplementation_stret)
- m_impl_stret_fn_addr = class_getMethodImplementation_stret->GetAddress().GetOpcodeLoadAddress (target);
- if (msg_forward)
- m_msg_forward_addr = msg_forward->GetAddress().GetOpcodeLoadAddress(target);
- if (msg_forward_stret)
- m_msg_forward_stret_addr = msg_forward_stret->GetAddress().GetOpcodeLoadAddress(target);
-
- // FIXME: Do some kind of logging here.
- if (m_impl_fn_addr == LLDB_INVALID_ADDRESS)
- {
- // If we can't even find the ordinary get method implementation function, then we aren't going to be able to
- // step through any method dispatches. Warn to that effect and get out of here.
- if (process_sp->CanJIT())
- {
- process_sp->GetTarget().GetDebugger().GetErrorFile()->Printf ("Could not find implementation lookup function \"%s\""
- " step in through ObjC method dispatch will not work.\n",
- get_impl_name.AsCString());
- }
- return;
- }
- else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS)
- {
- // It there is no stret return lookup function, assume that it is the same as the straight lookup:
- m_impl_stret_fn_addr = m_impl_fn_addr;
- // Also we will use the version of the lookup code that doesn't rely on the stret version of the function.
- m_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
- }
- else
- {
- m_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
+AppleObjCTrampolineHandler::AppleObjCTrampolineHandler(
+ const ProcessSP &process_sp, const ModuleSP &objc_module_sp)
+ : m_process_wp(), m_objc_module_sp(objc_module_sp),
+ m_lookup_implementation_function_code(nullptr),
+ m_impl_fn_addr(LLDB_INVALID_ADDRESS),
+ m_impl_stret_fn_addr(LLDB_INVALID_ADDRESS),
+ m_msg_forward_addr(LLDB_INVALID_ADDRESS) {
+ if (process_sp)
+ m_process_wp = process_sp;
+ // Look up the known resolution functions:
+
+ ConstString get_impl_name("class_getMethodImplementation");
+ ConstString get_impl_stret_name("class_getMethodImplementation_stret");
+ ConstString msg_forward_name("_objc_msgForward");
+ ConstString msg_forward_stret_name("_objc_msgForward_stret");
+
+ Target *target = process_sp ? &process_sp->GetTarget() : NULL;
+ const Symbol *class_getMethodImplementation =
+ m_objc_module_sp->FindFirstSymbolWithNameAndType(get_impl_name,
+ eSymbolTypeCode);
+ const Symbol *class_getMethodImplementation_stret =
+ m_objc_module_sp->FindFirstSymbolWithNameAndType(get_impl_stret_name,
+ eSymbolTypeCode);
+ const Symbol *msg_forward = m_objc_module_sp->FindFirstSymbolWithNameAndType(
+ msg_forward_name, eSymbolTypeCode);
+ const Symbol *msg_forward_stret =
+ m_objc_module_sp->FindFirstSymbolWithNameAndType(msg_forward_stret_name,
+ eSymbolTypeCode);
+
+ if (class_getMethodImplementation)
+ m_impl_fn_addr =
+ class_getMethodImplementation->GetAddress().GetOpcodeLoadAddress(
+ target);
+ if (class_getMethodImplementation_stret)
+ m_impl_stret_fn_addr =
+ class_getMethodImplementation_stret->GetAddress().GetOpcodeLoadAddress(
+ target);
+ if (msg_forward)
+ m_msg_forward_addr = msg_forward->GetAddress().GetOpcodeLoadAddress(target);
+ if (msg_forward_stret)
+ m_msg_forward_stret_addr =
+ msg_forward_stret->GetAddress().GetOpcodeLoadAddress(target);
+
+ // FIXME: Do some kind of logging here.
+ if (m_impl_fn_addr == LLDB_INVALID_ADDRESS) {
+ // If we can't even find the ordinary get method implementation function,
+ // then we aren't going to be able to
+ // step through any method dispatches. Warn to that effect and get out of
+ // here.
+ if (process_sp->CanJIT()) {
+ process_sp->GetTarget().GetDebugger().GetErrorFile()->Printf(
+ "Could not find implementation lookup function \"%s\""
+ " step in through ObjC method dispatch will not work.\n",
+ get_impl_name.AsCString());
}
-
- // Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol
- // names dynamically to figure out how to dispatch to them. If it becomes more complicated than this we can
- // turn the g_dispatch_functions char * array into a template table, and populate the DispatchFunction map
- // from there.
-
- for (size_t i = 0; i != llvm::array_lengthof(g_dispatch_functions); i++)
- {
- ConstString name_const_str(g_dispatch_functions[i].name);
- const Symbol *msgSend_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (name_const_str, eSymbolTypeCode);
- if (msgSend_symbol && msgSend_symbol->ValueIsAddress())
- {
- // FixMe: Make g_dispatch_functions static table of DispatchFunctions, and have the map be address->index.
- // Problem is we also need to lookup the dispatch function. For now we could have a side table of stret & non-stret
- // dispatch functions. If that's as complex as it gets, we're fine.
-
- lldb::addr_t sym_addr = msgSend_symbol->GetAddressRef().GetOpcodeLoadAddress(target);
-
- m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i));
- }
+ return;
+ } else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) {
+ // It there is no stret return lookup function, assume that it is the same
+ // as the straight lookup:
+ m_impl_stret_fn_addr = m_impl_fn_addr;
+ // Also we will use the version of the lookup code that doesn't rely on the
+ // stret version of the function.
+ m_lookup_implementation_function_code =
+ g_lookup_implementation_no_stret_function_code;
+ } else {
+ m_lookup_implementation_function_code =
+ g_lookup_implementation_with_stret_function_code;
+ }
+
+ // Look up the addresses for the objc dispatch functions and cache them. For
+ // now I'm inspecting the symbol
+ // names dynamically to figure out how to dispatch to them. If it becomes
+ // more complicated than this we can
+ // turn the g_dispatch_functions char * array into a template table, and
+ // populate the DispatchFunction map
+ // from there.
+
+ for (size_t i = 0; i != llvm::array_lengthof(g_dispatch_functions); i++) {
+ ConstString name_const_str(g_dispatch_functions[i].name);
+ const Symbol *msgSend_symbol =
+ m_objc_module_sp->FindFirstSymbolWithNameAndType(name_const_str,
+ eSymbolTypeCode);
+ if (msgSend_symbol && msgSend_symbol->ValueIsAddress()) {
+ // FixMe: Make g_dispatch_functions static table of DispatchFunctions, and
+ // have the map be address->index.
+ // Problem is we also need to lookup the dispatch function. For now we
+ // could have a side table of stret & non-stret
+ // dispatch functions. If that's as complex as it gets, we're fine.
+
+ lldb::addr_t sym_addr =
+ msgSend_symbol->GetAddressRef().GetOpcodeLoadAddress(target);
+
+ m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i));
}
-
- // Build our vtable dispatch handler here:
- m_vtables_ap.reset(new AppleObjCVTables(process_sp, m_objc_module_sp));
- if (m_vtables_ap.get())
- m_vtables_ap->ReadRegions();
+ }
+
+ // Build our vtable dispatch handler here:
+ m_vtables_ap.reset(new AppleObjCVTables(process_sp, m_objc_module_sp));
+ if (m_vtables_ap.get())
+ m_vtables_ap->ReadRegions();
}
lldb::addr_t
-AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, ValueList &dispatch_values)
-{
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx (thread_sp);
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
+ ValueList &dispatch_values) {
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx(thread_sp);
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *impl_function_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_impl_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_impl_code.get())
- {
- if (m_lookup_implementation_function_code != NULL)
- {
- Error error;
- m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (m_lookup_implementation_function_code,
- eLanguageTypeObjC,
- g_lookup_implementation_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get Utility Function for implementation lookup: %s.", error.AsCString());
- m_impl_code.reset();
- return args_addr;
- }
-
- if (!m_impl_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install implementation lookup.");
- diagnostics.Dump(log);
- }
- m_impl_code.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- log->Printf("No method lookup implementation code.");
- return LLDB_INVALID_ADDRESS;
- }
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *impl_function_caller = nullptr;
- // Next make the runner function for our implementation utility function.
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Error error;
-
- impl_function_caller = m_impl_code->MakeFunctionCaller(clang_void_ptr_type,
- dispatch_values,
- thread_sp,
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Error getting function caller for dispatch lookup: \"%s\".", error.AsCString());
- return args_addr;
- }
- }
- else
- {
- impl_function_caller = m_impl_code->GetFunctionCaller();
- }
- }
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_impl_function_mutex);
- diagnostics.Clear();
+ // First stage is to make the ClangUtility to hold our injected function:
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ if (!m_impl_code.get()) {
+ if (m_lookup_implementation_function_code != NULL) {
+ Error error;
+ m_impl_code.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ m_lookup_implementation_function_code, eLanguageTypeObjC,
+ g_lookup_implementation_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Failed to get Utility Function for implementation lookup: %s.",
+ error.AsCString());
+ m_impl_code.reset();
+ return args_addr;
+ }
- if (!impl_function_caller->WriteFunctionArguments(exe_ctx, args_addr, dispatch_values, diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing function arguments.");
+ if (!m_impl_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install implementation lookup.");
diagnostics.Dump(log);
+ }
+ m_impl_code.reset();
+ return args_addr;
}
+ } else {
+ if (log)
+ log->Printf("No method lookup implementation code.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Next make the runner function for our implementation utility function.
+ ClangASTContext *clang_ast_context =
+ thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Error error;
+
+ impl_function_caller = m_impl_code->MakeFunctionCaller(
+ clang_void_ptr_type, dispatch_values, thread_sp, error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Error getting function caller for dispatch lookup: \"%s\".",
+ error.AsCString());
return args_addr;
+ }
+ } else {
+ impl_function_caller = m_impl_code->GetFunctionCaller();
}
+ }
+ diagnostics.Clear();
+
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+ if (!impl_function_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, dispatch_values, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
return args_addr;
+ }
+
+ return args_addr;
}
ThreadPlanSP
-AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_others)
-{
- ThreadPlanSP ret_plan_sp;
- lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
-
- DispatchFunction this_dispatch;
- bool found_it = false;
-
- // First step is to look and see if we are in one of the known ObjC dispatch functions. We've already compiled
- // a table of same, so consult it.
-
- MsgsendMap::iterator pos;
- pos = m_msgSend_map.find (curr_pc);
- if (pos != m_msgSend_map.end())
- {
- this_dispatch = g_dispatch_functions[(*pos).second];
- found_it = true;
+AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
+ bool stop_others) {
+ ThreadPlanSP ret_plan_sp;
+ lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
+
+ DispatchFunction this_dispatch;
+ bool found_it = false;
+
+ // First step is to look and see if we are in one of the known ObjC dispatch
+ // functions. We've already compiled
+ // a table of same, so consult it.
+
+ MsgsendMap::iterator pos;
+ pos = m_msgSend_map.find(curr_pc);
+ if (pos != m_msgSend_map.end()) {
+ this_dispatch = g_dispatch_functions[(*pos).second];
+ found_it = true;
+ }
+
+ // Next check to see if we are in a vtable region:
+
+ if (!found_it) {
+ uint32_t flags;
+ if (m_vtables_ap.get()) {
+ found_it = m_vtables_ap->IsAddressInVTables(curr_pc, flags);
+ if (found_it) {
+ this_dispatch.name = "vtable";
+ this_dispatch.stret_return =
+ (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) ==
+ AppleObjCVTables::eOBJC_TRAMPOLINE_STRET;
+ this_dispatch.is_super = false;
+ this_dispatch.is_super2 = false;
+ this_dispatch.fixedup = DispatchFunction::eFixUpFixed;
+ }
}
-
- // Next check to see if we are in a vtable region:
-
- if (!found_it)
- {
- uint32_t flags;
- if (m_vtables_ap.get())
- {
- found_it = m_vtables_ap->IsAddressInVTables (curr_pc, flags);
- if (found_it)
- {
- this_dispatch.name = "vtable";
- this_dispatch.stret_return
- = (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) == AppleObjCVTables::eOBJC_TRAMPOLINE_STRET;
- this_dispatch.is_super = false;
- this_dispatch.is_super2 = false;
- this_dispatch.fixedup = DispatchFunction::eFixUpFixed;
- }
- }
+ }
+
+ if (found_it) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
+ // We are decoding a method dispatch.
+ // First job is to pull the arguments out:
+
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+
+ const ABI *abi = NULL;
+ ProcessSP process_sp(thread.CalculateProcess());
+ if (process_sp)
+ abi = process_sp->GetABI().get();
+ if (abi == NULL)
+ return ret_plan_sp;
+
+ TargetSP target_sp(thread.CalculateTarget());
+
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ ValueList argument_values;
+ Value void_ptr_value;
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ void_ptr_value.SetValueType(Value::eValueTypeScalar);
+ // void_ptr_value.SetContext (Value::eContextTypeClangType,
+ // clang_void_ptr_type);
+ void_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ int obj_index;
+ int sel_index;
+
+ // If this is a struct return dispatch, then the first argument is the
+ // return struct pointer, and the object is the second, and the selector is
+ // the third.
+ // Otherwise the object is the first and the selector the second.
+ if (this_dispatch.stret_return) {
+ obj_index = 1;
+ sel_index = 2;
+ argument_values.PushValue(void_ptr_value);
+ argument_values.PushValue(void_ptr_value);
+ argument_values.PushValue(void_ptr_value);
+ } else {
+ obj_index = 0;
+ sel_index = 1;
+ argument_values.PushValue(void_ptr_value);
+ argument_values.PushValue(void_ptr_value);
}
-
- if (found_it)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
- // We are decoding a method dispatch.
- // First job is to pull the arguments out:
-
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
-
- const ABI *abi = NULL;
- ProcessSP process_sp (thread.CalculateProcess());
- if (process_sp)
- abi = process_sp->GetABI().get();
- if (abi == NULL)
- return ret_plan_sp;
-
- TargetSP target_sp (thread.CalculateTarget());
-
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- ValueList argument_values;
- Value void_ptr_value;
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- void_ptr_value.SetValueType (Value::eValueTypeScalar);
- //void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
- void_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- int obj_index;
- int sel_index;
-
- // If this is a struct return dispatch, then the first argument is the
- // return struct pointer, and the object is the second, and the selector is the third.
- // Otherwise the object is the first and the selector the second.
- if (this_dispatch.stret_return)
- {
- obj_index = 1;
- sel_index = 2;
- argument_values.PushValue(void_ptr_value);
- argument_values.PushValue(void_ptr_value);
- argument_values.PushValue(void_ptr_value);
- }
- else
- {
- obj_index = 0;
- sel_index = 1;
- argument_values.PushValue(void_ptr_value);
- argument_values.PushValue(void_ptr_value);
- }
-
- bool success = abi->GetArgumentValues (thread, argument_values);
- if (!success)
- return ret_plan_sp;
-
- lldb::addr_t obj_addr = argument_values.GetValueAtIndex(obj_index)->GetScalar().ULongLong();
- if (obj_addr == 0x0)
- {
- if (log)
- log->Printf("Asked to step to dispatch to nil object, returning empty plan.");
- return ret_plan_sp;
- }
-
- ExecutionContext exe_ctx (thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- // isa_addr will store the class pointer that the method is being dispatched to - so either the class
- // directly or the super class if this is one of the objc_msgSendSuper flavors. That's mostly used to
- // look up the class/selector pair in our cache.
-
- lldb::addr_t isa_addr = LLDB_INVALID_ADDRESS;
- lldb::addr_t sel_addr = argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong();
-
- // Figure out the class this is being dispatched to and see if we've already cached this method call,
- // If so we can push a run-to-address plan directly. Otherwise we have to figure out where
- // the implementation lives.
-
- if (this_dispatch.is_super)
- {
- if (this_dispatch.is_super2)
- {
- // In the objc_msgSendSuper2 case, we don't get the object directly, we get a structure containing
- // the object and the class to which the super message is being sent. So we need to dig the super
- // out of the class and use that.
-
- Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
- super_value.GetScalar() += process->GetAddressByteSize();
- super_value.ResolveValue (&exe_ctx);
-
- if (super_value.GetScalar().IsValid())
- {
-
- // isa_value now holds the class pointer. The second word of the class pointer is the super-class pointer:
- super_value.GetScalar() += process->GetAddressByteSize();
- super_value.ResolveValue (&exe_ctx);
- if (super_value.GetScalar().IsValid())
- isa_addr = super_value.GetScalar().ULongLong();
- else
- {
- if (log)
- log->Printf("Failed to extract the super class value from the class in objc_super.");
- }
- }
- else
- {
- if (log)
- log->Printf("Failed to extract the class value from objc_super.");
- }
- }
- else
- {
- // In the objc_msgSendSuper case, we don't get the object directly, we get a two element structure containing
- // the object and the super class to which the super message is being sent. So the class we want is
- // the second element of this structure.
-
- Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
- super_value.GetScalar() += process->GetAddressByteSize();
- super_value.ResolveValue (&exe_ctx);
-
- if (super_value.GetScalar().IsValid())
- {
- isa_addr = super_value.GetScalar().ULongLong();
- }
- else
- {
- if (log)
- log->Printf("Failed to extract the class value from objc_super.");
- }
- }
- }
- else
- {
- // In the direct dispatch case, the object->isa is the class pointer we want.
-
- // This is a little cheesy, but since object->isa is the first field,
- // making the object value a load address value and resolving it will get
- // the pointer sized data pointed to by that value...
-
- // Note, it isn't a fatal error not to be able to get the address from the object, since this might
- // be a "tagged pointer" which isn't a real object, but rather some word length encoded dingus.
-
- Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
-
- isa_value.SetValueType(Value::eValueTypeLoadAddress);
- isa_value.ResolveValue(&exe_ctx);
- if (isa_value.GetScalar().IsValid())
- {
- isa_addr = isa_value.GetScalar().ULongLong();
- }
- else
- {
- if (log)
- log->Printf("Failed to extract the isa value from object.");
- }
+ bool success = abi->GetArgumentValues(thread, argument_values);
+ if (!success)
+ return ret_plan_sp;
- }
-
- // Okay, we've got the address of the class for which we're resolving this, let's see if it's in our cache:
- lldb::addr_t impl_addr = LLDB_INVALID_ADDRESS;
-
- if (isa_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- {
- log->Printf("Resolving call for class - 0x%" PRIx64 " and selector - 0x%" PRIx64,
- isa_addr, sel_addr);
- }
- ObjCLanguageRuntime *objc_runtime = thread.GetProcess()->GetObjCLanguageRuntime ();
- assert(objc_runtime != NULL);
-
- impl_addr = objc_runtime->LookupInMethodCache (isa_addr, sel_addr);
- }
-
- if (impl_addr != LLDB_INVALID_ADDRESS)
- {
- // Yup, it was in the cache, so we can run to that address directly.
-
+ lldb::addr_t obj_addr =
+ argument_values.GetValueAtIndex(obj_index)->GetScalar().ULongLong();
+ if (obj_addr == 0x0) {
+ if (log)
+ log->Printf(
+ "Asked to step to dispatch to nil object, returning empty plan.");
+ return ret_plan_sp;
+ }
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ // isa_addr will store the class pointer that the method is being dispatched
+ // to - so either the class
+ // directly or the super class if this is one of the objc_msgSendSuper
+ // flavors. That's mostly used to
+ // look up the class/selector pair in our cache.
+
+ lldb::addr_t isa_addr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t sel_addr =
+ argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong();
+
+ // Figure out the class this is being dispatched to and see if we've already
+ // cached this method call,
+ // If so we can push a run-to-address plan directly. Otherwise we have to
+ // figure out where
+ // the implementation lives.
+
+ if (this_dispatch.is_super) {
+ if (this_dispatch.is_super2) {
+ // In the objc_msgSendSuper2 case, we don't get the object directly, we
+ // get a structure containing
+ // the object and the class to which the super message is being sent.
+ // So we need to dig the super
+ // out of the class and use that.
+
+ Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
+ super_value.GetScalar() += process->GetAddressByteSize();
+ super_value.ResolveValue(&exe_ctx);
+
+ if (super_value.GetScalar().IsValid()) {
+
+ // isa_value now holds the class pointer. The second word of the
+ // class pointer is the super-class pointer:
+ super_value.GetScalar() += process->GetAddressByteSize();
+ super_value.ResolveValue(&exe_ctx);
+ if (super_value.GetScalar().IsValid())
+ isa_addr = super_value.GetScalar().ULongLong();
+ else {
if (log)
- log->Printf ("Found implementation address in cache: 0x%" PRIx64, impl_addr);
-
- ret_plan_sp.reset (new ThreadPlanRunToAddress (thread, impl_addr, stop_others));
+ log->Printf("Failed to extract the super class value from the "
+ "class in objc_super.");
+ }
+ } else {
+ if (log)
+ log->Printf("Failed to extract the class value from objc_super.");
}
- else
- {
- // We haven't seen this class/selector pair yet. Look it up.
- StreamString errors;
- Address impl_code_address;
-
- ValueList dispatch_values;
-
- // We've will inject a little function in the target that takes the object, selector and some flags,
- // and figures out the implementation. Looks like:
- // void *__lldb_objc_find_implementation_for_selector (void *object,
- // void *sel,
- // int is_stret,
- // int is_super,
- // int is_super2,
- // int is_fixup,
- // int is_fixed,
- // int debug)
- // So set up the arguments for that call.
-
- dispatch_values.PushValue (*(argument_values.GetValueAtIndex(obj_index)));
- dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index)));
-
- Value flag_value;
- CompilerType clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32);
- flag_value.SetValueType (Value::eValueTypeScalar);
- //flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
- flag_value.SetCompilerType (clang_int_type);
-
- if (this_dispatch.stret_return)
- flag_value.GetScalar() = 1;
- else
- flag_value.GetScalar() = 0;
- dispatch_values.PushValue (flag_value);
-
- if (this_dispatch.is_super)
- flag_value.GetScalar() = 1;
- else
- flag_value.GetScalar() = 0;
- dispatch_values.PushValue (flag_value);
-
- if (this_dispatch.is_super2)
- flag_value.GetScalar() = 1;
- else
- flag_value.GetScalar() = 0;
- dispatch_values.PushValue (flag_value);
-
- switch (this_dispatch.fixedup)
- {
- case DispatchFunction::eFixUpNone:
- flag_value.GetScalar() = 0;
- dispatch_values.PushValue (flag_value);
- dispatch_values.PushValue (flag_value);
- break;
- case DispatchFunction::eFixUpFixed:
- flag_value.GetScalar() = 1;
- dispatch_values.PushValue (flag_value);
- flag_value.GetScalar() = 1;
- dispatch_values.PushValue (flag_value);
- break;
- case DispatchFunction::eFixUpToFix:
- flag_value.GetScalar() = 1;
- dispatch_values.PushValue (flag_value);
- flag_value.GetScalar() = 0;
- dispatch_values.PushValue (flag_value);
- break;
- }
- if (log && log->GetVerbose())
- flag_value.GetScalar() = 1;
- else
- flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done.
- dispatch_values.PushValue (flag_value);
-
-
- // The step through code might have to fill in the cache, so it is not safe to run only one thread.
- // So we override the stop_others value passed in to us here:
- const bool trampoline_stop_others = false;
- ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread,
- this,
- dispatch_values,
- isa_addr,
- sel_addr,
- trampoline_stop_others));
- if (log)
- {
- StreamString s;
- ret_plan_sp->GetDescription(&s, eDescriptionLevelFull);
- log->Printf("Using ObjC step plan: %s.\n", s.GetData());
- }
+ } else {
+ // In the objc_msgSendSuper case, we don't get the object directly, we
+ // get a two element structure containing
+ // the object and the super class to which the super message is being
+ // sent. So the class we want is
+ // the second element of this structure.
+
+ Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
+ super_value.GetScalar() += process->GetAddressByteSize();
+ super_value.ResolveValue(&exe_ctx);
+
+ if (super_value.GetScalar().IsValid()) {
+ isa_addr = super_value.GetScalar().ULongLong();
+ } else {
+ if (log)
+ log->Printf("Failed to extract the class value from objc_super.");
}
+ }
+ } else {
+ // In the direct dispatch case, the object->isa is the class pointer we
+ // want.
+
+ // This is a little cheesy, but since object->isa is the first field,
+ // making the object value a load address value and resolving it will get
+ // the pointer sized data pointed to by that value...
+
+ // Note, it isn't a fatal error not to be able to get the address from the
+ // object, since this might
+ // be a "tagged pointer" which isn't a real object, but rather some word
+ // length encoded dingus.
+
+ Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
+
+ isa_value.SetValueType(Value::eValueTypeLoadAddress);
+ isa_value.ResolveValue(&exe_ctx);
+ if (isa_value.GetScalar().IsValid()) {
+ isa_addr = isa_value.GetScalar().ULongLong();
+ } else {
+ if (log)
+ log->Printf("Failed to extract the isa value from object.");
+ }
}
-
- return ret_plan_sp;
+
+ // Okay, we've got the address of the class for which we're resolving this,
+ // let's see if it's in our cache:
+ lldb::addr_t impl_addr = LLDB_INVALID_ADDRESS;
+
+ if (isa_addr != LLDB_INVALID_ADDRESS) {
+ if (log) {
+ log->Printf("Resolving call for class - 0x%" PRIx64
+ " and selector - 0x%" PRIx64,
+ isa_addr, sel_addr);
+ }
+ ObjCLanguageRuntime *objc_runtime =
+ thread.GetProcess()->GetObjCLanguageRuntime();
+ assert(objc_runtime != NULL);
+
+ impl_addr = objc_runtime->LookupInMethodCache(isa_addr, sel_addr);
+ }
+
+ if (impl_addr != LLDB_INVALID_ADDRESS) {
+ // Yup, it was in the cache, so we can run to that address directly.
+
+ if (log)
+ log->Printf("Found implementation address in cache: 0x%" PRIx64,
+ impl_addr);
+
+ ret_plan_sp.reset(
+ new ThreadPlanRunToAddress(thread, impl_addr, stop_others));
+ } else {
+ // We haven't seen this class/selector pair yet. Look it up.
+ StreamString errors;
+ Address impl_code_address;
+
+ ValueList dispatch_values;
+
+ // We've will inject a little function in the target that takes the
+ // object, selector and some flags,
+ // and figures out the implementation. Looks like:
+ // void *__lldb_objc_find_implementation_for_selector (void *object,
+ // void *sel,
+ // int is_stret,
+ // int is_super,
+ // int is_super2,
+ // int is_fixup,
+ // int is_fixed,
+ // int debug)
+ // So set up the arguments for that call.
+
+ dispatch_values.PushValue(*(argument_values.GetValueAtIndex(obj_index)));
+ dispatch_values.PushValue(*(argument_values.GetValueAtIndex(sel_index)));
+
+ Value flag_value;
+ CompilerType clang_int_type =
+ clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
+ lldb::eEncodingSint, 32);
+ flag_value.SetValueType(Value::eValueTypeScalar);
+ // flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
+ flag_value.SetCompilerType(clang_int_type);
+
+ if (this_dispatch.stret_return)
+ flag_value.GetScalar() = 1;
+ else
+ flag_value.GetScalar() = 0;
+ dispatch_values.PushValue(flag_value);
+
+ if (this_dispatch.is_super)
+ flag_value.GetScalar() = 1;
+ else
+ flag_value.GetScalar() = 0;
+ dispatch_values.PushValue(flag_value);
+
+ if (this_dispatch.is_super2)
+ flag_value.GetScalar() = 1;
+ else
+ flag_value.GetScalar() = 0;
+ dispatch_values.PushValue(flag_value);
+
+ switch (this_dispatch.fixedup) {
+ case DispatchFunction::eFixUpNone:
+ flag_value.GetScalar() = 0;
+ dispatch_values.PushValue(flag_value);
+ dispatch_values.PushValue(flag_value);
+ break;
+ case DispatchFunction::eFixUpFixed:
+ flag_value.GetScalar() = 1;
+ dispatch_values.PushValue(flag_value);
+ flag_value.GetScalar() = 1;
+ dispatch_values.PushValue(flag_value);
+ break;
+ case DispatchFunction::eFixUpToFix:
+ flag_value.GetScalar() = 1;
+ dispatch_values.PushValue(flag_value);
+ flag_value.GetScalar() = 0;
+ dispatch_values.PushValue(flag_value);
+ break;
+ }
+ if (log && log->GetVerbose())
+ flag_value.GetScalar() = 1;
+ else
+ flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done.
+ dispatch_values.PushValue(flag_value);
+
+ // The step through code might have to fill in the cache, so it is not
+ // safe to run only one thread.
+ // So we override the stop_others value passed in to us here:
+ const bool trampoline_stop_others = false;
+ ret_plan_sp.reset(new AppleThreadPlanStepThroughObjCTrampoline(
+ thread, this, dispatch_values, isa_addr, sel_addr,
+ trampoline_stop_others));
+ if (log) {
+ StreamString s;
+ ret_plan_sp->GetDescription(&s, eDescriptionLevelFull);
+ log->Printf("Using ObjC step plan: %s.\n", s.GetData());
+ }
+ }
+ }
+
+ return ret_plan_sp;
}
FunctionCaller *
-AppleObjCTrampolineHandler::GetLookupImplementationFunctionCaller ()
-{
- return m_impl_code->GetFunctionCaller();
+AppleObjCTrampolineHandler::GetLookupImplementationFunctionCaller() {
+ return m_impl_code->GetFunctionCaller();
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index c0d1944a7f2f..dc58a8bc1eb6 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -18,190 +18,143 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Expression/UtilityFunction.h"
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
-namespace lldb_private
-{
-
class AppleObjCTrampolineHandler {
public:
- AppleObjCTrampolineHandler (const lldb::ProcessSP &process_sp,
- const lldb::ModuleSP &objc_module_sp);
-
- ~AppleObjCTrampolineHandler();
-
- lldb::ThreadPlanSP
- GetStepThroughDispatchPlan (Thread &thread,
- bool stop_others);
-
- FunctionCaller *
- GetLookupImplementationFunctionCaller ();
-
- bool
- AddrIsMsgForward (lldb::addr_t addr) const
- {
- return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr);
- }
-
- struct DispatchFunction {
- public:
- typedef enum
- {
- eFixUpNone,
- eFixUpFixed,
- eFixUpToFix
- } FixUpState;
-
- const char *name;
- bool stret_return;
- bool is_super;
- bool is_super2;
- FixUpState fixedup;
- };
+ AppleObjCTrampolineHandler(const lldb::ProcessSP &process_sp,
+ const lldb::ModuleSP &objc_module_sp);
+
+ ~AppleObjCTrampolineHandler();
+
+ lldb::ThreadPlanSP GetStepThroughDispatchPlan(Thread &thread,
+ bool stop_others);
+
+ FunctionCaller *GetLookupImplementationFunctionCaller();
+
+ bool AddrIsMsgForward(lldb::addr_t addr) const {
+ return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr);
+ }
- lldb::addr_t
- SetupDispatchFunction (Thread &thread, ValueList &dispatch_values);
+ struct DispatchFunction {
+ public:
+ typedef enum { eFixUpNone, eFixUpFixed, eFixUpToFix } FixUpState;
+
+ const char *name;
+ bool stret_return;
+ bool is_super;
+ bool is_super2;
+ FixUpState fixedup;
+ };
+
+ lldb::addr_t SetupDispatchFunction(Thread &thread,
+ ValueList &dispatch_values);
private:
- static const char *g_lookup_implementation_function_name;
- static const char *g_lookup_implementation_with_stret_function_code;
- static const char *g_lookup_implementation_no_stret_function_code;
+ static const char *g_lookup_implementation_function_name;
+ static const char *g_lookup_implementation_with_stret_function_code;
+ static const char *g_lookup_implementation_no_stret_function_code;
+
+ class AppleObjCVTables {
+ public:
+ // These come from objc-gdb.h.
+ enum VTableFlags {
+ eOBJC_TRAMPOLINE_MESSAGE = (1 << 0), // trampoline acts like objc_msgSend
+ eOBJC_TRAMPOLINE_STRET = (1 << 1), // trampoline is struct-returning
+ eOBJC_TRAMPOLINE_VTABLE = (1 << 2) // trampoline is vtable dispatcher
+ };
+
+ private:
+ struct VTableDescriptor {
+ VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start)
+ : flags(in_flags), code_start(in_code_start) {}
- class AppleObjCVTables
- {
+ uint32_t flags;
+ lldb::addr_t code_start;
+ };
+
+ class VTableRegion {
public:
- // These come from objc-gdb.h.
- enum VTableFlags
- {
- eOBJC_TRAMPOLINE_MESSAGE = (1<<0), // trampoline acts like objc_msgSend
- eOBJC_TRAMPOLINE_STRET = (1<<1), // trampoline is struct-returning
- eOBJC_TRAMPOLINE_VTABLE = (1<<2) // trampoline is vtable dispatcher
- };
-
- private:
- struct VTableDescriptor
- {
- VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start) :
- flags(in_flags),
- code_start(in_code_start) {}
-
- uint32_t flags;
- lldb::addr_t code_start;
- };
-
- class VTableRegion
- {
- public:
- VTableRegion() :
- m_valid (false),
- m_owner (NULL),
- m_header_addr (LLDB_INVALID_ADDRESS),
- m_code_start_addr(0),
- m_code_end_addr (0),
- m_next_region (0)
- {}
-
- VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
-
- void SetUpRegion();
-
- lldb::addr_t GetNextRegionAddr ()
- {
- return m_next_region;
- }
-
- lldb::addr_t
- GetCodeStart ()
- {
- return m_code_start_addr;
- }
-
- lldb::addr_t
- GetCodeEnd ()
- {
- return m_code_end_addr;
- }
-
- uint32_t
- GetFlagsForVTableAtAddress (lldb::addr_t address)
- {
- return 0;
- }
-
- bool
- IsValid ()
- {
- return m_valid;
- }
-
- bool
- AddressInRegion (lldb::addr_t addr, uint32_t &flags);
-
- void
- Dump (Stream &s);
-
- public:
- bool m_valid;
- AppleObjCVTables *m_owner;
- lldb::addr_t m_header_addr;
- lldb::addr_t m_code_start_addr;
- lldb::addr_t m_code_end_addr;
- std::vector<VTableDescriptor> m_descriptors;
- lldb::addr_t m_next_region;
- };
-
+ VTableRegion()
+ : m_valid(false), m_owner(NULL), m_header_addr(LLDB_INVALID_ADDRESS),
+ m_code_start_addr(0), m_code_end_addr(0), m_next_region(0) {}
+
+ VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
+
+ void SetUpRegion();
+
+ lldb::addr_t GetNextRegionAddr() { return m_next_region; }
+
+ lldb::addr_t GetCodeStart() { return m_code_start_addr; }
+
+ lldb::addr_t GetCodeEnd() { return m_code_end_addr; }
+
+ uint32_t GetFlagsForVTableAtAddress(lldb::addr_t address) { return 0; }
+
+ bool IsValid() { return m_valid; }
+
+ bool AddressInRegion(lldb::addr_t addr, uint32_t &flags);
+
+ void Dump(Stream &s);
+
public:
- AppleObjCVTables(const lldb::ProcessSP &process_sp,
- const lldb::ModuleSP &objc_module_sp);
-
- ~AppleObjCVTables();
-
- bool
- InitializeVTableSymbols ();
-
- static bool RefreshTrampolines (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
- bool
- ReadRegions ();
-
- bool
- ReadRegions (lldb::addr_t region_addr);
-
- bool
- IsAddressInVTables (lldb::addr_t addr, uint32_t &flags);
-
- lldb::ProcessSP
- GetProcessSP ()
- {
- return m_process_wp.lock();
- }
-
- private:
- lldb::ProcessWP m_process_wp;
- typedef std::vector<VTableRegion> region_collection;
- lldb::addr_t m_trampoline_header;
- lldb::break_id_t m_trampolines_changed_bp_id;
- region_collection m_regions;
- lldb::ModuleSP m_objc_module_sp;
+ bool m_valid;
+ AppleObjCVTables *m_owner;
+ lldb::addr_t m_header_addr;
+ lldb::addr_t m_code_start_addr;
+ lldb::addr_t m_code_end_addr;
+ std::vector<VTableDescriptor> m_descriptors;
+ lldb::addr_t m_next_region;
};
-
- static const DispatchFunction g_dispatch_functions[];
-
- typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch fn address to the index in g_dispatch_functions
- MsgsendMap m_msgSend_map;
+
+ public:
+ AppleObjCVTables(const lldb::ProcessSP &process_sp,
+ const lldb::ModuleSP &objc_module_sp);
+
+ ~AppleObjCVTables();
+
+ bool InitializeVTableSymbols();
+
+ static bool RefreshTrampolines(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+ bool ReadRegions();
+
+ bool ReadRegions(lldb::addr_t region_addr);
+
+ bool IsAddressInVTables(lldb::addr_t addr, uint32_t &flags);
+
+ lldb::ProcessSP GetProcessSP() { return m_process_wp.lock(); }
+
+ private:
lldb::ProcessWP m_process_wp;
+ typedef std::vector<VTableRegion> region_collection;
+ lldb::addr_t m_trampoline_header;
+ lldb::break_id_t m_trampolines_changed_bp_id;
+ region_collection m_regions;
lldb::ModuleSP m_objc_module_sp;
- const char *m_lookup_implementation_function_code;
- std::unique_ptr<UtilityFunction> m_impl_code;
- std::mutex m_impl_function_mutex;
- lldb::addr_t m_impl_fn_addr;
- lldb::addr_t m_impl_stret_fn_addr;
- lldb::addr_t m_msg_forward_addr;
- lldb::addr_t m_msg_forward_stret_addr;
- std::unique_ptr<AppleObjCVTables> m_vtables_ap;
+ };
+
+ static const DispatchFunction g_dispatch_functions[];
+
+ typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch
+ // fn address to the index in
+ // g_dispatch_functions
+ MsgsendMap m_msgSend_map;
+ lldb::ProcessWP m_process_wp;
+ lldb::ModuleSP m_objc_module_sp;
+ const char *m_lookup_implementation_function_code;
+ std::unique_ptr<UtilityFunction> m_impl_code;
+ std::mutex m_impl_function_mutex;
+ lldb::addr_t m_impl_fn_addr;
+ lldb::addr_t m_impl_stret_fn_addr;
+ lldb::addr_t m_msg_forward_addr;
+ lldb::addr_t m_msg_forward_stret_addr;
+ std::unique_ptr<AppleObjCVTables> m_vtables_ap;
};
} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index d4adc094bc1b..316115b0dcb1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -21,379 +21,376 @@
using namespace lldb_private;
using namespace lldb_utility;
-AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser (ObjCLanguageRuntime& runtime) :
- ObjCLanguageRuntime::EncodingToType(),
- m_runtime(runtime)
-{
- if (!m_scratch_ast_ctx_ap)
- m_scratch_ast_ctx_ap.reset(new ClangASTContext(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().str().c_str()));
+AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
+ ObjCLanguageRuntime &runtime)
+ : ObjCLanguageRuntime::EncodingToType(), m_runtime(runtime) {
+ if (!m_scratch_ast_ctx_ap)
+ m_scratch_ast_ctx_ap.reset(new ClangASTContext(runtime.GetProcess()
+ ->GetTarget()
+ .GetArchitecture()
+ .GetTriple()
+ .str()
+ .c_str()));
}
std::string
-AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer& type)
-{
- StreamString buffer;
- while (type.HasAtLeast(1) && type.Peek() != '=')
- buffer.Printf("%c",type.Next());
- return buffer.GetString();
+AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer &type) {
+ StreamString buffer;
+ while (type.HasAtLeast(1) && type.Peek() != '=')
+ buffer.Printf("%c", type.Next());
+ return buffer.GetString();
}
std::string
-AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer& type)
-{
- StreamString buffer;
- while (type.HasAtLeast(1) && type.Peek() != '"')
- buffer.Printf("%c",type.Next());
- StringLexer::Character next = type.Next();
- UNUSED_IF_ASSERT_DISABLED(next);
- assert (next == '"');
- return buffer.GetString();
+AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) {
+ StreamString buffer;
+ while (type.HasAtLeast(1) && type.Peek() != '"')
+ buffer.Printf("%c", type.Next());
+ StringLexer::Character next = type.Next();
+ UNUSED_IF_ASSERT_DISABLED(next);
+ assert(next == '"');
+ return buffer.GetString();
}
uint32_t
-AppleObjCTypeEncodingParser::ReadNumber (lldb_utility::StringLexer& type)
-{
- uint32_t total = 0;
- while (type.HasAtLeast(1) && isdigit(type.Peek()))
- total = 10*total + (type.Next() - '0');
- return total;
+AppleObjCTypeEncodingParser::ReadNumber(lldb_utility::StringLexer &type) {
+ uint32_t total = 0;
+ while (type.HasAtLeast(1) && isdigit(type.Peek()))
+ total = 10 * total + (type.Next() - '0');
+ return total;
}
-// as an extension to the published grammar recent runtimes emit structs like this:
+// as an extension to the published grammar recent runtimes emit structs like
+// this:
// "{CGRect=\"origin\"{CGPoint=\"x\"d\"y\"d}\"size\"{CGSize=\"width\"d\"height\"d}}"
-AppleObjCTypeEncodingParser::StructElement::StructElement() :
-name(""),
-type(clang::QualType()),
-bitfield(0)
-{}
+AppleObjCTypeEncodingParser::StructElement::StructElement()
+ : name(""), type(clang::QualType()), bitfield(0) {}
AppleObjCTypeEncodingParser::StructElement
-AppleObjCTypeEncodingParser::ReadStructElement (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- StructElement retval;
- if (type.NextIf('"'))
- retval.name = ReadQuotedString(type);
- if (!type.NextIf('"'))
- return retval;
- uint32_t bitfield_size = 0;
- retval.type = BuildType(ast_ctx, type, for_expression, &bitfield_size);
- retval.bitfield = bitfield_size;
+AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ StructElement retval;
+ if (type.NextIf('"'))
+ retval.name = ReadQuotedString(type);
+ if (!type.NextIf('"'))
return retval;
+ uint32_t bitfield_size = 0;
+ retval.type = BuildType(ast_ctx, type, for_expression, &bitfield_size);
+ retval.bitfield = bitfield_size;
+ return retval;
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildStruct (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- return BuildAggregate(ast_ctx, type, for_expression, '{', '}', clang::TTK_Struct);
+AppleObjCTypeEncodingParser::BuildStruct(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ return BuildAggregate(ast_ctx, type, for_expression, '{', '}',
+ clang::TTK_Struct);
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildUnion (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- return BuildAggregate(ast_ctx, type, for_expression, '(', ')', clang::TTK_Union);
+AppleObjCTypeEncodingParser::BuildUnion(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ return BuildAggregate(ast_ctx, type, for_expression, '(', ')',
+ clang::TTK_Union);
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildAggregate (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression, char opener, char closer, uint32_t kind)
-{
- if (!type.NextIf(opener))
- return clang::QualType();
- std::string name(ReadStructName(type));
-
- // We do not handle templated classes/structs at the moment.
- // If the name has a < in it, we are going to abandon this.
- // We're still obliged to parse it, so we just set a flag that
- // means "Don't actually build anything."
-
- const bool is_templated = name.find('<') != std::string::npos;
-
- if (!type.NextIf('='))
- return clang::QualType();
- bool in_union = true;
- std::vector<StructElement> elements;
- while (in_union && type.HasAtLeast(1))
- {
- if (type.NextIf(closer))
- {
- in_union = false;
- break;
- }
- else
- {
- auto element = ReadStructElement(ast_ctx, type, for_expression);
- if (element.type.isNull())
- break;
- else
- elements.push_back(element);
- }
+clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
+ clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
+ bool for_expression, char opener, char closer, uint32_t kind) {
+ if (!type.NextIf(opener))
+ return clang::QualType();
+ std::string name(ReadStructName(type));
+
+ // We do not handle templated classes/structs at the moment.
+ // If the name has a < in it, we are going to abandon this.
+ // We're still obliged to parse it, so we just set a flag that
+ // means "Don't actually build anything."
+
+ const bool is_templated = name.find('<') != std::string::npos;
+
+ if (!type.NextIf('='))
+ return clang::QualType();
+ bool in_union = true;
+ std::vector<StructElement> elements;
+ while (in_union && type.HasAtLeast(1)) {
+ if (type.NextIf(closer)) {
+ in_union = false;
+ break;
+ } else {
+ auto element = ReadStructElement(ast_ctx, type, for_expression);
+ if (element.type.isNull())
+ break;
+ else
+ elements.push_back(element);
}
- if (in_union)
- return clang::QualType();
-
- if (is_templated)
- return clang::QualType(); // This is where we bail out. Sorry!
-
- ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
- if (!lldb_ctx)
- return clang::QualType();
- CompilerType union_type(lldb_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, name.c_str(), kind, lldb::eLanguageTypeC));
- if (union_type)
- {
- ClangASTContext::StartTagDeclarationDefinition(union_type);
-
- unsigned int count = 0;
- for (auto element: elements)
- {
- if (element.name.empty())
- {
- StreamString elem_name;
- elem_name.Printf("__unnamed_%u",count);
- element.name = std::string(elem_name.GetData());
- }
- ClangASTContext::AddFieldToRecordType(union_type, element.name.c_str(), CompilerType(&ast_ctx, element.type), lldb::eAccessPublic, element.bitfield);
- ++count;
- }
- ClangASTContext::CompleteTagDeclarationDefinition(union_type);
+ }
+ if (in_union)
+ return clang::QualType();
+
+ if (is_templated)
+ return clang::QualType(); // This is where we bail out. Sorry!
+
+ ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
+ if (!lldb_ctx)
+ return clang::QualType();
+ CompilerType union_type(lldb_ctx->CreateRecordType(
+ nullptr, lldb::eAccessPublic, name.c_str(), kind, lldb::eLanguageTypeC));
+ if (union_type) {
+ ClangASTContext::StartTagDeclarationDefinition(union_type);
+
+ unsigned int count = 0;
+ for (auto element : elements) {
+ if (element.name.empty()) {
+ StreamString elem_name;
+ elem_name.Printf("__unnamed_%u", count);
+ element.name = elem_name.GetString();
+ }
+ ClangASTContext::AddFieldToRecordType(
+ union_type, element.name.c_str(),
+ CompilerType(&ast_ctx, element.type), lldb::eAccessPublic,
+ element.bitfield);
+ ++count;
}
- return ClangUtil::GetQualType(union_type);
+ ClangASTContext::CompleteTagDeclarationDefinition(union_type);
+ }
+ return ClangUtil::GetQualType(union_type);
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildArray (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- if (!type.NextIf('['))
- return clang::QualType();
- uint32_t size = ReadNumber(type);
- clang::QualType element_type(BuildType(ast_ctx, type, for_expression));
- if (!type.NextIf(']'))
- return clang::QualType();
- ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
- if (!lldb_ctx)
- return clang::QualType();
- CompilerType array_type(lldb_ctx->CreateArrayType(CompilerType(&ast_ctx, element_type), size, false));
- return ClangUtil::GetQualType(array_type);
+AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ if (!type.NextIf('['))
+ return clang::QualType();
+ uint32_t size = ReadNumber(type);
+ clang::QualType element_type(BuildType(ast_ctx, type, for_expression));
+ if (!type.NextIf(']'))
+ return clang::QualType();
+ ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
+ if (!lldb_ctx)
+ return clang::QualType();
+ CompilerType array_type(lldb_ctx->CreateArrayType(
+ CompilerType(&ast_ctx, element_type), size, false));
+ return ClangUtil::GetQualType(array_type);
}
// the runtime can emit these in the form of @"SomeType", giving more specifics
-// this would be interesting for expression parser interop, but since we actually try
-// to avoid exposing the ivar info to the expression evaluator, consume but ignore the type info
-// and always return an 'id'; if anything, dynamic typing will resolve things for us anyway
-clang::QualType
-AppleObjCTypeEncodingParser::BuildObjCObjectPointerType (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- if (!type.NextIf('@'))
- return clang::QualType();
-
- std::string name;
-
- if (type.NextIf('"'))
- {
- // We have to be careful here. We're used to seeing
- // @"NSString"
- // but in records it is possible that the string following an @ is the name of the next field and @ means "id".
- // This is the case if anything unquoted except for "}", the end of the type, or another name follows the quoted string.
- //
- // E.g.
- // - @"NSString"@ means "id, followed by a field named NSString of type id"
- // - @"NSString"} means "a pointer to NSString and the end of the struct"
- // - @"NSString""nextField" means "a pointer to NSString and a field named nextField"
- // - @"NSString" followed by the end of the string means "a pointer to NSString"
- //
- // As a result, the rule is: If we see @ followed by a quoted string, we peek.
- // - If we see }, ), ], the end of the string, or a quote ("), the quoted string is a class name.
- // - If we see anything else, the quoted string is a field name and we push it back onto type.
-
- name = ReadQuotedString(type);
-
- if (type.HasAtLeast(1))
- {
- switch (type.Peek())
- {
- default:
- // roll back
- type.PutBack(name.length() + 2); // undo our consumption of the string and of the quotes
- name.clear();
- break;
- case '}':
- case ')':
- case ']':
- case '"':
- // the quoted string is a class name – see the rule
- break;
- }
- }
- else
- {
- // the quoted string is a class name – see the rule
- }
+// this would be interesting for expression parser interop, but since we
+// actually try
+// to avoid exposing the ivar info to the expression evaluator, consume but
+// ignore the type info
+// and always return an 'id'; if anything, dynamic typing will resolve things
+// for us anyway
+clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
+ clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
+ bool for_expression) {
+ if (!type.NextIf('@'))
+ return clang::QualType();
+
+ std::string name;
+
+ if (type.NextIf('"')) {
+ // We have to be careful here. We're used to seeing
+ // @"NSString"
+ // but in records it is possible that the string following an @ is the name
+ // of the next field and @ means "id".
+ // This is the case if anything unquoted except for "}", the end of the
+ // type, or another name follows the quoted string.
+ //
+ // E.g.
+ // - @"NSString"@ means "id, followed by a field named NSString of type id"
+ // - @"NSString"} means "a pointer to NSString and the end of the struct"
+ // - @"NSString""nextField" means "a pointer to NSString and a field named
+ // nextField"
+ // - @"NSString" followed by the end of the string means "a pointer to
+ // NSString"
+ //
+ // As a result, the rule is: If we see @ followed by a quoted string, we
+ // peek.
+ // - If we see }, ), ], the end of the string, or a quote ("), the quoted
+ // string is a class name.
+ // - If we see anything else, the quoted string is a field name and we push
+ // it back onto type.
+
+ name = ReadQuotedString(type);
+
+ if (type.HasAtLeast(1)) {
+ switch (type.Peek()) {
+ default:
+ // roll back
+ type.PutBack(name.length() +
+ 2); // undo our consumption of the string and of the quotes
+ name.clear();
+ break;
+ case '}':
+ case ')':
+ case ']':
+ case '"':
+ // the quoted string is a class name – see the rule
+ break;
+ }
+ } else {
+ // the quoted string is a class name – see the rule
+ }
+ }
+
+ if (for_expression && !name.empty()) {
+ size_t less_than_pos = name.find('<');
+
+ if (less_than_pos != std::string::npos) {
+ if (less_than_pos == 0)
+ return ast_ctx.getObjCIdType();
+ else
+ name.erase(less_than_pos);
}
-
- if (for_expression && !name.empty())
- {
- size_t less_than_pos = name.find('<');
-
- if (less_than_pos != std::string::npos)
- {
- if (less_than_pos == 0)
- return ast_ctx.getObjCIdType();
- else
- name.erase(less_than_pos);
- }
-
- DeclVendor *decl_vendor = m_runtime.GetDeclVendor();
-
- assert (decl_vendor); // how are we parsing type encodings for expressions if a type vendor isn't in play?
-
- const bool append = false;
- const uint32_t max_matches = 1;
- std::vector<clang::NamedDecl *> decls;
-
- uint32_t num_types = decl_vendor->FindDecls(ConstString(name),
- append,
- max_matches,
- decls);
-
- // The user can forward-declare something that has no definition. The runtime doesn't prohibit this at all.
- // This is a rare and very weird case. We keep this assert in debug builds so we catch other weird cases.
+
+ DeclVendor *decl_vendor = m_runtime.GetDeclVendor();
+ if (!decl_vendor)
+ return clang::QualType();
+
+ const bool append = false;
+ const uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ uint32_t num_types =
+ decl_vendor->FindDecls(ConstString(name), append, max_matches, decls);
+
+// The user can forward-declare something that has no definition. The runtime
+// doesn't prohibit this at all.
+// This is a rare and very weird case. We keep this assert in debug builds so
+// we catch other weird cases.
#ifdef LLDB_CONFIGURATION_DEBUG
- assert(num_types);
+ assert(num_types);
#else
- if (!num_types)
- return ast_ctx.getObjCIdType();
+ if (!num_types)
+ return ast_ctx.getObjCIdType();
#endif
- return ClangUtil::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
- }
- else
- {
- // We're going to resolve this dynamically anyway, so just smile and wave.
- return ast_ctx.getObjCIdType();
- }
+ return ClangUtil::GetQualType(
+ ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
+ } else {
+ // We're going to resolve this dynamically anyway, so just smile and wave.
+ return ast_ctx.getObjCIdType();
+ }
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildType (clang::ASTContext &ast_ctx, StringLexer& type, bool for_expression, uint32_t *bitfield_bit_size)
-{
- if (!type.HasAtLeast(1))
- return clang::QualType();
-
- switch (type.Peek())
- {
- default:
- break;
- case '{':
- return BuildStruct(ast_ctx, type, for_expression);
- case '[':
- return BuildArray(ast_ctx, type, for_expression);
- case '(':
- return BuildUnion(ast_ctx, type, for_expression);
- case '@':
- return BuildObjCObjectPointerType(ast_ctx, type, for_expression);
- }
-
- switch (type.Next())
- {
- default:
- type.PutBack(1);
+AppleObjCTypeEncodingParser::BuildType(clang::ASTContext &ast_ctx,
+ StringLexer &type, bool for_expression,
+ uint32_t *bitfield_bit_size) {
+ if (!type.HasAtLeast(1))
+ return clang::QualType();
+
+ switch (type.Peek()) {
+ default:
+ break;
+ case '{':
+ return BuildStruct(ast_ctx, type, for_expression);
+ case '[':
+ return BuildArray(ast_ctx, type, for_expression);
+ case '(':
+ return BuildUnion(ast_ctx, type, for_expression);
+ case '@':
+ return BuildObjCObjectPointerType(ast_ctx, type, for_expression);
+ }
+
+ switch (type.Next()) {
+ default:
+ type.PutBack(1);
+ return clang::QualType();
+ case 'c':
+ return ast_ctx.CharTy;
+ case 'i':
+ return ast_ctx.IntTy;
+ case 's':
+ return ast_ctx.ShortTy;
+ case 'l':
+ return ast_ctx.getIntTypeForBitwidth(32, true);
+ // this used to be done like this:
+ // ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
+ // if (!lldb_ctx)
+ // return clang::QualType();
+ // return lldb_ctx->GetIntTypeFromBitSize(32, true).GetQualType();
+ // which uses one of the constants if one is available, but we don't think all
+ // this work is necessary.
+ case 'q':
+ return ast_ctx.LongLongTy;
+ case 'C':
+ return ast_ctx.UnsignedCharTy;
+ case 'I':
+ return ast_ctx.UnsignedIntTy;
+ case 'S':
+ return ast_ctx.UnsignedShortTy;
+ case 'L':
+ return ast_ctx.getIntTypeForBitwidth(32, false);
+ // see note for 'l'
+ case 'Q':
+ return ast_ctx.UnsignedLongLongTy;
+ case 'f':
+ return ast_ctx.FloatTy;
+ case 'd':
+ return ast_ctx.DoubleTy;
+ case 'B':
+ return ast_ctx.BoolTy;
+ case 'v':
+ return ast_ctx.VoidTy;
+ case '*':
+ return ast_ctx.getPointerType(ast_ctx.CharTy);
+ case '#':
+ return ast_ctx.getObjCClassType();
+ case ':':
+ return ast_ctx.getObjCSelType();
+ case 'b': {
+ uint32_t size = ReadNumber(type);
+ if (bitfield_bit_size) {
+ *bitfield_bit_size = size;
+ return ast_ctx.UnsignedIntTy; // FIXME: the spec is fairly vague here.
+ } else
+ return clang::QualType();
+ }
+ case 'r': {
+ clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
+ if (target_type.isNull())
+ return clang::QualType();
+ else if (target_type == ast_ctx.UnknownAnyTy)
+ return ast_ctx.UnknownAnyTy;
+ else
+ return ast_ctx.getConstType(target_type);
+ }
+ case '^': {
+ if (!for_expression && type.NextIf('?')) {
+ // if we are not supporting the concept of unknownAny, but what is being
+ // created here is an unknownAny*, then
+ // we can just get away with a void*
+ // this is theoretically wrong (in the same sense as 'theoretically
+ // nothing exists') but is way better than outright failure
+ // in many practical cases
+ return ast_ctx.VoidPtrTy;
+ } else {
+ clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
+ if (target_type.isNull())
return clang::QualType();
- case 'c':
- return ast_ctx.CharTy;
- case 'i':
- return ast_ctx.IntTy;
- case 's':
- return ast_ctx.ShortTy;
- case 'l':
- return ast_ctx.getIntTypeForBitwidth(32, true);
- // this used to be done like this:
- // ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
- // if (!lldb_ctx)
- // return clang::QualType();
- // return lldb_ctx->GetIntTypeFromBitSize(32, true).GetQualType();
- // which uses one of the constants if one is available, but we don't think all this work is necessary.
- case 'q':
- return ast_ctx.LongLongTy;
- case 'C':
- return ast_ctx.UnsignedCharTy;
- case 'I':
- return ast_ctx.UnsignedIntTy;
- case 'S':
- return ast_ctx.UnsignedShortTy;
- case 'L':
- return ast_ctx.getIntTypeForBitwidth(32, false);
- // see note for 'l'
- case 'Q':
- return ast_ctx.UnsignedLongLongTy;
- case 'f':
- return ast_ctx.FloatTy;
- case 'd':
- return ast_ctx.DoubleTy;
- case 'B':
- return ast_ctx.BoolTy;
- case 'v':
- return ast_ctx.VoidTy;
- case '*':
- return ast_ctx.getPointerType(ast_ctx.CharTy);
- case '#':
- return ast_ctx.getObjCClassType();
- case ':':
- return ast_ctx.getObjCSelType();
- case 'b':
- {
- uint32_t size = ReadNumber(type);
- if (bitfield_bit_size)
- {
- *bitfield_bit_size = size;
- return ast_ctx.UnsignedIntTy; // FIXME: the spec is fairly vague here.
- }
- else
- return clang::QualType();
- }
- case 'r':
- {
- clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
- if (target_type.isNull())
- return clang::QualType();
- else if (target_type == ast_ctx.UnknownAnyTy)
- return ast_ctx.UnknownAnyTy;
- else
- return ast_ctx.getConstType(target_type);
- }
- case '^':
- {
- if (!for_expression && type.NextIf('?'))
- {
- // if we are not supporting the concept of unknownAny, but what is being created here is an unknownAny*, then
- // we can just get away with a void*
- // this is theoretically wrong (in the same sense as 'theoretically nothing exists') but is way better than outright failure
- // in many practical cases
- return ast_ctx.VoidPtrTy;
- }
- else
- {
- clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
- if (target_type.isNull())
- return clang::QualType();
- else if (target_type == ast_ctx.UnknownAnyTy)
- return ast_ctx.UnknownAnyTy;
- else
- return ast_ctx.getPointerType(target_type);
- }
- }
- case '?':
- return for_expression ? ast_ctx.UnknownAnyTy : clang::QualType();
+ else if (target_type == ast_ctx.UnknownAnyTy)
+ return ast_ctx.UnknownAnyTy;
+ else
+ return ast_ctx.getPointerType(target_type);
}
+ }
+ case '?':
+ return for_expression ? ast_ctx.UnknownAnyTy : clang::QualType();
+ }
}
-CompilerType
-AppleObjCTypeEncodingParser::RealizeType (clang::ASTContext &ast_ctx, const char* name, bool for_expression)
-{
- if (name && name[0])
- {
- StringLexer lexer(name);
- clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
- return CompilerType(&ast_ctx, qual_type);
- }
- return CompilerType();
+CompilerType AppleObjCTypeEncodingParser::RealizeType(
+ clang::ASTContext &ast_ctx, const char *name, bool for_expression) {
+ if (name && name[0]) {
+ StringLexer lexer(name);
+ clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
+ return CompilerType(&ast_ctx, qual_type);
+ }
+ return CompilerType();
}
-
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index 87c49cbc05b9..4da84dd92c3f 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -16,66 +16,72 @@
#include "clang/AST/ASTContext.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_utility {
- class StringLexer;
+class StringLexer;
}
namespace lldb_private {
- class AppleObjCTypeEncodingParser : public ObjCLanguageRuntime::EncodingToType
- {
- public:
- AppleObjCTypeEncodingParser (ObjCLanguageRuntime& runtime);
- ~AppleObjCTypeEncodingParser() override = default;
-
- CompilerType RealizeType(clang::ASTContext &ast_ctx, const char* name, bool for_expression) override;
-
- private:
- struct StructElement {
- std::string name;
- clang::QualType type;
- uint32_t bitfield;
-
- StructElement ();
- ~StructElement () = default;
- };
-
- clang::QualType
- BuildType (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression, uint32_t *bitfield_bit_size = nullptr);
-
- clang::QualType
- BuildStruct (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression);
-
- clang::QualType
- BuildAggregate (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression, char opener, char closer, uint32_t kind);
-
- clang::QualType
- BuildUnion (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression);
-
- clang::QualType
- BuildArray (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression);
-
- std::string
- ReadStructName(lldb_utility::StringLexer& type);
-
- StructElement
- ReadStructElement (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression);
-
- clang::QualType
- BuildObjCObjectPointerType (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression);
-
- uint32_t
- ReadNumber (lldb_utility::StringLexer& type);
-
- std::string
- ReadQuotedString(lldb_utility::StringLexer& type);
-
- ObjCLanguageRuntime& m_runtime;
- };
-
+class AppleObjCTypeEncodingParser : public ObjCLanguageRuntime::EncodingToType {
+public:
+ AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime);
+ ~AppleObjCTypeEncodingParser() override = default;
+
+ CompilerType RealizeType(clang::ASTContext &ast_ctx, const char *name,
+ bool for_expression) override;
+
+private:
+ struct StructElement {
+ std::string name;
+ clang::QualType type;
+ uint32_t bitfield;
+
+ StructElement();
+ ~StructElement() = default;
+ };
+
+ clang::QualType BuildType(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression,
+ uint32_t *bitfield_bit_size = nullptr);
+
+ clang::QualType BuildStruct(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression);
+
+ clang::QualType BuildAggregate(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression, char opener, char closer,
+ uint32_t kind);
+
+ clang::QualType BuildUnion(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression);
+
+ clang::QualType BuildArray(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression);
+
+ std::string ReadStructName(lldb_utility::StringLexer &type);
+
+ StructElement ReadStructElement(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression);
+
+ clang::QualType BuildObjCObjectPointerType(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression);
+
+ uint32_t ReadNumber(lldb_utility::StringLexer &type);
+
+ std::string ReadQuotedString(lldb_utility::StringLexer &type);
+
+ ObjCLanguageRuntime &m_runtime;
+};
+
} // namespace lldb_private
#endif // liblldb_AppleObjCTypeEncodingParser_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index a2101c927b4d..e49269532329 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -1,4 +1,5 @@
-//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp --------------------------*- C++ -*-===//
+//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp
+//--------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -30,212 +31,183 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// ThreadPlanStepThroughObjCTrampoline constructor
//----------------------------------------------------------------------
-AppleThreadPlanStepThroughObjCTrampoline::AppleThreadPlanStepThroughObjCTrampoline
-(
- Thread &thread,
- AppleObjCTrampolineHandler *trampoline_handler,
- ValueList &input_values,
- lldb::addr_t isa_addr,
- lldb::addr_t sel_addr,
- bool stop_others
-) :
- ThreadPlan (ThreadPlan::eKindGeneric,
- "MacOSX Step through ObjC Trampoline",
- thread,
- eVoteNoOpinion,
- eVoteNoOpinion),
- m_trampoline_handler (trampoline_handler),
- m_args_addr (LLDB_INVALID_ADDRESS),
- m_input_values (input_values),
- m_isa_addr(isa_addr),
- m_sel_addr(sel_addr),
- m_impl_function (NULL),
- m_stop_others (stop_others)
-{
-
-}
+AppleThreadPlanStepThroughObjCTrampoline::
+ AppleThreadPlanStepThroughObjCTrampoline(
+ Thread &thread, AppleObjCTrampolineHandler *trampoline_handler,
+ ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
+ bool stop_others)
+ : ThreadPlan(ThreadPlan::eKindGeneric,
+ "MacOSX Step through ObjC Trampoline", thread, eVoteNoOpinion,
+ eVoteNoOpinion),
+ m_trampoline_handler(trampoline_handler),
+ m_args_addr(LLDB_INVALID_ADDRESS), m_input_values(input_values),
+ m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(NULL),
+ m_stop_others(stop_others) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-AppleThreadPlanStepThroughObjCTrampoline::~AppleThreadPlanStepThroughObjCTrampoline()
-{
+AppleThreadPlanStepThroughObjCTrampoline::
+ ~AppleThreadPlanStepThroughObjCTrampoline() {}
+
+void AppleThreadPlanStepThroughObjCTrampoline::DidPush() {
+ // Setting up the memory space for the called function text might require
+ // allocations,
+ // i.e. a nested function call. This needs to be done as a PreResumeAction.
+ m_thread.GetProcess()->AddPreResumeAction(PreResumeInitializeFunctionCaller,
+ (void *)this);
}
-void
-AppleThreadPlanStepThroughObjCTrampoline::DidPush ()
-{
- // Setting up the memory space for the called function text might require allocations,
- // i.e. a nested function call. This needs to be done as a PreResumeAction.
- m_thread.GetProcess()->AddPreResumeAction (PreResumeInitializeFunctionCaller, (void *) this);
-}
+bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() {
+ if (!m_func_sp) {
+ DiagnosticManager diagnostics;
+ m_args_addr =
+ m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
-bool
-AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
-{
- if (!m_func_sp)
- {
- DiagnosticManager diagnostics;
- m_args_addr = m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
-
- if (m_args_addr == LLDB_INVALID_ADDRESS)
- {
- return false;
- }
- m_impl_function = m_trampoline_handler->GetLookupImplementationFunctionCaller();
- ExecutionContext exc_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetStopOthers(m_stop_others);
- m_thread.CalculateExecutionContext(exc_ctx);
- m_func_sp = m_impl_function->GetThreadPlanToCallFunction(exc_ctx, m_args_addr, options, diagnostics);
- m_func_sp->SetOkayToDiscard(true);
- m_thread.QueueThreadPlan(m_func_sp, false);
+ if (m_args_addr == LLDB_INVALID_ADDRESS) {
+ return false;
}
- return true;
+ m_impl_function =
+ m_trampoline_handler->GetLookupImplementationFunctionCaller();
+ ExecutionContext exc_ctx;
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(m_stop_others);
+ m_thread.CalculateExecutionContext(exc_ctx);
+ m_func_sp = m_impl_function->GetThreadPlanToCallFunction(
+ exc_ctx, m_args_addr, options, diagnostics);
+ m_func_sp->SetOkayToDiscard(true);
+ m_thread.QueueThreadPlan(m_func_sp, false);
+ }
+ return true;
}
-bool
-AppleThreadPlanStepThroughObjCTrampoline::PreResumeInitializeFunctionCaller(void *void_myself)
-{
- AppleThreadPlanStepThroughObjCTrampoline *myself = static_cast<AppleThreadPlanStepThroughObjCTrampoline *>(void_myself);
- return myself->InitializeFunctionCaller();
+bool AppleThreadPlanStepThroughObjCTrampoline::
+ PreResumeInitializeFunctionCaller(void *void_myself) {
+ AppleThreadPlanStepThroughObjCTrampoline *myself =
+ static_cast<AppleThreadPlanStepThroughObjCTrampoline *>(void_myself);
+ return myself->InitializeFunctionCaller();
}
-void
-AppleThreadPlanStepThroughObjCTrampoline::GetDescription (Stream *s,
- lldb::DescriptionLevel level)
-{
- if (level == lldb::eDescriptionLevelBrief)
- s->Printf("Step through ObjC trampoline");
- else
- {
- s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx, isa: 0x%" PRIx64 ", sel: 0x%" PRIx64,
- m_input_values.GetValueAtIndex(0)->GetScalar().ULongLong(), m_isa_addr, m_sel_addr);
- }
+void AppleThreadPlanStepThroughObjCTrampoline::GetDescription(
+ Stream *s, lldb::DescriptionLevel level) {
+ if (level == lldb::eDescriptionLevelBrief)
+ s->Printf("Step through ObjC trampoline");
+ else {
+ s->Printf("Stepping to implementation of ObjC method - obj: 0x%llx, isa: "
+ "0x%" PRIx64 ", sel: 0x%" PRIx64,
+ m_input_values.GetValueAtIndex(0)->GetScalar().ULongLong(),
+ m_isa_addr, m_sel_addr);
+ }
}
-
-bool
-AppleThreadPlanStepThroughObjCTrampoline::ValidatePlan (Stream *error)
-{
- return true;
+
+bool AppleThreadPlanStepThroughObjCTrampoline::ValidatePlan(Stream *error) {
+ return true;
}
-bool
-AppleThreadPlanStepThroughObjCTrampoline::DoPlanExplainsStop (Event *event_ptr)
-{
- // If we get asked to explain the stop it will be because something went
- // wrong (like the implementation for selector function crashed... We're going
- // to figure out what to do about that, so we do explain the stop.
- return true;
+bool AppleThreadPlanStepThroughObjCTrampoline::DoPlanExplainsStop(
+ Event *event_ptr) {
+ // If we get asked to explain the stop it will be because something went
+ // wrong (like the implementation for selector function crashed... We're
+ // going
+ // to figure out what to do about that, so we do explain the stop.
+ return true;
}
-lldb::StateType
-AppleThreadPlanStepThroughObjCTrampoline::GetPlanRunState ()
-{
- return eStateRunning;
+lldb::StateType AppleThreadPlanStepThroughObjCTrampoline::GetPlanRunState() {
+ return eStateRunning;
}
-bool
-AppleThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr)
-{
- // First stage: we are still handling the "call a function to get the target of the dispatch"
- if (m_func_sp)
- {
- if (!m_func_sp->IsPlanComplete())
- {
- return false;
- }
- else
- {
- if (!m_func_sp->PlanSucceeded())
- {
- SetPlanComplete(false);
- return true;
- }
- m_func_sp.reset();
- }
+bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
+ // First stage: we are still handling the "call a function to get the target
+ // of the dispatch"
+ if (m_func_sp) {
+ if (!m_func_sp->IsPlanComplete()) {
+ return false;
+ } else {
+ if (!m_func_sp->PlanSucceeded()) {
+ SetPlanComplete(false);
+ return true;
+ }
+ m_func_sp.reset();
}
-
- // Second stage, if all went well with the function calling, then fetch the target address, and
- // queue up a "run to that address" plan.
- if (!m_run_to_sp)
- {
- Value target_addr_value;
- ExecutionContext exc_ctx;
- m_thread.CalculateExecutionContext(exc_ctx);
- m_impl_function->FetchFunctionResults (exc_ctx, m_args_addr, target_addr_value);
- m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr);
- lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong();
- Address target_so_addr;
- target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (target_addr == 0)
- {
- if (log)
- log->Printf("Got target implementation of 0x0, stopping.");
- SetPlanComplete();
- return true;
- }
- if (m_trampoline_handler->AddrIsMsgForward(target_addr))
- {
- if (log)
- log->Printf ("Implementation lookup returned msgForward function: 0x%" PRIx64 ", stopping.", target_addr);
-
- SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(eSymbolContextEverything);
- 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);
- return false;
- }
-
- if (log)
- log->Printf("Running to ObjC method implementation: 0x%" PRIx64, target_addr);
-
- ObjCLanguageRuntime *objc_runtime = GetThread().GetProcess()->GetObjCLanguageRuntime();
- assert (objc_runtime != NULL);
- objc_runtime->AddToMethodCache (m_isa_addr, m_sel_addr, target_addr);
- if (log)
- log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64 "} = addr=0x%" PRIx64 " to cache.", m_isa_addr, m_sel_addr, target_addr);
-
- // Extract the target address from the value:
-
- m_run_to_sp.reset(new ThreadPlanRunToAddress(m_thread, target_so_addr, m_stop_others));
- m_thread.QueueThreadPlan(m_run_to_sp, false);
- m_run_to_sp->SetPrivate(true);
- return false;
+ }
+
+ // Second stage, if all went well with the function calling, then fetch the
+ // target address, and
+ // queue up a "run to that address" plan.
+ if (!m_run_to_sp) {
+ Value target_addr_value;
+ ExecutionContext exc_ctx;
+ m_thread.CalculateExecutionContext(exc_ctx);
+ m_impl_function->FetchFunctionResults(exc_ctx, m_args_addr,
+ target_addr_value);
+ m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr);
+ lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong();
+ Address target_so_addr;
+ target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr());
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (target_addr == 0) {
+ if (log)
+ log->Printf("Got target implementation of 0x0, stopping.");
+ SetPlanComplete();
+ return true;
}
- else if (m_thread.IsThreadPlanDone(m_run_to_sp.get()))
- {
- // Third stage, work the run to target plan.
- SetPlanComplete();
- return true;
+ if (m_trampoline_handler->AddrIsMsgForward(target_addr)) {
+ if (log)
+ log->Printf(
+ "Implementation lookup returned msgForward function: 0x%" PRIx64
+ ", stopping.",
+ target_addr);
+
+ SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(
+ eSymbolContextEverything);
+ 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);
+ return false;
}
+
+ if (log)
+ log->Printf("Running to ObjC method implementation: 0x%" PRIx64,
+ target_addr);
+
+ ObjCLanguageRuntime *objc_runtime =
+ GetThread().GetProcess()->GetObjCLanguageRuntime();
+ assert(objc_runtime != NULL);
+ objc_runtime->AddToMethodCache(m_isa_addr, m_sel_addr, target_addr);
+ if (log)
+ log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64
+ "} = addr=0x%" PRIx64 " to cache.",
+ m_isa_addr, m_sel_addr, target_addr);
+
+ // Extract the target address from the value:
+
+ m_run_to_sp.reset(
+ new ThreadPlanRunToAddress(m_thread, target_so_addr, m_stop_others));
+ m_thread.QueueThreadPlan(m_run_to_sp, false);
+ m_run_to_sp->SetPrivate(true);
return false;
+ } else if (m_thread.IsThreadPlanDone(m_run_to_sp.get())) {
+ // Third stage, work the run to target plan.
+ SetPlanComplete();
+ return true;
+ }
+ return false;
}
// 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;
-}
-
-bool
-AppleThreadPlanStepThroughObjCTrampoline::WillStop()
-{
+bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() {
+ if (IsPlanComplete())
return true;
+ else
+ return false;
}
+
+bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; }
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
index 8db9963fa51a..60c8b92d9cc7 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
@@ -14,80 +14,66 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-types.h"
-#include "lldb/lldb-enumerations.h"
+#include "AppleObjCTrampolineHandler.h"
#include "lldb/Core/Value.h"
#include "lldb/Target/ThreadPlan.h"
-#include "AppleObjCTrampolineHandler.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-types.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan
-{
+class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan {
public:
- AppleThreadPlanStepThroughObjCTrampoline(Thread &thread,
- AppleObjCTrampolineHandler *trampoline_handler,
- ValueList &values,
- lldb::addr_t isa_addr,
- lldb::addr_t sel_addr,
- bool stop_others);
-
- ~AppleThreadPlanStepThroughObjCTrampoline() override;
-
- static bool
- PreResumeInitializeFunctionCaller(void *myself);
-
- void
- GetDescription(Stream *s,
- lldb::DescriptionLevel level) override;
-
- bool
- ValidatePlan(Stream *error) override;
-
- lldb::StateType
- GetPlanRunState() override;
-
- bool
- ShouldStop(Event *event_ptr) override;
-
- bool
- StopOthers() override
- {
- return m_stop_others;
- }
-
- // The base class MischiefManaged does some cleanup - so you have to call it
- // in your MischiefManaged derived class.
- bool
- MischiefManaged() override;
-
- void
- DidPush() override;
-
- bool
- WillStop() override;
+ AppleThreadPlanStepThroughObjCTrampoline(
+ Thread &thread, AppleObjCTrampolineHandler *trampoline_handler,
+ ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
+ bool stop_others);
+
+ ~AppleThreadPlanStepThroughObjCTrampoline() override;
+
+ static bool PreResumeInitializeFunctionCaller(void *myself);
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ValidatePlan(Stream *error) override;
+
+ lldb::StateType GetPlanRunState() override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ bool StopOthers() override { return m_stop_others; }
+
+ // The base class MischiefManaged does some cleanup - so you have to call it
+ // in your MischiefManaged derived class.
+ bool MischiefManaged() override;
+
+ void DidPush() override;
+
+ bool WillStop() override;
protected:
- bool
- DoPlanExplainsStop(Event *event_ptr) override;
-
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
private:
- bool
- InitializeFunctionCaller ();
-
- AppleObjCTrampolineHandler *m_trampoline_handler; // FIXME - ensure this doesn't go away on us? SP maybe?
- lldb::addr_t m_args_addr; // Stores the address for our step through function result structure.
- //lldb::addr_t m_object_addr; // This is only for Description.
- ValueList m_input_values;
- lldb::addr_t m_isa_addr; // isa_addr and sel_addr are the keys we will use to cache the implementation.
- lldb::addr_t m_sel_addr;
- lldb::ThreadPlanSP m_func_sp; // This is the function call plan. We fill it at start, then set it
- // to NULL when this plan is done. That way we know to go to:
- lldb::ThreadPlanSP m_run_to_sp; // The plan that runs to the target.
- FunctionCaller *m_impl_function; // This is a pointer to a impl function that
- // is owned by the client that pushes this plan.
- bool m_stop_others;
+ bool InitializeFunctionCaller();
+
+ AppleObjCTrampolineHandler *m_trampoline_handler; // FIXME - ensure this
+ // doesn't go away on us?
+ // SP maybe?
+ lldb::addr_t m_args_addr; // Stores the address for our step through function
+ // result structure.
+ // lldb::addr_t m_object_addr; // This is only for Description.
+ ValueList m_input_values;
+ lldb::addr_t m_isa_addr; // isa_addr and sel_addr are the keys we will use to
+ // cache the implementation.
+ lldb::addr_t m_sel_addr;
+ lldb::ThreadPlanSP m_func_sp; // This is the function call plan. We fill it
+ // at start, then set it
+ // to NULL when this plan is done. That way we know to go to:
+ lldb::ThreadPlanSP m_run_to_sp; // The plan that runs to the target.
+ FunctionCaller *m_impl_function; // This is a pointer to a impl function that
+ // is owned by the client that pushes this plan.
+ bool m_stop_others;
};
} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt
index d93e9fa2a291..cd08f14137dc 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt
@@ -1,3 +1,14 @@
+if(NOT LLDB_BUILT_STANDALONE)
+ set(tablegen_deps intrinsics_gen)
+endif()
+
+
add_lldb_library(lldbPluginRenderScriptRuntime
RenderScriptRuntime.cpp
+ RenderScriptExpressionOpts.cpp
+ RenderScriptx86ABIFixups.cpp
+ RenderScriptScriptGroup.cpp
+
+ DEPENDS
+ ${tablegen_deps}
)
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
new file mode 100644
index 000000000000..b05618634868
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -0,0 +1,200 @@
+//===-- RenderScriptExpressionOpts.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 <string>
+
+// Other libraries and framework includes
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+
+#include "clang/Basic/TargetOptions.h"
+
+// Project includes
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "RenderScriptExpressionOpts.h"
+#include "RenderScriptRuntime.h"
+#include "RenderScriptx86ABIFixups.h"
+
+using namespace lldb_private;
+using namespace lldb_renderscript;
+
+// [``slang``](https://android.googlesource.com/platform/frameworks/compile/slang),
+// the compiler frontend for RenderScript embeds an ARM specific triple in IR
+// that is shipped in the app, after
+// generating IR that has some assumptions that an ARM device is the target.
+// As the IR is then compiled on a device of unknown (at time the IR was
+// generated at least) architecture,
+// when calling RenderScript API function as part of debugger expressions, we
+// have to perform a fixup pass that
+// removes those assumptions right before the module is sent to be generated by
+// the llvm backend.
+
+namespace {
+bool registerRSDefaultTargetOpts(clang::TargetOptions &proto,
+ const llvm::Triple::ArchType &arch) {
+ switch (arch) {
+ case llvm::Triple::ArchType::x86:
+ proto.Triple = "i686--linux-android";
+ proto.CPU = "atom";
+ proto.Features.push_back("+long64");
+ // Fallthrough for common x86 family features
+ LLVM_FALLTHROUGH;
+ case llvm::Triple::ArchType::x86_64:
+ proto.Features.push_back("+mmx");
+ proto.Features.push_back("+sse");
+ proto.Features.push_back("+sse2");
+ proto.Features.push_back("+sse3");
+ proto.Features.push_back("+ssse3");
+ proto.Features.push_back("+sse4.1");
+ proto.Features.push_back("+sse4.2");
+ break;
+ case llvm::Triple::ArchType::mipsel:
+ // pretend this is `arm' for the front-end
+ proto.Triple = "armv7-none-linux-android";
+ proto.CPU = "";
+ proto.Features.push_back("+long64");
+ break;
+ case llvm::Triple::ArchType::mips64el:
+ // pretend this is `aarch64' for the front-end
+ proto.Triple = "aarch64-none-linux-android";
+ proto.CPU = "";
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+} // end anonymous namespace
+
+bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
+ bool changed_module = false;
+ Log *log(
+ GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_EXPRESSIONS));
+
+ std::string err;
+ llvm::StringRef real_triple =
+ m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple();
+ const llvm::Target *target_info =
+ llvm::TargetRegistry::lookupTarget(real_triple, err);
+ if (!target_info) {
+ if (log)
+ log->Warning("couldn't determine real target architecture: '%s'",
+ err.c_str());
+ return false;
+ }
+
+ llvm::Optional<llvm::Reloc::Model> reloc_model = llvm::None;
+ assert(m_process_ptr && "no available lldb process");
+ switch (m_process_ptr->GetTarget().GetArchitecture().GetMachine()) {
+ case llvm::Triple::ArchType::x86:
+ changed_module |= fixupX86FunctionCalls(module);
+ // For some reason this triple gets totally missed by the backend, and must
+ // be set manually.
+ // There a reference in bcc/Main.cpp about auto feature-detection being
+ // removed from LLVM3.5, but I can't
+ // see that discussion anywhere public.
+ real_triple = "i686--linux-android";
+ break;
+ case llvm::Triple::ArchType::x86_64:
+ changed_module |= fixupX86_64FunctionCalls(module);
+ break;
+ case llvm::Triple::ArchType::mipsel:
+ case llvm::Triple::ArchType::mips64el:
+ // No actual IR fixup pass is needed on MIPS, but the datalayout
+ // and targetmachine do need to be explicitly set.
+
+ // bcc explicitly compiles MIPS code to use the static relocation
+ // model due to an issue with relocations in mclinker.
+ // see libbcc/support/CompilerConfig.cpp for details
+ reloc_model = llvm::Reloc::Static;
+ changed_module = true;
+ break;
+ case llvm::Triple::ArchType::arm:
+ case llvm::Triple::ArchType::aarch64:
+ // ARM subtargets need no fixup passes as they are the initial target as
+ // generated by the
+ // slang compiler frontend.
+ break;
+ default:
+ if (log)
+ log->Warning("Ignoring unknown renderscript target");
+ return false;
+ }
+
+ if (changed_module) {
+ llvm::TargetOptions options;
+ llvm::TargetMachine *target_machine = target_info->createTargetMachine(
+ real_triple, "", "", options, reloc_model);
+ assert(target_machine &&
+ "failed to identify RenderScriptRuntime target machine");
+ // We've been using a triple and datalayout of some ARM variant all along,
+ // so
+ // we need to let the backend know that this is no longer the case.
+ if (log) {
+ log->Printf("%s - Changing RS target triple to '%s'", __FUNCTION__,
+ real_triple.str().c_str());
+ log->Printf(
+ "%s - Changing RS datalayout to '%s'", __FUNCTION__,
+ target_machine->createDataLayout().getStringRepresentation().c_str());
+ }
+ module.setTargetTriple(real_triple);
+ module.setDataLayout(target_machine->createDataLayout());
+ }
+ return changed_module;
+}
+
+char RenderScriptRuntimeModulePass::ID = 0;
+
+namespace lldb_private {
+
+bool RenderScriptRuntime::GetOverrideExprOptions(clang::TargetOptions &proto) {
+ auto *process = GetProcess();
+ assert(process);
+ return registerRSDefaultTargetOpts(
+ proto, process->GetTarget().GetArchitecture().GetMachine());
+}
+
+bool RenderScriptRuntime::GetIRPasses(LLVMUserExpression::IRPasses &passes) {
+ if (!m_ir_passes)
+ m_ir_passes = new RSIRPasses(GetProcess());
+ assert(m_ir_passes);
+
+ passes.EarlyPasses = m_ir_passes->EarlyPasses;
+ passes.LatePasses = m_ir_passes->LatePasses;
+
+ return true;
+}
+
+namespace lldb_renderscript {
+
+RSIRPasses::RSIRPasses(Process *process) {
+ IRPasses();
+ assert(process);
+
+ EarlyPasses = std::make_shared<llvm::legacy::PassManager>();
+ assert(EarlyPasses);
+ EarlyPasses->add(new RenderScriptRuntimeModulePass(process));
+}
+
+RSIRPasses::~RSIRPasses() {}
+
+} // namespace lldb_renderscript
+} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
new file mode 100644
index 000000000000..f45ff83c5a2b
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
@@ -0,0 +1,57 @@
+//===-- RenderScriptExpressionOpts.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_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"
+
+#include "RenderScriptRuntime.h"
+#include "RenderScriptx86ABIFixups.h"
+
+// RenderScriptRuntimeModulePass is a simple llvm::ModulesPass that is used
+// during expression evaluation to apply RenderScript-specific fixes for
+// expression evaluation. In particular this is used to make expression IR
+// conformant with the ABI generated by the slang frontend. This ModulePass is
+// executed in ClangExpressionParser::PrepareForExecution whenever an
+// expression's DWARF language is eLanguageTypeExtRenderscript
+
+class RenderScriptRuntimeModulePass : public llvm::ModulePass {
+public:
+ static char ID;
+ RenderScriptRuntimeModulePass(const lldb_private::Process *process)
+ : ModulePass(ID), m_process_ptr(process) {}
+
+ bool runOnModule(llvm::Module &module);
+
+private:
+ const lldb_private::Process *m_process_ptr;
+};
+
+namespace lldb_private {
+namespace lldb_renderscript {
+struct RSIRPasses : public lldb_private::LLVMUserExpression::IRPasses {
+ RSIRPasses(lldb_private::Process *process);
+
+ ~RSIRPasses();
+};
+} // namespace lldb_renderscript
+} // namespace lldb_private
+#endif
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 7441fd991511..82473fba065b 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -10,8 +10,11 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "llvm/ADT/StringSwitch.h"
+
// Project includes
#include "RenderScriptRuntime.h"
+#include "RenderScriptScriptGroup.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/ConstString.h"
@@ -29,11 +32,13 @@
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -41,652 +46,661 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_renderscript;
-namespace
-{
+#define FMT_COORD "(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")"
+
+namespace {
// The empirical_type adds a basic level of validation to arbitrary data
-// allowing us to track if data has been discovered and stored or not.
-// An empirical_type will be marked as valid only if it has been explicitly assigned to.
-template <typename type_t> class empirical_type
-{
+// allowing us to track if data has been discovered and stored or not. An
+// empirical_type will be marked as valid only if it has been explicitly
+// assigned to.
+template <typename type_t> class empirical_type {
public:
- // Ctor. Contents is invalid when constructed.
- empirical_type() : valid(false) {}
-
- // Return true and copy contents to out if valid, else return false.
- bool
- get(type_t &out) const
- {
- if (valid)
- out = data;
- return valid;
- }
-
- // Return a pointer to the contents or nullptr if it was not valid.
- const type_t *
- get() const
- {
- return valid ? &data : nullptr;
- }
-
- // Assign data explicitly.
- void
- set(const type_t in)
- {
- data = in;
- valid = true;
- }
-
- // Mark contents as invalid.
- void
- invalidate()
- {
- valid = false;
- }
-
- // Returns true if this type contains valid data.
- bool
- isValid() const
- {
- return valid;
- }
-
- // Assignment operator.
- empirical_type<type_t> &
- operator=(const type_t in)
- {
- set(in);
- return *this;
- }
-
- // Dereference operator returns contents.
- // Warning: Will assert if not valid so use only when you know data is valid.
- const type_t &operator*() const
- {
- assert(valid);
- return data;
- }
+ // Ctor. Contents is invalid when constructed.
+ empirical_type() : valid(false) {}
+
+ // Return true and copy contents to out if valid, else return false.
+ bool get(type_t &out) const {
+ if (valid)
+ out = data;
+ return valid;
+ }
+
+ // Return a pointer to the contents or nullptr if it was not valid.
+ const type_t *get() const { return valid ? &data : nullptr; }
+
+ // Assign data explicitly.
+ void set(const type_t in) {
+ data = in;
+ valid = true;
+ }
+
+ // Mark contents as invalid.
+ void invalidate() { valid = false; }
+
+ // Returns true if this type contains valid data.
+ bool isValid() const { return valid; }
+
+ // Assignment operator.
+ empirical_type<type_t> &operator=(const type_t in) {
+ set(in);
+ return *this;
+ }
+
+ // Dereference operator returns contents.
+ // Warning: Will assert if not valid so use only when you know data is valid.
+ const type_t &operator*() const {
+ assert(valid);
+ return data;
+ }
protected:
- bool valid;
- type_t data;
+ bool valid;
+ type_t data;
};
-// ArgItem is used by the GetArgs() function when reading function arguments from the target.
-struct ArgItem
-{
- enum
- {
- ePointer,
- eInt32,
- eInt64,
- eLong,
- eBool
- } type;
+// ArgItem is used by the GetArgs() function when reading function arguments
+// from the target.
+struct ArgItem {
+ enum { ePointer, eInt32, eInt64, eLong, eBool } type;
- uint64_t value;
+ uint64_t value;
- explicit operator uint64_t() const { return value; }
+ explicit operator uint64_t() const { return value; }
};
-// Context structure to be passed into GetArgsXXX(), argument reading functions below.
-struct GetArgsCtx
-{
- RegisterContext *reg_ctx;
- Process *process;
+// Context structure to be passed into GetArgsXXX(), argument reading functions
+// below.
+struct GetArgsCtx {
+ RegisterContext *reg_ctx;
+ Process *process;
};
-bool
-GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
-{
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
- Error error;
+ Error err;
- // get the current stack pointer
- uint64_t sp = ctx.reg_ctx->GetSP();
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
- for (size_t i = 0; i < num_args; ++i)
- {
- ArgItem &arg = arg_list[i];
- // advance up the stack by one argument
- sp += sizeof(uint32_t);
- // get the argument type size
- size_t arg_size = sizeof(uint32_t);
- // read the argument from memory
- arg.value = 0;
- Error error;
- size_t read = ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), error);
- if (read != arg_size || !error.Success())
- {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 " '%s'", __FUNCTION__, uint64_t(i),
- error.AsCString());
- return false;
- }
- }
- return true;
+ for (size_t i = 0; i < num_args; ++i) {
+ ArgItem &arg = arg_list[i];
+ // advance up the stack by one argument
+ sp += sizeof(uint32_t);
+ // get the argument type size
+ size_t arg_size = sizeof(uint32_t);
+ // read the argument from memory
+ arg.value = 0;
+ Error err;
+ size_t read =
+ ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), err);
+ if (read != arg_size || !err.Success()) {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64 " '%s'",
+ __FUNCTION__, uint64_t(i), err.AsCString());
+ return false;
+ }
+ }
+ return true;
}
-bool
-GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
-{
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
-
- // number of arguments passed in registers
- static const uint32_t c_args_in_reg = 6;
- // register passing order
- static const std::array<const char *, c_args_in_reg> c_reg_names{{"rdi", "rsi", "rdx", "rcx", "r8", "r9"}};
- // argument type to size mapping
- static const std::array<size_t, 5> arg_size{{
- 8, // ePointer,
- 4, // eInt32,
- 8, // eInt64,
- 8, // eLong,
- 4, // eBool,
- }};
-
- Error error;
-
- // get the current stack pointer
- uint64_t sp = ctx.reg_ctx->GetSP();
- // step over the return address
- sp += sizeof(uint64_t);
-
- // check the stack alignment was correct (16 byte aligned)
- if ((sp & 0xf) != 0x0)
- {
- if (log)
- log->Printf("%s - stack misaligned", __FUNCTION__);
- return false;
- }
-
- // find the start of arguments on the stack
- uint64_t sp_offset = 0;
- for (uint32_t i = c_args_in_reg; i < num_args; ++i)
- {
- sp_offset += arg_size[arg_list[i].type];
- }
- // round up to multiple of 16
- sp_offset = (sp_offset + 0xf) & 0xf;
- sp += sp_offset;
-
- for (size_t i = 0; i < num_args; ++i)
- {
- bool success = false;
- ArgItem &arg = arg_list[i];
- // arguments passed in registers
- if (i < c_args_in_reg)
- {
- const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoByName(c_reg_names[i]);
- RegisterValue rVal;
- if (ctx.reg_ctx->ReadRegister(rArg, rVal))
- arg.value = rVal.GetAsUInt64(0, &success);
- }
- // arguments passed on the stack
- else
- {
- // get the argument type size
- const size_t size = arg_size[arg_list[i].type];
- // read the argument from memory
- arg.value = 0;
- // note: due to little endian layout reading 4 or 8 bytes will give the correct value.
- size_t read = ctx.process->ReadMemory(sp, &arg.value, size, error);
- success = (error.Success() && read==size);
- // advance past this argument
- sp -= size;
- }
- // fail if we couldn't read this argument
- if (!success)
- {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
- __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
- return false;
- }
- }
- return true;
+bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ // number of arguments passed in registers
+ static const uint32_t args_in_reg = 6;
+ // register passing order
+ static const std::array<const char *, args_in_reg> reg_names{
+ {"rdi", "rsi", "rdx", "rcx", "r8", "r9"}};
+ // argument type to size mapping
+ static const std::array<size_t, 5> arg_size{{
+ 8, // ePointer,
+ 4, // eInt32,
+ 8, // eInt64,
+ 8, // eLong,
+ 4, // eBool,
+ }};
+
+ Error err;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+ // step over the return address
+ sp += sizeof(uint64_t);
+
+ // check the stack alignment was correct (16 byte aligned)
+ if ((sp & 0xf) != 0x0) {
+ if (log)
+ log->Printf("%s - stack misaligned", __FUNCTION__);
+ return false;
+ }
+
+ // find the start of arguments on the stack
+ uint64_t sp_offset = 0;
+ for (uint32_t i = args_in_reg; i < num_args; ++i) {
+ sp_offset += arg_size[arg_list[i].type];
+ }
+ // round up to multiple of 16
+ sp_offset = (sp_offset + 0xf) & 0xf;
+ sp += sp_offset;
+
+ for (size_t i = 0; i < num_args; ++i) {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < args_in_reg) {
+ const RegisterInfo *reg =
+ ctx.reg_ctx->GetRegisterInfoByName(reg_names[i]);
+ RegisterValue reg_val;
+ if (ctx.reg_ctx->ReadRegister(reg, reg_val))
+ arg.value = reg_val.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else {
+ // get the argument type size
+ const size_t size = arg_size[arg_list[i].type];
+ // read the argument from memory
+ arg.value = 0;
+ // note: due to little endian layout reading 4 or 8 bytes will give the
+ // correct value.
+ size_t read = ctx.process->ReadMemory(sp, &arg.value, size, err);
+ success = (err.Success() && read == size);
+ // advance past this argument
+ sp -= size;
+ }
+ // fail if we couldn't read this argument
+ if (!success) {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
}
-bool
-GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
-{
- // number of arguments passed in registers
- static const uint32_t c_args_in_reg = 4;
+bool GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
+ // number of arguments passed in registers
+ static const uint32_t args_in_reg = 4;
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
- Error error;
+ Error err;
- // get the current stack pointer
- uint64_t sp = ctx.reg_ctx->GetSP();
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
- for (size_t i = 0; i < num_args; ++i)
- {
- bool success = false;
- ArgItem &arg = arg_list[i];
- // arguments passed in registers
- if (i < c_args_in_reg)
- {
- const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
- RegisterValue rVal;
- if (ctx.reg_ctx->ReadRegister(rArg, rVal))
- arg.value = rVal.GetAsUInt32(0, &success);
- }
- // arguments passed on the stack
- else
- {
- // get the argument type size
- const size_t arg_size = sizeof(uint32_t);
- // clear all 64bits
- arg.value = 0;
- // read this argument from memory
- size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
- success = (error.Success() && bytes_read == arg_size);
- // advance the stack pointer
- sp += sizeof(uint32_t);
- }
- // fail if we couldn't read this argument
- if (!success)
- {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
- __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
- return false;
- }
- }
- return true;
+ for (size_t i = 0; i < num_args; ++i) {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < args_in_reg) {
+ const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
+ RegisterValue reg_val;
+ if (ctx.reg_ctx->ReadRegister(reg, reg_val))
+ arg.value = reg_val.GetAsUInt32(0, &success);
+ }
+ // arguments passed on the stack
+ else {
+ // get the argument type size
+ const size_t arg_size = sizeof(uint32_t);
+ // clear all 64bits
+ arg.value = 0;
+ // read this argument from memory
+ size_t bytes_read =
+ ctx.process->ReadMemory(sp, &arg.value, arg_size, err);
+ success = (err.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += sizeof(uint32_t);
+ }
+ // fail if we couldn't read this argument
+ if (!success) {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
}
-bool
-GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
-{
- // number of arguments passed in registers
- static const uint32_t c_args_in_reg = 8;
+bool GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
+ // number of arguments passed in registers
+ static const uint32_t args_in_reg = 8;
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
- for (size_t i = 0; i < num_args; ++i)
- {
- bool success = false;
- ArgItem &arg = arg_list[i];
- // arguments passed in registers
- if (i < c_args_in_reg)
- {
- const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
- RegisterValue rVal;
- if (ctx.reg_ctx->ReadRegister(rArg, rVal))
- arg.value = rVal.GetAsUInt64(0, &success);
- }
- // arguments passed on the stack
- else
- {
- if (log)
- log->Printf("%s - reading arguments spilled to stack not implemented", __FUNCTION__);
- }
- // fail if we couldn't read this argument
- if (!success)
- {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64, __FUNCTION__,
- uint64_t(i));
- return false;
- }
- }
- return true;
+ for (size_t i = 0; i < num_args; ++i) {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < args_in_reg) {
+ const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
+ RegisterValue reg_val;
+ if (ctx.reg_ctx->ReadRegister(reg, reg_val))
+ arg.value = reg_val.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else {
+ if (log)
+ log->Printf("%s - reading arguments spilled to stack not implemented",
+ __FUNCTION__);
+ }
+ // fail if we couldn't read this argument
+ if (!success) {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64, __FUNCTION__,
+ uint64_t(i));
+ return false;
+ }
+ }
+ return true;
}
-bool
-GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
-{
- // number of arguments passed in registers
- static const uint32_t c_args_in_reg = 4;
- // register file offset to first argument
- static const uint32_t c_reg_offset = 4;
+bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
+ // number of arguments passed in registers
+ static const uint32_t args_in_reg = 4;
+ // register file offset to first argument
+ static const uint32_t reg_offset = 4;
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
- Error error;
+ Error err;
- // find offset to arguments on the stack (+16 to skip over a0-a3 shadow space)
- uint64_t sp = ctx.reg_ctx->GetSP() + 16;
+ // find offset to arguments on the stack (+16 to skip over a0-a3 shadow space)
+ uint64_t sp = ctx.reg_ctx->GetSP() + 16;
- for (size_t i = 0; i < num_args; ++i)
- {
- bool success = false;
- ArgItem &arg = arg_list[i];
- // arguments passed in registers
- if (i < c_args_in_reg)
- {
- const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i + c_reg_offset);
- RegisterValue rVal;
- if (ctx.reg_ctx->ReadRegister(rArg, rVal))
- arg.value = rVal.GetAsUInt64(0, &success);
- }
- // arguments passed on the stack
- else
- {
- const size_t arg_size = sizeof(uint32_t);
- arg.value = 0;
- size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
- success = (error.Success() && bytes_read == arg_size);
- // advance the stack pointer
- sp += arg_size;
- }
- // fail if we couldn't read this argument
- if (!success)
- {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
- __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
- return false;
- }
- }
- return true;
+ for (size_t i = 0; i < num_args; ++i) {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < args_in_reg) {
+ const RegisterInfo *reg =
+ ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset);
+ RegisterValue reg_val;
+ if (ctx.reg_ctx->ReadRegister(reg, reg_val))
+ arg.value = reg_val.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else {
+ const size_t arg_size = sizeof(uint32_t);
+ arg.value = 0;
+ size_t bytes_read =
+ ctx.process->ReadMemory(sp, &arg.value, arg_size, err);
+ success = (err.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += arg_size;
+ }
+ // fail if we couldn't read this argument
+ if (!success) {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
}
-bool
-GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
-{
- // number of arguments passed in registers
- static const uint32_t c_args_in_reg = 8;
- // register file offset to first argument
- static const uint32_t c_reg_offset = 4;
+bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
+ // number of arguments passed in registers
+ static const uint32_t args_in_reg = 8;
+ // register file offset to first argument
+ static const uint32_t reg_offset = 4;
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
- Error error;
+ Error err;
- // get the current stack pointer
- uint64_t sp = ctx.reg_ctx->GetSP();
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
- for (size_t i = 0; i < num_args; ++i)
- {
- bool success = false;
- ArgItem &arg = arg_list[i];
- // arguments passed in registers
- if (i < c_args_in_reg)
- {
- const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i + c_reg_offset);
- RegisterValue rVal;
- if (ctx.reg_ctx->ReadRegister(rArg, rVal))
- arg.value = rVal.GetAsUInt64(0, &success);
- }
- // arguments passed on the stack
- else
- {
- // get the argument type size
- const size_t arg_size = sizeof(uint64_t);
- // clear all 64bits
- arg.value = 0;
- // read this argument from memory
- size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
- success = (error.Success() && bytes_read == arg_size);
- // advance the stack pointer
- sp += arg_size;
- }
- // fail if we couldn't read this argument
- if (!success)
- {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
- __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
- return false;
- }
- }
- return true;
+ for (size_t i = 0; i < num_args; ++i) {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < args_in_reg) {
+ const RegisterInfo *reg =
+ ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset);
+ RegisterValue reg_val;
+ if (ctx.reg_ctx->ReadRegister(reg, reg_val))
+ arg.value = reg_val.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else {
+ // get the argument type size
+ const size_t arg_size = sizeof(uint64_t);
+ // clear all 64bits
+ arg.value = 0;
+ // read this argument from memory
+ size_t bytes_read =
+ ctx.process->ReadMemory(sp, &arg.value, arg_size, err);
+ success = (err.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += arg_size;
+ }
+ // fail if we couldn't read this argument
+ if (!success) {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
}
-bool
-GetArgs(ExecutionContext &context, ArgItem *arg_list, size_t num_args)
-{
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
- // verify that we have a target
- if (!context.GetTargetPtr())
- {
- if (log)
- log->Printf("%s - invalid target", __FUNCTION__);
- return false;
- }
+ // verify that we have a target
+ if (!exe_ctx.GetTargetPtr()) {
+ if (log)
+ log->Printf("%s - invalid target", __FUNCTION__);
+ return false;
+ }
- GetArgsCtx ctx = {context.GetRegisterContext(), context.GetProcessPtr()};
- assert(ctx.reg_ctx && ctx.process);
+ GetArgsCtx ctx = {exe_ctx.GetRegisterContext(), exe_ctx.GetProcessPtr()};
+ assert(ctx.reg_ctx && ctx.process);
- // dispatch based on architecture
- switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
- {
- case llvm::Triple::ArchType::x86:
- return GetArgsX86(ctx, arg_list, num_args);
+ // dispatch based on architecture
+ switch (exe_ctx.GetTargetPtr()->GetArchitecture().GetMachine()) {
+ case llvm::Triple::ArchType::x86:
+ return GetArgsX86(ctx, arg_list, num_args);
- case llvm::Triple::ArchType::x86_64:
- return GetArgsX86_64(ctx, arg_list, num_args);
+ case llvm::Triple::ArchType::x86_64:
+ return GetArgsX86_64(ctx, arg_list, num_args);
- case llvm::Triple::ArchType::arm:
- return GetArgsArm(ctx, arg_list, num_args);
+ case llvm::Triple::ArchType::arm:
+ return GetArgsArm(ctx, arg_list, num_args);
- case llvm::Triple::ArchType::aarch64:
- return GetArgsAarch64(ctx, arg_list, num_args);
+ case llvm::Triple::ArchType::aarch64:
+ return GetArgsAarch64(ctx, arg_list, num_args);
- case llvm::Triple::ArchType::mipsel:
- return GetArgsMipsel(ctx, arg_list, num_args);
+ case llvm::Triple::ArchType::mipsel:
+ return GetArgsMipsel(ctx, arg_list, num_args);
- case llvm::Triple::ArchType::mips64el:
- return GetArgsMips64el(ctx, arg_list, num_args);
+ case llvm::Triple::ArchType::mips64el:
+ return GetArgsMips64el(ctx, arg_list, num_args);
- default:
- // unsupported architecture
- if (log)
- {
- log->Printf("%s - architecture not supported: '%s'", __FUNCTION__,
- context.GetTargetRef().GetArchitecture().GetArchitectureName());
- }
- return false;
+ default:
+ // unsupported architecture
+ if (log) {
+ log->Printf(
+ "%s - architecture not supported: '%s'", __FUNCTION__,
+ exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName());
}
+ return false;
+ }
}
-} // anonymous namespace
-// The ScriptDetails class collects data associated with a single script instance.
-struct RenderScriptRuntime::ScriptDetails
-{
- ~ScriptDetails() = default;
+bool IsRenderScriptScriptModule(ModuleSP module) {
+ if (!module)
+ return false;
+ return module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"),
+ eSymbolTypeData) != nullptr;
+}
- enum ScriptType
- {
- eScript,
- eScriptC
- };
-
- // The derived type of the script.
- empirical_type<ScriptType> type;
- // The name of the original source file.
- empirical_type<std::string> resName;
- // Path to script .so file on the device.
- empirical_type<std::string> scriptDyLib;
- // Directory where kernel objects are cached on device.
- empirical_type<std::string> cacheDir;
- // Pointer to the context which owns this script.
- empirical_type<lldb::addr_t> context;
- // Pointer to the script object itself.
- empirical_type<lldb::addr_t> script;
-};
+bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) {
+ // takes an argument of the form 'num[,num][,num]'.
+ // Where 'coord_s' is a comma separated 1,2 or 3-dimensional coordinate
+ // with the whitespace trimmed.
+ // Missing coordinates are defaulted to zero.
+ // If parsing of any elements fails the contents of &coord are undefined
+ // and `false` is returned, `true` otherwise
+
+ RegularExpression regex;
+ RegularExpression::Match regex_match(3);
+
+ bool matched = false;
+ if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+),([0-9]+)$")) &&
+ regex.Execute(coord_s, &regex_match))
+ matched = true;
+ else if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+)$")) &&
+ regex.Execute(coord_s, &regex_match))
+ matched = true;
+ else if (regex.Compile(llvm::StringRef("^([0-9]+)$")) &&
+ regex.Execute(coord_s, &regex_match))
+ matched = true;
+
+ if (!matched)
+ return false;
-// This Element class represents the Element object in RS,
-// defining the type associated with an Allocation.
-struct RenderScriptRuntime::Element
-{
- // Taken from rsDefines.h
- enum DataKind
- {
- RS_KIND_USER,
- RS_KIND_PIXEL_L = 7,
- RS_KIND_PIXEL_A,
- RS_KIND_PIXEL_LA,
- RS_KIND_PIXEL_RGB,
- RS_KIND_PIXEL_RGBA,
- RS_KIND_PIXEL_DEPTH,
- RS_KIND_PIXEL_YUV,
- RS_KIND_INVALID = 100
- };
-
- // Taken from rsDefines.h
- enum DataType
- {
- RS_TYPE_NONE = 0,
- RS_TYPE_FLOAT_16,
- RS_TYPE_FLOAT_32,
- RS_TYPE_FLOAT_64,
- RS_TYPE_SIGNED_8,
- RS_TYPE_SIGNED_16,
- RS_TYPE_SIGNED_32,
- RS_TYPE_SIGNED_64,
- RS_TYPE_UNSIGNED_8,
- RS_TYPE_UNSIGNED_16,
- RS_TYPE_UNSIGNED_32,
- RS_TYPE_UNSIGNED_64,
- RS_TYPE_BOOLEAN,
-
- RS_TYPE_UNSIGNED_5_6_5,
- RS_TYPE_UNSIGNED_5_5_5_1,
- RS_TYPE_UNSIGNED_4_4_4_4,
-
- RS_TYPE_MATRIX_4X4,
- RS_TYPE_MATRIX_3X3,
- RS_TYPE_MATRIX_2X2,
-
- RS_TYPE_ELEMENT = 1000,
- RS_TYPE_TYPE,
- RS_TYPE_ALLOCATION,
- RS_TYPE_SAMPLER,
- RS_TYPE_SCRIPT,
- RS_TYPE_MESH,
- RS_TYPE_PROGRAM_FRAGMENT,
- RS_TYPE_PROGRAM_VERTEX,
- RS_TYPE_PROGRAM_RASTER,
- RS_TYPE_PROGRAM_STORE,
- RS_TYPE_FONT,
-
- RS_TYPE_INVALID = 10000
- };
-
- std::vector<Element> children; // Child Element fields for structs
- empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
- empirical_type<DataType> type; // Type of each data pointer stored by the allocation
- empirical_type<DataKind> type_kind; // Defines pixel type if Allocation is created from an image
- empirical_type<uint32_t> type_vec_size; // Vector size of each data point, e.g '4' for uchar4
- empirical_type<uint32_t> field_count; // Number of Subelements
- empirical_type<uint32_t> datum_size; // Size of a single Element with padding
- empirical_type<uint32_t> padding; // Number of padding bytes
- empirical_type<uint32_t> array_size; // Number of items in array, only needed for strucrs
- ConstString type_name; // Name of type, only needed for structs
-
- static const ConstString &
- GetFallbackStructName(); // Print this as the type name of a struct Element
- // If we can't resolve the actual struct name
-
- bool
- shouldRefresh() const
- {
- const bool valid_ptr = element_ptr.isValid() && *element_ptr.get() != 0x0;
- const bool valid_type = type.isValid() && type_vec_size.isValid() && type_kind.isValid();
- return !valid_ptr || !valid_type || !datum_size.isValid();
+ auto get_index = [&](int idx, uint32_t &i) -> bool {
+ std::string group;
+ errno = 0;
+ if (regex_match.GetMatchAtIndex(coord_s.str().c_str(), idx + 1, group))
+ return !llvm::StringRef(group).getAsInteger<uint32_t>(10, i);
+ return true;
+ };
+
+ return get_index(0, coord.x) && get_index(1, coord.y) &&
+ get_index(2, coord.z);
+}
+
+bool SkipPrologue(lldb::ModuleSP &module, Address &addr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ SymbolContext sc;
+ uint32_t resolved_flags =
+ module->ResolveSymbolContextForAddress(addr, eSymbolContextFunction, sc);
+ if (resolved_flags & eSymbolContextFunction) {
+ if (sc.function) {
+ const uint32_t offset = sc.function->GetPrologueByteSize();
+ ConstString name = sc.GetFunctionName();
+ if (offset)
+ addr.Slide(offset);
+ if (log)
+ log->Printf("%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
+ name.AsCString(), offset);
}
+ return true;
+ } else
+ return false;
+}
+} // anonymous namespace
+
+// The ScriptDetails class collects data associated with a single script
+// instance.
+struct RenderScriptRuntime::ScriptDetails {
+ ~ScriptDetails() = default;
+
+ enum ScriptType { eScript, eScriptC };
+
+ // The derived type of the script.
+ empirical_type<ScriptType> type;
+ // The name of the original source file.
+ empirical_type<std::string> res_name;
+ // Path to script .so file on the device.
+ empirical_type<std::string> shared_lib;
+ // Directory where kernel objects are cached on device.
+ empirical_type<std::string> cache_dir;
+ // Pointer to the context which owns this script.
+ empirical_type<lldb::addr_t> context;
+ // Pointer to the script object itself.
+ empirical_type<lldb::addr_t> script;
+};
+
+// This Element class represents the Element object in RS, defining the type
+// associated with an Allocation.
+struct RenderScriptRuntime::Element {
+ // Taken from rsDefines.h
+ enum DataKind {
+ RS_KIND_USER,
+ RS_KIND_PIXEL_L = 7,
+ RS_KIND_PIXEL_A,
+ RS_KIND_PIXEL_LA,
+ RS_KIND_PIXEL_RGB,
+ RS_KIND_PIXEL_RGBA,
+ RS_KIND_PIXEL_DEPTH,
+ RS_KIND_PIXEL_YUV,
+ RS_KIND_INVALID = 100
+ };
+
+ // Taken from rsDefines.h
+ enum DataType {
+ RS_TYPE_NONE = 0,
+ RS_TYPE_FLOAT_16,
+ RS_TYPE_FLOAT_32,
+ RS_TYPE_FLOAT_64,
+ RS_TYPE_SIGNED_8,
+ RS_TYPE_SIGNED_16,
+ RS_TYPE_SIGNED_32,
+ RS_TYPE_SIGNED_64,
+ RS_TYPE_UNSIGNED_8,
+ RS_TYPE_UNSIGNED_16,
+ RS_TYPE_UNSIGNED_32,
+ RS_TYPE_UNSIGNED_64,
+ RS_TYPE_BOOLEAN,
+
+ RS_TYPE_UNSIGNED_5_6_5,
+ RS_TYPE_UNSIGNED_5_5_5_1,
+ RS_TYPE_UNSIGNED_4_4_4_4,
+
+ RS_TYPE_MATRIX_4X4,
+ RS_TYPE_MATRIX_3X3,
+ RS_TYPE_MATRIX_2X2,
+
+ RS_TYPE_ELEMENT = 1000,
+ RS_TYPE_TYPE,
+ RS_TYPE_ALLOCATION,
+ RS_TYPE_SAMPLER,
+ RS_TYPE_SCRIPT,
+ RS_TYPE_MESH,
+ RS_TYPE_PROGRAM_FRAGMENT,
+ RS_TYPE_PROGRAM_VERTEX,
+ RS_TYPE_PROGRAM_RASTER,
+ RS_TYPE_PROGRAM_STORE,
+ RS_TYPE_FONT,
+
+ RS_TYPE_INVALID = 10000
+ };
+
+ std::vector<Element> children; // Child Element fields for structs
+ empirical_type<lldb::addr_t>
+ element_ptr; // Pointer to the RS Element of the Type
+ empirical_type<DataType>
+ type; // Type of each data pointer stored by the allocation
+ empirical_type<DataKind>
+ type_kind; // Defines pixel type if Allocation is created from an image
+ empirical_type<uint32_t>
+ type_vec_size; // Vector size of each data point, e.g '4' for uchar4
+ empirical_type<uint32_t> field_count; // Number of Subelements
+ empirical_type<uint32_t> datum_size; // Size of a single Element with padding
+ empirical_type<uint32_t> padding; // Number of padding bytes
+ empirical_type<uint32_t>
+ array_size; // Number of items in array, only needed for strucrs
+ ConstString type_name; // Name of type, only needed for structs
+
+ static const ConstString &
+ GetFallbackStructName(); // Print this as the type name of a struct Element
+ // If we can't resolve the actual struct name
+
+ bool ShouldRefresh() const {
+ const bool valid_ptr = element_ptr.isValid() && *element_ptr.get() != 0x0;
+ const bool valid_type =
+ type.isValid() && type_vec_size.isValid() && type_kind.isValid();
+ return !valid_ptr || !valid_type || !datum_size.isValid();
+ }
};
// This AllocationDetails class collects data associated with a single
// allocation instance.
-struct RenderScriptRuntime::AllocationDetails
-{
- struct Dimension
- {
- uint32_t dim_1;
- uint32_t dim_2;
- uint32_t dim_3;
- uint32_t cubeMap;
-
- Dimension()
- {
- dim_1 = 0;
- dim_2 = 0;
- dim_3 = 0;
- cubeMap = 0;
- }
- };
-
- // The FileHeader struct specifies the header we use for writing allocations to a binary file.
- // Our format begins with the ASCII characters "RSAD", identifying the file as an allocation dump.
- // Member variables dims and hdr_size are then written consecutively, immediately followed by an instance of
- // the ElementHeader struct. Because Elements can contain subelements, there may be more than one instance
- // of the ElementHeader struct. With this first instance being the root element, and the other instances being
- // the root's descendants. To identify which instances are an ElementHeader's children, each struct
- // is immediately followed by a sequence of consecutive offsets to the start of its child structs.
- // These offsets are 4 bytes in size, and the 0 offset signifies no more children.
- struct FileHeader
- {
- uint8_t ident[4]; // ASCII 'RSAD' identifying the file
- uint32_t dims[3]; // Dimensions
- uint16_t hdr_size; // Header size in bytes, including all element headers
- };
-
- struct ElementHeader
- {
- uint16_t type; // DataType enum
- uint32_t kind; // DataKind enum
- uint32_t element_size; // Size of a single element, including padding
- uint16_t vector_size; // Vector width
- uint32_t array_size; // Number of elements in array
- };
-
- // Monotonically increasing from 1
- static uint32_t ID;
-
- // Maps Allocation DataType enum and vector size to printable strings
- // using mapping from RenderScript numerical types summary documentation
- static const char *RsDataTypeToString[][4];
-
- // Maps Allocation DataKind enum to printable strings
- static const char *RsDataKindToString[];
-
- // Maps allocation types to format sizes for printing.
- static const uint32_t RSTypeToFormat[][3];
-
- // Give each allocation an ID as a way
- // for commands to reference it.
- const uint32_t id;
-
- RenderScriptRuntime::Element element; // Allocation Element type
- empirical_type<Dimension> dimension; // Dimensions of the Allocation
- empirical_type<lldb::addr_t> address; // Pointer to address of the RS Allocation
- empirical_type<lldb::addr_t> data_ptr; // Pointer to the data held by the Allocation
- empirical_type<lldb::addr_t> type_ptr; // Pointer to the RS Type of the Allocation
- empirical_type<lldb::addr_t> context; // Pointer to the RS Context of the Allocation
- empirical_type<uint32_t> size; // Size of the allocation
- empirical_type<uint32_t> stride; // Stride between rows of the allocation
-
- // Give each allocation an id, so we can reference it in user commands.
- AllocationDetails() : id(ID++) {}
-
- bool
- shouldRefresh() const
- {
- bool valid_ptrs = data_ptr.isValid() && *data_ptr.get() != 0x0;
- valid_ptrs = valid_ptrs && type_ptr.isValid() && *type_ptr.get() != 0x0;
- return !valid_ptrs || !dimension.isValid() || !size.isValid() || element.shouldRefresh();
- }
+struct RenderScriptRuntime::AllocationDetails {
+ struct Dimension {
+ uint32_t dim_1;
+ uint32_t dim_2;
+ uint32_t dim_3;
+ uint32_t cube_map;
+
+ Dimension() {
+ dim_1 = 0;
+ dim_2 = 0;
+ dim_3 = 0;
+ cube_map = 0;
+ }
+ };
+
+ // The FileHeader struct specifies the header we use for writing allocations
+ // to a binary file. Our format begins with the ASCII characters "RSAD",
+ // identifying the file as an allocation dump. Member variables dims and
+ // hdr_size are then written consecutively, immediately followed by an
+ // instance of the ElementHeader struct. Because Elements can contain
+ // subelements, there may be more than one instance of the ElementHeader
+ // struct. With this first instance being the root element, and the other
+ // instances being the root's descendants. To identify which instances are an
+ // ElementHeader's children, each struct is immediately followed by a sequence
+ // of consecutive offsets to the start of its child structs. These offsets are
+ // 4 bytes in size, and the 0 offset signifies no more children.
+ struct FileHeader {
+ uint8_t ident[4]; // ASCII 'RSAD' identifying the file
+ uint32_t dims[3]; // Dimensions
+ uint16_t hdr_size; // Header size in bytes, including all element headers
+ };
+
+ struct ElementHeader {
+ uint16_t type; // DataType enum
+ uint32_t kind; // DataKind enum
+ uint32_t element_size; // Size of a single element, including padding
+ uint16_t vector_size; // Vector width
+ uint32_t array_size; // Number of elements in array
+ };
+
+ // Monotonically increasing from 1
+ static uint32_t ID;
+
+ // Maps Allocation DataType enum and vector size to printable strings
+ // using mapping from RenderScript numerical types summary documentation
+ static const char *RsDataTypeToString[][4];
+
+ // Maps Allocation DataKind enum to printable strings
+ static const char *RsDataKindToString[];
+
+ // Maps allocation types to format sizes for printing.
+ static const uint32_t RSTypeToFormat[][3];
+
+ // Give each allocation an ID as a way
+ // for commands to reference it.
+ const uint32_t id;
+
+ // Allocation Element type
+ RenderScriptRuntime::Element element;
+ // Dimensions of the Allocation
+ empirical_type<Dimension> dimension;
+ // Pointer to address of the RS Allocation
+ empirical_type<lldb::addr_t> address;
+ // Pointer to the data held by the Allocation
+ empirical_type<lldb::addr_t> data_ptr;
+ // Pointer to the RS Type of the Allocation
+ empirical_type<lldb::addr_t> type_ptr;
+ // Pointer to the RS Context of the Allocation
+ empirical_type<lldb::addr_t> context;
+ // Size of the allocation
+ empirical_type<uint32_t> size;
+ // Stride between rows of the allocation
+ empirical_type<uint32_t> stride;
+
+ // Give each allocation an id, so we can reference it in user commands.
+ AllocationDetails() : id(ID++) {}
+
+ bool ShouldRefresh() const {
+ bool valid_ptrs = data_ptr.isValid() && *data_ptr.get() != 0x0;
+ valid_ptrs = valid_ptrs && type_ptr.isValid() && *type_ptr.get() != 0x0;
+ return !valid_ptrs || !dimension.isValid() || !size.isValid() ||
+ element.ShouldRefresh();
+ }
};
-const ConstString &
-RenderScriptRuntime::Element::GetFallbackStructName()
-{
- static const ConstString FallbackStructName("struct");
- return FallbackStructName;
+const ConstString &RenderScriptRuntime::Element::GetFallbackStructName() {
+ static const ConstString FallbackStructName("struct");
+ return FallbackStructName;
}
uint32_t RenderScriptRuntime::AllocationDetails::ID = 1;
const char *RenderScriptRuntime::AllocationDetails::RsDataKindToString[] = {
- "User",
- "Undefined", "Undefined", "Undefined", "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
+ "User", "Undefined", "Undefined", "Undefined",
+ "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
"L Pixel", "A Pixel", "LA Pixel", "RGB Pixel",
"RGBA Pixel", "Pixel Depth", "YUV Pixel"};
@@ -720,3627 +734,4274 @@ const char *RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] = {
// Deprecated
{"RS Mesh", "RS Mesh", "RS Mesh", "RS Mesh"},
- {"RS Program Fragment", "RS Program Fragment", "RS Program Fragment", "RS Program Fragment"},
- {"RS Program Vertex", "RS Program Vertex", "RS Program Vertex", "RS Program Vertex"},
- {"RS Program Raster", "RS Program Raster", "RS Program Raster", "RS Program Raster"},
- {"RS Program Store", "RS Program Store", "RS Program Store", "RS Program Store"},
+ {"RS Program Fragment", "RS Program Fragment", "RS Program Fragment",
+ "RS Program Fragment"},
+ {"RS Program Vertex", "RS Program Vertex", "RS Program Vertex",
+ "RS Program Vertex"},
+ {"RS Program Raster", "RS Program Raster", "RS Program Raster",
+ "RS Program Raster"},
+ {"RS Program Store", "RS Program Store", "RS Program Store",
+ "RS Program Store"},
{"RS Font", "RS Font", "RS Font", "RS Font"}};
// Used as an index into the RSTypeToFormat array elements
-enum TypeToFormatIndex
-{
- eFormatSingle = 0,
- eFormatVector,
- eElementSize
-};
+enum TypeToFormatIndex { eFormatSingle = 0, eFormatVector, eElementSize };
-// { format enum of single element, format enum of element vector, size of element}
+// { format enum of single element, format enum of element vector, size of
+// element}
const uint32_t RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] = {
- {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE
- {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16
- {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32
- {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64
- {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8
- {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16
- {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32
- {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64
- {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8
- {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16
- {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32
- {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64
- {eFormatBoolean, eFormatBoolean, 1}, // RS_TYPE_BOOL
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_6_5
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_5_5_1
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_4_4_4_4
- {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 16}, // RS_TYPE_MATRIX_4X4
- {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9}, // RS_TYPE_MATRIX_3X3
- {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // RS_TYPE_MATRIX_2X2
-};
+ // RS_TYPE_NONE
+ {eFormatHex, eFormatHex, 1},
+ // RS_TYPE_FLOAT_16
+ {eFormatFloat, eFormatVectorOfFloat16, 2},
+ // RS_TYPE_FLOAT_32
+ {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)},
+ // RS_TYPE_FLOAT_64
+ {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)},
+ // RS_TYPE_SIGNED_8
+ {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)},
+ // RS_TYPE_SIGNED_16
+ {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)},
+ // RS_TYPE_SIGNED_32
+ {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)},
+ // RS_TYPE_SIGNED_64
+ {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)},
+ // RS_TYPE_UNSIGNED_8
+ {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)},
+ // RS_TYPE_UNSIGNED_16
+ {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)},
+ // RS_TYPE_UNSIGNED_32
+ {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)},
+ // RS_TYPE_UNSIGNED_64
+ {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)},
+ // RS_TYPE_BOOL
+ {eFormatBoolean, eFormatBoolean, 1},
+ // RS_TYPE_UNSIGNED_5_6_5
+ {eFormatHex, eFormatHex, sizeof(uint16_t)},
+ // RS_TYPE_UNSIGNED_5_5_5_1
+ {eFormatHex, eFormatHex, sizeof(uint16_t)},
+ // RS_TYPE_UNSIGNED_4_4_4_4
+ {eFormatHex, eFormatHex, sizeof(uint16_t)},
+ // RS_TYPE_MATRIX_4X4
+ {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 16},
+ // RS_TYPE_MATRIX_3X3
+ {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9},
+ // RS_TYPE_MATRIX_2X2
+ {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4}};
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
LanguageRuntime *
-RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
-{
+RenderScriptRuntime::CreateInstance(Process *process,
+ lldb::LanguageType language) {
- if (language == eLanguageTypeExtRenderScript)
- return new RenderScriptRuntime(process);
- else
- return nullptr;
+ if (language == eLanguageTypeExtRenderScript)
+ return new RenderScriptRuntime(process);
+ else
+ return nullptr;
}
-// Callback with a module to search for matching symbols.
-// We first check that the module contains RS kernels.
-// Then look for a symbol which matches our kernel name.
-// The breakpoint address is finally set using the address of this symbol.
+// Callback with a module to search for matching symbols. We first check that
+// the module contains RS kernels. Then look for a symbol which matches our
+// kernel name. The breakpoint address is finally set using the address of this
+// symbol.
Searcher::CallbackReturn
-RSBreakpointResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *, bool)
-{
- ModuleSP module = context.module_sp;
+RSBreakpointResolver::SearchCallback(SearchFilter &filter,
+ SymbolContext &context, Address *, bool) {
+ ModuleSP module = context.module_sp;
- if (!module)
- return Searcher::eCallbackReturnContinue;
+ if (!module || !IsRenderScriptScriptModule(module))
+ return Searcher::eCallbackReturnContinue;
- // Is this a module containing renderscript kernels?
- if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
- return Searcher::eCallbackReturnContinue;
+ // Attempt to set a breakpoint on the kernel name symbol within the module
+ // library. If it's not found, it's likely debug info is unavailable - try to
+ // set a breakpoint on <name>.expand.
+ const Symbol *kernel_sym =
+ module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
+ if (!kernel_sym) {
+ std::string kernel_name_expanded(m_kernel_name.AsCString());
+ kernel_name_expanded.append(".expand");
+ kernel_sym = module->FindFirstSymbolWithNameAndType(
+ ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
+ }
+
+ if (kernel_sym) {
+ Address bp_addr = kernel_sym->GetAddress();
+ if (filter.AddressPasses(bp_addr))
+ m_breakpoint->AddLocation(bp_addr);
+ }
+
+ return Searcher::eCallbackReturnContinue;
+}
- // Attempt to set a breakpoint on the kernel name symbol within the module library.
- // If it's not found, it's likely debug info is unavailable - try to set a
- // breakpoint on <name>.expand.
+Searcher::CallbackReturn
+RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
+ lldb_private::SymbolContext &context,
+ Address *, bool) {
+ // We need to have access to the list of reductions currently parsed, as
+ // reduce names don't actually exist as
+ // symbols in a module. They are only identifiable by parsing the .rs.info
+ // packet, or finding the expand symbol. We
+ // therefore need access to the list of parsed rs modules to properly resolve
+ // reduction names.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ ModuleSP module = context.module_sp;
+
+ if (!module || !IsRenderScriptScriptModule(module))
+ return Searcher::eCallbackReturnContinue;
- const Symbol *kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
- if (!kernel_sym)
- {
- std::string kernel_name_expanded(m_kernel_name.AsCString());
- kernel_name_expanded.append(".expand");
- kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
- }
+ if (!m_rsmodules)
+ return Searcher::eCallbackReturnContinue;
- if (kernel_sym)
- {
- Address bp_addr = kernel_sym->GetAddress();
- if (filter.AddressPasses(bp_addr))
- m_breakpoint->AddLocation(bp_addr);
+ for (const auto &module_desc : *m_rsmodules) {
+ if (module_desc->m_module != module)
+ continue;
+
+ for (const auto &reduction : module_desc->m_reductions) {
+ if (reduction.m_reduce_name != m_reduce_name)
+ continue;
+
+ std::array<std::pair<ConstString, int>, 5> funcs{
+ {{reduction.m_init_name, eKernelTypeInit},
+ {reduction.m_accum_name, eKernelTypeAccum},
+ {reduction.m_comb_name, eKernelTypeComb},
+ {reduction.m_outc_name, eKernelTypeOutC},
+ {reduction.m_halter_name, eKernelTypeHalter}}};
+
+ for (const auto &kernel : funcs) {
+ // Skip constituent functions that don't match our spec
+ if (!(m_kernel_types & kernel.second))
+ continue;
+
+ const auto kernel_name = kernel.first;
+ const auto symbol = module->FindFirstSymbolWithNameAndType(
+ kernel_name, eSymbolTypeCode);
+ if (!symbol)
+ continue;
+
+ auto address = symbol->GetAddress();
+ if (filter.AddressPasses(address)) {
+ bool new_bp;
+ if (!SkipPrologue(module, address)) {
+ if (log)
+ log->Printf("%s: Error trying to skip prologue", __FUNCTION__);
+ }
+ m_breakpoint->AddLocation(address, &new_bp);
+ if (log)
+ log->Printf("%s: %s reduction breakpoint on %s in %s", __FUNCTION__,
+ new_bp ? "new" : "existing", kernel_name.GetCString(),
+ address.GetModule()->GetFileSpec().GetCString());
+ }
+ }
}
+ }
+ return eCallbackReturnContinue;
+}
+
+Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
+ SearchFilter &filter, SymbolContext &context, Address *addr,
+ bool containing) {
+
+ if (!m_breakpoint)
+ return eCallbackReturnContinue;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ ModuleSP &module = context.module_sp;
+ if (!module || !IsRenderScriptScriptModule(module))
return Searcher::eCallbackReturnContinue;
+
+ std::vector<std::string> names;
+ m_breakpoint->GetNames(names);
+ if (names.empty())
+ return eCallbackReturnContinue;
+
+ for (auto &name : names) {
+ const RSScriptGroupDescriptorSP sg = FindScriptGroup(ConstString(name));
+ if (!sg) {
+ if (log)
+ log->Printf("%s: could not find script group for %s", __FUNCTION__,
+ name.c_str());
+ continue;
+ }
+
+ if (log)
+ log->Printf("%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
+
+ for (const RSScriptGroupDescriptor::Kernel &k : sg->m_kernels) {
+ if (log) {
+ log->Printf("%s: Adding breakpoint for %s", __FUNCTION__,
+ k.m_name.AsCString());
+ log->Printf("%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr);
+ }
+
+ const lldb_private::Symbol *sym =
+ module->FindFirstSymbolWithNameAndType(k.m_name, eSymbolTypeCode);
+ if (!sym) {
+ if (log)
+ log->Printf("%s: Unable to find symbol for %s", __FUNCTION__,
+ k.m_name.AsCString());
+ continue;
+ }
+
+ if (log) {
+ log->Printf("%s: Found symbol name is %s", __FUNCTION__,
+ sym->GetName().AsCString());
+ }
+
+ auto address = sym->GetAddress();
+ if (!SkipPrologue(module, address)) {
+ if (log)
+ log->Printf("%s: Error trying to skip prologue", __FUNCTION__);
+ }
+
+ bool new_bp;
+ m_breakpoint->AddLocation(address, &new_bp);
+
+ if (log)
+ log->Printf("%s: Placed %sbreakpoint on %s", __FUNCTION__,
+ new_bp ? "new " : "", k.m_name.AsCString());
+
+ // exit after placing the first breakpoint if we do not intend to stop
+ // on all kernels making up this script group
+ if (!m_stop_on_all)
+ break;
+ }
+ }
+
+ return eCallbackReturnContinue;
}
-void
-RenderScriptRuntime::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance,
- GetCommandObject);
+void RenderScriptRuntime::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "RenderScript language support", CreateInstance,
+ GetCommandObject);
}
-void
-RenderScriptRuntime::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
+void RenderScriptRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-RenderScriptRuntime::GetPluginNameStatic()
-{
- static ConstString g_name("renderscript");
- return g_name;
+lldb_private::ConstString RenderScriptRuntime::GetPluginNameStatic() {
+ static ConstString plugin_name("renderscript");
+ return plugin_name;
}
RenderScriptRuntime::ModuleKind
-RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
-{
- if (module_sp)
- {
- // Is this a module containing renderscript kernels?
- const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
- if (info_sym)
- {
- return eModuleKindKernelObj;
- }
+RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) {
+ if (module_sp) {
+ if (IsRenderScriptScriptModule(module_sp))
+ return eModuleKindKernelObj;
- // Is this the main RS runtime library
- const ConstString rs_lib("libRS.so");
- if (module_sp->GetFileSpec().GetFilename() == rs_lib)
- {
- return eModuleKindLibRS;
- }
+ // Is this the main RS runtime library
+ const ConstString rs_lib("libRS.so");
+ if (module_sp->GetFileSpec().GetFilename() == rs_lib) {
+ return eModuleKindLibRS;
+ }
- const ConstString rs_driverlib("libRSDriver.so");
- if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
- {
- return eModuleKindDriver;
- }
+ const ConstString rs_driverlib("libRSDriver.so");
+ if (module_sp->GetFileSpec().GetFilename() == rs_driverlib) {
+ return eModuleKindDriver;
+ }
- const ConstString rs_cpureflib("libRSCpuRef.so");
- if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
- {
- return eModuleKindImpl;
- }
+ const ConstString rs_cpureflib("libRSCpuRef.so");
+ if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib) {
+ return eModuleKindImpl;
}
- return eModuleKindIgnored;
+ }
+ return eModuleKindIgnored;
}
-bool
-RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
-{
- return GetModuleKind(module_sp) != eModuleKindIgnored;
+bool RenderScriptRuntime::IsRenderScriptModule(
+ const lldb::ModuleSP &module_sp) {
+ return GetModuleKind(module_sp) != eModuleKindIgnored;
}
-void
-RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list)
-{
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+void RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list) {
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
- size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; i++)
- {
- auto mod = module_list.GetModuleAtIndex(i);
- if (IsRenderScriptModule(mod))
- {
- LoadModule(mod);
- }
+ size_t num_modules = module_list.GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ auto mod = module_list.GetModuleAtIndex(i);
+ if (IsRenderScriptModule(mod)) {
+ LoadModule(mod);
}
+ }
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-RenderScriptRuntime::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString RenderScriptRuntime::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-RenderScriptRuntime::GetPluginVersion()
-{
- return 1;
-}
+uint32_t RenderScriptRuntime::GetPluginVersion() { return 1; }
-bool
-RenderScriptRuntime::IsVTableName(const char *name)
-{
- return false;
-}
+bool RenderScriptRuntime::IsVTableName(const char *name) { return false; }
-bool
-RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type)
-{
- return false;
+bool RenderScriptRuntime::GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) {
+ return false;
}
TypeAndOrName
-RenderScriptRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value)
-{
- return type_and_or_name;
+RenderScriptRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) {
+ return type_and_or_name;
}
-bool
-RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
-{
- return false;
+bool RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
+ return false;
}
lldb::BreakpointResolverSP
-RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
-{
- BreakpointResolverSP resolver_sp;
- return resolver_sp;
+RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bp, bool catch_bp,
+ bool throw_bp) {
+ BreakpointResolverSP resolver_sp;
+ return resolver_sp;
}
-const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = {
- // rsdScript
- {
- "rsdScriptInit",
- "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj",
- "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj",
- 0,
- RenderScriptRuntime::eModuleKindDriver,
- &lldb_private::RenderScriptRuntime::CaptureScriptInit
- },
- {
- "rsdScriptInvokeForEachMulti",
- "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall",
- "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall",
- 0,
- RenderScriptRuntime::eModuleKindDriver,
- &lldb_private::RenderScriptRuntime::CaptureScriptInvokeForEachMulti
- },
- {
- "rsdScriptSetGlobalVar",
- "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj",
- "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm",
- 0,
- RenderScriptRuntime::eModuleKindDriver,
- &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar
- },
-
- // rsdAllocation
- {
- "rsdAllocationInit",
- "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb",
- "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb",
- 0,
- RenderScriptRuntime::eModuleKindDriver,
- &lldb_private::RenderScriptRuntime::CaptureAllocationInit
- },
- {
- "rsdAllocationRead2D",
- "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj",
- "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm",
- 0,
- RenderScriptRuntime::eModuleKindDriver,
- nullptr
- },
- {
- "rsdAllocationDestroy",
- "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE",
- "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE",
- 0,
- RenderScriptRuntime::eModuleKindDriver,
- &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy
- },
-};
-
-const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns) / sizeof(s_runtimeHookDefns[0]);
-
-bool
-RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
-{
- RuntimeHook *hook_info = (RuntimeHook *)baton;
- ExecutionContext context(ctx->exe_ctx_ref);
-
- RenderScriptRuntime *lang_rt =
- (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
-
- lang_rt->HookCallback(hook_info, context);
-
- return false;
+const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
+ {
+ // rsdScript
+ {"rsdScriptInit", "_Z13rsdScriptInitPKN7android12renderscript7ContextEP"
+ "NS0_7ScriptCEPKcS7_PKhjj",
+ "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_"
+ "7ScriptCEPKcS7_PKhmj",
+ 0, RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureScriptInit},
+ {"rsdScriptInvokeForEachMulti",
+ "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0"
+ "_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall",
+ "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0"
+ "_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall",
+ 0, RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureScriptInvokeForEachMulti},
+ {"rsdScriptSetGlobalVar", "_Z21rsdScriptSetGlobalVarPKN7android12render"
+ "script7ContextEPKNS0_6ScriptEjPvj",
+ "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_"
+ "6ScriptEjPvm",
+ 0, RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar},
+
+ // rsdAllocation
+ {"rsdAllocationInit", "_Z17rsdAllocationInitPKN7android12renderscript7C"
+ "ontextEPNS0_10AllocationEb",
+ "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_"
+ "10AllocationEb",
+ 0, RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureAllocationInit},
+ {"rsdAllocationRead2D",
+ "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_"
+ "10AllocationEjjj23RsAllocationCubemapFacejjPvjj",
+ "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_"
+ "10AllocationEjjj23RsAllocationCubemapFacejjPvmm",
+ 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
+ {"rsdAllocationDestroy", "_Z20rsdAllocationDestroyPKN7android12rendersc"
+ "ript7ContextEPNS0_10AllocationE",
+ "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_"
+ "10AllocationE",
+ 0, RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy},
+
+ // renderscript script groups
+ {"rsdDebugHintScriptGroup2", "_ZN7android12renderscript21debugHintScrip"
+ "tGroup2EPKcjPKPFvPK24RsExpandKernelDriver"
+ "InfojjjEj",
+ "_ZN7android12renderscript21debugHintScriptGroup2EPKcjPKPFvPK24RsExpan"
+ "dKernelDriverInfojjjEj",
+ 0, RenderScriptRuntime::eModuleKindImpl,
+ &lldb_private::RenderScriptRuntime::CaptureDebugHintScriptGroup2}};
+
+const size_t RenderScriptRuntime::s_runtimeHookCount =
+ sizeof(s_runtimeHookDefns) / sizeof(s_runtimeHookDefns[0]);
+
+bool RenderScriptRuntime::HookCallback(void *baton,
+ StoppointCallbackContext *ctx,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ RuntimeHook *hook = (RuntimeHook *)baton;
+ ExecutionContext exe_ctx(ctx->exe_ctx_ref);
+
+ RenderScriptRuntime *lang_rt =
+ (RenderScriptRuntime *)exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript);
+
+ lang_rt->HookCallback(hook, exe_ctx);
+
+ return false;
}
-void
-RenderScriptRuntime::HookCallback(RuntimeHook *hook_info, ExecutionContext &context)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+void RenderScriptRuntime::HookCallback(RuntimeHook *hook,
+ ExecutionContext &exe_ctx) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- log->Printf("%s - '%s'", __FUNCTION__, hook_info->defn->name);
+ if (log)
+ log->Printf("%s - '%s'", __FUNCTION__, hook->defn->name);
- if (hook_info->defn->grabber)
- {
- (this->*(hook_info->defn->grabber))(hook_info, context);
- }
+ if (hook->defn->grabber) {
+ (this->*(hook->defn->grabber))(hook, exe_ctx);
+ }
}
-void
-RenderScriptRuntime::CaptureScriptInvokeForEachMulti(RuntimeHook* hook_info,
- ExecutionContext& context)
-{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- enum
- {
- eRsContext = 0,
- eRsScript,
- eRsSlot,
- eRsAIns,
- eRsInLen,
- eRsAOut,
- eRsUsr,
- eRsUsrLen,
- eRsSc,
- };
-
- std::array<ArgItem, 9> args{{
- ArgItem{ArgItem::ePointer, 0}, // const Context *rsc
- ArgItem{ArgItem::ePointer, 0}, // Script *s
- ArgItem{ArgItem::eInt32, 0}, // uint32_t slot
- ArgItem{ArgItem::ePointer, 0}, // const Allocation **aIns
- ArgItem{ArgItem::eInt32, 0}, // size_t inLen
- ArgItem{ArgItem::ePointer, 0}, // Allocation *aout
- ArgItem{ArgItem::ePointer, 0}, // const void *usr
- ArgItem{ArgItem::eInt32, 0}, // size_t usrLen
- ArgItem{ArgItem::ePointer, 0}, // const RsScriptCall *sc
- }};
-
- bool success = GetArgs(context, &args[0], args.size());
- if (!success)
- {
- if (log)
- log->Printf("%s - Error while reading the function parameters", __FUNCTION__);
- return;
- }
-
- const uint32_t target_ptr_size = m_process->GetAddressByteSize();
- Error error;
- std::vector<uint64_t> allocs;
-
- // traverse allocation list
- for (uint64_t i = 0; i < uint64_t(args[eRsInLen]); ++i)
- {
- // calculate offest to allocation pointer
- const addr_t addr = addr_t(args[eRsAIns]) + i * target_ptr_size;
-
- // Note: due to little endian layout, reading 32bits or 64bits into res64 will
- // give the correct results.
-
- uint64_t res64 = 0;
- size_t read = m_process->ReadMemory(addr, &res64, target_ptr_size, error);
- if (read != target_ptr_size || !error.Success())
- {
- if (log)
- log->Printf("%s - Error while reading allocation list argument %" PRIu64, __FUNCTION__, i);
- }
- else
- {
- allocs.push_back(res64);
- }
- }
-
- // if there is an output allocation track it
- if (uint64_t aOut = uint64_t(args[eRsAOut]))
- {
- allocs.push_back(aOut);
+void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
+ RuntimeHook *hook_info, ExecutionContext &context) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ enum {
+ eGroupName = 0,
+ eGroupNameSize,
+ eKernel,
+ eKernelCount,
+ };
+
+ std::array<ArgItem, 4> args{{
+ {ArgItem::ePointer, 0}, // const char *groupName
+ {ArgItem::eInt32, 0}, // const uint32_t groupNameSize
+ {ArgItem::ePointer, 0}, // const ExpandFuncTy *kernel
+ {ArgItem::eInt32, 0}, // const uint32_t kernelCount
+ }};
+
+ if (!GetArgs(context, args.data(), args.size())) {
+ if (log)
+ log->Printf("%s - Error while reading the function parameters",
+ __FUNCTION__);
+ return;
+ } else if (log) {
+ log->Printf("%s - groupName : 0x%" PRIx64, __FUNCTION__,
+ addr_t(args[eGroupName]));
+ log->Printf("%s - groupNameSize: %" PRIu64, __FUNCTION__,
+ uint64_t(args[eGroupNameSize]));
+ log->Printf("%s - kernel : 0x%" PRIx64, __FUNCTION__,
+ addr_t(args[eKernel]));
+ log->Printf("%s - kernelCount : %" PRIu64, __FUNCTION__,
+ uint64_t(args[eKernelCount]));
+ }
+
+ // parse script group name
+ ConstString group_name;
+ {
+ Error err;
+ const uint64_t len = uint64_t(args[eGroupNameSize]);
+ std::unique_ptr<char[]> buffer(new char[uint32_t(len + 1)]);
+ m_process->ReadMemory(addr_t(args[eGroupName]), buffer.get(), len, err);
+ buffer.get()[len] = '\0';
+ if (!err.Success()) {
+ if (log)
+ log->Printf("Error reading scriptgroup name from target");
+ return;
+ } else {
+ if (log)
+ log->Printf("Extracted scriptgroup name %s", buffer.get());
+ }
+ // write back the script group name
+ group_name.SetCString(buffer.get());
+ }
+
+ // create or access existing script group
+ RSScriptGroupDescriptorSP group;
+ {
+ // search for existing script group
+ for (auto sg : m_scriptGroups) {
+ if (sg->m_name == group_name) {
+ group = sg;
+ break;
+ }
+ }
+ if (!group) {
+ group.reset(new RSScriptGroupDescriptor);
+ group->m_name = group_name;
+ m_scriptGroups.push_back(group);
+ } else {
+ // already have this script group
+ if (log)
+ log->Printf("Attempt to add duplicate script group %s",
+ group_name.AsCString());
+ return;
+ }
+ }
+ assert(group);
+
+ const uint32_t target_ptr_size = m_process->GetAddressByteSize();
+ std::vector<addr_t> kernels;
+ // parse kernel addresses in script group
+ for (uint64_t i = 0; i < uint64_t(args[eKernelCount]); ++i) {
+ RSScriptGroupDescriptor::Kernel kernel;
+ // extract script group kernel addresses from the target
+ const addr_t ptr_addr = addr_t(args[eKernel]) + i * target_ptr_size;
+ uint64_t kernel_addr = 0;
+ Error err;
+ size_t read =
+ m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err);
+ if (!err.Success() || read != target_ptr_size) {
+ if (log)
+ log->Printf("Error parsing kernel address %" PRIu64 " in script group",
+ i);
+ return;
}
-
- // for all allocations we have found
- for (const uint64_t alloc_addr : allocs)
- {
- AllocationDetails* alloc = LookUpAllocation(alloc_addr, true);
- if (alloc)
- {
- // save the allocation address
- if (alloc->address.isValid())
- {
- // check the allocation address we already have matches
- assert(*alloc->address.get() == alloc_addr);
- }
- else
- {
- alloc->address = alloc_addr;
- }
-
- // save the context
- if (log)
- {
- if (alloc->context.isValid() && *alloc->context.get() != addr_t(args[eRsContext]))
- log->Printf("%s - Allocation used by multiple contexts", __FUNCTION__);
- }
- alloc->context = addr_t(args[eRsContext]);
+ if (log)
+ log->Printf("Extracted scriptgroup kernel address - 0x%" PRIx64,
+ kernel_addr);
+ kernel.m_addr = kernel_addr;
+
+ // try to resolve the associated kernel name
+ if (!ResolveKernelName(kernel.m_addr, kernel.m_name)) {
+ if (log)
+ log->Printf("Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i,
+ kernel_addr);
+ return;
+ }
+
+ // try to find the non '.expand' function
+ {
+ const llvm::StringRef expand(".expand");
+ const llvm::StringRef name_ref = kernel.m_name.GetStringRef();
+ if (name_ref.endswith(expand)) {
+ const ConstString base_kernel(name_ref.drop_back(expand.size()));
+ // verify this function is a valid kernel
+ if (IsKnownKernel(base_kernel)) {
+ kernel.m_name = base_kernel;
+ if (log)
+ log->Printf("%s - found non expand version '%s'", __FUNCTION__,
+ base_kernel.GetCString());
}
+ }
}
+ // add to a list of script group kernels we know about
+ group->m_kernels.push_back(kernel);
+ }
- // make sure we track this script object
- if (lldb_private::RenderScriptRuntime::ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true))
- {
- if (log)
- {
- if (script->context.isValid() && *script->context.get() != addr_t(args[eRsContext]))
- log->Printf("%s - Script used by multiple contexts", __FUNCTION__);
+ // Resolve any pending scriptgroup breakpoints
+ {
+ Target &target = m_process->GetTarget();
+ const BreakpointList &list = target.GetBreakpointList();
+ const size_t num_breakpoints = list.GetSize();
+ if (log)
+ log->Printf("Resolving %zu breakpoints", num_breakpoints);
+ for (size_t i = 0; i < num_breakpoints; ++i) {
+ const BreakpointSP bp = list.GetBreakpointAtIndex(i);
+ if (bp) {
+ if (bp->MatchesName(group_name.AsCString())) {
+ if (log)
+ log->Printf("Found breakpoint with name %s",
+ group_name.AsCString());
+ bp->ResolveBreakpoint();
}
- script->context = addr_t(args[eRsContext]);
+ }
}
+ }
}
-void
-RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- enum
- {
- eRsContext,
- eRsScript,
- eRsId,
- eRsData,
- eRsLength,
- };
-
- std::array<ArgItem, 5> args{{
- ArgItem{ArgItem::ePointer, 0}, // eRsContext
- ArgItem{ArgItem::ePointer, 0}, // eRsScript
- ArgItem{ArgItem::eInt32, 0}, // eRsId
- ArgItem{ArgItem::ePointer, 0}, // eRsData
- ArgItem{ArgItem::eInt32, 0}, // eRsLength
- }};
-
- bool success = GetArgs(context, &args[0], args.size());
- if (!success)
- {
- if (log)
- log->Printf("%s - error reading the function parameters.", __FUNCTION__);
- return;
- }
-
+void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
+ RuntimeHook *hook, ExecutionContext &exe_ctx) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ enum {
+ eRsContext = 0,
+ eRsScript,
+ eRsSlot,
+ eRsAIns,
+ eRsInLen,
+ eRsAOut,
+ eRsUsr,
+ eRsUsrLen,
+ eRsSc,
+ };
+
+ std::array<ArgItem, 9> args{{
+ ArgItem{ArgItem::ePointer, 0}, // const Context *rsc
+ ArgItem{ArgItem::ePointer, 0}, // Script *s
+ ArgItem{ArgItem::eInt32, 0}, // uint32_t slot
+ ArgItem{ArgItem::ePointer, 0}, // const Allocation **aIns
+ ArgItem{ArgItem::eInt32, 0}, // size_t inLen
+ ArgItem{ArgItem::ePointer, 0}, // Allocation *aout
+ ArgItem{ArgItem::ePointer, 0}, // const void *usr
+ ArgItem{ArgItem::eInt32, 0}, // size_t usrLen
+ ArgItem{ArgItem::ePointer, 0}, // const RsScriptCall *sc
+ }};
+
+ bool success = GetArgs(exe_ctx, &args[0], args.size());
+ if (!success) {
if (log)
- {
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.", __FUNCTION__,
- uint64_t(args[eRsContext]), uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
- uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
-
- addr_t script_addr = addr_t(args[eRsScript]);
- if (m_scriptMappings.find(script_addr) != m_scriptMappings.end())
- {
- auto rsm = m_scriptMappings[script_addr];
- if (uint64_t(args[eRsId]) < rsm->m_globals.size())
- {
- auto rsg = rsm->m_globals[uint64_t(args[eRsId])];
- log->Printf("%s - Setting of '%s' within '%s' inferred", __FUNCTION__, rsg.m_name.AsCString(),
- rsm->m_module->GetFileSpec().GetFilename().AsCString());
- }
- }
- }
+ log->Printf("%s - Error while reading the function parameters",
+ __FUNCTION__);
+ return;
+ }
+
+ const uint32_t target_ptr_size = m_process->GetAddressByteSize();
+ Error err;
+ std::vector<uint64_t> allocs;
+
+ // traverse allocation list
+ for (uint64_t i = 0; i < uint64_t(args[eRsInLen]); ++i) {
+ // calculate offest to allocation pointer
+ const addr_t addr = addr_t(args[eRsAIns]) + i * target_ptr_size;
+
+ // Note: due to little endian layout, reading 32bits or 64bits into res
+ // will give the correct results.
+ uint64_t result = 0;
+ size_t read = m_process->ReadMemory(addr, &result, target_ptr_size, err);
+ if (read != target_ptr_size || !err.Success()) {
+ if (log)
+ log->Printf(
+ "%s - Error while reading allocation list argument %" PRIu64,
+ __FUNCTION__, i);
+ } else {
+ allocs.push_back(result);
+ }
+ }
+
+ // if there is an output allocation track it
+ if (uint64_t alloc_out = uint64_t(args[eRsAOut])) {
+ allocs.push_back(alloc_out);
+ }
+
+ // for all allocations we have found
+ for (const uint64_t alloc_addr : allocs) {
+ AllocationDetails *alloc = LookUpAllocation(alloc_addr);
+ if (!alloc)
+ alloc = CreateAllocation(alloc_addr);
+
+ if (alloc) {
+ // save the allocation address
+ if (alloc->address.isValid()) {
+ // check the allocation address we already have matches
+ assert(*alloc->address.get() == alloc_addr);
+ } else {
+ alloc->address = alloc_addr;
+ }
+
+ // save the context
+ if (log) {
+ if (alloc->context.isValid() &&
+ *alloc->context.get() != addr_t(args[eRsContext]))
+ log->Printf("%s - Allocation used by multiple contexts",
+ __FUNCTION__);
+ }
+ alloc->context = addr_t(args[eRsContext]);
+ }
+ }
+
+ // make sure we track this script object
+ if (lldb_private::RenderScriptRuntime::ScriptDetails *script =
+ LookUpScript(addr_t(args[eRsScript]), true)) {
+ if (log) {
+ if (script->context.isValid() &&
+ *script->context.get() != addr_t(args[eRsContext]))
+ log->Printf("%s - Script used by multiple contexts", __FUNCTION__);
+ }
+ script->context = addr_t(args[eRsContext]);
+ }
}
-void
-RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- enum
- {
- eRsContext,
- eRsAlloc,
- eRsForceZero
- };
-
- std::array<ArgItem, 3> args{{
- ArgItem{ArgItem::ePointer, 0}, // eRsContext
- ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
- ArgItem{ArgItem::eBool, 0}, // eRsForceZero
- }};
-
- bool success = GetArgs(context, &args[0], args.size());
- if (!success) // error case
- {
- if (log)
- log->Printf("%s - error while reading the function parameters", __FUNCTION__);
- return; // abort
- }
-
+void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook,
+ ExecutionContext &context) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ enum {
+ eRsContext,
+ eRsScript,
+ eRsId,
+ eRsData,
+ eRsLength,
+ };
+
+ std::array<ArgItem, 5> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsScript
+ ArgItem{ArgItem::eInt32, 0}, // eRsId
+ ArgItem{ArgItem::ePointer, 0}, // eRsData
+ ArgItem{ArgItem::eInt32, 0}, // eRsLength
+ }};
+
+ bool success = GetArgs(context, &args[0], args.size());
+ if (!success) {
if (log)
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsAlloc]), uint64_t(args[eRsForceZero]));
-
- AllocationDetails *alloc = LookUpAllocation(uint64_t(args[eRsAlloc]), true);
- if (alloc)
- alloc->context = uint64_t(args[eRsContext]);
+ log->Printf("%s - error reading the function parameters.", __FUNCTION__);
+ return;
+ }
+
+ if (log) {
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64
+ ":%" PRIu64 "bytes.",
+ __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
+ uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
+
+ addr_t script_addr = addr_t(args[eRsScript]);
+ if (m_scriptMappings.find(script_addr) != m_scriptMappings.end()) {
+ auto rsm = m_scriptMappings[script_addr];
+ if (uint64_t(args[eRsId]) < rsm->m_globals.size()) {
+ auto rsg = rsm->m_globals[uint64_t(args[eRsId])];
+ log->Printf("%s - Setting of '%s' within '%s' inferred", __FUNCTION__,
+ rsg.m_name.AsCString(),
+ rsm->m_module->GetFileSpec().GetFilename().AsCString());
+ }
+ }
+ }
}
-void
-RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook_info, ExecutionContext &context)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook,
+ ExecutionContext &exe_ctx) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- enum
- {
- eRsContext,
- eRsAlloc,
- };
+ enum { eRsContext, eRsAlloc, eRsForceZero };
- std::array<ArgItem, 2> args{{
- ArgItem{ArgItem::ePointer, 0}, // eRsContext
- ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
- }};
-
- bool success = GetArgs(context, &args[0], args.size());
- if (!success)
- {
- if (log)
- log->Printf("%s - error while reading the function parameters.", __FUNCTION__);
- return;
- }
+ std::array<ArgItem, 3> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
+ ArgItem{ArgItem::eBool, 0}, // eRsForceZero
+ }};
+ bool success = GetArgs(exe_ctx, &args[0], args.size());
+ if (!success) {
if (log)
- log->Printf("%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsAlloc]));
-
- for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter)
- {
- auto &allocation_ap = *iter; // get the unique pointer
- if (allocation_ap->address.isValid() && *allocation_ap->address.get() == addr_t(args[eRsAlloc]))
- {
- m_allocations.erase(iter);
- if (log)
- log->Printf("%s - deleted allocation entry.", __FUNCTION__);
- return;
- }
- }
-
- if (log)
- log->Printf("%s - couldn't find destroyed allocation.", __FUNCTION__);
+ log->Printf("%s - error while reading the function parameters",
+ __FUNCTION__);
+ return;
+ }
+
+ if (log)
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
+ __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsAlloc]), uint64_t(args[eRsForceZero]));
+
+ AllocationDetails *alloc = CreateAllocation(uint64_t(args[eRsAlloc]));
+ if (alloc)
+ alloc->context = uint64_t(args[eRsContext]);
}
-void
-RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook,
+ ExecutionContext &exe_ctx) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- Error error;
- Process *process = context.GetProcessPtr();
+ enum {
+ eRsContext,
+ eRsAlloc,
+ };
- enum
- {
- eRsContext,
- eRsScript,
- eRsResNamePtr,
- eRsCachedDirPtr
- };
-
- std::array<ArgItem, 4> args{{ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0},
- ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
- bool success = GetArgs(context, &args[0], args.size());
- if (!success)
- {
- if (log)
- log->Printf("%s - error while reading the function parameters.", __FUNCTION__);
- return;
- }
+ std::array<ArgItem, 2> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
+ }};
- std::string resname;
- process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), resname, error);
- if (error.Fail())
- {
- if (log)
- log->Printf("%s - error reading resname: %s.", __FUNCTION__, error.AsCString());
- }
+ bool success = GetArgs(exe_ctx, &args[0], args.size());
+ if (!success) {
+ if (log)
+ log->Printf("%s - error while reading the function parameters.",
+ __FUNCTION__);
+ return;
+ }
+
+ if (log)
+ log->Printf("%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__,
+ uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]));
+
+ for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter) {
+ auto &allocation_ap = *iter; // get the unique pointer
+ if (allocation_ap->address.isValid() &&
+ *allocation_ap->address.get() == addr_t(args[eRsAlloc])) {
+ m_allocations.erase(iter);
+ if (log)
+ log->Printf("%s - deleted allocation entry.", __FUNCTION__);
+ return;
+ }
+ }
+
+ if (log)
+ log->Printf("%s - couldn't find destroyed allocation.", __FUNCTION__);
+}
- std::string cachedir;
- process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cachedir, error);
- if (error.Fail())
- {
- if (log)
- log->Printf("%s - error reading cachedir: %s.", __FUNCTION__, error.AsCString());
- }
+void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
+ ExecutionContext &exe_ctx) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsScript]), resname.c_str(), cachedir.c_str());
+ Error err;
+ Process *process = exe_ctx.GetProcessPtr();
- if (resname.size() > 0)
- {
- StreamString strm;
- strm.Printf("librs.%s.so", resname.c_str());
-
- ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true);
- if (script)
- {
- script->type = ScriptDetails::eScriptC;
- script->cacheDir = cachedir;
- script->resName = resname;
- script->scriptDyLib = strm.GetData();
- script->context = addr_t(args[eRsContext]);
- }
+ enum { eRsContext, eRsScript, eRsResNamePtr, eRsCachedDirPtr };
- if (log)
- log->Printf("%s - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".", __FUNCTION__,
- strm.GetData(), uint64_t(args[eRsContext]), uint64_t(args[eRsScript]));
- }
- else if (log)
- {
- log->Printf("%s - resource name invalid, Script not tagged.", __FUNCTION__);
- }
-}
+ std::array<ArgItem, 4> args{
+ {ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0},
+ ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
+ bool success = GetArgs(exe_ctx, &args[0], args.size());
+ if (!success) {
+ if (log)
+ log->Printf("%s - error while reading the function parameters.",
+ __FUNCTION__);
+ return;
+ }
+
+ std::string res_name;
+ process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), res_name, err);
+ if (err.Fail()) {
+ if (log)
+ log->Printf("%s - error reading res_name: %s.", __FUNCTION__,
+ err.AsCString());
+ }
-void
-RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ std::string cache_dir;
+ process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cache_dir, err);
+ if (err.Fail()) {
+ if (log)
+ log->Printf("%s - error reading cache_dir: %s.", __FUNCTION__,
+ err.AsCString());
+ }
- if (!module)
- {
- return;
- }
+ if (log)
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
+ __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]), res_name.c_str(), cache_dir.c_str());
- Target &target = GetProcess()->GetTarget();
- llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
+ if (res_name.size() > 0) {
+ StreamString strm;
+ strm.Printf("librs.%s.so", res_name.c_str());
- if (targetArchType != llvm::Triple::ArchType::x86 &&
- targetArchType != llvm::Triple::ArchType::arm &&
- targetArchType != llvm::Triple::ArchType::aarch64 &&
- targetArchType != llvm::Triple::ArchType::mipsel &&
- targetArchType != llvm::Triple::ArchType::mips64el &&
- targetArchType != llvm::Triple::ArchType::x86_64)
- {
- if (log)
- log->Printf("%s - unable to hook runtime functions.", __FUNCTION__);
- return;
+ ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true);
+ if (script) {
+ script->type = ScriptDetails::eScriptC;
+ script->cache_dir = cache_dir;
+ script->res_name = res_name;
+ script->shared_lib = strm.GetString();
+ script->context = addr_t(args[eRsContext]);
}
- uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize();
-
- for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
- {
- const HookDefn *hook_defn = &s_runtimeHookDefns[idx];
- if (hook_defn->kind != kind)
- {
- continue;
- }
+ if (log)
+ log->Printf("%s - '%s' tagged with context 0x%" PRIx64
+ " and script 0x%" PRIx64 ".",
+ __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]));
+ } else if (log) {
+ log->Printf("%s - resource name invalid, Script not tagged.", __FUNCTION__);
+ }
+}
- const char *symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
+void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
+ ModuleKind kind) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
- if (!sym)
- {
- if (log)
- {
- log->Printf("%s - symbol '%s' related to the function %s not found",
- __FUNCTION__, symbol_name, hook_defn->name);
- }
- continue;
- }
+ if (!module) {
+ return;
+ }
- addr_t addr = sym->GetLoadAddress(&target);
- if (addr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf("%s - unable to resolve the address of hook function '%s' with symbol '%s'.",
- __FUNCTION__, hook_defn->name, symbol_name);
- continue;
- }
- else
- {
- if (log)
- log->Printf("%s - function %s, address resolved at 0x%" PRIx64,
- __FUNCTION__, hook_defn->name, addr);
- }
+ Target &target = GetProcess()->GetTarget();
+ const llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
- RuntimeHookSP hook(new RuntimeHook());
- hook->address = addr;
- hook->defn = hook_defn;
- hook->bp_sp = target.CreateBreakpoint(addr, true, false);
- hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
- m_runtimeHooks[addr] = hook;
- if (log)
- {
- log->Printf("%s - successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
- __FUNCTION__, hook_defn->name, module->GetFileSpec().GetFilename().AsCString(),
- (uint64_t)hook_defn->version, (uint64_t)addr);
- }
- }
+ if (machine != llvm::Triple::ArchType::x86 &&
+ machine != llvm::Triple::ArchType::arm &&
+ machine != llvm::Triple::ArchType::aarch64 &&
+ machine != llvm::Triple::ArchType::mipsel &&
+ machine != llvm::Triple::ArchType::mips64el &&
+ machine != llvm::Triple::ArchType::x86_64) {
+ if (log)
+ log->Printf("%s - unable to hook runtime functions.", __FUNCTION__);
+ return;
+ }
+
+ const uint32_t target_ptr_size =
+ target.GetArchitecture().GetAddressByteSize();
+
+ std::array<bool, s_runtimeHookCount> hook_placed;
+ hook_placed.fill(false);
+
+ for (size_t idx = 0; idx < s_runtimeHookCount; idx++) {
+ const HookDefn *hook_defn = &s_runtimeHookDefns[idx];
+ if (hook_defn->kind != kind) {
+ continue;
+ }
+
+ const char *symbol_name = (target_ptr_size == 4)
+ ? hook_defn->symbol_name_m32
+ : hook_defn->symbol_name_m64;
+
+ const Symbol *sym = module->FindFirstSymbolWithNameAndType(
+ ConstString(symbol_name), eSymbolTypeCode);
+ if (!sym) {
+ if (log) {
+ log->Printf("%s - symbol '%s' related to the function %s not found",
+ __FUNCTION__, symbol_name, hook_defn->name);
+ }
+ continue;
+ }
+
+ addr_t addr = sym->GetLoadAddress(&target);
+ if (addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("%s - unable to resolve the address of hook function '%s' "
+ "with symbol '%s'.",
+ __FUNCTION__, hook_defn->name, symbol_name);
+ continue;
+ } else {
+ if (log)
+ log->Printf("%s - function %s, address resolved at 0x%" PRIx64,
+ __FUNCTION__, hook_defn->name, addr);
+ }
+
+ RuntimeHookSP hook(new RuntimeHook());
+ hook->address = addr;
+ hook->defn = hook_defn;
+ hook->bp_sp = target.CreateBreakpoint(addr, true, false);
+ hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
+ m_runtimeHooks[addr] = hook;
+ if (log) {
+ log->Printf("%s - successfully hooked '%s' in '%s' version %" PRIu64
+ " at 0x%" PRIx64 ".",
+ __FUNCTION__, hook_defn->name,
+ module->GetFileSpec().GetFilename().AsCString(),
+ (uint64_t)hook_defn->version, (uint64_t)addr);
+ }
+ hook_placed[idx] = true;
+ }
+
+ // log any unhooked function
+ if (log) {
+ for (size_t i = 0; i < hook_placed.size(); ++i) {
+ if (hook_placed[i])
+ continue;
+ const HookDefn &hook_defn = s_runtimeHookDefns[i];
+ if (hook_defn.kind != kind)
+ continue;
+ log->Printf("%s - function %s was not hooked", __FUNCTION__,
+ hook_defn.name);
+ }
+ }
}
-void
-RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
-{
- if (!rsmodule_sp)
- return;
+void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) {
+ if (!rsmodule_sp)
+ return;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- const ModuleSP module = rsmodule_sp->m_module;
- const FileSpec &file = module->GetPlatformFileSpec();
+ const ModuleSP module = rsmodule_sp->m_module;
+ const FileSpec &file = module->GetPlatformFileSpec();
- // Iterate over all of the scripts that we currently know of.
- // Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
- for (const auto &rs_script : m_scripts)
- {
- // Extract the expected .so file path for this script.
- std::string dylib;
- if (!rs_script->scriptDyLib.get(dylib))
- continue;
+ // Iterate over all of the scripts that we currently know of.
+ // Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
+ for (const auto &rs_script : m_scripts) {
+ // Extract the expected .so file path for this script.
+ std::string shared_lib;
+ if (!rs_script->shared_lib.get(shared_lib))
+ continue;
- // Only proceed if the module that has loaded corresponds to this script.
- if (file.GetFilename() != ConstString(dylib.c_str()))
- continue;
+ // Only proceed if the module that has loaded corresponds to this script.
+ if (file.GetFilename() != ConstString(shared_lib.c_str()))
+ continue;
- // Obtain the script address which we use as a key.
- lldb::addr_t script;
- if (!rs_script->script.get(script))
- continue;
+ // Obtain the script address which we use as a key.
+ lldb::addr_t script;
+ if (!rs_script->script.get(script))
+ continue;
- // If we have a script mapping for the current script.
- if (m_scriptMappings.find(script) != m_scriptMappings.end())
- {
- // if the module we have stored is different to the one we just received.
- if (m_scriptMappings[script] != rsmodule_sp)
- {
- if (log)
- log->Printf("%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.", __FUNCTION__,
- (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
- }
- }
- // We don't have a script mapping for the current script.
- else
- {
- // Obtain the script resource name.
- std::string resName;
- if (rs_script->resName.get(resName))
- // Set the modules resource name.
- rsmodule_sp->m_resname = resName;
- // Add Script/Module pair to map.
- m_scriptMappings[script] = rsmodule_sp;
- if (log)
- log->Printf("%s - script %" PRIx64 " associated with rsmodule '%s'.", __FUNCTION__,
- (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
- }
- }
+ // If we have a script mapping for the current script.
+ if (m_scriptMappings.find(script) != m_scriptMappings.end()) {
+ // if the module we have stored is different to the one we just received.
+ if (m_scriptMappings[script] != rsmodule_sp) {
+ if (log)
+ log->Printf(
+ "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
+ __FUNCTION__, (uint64_t)script,
+ rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ }
+ }
+ // We don't have a script mapping for the current script.
+ else {
+ // Obtain the script resource name.
+ std::string res_name;
+ if (rs_script->res_name.get(res_name))
+ // Set the modules resource name.
+ rsmodule_sp->m_resname = res_name;
+ // Add Script/Module pair to map.
+ m_scriptMappings[script] = rsmodule_sp;
+ if (log)
+ log->Printf(
+ "%s - script %" PRIx64 " associated with rsmodule '%s'.",
+ __FUNCTION__, (uint64_t)script,
+ rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ }
+ }
}
-// Uses the Target API to evaluate the expression passed as a parameter to the function
-// The result of that expression is returned an unsigned 64 bit int, via the result* paramter.
-// Function returns true on success, and false on failure
-bool
-RenderScriptRuntime::EvalRSExpression(const char *expression, StackFrame *frame_ptr, uint64_t *result)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+// Uses the Target API to evaluate the expression passed as a parameter to the
+// function The result of that expression is returned an unsigned 64 bit int,
+// via the result* parameter. Function returns true on success, and false on
+// failure
+bool RenderScriptRuntime::EvalRSExpression(const char *expr,
+ StackFrame *frame_ptr,
+ uint64_t *result) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ if (log)
+ log->Printf("%s(%s)", __FUNCTION__, expr);
+
+ ValueObjectSP expr_result;
+ EvaluateExpressionOptions options;
+ options.SetLanguage(lldb::eLanguageTypeC_plus_plus);
+ // Perform the actual expression evaluation
+ auto &target = GetProcess()->GetTarget();
+ target.EvaluateExpression(expr, frame_ptr, expr_result, options);
+
+ if (!expr_result) {
if (log)
- log->Printf("%s(%s)", __FUNCTION__, expression);
+ log->Printf("%s: couldn't evaluate expression.", __FUNCTION__);
+ return false;
+ }
- ValueObjectSP expr_result;
- EvaluateExpressionOptions options;
- options.SetLanguage(lldb::eLanguageTypeC_plus_plus);
- // Perform the actual expression evaluation
- GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result, options);
+ // The result of the expression is invalid
+ if (!expr_result->GetError().Success()) {
+ Error err = expr_result->GetError();
+ // Expression returned is void, so this is actually a success
+ if (err.GetError() == UserExpression::kNoResult) {
+ if (log)
+ log->Printf("%s - expression returned void.", __FUNCTION__);
- if (!expr_result)
- {
- if (log)
- log->Printf("%s: couldn't evaluate expression.", __FUNCTION__);
- return false;
+ result = nullptr;
+ return true;
}
- // The result of the expression is invalid
- if (!expr_result->GetError().Success())
- {
- Error err = expr_result->GetError();
- if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success
- {
- if (log)
- log->Printf("%s - expression returned void.", __FUNCTION__);
-
- result = nullptr;
- return true;
- }
-
- if (log)
- log->Printf("%s - error evaluating expression result: %s", __FUNCTION__,
- err.AsCString());
- return false;
- }
+ if (log)
+ log->Printf("%s - error evaluating expression result: %s", __FUNCTION__,
+ err.AsCString());
+ return false;
+ }
- bool success = false;
- *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an uint32_t.
+ bool success = false;
+ // We only read the result as an uint32_t.
+ *result = expr_result->GetValueAsUnsigned(0, &success);
- if (!success)
- {
- if (log)
- log->Printf("%s - couldn't convert expression result to uint32_t", __FUNCTION__);
- return false;
- }
+ if (!success) {
+ if (log)
+ log->Printf("%s - couldn't convert expression result to uint32_t",
+ __FUNCTION__);
+ return false;
+ }
- return true;
+ return true;
}
-namespace
-{
+namespace {
// Used to index expression format strings
-enum ExpressionStrings
-{
- eExprGetOffsetPtr = 0,
- eExprAllocGetType,
- eExprTypeDimX,
- eExprTypeDimY,
- eExprTypeDimZ,
- eExprTypeElemPtr,
- eExprElementType,
- eExprElementKind,
- eExprElementVec,
- eExprElementFieldCount,
- eExprSubelementsId,
- eExprSubelementsName,
- eExprSubelementsArrSize,
-
- _eExprLast // keep at the end, implicit size of the array runtimeExpressions
+enum ExpressionStrings {
+ eExprGetOffsetPtr = 0,
+ eExprAllocGetType,
+ eExprTypeDimX,
+ eExprTypeDimY,
+ eExprTypeDimZ,
+ eExprTypeElemPtr,
+ eExprElementType,
+ eExprElementKind,
+ eExprElementVec,
+ eExprElementFieldCount,
+ eExprSubelementsId,
+ eExprSubelementsName,
+ eExprSubelementsArrSize,
+
+ _eExprLast // keep at the end, implicit size of the array runtime_expressions
};
// max length of an expanded expression
const int jit_max_expr_size = 512;
// Retrieve the string to JIT for the given expression
-const char*
-JITTemplate(ExpressionStrings e)
-{
- // Format strings containing the expressions we may need to evaluate.
- static std::array<const char*, _eExprLast> runtimeExpressions = {{
- // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
- "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace"
- "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)",
-
- // Type* rsaAllocationGetType(Context*, Allocation*)
- "(void*)rsaAllocationGetType(0x%" PRIx64 ", 0x%" PRIx64 ")",
-
- // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
- // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
- // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
- // Need to specify 32 or 64 bit for uint_t since this differs between devices
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[0]", // X dim
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[1]", // Y dim
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[2]", // Z dim
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[5]", // Element ptr
-
- // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
- // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[0]", // Type
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[1]", // Kind
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[3]", // Vector Size
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[4]", // Field Count
-
- // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
- // size_t *arraySizes, uint32_t dataSize)
- // Needed for Allocations of structs to gather details about fields/Subelements
- // Element* of field
- "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
- "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]",
-
- // Name of field
- "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
- "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]",
-
- // Array size of field
- "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
- "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"
- }};
-
- return runtimeExpressions[e];
+const char *JITTemplate(ExpressionStrings e) {
+ // Format strings containing the expressions we may need to evaluate.
+ static std::array<const char *, _eExprLast> runtime_expressions = {
+ {// Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
+ "(int*)_"
+ "Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocation"
+ "CubemapFace"
+ "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)",
+
+ // Type* rsaAllocationGetType(Context*, Allocation*)
+ "(void*)rsaAllocationGetType(0x%" PRIx64 ", 0x%" PRIx64 ")",
+
+ // rsaTypeGetNativeData(Context*, Type*, void* typeData, size) Pack the
+ // data in the following way mHal.state.dimX; mHal.state.dimY;
+ // mHal.state.dimZ; mHal.state.lodCount; mHal.state.faces; mElement; into
+ // typeData Need to specify 32 or 64 bit for uint_t since this differs
+ // between devices
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 6); data[0]", // X dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 6); data[1]", // Y dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 6); data[2]", // Z dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 6); data[5]", // Element ptr
+
+ // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
+ // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into
+ // elemData
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 5); data[0]", // Type
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 5); data[1]", // Kind
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 5); data[3]", // Vector Size
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
+ ", 0x%" PRIx64 ", data, 5); data[4]", // Field Count
+
+ // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t
+ // *ids, const char **names, size_t *arraySizes, uint32_t dataSize)
+ // Needed for Allocations of structs to gather details about
+ // fields/Subelements Element* of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
+ "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64
+ ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]",
+
+ // Name of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
+ "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64
+ ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]",
+
+ // Array size of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
+ "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64
+ ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"}};
+
+ return runtime_expressions[e];
}
} // end of the anonymous namespace
+// JITs the RS runtime for the internal data pointer of an allocation. Is passed
+// x,y,z coordinates for the pointer to a specific element. Then sets the
+// data_ptr member in Allocation with the result. Returns true on success, false
+// otherwise
+bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc,
+ StackFrame *frame_ptr, uint32_t x,
+ uint32_t y, uint32_t z) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-// JITs the RS runtime for the internal data pointer of an allocation.
-// Is passed x,y,z coordinates for the pointer to a specific element.
-// Then sets the data_ptr member in Allocation with the result.
-// Returns true on success, false otherwise
-bool
-RenderScriptRuntime::JITDataPointer(AllocationDetails *allocation, StackFrame *frame_ptr, uint32_t x,
- uint32_t y, uint32_t z)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- if (!allocation->address.isValid())
- {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
- return false;
- }
+ if (!alloc->address.isValid()) {
+ if (log)
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ return false;
+ }
- const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
- char buffer[jit_max_expr_size];
+ const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
+ char expr_buf[jit_max_expr_size];
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), x, y, z);
- if (chars_written < 0)
- {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
- return false;
- }
- else if (chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
- return false;
- }
+ int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
+ *alloc->address.get(), x, y, z);
+ if (written < 0) {
+ if (log)
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ return false;
+ } else if (written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - expression too long.", __FUNCTION__);
+ return false;
+ }
- uint64_t result = 0;
- if (!EvalRSExpression(buffer, frame_ptr, &result))
- return false;
+ uint64_t result = 0;
+ if (!EvalRSExpression(expr_buf, frame_ptr, &result))
+ return false;
- addr_t mem_ptr = static_cast<lldb::addr_t>(result);
- allocation->data_ptr = mem_ptr;
+ addr_t data_ptr = static_cast<lldb::addr_t>(result);
+ alloc->data_ptr = data_ptr;
- return true;
+ return true;
}
// JITs the RS runtime for the internal pointer to the RS Type of an allocation
-// Then sets the type_ptr member in Allocation with the result.
-// Returns true on success, false otherwise
-bool
-RenderScriptRuntime::JITTypePointer(AllocationDetails *allocation, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+// Then sets the type_ptr member in Allocation with the result. Returns true on
+// success, false otherwise
+bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (!allocation->address.isValid() || !allocation->context.isValid())
- {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
- return false;
- }
+ if (!alloc->address.isValid() || !alloc->context.isValid()) {
+ if (log)
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ return false;
+ }
- const char *expr_cstr = JITTemplate(eExprAllocGetType);
- char buffer[jit_max_expr_size];
+ const char *fmt_str = JITTemplate(eExprAllocGetType);
+ char expr_buf[jit_max_expr_size];
- int chars_written =
- snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
- if (chars_written < 0)
- {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
- return false;
- }
- else if (chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
- return false;
- }
+ int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
+ *alloc->context.get(), *alloc->address.get());
+ if (written < 0) {
+ if (log)
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ return false;
+ } else if (written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - expression too long.", __FUNCTION__);
+ return false;
+ }
- uint64_t result = 0;
- if (!EvalRSExpression(buffer, frame_ptr, &result))
- return false;
+ uint64_t result = 0;
+ if (!EvalRSExpression(expr_buf, frame_ptr, &result))
+ return false;
- addr_t type_ptr = static_cast<lldb::addr_t>(result);
- allocation->type_ptr = type_ptr;
+ addr_t type_ptr = static_cast<lldb::addr_t>(result);
+ alloc->type_ptr = type_ptr;
- return true;
+ return true;
}
-// JITs the RS runtime for information about the dimensions and type of an allocation
-// Then sets dimension and element_ptr members in Allocation with the result.
-// Returns true on success, false otherwise
-bool
-RenderScriptRuntime::JITTypePacked(AllocationDetails *allocation, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- if (!allocation->type_ptr.isValid() || !allocation->context.isValid())
- {
- if (log)
- log->Printf("%s - Failed to find allocation details.", __FUNCTION__);
- return false;
- }
-
- // Expression is different depending on if device is 32 or 64 bit
- uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
- const uint32_t bits = archByteSize == 4 ? 32 : 64;
-
- // We want 4 elements from packed data
- const uint32_t num_exprs = 4;
- assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions");
-
- char buffer[num_exprs][jit_max_expr_size];
- uint64_t results[num_exprs];
-
- for (uint32_t i = 0; i < num_exprs; ++i)
- {
- const char *expr_cstr = JITTemplate(ExpressionStrings(eExprTypeDimX + i));
- int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, bits, *allocation->context.get(),
- *allocation->type_ptr.get());
- if (chars_written < 0)
- {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
- return false;
- }
- else if (chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
- return false;
- }
-
- // Perform expression evaluation
- if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
- return false;
- }
-
- // Assign results to allocation members
- AllocationDetails::Dimension dims;
- dims.dim_1 = static_cast<uint32_t>(results[0]);
- dims.dim_2 = static_cast<uint32_t>(results[1]);
- dims.dim_3 = static_cast<uint32_t>(results[2]);
- allocation->dimension = dims;
-
- addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]);
- allocation->element.element_ptr = elem_ptr;
+// JITs the RS runtime for information about the dimensions and type of an
+// allocation Then sets dimension and element_ptr members in Allocation with the
+// result. Returns true on success, false otherwise
+bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ if (!alloc->type_ptr.isValid() || !alloc->context.isValid()) {
if (log)
- log->Printf("%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") Element*: 0x%" PRIx64 ".", __FUNCTION__,
- dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr);
-
- return true;
+ log->Printf("%s - Failed to find allocation details.", __FUNCTION__);
+ return false;
+ }
+
+ // Expression is different depending on if device is 32 or 64 bit
+ uint32_t target_ptr_size =
+ GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
+ const uint32_t bits = target_ptr_size == 4 ? 32 : 64;
+
+ // We want 4 elements from packed data
+ const uint32_t num_exprs = 4;
+ assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) &&
+ "Invalid number of expressions");
+
+ char expr_bufs[num_exprs][jit_max_expr_size];
+ uint64_t results[num_exprs];
+
+ for (uint32_t i = 0; i < num_exprs; ++i) {
+ const char *fmt_str = JITTemplate(ExpressionStrings(eExprTypeDimX + i));
+ int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, bits,
+ *alloc->context.get(), *alloc->type_ptr.get());
+ if (written < 0) {
+ if (log)
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ return false;
+ } else if (written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - expression too long.", __FUNCTION__);
+ return false;
+ }
+
+ // Perform expression evaluation
+ if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i]))
+ return false;
+ }
+
+ // Assign results to allocation members
+ AllocationDetails::Dimension dims;
+ dims.dim_1 = static_cast<uint32_t>(results[0]);
+ dims.dim_2 = static_cast<uint32_t>(results[1]);
+ dims.dim_3 = static_cast<uint32_t>(results[2]);
+ alloc->dimension = dims;
+
+ addr_t element_ptr = static_cast<lldb::addr_t>(results[3]);
+ alloc->element.element_ptr = element_ptr;
+
+ if (log)
+ log->Printf("%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32
+ ") Element*: 0x%" PRIx64 ".",
+ __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr);
+
+ return true;
}
-// JITs the RS runtime for information about the Element of an allocation
-// Then sets type, type_vec_size, field_count and type_kind members in Element with the result.
-// Returns true on success, false otherwise
-bool
-RenderScriptRuntime::JITElementPacked(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- if (!elem.element_ptr.isValid())
- {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
- return false;
- }
-
- // We want 4 elements from packed data
- const uint32_t num_exprs = 4;
- assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1) && "Invalid number of expressions");
-
- char buffer[num_exprs][jit_max_expr_size];
- uint64_t results[num_exprs];
-
- for (uint32_t i = 0; i < num_exprs; i++)
- {
- const char *expr_cstr = JITTemplate(ExpressionStrings(eExprElementType + i));
- int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, context, *elem.element_ptr.get());
- if (chars_written < 0)
- {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
- return false;
- }
- else if (chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
- return false;
- }
-
- // Perform expression evaluation
- if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
- return false;
- }
-
- // Assign results to allocation members
- elem.type = static_cast<RenderScriptRuntime::Element::DataType>(results[0]);
- elem.type_kind = static_cast<RenderScriptRuntime::Element::DataKind>(results[1]);
- elem.type_vec_size = static_cast<uint32_t>(results[2]);
- elem.field_count = static_cast<uint32_t>(results[3]);
+// JITs the RS runtime for information about the Element of an allocation Then
+// sets type, type_vec_size, field_count and type_kind members in Element with
+// the result. Returns true on success, false otherwise
+bool RenderScriptRuntime::JITElementPacked(Element &elem,
+ const lldb::addr_t context,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ if (!elem.element_ptr.isValid()) {
if (log)
- log->Printf("%s - data type %" PRIu32 ", pixel type %" PRIu32 ", vector size %" PRIu32 ", field count %" PRIu32,
- __FUNCTION__, *elem.type.get(), *elem.type_kind.get(), *elem.type_vec_size.get(), *elem.field_count.get());
-
- // 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;
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ return false;
+ }
+
+ // We want 4 elements from packed data
+ const uint32_t num_exprs = 4;
+ assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1) &&
+ "Invalid number of expressions");
+
+ char expr_bufs[num_exprs][jit_max_expr_size];
+ uint64_t results[num_exprs];
+
+ for (uint32_t i = 0; i < num_exprs; i++) {
+ const char *fmt_str = JITTemplate(ExpressionStrings(eExprElementType + i));
+ int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, context,
+ *elem.element_ptr.get());
+ if (written < 0) {
+ if (log)
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ return false;
+ } else if (written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - expression too long.", __FUNCTION__);
+ return false;
+ }
+
+ // Perform expression evaluation
+ if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i]))
+ return false;
+ }
+
+ // Assign results to allocation members
+ elem.type = static_cast<RenderScriptRuntime::Element::DataType>(results[0]);
+ elem.type_kind =
+ static_cast<RenderScriptRuntime::Element::DataKind>(results[1]);
+ elem.type_vec_size = static_cast<uint32_t>(results[2]);
+ elem.field_count = static_cast<uint32_t>(results[3]);
+
+ if (log)
+ log->Printf("%s - data type %" PRIu32 ", pixel type %" PRIu32
+ ", vector size %" PRIu32 ", field count %" PRIu32,
+ __FUNCTION__, *elem.type.get(), *elem.type_kind.get(),
+ *elem.type_vec_size.get(), *elem.field_count.get());
+
+ // 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 true;
}
-// JITs the RS runtime for information about the subelements/fields of a struct allocation
-// This is necessary for infering the struct type so we can pretty print the allocation's contents.
-// Returns true on success, false otherwise
-bool
-RenderScriptRuntime::JITSubelements(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+// JITs the RS runtime for information about the subelements/fields of a struct
+// allocation This is necessary for infering the struct type so we can pretty
+// print the allocation's contents. Returns true on success, false otherwise
+bool RenderScriptRuntime::JITSubelements(Element &elem,
+ const lldb::addr_t context,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (!elem.element_ptr.isValid() || !elem.field_count.isValid())
- {
+ if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) {
+ if (log)
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ return false;
+ }
+
+ const short num_exprs = 3;
+ assert(num_exprs == (eExprSubelementsArrSize - eExprSubelementsId + 1) &&
+ "Invalid number of expressions");
+
+ char expr_buffer[jit_max_expr_size];
+ uint64_t results;
+
+ // Iterate over struct fields.
+ const uint32_t field_count = *elem.field_count.get();
+ for (uint32_t field_index = 0; field_index < field_count; ++field_index) {
+ Element child;
+ for (uint32_t expr_index = 0; expr_index < num_exprs; ++expr_index) {
+ const char *fmt_str =
+ JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index));
+ int written = snprintf(expr_buffer, jit_max_expr_size, fmt_str,
+ field_count, field_count, field_count, context,
+ *elem.element_ptr.get(), field_count, field_index);
+ if (written < 0) {
if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
- }
-
- const short num_exprs = 3;
- assert(num_exprs == (eExprSubelementsArrSize - eExprSubelementsId + 1) && "Invalid number of expressions");
-
- char expr_buffer[jit_max_expr_size];
- uint64_t results;
+ } else if (written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - expression too long.", __FUNCTION__);
+ return false;
+ }
- // Iterate over struct fields.
- const uint32_t field_count = *elem.field_count.get();
- for (uint32_t field_index = 0; field_index < field_count; ++field_index)
- {
- Element child;
- for (uint32_t expr_index = 0; expr_index < num_exprs; ++expr_index)
- {
- const char *expr_cstr = JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index));
- int chars_written = snprintf(expr_buffer, jit_max_expr_size, expr_cstr,
- field_count, field_count, field_count,
- context, *elem.element_ptr.get(), field_count, field_index);
- if (chars_written < 0)
- {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
- return false;
- }
- else if (chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
- return false;
- }
-
- // Perform expression evaluation
- if (!EvalRSExpression(expr_buffer, frame_ptr, &results))
- return false;
+ // Perform expression evaluation
+ if (!EvalRSExpression(expr_buffer, frame_ptr, &results))
+ return false;
- if (log)
- log->Printf("%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
-
- switch (expr_index)
- {
- case 0: // Element* of child
- child.element_ptr = static_cast<addr_t>(results);
- break;
- case 1: // Name of child
- {
- lldb::addr_t address = static_cast<addr_t>(results);
- Error err;
- std::string name;
- GetProcess()->ReadCStringFromMemory(address, name, err);
- if (!err.Fail())
- child.type_name = ConstString(name);
- else
- {
- if (log)
- log->Printf("%s - warning: Couldn't read field name.", __FUNCTION__);
- }
- break;
- }
- case 2: // Array size of child
- child.array_size = static_cast<uint32_t>(results);
- break;
- }
+ if (log)
+ log->Printf("%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
+
+ switch (expr_index) {
+ case 0: // Element* of child
+ child.element_ptr = static_cast<addr_t>(results);
+ break;
+ case 1: // Name of child
+ {
+ lldb::addr_t address = static_cast<addr_t>(results);
+ Error err;
+ std::string name;
+ GetProcess()->ReadCStringFromMemory(address, name, err);
+ if (!err.Fail())
+ child.type_name = ConstString(name);
+ else {
+ if (log)
+ log->Printf("%s - warning: Couldn't read field name.",
+ __FUNCTION__);
}
-
- // We need to recursively JIT each Element field of the struct since
- // structs can be nested inside structs.
- if (!JITElementPacked(child, context, frame_ptr))
- return false;
- elem.children.push_back(child);
- }
-
- // Try to infer the name of the struct type so we can pretty print the allocation contents.
- FindStructTypeName(elem, frame_ptr);
-
- return true;
+ break;
+ }
+ case 2: // Array size of child
+ child.array_size = static_cast<uint32_t>(results);
+ break;
+ }
+ }
+
+ // We need to recursively JIT each Element field of the struct since
+ // structs can be nested inside structs.
+ if (!JITElementPacked(child, context, frame_ptr))
+ return false;
+ elem.children.push_back(child);
+ }
+
+ // Try to infer the name of the struct type so we can pretty print the
+ // allocation contents.
+ FindStructTypeName(elem, frame_ptr);
+
+ return true;
}
// JITs the RS runtime for the address of the last element in the allocation.
-// The `elem_size` paramter represents the size of a single element, including padding.
-// Which is needed as an offset from the last element pointer.
-// Using this offset minus the starting address we can calculate the size of the allocation.
-// Returns true on success, false otherwise
-bool
-RenderScriptRuntime::JITAllocationSize(AllocationDetails *allocation, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- if (!allocation->address.isValid() || !allocation->dimension.isValid() || !allocation->data_ptr.isValid() ||
- !allocation->element.datum_size.isValid())
- {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
- return false;
- }
-
- // Find dimensions
- uint32_t dim_x = allocation->dimension.get()->dim_1;
- uint32_t dim_y = allocation->dimension.get()->dim_2;
- uint32_t dim_z = allocation->dimension.get()->dim_3;
-
- // Our plan of jitting the last element address doesn't seem to work for struct Allocations
- // Instead try to infer the size ourselves without any inter element padding.
- if (allocation->element.children.size() > 0)
- {
- if (dim_x == 0) dim_x = 1;
- if (dim_y == 0) dim_y = 1;
- if (dim_z == 0) dim_z = 1;
-
- allocation->size = dim_x * dim_y * dim_z * *allocation->element.datum_size.get();
+// The `elem_size` parameter represents the size of a single element, including
+// padding. Which is needed as an offset from the last element pointer. Using
+// this offset minus the starting address we can calculate the size of the
+// allocation. Returns true on success, false otherwise
+bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ if (!alloc->address.isValid() || !alloc->dimension.isValid() ||
+ !alloc->data_ptr.isValid() || !alloc->element.datum_size.isValid()) {
+ if (log)
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ return false;
+ }
+
+ // Find dimensions
+ uint32_t dim_x = alloc->dimension.get()->dim_1;
+ uint32_t dim_y = alloc->dimension.get()->dim_2;
+ uint32_t dim_z = alloc->dimension.get()->dim_3;
+
+ // Our plan of jitting the last element address doesn't seem to work for
+ // struct Allocations` Instead try to infer the size ourselves without any
+ // inter element padding.
+ if (alloc->element.children.size() > 0) {
+ if (dim_x == 0)
+ dim_x = 1;
+ if (dim_y == 0)
+ dim_y = 1;
+ if (dim_z == 0)
+ dim_z = 1;
+
+ alloc->size = dim_x * dim_y * dim_z * *alloc->element.datum_size.get();
- if (log)
- log->Printf("%s - infered size of struct allocation %" PRIu32 ".", __FUNCTION__,
- *allocation->size.get());
- return true;
- }
+ if (log)
+ log->Printf("%s - inferred size of struct allocation %" PRIu32 ".",
+ __FUNCTION__, *alloc->size.get());
+ return true;
+ }
- const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
- char buffer[jit_max_expr_size];
+ const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
+ char expr_buf[jit_max_expr_size];
- // Calculate last element
- dim_x = dim_x == 0 ? 0 : dim_x - 1;
- dim_y = dim_y == 0 ? 0 : dim_y - 1;
- dim_z = dim_z == 0 ? 0 : dim_z - 1;
+ // Calculate last element
+ dim_x = dim_x == 0 ? 0 : dim_x - 1;
+ dim_y = dim_y == 0 ? 0 : dim_y - 1;
+ dim_z = dim_z == 0 ? 0 : dim_z - 1;
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), dim_x, dim_y, dim_z);
- if (chars_written < 0)
- {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
- return false;
- }
- else if (chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
- return false;
- }
+ int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
+ *alloc->address.get(), dim_x, dim_y, dim_z);
+ if (written < 0) {
+ if (log)
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ return false;
+ } else if (written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - expression too long.", __FUNCTION__);
+ return false;
+ }
- uint64_t result = 0;
- if (!EvalRSExpression(buffer, frame_ptr, &result))
- return false;
+ uint64_t result = 0;
+ if (!EvalRSExpression(expr_buf, frame_ptr, &result))
+ return false;
- addr_t mem_ptr = static_cast<lldb::addr_t>(result);
- // Find pointer to last element and add on size of an element
- allocation->size =
- static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + *allocation->element.datum_size.get();
+ addr_t mem_ptr = static_cast<lldb::addr_t>(result);
+ // Find pointer to last element and add on size of an element
+ alloc->size = static_cast<uint32_t>(mem_ptr - *alloc->data_ptr.get()) +
+ *alloc->element.datum_size.get();
- return true;
+ return true;
}
-// JITs the RS runtime for information about the stride between rows in the allocation.
-// This is done to detect padding, since allocated memory is 16-byte aligned.
+// JITs the RS runtime for information about the stride between rows in the
+// allocation. This is done to detect padding, since allocated memory is 16-byte
+// aligned.
// Returns true on success, false otherwise
-bool
-RenderScriptRuntime::JITAllocationStride(AllocationDetails *allocation, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (!allocation->address.isValid() || !allocation->data_ptr.isValid())
- {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
- return false;
- }
+ if (!alloc->address.isValid() || !alloc->data_ptr.isValid()) {
+ if (log)
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ return false;
+ }
- const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
- char buffer[jit_max_expr_size];
+ const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
+ char expr_buf[jit_max_expr_size];
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), 0, 1, 0);
- if (chars_written < 0)
- {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
- return false;
- }
- else if (chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
- return false;
- }
+ int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
+ *alloc->address.get(), 0, 1, 0);
+ if (written < 0) {
+ if (log)
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ return false;
+ } else if (written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - expression too long.", __FUNCTION__);
+ return false;
+ }
- uint64_t result = 0;
- if (!EvalRSExpression(buffer, frame_ptr, &result))
- return false;
+ uint64_t result = 0;
+ if (!EvalRSExpression(expr_buf, frame_ptr, &result))
+ return false;
- addr_t mem_ptr = static_cast<lldb::addr_t>(result);
- allocation->stride = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get());
+ addr_t mem_ptr = static_cast<lldb::addr_t>(result);
+ alloc->stride = static_cast<uint32_t>(mem_ptr - *alloc->data_ptr.get());
- return true;
+ return true;
}
// JIT all the current runtime info regarding an allocation
-bool
-RenderScriptRuntime::RefreshAllocation(AllocationDetails *allocation, StackFrame *frame_ptr)
-{
- // GetOffsetPointer()
- if (!JITDataPointer(allocation, frame_ptr))
- return false;
+bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc,
+ StackFrame *frame_ptr) {
+ // GetOffsetPointer()
+ if (!JITDataPointer(alloc, frame_ptr))
+ return false;
- // rsaAllocationGetType()
- if (!JITTypePointer(allocation, frame_ptr))
- return false;
+ // rsaAllocationGetType()
+ if (!JITTypePointer(alloc, frame_ptr))
+ return false;
- // rsaTypeGetNativeData()
- if (!JITTypePacked(allocation, frame_ptr))
- return false;
+ // rsaTypeGetNativeData()
+ if (!JITTypePacked(alloc, frame_ptr))
+ return false;
- // rsaElementGetNativeData()
- if (!JITElementPacked(allocation->element, *allocation->context.get(), frame_ptr))
- return false;
+ // rsaElementGetNativeData()
+ if (!JITElementPacked(alloc->element, *alloc->context.get(), frame_ptr))
+ return false;
- // Sets the datum_size member in Element
- SetElementSize(allocation->element);
+ // Sets the datum_size member in Element
+ SetElementSize(alloc->element);
- // Use GetOffsetPointer() to infer size of the allocation
- if (!JITAllocationSize(allocation, frame_ptr))
- return false;
+ // Use GetOffsetPointer() to infer size of the allocation
+ if (!JITAllocationSize(alloc, frame_ptr))
+ return false;
- return true;
+ return true;
}
-// Function attempts to set the type_name member of the paramaterised Element object.
+// Function attempts to set the type_name member of the paramaterised Element
+// object.
// This string should be the name of the struct type the Element represents.
// We need this string for pretty printing the Element to users.
-void
-RenderScriptRuntime::FindStructTypeName(Element &elem, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- if (!elem.type_name.IsEmpty()) // Name already set
- return;
- else
- elem.type_name = Element::GetFallbackStructName(); // Default type name if we don't succeed
-
- // Find all the global variables from the script rs modules
- VariableList variable_list;
- for (auto module_sp : m_rsmodules)
- module_sp->m_module->FindGlobalVariables(RegularExpression("."), true, UINT32_MAX, variable_list);
-
- // Iterate over all the global variables looking for one with a matching type to the Element.
- // We make the assumption a match exists since there needs to be a global variable to reflect the
- // struct type back into java host code.
- for (uint32_t var_index = 0; var_index < variable_list.GetSize(); ++var_index)
- {
- const VariableSP var_sp(variable_list.GetVariableAtIndex(var_index));
- if (!var_sp)
- continue;
-
- ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp);
- if (!valobj_sp)
- continue;
-
- // Find the number of variable fields.
- // If it has no fields, or more fields than our Element, then it can't be the struct we're looking for.
- // Don't check for equality since RS can add extra struct members for padding.
- size_t num_children = valobj_sp->GetNumChildren();
- if (num_children > elem.children.size() || num_children == 0)
- continue;
-
- // Iterate over children looking for members with matching field names.
- // If all the field names match, this is likely the struct we want.
- //
- // TODO: This could be made more robust by also checking children data sizes, or array size
- bool found = true;
- for (size_t child_index = 0; child_index < num_children; ++child_index)
- {
- ValueObjectSP child = valobj_sp->GetChildAtIndex(child_index, true);
- if (!child || (child->GetName() != elem.children[child_index].type_name))
- {
- found = false;
- break;
- }
- }
-
- // RS can add extra struct members for padding in the format '#rs_padding_[0-9]+'
- if (found && num_children < elem.children.size())
- {
- const uint32_t size_diff = elem.children.size() - num_children;
- if (log)
- log->Printf("%s - %" PRIu32 " padding struct entries", __FUNCTION__, size_diff);
-
- for (uint32_t padding_index = 0; padding_index < size_diff; ++padding_index)
- {
- const ConstString &name = elem.children[num_children + padding_index].type_name;
- if (strcmp(name.AsCString(), "#rs_padding") < 0)
- found = false;
- }
- }
-
- // We've found a global var with matching type
- if (found)
- {
- // Dereference since our Element type isn't a pointer.
- if (valobj_sp->IsPointerType())
- {
- Error err;
- ValueObjectSP deref_valobj = valobj_sp->Dereference(err);
- if (!err.Fail())
- valobj_sp = deref_valobj;
- }
-
- // Save name of variable in Element.
- elem.type_name = valobj_sp->GetTypeName();
- if (log)
- log->Printf("%s - element name set to %s", __FUNCTION__, elem.type_name.AsCString());
-
- return;
- }
- }
+void RenderScriptRuntime::FindStructTypeName(Element &elem,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ if (!elem.type_name.IsEmpty()) // Name already set
+ return;
+ else
+ elem.type_name = Element::GetFallbackStructName(); // Default type name if
+ // we don't succeed
+
+ // Find all the global variables from the script rs modules
+ VariableList var_list;
+ for (auto module_sp : m_rsmodules)
+ module_sp->m_module->FindGlobalVariables(
+ RegularExpression(llvm::StringRef(".")), true, UINT32_MAX, var_list);
+
+ // Iterate over all the global variables looking for one with a matching type
+ // to the Element.
+ // We make the assumption a match exists since there needs to be a global
+ // variable to reflect the struct type back into java host code.
+ for (uint32_t i = 0; i < var_list.GetSize(); ++i) {
+ const VariableSP var_sp(var_list.GetVariableAtIndex(i));
+ if (!var_sp)
+ continue;
+
+ ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp);
+ if (!valobj_sp)
+ continue;
+
+ // Find the number of variable fields.
+ // If it has no fields, or more fields than our Element, then it can't be
+ // the struct we're looking for.
+ // Don't check for equality since RS can add extra struct members for
+ // padding.
+ size_t num_children = valobj_sp->GetNumChildren();
+ if (num_children > elem.children.size() || num_children == 0)
+ continue;
+
+ // Iterate over children looking for members with matching field names.
+ // If all the field names match, this is likely the struct we want.
+ // TODO: This could be made more robust by also checking children data
+ // sizes, or array size
+ bool found = true;
+ for (size_t i = 0; i < num_children; ++i) {
+ ValueObjectSP child = valobj_sp->GetChildAtIndex(i, true);
+ if (!child || (child->GetName() != elem.children[i].type_name)) {
+ found = false;
+ break;
+ }
+ }
+
+ // RS can add extra struct members for padding in the format
+ // '#rs_padding_[0-9]+'
+ if (found && num_children < elem.children.size()) {
+ const uint32_t size_diff = elem.children.size() - num_children;
+ if (log)
+ log->Printf("%s - %" PRIu32 " padding struct entries", __FUNCTION__,
+ size_diff);
+
+ for (uint32_t i = 0; i < size_diff; ++i) {
+ const ConstString &name = elem.children[num_children + i].type_name;
+ if (strcmp(name.AsCString(), "#rs_padding") < 0)
+ found = false;
+ }
+ }
+
+ // We've found a global variable with matching type
+ if (found) {
+ // Dereference since our Element type isn't a pointer.
+ if (valobj_sp->IsPointerType()) {
+ Error err;
+ ValueObjectSP deref_valobj = valobj_sp->Dereference(err);
+ if (!err.Fail())
+ valobj_sp = deref_valobj;
+ }
+
+ // Save name of variable in Element.
+ elem.type_name = valobj_sp->GetTypeName();
+ if (log)
+ log->Printf("%s - element name set to %s", __FUNCTION__,
+ elem.type_name.AsCString());
+
+ return;
+ }
+ }
}
-// Function sets the datum_size member of Element. Representing the size of a single instance including padding.
+// Function sets the datum_size member of Element. Representing the size of a
+// single instance including padding.
// Assumes the relevant allocation information has already been jitted.
-void
-RenderScriptRuntime::SetElementSize(Element &elem)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- const Element::DataType type = *elem.type.get();
- assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && "Invalid allocation type");
-
- const uint32_t vec_size = *elem.type_vec_size.get();
- uint32_t data_size = 0;
- uint32_t padding = 0;
-
- // Element is of a struct type, calculate size recursively.
- if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0))
- {
- for (Element &child : elem.children)
- {
- SetElementSize(child);
- const uint32_t array_size = child.array_size.isValid() ? *child.array_size.get() : 1;
- data_size += *child.datum_size.get() * array_size;
- }
- }
- // These have been packed already
- else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 ||
- type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
- type == Element::RS_TYPE_UNSIGNED_4_4_4_4)
- {
- data_size = AllocationDetails::RSTypeToFormat[type][eElementSize];
- }
- else if (type < Element::RS_TYPE_ELEMENT)
- {
- data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize];
- if (vec_size == 3)
- padding = AllocationDetails::RSTypeToFormat[type][eElementSize];
- }
- else
- data_size = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
-
- elem.padding = padding;
- elem.datum_size = data_size + padding;
- if (log)
- log->Printf("%s - element size set to %" PRIu32, __FUNCTION__, data_size + padding);
+void RenderScriptRuntime::SetElementSize(Element &elem) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ const Element::DataType type = *elem.type.get();
+ assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT &&
+ "Invalid allocation type");
+
+ const uint32_t vec_size = *elem.type_vec_size.get();
+ uint32_t data_size = 0;
+ uint32_t padding = 0;
+
+ // Element is of a struct type, calculate size recursively.
+ if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0)) {
+ for (Element &child : elem.children) {
+ SetElementSize(child);
+ const uint32_t array_size =
+ child.array_size.isValid() ? *child.array_size.get() : 1;
+ data_size += *child.datum_size.get() * array_size;
+ }
+ }
+ // These have been packed already
+ else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 ||
+ type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
+ type == Element::RS_TYPE_UNSIGNED_4_4_4_4) {
+ data_size = AllocationDetails::RSTypeToFormat[type][eElementSize];
+ } else if (type < Element::RS_TYPE_ELEMENT) {
+ data_size =
+ vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize];
+ if (vec_size == 3)
+ padding = AllocationDetails::RSTypeToFormat[type][eElementSize];
+ } else
+ data_size =
+ GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
+
+ elem.padding = padding;
+ elem.datum_size = data_size + padding;
+ if (log)
+ log->Printf("%s - element size set to %" PRIu32, __FUNCTION__,
+ data_size + padding);
}
-// Given an allocation, this function copies the allocation contents from device into a buffer on the heap.
+// Given an allocation, this function copies the allocation contents from device
+// into a buffer on the heap.
// Returning a shared pointer to the buffer containing the data.
std::shared_ptr<uint8_t>
-RenderScriptRuntime::GetAllocationData(AllocationDetails *allocation, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- // JIT all the allocation details
- if (allocation->shouldRefresh())
- {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info", __FUNCTION__);
+ // JIT all the allocation details
+ if (alloc->ShouldRefresh()) {
+ if (log)
+ log->Printf("%s - allocation details not calculated yet, jitting info",
+ __FUNCTION__);
- if (!RefreshAllocation(allocation, frame_ptr))
- {
- if (log)
- log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
- return nullptr;
- }
+ if (!RefreshAllocation(alloc, frame_ptr)) {
+ if (log)
+ log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
+ return nullptr;
}
+ }
- assert(allocation->data_ptr.isValid() && allocation->element.type.isValid() &&
- allocation->element.type_vec_size.isValid() && allocation->size.isValid() &&
- "Allocation information not available");
+ assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() &&
+ alloc->element.type_vec_size.isValid() && alloc->size.isValid() &&
+ "Allocation information not available");
- // Allocate a buffer to copy data into
- const uint32_t size = *allocation->size.get();
- std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
- if (!buffer)
- {
- if (log)
- log->Printf("%s - couldn't allocate a %" PRIu32 " byte buffer", __FUNCTION__, size);
- return nullptr;
- }
+ // Allocate a buffer to copy data into
+ const uint32_t size = *alloc->size.get();
+ std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
+ if (!buffer) {
+ if (log)
+ log->Printf("%s - couldn't allocate a %" PRIu32 " byte buffer",
+ __FUNCTION__, size);
+ return nullptr;
+ }
- // Read the inferior memory
- Error error;
- lldb::addr_t data_ptr = *allocation->data_ptr.get();
- GetProcess()->ReadMemory(data_ptr, buffer.get(), size, error);
- if (error.Fail())
- {
- if (log)
- log->Printf("%s - '%s' Couldn't read %" PRIu32 " bytes of allocation data from 0x%" PRIx64,
- __FUNCTION__, error.AsCString(), size, data_ptr);
- return nullptr;
- }
+ // Read the inferior memory
+ Error err;
+ lldb::addr_t data_ptr = *alloc->data_ptr.get();
+ GetProcess()->ReadMemory(data_ptr, buffer.get(), size, err);
+ if (err.Fail()) {
+ if (log)
+ log->Printf("%s - '%s' Couldn't read %" PRIu32
+ " bytes of allocation data from 0x%" PRIx64,
+ __FUNCTION__, err.AsCString(), size, data_ptr);
+ return nullptr;
+ }
- return buffer;
+ return buffer;
}
// Function copies data from a binary file into an allocation.
-// There is a header at the start of the file, FileHeader, before the data content itself.
-// Information from this header is used to display warnings to the user about incompatabilities
-bool
-RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- // Find allocation with the given id
- AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
- if (!alloc)
- return false;
+// There is a header at the start of the file, FileHeader, before the data
+// content itself.
+// Information from this header is used to display warnings to the user about
+// incompatibilities
+bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
+ const char *path,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ // Find allocation with the given id
+ AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
+ if (!alloc)
+ return false;
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__, *alloc->address.get());
+ if (log)
+ log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__,
+ *alloc->address.get());
- // JIT all the allocation details
- if (alloc->shouldRefresh())
- {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
+ // JIT all the allocation details
+ if (alloc->ShouldRefresh()) {
+ if (log)
+ log->Printf("%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
- if (!RefreshAllocation(alloc, frame_ptr))
- {
- if (log)
- log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
- return false;
- }
+ if (!RefreshAllocation(alloc, frame_ptr)) {
+ if (log)
+ log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
+ return false;
}
+ }
- assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() &&
- alloc->size.isValid() && alloc->element.datum_size.isValid() && "Allocation information not available");
+ assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() &&
+ alloc->element.type_vec_size.isValid() && alloc->size.isValid() &&
+ alloc->element.datum_size.isValid() &&
+ "Allocation information not available");
- // Check we can read from file
- FileSpec file(filename, true);
- if (!file.Exists())
- {
- strm.Printf("Error: File %s does not exist", filename);
- strm.EOL();
- return false;
- }
+ // Check we can read from file
+ FileSpec file(path, true);
+ if (!file.Exists()) {
+ strm.Printf("Error: File %s does not exist", path);
+ strm.EOL();
+ return false;
+ }
- if (!file.Readable())
- {
- strm.Printf("Error: File %s does not have readable permissions", filename);
- strm.EOL();
- return false;
- }
+ if (!file.Readable()) {
+ strm.Printf("Error: File %s does not have readable permissions", path);
+ strm.EOL();
+ return false;
+ }
- // Read file into data buffer
- DataBufferSP data_sp(file.ReadFileContents());
+ // Read file into data buffer
+ DataBufferSP data_sp(file.ReadFileContents());
- // Cast start of buffer to FileHeader and use pointer to read metadata
- void *file_buffer = data_sp->GetBytes();
- if (file_buffer == nullptr ||
- data_sp->GetByteSize() < (sizeof(AllocationDetails::FileHeader) + sizeof(AllocationDetails::ElementHeader)))
- {
- strm.Printf("Error: File %s does not contain enough data for header", filename);
- strm.EOL();
- return false;
- }
- const AllocationDetails::FileHeader *file_header = static_cast<AllocationDetails::FileHeader *>(file_buffer);
+ // Cast start of buffer to FileHeader and use pointer to read metadata
+ void *file_buf = data_sp->GetBytes();
+ if (file_buf == nullptr ||
+ data_sp->GetByteSize() < (sizeof(AllocationDetails::FileHeader) +
+ sizeof(AllocationDetails::ElementHeader))) {
+ strm.Printf("Error: File %s does not contain enough data for header", path);
+ strm.EOL();
+ return false;
+ }
+ const AllocationDetails::FileHeader *file_header =
+ static_cast<AllocationDetails::FileHeader *>(file_buf);
+
+ // Check file starts with ascii characters "RSAD"
+ if (memcmp(file_header->ident, "RSAD", 4)) {
+ strm.Printf("Error: File doesn't contain identifier for an RS allocation "
+ "dump. Are you sure this is the correct file?");
+ strm.EOL();
+ return false;
+ }
+
+ // Look at the type of the root element in the header
+ AllocationDetails::ElementHeader root_el_hdr;
+ memcpy(&root_el_hdr, static_cast<uint8_t *>(file_buf) +
+ sizeof(AllocationDetails::FileHeader),
+ sizeof(AllocationDetails::ElementHeader));
+
+ if (log)
+ log->Printf("%s - header type %" PRIu32 ", element size %" PRIu32,
+ __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size);
+
+ // Check if the target allocation and file both have the same number of bytes
+ // for an Element
+ if (*alloc->element.datum_size.get() != root_el_hdr.element_size) {
+ strm.Printf("Warning: Mismatched Element sizes - file %" PRIu32
+ " bytes, allocation %" PRIu32 " bytes",
+ root_el_hdr.element_size, *alloc->element.datum_size.get());
+ strm.EOL();
+ }
- // Check file starts with ascii characters "RSAD"
- if (memcmp(file_header->ident, "RSAD", 4))
- {
- strm.Printf("Error: File doesn't contain identifier for an RS allocation dump. Are you sure this is the correct file?");
- strm.EOL();
- return false;
- }
+ // Check if the target allocation and file both have the same type
+ const uint32_t alloc_type = static_cast<uint32_t>(*alloc->element.type.get());
+ const uint32_t file_type = root_el_hdr.type;
- // Look at the type of the root element in the header
- AllocationDetails::ElementHeader root_element_header;
- memcpy(&root_element_header, static_cast<uint8_t *>(file_buffer) + sizeof(AllocationDetails::FileHeader),
- sizeof(AllocationDetails::ElementHeader));
+ if (file_type > Element::RS_TYPE_FONT) {
+ strm.Printf("Warning: File has unknown allocation type");
+ strm.EOL();
+ } else if (alloc_type != file_type) {
+ // Enum value isn't monotonous, so doesn't always index RsDataTypeToString
+ // array
+ uint32_t target_type_name_idx = alloc_type;
+ uint32_t head_type_name_idx = file_type;
+ if (alloc_type >= Element::RS_TYPE_ELEMENT &&
+ alloc_type <= Element::RS_TYPE_FONT)
+ target_type_name_idx = static_cast<Element::DataType>(
+ (alloc_type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
+
+ if (file_type >= Element::RS_TYPE_ELEMENT &&
+ file_type <= Element::RS_TYPE_FONT)
+ head_type_name_idx = static_cast<Element::DataType>(
+ (file_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 +
+ 1);
+
+ const char *head_type_name =
+ AllocationDetails::RsDataTypeToString[head_type_name_idx][0];
+ const char *target_type_name =
+ AllocationDetails::RsDataTypeToString[target_type_name_idx][0];
+
+ strm.Printf(
+ "Warning: Mismatched Types - file '%s' type, allocation '%s' type",
+ head_type_name, target_type_name);
+ strm.EOL();
+ }
- if (log)
- log->Printf("%s - header type %" PRIu32 ", element size %" PRIu32, __FUNCTION__,
- root_element_header.type, root_element_header.element_size);
+ // Advance buffer past header
+ file_buf = static_cast<uint8_t *>(file_buf) + file_header->hdr_size;
- // Check if the target allocation and file both have the same number of bytes for an Element
- if (*alloc->element.datum_size.get() != root_element_header.element_size)
- {
- strm.Printf("Warning: Mismatched Element sizes - file %" PRIu32 " bytes, allocation %" PRIu32 " bytes",
- root_element_header.element_size, *alloc->element.datum_size.get());
- strm.EOL();
- }
+ // Calculate size of allocation data in file
+ size_t size = data_sp->GetByteSize() - file_header->hdr_size;
- // Check if the target allocation and file both have the same type
- const uint32_t alloc_type = static_cast<uint32_t>(*alloc->element.type.get());
- const uint32_t file_type = root_element_header.type;
+ // Check if the target allocation and file both have the same total data size.
+ const uint32_t alloc_size = *alloc->size.get();
+ if (alloc_size != size) {
+ strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64
+ " bytes, allocation 0x%" PRIx32 " bytes",
+ (uint64_t)size, alloc_size);
+ strm.EOL();
+ // Set length to copy to minimum
+ size = alloc_size < size ? alloc_size : size;
+ }
+
+ // Copy file data from our buffer into the target allocation.
+ lldb::addr_t alloc_data = *alloc->data_ptr.get();
+ Error err;
+ size_t written = GetProcess()->WriteMemory(alloc_data, file_buf, size, err);
+ if (!err.Success() || written != size) {
+ strm.Printf("Error: Couldn't write data to allocation %s", err.AsCString());
+ strm.EOL();
+ return false;
+ }
- if (file_type > Element::RS_TYPE_FONT)
- {
- strm.Printf("Warning: File has unknown allocation type");
- strm.EOL();
- }
- else if (alloc_type != file_type)
- {
- // Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
- uint32_t printable_target_type_index = alloc_type;
- uint32_t printable_head_type_index = file_type;
- if (alloc_type >= Element::RS_TYPE_ELEMENT && alloc_type <= Element::RS_TYPE_FONT)
- printable_target_type_index = static_cast<Element::DataType>((alloc_type - Element::RS_TYPE_ELEMENT) +
- Element::RS_TYPE_MATRIX_2X2 + 1);
-
- if (file_type >= Element::RS_TYPE_ELEMENT && file_type <= Element::RS_TYPE_FONT)
- printable_head_type_index = static_cast<Element::DataType>((file_type - Element::RS_TYPE_ELEMENT) +
- Element::RS_TYPE_MATRIX_2X2 + 1);
-
- const char *file_type_cstr = AllocationDetails::RsDataTypeToString[printable_head_type_index][0];
- const char *target_type_cstr = AllocationDetails::RsDataTypeToString[printable_target_type_index][0];
-
- strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type", file_type_cstr,
- target_type_cstr);
- strm.EOL();
- }
+ strm.Printf("Contents of file '%s' read into allocation %" PRIu32, path,
+ alloc->id);
+ strm.EOL();
- // Advance buffer past header
- file_buffer = static_cast<uint8_t *>(file_buffer) + file_header->hdr_size;
+ return true;
+}
- // Calculate size of allocation data in file
- size_t length = data_sp->GetByteSize() - file_header->hdr_size;
+// Function takes as parameters a byte buffer, which will eventually be written
+// to file as the element header, an offset into that buffer, and an Element
+// that will be saved into the buffer at the parametrised offset.
+// Return value is the new offset after writing the element into the buffer.
+// Elements are saved to the file as the ElementHeader struct followed by
+// offsets to the structs of all the element's children.
+size_t RenderScriptRuntime::PopulateElementHeaders(
+ const std::shared_ptr<uint8_t> header_buffer, size_t offset,
+ const Element &elem) {
+ // File struct for an element header with all the relevant details copied from
+ // elem. We assume members are valid already.
+ AllocationDetails::ElementHeader elem_header;
+ elem_header.type = *elem.type.get();
+ elem_header.kind = *elem.type_kind.get();
+ elem_header.element_size = *elem.datum_size.get();
+ elem_header.vector_size = *elem.type_vec_size.get();
+ elem_header.array_size =
+ elem.array_size.isValid() ? *elem.array_size.get() : 0;
+ const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader);
+
+ // Copy struct into buffer and advance offset
+ // We assume that header_buffer has been checked for nullptr before this
+ // method is called
+ memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
+ offset += elem_header_size;
+
+ // Starting offset of child ElementHeader struct
+ size_t child_offset =
+ offset + ((elem.children.size() + 1) * sizeof(uint32_t));
+ for (const RenderScriptRuntime::Element &child : elem.children) {
+ // Recursively populate the buffer with the element header structs of
+ // children. Then save the offsets where they were set after the parent
+ // element header.
+ memcpy(header_buffer.get() + offset, &child_offset, sizeof(uint32_t));
+ offset += sizeof(uint32_t);
+
+ child_offset = PopulateElementHeaders(header_buffer, child_offset, child);
+ }
+
+ // Zero indicates no more children
+ memset(header_buffer.get() + offset, 0, sizeof(uint32_t));
+
+ return child_offset;
+}
- // Check if the target allocation and file both have the same total data size.
- const uint32_t alloc_size = *alloc->size.get();
- if (alloc_size != length)
- {
- strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%" PRIx32 " bytes",
- (uint64_t)length, alloc_size);
- strm.EOL();
- length = alloc_size < length ? alloc_size : length; // Set length to copy to minimum
- }
+// Given an Element object this function returns the total size needed in the
+// file header to store the element's details. Taking into account the size of
+// the element header struct, plus the offsets to all the element's children.
+// Function is recursive so that the size of all ancestors is taken into
+// account.
+size_t RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem) {
+ // Offsets to children plus zero terminator
+ size_t size = (elem.children.size() + 1) * sizeof(uint32_t);
+ // Size of header struct with type details
+ size += sizeof(AllocationDetails::ElementHeader);
+
+ // Calculate recursively for all descendants
+ for (const Element &child : elem.children)
+ size += CalculateElementHeaderSize(child);
+
+ return size;
+}
- // Copy file data from our buffer into the target allocation.
- lldb::addr_t alloc_data = *alloc->data_ptr.get();
- Error error;
- size_t bytes_written = GetProcess()->WriteMemory(alloc_data, file_buffer, length, error);
- if (!error.Success() || bytes_written != length)
- {
- strm.Printf("Error: Couldn't write data to allocation %s", error.AsCString());
- strm.EOL();
- return false;
- }
+// Function copies allocation contents into a binary file. This file can then be
+// loaded later into a different allocation. There is a header, FileHeader,
+// before the allocation data containing meta-data.
+bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
+ const char *path,
+ StackFrame *frame_ptr) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ // Find allocation with the given id
+ AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
+ if (!alloc)
+ return false;
- strm.Printf("Contents of file '%s' read into allocation %" PRIu32, filename, alloc->id);
- strm.EOL();
+ if (log)
+ log->Printf("%s - found allocation 0x%" PRIx64 ".", __FUNCTION__,
+ *alloc->address.get());
- return true;
-}
+ // JIT all the allocation details
+ if (alloc->ShouldRefresh()) {
+ if (log)
+ log->Printf("%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
+
+ if (!RefreshAllocation(alloc, frame_ptr)) {
+ if (log)
+ log->Printf("%s - couldn't JIT allocation details.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() &&
+ alloc->element.type_vec_size.isValid() &&
+ alloc->element.datum_size.get() &&
+ alloc->element.type_kind.isValid() && alloc->dimension.isValid() &&
+ "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);
+ if (!file) {
+ strm.Printf("Error: Failed to open '%s' for writing", path);
+ strm.EOL();
+ return false;
+ }
-// Function takes as parameters a byte buffer, which will eventually be written to file as the element header,
-// an offset into that buffer, and an Element that will be saved into the buffer at the parametrised offset.
-// Return value is the new offset after writing the element into the buffer.
-// Elements are saved to the file as the ElementHeader struct followed by offsets to the structs of all the element's
-// children.
-size_t
-RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset,
- const Element &elem)
-{
- // File struct for an element header with all the relevant details copied from elem.
- // We assume members are valid already.
- AllocationDetails::ElementHeader elem_header;
- elem_header.type = *elem.type.get();
- elem_header.kind = *elem.type_kind.get();
- elem_header.element_size = *elem.datum_size.get();
- elem_header.vector_size = *elem.type_vec_size.get();
- elem_header.array_size = elem.array_size.isValid() ? *elem.array_size.get() : 0;
- const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader);
-
- // Copy struct into buffer and advance offset
- // We assume that header_buffer has been checked for nullptr before this method is called
- memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
- offset += elem_header_size;
-
- // Starting offset of child ElementHeader struct
- size_t child_offset = offset + ((elem.children.size() + 1) * sizeof(uint32_t));
- for (const RenderScriptRuntime::Element &child : elem.children)
- {
- // Recursively populate the buffer with the element header structs of children.
- // Then save the offsets where they were set after the parent element header.
- memcpy(header_buffer.get() + offset, &child_offset, sizeof(uint32_t));
- offset += sizeof(uint32_t);
+ // Read allocation into buffer of heap memory
+ const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
+ if (!buffer) {
+ strm.Printf("Error: Couldn't read allocation data into buffer");
+ strm.EOL();
+ return false;
+ }
+
+ // Create the file header
+ AllocationDetails::FileHeader head;
+ memcpy(head.ident, "RSAD", 4);
+ head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1);
+ head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2);
+ head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3);
+
+ const size_t element_header_size = CalculateElementHeaderSize(alloc->element);
+ assert((sizeof(AllocationDetails::FileHeader) + element_header_size) <
+ UINT16_MAX &&
+ "Element header too large");
+ head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader) +
+ element_header_size);
+
+ // Write the file header
+ size_t num_bytes = sizeof(AllocationDetails::FileHeader);
+ if (log)
+ log->Printf("%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__,
+ (uint64_t)num_bytes);
+
+ Error err = file.Write(&head, num_bytes);
+ if (!err.Success()) {
+ strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
+ strm.EOL();
+ return false;
+ }
+
+ // Create the headers describing the element type of the allocation.
+ std::shared_ptr<uint8_t> element_header_buffer(
+ new uint8_t[element_header_size]);
+ if (element_header_buffer == nullptr) {
+ strm.Printf("Internal Error: Couldn't allocate %" PRIu64
+ " bytes on the heap",
+ (uint64_t)element_header_size);
+ strm.EOL();
+ return false;
+ }
- child_offset = PopulateElementHeaders(header_buffer, child_offset, child);
- }
+ PopulateElementHeaders(element_header_buffer, 0, alloc->element);
- // Zero indicates no more children
- memset(header_buffer.get() + offset, 0, sizeof(uint32_t));
+ // Write headers for allocation element type to file
+ num_bytes = element_header_size;
+ if (log)
+ log->Printf("%s - writing element headers, 0x%" PRIx64 " bytes.",
+ __FUNCTION__, (uint64_t)num_bytes);
- return child_offset;
-}
+ err = file.Write(element_header_buffer.get(), num_bytes);
+ if (!err.Success()) {
+ strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
+ strm.EOL();
+ return false;
+ }
-// Given an Element object this function returns the total size needed in the file header to store the element's
-// details.
-// Taking into account the size of the element header struct, plus the offsets to all the element's children.
-// Function is recursive so that the size of all ancestors is taken into account.
-size_t
-RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem)
-{
- size_t size = (elem.children.size() + 1) * sizeof(uint32_t); // Offsets to children plus zero terminator
- size += sizeof(AllocationDetails::ElementHeader); // Size of header struct with type details
-
- // Calculate recursively for all descendants
- for (const Element &child : elem.children)
- size += CalculateElementHeaderSize(child);
-
- return size;
-}
+ // Write allocation data to file
+ num_bytes = static_cast<size_t>(*alloc->size.get());
+ if (log)
+ log->Printf("%s - writing 0x%" PRIx64 " bytes", __FUNCTION__,
+ (uint64_t)num_bytes);
-// Function copies allocation contents into a binary file.
-// This file can then be loaded later into a different allocation.
-// There is a header, FileHeader, before the allocation data containing meta-data.
-bool
-RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ err = file.Write(buffer.get(), num_bytes);
+ if (!err.Success()) {
+ strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
+ strm.EOL();
+ return false;
+ }
- // Find allocation with the given id
- AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
- if (!alloc)
- return false;
+ strm.Printf("Allocation written to file '%s'", path);
+ strm.EOL();
+ return true;
+}
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64 ".", __FUNCTION__, *alloc->address.get());
+bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- // JIT all the allocation details
- if (alloc->shouldRefresh())
- {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
+ if (module_sp) {
+ for (const auto &rs_module : m_rsmodules) {
+ if (rs_module->m_module == module_sp) {
+ // Check if the user has enabled automatically breaking on
+ // all RS kernels.
+ if (m_breakAllKernels)
+ BreakOnModuleKernels(rs_module);
- if (!RefreshAllocation(alloc, frame_ptr))
- {
+ return false;
+ }
+ }
+ bool module_loaded = false;
+ switch (GetModuleKind(module_sp)) {
+ case eModuleKindKernelObj: {
+ RSModuleDescriptorSP module_desc;
+ module_desc.reset(new RSModuleDescriptor(module_sp));
+ if (module_desc->ParseRSInfo()) {
+ m_rsmodules.push_back(module_desc);
+ module_loaded = true;
+ }
+ if (module_loaded) {
+ FixupScriptDetails(module_desc);
+ }
+ break;
+ }
+ case eModuleKindDriver: {
+ if (!m_libRSDriver) {
+ m_libRSDriver = module_sp;
+ LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
+ }
+ break;
+ }
+ case eModuleKindImpl: {
+ if (!m_libRSCpuRef) {
+ m_libRSCpuRef = module_sp;
+ LoadRuntimeHooks(m_libRSCpuRef, RenderScriptRuntime::eModuleKindImpl);
+ }
+ break;
+ }
+ case eModuleKindLibRS: {
+ if (!m_libRS) {
+ m_libRS = module_sp;
+ static ConstString gDbgPresentStr("gDebuggerPresent");
+ const Symbol *debug_present = m_libRS->FindFirstSymbolWithNameAndType(
+ gDbgPresentStr, eSymbolTypeData);
+ if (debug_present) {
+ Error err;
+ uint32_t flag = 0x00000001U;
+ Target &target = GetProcess()->GetTarget();
+ addr_t addr = debug_present->GetLoadAddress(&target);
+ GetProcess()->WriteMemory(addr, &flag, sizeof(flag), err);
+ if (err.Success()) {
if (log)
- log->Printf("%s - couldn't JIT allocation details.", __FUNCTION__);
- return false;
+ log->Printf("%s - debugger present flag set on debugee.",
+ __FUNCTION__);
+
+ m_debuggerPresentFlagged = true;
+ } else if (log) {
+ log->Printf("%s - error writing debugger present flags '%s' ",
+ __FUNCTION__, err.AsCString());
+ }
+ } else if (log) {
+ log->Printf(
+ "%s - error writing debugger present flags - symbol not found",
+ __FUNCTION__);
}
+ }
+ break;
}
-
- assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() &&
- alloc->element.datum_size.get() && alloc->element.type_kind.isValid() && alloc->dimension.isValid() &&
- "Allocation information not available");
-
- // Check we can create writable file
- FileSpec file_spec(filename, true);
- File file(file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionTruncate);
- if (!file)
- {
- strm.Printf("Error: Failed to open '%s' for writing", filename);
- strm.EOL();
- return false;
+ default:
+ break;
}
+ if (module_loaded)
+ Update();
+ return module_loaded;
+ }
+ return false;
+}
- // Read allocation into buffer of heap memory
- const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
- if (!buffer)
- {
- strm.Printf("Error: Couldn't read allocation data into buffer");
- strm.EOL();
- return false;
+void RenderScriptRuntime::Update() {
+ if (m_rsmodules.size() > 0) {
+ if (!m_initiated) {
+ Initiate();
}
+ }
+}
- // Create the file header
- AllocationDetails::FileHeader head;
- memcpy(head.ident, "RSAD", 4);
- head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1);
- head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2);
- head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3);
-
- const size_t element_header_size = CalculateElementHeaderSize(alloc->element);
- assert((sizeof(AllocationDetails::FileHeader) + element_header_size) < UINT16_MAX && "Element header too large");
- head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader) + element_header_size);
-
- // Write the file header
- size_t num_bytes = sizeof(AllocationDetails::FileHeader);
- if (log)
- log->Printf("%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes);
+bool RSModuleDescriptor::ParsePragmaCount(llvm::StringRef *lines,
+ size_t n_lines) {
+ // Skip the pragma prototype line
+ ++lines;
+ for (; n_lines--; ++lines) {
+ const auto kv_pair = lines->split(" - ");
+ m_pragmas[kv_pair.first.trim().str()] = kv_pair.second.trim().str();
+ }
+ return true;
+}
- Error err = file.Write(&head, num_bytes);
- if (!err.Success())
- {
- strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
- strm.EOL();
+bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines,
+ size_t n_lines) {
+ // The list of reduction kernels in the `.rs.info` symbol is of the form
+ // "signature - accumulatordatasize - reduction_name - initializer_name -
+ // accumulator_name - combiner_name -
+ // outconverter_name - halter_name"
+ // Where a function is not explicitly named by the user, or is not generated
+ // by the compiler, it is named "." so the
+ // dash separated list should always be 8 items long
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+ // Skip the exportReduceCount line
+ ++lines;
+ for (; n_lines--; ++lines) {
+ llvm::SmallVector<llvm::StringRef, 8> spec;
+ lines->split(spec, " - ");
+ if (spec.size() != 8) {
+ if (spec.size() < 8) {
+ if (log)
+ log->Error("Error parsing RenderScript reduction spec. wrong number "
+ "of fields");
return false;
+ } else if (log)
+ log->Warning("Extraneous members in reduction spec: '%s'",
+ lines->str().c_str());
}
- // Create the headers describing the element type of the allocation.
- std::shared_ptr<uint8_t> element_header_buffer(new uint8_t[element_header_size]);
- if (element_header_buffer == nullptr)
- {
- strm.Printf("Internal Error: Couldn't allocate %" PRIu64 " bytes on the heap", (uint64_t)element_header_size);
- strm.EOL();
- return false;
+ const auto sig_s = spec[0];
+ uint32_t sig;
+ if (sig_s.getAsInteger(10, sig)) {
+ if (log)
+ log->Error("Error parsing Renderscript reduction spec: invalid kernel "
+ "signature: '%s'",
+ sig_s.str().c_str());
+ return false;
}
- PopulateElementHeaders(element_header_buffer, 0, alloc->element);
-
- // Write headers for allocation element type to file
- num_bytes = element_header_size;
- if (log)
- log->Printf("%s - writing element headers, 0x%" PRIx64 " bytes.", __FUNCTION__, (uint64_t)num_bytes);
-
- err = file.Write(element_header_buffer.get(), num_bytes);
- if (!err.Success())
- {
- strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
- strm.EOL();
- return false;
+ const auto accum_data_size_s = spec[1];
+ uint32_t accum_data_size;
+ if (accum_data_size_s.getAsInteger(10, accum_data_size)) {
+ if (log)
+ log->Error("Error parsing Renderscript reduction spec: invalid "
+ "accumulator data size %s",
+ accum_data_size_s.str().c_str());
+ return false;
}
- // Write allocation data to file
- num_bytes = static_cast<size_t>(*alloc->size.get());
if (log)
- log->Printf("%s - writing 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes);
+ log->Printf("Found RenderScript reduction '%s'", spec[2].str().c_str());
- err = file.Write(buffer.get(), num_bytes);
- if (!err.Success())
- {
- strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
- strm.EOL();
- return false;
- }
-
- strm.Printf("Allocation written to file '%s'", filename);
- strm.EOL();
- return true;
+ m_reductions.push_back(RSReductionDescriptor(this, sig, accum_data_size,
+ spec[2], spec[3], spec[4],
+ spec[5], spec[6], spec[7]));
+ }
+ return true;
}
-bool
-RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- if (module_sp)
- {
- for (const auto &rs_module : m_rsmodules)
- {
- if (rs_module->m_module == module_sp)
- {
- // Check if the user has enabled automatically breaking on
- // all RS kernels.
- if (m_breakAllKernels)
- BreakOnModuleKernels(rs_module);
-
- return false;
- }
- }
- bool module_loaded = false;
- switch (GetModuleKind(module_sp))
- {
- case eModuleKindKernelObj:
- {
- RSModuleDescriptorSP module_desc;
- module_desc.reset(new RSModuleDescriptor(module_sp));
- if (module_desc->ParseRSInfo())
- {
- m_rsmodules.push_back(module_desc);
- module_loaded = true;
- }
- if (module_loaded)
- {
- FixupScriptDetails(module_desc);
- }
- break;
- }
- case eModuleKindDriver:
- {
- if (!m_libRSDriver)
- {
- m_libRSDriver = module_sp;
- LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
- }
- break;
- }
- case eModuleKindImpl:
- {
- m_libRSCpuRef = module_sp;
- break;
- }
- case eModuleKindLibRS:
- {
- if (!m_libRS)
- {
- m_libRS = module_sp;
- static ConstString gDbgPresentStr("gDebuggerPresent");
- const Symbol *debug_present =
- m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
- if (debug_present)
- {
- Error error;
- uint32_t flag = 0x00000001U;
- Target &target = GetProcess()->GetTarget();
- addr_t addr = debug_present->GetLoadAddress(&target);
- GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
- if (error.Success())
- {
- if (log)
- log->Printf("%s - debugger present flag set on debugee.", __FUNCTION__);
-
- m_debuggerPresentFlagged = true;
- }
- else if (log)
- {
- log->Printf("%s - error writing debugger present flags '%s' ", __FUNCTION__,
- error.AsCString());
- }
- }
- else if (log)
- {
- log->Printf("%s - error writing debugger present flags - symbol not found", __FUNCTION__);
- }
- }
- break;
- }
- default:
- break;
- }
- if (module_loaded)
- Update();
- return module_loaded;
- }
- return false;
+bool RSModuleDescriptor::ParseExportForeachCount(llvm::StringRef *lines,
+ size_t n_lines) {
+ // Skip the exportForeachCount line
+ ++lines;
+ for (; n_lines--; ++lines) {
+ uint32_t slot;
+ // `forEach` kernels are listed in the `.rs.info` packet as a "slot - name"
+ // pair per line
+ const auto kv_pair = lines->split(" - ");
+ if (kv_pair.first.getAsInteger(10, slot))
+ return false;
+ m_kernels.push_back(RSKernelDescriptor(this, kv_pair.second, slot));
+ }
+ return true;
}
-void
-RenderScriptRuntime::Update()
-{
- if (m_rsmodules.size() > 0)
- {
- if (!m_initiated)
- {
- Initiate();
- }
- }
+bool RSModuleDescriptor::ParseExportVarCount(llvm::StringRef *lines,
+ size_t n_lines) {
+ // Skip the ExportVarCount line
+ ++lines;
+ for (; n_lines--; ++lines)
+ m_globals.push_back(RSGlobalDescriptor(this, *lines));
+ return true;
}
-// The maximum line length of an .rs.info packet
-#define MAXLINE 500
-#define STRINGIFY(x) #x
-#define MAXLINESTR_(x) "%" STRINGIFY(x) "s"
-#define MAXLINESTR MAXLINESTR_(MAXLINE)
-
-// The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
+// The .rs.info symbol in renderscript modules contains a string which needs to
+// be parsed.
// The string is basic and is parsed on a line by line basis.
-bool
-RSModuleDescriptor::ParseRSInfo()
-{
- assert(m_module);
- const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
- if (!info_sym)
- return false;
-
- const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
- if (addr == LLDB_INVALID_ADDRESS)
- return false;
+bool RSModuleDescriptor::ParseRSInfo() {
+ assert(m_module);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(
+ ConstString(".rs.info"), eSymbolTypeData);
+ if (!info_sym)
+ return false;
- const addr_t size = info_sym->GetByteSize();
- const FileSpec fs = m_module->GetFileSpec();
+ const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
- const DataBufferSP buffer = fs.ReadFileContents(addr, size);
- if (!buffer)
- return false;
+ const addr_t size = info_sym->GetByteSize();
+ const FileSpec fs = m_module->GetFileSpec();
- // split rs.info. contents into lines
- std::vector<std::string> info_lines;
- {
- const std::string info((const char *)buffer->GetBytes());
- for (size_t tail = 0; tail < info.size();)
- {
- // find next new line or end of string
- size_t head = info.find('\n', tail);
- head = (head == std::string::npos) ? info.size() : head;
- std::string line = info.substr(tail, head - tail);
- // add to line list
- info_lines.push_back(line);
- tail = head + 1;
- }
- }
+ const DataBufferSP buffer = fs.ReadFileContents(addr, size);
+ if (!buffer)
+ return false;
- std::array<char, MAXLINE> name{{'\0'}};
- std::array<char, MAXLINE> value{{'\0'}};
+ // split rs.info. contents into lines
+ llvm::SmallVector<llvm::StringRef, 128> info_lines;
+ {
+ const llvm::StringRef raw_rs_info((const char *)buffer->GetBytes());
+ raw_rs_info.split(info_lines, '\n');
+ if (log)
+ log->Printf("'.rs.info symbol for '%s':\n%s",
+ m_module->GetFileSpec().GetCString(),
+ raw_rs_info.str().c_str());
+ }
+
+ enum {
+ eExportVar,
+ eExportForEach,
+ eExportReduce,
+ ePragma,
+ eBuildChecksum,
+ eObjectSlot
+ };
+
+ const auto rs_info_handler = [](llvm::StringRef name) -> int {
+ return llvm::StringSwitch<int>(name)
+ // The number of visible global variables in the script
+ .Case("exportVarCount", eExportVar)
+ // The number of RenderScrip `forEach` kernels __attribute__((kernel))
+ .Case("exportForEachCount", eExportForEach)
+ // The number of generalreductions: This marked in the script by
+ // `#pragma reduce()`
+ .Case("exportReduceCount", eExportReduce)
+ // Total count of all RenderScript specific `#pragmas` used in the
+ // script
+ .Case("pragmaCount", ePragma)
+ .Case("objectSlotCount", eObjectSlot)
+ .Default(-1);
+ };
+
+ // parse all text lines of .rs.info
+ for (auto line = info_lines.begin(); line != info_lines.end(); ++line) {
+ const auto kv_pair = line->split(": ");
+ const auto key = kv_pair.first;
+ const auto val = kv_pair.second.trim();
+
+ const auto handler = rs_info_handler(key);
+ if (handler == -1)
+ continue;
+ // getAsInteger returns `true` on an error condition - we're only interested
+ // in numeric fields at the moment
+ uint64_t n_lines;
+ if (val.getAsInteger(10, n_lines)) {
+ if (log)
+ log->Debug("Failed to parse non-numeric '.rs.info' section %s",
+ line->str().c_str());
+ continue;
+ }
+ if (info_lines.end() - (line + 1) < (ptrdiff_t)n_lines)
+ return false;
- // parse all text lines of .rs.info
- for (auto line = info_lines.begin(); line != info_lines.end(); ++line)
- {
- uint32_t numDefns = 0;
- if (sscanf(line->c_str(), "exportVarCount: %" PRIu32 "", &numDefns) == 1)
- {
- while (numDefns--)
- m_globals.push_back(RSGlobalDescriptor(this, (++line)->c_str()));
- }
- else if (sscanf(line->c_str(), "exportForEachCount: %" PRIu32 "", &numDefns) == 1)
- {
- while (numDefns--)
- {
- uint32_t slot = 0;
- name[0] = '\0';
- static const char *fmt_s = "%" PRIu32 " - " MAXLINESTR;
- if (sscanf((++line)->c_str(), fmt_s, &slot, name.data()) == 2)
- {
- if (name[0] != '\0')
- m_kernels.push_back(RSKernelDescriptor(this, name.data(), slot));
- }
- }
- }
- else if (sscanf(line->c_str(), "pragmaCount: %" PRIu32 "", &numDefns) == 1)
- {
- while (numDefns--)
- {
- name[0] = value[0] = '\0';
- static const char *fmt_s = MAXLINESTR " - " MAXLINESTR;
- if (sscanf((++line)->c_str(), fmt_s, name.data(), value.data()) != 0)
- {
- if (name[0] != '\0')
- m_pragmas[std::string(name.data())] = value.data();
- }
- }
- }
- else
- {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- {
- log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__, line->c_str());
- }
- }
+ bool success = false;
+ switch (handler) {
+ case eExportVar:
+ success = ParseExportVarCount(line, n_lines);
+ break;
+ case eExportForEach:
+ success = ParseExportForeachCount(line, n_lines);
+ break;
+ case eExportReduce:
+ success = ParseExportReduceCount(line, n_lines);
+ break;
+ case ePragma:
+ success = ParsePragmaCount(line, n_lines);
+ break;
+ default: {
+ if (log)
+ log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__,
+ line->str().c_str());
+ continue;
}
-
- // 'root' kernel should always be present
- return m_kernels.size() > 0;
+ }
+ if (!success)
+ return false;
+ line += n_lines;
+ }
+ return info_lines.size() > 0;
}
-void
-RenderScriptRuntime::Status(Stream &strm) const
-{
- if (m_libRS)
- {
- strm.Printf("Runtime Library discovered.");
- strm.EOL();
- }
- if (m_libRSDriver)
- {
- strm.Printf("Runtime Driver discovered.");
- strm.EOL();
- }
- if (m_libRSCpuRef)
- {
- strm.Printf("CPU Reference Implementation discovered.");
- strm.EOL();
- }
+void RenderScriptRuntime::Status(Stream &strm) const {
+ if (m_libRS) {
+ strm.Printf("Runtime Library discovered.");
+ strm.EOL();
+ }
+ if (m_libRSDriver) {
+ strm.Printf("Runtime Driver discovered.");
+ strm.EOL();
+ }
+ if (m_libRSCpuRef) {
+ strm.Printf("CPU Reference Implementation discovered.");
+ strm.EOL();
+ }
- if (m_runtimeHooks.size())
- {
- strm.Printf("Runtime functions hooked:");
- strm.EOL();
- for (auto b : m_runtimeHooks)
- {
- strm.Indent(b.second->defn->name);
- strm.EOL();
- }
- }
- else
- {
- strm.Printf("Runtime is not hooked.");
- strm.EOL();
+ if (m_runtimeHooks.size()) {
+ strm.Printf("Runtime functions hooked:");
+ strm.EOL();
+ for (auto b : m_runtimeHooks) {
+ strm.Indent(b.second->defn->name);
+ strm.EOL();
}
+ } else {
+ strm.Printf("Runtime is not hooked.");
+ strm.EOL();
+ }
}
-void
-RenderScriptRuntime::DumpContexts(Stream &strm) const
-{
- strm.Printf("Inferred RenderScript Contexts:");
- strm.EOL();
- strm.IndentMore();
+void RenderScriptRuntime::DumpContexts(Stream &strm) const {
+ strm.Printf("Inferred RenderScript Contexts:");
+ strm.EOL();
+ strm.IndentMore();
- std::map<addr_t, uint64_t> contextReferences;
+ std::map<addr_t, uint64_t> contextReferences;
- // Iterate over all of the currently discovered scripts.
- // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script.
- for (const auto &script : m_scripts)
- {
- if (!script->context.isValid())
- continue;
- lldb::addr_t context = *script->context;
+ // Iterate over all of the currently discovered scripts.
+ // Note: We cant push or pop from m_scripts inside this loop or it may
+ // invalidate script.
+ for (const auto &script : m_scripts) {
+ if (!script->context.isValid())
+ continue;
+ lldb::addr_t context = *script->context;
- if (contextReferences.find(context) != contextReferences.end())
- {
- contextReferences[context]++;
- }
- else
- {
- contextReferences[context] = 1;
- }
+ if (contextReferences.find(context) != contextReferences.end()) {
+ contextReferences[context]++;
+ } else {
+ contextReferences[context] = 1;
}
+ }
- for (const auto &cRef : contextReferences)
- {
- strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
- strm.EOL();
- }
- strm.IndentLess();
+ for (const auto &cRef : contextReferences) {
+ strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances",
+ cRef.first, cRef.second);
+ strm.EOL();
+ }
+ strm.IndentLess();
}
-void
-RenderScriptRuntime::DumpKernels(Stream &strm) const
-{
- strm.Printf("RenderScript Kernels:");
+void RenderScriptRuntime::DumpKernels(Stream &strm) const {
+ strm.Printf("RenderScript Kernels:");
+ strm.EOL();
+ strm.IndentMore();
+ for (const auto &module : m_rsmodules) {
+ strm.Printf("Resource '%s':", module->m_resname.c_str());
strm.EOL();
- strm.IndentMore();
- for (const auto &module : m_rsmodules)
- {
- strm.Printf("Resource '%s':", module->m_resname.c_str());
- strm.EOL();
- for (const auto &kernel : module->m_kernels)
- {
- strm.Indent(kernel.m_name.AsCString());
- strm.EOL();
- }
+ for (const auto &kernel : module->m_kernels) {
+ strm.Indent(kernel.m_name.AsCString());
+ strm.EOL();
}
- strm.IndentLess();
+ }
+ strm.IndentLess();
}
RenderScriptRuntime::AllocationDetails *
-RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id)
-{
- AllocationDetails *alloc = nullptr;
-
- // See if we can find allocation using id as an index;
- if (alloc_id <= m_allocations.size() && alloc_id != 0 && m_allocations[alloc_id - 1]->id == alloc_id)
- {
- alloc = m_allocations[alloc_id - 1].get();
- return alloc;
- }
-
- // Fallback to searching
- for (const auto &a : m_allocations)
- {
- if (a->id == alloc_id)
- {
- alloc = a.get();
- break;
- }
- }
-
- if (alloc == nullptr)
- {
- strm.Printf("Error: Couldn't find allocation with id matching %" PRIu32, alloc_id);
- strm.EOL();
- }
+RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id) {
+ AllocationDetails *alloc = nullptr;
+ // See if we can find allocation using id as an index;
+ if (alloc_id <= m_allocations.size() && alloc_id != 0 &&
+ m_allocations[alloc_id - 1]->id == alloc_id) {
+ alloc = m_allocations[alloc_id - 1].get();
return alloc;
-}
-
-// Prints the contents of an allocation to the output stream, which may be a file
-bool
-RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- // Check we can find the desired allocation
- AllocationDetails *alloc = FindAllocByID(strm, id);
- if (!alloc)
- return false; // FindAllocByID() will print error message for us here
+ }
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__, *alloc->address.get());
-
- // Check we have information about the allocation, if not calculate it
- if (alloc->shouldRefresh())
- {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
-
- // JIT all the allocation information
- if (!RefreshAllocation(alloc, frame_ptr))
- {
- strm.Printf("Error: Couldn't JIT allocation details");
- strm.EOL();
- return false;
- }
+ // Fallback to searching
+ for (const auto &a : m_allocations) {
+ if (a->id == alloc_id) {
+ alloc = a.get();
+ break;
}
+ }
- // Establish format and size of each data element
- const uint32_t vec_size = *alloc->element.type_vec_size.get();
- const Element::DataType type = *alloc->element.type.get();
-
- assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && "Invalid allocation type");
+ if (alloc == nullptr) {
+ strm.Printf("Error: Couldn't find allocation with id matching %" PRIu32,
+ alloc_id);
+ strm.EOL();
+ }
- lldb::Format format;
- if (type >= Element::RS_TYPE_ELEMENT)
- format = eFormatHex;
- else
- format = vec_size == 1 ? static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle])
- : static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]);
+ return alloc;
+}
- const uint32_t data_size = *alloc->element.datum_size.get();
+// Prints the contents of an allocation to the output stream, which may be a
+// file
+bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
+ const uint32_t id) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- log->Printf("%s - element size %" PRIu32 " bytes, including padding", __FUNCTION__, data_size);
+ // Check we can find the desired allocation
+ AllocationDetails *alloc = FindAllocByID(strm, id);
+ if (!alloc)
+ return false; // FindAllocByID() will print error message for us here
- // Allocate a buffer to copy data into
- std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
- if (!buffer)
- {
- strm.Printf("Error: Couldn't read allocation data");
- strm.EOL();
- return false;
- }
+ if (log)
+ log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__,
+ *alloc->address.get());
- // Calculate stride between rows as there may be padding at end of rows since
- // allocated memory is 16-byte aligned
- if (!alloc->stride.isValid())
- {
- if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension
- alloc->stride = 0;
- else if (!JITAllocationStride(alloc, frame_ptr))
- {
- strm.Printf("Error: Couldn't calculate allocation row stride");
- strm.EOL();
- return false;
- }
- }
- const uint32_t stride = *alloc->stride.get();
- const uint32_t size = *alloc->size.get(); // Size of whole allocation
- const uint32_t padding = alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
+ // Check we have information about the allocation, if not calculate it
+ if (alloc->ShouldRefresh()) {
if (log)
- log->Printf("%s - stride %" PRIu32 " bytes, size %" PRIu32 " bytes, padding %" PRIu32,
- __FUNCTION__, stride, size, padding);
-
- // Find dimensions used to index loops, so need to be non-zero
- uint32_t dim_x = alloc->dimension.get()->dim_1;
- dim_x = dim_x == 0 ? 1 : dim_x;
-
- uint32_t dim_y = alloc->dimension.get()->dim_2;
- dim_y = dim_y == 0 ? 1 : dim_y;
-
- uint32_t dim_z = alloc->dimension.get()->dim_3;
- dim_z = dim_z == 0 ? 1 : dim_z;
-
- // Use data extractor to format output
- const uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
- DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), archByteSize);
-
- uint32_t offset = 0; // Offset in buffer to next element to be printed
- uint32_t prev_row = 0; // Offset to the start of the previous row
-
- // Iterate over allocation dimensions, printing results to user
- strm.Printf("Data (X, Y, Z):");
- for (uint32_t z = 0; z < dim_z; ++z)
- {
- for (uint32_t y = 0; y < dim_y; ++y)
- {
- // Use stride to index start of next row.
- if (!(y == 0 && z == 0))
- offset = prev_row + stride;
- prev_row = offset;
-
- // Print each element in the row individually
- for (uint32_t x = 0; x < dim_x; ++x)
- {
- strm.Printf("\n(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") = ", x, y, z);
- if ((type == Element::RS_TYPE_NONE) && (alloc->element.children.size() > 0) &&
- (alloc->element.type_name != Element::GetFallbackStructName()))
- {
- // Here we are dumping an Element of struct type.
- // This is done using expression evaluation with the name of the struct type and pointer to element.
-
- // Don't print the name of the resulting expression, since this will be '$[0-9]+'
- DumpValueObjectOptions expr_options;
- expr_options.SetHideName(true);
-
- // Setup expression as derefrencing a pointer cast to element address.
- char expr_char_buffer[jit_max_expr_size];
- int chars_written = snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64,
- alloc->element.type_name.AsCString(), *alloc->data_ptr.get() + offset);
-
- if (chars_written < 0 || chars_written >= jit_max_expr_size)
- {
- if (log)
- log->Printf("%s - error in snprintf().", __FUNCTION__);
- continue;
- }
-
- // Evaluate expression
- ValueObjectSP expr_result;
- GetProcess()->GetTarget().EvaluateExpression(expr_char_buffer, frame_ptr, expr_result);
-
- // Print the results to our stream.
- expr_result->Dump(strm, expr_options);
- }
- else
- {
- alloc_data.Dump(&strm, offset, format, data_size - padding, 1, 1, LLDB_INVALID_ADDRESS, 0, 0);
- }
- offset += data_size;
- }
- }
- }
+ log->Printf("%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
+
+ // JIT all the allocation information
+ if (!RefreshAllocation(alloc, frame_ptr)) {
+ strm.Printf("Error: Couldn't JIT allocation details");
+ strm.EOL();
+ return false;
+ }
+ }
+
+ // Establish format and size of each data element
+ const uint32_t vec_size = *alloc->element.type_vec_size.get();
+ const Element::DataType type = *alloc->element.type.get();
+
+ assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT &&
+ "Invalid allocation type");
+
+ lldb::Format format;
+ if (type >= Element::RS_TYPE_ELEMENT)
+ format = eFormatHex;
+ else
+ format = vec_size == 1
+ ? static_cast<lldb::Format>(
+ AllocationDetails::RSTypeToFormat[type][eFormatSingle])
+ : static_cast<lldb::Format>(
+ AllocationDetails::RSTypeToFormat[type][eFormatVector]);
+
+ const uint32_t data_size = *alloc->element.datum_size.get();
+
+ if (log)
+ log->Printf("%s - element size %" PRIu32 " bytes, including padding",
+ __FUNCTION__, data_size);
+
+ // Allocate a buffer to copy data into
+ std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
+ if (!buffer) {
+ strm.Printf("Error: Couldn't read allocation data");
strm.EOL();
-
- return true;
-}
-
-// Function recalculates all our cached information about allocations by jitting the
-// RS runtime regarding each allocation we know about.
-// Returns true if all allocations could be recomputed, false otherwise.
-bool
-RenderScriptRuntime::RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr)
-{
- bool success = true;
- for (auto &alloc : m_allocations)
- {
- // JIT current allocation information
- if (!RefreshAllocation(alloc.get(), frame_ptr))
- {
- strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32 "\n", alloc->id);
- success = false;
+ return false;
+ }
+
+ // Calculate stride between rows as there may be padding at end of rows since
+ // allocated memory is 16-byte aligned
+ if (!alloc->stride.isValid()) {
+ if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension
+ alloc->stride = 0;
+ else if (!JITAllocationStride(alloc, frame_ptr)) {
+ strm.Printf("Error: Couldn't calculate allocation row stride");
+ strm.EOL();
+ return false;
+ }
+ }
+ const uint32_t stride = *alloc->stride.get();
+ const uint32_t size = *alloc->size.get(); // Size of whole allocation
+ const uint32_t padding =
+ alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
+ if (log)
+ log->Printf("%s - stride %" PRIu32 " bytes, size %" PRIu32
+ " bytes, padding %" PRIu32,
+ __FUNCTION__, stride, size, padding);
+
+ // Find dimensions used to index loops, so need to be non-zero
+ uint32_t dim_x = alloc->dimension.get()->dim_1;
+ dim_x = dim_x == 0 ? 1 : dim_x;
+
+ uint32_t dim_y = alloc->dimension.get()->dim_2;
+ dim_y = dim_y == 0 ? 1 : dim_y;
+
+ uint32_t dim_z = alloc->dimension.get()->dim_3;
+ dim_z = dim_z == 0 ? 1 : dim_z;
+
+ // Use data extractor to format output
+ const uint32_t target_ptr_size =
+ GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
+ DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(),
+ target_ptr_size);
+
+ uint32_t offset = 0; // Offset in buffer to next element to be printed
+ uint32_t prev_row = 0; // Offset to the start of the previous row
+
+ // Iterate over allocation dimensions, printing results to user
+ strm.Printf("Data (X, Y, Z):");
+ for (uint32_t z = 0; z < dim_z; ++z) {
+ for (uint32_t y = 0; y < dim_y; ++y) {
+ // Use stride to index start of next row.
+ if (!(y == 0 && z == 0))
+ offset = prev_row + stride;
+ prev_row = offset;
+
+ // Print each element in the row individually
+ for (uint32_t x = 0; x < dim_x; ++x) {
+ strm.Printf("\n(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") = ", x, y, z);
+ if ((type == Element::RS_TYPE_NONE) &&
+ (alloc->element.children.size() > 0) &&
+ (alloc->element.type_name != Element::GetFallbackStructName())) {
+ // Here we are dumping an Element of struct type.
+ // This is done using expression evaluation with the name of the
+ // struct type and pointer to element.
+ // Don't print the name of the resulting expression, since this will
+ // be '$[0-9]+'
+ DumpValueObjectOptions expr_options;
+ expr_options.SetHideName(true);
+
+ // Setup expression as derefrencing a pointer cast to element address.
+ char expr_char_buffer[jit_max_expr_size];
+ int written =
+ snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64,
+ alloc->element.type_name.AsCString(),
+ *alloc->data_ptr.get() + offset);
+
+ if (written < 0 || written >= jit_max_expr_size) {
+ if (log)
+ log->Printf("%s - error in snprintf().", __FUNCTION__);
+ continue;
+ }
+
+ // Evaluate expression
+ ValueObjectSP expr_result;
+ GetProcess()->GetTarget().EvaluateExpression(expr_char_buffer,
+ frame_ptr, expr_result);
+
+ // Print the results to our stream.
+ expr_result->Dump(strm, expr_options);
+ } else {
+ alloc_data.Dump(&strm, offset, format, data_size - padding, 1, 1,
+ LLDB_INVALID_ADDRESS, 0, 0);
}
+ offset += data_size;
+ }
}
+ }
+ strm.EOL();
- if (success)
- strm.Printf("All allocations successfully recomputed");
- strm.EOL();
+ return true;
+}
- return success;
+// Function recalculates all our cached information about allocations by jitting
+// the RS runtime regarding each allocation we know about. Returns true if all
+// allocations could be recomputed, false otherwise.
+bool RenderScriptRuntime::RecomputeAllAllocations(Stream &strm,
+ StackFrame *frame_ptr) {
+ bool success = true;
+ for (auto &alloc : m_allocations) {
+ // JIT current allocation information
+ if (!RefreshAllocation(alloc.get(), frame_ptr)) {
+ strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32
+ "\n",
+ alloc->id);
+ success = false;
+ }
+ }
+
+ if (success)
+ strm.Printf("All allocations successfully recomputed");
+ strm.EOL();
+
+ return success;
}
-// Prints information regarding currently loaded allocations.
-// These details are gathered by jitting the runtime, which has as latency.
-// Index parameter specifies a single allocation ID to print, or a zero value to print them all
-void
-RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame *frame_ptr, const uint32_t index)
-{
- strm.Printf("RenderScript Allocations:");
+// Prints information regarding currently loaded allocations. These details are
+// gathered by jitting the runtime, which has as latency. Index parameter
+// specifies a single allocation ID to print, or a zero value to print them all
+void RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame *frame_ptr,
+ const uint32_t index) {
+ strm.Printf("RenderScript Allocations:");
+ strm.EOL();
+ strm.IndentMore();
+
+ for (auto &alloc : m_allocations) {
+ // index will only be zero if we want to print all allocations
+ if (index != 0 && index != alloc->id)
+ continue;
+
+ // JIT current allocation information
+ if (alloc->ShouldRefresh() && !RefreshAllocation(alloc.get(), frame_ptr)) {
+ strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32,
+ alloc->id);
+ strm.EOL();
+ continue;
+ }
+
+ strm.Printf("%" PRIu32 ":", alloc->id);
strm.EOL();
strm.IndentMore();
- for (auto &alloc : m_allocations)
- {
- // index will only be zero if we want to print all allocations
- if (index != 0 && index != alloc->id)
- continue;
-
- // JIT current allocation information
- if (alloc->shouldRefresh() && !RefreshAllocation(alloc.get(), frame_ptr))
- {
- strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32, alloc->id);
- strm.EOL();
- continue;
- }
-
- strm.Printf("%" PRIu32 ":", alloc->id);
- strm.EOL();
- strm.IndentMore();
-
- strm.Indent("Context: ");
- if (!alloc->context.isValid())
- strm.Printf("unknown\n");
- else
- strm.Printf("0x%" PRIx64 "\n", *alloc->context.get());
-
- strm.Indent("Address: ");
- if (!alloc->address.isValid())
- strm.Printf("unknown\n");
- else
- strm.Printf("0x%" PRIx64 "\n", *alloc->address.get());
-
- strm.Indent("Data pointer: ");
- if (!alloc->data_ptr.isValid())
- strm.Printf("unknown\n");
- else
- strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get());
+ strm.Indent("Context: ");
+ if (!alloc->context.isValid())
+ strm.Printf("unknown\n");
+ else
+ strm.Printf("0x%" PRIx64 "\n", *alloc->context.get());
- strm.Indent("Dimensions: ");
- if (!alloc->dimension.isValid())
- strm.Printf("unknown\n");
- else
- strm.Printf("(%" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
- alloc->dimension.get()->dim_1, alloc->dimension.get()->dim_2, alloc->dimension.get()->dim_3);
+ strm.Indent("Address: ");
+ if (!alloc->address.isValid())
+ strm.Printf("unknown\n");
+ else
+ strm.Printf("0x%" PRIx64 "\n", *alloc->address.get());
- strm.Indent("Data Type: ");
- if (!alloc->element.type.isValid() || !alloc->element.type_vec_size.isValid())
- strm.Printf("unknown\n");
- else
- {
- const int vector_size = *alloc->element.type_vec_size.get();
- Element::DataType type = *alloc->element.type.get();
-
- if (!alloc->element.type_name.IsEmpty())
- strm.Printf("%s\n", alloc->element.type_name.AsCString());
- else
- {
- // Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
- if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT)
- type = static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) +
- Element::RS_TYPE_MATRIX_2X2 + 1);
-
- if (type >= (sizeof(AllocationDetails::RsDataTypeToString) /
- sizeof(AllocationDetails::RsDataTypeToString[0])) ||
- vector_size > 4 || vector_size < 1)
- strm.Printf("invalid type\n");
- else
- strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<uint32_t>(type)]
- [vector_size - 1]);
- }
- }
+ strm.Indent("Data pointer: ");
+ if (!alloc->data_ptr.isValid())
+ strm.Printf("unknown\n");
+ else
+ strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get());
- strm.Indent("Data Kind: ");
- if (!alloc->element.type_kind.isValid())
- strm.Printf("unknown\n");
+ strm.Indent("Dimensions: ");
+ if (!alloc->dimension.isValid())
+ strm.Printf("unknown\n");
+ else
+ strm.Printf("(%" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
+ alloc->dimension.get()->dim_1, alloc->dimension.get()->dim_2,
+ alloc->dimension.get()->dim_3);
+
+ strm.Indent("Data Type: ");
+ if (!alloc->element.type.isValid() ||
+ !alloc->element.type_vec_size.isValid())
+ strm.Printf("unknown\n");
+ else {
+ const int vector_size = *alloc->element.type_vec_size.get();
+ Element::DataType type = *alloc->element.type.get();
+
+ if (!alloc->element.type_name.IsEmpty())
+ strm.Printf("%s\n", alloc->element.type_name.AsCString());
+ else {
+ // Enum value isn't monotonous, so doesn't always index
+ // RsDataTypeToString array
+ if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT)
+ type =
+ static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
+
+ if (type >= (sizeof(AllocationDetails::RsDataTypeToString) /
+ sizeof(AllocationDetails::RsDataTypeToString[0])) ||
+ vector_size > 4 || vector_size < 1)
+ strm.Printf("invalid type\n");
else
- {
- const Element::DataKind kind = *alloc->element.type_kind.get();
- if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV)
- strm.Printf("invalid kind\n");
- else
- strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<uint32_t>(kind)]);
- }
-
- strm.EOL();
- strm.IndentLess();
+ strm.Printf(
+ "%s\n",
+ AllocationDetails::RsDataTypeToString[static_cast<uint32_t>(type)]
+ [vector_size - 1]);
+ }
+ }
+
+ strm.Indent("Data Kind: ");
+ if (!alloc->element.type_kind.isValid())
+ strm.Printf("unknown\n");
+ else {
+ const Element::DataKind kind = *alloc->element.type_kind.get();
+ if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV)
+ strm.Printf("invalid kind\n");
+ else
+ strm.Printf(
+ "%s\n",
+ AllocationDetails::RsDataKindToString[static_cast<uint32_t>(kind)]);
}
+
+ strm.EOL();
strm.IndentLess();
+ }
+ strm.IndentLess();
}
// Set breakpoints on every kernel found in RS module
-void
-RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
-{
- for (const auto &kernel : rsmodule_sp->m_kernels)
- {
- // Don't set breakpoint on 'root' kernel
- if (strcmp(kernel.m_name.AsCString(), "root") == 0)
- continue;
-
- CreateKernelBreakpoint(kernel.m_name);
- }
+void RenderScriptRuntime::BreakOnModuleKernels(
+ const RSModuleDescriptorSP rsmodule_sp) {
+ for (const auto &kernel : rsmodule_sp->m_kernels) {
+ // Don't set breakpoint on 'root' kernel
+ if (strcmp(kernel.m_name.AsCString(), "root") == 0)
+ continue;
+
+ CreateKernelBreakpoint(kernel.m_name);
+ }
}
-// Method is internally called by the 'kernel breakpoint all' command to
-// enable or disable breaking on all kernels.
-//
-// When do_break is true we want to enable this functionality.
-// When do_break is false we want to disable it.
-void
-RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+// Method is internally called by the 'kernel breakpoint all' command to enable
+// or disable breaking on all kernels. When do_break is true we want to enable
+// this functionality. When do_break is false we want to disable it.
+void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
- InitSearchFilter(target);
+ InitSearchFilter(target);
- // Set breakpoints on all the kernels
- if (do_break && !m_breakAllKernels)
- {
- m_breakAllKernels = true;
+ // Set breakpoints on all the kernels
+ if (do_break && !m_breakAllKernels) {
+ m_breakAllKernels = true;
- for (const auto &module : m_rsmodules)
- BreakOnModuleKernels(module);
+ for (const auto &module : m_rsmodules)
+ BreakOnModuleKernels(module);
- if (log)
- log->Printf("%s(True) - breakpoints set on all currently loaded kernels.", __FUNCTION__);
- }
- else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
- {
- m_breakAllKernels = false;
+ if (log)
+ log->Printf("%s(True) - breakpoints set on all currently loaded kernels.",
+ __FUNCTION__);
+ } else if (!do_break &&
+ m_breakAllKernels) // Breakpoints won't be set on any new kernels.
+ {
+ m_breakAllKernels = false;
- if (log)
- log->Printf("%s(False) - breakpoints no longer automatically set.", __FUNCTION__);
- }
+ if (log)
+ log->Printf("%s(False) - breakpoints no longer automatically set.",
+ __FUNCTION__);
+ }
}
// Given the name of a kernel this function creates a breakpoint using our
// own breakpoint resolver, and returns the Breakpoint shared pointer.
BreakpointSP
-RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
- if (!m_filtersp)
- {
- if (log)
- log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
- return nullptr;
- }
+ if (!m_filtersp) {
+ if (log)
+ log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ return nullptr;
+ }
- BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
- BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
+ BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
+ BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ m_filtersp, resolver_sp, false, false, false);
- // Give RS breakpoints a specific name, so the user can manipulate them as a group.
- Error err;
- if (!bp->AddName("RenderScriptKernel", err) && log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__, err.AsCString());
+ // Give RS breakpoints a specific name, so the user can manipulate them as a
+ // group.
+ Error err;
+ if (!bp->AddName("RenderScriptKernel", err))
+ if (log)
+ log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
- return bp;
+ return bp;
}
-// Given an expression for a variable this function tries to calculate the variable's value.
-// If this is possible it returns true and sets the uint64_t parameter to the variables unsigned value.
-// Otherwise function returns false.
-bool
-RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const char *var_name, uint64_t &val)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- Error error;
- VariableSP var_sp;
-
- // Find variable in stack frame
- ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(
- var_name, eNoDynamicValues,
- StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
- var_sp, error));
- if (!error.Success())
- {
- if (log)
- log->Printf("%s - error, couldn't find '%s' in frame", __FUNCTION__, var_name);
- return false;
- }
+BreakpointSP
+RenderScriptRuntime::CreateReductionBreakpoint(const ConstString &name,
+ int kernel_types) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
- // Find the uint32_t value for the variable
- bool success = false;
- val = value_sp->GetValueAsUnsigned(0, &success);
- if (!success)
- {
- if (log)
- log->Printf("%s - error, couldn't parse '%s' as an uint32_t.", __FUNCTION__, var_name);
- return false;
- }
+ if (!m_filtersp) {
+ if (log)
+ log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ return nullptr;
+ }
- return true;
+ BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver(
+ nullptr, name, &m_rsmodules, kernel_types));
+ BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ m_filtersp, resolver_sp, false, false, false);
+
+ // Give RS breakpoints a specific name, so the user can manipulate them as a
+ // group.
+ Error err;
+ if (!bp->AddName("RenderScriptReduction", err))
+ if (log)
+ log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
+
+ return bp;
}
-// Function attempts to find the current coordinate of a kernel invocation by investigating the
-// values of frame variables in the .expand function. These coordinates are returned via the coord
-// array reference parameter. Returns true if the coordinates could be found, and false otherwise.
-bool
-RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, Thread *thread_ptr)
-{
- static const std::string s_runtimeExpandSuffix(".expand");
- static const std::array<const char *, 3> s_runtimeCoordVars{{"rsIndex", "p->current.y", "p->current.z"}};
+// Given an expression for a variable this function tries to calculate the
+// variable's value. If this is possible it returns true and sets the uint64_t
+// parameter to the variables unsigned value. Otherwise function returns false.
+bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp,
+ const char *var_name,
+ uint64_t &val) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Error err;
+ VariableSP var_sp;
+
+ // Find variable in stack frame
+ ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(
+ var_name, eNoDynamicValues,
+ StackFrame::eExpressionPathOptionCheckPtrVsMember |
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
+ var_sp, err));
+ if (!err.Success()) {
+ if (log)
+ log->Printf("%s - error, couldn't find '%s' in frame", __FUNCTION__,
+ var_name);
+ return false;
+ }
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ // Find the uint32_t value for the variable
+ bool success = false;
+ val = value_sp->GetValueAsUnsigned(0, &success);
+ if (!success) {
+ if (log)
+ log->Printf("%s - error, couldn't parse '%s' as an uint32_t.",
+ __FUNCTION__, var_name);
+ return false;
+ }
- if (!thread_ptr)
- {
- if (log)
- log->Printf("%s - Error, No thread pointer", __FUNCTION__);
+ return true;
+}
- return false;
- }
+// Function attempts to find the current coordinate of a kernel invocation by
+// investigating the values of frame variables in the .expand function. These
+// coordinates are returned via the coord array reference parameter. Returns
+// true if the coordinates could be found, and false otherwise.
+bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
+ Thread *thread_ptr) {
+ static const char *const x_expr = "rsIndex";
+ static const char *const y_expr = "p->current.y";
+ static const char *const z_expr = "p->current.z";
- // Walk the call stack looking for a function whose name has the suffix '.expand'
- // and contains the variables we're looking for.
- for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i)
- {
- if (!thread_ptr->SetSelectedFrameByIndex(i))
- continue;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- StackFrameSP frame_sp = thread_ptr->GetSelectedFrame();
- if (!frame_sp)
- continue;
+ if (!thread_ptr) {
+ if (log)
+ log->Printf("%s - Error, No thread pointer", __FUNCTION__);
- // Find the function name
- const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false);
- const char *func_name_cstr = sym_ctx.GetFunctionName().AsCString();
- if (!func_name_cstr)
- continue;
+ return false;
+ }
- if (log)
- log->Printf("%s - Inspecting function '%s'", __FUNCTION__, func_name_cstr);
+ // Walk the call stack looking for a function whose name has the suffix
+ // '.expand' and contains the variables we're looking for.
+ for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i) {
+ if (!thread_ptr->SetSelectedFrameByIndex(i))
+ continue;
- // Check if function name has .expand suffix
- std::string func_name(func_name_cstr);
- const int length_difference = func_name.length() - s_runtimeExpandSuffix.length();
- if (length_difference <= 0)
- continue;
+ StackFrameSP frame_sp = thread_ptr->GetSelectedFrame();
+ if (!frame_sp)
+ continue;
- const int32_t has_expand_suffix = func_name.compare(length_difference,
- s_runtimeExpandSuffix.length(),
- s_runtimeExpandSuffix);
+ // Find the function name
+ const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false);
+ const ConstString func_name = sym_ctx.GetFunctionName();
+ if (!func_name)
+ continue;
- if (has_expand_suffix != 0)
- continue;
+ if (log)
+ log->Printf("%s - Inspecting function '%s'", __FUNCTION__,
+ func_name.GetCString());
- if (log)
- log->Printf("%s - Found .expand function '%s'", __FUNCTION__, func_name_cstr);
-
- // Get values for variables in .expand frame that tell us the current kernel invocation
- bool found_coord_variables = true;
- assert(s_runtimeCoordVars.size() == coord.size());
-
- for (uint32_t i = 0; i < coord.size(); ++i)
- {
- uint64_t value = 0;
- if (!GetFrameVarAsUnsigned(frame_sp, s_runtimeCoordVars[i], value))
- {
- found_coord_variables = false;
- break;
- }
- coord[i] = value;
- }
+ // Check if function name has .expand suffix
+ if (!func_name.GetStringRef().endswith(".expand"))
+ continue;
- if (found_coord_variables)
- return true;
- }
- return false;
+ if (log)
+ log->Printf("%s - Found .expand function '%s'", __FUNCTION__,
+ func_name.GetCString());
+
+ // Get values for variables in .expand frame that tell us the current kernel
+ // invocation
+ uint64_t x, y, z;
+ bool found = GetFrameVarAsUnsigned(frame_sp, x_expr, x) &&
+ GetFrameVarAsUnsigned(frame_sp, y_expr, y) &&
+ GetFrameVarAsUnsigned(frame_sp, z_expr, z);
+
+ if (found) {
+ // The RenderScript runtime uses uint32_t for these vars. If they're not
+ // within bounds, our frame parsing is garbage
+ assert(x <= UINT32_MAX && y <= UINT32_MAX && z <= UINT32_MAX);
+ coord.x = (uint32_t)x;
+ coord.y = (uint32_t)y;
+ coord.z = (uint32_t)z;
+ return true;
+ }
+ }
+ return false;
}
-// Callback when a kernel breakpoint hits and we're looking for a specific coordinate.
-// Baton parameter contains a pointer to the target coordinate we want to break on.
-// Function then checks the .expand frame for the current coordinate and breaks to user if it matches.
+// Callback when a kernel breakpoint hits and we're looking for a specific
+// coordinate. Baton parameter contains a pointer to the target coordinate we
+// want to break on.
+// Function then checks the .expand frame for the current coordinate and breaks
+// to user if it matches.
// Parameter 'break_id' is the id of the Breakpoint which made the callback.
// Parameter 'break_loc_id' is the id for the BreakpointLocation which was hit,
// a single logical breakpoint can have multiple addresses.
-bool
-RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, user_id_t break_id,
- user_id_t break_loc_id)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
-
- assert(baton && "Error: null baton in conditional kernel breakpoint callback");
+bool RenderScriptRuntime::KernelBreakpointHit(void *baton,
+ StoppointCallbackContext *ctx,
+ user_id_t break_id,
+ user_id_t break_loc_id) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+
+ assert(baton &&
+ "Error: null baton in conditional kernel breakpoint callback");
+
+ // Coordinate we want to stop on
+ RSCoordinate target_coord = *static_cast<RSCoordinate *>(baton);
+
+ if (log)
+ log->Printf("%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__, break_id,
+ target_coord.x, target_coord.y, target_coord.z);
+
+ // Select current thread
+ ExecutionContext context(ctx->exe_ctx_ref);
+ Thread *thread_ptr = context.GetThreadPtr();
+ assert(thread_ptr && "Null thread pointer");
+
+ // Find current kernel invocation from .expand frame variables
+ RSCoordinate current_coord{};
+ if (!GetKernelCoordinate(current_coord, thread_ptr)) {
+ if (log)
+ log->Printf("%s - Error, couldn't select .expand stack frame",
+ __FUNCTION__);
+ return false;
+ }
- // Coordinate we want to stop on
- const uint32_t *target_coord = static_cast<const uint32_t *>(baton);
+ if (log)
+ log->Printf("%s - " FMT_COORD, __FUNCTION__, current_coord.x,
+ current_coord.y, current_coord.z);
+ // Check if the current kernel invocation coordinate matches our target
+ // coordinate
+ if (target_coord == current_coord) {
if (log)
- log->Printf("%s - Break ID %" PRIu64 ", (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", __FUNCTION__, break_id,
- target_coord[0], target_coord[1], target_coord[2]);
+ log->Printf("%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x,
+ current_coord.y, current_coord.z);
+
+ BreakpointSP breakpoint_sp =
+ context.GetTargetPtr()->GetBreakpointByID(break_id);
+ assert(breakpoint_sp != nullptr &&
+ "Error: Couldn't find breakpoint matching break id for callback");
+ breakpoint_sp->SetEnabled(false); // Optimise since conditional breakpoint
+ // should only be hit once.
+ return true;
+ }
- // Select current thread
- ExecutionContext context(ctx->exe_ctx_ref);
- Thread *thread_ptr = context.GetThreadPtr();
- assert(thread_ptr && "Null thread pointer");
+ // No match on coordinate
+ return false;
+}
- // Find current kernel invocation from .expand frame variables
- RSCoordinate current_coord{}; // Zero initialise array
- if (!GetKernelCoordinate(current_coord, thread_ptr))
- {
- if (log)
- log->Printf("%s - Error, couldn't select .expand stack frame", __FUNCTION__);
- return false;
- }
+void RenderScriptRuntime::SetConditional(BreakpointSP bp, Stream &messages,
+ const RSCoordinate &coord) {
+ messages.Printf("Conditional kernel breakpoint on coordinate " FMT_COORD,
+ coord.x, coord.y, coord.z);
+ messages.EOL();
- if (log)
- log->Printf("%s - (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0], current_coord[1],
- current_coord[2]);
+ // Allocate memory for the baton, and copy over coordinate
+ RSCoordinate *baton = new RSCoordinate(coord);
- // Check if the current kernel invocation coordinate matches our target coordinate
- if (current_coord[0] == target_coord[0] &&
- current_coord[1] == target_coord[1] &&
- current_coord[2] == target_coord[2])
- {
- if (log)
- log->Printf("%s, BREAKING (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0],
- current_coord[1], current_coord[2]);
+ // Create a callback that will be invoked every time the breakpoint is hit.
+ // The baton object passed to the handler is the target coordinate we want to
+ // break on.
+ bp->SetCallback(KernelBreakpointHit, baton, true);
- BreakpointSP breakpoint_sp = context.GetTargetPtr()->GetBreakpointByID(break_id);
- assert(breakpoint_sp != nullptr && "Error: Couldn't find breakpoint matching break id for callback");
- breakpoint_sp->SetEnabled(false); // Optimise since conditional breakpoint should only be hit once.
- return true;
- }
+ // Store a shared pointer to the baton, so the memory will eventually be
+ // cleaned up after destruction
+ m_conditional_breaks[bp->GetID()] = std::unique_ptr<RSCoordinate>(baton);
+}
- // No match on coordinate
+// Tries to set a breakpoint on the start of a kernel, resolved using the kernel
+// name. Argument 'coords', represents a three dimensional coordinate which can
+// be
+// used to specify a single kernel instance to break on. If this is set then we
+// add a callback
+// to the breakpoint.
+bool RenderScriptRuntime::PlaceBreakpointOnKernel(TargetSP target,
+ Stream &messages,
+ const char *name,
+ const RSCoordinate *coord) {
+ if (!name)
return false;
+
+ InitSearchFilter(target);
+
+ ConstString kernel_name(name);
+ BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
+ if (!bp)
+ return false;
+
+ // We have a conditional breakpoint on a specific coordinate
+ if (coord)
+ SetConditional(bp, messages, *coord);
+
+ bp->GetDescription(&messages, lldb::eDescriptionLevelInitial, false);
+
+ return true;
}
-// Tries to set a breakpoint on the start of a kernel, resolved using the kernel name.
-// Argument 'coords', represents a three dimensional coordinate which can be used to specify
-// a single kernel instance to break on. If this is set then we add a callback to the breakpoint.
-void
-RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int, 3> coords,
- Error &error, TargetSP target)
-{
- if (!name)
- {
- error.SetErrorString("invalid kernel name");
- return;
- }
+BreakpointSP
+RenderScriptRuntime::CreateScriptGroupBreakpoint(const ConstString &name,
+ bool stop_on_all) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
- InitSearchFilter(target);
+ if (!m_filtersp) {
+ if (log)
+ log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ return nullptr;
+ }
+
+ BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver(
+ nullptr, name, m_scriptGroups, stop_on_all));
+ BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+ m_filtersp, resolver_sp, false, false, false);
+ // Give RS breakpoints a specific name, so the user can manipulate them as a
+ // group.
+ Error err;
+ if (!bp->AddName(name.AsCString(), err))
+ if (log)
+ log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
+ // ask the breakpoint to resolve itself
+ bp->ResolveBreakpoint();
+ return bp;
+}
- ConstString kernel_name(name);
- BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
+bool RenderScriptRuntime::PlaceBreakpointOnScriptGroup(TargetSP target,
+ Stream &strm,
+ const ConstString &name,
+ bool multi) {
+ InitSearchFilter(target);
+ BreakpointSP bp = CreateScriptGroupBreakpoint(name, multi);
+ if (bp)
+ bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
+ return bool(bp);
+}
- // We have a conditional breakpoint on a specific coordinate
- if (coords[0] != -1)
- {
- strm.Printf("Conditional kernel breakpoint on coordinate %" PRId32 ", %" PRId32 ", %" PRId32,
- coords[0], coords[1], coords[2]);
- strm.EOL();
+bool RenderScriptRuntime::PlaceBreakpointOnReduction(TargetSP target,
+ Stream &messages,
+ const char *reduce_name,
+ const RSCoordinate *coord,
+ int kernel_types) {
+ if (!reduce_name)
+ return false;
- // Allocate memory for the baton, and copy over coordinate
- uint32_t *baton = new uint32_t[coords.size()];
- baton[0] = coords[0]; baton[1] = coords[1]; baton[2] = coords[2];
+ InitSearchFilter(target);
+ BreakpointSP bp =
+ CreateReductionBreakpoint(ConstString(reduce_name), kernel_types);
+ if (!bp)
+ return false;
- // Create a callback that will be invoked everytime the breakpoint is hit.
- // The baton object passed to the handler is the target coordinate we want to break on.
- bp->SetCallback(KernelBreakpointHit, baton, true);
+ if (coord)
+ SetConditional(bp, messages, *coord);
- // Store a shared pointer to the baton, so the memory will eventually be cleaned up after destruction
- m_conditional_breaks[bp->GetID()] = std::shared_ptr<uint32_t>(baton);
- }
+ bp->GetDescription(&messages, lldb::eDescriptionLevelInitial, false);
- if (bp)
- bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
+ return true;
}
-void
-RenderScriptRuntime::DumpModules(Stream &strm) const
-{
- strm.Printf("RenderScript Modules:");
- strm.EOL();
- strm.IndentMore();
- for (const auto &module : m_rsmodules)
- {
- module->Dump(strm);
- }
- strm.IndentLess();
+void RenderScriptRuntime::DumpModules(Stream &strm) const {
+ strm.Printf("RenderScript Modules:");
+ strm.EOL();
+ strm.IndentMore();
+ for (const auto &module : m_rsmodules) {
+ module->Dump(strm);
+ }
+ strm.IndentLess();
}
RenderScriptRuntime::ScriptDetails *
-RenderScriptRuntime::LookUpScript(addr_t address, bool create)
-{
- for (const auto &s : m_scripts)
- {
- if (s->script.isValid())
- if (*s->script == address)
- return s.get();
- }
- if (create)
- {
- std::unique_ptr<ScriptDetails> s(new ScriptDetails);
- s->script = address;
- m_scripts.push_back(std::move(s));
- return m_scripts.back().get();
- }
- return nullptr;
+RenderScriptRuntime::LookUpScript(addr_t address, bool create) {
+ for (const auto &s : m_scripts) {
+ if (s->script.isValid())
+ if (*s->script == address)
+ return s.get();
+ }
+ if (create) {
+ std::unique_ptr<ScriptDetails> s(new ScriptDetails);
+ s->script = address;
+ m_scripts.push_back(std::move(s));
+ return m_scripts.back().get();
+ }
+ return nullptr;
}
RenderScriptRuntime::AllocationDetails *
-RenderScriptRuntime::LookUpAllocation(addr_t address, bool create)
-{
- for (const auto &a : m_allocations)
- {
- if (a->address.isValid())
- if (*a->address == address)
- return a.get();
- }
- if (create)
- {
- std::unique_ptr<AllocationDetails> a(new AllocationDetails);
- a->address = address;
- m_allocations.push_back(std::move(a));
- return m_allocations.back().get();
- }
- return nullptr;
+RenderScriptRuntime::LookUpAllocation(addr_t address) {
+ for (const auto &a : m_allocations) {
+ if (a->address.isValid())
+ if (*a->address == address)
+ return a.get();
+ }
+ return nullptr;
}
-void
-RSModuleDescriptor::Dump(Stream &strm) const
-{
- strm.Indent();
- m_module->GetFileSpec().Dump(&strm);
- if (m_module->GetNumCompileUnits())
- {
- strm.Indent("Debug info loaded.");
- }
- else
- {
- strm.Indent("Debug info does not exist.");
- }
- strm.EOL();
- strm.IndentMore();
- strm.Indent();
- strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
- strm.EOL();
- strm.IndentMore();
- for (const auto &global : m_globals)
- {
- global.Dump(strm);
- }
- strm.IndentLess();
- strm.Indent();
- strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
- strm.EOL();
- strm.IndentMore();
- for (const auto &kernel : m_kernels)
- {
- kernel.Dump(strm);
- }
- strm.Printf("Pragmas: %" PRIu64, static_cast<uint64_t>(m_pragmas.size()));
- strm.EOL();
- strm.IndentMore();
- for (const auto &key_val : m_pragmas)
- {
- strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
- strm.EOL();
- }
- strm.IndentLess(4);
+RenderScriptRuntime::AllocationDetails *
+RenderScriptRuntime::CreateAllocation(addr_t address) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ // Remove any previous allocation which contains the same address
+ auto it = m_allocations.begin();
+ while (it != m_allocations.end()) {
+ if (*((*it)->address) == address) {
+ if (log)
+ log->Printf("%s - Removing allocation id: %d, address: 0x%" PRIx64,
+ __FUNCTION__, (*it)->id, address);
+
+ it = m_allocations.erase(it);
+ } else {
+ it++;
+ }
+ }
+
+ std::unique_ptr<AllocationDetails> a(new AllocationDetails);
+ a->address = address;
+ m_allocations.push_back(std::move(a));
+ return m_allocations.back().get();
}
-void
-RSGlobalDescriptor::Dump(Stream &strm) const
-{
- strm.Indent(m_name.AsCString());
- VariableList var_list;
- m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
- if (var_list.GetSize() == 1)
- {
- auto var = var_list.GetVariableAtIndex(0);
- auto type = var->GetType();
- if (type)
- {
- strm.Printf(" - ");
- type->DumpTypeName(&strm);
- }
- else
- {
- strm.Printf(" - Unknown Type");
- }
- }
- else
- {
- strm.Printf(" - variable identified, but not found in binary");
- const Symbol *s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
- if (s)
- {
- strm.Printf(" (symbol exists) ");
- }
- }
+bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr,
+ ConstString &name) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
- strm.EOL();
+ Target &target = GetProcess()->GetTarget();
+ Address resolved;
+ // RenderScript module
+ if (!target.GetSectionLoadList().ResolveLoadAddress(kernel_addr, resolved)) {
+ if (log)
+ log->Printf("%s: unable to resolve 0x%" PRIx64 " to a loaded symbol",
+ __FUNCTION__, kernel_addr);
+ return false;
+ }
+
+ Symbol *sym = resolved.CalculateSymbolContextSymbol();
+ if (!sym)
+ return false;
+
+ name = sym->GetName();
+ assert(IsRenderScriptModule(resolved.CalculateSymbolContextModule()));
+ if (log)
+ log->Printf("%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__,
+ kernel_addr, name.GetCString());
+ return true;
}
-void
-RSKernelDescriptor::Dump(Stream &strm) const
-{
- strm.Indent(m_name.AsCString());
+void RSModuleDescriptor::Dump(Stream &strm) const {
+ int indent = strm.GetIndentLevel();
+
+ strm.Indent();
+ m_module->GetFileSpec().Dump(&strm);
+ strm.Indent(m_module->GetNumCompileUnits() ? "Debug info loaded."
+ : "Debug info does not exist.");
+ strm.EOL();
+ strm.IndentMore();
+
+ strm.Indent();
+ strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
+ strm.EOL();
+ strm.IndentMore();
+ for (const auto &global : m_globals) {
+ global.Dump(strm);
+ }
+ strm.IndentLess();
+
+ strm.Indent();
+ strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
+ strm.EOL();
+ strm.IndentMore();
+ for (const auto &kernel : m_kernels) {
+ kernel.Dump(strm);
+ }
+ strm.IndentLess();
+
+ strm.Indent();
+ strm.Printf("Pragmas: %" PRIu64, static_cast<uint64_t>(m_pragmas.size()));
+ strm.EOL();
+ strm.IndentMore();
+ for (const auto &key_val : m_pragmas) {
+ strm.Indent();
+ strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
strm.EOL();
+ }
+ strm.IndentLess();
+
+ strm.Indent();
+ strm.Printf("Reductions: %" PRIu64,
+ static_cast<uint64_t>(m_reductions.size()));
+ strm.EOL();
+ strm.IndentMore();
+ for (const auto &reduction : m_reductions) {
+ reduction.Dump(strm);
+ }
+
+ strm.SetIndentLevel(indent);
}
-class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
-{
-public:
- CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript module dump",
- "Dumps renderscript specific information for all modules.", "renderscript module dump",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
- }
+void RSGlobalDescriptor::Dump(Stream &strm) const {
+ strm.Indent(m_name.AsCString());
+ VariableList var_list;
+ m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
+ if (var_list.GetSize() == 1) {
+ auto var = var_list.GetVariableAtIndex(0);
+ auto type = var->GetType();
+ if (type) {
+ strm.Printf(" - ");
+ type->DumpTypeName(&strm);
+ } else {
+ strm.Printf(" - Unknown Type");
+ }
+ } else {
+ strm.Printf(" - variable identified, but not found in binary");
+ const Symbol *s = m_module->m_module->FindFirstSymbolWithNameAndType(
+ m_name, eSymbolTypeData);
+ if (s) {
+ strm.Printf(" (symbol exists) ");
+ }
+ }
+
+ strm.EOL();
+}
- ~CommandObjectRenderScriptRuntimeModuleDump() override = default;
+void RSKernelDescriptor::Dump(Stream &strm) const {
+ strm.Indent(m_name.AsCString());
+ strm.EOL();
+}
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
- runtime->DumpModules(result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
-};
+void RSReductionDescriptor::Dump(lldb_private::Stream &stream) const {
+ stream.Indent(m_reduce_name.AsCString());
+ stream.IndentMore();
+ stream.EOL();
+ stream.Indent();
+ stream.Printf("accumulator: %s", m_accum_name.AsCString());
+ stream.EOL();
+ stream.Indent();
+ stream.Printf("initializer: %s", m_init_name.AsCString());
+ stream.EOL();
+ stream.Indent();
+ stream.Printf("combiner: %s", m_comb_name.AsCString());
+ stream.EOL();
+ stream.Indent();
+ stream.Printf("outconverter: %s", m_outc_name.AsCString());
+ stream.EOL();
+ // XXX This is currently unspecified by RenderScript, and unused
+ // stream.Indent();
+ // stream.Printf("halter: '%s'", m_init_name.AsCString());
+ // stream.EOL();
+ stream.IndentLess();
+}
-class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
-{
+class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with RenderScript modules.",
- nullptr)
- {
- LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
- }
-
- ~CommandObjectRenderScriptRuntimeModule() override = default;
+ CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript module dump",
+ "Dumps renderscript specific information for all modules.",
+ "renderscript module dump",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptRuntimeModuleDump() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ RenderScriptRuntime *runtime =
+ (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript);
+ runtime->DumpModules(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
};
-class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword {
public:
- CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript kernel list",
- "Lists renderscript kernel names and associated script resources.",
- "renderscript kernel list", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeKernelList() override = default;
-
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
- runtime->DumpKernels(result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
+ CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "renderscript module",
+ "Commands that deal with RenderScript modules.",
+ nullptr) {
+ LoadSubCommand(
+ "dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(
+ interpreter)));
+ }
+
+ ~CommandObjectRenderScriptRuntimeModule() override = default;
};
-class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
- "Sets a breakpoint on a renderscript kernel.",
- "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
- m_options(interpreter)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() override = default;
-
- Options *
- GetOptions() override
- {
- return &m_options;
- }
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) {}
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue(uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'c':
- if (!ParseCoordinate(option_arg))
- error.SetErrorStringWithFormat("Couldn't parse coordinate '%s', should be in format 'x,y,z'.",
- option_arg);
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
- }
- return error;
- }
-
- // -c takes an argument of the form 'num[,num][,num]'.
- // Where 'id_cstr' is this argument with the whitespace trimmed.
- // Missing coordinates are defaulted to zero.
- bool
- ParseCoordinate(const char *id_cstr)
- {
- RegularExpression regex;
- RegularExpression::Match regex_match(3);
-
- bool matched = false;
- if (regex.Compile("^([0-9]+),([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
- matched = true;
- else if (regex.Compile("^([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
- matched = true;
- else if (regex.Compile("^([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
- matched = true;
- for (uint32_t i = 0; i < 3; i++)
- {
- std::string group;
- if (regex_match.GetMatchAtIndex(id_cstr, i + 1, group))
- m_coord[i] = (uint32_t)strtoul(group.c_str(), nullptr, 0);
- else
- m_coord[i] = 0;
- }
- return matched;
- }
-
- void
- OptionParsingStarting() override
- {
- // -1 means the -c option hasn't been set
- m_coord[0] = -1;
- m_coord[1] = -1;
- m_coord[2] = -1;
- }
-
- const OptionDefinition *
- GetDefinitions() override
- {
- return g_option_table;
- }
-
- static OptionDefinition g_option_table[];
- std::array<int, 3> m_coord;
- };
+ CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript kernel list",
+ "Lists renderscript kernel names and associated script resources.",
+ "renderscript kernel list",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptRuntimeKernelList() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ RenderScriptRuntime *runtime =
+ (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript);
+ runtime->DumpKernels(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc < 1)
- {
- result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name, and an optional coordinate.",
- m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
+static OptionDefinition g_renderscript_reduction_bp_set_options[] = {
+ {LLDB_OPT_SET_1, false, "function-role", 't',
+ OptionParser::eRequiredArgument, nullptr, 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,
+ "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 "
+ "integers representing kernel dimensions. "
+ "Any unset dimensions will be defaulted to zero."}};
+
+class CommandObjectRenderScriptRuntimeReductionBreakpointSet
+ : public CommandObjectParsed {
+public:
+ CommandObjectRenderScriptRuntimeReductionBreakpointSet(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript reduction breakpoint set",
+ "Set a breakpoint on named RenderScript general reductions",
+ "renderscript reduction breakpoint set <kernel_name> [-t "
+ "<reduction_kernel_type,...>]",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options(){};
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(),
+ m_kernel_types(RSReduceBreakpointResolver::eKernelTypeAll) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *exe_ctx) override {
+ Error err;
+ StreamString err_str;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 't':
+ if (!ParseReductionTypes(option_arg, err_str))
+ err.SetErrorStringWithFormat(
+ "Unable to deduce reduction types for %s: %s",
+ option_arg.str().c_str(), err_str.GetData());
+ break;
+ case 'c': {
+ auto coord = RSCoordinate{};
+ if (!ParseCoordinate(option_arg, coord))
+ err.SetErrorStringWithFormat("unable to parse coordinate for %s",
+ option_arg.str().c_str());
+ else {
+ m_have_coord = true;
+ m_coord = coord;
}
+ break;
+ }
+ default:
+ err.SetErrorStringWithFormat("Invalid option '-%c'", short_option);
+ }
+ return err;
+ }
+
+ void OptionParsingStarting(ExecutionContext *exe_ctx) override {
+ m_have_coord = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_renderscript_reduction_bp_set_options);
+ }
+
+ bool ParseReductionTypes(llvm::StringRef option_val,
+ StreamString &err_str) {
+ m_kernel_types = RSReduceBreakpointResolver::eKernelTypeNone;
+ const auto reduce_name_to_type = [](llvm::StringRef name) -> int {
+ return llvm::StringSwitch<int>(name)
+ .Case("accumulator", RSReduceBreakpointResolver::eKernelTypeAccum)
+ .Case("initializer", RSReduceBreakpointResolver::eKernelTypeInit)
+ .Case("outconverter", RSReduceBreakpointResolver::eKernelTypeOutC)
+ .Case("combiner", RSReduceBreakpointResolver::eKernelTypeComb)
+ .Case("all", RSReduceBreakpointResolver::eKernelTypeAll)
+ // Currently not exposed by the runtime
+ // .Case("halter", RSReduceBreakpointResolver::eKernelTypeHalter)
+ .Default(0);
+ };
+
+ // Matching a comma separated list of known words is fairly
+ // straightforward with PCRE, but we're
+ // using ERE, so we end up with a little ugliness...
+ RegularExpression::Match match(/* max_matches */ 5);
+ RegularExpression match_type_list(
+ llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$"));
+
+ assert(match_type_list.IsValid());
+
+ if (!match_type_list.Execute(option_val, &match)) {
+ err_str.PutCString(
+ "a comma-separated list of kernel types is required");
+ return false;
+ }
- RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
-
- Error error;
- runtime->PlaceBreakpointOnKernel(result.GetOutputStream(), command.GetArgumentAtIndex(0), m_options.m_coord,
- error, m_exe_ctx.GetTargetSP());
+ // splitting on commas is much easier with llvm::StringRef than regex
+ llvm::SmallVector<llvm::StringRef, 5> type_names;
+ llvm::StringRef(option_val).split(type_names, ',');
- if (error.Success())
- {
- result.AppendMessage("Breakpoint(s) created");
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
+ for (const auto &name : type_names) {
+ const int type = reduce_name_to_type(name);
+ if (!type) {
+ err_str.Printf("unknown kernel type name %s", name.str().c_str());
+ return false;
}
- result.SetStatus(eReturnStatusFailed);
- result.AppendErrorWithFormat("Error: %s", error.AsCString());
- return false;
- }
+ m_kernel_types |= type;
+ }
+
+ return true;
+ }
+
+ int m_kernel_types;
+ llvm::StringRef m_reduce_name;
+ RSCoordinate m_coord;
+ bool m_have_coord;
+ };
+
+ Options *GetOptions() override { return &m_options; }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc < 1) {
+ result.AppendErrorWithFormat("'%s' takes 1 argument of reduction name, "
+ "and an optional kernel type list",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+
+ auto &outstream = result.GetOutputStream();
+ auto name = command.GetArgumentAtIndex(0);
+ auto &target = m_exe_ctx.GetTargetSP();
+ auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
+ if (!runtime->PlaceBreakpointOnReduction(target, outstream, name, coord,
+ m_options.m_kernel_types)) {
+ result.SetStatus(eReturnStatusFailed);
+ result.AppendError("Error: unable to place breakpoint on reduction");
+ return false;
+ }
+ result.AppendMessage("Breakpoint(s) created");
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
private:
- CommandOptions m_options;
+ CommandOptions m_options;
};
-OptionDefinition CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::g_option_table[] = {
- {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, nullptr, 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 integers representing kernel dimensions. "
- "Any unset dimensions will be defaulted to zero."},
- {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
-
-class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
-{
+static OptionDefinition g_renderscript_kernel_bp_set_options[] = {
+ {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument,
+ nullptr, 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 "
+ "integers representing kernel dimensions. "
+ "Any unset dimensions will be defaulted to zero."}};
+
+class CommandObjectRenderScriptRuntimeKernelBreakpointSet
+ : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "renderscript kernel breakpoint all",
- "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
- "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
- "but does not remove currently set breakpoints.",
- "renderscript kernel breakpoint all <enable/disable>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() override = default;
-
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc != 1)
- {
- result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
+ CommandObjectRenderScriptRuntimeKernelBreakpointSet(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript kernel breakpoint set",
+ "Sets a breakpoint on a renderscript kernel.",
+ "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options() {}
+
+ ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *exe_ctx) override {
+ Error err;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c': {
+ auto coord = RSCoordinate{};
+ if (!ParseCoordinate(option_arg, coord))
+ err.SetErrorStringWithFormat(
+ "Couldn't parse coordinate '%s', should be in format 'x,y,z'.",
+ option_arg.str().c_str());
+ else {
+ m_have_coord = true;
+ m_coord = coord;
}
+ break;
+ }
+ default:
+ err.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
+ break;
+ }
+ return err;
+ }
- RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
- m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ void OptionParsingStarting(ExecutionContext *exe_ctx) override {
+ m_have_coord = false;
+ }
- bool do_break = false;
- const char *argument = command.GetArgumentAtIndex(0);
- if (strcmp(argument, "enable") == 0)
- {
- do_break = true;
- result.AppendMessage("Breakpoints will be set on all kernels.");
- }
- else if (strcmp(argument, "disable") == 0)
- {
- do_break = false;
- result.AppendMessage("Breakpoints will not be set on any new kernels.");
- }
- else
- {
- result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_renderscript_kernel_bp_set_options);
+ }
- runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
+ RSCoordinate m_coord;
+ bool m_have_coord;
+ };
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc < 1) {
+ result.AppendErrorWithFormat(
+ "'%s' takes 1 argument of kernel name, and an optional coordinate.",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-};
-class CommandObjectRenderScriptRuntimeKernelCoordinate : public CommandObjectParsed
-{
-public:
- CommandObjectRenderScriptRuntimeKernelCoordinate(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript kernel coordinate",
- "Shows the (x,y,z) coordinate of the current kernel invocation.",
- "renderscript kernel coordinate",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
- {
+ RenderScriptRuntime *runtime =
+ (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript);
+
+ auto &outstream = result.GetOutputStream();
+ auto &target = m_exe_ctx.GetTargetSP();
+ auto name = command.GetArgumentAtIndex(0);
+ auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
+ if (!runtime->PlaceBreakpointOnKernel(target, outstream, name, coord)) {
+ result.SetStatus(eReturnStatusFailed);
+ result.AppendErrorWithFormat(
+ "Error: unable to set breakpoint on kernel '%s'", name);
+ return false;
}
- ~CommandObjectRenderScriptRuntimeKernelCoordinate() override = default;
+ result.AppendMessage("Breakpoint(s) created");
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- RSCoordinate coord{}; // Zero initialize array
- bool success = RenderScriptRuntime::GetKernelCoordinate(coord, m_exe_ctx.GetThreadPtr());
- Stream &stream = result.GetOutputStream();
-
- if (success)
- {
- stream.Printf("Coordinate: (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", coord[0], coord[1], coord[2]);
- stream.EOL();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else
- {
- stream.Printf("Error: Coordinate could not be found.");
- stream.EOL();
- result.SetStatus(eReturnStatusFailed);
- }
- return true;
- }
+private:
+ CommandOptions m_options;
};
-class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
-{
+class CommandObjectRenderScriptRuntimeKernelBreakpointAll
+ : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript kernel",
- "Commands that generate breakpoints on renderscript kernels.", nullptr)
- {
- LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
- LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
- }
-
- ~CommandObjectRenderScriptRuntimeKernelBreakpoint() override = default;
+ CommandObjectRenderScriptRuntimeKernelBreakpointAll(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript kernel breakpoint all",
+ "Automatically sets a breakpoint on all renderscript kernels that "
+ "are or will be loaded.\n"
+ "Disabling option means breakpoints will no longer be set on any "
+ "kernels loaded in the future, "
+ "but does not remove currently set breakpoints.",
+ "renderscript kernel breakpoint all <enable/disable>",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused) {}
+
+ ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc != 1) {
+ result.AppendErrorWithFormat(
+ "'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+
+ bool do_break = false;
+ const char *argument = command.GetArgumentAtIndex(0);
+ if (strcmp(argument, "enable") == 0) {
+ do_break = true;
+ result.AppendMessage("Breakpoints will be set on all kernels.");
+ } else if (strcmp(argument, "disable") == 0) {
+ do_break = false;
+ result.AppendMessage("Breakpoints will not be set on any new kernels.");
+ } else {
+ result.AppendErrorWithFormat(
+ "Argument must be either 'enable' or 'disable'");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
};
-class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
-{
+class CommandObjectRenderScriptRuntimeReductionBreakpoint
+ : public CommandObjectMultiword {
public:
- CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with RenderScript kernels.",
- nullptr)
- {
- LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
- LoadSubCommand("coordinate",
- CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelCoordinate(interpreter)));
- LoadSubCommand("breakpoint",
- CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
- }
-
- ~CommandObjectRenderScriptRuntimeKernel() override = default;
+ CommandObjectRenderScriptRuntimeReductionBreakpoint(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "renderscript reduction breakpoint",
+ "Commands that manipulate breakpoints on "
+ "renderscript general reductions.",
+ nullptr) {
+ LoadSubCommand(
+ "set", CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeReductionBreakpointSet(
+ interpreter)));
+ }
+
+ ~CommandObjectRenderScriptRuntimeReductionBreakpoint() override = default;
};
-class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeKernelCoordinate
+ : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript context dump", "Dumps renderscript context information.",
- "renderscript context dump", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeContextDump() override = default;
-
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
- runtime->DumpContexts(result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
+ CommandObjectRenderScriptRuntimeKernelCoordinate(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript kernel coordinate",
+ "Shows the (x,y,z) coordinate of the current kernel invocation.",
+ "renderscript kernel coordinate",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused) {}
+
+ ~CommandObjectRenderScriptRuntimeKernelCoordinate() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ RSCoordinate coord{};
+ bool success = RenderScriptRuntime::GetKernelCoordinate(
+ coord, m_exe_ctx.GetThreadPtr());
+ Stream &stream = result.GetOutputStream();
+
+ if (success) {
+ stream.Printf("Coordinate: " FMT_COORD, coord.x, coord.y, coord.z);
+ stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ stream.Printf("Error: Coordinate could not be found.");
+ stream.EOL();
+ result.SetStatus(eReturnStatusFailed);
}
+ return true;
+ }
};
-class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
-{
+class CommandObjectRenderScriptRuntimeKernelBreakpoint
+ : public CommandObjectMultiword {
public:
- CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with RenderScript contexts.",
- nullptr)
- {
- LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
- }
-
- ~CommandObjectRenderScriptRuntimeContext() override = default;
+ CommandObjectRenderScriptRuntimeKernelBreakpoint(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "renderscript kernel",
+ "Commands that generate breakpoints on renderscript kernels.",
+ nullptr) {
+ LoadSubCommand(
+ "set",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(
+ interpreter)));
+ LoadSubCommand(
+ "all",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(
+ interpreter)));
+ }
+
+ ~CommandObjectRenderScriptRuntimeKernelBreakpoint() override = default;
};
-class CommandObjectRenderScriptRuntimeAllocationDump : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword {
public:
- CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript allocation dump",
- "Displays the contents of a particular allocation", "renderscript allocation dump <ID>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched),
- m_options(interpreter)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeAllocationDump() override = default;
-
- Options *
- GetOptions() override
- {
- return &m_options;
- }
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) {}
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue(uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'f':
- m_outfile.SetFile(option_arg, true);
- if (m_outfile.Exists())
- {
- m_outfile.Clear();
- error.SetErrorStringWithFormat("file already exists: '%s'", option_arg);
- }
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting() override
- {
- m_outfile.Clear();
- }
-
- const OptionDefinition *
- GetDefinitions() override
- {
- return g_option_table;
- }
+ CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "renderscript kernel",
+ "Commands that deal with RenderScript kernels.",
+ nullptr) {
+ LoadSubCommand(
+ "list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(
+ interpreter)));
+ LoadSubCommand(
+ "coordinate",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeKernelCoordinate(interpreter)));
+ LoadSubCommand(
+ "breakpoint",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
+ }
+
+ ~CommandObjectRenderScriptRuntimeKernel() override = default;
+};
- static OptionDefinition g_option_table[];
- FileSpec m_outfile;
- };
+class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed {
+public:
+ CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript context dump",
+ "Dumps renderscript context information.",
+ "renderscript context dump",
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptRuntimeContextDump() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ RenderScriptRuntime *runtime =
+ (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript);
+ runtime->DumpContexts(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc < 1)
- {
- result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. As well as an optional -f argument",
- m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+static OptionDefinition g_renderscript_runtime_alloc_dump_options[] = {
+ {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument,
+ nullptr, nullptr, 0, eArgTypeFilename,
+ "Print results to specified file instead of command line."}};
- RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
- m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
-
- const char *id_cstr = command.GetArgumentAtIndex(0);
- bool convert_complete = false;
- const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
- if (!convert_complete)
- {
- result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword {
+public:
+ CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "renderscript context",
+ "Commands that deal with RenderScript contexts.",
+ nullptr) {
+ LoadSubCommand(
+ "dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(
+ interpreter)));
+ }
+
+ ~CommandObjectRenderScriptRuntimeContext() override = default;
+};
- Stream *output_strm = nullptr;
- StreamFile outfile_stream;
- const FileSpec &outfile_spec = 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())
- {
- output_strm = &outfile_stream;
- result.GetOutputStream().Printf("Results written to '%s'", path);
- result.GetOutputStream().EOL();
- }
- else
- {
- result.AppendErrorWithFormat("Couldn't open file '%s'", path);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+class CommandObjectRenderScriptRuntimeAllocationDump
+ : public CommandObjectParsed {
+public:
+ CommandObjectRenderScriptRuntimeAllocationDump(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript allocation dump",
+ "Displays the contents of a particular allocation",
+ "renderscript allocation dump <ID>",
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched),
+ m_options() {}
+
+ ~CommandObjectRenderScriptRuntimeAllocationDump() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *exe_ctx) override {
+ Error err;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ m_outfile.SetFile(option_arg, true);
+ if (m_outfile.Exists()) {
+ m_outfile.Clear();
+ err.SetErrorStringWithFormat("file already exists: '%s'",
+ option_arg.str().c_str());
}
- else
- output_strm = &result.GetOutputStream();
-
- assert(output_strm != nullptr);
- bool success = runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id);
-
- if (success)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
-
- return true;
+ break;
+ default:
+ err.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
+ break;
+ }
+ return err;
}
-private:
- CommandOptions m_options;
-};
-
-OptionDefinition CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] = {
- {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename,
- "Print results to specified file instead of command line."},
- {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
+ void OptionParsingStarting(ExecutionContext *exe_ctx) override {
+ m_outfile.Clear();
+ }
-class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed
-{
-public:
- CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript allocation list",
- "List renderscript allocations and their information.", "renderscript allocation list",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched),
- m_options(interpreter)
- {
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_renderscript_runtime_alloc_dump_options);
}
- ~CommandObjectRenderScriptRuntimeAllocationList() override = default;
+ FileSpec m_outfile;
+ };
- Options *
- GetOptions() override
- {
- return &m_options;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc < 1) {
+ result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. "
+ "As well as an optional -f argument",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_id(0) {}
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue(uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'i':
- bool success;
- m_id = StringConvert::ToUInt32(option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
- }
- return error;
- }
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
- void
- OptionParsingStarting() override
- {
- m_id = 0;
- }
+ const char *id_cstr = command.GetArgumentAtIndex(0);
+ bool success = false;
+ const uint32_t id =
+ StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid allocation id argument '%s'",
+ id_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Stream *output_strm = nullptr;
+ StreamFile outfile_stream;
+ const FileSpec &outfile_spec =
+ 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()) {
+ output_strm = &outfile_stream;
+ result.GetOutputStream().Printf("Results written to '%s'", path);
+ result.GetOutputStream().EOL();
+ } else {
+ result.AppendErrorWithFormat("Couldn't open file '%s'", path);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else
+ output_strm = &result.GetOutputStream();
- const OptionDefinition *
- GetDefinitions() override
- {
- return g_option_table;
- }
+ assert(output_strm != nullptr);
+ bool dumped =
+ runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id);
- static OptionDefinition g_option_table[];
- uint32_t m_id;
- };
+ if (dumped)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
- m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_id);
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
+ return true;
+ }
private:
- CommandOptions m_options;
+ CommandOptions m_options;
};
-OptionDefinition CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] = {
- {LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex,
- "Only show details of a single allocation with specified id."},
- {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
+static OptionDefinition g_renderscript_runtime_alloc_list_options[] = {
+ {LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr,
+ nullptr, 0, eArgTypeIndex,
+ "Only show details of a single allocation with specified id."}};
-class CommandObjectRenderScriptRuntimeAllocationLoad : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeAllocationList
+ : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "renderscript allocation load", "Loads renderscript allocation contents from a file.",
- "renderscript allocation load <ID> <filename>", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeAllocationLoad() override = default;
-
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc != 2)
- {
- result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.",
- m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
- m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
-
- const char *id_cstr = command.GetArgumentAtIndex(0);
- bool convert_complete = false;
- const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
- if (!convert_complete)
- {
- result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const char *filename = command.GetArgumentAtIndex(1);
- bool success = runtime->LoadAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
-
- if (success)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
+ CommandObjectRenderScriptRuntimeAllocationList(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript allocation list",
+ "List renderscript allocations and their information.",
+ "renderscript allocation list",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_options() {}
+
+ ~CommandObjectRenderScriptRuntimeAllocationList() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_id(0) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *exe_ctx) override {
+ Error err;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'i':
+ if (option_arg.getAsInteger(0, m_id))
+ err.SetErrorStringWithFormat("invalid integer value for option '%c'",
+ short_option);
+ break;
+ default:
+ err.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
+ break;
+ }
+ return err;
+ }
+
+ void OptionParsingStarting(ExecutionContext *exe_ctx) override { m_id = 0; }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_renderscript_runtime_alloc_list_options);
+ }
+
+ uint32_t m_id;
+ };
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+ runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(),
+ m_options.m_id);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
- return true;
- }
+private:
+ CommandOptions m_options;
};
-class CommandObjectRenderScriptRuntimeAllocationSave : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeAllocationLoad
+ : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeAllocationSave(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "renderscript allocation save", "Write renderscript allocation contents to a file.",
- "renderscript allocation save <ID> <filename>", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
+ CommandObjectRenderScriptRuntimeAllocationLoad(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript allocation load",
+ "Loads renderscript allocation contents from a file.",
+ "renderscript allocation load <ID> <filename>",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptRuntimeAllocationLoad() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc != 2) {
+ result.AppendErrorWithFormat(
+ "'%s' takes 2 arguments, an allocation ID and filename to read from.",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+
+ const char *id_cstr = command.GetArgumentAtIndex(0);
+ bool success = false;
+ const uint32_t id =
+ StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid allocation id argument '%s'",
+ id_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectRenderScriptRuntimeAllocationSave() override = default;
+ const char *path = command.GetArgumentAtIndex(1);
+ bool loaded = runtime->LoadAllocation(result.GetOutputStream(), id, path,
+ m_exe_ctx.GetFramePtr());
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc != 2)
- {
- result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.",
- m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
- m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
-
- const char *id_cstr = command.GetArgumentAtIndex(0);
- bool convert_complete = false;
- const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
- if (!convert_complete)
- {
- result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const char *filename = command.GetArgumentAtIndex(1);
- bool success = runtime->SaveAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
-
- if (success)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
+ if (loaded)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
- return true;
- }
+ return true;
+ }
};
-class CommandObjectRenderScriptRuntimeAllocationRefresh : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeAllocationSave
+ : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeAllocationRefresh(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript allocation refresh",
- "Recomputes the details of all allocations.", "renderscript allocation refresh",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
+ CommandObjectRenderScriptRuntimeAllocationSave(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript allocation save",
+ "Write renderscript allocation contents to a file.",
+ "renderscript allocation save <ID> <filename>",
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptRuntimeAllocationSave() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc != 2) {
+ result.AppendErrorWithFormat(
+ "'%s' takes 2 arguments, an allocation ID and filename to read from.",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+
+ const char *id_cstr = command.GetArgumentAtIndex(0);
+ bool success = false;
+ const uint32_t id =
+ StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid allocation id argument '%s'",
+ id_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectRenderScriptRuntimeAllocationRefresh() override = default;
-
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
- m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ const char *path = command.GetArgumentAtIndex(1);
+ bool saved = runtime->SaveAllocation(result.GetOutputStream(), id, path,
+ m_exe_ctx.GetFramePtr());
- bool success = runtime->RecomputeAllAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr());
+ if (saved)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
- if (success)
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- else
- {
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
+ return true;
+ }
};
-class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword
-{
+class CommandObjectRenderScriptRuntimeAllocationRefresh
+ : public CommandObjectParsed {
public:
- CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript allocation",
- "Commands that deal with RenderScript allocations.", nullptr)
- {
- LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
- LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationDump(interpreter)));
- LoadSubCommand("save", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationSave(interpreter)));
- LoadSubCommand("load", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter)));
- LoadSubCommand("refresh", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationRefresh(interpreter)));
- }
-
- ~CommandObjectRenderScriptRuntimeAllocation() override = default;
+ CommandObjectRenderScriptRuntimeAllocationRefresh(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript allocation refresh",
+ "Recomputes the details of all allocations.",
+ "renderscript allocation refresh",
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptRuntimeAllocationRefresh() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+
+ bool success = runtime->RecomputeAllAllocations(result.GetOutputStream(),
+ m_exe_ctx.GetFramePtr());
+
+ if (success) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ } else {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
};
-class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
-{
+class CommandObjectRenderScriptRuntimeAllocation
+ : public CommandObjectMultiword {
public:
- CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript status", "Displays current RenderScript runtime status.",
- "renderscript status", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeStatus() override = default;
+ CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "renderscript allocation",
+ "Commands that deal with RenderScript allocations.", nullptr) {
+ LoadSubCommand(
+ "list",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
+ LoadSubCommand(
+ "dump",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeAllocationDump(interpreter)));
+ LoadSubCommand(
+ "save",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeAllocationSave(interpreter)));
+ LoadSubCommand(
+ "load",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter)));
+ LoadSubCommand(
+ "refresh",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationRefresh(
+ interpreter)));
+ }
+
+ ~CommandObjectRenderScriptRuntimeAllocation() override = default;
+};
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
- runtime->Status(result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
+class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed {
+public:
+ CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript status",
+ "Displays current RenderScript runtime status.",
+ "renderscript status",
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptRuntimeStatus() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ RenderScriptRuntime *runtime =
+ (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript);
+ runtime->Status(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
};
-class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
-{
+class CommandObjectRenderScriptRuntimeReduction
+ : public CommandObjectMultiword {
public:
- CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript", "Commands for operating on the RenderScript runtime.",
- "renderscript <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
- LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
- LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
- LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
- LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
- }
+ CommandObjectRenderScriptRuntimeReduction(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "renderscript reduction",
+ "Commands that handle general reduction kernels",
+ nullptr) {
+ LoadSubCommand(
+ "breakpoint",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeReductionBreakpoint(
+ interpreter)));
+ }
+ ~CommandObjectRenderScriptRuntimeReduction() override = default;
+};
- ~CommandObjectRenderScriptRuntime() override = default;
+class CommandObjectRenderScriptRuntime : public CommandObjectMultiword {
+public:
+ CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "renderscript",
+ "Commands for operating on the RenderScript runtime.",
+ "renderscript <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "module", CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeModule(interpreter)));
+ LoadSubCommand(
+ "status", CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeStatus(interpreter)));
+ LoadSubCommand(
+ "kernel", CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeKernel(interpreter)));
+ LoadSubCommand("context",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(
+ interpreter)));
+ LoadSubCommand(
+ "allocation",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
+ LoadSubCommand("scriptgroup",
+ NewCommandObjectRenderScriptScriptGroup(interpreter));
+ LoadSubCommand(
+ "reduction",
+ CommandObjectSP(
+ new CommandObjectRenderScriptRuntimeReduction(interpreter)));
+ }
+
+ ~CommandObjectRenderScriptRuntime() override = default;
};
-void
-RenderScriptRuntime::Initiate()
-{
- assert(!m_initiated);
-}
+void RenderScriptRuntime::Initiate() { assert(!m_initiated); }
RenderScriptRuntime::RenderScriptRuntime(Process *process)
- : lldb_private::CPPLanguageRuntime(process),
- m_initiated(false),
- m_debuggerPresentFlagged(false),
- m_breakAllKernels(false)
-{
- ModulesDidLoad(process->GetTarget().GetImages());
+ : lldb_private::CPPLanguageRuntime(process), m_initiated(false),
+ m_debuggerPresentFlagged(false), m_breakAllKernels(false),
+ m_ir_passes(nullptr) {
+ ModulesDidLoad(process->GetTarget().GetImages());
}
-lldb::CommandObjectSP
-RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter &interpreter)
-{
- return CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter));
+lldb::CommandObjectSP RenderScriptRuntime::GetCommandObject(
+ lldb_private::CommandInterpreter &interpreter) {
+ return CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter));
}
RenderScriptRuntime::~RenderScriptRuntime() = default;
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 2a0839a1a78b..a1211a2814b7 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -19,397 +19,560 @@
#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"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/lldb-private.h"
-namespace lldb_private
-{
-namespace lldb_renderscript
-{
+namespace lldb_private {
+namespace lldb_renderscript {
typedef uint32_t RSSlot;
class RSModuleDescriptor;
struct RSGlobalDescriptor;
struct RSKernelDescriptor;
+struct RSReductionDescriptor;
+struct RSScriptGroupDescriptor;
typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
-typedef std::array<uint32_t, 3> RSCoordinate;
+typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP;
-// Breakpoint Resolvers decide where a breakpoint is placed,
-// so having our own allows us to limit the search scope to RS kernel modules.
-// As well as check for .expand kernels as a fallback.
-class RSBreakpointResolver : public BreakpointResolver
-{
+struct RSCoordinate {
+ uint32_t x, y, z;
+
+ RSCoordinate() : x(), y(), z(){};
+
+ bool operator==(const lldb_renderscript::RSCoordinate &rhs) {
+ return x == rhs.x && y == rhs.y && z == rhs.z;
+ }
+};
+
+// Breakpoint Resolvers decide where a breakpoint is placed, so having our own
+// allows us to limit the search scope to RS kernel modules. As well as check
+// for .expand kernels as a fallback.
+class RSBreakpointResolver : public BreakpointResolver {
public:
- RSBreakpointResolver(Breakpoint *bkpt, ConstString name)
- : BreakpointResolver(bkpt, BreakpointResolver::NameResolver), m_kernel_name(name)
- {
- }
+ RSBreakpointResolver(Breakpoint *bp, ConstString name)
+ : BreakpointResolver(bp, BreakpointResolver::NameResolver),
+ m_kernel_name(name) {}
- void
- GetDescription(Stream *strm) override
- {
- if (strm)
- strm->Printf("RenderScript kernel breakpoint for '%s'", m_kernel_name.AsCString());
- }
+ void GetDescription(Stream *strm) override {
+ if (strm)
+ strm->Printf("RenderScript kernel breakpoint for '%s'",
+ m_kernel_name.AsCString());
+ }
- void
- Dump(Stream *s) const override
- {
- }
+ void Dump(Stream *s) const override {}
- Searcher::CallbackReturn
- SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr, bool containing) override;
+ Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
+ SymbolContext &context, Address *addr,
+ bool containing) override;
- Searcher::Depth
- GetDepth() override
- {
- return Searcher::eDepthModule;
- }
+ Searcher::Depth GetDepth() override { return Searcher::eDepthModule; }
- lldb::BreakpointResolverSP
- CopyForBreakpoint(Breakpoint &breakpoint) override
- {
- lldb::BreakpointResolverSP ret_sp(new RSBreakpointResolver(&breakpoint, m_kernel_name));
- return ret_sp;
- }
+ lldb::BreakpointResolverSP
+ CopyForBreakpoint(Breakpoint &breakpoint) override {
+ lldb::BreakpointResolverSP ret_sp(
+ new RSBreakpointResolver(&breakpoint, m_kernel_name));
+ return ret_sp;
+ }
protected:
- ConstString m_kernel_name;
+ ConstString m_kernel_name;
};
-struct RSKernelDescriptor
-{
+class RSReduceBreakpointResolver : public BreakpointResolver {
public:
- RSKernelDescriptor(const RSModuleDescriptor *module, const char *name, uint32_t slot)
- : m_module(module), m_name(name), m_slot(slot)
- {
- }
+ enum ReduceKernelTypeFlags {
+ eKernelTypeAll = ~(0),
+ eKernelTypeNone = 0,
+ eKernelTypeAccum = (1 << 0),
+ eKernelTypeInit = (1 << 1),
+ eKernelTypeComb = (1 << 2),
+ eKernelTypeOutC = (1 << 3),
+ eKernelTypeHalter = (1 << 4)
+ };
+
+ RSReduceBreakpointResolver(
+ Breakpoint *breakpoint, ConstString reduce_name,
+ std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules,
+ int kernel_types = eKernelTypeAll)
+ : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver),
+ m_reduce_name(reduce_name), m_rsmodules(rs_modules),
+ m_kernel_types(kernel_types) {
+ // The reduce breakpoint resolver handles adding breakpoints for named
+ // reductions.
+ // Breakpoints will be resolved for all constituent kernels in the named
+ // reduction
+ }
+
+ void GetDescription(Stream *strm) override {
+ if (strm)
+ strm->Printf("RenderScript reduce breakpoint for '%s'",
+ m_reduce_name.AsCString());
+ }
+
+ void Dump(Stream *s) const override {}
+
+ Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
+ SymbolContext &context, Address *addr,
+ bool containing) override;
+
+ Searcher::Depth GetDepth() override { return Searcher::eDepthModule; }
+
+ lldb::BreakpointResolverSP
+ CopyForBreakpoint(Breakpoint &breakpoint) override {
+ lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver(
+ &breakpoint, m_reduce_name, m_rsmodules, m_kernel_types));
+ return ret_sp;
+ }
- void
- Dump(Stream &strm) const;
+private:
+ ConstString m_reduce_name; // The name of the reduction
+ std::vector<lldb_renderscript::RSModuleDescriptorSP> *m_rsmodules;
+ int m_kernel_types;
+};
- const RSModuleDescriptor *m_module;
- ConstString m_name;
- RSSlot m_slot;
+struct RSKernelDescriptor {
+public:
+ RSKernelDescriptor(const RSModuleDescriptor *module, llvm::StringRef name,
+ uint32_t slot)
+ : m_module(module), m_name(name), m_slot(slot) {}
+
+ void Dump(Stream &strm) const;
+
+ const RSModuleDescriptor *m_module;
+ ConstString m_name;
+ RSSlot m_slot;
};
-struct RSGlobalDescriptor
-{
+struct RSGlobalDescriptor {
public:
- RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name) : m_module(module), m_name(name) {}
+ RSGlobalDescriptor(const RSModuleDescriptor *module, llvm::StringRef name)
+ : m_module(module), m_name(name) {}
- void
- Dump(Stream &strm) const;
+ void Dump(Stream &strm) const;
- const RSModuleDescriptor *m_module;
- ConstString m_name;
+ const RSModuleDescriptor *m_module;
+ ConstString m_name;
+};
+
+struct RSReductionDescriptor {
+ RSReductionDescriptor(const RSModuleDescriptor *module, uint32_t sig,
+ uint32_t accum_data_size, llvm::StringRef name,
+ llvm::StringRef init_name, llvm::StringRef accum_name,
+ llvm::StringRef comb_name, llvm::StringRef outc_name,
+ llvm::StringRef halter_name = ".")
+ : m_module(module), m_reduce_name(name), m_init_name(init_name),
+ m_accum_name(accum_name), m_comb_name(comb_name),
+ m_outc_name(outc_name), m_halter_name(halter_name) {
+ // TODO Check whether the combiner is an autogenerated name, and track
+ // this
+ }
+
+ void Dump(Stream &strm) const;
+
+ const RSModuleDescriptor *m_module;
+ ConstString m_reduce_name; // This is the name given to the general reduction
+ // as a group as passed to pragma
+ // reduce(m_reduce_name). There is no kernel function with this name
+ ConstString m_init_name; // The name of the initializer name. "." if no
+ // initializer given
+ ConstString m_accum_name; // The accumulator function name. "." if not given
+ ConstString m_comb_name; // The name of the combiner function. If this was not
+ // given, a name is generated by the
+ // compiler. TODO
+ ConstString m_outc_name; // The name of the outconverter
+
+ ConstString m_halter_name; // The name of the halter function. XXX This is not
+ // yet specified by the RenderScript
+ // compiler or runtime, and its semantics and existence is still under
+ // discussion by the
+ // RenderScript Contributors
+ RSSlot m_accum_sig; // metatdata signature for this reduction (bitwise mask of
+ // type information (see
+ // libbcc/include/bcinfo/MetadataExtractor.h
+ uint32_t m_accum_data_size; // Data size of the accumulator function input
+ bool m_comb_name_generated; // Was the combiner name generated by the compiler
};
-class RSModuleDescriptor
-{
+class RSModuleDescriptor {
+ bool ParseExportForeachCount(llvm::StringRef *, size_t n_lines);
+
+ bool ParseExportVarCount(llvm::StringRef *, size_t n_lines);
+
+ bool ParseExportReduceCount(llvm::StringRef *, size_t n_lines);
+
+ bool ParseBuildChecksum(llvm::StringRef *, size_t n_lines);
+
+ bool ParsePragmaCount(llvm::StringRef *, size_t n_lines);
+
public:
- RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {}
+ RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {}
+
+ ~RSModuleDescriptor() = default;
- ~RSModuleDescriptor() = default;
+ bool ParseRSInfo();
- bool
- ParseRSInfo();
+ void Dump(Stream &strm) const;
- void
- Dump(Stream &strm) const;
+ const lldb::ModuleSP m_module;
+ std::vector<RSKernelDescriptor> m_kernels;
+ std::vector<RSGlobalDescriptor> m_globals;
+ std::vector<RSReductionDescriptor> m_reductions;
+ std::map<std::string, std::string> m_pragmas;
+ std::string m_resname;
+};
- const lldb::ModuleSP m_module;
- std::vector<RSKernelDescriptor> m_kernels;
- std::vector<RSGlobalDescriptor> m_globals;
- std::map<std::string, std::string> m_pragmas;
- std::string m_resname;
+struct RSScriptGroupDescriptor {
+ struct Kernel {
+ ConstString m_name;
+ lldb::addr_t m_addr;
+ };
+ ConstString m_name;
+ std::vector<Kernel> m_kernels;
};
+typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList;
+
+class RSScriptGroupBreakpointResolver : public BreakpointResolver {
+public:
+ RSScriptGroupBreakpointResolver(Breakpoint *bp, const ConstString &name,
+ const RSScriptGroupList &groups,
+ bool stop_on_all)
+ : BreakpointResolver(bp, BreakpointResolver::NameResolver),
+ m_group_name(name), m_script_groups(groups),
+ m_stop_on_all(stop_on_all) {}
+
+ void GetDescription(Stream *strm) override {
+ if (strm)
+ strm->Printf("RenderScript ScriptGroup breakpoint for '%s'",
+ m_group_name.AsCString());
+ }
+
+ void Dump(Stream *s) const override {}
+
+ Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
+ SymbolContext &context, Address *addr,
+ bool containing) override;
+
+ Searcher::Depth GetDepth() override { return Searcher::eDepthModule; }
+
+ lldb::BreakpointResolverSP
+ CopyForBreakpoint(Breakpoint &breakpoint) override {
+ lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver(
+ &breakpoint, m_group_name, m_script_groups, m_stop_on_all));
+ return ret_sp;
+ }
+
+protected:
+ const RSScriptGroupDescriptorSP
+ FindScriptGroup(const ConstString &name) const {
+ for (auto sg : m_script_groups) {
+ if (ConstString::Compare(sg->m_name, name) == 0)
+ return sg;
+ }
+ return RSScriptGroupDescriptorSP();
+ }
+
+ ConstString m_group_name;
+ const RSScriptGroupList &m_script_groups;
+ bool m_stop_on_all;
+};
} // namespace lldb_renderscript
-class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime
-{
+class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime {
public:
- enum ModuleKind
- {
- eModuleKindIgnored,
- eModuleKindLibRS,
- eModuleKindDriver,
- eModuleKindImpl,
- eModuleKindKernelObj
- };
+ enum ModuleKind {
+ eModuleKindIgnored,
+ eModuleKindLibRS,
+ eModuleKindDriver,
+ eModuleKindImpl,
+ eModuleKindKernelObj
+ };
+
+ ~RenderScriptRuntime() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
- ~RenderScriptRuntime() override;
+ static lldb::CommandObjectSP
+ GetCommandObject(CommandInterpreter &interpreter);
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ static lldb_private::ConstString GetPluginNameStatic();
- static void
- Terminate();
+ static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp);
- static lldb_private::LanguageRuntime *
- CreateInstance(Process *process, lldb::LanguageType language);
+ static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp);
- static lldb::CommandObjectSP
- GetCommandObject(CommandInterpreter &interpreter);
+ static void ModulesDidLoad(const lldb::ProcessSP &process_sp,
+ const ModuleList &module_list);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ bool IsVTableName(const char *name) override;
- static bool
- IsRenderScriptModule(const lldb::ModuleSP &module_sp);
+ bool GetDynamicTypeAndAddress(ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address,
+ Value::ValueType &value_type) override;
- static ModuleKind
- GetModuleKind(const lldb::ModuleSP &module_sp);
+ TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) override;
- static void
- ModulesDidLoad(const lldb::ProcessSP &process_sp, const ModuleList &module_list);
+ bool CouldHaveDynamicValue(ValueObject &in_value) override;
- bool
- IsVTableName(const char *name) override;
+ lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bp,
+ bool catch_bp,
+ bool throw_bp) override;
- bool
- GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type) override;
+ bool LoadModule(const lldb::ModuleSP &module_sp);
- TypeAndOrName
- FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override;
+ void DumpModules(Stream &strm) const;
- bool
- CouldHaveDynamicValue(ValueObject &in_value) override;
+ void DumpContexts(Stream &strm) const;
- lldb::BreakpointResolverSP
- CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
+ void DumpKernels(Stream &strm) const;
- bool
- LoadModule(const lldb::ModuleSP &module_sp);
+ bool DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id);
- void
- DumpModules(Stream &strm) const;
+ void ListAllocations(Stream &strm, StackFrame *frame_ptr,
+ const uint32_t index);
- void
- DumpContexts(Stream &strm) const;
+ bool RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr);
- void
- DumpKernels(Stream &strm) const;
+ bool PlaceBreakpointOnKernel(
+ lldb::TargetSP target, Stream &messages, const char *name,
+ const lldb_renderscript::RSCoordinate *coords = nullptr);
- bool
- DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id);
+ bool PlaceBreakpointOnReduction(
+ lldb::TargetSP target, Stream &messages, const char *reduce_name,
+ const lldb_renderscript::RSCoordinate *coords = nullptr,
+ int kernel_types = ~(0));
- void
- ListAllocations(Stream &strm, StackFrame *frame_ptr, const uint32_t index);
+ bool PlaceBreakpointOnScriptGroup(lldb::TargetSP target, Stream &strm,
+ const ConstString &name, bool stop_on_all);
- bool
- RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr);
+ void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
- void
- PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int, 3> coords, Error &error,
- lldb::TargetSP target);
+ void Status(Stream &strm) const;
- void
- SetBreakAllKernels(bool do_break, lldb::TargetSP target);
+ void ModulesDidLoad(const ModuleList &module_list) override;
- void
- Status(Stream &strm) const;
+ bool LoadAllocation(Stream &strm, const uint32_t alloc_id,
+ const char *filename, StackFrame *frame_ptr);
- void
- ModulesDidLoad(const ModuleList &module_list) override;
+ bool SaveAllocation(Stream &strm, const uint32_t alloc_id,
+ const char *filename, StackFrame *frame_ptr);
- bool
- LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr);
+ void Update();
- bool
- SaveAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr);
+ void Initiate();
- void
- Update();
+ const lldb_renderscript::RSScriptGroupList &GetScriptGroups() const {
+ return m_scriptGroups;
+ };
- void
- Initiate();
+ bool IsKnownKernel(const ConstString &name) {
+ for (const auto &module : m_rsmodules)
+ for (const auto &kernel : module->m_kernels)
+ if (kernel.m_name == name)
+ return true;
+ return false;
+ }
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- static bool
- GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, Thread *thread_ptr);
+ static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord,
+ Thread *thread_ptr);
+
+ bool ResolveKernelName(lldb::addr_t kernel_address, ConstString &name);
protected:
- struct ScriptDetails;
- struct AllocationDetails;
- struct Element;
-
- void
- InitSearchFilter(lldb::TargetSP target)
- {
- if (!m_filtersp)
- m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
- }
-
- void
- FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
+ struct ScriptDetails;
+ struct AllocationDetails;
+ struct Element;
+
+ lldb_renderscript::RSScriptGroupList m_scriptGroups;
+
+ void InitSearchFilter(lldb::TargetSP target) {
+ if (!m_filtersp)
+ m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
+ }
+
+ void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
+
+ void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
- void
- LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
+ bool RefreshAllocation(AllocationDetails *alloc, StackFrame *frame_ptr);
- bool
- RefreshAllocation(AllocationDetails *allocation, StackFrame *frame_ptr);
+ bool EvalRSExpression(const char *expression, StackFrame *frame_ptr,
+ uint64_t *result);
- bool
- EvalRSExpression(const char *expression, StackFrame *frame_ptr, uint64_t *result);
+ lldb::BreakpointSP CreateScriptGroupBreakpoint(const ConstString &name,
+ bool multi);
- lldb::BreakpointSP
- CreateKernelBreakpoint(const ConstString &name);
+ lldb::BreakpointSP CreateKernelBreakpoint(const ConstString &name);
- void
- BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
+ lldb::BreakpointSP CreateReductionBreakpoint(const ConstString &name,
+ int kernel_types);
- struct RuntimeHook;
- typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook *hook_info,
- ExecutionContext &context); // Please do this!
+ void BreakOnModuleKernels(
+ const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
- struct HookDefn
- {
- const char *name;
- const char *symbol_name_m32; // mangled name for the 32 bit architectures
- const char *symbol_name_m64; // mangled name for the 64 bit archs
- uint32_t version;
- ModuleKind kind;
- CaptureStateFn grabber;
- };
+ struct RuntimeHook;
+ typedef void (RenderScriptRuntime::*CaptureStateFn)(
+ RuntimeHook *hook_info,
+ ExecutionContext &context); // Please do this!
- struct RuntimeHook
- {
- lldb::addr_t address;
- const HookDefn *defn;
- lldb::BreakpointSP bp_sp;
- };
+ struct HookDefn {
+ const char *name;
+ const char *symbol_name_m32; // mangled name for the 32 bit architectures
+ const char *symbol_name_m64; // mangled name for the 64 bit archs
+ uint32_t version;
+ ModuleKind kind;
+ CaptureStateFn grabber;
+ };
- typedef std::shared_ptr<RuntimeHook> RuntimeHookSP;
+ struct RuntimeHook {
+ lldb::addr_t address;
+ const HookDefn *defn;
+ lldb::BreakpointSP bp_sp;
+ };
- lldb::ModuleSP m_libRS;
- lldb::ModuleSP m_libRSDriver;
- lldb::ModuleSP m_libRSCpuRef;
- std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules;
+ typedef std::shared_ptr<RuntimeHook> RuntimeHookSP;
- std::vector<std::unique_ptr<ScriptDetails>> m_scripts;
- std::vector<std::unique_ptr<AllocationDetails>> m_allocations;
+ lldb::ModuleSP m_libRS;
+ lldb::ModuleSP m_libRSDriver;
+ lldb::ModuleSP m_libRSCpuRef;
+ std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules;
- std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings;
- std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
- std::map<lldb::user_id_t, std::shared_ptr<uint32_t>> m_conditional_breaks;
+ std::vector<std::unique_ptr<ScriptDetails>> m_scripts;
+ std::vector<std::unique_ptr<AllocationDetails>> m_allocations;
- lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API
+ std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP>
+ m_scriptMappings;
+ std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
+ std::map<lldb::user_id_t, std::unique_ptr<lldb_renderscript::RSCoordinate>>
+ m_conditional_breaks;
- bool m_initiated;
- bool m_debuggerPresentFlagged;
- bool m_breakAllKernels;
- static const HookDefn s_runtimeHookDefns[];
- static const size_t s_runtimeHookCount;
+ lldb::SearchFilterSP
+ m_filtersp; // Needed to create breakpoints through Target API
+
+ bool m_initiated;
+ bool m_debuggerPresentFlagged;
+ bool m_breakAllKernels;
+ static const HookDefn s_runtimeHookDefns[];
+ static const size_t s_runtimeHookCount;
+ LLVMUserExpression::IRPasses *m_ir_passes;
private:
- RenderScriptRuntime(Process *process); // Call CreateInstance instead.
-
- static bool
- HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+ RenderScriptRuntime(Process *process); // Call CreateInstance instead.
+
+ static bool HookCallback(void *baton, StoppointCallbackContext *ctx,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ void HookCallback(RuntimeHook *hook_info, ExecutionContext &context);
+
+ // Callback function when 'debugHintScriptGroup2' executes on the target.
+ void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info,
+ ExecutionContext &context);
+
+ void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context);
- static bool
- KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
+ void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context);
- void
- HookCallback(RuntimeHook *hook_info, ExecutionContext &context);
+ void CaptureAllocationDestroy(RuntimeHook *hook_info,
+ ExecutionContext &context);
- void
- CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context);
+ void CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context);
- void
- CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context);
+ void CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info,
+ ExecutionContext &context);
- void
- CaptureAllocationDestroy(RuntimeHook *hook_info, ExecutionContext &context);
+ AllocationDetails *FindAllocByID(Stream &strm, const uint32_t alloc_id);
- void
- CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context);
+ std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails *alloc,
+ StackFrame *frame_ptr);
- void
- CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info, ExecutionContext &context);
+ void SetElementSize(Element &elem);
- AllocationDetails *
- FindAllocByID(Stream &strm, const uint32_t alloc_id);
+ static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP,
+ const char *var_name, uint64_t &val);
- std::shared_ptr<uint8_t>
- GetAllocationData(AllocationDetails *allocation, StackFrame *frame_ptr);
+ void FindStructTypeName(Element &elem, StackFrame *frame_ptr);
- void
- SetElementSize(Element &elem);
+ size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer,
+ size_t offset, const Element &elem);
- static bool
- GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char *var_name, uint64_t &val);
+ size_t CalculateElementHeaderSize(const Element &elem);
- void
- FindStructTypeName(Element &elem, StackFrame *frame_ptr);
+ void SetConditional(lldb::BreakpointSP bp, lldb_private::Stream &messages,
+ const lldb_renderscript::RSCoordinate &coord);
+ //
+ // Helper functions for jitting the runtime
+ //
- size_t
- PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element &elem);
+ bool JITDataPointer(AllocationDetails *alloc, StackFrame *frame_ptr,
+ uint32_t x = 0, uint32_t y = 0, uint32_t z = 0);
- size_t
- CalculateElementHeaderSize(const Element &elem);
+ bool JITTypePointer(AllocationDetails *alloc, StackFrame *frame_ptr);
- //
- // Helper functions for jitting the runtime
- //
+ bool JITTypePacked(AllocationDetails *alloc, StackFrame *frame_ptr);
- bool
- JITDataPointer(AllocationDetails *allocation, StackFrame *frame_ptr,
- uint32_t x = 0, uint32_t y = 0, uint32_t z = 0);
+ bool JITElementPacked(Element &elem, const lldb::addr_t context,
+ StackFrame *frame_ptr);
- bool
- JITTypePointer(AllocationDetails *allocation, StackFrame *frame_ptr);
+ bool JITAllocationSize(AllocationDetails *alloc, StackFrame *frame_ptr);
- bool
- JITTypePacked(AllocationDetails *allocation, StackFrame *frame_ptr);
+ bool JITSubelements(Element &elem, const lldb::addr_t context,
+ StackFrame *frame_ptr);
- bool
- JITElementPacked(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr);
+ bool JITAllocationStride(AllocationDetails *alloc, StackFrame *frame_ptr);
- bool
- JITAllocationSize(AllocationDetails *allocation, StackFrame *frame_ptr);
+ // Search for a script detail object using a target address.
+ // If a script does not currently exist this function will return nullptr.
+ // If 'create' is true and there is no previous script with this address,
+ // then a new Script detail object will be created for this address and
+ // returned.
+ ScriptDetails *LookUpScript(lldb::addr_t address, bool create);
- bool
- JITSubelements(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr);
+ // Search for a previously saved allocation detail object using a target
+ // address.
+ // If an allocation does not exist for this address then nullptr will be
+ // returned.
+ AllocationDetails *LookUpAllocation(lldb::addr_t address);
- bool
- JITAllocationStride(AllocationDetails *allocation, StackFrame *frame_ptr);
+ // Creates a new allocation with the specified address assigning a new ID and
+ // removes
+ // any previous stored allocation which has the same address.
+ AllocationDetails *CreateAllocation(lldb::addr_t address);
- // Search for a script detail object using a target address.
- // If a script does not currently exist this function will return nullptr.
- // If 'create' is true and there is no previous script with this address,
- // then a new Script detail object will be created for this address and returned.
- ScriptDetails *
- LookUpScript(lldb::addr_t address, bool create);
+ bool GetOverrideExprOptions(clang::TargetOptions &prototype) override;
- // Search for a previously saved allocation detail object using a target address.
- // If an allocation does not exist for this address then nullptr will be returned.
- // If 'create' is true and there is no previous allocation then a new allocation
- // detail object will be created for this address and returned.
- AllocationDetails *
- LookUpAllocation(lldb::addr_t address, bool create);
+ bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override;
};
} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
new file mode 100644
index 000000000000..a8202dd08814
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
@@ -0,0 +1,162 @@
+//===-- RenderScriptScriptGroup.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "RenderScriptRuntime.h"
+#include "RenderScriptScriptGroup.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_renderscript;
+
+class CommandObjectRenderScriptScriptGroupBreakpointSet
+ : public CommandObjectParsed {
+public:
+ CommandObjectRenderScriptScriptGroupBreakpointSet(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "renderscript scriptgroup breakpoint set",
+ "Place a breakpoint on all kernels forming a script group.",
+ "renderscript scriptgroup breakpoint set <group_name>",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptScriptGroupBreakpointSet() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Stream &stream = result.GetOutputStream();
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+ assert(runtime);
+ auto &target = m_exe_ctx.GetTargetSP();
+ bool stop_on_all = false;
+ const llvm::StringRef long_stop_all("--stop-on-all"), short_stop_all("-a");
+ std::vector<ConstString> sites;
+ sites.reserve(command.GetArgumentCount());
+ for (size_t i = 0; i < command.GetArgumentCount(); ++i) {
+ const auto arg = command.GetArgumentAtIndex(i);
+ if (long_stop_all == arg || short_stop_all == arg)
+ stop_on_all = true;
+ else
+ sites.push_back(ConstString(arg));
+ }
+ for (const auto &name : sites) {
+ runtime->PlaceBreakpointOnScriptGroup(target, stream, name, stop_on_all);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
+
+class CommandObjectRenderScriptScriptGroupBreakpoint
+ : public CommandObjectMultiword {
+public:
+ CommandObjectRenderScriptScriptGroupBreakpoint(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "renderscript scriptgroup breakpoint",
+ "Renderscript scriptgroup breakpoint interaction.",
+ "renderscript scriptgroup breakpoint set [--stop-on-all/-a]"
+ "<scriptgroup name> ...",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched) {
+ LoadSubCommand(
+ "set",
+ CommandObjectSP(new CommandObjectRenderScriptScriptGroupBreakpointSet(
+ interpreter)));
+ }
+
+ ~CommandObjectRenderScriptScriptGroupBreakpoint() override = default;
+};
+
+class CommandObjectRenderScriptScriptGroupList : public CommandObjectParsed {
+public:
+ CommandObjectRenderScriptScriptGroupList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript scriptgroup list",
+ "List all currently discovered script groups.",
+ "renderscript scriptgroup list",
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched) {}
+
+ ~CommandObjectRenderScriptScriptGroupList() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Stream &stream = result.GetOutputStream();
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
+ eLanguageTypeExtRenderScript));
+ assert(runtime);
+ const RSScriptGroupList &groups = runtime->GetScriptGroups();
+ // print script group count
+ stream.Printf("%" PRIu64 " script %s", uint64_t(groups.size()),
+ (groups.size() == 1) ? "group" : "groups");
+ stream.EOL();
+ // print script group details
+ stream.IndentMore();
+ for (const RSScriptGroupDescriptorSP &g : groups) {
+ if (g) {
+ stream.Indent();
+ // script group name
+ stream.Printf("%s", g->m_name.AsCString());
+ stream.EOL();
+ // print out the kernels
+ stream.IndentMore();
+ for (const auto &k : g->m_kernels) {
+ stream.Indent();
+ stream.Printf(". %s", k.m_name.AsCString());
+ stream.EOL();
+ }
+ stream.IndentLess();
+ }
+ }
+ stream.IndentLess();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
+
+class CommandObjectRenderScriptScriptGroup : public CommandObjectMultiword {
+public:
+ CommandObjectRenderScriptScriptGroup(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "renderscript scriptgroup",
+ "Command set for interacting with scriptgroups.",
+ nullptr, eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched) {
+ LoadSubCommand(
+ "breakpoint",
+ CommandObjectSP(
+ new CommandObjectRenderScriptScriptGroupBreakpoint(interpreter)));
+ LoadSubCommand(
+ "list", CommandObjectSP(
+ new CommandObjectRenderScriptScriptGroupList(interpreter)));
+ }
+
+ ~CommandObjectRenderScriptScriptGroup() override = default;
+};
+
+lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup(
+ lldb_private::CommandInterpreter &interpreter) {
+ return CommandObjectSP(new CommandObjectRenderScriptScriptGroup(interpreter));
+}
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h
new file mode 100644
index 000000000000..5c5608c99862
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h
@@ -0,0 +1,18 @@
+//===-- RenderScriptScriptGroup.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_RenderScriptScriptGroup_h_
+#define liblldb_RenderScriptScriptGroup_h_
+
+#include "lldb/Interpreter/CommandInterpreter.h"
+
+lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup(
+ lldb_private::CommandInterpreter &interpreter);
+
+#endif // liblldb_RenderScriptScriptGroup_h_
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
new file mode 100644
index 000000000000..ba531b2e3f2d
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
@@ -0,0 +1,297 @@
+//===-- RenderScriptx86ABIFixups.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 <set>
+
+// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IRReader/IRReader.h"
+#include "llvm/Pass.h"
+
+// Project includes
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb_private;
+namespace {
+
+bool isRSAPICall(llvm::Module &module, llvm::CallInst *call_inst) {
+ // TODO get the list of renderscript modules from lldb and check if
+ // this llvm::Module calls into any of them.
+ (void)module;
+ const auto func_name = call_inst->getCalledFunction()->getName();
+ if (func_name.startswith("llvm") || func_name.startswith("lldb"))
+ return false;
+
+ if (call_inst->getCalledFunction()->isIntrinsic())
+ return false;
+
+ return true;
+}
+
+bool isRSLargeReturnCall(llvm::Module &module, llvm::CallInst *call_inst) {
+ // i686 and x86_64 returns for large vectors in the RenderScript API are not
+ // handled as normal
+ // register pairs, but as a hidden sret type. This is not reflected in the
+ // debug info or mangled
+ // symbol name, and the android ABI for x86 and x86_64, (as well as the
+ // emulators) specifies there is
+ // no AVX, so bcc generates an sret function because we cannot natively return
+ // 256 bit vectors.
+ // This function simply checks whether a function has a > 128bit return type.
+ // It is perhaps an
+ // unreliable heuristic, and relies on bcc not generating AVX code, so if the
+ // android ABI one day
+ // provides for AVX, this function may go out of fashion.
+ (void)module;
+ if (!call_inst || !call_inst->getCalledFunction())
+ return false;
+
+ return call_inst->getCalledFunction()
+ ->getReturnType()
+ ->getPrimitiveSizeInBits() > 128;
+}
+
+bool isRSAllocationPtrTy(const llvm::Type *type) {
+ if (!type->isPointerTy())
+ return false;
+ auto ptr_type = type->getPointerElementType();
+
+ return ptr_type->isStructTy() &&
+ ptr_type->getStructName().startswith("struct.rs_allocation");
+}
+
+bool isRSAllocationTyCallSite(llvm::Module &module, llvm::CallInst *call_inst) {
+ (void)module;
+ if (!call_inst->hasByValArgument())
+ return false;
+ for (const auto &param : call_inst->operand_values())
+ if (isRSAllocationPtrTy(param->getType()))
+ return true;
+ return false;
+}
+
+llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
+ // on x86 StructReturn functions return a pointer to the return value, rather
+ // than the return
+ // value itself [ref](http://www.agner.org/optimize/calling_conventions.pdf
+ // section 6).
+ // We create a return type by getting the pointer type of the old return type,
+ // and inserting a new
+ // initial argument of pointer type of the original return type.
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_EXPRESSIONS));
+
+ assert(call_inst && "no CallInst");
+ llvm::Function *orig = call_inst->getCalledFunction();
+ assert(orig && "CallInst has no called function");
+ llvm::FunctionType *orig_type = orig->getFunctionType();
+ auto name = orig->getName();
+ if (log)
+ log->Printf("%s - cloning to StructRet function for '%s'", __FUNCTION__,
+ name.str().c_str());
+
+ unsigned num_params = orig_type->getNumParams();
+ std::vector<llvm::Type *> new_params{num_params + 1, nullptr};
+ std::vector<llvm::Type *> params{orig_type->param_begin(),
+ orig_type->param_end()};
+
+ // This may not work if the function is somehow declared void as llvm is
+ // strongly typed
+ // and represents void* with i8*
+ assert(!orig_type->getReturnType()->isVoidTy() &&
+ "Cannot add StructRet attribute to void function");
+ llvm::PointerType *return_type_ptr_type =
+ llvm::PointerType::getUnqual(orig->getReturnType());
+ assert(return_type_ptr_type &&
+ "failed to get function return type PointerType");
+ if (!return_type_ptr_type)
+ return nullptr;
+
+ if (log)
+ log->Printf("%s - return type pointer type for StructRet clone @ '0x%p':\n",
+ __FUNCTION__, (void *)return_type_ptr_type);
+ // put the the sret pointer argument in place at the beginning of the argument
+ // list.
+ params.emplace(params.begin(), return_type_ptr_type);
+ assert(params.size() == num_params + 1);
+ return llvm::FunctionType::get(return_type_ptr_type, params,
+ orig->isVarArg());
+}
+
+bool findRSCallSites(llvm::Module &module,
+ std::set<llvm::CallInst *> &rs_callsites,
+ bool (*predicate)(llvm::Module &, llvm::CallInst *)) {
+ bool found = false;
+
+ for (auto &func : module.getFunctionList())
+ for (auto &block : func.getBasicBlockList())
+ for (auto &inst : block) {
+ llvm::CallInst *call_inst =
+ llvm::dyn_cast_or_null<llvm::CallInst>(&inst);
+ if (!call_inst || !call_inst->getCalledFunction())
+ // This is not the call-site you are looking for...
+ continue;
+ if (isRSAPICall(module, call_inst) && predicate(module, call_inst)) {
+ rs_callsites.insert(call_inst);
+ found = true;
+ }
+ }
+ return found;
+}
+
+bool fixupX86StructRetCalls(llvm::Module &module) {
+ bool changed = false;
+ // changing a basic block while iterating over it seems to have some undefined
+ // behaviour
+ // going on so we find all RS callsites first, then fix them up after
+ // consuming
+ // the iterator.
+ std::set<llvm::CallInst *> rs_callsites;
+ if (!findRSCallSites(module, rs_callsites, isRSLargeReturnCall))
+ return false;
+
+ for (auto call_inst : rs_callsites) {
+ llvm::FunctionType *new_func_type = cloneToStructRetFnTy(call_inst);
+ assert(new_func_type &&
+ "failed to clone functionType for Renderscript ABI fixup");
+
+ llvm::CallSite call_site(call_inst);
+ llvm::Function *func = call_inst->getCalledFunction();
+ assert(func && "cannot resolve function in RenderScriptRuntime");
+ // Copy the original call arguments
+ std::vector<llvm::Value *> new_call_args(call_site.arg_begin(),
+ call_site.arg_end());
+
+ // Allocate enough space to store the return value of the original function
+ // we pass a pointer to this allocation as the StructRet param, and then
+ // copy its
+ // value into the lldb return value
+ llvm::AllocaInst *return_value_alloc = new llvm::AllocaInst(
+ func->getReturnType(), "var_vector_return_alloc", call_inst);
+ // use the new allocation as the new first argument
+ new_call_args.emplace(new_call_args.begin(),
+ llvm::cast<llvm::Value>(return_value_alloc));
+ llvm::PointerType *new_func_ptr_type =
+ llvm::PointerType::get(new_func_type, 0);
+ // Create the type cast from the old function type to the new one
+ llvm::Constant *new_func_cast = llvm::ConstantExpr::getCast(
+ llvm::Instruction::BitCast, func, new_func_ptr_type);
+ // create an allocation for a new function pointer
+ llvm::AllocaInst *new_func_ptr =
+ new llvm::AllocaInst(new_func_ptr_type, "new_func_ptr", call_inst);
+ // store the new_func_cast to the newly allocated space
+ (void)new llvm::StoreInst(new_func_cast, new_func_ptr,
+ "new_func_ptr_load_cast", call_inst);
+ // load the new function address ready for a jump
+ llvm::LoadInst *new_func_addr_load =
+ new llvm::LoadInst(new_func_ptr, "load_func_pointer", call_inst);
+ // and create a callinstruction from it
+ llvm::CallInst *new_call_inst = llvm::CallInst::Create(
+ new_func_addr_load, new_call_args, "new_func_call", call_inst);
+ new_call_inst->setCallingConv(call_inst->getCallingConv());
+ new_call_inst->setTailCall(call_inst->isTailCall());
+ llvm::LoadInst *lldb_save_result_address =
+ new llvm::LoadInst(return_value_alloc, "save_return_val", call_inst);
+
+ // Now remove the old broken call
+ call_inst->replaceAllUsesWith(lldb_save_result_address);
+ call_inst->eraseFromParent();
+ changed = true;
+ }
+ return changed;
+}
+
+bool fixupRSAllocationStructByValCalls(llvm::Module &module) {
+ // On x86_64, calls to functions in the RS runtime that take an
+ // `rs_allocation` type argument
+ // are actually handled as by-ref params by bcc, but appear to be passed by
+ // value by lldb (the callsite all use
+ // `struct byval`).
+ // On x86_64 Linux, struct arguments are transferred in registers if the
+ // struct size is no bigger than
+ // 128bits [ref](http://www.agner.org/optimize/calling_conventions.pdf)
+ // section 7.1 "Passing and returning objects"
+ // otherwise passed on the stack.
+ // an object of type `rs_allocation` is actually 256bits, so should be passed
+ // on the stack. However, code generated
+ // by bcc actually treats formal params of type `rs_allocation` as
+ // `rs_allocation *` so we need to convert the
+ // calling convention to pass by reference, and remove any hint of byval from
+ // formal parameters.
+ bool changed = false;
+ std::set<llvm::CallInst *> rs_callsites;
+ if (!findRSCallSites(module, rs_callsites, isRSAllocationTyCallSite))
+ return false;
+
+ std::set<llvm::Function *> rs_functions;
+
+ // for all call instructions
+ for (auto call_inst : rs_callsites) {
+ // add the called function to a set so that we can strip its byval
+ // attributes in another pass
+ rs_functions.insert(call_inst->getCalledFunction());
+
+ // get the function attributes
+ llvm::AttributeSet call_attribs = call_inst->getAttributes();
+
+ // iterate over the argument attributes
+ for (size_t i = 1; i <= call_attribs.getNumSlots(); ++i) {
+ // if this argument is passed by val
+ if (call_attribs.hasAttribute(i, llvm::Attribute::ByVal)) {
+ // strip away the byval attribute
+ call_inst->removeAttribute(i, llvm::Attribute::ByVal);
+ changed = true;
+ }
+ }
+ }
+
+ llvm::AttributeSet attr_byval =
+ llvm::AttributeSet::get(module.getContext(), 1u, llvm::Attribute::ByVal);
+
+ // for all called function decls
+ for (auto func : rs_functions) {
+ // inspect all of the arguments in the call
+ llvm::SymbolTableList<llvm::Argument> &arg_list = func->getArgumentList();
+ for (auto &arg : arg_list) {
+ if (arg.hasByValAttr()) {
+ arg.removeAttr(attr_byval);
+ changed = true;
+ }
+ }
+ }
+ return changed;
+}
+} // end anonymous namespace
+
+namespace lldb_private {
+namespace lldb_renderscript {
+
+bool fixupX86FunctionCalls(llvm::Module &module) {
+ return fixupX86StructRetCalls(module);
+}
+
+bool fixupX86_64FunctionCalls(llvm::Module &module) {
+ bool changed = false;
+ changed |= fixupX86StructRetCalls(module);
+ changed |= fixupRSAllocationStructByValCalls(module);
+ return changed;
+}
+
+} // end namespace lldb_renderscript
+} // end namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h
new file mode 100644
index 000000000000..b2caea49bd1e
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h
@@ -0,0 +1,23 @@
+//===-- RenderScriptx86ABIFixups.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_RENDERSCRIPT_X86_H
+#define LLDB_RENDERSCRIPT_X86_H
+
+#include "llvm/IR/Module.h"
+
+namespace lldb_private {
+namespace lldb_renderscript {
+
+bool fixupX86FunctionCalls(llvm::Module &module);
+
+bool fixupX86_64FunctionCalls(llvm::Module &module);
+}
+}
+#endif
diff --git a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
index a9d13ac79c37..35247edfbd56 100644
--- a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
+++ b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
@@ -11,80 +11,66 @@
#include "lldb/Target/MemoryHistory.h"
-#include "lldb/lldb-private.h"
+#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/UserExpression.h"
-#include "lldb/Target/ThreadList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Core/Module.h"
-#include "Plugins/Process/Utility/HistoryThread.h"
-#include "lldb/Core/ValueObject.h"
+#include "lldb/Target/ThreadList.h"
+#include "lldb/lldb-private.h"
#include <sstream>
using namespace lldb;
using namespace lldb_private;
-MemoryHistorySP
-MemoryHistoryASan::CreateInstance (const ProcessSP &process_sp)
-{
- if (!process_sp.get())
- return NULL;
+MemoryHistorySP MemoryHistoryASan::CreateInstance(const ProcessSP &process_sp) {
+ if (!process_sp.get())
+ return NULL;
- Target & target = process_sp->GetTarget();
+ Target &target = process_sp->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- for (size_t i = 0; i < num_modules; ++i)
- {
- Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
+ const ModuleList &target_modules = target.GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ for (size_t i = 0; i < num_modules; ++i) {
+ Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
- const Symbol* symbol = module_pointer->FindFirstSymbolWithNameAndType(
- ConstString("__asan_get_alloc_stack"),
- lldb::eSymbolTypeAny);
+ const Symbol *symbol = module_pointer->FindFirstSymbolWithNameAndType(
+ ConstString("__asan_get_alloc_stack"), lldb::eSymbolTypeAny);
- if (symbol != nullptr)
- return MemoryHistorySP(new MemoryHistoryASan(process_sp));
- }
+ if (symbol != nullptr)
+ return MemoryHistorySP(new MemoryHistoryASan(process_sp));
+ }
- return MemoryHistorySP();
+ return MemoryHistorySP();
}
-void
-MemoryHistoryASan::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "ASan memory history provider.",
- CreateInstance);
+void MemoryHistoryASan::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "ASan memory history provider.", CreateInstance);
}
-void
-MemoryHistoryASan::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void MemoryHistoryASan::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-ConstString
-MemoryHistoryASan::GetPluginNameStatic()
-{
- static ConstString g_name("asan");
- return g_name;
+ConstString MemoryHistoryASan::GetPluginNameStatic() {
+ static ConstString g_name("asan");
+ return g_name;
}
-MemoryHistoryASan::MemoryHistoryASan(const ProcessSP &process_sp)
-{
- if (process_sp)
- m_process_wp = process_sp;
+MemoryHistoryASan::MemoryHistoryASan(const ProcessSP &process_sp) {
+ if (process_sp)
+ m_process_wp = process_sp;
}
-const char *
-memory_history_asan_command_prefix = R"(
+const char *memory_history_asan_command_prefix = R"(
extern "C"
{
size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size, int *thread_id);
@@ -102,109 +88,117 @@ memory_history_asan_command_prefix = R"(
};
)";
-const char *
-memory_history_asan_command_format = R"(
+const char *memory_history_asan_command_format =
+ R"(
data t;
- t.alloc_count = __asan_get_alloc_stack((void *)0x%)" PRIx64 R"(, t.alloc_trace, 256, &t.alloc_tid);
- t.free_count = __asan_get_free_stack((void *)0x%)" PRIx64 R"(, t.free_trace, 256, &t.free_tid);
+ t.alloc_count = __asan_get_alloc_stack((void *)0x%)" PRIx64
+ R"(, t.alloc_trace, 256, &t.alloc_tid);
+ t.free_count = __asan_get_free_stack((void *)0x%)" PRIx64
+ R"(, t.free_trace, 256, &t.free_tid);
t;
)";
-static void CreateHistoryThreadFromValueObject(ProcessSP process_sp, ValueObjectSP return_value_sp, const char *type, const char *thread_name, HistoryThreads & result)
-{
- std::string count_path = "." + std::string(type) + "_count";
- std::string tid_path = "." + std::string(type) + "_tid";
- std::string trace_path = "." + std::string(type) + "_trace";
-
- ValueObjectSP count_sp = return_value_sp->GetValueForExpressionPath(count_path.c_str());
- ValueObjectSP tid_sp = return_value_sp->GetValueForExpressionPath(tid_path.c_str());
-
- if (!count_sp || !tid_sp)
- return;
-
- int count = count_sp->GetValueAsUnsigned(0);
- tid_t tid = tid_sp->GetValueAsUnsigned(0) + 1;
-
- if (count <= 0)
- return;
-
- ValueObjectSP trace_sp = return_value_sp->GetValueForExpressionPath(trace_path.c_str());
-
- if (!trace_sp)
- return;
-
- std::vector<lldb::addr_t> pcs;
- for (int i = 0; i < count; i++)
- {
- addr_t pc = trace_sp->GetChildAtIndex(i, true)->GetValueAsUnsigned(0);
- if (pc == 0 || pc == 1 || pc == LLDB_INVALID_ADDRESS)
- continue;
- pcs.push_back(pc);
- }
-
- HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, 0, false);
- ThreadSP new_thread_sp(history_thread);
- std::ostringstream thread_name_with_number;
- thread_name_with_number << thread_name << " Thread " << tid;
- history_thread->SetThreadName(thread_name_with_number.str().c_str());
- // Save this in the Process' ExtendedThreadList so a strong pointer retains the object
- process_sp->GetExtendedThreadList().AddThread (new_thread_sp);
- result.push_back(new_thread_sp);
+static void CreateHistoryThreadFromValueObject(ProcessSP process_sp,
+ ValueObjectSP return_value_sp,
+ const char *type,
+ const char *thread_name,
+ HistoryThreads &result) {
+ std::string count_path = "." + std::string(type) + "_count";
+ std::string tid_path = "." + std::string(type) + "_tid";
+ std::string trace_path = "." + std::string(type) + "_trace";
+
+ ValueObjectSP count_sp =
+ return_value_sp->GetValueForExpressionPath(count_path.c_str());
+ ValueObjectSP tid_sp =
+ return_value_sp->GetValueForExpressionPath(tid_path.c_str());
+
+ if (!count_sp || !tid_sp)
+ return;
+
+ int count = count_sp->GetValueAsUnsigned(0);
+ tid_t tid = tid_sp->GetValueAsUnsigned(0) + 1;
+
+ if (count <= 0)
+ return;
+
+ ValueObjectSP trace_sp =
+ return_value_sp->GetValueForExpressionPath(trace_path.c_str());
+
+ if (!trace_sp)
+ return;
+
+ std::vector<lldb::addr_t> pcs;
+ for (int i = 0; i < count; i++) {
+ addr_t pc = trace_sp->GetChildAtIndex(i, true)->GetValueAsUnsigned(0);
+ if (pc == 0 || pc == 1 || pc == LLDB_INVALID_ADDRESS)
+ continue;
+ pcs.push_back(pc);
+ }
+
+ HistoryThread *history_thread =
+ new HistoryThread(*process_sp, tid, pcs, 0, false);
+ ThreadSP new_thread_sp(history_thread);
+ std::ostringstream thread_name_with_number;
+ thread_name_with_number << thread_name << " Thread " << tid;
+ history_thread->SetThreadName(thread_name_with_number.str().c_str());
+ // Save this in the Process' ExtendedThreadList so a strong pointer retains
+ // the object
+ process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
+ result.push_back(new_thread_sp);
}
-#define GET_STACK_FUNCTION_TIMEOUT_USEC 2*1000*1000
-
-HistoryThreads
-MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address)
-{
- HistoryThreads result;
-
- ProcessSP process_sp = m_process_wp.lock();
- if (! process_sp)
- return result;
-
- ThreadSP thread_sp = process_sp->GetThreadList().GetExpressionExecutionThread();
- if (!thread_sp)
- return result;
-
- StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
- if (!frame_sp)
- return result;
-
- ExecutionContext exe_ctx (frame_sp);
- ValueObjectSP return_value_sp;
- StreamString expr;
- Error eval_error;
- expr.Printf(memory_history_asan_command_format, address, address);
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(true);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeoutUsec(GET_STACK_FUNCTION_TIMEOUT_USEC);
- options.SetPrefix(memory_history_asan_command_prefix);
- options.SetAutoApplyFixIts(false);
- options.SetLanguage(eLanguageTypeObjC_plus_plus);
-
- ExpressionResults expr_result = UserExpression::Evaluate (exe_ctx,
- options,
- expr.GetData(),
- "",
- return_value_sp,
- eval_error);
- if (expr_result != eExpressionCompleted) {
- process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", eval_error.AsCString());
- return result;
- }
+static constexpr std::chrono::seconds g_get_stack_function_timeout(2);
+
+HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) {
+ HistoryThreads result;
+
+ ProcessSP process_sp = m_process_wp.lock();
+ if (!process_sp)
+ return result;
+
+ ThreadSP thread_sp =
+ process_sp->GetThreadList().GetExpressionExecutionThread();
+ if (!thread_sp)
+ return result;
- if (!return_value_sp)
- return result;
-
- CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "free", "Memory deallocated by", result);
- CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "alloc", "Memory allocated by", result);
-
+ StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
+ if (!frame_sp)
return result;
+
+ ExecutionContext exe_ctx(frame_sp);
+ ValueObjectSP return_value_sp;
+ StreamString expr;
+ Error eval_error;
+ expr.Printf(memory_history_asan_command_format, address, address);
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(g_get_stack_function_timeout);
+ options.SetPrefix(memory_history_asan_command_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeObjC_plus_plus);
+
+ ExpressionResults expr_result = UserExpression::Evaluate(
+ exe_ctx, options, expr.GetString(), "", return_value_sp, eval_error);
+ if (expr_result != eExpressionCompleted) {
+ process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf(
+ "Warning: Cannot evaluate AddressSanitizer expression:\n%s\n",
+ eval_error.AsCString());
+ return result;
+ }
+
+ if (!return_value_sp)
+ return result;
+
+ CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "free",
+ "Memory deallocated by", result);
+ CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "alloc",
+ "Memory allocated by", result);
+
+ return result;
}
diff --git a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
index b38f95ed744e..31e9873fb1ee 100644
--- a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
+++ b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
@@ -14,51 +14,40 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/Process.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-class MemoryHistoryASan : public lldb_private::MemoryHistory
-{
+class MemoryHistoryASan : public lldb_private::MemoryHistory {
public:
- ~MemoryHistoryASan() override = default;
+ ~MemoryHistoryASan() override = default;
+
+ static lldb::MemoryHistorySP
+ CreateInstance(const lldb::ProcessSP &process_sp);
+
+ static void Initialize();
+
+ static void Terminate();
- static lldb::MemoryHistorySP
- CreateInstance (const lldb::ProcessSP &process_sp);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ lldb_private::HistoryThreads GetHistoryThreads(lldb::addr_t address) override;
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- lldb_private::HistoryThreads
- GetHistoryThreads(lldb::addr_t address) override;
-
private:
- MemoryHistoryASan(const lldb::ProcessSP &process_sp);
-
- lldb::ProcessWP m_process_wp;
+ MemoryHistoryASan(const lldb::ProcessSP &process_sp);
+
+ lldb::ProcessWP m_process_wp;
};
} // namespace lldb_private
-
+
#endif // liblldb_MemoryHistoryASan_h_
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 984a9ece12ef..5bca1de89fbd 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -9,20 +9,19 @@
#include "ObjectContainerBSDArchive.h"
-#if defined(_WIN32) || defined(__ANDROID_NDK__)
+#if defined(_WIN32) || defined(__ANDROID__)
// Defines from ar, missing on Windows
-#define ARMAG "!<arch>\n"
-#define SARMAG 8
-#define ARFMAG "`\n"
-
-typedef struct ar_hdr
-{
- char ar_name[16];
- char ar_date[12];
- char ar_uid[6], ar_gid[6];
- char ar_mode[8];
- char ar_size[10];
- char ar_fmag[2];
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+typedef struct ar_hdr {
+ char ar_name[16];
+ char ar_date[12];
+ char ar_uid[6], ar_gid[6];
+ char ar_mode[8];
+ char ar_size[10];
+ char ar_fmag[2];
} ar_hdr;
#else
#include <ar.h>
@@ -35,596 +34,482 @@ typedef struct ar_hdr
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/ObjectFile.h"
using namespace lldb;
using namespace lldb_private;
-
-
-ObjectContainerBSDArchive::Object::Object() :
- ar_name(),
- ar_date(0),
- ar_uid(0),
- ar_gid(0),
- ar_mode(0),
- ar_size(0),
- ar_file_offset(0),
- ar_file_size(0)
-{
-}
-
-void
-ObjectContainerBSDArchive::Object::Clear()
-{
- ar_name.Clear();
- ar_date = 0;
- ar_uid = 0;
- ar_gid = 0;
- ar_mode = 0;
- ar_size = 0;
- ar_file_offset = 0;
- ar_file_size = 0;
+ObjectContainerBSDArchive::Object::Object()
+ : ar_name(), ar_date(0), ar_uid(0), ar_gid(0), ar_mode(0), ar_size(0),
+ ar_file_offset(0), ar_file_size(0) {}
+
+void ObjectContainerBSDArchive::Object::Clear() {
+ ar_name.Clear();
+ ar_date = 0;
+ ar_uid = 0;
+ ar_gid = 0;
+ ar_mode = 0;
+ ar_size = 0;
+ ar_file_offset = 0;
+ ar_file_size = 0;
}
lldb::offset_t
-ObjectContainerBSDArchive::Object::Extract (const DataExtractor& data, lldb::offset_t offset)
-{
- size_t ar_name_len = 0;
- std::string str;
- char *err;
-
-
- // File header
- //
- // The common format is as follows.
- //
- // Offset Length Name Format
- // 0 16 File name ASCII right padded with spaces (no spaces allowed in file name)
- // 16 12 File mod Decimal as cstring right padded with spaces
- // 28 6 Owner ID Decimal as cstring right padded with spaces
- // 34 6 Group ID Decimal as cstring right padded with spaces
- // 40 8 File mode Octal as cstring right padded with spaces
- // 48 10 File byte size Decimal as cstring right padded with spaces
- // 58 2 File magic 0x60 0x0A
-
- // Make sure there is enough data for the file header and bail if not
- if (!data.ValidOffsetForDataOfSize(offset, 60))
- return LLDB_INVALID_OFFSET;
+ObjectContainerBSDArchive::Object::Extract(const DataExtractor &data,
+ lldb::offset_t offset) {
+ size_t ar_name_len = 0;
+ std::string str;
+ char *err;
+
+ // File header
+ //
+ // The common format is as follows.
+ //
+ // Offset Length Name Format
+ // 0 16 File name ASCII right padded with spaces (no spaces
+ // allowed in file name)
+ // 16 12 File mod Decimal as cstring right padded with
+ // spaces
+ // 28 6 Owner ID Decimal as cstring right padded with
+ // spaces
+ // 34 6 Group ID Decimal as cstring right padded with
+ // spaces
+ // 40 8 File mode Octal as cstring right padded with
+ // spaces
+ // 48 10 File byte size Decimal as cstring right padded with
+ // spaces
+ // 58 2 File magic 0x60 0x0A
+
+ // Make sure there is enough data for the file header and bail if not
+ if (!data.ValidOffsetForDataOfSize(offset, 60))
+ return LLDB_INVALID_OFFSET;
- str.assign ((const char *)data.GetData(&offset, 16), 16);
- if (str.find("#1/") == 0)
- {
- // If the name is longer than 16 bytes, or contains an embedded space
- // then it will use this format where the length of the name is
- // here and the name characters are after this header.
- ar_name_len = strtoul(str.c_str() + 3, &err, 10);
- }
- else
- {
- // Strip off any trailing spaces.
- const size_t last_pos = str.find_last_not_of(' ');
- if (last_pos != std::string::npos)
- {
- if (last_pos + 1 < 16)
- str.erase (last_pos + 1);
- }
- ar_name.SetCString(str.c_str());
+ str.assign((const char *)data.GetData(&offset, 16), 16);
+ if (str.find("#1/") == 0) {
+ // If the name is longer than 16 bytes, or contains an embedded space
+ // then it will use this format where the length of the name is
+ // here and the name characters are after this header.
+ ar_name_len = strtoul(str.c_str() + 3, &err, 10);
+ } else {
+ // Strip off any trailing spaces.
+ const size_t last_pos = str.find_last_not_of(' ');
+ if (last_pos != std::string::npos) {
+ if (last_pos + 1 < 16)
+ str.erase(last_pos + 1);
}
+ ar_name.SetCString(str.c_str());
+ }
- str.assign ((const char *)data.GetData(&offset, 12), 12);
- ar_date = strtoul(str.c_str(), &err, 10);
+ str.assign((const char *)data.GetData(&offset, 12), 12);
+ ar_date = strtoul(str.c_str(), &err, 10);
- str.assign ((const char *)data.GetData(&offset, 6), 6);
- ar_uid = strtoul(str.c_str(), &err, 10);
+ str.assign((const char *)data.GetData(&offset, 6), 6);
+ ar_uid = strtoul(str.c_str(), &err, 10);
- str.assign ((const char *)data.GetData(&offset, 6), 6);
- ar_gid = strtoul(str.c_str(), &err, 10);
+ str.assign((const char *)data.GetData(&offset, 6), 6);
+ ar_gid = strtoul(str.c_str(), &err, 10);
- str.assign ((const char *)data.GetData(&offset, 8), 8);
- ar_mode = strtoul(str.c_str(), &err, 8);
+ str.assign((const char *)data.GetData(&offset, 8), 8);
+ ar_mode = strtoul(str.c_str(), &err, 8);
- str.assign ((const char *)data.GetData(&offset, 10), 10);
- ar_size = strtoul(str.c_str(), &err, 10);
+ str.assign((const char *)data.GetData(&offset, 10), 10);
+ ar_size = strtoul(str.c_str(), &err, 10);
- str.assign ((const char *)data.GetData(&offset, 2), 2);
- if (str == ARFMAG)
- {
- if (ar_name_len > 0)
- {
- const void *ar_name_ptr = data.GetData(&offset, ar_name_len);
- // Make sure there was enough data for the string value and bail if not
- if (ar_name_ptr == NULL)
- return LLDB_INVALID_OFFSET;
- str.assign ((const char *)ar_name_ptr, ar_name_len);
- ar_name.SetCString (str.c_str());
- }
- ar_file_offset = offset;
- ar_file_size = ar_size - ar_name_len;
- return offset;
+ str.assign((const char *)data.GetData(&offset, 2), 2);
+ if (str == ARFMAG) {
+ if (ar_name_len > 0) {
+ const void *ar_name_ptr = data.GetData(&offset, ar_name_len);
+ // Make sure there was enough data for the string value and bail if not
+ if (ar_name_ptr == NULL)
+ return LLDB_INVALID_OFFSET;
+ str.assign((const char *)ar_name_ptr, ar_name_len);
+ ar_name.SetCString(str.c_str());
}
- return LLDB_INVALID_OFFSET;
-}
-
-ObjectContainerBSDArchive::Archive::Archive
-(
- const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &time,
- lldb::offset_t file_offset,
- lldb_private::DataExtractor &data
-) :
- m_arch (arch),
- m_time (time),
- m_file_offset (file_offset),
- m_objects(),
- m_data (data)
-{
+ ar_file_offset = offset;
+ ar_file_size = ar_size - ar_name_len;
+ return offset;
+ }
+ return LLDB_INVALID_OFFSET;
}
-ObjectContainerBSDArchive::Archive::~Archive ()
-{
-}
-
-size_t
-ObjectContainerBSDArchive::Archive::ParseObjects ()
-{
- DataExtractor &data = m_data;
- std::string str;
- lldb::offset_t offset = 0;
- str.assign((const char *)data.GetData(&offset, SARMAG), SARMAG);
- if (str == ARMAG)
- {
- Object obj;
- do
- {
- offset = obj.Extract (data, offset);
- if (offset == LLDB_INVALID_OFFSET)
- break;
- size_t obj_idx = m_objects.size();
- m_objects.push_back(obj);
- // Insert all of the C strings out of order for now...
- m_object_name_to_index_map.Append (obj.ar_name.GetCString(), obj_idx);
- offset += obj.ar_file_size;
- obj.Clear();
- } while (data.ValidOffset(offset));
-
- // Now sort all of the object name pointers
- m_object_name_to_index_map.Sort ();
- }
- return m_objects.size();
+ObjectContainerBSDArchive::Archive::Archive(const lldb_private::ArchSpec &arch,
+ const llvm::sys::TimePoint<> &time,
+ lldb::offset_t file_offset,
+ lldb_private::DataExtractor &data)
+ : m_arch(arch), m_time(time), m_file_offset(file_offset), m_objects(),
+ m_data(data) {}
+
+ObjectContainerBSDArchive::Archive::~Archive() {}
+
+size_t ObjectContainerBSDArchive::Archive::ParseObjects() {
+ DataExtractor &data = m_data;
+ std::string str;
+ lldb::offset_t offset = 0;
+ str.assign((const char *)data.GetData(&offset, SARMAG), SARMAG);
+ if (str == ARMAG) {
+ Object obj;
+ do {
+ offset = obj.Extract(data, offset);
+ if (offset == LLDB_INVALID_OFFSET)
+ break;
+ size_t obj_idx = m_objects.size();
+ m_objects.push_back(obj);
+ // Insert all of the C strings out of order for now...
+ m_object_name_to_index_map.Append(obj.ar_name.GetStringRef(), obj_idx);
+ offset += obj.ar_file_size;
+ obj.Clear();
+ } while (data.ValidOffset(offset));
+
+ // Now sort all of the object name pointers
+ m_object_name_to_index_map.Sort();
+ }
+ return m_objects.size();
}
ObjectContainerBSDArchive::Object *
-ObjectContainerBSDArchive::Archive::FindObject (const ConstString &object_name, const TimeValue &object_mod_time)
-{
- const ObjectNameToIndexMap::Entry *match = m_object_name_to_index_map.FindFirstValueForName (object_name.GetCString());
- if (match)
- {
- if (object_mod_time.IsValid())
- {
- const uint64_t object_date = object_mod_time.GetAsSecondsSinceJan1_1970();
- if (m_objects[match->value].ar_date == object_date)
- return &m_objects[match->value];
- const ObjectNameToIndexMap::Entry *next_match = m_object_name_to_index_map.FindNextValueForName (match);
- while (next_match)
- {
- if (m_objects[next_match->value].ar_date == object_date)
- return &m_objects[next_match->value];
- next_match = m_object_name_to_index_map.FindNextValueForName (next_match);
- }
- }
- else
- {
- return &m_objects[match->value];
- }
+ObjectContainerBSDArchive::Archive::FindObject(
+ const ConstString &object_name,
+ const llvm::sys::TimePoint<> &object_mod_time) {
+ const ObjectNameToIndexMap::Entry *match =
+ m_object_name_to_index_map.FindFirstValueForName(
+ object_name.GetStringRef());
+ if (match) {
+ if (object_mod_time != llvm::sys::TimePoint<>()) {
+ const uint64_t object_date = llvm::sys::toTimeT(object_mod_time);
+ if (m_objects[match->value].ar_date == object_date)
+ return &m_objects[match->value];
+ const ObjectNameToIndexMap::Entry *next_match =
+ m_object_name_to_index_map.FindNextValueForName(match);
+ while (next_match) {
+ if (m_objects[next_match->value].ar_date == object_date)
+ return &m_objects[next_match->value];
+ next_match =
+ m_object_name_to_index_map.FindNextValueForName(next_match);
+ }
+ } else {
+ return &m_objects[match->value];
}
- return NULL;
+ }
+ return NULL;
}
-
ObjectContainerBSDArchive::Archive::shared_ptr
-ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, const ArchSpec &arch, const TimeValue &time, lldb::offset_t file_offset)
-{
- std::lock_guard<std::recursive_mutex> guard(Archive::GetArchiveCacheMutex());
- shared_ptr archive_sp;
- Archive::Map &archive_map = Archive::GetArchiveCache ();
- Archive::Map::iterator pos = archive_map.find (file);
- // Don't cache a value for "archive_map.end()" below since we might
- // delete an archive entry...
- while (pos != archive_map.end() && pos->first == file)
- {
- bool match = true;
- if (arch.IsValid() && pos->second->GetArchitecture().IsCompatibleMatch(arch) == false)
- match = false;
- else if (file_offset != LLDB_INVALID_OFFSET && pos->second->GetFileOffset() != file_offset)
- match = false;
- if (match)
- {
- if (pos->second->GetModificationTime() == time)
- {
- return pos->second;
- }
- else
- {
- // We have a file at the same path with the same architecture
- // whose modification time doesn't match. It doesn't make sense
- // for us to continue to use this BSD archive since we cache only
- // the object info which consists of file time info and also the
- // file offset and file size of any contained objects. Since
- // this information is now out of date, we won't get the correct
- // information if we go and extract the file data, so we should
- // remove the old and outdated entry.
- archive_map.erase (pos);
- pos = archive_map.find (file);
- continue; // Continue to next iteration so we don't increment pos below...
- }
- }
- ++pos;
+ObjectContainerBSDArchive::Archive::FindCachedArchive(
+ const FileSpec &file, const ArchSpec &arch,
+ const llvm::sys::TimePoint<> &time, lldb::offset_t file_offset) {
+ std::lock_guard<std::recursive_mutex> guard(Archive::GetArchiveCacheMutex());
+ shared_ptr archive_sp;
+ Archive::Map &archive_map = Archive::GetArchiveCache();
+ Archive::Map::iterator pos = archive_map.find(file);
+ // Don't cache a value for "archive_map.end()" below since we might
+ // delete an archive entry...
+ while (pos != archive_map.end() && pos->first == file) {
+ bool match = true;
+ if (arch.IsValid() &&
+ pos->second->GetArchitecture().IsCompatibleMatch(arch) == false)
+ match = false;
+ else if (file_offset != LLDB_INVALID_OFFSET &&
+ pos->second->GetFileOffset() != file_offset)
+ match = false;
+ if (match) {
+ if (pos->second->GetModificationTime() == time) {
+ return pos->second;
+ } else {
+ // We have a file at the same path with the same architecture
+ // whose modification time doesn't match. It doesn't make sense
+ // for us to continue to use this BSD archive since we cache only
+ // the object info which consists of file time info and also the
+ // file offset and file size of any contained objects. Since
+ // this information is now out of date, we won't get the correct
+ // information if we go and extract the file data, so we should
+ // remove the old and outdated entry.
+ archive_map.erase(pos);
+ pos = archive_map.find(file);
+ continue; // Continue to next iteration so we don't increment pos
+ // below...
+ }
}
- return archive_sp;
+ ++pos;
+ }
+ return archive_sp;
}
ObjectContainerBSDArchive::Archive::shared_ptr
-ObjectContainerBSDArchive::Archive::ParseAndCacheArchiveForFile
-(
- const FileSpec &file,
- const ArchSpec &arch,
- const TimeValue &time,
- lldb::offset_t file_offset,
- DataExtractor &data
-)
-{
- shared_ptr archive_sp(new Archive (arch, time, file_offset, data));
- if (archive_sp)
- {
- const size_t num_objects = archive_sp->ParseObjects ();
- if (num_objects > 0)
- {
- std::lock_guard<std::recursive_mutex> guard(Archive::GetArchiveCacheMutex());
- Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
- }
- else
- {
- archive_sp.reset();
- }
+ObjectContainerBSDArchive::Archive::ParseAndCacheArchiveForFile(
+ const FileSpec &file, const ArchSpec &arch,
+ const llvm::sys::TimePoint<> &time, lldb::offset_t file_offset,
+ DataExtractor &data) {
+ shared_ptr archive_sp(new Archive(arch, time, file_offset, data));
+ if (archive_sp) {
+ const size_t num_objects = archive_sp->ParseObjects();
+ if (num_objects > 0) {
+ std::lock_guard<std::recursive_mutex> guard(
+ Archive::GetArchiveCacheMutex());
+ Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
+ } else {
+ archive_sp.reset();
}
- return archive_sp;
+ }
+ return archive_sp;
}
ObjectContainerBSDArchive::Archive::Map &
-ObjectContainerBSDArchive::Archive::GetArchiveCache ()
-{
- static Archive::Map g_archive_map;
- return g_archive_map;
+ObjectContainerBSDArchive::Archive::GetArchiveCache() {
+ static Archive::Map g_archive_map;
+ return g_archive_map;
}
std::recursive_mutex &
-ObjectContainerBSDArchive::Archive::GetArchiveCacheMutex()
-{
- static std::recursive_mutex g_archive_map_mutex;
- return g_archive_map_mutex;
+ObjectContainerBSDArchive::Archive::GetArchiveCacheMutex() {
+ static std::recursive_mutex g_archive_map_mutex;
+ return g_archive_map_mutex;
}
-void
-ObjectContainerBSDArchive::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- GetModuleSpecifications);
+void ObjectContainerBSDArchive::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ GetModuleSpecifications);
}
-void
-ObjectContainerBSDArchive::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ObjectContainerBSDArchive::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-ObjectContainerBSDArchive::GetPluginNameStatic()
-{
- static ConstString g_name("bsd-archive");
- return g_name;
+lldb_private::ConstString ObjectContainerBSDArchive::GetPluginNameStatic() {
+ static ConstString g_name("bsd-archive");
+ return g_name;
}
-const char *
-ObjectContainerBSDArchive::GetPluginDescriptionStatic()
-{
- return "BSD Archive object container reader.";
+const char *ObjectContainerBSDArchive::GetPluginDescriptionStatic() {
+ return "BSD Archive object container reader.";
}
-
-ObjectContainer *
-ObjectContainerBSDArchive::CreateInstance
-(
- const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t length)
-{
- ConstString object_name (module_sp->GetObjectName());
- if (object_name)
- {
- if (data_sp)
- {
- // We have data, which means this is the first 512 bytes of the file
- // Check to see if the magic bytes match and if they do, read the entire
- // table of contents for the archive and cache it
- DataExtractor data;
- data.SetData (data_sp, data_offset, length);
- if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
- {
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "ObjectContainerBSDArchive::CreateInstance (module = %s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
- module_sp->GetFileSpec().GetPath().c_str(),
- static_cast<const void*>(file),
- static_cast<uint64_t>(file_offset),
- static_cast<uint64_t>(length));
-
- // Map the entire .a file to be sure that we don't lose any data if the file
- // gets updated by a new build while this .a file is being used for debugging
- DataBufferSP archive_data_sp (file->MemoryMapFileContentsIfLocal(file_offset, length));
- lldb::offset_t archive_data_offset = 0;
-
- Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file,
- module_sp->GetArchitecture(),
- module_sp->GetModificationTime(),
- file_offset));
- std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp,
- archive_data_sp,
- archive_data_offset,
- file,
- file_offset,
- length));
-
- if (container_ap.get())
- {
- if (archive_sp)
- {
- // We already have this archive in our cache, use it
- container_ap->SetArchive (archive_sp);
- return container_ap.release();
- }
- else if (container_ap->ParseHeader())
- return container_ap.release();
- }
- }
+ObjectContainer *ObjectContainerBSDArchive::CreateInstance(
+ const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length) {
+ ConstString object_name(module_sp->GetObjectName());
+ if (object_name) {
+ if (data_sp) {
+ // We have data, which means this is the first 512 bytes of the file
+ // Check to see if the magic bytes match and if they do, read the entire
+ // table of contents for the archive and cache it
+ DataExtractor data;
+ data.SetData(data_sp, data_offset, length);
+ if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data)) {
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "ObjectContainerBSDArchive::CreateInstance (module = %s, file = "
+ "%p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
+ module_sp->GetFileSpec().GetPath().c_str(),
+ static_cast<const void *>(file), static_cast<uint64_t>(file_offset),
+ static_cast<uint64_t>(length));
+
+ // Map the entire .a file to be sure that we don't lose any data if the
+ // file
+ // gets updated by a new build while this .a file is being used for
+ // debugging
+ DataBufferSP archive_data_sp(
+ file->MemoryMapFileContentsIfLocal(file_offset, length));
+ lldb::offset_t archive_data_offset = 0;
+
+ Archive::shared_ptr archive_sp(Archive::FindCachedArchive(
+ *file, module_sp->GetArchitecture(),
+ module_sp->GetModificationTime(), file_offset));
+ std::unique_ptr<ObjectContainerBSDArchive> container_ap(
+ new ObjectContainerBSDArchive(module_sp, archive_data_sp,
+ archive_data_offset, file,
+ file_offset, length));
+
+ if (container_ap.get()) {
+ if (archive_sp) {
+ // We already have this archive in our cache, use it
+ container_ap->SetArchive(archive_sp);
+ return container_ap.release();
+ } else if (container_ap->ParseHeader())
+ return container_ap.release();
}
- else
- {
- // No data, just check for a cached archive
- Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file,
- module_sp->GetArchitecture(),
- module_sp->GetModificationTime(),
- file_offset));
- if (archive_sp)
- {
- std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, data_offset, file, file_offset, length));
-
- if (container_ap.get())
- {
- // We already have this archive in our cache, use it
- container_ap->SetArchive (archive_sp);
- return container_ap.release();
- }
- }
+ }
+ } else {
+ // No data, just check for a cached archive
+ Archive::shared_ptr archive_sp(Archive::FindCachedArchive(
+ *file, module_sp->GetArchitecture(), module_sp->GetModificationTime(),
+ file_offset));
+ if (archive_sp) {
+ std::unique_ptr<ObjectContainerBSDArchive> container_ap(
+ new ObjectContainerBSDArchive(module_sp, data_sp, data_offset, file,
+ file_offset, length));
+
+ if (container_ap.get()) {
+ // We already have this archive in our cache, use it
+ container_ap->SetArchive(archive_sp);
+ return container_ap.release();
}
+ }
}
- return NULL;
+ }
+ return NULL;
}
-
-
-bool
-ObjectContainerBSDArchive::MagicBytesMatch (const DataExtractor &data)
-{
- uint32_t offset = 0;
- const char* armag = (const char* )data.PeekData (offset, sizeof(ar_hdr));
- if (armag && ::strncmp(armag, ARMAG, SARMAG) == 0)
- {
- armag += offsetof(struct ar_hdr, ar_fmag) + SARMAG;
- if (strncmp(armag, ARFMAG, 2) == 0)
- return true;
- }
- return false;
+bool ObjectContainerBSDArchive::MagicBytesMatch(const DataExtractor &data) {
+ uint32_t offset = 0;
+ const char *armag = (const char *)data.PeekData(offset, sizeof(ar_hdr));
+ if (armag && ::strncmp(armag, ARMAG, SARMAG) == 0) {
+ armag += offsetof(struct ar_hdr, ar_fmag) + SARMAG;
+ if (strncmp(armag, ARFMAG, 2) == 0)
+ return true;
+ }
+ return false;
}
-ObjectContainerBSDArchive::ObjectContainerBSDArchive
-(
- const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t size
-) :
- ObjectContainer (module_sp, file, file_offset, size, data_sp, data_offset),
- m_archive_sp ()
-{
-}
-void
-ObjectContainerBSDArchive::SetArchive (Archive::shared_ptr &archive_sp)
-{
- m_archive_sp = archive_sp;
+ObjectContainerBSDArchive::ObjectContainerBSDArchive(
+ const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t size)
+ : ObjectContainer(module_sp, file, file_offset, size, data_sp, data_offset),
+ m_archive_sp() {}
+void ObjectContainerBSDArchive::SetArchive(Archive::shared_ptr &archive_sp) {
+ m_archive_sp = archive_sp;
}
-
-
-ObjectContainerBSDArchive::~ObjectContainerBSDArchive()
-{
-}
-
-bool
-ObjectContainerBSDArchive::ParseHeader ()
-{
- if (m_archive_sp.get() == NULL)
- {
- if (m_data.GetByteSize() > 0)
- {
- ModuleSP module_sp (GetModule());
- if (module_sp)
- {
- m_archive_sp = Archive::ParseAndCacheArchiveForFile (m_file,
- module_sp->GetArchitecture(),
- module_sp->GetModificationTime(),
- m_offset,
- m_data);
- }
- // Clear the m_data that contains the entire archive
- // data and let our m_archive_sp hold onto the data.
- m_data.Clear();
- }
+ObjectContainerBSDArchive::~ObjectContainerBSDArchive() {}
+
+bool ObjectContainerBSDArchive::ParseHeader() {
+ if (m_archive_sp.get() == NULL) {
+ if (m_data.GetByteSize() > 0) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ m_archive_sp = Archive::ParseAndCacheArchiveForFile(
+ m_file, module_sp->GetArchitecture(),
+ module_sp->GetModificationTime(), m_offset, m_data);
+ }
+ // Clear the m_data that contains the entire archive
+ // data and let our m_archive_sp hold onto the data.
+ m_data.Clear();
}
- return m_archive_sp.get() != NULL;
+ }
+ return m_archive_sp.get() != NULL;
}
-void
-ObjectContainerBSDArchive::Dump (Stream *s) const
-{
- s->Printf("%p: ", static_cast<const void*>(this));
+void ObjectContainerBSDArchive::Dump(Stream *s) const {
+ s->Printf("%p: ", static_cast<const void *>(this));
+ s->Indent();
+ const size_t num_archs = GetNumArchitectures();
+ const size_t num_objects = GetNumObjects();
+ s->Printf("ObjectContainerBSDArchive, num_archs = %" PRIu64
+ ", num_objects = %" PRIu64 "",
+ (uint64_t)num_archs, (uint64_t)num_objects);
+ uint32_t i;
+ ArchSpec arch;
+ s->IndentMore();
+ for (i = 0; i < num_archs; i++) {
s->Indent();
- const size_t num_archs = GetNumArchitectures();
- const size_t num_objects = GetNumObjects();
- s->Printf("ObjectContainerBSDArchive, num_archs = %" PRIu64 ", num_objects = %" PRIu64 "", (uint64_t)num_archs, (uint64_t)num_objects);
- uint32_t i;
- ArchSpec arch;
- s->IndentMore();
- for (i=0; i<num_archs; i++)
- {
- s->Indent();
- GetArchitectureAtIndex(i, arch);
- s->Printf("arch[%u] = %s\n", i, arch.GetArchitectureName());
- }
- for (i=0; i<num_objects; i++)
- {
- s->Indent();
- s->Printf("object[%u] = %s\n", i, GetObjectNameAtIndex (i));
- }
- s->IndentLess();
- s->EOL();
+ GetArchitectureAtIndex(i, arch);
+ s->Printf("arch[%u] = %s\n", i, arch.GetArchitectureName());
+ }
+ for (i = 0; i < num_objects; i++) {
+ s->Indent();
+ s->Printf("object[%u] = %s\n", i, GetObjectNameAtIndex(i));
+ }
+ s->IndentLess();
+ s->EOL();
}
-ObjectFileSP
-ObjectContainerBSDArchive::GetObjectFile (const FileSpec *file)
-{
- ModuleSP module_sp (GetModule());
- if (module_sp)
- {
- if (module_sp->GetObjectName() && m_archive_sp)
- {
- Object *object = m_archive_sp->FindObject (module_sp->GetObjectName(),
- module_sp->GetObjectModificationTime());
- if (object)
- {
- lldb::offset_t data_offset = object->ar_file_offset;
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + object->ar_file_offset,
- object->ar_file_size,
- m_archive_sp->GetData().GetSharedDataBuffer(),
- data_offset);
- }
- }
+ObjectFileSP ObjectContainerBSDArchive::GetObjectFile(const FileSpec *file) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ if (module_sp->GetObjectName() && m_archive_sp) {
+ Object *object = m_archive_sp->FindObject(
+ module_sp->GetObjectName(), module_sp->GetObjectModificationTime());
+ if (object) {
+ lldb::offset_t data_offset = object->ar_file_offset;
+ return ObjectFile::FindPlugin(
+ module_sp, file, m_offset + object->ar_file_offset,
+ object->ar_file_size, m_archive_sp->GetData().GetSharedDataBuffer(),
+ data_offset);
+ }
}
- return ObjectFileSP();
+ }
+ return ObjectFileSP();
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ObjectContainerBSDArchive::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ObjectContainerBSDArchive::GetPluginVersion()
-{
- return 1;
+lldb_private::ConstString ObjectContainerBSDArchive::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t ObjectContainerBSDArchive::GetPluginVersion() { return 1; }
+
+size_t ObjectContainerBSDArchive::GetModuleSpecifications(
+ const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, lldb::offset_t file_offset,
+ lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
+
+ // We have data, which means this is the first 512 bytes of the file
+ // Check to see if the magic bytes match and if they do, read the entire
+ // table of contents for the archive and cache it
+ DataExtractor data;
+ data.SetData(data_sp, data_offset, data_sp->GetByteSize());
+ if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data)) {
+ const size_t initial_count = specs.GetSize();
+ llvm::sys::TimePoint<> file_mod_time =
+ FileSystem::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;
+ DataBufferSP data_sp(
+ file.MemoryMapFileContentsIfLocal(file_offset, file_size));
+ data.SetData(data_sp, 0, data_sp->GetByteSize());
+ archive_sp = Archive::ParseAndCacheArchiveForFile(
+ file, ArchSpec(), file_mod_time, file_offset, data);
+ }
-size_t
-ObjectContainerBSDArchive::GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t file_size,
- lldb_private::ModuleSpecList &specs)
-{
-
- // We have data, which means this is the first 512 bytes of the file
- // Check to see if the magic bytes match and if they do, read the entire
- // table of contents for the archive and cache it
- DataExtractor data;
- data.SetData (data_sp, data_offset, data_sp->GetByteSize());
- if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
- {
- const size_t initial_count = specs.GetSize();
- TimeValue file_mod_time = file.GetModificationTime();
- 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;
- DataBufferSP data_sp (file.MemoryMapFileContentsIfLocal(file_offset, file_size));
- data.SetData (data_sp, 0, data_sp->GetByteSize());
- archive_sp = Archive::ParseAndCacheArchiveForFile(file, ArchSpec(), file_mod_time, file_offset, data);
- }
-
- if (archive_sp)
- {
- const size_t num_objects = archive_sp->GetNumObjects();
- for (size_t idx = 0; idx < num_objects; ++idx)
- {
- const Object *object = archive_sp->GetObjectAtIndex (idx);
- if (object)
- {
- const lldb::offset_t object_file_offset = file_offset + object->ar_file_offset;
- if (object->ar_file_offset < file_size && file_size > object_file_offset)
- {
- if (ObjectFile::GetModuleSpecifications(file,
- object_file_offset,
- file_size - object_file_offset,
- specs))
- {
- ModuleSpec &spec = specs.GetModuleSpecRefAtIndex (specs.GetSize() - 1);
- TimeValue object_mod_time;
- object_mod_time.OffsetWithSeconds(object->ar_date);
- spec.GetObjectName () = object->ar_name;
- spec.SetObjectOffset (object_file_offset);
- spec.SetObjectSize (file_size - object_file_offset);
- spec.GetObjectModificationTime () = object_mod_time;
- }
- }
- }
+ if (archive_sp) {
+ const size_t num_objects = archive_sp->GetNumObjects();
+ for (size_t idx = 0; idx < num_objects; ++idx) {
+ const Object *object = archive_sp->GetObjectAtIndex(idx);
+ if (object) {
+ const lldb::offset_t object_file_offset =
+ file_offset + object->ar_file_offset;
+ if (object->ar_file_offset < file_size &&
+ file_size > object_file_offset) {
+ if (ObjectFile::GetModuleSpecifications(
+ file, object_file_offset, file_size - object_file_offset,
+ specs)) {
+ ModuleSpec &spec =
+ specs.GetModuleSpecRefAtIndex(specs.GetSize() - 1);
+ llvm::sys::TimePoint<> object_mod_time(
+ std::chrono::seconds(object->ar_date));
+ spec.GetObjectName() = object->ar_name;
+ spec.SetObjectOffset(object_file_offset);
+ spec.SetObjectSize(file_size - object_file_offset);
+ spec.GetObjectModificationTime() = object_mod_time;
}
+ }
}
- const size_t end_count = specs.GetSize();
- size_t num_specs_added = end_count - initial_count;
- if (set_archive_arch && num_specs_added > 0)
- {
- // The archive was created but we didn't have an architecture
- // so we need to set it
- for (size_t i=initial_count; i<end_count; ++ i)
- {
- ModuleSpec module_spec;
- if (specs.GetModuleSpecAtIndex(i, module_spec))
- {
- if (module_spec.GetArchitecture().IsValid())
- {
- archive_sp->SetArchitecture (module_spec.GetArchitecture());
- break;
- }
- }
- }
+ }
+ }
+ const size_t end_count = specs.GetSize();
+ size_t num_specs_added = end_count - initial_count;
+ if (set_archive_arch && num_specs_added > 0) {
+ // The archive was created but we didn't have an architecture
+ // so we need to set it
+ for (size_t i = initial_count; i < end_count; ++i) {
+ ModuleSpec module_spec;
+ if (specs.GetModuleSpecAtIndex(i, module_spec)) {
+ if (module_spec.GetArchitecture().IsValid()) {
+ archive_sp->SetArchitecture(module_spec.GetArchitecture());
+ break;
+ }
}
- return num_specs_added;
+ }
}
- return 0;
+ return num_specs_added;
+ }
+ return 0;
}
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index 03b0bf3e2f09..de0f24e3bfcc 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -10,223 +10,168 @@
#ifndef liblldb_ObjectContainerBSDArchive_h_
#define liblldb_ObjectContainerBSDArchive_h_
-// C Includes
-// C++ Includes
-#include <mutex>
-
-// Other libraries and framework includes
// Project includes
-#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/UniqueCStringMap.h"
-#include "lldb/Host/TimeValue.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Symbol/ObjectContainer.h"
+
+// Other libraries and framework includes
+#include "llvm/Support/Chrono.h"
+
+// C Includes
+// C++ Includes
+#include <mutex>
-class ObjectContainerBSDArchive :
- public lldb_private::ObjectContainer
-{
+class ObjectContainerBSDArchive : public lldb_private::ObjectContainer {
public:
- ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t offset,
- lldb::offset_t length);
-
- ~ObjectContainerBSDArchive() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::ObjectContainer *
- CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t offset,
- lldb::offset_t length);
-
- static size_t
- GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool
- MagicBytesMatch (const lldb_private::DataExtractor &data);
-
- //------------------------------------------------------------------
- // Member Functions
- //------------------------------------------------------------------
- bool
- ParseHeader() override;
-
- size_t
- GetNumObjects() const override
- {
- if (m_archive_sp)
- return m_archive_sp->GetNumObjects();
- return 0;
- }
+ ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+
+ ~ObjectContainerBSDArchive() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::ObjectContainer *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+
+ static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb_private::ModuleSpecList &specs);
+
+ static bool MagicBytesMatch(const lldb_private::DataExtractor &data);
+
+ //------------------------------------------------------------------
+ // Member Functions
+ //------------------------------------------------------------------
+ bool ParseHeader() override;
+
+ size_t GetNumObjects() const override {
+ if (m_archive_sp)
+ return m_archive_sp->GetNumObjects();
+ return 0;
+ }
- void
- Dump(lldb_private::Stream *s) const override;
+ void Dump(lldb_private::Stream *s) const override;
- lldb::ObjectFileSP
- GetObjectFile(const lldb_private::FileSpec *file) override;
+ lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- struct Object
- {
- Object();
-
- void
- Clear();
-
- lldb::offset_t
- Extract (const lldb_private::DataExtractor& data, lldb::offset_t offset);
-
- lldb_private::ConstString ar_name; // name
- uint32_t ar_date; // modification time
- uint16_t ar_uid; // user id
- uint16_t ar_gid; // group id
- uint16_t ar_mode; // octal file permissions
- uint32_t ar_size; // size in bytes
- lldb::offset_t ar_file_offset; // file offset in bytes from the beginning of the file of the object data
- lldb::offset_t ar_file_size; // length of the object data
-
- typedef std::vector<Object> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- };
-
- class Archive
- {
- public:
- typedef std::shared_ptr<Archive> shared_ptr;
- typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map;
-
- Archive(const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &mod_time,
- lldb::offset_t file_offset,
- lldb_private::DataExtractor &data);
-
- ~Archive();
-
- static Map &
- GetArchiveCache ();
-
- static std::recursive_mutex &
- GetArchiveCacheMutex();
-
- static Archive::shared_ptr
- FindCachedArchive (const lldb_private::FileSpec &file,
- const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &mod_time,
- lldb::offset_t file_offset);
-
- static Archive::shared_ptr
- ParseAndCacheArchiveForFile (const lldb_private::FileSpec &file,
- const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &mod_time,
- lldb::offset_t file_offset,
- lldb_private::DataExtractor &data);
-
- size_t
- GetNumObjects () const
- {
- return m_objects.size();
- }
-
- const Object *
- GetObjectAtIndex (size_t idx)
- {
- if (idx < m_objects.size())
- return &m_objects[idx];
- return NULL;
- }
-
- size_t
- ParseObjects ();
-
- Object *
- FindObject (const lldb_private::ConstString &object_name,
- const lldb_private::TimeValue &object_mod_time);
-
- lldb::offset_t
- GetFileOffset () const
- {
- return m_file_offset;
- }
-
- const lldb_private::TimeValue &
- GetModificationTime()
- {
- return m_time;
- }
-
- const lldb_private::ArchSpec &
- GetArchitecture () const
- {
- return m_arch;
- }
-
- void
- SetArchitecture (const lldb_private::ArchSpec &arch)
- {
- m_arch = arch;
- }
-
- bool
- HasNoExternalReferences() const;
-
- lldb_private::DataExtractor &
- GetData ()
- {
- return m_data;
- }
-
- protected:
- typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
- //----------------------------------------------------------------------
- // Member Variables
- //----------------------------------------------------------------------
- lldb_private::ArchSpec m_arch;
- lldb_private::TimeValue m_time;
- lldb::offset_t m_file_offset;
- Object::collection m_objects;
- ObjectNameToIndexMap m_object_name_to_index_map;
- lldb_private::DataExtractor m_data; ///< The data for this object container so we don't lose data if the .a files gets modified
- };
-
- void
- SetArchive (Archive::shared_ptr &archive_sp);
-
- Archive::shared_ptr m_archive_sp;
+ struct Object {
+ Object();
+
+ void Clear();
+
+ lldb::offset_t Extract(const lldb_private::DataExtractor &data,
+ lldb::offset_t offset);
+
+ lldb_private::ConstString ar_name; // name
+ uint32_t ar_date; // modification time
+ uint16_t ar_uid; // user id
+ uint16_t ar_gid; // group id
+ uint16_t ar_mode; // octal file permissions
+ uint32_t ar_size; // size in bytes
+ lldb::offset_t ar_file_offset; // file offset in bytes from the beginning of
+ // the file of the object data
+ lldb::offset_t ar_file_size; // length of the object data
+
+ typedef std::vector<Object> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ };
+
+ class Archive {
+ public:
+ typedef std::shared_ptr<Archive> shared_ptr;
+ typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map;
+
+ Archive(const lldb_private::ArchSpec &arch,
+ const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
+ lldb_private::DataExtractor &data);
+
+ ~Archive();
+
+ static Map &GetArchiveCache();
+
+ static std::recursive_mutex &GetArchiveCacheMutex();
+
+ static Archive::shared_ptr FindCachedArchive(
+ const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch,
+ const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset);
+
+ static Archive::shared_ptr ParseAndCacheArchiveForFile(
+ const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch,
+ const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
+ lldb_private::DataExtractor &data);
+
+ size_t GetNumObjects() const { return m_objects.size(); }
+
+ const Object *GetObjectAtIndex(size_t idx) {
+ if (idx < m_objects.size())
+ return &m_objects[idx];
+ return NULL;
+ }
+
+ size_t ParseObjects();
+
+ Object *FindObject(const lldb_private::ConstString &object_name,
+ const llvm::sys::TimePoint<> &object_mod_time);
+
+ lldb::offset_t GetFileOffset() const { return m_file_offset; }
+
+ const llvm::sys::TimePoint<> &GetModificationTime() { return m_time; }
+
+ const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; }
+
+ void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; }
+
+ bool HasNoExternalReferences() const;
+
+ lldb_private::DataExtractor &GetData() { return m_data; }
+
+ protected:
+ typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
+ //----------------------------------------------------------------------
+ // Member Variables
+ //----------------------------------------------------------------------
+ lldb_private::ArchSpec m_arch;
+ llvm::sys::TimePoint<> m_time;
+ lldb::offset_t m_file_offset;
+ Object::collection m_objects;
+ ObjectNameToIndexMap m_object_name_to_index_map;
+ lldb_private::DataExtractor m_data; ///< The data for this object container
+ ///so we don't lose data if the .a files
+ ///gets modified
+ };
+
+ void SetArchive(Archive::shared_ptr &archive_sp);
+
+ Archive::shared_ptr m_archive_sp;
};
#endif // liblldb_ObjectContainerBSDArchive_h_
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
index 7497b987eba4..a412254e1eb0 100644
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
+++ b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
@@ -21,290 +21,219 @@ using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;
-void
-ObjectContainerUniversalMachO::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- GetModuleSpecifications);
+void ObjectContainerUniversalMachO::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ GetModuleSpecifications);
}
-void
-ObjectContainerUniversalMachO::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ObjectContainerUniversalMachO::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-ObjectContainerUniversalMachO::GetPluginNameStatic()
-{
- static ConstString g_name("mach-o");
- return g_name;
+lldb_private::ConstString ObjectContainerUniversalMachO::GetPluginNameStatic() {
+ static ConstString g_name("mach-o");
+ return g_name;
}
-const char *
-ObjectContainerUniversalMachO::GetPluginDescriptionStatic()
-{
- return "Universal mach-o object container reader.";
+const char *ObjectContainerUniversalMachO::GetPluginDescriptionStatic() {
+ return "Universal mach-o object container reader.";
}
-
-ObjectContainer *
-ObjectContainerUniversalMachO::CreateInstance
-(
- const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t length
-)
-{
- // We get data when we aren't trying to look for cached container information,
- // so only try and look for an architecture slice if we get data
- if (data_sp)
- {
- DataExtractor data;
- data.SetData (data_sp, data_offset, length);
- if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
- {
- std::unique_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, data_offset, file, file_offset, length));
- if (container_ap->ParseHeader())
- {
- return container_ap.release();
- }
- }
+ObjectContainer *ObjectContainerUniversalMachO::CreateInstance(
+ const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length) {
+ // We get data when we aren't trying to look for cached container information,
+ // so only try and look for an architecture slice if we get data
+ if (data_sp) {
+ DataExtractor data;
+ data.SetData(data_sp, data_offset, length);
+ if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
+ std::unique_ptr<ObjectContainerUniversalMachO> container_ap(
+ new ObjectContainerUniversalMachO(module_sp, data_sp, data_offset,
+ file, file_offset, length));
+ if (container_ap->ParseHeader()) {
+ return container_ap.release();
+ }
}
- return NULL;
+ }
+ return NULL;
}
-bool
-ObjectContainerUniversalMachO::MagicBytesMatch (const DataExtractor &data)
-{
- lldb::offset_t offset = 0;
- uint32_t magic = data.GetU32(&offset);
- return magic == FAT_MAGIC || magic == FAT_CIGAM;
+bool ObjectContainerUniversalMachO::MagicBytesMatch(const DataExtractor &data) {
+ lldb::offset_t offset = 0;
+ uint32_t magic = data.GetU32(&offset);
+ return magic == FAT_MAGIC || magic == FAT_CIGAM;
}
-ObjectContainerUniversalMachO::ObjectContainerUniversalMachO
-(
- const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const FileSpec *file,
- lldb::offset_t file_offset,
- lldb::offset_t length
-) :
- ObjectContainer (module_sp, file, file_offset, length, data_sp, data_offset),
- m_header(),
- m_fat_archs()
-{
- memset(&m_header, 0, sizeof(m_header));
+ObjectContainerUniversalMachO::ObjectContainerUniversalMachO(
+ const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length)
+ : ObjectContainer(module_sp, file, file_offset, length, data_sp,
+ data_offset),
+ m_header(), m_fat_archs() {
+ memset(&m_header, 0, sizeof(m_header));
}
+ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO() {}
-ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO()
-{
+bool ObjectContainerUniversalMachO::ParseHeader() {
+ bool success = ParseHeader(m_data, m_header, m_fat_archs);
+ // We no longer need any data, we parsed all we needed to parse
+ // and cached it in m_header and m_fat_archs
+ m_data.Clear();
+ return success;
}
-bool
-ObjectContainerUniversalMachO::ParseHeader ()
-{
- bool success = ParseHeader (m_data, m_header, m_fat_archs);
- // We no longer need any data, we parsed all we needed to parse
- // and cached it in m_header and m_fat_archs
- m_data.Clear();
- return success;
-}
+bool ObjectContainerUniversalMachO::ParseHeader(
+ lldb_private::DataExtractor &data, llvm::MachO::fat_header &header,
+ std::vector<llvm::MachO::fat_arch> &fat_archs) {
+ bool success = false;
+ // Store the file offset for this universal file as we could have a universal
+ // .o file
+ // in a BSD archive, or be contained in another kind of object.
+ // Universal mach-o files always have their headers in big endian.
+ lldb::offset_t offset = 0;
+ data.SetByteOrder(eByteOrderBig);
+ header.magic = data.GetU32(&offset);
+ fat_archs.clear();
-bool
-ObjectContainerUniversalMachO::ParseHeader (lldb_private::DataExtractor &data,
- llvm::MachO::fat_header &header,
- std::vector<llvm::MachO::fat_arch> &fat_archs)
-{
- bool success = false;
- // Store the file offset for this universal file as we could have a universal .o file
- // in a BSD archive, or be contained in another kind of object.
- // Universal mach-o files always have their headers in big endian.
- lldb::offset_t offset = 0;
- data.SetByteOrder (eByteOrderBig);
- header.magic = data.GetU32(&offset);
- fat_archs.clear();
+ if (header.magic == FAT_MAGIC) {
- if (header.magic == FAT_MAGIC)
- {
+ data.SetAddressByteSize(4);
- data.SetAddressByteSize(4);
-
- header.nfat_arch = data.GetU32(&offset);
-
- // Now we should have enough data for all of the fat headers, so lets index
- // them so we know how many architectures that this universal binary contains.
- uint32_t arch_idx = 0;
- for (arch_idx = 0; arch_idx < header.nfat_arch; ++arch_idx)
- {
- if (data.ValidOffsetForDataOfSize(offset, sizeof(fat_arch)))
- {
- fat_arch arch;
- if (data.GetU32(&offset, &arch, sizeof(fat_arch)/sizeof(uint32_t)))
- fat_archs.push_back(arch);
- }
- }
- success = true;
- }
- else
- {
- memset(&header, 0, sizeof(header));
- }
- return success;
-}
+ header.nfat_arch = data.GetU32(&offset);
-void
-ObjectContainerUniversalMachO::Dump (Stream *s) const
-{
- s->Printf("%p: ", static_cast<const void*>(this));
- s->Indent();
- const size_t num_archs = GetNumArchitectures();
- const size_t num_objects = GetNumObjects();
- s->Printf("ObjectContainerUniversalMachO, num_archs = %lu, num_objects = %lu", num_archs, num_objects);
- uint32_t i;
- ArchSpec arch;
- s->IndentMore();
- for (i=0; i<num_archs; i++)
- {
- s->Indent();
- GetArchitectureAtIndex(i, arch);
- s->Printf("arch[%u] = %s\n", i, arch.GetArchitectureName());
- }
- for (i=0; i<num_objects; i++)
- {
- s->Indent();
- s->Printf("object[%u] = %s\n", i, GetObjectNameAtIndex (i));
+ // Now we should have enough data for all of the fat headers, so lets index
+ // them so we know how many architectures that this universal binary
+ // contains.
+ uint32_t arch_idx = 0;
+ for (arch_idx = 0; arch_idx < header.nfat_arch; ++arch_idx) {
+ if (data.ValidOffsetForDataOfSize(offset, sizeof(fat_arch))) {
+ fat_arch arch;
+ if (data.GetU32(&offset, &arch, sizeof(fat_arch) / sizeof(uint32_t)))
+ fat_archs.push_back(arch);
+ }
}
- s->IndentLess();
- s->EOL();
+ success = true;
+ } else {
+ memset(&header, 0, sizeof(header));
+ }
+ return success;
+}
+
+void ObjectContainerUniversalMachO::Dump(Stream *s) const {
+ s->Printf("%p: ", static_cast<const void *>(this));
+ s->Indent();
+ const size_t num_archs = GetNumArchitectures();
+ const size_t num_objects = GetNumObjects();
+ s->Printf("ObjectContainerUniversalMachO, num_archs = %zu, num_objects = %zu",
+ num_archs, num_objects);
+ uint32_t i;
+ ArchSpec arch;
+ s->IndentMore();
+ for (i = 0; i < num_archs; i++) {
+ s->Indent();
+ GetArchitectureAtIndex(i, arch);
+ s->Printf("arch[%u] = %s\n", i, arch.GetArchitectureName());
+ }
+ for (i = 0; i < num_objects; i++) {
+ s->Indent();
+ s->Printf("object[%u] = %s\n", i, GetObjectNameAtIndex(i));
+ }
+ s->IndentLess();
+ s->EOL();
}
-size_t
-ObjectContainerUniversalMachO::GetNumArchitectures () const
-{
- return m_header.nfat_arch;
+size_t ObjectContainerUniversalMachO::GetNumArchitectures() const {
+ return m_header.nfat_arch;
}
-bool
-ObjectContainerUniversalMachO::GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const
-{
- if (idx < m_header.nfat_arch)
- {
- arch.SetArchitecture (eArchTypeMachO, m_fat_archs[idx].cputype, m_fat_archs[idx].cpusubtype);
- return true;
- }
- return false;
+bool ObjectContainerUniversalMachO::GetArchitectureAtIndex(
+ uint32_t idx, ArchSpec &arch) const {
+ if (idx < m_header.nfat_arch) {
+ arch.SetArchitecture(eArchTypeMachO, m_fat_archs[idx].cputype,
+ m_fat_archs[idx].cpusubtype);
+ return true;
+ }
+ return false;
}
ObjectFileSP
-ObjectContainerUniversalMachO::GetObjectFile (const FileSpec *file)
-{
- uint32_t arch_idx = 0;
- ArchSpec arch;
- // If the module hasn't specified an architecture yet, set it to the default
- // architecture:
- ModuleSP module_sp (GetModule());
- if (module_sp)
- {
- if (!module_sp->GetArchitecture().IsValid())
- {
- arch = Target::GetDefaultArchitecture ();
- if (!arch.IsValid())
- arch.SetTriple (LLDB_ARCH_DEFAULT);
- }
- else
- arch = module_sp->GetArchitecture();
-
- ArchSpec curr_arch;
- // First, try to find an exact match for the Arch of the Target.
- for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
- {
- if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsExactMatch(curr_arch))
- break;
- }
+ObjectContainerUniversalMachO::GetObjectFile(const FileSpec *file) {
+ uint32_t arch_idx = 0;
+ ArchSpec arch;
+ // If the module hasn't specified an architecture yet, set it to the default
+ // architecture:
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ if (!module_sp->GetArchitecture().IsValid()) {
+ arch = Target::GetDefaultArchitecture();
+ if (!arch.IsValid())
+ arch.SetTriple(LLDB_ARCH_DEFAULT);
+ } else
+ arch = module_sp->GetArchitecture();
+
+ ArchSpec curr_arch;
+ // First, try to find an exact match for the Arch of the Target.
+ for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
+ if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
+ arch.IsExactMatch(curr_arch))
+ break;
+ }
- // Failing an exact match, try to find a compatible Arch of the Target.
- if (arch_idx >= m_header.nfat_arch)
- {
- for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
- {
- if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsCompatibleMatch(curr_arch))
- break;
- }
- }
+ // Failing an exact match, try to find a compatible Arch of the Target.
+ if (arch_idx >= m_header.nfat_arch) {
+ for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) {
+ if (GetArchitectureAtIndex(arch_idx, curr_arch) &&
+ arch.IsCompatibleMatch(curr_arch))
+ break;
+ }
+ }
- if (arch_idx < m_header.nfat_arch)
- {
- DataBufferSP data_sp;
- lldb::offset_t data_offset = 0;
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size,
- data_sp,
- data_offset);
- }
+ if (arch_idx < m_header.nfat_arch) {
+ DataBufferSP data_sp;
+ lldb::offset_t data_offset = 0;
+ return ObjectFile::FindPlugin(
+ module_sp, file, m_offset + m_fat_archs[arch_idx].offset,
+ m_fat_archs[arch_idx].size, data_sp, data_offset);
}
- return ObjectFileSP();
+ }
+ return ObjectFileSP();
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ObjectContainerUniversalMachO::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ObjectContainerUniversalMachO::GetPluginVersion()
-{
- return 1;
-}
-
-
-size_t
-ObjectContainerUniversalMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t file_size,
- lldb_private::ModuleSpecList &specs)
-{
- const size_t initial_count = specs.GetSize();
-
- DataExtractor data;
- data.SetData (data_sp, data_offset, data_sp->GetByteSize());
-
- if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
- {
- llvm::MachO::fat_header header;
- std::vector<llvm::MachO::fat_arch> fat_archs;
- if (ParseHeader (data, header, fat_archs))
- {
- for (const llvm::MachO::fat_arch &fat_arch : fat_archs)
- {
- const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset;
- if (fat_arch.offset < file_size && file_size > slice_file_offset)
- {
- ObjectFile::GetModuleSpecifications (file,
- slice_file_offset,
- file_size - slice_file_offset,
- specs);
- }
- }
+lldb_private::ConstString ObjectContainerUniversalMachO::GetPluginName() {
+ return GetPluginNameStatic();
+}
+
+uint32_t ObjectContainerUniversalMachO::GetPluginVersion() { return 1; }
+
+size_t ObjectContainerUniversalMachO::GetModuleSpecifications(
+ const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, lldb::offset_t file_offset,
+ lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
+ const size_t initial_count = specs.GetSize();
+
+ DataExtractor data;
+ data.SetData(data_sp, data_offset, data_sp->GetByteSize());
+
+ if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
+ llvm::MachO::fat_header header;
+ std::vector<llvm::MachO::fat_arch> fat_archs;
+ if (ParseHeader(data, header, fat_archs)) {
+ for (const llvm::MachO::fat_arch &fat_arch : fat_archs) {
+ const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset;
+ if (fat_arch.offset < file_size && file_size > slice_file_offset) {
+ ObjectFile::GetModuleSpecifications(
+ file, slice_file_offset, file_size - slice_file_offset, specs);
}
+ }
}
- return specs.GetSize() - initial_count;
+ }
+ return specs.GetSize() - initial_count;
}
-
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
index 162402e4b2ba..36542559e082 100644
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
+++ b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
@@ -14,92 +14,73 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Utility/SafeMachO.h"
-class ObjectContainerUniversalMachO :
- public lldb_private::ObjectContainer
-{
+class ObjectContainerUniversalMachO : public lldb_private::ObjectContainer {
public:
- ObjectContainerUniversalMachO(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t offset,
- lldb::offset_t length);
-
- ~ObjectContainerUniversalMachO() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::ObjectContainer *
- CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec *file,
- lldb::offset_t offset,
- lldb::offset_t length);
-
- static size_t
- GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool
- MagicBytesMatch (const lldb_private::DataExtractor &data);
-
- //------------------------------------------------------------------
- // Member Functions
- //------------------------------------------------------------------
- bool
- ParseHeader() override;
-
- void
- Dump(lldb_private::Stream *s) const override;
-
- size_t
- GetNumArchitectures() const override;
-
- bool
- GetArchitectureAtIndex(uint32_t cpu_idx, lldb_private::ArchSpec& arch) const override;
-
- lldb::ObjectFileSP
- GetObjectFile(const lldb_private::FileSpec *file) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ObjectContainerUniversalMachO(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+
+ ~ObjectContainerUniversalMachO() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::ObjectContainer *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+
+ static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb_private::ModuleSpecList &specs);
+
+ static bool MagicBytesMatch(const lldb_private::DataExtractor &data);
+
+ //------------------------------------------------------------------
+ // Member Functions
+ //------------------------------------------------------------------
+ bool ParseHeader() override;
+
+ void Dump(lldb_private::Stream *s) const override;
+
+ size_t GetNumArchitectures() const override;
+
+ bool GetArchitectureAtIndex(uint32_t cpu_idx,
+ lldb_private::ArchSpec &arch) const override;
+
+ lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- llvm::MachO::fat_header m_header;
- std::vector<llvm::MachO::fat_arch> m_fat_archs;
-
- static bool
- ParseHeader (lldb_private::DataExtractor &data,
- llvm::MachO::fat_header &header,
- std::vector<llvm::MachO::fat_arch> &fat_archs);
+ llvm::MachO::fat_header m_header;
+ std::vector<llvm::MachO::fat_arch> m_fat_archs;
+
+ static bool ParseHeader(lldb_private::DataExtractor &data,
+ llvm::MachO::fat_header &header,
+ std::vector<llvm::MachO::fat_arch> &fat_archs);
};
#endif // liblldb_ObjectContainerUniversalMachO_h_
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
index 625cce3c1062..a3e82390d262 100644
--- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
+++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
@@ -24,240 +24,201 @@ using namespace llvm::ELF;
//
// GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
// with error handling code and provide for parsing a sequence of values.
-static bool
-GetMaxU64(const lldb_private::DataExtractor &data,
- lldb::offset_t *offset,
- uint64_t *value,
- uint32_t byte_size)
-{
- const lldb::offset_t saved_offset = *offset;
- *value = data.GetMaxU64(offset, byte_size);
- return *offset != saved_offset;
+static bool GetMaxU64(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset, uint64_t *value,
+ uint32_t byte_size) {
+ const lldb::offset_t saved_offset = *offset;
+ *value = data.GetMaxU64(offset, byte_size);
+ return *offset != saved_offset;
}
-static bool
-GetMaxU64(const lldb_private::DataExtractor &data,
- lldb::offset_t *offset,
- uint64_t *value,
- uint32_t byte_size,
- uint32_t count)
-{
- lldb::offset_t saved_offset = *offset;
-
- for (uint32_t i = 0; i < count; ++i, ++value)
- {
- if (GetMaxU64(data, offset, value, byte_size) == false)
- {
- *offset = saved_offset;
- return false;
- }
+static bool GetMaxU64(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset, uint64_t *value,
+ uint32_t byte_size, uint32_t count) {
+ lldb::offset_t saved_offset = *offset;
+
+ for (uint32_t i = 0; i < count; ++i, ++value) {
+ if (GetMaxU64(data, offset, value, byte_size) == false) {
+ *offset = saved_offset;
+ return false;
}
- return true;
+ }
+ return true;
}
-static bool
-GetMaxS64(const lldb_private::DataExtractor &data,
- lldb::offset_t *offset,
- int64_t *value,
- uint32_t byte_size)
-{
- const lldb::offset_t saved_offset = *offset;
- *value = data.GetMaxS64(offset, byte_size);
- return *offset != saved_offset;
+static bool GetMaxS64(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset, int64_t *value,
+ uint32_t byte_size) {
+ const lldb::offset_t saved_offset = *offset;
+ *value = data.GetMaxS64(offset, byte_size);
+ return *offset != saved_offset;
}
-static bool
-GetMaxS64(const lldb_private::DataExtractor &data,
- lldb::offset_t *offset,
- int64_t *value,
- uint32_t byte_size,
- uint32_t count)
-{
- lldb::offset_t saved_offset = *offset;
-
- for (uint32_t i = 0; i < count; ++i, ++value)
- {
- if (GetMaxS64(data, offset, value, byte_size) == false)
- {
- *offset = saved_offset;
- return false;
- }
+static bool GetMaxS64(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset, int64_t *value,
+ uint32_t byte_size, uint32_t count) {
+ lldb::offset_t saved_offset = *offset;
+
+ for (uint32_t i = 0; i < count; ++i, ++value) {
+ if (GetMaxS64(data, offset, value, byte_size) == false) {
+ *offset = saved_offset;
+ return false;
}
- return true;
+ }
+ return true;
}
//------------------------------------------------------------------------------
// ELFHeader
-ELFHeader::ELFHeader()
-{
- memset(this, 0, sizeof(ELFHeader));
-}
+ELFHeader::ELFHeader() { memset(this, 0, sizeof(ELFHeader)); }
-ByteOrder
-ELFHeader::GetByteOrder() const
-{
- if (e_ident[EI_DATA] == ELFDATA2MSB)
- return eByteOrderBig;
- if (e_ident[EI_DATA] == ELFDATA2LSB)
- return eByteOrderLittle;
- return eByteOrderInvalid;
+ByteOrder ELFHeader::GetByteOrder() const {
+ if (e_ident[EI_DATA] == ELFDATA2MSB)
+ return eByteOrderBig;
+ if (e_ident[EI_DATA] == ELFDATA2LSB)
+ return eByteOrderLittle;
+ return eByteOrderInvalid;
}
-bool
-ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset)
-{
- // Read e_ident. This provides byte order and address size info.
- if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
- return false;
+bool ELFHeader::Parse(lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ // Read e_ident. This provides byte order and address size info.
+ if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
+ return false;
- const unsigned byte_size = Is32Bit() ? 4 : 8;
- data.SetByteOrder(GetByteOrder());
- data.SetAddressByteSize(byte_size);
+ const unsigned byte_size = Is32Bit() ? 4 : 8;
+ data.SetByteOrder(GetByteOrder());
+ data.SetAddressByteSize(byte_size);
- // Read e_type and e_machine.
- if (data.GetU16(offset, &e_type, 2) == NULL)
- return false;
+ // Read e_type and e_machine.
+ if (data.GetU16(offset, &e_type, 2) == NULL)
+ return false;
- // Read e_version.
- if (data.GetU32(offset, &e_version, 1) == NULL)
- return false;
+ // Read e_version.
+ if (data.GetU32(offset, &e_version, 1) == NULL)
+ return false;
- // Read e_entry, e_phoff and e_shoff.
- if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
- return false;
+ // Read e_entry, e_phoff and e_shoff.
+ if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
+ return false;
- // Read e_flags.
- if (data.GetU32(offset, &e_flags, 1) == NULL)
- return false;
+ // Read e_flags.
+ if (data.GetU32(offset, &e_flags, 1) == NULL)
+ return false;
- // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and
- // e_shstrndx.
- if (data.GetU16(offset, &e_ehsize, 6) == NULL)
- return false;
+ // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and
+ // e_shstrndx.
+ if (data.GetU16(offset, &e_ehsize, 6) == NULL)
+ return false;
- return true;
+ return true;
}
-bool
-ELFHeader::MagicBytesMatch(const uint8_t *magic)
-{
- return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;
+bool ELFHeader::MagicBytesMatch(const uint8_t *magic) {
+ return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;
}
-unsigned
-ELFHeader::AddressSizeInBytes(const uint8_t *magic)
-{
- unsigned address_size = 0;
-
- switch (magic[EI_CLASS])
- {
- case ELFCLASS32:
- address_size = 4;
- break;
-
- case ELFCLASS64:
- address_size = 8;
- break;
- }
- return address_size;
-}
+unsigned ELFHeader::AddressSizeInBytes(const uint8_t *magic) {
+ unsigned address_size = 0;
-unsigned
-ELFHeader::GetRelocationJumpSlotType() const
-{
- unsigned slot = 0;
-
- switch (e_machine)
- {
- default:
- assert(false && "architecture not supported");
- break;
- case EM_PPC:
- slot = R_PPC_JMP_SLOT;
- break;
- case EM_PPC64:
- slot = R_PPC64_JMP_SLOT;
- break;
- case EM_386:
- case EM_IAMCU: // FIXME: is this correct?
- slot = R_386_JUMP_SLOT;
- break;
- case EM_X86_64:
- slot = R_X86_64_JUMP_SLOT;
- break;
- case EM_ARM:
- slot = R_ARM_JUMP_SLOT;
- break;
- case EM_HEXAGON:
- slot = R_HEX_JMP_SLOT;
- break;
- case EM_AARCH64:
- slot = R_AARCH64_JUMP_SLOT;
- break;
- case EM_MIPS:
- slot = R_MIPS_JUMP_SLOT;
- break;
- case EM_S390:
- slot = R_390_JMP_SLOT;
- break;
- }
+ switch (magic[EI_CLASS]) {
+ case ELFCLASS32:
+ address_size = 4;
+ break;
- return slot;
+ case ELFCLASS64:
+ address_size = 8;
+ break;
+ }
+ return address_size;
+}
+
+unsigned ELFHeader::GetRelocationJumpSlotType() const {
+ unsigned slot = 0;
+
+ switch (e_machine) {
+ default:
+ assert(false && "architecture not supported");
+ break;
+ case EM_PPC:
+ slot = R_PPC_JMP_SLOT;
+ break;
+ case EM_PPC64:
+ slot = R_PPC64_JMP_SLOT;
+ break;
+ case EM_386:
+ case EM_IAMCU: // FIXME: is this correct?
+ slot = R_386_JUMP_SLOT;
+ break;
+ case EM_X86_64:
+ slot = R_X86_64_JUMP_SLOT;
+ break;
+ case EM_ARM:
+ slot = R_ARM_JUMP_SLOT;
+ break;
+ case EM_HEXAGON:
+ slot = R_HEX_JMP_SLOT;
+ break;
+ case EM_AARCH64:
+ slot = R_AARCH64_JUMP_SLOT;
+ break;
+ case EM_MIPS:
+ slot = R_MIPS_JUMP_SLOT;
+ break;
+ case EM_S390:
+ slot = R_390_JMP_SLOT;
+ break;
+ }
+
+ return slot;
}
//------------------------------------------------------------------------------
// ELFSectionHeader
-ELFSectionHeader::ELFSectionHeader()
-{
- memset(this, 0, sizeof(ELFSectionHeader));
+ELFSectionHeader::ELFSectionHeader() {
+ memset(this, 0, sizeof(ELFSectionHeader));
}
-bool
-ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
- lldb::offset_t *offset)
-{
- const unsigned byte_size = data.GetAddressByteSize();
+bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ const unsigned byte_size = data.GetAddressByteSize();
- // Read sh_name and sh_type.
- if (data.GetU32(offset, &sh_name, 2) == NULL)
- return false;
+ // Read sh_name and sh_type.
+ if (data.GetU32(offset, &sh_name, 2) == NULL)
+ return false;
- // Read sh_flags.
- if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
- return false;
+ // Read sh_flags.
+ if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
+ return false;
- // Read sh_addr, sh_off and sh_size.
- if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
- return false;
+ // Read sh_addr, sh_off and sh_size.
+ if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
+ return false;
- // Read sh_link and sh_info.
- if (data.GetU32(offset, &sh_link, 2) == NULL)
- return false;
+ // Read sh_link and sh_info.
+ if (data.GetU32(offset, &sh_link, 2) == NULL)
+ return false;
- // Read sh_addralign and sh_entsize.
- if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
- return false;
+ // Read sh_addralign and sh_entsize.
+ if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
+ return false;
- return true;
+ return true;
}
//------------------------------------------------------------------------------
// ELFSymbol
-ELFSymbol::ELFSymbol()
-{
- memset(this, 0, sizeof(ELFSymbol));
-}
+ELFSymbol::ELFSymbol() { memset(this, 0, sizeof(ELFSymbol)); }
-#define ENUM_TO_CSTR(e) case e: return #e
+#define ENUM_TO_CSTR(e) \
+ case e: \
+ return #e
-const char *
-ELFSymbol::bindingToCString(unsigned char binding)
-{
- switch (binding)
- {
+const char *ELFSymbol::bindingToCString(unsigned char binding) {
+ switch (binding) {
ENUM_TO_CSTR(STB_LOCAL);
ENUM_TO_CSTR(STB_GLOBAL);
ENUM_TO_CSTR(STB_WEAK);
@@ -265,15 +226,12 @@ ELFSymbol::bindingToCString(unsigned char binding)
ENUM_TO_CSTR(STB_HIOS);
ENUM_TO_CSTR(STB_LOPROC);
ENUM_TO_CSTR(STB_HIPROC);
- }
- return "";
+ }
+ return "";
}
-const char *
-ELFSymbol::typeToCString(unsigned char type)
-{
- switch (type)
- {
+const char *ELFSymbol::typeToCString(unsigned char type) {
+ switch (type) {
ENUM_TO_CSTR(STT_NOTYPE);
ENUM_TO_CSTR(STT_OBJECT);
ENUM_TO_CSTR(STT_FUNC);
@@ -285,16 +243,13 @@ ELFSymbol::typeToCString(unsigned char type)
ENUM_TO_CSTR(STT_HIOS);
ENUM_TO_CSTR(STT_LOPROC);
ENUM_TO_CSTR(STT_HIPROC);
- }
- return "";
+ }
+ return "";
}
-const char *
-ELFSymbol::sectionIndexToCString (elf_half shndx,
- const lldb_private::SectionList *section_list)
-{
- switch (shndx)
- {
+const char *ELFSymbol::sectionIndexToCString(
+ elf_half shndx, const lldb_private::SectionList *section_list) {
+ switch (shndx) {
ENUM_TO_CSTR(SHN_UNDEF);
ENUM_TO_CSTR(SHN_LOPROC);
ENUM_TO_CSTR(SHN_HIPROC);
@@ -303,180 +258,148 @@ ELFSymbol::sectionIndexToCString (elf_half shndx,
ENUM_TO_CSTR(SHN_ABS);
ENUM_TO_CSTR(SHN_COMMON);
ENUM_TO_CSTR(SHN_XINDEX);
- default:
- {
- const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get();
- if (section)
- return section->GetName().AsCString("");
- }
- break;
- }
- return "";
+ default: {
+ const lldb_private::Section *section =
+ section_list->GetSectionAtIndex(shndx).get();
+ if (section)
+ return section->GetName().AsCString("");
+ } break;
+ }
+ return "";
}
-void
-ELFSymbol::Dump (lldb_private::Stream *s,
- uint32_t idx,
- const lldb_private::DataExtractor *strtab_data,
- const lldb_private::SectionList *section_list)
-{
- s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n",
- idx,
- st_value,
- st_size,
- st_name,
- st_info,
- bindingToCString (getBinding()),
- typeToCString (getType()),
- st_other,
- st_shndx,
- sectionIndexToCString (st_shndx, section_list),
- strtab_data ? strtab_data->PeekCStr(st_name) : "");
+void ELFSymbol::Dump(lldb_private::Stream *s, uint32_t idx,
+ const lldb_private::DataExtractor *strtab_data,
+ const lldb_private::SectionList *section_list) {
+ s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64
+ " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n",
+ idx, st_value, st_size, st_name, st_info,
+ bindingToCString(getBinding()), typeToCString(getType()), st_other,
+ st_shndx, sectionIndexToCString(st_shndx, section_list),
+ strtab_data ? strtab_data->PeekCStr(st_name) : "");
}
-bool
-ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
-{
- const unsigned byte_size = data.GetAddressByteSize();
- const bool parsing_32 = byte_size == 4;
-
- // Read st_name.
- if (data.GetU32(offset, &st_name, 1) == NULL)
- return false;
-
- if (parsing_32)
- {
- // Read st_value and st_size.
- if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
- return false;
-
- // Read st_info and st_other.
- if (data.GetU8(offset, &st_info, 2) == NULL)
- return false;
-
- // Read st_shndx.
- if (data.GetU16(offset, &st_shndx, 1) == NULL)
- return false;
- }
- else
- {
- // Read st_info and st_other.
- if (data.GetU8(offset, &st_info, 2) == NULL)
- return false;
-
- // Read st_shndx.
- if (data.GetU16(offset, &st_shndx, 1) == NULL)
- return false;
-
- // Read st_value and st_size.
- if (data.GetU64(offset, &st_value, 2) == NULL)
- return false;
- }
- return true;
+bool ELFSymbol::Parse(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ const unsigned byte_size = data.GetAddressByteSize();
+ const bool parsing_32 = byte_size == 4;
+
+ // Read st_name.
+ if (data.GetU32(offset, &st_name, 1) == NULL)
+ return false;
+
+ if (parsing_32) {
+ // Read st_value and st_size.
+ if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
+ return false;
+
+ // Read st_info and st_other.
+ if (data.GetU8(offset, &st_info, 2) == NULL)
+ return false;
+
+ // Read st_shndx.
+ if (data.GetU16(offset, &st_shndx, 1) == NULL)
+ return false;
+ } else {
+ // Read st_info and st_other.
+ if (data.GetU8(offset, &st_info, 2) == NULL)
+ return false;
+
+ // Read st_shndx.
+ if (data.GetU16(offset, &st_shndx, 1) == NULL)
+ return false;
+
+ // Read st_value and st_size.
+ if (data.GetU64(offset, &st_value, 2) == NULL)
+ return false;
+ }
+ return true;
}
//------------------------------------------------------------------------------
// ELFProgramHeader
-ELFProgramHeader::ELFProgramHeader()
-{
- memset(this, 0, sizeof(ELFProgramHeader));
+ELFProgramHeader::ELFProgramHeader() {
+ memset(this, 0, sizeof(ELFProgramHeader));
}
-bool
-ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
- lldb::offset_t *offset)
-{
- const uint32_t byte_size = data.GetAddressByteSize();
- const bool parsing_32 = byte_size == 4;
-
- // Read p_type;
- if (data.GetU32(offset, &p_type, 1) == NULL)
- return false;
-
- 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)
- return false;
-
- // Read p_flags.
- if (data.GetU32(offset, &p_flags, 1) == NULL)
- return false;
-
- // Read p_align.
- if (GetMaxU64(data, offset, &p_align, byte_size) == false)
- return false;
- }
- else {
- // Read p_flags.
- if (data.GetU32(offset, &p_flags, 1) == NULL)
- 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)
- return false;
- }
-
- return true;
+bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ const uint32_t byte_size = data.GetAddressByteSize();
+ const bool parsing_32 = byte_size == 4;
+
+ // Read p_type;
+ if (data.GetU32(offset, &p_type, 1) == NULL)
+ return false;
+
+ 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)
+ return false;
+
+ // Read p_flags.
+ if (data.GetU32(offset, &p_flags, 1) == NULL)
+ return false;
+
+ // Read p_align.
+ if (GetMaxU64(data, offset, &p_align, byte_size) == false)
+ return false;
+ } else {
+ // Read p_flags.
+ if (data.GetU32(offset, &p_flags, 1) == NULL)
+ 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)
+ return false;
+ }
+
+ return true;
}
//------------------------------------------------------------------------------
// ELFDynamic
-ELFDynamic::ELFDynamic()
-{
- memset(this, 0, sizeof(ELFDynamic));
-}
+ELFDynamic::ELFDynamic() { memset(this, 0, sizeof(ELFDynamic)); }
-bool
-ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
-{
- const unsigned byte_size = data.GetAddressByteSize();
- return GetMaxS64(data, offset, &d_tag, byte_size, 2);
+bool ELFDynamic::Parse(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ const unsigned byte_size = data.GetAddressByteSize();
+ return GetMaxS64(data, offset, &d_tag, byte_size, 2);
}
//------------------------------------------------------------------------------
// ELFRel
-ELFRel::ELFRel()
-{
- memset(this, 0, sizeof(ELFRel));
-}
+ELFRel::ELFRel() { memset(this, 0, sizeof(ELFRel)); }
-bool
-ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
-{
- const unsigned byte_size = data.GetAddressByteSize();
+bool ELFRel::Parse(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ const unsigned byte_size = data.GetAddressByteSize();
- // Read r_offset and r_info.
- if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
- return false;
+ // Read r_offset and r_info.
+ if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
+ return false;
- return true;
+ return true;
}
//------------------------------------------------------------------------------
// ELFRela
-ELFRela::ELFRela()
-{
- memset(this, 0, sizeof(ELFRela));
-}
+ELFRela::ELFRela() { memset(this, 0, sizeof(ELFRela)); }
-bool
-ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
-{
- const unsigned byte_size = data.GetAddressByteSize();
+bool ELFRela::Parse(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ const unsigned byte_size = data.GetAddressByteSize();
- // Read r_offset and r_info.
- if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
- return false;
+ // Read r_offset and r_info.
+ if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
+ return false;
- // Read r_addend;
- if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
- return false;
+ // Read r_addend;
+ if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
+ return false;
- return true;
+ return true;
}
-
-
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.h b/source/Plugins/ObjectFile/ELF/ELFHeader.h
index 4ea22b51baf7..71b200f1c16b 100644
--- a/source/Plugins/ObjectFile/ELF/ELFHeader.h
+++ b/source/Plugins/ObjectFile/ELF/ELFHeader.h
@@ -25,13 +25,11 @@
#include "lldb/lldb-enumerations.h"
-namespace lldb_private
-{
+namespace lldb_private {
class DataExtractor;
} // End namespace lldb_private.
-namespace elf
-{
+namespace elf {
//------------------------------------------------------------------------------
/// @name ELF type definitions.
@@ -44,10 +42,10 @@ typedef uint64_t elf_addr;
typedef uint64_t elf_off;
typedef uint16_t elf_half;
typedef uint32_t elf_word;
-typedef int32_t elf_sword;
+typedef int32_t elf_sword;
typedef uint64_t elf_size;
typedef uint64_t elf_xword;
-typedef int64_t elf_sxword;
+typedef int64_t elf_sxword;
//@}
//------------------------------------------------------------------------------
@@ -56,376 +54,331 @@ typedef int64_t elf_sxword;
///
/// This object is used to identify the general attributes on an ELF file and to
/// locate additional sections within the file.
-struct ELFHeader
-{
- unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
- elf_addr e_entry; ///< Virtual address program entry point.
- elf_off e_phoff; ///< File offset of program header table.
- elf_off e_shoff; ///< File offset of section header table.
- elf_word e_flags; ///< Processor specific flags.
- elf_word e_version; ///< Version of object file (always 1).
- elf_half e_type; ///< Object file type.
- elf_half e_machine; ///< Target architecture.
- elf_half e_ehsize; ///< Byte size of the ELF header.
- elf_half e_phentsize; ///< Size of a program header table entry.
- elf_half e_phnum; ///< Number of program header entries.
- elf_half e_shentsize; ///< Size of a section header table entry.
- elf_half e_shnum; ///< Number of section header entries.
- elf_half e_shstrndx; ///< String table section index.
-
- ELFHeader();
-
- //--------------------------------------------------------------------------
- /// Returns true if this is a 32 bit ELF file header.
- ///
- /// @return
- /// True if this is a 32 bit ELF file header.
- bool Is32Bit() const {
- return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
- }
-
- //--------------------------------------------------------------------------
- /// Returns true if this is a 64 bit ELF file header.
- ///
- /// @return
- /// True if this is a 64 bit ELF file header.
- bool Is64Bit() const {
- return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
- }
-
- //--------------------------------------------------------------------------
- /// The byte order of this ELF file header.
- ///
- /// @return
- /// The byte order of this ELF file as described by the header.
- lldb::ByteOrder
- GetByteOrder() const;
-
- //--------------------------------------------------------------------------
- /// The jump slot relocation type of this ELF.
- unsigned
- GetRelocationJumpSlotType() const;
-
- //--------------------------------------------------------------------------
- /// Parse an ELFHeader entry starting at position \p offset and
- /// update the data extractor with the address size and byte order
- /// attributes as defined by the header.
- ///
- /// @param[in,out] data
- /// The DataExtractor to read from. Updated with the address size and
- /// byte order attributes appropriate to this header.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFHeader was successfully read and false
- /// otherwise.
- bool
- Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
-
- //--------------------------------------------------------------------------
- /// Examines at most EI_NIDENT bytes starting from the given pointer and
- /// determines if the magic ELF identification exists.
- ///
- /// @return
- /// True if the given sequence of bytes identifies an ELF file.
- static bool
- MagicBytesMatch(const uint8_t *magic);
-
- //--------------------------------------------------------------------------
- /// Examines at most EI_NIDENT bytes starting from the given address and
- /// determines the address size of the underlying ELF file. This function
- /// should only be called on an pointer for which MagicBytesMatch returns
- /// true.
- ///
- /// @return
- /// The number of bytes forming an address in the ELF file (either 4 or
- /// 8), else zero if the address size could not be determined.
- static unsigned
- AddressSizeInBytes(const uint8_t *magic);
+struct ELFHeader {
+ unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
+ elf_addr e_entry; ///< Virtual address program entry point.
+ elf_off e_phoff; ///< File offset of program header table.
+ elf_off e_shoff; ///< File offset of section header table.
+ elf_word e_flags; ///< Processor specific flags.
+ elf_word e_version; ///< Version of object file (always 1).
+ elf_half e_type; ///< Object file type.
+ elf_half e_machine; ///< Target architecture.
+ elf_half e_ehsize; ///< Byte size of the ELF header.
+ elf_half e_phentsize; ///< Size of a program header table entry.
+ elf_half e_phnum; ///< Number of program header entries.
+ elf_half e_shentsize; ///< Size of a section header table entry.
+ elf_half e_shnum; ///< Number of section header entries.
+ elf_half e_shstrndx; ///< String table section index.
+
+ ELFHeader();
+
+ //--------------------------------------------------------------------------
+ /// Returns true if this is a 32 bit ELF file header.
+ ///
+ /// @return
+ /// True if this is a 32 bit ELF file header.
+ bool Is32Bit() const {
+ return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
+ }
+
+ //--------------------------------------------------------------------------
+ /// Returns true if this is a 64 bit ELF file header.
+ ///
+ /// @return
+ /// True if this is a 64 bit ELF file header.
+ bool Is64Bit() const {
+ return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
+ }
+
+ //--------------------------------------------------------------------------
+ /// The byte order of this ELF file header.
+ ///
+ /// @return
+ /// The byte order of this ELF file as described by the header.
+ lldb::ByteOrder GetByteOrder() const;
+
+ //--------------------------------------------------------------------------
+ /// The jump slot relocation type of this ELF.
+ unsigned GetRelocationJumpSlotType() const;
+
+ //--------------------------------------------------------------------------
+ /// Parse an ELFHeader entry starting at position \p offset and
+ /// update the data extractor with the address size and byte order
+ /// attributes as defined by the header.
+ ///
+ /// @param[in,out] data
+ /// The DataExtractor to read from. Updated with the address size and
+ /// byte order attributes appropriate to this header.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFHeader was successfully read and false
+ /// otherwise.
+ bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
+
+ //--------------------------------------------------------------------------
+ /// Examines at most EI_NIDENT bytes starting from the given pointer and
+ /// determines if the magic ELF identification exists.
+ ///
+ /// @return
+ /// True if the given sequence of bytes identifies an ELF file.
+ static bool MagicBytesMatch(const uint8_t *magic);
+
+ //--------------------------------------------------------------------------
+ /// Examines at most EI_NIDENT bytes starting from the given address and
+ /// determines the address size of the underlying ELF file. This function
+ /// should only be called on an pointer for which MagicBytesMatch returns
+ /// true.
+ ///
+ /// @return
+ /// The number of bytes forming an address in the ELF file (either 4 or
+ /// 8), else zero if the address size could not be determined.
+ static unsigned AddressSizeInBytes(const uint8_t *magic);
};
//------------------------------------------------------------------------------
/// @class ELFSectionHeader
/// @brief Generic representation of an ELF section header.
-struct ELFSectionHeader
-{
- elf_word sh_name; ///< Section name string index.
- elf_word sh_type; ///< Section type.
- elf_xword sh_flags; ///< Section attributes.
- elf_addr sh_addr; ///< Virtual address of the section in memory.
- elf_off sh_offset; ///< Start of section from beginning of file.
- elf_xword sh_size; ///< Number of bytes occupied in the file.
- elf_word sh_link; ///< Index of associated section.
- elf_word sh_info; ///< Extra section info (overloaded).
- elf_xword sh_addralign; ///< Power of two alignment constraint.
- elf_xword sh_entsize; ///< Byte size of each section entry.
-
- ELFSectionHeader();
-
- //--------------------------------------------------------------------------
- /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
- /// position \p offset.
- ///
- /// @param[in] data
- /// The DataExtractor to read from. The address size of the extractor
- /// determines if a 32 or 64 bit object should be read.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFSectionHeader was successfully read and false
- /// otherwise.
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+struct ELFSectionHeader {
+ elf_word sh_name; ///< Section name string index.
+ elf_word sh_type; ///< Section type.
+ elf_xword sh_flags; ///< Section attributes.
+ elf_addr sh_addr; ///< Virtual address of the section in memory.
+ elf_off sh_offset; ///< Start of section from beginning of file.
+ elf_xword sh_size; ///< Number of bytes occupied in the file.
+ elf_word sh_link; ///< Index of associated section.
+ elf_word sh_info; ///< Extra section info (overloaded).
+ elf_xword sh_addralign; ///< Power of two alignment constraint.
+ elf_xword sh_entsize; ///< Byte size of each section entry.
+
+ ELFSectionHeader();
+
+ //--------------------------------------------------------------------------
+ /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
+ /// position \p offset.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from. The address size of the extractor
+ /// determines if a 32 or 64 bit object should be read.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFSectionHeader was successfully read and false
+ /// otherwise.
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
/// @class ELFProgramHeader
/// @brief Generic representation of an ELF program header.
-struct ELFProgramHeader
-{
- elf_word p_type; ///< Type of program segment.
- elf_word p_flags; ///< Segment attributes.
- elf_off p_offset; ///< Start of segment from beginning of file.
- elf_addr p_vaddr; ///< Virtual address of segment in memory.
- elf_addr p_paddr; ///< Physical address (for non-VM systems).
- elf_xword p_filesz; ///< Byte size of the segment in file.
- elf_xword p_memsz; ///< Byte size of the segment in memory.
- elf_xword p_align; ///< Segment alignment constraint.
-
- ELFProgramHeader();
-
- /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
- /// position \p offset. The address size of the DataExtractor determines if
- /// a 32 or 64 bit object is to be parsed.
- ///
- /// @param[in] data
- /// The DataExtractor to read from. The address size of the extractor
- /// determines if a 32 or 64 bit object should be read.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFProgramHeader was successfully read and false
- /// otherwise.
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+struct ELFProgramHeader {
+ elf_word p_type; ///< Type of program segment.
+ elf_word p_flags; ///< Segment attributes.
+ elf_off p_offset; ///< Start of segment from beginning of file.
+ elf_addr p_vaddr; ///< Virtual address of segment in memory.
+ elf_addr p_paddr; ///< Physical address (for non-VM systems).
+ elf_xword p_filesz; ///< Byte size of the segment in file.
+ elf_xword p_memsz; ///< Byte size of the segment in memory.
+ elf_xword p_align; ///< Segment alignment constraint.
+
+ ELFProgramHeader();
+
+ /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
+ /// position \p offset. The address size of the DataExtractor determines if
+ /// a 32 or 64 bit object is to be parsed.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from. The address size of the extractor
+ /// determines if a 32 or 64 bit object should be read.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFProgramHeader was successfully read and false
+ /// otherwise.
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
/// @class ELFSymbol
/// @brief Represents a symbol within an ELF symbol table.
-struct ELFSymbol
-{
- elf_addr st_value; ///< Absolute or relocatable address.
- elf_xword st_size; ///< Size of the symbol or zero.
- elf_word st_name; ///< Symbol name string index.
- unsigned char st_info; ///< Symbol type and binding attributes.
- unsigned char st_other; ///< Reserved for future use.
- elf_half st_shndx; ///< Section to which this symbol applies.
-
- ELFSymbol();
-
- /// Returns the binding attribute of the st_info member.
- unsigned char getBinding() const { return st_info >> 4; }
-
- /// Returns the type attribute of the st_info member.
- unsigned char getType() const { return st_info & 0x0F; }
-
- /// Sets the binding and type of the st_info member.
- void setBindingAndType(unsigned char binding, unsigned char type) {
- st_info = (binding << 4) + (type & 0x0F);
- }
-
- static const char *
- bindingToCString(unsigned char binding);
-
- static const char *
- typeToCString(unsigned char type);
-
- static const char *
- sectionIndexToCString(elf_half shndx,
- const lldb_private::SectionList *section_list);
-
- /// Parse an ELFSymbol entry from the given DataExtractor starting at
- /// position \p offset. The address size of the DataExtractor determines if
- /// a 32 or 64 bit object is to be parsed.
- ///
- /// @param[in] data
- /// The DataExtractor to read from. The address size of the extractor
- /// determines if a 32 or 64 bit object should be read.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFSymbol was successfully read and false otherwise.
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
-
- void
- Dump (lldb_private::Stream *s,
- uint32_t idx,
- const lldb_private::DataExtractor *strtab_data,
- const lldb_private::SectionList *section_list);
+struct ELFSymbol {
+ elf_addr st_value; ///< Absolute or relocatable address.
+ elf_xword st_size; ///< Size of the symbol or zero.
+ elf_word st_name; ///< Symbol name string index.
+ unsigned char st_info; ///< Symbol type and binding attributes.
+ unsigned char st_other; ///< Reserved for future use.
+ elf_half st_shndx; ///< Section to which this symbol applies.
+
+ ELFSymbol();
+
+ /// Returns the binding attribute of the st_info member.
+ unsigned char getBinding() const { return st_info >> 4; }
+
+ /// Returns the type attribute of the st_info member.
+ unsigned char getType() const { return st_info & 0x0F; }
+
+ /// Sets the binding and type of the st_info member.
+ void setBindingAndType(unsigned char binding, unsigned char type) {
+ st_info = (binding << 4) + (type & 0x0F);
+ }
+
+ static const char *bindingToCString(unsigned char binding);
+
+ static const char *typeToCString(unsigned char type);
+
+ static const char *
+ sectionIndexToCString(elf_half shndx,
+ const lldb_private::SectionList *section_list);
+
+ /// Parse an ELFSymbol entry from the given DataExtractor starting at
+ /// position \p offset. The address size of the DataExtractor determines if
+ /// a 32 or 64 bit object is to be parsed.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from. The address size of the extractor
+ /// determines if a 32 or 64 bit object should be read.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFSymbol was successfully read and false otherwise.
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+
+ void Dump(lldb_private::Stream *s, uint32_t idx,
+ const lldb_private::DataExtractor *strtab_data,
+ const lldb_private::SectionList *section_list);
};
//------------------------------------------------------------------------------
/// @class ELFDynamic
/// @brief Represents an entry in an ELF dynamic table.
-struct ELFDynamic
-{
- elf_sxword d_tag; ///< Type of dynamic table entry.
- union
- {
- elf_xword d_val; ///< Integer value of the table entry.
- elf_addr d_ptr; ///< Pointer value of the table entry.
- };
-
- ELFDynamic();
-
- /// Parse an ELFDynamic entry from the given DataExtractor starting at
- /// position \p offset. The address size of the DataExtractor determines if
- /// a 32 or 64 bit object is to be parsed.
- ///
- /// @param[in] data
- /// The DataExtractor to read from. The address size of the extractor
- /// determines if a 32 or 64 bit object should be read.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFDynamic entry was successfully read and false
- /// otherwise.
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+struct ELFDynamic {
+ elf_sxword d_tag; ///< Type of dynamic table entry.
+ union {
+ elf_xword d_val; ///< Integer value of the table entry.
+ elf_addr d_ptr; ///< Pointer value of the table entry.
+ };
+
+ ELFDynamic();
+
+ /// Parse an ELFDynamic entry from the given DataExtractor starting at
+ /// position \p offset. The address size of the DataExtractor determines if
+ /// a 32 or 64 bit object is to be parsed.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from. The address size of the extractor
+ /// determines if a 32 or 64 bit object should be read.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFDynamic entry was successfully read and false
+ /// otherwise.
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
/// @class ELFRel
/// @brief Represents a relocation entry with an implicit addend.
-struct ELFRel
-{
- elf_addr r_offset; ///< Address of reference.
- elf_xword r_info; ///< symbol index and type of relocation.
-
- ELFRel();
-
- /// Parse an ELFRel entry from the given DataExtractor starting at position
- /// \p offset. The address size of the DataExtractor determines if a 32 or
- /// 64 bit object is to be parsed.
- ///
- /// @param[in] data
- /// The DataExtractor to read from. The address size of the extractor
- /// determines if a 32 or 64 bit object should be read.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFRel entry was successfully read and false otherwise.
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
-
- /// Returns the type when the given entry represents a 32-bit relocation.
- static unsigned
- RelocType32(const ELFRel &rel)
- {
- return rel.r_info & 0x0ff;
- }
-
- /// Returns the type when the given entry represents a 64-bit relocation.
- static unsigned
- RelocType64(const ELFRel &rel)
- {
- return rel.r_info & 0xffffffff;
- }
-
- /// Returns the symbol index when the given entry represents a 32-bit
- /// relocation.
- static unsigned
- RelocSymbol32(const ELFRel &rel)
- {
- return rel.r_info >> 8;
- }
-
- /// Returns the symbol index when the given entry represents a 64-bit
- /// relocation.
- static unsigned
- RelocSymbol64(const ELFRel &rel)
- {
- return rel.r_info >> 32;
- }
+struct ELFRel {
+ elf_addr r_offset; ///< Address of reference.
+ elf_xword r_info; ///< symbol index and type of relocation.
+
+ ELFRel();
+
+ /// Parse an ELFRel entry from the given DataExtractor starting at position
+ /// \p offset. The address size of the DataExtractor determines if a 32 or
+ /// 64 bit object is to be parsed.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from. The address size of the extractor
+ /// determines if a 32 or 64 bit object should be read.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFRel entry was successfully read and false otherwise.
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+
+ /// Returns the type when the given entry represents a 32-bit relocation.
+ static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }
+
+ /// Returns the type when the given entry represents a 64-bit relocation.
+ static unsigned RelocType64(const ELFRel &rel) {
+ return rel.r_info & 0xffffffff;
+ }
+
+ /// Returns the symbol index when the given entry represents a 32-bit
+ /// relocation.
+ static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }
+
+ /// Returns the symbol index when the given entry represents a 64-bit
+ /// relocation.
+ static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }
};
//------------------------------------------------------------------------------
/// @class ELFRela
/// @brief Represents a relocation entry with an explicit addend.
-struct ELFRela
-{
- elf_addr r_offset; ///< Address of reference.
- elf_xword r_info; ///< Symbol index and type of relocation.
- elf_sxword r_addend; ///< Constant part of expression.
-
- ELFRela();
-
- /// Parse an ELFRela entry from the given DataExtractor starting at position
- /// \p offset. The address size of the DataExtractor determines if a 32 or
- /// 64 bit object is to be parsed.
- ///
- /// @param[in] data
- /// The DataExtractor to read from. The address size of the extractor
- /// determines if a 32 or 64 bit object should be read.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFRela entry was successfully read and false otherwise.
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
-
- /// Returns the type when the given entry represents a 32-bit relocation.
- static unsigned
- RelocType32(const ELFRela &rela)
- {
- return rela.r_info & 0x0ff;
- }
-
- /// Returns the type when the given entry represents a 64-bit relocation.
- static unsigned
- RelocType64(const ELFRela &rela)
- {
- return rela.r_info & 0xffffffff;
- }
-
- /// Returns the symbol index when the given entry represents a 32-bit
- /// relocation.
- static unsigned
- RelocSymbol32(const ELFRela &rela)
- {
- return rela.r_info >> 8;
- }
-
- /// Returns the symbol index when the given entry represents a 64-bit
- /// relocation.
- static unsigned
- RelocSymbol64(const ELFRela &rela)
- {
- return rela.r_info >> 32;
- }
+struct ELFRela {
+ elf_addr r_offset; ///< Address of reference.
+ elf_xword r_info; ///< Symbol index and type of relocation.
+ elf_sxword r_addend; ///< Constant part of expression.
+
+ ELFRela();
+
+ /// Parse an ELFRela entry from the given DataExtractor starting at position
+ /// \p offset. The address size of the DataExtractor determines if a 32 or
+ /// 64 bit object is to be parsed.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from. The address size of the extractor
+ /// determines if a 32 or 64 bit object should be read.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFRela entry was successfully read and false otherwise.
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+
+ /// Returns the type when the given entry represents a 32-bit relocation.
+ static unsigned RelocType32(const ELFRela &rela) {
+ return rela.r_info & 0x0ff;
+ }
+
+ /// Returns the type when the given entry represents a 64-bit relocation.
+ static unsigned RelocType64(const ELFRela &rela) {
+ return rela.r_info & 0xffffffff;
+ }
+
+ /// Returns the symbol index when the given entry represents a 32-bit
+ /// relocation.
+ static unsigned RelocSymbol32(const ELFRela &rela) {
+ return rela.r_info >> 8;
+ }
+
+ /// Returns the symbol index when the given entry represents a 64-bit
+ /// relocation.
+ static unsigned RelocSymbol64(const ELFRela &rela) {
+ return rela.r_info >> 32;
+ }
};
} // End namespace elf.
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 68e4e50a96e5..eb983154618b 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -9,8 +9,8 @@
#include "ObjectFileELF.h"
-#include <cassert>
#include <algorithm>
+#include <cassert>
#include <unordered_map>
#include "lldb/Core/ArchSpec.h"
@@ -35,8 +35,10 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MipsABIFlags.h"
-#define CASE_AND_STREAM(s, def, width) \
- case def: s->Printf("%-*s", width, #def); break;
+#define CASE_AND_STREAM(s, def, width) \
+ case def: \
+ s->Printf("%-*s", width, #def); \
+ break;
using namespace lldb;
using namespace lldb_private;
@@ -47,64 +49,64 @@ namespace {
// ELF note owner definitions
const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";
-const char *const LLDB_NT_OWNER_GNU = "GNU";
-const char *const LLDB_NT_OWNER_NETBSD = "NetBSD";
-const char *const LLDB_NT_OWNER_CSR = "csr";
+const char *const LLDB_NT_OWNER_GNU = "GNU";
+const char *const LLDB_NT_OWNER_NETBSD = "NetBSD";
+const char *const LLDB_NT_OWNER_CSR = "csr";
const char *const LLDB_NT_OWNER_ANDROID = "Android";
-const char *const LLDB_NT_OWNER_CORE = "CORE";
-const char *const LLDB_NT_OWNER_LINUX = "LINUX";
+const char *const LLDB_NT_OWNER_CORE = "CORE";
+const char *const LLDB_NT_OWNER_LINUX = "LINUX";
// ELF note type definitions
-const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01;
+const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01;
const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4;
-const elf_word LLDB_NT_GNU_ABI_TAG = 0x01;
-const elf_word LLDB_NT_GNU_ABI_SIZE = 16;
+const elf_word LLDB_NT_GNU_ABI_TAG = 0x01;
+const elf_word LLDB_NT_GNU_ABI_SIZE = 16;
const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03;
-const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01;
-const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4;
+const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01;
+const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4;
// GNU ABI note OS constants
-const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
-const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
+const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
+const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
// LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants
-#define NT_PRSTATUS 1
-#define NT_PRFPREG 2
-#define NT_PRPSINFO 3
-#define NT_TASKSTRUCT 4
-#define NT_AUXV 6
-#define NT_SIGINFO 0x53494749
-#define NT_FILE 0x46494c45
-#define NT_PRXFPREG 0x46e62b7f
-#define NT_PPC_VMX 0x100
-#define NT_PPC_SPE 0x101
-#define NT_PPC_VSX 0x102
-#define NT_386_TLS 0x200
-#define NT_386_IOPERM 0x201
-#define NT_X86_XSTATE 0x202
-#define NT_S390_HIGH_GPRS 0x300
-#define NT_S390_TIMER 0x301
-#define NT_S390_TODCMP 0x302
-#define NT_S390_TODPREG 0x303
-#define NT_S390_CTRS 0x304
-#define NT_S390_PREFIX 0x305
-#define NT_S390_LAST_BREAK 0x306
-#define NT_S390_SYSTEM_CALL 0x307
-#define NT_S390_TDB 0x308
-#define NT_S390_VXRS_LOW 0x309
-#define NT_S390_VXRS_HIGH 0x30a
-#define NT_ARM_VFP 0x400
-#define NT_ARM_TLS 0x401
-#define NT_ARM_HW_BREAK 0x402
-#define NT_ARM_HW_WATCH 0x403
-#define NT_ARM_SYSTEM_CALL 0x404
-#define NT_METAG_CBUF 0x500
-#define NT_METAG_RPIPE 0x501
-#define NT_METAG_TLS 0x502
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+#define NT_AUXV 6
+#define NT_SIGINFO 0x53494749
+#define NT_FILE 0x46494c45
+#define NT_PRXFPREG 0x46e62b7f
+#define NT_PPC_VMX 0x100
+#define NT_PPC_SPE 0x101
+#define NT_PPC_VSX 0x102
+#define NT_386_TLS 0x200
+#define NT_386_IOPERM 0x201
+#define NT_X86_XSTATE 0x202
+#define NT_S390_HIGH_GPRS 0x300
+#define NT_S390_TIMER 0x301
+#define NT_S390_TODCMP 0x302
+#define NT_S390_TODPREG 0x303
+#define NT_S390_CTRS 0x304
+#define NT_S390_PREFIX 0x305
+#define NT_S390_LAST_BREAK 0x306
+#define NT_S390_SYSTEM_CALL 0x307
+#define NT_S390_TDB 0x308
+#define NT_S390_VXRS_LOW 0x309
+#define NT_S390_VXRS_HIGH 0x30a
+#define NT_ARM_VFP 0x400
+#define NT_ARM_TLS 0x401
+#define NT_ARM_HW_BREAK 0x402
+#define NT_ARM_HW_WATCH 0x403
+#define NT_ARM_SYSTEM_CALL 0x404
+#define NT_METAG_CBUF 0x500
+#define NT_METAG_RPIPE 0x501
+#define NT_METAG_TLS 0x502
//===----------------------------------------------------------------------===//
/// @class ELFRelocation
@@ -112,401 +114,335 @@ const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
///
/// This helper class allows us to parse both ELFRel and ELFRela relocation
/// entries in a generic manner.
-class ELFRelocation
-{
+class ELFRelocation {
public:
+ /// Constructs an ELFRelocation entry with a personality as given by @p
+ /// type.
+ ///
+ /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
+ ELFRelocation(unsigned type);
- /// Constructs an ELFRelocation entry with a personality as given by @p
- /// type.
- ///
- /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
- ELFRelocation(unsigned type);
-
- ~ELFRelocation();
+ ~ELFRelocation();
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
- static unsigned
- RelocType32(const ELFRelocation &rel);
+ static unsigned RelocType32(const ELFRelocation &rel);
- static unsigned
- RelocType64(const ELFRelocation &rel);
+ static unsigned RelocType64(const ELFRelocation &rel);
- static unsigned
- RelocSymbol32(const ELFRelocation &rel);
+ static unsigned RelocSymbol32(const ELFRelocation &rel);
- static unsigned
- RelocSymbol64(const ELFRelocation &rel);
+ static unsigned RelocSymbol64(const ELFRelocation &rel);
- static unsigned
- RelocOffset32(const ELFRelocation &rel);
+ static unsigned RelocOffset32(const ELFRelocation &rel);
- static unsigned
- RelocOffset64(const ELFRelocation &rel);
+ static unsigned RelocOffset64(const ELFRelocation &rel);
- static unsigned
- RelocAddend32(const ELFRelocation &rel);
+ static unsigned RelocAddend32(const ELFRelocation &rel);
- static unsigned
- RelocAddend64(const ELFRelocation &rel);
+ static unsigned RelocAddend64(const ELFRelocation &rel);
private:
- typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion;
+ typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
- RelocUnion reloc;
+ RelocUnion reloc;
};
-ELFRelocation::ELFRelocation(unsigned type)
-{
- if (type == DT_REL || type == SHT_REL)
- reloc = new ELFRel();
- else if (type == DT_RELA || type == SHT_RELA)
- reloc = new ELFRela();
- else {
- assert(false && "unexpected relocation type");
- reloc = static_cast<ELFRel*>(NULL);
- }
+ELFRelocation::ELFRelocation(unsigned type) {
+ if (type == DT_REL || type == SHT_REL)
+ reloc = new ELFRel();
+ else if (type == DT_RELA || type == SHT_RELA)
+ reloc = new ELFRela();
+ else {
+ assert(false && "unexpected relocation type");
+ reloc = static_cast<ELFRel *>(NULL);
+ }
}
-ELFRelocation::~ELFRelocation()
-{
- if (reloc.is<ELFRel*>())
- delete reloc.get<ELFRel*>();
- else
- delete reloc.get<ELFRela*>();
+ELFRelocation::~ELFRelocation() {
+ if (reloc.is<ELFRel *>())
+ delete reloc.get<ELFRel *>();
+ else
+ delete reloc.get<ELFRela *>();
}
-bool
-ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
-{
- if (reloc.is<ELFRel*>())
- return reloc.get<ELFRel*>()->Parse(data, offset);
- else
- return reloc.get<ELFRela*>()->Parse(data, offset);
+bool ELFRelocation::Parse(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset) {
+ if (reloc.is<ELFRel *>())
+ return reloc.get<ELFRel *>()->Parse(data, offset);
+ else
+ return reloc.get<ELFRela *>()->Parse(data, offset);
}
-unsigned
-ELFRelocation::RelocType32(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>());
- else
- return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>());
+unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>());
+ else
+ return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>());
}
-unsigned
-ELFRelocation::RelocType64(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>());
- else
- return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>());
+unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>());
+ else
+ return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>());
}
-unsigned
-ELFRelocation::RelocSymbol32(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>());
- else
- return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>());
+unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>());
+ else
+ return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>());
}
-unsigned
-ELFRelocation::RelocSymbol64(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>());
- else
- return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>());
+unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>());
+ else
+ return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>());
}
-unsigned
-ELFRelocation::RelocOffset32(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return rel.reloc.get<ELFRel*>()->r_offset;
- else
- return rel.reloc.get<ELFRela*>()->r_offset;
+unsigned ELFRelocation::RelocOffset32(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return rel.reloc.get<ELFRel *>()->r_offset;
+ else
+ return rel.reloc.get<ELFRela *>()->r_offset;
}
-unsigned
-ELFRelocation::RelocOffset64(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return rel.reloc.get<ELFRel*>()->r_offset;
- else
- return rel.reloc.get<ELFRela*>()->r_offset;
+unsigned ELFRelocation::RelocOffset64(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return rel.reloc.get<ELFRel *>()->r_offset;
+ else
+ return rel.reloc.get<ELFRela *>()->r_offset;
}
-unsigned
-ELFRelocation::RelocAddend32(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return 0;
- else
- return rel.reloc.get<ELFRela*>()->r_addend;
+unsigned ELFRelocation::RelocAddend32(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return 0;
+ else
+ return rel.reloc.get<ELFRela *>()->r_addend;
}
-unsigned
-ELFRelocation::RelocAddend64(const ELFRelocation &rel)
-{
- if (rel.reloc.is<ELFRel*>())
- return 0;
- else
- return rel.reloc.get<ELFRela*>()->r_addend;
+unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
+ if (rel.reloc.is<ELFRel *>())
+ return 0;
+ else
+ return rel.reloc.get<ELFRela *>()->r_addend;
}
} // end anonymous namespace
-bool
-ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset)
-{
- // Read all fields.
- if (data.GetU32(offset, &n_namesz, 3) == NULL)
- return false;
-
- // The name field is required to be nul-terminated, and n_namesz
- // includes the terminating nul in observed implementations (contrary
- // to the ELF-64 spec). A special case is needed for cores generated
- // by some older Linux versions, which write a note named "CORE"
- // without a nul terminator and n_namesz = 4.
- if (n_namesz == 4)
- {
- char buf[4];
- if (data.ExtractBytes (*offset, 4, data.GetByteOrder(), buf) != 4)
- return false;
- if (strncmp (buf, "CORE", 4) == 0)
- {
- n_name = "CORE";
- *offset += 4;
- return true;
- }
- }
-
- const char *cstr = data.GetCStr(offset, llvm::alignTo (n_namesz, 4));
- if (cstr == NULL)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
- if (log)
- log->Printf("Failed to parse note name lacking nul terminator");
-
- return false;
- }
- n_name = cstr;
- return true;
-}
-
-static uint32_t
-kalimbaVariantFromElfFlags(const elf::elf_word e_flags)
-{
- const uint32_t dsp_rev = e_flags & 0xFF;
- uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE;
- switch(dsp_rev)
- {
- // TODO(mg11) Support more variants
- case 10:
- kal_arch_variant = llvm::Triple::KalimbaSubArch_v3;
- break;
- case 14:
- kal_arch_variant = llvm::Triple::KalimbaSubArch_v4;
- break;
- case 17:
- case 20:
- kal_arch_variant = llvm::Triple::KalimbaSubArch_v5;
- break;
- default:
- break;
- }
- return kal_arch_variant;
-}
-
-static uint32_t
-mipsVariantFromElfFlags(const elf::elf_word e_flags, uint32_t endian)
-{
- const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH;
- uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
-
- switch (mips_arch)
- {
- case llvm::ELF::EF_MIPS_ARCH_1:
- case llvm::ELF::EF_MIPS_ARCH_2:
- case llvm::ELF::EF_MIPS_ARCH_32:
- return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el : ArchSpec::eMIPSSubType_mips32;
- case llvm::ELF::EF_MIPS_ARCH_32R2:
- return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el : ArchSpec::eMIPSSubType_mips32r2;
- case llvm::ELF::EF_MIPS_ARCH_32R6:
- return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el : ArchSpec::eMIPSSubType_mips32r6;
- case llvm::ELF::EF_MIPS_ARCH_3:
- case llvm::ELF::EF_MIPS_ARCH_4:
- case llvm::ELF::EF_MIPS_ARCH_5:
- case llvm::ELF::EF_MIPS_ARCH_64:
- return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el : ArchSpec::eMIPSSubType_mips64;
- case llvm::ELF::EF_MIPS_ARCH_64R2:
- return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el : ArchSpec::eMIPSSubType_mips64r2;
- case llvm::ELF::EF_MIPS_ARCH_64R6:
- return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el : ArchSpec::eMIPSSubType_mips64r6;
- default:
- break;
- }
-
- return arch_variant;
-}
+bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
+ // Read all fields.
+ if (data.GetU32(offset, &n_namesz, 3) == NULL)
+ return false;
-static uint32_t
-subTypeFromElfHeader(const elf::ELFHeader& header)
-{
- if (header.e_machine == llvm::ELF::EM_MIPS)
- return mipsVariantFromElfFlags (header.e_flags,
- header.e_ident[EI_DATA]);
+ // The name field is required to be nul-terminated, and n_namesz
+ // includes the terminating nul in observed implementations (contrary
+ // to the ELF-64 spec). A special case is needed for cores generated
+ // by some older Linux versions, which write a note named "CORE"
+ // without a nul terminator and n_namesz = 4.
+ if (n_namesz == 4) {
+ char buf[4];
+ if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4)
+ return false;
+ if (strncmp(buf, "CORE", 4) == 0) {
+ n_name = "CORE";
+ *offset += 4;
+ return true;
+ }
+ }
+
+ const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
+ if (cstr == NULL) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+ if (log)
+ log->Printf("Failed to parse note name lacking nul terminator");
- return
- llvm::ELF::EM_CSR_KALIMBA == header.e_machine ?
- kalimbaVariantFromElfFlags(header.e_flags) :
- LLDB_INVALID_CPUTYPE;
+ return false;
+ }
+ n_name = cstr;
+ return true;
+}
+
+static uint32_t kalimbaVariantFromElfFlags(const elf::elf_word e_flags) {
+ const uint32_t dsp_rev = e_flags & 0xFF;
+ uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE;
+ switch (dsp_rev) {
+ // TODO(mg11) Support more variants
+ case 10:
+ kal_arch_variant = llvm::Triple::KalimbaSubArch_v3;
+ break;
+ case 14:
+ kal_arch_variant = llvm::Triple::KalimbaSubArch_v4;
+ break;
+ case 17:
+ case 20:
+ kal_arch_variant = llvm::Triple::KalimbaSubArch_v5;
+ break;
+ default:
+ break;
+ }
+ return kal_arch_variant;
+}
+
+static uint32_t mipsVariantFromElfFlags(const elf::elf_word e_flags,
+ uint32_t endian) {
+ const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH;
+ uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
+
+ switch (mips_arch) {
+ case llvm::ELF::EF_MIPS_ARCH_1:
+ case llvm::ELF::EF_MIPS_ARCH_2:
+ case llvm::ELF::EF_MIPS_ARCH_32:
+ return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
+ : ArchSpec::eMIPSSubType_mips32;
+ case llvm::ELF::EF_MIPS_ARCH_32R2:
+ return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el
+ : ArchSpec::eMIPSSubType_mips32r2;
+ case llvm::ELF::EF_MIPS_ARCH_32R6:
+ return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el
+ : ArchSpec::eMIPSSubType_mips32r6;
+ case llvm::ELF::EF_MIPS_ARCH_3:
+ case llvm::ELF::EF_MIPS_ARCH_4:
+ case llvm::ELF::EF_MIPS_ARCH_5:
+ case llvm::ELF::EF_MIPS_ARCH_64:
+ return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
+ : ArchSpec::eMIPSSubType_mips64;
+ case llvm::ELF::EF_MIPS_ARCH_64R2:
+ return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el
+ : ArchSpec::eMIPSSubType_mips64r2;
+ case llvm::ELF::EF_MIPS_ARCH_64R6:
+ return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el
+ : ArchSpec::eMIPSSubType_mips64r6;
+ default:
+ break;
+ }
+
+ return arch_variant;
+}
+
+static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
+ if (header.e_machine == llvm::ELF::EM_MIPS)
+ return mipsVariantFromElfFlags(header.e_flags, header.e_ident[EI_DATA]);
+
+ return llvm::ELF::EM_CSR_KALIMBA == header.e_machine
+ ? kalimbaVariantFromElfFlags(header.e_flags)
+ : LLDB_INVALID_CPUTYPE;
}
//! The kalimba toolchain identifies a code section as being
//! one with the SHT_PROGBITS set in the section sh_type and the top
//! bit in the 32-bit address field set.
static lldb::SectionType
-kalimbaSectionType(
- const elf::ELFHeader& header,
- const elf::ELFSectionHeader& sect_hdr)
-{
- if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine)
- {
- return eSectionTypeOther;
- }
+kalimbaSectionType(const elf::ELFHeader &header,
+ const elf::ELFSectionHeader &sect_hdr) {
+ if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine) {
+ return eSectionTypeOther;
+ }
- if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type)
- {
- return eSectionTypeZeroFill;
- }
+ if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type) {
+ return eSectionTypeZeroFill;
+ }
- if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type)
- {
- const lldb::addr_t KAL_CODE_BIT = 1 << 31;
- return KAL_CODE_BIT & sect_hdr.sh_addr ?
- eSectionTypeCode : eSectionTypeData;
- }
+ if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type) {
+ const lldb::addr_t KAL_CODE_BIT = 1 << 31;
+ return KAL_CODE_BIT & sect_hdr.sh_addr ? eSectionTypeCode
+ : eSectionTypeData;
+ }
- return eSectionTypeOther;
+ return eSectionTypeOther;
}
// Arbitrary constant used as UUID prefix for core files.
-const uint32_t
-ObjectFileELF::g_core_uuid_magic(0xE210C);
+const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
//------------------------------------------------------------------
// Static methods.
//------------------------------------------------------------------
-void
-ObjectFileELF::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- CreateMemoryInstance,
- GetModuleSpecifications);
-}
-
-void
-ObjectFileELF::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString
-ObjectFileELF::GetPluginNameStatic()
-{
- static ConstString g_name("elf");
- return g_name;
-}
-
-const char *
-ObjectFileELF::GetPluginDescriptionStatic()
-{
- return "ELF object file reader.";
-}
-
-ObjectFile *
-ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP &data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length)
-{
- if (!data_sp)
- {
- data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
- data_offset = 0;
- }
+void ObjectFileELF::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ CreateMemoryInstance, GetModuleSpecifications);
+}
- if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
- {
- const uint8_t *magic = data_sp->GetBytes() + data_offset;
- if (ELFHeader::MagicBytesMatch(magic))
- {
- // Update the data to contain the entire file if it doesn't already
- if (data_sp->GetByteSize() < length) {
- data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
- data_offset = 0;
- magic = data_sp->GetBytes();
- }
- unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
- 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))
- return objfile_ap.release();
- }
- }
- }
- return NULL;
+void ObjectFileELF::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
+lldb_private::ConstString ObjectFileELF::GetPluginNameStatic() {
+ static ConstString g_name("elf");
+ return g_name;
+}
-ObjectFile*
-ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- const lldb::ProcessSP &process_sp,
- lldb::addr_t header_addr)
-{
- if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT))
- {
- const uint8_t *magic = data_sp->GetBytes();
- if (ELFHeader::MagicBytesMatch(magic))
- {
- unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
- if (address_size == 4 || address_size == 8)
- {
- std::auto_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))
- return objfile_ap.release();
- }
- }
- }
- return NULL;
+const char *ObjectFileELF::GetPluginDescriptionStatic() {
+ return "ELF object file reader.";
}
-bool
-ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,
- lldb::addr_t data_offset,
- lldb::addr_t data_length)
-{
- if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
- {
- const uint8_t *magic = data_sp->GetBytes() + data_offset;
- return ELFHeader::MagicBytesMatch(magic);
- }
- return false;
+ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec *file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length) {
+ if (!data_sp) {
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (data_sp &&
+ data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
+ const uint8_t *magic = data_sp->GetBytes() + data_offset;
+ if (ELFHeader::MagicBytesMatch(magic)) {
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length) {
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
+ data_offset = 0;
+ magic = data_sp->GetBytes();
+ }
+ unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
+ 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))
+ return objfile_ap.release();
+ }
+ }
+ }
+ return NULL;
+}
+
+ObjectFile *ObjectFileELF::CreateMemoryInstance(
+ const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
+ const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
+ if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) {
+ const uint8_t *magic = data_sp->GetBytes();
+ if (ELFHeader::MagicBytesMatch(magic)) {
+ unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
+ if (address_size == 4 || address_size == 8) {
+ std::auto_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))
+ return objfile_ap.release();
+ }
+ }
+ }
+ return NULL;
+}
+
+bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
+ lldb::addr_t data_offset,
+ lldb::addr_t data_length) {
+ if (data_sp &&
+ data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
+ const uint8_t *magic = data_sp->GetBytes() + data_offset;
+ return ELFHeader::MagicBytesMatch(magic);
+ }
+ return false;
}
/*
@@ -515,130 +451,117 @@ ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
-static uint32_t
-calc_crc32(uint32_t crc, const void *buf, size_t size)
-{
- static const uint32_t g_crc32_tab[] =
- {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
- };
- const uint8_t *p = (const uint8_t *)buf;
-
- crc = crc ^ ~0U;
- while (size--)
- crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
- return crc ^ ~0U;
-}
-
-static uint32_t
-calc_gnu_debuglink_crc32(const void *buf, size_t size)
-{
- return calc_crc32(0U, buf, 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;
-
- DataExtractor segment_data;
- if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size)
- {
- // The ELF program header contained incorrect data,
- // probably corefile is incomplete or corrupted.
- break;
- }
-
- core_notes_crc = calc_crc32(core_notes_crc,
- segment_data.GetDataStart(),
- segment_data.GetByteSize());
- }
- }
-
- return core_notes_crc;
-}
-
-static const char*
-OSABIAsCString (unsigned char osabi_byte)
-{
-#define _MAKE_OSABI_CASE(x) case x: return #x
- switch (osabi_byte)
- {
- _MAKE_OSABI_CASE(ELFOSABI_NONE);
- _MAKE_OSABI_CASE(ELFOSABI_HPUX);
- _MAKE_OSABI_CASE(ELFOSABI_NETBSD);
- _MAKE_OSABI_CASE(ELFOSABI_GNU);
- _MAKE_OSABI_CASE(ELFOSABI_HURD);
- _MAKE_OSABI_CASE(ELFOSABI_SOLARIS);
- _MAKE_OSABI_CASE(ELFOSABI_AIX);
- _MAKE_OSABI_CASE(ELFOSABI_IRIX);
- _MAKE_OSABI_CASE(ELFOSABI_FREEBSD);
- _MAKE_OSABI_CASE(ELFOSABI_TRU64);
- _MAKE_OSABI_CASE(ELFOSABI_MODESTO);
- _MAKE_OSABI_CASE(ELFOSABI_OPENBSD);
- _MAKE_OSABI_CASE(ELFOSABI_OPENVMS);
- _MAKE_OSABI_CASE(ELFOSABI_NSK);
- _MAKE_OSABI_CASE(ELFOSABI_AROS);
- _MAKE_OSABI_CASE(ELFOSABI_FENIXOS);
- _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI);
- _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX);
- _MAKE_OSABI_CASE(ELFOSABI_ARM);
- _MAKE_OSABI_CASE(ELFOSABI_STANDALONE);
- default:
- return "<unknown-osabi>";
- }
+static uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) {
+ static const uint32_t g_crc32_tab[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
+ const uint8_t *p = (const uint8_t *)buf;
+
+ crc = crc ^ ~0U;
+ while (size--)
+ crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+ return crc ^ ~0U;
+}
+
+static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) {
+ return calc_crc32(0U, buf, 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;
+
+ DataExtractor segment_data;
+ if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) {
+ // The ELF program header contained incorrect data,
+ // probably corefile is incomplete or corrupted.
+ break;
+ }
+
+ core_notes_crc = calc_crc32(core_notes_crc, segment_data.GetDataStart(),
+ segment_data.GetByteSize());
+ }
+ }
+
+ return core_notes_crc;
+}
+
+static const char *OSABIAsCString(unsigned char osabi_byte) {
+#define _MAKE_OSABI_CASE(x) \
+ case x: \
+ return #x
+ switch (osabi_byte) {
+ _MAKE_OSABI_CASE(ELFOSABI_NONE);
+ _MAKE_OSABI_CASE(ELFOSABI_HPUX);
+ _MAKE_OSABI_CASE(ELFOSABI_NETBSD);
+ _MAKE_OSABI_CASE(ELFOSABI_GNU);
+ _MAKE_OSABI_CASE(ELFOSABI_HURD);
+ _MAKE_OSABI_CASE(ELFOSABI_SOLARIS);
+ _MAKE_OSABI_CASE(ELFOSABI_AIX);
+ _MAKE_OSABI_CASE(ELFOSABI_IRIX);
+ _MAKE_OSABI_CASE(ELFOSABI_FREEBSD);
+ _MAKE_OSABI_CASE(ELFOSABI_TRU64);
+ _MAKE_OSABI_CASE(ELFOSABI_MODESTO);
+ _MAKE_OSABI_CASE(ELFOSABI_OPENBSD);
+ _MAKE_OSABI_CASE(ELFOSABI_OPENVMS);
+ _MAKE_OSABI_CASE(ELFOSABI_NSK);
+ _MAKE_OSABI_CASE(ELFOSABI_AROS);
+ _MAKE_OSABI_CASE(ELFOSABI_FENIXOS);
+ _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI);
+ _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX);
+ _MAKE_OSABI_CASE(ELFOSABI_ARM);
+ _MAKE_OSABI_CASE(ELFOSABI_STANDALONE);
+ default:
+ return "<unknown-osabi>";
+ }
#undef _MAKE_OSABI_CASE
}
@@ -648,2480 +571,2427 @@ OSABIAsCString (unsigned char osabi_byte)
// This function is only being kept to validate the move.
//
// TODO : Remove this function
-static bool
-GetOsFromOSABI (unsigned char osabi_byte, llvm::Triple::OSType &ostype)
-{
- switch (osabi_byte)
- {
- case ELFOSABI_AIX: ostype = llvm::Triple::OSType::AIX; break;
- case ELFOSABI_FREEBSD: ostype = llvm::Triple::OSType::FreeBSD; break;
- case ELFOSABI_GNU: ostype = llvm::Triple::OSType::Linux; break;
- case ELFOSABI_NETBSD: ostype = llvm::Triple::OSType::NetBSD; break;
- case ELFOSABI_OPENBSD: ostype = llvm::Triple::OSType::OpenBSD; break;
- case ELFOSABI_SOLARIS: ostype = llvm::Triple::OSType::Solaris; break;
- default:
- ostype = llvm::Triple::OSType::UnknownOS;
- }
- return ostype != llvm::Triple::OSType::UnknownOS;
-}
-
-size_t
-ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES));
-
- const size_t initial_count = specs.GetSize();
-
- if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
- {
- DataExtractor data;
- data.SetData(data_sp);
- elf::ELFHeader header;
- if (header.Parse(data, &data_offset))
- {
- if (data_sp)
- {
- ModuleSpec spec (file);
-
- const uint32_t sub_type = subTypeFromElfHeader(header);
- spec.GetArchitecture().SetArchitecture(eArchTypeELF,
- header.e_machine,
- sub_type,
- header.e_ident[EI_OSABI]);
-
- if (spec.GetArchitecture().IsValid())
- {
- llvm::Triple::OSType ostype;
- llvm::Triple::VendorType vendor;
- llvm::Triple::OSType spec_ostype = spec.GetArchitecture ().GetTriple ().getOS ();
-
- if (log)
- log->Printf ("ObjectFileELF::%s file '%s' module OSABI: %s", __FUNCTION__, file.GetPath ().c_str (), OSABIAsCString (header.e_ident[EI_OSABI]));
-
- // SetArchitecture should have set the vendor to unknown
- vendor = spec.GetArchitecture ().GetTriple ().getVendor ();
- assert(vendor == llvm::Triple::UnknownVendor);
-
- //
- // Validate it is ok to remove GetOsFromOSABI
- GetOsFromOSABI (header.e_ident[EI_OSABI], ostype);
- assert(spec_ostype == ostype);
- if (spec_ostype != llvm::Triple::OSType::UnknownOS)
- {
- if (log)
- log->Printf ("ObjectFileELF::%s file '%s' set ELF module OS type from ELF header OSABI.", __FUNCTION__, file.GetPath ().c_str ());
- }
-
- // Try to get the UUID from the section list. Usually that's at the end, so
- // map the file in if we don't have it already.
- size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
- if (section_header_end > data_sp->GetByteSize())
- {
- data_sp = file.MemoryMapFileContentsIfLocal (file_offset, section_header_end);
- data.SetData(data_sp);
- }
-
- uint32_t gnu_debuglink_crc = 0;
- std::string gnu_debuglink_file;
- SectionHeaderColl section_headers;
- lldb_private::UUID &uuid = spec.GetUUID();
-
- using namespace std::placeholders;
- const SetDataFunction set_data = std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3);
- GetSectionHeaderInfo(section_headers, set_data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ());
-
-
- llvm::Triple &spec_triple = spec.GetArchitecture ().GetTriple ();
-
- if (log)
- log->Printf ("ObjectFileELF::%s file '%s' module set to triple: %s (architecture %s)", __FUNCTION__, file.GetPath ().c_str (), spec_triple.getTriple ().c_str (), spec.GetArchitecture ().GetArchitectureName ());
-
- if (!uuid.IsValid())
- {
- uint32_t core_notes_crc = 0;
-
- if (!gnu_debuglink_crc)
- {
- lldb_private::Timer scoped_timer (__PRETTY_FUNCTION__,
- "Calculating module crc32 %s with size %" PRIu64 " KiB",
- file.GetLastPathComponent().AsCString(),
- (file.GetByteSize()-file_offset)/1024);
-
- // For core files - which usually don't happen to have a gnu_debuglink,
- // and are pretty bulky - calculating whole contents crc32 would be too much of luxury.
- // Thus we will need to fallback to something simpler.
- if (header.e_type == llvm::ELF::ET_CORE)
- {
- size_t program_headers_end = header.e_phoff + header.e_phnum * header.e_phentsize;
- if (program_headers_end > data_sp->GetByteSize())
- {
- data_sp = file.MemoryMapFileContentsIfLocal(file_offset, program_headers_end);
- data.SetData(data_sp);
- }
- ProgramHeaderColl program_headers;
- GetProgramHeaderInfo(program_headers, set_data, header);
-
- size_t segment_data_end = 0;
- for (ProgramHeaderCollConstIter I = program_headers.begin();
- I != program_headers.end(); ++I)
- {
- segment_data_end = std::max<unsigned long long> (I->p_offset + I->p_filesz, segment_data_end);
- }
-
- if (segment_data_end > data_sp->GetByteSize())
- {
- data_sp = file.MemoryMapFileContentsIfLocal(file_offset, segment_data_end);
- data.SetData(data_sp);
- }
-
- core_notes_crc = CalculateELFNotesSegmentsCRC32 (program_headers, data);
- }
- else
- {
- // Need to map entire file into memory to calculate the crc.
- data_sp = file.MemoryMapFileContentsIfLocal (file_offset, SIZE_MAX);
- data.SetData(data_sp);
- gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
- }
- }
- if (gnu_debuglink_crc)
- {
- // Use 4 bytes of crc from the .gnu_debuglink section.
- uint32_t uuidt[4] = { gnu_debuglink_crc, 0, 0, 0 };
- uuid.SetBytes (uuidt, sizeof(uuidt));
- }
- else if (core_notes_crc)
- {
- // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it look different form
- // .gnu_debuglink crc followed by 4 bytes of note segments crc.
- uint32_t uuidt[4] = { g_core_uuid_magic, core_notes_crc, 0, 0 };
- uuid.SetBytes (uuidt, sizeof(uuidt));
- }
- }
-
- specs.Append(spec);
+static bool GetOsFromOSABI(unsigned char osabi_byte,
+ llvm::Triple::OSType &ostype) {
+ switch (osabi_byte) {
+ case ELFOSABI_AIX:
+ ostype = llvm::Triple::OSType::AIX;
+ break;
+ case ELFOSABI_FREEBSD:
+ ostype = llvm::Triple::OSType::FreeBSD;
+ break;
+ case ELFOSABI_GNU:
+ ostype = llvm::Triple::OSType::Linux;
+ break;
+ case ELFOSABI_NETBSD:
+ ostype = llvm::Triple::OSType::NetBSD;
+ break;
+ case ELFOSABI_OPENBSD:
+ ostype = llvm::Triple::OSType::OpenBSD;
+ break;
+ case ELFOSABI_SOLARIS:
+ ostype = llvm::Triple::OSType::Solaris;
+ break;
+ default:
+ ostype = llvm::Triple::OSType::UnknownOS;
+ }
+ return ostype != llvm::Triple::OSType::UnknownOS;
+}
+
+size_t ObjectFileELF::GetModuleSpecifications(
+ const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, lldb::offset_t file_offset,
+ lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+
+ const size_t initial_count = specs.GetSize();
+
+ if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
+ DataExtractor data;
+ data.SetData(data_sp);
+ elf::ELFHeader header;
+ if (header.Parse(data, &data_offset)) {
+ if (data_sp) {
+ ModuleSpec spec(file);
+
+ const uint32_t sub_type = subTypeFromElfHeader(header);
+ spec.GetArchitecture().SetArchitecture(
+ eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]);
+
+ if (spec.GetArchitecture().IsValid()) {
+ llvm::Triple::OSType ostype;
+ llvm::Triple::VendorType vendor;
+ llvm::Triple::OSType spec_ostype =
+ spec.GetArchitecture().GetTriple().getOS();
+
+ if (log)
+ log->Printf("ObjectFileELF::%s file '%s' module OSABI: %s",
+ __FUNCTION__, file.GetPath().c_str(),
+ OSABIAsCString(header.e_ident[EI_OSABI]));
+
+ // SetArchitecture should have set the vendor to unknown
+ vendor = spec.GetArchitecture().GetTriple().getVendor();
+ assert(vendor == llvm::Triple::UnknownVendor);
+
+ //
+ // Validate it is ok to remove GetOsFromOSABI
+ GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
+ assert(spec_ostype == ostype);
+ if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
+ if (log)
+ log->Printf("ObjectFileELF::%s file '%s' set ELF module OS type "
+ "from ELF header OSABI.",
+ __FUNCTION__, file.GetPath().c_str());
+ }
+
+ // Try to get the UUID from the section list. Usually that's at the
+ // end, so
+ // map the file in if we don't have it already.
+ size_t section_header_end =
+ header.e_shoff + header.e_shnum * header.e_shentsize;
+ if (section_header_end > data_sp->GetByteSize()) {
+ data_sp = file.MemoryMapFileContentsIfLocal(file_offset,
+ section_header_end);
+ data.SetData(data_sp);
+ }
+
+ uint32_t gnu_debuglink_crc = 0;
+ std::string gnu_debuglink_file;
+ SectionHeaderColl section_headers;
+ lldb_private::UUID &uuid = spec.GetUUID();
+
+ using namespace std::placeholders;
+ const SetDataFunction set_data =
+ std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3);
+ GetSectionHeaderInfo(section_headers, set_data, header, uuid,
+ gnu_debuglink_file, gnu_debuglink_crc,
+ spec.GetArchitecture());
+
+ llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple();
+
+ if (log)
+ log->Printf("ObjectFileELF::%s file '%s' module set to triple: %s "
+ "(architecture %s)",
+ __FUNCTION__, file.GetPath().c_str(),
+ spec_triple.getTriple().c_str(),
+ spec.GetArchitecture().GetArchitectureName());
+
+ if (!uuid.IsValid()) {
+ uint32_t core_notes_crc = 0;
+
+ if (!gnu_debuglink_crc) {
+ lldb_private::Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "Calculating module crc32 %s with size %" PRIu64 " KiB",
+ file.GetLastPathComponent().AsCString(),
+ (file.GetByteSize() - file_offset) / 1024);
+
+ // For core files - which usually don't happen to have a
+ // gnu_debuglink,
+ // and are pretty bulky - calculating whole contents crc32 would
+ // be too much of luxury.
+ // Thus we will need to fallback to something simpler.
+ if (header.e_type == llvm::ELF::ET_CORE) {
+ size_t program_headers_end =
+ header.e_phoff + header.e_phnum * header.e_phentsize;
+ if (program_headers_end > data_sp->GetByteSize()) {
+ data_sp = file.MemoryMapFileContentsIfLocal(
+ file_offset, program_headers_end);
+ data.SetData(data_sp);
+ }
+ ProgramHeaderColl program_headers;
+ GetProgramHeaderInfo(program_headers, set_data, header);
+
+ size_t segment_data_end = 0;
+ for (ProgramHeaderCollConstIter I = program_headers.begin();
+ I != program_headers.end(); ++I) {
+ segment_data_end = std::max<unsigned long long>(
+ I->p_offset + I->p_filesz, segment_data_end);
}
+
+ if (segment_data_end > data_sp->GetByteSize()) {
+ data_sp = file.MemoryMapFileContentsIfLocal(file_offset,
+ segment_data_end);
+ data.SetData(data_sp);
+ }
+
+ core_notes_crc =
+ CalculateELFNotesSegmentsCRC32(program_headers, data);
+ } else {
+ // Need to map entire file into memory to calculate the crc.
+ data_sp =
+ file.MemoryMapFileContentsIfLocal(file_offset, SIZE_MAX);
+ data.SetData(data_sp);
+ gnu_debuglink_crc = calc_gnu_debuglink_crc32(
+ data.GetDataStart(), data.GetByteSize());
+ }
}
+ if (gnu_debuglink_crc) {
+ // Use 4 bytes of crc from the .gnu_debuglink section.
+ uint32_t uuidt[4] = {gnu_debuglink_crc, 0, 0, 0};
+ uuid.SetBytes(uuidt, sizeof(uuidt));
+ } else if (core_notes_crc) {
+ // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make
+ // it look different form
+ // .gnu_debuglink crc followed by 4 bytes of note segments crc.
+ uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0};
+ uuid.SetBytes(uuidt, sizeof(uuidt));
+ }
+ }
+
+ specs.Append(spec);
}
+ }
}
+ }
- return specs.GetSize() - initial_count;
+ return specs.GetSize() - initial_count;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ObjectFileELF::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ObjectFileELF::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ObjectFileELF::GetPluginVersion()
-{
- return m_plugin_version;
-}
+uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; }
//------------------------------------------------------------------
// ObjectFile protocol
//------------------------------------------------------------------
-ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length) :
- ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_header(),
- m_uuid(),
- m_gnu_debuglink_file(),
- m_gnu_debuglink_crc(0),
- m_program_headers(),
- m_section_headers(),
- m_dynamic_symbols(),
- m_filespec_ap(),
- m_entry_point_address(),
- m_arch_spec()
-{
- if (file)
- m_file = *file;
- ::memset(&m_header, 0, sizeof(m_header));
-}
-
-ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
- DataBufferSP& header_data_sp,
- const lldb::ProcessSP &process_sp,
- addr_t header_addr) :
- ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_header(),
- m_uuid(),
- m_gnu_debuglink_file(),
- m_gnu_debuglink_crc(0),
- m_program_headers(),
- m_section_headers(),
- m_dynamic_symbols(),
- m_filespec_ap(),
- m_entry_point_address(),
- m_arch_spec()
-{
- ::memset(&m_header, 0, sizeof(m_header));
-}
-
-ObjectFileELF::~ObjectFileELF()
-{
-}
-
-bool
-ObjectFileELF::IsExecutable() const
-{
- return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
-}
-
-bool
-ObjectFileELF::SetLoadAddress (Target &target,
- lldb::addr_t value,
- bool value_is_offset)
-{
- ModuleSP module_sp = GetModule();
- if (module_sp)
- {
- size_t num_loaded_sections = 0;
- SectionList *section_list = GetSectionList ();
- if (section_list)
- {
- if (!value_is_offset)
- {
- bool found_offset = false;
- for (size_t i = 0, 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)
- return false;
- }
+ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
+ DataBufferSP &data_sp, lldb::offset_t data_offset,
+ const FileSpec *file, lldb::offset_t file_offset,
+ lldb::offset_t length)
+ : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
+ m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
+ m_program_headers(), m_section_headers(), m_dynamic_symbols(),
+ m_filespec_ap(), m_entry_point_address(), m_arch_spec() {
+ if (file)
+ m_file = *file;
+ ::memset(&m_header, 0, sizeof(m_header));
+}
+
+ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
+ DataBufferSP &header_data_sp,
+ const lldb::ProcessSP &process_sp,
+ addr_t header_addr)
+ : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
+ m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
+ m_program_headers(), m_section_headers(), m_dynamic_symbols(),
+ m_filespec_ap(), m_entry_point_address(), m_arch_spec() {
+ ::memset(&m_header, 0, sizeof(m_header));
+}
+
+ObjectFileELF::~ObjectFileELF() {}
+
+bool ObjectFileELF::IsExecutable() const {
+ return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
+}
+
+bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
+ bool value_is_offset) {
+ ModuleSP module_sp = GetModule();
+ if (module_sp) {
+ size_t num_loaded_sections = 0;
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ if (!value_is_offset) {
+ bool found_offset = false;
+ for (size_t i = 0, count = GetProgramHeaderCount(); i < count; ++i) {
+ const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i);
+ if (header == nullptr)
+ continue;
- const size_t num_sections = section_list->GetSize();
- size_t sect_idx = 0;
-
- for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
- {
- // Iterate through the object file sections to find all
- // of the sections that have SHF_ALLOC in their flag bits.
- SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- if (section_sp && section_sp->Test(SHF_ALLOC))
- {
- lldb::addr_t load_addr = section_sp->GetFileAddress();
- // We don't want to update the load address of a section with type
- // eSectionTypeAbsoluteAddress as they already have the absolute load address
- // already specified
- if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
- load_addr += value;
-
- // On 32-bit systems the load address have to fit into 4 bytes. The rest of
- // the bytes are the overflow from the addition.
- if (GetAddressByteSize() == 4)
- load_addr &= 0xFFFFFFFF;
-
- if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
- ++num_loaded_sections;
- }
- }
- return num_loaded_sections > 0;
+ if (header->p_type != PT_LOAD || header->p_offset != 0)
+ continue;
+
+ value = value - header->p_vaddr;
+ found_offset = true;
+ break;
+ }
+ if (!found_offset)
+ return false;
+ }
+
+ const size_t num_sections = section_list->GetSize();
+ size_t sect_idx = 0;
+
+ for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ // Iterate through the object file sections to find all
+ // of the sections that have SHF_ALLOC in their flag bits.
+ SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+ if (section_sp && section_sp->Test(SHF_ALLOC)) {
+ lldb::addr_t load_addr = section_sp->GetFileAddress();
+ // We don't want to update the load address of a section with type
+ // eSectionTypeAbsoluteAddress as they already have the absolute load
+ // address
+ // already specified
+ if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
+ load_addr += value;
+
+ // On 32-bit systems the load address have to fit into 4 bytes. The
+ // rest of
+ // the bytes are the overflow from the addition.
+ if (GetAddressByteSize() == 4)
+ load_addr &= 0xFFFFFFFF;
+
+ if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp,
+ load_addr))
+ ++num_loaded_sections;
}
+ }
+ return num_loaded_sections > 0;
}
- return false;
+ }
+ return false;
}
-ByteOrder
-ObjectFileELF::GetByteOrder() const
-{
- if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
- return eByteOrderBig;
- if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
- return eByteOrderLittle;
- return eByteOrderInvalid;
-}
-
-uint32_t
-ObjectFileELF::GetAddressByteSize() const
-{
- return m_data.GetAddressByteSize();
-}
-
-AddressClass
-ObjectFileELF::GetAddressClass (addr_t file_addr)
-{
- Symtab* symtab = GetSymtab();
- if (!symtab)
- return eAddressClassUnknown;
-
- // The address class is determined based on the symtab. Ask it from the object file what
- // contains the symtab information.
- ObjectFile* symtab_objfile = symtab->GetObjectFile();
- if (symtab_objfile != nullptr && symtab_objfile != this)
- return symtab_objfile->GetAddressClass(file_addr);
-
- auto res = ObjectFile::GetAddressClass (file_addr);
- if (res != eAddressClassCode)
- return res;
-
- auto ub = m_address_class_map.upper_bound(file_addr);
- if (ub == m_address_class_map.begin())
- {
- // No entry in the address class map before the address. Return
- // default address class for an address in a code section.
- return eAddressClassCode;
- }
+ByteOrder ObjectFileELF::GetByteOrder() const {
+ if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
+ return eByteOrderBig;
+ if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
+ return eByteOrderLittle;
+ return eByteOrderInvalid;
+}
+
+uint32_t ObjectFileELF::GetAddressByteSize() const {
+ return m_data.GetAddressByteSize();
+}
+
+AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
+ Symtab *symtab = GetSymtab();
+ if (!symtab)
+ return eAddressClassUnknown;
+
+ // The address class is determined based on the symtab. Ask it from the object
+ // file what
+ // contains the symtab information.
+ ObjectFile *symtab_objfile = symtab->GetObjectFile();
+ if (symtab_objfile != nullptr && symtab_objfile != this)
+ return symtab_objfile->GetAddressClass(file_addr);
+
+ auto res = ObjectFile::GetAddressClass(file_addr);
+ if (res != eAddressClassCode)
+ return res;
+
+ auto ub = m_address_class_map.upper_bound(file_addr);
+ if (ub == m_address_class_map.begin()) {
+ // No entry in the address class map before the address. Return
+ // default address class for an address in a code section.
+ return eAddressClassCode;
+ }
- // Move iterator to the address class entry preceding address
- --ub;
+ // Move iterator to the address class entry preceding address
+ --ub;
- return ub->second;
+ return ub->second;
}
-size_t
-ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
-{
- return std::distance(m_section_headers.begin(), I) + 1u;
+size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) {
+ return std::distance(m_section_headers.begin(), I) + 1u;
}
-size_t
-ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
-{
- return std::distance(m_section_headers.begin(), I) + 1u;
+size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const {
+ return std::distance(m_section_headers.begin(), I) + 1u;
}
-bool
-ObjectFileELF::ParseHeader()
-{
- lldb::offset_t offset = 0;
- if (!m_header.Parse(m_data, &offset))
- return false;
-
- if (!IsInMemory())
- return true;
-
- // For in memory object files m_data might not contain the full object file. Try to load it
- // until the end of the "Section header table" what is at the end of the ELF file.
- addr_t file_size = m_header.e_shoff + m_header.e_shnum * m_header.e_shentsize;
- if (m_data.GetByteSize() < file_size)
- {
- ProcessSP process_sp (m_process_wp.lock());
- if (!process_sp)
- return false;
-
- DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size);
- if (!data_sp)
- return false;
- m_data.SetData(data_sp, 0, file_size);
- }
+bool ObjectFileELF::ParseHeader() {
+ lldb::offset_t offset = 0;
+ if (!m_header.Parse(m_data, &offset))
+ return false;
+ if (!IsInMemory())
return true;
+
+ // For in memory object files m_data might not contain the full object file.
+ // Try to load it
+ // until the end of the "Section header table" what is at the end of the ELF
+ // file.
+ addr_t file_size = m_header.e_shoff + m_header.e_shnum * m_header.e_shentsize;
+ if (m_data.GetByteSize() < file_size) {
+ ProcessSP process_sp(m_process_wp.lock());
+ if (!process_sp)
+ return false;
+
+ DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size);
+ if (!data_sp)
+ return false;
+ m_data.SetData(data_sp, 0, file_size);
+ }
+
+ return true;
}
-bool
-ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
-{
- // Need to parse the section list to get the UUIDs, so make sure that's been done.
- if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
- return false;
+bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) {
+ // Need to parse the section list to get the UUIDs, so make sure that's been
+ // done.
+ if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
+ return false;
- if (m_uuid.IsValid())
- {
- // We have the full build id uuid.
- *uuid = m_uuid;
- return true;
- }
- else if (GetType() == ObjectFile::eTypeCoreFile)
- {
- uint32_t core_notes_crc = 0;
-
- if (!ParseProgramHeaders())
- return false;
-
- core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
-
- if (core_notes_crc)
- {
- // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
- // look different form .gnu_debuglink crc - followed by 4 bytes of note
- // segments crc.
- uint32_t uuidt[4] = { g_core_uuid_magic, core_notes_crc, 0, 0 };
- m_uuid.SetBytes (uuidt, sizeof(uuidt));
- }
- }
- else
- {
- if (!m_gnu_debuglink_crc)
- m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
- if (m_gnu_debuglink_crc)
- {
- // Use 4 bytes of crc from the .gnu_debuglink section.
- uint32_t uuidt[4] = { m_gnu_debuglink_crc, 0, 0, 0 };
- m_uuid.SetBytes (uuidt, sizeof(uuidt));
- }
- }
+ if (m_uuid.IsValid()) {
+ // We have the full build id uuid.
+ *uuid = m_uuid;
+ return true;
+ } else if (GetType() == ObjectFile::eTypeCoreFile) {
+ uint32_t core_notes_crc = 0;
- if (m_uuid.IsValid())
- {
- *uuid = m_uuid;
- return true;
- }
+ if (!ParseProgramHeaders())
+ return false;
+
+ core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
+
+ if (core_notes_crc) {
+ // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
+ // look different form .gnu_debuglink crc - followed by 4 bytes of note
+ // segments crc.
+ uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0};
+ m_uuid.SetBytes(uuidt, sizeof(uuidt));
+ }
+ } else {
+ if (!m_gnu_debuglink_crc)
+ m_gnu_debuglink_crc =
+ calc_gnu_debuglink_crc32(m_data.GetDataStart(), m_data.GetByteSize());
+ if (m_gnu_debuglink_crc) {
+ // Use 4 bytes of crc from the .gnu_debuglink section.
+ uint32_t uuidt[4] = {m_gnu_debuglink_crc, 0, 0, 0};
+ m_uuid.SetBytes(uuidt, sizeof(uuidt));
+ }
+ }
+
+ if (m_uuid.IsValid()) {
+ *uuid = m_uuid;
+ return true;
+ }
- return false;
+ return false;
}
-lldb_private::FileSpecList
-ObjectFileELF::GetDebugSymbolFilePaths()
-{
- FileSpecList file_spec_list;
+lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() {
+ FileSpecList file_spec_list;
- if (!m_gnu_debuglink_file.empty())
- {
- FileSpec file_spec (m_gnu_debuglink_file.c_str(), false);
- file_spec_list.Append (file_spec);
- }
- return file_spec_list;
+ if (!m_gnu_debuglink_file.empty()) {
+ FileSpec file_spec(m_gnu_debuglink_file, false);
+ file_spec_list.Append(file_spec);
+ }
+ return file_spec_list;
}
-uint32_t
-ObjectFileELF::GetDependentModules(FileSpecList &files)
-{
- size_t num_modules = ParseDependentModules();
- uint32_t num_specs = 0;
+uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
+ size_t num_modules = ParseDependentModules();
+ uint32_t num_specs = 0;
- for (unsigned i = 0; i < num_modules; ++i)
- {
- if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
- num_specs++;
- }
+ for (unsigned i = 0; i < num_modules; ++i) {
+ if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
+ num_specs++;
+ }
- return num_specs;
+ return num_specs;
}
-Address
-ObjectFileELF::GetImageInfoAddress(Target *target)
-{
- if (!ParseDynamicSymbols())
- return Address();
+Address ObjectFileELF::GetImageInfoAddress(Target *target) {
+ if (!ParseDynamicSymbols())
+ return Address();
- SectionList *section_list = GetSectionList();
- if (!section_list)
- return Address();
+ SectionList *section_list = GetSectionList();
+ if (!section_list)
+ return Address();
- // Find the SHT_DYNAMIC (.dynamic) section.
- SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
- if (!dynsym_section_sp)
- return Address();
- assert (dynsym_section_sp->GetObjectFile() == this);
+ // Find the SHT_DYNAMIC (.dynamic) section.
+ SectionSP dynsym_section_sp(
+ section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true));
+ if (!dynsym_section_sp)
+ return Address();
+ assert(dynsym_section_sp->GetObjectFile() == this);
- user_id_t dynsym_id = dynsym_section_sp->GetID();
- const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
- if (!dynsym_hdr)
- return Address();
+ user_id_t dynsym_id = dynsym_section_sp->GetID();
+ const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
+ if (!dynsym_hdr)
+ return Address();
- for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
- {
- ELFDynamic &symbol = m_dynamic_symbols[i];
+ for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) {
+ ELFDynamic &symbol = m_dynamic_symbols[i];
+
+ if (symbol.d_tag == DT_DEBUG) {
+ // Compute the offset as the number of previous entries plus the
+ // size of d_tag.
+ addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
+ return Address(dynsym_section_sp, offset);
+ }
+ // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP
+ // exists in non-PIE.
+ else if ((symbol.d_tag == DT_MIPS_RLD_MAP ||
+ symbol.d_tag == DT_MIPS_RLD_MAP_REL) &&
+ target) {
+ addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
+ addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
+ if (dyn_base == LLDB_INVALID_ADDRESS)
+ return Address();
- if (symbol.d_tag == DT_DEBUG)
- {
- // Compute the offset as the number of previous entries plus the
- // size of d_tag.
- addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
- return Address(dynsym_section_sp, offset);
- }
- // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP exists in non-PIE.
- else if ((symbol.d_tag == DT_MIPS_RLD_MAP || symbol.d_tag == DT_MIPS_RLD_MAP_REL) && target)
- {
- addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
- addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
- if (dyn_base == LLDB_INVALID_ADDRESS)
- return Address();
-
- Error error;
- if (symbol.d_tag == DT_MIPS_RLD_MAP)
- {
- // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
- Address addr;
- if (target->ReadPointerFromMemory(dyn_base + offset, false, error, addr))
- return addr;
- }
- if (symbol.d_tag == DT_MIPS_RLD_MAP_REL)
- {
- // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer, relative to the address of the tag.
- uint64_t rel_offset;
- rel_offset = target->ReadUnsignedIntegerFromMemory(dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
- if (error.Success() && rel_offset != UINT64_MAX)
- {
- Address addr;
- addr_t debug_ptr_address = dyn_base + (offset - GetAddressByteSize()) + rel_offset;
- addr.SetOffset (debug_ptr_address);
- return addr;
- }
- }
+ Error error;
+ if (symbol.d_tag == DT_MIPS_RLD_MAP) {
+ // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
+ Address addr;
+ if (target->ReadPointerFromMemory(dyn_base + offset, false, error,
+ addr))
+ return addr;
+ }
+ if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
+ // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
+ // relative to the address of the tag.
+ uint64_t rel_offset;
+ rel_offset = target->ReadUnsignedIntegerFromMemory(
+ dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
+ if (error.Success() && rel_offset != UINT64_MAX) {
+ Address addr;
+ addr_t debug_ptr_address =
+ dyn_base + (offset - GetAddressByteSize()) + rel_offset;
+ addr.SetOffset(debug_ptr_address);
+ return addr;
}
+ }
}
+ }
- return Address();
+ return Address();
}
-lldb_private::Address
-ObjectFileELF::GetEntryPointAddress ()
-{
- if (m_entry_point_address.IsValid())
- return m_entry_point_address;
+lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
+ if (m_entry_point_address.IsValid())
+ return m_entry_point_address;
- if (!ParseHeader() || !IsExecutable())
- return m_entry_point_address;
+ if (!ParseHeader() || !IsExecutable())
+ return m_entry_point_address;
- SectionList *section_list = GetSectionList();
- addr_t offset = m_header.e_entry;
+ SectionList *section_list = GetSectionList();
+ addr_t offset = m_header.e_entry;
- if (!section_list)
- m_entry_point_address.SetOffset(offset);
- else
- m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
- return m_entry_point_address;
+ if (!section_list)
+ m_entry_point_address.SetOffset(offset);
+ else
+ m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
+ return m_entry_point_address;
}
//----------------------------------------------------------------------
// ParseDependentModules
//----------------------------------------------------------------------
-size_t
-ObjectFileELF::ParseDependentModules()
-{
- if (m_filespec_ap.get())
- return m_filespec_ap->GetSize();
+size_t ObjectFileELF::ParseDependentModules() {
+ if (m_filespec_ap.get())
+ return m_filespec_ap->GetSize();
- m_filespec_ap.reset(new FileSpecList());
+ m_filespec_ap.reset(new FileSpecList());
- if (!ParseSectionHeaders())
- return 0;
+ if (!ParseSectionHeaders())
+ return 0;
- SectionList *section_list = GetSectionList();
- if (!section_list)
- return 0;
-
- // Find the SHT_DYNAMIC section.
- Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
- if (!dynsym)
- return 0;
- assert (dynsym->GetObjectFile() == this);
-
- const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
- if (!header)
- 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();
- if (!dynstr)
- return 0;
-
- DataExtractor dynsym_data;
- DataExtractor dynstr_data;
- if (ReadSectionData(dynsym, dynsym_data) &&
- ReadSectionData(dynstr, dynstr_data))
- {
- ELFDynamic symbol;
- const lldb::offset_t section_size = dynsym_data.GetByteSize();
- lldb::offset_t offset = 0;
-
- // The only type of entries we are concerned with are tagged DT_NEEDED,
- // yielding the name of a required library.
- while (offset < section_size)
- {
- if (!symbol.Parse(dynsym_data, &offset))
- break;
+ SectionList *section_list = GetSectionList();
+ if (!section_list)
+ return 0;
- if (symbol.d_tag != DT_NEEDED)
- continue;
+ // Find the SHT_DYNAMIC section.
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
+ .get();
+ if (!dynsym)
+ return 0;
+ assert(dynsym->GetObjectFile() == this);
- 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));
- }
+ const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID());
+ if (!header)
+ 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();
+ if (!dynstr)
+ return 0;
+
+ DataExtractor dynsym_data;
+ DataExtractor dynstr_data;
+ if (ReadSectionData(dynsym, dynsym_data) &&
+ ReadSectionData(dynstr, dynstr_data)) {
+ ELFDynamic symbol;
+ const lldb::offset_t section_size = dynsym_data.GetByteSize();
+ lldb::offset_t offset = 0;
+
+ // The only type of entries we are concerned with are tagged DT_NEEDED,
+ // yielding the name of a required library.
+ while (offset < section_size) {
+ if (!symbol.Parse(dynsym_data, &offset))
+ break;
+
+ if (symbol.d_tag != DT_NEEDED)
+ continue;
+
+ 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));
}
+ }
- return m_filespec_ap->GetSize();
+ return m_filespec_ap->GetSize();
}
//----------------------------------------------------------------------
// GetProgramHeaderInfo
//----------------------------------------------------------------------
-size_t
-ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
- const SetDataFunction &set_data,
- const ELFHeader &header)
-{
- // We have already parsed the program headers
- if (!program_headers.empty())
- return program_headers.size();
-
- // If there are no program headers to read we are done.
- if (header.e_phnum == 0)
- return 0;
-
- program_headers.resize(header.e_phnum);
- if (program_headers.size() != header.e_phnum)
- return 0;
-
- const size_t ph_size = header.e_phnum * header.e_phentsize;
- const elf_off ph_offset = header.e_phoff;
- DataExtractor data;
- if (set_data(data, ph_offset, ph_size) != ph_size)
- return 0;
-
- 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)
- break;
- }
+size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
+ const SetDataFunction &set_data,
+ const ELFHeader &header) {
+ // We have already parsed the program headers
+ if (!program_headers.empty())
+ return program_headers.size();
- if (idx < program_headers.size())
- program_headers.resize(idx);
+ // If there are no program headers to read we are done.
+ if (header.e_phnum == 0)
+ return 0;
- return program_headers.size();
+ program_headers.resize(header.e_phnum);
+ if (program_headers.size() != header.e_phnum)
+ return 0;
+
+ const size_t ph_size = header.e_phnum * header.e_phentsize;
+ const elf_off ph_offset = header.e_phoff;
+ DataExtractor data;
+ if (set_data(data, ph_offset, ph_size) != ph_size)
+ return 0;
+
+ 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)
+ break;
+ }
+ if (idx < program_headers.size())
+ program_headers.resize(idx);
+
+ return program_headers.size();
}
//----------------------------------------------------------------------
// ParseProgramHeaders
//----------------------------------------------------------------------
-size_t
-ObjectFileELF::ParseProgramHeaders()
-{
- using namespace std::placeholders;
- return GetProgramHeaderInfo(m_program_headers,
- std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3),
- m_header);
+size_t ObjectFileELF::ParseProgramHeaders() {
+ using namespace std::placeholders;
+ return GetProgramHeaderInfo(
+ m_program_headers,
+ std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2,
+ _3),
+ m_header);
}
lldb_private::Error
-ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES));
- Error error;
+ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
+ lldb_private::ArchSpec &arch_spec,
+ lldb_private::UUID &uuid) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ Error error;
+
+ lldb::offset_t offset = 0;
+
+ while (true) {
+ // Parse the note header. If this fails, bail out.
+ const lldb::offset_t note_offset = offset;
+ ELFNote note = ELFNote();
+ if (!note.Parse(data, &offset)) {
+ // We're done.
+ return error;
+ }
+
+ if (log)
+ log->Printf("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
+ __FUNCTION__, note.n_name.c_str(), note.n_type);
+
+ // Process FreeBSD ELF notes.
+ if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
+ (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&
+ (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) {
+ // Pull out the min version info.
+ uint32_t version_info;
+ if (data.GetU32(&offset, &version_info, 1) == nullptr) {
+ error.SetErrorString("failed to read FreeBSD ABI note payload");
+ return error;
+ }
+
+ // Convert the version info into a major/minor number.
+ const uint32_t version_major = version_info / 100000;
+ const uint32_t version_minor = (version_info / 1000) % 100;
+
+ char os_name[32];
+ snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32 ".%" PRIu32,
+ version_major, version_minor);
+
+ // Set the elf OS version to FreeBSD. Also clear the vendor.
+ arch_spec.GetTriple().setOSName(os_name);
+ arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
+
+ if (log)
+ log->Printf("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
+ ".%" PRIu32,
+ __FUNCTION__, version_major, version_minor,
+ static_cast<uint32_t>(version_info % 1000));
+ }
+ // Process GNU ELF notes.
+ else if (note.n_name == LLDB_NT_OWNER_GNU) {
+ switch (note.n_type) {
+ case LLDB_NT_GNU_ABI_TAG:
+ if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) {
+ // Pull out the min OS version supporting the ABI.
+ uint32_t version_info[4];
+ if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) ==
+ nullptr) {
+ error.SetErrorString("failed to read GNU ABI note payload");
+ return error;
+ }
- lldb::offset_t offset = 0;
+ // Set the OS per the OS field.
+ switch (version_info[0]) {
+ case LLDB_NT_GNU_ABI_OS_LINUX:
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
+ arch_spec.GetTriple().setVendor(
+ llvm::Triple::VendorType::UnknownVendor);
+ if (log)
+ log->Printf(
+ "ObjectFileELF::%s detected Linux, min version %" PRIu32
+ ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
+ // FIXME we have the minimal version number, we could be propagating
+ // that. version_info[1] = OS Major, version_info[2] = OS Minor,
+ // version_info[3] = Revision.
+ break;
+ case LLDB_NT_GNU_ABI_OS_HURD:
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
+ arch_spec.GetTriple().setVendor(
+ llvm::Triple::VendorType::UnknownVendor);
+ if (log)
+ log->Printf("ObjectFileELF::%s detected Hurd (unsupported), min "
+ "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
+ break;
+ case LLDB_NT_GNU_ABI_OS_SOLARIS:
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris);
+ arch_spec.GetTriple().setVendor(
+ llvm::Triple::VendorType::UnknownVendor);
+ if (log)
+ log->Printf(
+ "ObjectFileELF::%s detected Solaris, min version %" PRIu32
+ ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
+ break;
+ default:
+ if (log)
+ log->Printf(
+ "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
+ ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[0], version_info[1],
+ version_info[2], version_info[3]);
+ break;
+ }
+ }
+ break;
+
+ case LLDB_NT_GNU_BUILD_ID_TAG:
+ // Only bother processing this if we don't already have the uuid set.
+ if (!uuid.IsValid()) {
+ // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a
+ // build-id of a different
+ // length. Accept it as long as it's at least 4 bytes as it will be
+ // better than our own crc32.
+ if (note.n_descsz >= 4 && note.n_descsz <= 20) {
+ uint8_t uuidbuf[20];
+ if (data.GetU8(&offset, &uuidbuf, note.n_descsz) == nullptr) {
+ error.SetErrorString("failed to read GNU_BUILD_ID note payload");
+ return error;
+ }
- while (true)
- {
- // Parse the note header. If this fails, bail out.
- const lldb::offset_t note_offset = offset;
- ELFNote note = ELFNote();
- if (!note.Parse(data, &offset))
- {
- // We're done.
+ // Save the build id as the UUID for the module.
+ uuid.SetBytes(uuidbuf, note.n_descsz);
+ }
+ }
+ break;
+ }
+ }
+ // Process NetBSD ELF notes.
+ else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
+ (note.n_type == LLDB_NT_NETBSD_ABI_TAG) &&
+ (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE)) {
+ // Pull out the min version info.
+ uint32_t version_info;
+ if (data.GetU32(&offset, &version_info, 1) == nullptr) {
+ error.SetErrorString("failed to read NetBSD ABI note payload");
+ return error;
+ }
+
+ // Set the elf OS version to NetBSD. Also clear the vendor.
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD);
+ arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
+
+ if (log)
+ log->Printf(
+ "ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32,
+ __FUNCTION__, version_info);
+ }
+ // Process CSR kalimba notes
+ else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) &&
+ (note.n_name == LLDB_NT_OWNER_CSR)) {
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
+ arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR);
+
+ // TODO At some point the description string could be processed.
+ // It could provide a steer towards the kalimba variant which
+ // this ELF targets.
+ if (note.n_descsz) {
+ const char *cstr =
+ data.GetCStr(&offset, llvm::alignTo(note.n_descsz, 4));
+ (void)cstr;
+ }
+ } else if (note.n_name == LLDB_NT_OWNER_ANDROID) {
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
+ arch_spec.GetTriple().setEnvironment(
+ llvm::Triple::EnvironmentType::Android);
+ } else if (note.n_name == LLDB_NT_OWNER_LINUX) {
+ // This is sometimes found in core files and usually contains extended
+ // register info
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
+ } else if (note.n_name == LLDB_NT_OWNER_CORE) {
+ // Parse the NT_FILE to look for stuff in paths to shared libraries
+ // As the contents look like this in a 64 bit ELF core file:
+ // count = 0x000000000000000a (10)
+ // page_size = 0x0000000000001000 (4096)
+ // Index start end file_ofs path
+ // ===== ------------------ ------------------ ------------------
+ // -------------------------------------
+ // [ 0] 0x0000000000400000 0x0000000000401000 0x0000000000000000
+ // /tmp/a.out
+ // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000
+ // /tmp/a.out
+ // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001
+ // /tmp/a.out
+ // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000
+ // /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb
+ // /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba
+ // /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be
+ // /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000
+ // /lib/x86_64-linux-gnu/ld-2.19.so
+ // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022
+ // /lib/x86_64-linux-gnu/ld-2.19.so
+ // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023
+ // /lib/x86_64-linux-gnu/ld-2.19.so
+ // In the 32 bit ELFs the count, page_size, start, end, file_ofs are
+ // uint32_t
+ // For reference: see readelf source code (in binutils).
+ if (note.n_type == NT_FILE) {
+ uint64_t count = data.GetAddress(&offset);
+ const char *cstr;
+ data.GetAddress(&offset); // Skip page size
+ offset += count * 3 *
+ data.GetAddressByteSize(); // Skip all start/end/file_ofs
+ for (size_t i = 0; i < count; ++i) {
+ cstr = data.GetCStr(&offset);
+ if (cstr == nullptr) {
+ error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read "
+ "at an offset after the end "
+ "(GetCStr returned nullptr)",
+ __FUNCTION__);
return error;
+ }
+ llvm::StringRef path(cstr);
+ if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
+ break;
+ }
}
+ }
+ }
- if (log)
- log->Printf ("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, __FUNCTION__, note.n_name.c_str (), note.n_type);
-
- // Process FreeBSD ELF notes.
- if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
- (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&
- (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE))
- {
- // Pull out the min version info.
- uint32_t version_info;
- if (data.GetU32 (&offset, &version_info, 1) == nullptr)
- {
- error.SetErrorString ("failed to read FreeBSD ABI note payload");
- return error;
- }
+ // Calculate the offset of the next note just in case "offset" has been used
+ // to poke at the contents of the note data
+ offset = note_offset + note.GetByteSize();
+ }
- // Convert the version info into a major/minor number.
- const uint32_t version_major = version_info / 100000;
- const uint32_t version_minor = (version_info / 1000) % 100;
+ return error;
+}
- char os_name[32];
- snprintf (os_name, sizeof (os_name), "freebsd%" PRIu32 ".%" PRIu32, version_major, version_minor);
+void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
+ ArchSpec &arch_spec) {
+ lldb::offset_t Offset = 0;
- // Set the elf OS version to FreeBSD. Also clear the vendor.
- arch_spec.GetTriple ().setOSName (os_name);
- arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
+ uint8_t FormatVersion = data.GetU8(&Offset);
+ if (FormatVersion != llvm::ARMBuildAttrs::Format_Version)
+ return;
- if (log)
- log->Printf ("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_major, version_minor, static_cast<uint32_t> (version_info % 1000));
- }
- // Process GNU ELF notes.
- else if (note.n_name == LLDB_NT_OWNER_GNU)
- {
- switch (note.n_type)
- {
- case LLDB_NT_GNU_ABI_TAG:
- if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE)
- {
- // Pull out the min OS version supporting the ABI.
- uint32_t version_info[4];
- if (data.GetU32 (&offset, &version_info[0], note.n_descsz / 4) == nullptr)
- {
- error.SetErrorString ("failed to read GNU ABI note payload");
- return error;
- }
-
- // Set the OS per the OS field.
- switch (version_info[0])
- {
- case LLDB_NT_GNU_ABI_OS_LINUX:
- arch_spec.GetTriple ().setOS (llvm::Triple::OSType::Linux);
- arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf ("ObjectFileELF::%s detected Linux, min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]);
- // FIXME we have the minimal version number, we could be propagating that. version_info[1] = OS Major, version_info[2] = OS Minor, version_info[3] = Revision.
- break;
- case LLDB_NT_GNU_ABI_OS_HURD:
- arch_spec.GetTriple ().setOS (llvm::Triple::OSType::UnknownOS);
- arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf ("ObjectFileELF::%s detected Hurd (unsupported), min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]);
- break;
- case LLDB_NT_GNU_ABI_OS_SOLARIS:
- arch_spec.GetTriple ().setOS (llvm::Triple::OSType::Solaris);
- arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf ("ObjectFileELF::%s detected Solaris, min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]);
- break;
- default:
- if (log)
- log->Printf ("ObjectFileELF::%s unrecognized OS in note, id %" PRIu32 ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[0], version_info[1], version_info[2], version_info[3]);
- break;
- }
- }
- break;
-
- case LLDB_NT_GNU_BUILD_ID_TAG:
- // Only bother processing this if we don't already have the uuid set.
- if (!uuid.IsValid())
- {
- // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a build-id of a different
- // length. Accept it as long as it's at least 4 bytes as it will be better than our own crc32.
- if (note.n_descsz >= 4 && note.n_descsz <= 20)
- {
- uint8_t uuidbuf[20];
- if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == nullptr)
- {
- error.SetErrorString ("failed to read GNU_BUILD_ID note payload");
- return error;
- }
-
- // Save the build id as the UUID for the module.
- uuid.SetBytes (uuidbuf, note.n_descsz);
- }
- }
- break;
- }
- }
- // Process NetBSD ELF notes.
- else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
- (note.n_type == LLDB_NT_NETBSD_ABI_TAG) &&
- (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE))
- {
- // Pull out the min version info.
- uint32_t version_info;
- if (data.GetU32 (&offset, &version_info, 1) == nullptr)
- {
- error.SetErrorString ("failed to read NetBSD ABI note payload");
- return error;
- }
+ Offset = Offset + sizeof(uint32_t); // Section Length
+ llvm::StringRef VendorName = data.GetCStr(&Offset);
- // Set the elf OS version to NetBSD. Also clear the vendor.
- arch_spec.GetTriple ().setOS (llvm::Triple::OSType::NetBSD);
- arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
+ if (VendorName != "aeabi")
+ return;
- if (log)
- log->Printf ("ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32, __FUNCTION__, version_info);
- }
- // Process CSR kalimba notes
- else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) &&
- (note.n_name == LLDB_NT_OWNER_CSR))
- {
- arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
- arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR);
-
- // TODO At some point the description string could be processed.
- // It could provide a steer towards the kalimba variant which
- // this ELF targets.
- if(note.n_descsz)
- {
- const char *cstr = data.GetCStr(&offset, llvm::alignTo (note.n_descsz, 4));
- (void)cstr;
- }
- }
- else if (note.n_name == LLDB_NT_OWNER_ANDROID)
- {
- arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
- arch_spec.GetTriple().setEnvironment(llvm::Triple::EnvironmentType::Android);
- }
- else if (note.n_name == LLDB_NT_OWNER_LINUX)
- {
- // This is sometimes found in core files and usually contains extended register info
- arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
- }
- else if (note.n_name == LLDB_NT_OWNER_CORE)
- {
- // Parse the NT_FILE to look for stuff in paths to shared libraries
- // As the contents look like:
- // count = 0x000000000000000a (10)
- // page_size = 0x0000000000001000 (4096)
- // Index start end file_ofs path
- // ===== ------------------ ------------------ ------------------ -------------------------------------
- // [ 0] 0x0000000000400000 0x0000000000401000 0x0000000000000000 /tmp/a.out
- // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out
- // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
- // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
- // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so
- // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
- if (note.n_type == NT_FILE)
- {
- uint64_t count = data.GetU64(&offset);
- offset += 8 + 3*8*count; // Skip page size and all start/end/file_ofs
- for (size_t i=0; i<count; ++i)
- {
- llvm::StringRef path(data.GetCStr(&offset));
- if (path.startswith("/lib/x86_64-linux-gnu"))
- {
- arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
- break;
- }
- }
- }
- }
+ if (arch_spec.GetTriple().getEnvironment() ==
+ llvm::Triple::UnknownEnvironment)
+ arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
- // Calculate the offset of the next note just in case "offset" has been used
- // to poke at the contents of the note data
- offset = note_offset + note.GetByteSize();
- }
+ while (Offset < length) {
+ uint8_t Tag = data.GetU8(&Offset);
+ uint32_t Size = data.GetU32(&Offset);
- return error;
-}
+ if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
+ continue;
-void
-ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, ArchSpec &arch_spec)
-{
- lldb::offset_t Offset = 0;
+ while (Offset < length) {
+ uint64_t Tag = data.GetULEB128(&Offset);
+ switch (Tag) {
+ default:
+ if (Tag < 32)
+ data.GetULEB128(&Offset);
+ else if (Tag % 2 == 0)
+ data.GetULEB128(&Offset);
+ else
+ data.GetCStr(&Offset);
- uint8_t FormatVersion = data.GetU8(&Offset);
- if (FormatVersion != llvm::ARMBuildAttrs::Format_Version)
- return;
+ break;
- Offset = Offset + sizeof(uint32_t); // Section Length
- llvm::StringRef VendorName = data.GetCStr(&Offset);
+ case llvm::ARMBuildAttrs::CPU_raw_name:
+ case llvm::ARMBuildAttrs::CPU_name:
+ data.GetCStr(&Offset);
- if (VendorName != "aeabi")
- return;
+ break;
- if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment)
- arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
+ case llvm::ARMBuildAttrs::ABI_VFP_args: {
+ uint64_t VFPArgs = data.GetULEB128(&Offset);
- while (Offset < length)
- {
- uint8_t Tag = data.GetU8(&Offset);
- uint32_t Size = data.GetU32(&Offset);
+ if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) {
+ if (arch_spec.GetTriple().getEnvironment() ==
+ llvm::Triple::UnknownEnvironment ||
+ arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
+ arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
- if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
- continue;
+ arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
+ } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) {
+ if (arch_spec.GetTriple().getEnvironment() ==
+ llvm::Triple::UnknownEnvironment ||
+ arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
+ arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);
- while (Offset < length)
- {
- uint64_t Tag = data.GetULEB128(&Offset);
- switch (Tag)
- {
- default:
- if (Tag < 32)
- data.GetULEB128(&Offset);
- else if (Tag % 2 == 0)
- data.GetULEB128(&Offset);
- else
- data.GetCStr(&Offset);
-
- break;
-
- case llvm::ARMBuildAttrs::CPU_raw_name:
- case llvm::ARMBuildAttrs::CPU_name:
- data.GetCStr(&Offset);
-
- break;
-
- case llvm::ARMBuildAttrs::ABI_VFP_args:
- {
- uint64_t VFPArgs = data.GetULEB128(&Offset);
-
- if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS)
- {
- if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment ||
- arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
- arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
-
- arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
- }
- else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS)
- {
- if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment ||
- arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
- arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);
-
- arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
- }
-
- break;
- }
- }
+ arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
}
+
+ break;
+ }
+ }
}
+ }
}
//----------------------------------------------------------------------
// GetSectionHeaderInfo
//----------------------------------------------------------------------
-size_t
-ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
- const SetDataFunction &set_data,
- const elf::ELFHeader &header,
- lldb_private::UUID &uuid,
- std::string &gnu_debuglink_file,
- uint32_t &gnu_debuglink_crc,
- ArchSpec &arch_spec)
-{
- // Don't reparse the section headers if we already did that.
- if (!section_headers.empty())
- return section_headers.size();
-
- // Only initialize the arch_spec to okay defaults if they're not already set.
- // We'll refine this with note data as we parse the notes.
- if (arch_spec.GetTriple ().getOS () == llvm::Triple::OSType::UnknownOS)
- {
- llvm::Triple::OSType ostype;
- llvm::Triple::OSType spec_ostype;
- 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
- GetOsFromOSABI (header.e_ident[EI_OSABI], ostype);
- spec_ostype = arch_spec.GetTriple ().getOS ();
- assert(spec_ostype == ostype);
- }
-
- if (arch_spec.GetMachine() == llvm::Triple::mips || arch_spec.GetMachine() == llvm::Triple::mipsel
- || arch_spec.GetMachine() == llvm::Triple::mips64 || arch_spec.GetMachine() == llvm::Triple::mips64el)
- {
- switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE)
- {
- case llvm::ELF::EF_MIPS_MICROMIPS:
- arch_spec.SetFlags (ArchSpec::eMIPSAse_micromips);
- break;
- case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
- arch_spec.SetFlags (ArchSpec::eMIPSAse_mips16);
- break;
- case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
- arch_spec.SetFlags (ArchSpec::eMIPSAse_mdmx);
- break;
- default:
- break;
- }
+size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
+ const SetDataFunction &set_data,
+ const elf::ELFHeader &header,
+ lldb_private::UUID &uuid,
+ std::string &gnu_debuglink_file,
+ uint32_t &gnu_debuglink_crc,
+ ArchSpec &arch_spec) {
+ // Don't reparse the section headers if we already did that.
+ if (!section_headers.empty())
+ return section_headers.size();
+
+ // Only initialize the arch_spec to okay defaults if they're not already set.
+ // We'll refine this with note data as we parse the notes.
+ if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) {
+ llvm::Triple::OSType ostype;
+ llvm::Triple::OSType spec_ostype;
+ 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 might be not enough: for example
+ // a shared library might not have any notes at all
+ // and have EI_OSABI flag set to System V,
+ // as result the OS will be set to UnknownOS.
+ GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
+ spec_ostype = arch_spec.GetTriple().getOS();
+ assert(spec_ostype == ostype);
+ }
+
+ if (arch_spec.GetMachine() == llvm::Triple::mips ||
+ arch_spec.GetMachine() == llvm::Triple::mipsel ||
+ arch_spec.GetMachine() == llvm::Triple::mips64 ||
+ arch_spec.GetMachine() == llvm::Triple::mips64el) {
+ switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) {
+ case llvm::ELF::EF_MIPS_MICROMIPS:
+ arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips);
+ break;
+ case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
+ arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16);
+ break;
+ case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
+ arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx);
+ break;
+ default:
+ break;
}
+ }
- if (arch_spec.GetMachine() == llvm::Triple::arm ||
- arch_spec.GetMachine() == llvm::Triple::thumb)
- {
- if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
- arch_spec.SetFlags (ArchSpec::eARM_abi_soft_float);
- else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
- arch_spec.SetFlags (ArchSpec::eARM_abi_hard_float);
- }
+ if (arch_spec.GetMachine() == llvm::Triple::arm ||
+ arch_spec.GetMachine() == llvm::Triple::thumb) {
+ if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
+ arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
+ else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
+ arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
+ }
- // If there are no section headers we are done.
- if (header.e_shnum == 0)
- return 0;
+ // If there are no section headers we are done.
+ if (header.e_shnum == 0)
+ return 0;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
- section_headers.resize(header.e_shnum);
- if (section_headers.size() != header.e_shnum)
- return 0;
+ section_headers.resize(header.e_shnum);
+ if (section_headers.size() != header.e_shnum)
+ return 0;
- const size_t sh_size = header.e_shnum * header.e_shentsize;
- const elf_off sh_offset = header.e_shoff;
- DataExtractor sh_data;
- if (set_data (sh_data, sh_offset, sh_size) != sh_size)
- return 0;
+ const size_t sh_size = header.e_shnum * header.e_shentsize;
+ const elf_off sh_offset = header.e_shoff;
+ DataExtractor sh_data;
+ if (set_data(sh_data, sh_offset, sh_size) != sh_size)
+ return 0;
- 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)
+ 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)
+ break;
+ }
+ if (idx < section_headers.size())
+ section_headers.resize(idx);
+
+ const unsigned strtab_idx = header.e_shstrndx;
+ if (strtab_idx && strtab_idx < section_headers.size()) {
+ const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
+ const size_t byte_size = sheader.sh_size;
+ const Elf64_Off offset = sheader.sh_offset;
+ lldb_private::DataExtractor shstr_data;
+
+ if (set_data(shstr_data, offset, byte_size) == byte_size) {
+ for (SectionHeaderCollIter I = section_headers.begin();
+ I != section_headers.end(); ++I) {
+ static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink");
+ const ELFSectionHeaderInfo &sheader = *I;
+ const uint64_t section_size =
+ sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size;
+ ConstString name(shstr_data.PeekCStr(I->sh_name));
+
+ I->section_name = name;
+
+ if (arch_spec.IsMIPS()) {
+ uint32_t arch_flags = arch_spec.GetFlags();
+ DataExtractor data;
+ if (sheader.sh_type == SHT_MIPS_ABIFLAGS) {
+
+ if (section_size && (set_data(data, sheader.sh_offset,
+ section_size) == section_size)) {
+ // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
+ lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
+ arch_flags |= data.GetU32(&offset);
+
+ // The floating point ABI is at offset 7
+ offset = 7;
+ switch (data.GetU8(&offset)) {
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_64:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64;
+ break;
+ case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A:
+ arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A;
+ break;
+ }
+ }
+ }
+ // Settings appropriate ArchSpec ABI Flags
+ switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) {
+ case llvm::ELF::EF_MIPS_ABI_O32:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
break;
- }
- if (idx < section_headers.size())
- section_headers.resize(idx);
-
- const unsigned strtab_idx = header.e_shstrndx;
- if (strtab_idx && strtab_idx < section_headers.size())
- {
- const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
- const size_t byte_size = sheader.sh_size;
- const Elf64_Off offset = sheader.sh_offset;
- lldb_private::DataExtractor shstr_data;
-
- if (set_data (shstr_data, offset, byte_size) == byte_size)
- {
- for (SectionHeaderCollIter I = section_headers.begin();
- I != section_headers.end(); ++I)
- {
- static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
- const ELFSectionHeaderInfo &sheader = *I;
- const uint64_t section_size = sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size;
- ConstString name(shstr_data.PeekCStr(I->sh_name));
-
- I->section_name = name;
-
- if (arch_spec.IsMIPS())
- {
- uint32_t arch_flags = arch_spec.GetFlags ();
- DataExtractor data;
- if (sheader.sh_type == SHT_MIPS_ABIFLAGS)
- {
-
- if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
- {
- // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
- lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
- arch_flags |= data.GetU32 (&offset);
-
- // The floating point ABI is at offset 7
- offset = 7;
- switch (data.GetU8 (&offset))
- {
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY;
- break;
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE;
- break;
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE;
- break;
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT;
- break;
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64 :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64;
- break;
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX;
- break;
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_64 :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64;
- break;
- case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A :
- arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A;
- break;
- }
- }
- }
- // Settings appropriate ArchSpec ABI Flags
- switch(header.e_flags & llvm::ELF::EF_MIPS_ABI)
- {
- case llvm::ELF::EF_MIPS_ABI_O32:
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
- break;
- case EF_MIPS_ABI_O64:
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64;
- break;
- case EF_MIPS_ABI_EABI32:
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32;
- break;
- case EF_MIPS_ABI_EABI64:
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64;
- break;
- default:
- // ABI Mask doesn't cover N32 and N64 ABI.
- if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64;
- else if (header.e_flags && llvm::ELF::EF_MIPS_ABI2)
- arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
- break;
- }
- arch_spec.SetFlags (arch_flags);
- }
+ case EF_MIPS_ABI_O64:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64;
+ break;
+ case EF_MIPS_ABI_EABI32:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32;
+ break;
+ case EF_MIPS_ABI_EABI64:
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64;
+ break;
+ default:
+ // ABI Mask doesn't cover N32 and N64 ABI.
+ if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64;
+ else if (header.e_flags && llvm::ELF::EF_MIPS_ABI2)
+ arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
+ break;
+ }
+ arch_spec.SetFlags(arch_flags);
+ }
- if (arch_spec.GetMachine() == llvm::Triple::arm || arch_spec.GetMachine() == llvm::Triple::thumb)
- {
- DataExtractor data;
+ if (arch_spec.GetMachine() == llvm::Triple::arm ||
+ arch_spec.GetMachine() == llvm::Triple::thumb) {
+ DataExtractor data;
- if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
- set_data(data, sheader.sh_offset, section_size) == section_size)
- ParseARMAttributes(data, section_size, arch_spec);
- }
+ if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
+ set_data(data, sheader.sh_offset, section_size) == section_size)
+ ParseARMAttributes(data, section_size, arch_spec);
+ }
- if (name == g_sect_name_gnu_debuglink)
- {
- DataExtractor data;
- if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
- {
- lldb::offset_t gnu_debuglink_offset = 0;
- gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
- gnu_debuglink_offset = llvm::alignTo (gnu_debuglink_offset, 4);
- data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
- }
- }
+ if (name == g_sect_name_gnu_debuglink) {
+ DataExtractor data;
+ if (section_size && (set_data(data, sheader.sh_offset,
+ section_size) == section_size)) {
+ lldb::offset_t gnu_debuglink_offset = 0;
+ gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset);
+ gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
+ data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
+ }
+ }
- // Process ELF note section entries.
- bool is_note_header = (sheader.sh_type == SHT_NOTE);
-
- // The section header ".note.android.ident" is stored as a
- // PROGBITS type header but it is actually a note header.
- static ConstString g_sect_name_android_ident (".note.android.ident");
- if (!is_note_header && name == g_sect_name_android_ident)
- is_note_header = true;
-
- if (is_note_header)
- {
- // Allow notes to refine module info.
- DataExtractor data;
- if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
- {
- Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("ObjectFileELF::%s ELF note processing failed: %s", __FUNCTION__, error.AsCString ());
- }
- }
- }
+ // Process ELF note section entries.
+ bool is_note_header = (sheader.sh_type == SHT_NOTE);
+
+ // The section header ".note.android.ident" is stored as a
+ // PROGBITS type header but it is actually a note header.
+ static ConstString g_sect_name_android_ident(".note.android.ident");
+ if (!is_note_header && name == g_sect_name_android_ident)
+ is_note_header = true;
+
+ if (is_note_header) {
+ // Allow notes to refine module info.
+ DataExtractor data;
+ if (section_size && (set_data(data, sheader.sh_offset,
+ section_size) == section_size)) {
+ Error error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("ObjectFileELF::%s ELF note processing failed: %s",
+ __FUNCTION__, error.AsCString());
}
+ }
+ }
+ }
- // Make any unknown triple components to be unspecified unknowns.
- if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
- arch_spec.GetTriple().setVendorName (llvm::StringRef());
- if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
- arch_spec.GetTriple().setOSName (llvm::StringRef());
+ // Make any unknown triple components to be unspecified unknowns.
+ if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
+ arch_spec.GetTriple().setVendorName(llvm::StringRef());
+ if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
+ arch_spec.GetTriple().setOSName(llvm::StringRef());
- return section_headers.size();
- }
+ return section_headers.size();
}
+ }
- section_headers.clear();
- return 0;
+ section_headers.clear();
+ return 0;
}
-size_t
-ObjectFileELF::GetProgramHeaderCount()
-{
- return ParseProgramHeaders();
-}
+size_t ObjectFileELF::GetProgramHeaderCount() { return ParseProgramHeaders(); }
const elf::ELFProgramHeader *
-ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id)
-{
- if (!id || !ParseProgramHeaders())
- return NULL;
+ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id) {
+ if (!id || !ParseProgramHeaders())
+ return NULL;
- if (--id < m_program_headers.size())
- return &m_program_headers[id];
+ if (--id < m_program_headers.size())
+ return &m_program_headers[id];
- return NULL;
+ 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);
+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);
}
std::string
-ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const
-{
- size_t pos = symbol_name.find('@');
- return symbol_name.substr(0, pos).str();
+ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
+ size_t pos = symbol_name.find('@');
+ return symbol_name.substr(0, pos).str();
}
//----------------------------------------------------------------------
// ParseSectionHeaders
//----------------------------------------------------------------------
-size_t
-ObjectFileELF::ParseSectionHeaders()
-{
- using namespace std::placeholders;
+size_t ObjectFileELF::ParseSectionHeaders() {
+ using namespace std::placeholders;
- return GetSectionHeaderInfo(m_section_headers,
- std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3),
- m_header,
- m_uuid,
- m_gnu_debuglink_file,
- m_gnu_debuglink_crc,
- m_arch_spec);
+ return GetSectionHeaderInfo(
+ m_section_headers,
+ std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2,
+ _3),
+ m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec);
}
-lldb::offset_t
-ObjectFileELF::SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length)
-{
- return dst.SetData(src, offset, length);
+lldb::offset_t ObjectFileELF::SetData(const lldb_private::DataExtractor &src,
+ lldb_private::DataExtractor &dst,
+ lldb::offset_t offset,
+ lldb::offset_t length) {
+ return dst.SetData(src, offset, length);
}
lldb::offset_t
-ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length)
-{
- if (offset + length <= m_data.GetByteSize())
- return dst.SetData(m_data, offset, length);
-
- const auto process_sp = m_process_wp.lock();
- if (process_sp != nullptr)
- {
- addr_t file_size = offset + length;
-
- DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size);
- if (!data_sp)
- return false;
- m_data.SetData(data_sp, 0, file_size);
- }
-
+ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst,
+ lldb::offset_t offset,
+ lldb::offset_t length) {
+ if (offset + length <= m_data.GetByteSize())
return dst.SetData(m_data, offset, length);
+
+ const auto process_sp = m_process_wp.lock();
+ if (process_sp != nullptr) {
+ addr_t file_size = offset + length;
+
+ DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size);
+ if (!data_sp)
+ return false;
+ m_data.SetData(data_sp, 0, file_size);
+ }
+
+ return dst.SetData(m_data, offset, length);
}
const ObjectFileELF::ELFSectionHeaderInfo *
-ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
-{
- if (!id || !ParseSectionHeaders())
- return NULL;
+ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) {
+ if (!id || !ParseSectionHeaders())
+ return NULL;
- if (--id < m_section_headers.size())
- return &m_section_headers[id];
+ if (--id < m_section_headers.size())
+ return &m_section_headers[id];
- return NULL;
+ return NULL;
}
-lldb::user_id_t
-ObjectFileELF::GetSectionIndexByName(const char* name)
-{
- if (!name || !name[0] || !ParseSectionHeaders())
- return 0;
- for (size_t i = 1; i < m_section_headers.size(); ++i)
- if (m_section_headers[i].section_name == ConstString(name))
- return i;
+lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) {
+ if (!name || !name[0] || !ParseSectionHeaders())
return 0;
+ for (size_t i = 1; i < m_section_headers.size(); ++i)
+ if (m_section_headers[i].section_name == ConstString(name))
+ return i;
+ return 0;
}
-void
-ObjectFileELF::CreateSections(SectionList &unified_section_list)
-{
- if (!m_sections_ap.get() && ParseSectionHeaders())
- {
- m_sections_ap.reset(new SectionList());
-
- 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_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_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_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");
-
- 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_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_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_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;
-
- const uint32_t permissions = ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0) |
- ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0) |
- ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0);
- 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;
- }
-
- 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);
- }
-
- 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);
- 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.
- header.sh_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);
- }
- }
+void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
+ if (!m_sections_ap.get() && ParseSectionHeaders()) {
+ m_sections_ap.reset(new SectionList());
- if (m_sections_ap.get())
- {
- if (GetType() == eTypeDebugInfo)
- {
- static const SectionType g_sections[] =
- {
- eSectionTypeDWARFDebugAbbrev,
- eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges,
- eSectionTypeDWARFDebugFrame,
- eSectionTypeDWARFDebugInfo,
- eSectionTypeDWARFDebugLine,
- eSectionTypeDWARFDebugLoc,
- eSectionTypeDWARFDebugMacInfo,
- eSectionTypeDWARFDebugPubNames,
- eSectionTypeDWARFDebugPubTypes,
- eSectionTypeDWARFDebugRanges,
- eSectionTypeDWARFDebugStr,
- eSectionTypeDWARFDebugStrOffsets,
- eSectionTypeELFSymbolTable,
- };
- SectionList *elf_section_list = m_sections_ap.get();
- for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
- {
- SectionType section_type = g_sections[idx];
- SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
- if (section_sp)
- {
- SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
- if (module_section_sp)
- unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
- else
- unified_section_list.AddSection (section_sp);
- }
- }
- }
- else
- {
- unified_section_list = *m_sections_ap;
+ for (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_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_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_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");
+
+ 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_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_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_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;
+
+ 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;
+ }
+
+ 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);
+ }
+
+ 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);
+ 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.
+ header.sh_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);
+ }
+ }
+
+ if (m_sections_ap.get()) {
+ if (GetType() == eTypeDebugInfo) {
+ static const SectionType g_sections[] = {
+ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
+ eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugFrame,
+ eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine,
+ eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugMacInfo,
+ eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
+ eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr,
+ eSectionTypeDWARFDebugStrOffsets, eSectionTypeELFSymbolTable,
+ };
+ SectionList *elf_section_list = m_sections_ap.get();
+ for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
+ ++idx) {
+ SectionType section_type = g_sections[idx];
+ SectionSP section_sp(
+ elf_section_list->FindSectionByType(section_type, true));
+ if (section_sp) {
+ SectionSP module_section_sp(
+ unified_section_list.FindSectionByType(section_type, true));
+ if (module_section_sp)
+ unified_section_list.ReplaceSection(module_section_sp->GetID(),
+ section_sp);
+ else
+ unified_section_list.AddSection(section_sp);
}
+ }
+ } else {
+ unified_section_list = *m_sections_ap;
}
+ }
}
-// Find the arm/aarch64 mapping symbol character in the given symbol name. Mapping symbols have the
-// form of "$<char>[.<any>]*". Additionally we recognize cases when the mapping symbol prefixed by
-// an arbitrary string because if a symbol prefix added to each symbol in the object file with
+// Find the arm/aarch64 mapping symbol character in the given symbol name.
+// Mapping symbols have the
+// form of "$<char>[.<any>]*". Additionally we recognize cases when the mapping
+// symbol prefixed by
+// an arbitrary string because if a symbol prefix added to each symbol in the
+// object file with
// objcopy then the mapping symbols are also prefixed.
-static char
-FindArmAarch64MappingSymbol(const char* symbol_name)
-{
- if (!symbol_name)
- return '\0';
-
- const char* dollar_pos = ::strchr(symbol_name, '$');
- if (!dollar_pos || dollar_pos[1] == '\0')
- return '\0';
+static char FindArmAarch64MappingSymbol(const char *symbol_name) {
+ if (!symbol_name)
+ return '\0';
- if (dollar_pos[2] == '\0' || dollar_pos[2] == '.')
- return dollar_pos[1];
+ const char *dollar_pos = ::strchr(symbol_name, '$');
+ if (!dollar_pos || dollar_pos[1] == '\0')
return '\0';
+
+ if (dollar_pos[2] == '\0' || dollar_pos[2] == '.')
+ return dollar_pos[1];
+ return '\0';
}
-#define STO_MIPS_ISA (3 << 6)
-#define STO_MICROMIPS (2 << 6)
-#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER) & STO_MIPS_ISA) == STO_MICROMIPS)
+#define STO_MIPS_ISA (3 << 6)
+#define STO_MICROMIPS (2 << 6)
+#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
// private
-unsigned
-ObjectFileELF::ParseSymbols (Symtab *symtab,
- user_id_t start_id,
- SectionList *section_list,
- const size_t num_symbols,
- const DataExtractor &symtab_data,
- const DataExtractor &strtab_data)
-{
- ELFSymbol symbol;
- lldb::offset_t offset = 0;
+unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
+ SectionList *section_list,
+ const size_t num_symbols,
+ const DataExtractor &symtab_data,
+ const DataExtractor &strtab_data) {
+ ELFSymbol symbol;
+ lldb::offset_t offset = 0;
+
+ static ConstString text_section_name(".text");
+ static ConstString init_section_name(".init");
+ static ConstString fini_section_name(".fini");
+ static ConstString ctors_section_name(".ctors");
+ static ConstString dtors_section_name(".dtors");
+
+ static ConstString data_section_name(".data");
+ static ConstString rodata_section_name(".rodata");
+ static ConstString rodata1_section_name(".rodata1");
+ static ConstString data2_section_name(".data1");
+ static ConstString bss_section_name(".bss");
+ static ConstString opd_section_name(".opd"); // For ppc64
+
+ // On Android the oatdata and the oatexec symbols in the oat and odex files
+ // covers the full
+ // .text section what causes issues with displaying unusable symbol name to
+ // the user and very
+ // slow unwinding speed because the instruction emulation based unwind plans
+ // try to emulate all
+ // instructions in these symbols. Don't add these symbols to the symbol list
+ // as they have no
+ // use for the debugger and they are causing a lot of trouble.
+ // Filtering can't be restricted to Android because this special object file
+ // don't contain the
+ // note section specifying the environment to Android but the custom extension
+ // and file name
+ // makes it highly unlikely that this will collide with anything else.
+ ConstString file_extension = m_file.GetFileNameExtension();
+ bool skip_oatdata_oatexec = file_extension == ConstString("oat") ||
+ file_extension == ConstString("odex");
+
+ ArchSpec arch;
+ GetArchitecture(arch);
+ ModuleSP module_sp(GetModule());
+ SectionList *module_section_list =
+ module_sp ? module_sp->GetSectionList() : nullptr;
+
+ // Local cache to avoid doing a FindSectionByName for each symbol. The "const
+ // char*" key must
+ // came from a ConstString object so they can be compared by pointer
+ std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
+
+ unsigned i;
+ for (i = 0; i < num_symbols; ++i) {
+ if (symbol.Parse(symtab_data, &offset) == false)
+ break;
+
+ const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
+ if (!symbol_name)
+ symbol_name = "";
+
+ // No need to add non-section symbols that have no names
+ if (symbol.getType() != STT_SECTION &&
+ (symbol_name == nullptr || symbol_name[0] == '\0'))
+ continue;
+
+ // Skipping oatdata and oatexec sections if it is requested. See details
+ // above the
+ // definition of skip_oatdata_oatexec for the reasons.
+ if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 ||
+ ::strcmp(symbol_name, "oatexec") == 0))
+ continue;
+
+ SectionSP symbol_section_sp;
+ SymbolType symbol_type = eSymbolTypeInvalid;
+ Elf64_Half section_idx = symbol.st_shndx;
+
+ switch (section_idx) {
+ case SHN_ABS:
+ symbol_type = eSymbolTypeAbsolute;
+ break;
+ case SHN_UNDEF:
+ symbol_type = eSymbolTypeUndefined;
+ break;
+ default:
+ symbol_section_sp = section_list->GetSectionAtIndex(section_idx);
+ break;
+ }
- static ConstString text_section_name(".text");
- static ConstString init_section_name(".init");
- static ConstString fini_section_name(".fini");
- static ConstString ctors_section_name(".ctors");
- static ConstString dtors_section_name(".dtors");
-
- static ConstString data_section_name(".data");
- static ConstString rodata_section_name(".rodata");
- static ConstString rodata1_section_name(".rodata1");
- static ConstString data2_section_name(".data1");
- static ConstString bss_section_name(".bss");
- static ConstString opd_section_name(".opd"); // For ppc64
-
- // On Android the oatdata and the oatexec symbols in the oat and odex files covers the full
- // .text section what causes issues with displaying unusable symbol name to the user and very
- // slow unwinding speed because the instruction emulation based unwind plans try to emulate all
- // instructions in these symbols. Don't add these symbols to the symbol list as they have no
- // use for the debugger and they are causing a lot of trouble.
- // Filtering can't be restricted to Android because this special object file don't contain the
- // note section specifying the environment to Android but the custom extension and file name
- // makes it highly unlikely that this will collide with anything else.
- ConstString file_extension = m_file.GetFileNameExtension();
- bool skip_oatdata_oatexec = file_extension == ConstString("oat") || file_extension == ConstString("odex");
-
- ArchSpec arch;
- GetArchitecture(arch);
- ModuleSP module_sp(GetModule());
- SectionList* module_section_list = module_sp ? module_sp->GetSectionList() : nullptr;
-
- // Local cache to avoid doing a FindSectionByName for each symbol. The "const char*" key must
- // came from a ConstString object so they can be compared by pointer
- std::unordered_map<const char*, lldb::SectionSP> section_name_to_section;
-
- unsigned i;
- for (i = 0; i < num_symbols; ++i)
- {
- if (symbol.Parse(symtab_data, &offset) == false)
- break;
+ // If a symbol is undefined do not process it further even if it has a STT
+ // type
+ if (symbol_type != eSymbolTypeUndefined) {
+ switch (symbol.getType()) {
+ default:
+ case STT_NOTYPE:
+ // The symbol's type is not specified.
+ break;
- const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
+ case STT_OBJECT:
+ // The symbol is associated with a data object, such as a variable,
+ // an array, etc.
+ symbol_type = eSymbolTypeData;
+ break;
- // No need to add non-section symbols that have no names
- if (symbol.getType() != STT_SECTION &&
- (symbol_name == NULL || symbol_name[0] == '\0'))
- continue;
+ case STT_FUNC:
+ // The symbol is associated with a function or other executable code.
+ symbol_type = eSymbolTypeCode;
+ break;
- // Skipping oatdata and oatexec sections if it is requested. See details above the
- // definition of skip_oatdata_oatexec for the reasons.
- if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 || ::strcmp(symbol_name, "oatexec") == 0))
- continue;
+ case STT_SECTION:
+ // The symbol is associated with a section. Symbol table entries of
+ // this type exist primarily for relocation and normally have
+ // STB_LOCAL binding.
+ break;
- SectionSP symbol_section_sp;
- SymbolType symbol_type = eSymbolTypeInvalid;
- Elf64_Half section_idx = symbol.st_shndx;
+ case STT_FILE:
+ // Conventionally, the symbol's name gives the name of the source
+ // file associated with the object file. A file symbol has STB_LOCAL
+ // binding, its section index is SHN_ABS, and it precedes the other
+ // STB_LOCAL symbols for the file, if it is present.
+ symbol_type = eSymbolTypeSourceFile;
+ break;
- switch (section_idx)
- {
- case SHN_ABS:
- symbol_type = eSymbolTypeAbsolute;
- break;
- case SHN_UNDEF:
- symbol_type = eSymbolTypeUndefined;
- break;
- default:
- symbol_section_sp = section_list->GetSectionAtIndex(section_idx);
- break;
+ case STT_GNU_IFUNC:
+ // The symbol is associated with an indirect function. The actual
+ // function will be resolved if it is referenced.
+ symbol_type = eSymbolTypeResolver;
+ break;
+ }
+ }
+
+ if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) {
+ if (symbol_section_sp) {
+ const ConstString &sect_name = symbol_section_sp->GetName();
+ if (sect_name == text_section_name || sect_name == init_section_name ||
+ sect_name == fini_section_name || sect_name == ctors_section_name ||
+ sect_name == dtors_section_name) {
+ symbol_type = eSymbolTypeCode;
+ } else if (sect_name == data_section_name ||
+ sect_name == data2_section_name ||
+ sect_name == rodata_section_name ||
+ sect_name == rodata1_section_name ||
+ sect_name == bss_section_name) {
+ symbol_type = eSymbolTypeData;
}
-
- // If a symbol is undefined do not process it further even if it has a STT type
- if (symbol_type != eSymbolTypeUndefined)
- {
- switch (symbol.getType())
- {
- default:
- case STT_NOTYPE:
- // The symbol's type is not specified.
- break;
-
- case STT_OBJECT:
- // The symbol is associated with a data object, such as a variable,
- // an array, etc.
- symbol_type = eSymbolTypeData;
- break;
-
- case STT_FUNC:
- // The symbol is associated with a function or other executable code.
- symbol_type = eSymbolTypeCode;
- break;
-
- case STT_SECTION:
- // The symbol is associated with a section. Symbol table entries of
- // this type exist primarily for relocation and normally have
- // STB_LOCAL binding.
- break;
-
- case STT_FILE:
- // Conventionally, the symbol's name gives the name of the source
- // file associated with the object file. A file symbol has STB_LOCAL
- // binding, its section index is SHN_ABS, and it precedes the other
- // STB_LOCAL symbols for the file, if it is present.
- symbol_type = eSymbolTypeSourceFile;
- break;
-
- case STT_GNU_IFUNC:
- // The symbol is associated with an indirect function. The actual
- // function will be resolved if it is referenced.
- symbol_type = eSymbolTypeResolver;
- break;
- }
- }
-
- if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION)
- {
- if (symbol_section_sp)
- {
- const ConstString &sect_name = symbol_section_sp->GetName();
- if (sect_name == text_section_name ||
- sect_name == init_section_name ||
- sect_name == fini_section_name ||
- sect_name == ctors_section_name ||
- sect_name == dtors_section_name)
- {
- symbol_type = eSymbolTypeCode;
- }
- else if (sect_name == data_section_name ||
- sect_name == data2_section_name ||
- sect_name == rodata_section_name ||
- sect_name == rodata1_section_name ||
- sect_name == bss_section_name)
- {
- symbol_type = eSymbolTypeData;
- }
+ }
+ }
+
+ int64_t symbol_value_offset = 0;
+ uint32_t additional_flags = 0;
+
+ if (arch.IsValid()) {
+ if (arch.GetMachine() == llvm::Triple::arm) {
+ if (symbol.getBinding() == STB_LOCAL) {
+ char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
+ if (symbol_type == eSymbolTypeCode) {
+ switch (mapping_symbol) {
+ case 'a':
+ // $a[.<any>]* - marks an ARM instruction sequence
+ m_address_class_map[symbol.st_value] = eAddressClassCode;
+ break;
+ case 'b':
+ case 't':
+ // $b[.<any>]* - marks a THUMB BL instruction sequence
+ // $t[.<any>]* - marks a THUMB instruction sequence
+ m_address_class_map[symbol.st_value] =
+ eAddressClassCodeAlternateISA;
+ break;
+ case 'd':
+ // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
+ m_address_class_map[symbol.st_value] = eAddressClassData;
+ break;
}
+ }
+ if (mapping_symbol)
+ continue;
}
-
- int64_t symbol_value_offset = 0;
- uint32_t additional_flags = 0;
-
- if (arch.IsValid())
- {
- if (arch.GetMachine() == llvm::Triple::arm)
- {
- if (symbol.getBinding() == STB_LOCAL)
- {
- char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
- if (symbol_type == eSymbolTypeCode)
- {
- switch (mapping_symbol)
- {
- case 'a':
- // $a[.<any>]* - marks an ARM instruction sequence
- m_address_class_map[symbol.st_value] = eAddressClassCode;
- break;
- case 'b':
- case 't':
- // $b[.<any>]* - marks a THUMB BL instruction sequence
- // $t[.<any>]* - marks a THUMB instruction sequence
- m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
- break;
- case 'd':
- // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
- m_address_class_map[symbol.st_value] = eAddressClassData;
- break;
- }
- }
- if (mapping_symbol)
- continue;
- }
- }
- else if (arch.GetMachine() == llvm::Triple::aarch64)
- {
- if (symbol.getBinding() == STB_LOCAL)
- {
- char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
- if (symbol_type == eSymbolTypeCode)
- {
- switch (mapping_symbol)
- {
- case 'x':
- // $x[.<any>]* - marks an A64 instruction sequence
- m_address_class_map[symbol.st_value] = eAddressClassCode;
- break;
- case 'd':
- // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
- m_address_class_map[symbol.st_value] = eAddressClassData;
- break;
- }
- }
- if (mapping_symbol)
- continue;
- }
- }
-
- if (arch.GetMachine() == llvm::Triple::arm)
- {
- if (symbol_type == eSymbolTypeCode)
- {
- if (symbol.st_value & 1)
- {
- // Subtracting 1 from the address effectively unsets
- // the low order bit, which results in the address
- // actually pointing to the beginning of the symbol.
- // This delta will be used below in conjunction with
- // symbol.st_value to produce the final symbol_value
- // that we store in the symtab.
- symbol_value_offset = -1;
- m_address_class_map[symbol.st_value^1] = eAddressClassCodeAlternateISA;
- }
- else
- {
- // This address is ARM
- m_address_class_map[symbol.st_value] = eAddressClassCode;
- }
- }
- }
-
- /*
- * MIPS:
- * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for MIPS).
- * This allows processer to switch between microMIPS and MIPS without any need
- * for special mode-control register. However, apart from .debug_line, none of
- * the ELF/DWARF sections set the ISA bit (for symbol or section). Use st_other
- * flag to check whether the symbol is microMIPS and then set the address class
- * accordingly.
- */
- const llvm::Triple::ArchType llvm_arch = arch.GetMachine();
- if (llvm_arch == llvm::Triple::mips || llvm_arch == llvm::Triple::mipsel
- || llvm_arch == llvm::Triple::mips64 || llvm_arch == llvm::Triple::mips64el)
- {
- if (IS_MICROMIPS(symbol.st_other))
- m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
- else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode))
- {
- symbol.st_value = symbol.st_value & (~1ull);
- m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
- }
- else
- {
- if (symbol_type == eSymbolTypeCode)
- m_address_class_map[symbol.st_value] = eAddressClassCode;
- else if (symbol_type == eSymbolTypeData)
- m_address_class_map[symbol.st_value] = eAddressClassData;
- else
- m_address_class_map[symbol.st_value] = eAddressClassUnknown;
- }
+ } else if (arch.GetMachine() == llvm::Triple::aarch64) {
+ if (symbol.getBinding() == STB_LOCAL) {
+ char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
+ if (symbol_type == eSymbolTypeCode) {
+ switch (mapping_symbol) {
+ case 'x':
+ // $x[.<any>]* - marks an A64 instruction sequence
+ m_address_class_map[symbol.st_value] = eAddressClassCode;
+ break;
+ case 'd':
+ // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
+ m_address_class_map[symbol.st_value] = eAddressClassData;
+ break;
}
+ }
+ if (mapping_symbol)
+ continue;
}
-
- // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB symbols. See above for
- // more details.
- uint64_t symbol_value = symbol.st_value + symbol_value_offset;
-
- if (symbol_section_sp == nullptr && section_idx == SHN_ABS && symbol.st_size != 0)
- {
- // We don't have a section for a symbol with non-zero size. Create a new section for it
- // so the address range covered by the symbol is also covered by the module (represented
- // through the section list). It is needed so module lookup for the addresses covered
- // by this symbol will be successfull. This case happens for absolute symbols.
- ConstString fake_section_name(std::string(".absolute.") + symbol_name);
- symbol_section_sp = std::make_shared<Section>(module_sp,
- this,
- SHN_ABS,
- fake_section_name,
- eSectionTypeAbsoluteAddress,
- symbol_value,
- symbol.st_size,
- 0, 0, 0,
- SHF_ALLOC);
-
- module_section_list->AddSection(symbol_section_sp);
- section_list->AddSection(symbol_section_sp);
+ }
+
+ if (arch.GetMachine() == llvm::Triple::arm) {
+ if (symbol_type == eSymbolTypeCode) {
+ if (symbol.st_value & 1) {
+ // Subtracting 1 from the address effectively unsets
+ // the low order bit, which results in the address
+ // actually pointing to the beginning of the symbol.
+ // This delta will be used below in conjunction with
+ // symbol.st_value to produce the final symbol_value
+ // that we store in the symtab.
+ symbol_value_offset = -1;
+ m_address_class_map[symbol.st_value ^ 1] =
+ eAddressClassCodeAlternateISA;
+ } else {
+ // This address is ARM
+ m_address_class_map[symbol.st_value] = eAddressClassCode;
+ }
}
-
- if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile)
- symbol_value -= symbol_section_sp->GetFileAddress();
-
- if (symbol_section_sp && module_section_list && module_section_list != section_list)
- {
- const ConstString &sect_name = symbol_section_sp->GetName();
- auto section_it = section_name_to_section.find(sect_name.GetCString());
- if (section_it == section_name_to_section.end())
- section_it = section_name_to_section.emplace(
- sect_name.GetCString(),
- module_section_list->FindSectionByName (sect_name)).first;
- if (section_it->second && section_it->second->GetFileSize())
- symbol_section_sp = section_it->second;
+ }
+
+ /*
+ * MIPS:
+ * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for
+ * MIPS).
+ * This allows processor to switch between microMIPS and MIPS without any
+ * need
+ * for special mode-control register. However, apart from .debug_line,
+ * none of
+ * the ELF/DWARF sections set the ISA bit (for symbol or section). Use
+ * st_other
+ * flag to check whether the symbol is microMIPS and then set the address
+ * class
+ * accordingly.
+ */
+ const llvm::Triple::ArchType llvm_arch = arch.GetMachine();
+ if (llvm_arch == llvm::Triple::mips ||
+ llvm_arch == llvm::Triple::mipsel ||
+ llvm_arch == llvm::Triple::mips64 ||
+ llvm_arch == llvm::Triple::mips64el) {
+ if (IS_MICROMIPS(symbol.st_other))
+ m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
+ else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
+ symbol.st_value = symbol.st_value & (~1ull);
+ m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
+ } else {
+ if (symbol_type == eSymbolTypeCode)
+ m_address_class_map[symbol.st_value] = eAddressClassCode;
+ else if (symbol_type == eSymbolTypeData)
+ m_address_class_map[symbol.st_value] = eAddressClassData;
+ else
+ m_address_class_map[symbol.st_value] = eAddressClassUnknown;
}
+ }
+ }
+
+ // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB
+ // symbols. See above for
+ // more details.
+ uint64_t symbol_value = symbol.st_value + symbol_value_offset;
+
+ if (symbol_section_sp == nullptr && section_idx == SHN_ABS &&
+ symbol.st_size != 0) {
+ // We don't have a section for a symbol with non-zero size. Create a new
+ // section for it
+ // so the address range covered by the symbol is also covered by the
+ // module (represented
+ // through the section list). It is needed so module lookup for the
+ // addresses covered
+ // by this symbol will be successfull. This case happens for absolute
+ // symbols.
+ ConstString fake_section_name(std::string(".absolute.") + symbol_name);
+ symbol_section_sp =
+ std::make_shared<Section>(module_sp, this, SHN_ABS, fake_section_name,
+ eSectionTypeAbsoluteAddress, symbol_value,
+ symbol.st_size, 0, 0, 0, SHF_ALLOC);
+
+ module_section_list->AddSection(symbol_section_sp);
+ section_list->AddSection(symbol_section_sp);
+ }
+
+ if (symbol_section_sp &&
+ CalculateType() != ObjectFile::Type::eTypeObjectFile)
+ symbol_value -= symbol_section_sp->GetFileAddress();
+
+ if (symbol_section_sp && module_section_list &&
+ module_section_list != section_list) {
+ const ConstString &sect_name = symbol_section_sp->GetName();
+ auto section_it = section_name_to_section.find(sect_name.GetCString());
+ if (section_it == section_name_to_section.end())
+ section_it =
+ section_name_to_section
+ .emplace(sect_name.GetCString(),
+ module_section_list->FindSectionByName(sect_name))
+ .first;
+ if (section_it->second && section_it->second->GetFileSize())
+ symbol_section_sp = section_it->second;
+ }
+
+ bool is_global = symbol.getBinding() == STB_GLOBAL;
+ uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
+ bool is_mangled = (symbol_name[0] == '_' && symbol_name[1] == 'Z');
+
+ llvm::StringRef symbol_ref(symbol_name);
+
+ // Symbol names may contain @VERSION suffixes. Find those and strip them
+ // temporarily.
+ size_t version_pos = symbol_ref.find('@');
+ bool has_suffix = version_pos != llvm::StringRef::npos;
+ llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
+ Mangled mangled(ConstString(symbol_bare), is_mangled);
+
+ // Now append the suffix back to mangled and unmangled names. Only do it if
+ // the
+ // demangling was successful (string is not empty).
+ if (has_suffix) {
+ llvm::StringRef suffix = symbol_ref.substr(version_pos);
+
+ llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
+ if (!mangled_name.empty())
+ mangled.SetMangledName(ConstString((mangled_name + suffix).str()));
+
+ ConstString demangled =
+ mangled.GetDemangledName(lldb::eLanguageTypeUnknown);
+ llvm::StringRef demangled_name = demangled.GetStringRef();
+ if (!demangled_name.empty())
+ mangled.SetDemangledName(ConstString((demangled_name + suffix).str()));
+ }
+
+ // In ELF all symbol should have a valid size but it is not true for some
+ // function symbols
+ // coming from hand written assembly. As none of the function symbol should
+ // have 0 size we
+ // try to calculate the size for these symbols in the symtab with saying
+ // that their original
+ // size is not valid.
+ bool symbol_size_valid =
+ symbol.st_size != 0 || symbol.getType() != STT_FUNC;
+
+ Symbol dc_symbol(
+ i + start_id, // ID is the original symbol table index.
+ mangled,
+ symbol_type, // Type of this symbol
+ is_global, // Is this globally visible?
+ false, // Is this symbol debug info?
+ false, // Is this symbol a trampoline?
+ false, // Is this symbol artificial?
+ AddressRange(symbol_section_sp, // Section in which this symbol is
+ // defined or null.
+ symbol_value, // Offset in section or symbol value.
+ symbol.st_size), // Size in bytes of this symbol.
+ symbol_size_valid, // Symbol size is valid
+ has_suffix, // Contains linker annotations?
+ flags); // Symbol flags.
+ symtab->AddSymbol(dc_symbol);
+ }
+ return i;
+}
+
+unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
+ user_id_t start_id,
+ lldb_private::Section *symtab) {
+ if (symtab->GetObjectFile() != this) {
+ // If the symbol table section is owned by a different object file, have it
+ // do the
+ // parsing.
+ ObjectFileELF *obj_file_elf =
+ static_cast<ObjectFileELF *>(symtab->GetObjectFile());
+ return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
+ }
+
+ // Get section list for this object file.
+ SectionList *section_list = m_sections_ap.get();
+ if (!section_list)
+ return 0;
- bool is_global = symbol.getBinding() == STB_GLOBAL;
- uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
- bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
-
- llvm::StringRef symbol_ref(symbol_name);
-
- // Symbol names may contain @VERSION suffixes. Find those and strip them temporarily.
- size_t version_pos = symbol_ref.find('@');
- bool has_suffix = version_pos != llvm::StringRef::npos;
- llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
- Mangled mangled(ConstString(symbol_bare), is_mangled);
+ user_id_t symtab_id = symtab->GetID();
+ const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
+ assert(symtab_hdr->sh_type == SHT_SYMTAB ||
+ symtab_hdr->sh_type == SHT_DYNSYM);
- // Now append the suffix back to mangled and unmangled names. Only do it if the
- // demangling was successful (string is not empty).
- if (has_suffix)
- {
- llvm::StringRef suffix = symbol_ref.substr(version_pos);
+ // sh_link: section header index of associated string table.
+ // Section ID's are ones based.
+ user_id_t strtab_id = symtab_hdr->sh_link + 1;
+ Section *strtab = section_list->FindSectionByID(strtab_id).get();
- llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
- if (! mangled_name.empty())
- mangled.SetMangledName( ConstString((mangled_name + suffix).str()) );
+ if (symtab && strtab) {
+ assert(symtab->GetObjectFile() == this);
+ assert(strtab->GetObjectFile() == this);
- ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeUnknown);
- llvm::StringRef demangled_name = demangled.GetStringRef();
- if (!demangled_name.empty())
- mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) );
- }
+ DataExtractor symtab_data;
+ DataExtractor strtab_data;
+ if (ReadSectionData(symtab, symtab_data) &&
+ ReadSectionData(strtab, strtab_data)) {
+ size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
- // In ELF all symbol should have a valid size but it is not true for some function symbols
- // coming from hand written assembly. As none of the function symbol should have 0 size we
- // try to calculate the size for these symbols in the symtab with saying that their original
- // size is not valid.
- bool symbol_size_valid = symbol.st_size != 0 || symbol.getType() != STT_FUNC;
-
- Symbol dc_symbol(
- i + start_id, // ID is the original symbol table index.
- mangled,
- symbol_type, // Type of this symbol
- is_global, // Is this globally visible?
- false, // Is this symbol debug info?
- false, // Is this symbol a trampoline?
- false, // Is this symbol artificial?
- AddressRange(
- symbol_section_sp, // Section in which this symbol is defined or null.
- symbol_value, // Offset in section or symbol value.
- symbol.st_size), // Size in bytes of this symbol.
- symbol_size_valid, // Symbol size is valid
- has_suffix, // Contains linker annotations?
- flags); // Symbol flags.
- symtab->AddSymbol(dc_symbol);
+ return ParseSymbols(symbol_table, start_id, section_list, num_symbols,
+ symtab_data, strtab_data);
}
- return i;
-}
+ }
-unsigned
-ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
- user_id_t start_id,
- lldb_private::Section *symtab)
-{
- if (symtab->GetObjectFile() != this)
- {
- // If the symbol table section is owned by a different object file, have it do the
- // parsing.
- ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
- return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
- }
+ return 0;
+}
- // Get section list for this object file.
- SectionList *section_list = m_sections_ap.get();
- if (!section_list)
- return 0;
-
- user_id_t symtab_id = symtab->GetID();
- const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
- 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;
- Section *strtab = section_list->FindSectionByID(strtab_id).get();
-
- if (symtab && strtab)
- {
- assert (symtab->GetObjectFile() == this);
- assert (strtab->GetObjectFile() == this);
-
- DataExtractor symtab_data;
- DataExtractor strtab_data;
- if (ReadSectionData(symtab, symtab_data) &&
- ReadSectionData(strtab, strtab_data))
- {
- size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
-
- return ParseSymbols(symbol_table, start_id, section_list,
- num_symbols, symtab_data, strtab_data);
- }
- }
+size_t ObjectFileELF::ParseDynamicSymbols() {
+ if (m_dynamic_symbols.size())
+ return m_dynamic_symbols.size();
+ SectionList *section_list = GetSectionList();
+ if (!section_list)
return 0;
-}
-size_t
-ObjectFileELF::ParseDynamicSymbols()
-{
- if (m_dynamic_symbols.size())
- return m_dynamic_symbols.size();
-
- SectionList *section_list = GetSectionList();
- if (!section_list)
- return 0;
+ // Find the SHT_DYNAMIC section.
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
+ .get();
+ if (!dynsym)
+ return 0;
+ assert(dynsym->GetObjectFile() == this);
- // Find the SHT_DYNAMIC section.
- Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
- if (!dynsym)
- return 0;
- assert (dynsym->GetObjectFile() == this);
+ ELFDynamic symbol;
+ DataExtractor dynsym_data;
+ if (ReadSectionData(dynsym, dynsym_data)) {
+ const lldb::offset_t section_size = dynsym_data.GetByteSize();
+ lldb::offset_t cursor = 0;
- ELFDynamic symbol;
- DataExtractor dynsym_data;
- if (ReadSectionData(dynsym, dynsym_data))
- {
- const lldb::offset_t section_size = dynsym_data.GetByteSize();
- lldb::offset_t cursor = 0;
-
- while (cursor < section_size)
- {
- if (!symbol.Parse(dynsym_data, &cursor))
- break;
+ while (cursor < section_size) {
+ if (!symbol.Parse(dynsym_data, &cursor))
+ break;
- m_dynamic_symbols.push_back(symbol);
- }
+ m_dynamic_symbols.push_back(symbol);
}
+ }
- return m_dynamic_symbols.size();
+ return m_dynamic_symbols.size();
}
-const ELFDynamic *
-ObjectFileELF::FindDynamicSymbol(unsigned tag)
-{
- if (!ParseDynamicSymbols())
- return NULL;
+const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) {
+ if (!ParseDynamicSymbols())
+ return NULL;
- DynamicSymbolCollIter I = m_dynamic_symbols.begin();
- DynamicSymbolCollIter E = m_dynamic_symbols.end();
- for ( ; I != E; ++I)
- {
- ELFDynamic *symbol = &*I;
+ DynamicSymbolCollIter I = m_dynamic_symbols.begin();
+ DynamicSymbolCollIter E = m_dynamic_symbols.end();
+ for (; I != E; ++I) {
+ ELFDynamic *symbol = &*I;
- if (symbol->d_tag == tag)
- return symbol;
- }
+ if (symbol->d_tag == tag)
+ return symbol;
+ }
- return NULL;
+ return NULL;
}
-unsigned
-ObjectFileELF::PLTRelocationType()
-{
- // DT_PLTREL
- // This member specifies the type of relocation entry to which the
- // procedure linkage table refers. The d_val member holds DT_REL or
- // DT_RELA, as appropriate. All relocations in a procedure linkage table
- // must use the same relocation.
- const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
-
- if (symbol)
- return symbol->d_val;
+unsigned ObjectFileELF::PLTRelocationType() {
+ // DT_PLTREL
+ // This member specifies the type of relocation entry to which the
+ // procedure linkage table refers. The d_val member holds DT_REL or
+ // DT_RELA, as appropriate. All relocations in a procedure linkage table
+ // must use the same relocation.
+ const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
- return 0;
+ if (symbol)
+ return symbol->d_val;
+
+ return 0;
}
-// Returns the size of the normal plt entries and the offset of the first normal plt entry. The
-// 0th entry in the plt table is usually a resolution entry which have different size in some
+// Returns the size of the normal plt entries and the offset of the first normal
+// plt entry. The
+// 0th entry in the plt table is usually a resolution entry which have different
+// size in some
// architectures then the rest of the plt entries.
static std::pair<uint64_t, uint64_t>
-GetPltEntrySizeAndOffset(const ELFSectionHeader* rel_hdr, const ELFSectionHeader* plt_hdr)
-{
- const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
-
- // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes.
- // So round the entsize up by the alignment if addralign is set.
- elf_xword plt_entsize = plt_hdr->sh_addralign ?
- llvm::alignTo (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
-
- // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly.
- // PLT entries relocation code in general requires multiple instruction and
- // should be greater than 4 bytes in most cases. Try to guess correct size just in case.
- if (plt_entsize <= 4)
- {
- // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the size of the plt
- // entries based on the number of entries and the size of the plt section with the
- // assumption that the size of the 0th entry is at least as big as the size of the normal
- // entries and it isn't much bigger then that.
- if (plt_hdr->sh_addralign)
- plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign / (num_relocations + 1) * plt_hdr->sh_addralign;
- else
- plt_entsize = plt_hdr->sh_size / (num_relocations + 1);
- }
-
- elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize;
-
- return std::make_pair(plt_entsize, plt_offset);
-}
-
-static unsigned
-ParsePLTRelocations(Symtab *symbol_table,
- user_id_t start_id,
- unsigned rel_type,
- const ELFHeader *hdr,
- const ELFSectionHeader *rel_hdr,
- const ELFSectionHeader *plt_hdr,
- const ELFSectionHeader *sym_hdr,
- const lldb::SectionSP &plt_section_sp,
- DataExtractor &rel_data,
- DataExtractor &symtab_data,
- DataExtractor &strtab_data)
-{
- ELFRelocation rel(rel_type);
- ELFSymbol symbol;
- lldb::offset_t offset = 0;
-
- uint64_t plt_offset, plt_entsize;
- std::tie(plt_entsize, plt_offset) = GetPltEntrySizeAndOffset(rel_hdr, plt_hdr);
- const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
-
- typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
- reloc_info_fn reloc_type;
- reloc_info_fn reloc_symbol;
-
- if (hdr->Is32Bit())
- {
- reloc_type = ELFRelocation::RelocType32;
- reloc_symbol = ELFRelocation::RelocSymbol32;
- }
+GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
+ const ELFSectionHeader *plt_hdr) {
+ const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
+
+ // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16
+ // bytes.
+ // So round the entsize up by the alignment if addralign is set.
+ elf_xword plt_entsize =
+ plt_hdr->sh_addralign
+ ? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign)
+ : plt_hdr->sh_entsize;
+
+ // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly.
+ // PLT entries relocation code in general requires multiple instruction and
+ // should be greater than 4 bytes in most cases. Try to guess correct size
+ // just in case.
+ if (plt_entsize <= 4) {
+ // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the
+ // size of the plt
+ // entries based on the number of entries and the size of the plt section
+ // with the
+ // assumption that the size of the 0th entry is at least as big as the size
+ // of the normal
+ // entries and it isn't much bigger then that.
+ if (plt_hdr->sh_addralign)
+ plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign /
+ (num_relocations + 1) * plt_hdr->sh_addralign;
else
- {
- reloc_type = ELFRelocation::RelocType64;
- reloc_symbol = ELFRelocation::RelocSymbol64;
- }
-
- unsigned slot_type = hdr->GetRelocationJumpSlotType();
- unsigned i;
- for (i = 0; i < num_relocations; ++i)
- {
- if (rel.Parse(rel_data, &offset) == false)
- break;
-
- if (reloc_type(rel) != slot_type)
- continue;
-
- lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
- if (!symbol.Parse(symtab_data, &symbol_offset))
- break;
-
- const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
- bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
- uint64_t plt_index = plt_offset + i * plt_entsize;
-
- Symbol jump_symbol(
- i + start_id, // Symbol table index
- symbol_name, // symbol name.
- is_mangled, // is the symbol name mangled?
- eSymbolTypeTrampoline, // Type of this symbol
- false, // Is this globally visible?
- false, // Is this symbol debug info?
- true, // Is this symbol a trampoline?
- true, // Is this symbol artificial?
- plt_section_sp, // Section in which this symbol is defined or null.
- plt_index, // Offset in section or symbol value.
- plt_entsize, // Size in bytes of this symbol.
- true, // Size is valid
- false, // Contains linker annotations?
- 0); // Symbol flags.
-
- symbol_table->AddSymbol(jump_symbol);
- }
-
- return i;
+ plt_entsize = plt_hdr->sh_size / (num_relocations + 1);
+ }
+
+ elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize;
+
+ return std::make_pair(plt_entsize, plt_offset);
+}
+
+static unsigned ParsePLTRelocations(
+ Symtab *symbol_table, user_id_t start_id, unsigned rel_type,
+ const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
+ const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr,
+ const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data,
+ DataExtractor &symtab_data, DataExtractor &strtab_data) {
+ ELFRelocation rel(rel_type);
+ ELFSymbol symbol;
+ lldb::offset_t offset = 0;
+
+ uint64_t plt_offset, plt_entsize;
+ std::tie(plt_entsize, plt_offset) =
+ GetPltEntrySizeAndOffset(rel_hdr, plt_hdr);
+ const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
+
+ typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
+ reloc_info_fn reloc_type;
+ reloc_info_fn reloc_symbol;
+
+ if (hdr->Is32Bit()) {
+ reloc_type = ELFRelocation::RelocType32;
+ reloc_symbol = ELFRelocation::RelocSymbol32;
+ } else {
+ reloc_type = ELFRelocation::RelocType64;
+ reloc_symbol = ELFRelocation::RelocSymbol64;
+ }
+
+ unsigned slot_type = hdr->GetRelocationJumpSlotType();
+ unsigned i;
+ for (i = 0; i < num_relocations; ++i) {
+ if (rel.Parse(rel_data, &offset) == false)
+ break;
+
+ if (reloc_type(rel) != slot_type)
+ continue;
+
+ lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
+ if (!symbol.Parse(symtab_data, &symbol_offset))
+ break;
+
+ const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
+ bool is_mangled =
+ symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
+ uint64_t plt_index = plt_offset + i * plt_entsize;
+
+ Symbol jump_symbol(
+ i + start_id, // Symbol table index
+ symbol_name, // symbol name.
+ is_mangled, // is the symbol name mangled?
+ eSymbolTypeTrampoline, // Type of this symbol
+ false, // Is this globally visible?
+ false, // Is this symbol debug info?
+ true, // Is this symbol a trampoline?
+ true, // Is this symbol artificial?
+ plt_section_sp, // Section in which this symbol is defined or null.
+ plt_index, // Offset in section or symbol value.
+ plt_entsize, // Size in bytes of this symbol.
+ true, // Size is valid
+ false, // Contains linker annotations?
+ 0); // Symbol flags.
+
+ symbol_table->AddSymbol(jump_symbol);
+ }
+
+ return i;
}
unsigned
-ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
- user_id_t start_id,
+ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
const ELFSectionHeaderInfo *rel_hdr,
- user_id_t rel_id)
-{
- assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
-
- // The link field points to the associated symbol table.
- user_id_t symtab_id = rel_hdr->sh_link;
-
- // If the link field doesn't point to the appropriate symbol name table then
- // try to find it by name as some compiler don't fill in the link fields.
- if (!symtab_id)
- symtab_id = GetSectionIndexByName(".dynsym");
+ user_id_t rel_id) {
+ assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
- // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers
- // point that to the .got.plt or .got section instead of .plt.
- user_id_t plt_id = GetSectionIndexByName(".plt");
+ // The link field points to the associated symbol table.
+ user_id_t symtab_id = rel_hdr->sh_link;
- if (!symtab_id || !plt_id)
- return 0;
+ // If the link field doesn't point to the appropriate symbol name table then
+ // try to find it by name as some compiler don't fill in the link fields.
+ if (!symtab_id)
+ symtab_id = GetSectionIndexByName(".dynsym");
- // Section ID's are ones based;
- symtab_id++;
- plt_id++;
+ // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers
+ // point that to the .got.plt or .got section instead of .plt.
+ user_id_t plt_id = GetSectionIndexByName(".plt");
- const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
- if (!plt_hdr)
- return 0;
+ if (!symtab_id || !plt_id)
+ return 0;
- const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
- if (!sym_hdr)
- return 0;
+ // Section ID's are ones based;
+ symtab_id++;
+ plt_id++;
- SectionList *section_list = m_sections_ap.get();
- if (!section_list)
- return 0;
+ const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
+ if (!plt_hdr)
+ return 0;
- Section *rel_section = section_list->FindSectionByID(rel_id).get();
- if (!rel_section)
- return 0;
+ const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
+ if (!sym_hdr)
+ return 0;
- SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
- if (!plt_section_sp)
- return 0;
+ SectionList *section_list = m_sections_ap.get();
+ if (!section_list)
+ return 0;
- Section *symtab = section_list->FindSectionByID(symtab_id).get();
- if (!symtab)
- return 0;
+ Section *rel_section = section_list->FindSectionByID(rel_id).get();
+ if (!rel_section)
+ return 0;
- // sh_link points to associated string table.
- Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
- if (!strtab)
- return 0;
+ SectionSP plt_section_sp(section_list->FindSectionByID(plt_id));
+ if (!plt_section_sp)
+ return 0;
- DataExtractor rel_data;
- if (!ReadSectionData(rel_section, rel_data))
- return 0;
+ Section *symtab = section_list->FindSectionByID(symtab_id).get();
+ if (!symtab)
+ return 0;
- DataExtractor symtab_data;
- if (!ReadSectionData(symtab, symtab_data))
- return 0;
+ // sh_link points to associated string table.
+ Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
+ if (!strtab)
+ return 0;
- DataExtractor strtab_data;
- if (!ReadSectionData(strtab, strtab_data))
- return 0;
-
- unsigned rel_type = PLTRelocationType();
- if (!rel_type)
- return 0;
-
- return ParsePLTRelocations (symbol_table,
- start_id,
- rel_type,
- &m_header,
- rel_hdr,
- plt_hdr,
- sym_hdr,
- plt_section_sp,
- rel_data,
- symtab_data,
- strtab_data);
-}
+ DataExtractor rel_data;
+ if (!ReadSectionData(rel_section, rel_data))
+ return 0;
-unsigned
-ObjectFileELF::RelocateSection(Symtab* symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
- const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
- DataExtractor &rel_data, DataExtractor &symtab_data,
- DataExtractor &debug_data, Section* rel_section)
-{
- ELFRelocation rel(rel_hdr->sh_type);
- lldb::addr_t offset = 0;
- const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
- typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
- reloc_info_fn reloc_type;
- reloc_info_fn reloc_symbol;
-
- if (hdr->Is32Bit())
- {
- reloc_type = ELFRelocation::RelocType32;
- reloc_symbol = ELFRelocation::RelocSymbol32;
- }
- else
- {
- reloc_type = ELFRelocation::RelocType64;
- reloc_symbol = ELFRelocation::RelocSymbol64;
- }
+ DataExtractor symtab_data;
+ if (!ReadSectionData(symtab, symtab_data))
+ return 0;
- for (unsigned i = 0; i < num_relocations; ++i)
- {
- if (rel.Parse(rel_data, &offset) == false)
- break;
+ DataExtractor strtab_data;
+ if (!ReadSectionData(strtab, strtab_data))
+ return 0;
- Symbol* symbol = NULL;
+ unsigned rel_type = PLTRelocationType();
+ if (!rel_type)
+ return 0;
- if (hdr->Is32Bit())
- {
- switch (reloc_type(rel)) {
- case R_386_32:
- case R_386_PC32:
- default:
- assert(false && "unexpected relocation type");
- }
- } else {
- switch (reloc_type(rel)) {
- case R_X86_64_64:
- {
- symbol = symtab->FindSymbolByID(reloc_symbol(rel));
- if (symbol)
- {
- addr_t value = symbol->GetAddressRef().GetFileAddress();
- DataBufferSP& data_buffer_sp = debug_data.GetSharedDataBuffer();
- uint64_t* dst = reinterpret_cast<uint64_t*>(data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset64(rel));
- *dst = value + ELFRelocation::RelocAddend64(rel);
- }
- break;
- }
- case R_X86_64_32:
- case R_X86_64_32S:
- {
- 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)) ||
- (reloc_type(rel) == R_X86_64_32S &&
- ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN)));
- 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;
- }
- break;
- }
- case R_X86_64_PC32:
- default:
- assert(false && "unexpected relocation type");
- }
+ return ParsePLTRelocations(symbol_table, start_id, rel_type, &m_header,
+ rel_hdr, plt_hdr, sym_hdr, plt_section_sp,
+ rel_data, symtab_data, strtab_data);
+}
+
+unsigned ObjectFileELF::RelocateSection(
+ Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
+ const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
+ DataExtractor &rel_data, DataExtractor &symtab_data,
+ DataExtractor &debug_data, Section *rel_section) {
+ ELFRelocation rel(rel_hdr->sh_type);
+ lldb::addr_t offset = 0;
+ const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
+ typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
+ reloc_info_fn reloc_type;
+ reloc_info_fn reloc_symbol;
+
+ if (hdr->Is32Bit()) {
+ reloc_type = ELFRelocation::RelocType32;
+ reloc_symbol = ELFRelocation::RelocSymbol32;
+ } else {
+ reloc_type = ELFRelocation::RelocType64;
+ reloc_symbol = ELFRelocation::RelocSymbol64;
+ }
+
+ for (unsigned i = 0; i < num_relocations; ++i) {
+ if (rel.Parse(rel_data, &offset) == false)
+ break;
+
+ Symbol *symbol = NULL;
+
+ if (hdr->Is32Bit()) {
+ switch (reloc_type(rel)) {
+ case R_386_32:
+ case R_386_PC32:
+ default:
+ assert(false && "unexpected relocation type");
+ }
+ } else {
+ switch (reloc_type(rel)) {
+ case R_X86_64_64: {
+ symbol = symtab->FindSymbolByID(reloc_symbol(rel));
+ if (symbol) {
+ addr_t value = symbol->GetAddressRef().GetFileAddress();
+ DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
+ uint64_t *dst = reinterpret_cast<uint64_t *>(
+ data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
+ ELFRelocation::RelocOffset64(rel));
+ *dst = value + ELFRelocation::RelocAddend64(rel);
}
+ break;
+ }
+ case R_X86_64_32:
+ case R_X86_64_32S: {
+ 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)) ||
+ (reloc_type(rel) == R_X86_64_32S &&
+ ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN)));
+ 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;
+ }
+ break;
+ }
+ case R_X86_64_PC32:
+ default:
+ assert(false && "unexpected relocation type");
+ }
}
+ }
- return 0;
+ return 0;
}
-unsigned
-ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, user_id_t rel_id)
-{
- assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
+unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
+ user_id_t rel_id) {
+ assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
- // Parse in the section list if needed.
- SectionList *section_list = GetSectionList();
- if (!section_list)
- return 0;
+ // Parse in the section list if needed.
+ SectionList *section_list = GetSectionList();
+ 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;
+ // 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;
- const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
- if (!symtab_hdr)
- return 0;
+ const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
+ if (!symtab_hdr)
+ return 0;
- const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
- if (!debug_hdr)
- return 0;
+ const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
+ if (!debug_hdr)
+ return 0;
- Section *rel = section_list->FindSectionByID(rel_id).get();
- if (!rel)
- return 0;
+ Section *rel = section_list->FindSectionByID(rel_id).get();
+ if (!rel)
+ return 0;
- Section *symtab = section_list->FindSectionByID(symtab_id).get();
- if (!symtab)
- return 0;
+ Section *symtab = section_list->FindSectionByID(symtab_id).get();
+ if (!symtab)
+ return 0;
- Section *debug = section_list->FindSectionByID(debug_id).get();
- if (!debug)
- return 0;
+ Section *debug = section_list->FindSectionByID(debug_id).get();
+ if (!debug)
+ return 0;
- DataExtractor rel_data;
- DataExtractor symtab_data;
- DataExtractor debug_data;
-
- if (ReadSectionData(rel, rel_data) &&
- ReadSectionData(symtab, symtab_data) &&
- ReadSectionData(debug, debug_data))
- {
- RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr, debug_hdr,
- rel_data, symtab_data, debug_data, debug);
- }
+ DataExtractor rel_data;
+ DataExtractor symtab_data;
+ DataExtractor debug_data;
- return 0;
+ if (ReadSectionData(rel, rel_data) && ReadSectionData(symtab, symtab_data) &&
+ ReadSectionData(debug, debug_data)) {
+ RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr,
+ debug_hdr, rel_data, symtab_data, debug_data, debug);
+ }
+
+ return 0;
}
-Symtab *
-ObjectFileELF::GetSymtab()
-{
- ModuleSP module_sp(GetModule());
- if (!module_sp)
- return NULL;
-
- // We always want to use the main object file so we (hopefully) only have one cached copy
- // of our symtab, dynamic sections, etc.
- ObjectFile *module_obj_file = module_sp->GetObjectFile();
- if (module_obj_file && module_obj_file != this)
- return module_obj_file->GetSymtab();
-
- if (m_symtab_ap.get() == NULL)
- {
- SectionList *section_list = module_sp->GetSectionList();
- if (!section_list)
- return NULL;
-
- uint64_t symbol_id = 0;
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-
- // Sharable objects and dynamic executables usually have 2 distinct symbol
- // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
- // version of the symtab that only contains global symbols. The information found
- // in the dynsym is therefore also found in the symtab, while the reverse is not
- // necessarily true.
- Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
- if (!symtab)
- {
- // The symtab section is non-allocable and can be stripped, so if it doesn't exist
- // then use the dynsym section which should always be there.
- symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
- }
- if (symtab)
- {
- m_symtab_ap.reset(new Symtab(symtab->GetObjectFile()));
- symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
- }
+Symtab *ObjectFileELF::GetSymtab() {
+ ModuleSP module_sp(GetModule());
+ if (!module_sp)
+ return NULL;
- // DT_JMPREL
- // If present, this entry's d_ptr member holds the address of relocation
- // entries associated solely with the procedure linkage table. Separating
- // these relocation entries lets the dynamic linker ignore them during
- // process initialization, if lazy binding is enabled. If this entry is
- // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
- // also be present.
- const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
- if (symbol)
- {
- // Synthesize trampoline symbols to help navigate the PLT.
- addr_t addr = symbol->d_ptr;
- Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
- if (reloc_section)
- {
- user_id_t reloc_id = reloc_section->GetID();
- const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
- assert(reloc_header);
-
- if (m_symtab_ap == nullptr)
- m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile()));
-
- ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
- }
- }
+ // We always want to use the main object file so we (hopefully) only have one
+ // cached copy
+ // of our symtab, dynamic sections, etc.
+ ObjectFile *module_obj_file = module_sp->GetObjectFile();
+ if (module_obj_file && module_obj_file != this)
+ return module_obj_file->GetSymtab();
- DWARFCallFrameInfo* eh_frame = GetUnwindTable().GetEHFrameInfo();
- if (eh_frame)
- {
- if (m_symtab_ap == nullptr)
- m_symtab_ap.reset(new Symtab(this));
- ParseUnwindSymbols (m_symtab_ap.get(), eh_frame);
- }
+ if (m_symtab_ap.get() == NULL) {
+ SectionList *section_list = module_sp->GetSectionList();
+ if (!section_list)
+ return NULL;
- // If we still don't have any symtab then create an empty instance to avoid do the section
- // lookup next time.
- if (m_symtab_ap == nullptr)
- m_symtab_ap.reset(new Symtab(this));
+ uint64_t symbol_id = 0;
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- m_symtab_ap->CalculateSymbolSizes();
- }
+ // Sharable objects and dynamic executables usually have 2 distinct symbol
+ // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
+ // smaller
+ // version of the symtab that only contains global symbols. The information
+ // found
+ // in the dynsym is therefore also found in the symtab, while the reverse is
+ // not
+ // necessarily true.
+ Section *symtab =
+ section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
+ if (!symtab) {
+ // The symtab section is non-allocable and can be stripped, so if it
+ // doesn't exist
+ // then use the dynsym section which should always be there.
+ symtab =
+ section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+ .get();
+ }
+ if (symtab) {
+ m_symtab_ap.reset(new Symtab(symtab->GetObjectFile()));
+ symbol_id += ParseSymbolTable(m_symtab_ap.get(), symbol_id, symtab);
+ }
+
+ // DT_JMPREL
+ // If present, this entry's d_ptr member holds the address of
+ // relocation
+ // entries associated solely with the procedure linkage table.
+ // Separating
+ // these relocation entries lets the dynamic linker ignore them during
+ // process initialization, if lazy binding is enabled. If this entry is
+ // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
+ // also be present.
+ const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
+ if (symbol) {
+ // Synthesize trampoline symbols to help navigate the PLT.
+ addr_t addr = symbol->d_ptr;
+ Section *reloc_section =
+ section_list->FindSectionContainingFileAddress(addr).get();
+ if (reloc_section) {
+ user_id_t reloc_id = reloc_section->GetID();
+ const ELFSectionHeaderInfo *reloc_header =
+ GetSectionHeaderByIndex(reloc_id);
+ assert(reloc_header);
- for (SectionHeaderCollIter I = m_section_headers.begin();
- I != m_section_headers.end(); ++I)
- {
- if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL)
- {
- if (CalculateType() == eTypeObjectFile)
- {
- const char *section_name = I->section_name.AsCString("");
- if (strstr(section_name, ".rela.debug") ||
- strstr(section_name, ".rel.debug"))
- {
- const ELFSectionHeader &reloc_header = *I;
- user_id_t reloc_id = SectionIndex(I);
- RelocateDebugSections(&reloc_header, reloc_id);
- }
- }
+ if (m_symtab_ap == nullptr)
+ m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile()));
+
+ ParseTrampolineSymbols(m_symtab_ap.get(), symbol_id, reloc_header,
+ reloc_id);
+ }
+ }
+
+ DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo();
+ if (eh_frame) {
+ if (m_symtab_ap == nullptr)
+ m_symtab_ap.reset(new Symtab(this));
+ ParseUnwindSymbols(m_symtab_ap.get(), eh_frame);
+ }
+
+ // If we still don't have any symtab then create an empty instance to avoid
+ // do the section
+ // lookup next time.
+ if (m_symtab_ap == nullptr)
+ m_symtab_ap.reset(new Symtab(this));
+
+ m_symtab_ap->CalculateSymbolSizes();
+ }
+
+ for (SectionHeaderCollIter I = m_section_headers.begin();
+ I != m_section_headers.end(); ++I) {
+ if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
+ if (CalculateType() == eTypeObjectFile) {
+ const char *section_name = I->section_name.AsCString("");
+ if (strstr(section_name, ".rela.debug") ||
+ strstr(section_name, ".rel.debug")) {
+ const ELFSectionHeader &reloc_header = *I;
+ user_id_t reloc_id = SectionIndex(I);
+ RelocateDebugSections(&reloc_header, reloc_id);
}
+ }
+ }
+ }
+ return m_symtab_ap.get();
+}
+
+void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
+ DWARFCallFrameInfo *eh_frame) {
+ SectionList *section_list = GetSectionList();
+ if (!section_list)
+ return;
+
+ // First we save the new symbols into a separate list and add them to the
+ // symbol table after
+ // we colleced all symbols we want to add. This is neccessary because adding a
+ // new symbol
+ // invalidates the internal index of the symtab what causing the next lookup
+ // to be slow because
+ // it have to recalculate the index first.
+ std::vector<Symbol> new_symbols;
+
+ eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
+ lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
+ Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
+ if (symbol) {
+ if (!symbol->GetByteSizeIsValid()) {
+ symbol->SetByteSize(size);
+ symbol->SetSizeIsSynthesized(true);
+ }
+ } else {
+ SectionSP section_sp =
+ section_list->FindSectionContainingFileAddress(file_addr);
+ if (section_sp) {
+ addr_t offset = file_addr - section_sp->GetFileAddress();
+ const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
+ uint64_t symbol_id = symbol_table->GetNumSymbols();
+ Symbol eh_symbol(
+ symbol_id, // Symbol table index.
+ symbol_name, // Symbol name.
+ false, // Is the symbol name mangled?
+ eSymbolTypeCode, // Type of this symbol.
+ true, // Is this globally visible?
+ false, // Is this symbol debug info?
+ false, // Is this symbol a trampoline?
+ true, // Is this symbol artificial?
+ section_sp, // Section in which this symbol is defined or null.
+ offset, // Offset in section or symbol value.
+ 0, // Size: Don't specify the size as an FDE can
+ false, // Size is valid: cover multiple symbols.
+ false, // Contains linker annotations?
+ 0); // Symbol flags.
+ new_symbols.push_back(eh_symbol);
+ }
}
- return m_symtab_ap.get();
-}
-
-void
-ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, DWARFCallFrameInfo* eh_frame)
-{
- SectionList* section_list = GetSectionList();
- if (!section_list)
- return;
-
- // First we save the new symbols into a separate list and add them to the symbol table after
- // we colleced all symbols we want to add. This is neccessary because adding a new symbol
- // invalidates the internal index of the symtab what causing the next lookup to be slow because
- // it have to recalculate the index first.
- std::vector<Symbol> new_symbols;
-
- eh_frame->ForEachFDEEntries(
- [this, symbol_table, section_list, &new_symbols](lldb::addr_t file_addr,
- uint32_t size,
- dw_offset_t) {
- Symbol* symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
- if (symbol)
- {
- if (!symbol->GetByteSizeIsValid())
- {
- symbol->SetByteSize(size);
- symbol->SetSizeIsSynthesized(true);
- }
- }
- else
- {
- SectionSP section_sp = section_list->FindSectionContainingFileAddress(file_addr);
- if (section_sp)
- {
- addr_t offset = file_addr - section_sp->GetFileAddress();
- const char* symbol_name = GetNextSyntheticSymbolName().GetCString();
- uint64_t symbol_id = symbol_table->GetNumSymbols();
- Symbol eh_symbol(
- symbol_id, // Symbol table index.
- symbol_name, // Symbol name.
- false, // Is the symbol name mangled?
- eSymbolTypeCode, // Type of this symbol.
- true, // Is this globally visible?
- false, // Is this symbol debug info?
- false, // Is this symbol a trampoline?
- true, // Is this symbol artificial?
- section_sp, // Section in which this symbol is defined or null.
- offset, // Offset in section or symbol value.
- 0, // Size: Don't specify the size as an FDE can
- false, // Size is valid: cover multiple symbols.
- false, // Contains linker annotations?
- 0); // Symbol flags.
- new_symbols.push_back(eh_symbol);
- }
- }
- return true;
- });
+ return true;
+ });
- for (const Symbol& s : new_symbols)
- symbol_table->AddSymbol(s);
+ for (const Symbol &s : new_symbols)
+ symbol_table->AddSymbol(s);
}
-bool
-ObjectFileELF::IsStripped ()
-{
- // TODO: determine this for ELF
- return false;
+bool ObjectFileELF::IsStripped() {
+ // TODO: determine this for ELF
+ return false;
}
//===----------------------------------------------------------------------===//
@@ -3130,40 +3000,38 @@ ObjectFileELF::IsStripped ()
// Dump the specifics of the runtime file container (such as any headers
// segments, sections, etc).
//----------------------------------------------------------------------
-void
-ObjectFileELF::Dump(Stream *s)
-{
- ModuleSP module_sp(GetModule());
- if (!module_sp)
- {
- return;
- }
-
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- s->Printf("%p: ", static_cast<void *>(this));
- s->Indent();
- s->PutCString("ObjectFileELF");
-
- ArchSpec header_arch;
- GetArchitecture(header_arch);
-
- *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
-
- DumpELFHeader(s, m_header);
- s->EOL();
- DumpELFProgramHeaders(s);
- s->EOL();
- DumpELFSectionHeaders(s);
- s->EOL();
- SectionList *section_list = GetSectionList();
- if (section_list)
- section_list->Dump(s, NULL, true, UINT32_MAX);
- Symtab *symtab = GetSymtab();
- if (symtab)
- symtab->Dump(s, NULL, eSortOrderNone);
- s->EOL();
- DumpDependentModules(s);
- s->EOL();
+void ObjectFileELF::Dump(Stream *s) {
+ ModuleSP module_sp(GetModule());
+ if (!module_sp) {
+ return;
+ }
+
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ s->Printf("%p: ", static_cast<void *>(this));
+ s->Indent();
+ s->PutCString("ObjectFileELF");
+
+ ArchSpec header_arch;
+ GetArchitecture(header_arch);
+
+ *s << ", file = '" << m_file
+ << "', arch = " << header_arch.GetArchitectureName() << "\n";
+
+ DumpELFHeader(s, m_header);
+ s->EOL();
+ DumpELFProgramHeaders(s);
+ s->EOL();
+ DumpELFSectionHeaders(s);
+ s->EOL();
+ SectionList *section_list = GetSectionList();
+ if (section_list)
+ section_list->Dump(s, NULL, true, UINT32_MAX);
+ Symtab *symtab = GetSymtab();
+ if (symtab)
+ symtab->Dump(s, NULL, eSortOrderNone);
+ s->EOL();
+ DumpDependentModules(s);
+ s->EOL();
}
//----------------------------------------------------------------------
@@ -3171,38 +3039,36 @@ ObjectFileELF::Dump(Stream *s)
//
// Dump the ELF header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
-{
- s->PutCString("ELF Header\n");
- s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
- s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
- header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
- s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
- header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
- s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
- header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
-
- s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
- s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
- DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
- s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
- s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
-
- s->Printf("e_type = 0x%4.4x ", header.e_type);
- DumpELFHeader_e_type(s, header.e_type);
- s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
- s->Printf("e_version = 0x%8.8x\n", header.e_version);
- s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
- s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
- s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
- s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
- s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
- s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
- s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
- s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
- s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
- s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
+void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {
+ s->PutCString("ELF Header\n");
+ s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
+ s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1],
+ header.e_ident[EI_MAG1]);
+ s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2],
+ header.e_ident[EI_MAG2]);
+ s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3],
+ header.e_ident[EI_MAG3]);
+
+ s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
+ s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
+ DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
+ s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
+ s->Printf("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
+
+ s->Printf("e_type = 0x%4.4x ", header.e_type);
+ DumpELFHeader_e_type(s, header.e_type);
+ s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
+ s->Printf("e_version = 0x%8.8x\n", header.e_version);
+ s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
+ s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
+ s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
+ s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
+ s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
+ s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
+ s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
+ s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
+ s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
+ s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
}
//----------------------------------------------------------------------
@@ -3210,19 +3076,26 @@ ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
//
// Dump an token value for the ELF header member e_type
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
-{
- switch (e_type)
- {
- case ET_NONE: *s << "ET_NONE"; break;
- case ET_REL: *s << "ET_REL"; break;
- case ET_EXEC: *s << "ET_EXEC"; break;
- case ET_DYN: *s << "ET_DYN"; break;
- case ET_CORE: *s << "ET_CORE"; break;
- default:
- break;
- }
+void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {
+ switch (e_type) {
+ case ET_NONE:
+ *s << "ET_NONE";
+ break;
+ case ET_REL:
+ *s << "ET_REL";
+ break;
+ case ET_EXEC:
+ *s << "ET_EXEC";
+ break;
+ case ET_DYN:
+ *s << "ET_DYN";
+ break;
+ case ET_CORE:
+ *s << "ET_CORE";
+ break;
+ default:
+ break;
+ }
}
//----------------------------------------------------------------------
@@ -3230,34 +3103,38 @@ ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
//
// Dump an token value for the ELF header member e_ident[EI_DATA]
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
-{
- switch (ei_data)
- {
- case ELFDATANONE: *s << "ELFDATANONE"; break;
- case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
- case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
- default:
- break;
- }
+void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,
+ unsigned char ei_data) {
+ switch (ei_data) {
+ case ELFDATANONE:
+ *s << "ELFDATANONE";
+ break;
+ case ELFDATA2LSB:
+ *s << "ELFDATA2LSB - Little Endian";
+ break;
+ case ELFDATA2MSB:
+ *s << "ELFDATA2MSB - Big Endian";
+ break;
+ default:
+ break;
+ }
}
-
//----------------------------------------------------------------------
// DumpELFProgramHeader
//
// Dump a single ELF program header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
-{
- DumpELFProgramHeader_p_type(s, ph.p_type);
- s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
- s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags);
+void ObjectFileELF::DumpELFProgramHeader(Stream *s,
+ const ELFProgramHeader &ph) {
+ DumpELFProgramHeader_p_type(s, ph.p_type);
+ s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset,
+ ph.p_vaddr, ph.p_paddr);
+ s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz,
+ ph.p_flags);
- DumpELFProgramHeader_p_flags(s, ph.p_flags);
- s->Printf(") %8.8" PRIx64, ph.p_align);
+ DumpELFProgramHeader_p_flags(s, ph.p_flags);
+ s->Printf(") %8.8" PRIx64, ph.p_align);
}
//----------------------------------------------------------------------
@@ -3266,41 +3143,35 @@ ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
// Dump an token value for the ELF program header member p_type which
// describes the type of the program header
// ----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
-{
- const int kStrWidth = 15;
- switch (p_type)
- {
- CASE_AND_STREAM(s, PT_NULL , kStrWidth);
- CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
- CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
- CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
- CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
- CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
- CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
- CASE_AND_STREAM(s, PT_TLS , kStrWidth);
+void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {
+ const int kStrWidth = 15;
+ switch (p_type) {
+ CASE_AND_STREAM(s, PT_NULL, kStrWidth);
+ CASE_AND_STREAM(s, PT_LOAD, kStrWidth);
+ CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth);
+ CASE_AND_STREAM(s, PT_INTERP, kStrWidth);
+ CASE_AND_STREAM(s, PT_NOTE, kStrWidth);
+ CASE_AND_STREAM(s, PT_SHLIB, kStrWidth);
+ CASE_AND_STREAM(s, PT_PHDR, kStrWidth);
+ CASE_AND_STREAM(s, PT_TLS, kStrWidth);
CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
- default:
- s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
- break;
- }
+ default:
+ s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
+ break;
+ }
}
-
//----------------------------------------------------------------------
// DumpELFProgramHeader_p_flags
//
// Dump an token value for the ELF program header member p_flags
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
-{
- *s << ((p_flags & PF_X) ? "PF_X" : " ")
- << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
- << ((p_flags & PF_W) ? "PF_W" : " ")
- << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
- << ((p_flags & PF_R) ? "PF_R" : " ");
+void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {
+ *s << ((p_flags & PF_X) ? "PF_X" : " ")
+ << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
+ << ((p_flags & PF_W) ? "PF_W" : " ")
+ << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
+ << ((p_flags & PF_R) ? "PF_R" : " ");
}
//----------------------------------------------------------------------
@@ -3308,26 +3179,23 @@ ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
//
// Dump all of the ELF program header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFProgramHeaders(Stream *s)
-{
- if (!ParseProgramHeaders())
- return;
-
- s->PutCString("Program Headers\n");
- s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
- "p_filesz p_memsz p_flags p_align\n");
- 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);
- s->EOL();
- }
+void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {
+ if (!ParseProgramHeaders())
+ return;
+
+ s->PutCString("Program Headers\n");
+ s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
+ "p_filesz p_memsz p_flags p_align\n");
+ 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);
+ s->EOL();
+ }
}
//----------------------------------------------------------------------
@@ -3335,16 +3203,16 @@ ObjectFileELF::DumpELFProgramHeaders(Stream *s)
//
// Dump a single ELF section header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
-{
- s->Printf("%8.8x ", sh.sh_name);
- DumpELFSectionHeader_sh_type(s, sh.sh_type);
- s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
- DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
- s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr, sh.sh_offset, sh.sh_size);
- s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
- s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
+void ObjectFileELF::DumpELFSectionHeader(Stream *s,
+ const ELFSectionHeaderInfo &sh) {
+ s->Printf("%8.8x ", sh.sh_name);
+ DumpELFSectionHeader_sh_type(s, sh.sh_type);
+ s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
+ DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
+ s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr,
+ sh.sh_offset, sh.sh_size);
+ s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
+ s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
}
//----------------------------------------------------------------------
@@ -3353,32 +3221,29 @@ ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
// Dump an token value for the ELF section header member sh_type which
// describes the type of the section
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
-{
- const int kStrWidth = 12;
- switch (sh_type)
- {
- CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
- CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
- CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
- CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
- CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
- CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
- CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
- CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
- CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
- CASE_AND_STREAM(s, SHT_REL , kStrWidth);
- CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
- CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
- CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
- CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
- CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
- CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
- default:
- s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
- break;
- }
+void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {
+ const int kStrWidth = 12;
+ switch (sh_type) {
+ CASE_AND_STREAM(s, SHT_NULL, kStrWidth);
+ CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth);
+ CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth);
+ CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth);
+ CASE_AND_STREAM(s, SHT_RELA, kStrWidth);
+ CASE_AND_STREAM(s, SHT_HASH, kStrWidth);
+ CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth);
+ CASE_AND_STREAM(s, SHT_NOTE, kStrWidth);
+ CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth);
+ CASE_AND_STREAM(s, SHT_REL, kStrWidth);
+ CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth);
+ CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth);
+ CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth);
+ CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth);
+ CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth);
+ CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth);
+ default:
+ s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
+ break;
+ }
}
//----------------------------------------------------------------------
@@ -3386,14 +3251,13 @@ ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
//
// Dump an token value for the ELF section header member sh_flags
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
-{
- *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
- << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
- << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
- << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
- << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
+void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,
+ elf_xword sh_flags) {
+ *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
+ << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
+ << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
+ << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
+ << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
}
//----------------------------------------------------------------------
@@ -3401,153 +3265,135 @@ ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
//
// Dump all of the ELF section header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFileELF::DumpELFSectionHeaders(Stream *s)
-{
- if (!ParseSectionHeaders())
- return;
-
- s->PutCString("Section Headers\n");
- s->PutCString("IDX name type flags "
- "addr offset size link info addralgn "
- "entsize Name\n");
- s->PutCString("==== -------- ------------ -------------------------------- "
- "-------- -------- -------- -------- -------- -------- "
- "-------- ====================\n");
-
- uint32_t idx = 0;
- for (SectionHeaderCollConstIter I = m_section_headers.begin();
- I != m_section_headers.end(); ++I, ++idx)
- {
- s->Printf("[%2u] ", idx);
- ObjectFileELF::DumpELFSectionHeader(s, *I);
- const char* section_name = I->section_name.AsCString("");
- if (section_name)
- *s << ' ' << section_name << "\n";
- }
-}
-
-void
-ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
-{
- size_t num_modules = ParseDependentModules();
+void ObjectFileELF::DumpELFSectionHeaders(Stream *s) {
+ if (!ParseSectionHeaders())
+ return;
+
+ s->PutCString("Section Headers\n");
+ s->PutCString("IDX name type flags "
+ "addr offset size link info addralgn "
+ "entsize Name\n");
+ s->PutCString("==== -------- ------------ -------------------------------- "
+ "-------- -------- -------- -------- -------- -------- "
+ "-------- ====================\n");
+
+ uint32_t idx = 0;
+ for (SectionHeaderCollConstIter I = m_section_headers.begin();
+ I != m_section_headers.end(); ++I, ++idx) {
+ s->Printf("[%2u] ", idx);
+ ObjectFileELF::DumpELFSectionHeader(s, *I);
+ const char *section_name = I->section_name.AsCString("");
+ if (section_name)
+ *s << ' ' << section_name << "\n";
+ }
+}
+
+void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) {
+ size_t num_modules = ParseDependentModules();
+
+ if (num_modules > 0) {
+ s->PutCString("Dependent Modules:\n");
+ for (unsigned i = 0; i < num_modules; ++i) {
+ const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
+ s->Printf(" %s\n", spec.GetFilename().GetCString());
+ }
+ }
+}
+
+bool ObjectFileELF::GetArchitecture(ArchSpec &arch) {
+ if (!ParseHeader())
+ return false;
- if (num_modules > 0)
- {
- s->PutCString("Dependent Modules:\n");
- for (unsigned i = 0; i < num_modules; ++i)
- {
- const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
- s->Printf(" %s\n", spec.GetFilename().GetCString());
+ if (m_section_headers.empty()) {
+ // Allow elf notes to be parsed which may affect the detected architecture.
+ ParseSectionHeaders();
+ }
+
+ if (CalculateType() == eTypeCoreFile &&
+ m_arch_spec.TripleOSIsUnspecifiedUnknown()) {
+ // Core files don't have section headers yet they have PT_NOTE program
+ // headers
+ // that might shed more light on the architecture
+ if (ParseProgramHeaders()) {
+ for (size_t i = 0, 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);
+ }
}
+ }
}
+ }
+ arch = m_arch_spec;
+ return true;
}
-bool
-ObjectFileELF::GetArchitecture (ArchSpec &arch)
-{
- if (!ParseHeader())
- return false;
+ObjectFile::Type ObjectFileELF::CalculateType() {
+ switch (m_header.e_type) {
+ case llvm::ELF::ET_NONE:
+ // 0 - No file type
+ return eTypeUnknown;
- if (m_section_headers.empty())
- {
- // Allow elf notes to be parsed which may affect the detected architecture.
- ParseSectionHeaders();
- }
+ case llvm::ELF::ET_REL:
+ // 1 - Relocatable file
+ return eTypeObjectFile;
- if (CalculateType() == eTypeCoreFile && m_arch_spec.TripleOSIsUnspecifiedUnknown())
- {
- // Core files don't have section headers yet they have PT_NOTE program headers
- // that might shed more light on the architecture
- if (ParseProgramHeaders())
- {
- for (size_t i = 0, 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);
- }
- }
- }
- }
- }
- arch = m_arch_spec;
- return true;
-}
+ case llvm::ELF::ET_EXEC:
+ // 2 - Executable file
+ return eTypeExecutable;
-ObjectFile::Type
-ObjectFileELF::CalculateType()
-{
- switch (m_header.e_type)
- {
- case llvm::ELF::ET_NONE:
- // 0 - No file type
- return eTypeUnknown;
+ case llvm::ELF::ET_DYN:
+ // 3 - Shared object file
+ return eTypeSharedLibrary;
- case llvm::ELF::ET_REL:
- // 1 - Relocatable file
- return eTypeObjectFile;
+ case ET_CORE:
+ // 4 - Core file
+ return eTypeCoreFile;
- case llvm::ELF::ET_EXEC:
- // 2 - Executable file
- return eTypeExecutable;
+ default:
+ break;
+ }
+ return eTypeUnknown;
+}
- case llvm::ELF::ET_DYN:
- // 3 - Shared object file
- return eTypeSharedLibrary;
+ObjectFile::Strata ObjectFileELF::CalculateStrata() {
+ switch (m_header.e_type) {
+ case llvm::ELF::ET_NONE:
+ // 0 - No file type
+ return eStrataUnknown;
- case ET_CORE:
- // 4 - Core file
- return eTypeCoreFile;
+ case llvm::ELF::ET_REL:
+ // 1 - Relocatable file
+ return eStrataUnknown;
- default:
- break;
- }
- return eTypeUnknown;
-}
+ case llvm::ELF::ET_EXEC:
+ // 2 - Executable file
+ // TODO: is there any way to detect that an executable is a kernel
+ // related executable by inspecting the program headers, section
+ // headers, symbols, or any other flag bits???
+ return eStrataUser;
+
+ case llvm::ELF::ET_DYN:
+ // 3 - Shared object file
+ // TODO: is there any way to detect that an shared library is a kernel
+ // related executable by inspecting the program headers, section
+ // headers, symbols, or any other flag bits???
+ return eStrataUnknown;
-ObjectFile::Strata
-ObjectFileELF::CalculateStrata()
-{
- switch (m_header.e_type)
- {
- case llvm::ELF::ET_NONE:
- // 0 - No file type
- return eStrataUnknown;
-
- case llvm::ELF::ET_REL:
- // 1 - Relocatable file
- return eStrataUnknown;
-
- case llvm::ELF::ET_EXEC:
- // 2 - Executable file
- // TODO: is there any way to detect that an executable is a kernel
- // related executable by inspecting the program headers, section
- // headers, symbols, or any other flag bits???
- return eStrataUser;
-
- case llvm::ELF::ET_DYN:
- // 3 - Shared object file
- // TODO: is there any way to detect that an shared library is a kernel
- // related executable by inspecting the program headers, section
- // headers, symbols, or any other flag bits???
- return eStrataUnknown;
-
- case ET_CORE:
- // 4 - Core file
- // TODO: is there any way to detect that an core file is a kernel
- // related executable by inspecting the program headers, section
- // headers, symbols, or any other flag bits???
- return eStrataUnknown;
-
- default:
- break;
- }
+ case ET_CORE:
+ // 4 - Core file
+ // TODO: is there any way to detect that an core file is a kernel
+ // related executable by inspecting the program headers, section
+ // headers, symbols, or any other flag bits???
return eStrataUnknown;
-}
+ default:
+ break;
+ }
+ return eStrataUnknown;
+}
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index e2f73f53ec63..4ce5648cfed5 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -19,46 +19,40 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Core/UUID.h"
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/lldb-private.h"
#include "ELFHeader.h"
-struct ELFNote
-{
- elf::elf_word n_namesz;
- elf::elf_word n_descsz;
- elf::elf_word n_type;
-
- std::string n_name;
-
- ELFNote() : n_namesz(0), n_descsz(0), n_type(0)
- {
- }
-
- /// Parse an ELFNote entry from the given DataExtractor starting at position
- /// \p offset.
- ///
- /// @param[in] data
- /// The DataExtractor to read from.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFRel entry was successfully read and false otherwise.
- bool
- Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
-
- size_t
- GetByteSize() const
- {
- return 12 + llvm::alignTo (n_namesz, 4) + llvm::alignTo (n_descsz, 4);
- }
+struct ELFNote {
+ elf::elf_word n_namesz;
+ elf::elf_word n_descsz;
+ elf::elf_word n_type;
+
+ std::string n_name;
+
+ ELFNote() : n_namesz(0), n_descsz(0), n_type(0) {}
+
+ /// Parse an ELFNote entry from the given DataExtractor starting at position
+ /// \p offset.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFRel entry was successfully read and false otherwise.
+ bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+
+ size_t GetByteSize() const {
+ return 12 + llvm::alignTo(n_namesz, 4) + llvm::alignTo(n_descsz, 4);
+ }
};
//------------------------------------------------------------------------------
@@ -67,390 +61,332 @@ struct ELFNote
///
/// This class provides a generic ELF (32/64 bit) reader plugin implementing the
/// ObjectFile protocol.
-class ObjectFileELF :
- public lldb_private::ObjectFile
-{
+class ObjectFileELF : public lldb_private::ObjectFile {
public:
- ~ObjectFileELF() override;
+ ~ObjectFileELF() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::ObjectFile *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length);
+
+ static lldb_private::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 lldb_private::FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb_private::ModuleSpecList &specs);
+
+ static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,
+ lldb::addr_t length);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ //------------------------------------------------------------------
+ // ObjectFile Protocol.
+ //------------------------------------------------------------------
+ bool ParseHeader() override;
+
+ bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
+ bool value_is_offset) override;
+
+ lldb::ByteOrder GetByteOrder() const override;
+
+ bool IsExecutable() const override;
+
+ uint32_t GetAddressByteSize() const override;
+
+ lldb::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
+
+ lldb_private::Symtab *GetSymtab() override;
+
+ bool IsStripped() override;
+
+ void CreateSections(lldb_private::SectionList &unified_section_list) override;
+
+ void Dump(lldb_private::Stream *s) override;
+
+ bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+
+ bool GetUUID(lldb_private::UUID *uuid) override;
+
+ lldb_private::FileSpecList GetDebugSymbolFilePaths() override;
+
+ uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
+
+ lldb_private::Address
+ GetImageInfoAddress(lldb_private::Target *target) override;
+
+ lldb_private::Address GetEntryPointAddress() override;
+
+ ObjectFile::Type CalculateType() override;
+
+ ObjectFile::Strata CalculateStrata() 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);
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::ObjectFile *
- CreateInstance(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length);
-
- static lldb_private::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 lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool
- MagicBytesMatch (lldb::DataBufferSP& data_sp,
- lldb::addr_t offset,
- lldb::addr_t length);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // ObjectFile Protocol.
- //------------------------------------------------------------------
- bool
- ParseHeader() override;
-
- bool
- SetLoadAddress (lldb_private::Target &target,
- lldb::addr_t value,
- bool value_is_offset) override;
-
- lldb::ByteOrder
- GetByteOrder() const override;
-
- bool
- IsExecutable () const override;
-
- uint32_t
- GetAddressByteSize() const override;
-
- lldb::AddressClass
- GetAddressClass (lldb::addr_t file_addr) override;
-
- lldb_private::Symtab *
- GetSymtab() override;
-
- bool
- IsStripped () override;
-
- void
- CreateSections (lldb_private::SectionList &unified_section_list) override;
-
- void
- Dump(lldb_private::Stream *s) override;
-
- bool
- GetArchitecture (lldb_private::ArchSpec &arch) override;
-
- bool
- GetUUID(lldb_private::UUID* uuid) override;
-
- lldb_private::FileSpecList
- GetDebugSymbolFilePaths() override;
-
- uint32_t
- GetDependentModules(lldb_private::FileSpecList& files) override;
-
- lldb_private::Address
- GetImageInfoAddress(lldb_private::Target *target) override;
-
- lldb_private::Address
- GetEntryPointAddress () override;
-
- ObjectFile::Type
- CalculateType() override;
-
- ObjectFile::Strata
- CalculateStrata() 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);
-
- std::string
- StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;
+ std::string
+ StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;
private:
- ObjectFileELF(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t offset,
- lldb::offset_t length);
-
- ObjectFileELF (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& header_data_sp,
- 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;
- };
-
- typedef std::vector<ELFSectionHeaderInfo> SectionHeaderColl;
- typedef SectionHeaderColl::iterator SectionHeaderCollIter;
- typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
-
- typedef std::vector<elf::ELFDynamic> DynamicSymbolColl;
- typedef DynamicSymbolColl::iterator DynamicSymbolCollIter;
- typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;
-
- typedef std::map<lldb::addr_t, lldb::AddressClass> FileAddressToAddressClassMap;
- typedef std::function<lldb::offset_t (lldb_private::DataExtractor &, lldb::offset_t, lldb::offset_t)> SetDataFunction;
-
- /// Version of this reader common to all plugins based on this class.
- static const uint32_t m_plugin_version = 1;
- static const uint32_t g_core_uuid_magic;
-
- /// ELF file header.
- elf::ELFHeader m_header;
-
- /// ELF build ID.
- lldb_private::UUID m_uuid;
-
- /// ELF .gnu_debuglink file and crc data if available.
- std::string m_gnu_debuglink_file;
- uint32_t m_gnu_debuglink_crc;
-
- /// Collection of program headers.
- ProgramHeaderColl m_program_headers;
-
- /// Collection of section headers.
- SectionHeaderColl m_section_headers;
-
- /// Collection of symbols from the dynamic table.
- DynamicSymbolColl m_dynamic_symbols;
-
- /// List of file specifications corresponding to the modules (shared
- /// libraries) on which this object file depends.
- mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap;
-
- /// Cached value of the entry point for this module.
- lldb_private::Address m_entry_point_address;
-
- /// The architecture detected from parsing elf file contents.
- lldb_private::ArchSpec m_arch_spec;
-
- /// 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.
- size_t
- SectionIndex(const SectionHeaderCollIter &I);
-
- /// Returns a 1 based index of the given section header.
- size_t
- SectionIndex(const SectionHeaderCollConstIter &I) const;
-
- // Parses the ELF program headers.
- static size_t
- GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
- const SetDataFunction &set_data,
- const elf::ELFHeader &header);
-
- // Finds PT_NOTE segments and calculates their crc sum.
- static uint32_t
- CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl& program_headers,
- lldb_private::DataExtractor &data);
-
- /// 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();
-
- /// 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();
-
- static void
- ParseARMAttributes(lldb_private::DataExtractor &data, uint64_t length,
- lldb_private::ArchSpec &arch_spec);
-
- /// Parses the elf section headers and returns the uuid, debug link name, crc, archspec.
- static size_t
- GetSectionHeaderInfo(SectionHeaderColl &section_headers,
- const SetDataFunction &set_data,
- const elf::ELFHeader &header,
- lldb_private::UUID &uuid,
- std::string &gnu_debuglink_file,
- uint32_t &gnu_debuglink_crc,
- lldb_private::ArchSpec &arch_spec);
-
- /// Scans the dynamic section and locates all dependent modules (shared
- /// libraries) populating m_filespec_ap. This method will compute the
- /// dependent module list only once. Returns the number of dependent
- /// modules parsed.
- size_t
- ParseDependentModules();
-
- /// Parses the dynamic symbol table and populates m_dynamic_symbols. The
- /// vector retains the order as found in the object file. Returns the
- /// number of dynamic symbols parsed.
- size_t
- ParseDynamicSymbols();
-
- /// Populates m_symtab_ap will all non-dynamic linker symbols. This method
- /// will parse the symbols only once. Returns the number of symbols parsed.
- unsigned
- ParseSymbolTable(lldb_private::Symtab *symbol_table,
- lldb::user_id_t start_id,
- lldb_private::Section *symtab);
-
- /// Helper routine for ParseSymbolTable().
- unsigned
- ParseSymbols(lldb_private::Symtab *symbol_table,
- lldb::user_id_t start_id,
- lldb_private::SectionList *section_list,
- const size_t num_symbols,
- const lldb_private::DataExtractor &symtab_data,
- const lldb_private::DataExtractor &strtab_data);
-
- /// Scans the relocation entries and adds a set of artificial symbols to the
- /// given symbol table for each PLT slot. Returns the number of symbols
- /// added.
- unsigned
- ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,
- lldb::user_id_t start_id,
- const ELFSectionHeaderInfo *rela_hdr,
- lldb::user_id_t section_id);
-
- void
- ParseUnwindSymbols(lldb_private::Symtab *symbol_table,
- lldb_private::DWARFCallFrameInfo* eh_frame);
-
- /// Relocates debug sections
- unsigned
- RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, lldb::user_id_t rel_id);
-
- unsigned
- RelocateSection(lldb_private::Symtab* symtab, const elf::ELFHeader *hdr, const elf::ELFSectionHeader *rel_hdr,
- const elf::ELFSectionHeader *symtab_hdr, const elf::ELFSectionHeader *debug_hdr,
- lldb_private::DataExtractor &rel_data, lldb_private::DataExtractor &symtab_data,
- lldb_private::DataExtractor &debug_data, lldb_private::Section* rel_section);
-
- /// Loads the section name string table into m_shstr_data. Returns the
- /// number of bytes constituting the table.
- size_t
- GetSectionHeaderStringTable();
-
- /// Utility method for looking up a section given its name. Returns the
- /// index of the corresponding section or zero if no section with the given
- /// name can be found (note that section indices are always 1 based, and so
- /// section index 0 is never valid).
- lldb::user_id_t
- GetSectionIndexByName(const char *name);
-
- // Returns the ID of the first section that has the given type.
- lldb::user_id_t
- GetSectionIndexByType(unsigned type);
-
- /// Returns the section header with the given id or NULL.
- const ELFSectionHeaderInfo *
- GetSectionHeaderByIndex(lldb::user_id_t id);
-
- /// @name ELF header dump routines
- //@{
- static void
- DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader& header);
-
- static void
- DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
- unsigned char ei_data);
-
- static void
- DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type);
- //@}
-
- /// @name ELF program header dump routines
- //@{
- void
- DumpELFProgramHeaders(lldb_private::Stream *s);
-
- static void
- DumpELFProgramHeader(lldb_private::Stream *s,
- const elf::ELFProgramHeader &ph);
-
- static void
- DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type);
-
- static void
- DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
- elf::elf_word p_flags);
- //@}
-
- /// @name ELF section header dump routines
- //@{
- void
- DumpELFSectionHeaders(lldb_private::Stream *s);
-
- static void
- DumpELFSectionHeader(lldb_private::Stream *s,
- const ELFSectionHeaderInfo& sh);
-
- static void
- DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
- elf::elf_word sh_type);
-
- static void
- DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
- elf::elf_xword sh_flags);
- //@}
-
- /// ELF dependent module dump routine.
- void
- DumpDependentModules(lldb_private::Stream *s);
-
- const elf::ELFDynamic *
- FindDynamicSymbol(unsigned tag);
-
- unsigned
- PLTRelocationType();
-
- static lldb_private::Error
- RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid);
-
-
- static lldb::offset_t
- SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length);
-
- lldb::offset_t
- SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length);
+ ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+
+ ObjectFileELF(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &header_data_sp,
+ 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;
+ };
+
+ typedef std::vector<ELFSectionHeaderInfo> SectionHeaderColl;
+ typedef SectionHeaderColl::iterator SectionHeaderCollIter;
+ typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
+
+ typedef std::vector<elf::ELFDynamic> DynamicSymbolColl;
+ typedef DynamicSymbolColl::iterator DynamicSymbolCollIter;
+ typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;
+
+ typedef std::map<lldb::addr_t, lldb::AddressClass>
+ FileAddressToAddressClassMap;
+ typedef std::function<lldb::offset_t(lldb_private::DataExtractor &,
+ lldb::offset_t, lldb::offset_t)>
+ SetDataFunction;
+
+ /// Version of this reader common to all plugins based on this class.
+ static const uint32_t m_plugin_version = 1;
+ static const uint32_t g_core_uuid_magic;
+
+ /// ELF file header.
+ elf::ELFHeader m_header;
+
+ /// ELF build ID.
+ lldb_private::UUID m_uuid;
+
+ /// ELF .gnu_debuglink file and crc data if available.
+ std::string m_gnu_debuglink_file;
+ uint32_t m_gnu_debuglink_crc;
+
+ /// Collection of program headers.
+ ProgramHeaderColl m_program_headers;
+
+ /// Collection of section headers.
+ SectionHeaderColl m_section_headers;
+
+ /// Collection of symbols from the dynamic table.
+ DynamicSymbolColl m_dynamic_symbols;
+
+ /// List of file specifications corresponding to the modules (shared
+ /// libraries) on which this object file depends.
+ mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap;
+
+ /// Cached value of the entry point for this module.
+ lldb_private::Address m_entry_point_address;
+
+ /// The architecture detected from parsing elf file contents.
+ lldb_private::ArchSpec m_arch_spec;
+
+ /// 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.
+ size_t SectionIndex(const SectionHeaderCollIter &I);
+
+ /// Returns a 1 based index of the given section header.
+ size_t SectionIndex(const SectionHeaderCollConstIter &I) const;
+
+ // Parses the ELF program headers.
+ static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
+ const SetDataFunction &set_data,
+ const elf::ELFHeader &header);
+
+ // Finds PT_NOTE segments and calculates their crc sum.
+ static uint32_t
+ CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl &program_headers,
+ lldb_private::DataExtractor &data);
+
+ /// 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();
+
+ /// 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();
+
+ static void ParseARMAttributes(lldb_private::DataExtractor &data,
+ uint64_t length,
+ lldb_private::ArchSpec &arch_spec);
+
+ /// Parses the elf section headers and returns the uuid, debug link name, crc,
+ /// archspec.
+ static size_t GetSectionHeaderInfo(SectionHeaderColl &section_headers,
+ const SetDataFunction &set_data,
+ const elf::ELFHeader &header,
+ lldb_private::UUID &uuid,
+ std::string &gnu_debuglink_file,
+ uint32_t &gnu_debuglink_crc,
+ lldb_private::ArchSpec &arch_spec);
+
+ /// Scans the dynamic section and locates all dependent modules (shared
+ /// libraries) populating m_filespec_ap. This method will compute the
+ /// dependent module list only once. Returns the number of dependent
+ /// modules parsed.
+ size_t ParseDependentModules();
+
+ /// Parses the dynamic symbol table and populates m_dynamic_symbols. The
+ /// vector retains the order as found in the object file. Returns the
+ /// number of dynamic symbols parsed.
+ size_t ParseDynamicSymbols();
+
+ /// Populates m_symtab_ap will all non-dynamic linker symbols. This method
+ /// will parse the symbols only once. Returns the number of symbols parsed.
+ unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table,
+ lldb::user_id_t start_id,
+ lldb_private::Section *symtab);
+
+ /// Helper routine for ParseSymbolTable().
+ unsigned ParseSymbols(lldb_private::Symtab *symbol_table,
+ lldb::user_id_t start_id,
+ lldb_private::SectionList *section_list,
+ const size_t num_symbols,
+ const lldb_private::DataExtractor &symtab_data,
+ const lldb_private::DataExtractor &strtab_data);
+
+ /// Scans the relocation entries and adds a set of artificial symbols to the
+ /// given symbol table for each PLT slot. Returns the number of symbols
+ /// added.
+ unsigned ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,
+ lldb::user_id_t start_id,
+ const ELFSectionHeaderInfo *rela_hdr,
+ lldb::user_id_t section_id);
+
+ void ParseUnwindSymbols(lldb_private::Symtab *symbol_table,
+ lldb_private::DWARFCallFrameInfo *eh_frame);
+
+ /// Relocates debug sections
+ unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr,
+ lldb::user_id_t rel_id);
+
+ unsigned RelocateSection(lldb_private::Symtab *symtab,
+ const elf::ELFHeader *hdr,
+ const elf::ELFSectionHeader *rel_hdr,
+ const elf::ELFSectionHeader *symtab_hdr,
+ const elf::ELFSectionHeader *debug_hdr,
+ lldb_private::DataExtractor &rel_data,
+ lldb_private::DataExtractor &symtab_data,
+ lldb_private::DataExtractor &debug_data,
+ lldb_private::Section *rel_section);
+
+ /// Loads the section name string table into m_shstr_data. Returns the
+ /// number of bytes constituting the table.
+ size_t GetSectionHeaderStringTable();
+
+ /// Utility method for looking up a section given its name. Returns the
+ /// index of the corresponding section or zero if no section with the given
+ /// name can be found (note that section indices are always 1 based, and so
+ /// section index 0 is never valid).
+ lldb::user_id_t GetSectionIndexByName(const char *name);
+
+ // Returns the ID of the first section that has the given type.
+ lldb::user_id_t GetSectionIndexByType(unsigned type);
+
+ /// Returns the section header with the given id or NULL.
+ const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id);
+
+ /// @name ELF header dump routines
+ //@{
+ static void DumpELFHeader(lldb_private::Stream *s,
+ const elf::ELFHeader &header);
+
+ static void DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
+ unsigned char ei_data);
+
+ static void DumpELFHeader_e_type(lldb_private::Stream *s,
+ elf::elf_half e_type);
+ //@}
+
+ /// @name ELF program header dump routines
+ //@{
+ void DumpELFProgramHeaders(lldb_private::Stream *s);
+
+ static void DumpELFProgramHeader(lldb_private::Stream *s,
+ const elf::ELFProgramHeader &ph);
+
+ static void DumpELFProgramHeader_p_type(lldb_private::Stream *s,
+ elf::elf_word p_type);
+
+ static void DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
+ elf::elf_word p_flags);
+ //@}
+
+ /// @name ELF section header dump routines
+ //@{
+ void DumpELFSectionHeaders(lldb_private::Stream *s);
+
+ static void DumpELFSectionHeader(lldb_private::Stream *s,
+ const ELFSectionHeaderInfo &sh);
+
+ static void DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
+ elf::elf_word sh_type);
+
+ static void DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
+ elf::elf_xword sh_flags);
+ //@}
+
+ /// ELF dependent module dump routine.
+ void DumpDependentModules(lldb_private::Stream *s);
+
+ const elf::ELFDynamic *FindDynamicSymbol(unsigned tag);
+
+ unsigned PLTRelocationType();
+
+ static lldb_private::Error
+ RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
+ lldb_private::ArchSpec &arch_spec,
+ lldb_private::UUID &uuid);
+
+ static lldb::offset_t SetData(const lldb_private::DataExtractor &src,
+ lldb_private::DataExtractor &dst,
+ lldb::offset_t offset, lldb::offset_t length);
+
+ lldb::offset_t SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst,
+ lldb::offset_t offset,
+ lldb::offset_t length);
};
#endif // liblldb_ObjectFileELF_h_
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index e3d838333711..b5b5e38e1f6f 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -26,8 +26,8 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/UUID.h"
-#include "lldb/Host/Host.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
@@ -41,322 +41,227 @@
using namespace lldb;
using namespace lldb_private;
-
-void
-ObjectFileJIT::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- CreateMemoryInstance,
- GetModuleSpecifications);
+void ObjectFileJIT::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ CreateMemoryInstance, GetModuleSpecifications);
}
-void
-ObjectFileJIT::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-
-lldb_private::ConstString
-ObjectFileJIT::GetPluginNameStatic()
-{
- static ConstString g_name("jit");
- return g_name;
+void ObjectFileJIT::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-const char *
-ObjectFileJIT::GetPluginDescriptionStatic()
-{
- return "JIT code object file";
+lldb_private::ConstString ObjectFileJIT::GetPluginNameStatic() {
+ static ConstString g_name("jit");
+ return g_name;
}
-ObjectFile *
-ObjectFileJIT::CreateInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length)
-{
- // JIT'ed object file is backed by the ObjectFileJITDelegate, never
- // read from a file
- return NULL;
+const char *ObjectFileJIT::GetPluginDescriptionStatic() {
+ return "JIT code object file";
}
-ObjectFile *
-ObjectFileJIT::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- const ProcessSP &process_sp,
- lldb::addr_t header_addr)
-{
- // JIT'ed object file is backed by the ObjectFileJITDelegate, never
- // read from memory
- return NULL;
+ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const FileSpec *file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length) {
+ // JIT'ed object file is backed by the ObjectFileJITDelegate, never
+ // read from a file
+ return NULL;
}
-size_t
-ObjectFileJIT::GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs)
-{
- // JIT'ed object file can't be read from a file on disk
- return 0;
+ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ const ProcessSP &process_sp,
+ lldb::addr_t header_addr) {
+ // JIT'ed object file is backed by the ObjectFileJITDelegate, never
+ // read from memory
+ return NULL;
}
-ObjectFileJIT::ObjectFileJIT (const lldb::ModuleSP &module_sp,
- const ObjectFileJITDelegateSP &delegate_sp) :
- ObjectFile(module_sp, NULL, 0, 0, DataBufferSP(), 0),
- m_delegate_wp ()
-{
- if (delegate_sp)
- {
- m_delegate_wp = delegate_sp;
- m_data.SetByteOrder(delegate_sp->GetByteOrder());
- m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize());
- }
+size_t ObjectFileJIT::GetModuleSpecifications(
+ const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, lldb::offset_t file_offset,
+ lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
+ // JIT'ed object file can't be read from a file on disk
+ return 0;
}
-ObjectFileJIT::~ObjectFileJIT()
-{
+ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp,
+ const ObjectFileJITDelegateSP &delegate_sp)
+ : ObjectFile(module_sp, NULL, 0, 0, DataBufferSP(), 0), m_delegate_wp() {
+ if (delegate_sp) {
+ m_delegate_wp = delegate_sp;
+ m_data.SetByteOrder(delegate_sp->GetByteOrder());
+ m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize());
+ }
}
+ObjectFileJIT::~ObjectFileJIT() {}
-bool
-ObjectFileJIT::ParseHeader ()
-{
- // JIT code is never in a file, nor is it required to have any header
- return false;
+bool ObjectFileJIT::ParseHeader() {
+ // JIT code is never in a file, nor is it required to have any header
+ return false;
}
-ByteOrder
-ObjectFileJIT::GetByteOrder () const
-{
- return m_data.GetByteOrder();
-}
+ByteOrder ObjectFileJIT::GetByteOrder() const { return m_data.GetByteOrder(); }
-bool
-ObjectFileJIT::IsExecutable() const
-{
- return false;
-}
+bool ObjectFileJIT::IsExecutable() const { return false; }
-uint32_t
-ObjectFileJIT::GetAddressByteSize () const
-{
- return m_data.GetAddressByteSize();
+uint32_t ObjectFileJIT::GetAddressByteSize() const {
+ return m_data.GetAddressByteSize();
}
-
-Symtab *
-ObjectFileJIT::GetSymtab()
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_symtab_ap.get() == NULL)
- {
- m_symtab_ap.reset(new Symtab(this));
- std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex());
- ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock());
- if (delegate_sp)
- delegate_sp->PopulateSymtab(this, *m_symtab_ap);
- // TODO: get symbols from delegate
- m_symtab_ap->Finalize ();
- }
+Symtab *ObjectFileJIT::GetSymtab() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (m_symtab_ap.get() == NULL) {
+ m_symtab_ap.reset(new Symtab(this));
+ std::lock_guard<std::recursive_mutex> symtab_guard(
+ m_symtab_ap->GetMutex());
+ ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
+ if (delegate_sp)
+ delegate_sp->PopulateSymtab(this, *m_symtab_ap);
+ // TODO: get symbols from delegate
+ m_symtab_ap->Finalize();
}
- return m_symtab_ap.get();
+ }
+ return m_symtab_ap.get();
}
-bool
-ObjectFileJIT::IsStripped ()
-{
- return false; // JIT code that is in a module is never stripped
+bool ObjectFileJIT::IsStripped() {
+ return false; // JIT code that is in a module is never stripped
}
-void
-ObjectFileJIT::CreateSections (SectionList &unified_section_list)
-{
- if (!m_sections_ap.get())
- {
- m_sections_ap.reset(new SectionList());
- ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock());
- if (delegate_sp)
- {
- delegate_sp->PopulateSectionList(this, *m_sections_ap);
- unified_section_list = *m_sections_ap;
- }
+void ObjectFileJIT::CreateSections(SectionList &unified_section_list) {
+ if (!m_sections_ap.get()) {
+ m_sections_ap.reset(new SectionList());
+ ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
+ if (delegate_sp) {
+ delegate_sp->PopulateSectionList(this, *m_sections_ap);
+ unified_section_list = *m_sections_ap;
}
+ }
}
-void
-ObjectFileJIT::Dump (Stream *s)
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- s->Printf("%p: ", static_cast<void*>(this));
- s->Indent();
- s->PutCString("ObjectFileJIT");
-
- ArchSpec arch;
- if (GetArchitecture(arch))
- *s << ", arch = " << arch.GetArchitectureName();
-
- s->EOL();
-
- SectionList *sections = GetSectionList();
- if (sections)
- sections->Dump(s, NULL, true, UINT32_MAX);
-
- if (m_symtab_ap.get())
- m_symtab_ap->Dump(s, NULL, eSortOrderNone);
- }
-}
+void ObjectFileJIT::Dump(Stream *s) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ s->Printf("%p: ", static_cast<void *>(this));
+ s->Indent();
+ s->PutCString("ObjectFileJIT");
-bool
-ObjectFileJIT::GetUUID (lldb_private::UUID* uuid)
-{
- // TODO: maybe get from delegate, not needed for first pass
- return false;
-}
+ ArchSpec arch;
+ if (GetArchitecture(arch))
+ *s << ", arch = " << arch.GetArchitectureName();
+ s->EOL();
-uint32_t
-ObjectFileJIT::GetDependentModules (FileSpecList& files)
-{
- // JIT modules don't have dependencies, but they could
- // if external functions are called and we know where they are
- files.Clear();
- return 0;
-}
+ SectionList *sections = GetSectionList();
+ if (sections)
+ sections->Dump(s, NULL, true, UINT32_MAX);
-lldb_private::Address
-ObjectFileJIT::GetEntryPointAddress ()
-{
- return Address();
+ if (m_symtab_ap.get())
+ m_symtab_ap->Dump(s, NULL, eSortOrderNone);
+ }
}
-lldb_private::Address
-ObjectFileJIT::GetHeaderAddress ()
-{
- return Address();
+bool ObjectFileJIT::GetUUID(lldb_private::UUID *uuid) {
+ // TODO: maybe get from delegate, not needed for first pass
+ return false;
}
-
-
-ObjectFile::Type
-ObjectFileJIT::CalculateType()
-{
- return eTypeJIT;
+uint32_t ObjectFileJIT::GetDependentModules(FileSpecList &files) {
+ // JIT modules don't have dependencies, but they could
+ // if external functions are called and we know where they are
+ files.Clear();
+ return 0;
}
-ObjectFile::Strata
-ObjectFileJIT::CalculateStrata()
-{
- return eStrataJIT;
+lldb_private::Address ObjectFileJIT::GetEntryPointAddress() {
+ return Address();
}
+lldb_private::Address ObjectFileJIT::GetHeaderAddress() { 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;
+bool ObjectFileJIT::GetArchitecture(ArchSpec &arch) {
+ ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
+ if (delegate_sp)
+ return delegate_sp->GetArchitecture(arch);
+ return false;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ObjectFileJIT::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ObjectFileJIT::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ObjectFileJIT::GetPluginVersion()
-{
- return 1;
-}
-
-
-bool
-ObjectFileJIT::SetLoadAddress (Target &target,
- lldb::addr_t value,
- bool value_is_offset)
-{
- size_t num_loaded_sections = 0;
- SectionList *section_list = GetSectionList ();
- if (section_list)
- {
- const size_t num_sections = section_list->GetSize();
- // "value" is an offset to apply to each top level segment
- for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
- {
- // Iterate through the object file sections to find all
- // of the sections that size on disk (to avoid __PAGEZERO)
- // and load them
- SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- if (section_sp &&
- section_sp->GetFileSize() > 0 &&
- section_sp->IsThreadSpecific() == false)
- {
- if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
- ++num_loaded_sections;
- }
- }
+uint32_t ObjectFileJIT::GetPluginVersion() { return 1; }
+
+bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value,
+ bool value_is_offset) {
+ size_t num_loaded_sections = 0;
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ const size_t num_sections = section_list->GetSize();
+ // "value" is an offset to apply to each top level segment
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ // Iterate through the object file sections to find all
+ // of the sections that size on disk (to avoid __PAGEZERO)
+ // and load them
+ SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+ if (section_sp && section_sp->GetFileSize() > 0 &&
+ section_sp->IsThreadSpecific() == false) {
+ if (target.GetSectionLoadList().SetSectionLoadAddress(
+ section_sp, section_sp->GetFileAddress() + value))
+ ++num_loaded_sections;
+ }
}
- return num_loaded_sections > 0;
+ }
+ return num_loaded_sections > 0;
}
-
-size_t
-ObjectFileJIT::ReadSectionData (const lldb_private::Section *section,
- lldb::offset_t section_offset,
- void *dst,
- size_t dst_len) const
-{
- lldb::offset_t file_size = section->GetFileSize();
- if (section_offset < file_size)
- {
- size_t src_len = file_size - section_offset;
- if (src_len > dst_len)
- src_len = dst_len;
- const uint8_t *src = ((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset;
-
- memcpy (dst, src, src_len);
- return src_len;
- }
- return 0;
+size_t ObjectFileJIT::ReadSectionData(const lldb_private::Section *section,
+ lldb::offset_t section_offset, void *dst,
+ size_t dst_len) const {
+ lldb::offset_t file_size = section->GetFileSize();
+ if (section_offset < file_size) {
+ size_t src_len = file_size - section_offset;
+ if (src_len > dst_len)
+ src_len = dst_len;
+ const uint8_t *src =
+ ((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset;
+
+ memcpy(dst, src, src_len);
+ return src_len;
+ }
+ return 0;
}
-size_t
-ObjectFileJIT::ReadSectionData (const lldb_private::Section *section,
- lldb_private::DataExtractor& section_data) const
-{
- if (section->GetFileSize())
- {
- const void *src = (void *)(uintptr_t)section->GetFileOffset();
-
- DataBufferSP data_sp (new lldb_private::DataBufferHeap(src, section->GetFileSize()));
- if (data_sp)
- {
- section_data.SetData (data_sp, 0, data_sp->GetByteSize());
- section_data.SetByteOrder (GetByteOrder());
- section_data.SetAddressByteSize (GetAddressByteSize());
- return section_data.GetByteSize();
- }
+size_t ObjectFileJIT::ReadSectionData(
+ const lldb_private::Section *section,
+ lldb_private::DataExtractor &section_data) const {
+ if (section->GetFileSize()) {
+ const void *src = (void *)(uintptr_t)section->GetFileOffset();
+
+ DataBufferSP data_sp(
+ new lldb_private::DataBufferHeap(src, section->GetFileSize()));
+ if (data_sp) {
+ section_data.SetData(data_sp, 0, data_sp->GetByteSize());
+ section_data.SetByteOrder(GetByteOrder());
+ section_data.SetAddressByteSize(GetAddressByteSize());
+ return section_data.GetByteSize();
}
- section_data.Clear();
- return 0;
+ }
+ section_data.Clear();
+ return 0;
}
-
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index 39dbb3fb047b..a211645d5d8b 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -21,126 +21,93 @@
// This class needs to be hidden as eventually belongs in a plugin that
// will export the ObjectFile protocol
//----------------------------------------------------------------------
-class ObjectFileJIT :
- public lldb_private::ObjectFile
-{
+class ObjectFileJIT : public lldb_private::ObjectFile {
public:
- ObjectFileJIT(const lldb::ModuleSP &module_sp,
- const lldb::ObjectFileJITDelegateSP &delegate_sp);
-
- ~ObjectFileJIT() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::ObjectFile *
- CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length);
-
- static lldb_private::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 lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- //------------------------------------------------------------------
- // Member Functions
- //------------------------------------------------------------------
- bool
- ParseHeader() override;
-
- bool
- SetLoadAddress(lldb_private::Target &target,
- lldb::addr_t value,
- bool value_is_offset) override;
-
- lldb::ByteOrder
- GetByteOrder() const override;
-
- bool
- IsExecutable() const override;
-
- uint32_t
- GetAddressByteSize() const override;
-
- lldb_private::Symtab *
- GetSymtab() override;
-
- bool
- IsStripped() override;
-
- void
- CreateSections(lldb_private::SectionList &unified_section_list) override;
-
- void
- Dump(lldb_private::Stream *s) override;
-
- bool
- GetArchitecture(lldb_private::ArchSpec &arch) override;
-
- bool
- GetUUID(lldb_private::UUID* uuid) override;
-
- uint32_t
- GetDependentModules(lldb_private::FileSpecList& files) override;
-
- size_t
- ReadSectionData(const lldb_private::Section *section,
- lldb::offset_t section_offset,
- void *dst,
- size_t dst_len) const override;
-
- size_t
- ReadSectionData(const lldb_private::Section *section,
- lldb_private::DataExtractor& section_data) const override;
-
- lldb_private::Address
- GetEntryPointAddress() override;
-
- lldb_private::Address
- GetHeaderAddress() override;
-
- ObjectFile::Type
- CalculateType() override;
-
- ObjectFile::Strata
- CalculateStrata() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ObjectFileJIT(const lldb::ModuleSP &module_sp,
+ const lldb::ObjectFileJITDelegateSP &delegate_sp);
+
+ ~ObjectFileJIT() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::ObjectFile *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length);
+
+ static lldb_private::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 lldb_private::FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb_private::ModuleSpecList &specs);
+
+ //------------------------------------------------------------------
+ // Member Functions
+ //------------------------------------------------------------------
+ bool ParseHeader() override;
+
+ bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
+ bool value_is_offset) override;
+
+ lldb::ByteOrder GetByteOrder() const override;
+
+ bool IsExecutable() const override;
+
+ uint32_t GetAddressByteSize() const override;
+
+ lldb_private::Symtab *GetSymtab() override;
+
+ bool IsStripped() override;
+
+ void CreateSections(lldb_private::SectionList &unified_section_list) override;
+
+ void Dump(lldb_private::Stream *s) override;
+
+ bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+
+ bool GetUUID(lldb_private::UUID *uuid) override;
+
+ uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
+
+ size_t ReadSectionData(const lldb_private::Section *section,
+ lldb::offset_t section_offset, void *dst,
+ size_t dst_len) const override;
+
+ size_t
+ ReadSectionData(const lldb_private::Section *section,
+ lldb_private::DataExtractor &section_data) const override;
+
+ lldb_private::Address GetEntryPointAddress() override;
+
+ lldb_private::Address GetHeaderAddress() override;
+
+ ObjectFile::Type CalculateType() override;
+
+ ObjectFile::Strata CalculateStrata() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- lldb::ObjectFileJITDelegateWP m_delegate_wp;
+ lldb::ObjectFileJITDelegateWP m_delegate_wp;
};
#endif // liblldb_ObjectFileJIT_h_
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 5f8242211b7f..9ef4e9c3c9b1 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -10,9 +10,13 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
+#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"
+#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Debugger.h"
@@ -28,10 +32,11 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/UUID.h"
-#include "lldb/Host/Host.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
@@ -39,16 +44,13 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadList.h"
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
-#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
#include "lldb/Utility/SafeMachO.h"
#include "ObjectFileMachO.h"
-#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
+#if defined(__APPLE__) && \
+ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
// GetLLDBSharedCacheUUID() needs to call dlsym()
#include <dlfcn.h>
#endif
@@ -65,3870 +67,2966 @@ using namespace llvm::MachO;
// Some structure definitions needed for parsing the dyld shared cache files
// found on iOS devices.
-struct lldb_copy_dyld_cache_header_v1
-{
- char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
- uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
- uint32_t mappingCount; // number of dyld_cache_mapping_info entries
- uint32_t imagesOffset;
- uint32_t imagesCount;
- uint64_t dyldBaseAddress;
- uint64_t codeSignatureOffset;
- uint64_t codeSignatureSize;
- uint64_t slideInfoOffset;
- uint64_t slideInfoSize;
- uint64_t localSymbolsOffset;
- uint64_t localSymbolsSize;
- uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
+struct lldb_copy_dyld_cache_header_v1 {
+ char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
+ uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
+ uint32_t mappingCount; // number of dyld_cache_mapping_info entries
+ uint32_t imagesOffset;
+ uint32_t imagesCount;
+ uint64_t dyldBaseAddress;
+ uint64_t codeSignatureOffset;
+ uint64_t codeSignatureSize;
+ uint64_t slideInfoOffset;
+ uint64_t slideInfoSize;
+ uint64_t localSymbolsOffset;
+ uint64_t localSymbolsSize;
+ uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13
+ // and later
};
-struct lldb_copy_dyld_cache_mapping_info
-{
- uint64_t address;
- uint64_t size;
- uint64_t fileOffset;
- uint32_t maxProt;
- uint32_t initProt;
+struct lldb_copy_dyld_cache_mapping_info {
+ uint64_t address;
+ uint64_t size;
+ uint64_t fileOffset;
+ uint32_t maxProt;
+ uint32_t initProt;
};
-struct lldb_copy_dyld_cache_local_symbols_info
-{
- uint32_t nlistOffset;
- uint32_t nlistCount;
- uint32_t stringsOffset;
- uint32_t stringsSize;
- uint32_t entriesOffset;
- uint32_t entriesCount;
+struct lldb_copy_dyld_cache_local_symbols_info {
+ uint32_t nlistOffset;
+ uint32_t nlistCount;
+ uint32_t stringsOffset;
+ uint32_t stringsSize;
+ uint32_t entriesOffset;
+ uint32_t entriesCount;
};
-struct lldb_copy_dyld_cache_local_symbols_entry
-{
- uint32_t dylibOffset;
- uint32_t nlistStartIndex;
- uint32_t nlistCount;
+struct lldb_copy_dyld_cache_local_symbols_entry {
+ uint32_t dylibOffset;
+ uint32_t nlistStartIndex;
+ uint32_t nlistCount;
};
-
-class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
-{
+class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {
public:
- RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
- RegisterContextDarwin_x86_64 (thread, 0)
- {
- SetRegisterDataFrom_LC_THREAD (data);
- }
+ RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread,
+ const DataExtractor &data)
+ : RegisterContextDarwin_x86_64(thread, 0) {
+ SetRegisterDataFrom_LC_THREAD(data);
+ }
- void
- InvalidateAllRegisters() override
- {
- // Do nothing... registers are always valid...
- }
-
- void
- SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
- {
- lldb::offset_t offset = 0;
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
- bool done = false;
-
- while (!done)
- {
- int flavor = data.GetU32 (&offset);
- if (flavor == 0)
- done = true;
- else
- {
- uint32_t i;
- uint32_t count = data.GetU32 (&offset);
- switch (flavor)
- {
- case GPRRegSet:
- for (i=0; i<count; ++i)
- (&gpr.rax)[i] = data.GetU64(&offset);
- SetError (GPRRegSet, Read, 0);
- done = true;
+ void InvalidateAllRegisters() override {
+ // Do nothing... registers are always valid...
+ }
- break;
- case FPURegSet:
- // TODO: fill in FPU regs....
- //SetError (FPURegSet, Read, -1);
- done = true;
-
- break;
- case EXCRegSet:
- exc.trapno = data.GetU32(&offset);
- exc.err = data.GetU32(&offset);
- exc.faultvaddr = data.GetU64(&offset);
- SetError (EXCRegSet, Read, 0);
- done = true;
- break;
- case 7:
- case 8:
- case 9:
- // fancy flavors that encapsulate of the above
- // flavors...
- break;
+ void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
+ lldb::offset_t offset = 0;
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ bool done = false;
+
+ while (!done) {
+ int flavor = data.GetU32(&offset);
+ if (flavor == 0)
+ done = true;
+ else {
+ uint32_t i;
+ uint32_t count = data.GetU32(&offset);
+ switch (flavor) {
+ case GPRRegSet:
+ for (i = 0; i < count; ++i)
+ (&gpr.rax)[i] = data.GetU64(&offset);
+ SetError(GPRRegSet, Read, 0);
+ done = true;
+
+ break;
+ case FPURegSet:
+ // TODO: fill in FPU regs....
+ // SetError (FPURegSet, Read, -1);
+ done = true;
+
+ break;
+ case EXCRegSet:
+ exc.trapno = data.GetU32(&offset);
+ exc.err = data.GetU32(&offset);
+ exc.faultvaddr = data.GetU64(&offset);
+ SetError(EXCRegSet, Read, 0);
+ done = true;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ // fancy flavors that encapsulate of the above
+ // flavors...
+ break;
- default:
- done = true;
- break;
- }
- }
+ default:
+ done = true;
+ break;
}
+ }
}
-
- static size_t
- WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info)
- {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value))
- {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else
- {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
- }
- // Just write zeros if all else fails
- for (size_t i=0; i<reg_byte_size; ++ i)
+ }
+
+ static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
+ const char *alt_name, size_t reg_byte_size,
+ Stream &data) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
+ if (reg_info == NULL)
+ reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
+ if (reg_info) {
+ lldb_private::RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ if (reg_info->byte_size >= reg_byte_size)
+ data.Write(reg_value.GetBytes(), reg_byte_size);
+ else {
+ data.Write(reg_value.GetBytes(), reg_info->byte_size);
+ for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
+ ++i)
data.PutChar(0);
+ }
return reg_byte_size;
+ }
}
-
- static bool
- Create_LC_THREAD (Thread *thread, Stream &data)
- {
- RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
- if (reg_ctx_sp)
- {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32 (GPRRegSet); // Flavor
- data.PutHex32 (GPRWordCount);
- WriteRegister (reg_ctx, "rax", NULL, 8, data);
- WriteRegister (reg_ctx, "rbx", NULL, 8, data);
- WriteRegister (reg_ctx, "rcx", NULL, 8, data);
- WriteRegister (reg_ctx, "rdx", NULL, 8, data);
- WriteRegister (reg_ctx, "rdi", NULL, 8, data);
- WriteRegister (reg_ctx, "rsi", NULL, 8, data);
- WriteRegister (reg_ctx, "rbp", NULL, 8, data);
- WriteRegister (reg_ctx, "rsp", NULL, 8, data);
- WriteRegister (reg_ctx, "r8", NULL, 8, data);
- WriteRegister (reg_ctx, "r9", NULL, 8, data);
- WriteRegister (reg_ctx, "r10", NULL, 8, data);
- WriteRegister (reg_ctx, "r11", NULL, 8, data);
- WriteRegister (reg_ctx, "r12", NULL, 8, data);
- WriteRegister (reg_ctx, "r13", NULL, 8, data);
- WriteRegister (reg_ctx, "r14", NULL, 8, data);
- WriteRegister (reg_ctx, "r15", NULL, 8, data);
- WriteRegister (reg_ctx, "rip", NULL, 8, data);
- WriteRegister (reg_ctx, "rflags", NULL, 8, data);
- WriteRegister (reg_ctx, "cs", NULL, 8, data);
- WriteRegister (reg_ctx, "fs", NULL, 8, data);
- WriteRegister (reg_ctx, "gs", NULL, 8, data);
-
-// // Write out the FPU registers
-// const size_t fpu_byte_size = sizeof(FPU);
-// size_t bytes_written = 0;
-// data.PutHex32 (FPURegSet);
-// data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
-// bytes_written += data.PutHex32(0); // uint32_t pad[0]
-// bytes_written += data.PutHex32(0); // uint32_t pad[1]
-// bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data); // uint16_t fcw; // "fctrl"
-// bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data); // uint16_t fsw; // "fstat"
-// bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data); // uint8_t ftw; // "ftag"
-// bytes_written += data.PutHex8 (0); // uint8_t pad1;
-// bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data); // uint16_t fop; // "fop"
-// bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data); // uint32_t ip; // "fioff"
-// bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data); // uint16_t cs; // "fiseg"
-// bytes_written += data.PutHex16 (0); // uint16_t pad2;
-// bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data); // uint32_t dp; // "fooff"
-// bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data); // uint16_t ds; // "foseg"
-// bytes_written += data.PutHex16 (0); // uint16_t pad3;
-// bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data); // uint32_t mxcsr;
-// bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t mxcsrmask;
-// bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data);
-// bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data);
-//
-// // Fill rest with zeros
-// for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i)
-// data.PutChar(0);
-
- // Write out the EXC registers
- data.PutHex32 (EXCRegSet);
- data.PutHex32 (EXCWordCount);
- WriteRegister (reg_ctx, "trapno", NULL, 4, data);
- WriteRegister (reg_ctx, "err", NULL, 4, data);
- WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data);
- return true;
- }
- return false;
+ // Just write zeros if all else fails
+ for (size_t i = 0; i < reg_byte_size; ++i)
+ data.PutChar(0);
+ return reg_byte_size;
+ }
+
+ static bool Create_LC_THREAD(Thread *thread, Stream &data) {
+ RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
+ if (reg_ctx_sp) {
+ RegisterContext *reg_ctx = reg_ctx_sp.get();
+
+ data.PutHex32(GPRRegSet); // Flavor
+ data.PutHex32(GPRWordCount);
+ WriteRegister(reg_ctx, "rax", NULL, 8, data);
+ WriteRegister(reg_ctx, "rbx", NULL, 8, data);
+ WriteRegister(reg_ctx, "rcx", NULL, 8, data);
+ WriteRegister(reg_ctx, "rdx", NULL, 8, data);
+ WriteRegister(reg_ctx, "rdi", NULL, 8, data);
+ WriteRegister(reg_ctx, "rsi", NULL, 8, data);
+ WriteRegister(reg_ctx, "rbp", NULL, 8, data);
+ WriteRegister(reg_ctx, "rsp", NULL, 8, data);
+ WriteRegister(reg_ctx, "r8", NULL, 8, data);
+ WriteRegister(reg_ctx, "r9", NULL, 8, data);
+ WriteRegister(reg_ctx, "r10", NULL, 8, data);
+ WriteRegister(reg_ctx, "r11", NULL, 8, data);
+ WriteRegister(reg_ctx, "r12", NULL, 8, data);
+ WriteRegister(reg_ctx, "r13", NULL, 8, data);
+ WriteRegister(reg_ctx, "r14", NULL, 8, data);
+ WriteRegister(reg_ctx, "r15", NULL, 8, data);
+ WriteRegister(reg_ctx, "rip", NULL, 8, data);
+ WriteRegister(reg_ctx, "rflags", NULL, 8, data);
+ WriteRegister(reg_ctx, "cs", NULL, 8, data);
+ WriteRegister(reg_ctx, "fs", NULL, 8, data);
+ WriteRegister(reg_ctx, "gs", NULL, 8, data);
+
+ // // Write out the FPU registers
+ // const size_t fpu_byte_size = sizeof(FPU);
+ // size_t bytes_written = 0;
+ // data.PutHex32 (FPURegSet);
+ // data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
+ // bytes_written += data.PutHex32(0); // uint32_t pad[0]
+ // bytes_written += data.PutHex32(0); // uint32_t pad[1]
+ // bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2,
+ // data); // uint16_t fcw; // "fctrl"
+ // bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2,
+ // data); // uint16_t fsw; // "fstat"
+ // bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1,
+ // data); // uint8_t ftw; // "ftag"
+ // bytes_written += data.PutHex8 (0); // uint8_t pad1;
+ // bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2,
+ // data); // uint16_t fop; // "fop"
+ // bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4,
+ // data); // uint32_t ip; // "fioff"
+ // bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2,
+ // data); // uint16_t cs; // "fiseg"
+ // bytes_written += data.PutHex16 (0); // uint16_t pad2;
+ // bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4,
+ // data); // uint32_t dp; // "fooff"
+ // bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2,
+ // data); // uint16_t ds; // "foseg"
+ // bytes_written += data.PutHex16 (0); // uint16_t pad3;
+ // bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4,
+ // data); // uint32_t mxcsr;
+ // bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL,
+ // 4, data);// uint32_t mxcsrmask;
+ // bytes_written += WriteRegister (reg_ctx, "stmm0", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "stmm1", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "stmm2", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "stmm3", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "stmm4", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "stmm5", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "stmm6", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "stmm7", NULL,
+ // sizeof(MMSReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm10", NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm11", NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm12", NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm13", NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm14", NULL,
+ // sizeof(XMMReg), data);
+ // bytes_written += WriteRegister (reg_ctx, "xmm15", NULL,
+ // sizeof(XMMReg), data);
+ //
+ // // Fill rest with zeros
+ // for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++
+ // i)
+ // data.PutChar(0);
+
+ // Write out the EXC registers
+ data.PutHex32(EXCRegSet);
+ data.PutHex32(EXCWordCount);
+ WriteRegister(reg_ctx, "trapno", NULL, 4, data);
+ WriteRegister(reg_ctx, "err", NULL, 4, data);
+ WriteRegister(reg_ctx, "faultvaddr", NULL, 8, data);
+ return true;
}
+ return false;
+ }
protected:
- int
- DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
- {
- return 0;
- }
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }
- int
- DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
- {
- return 0;
- }
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }
- int
- DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
- {
- return 0;
- }
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }
- int
- DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
- {
- return 0;
- }
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
+ return 0;
+ }
- int
- DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
- {
- return 0;
- }
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
+ return 0;
+ }
- int
- DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
- {
- return 0;
- }
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
+ return 0;
+ }
};
-class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
-{
+class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386 {
public:
- RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
- RegisterContextDarwin_i386 (thread, 0)
- {
- SetRegisterDataFrom_LC_THREAD (data);
- }
-
- void
- InvalidateAllRegisters() override
- {
- // Do nothing... registers are always valid...
- }
+ RegisterContextDarwin_i386_Mach(lldb_private::Thread &thread,
+ const DataExtractor &data)
+ : RegisterContextDarwin_i386(thread, 0) {
+ SetRegisterDataFrom_LC_THREAD(data);
+ }
- void
- SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
- {
- lldb::offset_t offset = 0;
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
- bool done = false;
-
- while (!done)
- {
- int flavor = data.GetU32 (&offset);
- if (flavor == 0)
- done = true;
- else
- {
- uint32_t i;
- uint32_t count = data.GetU32 (&offset);
- switch (flavor)
- {
- case GPRRegSet:
- for (i=0; i<count; ++i)
- (&gpr.eax)[i] = data.GetU32(&offset);
- SetError (GPRRegSet, Read, 0);
- done = true;
+ void InvalidateAllRegisters() override {
+ // Do nothing... registers are always valid...
+ }
- break;
- case FPURegSet:
- // TODO: fill in FPU regs....
- //SetError (FPURegSet, Read, -1);
- done = true;
-
- break;
- case EXCRegSet:
- exc.trapno = data.GetU32(&offset);
- exc.err = data.GetU32(&offset);
- exc.faultvaddr = data.GetU32(&offset);
- SetError (EXCRegSet, Read, 0);
- done = true;
- break;
- case 7:
- case 8:
- case 9:
- // fancy flavors that encapsulate of the above
- // flavors...
- break;
+ void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
+ lldb::offset_t offset = 0;
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ bool done = false;
+
+ while (!done) {
+ int flavor = data.GetU32(&offset);
+ if (flavor == 0)
+ done = true;
+ else {
+ uint32_t i;
+ uint32_t count = data.GetU32(&offset);
+ switch (flavor) {
+ case GPRRegSet:
+ for (i = 0; i < count; ++i)
+ (&gpr.eax)[i] = data.GetU32(&offset);
+ SetError(GPRRegSet, Read, 0);
+ done = true;
+
+ break;
+ case FPURegSet:
+ // TODO: fill in FPU regs....
+ // SetError (FPURegSet, Read, -1);
+ done = true;
+
+ break;
+ case EXCRegSet:
+ exc.trapno = data.GetU32(&offset);
+ exc.err = data.GetU32(&offset);
+ exc.faultvaddr = data.GetU32(&offset);
+ SetError(EXCRegSet, Read, 0);
+ done = true;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ // fancy flavors that encapsulate of the above
+ // flavors...
+ break;
- default:
- done = true;
- break;
- }
- }
+ default:
+ done = true;
+ break;
}
+ }
}
-
- static size_t
- WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info)
- {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value))
- {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else
- {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
- }
- // Just write zeros if all else fails
- for (size_t i=0; i<reg_byte_size; ++ i)
+ }
+
+ static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
+ const char *alt_name, size_t reg_byte_size,
+ Stream &data) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
+ if (reg_info == NULL)
+ reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
+ if (reg_info) {
+ lldb_private::RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ if (reg_info->byte_size >= reg_byte_size)
+ data.Write(reg_value.GetBytes(), reg_byte_size);
+ else {
+ data.Write(reg_value.GetBytes(), reg_info->byte_size);
+ for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
+ ++i)
data.PutChar(0);
+ }
return reg_byte_size;
+ }
}
-
- static bool
- Create_LC_THREAD (Thread *thread, Stream &data)
- {
- RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
- if (reg_ctx_sp)
- {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32 (GPRRegSet); // Flavor
- data.PutHex32 (GPRWordCount);
- WriteRegister (reg_ctx, "eax", NULL, 4, data);
- WriteRegister (reg_ctx, "ebx", NULL, 4, data);
- WriteRegister (reg_ctx, "ecx", NULL, 4, data);
- WriteRegister (reg_ctx, "edx", NULL, 4, data);
- WriteRegister (reg_ctx, "edi", NULL, 4, data);
- WriteRegister (reg_ctx, "esi", NULL, 4, data);
- WriteRegister (reg_ctx, "ebp", NULL, 4, data);
- WriteRegister (reg_ctx, "esp", NULL, 4, data);
- WriteRegister (reg_ctx, "ss", NULL, 4, data);
- WriteRegister (reg_ctx, "eflags", NULL, 4, data);
- WriteRegister (reg_ctx, "eip", NULL, 4, data);
- WriteRegister (reg_ctx, "cs", NULL, 4, data);
- WriteRegister (reg_ctx, "ds", NULL, 4, data);
- WriteRegister (reg_ctx, "es", NULL, 4, data);
- WriteRegister (reg_ctx, "fs", NULL, 4, data);
- WriteRegister (reg_ctx, "gs", NULL, 4, data);
-
- // Write out the EXC registers
- data.PutHex32 (EXCRegSet);
- data.PutHex32 (EXCWordCount);
- WriteRegister (reg_ctx, "trapno", NULL, 4, data);
- WriteRegister (reg_ctx, "err", NULL, 4, data);
- WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data);
- return true;
- }
- return false;
+ // Just write zeros if all else fails
+ for (size_t i = 0; i < reg_byte_size; ++i)
+ data.PutChar(0);
+ return reg_byte_size;
+ }
+
+ static bool Create_LC_THREAD(Thread *thread, Stream &data) {
+ RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
+ if (reg_ctx_sp) {
+ RegisterContext *reg_ctx = reg_ctx_sp.get();
+
+ data.PutHex32(GPRRegSet); // Flavor
+ data.PutHex32(GPRWordCount);
+ WriteRegister(reg_ctx, "eax", NULL, 4, data);
+ WriteRegister(reg_ctx, "ebx", NULL, 4, data);
+ WriteRegister(reg_ctx, "ecx", NULL, 4, data);
+ WriteRegister(reg_ctx, "edx", NULL, 4, data);
+ WriteRegister(reg_ctx, "edi", NULL, 4, data);
+ WriteRegister(reg_ctx, "esi", NULL, 4, data);
+ WriteRegister(reg_ctx, "ebp", NULL, 4, data);
+ WriteRegister(reg_ctx, "esp", NULL, 4, data);
+ WriteRegister(reg_ctx, "ss", NULL, 4, data);
+ WriteRegister(reg_ctx, "eflags", NULL, 4, data);
+ WriteRegister(reg_ctx, "eip", NULL, 4, data);
+ WriteRegister(reg_ctx, "cs", NULL, 4, data);
+ WriteRegister(reg_ctx, "ds", NULL, 4, data);
+ WriteRegister(reg_ctx, "es", NULL, 4, data);
+ WriteRegister(reg_ctx, "fs", NULL, 4, data);
+ WriteRegister(reg_ctx, "gs", NULL, 4, data);
+
+ // Write out the EXC registers
+ data.PutHex32(EXCRegSet);
+ data.PutHex32(EXCWordCount);
+ WriteRegister(reg_ctx, "trapno", NULL, 4, data);
+ WriteRegister(reg_ctx, "err", NULL, 4, data);
+ WriteRegister(reg_ctx, "faultvaddr", NULL, 4, data);
+ return true;
}
+ return false;
+ }
protected:
- int
- DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
- {
- return 0;
- }
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }
- int
- DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
- {
- return 0;
- }
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }
- int
- DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
- {
- return 0;
- }
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }
- int
- DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
- {
- return 0;
- }
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
+ return 0;
+ }
- int
- DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
- {
- return 0;
- }
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
+ return 0;
+ }
- int
- DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
- {
- return 0;
- }
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
+ return 0;
+ }
};
-class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
-{
+class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm {
public:
- RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
- RegisterContextDarwin_arm (thread, 0)
- {
- SetRegisterDataFrom_LC_THREAD (data);
- }
-
- void
- InvalidateAllRegisters() override
- {
- // Do nothing... registers are always valid...
- }
-
- void
- SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
- {
- lldb::offset_t offset = 0;
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
- bool done = false;
-
- while (!done)
- {
- int flavor = data.GetU32 (&offset);
- uint32_t count = data.GetU32 (&offset);
- lldb::offset_t next_thread_state = offset + (count * 4);
- switch (flavor)
- {
- case GPRAltRegSet:
- case GPRRegSet:
- for (uint32_t i=0; i<count; ++i)
- {
- gpr.r[i] = data.GetU32(&offset);
- }
-
- // Note that gpr.cpsr is also copied by the above loop; this loop technically extends
- // one element past the end of the gpr.r[] array.
-
- SetError (GPRRegSet, Read, 0);
- offset = next_thread_state;
- break;
+ RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread,
+ const DataExtractor &data)
+ : RegisterContextDarwin_arm(thread, 0) {
+ SetRegisterDataFrom_LC_THREAD(data);
+ }
- case FPURegSet:
- {
- uint8_t *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
- const int fpu_reg_buf_size = sizeof (fpu.floats);
- if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
- {
- offset += fpu_reg_buf_size;
- fpu.fpscr = data.GetU32(&offset);
- SetError (FPURegSet, Read, 0);
- }
- else
- {
- done = true;
- }
- }
- offset = next_thread_state;
- break;
+ void InvalidateAllRegisters() override {
+ // Do nothing... registers are always valid...
+ }
- case EXCRegSet:
- if (count == 3)
- {
- exc.exception = data.GetU32(&offset);
- exc.fsr = data.GetU32(&offset);
- exc.far = data.GetU32(&offset);
- SetError (EXCRegSet, Read, 0);
- }
- done = true;
- offset = next_thread_state;
- break;
-
- // Unknown register set flavor, stop trying to parse.
- default:
- done = true;
- }
+ void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
+ lldb::offset_t offset = 0;
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ bool done = false;
+
+ while (!done) {
+ int flavor = data.GetU32(&offset);
+ uint32_t count = data.GetU32(&offset);
+ lldb::offset_t next_thread_state = offset + (count * 4);
+ switch (flavor) {
+ case GPRAltRegSet:
+ case GPRRegSet:
+ for (uint32_t i = 0; i < count; ++i) {
+ gpr.r[i] = data.GetU32(&offset);
}
- }
- static size_t
- WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info)
- {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value))
- {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else
- {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
+ // Note that gpr.cpsr is also copied by the above loop; this loop
+ // technically extends
+ // one element past the end of the gpr.r[] array.
+
+ SetError(GPRRegSet, Read, 0);
+ offset = next_thread_state;
+ break;
+
+ case FPURegSet: {
+ uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats.s[0];
+ const int fpu_reg_buf_size = sizeof(fpu.floats);
+ if (data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
+ fpu_reg_buf) == fpu_reg_buf_size) {
+ offset += fpu_reg_buf_size;
+ fpu.fpscr = data.GetU32(&offset);
+ SetError(FPURegSet, Read, 0);
+ } else {
+ done = true;
+ }
+ }
+ offset = next_thread_state;
+ break;
+
+ case EXCRegSet:
+ if (count == 3) {
+ exc.exception = data.GetU32(&offset);
+ exc.fsr = data.GetU32(&offset);
+ exc.far = data.GetU32(&offset);
+ SetError(EXCRegSet, Read, 0);
}
- // Just write zeros if all else fails
- for (size_t i=0; i<reg_byte_size; ++ i)
+ done = true;
+ offset = next_thread_state;
+ break;
+
+ // Unknown register set flavor, stop trying to parse.
+ default:
+ done = true;
+ }
+ }
+ }
+
+ static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
+ const char *alt_name, size_t reg_byte_size,
+ Stream &data) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
+ if (reg_info == NULL)
+ reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
+ if (reg_info) {
+ lldb_private::RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ if (reg_info->byte_size >= reg_byte_size)
+ data.Write(reg_value.GetBytes(), reg_byte_size);
+ else {
+ data.Write(reg_value.GetBytes(), reg_info->byte_size);
+ for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
+ ++i)
data.PutChar(0);
+ }
return reg_byte_size;
+ }
}
-
- static bool
- Create_LC_THREAD (Thread *thread, Stream &data)
- {
- RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
- if (reg_ctx_sp)
- {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32 (GPRRegSet); // Flavor
- data.PutHex32 (GPRWordCount);
- WriteRegister (reg_ctx, "r0", NULL, 4, data);
- WriteRegister (reg_ctx, "r1", NULL, 4, data);
- WriteRegister (reg_ctx, "r2", NULL, 4, data);
- WriteRegister (reg_ctx, "r3", NULL, 4, data);
- WriteRegister (reg_ctx, "r4", NULL, 4, data);
- WriteRegister (reg_ctx, "r5", NULL, 4, data);
- WriteRegister (reg_ctx, "r6", NULL, 4, data);
- WriteRegister (reg_ctx, "r7", NULL, 4, data);
- WriteRegister (reg_ctx, "r8", NULL, 4, data);
- WriteRegister (reg_ctx, "r9", NULL, 4, data);
- WriteRegister (reg_ctx, "r10", NULL, 4, data);
- WriteRegister (reg_ctx, "r11", NULL, 4, data);
- WriteRegister (reg_ctx, "r12", NULL, 4, data);
- WriteRegister (reg_ctx, "sp", NULL, 4, data);
- WriteRegister (reg_ctx, "lr", NULL, 4, data);
- WriteRegister (reg_ctx, "pc", NULL, 4, data);
- WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
-
- // Write out the EXC registers
-// data.PutHex32 (EXCRegSet);
-// data.PutHex32 (EXCWordCount);
-// WriteRegister (reg_ctx, "exception", NULL, 4, data);
-// WriteRegister (reg_ctx, "fsr", NULL, 4, data);
-// WriteRegister (reg_ctx, "far", NULL, 4, data);
- return true;
- }
- return false;
+ // Just write zeros if all else fails
+ for (size_t i = 0; i < reg_byte_size; ++i)
+ data.PutChar(0);
+ return reg_byte_size;
+ }
+
+ static bool Create_LC_THREAD(Thread *thread, Stream &data) {
+ RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
+ if (reg_ctx_sp) {
+ RegisterContext *reg_ctx = reg_ctx_sp.get();
+
+ data.PutHex32(GPRRegSet); // Flavor
+ data.PutHex32(GPRWordCount);
+ WriteRegister(reg_ctx, "r0", NULL, 4, data);
+ WriteRegister(reg_ctx, "r1", NULL, 4, data);
+ WriteRegister(reg_ctx, "r2", NULL, 4, data);
+ WriteRegister(reg_ctx, "r3", NULL, 4, data);
+ WriteRegister(reg_ctx, "r4", NULL, 4, data);
+ WriteRegister(reg_ctx, "r5", NULL, 4, data);
+ WriteRegister(reg_ctx, "r6", NULL, 4, data);
+ WriteRegister(reg_ctx, "r7", NULL, 4, data);
+ WriteRegister(reg_ctx, "r8", NULL, 4, data);
+ WriteRegister(reg_ctx, "r9", NULL, 4, data);
+ WriteRegister(reg_ctx, "r10", NULL, 4, data);
+ WriteRegister(reg_ctx, "r11", NULL, 4, data);
+ WriteRegister(reg_ctx, "r12", NULL, 4, data);
+ WriteRegister(reg_ctx, "sp", NULL, 4, data);
+ WriteRegister(reg_ctx, "lr", NULL, 4, data);
+ WriteRegister(reg_ctx, "pc", NULL, 4, data);
+ WriteRegister(reg_ctx, "cpsr", NULL, 4, data);
+
+ // Write out the EXC registers
+ // data.PutHex32 (EXCRegSet);
+ // data.PutHex32 (EXCWordCount);
+ // WriteRegister (reg_ctx, "exception", NULL, 4, data);
+ // WriteRegister (reg_ctx, "fsr", NULL, 4, data);
+ // WriteRegister (reg_ctx, "far", NULL, 4, data);
+ return true;
}
+ return false;
+ }
protected:
- int
- DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
- {
- return -1;
- }
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
- int
- DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
- {
- return -1;
- }
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
- int
- DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
- {
- return -1;
- }
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
- int
- DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
- {
- return -1;
- }
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
- int
- DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
- {
- return 0;
- }
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
+ return 0;
+ }
- int
- DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
- {
- return 0;
- }
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
+ return 0;
+ }
- int
- DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
- {
- return 0;
- }
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
+ return 0;
+ }
- int
- DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
- {
- return -1;
- }
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
+ return -1;
+ }
};
-class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
-{
+class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {
public:
- RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
- RegisterContextDarwin_arm64 (thread, 0)
- {
- SetRegisterDataFrom_LC_THREAD (data);
- }
-
- void
- InvalidateAllRegisters() override
- {
- // Do nothing... registers are always valid...
- }
-
- void
- SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
- {
- lldb::offset_t offset = 0;
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
- bool done = false;
- while (!done)
- {
- int flavor = data.GetU32 (&offset);
- uint32_t count = data.GetU32 (&offset);
- lldb::offset_t next_thread_state = offset + (count * 4);
- switch (flavor)
- {
- case GPRRegSet:
- // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
- if (count >= (33 * 2) + 1)
- {
- for (uint32_t i=0; i<33; ++i)
- gpr.x[i] = data.GetU64(&offset);
- gpr.cpsr = data.GetU32(&offset);
- SetError (GPRRegSet, Read, 0);
- }
- offset = next_thread_state;
- break;
- case FPURegSet:
- {
- uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
- const int fpu_reg_buf_size = sizeof (fpu);
- if (fpu_reg_buf_size == count
- && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
- {
- SetError (FPURegSet, Read, 0);
- }
- else
- {
- done = true;
- }
- }
- offset = next_thread_state;
- break;
- case EXCRegSet:
- if (count == 4)
- {
- exc.far = data.GetU64(&offset);
- exc.esr = data.GetU32(&offset);
- exc.exception = data.GetU32(&offset);
- SetError (EXCRegSet, Read, 0);
- }
- offset = next_thread_state;
- break;
- default:
- done = true;
- break;
- }
- }
- }
+ RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread,
+ const DataExtractor &data)
+ : RegisterContextDarwin_arm64(thread, 0) {
+ SetRegisterDataFrom_LC_THREAD(data);
+ }
- static size_t
- WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
- if (reg_info == NULL)
- reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
- if (reg_info)
- {
- lldb_private::RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value))
- {
- if (reg_info->byte_size >= reg_byte_size)
- data.Write(reg_value.GetBytes(), reg_byte_size);
- else
- {
- data.Write(reg_value.GetBytes(), reg_info->byte_size);
- for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
- data.PutChar(0);
- }
- return reg_byte_size;
- }
+ void InvalidateAllRegisters() override {
+ // Do nothing... registers are always valid...
+ }
+
+ void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
+ lldb::offset_t offset = 0;
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ bool done = false;
+ while (!done) {
+ int flavor = data.GetU32(&offset);
+ uint32_t count = data.GetU32(&offset);
+ lldb::offset_t next_thread_state = offset + (count * 4);
+ switch (flavor) {
+ case GPRRegSet:
+ // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1
+ // 32-bit register)
+ if (count >= (33 * 2) + 1) {
+ for (uint32_t i = 0; i < 29; ++i)
+ gpr.x[i] = data.GetU64(&offset);
+ gpr.fp = data.GetU64(&offset);
+ gpr.lr = data.GetU64(&offset);
+ gpr.sp = data.GetU64(&offset);
+ gpr.pc = data.GetU64(&offset);
+ gpr.cpsr = data.GetU32(&offset);
+ SetError(GPRRegSet, Read, 0);
+ }
+ offset = next_thread_state;
+ break;
+ case FPURegSet: {
+ uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
+ const int fpu_reg_buf_size = sizeof(fpu);
+ if (fpu_reg_buf_size == count &&
+ data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
+ fpu_reg_buf) == fpu_reg_buf_size) {
+ SetError(FPURegSet, Read, 0);
+ } else {
+ done = true;
+ }
+ }
+ offset = next_thread_state;
+ break;
+ case EXCRegSet:
+ if (count == 4) {
+ exc.far = data.GetU64(&offset);
+ exc.esr = data.GetU32(&offset);
+ exc.exception = data.GetU32(&offset);
+ SetError(EXCRegSet, Read, 0);
}
- // Just write zeros if all else fails
- for (size_t i=0; i<reg_byte_size; ++ i)
+ offset = next_thread_state;
+ break;
+ default:
+ done = true;
+ break;
+ }
+ }
+ }
+
+ static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
+ const char *alt_name, size_t reg_byte_size,
+ Stream &data) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
+ if (reg_info == NULL)
+ reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
+ if (reg_info) {
+ lldb_private::RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ if (reg_info->byte_size >= reg_byte_size)
+ data.Write(reg_value.GetBytes(), reg_byte_size);
+ else {
+ data.Write(reg_value.GetBytes(), reg_info->byte_size);
+ for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
+ ++i)
data.PutChar(0);
+ }
return reg_byte_size;
+ }
}
-
- static bool
- Create_LC_THREAD (Thread *thread, Stream &data)
- {
- RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
- if (reg_ctx_sp)
- {
- RegisterContext *reg_ctx = reg_ctx_sp.get();
-
- data.PutHex32 (GPRRegSet); // Flavor
- data.PutHex32 (GPRWordCount);
- WriteRegister (reg_ctx, "x0", NULL, 8, data);
- WriteRegister (reg_ctx, "x1", NULL, 8, data);
- WriteRegister (reg_ctx, "x2", NULL, 8, data);
- WriteRegister (reg_ctx, "x3", NULL, 8, data);
- WriteRegister (reg_ctx, "x4", NULL, 8, data);
- WriteRegister (reg_ctx, "x5", NULL, 8, data);
- WriteRegister (reg_ctx, "x6", NULL, 8, data);
- WriteRegister (reg_ctx, "x7", NULL, 8, data);
- WriteRegister (reg_ctx, "x8", NULL, 8, data);
- WriteRegister (reg_ctx, "x9", NULL, 8, data);
- WriteRegister (reg_ctx, "x10", NULL, 8, data);
- WriteRegister (reg_ctx, "x11", NULL, 8, data);
- WriteRegister (reg_ctx, "x12", NULL, 8, data);
- WriteRegister (reg_ctx, "x13", NULL, 8, data);
- WriteRegister (reg_ctx, "x14", NULL, 8, data);
- WriteRegister (reg_ctx, "x15", NULL, 8, data);
- WriteRegister (reg_ctx, "x16", NULL, 8, data);
- WriteRegister (reg_ctx, "x17", NULL, 8, data);
- WriteRegister (reg_ctx, "x18", NULL, 8, data);
- WriteRegister (reg_ctx, "x19", NULL, 8, data);
- WriteRegister (reg_ctx, "x20", NULL, 8, data);
- WriteRegister (reg_ctx, "x21", NULL, 8, data);
- WriteRegister (reg_ctx, "x22", NULL, 8, data);
- WriteRegister (reg_ctx, "x23", NULL, 8, data);
- WriteRegister (reg_ctx, "x24", NULL, 8, data);
- WriteRegister (reg_ctx, "x25", NULL, 8, data);
- WriteRegister (reg_ctx, "x26", NULL, 8, data);
- WriteRegister (reg_ctx, "x27", NULL, 8, data);
- WriteRegister (reg_ctx, "x28", NULL, 8, data);
- WriteRegister (reg_ctx, "fp", NULL, 8, data);
- WriteRegister (reg_ctx, "lr", NULL, 8, data);
- WriteRegister (reg_ctx, "sp", NULL, 8, data);
- WriteRegister (reg_ctx, "pc", NULL, 8, data);
- WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
-
- // Write out the EXC registers
-// data.PutHex32 (EXCRegSet);
-// data.PutHex32 (EXCWordCount);
-// WriteRegister (reg_ctx, "far", NULL, 8, data);
-// WriteRegister (reg_ctx, "esr", NULL, 4, data);
-// WriteRegister (reg_ctx, "exception", NULL, 4, data);
- return true;
- }
- return false;
+ // Just write zeros if all else fails
+ for (size_t i = 0; i < reg_byte_size; ++i)
+ data.PutChar(0);
+ return reg_byte_size;
+ }
+
+ static bool Create_LC_THREAD(Thread *thread, Stream &data) {
+ RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
+ if (reg_ctx_sp) {
+ RegisterContext *reg_ctx = reg_ctx_sp.get();
+
+ data.PutHex32(GPRRegSet); // Flavor
+ data.PutHex32(GPRWordCount);
+ WriteRegister(reg_ctx, "x0", NULL, 8, data);
+ WriteRegister(reg_ctx, "x1", NULL, 8, data);
+ WriteRegister(reg_ctx, "x2", NULL, 8, data);
+ WriteRegister(reg_ctx, "x3", NULL, 8, data);
+ WriteRegister(reg_ctx, "x4", NULL, 8, data);
+ WriteRegister(reg_ctx, "x5", NULL, 8, data);
+ WriteRegister(reg_ctx, "x6", NULL, 8, data);
+ WriteRegister(reg_ctx, "x7", NULL, 8, data);
+ WriteRegister(reg_ctx, "x8", NULL, 8, data);
+ WriteRegister(reg_ctx, "x9", NULL, 8, data);
+ WriteRegister(reg_ctx, "x10", NULL, 8, data);
+ WriteRegister(reg_ctx, "x11", NULL, 8, data);
+ WriteRegister(reg_ctx, "x12", NULL, 8, data);
+ WriteRegister(reg_ctx, "x13", NULL, 8, data);
+ WriteRegister(reg_ctx, "x14", NULL, 8, data);
+ WriteRegister(reg_ctx, "x15", NULL, 8, data);
+ WriteRegister(reg_ctx, "x16", NULL, 8, data);
+ WriteRegister(reg_ctx, "x17", NULL, 8, data);
+ WriteRegister(reg_ctx, "x18", NULL, 8, data);
+ WriteRegister(reg_ctx, "x19", NULL, 8, data);
+ WriteRegister(reg_ctx, "x20", NULL, 8, data);
+ WriteRegister(reg_ctx, "x21", NULL, 8, data);
+ WriteRegister(reg_ctx, "x22", NULL, 8, data);
+ WriteRegister(reg_ctx, "x23", NULL, 8, data);
+ WriteRegister(reg_ctx, "x24", NULL, 8, data);
+ WriteRegister(reg_ctx, "x25", NULL, 8, data);
+ WriteRegister(reg_ctx, "x26", NULL, 8, data);
+ WriteRegister(reg_ctx, "x27", NULL, 8, data);
+ WriteRegister(reg_ctx, "x28", NULL, 8, data);
+ WriteRegister(reg_ctx, "fp", NULL, 8, data);
+ WriteRegister(reg_ctx, "lr", NULL, 8, data);
+ WriteRegister(reg_ctx, "sp", NULL, 8, data);
+ WriteRegister(reg_ctx, "pc", NULL, 8, data);
+ WriteRegister(reg_ctx, "cpsr", NULL, 4, data);
+
+ // Write out the EXC registers
+ // data.PutHex32 (EXCRegSet);
+ // data.PutHex32 (EXCWordCount);
+ // WriteRegister (reg_ctx, "far", NULL, 8, data);
+ // WriteRegister (reg_ctx, "esr", NULL, 4, data);
+ // WriteRegister (reg_ctx, "exception", NULL, 4, data);
+ return true;
}
+ return false;
+ }
protected:
- int
- DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
- {
- return -1;
- }
-
- int
- DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
- {
- return -1;
- }
-
- int
- DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
- {
- return -1;
- }
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
- int
- DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
- {
- return -1;
- }
-
- int
- DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
- {
- return 0;
- }
-
- int
- DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
- {
- return 0;
- }
-
- int
- DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
- {
- return 0;
- }
-
- int
- DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
- {
- return -1;
- }
-};
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
-static uint32_t
-MachHeaderSizeFromMagic(uint32_t magic)
-{
- switch (magic)
- {
- case MH_MAGIC:
- case MH_CIGAM:
- return sizeof(struct mach_header);
-
- case MH_MAGIC_64:
- case MH_CIGAM_64:
- return sizeof(struct mach_header_64);
- break;
-
- default:
- break;
- }
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
+
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
+ return 0;
+ }
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
+ return 0;
+ }
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
return 0;
+ }
+
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
+ return -1;
+ }
+};
+
+static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
+ switch (magic) {
+ case MH_MAGIC:
+ case MH_CIGAM:
+ return sizeof(struct mach_header);
+
+ case MH_MAGIC_64:
+ case MH_CIGAM_64:
+ return sizeof(struct mach_header_64);
+ break;
+
+ default:
+ break;
+ }
+ return 0;
}
#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
-void
-ObjectFileMachO::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- CreateMemoryInstance,
- GetModuleSpecifications,
- SaveCore);
+void ObjectFileMachO::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
+ CreateMemoryInstance, GetModuleSpecifications, SaveCore);
}
-void
-ObjectFileMachO::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ObjectFileMachO::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ObjectFileMachO::GetPluginNameStatic()
-{
- static ConstString g_name("mach-o");
- return g_name;
+lldb_private::ConstString ObjectFileMachO::GetPluginNameStatic() {
+ static ConstString g_name("mach-o");
+ return g_name;
}
-const char *
-ObjectFileMachO::GetPluginDescriptionStatic()
-{
- return "Mach-o object file reader (32 and 64 bit)";
+const char *ObjectFileMachO::GetPluginDescriptionStatic() {
+ return "Mach-o object file reader (32 and 64 bit)";
}
-ObjectFile *
-ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length)
-{
- if (!data_sp)
- {
- data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
- data_offset = 0;
- }
-
- if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
- {
- // Update the data to contain the entire file if it doesn't already
- if (data_sp->GetByteSize() < length)
- {
- data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
- data_offset = 0;
- }
- std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length));
- if (objfile_ap.get() && objfile_ap->ParseHeader())
- return objfile_ap.release();
+ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const FileSpec *file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length) {
+ if (!data_sp) {
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length)) {
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length) {
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
+ data_offset = 0;
}
- return NULL;
+ std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO(
+ module_sp, data_sp, data_offset, file, file_offset, length));
+ if (objfile_ap.get() && objfile_ap->ParseHeader())
+ return objfile_ap.release();
+ }
+ return NULL;
}
-ObjectFile *
-ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- const ProcessSP &process_sp,
- lldb::addr_t header_addr)
-{
- if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
- {
- std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
- if (objfile_ap.get() && objfile_ap->ParseHeader())
- return objfile_ap.release();
- }
- return NULL;
+ObjectFile *ObjectFileMachO::CreateMemoryInstance(
+ const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
+ const ProcessSP &process_sp, lldb::addr_t header_addr) {
+ if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
+ std::unique_ptr<ObjectFile> objfile_ap(
+ new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));
+ if (objfile_ap.get() && objfile_ap->ParseHeader())
+ return objfile_ap.release();
+ }
+ return NULL;
}
-size_t
-ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs)
-{
- const size_t initial_count = specs.GetSize();
-
- if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
- {
- DataExtractor data;
+size_t ObjectFileMachO::GetModuleSpecifications(
+ const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, lldb::offset_t file_offset,
+ lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
+ const size_t initial_count = specs.GetSize();
+
+ if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
+ DataExtractor data;
+ data.SetData(data_sp);
+ llvm::MachO::mach_header header;
+ if (ParseHeader(data, &data_offset, header)) {
+ size_t header_and_load_cmds =
+ header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
+ if (header_and_load_cmds >= data_sp->GetByteSize()) {
+ data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
data.SetData(data_sp);
- llvm::MachO::mach_header header;
- if (ParseHeader (data, &data_offset, header))
- {
- size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
- if (header_and_load_cmds >= data_sp->GetByteSize())
- {
- data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
- data.SetData(data_sp);
- data_offset = MachHeaderSizeFromMagic(header.magic);
- }
- if (data_sp)
- {
- ModuleSpec spec;
- spec.GetFileSpec() = file;
- 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);
- }
- }
- }
+ data_offset = MachHeaderSizeFromMagic(header.magic);
+ }
+ if (data_sp) {
+ ModuleSpec spec;
+ spec.GetFileSpec() = file;
+ 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);
+ }
}
+ }
}
- return specs.GetSize() - initial_count;
+ }
+ return specs.GetSize() - initial_count;
}
-const ConstString &
-ObjectFileMachO::GetSegmentNameTEXT()
-{
- static ConstString g_segment_name_TEXT ("__TEXT");
- return g_segment_name_TEXT;
+const ConstString &ObjectFileMachO::GetSegmentNameTEXT() {
+ static ConstString g_segment_name_TEXT("__TEXT");
+ return g_segment_name_TEXT;
}
-const ConstString &
-ObjectFileMachO::GetSegmentNameDATA()
-{
- static ConstString g_segment_name_DATA ("__DATA");
- return g_segment_name_DATA;
+const ConstString &ObjectFileMachO::GetSegmentNameDATA() {
+ static ConstString g_segment_name_DATA("__DATA");
+ return g_segment_name_DATA;
}
-const ConstString &
-ObjectFileMachO::GetSegmentNameDATA_DIRTY()
-{
- static ConstString g_segment_name ("__DATA_DIRTY");
- return g_segment_name;
+const ConstString &ObjectFileMachO::GetSegmentNameDATA_DIRTY() {
+ static ConstString g_segment_name("__DATA_DIRTY");
+ return g_segment_name;
}
-const ConstString &
-ObjectFileMachO::GetSegmentNameDATA_CONST()
-{
- static ConstString g_segment_name ("__DATA_CONST");
- return g_segment_name;
+const ConstString &ObjectFileMachO::GetSegmentNameDATA_CONST() {
+ static ConstString g_segment_name("__DATA_CONST");
+ return g_segment_name;
}
-const ConstString &
-ObjectFileMachO::GetSegmentNameOBJC()
-{
- static ConstString g_segment_name_OBJC ("__OBJC");
- return g_segment_name_OBJC;
+const ConstString &ObjectFileMachO::GetSegmentNameOBJC() {
+ static ConstString g_segment_name_OBJC("__OBJC");
+ return g_segment_name_OBJC;
}
-const ConstString &
-ObjectFileMachO::GetSegmentNameLINKEDIT()
-{
- static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
- return g_section_name_LINKEDIT;
+const ConstString &ObjectFileMachO::GetSegmentNameLINKEDIT() {
+ static ConstString g_section_name_LINKEDIT("__LINKEDIT");
+ return g_section_name_LINKEDIT;
}
-const ConstString &
-ObjectFileMachO::GetSectionNameEHFrame()
-{
- static ConstString g_section_name_eh_frame ("__eh_frame");
- return g_section_name_eh_frame;
+const ConstString &ObjectFileMachO::GetSectionNameEHFrame() {
+ static ConstString g_section_name_eh_frame("__eh_frame");
+ return g_section_name_eh_frame;
}
-bool
-ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
- lldb::addr_t data_offset,
- lldb::addr_t data_length)
-{
- DataExtractor data;
- data.SetData (data_sp, data_offset, data_length);
- lldb::offset_t offset = 0;
- uint32_t magic = data.GetU32(&offset);
- return MachHeaderSizeFromMagic(magic) != 0;
+bool ObjectFileMachO::MagicBytesMatch(DataBufferSP &data_sp,
+ lldb::addr_t data_offset,
+ lldb::addr_t data_length) {
+ DataExtractor data;
+ data.SetData(data_sp, data_offset, data_length);
+ lldb::offset_t offset = 0;
+ uint32_t magic = data.GetU32(&offset);
+ return MachHeaderSizeFromMagic(magic) != 0;
}
ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
+ DataBufferSP &data_sp,
lldb::offset_t data_offset,
- const FileSpec* file,
+ const FileSpec *file,
lldb::offset_t file_offset,
- lldb::offset_t length) :
- ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_mach_segments(),
- m_mach_sections(),
- m_entry_point_address(),
- m_thread_context_offsets(),
- m_thread_context_offsets_valid(false),
- m_reexported_dylibs (),
- m_allow_assembly_emulation_unwind_plans (true)
-{
- ::memset (&m_header, 0, sizeof(m_header));
- ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
+ lldb::offset_t length)
+ : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
+ m_mach_segments(), m_mach_sections(), m_entry_point_address(),
+ m_thread_context_offsets(), m_thread_context_offsets_valid(false),
+ m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
+ ::memset(&m_header, 0, sizeof(m_header));
+ ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
}
-ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& header_data_sp,
- const lldb::ProcessSP &process_sp,
- lldb::addr_t header_addr) :
- ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_mach_segments(),
- m_mach_sections(),
- m_entry_point_address(),
- m_thread_context_offsets(),
- m_thread_context_offsets_valid(false),
- m_reexported_dylibs (),
- m_allow_assembly_emulation_unwind_plans (true)
-{
- ::memset (&m_header, 0, sizeof(m_header));
- ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
+ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &header_data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr)
+ : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
+ m_mach_segments(), m_mach_sections(), m_entry_point_address(),
+ m_thread_context_offsets(), m_thread_context_offsets_valid(false),
+ m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
+ ::memset(&m_header, 0, sizeof(m_header));
+ ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
}
-bool
-ObjectFileMachO::ParseHeader (DataExtractor &data,
- lldb::offset_t *data_offset_ptr,
- llvm::MachO::mach_header &header)
-{
- data.SetByteOrder (endian::InlHostByteOrder());
- // Leave magic in the original byte order
- header.magic = data.GetU32(data_offset_ptr);
- bool can_parse = false;
- bool is_64_bit = false;
- switch (header.magic)
- {
- case MH_MAGIC:
- data.SetByteOrder (endian::InlHostByteOrder());
- data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_MAGIC_64:
- data.SetByteOrder (endian::InlHostByteOrder());
- data.SetAddressByteSize(8);
- can_parse = true;
- is_64_bit = true;
- break;
-
- case MH_CIGAM:
- data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
- data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_CIGAM_64:
- data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
- data.SetAddressByteSize(8);
- is_64_bit = true;
- can_parse = true;
- break;
-
- default:
- break;
- }
-
- if (can_parse)
- {
- data.GetU32(data_offset_ptr, &header.cputype, 6);
- if (is_64_bit)
- *data_offset_ptr += 4;
- return true;
- }
- else
- {
- memset(&header, 0, sizeof(header));
- }
- return false;
+bool ObjectFileMachO::ParseHeader(DataExtractor &data,
+ lldb::offset_t *data_offset_ptr,
+ llvm::MachO::mach_header &header) {
+ data.SetByteOrder(endian::InlHostByteOrder());
+ // Leave magic in the original byte order
+ header.magic = data.GetU32(data_offset_ptr);
+ bool can_parse = false;
+ bool is_64_bit = false;
+ switch (header.magic) {
+ case MH_MAGIC:
+ data.SetByteOrder(endian::InlHostByteOrder());
+ data.SetAddressByteSize(4);
+ can_parse = true;
+ break;
+
+ case MH_MAGIC_64:
+ data.SetByteOrder(endian::InlHostByteOrder());
+ data.SetAddressByteSize(8);
+ can_parse = true;
+ is_64_bit = true;
+ break;
+
+ case MH_CIGAM:
+ data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
+ ? eByteOrderLittle
+ : eByteOrderBig);
+ data.SetAddressByteSize(4);
+ can_parse = true;
+ break;
+
+ case MH_CIGAM_64:
+ data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
+ ? eByteOrderLittle
+ : eByteOrderBig);
+ data.SetAddressByteSize(8);
+ is_64_bit = true;
+ can_parse = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (can_parse) {
+ data.GetU32(data_offset_ptr, &header.cputype, 6);
+ if (is_64_bit)
+ *data_offset_ptr += 4;
+ return true;
+ } else {
+ memset(&header, 0, sizeof(header));
+ }
+ return false;
}
-bool
-ObjectFileMachO::ParseHeader ()
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- bool can_parse = false;
- lldb::offset_t offset = 0;
- m_data.SetByteOrder (endian::InlHostByteOrder());
- // Leave magic in the original byte order
- m_header.magic = m_data.GetU32(&offset);
- switch (m_header.magic)
- {
- case MH_MAGIC:
- m_data.SetByteOrder (endian::InlHostByteOrder());
- m_data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_MAGIC_64:
- m_data.SetByteOrder (endian::InlHostByteOrder());
- m_data.SetAddressByteSize(8);
- can_parse = true;
- break;
-
- case MH_CIGAM:
- m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
- m_data.SetAddressByteSize(4);
- can_parse = true;
- break;
-
- case MH_CIGAM_64:
- m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
- m_data.SetAddressByteSize(8);
- can_parse = true;
- break;
-
- default:
- break;
- }
-
- if (can_parse)
- {
- m_data.GetU32(&offset, &m_header.cputype, 6);
+bool ObjectFileMachO::ParseHeader() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ bool can_parse = false;
+ lldb::offset_t offset = 0;
+ m_data.SetByteOrder(endian::InlHostByteOrder());
+ // Leave magic in the original byte order
+ m_header.magic = m_data.GetU32(&offset);
+ switch (m_header.magic) {
+ case MH_MAGIC:
+ m_data.SetByteOrder(endian::InlHostByteOrder());
+ m_data.SetAddressByteSize(4);
+ can_parse = true;
+ break;
+
+ case MH_MAGIC_64:
+ m_data.SetByteOrder(endian::InlHostByteOrder());
+ m_data.SetAddressByteSize(8);
+ can_parse = true;
+ break;
+
+ case MH_CIGAM:
+ m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
+ ? eByteOrderLittle
+ : eByteOrderBig);
+ m_data.SetAddressByteSize(4);
+ can_parse = true;
+ break;
+
+ case MH_CIGAM_64:
+ m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
+ ? eByteOrderLittle
+ : eByteOrderBig);
+ m_data.SetAddressByteSize(8);
+ can_parse = true;
+ break;
+
+ default:
+ break;
+ }
-
- ArchSpec mach_arch;
-
- if (GetArchitecture (mach_arch))
- {
- // Check if the module has a required architecture
- const ArchSpec &module_arch = module_sp->GetArchitecture();
- if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
- return false;
-
- if (SetModulesArchitecture (mach_arch))
- {
- const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
- if (m_data.GetByteSize() < header_and_lc_size)
- {
- DataBufferSP data_sp;
- ProcessSP process_sp (m_process_wp.lock());
- if (process_sp)
- {
- data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
- }
- else
- {
- // Read in all only the load command data from the file on disk
- data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
- if (data_sp->GetByteSize() != header_and_lc_size)
- return false;
- }
- if (data_sp)
- m_data.SetData (data_sp);
- }
- }
- return true;
+ if (can_parse) {
+ m_data.GetU32(&offset, &m_header.cputype, 6);
+
+ ArchSpec mach_arch;
+
+ if (GetArchitecture(mach_arch)) {
+ // Check if the module has a required architecture
+ const ArchSpec &module_arch = module_sp->GetArchitecture();
+ if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
+ return false;
+
+ if (SetModulesArchitecture(mach_arch)) {
+ const size_t header_and_lc_size =
+ m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
+ if (m_data.GetByteSize() < header_and_lc_size) {
+ DataBufferSP data_sp;
+ ProcessSP process_sp(m_process_wp.lock());
+ if (process_sp) {
+ data_sp =
+ ReadMemory(process_sp, m_memory_addr, header_and_lc_size);
+ } else {
+ // Read in all only the load command data from the file on disk
+ data_sp =
+ m_file.ReadFileContents(m_file_offset, header_and_lc_size);
+ if (data_sp->GetByteSize() != header_and_lc_size)
+ return false;
}
+ if (data_sp)
+ m_data.SetData(data_sp);
+ }
}
- else
- {
- memset(&m_header, 0, sizeof(struct mach_header));
- }
+ return true;
+ }
+ } else {
+ memset(&m_header, 0, sizeof(struct mach_header));
}
- return false;
+ }
+ return false;
}
-ByteOrder
-ObjectFileMachO::GetByteOrder () const
-{
- return m_data.GetByteOrder ();
+ByteOrder ObjectFileMachO::GetByteOrder() const {
+ return m_data.GetByteOrder();
}
-bool
-ObjectFileMachO::IsExecutable() const
-{
- return m_header.filetype == MH_EXECUTE;
+bool ObjectFileMachO::IsExecutable() const {
+ return m_header.filetype == MH_EXECUTE;
}
-uint32_t
-ObjectFileMachO::GetAddressByteSize () const
-{
- return m_data.GetAddressByteSize ();
+uint32_t ObjectFileMachO::GetAddressByteSize() const {
+ return m_data.GetAddressByteSize();
}
-AddressClass
-ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
-{
- Symtab *symtab = GetSymtab();
- if (symtab)
- {
- Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
- if (symbol)
- {
- if (symbol->ValueIsAddress())
- {
- SectionSP section_sp (symbol->GetAddressRef().GetSection());
- if (section_sp)
- {
- const lldb::SectionType section_type = section_sp->GetType();
- switch (section_type)
- {
- case eSectionTypeInvalid:
- return eAddressClassUnknown;
-
- case eSectionTypeCode:
- if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
- {
- // For ARM we have a bit in the n_desc field of the symbol
- // that tells us ARM/Thumb which is bit 0x0008.
- if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
- return eAddressClassCodeAlternateISA;
- }
- return eAddressClassCode;
-
- case eSectionTypeContainer:
- return eAddressClassUnknown;
-
- case eSectionTypeData:
- case eSectionTypeDataCString:
- case eSectionTypeDataCStringPointers:
- case eSectionTypeDataSymbolAddress:
- case eSectionTypeData4:
- case eSectionTypeData8:
- case eSectionTypeData16:
- case eSectionTypeDataPointers:
- case eSectionTypeZeroFill:
- case eSectionTypeDataObjCMessageRefs:
- case eSectionTypeDataObjCCFStrings:
- case eSectionTypeGoSymtab:
- return eAddressClassData;
-
- case eSectionTypeDebug:
- case eSectionTypeDWARFDebugAbbrev:
- case eSectionTypeDWARFDebugAddr:
- case eSectionTypeDWARFDebugAranges:
- case eSectionTypeDWARFDebugFrame:
- case eSectionTypeDWARFDebugInfo:
- case eSectionTypeDWARFDebugLine:
- case eSectionTypeDWARFDebugLoc:
- case eSectionTypeDWARFDebugMacInfo:
- case eSectionTypeDWARFDebugMacro:
- case eSectionTypeDWARFDebugPubNames:
- case eSectionTypeDWARFDebugPubTypes:
- case eSectionTypeDWARFDebugRanges:
- case eSectionTypeDWARFDebugStr:
- case eSectionTypeDWARFDebugStrOffsets:
- case eSectionTypeDWARFAppleNames:
- case eSectionTypeDWARFAppleTypes:
- case eSectionTypeDWARFAppleNamespaces:
- case eSectionTypeDWARFAppleObjC:
- return eAddressClassDebug;
-
- case eSectionTypeEHFrame:
- case eSectionTypeARMexidx:
- case eSectionTypeARMextab:
- case eSectionTypeCompactUnwind:
- return eAddressClassRuntime;
-
- case eSectionTypeAbsoluteAddress:
- case eSectionTypeELFSymbolTable:
- case eSectionTypeELFDynamicSymbols:
- case eSectionTypeELFRelocationEntries:
- case eSectionTypeELFDynamicLinkInfo:
- case eSectionTypeOther:
- return eAddressClassUnknown;
- }
- }
- }
-
- const SymbolType symbol_type = symbol->GetType();
- switch (symbol_type)
- {
- case eSymbolTypeAny: return eAddressClassUnknown;
- case eSymbolTypeAbsolute: return eAddressClassUnknown;
-
- case eSymbolTypeCode:
- case eSymbolTypeTrampoline:
- case eSymbolTypeResolver:
- if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
- {
- // For ARM we have a bit in the n_desc field of the symbol
- // that tells us ARM/Thumb which is bit 0x0008.
- if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
- return eAddressClassCodeAlternateISA;
- }
- return eAddressClassCode;
-
- case eSymbolTypeData: return eAddressClassData;
- case eSymbolTypeRuntime: return eAddressClassRuntime;
- case eSymbolTypeException: return eAddressClassRuntime;
- case eSymbolTypeSourceFile: return eAddressClassDebug;
- case eSymbolTypeHeaderFile: return eAddressClassDebug;
- case eSymbolTypeObjectFile: return eAddressClassDebug;
- case eSymbolTypeCommonBlock: return eAddressClassDebug;
- case eSymbolTypeBlock: return eAddressClassDebug;
- case eSymbolTypeLocal: return eAddressClassData;
- case eSymbolTypeParam: return eAddressClassData;
- case eSymbolTypeVariable: return eAddressClassData;
- case eSymbolTypeVariableType: return eAddressClassDebug;
- case eSymbolTypeLineEntry: return eAddressClassDebug;
- case eSymbolTypeLineHeader: return eAddressClassDebug;
- case eSymbolTypeScopeBegin: return eAddressClassDebug;
- case eSymbolTypeScopeEnd: return eAddressClassDebug;
- case eSymbolTypeAdditional: return eAddressClassUnknown;
- case eSymbolTypeCompiler: return eAddressClassDebug;
- case eSymbolTypeInstrumentation:return eAddressClassDebug;
- case eSymbolTypeUndefined: return eAddressClassUnknown;
- case eSymbolTypeObjCClass: return eAddressClassRuntime;
- case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
- case eSymbolTypeObjCIVar: return eAddressClassRuntime;
- case eSymbolTypeReExported: return eAddressClassRuntime;
+AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
+ Symtab *symtab = GetSymtab();
+ if (symtab) {
+ Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
+ if (symbol) {
+ if (symbol->ValueIsAddress()) {
+ SectionSP section_sp(symbol->GetAddressRef().GetSection());
+ if (section_sp) {
+ const lldb::SectionType section_type = section_sp->GetType();
+ switch (section_type) {
+ case eSectionTypeInvalid:
+ return eAddressClassUnknown;
+
+ case eSectionTypeCode:
+ if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
+ // For ARM we have a bit in the n_desc field of the symbol
+ // that tells us ARM/Thumb which is bit 0x0008.
+ if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
+ return eAddressClassCodeAlternateISA;
}
+ return eAddressClassCode;
+
+ case eSectionTypeContainer:
+ return eAddressClassUnknown;
+
+ case eSectionTypeData:
+ case eSectionTypeDataCString:
+ case eSectionTypeDataCStringPointers:
+ case eSectionTypeDataSymbolAddress:
+ case eSectionTypeData4:
+ case eSectionTypeData8:
+ case eSectionTypeData16:
+ case eSectionTypeDataPointers:
+ case eSectionTypeZeroFill:
+ case eSectionTypeDataObjCMessageRefs:
+ case eSectionTypeDataObjCCFStrings:
+ case eSectionTypeGoSymtab:
+ return eAddressClassData;
+
+ case eSectionTypeDebug:
+ case eSectionTypeDWARFDebugAbbrev:
+ case eSectionTypeDWARFDebugAddr:
+ case eSectionTypeDWARFDebugAranges:
+ case eSectionTypeDWARFDebugFrame:
+ case eSectionTypeDWARFDebugInfo:
+ case eSectionTypeDWARFDebugLine:
+ case eSectionTypeDWARFDebugLoc:
+ case eSectionTypeDWARFDebugMacInfo:
+ case eSectionTypeDWARFDebugMacro:
+ case eSectionTypeDWARFDebugPubNames:
+ case eSectionTypeDWARFDebugPubTypes:
+ case eSectionTypeDWARFDebugRanges:
+ case eSectionTypeDWARFDebugStr:
+ case eSectionTypeDWARFDebugStrOffsets:
+ case eSectionTypeDWARFAppleNames:
+ case eSectionTypeDWARFAppleTypes:
+ case eSectionTypeDWARFAppleNamespaces:
+ case eSectionTypeDWARFAppleObjC:
+ return eAddressClassDebug;
+
+ case eSectionTypeEHFrame:
+ case eSectionTypeARMexidx:
+ case eSectionTypeARMextab:
+ case eSectionTypeCompactUnwind:
+ return eAddressClassRuntime;
+
+ case eSectionTypeAbsoluteAddress:
+ case eSectionTypeELFSymbolTable:
+ case eSectionTypeELFDynamicSymbols:
+ case eSectionTypeELFRelocationEntries:
+ case eSectionTypeELFDynamicLinkInfo:
+ case eSectionTypeOther:
+ return eAddressClassUnknown;
+ }
}
+ }
+
+ const SymbolType symbol_type = symbol->GetType();
+ switch (symbol_type) {
+ case eSymbolTypeAny:
+ return eAddressClassUnknown;
+ case eSymbolTypeAbsolute:
+ return eAddressClassUnknown;
+
+ case eSymbolTypeCode:
+ case eSymbolTypeTrampoline:
+ case eSymbolTypeResolver:
+ if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
+ // For ARM we have a bit in the n_desc field of the symbol
+ // that tells us ARM/Thumb which is bit 0x0008.
+ if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
+ return eAddressClassCodeAlternateISA;
+ }
+ return eAddressClassCode;
+
+ case eSymbolTypeData:
+ return eAddressClassData;
+ case eSymbolTypeRuntime:
+ return eAddressClassRuntime;
+ case eSymbolTypeException:
+ return eAddressClassRuntime;
+ case eSymbolTypeSourceFile:
+ return eAddressClassDebug;
+ case eSymbolTypeHeaderFile:
+ return eAddressClassDebug;
+ case eSymbolTypeObjectFile:
+ return eAddressClassDebug;
+ case eSymbolTypeCommonBlock:
+ return eAddressClassDebug;
+ case eSymbolTypeBlock:
+ return eAddressClassDebug;
+ case eSymbolTypeLocal:
+ return eAddressClassData;
+ case eSymbolTypeParam:
+ return eAddressClassData;
+ case eSymbolTypeVariable:
+ return eAddressClassData;
+ case eSymbolTypeVariableType:
+ return eAddressClassDebug;
+ case eSymbolTypeLineEntry:
+ return eAddressClassDebug;
+ case eSymbolTypeLineHeader:
+ return eAddressClassDebug;
+ case eSymbolTypeScopeBegin:
+ return eAddressClassDebug;
+ case eSymbolTypeScopeEnd:
+ return eAddressClassDebug;
+ case eSymbolTypeAdditional:
+ return eAddressClassUnknown;
+ case eSymbolTypeCompiler:
+ return eAddressClassDebug;
+ case eSymbolTypeInstrumentation:
+ return eAddressClassDebug;
+ case eSymbolTypeUndefined:
+ return eAddressClassUnknown;
+ case eSymbolTypeObjCClass:
+ return eAddressClassRuntime;
+ case eSymbolTypeObjCMetaClass:
+ return eAddressClassRuntime;
+ case eSymbolTypeObjCIVar:
+ return eAddressClassRuntime;
+ case eSymbolTypeReExported:
+ return eAddressClassRuntime;
+ }
+ }
+ }
+ return eAddressClassUnknown;
+}
+
+Symtab *ObjectFileMachO::GetSymtab() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (m_symtab_ap.get() == NULL) {
+ m_symtab_ap.reset(new Symtab(this));
+ std::lock_guard<std::recursive_mutex> symtab_guard(
+ m_symtab_ap->GetMutex());
+ ParseSymtab();
+ m_symtab_ap->Finalize();
}
- return eAddressClassUnknown;
+ }
+ return m_symtab_ap.get();
}
-Symtab *
-ObjectFileMachO::GetSymtab()
-{
+bool ObjectFileMachO::IsStripped() {
+ if (m_dysymtab.cmd == 0) {
ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_symtab_ap.get() == NULL)
- {
- m_symtab_ap.reset(new Symtab(this));
- std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex());
- ParseSymtab ();
- m_symtab_ap->Finalize ();
+ if (module_sp) {
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ for (uint32_t i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t load_cmd_offset = offset;
+
+ load_command lc;
+ if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
+ break;
+ if (lc.cmd == LC_DYSYMTAB) {
+ m_dysymtab.cmd = lc.cmd;
+ m_dysymtab.cmdsize = lc.cmdsize;
+ if (m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
+ (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) ==
+ NULL) {
+ // Clear m_dysymtab if we were unable to read all items from the
+ // load command
+ ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
+ }
}
+ offset = load_cmd_offset + lc.cmdsize;
+ }
}
- return m_symtab_ap.get();
+ }
+ if (m_dysymtab.cmd)
+ return m_dysymtab.nlocalsym <= 1;
+ return false;
}
-bool
-ObjectFileMachO::IsStripped ()
-{
- if (m_dysymtab.cmd == 0)
- {
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- for (uint32_t i=0; i<m_header.ncmds; ++i)
- {
- const lldb::offset_t load_cmd_offset = offset;
-
- load_command lc;
- if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
- break;
- if (lc.cmd == LC_DYSYMTAB)
- {
- m_dysymtab.cmd = lc.cmd;
- m_dysymtab.cmdsize = lc.cmdsize;
- if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
- {
- // Clear m_dysymtab if we were unable to read all items from the load command
- ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
- }
- }
- offset = load_cmd_offset + lc.cmdsize;
- }
+void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
+ if (!m_sections_ap.get()) {
+ m_sections_ap.reset(new SectionList());
+
+ const bool is_dsym = (m_header.filetype == MH_DSYM);
+ lldb::user_id_t segID = 0;
+ lldb::user_id_t sectID = 0;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ uint32_t i;
+ const bool is_core = GetType() == eTypeCoreFile;
+ // bool dump_sections = false;
+ ModuleSP module_sp(GetModule());
+ // First look up any LC_ENCRYPTION_INFO load commands
+ typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
+ EncryptedFileRanges encrypted_file_ranges;
+ encryption_info_command encryption_cmd;
+ for (i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t load_cmd_offset = offset;
+ if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
+ break;
+
+ // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
+ // the 3 fields we care about, so treat them the same.
+ if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
+ encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
+ if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
+ if (encryption_cmd.cryptid != 0) {
+ EncryptedFileRanges::Entry entry;
+ entry.SetRangeBase(encryption_cmd.cryptoff);
+ entry.SetByteSize(encryption_cmd.cryptsize);
+ encrypted_file_ranges.Append(entry);
+ }
}
+ }
+ offset = load_cmd_offset + encryption_cmd.cmdsize;
}
- if (m_dysymtab.cmd)
- return m_dysymtab.nlocalsym <= 1;
- return false;
-}
-void
-ObjectFileMachO::CreateSections (SectionList &unified_section_list)
-{
- if (!m_sections_ap.get())
- {
- m_sections_ap.reset(new SectionList());
-
- const bool is_dsym = (m_header.filetype == MH_DSYM);
- lldb::user_id_t segID = 0;
- lldb::user_id_t sectID = 0;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t i;
- const bool is_core = GetType() == eTypeCoreFile;
- //bool dump_sections = false;
- ModuleSP module_sp (GetModule());
- // First look up any LC_ENCRYPTION_INFO load commands
- typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
- EncryptedFileRanges encrypted_file_ranges;
- encryption_info_command encryption_cmd;
- for (i=0; i<m_header.ncmds; ++i)
- {
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
- break;
+ bool section_file_addresses_changed = false;
+
+ offset = MachHeaderSizeFromMagic(m_header.magic);
+
+ struct segment_command_64 load_cmd;
+ for (i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t load_cmd_offset = offset;
+ if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
+
+ if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64) {
+ if (m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16)) {
+ bool add_section = true;
+ bool add_to_unified = true;
+ ConstString const_segname(load_cmd.segname,
+ std::min<size_t>(strlen(load_cmd.segname),
+ sizeof(load_cmd.segname)));
+
+ SectionSP unified_section_sp(
+ unified_section_list.FindSectionByName(const_segname));
+ if (is_dsym && unified_section_sp) {
+ if (const_segname == GetSegmentNameLINKEDIT()) {
+ // We need to keep the __LINKEDIT segment private to this object
+ // file only
+ add_to_unified = false;
+ } else {
+ // This is the dSYM file and this section has already been created
+ // by
+ // the object file, no need to create it.
+ add_section = false;
+ }
+ }
+ load_cmd.vmaddr = m_data.GetAddress(&offset);
+ load_cmd.vmsize = m_data.GetAddress(&offset);
+ load_cmd.fileoff = m_data.GetAddress(&offset);
+ load_cmd.filesize = m_data.GetAddress(&offset);
+ if (m_length != 0 && load_cmd.filesize != 0) {
+ if (load_cmd.fileoff > m_length) {
+ // We have a load command that says it extends past the end of the
+ // file. This is likely
+ // a corrupt file. We don't have any way to return an error
+ // condition here (this method
+ // was likely invoked from something like
+ // ObjectFile::GetSectionList()) -- all we can do
+ // is null out the SectionList vector and if a process has been
+ // set up, dump a message
+ // to stdout. The most common case here is core file debugging
+ // with a truncated file.
+ const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64
+ ? "LC_SEGMENT_64"
+ : "LC_SEGMENT";
+ module_sp->ReportWarning(
+ "load command %u %s has a fileoff (0x%" PRIx64
+ ") that extends beyond the end of the file (0x%" PRIx64
+ "), ignoring this section",
+ i, lc_segment_name, load_cmd.fileoff, m_length);
+
+ load_cmd.fileoff = 0;
+ load_cmd.filesize = 0;
+ }
- // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
- // the 3 fields we care about, so treat them the same.
- if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || encryption_cmd.cmd == LC_ENCRYPTION_INFO_64)
- {
- if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
- {
- if (encryption_cmd.cryptid != 0)
- {
- EncryptedFileRanges::Entry entry;
- entry.SetRangeBase(encryption_cmd.cryptoff);
- entry.SetByteSize(encryption_cmd.cryptsize);
- encrypted_file_ranges.Append(entry);
- }
+ if (load_cmd.fileoff + load_cmd.filesize > m_length) {
+ // We have a load command that says it extends past the end of the
+ // file. This is likely
+ // a corrupt file. We don't have any way to return an error
+ // condition here (this method
+ // was likely invoked from something like
+ // ObjectFile::GetSectionList()) -- all we can do
+ // is null out the SectionList vector and if a process has been
+ // set up, dump a message
+ // to stdout. The most common case here is core file debugging
+ // with a truncated file.
+ const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64
+ ? "LC_SEGMENT_64"
+ : "LC_SEGMENT";
+ GetModule()->ReportWarning(
+ "load command %u %s has a fileoff + filesize (0x%" PRIx64
+ ") that extends beyond the end of the file (0x%" PRIx64
+ "), the segment will be truncated to match",
+ i, lc_segment_name, load_cmd.fileoff + load_cmd.filesize,
+ m_length);
+
+ // Tuncase the length
+ load_cmd.filesize = m_length - load_cmd.fileoff;
+ }
+ }
+ if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) {
+ uint32_t segment_permissions = 0;
+ if (load_cmd.initprot & VM_PROT_READ)
+ segment_permissions |= ePermissionsReadable;
+ if (load_cmd.initprot & VM_PROT_WRITE)
+ segment_permissions |= ePermissionsWritable;
+ if (load_cmd.initprot & VM_PROT_EXECUTE)
+ segment_permissions |= ePermissionsExecutable;
+
+ const bool segment_is_encrypted =
+ (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
+
+ // Keep a list of mach segments around in case we need to
+ // get at data that isn't stored in the abstracted Sections.
+ m_mach_segments.push_back(load_cmd);
+
+ // Use a segment ID of the segment index shifted left by 8 so they
+ // never conflict with any of the sections.
+ SectionSP segment_sp;
+ if (add_section && (const_segname || is_core)) {
+ segment_sp.reset(new Section(
+ module_sp, // Module to which this section belongs
+ this, // Object file to which this sections belongs
+ ++segID << 8, // Section ID is the 1 based segment index
+ // shifted right by 8 bits as not to collide
+ // with any of the 256 section IDs that are
+ // possible
+ const_segname, // Name of this section
+ eSectionTypeContainer, // This section is a container of other
+ // sections.
+ load_cmd.vmaddr, // File VM address == addresses as they are
+ // found in the object file
+ load_cmd.vmsize, // VM size in bytes of this section
+ load_cmd.fileoff, // Offset to the data for this section in
+ // the file
+ load_cmd.filesize, // Size in bytes of this section as found
+ // in the file
+ 0, // Segments have no alignment information
+ load_cmd.flags)); // Flags for this section
+
+ segment_sp->SetIsEncrypted(segment_is_encrypted);
+ m_sections_ap->AddSection(segment_sp);
+ segment_sp->SetPermissions(segment_permissions);
+ if (add_to_unified)
+ unified_section_list.AddSection(segment_sp);
+ } else if (unified_section_sp) {
+ if (is_dsym &&
+ unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
+ // Check to see if the module was read from memory?
+ if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
+ // We have a module that is in memory and needs to have its
+ // file address adjusted. We need to do this because when we
+ // load a file from memory, its addresses will be slid
+ // already,
+ // yet the addresses in the new symbol file will still be
+ // unslid.
+ // Since everything is stored as section offset, this
+ // shouldn't
+ // cause any problems.
+
+ // Make sure we've parsed the symbol table from the
+ // ObjectFile before we go around changing its Sections.
+ module_sp->GetObjectFile()->GetSymtab();
+ // eh_frame would present the same problems but we parse that
+ // on
+ // a per-function basis as-needed so it's more difficult to
+ // remove its use of the Sections. Realistically, the
+ // environments
+ // where this code path will be taken will not have eh_frame
+ // sections.
+
+ unified_section_sp->SetFileAddress(load_cmd.vmaddr);
+
+ // Notify the module that the section addresses have been
+ // changed once
+ // we're done so any file-address caches can be updated.
+ section_file_addresses_changed = true;
}
+ }
+ m_sections_ap->AddSection(unified_section_sp);
}
- offset = load_cmd_offset + encryption_cmd.cmdsize;
- }
- bool section_file_addresses_changed = false;
-
- offset = MachHeaderSizeFromMagic(m_header.magic);
+ struct section_64 sect64;
+ ::memset(&sect64, 0, sizeof(sect64));
+ // Push a section into our mach sections for the section at
+ // index zero (NO_SECT) if we don't have any mach sections yet...
+ if (m_mach_sections.empty())
+ m_mach_sections.push_back(sect64);
+ uint32_t segment_sect_idx;
+ const lldb::user_id_t first_segment_sectID = sectID + 1;
+
+ const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
+ for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
+ ++segment_sect_idx) {
+ if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname,
+ sizeof(sect64.sectname)) == NULL)
+ break;
+ if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,
+ sizeof(sect64.segname)) == NULL)
+ break;
+ sect64.addr = m_data.GetAddress(&offset);
+ sect64.size = m_data.GetAddress(&offset);
- struct segment_command_64 load_cmd;
- for (i=0; i<m_header.ncmds; ++i)
- {
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+ if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
break;
- if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
- {
- if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
- {
- bool add_section = true;
- bool add_to_unified = true;
- ConstString const_segname (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
-
- SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
- if (is_dsym && unified_section_sp)
- {
- if (const_segname == GetSegmentNameLINKEDIT())
- {
- // We need to keep the __LINKEDIT segment private to this object file only
- add_to_unified = false;
- }
- else
- {
- // This is the dSYM file and this section has already been created by
- // the object file, no need to create it.
- add_section = false;
- }
+ // Keep a list of mach sections around in case we need to
+ // get at data that isn't stored in the abstracted Sections.
+ m_mach_sections.push_back(sect64);
+
+ if (add_section) {
+ ConstString section_name(
+ sect64.sectname, std::min<size_t>(strlen(sect64.sectname),
+ sizeof(sect64.sectname)));
+ if (!const_segname) {
+ // We have a segment with no name so we need to conjure up
+ // segments that correspond to the section's segname if there
+ // isn't already such a section. If there is such a section,
+ // we resize the section so that it spans all sections.
+ // We also mark these sections as fake so address matches
+ // don't
+ // hit if they land in the gaps between the child sections.
+ const_segname.SetTrimmedCStringWithLength(
+ sect64.segname, sizeof(sect64.segname));
+ segment_sp =
+ unified_section_list.FindSectionByName(const_segname);
+ if (segment_sp.get()) {
+ Section *segment = segment_sp.get();
+ // Grow the section size as needed.
+ const lldb::addr_t sect64_min_addr = sect64.addr;
+ const lldb::addr_t sect64_max_addr =
+ sect64_min_addr + sect64.size;
+ const lldb::addr_t curr_seg_byte_size =
+ segment->GetByteSize();
+ const lldb::addr_t curr_seg_min_addr =
+ segment->GetFileAddress();
+ const lldb::addr_t curr_seg_max_addr =
+ curr_seg_min_addr + curr_seg_byte_size;
+ if (sect64_min_addr >= curr_seg_min_addr) {
+ const lldb::addr_t new_seg_byte_size =
+ sect64_max_addr - curr_seg_min_addr;
+ // Only grow the section size if needed
+ if (new_seg_byte_size > curr_seg_byte_size)
+ segment->SetByteSize(new_seg_byte_size);
+ } else {
+ // We need to change the base address of the segment and
+ // adjust the child section offsets for all existing
+ // children.
+ const lldb::addr_t slide_amount =
+ sect64_min_addr - curr_seg_min_addr;
+ segment->Slide(slide_amount, false);
+ segment->GetChildren().Slide(-slide_amount, false);
+ segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);
}
- load_cmd.vmaddr = m_data.GetAddress(&offset);
- load_cmd.vmsize = m_data.GetAddress(&offset);
- load_cmd.fileoff = m_data.GetAddress(&offset);
- load_cmd.filesize = m_data.GetAddress(&offset);
- if (m_length != 0 && load_cmd.filesize != 0)
- {
- if (load_cmd.fileoff > m_length)
- {
- // We have a load command that says it extends past the end of the file. This is likely
- // a corrupt file. We don't have any way to return an error condition here (this method
- // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
- // is null out the SectionList vector and if a process has been set up, dump a message
- // to stdout. The most common case here is core file debugging with a truncated file.
- const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
- module_sp->ReportWarning("load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), ignoring this section",
- i,
- lc_segment_name,
- load_cmd.fileoff,
- m_length);
-
- load_cmd.fileoff = 0;
- load_cmd.filesize = 0;
- }
-
- if (load_cmd.fileoff + load_cmd.filesize > m_length)
- {
- // We have a load command that says it extends past the end of the file. This is likely
- // a corrupt file. We don't have any way to return an error condition here (this method
- // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
- // is null out the SectionList vector and if a process has been set up, dump a message
- // to stdout. The most common case here is core file debugging with a truncated file.
- const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
- GetModule()->ReportWarning("load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated to match",
- i,
- lc_segment_name,
- load_cmd.fileoff + load_cmd.filesize,
- m_length);
-
- // Tuncase the length
- load_cmd.filesize = m_length - load_cmd.fileoff;
- }
- }
- if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
- {
- const uint32_t segment_permissions =
- ((load_cmd.initprot & VM_PROT_READ) ? ePermissionsReadable : 0) |
- ((load_cmd.initprot & VM_PROT_WRITE) ? ePermissionsWritable : 0) |
- ((load_cmd.initprot & VM_PROT_EXECUTE) ? ePermissionsExecutable : 0);
-
- const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
-
- // Keep a list of mach segments around in case we need to
- // get at data that isn't stored in the abstracted Sections.
- m_mach_segments.push_back (load_cmd);
-
- // Use a segment ID of the segment index shifted left by 8 so they
- // never conflict with any of the sections.
- SectionSP segment_sp;
- if (add_section && (const_segname || is_core))
- {
- segment_sp.reset(new Section (module_sp, // Module to which this section belongs
- this, // Object file to which this sections belongs
- ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
- const_segname, // Name of this section
- eSectionTypeContainer, // This section is a container of other sections.
- load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
- load_cmd.vmsize, // VM size in bytes of this section
- load_cmd.fileoff, // Offset to the data for this section in the file
- load_cmd.filesize, // Size in bytes of this section as found in the file
- 0, // Segments have no alignment information
- load_cmd.flags)); // Flags for this section
-
- segment_sp->SetIsEncrypted (segment_is_encrypted);
- m_sections_ap->AddSection(segment_sp);
- segment_sp->SetPermissions(segment_permissions);
- if (add_to_unified)
- unified_section_list.AddSection(segment_sp);
- }
- else if (unified_section_sp)
- {
- if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
- {
- // Check to see if the module was read from memory?
- if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
- {
- // We have a module that is in memory and needs to have its
- // file address adjusted. We need to do this because when we
- // load a file from memory, its addresses will be slid already,
- // yet the addresses in the new symbol file will still be unslid.
- // Since everything is stored as section offset, this shouldn't
- // cause any problems.
-
- // Make sure we've parsed the symbol table from the
- // ObjectFile before we go around changing its Sections.
- module_sp->GetObjectFile()->GetSymtab();
- // eh_frame would present the same problems but we parse that on
- // a per-function basis as-needed so it's more difficult to
- // remove its use of the Sections. Realistically, the environments
- // where this code path will be taken will not have eh_frame sections.
-
- unified_section_sp->SetFileAddress(load_cmd.vmaddr);
-
- // Notify the module that the section addresses have been changed once
- // we're done so any file-address caches can be updated.
- section_file_addresses_changed = true;
- }
- }
- m_sections_ap->AddSection(unified_section_sp);
- }
-
- struct section_64 sect64;
- ::memset (&sect64, 0, sizeof(sect64));
- // Push a section into our mach sections for the section at
- // index zero (NO_SECT) if we don't have any mach sections yet...
- if (m_mach_sections.empty())
- m_mach_sections.push_back(sect64);
- uint32_t segment_sect_idx;
- const lldb::user_id_t first_segment_sectID = sectID + 1;
-
-
- const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
- for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
- {
- if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
- break;
- if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
- break;
- sect64.addr = m_data.GetAddress(&offset);
- sect64.size = m_data.GetAddress(&offset);
-
- if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
- break;
-
- // Keep a list of mach sections around in case we need to
- // get at data that isn't stored in the abstracted Sections.
- m_mach_sections.push_back (sect64);
-
- if (add_section)
- {
- ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
- if (!const_segname)
- {
- // We have a segment with no name so we need to conjure up
- // segments that correspond to the section's segname if there
- // isn't already such a section. If there is such a section,
- // we resize the section so that it spans all sections.
- // We also mark these sections as fake so address matches don't
- // hit if they land in the gaps between the child sections.
- const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
- segment_sp = unified_section_list.FindSectionByName (const_segname);
- if (segment_sp.get())
- {
- Section *segment = segment_sp.get();
- // Grow the section size as needed.
- const lldb::addr_t sect64_min_addr = sect64.addr;
- const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
- const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
- const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
- const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
- if (sect64_min_addr >= curr_seg_min_addr)
- {
- const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
- // Only grow the section size if needed
- if (new_seg_byte_size > curr_seg_byte_size)
- segment->SetByteSize (new_seg_byte_size);
- }
- else
- {
- // We need to change the base address of the segment and
- // adjust the child section offsets for all existing children.
- const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
- segment->Slide(slide_amount, false);
- segment->GetChildren().Slide(-slide_amount, false);
- segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
- }
-
- // Grow the section size as needed.
- if (sect64.offset)
- {
- const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
- const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
-
- const lldb::addr_t section_min_file_offset = sect64.offset;
- const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
- const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
- const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
- segment->SetFileOffset (new_file_offset);
- segment->SetFileSize (new_file_size);
- }
- }
- else
- {
- // Create a fake section for the section's named segment
- segment_sp.reset(new Section (segment_sp, // Parent section
- module_sp, // Module to which this section belongs
- this, // Object file to which this section belongs
- ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
- const_segname, // Name of this section
- eSectionTypeContainer, // This section is a container of other sections.
- sect64.addr, // File VM address == addresses as they are found in the object file
- sect64.size, // VM size in bytes of this section
- sect64.offset, // Offset to the data for this section in the file
- sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the file
- sect64.align,
- load_cmd.flags)); // Flags for this section
- segment_sp->SetIsFake(true);
- segment_sp->SetPermissions(segment_permissions);
- m_sections_ap->AddSection(segment_sp);
- if (add_to_unified)
- unified_section_list.AddSection(segment_sp);
- segment_sp->SetIsEncrypted (segment_is_encrypted);
- }
- }
- assert (segment_sp.get());
-
- lldb::SectionType sect_type = eSectionTypeOther;
-
- if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
- sect_type = eSectionTypeCode;
- else
- {
- uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
- static ConstString g_sect_name_objc_data ("__objc_data");
- static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
- static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
- static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
- static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
- static ConstString g_sect_name_objc_const ("__objc_const");
- static ConstString g_sect_name_objc_classlist ("__objc_classlist");
- static ConstString g_sect_name_cfstring ("__cfstring");
-
- static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
- static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
- static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
- static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
- static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
- static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
- static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
- static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
- static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
- static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
- static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
- static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
- static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
- static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
- static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
- static ConstString g_sect_name_eh_frame ("__eh_frame");
- static ConstString g_sect_name_compact_unwind ("__unwind_info");
- static ConstString g_sect_name_text ("__text");
- static ConstString g_sect_name_data ("__data");
- static ConstString g_sect_name_go_symtab ("__gosymtab");
-
- if (section_name == g_sect_name_dwarf_debug_abbrev)
- sect_type = eSectionTypeDWARFDebugAbbrev;
- else if (section_name == g_sect_name_dwarf_debug_aranges)
- sect_type = eSectionTypeDWARFDebugAranges;
- else if (section_name == g_sect_name_dwarf_debug_frame)
- sect_type = eSectionTypeDWARFDebugFrame;
- else if (section_name == g_sect_name_dwarf_debug_info)
- sect_type = eSectionTypeDWARFDebugInfo;
- else if (section_name == g_sect_name_dwarf_debug_line)
- sect_type = eSectionTypeDWARFDebugLine;
- else if (section_name == g_sect_name_dwarf_debug_loc)
- sect_type = eSectionTypeDWARFDebugLoc;
- else if (section_name == g_sect_name_dwarf_debug_macinfo)
- sect_type = eSectionTypeDWARFDebugMacInfo;
- else if (section_name == g_sect_name_dwarf_debug_pubnames)
- sect_type = eSectionTypeDWARFDebugPubNames;
- else if (section_name == g_sect_name_dwarf_debug_pubtypes)
- sect_type = eSectionTypeDWARFDebugPubTypes;
- else if (section_name == g_sect_name_dwarf_debug_ranges)
- sect_type = eSectionTypeDWARFDebugRanges;
- else if (section_name == g_sect_name_dwarf_debug_str)
- sect_type = eSectionTypeDWARFDebugStr;
- else if (section_name == g_sect_name_dwarf_apple_names)
- sect_type = eSectionTypeDWARFAppleNames;
- else if (section_name == g_sect_name_dwarf_apple_types)
- sect_type = eSectionTypeDWARFAppleTypes;
- else if (section_name == g_sect_name_dwarf_apple_namespaces)
- sect_type = eSectionTypeDWARFAppleNamespaces;
- else if (section_name == g_sect_name_dwarf_apple_objc)
- sect_type = eSectionTypeDWARFAppleObjC;
- else if (section_name == g_sect_name_objc_selrefs)
- sect_type = eSectionTypeDataCStringPointers;
- else if (section_name == g_sect_name_objc_msgrefs)
- sect_type = eSectionTypeDataObjCMessageRefs;
- else if (section_name == g_sect_name_eh_frame)
- sect_type = eSectionTypeEHFrame;
- else if (section_name == g_sect_name_compact_unwind)
- sect_type = eSectionTypeCompactUnwind;
- else if (section_name == g_sect_name_cfstring)
- sect_type = eSectionTypeDataObjCCFStrings;
- else if (section_name == g_sect_name_go_symtab)
- sect_type = eSectionTypeGoSymtab;
- else if (section_name == g_sect_name_objc_data ||
- section_name == g_sect_name_objc_classrefs ||
- section_name == g_sect_name_objc_superrefs ||
- section_name == g_sect_name_objc_const ||
- section_name == g_sect_name_objc_classlist)
- {
- sect_type = eSectionTypeDataPointers;
- }
-
- if (sect_type == eSectionTypeOther)
- {
- switch (mach_sect_type)
- {
- // TODO: categorize sections by other flags for regular sections
- case S_REGULAR:
- if (section_name == g_sect_name_text)
- sect_type = eSectionTypeCode;
- else if (section_name == g_sect_name_data)
- sect_type = eSectionTypeData;
- else
- sect_type = eSectionTypeOther;
- break;
- case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
- case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
- case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
- case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
- case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
- case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
- case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
- case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
- case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
- case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
- case S_COALESCED: sect_type = eSectionTypeOther; break;
- case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
- case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
- case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
- case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break;
- case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break;
- default: break;
- }
- }
- }
- SectionSP section_sp(new Section (segment_sp,
- module_sp,
- this,
- ++sectID,
- section_name,
- sect_type,
- sect64.addr - segment_sp->GetFileAddress(),
- sect64.size,
- sect64.offset,
- sect64.offset == 0 ? 0 : sect64.size,
- sect64.align,
- sect64.flags));
- // Set the section to be encrypted to match the segment
-
- bool section_is_encrypted = false;
- if (!segment_is_encrypted && load_cmd.filesize != 0)
- section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
-
- section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
- section_sp->SetPermissions(segment_permissions);
- segment_sp->GetChildren().AddSection(section_sp);
-
- if (segment_sp->IsFake())
- {
- segment_sp.reset();
- const_segname.Clear();
- }
- }
- }
- if (segment_sp && is_dsym)
- {
- if (first_segment_sectID <= sectID)
- {
- lldb::user_id_t sect_uid;
- for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
- {
- SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
- SectionSP next_section_sp;
- if (sect_uid + 1 <= sectID)
- next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
-
- if (curr_section_sp.get())
- {
- if (curr_section_sp->GetByteSize() == 0)
- {
- if (next_section_sp.get() != NULL)
- curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
- else
- curr_section_sp->SetByteSize ( load_cmd.vmsize );
- }
- }
- }
- }
- }
+ // Grow the section size as needed.
+ if (sect64.offset) {
+ const lldb::addr_t segment_min_file_offset =
+ segment->GetFileOffset();
+ const lldb::addr_t segment_max_file_offset =
+ segment_min_file_offset + segment->GetFileSize();
+
+ const lldb::addr_t section_min_file_offset =
+ sect64.offset;
+ const lldb::addr_t section_max_file_offset =
+ section_min_file_offset + sect64.size;
+ const lldb::addr_t new_file_offset = std::min(
+ section_min_file_offset, segment_min_file_offset);
+ const lldb::addr_t new_file_size =
+ std::max(section_max_file_offset,
+ segment_max_file_offset) -
+ new_file_offset;
+ segment->SetFileOffset(new_file_offset);
+ segment->SetFileSize(new_file_size);
+ }
+ } else {
+ // Create a fake section for the section's named segment
+ segment_sp.reset(new Section(
+ segment_sp, // Parent section
+ module_sp, // Module to which this section belongs
+ this, // Object file to which this section belongs
+ ++segID << 8, // Section ID is the 1 based segment index
+ // shifted right by 8 bits as not to
+ // collide with any of the 256 section IDs
+ // that are possible
+ const_segname, // Name of this section
+ eSectionTypeContainer, // This section is a container of
+ // other sections.
+ sect64.addr, // File VM address == addresses as they are
+ // found in the object file
+ sect64.size, // VM size in bytes of this section
+ sect64.offset, // Offset to the data for this section in
+ // the file
+ sect64.offset ? sect64.size : 0, // Size in bytes of
+ // this section as
+ // found in the file
+ sect64.align,
+ load_cmd.flags)); // Flags for this section
+ segment_sp->SetIsFake(true);
+ segment_sp->SetPermissions(segment_permissions);
+ m_sections_ap->AddSection(segment_sp);
+ if (add_to_unified)
+ unified_section_list.AddSection(segment_sp);
+ segment_sp->SetIsEncrypted(segment_is_encrypted);
+ }
+ }
+ assert(segment_sp.get());
+
+ lldb::SectionType sect_type = eSectionTypeOther;
+
+ if (sect64.flags &
+ (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
+ sect_type = eSectionTypeCode;
+ else {
+ uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
+ static ConstString g_sect_name_objc_data("__objc_data");
+ static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");
+ static ConstString g_sect_name_objc_selrefs("__objc_selrefs");
+ static ConstString g_sect_name_objc_classrefs(
+ "__objc_classrefs");
+ static ConstString g_sect_name_objc_superrefs(
+ "__objc_superrefs");
+ static ConstString g_sect_name_objc_const("__objc_const");
+ static ConstString g_sect_name_objc_classlist(
+ "__objc_classlist");
+ static ConstString g_sect_name_cfstring("__cfstring");
+
+ static ConstString g_sect_name_dwarf_debug_abbrev(
+ "__debug_abbrev");
+ static ConstString g_sect_name_dwarf_debug_aranges(
+ "__debug_aranges");
+ static ConstString g_sect_name_dwarf_debug_frame(
+ "__debug_frame");
+ static ConstString g_sect_name_dwarf_debug_info(
+ "__debug_info");
+ static ConstString g_sect_name_dwarf_debug_line(
+ "__debug_line");
+ static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
+ static ConstString g_sect_name_dwarf_debug_macinfo(
+ "__debug_macinfo");
+ static ConstString g_sect_name_dwarf_debug_pubnames(
+ "__debug_pubnames");
+ static ConstString g_sect_name_dwarf_debug_pubtypes(
+ "__debug_pubtypes");
+ static ConstString g_sect_name_dwarf_debug_ranges(
+ "__debug_ranges");
+ static ConstString g_sect_name_dwarf_debug_str("__debug_str");
+ static ConstString g_sect_name_dwarf_apple_names(
+ "__apple_names");
+ static ConstString g_sect_name_dwarf_apple_types(
+ "__apple_types");
+ static ConstString g_sect_name_dwarf_apple_namespaces(
+ "__apple_namespac");
+ static ConstString g_sect_name_dwarf_apple_objc(
+ "__apple_objc");
+ static ConstString g_sect_name_eh_frame("__eh_frame");
+ static ConstString g_sect_name_compact_unwind(
+ "__unwind_info");
+ static ConstString g_sect_name_text("__text");
+ static ConstString g_sect_name_data("__data");
+ static ConstString g_sect_name_go_symtab("__gosymtab");
+
+ if (section_name == g_sect_name_dwarf_debug_abbrev)
+ sect_type = eSectionTypeDWARFDebugAbbrev;
+ else if (section_name == g_sect_name_dwarf_debug_aranges)
+ sect_type = eSectionTypeDWARFDebugAranges;
+ else if (section_name == g_sect_name_dwarf_debug_frame)
+ sect_type = eSectionTypeDWARFDebugFrame;
+ else if (section_name == g_sect_name_dwarf_debug_info)
+ sect_type = eSectionTypeDWARFDebugInfo;
+ else if (section_name == g_sect_name_dwarf_debug_line)
+ sect_type = eSectionTypeDWARFDebugLine;
+ else if (section_name == g_sect_name_dwarf_debug_loc)
+ sect_type = eSectionTypeDWARFDebugLoc;
+ else if (section_name == g_sect_name_dwarf_debug_macinfo)
+ sect_type = eSectionTypeDWARFDebugMacInfo;
+ else if (section_name == g_sect_name_dwarf_debug_pubnames)
+ sect_type = eSectionTypeDWARFDebugPubNames;
+ else if (section_name == g_sect_name_dwarf_debug_pubtypes)
+ sect_type = eSectionTypeDWARFDebugPubTypes;
+ else if (section_name == g_sect_name_dwarf_debug_ranges)
+ sect_type = eSectionTypeDWARFDebugRanges;
+ else if (section_name == g_sect_name_dwarf_debug_str)
+ sect_type = eSectionTypeDWARFDebugStr;
+ else if (section_name == g_sect_name_dwarf_apple_names)
+ sect_type = eSectionTypeDWARFAppleNames;
+ else if (section_name == g_sect_name_dwarf_apple_types)
+ sect_type = eSectionTypeDWARFAppleTypes;
+ else if (section_name == g_sect_name_dwarf_apple_namespaces)
+ sect_type = eSectionTypeDWARFAppleNamespaces;
+ else if (section_name == g_sect_name_dwarf_apple_objc)
+ sect_type = eSectionTypeDWARFAppleObjC;
+ else if (section_name == g_sect_name_objc_selrefs)
+ sect_type = eSectionTypeDataCStringPointers;
+ else if (section_name == g_sect_name_objc_msgrefs)
+ sect_type = eSectionTypeDataObjCMessageRefs;
+ else if (section_name == g_sect_name_eh_frame)
+ sect_type = eSectionTypeEHFrame;
+ else if (section_name == g_sect_name_compact_unwind)
+ sect_type = eSectionTypeCompactUnwind;
+ else if (section_name == g_sect_name_cfstring)
+ sect_type = eSectionTypeDataObjCCFStrings;
+ else if (section_name == g_sect_name_go_symtab)
+ sect_type = eSectionTypeGoSymtab;
+ else if (section_name == g_sect_name_objc_data ||
+ section_name == g_sect_name_objc_classrefs ||
+ section_name == g_sect_name_objc_superrefs ||
+ section_name == g_sect_name_objc_const ||
+ section_name == g_sect_name_objc_classlist) {
+ sect_type = eSectionTypeDataPointers;
+ }
+
+ if (sect_type == eSectionTypeOther) {
+ switch (mach_sect_type) {
+ // TODO: categorize sections by other flags for regular
+ // sections
+ case S_REGULAR:
+ if (section_name == g_sect_name_text)
+ sect_type = eSectionTypeCode;
+ else if (section_name == g_sect_name_data)
+ sect_type = eSectionTypeData;
+ else
+ sect_type = eSectionTypeOther;
+ break;
+ case S_ZEROFILL:
+ sect_type = eSectionTypeZeroFill;
+ break;
+ case S_CSTRING_LITERALS:
+ sect_type = eSectionTypeDataCString;
+ break; // section with only literal C strings
+ case S_4BYTE_LITERALS:
+ sect_type = eSectionTypeData4;
+ break; // section with only 4 byte literals
+ case S_8BYTE_LITERALS:
+ sect_type = eSectionTypeData8;
+ break; // section with only 8 byte literals
+ case S_LITERAL_POINTERS:
+ sect_type = eSectionTypeDataPointers;
+ break; // section with only pointers to literals
+ case S_NON_LAZY_SYMBOL_POINTERS:
+ sect_type = eSectionTypeDataPointers;
+ break; // section with only non-lazy symbol pointers
+ case S_LAZY_SYMBOL_POINTERS:
+ sect_type = eSectionTypeDataPointers;
+ break; // section with only lazy symbol pointers
+ case S_SYMBOL_STUBS:
+ sect_type = eSectionTypeCode;
+ break; // section with only symbol stubs, byte size of
+ // stub in the reserved2 field
+ case S_MOD_INIT_FUNC_POINTERS:
+ sect_type = eSectionTypeDataPointers;
+ break; // section with only function pointers for
+ // initialization
+ case S_MOD_TERM_FUNC_POINTERS:
+ sect_type = eSectionTypeDataPointers;
+ break; // section with only function pointers for
+ // termination
+ case S_COALESCED:
+ sect_type = eSectionTypeOther;
+ break;
+ case S_GB_ZEROFILL:
+ sect_type = eSectionTypeZeroFill;
+ break;
+ case S_INTERPOSING:
+ sect_type = eSectionTypeCode;
+ break; // section with only pairs of function pointers for
+ // interposing
+ case S_16BYTE_LITERALS:
+ sect_type = eSectionTypeData16;
+ break; // section with only 16 byte literals
+ case S_DTRACE_DOF:
+ sect_type = eSectionTypeDebug;
+ break;
+ case S_LAZY_DYLIB_SYMBOL_POINTERS:
+ sect_type = eSectionTypeDataPointers;
+ break;
+ default:
+ break;
}
+ }
}
+
+ SectionSP section_sp(new Section(
+ segment_sp, module_sp, this, ++sectID, section_name,
+ sect_type, sect64.addr - segment_sp->GetFileAddress(),
+ sect64.size, sect64.offset,
+ sect64.offset == 0 ? 0 : sect64.size, sect64.align,
+ sect64.flags));
+ // Set the section to be encrypted to match the segment
+
+ bool section_is_encrypted = false;
+ if (!segment_is_encrypted && load_cmd.filesize != 0)
+ section_is_encrypted =
+ encrypted_file_ranges.FindEntryThatContains(
+ sect64.offset) != NULL;
+
+ section_sp->SetIsEncrypted(segment_is_encrypted ||
+ section_is_encrypted);
+ section_sp->SetPermissions(segment_permissions);
+ segment_sp->GetChildren().AddSection(section_sp);
+
+ if (segment_sp->IsFake()) {
+ segment_sp.reset();
+ const_segname.Clear();
+ }
+ }
}
- else if (load_cmd.cmd == LC_DYSYMTAB)
- {
- m_dysymtab.cmd = load_cmd.cmd;
- m_dysymtab.cmdsize = load_cmd.cmdsize;
- m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
+ if (segment_sp && is_dsym) {
+ if (first_segment_sectID <= sectID) {
+ lldb::user_id_t sect_uid;
+ for (sect_uid = first_segment_sectID; sect_uid <= sectID;
+ ++sect_uid) {
+ SectionSP curr_section_sp(
+ segment_sp->GetChildren().FindSectionByID(sect_uid));
+ SectionSP next_section_sp;
+ if (sect_uid + 1 <= sectID)
+ next_section_sp =
+ segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
+
+ if (curr_section_sp.get()) {
+ if (curr_section_sp->GetByteSize() == 0) {
+ if (next_section_sp.get() != NULL)
+ curr_section_sp->SetByteSize(
+ next_section_sp->GetFileAddress() -
+ curr_section_sp->GetFileAddress());
+ else
+ curr_section_sp->SetByteSize(load_cmd.vmsize);
+ }
+ }
+ }
+ }
}
-
- offset = load_cmd_offset + load_cmd.cmdsize;
+ }
}
+ } else if (load_cmd.cmd == LC_DYSYMTAB) {
+ m_dysymtab.cmd = load_cmd.cmd;
+ m_dysymtab.cmdsize = load_cmd.cmdsize;
+ m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
+ (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
+ }
+
+ offset = load_cmd_offset + load_cmd.cmdsize;
+ }
-
- if (section_file_addresses_changed && module_sp.get())
- {
- module_sp->SectionFileAddressesChanged();
- }
+ if (section_file_addresses_changed && module_sp.get()) {
+ module_sp->SectionFileAddressesChanged();
}
+ }
}
-class MachSymtabSectionInfo
-{
+class MachSymtabSectionInfo {
public:
- MachSymtabSectionInfo (SectionList *section_list) :
- m_section_list (section_list),
- m_section_infos()
- {
- // Get the number of sections down to a depth of 1 to include
- // all segments and their sections, but no other sections that
- // may be added for debug map or
- m_section_infos.resize(section_list->GetNumSections(1));
- }
-
- SectionSP
- GetSection (uint8_t n_sect, addr_t file_addr)
- {
- if (n_sect == 0)
- return SectionSP();
- if (n_sect < m_section_infos.size())
- {
- if (!m_section_infos[n_sect].section_sp)
- {
- SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
- m_section_infos[n_sect].section_sp = section_sp;
- if (section_sp)
- {
- m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
- m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
- }
- else
- {
- Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
- }
- }
- if (m_section_infos[n_sect].vm_range.Contains(file_addr))
- {
- // Symbol is in section.
- return m_section_infos[n_sect].section_sp;
- }
- else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
- m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
- {
- // Symbol is in section with zero size, but has the same start
- // address as the section. This can happen with linker symbols
- // (symbols that start with the letter 'l' or 'L'.
- return m_section_infos[n_sect].section_sp;
- }
+ MachSymtabSectionInfo(SectionList *section_list)
+ : m_section_list(section_list), m_section_infos() {
+ // Get the number of sections down to a depth of 1 to include
+ // all segments and their sections, but no other sections that
+ // may be added for debug map or
+ m_section_infos.resize(section_list->GetNumSections(1));
+ }
+
+ SectionSP GetSection(uint8_t n_sect, addr_t file_addr) {
+ if (n_sect == 0)
+ return SectionSP();
+ if (n_sect < m_section_infos.size()) {
+ if (!m_section_infos[n_sect].section_sp) {
+ SectionSP section_sp(m_section_list->FindSectionByID(n_sect));
+ m_section_infos[n_sect].section_sp = section_sp;
+ if (section_sp) {
+ m_section_infos[n_sect].vm_range.SetBaseAddress(
+ section_sp->GetFileAddress());
+ m_section_infos[n_sect].vm_range.SetByteSize(
+ section_sp->GetByteSize());
+ } else {
+ Host::SystemLog(Host::eSystemLogError,
+ "error: unable to find section for section %u\n",
+ n_sect);
}
- return m_section_list->FindSectionContainingFileAddress(file_addr);
+ }
+ if (m_section_infos[n_sect].vm_range.Contains(file_addr)) {
+ // Symbol is in section.
+ return m_section_infos[n_sect].section_sp;
+ } else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 &&
+ m_section_infos[n_sect].vm_range.GetBaseAddress() ==
+ file_addr) {
+ // Symbol is in section with zero size, but has the same start
+ // address as the section. This can happen with linker symbols
+ // (symbols that start with the letter 'l' or 'L'.
+ return m_section_infos[n_sect].section_sp;
+ }
}
+ return m_section_list->FindSectionContainingFileAddress(file_addr);
+ }
protected:
- struct SectionInfo
- {
- SectionInfo () :
- vm_range(),
- section_sp ()
- {
- }
-
- VMRange vm_range;
- SectionSP section_sp;
- };
- SectionList *m_section_list;
- std::vector<SectionInfo> m_section_infos;
+ struct SectionInfo {
+ SectionInfo() : vm_range(), section_sp() {}
+
+ VMRange vm_range;
+ SectionSP section_sp;
+ };
+ SectionList *m_section_list;
+ std::vector<SectionInfo> m_section_infos;
};
-struct TrieEntry
-{
- TrieEntry () :
- name(),
- address(LLDB_INVALID_ADDRESS),
- flags (0),
- other(0),
- import_name()
- {
- }
-
- void
- Clear ()
- {
- name.Clear();
- address = LLDB_INVALID_ADDRESS;
- flags = 0;
- other = 0;
- import_name.Clear();
- }
-
- void
- Dump () const
- {
- printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
- static_cast<unsigned long long>(address),
- static_cast<unsigned long long>(flags),
- static_cast<unsigned long long>(other), name.GetCString());
- if (import_name)
- printf (" -> \"%s\"\n", import_name.GetCString());
- else
- printf ("\n");
- }
- ConstString name;
- uint64_t address;
- uint64_t flags;
- uint64_t other;
- ConstString import_name;
+struct TrieEntry {
+ TrieEntry()
+ : name(), address(LLDB_INVALID_ADDRESS), flags(0), other(0),
+ import_name() {}
+
+ void Clear() {
+ name.Clear();
+ address = LLDB_INVALID_ADDRESS;
+ flags = 0;
+ other = 0;
+ import_name.Clear();
+ }
+
+ void Dump() const {
+ printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
+ static_cast<unsigned long long>(address),
+ static_cast<unsigned long long>(flags),
+ static_cast<unsigned long long>(other), name.GetCString());
+ if (import_name)
+ printf(" -> \"%s\"\n", import_name.GetCString());
+ else
+ printf("\n");
+ }
+ ConstString name;
+ uint64_t address;
+ uint64_t flags;
+ uint64_t other;
+ ConstString import_name;
};
-struct TrieEntryWithOffset
-{
- lldb::offset_t nodeOffset;
- TrieEntry entry;
+struct TrieEntryWithOffset {
+ lldb::offset_t nodeOffset;
+ TrieEntry entry;
- TrieEntryWithOffset (lldb::offset_t offset) :
- nodeOffset (offset),
- entry()
- {
- }
+ TrieEntryWithOffset(lldb::offset_t offset) : nodeOffset(offset), entry() {}
- void
- Dump (uint32_t idx) const
- {
- printf ("[%3u] 0x%16.16llx: ", idx,
- static_cast<unsigned long long>(nodeOffset));
- entry.Dump();
- }
+ void Dump(uint32_t idx) const {
+ printf("[%3u] 0x%16.16llx: ", idx,
+ static_cast<unsigned long long>(nodeOffset));
+ entry.Dump();
+ }
- bool
- operator<(const TrieEntryWithOffset& other) const
- {
- return ( nodeOffset < other.nodeOffset );
- }
+ bool operator<(const TrieEntryWithOffset &other) const {
+ return (nodeOffset < other.nodeOffset);
+ }
};
-static bool
-ParseTrieEntries (DataExtractor &data,
- lldb::offset_t offset,
- const bool is_arm,
- std::vector<llvm::StringRef> &nameSlices,
- std::set<lldb::addr_t> &resolver_addresses,
- std::vector<TrieEntryWithOffset>& output)
-{
- if (!data.ValidOffset(offset))
- return true;
-
- const uint64_t terminalSize = data.GetULEB128(&offset);
- lldb::offset_t children_offset = offset + terminalSize;
- if ( terminalSize != 0 ) {
- TrieEntryWithOffset e (offset);
- e.entry.flags = data.GetULEB128(&offset);
- const char *import_name = NULL;
- if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
- e.entry.address = 0;
- e.entry.other = data.GetULEB128(&offset); // dylib ordinal
- import_name = data.GetCStr(&offset);
- }
- else {
- e.entry.address = data.GetULEB128(&offset);
- if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
- {
- e.entry.other = data.GetULEB128(&offset);
- uint64_t resolver_addr = e.entry.other;
- if (is_arm)
- resolver_addr &= THUMB_ADDRESS_BIT_MASK;
- resolver_addresses.insert(resolver_addr);
- }
- else
- e.entry.other = 0;
- }
- // Only add symbols that are reexport symbols with a valid import name
- if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
- {
- std::string name;
- if (!nameSlices.empty())
- {
- for (auto name_slice: nameSlices)
- name.append(name_slice.data(), name_slice.size());
- }
- if (name.size() > 1)
- {
- // Skip the leading '_'
- e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
- }
- if (import_name)
- {
- // Skip the leading '_'
- e.entry.import_name.SetCString(import_name+1);
- }
- output.push_back(e);
- }
- }
-
- const uint8_t childrenCount = data.GetU8(&children_offset);
- for (uint8_t i=0; i < childrenCount; ++i) {
- const char *cstr = data.GetCStr(&children_offset);
- if (cstr)
- nameSlices.push_back(llvm::StringRef(cstr));
- else
- return false; // Corrupt data
- lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
- if (childNodeOffset)
- {
- if (!ParseTrieEntries(data,
- childNodeOffset,
- is_arm,
- nameSlices,
- resolver_addresses,
- output))
- {
- return false;
- }
- }
- nameSlices.pop_back();
- }
+static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset,
+ const bool is_arm,
+ std::vector<llvm::StringRef> &nameSlices,
+ std::set<lldb::addr_t> &resolver_addresses,
+ std::vector<TrieEntryWithOffset> &output) {
+ if (!data.ValidOffset(offset))
return true;
+
+ const uint64_t terminalSize = data.GetULEB128(&offset);
+ lldb::offset_t children_offset = offset + terminalSize;
+ if (terminalSize != 0) {
+ TrieEntryWithOffset e(offset);
+ e.entry.flags = data.GetULEB128(&offset);
+ const char *import_name = NULL;
+ if (e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
+ e.entry.address = 0;
+ e.entry.other = data.GetULEB128(&offset); // dylib ordinal
+ import_name = data.GetCStr(&offset);
+ } else {
+ e.entry.address = data.GetULEB128(&offset);
+ if (e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
+ e.entry.other = data.GetULEB128(&offset);
+ uint64_t resolver_addr = e.entry.other;
+ if (is_arm)
+ resolver_addr &= THUMB_ADDRESS_BIT_MASK;
+ resolver_addresses.insert(resolver_addr);
+ } else
+ e.entry.other = 0;
+ }
+ // Only add symbols that are reexport symbols with a valid import name
+ if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name &&
+ import_name[0]) {
+ std::string name;
+ if (!nameSlices.empty()) {
+ for (auto name_slice : nameSlices)
+ name.append(name_slice.data(), name_slice.size());
+ }
+ if (name.size() > 1) {
+ // Skip the leading '_'
+ e.entry.name.SetCStringWithLength(name.c_str() + 1, name.size() - 1);
+ }
+ if (import_name) {
+ // Skip the leading '_'
+ e.entry.import_name.SetCString(import_name + 1);
+ }
+ output.push_back(e);
+ }
+ }
+
+ const uint8_t childrenCount = data.GetU8(&children_offset);
+ for (uint8_t i = 0; i < childrenCount; ++i) {
+ const char *cstr = data.GetCStr(&children_offset);
+ if (cstr)
+ nameSlices.push_back(llvm::StringRef(cstr));
+ else
+ return false; // Corrupt data
+ lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
+ if (childNodeOffset) {
+ if (!ParseTrieEntries(data, childNodeOffset, is_arm, nameSlices,
+ resolver_addresses, output)) {
+ return false;
+ }
+ }
+ nameSlices.pop_back();
+ }
+ return true;
}
// Read the UUID out of a dyld_shared_cache file on-disk.
-UUID
-ObjectFileMachO::GetSharedCacheUUID (FileSpec dyld_shared_cache, const ByteOrder byte_order, const uint32_t addr_byte_size)
-{
- UUID dsc_uuid;
- DataBufferSP dsc_data_sp = dyld_shared_cache.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
- if (dsc_data_sp)
- {
- DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size);
-
- char version_str[7];
- lldb::offset_t offset = 0;
- memcpy (version_str, dsc_header_data.GetData (&offset, 6), 6);
- version_str[6] = '\0';
- if (strcmp (version_str, "dyld_v") == 0)
- {
- offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
- uint8_t uuid_bytes[sizeof (uuid_t)];
- memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
- dsc_uuid.SetBytes (uuid_bytes);
- }
+UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache,
+ const ByteOrder byte_order,
+ const uint32_t addr_byte_size) {
+ UUID dsc_uuid;
+ DataBufferSP dsc_data_sp = dyld_shared_cache.MemoryMapFileContentsIfLocal(
+ 0, sizeof(struct lldb_copy_dyld_cache_header_v1));
+ if (dsc_data_sp) {
+ DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
+
+ char version_str[7];
+ lldb::offset_t offset = 0;
+ memcpy(version_str, dsc_header_data.GetData(&offset, 6), 6);
+ version_str[6] = '\0';
+ if (strcmp(version_str, "dyld_v") == 0) {
+ offset = offsetof(struct lldb_copy_dyld_cache_header_v1, uuid);
+ uint8_t uuid_bytes[sizeof(uuid_t)];
+ memcpy(uuid_bytes, dsc_header_data.GetData(&offset, sizeof(uuid_t)),
+ sizeof(uuid_t));
+ dsc_uuid.SetBytes(uuid_bytes);
}
- return dsc_uuid;
+ }
+ return dsc_uuid;
}
-size_t
-ObjectFileMachO::ParseSymtab ()
-{
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "ObjectFileMachO::ParseSymtab () module = %s",
- m_file.GetFilename().AsCString(""));
- ModuleSP module_sp (GetModule());
- if (!module_sp)
- return 0;
-
- struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
- struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
- struct dyld_info_command dyld_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
- FunctionStarts function_starts;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t i;
- FileSpecList dylib_files;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
- static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
-
- for (i=0; i<m_header.ncmds; ++i)
- {
- const lldb::offset_t cmd_offset = offset;
- // Read in the load command and load command size
- struct load_command lc;
- if (m_data.GetU32(&offset, &lc, 2) == NULL)
- break;
- // Watch for the symbol table load command
- switch (lc.cmd)
- {
- case LC_SYMTAB:
- symtab_load_command.cmd = lc.cmd;
- symtab_load_command.cmdsize = lc.cmdsize;
- // Read in the rest of the symtab load command
- if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
- return 0;
- if (symtab_load_command.symoff == 0)
- {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
- return 0;
- }
-
- if (symtab_load_command.stroff == 0)
- {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
- return 0;
- }
-
- if (symtab_load_command.nsyms == 0)
- {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
- return 0;
- }
-
- if (symtab_load_command.strsize == 0)
- {
- if (log)
- module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
- return 0;
- }
- break;
-
- case LC_DYLD_INFO:
- case LC_DYLD_INFO_ONLY:
- if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
- {
- dyld_info.cmd = lc.cmd;
- dyld_info.cmdsize = lc.cmdsize;
- }
- else
- {
- memset (&dyld_info, 0, sizeof(dyld_info));
- }
- break;
+size_t ObjectFileMachO::ParseSymtab() {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "ObjectFileMachO::ParseSymtab () module = %s",
+ m_file.GetFilename().AsCString(""));
+ ModuleSP module_sp(GetModule());
+ if (!module_sp)
+ return 0;
- case LC_LOAD_DYLIB:
- case LC_LOAD_WEAK_DYLIB:
- case LC_REEXPORT_DYLIB:
- case LC_LOADFVMLIB:
- case LC_LOAD_UPWARD_DYLIB:
- {
- 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);
- // Strip the path if there is @rpath, @executable, etc so we just use the basename
- if (path[0] == '@')
- file_spec.GetDirectory().Clear();
-
- if (lc.cmd == LC_REEXPORT_DYLIB)
- {
- m_reexported_dylibs.AppendIfUnique(file_spec);
- }
+ struct symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
+ struct linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
+ struct dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
+ FunctionStarts function_starts;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ uint32_t i;
+ FileSpecList dylib_files;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+ static const llvm::StringRef g_objc_v2_prefix_class("_OBJC_CLASS_$_");
+ static const llvm::StringRef g_objc_v2_prefix_metaclass("_OBJC_METACLASS_$_");
+ static const llvm::StringRef g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
+
+ for (i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t cmd_offset = offset;
+ // Read in the load command and load command size
+ struct load_command lc;
+ if (m_data.GetU32(&offset, &lc, 2) == NULL)
+ break;
+ // Watch for the symbol table load command
+ switch (lc.cmd) {
+ case LC_SYMTAB:
+ symtab_load_command.cmd = lc.cmd;
+ symtab_load_command.cmdsize = lc.cmdsize;
+ // Read in the rest of the symtab load command
+ if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) ==
+ 0) // fill in symoff, nsyms, stroff, strsize fields
+ return 0;
+ if (symtab_load_command.symoff == 0) {
+ if (log)
+ module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
+ return 0;
+ }
- dylib_files.Append(file_spec);
- }
- }
- break;
+ if (symtab_load_command.stroff == 0) {
+ if (log)
+ module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
+ return 0;
+ }
- case LC_FUNCTION_STARTS:
- function_starts_load_command.cmd = lc.cmd;
- function_starts_load_command.cmdsize = lc.cmdsize;
- if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
- memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
- break;
+ if (symtab_load_command.nsyms == 0) {
+ if (log)
+ module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
+ return 0;
+ }
- default:
- break;
+ if (symtab_load_command.strsize == 0) {
+ if (log)
+ module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
+ return 0;
+ }
+ break;
+
+ case LC_DYLD_INFO:
+ case LC_DYLD_INFO_ONLY:
+ if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) {
+ dyld_info.cmd = lc.cmd;
+ dyld_info.cmdsize = lc.cmdsize;
+ } else {
+ memset(&dyld_info, 0, sizeof(dyld_info));
+ }
+ break;
+
+ case LC_LOAD_DYLIB:
+ case LC_LOAD_WEAK_DYLIB:
+ case LC_REEXPORT_DYLIB:
+ case LC_LOADFVMLIB:
+ case LC_LOAD_UPWARD_DYLIB: {
+ 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);
+ // Strip the path if there is @rpath, @executable, etc so we just use
+ // the basename
+ if (path[0] == '@')
+ file_spec.GetDirectory().Clear();
+
+ if (lc.cmd == LC_REEXPORT_DYLIB) {
+ m_reexported_dylibs.AppendIfUnique(file_spec);
}
- offset = cmd_offset + lc.cmdsize;
- }
-
- if (symtab_load_command.cmd)
- {
- Symtab *symtab = m_symtab_ap.get();
- SectionList *section_list = GetSectionList();
- if (section_list == NULL)
- return 0;
-
- const uint32_t addr_byte_size = m_data.GetAddressByteSize();
- const ByteOrder byte_order = m_data.GetByteOrder();
- bool bit_width_32 = addr_byte_size == 4;
- const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
-
- DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
- DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
- DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
- DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
- DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
-
- const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
- const addr_t strtab_data_byte_size = symtab_load_command.strsize;
- addr_t strtab_addr = LLDB_INVALID_ADDRESS;
-
- ProcessSP process_sp (m_process_wp.lock());
- Process *process = process_sp.get();
-
- uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
-
- if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
- {
- Target &target = process->GetTarget();
-
- memory_module_load_level = target.GetMemoryModuleLoadLevel();
-
- SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
- // Reading mach file from memory in a process or core file...
-
- if (linkedit_section_sp)
- {
- addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
- if (linkedit_load_addr == LLDB_INVALID_ADDRESS)
- {
- // We might be trying to access the symbol table before the __LINKEDIT's load
- // address has been set in the target. We can't fail to read the symbol table,
- // so calculate the right address manually
- linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
- }
-
- const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
- const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
- strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
-
- bool data_was_read = false;
-
-#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
- if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
- {
- // This mach-o memory file is in the dyld shared cache. If this
- // program is not remote and this is iOS, then this process will
- // share the same shared cache as the process we are debugging and
- // we can read the entire __LINKEDIT from the address space in this
- // process. This is a needed optimization that is used for local iOS
- // debugging only since all shared libraries in the shared cache do
- // not have corresponding files that exist in the file system of the
- // device. They have been combined into a single file. This means we
- // always have to load these files from memory. All of the symbol and
- // string tables from all of the __LINKEDIT sections from the shared
- // libraries in the shared cache have been merged into a single large
- // symbol and string table. Reading all of this symbol and string table
- // data across can slow down debug launch times, so we optimize this by
- // reading the memory for the __LINKEDIT section from this process.
-
- UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
- UUID process_shared_cache(GetProcessSharedCacheUUID(process));
- bool use_lldb_cache = true;
- if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
- {
- use_lldb_cache = false;
- ModuleSP module_sp (GetModule());
- if (module_sp)
- module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");
- }
-
- PlatformSP platform_sp (target.GetPlatform());
- if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
- {
- data_was_read = true;
- nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
- strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
- if (function_starts_load_command.cmd)
- {
- const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
- function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
- }
- }
- }
-#endif
+ dylib_files.Append(file_spec);
+ }
+ } break;
+
+ case LC_FUNCTION_STARTS:
+ function_starts_load_command.cmd = lc.cmd;
+ function_starts_load_command.cmdsize = lc.cmdsize;
+ if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
+ NULL) // fill in symoff, nsyms, stroff, strsize fields
+ memset(&function_starts_load_command, 0,
+ sizeof(function_starts_load_command));
+ break;
+
+ default:
+ break;
+ }
+ offset = cmd_offset + lc.cmdsize;
+ }
- if (!data_was_read)
- {
- if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
- {
- DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
- 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 - linkedit_file_offset;
- DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
- if (indirect_syms_data_sp)
- indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
- }
- }
-
- if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
- {
- if (function_starts_load_command.cmd)
- {
- const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
- DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
- if (func_start_data_sp)
- function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
- }
- }
- }
- }
+ if (symtab_load_command.cmd) {
+ Symtab *symtab = m_symtab_ap.get();
+ SectionList *section_list = GetSectionList();
+ if (section_list == NULL)
+ return 0;
+
+ const uint32_t addr_byte_size = m_data.GetAddressByteSize();
+ const ByteOrder byte_order = m_data.GetByteOrder();
+ bool bit_width_32 = addr_byte_size == 4;
+ const size_t nlist_byte_size =
+ bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
+
+ DataExtractor nlist_data(NULL, 0, byte_order, addr_byte_size);
+ DataExtractor strtab_data(NULL, 0, byte_order, addr_byte_size);
+ DataExtractor function_starts_data(NULL, 0, byte_order, addr_byte_size);
+ DataExtractor indirect_symbol_index_data(NULL, 0, byte_order,
+ addr_byte_size);
+ DataExtractor dyld_trie_data(NULL, 0, byte_order, addr_byte_size);
+
+ const addr_t nlist_data_byte_size =
+ symtab_load_command.nsyms * nlist_byte_size;
+ const addr_t strtab_data_byte_size = symtab_load_command.strsize;
+ addr_t strtab_addr = LLDB_INVALID_ADDRESS;
+
+ ProcessSP process_sp(m_process_wp.lock());
+ Process *process = process_sp.get();
+
+ uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
+
+ if (process && m_header.filetype != llvm::MachO::MH_OBJECT) {
+ Target &target = process->GetTarget();
+
+ memory_module_load_level = target.GetMemoryModuleLoadLevel();
+
+ SectionSP linkedit_section_sp(
+ section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
+ // Reading mach file from memory in a process or core file...
+
+ if (linkedit_section_sp) {
+ addr_t linkedit_load_addr =
+ linkedit_section_sp->GetLoadBaseAddress(&target);
+ if (linkedit_load_addr == LLDB_INVALID_ADDRESS) {
+ // We might be trying to access the symbol table before the
+ // __LINKEDIT's load
+ // address has been set in the target. We can't fail to read the
+ // symbol table,
+ // so calculate the right address manually
+ linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
+ m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
}
- else
- {
- nlist_data.SetData (m_data,
- symtab_load_command.symoff,
- nlist_data_byte_size);
- strtab_data.SetData (m_data,
- symtab_load_command.stroff,
- strtab_data_byte_size);
-
- if (dyld_info.export_size > 0)
- {
- dyld_trie_data.SetData (m_data,
- dyld_info.export_off,
- dyld_info.export_size);
- }
- if (m_dysymtab.nindirectsyms != 0)
- {
- indirect_symbol_index_data.SetData (m_data,
- m_dysymtab.indirectsymoff,
- m_dysymtab.nindirectsyms * 4);
- }
- if (function_starts_load_command.cmd)
- {
- function_starts_data.SetData (m_data,
- function_starts_load_command.dataoff,
- function_starts_load_command.datasize);
+ const addr_t linkedit_file_offset =
+ linkedit_section_sp->GetFileOffset();
+ const addr_t symoff_addr = linkedit_load_addr +
+ symtab_load_command.symoff -
+ linkedit_file_offset;
+ strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
+ linkedit_file_offset;
+
+ bool data_was_read = false;
+
+#if defined(__APPLE__) && \
+ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
+ if (m_header.flags & 0x80000000u &&
+ process->GetAddressByteSize() == sizeof(void *)) {
+ // This mach-o memory file is in the dyld shared cache. If this
+ // program is not remote and this is iOS, then this process will
+ // share the same shared cache as the process we are debugging and
+ // we can read the entire __LINKEDIT from the address space in this
+ // process. This is a needed optimization that is used for local iOS
+ // debugging only since all shared libraries in the shared cache do
+ // not have corresponding files that exist in the file system of the
+ // device. They have been combined into a single file. This means we
+ // always have to load these files from memory. All of the symbol and
+ // string tables from all of the __LINKEDIT sections from the shared
+ // libraries in the shared cache have been merged into a single large
+ // symbol and string table. Reading all of this symbol and string
+ // table
+ // data across can slow down debug launch times, so we optimize this
+ // by
+ // reading the memory for the __LINKEDIT section from this process.
+
+ UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
+ UUID process_shared_cache(GetProcessSharedCacheUUID(process));
+ bool use_lldb_cache = true;
+ if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() &&
+ lldb_shared_cache != process_shared_cache) {
+ use_lldb_cache = false;
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ module_sp->ReportWarning("shared cache in process does not match "
+ "lldb's own shared cache, startup will "
+ "be slow.");
+ }
+
+ PlatformSP platform_sp(target.GetPlatform());
+ if (platform_sp && platform_sp->IsHost() && use_lldb_cache) {
+ data_was_read = true;
+ nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size,
+ eByteOrderLittle);
+ strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size,
+ eByteOrderLittle);
+ if (function_starts_load_command.cmd) {
+ const addr_t func_start_addr =
+ linkedit_load_addr + function_starts_load_command.dataoff -
+ linkedit_file_offset;
+ function_starts_data.SetData(
+ (void *)func_start_addr,
+ function_starts_load_command.datasize, eByteOrderLittle);
}
+ }
}
+#endif
- if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
- {
- if (log)
- module_sp->LogMessage(log, "failed to read nlist data");
- return 0;
- }
-
- const bool have_strtab_data = strtab_data.GetByteSize() > 0;
- if (!have_strtab_data)
- {
- if (process)
- {
- if (strtab_addr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- module_sp->LogMessage(log, "failed to locate the strtab in memory");
- return 0;
- }
+ if (!data_was_read) {
+ // Always load dyld - the dynamic linker - from memory if we didn't
+ // find a binary anywhere else.
+ // lldb will not register dylib/framework/bundle loads/unloads if we
+ // don't have the dyld symbols,
+ // we force dyld to load from memory despite the user's
+ // target.memory-module-load-level setting.
+ if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
+ m_header.filetype == llvm::MachO::MH_DYLINKER) {
+ DataBufferSP nlist_data_sp(
+ ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
+ 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 -
+ linkedit_file_offset;
+ DataBufferSP indirect_syms_data_sp(
+ ReadMemory(process_sp, indirect_syms_addr,
+ m_dysymtab.nindirectsyms * 4));
+ if (indirect_syms_data_sp)
+ indirect_symbol_index_data.SetData(
+ indirect_syms_data_sp, 0,
+ indirect_syms_data_sp->GetByteSize());
}
- else
- {
- if (log)
- module_sp->LogMessage(log, "failed to read strtab data");
- return 0;
+ } else if (memory_module_load_level >=
+ eMemoryModuleLoadLevelPartial) {
+ if (function_starts_load_command.cmd) {
+ const addr_t func_start_addr =
+ linkedit_load_addr + function_starts_load_command.dataoff -
+ linkedit_file_offset;
+ DataBufferSP func_start_data_sp(
+ ReadMemory(process_sp, func_start_addr,
+ function_starts_load_command.datasize));
+ if (func_start_data_sp)
+ function_starts_data.SetData(func_start_data_sp, 0,
+ func_start_data_sp->GetByteSize());
}
+ }
}
+ }
+ } else {
+ nlist_data.SetData(m_data, symtab_load_command.symoff,
+ nlist_data_byte_size);
+ strtab_data.SetData(m_data, symtab_load_command.stroff,
+ strtab_data_byte_size);
+
+ if (dyld_info.export_size > 0) {
+ dyld_trie_data.SetData(m_data, dyld_info.export_off,
+ dyld_info.export_size);
+ }
+
+ if (m_dysymtab.nindirectsyms != 0) {
+ indirect_symbol_index_data.SetData(m_data, m_dysymtab.indirectsymoff,
+ m_dysymtab.nindirectsyms * 4);
+ }
+ if (function_starts_load_command.cmd) {
+ function_starts_data.SetData(m_data,
+ function_starts_load_command.dataoff,
+ function_starts_load_command.datasize);
+ }
+ }
- const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
- const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
- const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
- const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
- const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
- const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
- SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
- SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
- SectionSP data_dirty_section_sp(section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
- SectionSP data_const_section_sp(section_list->FindSectionByName(g_segment_name_DATA_CONST));
- SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
- SectionSP eh_frame_section_sp;
- if (text_section_sp.get())
- eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
- else
- eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
-
- const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
-
- // lldb works best if it knows the start address of all functions in a module.
- // Linker symbols or debug info are normally the best source of information for start addr / size but
- // they may be stripped in a released binary.
- // Two additional sources of information exist in Mach-O binaries:
- // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
- // binary, relative to the text section.
- // eh_frame - the eh_frame FDEs have the start addr & size of each function
- // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
- // Binaries built to run on older releases may need to use eh_frame information.
-
- if (text_section_sp && function_starts_data.GetByteSize())
- {
- FunctionStarts::Entry function_start_entry;
- function_start_entry.data = false;
- lldb::offset_t function_start_offset = 0;
- function_start_entry.addr = text_section_sp->GetFileAddress();
- uint64_t delta;
- while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
- {
- // Now append the current entry
- function_start_entry.addr += delta;
- function_starts.Append(function_start_entry);
- }
- }
- else
- {
- // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
- // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
- // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
- // the module.
- if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
- {
- DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindEHFrame, true);
- DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
- eh_frame.GetFunctionAddressAndSizeVector (functions);
- addr_t text_base_addr = text_section_sp->GetFileAddress();
- size_t count = functions.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
- if (func)
- {
- FunctionStarts::Entry function_start_entry;
- function_start_entry.addr = func->base - text_base_addr;
- function_starts.Append(function_start_entry);
- }
- }
- }
- }
+ if (nlist_data.GetByteSize() == 0 &&
+ memory_module_load_level == eMemoryModuleLoadLevelComplete) {
+ if (log)
+ module_sp->LogMessage(log, "failed to read nlist data");
+ return 0;
+ }
- const size_t function_starts_count = function_starts.GetSize();
-
- // For user process binaries (executables, dylibs, frameworks, bundles), if we don't have
- // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume the binary
- // has been stripped. Don't allow assembly language instruction emulation because we don't
- // know proper function start boundaries.
- //
- // For all other types of binaries (kernels, stand-alone bare board binaries, kexts), they
- // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make any assumptions
- // about them based on that.
- if (function_starts_count == 0 && CalculateStrata() == eStrataUser)
- {
- m_allow_assembly_emulation_unwind_plans = false;
- Log *unwind_or_symbol_log (lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND));
-
- if (unwind_or_symbol_log)
- module_sp->LogMessage(unwind_or_symbol_log, "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
+ const bool have_strtab_data = strtab_data.GetByteSize() > 0;
+ if (!have_strtab_data) {
+ if (process) {
+ if (strtab_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ module_sp->LogMessage(log, "failed to locate the strtab in memory");
+ return 0;
}
+ } else {
+ if (log)
+ module_sp->LogMessage(log, "failed to read strtab data");
+ return 0;
+ }
+ }
- const user_id_t TEXT_eh_frame_sectID =
- eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
- : static_cast<user_id_t>(NO_SECT);
-
- lldb::offset_t nlist_data_offset = 0;
-
- uint32_t N_SO_index = UINT32_MAX;
-
- MachSymtabSectionInfo section_info (section_list);
- std::vector<uint32_t> N_FUN_indexes;
- std::vector<uint32_t> N_NSYM_indexes;
- std::vector<uint32_t> N_INCL_indexes;
- std::vector<uint32_t> N_BRAC_indexes;
- std::vector<uint32_t> N_COMM_indexes;
- typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
- typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
- typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
- ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
- ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
- ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
- // Any symbols that get merged into another will get an entry
- // in this map so we know
- NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
- uint32_t nlist_idx = 0;
- Symbol *symbol_ptr = NULL;
-
- uint32_t sym_idx = 0;
- Symbol *sym = NULL;
- size_t num_syms = 0;
- std::string memory_symbol_name;
- uint32_t unmapped_local_symbols_found = 0;
-
- std::vector<TrieEntryWithOffset> trie_entries;
- std::set<lldb::addr_t> resolver_addresses;
-
- if (dyld_trie_data.GetByteSize() > 0)
- {
- std::vector<llvm::StringRef> nameSlices;
- ParseTrieEntries (dyld_trie_data,
- 0,
- is_arm,
- nameSlices,
- resolver_addresses,
- trie_entries);
-
- ConstString text_segment_name ("__TEXT");
- SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
- if (text_segment_sp)
- {
- const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
- if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
- {
- for (auto &e : trie_entries)
- e.entry.address += text_segment_file_addr;
- }
- }
+ const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
+ const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
+ const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
+ const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
+ const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
+ const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
+ SectionSP text_section_sp(
+ section_list->FindSectionByName(g_segment_name_TEXT));
+ SectionSP data_section_sp(
+ section_list->FindSectionByName(g_segment_name_DATA));
+ SectionSP data_dirty_section_sp(
+ section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
+ SectionSP data_const_section_sp(
+ section_list->FindSectionByName(g_segment_name_DATA_CONST));
+ SectionSP objc_section_sp(
+ section_list->FindSectionByName(g_segment_name_OBJC));
+ SectionSP eh_frame_section_sp;
+ if (text_section_sp.get())
+ eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
+ g_section_name_eh_frame);
+ else
+ eh_frame_section_sp =
+ section_list->FindSectionByName(g_section_name_eh_frame);
+
+ const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
+
+ // lldb works best if it knows the start address of all functions in a
+ // module.
+ // Linker symbols or debug info are normally the best source of information
+ // for start addr / size but
+ // they may be stripped in a released binary.
+ // Two additional sources of information exist in Mach-O binaries:
+ // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each
+ // function's start address in the
+ // binary, relative to the text section.
+ // eh_frame - the eh_frame FDEs have the start addr & size of
+ // each function
+ // LC_FUNCTION_STARTS is the fastest source to read in, and is present on
+ // all modern binaries.
+ // Binaries built to run on older releases may need to use eh_frame
+ // information.
+
+ if (text_section_sp && function_starts_data.GetByteSize()) {
+ FunctionStarts::Entry function_start_entry;
+ function_start_entry.data = false;
+ lldb::offset_t function_start_offset = 0;
+ function_start_entry.addr = text_section_sp->GetFileAddress();
+ uint64_t delta;
+ while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
+ 0) {
+ // Now append the current entry
+ function_start_entry.addr += delta;
+ function_starts.Append(function_start_entry);
+ }
+ } else {
+ // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the
+ // load command claiming an eh_frame
+ // but it doesn't actually have the eh_frame content. And if we have a
+ // dSYM, we don't need to do any
+ // of this fill-in-the-missing-symbols works anyway - the debug info
+ // should give us all the functions in
+ // the module.
+ if (text_section_sp.get() && eh_frame_section_sp.get() &&
+ m_type != eTypeDebugInfo) {
+ DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,
+ eRegisterKindEHFrame, true);
+ DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
+ eh_frame.GetFunctionAddressAndSizeVector(functions);
+ addr_t text_base_addr = text_section_sp->GetFileAddress();
+ size_t count = functions.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func =
+ functions.GetEntryAtIndex(i);
+ if (func) {
+ FunctionStarts::Entry function_start_entry;
+ function_start_entry.addr = func->base - text_base_addr;
+ function_starts.Append(function_start_entry);
+ }
}
+ }
+ }
- typedef std::set<ConstString> IndirectSymbols;
- IndirectSymbols indirect_symbol_names;
-
-#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
-
- // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
- // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
- // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
- // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
- // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
- // nlist parser to ignore all LOCAL symbols.
-
- if (m_header.flags & 0x80000000u)
- {
- // Before we can start mapping the DSC, we need to make certain the target process is actually
- // using the cache we can find.
-
- // Next we need to determine the correct path for the dyld shared cache.
-
- ArchSpec header_arch;
- GetArchitecture(header_arch);
- char dsc_path[PATH_MAX];
- char dsc_path_development[PATH_MAX];
-
- snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
- "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
- "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
- header_arch.GetArchitectureName());
-
- snprintf(dsc_path_development, sizeof(dsc_path), "%s%s%s%s",
- "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
- "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
- header_arch.GetArchitectureName(),
- ".development");
-
- FileSpec dsc_nondevelopment_filespec(dsc_path, false);
- FileSpec dsc_development_filespec(dsc_path_development, false);
- FileSpec dsc_filespec;
-
- UUID dsc_uuid;
- UUID process_shared_cache_uuid;
-
- if (process)
- {
- process_shared_cache_uuid = GetProcessSharedCacheUUID(process);
- }
-
- // First see if we can find an exact match for the inferior process shared cache UUID in
- // the development or non-development shared caches on disk.
- if (process_shared_cache_uuid.IsValid())
- {
- if (dsc_development_filespec.Exists())
- {
- UUID dsc_development_uuid = GetSharedCacheUUID (dsc_development_filespec, byte_order, addr_byte_size);
- if (dsc_development_uuid.IsValid() && dsc_development_uuid == process_shared_cache_uuid)
- {
- dsc_filespec = dsc_development_filespec;
- dsc_uuid = dsc_development_uuid;
- }
- }
- if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists())
- {
- UUID dsc_nondevelopment_uuid = GetSharedCacheUUID (dsc_nondevelopment_filespec, byte_order, addr_byte_size);
- if (dsc_nondevelopment_uuid.IsValid() && dsc_nondevelopment_uuid == process_shared_cache_uuid)
- {
- dsc_filespec = dsc_nondevelopment_filespec;
- dsc_uuid = dsc_nondevelopment_uuid;
- }
- }
- }
-
- // Failing a UUID match, prefer the development dyld_shared cache if both are present.
- if (!dsc_filespec.Exists())
- {
- if (dsc_development_filespec.Exists())
- {
- dsc_filespec = dsc_development_filespec;
- }
- else
- {
- dsc_filespec = dsc_nondevelopment_filespec;
- }
- }
-
- /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
- The dyld_cache_local_symbols_info structure gives us three things:
- 1. The start and count of the nlist records in the dyld_shared_cache file
- 2. The start and size of the strings for these nlist records
- 3. The start and count of dyld_cache_local_symbols_entry entries
-
- There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
- The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
- The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
- and the count of how many nlist records there are for this dylib/framework.
- */
-
- // Process the dyld shared cache header to find the unmapped symbols
-
- DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
- if (!dsc_uuid.IsValid())
- {
- dsc_uuid = GetSharedCacheUUID (dsc_filespec, byte_order, addr_byte_size);
- }
- if (dsc_data_sp)
- {
- DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size);
-
- bool uuid_match = true;
- if (dsc_uuid.IsValid() && process)
- {
- if (process_shared_cache_uuid.IsValid() && dsc_uuid != process_shared_cache_uuid)
- {
- // The on-disk dyld_shared_cache file is not the same as the one in this
- // process' memory, don't use it.
- uuid_match = false;
- ModuleSP module_sp (GetModule());
- if (module_sp)
- module_sp->ReportWarning ("process shared cache does not match on-disk dyld_shared_cache file, some symbol names will be missing.");
- }
- }
-
- offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
-
- uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
-
- // If the mappingOffset points to a location inside the header, we've
- // opened an old dyld shared cache, and should not proceed further.
- if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1))
- {
-
- DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
- DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
- offset = 0;
-
- // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
- // in the shared library cache need to be adjusted by an offset to match up with the
- // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
- // recorded in mapping_offset_value.
- const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
-
- offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
- uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
- uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
+ const size_t function_starts_count = function_starts.GetSize();
- if (localSymbolsOffset && localSymbolsSize)
- {
- // Map the local symbols
- if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize))
- {
- DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
-
- offset = 0;
-
- typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
- typedef std::map<uint32_t, ConstString> SymbolIndexToName;
- UndefinedNameToDescMap undefined_name_to_desc;
- SymbolIndexToName reexport_shlib_needs_fixup;
-
-
- // Read the local_symbols_infos struct in one shot
- struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
- dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
-
- SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
-
- uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
-
- offset = local_symbols_info.entriesOffset;
- for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
- {
- struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
- local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
- local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
- local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
-
- if (header_file_offset == local_symbols_entry.dylibOffset)
- {
- unmapped_local_symbols_found = local_symbols_entry.nlistCount;
-
- // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
- sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
- num_syms = symtab->GetNumSymbols();
-
- nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
- uint32_t string_table_offset = local_symbols_info.stringsOffset;
-
- for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
- {
- /////////////////////////////
- {
- struct nlist_64 nlist;
- if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
- break;
-
- nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
- nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
- nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
- nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
- nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
-
- SymbolType type = eSymbolTypeInvalid;
- const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
-
- if (symbol_name == NULL)
- {
- // No symbol should be NULL, even the symbols with no
- // string values should have an offset zero which points
- // to an empty C-string
- Host::SystemLog (Host::eSystemLogError,
- "error: DSC unmapped local symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
- entry_index,
- nlist.n_strx,
- module_sp->GetFileSpec().GetPath().c_str());
- continue;
- }
- if (symbol_name[0] == '\0')
- symbol_name = NULL;
-
- const char *symbol_name_non_abi_mangled = NULL;
-
- SectionSP symbol_section;
- uint32_t symbol_byte_size = 0;
- bool add_nlist = true;
- bool is_debug = ((nlist.n_type & N_STAB) != 0);
- bool demangled_is_synthesized = false;
- bool is_gsym = false;
- bool set_value = true;
-
- assert (sym_idx < num_syms);
-
- sym[sym_idx].SetDebug (is_debug);
-
- if (is_debug)
- {
- switch (nlist.n_type)
- {
- case N_GSYM:
- // global symbol: name,,NO_SECT,type,0
- // Sometimes the N_GSYM value contains the address.
-
- // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
- // have the same address, but we want to ensure that we always find only the real symbol,
- // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
- // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
- // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
- // same address.
-
- is_gsym = true;
- sym[sym_idx].SetExternal(true);
-
- if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
- {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- else
- {
- if (nlist.n_value != 0)
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeData;
- }
- break;
-
- case N_FNAME:
- // procedure name (f77 kludge): name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_FUN:
- // procedure: name,,n_sect,linenumber,address
- if (symbol_name)
- {
- type = eSymbolTypeCode;
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-
- N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- N_FUN_indexes.push_back(sym_idx);
- }
- else
- {
- type = eSymbolTypeCompiler;
-
- if ( !N_FUN_indexes.empty() )
- {
- // Copy the size of the function into the original STAB entry so we don't have
- // to hunt for it later
- symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
- N_FUN_indexes.pop_back();
- // We don't really need the end function STAB as it contains the size which
- // we already placed with the original symbol, so don't add it if we want a
- // minimal symbol table
- add_nlist = false;
- }
- }
- break;
-
- case N_STSYM:
- // static symbol: name,,n_sect,type,address
- N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- if (symbol_name && symbol_name[0])
- {
- type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData);
- }
- break;
-
- case N_LCSYM:
- // .lcomm symbol: name,,n_sect,type,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeCommonBlock;
- break;
-
- case N_BNSYM:
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
-
- case N_ENSYM:
- // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
-
- case N_OPT:
- // emitted with gcc2_compiled and in gcc source
- type = eSymbolTypeCompiler;
- break;
-
- case N_RSYM:
- // register sym: name,,NO_SECT,type,register
- type = eSymbolTypeVariable;
- break;
-
- case N_SLINE:
- // src line: 0,,n_sect,linenumber,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- case N_SSYM:
- // structure elt: name,,NO_SECT,type,struct_offset
- type = eSymbolTypeVariableType;
- break;
-
- case N_SO:
- // source file name
- type = eSymbolTypeSourceFile;
- if (symbol_name == NULL)
- {
- add_nlist = false;
- if (N_SO_index != UINT32_MAX)
- {
- // Set the size of the N_SO to the terminating index of this N_SO
- // so that we can always skip the entire N_SO if we need to navigate
- // more quickly at the source level when parsing STABS
- symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
- symbol_ptr->SetByteSize(sym_idx);
- symbol_ptr->SetSizeIsSibling(true);
- }
- N_NSYM_indexes.clear();
- N_INCL_indexes.clear();
- N_BRAC_indexes.clear();
- N_COMM_indexes.clear();
- N_FUN_indexes.clear();
- N_SO_index = UINT32_MAX;
- }
- else
- {
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- const bool N_SO_has_full_path = symbol_name[0] == '/';
- if (N_SO_has_full_path)
- {
- if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
- {
- // We have two consecutive N_SO entries where the first contains a directory
- // and the second contains a full path.
- sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- add_nlist = false;
- }
- else
- {
- // This is the first entry in a N_SO that contains a directory or
- // a full path to the source file
- N_SO_index = sym_idx;
- }
- }
- else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
- {
- // This is usually the second N_SO entry that contains just the filename,
- // so here we combine it with the first one if we are minimizing the symbol table
- const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString();
- if (so_path && so_path[0])
- {
- std::string full_so_path (so_path);
- const size_t double_slash_pos = full_so_path.find("//");
- if (double_slash_pos != std::string::npos)
- {
- // The linker has been generating bad N_SO entries with doubled up paths
- // in the format "%s%s" where the first string in the DW_AT_comp_dir,
- // and the second is the directory for the source file so you end up with
- // a path that looks like "/tmp/src//tmp/src/"
- FileSpec so_dir(so_path, false);
- if (!so_dir.Exists())
- {
- so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
- if (so_dir.Exists())
- {
- // Trim off the incorrect path
- full_so_path.erase(0, double_slash_pos + 1);
- }
- }
- }
- if (*full_so_path.rbegin() != '/')
- full_so_path += '/';
- full_so_path += symbol_name;
- sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
- add_nlist = false;
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- }
- }
- else
- {
- // This could be a relative path to a N_SO
- N_SO_index = sym_idx;
- }
- }
- break;
-
- case N_OSO:
- // object file name: name,,0,0,st_mtime
- type = eSymbolTypeObjectFile;
- break;
-
- case N_LSYM:
- // local sym: name,,NO_SECT,type,offset
- type = eSymbolTypeLocal;
- break;
-
- //----------------------------------------------------------------------
- // INCL scopes
- //----------------------------------------------------------------------
- case N_BINCL:
- // include file beginning: name,,NO_SECT,0,sum
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- N_INCL_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_EINCL:
- // include file end: name,,NO_SECT,0,0
- // Set the size of the N_BINCL to the terminating index of this N_EINCL
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- if ( !N_INCL_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_INCL_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_SOL:
- // #included file name: name,,n_sect,0,address
- type = eSymbolTypeHeaderFile;
-
- // We currently don't use the header files on darwin
- add_nlist = false;
- break;
-
- case N_PARAMS:
- // compiler parameters: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_VERSION:
- // compiler version: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_OLEVEL:
- // compiler -O level: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_PSYM:
- // parameter: name,,NO_SECT,type,offset
- type = eSymbolTypeVariable;
- break;
-
- case N_ENTRY:
- // alternate entry: name,,n_sect,linenumber,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- //----------------------------------------------------------------------
- // Left and Right Braces
- //----------------------------------------------------------------------
- case N_LBRAC:
- // left bracket: 0,,NO_SECT,nesting level,address
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- N_BRAC_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_RBRAC:
- // right bracket: 0,,NO_SECT,nesting level,address
- // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- if ( !N_BRAC_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_BRAC_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_EXCL:
- // deleted include file: name,,NO_SECT,0,sum
- type = eSymbolTypeHeaderFile;
- break;
-
- //----------------------------------------------------------------------
- // COMM scopes
- //----------------------------------------------------------------------
- case N_BCOMM:
- // begin common: name,,NO_SECT,0,0
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- type = eSymbolTypeScopeBegin;
- N_COMM_indexes.push_back(sym_idx);
- break;
-
- case N_ECOML:
- // end common (local name): 0,,n_sect,0,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- // Fall through
-
- case N_ECOMM:
- // end common: name,,n_sect,0,0
- // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- if ( !N_COMM_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_COMM_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_LENG:
- // second stab entry with length information
- type = eSymbolTypeAdditional;
- break;
-
- default: break;
- }
- }
- else
- {
- //uint8_t n_pext = N_PEXT & nlist.n_type;
- uint8_t n_type = N_TYPE & nlist.n_type;
- sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
-
- switch (n_type)
- {
- case N_INDR:
- {
- const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
- if (reexport_name_cstr && reexport_name_cstr[0])
- {
- type = eSymbolTypeReExported;
- ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
- sym[sym_idx].SetReExportedSymbolName(reexport_name);
- set_value = false;
- reexport_shlib_needs_fixup[sym_idx] = reexport_name;
- indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
- }
- else
- type = eSymbolTypeUndefined;
- }
- break;
-
- case N_UNDF:
- if (symbol_name && symbol_name[0])
- {
- ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
- undefined_name_to_desc[undefined_name] = nlist.n_desc;
- }
- // Fall through
- case N_PBUD:
- type = eSymbolTypeUndefined;
- break;
-
- case N_ABS:
- type = eSymbolTypeAbsolute;
- break;
-
- case N_SECT:
- {
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-
- if (symbol_section == NULL)
- {
- // TODO: warn about this?
- add_nlist = false;
- break;
- }
-
- if (TEXT_eh_frame_sectID == nlist.n_sect)
- {
- type = eSymbolTypeException;
- }
- else
- {
- uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
-
- switch (section_type)
- {
- case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
- case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
- case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
- case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
- case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
- case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
- case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
- case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
- case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
- case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
- case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
- case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
- case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
- default:
- switch (symbol_section->GetType())
- {
- case lldb::eSectionTypeCode:
- type = eSymbolTypeCode;
- break;
- case eSectionTypeData:
- case eSectionTypeDataCString: // Inlined C string data
- case eSectionTypeDataCStringPointers: // Pointers to C string data
- case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
- case eSectionTypeData4:
- case eSectionTypeData8:
- case eSectionTypeData16:
- type = eSymbolTypeData;
- break;
- default:
- break;
- }
- break;
- }
-
- if (type == eSymbolTypeInvalid)
- {
- const char *symbol_sect_name = symbol_section->GetName().AsCString();
- if (symbol_section->IsDescendant (text_section_sp.get()))
- {
- if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
- S_ATTR_SELF_MODIFYING_CODE |
- S_ATTR_SOME_INSTRUCTIONS))
- type = eSymbolTypeData;
- else
- type = eSymbolTypeCode;
- }
- else if (symbol_section->IsDescendant(data_section_sp.get()) ||
- symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
- symbol_section->IsDescendant(data_const_section_sp.get()))
- {
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
- {
- type = eSymbolTypeRuntime;
-
- if (symbol_name)
- {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.startswith("_OBJC_"))
- {
- static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
- if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- }
- }
- else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
- {
- type = eSymbolTypeException;
- }
- else
- {
- type = eSymbolTypeData;
- }
- }
- else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
- {
- type = eSymbolTypeTrampoline;
- }
- else if (symbol_section->IsDescendant(objc_section_sp.get()))
- {
- type = eSymbolTypeRuntime;
- if (symbol_name && symbol_name[0] == '.')
- {
- llvm::StringRef symbol_name_ref(symbol_name);
- static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
- if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name;
- symbol_name = symbol_name + g_objc_v1_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- }
- }
- }
- }
- }
- }
- break;
- }
- }
-
- if (add_nlist)
- {
- uint64_t symbol_value = nlist.n_value;
- if (symbol_name_non_abi_mangled)
- {
- sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
- sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
- }
- else
- {
- bool symbol_name_is_mangled = false;
-
- if (symbol_name && symbol_name[0] == '_')
- {
- symbol_name_is_mangled = symbol_name[1] == '_';
- symbol_name++; // Skip the leading underscore
- }
-
- if (symbol_name)
- {
- ConstString const_symbol_name(symbol_name);
- sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
- if (is_gsym && is_debug)
- {
- const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
- if (gsym_name)
- N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
- }
- }
- }
- if (symbol_section)
- {
- const addr_t section_file_addr = symbol_section->GetFileAddress();
- if (symbol_byte_size == 0 && function_starts_count > 0)
- {
- addr_t symbol_lookup_file_addr = nlist.n_value;
- // Do an exact address match for non-ARM addresses, else get the closest since
- // the symbol might be a thumb symbol which has an address with bit zero set
- FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
- if (is_arm && func_start_entry)
- {
- // Verify that the function start address is the symbol address (ARM)
- // or the symbol address + 1 (thumb)
- if (func_start_entry->addr != symbol_lookup_file_addr &&
- func_start_entry->addr != (symbol_lookup_file_addr + 1))
- {
- // Not the right entry, NULL it out...
- func_start_entry = NULL;
- }
- }
- if (func_start_entry)
- {
- func_start_entry->data = true;
-
- addr_t symbol_file_addr = func_start_entry->addr;
- uint32_t symbol_flags = 0;
- if (is_arm)
- {
- if (symbol_file_addr & 1)
- symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
- symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- }
-
- const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
- const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
- if (next_func_start_entry)
- {
- addr_t next_symbol_file_addr = next_func_start_entry->addr;
- // Be sure the clear the Thumb address bit when we calculate the size
- // from the current and next address
- if (is_arm)
- next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
- }
- else
- {
- symbol_byte_size = section_end_file_addr - symbol_file_addr;
- }
- }
- }
- symbol_value -= section_file_addr;
- }
-
- if (is_debug == false)
- {
- if (type == eSymbolTypeCode)
- {
- // See if we can find a N_FUN entry for any code symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the function symbol to avoid
- // duplicate entries in the symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
- range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
- if (range.first != range.second)
- {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
- {
- if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
- {
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put these flags
- // into the N_FUN flags to avoid duplicate symbols in the symbol table
- sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
- sym[pos->second].SetType (eSymbolTypeResolver);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
- }
- if (found_it)
- continue;
- }
- else
- {
- if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
- type = eSymbolTypeResolver;
- }
- }
- else if (type == eSymbolTypeData ||
- type == eSymbolTypeObjCClass ||
- type == eSymbolTypeObjCMetaClass ||
- type == eSymbolTypeObjCIVar )
- {
- // See if we can find a N_STSYM entry for any data symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the Static symbol to avoid
- // duplicate entries in the symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
- range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
- if (range.first != range.second)
- {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
- {
- if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
- {
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put these flags
- // into the N_STSYM flags to avoid duplicate symbols in the symbol table
- sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
- }
- if (found_it)
- continue;
- }
- else
- {
- const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
- if (gsym_name)
- {
- // Combine N_GSYM stab entries with the non stab symbol
- ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
- if (pos != N_GSYM_name_to_sym_idx.end())
- {
- const uint32_t GSYM_sym_idx = pos->second;
- m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
- // Copy the address, because often the N_GSYM address has an invalid address of zero
- // when the global is a common symbol
- sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
- sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
- // We just need the flags from the linker symbol, so put these flags
- // into the N_GSYM flags to avoid duplicate symbols in the symbol table
- sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- continue;
- }
- }
- }
- }
- }
-
- sym[sym_idx].SetID (nlist_idx);
- sym[sym_idx].SetType (type);
- if (set_value)
- {
- sym[sym_idx].GetAddressRef().SetSection (symbol_section);
- sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
- }
- sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
-
- if (symbol_byte_size > 0)
- sym[sym_idx].SetByteSize(symbol_byte_size);
-
- if (demangled_is_synthesized)
- sym[sym_idx].SetDemangledNameIsSynthesized(true);
- ++sym_idx;
- }
- else
- {
- sym[sym_idx].Clear();
- }
-
- }
- /////////////////////////////
- }
- break; // No more entries to consider
- }
- }
+ // For user process binaries (executables, dylibs, frameworks, bundles), if
+ // we don't have
+ // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume
+ // the binary
+ // has been stripped. Don't allow assembly language instruction emulation
+ // because we don't
+ // know proper function start boundaries.
+ //
+ // For all other types of binaries (kernels, stand-alone bare board
+ // binaries, kexts), they
+ // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make
+ // any assumptions
+ // about them based on that.
+ if (function_starts_count == 0 && CalculateStrata() == eStrataUser) {
+ m_allow_assembly_emulation_unwind_plans = false;
+ Log *unwind_or_symbol_log(lldb_private::GetLogIfAnyCategoriesSet(
+ LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND));
+
+ if (unwind_or_symbol_log)
+ module_sp->LogMessage(
+ unwind_or_symbol_log,
+ "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
+ }
- for (const auto &pos :reexport_shlib_needs_fixup)
- {
- const auto undef_pos = undefined_name_to_desc.find(pos.second);
- if (undef_pos != undefined_name_to_desc.end())
- {
- const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
- if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
- sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
- }
- }
- }
- }
- }
- }
+ const user_id_t TEXT_eh_frame_sectID =
+ eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
+ : static_cast<user_id_t>(NO_SECT);
+
+ lldb::offset_t nlist_data_offset = 0;
+
+ uint32_t N_SO_index = UINT32_MAX;
+
+ MachSymtabSectionInfo section_info(section_list);
+ std::vector<uint32_t> N_FUN_indexes;
+ std::vector<uint32_t> N_NSYM_indexes;
+ std::vector<uint32_t> N_INCL_indexes;
+ std::vector<uint32_t> N_BRAC_indexes;
+ std::vector<uint32_t> N_COMM_indexes;
+ typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
+ typedef std::map<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
+ typedef std::map<const char *, uint32_t> ConstNameToSymbolIndexMap;
+ ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
+ ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
+ ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
+ // Any symbols that get merged into another will get an entry
+ // in this map so we know
+ NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
+ uint32_t nlist_idx = 0;
+ Symbol *symbol_ptr = NULL;
+
+ uint32_t sym_idx = 0;
+ Symbol *sym = NULL;
+ size_t num_syms = 0;
+ std::string memory_symbol_name;
+ uint32_t unmapped_local_symbols_found = 0;
+
+ std::vector<TrieEntryWithOffset> trie_entries;
+ std::set<lldb::addr_t> resolver_addresses;
+
+ if (dyld_trie_data.GetByteSize() > 0) {
+ std::vector<llvm::StringRef> nameSlices;
+ ParseTrieEntries(dyld_trie_data, 0, is_arm, nameSlices,
+ resolver_addresses, trie_entries);
+
+ ConstString text_segment_name("__TEXT");
+ SectionSP text_segment_sp =
+ GetSectionList()->FindSectionByName(text_segment_name);
+ if (text_segment_sp) {
+ const lldb::addr_t text_segment_file_addr =
+ text_segment_sp->GetFileAddress();
+ if (text_segment_file_addr != LLDB_INVALID_ADDRESS) {
+ for (auto &e : trie_entries)
+ e.entry.address += text_segment_file_addr;
}
+ }
+ }
- // Must reset this in case it was mutated above!
- nlist_data_offset = 0;
-#endif
-
- if (nlist_data.GetByteSize() > 0)
- {
-
- // If the sym array was not created while parsing the DSC unmapped
- // symbols, create it now.
- if (sym == NULL)
- {
- sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
- num_syms = symtab->GetNumSymbols();
- }
-
- if (unmapped_local_symbols_found)
- {
- assert(m_dysymtab.ilocalsym == 0);
- nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
- nlist_idx = m_dysymtab.nlocalsym;
- }
- else
- {
- nlist_idx = 0;
- }
-
- typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
- typedef std::map<uint32_t, ConstString> SymbolIndexToName;
- UndefinedNameToDescMap undefined_name_to_desc;
- SymbolIndexToName reexport_shlib_needs_fixup;
- for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
- {
- struct nlist_64 nlist;
- if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
- break;
-
- nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
- nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
- nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
- nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
- nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
-
- SymbolType type = eSymbolTypeInvalid;
- const char *symbol_name = NULL;
-
- if (have_strtab_data)
- {
- symbol_name = strtab_data.PeekCStr(nlist.n_strx);
+ typedef std::set<ConstString> IndirectSymbols;
+ IndirectSymbols indirect_symbol_names;
+
+#if defined(__APPLE__) && \
+ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
+
+ // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
+ // optimized by moving LOCAL
+ // symbols out of the memory mapped portion of the DSC. The symbol
+ // information has all been retained,
+ // but it isn't available in the normal nlist data. However, there *are*
+ // duplicate entries of *some*
+ // LOCAL symbols in the normal nlist data. To handle this situation
+ // correctly, we must first attempt
+ // to parse any DSC unmapped symbol information. If we find any, we set a
+ // flag that tells the normal
+ // nlist parser to ignore all LOCAL symbols.
+
+ if (m_header.flags & 0x80000000u) {
+ // Before we can start mapping the DSC, we need to make certain the target
+ // process is actually
+ // using the cache we can find.
+
+ // Next we need to determine the correct path for the dyld shared cache.
+
+ ArchSpec header_arch;
+ GetArchitecture(header_arch);
+ char dsc_path[PATH_MAX];
+ char dsc_path_development[PATH_MAX];
+
+ snprintf(
+ dsc_path, sizeof(dsc_path), "%s%s%s",
+ "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
+ */
+ "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
+ header_arch.GetArchitectureName());
+
+ snprintf(
+ dsc_path_development, sizeof(dsc_path), "%s%s%s%s",
+ "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
+ */
+ "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
+ header_arch.GetArchitectureName(), ".development");
+
+ FileSpec dsc_nondevelopment_filespec(dsc_path, false);
+ FileSpec dsc_development_filespec(dsc_path_development, false);
+ FileSpec dsc_filespec;
+
+ UUID dsc_uuid;
+ UUID process_shared_cache_uuid;
+
+ if (process) {
+ process_shared_cache_uuid = GetProcessSharedCacheUUID(process);
+ }
+
+ // First see if we can find an exact match for the inferior process shared
+ // cache UUID in
+ // the development or non-development shared caches on disk.
+ if (process_shared_cache_uuid.IsValid()) {
+ if (dsc_development_filespec.Exists()) {
+ UUID dsc_development_uuid = GetSharedCacheUUID(
+ dsc_development_filespec, byte_order, addr_byte_size);
+ if (dsc_development_uuid.IsValid() &&
+ dsc_development_uuid == process_shared_cache_uuid) {
+ dsc_filespec = dsc_development_filespec;
+ dsc_uuid = dsc_development_uuid;
+ }
+ }
+ if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists()) {
+ UUID dsc_nondevelopment_uuid = GetSharedCacheUUID(
+ dsc_nondevelopment_filespec, byte_order, addr_byte_size);
+ if (dsc_nondevelopment_uuid.IsValid() &&
+ dsc_nondevelopment_uuid == process_shared_cache_uuid) {
+ dsc_filespec = dsc_nondevelopment_filespec;
+ dsc_uuid = dsc_nondevelopment_uuid;
+ }
+ }
+ }
+
+ // Failing a UUID match, prefer the development dyld_shared cache if both
+ // are present.
+ if (!dsc_filespec.Exists()) {
+ if (dsc_development_filespec.Exists()) {
+ dsc_filespec = dsc_development_filespec;
+ } else {
+ dsc_filespec = dsc_nondevelopment_filespec;
+ }
+ }
+
+ /* The dyld_cache_header has a pointer to the
+ dyld_cache_local_symbols_info structure (localSymbolsOffset).
+ The dyld_cache_local_symbols_info structure gives us three things:
+ 1. The start and count of the nlist records in the dyld_shared_cache
+ file
+ 2. The start and size of the strings for these nlist records
+ 3. The start and count of dyld_cache_local_symbols_entry entries
+
+ There is one dyld_cache_local_symbols_entry per dylib/framework in the
+ dyld shared cache.
+ The "dylibOffset" field is the Mach-O header of this dylib/framework in
+ the dyld shared cache.
+ The dyld_cache_local_symbols_entry also lists the start of this
+ dylib/framework's nlist records
+ and the count of how many nlist records there are for this
+ dylib/framework.
+ */
+
+ // Process the dyld shared cache header to find the unmapped symbols
+
+ DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(
+ 0, sizeof(struct lldb_copy_dyld_cache_header_v1));
+ if (!dsc_uuid.IsValid()) {
+ dsc_uuid = GetSharedCacheUUID(dsc_filespec, byte_order, addr_byte_size);
+ }
+ if (dsc_data_sp) {
+ DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
+
+ bool uuid_match = true;
+ if (dsc_uuid.IsValid() && process) {
+ if (process_shared_cache_uuid.IsValid() &&
+ dsc_uuid != process_shared_cache_uuid) {
+ // The on-disk dyld_shared_cache file is not the same as the one in
+ // this
+ // process' memory, don't use it.
+ uuid_match = false;
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ module_sp->ReportWarning("process shared cache does not match "
+ "on-disk dyld_shared_cache file, some "
+ "symbol names will be missing.");
+ }
+ }
- if (symbol_name == NULL)
+ offset = offsetof(struct lldb_copy_dyld_cache_header_v1, mappingOffset);
+
+ uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
+
+ // If the mappingOffset points to a location inside the header, we've
+ // opened an old dyld shared cache, and should not proceed further.
+ if (uuid_match &&
+ mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) {
+
+ DataBufferSP dsc_mapping_info_data_sp =
+ dsc_filespec.MemoryMapFileContentsIfLocal(
+ mappingOffset,
+ sizeof(struct lldb_copy_dyld_cache_mapping_info));
+ DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp,
+ byte_order, addr_byte_size);
+ offset = 0;
+
+ // The File addresses (from the in-memory Mach-O load commands) for
+ // the shared libraries
+ // in the shared library cache need to be adjusted by an offset to
+ // match up with the
+ // dylibOffset identifying field in the
+ // dyld_cache_local_symbol_entry's. This offset is
+ // recorded in mapping_offset_value.
+ const uint64_t mapping_offset_value =
+ dsc_mapping_info_data.GetU64(&offset);
+
+ offset = offsetof(struct lldb_copy_dyld_cache_header_v1,
+ localSymbolsOffset);
+ uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
+ uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
+
+ if (localSymbolsOffset && localSymbolsSize) {
+ // Map the local symbols
+ if (DataBufferSP dsc_local_symbols_data_sp =
+ dsc_filespec.MemoryMapFileContentsIfLocal(
+ localSymbolsOffset, localSymbolsSize)) {
+ DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp,
+ byte_order, addr_byte_size);
+
+ offset = 0;
+
+ typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
+ typedef std::map<uint32_t, ConstString> SymbolIndexToName;
+ UndefinedNameToDescMap undefined_name_to_desc;
+ SymbolIndexToName reexport_shlib_needs_fixup;
+
+ // Read the local_symbols_infos struct in one shot
+ struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
+ dsc_local_symbols_data.GetU32(&offset,
+ &local_symbols_info.nlistOffset, 6);
+
+ SectionSP text_section_sp(
+ section_list->FindSectionByName(GetSegmentNameTEXT()));
+
+ uint32_t header_file_offset =
+ (text_section_sp->GetFileAddress() - mapping_offset_value);
+
+ offset = local_symbols_info.entriesOffset;
+ for (uint32_t entry_index = 0;
+ entry_index < local_symbols_info.entriesCount;
+ entry_index++) {
+ struct lldb_copy_dyld_cache_local_symbols_entry
+ local_symbols_entry;
+ local_symbols_entry.dylibOffset =
+ dsc_local_symbols_data.GetU32(&offset);
+ local_symbols_entry.nlistStartIndex =
+ dsc_local_symbols_data.GetU32(&offset);
+ local_symbols_entry.nlistCount =
+ dsc_local_symbols_data.GetU32(&offset);
+
+ if (header_file_offset == local_symbols_entry.dylibOffset) {
+ unmapped_local_symbols_found = local_symbols_entry.nlistCount;
+
+ // The normal nlist code cannot correctly size the Symbols
+ // array, we need to allocate it here.
+ sym = symtab->Resize(
+ symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
+ unmapped_local_symbols_found - m_dysymtab.nlocalsym);
+ num_syms = symtab->GetNumSymbols();
+
+ nlist_data_offset =
+ local_symbols_info.nlistOffset +
+ (nlist_byte_size * local_symbols_entry.nlistStartIndex);
+ uint32_t string_table_offset =
+ local_symbols_info.stringsOffset;
+
+ for (uint32_t nlist_index = 0;
+ nlist_index < local_symbols_entry.nlistCount;
+ nlist_index++) {
+ /////////////////////////////
{
+ struct nlist_64 nlist;
+ if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(
+ nlist_data_offset, nlist_byte_size))
+ break;
+
+ nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(
+ &nlist_data_offset);
+ nlist.n_type = dsc_local_symbols_data.GetU8_unchecked(
+ &nlist_data_offset);
+ nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked(
+ &nlist_data_offset);
+ nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked(
+ &nlist_data_offset);
+ nlist.n_value =
+ dsc_local_symbols_data.GetAddress_unchecked(
+ &nlist_data_offset);
+
+ SymbolType type = eSymbolTypeInvalid;
+ const char *symbol_name = dsc_local_symbols_data.PeekCStr(
+ string_table_offset + nlist.n_strx);
+
+ if (symbol_name == NULL) {
// No symbol should be NULL, even the symbols with no
// string values should have an offset zero which points
// to an empty C-string
- Host::SystemLog (Host::eSystemLogError,
- "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
- nlist_idx,
- nlist.n_strx,
- module_sp->GetFileSpec().GetPath().c_str());
+ Host::SystemLog(
+ Host::eSystemLogError,
+ "error: DSC unmapped local symbol[%u] has invalid "
+ "string table offset 0x%x in %s, ignoring symbol\n",
+ entry_index, nlist.n_strx,
+ module_sp->GetFileSpec().GetPath().c_str());
continue;
- }
- if (symbol_name[0] == '\0')
+ }
+ if (symbol_name[0] == '\0')
symbol_name = NULL;
- }
- else
- {
- const addr_t str_addr = strtab_addr + nlist.n_strx;
- Error str_error;
- if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
- symbol_name = memory_symbol_name.c_str();
- }
- const char *symbol_name_non_abi_mangled = NULL;
-
- SectionSP symbol_section;
- lldb::addr_t symbol_byte_size = 0;
- bool add_nlist = true;
- bool is_gsym = false;
- bool is_debug = ((nlist.n_type & N_STAB) != 0);
- bool demangled_is_synthesized = false;
- bool set_value = true;
- assert (sym_idx < num_syms);
-
- sym[sym_idx].SetDebug (is_debug);
-
- if (is_debug)
- {
- switch (nlist.n_type)
- {
- case N_GSYM:
- // global symbol: name,,NO_SECT,type,0
- // Sometimes the N_GSYM value contains the address.
-
- // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
- // have the same address, but we want to ensure that we always find only the real symbol,
- // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
- // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
- // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
- // same address.
- is_gsym = true;
- sym[sym_idx].SetExternal(true);
-
- if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
- {
+
+ const char *symbol_name_non_abi_mangled = NULL;
+
+ SectionSP symbol_section;
+ uint32_t symbol_byte_size = 0;
+ bool add_nlist = true;
+ bool is_debug = ((nlist.n_type & N_STAB) != 0);
+ bool demangled_is_synthesized = false;
+ bool is_gsym = false;
+ bool set_value = true;
+
+ assert(sym_idx < num_syms);
+
+ sym[sym_idx].SetDebug(is_debug);
+
+ if (is_debug) {
+ switch (nlist.n_type) {
+ case N_GSYM:
+ // global symbol: name,,NO_SECT,type,0
+ // Sometimes the N_GSYM value contains the address.
+
+ // FIXME: In the .o files, we have a GSYM and a debug
+ // symbol for all the ObjC data. They
+ // have the same address, but we want to ensure that
+ // we always find only the real symbol,
+ // 'cause we don't currently correctly attribute the
+ // GSYM one to the ObjCClass/Ivar/MetaClass
+ // symbol type. This is a temporary hack to make sure
+ // the ObjectiveC symbols get treated
+ // correctly. To do this right, we should coalesce
+ // all the GSYM & global symbols that have the
+ // same address.
+
+ is_gsym = true;
+ sym[sym_idx].SetExternal(true);
+
+ if (symbol_name && symbol_name[0] == '_' &&
+ symbol_name[1] == 'O') {
llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
+ if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+
+ } else if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_metaclass)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name +
+ g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
+ } else if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_ivar)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
}
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- else
- {
+ } else {
if (nlist.n_value != 0)
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
type = eSymbolTypeData;
- }
- break;
+ }
+ break;
- case N_FNAME:
- // procedure name (f77 kludge): name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
+ case N_FNAME:
+ // procedure name (f77 kludge): name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- case N_FUN:
- // procedure: name,,n_sect,linenumber,address
- if (symbol_name)
- {
+ case N_FUN:
+ // procedure: name,,n_sect,linenumber,address
+ if (symbol_name) {
type = eSymbolTypeCode;
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-
- N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+
+ N_FUN_addr_to_sym_idx.insert(
+ std::make_pair(nlist.n_value, sym_idx));
+ // We use the current number of symbols in the
+ // symbol table in lieu of
+ // using nlist_idx in case we ever start trimming
+ // entries out
N_FUN_indexes.push_back(sym_idx);
- }
- else
- {
+ } else {
type = eSymbolTypeCompiler;
- if ( !N_FUN_indexes.empty() )
- {
- // Copy the size of the function into the original STAB entry so we don't have
- // to hunt for it later
- symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
- N_FUN_indexes.pop_back();
- // We don't really need the end function STAB as it contains the size which
- // we already placed with the original symbol, so don't add it if we want a
- // minimal symbol table
- add_nlist = false;
+ if (!N_FUN_indexes.empty()) {
+ // Copy the size of the function into the original
+ // STAB entry so we don't have
+ // to hunt for it later
+ symtab->SymbolAtIndex(N_FUN_indexes.back())
+ ->SetByteSize(nlist.n_value);
+ N_FUN_indexes.pop_back();
+ // We don't really need the end function STAB as
+ // it contains the size which
+ // we already placed with the original symbol, so
+ // don't add it if we want a
+ // minimal symbol table
+ add_nlist = false;
}
- }
- break;
-
- case N_STSYM:
- // static symbol: name,,n_sect,type,address
- N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- if (symbol_name && symbol_name[0])
- {
- type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData);
- }
- break;
-
- case N_LCSYM:
- // .lcomm symbol: name,,n_sect,type,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeCommonBlock;
- break;
-
- case N_BNSYM:
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
-
- case N_ENSYM:
- // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
-
-
- case N_OPT:
- // emitted with gcc2_compiled and in gcc source
- type = eSymbolTypeCompiler;
- break;
-
- case N_RSYM:
- // register sym: name,,NO_SECT,type,register
- type = eSymbolTypeVariable;
- break;
-
- case N_SLINE:
- // src line: 0,,n_sect,linenumber,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- case N_SSYM:
- // structure elt: name,,NO_SECT,type,struct_offset
- type = eSymbolTypeVariableType;
- break;
-
- case N_SO:
- // source file name
- type = eSymbolTypeSourceFile;
- if (symbol_name == NULL)
- {
+ }
+ break;
+
+ case N_STSYM:
+ // static symbol: name,,n_sect,type,address
+ N_STSYM_addr_to_sym_idx.insert(
+ std::make_pair(nlist.n_value, sym_idx));
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+ if (symbol_name && symbol_name[0]) {
+ type = ObjectFile::GetSymbolTypeFromName(
+ symbol_name + 1, eSymbolTypeData);
+ }
+ break;
+
+ case N_LCSYM:
+ // .lcomm symbol: name,,n_sect,type,address
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeCommonBlock;
+ break;
+
+ case N_BNSYM:
+ // We use the current number of symbols in the symbol
+ // table in lieu of
+ // using nlist_idx in case we ever start trimming
+ // entries out
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ break;
+
+ case N_ENSYM:
+ // Set the size of the N_BNSYM to the terminating
+ // index of this N_ENSYM
+ // so that we can always skip the entire symbol if we
+ // need to navigate
+ // more quickly at the source level when parsing STABS
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ break;
+
+ case N_OPT:
+ // emitted with gcc2_compiled and in gcc source
+ type = eSymbolTypeCompiler;
+ break;
+
+ case N_RSYM:
+ // register sym: name,,NO_SECT,type,register
+ type = eSymbolTypeVariable;
+ break;
+
+ case N_SLINE:
+ // src line: 0,,n_sect,linenumber,address
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeLineEntry;
+ break;
+
+ case N_SSYM:
+ // structure elt: name,,NO_SECT,type,struct_offset
+ type = eSymbolTypeVariableType;
+ break;
+
+ case N_SO:
+ // source file name
+ type = eSymbolTypeSourceFile;
+ if (symbol_name == NULL) {
add_nlist = false;
- if (N_SO_index != UINT32_MAX)
- {
- // Set the size of the N_SO to the terminating index of this N_SO
- // so that we can always skip the entire N_SO if we need to navigate
- // more quickly at the source level when parsing STABS
- symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
- symbol_ptr->SetByteSize(sym_idx);
- symbol_ptr->SetSizeIsSibling(true);
+ if (N_SO_index != UINT32_MAX) {
+ // Set the size of the N_SO to the terminating
+ // index of this N_SO
+ // so that we can always skip the entire N_SO if
+ // we need to navigate
+ // more quickly at the source level when parsing
+ // STABS
+ symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
+ symbol_ptr->SetByteSize(sym_idx);
+ symbol_ptr->SetSizeIsSibling(true);
}
N_NSYM_indexes.clear();
N_INCL_indexes.clear();
@@ -3936,2204 +3034,3061 @@ ObjectFileMachO::ParseSymtab ()
N_COMM_indexes.clear();
N_FUN_indexes.clear();
N_SO_index = UINT32_MAX;
- }
- else
- {
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- const bool N_SO_has_full_path = symbol_name[0] == '/';
- if (N_SO_has_full_path)
- {
- if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
- {
- // We have two consecutive N_SO entries where the first contains a directory
- // and the second contains a full path.
- sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- add_nlist = false;
- }
- else
- {
- // This is the first entry in a N_SO that contains a directory or
- // a full path to the source file
- N_SO_index = sym_idx;
- }
- }
- else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
- {
- // This is usually the second N_SO entry that contains just the filename,
- // so here we combine it with the first one if we are minimizing the symbol table
- const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString();
- if (so_path && so_path[0])
- {
- std::string full_so_path (so_path);
- const size_t double_slash_pos = full_so_path.find("//");
- if (double_slash_pos != std::string::npos)
- {
- // The linker has been generating bad N_SO entries with doubled up paths
- // in the format "%s%s" where the first string in the DW_AT_comp_dir,
- // and the second is the directory for the source file so you end up with
- // a path that looks like "/tmp/src//tmp/src/"
- FileSpec so_dir(so_path, false);
- if (!so_dir.Exists())
- {
- so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
- if (so_dir.Exists())
- {
- // Trim off the incorrect path
- full_so_path.erase(0, double_slash_pos + 1);
- }
- }
+ } else {
+ // We use the current number of symbols in the
+ // symbol table in lieu of
+ // using nlist_idx in case we ever start trimming
+ // entries out
+ const bool N_SO_has_full_path =
+ symbol_name[0] == '/';
+ if (N_SO_has_full_path) {
+ if ((N_SO_index == sym_idx - 1) &&
+ ((sym_idx - 1) < num_syms)) {
+ // We have two consecutive N_SO entries where
+ // the first contains a directory
+ // and the second contains a full path.
+ sym[sym_idx - 1].GetMangled().SetValue(
+ ConstString(symbol_name), false);
+ m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
+ add_nlist = false;
+ } else {
+ // This is the first entry in a N_SO that
+ // contains a directory or
+ // a full path to the source file
+ N_SO_index = sym_idx;
+ }
+ } else if ((N_SO_index == sym_idx - 1) &&
+ ((sym_idx - 1) < num_syms)) {
+ // This is usually the second N_SO entry that
+ // contains just the filename,
+ // so here we combine it with the first one if we
+ // are minimizing the symbol table
+ const char *so_path =
+ sym[sym_idx - 1]
+ .GetMangled()
+ .GetDemangledName(
+ lldb::eLanguageTypeUnknown)
+ .AsCString();
+ if (so_path && so_path[0]) {
+ std::string full_so_path(so_path);
+ const size_t double_slash_pos =
+ full_so_path.find("//");
+ if (double_slash_pos != std::string::npos) {
+ // The linker has been generating bad N_SO
+ // entries with doubled up paths
+ // in the format "%s%s" where the first string
+ // in the DW_AT_comp_dir,
+ // and the second is the directory for the
+ // source file so you end up with
+ // a path that looks like "/tmp/src//tmp/src/"
+ FileSpec so_dir(so_path, false);
+ if (!so_dir.Exists()) {
+ so_dir.SetFile(
+ &full_so_path[double_slash_pos + 1],
+ false);
+ if (so_dir.Exists()) {
+ // Trim off the incorrect path
+ full_so_path.erase(0,
+ double_slash_pos + 1);
}
- if (*full_so_path.rbegin() != '/')
- full_so_path += '/';
- full_so_path += symbol_name;
- sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
- add_nlist = false;
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
+ }
}
+ if (*full_so_path.rbegin() != '/')
+ full_so_path += '/';
+ full_so_path += symbol_name;
+ sym[sym_idx - 1].GetMangled().SetValue(
+ ConstString(full_so_path.c_str()), false);
+ add_nlist = false;
+ m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
+ }
+ } else {
+ // This could be a relative path to a N_SO
+ N_SO_index = sym_idx;
}
- else
- {
- // This could be a relative path to a N_SO
- N_SO_index = sym_idx;
- }
- }
- break;
-
- case N_OSO:
- // object file name: name,,0,0,st_mtime
- type = eSymbolTypeObjectFile;
- break;
-
- case N_LSYM:
- // local sym: name,,NO_SECT,type,offset
- type = eSymbolTypeLocal;
- break;
-
- //----------------------------------------------------------------------
- // INCL scopes
- //----------------------------------------------------------------------
- case N_BINCL:
- // include file beginning: name,,NO_SECT,0,sum
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- N_INCL_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_EINCL:
- // include file end: name,,NO_SECT,0,0
- // Set the size of the N_BINCL to the terminating index of this N_EINCL
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- if ( !N_INCL_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
+ }
+ break;
+
+ case N_OSO:
+ // object file name: name,,0,0,st_mtime
+ type = eSymbolTypeObjectFile;
+ break;
+
+ case N_LSYM:
+ // local sym: name,,NO_SECT,type,offset
+ type = eSymbolTypeLocal;
+ break;
+
+ //----------------------------------------------------------------------
+ // INCL scopes
+ //----------------------------------------------------------------------
+ case N_BINCL:
+ // include file beginning: name,,NO_SECT,0,sum
+ // We use the current number of symbols in the symbol
+ // table in lieu of
+ // using nlist_idx in case we ever start trimming
+ // entries out
+ N_INCL_indexes.push_back(sym_idx);
+ type = eSymbolTypeScopeBegin;
+ break;
+
+ case N_EINCL:
+ // include file end: name,,NO_SECT,0,0
+ // Set the size of the N_BINCL to the terminating
+ // index of this N_EINCL
+ // so that we can always skip the entire symbol if we
+ // need to navigate
+ // more quickly at the source level when parsing STABS
+ if (!N_INCL_indexes.empty()) {
+ symbol_ptr =
+ symtab->SymbolAtIndex(N_INCL_indexes.back());
symbol_ptr->SetByteSize(sym_idx + 1);
symbol_ptr->SetSizeIsSibling(true);
N_INCL_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_SOL:
- // #included file name: name,,n_sect,0,address
- type = eSymbolTypeHeaderFile;
-
- // We currently don't use the header files on darwin
- add_nlist = false;
- break;
-
- case N_PARAMS:
- // compiler parameters: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_VERSION:
- // compiler version: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_OLEVEL:
- // compiler -O level: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
-
- case N_PSYM:
- // parameter: name,,NO_SECT,type,offset
- type = eSymbolTypeVariable;
- break;
-
- case N_ENTRY:
- // alternate entry: name,,n_sect,linenumber,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
-
- //----------------------------------------------------------------------
- // Left and Right Braces
- //----------------------------------------------------------------------
- case N_LBRAC:
- // left bracket: 0,,NO_SECT,nesting level,address
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- N_BRAC_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
-
- case N_RBRAC:
- // right bracket: 0,,NO_SECT,nesting level,address
- // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- if ( !N_BRAC_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
+ }
+ type = eSymbolTypeScopeEnd;
+ break;
+
+ case N_SOL:
+ // #included file name: name,,n_sect,0,address
+ type = eSymbolTypeHeaderFile;
+
+ // We currently don't use the header files on darwin
+ add_nlist = false;
+ break;
+
+ case N_PARAMS:
+ // compiler parameters: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
+
+ case N_VERSION:
+ // compiler version: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
+
+ case N_OLEVEL:
+ // compiler -O level: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
+
+ case N_PSYM:
+ // parameter: name,,NO_SECT,type,offset
+ type = eSymbolTypeVariable;
+ break;
+
+ case N_ENTRY:
+ // alternate entry: name,,n_sect,linenumber,address
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeLineEntry;
+ break;
+
+ //----------------------------------------------------------------------
+ // Left and Right Braces
+ //----------------------------------------------------------------------
+ case N_LBRAC:
+ // left bracket: 0,,NO_SECT,nesting level,address
+ // We use the current number of symbols in the symbol
+ // table in lieu of
+ // using nlist_idx in case we ever start trimming
+ // entries out
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+ N_BRAC_indexes.push_back(sym_idx);
+ type = eSymbolTypeScopeBegin;
+ break;
+
+ case N_RBRAC:
+ // right bracket: 0,,NO_SECT,nesting level,address
+ // Set the size of the N_LBRAC to the terminating
+ // index of this N_RBRAC
+ // so that we can always skip the entire symbol if we
+ // need to navigate
+ // more quickly at the source level when parsing STABS
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+ if (!N_BRAC_indexes.empty()) {
+ symbol_ptr =
+ symtab->SymbolAtIndex(N_BRAC_indexes.back());
symbol_ptr->SetByteSize(sym_idx + 1);
symbol_ptr->SetSizeIsSibling(true);
N_BRAC_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_EXCL:
- // deleted include file: name,,NO_SECT,0,sum
- type = eSymbolTypeHeaderFile;
- break;
-
- //----------------------------------------------------------------------
- // COMM scopes
- //----------------------------------------------------------------------
- case N_BCOMM:
- // begin common: name,,NO_SECT,0,0
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- type = eSymbolTypeScopeBegin;
- N_COMM_indexes.push_back(sym_idx);
- break;
-
- case N_ECOML:
- // end common (local name): 0,,n_sect,0,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- LLVM_FALLTHROUGH;
-
- case N_ECOMM:
- // end common: name,,n_sect,0,0
- // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- if ( !N_COMM_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
+ }
+ type = eSymbolTypeScopeEnd;
+ break;
+
+ case N_EXCL:
+ // deleted include file: name,,NO_SECT,0,sum
+ type = eSymbolTypeHeaderFile;
+ break;
+
+ //----------------------------------------------------------------------
+ // COMM scopes
+ //----------------------------------------------------------------------
+ case N_BCOMM:
+ // begin common: name,,NO_SECT,0,0
+ // We use the current number of symbols in the symbol
+ // table in lieu of
+ // using nlist_idx in case we ever start trimming
+ // entries out
+ type = eSymbolTypeScopeBegin;
+ N_COMM_indexes.push_back(sym_idx);
+ break;
+
+ case N_ECOML:
+ // end common (local name): 0,,n_sect,0,address
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+ // Fall through
+
+ case N_ECOMM:
+ // end common: name,,n_sect,0,0
+ // Set the size of the N_BCOMM to the terminating
+ // index of this N_ECOMM/N_ECOML
+ // so that we can always skip the entire symbol if we
+ // need to navigate
+ // more quickly at the source level when parsing STABS
+ if (!N_COMM_indexes.empty()) {
+ symbol_ptr =
+ symtab->SymbolAtIndex(N_COMM_indexes.back());
symbol_ptr->SetByteSize(sym_idx + 1);
symbol_ptr->SetSizeIsSibling(true);
N_COMM_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
-
- case N_LENG:
- // second stab entry with length information
- type = eSymbolTypeAdditional;
- break;
+ }
+ type = eSymbolTypeScopeEnd;
+ break;
- default: break;
- }
- }
- else
- {
- //uint8_t n_pext = N_PEXT & nlist.n_type;
- uint8_t n_type = N_TYPE & nlist.n_type;
- sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
+ case N_LENG:
+ // second stab entry with length information
+ type = eSymbolTypeAdditional;
+ break;
- switch (n_type)
- {
- case N_INDR:
- {
- const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
- if (reexport_name_cstr && reexport_name_cstr[0])
- {
- type = eSymbolTypeReExported;
- ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
- sym[sym_idx].SetReExportedSymbolName(reexport_name);
- set_value = false;
- reexport_shlib_needs_fixup[sym_idx] = reexport_name;
- indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
- }
- else
- type = eSymbolTypeUndefined;
- }
- break;
-
- case N_UNDF:
- if (symbol_name && symbol_name[0])
- {
- ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
- undefined_name_to_desc[undefined_name] = nlist.n_desc;
+ default:
+ break;
}
- LLVM_FALLTHROUGH;
-
- case N_PBUD:
- type = eSymbolTypeUndefined;
- break;
-
- case N_ABS:
- type = eSymbolTypeAbsolute;
- break;
-
- case N_SECT:
- {
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-
- if (!symbol_section)
- {
- // TODO: warn about this?
- add_nlist = false;
+ } else {
+ // uint8_t n_pext = N_PEXT & nlist.n_type;
+ uint8_t n_type = N_TYPE & nlist.n_type;
+ sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
+
+ switch (n_type) {
+ case N_INDR: {
+ const char *reexport_name_cstr =
+ strtab_data.PeekCStr(nlist.n_value);
+ if (reexport_name_cstr && reexport_name_cstr[0]) {
+ type = eSymbolTypeReExported;
+ ConstString reexport_name(
+ reexport_name_cstr +
+ ((reexport_name_cstr[0] == '_') ? 1 : 0));
+ sym[sym_idx].SetReExportedSymbolName(reexport_name);
+ set_value = false;
+ reexport_shlib_needs_fixup[sym_idx] = reexport_name;
+ indirect_symbol_names.insert(
+ ConstString(symbol_name +
+ ((symbol_name[0] == '_') ? 1 : 0)));
+ } else
+ type = eSymbolTypeUndefined;
+ } break;
+
+ case N_UNDF:
+ if (symbol_name && symbol_name[0]) {
+ ConstString undefined_name(
+ symbol_name +
+ ((symbol_name[0] == '_') ? 1 : 0));
+ undefined_name_to_desc[undefined_name] =
+ nlist.n_desc;
+ }
+ // Fall through
+ case N_PBUD:
+ type = eSymbolTypeUndefined;
+ break;
+
+ case N_ABS:
+ type = eSymbolTypeAbsolute;
+ break;
+
+ case N_SECT: {
+ symbol_section = section_info.GetSection(
+ nlist.n_sect, nlist.n_value);
+
+ if (symbol_section == NULL) {
+ // TODO: warn about this?
+ add_nlist = false;
+ break;
+ }
+
+ if (TEXT_eh_frame_sectID == nlist.n_sect) {
+ type = eSymbolTypeException;
+ } else {
+ uint32_t section_type =
+ symbol_section->Get() & SECTION_TYPE;
+
+ switch (section_type) {
+ case S_CSTRING_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only literal C strings
+ case S_4BYTE_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only 4 byte literals
+ case S_8BYTE_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only 8 byte literals
+ case S_LITERAL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only pointers to literals
+ case S_NON_LAZY_SYMBOL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only non-lazy symbol
+ // pointers
+ case S_LAZY_SYMBOL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only lazy symbol pointers
+ case S_SYMBOL_STUBS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only symbol stubs, byte
+ // size of stub in the reserved2 field
+ case S_MOD_INIT_FUNC_POINTERS:
+ type = eSymbolTypeCode;
+ break; // section with only function pointers for
+ // initialization
+ case S_MOD_TERM_FUNC_POINTERS:
+ type = eSymbolTypeCode;
+ break; // section with only function pointers for
+ // termination
+ case S_INTERPOSING:
+ type = eSymbolTypeTrampoline;
+ break; // section with only pairs of function
+ // pointers for interposing
+ case S_16BYTE_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only 16 byte literals
+ case S_DTRACE_DOF:
+ type = eSymbolTypeInstrumentation;
+ break;
+ case S_LAZY_DYLIB_SYMBOL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break;
+ default:
+ switch (symbol_section->GetType()) {
+ case lldb::eSectionTypeCode:
+ type = eSymbolTypeCode;
+ break;
+ case eSectionTypeData:
+ case eSectionTypeDataCString: // Inlined C string
+ // data
+ case eSectionTypeDataCStringPointers: // Pointers
+ // to C
+ // string
+ // data
+ case eSectionTypeDataSymbolAddress: // Address of
+ // a symbol in
+ // the symbol
+ // table
+ case eSectionTypeData4:
+ case eSectionTypeData8:
+ case eSectionTypeData16:
+ type = eSymbolTypeData;
+ break;
+ default:
break;
+ }
+ break;
}
- if (TEXT_eh_frame_sectID == nlist.n_sect)
- {
- type = eSymbolTypeException;
- }
- else
- {
- uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
-
- switch (section_type)
- {
- case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
- case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
- case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
- case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
- case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
- case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
- case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
- case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
- case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
- case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
- case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
- case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
- case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
- default:
- switch (symbol_section->GetType())
- {
- case lldb::eSectionTypeCode:
- type = eSymbolTypeCode;
- break;
- case eSectionTypeData:
- case eSectionTypeDataCString: // Inlined C string data
- case eSectionTypeDataCStringPointers: // Pointers to C string data
- case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
- case eSectionTypeData4:
- case eSectionTypeData8:
- case eSectionTypeData16:
- type = eSymbolTypeData;
- break;
- default:
- break;
+ if (type == eSymbolTypeInvalid) {
+ const char *symbol_sect_name =
+ symbol_section->GetName().AsCString();
+ if (symbol_section->IsDescendant(
+ text_section_sp.get())) {
+ if (symbol_section->IsClear(
+ S_ATTR_PURE_INSTRUCTIONS |
+ S_ATTR_SELF_MODIFYING_CODE |
+ S_ATTR_SOME_INSTRUCTIONS))
+ type = eSymbolTypeData;
+ else
+ type = eSymbolTypeCode;
+ } else if (symbol_section->IsDescendant(
+ data_section_sp.get()) ||
+ symbol_section->IsDescendant(
+ data_dirty_section_sp.get()) ||
+ symbol_section->IsDescendant(
+ data_const_section_sp.get())) {
+ if (symbol_sect_name &&
+ ::strstr(symbol_sect_name, "__objc") ==
+ symbol_sect_name) {
+ type = eSymbolTypeRuntime;
+
+ if (symbol_name) {
+ llvm::StringRef symbol_name_ref(
+ symbol_name);
+ if (symbol_name_ref.startswith("_OBJC_")) {
+ static const llvm::StringRef
+ g_objc_v2_prefix_class(
+ "_OBJC_CLASS_$_");
+ static const llvm::StringRef
+ g_objc_v2_prefix_metaclass(
+ "_OBJC_METACLASS_$_");
+ static const llvm::StringRef
+ g_objc_v2_prefix_ivar(
+ "_OBJC_IVAR_$_");
+ if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_class)) {
+ symbol_name_non_abi_mangled =
+ symbol_name + 1;
+ symbol_name =
+ symbol_name +
+ g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+ } else if (
+ symbol_name_ref.startswith(
+ g_objc_v2_prefix_metaclass)) {
+ symbol_name_non_abi_mangled =
+ symbol_name + 1;
+ symbol_name =
+ symbol_name +
+ g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
+ } else if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_ivar)) {
+ symbol_name_non_abi_mangled =
+ symbol_name + 1;
+ symbol_name =
+ symbol_name +
+ g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
+ }
}
- break;
+ }
+ } else if (symbol_sect_name &&
+ ::strstr(symbol_sect_name,
+ "__gcc_except_tab") ==
+ symbol_sect_name) {
+ type = eSymbolTypeException;
+ } else {
+ type = eSymbolTypeData;
}
-
- if (type == eSymbolTypeInvalid)
- {
- const char *symbol_sect_name = symbol_section->GetName().AsCString();
- if (symbol_section->IsDescendant (text_section_sp.get()))
- {
- if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
- S_ATTR_SELF_MODIFYING_CODE |
- S_ATTR_SOME_INSTRUCTIONS))
- type = eSymbolTypeData;
- else
- type = eSymbolTypeCode;
- }
- else
- if (symbol_section->IsDescendant(data_section_sp.get()) ||
- symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
- symbol_section->IsDescendant(data_const_section_sp.get()))
- {
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
- {
- type = eSymbolTypeRuntime;
-
- if (symbol_name)
- {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.startswith("_OBJC_"))
- {
- static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
- if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- }
- }
- else
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
- {
- type = eSymbolTypeException;
- }
- else
- {
- type = eSymbolTypeData;
- }
- }
- else
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
- {
- type = eSymbolTypeTrampoline;
- }
- else
- if (symbol_section->IsDescendant(objc_section_sp.get()))
- {
- type = eSymbolTypeRuntime;
- if (symbol_name && symbol_name[0] == '.')
- {
- llvm::StringRef symbol_name_ref(symbol_name);
- static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
- if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name;
- symbol_name = symbol_name + g_objc_v1_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- }
- }
- }
+ } else if (symbol_sect_name &&
+ ::strstr(symbol_sect_name,
+ "__IMPORT") ==
+ symbol_sect_name) {
+ type = eSymbolTypeTrampoline;
+ } else if (symbol_section->IsDescendant(
+ objc_section_sp.get())) {
+ type = eSymbolTypeRuntime;
+ if (symbol_name && symbol_name[0] == '.') {
+ llvm::StringRef symbol_name_ref(symbol_name);
+ static const llvm::StringRef
+ g_objc_v1_prefix_class(
+ ".objc_class_name_");
+ if (symbol_name_ref.startswith(
+ g_objc_v1_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name;
+ symbol_name = symbol_name +
+ g_objc_v1_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+ }
}
+ }
}
+ }
+ } break;
}
- break;
- }
- }
-
- if (add_nlist)
- {
- uint64_t symbol_value = nlist.n_value;
-
- if (symbol_name_non_abi_mangled)
- {
- sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
- sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
- }
- else
- {
- bool symbol_name_is_mangled = false;
-
- if (symbol_name && symbol_name[0] == '_')
- {
+ }
+
+ if (add_nlist) {
+ uint64_t symbol_value = nlist.n_value;
+ if (symbol_name_non_abi_mangled) {
+ sym[sym_idx].GetMangled().SetMangledName(
+ ConstString(symbol_name_non_abi_mangled));
+ sym[sym_idx].GetMangled().SetDemangledName(
+ ConstString(symbol_name));
+ } else {
+ bool symbol_name_is_mangled = false;
+
+ if (symbol_name && symbol_name[0] == '_') {
symbol_name_is_mangled = symbol_name[1] == '_';
- symbol_name++; // Skip the leading underscore
- }
+ symbol_name++; // Skip the leading underscore
+ }
- if (symbol_name)
- {
+ if (symbol_name) {
ConstString const_symbol_name(symbol_name);
- sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
+ sym[sym_idx].GetMangled().SetValue(
+ const_symbol_name, symbol_name_is_mangled);
+ if (is_gsym && is_debug) {
+ const char *gsym_name =
+ sym[sym_idx]
+ .GetMangled()
+ .GetName(lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)
+ .GetCString();
+ if (gsym_name)
+ N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
+ }
+ }
}
- }
-
- if (is_gsym)
- {
- const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
- if (gsym_name)
- N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
- }
-
- if (symbol_section)
- {
- const addr_t section_file_addr = symbol_section->GetFileAddress();
- if (symbol_byte_size == 0 && function_starts_count > 0)
- {
+ if (symbol_section) {
+ const addr_t section_file_addr =
+ symbol_section->GetFileAddress();
+ if (symbol_byte_size == 0 &&
+ function_starts_count > 0) {
addr_t symbol_lookup_file_addr = nlist.n_value;
- // Do an exact address match for non-ARM addresses, else get the closest since
- // the symbol might be a thumb symbol which has an address with bit zero set
- FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
- if (is_arm && func_start_entry)
- {
- // Verify that the function start address is the symbol address (ARM)
- // or the symbol address + 1 (thumb)
- if (func_start_entry->addr != symbol_lookup_file_addr &&
- func_start_entry->addr != (symbol_lookup_file_addr + 1))
- {
- // Not the right entry, NULL it out...
- func_start_entry = NULL;
- }
+ // Do an exact address match for non-ARM addresses,
+ // else get the closest since
+ // the symbol might be a thumb symbol which has an
+ // address with bit zero set
+ FunctionStarts::Entry *func_start_entry =
+ function_starts.FindEntry(
+ symbol_lookup_file_addr, !is_arm);
+ if (is_arm && func_start_entry) {
+ // Verify that the function start address is the
+ // symbol address (ARM)
+ // or the symbol address + 1 (thumb)
+ if (func_start_entry->addr !=
+ symbol_lookup_file_addr &&
+ func_start_entry->addr !=
+ (symbol_lookup_file_addr + 1)) {
+ // Not the right entry, NULL it out...
+ func_start_entry = NULL;
+ }
}
- if (func_start_entry)
- {
- func_start_entry->data = true;
-
- addr_t symbol_file_addr = func_start_entry->addr;
+ if (func_start_entry) {
+ func_start_entry->data = true;
+
+ addr_t symbol_file_addr = func_start_entry->addr;
+ uint32_t symbol_flags = 0;
+ if (is_arm) {
+ if (symbol_file_addr & 1)
+ symbol_flags =
+ MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
+ symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
+ }
+
+ const FunctionStarts::Entry
+ *next_func_start_entry =
+ function_starts.FindNextEntry(
+ func_start_entry);
+ const addr_t section_end_file_addr =
+ section_file_addr +
+ symbol_section->GetByteSize();
+ if (next_func_start_entry) {
+ addr_t next_symbol_file_addr =
+ next_func_start_entry->addr;
+ // Be sure the clear the Thumb address bit when
+ // we calculate the size
+ // from the current and next address
if (is_arm)
- symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
-
- const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
- const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
- if (next_func_start_entry)
- {
- addr_t next_symbol_file_addr = next_func_start_entry->addr;
- // Be sure the clear the Thumb address bit when we calculate the size
- // from the current and next address
- if (is_arm)
- next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
- }
- else
- {
- symbol_byte_size = section_end_file_addr - symbol_file_addr;
- }
+ next_symbol_file_addr &=
+ THUMB_ADDRESS_BIT_MASK;
+ symbol_byte_size = std::min<lldb::addr_t>(
+ next_symbol_file_addr - symbol_file_addr,
+ section_end_file_addr - symbol_file_addr);
+ } else {
+ symbol_byte_size =
+ section_end_file_addr - symbol_file_addr;
+ }
}
+ }
+ symbol_value -= section_file_addr;
}
- symbol_value -= section_file_addr;
- }
- if (is_debug == false)
- {
- if (type == eSymbolTypeCode)
- {
- // See if we can find a N_FUN entry for any code symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the function symbol to avoid
+ if (is_debug == false) {
+ if (type == eSymbolTypeCode) {
+ // See if we can find a N_FUN entry for any code
+ // symbols.
+ // If we do find a match, and the name matches, then
+ // we
+ // can merge the two into just the function symbol
+ // to avoid
// duplicate entries in the symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
- range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
- if (range.first != range.second)
- {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
- {
- if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
- {
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put these flags
- // into the N_FUN flags to avoid duplicate symbols in the symbol table
- sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
- sym[pos->second].SetType (eSymbolTypeResolver);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
+ std::pair<ValueToSymbolIndexMap::const_iterator,
+ ValueToSymbolIndexMap::const_iterator>
+ range;
+ range = N_FUN_addr_to_sym_idx.equal_range(
+ nlist.n_value);
+ if (range.first != range.second) {
+ bool found_it = false;
+ for (ValueToSymbolIndexMap::const_iterator pos =
+ range.first;
+ pos != range.second; ++pos) {
+ if (sym[sym_idx].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled) ==
+ sym[pos->second].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)) {
+ m_nlist_idx_to_sym_idx[nlist_idx] =
+ pos->second;
+ // We just need the flags from the linker
+ // symbol, so put these flags
+ // into the N_FUN flags to avoid duplicate
+ // symbols in the symbol table
+ sym[pos->second].SetExternal(
+ sym[sym_idx].IsExternal());
+ sym[pos->second].SetFlags(nlist.n_type << 16 |
+ nlist.n_desc);
+ if (resolver_addresses.find(nlist.n_value) !=
+ resolver_addresses.end())
+ sym[pos->second].SetType(
+ eSymbolTypeResolver);
+ sym[sym_idx].Clear();
+ found_it = true;
+ break;
}
- if (found_it)
- continue;
- }
- else
- {
- if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
- type = eSymbolTypeResolver;
+ }
+ if (found_it)
+ continue;
+ } else {
+ if (resolver_addresses.find(nlist.n_value) !=
+ resolver_addresses.end())
+ type = eSymbolTypeResolver;
}
- }
- else if (type == eSymbolTypeData ||
- type == eSymbolTypeObjCClass ||
- type == eSymbolTypeObjCMetaClass ||
- type == eSymbolTypeObjCIVar )
- {
- // See if we can find a N_STSYM entry for any data symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the Static symbol to avoid
+ } else if (type == eSymbolTypeData ||
+ type == eSymbolTypeObjCClass ||
+ type == eSymbolTypeObjCMetaClass ||
+ type == eSymbolTypeObjCIVar) {
+ // See if we can find a N_STSYM entry for any data
+ // symbols.
+ // If we do find a match, and the name matches, then
+ // we
+ // can merge the two into just the Static symbol to
+ // avoid
// duplicate entries in the symbol table
- std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
- range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
- if (range.first != range.second)
- {
- bool found_it = false;
- for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
- {
- if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
- {
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put these flags
- // into the N_STSYM flags to avoid duplicate symbols in the symbol table
- sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
- sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- found_it = true;
- break;
- }
+ std::pair<ValueToSymbolIndexMap::const_iterator,
+ ValueToSymbolIndexMap::const_iterator>
+ range;
+ range = N_STSYM_addr_to_sym_idx.equal_range(
+ nlist.n_value);
+ if (range.first != range.second) {
+ bool found_it = false;
+ for (ValueToSymbolIndexMap::const_iterator pos =
+ range.first;
+ pos != range.second; ++pos) {
+ if (sym[sym_idx].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled) ==
+ sym[pos->second].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)) {
+ m_nlist_idx_to_sym_idx[nlist_idx] =
+ pos->second;
+ // We just need the flags from the linker
+ // symbol, so put these flags
+ // into the N_STSYM flags to avoid duplicate
+ // symbols in the symbol table
+ sym[pos->second].SetExternal(
+ sym[sym_idx].IsExternal());
+ sym[pos->second].SetFlags(nlist.n_type << 16 |
+ nlist.n_desc);
+ sym[sym_idx].Clear();
+ found_it = true;
+ break;
}
- if (found_it)
- continue;
- }
- else
- {
- // Combine N_GSYM stab entries with the non stab symbol
- const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
- if (gsym_name)
- {
- ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
- if (pos != N_GSYM_name_to_sym_idx.end())
- {
- const uint32_t GSYM_sym_idx = pos->second;
- m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
- // Copy the address, because often the N_GSYM address has an invalid address of zero
- // when the global is a common symbol
- sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
- sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
- // We just need the flags from the linker symbol, so put these flags
- // into the N_GSYM flags to avoid duplicate symbols in the symbol table
- sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- continue;
- }
+ }
+ if (found_it)
+ continue;
+ } else {
+ const char *gsym_name =
+ sym[sym_idx]
+ .GetMangled()
+ .GetName(lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)
+ .GetCString();
+ if (gsym_name) {
+ // Combine N_GSYM stab entries with the non stab
+ // symbol
+ ConstNameToSymbolIndexMap::const_iterator pos =
+ N_GSYM_name_to_sym_idx.find(gsym_name);
+ if (pos != N_GSYM_name_to_sym_idx.end()) {
+ const uint32_t GSYM_sym_idx = pos->second;
+ m_nlist_idx_to_sym_idx[nlist_idx] =
+ GSYM_sym_idx;
+ // Copy the address, because often the N_GSYM
+ // address has an invalid address of zero
+ // when the global is a common symbol
+ sym[GSYM_sym_idx].GetAddressRef().SetSection(
+ symbol_section);
+ sym[GSYM_sym_idx].GetAddressRef().SetOffset(
+ symbol_value);
+ // We just need the flags from the linker
+ // symbol, so put these flags
+ // into the N_GSYM flags to avoid duplicate
+ // symbols in the symbol table
+ sym[GSYM_sym_idx].SetFlags(
+ nlist.n_type << 16 | nlist.n_desc);
+ sym[sym_idx].Clear();
+ continue;
}
+ }
}
+ }
}
- }
-
- sym[sym_idx].SetID (nlist_idx);
- sym[sym_idx].SetType (type);
- if (set_value)
- {
- sym[sym_idx].GetAddressRef().SetSection (symbol_section);
- sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
- }
- sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- if (symbol_byte_size > 0)
- sym[sym_idx].SetByteSize(symbol_byte_size);
+ sym[sym_idx].SetID(nlist_idx);
+ sym[sym_idx].SetType(type);
+ if (set_value) {
+ sym[sym_idx].GetAddressRef().SetSection(
+ symbol_section);
+ sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
+ }
+ sym[sym_idx].SetFlags(nlist.n_type << 16 |
+ nlist.n_desc);
- if (demangled_is_synthesized)
- sym[sym_idx].SetDemangledNameIsSynthesized(true);
+ if (symbol_byte_size > 0)
+ sym[sym_idx].SetByteSize(symbol_byte_size);
- ++sym_idx;
- }
- else
- {
- sym[sym_idx].Clear();
+ if (demangled_is_synthesized)
+ sym[sym_idx].SetDemangledNameIsSynthesized(true);
+ ++sym_idx;
+ } else {
+ sym[sym_idx].Clear();
+ }
+ }
+ /////////////////////////////
+ }
+ break; // No more entries to consider
}
- }
+ }
- for (const auto &pos :reexport_shlib_needs_fixup)
- {
+ for (const auto &pos : reexport_shlib_needs_fixup) {
const auto undef_pos = undefined_name_to_desc.find(pos.second);
- if (undef_pos != undefined_name_to_desc.end())
- {
- const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
- if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
- sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
+ if (undef_pos != undefined_name_to_desc.end()) {
+ const uint8_t dylib_ordinal =
+ llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
+ if (dylib_ordinal > 0 &&
+ dylib_ordinal < dylib_files.GetSize())
+ sym[pos.first].SetReExportedSymbolSharedLibrary(
+ dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
}
+ }
}
+ }
}
+ }
+ }
- uint32_t synthetic_sym_id = symtab_load_command.nsyms;
+ // Must reset this in case it was mutated above!
+ nlist_data_offset = 0;
+#endif
- 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)
- ++num_synthetic_function_symbols;
+ if (nlist_data.GetByteSize() > 0) {
+
+ // If the sym array was not created while parsing the DSC unmapped
+ // symbols, create it now.
+ if (sym == NULL) {
+ sym = symtab->Resize(symtab_load_command.nsyms +
+ m_dysymtab.nindirectsyms);
+ num_syms = symtab->GetNumSymbols();
+ }
+
+ if (unmapped_local_symbols_found) {
+ assert(m_dysymtab.ilocalsym == 0);
+ nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
+ nlist_idx = m_dysymtab.nlocalsym;
+ } else {
+ nlist_idx = 0;
+ }
+
+ typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
+ typedef std::map<uint32_t, ConstString> SymbolIndexToName;
+ UndefinedNameToDescMap undefined_name_to_desc;
+ SymbolIndexToName reexport_shlib_needs_fixup;
+ for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
+ struct nlist_64 nlist;
+ if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset,
+ nlist_byte_size))
+ break;
+
+ nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
+ nlist.n_type = nlist_data.GetU8_unchecked(&nlist_data_offset);
+ nlist.n_sect = nlist_data.GetU8_unchecked(&nlist_data_offset);
+ nlist.n_desc = nlist_data.GetU16_unchecked(&nlist_data_offset);
+ nlist.n_value = nlist_data.GetAddress_unchecked(&nlist_data_offset);
+
+ SymbolType type = eSymbolTypeInvalid;
+ const char *symbol_name = NULL;
+
+ if (have_strtab_data) {
+ symbol_name = strtab_data.PeekCStr(nlist.n_strx);
+
+ if (symbol_name == NULL) {
+ // No symbol should be NULL, even the symbols with no
+ // string values should have an offset zero which points
+ // to an empty C-string
+ Host::SystemLog(Host::eSystemLogError,
+ "error: symbol[%u] has invalid string table offset "
+ "0x%x in %s, ignoring symbol\n",
+ nlist_idx, nlist.n_strx,
+ module_sp->GetFileSpec().GetPath().c_str());
+ continue;
+ }
+ if (symbol_name[0] == '\0')
+ symbol_name = NULL;
+ } else {
+ const addr_t str_addr = strtab_addr + nlist.n_strx;
+ Error str_error;
+ if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
+ str_error))
+ symbol_name = memory_symbol_name.c_str();
+ }
+ const char *symbol_name_non_abi_mangled = NULL;
+
+ SectionSP symbol_section;
+ lldb::addr_t symbol_byte_size = 0;
+ bool add_nlist = true;
+ bool is_gsym = false;
+ bool is_debug = ((nlist.n_type & N_STAB) != 0);
+ bool demangled_is_synthesized = false;
+ bool set_value = true;
+ assert(sym_idx < num_syms);
+
+ sym[sym_idx].SetDebug(is_debug);
+
+ if (is_debug) {
+ switch (nlist.n_type) {
+ case N_GSYM:
+ // global symbol: name,,NO_SECT,type,0
+ // Sometimes the N_GSYM value contains the address.
+
+ // FIXME: In the .o files, we have a GSYM and a debug symbol for all
+ // the ObjC data. They
+ // have the same address, but we want to ensure that we always find
+ // only the real symbol,
+ // 'cause we don't currently correctly attribute the GSYM one to the
+ // ObjCClass/Ivar/MetaClass
+ // symbol type. This is a temporary hack to make sure the
+ // ObjectiveC symbols get treated
+ // correctly. To do this right, we should coalesce all the GSYM &
+ // global symbols that have the
+ // same address.
+ is_gsym = true;
+ sym[sym_idx].SetExternal(true);
+
+ if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O') {
+ llvm::StringRef symbol_name_ref(symbol_name);
+ if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+
+ } else if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_metaclass)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
+ } else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
+ }
+ } else {
+ if (nlist.n_value != 0)
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeData;
}
+ break;
- if (num_synthetic_function_symbols > 0)
- {
- if (num_syms < sym_idx + num_synthetic_function_symbols)
- {
- num_syms = sym_idx + num_synthetic_function_symbols;
- sym = symtab->Resize (num_syms);
- }
- for (i=0; i<function_starts_count; ++i)
- {
- const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
- if (func_start_entry->data == false)
- {
- addr_t symbol_file_addr = func_start_entry->addr;
- uint32_t symbol_flags = 0;
- if (is_arm)
- {
- if (symbol_file_addr & 1)
- symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
- symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- }
- Address symbol_addr;
- if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
- {
- SectionSP symbol_section (symbol_addr.GetSection());
- uint32_t symbol_byte_size = 0;
- if (symbol_section)
- {
- const addr_t section_file_addr = symbol_section->GetFileAddress();
- const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
- const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
- if (next_func_start_entry)
- {
- addr_t next_symbol_file_addr = next_func_start_entry->addr;
- if (is_arm)
- next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
- }
- else
- {
- symbol_byte_size = section_end_file_addr - symbol_file_addr;
- }
- sym[sym_idx].SetID (synthetic_sym_id++);
- sym[sym_idx].GetMangled().SetDemangledName(GetNextSyntheticSymbolName());
- sym[sym_idx].SetType (eSymbolTypeCode);
- sym[sym_idx].SetIsSynthetic (true);
- sym[sym_idx].GetAddressRef() = symbol_addr;
- if (symbol_flags)
- sym[sym_idx].SetFlags (symbol_flags);
- if (symbol_byte_size)
- sym[sym_idx].SetByteSize (symbol_byte_size);
- ++sym_idx;
- }
- }
- }
- }
+ case N_FNAME:
+ // procedure name (f77 kludge): name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
+
+ case N_FUN:
+ // procedure: name,,n_sect,linenumber,address
+ if (symbol_name) {
+ type = eSymbolTypeCode;
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+
+ N_FUN_addr_to_sym_idx.insert(
+ std::make_pair(nlist.n_value, sym_idx));
+ // We use the current number of symbols in the symbol table in
+ // lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ N_FUN_indexes.push_back(sym_idx);
+ } else {
+ type = eSymbolTypeCompiler;
+
+ if (!N_FUN_indexes.empty()) {
+ // Copy the size of the function into the original STAB entry so
+ // we don't have
+ // to hunt for it later
+ symtab->SymbolAtIndex(N_FUN_indexes.back())
+ ->SetByteSize(nlist.n_value);
+ N_FUN_indexes.pop_back();
+ // We don't really need the end function STAB as it contains the
+ // size which
+ // we already placed with the original symbol, so don't add it
+ // if we want a
+ // minimal symbol table
+ add_nlist = false;
+ }
}
- }
+ break;
- // Trim our symbols down to just what we ended up with after
- // removing any symbols.
- if (sym_idx < num_syms)
- {
- num_syms = sym_idx;
- sym = symtab->Resize (num_syms);
- }
+ case N_STSYM:
+ // static symbol: name,,n_sect,type,address
+ N_STSYM_addr_to_sym_idx.insert(
+ std::make_pair(nlist.n_value, sym_idx));
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ if (symbol_name && symbol_name[0]) {
+ type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
+ eSymbolTypeData);
+ }
+ break;
- // Now synthesize indirect symbols
- if (m_dysymtab.nindirectsyms != 0)
- {
- if (indirect_symbol_index_data.GetByteSize())
- {
- NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
+ case N_LCSYM:
+ // .lcomm symbol: name,,n_sect,type,address
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeCommonBlock;
+ break;
- for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
- {
- if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
- {
- uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
- if (symbol_stub_byte_size == 0)
- continue;
-
- const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
-
- if (num_symbol_stubs == 0)
- continue;
-
- const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
- for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
- {
- const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
- const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
- lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
- if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
- {
- const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
- if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
- continue;
-
- NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
- Symbol *stub_symbol = NULL;
- if (index_pos != end_index_pos)
- {
- // We have a remapping from the original nlist index to
- // a current symbol index, so just look this up by index
- stub_symbol = symtab->SymbolAtIndex (index_pos->second);
- }
- else
- {
- // We need to lookup a symbol using the original nlist
- // symbol index since this index is coming from the
- // S_SYMBOL_STUBS
- stub_symbol = symtab->FindSymbolByID (stub_sym_id);
- }
+ case N_BNSYM:
+ // We use the current number of symbols in the symbol table in lieu
+ // of
+ // using nlist_idx in case we ever start trimming entries out
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ break;
- if (stub_symbol)
- {
- Address so_addr(symbol_stub_addr, section_list);
-
- if (stub_symbol->GetType() == eSymbolTypeUndefined)
- {
- // Change the external symbol into a trampoline that makes sense
- // These symbols were N_UNDF N_EXT, and are useless to us, so we
- // can re-use them so we don't have to make up a synthetic symbol
- // for no good reason.
- if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
- stub_symbol->SetType (eSymbolTypeTrampoline);
- else
- stub_symbol->SetType (eSymbolTypeResolver);
- stub_symbol->SetExternal (false);
- stub_symbol->GetAddressRef() = so_addr;
- stub_symbol->SetByteSize (symbol_stub_byte_size);
- }
- else
- {
- // Make a synthetic symbol to describe the trampoline stub
- Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
- if (sym_idx >= num_syms)
- {
- sym = symtab->Resize (++num_syms);
- stub_symbol = NULL; // this pointer no longer valid
- }
- sym[sym_idx].SetID (synthetic_sym_id++);
- sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
- if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
- sym[sym_idx].SetType (eSymbolTypeTrampoline);
- else
- sym[sym_idx].SetType (eSymbolTypeResolver);
- sym[sym_idx].SetIsSynthetic (true);
- sym[sym_idx].GetAddressRef() = so_addr;
- sym[sym_idx].SetByteSize (symbol_stub_byte_size);
- ++sym_idx;
- }
- }
- else
- {
- if (log)
- log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
- }
- }
- }
- }
- }
- }
- }
+ case N_ENSYM:
+ // Set the size of the N_BNSYM to the terminating index of this
+ // N_ENSYM
+ // so that we can always skip the entire symbol if we need to
+ // navigate
+ // more quickly at the source level when parsing STABS
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ break;
- if (!trie_entries.empty())
- {
- for (const auto &e : trie_entries)
- {
- if (e.entry.import_name)
- {
- // Only add indirect symbols from the Trie entries if we
- // didn't have a N_INDR nlist entry for this already
- if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end())
- {
- // Make a synthetic symbol to describe re-exported symbol.
- if (sym_idx >= num_syms)
- sym = symtab->Resize (++num_syms);
- sym[sym_idx].SetID (synthetic_sym_id++);
- sym[sym_idx].GetMangled() = Mangled(e.entry.name);
- sym[sym_idx].SetType (eSymbolTypeReExported);
- sym[sym_idx].SetIsSynthetic (true);
- sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
- if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
- {
- sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
- }
- ++sym_idx;
+ case N_OPT:
+ // emitted with gcc2_compiled and in gcc source
+ type = eSymbolTypeCompiler;
+ break;
+
+ case N_RSYM:
+ // register sym: name,,NO_SECT,type,register
+ type = eSymbolTypeVariable;
+ break;
+
+ case N_SLINE:
+ // src line: 0,,n_sect,linenumber,address
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeLineEntry;
+ break;
+
+ case N_SSYM:
+ // structure elt: name,,NO_SECT,type,struct_offset
+ type = eSymbolTypeVariableType;
+ break;
+
+ case N_SO:
+ // source file name
+ type = eSymbolTypeSourceFile;
+ if (symbol_name == NULL) {
+ add_nlist = false;
+ if (N_SO_index != UINT32_MAX) {
+ // Set the size of the N_SO to the terminating index of this
+ // N_SO
+ // so that we can always skip the entire N_SO if we need to
+ // navigate
+ // more quickly at the source level when parsing STABS
+ symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
+ symbol_ptr->SetByteSize(sym_idx);
+ symbol_ptr->SetSizeIsSibling(true);
+ }
+ N_NSYM_indexes.clear();
+ N_INCL_indexes.clear();
+ N_BRAC_indexes.clear();
+ N_COMM_indexes.clear();
+ N_FUN_indexes.clear();
+ N_SO_index = UINT32_MAX;
+ } else {
+ // We use the current number of symbols in the symbol table in
+ // lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ const bool N_SO_has_full_path = symbol_name[0] == '/';
+ if (N_SO_has_full_path) {
+ if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
+ // We have two consecutive N_SO entries where the first
+ // contains a directory
+ // and the second contains a full path.
+ sym[sym_idx - 1].GetMangled().SetValue(
+ ConstString(symbol_name), false);
+ m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
+ add_nlist = false;
+ } else {
+ // This is the first entry in a N_SO that contains a directory
+ // or
+ // a full path to the source file
+ N_SO_index = sym_idx;
+ }
+ } else if ((N_SO_index == sym_idx - 1) &&
+ ((sym_idx - 1) < num_syms)) {
+ // This is usually the second N_SO entry that contains just the
+ // filename,
+ // so here we combine it with the first one if we are minimizing
+ // the symbol table
+ const char *so_path =
+ sym[sym_idx - 1]
+ .GetMangled()
+ .GetDemangledName(lldb::eLanguageTypeUnknown)
+ .AsCString();
+ if (so_path && so_path[0]) {
+ std::string full_so_path(so_path);
+ const size_t double_slash_pos = full_so_path.find("//");
+ if (double_slash_pos != std::string::npos) {
+ // The linker has been generating bad N_SO entries with
+ // doubled up paths
+ // in the format "%s%s" where the first string in the
+ // DW_AT_comp_dir,
+ // and the second is the directory for the source file so
+ // you end up with
+ // a path that looks like "/tmp/src//tmp/src/"
+ FileSpec so_dir(so_path, false);
+ if (!so_dir.Exists()) {
+ so_dir.SetFile(&full_so_path[double_slash_pos + 1],
+ false);
+ if (so_dir.Exists()) {
+ // Trim off the incorrect path
+ full_so_path.erase(0, double_slash_pos + 1);
+ }
}
+ }
+ if (*full_so_path.rbegin() != '/')
+ full_so_path += '/';
+ full_so_path += symbol_name;
+ sym[sym_idx - 1].GetMangled().SetValue(
+ ConstString(full_so_path.c_str()), false);
+ add_nlist = false;
+ m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
}
+ } else {
+ // This could be a relative path to a N_SO
+ N_SO_index = sym_idx;
+ }
}
- }
-
-// StreamFile s(stdout, false);
-// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
-// symtab->Dump(&s, NULL, eSortOrderNone);
- // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
- symtab->CalculateSymbolSizes();
+ break;
-// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
-// symtab->Dump(&s, NULL, eSortOrderNone);
+ case N_OSO:
+ // object file name: name,,0,0,st_mtime
+ type = eSymbolTypeObjectFile;
+ break;
- return symtab->GetNumSymbols();
- }
- return 0;
-}
+ case N_LSYM:
+ // local sym: name,,NO_SECT,type,offset
+ type = eSymbolTypeLocal;
+ break;
-void
-ObjectFileMachO::Dump (Stream *s)
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- s->Printf("%p: ", static_cast<void*>(this));
- s->Indent();
- if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
- s->PutCString("ObjectFileMachO64");
- else
- s->PutCString("ObjectFileMachO32");
+ //----------------------------------------------------------------------
+ // INCL scopes
+ //----------------------------------------------------------------------
+ case N_BINCL:
+ // include file beginning: name,,NO_SECT,0,sum
+ // We use the current number of symbols in the symbol table in lieu
+ // of
+ // using nlist_idx in case we ever start trimming entries out
+ N_INCL_indexes.push_back(sym_idx);
+ type = eSymbolTypeScopeBegin;
+ break;
- ArchSpec header_arch;
- GetArchitecture(header_arch);
+ case N_EINCL:
+ // include file end: name,,NO_SECT,0,0
+ // Set the size of the N_BINCL to the terminating index of this
+ // N_EINCL
+ // so that we can always skip the entire symbol if we need to
+ // navigate
+ // more quickly at the source level when parsing STABS
+ if (!N_INCL_indexes.empty()) {
+ symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
+ symbol_ptr->SetByteSize(sym_idx + 1);
+ symbol_ptr->SetSizeIsSibling(true);
+ N_INCL_indexes.pop_back();
+ }
+ type = eSymbolTypeScopeEnd;
+ break;
- *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
+ case N_SOL:
+ // #included file name: name,,n_sect,0,address
+ type = eSymbolTypeHeaderFile;
- SectionList *sections = GetSectionList();
- if (sections)
- sections->Dump(s, NULL, true, UINT32_MAX);
+ // We currently don't use the header files on darwin
+ add_nlist = false;
+ break;
- if (m_symtab_ap.get())
- m_symtab_ap->Dump(s, NULL, eSortOrderNone);
- }
-}
+ case N_PARAMS:
+ // compiler parameters: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
-bool
-ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- lldb::offset_t lc_offset,
- lldb_private::UUID& uuid)
-{
- uint32_t i;
- struct uuid_command load_cmd;
+ case N_VERSION:
+ // compiler version: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- lldb::offset_t offset = lc_offset;
- for (i=0; i<header.ncmds; ++i)
- {
- const lldb::offset_t cmd_offset = offset;
- if (data.GetU32(&offset, &load_cmd, 2) == NULL)
+ case N_OLEVEL:
+ // compiler -O level: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
break;
-
- if (load_cmd.cmd == LC_UUID)
- {
- const uint8_t *uuid_bytes = data.PeekData(offset, 16);
-
- if (uuid_bytes)
- {
- // OpenCL on Mac OS X uses the same UUID for each of its object files.
- // We pretend these object files have no UUID to prevent crashing.
-
- const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
- 0x3b, 0xa8,
- 0x4b, 0x16,
- 0xb6, 0xa4,
- 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
-
- if (!memcmp(uuid_bytes, opencl_uuid, 16))
- return false;
-
- uuid.SetBytes (uuid_bytes);
- return true;
- }
- return false;
- }
- offset = cmd_offset + load_cmd.cmdsize;
- }
- return false;
-}
-bool
-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())
- {
- llvm::Triple &triple = arch.GetTriple();
-
- // Set OS to an unspecified unknown or a "*" so it can match any OS
- triple.setOS(llvm::Triple::UnknownOS);
- triple.setOSName(llvm::StringRef());
-
- if (header.filetype == MH_PRELOAD)
- {
- if (header.cputype == CPU_TYPE_ARM)
- {
- // If this is a 32-bit arm binary, and it's a standalone binary,
- // force the Vendor to Apple so we don't accidentally pick up
- // the generic armv7 ABI at runtime. Apple's armv7 ABI always uses
- // r7 for the frame pointer register; most other armv7 ABIs use a
- // combination of r7 and r11.
- triple.setVendor(llvm::Triple::Apple);
- }
- else
- {
- // Set vendor to an unspecified unknown or a "*" so it can match any vendor
- // This is required for correct behavior of EFI debugging on x86_64
- triple.setVendor(llvm::Triple::UnknownVendor);
- triple.setVendorName(llvm::StringRef());
+ case N_PSYM:
+ // parameter: name,,NO_SECT,type,offset
+ type = eSymbolTypeVariable;
+ break;
+
+ case N_ENTRY:
+ // alternate entry: name,,n_sect,linenumber,address
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeLineEntry;
+ break;
+
+ //----------------------------------------------------------------------
+ // Left and Right Braces
+ //----------------------------------------------------------------------
+ case N_LBRAC:
+ // left bracket: 0,,NO_SECT,nesting level,address
+ // We use the current number of symbols in the symbol table in lieu
+ // of
+ // using nlist_idx in case we ever start trimming entries out
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ N_BRAC_indexes.push_back(sym_idx);
+ type = eSymbolTypeScopeBegin;
+ break;
+
+ case N_RBRAC:
+ // right bracket: 0,,NO_SECT,nesting level,address
+ // Set the size of the N_LBRAC to the terminating index of this
+ // N_RBRAC
+ // so that we can always skip the entire symbol if we need to
+ // navigate
+ // more quickly at the source level when parsing STABS
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ if (!N_BRAC_indexes.empty()) {
+ symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
+ symbol_ptr->SetByteSize(sym_idx + 1);
+ symbol_ptr->SetSizeIsSibling(true);
+ N_BRAC_indexes.pop_back();
}
- return true;
- }
- else
- {
- struct load_command load_cmd;
+ type = eSymbolTypeScopeEnd;
+ break;
- 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;
-
- switch (load_cmd.cmd)
- {
- case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
- triple.setOS (llvm::Triple::IOS);
- return true;
-
- case llvm::MachO::LC_VERSION_MIN_MACOSX:
- triple.setOS (llvm::Triple::MacOSX);
- return true;
-
- case llvm::MachO::LC_VERSION_MIN_TVOS:
- triple.setOS (llvm::Triple::TvOS);
- return true;
-
- case llvm::MachO::LC_VERSION_MIN_WATCHOS:
- triple.setOS (llvm::Triple::WatchOS);
- return true;
+ case N_EXCL:
+ // deleted include file: name,,NO_SECT,0,sum
+ type = eSymbolTypeHeaderFile;
+ break;
- default:
- break;
- }
+ //----------------------------------------------------------------------
+ // COMM scopes
+ //----------------------------------------------------------------------
+ case N_BCOMM:
+ // begin common: name,,NO_SECT,0,0
+ // We use the current number of symbols in the symbol table in lieu
+ // of
+ // using nlist_idx in case we ever start trimming entries out
+ type = eSymbolTypeScopeBegin;
+ N_COMM_indexes.push_back(sym_idx);
+ break;
- offset = cmd_offset + load_cmd.cmdsize;
+ case N_ECOML:
+ // end common (local name): 0,,n_sect,0,address
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+ LLVM_FALLTHROUGH;
+
+ case N_ECOMM:
+ // end common: name,,n_sect,0,0
+ // Set the size of the N_BCOMM to the terminating index of this
+ // N_ECOMM/N_ECOML
+ // so that we can always skip the entire symbol if we need to
+ // navigate
+ // more quickly at the source level when parsing STABS
+ if (!N_COMM_indexes.empty()) {
+ symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
+ symbol_ptr->SetByteSize(sym_idx + 1);
+ symbol_ptr->SetSizeIsSibling(true);
+ N_COMM_indexes.pop_back();
}
-
- 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 unknown
- triple.setVendor(llvm::Triple::UnknownVendor);
- triple.setVendorName(llvm::StringRef());
+ type = eSymbolTypeScopeEnd;
+ break;
+
+ case N_LENG:
+ // second stab entry with length information
+ type = eSymbolTypeAdditional;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ // uint8_t n_pext = N_PEXT & nlist.n_type;
+ uint8_t n_type = N_TYPE & nlist.n_type;
+ sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
+
+ switch (n_type) {
+ case N_INDR: {
+ const char *reexport_name_cstr =
+ strtab_data.PeekCStr(nlist.n_value);
+ if (reexport_name_cstr && reexport_name_cstr[0]) {
+ type = eSymbolTypeReExported;
+ ConstString reexport_name(
+ reexport_name_cstr +
+ ((reexport_name_cstr[0] == '_') ? 1 : 0));
+ sym[sym_idx].SetReExportedSymbolName(reexport_name);
+ set_value = false;
+ reexport_shlib_needs_fixup[sym_idx] = reexport_name;
+ indirect_symbol_names.insert(
+ ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
+ } else
+ type = eSymbolTypeUndefined;
+ } break;
+
+ case N_UNDF:
+ if (symbol_name && symbol_name[0]) {
+ ConstString undefined_name(symbol_name +
+ ((symbol_name[0] == '_') ? 1 : 0));
+ undefined_name_to_desc[undefined_name] = nlist.n_desc;
}
- }
- }
- return arch.IsValid();
-}
+ LLVM_FALLTHROUGH;
-bool
-ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- return GetUUID (m_header, m_data, offset, *uuid);
- }
- return false;
-}
+ case N_PBUD:
+ type = eSymbolTypeUndefined;
+ break;
-uint32_t
-ObjectFileMachO::GetDependentModules (FileSpecList& files)
-{
- uint32_t count = 0;
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- struct load_command load_cmd;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- std::vector<std::string> rpath_paths;
- std::vector<std::string> rpath_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;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
+ case N_ABS:
+ type = eSymbolTypeAbsolute;
+ break;
- switch (load_cmd.cmd)
- {
- case LC_RPATH:
- case LC_LOAD_DYLIB:
- case LC_LOAD_WEAK_DYLIB:
- case LC_REEXPORT_DYLIB:
- case LC_LOAD_DYLINKER:
- case LC_LOADFVMLIB:
- case LC_LOAD_UPWARD_DYLIB:
- {
- uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
- const char *path = m_data.PeekCStr(name_offset);
- if (path)
- {
- if (load_cmd.cmd == LC_RPATH)
- rpath_paths.push_back(path);
- else
- {
- if (path[0] == '@')
- {
- if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
- rpath_relative_paths.push_back(path + strlen("@rpath"));
- }
- else
- {
- FileSpec file_spec(path, resolve_path);
- if (files.AppendIfUnique(file_spec))
- count++;
- }
+ case N_SECT: {
+ symbol_section =
+ section_info.GetSection(nlist.n_sect, nlist.n_value);
+
+ if (!symbol_section) {
+ // TODO: warn about this?
+ add_nlist = false;
+ break;
+ }
+
+ if (TEXT_eh_frame_sectID == nlist.n_sect) {
+ type = eSymbolTypeException;
+ } else {
+ uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
+
+ switch (section_type) {
+ case S_CSTRING_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only literal C strings
+ case S_4BYTE_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only 4 byte literals
+ case S_8BYTE_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only 8 byte literals
+ case S_LITERAL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only pointers to literals
+ case S_NON_LAZY_SYMBOL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only non-lazy symbol pointers
+ case S_LAZY_SYMBOL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only lazy symbol pointers
+ case S_SYMBOL_STUBS:
+ type = eSymbolTypeTrampoline;
+ break; // section with only symbol stubs, byte size of stub in
+ // the reserved2 field
+ case S_MOD_INIT_FUNC_POINTERS:
+ type = eSymbolTypeCode;
+ break; // section with only function pointers for initialization
+ case S_MOD_TERM_FUNC_POINTERS:
+ type = eSymbolTypeCode;
+ break; // section with only function pointers for termination
+ case S_INTERPOSING:
+ type = eSymbolTypeTrampoline;
+ break; // section with only pairs of function pointers for
+ // interposing
+ case S_16BYTE_LITERALS:
+ type = eSymbolTypeData;
+ break; // section with only 16 byte literals
+ case S_DTRACE_DOF:
+ type = eSymbolTypeInstrumentation;
+ break;
+ case S_LAZY_DYLIB_SYMBOL_POINTERS:
+ type = eSymbolTypeTrampoline;
+ break;
+ default:
+ switch (symbol_section->GetType()) {
+ case lldb::eSectionTypeCode:
+ type = eSymbolTypeCode;
+ break;
+ case eSectionTypeData:
+ case eSectionTypeDataCString: // Inlined C string data
+ case eSectionTypeDataCStringPointers: // Pointers to C string
+ // data
+ case eSectionTypeDataSymbolAddress: // Address of a symbol in
+ // the symbol table
+ case eSectionTypeData4:
+ case eSectionTypeData8:
+ case eSectionTypeData16:
+ type = eSymbolTypeData;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ if (type == eSymbolTypeInvalid) {
+ const char *symbol_sect_name =
+ symbol_section->GetName().AsCString();
+ if (symbol_section->IsDescendant(text_section_sp.get())) {
+ if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
+ S_ATTR_SELF_MODIFYING_CODE |
+ S_ATTR_SOME_INSTRUCTIONS))
+ type = eSymbolTypeData;
+ else
+ type = eSymbolTypeCode;
+ } else if (symbol_section->IsDescendant(
+ data_section_sp.get()) ||
+ symbol_section->IsDescendant(
+ data_dirty_section_sp.get()) ||
+ symbol_section->IsDescendant(
+ data_const_section_sp.get())) {
+ if (symbol_sect_name &&
+ ::strstr(symbol_sect_name, "__objc") ==
+ symbol_sect_name) {
+ type = eSymbolTypeRuntime;
+
+ if (symbol_name) {
+ llvm::StringRef symbol_name_ref(symbol_name);
+ if (symbol_name_ref.startswith("_OBJC_")) {
+ static const llvm::StringRef g_objc_v2_prefix_class(
+ "_OBJC_CLASS_$_");
+ static const llvm::StringRef g_objc_v2_prefix_metaclass(
+ "_OBJC_METACLASS_$_");
+ static const llvm::StringRef g_objc_v2_prefix_ivar(
+ "_OBJC_IVAR_$_");
+ if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+ } else if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_metaclass)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
+ } else if (symbol_name_ref.startswith(
+ g_objc_v2_prefix_ivar)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
}
+ }
+ }
+ } else if (symbol_sect_name &&
+ ::strstr(symbol_sect_name, "__gcc_except_tab") ==
+ symbol_sect_name) {
+ type = eSymbolTypeException;
+ } else {
+ type = eSymbolTypeData;
+ }
+ } else if (symbol_sect_name &&
+ ::strstr(symbol_sect_name, "__IMPORT") ==
+ symbol_sect_name) {
+ type = eSymbolTypeTrampoline;
+ } else if (symbol_section->IsDescendant(
+ objc_section_sp.get())) {
+ type = eSymbolTypeRuntime;
+ if (symbol_name && symbol_name[0] == '.') {
+ llvm::StringRef symbol_name_ref(symbol_name);
+ static const llvm::StringRef g_objc_v1_prefix_class(
+ ".objc_class_name_");
+ if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name;
+ symbol_name = symbol_name + g_objc_v1_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
}
+ }
}
- break;
-
- default:
- break;
+ }
}
- offset = cmd_offset + load_cmd.cmdsize;
+ } break;
+ }
}
- if (!rpath_paths.empty())
- {
- // Fixup all LC_RPATH values to be absolute paths
- FileSpec this_file_spec(m_file);
- this_file_spec.ResolvePath();
- std::string loader_path("@loader_path");
- std::string executable_path("@executable_path");
- for (auto &rpath : rpath_paths)
- {
- if (rpath.find(loader_path) == 0)
- {
- rpath.erase(0, loader_path.size());
- rpath.insert(0, this_file_spec.GetDirectory().GetCString());
+ if (add_nlist) {
+ uint64_t symbol_value = nlist.n_value;
+
+ if (symbol_name_non_abi_mangled) {
+ sym[sym_idx].GetMangled().SetMangledName(
+ ConstString(symbol_name_non_abi_mangled));
+ sym[sym_idx].GetMangled().SetDemangledName(
+ ConstString(symbol_name));
+ } else {
+ bool symbol_name_is_mangled = false;
+
+ if (symbol_name && symbol_name[0] == '_') {
+ symbol_name_is_mangled = symbol_name[1] == '_';
+ symbol_name++; // Skip the leading underscore
+ }
+
+ if (symbol_name) {
+ ConstString const_symbol_name(symbol_name);
+ sym[sym_idx].GetMangled().SetValue(const_symbol_name,
+ symbol_name_is_mangled);
+ }
+ }
+
+ if (is_gsym) {
+ const char *gsym_name = sym[sym_idx]
+ .GetMangled()
+ .GetName(lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)
+ .GetCString();
+ if (gsym_name)
+ N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
+ }
+
+ if (symbol_section) {
+ const addr_t section_file_addr = symbol_section->GetFileAddress();
+ if (symbol_byte_size == 0 && function_starts_count > 0) {
+ addr_t symbol_lookup_file_addr = nlist.n_value;
+ // Do an exact address match for non-ARM addresses, else get the
+ // closest since
+ // the symbol might be a thumb symbol which has an address with
+ // bit zero set
+ FunctionStarts::Entry *func_start_entry =
+ function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
+ if (is_arm && func_start_entry) {
+ // Verify that the function start address is the symbol address
+ // (ARM)
+ // or the symbol address + 1 (thumb)
+ if (func_start_entry->addr != symbol_lookup_file_addr &&
+ func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
+ // Not the right entry, NULL it out...
+ func_start_entry = NULL;
}
- else if (rpath.find(executable_path) == 0)
- {
- rpath.erase(0, executable_path.size());
- rpath.insert(0, this_file_spec.GetDirectory().GetCString());
+ }
+ if (func_start_entry) {
+ func_start_entry->data = true;
+
+ addr_t symbol_file_addr = func_start_entry->addr;
+ if (is_arm)
+ symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
+
+ const FunctionStarts::Entry *next_func_start_entry =
+ function_starts.FindNextEntry(func_start_entry);
+ const addr_t section_end_file_addr =
+ section_file_addr + symbol_section->GetByteSize();
+ if (next_func_start_entry) {
+ addr_t next_symbol_file_addr = next_func_start_entry->addr;
+ // Be sure the clear the Thumb address bit when we calculate
+ // the size
+ // from the current and next address
+ if (is_arm)
+ next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
+ symbol_byte_size = std::min<lldb::addr_t>(
+ next_symbol_file_addr - symbol_file_addr,
+ section_end_file_addr - symbol_file_addr);
+ } else {
+ symbol_byte_size = section_end_file_addr - symbol_file_addr;
}
+ }
}
-
- for (const auto &rpath_relative_path : rpath_relative_paths)
- {
- for (const auto &rpath : rpath_paths)
- {
- std::string path = rpath;
- path += rpath_relative_path;
- // It is OK to resolve this path because we must find a file on
- // disk for us to accept it anyway if it is rpath relative.
- FileSpec file_spec(path, true);
- // Remove any redundant parts of the path (like "../foo") since
- // LC_RPATH values often contain "..".
- file_spec.NormalizePath ();
- if (file_spec.Exists() && files.AppendIfUnique(file_spec))
- {
- count++;
- break;
- }
+ symbol_value -= section_file_addr;
+ }
+
+ if (is_debug == false) {
+ if (type == eSymbolTypeCode) {
+ // See if we can find a N_FUN entry for any code symbols.
+ // If we do find a match, and the name matches, then we
+ // can merge the two into just the function symbol to avoid
+ // duplicate entries in the symbol table
+ std::pair<ValueToSymbolIndexMap::const_iterator,
+ ValueToSymbolIndexMap::const_iterator>
+ range;
+ range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
+ if (range.first != range.second) {
+ bool found_it = false;
+ for (ValueToSymbolIndexMap::const_iterator pos = range.first;
+ pos != range.second; ++pos) {
+ if (sym[sym_idx].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled) ==
+ sym[pos->second].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)) {
+ m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
+ // We just need the flags from the linker symbol, so put
+ // these flags
+ // into the N_FUN flags to avoid duplicate symbols in the
+ // symbol table
+ sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
+ sym[pos->second].SetFlags(nlist.n_type << 16 |
+ nlist.n_desc);
+ if (resolver_addresses.find(nlist.n_value) !=
+ resolver_addresses.end())
+ sym[pos->second].SetType(eSymbolTypeResolver);
+ sym[sym_idx].Clear();
+ found_it = true;
+ break;
+ }
+ }
+ if (found_it)
+ continue;
+ } else {
+ if (resolver_addresses.find(nlist.n_value) !=
+ resolver_addresses.end())
+ type = eSymbolTypeResolver;
+ }
+ } else if (type == eSymbolTypeData ||
+ type == eSymbolTypeObjCClass ||
+ type == eSymbolTypeObjCMetaClass ||
+ type == eSymbolTypeObjCIVar) {
+ // See if we can find a N_STSYM entry for any data symbols.
+ // If we do find a match, and the name matches, then we
+ // can merge the two into just the Static symbol to avoid
+ // duplicate entries in the symbol table
+ std::pair<ValueToSymbolIndexMap::const_iterator,
+ ValueToSymbolIndexMap::const_iterator>
+ range;
+ range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
+ if (range.first != range.second) {
+ bool found_it = false;
+ for (ValueToSymbolIndexMap::const_iterator pos = range.first;
+ pos != range.second; ++pos) {
+ if (sym[sym_idx].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled) ==
+ sym[pos->second].GetMangled().GetName(
+ lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)) {
+ m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
+ // We just need the flags from the linker symbol, so put
+ // these flags
+ // into the N_STSYM flags to avoid duplicate symbols in the
+ // symbol table
+ sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
+ sym[pos->second].SetFlags(nlist.n_type << 16 |
+ nlist.n_desc);
+ sym[sym_idx].Clear();
+ found_it = true;
+ break;
+ }
+ }
+ if (found_it)
+ continue;
+ } else {
+ // Combine N_GSYM stab entries with the non stab symbol
+ const char *gsym_name = sym[sym_idx]
+ .GetMangled()
+ .GetName(lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled)
+ .GetCString();
+ if (gsym_name) {
+ ConstNameToSymbolIndexMap::const_iterator pos =
+ N_GSYM_name_to_sym_idx.find(gsym_name);
+ if (pos != N_GSYM_name_to_sym_idx.end()) {
+ const uint32_t GSYM_sym_idx = pos->second;
+ m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
+ // Copy the address, because often the N_GSYM address has an
+ // invalid address of zero
+ // when the global is a common symbol
+ sym[GSYM_sym_idx].GetAddressRef().SetSection(
+ symbol_section);
+ sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value);
+ // We just need the flags from the linker symbol, so put
+ // these flags
+ // into the N_GSYM flags to avoid duplicate symbols in the
+ // symbol table
+ sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
+ nlist.n_desc);
+ sym[sym_idx].Clear();
+ continue;
+ }
}
+ }
}
- }
- }
- return count;
-}
+ }
-lldb_private::Address
-ObjectFileMachO::GetEntryPointAddress ()
-{
- // If the object file is not an executable it can't hold the entry point. m_entry_point_address
- // is initialized to an invalid address, so we can just return that.
- // If m_entry_point_address is valid it means we've found it already, so return the cached value.
+ sym[sym_idx].SetID(nlist_idx);
+ sym[sym_idx].SetType(type);
+ if (set_value) {
+ sym[sym_idx].GetAddressRef().SetSection(symbol_section);
+ sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
+ }
+ sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
- if (!IsExecutable() || m_entry_point_address.IsValid())
- return m_entry_point_address;
+ if (symbol_byte_size > 0)
+ sym[sym_idx].SetByteSize(symbol_byte_size);
- // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
- // /usr/include/mach-o.h, but it is basically:
- //
- // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
- // uint32_t count - this is the count of longs in the thread state data
- // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
- // <repeat this trio>
- //
- // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
- // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
- // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
- // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
- //
- // For now we hard-code the offsets and flavors we need:
- //
- //
+ if (demangled_is_synthesized)
+ sym[sym_idx].SetDemangledNameIsSynthesized(true);
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- struct load_command load_cmd;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t i;
- lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
- bool done = false;
+ ++sym_idx;
+ } else {
+ sym[sym_idx].Clear();
+ }
+ }
+
+ for (const auto &pos : reexport_shlib_needs_fixup) {
+ const auto undef_pos = undefined_name_to_desc.find(pos.second);
+ if (undef_pos != undefined_name_to_desc.end()) {
+ const uint8_t dylib_ordinal =
+ llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
+ if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
+ sym[pos.first].SetReExportedSymbolSharedLibrary(
+ dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
+ }
+ }
+ }
- for (i=0; i<m_header.ncmds; ++i)
- {
- const lldb::offset_t cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
+ uint32_t synthetic_sym_id = symtab_load_command.nsyms;
- switch (load_cmd.cmd)
- {
- case LC_UNIXTHREAD:
- case LC_THREAD:
- {
- while (offset < cmd_offset + load_cmd.cmdsize)
- {
- uint32_t flavor = m_data.GetU32(&offset);
- uint32_t count = m_data.GetU32(&offset);
- if (count == 0)
- {
- // We've gotten off somehow, log and exit;
- return m_entry_point_address;
- }
+ 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)
+ ++num_synthetic_function_symbols;
+ }
- switch (m_header.cputype)
- {
- case llvm::MachO::CPU_TYPE_ARM:
- if (flavor == 1 || flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from mach/arm/thread_status.h
- {
- offset += 60; // This is the offset of pc in the GPR thread state data structure.
- start_address = m_data.GetU32(&offset);
- done = true;
- }
- break;
- case llvm::MachO::CPU_TYPE_ARM64:
- if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
- {
- offset += 256; // This is the offset of pc in the GPR thread state data structure.
- start_address = m_data.GetU64(&offset);
- done = true;
- }
- break;
- case llvm::MachO::CPU_TYPE_I386:
- if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
- {
- offset += 40; // This is the offset of eip in the GPR thread state data structure.
- start_address = m_data.GetU32(&offset);
- done = true;
- }
- break;
- case llvm::MachO::CPU_TYPE_X86_64:
- if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
- {
- offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
- start_address = m_data.GetU64(&offset);
- done = true;
- }
- break;
- default:
- return m_entry_point_address;
- }
- // Haven't found the GPR flavor yet, skip over the data for this flavor:
- if (done)
- break;
- offset += count * 4;
- }
- }
- break;
- case LC_MAIN:
- {
- ConstString text_segment_name ("__TEXT");
- uint64_t entryoffset = m_data.GetU64(&offset);
- SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
- if (text_segment_sp)
- {
- done = true;
- start_address = text_segment_sp->GetFileAddress() + entryoffset;
- }
+ if (num_synthetic_function_symbols > 0) {
+ if (num_syms < sym_idx + num_synthetic_function_symbols) {
+ num_syms = sym_idx + num_synthetic_function_symbols;
+ sym = symtab->Resize(num_syms);
+ }
+ for (i = 0; i < function_starts_count; ++i) {
+ const FunctionStarts::Entry *func_start_entry =
+ function_starts.GetEntryAtIndex(i);
+ if (func_start_entry->data == false) {
+ addr_t symbol_file_addr = func_start_entry->addr;
+ uint32_t symbol_flags = 0;
+ if (is_arm) {
+ if (symbol_file_addr & 1)
+ symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
+ symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
+ }
+ Address symbol_addr;
+ if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
+ SectionSP symbol_section(symbol_addr.GetSection());
+ uint32_t symbol_byte_size = 0;
+ if (symbol_section) {
+ const addr_t section_file_addr =
+ symbol_section->GetFileAddress();
+ const FunctionStarts::Entry *next_func_start_entry =
+ function_starts.FindNextEntry(func_start_entry);
+ const addr_t section_end_file_addr =
+ section_file_addr + symbol_section->GetByteSize();
+ if (next_func_start_entry) {
+ addr_t next_symbol_file_addr = next_func_start_entry->addr;
+ if (is_arm)
+ next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
+ symbol_byte_size = std::min<lldb::addr_t>(
+ next_symbol_file_addr - symbol_file_addr,
+ section_end_file_addr - symbol_file_addr);
+ } else {
+ symbol_byte_size = section_end_file_addr - symbol_file_addr;
}
- break;
-
- default:
- break;
+ sym[sym_idx].SetID(synthetic_sym_id++);
+ sym[sym_idx].GetMangled().SetDemangledName(
+ GetNextSyntheticSymbolName());
+ sym[sym_idx].SetType(eSymbolTypeCode);
+ sym[sym_idx].SetIsSynthetic(true);
+ sym[sym_idx].GetAddressRef() = symbol_addr;
+ if (symbol_flags)
+ sym[sym_idx].SetFlags(symbol_flags);
+ if (symbol_byte_size)
+ sym[sym_idx].SetByteSize(symbol_byte_size);
+ ++sym_idx;
+ }
}
- if (done)
- break;
-
- // Go to the next load command:
- offset = cmd_offset + load_cmd.cmdsize;
+ }
}
+ }
+ }
- if (start_address != LLDB_INVALID_ADDRESS)
- {
- // We got the start address from the load commands, so now resolve that address in the sections
- // of this ObjectFile:
- if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
- {
- m_entry_point_address.Clear();
- }
- }
- else
- {
- // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
- // "start" symbol in the main executable.
+ // Trim our symbols down to just what we ended up with after
+ // removing any symbols.
+ if (sym_idx < num_syms) {
+ num_syms = sym_idx;
+ sym = symtab->Resize(num_syms);
+ }
- ModuleSP module_sp (GetModule());
+ // Now synthesize indirect symbols
+ if (m_dysymtab.nindirectsyms != 0) {
+ if (indirect_symbol_index_data.GetByteSize()) {
+ NListIndexToSymbolIndexMap::const_iterator end_index_pos =
+ m_nlist_idx_to_sym_idx.end();
+
+ for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
+ ++sect_idx) {
+ if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
+ S_SYMBOL_STUBS) {
+ uint32_t symbol_stub_byte_size =
+ m_mach_sections[sect_idx].reserved2;
+ if (symbol_stub_byte_size == 0)
+ continue;
+
+ const uint32_t num_symbol_stubs =
+ m_mach_sections[sect_idx].size / symbol_stub_byte_size;
+
+ if (num_symbol_stubs == 0)
+ continue;
+
+ const uint32_t symbol_stub_index_offset =
+ m_mach_sections[sect_idx].reserved1;
+ for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs;
+ ++stub_idx) {
+ const uint32_t symbol_stub_index =
+ symbol_stub_index_offset + stub_idx;
+ const lldb::addr_t symbol_stub_addr =
+ m_mach_sections[sect_idx].addr +
+ (stub_idx * symbol_stub_byte_size);
+ lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
+ if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
+ symbol_stub_offset, 4)) {
+ const uint32_t stub_sym_id =
+ indirect_symbol_index_data.GetU32(&symbol_stub_offset);
+ if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
+ continue;
+
+ NListIndexToSymbolIndexMap::const_iterator index_pos =
+ m_nlist_idx_to_sym_idx.find(stub_sym_id);
+ Symbol *stub_symbol = NULL;
+ if (index_pos != end_index_pos) {
+ // We have a remapping from the original nlist index to
+ // a current symbol index, so just look this up by index
+ stub_symbol = symtab->SymbolAtIndex(index_pos->second);
+ } else {
+ // We need to lookup a symbol using the original nlist
+ // symbol index since this index is coming from the
+ // S_SYMBOL_STUBS
+ stub_symbol = symtab->FindSymbolByID(stub_sym_id);
+ }
- if (module_sp)
- {
- SymbolContextList contexts;
- SymbolContext context;
- if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
- {
- if (contexts.GetContextAtIndex(0, context))
- m_entry_point_address = context.symbol->GetAddress();
+ if (stub_symbol) {
+ Address so_addr(symbol_stub_addr, section_list);
+
+ if (stub_symbol->GetType() == eSymbolTypeUndefined) {
+ // Change the external symbol into a trampoline that makes
+ // sense
+ // These symbols were N_UNDF N_EXT, and are useless to us,
+ // so we
+ // can re-use them so we don't have to make up a synthetic
+ // symbol
+ // for no good reason.
+ if (resolver_addresses.find(symbol_stub_addr) ==
+ resolver_addresses.end())
+ stub_symbol->SetType(eSymbolTypeTrampoline);
+ else
+ stub_symbol->SetType(eSymbolTypeResolver);
+ stub_symbol->SetExternal(false);
+ stub_symbol->GetAddressRef() = so_addr;
+ stub_symbol->SetByteSize(symbol_stub_byte_size);
+ } else {
+ // Make a synthetic symbol to describe the trampoline stub
+ Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
+ if (sym_idx >= num_syms) {
+ sym = symtab->Resize(++num_syms);
+ stub_symbol = NULL; // this pointer no longer valid
+ }
+ sym[sym_idx].SetID(synthetic_sym_id++);
+ sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
+ if (resolver_addresses.find(symbol_stub_addr) ==
+ resolver_addresses.end())
+ sym[sym_idx].SetType(eSymbolTypeTrampoline);
+ else
+ sym[sym_idx].SetType(eSymbolTypeResolver);
+ sym[sym_idx].SetIsSynthetic(true);
+ sym[sym_idx].GetAddressRef() = so_addr;
+ sym[sym_idx].SetByteSize(symbol_stub_byte_size);
+ ++sym_idx;
+ }
+ } else {
+ if (log)
+ log->Warning("symbol stub referencing symbol table symbol "
+ "%u that isn't in our minimal symbol table, "
+ "fix this!!!",
+ stub_sym_id);
}
+ }
}
+ }
}
+ }
}
- return m_entry_point_address;
-}
-
-lldb_private::Address
-ObjectFileMachO::GetHeaderAddress ()
-{
- lldb_private::Address header_addr;
- SectionList *section_list = GetSectionList();
- if (section_list)
- {
- SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
- if (text_segment_sp)
- {
- header_addr.SetSection (text_segment_sp);
- header_addr.SetOffset (0);
+ if (!trie_entries.empty()) {
+ for (const auto &e : trie_entries) {
+ if (e.entry.import_name) {
+ // Only add indirect symbols from the Trie entries if we
+ // didn't have a N_INDR nlist entry for this already
+ if (indirect_symbol_names.find(e.entry.name) ==
+ indirect_symbol_names.end()) {
+ // Make a synthetic symbol to describe re-exported symbol.
+ if (sym_idx >= num_syms)
+ sym = symtab->Resize(++num_syms);
+ sym[sym_idx].SetID(synthetic_sym_id++);
+ sym[sym_idx].GetMangled() = Mangled(e.entry.name);
+ sym[sym_idx].SetType(eSymbolTypeReExported);
+ sym[sym_idx].SetIsSynthetic(true);
+ sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
+ if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
+ sym[sym_idx].SetReExportedSymbolSharedLibrary(
+ dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
+ }
+ ++sym_idx;
+ }
}
+ }
}
- return header_addr;
+
+ // StreamFile s(stdout, false);
+ // s.Printf ("Symbol table before CalculateSymbolSizes():\n");
+ // symtab->Dump(&s, NULL, eSortOrderNone);
+ // Set symbol byte sizes correctly since mach-o nlist entries don't have
+ // sizes
+ symtab->CalculateSymbolSizes();
+
+ // s.Printf ("Symbol table after CalculateSymbolSizes():\n");
+ // symtab->Dump(&s, NULL, eSortOrderNone);
+
+ return symtab->GetNumSymbols();
+ }
+ return 0;
}
-uint32_t
-ObjectFileMachO::GetNumThreadContexts ()
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (!m_thread_context_offsets_valid)
- {
- m_thread_context_offsets_valid = true;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- FileRangeArray::Entry file_range;
- thread_command thread_cmd;
- for (uint32_t i=0; i<m_header.ncmds; ++i)
- {
- const uint32_t cmd_offset = offset;
- if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
- break;
+void ObjectFileMachO::Dump(Stream *s) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ s->Printf("%p: ", static_cast<void *>(this));
+ s->Indent();
+ if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
+ s->PutCString("ObjectFileMachO64");
+ else
+ s->PutCString("ObjectFileMachO32");
- if (thread_cmd.cmd == LC_THREAD)
- {
- file_range.SetRangeBase (offset);
- file_range.SetByteSize (thread_cmd.cmdsize - 8);
- m_thread_context_offsets.Append (file_range);
- }
- offset = cmd_offset + thread_cmd.cmdsize;
- }
- }
- }
- return m_thread_context_offsets.GetSize();
+ ArchSpec header_arch;
+ GetArchitecture(header_arch);
+
+ *s << ", file = '" << m_file
+ << "', arch = " << header_arch.GetArchitectureName() << "\n";
+
+ SectionList *sections = GetSectionList();
+ if (sections)
+ sections->Dump(s, NULL, true, UINT32_MAX);
+
+ if (m_symtab_ap.get())
+ m_symtab_ap->Dump(s, NULL, eSortOrderNone);
+ }
}
-lldb::RegisterContextSP
-ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
-{
- lldb::RegisterContextSP reg_ctx_sp;
+bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t lc_offset,
+ lldb_private::UUID &uuid) {
+ uint32_t i;
+ struct uuid_command load_cmd;
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (!m_thread_context_offsets_valid)
- GetNumThreadContexts ();
+ lldb::offset_t offset = lc_offset;
+ for (i = 0; i < header.ncmds; ++i) {
+ const lldb::offset_t cmd_offset = offset;
+ if (data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
- const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
- if (thread_context_file_range)
- {
+ if (load_cmd.cmd == LC_UUID) {
+ const uint8_t *uuid_bytes = data.PeekData(offset, 16);
- DataExtractor data (m_data,
- thread_context_file_range->GetRangeBase(),
- thread_context_file_range->GetByteSize());
+ if (uuid_bytes) {
+ // OpenCL on Mac OS X uses the same UUID for each of its object files.
+ // We pretend these object files have no UUID to prevent crashing.
- switch (m_header.cputype)
- {
- case llvm::MachO::CPU_TYPE_ARM64:
- reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
- break;
-
- case llvm::MachO::CPU_TYPE_ARM:
- reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
- break;
+ const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
+ 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
+ 0xbb, 0x14, 0xf0, 0x0d};
- case llvm::MachO::CPU_TYPE_I386:
- reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
- break;
+ if (!memcmp(uuid_bytes, opencl_uuid, 16))
+ return false;
- case llvm::MachO::CPU_TYPE_X86_64:
- reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
- break;
- }
+ uuid.SetBytes(uuid_bytes);
+ return true;
+ }
+ return false;
+ }
+ offset = cmd_offset + load_cmd.cmdsize;
+ }
+ return false;
+}
+
+bool 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()) {
+ llvm::Triple &triple = arch.GetTriple();
+
+ // Set OS to an unspecified unknown or a "*" so it can match any OS
+ triple.setOS(llvm::Triple::UnknownOS);
+ triple.setOSName(llvm::StringRef());
+
+ if (header.filetype == MH_PRELOAD) {
+ if (header.cputype == CPU_TYPE_ARM) {
+ // If this is a 32-bit arm binary, and it's a standalone binary,
+ // force the Vendor to Apple so we don't accidentally pick up
+ // the generic armv7 ABI at runtime. Apple's armv7 ABI always uses
+ // r7 for the frame pointer register; most other armv7 ABIs use a
+ // combination of r7 and r11.
+ triple.setVendor(llvm::Triple::Apple);
+ } else {
+ // Set vendor to an unspecified unknown or a "*" so it can match any
+ // vendor
+ // This is required for correct behavior of EFI debugging on x86_64
+ triple.setVendor(llvm::Triple::UnknownVendor);
+ triple.setVendorName(llvm::StringRef());
+ }
+ return true;
+ } else {
+ struct load_command load_cmd;
+
+ 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;
+
+ switch (load_cmd.cmd) {
+ case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
+ triple.setOS(llvm::Triple::IOS);
+ return true;
+
+ case llvm::MachO::LC_VERSION_MIN_MACOSX:
+ triple.setOS(llvm::Triple::MacOSX);
+ return true;
+
+ case llvm::MachO::LC_VERSION_MIN_TVOS:
+ triple.setOS(llvm::Triple::TvOS);
+ return true;
+
+ case llvm::MachO::LC_VERSION_MIN_WATCHOS:
+ triple.setOS(llvm::Triple::WatchOS);
+ return true;
+
+ default:
+ break;
}
+
+ 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
+ // unknown
+ triple.setVendor(llvm::Triple::UnknownVendor);
+ triple.setVendorName(llvm::StringRef());
+ }
}
- return reg_ctx_sp;
+ }
+ return arch.IsValid();
}
-ObjectFile::Type
-ObjectFileMachO::CalculateType()
-{
- switch (m_header.filetype)
- {
- case MH_OBJECT: // 0x1u
- if (GetAddressByteSize () == 4)
- {
- // 32 bit kexts are just object files, but they do have a valid
- // UUID load command.
- UUID uuid;
- if (GetUUID(&uuid))
- {
- // this checking for the UUID load command is not enough
- // we could eventually look for the symbol named
- // "OSKextGetCurrentIdentifier" as this is required of kexts
- if (m_strata == eStrataInvalid)
- m_strata = eStrataKernel;
- return eTypeSharedLibrary;
- }
+bool ObjectFileMachO::GetUUID(lldb_private::UUID *uuid) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ return GetUUID(m_header, m_data, offset, *uuid);
+ }
+ return false;
+}
+
+uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
+ uint32_t count = 0;
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ struct load_command load_cmd;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ std::vector<std::string> rpath_paths;
+ std::vector<std::string> rpath_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;
+ if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
+
+ switch (load_cmd.cmd) {
+ case LC_RPATH:
+ case LC_LOAD_DYLIB:
+ case LC_LOAD_WEAK_DYLIB:
+ case LC_REEXPORT_DYLIB:
+ case LC_LOAD_DYLINKER:
+ case LC_LOADFVMLIB:
+ case LC_LOAD_UPWARD_DYLIB: {
+ uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
+ const char *path = m_data.PeekCStr(name_offset);
+ if (path) {
+ if (load_cmd.cmd == LC_RPATH)
+ rpath_paths.push_back(path);
+ else {
+ if (path[0] == '@') {
+ if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
+ rpath_relative_paths.push_back(path + strlen("@rpath"));
+ } else {
+ FileSpec file_spec(path, resolve_path);
+ if (files.AppendIfUnique(file_spec))
+ count++;
}
- return eTypeObjectFile;
-
- case MH_EXECUTE: return eTypeExecutable; // 0x2u
- case MH_FVMLIB: return eTypeSharedLibrary; // 0x3u
- case MH_CORE: return eTypeCoreFile; // 0x4u
- case MH_PRELOAD: return eTypeSharedLibrary; // 0x5u
- case MH_DYLIB: return eTypeSharedLibrary; // 0x6u
- case MH_DYLINKER: return eTypeDynamicLinker; // 0x7u
- case MH_BUNDLE: return eTypeSharedLibrary; // 0x8u
- case MH_DYLIB_STUB: return eTypeStubLibrary; // 0x9u
- case MH_DSYM: return eTypeDebugInfo; // 0xAu
- case MH_KEXT_BUNDLE: return eTypeSharedLibrary; // 0xBu
- default:
+ }
+ }
+ } break;
+
+ default:
+ break;
+ }
+ offset = cmd_offset + load_cmd.cmdsize;
+ }
+
+ if (!rpath_paths.empty()) {
+ // Fixup all LC_RPATH values to be absolute paths
+ FileSpec this_file_spec(m_file);
+ this_file_spec.ResolvePath();
+ std::string loader_path("@loader_path");
+ std::string executable_path("@executable_path");
+ for (auto &rpath : rpath_paths) {
+ if (rpath.find(loader_path) == 0) {
+ rpath.erase(0, loader_path.size());
+ rpath.insert(0, this_file_spec.GetDirectory().GetCString());
+ } else if (rpath.find(executable_path) == 0) {
+ rpath.erase(0, executable_path.size());
+ rpath.insert(0, this_file_spec.GetDirectory().GetCString());
+ }
+ }
+
+ for (const auto &rpath_relative_path : rpath_relative_paths) {
+ for (const auto &rpath : rpath_paths) {
+ std::string path = rpath;
+ path += rpath_relative_path;
+ // It is OK to resolve this path because we must find a file on
+ // disk for us to accept it anyway if it is rpath relative.
+ FileSpec file_spec(path, true);
+ // Remove any redundant parts of the path (like "../foo") since
+ // LC_RPATH values often contain "..".
+ file_spec = file_spec.GetNormalizedPath();
+ if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
+ count++;
break;
+ }
+ }
+ }
}
- return eTypeUnknown;
+ }
+ return count;
}
-ObjectFile::Strata
-ObjectFileMachO::CalculateStrata()
-{
- switch (m_header.filetype)
- {
- case MH_OBJECT: // 0x1u
+lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
+ // If the object file is not an executable it can't hold the entry point.
+ // m_entry_point_address
+ // is initialized to an invalid address, so we can just return that.
+ // If m_entry_point_address is valid it means we've found it already, so
+ // return the cached value.
+
+ if (!IsExecutable() || m_entry_point_address.IsValid())
+ return m_entry_point_address;
+
+ // Otherwise, look for the UnixThread or Thread command. The data for the
+ // Thread command is given in
+ // /usr/include/mach-o.h, but it is basically:
+ //
+ // uint32_t flavor - this is the flavor argument you would pass to
+ // thread_get_state
+ // uint32_t count - this is the count of longs in the thread state data
+ // struct XXX_thread_state state - this is the structure from
+ // <machine/thread_status.h> corresponding to the flavor.
+ // <repeat this trio>
+ //
+ // So we just keep reading the various register flavors till we find the GPR
+ // one, then read the PC out of there.
+ // FIXME: We will need to have a "RegisterContext data provider" class at some
+ // point that can get all the registers
+ // out of data in this form & attach them to a given thread. That should
+ // underlie the MacOS X User process plugin,
+ // and we'll also need it for the MacOS X Core File process plugin. When we
+ // have that we can also use it here.
+ //
+ // For now we hard-code the offsets and flavors we need:
+ //
+ //
+
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ struct load_command load_cmd;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ uint32_t i;
+ lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
+ bool done = false;
+
+ for (i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t cmd_offset = offset;
+ if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
+
+ switch (load_cmd.cmd) {
+ case LC_UNIXTHREAD:
+ case LC_THREAD: {
+ while (offset < cmd_offset + load_cmd.cmdsize) {
+ uint32_t flavor = m_data.GetU32(&offset);
+ uint32_t count = m_data.GetU32(&offset);
+ if (count == 0) {
+ // We've gotten off somehow, log and exit;
+ return m_entry_point_address;
+ }
+
+ switch (m_header.cputype) {
+ case llvm::MachO::CPU_TYPE_ARM:
+ if (flavor == 1 ||
+ flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from
+ // mach/arm/thread_status.h
{
- // 32 bit kexts are just object files, but they do have a valid
- // UUID load command.
- UUID uuid;
- if (GetUUID(&uuid))
- {
- // this checking for the UUID load command is not enough
- // we could eventually look for the symbol named
- // "OSKextGetCurrentIdentifier" as this is required of kexts
- if (m_type == eTypeInvalid)
- m_type = eTypeSharedLibrary;
-
- return eStrataKernel;
- }
+ offset += 60; // This is the offset of pc in the GPR thread state
+ // data structure.
+ start_address = m_data.GetU32(&offset);
+ done = true;
}
- return eStrataUnknown;
-
- case MH_EXECUTE: // 0x2u
- // Check for the MH_DYLDLINK bit in the flags
- if (m_header.flags & MH_DYLDLINK)
+ break;
+ case llvm::MachO::CPU_TYPE_ARM64:
+ if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
{
- return eStrataUser;
+ offset += 256; // This is the offset of pc in the GPR thread state
+ // data structure.
+ start_address = m_data.GetU64(&offset);
+ done = true;
}
- else
+ break;
+ case llvm::MachO::CPU_TYPE_I386:
+ if (flavor ==
+ 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
{
- SectionList *section_list = GetSectionList();
- if (section_list)
- {
- static ConstString g_kld_section_name ("__KLD");
- if (section_list->FindSectionByName(g_kld_section_name))
- return eStrataKernel;
- }
+ offset += 40; // This is the offset of eip in the GPR thread state
+ // data structure.
+ start_address = m_data.GetU32(&offset);
+ done = true;
}
- return eStrataRawImage;
-
- case MH_FVMLIB: return eStrataUser; // 0x3u
- case MH_CORE: return eStrataUnknown; // 0x4u
- case MH_PRELOAD: return eStrataRawImage; // 0x5u
- case MH_DYLIB: return eStrataUser; // 0x6u
- case MH_DYLINKER: return eStrataUser; // 0x7u
- case MH_BUNDLE: return eStrataUser; // 0x8u
- case MH_DYLIB_STUB: return eStrataUser; // 0x9u
- case MH_DSYM: return eStrataUnknown; // 0xAu
- case MH_KEXT_BUNDLE: return eStrataKernel; // 0xBu
- default:
break;
+ case llvm::MachO::CPU_TYPE_X86_64:
+ if (flavor ==
+ 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
+ {
+ offset += 16 * 8; // This is the offset of rip in the GPR thread
+ // state data structure.
+ start_address = m_data.GetU64(&offset);
+ done = true;
+ }
+ break;
+ default:
+ return m_entry_point_address;
+ }
+ // Haven't found the GPR flavor yet, skip over the data for this
+ // flavor:
+ if (done)
+ break;
+ offset += count * 4;
+ }
+ } break;
+ case LC_MAIN: {
+ ConstString text_segment_name("__TEXT");
+ uint64_t entryoffset = m_data.GetU64(&offset);
+ SectionSP text_segment_sp =
+ GetSectionList()->FindSectionByName(text_segment_name);
+ if (text_segment_sp) {
+ done = true;
+ start_address = text_segment_sp->GetFileAddress() + entryoffset;
+ }
+ } break;
+
+ default:
+ break;
+ }
+ if (done)
+ break;
+
+ // Go to the next load command:
+ offset = cmd_offset + load_cmd.cmdsize;
}
- return eStrataUnknown;
+
+ if (start_address != LLDB_INVALID_ADDRESS) {
+ // We got the start address from the load commands, so now resolve that
+ // address in the sections
+ // of this ObjectFile:
+ if (!m_entry_point_address.ResolveAddressUsingFileSections(
+ start_address, GetSectionList())) {
+ m_entry_point_address.Clear();
+ }
+ } else {
+ // We couldn't read the UnixThread load command - maybe it wasn't there.
+ // As a fallback look for the
+ // "start" symbol in the main executable.
+
+ ModuleSP module_sp(GetModule());
+
+ if (module_sp) {
+ SymbolContextList contexts;
+ SymbolContext context;
+ if (module_sp->FindSymbolsWithNameAndType(ConstString("start"),
+ eSymbolTypeCode, contexts)) {
+ if (contexts.GetContextAtIndex(0, context))
+ m_entry_point_address = context.symbol->GetAddress();
+ }
+ }
+ }
+ }
+
+ return m_entry_point_address;
}
-uint32_t
-ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- struct dylib_command load_cmd;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t version_cmd = 0;
- uint64_t version = 0;
- uint32_t i;
- for (i=0; i<m_header.ncmds; ++i)
- {
- const lldb::offset_t cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
+lldb_private::Address ObjectFileMachO::GetHeaderAddress() {
+ lldb_private::Address header_addr;
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ SectionSP text_segment_sp(
+ section_list->FindSectionByName(GetSegmentNameTEXT()));
+ if (text_segment_sp) {
+ header_addr.SetSection(text_segment_sp);
+ header_addr.SetOffset(0);
+ }
+ }
+ return header_addr;
+}
- if (load_cmd.cmd == LC_ID_DYLIB)
- {
- if (version_cmd == 0)
- {
- version_cmd = load_cmd.cmd;
- if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
- break;
- version = load_cmd.dylib.current_version;
- }
- break; // Break for now unless there is another more complete version
- // number load command in the future.
- }
- offset = cmd_offset + load_cmd.cmdsize;
+uint32_t ObjectFileMachO::GetNumThreadContexts() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (!m_thread_context_offsets_valid) {
+ m_thread_context_offsets_valid = true;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ FileRangeArray::Entry file_range;
+ thread_command thread_cmd;
+ for (uint32_t i = 0; i < m_header.ncmds; ++i) {
+ const uint32_t cmd_offset = offset;
+ if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
+ break;
+
+ if (thread_cmd.cmd == LC_THREAD) {
+ file_range.SetRangeBase(offset);
+ file_range.SetByteSize(thread_cmd.cmdsize - 8);
+ m_thread_context_offsets.Append(file_range);
}
+ offset = cmd_offset + thread_cmd.cmdsize;
+ }
+ }
+ }
+ return m_thread_context_offsets.GetSize();
+}
- if (version_cmd == LC_ID_DYLIB)
- {
- if (versions != NULL && num_versions > 0)
- {
- if (num_versions > 0)
- versions[0] = (version & 0xFFFF0000ull) >> 16;
- if (num_versions > 1)
- versions[1] = (version & 0x0000FF00ull) >> 8;
- if (num_versions > 2)
- versions[2] = (version & 0x000000FFull);
- // Fill in an remaining version numbers with invalid values
- for (i=3; i<num_versions; ++i)
- versions[i] = UINT32_MAX;
- }
- // The LC_ID_DYLIB load command has a version with 3 version numbers
- // in it, so always return 3
- return 3;
- }
+lldb::RegisterContextSP
+ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
+ lldb_private::Thread &thread) {
+ lldb::RegisterContextSP reg_ctx_sp;
+
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (!m_thread_context_offsets_valid)
+ GetNumThreadContexts();
+
+ const FileRangeArray::Entry *thread_context_file_range =
+ m_thread_context_offsets.GetEntryAtIndex(idx);
+ if (thread_context_file_range) {
+
+ DataExtractor data(m_data, thread_context_file_range->GetRangeBase(),
+ thread_context_file_range->GetByteSize());
+
+ switch (m_header.cputype) {
+ case llvm::MachO::CPU_TYPE_ARM64:
+ reg_ctx_sp.reset(new RegisterContextDarwin_arm64_Mach(thread, data));
+ break;
+
+ case llvm::MachO::CPU_TYPE_ARM:
+ reg_ctx_sp.reset(new RegisterContextDarwin_arm_Mach(thread, data));
+ break;
+
+ case llvm::MachO::CPU_TYPE_I386:
+ reg_ctx_sp.reset(new RegisterContextDarwin_i386_Mach(thread, data));
+ break;
+
+ case llvm::MachO::CPU_TYPE_X86_64:
+ reg_ctx_sp.reset(new RegisterContextDarwin_x86_64_Mach(thread, data));
+ break;
+ }
}
- return false;
+ }
+ return reg_ctx_sp;
}
-bool
-ObjectFileMachO::GetArchitecture (ArchSpec &arch)
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
+ObjectFile::Type ObjectFileMachO::CalculateType() {
+ switch (m_header.filetype) {
+ case MH_OBJECT: // 0x1u
+ if (GetAddressByteSize() == 4) {
+ // 32 bit kexts are just object files, but they do have a valid
+ // UUID load command.
+ UUID uuid;
+ if (GetUUID(&uuid)) {
+ // this checking for the UUID load command is not enough
+ // we could eventually look for the symbol named
+ // "OSKextGetCurrentIdentifier" as this is required of kexts
+ if (m_strata == eStrataInvalid)
+ m_strata = eStrataKernel;
+ return eTypeSharedLibrary;
+ }
}
- return false;
+ return eTypeObjectFile;
+
+ case MH_EXECUTE:
+ return eTypeExecutable; // 0x2u
+ case MH_FVMLIB:
+ return eTypeSharedLibrary; // 0x3u
+ case MH_CORE:
+ return eTypeCoreFile; // 0x4u
+ case MH_PRELOAD:
+ return eTypeSharedLibrary; // 0x5u
+ case MH_DYLIB:
+ return eTypeSharedLibrary; // 0x6u
+ case MH_DYLINKER:
+ return eTypeDynamicLinker; // 0x7u
+ case MH_BUNDLE:
+ return eTypeSharedLibrary; // 0x8u
+ case MH_DYLIB_STUB:
+ return eTypeStubLibrary; // 0x9u
+ case MH_DSYM:
+ return eTypeDebugInfo; // 0xAu
+ case MH_KEXT_BUNDLE:
+ return eTypeSharedLibrary; // 0xBu
+ default:
+ break;
+ }
+ return eTypeUnknown;
}
-UUID
-ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
-{
+ObjectFile::Strata ObjectFileMachO::CalculateStrata() {
+ switch (m_header.filetype) {
+ case MH_OBJECT: // 0x1u
+ {
+ // 32 bit kexts are just object files, but they do have a valid
+ // UUID load command.
UUID uuid;
- if (process)
- {
- addr_t all_image_infos = process->GetImageInfoAddress();
-
- // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
- // or it may be the address of the dyld_all_image_infos structure (want). The first four
- // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
- // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
-
- Error err;
- uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
- if (version_or_magic != static_cast<uint32_t>(-1)
- && version_or_magic != MH_MAGIC
- && version_or_magic != MH_CIGAM
- && version_or_magic != MH_MAGIC_64
- && version_or_magic != MH_CIGAM_64
- && version_or_magic >= 13)
- {
- addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
- int wordsize = process->GetAddressByteSize();
- if (wordsize == 8)
- {
- sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
- }
- if (wordsize == 4)
- {
- sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
- }
- if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
- {
- uuid_t shared_cache_uuid;
- if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
- {
- uuid.SetBytes (shared_cache_uuid);
- }
- }
+ if (GetUUID(&uuid)) {
+ // this checking for the UUID load command is not enough
+ // we could eventually look for the symbol named
+ // "OSKextGetCurrentIdentifier" as this is required of kexts
+ if (m_type == eTypeInvalid)
+ m_type = eTypeSharedLibrary;
+
+ return eStrataKernel;
+ }
+ }
+ return eStrataUnknown;
+
+ case MH_EXECUTE: // 0x2u
+ // Check for the MH_DYLDLINK bit in the flags
+ if (m_header.flags & MH_DYLDLINK) {
+ return eStrataUser;
+ } else {
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ static ConstString g_kld_section_name("__KLD");
+ if (section_list->FindSectionByName(g_kld_section_name))
+ return eStrataKernel;
+ }
+ }
+ return eStrataRawImage;
+
+ case MH_FVMLIB:
+ return eStrataUser; // 0x3u
+ case MH_CORE:
+ return eStrataUnknown; // 0x4u
+ case MH_PRELOAD:
+ return eStrataRawImage; // 0x5u
+ case MH_DYLIB:
+ return eStrataUser; // 0x6u
+ case MH_DYLINKER:
+ return eStrataUser; // 0x7u
+ case MH_BUNDLE:
+ return eStrataUser; // 0x8u
+ case MH_DYLIB_STUB:
+ return eStrataUser; // 0x9u
+ case MH_DSYM:
+ return eStrataUnknown; // 0xAu
+ case MH_KEXT_BUNDLE:
+ return eStrataKernel; // 0xBu
+ default:
+ break;
+ }
+ return eStrataUnknown;
+}
+
+uint32_t ObjectFileMachO::GetVersion(uint32_t *versions,
+ uint32_t num_versions) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ struct dylib_command load_cmd;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ uint32_t version_cmd = 0;
+ uint64_t version = 0;
+ uint32_t i;
+ for (i = 0; i < m_header.ncmds; ++i) {
+ const lldb::offset_t cmd_offset = offset;
+ if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
+
+ if (load_cmd.cmd == LC_ID_DYLIB) {
+ if (version_cmd == 0) {
+ version_cmd = load_cmd.cmd;
+ if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
+ break;
+ version = load_cmd.dylib.current_version;
}
+ break; // Break for now unless there is another more complete version
+ // number load command in the future.
+ }
+ offset = cmd_offset + load_cmd.cmdsize;
+ }
+
+ if (version_cmd == LC_ID_DYLIB) {
+ if (versions != NULL && num_versions > 0) {
+ if (num_versions > 0)
+ versions[0] = (version & 0xFFFF0000ull) >> 16;
+ if (num_versions > 1)
+ versions[1] = (version & 0x0000FF00ull) >> 8;
+ if (num_versions > 2)
+ versions[2] = (version & 0x000000FFull);
+ // Fill in an remaining version numbers with invalid values
+ for (i = 3; i < num_versions; ++i)
+ versions[i] = UINT32_MAX;
+ }
+ // The LC_ID_DYLIB load command has a version with 3 version numbers
+ // in it, so always return 3
+ return 3;
}
- return uuid;
+ }
+ return false;
}
-UUID
-ObjectFileMachO::GetLLDBSharedCacheUUID ()
-{
- UUID uuid;
-#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
- uint8_t *(*dyld_get_all_image_infos)(void);
- dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
- if (dyld_get_all_image_infos)
- {
- uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
- if (dyld_all_image_infos_address)
- {
- uint32_t *version = (uint32_t*) dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
- if (*version >= 13)
- {
- uuid_t *sharedCacheUUID_address = 0;
- int wordsize = sizeof (uint8_t *);
- if (wordsize == 8)
- {
- sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
- }
- else
- {
- sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84); // sharedCacheUUID <mach-o/dyld_images.h>
- }
- uuid.SetBytes (sharedCacheUUID_address);
- }
+bool ObjectFileMachO::GetArchitecture(ArchSpec &arch) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ return GetArchitecture(m_header, m_data,
+ MachHeaderSizeFromMagic(m_header.magic), arch);
+ }
+ return false;
+}
+
+UUID ObjectFileMachO::GetProcessSharedCacheUUID(Process *process) {
+ UUID uuid;
+ if (process && process->GetDynamicLoader()) {
+ DynamicLoader *dl = process->GetDynamicLoader();
+ addr_t load_address;
+ LazyBool using_shared_cache;
+ LazyBool private_shared_cache;
+ dl->GetSharedCacheInformation(load_address, uuid, using_shared_cache,
+ private_shared_cache);
+ }
+ return uuid;
+}
+
+UUID ObjectFileMachO::GetLLDBSharedCacheUUID() {
+ UUID uuid;
+#if defined(__APPLE__) && \
+ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
+ uint8_t *(*dyld_get_all_image_infos)(void);
+ dyld_get_all_image_infos =
+ (uint8_t * (*)())dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");
+ if (dyld_get_all_image_infos) {
+ uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
+ if (dyld_all_image_infos_address) {
+ uint32_t *version = (uint32_t *)
+ dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
+ if (*version >= 13) {
+ uuid_t *sharedCacheUUID_address = 0;
+ int wordsize = sizeof(uint8_t *);
+ if (wordsize == 8) {
+ sharedCacheUUID_address =
+ (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
+ 160); // sharedCacheUUID <mach-o/dyld_images.h>
+ } else {
+ sharedCacheUUID_address =
+ (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
+ 84); // sharedCacheUUID <mach-o/dyld_images.h>
}
+ uuid.SetBytes(sharedCacheUUID_address);
+ }
}
+ }
#endif
- return uuid;
+ return uuid;
}
-uint32_t
-ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
-{
- if (m_min_os_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)
- {
- 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_VERSION_MIN_MACOSX
- || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS
- || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS
- || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS)
- {
- if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
- {
- const uint32_t xxxx = lc.version >> 16;
- const uint32_t yy = (lc.version >> 8) & 0xffu;
- const uint32_t zz = lc.version & 0xffu;
- if (xxxx)
- {
- m_min_os_versions.push_back(xxxx);
- m_min_os_versions.push_back(yy);
- m_min_os_versions.push_back(zz);
- }
- success = true;
- }
- }
- offset = load_cmd_offset + lc.cmdsize;
- }
-
- if (success == false)
- {
- // Push an invalid value so we don't keep trying to
- m_min_os_versions.push_back(UINT32_MAX);
+uint32_t ObjectFileMachO::GetMinimumOSVersion(uint32_t *versions,
+ uint32_t num_versions) {
+ if (m_min_os_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) {
+ 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_VERSION_MIN_MACOSX ||
+ lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
+ lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
+ lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
+ if (m_data.GetU32(&offset, &lc.version,
+ (sizeof(lc) / sizeof(uint32_t)) - 2)) {
+ const uint32_t xxxx = lc.version >> 16;
+ const uint32_t yy = (lc.version >> 8) & 0xffu;
+ const uint32_t zz = lc.version & 0xffu;
+ if (xxxx) {
+ m_min_os_versions.push_back(xxxx);
+ m_min_os_versions.push_back(yy);
+ m_min_os_versions.push_back(zz);
+ }
+ success = true;
}
+ }
+ offset = load_cmd_offset + lc.cmdsize;
}
-
- if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
- {
- if (versions != NULL && num_versions > 0)
- {
- for (size_t i=0; i<num_versions; ++i)
- {
- if (i < m_min_os_versions.size())
- versions[i] = m_min_os_versions[i];
- else
- versions[i] = 0;
- }
- }
- return m_min_os_versions.size();
+
+ if (success == false) {
+ // Push an invalid value so we don't keep trying to
+ m_min_os_versions.push_back(UINT32_MAX);
+ }
+ }
+
+ if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX) {
+ if (versions != NULL && num_versions > 0) {
+ for (size_t i = 0; i < num_versions; ++i) {
+ if (i < m_min_os_versions.size())
+ versions[i] = m_min_os_versions[i];
+ else
+ versions[i] = 0;
+ }
}
- // Call the superclasses version that will empty out the data
- return ObjectFile::GetMinimumOSVersion (versions, num_versions);
+ return m_min_os_versions.size();
+ }
+ // Call the superclasses version that will empty out the data
+ return ObjectFile::GetMinimumOSVersion(versions, num_versions);
}
-uint32_t
-ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_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)
- {
- 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_VERSION_MIN_MACOSX
- || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS
- || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS
- || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS)
- {
- if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
- {
- const uint32_t xxxx = lc.sdk >> 16;
- const uint32_t yy = (lc.sdk >> 8) & 0xffu;
- const uint32_t zz = lc.sdk & 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 == false)
- {
- // Push an invalid value so we don't keep trying to
- m_sdk_versions.push_back(UINT32_MAX);
+uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
+ uint32_t num_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) {
+ 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_VERSION_MIN_MACOSX ||
+ lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
+ lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
+ lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
+ if (m_data.GetU32(&offset, &lc.version,
+ (sizeof(lc) / sizeof(uint32_t)) - 2)) {
+ const uint32_t xxxx = lc.sdk >> 16;
+ const uint32_t yy = (lc.sdk >> 8) & 0xffu;
+ const uint32_t zz = lc.sdk & 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 (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
- {
- if (versions != NULL && num_versions > 0)
- {
- for (size_t i=0; i<num_versions; ++i)
- {
- if (i < m_sdk_versions.size())
- versions[i] = m_sdk_versions[i];
- else
- versions[i] = 0;
- }
- }
- return m_sdk_versions.size();
+
+ if (success == false) {
+ // Push an invalid value so we don't keep trying to
+ m_sdk_versions.push_back(UINT32_MAX);
}
- // Call the superclasses version that will empty out the data
- return ObjectFile::GetSDKVersion (versions, num_versions);
+ }
+
+ if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX) {
+ if (versions != NULL && num_versions > 0) {
+ for (size_t i = 0; i < num_versions; ++i) {
+ if (i < m_sdk_versions.size())
+ versions[i] = m_sdk_versions[i];
+ else
+ versions[i] = 0;
+ }
+ }
+ return m_sdk_versions.size();
+ }
+ // Call the superclasses version that will empty out the data
+ return ObjectFile::GetSDKVersion(versions, num_versions);
}
-bool
-ObjectFileMachO::GetIsDynamicLinkEditor()
-{
- return m_header.filetype == llvm::MachO::MH_DYLINKER;
+bool ObjectFileMachO::GetIsDynamicLinkEditor() {
+ return m_header.filetype == llvm::MachO::MH_DYLINKER;
}
-bool
-ObjectFileMachO::AllowAssemblyEmulationUnwindPlans ()
-{
- return m_allow_assembly_emulation_unwind_plans;
+bool ObjectFileMachO::AllowAssemblyEmulationUnwindPlans() {
+ return m_allow_assembly_emulation_unwind_plans;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ObjectFileMachO::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ObjectFileMachO::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ObjectFileMachO::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ObjectFileMachO::GetPluginVersion() { return 1; }
-Section *
-ObjectFileMachO::GetMachHeaderSection()
-{
- // Find the first address of the mach header which is the first non-zero
- // file sized section whose file offset is zero. This is the base file address
- // of the mach-o file which can be subtracted from the vmaddr of the other
- // 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;
- }
- }
+Section *ObjectFileMachO::GetMachHeaderSection() {
+ // Find the first address of the mach header which is the first non-zero
+ // file sized section whose file offset is zero. This is the base file address
+ // of the mach-o file which can be subtracted from the vmaddr of the other
+ // 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;
}
+ }
}
- return nullptr;
+ }
+ return nullptr;
}
-lldb::addr_t
-ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_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;
- }
+lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
+ lldb::addr_t mach_header_load_address, const Section *mach_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;
+ }
}
- return LLDB_INVALID_ADDRESS;
+ }
+ return LLDB_INVALID_ADDRESS;
}
-bool
-ObjectFileMachO::SetLoadAddress (Target &target,
- lldb::addr_t value,
- bool value_is_offset)
-{
- ModuleSP module_sp = GetModule();
- if (module_sp)
- {
- size_t num_loaded_sections = 0;
- SectionList *section_list = GetSectionList ();
- if (section_list)
- {
- const size_t num_sections = section_list->GetSize();
-
- if (value_is_offset)
- {
- // "value" is an offset to apply to each top level segment
- for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
- {
- // Iterate through the object file sections to find all
- // of the sections that size on disk (to avoid __PAGEZERO)
- // and load them
- 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 (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
- ++num_loaded_sections;
- }
- }
+bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
+ bool value_is_offset) {
+ ModuleSP module_sp = GetModule();
+ if (module_sp) {
+ size_t num_loaded_sections = 0;
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ const size_t num_sections = section_list->GetSize();
+
+ if (value_is_offset) {
+ // "value" is an offset to apply to each top level segment
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ // Iterate through the object file sections to find all
+ // of the sections that size on disk (to avoid __PAGEZERO)
+ // and load them
+ 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;
}
- else
- {
- // "value" is the new base address of the mach_header, adjust each
- // section accordingly
-
- Section *mach_header_section = GetMachHeaderSection();
- if (mach_header_section)
- {
- for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
- {
- SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
-
- lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get());
- if (section_load_addr != LLDB_INVALID_ADDRESS)
- {
- if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr))
- ++num_loaded_sections;
- }
- }
- }
+ 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
+ // section accordingly
+
+ Section *mach_header_section = GetMachHeaderSection();
+ if (mach_header_section) {
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+
+ lldb::addr_t section_load_addr =
+ CalculateSectionLoadAddressForMemoryImage(
+ value, mach_header_section, section_sp.get());
+ if (section_load_addr != LLDB_INVALID_ADDRESS) {
+ if (target.GetSectionLoadList().SetSectionLoadAddress(
+ section_sp, section_load_addr))
+ ++num_loaded_sections;
}
+ }
}
- return num_loaded_sections > 0;
+ }
}
- return false;
+ return num_loaded_sections > 0;
+ }
+ return false;
}
-bool
-ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
- const FileSpec &outfile,
- Error &error)
-{
- if (process_sp)
- {
- Target &target = process_sp->GetTarget();
- const ArchSpec target_arch = target.GetArchitecture();
- const llvm::Triple &target_triple = target_arch.GetTriple();
- if (target_triple.getVendor() == llvm::Triple::Apple &&
- (target_triple.getOS() == llvm::Triple::MacOSX
- || target_triple.getOS() == llvm::Triple::IOS
- || target_triple.getOS() == llvm::Triple::WatchOS
- || target_triple.getOS() == llvm::Triple::TvOS))
- {
- bool make_core = false;
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- make_core = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
- break;
+bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
+ const FileSpec &outfile, Error &error) {
+ if (process_sp) {
+ Target &target = process_sp->GetTarget();
+ const ArchSpec target_arch = target.GetArchitecture();
+ const llvm::Triple &target_triple = target_arch.GetTriple();
+ if (target_triple.getVendor() == llvm::Triple::Apple &&
+ (target_triple.getOS() == llvm::Triple::MacOSX ||
+ target_triple.getOS() == llvm::Triple::IOS ||
+ target_triple.getOS() == llvm::Triple::WatchOS ||
+ target_triple.getOS() == llvm::Triple::TvOS)) {
+ bool make_core = false;
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ make_core = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unsupported core architecture: %s",
+ target_triple.str().c_str());
+ break;
+ }
+
+ if (make_core) {
+ std::vector<segment_command_64> segment_load_commands;
+ // uint32_t range_info_idx = 0;
+ MemoryRegionInfo range_info;
+ Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
+ const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
+ const ByteOrder byte_order = target_arch.GetByteOrder();
+ if (range_error.Success()) {
+ while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS) {
+ const addr_t addr = range_info.GetRange().GetRangeBase();
+ const addr_t size = range_info.GetRange().GetByteSize();
+
+ if (size == 0)
+ break;
+
+ // Calculate correct protections
+ uint32_t prot = 0;
+ if (range_info.GetReadable() == MemoryRegionInfo::eYes)
+ prot |= VM_PROT_READ;
+ if (range_info.GetWritable() == MemoryRegionInfo::eYes)
+ prot |= VM_PROT_WRITE;
+ if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
+ prot |= VM_PROT_EXECUTE;
+
+ // printf ("[%3u] [0x%16.16" PRIx64 " -
+ // 0x%16.16" PRIx64 ") %c%c%c\n",
+ // range_info_idx,
+ // addr,
+ // size,
+ // (prot & VM_PROT_READ ) ? 'r' :
+ // '-',
+ // (prot & VM_PROT_WRITE ) ? 'w' :
+ // '-',
+ // (prot & VM_PROT_EXECUTE) ? 'x' :
+ // '-');
+
+ if (prot != 0) {
+ uint32_t cmd_type = LC_SEGMENT_64;
+ uint32_t segment_size = sizeof(segment_command_64);
+ if (addr_byte_size == 4) {
+ cmd_type = LC_SEGMENT;
+ segment_size = sizeof(segment_command);
+ }
+ segment_command_64 segment = {
+ cmd_type, // uint32_t cmd;
+ segment_size, // uint32_t cmdsize;
+ {0}, // char segname[16];
+ addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
+ size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
+ 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
+ size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
+ prot, // uint32_t maxprot;
+ prot, // uint32_t initprot;
+ 0, // uint32_t nsects;
+ 0}; // uint32_t flags;
+ segment_load_commands.push_back(segment);
+ } else {
+ // No protections and a size of 1 used to be returned from old
+ // debugservers when we asked about a region that was past the
+ // last memory region and it indicates the end...
+ if (size == 1)
+ break;
}
-
- if (make_core)
- {
- std::vector<segment_command_64> segment_load_commands;
-// uint32_t range_info_idx = 0;
- MemoryRegionInfo range_info;
- Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
- const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
- const ByteOrder byte_order = target_arch.GetByteOrder();
- if (range_error.Success())
- {
- while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
- {
- const addr_t addr = range_info.GetRange().GetRangeBase();
- const addr_t size = range_info.GetRange().GetByteSize();
- if (size == 0)
- break;
-
- // Calculate correct protections
- uint32_t prot = 0;
- if (range_info.GetReadable() == MemoryRegionInfo::eYes)
- prot |= VM_PROT_READ;
- if (range_info.GetWritable() == MemoryRegionInfo::eYes)
- prot |= VM_PROT_WRITE;
- if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
- prot |= VM_PROT_EXECUTE;
-
-// printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
-// range_info_idx,
-// addr,
-// size,
-// (prot & VM_PROT_READ ) ? 'r' : '-',
-// (prot & VM_PROT_WRITE ) ? 'w' : '-',
-// (prot & VM_PROT_EXECUTE) ? 'x' : '-');
-
- if (prot != 0)
- {
- uint32_t cmd_type = LC_SEGMENT_64;
- uint32_t segment_size = sizeof (segment_command_64);
- if (addr_byte_size == 4)
- {
- cmd_type = LC_SEGMENT;
- segment_size = sizeof (segment_command);
- }
- segment_command_64 segment = {
- cmd_type, // uint32_t cmd;
- segment_size, // uint32_t cmdsize;
- {0}, // char segname[16];
- addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
- size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
- 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
- size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
- prot, // uint32_t maxprot;
- prot, // uint32_t initprot;
- 0, // uint32_t nsects;
- 0 }; // uint32_t flags;
- segment_load_commands.push_back(segment);
- }
- else
- {
- // No protections and a size of 1 used to be returned from old
- // debugservers when we asked about a region that was past the
- // last memory region and it indicates the end...
- if (size == 1)
- break;
- }
-
- range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
- if (range_error.Fail())
- break;
- }
-
- StreamString buffer (Stream::eBinary,
- addr_byte_size,
- byte_order);
+ range_error = process_sp->GetMemoryRegionInfo(
+ range_info.GetRange().GetRangeEnd(), range_info);
+ if (range_error.Fail())
+ break;
+ }
+
+ StreamString buffer(Stream::eBinary, addr_byte_size, byte_order);
+
+ mach_header_64 mach_header;
+ if (addr_byte_size == 8) {
+ mach_header.magic = MH_MAGIC_64;
+ } else {
+ mach_header.magic = MH_MAGIC;
+ }
+ mach_header.cputype = target_arch.GetMachOCPUType();
+ mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
+ mach_header.filetype = MH_CORE;
+ mach_header.ncmds = segment_load_commands.size();
+ mach_header.flags = 0;
+ mach_header.reserved = 0;
+ ThreadList &thread_list = process_sp->GetThreadList();
+ const uint32_t num_threads = thread_list.GetSize();
+
+ // Make an array of LC_THREAD data items. Each one contains
+ // the contents of the LC_THREAD load command. The data doesn't
+ // contain the load command + load command size, we will
+ // add the load command and load command size as we emit the data.
+ std::vector<StreamString> LC_THREAD_datas(num_threads);
+ for (auto &LC_THREAD_data : LC_THREAD_datas) {
+ LC_THREAD_data.GetFlags().Set(Stream::eBinary);
+ LC_THREAD_data.SetAddressByteSize(addr_byte_size);
+ LC_THREAD_data.SetByteOrder(byte_order);
+ }
+ for (uint32_t thread_idx = 0; thread_idx < num_threads;
+ ++thread_idx) {
+ ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
+ if (thread_sp) {
+ switch (mach_header.cputype) {
+ case llvm::MachO::CPU_TYPE_ARM64:
+ RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
- mach_header_64 mach_header;
- if (addr_byte_size == 8)
- {
- mach_header.magic = MH_MAGIC_64;
- }
- else
- {
- mach_header.magic = MH_MAGIC;
- }
- mach_header.cputype = target_arch.GetMachOCPUType();
- mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
- mach_header.filetype = MH_CORE;
- mach_header.ncmds = segment_load_commands.size();
- mach_header.flags = 0;
- mach_header.reserved = 0;
- ThreadList &thread_list = process_sp->GetThreadList();
- const uint32_t num_threads = thread_list.GetSize();
-
- // Make an array of LC_THREAD data items. Each one contains
- // the contents of the LC_THREAD load command. The data doesn't
- // contain the load command + load command size, we will
- // add the load command and load command size as we emit the data.
- std::vector<StreamString> LC_THREAD_datas(num_threads);
- for (auto &LC_THREAD_data : LC_THREAD_datas)
- {
- LC_THREAD_data.GetFlags().Set(Stream::eBinary);
- LC_THREAD_data.SetAddressByteSize(addr_byte_size);
- LC_THREAD_data.SetByteOrder(byte_order);
- }
- for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
- {
- ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
- if (thread_sp)
- {
- switch (mach_header.cputype)
- {
- case llvm::MachO::CPU_TYPE_ARM64:
- RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
-
- case llvm::MachO::CPU_TYPE_ARM:
- RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
-
- case llvm::MachO::CPU_TYPE_I386:
- RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
-
- case llvm::MachO::CPU_TYPE_X86_64:
- RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
- }
-
- }
- }
-
- // The size of the load command is the size of the segments...
- if (addr_byte_size == 8)
- {
- mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64);
- }
- else
- {
- mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command);
- }
-
- // and the size of all LC_THREAD load command
- for (const auto &LC_THREAD_data : LC_THREAD_datas)
- {
- ++mach_header.ncmds;
- mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
- }
+ case llvm::MachO::CPU_TYPE_ARM:
+ RegisterContextDarwin_arm_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
- printf ("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
- mach_header.magic,
- mach_header.cputype,
- mach_header.cpusubtype,
- mach_header.filetype,
- mach_header.ncmds,
- mach_header.sizeofcmds,
- mach_header.flags,
- mach_header.reserved);
-
- // Write the mach header
- buffer.PutHex32(mach_header.magic);
- buffer.PutHex32(mach_header.cputype);
- buffer.PutHex32(mach_header.cpusubtype);
- buffer.PutHex32(mach_header.filetype);
- buffer.PutHex32(mach_header.ncmds);
- buffer.PutHex32(mach_header.sizeofcmds);
- buffer.PutHex32(mach_header.flags);
- if (addr_byte_size == 8)
- {
- buffer.PutHex32(mach_header.reserved);
- }
-
- // Skip the mach header and all load commands and align to the next
- // 0x1000 byte boundary
- addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
- if (file_offset & 0x00000fff)
- {
- file_offset += 0x00001000ull;
- file_offset &= (~0x00001000ull + 1);
- }
-
- for (auto &segment : segment_load_commands)
- {
- segment.fileoff = file_offset;
- file_offset += segment.filesize;
- }
-
- // Write out all of the LC_THREAD load commands
- for (const auto &LC_THREAD_data : LC_THREAD_datas)
- {
- const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
- buffer.PutHex32(LC_THREAD);
- buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
- buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
- }
+ case llvm::MachO::CPU_TYPE_I386:
+ RegisterContextDarwin_i386_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
- // Write out all of the segment load commands
- for (const auto &segment : segment_load_commands)
- {
- printf ("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64 ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
- segment.cmd,
- segment.cmdsize,
- segment.vmaddr,
- segment.vmaddr + segment.vmsize,
- segment.fileoff,
- segment.filesize,
- segment.maxprot,
- segment.initprot,
- segment.nsects,
- segment.flags);
-
- buffer.PutHex32(segment.cmd);
- buffer.PutHex32(segment.cmdsize);
- buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
- if (addr_byte_size == 8)
- {
- buffer.PutHex64(segment.vmaddr);
- buffer.PutHex64(segment.vmsize);
- buffer.PutHex64(segment.fileoff);
- buffer.PutHex64(segment.filesize);
- }
- else
- {
- buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
- buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
- buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
- buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
- }
- buffer.PutHex32(segment.maxprot);
- buffer.PutHex32(segment.initprot);
- buffer.PutHex32(segment.nsects);
- buffer.PutHex32(segment.flags);
- }
-
- 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);
- if (error.Success())
- {
- // Read 1 page at a time
- uint8_t bytes[0x1000];
- // Write the mach header and load commands out to the core file
- size_t bytes_written = buffer.GetString().size();
- error = core_file.Write(buffer.GetString().data(), bytes_written);
- if (error.Success())
- {
- // Now write the file data for all memory segments in the process
- for (const auto &segment : segment_load_commands)
- {
- if (core_file.SeekFromStart(segment.fileoff) == -1)
- {
- error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
- break;
- }
-
- printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr);
- addr_t bytes_left = segment.vmsize;
- addr_t addr = segment.vmaddr;
- Error memory_read_error;
- while (bytes_left > 0 && error.Success())
- {
- const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
- const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
- if (bytes_read == bytes_to_read)
- {
- size_t bytes_written = bytes_read;
- error = core_file.Write(bytes, bytes_written);
- bytes_left -= bytes_read;
- addr += bytes_read;
- }
- else
- {
- // Some pages within regions are not readable, those
- // should be zero filled
- memset (bytes, 0, bytes_to_read);
- size_t bytes_written = bytes_to_read;
- error = core_file.Write(bytes, bytes_written);
- bytes_left -= bytes_to_read;
- addr += bytes_to_read;
- }
- }
- }
- }
- }
+ case llvm::MachO::CPU_TYPE_X86_64:
+ RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
+ }
+ }
+ }
+
+ // The size of the load command is the size of the segments...
+ if (addr_byte_size == 8) {
+ mach_header.sizeofcmds = segment_load_commands.size() *
+ sizeof(struct segment_command_64);
+ } else {
+ mach_header.sizeofcmds =
+ segment_load_commands.size() * sizeof(struct segment_command);
+ }
+
+ // and the size of all LC_THREAD load command
+ for (const auto &LC_THREAD_data : LC_THREAD_datas) {
+ ++mach_header.ncmds;
+ mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
+ }
+
+ printf("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x "
+ "0x%8.8x 0x%8.8x\n",
+ mach_header.magic, mach_header.cputype, mach_header.cpusubtype,
+ mach_header.filetype, mach_header.ncmds,
+ mach_header.sizeofcmds, mach_header.flags,
+ mach_header.reserved);
+
+ // Write the mach header
+ buffer.PutHex32(mach_header.magic);
+ buffer.PutHex32(mach_header.cputype);
+ buffer.PutHex32(mach_header.cpusubtype);
+ buffer.PutHex32(mach_header.filetype);
+ buffer.PutHex32(mach_header.ncmds);
+ buffer.PutHex32(mach_header.sizeofcmds);
+ buffer.PutHex32(mach_header.flags);
+ if (addr_byte_size == 8) {
+ buffer.PutHex32(mach_header.reserved);
+ }
+
+ // Skip the mach header and all load commands and align to the next
+ // 0x1000 byte boundary
+ addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
+ if (file_offset & 0x00000fff) {
+ file_offset += 0x00001000ull;
+ file_offset &= (~0x00001000ull + 1);
+ }
+
+ for (auto &segment : segment_load_commands) {
+ segment.fileoff = file_offset;
+ file_offset += segment.filesize;
+ }
+
+ // Write out all of the LC_THREAD load commands
+ for (const auto &LC_THREAD_data : LC_THREAD_datas) {
+ const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
+ buffer.PutHex32(LC_THREAD);
+ buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
+ buffer.Write(LC_THREAD_data.GetString().data(),
+ LC_THREAD_data_size);
+ }
+
+ // Write out all of the segment load commands
+ for (const auto &segment : segment_load_commands) {
+ printf("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
+ ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64
+ ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
+ segment.cmd, segment.cmdsize, segment.vmaddr,
+ segment.vmaddr + segment.vmsize, segment.fileoff,
+ segment.filesize, segment.maxprot, segment.initprot,
+ segment.nsects, segment.flags);
+
+ buffer.PutHex32(segment.cmd);
+ buffer.PutHex32(segment.cmdsize);
+ buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
+ if (addr_byte_size == 8) {
+ buffer.PutHex64(segment.vmaddr);
+ buffer.PutHex64(segment.vmsize);
+ buffer.PutHex64(segment.fileoff);
+ buffer.PutHex64(segment.filesize);
+ } else {
+ buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
+ buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
+ buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
+ buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
+ }
+ buffer.PutHex32(segment.maxprot);
+ buffer.PutHex32(segment.initprot);
+ buffer.PutHex32(segment.nsects);
+ buffer.PutHex32(segment.flags);
+ }
+
+ 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);
+ if (error.Success()) {
+ // Read 1 page at a time
+ uint8_t bytes[0x1000];
+ // Write the mach header and load commands out to the core file
+ size_t bytes_written = buffer.GetString().size();
+ error = core_file.Write(buffer.GetString().data(), bytes_written);
+ if (error.Success()) {
+ // Now write the file data for all memory segments in the process
+ for (const auto &segment : segment_load_commands) {
+ if (core_file.SeekFromStart(segment.fileoff) == -1) {
+ error.SetErrorStringWithFormat(
+ "unable to seek to offset 0x%" PRIx64 " in '%s'",
+ segment.fileoff, core_file_path.c_str());
+ break;
}
- else
- {
- error.SetErrorString("process doesn't support getting memory region info");
+
+ printf("Saving %" PRId64
+ " bytes of data for memory region at 0x%" PRIx64 "\n",
+ segment.vmsize, segment.vmaddr);
+ addr_t bytes_left = segment.vmsize;
+ addr_t addr = segment.vmaddr;
+ Error memory_read_error;
+ while (bytes_left > 0 && error.Success()) {
+ const size_t bytes_to_read =
+ bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
+ const size_t bytes_read = process_sp->ReadMemory(
+ addr, bytes, bytes_to_read, memory_read_error);
+ if (bytes_read == bytes_to_read) {
+ size_t bytes_written = bytes_read;
+ error = core_file.Write(bytes, bytes_written);
+ bytes_left -= bytes_read;
+ addr += bytes_read;
+ } else {
+ // Some pages within regions are not readable, those
+ // should be zero filled
+ memset(bytes, 0, bytes_to_read);
+ size_t bytes_written = bytes_to_read;
+ error = core_file.Write(bytes, bytes_written);
+ bytes_left -= bytes_to_read;
+ addr += bytes_to_read;
+ }
}
+ }
}
- return true; // This is the right plug to handle saving core files for this process
+ }
+ } else {
+ error.SetErrorString(
+ "process doesn't support getting memory region info");
}
+ }
+ return true; // This is the right plug to handle saving core files for
+ // this process
}
- return false;
+ }
+ return false;
}
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 251a0865e782..cac176fe2ca6 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -14,242 +14,192 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Utility/SafeMachO.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/SafeMachO.h"
//----------------------------------------------------------------------
// This class needs to be hidden as eventually belongs in a plugin that
// will export the ObjectFile protocol
//----------------------------------------------------------------------
-class ObjectFileMachO :
- public lldb_private::ObjectFile
-{
+class ObjectFileMachO : public lldb_private::ObjectFile {
public:
- ObjectFileMachO(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t offset,
- lldb::offset_t length);
-
- ObjectFileMachO(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- const lldb::ProcessSP &process_sp,
- lldb::addr_t header_addr);
-
- ~ObjectFileMachO() override = default;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::ObjectFile *
- CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length);
-
- static lldb_private::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 lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool
- SaveCore (const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Error &error);
-
- static bool
- MagicBytesMatch (lldb::DataBufferSP& data_sp,
- lldb::addr_t offset,
- lldb::addr_t length);
-
- //------------------------------------------------------------------
- // Member Functions
- //------------------------------------------------------------------
- bool
- ParseHeader() override;
-
- bool
- SetLoadAddress(lldb_private::Target &target,
- lldb::addr_t value,
- bool value_is_offset) override;
-
- lldb::ByteOrder
- GetByteOrder() const override;
-
- bool
- IsExecutable() const override;
-
- uint32_t
- GetAddressByteSize() const override;
-
- lldb::AddressClass
- GetAddressClass(lldb::addr_t file_addr) override;
-
- lldb_private::Symtab *
- GetSymtab() override;
-
- bool
- IsStripped() override;
-
- void
- CreateSections(lldb_private::SectionList &unified_section_list) override;
-
- void
- Dump(lldb_private::Stream *s) override;
-
- bool
- GetArchitecture(lldb_private::ArchSpec &arch) override;
-
- bool
- GetUUID(lldb_private::UUID* uuid) override;
-
- uint32_t
- GetDependentModules(lldb_private::FileSpecList& files) override;
-
- lldb_private::FileSpecList
- GetReExportedLibraries() override
- {
- return m_reexported_dylibs;
- }
-
- lldb_private::Address
- GetEntryPointAddress() override;
-
- lldb_private::Address
- GetHeaderAddress() override;
-
- uint32_t
- GetNumThreadContexts() override;
-
- lldb::RegisterContextSP
- GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override;
-
- ObjectFile::Type
- CalculateType() override;
-
- ObjectFile::Strata
- CalculateStrata() override;
-
- uint32_t
- GetVersion(uint32_t *versions, uint32_t num_versions) override;
-
- uint32_t
- GetMinimumOSVersion(uint32_t *versions, uint32_t num_versions) override;
-
- uint32_t
- GetSDKVersion(uint32_t *versions, uint32_t num_versions) override;
-
- bool
- GetIsDynamicLinkEditor() override;
-
- static bool
- ParseHeader (lldb_private::DataExtractor &data,
- lldb::offset_t *data_offset_ptr,
- llvm::MachO::mach_header &header);
-
- bool
- AllowAssemblyEmulationUnwindPlans () override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec *file, lldb::offset_t offset,
+ lldb::offset_t length);
+
+ ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
+
+ ~ObjectFileMachO() override = default;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::ObjectFile *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length);
+
+ static lldb_private::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 lldb_private::FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb_private::ModuleSpecList &specs);
+
+ static bool SaveCore(const lldb::ProcessSP &process_sp,
+ const lldb_private::FileSpec &outfile,
+ lldb_private::Error &error);
+
+ static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,
+ lldb::addr_t length);
+
+ //------------------------------------------------------------------
+ // Member Functions
+ //------------------------------------------------------------------
+ bool ParseHeader() override;
+
+ bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
+ bool value_is_offset) override;
+
+ lldb::ByteOrder GetByteOrder() const override;
+
+ bool IsExecutable() const override;
+
+ uint32_t GetAddressByteSize() const override;
+
+ lldb::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
+
+ lldb_private::Symtab *GetSymtab() override;
+
+ bool IsStripped() override;
+
+ void CreateSections(lldb_private::SectionList &unified_section_list) override;
+
+ void Dump(lldb_private::Stream *s) override;
+
+ bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+
+ bool GetUUID(lldb_private::UUID *uuid) override;
+
+ uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
+
+ lldb_private::FileSpecList GetReExportedLibraries() override {
+ return m_reexported_dylibs;
+ }
+
+ lldb_private::Address GetEntryPointAddress() override;
+
+ lldb_private::Address GetHeaderAddress() override;
+
+ uint32_t GetNumThreadContexts() override;
+
+ lldb::RegisterContextSP
+ GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override;
+
+ ObjectFile::Type CalculateType() override;
+
+ ObjectFile::Strata CalculateStrata() override;
+
+ uint32_t GetVersion(uint32_t *versions, uint32_t num_versions) override;
+
+ uint32_t GetMinimumOSVersion(uint32_t *versions,
+ uint32_t num_versions) override;
+
+ uint32_t GetSDKVersion(uint32_t *versions, uint32_t num_versions) override;
+
+ bool GetIsDynamicLinkEditor() override;
+
+ static bool ParseHeader(lldb_private::DataExtractor &data,
+ lldb::offset_t *data_offset_ptr,
+ llvm::MachO::mach_header &header);
+
+ bool AllowAssemblyEmulationUnwindPlans() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- static bool
- GetUUID (const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- 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);
-
- // Intended for same-host arm device debugging where lldb needs to
- // detect libraries in the shared cache and augment the nlist entries
- // with an on-disk dyld_shared_cache file. The process will record
- // the shared cache UUID so the on-disk cache can be matched or rejected
- // correctly.
- lldb_private::UUID
- GetProcessSharedCacheUUID (lldb_private::Process *);
-
- // Intended for same-host arm device debugging where lldb will read
- // shared cache libraries out of its own memory instead of the remote
- // process' memory as an optimization. If lldb's shared cache UUID
- // does not match the process' shared cache UUID, this optimization
- // should not be used.
- lldb_private::UUID
- GetLLDBSharedCacheUUID ();
-
- lldb_private::Section *
- GetMachHeaderSection();
-
- lldb::addr_t
- CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address,
- const lldb_private::Section *mach_header_section,
- const lldb_private::Section *section);
-
- lldb_private::UUID
- GetSharedCacheUUID (lldb_private::FileSpec dyld_shared_cache, const lldb::ByteOrder byte_order, const uint32_t addr_byte_size);
-
- size_t
- ParseSymtab();
-
- llvm::MachO::mach_header m_header;
- static const lldb_private::ConstString &GetSegmentNameTEXT();
- static const lldb_private::ConstString &GetSegmentNameDATA();
- static const lldb_private::ConstString &GetSegmentNameDATA_DIRTY();
- static const lldb_private::ConstString &GetSegmentNameDATA_CONST();
- static const lldb_private::ConstString &GetSegmentNameOBJC();
- static const lldb_private::ConstString &GetSegmentNameLINKEDIT();
- static const lldb_private::ConstString &GetSectionNameEHFrame();
-
- llvm::MachO::dysymtab_command m_dysymtab;
- std::vector<llvm::MachO::segment_command_64> m_mach_segments;
- std::vector<llvm::MachO::section_64> m_mach_sections;
- std::vector<uint32_t> m_min_os_versions;
- std::vector<uint32_t> m_sdk_versions;
- typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
- lldb_private::Address m_entry_point_address;
- FileRangeArray m_thread_context_offsets;
- bool m_thread_context_offsets_valid;
- lldb_private::FileSpecList m_reexported_dylibs;
- bool m_allow_assembly_emulation_unwind_plans;
+ static bool
+ GetUUID(const llvm::MachO::mach_header &header,
+ const lldb_private::DataExtractor &data,
+ 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);
+
+ // Intended for same-host arm device debugging where lldb needs to
+ // detect libraries in the shared cache and augment the nlist entries
+ // with an on-disk dyld_shared_cache file. The process will record
+ // the shared cache UUID so the on-disk cache can be matched or rejected
+ // correctly.
+ lldb_private::UUID GetProcessSharedCacheUUID(lldb_private::Process *);
+
+ // Intended for same-host arm device debugging where lldb will read
+ // shared cache libraries out of its own memory instead of the remote
+ // process' memory as an optimization. If lldb's shared cache UUID
+ // does not match the process' shared cache UUID, this optimization
+ // should not be used.
+ lldb_private::UUID GetLLDBSharedCacheUUID();
+
+ lldb_private::Section *GetMachHeaderSection();
+
+ lldb::addr_t CalculateSectionLoadAddressForMemoryImage(
+ lldb::addr_t mach_header_load_address,
+ const lldb_private::Section *mach_header_section,
+ const lldb_private::Section *section);
+
+ lldb_private::UUID
+ GetSharedCacheUUID(lldb_private::FileSpec dyld_shared_cache,
+ const lldb::ByteOrder byte_order,
+ const uint32_t addr_byte_size);
+
+ size_t ParseSymtab();
+
+ llvm::MachO::mach_header m_header;
+ static const lldb_private::ConstString &GetSegmentNameTEXT();
+ static const lldb_private::ConstString &GetSegmentNameDATA();
+ static const lldb_private::ConstString &GetSegmentNameDATA_DIRTY();
+ static const lldb_private::ConstString &GetSegmentNameDATA_CONST();
+ static const lldb_private::ConstString &GetSegmentNameOBJC();
+ static const lldb_private::ConstString &GetSegmentNameLINKEDIT();
+ static const lldb_private::ConstString &GetSectionNameEHFrame();
+
+ llvm::MachO::dysymtab_command m_dysymtab;
+ std::vector<llvm::MachO::segment_command_64> m_mach_segments;
+ std::vector<llvm::MachO::section_64> m_mach_sections;
+ std::vector<uint32_t> m_min_os_versions;
+ std::vector<uint32_t> m_sdk_versions;
+ typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
+ lldb_private::Address m_entry_point_address;
+ FileRangeArray m_thread_context_offsets;
+ bool m_thread_context_offsets_valid;
+ lldb_private::FileSpecList m_reexported_dylibs;
+ bool m_allow_assembly_emulation_unwind_plans;
};
#endif // liblldb_ObjectFileMachO_h_
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 5f5a0ab07ad6..f0647e02158b 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -14,7 +14,7 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBuffer.h"
-#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -24,858 +24,818 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
-#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
-#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
-#define OPT_HEADER_MAGIC_PE32 0x010b
-#define OPT_HEADER_MAGIC_PE32_PLUS 0x020b
+#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
+#define OPT_HEADER_MAGIC_PE32 0x010b
+#define OPT_HEADER_MAGIC_PE32_PLUS 0x020b
using namespace lldb;
using namespace lldb_private;
-void
-ObjectFilePECOFF::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- CreateMemoryInstance,
- GetModuleSpecifications,
- SaveCore);
+void ObjectFilePECOFF::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
+ CreateMemoryInstance, GetModuleSpecifications, SaveCore);
}
-void
-ObjectFilePECOFF::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ObjectFilePECOFF::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
+lldb_private::ConstString ObjectFilePECOFF::GetPluginNameStatic() {
+ static ConstString g_name("pe-coff");
+ return g_name;
+}
-lldb_private::ConstString
-ObjectFilePECOFF::GetPluginNameStatic()
-{
- static ConstString g_name("pe-coff");
- return g_name;
+const char *ObjectFilePECOFF::GetPluginDescriptionStatic() {
+ return "Portable Executable and Common Object File Format object file reader "
+ "(32 and 64 bit)";
}
-const char *
-ObjectFilePECOFF::GetPluginDescriptionStatic()
-{
- return "Portable Executable and Common Object File Format object file reader (32 and 64 bit)";
+ObjectFile *ObjectFilePECOFF::CreateInstance(const lldb::ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec *file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length) {
+ if (!data_sp) {
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) {
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length)
+ data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
+ std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF(
+ module_sp, data_sp, data_offset, file, file_offset, length));
+ if (objfile_ap.get() && objfile_ap->ParseHeader())
+ return objfile_ap.release();
+ }
+ return NULL;
}
+ObjectFile *ObjectFilePECOFF::CreateMemoryInstance(
+ const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
+ if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp))
+ return nullptr;
+ auto objfile_ap = llvm::make_unique<ObjectFilePECOFF>(
+ module_sp, data_sp, process_sp, header_addr);
+ if (objfile_ap.get() && objfile_ap->ParseHeader()) {
+ return objfile_ap.release();
+ }
+ return nullptr;
+}
-ObjectFile *
-ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length)
-{
- if (!data_sp)
- {
- data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
- data_offset = 0;
- }
+size_t ObjectFilePECOFF::GetModuleSpecifications(
+ const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, lldb::offset_t file_offset,
+ lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
+ const size_t initial_count = specs.GetSize();
- if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
- {
- // Update the data to contain the entire file if it doesn't already
- if (data_sp->GetByteSize() < length)
- data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
- std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length));
- if (objfile_ap.get() && objfile_ap->ParseHeader())
- return objfile_ap.release();
- }
- return NULL;
-}
+ if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) {
+ DataExtractor data;
+ data.SetData(data_sp, data_offset, length);
+ data.SetByteOrder(eByteOrderLittle);
-ObjectFile *
-ObjectFilePECOFF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- const lldb::ProcessSP &process_sp,
- lldb::addr_t header_addr)
-{
- return NULL;
-}
+ dos_header_t dos_header;
+ coff_header_t coff_header;
-size_t
-ObjectFilePECOFF::GetModuleSpecifications (const lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs)
-{
- const size_t initial_count = specs.GetSize();
-
- if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
- {
- DataExtractor data;
- data.SetData(data_sp, data_offset, length);
- data.SetByteOrder(eByteOrderLittle);
-
- dos_header_t dos_header;
- coff_header_t coff_header;
-
- if (ParseDOSHeader(data, dos_header))
- {
- lldb::offset_t offset = dos_header.e_lfanew;
- uint32_t pe_signature = data.GetU32(&offset);
- if (pe_signature != IMAGE_NT_SIGNATURE)
- return false;
- if (ParseCOFFHeader(data, &offset, coff_header))
- {
- ArchSpec spec;
- if (coff_header.machine == MachineAmd64)
- {
- spec.SetTriple("x86_64-pc-windows");
- specs.Append(ModuleSpec(file, spec));
- }
- else if (coff_header.machine == MachineX86)
- {
- spec.SetTriple("i386-pc-windows");
- specs.Append(ModuleSpec(file, spec));
- spec.SetTriple("i686-pc-windows");
- specs.Append(ModuleSpec(file, spec));
- }
- }
+ if (ParseDOSHeader(data, dos_header)) {
+ lldb::offset_t offset = dos_header.e_lfanew;
+ uint32_t pe_signature = data.GetU32(&offset);
+ if (pe_signature != IMAGE_NT_SIGNATURE)
+ return false;
+ if (ParseCOFFHeader(data, &offset, coff_header)) {
+ ArchSpec spec;
+ if (coff_header.machine == MachineAmd64) {
+ spec.SetTriple("x86_64-pc-windows");
+ specs.Append(ModuleSpec(file, spec));
+ } else if (coff_header.machine == MachineX86) {
+ spec.SetTriple("i386-pc-windows");
+ specs.Append(ModuleSpec(file, spec));
+ spec.SetTriple("i686-pc-windows");
+ specs.Append(ModuleSpec(file, spec));
}
+ }
}
+ }
- return specs.GetSize() - initial_count;
+ return specs.GetSize() - initial_count;
}
-bool
-ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Error &error)
-{
- return SaveMiniDump(process_sp, outfile, error);
+bool ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp,
+ const lldb_private::FileSpec &outfile,
+ lldb_private::Error &error) {
+ return SaveMiniDump(process_sp, outfile, error);
}
-
-bool
-ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp)
-{
- DataExtractor data(data_sp, eByteOrderLittle, 4);
- lldb::offset_t offset = 0;
- uint16_t magic = data.GetU16 (&offset);
- return magic == IMAGE_DOS_SIGNATURE;
+bool ObjectFilePECOFF::MagicBytesMatch(DataBufferSP &data_sp) {
+ DataExtractor data(data_sp, eByteOrderLittle, 4);
+ lldb::offset_t offset = 0;
+ uint16_t magic = data.GetU16(&offset);
+ return magic == IMAGE_DOS_SIGNATURE;
}
-lldb::SymbolType
-ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type)
-{
- // TODO: We need to complete this mapping of COFF symbol types to LLDB ones.
- // For now, here's a hack to make sure our function have types.
- const auto complex_type = coff_symbol_type >> llvm::COFF::SCT_COMPLEX_TYPE_SHIFT;
- if (complex_type == llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION)
- {
- return lldb::eSymbolTypeCode;
- }
- return lldb::eSymbolTypeInvalid;
+lldb::SymbolType ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type) {
+ // TODO: We need to complete this mapping of COFF symbol types to LLDB ones.
+ // For now, here's a hack to make sure our function have types.
+ const auto complex_type =
+ coff_symbol_type >> llvm::COFF::SCT_COMPLEX_TYPE_SHIFT;
+ if (complex_type == llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION) {
+ return lldb::eSymbolTypeCode;
+ }
+ return lldb::eSymbolTypeInvalid;
}
-ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length) :
- 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 ()
-{
- ::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));
+ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const FileSpec *file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
+ : 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() {
+ ::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));
}
-
-ObjectFilePECOFF::~ObjectFilePECOFF()
-{
+ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
+ DataBufferSP &header_data_sp,
+ const lldb::ProcessSP &process_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() {
+ ::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));
}
+ObjectFilePECOFF::~ObjectFilePECOFF() {}
-bool
-ObjectFilePECOFF::ParseHeader ()
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- m_sect_headers.clear();
- m_data.SetByteOrder (eByteOrderLittle);
- lldb::offset_t offset = 0;
-
- if (ParseDOSHeader(m_data, m_dos_header))
- {
- offset = m_dos_header.e_lfanew;
- uint32_t pe_signature = m_data.GetU32 (&offset);
- if (pe_signature != IMAGE_NT_SIGNATURE)
- return false;
- if (ParseCOFFHeader(m_data, &offset, m_coff_header))
- {
- if (m_coff_header.hdrsize > 0)
- ParseCOFFOptionalHeader(&offset);
- ParseSectionHeaders (offset);
- }
- return true;
- }
+bool ObjectFilePECOFF::ParseHeader() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ m_sect_headers.clear();
+ m_data.SetByteOrder(eByteOrderLittle);
+ lldb::offset_t offset = 0;
+
+ if (ParseDOSHeader(m_data, m_dos_header)) {
+ offset = m_dos_header.e_lfanew;
+ uint32_t pe_signature = m_data.GetU32(&offset);
+ if (pe_signature != IMAGE_NT_SIGNATURE)
+ return false;
+ if (ParseCOFFHeader(m_data, &offset, m_coff_header)) {
+ if (m_coff_header.hdrsize > 0)
+ ParseCOFFOptionalHeader(&offset);
+ ParseSectionHeaders(offset);
+ }
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-ObjectFilePECOFF::SetLoadAddress(Target &target, addr_t value, bool value_is_offset)
-{
- bool changed = false;
- ModuleSP module_sp = GetModule();
- if (module_sp)
- {
- size_t num_loaded_sections = 0;
- SectionList *section_list = GetSectionList ();
- if (section_list)
- {
- if (!value_is_offset)
- {
- value -= m_image_base;
- }
-
- const size_t num_sections = section_list->GetSize();
- size_t sect_idx = 0;
-
- for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
- {
- // Iterate through the object file sections to find all
- // of the sections that have SHF_ALLOC in their flag bits.
- SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- if (section_sp && !section_sp->IsThreadSpecific())
- {
- if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
- ++num_loaded_sections;
- }
- }
- changed = num_loaded_sections > 0;
+bool ObjectFilePECOFF::SetLoadAddress(Target &target, addr_t value,
+ bool value_is_offset) {
+ bool changed = false;
+ ModuleSP module_sp = GetModule();
+ if (module_sp) {
+ size_t num_loaded_sections = 0;
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ if (!value_is_offset) {
+ value -= m_image_base;
+ }
+
+ const size_t num_sections = section_list->GetSize();
+ size_t sect_idx = 0;
+
+ for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ // Iterate through the object file sections to find all
+ // of the sections that have SHF_ALLOC in their flag bits.
+ SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+ if (section_sp && !section_sp->IsThreadSpecific()) {
+ if (target.GetSectionLoadList().SetSectionLoadAddress(
+ section_sp, section_sp->GetFileAddress() + value))
+ ++num_loaded_sections;
}
+ }
+ changed = num_loaded_sections > 0;
}
- return changed;
+ }
+ return changed;
}
+ByteOrder ObjectFilePECOFF::GetByteOrder() const { return eByteOrderLittle; }
-ByteOrder
-ObjectFilePECOFF::GetByteOrder () const
-{
- return eByteOrderLittle;
-}
-
-bool
-ObjectFilePECOFF::IsExecutable() const
-{
- return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0;
+bool ObjectFilePECOFF::IsExecutable() const {
+ return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0;
}
-uint32_t
-ObjectFilePECOFF::GetAddressByteSize () const
-{
- if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
- return 8;
- else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
- return 4;
+uint32_t ObjectFilePECOFF::GetAddressByteSize() const {
+ if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
+ return 8;
+ else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
return 4;
+ return 4;
}
//----------------------------------------------------------------------
// NeedsEndianSwap
//
-// Return true if an endian swap needs to occur when extracting data
+// Return true if an endian swap needs to occur when extracting data
// from this file.
//----------------------------------------------------------------------
-bool
-ObjectFilePECOFF::NeedsEndianSwap() const
-{
+bool ObjectFilePECOFF::NeedsEndianSwap() const {
#if defined(__LITTLE_ENDIAN__)
- return false;
+ return false;
#else
- return true;
+ return true;
#endif
}
//----------------------------------------------------------------------
// ParseDOSHeader
//----------------------------------------------------------------------
-bool
-ObjectFilePECOFF::ParseDOSHeader (DataExtractor &data, dos_header_t &dos_header)
-{
- bool success = false;
- lldb::offset_t offset = 0;
- success = data.ValidOffsetForDataOfSize(0, sizeof(dos_header));
-
- if (success)
- {
- dos_header.e_magic = data.GetU16(&offset); // Magic number
- success = dos_header.e_magic == IMAGE_DOS_SIGNATURE;
-
- if (success)
- {
- dos_header.e_cblp = data.GetU16(&offset); // Bytes on last page of file
- dos_header.e_cp = data.GetU16(&offset); // Pages in file
- dos_header.e_crlc = data.GetU16(&offset); // Relocations
- dos_header.e_cparhdr = data.GetU16(&offset); // Size of header in paragraphs
- dos_header.e_minalloc = data.GetU16(&offset); // Minimum extra paragraphs needed
- dos_header.e_maxalloc = data.GetU16(&offset); // Maximum extra paragraphs needed
- dos_header.e_ss = data.GetU16(&offset); // Initial (relative) SS value
- dos_header.e_sp = data.GetU16(&offset); // Initial SP value
- dos_header.e_csum = data.GetU16(&offset); // Checksum
- dos_header.e_ip = data.GetU16(&offset); // Initial IP value
- dos_header.e_cs = data.GetU16(&offset); // Initial (relative) CS value
- dos_header.e_lfarlc = data.GetU16(&offset); // File address of relocation table
- dos_header.e_ovno = data.GetU16(&offset); // Overlay number
-
- dos_header.e_res[0] = data.GetU16(&offset); // Reserved words
- dos_header.e_res[1] = data.GetU16(&offset); // Reserved words
- dos_header.e_res[2] = data.GetU16(&offset); // Reserved words
- dos_header.e_res[3] = data.GetU16(&offset); // Reserved words
-
- dos_header.e_oemid = data.GetU16(&offset); // OEM identifier (for e_oeminfo)
- dos_header.e_oeminfo = data.GetU16(&offset); // OEM information; e_oemid specific
- dos_header.e_res2[0] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[1] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[2] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[3] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[4] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[5] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[6] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[7] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[8] = data.GetU16(&offset); // Reserved words
- dos_header.e_res2[9] = data.GetU16(&offset); // Reserved words
-
- dos_header.e_lfanew = data.GetU32(&offset); // File address of new exe header
- }
+bool ObjectFilePECOFF::ParseDOSHeader(DataExtractor &data,
+ dos_header_t &dos_header) {
+ bool success = false;
+ lldb::offset_t offset = 0;
+ success = data.ValidOffsetForDataOfSize(0, sizeof(dos_header));
+
+ if (success) {
+ dos_header.e_magic = data.GetU16(&offset); // Magic number
+ success = dos_header.e_magic == IMAGE_DOS_SIGNATURE;
+
+ if (success) {
+ dos_header.e_cblp = data.GetU16(&offset); // Bytes on last page of file
+ dos_header.e_cp = data.GetU16(&offset); // Pages in file
+ dos_header.e_crlc = data.GetU16(&offset); // Relocations
+ dos_header.e_cparhdr =
+ data.GetU16(&offset); // Size of header in paragraphs
+ dos_header.e_minalloc =
+ data.GetU16(&offset); // Minimum extra paragraphs needed
+ dos_header.e_maxalloc =
+ data.GetU16(&offset); // Maximum extra paragraphs needed
+ dos_header.e_ss = data.GetU16(&offset); // Initial (relative) SS value
+ dos_header.e_sp = data.GetU16(&offset); // Initial SP value
+ dos_header.e_csum = data.GetU16(&offset); // Checksum
+ dos_header.e_ip = data.GetU16(&offset); // Initial IP value
+ dos_header.e_cs = data.GetU16(&offset); // Initial (relative) CS value
+ dos_header.e_lfarlc =
+ data.GetU16(&offset); // File address of relocation table
+ dos_header.e_ovno = data.GetU16(&offset); // Overlay number
+
+ dos_header.e_res[0] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res[1] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res[2] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res[3] = data.GetU16(&offset); // Reserved words
+
+ dos_header.e_oemid =
+ data.GetU16(&offset); // OEM identifier (for e_oeminfo)
+ dos_header.e_oeminfo =
+ data.GetU16(&offset); // OEM information; e_oemid specific
+ dos_header.e_res2[0] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[1] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[2] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[3] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[4] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[5] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[6] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[7] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[8] = data.GetU16(&offset); // Reserved words
+ dos_header.e_res2[9] = data.GetU16(&offset); // Reserved words
+
+ dos_header.e_lfanew =
+ data.GetU32(&offset); // File address of new exe header
}
- if (!success)
- memset(&dos_header, 0, sizeof(dos_header));
- return success;
+ }
+ if (!success)
+ memset(&dos_header, 0, sizeof(dos_header));
+ return success;
}
-
//----------------------------------------------------------------------
// ParserCOFFHeader
//----------------------------------------------------------------------
-bool
-ObjectFilePECOFF::ParseCOFFHeader(DataExtractor &data, lldb::offset_t *offset_ptr, coff_header_t &coff_header)
-{
- bool success = data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(coff_header));
- if (success)
- {
- coff_header.machine = data.GetU16(offset_ptr);
- coff_header.nsects = data.GetU16(offset_ptr);
- coff_header.modtime = data.GetU32(offset_ptr);
- coff_header.symoff = data.GetU32(offset_ptr);
- coff_header.nsyms = data.GetU32(offset_ptr);
- coff_header.hdrsize = data.GetU16(offset_ptr);
- coff_header.flags = data.GetU16(offset_ptr);
- }
- if (!success)
- memset(&coff_header, 0, sizeof(coff_header));
- return success;
+bool ObjectFilePECOFF::ParseCOFFHeader(DataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ coff_header_t &coff_header) {
+ bool success =
+ data.ValidOffsetForDataOfSize(*offset_ptr, sizeof(coff_header));
+ if (success) {
+ coff_header.machine = data.GetU16(offset_ptr);
+ coff_header.nsects = data.GetU16(offset_ptr);
+ coff_header.modtime = data.GetU32(offset_ptr);
+ coff_header.symoff = data.GetU32(offset_ptr);
+ coff_header.nsyms = data.GetU32(offset_ptr);
+ coff_header.hdrsize = data.GetU16(offset_ptr);
+ coff_header.flags = data.GetU16(offset_ptr);
+ }
+ if (!success)
+ memset(&coff_header, 0, sizeof(coff_header));
+ return success;
}
-bool
-ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr)
-{
- bool success = false;
- const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
- if (*offset_ptr < end_offset)
- {
- success = true;
- m_coff_header_opt.magic = m_data.GetU16(offset_ptr);
- m_coff_header_opt.major_linker_version = m_data.GetU8 (offset_ptr);
- m_coff_header_opt.minor_linker_version = m_data.GetU8 (offset_ptr);
- m_coff_header_opt.code_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.data_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.bss_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.entry = m_data.GetU32(offset_ptr);
- m_coff_header_opt.code_offset = m_data.GetU32(offset_ptr);
-
- const uint32_t addr_byte_size = GetAddressByteSize ();
-
- if (*offset_ptr < end_offset)
- {
- if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
- {
- // PE32 only
- m_coff_header_opt.data_offset = m_data.GetU32(offset_ptr);
- }
- else
- m_coff_header_opt.data_offset = 0;
-
- if (*offset_ptr < end_offset)
- {
- m_coff_header_opt.image_base = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
- m_coff_header_opt.sect_alignment = m_data.GetU32(offset_ptr);
- m_coff_header_opt.file_alignment = m_data.GetU32(offset_ptr);
- m_coff_header_opt.major_os_system_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.minor_os_system_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.major_image_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.minor_image_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.major_subsystem_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.minor_subsystem_version = m_data.GetU16(offset_ptr);
- m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr);
- m_coff_header_opt.image_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.header_size = m_data.GetU32(offset_ptr);
- m_coff_header_opt.checksum = m_data.GetU32(offset_ptr);
- m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr);
- m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr);
- m_coff_header_opt.stack_reserve_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
- m_coff_header_opt.stack_commit_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
- m_coff_header_opt.heap_reserve_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
- m_coff_header_opt.heap_commit_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
- m_coff_header_opt.loader_flags = m_data.GetU32(offset_ptr);
- uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr);
- m_coff_header_opt.data_dirs.clear();
- m_coff_header_opt.data_dirs.resize(num_data_dir_entries);
- uint32_t i;
- for (i=0; i<num_data_dir_entries; i++)
- {
- m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr);
- m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr);
- }
-
- m_file_offset = m_coff_header_opt.image_base;
- m_image_base = m_coff_header_opt.image_base;
- }
+bool ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr) {
+ bool success = false;
+ const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
+ if (*offset_ptr < end_offset) {
+ success = true;
+ m_coff_header_opt.magic = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.major_linker_version = m_data.GetU8(offset_ptr);
+ m_coff_header_opt.minor_linker_version = m_data.GetU8(offset_ptr);
+ m_coff_header_opt.code_size = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.data_size = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.bss_size = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.entry = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.code_offset = m_data.GetU32(offset_ptr);
+
+ const uint32_t addr_byte_size = GetAddressByteSize();
+
+ if (*offset_ptr < end_offset) {
+ if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) {
+ // PE32 only
+ m_coff_header_opt.data_offset = m_data.GetU32(offset_ptr);
+ } else
+ m_coff_header_opt.data_offset = 0;
+
+ if (*offset_ptr < end_offset) {
+ m_coff_header_opt.image_base =
+ m_data.GetMaxU64(offset_ptr, addr_byte_size);
+ m_coff_header_opt.sect_alignment = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.file_alignment = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.major_os_system_version = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.minor_os_system_version = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.major_image_version = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.minor_image_version = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.major_subsystem_version = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.minor_subsystem_version = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.image_size = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.header_size = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.checksum = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr);
+ m_coff_header_opt.stack_reserve_size =
+ m_data.GetMaxU64(offset_ptr, addr_byte_size);
+ m_coff_header_opt.stack_commit_size =
+ m_data.GetMaxU64(offset_ptr, addr_byte_size);
+ m_coff_header_opt.heap_reserve_size =
+ m_data.GetMaxU64(offset_ptr, addr_byte_size);
+ m_coff_header_opt.heap_commit_size =
+ m_data.GetMaxU64(offset_ptr, addr_byte_size);
+ m_coff_header_opt.loader_flags = m_data.GetU32(offset_ptr);
+ uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.data_dirs.clear();
+ m_coff_header_opt.data_dirs.resize(num_data_dir_entries);
+ uint32_t i;
+ for (i = 0; i < num_data_dir_entries; i++) {
+ m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr);
+ m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr);
}
+
+ m_file_offset = m_coff_header_opt.image_base;
+ m_image_base = m_coff_header_opt.image_base;
+ }
}
- // Make sure we are on track for section data which follows
- *offset_ptr = end_offset;
- return success;
+ }
+ // Make sure we are on track for section data which follows
+ *offset_ptr = end_offset;
+ return success;
}
+DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
+ if (m_file) {
+ DataBufferSP buffer_sp(m_file.ReadFileContents(offset, size));
+ return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
+ }
+ ProcessSP process_sp(m_process_wp.lock());
+ DataExtractor data;
+ if (process_sp) {
+ auto data_ap = llvm::make_unique<DataBufferHeap>(size, 0);
+ Error readmem_error;
+ size_t bytes_read =
+ process_sp->ReadMemory(m_image_base + offset, data_ap->GetBytes(),
+ data_ap->GetByteSize(), readmem_error);
+ if (bytes_read == size) {
+ DataBufferSP buffer_sp(data_ap.release());
+ data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
+ }
+ }
+ return data;
+}
//----------------------------------------------------------------------
// ParseSectionHeaders
//----------------------------------------------------------------------
-bool
-ObjectFilePECOFF::ParseSectionHeaders (uint32_t section_header_data_offset)
-{
- const uint32_t nsects = m_coff_header.nsects;
- m_sect_headers.clear();
-
- if (nsects > 0)
- {
- const uint32_t addr_byte_size = GetAddressByteSize ();
- const size_t section_header_byte_size = nsects * sizeof(section_header_t);
- DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size));
- DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size);
+bool ObjectFilePECOFF::ParseSectionHeaders(
+ uint32_t section_header_data_offset) {
+ const uint32_t nsects = m_coff_header.nsects;
+ m_sect_headers.clear();
- lldb::offset_t offset = 0;
- if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size))
- {
- m_sect_headers.resize(nsects);
-
- for (uint32_t idx = 0; idx<nsects; ++idx)
- {
- const void *name_data = section_header_data.GetData(&offset, 8);
- if (name_data)
- {
- memcpy(m_sect_headers[idx].name, name_data, 8);
- m_sect_headers[idx].vmsize = section_header_data.GetU32(&offset);
- m_sect_headers[idx].vmaddr = section_header_data.GetU32(&offset);
- m_sect_headers[idx].size = section_header_data.GetU32(&offset);
- m_sect_headers[idx].offset = section_header_data.GetU32(&offset);
- m_sect_headers[idx].reloff = section_header_data.GetU32(&offset);
- m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset);
- m_sect_headers[idx].nreloc = section_header_data.GetU16(&offset);
- m_sect_headers[idx].nline = section_header_data.GetU16(&offset);
- m_sect_headers[idx].flags = section_header_data.GetU32(&offset);
- }
- }
+ if (nsects > 0) {
+ const size_t section_header_byte_size = nsects * sizeof(section_header_t);
+ DataExtractor section_header_data =
+ ReadImageData(section_header_data_offset, section_header_byte_size);
+
+ lldb::offset_t offset = 0;
+ if (section_header_data.ValidOffsetForDataOfSize(
+ offset, section_header_byte_size)) {
+ m_sect_headers.resize(nsects);
+
+ for (uint32_t idx = 0; idx < nsects; ++idx) {
+ const void *name_data = section_header_data.GetData(&offset, 8);
+ if (name_data) {
+ memcpy(m_sect_headers[idx].name, name_data, 8);
+ m_sect_headers[idx].vmsize = section_header_data.GetU32(&offset);
+ m_sect_headers[idx].vmaddr = section_header_data.GetU32(&offset);
+ m_sect_headers[idx].size = section_header_data.GetU32(&offset);
+ m_sect_headers[idx].offset = section_header_data.GetU32(&offset);
+ m_sect_headers[idx].reloff = section_header_data.GetU32(&offset);
+ m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset);
+ m_sect_headers[idx].nreloc = section_header_data.GetU16(&offset);
+ m_sect_headers[idx].nline = section_header_data.GetU16(&offset);
+ m_sect_headers[idx].flags = section_header_data.GetU32(&offset);
}
+ }
}
-
- return m_sect_headers.empty() == false;
+ }
+
+ return m_sect_headers.empty() == false;
}
-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);
- 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;
+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);
+ 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;
}
- sect_name = sect.name;
- return true;
-}
+
+ return false;
+ }
+ sect_name = sect.name;
+ return true;
+}
//----------------------------------------------------------------------
// GetNListSymtab
//----------------------------------------------------------------------
-Symtab *
-ObjectFilePECOFF::GetSymtab()
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_symtab_ap.get() == NULL)
- {
- SectionList *sect_list = GetSectionList();
- m_symtab_ap.reset(new Symtab(this));
- std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex());
-
- const uint32_t num_syms = m_coff_header.nsyms;
-
- if (num_syms > 0 && m_coff_header.symoff > 0)
- {
- const uint32_t symbol_size = 18;
- const uint32_t addr_byte_size = GetAddressByteSize ();
- const size_t symbol_data_size = num_syms * symbol_size;
- // Include the 4-byte string table size at the end of the symbols
- DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4));
- DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size);
- lldb::offset_t offset = symbol_data_size;
- const uint32_t strtab_size = symtab_data.GetU32 (&offset);
- DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size, strtab_size));
- DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size);
-
- // First 4 bytes should be zeroed after strtab_size has been read,
- // because it is used as offset 0 to encode a NULL string.
- uint32_t* strtab_data_start = (uint32_t*)strtab_data_sp->GetBytes();
- strtab_data_start[0] = 0;
-
- offset = 0;
- std::string symbol_name;
- Symbol *symbols = m_symtab_ap->Resize (num_syms);
- for (uint32_t i=0; i<num_syms; ++i)
- {
- coff_symbol_t symbol;
- const uint32_t symbol_offset = offset;
- const char *symbol_name_cstr = NULL;
- // If the first 4 bytes of the symbol string are zero, then they
- // are followed by a 4-byte string table offset. Else these
- // 8 bytes contain the symbol name
- if (symtab_data.GetU32 (&offset) == 0)
- {
- // Long string that doesn't fit into the symbol table name,
- // so now we must read the 4 byte string table offset
- uint32_t strtab_offset = symtab_data.GetU32 (&offset);
- symbol_name_cstr = strtab_data.PeekCStr (strtab_offset);
- symbol_name.assign (symbol_name_cstr);
- }
- else
- {
- // Short string that fits into the symbol table name which is 8 bytes
- offset += sizeof(symbol.name) - 4; // Skip remaining
- symbol_name_cstr = symtab_data.PeekCStr (symbol_offset);
- if (symbol_name_cstr == NULL)
- break;
- symbol_name.assign (symbol_name_cstr, sizeof(symbol.name));
- }
- symbol.value = symtab_data.GetU32 (&offset);
- symbol.sect = symtab_data.GetU16 (&offset);
- symbol.type = symtab_data.GetU16 (&offset);
- symbol.storage = symtab_data.GetU8 (&offset);
- symbol.naux = symtab_data.GetU8 (&offset);
- symbols[i].GetMangled ().SetValue (ConstString(symbol_name.c_str()));
- if ((int16_t)symbol.sect >= 1)
- {
- Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value);
- symbols[i].GetAddressRef() = symbol_addr;
- symbols[i].SetType(MapSymbolType(symbol.type));
- }
-
- if (symbol.naux > 0)
- {
- i += symbol.naux;
- offset += symbol_size;
- }
- }
-
+Symtab *ObjectFilePECOFF::GetSymtab() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (m_symtab_ap.get() == NULL) {
+ SectionList *sect_list = GetSectionList();
+ m_symtab_ap.reset(new Symtab(this));
+ std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex());
+
+ const uint32_t num_syms = m_coff_header.nsyms;
+
+ if (m_file && num_syms > 0 && m_coff_header.symoff > 0) {
+ const uint32_t symbol_size = 18;
+ const size_t symbol_data_size = num_syms * symbol_size;
+ // Include the 4-byte string table size at the end of the symbols
+ DataExtractor symtab_data =
+ ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
+ lldb::offset_t offset = symbol_data_size;
+ const uint32_t strtab_size = symtab_data.GetU32(&offset);
+ if (strtab_size > 0) {
+ DataExtractor strtab_data = ReadImageData(
+ m_coff_header.symoff + symbol_data_size, strtab_size);
+
+ // First 4 bytes should be zeroed after strtab_size has been read,
+ // because it is used as offset 0 to encode a NULL string.
+ uint32_t *strtab_data_start = (uint32_t *)strtab_data.GetDataStart();
+ strtab_data_start[0] = 0;
+
+ offset = 0;
+ std::string symbol_name;
+ Symbol *symbols = m_symtab_ap->Resize(num_syms);
+ for (uint32_t i = 0; i < num_syms; ++i) {
+ coff_symbol_t symbol;
+ const uint32_t symbol_offset = offset;
+ const char *symbol_name_cstr = NULL;
+ // If the first 4 bytes of the symbol string are zero, then they
+ // are followed by a 4-byte string table offset. Else these
+ // 8 bytes contain the symbol name
+ if (symtab_data.GetU32(&offset) == 0) {
+ // Long string that doesn't fit into the symbol table name,
+ // so now we must read the 4 byte string table offset
+ uint32_t strtab_offset = symtab_data.GetU32(&offset);
+ symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
+ symbol_name.assign(symbol_name_cstr);
+ } else {
+ // Short string that fits into the symbol table name which is 8
+ // bytes
+ offset += sizeof(symbol.name) - 4; // Skip remaining
+ symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
+ if (symbol_name_cstr == NULL)
+ break;
+ symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
+ }
+ symbol.value = symtab_data.GetU32(&offset);
+ symbol.sect = symtab_data.GetU16(&offset);
+ symbol.type = symtab_data.GetU16(&offset);
+ symbol.storage = symtab_data.GetU8(&offset);
+ symbol.naux = symtab_data.GetU8(&offset);
+ symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
+ if ((int16_t)symbol.sect >= 1) {
+ Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect - 1),
+ symbol.value);
+ symbols[i].GetAddressRef() = symbol_addr;
+ symbols[i].SetType(MapSymbolType(symbol.type));
}
- // Read export header
- if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size()
- && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0)
- {
- export_directory_entry export_table;
- uint32_t data_start = m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
- Address address(m_coff_header_opt.image_base + data_start, sect_list);
- DataBufferSP symtab_data_sp(m_file.ReadFileContents(address.GetSection()->GetFileOffset() + address.GetOffset(), m_coff_header_opt.data_dirs[0].vmsize));
- DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), GetAddressByteSize());
- lldb::offset_t offset = 0;
-
- // Read export_table header
- export_table.characteristics = symtab_data.GetU32(&offset);
- export_table.time_date_stamp = symtab_data.GetU32(&offset);
- export_table.major_version = symtab_data.GetU16(&offset);
- export_table.minor_version = symtab_data.GetU16(&offset);
- export_table.name = symtab_data.GetU32(&offset);
- export_table.base = symtab_data.GetU32(&offset);
- export_table.number_of_functions = symtab_data.GetU32(&offset);
- export_table.number_of_names = symtab_data.GetU32(&offset);
- export_table.address_of_functions = symtab_data.GetU32(&offset);
- export_table.address_of_names = symtab_data.GetU32(&offset);
- export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
-
- bool has_ordinal = export_table.address_of_name_ordinals != 0;
-
- lldb::offset_t name_offset = export_table.address_of_names - data_start;
- lldb::offset_t name_ordinal_offset = export_table.address_of_name_ordinals - data_start;
-
- Symbol *symbols = m_symtab_ap->Resize(export_table.number_of_names);
-
- std::string symbol_name;
-
- // Read each export table entry
- for (size_t i = 0; i < export_table.number_of_names; ++i)
- {
- uint32_t name_ordinal = has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
- uint32_t name_address = symtab_data.GetU32(&name_offset);
-
- const char* symbol_name_cstr = symtab_data.PeekCStr(name_address - data_start);
- symbol_name.assign(symbol_name_cstr);
-
- lldb::offset_t function_offset = export_table.address_of_functions - data_start + sizeof(uint32_t) * name_ordinal;
- uint32_t function_rva = symtab_data.GetU32(&function_offset);
-
- Address symbol_addr(m_coff_header_opt.image_base + function_rva, sect_list);
- symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
- symbols[i].GetAddressRef() = symbol_addr;
- symbols[i].SetType(lldb::eSymbolTypeCode);
- symbols[i].SetDebug(true);
- }
+ if (symbol.naux > 0) {
+ i += symbol.naux;
+ offset += symbol_size;
}
- m_symtab_ap->CalculateSymbolSizes();
+ }
}
- }
- return m_symtab_ap.get();
+ }
+
+ // Read export header
+ if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() &&
+ m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 &&
+ m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) {
+ export_directory_entry export_table;
+ uint32_t data_start =
+ m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
+
+ uint32_t address_rva = data_start;
+ if (m_file) {
+ Address address(m_coff_header_opt.image_base + data_start, sect_list);
+ address_rva =
+ address.GetSection()->GetFileOffset() + address.GetOffset();
+ }
+ DataExtractor symtab_data =
+ ReadImageData(address_rva, m_coff_header_opt.data_dirs[0].vmsize);
+ lldb::offset_t offset = 0;
+ // Read export_table header
+ export_table.characteristics = symtab_data.GetU32(&offset);
+ export_table.time_date_stamp = symtab_data.GetU32(&offset);
+ export_table.major_version = symtab_data.GetU16(&offset);
+ export_table.minor_version = symtab_data.GetU16(&offset);
+ export_table.name = symtab_data.GetU32(&offset);
+ export_table.base = symtab_data.GetU32(&offset);
+ export_table.number_of_functions = symtab_data.GetU32(&offset);
+ export_table.number_of_names = symtab_data.GetU32(&offset);
+ export_table.address_of_functions = symtab_data.GetU32(&offset);
+ export_table.address_of_names = symtab_data.GetU32(&offset);
+ export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
+
+ bool has_ordinal = export_table.address_of_name_ordinals != 0;
+
+ lldb::offset_t name_offset = export_table.address_of_names - data_start;
+ lldb::offset_t name_ordinal_offset =
+ export_table.address_of_name_ordinals - data_start;
+
+ Symbol *symbols = m_symtab_ap->Resize(export_table.number_of_names);
+
+ std::string symbol_name;
+
+ // Read each export table entry
+ for (size_t i = 0; i < export_table.number_of_names; ++i) {
+ uint32_t name_ordinal =
+ has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
+ uint32_t name_address = symtab_data.GetU32(&name_offset);
+
+ const char *symbol_name_cstr =
+ symtab_data.PeekCStr(name_address - data_start);
+ symbol_name.assign(symbol_name_cstr);
+
+ lldb::offset_t function_offset = export_table.address_of_functions -
+ data_start +
+ sizeof(uint32_t) * name_ordinal;
+ uint32_t function_rva = symtab_data.GetU32(&function_offset);
+
+ Address symbol_addr(m_coff_header_opt.image_base + function_rva,
+ sect_list);
+ symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
+ symbols[i].GetAddressRef() = symbol_addr;
+ symbols[i].SetType(lldb::eSymbolTypeCode);
+ symbols[i].SetDebug(true);
+ }
+ }
+ m_symtab_ap->CalculateSymbolSizes();
+ }
+ }
+ return m_symtab_ap.get();
}
-bool
-ObjectFilePECOFF::IsStripped ()
-{
- // TODO: determine this for COFF
- return false;
+bool ObjectFilePECOFF::IsStripped() {
+ // TODO: determine this for COFF
+ return false;
}
+void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
+ if (!m_sections_ap.get()) {
+ m_sections_ap.reset(new SectionList());
-
-void
-ObjectFilePECOFF::CreateSections (SectionList &unified_section_list)
-{
- if (!m_sections_ap.get())
- {
- 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());
- 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_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_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)))
- {
- 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_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_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;
- }
-
- // 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);
- }
+ 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_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_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))) {
+ 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_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_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;
}
+
+ // 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;
-}
+bool ObjectFilePECOFF::GetUUID(UUID *uuid) { return false; }
-uint32_t
-ObjectFilePECOFF::GetDependentModules (FileSpecList& files)
-{
- return 0;
+uint32_t ObjectFilePECOFF::GetDependentModules(FileSpecList &files) {
+ return 0;
}
-lldb_private::Address
-ObjectFilePECOFF::GetEntryPointAddress ()
-{
- if (m_entry_point_address.IsValid())
- return m_entry_point_address;
+lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() {
+ if (m_entry_point_address.IsValid())
+ return m_entry_point_address;
- if (!ParseHeader() || !IsExecutable())
- return m_entry_point_address;
+ if (!ParseHeader() || !IsExecutable())
+ return m_entry_point_address;
- SectionList *section_list = GetSectionList();
- addr_t offset = m_coff_header_opt.entry;
+ SectionList *section_list = GetSectionList();
+ addr_t offset = m_coff_header_opt.entry;
- if (!section_list)
- m_entry_point_address.SetOffset(offset);
- else
- m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
- return m_entry_point_address;
+ if (!section_list)
+ m_entry_point_address.SetOffset(offset);
+ else
+ m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
+ return m_entry_point_address;
}
-
//----------------------------------------------------------------------
// Dump
//
// Dump the specifics of the runtime file container (such as any headers
// segments, sections, etc).
//----------------------------------------------------------------------
-void
-ObjectFilePECOFF::Dump(Stream *s)
-{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- s->Printf("%p: ", static_cast<void*>(this));
- s->Indent();
- s->PutCString("ObjectFilePECOFF");
-
- ArchSpec header_arch;
- GetArchitecture (header_arch);
-
- *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
-
- SectionList *sections = GetSectionList();
- if (sections)
- sections->Dump(s, NULL, true, UINT32_MAX);
-
- if (m_symtab_ap.get())
- m_symtab_ap->Dump(s, NULL, eSortOrderNone);
-
- if (m_dos_header.e_magic)
- DumpDOSHeader (s, m_dos_header);
- if (m_coff_header.machine)
- {
- DumpCOFFHeader (s, m_coff_header);
- if (m_coff_header.hdrsize)
- DumpOptCOFFHeader (s, m_coff_header_opt);
- }
- s->EOL();
- DumpSectionHeaders(s);
- s->EOL();
+void ObjectFilePECOFF::Dump(Stream *s) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ s->Printf("%p: ", static_cast<void *>(this));
+ s->Indent();
+ s->PutCString("ObjectFilePECOFF");
+
+ ArchSpec header_arch;
+ GetArchitecture(header_arch);
+
+ *s << ", file = '" << m_file
+ << "', arch = " << header_arch.GetArchitectureName() << "\n";
+
+ SectionList *sections = GetSectionList();
+ if (sections)
+ sections->Dump(s, NULL, true, UINT32_MAX);
+
+ if (m_symtab_ap.get())
+ m_symtab_ap->Dump(s, NULL, eSortOrderNone);
+
+ if (m_dos_header.e_magic)
+ DumpDOSHeader(s, m_dos_header);
+ if (m_coff_header.machine) {
+ DumpCOFFHeader(s, m_coff_header);
+ if (m_coff_header.hdrsize)
+ DumpOptCOFFHeader(s, m_coff_header_opt);
}
+ s->EOL();
+ DumpSectionHeaders(s);
+ s->EOL();
+ }
}
//----------------------------------------------------------------------
@@ -883,43 +843,33 @@ ObjectFilePECOFF::Dump(Stream *s)
//
// Dump the MS-DOS header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header)
-{
- s->PutCString ("MSDOS Header\n");
- s->Printf (" e_magic = 0x%4.4x\n", header.e_magic);
- s->Printf (" e_cblp = 0x%4.4x\n", header.e_cblp);
- s->Printf (" e_cp = 0x%4.4x\n", header.e_cp);
- s->Printf (" e_crlc = 0x%4.4x\n", header.e_crlc);
- s->Printf (" e_cparhdr = 0x%4.4x\n", header.e_cparhdr);
- s->Printf (" e_minalloc = 0x%4.4x\n", header.e_minalloc);
- s->Printf (" e_maxalloc = 0x%4.4x\n", header.e_maxalloc);
- s->Printf (" e_ss = 0x%4.4x\n", header.e_ss);
- s->Printf (" e_sp = 0x%4.4x\n", header.e_sp);
- s->Printf (" e_csum = 0x%4.4x\n", header.e_csum);
- s->Printf (" e_ip = 0x%4.4x\n", header.e_ip);
- s->Printf (" e_cs = 0x%4.4x\n", header.e_cs);
- s->Printf (" e_lfarlc = 0x%4.4x\n", header.e_lfarlc);
- s->Printf (" e_ovno = 0x%4.4x\n", header.e_ovno);
- s->Printf (" e_res[4] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
- header.e_res[0],
- header.e_res[1],
- header.e_res[2],
- header.e_res[3]);
- s->Printf (" e_oemid = 0x%4.4x\n", header.e_oemid);
- s->Printf (" e_oeminfo = 0x%4.4x\n", header.e_oeminfo);
- s->Printf (" e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
- header.e_res2[0],
- header.e_res2[1],
- header.e_res2[2],
- header.e_res2[3],
- header.e_res2[4],
- header.e_res2[5],
- header.e_res2[6],
- header.e_res2[7],
- header.e_res2[8],
- header.e_res2[9]);
- s->Printf (" e_lfanew = 0x%8.8x\n", header.e_lfanew);
+void ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t &header) {
+ s->PutCString("MSDOS Header\n");
+ s->Printf(" e_magic = 0x%4.4x\n", header.e_magic);
+ s->Printf(" e_cblp = 0x%4.4x\n", header.e_cblp);
+ s->Printf(" e_cp = 0x%4.4x\n", header.e_cp);
+ s->Printf(" e_crlc = 0x%4.4x\n", header.e_crlc);
+ s->Printf(" e_cparhdr = 0x%4.4x\n", header.e_cparhdr);
+ s->Printf(" e_minalloc = 0x%4.4x\n", header.e_minalloc);
+ s->Printf(" e_maxalloc = 0x%4.4x\n", header.e_maxalloc);
+ s->Printf(" e_ss = 0x%4.4x\n", header.e_ss);
+ s->Printf(" e_sp = 0x%4.4x\n", header.e_sp);
+ s->Printf(" e_csum = 0x%4.4x\n", header.e_csum);
+ s->Printf(" e_ip = 0x%4.4x\n", header.e_ip);
+ s->Printf(" e_cs = 0x%4.4x\n", header.e_cs);
+ s->Printf(" e_lfarlc = 0x%4.4x\n", header.e_lfarlc);
+ s->Printf(" e_ovno = 0x%4.4x\n", header.e_ovno);
+ s->Printf(" e_res[4] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
+ header.e_res[0], header.e_res[1], header.e_res[2], header.e_res[3]);
+ s->Printf(" e_oemid = 0x%4.4x\n", header.e_oemid);
+ s->Printf(" e_oeminfo = 0x%4.4x\n", header.e_oeminfo);
+ s->Printf(" e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, "
+ "0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
+ header.e_res2[0], header.e_res2[1], header.e_res2[2],
+ header.e_res2[3], header.e_res2[4], header.e_res2[5],
+ header.e_res2[6], header.e_res2[7], header.e_res2[8],
+ header.e_res2[9]);
+ s->Printf(" e_lfanew = 0x%8.8x\n", header.e_lfanew);
}
//----------------------------------------------------------------------
@@ -927,16 +877,14 @@ ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header)
//
// Dump the COFF header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header)
-{
- s->PutCString ("COFF Header\n");
- s->Printf (" machine = 0x%4.4x\n", header.machine);
- s->Printf (" nsects = 0x%4.4x\n", header.nsects);
- s->Printf (" modtime = 0x%8.8x\n", header.modtime);
- s->Printf (" symoff = 0x%8.8x\n", header.symoff);
- s->Printf (" nsyms = 0x%8.8x\n", header.nsyms);
- s->Printf (" hdrsize = 0x%4.4x\n", header.hdrsize);
+void ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t &header) {
+ s->PutCString("COFF Header\n");
+ s->Printf(" machine = 0x%4.4x\n", header.machine);
+ s->Printf(" nsects = 0x%4.4x\n", header.nsects);
+ s->Printf(" modtime = 0x%8.8x\n", header.modtime);
+ s->Printf(" symoff = 0x%8.8x\n", header.symoff);
+ s->Printf(" nsyms = 0x%8.8x\n", header.nsyms);
+ s->Printf(" hdrsize = 0x%4.4x\n", header.hdrsize);
}
//----------------------------------------------------------------------
@@ -944,147 +892,145 @@ ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header)
//
// Dump the optional COFF header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, const coff_opt_header_t& header)
-{
- s->PutCString ("Optional COFF Header\n");
- s->Printf (" magic = 0x%4.4x\n", header.magic);
- s->Printf (" major_linker_version = 0x%2.2x\n", header.major_linker_version);
- s->Printf (" minor_linker_version = 0x%2.2x\n", header.minor_linker_version);
- s->Printf (" code_size = 0x%8.8x\n", header.code_size);
- s->Printf (" data_size = 0x%8.8x\n", header.data_size);
- s->Printf (" bss_size = 0x%8.8x\n", header.bss_size);
- s->Printf (" entry = 0x%8.8x\n", header.entry);
- s->Printf (" code_offset = 0x%8.8x\n", header.code_offset);
- s->Printf (" data_offset = 0x%8.8x\n", header.data_offset);
- s->Printf (" image_base = 0x%16.16" PRIx64 "\n", header.image_base);
- s->Printf (" sect_alignment = 0x%8.8x\n", header.sect_alignment);
- s->Printf (" file_alignment = 0x%8.8x\n", header.file_alignment);
- s->Printf (" major_os_system_version = 0x%4.4x\n", header.major_os_system_version);
- s->Printf (" minor_os_system_version = 0x%4.4x\n", header.minor_os_system_version);
- s->Printf (" major_image_version = 0x%4.4x\n", header.major_image_version);
- s->Printf (" minor_image_version = 0x%4.4x\n", header.minor_image_version);
- s->Printf (" major_subsystem_version = 0x%4.4x\n", header.major_subsystem_version);
- s->Printf (" minor_subsystem_version = 0x%4.4x\n", header.minor_subsystem_version);
- s->Printf (" reserved1 = 0x%8.8x\n", header.reserved1);
- s->Printf (" image_size = 0x%8.8x\n", header.image_size);
- s->Printf (" header_size = 0x%8.8x\n", header.header_size);
- s->Printf (" checksum = 0x%8.8x\n", header.checksum);
- s->Printf (" subsystem = 0x%4.4x\n", header.subsystem);
- s->Printf (" dll_flags = 0x%4.4x\n", header.dll_flags);
- s->Printf (" stack_reserve_size = 0x%16.16" PRIx64 "\n", header.stack_reserve_size);
- s->Printf (" stack_commit_size = 0x%16.16" PRIx64 "\n", header.stack_commit_size);
- s->Printf (" heap_reserve_size = 0x%16.16" PRIx64 "\n", header.heap_reserve_size);
- s->Printf (" heap_commit_size = 0x%16.16" PRIx64 "\n", header.heap_commit_size);
- s->Printf (" loader_flags = 0x%8.8x\n", header.loader_flags);
- s->Printf (" num_data_dir_entries = 0x%8.8x\n", (uint32_t)header.data_dirs.size());
- uint32_t i;
- for (i=0; i<header.data_dirs.size(); i++)
- {
- s->Printf (" data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n",
- i,
- header.data_dirs[i].vmaddr,
- header.data_dirs[i].vmsize);
- }
+void ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s,
+ const coff_opt_header_t &header) {
+ s->PutCString("Optional COFF Header\n");
+ s->Printf(" magic = 0x%4.4x\n", header.magic);
+ s->Printf(" major_linker_version = 0x%2.2x\n",
+ header.major_linker_version);
+ s->Printf(" minor_linker_version = 0x%2.2x\n",
+ header.minor_linker_version);
+ s->Printf(" code_size = 0x%8.8x\n", header.code_size);
+ s->Printf(" data_size = 0x%8.8x\n", header.data_size);
+ s->Printf(" bss_size = 0x%8.8x\n", header.bss_size);
+ s->Printf(" entry = 0x%8.8x\n", header.entry);
+ s->Printf(" code_offset = 0x%8.8x\n", header.code_offset);
+ s->Printf(" data_offset = 0x%8.8x\n", header.data_offset);
+ s->Printf(" image_base = 0x%16.16" PRIx64 "\n",
+ header.image_base);
+ s->Printf(" sect_alignment = 0x%8.8x\n", header.sect_alignment);
+ s->Printf(" file_alignment = 0x%8.8x\n", header.file_alignment);
+ s->Printf(" major_os_system_version = 0x%4.4x\n",
+ header.major_os_system_version);
+ s->Printf(" minor_os_system_version = 0x%4.4x\n",
+ header.minor_os_system_version);
+ s->Printf(" major_image_version = 0x%4.4x\n",
+ header.major_image_version);
+ s->Printf(" minor_image_version = 0x%4.4x\n",
+ header.minor_image_version);
+ s->Printf(" major_subsystem_version = 0x%4.4x\n",
+ header.major_subsystem_version);
+ s->Printf(" minor_subsystem_version = 0x%4.4x\n",
+ header.minor_subsystem_version);
+ s->Printf(" reserved1 = 0x%8.8x\n", header.reserved1);
+ s->Printf(" image_size = 0x%8.8x\n", header.image_size);
+ s->Printf(" header_size = 0x%8.8x\n", header.header_size);
+ s->Printf(" checksum = 0x%8.8x\n", header.checksum);
+ s->Printf(" subsystem = 0x%4.4x\n", header.subsystem);
+ s->Printf(" dll_flags = 0x%4.4x\n", header.dll_flags);
+ s->Printf(" stack_reserve_size = 0x%16.16" PRIx64 "\n",
+ header.stack_reserve_size);
+ s->Printf(" stack_commit_size = 0x%16.16" PRIx64 "\n",
+ header.stack_commit_size);
+ s->Printf(" heap_reserve_size = 0x%16.16" PRIx64 "\n",
+ header.heap_reserve_size);
+ s->Printf(" heap_commit_size = 0x%16.16" PRIx64 "\n",
+ header.heap_commit_size);
+ s->Printf(" loader_flags = 0x%8.8x\n", header.loader_flags);
+ s->Printf(" num_data_dir_entries = 0x%8.8x\n",
+ (uint32_t)header.data_dirs.size());
+ uint32_t i;
+ for (i = 0; i < header.data_dirs.size(); i++) {
+ s->Printf(" data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", i,
+ header.data_dirs[i].vmaddr, header.data_dirs[i].vmsize);
+ }
}
//----------------------------------------------------------------------
// DumpSectionHeader
//
// Dump a single ELF section header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFilePECOFF::DumpSectionHeader(Stream *s, const section_header_t& sh)
-{
- std::string name;
- GetSectionName(name, 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,
- sh.lineoff,
- sh.nreloc,
- sh.nline,
- sh.flags);
+void ObjectFilePECOFF::DumpSectionHeader(Stream *s,
+ const section_header_t &sh) {
+ std::string name;
+ GetSectionName(name, 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,
+ sh.lineoff, sh.nreloc, sh.nline, sh.flags);
}
-
//----------------------------------------------------------------------
// DumpSectionHeaders
//
// Dump all of the ELF section header to the specified output stream
//----------------------------------------------------------------------
-void
-ObjectFilePECOFF::DumpSectionHeaders(Stream *s)
-{
-
- s->PutCString ("Section Headers\n");
- s->PutCString ("IDX name vm addr vm size file off file size reloc off line off nreloc nline flags\n");
- s->PutCString ("==== ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ------ ------ ----------\n");
-
- uint32_t idx = 0;
- SectionHeaderCollIter pos, end = m_sect_headers.end();
-
- for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx)
- {
- s->Printf ("[%2u] ", idx);
- ObjectFilePECOFF::DumpSectionHeader(s, *pos);
- }
+void ObjectFilePECOFF::DumpSectionHeaders(Stream *s) {
+
+ s->PutCString("Section Headers\n");
+ s->PutCString("IDX name vm addr vm size file off file "
+ "size reloc off line off nreloc nline flags\n");
+ s->PutCString("==== ---------------- ---------- ---------- ---------- "
+ "---------- ---------- ---------- ------ ------ ----------\n");
+
+ uint32_t idx = 0;
+ SectionHeaderCollIter pos, end = m_sect_headers.end();
+
+ for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) {
+ s->Printf("[%2u] ", idx);
+ ObjectFilePECOFF::DumpSectionHeader(s, *pos);
+ }
}
-bool
-ObjectFilePECOFF::GetArchitecture (ArchSpec &arch)
-{
- uint16_t machine = m_coff_header.machine;
- switch (machine)
- {
- case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
- case llvm::COFF::IMAGE_FILE_MACHINE_I386:
- case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC:
- case llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP:
- case llvm::COFF::IMAGE_FILE_MACHINE_ARM:
- case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
- case llvm::COFF::IMAGE_FILE_MACHINE_THUMB:
- arch.SetArchitecture (eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE);
- return true;
- default:
- break;
- }
+bool ObjectFilePECOFF::IsWindowsSubsystem() {
+ switch (m_coff_header_opt.subsystem) {
+ case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE:
+ case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI:
+ case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI:
+ case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE_WINDOWS:
+ case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
+ case llvm::COFF::IMAGE_SUBSYSTEM_XBOX:
+ case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION:
+ return true;
+ default:
return false;
+ }
}
-ObjectFile::Type
-ObjectFilePECOFF::CalculateType()
-{
- if (m_coff_header.machine != 0)
- {
- if ((m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0)
- return eTypeExecutable;
- else
- return eTypeSharedLibrary;
- }
- return eTypeExecutable;
+bool ObjectFilePECOFF::GetArchitecture(ArchSpec &arch) {
+ uint16_t machine = m_coff_header.machine;
+ switch (machine) {
+ case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
+ case llvm::COFF::IMAGE_FILE_MACHINE_I386:
+ case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC:
+ case llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP:
+ case llvm::COFF::IMAGE_FILE_MACHINE_ARM:
+ case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
+ case llvm::COFF::IMAGE_FILE_MACHINE_THUMB:
+ arch.SetArchitecture(eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE,
+ IsWindowsSubsystem() ? llvm::Triple::Win32
+ : llvm::Triple::UnknownOS);
+ return true;
+ default:
+ break;
+ }
+ return false;
}
-ObjectFile::Strata
-ObjectFilePECOFF::CalculateStrata()
-{
- return eStrataUser;
+ObjectFile::Type ObjectFilePECOFF::CalculateType() {
+ if (m_coff_header.machine != 0) {
+ if ((m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0)
+ return eTypeExecutable;
+ else
+ return eTypeSharedLibrary;
+ }
+ return eTypeExecutable;
}
+
+ObjectFile::Strata ObjectFilePECOFF::CalculateStrata() { return eStrataUser; }
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-ObjectFilePECOFF::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ObjectFilePECOFF::GetPluginVersion()
-{
- return 1;
-}
+ConstString ObjectFilePECOFF::GetPluginName() { return GetPluginNameStatic(); }
+uint32_t ObjectFilePECOFF::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index 6c1cdbf56c6b..2313047735e0 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -18,290 +18,270 @@
// Project includes
#include "lldb/Symbol/ObjectFile.h"
-class ObjectFilePECOFF :
- public lldb_private::ObjectFile
-{
+class ObjectFilePECOFF : public lldb_private::ObjectFile {
public:
- typedef enum MachineType
- {
- MachineUnknown = 0x0,
- MachineAm33 = 0x1d3,
- MachineAmd64 = 0x8664,
- MachineArm = 0x1c0,
- MachineArmNt = 0x1c4,
- MachineArm64 = 0xaa64,
- MachineEbc = 0xebc,
- MachineX86 = 0x14c,
- MachineIA64 = 0x200,
- MachineM32R = 0x9041,
- MachineMips16 = 0x266,
- MachineMipsFpu = 0x366,
- MachineMipsFpu16 = 0x466,
- MachinePowerPc = 0x1f0,
- MachinePowerPcfp = 0x1f1,
- MachineR4000 = 0x166,
- MachineSh3 = 0x1a2,
- MachineSh3dsp = 0x1a3,
- MachineSh4 = 0x1a6,
- MachineSh5 = 0x1a8,
- MachineThumb = 0x1c2,
- MachineWcemIpsv2 = 0x169
- } MachineType;
-
- ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t file_offset,
- lldb::offset_t length);
-
- ~ObjectFilePECOFF() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static ObjectFile *
- CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- const lldb_private::FileSpec* file,
- lldb::offset_t offset,
- lldb::offset_t length);
-
- static lldb_private::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 lldb_private::FileSpec& file,
- lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset,
- lldb::offset_t file_offset,
- lldb::offset_t length,
- lldb_private::ModuleSpecList &specs);
-
- static bool
- SaveCore (const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Error &error);
-
- static bool
- MagicBytesMatch (lldb::DataBufferSP& data_sp);
-
- static lldb::SymbolType
- MapSymbolType(uint16_t coff_symbol_type);
-
- bool
- ParseHeader() override;
-
- bool
- SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override;
-
- lldb::ByteOrder
- GetByteOrder() const override;
-
- bool
- IsExecutable() const override;
-
- uint32_t
- GetAddressByteSize() const override;
-
-// virtual lldb_private::AddressClass
-// GetAddressClass (lldb::addr_t file_addr);
-
- lldb_private::Symtab *
- GetSymtab() override;
-
- bool
- IsStripped() override;
-
- void
- CreateSections(lldb_private::SectionList &unified_section_list) override;
-
- void
- Dump(lldb_private::Stream *s) override;
-
- bool
- GetArchitecture(lldb_private::ArchSpec &arch) override;
-
- bool
- GetUUID(lldb_private::UUID* uuid) override;
-
- uint32_t
- GetDependentModules(lldb_private::FileSpecList& files) override;
-
- virtual lldb_private::Address
- GetEntryPointAddress () override;
-
- ObjectFile::Type
- CalculateType() override;
-
- ObjectFile::Strata
- CalculateStrata() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ typedef enum MachineType {
+ MachineUnknown = 0x0,
+ MachineAm33 = 0x1d3,
+ MachineAmd64 = 0x8664,
+ MachineArm = 0x1c0,
+ MachineArmNt = 0x1c4,
+ MachineArm64 = 0xaa64,
+ MachineEbc = 0xebc,
+ MachineX86 = 0x14c,
+ MachineIA64 = 0x200,
+ MachineM32R = 0x9041,
+ MachineMips16 = 0x266,
+ MachineMipsFpu = 0x366,
+ MachineMipsFpu16 = 0x466,
+ MachinePowerPc = 0x1f0,
+ MachinePowerPcfp = 0x1f1,
+ MachineR4000 = 0x166,
+ MachineSh3 = 0x1a2,
+ MachineSh3dsp = 0x1a3,
+ MachineSh4 = 0x1a6,
+ MachineSh5 = 0x1a8,
+ MachineThumb = 0x1c2,
+ MachineWcemIpsv2 = 0x169
+ } MachineType;
+
+ ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length);
+
+ ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &header_data_sp,
+ const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
+
+ ~ObjectFilePECOFF() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static ObjectFile *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+
+ static lldb_private::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 lldb_private::FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb_private::ModuleSpecList &specs);
+
+ static bool SaveCore(const lldb::ProcessSP &process_sp,
+ const lldb_private::FileSpec &outfile,
+ lldb_private::Error &error);
+
+ static bool MagicBytesMatch(lldb::DataBufferSP &data_sp);
+
+ static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
+
+ bool ParseHeader() override;
+
+ bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
+ bool value_is_offset) override;
+
+ lldb::ByteOrder GetByteOrder() const override;
+
+ bool IsExecutable() const override;
+
+ uint32_t GetAddressByteSize() const override;
+
+ // virtual lldb_private::AddressClass
+ // GetAddressClass (lldb::addr_t file_addr);
+
+ lldb_private::Symtab *GetSymtab() override;
+
+ bool IsStripped() override;
+
+ void CreateSections(lldb_private::SectionList &unified_section_list) override;
+
+ void Dump(lldb_private::Stream *s) override;
+
+ bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+
+ bool GetUUID(lldb_private::UUID *uuid) override;
+
+ uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
+
+ virtual lldb_private::Address GetEntryPointAddress() override;
+
+ ObjectFile::Type CalculateType() override;
+
+ ObjectFile::Strata CalculateStrata() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ bool IsWindowsSubsystem();
+
+ lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
protected:
- bool NeedsEndianSwap() const;
-
- typedef struct dos_header { // DOS .EXE header
- uint16_t e_magic; // Magic number
- uint16_t e_cblp; // Bytes on last page of file
- uint16_t e_cp; // Pages in file
- uint16_t e_crlc; // Relocations
- uint16_t e_cparhdr; // Size of header in paragraphs
- uint16_t e_minalloc; // Minimum extra paragraphs needed
- uint16_t e_maxalloc; // Maximum extra paragraphs needed
- uint16_t e_ss; // Initial (relative) SS value
- uint16_t e_sp; // Initial SP value
- uint16_t e_csum; // Checksum
- uint16_t e_ip; // Initial IP value
- uint16_t e_cs; // Initial (relative) CS value
- uint16_t e_lfarlc; // File address of relocation table
- uint16_t e_ovno; // Overlay number
- uint16_t e_res[4]; // Reserved words
- uint16_t e_oemid; // OEM identifier (for e_oeminfo)
- uint16_t e_oeminfo; // OEM information; e_oemid specific
- uint16_t e_res2[10]; // Reserved words
- uint32_t e_lfanew; // File address of new exe header
- } dos_header_t;
-
- typedef struct coff_header {
- uint16_t machine;
- uint16_t nsects;
- uint32_t modtime;
- uint32_t symoff;
- uint32_t nsyms;
- uint16_t hdrsize;
- uint16_t flags;
- } coff_header_t;
-
- typedef struct data_directory {
- uint32_t vmaddr;
- uint32_t vmsize;
- } data_directory_t;
-
- typedef struct coff_opt_header
- {
- uint16_t magic;
- uint8_t major_linker_version;
- uint8_t minor_linker_version;
- uint32_t code_size;
- uint32_t data_size;
- uint32_t bss_size;
- uint32_t entry;
- uint32_t code_offset;
- uint32_t data_offset;
-
- uint64_t image_base;
- uint32_t sect_alignment;
- uint32_t file_alignment;
- uint16_t major_os_system_version;
- uint16_t minor_os_system_version;
- uint16_t major_image_version;
- uint16_t minor_image_version;
- uint16_t major_subsystem_version;
- uint16_t minor_subsystem_version;
- uint32_t reserved1;
- uint32_t image_size;
- uint32_t header_size;
- uint32_t checksum;
- uint16_t subsystem;
- uint16_t dll_flags;
- uint64_t stack_reserve_size;
- uint64_t stack_commit_size;
- uint64_t heap_reserve_size;
- uint64_t heap_commit_size;
- uint32_t loader_flags;
- // uint32_t num_data_dir_entries;
- std::vector<data_directory> data_dirs; // will contain num_data_dir_entries entries
- } coff_opt_header_t;
-
- typedef enum coff_data_dir_type
- {
- coff_data_dir_export_table = 0,
- coff_data_dir_import_table = 1,
- } coff_data_dir_type;
-
- typedef struct section_header {
- char name[8];
- uint32_t vmsize; // Virtual Size
- uint32_t vmaddr; // Virtual Addr
- uint32_t size; // File size
- uint32_t offset; // File offset
- uint32_t reloff; // Offset to relocations
- uint32_t lineoff;// Offset to line table entries
- uint16_t nreloc; // Number of relocation entries
- uint16_t nline; // Number of line table entries
- uint32_t flags;
- } section_header_t;
-
- typedef struct coff_symbol {
- char name[8];
- uint32_t value;
- uint16_t sect;
- uint16_t type;
- uint8_t storage;
- uint8_t naux;
- } coff_symbol_t;
-
- typedef struct export_directory_entry {
- uint32_t characteristics;
- uint32_t time_date_stamp;
- uint16_t major_version;
- uint16_t minor_version;
- uint32_t name;
- uint32_t base;
- uint32_t number_of_functions;
- uint32_t number_of_names;
- uint32_t address_of_functions;
- uint32_t address_of_names;
- uint32_t address_of_name_ordinals;
- } export_directory_entry;
-
- static bool ParseDOSHeader (lldb_private::DataExtractor &data, dos_header_t &dos_header);
- static bool ParseCOFFHeader (lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr, coff_header_t &coff_header);
- bool ParseCOFFOptionalHeader (lldb::offset_t *offset_ptr);
- bool ParseSectionHeaders (uint32_t offset);
-
- static void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t& header);
- static void DumpCOFFHeader(lldb_private::Stream *s, const coff_header_t& header);
- static void DumpOptCOFFHeader(lldb_private::Stream *s, 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);
-
- typedef std::vector<section_header_t> SectionHeaderColl;
- typedef SectionHeaderColl::iterator SectionHeaderCollIter;
- typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
+ bool NeedsEndianSwap() const;
+
+ typedef struct dos_header { // DOS .EXE header
+ uint16_t e_magic; // Magic number
+ uint16_t e_cblp; // Bytes on last page of file
+ uint16_t e_cp; // Pages in file
+ uint16_t e_crlc; // Relocations
+ uint16_t e_cparhdr; // Size of header in paragraphs
+ uint16_t e_minalloc; // Minimum extra paragraphs needed
+ uint16_t e_maxalloc; // Maximum extra paragraphs needed
+ uint16_t e_ss; // Initial (relative) SS value
+ uint16_t e_sp; // Initial SP value
+ uint16_t e_csum; // Checksum
+ uint16_t e_ip; // Initial IP value
+ uint16_t e_cs; // Initial (relative) CS value
+ uint16_t e_lfarlc; // File address of relocation table
+ uint16_t e_ovno; // Overlay number
+ uint16_t e_res[4]; // Reserved words
+ uint16_t e_oemid; // OEM identifier (for e_oeminfo)
+ uint16_t e_oeminfo; // OEM information; e_oemid specific
+ uint16_t e_res2[10]; // Reserved words
+ uint32_t e_lfanew; // File address of new exe header
+ } dos_header_t;
+
+ typedef struct coff_header {
+ uint16_t machine;
+ uint16_t nsects;
+ uint32_t modtime;
+ uint32_t symoff;
+ uint32_t nsyms;
+ uint16_t hdrsize;
+ uint16_t flags;
+ } coff_header_t;
+
+ typedef struct data_directory {
+ uint32_t vmaddr;
+ uint32_t vmsize;
+ } data_directory_t;
+
+ typedef struct coff_opt_header {
+ uint16_t magic;
+ uint8_t major_linker_version;
+ uint8_t minor_linker_version;
+ uint32_t code_size;
+ uint32_t data_size;
+ uint32_t bss_size;
+ uint32_t entry;
+ uint32_t code_offset;
+ uint32_t data_offset;
+
+ uint64_t image_base;
+ uint32_t sect_alignment;
+ uint32_t file_alignment;
+ uint16_t major_os_system_version;
+ uint16_t minor_os_system_version;
+ uint16_t major_image_version;
+ uint16_t minor_image_version;
+ uint16_t major_subsystem_version;
+ uint16_t minor_subsystem_version;
+ uint32_t reserved1;
+ uint32_t image_size;
+ uint32_t header_size;
+ uint32_t checksum;
+ uint16_t subsystem;
+ uint16_t dll_flags;
+ uint64_t stack_reserve_size;
+ uint64_t stack_commit_size;
+ uint64_t heap_reserve_size;
+ uint64_t heap_commit_size;
+ uint32_t loader_flags;
+ // uint32_t num_data_dir_entries;
+ std::vector<data_directory>
+ data_dirs; // will contain num_data_dir_entries entries
+ } coff_opt_header_t;
+
+ typedef enum coff_data_dir_type {
+ coff_data_dir_export_table = 0,
+ coff_data_dir_import_table = 1,
+ } coff_data_dir_type;
+
+ typedef struct section_header {
+ char name[8];
+ uint32_t vmsize; // Virtual Size
+ uint32_t vmaddr; // Virtual Addr
+ uint32_t size; // File size
+ uint32_t offset; // File offset
+ uint32_t reloff; // Offset to relocations
+ uint32_t lineoff; // Offset to line table entries
+ uint16_t nreloc; // Number of relocation entries
+ uint16_t nline; // Number of line table entries
+ uint32_t flags;
+ } section_header_t;
+
+ typedef struct coff_symbol {
+ char name[8];
+ uint32_t value;
+ uint16_t sect;
+ uint16_t type;
+ uint8_t storage;
+ uint8_t naux;
+ } coff_symbol_t;
+
+ typedef struct export_directory_entry {
+ uint32_t characteristics;
+ uint32_t time_date_stamp;
+ uint16_t major_version;
+ uint16_t minor_version;
+ uint32_t name;
+ uint32_t base;
+ uint32_t number_of_functions;
+ uint32_t number_of_names;
+ uint32_t address_of_functions;
+ uint32_t address_of_names;
+ uint32_t address_of_name_ordinals;
+ } export_directory_entry;
+
+ static bool ParseDOSHeader(lldb_private::DataExtractor &data,
+ dos_header_t &dos_header);
+ static bool ParseCOFFHeader(lldb_private::DataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ coff_header_t &coff_header);
+ bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
+ bool ParseSectionHeaders(uint32_t offset);
+
+ static void DumpDOSHeader(lldb_private::Stream *s,
+ const dos_header_t &header);
+ static void DumpCOFFHeader(lldb_private::Stream *s,
+ const coff_header_t &header);
+ static void DumpOptCOFFHeader(lldb_private::Stream *s,
+ 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);
+
+ typedef std::vector<section_header_t> SectionHeaderColl;
+ typedef SectionHeaderColl::iterator SectionHeaderCollIter;
+ typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
+
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;
+ 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;
};
#endif // liblldb_ObjectFilePECOFF_h_
diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
index 14c73eff2388..3fd6cdc5c9a7 100644
--- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
@@ -16,41 +16,44 @@
#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
-#include <DbgHelp.h> // for MiniDumpWriteDump
+#include <dbghelp.h> // for MiniDumpWriteDump
#endif
namespace lldb_private {
-bool
-SaveMiniDump(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Error &error)
-{
- if (!process_sp) return false;
+bool SaveMiniDump(const lldb::ProcessSP &process_sp,
+ const lldb_private::FileSpec &outfile,
+ lldb_private::Error &error) {
+ if (!process_sp)
+ return false;
#ifdef _WIN32
- HANDLE process_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_sp->GetID());
- const std::string file_name = outfile.GetCString();
- std::wstring wide_name;
- wide_name.resize(file_name.size() + 1);
- char * result_ptr = reinterpret_cast<char *>(&wide_name[0]);
- const UTF8 *error_ptr = nullptr;
- if (!llvm::ConvertUTF8toWide(sizeof(wchar_t), file_name, result_ptr, error_ptr)) {
- error.SetErrorString("cannot convert file name");
- return false;
- }
- HANDLE file_handle = ::CreateFileW(wide_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- const auto result = ::MiniDumpWriteDump(process_handle, process_sp->GetID(), file_handle,
- MiniDumpWithFullMemoryInfo, NULL, NULL, NULL);
- ::CloseHandle(file_handle);
- ::CloseHandle(process_handle);
- if (!result)
- {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return false;
- }
- return true;
-#endif
+ HANDLE process_handle = ::OpenProcess(
+ PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_sp->GetID());
+ const std::string file_name = outfile.GetCString();
+ std::wstring wide_name;
+ wide_name.resize(file_name.size() + 1);
+ char *result_ptr = reinterpret_cast<char *>(&wide_name[0]);
+ const llvm::UTF8 *error_ptr = nullptr;
+ if (!llvm::ConvertUTF8toWide(sizeof(wchar_t), file_name, result_ptr,
+ error_ptr)) {
+ error.SetErrorString("cannot convert file name");
return false;
+ }
+ HANDLE file_handle =
+ ::CreateFileW(wide_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ const auto result =
+ ::MiniDumpWriteDump(process_handle, process_sp->GetID(), file_handle,
+ MiniDumpWithFullMemoryInfo, NULL, NULL, NULL);
+ ::CloseHandle(file_handle);
+ ::CloseHandle(process_handle);
+ if (!result) {
+ error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
+ return false;
+ }
+ return true;
+#endif
+ return false;
}
-} // namesapce lldb_private
+} // namesapce lldb_private
diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h
index cbea88af1fb0..3f741dc04f51 100644
--- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h
+++ b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h
@@ -14,11 +14,10 @@
namespace lldb_private {
-bool
-SaveMiniDump(const lldb::ProcessSP &process_sp,
- const lldb_private::FileSpec &outfile,
- lldb_private::Error &error);
+bool SaveMiniDump(const lldb::ProcessSP &process_sp,
+ const lldb_private::FileSpec &outfile,
+ lldb_private::Error &error);
-} // namespace lldb_private
+} // namespace lldb_private
#endif
diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
index ec0b7014d4d4..c5a3ddee4843 100644
--- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
+++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
@@ -15,6 +15,9 @@
// 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/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -24,10 +27,10 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Interpreter/Options.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"
@@ -35,536 +38,462 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadList.h"
#include "lldb/Target/Thread.h"
-#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
-#include "Plugins/Process/Utility/RegisterContextMemory.h"
-#include "Plugins/Process/Utility/ThreadMemory.h"
+#include "lldb/Target/ThreadList.h"
using namespace lldb;
using namespace lldb_private;
-namespace
-{
+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}};
+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,
+enum {
+ ePropertyEnableGoroutines,
};
-class PluginProperties : public Properties
-{
+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);
- }
+ 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;
+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
-{
+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(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;
}
-
- ~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;
- }
+ }
+
+ 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);
+ 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;
+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::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::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);
+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;
- }
- }
+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);
+ if (!found_go_runtime)
+ return nullptr;
+ }
+ return new OperatingSystemGo(process);
}
OperatingSystemGo::OperatingSystemGo(lldb_private::Process *process)
- : OperatingSystem(process)
- , m_reginfo(new DynamicRegisterInfo)
-{
-}
+ : OperatingSystem(process), m_reginfo(new DynamicRegisterInfo) {}
OperatingSystemGo::~OperatingSystemGo() = default;
-ConstString
-OperatingSystemGo::GetPluginNameStatic()
-{
- static ConstString g_name("goroutines");
- return g_name;
+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.";
+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;
+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 (!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;
- }
+ 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;
}
- 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;
+ 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;
}
- 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;
+ 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();
-}
+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));
+uint32_t OperatingSystemGo::GetPluginVersion() { return 1; }
- if (!(m_allg_sp || Init(real_thread_list)) || (m_allg_sp && !m_allglen_sp) ||
- !GetGlobalPluginProperties()->GetEnableGoroutines())
- {
- return new_thread_list.GetSize(false) > 0;
- }
+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 (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;
+ 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.
+
+ Error err;
+ for (uint64_t i = 0; i < allglen; ++i) {
+ goroutines.push_back(CreateGoroutineAtIndex(i, err));
+ if (err.Fail()) {
+ err.PutToLog(log, "OperatingSystemGo::UpdateThreadList");
+ 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.
-
- Error err;
- for (uint64_t i = 0; i < allglen; ++i)
- {
- goroutines.push_back(CreateGoroutineAtIndex(i, err));
- if (err.Fail())
- {
- err.PutToLog(log, "OperatingSystemGo::UpdateThreadList");
- 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;
}
- // 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;
+ 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, nullptr, nullptr, goroutine.m_gobuf));
}
- for (const Goroutine &goroutine : goroutines)
- {
- if (0 /* Gidle */ == goroutine.m_status || 6 /* Gdead */ == goroutine.m_status)
- {
- continue;
+ // 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);
}
- 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, nullptr, nullptr, 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);
+ }
}
+ new_thread_list.AddThread(memory_thread);
+ }
- return new_thread_list.GetSize(false) > 0;
+ return new_thread_list.GetSize(false) > 0;
}
-void
-OperatingSystemGo::ThreadWasSelected(Thread *thread)
-{
-}
+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;
+OperatingSystemGo::CreateRegisterContextForThread(Thread *thread,
+ addr_t reg_data_addr) {
+ RegisterContextSP reg_ctx_sp;
+ if (!thread)
+ return reg_ctx_sp;
- reg_ctx_sp.reset(new RegisterContextGo(*thread, 0, *m_reginfo, reg_data_addr));
+ 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;
+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));
+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);
+ if (log)
+ log->Printf("OperatingSystemGo::CreateThread (tid = 0x%" PRIx64
+ ", context = 0x%" PRIx64 ") not implemented",
+ tid, context);
- return ThreadSP();
+ return ThreadSP();
}
-ValueObjectSP
-OperatingSystemGo::FindGlobal(TargetSP target, const char *name)
-{
- VariableList variable_list;
- const bool append = true;
-
- 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), append, 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();
+ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) {
+ VariableList variable_list;
+ const bool append = true;
+
+ 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), append, 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;
- }
+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));
+ }
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
- if (log)
- log->Printf("OperatingSystemGo::FindType(%s): not found", name);
- return TypeSP();
+ if (log)
+ log->Printf("OperatingSystemGo::FindType(%s): not found", name);
+ return TypeSP();
}
OperatingSystemGo::Goroutine
-OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &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;
- }
+OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &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
index d3391d907dfe..d289985c72ad 100644
--- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h
+++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h
@@ -20,68 +20,71 @@
class DynamicRegisterInfo;
-class OperatingSystemGo : public lldb_private::OperatingSystem
-{
+class OperatingSystemGo : public lldb_private::OperatingSystem {
public:
- OperatingSystemGo(lldb_private::Process *process);
+ OperatingSystemGo(lldb_private::Process *process);
- ~OperatingSystemGo() override;
+ ~OperatingSystemGo() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static lldb_private::OperatingSystem *CreateInstance(lldb_private::Process *process, bool force);
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static lldb_private::OperatingSystem *
+ CreateInstance(lldb_private::Process *process, bool force);
- static void Initialize();
+ static void Initialize();
- static void DebuggerInitialize(lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- static void Terminate();
+ static void Terminate();
- static lldb_private::ConstString GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
- // lldb_private::PluginInterface Methods
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
+ //------------------------------------------------------------------
+ // lldb_private::PluginInterface Methods
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t GetPluginVersion() 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;
+ //------------------------------------------------------------------
+ // 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;
+ void ThreadWasSelected(lldb_private::Thread *thread) override;
- lldb::RegisterContextSP CreateRegisterContextForThread(lldb_private::Thread *thread,
- lldb::addr_t reg_data_addr) override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForThread(lldb_private::Thread *thread,
+ lldb::addr_t reg_data_addr) override;
- lldb::StopInfoSP CreateThreadStopReason(lldb_private::Thread *thread) 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;
+ //------------------------------------------------------------------
+ // Method for lazy creation of threads on demand
+ //------------------------------------------------------------------
+ lldb::ThreadSP CreateThread(lldb::tid_t tid, lldb::addr_t context) override;
private:
- struct Goroutine;
+ struct Goroutine;
- static lldb::ValueObjectSP FindGlobal(lldb::TargetSP target, const char *name);
+ static lldb::ValueObjectSP FindGlobal(lldb::TargetSP target,
+ const char *name);
- static lldb::TypeSP FindType(lldb::TargetSP target_sp, const char *name);
+ static lldb::TypeSP FindType(lldb::TargetSP target_sp, const char *name);
- bool Init(lldb_private::ThreadList &threads);
+ bool Init(lldb_private::ThreadList &threads);
- Goroutine CreateGoroutineAtIndex(uint64_t idx, lldb_private::Error &err);
+ Goroutine CreateGoroutineAtIndex(uint64_t idx, lldb_private::Error &err);
- std::unique_ptr<DynamicRegisterInfo> m_reginfo;
- lldb::ValueObjectSP m_allg_sp;
- lldb::ValueObjectSP m_allglen_sp;
+ 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 dfb631e399f1..69826a0f638c 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -1,4 +1,4 @@
-//===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===//
+//===-- OperatingSystemPython.cpp --------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,6 +13,10 @@
// 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"
+#include "Plugins/Process/Utility/ThreadMemory.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
@@ -29,395 +33,385 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadList.h"
#include "lldb/Target/Thread.h"
-#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
-#include "Plugins/Process/Utility/RegisterContextDummy.h"
-#include "Plugins/Process/Utility/RegisterContextMemory.h"
-#include "Plugins/Process/Utility/ThreadMemory.h"
+#include "lldb/Target/ThreadList.h"
using namespace lldb;
using namespace lldb_private;
-void
-OperatingSystemPython::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, nullptr);
+void OperatingSystemPython::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ nullptr);
}
-void
-OperatingSystemPython::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void OperatingSystemPython::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-OperatingSystem *
-OperatingSystemPython::CreateInstance (Process *process, bool force)
-{
- // Python OperatingSystem plug-ins must be requested by name, so force must be true
- FileSpec python_os_plugin_spec (process->GetPythonOSPluginPath());
- if (python_os_plugin_spec && python_os_plugin_spec.Exists())
- {
- std::unique_ptr<OperatingSystemPython> os_ap (new OperatingSystemPython (process, python_os_plugin_spec));
- if (os_ap.get() && os_ap->IsValid())
- return os_ap.release();
- }
- return NULL;
+OperatingSystem *OperatingSystemPython::CreateInstance(Process *process,
+ bool force) {
+ // Python OperatingSystem plug-ins must be requested by name, so force must be
+ // true
+ FileSpec python_os_plugin_spec(process->GetPythonOSPluginPath());
+ if (python_os_plugin_spec && python_os_plugin_spec.Exists()) {
+ std::unique_ptr<OperatingSystemPython> os_ap(
+ new OperatingSystemPython(process, python_os_plugin_spec));
+ if (os_ap.get() && os_ap->IsValid())
+ return os_ap.release();
+ }
+ return NULL;
}
-
-ConstString
-OperatingSystemPython::GetPluginNameStatic()
-{
- static ConstString g_name("python");
- return g_name;
+ConstString OperatingSystemPython::GetPluginNameStatic() {
+ static ConstString g_name("python");
+ return g_name;
}
-const char *
-OperatingSystemPython::GetPluginDescriptionStatic()
-{
- return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality.";
+const char *OperatingSystemPython::GetPluginDescriptionStatic() {
+ return "Operating system plug-in that gathers OS information from a python "
+ "class that implements the necessary OperatingSystem functionality.";
}
-
-OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process, const FileSpec &python_module_path) :
- OperatingSystem (process),
- m_thread_list_valobj_sp (),
- m_register_info_ap (),
- m_interpreter (NULL),
- m_python_object_sp ()
-{
- if (!process)
- return;
- TargetSP target_sp = process->CalculateTarget();
- if (!target_sp)
- return;
- m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (m_interpreter)
- {
-
- std::string os_plugin_class_name (python_module_path.GetFilename().AsCString(""));
- if (!os_plugin_class_name.empty())
- {
- const bool init_session = false;
- const bool allow_reload = true;
- char python_module_path_cstr[PATH_MAX];
- python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr));
- Error error;
- if (m_interpreter->LoadScriptingModule (python_module_path_cstr, allow_reload, init_session, error))
- {
- // Strip the ".py" extension if there is one
- size_t py_extension_pos = os_plugin_class_name.rfind(".py");
- if (py_extension_pos != std::string::npos)
- os_plugin_class_name.erase (py_extension_pos);
- // Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn"
- os_plugin_class_name += ".OperatingSystemPlugIn";
- StructuredData::ObjectSP object_sp =
- m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess());
- if (object_sp && object_sp->IsValid())
- m_python_object_sp = object_sp;
- }
- }
+OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process,
+ const FileSpec &python_module_path)
+ : OperatingSystem(process), m_thread_list_valobj_sp(), m_register_info_ap(),
+ m_interpreter(NULL), m_python_object_sp() {
+ if (!process)
+ return;
+ TargetSP target_sp = process->CalculateTarget();
+ if (!target_sp)
+ return;
+ m_interpreter =
+ target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ if (m_interpreter) {
+
+ std::string os_plugin_class_name(
+ python_module_path.GetFilename().AsCString(""));
+ if (!os_plugin_class_name.empty()) {
+ const bool init_session = false;
+ const bool allow_reload = true;
+ char python_module_path_cstr[PATH_MAX];
+ python_module_path.GetPath(python_module_path_cstr,
+ sizeof(python_module_path_cstr));
+ Error error;
+ if (m_interpreter->LoadScriptingModule(
+ python_module_path_cstr, allow_reload, init_session, error)) {
+ // Strip the ".py" extension if there is one
+ size_t py_extension_pos = os_plugin_class_name.rfind(".py");
+ if (py_extension_pos != std::string::npos)
+ os_plugin_class_name.erase(py_extension_pos);
+ // Add ".OperatingSystemPlugIn" to the module name to get a string like
+ // "modulename.OperatingSystemPlugIn"
+ os_plugin_class_name += ".OperatingSystemPlugIn";
+ StructuredData::ObjectSP object_sp =
+ m_interpreter->OSPlugin_CreatePluginObject(
+ os_plugin_class_name.c_str(), process->CalculateProcess());
+ if (object_sp && object_sp->IsValid())
+ m_python_object_sp = object_sp;
+ }
}
+ }
}
-OperatingSystemPython::~OperatingSystemPython ()
-{
-}
+OperatingSystemPython::~OperatingSystemPython() {}
-DynamicRegisterInfo *
-OperatingSystemPython::GetDynamicRegisterInfo ()
-{
- if (m_register_info_ap.get() == NULL)
- {
- if (!m_interpreter || !m_python_object_sp)
- return NULL;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS));
-
- if (log)
- log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID());
-
- StructuredData::DictionarySP dictionary = m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp);
- if (!dictionary)
- return NULL;
-
- m_register_info_ap.reset(new DynamicRegisterInfo(*dictionary, m_process->GetTarget().GetArchitecture()));
- assert (m_register_info_ap->GetNumRegisters() > 0);
- assert (m_register_info_ap->GetNumRegisterSets() > 0);
- }
- return m_register_info_ap.get();
+DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
+ if (m_register_info_ap.get() == NULL) {
+ if (!m_interpreter || !m_python_object_sp)
+ return NULL;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
+
+ if (log)
+ log->Printf("OperatingSystemPython::GetDynamicRegisterInfo() fetching "
+ "thread register definitions from python for pid %" PRIu64,
+ m_process->GetID());
+
+ StructuredData::DictionarySP dictionary =
+ m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp);
+ if (!dictionary)
+ return NULL;
+
+ m_register_info_ap.reset(new DynamicRegisterInfo(
+ *dictionary, m_process->GetTarget().GetArchitecture()));
+ assert(m_register_info_ap->GetNumRegisters() > 0);
+ assert(m_register_info_ap->GetNumRegisterSets() > 0);
+ }
+ return m_register_info_ap.get();
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-OperatingSystemPython::GetPluginName()
-{
- return GetPluginNameStatic();
+ConstString OperatingSystemPython::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-OperatingSystemPython::GetPluginVersion()
-{
- return 1;
-}
-
-bool
-OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list,
- ThreadList &core_thread_list,
- ThreadList &new_thread_list)
-{
- if (!m_interpreter || !m_python_object_sp)
- return false;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS));
-
- // First thing we have to do is to try to get the API lock, and the run lock.
- // We're going to change the thread content of the process, and we're going
- // to use python, which requires the API lock to do it.
- //
- // If someone already has the API lock, that is ok, we just want to avoid
- // external code from making new API calls while this call is happening.
- //
- // This is a recursive lock so we can grant it to any Python code called on
- // the stack below us.
- Target &target = m_process->GetTarget();
- std::unique_lock<std::recursive_mutex> lock(target.GetAPIMutex(), std::defer_lock);
- lock.try_lock();
-
- if (log)
- log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %" PRIu64, m_process->GetID());
-
- // The threads that are in "new_thread_list" upon entry are the threads from the
- // lldb_private::Process subclass, no memory threads will be in this list.
-
- auto interpreter_lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive
- StructuredData::ArraySP threads_list = m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp);
-
- const uint32_t num_cores = core_thread_list.GetSize(false);
-
- // Make a map so we can keep track of which cores were used from the
- // core_thread list. Any real threads/cores that weren't used should
- // later be put back into the "new_thread_list".
- std::vector<bool> core_used_map(num_cores, false);
- if (threads_list)
- {
- if (log)
- {
- StreamString strm;
- threads_list->Dump(strm);
- log->Printf("threads_list = %s", strm.GetString().c_str());
- }
-
- const uint32_t num_threads = threads_list->GetSize();
- for (uint32_t i = 0; i < num_threads; ++i)
- {
- StructuredData::ObjectSP thread_dict_obj = threads_list->GetItemAtIndex(i);
- if (auto thread_dict = thread_dict_obj->GetAsDictionary())
- {
- ThreadSP thread_sp(CreateThreadFromThreadInfo(*thread_dict, core_thread_list, old_thread_list, core_used_map, NULL));
- if (thread_sp)
- new_thread_list.AddThread(thread_sp);
- }
- }
+uint32_t OperatingSystemPython::GetPluginVersion() { return 1; }
+
+bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &core_thread_list,
+ ThreadList &new_thread_list) {
+ if (!m_interpreter || !m_python_object_sp)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
+
+ // First thing we have to do is to try to get the API lock, and the run lock.
+ // We're going to change the thread content of the process, and we're going
+ // to use python, which requires the API lock to do it.
+ //
+ // If someone already has the API lock, that is ok, we just want to avoid
+ // external code from making new API calls while this call is happening.
+ //
+ // This is a recursive lock so we can grant it to any Python code called on
+ // the stack below us.
+ Target &target = m_process->GetTarget();
+ std::unique_lock<std::recursive_mutex> lock(target.GetAPIMutex(),
+ std::defer_lock);
+ lock.try_lock();
+
+ if (log)
+ log->Printf("OperatingSystemPython::UpdateThreadList() fetching thread "
+ "data from python for pid %" PRIu64,
+ m_process->GetID());
+
+ // The threads that are in "new_thread_list" upon entry are the threads from
+ // the
+ // lldb_private::Process subclass, no memory threads will be in this list.
+
+ auto interpreter_lock =
+ m_interpreter
+ ->AcquireInterpreterLock(); // to make sure threads_list stays alive
+ StructuredData::ArraySP threads_list =
+ m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp);
+
+ const uint32_t num_cores = core_thread_list.GetSize(false);
+
+ // Make a map so we can keep track of which cores were used from the
+ // core_thread list. Any real threads/cores that weren't used should
+ // later be put back into the "new_thread_list".
+ std::vector<bool> core_used_map(num_cores, false);
+ if (threads_list) {
+ if (log) {
+ StreamString strm;
+ threads_list->Dump(strm);
+ log->Printf("threads_list = %s", strm.GetData());
}
- // Any real core threads that didn't end up backing a memory thread should
- // still be in the main thread list, and they should be inserted at the beginning
- // of the list
- uint32_t insert_idx = 0;
- for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx)
- {
- if (core_used_map[core_idx] == false)
- {
- new_thread_list.InsertThread (core_thread_list.GetThreadAtIndex(core_idx, false), insert_idx);
- ++insert_idx;
- }
+ const uint32_t num_threads = threads_list->GetSize();
+ for (uint32_t i = 0; i < num_threads; ++i) {
+ StructuredData::ObjectSP thread_dict_obj =
+ threads_list->GetItemAtIndex(i);
+ if (auto thread_dict = thread_dict_obj->GetAsDictionary()) {
+ ThreadSP thread_sp(
+ CreateThreadFromThreadInfo(*thread_dict, core_thread_list,
+ old_thread_list, core_used_map, NULL));
+ if (thread_sp)
+ new_thread_list.AddThread(thread_sp);
+ }
}
+ }
+
+ // Any real core threads that didn't end up backing a memory thread should
+ // still be in the main thread list, and they should be inserted at the
+ // beginning
+ // of the list
+ uint32_t insert_idx = 0;
+ for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx) {
+ if (core_used_map[core_idx] == false) {
+ new_thread_list.InsertThread(
+ core_thread_list.GetThreadAtIndex(core_idx, false), insert_idx);
+ ++insert_idx;
+ }
+ }
- return new_thread_list.GetSize(false) > 0;
+ return new_thread_list.GetSize(false) > 0;
}
-ThreadSP
-OperatingSystemPython::CreateThreadFromThreadInfo(StructuredData::Dictionary &thread_dict, ThreadList &core_thread_list,
- ThreadList &old_thread_list, std::vector<bool> &core_used_map, bool *did_create_ptr)
-{
- ThreadSP thread_sp;
- tid_t tid = LLDB_INVALID_THREAD_ID;
- if (!thread_dict.GetValueForKeyAsInteger("tid", tid))
- return ThreadSP();
-
- uint32_t core_number;
- addr_t reg_data_addr;
- std::string name;
- std::string queue;
-
- thread_dict.GetValueForKeyAsInteger("core", core_number, UINT32_MAX);
- thread_dict.GetValueForKeyAsInteger("register_data_addr", reg_data_addr, LLDB_INVALID_ADDRESS);
- thread_dict.GetValueForKeyAsString("name", name);
- thread_dict.GetValueForKeyAsString("queue", queue);
-
- // See if a thread already exists for "tid"
- thread_sp = old_thread_list.FindThreadByID(tid, false);
- if (thread_sp)
- {
- // A thread already does exist for "tid", make sure it was an operating system
- // plug-in generated thread.
- if (!IsOperatingSystemPluginThread(thread_sp))
- {
- // We have thread ID overlap between the protocol threads and the
- // operating system threads, clear the thread so we create an
- // operating system thread for this.
- thread_sp.reset();
- }
- }
+ThreadSP OperatingSystemPython::CreateThreadFromThreadInfo(
+ StructuredData::Dictionary &thread_dict, ThreadList &core_thread_list,
+ ThreadList &old_thread_list, std::vector<bool> &core_used_map,
+ bool *did_create_ptr) {
+ ThreadSP thread_sp;
+ tid_t tid = LLDB_INVALID_THREAD_ID;
+ if (!thread_dict.GetValueForKeyAsInteger("tid", tid))
+ return ThreadSP();
- if (!thread_sp)
- {
- if (did_create_ptr)
- *did_create_ptr = true;
- thread_sp.reset(new ThreadMemory(*m_process, tid, name.c_str(), queue.c_str(), reg_data_addr));
+ uint32_t core_number;
+ addr_t reg_data_addr;
+ std::string name;
+ std::string queue;
+
+ thread_dict.GetValueForKeyAsInteger("core", core_number, UINT32_MAX);
+ thread_dict.GetValueForKeyAsInteger("register_data_addr", reg_data_addr,
+ LLDB_INVALID_ADDRESS);
+ thread_dict.GetValueForKeyAsString("name", name);
+ thread_dict.GetValueForKeyAsString("queue", queue);
+
+ // See if a thread already exists for "tid"
+ thread_sp = old_thread_list.FindThreadByID(tid, false);
+ if (thread_sp) {
+ // A thread already does exist for "tid", make sure it was an operating
+ // system
+ // plug-in generated thread.
+ if (!IsOperatingSystemPluginThread(thread_sp)) {
+ // We have thread ID overlap between the protocol threads and the
+ // operating system threads, clear the thread so we create an
+ // operating system thread for this.
+ thread_sp.reset();
}
-
- if (core_number < core_thread_list.GetSize(false))
- {
- ThreadSP core_thread_sp(core_thread_list.GetThreadAtIndex(core_number, false));
- if (core_thread_sp)
- {
- // Keep track of which cores were set as the backing thread for memory threads...
- if (core_number < core_used_map.size())
- core_used_map[core_number] = true;
-
- ThreadSP backing_core_thread_sp(core_thread_sp->GetBackingThread());
- if (backing_core_thread_sp)
- {
- thread_sp->SetBackingThread(backing_core_thread_sp);
- }
- else
- {
- thread_sp->SetBackingThread(core_thread_sp);
- }
- }
+ }
+
+ if (!thread_sp) {
+ if (did_create_ptr)
+ *did_create_ptr = true;
+ thread_sp.reset(new ThreadMemory(*m_process, tid, name.c_str(),
+ queue.c_str(), reg_data_addr));
+ }
+
+ if (core_number < core_thread_list.GetSize(false)) {
+ ThreadSP core_thread_sp(
+ core_thread_list.GetThreadAtIndex(core_number, false));
+ if (core_thread_sp) {
+ // Keep track of which cores were set as the backing thread for memory
+ // threads...
+ if (core_number < core_used_map.size())
+ core_used_map[core_number] = true;
+
+ ThreadSP backing_core_thread_sp(core_thread_sp->GetBackingThread());
+ if (backing_core_thread_sp) {
+ thread_sp->SetBackingThread(backing_core_thread_sp);
+ } else {
+ thread_sp->SetBackingThread(core_thread_sp);
+ }
}
- return thread_sp;
+ }
+ return thread_sp;
}
-
-
-void
-OperatingSystemPython::ThreadWasSelected (Thread *thread)
-{
-}
+void OperatingSystemPython::ThreadWasSelected(Thread *thread) {}
RegisterContextSP
-OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t reg_data_addr)
-{
- RegisterContextSP reg_ctx_sp;
- if (!m_interpreter || !m_python_object_sp || !thread)
- return reg_ctx_sp;
-
- if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
- return reg_ctx_sp;
-
- // First thing we have to do is get the API lock, and the run lock. We're going to change the thread
- // content of the process, and we're going to use python, which requires the API lock to do it.
- // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
- Target &target = m_process->GetTarget();
- std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
+OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
+ addr_t reg_data_addr) {
+ RegisterContextSP reg_ctx_sp;
+ if (!m_interpreter || !m_python_object_sp || !thread)
+ return reg_ctx_sp;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
-
- auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure python objects stays alive
- if (reg_data_addr != LLDB_INVALID_ADDRESS)
- {
- // The registers data is in contiguous memory, just create the register
- // context using the address provided
- if (log)
- log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context",
- thread->GetID(),
- thread->GetProtocolID(),
- reg_data_addr);
- reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr));
- }
- else
- {
- // No register data address is provided, query the python plug-in to let
- // it make up the data as it sees fit
- if (log)
- log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ") fetching register data from python",
- thread->GetID(),
- thread->GetProtocolID());
-
- StructuredData::StringSP reg_context_data = m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp, thread->GetID());
- if (reg_context_data)
- {
- std::string value = reg_context_data->GetValue();
- DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length()));
- if (data_sp->GetByteSize())
- {
- RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS);
- if (reg_ctx_memory)
- {
- reg_ctx_sp.reset(reg_ctx_memory);
- reg_ctx_memory->SetAllRegisterData (data_sp);
- }
- }
+ if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
+ return reg_ctx_sp;
+
+ // First thing we have to do is get the API lock, and the run lock. We're
+ // going to change the thread
+ // content of the process, and we're going to use python, which requires the
+ // API lock to do it.
+ // So get & hold that. This is a recursive lock so we can grant it to any
+ // Python code called on the stack below us.
+ Target &target = m_process->GetTarget();
+ std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ auto lock =
+ m_interpreter
+ ->AcquireInterpreterLock(); // to make sure python objects stays alive
+ if (reg_data_addr != LLDB_INVALID_ADDRESS) {
+ // The registers data is in contiguous memory, just create the register
+ // context using the address provided
+ if (log)
+ log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64
+ ") creating memory register context",
+ thread->GetID(), thread->GetProtocolID(), reg_data_addr);
+ reg_ctx_sp.reset(new RegisterContextMemory(
+ *thread, 0, *GetDynamicRegisterInfo(), reg_data_addr));
+ } else {
+ // No register data address is provided, query the python plug-in to let
+ // it make up the data as it sees fit
+ if (log)
+ log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ", 0x%" PRIx64
+ ") fetching register data from python",
+ thread->GetID(), thread->GetProtocolID());
+
+ StructuredData::StringSP reg_context_data =
+ m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp,
+ thread->GetID());
+ if (reg_context_data) {
+ std::string value = reg_context_data->GetValue();
+ DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length()));
+ if (data_sp->GetByteSize()) {
+ RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory(
+ *thread, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS);
+ if (reg_ctx_memory) {
+ reg_ctx_sp.reset(reg_ctx_memory);
+ reg_ctx_memory->SetAllRegisterData(data_sp);
}
+ }
}
- // if we still have no register data, fallback on a dummy context to avoid crashing
- if (!reg_ctx_sp)
- {
- if (log)
- log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") forcing a dummy register context", thread->GetID());
- reg_ctx_sp.reset(new RegisterContextDummy(*thread,0,target.GetArchitecture().GetAddressByteSize()));
- }
- return reg_ctx_sp;
+ }
+ // if we still have no register data, fallback on a dummy context to avoid
+ // crashing
+ if (!reg_ctx_sp) {
+ if (log)
+ log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ") forcing a dummy register context",
+ thread->GetID());
+ reg_ctx_sp.reset(new RegisterContextDummy(
+ *thread, 0, target.GetArchitecture().GetAddressByteSize()));
+ }
+ return reg_ctx_sp;
}
StopInfoSP
-OperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread)
-{
- // We should have gotten the thread stop info from the dictionary of data for
- // the thread in the initial call to get_thread_info(), this should have been
- // cached so we can return it here
- StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
- return stop_info_sp;
+OperatingSystemPython::CreateThreadStopReason(lldb_private::Thread *thread) {
+ // We should have gotten the thread stop info from the dictionary of data for
+ // the thread in the initial call to get_thread_info(), this should have been
+ // cached so we can return it here
+ StopInfoSP
+ stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
+ return stop_info_sp;
}
-lldb::ThreadSP
-OperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
-
- if (log)
- log->Printf ("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") fetching register data from python", tid, context);
-
- if (m_interpreter && m_python_object_sp)
- {
- // First thing we have to do is get the API lock, and the run lock. We're going to change the thread
- // content of the process, and we're going to use python, which requires the API lock to do it.
- // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
- Target &target = m_process->GetTarget();
- std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
-
- auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive
- StructuredData::DictionarySP thread_info_dict = m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context);
- std::vector<bool> core_used_map;
- if (thread_info_dict)
- {
- ThreadList core_threads(m_process);
- ThreadList &thread_list = m_process->GetThreadList();
- bool did_create = false;
- ThreadSP thread_sp(CreateThreadFromThreadInfo(*thread_info_dict, core_threads, thread_list, core_used_map, &did_create));
- if (did_create)
- thread_list.AddThread(thread_sp);
- return thread_sp;
- }
+lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid,
+ addr_t context) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ if (log)
+ log->Printf("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64
+ ", context = 0x%" PRIx64 ") fetching register data from python",
+ tid, context);
+
+ if (m_interpreter && m_python_object_sp) {
+ // First thing we have to do is get the API lock, and the run lock. We're
+ // going to change the thread
+ // content of the process, and we're going to use python, which requires the
+ // API lock to do it.
+ // So get & hold that. This is a recursive lock so we can grant it to any
+ // Python code called on the stack below us.
+ Target &target = m_process->GetTarget();
+ std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
+
+ auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure
+ // thread_info_dict
+ // stays alive
+ StructuredData::DictionarySP thread_info_dict =
+ m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context);
+ std::vector<bool> core_used_map;
+ if (thread_info_dict) {
+ ThreadList core_threads(m_process);
+ ThreadList &thread_list = m_process->GetThreadList();
+ bool did_create = false;
+ ThreadSP thread_sp(
+ CreateThreadFromThreadInfo(*thread_info_dict, core_threads,
+ thread_list, core_used_map, &did_create));
+ if (did_create)
+ thread_list.AddThread(thread_sp);
+ return thread_sp;
}
- return ThreadSP();
+ }
+ return ThreadSP();
}
-
-
#endif // #ifndef LLDB_DISABLE_PYTHON
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
index 1b33c42cf0fe..1eec30ef38c7 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
@@ -21,87 +21,76 @@
class DynamicRegisterInfo;
-namespace lldb_private
-{
+namespace lldb_private {
class ScriptInterpreter;
}
-class OperatingSystemPython : public lldb_private::OperatingSystem
-{
+class OperatingSystemPython : public lldb_private::OperatingSystem {
public:
- OperatingSystemPython(lldb_private::Process *process,
- const lldb_private::FileSpec &python_module_path);
-
- ~OperatingSystemPython() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static lldb_private::OperatingSystem *
- CreateInstance (lldb_private::Process *process, bool force);
-
- static void
- Initialize();
-
- 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;
+ OperatingSystemPython(lldb_private::Process *process,
+ const lldb_private::FileSpec &python_module_path);
+
+ ~OperatingSystemPython() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static lldb_private::OperatingSystem *
+ CreateInstance(lldb_private::Process *process, bool force);
+
+ static void Initialize();
+
+ 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;
protected:
- bool IsValid() const
- {
- return m_python_object_sp && m_python_object_sp->IsValid();
- }
-
- lldb::ThreadSP CreateThreadFromThreadInfo(lldb_private::StructuredData::Dictionary &thread_dict,
- lldb_private::ThreadList &core_thread_list, lldb_private::ThreadList &old_thread_list,
- std::vector<bool> &core_used_map, bool *did_create_ptr);
-
- DynamicRegisterInfo *
- GetDynamicRegisterInfo ();
-
- lldb::ValueObjectSP m_thread_list_valobj_sp;
- std::unique_ptr<DynamicRegisterInfo> m_register_info_ap;
- lldb_private::ScriptInterpreter *m_interpreter;
- lldb_private::StructuredData::ObjectSP m_python_object_sp;
+ bool IsValid() const {
+ return m_python_object_sp && m_python_object_sp->IsValid();
+ }
+
+ lldb::ThreadSP CreateThreadFromThreadInfo(
+ lldb_private::StructuredData::Dictionary &thread_dict,
+ lldb_private::ThreadList &core_thread_list,
+ lldb_private::ThreadList &old_thread_list,
+ std::vector<bool> &core_used_map, bool *did_create_ptr);
+
+ DynamicRegisterInfo *GetDynamicRegisterInfo();
+
+ lldb::ValueObjectSP m_thread_list_valobj_sp;
+ std::unique_ptr<DynamicRegisterInfo> m_register_info_ap;
+ lldb_private::ScriptInterpreter *m_interpreter;
+ lldb_private::StructuredData::ObjectSP m_python_object_sp;
};
#endif // LLDB_DISABLE_PYTHON
diff --git a/source/Plugins/Platform/Android/AdbClient.cpp b/source/Plugins/Platform/Android/AdbClient.cpp
index 1b07ddba59fc..eb684ad0fbc0 100644
--- a/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/source/Plugins/Platform/Android/AdbClient.cpp
@@ -10,9 +10,9 @@
// Other libraries and framework includes
#include "AdbClient.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FileUtilities.h"
#include "lldb/Core/DataBuffer.h"
@@ -22,6 +22,8 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/PosixApi.h"
#include <limits.h>
@@ -39,667 +41,605 @@
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_android;
+using namespace std::chrono;
namespace {
-const std::chrono::seconds kReadTimeout(8);
-const char * kOKAY = "OKAY";
-const char * kFAIL = "FAIL";
-const char * kDATA = "DATA";
-const char * kDONE = "DONE";
+const seconds kReadTimeout(8);
+const char *kOKAY = "OKAY";
+const char *kFAIL = "FAIL";
+const char *kDATA = "DATA";
+const char *kDONE = "DONE";
-const char * kSEND = "SEND";
-const char * kRECV = "RECV";
-const char * kSTAT = "STAT";
+const char *kSEND = "SEND";
+const char *kRECV = "RECV";
+const char *kSTAT = "STAT";
const size_t kSyncPacketLen = 8;
// Maximum size of a filesync DATA packet.
-const size_t kMaxPushData = 2*1024;
+const size_t kMaxPushData = 2 * 1024;
// Default mode for pushed files.
const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG
-const char * kSocketNamespaceAbstract = "localabstract";
-const char * kSocketNamespaceFileSystem = "localfilesystem";
-
-Error
-ReadAllBytes (Connection &conn, void *buffer, size_t size)
-{
- using namespace std::chrono;
-
- Error error;
- ConnectionStatus status;
- char *read_buffer = static_cast<char*>(buffer);
-
- auto now = steady_clock::now();
- const auto deadline = now + kReadTimeout;
- size_t total_read_bytes = 0;
- while (total_read_bytes < size && now < deadline)
- {
- uint32_t timeout_usec = duration_cast<microseconds>(deadline - now).count();
- auto read_bytes =
- conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, timeout_usec, status, &error);
- if (error.Fail ())
- return error;
- total_read_bytes += read_bytes;
- if (status != eConnectionStatusSuccess)
- break;
- now = steady_clock::now();
- }
- if (total_read_bytes < size)
- error = Error("Unable to read requested number of bytes. Connection status: %d.", status);
- return error;
-}
+const char *kSocketNamespaceAbstract = "localabstract";
+const char *kSocketNamespaceFileSystem = "localfilesystem";
+
+Error ReadAllBytes(Connection &conn, void *buffer, size_t size) {
-} // namespace
+ Error error;
+ ConnectionStatus status;
+ char *read_buffer = static_cast<char *>(buffer);
-Error
-AdbClient::CreateByDeviceID(const std::string &device_id, AdbClient &adb)
-{
- DeviceIDList connect_devices;
- auto error = adb.GetDevices(connect_devices);
+ auto now = steady_clock::now();
+ const auto deadline = now + kReadTimeout;
+ size_t total_read_bytes = 0;
+ while (total_read_bytes < size && now < deadline) {
+ auto read_bytes =
+ conn.Read(read_buffer + total_read_bytes, size - total_read_bytes,
+ duration_cast<microseconds>(deadline - now), status, &error);
if (error.Fail())
- return error;
-
- std::string android_serial;
- if (!device_id.empty())
- android_serial = device_id;
- else if (const char *env_serial = std::getenv("ANDROID_SERIAL"))
- android_serial = env_serial;
-
- if (android_serial.empty())
- {
- if (connect_devices.size() != 1)
- return Error("Expected a single connected device, got instead %zu - try setting 'ANDROID_SERIAL'",
- connect_devices.size());
- adb.SetDeviceID(connect_devices.front());
- }
- else
- {
- auto find_it = std::find(connect_devices.begin(), connect_devices.end(), android_serial);
- if (find_it == connect_devices.end())
- return Error("Device \"%s\" not found", android_serial.c_str());
-
- adb.SetDeviceID(*find_it);
- }
+ return error;
+ total_read_bytes += read_bytes;
+ if (status != eConnectionStatusSuccess)
+ break;
+ now = steady_clock::now();
+ }
+ if (total_read_bytes < size)
+ error = Error(
+ "Unable to read requested number of bytes. Connection status: %d.",
+ status);
+ return error;
+}
+
+} // namespace
+
+Error AdbClient::CreateByDeviceID(const std::string &device_id,
+ AdbClient &adb) {
+ DeviceIDList connect_devices;
+ auto error = adb.GetDevices(connect_devices);
+ if (error.Fail())
return error;
-}
-AdbClient::AdbClient () {}
+ std::string android_serial;
+ if (!device_id.empty())
+ android_serial = device_id;
+ else if (const char *env_serial = std::getenv("ANDROID_SERIAL"))
+ android_serial = env_serial;
+
+ if (android_serial.empty()) {
+ if (connect_devices.size() != 1)
+ return Error("Expected a single connected device, got instead %zu - try "
+ "setting 'ANDROID_SERIAL'",
+ connect_devices.size());
+ adb.SetDeviceID(connect_devices.front());
+ } else {
+ auto find_it = std::find(connect_devices.begin(), connect_devices.end(),
+ android_serial);
+ if (find_it == connect_devices.end())
+ return Error("Device \"%s\" not found", android_serial.c_str());
-AdbClient::AdbClient (const std::string &device_id)
- : m_device_id (device_id)
-{
+ adb.SetDeviceID(*find_it);
+ }
+ return error;
}
+AdbClient::AdbClient() {}
+
+AdbClient::AdbClient(const std::string &device_id) : m_device_id(device_id) {}
+
AdbClient::~AdbClient() {}
-void
-AdbClient::SetDeviceID (const std::string &device_id)
-{
- m_device_id = device_id;
+void AdbClient::SetDeviceID(const std::string &device_id) {
+ m_device_id = device_id;
}
-const std::string&
-AdbClient::GetDeviceID() const
-{
- return m_device_id;
-}
+const std::string &AdbClient::GetDeviceID() const { return m_device_id; }
-Error
-AdbClient::Connect ()
-{
- Error error;
- m_conn.reset (new ConnectionFileDescriptor);
- m_conn->Connect ("connect://localhost:5037", &error);
+Error AdbClient::Connect() {
+ Error error;
+ m_conn.reset(new ConnectionFileDescriptor);
+ m_conn->Connect("connect://localhost:5037", &error);
- return error;
+ return error;
}
-Error
-AdbClient::GetDevices (DeviceIDList &device_list)
-{
- device_list.clear ();
+Error AdbClient::GetDevices(DeviceIDList &device_list) {
+ device_list.clear();
- auto error = SendMessage ("host:devices");
- if (error.Fail ())
- return error;
+ auto error = SendMessage("host:devices");
+ if (error.Fail())
+ return error;
- error = ReadResponseStatus ();
- if (error.Fail ())
- return error;
+ error = ReadResponseStatus();
+ if (error.Fail())
+ return error;
- std::vector<char> in_buffer;
- error = ReadMessage (in_buffer);
+ std::vector<char> in_buffer;
+ error = ReadMessage(in_buffer);
- llvm::StringRef response (&in_buffer[0], in_buffer.size ());
- llvm::SmallVector<llvm::StringRef, 4> devices;
- response.split (devices, "\n", -1, false);
+ llvm::StringRef response(&in_buffer[0], in_buffer.size());
+ llvm::SmallVector<llvm::StringRef, 4> devices;
+ response.split(devices, "\n", -1, false);
- for (const auto device: devices)
- device_list.push_back (device.split ('\t').first);
+ for (const auto device : devices)
+ device_list.push_back(device.split('\t').first);
- // Force disconnect since ADB closes connection after host:devices
- // response is sent.
- m_conn.reset ();
- return error;
+ // Force disconnect since ADB closes connection after host:devices
+ // response is sent.
+ m_conn.reset();
+ return error;
}
-Error
-AdbClient::SetPortForwarding (const uint16_t local_port, const uint16_t remote_port)
-{
- char message[48];
- snprintf (message, sizeof (message), "forward:tcp:%d;tcp:%d", local_port, remote_port);
+Error AdbClient::SetPortForwarding(const uint16_t local_port,
+ const uint16_t remote_port) {
+ char message[48];
+ snprintf(message, sizeof(message), "forward:tcp:%d;tcp:%d", local_port,
+ remote_port);
- const auto error = SendDeviceMessage (message);
- if (error.Fail ())
- return error;
+ const auto error = SendDeviceMessage(message);
+ if (error.Fail())
+ return error;
- return ReadResponseStatus ();
+ return ReadResponseStatus();
}
-Error
-AdbClient::SetPortForwarding (const uint16_t local_port,
- const char* remote_socket_name,
- const UnixSocketNamespace socket_namespace)
-{
- char message[PATH_MAX];
- const char * sock_namespace_str = (socket_namespace == UnixSocketNamespaceAbstract) ?
- kSocketNamespaceAbstract : kSocketNamespaceFileSystem;
- snprintf (message, sizeof (message), "forward:tcp:%d;%s:%s",
- local_port,
- sock_namespace_str,
- remote_socket_name);
+Error AdbClient::SetPortForwarding(const uint16_t local_port,
+ llvm::StringRef remote_socket_name,
+ const UnixSocketNamespace socket_namespace) {
+ char message[PATH_MAX];
+ const char *sock_namespace_str =
+ (socket_namespace == UnixSocketNamespaceAbstract)
+ ? kSocketNamespaceAbstract
+ : kSocketNamespaceFileSystem;
+ snprintf(message, sizeof(message), "forward:tcp:%d;%s:%s", local_port,
+ sock_namespace_str, remote_socket_name.str().c_str());
- const auto error = SendDeviceMessage (message);
- if (error.Fail ())
- return error;
+ const auto error = SendDeviceMessage(message);
+ if (error.Fail())
+ return error;
- return ReadResponseStatus ();
+ return ReadResponseStatus();
}
-Error
-AdbClient::DeletePortForwarding (const uint16_t local_port)
-{
- char message[32];
- snprintf (message, sizeof (message), "killforward:tcp:%d", local_port);
+Error AdbClient::DeletePortForwarding(const uint16_t local_port) {
+ char message[32];
+ snprintf(message, sizeof(message), "killforward:tcp:%d", local_port);
- const auto error = SendDeviceMessage (message);
- if (error.Fail ())
- return error;
+ const auto error = SendDeviceMessage(message);
+ if (error.Fail())
+ return error;
- return ReadResponseStatus ();
+ return ReadResponseStatus();
}
-Error
-AdbClient::SendMessage (const std::string &packet, const bool reconnect)
-{
- Error error;
- if (!m_conn || reconnect)
- {
- error = Connect ();
- if (error.Fail ())
- return error;
- }
-
- char length_buffer[5];
- snprintf (length_buffer, sizeof (length_buffer), "%04x", static_cast<int>(packet.size ()));
+Error AdbClient::SendMessage(const std::string &packet, const bool reconnect) {
+ Error error;
+ if (!m_conn || reconnect) {
+ error = Connect();
+ if (error.Fail())
+ return error;
+ }
- ConnectionStatus status;
+ char length_buffer[5];
+ snprintf(length_buffer, sizeof(length_buffer), "%04x",
+ static_cast<int>(packet.size()));
- m_conn->Write (length_buffer, 4, status, &error);
- if (error.Fail ())
- return error;
+ ConnectionStatus status;
- m_conn->Write (packet.c_str (), packet.size (), status, &error);
+ m_conn->Write(length_buffer, 4, status, &error);
+ if (error.Fail())
return error;
+
+ m_conn->Write(packet.c_str(), packet.size(), status, &error);
+ return error;
}
-Error
-AdbClient::SendDeviceMessage (const std::string &packet)
-{
- std::ostringstream msg;
- msg << "host-serial:" << m_device_id << ":" << packet;
- return SendMessage (msg.str ());
+Error AdbClient::SendDeviceMessage(const std::string &packet) {
+ std::ostringstream msg;
+ msg << "host-serial:" << m_device_id << ":" << packet;
+ return SendMessage(msg.str());
}
-Error
-AdbClient::ReadMessage (std::vector<char> &message)
-{
- message.clear ();
+Error AdbClient::ReadMessage(std::vector<char> &message) {
+ message.clear();
- char buffer[5];
- buffer[4] = 0;
+ char buffer[5];
+ buffer[4] = 0;
- auto error = ReadAllBytes (buffer, 4);
- if (error.Fail ())
- return error;
+ auto error = ReadAllBytes(buffer, 4);
+ if (error.Fail())
+ return error;
- unsigned int packet_len = 0;
- sscanf (buffer, "%x", &packet_len);
+ unsigned int packet_len = 0;
+ sscanf(buffer, "%x", &packet_len);
- message.resize (packet_len, 0);
- error = ReadAllBytes (&message[0], packet_len);
- if (error.Fail ())
- message.clear ();
+ message.resize(packet_len, 0);
+ error = ReadAllBytes(&message[0], packet_len);
+ if (error.Fail())
+ message.clear();
- return error;
+ return error;
}
-Error
-AdbClient::ReadMessageStream (std::vector<char>& message, uint32_t timeout_ms)
-{
- auto start = std::chrono::steady_clock::now();
- message.clear();
+Error AdbClient::ReadMessageStream(std::vector<char> &message,
+ milliseconds timeout) {
+ auto start = steady_clock::now();
+ message.clear();
- Error error;
- lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess;
- char buffer[1024];
- while (error.Success() && status == lldb::eConnectionStatusSuccess)
- {
- auto end = std::chrono::steady_clock::now();
- uint32_t elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
- if (elapsed_time >= timeout_ms)
- return Error("Timed out");
-
- size_t n = m_conn->Read(buffer, sizeof(buffer), 1000 * (timeout_ms - elapsed_time), status, &error);
- if (n > 0)
- message.insert(message.end(), &buffer[0], &buffer[n]);
- }
- return error;
+ Error error;
+ lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess;
+ char buffer[1024];
+ while (error.Success() && status == lldb::eConnectionStatusSuccess) {
+ auto end = steady_clock::now();
+ auto elapsed = end - start;
+ if (elapsed >= timeout)
+ return Error("Timed out");
+
+ size_t n = m_conn->Read(buffer, sizeof(buffer),
+ duration_cast<microseconds>(timeout - elapsed),
+ status, &error);
+ if (n > 0)
+ message.insert(message.end(), &buffer[0], &buffer[n]);
+ }
+ return error;
}
-Error
-AdbClient::ReadResponseStatus()
-{
- char response_id[5];
+Error AdbClient::ReadResponseStatus() {
+ char response_id[5];
- static const size_t packet_len = 4;
- response_id[packet_len] = 0;
+ static const size_t packet_len = 4;
+ response_id[packet_len] = 0;
- auto error = ReadAllBytes (response_id, packet_len);
- if (error.Fail ())
- return error;
+ auto error = ReadAllBytes(response_id, packet_len);
+ if (error.Fail())
+ return error;
- if (strncmp (response_id, kOKAY, packet_len) != 0)
- return GetResponseError (response_id);
+ if (strncmp(response_id, kOKAY, packet_len) != 0)
+ return GetResponseError(response_id);
- return error;
+ return error;
}
-Error
-AdbClient::GetResponseError (const char *response_id)
-{
- if (strcmp (response_id, kFAIL) != 0)
- return Error ("Got unexpected response id from adb: \"%s\"", response_id);
+Error AdbClient::GetResponseError(const char *response_id) {
+ if (strcmp(response_id, kFAIL) != 0)
+ return Error("Got unexpected response id from adb: \"%s\"", response_id);
- std::vector<char> error_message;
- auto error = ReadMessage (error_message);
- if (error.Success ())
- error.SetErrorString (std::string (&error_message[0], error_message.size ()).c_str ());
+ std::vector<char> error_message;
+ auto error = ReadMessage(error_message);
+ if (error.Success())
+ error.SetErrorString(
+ std::string(&error_message[0], error_message.size()).c_str());
- return error;
+ return error;
}
-Error
-AdbClient::SwitchDeviceTransport ()
-{
- std::ostringstream msg;
- msg << "host:transport:" << m_device_id;
+Error AdbClient::SwitchDeviceTransport() {
+ std::ostringstream msg;
+ msg << "host:transport:" << m_device_id;
- auto error = SendMessage (msg.str ());
- if (error.Fail ())
- return error;
+ auto error = SendMessage(msg.str());
+ if (error.Fail())
+ return error;
- return ReadResponseStatus ();
+ return ReadResponseStatus();
}
-Error
-AdbClient::StartSync ()
-{
- auto error = SwitchDeviceTransport ();
- if (error.Fail ())
- return Error ("Failed to switch to device transport: %s", error.AsCString ());
+Error AdbClient::StartSync() {
+ auto error = SwitchDeviceTransport();
+ if (error.Fail())
+ return Error("Failed to switch to device transport: %s", error.AsCString());
- error = Sync ();
- if (error.Fail ())
- return Error ("Sync failed: %s", error.AsCString ());
+ error = Sync();
+ if (error.Fail())
+ return Error("Sync failed: %s", error.AsCString());
- return error;
+ return error;
}
-Error
-AdbClient::Sync ()
-{
- auto error = SendMessage ("sync:", false);
- if (error.Fail ())
- return error;
+Error AdbClient::Sync() {
+ auto error = SendMessage("sync:", false);
+ if (error.Fail())
+ return error;
- return ReadResponseStatus ();
+ return ReadResponseStatus();
}
-Error
-AdbClient::ReadAllBytes (void *buffer, size_t size)
-{
- return ::ReadAllBytes (*m_conn, buffer, size);
+Error AdbClient::ReadAllBytes(void *buffer, size_t size) {
+ return ::ReadAllBytes(*m_conn, buffer, size);
}
-Error
-AdbClient::internalShell(const char *command, uint32_t timeout_ms, std::vector<char> &output_buf)
-{
- output_buf.clear();
+Error AdbClient::internalShell(const char *command, milliseconds timeout,
+ std::vector<char> &output_buf) {
+ output_buf.clear();
- auto error = SwitchDeviceTransport();
- if (error.Fail())
- return Error("Failed to switch to device transport: %s", error.AsCString());
+ auto error = SwitchDeviceTransport();
+ if (error.Fail())
+ return Error("Failed to switch to device transport: %s", error.AsCString());
- StreamString adb_command;
- adb_command.Printf("shell:%s", command);
- error = SendMessage(adb_command.GetData(), false);
- if (error.Fail())
- return error;
+ StreamString adb_command;
+ adb_command.Printf("shell:%s", command);
+ error = SendMessage(adb_command.GetString(), false);
+ if (error.Fail())
+ return error;
- error = ReadResponseStatus();
- if (error.Fail())
- return error;
+ error = ReadResponseStatus();
+ if (error.Fail())
+ return error;
- error = ReadMessageStream(output_buf, timeout_ms);
- if (error.Fail())
- return error;
-
- // ADB doesn't propagate return code of shell execution - if
- // output starts with /system/bin/sh: most likely command failed.
- static const char *kShellPrefix = "/system/bin/sh:";
- if (output_buf.size() > strlen(kShellPrefix))
- {
- if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix)))
- return Error("Shell command %s failed: %s", command,
- std::string(output_buf.begin(), output_buf.end()).c_str());
- }
-
- return Error();
-}
-
-Error
-AdbClient::Shell(const char *command, uint32_t timeout_ms, std::string *output)
-{
- std::vector<char> output_buffer;
- auto error = internalShell(command, timeout_ms, output_buffer);
- if (error.Fail())
- return error;
+ error = ReadMessageStream(output_buf, timeout);
+ if (error.Fail())
+ return error;
- if (output)
- output->assign(output_buffer.begin(), output_buffer.end());
+ // ADB doesn't propagate return code of shell execution - if
+ // output starts with /system/bin/sh: most likely command failed.
+ static const char *kShellPrefix = "/system/bin/sh:";
+ if (output_buf.size() > strlen(kShellPrefix)) {
+ if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix)))
+ return Error("Shell command %s failed: %s", command,
+ std::string(output_buf.begin(), output_buf.end()).c_str());
+ }
+
+ return Error();
+}
+
+Error AdbClient::Shell(const char *command, milliseconds timeout,
+ std::string *output) {
+ std::vector<char> output_buffer;
+ auto error = internalShell(command, timeout, output_buffer);
+ if (error.Fail())
return error;
+
+ if (output)
+ output->assign(output_buffer.begin(), output_buffer.end());
+ return error;
}
-Error
-AdbClient::ShellToFile(const char *command, uint32_t timeout_ms, const FileSpec &output_file_spec)
-{
- std::vector<char> output_buffer;
- auto error = internalShell(command, timeout_ms, output_buffer);
- if (error.Fail())
- return error;
+Error AdbClient::ShellToFile(const char *command, milliseconds timeout,
+ const FileSpec &output_file_spec) {
+ std::vector<char> output_buffer;
+ auto error = internalShell(command, timeout, output_buffer);
+ if (error.Fail())
+ return error;
- const auto output_filename = output_file_spec.GetPath();
- std::ofstream dst(output_filename, std::ios::out | std::ios::binary);
- if (!dst.is_open())
- return Error("Unable to open local file %s", output_filename.c_str());
+ const auto output_filename = output_file_spec.GetPath();
+ std::ofstream dst(output_filename, std::ios::out | std::ios::binary);
+ if (!dst.is_open())
+ return Error("Unable to open local file %s", output_filename.c_str());
- dst.write(&output_buffer[0], output_buffer.size());
- dst.close();
- if (!dst)
- return Error("Failed to write file %s", output_filename.c_str());
- return Error();
+ dst.write(&output_buffer[0], output_buffer.size());
+ dst.close();
+ if (!dst)
+ return Error("Failed to write file %s", output_filename.c_str());
+ return Error();
}
std::unique_ptr<AdbClient::SyncService>
-AdbClient::GetSyncService (Error &error)
-{
- std::unique_ptr<SyncService> sync_service;
- error = StartSync ();
- if (error.Success ())
- sync_service.reset (new SyncService(std::move(m_conn)));
-
- return sync_service;
-}
-
-Error
-AdbClient::SyncService::internalPullFile (const FileSpec &remote_file, const FileSpec &local_file)
-{
- const auto local_file_path = local_file.GetPath ();
- llvm::FileRemover local_file_remover (local_file_path.c_str ());
-
- std::ofstream dst (local_file_path, std::ios::out | std::ios::binary);
- if (!dst.is_open ())
- return Error ("Unable to open local file %s", local_file_path.c_str());
-
- const auto remote_file_path = remote_file.GetPath (false);
- auto error = SendSyncRequest (kRECV, remote_file_path.length (), remote_file_path.c_str ());
- if (error.Fail ())
- return error;
-
- std::vector<char> chunk;
- bool eof = false;
- while (!eof)
- {
- error = PullFileChunk (chunk, eof);
- if (error.Fail ())
- return error;
- if (!eof)
- dst.write (&chunk[0], chunk.size ());
- }
-
- local_file_remover.releaseFile ();
- return error;
+AdbClient::GetSyncService(Error &error) {
+ std::unique_ptr<SyncService> sync_service;
+ error = StartSync();
+ if (error.Success())
+ sync_service.reset(new SyncService(std::move(m_conn)));
+
+ return sync_service;
}
-Error
-AdbClient::SyncService::internalPushFile (const FileSpec &local_file, const FileSpec &remote_file)
-{
- const auto local_file_path (local_file.GetPath ());
- std::ifstream src (local_file_path.c_str(), std::ios::in | std::ios::binary);
- if (!src.is_open ())
- return Error ("Unable to open local file %s", local_file_path.c_str());
-
- std::stringstream file_description;
- file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode;
- std::string file_description_str = file_description.str();
- auto error = SendSyncRequest (kSEND, file_description_str.length(), file_description_str.c_str());
- if (error.Fail ())
- return error;
-
- char chunk[kMaxPushData];
- while (!src.eof() && !src.read(chunk, kMaxPushData).bad())
- {
- size_t chunk_size = src.gcount();
- error = SendSyncRequest(kDATA, chunk_size, chunk);
- if (error.Fail ())
- return Error ("Failed to send file chunk: %s", error.AsCString ());
- }
- error = SendSyncRequest(kDONE, local_file.GetModificationTime().seconds(), nullptr);
- if (error.Fail ())
- return error;
-
- std::string response_id;
- uint32_t data_len;
- error = ReadSyncHeader (response_id, data_len);
- if (error.Fail ())
- return Error ("Failed to read DONE response: %s", error.AsCString ());
- if (response_id == kFAIL)
- {
- std::string error_message (data_len, 0);
- error = ReadAllBytes (&error_message[0], data_len);
- if (error.Fail ())
- return Error ("Failed to read DONE error message: %s", error.AsCString ());
- return Error ("Failed to push file: %s", error_message.c_str ());
- }
- else if (response_id != kOKAY)
- return Error ("Got unexpected DONE response: %s", response_id.c_str ());
-
- // If there was an error reading the source file, finish the adb file
- // transfer first so that adb isn't expecting any more data.
- if (src.bad())
- return Error ("Failed read on %s", local_file_path.c_str());
+Error AdbClient::SyncService::internalPullFile(const FileSpec &remote_file,
+ const FileSpec &local_file) {
+ const auto local_file_path = local_file.GetPath();
+ llvm::FileRemover local_file_remover(local_file_path);
+
+ std::ofstream dst(local_file_path, std::ios::out | std::ios::binary);
+ if (!dst.is_open())
+ return Error("Unable to open local file %s", local_file_path.c_str());
+
+ const auto remote_file_path = remote_file.GetPath(false);
+ auto error = SendSyncRequest(kRECV, remote_file_path.length(),
+ remote_file_path.c_str());
+ if (error.Fail())
+ return error;
+
+ std::vector<char> chunk;
+ bool eof = false;
+ while (!eof) {
+ error = PullFileChunk(chunk, eof);
+ if (error.Fail())
+ return error;
+ if (!eof)
+ dst.write(&chunk[0], chunk.size());
+ }
+
+ local_file_remover.releaseFile();
+ return error;
+}
+
+Error AdbClient::SyncService::internalPushFile(const FileSpec &local_file,
+ const FileSpec &remote_file) {
+ const auto local_file_path(local_file.GetPath());
+ std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary);
+ if (!src.is_open())
+ return Error("Unable to open local file %s", local_file_path.c_str());
+
+ std::stringstream file_description;
+ file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode;
+ std::string file_description_str = file_description.str();
+ auto error = SendSyncRequest(kSEND, file_description_str.length(),
+ file_description_str.c_str());
+ if (error.Fail())
+ return error;
+
+ char chunk[kMaxPushData];
+ while (!src.eof() && !src.read(chunk, kMaxPushData).bad()) {
+ size_t chunk_size = src.gcount();
+ error = SendSyncRequest(kDATA, chunk_size, chunk);
+ if (error.Fail())
+ return Error("Failed to send file chunk: %s", error.AsCString());
+ }
+ error = SendSyncRequest(
+ kDONE, llvm::sys::toTimeT(FileSystem::GetModificationTime(local_file)),
+ nullptr);
+ if (error.Fail())
return error;
+
+ std::string response_id;
+ uint32_t data_len;
+ error = ReadSyncHeader(response_id, data_len);
+ if (error.Fail())
+ return Error("Failed to read DONE response: %s", error.AsCString());
+ if (response_id == kFAIL) {
+ std::string error_message(data_len, 0);
+ error = ReadAllBytes(&error_message[0], data_len);
+ if (error.Fail())
+ return Error("Failed to read DONE error message: %s", error.AsCString());
+ return Error("Failed to push file: %s", error_message.c_str());
+ } else if (response_id != kOKAY)
+ return Error("Got unexpected DONE response: %s", response_id.c_str());
+
+ // If there was an error reading the source file, finish the adb file
+ // transfer first so that adb isn't expecting any more data.
+ if (src.bad())
+ return Error("Failed read on %s", local_file_path.c_str());
+ return error;
}
-Error
-AdbClient::SyncService::internalStat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime)
-{
- const std::string remote_file_path (remote_file.GetPath (false));
- auto error = SendSyncRequest (kSTAT, remote_file_path.length (), remote_file_path.c_str ());
- if (error.Fail ())
- return Error ("Failed to send request: %s", error.AsCString ());
+Error AdbClient::SyncService::internalStat(const FileSpec &remote_file,
+ uint32_t &mode, uint32_t &size,
+ uint32_t &mtime) {
+ const std::string remote_file_path(remote_file.GetPath(false));
+ auto error = SendSyncRequest(kSTAT, remote_file_path.length(),
+ remote_file_path.c_str());
+ if (error.Fail())
+ return Error("Failed to send request: %s", error.AsCString());
- static const size_t stat_len = strlen (kSTAT);
- static const size_t response_len = stat_len + (sizeof (uint32_t) * 3);
+ static const size_t stat_len = strlen(kSTAT);
+ static const size_t response_len = stat_len + (sizeof(uint32_t) * 3);
- std::vector<char> buffer (response_len);
- error = ReadAllBytes (&buffer[0], buffer.size ());
- if (error.Fail ())
- return Error ("Failed to read response: %s", error.AsCString ());
+ std::vector<char> buffer(response_len);
+ error = ReadAllBytes(&buffer[0], buffer.size());
+ if (error.Fail())
+ return Error("Failed to read response: %s", error.AsCString());
- DataExtractor extractor (&buffer[0], buffer.size (), eByteOrderLittle, sizeof (void*));
- offset_t offset = 0;
+ DataExtractor extractor(&buffer[0], buffer.size(), eByteOrderLittle,
+ sizeof(void *));
+ offset_t offset = 0;
- const void* command = extractor.GetData (&offset, stat_len);
- if (!command)
- return Error ("Failed to get response command");
- const char* command_str = static_cast<const char*> (command);
- if (strncmp (command_str, kSTAT, stat_len))
- return Error ("Got invalid stat command: %s", command_str);
+ const void *command = extractor.GetData(&offset, stat_len);
+ if (!command)
+ return Error("Failed to get response command");
+ const char *command_str = static_cast<const char *>(command);
+ if (strncmp(command_str, kSTAT, stat_len))
+ return Error("Got invalid stat command: %s", command_str);
- mode = extractor.GetU32 (&offset);
- size = extractor.GetU32 (&offset);
- mtime = extractor.GetU32 (&offset);
- return Error ();
+ mode = extractor.GetU32(&offset);
+ size = extractor.GetU32(&offset);
+ mtime = extractor.GetU32(&offset);
+ return Error();
}
-Error
-AdbClient::SyncService::PullFile (const FileSpec &remote_file, const FileSpec &local_file)
-{
- return executeCommand ([this, &remote_file, &local_file]() {
- return internalPullFile (remote_file, local_file);
- });
+Error AdbClient::SyncService::PullFile(const FileSpec &remote_file,
+ const FileSpec &local_file) {
+ return executeCommand([this, &remote_file, &local_file]() {
+ return internalPullFile(remote_file, local_file);
+ });
}
-Error
-AdbClient::SyncService::PushFile (const FileSpec &local_file, const FileSpec &remote_file)
-{
- return executeCommand ([this, &local_file, &remote_file]() {
- return internalPushFile (local_file, remote_file);
- });
+Error AdbClient::SyncService::PushFile(const FileSpec &local_file,
+ const FileSpec &remote_file) {
+ return executeCommand([this, &local_file, &remote_file]() {
+ return internalPushFile(local_file, remote_file);
+ });
}
-Error
-AdbClient::SyncService::Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime)
-{
- return executeCommand ([this, &remote_file, &mode, &size, &mtime]() {
- return internalStat (remote_file, mode, size, mtime);
- });
+Error AdbClient::SyncService::Stat(const FileSpec &remote_file, uint32_t &mode,
+ uint32_t &size, uint32_t &mtime) {
+ return executeCommand([this, &remote_file, &mode, &size, &mtime]() {
+ return internalStat(remote_file, mode, size, mtime);
+ });
}
-bool
-AdbClient::SyncService::IsConnected () const
-{
- return m_conn && m_conn->IsConnected ();
+bool AdbClient::SyncService::IsConnected() const {
+ return m_conn && m_conn->IsConnected();
}
-AdbClient::SyncService::SyncService(std::unique_ptr<Connection> &&conn):
-m_conn(std::move(conn))
-{
-}
+AdbClient::SyncService::SyncService(std::unique_ptr<Connection> &&conn)
+ : m_conn(std::move(conn)) {}
-Error
-AdbClient::SyncService::executeCommand (const std::function<Error()> &cmd)
-{
- if (!m_conn)
- return Error ("SyncService is disconnected");
+Error AdbClient::SyncService::executeCommand(
+ const std::function<Error()> &cmd) {
+ if (!m_conn)
+ return Error("SyncService is disconnected");
- const auto error = cmd ();
- if (error.Fail ())
- m_conn.reset ();
+ const auto error = cmd();
+ if (error.Fail())
+ m_conn.reset();
- return error;
+ return error;
}
-AdbClient::SyncService::~SyncService () {}
+AdbClient::SyncService::~SyncService() {}
-Error
-AdbClient::SyncService::SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data)
-{
- const DataBufferSP data_sp (new DataBufferHeap (kSyncPacketLen, 0));
- DataEncoder encoder (data_sp, eByteOrderLittle, sizeof (void*));
- auto offset = encoder.PutData (0, request_id, strlen(request_id));
- encoder.PutU32 (offset, data_len);
+Error AdbClient::SyncService::SendSyncRequest(const char *request_id,
+ const uint32_t data_len,
+ const void *data) {
+ const DataBufferSP data_sp(new DataBufferHeap(kSyncPacketLen, 0));
+ DataEncoder encoder(data_sp, eByteOrderLittle, sizeof(void *));
+ auto offset = encoder.PutData(0, request_id, strlen(request_id));
+ encoder.PutU32(offset, data_len);
- Error error;
- ConnectionStatus status;
- m_conn->Write (data_sp->GetBytes (), kSyncPacketLen, status, &error);
- if (error.Fail ())
- return error;
-
- if (data)
- m_conn->Write (data, data_len, status, &error);
+ Error error;
+ ConnectionStatus status;
+ m_conn->Write(data_sp->GetBytes(), kSyncPacketLen, status, &error);
+ if (error.Fail())
return error;
+
+ if (data)
+ m_conn->Write(data, data_len, status, &error);
+ return error;
}
-Error
-AdbClient::SyncService::ReadSyncHeader (std::string &response_id, uint32_t &data_len)
-{
- char buffer[kSyncPacketLen];
+Error AdbClient::SyncService::ReadSyncHeader(std::string &response_id,
+ uint32_t &data_len) {
+ char buffer[kSyncPacketLen];
- auto error = ReadAllBytes (buffer, kSyncPacketLen);
- if (error.Success ())
- {
- response_id.assign (&buffer[0], 4);
- DataExtractor extractor (&buffer[4], 4, eByteOrderLittle, sizeof (void*));
- offset_t offset = 0;
- data_len = extractor.GetU32 (&offset);
- }
+ auto error = ReadAllBytes(buffer, kSyncPacketLen);
+ if (error.Success()) {
+ response_id.assign(&buffer[0], 4);
+ DataExtractor extractor(&buffer[4], 4, eByteOrderLittle, sizeof(void *));
+ offset_t offset = 0;
+ data_len = extractor.GetU32(&offset);
+ }
- return error;
+ return error;
}
-Error
-AdbClient::SyncService::PullFileChunk (std::vector<char> &buffer, bool &eof)
-{
- buffer.clear ();
-
- std::string response_id;
- uint32_t data_len;
- auto error = ReadSyncHeader (response_id, data_len);
- if (error.Fail ())
- return error;
-
- if (response_id == kDATA)
- {
- buffer.resize (data_len, 0);
- error = ReadAllBytes (&buffer[0], data_len);
- if (error.Fail ())
- buffer.clear ();
- }
- else if (response_id == kDONE)
- {
- eof = true;
- }
- else if (response_id == kFAIL)
- {
- std::string error_message (data_len, 0);
- error = ReadAllBytes (&error_message[0], data_len);
- if (error.Fail ())
- return Error ("Failed to read pull error message: %s", error.AsCString ());
- return Error ("Failed to pull file: %s", error_message.c_str ());
- }
- else
- return Error ("Pull failed with unknown response: %s", response_id.c_str ());
-
- return Error ();
-}
-
-Error
-AdbClient::SyncService::ReadAllBytes (void *buffer, size_t size)
-{
- return ::ReadAllBytes (*m_conn, buffer, size);
+Error AdbClient::SyncService::PullFileChunk(std::vector<char> &buffer,
+ bool &eof) {
+ buffer.clear();
+
+ std::string response_id;
+ uint32_t data_len;
+ auto error = ReadSyncHeader(response_id, data_len);
+ if (error.Fail())
+ return error;
+
+ if (response_id == kDATA) {
+ buffer.resize(data_len, 0);
+ error = ReadAllBytes(&buffer[0], data_len);
+ if (error.Fail())
+ buffer.clear();
+ } else if (response_id == kDONE) {
+ eof = true;
+ } else if (response_id == kFAIL) {
+ std::string error_message(data_len, 0);
+ error = ReadAllBytes(&error_message[0], data_len);
+ if (error.Fail())
+ return Error("Failed to read pull error message: %s", error.AsCString());
+ return Error("Failed to pull file: %s", error_message.c_str());
+ } else
+ return Error("Pull failed with unknown response: %s", response_id.c_str());
+
+ return Error();
}
+Error AdbClient::SyncService::ReadAllBytes(void *buffer, size_t size) {
+ return ::ReadAllBytes(*m_conn, buffer, size);
+}
diff --git a/source/Plugins/Platform/Android/AdbClient.h b/source/Plugins/Platform/Android/AdbClient.h
index 37973bbdccf8..169a0b5a4e3e 100644
--- a/source/Plugins/Platform/Android/AdbClient.h
+++ b/source/Plugins/Platform/Android/AdbClient.h
@@ -10,167 +10,131 @@
#ifndef liblldb_AdbClient_h_
#define liblldb_AdbClient_h_
-// C Includes
-
-// C++ Includes
-
+#include "lldb/Core/Error.h"
+#include <chrono>
#include <functional>
#include <list>
#include <memory>
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
-
-#include "lldb/Core/Error.h"
-
namespace lldb_private {
class FileSpec;
namespace platform_android {
-class AdbClient
-{
+class AdbClient {
public:
- enum UnixSocketNamespace
- {
- UnixSocketNamespaceAbstract,
- UnixSocketNamespaceFileSystem,
- };
+ enum UnixSocketNamespace {
+ UnixSocketNamespaceAbstract,
+ UnixSocketNamespaceFileSystem,
+ };
- using DeviceIDList = std::list<std::string>;
+ using DeviceIDList = std::list<std::string>;
- class SyncService
- {
- friend class AdbClient;
+ class SyncService {
+ friend class AdbClient;
- public:
- ~SyncService ();
+ public:
+ ~SyncService();
- Error
- PullFile (const FileSpec &remote_file, const FileSpec &local_file);
+ Error PullFile(const FileSpec &remote_file, const FileSpec &local_file);
- Error
- PushFile (const FileSpec &local_file, const FileSpec &remote_file);
+ Error PushFile(const FileSpec &local_file, const FileSpec &remote_file);
- Error
- Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime);
+ Error Stat(const FileSpec &remote_file, uint32_t &mode, uint32_t &size,
+ uint32_t &mtime);
- bool
- IsConnected () const;
+ bool IsConnected() const;
- private:
- explicit SyncService (std::unique_ptr<Connection> &&conn);
+ private:
+ explicit SyncService(std::unique_ptr<Connection> &&conn);
- Error
- SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data);
+ Error SendSyncRequest(const char *request_id, const uint32_t data_len,
+ const void *data);
- Error
- ReadSyncHeader (std::string &response_id, uint32_t &data_len);
+ Error ReadSyncHeader(std::string &response_id, uint32_t &data_len);
- Error
- PullFileChunk (std::vector<char> &buffer, bool &eof);
+ Error PullFileChunk(std::vector<char> &buffer, bool &eof);
- Error
- ReadAllBytes (void *buffer, size_t size);
+ Error ReadAllBytes(void *buffer, size_t size);
- Error
- internalPullFile (const FileSpec &remote_file, const FileSpec &local_file);
+ Error internalPullFile(const FileSpec &remote_file,
+ const FileSpec &local_file);
- Error
- internalPushFile (const FileSpec &local_file, const FileSpec &remote_file);
+ Error internalPushFile(const FileSpec &local_file,
+ const FileSpec &remote_file);
- Error
- internalStat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime);
+ Error internalStat(const FileSpec &remote_file, uint32_t &mode,
+ uint32_t &size, uint32_t &mtime);
- Error
- executeCommand (const std::function<Error()> &cmd);
+ Error executeCommand(const std::function<Error()> &cmd);
- std::unique_ptr<Connection> m_conn;
- };
+ std::unique_ptr<Connection> m_conn;
+ };
- static Error
- CreateByDeviceID(const std::string &device_id, AdbClient &adb);
+ static Error CreateByDeviceID(const std::string &device_id, AdbClient &adb);
- AdbClient ();
- explicit AdbClient (const std::string &device_id);
+ AdbClient();
+ explicit AdbClient(const std::string &device_id);
- ~AdbClient();
+ ~AdbClient();
- const std::string&
- GetDeviceID() const;
+ const std::string &GetDeviceID() const;
- Error
- GetDevices (DeviceIDList &device_list);
+ Error GetDevices(DeviceIDList &device_list);
- Error
- SetPortForwarding (const uint16_t local_port, const uint16_t remote_port);
+ Error SetPortForwarding(const uint16_t local_port,
+ const uint16_t remote_port);
- Error
- SetPortForwarding (const uint16_t local_port,
- const char* remote_socket_name,
- const UnixSocketNamespace socket_namespace);
+ Error SetPortForwarding(const uint16_t local_port,
+ llvm::StringRef remote_socket_name,
+ const UnixSocketNamespace socket_namespace);
- Error
- DeletePortForwarding (const uint16_t local_port);
+ Error DeletePortForwarding(const uint16_t local_port);
- Error
- Shell (const char* command, uint32_t timeout_ms, std::string* output);
+ Error Shell(const char *command, std::chrono::milliseconds timeout,
+ std::string *output);
- Error
- ShellToFile(const char *command, uint32_t timeout_ms, const FileSpec &output_file_spec);
+ Error ShellToFile(const char *command, std::chrono::milliseconds timeout,
+ const FileSpec &output_file_spec);
- std::unique_ptr<SyncService>
- GetSyncService (Error &error);
+ std::unique_ptr<SyncService> GetSyncService(Error &error);
- Error
- SwitchDeviceTransport ();
+ Error SwitchDeviceTransport();
private:
- Error
- Connect ();
+ Error Connect();
- void
- SetDeviceID (const std::string &device_id);
+ void SetDeviceID(const std::string &device_id);
- Error
- SendMessage (const std::string &packet, const bool reconnect = true);
+ Error SendMessage(const std::string &packet, const bool reconnect = true);
- Error
- SendDeviceMessage (const std::string &packet);
+ Error SendDeviceMessage(const std::string &packet);
- Error
- ReadMessage (std::vector<char> &message);
+ Error ReadMessage(std::vector<char> &message);
- Error
- ReadMessageStream (std::vector<char> &message, uint32_t timeout_ms);
+ Error ReadMessageStream(std::vector<char> &message, std::chrono::milliseconds timeout);
- Error
- GetResponseError (const char *response_id);
+ Error GetResponseError(const char *response_id);
- Error
- ReadResponseStatus ();
+ Error ReadResponseStatus();
- Error
- Sync ();
+ Error Sync();
- Error
- StartSync ();
+ Error StartSync();
- Error
- internalShell(const char *command, uint32_t timeout_ms, std::vector<char> &output_buf);
+ Error internalShell(const char *command, std::chrono::milliseconds timeout,
+ std::vector<char> &output_buf);
- Error
- ReadAllBytes(void *buffer, size_t size);
+ Error ReadAllBytes(void *buffer, size_t size);
- std::string m_device_id;
- std::unique_ptr<Connection> m_conn;
+ std::string m_device_id;
+ std::unique_ptr<Connection> m_conn;
};
} // namespace platform_android
} // namespace lldb_private
-#endif // liblldb_AdbClient_h_
-
+#endif // liblldb_AdbClient_h_
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
index 381795171d36..64a320f8c3fc 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -10,6 +10,7 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "Utility/UriParser.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -18,7 +19,6 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
-#include "Utility/UriParser.h"
// Project includes
#include "AdbClient.h"
@@ -28,390 +28,349 @@
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_android;
+using namespace std::chrono;
static uint32_t g_initialize_count = 0;
-static const unsigned int g_android_default_cache_size = 2048; // Fits inside 4k adb packet.
+static const unsigned int g_android_default_cache_size =
+ 2048; // Fits inside 4k adb packet.
-void
-PlatformAndroid::Initialize ()
-{
- PlatformLinux::Initialize ();
+void PlatformAndroid::Initialize() {
+ PlatformLinux::Initialize();
- if (g_initialize_count++ == 0)
- {
+ if (g_initialize_count++ == 0) {
#if defined(__ANDROID__)
- PlatformSP default_platform_sp (new PlatformAndroid(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform (default_platform_sp);
+ PlatformSP default_platform_sp(new PlatformAndroid(true));
+ default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+ Platform::SetHostPlatform(default_platform_sp);
#endif
- PluginManager::RegisterPlugin (PlatformAndroid::GetPluginNameStatic(false),
- PlatformAndroid::GetPluginDescriptionStatic(false),
- PlatformAndroid::CreateInstance);
- }
+ PluginManager::RegisterPlugin(
+ PlatformAndroid::GetPluginNameStatic(false),
+ PlatformAndroid::GetPluginDescriptionStatic(false),
+ PlatformAndroid::CreateInstance);
+ }
}
-void
-PlatformAndroid::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformAndroid::CreateInstance);
- }
+void PlatformAndroid::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformAndroid::CreateInstance);
}
+ }
- PlatformLinux::Terminate ();
+ PlatformLinux::Terminate();
}
-PlatformSP
-PlatformAndroid::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>";
+PlatformSP PlatformAndroid::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>";
+ const char *triple_cstr =
+ arch ? arch->GetTriple().getTriple().c_str() : "<null>";
- log->Printf ("PlatformAndroid::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
+ log->Printf("PlatformAndroid::%s(force=%s, arch={%s,%s})", __FUNCTION__,
+ force ? "true" : "false", arch_name, triple_cstr);
+ }
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- case llvm::Triple::PC:
- create = true;
- break;
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::PC:
+ create = true;
+ break;
#if defined(__ANDROID__)
- // Only accept "unknown" for the vendor if the host is android and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified_
- case llvm::Triple::VendorType::UnknownVendor:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for the vendor if the host is android and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified_
+ case llvm::Triple::VendorType::UnknownVendor:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
-
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::Android:
- break;
+ default:
+ break;
+ }
+
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::Android:
+ break;
#if defined(__ANDROID__)
- // Only accept "unknown" for the OS if the host is android and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::OSType::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
+ // Only accept "unknown" for the OS if the host is android and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::OSType::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
#endif
- default:
- create = false;
- break;
- }
- }
- }
-
- if (create)
- {
- if (log)
- log->Printf ("PlatformAndroid::%s() creating remote-android platform", __FUNCTION__);
- return PlatformSP(new PlatformAndroid(false));
+ default:
+ create = false;
+ break;
+ }
}
+ }
+ if (create) {
if (log)
- log->Printf ("PlatformAndroid::%s() aborting creation of remote-android platform", __FUNCTION__);
+ log->Printf("PlatformAndroid::%s() creating remote-android platform",
+ __FUNCTION__);
+ return PlatformSP(new PlatformAndroid(false));
+ }
- return PlatformSP();
-}
+ if (log)
+ log->Printf(
+ "PlatformAndroid::%s() aborting creation of remote-android platform",
+ __FUNCTION__);
-PlatformAndroid::PlatformAndroid (bool is_host) :
- PlatformLinux(is_host),
- m_sdk_version(0)
-{
+ return PlatformSP();
}
-PlatformAndroid::~PlatformAndroid()
-{
-}
+PlatformAndroid::PlatformAndroid(bool is_host)
+ : PlatformLinux(is_host), m_sdk_version(0) {}
-ConstString
-PlatformAndroid::GetPluginNameStatic (bool is_host)
-{
- if (is_host)
- {
- static ConstString g_host_name(Platform::GetHostPlatformName ());
- return g_host_name;
- }
- else
- {
- static ConstString g_remote_name("remote-android");
- return g_remote_name;
- }
-}
+PlatformAndroid::~PlatformAndroid() {}
-const char *
-PlatformAndroid::GetPluginDescriptionStatic (bool is_host)
-{
- if (is_host)
- return "Local Android user platform plug-in.";
- else
- return "Remote Android user platform plug-in.";
+ConstString PlatformAndroid::GetPluginNameStatic(bool is_host) {
+ if (is_host) {
+ static ConstString g_host_name(Platform::GetHostPlatformName());
+ return g_host_name;
+ } else {
+ static ConstString g_remote_name("remote-android");
+ return g_remote_name;
+ }
}
-ConstString
-PlatformAndroid::GetPluginName()
-{
- return GetPluginNameStatic(IsHost());
+const char *PlatformAndroid::GetPluginDescriptionStatic(bool is_host) {
+ if (is_host)
+ return "Local Android user platform plug-in.";
+ else
+ return "Remote Android user platform plug-in.";
}
-Error
-PlatformAndroid::ConnectRemote(Args& args)
-{
- m_device_id.clear();
+ConstString PlatformAndroid::GetPluginName() {
+ return GetPluginNameStatic(IsHost());
+}
- if (IsHost())
- {
- return Error ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString());
- }
+Error PlatformAndroid::ConnectRemote(Args &args) {
+ m_device_id.clear();
+
+ if (IsHost()) {
+ return Error("can't connect to the host platform '%s', always connected",
+ GetPluginName().GetCString());
+ }
+
+ if (!m_remote_platform_sp)
+ m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer());
+
+ int port;
+ llvm::StringRef scheme, host, path;
+ const char *url = args.GetArgumentAtIndex(0);
+ if (!url)
+ return Error("URL is null.");
+ if (!UriParser::Parse(url, scheme, host, port, path))
+ return Error("Invalid URL: %s", url);
+ if (host != "localhost")
+ m_device_id = host;
+
+ auto error = PlatformLinux::ConnectRemote(args);
+ if (error.Success()) {
+ AdbClient adb;
+ error = AdbClient::CreateByDeviceID(m_device_id, adb);
+ if (error.Fail())
+ return error;
- if (!m_remote_platform_sp)
- m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer());
-
- int port;
- std::string scheme, host, path;
- const char *url = args.GetArgumentAtIndex(0);
- if (!url)
- return Error("URL is null.");
- if (!UriParser::Parse(url, scheme, host, port, path))
- return Error("Invalid URL: %s", url);
- if (host != "localhost")
- m_device_id = host;
-
- auto error = PlatformLinux::ConnectRemote(args);
- if (error.Success())
- {
- AdbClient adb;
- error = AdbClient::CreateByDeviceID(m_device_id, adb);
- if (error.Fail())
- return error;
-
- m_device_id = adb.GetDeviceID();
- }
- return error;
+ m_device_id = adb.GetDeviceID();
+ }
+ return error;
}
-Error
-PlatformAndroid::GetFile (const FileSpec& source,
- const FileSpec& destination)
-{
- if (IsHost() || !m_remote_platform_sp)
- return PlatformLinux::GetFile(source, destination);
+Error PlatformAndroid::GetFile(const FileSpec &source,
+ const FileSpec &destination) {
+ if (IsHost() || !m_remote_platform_sp)
+ return PlatformLinux::GetFile(source, destination);
- FileSpec source_spec (source.GetPath (false), false, FileSpec::ePathSyntaxPosix);
- if (source_spec.IsRelative())
- source_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (source_spec.GetCString (false));
+ FileSpec source_spec(source.GetPath(false), false,
+ FileSpec::ePathSyntaxPosix);
+ if (source_spec.IsRelative())
+ source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
+ source_spec.GetCString(false));
- Error error;
- auto sync_service = GetSyncService (error);
- if (error.Fail ())
- return error;
+ Error error;
+ auto sync_service = GetSyncService(error);
+ if (error.Fail())
+ return error;
- uint32_t mode = 0, size = 0, mtime = 0;
- error = sync_service->Stat(source_spec, mode, size, mtime);
- if (error.Fail())
- return error;
+ uint32_t mode = 0, size = 0, mtime = 0;
+ error = sync_service->Stat(source_spec, mode, size, mtime);
+ if (error.Fail())
+ return error;
- if (mode != 0)
- return sync_service->PullFile(source_spec, destination);
+ if (mode != 0)
+ return sync_service->PullFile(source_spec, destination);
- auto source_file = source_spec.GetCString(false);
+ auto source_file = source_spec.GetCString(false);
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Got mode == 0 on '%s': try to get file via 'shell cat'", source_file);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("Got mode == 0 on '%s': try to get file via 'shell cat'",
+ source_file);
- if (strchr(source_file, '\'') != nullptr)
- return Error("Doesn't support single-quotes in filenames");
+ if (strchr(source_file, '\'') != nullptr)
+ return Error("Doesn't support single-quotes in filenames");
- // mode == 0 can signify that adbd cannot access the file
- // due security constraints - try "cat ..." as a fallback.
- AdbClient adb(m_device_id);
+ // mode == 0 can signify that adbd cannot access the file
+ // due security constraints - try "cat ..." as a fallback.
+ AdbClient adb(m_device_id);
- char cmd[PATH_MAX];
- snprintf(cmd, sizeof(cmd), "cat '%s'", source_file);
+ char cmd[PATH_MAX];
+ snprintf(cmd, sizeof(cmd), "cat '%s'", source_file);
- return adb.ShellToFile(cmd, 60000 /* ms */, destination);
+ return adb.ShellToFile(cmd, minutes(1), destination);
}
-Error
-PlatformAndroid::PutFile (const FileSpec& source,
- const FileSpec& destination,
- uint32_t uid,
- uint32_t gid)
-{
- if (IsHost() || !m_remote_platform_sp)
- return PlatformLinux::PutFile (source, destination, uid, gid);
-
- FileSpec destination_spec (destination.GetPath (false), false, FileSpec::ePathSyntaxPosix);
- if (destination_spec.IsRelative())
- destination_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (destination_spec.GetCString (false));
-
- // TODO: Set correct uid and gid on remote file.
- Error error;
- auto sync_service = GetSyncService (error);
- if (error.Fail ())
- return error;
- return sync_service->PushFile(source, destination_spec);
+Error PlatformAndroid::PutFile(const FileSpec &source,
+ const FileSpec &destination, uint32_t uid,
+ uint32_t gid) {
+ if (IsHost() || !m_remote_platform_sp)
+ return PlatformLinux::PutFile(source, destination, uid, gid);
+
+ FileSpec destination_spec(destination.GetPath(false), false,
+ FileSpec::ePathSyntaxPosix);
+ if (destination_spec.IsRelative())
+ destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
+ destination_spec.GetCString(false));
+
+ // TODO: Set correct uid and gid on remote file.
+ Error error;
+ auto sync_service = GetSyncService(error);
+ if (error.Fail())
+ return error;
+ return sync_service->PushFile(source, destination_spec);
}
-const char *
-PlatformAndroid::GetCacheHostname ()
-{
- return m_device_id.c_str ();
-}
+const char *PlatformAndroid::GetCacheHostname() { return m_device_id.c_str(); }
-Error
-PlatformAndroid::DownloadModuleSlice (const FileSpec &src_file_spec,
- const uint64_t src_offset,
- const uint64_t src_size,
- const FileSpec &dst_file_spec)
-{
- if (src_offset != 0)
- return Error ("Invalid offset - %" PRIu64, src_offset);
+Error PlatformAndroid::DownloadModuleSlice(const FileSpec &src_file_spec,
+ const uint64_t src_offset,
+ const uint64_t src_size,
+ const FileSpec &dst_file_spec) {
+ if (src_offset != 0)
+ return Error("Invalid offset - %" PRIu64, src_offset);
- return GetFile (src_file_spec, dst_file_spec);
+ return GetFile(src_file_spec, dst_file_spec);
}
-Error
-PlatformAndroid::DisconnectRemote()
-{
- Error error = PlatformLinux::DisconnectRemote();
- if (error.Success())
- {
- m_device_id.clear();
- m_sdk_version = 0;
- }
- return error;
+Error PlatformAndroid::DisconnectRemote() {
+ Error error = PlatformLinux::DisconnectRemote();
+ if (error.Success()) {
+ m_device_id.clear();
+ m_sdk_version = 0;
+ }
+ return error;
}
-uint32_t
-PlatformAndroid::GetDefaultMemoryCacheLineSize()
-{
- return g_android_default_cache_size;
+uint32_t PlatformAndroid::GetDefaultMemoryCacheLineSize() {
+ return g_android_default_cache_size;
}
-uint32_t
-PlatformAndroid::GetSdkVersion()
-{
- if (!IsConnected())
- return 0;
-
- if (m_sdk_version != 0)
- return m_sdk_version;
-
- std::string version_string;
- AdbClient adb(m_device_id);
- Error error = adb.Shell("getprop ro.build.version.sdk", 5000 /* ms */, &version_string);
- version_string = llvm::StringRef(version_string).trim().str();
-
- if (error.Fail() || version_string.empty())
- {
- Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("Get SDK version failed. (error: %s, output: %s)",
- error.AsCString(), version_string.c_str());
- return 0;
- }
+uint32_t PlatformAndroid::GetSdkVersion() {
+ if (!IsConnected())
+ return 0;
- m_sdk_version = StringConvert::ToUInt32(version_string.c_str());
+ if (m_sdk_version != 0)
return m_sdk_version;
+
+ std::string version_string;
+ AdbClient adb(m_device_id);
+ Error error =
+ adb.Shell("getprop ro.build.version.sdk", seconds(5), &version_string);
+ version_string = llvm::StringRef(version_string).trim().str();
+
+ if (error.Fail() || version_string.empty()) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("Get SDK version failed. (error: %s, output: %s)",
+ error.AsCString(), version_string.c_str());
+ return 0;
+ }
+
+ m_sdk_version = StringConvert::ToUInt32(version_string.c_str());
+ return m_sdk_version;
}
-Error
-PlatformAndroid::DownloadSymbolFile (const lldb::ModuleSP& module_sp,
- const FileSpec& dst_file_spec)
-{
- // For oat file we can try to fetch additional debug info from the device
- ConstString extension = module_sp->GetFileSpec().GetFileNameExtension();
- if (extension != ConstString("oat") && extension != ConstString("odex"))
- return Error("Symbol file downloading only supported for oat and odex files");
-
- // If we have no information about the platform file we can't execute oatdump
- if (!module_sp->GetPlatformFileSpec())
- return Error("No platform file specified");
-
- // Symbolizer isn't available before SDK version 23
- if (GetSdkVersion() < 23)
- return Error("Symbol file generation only supported on SDK 23+");
-
- // If we already have symtab then we don't have to try and generate one
- if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) != nullptr)
- return Error("Symtab already available in the module");
-
- AdbClient adb(m_device_id);
- std::string tmpdir;
- Error error = adb.Shell("mktemp --directory --tmpdir /data/local/tmp", 5000 /* ms */, &tmpdir);
- if (error.Fail() || tmpdir.empty())
- return Error("Failed to generate temporary directory on the device (%s)", error.AsCString());
- tmpdir = llvm::StringRef(tmpdir).trim().str();
-
- // Create file remover for the temporary directory created on the device
- std::unique_ptr<std::string, std::function<void(std::string*)>> tmpdir_remover(
- &tmpdir,
- [this, &adb](std::string* s) {
- StreamString command;
- command.Printf("rm -rf %s", s->c_str());
- Error error = adb.Shell(command.GetData(), 5000 /* ms */, nullptr);
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
- if (error.Fail())
- log->Printf("Failed to remove temp directory: %s", error.AsCString());
- }
- );
-
- FileSpec symfile_platform_filespec(tmpdir.c_str(), false);
- symfile_platform_filespec.AppendPathComponent("symbolized.oat");
-
- // Execute oatdump on the remote device to generate a file with symtab
+Error PlatformAndroid::DownloadSymbolFile(const lldb::ModuleSP &module_sp,
+ const FileSpec &dst_file_spec) {
+ // For oat file we can try to fetch additional debug info from the device
+ ConstString extension = module_sp->GetFileSpec().GetFileNameExtension();
+ if (extension != ConstString("oat") && extension != ConstString("odex"))
+ return Error(
+ "Symbol file downloading only supported for oat and odex files");
+
+ // If we have no information about the platform file we can't execute oatdump
+ if (!module_sp->GetPlatformFileSpec())
+ return Error("No platform file specified");
+
+ // Symbolizer isn't available before SDK version 23
+ if (GetSdkVersion() < 23)
+ return Error("Symbol file generation only supported on SDK 23+");
+
+ // If we already have symtab then we don't have to try and generate one
+ if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) !=
+ nullptr)
+ return Error("Symtab already available in the module");
+
+ AdbClient adb(m_device_id);
+ std::string tmpdir;
+ Error error = adb.Shell("mktemp --directory --tmpdir /data/local/tmp",
+ seconds(5), &tmpdir);
+ if (error.Fail() || tmpdir.empty())
+ return Error("Failed to generate temporary directory on the device (%s)",
+ error.AsCString());
+ tmpdir = llvm::StringRef(tmpdir).trim().str();
+
+ // Create file remover for the temporary directory created on the device
+ std::unique_ptr<std::string, std::function<void(std::string *)>>
+ tmpdir_remover(&tmpdir, [this, &adb](std::string *s) {
StreamString command;
- command.Printf("oatdump --symbolize=%s --output=%s",
- module_sp->GetPlatformFileSpec().GetCString(false),
- symfile_platform_filespec.GetCString(false));
- error = adb.Shell(command.GetData(), 60000 /* ms */, nullptr);
- if (error.Fail())
- return Error("Oatdump failed: %s", error.AsCString());
+ command.Printf("rm -rf %s", s->c_str());
+ Error error = adb.Shell(command.GetData(), seconds(5), nullptr);
- // Download the symbolfile from the remote device
- return GetFile(symfile_platform_filespec, dst_file_spec);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log && error.Fail())
+ log->Printf("Failed to remove temp directory: %s", error.AsCString());
+ });
+
+ FileSpec symfile_platform_filespec(tmpdir, false);
+ symfile_platform_filespec.AppendPathComponent("symbolized.oat");
+
+ // Execute oatdump on the remote device to generate a file with symtab
+ StreamString command;
+ command.Printf("oatdump --symbolize=%s --output=%s",
+ module_sp->GetPlatformFileSpec().GetCString(false),
+ symfile_platform_filespec.GetCString(false));
+ error = adb.Shell(command.GetData(), minutes(1), nullptr);
+ if (error.Fail())
+ return Error("Oatdump failed: %s", error.AsCString());
+
+ // Download the symbolfile from the remote device
+ return GetFile(symfile_platform_filespec, dst_file_spec);
}
-bool
-PlatformAndroid::GetRemoteOSVersion ()
-{
- m_major_os_version = GetSdkVersion();
- m_minor_os_version = 0;
- m_update_os_version = 0;
- return m_major_os_version != 0;
+bool PlatformAndroid::GetRemoteOSVersion() {
+ m_major_os_version = GetSdkVersion();
+ m_minor_os_version = 0;
+ m_update_os_version = 0;
+ return m_major_os_version != 0;
}
-const char*
-PlatformAndroid::GetLibdlFunctionDeclarations() const
-{
- return R"(
+const char *PlatformAndroid::GetLibdlFunctionDeclarations() const {
+ return R"(
extern "C" void* dlopen(const char*, int) asm("__dl_dlopen");
extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym");
extern "C" int dlclose(void*) asm("__dl_dlclose");
@@ -419,14 +378,11 @@ PlatformAndroid::GetLibdlFunctionDeclarations() const
)";
}
-AdbClient::SyncService*
-PlatformAndroid::GetSyncService (Error &error)
-{
- if (m_adb_sync_svc && m_adb_sync_svc->IsConnected ())
- return m_adb_sync_svc.get ();
+AdbClient::SyncService *PlatformAndroid::GetSyncService(Error &error) {
+ if (m_adb_sync_svc && m_adb_sync_svc->IsConnected())
+ return m_adb_sync_svc.get();
- AdbClient adb (m_device_id);
- m_adb_sync_svc = adb.GetSyncService (error);
- return (error.Success ()) ? m_adb_sync_svc.get () : nullptr;
+ AdbClient adb(m_device_id);
+ m_adb_sync_svc = adb.GetSyncService(error);
+ return (error.Success()) ? m_adb_sync_svc.get() : nullptr;
}
-
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.h b/source/Plugins/Platform/Android/PlatformAndroid.h
index 6f7a87ca9fef..8417055733f6 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.h
+++ b/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -24,95 +24,69 @@
namespace lldb_private {
namespace platform_android {
- class PlatformAndroid : public platform_linux::PlatformLinux
- {
- public:
- PlatformAndroid(bool is_host);
-
- ~PlatformAndroid() override;
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance (bool force, const ArchSpec *arch);
-
- static ConstString
- GetPluginNameStatic (bool is_host);
-
- static const char *
- GetPluginDescriptionStatic (bool is_host);
-
- ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- Error
- ConnectRemote (Args& args) override;
-
- Error
- GetFile (const FileSpec& source,
- const FileSpec& destination) override;
-
- Error
- PutFile (const FileSpec& source,
- const FileSpec& destination,
- uint32_t uid = UINT32_MAX,
- uint32_t gid = UINT32_MAX) override;
-
- uint32_t
- GetSdkVersion();
-
- bool
- GetRemoteOSVersion() override;
-
- Error
- DisconnectRemote () override;
-
- uint32_t
- GetDefaultMemoryCacheLineSize() override;
-
- protected:
- const char *
- GetCacheHostname () override;
-
- Error
- DownloadModuleSlice (const FileSpec &src_file_spec,
- const uint64_t src_offset,
- const uint64_t src_size,
- const FileSpec &dst_file_spec) override;
-
- Error
- DownloadSymbolFile (const lldb::ModuleSP& module_sp,
- const FileSpec& dst_file_spec) override;
-
- const char*
- GetLibdlFunctionDeclarations() const override;
-
- private:
- AdbClient::SyncService* GetSyncService (Error &error);
-
- std::unique_ptr<AdbClient::SyncService> m_adb_sync_svc;
- std::string m_device_id;
- uint32_t m_sdk_version;
-
- DISALLOW_COPY_AND_ASSIGN (PlatformAndroid);
- };
+class PlatformAndroid : public platform_linux::PlatformLinux {
+public:
+ PlatformAndroid(bool is_host);
+
+ ~PlatformAndroid() override;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+
+ static ConstString GetPluginNameStatic(bool is_host);
+
+ static const char *GetPluginDescriptionStatic(bool is_host);
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+
+ Error ConnectRemote(Args &args) override;
+
+ Error GetFile(const FileSpec &source, const FileSpec &destination) override;
+
+ Error PutFile(const FileSpec &source, const FileSpec &destination,
+ uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override;
+
+ uint32_t GetSdkVersion();
+
+ bool GetRemoteOSVersion() override;
+
+ Error DisconnectRemote() override;
+
+ uint32_t GetDefaultMemoryCacheLineSize() override;
+
+protected:
+ const char *GetCacheHostname() override;
+
+ Error DownloadModuleSlice(const FileSpec &src_file_spec,
+ const uint64_t src_offset, const uint64_t src_size,
+ const FileSpec &dst_file_spec) override;
+
+ Error DownloadSymbolFile(const lldb::ModuleSP &module_sp,
+ const FileSpec &dst_file_spec) override;
+
+ const char *GetLibdlFunctionDeclarations() const override;
+
+private:
+ AdbClient::SyncService *GetSyncService(Error &error);
+
+ std::unique_ptr<AdbClient::SyncService> m_adb_sync_svc;
+ std::string m_device_id;
+ uint32_t m_sdk_version;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformAndroid);
+};
} // namespace platofor_android
} // namespace lldb_private
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index f11f2874e356..cabb3ffb1c15 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -10,8 +10,8 @@
// Other libraries and framework includes
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
-#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/common/TCPSocket.h"
#include "PlatformAndroidRemoteGDBServer.h"
#include "Utility/UriParser.h"
@@ -22,241 +22,212 @@ using namespace lldb;
using namespace lldb_private;
using namespace platform_android;
-static const lldb::pid_t g_remote_platform_pid = 0; // Alias for the process id of lldb-platform
-
-static Error
-ForwardPortWithAdb (const uint16_t local_port,
- const uint16_t remote_port,
- const char* remote_socket_name,
- const llvm::Optional<AdbClient::UnixSocketNamespace>& socket_namespace,
- std::string& device_id)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+static const lldb::pid_t g_remote_platform_pid =
+ 0; // Alias for the process id of lldb-platform
- AdbClient adb;
- auto error = AdbClient::CreateByDeviceID(device_id, adb);
- if (error.Fail ())
- return error;
+static Error ForwardPortWithAdb(
+ const uint16_t local_port, const uint16_t remote_port,
+ llvm::StringRef remote_socket_name,
+ const llvm::Optional<AdbClient::UnixSocketNamespace> &socket_namespace,
+ std::string &device_id) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- device_id = adb.GetDeviceID();
- if (log)
- log->Printf("Connected to Android device \"%s\"", device_id.c_str ());
+ AdbClient adb;
+ auto error = AdbClient::CreateByDeviceID(device_id, adb);
+ if (error.Fail())
+ return error;
- if (remote_port != 0)
- {
- if (log)
- log->Printf("Forwarding remote TCP port %d to local TCP port %d", remote_port, local_port);
- return adb.SetPortForwarding(local_port, remote_port);
- }
+ device_id = adb.GetDeviceID();
+ if (log)
+ log->Printf("Connected to Android device \"%s\"", device_id.c_str());
+ if (remote_port != 0) {
if (log)
- log->Printf("Forwarding remote socket \"%s\" to local TCP port %d", remote_socket_name, local_port);
+ log->Printf("Forwarding remote TCP port %d to local TCP port %d",
+ remote_port, local_port);
+ return adb.SetPortForwarding(local_port, remote_port);
+ }
- if (!socket_namespace)
- return Error("Invalid socket namespace");
+ if (log)
+ log->Printf("Forwarding remote socket \"%s\" to local TCP port %d",
+ remote_socket_name.str().c_str(), local_port);
- return adb.SetPortForwarding(local_port, remote_socket_name, *socket_namespace);
+ if (!socket_namespace)
+ return Error("Invalid socket namespace");
+
+ return adb.SetPortForwarding(local_port, remote_socket_name,
+ *socket_namespace);
}
-static Error
-DeleteForwardPortWithAdb (uint16_t local_port, const std::string& device_id)
-{
- AdbClient adb (device_id);
- return adb.DeletePortForwarding (local_port);
+static Error DeleteForwardPortWithAdb(uint16_t local_port,
+ const std::string &device_id) {
+ AdbClient adb(device_id);
+ return adb.DeletePortForwarding(local_port);
}
-static Error
-FindUnusedPort (uint16_t& port)
-{
- Error error;
- std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(false, error));
- if (error.Fail())
- return error;
+static Error FindUnusedPort(uint16_t &port) {
+ Error error;
+ std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(false, error));
+ if (error.Fail())
+ return error;
- error = tcp_socket->Listen("127.0.0.1:0", 1);
- if (error.Success())
- port = tcp_socket->GetLocalPortNumber();
+ error = tcp_socket->Listen("127.0.0.1:0", 1);
+ if (error.Success())
+ port = tcp_socket->GetLocalPortNumber();
- return error;
+ return error;
}
-PlatformAndroidRemoteGDBServer::PlatformAndroidRemoteGDBServer ()
-{
-}
+PlatformAndroidRemoteGDBServer::PlatformAndroidRemoteGDBServer() {}
-PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer ()
-{
- for (const auto& it : m_port_forwards)
- DeleteForwardPortWithAdb(it.second, m_device_id);
+PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer() {
+ for (const auto &it : m_port_forwards)
+ DeleteForwardPortWithAdb(it.second, m_device_id);
}
-bool
-PlatformAndroidRemoteGDBServer::LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url)
-{
- uint16_t remote_port = 0;
- std::string socket_name;
- if (!m_gdb_client.LaunchGDBServer ("127.0.0.1", pid, remote_port, socket_name))
- return false;
+bool PlatformAndroidRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
+ std::string &connect_url) {
+ uint16_t remote_port = 0;
+ std::string socket_name;
+ if (!m_gdb_client.LaunchGDBServer("127.0.0.1", pid, remote_port, socket_name))
+ return false;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- auto error = MakeConnectURL (pid,
- remote_port,
- socket_name.c_str (),
- connect_url);
- if (error.Success() && log)
- log->Printf("gdbserver connect URL: %s", connect_url.c_str());
+ auto error =
+ MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url);
+ if (error.Success() && log)
+ log->Printf("gdbserver connect URL: %s", connect_url.c_str());
- return error.Success();
+ return error.Success();
}
-bool
-PlatformAndroidRemoteGDBServer::KillSpawnedProcess (lldb::pid_t pid)
-{
- DeleteForwardPort (pid);
- return m_gdb_client.KillSpawnedProcess (pid);
+bool PlatformAndroidRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) {
+ DeleteForwardPort(pid);
+ return m_gdb_client.KillSpawnedProcess(pid);
}
-Error
-PlatformAndroidRemoteGDBServer::ConnectRemote (Args& args)
-{
- m_device_id.clear();
-
- if (args.GetArgumentCount() != 1)
- return Error("\"platform connect\" takes a single argument: <connect-url>");
-
- int remote_port;
- std::string scheme, host, path;
- const char *url = args.GetArgumentAtIndex (0);
- if (!url)
- return Error("URL is null.");
- if (!UriParser::Parse (url, scheme, host, remote_port, path))
- return Error("Invalid URL: %s", url);
- if (host != "localhost")
- m_device_id = host;
-
- m_socket_namespace.reset();
- if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME)
- m_socket_namespace = AdbClient::UnixSocketNamespaceFileSystem;
- else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME)
- m_socket_namespace = AdbClient::UnixSocketNamespaceAbstract;
-
- std::string connect_url;
- auto error = MakeConnectURL (g_remote_platform_pid,
- (remote_port < 0) ? 0 : remote_port,
- path.c_str (),
- connect_url);
-
- if (error.Fail ())
- return error;
-
- args.ReplaceArgumentAtIndex (0, connect_url.c_str ());
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Rewritten platform connect URL: %s", connect_url.c_str());
+Error PlatformAndroidRemoteGDBServer::ConnectRemote(Args &args) {
+ m_device_id.clear();
+
+ if (args.GetArgumentCount() != 1)
+ return Error("\"platform connect\" takes a single argument: <connect-url>");
+
+ int remote_port;
+ llvm::StringRef scheme, host, path;
+ const char *url = args.GetArgumentAtIndex(0);
+ if (!url)
+ return Error("URL is null.");
+ if (!UriParser::Parse(url, scheme, host, remote_port, path))
+ return Error("Invalid URL: %s", url);
+ if (host != "localhost")
+ m_device_id = host;
+
+ m_socket_namespace.reset();
+ if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME)
+ m_socket_namespace = AdbClient::UnixSocketNamespaceFileSystem;
+ else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME)
+ m_socket_namespace = AdbClient::UnixSocketNamespaceAbstract;
+
+ std::string connect_url;
+ auto error =
+ MakeConnectURL(g_remote_platform_pid, (remote_port < 0) ? 0 : remote_port,
+ path, connect_url);
+
+ if (error.Fail())
+ return error;
- error = PlatformRemoteGDBServer::ConnectRemote(args);
- if (error.Fail ())
- DeleteForwardPort (g_remote_platform_pid);
+ args.ReplaceArgumentAtIndex(0, connect_url);
- return error;
-}
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("Rewritten platform connect URL: %s", connect_url.c_str());
-Error
-PlatformAndroidRemoteGDBServer::DisconnectRemote ()
-{
- DeleteForwardPort (g_remote_platform_pid);
- return PlatformRemoteGDBServer::DisconnectRemote ();
+ error = PlatformRemoteGDBServer::ConnectRemote(args);
+ if (error.Fail())
+ DeleteForwardPort(g_remote_platform_pid);
+
+ return error;
}
-void
-PlatformAndroidRemoteGDBServer::DeleteForwardPort (lldb::pid_t pid)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
-
- auto it = m_port_forwards.find(pid);
- if (it == m_port_forwards.end())
- return;
-
- const auto port = it->second;
- const auto error = DeleteForwardPortWithAdb(port, m_device_id);
- if (error.Fail()) {
- if (log)
- log->Printf("Failed to delete port forwarding (pid=%" PRIu64 ", port=%d, device=%s): %s",
- pid, port, m_device_id.c_str(), error.AsCString());
- }
- m_port_forwards.erase(it);
+Error PlatformAndroidRemoteGDBServer::DisconnectRemote() {
+ DeleteForwardPort(g_remote_platform_pid);
+ return PlatformRemoteGDBServer::DisconnectRemote();
}
-Error
-PlatformAndroidRemoteGDBServer::MakeConnectURL(const lldb::pid_t pid,
- const uint16_t remote_port,
- const char* remote_socket_name,
- std::string& connect_url)
-{
- static const int kAttempsNum = 5;
-
- Error error;
- // There is a race possibility that somebody will occupy
- // a port while we're in between FindUnusedPort and ForwardPortWithAdb -
- // adding the loop to mitigate such problem.
- for (auto i = 0; i < kAttempsNum; ++i)
- {
- uint16_t local_port = 0;
- error = FindUnusedPort(local_port);
- if (error.Fail())
- return error;
-
- error = ForwardPortWithAdb(local_port,
- remote_port,
- remote_socket_name,
- m_socket_namespace,
- m_device_id);
- if (error.Success())
- {
- m_port_forwards[pid] = local_port;
- std::ostringstream url_str;
- url_str << "connect://localhost:" << local_port;
- connect_url = url_str.str();
- break;
- }
- }
+void PlatformAndroidRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- return error;
+ auto it = m_port_forwards.find(pid);
+ if (it == m_port_forwards.end())
+ return;
+
+ const auto port = it->second;
+ const auto error = DeleteForwardPortWithAdb(port, m_device_id);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to delete port forwarding (pid=%" PRIu64
+ ", port=%d, device=%s): %s",
+ pid, port, m_device_id.c_str(), error.AsCString());
+ }
+ m_port_forwards.erase(it);
}
-lldb::ProcessSP
-PlatformAndroidRemoteGDBServer::ConnectProcess(const char* connect_url,
- const char* plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error)
-{
- // We don't have the pid of the remote gdbserver when it isn't started by us but we still want
- // to store the list of port forwards we set up in our port forward map. Generate a fake pid for
- // these cases what won't collide with any other valid pid on android.
- static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL;
-
- int remote_port;
- std::string scheme, host, path;
- if (!UriParser::Parse(connect_url, scheme, host, remote_port, path))
- {
- error.SetErrorStringWithFormat("Invalid URL: %s", connect_url);
- return nullptr;
+Error PlatformAndroidRemoteGDBServer::MakeConnectURL(
+ const lldb::pid_t pid, const uint16_t remote_port,
+ llvm::StringRef remote_socket_name, std::string &connect_url) {
+ static const int kAttempsNum = 5;
+
+ Error error;
+ // There is a race possibility that somebody will occupy
+ // a port while we're in between FindUnusedPort and ForwardPortWithAdb -
+ // adding the loop to mitigate such problem.
+ for (auto i = 0; i < kAttempsNum; ++i) {
+ uint16_t local_port = 0;
+ error = FindUnusedPort(local_port);
+ if (error.Fail())
+ return error;
+
+ error = ForwardPortWithAdb(local_port, remote_port, remote_socket_name,
+ m_socket_namespace, m_device_id);
+ if (error.Success()) {
+ m_port_forwards[pid] = local_port;
+ std::ostringstream url_str;
+ url_str << "connect://localhost:" << local_port;
+ connect_url = url_str.str();
+ break;
}
+ }
- std::string new_connect_url;
- error = MakeConnectURL(s_remote_gdbserver_fake_pid--,
- (remote_port < 0) ? 0 : remote_port,
- path.c_str(),
- new_connect_url);
- if (error.Fail())
- return nullptr;
+ return error;
+}
- return PlatformRemoteGDBServer::ConnectProcess(new_connect_url.c_str(),
- plugin_name,
- debugger,
- target,
- error);
+lldb::ProcessSP PlatformAndroidRemoteGDBServer::ConnectProcess(
+ llvm::StringRef connect_url, llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger, lldb_private::Target *target,
+ lldb_private::Error &error) {
+ // We don't have the pid of the remote gdbserver when it isn't started by us
+ // but we still want
+ // to store the list of port forwards we set up in our port forward map.
+ // Generate a fake pid for
+ // these cases what won't collide with any other valid pid on android.
+ static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL;
+
+ int remote_port;
+ llvm::StringRef scheme, host, path;
+ if (!UriParser::Parse(connect_url, scheme, host, remote_port, path)) {
+ error.SetErrorStringWithFormat("Invalid URL: %s",
+ connect_url.str().c_str());
+ return nullptr;
+ }
+
+ std::string new_connect_url;
+ error = MakeConnectURL(s_remote_gdbserver_fake_pid--,
+ (remote_port < 0) ? 0 : remote_port, path,
+ new_connect_url);
+ if (error.Fail())
+ return nullptr;
+
+ return PlatformRemoteGDBServer::ConnectProcess(new_connect_url, plugin_name,
+ debugger, target, error);
}
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
index 79e273c665eb..6d5bfecd9938 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
@@ -26,48 +26,40 @@
namespace lldb_private {
namespace platform_android {
-class PlatformAndroidRemoteGDBServer : public platform_gdb_server::PlatformRemoteGDBServer
-{
+class PlatformAndroidRemoteGDBServer
+ : public platform_gdb_server::PlatformRemoteGDBServer {
public:
- PlatformAndroidRemoteGDBServer();
+ PlatformAndroidRemoteGDBServer();
- ~PlatformAndroidRemoteGDBServer() override;
+ ~PlatformAndroidRemoteGDBServer() override;
- Error
- ConnectRemote (Args& args) override;
+ Error ConnectRemote(Args &args) override;
- Error
- DisconnectRemote () override;
+ Error DisconnectRemote() override;
- lldb::ProcessSP
- ConnectProcess (const char* connect_url,
- const char* plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error) override;
+ lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
+ llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
protected:
- std::string m_device_id;
- std::map<lldb::pid_t, uint16_t> m_port_forwards;
- llvm::Optional<AdbClient::UnixSocketNamespace> m_socket_namespace;
+ std::string m_device_id;
+ std::map<lldb::pid_t, uint16_t> m_port_forwards;
+ llvm::Optional<AdbClient::UnixSocketNamespace> m_socket_namespace;
- bool
- LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url) override;
+ bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override;
- bool
- KillSpawnedProcess (lldb::pid_t pid) override;
+ bool KillSpawnedProcess(lldb::pid_t pid) override;
- void
- DeleteForwardPort (lldb::pid_t pid);
+ void DeleteForwardPort(lldb::pid_t pid);
- Error
- MakeConnectURL(const lldb::pid_t pid,
- const uint16_t remote_port,
- const char* remote_socket_name,
- std::string& connect_url);
+ Error MakeConnectURL(const lldb::pid_t pid, const uint16_t remote_port,
+ llvm::StringRef remote_socket_name,
+ std::string &connect_url);
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformAndroidRemoteGDBServer);
+ DISALLOW_COPY_AND_ASSIGN(PlatformAndroidRemoteGDBServer);
};
} // namespace platform_android
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 83c9247f4682..9ea97a5f70ba 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -21,8 +21,8 @@
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -34,271 +34,232 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_freebsd;
-PlatformSP
-PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch)
-{
- // The only time we create an instance is when we are creating a remote
- // freebsd platform
- const bool is_host = false;
-
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getOS())
- {
- case llvm::Triple::FreeBSD:
- create = true;
- break;
+PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch) {
+ // The only time we create an instance is when we are creating a remote
+ // freebsd platform
+ const bool is_host = false;
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getOS()) {
+ case llvm::Triple::FreeBSD:
+ create = true;
+ break;
#if defined(__FreeBSD__) || defined(__OpenBSD__)
- // Only accept "unknown" for the OS if the host is BSD and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::OSType::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
+ // Only accept "unknown" for the OS if the host is BSD and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::OSType::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
#endif
- default:
- break;
- }
+ default:
+ break;
}
- if (create)
- return PlatformSP(new PlatformFreeBSD (is_host));
- return PlatformSP();
-
+ }
+ if (create)
+ return PlatformSP(new PlatformFreeBSD(is_host));
+ return PlatformSP();
}
-ConstString
-PlatformFreeBSD::GetPluginNameStatic(bool is_host)
-{
- if (is_host)
- {
- static ConstString g_host_name(Platform::GetHostPlatformName ());
- return g_host_name;
- }
- else
- {
- static ConstString g_remote_name("remote-freebsd");
- return g_remote_name;
- }
+ConstString PlatformFreeBSD::GetPluginNameStatic(bool is_host) {
+ if (is_host) {
+ static ConstString g_host_name(Platform::GetHostPlatformName());
+ return g_host_name;
+ } else {
+ static ConstString g_remote_name("remote-freebsd");
+ return g_remote_name;
+ }
}
-const char *
-PlatformFreeBSD::GetDescriptionStatic (bool is_host)
-{
- if (is_host)
- return "Local FreeBSD user platform plug-in.";
- else
- return "Remote FreeBSD user platform plug-in.";
+const char *PlatformFreeBSD::GetDescriptionStatic(bool is_host) {
+ if (is_host)
+ return "Local FreeBSD user platform plug-in.";
+ else
+ return "Remote FreeBSD user platform plug-in.";
}
static uint32_t g_initialize_count = 0;
-void
-PlatformFreeBSD::Initialize ()
-{
- Platform::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
-#if defined (__FreeBSD__)
- // Force a host flag to true for the default platform object.
- PlatformSP default_platform_sp (new PlatformFreeBSD(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform (default_platform_sp);
+void PlatformFreeBSD::Initialize() {
+ Platform::Initialize();
+
+ if (g_initialize_count++ == 0) {
+#if defined(__FreeBSD__)
+ // Force a host flag to true for the default platform object.
+ PlatformSP default_platform_sp(new PlatformFreeBSD(true));
+ default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+ Platform::SetHostPlatform(default_platform_sp);
#endif
- PluginManager::RegisterPlugin(PlatformFreeBSD::GetPluginNameStatic(false),
- PlatformFreeBSD::GetDescriptionStatic(false),
- PlatformFreeBSD::CreateInstance);
- }
+ PluginManager::RegisterPlugin(PlatformFreeBSD::GetPluginNameStatic(false),
+ PlatformFreeBSD::GetDescriptionStatic(false),
+ PlatformFreeBSD::CreateInstance);
+ }
}
-void
-PlatformFreeBSD::Terminate ()
-{
- if (g_initialize_count > 0 && --g_initialize_count == 0)
- PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance);
+void PlatformFreeBSD::Terminate() {
+ if (g_initialize_count > 0 && --g_initialize_count == 0)
+ PluginManager::UnregisterPlugin(PlatformFreeBSD::CreateInstance);
- Platform::Terminate ();
+ Platform::Terminate();
}
-bool
-PlatformFreeBSD::GetModuleSpec (const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
+bool PlatformFreeBSD::GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch,
+ ModuleSpec &module_spec) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
+ module_spec);
- return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
+ return Platform::GetModuleSpec(module_file_spec, arch, module_spec);
}
-Error
-PlatformFreeBSD::RunShellCommand(const char *command,
- const FileSpec &working_dir,
- int *status_ptr,
- int *signo_ptr,
- std::string *command_output,
- uint32_t timeout_sec)
-{
- if (IsHost())
- return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
+Error PlatformFreeBSD::RunShellCommand(const char *command,
+ const FileSpec &working_dir,
+ int *status_ptr, int *signo_ptr,
+ std::string *command_output,
+ uint32_t timeout_sec) {
+ if (IsHost())
+ return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
+ command_output, timeout_sec);
+ else {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->RunShellCommand(command, working_dir,
+ status_ptr, signo_ptr,
+ command_output, timeout_sec);
else
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
- else
- return Error("unable to run a remote command without a platform");
- }
+ return Error("unable to run a remote command without a platform");
+ }
}
-Error
-PlatformFreeBSD::ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec(module_spec);
-
- if (IsHost())
- {
- // If we have "ls" as the module_spec's file, resolve the executable location based on
- // the current path variables
- if (!resolved_module_spec.GetFileSpec().Exists())
- {
- module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
- }
+Error PlatformFreeBSD::ResolveExecutable(
+ const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ char exe_path[PATH_MAX];
+ ModuleSpec resolved_module_spec(module_spec);
+
+ if (IsHost()) {
+ // If we have "ls" as the module_spec's file, resolve the executable
+ // location based on
+ // the current path variables
+ if (!resolved_module_spec.GetFileSpec().Exists()) {
+ module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+ resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
+ }
- if (!resolved_module_spec.GetFileSpec().Exists())
- resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();
+ if (!resolved_module_spec.GetFileSpec().Exists())
+ resolved_module_spec.GetFileSpec().ResolveExecutableLocation();
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- {
- error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else {
+ error.SetErrorStringWithFormat(
+ "unable to find executable for '%s'",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
- else
- {
- if (m_remote_platform_sp)
- {
- error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
- }
- else
- {
- // We may connect to a process and use the provided executable (Don't use local $PATH).
-
- // Resolve any executable within a bundle on MacOSX
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- error.Clear();
- }
- else
- {
- error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+ } else {
+ if (m_remote_platform_sp) {
+ error =
+ GetCachedExecutable(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, *m_remote_platform_sp);
+ } else {
+ // We may connect to a process and use the provided executable (Don't use
+ // local $PATH).
+
+ // Resolve any executable within a bundle on MacOSX
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ error.Clear();
+ } else {
+ error.SetErrorStringWithFormat(
+ "the platform is not currently connected, and '%s' doesn't exist "
+ "in the system root.",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
}
-
- if (error.Success())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
-
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
- {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
+ }
+
+ if (error.Success()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+
+ if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) {
+ exe_module_sp.reset();
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain the architecture %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+ } else {
+ // No valid architecture was specified, ask the platform for
+ // the architectures that we should be using (in the correct order)
+ // and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error =
+ ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
- else
- {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
+ }
}
+ }
- return error;
+ return error;
}
// From PlatformMacOSX only
-Error
-PlatformFreeBSD::GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
- }
+Error PlatformFreeBSD::GetFileWithUUID(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ if (IsRemote()) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
+ local_file);
+ }
- // Default to the local case
- local_file = platform_file;
- return Error();
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
}
-
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformFreeBSD::PlatformFreeBSD (bool is_host) :
- Platform(is_host),
- m_remote_platform_sp()
-{
-}
+PlatformFreeBSD::PlatformFreeBSD(bool is_host)
+ : Platform(is_host), m_remote_platform_sp() {}
//------------------------------------------------------------------
/// Destructor.
@@ -306,409 +267,345 @@ PlatformFreeBSD::PlatformFreeBSD (bool is_host) :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformFreeBSD::~PlatformFreeBSD()
-{
-}
-
-//TODO:VK: inherit PlatformPOSIX
+PlatformFreeBSD::~PlatformFreeBSD() {}
+// TODO:VK: inherit PlatformPOSIX
-bool
-PlatformFreeBSD::GetRemoteOSVersion ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetOSVersion (m_major_os_version,
- m_minor_os_version,
- m_update_os_version);
- return false;
+bool PlatformFreeBSD::GetRemoteOSVersion() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetOSVersion(
+ m_major_os_version, m_minor_os_version, m_update_os_version);
+ return false;
}
-bool
-PlatformFreeBSD::GetRemoteOSBuildString (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSBuildString (s);
- s.clear();
- return false;
+bool PlatformFreeBSD::GetRemoteOSBuildString(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSBuildString(s);
+ s.clear();
+ return false;
}
-bool
-PlatformFreeBSD::GetRemoteOSKernelDescription (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSKernelDescription (s);
- s.clear();
- return false;
+bool PlatformFreeBSD::GetRemoteOSKernelDescription(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
+ s.clear();
+ return false;
}
// Remote Platform subclasses need to override this function
-ArchSpec
-PlatformFreeBSD::GetRemoteSystemArchitecture ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteSystemArchitecture ();
- return ArchSpec();
+ArchSpec PlatformFreeBSD::GetRemoteSystemArchitecture() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteSystemArchitecture();
+ return ArchSpec();
}
+const char *PlatformFreeBSD::GetHostname() {
+ if (IsHost())
+ return Platform::GetHostname();
-const char *
-PlatformFreeBSD::GetHostname ()
-{
- if (IsHost())
- return Platform::GetHostname();
-
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetHostname ();
- return NULL;
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetHostname();
+ return NULL;
}
-bool
-PlatformFreeBSD::IsConnected () const
-{
- if (IsHost())
- return true;
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->IsConnected();
- return false;
+bool PlatformFreeBSD::IsConnected() const {
+ if (IsHost())
+ return true;
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->IsConnected();
+ return false;
}
-Error
-PlatformFreeBSD::ConnectRemote (Args& args)
-{
- Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString());
- }
- else
- {
- if (!m_remote_platform_sp)
- m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error);
-
- if (m_remote_platform_sp)
- {
- if (error.Success())
- {
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->ConnectRemote (args);
- }
- else
- {
- error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
- }
- }
+Error PlatformFreeBSD::ConnectRemote(Args &args) {
+ Error error;
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't connect to the host platform '%s', always connected",
+ GetPluginName().GetCString());
+ } else {
+ if (!m_remote_platform_sp)
+ m_remote_platform_sp =
+ Platform::Create(ConstString("remote-gdb-server"), error);
+
+ if (m_remote_platform_sp) {
+ if (error.Success()) {
+ if (m_remote_platform_sp) {
+ error = m_remote_platform_sp->ConnectRemote(args);
+ } else {
+ error.SetErrorString(
+ "\"platform connect\" takes a single argument: <connect-url>");
}
- else
- error.SetErrorString ("failed to create a 'remote-gdb-server' platform");
+ }
+ } else
+ error.SetErrorString("failed to create a 'remote-gdb-server' platform");
- if (error.Fail())
- m_remote_platform_sp.reset();
- }
+ if (error.Fail())
+ m_remote_platform_sp.reset();
+ }
- return error;
+ return error;
}
-Error
-PlatformFreeBSD::DisconnectRemote ()
-{
- Error error;
+Error PlatformFreeBSD::DisconnectRemote() {
+ Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString());
- }
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't disconnect from the host platform '%s', always connected",
+ GetPluginName().GetCString());
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->DisconnectRemote();
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->DisconnectRemote ();
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-bool
-PlatformFreeBSD::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- bool success = false;
- if (IsHost())
- {
- success = Platform::GetProcessInfo (pid, process_info);
- }
- else if (m_remote_platform_sp)
- {
- success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
- }
- return success;
+bool PlatformFreeBSD::GetProcessInfo(lldb::pid_t pid,
+ ProcessInstanceInfo &process_info) {
+ bool success = false;
+ if (IsHost()) {
+ success = Platform::GetProcessInfo(pid, process_info);
+ } else if (m_remote_platform_sp) {
+ success = m_remote_platform_sp->GetProcessInfo(pid, process_info);
+ }
+ return success;
}
uint32_t
-PlatformFreeBSD::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- uint32_t match_count = 0;
- if (IsHost())
- {
- // Let the base class figure out the host details
- match_count = Platform::FindProcesses (match_info, process_infos);
- }
- else
- {
- // If we are remote, we can only return results if we are connected
- if (m_remote_platform_sp)
- match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
- }
- return match_count;
-}
-
-const char *
-PlatformFreeBSD::GetUserName (uint32_t uid)
-{
- // Check the cache in Platform in case we have already looked this uid up
- const char *user_name = Platform::GetUserName(uid);
- if (user_name)
- return user_name;
-
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetUserName(uid);
- return NULL;
+PlatformFreeBSD::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ uint32_t match_count = 0;
+ if (IsHost()) {
+ // Let the base class figure out the host details
+ match_count = Platform::FindProcesses(match_info, process_infos);
+ } else {
+ // If we are remote, we can only return results if we are connected
+ if (m_remote_platform_sp)
+ match_count =
+ m_remote_platform_sp->FindProcesses(match_info, process_infos);
+ }
+ return match_count;
}
-const char *
-PlatformFreeBSD::GetGroupName (uint32_t gid)
-{
- const char *group_name = Platform::GetGroupName(gid);
- if (group_name)
- return group_name;
+const char *PlatformFreeBSD::GetUserName(uint32_t uid) {
+ // Check the cache in Platform in case we have already looked this uid up
+ const char *user_name = Platform::GetUserName(uid);
+ if (user_name)
+ return user_name;
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetGroupName(gid);
- return NULL;
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetUserName(uid);
+ return NULL;
}
+const char *PlatformFreeBSD::GetGroupName(uint32_t gid) {
+ const char *group_name = Platform::GetGroupName(gid);
+ if (group_name)
+ return group_name;
-Error
-PlatformFreeBSD::GetSharedModule (const ModuleSpec &module_spec,
- Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- Error error;
- module_sp.reset();
-
- if (IsRemote())
- {
- // If we have a remote platform always, let it try and locate
- // the shared module first.
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
- }
- }
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetGroupName(gid);
+ return NULL;
+}
- if (!module_sp)
- {
- // Fall back to the local platform and find the file locally
- error = Platform::GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
+Error PlatformFreeBSD::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ Error error;
+ module_sp.reset();
+
+ if (IsRemote()) {
+ // If we have a remote platform always, let it try and locate
+ // the shared module first.
+ if (m_remote_platform_sp) {
+ error = m_remote_platform_sp->GetSharedModule(
+ module_spec, process, module_sp, module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
}
- if (module_sp)
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return error;
+ }
+
+ if (!module_sp) {
+ // Fall back to the local platform and find the file locally
+ error = Platform::GetSharedModule(module_spec, process, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
+ return error;
}
-
-bool
-PlatformFreeBSD::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- if (IsHost())
- {
- ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- if (hostArch.GetTriple().isOSFreeBSD())
- {
- if (idx == 0)
- {
- arch = hostArch;
- return arch.IsValid();
- }
- else if (idx == 1)
- {
- // If the default host architecture is 64-bit, look for a 32-bit variant
- if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
- {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return arch.IsValid();
- }
- }
+bool PlatformFreeBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ if (IsHost()) {
+ ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ if (hostArch.GetTriple().isOSFreeBSD()) {
+ if (idx == 0) {
+ arch = hostArch;
+ return arch.IsValid();
+ } else if (idx == 1) {
+ // If the default host architecture is 64-bit, look for a 32-bit variant
+ if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) {
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ return arch.IsValid();
}
+ }
}
- else
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
-
- llvm::Triple triple;
- // Set the OS to FreeBSD
- triple.setOS(llvm::Triple::FreeBSD);
- // Set the architecture
- switch (idx)
- {
- case 0: triple.setArchName("x86_64"); break;
- case 1: triple.setArchName("i386"); break;
- case 2: triple.setArchName("aarch64"); break;
- case 3: triple.setArchName("arm"); break;
- case 4: triple.setArchName("mips64"); break;
- case 5: triple.setArchName("mips"); break;
- case 6: triple.setArchName("ppc64"); break;
- case 7: triple.setArchName("ppc"); break;
- default: return false;
- }
- // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified unknown".
- // This means when someone calls triple.GetVendorName() it will return an empty string
- // which indicates that the vendor can be set when two architectures are merged
-
- // Now set the triple into "arch" and return true
- arch.SetTriple(triple);
- return true;
+ } else {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
+
+ llvm::Triple triple;
+ // Set the OS to FreeBSD
+ triple.setOS(llvm::Triple::FreeBSD);
+ // Set the architecture
+ switch (idx) {
+ case 0:
+ triple.setArchName("x86_64");
+ break;
+ case 1:
+ triple.setArchName("i386");
+ break;
+ case 2:
+ triple.setArchName("aarch64");
+ break;
+ case 3:
+ triple.setArchName("arm");
+ break;
+ case 4:
+ triple.setArchName("mips64");
+ break;
+ case 5:
+ triple.setArchName("mips");
+ break;
+ case 6:
+ triple.setArchName("ppc64");
+ break;
+ case 7:
+ triple.setArchName("ppc");
+ break;
+ default:
+ return false;
}
- return false;
+ // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
+ // vendor by
+ // calling triple.SetVendorName("unknown") so that it is a "unspecified
+ // unknown".
+ // This means when someone calls triple.GetVendorName() it will return an
+ // empty string
+ // which indicates that the vendor can be set when two architectures are
+ // merged
+
+ // Now set the triple into "arch" and return true
+ arch.SetTriple(triple);
+ return true;
+ }
+ return false;
}
-void
-PlatformFreeBSD::GetStatus (Stream &strm)
-{
+void PlatformFreeBSD::GetStatus(Stream &strm) {
#ifndef LLDB_DISABLE_POSIX
- struct utsname un;
+ struct utsname un;
- strm << " Host: ";
+ strm << " Host: ";
- ::memset(&un, 0, sizeof(utsname));
- if (uname(&un) == -1)
- strm << "FreeBSD" << '\n';
+ ::memset(&un, 0, sizeof(utsname));
+ if (uname(&un) == -1)
+ strm << "FreeBSD" << '\n';
- strm << un.sysname << ' ' << un.release;
- if (un.nodename[0] != '\0')
- strm << " (" << un.nodename << ')';
- strm << '\n';
+ strm << un.sysname << ' ' << un.release;
+ if (un.nodename[0] != '\0')
+ strm << " (" << un.nodename << ')';
+ strm << '\n';
- // Dump a common information about the platform status.
- strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version << '\n';
+ // Dump a common information about the platform status.
+ strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version
+ << '\n';
#endif
- Platform::GetStatus(strm);
+ Platform::GetStatus(strm);
}
size_t
-PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
-{
- switch (target.GetArchitecture().GetMachine())
- {
- case llvm::Triple::arm:
- {
- lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
- AddressClass addr_class = eAddressClassUnknown;
-
- if (bp_loc_sp)
- {
- addr_class = bp_loc_sp->GetAddress().GetAddressClass();
- if (addr_class == eAddressClassUnknown && (bp_loc_sp->GetAddress().GetFileAddress() & 1))
- addr_class = eAddressClassCodeAlternateISA;
- }
-
- if (addr_class == eAddressClassCodeAlternateISA)
- {
- // TODO: Enable when FreeBSD supports thumb breakpoints.
- // FreeBSD kernel as of 10.x, does not support thumb breakpoints
- return 0;
- }
- }
- LLVM_FALLTHROUGH;
- default:
- return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
+PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode(Target &target,
+ BreakpointSite *bp_site) {
+ switch (target.GetArchitecture().GetMachine()) {
+ case llvm::Triple::arm: {
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ AddressClass addr_class = eAddressClassUnknown;
+
+ if (bp_loc_sp) {
+ addr_class = bp_loc_sp->GetAddress().GetAddressClass();
+ if (addr_class == eAddressClassUnknown &&
+ (bp_loc_sp->GetAddress().GetFileAddress() & 1))
+ addr_class = eAddressClassCodeAlternateISA;
}
-}
+ if (addr_class == eAddressClassCodeAlternateISA) {
+ // TODO: Enable when FreeBSD supports thumb breakpoints.
+ // FreeBSD kernel as of 10.x, does not support thumb breakpoints
+ return 0;
+ }
+ }
+ LLVM_FALLTHROUGH;
+ default:
+ return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
+ }
+}
-void
-PlatformFreeBSD::CalculateTrapHandlerSymbolNames ()
-{
- m_trap_handlers.push_back (ConstString ("_sigtramp"));
+void PlatformFreeBSD::CalculateTrapHandlerSymbolNames() {
+ m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-Error
-PlatformFreeBSD::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Error error;
- if (IsHost())
- {
- error = Platform::LaunchProcess (launch_info);
- }
+Error PlatformFreeBSD::LaunchProcess(ProcessLaunchInfo &launch_info) {
+ Error error;
+ if (IsHost()) {
+ error = Platform::LaunchProcess(launch_info);
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->LaunchProcess(launch_info);
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->LaunchProcess (launch_info);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-lldb::ProcessSP
-PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error)
-{
- lldb::ProcessSP process_sp;
- if (IsHost())
- {
- if (target == NULL)
- {
- TargetSP new_target_sp;
- ArchSpec emptyArchSpec;
-
- error = debugger.GetTargetList().CreateTarget (debugger,
- NULL,
- emptyArchSpec,
- false,
- m_remote_platform_sp,
- new_target_sp);
- target = new_target_sp.get();
- }
- else
- error.Clear();
-
- if (target && error.Success())
- {
- debugger.GetTargetList().SetSelectedTarget(target);
- // The freebsd always currently uses the GDB remote debugger plug-in
- // so even when debugging locally we are debugging remotely!
- // Just like the darwin plugin.
- process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
-
- if (process_sp)
- error = process_sp->Attach (attach_info);
- }
+lldb::ProcessSP PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger, Target *target,
+ Error &error) {
+ lldb::ProcessSP process_sp;
+ if (IsHost()) {
+ if (target == NULL) {
+ TargetSP new_target_sp;
+ ArchSpec emptyArchSpec;
+
+ error = debugger.GetTargetList().CreateTarget(debugger, "", emptyArchSpec,
+ false, m_remote_platform_sp,
+ new_target_sp);
+ target = new_target_sp.get();
+ } else
+ error.Clear();
+
+ if (target && error.Success()) {
+ debugger.GetTargetList().SetSelectedTarget(target);
+ // The freebsd always currently uses the GDB remote debugger plug-in
+ // so even when debugging locally we are debugging remotely!
+ // Just like the darwin plugin.
+ process_sp = target->CreateProcess(
+ attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
+
+ if (process_sp)
+ error = process_sp->Attach(attach_info);
}
+ } else {
+ if (m_remote_platform_sp)
+ process_sp =
+ m_remote_platform_sp->Attach(attach_info, debugger, target, error);
else
- {
- if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return process_sp;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return process_sp;
}
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index d1bfc438a341..f0ebfbcae701 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -19,157 +19,111 @@
namespace lldb_private {
namespace platform_freebsd {
- class PlatformFreeBSD : public Platform
- {
- public:
- PlatformFreeBSD(bool is_host);
-
- ~PlatformFreeBSD() override;
-
- //------------------------------------------------------------
- // Class functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance(bool force, const ArchSpec *arch);
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static ConstString
- GetPluginNameStatic (bool is_host);
-
- static const char *
- GetDescriptionStatic (bool is_host);
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic (IsHost());
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic(IsHost());
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- bool
- GetModuleSpec(const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec) override;
-
- Error
- RunShellCommand(const char *command,
- const FileSpec &working_dir,
- int *status_ptr,
- int *signo_ptr,
+class PlatformFreeBSD : public Platform {
+public:
+ PlatformFreeBSD(bool is_host);
+
+ ~PlatformFreeBSD() override;
+
+ //------------------------------------------------------------
+ // Class functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic(bool is_host);
+
+ static const char *GetDescriptionStatic(bool is_host);
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ ConstString GetPluginName() override { return GetPluginNameStatic(IsHost()); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ const char *GetDescription() override {
+ return GetDescriptionStatic(IsHost());
+ }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
+ ModuleSpec &module_spec) override;
+
+ Error RunShellCommand(const char *command, const FileSpec &working_dir,
+ int *status_ptr, int *signo_ptr,
std::string *command_output,
uint32_t timeout_sec) override;
- Error
- ResolveExecutable(const ModuleSpec &module_spec,
+ Error ResolveExecutable(const ModuleSpec &module_spec,
lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr) override;
- size_t
- GetSoftwareBreakpointTrapOpcode(Target &target,
- BreakpointSite *bp_site) override;
+ size_t GetSoftwareBreakpointTrapOpcode(Target &target,
+ BreakpointSite *bp_site) override;
- bool
- GetRemoteOSVersion () override;
+ bool GetRemoteOSVersion() override;
- bool
- GetRemoteOSBuildString (std::string &s) override;
+ bool GetRemoteOSBuildString(std::string &s) override;
- bool
- GetRemoteOSKernelDescription (std::string &s) override;
+ bool GetRemoteOSKernelDescription(std::string &s) override;
- // Remote Platform subclasses need to override this function
- ArchSpec
- GetRemoteSystemArchitecture() override;
+ // Remote Platform subclasses need to override this function
+ ArchSpec GetRemoteSystemArchitecture() override;
- bool
- IsConnected () const override;
+ bool IsConnected() const override;
- Error
- ConnectRemote(Args& args) override;
+ Error ConnectRemote(Args &args) override;
- Error
- DisconnectRemote() override;
+ Error DisconnectRemote() override;
- const char *
- GetHostname () override;
+ const char *GetHostname() override;
- const char *
- GetUserName (uint32_t uid) override;
+ const char *GetUserName(uint32_t uid) override;
- const char *
- GetGroupName (uint32_t gid) override;
+ const char *GetGroupName(uint32_t gid) override;
- bool
- GetProcessInfo(lldb::pid_t pid,
- ProcessInstanceInfo &proc_info) override;
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
- uint32_t
- FindProcesses(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) override;
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) override;
- Error
- LaunchProcess(ProcessLaunchInfo &launch_info) override;
+ Error LaunchProcess(ProcessLaunchInfo &launch_info) override;
- lldb::ProcessSP
- Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error) override;
+ lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, Error &error) override;
- // FreeBSD processes can not be launched by spawning and attaching.
- bool
- CanDebugProcess () override { return false; }
+ // FreeBSD processes can not be launched by spawning and attaching.
+ bool CanDebugProcess() override { return false; }
- // Only on PlatformMacOSX:
- Error
- GetFileWithUUID(const FileSpec &platform_file,
- const UUID* uuid, FileSpec &local_file) override;
+ // Only on PlatformMacOSX:
+ Error GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid,
+ FileSpec &local_file) override;
- Error
- GetSharedModule(const ModuleSpec &module_spec,
- Process* process,
+ Error GetSharedModule(const ModuleSpec &module_spec, Process *process,
lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr,
lldb::ModuleSP *old_module_sp_ptr,
bool *did_create_ptr) override;
- bool
- GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
+ bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
- void
- GetStatus(Stream &strm) override;
+ void GetStatus(Stream &strm) override;
- void
- CalculateTrapHandlerSymbolNames () override;
+ void CalculateTrapHandlerSymbolNames() override;
- protected:
- lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote freebsd OS
+protected:
+ lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a
+ // remote freebsd OS
- private:
- DISALLOW_COPY_AND_ASSIGN (PlatformFreeBSD);
- };
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformFreeBSD);
+};
} // namespace platform_freebsd
} // namespace lldb_private
diff --git a/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp b/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
index 2f1e4d554320..ac3fe6eafd52 100644
--- a/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
+++ b/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
@@ -1,4 +1,5 @@
-//===-- PlatformKalimba.cpp ---------------------------------------*- C++ -*-===//
+//===-- PlatformKalimba.cpp ---------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,8 +14,8 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Error.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -22,202 +23,171 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
static uint32_t g_initialize_count = 0;
-PlatformSP
-PlatformKalimba::CreateInstance (bool force, const ArchSpec *arch)
-{
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- case llvm::Triple::CSR:
- create = true;
- break;
-
- default:
- break;
- }
+PlatformSP PlatformKalimba::CreateInstance(bool force, const ArchSpec *arch) {
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::CSR:
+ create = true;
+ break;
+
+ default:
+ break;
}
- if (create)
- return PlatformSP(new PlatformKalimba(false));
- return PlatformSP();
+ }
+ if (create)
+ return PlatformSP(new PlatformKalimba(false));
+ return PlatformSP();
}
lldb_private::ConstString
-PlatformKalimba::GetPluginNameStatic (bool /*is_host*/)
-{
- static ConstString g_remote_name("kalimba");
- return g_remote_name;
+PlatformKalimba::GetPluginNameStatic(bool /*is_host*/) {
+ static ConstString g_remote_name("kalimba");
+ return g_remote_name;
}
-const char *
-PlatformKalimba::GetPluginDescriptionStatic (bool /*is_host*/)
-{
- return "Kalimba user platform plug-in.";
+const char *PlatformKalimba::GetPluginDescriptionStatic(bool /*is_host*/) {
+ return "Kalimba user platform plug-in.";
}
-lldb_private::ConstString
-PlatformKalimba::GetPluginName()
-{
- return GetPluginNameStatic(false);
+lldb_private::ConstString PlatformKalimba::GetPluginName() {
+ return GetPluginNameStatic(false);
}
-void
-PlatformKalimba::Initialize ()
-{
- Platform::Initialize ();
+void PlatformKalimba::Initialize() {
+ Platform::Initialize();
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin(PlatformKalimba::GetPluginNameStatic(false),
- PlatformKalimba::GetPluginDescriptionStatic(false),
- PlatformKalimba::CreateInstance);
- }
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(
+ PlatformKalimba::GetPluginNameStatic(false),
+ PlatformKalimba::GetPluginDescriptionStatic(false),
+ PlatformKalimba::CreateInstance);
+ }
}
-void
-PlatformKalimba::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformKalimba::CreateInstance);
- }
+void PlatformKalimba::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformKalimba::CreateInstance);
}
+ }
- Platform::Terminate ();
+ Platform::Terminate();
}
-Error
-PlatformKalimba::ResolveExecutable (const ModuleSpec &ms,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec(ms);
-
- if (!resolved_module_spec.GetFileSpec().Exists())
- {
- resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
- }
+Error PlatformKalimba::ResolveExecutable(
+ const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ char exe_path[PATH_MAX];
+ ModuleSpec resolved_module_spec(ms);
+
+ if (!resolved_module_spec.GetFileSpec().Exists()) {
+ resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+ error.SetErrorStringWithFormat("unable to find executable for '%s'",
+ exe_path);
+ }
+
+ if (error.Success()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ if (error.Fail()) {
+ // If we failed, it may be because the vendor and os aren't known. If
+ // that is the
+ // case, try setting them to the host architecture and give it another
+ // try.
+ llvm::Triple &module_triple =
+ resolved_module_spec.GetArchitecture().GetTriple();
+ bool is_vendor_specified =
+ (module_triple.getVendor() != llvm::Triple::UnknownVendor);
+ bool is_os_specified =
+ (module_triple.getOS() != llvm::Triple::UnknownOS);
+ if (!is_vendor_specified || !is_os_specified) {
+ const llvm::Triple &host_triple =
+ HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
+
+ if (!is_vendor_specified)
+ module_triple.setVendorName(host_triple.getVendorName());
+ if (!is_os_specified)
+ module_triple.setOSName(host_triple.getOSName());
- if (error.Success())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- if (error.Fail())
- {
- // If we failed, it may be because the vendor and os aren't known. If that is the
- // case, try setting them to the host architecture and give it another try.
- llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple();
- bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
- bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
- if (!is_vendor_specified || !is_os_specified)
- {
- const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
-
- if (!is_vendor_specified)
- module_triple.setVendorName (host_triple.getVendorName());
- if (!is_os_specified)
- module_triple.setOSName (host_triple.getOSName());
-
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- }
- }
-
- // TODO find out why exe_module_sp might be NULL
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
- {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
+ error = ModuleList::GetSharedModule(resolved_module_spec,
+ exe_module_sp, NULL, NULL, NULL);
}
- else
- {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+ }
+
+ // TODO find out why exe_module_sp might be NULL
+ if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) {
+ exe_module_sp.reset();
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain the architecture %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+ } else {
+ // No valid architecture was specified, ask the platform for
+ // the architectures that we should be using (in the correct order)
+ // and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
+ }
}
+ }
- return error;
+ return error;
}
-Error
-PlatformKalimba::GetFileWithUUID (const FileSpec & /*platform_file*/,
- const UUID * /*uuid_ptr*/, FileSpec & /*local_file*/)
-{
- return Error();
+Error PlatformKalimba::GetFileWithUUID(const FileSpec & /*platform_file*/,
+ const UUID * /*uuid_ptr*/,
+ FileSpec & /*local_file*/) {
+ return Error();
}
-
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformKalimba::PlatformKalimba (bool is_host) :
- Platform(is_host), // This is the local host platform
- m_remote_platform_sp ()
-{
-}
+PlatformKalimba::PlatformKalimba(bool is_host)
+ : Platform(is_host), // This is the local host platform
+ m_remote_platform_sp() {}
//------------------------------------------------------------------
/// Destructor.
@@ -225,100 +195,73 @@ PlatformKalimba::PlatformKalimba (bool is_host) :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformKalimba::~PlatformKalimba()
-{
-}
+PlatformKalimba::~PlatformKalimba() {}
-bool
-PlatformKalimba::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- bool success = false;
- if (IsHost())
- {
- success = false;
- }
- else
- {
- if (m_remote_platform_sp)
- success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
- }
- return success;
+bool PlatformKalimba::GetProcessInfo(lldb::pid_t pid,
+ ProcessInstanceInfo &process_info) {
+ bool success = false;
+ if (IsHost()) {
+ success = false;
+ } else {
+ if (m_remote_platform_sp)
+ success = m_remote_platform_sp->GetProcessInfo(pid, process_info);
+ }
+ return success;
}
-bool
-PlatformKalimba::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- if (idx == 0)
- {
- arch = ArchSpec("kalimba3-csr-unknown");
- return true;
- }
- if (idx == 1)
- {
- arch = ArchSpec("kalimba4-csr-unknown");
- return true;
- }
- if (idx == 2)
- {
- arch = ArchSpec("kalimba5-csr-unknown");
- return true;
- }
- return false;
+bool PlatformKalimba::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ if (idx == 0) {
+ arch = ArchSpec("kalimba3-csr-unknown");
+ return true;
+ }
+ if (idx == 1) {
+ arch = ArchSpec("kalimba4-csr-unknown");
+ return true;
+ }
+ if (idx == 2) {
+ arch = ArchSpec("kalimba5-csr-unknown");
+ return true;
+ }
+ return false;
}
-void
-PlatformKalimba::GetStatus (Stream &strm)
-{
- Platform::GetStatus(strm);
-}
+void PlatformKalimba::GetStatus(Stream &strm) { Platform::GetStatus(strm); }
size_t
-PlatformKalimba::GetSoftwareBreakpointTrapOpcode (Target & /*target*/,
- BreakpointSite * /*bp_site*/)
-{
- // the target hardware does not support software breakpoints
- return 0;
+PlatformKalimba::GetSoftwareBreakpointTrapOpcode(Target & /*target*/,
+ BreakpointSite * /*bp_site*/) {
+ // the target hardware does not support software breakpoints
+ return 0;
}
-Error
-PlatformKalimba::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Error error;
-
- if (IsHost())
- {
- error.SetErrorString ("native execution is not possible");
- }
- else
- {
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+Error PlatformKalimba::LaunchProcess(ProcessLaunchInfo &launch_info) {
+ Error error;
+
+ if (IsHost()) {
+ error.SetErrorString("native execution is not possible");
+ } else {
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-lldb::ProcessSP
-PlatformKalimba::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error)
-{
- lldb::ProcessSP process_sp;
- if (IsHost())
- {
- error.SetErrorString ("native execution is not possible");
- }
+lldb::ProcessSP PlatformKalimba::Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger, Target *target,
+ Error &error) {
+ lldb::ProcessSP process_sp;
+ if (IsHost()) {
+ error.SetErrorString("native execution is not possible");
+ } else {
+ if (m_remote_platform_sp)
+ process_sp =
+ m_remote_platform_sp->Attach(attach_info, debugger, target, error);
else
- {
- if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return process_sp;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return process_sp;
}
-void
-PlatformKalimba::CalculateTrapHandlerSymbolNames ()
-{
- // TODO Research this sometime.
-}
+void PlatformKalimba::CalculateTrapHandlerSymbolNames() {
+ // TODO Research this sometime.
+}
diff --git a/source/Plugins/Platform/Kalimba/PlatformKalimba.h b/source/Plugins/Platform/Kalimba/PlatformKalimba.h
index dd68415838f0..76e6d41e8716 100644
--- a/source/Plugins/Platform/Kalimba/PlatformKalimba.h
+++ b/source/Plugins/Platform/Kalimba/PlatformKalimba.h
@@ -18,81 +18,70 @@
namespace lldb_private {
- class PlatformKalimba : public Platform
- {
- public:
- PlatformKalimba(bool is_host);
+class PlatformKalimba : public Platform {
+public:
+ PlatformKalimba(bool is_host);
- ~PlatformKalimba() override;
+ ~PlatformKalimba() override;
- static void
- Initialize ();
+ static void Initialize();
- static void
- Terminate ();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance (bool force, const lldb_private::ArchSpec *arch);
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic (bool is_host);
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch);
- static const char *
- GetPluginDescriptionStatic (bool is_host);
+ static lldb_private::ConstString GetPluginNameStatic(bool is_host);
- lldb_private::ConstString GetPluginName() override;
+ static const char *GetPluginDescriptionStatic(bool is_host);
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ lldb_private::ConstString GetPluginName() override;
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- Error ResolveExecutable(const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr) override;
+ uint32_t GetPluginVersion() override { return 1; }
- const char *
- GetDescription() override
- {
- return GetPluginDescriptionStatic(IsHost());
- }
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ Error ResolveExecutable(const lldb_private::ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr) override;
- void GetStatus(Stream &strm) override;
+ const char *GetDescription() override {
+ return GetPluginDescriptionStatic(IsHost());
+ }
- Error GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid, FileSpec &local_file) override;
+ void GetStatus(Stream &strm) override;
- bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
+ Error GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid,
+ FileSpec &local_file) override;
- bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
- size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site) override;
+ bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
- lldb_private::Error LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
+ size_t GetSoftwareBreakpointTrapOpcode(Target &target,
+ BreakpointSite *bp_site) override;
- lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target,
- Error &error) override;
+ lldb_private::Error
+ LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
- // Kalimba processes can not be launched by spawning and attaching.
- bool
- CanDebugProcess() override
- {
- return false;
- }
+ lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, Error &error) override;
- void CalculateTrapHandlerSymbolNames() override;
+ // Kalimba processes can not be launched by spawning and attaching.
+ bool CanDebugProcess() override { return false; }
- protected:
- lldb::PlatformSP m_remote_platform_sp;
+ void CalculateTrapHandlerSymbolNames() override;
- private:
- DISALLOW_COPY_AND_ASSIGN (PlatformKalimba);
- };
+protected:
+ lldb::PlatformSP m_remote_platform_sp;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformKalimba);
+};
} // namespace lldb_private
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 846e350eec56..036c0f1be835 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -33,8 +33,8 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Property.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
// Define these constants from Linux mman.h for use when targeting
// remote linux systems even when host has different values.
@@ -51,352 +51,305 @@ static uint32_t g_initialize_count = 0;
/// Code to handle the PlatformLinux settings
//------------------------------------------------------------------
-namespace
-{
- class PlatformLinuxProperties : public Properties
- {
- public:
- PlatformLinuxProperties();
+namespace {
+class PlatformLinuxProperties : public Properties {
+public:
+ PlatformLinuxProperties();
- ~PlatformLinuxProperties() override = default;
+ ~PlatformLinuxProperties() override = default;
- static ConstString&
- GetSettingName ();
+ static ConstString &GetSettingName();
- private:
- static const PropertyDefinition*
- GetStaticPropertyDefinitions();
- };
+private:
+ static const PropertyDefinition *GetStaticPropertyDefinitions();
+};
- typedef std::shared_ptr<PlatformLinuxProperties> PlatformLinuxPropertiesSP;
+typedef std::shared_ptr<PlatformLinuxProperties> PlatformLinuxPropertiesSP;
} // anonymous namespace
-PlatformLinuxProperties::PlatformLinuxProperties() :
- Properties ()
-{
- m_collection_sp.reset (new OptionValueProperties(GetSettingName ()));
- m_collection_sp->Initialize (GetStaticPropertyDefinitions ());
+PlatformLinuxProperties::PlatformLinuxProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(GetStaticPropertyDefinitions());
}
-ConstString&
-PlatformLinuxProperties::GetSettingName ()
-{
- static ConstString g_setting_name("linux");
- return g_setting_name;
+ConstString &PlatformLinuxProperties::GetSettingName() {
+ static ConstString g_setting_name("linux");
+ return g_setting_name;
}
-const PropertyDefinition*
-PlatformLinuxProperties::GetStaticPropertyDefinitions()
-{
- static PropertyDefinition
- g_properties[] =
- {
- { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL }
- };
+const PropertyDefinition *
+PlatformLinuxProperties::GetStaticPropertyDefinitions() {
+ static PropertyDefinition g_properties[] = {
+ {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
- return g_properties;
+ return g_properties;
}
-static const PlatformLinuxPropertiesSP &
-GetGlobalProperties()
-{
- static PlatformLinuxPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new PlatformLinuxProperties ());
- return g_settings_sp;
+static const PlatformLinuxPropertiesSP &GetGlobalProperties() {
+ static PlatformLinuxPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new PlatformLinuxProperties());
+ return g_settings_sp;
}
-void
-PlatformLinux::DebuggerInitialize (Debugger &debugger)
-{
- if (!PluginManager::GetSettingForPlatformPlugin (debugger, PlatformLinuxProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForPlatformPlugin (debugger,
- GetGlobalProperties()->GetValueProperties(),
- ConstString ("Properties for the PlatformLinux plug-in."),
- is_global_setting);
- }
+void PlatformLinux::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForPlatformPlugin(
+ debugger, PlatformLinuxProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForPlatformPlugin(
+ debugger, GetGlobalProperties()->GetValueProperties(),
+ ConstString("Properties for the PlatformLinux plug-in."),
+ is_global_setting);
+ }
}
//------------------------------------------------------------------
-PlatformSP
-PlatformLinux::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>";
+PlatformSP PlatformLinux::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>";
+ const char *triple_cstr =
+ arch ? arch->GetTriple().getTriple().c_str() : "<null>";
- log->Printf ("PlatformLinux::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
+ log->Printf("PlatformLinux::%s(force=%s, arch={%s,%s})", __FUNCTION__,
+ force ? "true" : "false", arch_name, triple_cstr);
+ }
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getOS())
- {
- case llvm::Triple::Linux:
- create = true;
- break;
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getOS()) {
+ case llvm::Triple::Linux:
+ create = true;
+ break;
#if defined(__linux__)
- // Only accept "unknown" for the OS if the host is linux and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::OSType::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
+ // Only accept "unknown" for the OS if the host is linux and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::OSType::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
#endif
- default:
- break;
- }
- }
-
- if (create)
- {
- if (log)
- log->Printf ("PlatformLinux::%s() creating remote-linux platform", __FUNCTION__);
- return PlatformSP(new PlatformLinux(false));
+ default:
+ break;
}
+ }
+ if (create) {
if (log)
- log->Printf ("PlatformLinux::%s() aborting creation of remote-linux platform", __FUNCTION__);
+ log->Printf("PlatformLinux::%s() creating remote-linux platform",
+ __FUNCTION__);
+ return PlatformSP(new PlatformLinux(false));
+ }
+
+ if (log)
+ log->Printf(
+ "PlatformLinux::%s() aborting creation of remote-linux platform",
+ __FUNCTION__);
- return PlatformSP();
+ return PlatformSP();
}
-ConstString
-PlatformLinux::GetPluginNameStatic (bool is_host)
-{
- if (is_host)
- {
- static ConstString g_host_name(Platform::GetHostPlatformName ());
- return g_host_name;
- }
- else
- {
- static ConstString g_remote_name("remote-linux");
- return g_remote_name;
- }
+ConstString PlatformLinux::GetPluginNameStatic(bool is_host) {
+ if (is_host) {
+ static ConstString g_host_name(Platform::GetHostPlatformName());
+ return g_host_name;
+ } else {
+ static ConstString g_remote_name("remote-linux");
+ return g_remote_name;
+ }
}
-const char *
-PlatformLinux::GetPluginDescriptionStatic (bool is_host)
-{
- if (is_host)
- return "Local Linux user platform plug-in.";
- else
- return "Remote Linux user platform plug-in.";
+const char *PlatformLinux::GetPluginDescriptionStatic(bool is_host) {
+ if (is_host)
+ return "Local Linux user platform plug-in.";
+ else
+ return "Remote Linux user platform plug-in.";
}
-ConstString
-PlatformLinux::GetPluginName()
-{
- return GetPluginNameStatic(IsHost());
+ConstString PlatformLinux::GetPluginName() {
+ return GetPluginNameStatic(IsHost());
}
-void
-PlatformLinux::Initialize ()
-{
- PlatformPOSIX::Initialize ();
+void PlatformLinux::Initialize() {
+ PlatformPOSIX::Initialize();
- if (g_initialize_count++ == 0)
- {
+ if (g_initialize_count++ == 0) {
#if defined(__linux__) && !defined(__ANDROID__)
- PlatformSP default_platform_sp (new PlatformLinux(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform (default_platform_sp);
+ PlatformSP default_platform_sp(new PlatformLinux(true));
+ default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+ Platform::SetHostPlatform(default_platform_sp);
#endif
- PluginManager::RegisterPlugin(PlatformLinux::GetPluginNameStatic(false),
- PlatformLinux::GetPluginDescriptionStatic(false),
- PlatformLinux::CreateInstance,
- PlatformLinux::DebuggerInitialize);
- }
+ PluginManager::RegisterPlugin(
+ PlatformLinux::GetPluginNameStatic(false),
+ PlatformLinux::GetPluginDescriptionStatic(false),
+ PlatformLinux::CreateInstance, PlatformLinux::DebuggerInitialize);
+ }
}
-void
-PlatformLinux::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformLinux::CreateInstance);
- }
+void PlatformLinux::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformLinux::CreateInstance);
}
+ }
- PlatformPOSIX::Terminate ();
+ PlatformPOSIX::Terminate();
}
-Error
-PlatformLinux::ResolveExecutable (const ModuleSpec &ms,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec (ms);
-
- 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())
- {
- resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
- }
+Error PlatformLinux::ResolveExecutable(
+ const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ char exe_path[PATH_MAX];
+ ModuleSpec resolved_module_spec(ms);
+
+ 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()) {
+ resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+ resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
+ }
- if (!resolved_module_spec.GetFileSpec().Exists())
- resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();
+ if (!resolved_module_spec.GetFileSpec().Exists())
+ resolved_module_spec.GetFileSpec().ResolveExecutableLocation();
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- {
- error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else {
+ error.SetErrorStringWithFormat(
+ "unable to find executable for '%s'",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
- else
- {
- if (m_remote_platform_sp)
- {
- error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
+ } else {
+ if (m_remote_platform_sp) {
+ error =
+ GetCachedExecutable(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, *m_remote_platform_sp);
+ } else {
+ // We may connect to a process and use the provided executable (Don't use
+ // local $PATH).
+
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else
+ error.SetErrorStringWithFormat("the platform is not currently "
+ "connected, and '%s' doesn't exist in "
+ "the system root.",
+ exe_path);
+ }
+ }
+
+ if (error.Success()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ if (error.Fail()) {
+ // If we failed, it may be because the vendor and os aren't known. If
+ // that is the
+ // case, try setting them to the host architecture and give it another
+ // try.
+ llvm::Triple &module_triple =
+ resolved_module_spec.GetArchitecture().GetTriple();
+ bool is_vendor_specified =
+ (module_triple.getVendor() != llvm::Triple::UnknownVendor);
+ bool is_os_specified =
+ (module_triple.getOS() != llvm::Triple::UnknownOS);
+ if (!is_vendor_specified || !is_os_specified) {
+ const llvm::Triple &host_triple =
+ HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
+
+ if (!is_vendor_specified)
+ module_triple.setVendorName(host_triple.getVendorName());
+ if (!is_os_specified)
+ module_triple.setOSName(host_triple.getOSName());
+
+ error = ModuleList::GetSharedModule(resolved_module_spec,
+ exe_module_sp, NULL, NULL, NULL);
}
- else
- {
- // We may connect to a process and use the provided executable (Don't use local $PATH).
-
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
+ }
+
+ // TODO find out why exe_module_sp might be NULL
+ if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) {
+ exe_module_sp.reset();
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain the architecture %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+ } else {
+ // No valid architecture was specified, ask the platform for
+ // the architectures that we should be using (in the correct order)
+ // and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
- }
- if (error.Success())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- if (error.Fail())
- {
- // If we failed, it may be because the vendor and os aren't known. If that is the
- // case, try setting them to the host architecture and give it another try.
- llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple();
- bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
- bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
- if (!is_vendor_specified || !is_os_specified)
- {
- const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
-
- if (!is_vendor_specified)
- module_triple.setVendorName (host_triple.getVendorName());
- if (!is_os_specified)
- module_triple.setOSName (host_triple.getOSName());
-
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- }
- }
-
- // TODO find out why exe_module_sp might be NULL
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
- {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
- }
- else
- {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
+ }
}
+ }
- return error;
+ return error;
}
-Error
-PlatformLinux::GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr, FileSpec &local_file)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
- }
-
- // Default to the local case
- local_file = platform_file;
- return Error();
+Error PlatformLinux::GetFileWithUUID(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ if (IsRemote()) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
+ local_file);
+ }
+
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformLinux::PlatformLinux (bool is_host) :
- PlatformPOSIX(is_host) // This is the local host platform
-{
-}
+PlatformLinux::PlatformLinux(bool is_host)
+ : PlatformPOSIX(is_host) // This is the local host platform
+{}
//------------------------------------------------------------------
/// Destructor.
@@ -406,372 +359,359 @@ PlatformLinux::PlatformLinux (bool is_host) :
//------------------------------------------------------------------
PlatformLinux::~PlatformLinux() = default;
-bool
-PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- bool success = false;
- if (IsHost())
- {
- success = Platform::GetProcessInfo (pid, process_info);
- }
- else
- {
- if (m_remote_platform_sp)
- success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
- }
- return success;
+bool PlatformLinux::GetProcessInfo(lldb::pid_t pid,
+ ProcessInstanceInfo &process_info) {
+ bool success = false;
+ if (IsHost()) {
+ success = Platform::GetProcessInfo(pid, process_info);
+ } else {
+ if (m_remote_platform_sp)
+ success = m_remote_platform_sp->GetProcessInfo(pid, process_info);
+ }
+ return success;
}
uint32_t
-PlatformLinux::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- uint32_t match_count = 0;
- if (IsHost())
- {
- // Let the base class figure out the host details
- match_count = Platform::FindProcesses (match_info, process_infos);
- }
- else
- {
- // If we are remote, we can only return results if we are connected
- if (m_remote_platform_sp)
- match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
- }
- return match_count;
+PlatformLinux::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ uint32_t match_count = 0;
+ if (IsHost()) {
+ // Let the base class figure out the host details
+ match_count = Platform::FindProcesses(match_info, process_infos);
+ } else {
+ // If we are remote, we can only return results if we are connected
+ if (m_remote_platform_sp)
+ match_count =
+ m_remote_platform_sp->FindProcesses(match_info, process_infos);
+ }
+ return match_count;
}
-bool
-PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- if (IsHost())
- {
- ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- if (hostArch.GetTriple().isOSLinux())
- {
- if (idx == 0)
- {
- arch = hostArch;
- return arch.IsValid();
- }
- else if (idx == 1)
- {
- // If the default host architecture is 64-bit, look for a 32-bit variant
- if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
- {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return arch.IsValid();
- }
- }
+bool PlatformLinux::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ if (IsHost()) {
+ ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ if (hostArch.GetTriple().isOSLinux()) {
+ if (idx == 0) {
+ arch = hostArch;
+ return arch.IsValid();
+ } else if (idx == 1) {
+ // If the default host architecture is 64-bit, look for a 32-bit variant
+ if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) {
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ return arch.IsValid();
}
+ }
}
- else
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
-
- llvm::Triple triple;
- // Set the OS to linux
- triple.setOS(llvm::Triple::Linux);
- // Set the architecture
- switch (idx)
- {
- case 0: triple.setArchName("x86_64"); break;
- case 1: triple.setArchName("i386"); break;
- case 2: triple.setArchName("arm"); break;
- case 3: triple.setArchName("aarch64"); break;
- case 4: triple.setArchName("mips64"); break;
- case 5: triple.setArchName("hexagon"); break;
- case 6: triple.setArchName("mips"); break;
- case 7: triple.setArchName("mips64el"); break;
- case 8: triple.setArchName("mipsel"); break;
- case 9: triple.setArchName("s390x"); break;
- default: return false;
- }
- // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified unknown".
- // This means when someone calls triple.GetVendorName() it will return an empty string
- // which indicates that the vendor can be set when two architectures are merged
-
- // Now set the triple into "arch" and return true
- arch.SetTriple(triple);
- return true;
+ } else {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
+
+ llvm::Triple triple;
+ // Set the OS to linux
+ triple.setOS(llvm::Triple::Linux);
+ // Set the architecture
+ switch (idx) {
+ case 0:
+ triple.setArchName("x86_64");
+ break;
+ case 1:
+ triple.setArchName("i386");
+ break;
+ case 2:
+ triple.setArchName("arm");
+ break;
+ case 3:
+ triple.setArchName("aarch64");
+ break;
+ case 4:
+ triple.setArchName("mips64");
+ break;
+ case 5:
+ triple.setArchName("hexagon");
+ break;
+ case 6:
+ triple.setArchName("mips");
+ break;
+ case 7:
+ triple.setArchName("mips64el");
+ break;
+ case 8:
+ triple.setArchName("mipsel");
+ break;
+ case 9:
+ triple.setArchName("s390x");
+ break;
+ default:
+ return false;
}
- return false;
+ // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
+ // vendor by
+ // calling triple.SetVendorName("unknown") so that it is a "unspecified
+ // unknown".
+ // This means when someone calls triple.GetVendorName() it will return an
+ // empty string
+ // which indicates that the vendor can be set when two architectures are
+ // merged
+
+ // Now set the triple into "arch" and return true
+ arch.SetTriple(triple);
+ return true;
+ }
+ return false;
}
-void
-PlatformLinux::GetStatus (Stream &strm)
-{
- Platform::GetStatus(strm);
+void PlatformLinux::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
#ifndef LLDB_DISABLE_POSIX
- // Display local kernel information only when we are running in host mode.
- // Otherwise, we would end up printing non-Linux information (when running
- // on Mac OS for example).
- if (IsHost())
- {
- struct utsname un;
-
- if (uname(&un))
- return;
-
- strm.Printf (" Kernel: %s\n", un.sysname);
- strm.Printf (" Release: %s\n", un.release);
- strm.Printf (" Version: %s\n", un.version);
- }
+ // Display local kernel information only when we are running in host mode.
+ // Otherwise, we would end up printing non-Linux information (when running
+ // on Mac OS for example).
+ if (IsHost()) {
+ struct utsname un;
+
+ if (uname(&un))
+ return;
+
+ strm.Printf(" Kernel: %s\n", un.sysname);
+ strm.Printf(" Release: %s\n", un.release);
+ strm.Printf(" Version: %s\n", un.version);
+ }
#endif
}
int32_t
-PlatformLinux::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
-{
- int32_t resume_count = 0;
-
- // Always resume past the initial stop when we use eLaunchFlagDebug
- if (launch_info.GetFlags ().Test (eLaunchFlagDebug))
- {
- // Resume past the stop for the final exec into the true inferior.
- ++resume_count;
- }
-
- // If we're not launching a shell, we're done.
- const FileSpec &shell = launch_info.GetShell();
- if (!shell)
- return resume_count;
+PlatformLinux::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
+ int32_t resume_count = 0;
- std::string shell_string = shell.GetPath();
- // We're in a shell, so for sure we have to resume past the shell exec.
+ // Always resume past the initial stop when we use eLaunchFlagDebug
+ if (launch_info.GetFlags().Test(eLaunchFlagDebug)) {
+ // Resume past the stop for the final exec into the true inferior.
++resume_count;
+ }
- // Figure out what shell we're planning on using.
- const char *shell_name = strrchr (shell_string.c_str(), '/');
- if (shell_name == NULL)
- shell_name = shell_string.c_str();
- else
- shell_name++;
-
- if (strcmp (shell_name, "csh") == 0
- || strcmp (shell_name, "tcsh") == 0
- || strcmp (shell_name, "zsh") == 0
- || strcmp (shell_name, "sh") == 0)
- {
- // These shells seem to re-exec themselves. Add another resume.
- ++resume_count;
- }
-
+ // If we're not launching a shell, we're done.
+ const FileSpec &shell = launch_info.GetShell();
+ if (!shell)
return resume_count;
+
+ std::string shell_string = shell.GetPath();
+ // We're in a shell, so for sure we have to resume past the shell exec.
+ ++resume_count;
+
+ // Figure out what shell we're planning on using.
+ const char *shell_name = strrchr(shell_string.c_str(), '/');
+ if (shell_name == NULL)
+ shell_name = shell_string.c_str();
+ else
+ shell_name++;
+
+ if (strcmp(shell_name, "csh") == 0 || strcmp(shell_name, "tcsh") == 0 ||
+ strcmp(shell_name, "zsh") == 0 || strcmp(shell_name, "sh") == 0) {
+ // These shells seem to re-exec themselves. Add another resume.
+ ++resume_count;
+ }
+
+ return resume_count;
}
-bool
-PlatformLinux::CanDebugProcess ()
-{
- if (IsHost ())
- {
- return true;
- }
- else
- {
- // If we're connected, we can debug.
- return IsConnected ();
- }
+bool PlatformLinux::CanDebugProcess() {
+ if (IsHost()) {
+ return true;
+ } else {
+ // If we're connected, we can debug.
+ return IsConnected();
+ }
}
-// For local debugging, Linux will override the debug logic to use llgs-launch rather than
-// lldb-launch, llgs-attach. This differs from current lldb-launch, debugserver-attach
+// For local debugging, Linux will override the debug logic to use llgs-launch
+// rather than
+// lldb-launch, llgs-attach. This differs from current lldb-launch,
+// debugserver-attach
// approach on MacOSX.
lldb::ProcessSP
-PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
- Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
- Error &error)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new
+ // target, else use existing one
+ Error &error) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("PlatformLinux::%s entered (target %p)", __FUNCTION__,
+ static_cast<void *>(target));
+
+ // If we're a remote host, use standard behavior from parent class.
+ if (!IsHost())
+ return PlatformPOSIX::DebugProcess(launch_info, debugger, target, error);
+
+ //
+ // For local debugging, we'll insist on having ProcessGDBRemote create the
+ // process.
+ //
+
+ ProcessSP process_sp;
+
+ // Make sure we stop at the entry point
+ launch_info.GetFlags().Set(eLaunchFlagDebug);
+
+ // We always launch the process we are going to debug in a separate process
+ // group, since then we can handle ^C interrupts ourselves w/o having to worry
+ // about the target getting them as well.
+ launch_info.SetLaunchInSeparateProcessGroup(true);
+
+ // Ensure we have a target.
+ if (target == nullptr) {
if (log)
- log->Printf ("PlatformLinux::%s entered (target %p)", __FUNCTION__, static_cast<void*>(target));
-
- // If we're a remote host, use standard behavior from parent class.
- if (!IsHost ())
- return PlatformPOSIX::DebugProcess (launch_info, debugger, target, error);
-
- //
- // For local debugging, we'll insist on having ProcessGDBRemote create the process.
- //
+ log->Printf("PlatformLinux::%s creating new target", __FUNCTION__);
+
+ TargetSP new_target_sp;
+ error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
+ nullptr, new_target_sp);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("PlatformLinux::%s failed to create new target: %s",
+ __FUNCTION__, error.AsCString());
+ return process_sp;
+ }
- ProcessSP process_sp;
+ target = new_target_sp.get();
+ if (!target) {
+ error.SetErrorString("CreateTarget() returned nullptr");
+ if (log)
+ log->Printf("PlatformLinux::%s failed: %s", __FUNCTION__,
+ error.AsCString());
+ return process_sp;
+ }
+ } else {
+ if (log)
+ log->Printf("PlatformLinux::%s using provided target", __FUNCTION__);
+ }
+
+ // Mark target as currently selected target.
+ debugger.GetTargetList().SetSelectedTarget(target);
+
+ // Now create the gdb-remote process.
+ if (log)
+ log->Printf(
+ "PlatformLinux::%s having target create process with gdb-remote plugin",
+ __FUNCTION__);
+ process_sp = target->CreateProcess(
+ launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);
+
+ if (!process_sp) {
+ error.SetErrorString("CreateProcess() failed for gdb-remote process");
+ if (log)
+ log->Printf("PlatformLinux::%s failed: %s", __FUNCTION__,
+ error.AsCString());
+ return process_sp;
+ } else {
+ if (log)
+ log->Printf("PlatformLinux::%s successfully created process",
+ __FUNCTION__);
+ }
- // Make sure we stop at the entry point
- launch_info.GetFlags ().Set (eLaunchFlagDebug);
+ // Adjust launch for a hijacker.
+ ListenerSP listener_sp;
+ if (!launch_info.GetHijackListener()) {
+ if (log)
+ log->Printf("PlatformLinux::%s setting up hijacker", __FUNCTION__);
- // We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to worry
- // about the target getting them as well.
- launch_info.SetLaunchInSeparateProcessGroup(true);
+ listener_sp =
+ Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
+ launch_info.SetHijackListener(listener_sp);
+ process_sp->HijackProcessEvents(listener_sp);
+ }
- // Ensure we have a target.
- if (target == nullptr)
- {
- if (log)
- log->Printf ("PlatformLinux::%s creating new target", __FUNCTION__);
-
- TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget (debugger,
- nullptr,
- nullptr,
- false,
- nullptr,
- new_target_sp);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("PlatformLinux::%s failed to create new target: %s", __FUNCTION__, error.AsCString ());
- return process_sp;
- }
+ // Log file actions.
+ if (log) {
+ log->Printf(
+ "PlatformLinux::%s launching process with the following file actions:",
+ __FUNCTION__);
- target = new_target_sp.get();
- if (!target)
- {
- error.SetErrorString ("CreateTarget() returned nullptr");
- if (log)
- log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
- return process_sp;
- }
- }
- else
- {
- if (log)
- log->Printf ("PlatformLinux::%s using provided target", __FUNCTION__);
+ StreamString stream;
+ size_t i = 0;
+ const FileAction *file_action;
+ while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
+ file_action->Dump(stream);
+ log->PutCString(stream.GetData());
+ stream.Clear();
}
+ }
- // Mark target as currently selected target.
- debugger.GetTargetList().SetSelectedTarget(target);
+ // Do the launch.
+ error = process_sp->Launch(launch_info);
+ if (error.Success()) {
+ // Handle the hijacking of process events.
+ if (listener_sp) {
+ const StateType state = process_sp->WaitForProcessToStop(
+ llvm::None, NULL, false, listener_sp);
- // Now create the gdb-remote process.
- if (log)
- log->Printf ("PlatformLinux::%s having target create process with gdb-remote plugin", __FUNCTION__);
- process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);
-
- if (!process_sp)
- {
- error.SetErrorString ("CreateProcess() failed for gdb-remote process");
+ if (state == eStateStopped) {
if (log)
- log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
- return process_sp;
- }
- else
- {
+ log->Printf("PlatformLinux::%s pid %" PRIu64 " state %s\n",
+ __FUNCTION__, process_sp->GetID(), StateAsCString(state));
+ } else {
if (log)
- log->Printf ("PlatformLinux::%s successfully created process", __FUNCTION__);
+ log->Printf("PlatformLinux::%s pid %" PRIu64
+ " state is not stopped - %s\n",
+ __FUNCTION__, process_sp->GetID(), StateAsCString(state));
+ }
}
- // Adjust launch for a hijacker.
- ListenerSP listener_sp;
- if (!launch_info.GetHijackListener ())
- {
- if (log)
- log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__);
-
- listener_sp = Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
- launch_info.SetHijackListener (listener_sp);
- process_sp->HijackProcessEvents (listener_sp);
+ // Hook up process PTY if we have one (which we should for local debugging
+ // with llgs).
+ int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+ if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) {
+ process_sp->SetSTDIOFileDescriptor(pty_fd);
+ if (log)
+ log->Printf("PlatformLinux::%s pid %" PRIu64
+ " hooked up STDIO pty to process",
+ __FUNCTION__, process_sp->GetID());
+ } else {
+ if (log)
+ log->Printf("PlatformLinux::%s pid %" PRIu64
+ " not using process STDIO pty",
+ __FUNCTION__, process_sp->GetID());
}
-
- // Log file actions.
+ } else {
if (log)
- {
- log->Printf ("PlatformLinux::%s launching process with the following file actions:", __FUNCTION__);
-
- StreamString stream;
- size_t i = 0;
- const FileAction *file_action;
- while ((file_action = launch_info.GetFileActionAtIndex (i++)) != nullptr)
- {
- file_action->Dump (stream);
- log->PutCString (stream.GetString().c_str ());
- stream.Clear();
- }
- }
-
- // Do the launch.
- error = process_sp->Launch(launch_info);
- if (error.Success ())
- {
- // Handle the hijacking of process events.
- if (listener_sp)
- {
- const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp);
-
- if (state == eStateStopped)
- {
- if (log)
- log->Printf ("PlatformLinux::%s pid %" PRIu64 " state %s\n",
- __FUNCTION__, process_sp->GetID (), StateAsCString (state));
- }
- else
- {
- if (log)
- log->Printf ("PlatformLinux::%s pid %" PRIu64 " state is not stopped - %s\n",
- __FUNCTION__, process_sp->GetID (), StateAsCString (state));
- }
- }
+ log->Printf("PlatformLinux::%s process launch failed: %s", __FUNCTION__,
+ error.AsCString());
+ // FIXME figure out appropriate cleanup here. Do we delete the target? Do
+ // we delete the process? Does our caller do that?
+ }
- // Hook up process PTY if we have one (which we should for local debugging with llgs).
- int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
- {
- process_sp->SetSTDIOFileDescriptor(pty_fd);
- if (log)
- log->Printf ("PlatformLinux::%s pid %" PRIu64 " hooked up STDIO pty to process", __FUNCTION__, process_sp->GetID ());
- }
- else
- {
- if (log)
- log->Printf ("PlatformLinux::%s pid %" PRIu64 " not using process STDIO pty", __FUNCTION__, process_sp->GetID ());
- }
- }
- else
- {
- if (log)
- log->Printf ("PlatformLinux::%s process launch failed: %s", __FUNCTION__, error.AsCString ());
- // FIXME figure out appropriate cleanup here. Do we delete the target? Do we delete the process? Does our caller do that?
- }
-
- return process_sp;
+ return process_sp;
}
-void
-PlatformLinux::CalculateTrapHandlerSymbolNames ()
-{
- m_trap_handlers.push_back (ConstString ("_sigtramp"));
+void PlatformLinux::CalculateTrapHandlerSymbolNames() {
+ m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-uint64_t
-PlatformLinux::ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags)
-{
- uint64_t flags_platform = 0;
- uint64_t map_anon = MAP_ANON;
-
- // To get correct flags for MIPS Architecture
- if (arch.GetTriple ().getArch () == llvm::Triple::mips64
- || arch.GetTriple ().getArch () == llvm::Triple::mips64el
- || arch.GetTriple ().getArch () == llvm::Triple::mips
- || arch.GetTriple ().getArch () == llvm::Triple::mipsel)
- map_anon = 0x800;
-
- if (flags & eMmapFlagsPrivate)
- flags_platform |= MAP_PRIVATE;
- if (flags & eMmapFlagsAnon)
- flags_platform |= map_anon;
- return flags_platform;
+uint64_t PlatformLinux::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
+ unsigned flags) {
+ uint64_t flags_platform = 0;
+ uint64_t map_anon = MAP_ANON;
+
+ // To get correct flags for MIPS Architecture
+ if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
+ arch.GetTriple().getArch() == llvm::Triple::mips64el ||
+ arch.GetTriple().getArch() == llvm::Triple::mips ||
+ arch.GetTriple().getArch() == llvm::Triple::mipsel)
+ map_anon = 0x800;
+
+ if (flags & eMmapFlagsPrivate)
+ flags_platform |= MAP_PRIVATE;
+ if (flags & eMmapFlagsAnon)
+ flags_platform |= map_anon;
+ return flags_platform;
}
-ConstString
-PlatformLinux::GetFullNameForDylib (ConstString basename)
-{
- if (basename.IsEmpty())
- return basename;
-
- StreamString stream;
- stream.Printf("lib%s.so", basename.GetCString());
- return ConstString(stream.GetData());
+ConstString PlatformLinux::GetFullNameForDylib(ConstString basename) {
+ if (basename.IsEmpty())
+ return basename;
+
+ StreamString stream;
+ stream.Printf("lib%s.so", basename.GetCString());
+ return ConstString(stream.GetString());
}
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.h b/source/Plugins/Platform/Linux/PlatformLinux.h
index d99256cff0ea..f98c3e988cd1 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.h
+++ b/source/Plugins/Platform/Linux/PlatformLinux.h
@@ -19,98 +19,72 @@
namespace lldb_private {
namespace platform_linux {
- class PlatformLinux : public PlatformPOSIX
- {
- public:
- PlatformLinux(bool is_host);
-
- ~PlatformLinux() override;
-
- static void
- DebuggerInitialize (Debugger &debugger);
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance (bool force, const ArchSpec *arch);
-
- static ConstString
- GetPluginNameStatic (bool is_host);
-
- static const char *
- GetPluginDescriptionStatic (bool is_host);
-
- ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- Error
- ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetPluginDescriptionStatic(IsHost());
- }
-
- void
- GetStatus (Stream &strm) override;
-
- Error
- GetFileWithUUID (const FileSpec &platform_file,
- const UUID* uuid, FileSpec &local_file) override;
-
- bool
- GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
-
- uint32_t
- FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) override;
-
- int32_t
- GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info) override;
-
- bool
- CanDebugProcess () override;
-
- lldb::ProcessSP
- DebugProcess (ProcessLaunchInfo &launch_info,
- Debugger &debugger,
- Target *target,
- Error &error) override;
-
- void
- CalculateTrapHandlerSymbolNames () override;
-
- uint64_t
- ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags) override;
-
- ConstString
- GetFullNameForDylib (ConstString basename) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN (PlatformLinux);
- };
+class PlatformLinux : public PlatformPOSIX {
+public:
+ PlatformLinux(bool is_host);
+
+ ~PlatformLinux() override;
+
+ static void DebuggerInitialize(Debugger &debugger);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+
+ static ConstString GetPluginNameStatic(bool is_host);
+
+ static const char *GetPluginDescriptionStatic(bool is_host);
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ Error ResolveExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr) override;
+
+ const char *GetDescription() override {
+ return GetPluginDescriptionStatic(IsHost());
+ }
+
+ void GetStatus(Stream &strm) override;
+
+ Error GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid,
+ FileSpec &local_file) override;
+
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
+
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
+
+ int32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override;
+
+ bool CanDebugProcess() override;
+
+ lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger, Target *target,
+ Error &error) override;
+
+ void CalculateTrapHandlerSymbolNames() override;
+
+ uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch,
+ unsigned flags) override;
+
+ ConstString GetFullNameForDylib(ConstString basename) override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformLinux);
+};
} // namespace platform_linux
} // namespace lldb_private
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index a5f165e1f925..e6da63e8af6a 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -35,26 +35,16 @@ using namespace lldb_private;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformAppleSimulator::Initialize ()
-{
- PlatformDarwin::Initialize ();
-}
+void PlatformAppleSimulator::Initialize() { PlatformDarwin::Initialize(); }
-void
-PlatformAppleSimulator::Terminate ()
-{
- PlatformDarwin::Terminate ();
-}
+void PlatformAppleSimulator::Terminate() { PlatformDarwin::Terminate(); }
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformAppleSimulator::PlatformAppleSimulator () :
- PlatformDarwin (true),
- m_core_simulator_framework_path()
-{
-}
+PlatformAppleSimulator::PlatformAppleSimulator()
+ : PlatformDarwin(true), m_core_sim_path_mutex(),
+ m_core_simulator_framework_path(), m_device() {}
//------------------------------------------------------------------
/// Destructor.
@@ -62,242 +52,218 @@ PlatformAppleSimulator::PlatformAppleSimulator () :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformAppleSimulator::~PlatformAppleSimulator()
-{
-}
+PlatformAppleSimulator::~PlatformAppleSimulator() {}
-lldb_private::Error
-PlatformAppleSimulator::LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info)
-{
+lldb_private::Error PlatformAppleSimulator::LaunchProcess(
+ lldb_private::ProcessLaunchInfo &launch_info) {
#if defined(__APPLE__)
- LoadCoreSimulator();
- CoreSimulatorSupport::Device device(GetSimulatorDevice());
-
- if (device.GetState() != CoreSimulatorSupport::Device::State::Booted)
- {
- Error boot_err;
- device.Boot(boot_err);
- if (boot_err.Fail())
- return boot_err;
- }
-
- auto spawned = device.Spawn(launch_info);
-
- if (spawned)
- {
- launch_info.SetProcessID(spawned.GetPID());
- return Error();
- }
- else
- return spawned.GetError();
+ LoadCoreSimulator();
+ CoreSimulatorSupport::Device device(GetSimulatorDevice());
+
+ if (device.GetState() != CoreSimulatorSupport::Device::State::Booted) {
+ Error boot_err;
+ device.Boot(boot_err);
+ if (boot_err.Fail())
+ return boot_err;
+ }
+
+ auto spawned = device.Spawn(launch_info);
+
+ if (spawned) {
+ launch_info.SetProcessID(spawned.GetPID());
+ return Error();
+ } else
+ return spawned.GetError();
#else
- Error err;
- err.SetErrorString(UNSUPPORTED_ERROR);
- return err;
+ Error err;
+ err.SetErrorString(UNSUPPORTED_ERROR);
+ return err;
#endif
}
-void
-PlatformAppleSimulator::GetStatus (Stream &strm)
-{
+void PlatformAppleSimulator::GetStatus(Stream &strm) {
#if defined(__APPLE__)
- // This will get called by subclasses, so just output status on the
- // current simulator
- PlatformAppleSimulator::LoadCoreSimulator();
-
- CoreSimulatorSupport::DeviceSet devices = CoreSimulatorSupport::DeviceSet::GetAvailableDevices();
- const size_t num_devices = devices.GetNumDevices();
- if (num_devices)
- {
- strm.Printf("Available devices:\n");
- for (size_t i=0; i<num_devices; ++i)
- {
- CoreSimulatorSupport::Device device = devices.GetDeviceAtIndex(i);
- strm.Printf(" %s: %s\n", device.GetUDID().c_str(), device.GetName().c_str());
- }
+ // This will get called by subclasses, so just output status on the
+ // current simulator
+ PlatformAppleSimulator::LoadCoreSimulator();
- if (m_device.hasValue() && m_device->operator bool())
- {
- strm.Printf("Current device: %s: %s", m_device->GetUDID().c_str(), m_device->GetName().c_str());
- if (m_device->GetState() == CoreSimulatorSupport::Device::State::Booted)
- {
- strm.Printf(" state = booted");
- }
- strm.Printf("\nType \"platform connect <ARG>\" where <ARG> is a device UDID or a device name to disconnect and connect to a different device.\n");
+ CoreSimulatorSupport::DeviceSet devices =
+ CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
+ GetDeveloperDirectory());
+ const size_t num_devices = devices.GetNumDevices();
+ if (num_devices) {
+ strm.Printf("Available devices:\n");
+ for (size_t i = 0; i < num_devices; ++i) {
+ CoreSimulatorSupport::Device device = devices.GetDeviceAtIndex(i);
+ strm.Printf(" %s: %s\n", device.GetUDID().c_str(),
+ device.GetName().c_str());
+ }
- }
- else
- {
- strm.Printf("No current device is selected, \"platform connect <ARG>\" where <ARG> is a device UDID or a device name to connect to a specific device.\n");
- }
+ if (m_device.hasValue() && m_device->operator bool()) {
+ strm.Printf("Current device: %s: %s", m_device->GetUDID().c_str(),
+ m_device->GetName().c_str());
+ if (m_device->GetState() == CoreSimulatorSupport::Device::State::Booted) {
+ strm.Printf(" state = booted");
+ }
+ strm.Printf("\nType \"platform connect <ARG>\" where <ARG> is a device "
+ "UDID or a device name to disconnect and connect to a "
+ "different device.\n");
+ } else {
+ strm.Printf("No current device is selected, \"platform connect <ARG>\" "
+ "where <ARG> is a device UDID or a device name to connect to "
+ "a specific device.\n");
}
- else
- {
- strm.Printf("No devices are available.\n");
- }
+
+ } else {
+ strm.Printf("No devices are available.\n");
+ }
#else
- strm.Printf(UNSUPPORTED_ERROR);
+ strm.Printf(UNSUPPORTED_ERROR);
#endif
}
-Error
-PlatformAppleSimulator::ConnectRemote (Args& args)
-{
+Error PlatformAppleSimulator::ConnectRemote(Args &args) {
#if defined(__APPLE__)
- Error error;
- if (args.GetArgumentCount() == 1)
- {
- if (m_device)
- DisconnectRemote ();
- PlatformAppleSimulator::LoadCoreSimulator();
- const char *arg_cstr = args.GetArgumentAtIndex(0);
- if (arg_cstr)
- {
- std::string arg_str(arg_cstr);
- CoreSimulatorSupport::DeviceSet devices = CoreSimulatorSupport::DeviceSet::GetAvailableDevices();
- devices.ForEach([this, &arg_str](const CoreSimulatorSupport::Device &device) -> bool {
- if (arg_str == device.GetUDID() || arg_str == device.GetName())
- {
- m_device = device;
- return false; // Stop iterating
- }
- else
- {
- return true; // Keep iterating
- }
- });
- if (!m_device)
- error.SetErrorStringWithFormat("no device with UDID or name '%s' was found", arg_cstr);
- }
- }
- else
- {
- error.SetErrorString("this command take a single UDID argument of the device you want to connect to.");
+ Error error;
+ if (args.GetArgumentCount() == 1) {
+ if (m_device)
+ DisconnectRemote();
+ PlatformAppleSimulator::LoadCoreSimulator();
+ const char *arg_cstr = args.GetArgumentAtIndex(0);
+ if (arg_cstr) {
+ std::string arg_str(arg_cstr);
+ CoreSimulatorSupport::DeviceSet devices =
+ CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
+ GetDeveloperDirectory());
+ devices.ForEach(
+ [this, &arg_str](const CoreSimulatorSupport::Device &device) -> bool {
+ if (arg_str == device.GetUDID() || arg_str == device.GetName()) {
+ m_device = device;
+ return false; // Stop iterating
+ } else {
+ return true; // Keep iterating
+ }
+ });
+ if (!m_device)
+ error.SetErrorStringWithFormat(
+ "no device with UDID or name '%s' was found", arg_cstr);
}
- return error;
+ } else {
+ error.SetErrorString("this command take a single UDID argument of the "
+ "device you want to connect to.");
+ }
+ return error;
#else
- Error err;
- err.SetErrorString(UNSUPPORTED_ERROR);
- return err;
+ Error err;
+ err.SetErrorString(UNSUPPORTED_ERROR);
+ return err;
#endif
}
-Error
-PlatformAppleSimulator::DisconnectRemote ()
-{
+Error PlatformAppleSimulator::DisconnectRemote() {
#if defined(__APPLE__)
- m_device.reset();
- return Error();
+ m_device.reset();
+ return Error();
#else
- Error err;
- err.SetErrorString(UNSUPPORTED_ERROR);
- return err;
+ Error err;
+ err.SetErrorString(UNSUPPORTED_ERROR);
+ return err;
#endif
}
-
-lldb::ProcessSP
-PlatformAppleSimulator::DebugProcess (ProcessLaunchInfo &launch_info,
- Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
- Error &error)
-{
+lldb::ProcessSP PlatformAppleSimulator::DebugProcess(
+ ProcessLaunchInfo &launch_info, Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new target, else use
+ // existing one
+ Error &error) {
#if defined(__APPLE__)
- ProcessSP process_sp;
- // Make sure we stop at the entry point
- launch_info.GetFlags ().Set (eLaunchFlagDebug);
- // We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to worry
- // about the target getting them as well.
- launch_info.SetLaunchInSeparateProcessGroup(true);
+ ProcessSP process_sp;
+ // Make sure we stop at the entry point
+ launch_info.GetFlags().Set(eLaunchFlagDebug);
+ // We always launch the process we are going to debug in a separate process
+ // group, since then we can handle ^C interrupts ourselves w/o having to worry
+ // about the target getting them as well.
+ launch_info.SetLaunchInSeparateProcessGroup(true);
- error = LaunchProcess (launch_info);
- if (error.Success())
- {
- if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- {
- ProcessAttachInfo attach_info (launch_info);
- process_sp = Attach (attach_info, debugger, target, error);
- if (process_sp)
- {
- launch_info.SetHijackListener(attach_info.GetHijackListener());
+ error = LaunchProcess(launch_info);
+ if (error.Success()) {
+ if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
+ ProcessAttachInfo attach_info(launch_info);
+ process_sp = Attach(attach_info, debugger, target, error);
+ if (process_sp) {
+ launch_info.SetHijackListener(attach_info.GetHijackListener());
- // Since we attached to the process, it will think it needs to detach
- // if the process object just goes away without an explicit call to
- // Process::Kill() or Process::Detach(), so let it know to kill the
- // process if this happens.
- process_sp->SetShouldDetach (false);
-
- // If we didn't have any file actions, the pseudo terminal might
- // have been used where the slave side was given as the file to
- // open for stdin/out/err after we have already opened the master
- // so we can read/write stdin/out/err.
- int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
- {
- process_sp->SetSTDIOFileDescriptor(pty_fd);
- }
- }
+ // Since we attached to the process, it will think it needs to detach
+ // if the process object just goes away without an explicit call to
+ // Process::Kill() or Process::Detach(), so let it know to kill the
+ // process if this happens.
+ process_sp->SetShouldDetach(false);
+
+ // If we didn't have any file actions, the pseudo terminal might
+ // have been used where the slave side was given as the file to
+ // open for stdin/out/err after we have already opened the master
+ // so we can read/write stdin/out/err.
+ int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+ if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) {
+ process_sp->SetSTDIOFileDescriptor(pty_fd);
}
+ }
}
+ }
- return process_sp;
+ return process_sp;
#else
- return ProcessSP();
+ return ProcessSP();
#endif
}
-FileSpec
-PlatformAppleSimulator::GetCoreSimulatorPath()
-{
+FileSpec PlatformAppleSimulator::GetCoreSimulatorPath() {
#if defined(__APPLE__)
- std::lock_guard<std::mutex> guard(m_mutex);
- if (!m_core_simulator_framework_path.hasValue())
- {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir)
- {
- StreamString cs_path;
- 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);
- }
+ std::lock_guard<std::mutex> guard(m_core_sim_path_mutex);
+ if (!m_core_simulator_framework_path.hasValue()) {
+ const char *developer_dir = GetDeveloperDirectory();
+ if (developer_dir) {
+ StreamString cs_path;
+ 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);
}
-
- return m_core_simulator_framework_path.getValue();
+ }
+
+ return m_core_simulator_framework_path.getValue();
#else
- return FileSpec();
+ return FileSpec();
#endif
}
-void
-PlatformAppleSimulator::LoadCoreSimulator ()
-{
+void PlatformAppleSimulator::LoadCoreSimulator() {
#if defined(__APPLE__)
- static std::once_flag g_load_core_sim_flag;
- std::call_once(g_load_core_sim_flag, [this] {
- const std::string core_sim_path(GetCoreSimulatorPath().GetPath());
- if (core_sim_path.size())
- dlopen(core_sim_path.c_str(), RTLD_LAZY);
- });
+ static std::once_flag g_load_core_sim_flag;
+ std::call_once(g_load_core_sim_flag, [this] {
+ const std::string core_sim_path(GetCoreSimulatorPath().GetPath());
+ if (core_sim_path.size())
+ dlopen(core_sim_path.c_str(), RTLD_LAZY);
+ });
#endif
}
#if defined(__APPLE__)
-CoreSimulatorSupport::Device
-PlatformAppleSimulator::GetSimulatorDevice ()
-{
- if (!m_device.hasValue())
- {
- const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id = CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone;
- m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices().GetFanciest(dev_id);
- }
-
- if (m_device.hasValue())
- return m_device.getValue();
- else
- return CoreSimulatorSupport::Device();
+CoreSimulatorSupport::Device PlatformAppleSimulator::GetSimulatorDevice() {
+ if (!m_device.hasValue()) {
+ const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id =
+ CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone;
+ m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
+ GetDeveloperDirectory())
+ .GetFanciest(dev_id);
+ }
+
+ if (m_device.hasValue())
+ return m_device.getValue();
+ else
+ return CoreSimulatorSupport::Device();
}
#endif
-
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
index de8673b2a2af..04bc28842c39 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
@@ -12,70 +12,61 @@
// C Includes
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
-#include "lldb/Host/FileSpec.h"
#include "PlatformDarwin.h"
#include "PlatformiOSSimulatorCoreSimulatorSupport.h"
+#include "lldb/Host/FileSpec.h"
#include "llvm/ADT/Optional.h"
-class PlatformAppleSimulator : public PlatformDarwin
-{
+class PlatformAppleSimulator : public PlatformDarwin {
public:
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformAppleSimulator ();
-
- virtual
- ~PlatformAppleSimulator();
-
- lldb_private::Error
- LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info) override;
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- lldb_private::Error
- ConnectRemote (lldb_private::Args& args) override;
-
- lldb_private::Error
- DisconnectRemote () override;
-
- lldb::ProcessSP
- DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error) override;
+ //------------------------------------------------------------
+ // Class Functions
+ //------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ //------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------
+ PlatformAppleSimulator();
+
+ virtual ~PlatformAppleSimulator();
+
+ lldb_private::Error
+ LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ lldb_private::Error ConnectRemote(lldb_private::Args &args) override;
+
+ lldb_private::Error DisconnectRemote() override;
+
+ lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
protected:
- llvm::Optional<lldb_private::FileSpec> m_core_simulator_framework_path;
- llvm::Optional<CoreSimulatorSupport::Device> m_device;
-
- lldb_private::FileSpec
- GetCoreSimulatorPath();
-
- void
- LoadCoreSimulator ();
-
+ std::mutex m_core_sim_path_mutex;
+ llvm::Optional<lldb_private::FileSpec> m_core_simulator_framework_path;
+ llvm::Optional<CoreSimulatorSupport::Device> m_device;
+
+ lldb_private::FileSpec GetCoreSimulatorPath();
+
+ void LoadCoreSimulator();
+
#if defined(__APPLE__)
- CoreSimulatorSupport::Device
- GetSimulatorDevice ();
+ CoreSimulatorSupport::Device GetSimulatorDevice();
#endif
-
+
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformAppleSimulator);
-
+ DISALLOW_COPY_AND_ASSIGN(PlatformAppleSimulator);
};
-#endif // liblldb_PlatformAppleSimulator_h_
+#endif // liblldb_PlatformAppleSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
index 097d58dcfbc1..968ce5f9767b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
@@ -39,139 +39,118 @@ static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformAppleTVSimulator::Initialize ()
-{
- PlatformDarwin::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin (PlatformAppleTVSimulator::GetPluginNameStatic(),
- PlatformAppleTVSimulator::GetDescriptionStatic(),
- PlatformAppleTVSimulator::CreateInstance);
- }
+void PlatformAppleTVSimulator::Initialize() {
+ PlatformDarwin::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(
+ PlatformAppleTVSimulator::GetPluginNameStatic(),
+ PlatformAppleTVSimulator::GetDescriptionStatic(),
+ PlatformAppleTVSimulator::CreateInstance);
+ }
}
-void
-PlatformAppleTVSimulator::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformAppleTVSimulator::CreateInstance);
- }
+void PlatformAppleTVSimulator::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformAppleTVSimulator::CreateInstance);
}
+ }
- PlatformDarwin::Terminate ();
+ PlatformDarwin::Terminate();
}
-PlatformSP
-PlatformAppleTVSimulator::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>";
+PlatformSP PlatformAppleTVSimulator::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>";
+ const char *triple_cstr =
+ arch ? arch->GetTriple().getTriple().c_str() : "<null>";
- log->Printf ("PlatformAppleTVSimulator::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
+ log->Printf("PlatformAppleTVSimulator::%s(force=%s, arch={%s,%s})",
+ __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
+ }
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ switch (arch->GetMachine()) {
+ case llvm::Triple::x86_64: {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::Apple:
+ create = true;
+ break;
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- switch (arch->GetMachine())
- {
- case llvm::Triple::x86_64:
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- 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::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for the vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
-
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::TvOS:
- break;
-
+ default:
+ break;
+ }
+
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::TvOS:
+ break;
+
#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
+ // Only accept "unknown" for the OS if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
#endif
- default:
- create = false;
- break;
- }
- }
- }
- break;
default:
- break;
+ create = false;
+ break;
}
+ }
+ } break;
+ default:
+ break;
}
- if (create)
- {
- if (log)
- log->Printf ("PlatformAppleTVSimulator::%s() creating platform", __FUNCTION__);
-
- return PlatformSP(new PlatformAppleTVSimulator ());
- }
-
+ }
+ if (create) {
if (log)
- log->Printf ("PlatformAppleTVSimulator::%s() aborting creation of platform", __FUNCTION__);
+ log->Printf("PlatformAppleTVSimulator::%s() creating platform",
+ __FUNCTION__);
- return PlatformSP();
-}
+ return PlatformSP(new PlatformAppleTVSimulator());
+ }
+ if (log)
+ log->Printf("PlatformAppleTVSimulator::%s() aborting creation of platform",
+ __FUNCTION__);
-lldb_private::ConstString
-PlatformAppleTVSimulator::GetPluginNameStatic ()
-{
- static ConstString g_name("tvos-simulator");
- return g_name;
+ return PlatformSP();
}
-const char *
-PlatformAppleTVSimulator::GetDescriptionStatic()
-{
- return "Apple TV simulator platform plug-in.";
+lldb_private::ConstString PlatformAppleTVSimulator::GetPluginNameStatic() {
+ static ConstString g_name("tvos-simulator");
+ return g_name;
}
+const char *PlatformAppleTVSimulator::GetDescriptionStatic() {
+ return "Apple TV simulator platform plug-in.";
+}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformAppleTVSimulator::PlatformAppleTVSimulator () :
- PlatformDarwin (true),
- m_sdk_directory ()
-{
-}
+PlatformAppleTVSimulator::PlatformAppleTVSimulator()
+ : PlatformDarwin(true), m_sdk_dir_mutex(), m_sdk_directory() {}
//------------------------------------------------------------------
/// Destructor.
@@ -179,288 +158,236 @@ PlatformAppleTVSimulator::PlatformAppleTVSimulator () :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformAppleTVSimulator::~PlatformAppleTVSimulator()
-{
-}
-
-
-void
-PlatformAppleTVSimulator::GetStatus (Stream &strm)
-{
- Platform::GetStatus (strm);
- const char *sdk_directory = GetSDKDirectoryAsCString();
- if (sdk_directory)
- strm.Printf (" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString (" SDK Path: error: unable to locate SDK\n");
+PlatformAppleTVSimulator::~PlatformAppleTVSimulator() {}
+
+void PlatformAppleTVSimulator::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ const char *sdk_directory = GetSDKDirectoryAsCString();
+ if (sdk_directory)
+ strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
+ else
+ strm.PutCString(" SDK Path: error: unable to locate SDK\n");
}
-
-Error
-PlatformAppleTVSimulator::ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(module_spec);
-
- // If we have "ls" as the exe_file, resolve the executable loation based on
- // the current path variables
- // TODO: resolve bare executables in the Platform SDK
-// if (!resolved_exe_file.Exists())
-// resolved_exe_file.ResolveExecutableLocation ();
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one ourselves
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- ArchSpec platform_arch;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- // Only match x86 with x86 and x86_64 with x86_64...
- if (!module_spec.GetArchitecture().IsValid() || module_spec.GetArchitecture().GetCore() == resolved_module_spec.GetArchitecture().GetCore())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (platform_arch.GetArchitectureName());
- }
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+Error PlatformAppleTVSimulator::ResolveExecutable(
+ const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(module_spec);
+
+ // If we have "ls" as the exe_file, resolve the executable loation based on
+ // the current path variables
+ // TODO: resolve bare executables in the Platform SDK
+ // if (!resolved_exe_file.Exists())
+ // resolved_exe_file.ResolveExecutableLocation ();
+
+ // Resolve any executable within a bundle on MacOSX
+ // TODO: verify that this handles shallow bundles, if not then implement one
+ // ourselves
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
}
- else
- {
- error.SetErrorStringWithFormat ("'%s' does not exist",
- module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-static FileSpec::EnumerateDirectoryResult
-EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec)
-{
- if (file_type == FileSpec::eFileTypeDirectory)
- {
- 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;
+ // No valid architecture was specified or the exact ARM slice wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ ArchSpec platform_arch;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ // Only match x86 with x86 and x86_64 with x86_64...
+ if (!module_spec.GetArchitecture().IsValid() ||
+ module_spec.GetArchitecture().GetCore() ==
+ resolved_module_spec.GetArchitecture().GetCore()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
- }
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(platform_arch.GetArchitectureName());
+ }
+ }
-const char *
-PlatformAppleTVSimulator::GetSDKDirectoryAsCString()
-{
- std::lock_guard<std::mutex> guard(m_mutex);
- if (m_sdk_directory.empty())
- {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir)
- {
- char sdks_directory[PATH_MAX];
- char sdk_dirname[PATH_MAX];
- sdk_dirname[0] = '\0';
- snprintf (sdks_directory,
- sizeof(sdks_directory),
- "%s/Platforms/AppleTVSimulator.platform/Developer/SDKs",
- developer_dir);
- FileSpec simulator_sdk_spec;
- 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);
-
- if (sdk_dirname[0])
- {
- m_sdk_directory = sdks_directory;
- m_sdk_directory.append (1, '/');
- m_sdk_directory.append (sdk_dirname);
- return m_sdk_directory.c_str();
- }
- }
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_sdk_directory.assign (1, '\0');
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetString().str().c_str());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
}
+ } else {
+ error.SetErrorStringWithFormat("'%s' does not exist",
+ module_spec.GetFileSpec().GetPath().c_str());
+ }
- // We should have put a single NULL character into m_sdk_directory
- // or it should have a valid path if the code gets here
- assert (m_sdk_directory.empty() == false);
- if (m_sdk_directory[0])
- return m_sdk_directory.c_str();
- return NULL;
+ return error;
}
-Error
-PlatformAppleTVSimulator::GetSymbolFile (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- char resolved_path[PATH_MAX];
-
- const char * sdk_dir = GetSDKDirectoryAsCString();
- if (sdk_dir)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/%s",
- sdk_dir,
- platform_file_path);
-
- // First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- return error;
-
- // Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true);
- if (local_file.Exists())
- return error;
-
- }
- error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path,
- GetPluginName().GetCString());
- }
- else
- {
- error.SetErrorString ("invalid platform file argument");
+static FileSpec::EnumerateDirectoryResult
+EnumerateDirectoryCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ if (file_type == FileSpec::eFileTypeDirectory) {
+ 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 error;
+ }
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-Error
-PlatformAppleTVSimulator::GetSharedModule (const ModuleSpec &module_spec,
- lldb_private::Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- // For AppleTV, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- Error error;
- ModuleSpec platform_module_spec (module_spec);
- const FileSpec &platform_file = module_spec.GetFileSpec();
- error = GetSymbolFile (platform_file, module_spec.GetUUIDPtr(), platform_module_spec.GetFileSpec());
- if (error.Success())
- {
- error = ResolveExecutable (platform_module_spec, module_sp, module_search_paths_ptr);
+const char *PlatformAppleTVSimulator::GetSDKDirectoryAsCString() {
+ std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
+ if (m_sdk_directory.empty()) {
+ const char *developer_dir = GetDeveloperDirectory();
+ if (developer_dir) {
+ char sdks_directory[PATH_MAX];
+ char sdk_dirname[PATH_MAX];
+ sdk_dirname[0] = '\0';
+ snprintf(sdks_directory, sizeof(sdks_directory),
+ "%s/Platforms/AppleTVSimulator.platform/Developer/SDKs",
+ developer_dir);
+ FileSpec simulator_sdk_spec;
+ 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);
+
+ if (sdk_dirname[0]) {
+ m_sdk_directory = sdks_directory;
+ m_sdk_directory.append(1, '/');
+ m_sdk_directory.append(sdk_dirname);
+ return m_sdk_directory.c_str();
+ }
}
- else
- {
- const bool always_create = false;
- error = ModuleList::GetSharedModule (module_spec,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr,
- always_create);
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_sdk_directory.assign(1, '\0');
+ }
+
+ // We should have put a single NULL character into m_sdk_directory
+ // or it should have a valid path if the code gets here
+ assert(m_sdk_directory.empty() == false);
+ if (m_sdk_directory[0])
+ return m_sdk_directory.c_str();
+ return NULL;
+}
+Error PlatformAppleTVSimulator::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ Error error;
+ char platform_file_path[PATH_MAX];
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ char resolved_path[PATH_MAX];
+
+ const char *sdk_dir = GetSDKDirectoryAsCString();
+ if (sdk_dir) {
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
+ platform_file_path);
+
+ // First try in the SDK and see if the file is in there
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists())
+ return error;
+
+ // Else fall back to the actual path itself
+ local_file.SetFile(platform_file_path, true);
+ if (local_file.Exists())
+ return error;
}
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
+ error.SetErrorStringWithFormat(
+ "unable to locate a platform file for '%s' in platform '%s'",
+ platform_file_path, GetPluginName().GetCString());
+ } else {
+ error.SetErrorString("invalid platform file argument");
+ }
+ return error;
}
+Error PlatformAppleTVSimulator::GetSharedModule(
+ const ModuleSpec &module_spec, lldb_private::Process *process,
+ ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
+ ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
+ // For AppleTV, the SDK files are all cached locally on the host
+ // system. So first we ask for the file in the cached SDK,
+ // then we attempt to get a shared module for the right architecture
+ // with the right UUID.
+ Error error;
+ ModuleSpec platform_module_spec(module_spec);
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
+ platform_module_spec.GetFileSpec());
+ if (error.Success()) {
+ error = ResolveExecutable(platform_module_spec, module_sp,
+ module_search_paths_ptr);
+ } else {
+ const bool always_create = false;
+ error = ModuleList::GetSharedModule(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr, always_create);
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
+
+ return error;
+}
-uint32_t
-PlatformAppleTVSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- ProcessInstanceInfoList all_osx_process_infos;
- // First we get all OSX processes
- const uint32_t n = Host::FindProcesses (match_info, all_osx_process_infos);
-
- // Now we filter them down to only the TvOS triples
- for (uint32_t i=0; i<n; ++i)
- {
- const ProcessInstanceInfo &proc_info = all_osx_process_infos.GetProcessInfoAtIndex(i);
- if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::TvOS) {
- process_infos.Append(proc_info);
- }
+uint32_t PlatformAppleTVSimulator::FindProcesses(
+ const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ ProcessInstanceInfoList all_osx_process_infos;
+ // First we get all OSX processes
+ const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
+
+ // Now we filter them down to only the TvOS triples
+ for (uint32_t i = 0; i < n; ++i) {
+ const ProcessInstanceInfo &proc_info =
+ all_osx_process_infos.GetProcessInfoAtIndex(i);
+ if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::TvOS) {
+ process_infos.Append(proc_info);
}
- return process_infos.GetSize();
+ }
+ return process_infos.GetSize();
}
-bool
-PlatformAppleTVSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- static const ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKind64));
-
- if (idx == 0)
- {
- arch = platform_arch;
- if (arch.IsValid())
- {
- arch.GetTriple().setOS (llvm::Triple::TvOS);
- return true;
- }
+bool PlatformAppleTVSimulator::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ static const ArchSpec platform_arch(
+ HostInfo::GetArchitecture(HostInfo::eArchKind64));
+
+ if (idx == 0) {
+ arch = platform_arch;
+ if (arch.IsValid()) {
+ arch.GetTriple().setOS(llvm::Triple::TvOS);
+ return true;
}
- return false;
+ }
+ return false;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
index 0990f0729203..311ba05d76a2 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
@@ -16,106 +16,84 @@
// Project includes
#include "PlatformDarwin.h"
-class PlatformAppleTVSimulator : public PlatformDarwin
-{
+class PlatformAppleTVSimulator : public PlatformDarwin {
public:
+ //------------------------------------------------------------
+ // Class Functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch);
- //------------------------------------------------------------
- // 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();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformAppleTVSimulator ();
-
- virtual
- ~PlatformAppleTVSimulator();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Error
- ResolveExecutable (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic();
- }
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- uint32_t
- FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override
- {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneSimulator);
- }
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetDescriptionStatic();
+
+ //------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------
+ PlatformAppleTVSimulator();
+
+ virtual ~PlatformAppleTVSimulator();
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ virtual lldb_private::Error
+ GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ uint32_t
+ FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
+ lldb_private::ProcessInstanceInfoList &process_infos) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::iPhoneSimulator);
+ }
protected:
- std::string m_sdk_directory;
- std::string m_build_update;
-
- const char *
- GetSDKDirectoryAsCString();
+ std::mutex m_sdk_dir_mutex;
+ std::string m_sdk_directory;
+ std::string m_build_update;
-private:
- DISALLOW_COPY_AND_ASSIGN (PlatformAppleTVSimulator);
+ const char *GetSDKDirectoryAsCString();
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformAppleTVSimulator);
};
-
-#endif // liblldb_PlatformAppleTVSimulator_h_
+#endif // liblldb_PlatformAppleTVSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
index 46e5970bc089..291f58607597 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
@@ -39,139 +39,120 @@ static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformAppleWatchSimulator::Initialize ()
-{
- PlatformDarwin::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin (PlatformAppleWatchSimulator::GetPluginNameStatic(),
- PlatformAppleWatchSimulator::GetDescriptionStatic(),
- PlatformAppleWatchSimulator::CreateInstance);
- }
+void PlatformAppleWatchSimulator::Initialize() {
+ PlatformDarwin::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(
+ PlatformAppleWatchSimulator::GetPluginNameStatic(),
+ PlatformAppleWatchSimulator::GetDescriptionStatic(),
+ PlatformAppleWatchSimulator::CreateInstance);
+ }
}
-void
-PlatformAppleWatchSimulator::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformAppleWatchSimulator::CreateInstance);
- }
+void PlatformAppleWatchSimulator::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(
+ PlatformAppleWatchSimulator::CreateInstance);
}
+ }
- PlatformDarwin::Terminate ();
+ PlatformDarwin::Terminate();
}
-PlatformSP
-PlatformAppleWatchSimulator::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>";
+PlatformSP PlatformAppleWatchSimulator::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>";
+ const char *triple_cstr =
+ arch ? arch->GetTriple().getTriple().c_str() : "<null>";
- log->Printf ("PlatformAppleWatchSimulator::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
+ log->Printf("PlatformAppleWatchSimulator::%s(force=%s, arch={%s,%s})",
+ __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
+ }
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ switch (arch->GetMachine()) {
+ case llvm::Triple::x86_64: {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::Apple:
+ create = true;
+ break;
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- switch (arch->GetMachine())
- {
- case llvm::Triple::x86_64:
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- 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::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for the vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
-
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::WatchOS:
- break;
-
+ default:
+ break;
+ }
+
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::WatchOS:
+ break;
+
#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
+ // Only accept "unknown" for the OS if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
#endif
- default:
- create = false;
- break;
- }
- }
- }
- break;
default:
- break;
+ create = false;
+ break;
}
+ }
+ } break;
+ default:
+ break;
}
- if (create)
- {
- if (log)
- log->Printf ("PlatformAppleWatchSimulator::%s() creating platform", __FUNCTION__);
-
- return PlatformSP(new PlatformAppleWatchSimulator ());
- }
-
+ }
+ if (create) {
if (log)
- log->Printf ("PlatformAppleWatchSimulator::%s() aborting creation of platform", __FUNCTION__);
+ log->Printf("PlatformAppleWatchSimulator::%s() creating platform",
+ __FUNCTION__);
- return PlatformSP();
-}
+ return PlatformSP(new PlatformAppleWatchSimulator());
+ }
+ if (log)
+ log->Printf(
+ "PlatformAppleWatchSimulator::%s() aborting creation of platform",
+ __FUNCTION__);
-lldb_private::ConstString
-PlatformAppleWatchSimulator::GetPluginNameStatic ()
-{
- static ConstString g_name("watchos-simulator");
- return g_name;
+ return PlatformSP();
}
-const char *
-PlatformAppleWatchSimulator::GetDescriptionStatic()
-{
- return "Apple Watch simulator platform plug-in.";
+lldb_private::ConstString PlatformAppleWatchSimulator::GetPluginNameStatic() {
+ static ConstString g_name("watchos-simulator");
+ return g_name;
}
+const char *PlatformAppleWatchSimulator::GetDescriptionStatic() {
+ return "Apple Watch simulator platform plug-in.";
+}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformAppleWatchSimulator::PlatformAppleWatchSimulator () :
- PlatformDarwin (true),
- m_sdk_directory ()
-{
-}
+PlatformAppleWatchSimulator::PlatformAppleWatchSimulator()
+ : PlatformDarwin(true), m_sdk_directory() {}
//------------------------------------------------------------------
/// Destructor.
@@ -179,288 +160,237 @@ PlatformAppleWatchSimulator::PlatformAppleWatchSimulator () :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformAppleWatchSimulator::~PlatformAppleWatchSimulator()
-{
-}
-
-
-void
-PlatformAppleWatchSimulator::GetStatus (Stream &strm)
-{
- Platform::GetStatus (strm);
- const char *sdk_directory = GetSDKDirectoryAsCString();
- if (sdk_directory)
- strm.Printf (" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString (" SDK Path: error: unable to locate SDK\n");
+PlatformAppleWatchSimulator::~PlatformAppleWatchSimulator() {}
+
+void PlatformAppleWatchSimulator::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ const char *sdk_directory = GetSDKDirectoryAsCString();
+ if (sdk_directory)
+ strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
+ else
+ strm.PutCString(" SDK Path: error: unable to locate SDK\n");
}
-
-Error
-PlatformAppleWatchSimulator::ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(module_spec);
-
- // If we have "ls" as the exe_file, resolve the executable loation based on
- // the current path variables
- // TODO: resolve bare executables in the Platform SDK
-// if (!resolved_exe_file.Exists())
-// resolved_exe_file.ResolveExecutableLocation ();
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one ourselves
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- ArchSpec platform_arch;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- // Only match x86 with x86 and x86_64 with x86_64...
- if (!module_spec.GetArchitecture().IsValid() || module_spec.GetArchitecture().GetCore() == resolved_module_spec.GetArchitecture().GetCore())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (platform_arch.GetArchitectureName());
- }
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+Error PlatformAppleWatchSimulator::ResolveExecutable(
+ const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(module_spec);
+
+ // If we have "ls" as the exe_file, resolve the executable loation based on
+ // the current path variables
+ // TODO: resolve bare executables in the Platform SDK
+ // if (!resolved_exe_file.Exists())
+ // resolved_exe_file.ResolveExecutableLocation ();
+
+ // Resolve any executable within a bundle on MacOSX
+ // TODO: verify that this handles shallow bundles, if not then implement one
+ // ourselves
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
}
- else
- {
- error.SetErrorStringWithFormat ("'%s' does not exist",
- module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-static FileSpec::EnumerateDirectoryResult
-EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec)
-{
- if (file_type == FileSpec::eFileTypeDirectory)
- {
- 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;
+ // No valid architecture was specified or the exact ARM slice wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ ArchSpec platform_arch;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ // Only match x86 with x86 and x86_64 with x86_64...
+ if (!module_spec.GetArchitecture().IsValid() ||
+ module_spec.GetArchitecture().GetCore() ==
+ resolved_module_spec.GetArchitecture().GetCore()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
- }
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(platform_arch.GetArchitectureName());
+ }
+ }
-const char *
-PlatformAppleWatchSimulator::GetSDKDirectoryAsCString()
-{
- std::lock_guard<std::mutex> guard(m_mutex);
- if (m_sdk_directory.empty())
- {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir)
- {
- char sdks_directory[PATH_MAX];
- char sdk_dirname[PATH_MAX];
- sdk_dirname[0] = '\0';
- snprintf (sdks_directory,
- sizeof(sdks_directory),
- "%s/Platforms/AppleWatchSimulator.platform/Developer/SDKs",
- developer_dir);
- FileSpec simulator_sdk_spec;
- 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);
-
- if (sdk_dirname[0])
- {
- m_sdk_directory = sdks_directory;
- m_sdk_directory.append (1, '/');
- m_sdk_directory.append (sdk_dirname);
- return m_sdk_directory.c_str();
- }
- }
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_sdk_directory.assign (1, '\0');
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetString().str().c_str());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
}
+ } else {
+ error.SetErrorStringWithFormat("'%s' does not exist",
+ module_spec.GetFileSpec().GetPath().c_str());
+ }
- // We should have put a single NULL character into m_sdk_directory
- // or it should have a valid path if the code gets here
- assert (m_sdk_directory.empty() == false);
- if (m_sdk_directory[0])
- return m_sdk_directory.c_str();
- return NULL;
+ return error;
}
-Error
-PlatformAppleWatchSimulator::GetSymbolFile (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- char resolved_path[PATH_MAX];
-
- const char * sdk_dir = GetSDKDirectoryAsCString();
- if (sdk_dir)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/%s",
- sdk_dir,
- platform_file_path);
-
- // First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- return error;
-
- // Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true);
- if (local_file.Exists())
- return error;
-
- }
- error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path,
- GetPluginName().GetCString());
- }
- else
- {
- error.SetErrorString ("invalid platform file argument");
+static FileSpec::EnumerateDirectoryResult
+EnumerateDirectoryCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ if (file_type == FileSpec::eFileTypeDirectory) {
+ 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 error;
+ }
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-Error
-PlatformAppleWatchSimulator::GetSharedModule (const ModuleSpec &module_spec,
- lldb_private::Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- // For AppleWatch, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- Error error;
- ModuleSpec platform_module_spec (module_spec);
- const FileSpec &platform_file = module_spec.GetFileSpec();
- error = GetSymbolFile (platform_file, module_spec.GetUUIDPtr(), platform_module_spec.GetFileSpec());
- if (error.Success())
- {
- error = ResolveExecutable (platform_module_spec, module_sp, module_search_paths_ptr);
+const char *PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() {
+ std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
+ if (m_sdk_directory.empty()) {
+ const char *developer_dir = GetDeveloperDirectory();
+ if (developer_dir) {
+ char sdks_directory[PATH_MAX];
+ char sdk_dirname[PATH_MAX];
+ sdk_dirname[0] = '\0';
+ snprintf(sdks_directory, sizeof(sdks_directory),
+ "%s/Platforms/AppleWatchSimulator.platform/Developer/SDKs",
+ developer_dir);
+ FileSpec simulator_sdk_spec;
+ 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);
+
+ if (sdk_dirname[0]) {
+ m_sdk_directory = sdks_directory;
+ m_sdk_directory.append(1, '/');
+ m_sdk_directory.append(sdk_dirname);
+ return m_sdk_directory.c_str();
+ }
}
- else
- {
- const bool always_create = false;
- error = ModuleList::GetSharedModule (module_spec,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr,
- always_create);
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_sdk_directory.assign(1, '\0');
+ }
+
+ // We should have put a single NULL character into m_sdk_directory
+ // or it should have a valid path if the code gets here
+ assert(m_sdk_directory.empty() == false);
+ if (m_sdk_directory[0])
+ return m_sdk_directory.c_str();
+ return NULL;
+}
+Error PlatformAppleWatchSimulator::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ Error error;
+ char platform_file_path[PATH_MAX];
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ char resolved_path[PATH_MAX];
+
+ const char *sdk_dir = GetSDKDirectoryAsCString();
+ if (sdk_dir) {
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
+ platform_file_path);
+
+ // First try in the SDK and see if the file is in there
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists())
+ return error;
+
+ // Else fall back to the actual path itself
+ local_file.SetFile(platform_file_path, true);
+ if (local_file.Exists())
+ return error;
}
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
+ error.SetErrorStringWithFormat(
+ "unable to locate a platform file for '%s' in platform '%s'",
+ platform_file_path, GetPluginName().GetCString());
+ } else {
+ error.SetErrorString("invalid platform file argument");
+ }
+ return error;
}
+Error PlatformAppleWatchSimulator::GetSharedModule(
+ const ModuleSpec &module_spec, lldb_private::Process *process,
+ ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
+ ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
+ // For AppleWatch, the SDK files are all cached locally on the host
+ // system. So first we ask for the file in the cached SDK,
+ // then we attempt to get a shared module for the right architecture
+ // with the right UUID.
+ Error error;
+ ModuleSpec platform_module_spec(module_spec);
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
+ platform_module_spec.GetFileSpec());
+ if (error.Success()) {
+ error = ResolveExecutable(platform_module_spec, module_sp,
+ module_search_paths_ptr);
+ } else {
+ const bool always_create = false;
+ error = ModuleList::GetSharedModule(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr, always_create);
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
+
+ return error;
+}
-uint32_t
-PlatformAppleWatchSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- ProcessInstanceInfoList all_osx_process_infos;
- // First we get all OSX processes
- const uint32_t n = Host::FindProcesses (match_info, all_osx_process_infos);
-
- // Now we filter them down to only the WatchOS triples
- for (uint32_t i=0; i<n; ++i)
- {
- const ProcessInstanceInfo &proc_info = all_osx_process_infos.GetProcessInfoAtIndex(i);
- if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::WatchOS) {
- process_infos.Append(proc_info);
- }
+uint32_t PlatformAppleWatchSimulator::FindProcesses(
+ const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ ProcessInstanceInfoList all_osx_process_infos;
+ // First we get all OSX processes
+ const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
+
+ // Now we filter them down to only the WatchOS triples
+ for (uint32_t i = 0; i < n; ++i) {
+ const ProcessInstanceInfo &proc_info =
+ all_osx_process_infos.GetProcessInfoAtIndex(i);
+ if (proc_info.GetArchitecture().GetTriple().getOS() ==
+ llvm::Triple::WatchOS) {
+ process_infos.Append(proc_info);
}
- return process_infos.GetSize();
+ }
+ return process_infos.GetSize();
}
-bool
-PlatformAppleWatchSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- static const ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKind64));
-
- if (idx == 0)
- {
- arch = platform_arch;
- if (arch.IsValid())
- {
- arch.GetTriple().setOS (llvm::Triple::WatchOS);
- return true;
- }
+bool PlatformAppleWatchSimulator::GetSupportedArchitectureAtIndex(
+ uint32_t idx, ArchSpec &arch) {
+ static const ArchSpec platform_arch(
+ HostInfo::GetArchitecture(HostInfo::eArchKind64));
+
+ if (idx == 0) {
+ arch = platform_arch;
+ if (arch.IsValid()) {
+ arch.GetTriple().setOS(llvm::Triple::WatchOS);
+ return true;
}
- return false;
+ }
+ return false;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
index 8bcc0d4784fc..2b15611df47b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
@@ -16,105 +16,84 @@
// Project includes
#include "PlatformDarwin.h"
-class PlatformAppleWatchSimulator : public PlatformDarwin
-{
+class PlatformAppleWatchSimulator : public PlatformDarwin {
public:
+ //------------------------------------------------------------
+ // Class Functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch);
- //------------------------------------------------------------
- // 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();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformAppleWatchSimulator ();
-
- virtual
- ~PlatformAppleWatchSimulator();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Error
- ResolveExecutable (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic();
- }
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- uint32_t
- FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override
- {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneSimulator);
- }
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetDescriptionStatic();
+
+ //------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------
+ PlatformAppleWatchSimulator();
+
+ virtual ~PlatformAppleWatchSimulator();
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ virtual lldb_private::Error
+ GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ uint32_t
+ FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
+ lldb_private::ProcessInstanceInfoList &process_infos) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::iPhoneSimulator);
+ }
protected:
- std::string m_sdk_directory;
- std::string m_build_update;
-
- const char *
- GetSDKDirectoryAsCString();
+ std::mutex m_sdk_dir_mutex;
+ std::string m_sdk_directory;
+ std::string m_build_update;
-private:
- DISALLOW_COPY_AND_ASSIGN (PlatformAppleWatchSimulator);
+ const char *GetSDKDirectoryAsCString();
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformAppleWatchSimulator);
};
-#endif // liblldb_PlatformAppleWatchSimulator_h_
+#endif // liblldb_PlatformAppleWatchSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index f9eada986529..184912046706 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -27,11 +27,11 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Host/Symbols.h"
#include "lldb/Host/XML.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -41,22 +41,19 @@
#include "lldb/Target/Target.h"
#include "llvm/ADT/STLExtras.h"
-#if defined (__APPLE__)
+#if defined(__APPLE__)
#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH
#endif
using namespace lldb;
using namespace lldb_private;
-
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformDarwin::PlatformDarwin (bool is_host) :
- PlatformPOSIX(is_host), // This is the local host platform
- m_developer_directory ()
-{
-}
+PlatformDarwin::PlatformDarwin(bool is_host)
+ : PlatformPOSIX(is_host), // This is the local host platform
+ m_developer_directory() {}
//------------------------------------------------------------------
/// Destructor.
@@ -64,1659 +61,1831 @@ PlatformDarwin::PlatformDarwin (bool is_host) :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformDarwin::~PlatformDarwin()
-{
-}
+PlatformDarwin::~PlatformDarwin() {}
+
+FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
+ Target *target, Module &module, Stream *feedback_stream) {
+ FileSpecList file_list;
+ if (target &&
+ target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython) {
+ // NB some extensions might be meaningful and should not be stripped -
+ // "this.binary.file"
+ // should not lose ".file" but GetFileNameStrippingExtension() will do
+ // precisely that.
+ // Ideally, we should have a per-platform list of extensions (".exe",
+ // ".app", ".dSYM", ".framework")
+ // which should be stripped while leaving "this.binary.file" as-is.
+ ScriptInterpreter *script_interpreter =
+ target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+
+ FileSpec module_spec = module.GetFileSpec();
+
+ if (module_spec) {
+ SymbolVendor *symbols = module.GetSymbolVendor();
+ if (symbols) {
+ SymbolFile *symfile = symbols->GetSymbolFile();
+ if (symfile) {
+ ObjectFile *objfile = symfile->GetObjectFile();
+ if (objfile) {
+ FileSpec symfile_spec(objfile->GetFileSpec());
+ if (symfile_spec && symfile_spec.Exists()) {
+ while (module_spec.GetFilename()) {
+ std::string module_basename(
+ module_spec.GetFilename().GetCString());
+ std::string original_module_basename(module_basename);
+
+ bool was_keyword = false;
+
+ // FIXME: for Python, we cannot allow certain characters in
+ // module
+ // filenames we import. Theoretically, different scripting
+ // languages may
+ // have different sets of forbidden tokens in filenames, and
+ // that should
+ // be dealt with by each ScriptInterpreter. For now, we just
+ // replace dots
+ // with underscores, but if we ever support anything other than
+ // Python
+ // we will need to rework this
+ std::replace(module_basename.begin(), module_basename.end(),
+ '.', '_');
+ std::replace(module_basename.begin(), module_basename.end(),
+ ' ', '_');
+ std::replace(module_basename.begin(), module_basename.end(),
+ '-', '_');
+ if (script_interpreter &&
+ script_interpreter->IsReservedWord(
+ module_basename.c_str())) {
+ module_basename.insert(module_basename.begin(), '_');
+ was_keyword = true;
+ }
-FileSpecList
-PlatformDarwin::LocateExecutableScriptingResources (Target *target,
- Module &module,
- Stream* feedback_stream)
-{
- FileSpecList file_list;
- if (target && target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython)
- {
- // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
- // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
- // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
- // which should be stripped while leaving "this.binary.file" as-is.
- ScriptInterpreter *script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
-
- FileSpec module_spec = module.GetFileSpec();
-
- if (module_spec)
- {
- SymbolVendor *symbols = module.GetSymbolVendor ();
- if (symbols)
- {
- SymbolFile *symfile = symbols->GetSymbolFile();
- if (symfile)
- {
- ObjectFile *objfile = symfile->GetObjectFile();
- if (objfile)
- {
- FileSpec symfile_spec (objfile->GetFileSpec());
- if (symfile_spec && symfile_spec.Exists())
- {
- while (module_spec.GetFilename())
- {
- std::string module_basename (module_spec.GetFilename().GetCString());
- std::string original_module_basename (module_basename);
-
- bool was_keyword = false;
-
- // FIXME: for Python, we cannot allow certain characters in module
- // filenames we import. Theoretically, different scripting languages may
- // have different sets of forbidden tokens in filenames, and that should
- // be dealt with by each ScriptInterpreter. For now, we just replace dots
- // with underscores, but if we ever support anything other than Python
- // we will need to rework this
- std::replace(module_basename.begin(), module_basename.end(), '.', '_');
- std::replace(module_basename.begin(), module_basename.end(), ' ', '_');
- std::replace(module_basename.begin(), module_basename.end(), '-', '_');
- if (script_interpreter && script_interpreter->IsReservedWord(module_basename.c_str()))
- {
- module_basename.insert(module_basename.begin(), '_');
- was_keyword = true;
- }
-
- StreamString path_string;
- StreamString original_path_string;
- // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
- // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
- path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), module_basename.c_str());
- original_path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), original_module_basename.c_str());
- FileSpec script_fspec(path_string.GetData(), true);
- FileSpec orig_script_fspec(original_path_string.GetData(), true);
-
- // if we did some replacements of reserved characters, and a file with the untampered name
- // exists, then warn the user that the file as-is shall not be loaded
- if (feedback_stream)
- {
- if (module_basename != original_module_basename
- && orig_script_fspec.Exists())
- {
- const char* reason_for_complaint = was_keyword ? "conflicts with a keyword" : "contains reserved characters";
- if (script_fspec.Exists())
- feedback_stream->Printf("warning: the symbol file '%s' contains a debug script. However, its name"
- " '%s' %s and as such cannot be loaded. LLDB will"
- " load '%s' instead. Consider removing the file with the malformed name to"
- " eliminate this warning.\n",
- symfile_spec.GetPath().c_str(),
- original_path_string.GetData(),
- reason_for_complaint,
- path_string.GetData());
- else
- feedback_stream->Printf("warning: the symbol file '%s' contains a debug script. However, its name"
- " %s and as such cannot be loaded. If you intend"
- " to have this script loaded, please rename '%s' to '%s' and retry.\n",
- symfile_spec.GetPath().c_str(),
- reason_for_complaint,
- original_path_string.GetData(),
- path_string.GetData());
- }
- }
-
- if (script_fspec.Exists())
- {
- file_list.Append (script_fspec);
- break;
- }
-
- // If we didn't find the python file, then keep
- // stripping the extensions and try again
- ConstString filename_no_extension (module_spec.GetFileNameStrippingExtension());
- if (module_spec.GetFilename() == filename_no_extension)
- break;
-
- module_spec.GetFilename() = filename_no_extension;
- }
- }
- }
+ StreamString path_string;
+ StreamString original_path_string;
+ // for OSX we are going to be in
+ // .dSYM/Contents/Resources/DWARF/<basename>
+ // let us go to .dSYM/Contents/Resources/Python/<basename>.py
+ // and see if the file exists
+ path_string.Printf("%s/../Python/%s.py",
+ symfile_spec.GetDirectory().GetCString(),
+ module_basename.c_str());
+ original_path_string.Printf(
+ "%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);
+
+ // 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()) {
+ const char *reason_for_complaint =
+ was_keyword ? "conflicts with a keyword"
+ : "contains reserved characters";
+ if (script_fspec.Exists())
+ feedback_stream->Printf(
+ "warning: the symbol file '%s' contains a debug "
+ "script. However, its name"
+ " '%s' %s and as such cannot be loaded. LLDB will"
+ " load '%s' instead. Consider removing the file with "
+ "the malformed name to"
+ " eliminate this warning.\n",
+ symfile_spec.GetPath().c_str(),
+ original_path_string.GetData(), reason_for_complaint,
+ path_string.GetData());
+ else
+ feedback_stream->Printf(
+ "warning: the symbol file '%s' contains a debug "
+ "script. However, its name"
+ " %s and as such cannot be loaded. If you intend"
+ " to have this script loaded, please rename '%s' to "
+ "'%s' and retry.\n",
+ symfile_spec.GetPath().c_str(), reason_for_complaint,
+ original_path_string.GetData(),
+ path_string.GetData());
+ }
+ }
+
+ if (script_fspec.Exists()) {
+ file_list.Append(script_fspec);
+ break;
}
+
+ // If we didn't find the python file, then keep
+ // stripping the extensions and try again
+ ConstString filename_no_extension(
+ module_spec.GetFileNameStrippingExtension());
+ if (module_spec.GetFilename() == filename_no_extension)
+ break;
+
+ module_spec.GetFilename() = filename_no_extension;
+ }
}
+ }
}
+ }
}
- return file_list;
+ }
+ return file_list;
}
-Error
-PlatformDarwin::ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec(module_spec);
-
- if (IsHost())
- {
- // If we have "ls" as the exe_file, resolve the executable loation based on
- // the current path variables
- if (!resolved_module_spec.GetFileSpec().Exists())
- {
- module_spec.GetFileSpec().GetPath (exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
- }
-
- if (!resolved_module_spec.GetFileSpec().Exists())
- resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();
-
- // Resolve any executable within a bundle on MacOSX
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- {
- const uint32_t permissions = resolved_module_spec.GetFileSpec().GetPermissions();
- if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
- error.SetErrorStringWithFormat ("executable '%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- else
- error.SetErrorStringWithFormat ("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
+Error PlatformDarwin::ResolveExecutable(
+ const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ char exe_path[PATH_MAX];
+ ModuleSpec resolved_module_spec(module_spec);
+
+ if (IsHost()) {
+ // If we have "ls" as the exe_file, resolve the executable loation based on
+ // the current path variables
+ if (!resolved_module_spec.GetFileSpec().Exists()) {
+ module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+ resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
}
- else
- {
- if (m_remote_platform_sp)
- {
- error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
- }
- else
- {
- // We may connect to a process and use the provided executable (Don't use local $PATH).
- // Resolve any executable within a bundle on MacOSX
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_module_spec.GetFileSpec().GetFilename().AsCString(""));
- }
+ if (!resolved_module_spec.GetFileSpec().Exists())
+ resolved_module_spec.GetFileSpec().ResolveExecutableLocation();
+
+ // Resolve any executable within a bundle on MacOSX
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else {
+ const uint32_t permissions =
+ resolved_module_spec.GetFileSpec().GetPermissions();
+ if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
+ error.SetErrorStringWithFormat(
+ "executable '%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ else
+ error.SetErrorStringWithFormat(
+ "unable to find executable for '%s'",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
-
-
- if (error.Success())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
-
- if (error.Fail() || exe_module_sp.get() == NULL || exe_module_sp->GetObjectFile() == NULL)
- {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
+ } else {
+ if (m_remote_platform_sp) {
+ error =
+ GetCachedExecutable(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, *m_remote_platform_sp);
+ } else {
+ // We may connect to a process and use the provided executable (Don't use
+ // local $PATH).
+
+ // Resolve any executable within a bundle on MacOSX
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else
+ error.SetErrorStringWithFormat(
+ "the platform is not currently connected, and '%s' doesn't exist "
+ "in the system root.",
+ resolved_module_spec.GetFileSpec().GetFilename().AsCString(""));
+ }
+ }
+
+ if (error.Success()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+
+ if (error.Fail() || exe_module_sp.get() == NULL ||
+ exe_module_sp->GetObjectFile() == NULL) {
+ exe_module_sp.reset();
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain the architecture %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+ } else {
+ // No valid architecture was specified, ask the platform for
+ // the architectures that we should be using (in the correct order)
+ // and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = GetSharedModule(resolved_module_spec, NULL, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
- else
- {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = GetSharedModule (resolved_module_spec,
- NULL,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
+ }
}
+ }
- return error;
+ return error;
}
-Error
-PlatformDarwin::ResolveSymbolFile (Target &target,
- const ModuleSpec &sym_spec,
- FileSpec &sym_file)
-{
- Error error;
- sym_file = sym_spec.GetSymbolFileSpec();
- if (sym_file.Exists())
- {
- if (sym_file.GetFileType() == FileSpec::eFileTypeDirectory)
- {
- sym_file = Symbols::FindSymbolFileInBundle (sym_file,
- sym_spec.GetUUIDPtr(),
- sym_spec.GetArchitecturePtr());
- }
+Error PlatformDarwin::ResolveSymbolFile(Target &target,
+ const ModuleSpec &sym_spec,
+ FileSpec &sym_file) {
+ Error error;
+ sym_file = sym_spec.GetSymbolFileSpec();
+ if (sym_file.Exists()) {
+ if (sym_file.GetFileType() == FileSpec::eFileTypeDirectory) {
+ sym_file = Symbols::FindSymbolFileInBundle(
+ sym_file, sym_spec.GetUUIDPtr(), sym_spec.GetArchitecturePtr());
}
- else
- {
- if (sym_spec.GetUUID().IsValid())
- {
-
- }
+ } else {
+ if (sym_spec.GetUUID().IsValid()) {
}
- return error;
-
+ }
+ return error;
}
static lldb_private::Error
-MakeCacheFolderForFile (const FileSpec& module_cache_spec)
-{
- FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
- return FileSystem::MakeDirectory(module_cache_folder, eFilePermissionsDirectoryDefault);
+MakeCacheFolderForFile(const FileSpec &module_cache_spec) {
+ FileSpec module_cache_folder =
+ module_cache_spec.CopyByRemovingLastPathComponent();
+ return FileSystem::MakeDirectory(module_cache_folder,
+ eFilePermissionsDirectoryDefault);
}
static lldb_private::Error
-BringInRemoteFile (Platform* platform,
- const lldb_private::ModuleSpec &module_spec,
- const FileSpec& module_cache_spec)
-{
- MakeCacheFolderForFile(module_cache_spec);
- Error err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
- return err;
+BringInRemoteFile(Platform *platform,
+ const lldb_private::ModuleSpec &module_spec,
+ const FileSpec &module_cache_spec) {
+ MakeCacheFolderForFile(module_cache_spec);
+ Error err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
+ return err;
}
-lldb_private::Error
-PlatformDarwin::GetSharedModuleWithLocalCache (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol path %s/%s",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString(),
- module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
- module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
- module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
- module_spec.GetSymbolFileSpec().GetFilename().AsCString());
-
- Error err;
-
- err = ModuleList::GetSharedModule(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
- if (module_sp)
- return err;
-
- if (!IsHost())
- {
- std::string cache_path(GetLocalCacheDirectory());
- // Only search for a locally cached file if we have a valid cache path
- if (!cache_path.empty())
- {
- std::string module_path (module_spec.GetFileSpec().GetPath());
- cache_path.append(module_path);
- FileSpec module_cache_spec(cache_path.c_str(),false);
-
- // if rsync is supported, always bring in the file - rsync will be very efficient
- // when files are the same on the local and remote end of the connection
- if (this->GetSupportsRSync())
- {
- err = BringInRemoteFile (this, module_spec, module_cache_spec);
- if (err.Fail())
- return err;
- if (module_cache_spec.Exists())
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] module %s/%s was rsynced and is now there",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
- module_sp.reset(new Module(local_spec));
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return Error();
- }
- }
-
- // try to find the module in the cache
- if (module_cache_spec.Exists())
- {
- // get the local and remote MD5 and compare
- if (m_remote_platform_sp)
- {
- // when going over the *slow* GDB remote transfer mechanism we first check
- // the hashes of the files - and only do the actual transfer if they differ
- uint64_t high_local,high_remote,low_local,low_remote;
- FileSystem::CalculateMD5(module_cache_spec, low_local, high_local);
- m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), low_remote, high_remote);
- if (low_local != low_remote || high_local != high_remote)
- {
- // bring in the remote file
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] module %s/%s needs to be replaced from remote copy",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
- if (err.Fail())
- return err;
- }
- }
-
- ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
- module_sp.reset(new Module(local_spec));
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] module %s/%s was found in the cache",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- return Error();
- }
-
- // bring in the remote module file
+lldb_private::Error PlatformDarwin::GetSharedModuleWithLocalCache(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol "
+ "path %s/%s",
+ (IsHost() ? "host" : "remote"),
+ module_spec.GetFileSpec().GetDirectory().AsCString(),
+ module_spec.GetFileSpec().GetFilename().AsCString(),
+ module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
+ module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
+ module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
+ module_spec.GetSymbolFileSpec().GetFilename().AsCString());
+
+ Error err;
+
+ err = ModuleList::GetSharedModule(module_spec, module_sp,
+ module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr);
+ if (module_sp)
+ return err;
+
+ if (!IsHost()) {
+ std::string cache_path(GetLocalCacheDirectory());
+ // Only search for a locally cached file if we have a valid cache path
+ if (!cache_path.empty()) {
+ std::string module_path(module_spec.GetFileSpec().GetPath());
+ cache_path.append(module_path);
+ FileSpec module_cache_spec(cache_path, false);
+
+ // if rsync is supported, always bring in the file - rsync will be very
+ // efficient
+ // when files are the same on the local and remote end of the connection
+ if (this->GetSupportsRSync()) {
+ err = BringInRemoteFile(this, module_spec, module_cache_spec);
+ if (err.Fail())
+ return err;
+ if (module_cache_spec.Exists()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("[%s] module %s/%s was rsynced and is now there",
+ (IsHost() ? "host" : "remote"),
+ module_spec.GetFileSpec().GetDirectory().AsCString(),
+ module_spec.GetFileSpec().GetFilename().AsCString());
+ ModuleSpec local_spec(module_cache_spec,
+ module_spec.GetArchitecture());
+ module_sp.reset(new Module(local_spec));
+ module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
+ return Error();
+ }
+ }
+
+ // try to find the module in the cache
+ if (module_cache_spec.Exists()) {
+ // get the local and remote MD5 and compare
+ if (m_remote_platform_sp) {
+ // when going over the *slow* GDB remote transfer mechanism we first
+ // check
+ // the hashes of the files - and only do the actual transfer if they
+ // differ
+ uint64_t high_local, high_remote, low_local, low_remote;
+ FileSystem::CalculateMD5(module_cache_spec, low_local, high_local);
+ m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(),
+ low_remote, high_remote);
+ if (low_local != low_remote || high_local != high_remote) {
+ // bring in the remote file
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log)
- log->Printf("[%s] module %s/%s needs to come in remotely",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
+ log->Printf(
+ "[%s] module %s/%s needs to be replaced from remote copy",
+ (IsHost() ? "host" : "remote"),
+ module_spec.GetFileSpec().GetDirectory().AsCString(),
+ module_spec.GetFileSpec().GetFilename().AsCString());
+ Error err = BringInRemoteFile(this, module_spec, module_cache_spec);
if (err.Fail())
- return err;
- if (module_cache_spec.Exists())
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[%s] module %s/%s is now cached and fine",
- (IsHost() ? "host" : "remote"),
- module_spec.GetFileSpec().GetDirectory().AsCString(),
- module_spec.GetFileSpec().GetFilename().AsCString());
- ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
- module_sp.reset(new Module(local_spec));
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return Error();
- }
- else
- return Error("unable to obtain valid module file");
+ return err;
+ }
}
- else
- return Error("no cache path");
- }
- else
- return Error ("unable to resolve module");
+
+ ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
+ module_sp.reset(new Module(local_spec));
+ module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("[%s] module %s/%s was found in the cache",
+ (IsHost() ? "host" : "remote"),
+ module_spec.GetFileSpec().GetDirectory().AsCString(),
+ module_spec.GetFileSpec().GetFilename().AsCString());
+ return Error();
+ }
+
+ // bring in the remote module file
+ if (log)
+ log->Printf("[%s] module %s/%s needs to come in remotely",
+ (IsHost() ? "host" : "remote"),
+ module_spec.GetFileSpec().GetDirectory().AsCString(),
+ module_spec.GetFileSpec().GetFilename().AsCString());
+ Error err = BringInRemoteFile(this, module_spec, module_cache_spec);
+ if (err.Fail())
+ return err;
+ if (module_cache_spec.Exists()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("[%s] module %s/%s is now cached and fine",
+ (IsHost() ? "host" : "remote"),
+ module_spec.GetFileSpec().GetDirectory().AsCString(),
+ module_spec.GetFileSpec().GetFilename().AsCString());
+ ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
+ module_sp.reset(new Module(local_spec));
+ module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
+ return Error();
+ } else
+ return Error("unable to obtain valid module file");
+ } else
+ return Error("no cache path");
+ } else
+ return Error("unable to resolve module");
}
-Error
-PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
- Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- Error error;
- module_sp.reset();
-
- if (IsRemote())
- {
- // If we have a remote platform always, let it try and locate
- // the shared module first.
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
- }
+Error PlatformDarwin::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ Error error;
+ module_sp.reset();
+
+ if (IsRemote()) {
+ // If we have a remote platform always, let it try and locate
+ // the shared module first.
+ if (m_remote_platform_sp) {
+ error = m_remote_platform_sp->GetSharedModule(
+ module_spec, process, module_sp, module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
}
-
- if (!module_sp)
- {
- // Fall back to the local platform and find the file locally
- error = Platform::GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
-
- const FileSpec &platform_file = module_spec.GetFileSpec();
- if (!module_sp && module_search_paths_ptr && platform_file)
- {
- // We can try to pull off part of the file path up to the bundle
- // directory level and try any module search paths...
- FileSpec bundle_directory;
- if (Host::GetBundleDirectory (platform_file, bundle_directory))
- {
- if (platform_file == bundle_directory)
- {
- ModuleSpec new_module_spec (module_spec);
- new_module_spec.GetFileSpec() = bundle_directory;
- if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
- {
- Error new_error (Platform::GetSharedModule (new_module_spec,
- process,
- module_sp,
- NULL,
- old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
- return new_error;
- }
- }
- else
- {
- char platform_path[PATH_MAX];
- char bundle_dir[PATH_MAX];
- platform_file.GetPath (platform_path, sizeof(platform_path));
- const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
- char new_path[PATH_MAX];
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i=0; i<num_module_search_paths; ++i)
- {
- const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
- if (search_path_len < sizeof(new_path))
- {
- 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())
- {
- ModuleSpec new_module_spec (module_spec);
- new_module_spec.GetFileSpec() = new_file_spec;
- Error new_error (Platform::GetSharedModule (new_module_spec,
- process,
- module_sp,
- NULL,
- old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
- {
- module_sp->SetPlatformFileSpec(new_file_spec);
- return new_error;
- }
- }
- }
- }
+ }
+
+ if (!module_sp) {
+ // Fall back to the local platform and find the file locally
+ error = Platform::GetSharedModule(module_spec, process, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ if (!module_sp && module_search_paths_ptr && platform_file) {
+ // We can try to pull off part of the file path up to the bundle
+ // directory level and try any module search paths...
+ FileSpec bundle_directory;
+ if (Host::GetBundleDirectory(platform_file, bundle_directory)) {
+ if (platform_file == bundle_directory) {
+ ModuleSpec new_module_spec(module_spec);
+ new_module_spec.GetFileSpec() = bundle_directory;
+ if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) {
+ Error new_error(Platform::GetSharedModule(
+ new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ return new_error;
+ }
+ } else {
+ char platform_path[PATH_MAX];
+ char bundle_dir[PATH_MAX];
+ platform_file.GetPath(platform_path, sizeof(platform_path));
+ const size_t bundle_directory_len =
+ bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir));
+ char new_path[PATH_MAX];
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i) {
+ const size_t search_path_len =
+ module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(
+ new_path, sizeof(new_path));
+ if (search_path_len < sizeof(new_path)) {
+ 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()) {
+ ModuleSpec new_module_spec(module_spec);
+ new_module_spec.GetFileSpec() = new_file_spec;
+ Error new_error(Platform::GetSharedModule(
+ new_module_spec, process, module_sp, NULL,
+ old_module_sp_ptr, did_create_ptr));
+
+ if (module_sp) {
+ module_sp->SetPlatformFileSpec(new_file_spec);
+ return new_error;
}
+ }
}
+ }
}
+ }
}
- if (module_sp)
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return error;
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
+ return error;
}
size_t
-PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
-{
- const uint8_t *trap_opcode = nullptr;
- uint32_t trap_opcode_size = 0;
- bool bp_is_thumb = false;
-
- llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
- switch (machine)
- {
- case llvm::Triple::aarch64:
- {
- // TODO: fix this with actual darwin breakpoint opcode for arm64.
- // right now debugging uses the Z packets with GDB remote so this
- // is not needed, but the size needs to be correct...
- static const uint8_t g_arm64_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
- trap_opcode = g_arm64_breakpoint_opcode;
- trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
- }
- break;
-
- case llvm::Triple::thumb:
- bp_is_thumb = true;
- LLVM_FALLTHROUGH;
- case llvm::Triple::arm:
- {
- static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
- static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
-
- // Auto detect arm/thumb if it wasn't explicitly specified
- if (!bp_is_thumb)
- {
- lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
- if (bp_loc_sp)
- bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA;
- }
- if (bp_is_thumb)
- {
- trap_opcode = g_thumb_breakpooint_opcode;
- trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
- break;
- }
- trap_opcode = g_arm_breakpoint_opcode;
- trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- {
- static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
- trap_opcode = g_ppc_breakpoint_opcode;
- trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
- }
- break;
-
- default:
- return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
+PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,
+ BreakpointSite *bp_site) {
+ const uint8_t *trap_opcode = nullptr;
+ uint32_t trap_opcode_size = 0;
+ bool bp_is_thumb = false;
+
+ llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
+ switch (machine) {
+ case llvm::Triple::aarch64: {
+ // TODO: fix this with actual darwin breakpoint opcode for arm64.
+ // right now debugging uses the Z packets with GDB remote so this
+ // is not needed, but the size needs to be correct...
+ static const uint8_t g_arm64_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
+ trap_opcode = g_arm64_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
+ } break;
+
+ case llvm::Triple::thumb:
+ bp_is_thumb = true;
+ LLVM_FALLTHROUGH;
+ case llvm::Triple::arm: {
+ static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
+ static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE};
+
+ // Auto detect arm/thumb if it wasn't explicitly specified
+ if (!bp_is_thumb) {
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ if (bp_loc_sp)
+ bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
+ eAddressClassCodeAlternateISA;
}
-
- if (trap_opcode && trap_opcode_size)
- {
- if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
- return trap_opcode_size;
+ if (bp_is_thumb) {
+ trap_opcode = g_thumb_breakpooint_opcode;
+ trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
+ break;
}
- return 0;
-
+ trap_opcode = g_arm_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
+ } break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64: {
+ static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
+ trap_opcode = g_ppc_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
+ } break;
+
+ default:
+ return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
+ }
+
+ if (trap_opcode && trap_opcode_size) {
+ if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
+ return trap_opcode_size;
+ }
+ return 0;
}
-bool
-PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- bool success = false;
- if (IsHost())
- {
- success = Platform::GetProcessInfo (pid, process_info);
- }
- else
- {
- if (m_remote_platform_sp)
- success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
- }
- return success;
+bool PlatformDarwin::GetProcessInfo(lldb::pid_t pid,
+ ProcessInstanceInfo &process_info) {
+ bool success = false;
+ if (IsHost()) {
+ success = Platform::GetProcessInfo(pid, process_info);
+ } else {
+ if (m_remote_platform_sp)
+ success = m_remote_platform_sp->GetProcessInfo(pid, process_info);
+ }
+ return success;
}
uint32_t
-PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- uint32_t match_count = 0;
- if (IsHost())
- {
- // Let the base class figure out the host details
- match_count = Platform::FindProcesses (match_info, process_infos);
- }
- else
- {
- // If we are remote, we can only return results if we are connected
- if (m_remote_platform_sp)
- match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
- }
- return match_count;
+PlatformDarwin::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ uint32_t match_count = 0;
+ if (IsHost()) {
+ // Let the base class figure out the host details
+ match_count = Platform::FindProcesses(match_info, process_infos);
+ } else {
+ // If we are remote, we can only return results if we are connected
+ if (m_remote_platform_sp)
+ match_count =
+ m_remote_platform_sp->FindProcesses(match_info, process_infos);
+ }
+ return match_count;
}
-bool
-PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp)
-{
- if (!module_sp)
- return false;
-
- ObjectFile *obj_file = module_sp->GetObjectFile();
- if (!obj_file)
- return false;
-
- ObjectFile::Type obj_type = obj_file->GetType();
- if (obj_type == ObjectFile::eTypeDynamicLinker)
- return true;
- else
- return false;
+bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches(
+ lldb_private::Target &target, const lldb::ModuleSP &module_sp) {
+ if (!module_sp)
+ return false;
+
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (!obj_file)
+ return false;
+
+ ObjectFile::Type obj_type = obj_file->GetType();
+ if (obj_type == ObjectFile::eTypeDynamicLinker)
+ return true;
+ else
+ return false;
}
-bool
-PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h)
- {
- switch (idx)
- {
- case 0:
- arch = host_arch;
- return true;
-
- case 1:
- arch.SetTriple("x86_64-apple-macosx");
- return true;
-
- case 2:
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return true;
-
- default: return false;
- }
+bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) {
+ switch (idx) {
+ case 0:
+ arch = host_arch;
+ return true;
+
+ case 1:
+ arch.SetTriple("x86_64-apple-macosx");
+ return true;
+
+ case 2:
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ return true;
+
+ default:
+ return false;
}
- else
- {
- if (idx == 0)
- {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- return arch.IsValid();
- }
- else if (idx == 1)
- {
- ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
- ArchSpec platform_arch64(HostInfo::GetArchitecture(HostInfo::eArchKind64));
- if (platform_arch.IsExactMatch(platform_arch64))
- {
- // This macosx platform supports both 32 and 64 bit. Since we already
- // returned the 64 bit arch for idx == 0, return the 32 bit arch
- // for idx == 1
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return arch.IsValid();
- }
- }
+ } else {
+ if (idx == 0) {
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ return arch.IsValid();
+ } else if (idx == 1) {
+ ArchSpec platform_arch(
+ HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
+ ArchSpec platform_arch64(
+ HostInfo::GetArchitecture(HostInfo::eArchKind64));
+ if (platform_arch.IsExactMatch(platform_arch64)) {
+ // This macosx platform supports both 32 and 64 bit. Since we already
+ // returned the 64 bit arch for idx == 0, return the 32 bit arch
+ // for idx == 1
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ return arch.IsValid();
+ }
}
- return false;
+ }
+ return false;
}
// The architecture selection rules for arm processors
-// These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor.
+// These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run
+// fine on an armv7f processor.
-bool
-PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- ArchSpec system_arch (GetSystemArchitecture());
+bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ ArchSpec system_arch(GetSystemArchitecture());
- // When lldb is running on a watch or tv, set the arch OS name appropriately.
-#if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
+// When lldb is running on a watch or tv, set the arch OS name appropriately.
+#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
#define OSNAME "tvos"
-#elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
+#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
#define OSNAME "watchos"
#else
#define OSNAME "ios"
#endif
- const ArchSpec::Core system_core = system_arch.GetCore();
- switch (system_core)
- {
+ const ArchSpec::Core system_core = system_arch.GetCore();
+ switch (system_core) {
+ default:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("arm64-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv7f-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv7k-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv7s-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("armv7m-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("armv7em-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 12:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 13:
+ arch.SetTriple("thumbv7f-apple-" OSNAME);
+ return true;
+ case 14:
+ arch.SetTriple("thumbv7k-apple-" OSNAME);
+ return true;
+ case 15:
+ arch.SetTriple("thumbv7s-apple-" OSNAME);
+ return true;
+ case 16:
+ arch.SetTriple("thumbv7m-apple-" OSNAME);
+ return true;
+ case 17:
+ arch.SetTriple("thumbv7em-apple-" OSNAME);
+ return true;
+ case 18:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 19:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 20:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 21:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 22:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
default:
- switch (idx)
- {
- case 0: arch.SetTriple ("arm64-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv7f-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv7k-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv7s-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("armv7m-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("armv7em-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 12: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 13: arch.SetTriple ("thumbv7f-apple-" OSNAME); return true;
- case 14: arch.SetTriple ("thumbv7k-apple-" OSNAME); return true;
- case 15: arch.SetTriple ("thumbv7s-apple-" OSNAME); return true;
- case 16: arch.SetTriple ("thumbv7m-apple-" OSNAME); return true;
- case 17: arch.SetTriple ("thumbv7em-apple-" OSNAME); return true;
- case 18: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 19: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 20: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 21: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 22: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- switch (idx)
- {
- case 0: arch.SetTriple ("arm64-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv7s-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv7f-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv7m-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv7em-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 12: arch.SetTriple ("thumbv7f-apple-" OSNAME); return true;
- case 13: arch.SetTriple ("thumbv7k-apple-" OSNAME); return true;
- case 14: arch.SetTriple ("thumbv7s-apple-" OSNAME); return true;
- case 15: arch.SetTriple ("thumbv7m-apple-" OSNAME); return true;
- case 16: arch.SetTriple ("thumbv7em-apple-" OSNAME); return true;
- case 17: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 18: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 19: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 20: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 21: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7f:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7f-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumbv7f-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7k:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7k-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumbv7k-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7s:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7s-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumbv7s-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7m:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7m-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumbv7m-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7em:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7em-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumbv7em-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("thumbv7-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 10: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 11: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv6m:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv6m-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 8: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 9: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv6:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv6-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("thumbv6-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 6: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 7: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv5:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv5-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("thumbv5-apple-" OSNAME); return true;
- case 4: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 5: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv4:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv4-apple-" OSNAME); return true;
- case 1: arch.SetTriple ("arm-apple-" OSNAME); return true;
- case 2: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true;
- case 3: arch.SetTriple ("thumb-apple-" OSNAME); return true;
- default: break;
- }
- break;
+ break;
}
- arch.Clear();
- return false;
+ break;
+
+ case ArchSpec::eCore_arm_arm64:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("arm64-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv7s-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv7f-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv7m-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv7em-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 12:
+ arch.SetTriple("thumbv7f-apple-" OSNAME);
+ return true;
+ case 13:
+ arch.SetTriple("thumbv7k-apple-" OSNAME);
+ return true;
+ case 14:
+ arch.SetTriple("thumbv7s-apple-" OSNAME);
+ return true;
+ case 15:
+ arch.SetTriple("thumbv7m-apple-" OSNAME);
+ return true;
+ case 16:
+ arch.SetTriple("thumbv7em-apple-" OSNAME);
+ return true;
+ case 17:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 18:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 19:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 20:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 21:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7f:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7f-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumbv7f-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 12:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 13:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7k:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7k-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumbv7k-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 12:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 13:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7s:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7s-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumbv7s-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 12:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 13:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7m:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7m-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumbv7m-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 12:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 13:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7em:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7em-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumbv7em-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 12:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 13:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("thumbv7-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 10:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 11:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv6m:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv6m-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("thumbv6m-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 8:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 9:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv6:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv6-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("thumbv6-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 6:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 7:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv5:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv5-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("thumbv5-apple-" OSNAME);
+ return true;
+ case 4:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 5:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv4:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv4-apple-" OSNAME);
+ return true;
+ case 1:
+ arch.SetTriple("arm-apple-" OSNAME);
+ return true;
+ case 2:
+ arch.SetTriple("thumbv4t-apple-" OSNAME);
+ return true;
+ case 3:
+ arch.SetTriple("thumb-apple-" OSNAME);
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ arch.Clear();
+ return false;
}
-
-const char *
-PlatformDarwin::GetDeveloperDirectory()
-{
- std::lock_guard<std::mutex> guard(m_mutex);
- if (m_developer_directory.empty())
- {
- bool developer_dir_path_valid = false;
- char developer_dir_path[PATH_MAX];
- FileSpec temp_file_spec;
- if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec))
- {
- if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path)))
- {
- char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework");
- if (shared_frameworks)
- {
- ::snprintf (shared_frameworks,
- sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path),
- "/Developer");
- developer_dir_path_valid = true;
- }
- else
- {
- char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework");
- if (lib_priv_frameworks)
- {
- *lib_priv_frameworks = '\0';
- developer_dir_path_valid = true;
- }
- }
- }
- }
-
- if (!developer_dir_path_valid)
- {
- std::string xcode_dir_path;
- const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR");
- 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.c_str(), false);
- size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL);
- if (bytes_read > 0)
- {
- developer_dir_path[bytes_read] = '\0';
- while (developer_dir_path[bytes_read-1] == '\r' ||
- developer_dir_path[bytes_read-1] == '\n')
- developer_dir_path[--bytes_read] = '\0';
- developer_dir_path_valid = true;
- }
- }
-
- if (!developer_dir_path_valid)
- {
- FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false);
- if (xcode_select_cmd.Exists())
- {
- int exit_status = -1;
- int signo = -1;
- std::string command_output;
- Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path",
- NULL, // current working directory
- &exit_status,
- &signo,
- &command_output,
- 2, // short timeout
- false); // don't run in a shell
- if (error.Success() && exit_status == 0 && !command_output.empty())
- {
- const char *cmd_output_ptr = command_output.c_str();
- developer_dir_path[sizeof (developer_dir_path) - 1] = '\0';
- size_t i;
- for (i = 0; i < sizeof (developer_dir_path) - 1; i++)
- {
- if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0')
- break;
- developer_dir_path[i] = cmd_output_ptr[i];
- }
- developer_dir_path[i] = '\0';
-
- FileSpec devel_dir (developer_dir_path, false);
- if (devel_dir.Exists() && devel_dir.IsDirectory())
- {
- developer_dir_path_valid = true;
- }
- }
- }
- }
-
- if (developer_dir_path_valid)
- {
- temp_file_spec.SetFile (developer_dir_path, false);
- if (temp_file_spec.Exists())
- {
- m_developer_directory.assign (developer_dir_path);
- return m_developer_directory.c_str();
- }
+const char *PlatformDarwin::GetDeveloperDirectory() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ if (m_developer_directory.empty()) {
+ bool developer_dir_path_valid = false;
+ char developer_dir_path[PATH_MAX];
+ FileSpec temp_file_spec;
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec)) {
+ if (temp_file_spec.GetPath(developer_dir_path,
+ sizeof(developer_dir_path))) {
+ char *shared_frameworks =
+ strstr(developer_dir_path, "/SharedFrameworks/LLDB.framework");
+ if (shared_frameworks) {
+ ::snprintf(shared_frameworks,
+ sizeof(developer_dir_path) -
+ (shared_frameworks - developer_dir_path),
+ "/Developer");
+ developer_dir_path_valid = true;
+ } else {
+ char *lib_priv_frameworks = strstr(
+ developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework");
+ if (lib_priv_frameworks) {
+ *lib_priv_frameworks = '\0';
+ developer_dir_path_valid = true;
+ }
}
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_developer_directory.assign (1, '\0');
+ }
}
-
- // We should have put a single NULL character into m_developer_directory
- // or it should have a valid path if the code gets here
- assert (m_developer_directory.empty() == false);
- if (m_developer_directory[0])
- return m_developer_directory.c_str();
- return NULL;
-}
+ if (!developer_dir_path_valid) {
+ std::string xcode_dir_path;
+ const char *xcode_select_prefix_dir = getenv("XCODE_SELECT_PREFIX_DIR");
+ 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);
+ size_t bytes_read = temp_file_spec.ReadFileContents(
+ 0, developer_dir_path, sizeof(developer_dir_path), NULL);
+ if (bytes_read > 0) {
+ developer_dir_path[bytes_read] = '\0';
+ while (developer_dir_path[bytes_read - 1] == '\r' ||
+ developer_dir_path[bytes_read - 1] == '\n')
+ developer_dir_path[--bytes_read] = '\0';
+ developer_dir_path_valid = true;
+ }
+ }
-BreakpointSP
-PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
-{
- BreakpointSP bp_sp;
- static const char *g_bp_names[] =
- {
- "start_wqthread",
- "_pthread_wqthread",
- "_pthread_start",
- };
-
- static const char *g_bp_modules[] =
- {
- "libsystem_c.dylib",
- "libSystem.B.dylib"
- };
-
- 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));
+ if (!developer_dir_path_valid) {
+ FileSpec xcode_select_cmd("/usr/bin/xcode-select", false);
+ if (xcode_select_cmd.Exists()) {
+ int exit_status = -1;
+ int signo = -1;
+ std::string command_output;
+ Error error =
+ Host::RunShellCommand("/usr/bin/xcode-select --print-path",
+ NULL, // current working directory
+ &exit_status, &signo, &command_output,
+ 2, // short timeout
+ false); // don't run in a shell
+ if (error.Success() && exit_status == 0 && !command_output.empty()) {
+ const char *cmd_output_ptr = command_output.c_str();
+ developer_dir_path[sizeof(developer_dir_path) - 1] = '\0';
+ size_t i;
+ for (i = 0; i < sizeof(developer_dir_path) - 1; i++) {
+ if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' ||
+ cmd_output_ptr[i] == '\0')
+ break;
+ developer_dir_path[i] = cmd_output_ptr[i];
+ }
+ developer_dir_path[i] = '\0';
+
+ FileSpec devel_dir(developer_dir_path, false);
+ if (devel_dir.Exists() && devel_dir.IsDirectory()) {
+ developer_dir_path_valid = true;
+ }
+ }
+ }
}
- bool internal = true;
- bool hardware = false;
- LazyBool skip_prologue = eLazyBoolNo;
- bp_sp = target.CreateBreakpoint (&bp_modules,
- NULL,
- g_bp_names,
- llvm::array_lengthof(g_bp_names),
- eFunctionNameTypeFull,
- eLanguageTypeUnknown,
- 0,
- skip_prologue,
- internal,
- hardware);
- bp_sp->SetBreakpointKind("thread-creation");
-
- return bp_sp;
+ if (developer_dir_path_valid) {
+ temp_file_spec.SetFile(developer_dir_path, false);
+ if (temp_file_spec.Exists()) {
+ m_developer_directory.assign(developer_dir_path);
+ return m_developer_directory.c_str();
+ }
+ }
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_developer_directory.assign(1, '\0');
+ }
+
+ // We should have put a single NULL character into m_developer_directory
+ // or it should have a valid path if the code gets here
+ assert(m_developer_directory.empty() == false);
+ if (m_developer_directory[0])
+ return m_developer_directory.c_str();
+ return NULL;
}
+BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) {
+ BreakpointSP bp_sp;
+ static const char *g_bp_names[] = {
+ "start_wqthread", "_pthread_wqthread", "_pthread_start",
+ };
+
+ static const char *g_bp_modules[] = {"libsystem_c.dylib",
+ "libSystem.B.dylib"};
+
+ 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));
+ }
+
+ bool internal = true;
+ bool hardware = false;
+ LazyBool skip_prologue = eLazyBoolNo;
+ bp_sp = target.CreateBreakpoint(&bp_modules, NULL, g_bp_names,
+ llvm::array_lengthof(g_bp_names),
+ eFunctionNameTypeFull, eLanguageTypeUnknown,
+ 0, skip_prologue, internal, hardware);
+ bp_sp->SetBreakpointKind("thread-creation");
+
+ return bp_sp;
+}
int32_t
-PlatformDarwin::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
-{
- const FileSpec &shell = launch_info.GetShell();
- if (!shell)
- return 1;
-
- std::string shell_string = shell.GetPath();
- const char *shell_name = strrchr (shell_string.c_str(), '/');
- if (shell_name == NULL)
- shell_name = shell_string.c_str();
- else
- shell_name++;
-
- if (strcmp (shell_name, "sh") == 0)
- {
- // /bin/sh re-exec's itself as /bin/bash requiring another resume.
- // But it only does this if the COMMAND_MODE environment variable
- // is set to "legacy".
- const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
- if (envp != NULL)
- {
- for (int i = 0; envp[i] != NULL; i++)
- {
- if (strcmp (envp[i], "COMMAND_MODE=legacy" ) == 0)
- return 2;
- }
- }
- return 1;
+PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
+ const FileSpec &shell = launch_info.GetShell();
+ if (!shell)
+ return 1;
+
+ std::string shell_string = shell.GetPath();
+ const char *shell_name = strrchr(shell_string.c_str(), '/');
+ if (shell_name == NULL)
+ shell_name = shell_string.c_str();
+ else
+ shell_name++;
+
+ if (strcmp(shell_name, "sh") == 0) {
+ // /bin/sh re-exec's itself as /bin/bash requiring another resume.
+ // But it only does this if the COMMAND_MODE environment variable
+ // is set to "legacy".
+ const char **envp =
+ launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+ if (envp != NULL) {
+ for (int i = 0; envp[i] != NULL; i++) {
+ if (strcmp(envp[i], "COMMAND_MODE=legacy") == 0)
+ return 2;
+ }
}
- else if (strcmp (shell_name, "csh") == 0
- || strcmp (shell_name, "tcsh") == 0
- || strcmp (shell_name, "zsh") == 0)
- {
- // csh and tcsh always seem to re-exec themselves.
- return 2;
- }
- else
- return 1;
+ return 1;
+ } else if (strcmp(shell_name, "csh") == 0 ||
+ strcmp(shell_name, "tcsh") == 0 ||
+ strcmp(shell_name, "zsh") == 0) {
+ // csh and tcsh always seem to re-exec themselves.
+ return 2;
+ } else
+ return 1;
}
-void
-PlatformDarwin::CalculateTrapHandlerSymbolNames ()
-{
- m_trap_handlers.push_back (ConstString ("_sigtramp"));
+void PlatformDarwin::CalculateTrapHandlerSymbolNames() {
+ m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-
static const char *const sdk_strings[] = {
- "MacOSX",
- "iPhoneSimulator",
- "iPhoneOS",
+ "MacOSX", "iPhoneSimulator", "iPhoneOS",
};
-static FileSpec
-CheckPathForXcode(const FileSpec &fspec)
-{
- if (fspec.Exists())
- {
- 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.c_str(), false);
-
- FileSpec xcode_binary_path = ret;
- xcode_binary_path.AppendPathComponent("MacOS");
- xcode_binary_path.AppendPathComponent("Xcode");
-
- if (xcode_binary_path.Exists())
- {
- return ret;
- }
- }
+static FileSpec CheckPathForXcode(const FileSpec &fspec) {
+ if (fspec.Exists()) {
+ 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 xcode_binary_path = ret;
+ xcode_binary_path.AppendPathComponent("MacOS");
+ xcode_binary_path.AppendPathComponent("Xcode");
+
+ if (xcode_binary_path.Exists()) {
+ return ret;
+ }
}
- return FileSpec();
+ }
+ return FileSpec();
}
-static FileSpec
-GetXcodeContentsPath ()
-{
- static FileSpec g_xcode_filespec;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
-
-
- FileSpec fspec;
-
- // First get the program file spec. If lldb.so or LLDB.framework is running
- // in a program and that program is Xcode, the path returned with be the path
- // to Xcode.app/Contents/MacOS/Xcode, so this will be the correct Xcode to use.
- fspec = HostInfo::GetProgramFileSpec();
-
- if (fspec)
- {
- // Ignore the current binary if it is python.
- std::string basename_lower = fspec.GetFilename ().GetCString ();
- std::transform(basename_lower.begin (), basename_lower.end (), basename_lower.begin (), tolower);
- if (basename_lower != "python")
- {
- g_xcode_filespec = CheckPathForXcode(fspec);
- }
- }
-
- // Next check DEVELOPER_DIR environment variable
- 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));
- }
+static FileSpec GetXcodeContentsPath() {
+ static FileSpec g_xcode_filespec;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+
+ FileSpec fspec;
+
+ // First get the program file spec. If lldb.so or LLDB.framework is running
+ // in a program and that program is Xcode, the path returned with be the
+ // path
+ // to Xcode.app/Contents/MacOS/Xcode, so this will be the correct Xcode to
+ // use.
+ fspec = HostInfo::GetProgramFileSpec();
+
+ if (fspec) {
+ // Ignore the current binary if it is python.
+ std::string basename_lower = fspec.GetFilename().GetCString();
+ std::transform(basename_lower.begin(), basename_lower.end(),
+ basename_lower.begin(), tolower);
+ if (basename_lower != "python") {
+ g_xcode_filespec = CheckPathForXcode(fspec);
+ }
+ }
- // Fall back to using "xcrun" to find the selected Xcode
- if (!g_xcode_filespec)
- {
- int status = 0;
- int signo = 0;
- std::string output;
- const char *command = "/usr/bin/xcode-select -p";
- lldb_private::Error error = Host::RunShellCommand (command, // shell command to run
- NULL, // current working directory
- &status, // Put the exit status of the process in here
- &signo, // Put the signal that caused the process to exit in here
- &output, // Get the output from the command and place it in this string
- 3); // Timeout in seconds to wait for shell program to finish
- if (status == 0 && !output.empty())
- {
- size_t first_non_newline = output.find_last_not_of("\r\n");
- if (first_non_newline != std::string::npos)
- {
- output.erase(first_non_newline+1);
- }
- output.append("/..");
-
- g_xcode_filespec = CheckPathForXcode(FileSpec(output.c_str(), false));
- }
- }
+ // Next check DEVELOPER_DIR environment variable
+ 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));
+ }
+
+ // Fall back to using "xcrun" to find the selected Xcode
+ if (!g_xcode_filespec) {
+ int status = 0;
+ int signo = 0;
+ std::string output;
+ const char *command = "/usr/bin/xcode-select -p";
+ lldb_private::Error error = Host::RunShellCommand(
+ command, // shell command to run
+ NULL, // current working directory
+ &status, // Put the exit status of the process in here
+ &signo, // Put the signal that caused the process to exit in here
+ &output, // Get the output from the command and place it in this
+ // string
+ 3); // Timeout in seconds to wait for shell program to finish
+ if (status == 0 && !output.empty()) {
+ size_t first_non_newline = output.find_last_not_of("\r\n");
+ if (first_non_newline != std::string::npos) {
+ output.erase(first_non_newline + 1);
+ }
+ output.append("/..");
+
+ g_xcode_filespec = CheckPathForXcode(FileSpec(output, false));
}
- });
-
- return g_xcode_filespec;
+ }
+ }
+ });
+
+ return g_xcode_filespec;
}
-bool
-PlatformDarwin::SDKSupportsModules (SDKType sdk_type, uint32_t major, uint32_t minor, uint32_t micro)
-{
- switch (sdk_type)
- {
- case SDKType::MacOSX:
- if (major > 10 || (major == 10 && minor >= 10))
- return true;
- break;
- case SDKType::iPhoneOS:
- case SDKType::iPhoneSimulator:
- if (major >= 8)
- return true;
- break;
- }
-
- return false;
+bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type, uint32_t major,
+ uint32_t minor, uint32_t micro) {
+ switch (sdk_type) {
+ case SDKType::MacOSX:
+ if (major > 10 || (major == 10 && minor >= 10))
+ return true;
+ break;
+ case SDKType::iPhoneOS:
+ case SDKType::iPhoneSimulator:
+ if (major >= 8)
+ return true;
+ break;
+ }
+
+ return false;
}
-bool
-PlatformDarwin::SDKSupportsModules (SDKType desired_type, const FileSpec &sdk_path)
-{
- ConstString last_path_component = sdk_path.GetLastPathComponent();
-
- 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
- {
- return false;
- }
-
- const size_t major_dot_offset = version_part.find('.');
- if (major_dot_offset == llvm::StringRef::npos)
- return false;
-
- const llvm::StringRef major_version = version_part.slice(0, major_dot_offset);
- const llvm::StringRef minor_part = version_part.drop_front(major_dot_offset + 1);
-
- const size_t minor_dot_offset = minor_part.find('.');
- if (minor_dot_offset == llvm::StringRef::npos)
- return false;
-
- const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset);
-
- unsigned int major = 0;
- unsigned int minor = 0;
- unsigned int micro = 0;
-
- if (major_version.getAsInteger(10, major))
- return false;
-
- if (minor_version.getAsInteger(10, minor))
- return false;
-
- return SDKSupportsModules(desired_type, major, minor, micro);
+bool PlatformDarwin::SDKSupportsModules(SDKType desired_type,
+ const FileSpec &sdk_path) {
+ ConstString last_path_component = sdk_path.GetLastPathComponent();
+
+ 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 {
+ return false;
}
-
- return false;
+
+ const size_t major_dot_offset = version_part.find('.');
+ if (major_dot_offset == llvm::StringRef::npos)
+ return false;
+
+ const llvm::StringRef major_version =
+ version_part.slice(0, major_dot_offset);
+ const llvm::StringRef minor_part =
+ version_part.drop_front(major_dot_offset + 1);
+
+ const size_t minor_dot_offset = minor_part.find('.');
+ if (minor_dot_offset == llvm::StringRef::npos)
+ return false;
+
+ const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset);
+
+ unsigned int major = 0;
+ unsigned int minor = 0;
+ unsigned int micro = 0;
+
+ if (major_version.getAsInteger(10, major))
+ return false;
+
+ if (minor_version.getAsInteger(10, minor))
+ return false;
+
+ return SDKSupportsModules(desired_type, major, minor, micro);
+ }
+
+ return false;
}
FileSpec::EnumerateDirectoryResult
-PlatformDarwin::DirectoryEnumerator(void *baton,
- FileSpec::FileType file_type,
- const FileSpec &spec)
-{
- SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo*>(baton);
-
- if (SDKSupportsModules(enumerator_info->sdk_type, spec))
- {
- enumerator_info->found_path = spec;
- return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
- }
-
+PlatformDarwin::DirectoryEnumerator(void *baton, FileSpec::FileType file_type,
+ const FileSpec &spec) {
+ SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);
+
+ if (SDKSupportsModules(enumerator_info->sdk_type, spec)) {
+ enumerator_info->found_path = spec;
return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
+ }
+
+ return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
}
-FileSpec
-PlatformDarwin::FindSDKInXcodeForModules (SDKType sdk_type,
- const FileSpec &sdks_spec)
-{
- // Look inside Xcode for the required installed iOS SDK version
-
- if (!sdks_spec.IsDirectory())
- return FileSpec();
-
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = true; // include symlinks
-
- SDKEnumeratorInfo enumerator_info;
-
- enumerator_info.sdk_type = sdk_type;
-
- FileSpec::EnumerateDirectory(sdks_spec.GetPath().c_str(),
- find_directories,
- find_files,
- find_other,
- DirectoryEnumerator,
- &enumerator_info);
-
- if (enumerator_info.found_path.IsDirectory())
- return enumerator_info.found_path;
- else
- return FileSpec();
+FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type,
+ const FileSpec &sdks_spec) {
+ // Look inside Xcode for the required installed iOS SDK version
+
+ if (!sdks_spec.IsDirectory())
+ return FileSpec();
+
+ const bool find_directories = true;
+ const bool find_files = false;
+ const bool find_other = true; // include symlinks
+
+ SDKEnumeratorInfo enumerator_info;
+
+ enumerator_info.sdk_type = sdk_type;
+
+ FileSpec::EnumerateDirectory(sdks_spec.GetPath(), find_directories,
+ find_files, find_other, DirectoryEnumerator,
+ &enumerator_info);
+
+ if (enumerator_info.found_path.IsDirectory())
+ return enumerator_info.found_path;
+ else
+ return FileSpec();
}
-FileSpec
-PlatformDarwin::GetSDKDirectoryForModules (SDKType sdk_type)
-{
- switch (sdk_type)
- {
- case SDKType::MacOSX:
- case SDKType::iPhoneSimulator:
- case SDKType::iPhoneOS:
- break;
- }
-
- FileSpec sdks_spec = GetXcodeContentsPath();
- sdks_spec.AppendPathComponent("Developer");
- sdks_spec.AppendPathComponent("Platforms");
-
- switch (sdk_type)
- {
- case SDKType::MacOSX:
- sdks_spec.AppendPathComponent("MacOSX.platform");
- break;
- case SDKType::iPhoneSimulator:
- sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
- break;
- case SDKType::iPhoneOS:
- sdks_spec.AppendPathComponent("iPhoneOS.platform");
- break;
- }
-
- sdks_spec.AppendPathComponent("Developer");
- sdks_spec.AppendPathComponent("SDKs");
-
- if (sdk_type == SDKType::MacOSX)
- {
- uint32_t major = 0;
- uint32_t minor = 0;
- uint32_t micro = 0;
-
- if (HostInfo::GetOSVersion(major, minor, micro))
- {
- if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro))
- {
- // We slightly prefer the exact SDK for this machine. See if it is there.
-
- FileSpec native_sdk_spec = sdks_spec;
- StreamString native_sdk_name;
- native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor);
- native_sdk_spec.AppendPathComponent(native_sdk_name.GetString().c_str());
-
- if (native_sdk_spec.Exists())
- {
- return native_sdk_spec;
- }
- }
+FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
+ switch (sdk_type) {
+ case SDKType::MacOSX:
+ case SDKType::iPhoneSimulator:
+ case SDKType::iPhoneOS:
+ break;
+ }
+
+ FileSpec sdks_spec = GetXcodeContentsPath();
+ sdks_spec.AppendPathComponent("Developer");
+ sdks_spec.AppendPathComponent("Platforms");
+
+ switch (sdk_type) {
+ case SDKType::MacOSX:
+ sdks_spec.AppendPathComponent("MacOSX.platform");
+ break;
+ case SDKType::iPhoneSimulator:
+ sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
+ break;
+ case SDKType::iPhoneOS:
+ sdks_spec.AppendPathComponent("iPhoneOS.platform");
+ break;
+ }
+
+ sdks_spec.AppendPathComponent("Developer");
+ sdks_spec.AppendPathComponent("SDKs");
+
+ if (sdk_type == SDKType::MacOSX) {
+ uint32_t major = 0;
+ uint32_t minor = 0;
+ uint32_t micro = 0;
+
+ if (HostInfo::GetOSVersion(major, minor, micro)) {
+ if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro)) {
+ // We slightly prefer the exact SDK for this machine. See if it is
+ // there.
+
+ FileSpec native_sdk_spec = sdks_spec;
+ StreamString native_sdk_name;
+ native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor);
+ native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
+
+ if (native_sdk_spec.Exists()) {
+ return native_sdk_spec;
}
+ }
}
-
- return FindSDKInXcodeForModules(sdk_type, sdks_spec);
+ }
+
+ return FindSDKInXcodeForModules(sdk_type, sdks_spec);
+}
+
+std::tuple<uint32_t, uint32_t, uint32_t, llvm::StringRef>
+PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
+ uint32_t major, minor, update;
+ llvm::StringRef build;
+ llvm::StringRef version_str;
+ llvm::StringRef build_str;
+ std::tie(version_str, build_str) = dir.split(' ');
+ if (Args::StringToVersion(version_str, major, minor, update) ||
+ build_str.empty()) {
+ if (build_str.consume_front("(")) {
+ size_t pos = build_str.find(')');
+ build = build_str.slice(0, pos);
+ }
+ }
+
+ return std::make_tuple(major, minor, update, build);
}
-void
-PlatformDarwin::AddClangModuleCompilationOptionsForSDKType (Target *target, std::vector<std::string> &options, SDKType sdk_type)
-{
- const std::vector<std::string> apple_arguments =
- {
- "-x", "objective-c++",
- "-fobjc-arc",
- "-fblocks",
- "-D_ISO646_H",
- "-D__ISO646_H"
- };
-
- options.insert(options.end(),
- apple_arguments.begin(),
- apple_arguments.end());
-
- StreamString minimum_version_option;
- uint32_t versions[3] = { 0, 0, 0 };
- bool use_current_os_version = false;
- switch (sdk_type)
- {
- case SDKType::iPhoneOS:
-#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
- use_current_os_version = true;
+void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ Target *target, std::vector<std::string> &options, SDKType sdk_type) {
+ const std::vector<std::string> apple_arguments = {
+ "-x", "objective-c++", "-fobjc-arc",
+ "-fblocks", "-D_ISO646_H", "-D__ISO646_H"};
+
+ options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
+
+ StreamString minimum_version_option;
+ uint32_t versions[3] = {0, 0, 0};
+ bool use_current_os_version = false;
+ switch (sdk_type) {
+ case SDKType::iPhoneOS:
+#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ use_current_os_version = true;
#else
- use_current_os_version = false;
+ use_current_os_version = false;
#endif
- break;
+ break;
- case SDKType::iPhoneSimulator:
- use_current_os_version = false;
- break;
+ case SDKType::iPhoneSimulator:
+ use_current_os_version = false;
+ break;
- case SDKType::MacOSX:
-#if defined (__i386__) || defined (__x86_64__)
- use_current_os_version = true;
+ case SDKType::MacOSX:
+#if defined(__i386__) || defined(__x86_64__)
+ use_current_os_version = true;
#else
- use_current_os_version = false;
+ use_current_os_version = false;
#endif
- break;
+ break;
+ }
+
+ bool versions_valid = false;
+ if (use_current_os_version)
+ versions_valid = GetOSVersion(versions[0], versions[1], versions[2]);
+ else if (target) {
+ // Our OS doesn't match our executable so we need to get the min OS version
+ // from the object file
+ ModuleSP exe_module_sp = target->GetExecutableModule();
+ if (exe_module_sp) {
+ ObjectFile *object_file = exe_module_sp->GetObjectFile();
+ if (object_file)
+ versions_valid = object_file->GetMinimumOSVersion(versions, 3) > 0;
}
-
- bool versions_valid = false;
- if (use_current_os_version)
- versions_valid = GetOSVersion(versions[0], versions[1], versions[2]);
- else if (target)
- {
- // Our OS doesn't match our executable so we need to get the min OS version from the object file
- ModuleSP exe_module_sp = target->GetExecutableModule();
- if (exe_module_sp)
- {
- ObjectFile *object_file = exe_module_sp->GetObjectFile();
- if (object_file)
- versions_valid = object_file->GetMinimumOSVersion(versions, 3) > 0;
- }
- }
- // Only add the version-min options if we got a version from somewhere
- if (versions_valid && versions[0] != UINT32_MAX)
- {
- // Make any invalid versions be zero if needed
- if (versions[1] == UINT32_MAX)
- versions[1] = 0;
- if (versions[2] == UINT32_MAX)
- versions[2] = 0;
-
- switch (sdk_type)
- {
- case SDKType::iPhoneOS:
- minimum_version_option.PutCString("-mios-version-min=");
- minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str());
- break;
- case SDKType::iPhoneSimulator:
- minimum_version_option.PutCString("-mios-simulator-version-min=");
- minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str());
- break;
- case SDKType::MacOSX:
- minimum_version_option.PutCString("-mmacosx-version-min=");
- minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str());
- }
- options.push_back(minimum_version_option.GetString());
+ }
+ // Only add the version-min options if we got a version from somewhere
+ if (versions_valid && versions[0] != UINT32_MAX) {
+ // Make any invalid versions be zero if needed
+ if (versions[1] == UINT32_MAX)
+ versions[1] = 0;
+ if (versions[2] == UINT32_MAX)
+ versions[2] = 0;
+
+ switch (sdk_type) {
+ case SDKType::iPhoneOS:
+ minimum_version_option.PutCString("-mios-version-min=");
+ minimum_version_option.PutCString(
+ clang::VersionTuple(versions[0], versions[1], versions[2])
+ .getAsString());
+ break;
+ case SDKType::iPhoneSimulator:
+ minimum_version_option.PutCString("-mios-simulator-version-min=");
+ minimum_version_option.PutCString(
+ clang::VersionTuple(versions[0], versions[1], versions[2])
+ .getAsString());
+ break;
+ case SDKType::MacOSX:
+ minimum_version_option.PutCString("-mmacosx-version-min=");
+ minimum_version_option.PutCString(
+ clang::VersionTuple(versions[0], versions[1], versions[2])
+ .getAsString());
}
+ options.push_back(minimum_version_option.GetString());
+ }
- FileSpec sysroot_spec;
- // Scope for mutex locker below
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- sysroot_spec = GetSDKDirectoryForModules(sdk_type);
- }
+ FileSpec sysroot_spec;
+ // Scope for mutex locker below
+ {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ sysroot_spec = GetSDKDirectoryForModules(sdk_type);
+ }
- if (sysroot_spec.IsDirectory())
- {
- options.push_back("-isysroot");
- options.push_back(sysroot_spec.GetPath());
- }
+ if (sysroot_spec.IsDirectory()) {
+ options.push_back("-isysroot");
+ options.push_back(sysroot_spec.GetPath());
+ }
}
-ConstString
-PlatformDarwin::GetFullNameForDylib (ConstString basename)
-{
- if (basename.IsEmpty())
- return basename;
-
- StreamString stream;
- stream.Printf("lib%s.dylib", basename.GetCString());
- return ConstString(stream.GetData());
-}
+ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) {
+ if (basename.IsEmpty())
+ return basename;
-bool
-PlatformDarwin::GetOSVersion (uint32_t &major,
- uint32_t &minor,
- uint32_t &update,
- Process *process)
-{
- if (process && strstr(GetPluginName().GetCString(), "-simulator"))
- {
- lldb_private::ProcessInstanceInfo proc_info;
- if (Host::GetProcessInfo(process->GetID(), proc_info))
- {
- Args &env = proc_info.GetEnvironmentEntries();
- const size_t n = env.GetArgumentCount();
- const llvm::StringRef k_runtime_version("SIMULATOR_RUNTIME_VERSION=");
- const llvm::StringRef k_dyld_root_path("DYLD_ROOT_PATH=");
- std::string dyld_root_path;
-
- for (size_t i=0; i<n; ++i)
- {
- const char *env_cstr = env.GetArgumentAtIndex(i);
- if (env_cstr)
- {
- llvm::StringRef env_str(env_cstr);
- if (env_str.startswith(k_runtime_version))
- {
- llvm::StringRef version_str(env_str.substr(k_runtime_version.size()));
- Args::StringToVersion (version_str.data(), major, minor, update);
- if (major != UINT32_MAX)
- return true;
- }
- else if (env_str.startswith(k_dyld_root_path))
- {
- dyld_root_path = env_str.substr(k_dyld_root_path.size()).str();
- }
- }
- }
-
- if (!dyld_root_path.empty())
- {
- dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
- ApplePropertyList system_version_plist(dyld_root_path.c_str());
- std::string product_version;
- if (system_version_plist.GetValueAsString("ProductVersion", product_version))
- {
- Args::StringToVersion (product_version.c_str(), major, minor, update);
- return major != UINT32_MAX;
- }
- }
+ StreamString stream;
+ stream.Printf("lib%s.dylib", basename.GetCString());
+ return ConstString(stream.GetString());
+}
+bool PlatformDarwin::GetOSVersion(uint32_t &major, uint32_t &minor,
+ uint32_t &update, Process *process) {
+ if (process && strstr(GetPluginName().GetCString(), "-simulator")) {
+ lldb_private::ProcessInstanceInfo proc_info;
+ if (Host::GetProcessInfo(process->GetID(), proc_info)) {
+ Args &env = proc_info.GetEnvironmentEntries();
+ const size_t n = env.GetArgumentCount();
+ const llvm::StringRef k_runtime_version("SIMULATOR_RUNTIME_VERSION=");
+ const llvm::StringRef k_dyld_root_path("DYLD_ROOT_PATH=");
+ std::string dyld_root_path;
+
+ for (size_t i = 0; i < n; ++i) {
+ const char *env_cstr = env.GetArgumentAtIndex(i);
+ if (env_cstr) {
+ llvm::StringRef env_str(env_cstr);
+ if (env_str.consume_front(k_runtime_version)) {
+ if (Args::StringToVersion(env_str, major, minor, update))
+ return true;
+ } else if (env_str.consume_front(k_dyld_root_path)) {
+ dyld_root_path = env_str;
+ }
+ }
+ }
+
+ if (!dyld_root_path.empty()) {
+ dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
+ ApplePropertyList system_version_plist(dyld_root_path.c_str());
+ std::string product_version;
+ if (system_version_plist.GetValueAsString("ProductVersion",
+ product_version)) {
+ return Args::StringToVersion(product_version, major, minor, update);
}
- // For simulator platforms, do NOT call back through Platform::GetOSVersion()
- // as it might call Process::GetHostOSVersion() which we don't want as it will be
- // incorrect
- return false;
+ }
}
+ // For simulator platforms, do NOT call back through
+ // Platform::GetOSVersion()
+ // as it might call Process::GetHostOSVersion() which we don't want as it
+ // will be
+ // incorrect
+ return false;
+ }
- return Platform::GetOSVersion(major, minor, update, process);
+ return Platform::GetOSVersion(major, minor, update, process);
}
-lldb_private::FileSpec
-PlatformDarwin::LocateExecutable (const char *basename)
-{
- // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled in with
- // any executable directories that should be searched.
- static std::vector<FileSpec> g_executable_dirs;
-
- // Find the global list of directories that we will search for
- // executables once so we don't keep doing the work over and over.
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
-
- // When locating executables, trust the DEVELOPER_DIR first if it is set
- FileSpec xcode_contents_dir = GetXcodeContentsPath();
- if (xcode_contents_dir)
- {
- FileSpec xcode_lldb_resources = xcode_contents_dir;
- xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
- xcode_lldb_resources.AppendPathComponent("LLDB.framework");
- xcode_lldb_resources.AppendPathComponent("Resources");
- if (xcode_lldb_resources.Exists())
- {
- FileSpec dir;
- dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
- g_executable_dirs.push_back(dir);
- }
- }
- });
-
- // Now search the global list of executable directories for the executable we
- // are looking for
- for (const auto &executable_dir : g_executable_dirs)
- {
- FileSpec executable_file;
- executable_file.GetDirectory() = executable_dir.GetDirectory();
- executable_file.GetFilename().SetCString(basename);
- if (executable_file.Exists())
- return executable_file;
+lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
+ // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled
+ // in with
+ // any executable directories that should be searched.
+ static std::vector<FileSpec> g_executable_dirs;
+
+ // Find the global list of directories that we will search for
+ // executables once so we don't keep doing the work over and over.
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+
+ // When locating executables, trust the DEVELOPER_DIR first if it is set
+ FileSpec xcode_contents_dir = GetXcodeContentsPath();
+ if (xcode_contents_dir) {
+ FileSpec xcode_lldb_resources = xcode_contents_dir;
+ xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
+ xcode_lldb_resources.AppendPathComponent("LLDB.framework");
+ xcode_lldb_resources.AppendPathComponent("Resources");
+ if (xcode_lldb_resources.Exists()) {
+ FileSpec dir;
+ dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
+ g_executable_dirs.push_back(dir);
+ }
}
-
- return FileSpec();
+ });
+
+ // Now search the global list of executable directories for the executable we
+ // are looking for
+ for (const auto &executable_dir : g_executable_dirs) {
+ FileSpec executable_file;
+ executable_file.GetDirectory() = executable_dir.GetDirectory();
+ executable_file.GetFilename().SetCString(basename);
+ if (executable_file.Exists())
+ return executable_file;
+ }
+
+ return FileSpec();
}
lldb_private::Error
-PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info)
-{
- // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr
- // if the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't
- // require any specific value; rather, it just needs to exist).
- // We will set it here as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag
- // is not set. Xcode makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
- // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
- // specifically want it unset.
- const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
- auto &env_vars = launch_info.GetEnvironmentEntries();
- if (!env_vars.ContainsEnvironmentVariable(disable_env_var))
- {
- // We want to make sure that OS_ACTIVITY_DT_MODE is set so that
- // we get os_log and NSLog messages mirrored to the target process
- // stderr.
- if (!env_vars.ContainsEnvironmentVariable("OS_ACTIVITY_DT_MODE"))
- env_vars.AppendArgument("OS_ACTIVITY_DT_MODE=enable");
- }
-
- // Let our parent class do the real launching.
- return PlatformPOSIX::LaunchProcess(launch_info);
+PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) {
+ // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr
+ // if the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't
+ // require any specific value; rather, it just needs to exist).
+ // We will set it here as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag
+ // is not set. Xcode makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
+ // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
+ // specifically want it unset.
+ const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
+ auto &env_vars = launch_info.GetEnvironmentEntries();
+ if (!env_vars.ContainsEnvironmentVariable(llvm::StringRef(disable_env_var))) {
+ // We want to make sure that OS_ACTIVITY_DT_MODE is set so that
+ // we get os_log and NSLog messages mirrored to the target process
+ // stderr.
+ if (!env_vars.ContainsEnvironmentVariable(
+ llvm::StringRef("OS_ACTIVITY_DT_MODE")))
+ env_vars.AppendArgument(llvm::StringRef("OS_ACTIVITY_DT_MODE=enable"));
+ }
+
+ // Let our parent class do the real launching.
+ return PlatformPOSIX::LaunchProcess(launch_info);
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index faecf4cc5a24..2abff92fa906 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -12,148 +12,138 @@
// C Includes
// C++ Includes
-#include <string>
// Other libraries and framework includes
// Project includes
-#include "lldb/Host/FileSpec.h"
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
+#include "lldb/Host/FileSpec.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <string>
+#include <tuple>
-class PlatformDarwin : public PlatformPOSIX
-{
+class PlatformDarwin : public PlatformPOSIX {
public:
- PlatformDarwin(bool is_host);
-
- ~PlatformDarwin() override;
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Error
- ResolveExecutable (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- lldb_private::Error
- ResolveSymbolFile (lldb_private::Target &target,
- const lldb_private::ModuleSpec &sym_spec,
- lldb_private::FileSpec &sym_file) override;
-
- lldb_private::FileSpecList
- LocateExecutableScriptingResources (lldb_private::Target *target,
- lldb_private::Module &module,
- lldb_private::Stream* feedback_stream) override;
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- size_t
- GetSoftwareBreakpointTrapOpcode (lldb_private::Target &target,
- lldb_private::BreakpointSite *bp_site) override;
-
- bool
- GetProcessInfo (lldb::pid_t pid,
- lldb_private::ProcessInstanceInfo &proc_info) override;
-
- lldb::BreakpointSP
- SetThreadCreationBreakpoint (lldb_private::Target &target) override;
-
- uint32_t
- FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- bool
- ModuleIsExcludedForUnconstrainedSearches(lldb_private::Target &target,
- const lldb::ModuleSP &module_sp) override;
-
- bool
- ARMGetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch);
-
- bool
- x86GetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch);
-
- int32_t
- GetResumeCountForLaunchInfo (lldb_private::ProcessLaunchInfo &launch_info) override;
-
- void
- CalculateTrapHandlerSymbolNames () override;
-
- bool
- GetOSVersion (uint32_t &major,
- uint32_t &minor,
- uint32_t &update,
- lldb_private::Process *process = nullptr) override;
-
- bool
- SupportsModules () override { return true; }
-
- lldb_private::ConstString
- GetFullNameForDylib (lldb_private::ConstString basename) override;
-
- lldb_private::FileSpec
- LocateExecutable (const char *basename) override;
-
- lldb_private::Error
- LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
+ PlatformDarwin(bool is_host);
+
+ ~PlatformDarwin() override;
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ lldb_private::Error
+ ResolveSymbolFile(lldb_private::Target &target,
+ const lldb_private::ModuleSpec &sym_spec,
+ lldb_private::FileSpec &sym_file) override;
+
+ lldb_private::FileSpecList LocateExecutableScriptingResources(
+ lldb_private::Target *target, lldb_private::Module &module,
+ lldb_private::Stream *feedback_stream) override;
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ size_t GetSoftwareBreakpointTrapOpcode(
+ lldb_private::Target &target,
+ lldb_private::BreakpointSite *bp_site) override;
+
+ bool GetProcessInfo(lldb::pid_t pid,
+ lldb_private::ProcessInstanceInfo &proc_info) override;
+
+ lldb::BreakpointSP
+ SetThreadCreationBreakpoint(lldb_private::Target &target) override;
+
+ uint32_t
+ FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
+ lldb_private::ProcessInstanceInfoList &process_infos) override;
+
+ bool ModuleIsExcludedForUnconstrainedSearches(
+ lldb_private::Target &target, const lldb::ModuleSP &module_sp) override;
+
+ bool ARMGetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch);
+
+ bool x86GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch);
+
+ int32_t GetResumeCountForLaunchInfo(
+ lldb_private::ProcessLaunchInfo &launch_info) override;
+
+ void CalculateTrapHandlerSymbolNames() override;
+
+ bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update,
+ lldb_private::Process *process = nullptr) override;
+
+ bool SupportsModules() override { return true; }
+
+ lldb_private::ConstString
+ GetFullNameForDylib(lldb_private::ConstString basename) override;
+
+ lldb_private::FileSpec LocateExecutable(const char *basename) override;
+
+ lldb_private::Error
+ LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
+
+ static std::tuple<uint32_t, uint32_t, uint32_t, llvm::StringRef>
+ ParseVersionBuildDir(llvm::StringRef str);
protected:
- void
- ReadLibdispatchOffsetsAddress (lldb_private::Process *process);
-
- void
- ReadLibdispatchOffsets (lldb_private::Process *process);
-
- virtual lldb_private::Error
- GetSharedModuleWithLocalCache (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- 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, uint32_t major, uint32_t minor, uint32_t micro);
-
- static bool
- SDKSupportsModules (SDKType desired_type, const lldb_private::FileSpec &sdk_path);
-
- struct SDKEnumeratorInfo {
- lldb_private::FileSpec found_path;
- SDKType sdk_type;
- };
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- DirectoryEnumerator(void *baton,
- lldb_private::FileSpec::FileType file_type,
- const lldb_private::FileSpec &spec);
-
- static lldb_private::FileSpec
- FindSDKInXcodeForModules (SDKType sdk_type,
- const lldb_private::FileSpec &sdks_spec);
-
- static lldb_private::FileSpec
- GetSDKDirectoryForModules (PlatformDarwin::SDKType sdk_type);
-
- void
- AddClangModuleCompilationOptionsForSDKType (lldb_private::Target *target, std::vector<std::string> &options, SDKType sdk_type);
-
- std::string m_developer_directory;
-
- const char *
- GetDeveloperDirectory();
-
+ void ReadLibdispatchOffsetsAddress(lldb_private::Process *process);
+
+ void ReadLibdispatchOffsets(lldb_private::Process *process);
+
+ virtual lldb_private::Error GetSharedModuleWithLocalCache(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ 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, uint32_t major,
+ uint32_t minor, uint32_t micro);
+
+ static bool SDKSupportsModules(SDKType desired_type,
+ const lldb_private::FileSpec &sdk_path);
+
+ struct SDKEnumeratorInfo {
+ lldb_private::FileSpec found_path;
+ SDKType sdk_type;
+ };
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ DirectoryEnumerator(void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &spec);
+
+ static lldb_private::FileSpec
+ FindSDKInXcodeForModules(SDKType sdk_type,
+ const lldb_private::FileSpec &sdks_spec);
+
+ static lldb_private::FileSpec
+ GetSDKDirectoryForModules(PlatformDarwin::SDKType sdk_type);
+
+ void
+ AddClangModuleCompilationOptionsForSDKType(lldb_private::Target *target,
+ std::vector<std::string> &options,
+ SDKType sdk_type);
+
+ std::string m_developer_directory;
+
+ const char *GetDeveloperDirectory();
+
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformDarwin);
+ DISALLOW_COPY_AND_ASSIGN(PlatformDarwin);
};
#endif // liblldb_PlatformDarwin_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index d3c1c805a83b..f4fd9c694000 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -1,4 +1,5 @@
-//===-- PlatformDarwinKernel.cpp -----------------------------------*- C++ -*-===//
+//===-- PlatformDarwinKernel.cpp -----------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,8 +10,8 @@
#include "PlatformDarwinKernel.h"
-#if defined (__APPLE__) // This Plugin uses the Mac-specific source/Host/macosx/cfcpp utilities
-
+#if defined(__APPLE__) // This Plugin uses the Mac-specific
+ // source/Host/macosx/cfcpp utilities
// C Includes
// C++ Includes
@@ -50,253 +51,223 @@ static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformDarwinKernel::Initialize ()
-{
- PlatformDarwin::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin (PlatformDarwinKernel::GetPluginNameStatic(),
- PlatformDarwinKernel::GetDescriptionStatic(),
- PlatformDarwinKernel::CreateInstance,
- PlatformDarwinKernel::DebuggerInitialize);
- }
+void PlatformDarwinKernel::Initialize() {
+ PlatformDarwin::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(PlatformDarwinKernel::GetPluginNameStatic(),
+ PlatformDarwinKernel::GetDescriptionStatic(),
+ PlatformDarwinKernel::CreateInstance,
+ PlatformDarwinKernel::DebuggerInitialize);
+ }
}
-void
-PlatformDarwinKernel::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformDarwinKernel::CreateInstance);
- }
+void PlatformDarwinKernel::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformDarwinKernel::CreateInstance);
}
+ }
- PlatformDarwin::Terminate ();
+ PlatformDarwin::Terminate();
}
-PlatformSP
-PlatformDarwinKernel::CreateInstance (bool force, const ArchSpec *arch)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+PlatformSP PlatformDarwinKernel::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("PlatformDarwinKernel::%s(force=%s, arch={%s,%s})",
+ __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
+ }
+
+ // This is a special plugin that we don't want to activate just based on an
+ // ArchSpec for normal
+ // userland debugging. It is only useful in kernel debug sessions and the
+ // DynamicLoaderDarwinPlugin
+ // (or a user doing 'platform select') will force the creation of this
+ // Platform plugin.
+ if (force == false) {
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 ("PlatformDarwinKernel::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- // This is a special plugin that we don't want to activate just based on an ArchSpec for normal
- // userland debugging. It is only useful in kernel debug sessions and the DynamicLoaderDarwinPlugin
- // (or a user doing 'platform select') will force the creation of this Platform plugin.
- if (force == false)
- {
- if (log)
- log->Printf ("PlatformDarwinKernel::%s() aborting creation of platform because force == false", __FUNCTION__);
- return PlatformSP();
- }
-
- bool create = force;
- LazyBool is_ios_debug_session = eLazyBoolCalculate;
-
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- case llvm::Triple::Apple:
- create = true;
- break;
-
- // Only accept "unknown" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
- default:
- break;
- }
-
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::WatchOS:
- case llvm::Triple::TvOS:
- break;
- // Only accept "vendor" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
- default:
- create = false;
- break;
- }
- }
- }
- if (arch && arch->IsValid())
- {
- switch (arch->GetMachine())
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- is_ios_debug_session = eLazyBoolNo;
- break;
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb:
- is_ios_debug_session = eLazyBoolYes;
- break;
- default:
- is_ios_debug_session = eLazyBoolCalculate;
- break;
- }
- }
- if (create)
- {
- if (log)
- log->Printf ("PlatformDarwinKernel::%s() creating platform", __FUNCTION__);
+ log->Printf("PlatformDarwinKernel::%s() aborting creation of platform "
+ "because force == false",
+ __FUNCTION__);
+ return PlatformSP();
+ }
+
+ bool create = force;
+ LazyBool is_ios_debug_session = eLazyBoolCalculate;
+
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::Apple:
+ create = true;
+ break;
+
+ // Only accept "unknown" for vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
+ default:
+ break;
+ }
+
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::WatchOS:
+ case llvm::Triple::TvOS:
+ break;
+ // Only accept "vendor" for vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
+ default:
+ create = false;
+ break;
+ }
+ }
+ }
+ if (arch && arch->IsValid()) {
+ switch (arch->GetMachine()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ is_ios_debug_session = eLazyBoolNo;
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::thumb:
+ is_ios_debug_session = eLazyBoolYes;
+ break;
+ default:
+ is_ios_debug_session = eLazyBoolCalculate;
+ break;
+ }
+ }
+ if (create) {
+ if (log)
+ log->Printf("PlatformDarwinKernel::%s() creating platform", __FUNCTION__);
- return PlatformSP(new PlatformDarwinKernel (is_ios_debug_session));
- }
+ return PlatformSP(new PlatformDarwinKernel(is_ios_debug_session));
+ }
- if (log)
- log->Printf ("PlatformDarwinKernel::%s() aborting creation of platform", __FUNCTION__);
+ if (log)
+ log->Printf("PlatformDarwinKernel::%s() aborting creation of platform",
+ __FUNCTION__);
- return PlatformSP();
+ return PlatformSP();
}
-
-lldb_private::ConstString
-PlatformDarwinKernel::GetPluginNameStatic ()
-{
- static ConstString g_name("darwin-kernel");
- return g_name;
+lldb_private::ConstString PlatformDarwinKernel::GetPluginNameStatic() {
+ static ConstString g_name("darwin-kernel");
+ return g_name;
}
-const char *
-PlatformDarwinKernel::GetDescriptionStatic()
-{
- return "Darwin Kernel platform plug-in.";
+const char *PlatformDarwinKernel::GetDescriptionStatic() {
+ return "Darwin Kernel platform plug-in.";
}
//------------------------------------------------------------------
/// Code to handle the PlatformDarwinKernel settings
//------------------------------------------------------------------
-static PropertyDefinition
-g_properties[] =
-{
- { "search-locally-for-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically search for kexts on the local system when doing kernel debugging." },
- { "kext-directories", OptionValue::eTypeFileSpecList, false, 0, NULL, NULL, "Directories/KDKs to search for kexts in when starting a kernel debug session." },
- { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL }
-};
-
-enum {
- ePropertySearchForKexts = 0,
- ePropertyKextDirectories
-};
-
+static PropertyDefinition g_properties[] = {
+ {"search-locally-for-kexts", OptionValue::eTypeBoolean, true, true, NULL,
+ NULL, "Automatically search for kexts on the local system when doing "
+ "kernel debugging."},
+ {"kext-directories", OptionValue::eTypeFileSpecList, false, 0, NULL, NULL,
+ "Directories/KDKs to search for kexts in when starting a kernel debug "
+ "session."},
+ {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
+enum { ePropertySearchForKexts = 0, ePropertyKextDirectories };
-class PlatformDarwinKernelProperties : public Properties
-{
+class PlatformDarwinKernelProperties : public Properties {
public:
-
- static ConstString &
- GetSettingName ()
- {
- static ConstString g_setting_name("darwin-kernel");
- return g_setting_name;
- }
-
- PlatformDarwinKernelProperties() :
- Properties ()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual
- ~PlatformDarwinKernelProperties()
- {
- }
-
- bool
- GetSearchForKexts() const
- {
- const uint32_t idx = ePropertySearchForKexts;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
- }
-
- FileSpecList &
- GetKextDirectories() const
- {
- const uint32_t idx = ePropertyKextDirectories;
- OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList (NULL, false, idx);
- assert(option_value);
- return option_value->GetCurrentValue();
- }
+ static ConstString &GetSettingName() {
+ static ConstString g_setting_name("darwin-kernel");
+ return g_setting_name;
+ }
+
+ PlatformDarwinKernelProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~PlatformDarwinKernelProperties() {}
+
+ bool GetSearchForKexts() const {
+ const uint32_t idx = ePropertySearchForKexts;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ NULL, idx, g_properties[idx].default_uint_value != 0);
+ }
+
+ FileSpecList &GetKextDirectories() const {
+ const uint32_t idx = ePropertyKextDirectories;
+ OptionValueFileSpecList *option_value =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
+ NULL, false, idx);
+ assert(option_value);
+ return option_value->GetCurrentValue();
+ }
};
-typedef std::shared_ptr<PlatformDarwinKernelProperties> PlatformDarwinKernelPropertiesSP;
+typedef std::shared_ptr<PlatformDarwinKernelProperties>
+ PlatformDarwinKernelPropertiesSP;
-static const PlatformDarwinKernelPropertiesSP &
-GetGlobalProperties()
-{
- static PlatformDarwinKernelPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new PlatformDarwinKernelProperties ());
- return g_settings_sp;
+static const PlatformDarwinKernelPropertiesSP &GetGlobalProperties() {
+ static PlatformDarwinKernelPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new PlatformDarwinKernelProperties());
+ return g_settings_sp;
}
-void
-PlatformDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
-{
- if (!PluginManager::GetSettingForPlatformPlugin (debugger, PlatformDarwinKernelProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForPlatformPlugin (debugger,
- GetGlobalProperties()->GetValueProperties(),
- ConstString ("Properties for the PlatformDarwinKernel plug-in."),
- is_global_setting);
- }
+void PlatformDarwinKernel::DebuggerInitialize(
+ lldb_private::Debugger &debugger) {
+ if (!PluginManager::GetSettingForPlatformPlugin(
+ debugger, PlatformDarwinKernelProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForPlatformPlugin(
+ debugger, GetGlobalProperties()->GetValueProperties(),
+ ConstString("Properties for the PlatformDarwinKernel plug-in."),
+ is_global_setting);
+ }
}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformDarwinKernel::PlatformDarwinKernel (lldb_private::LazyBool is_ios_debug_session) :
- PlatformDarwin (false), // This is a remote platform
- m_name_to_kext_path_map(),
- m_search_directories(),
- m_kernel_binaries(),
- m_ios_debug_session(is_ios_debug_session)
+PlatformDarwinKernel::PlatformDarwinKernel(
+ lldb_private::LazyBool is_ios_debug_session)
+ : PlatformDarwin(false), // This is a remote platform
+ m_name_to_kext_path_map_with_dsyms(),
+ m_name_to_kext_path_map_without_dsyms(), m_search_directories(),
+ m_search_directories_no_recursing(), m_kernel_binaries_with_dsyms(),
+ m_kernel_binaries_without_dsyms(),
+ m_ios_debug_session(is_ios_debug_session)
{
- if (GetGlobalProperties()->GetSearchForKexts())
- {
- CollectKextAndKernelDirectories ();
- IndexKextsInDirectories ();
- IndexKernelsInDirectories ();
- }
+ if (GetGlobalProperties()->GetSearchForKexts()) {
+ CollectKextAndKernelDirectories();
+ SearchForKextsAndKernelsRecursively();
+ }
}
//------------------------------------------------------------------
@@ -305,688 +276,552 @@ PlatformDarwinKernel::PlatformDarwinKernel (lldb_private::LazyBool is_ios_debug_
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformDarwinKernel::~PlatformDarwinKernel()
-{
-}
-
-
-void
-PlatformDarwinKernel::GetStatus (Stream &strm)
-{
- Platform::GetStatus (strm);
- strm.Printf (" Debug session type: ");
- if (m_ios_debug_session == eLazyBoolYes)
- strm.Printf ("iOS kernel debugging\n");
- else if (m_ios_debug_session == eLazyBoolNo)
- strm.Printf ("Mac OS X kernel debugging\n");
- else
- strm.Printf ("unknown kernel debugging\n");
- const uint32_t num_kext_dirs = m_search_directories.size();
- for (uint32_t i=0; i<num_kext_dirs; ++i)
- {
- const FileSpec &kext_dir = m_search_directories[i];
- strm.Printf (" Kext directories: [%2u] \"%s\"\n", i, kext_dir.GetPath().c_str());
- }
- strm.Printf (" Total number of kexts indexed: %d\n", (int) m_name_to_kext_path_map.size());
+PlatformDarwinKernel::~PlatformDarwinKernel() {}
+
+void PlatformDarwinKernel::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ strm.Printf(" Debug session type: ");
+ if (m_ios_debug_session == eLazyBoolYes)
+ strm.Printf("iOS kernel debugging\n");
+ else if (m_ios_debug_session == eLazyBoolNo)
+ strm.Printf("Mac OS X kernel debugging\n");
+ else
+ strm.Printf("unknown kernel debugging\n");
+
+ strm.Printf("Directories searched recursively:\n");
+ const uint32_t num_kext_dirs = m_search_directories.size();
+ for (uint32_t i = 0; i < num_kext_dirs; ++i) {
+ strm.Printf("[%d] %s\n", i, m_search_directories[i].GetPath().c_str());
+ }
+
+ strm.Printf("Directories not searched recursively:\n");
+ const uint32_t num_kext_dirs_no_recursion =
+ m_search_directories_no_recursing.size();
+ for (uint32_t i = 0; i < num_kext_dirs_no_recursion; i++) {
+ strm.Printf("[%d] %s\n", i,
+ m_search_directories_no_recursing[i].GetPath().c_str());
+ }
+
+ strm.Printf(" Number of kexts with dSYMs indexed: %d\n",
+ (int)m_name_to_kext_path_map_with_dsyms.size());
+ strm.Printf(" Number of kexts without dSYMs indexed: %d\n",
+ (int)m_name_to_kext_path_map_without_dsyms.size());
+ strm.Printf(" Number of Kernel binaries with dSYMs indexed: %d\n",
+ (int)m_kernel_binaries_with_dsyms.size());
+ strm.Printf(" Number of Kernel binaries without dSYMs indexed: %d\n",
+ (int)m_kernel_binaries_without_dsyms.size());
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log) {
+ log->Printf("\nkexts with dSYMs");
+ for (auto pos : m_name_to_kext_path_map_with_dsyms) {
+ log->Printf("%s", pos.second.GetPath().c_str());
+ }
+ log->Printf("\nkexts without dSYMs");
+
+ for (auto pos : m_name_to_kext_path_map_without_dsyms) {
+ log->Printf("%s", pos.second.GetPath().c_str());
+ }
+ log->Printf("\nkernels with dSYMS");
+ for (auto fs : m_kernel_binaries_with_dsyms) {
+ log->Printf("%s", fs.GetPath().c_str());
+ }
+ log->Printf("\nkernels without dSYMS");
+ for (auto fs : m_kernel_binaries_without_dsyms) {
+ log->Printf("%s", fs.GetPath().c_str());
+ }
+ log->Printf("\n");
+ }
}
// Populate the m_search_directories vector with directories we should search
// for kernel & kext binaries.
-void
-PlatformDarwinKernel::CollectKextAndKernelDirectories ()
-{
- // Differentiate between "ios debug session" and "mac debug session" so we don't index
- // kext bundles that won't be used in this debug session. If this is an ios kext debug
- // session, looking in /System/Library/Extensions is a waste of stat()s, for example.
-
- // Build up a list of all SDKs we'll be searching for directories of kexts/kernels
- // e.g. /Applications/Xcode.app//Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.Internal.sdk
- std::vector<FileSpec> sdk_dirs;
- if (m_ios_debug_session != eLazyBoolNo)
- {
- GetiOSSDKDirectoriesToSearch (sdk_dirs);
- GetAppleTVOSSDKDirectoriesToSearch (sdk_dirs);
- GetWatchOSSDKDirectoriesToSearch (sdk_dirs);
- }
- if (m_ios_debug_session != eLazyBoolYes)
- GetMacSDKDirectoriesToSearch (sdk_dirs);
-
- GetGenericSDKDirectoriesToSearch (sdk_dirs);
-
- // Build up a list of directories that hold may kext bundles & kernels
- //
- // e.g. given /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
- // find
- // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.Internal.sdk/
- // and
- // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.Internal.sdk/System/Library/Extensions
-
- std::vector<FileSpec> kext_dirs;
- SearchSDKsForKextDirectories (sdk_dirs, kext_dirs);
-
- if (m_ios_debug_session != eLazyBoolNo)
- GetiOSDirectoriesToSearch (kext_dirs);
- if (m_ios_debug_session != eLazyBoolYes)
- GetMacDirectoriesToSearch (kext_dirs);
-
- GetGenericDirectoriesToSearch (kext_dirs);
-
- GetUserSpecifiedDirectoriesToSearch (kext_dirs);
-
- GetKernelDirectoriesToSearch (kext_dirs);
-
- GetCurrentDirectoryToSearch (kext_dirs);
-
- // We now have a complete list of directories that we will search for kext bundles
- m_search_directories = kext_dirs;
-}
-
-void
-PlatformDarwinKernel::GetiOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer"
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir == NULL)
- developer_dir = "/Applications/Xcode.app/Contents/Developer";
-
- char pathbuf[PATH_MAX];
- ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/iPhoneOS.platform/Developer/SDKs", developer_dir);
- FileSpec ios_sdk(pathbuf, true);
- if (ios_sdk.Exists() && ios_sdk.IsDirectory())
- {
- directories.push_back (ios_sdk);
- }
-}
-
-void
-PlatformDarwinKernel::GetAppleTVOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer"
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir == NULL)
- developer_dir = "/Applications/Xcode.app/Contents/Developer";
-
- char pathbuf[PATH_MAX];
- ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/AppleTVOS.platform/Developer/SDKs", developer_dir);
- FileSpec ios_sdk(pathbuf, true);
- if (ios_sdk.Exists() && ios_sdk.IsDirectory())
- {
- directories.push_back (ios_sdk);
- }
-}
-
-void
-PlatformDarwinKernel::GetWatchOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer"
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir == NULL)
- developer_dir = "/Applications/Xcode.app/Contents/Developer";
-
- char pathbuf[PATH_MAX];
- ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/watchOS.platform/Developer/SDKs", developer_dir);
- FileSpec ios_sdk(pathbuf, true);
- if (ios_sdk.Exists() && ios_sdk.IsDirectory())
- {
- directories.push_back (ios_sdk);
- }
- else
- {
- ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/WatchOS.platform/Developer/SDKs", developer_dir);
- FileSpec alt_watch_sdk(pathbuf, true);
- if (ios_sdk.Exists() && ios_sdk.IsDirectory())
- {
- directories.push_back (ios_sdk);
- }
- }
-}
-
-
-void
-PlatformDarwinKernel::GetMacSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer"
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir == NULL)
- developer_dir = "/Applications/Xcode.app/Contents/Developer";
-
- char pathbuf[PATH_MAX];
- ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/MacOSX.platform/Developer/SDKs", developer_dir);
- FileSpec mac_sdk(pathbuf, true);
- if (mac_sdk.Exists() && mac_sdk.IsDirectory())
- {
- directories.push_back (mac_sdk);
- }
-}
-
-void
-PlatformDarwinKernel::GetGenericSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- FileSpec generic_sdk("/AppleInternal/Developer/KDKs", true);
- if (generic_sdk.Exists() && generic_sdk.IsDirectory())
- {
- directories.push_back (generic_sdk);
- }
-
- // The KDKs distributed from Apple installed on external
- // developer systems may be in directories like
- // /Library/Developer/KDKs/KDK_10.10_14A298i.kdk
- FileSpec installed_kdks("/Library/Developer/KDKs", true);
- if (installed_kdks.Exists() && installed_kdks.IsDirectory())
- {
- directories.push_back (installed_kdks);
- }
-}
-
-void
-PlatformDarwinKernel::GetiOSDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
-}
-
-void
-PlatformDarwinKernel::GetMacDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- FileSpec sle("/System/Library/Extensions", true);
- if (sle.Exists() && sle.IsDirectory())
- {
- directories.push_back(sle);
- }
-
- FileSpec le("/Library/Extensions", true);
- if (le.Exists() && le.IsDirectory())
- {
- directories.push_back(le);
- }
-
- FileSpec kdk("/Volumes/KernelDebugKit", true);
- if (kdk.Exists() && kdk.IsDirectory())
- {
- directories.push_back(kdk);
- }
-}
-
-void
-PlatformDarwinKernel::GetGenericDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer"
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir == NULL)
- developer_dir = "/Applications/Xcode.app/Contents/Developer";
-
- char pathbuf[PATH_MAX];
- ::snprintf (pathbuf, sizeof (pathbuf), "%s/../Symbols", developer_dir);
- FileSpec symbols_dir (pathbuf, true);
- if (symbols_dir.Exists() && symbols_dir.IsDirectory())
- {
- directories.push_back (symbols_dir);
- }
-}
-
-void
-PlatformDarwinKernel::GetKernelDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- FileSpec system_library_kernels ("/System/Library/Kernels", true);
- if (system_library_kernels.Exists() && system_library_kernels.IsDirectory())
- {
- directories.push_back (system_library_kernels);
- }
- FileSpec slek("/System/Library/Extensions/KDK", true);
- if (slek.Exists() && slek.IsDirectory())
- {
- directories.push_back(slek);
- }
-}
-
-void
-PlatformDarwinKernel::GetCurrentDirectoryToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- directories.push_back (FileSpec (".", true));
-
- FileSpec sle_directory ("System/Library/Extensions", true);
- if (sle_directory.Exists() && sle_directory.IsDirectory())
- {
- directories.push_back (sle_directory);
- }
-
- FileSpec le_directory ("Library/Extensions", true);
- if (le_directory.Exists() && le_directory.IsDirectory())
- {
- directories.push_back (le_directory);
- }
-
- FileSpec slk_directory ("System/Library/Kernels", true);
- if (slk_directory.Exists() && slk_directory.IsDirectory())
- {
- directories.push_back (slk_directory);
- }
- FileSpec slek("System/Library/Extensions/KDK", true);
- if (slek.Exists() && slek.IsDirectory())
- {
- directories.push_back(slek);
- }
-}
-
-void
-PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories)
-{
- FileSpecList user_dirs(GetGlobalProperties()->GetKextDirectories());
- std::vector<FileSpec> possible_sdk_dirs;
-
- 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 (dir.Exists() && dir.IsDirectory())
- {
- directories.push_back (dir);
- possible_sdk_dirs.push_back (dir); // does this directory have a *.sdk or *.kdk that we should look in?
-
- // Is there a "System/Library/Extensions" subdir of this directory?
- std::string dir_sle_path = dir.GetPath();
- dir_sle_path.append ("/System/Library/Extensions");
- FileSpec dir_sle(dir_sle_path.c_str(), true);
- if (dir_sle.Exists() && dir_sle.IsDirectory())
- {
- directories.push_back (dir_sle);
- }
-
- // Is there a "System/Library/Kernels" subdir of this directory?
- std::string dir_slk_path = dir.GetPath();
- dir_slk_path.append ("/System/Library/Kernels");
- FileSpec dir_slk(dir_slk_path.c_str(), true);
- if (dir_slk.Exists() && dir_slk.IsDirectory())
- {
- directories.push_back (dir_slk);
- }
-
- // Is there a "System/Library/Extensions/KDK" subdir of this directory?
- std::string dir_slek_path = dir.GetPath();
- dir_slek_path.append ("/System/Library/Kernels");
- FileSpec dir_slek(dir_slek_path.c_str(), true);
- if (dir_slek.Exists() && dir_slek.IsDirectory())
- {
- directories.push_back (dir_slek);
- }
- }
- }
-
- SearchSDKsForKextDirectories (possible_sdk_dirs, directories);
-}
-
-// Scan through the SDK directories, looking for directories where kexts are likely.
-// Add those directories to kext_dirs.
-void
-PlatformDarwinKernel::SearchSDKsForKextDirectories (std::vector<lldb_private::FileSpec> sdk_dirs, std::vector<lldb_private::FileSpec> &kext_dirs)
-{
- const uint32_t num_sdks = sdk_dirs.size();
- for (uint32_t i = 0; i < num_sdks; i++)
- {
- const FileSpec &sdk_dir = sdk_dirs[i];
- std::string sdk_dir_path = sdk_dir.GetPath();
- if (!sdk_dir_path.empty())
- {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
- FileSpec::EnumerateDirectory (sdk_dir_path.c_str(),
- find_directories,
- find_files,
- find_other,
- GetKextDirectoriesInSDK,
- &kext_dirs);
- }
- }
-}
-
-// Callback for FileSpec::EnumerateDirectory().
-// Step through the entries in a directory like
-// /Applications/Xcode.app//Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
-// looking for any subdirectories of the form MacOSX10.8.Internal.sdk/System/Library/Extensions
-// Adds these to the vector of FileSpec's.
-
+void PlatformDarwinKernel::CollectKextAndKernelDirectories() {
+ // Differentiate between "ios debug session" and "mac debug session" so we
+ // don't index
+ // kext bundles that won't be used in this debug session. If this is an ios
+ // kext debug
+ // session, looking in /System/Library/Extensions is a waste of stat()s, for
+ // example.
+
+ // DeveloperDirectory is something like
+ // "/Applications/Xcode.app/Contents/Developer"
+ std::string developer_dir = GetDeveloperDirectory();
+ if (developer_dir.empty())
+ developer_dir = "/Applications/Xcode.app/Contents/Developer";
+
+ if (m_ios_debug_session != eLazyBoolNo) {
+ AddSDKSubdirsToSearchPaths(developer_dir +
+ "/Platforms/iPhoneOS.platform/Developer/SDKs");
+ AddSDKSubdirsToSearchPaths(developer_dir +
+ "/Platforms/AppleTVOS.platform/Developer/SDKs");
+ AddSDKSubdirsToSearchPaths(developer_dir +
+ "/Platforms/WatchOS.platform/Developer/SDKs");
+ }
+ if (m_ios_debug_session != eLazyBoolYes) {
+ AddSDKSubdirsToSearchPaths(developer_dir +
+ "/Platforms/MacOSX.platform/Developer/SDKs");
+ }
+
+ AddSDKSubdirsToSearchPaths("/Volumes/KernelDebugKit");
+ AddSDKSubdirsToSearchPaths("/AppleInternal/Developer/KDKs");
+ // The KDKs distributed from Apple installed on external
+ // developer systems may be in directories like
+ // /Library/Developer/KDKs/KDK_10.10_14A298i.kdk
+ AddSDKSubdirsToSearchPaths("/Library/Developer/KDKs");
+
+ if (m_ios_debug_session != eLazyBoolNo) {
+ }
+ if (m_ios_debug_session != eLazyBoolYes) {
+ AddRootSubdirsToSearchPaths(this, "/");
+ }
+
+ GetUserSpecifiedDirectoriesToSearch();
+
+ // Add simple directory /Applications/Xcode.app/Contents/Developer/../Symbols
+ FileSpec possible_dir(developer_dir + "/../Symbols", true);
+ if (possible_dir.Exists() && possible_dir.IsDirectory())
+ m_search_directories.push_back(possible_dir);
+
+ // Add simple directory of the current working directory
+ m_search_directories_no_recursing.push_back(FileSpec(".", true));
+}
+
+void PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch() {
+ FileSpecList user_dirs(GetGlobalProperties()->GetKextDirectories());
+ std::vector<FileSpec> possible_sdk_dirs;
+
+ 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 (dir.Exists() && dir.IsDirectory()) {
+ m_search_directories.push_back(dir);
+ }
+ }
+}
+
+void PlatformDarwinKernel::AddRootSubdirsToSearchPaths(
+ PlatformDarwinKernel *thisp, const std::string &dir) {
+ const char *subdirs[] = {
+ "/System/Library/Extensions", "/Library/Extensions",
+ "/System/Library/Kernels",
+ "/System/Library/Extensions/KDK", // this one probably only exist in
+ // /AppleInternal/Developer/KDKs/*.kdk/...
+ nullptr};
+ for (int i = 0; subdirs[i] != nullptr; i++) {
+ FileSpec testdir(dir + subdirs[i], true);
+ if (testdir.Exists() && testdir.IsDirectory())
+ 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));
+}
+
+// Given a directory path dir, look for any subdirs named *.kdk and *.sdk
+void PlatformDarwinKernel::AddSDKSubdirsToSearchPaths(const std::string &dir) {
+ // Look for *.kdk and *.sdk in 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);
+}
+
+// Helper function to find *.sdk and *.kdk directories in a given directory.
FileSpec::EnumerateDirectoryResult
-PlatformDarwinKernel::GetKextDirectoriesInSDK (void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- if (file_type == FileSpec::eFileTypeDirectory
- && (file_spec.GetFileNameExtension() == ConstString("sdk")
- || file_spec.GetFileNameExtension() == ConstString("kdk")))
- {
- std::string kext_directory_path = file_spec.GetPath();
-
- // Append the raw directory path, e.g. /Library/Developer/KDKs/KDK_10.10_14A298i.kdk
- // to the directory search list -- there may be kexts sitting directly
- // in that directory instead of being in a System/Library/Extensions subdir.
- ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec);
-
- // Check to see if there is a System/Library/Extensions subdir & add it if it exists
-
- std::string sle_kext_directory_path (kext_directory_path);
- sle_kext_directory_path.append ("/System/Library/Extensions");
- FileSpec sle_kext_directory (sle_kext_directory_path.c_str(), true);
- if (sle_kext_directory.Exists() && sle_kext_directory.IsDirectory())
- {
- ((std::vector<lldb_private::FileSpec> *)baton)->push_back(sle_kext_directory);
- }
-
- // Check to see if there is a Library/Extensions subdir & add it if it exists
-
- std::string le_kext_directory_path (kext_directory_path);
- le_kext_directory_path.append ("/Library/Extensions");
- FileSpec le_kext_directory (le_kext_directory_path.c_str(), true);
- if (le_kext_directory.Exists() && le_kext_directory.IsDirectory())
- {
- ((std::vector<lldb_private::FileSpec> *)baton)->push_back(le_kext_directory);
- }
-
- // Check to see if there is a System/Library/Kernels subdir & add it if it exists
- std::string slk_kernel_path (kext_directory_path);
- slk_kernel_path.append ("/System/Library/Kernels");
- FileSpec slk_kernel_directory (slk_kernel_path.c_str(), true);
- if (slk_kernel_directory.Exists() && slk_kernel_directory.IsDirectory())
- {
- ((std::vector<lldb_private::FileSpec> *)baton)->push_back(slk_kernel_directory);
- }
-
- // Check to see if there is a System/Library/Extensions/KDK subdir & add it if it exists
- std::string slek_kernel_path (kext_directory_path);
- slek_kernel_path.append ("/System/Library/Extensions/KDK");
- FileSpec slek_kernel_directory (slek_kernel_path.c_str(), true);
- if (slek_kernel_directory.Exists() && slek_kernel_directory.IsDirectory())
- {
- ((std::vector<lldb_private::FileSpec> *)baton)->push_back(slek_kernel_directory);
- }
- }
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-
-void
-PlatformDarwinKernel::IndexKextsInDirectories ()
-{
- std::vector<FileSpec> kext_bundles;
-
- const uint32_t num_dirs = m_search_directories.size();
- for (uint32_t i = 0; i < num_dirs; i++)
- {
- const FileSpec &dir = m_search_directories[i];
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
- FileSpec::EnumerateDirectory (dir.GetPath().c_str(),
- find_directories,
- find_files,
- find_other,
- GetKextsInDirectory,
- &kext_bundles);
- }
-
- const uint32_t num_kexts = kext_bundles.size();
- for (uint32_t i = 0; i < num_kexts; i++)
- {
- const FileSpec &kext = kext_bundles[i];
- CFCBundle bundle (kext.GetPath().c_str());
- CFStringRef bundle_id (bundle.GetIdentifier());
- if (bundle_id && CFGetTypeID (bundle_id) == CFStringGetTypeID ())
- {
- char bundle_id_buf[PATH_MAX];
- if (CFStringGetCString (bundle_id, bundle_id_buf, sizeof (bundle_id_buf), kCFStringEncodingUTF8))
- {
- ConstString bundle_conststr(bundle_id_buf);
- m_name_to_kext_path_map.insert(std::pair<ConstString, FileSpec>(bundle_conststr, kext));
- }
- }
- }
-}
-
-// Callback for FileSpec::EnumerateDirectory().
-// Step through the entries in a directory like /System/Library/Extensions, find .kext bundles, add them
-// to the vector of FileSpecs.
-// If a .kext bundle has a Contents/PlugIns or PlugIns subdir, search for kexts in there too.
+PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory(
+ void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) {
+ static ConstString g_sdk_suffix = ConstString("sdk");
+ static ConstString g_kdk_suffix = ConstString("kdk");
+
+ PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
+ if (file_type == FileSpec::eFileTypeDirectory &&
+ (file_spec.GetFileNameExtension() == g_sdk_suffix ||
+ file_spec.GetFileNameExtension() == g_kdk_suffix)) {
+ AddRootSubdirsToSearchPaths(thisp, file_spec.GetPath());
+ }
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+// Recursively search trough m_search_directories looking for
+// kext and kernel binaries, adding files found to the appropriate
+// lists.
+void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
+ const uint32_t num_dirs = m_search_directories.size();
+ for (uint32_t i = 0; i < num_dirs; i++) {
+ const FileSpec &dir = m_search_directories[i];
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s.
+ FileSpec::EnumerateDirectory(
+ dir.GetPath().c_str(), find_directories, find_files, find_other,
+ GetKernelsAndKextsInDirectoryWithRecursion, this);
+ }
+ const uint32_t num_dirs_no_recurse = m_search_directories_no_recursing.size();
+ for (uint32_t i = 0; i < num_dirs_no_recurse; i++) {
+ const FileSpec &dir = m_search_directories_no_recursing[i];
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s.
+ FileSpec::EnumerateDirectory(
+ dir.GetPath().c_str(), find_directories, find_files, find_other,
+ GetKernelsAndKextsInDirectoryNoRecursion, this);
+ }
+}
+
+// We're only doing a filename match here. We won't try opening the file to see
+// if it's really
+// a kernel or not until we need to find a kernel of a given UUID. There's no
+// cheap way to find
+// the UUID of a file (or if it's a Mach-O binary at all) without creating a
+// whole Module for
+// the file and throwing it away if it's not wanted.
+//
+// Recurse into any subdirectories found.
FileSpec::EnumerateDirectoryResult
-PlatformDarwinKernel::GetKextsInDirectory (void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- if (file_type == FileSpec::eFileTypeDirectory && file_spec.GetFileNameExtension() == ConstString("kext"))
- {
- ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec);
- std::string kext_bundle_path = file_spec.GetPath();
- std::string search_here_too;
- std::string contents_plugins_path = kext_bundle_path + "/Contents/PlugIns";
- FileSpec contents_plugins (contents_plugins_path.c_str(), false);
- if (contents_plugins.Exists() && contents_plugins.IsDirectory())
- {
- search_here_too = contents_plugins_path;
- }
- else
- {
- std::string plugins_path = kext_bundle_path + "/PlugIns";
- FileSpec plugins (plugins_path.c_str(), false);
- if (plugins.Exists() && plugins.IsDirectory())
- {
- search_here_too = plugins_path;
- }
- }
-
- if (!search_here_too.empty())
- {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
- FileSpec::EnumerateDirectory (search_here_too.c_str(),
- find_directories,
- find_files,
- find_other,
- GetKextsInDirectory,
- baton);
- }
- }
- return FileSpec::eEnumerateDirectoryResultNext;
+PlatformDarwinKernel::GetKernelsAndKextsInDirectoryWithRecursion(
+ void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) {
+ return GetKernelsAndKextsInDirectoryHelper(baton, file_type, file_spec, true);
}
-void
-PlatformDarwinKernel::IndexKernelsInDirectories ()
-{
- std::vector<FileSpec> kernels;
-
-
- const uint32_t num_dirs = m_search_directories.size();
- for (uint32_t i = 0; i < num_dirs; i++)
- {
- const FileSpec &dir = m_search_directories[i];
- const bool find_directories = false;
- const bool find_files = true;
- const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s.
- FileSpec::EnumerateDirectory (dir.GetPath().c_str(),
- find_directories,
- find_files,
- find_other,
- GetKernelsInDirectory,
- &m_kernel_binaries);
- }
+FileSpec::EnumerateDirectoryResult
+PlatformDarwinKernel::GetKernelsAndKextsInDirectoryNoRecursion(
+ void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) {
+ return GetKernelsAndKextsInDirectoryHelper(baton, file_type, file_spec,
+ false);
}
-// Callback for FileSpec::EnumerateDirectory().
-// Step through the entries in a directory like /System/Library/Kernels/, find kernel binaries,
-// add them to m_kernel_binaries.
-
-// We're only doing a filename match here. We won't try opening the file to see if it's really
-// a kernel or not until we need to find a kernel of a given UUID. There's no cheap way to find
-// the UUID of a file (or if it's a Mach-O binary at all) without creating a whole Module for
-// the file and throwing it away if it's not wanted.
-
FileSpec::EnumerateDirectoryResult
-PlatformDarwinKernel::GetKernelsInDirectory (void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- if (file_type == FileSpec::eFileTypeRegular || file_type == FileSpec::eFileTypeSymbolicLink)
- {
- ConstString filename = file_spec.GetFilename();
- if (strncmp (filename.GetCString(), "kernel", 6) == 0
- || strncmp (filename.GetCString(), "mach", 4) == 0)
- {
- // This is m_kernel_binaries but we're in a class method here
- ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec);
- }
+PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
+ void *baton, FileSpec::FileType file_type, const FileSpec &file_spec,
+ bool recurse) {
+ static ConstString g_kext_suffix = ConstString("kext");
+ static ConstString g_dsym_suffix = ConstString("dSYM");
+ static ConstString g_bundle_suffix = ConstString("Bundle");
+ ConstString file_spec_extension = file_spec.GetFileNameExtension();
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("PlatformDarwinKernel examining %s",
+ file_spec.GetPath().c_str());
+
+ PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
+ if (file_type == FileSpec::eFileTypeRegular ||
+ file_type == FileSpec::eFileTypeSymbolicLink) {
+ ConstString filename = file_spec.GetFilename();
+ if ((strncmp(filename.GetCString(), "kernel", 6) == 0 ||
+ strncmp(filename.GetCString(), "mach", 4) == 0) &&
+ file_spec_extension != g_dsym_suffix) {
+ if (KernelHasdSYMSibling(file_spec))
+ thisp->m_kernel_binaries_with_dsyms.push_back(file_spec);
+ else
+ thisp->m_kernel_binaries_without_dsyms.push_back(file_spec);
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+ } else if (file_type == FileSpec::eFileTypeDirectory &&
+ 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);
+ std::string search_here_too;
+ if (contents_plugins.Exists() && contents_plugins.IsDirectory()) {
+ search_here_too = contents_plugins.GetPath();
+ } else {
+ FileSpec plugins(file_spec.GetPath() + "/PlugIns", false);
+ if (plugins.Exists() && plugins.IsDirectory()) {
+ search_here_too = plugins.GetPath();
+ }
+ }
+
+ if (!search_here_too.empty()) {
+ const bool find_directories = true;
+ const bool find_files = false;
+ const bool find_other = false;
+ FileSpec::EnumerateDirectory(
+ search_here_too.c_str(), find_directories, find_files, find_other,
+ recurse ? GetKernelsAndKextsInDirectoryWithRecursion
+ : GetKernelsAndKextsInDirectoryNoRecursion,
+ baton);
}
return FileSpec::eEnumerateDirectoryResultNext;
-}
-
-
-Error
-PlatformDarwinKernel::GetSharedModule (const ModuleSpec &module_spec,
- Process *process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- Error error;
- module_sp.reset();
- const FileSpec &platform_file = module_spec.GetFileSpec();
-
- // Treat the file's path as a kext bundle ID (e.g. "com.apple.driver.AppleIRController") and search our kext index.
- std::string kext_bundle_id = platform_file.GetPath();
- if (!kext_bundle_id.empty())
- {
- ConstString kext_bundle_cs(kext_bundle_id.c_str());
- if (m_name_to_kext_path_map.count(kext_bundle_cs) > 0)
- {
- for (BundleIDToKextIterator it = m_name_to_kext_path_map.begin (); it != m_name_to_kext_path_map.end (); ++it)
- {
- if (it->first == kext_bundle_cs)
- {
- error = ExamineKextForMatchingUUID (it->second, module_spec.GetUUID(), module_spec.GetArchitecture(), module_sp);
- if (module_sp.get())
- {
- return error;
- }
- }
- }
+ }
+ // Don't recurse into dSYM/kext/bundle directories
+ if (recurse && file_spec_extension != g_dsym_suffix &&
+ file_spec_extension != g_kext_suffix &&
+ file_spec_extension != g_bundle_suffix) {
+ return FileSpec::eEnumerateDirectoryResultEnter;
+ } else {
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+}
+
+void PlatformDarwinKernel::AddKextToMap(PlatformDarwinKernel *thisp,
+ const FileSpec &file_spec) {
+ CFCBundle bundle(file_spec.GetPath().c_str());
+ CFStringRef bundle_id(bundle.GetIdentifier());
+ if (bundle_id && CFGetTypeID(bundle_id) == CFStringGetTypeID()) {
+ char bundle_id_buf[PATH_MAX];
+ if (CFStringGetCString(bundle_id, bundle_id_buf, sizeof(bundle_id_buf),
+ kCFStringEncodingUTF8)) {
+ ConstString bundle_conststr(bundle_id_buf);
+ if (KextHasdSYMSibling(file_spec))
+ thisp->m_name_to_kext_path_map_with_dsyms.insert(
+ std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
+ else
+ thisp->m_name_to_kext_path_map_without_dsyms.insert(
+ std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
+ }
+ }
+}
+
+// Given a FileSpec of /dir/dir/foo.kext
+// Return true if any of these exist:
+// /dir/dir/foo.kext.dSYM
+// /dir/dir/foo.kext/Contents/MacOS/foo.dSYM
+// /dir/dir/foo.kext/foo.dSYM
+bool PlatformDarwinKernel::KextHasdSYMSibling(
+ const FileSpec &kext_bundle_filepath) {
+ FileSpec dsym_fspec = kext_bundle_filepath;
+ std::string filename = dsym_fspec.GetFilename().AsCString();
+ filename += ".dSYM";
+ dsym_fspec.GetFilename() = ConstString(filename);
+ if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) {
+ return true;
+ }
+ // Should probably get the CFBundleExecutable here or call
+ // CFBundleCopyExecutableURL
+
+ // Look for a deep bundle foramt
+ ConstString executable_name =
+ kext_bundle_filepath.GetFileNameStrippingExtension();
+ std::string deep_bundle_str =
+ kext_bundle_filepath.GetPath() + "/Contents/MacOS/";
+ deep_bundle_str += executable_name.AsCString();
+ deep_bundle_str += ".dSYM";
+ dsym_fspec.SetFile(deep_bundle_str, true);
+ if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) {
+ return true;
+ }
+
+ // look for a shallow bundle format
+ //
+ 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);
+ if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) {
+ return true;
+ }
+ return false;
+}
+
+// Given a FileSpec of /dir/dir/mach.development.t7004
+// Return true if a dSYM exists next to it:
+// /dir/dir/mach.development.t7004.dSYM
+bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) {
+ FileSpec kernel_dsym = kernel_binary;
+ std::string filename = kernel_binary.GetFilename().AsCString();
+ filename += ".dSYM";
+ kernel_dsym.GetFilename() = ConstString(filename);
+ if (kernel_dsym.Exists() && kernel_dsym.IsDirectory()) {
+ return true;
+ }
+ return false;
+}
+
+Error PlatformDarwinKernel::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ Error error;
+ module_sp.reset();
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+
+ // Treat the file's path as a kext bundle ID (e.g.
+ // "com.apple.driver.AppleIRController") and search our kext index.
+ std::string kext_bundle_id = platform_file.GetPath();
+ if (!kext_bundle_id.empty()) {
+ ConstString kext_bundle_cs(kext_bundle_id.c_str());
+
+ // First look through the kext bundles that had a dsym next to them
+ if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle_cs) > 0) {
+ for (BundleIDToKextIterator it =
+ m_name_to_kext_path_map_with_dsyms.begin();
+ it != m_name_to_kext_path_map_with_dsyms.end(); ++it) {
+ if (it->first == kext_bundle_cs) {
+ error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
+ module_spec.GetArchitecture(),
+ module_sp);
+ if (module_sp.get()) {
+ return error;
+ }
}
- }
-
- if (kext_bundle_id.compare("mach_kernel") == 0 && module_spec.GetUUID().IsValid())
- {
- for (auto possible_kernel : m_kernel_binaries)
- {
- if (possible_kernel.Exists())
- {
- ModuleSpec kern_spec (possible_kernel);
- kern_spec.GetUUID() = module_spec.GetUUID();
- ModuleSP module_sp (new Module (kern_spec));
- if (module_sp && module_sp->GetObjectFile() && module_sp->MatchesModuleSpec (kern_spec))
- {
- // module_sp is an actual kernel binary we want to add.
- if (process)
- {
- process->GetTarget().GetImages().AppendIfNeeded (module_sp);
- error.Clear();
- return error;
- }
- else
- {
- error = ModuleList::GetSharedModule (kern_spec, module_sp, NULL, NULL, NULL);
- if (module_sp
- && module_sp->GetObjectFile()
- && module_sp->GetObjectFile()->GetType() != ObjectFile::Type::eTypeCoreFile)
- {
- return error;
- }
- module_sp.reset();
- }
- }
- }
+ }
+ }
+
+ // Second look through the kext binarys without dSYMs
+ if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle_cs) > 0) {
+ for (BundleIDToKextIterator it =
+ m_name_to_kext_path_map_without_dsyms.begin();
+ it != m_name_to_kext_path_map_without_dsyms.end(); ++it) {
+ if (it->first == kext_bundle_cs) {
+ error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
+ module_spec.GetArchitecture(),
+ module_sp);
+ if (module_sp.get()) {
+ return error;
+ }
}
- }
-
- // Else fall back to treating the file's path as an actual file path - defer to PlatformDarwin's GetSharedModule.
- return PlatformDarwin::GetSharedModule (module_spec, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
-}
-
-Error
-PlatformDarwinKernel::ExamineKextForMatchingUUID (const FileSpec &kext_bundle_path, const lldb_private::UUID &uuid, const ArchSpec &arch, ModuleSP &exe_module_sp)
-{
- Error error;
- FileSpec exe_file = kext_bundle_path;
- Host::ResolveExecutableInBundle (exe_file);
- if (exe_file.Exists())
- {
- ModuleSpec exe_spec (exe_file);
- exe_spec.GetUUID() = uuid;
- if (!uuid.IsValid())
- {
- exe_spec.GetArchitecture() = arch;
+ }
+ }
+ }
+
+ if (kext_bundle_id.compare("mach_kernel") == 0 &&
+ 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()) {
+ ModuleSpec kern_spec(possible_kernel);
+ kern_spec.GetUUID() = module_spec.GetUUID();
+ ModuleSP module_sp(new Module(kern_spec));
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->MatchesModuleSpec(kern_spec)) {
+ // module_sp is an actual kernel binary we want to add.
+ if (process) {
+ process->GetTarget().GetImages().AppendIfNeeded(module_sp);
+ error.Clear();
+ return error;
+ } else {
+ error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL,
+ NULL, NULL);
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->GetObjectFile()->GetType() !=
+ ObjectFile::Type::eTypeCoreFile) {
+ return error;
+ }
+ module_sp.reset();
+ }
}
-
- // First try to create a ModuleSP with the file / arch and see if the UUID matches.
- // If that fails (this exec file doesn't have the correct uuid), don't call GetSharedModule
- // (which may call in to the DebugSymbols framework and therefore can be slow.)
- ModuleSP module_sp (new Module (exe_spec));
- if (module_sp && module_sp->GetObjectFile() && module_sp->MatchesModuleSpec (exe_spec))
- {
- error = ModuleList::GetSharedModule (exe_spec, exe_module_sp, NULL, NULL, NULL);
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- {
- return error;
+ }
+ }
+ // Second try all kernel binaries that don't have a dSYM
+ for (auto possible_kernel : m_kernel_binaries_without_dsyms) {
+ if (possible_kernel.Exists()) {
+ ModuleSpec kern_spec(possible_kernel);
+ kern_spec.GetUUID() = module_spec.GetUUID();
+ ModuleSP module_sp(new Module(kern_spec));
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->MatchesModuleSpec(kern_spec)) {
+ // module_sp is an actual kernel binary we want to add.
+ if (process) {
+ process->GetTarget().GetImages().AppendIfNeeded(module_sp);
+ error.Clear();
+ return error;
+ } else {
+ error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL,
+ NULL, NULL);
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->GetObjectFile()->GetType() !=
+ ObjectFile::Type::eTypeCoreFile) {
+ return error;
}
+ module_sp.reset();
+ }
}
- exe_module_sp.reset();
- }
- return error;
-}
-
-bool
-PlatformDarwinKernel::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
-#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
- return ARMGetSupportedArchitectureAtIndex (idx, arch);
+ }
+ }
+ }
+
+ // Else fall back to treating the file's path as an actual file path - defer
+ // to PlatformDarwin's GetSharedModule.
+ return PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+}
+
+Error PlatformDarwinKernel::ExamineKextForMatchingUUID(
+ const FileSpec &kext_bundle_path, const lldb_private::UUID &uuid,
+ const ArchSpec &arch, ModuleSP &exe_module_sp) {
+ Error error;
+ FileSpec exe_file = kext_bundle_path;
+ Host::ResolveExecutableInBundle(exe_file);
+ if (exe_file.Exists()) {
+ ModuleSpec exe_spec(exe_file);
+ exe_spec.GetUUID() = uuid;
+ if (!uuid.IsValid()) {
+ exe_spec.GetArchitecture() = arch;
+ }
+
+ // First try to create a ModuleSP with the file / arch and see if the UUID
+ // matches.
+ // If that fails (this exec file doesn't have the correct uuid), don't call
+ // GetSharedModule
+ // (which may call in to the DebugSymbols framework and therefore can be
+ // slow.)
+ ModuleSP module_sp(new Module(exe_spec));
+ if (module_sp && module_sp->GetObjectFile() &&
+ module_sp->MatchesModuleSpec(exe_spec)) {
+ error = ModuleList::GetSharedModule(exe_spec, exe_module_sp, NULL, NULL,
+ NULL);
+ if (exe_module_sp && exe_module_sp->GetObjectFile()) {
+ return error;
+ }
+ }
+ exe_module_sp.reset();
+ }
+ return error;
+}
+
+bool PlatformDarwinKernel::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ return ARMGetSupportedArchitectureAtIndex(idx, arch);
#else
- return x86GetSupportedArchitectureAtIndex (idx, arch);
+ return x86GetSupportedArchitectureAtIndex(idx, arch);
#endif
}
-void
-PlatformDarwinKernel::CalculateTrapHandlerSymbolNames ()
-{
- m_trap_handlers.push_back(ConstString ("trap_from_kernel"));
- m_trap_handlers.push_back(ConstString ("hndl_machine_check"));
- m_trap_handlers.push_back(ConstString ("hndl_double_fault"));
- m_trap_handlers.push_back(ConstString ("hndl_allintrs"));
- m_trap_handlers.push_back(ConstString ("hndl_alltraps"));
- m_trap_handlers.push_back(ConstString ("interrupt"));
- m_trap_handlers.push_back(ConstString ("fleh_prefabt"));
- m_trap_handlers.push_back(ConstString ("ExceptionVectorsBase"));
- m_trap_handlers.push_back(ConstString ("ExceptionVectorsTable"));
- m_trap_handlers.push_back(ConstString ("fleh_undef"));
- m_trap_handlers.push_back(ConstString ("fleh_dataabt"));
- m_trap_handlers.push_back(ConstString ("fleh_irq"));
- m_trap_handlers.push_back(ConstString ("fleh_decirq"));
- m_trap_handlers.push_back(ConstString ("fleh_fiq_generic"));
- m_trap_handlers.push_back(ConstString ("fleh_dec"));
-
+void PlatformDarwinKernel::CalculateTrapHandlerSymbolNames() {
+ m_trap_handlers.push_back(ConstString("trap_from_kernel"));
+ m_trap_handlers.push_back(ConstString("hndl_machine_check"));
+ m_trap_handlers.push_back(ConstString("hndl_double_fault"));
+ m_trap_handlers.push_back(ConstString("hndl_allintrs"));
+ m_trap_handlers.push_back(ConstString("hndl_alltraps"));
+ m_trap_handlers.push_back(ConstString("interrupt"));
+ m_trap_handlers.push_back(ConstString("fleh_prefabt"));
+ m_trap_handlers.push_back(ConstString("ExceptionVectorsBase"));
+ m_trap_handlers.push_back(ConstString("ExceptionVectorsTable"));
+ m_trap_handlers.push_back(ConstString("fleh_undef"));
+ m_trap_handlers.push_back(ConstString("fleh_dataabt"));
+ m_trap_handlers.push_back(ConstString("fleh_irq"));
+ m_trap_handlers.push_back(ConstString("fleh_decirq"));
+ m_trap_handlers.push_back(ConstString("fleh_fiq_generic"));
+ m_trap_handlers.push_back(ConstString("fleh_dec"));
}
-#else // __APPLE__
+#else // __APPLE__
// Since DynamicLoaderDarwinKernel is compiled in for all systems, and relies on
-// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name in
-// here to avoid issues. We are tracking an internal bug to resolve this issue by
-// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to make
-// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently not
+// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name
+// in
+// here to avoid issues. We are tracking an internal bug to resolve this issue
+// by
+// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to
+// make
+// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently
+// not
// compiled on other platforms due to the use of the Mac-specific
// source/Host/macosx/cfcpp utilities.
-lldb_private::ConstString
-PlatformDarwinKernel::GetPluginNameStatic ()
-{
- static lldb_private::ConstString g_name("darwin-kernel");
- return g_name;
+lldb_private::ConstString PlatformDarwinKernel::GetPluginNameStatic() {
+ static lldb_private::ConstString g_name("darwin-kernel");
+ return g_name;
}
#endif // __APPLE__
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
index c1fe23178bf4..2010c4860309 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
@@ -12,8 +12,8 @@
#include "lldb/Core/ConstString.h"
-#if defined (__APPLE__) // This Plugin uses the Mac-specific source/Host/macosx/cfcpp utilities
-
+#if defined(__APPLE__) // This Plugin uses the Mac-specific
+ // source/Host/macosx/cfcpp utilities
// C Includes
// C++ Includes
@@ -23,206 +23,186 @@
// Project includes
#include "PlatformDarwin.h"
-class PlatformDarwinKernel : public PlatformDarwin
-{
+class PlatformDarwinKernel : public PlatformDarwin {
public:
+ //------------------------------------------------------------
+ // Class Functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch);
- //------------------------------------------------------------
- // Class Functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance (bool force, const lldb_private::ArchSpec *arch);
-
- static void
- DebuggerInitialize (lldb_private::Debugger &debugger);
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic ();
-
- static const char *
- GetDescriptionStatic();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- PlatformDarwinKernel (lldb_private::LazyBool is_ios_debug_session);
-
- virtual
- ~PlatformDarwinKernel();
-
- //------------------------------------------------------------
- // 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();
- }
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- bool
- SupportsModules() override { return false; }
-
- void
- CalculateTrapHandlerSymbolNames () override;
-
-protected:
-
- // Map from kext bundle ID ("com.apple.filesystems.exfat") to FileSpec for the kext bundle on
- // the host ("/System/Library/Extensions/exfat.kext/Contents/Info.plist").
- typedef std::multimap<lldb_private::ConstString, lldb_private::FileSpec> BundleIDToKextMap;
- typedef BundleIDToKextMap::iterator BundleIDToKextIterator;
-
- typedef std::vector<lldb_private::FileSpec> KernelBinaryCollection;
-
- // Array of directories that were searched for kext bundles (used only for reporting to user)
- typedef std::vector<lldb_private::FileSpec> DirectoriesSearchedCollection;
- typedef DirectoriesSearchedCollection::iterator DirectoriesSearchedIterator;
-
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetKextDirectoriesInSDK (void *baton,
- lldb_private::FileSpec::FileType file_type,
- const lldb_private::FileSpec &file_spec);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetKextsInDirectory (void *baton,
- lldb_private::FileSpec::FileType file_type,
- const lldb_private::FileSpec &file_spec);
+ static void Initialize();
- // Populate m_search_directories vector of directories
- void
- CollectKextAndKernelDirectories ();
+ static void Terminate();
- // Directories where we may find iOS SDKs with kext bundles in them
- void
- GetiOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ static lldb_private::ConstString GetPluginNameStatic();
- // Directories where we may find AppleTVOS SDKs with kext bundles in them
- void
- GetAppleTVOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
-
- // Directories where we may find WatchOS SDKs with kext bundles in them
- void
- GetWatchOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ static const char *GetDescriptionStatic();
- // Directories where we may find Mac OS X SDKs with kext bundles in them
- void
- GetMacSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ //------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------
+ PlatformDarwinKernel(lldb_private::LazyBool is_ios_debug_session);
- // Directories where we may find Mac OS X or iOS SDKs with kext bundles in them
- void
- GetGenericSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ virtual ~PlatformDarwinKernel();
- // Directories where we may find iOS kext bundles
- void
- GetiOSDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
- // Directories where we may find MacOSX kext bundles
- void
- GetMacDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ uint32_t GetPluginVersion() override { return 1; }
- // Directories where we may find iOS or MacOSX kext bundles
- void
- GetGenericDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ const char *GetDescription() override { return GetDescriptionStatic(); }
- // Directories specified via the "kext-directories" setting - maybe KDK/SDKs, may be plain directories
- void
- GetUserSpecifiedDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ void GetStatus(lldb_private::Stream &strm) override;
- void
- GetCurrentDirectoryToSearch (std::vector<lldb_private::FileSpec> &directories);
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
- // Directories where we may find kernels exclusively
- void
- GetKernelDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories);
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
- // Search through a vector of SDK FileSpecs, add any directories that may contain kexts
- // to the vector of kext dir FileSpecs
- void
- SearchSDKsForKextDirectories (std::vector<lldb_private::FileSpec> sdk_dirs, std::vector<lldb_private::FileSpec> &kext_dirs);
+ bool SupportsModules() override { return false; }
- // Search through all of the directories passed in, find all .kext bundles in those directories,
- // get the CFBundleIDs out of the Info.plists and add the bundle ID and kext path to m_name_to_kext_path_map.
- void
- IndexKextsInDirectories ();
+ void CalculateTrapHandlerSymbolNames() override;
- // Search through all of the directories passed in, find all kernel binaries in those directories
- // (look for "kernel*", "mach.*", assume those are kernels. False positives aren't a huge problem.)
- void
- IndexKernelsInDirectories ();
-
- // Callback which iterates over all the files in a given directory, looking for kernel binaries
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetKernelsInDirectory (void *baton,
- lldb_private::FileSpec::FileType file_type,
- const lldb_private::FileSpec &file_spec);
-
- lldb_private::Error
- ExamineKextForMatchingUUID (const lldb_private::FileSpec &kext_bundle_path, const lldb_private::UUID &uuid, const lldb_private::ArchSpec &arch, lldb::ModuleSP &exe_module_sp);
-
-private:
-
- BundleIDToKextMap m_name_to_kext_path_map; // multimap of CFBundleID to FileSpec on local filesystem
- DirectoriesSearchedCollection m_search_directories; // list of directories we search for kexts/kernels
- KernelBinaryCollection m_kernel_binaries; // list of kernel binaries we found on local filesystem
- lldb_private::LazyBool m_ios_debug_session;
-
- DISALLOW_COPY_AND_ASSIGN (PlatformDarwinKernel);
+protected:
+ // Map from kext bundle ID ("com.apple.filesystems.exfat") to FileSpec for the
+ // kext bundle on
+ // the host ("/System/Library/Extensions/exfat.kext/Contents/Info.plist").
+ typedef std::multimap<lldb_private::ConstString, lldb_private::FileSpec>
+ BundleIDToKextMap;
+ typedef BundleIDToKextMap::iterator BundleIDToKextIterator;
+
+ typedef std::vector<lldb_private::FileSpec> KernelBinaryCollection;
+
+ // Array of directories that were searched for kext bundles (used only for
+ // reporting to user)
+ typedef std::vector<lldb_private::FileSpec> DirectoriesSearchedCollection;
+ typedef DirectoriesSearchedCollection::iterator DirectoriesSearchedIterator;
+
+ // Populate m_search_directories and m_search_directories_no_recursing vectors
+ // of directories
+ void CollectKextAndKernelDirectories();
+
+ void GetUserSpecifiedDirectoriesToSearch();
+
+ static void AddRootSubdirsToSearchPaths(PlatformDarwinKernel *thisp,
+ const std::string &dir);
+
+ void AddSDKSubdirsToSearchPaths(const std::string &dir);
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ FindKDKandSDKDirectoriesInDirectory(
+ void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &file_spec);
+
+ void SearchForKextsAndKernelsRecursively();
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ GetKernelsAndKextsInDirectoryWithRecursion(
+ void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &file_spec);
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ GetKernelsAndKextsInDirectoryNoRecursion(
+ void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &file_spec);
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ GetKernelsAndKextsInDirectoryHelper(
+ void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &file_spec, bool recurse);
+
+ static void AddKextToMap(PlatformDarwinKernel *thisp,
+ const lldb_private::FileSpec &file_spec);
+
+ // Returns true if there is a .dSYM bundle next to the kext, or next to the
+ // binary inside the kext.
+ static bool
+ KextHasdSYMSibling(const lldb_private::FileSpec &kext_bundle_filepath);
+
+ // Returns true if there is a .dSYM bundle next to the kernel
+ static bool
+ KernelHasdSYMSibling(const lldb_private::FileSpec &kext_bundle_filepath);
+
+ lldb_private::Error
+ ExamineKextForMatchingUUID(const lldb_private::FileSpec &kext_bundle_path,
+ const lldb_private::UUID &uuid,
+ const lldb_private::ArchSpec &arch,
+ lldb::ModuleSP &exe_module_sp);
+
+ // Most of the ivars are assembled under FileSpec::EnumerateDirectory calls
+ // where the
+ // function being called for each file/directory must be static. We'll pass a
+ // this pointer
+ // as a baton and access the ivars directly. Toss-up whether this should just
+ // be a struct
+ // at this point.
+public:
+ BundleIDToKextMap m_name_to_kext_path_map_with_dsyms; // multimap of
+ // CFBundleID to
+ // FileSpec on local
+ // filesystem, kexts
+ // with dSYMs next to
+ // them
+ BundleIDToKextMap m_name_to_kext_path_map_without_dsyms; // multimap of
+ // CFBundleID to
+ // FileSpec on local
+ // filesystem, kexts
+ // without dSYMs next
+ // to them
+ DirectoriesSearchedCollection
+ m_search_directories; // list of directories we search for kexts/kernels
+ DirectoriesSearchedCollection
+ m_search_directories_no_recursing; // list of directories we search for
+ // kexts/kernels, no recursion
+ KernelBinaryCollection m_kernel_binaries_with_dsyms; // list of kernel
+ // binaries we found on
+ // local filesystem,
+ // without dSYMs next to
+ // them
+ KernelBinaryCollection m_kernel_binaries_without_dsyms; // list of kernel
+ // binaries we found
+ // on local
+ // filesystem, with
+ // dSYMs next to them
+ lldb_private::LazyBool m_ios_debug_session;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformDarwinKernel);
};
-#else // __APPLE__
+#else // __APPLE__
// Since DynamicLoaderDarwinKernel is compiled in for all systems, and relies on
-// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name in
-// here to avoid issues. We are tracking an internal bug to resolve this issue by
-// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to make
-// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently not
+// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name
+// in
+// here to avoid issues. We are tracking an internal bug to resolve this issue
+// by
+// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to
+// make
+// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently
+// not
// compiled on other platforms due to the use of the Mac-specific
// source/Host/macosx/cfcpp utilities.
-class PlatformDarwinKernel
-{
- static lldb_private::ConstString
- GetPluginNameStatic ();
+class PlatformDarwinKernel {
+ static lldb_private::ConstString GetPluginNameStatic();
};
-#endif // __APPLE__
+#endif // __APPLE__
-#endif // liblldb_PlatformDarwinKernel_h_
+#endif // liblldb_PlatformDarwinKernel_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index 7e15facc1b03..0e7df95b5337 100644
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -17,8 +17,8 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -35,150 +35,128 @@
using namespace lldb;
using namespace lldb_private;
-
+
static uint32_t g_initialize_count = 0;
-void
-PlatformMacOSX::Initialize ()
-{
- PlatformDarwin::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
-#if defined (__APPLE__)
- PlatformSP default_platform_sp (new PlatformMacOSX(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform (default_platform_sp);
-#endif
- PluginManager::RegisterPlugin (PlatformMacOSX::GetPluginNameStatic(false),
- PlatformMacOSX::GetDescriptionStatic(false),
- PlatformMacOSX::CreateInstance);
- }
+void PlatformMacOSX::Initialize() {
+ PlatformDarwin::Initialize();
+ if (g_initialize_count++ == 0) {
+#if defined(__APPLE__)
+ PlatformSP default_platform_sp(new PlatformMacOSX(true));
+ default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+ Platform::SetHostPlatform(default_platform_sp);
+#endif
+ PluginManager::RegisterPlugin(PlatformMacOSX::GetPluginNameStatic(false),
+ PlatformMacOSX::GetDescriptionStatic(false),
+ PlatformMacOSX::CreateInstance);
+ }
}
-void
-PlatformMacOSX::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformMacOSX::CreateInstance);
- }
+void PlatformMacOSX::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformMacOSX::CreateInstance);
}
+ }
- PlatformDarwin::Terminate ();
+ PlatformDarwin::Terminate();
}
-PlatformSP
-PlatformMacOSX::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>";
+PlatformSP PlatformMacOSX::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>";
+ const char *triple_cstr =
+ arch ? arch->GetTriple().getTriple().c_str() : "<null>";
- log->Printf ("PlatformMacOSX::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
+ log->Printf("PlatformMacOSX::%s(force=%s, arch={%s,%s})", __FUNCTION__,
+ force ? "true" : "false", arch_name, triple_cstr);
+ }
+
+ // The only time we create an instance is when we are creating a remote
+ // macosx platform
+ const bool is_host = false;
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::Apple:
+ create = true;
+ break;
- // The only time we create an instance is when we are creating a remote
- // macosx platform
- const bool is_host = false;
-
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- case llvm::Triple::Apple:
- create = true;
- break;
-
#if defined(__APPLE__)
- // Only accept "unknown" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
-
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::Darwin: // Deprecated, but still support Darwin for historical reasons
- case llvm::Triple::MacOSX:
- break;
+ default:
+ break;
+ }
+
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
+ // historical reasons
+ case llvm::Triple::MacOSX:
+ break;
#if defined(__APPLE__)
- // Only accept "vendor" for vendor if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- 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)
+ case llvm::Triple::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
#endif
- default:
- create = false;
- break;
- }
- }
- }
- if (create)
- {
- if (log)
- log->Printf ("PlatformMacOSX::%s() creating platform", __FUNCTION__);
- return PlatformSP(new PlatformMacOSX (is_host));
+ default:
+ create = false;
+ break;
+ }
}
-
+ }
+ if (create) {
if (log)
- log->Printf ("PlatformMacOSX::%s() aborting creation of platform", __FUNCTION__);
+ log->Printf("PlatformMacOSX::%s() creating platform", __FUNCTION__);
+ return PlatformSP(new PlatformMacOSX(is_host));
+ }
- return PlatformSP();
+ if (log)
+ log->Printf("PlatformMacOSX::%s() aborting creation of platform",
+ __FUNCTION__);
+
+ return PlatformSP();
}
-lldb_private::ConstString
-PlatformMacOSX::GetPluginNameStatic (bool is_host)
-{
- if (is_host)
- {
- static ConstString g_host_name(Platform::GetHostPlatformName ());
- return g_host_name;
- }
- else
- {
- static ConstString g_remote_name("remote-macosx");
- return g_remote_name;
- }
+lldb_private::ConstString PlatformMacOSX::GetPluginNameStatic(bool is_host) {
+ if (is_host) {
+ static ConstString g_host_name(Platform::GetHostPlatformName());
+ return g_host_name;
+ } else {
+ static ConstString g_remote_name("remote-macosx");
+ return g_remote_name;
+ }
}
-const char *
-PlatformMacOSX::GetDescriptionStatic (bool is_host)
-{
- if (is_host)
- return "Local Mac OS X user platform plug-in.";
- else
- return "Remote Mac OS X user platform plug-in.";
+const char *PlatformMacOSX::GetDescriptionStatic(bool is_host) {
+ if (is_host)
+ return "Local Mac OS X user platform plug-in.";
+ else
+ return "Remote Mac OS X user platform plug-in.";
}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformMacOSX::PlatformMacOSX (bool is_host) :
- PlatformDarwin (is_host)
-{
-}
+PlatformMacOSX::PlatformMacOSX(bool is_host) : PlatformDarwin(is_host) {}
//------------------------------------------------------------------
/// Destructor.
@@ -186,201 +164,181 @@ PlatformMacOSX::PlatformMacOSX (bool is_host) :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformMacOSX::~PlatformMacOSX()
-{
-}
+PlatformMacOSX::~PlatformMacOSX() {}
-ConstString
-PlatformMacOSX::GetSDKDirectory (lldb_private::Target &target)
-{
- ModuleSP exe_module_sp (target.GetExecutableModule());
- if (exe_module_sp)
- {
- ObjectFile *objfile = exe_module_sp->GetObjectFile();
- if (objfile)
- {
- std::string xcode_contents_path;
- std::string default_xcode_sdk;
- FileSpec fspec;
- uint32_t versions[2];
- if (objfile->GetSDKVersion(versions, sizeof(versions)))
- {
- if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, fspec))
- {
- std::string path;
- xcode_contents_path = fspec.GetPath();
- size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
- if (pos != std::string::npos)
- {
- // LLDB.framework is inside an Xcode app bundle, we can locate the SDK from here
- xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/"));
- }
- else
- {
- xcode_contents_path.clear();
- // Use the selected Xcode
- int status = 0;
- int signo = 0;
- std::string output;
- const char *command = "xcrun -sdk macosx --show-sdk-path";
- lldb_private::Error error = RunShellCommand (command, // shell command to run
- NULL, // current working directory
- &status, // Put the exit status of the process in here
- &signo, // Put the signal that caused the process to exit in here
- &output, // Get the output from the command and place it in this string
- 3); // Timeout in seconds to wait for shell program to finish
- if (status == 0 && !output.empty())
- {
- size_t first_non_newline = output.find_last_not_of("\r\n");
- if (first_non_newline != std::string::npos)
- output.erase(first_non_newline+1);
- default_xcode_sdk = output;
-
- pos = default_xcode_sdk.find("/Xcode.app/Contents/");
- if (pos != std::string::npos)
- xcode_contents_path = default_xcode_sdk.substr(0, pos + strlen("/Xcode.app/Contents/"));
- }
- }
- }
-
- if (!xcode_contents_path.empty())
- {
- StreamString sdk_path;
- sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/SDKs/MacOSX%u.%u.sdk", xcode_contents_path.c_str(), versions[0], versions[1]);
- fspec.SetFile(sdk_path.GetString().c_str(), false);
- if (fspec.Exists())
- return ConstString(sdk_path.GetString().c_str());
- }
-
- if (!default_xcode_sdk.empty())
- {
- fspec.SetFile(default_xcode_sdk.c_str(), false);
- if (fspec.Exists())
- return ConstString(default_xcode_sdk.c_str());
- }
+ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
+ ModuleSP exe_module_sp(target.GetExecutableModule());
+ if (exe_module_sp) {
+ ObjectFile *objfile = exe_module_sp->GetObjectFile();
+ if (objfile) {
+ std::string xcode_contents_path;
+ std::string default_xcode_sdk;
+ FileSpec fspec;
+ uint32_t versions[2];
+ if (objfile->GetSDKVersion(versions, sizeof(versions))) {
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, fspec)) {
+ std::string path;
+ xcode_contents_path = fspec.GetPath();
+ size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
+ if (pos != std::string::npos) {
+ // LLDB.framework is inside an Xcode app bundle, we can locate the
+ // SDK from here
+ xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/"));
+ } else {
+ xcode_contents_path.clear();
+ // Use the selected Xcode
+ int status = 0;
+ int signo = 0;
+ std::string output;
+ const char *command = "xcrun -sdk macosx --show-sdk-path";
+ lldb_private::Error error = RunShellCommand(
+ command, // shell command to run
+ NULL, // current working directory
+ &status, // Put the exit status of the process in here
+ &signo, // Put the signal that caused the process to exit in
+ // here
+ &output, // Get the output from the command and place it in this
+ // string
+ 3); // Timeout in seconds to wait for shell program to finish
+ if (status == 0 && !output.empty()) {
+ size_t first_non_newline = output.find_last_not_of("\r\n");
+ if (first_non_newline != std::string::npos)
+ output.erase(first_non_newline + 1);
+ default_xcode_sdk = output;
+
+ pos = default_xcode_sdk.find("/Xcode.app/Contents/");
+ if (pos != std::string::npos)
+ xcode_contents_path = default_xcode_sdk.substr(
+ 0, pos + strlen("/Xcode.app/Contents/"));
}
+ }
}
- }
- return ConstString();
-}
+ if (!xcode_contents_path.empty()) {
+ StreamString sdk_path;
+ sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/"
+ "SDKs/MacOSX%u.%u.sdk",
+ xcode_contents_path.c_str(), versions[0],
+ versions[1]);
+ fspec.SetFile(sdk_path.GetString(), false);
+ if (fspec.Exists())
+ return ConstString(sdk_path.GetString());
+ }
-Error
-PlatformMacOSX::GetSymbolFile (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
+ if (!default_xcode_sdk.empty()) {
+ fspec.SetFile(default_xcode_sdk, false);
+ if (fspec.Exists())
+ return ConstString(default_xcode_sdk);
+ }
+ }
}
+ }
+ return ConstString();
+}
+
+Error PlatformMacOSX::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ if (IsRemote()) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
+ local_file);
+ }
- // Default to the local case
- local_file = platform_file;
- return Error();
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
}
lldb_private::Error
-PlatformMacOSX::GetFileWithUUID (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file)
-{
- if (IsRemote() && m_remote_platform_sp)
- {
- std::string local_os_build;
+PlatformMacOSX::GetFileWithUUID(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file) {
+ if (IsRemote() && m_remote_platform_sp) {
+ std::string local_os_build;
#if !defined(__linux__)
- HostInfo::GetOSBuildString(local_os_build);
+ HostInfo::GetOSBuildString(local_os_build);
#endif
- std::string remote_os_build;
- m_remote_platform_sp->GetOSBuildString(remote_os_build);
- if (local_os_build.compare(remote_os_build) == 0)
- {
- // same OS version: the local file is good enough
- local_file = platform_file;
- return Error();
- }
- else
- {
- // try to find the file in the cache
- std::string cache_path(GetLocalCacheDirectory());
- std::string module_path (platform_file.GetPath());
- cache_path.append(module_path);
- FileSpec module_cache_spec(cache_path.c_str(),false);
- if (module_cache_spec.Exists())
- {
- local_file = module_cache_spec;
- return Error();
- }
- // bring in the remote module file
- FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
- // try to make the local directory first
- Error err =
- FileSystem::MakeDirectory(module_cache_folder, eFilePermissionsDirectoryDefault);
- if (err.Fail())
- return err;
- err = GetFile(platform_file, module_cache_spec);
- if (err.Fail())
- return err;
- if (module_cache_spec.Exists())
- {
- local_file = module_cache_spec;
- return Error();
- }
- else
- return Error("unable to obtain valid module file");
- }
+ std::string remote_os_build;
+ m_remote_platform_sp->GetOSBuildString(remote_os_build);
+ if (local_os_build.compare(remote_os_build) == 0) {
+ // same OS version: the local file is good enough
+ local_file = platform_file;
+ return Error();
+ } else {
+ // try to find the file in the cache
+ 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()) {
+ local_file = module_cache_spec;
+ return Error();
+ }
+ // bring in the remote module file
+ FileSpec module_cache_folder =
+ module_cache_spec.CopyByRemovingLastPathComponent();
+ // try to make the local directory first
+ Error err = FileSystem::MakeDirectory(module_cache_folder,
+ eFilePermissionsDirectoryDefault);
+ if (err.Fail())
+ return err;
+ err = GetFile(platform_file, module_cache_spec);
+ if (err.Fail())
+ return err;
+ if (module_cache_spec.Exists()) {
+ local_file = module_cache_spec;
+ return Error();
+ } else
+ return Error("unable to obtain valid module file");
}
- local_file = platform_file;
- return Error();
+ }
+ local_file = platform_file;
+ return Error();
}
-bool
-PlatformMacOSX::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
-#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
- return ARMGetSupportedArchitectureAtIndex (idx, arch);
+bool PlatformMacOSX::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ return ARMGetSupportedArchitectureAtIndex(idx, arch);
#else
- return x86GetSupportedArchitectureAtIndex (idx, arch);
+ return x86GetSupportedArchitectureAtIndex(idx, arch);
#endif
}
-lldb_private::Error
-PlatformMacOSX::GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- Error error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
-
- if (module_sp)
- {
- if (module_spec.GetArchitecture().GetCore() == ArchSpec::eCore_x86_64_x86_64h)
- {
- ObjectFile *objfile = module_sp->GetObjectFile();
- if (objfile == NULL)
- {
- // We didn't find an x86_64h slice, fall back to a x86_64 slice
- ModuleSpec module_spec_x86_64 (module_spec);
- module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx");
- lldb::ModuleSP x86_64_module_sp;
- lldb::ModuleSP old_x86_64_module_sp;
- bool did_create = false;
- Error x86_64_error = GetSharedModuleWithLocalCache(module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr, &old_x86_64_module_sp, &did_create);
- if (x86_64_module_sp && x86_64_module_sp->GetObjectFile())
- {
- module_sp = x86_64_module_sp;
- if (old_module_sp_ptr)
- *old_module_sp_ptr = old_x86_64_module_sp;
- if (did_create_ptr)
- *did_create_ptr = did_create;
- return x86_64_error;
- }
- }
+lldb_private::Error PlatformMacOSX::GetSharedModule(
+ const lldb_private::ModuleSpec &module_spec, Process *process,
+ lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
+ Error error = GetSharedModuleWithLocalCache(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr);
+
+ if (module_sp) {
+ if (module_spec.GetArchitecture().GetCore() ==
+ ArchSpec::eCore_x86_64_x86_64h) {
+ ObjectFile *objfile = module_sp->GetObjectFile();
+ if (objfile == NULL) {
+ // We didn't find an x86_64h slice, fall back to a x86_64 slice
+ ModuleSpec module_spec_x86_64(module_spec);
+ module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx");
+ lldb::ModuleSP x86_64_module_sp;
+ lldb::ModuleSP old_x86_64_module_sp;
+ bool did_create = false;
+ Error x86_64_error = GetSharedModuleWithLocalCache(
+ module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr,
+ &old_x86_64_module_sp, &did_create);
+ if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) {
+ module_sp = x86_64_module_sp;
+ if (old_module_sp_ptr)
+ *old_module_sp_ptr = old_x86_64_module_sp;
+ if (did_create_ptr)
+ *did_create_ptr = did_create;
+ return x86_64_error;
}
+ }
}
- return error;
+ }
+ return error;
}
-
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
index 10e177ea6362..d5b5d69f1fb3 100644
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
@@ -16,89 +16,76 @@
// Project includes
#include "PlatformDarwin.h"
-class PlatformMacOSX : public PlatformDarwin
-{
+class PlatformMacOSX : public PlatformDarwin {
public:
- PlatformMacOSX(bool is_host);
-
- ~PlatformMacOSX() override;
-
- //------------------------------------------------------------
- // Class functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance (bool force, const lldb_private::ArchSpec *arch);
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb_private::ConstString
- GetPluginNameStatic (bool is_host);
-
- static const char *
- GetDescriptionStatic(bool is_host);
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic (IsHost());
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic (IsHost());
- }
-
- lldb_private::Error
- GetSymbolFile (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetFile (const lldb_private::FileSpec& source,
- const lldb_private::FileSpec& destination) override
- {
- return PlatformDarwin::GetFile (source,destination);
- }
-
- lldb_private::Error
- GetFileWithUUID (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file) override;
-
- bool GetSupportedArchitectureAtIndex(uint32_t idx, lldb_private::ArchSpec &arch) override;
-
- lldb_private::ConstString GetSDKDirectory(lldb_private::Target &target) override;
-
- void
- AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override
- {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::MacOSX);
- }
+ PlatformMacOSX(bool is_host);
+
+ ~PlatformMacOSX() override;
+
+ //------------------------------------------------------------
+ // Class functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic(bool is_host);
+
+ static const char *GetDescriptionStatic(bool is_host);
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic(IsHost());
+ }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ const char *GetDescription() override {
+ return GetDescriptionStatic(IsHost());
+ }
+
+ lldb_private::Error GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetFile(const lldb_private::FileSpec &source,
+ const lldb_private::FileSpec &destination) override {
+ return PlatformDarwin::GetFile(source, destination);
+ }
+
+ lldb_private::Error
+ GetFileWithUUID(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+ lldb_private::ConstString
+ GetSDKDirectory(lldb_private::Target &target) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::MacOSX);
+ }
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformMacOSX);
+ DISALLOW_COPY_AND_ASSIGN(PlatformMacOSX);
};
#endif // liblldb_PlatformMacOSX_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
index 30af2bb2250b..47b1c8f07dfa 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
@@ -36,38 +36,22 @@ using namespace lldb_private;
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformRemoteAppleTV::PlatformRemoteAppleTV () :
- PlatformDarwin (false), // This is a remote platform
- m_sdk_directory_infos(),
- m_device_support_directory(),
- m_device_support_directory_for_os_version (),
- m_build_update(),
- m_last_module_sdk_idx (UINT32_MAX),
- m_connected_module_sdk_idx (UINT32_MAX)
-{
-}
-
-PlatformRemoteAppleTV::SDKDirectoryInfo::SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir) :
- directory(sdk_dir),
- build(),
- version_major(0),
- version_minor(0),
- version_update(0),
- user_cached(false)
-{
- const char *dirname_cstr = sdk_dir.GetFilename().GetCString();
- const char *pos = Args::StringToVersion (dirname_cstr,
- version_major,
- version_minor,
- version_update);
-
- if (pos && pos[0] == ' ' && pos[1] == '(')
- {
- const char *build_start = pos + 2;
- const char *end_paren = strchr (build_start, ')');
- if (end_paren && build_start < end_paren)
- build.SetCStringWithLength(build_start, end_paren - build_start);
- }
+PlatformRemoteAppleTV::PlatformRemoteAppleTV()
+ : PlatformDarwin(false), // This is a remote platform
+ m_sdk_directory_infos(), m_device_support_directory(),
+ m_device_support_directory_for_os_version(), m_build_update(),
+ m_last_module_sdk_idx(UINT32_MAX),
+ m_connected_module_sdk_idx(UINT32_MAX) {}
+
+PlatformRemoteAppleTV::SDKDirectoryInfo::SDKDirectoryInfo(
+ const lldb_private::FileSpec &sdk_dir)
+ : directory(sdk_dir), build(), version_major(0), version_minor(0),
+ version_update(0), user_cached(false) {
+ llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
+ llvm::StringRef build_str;
+ std::tie(version_major, version_minor, version_update, build_str) =
+ ParseVersionBuildDir(dirname_str);
+ build.SetString(build_str);
}
//------------------------------------------------------------------
@@ -78,973 +62,835 @@ static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformRemoteAppleTV::Initialize ()
-{
- PlatformDarwin::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin (PlatformRemoteAppleTV::GetPluginNameStatic(),
- PlatformRemoteAppleTV::GetDescriptionStatic(),
- PlatformRemoteAppleTV::CreateInstance);
- }
+void PlatformRemoteAppleTV::Initialize() {
+ PlatformDarwin::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(PlatformRemoteAppleTV::GetPluginNameStatic(),
+ PlatformRemoteAppleTV::GetDescriptionStatic(),
+ PlatformRemoteAppleTV::CreateInstance);
+ }
}
-void
-PlatformRemoteAppleTV::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformRemoteAppleTV::CreateInstance);
- }
+void PlatformRemoteAppleTV::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformRemoteAppleTV::CreateInstance);
}
+ }
- PlatformDarwin::Terminate ();
+ PlatformDarwin::Terminate();
}
-PlatformSP
-PlatformRemoteAppleTV::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 ("PlatformRemoteAppleTV::%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::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb:
- {
- const llvm::Triple &triple = arch->GetTriple();
- llvm::Triple::VendorType vendor = triple.getVendor();
- switch (vendor)
- {
- case llvm::Triple::Apple:
- create = true;
- break;
+PlatformSP PlatformRemoteAppleTV::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("PlatformRemoteAppleTV::%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::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::thumb: {
+ 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::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for the vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::TvOS: // This is the right triple value for Apple TV debugging
- break;
-
- default:
- create = false;
- break;
- }
- }
- }
- break;
+ default:
+ break;
+ }
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::TvOS: // This is the right triple value for Apple TV
+ // debugging
+ break;
+
default:
- break;
+ create = false;
+ break;
}
+ }
+ } break;
+ default:
+ break;
}
+ }
- if (create)
- {
- if (log)
- log->Printf ("PlatformRemoteAppleTV::%s() creating platform", __FUNCTION__);
+ if (create) {
+ if (log)
+ log->Printf("PlatformRemoteAppleTV::%s() creating platform",
+ __FUNCTION__);
- return lldb::PlatformSP(new PlatformRemoteAppleTV ());
- }
+ return lldb::PlatformSP(new PlatformRemoteAppleTV());
+ }
- if (log)
- log->Printf ("PlatformRemoteAppleTV::%s() aborting creation of platform", __FUNCTION__);
+ if (log)
+ log->Printf("PlatformRemoteAppleTV::%s() aborting creation of platform",
+ __FUNCTION__);
- return lldb::PlatformSP();
+ return lldb::PlatformSP();
}
-lldb_private::ConstString
-PlatformRemoteAppleTV::GetPluginNameStatic ()
-{
- static ConstString g_name("remote-tvos");
- return g_name;
+lldb_private::ConstString PlatformRemoteAppleTV::GetPluginNameStatic() {
+ static ConstString g_name("remote-tvos");
+ return g_name;
}
-const char *
-PlatformRemoteAppleTV::GetDescriptionStatic()
-{
- return "Remote Apple TV platform plug-in.";
+const char *PlatformRemoteAppleTV::GetDescriptionStatic() {
+ return "Remote Apple TV platform plug-in.";
}
-void
-PlatformRemoteAppleTV::GetStatus (Stream &strm)
-{
- Platform::GetStatus (strm);
- const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
- if (sdk_directory)
- strm.Printf (" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString (" SDK Path: error: unable to locate SDK\n");
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- strm.Printf (" SDK Roots: [%2u] \"%s\"\n",
- i,
- sdk_dir_info.directory.GetPath().c_str());
- }
+void PlatformRemoteAppleTV::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
+ if (sdk_directory)
+ strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
+ else
+ strm.PutCString(" SDK Path: error: unable to locate SDK\n");
+
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
+ sdk_dir_info.directory.GetPath().c_str());
+ }
}
-Error
-PlatformRemoteAppleTV::ResolveExecutable (const ModuleSpec &ms,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(ms);
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one ourselves
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
- {
- error = ModuleList::GetSharedModule(resolved_module_spec,
- exe_module_sp,
- nullptr,
- nullptr,
- nullptr);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule(resolved_module_spec,
- exe_module_sp,
- nullptr,
- nullptr,
- nullptr);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+Error PlatformRemoteAppleTV::ResolveExecutable(
+ const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(ms);
+
+ // Resolve any executable within a bundle on MacOSX
+ // TODO: verify that this handles shallow bundles, if not then implement one
+ // ourselves
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (resolved_module_spec.GetArchitecture().IsValid() ||
+ resolved_module_spec.GetUUID().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ nullptr, nullptr, nullptr);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
}
- else
- {
- error.SetErrorStringWithFormat ("'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
+ // No valid architecture was specified or the exact ARM slice wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ nullptr, nullptr, nullptr);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
}
- return error;
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' does not exist",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+
+ return error;
}
-FileSpec::EnumerateDirectoryResult
-PlatformRemoteAppleTV::GetContainedFilesIntoVectorOfStringsCallback (void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- ((PlatformRemoteAppleTV::SDKDirectoryInfoCollection *)baton)->push_back(PlatformRemoteAppleTV::SDKDirectoryInfo(file_spec));
- return FileSpec::eEnumerateDirectoryResultNext;
+FileSpec::EnumerateDirectoryResult
+PlatformRemoteAppleTV::GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) {
+ ((PlatformRemoteAppleTV::SDKDirectoryInfoCollection *)baton)
+ ->push_back(PlatformRemoteAppleTV::SDKDirectoryInfo(file_spec));
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-bool
-PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded()
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (m_sdk_directory_infos.empty())
- {
- const char *device_support_dir = GetDeviceSupportDirectory();
- if (log)
- {
- log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded Got DeviceSupport directory %s", device_support_dir);
+bool PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded() {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
+ if (m_sdk_directory_infos.empty()) {
+ const char *device_support_dir = GetDeviceSupportDirectory();
+ if (log) {
+ log->Printf("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded Got "
+ "DeviceSupport directory %s",
+ device_support_dir);
+ }
+ if (device_support_dir) {
+ const bool find_directories = true;
+ const bool find_files = false;
+ 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);
+
+ // Only add SDK directories that have symbols in them, some SDKs only
+ // contain
+ // developer disk images and no symbols, so they aren't useful to us.
+ FileSpec sdk_symbols_symlink_fspec;
+ for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
+ sdk_symbols_symlink_fspec = sdk_directory_info.directory;
+ sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
+ if (sdk_symbols_symlink_fspec.Exists()) {
+ m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteAppleTV::"
+ "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
+ "directory %s",
+ sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
+ } else {
+ sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
+ if (sdk_symbols_symlink_fspec.Exists())
+ m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteAppleTV::"
+ "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
+ "directory %s",
+ sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
}
- if (device_support_dir)
- {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
-
- SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSpec::EnumerateDirectory (m_device_support_directory.c_str(),
- 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 us.
- FileSpec sdk_symbols_symlink_fspec;
- for (const auto &sdk_directory_info : builtin_sdk_directory_infos)
- {
- sdk_symbols_symlink_fspec = sdk_directory_info.directory;
- sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
- if (sdk_symbols_symlink_fspec.Exists())
- {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log)
- {
- log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- else
- {
- sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
- if (sdk_symbols_symlink_fspec.Exists())
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log)
- {
- log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
-
- const uint32_t num_installed = m_sdk_directory_infos.size();
- FileSpec local_sdk_cache("~/Library/Developer/Xcode/tvOS DeviceSupport", true);
- if (!local_sdk_cache.Exists())
- {
- // Try looking for another possible name
- local_sdk_cache = FileSpec("~/Library/Developer/Xcode/Apple TVOS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists())
- {
- // Try looking for another possible name
- local_sdk_cache = FileSpec("~/Library/Developer/Xcode/AppleTVOS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists())
- {
- // Try looking for another possible name
- local_sdk_cache = FileSpec("~/Library/Developer/Xcode/AppleTV OS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists())
- {
- // Try looking for another possible name
- local_sdk_cache = FileSpec("~/Library/Developer/Xcode/Apple TV OS DeviceSupport", true);
- }
- if (local_sdk_cache.Exists())
- {
- if (log)
- {
- log->Printf ("PlatformRemoteAppleTV::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)
- {
- m_sdk_directory_infos[i].user_cached = true;
- if (log)
- {
- log->Printf ("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded user SDK directory %s", m_sdk_directory_infos[i].directory.GetPath().c_str());
- }
- }
- }
+ }
+
+ const uint32_t num_installed = m_sdk_directory_infos.size();
+ FileSpec local_sdk_cache("~/Library/Developer/Xcode/tvOS DeviceSupport",
+ true);
+ if (!local_sdk_cache.Exists()) {
+ // Try looking for another possible name
+ local_sdk_cache = FileSpec(
+ "~/Library/Developer/Xcode/Apple TVOS DeviceSupport", true);
+ }
+ if (!local_sdk_cache.Exists()) {
+ // Try looking for another possible name
+ local_sdk_cache =
+ FileSpec("~/Library/Developer/Xcode/AppleTVOS DeviceSupport", true);
+ }
+ if (!local_sdk_cache.Exists()) {
+ // Try looking for another possible name
+ local_sdk_cache = FileSpec(
+ "~/Library/Developer/Xcode/AppleTV OS DeviceSupport", true);
+ }
+ if (!local_sdk_cache.Exists()) {
+ // Try looking for another possible name
+ local_sdk_cache = FileSpec(
+ "~/Library/Developer/Xcode/Apple TV OS DeviceSupport", true);
+ }
+ if (local_sdk_cache.Exists()) {
+ if (log) {
+ log->Printf("PlatformRemoteAppleTV::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) {
+ m_sdk_directory_infos[i].user_cached = true;
+ if (log) {
+ log->Printf("PlatformRemoteAppleTV::"
+ "UpdateSDKDirectoryInfosIfNeeded user SDK directory "
+ "%s",
+ m_sdk_directory_infos[i].directory.GetPath().c_str());
}
+ }
}
+ }
}
- return !m_sdk_directory_infos.empty();
+ }
+ return !m_sdk_directory_infos.empty();
}
const PlatformRemoteAppleTV::SDKDirectoryInfo *
-PlatformRemoteAppleTV::GetSDKDirectoryForCurrentOSVersion ()
-{
- uint32_t i;
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+PlatformRemoteAppleTV::GetSDKDirectoryForCurrentOSVersion() {
+ uint32_t i;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+
+ // Check to see if the user specified a build string. If they did, then
+ // be sure to match it.
+ std::vector<bool> check_sdk_info(num_sdk_infos, true);
+ ConstString build(m_sdk_build);
+ if (build) {
+ for (i = 0; i < num_sdk_infos; ++i)
+ check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
+ }
- // Check to see if the user specified a build string. If they did, then
- // be sure to match it.
- std::vector<bool> check_sdk_info(num_sdk_infos, true);
- ConstString build(m_sdk_build);
- if (build)
- {
- for (i=0; i<num_sdk_infos; ++i)
- check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
+ // If we are connected we can find the version of the OS the platform
+ // us running on and select the right SDK
+ uint32_t major, minor, update;
+ if (GetOSVersion(major, minor, update)) {
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ // First try for an exact match of major, minor and update
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor &&
+ m_sdk_directory_infos[i].version_update == update) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
}
-
- // If we are connected we can find the version of the OS the platform
- // us running on and select the right SDK
- uint32_t major, minor, update;
- if (GetOSVersion(major, minor, update))
- {
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- // First try for an exact match of major, minor and update
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor &&
- m_sdk_directory_infos[i].version_update == update)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // First try for an exact match of major and minor
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // Lastly try to match of major version only..
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
+ // First try for an exact match of major and minor
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor) {
+ return &m_sdk_directory_infos[i];
}
+ }
}
- else if (build)
- {
- // No version, just a build number, search for the first one that matches
- for (i=0; i<num_sdk_infos; ++i)
- if (check_sdk_info[i])
- return &m_sdk_directory_infos[i];
+ // Lastly try to match of major version only..
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
}
+ }
+ } else if (build) {
+ // No version, just a build number, search for the first one that matches
+ for (i = 0; i < num_sdk_infos; ++i)
+ if (check_sdk_info[i])
+ return &m_sdk_directory_infos[i];
}
- return nullptr;
+ }
+ return nullptr;
}
const PlatformRemoteAppleTV::SDKDirectoryInfo *
-PlatformRemoteAppleTV::GetSDKDirectoryForLatestOSVersion ()
-{
- const PlatformRemoteAppleTV::SDKDirectoryInfo *result = nullptr;
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (sdk_dir_info.version_major != UINT32_MAX)
- {
- if (result == nullptr || sdk_dir_info.version_major > result->version_major)
- {
- result = &sdk_dir_info;
- }
- else if (sdk_dir_info.version_major == result->version_major)
- {
- if (sdk_dir_info.version_minor > result->version_minor)
- {
- result = &sdk_dir_info;
- }
- else if (sdk_dir_info.version_minor == result->version_minor)
- {
- if (sdk_dir_info.version_update > result->version_update)
- {
- result = &sdk_dir_info;
- }
- }
- }
+PlatformRemoteAppleTV::GetSDKDirectoryForLatestOSVersion() {
+ const PlatformRemoteAppleTV::SDKDirectoryInfo *result = nullptr;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ // First try for an exact match of major, minor and update
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (sdk_dir_info.version_major != UINT32_MAX) {
+ if (result == nullptr ||
+ sdk_dir_info.version_major > result->version_major) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_major == result->version_major) {
+ if (sdk_dir_info.version_minor > result->version_minor) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_minor == result->version_minor) {
+ if (sdk_dir_info.version_update > result->version_update) {
+ result = &sdk_dir_info;
}
+ }
}
+ }
}
- return result;
+ }
+ return result;
}
-const char *
-PlatformRemoteAppleTV::GetDeviceSupportDirectory()
-{
- if (m_device_support_directory.empty())
- {
- const char *device_support_dir = GetDeveloperDirectory();
- if (device_support_dir)
- {
- m_device_support_directory.assign (device_support_dir);
- m_device_support_directory.append ("/Platforms/AppleTVOS.platform/DeviceSupport");
- }
- else
- {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory.assign (1, '\0');
- }
+const char *PlatformRemoteAppleTV::GetDeviceSupportDirectory() {
+ if (m_device_support_directory.empty()) {
+ const char *device_support_dir = GetDeveloperDirectory();
+ if (device_support_dir) {
+ m_device_support_directory.assign(device_support_dir);
+ m_device_support_directory.append(
+ "/Platforms/AppleTVOS.platform/DeviceSupport");
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory.assign(1, '\0');
}
- // We should have put a single NULL character into m_device_support_directory
- // or it should have a valid path if the code gets here
- assert (m_device_support_directory.empty() == false);
- if (m_device_support_directory[0])
- return m_device_support_directory.c_str();
- return nullptr;
+ }
+ // We should have put a single NULL character into m_device_support_directory
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory.empty() == false);
+ if (m_device_support_directory[0])
+ return m_device_support_directory.c_str();
+ return nullptr;
}
-
-const char *
-PlatformRemoteAppleTV::GetDeviceSupportDirectoryForOSVersion()
-{
- if (m_sdk_sysroot)
- return m_sdk_sysroot.GetCString();
-
- if (m_device_support_directory_for_os_version.empty())
- {
- const PlatformRemoteAppleTV::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion ();
- if (sdk_dir_info == nullptr)
- sdk_dir_info = GetSDKDirectoryForLatestOSVersion ();
- if (sdk_dir_info)
- {
- char path[PATH_MAX];
- if (sdk_dir_info->directory.GetPath(path, sizeof(path)))
- {
- m_device_support_directory_for_os_version = path;
- return m_device_support_directory_for_os_version.c_str();
- }
- }
- else
- {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory_for_os_version.assign (1, '\0');
- }
- }
- // We should have put a single NULL character into m_device_support_directory_for_os_version
- // or it should have a valid path if the code gets here
- assert (m_device_support_directory_for_os_version.empty() == false);
- if (m_device_support_directory_for_os_version[0])
+
+const char *PlatformRemoteAppleTV::GetDeviceSupportDirectoryForOSVersion() {
+ if (m_sdk_sysroot)
+ return m_sdk_sysroot.GetCString();
+
+ if (m_device_support_directory_for_os_version.empty()) {
+ const PlatformRemoteAppleTV::SDKDirectoryInfo *sdk_dir_info =
+ GetSDKDirectoryForCurrentOSVersion();
+ if (sdk_dir_info == nullptr)
+ sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
+ if (sdk_dir_info) {
+ char path[PATH_MAX];
+ if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
+ m_device_support_directory_for_os_version = path;
return m_device_support_directory_for_os_version.c_str();
- return nullptr;
+ }
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory_for_os_version.assign(1, '\0');
+ }
+ }
+ // We should have put a single NULL character into
+ // m_device_support_directory_for_os_version
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory_for_os_version.empty() == false);
+ if (m_device_support_directory_for_os_version[0])
+ return m_device_support_directory_for_os_version.c_str();
+ return nullptr;
}
uint32_t
-PlatformRemoteAppleTV::FindFileInAllSDKs (const char *platform_file_path,
- FileSpecList &file_list)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
- if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- lldb_private::FileSpec local_file;
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path,
- sdk_idx,
- local_file))
- {
- file_list.Append(local_file);
- }
- }
+PlatformRemoteAppleTV::FindFileInAllSDKs(const char *platform_file_path,
+ FileSpecList &file_list) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_VERBOSE);
+ if (platform_file_path && platform_file_path[0] &&
+ UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ lldb_private::FileSpec local_file;
+ // First try for an exact match of major, minor and update
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
+ if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
+ file_list.Append(local_file);
+ }
}
- return file_list.GetSize();
+ }
+ return file_list.GetSize();
}
-bool
-PlatformRemoteAppleTV::GetFileInSDK (const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file)
-{
- if (sdk_idx < m_sdk_directory_infos.size())
- {
- char sdkroot_path[PATH_MAX];
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx];
- if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path)))
- {
- const bool symbols_dirs_only = true;
-
- return GetFileInSDKRoot (platform_file_path,
- sdkroot_path,
- symbols_dirs_only,
- local_file);
+bool PlatformRemoteAppleTV::GetFileInSDK(const char *platform_file_path,
+ uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (sdk_idx < m_sdk_directory_infos.size()) {
+ std::string sdkroot_path =
+ m_sdk_directory_infos[sdk_idx].directory.GetPath();
+ if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
+ // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
+ // the
+ // SDK root directory and the 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);
+ 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()) {
+ if (log)
+ log->Printf("Found a copy of %s in the SDK dir %s/%s",
+ platform_file_path, sdkroot_path.c_str(),
+ paths_to_try[i]);
+ return true;
}
+ local_file.Clear();
+ }
}
- return false;
+ }
+ return false;
}
-bool
-PlatformRemoteAppleTV::GetFileInSDKRoot (const char *platform_file_path,
- const char *sdkroot_path,
- bool symbols_dirs_only,
- lldb_private::FileSpec &local_file)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
- {
- char resolved_path[PATH_MAX];
-
- if (!symbols_dirs_only)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path);
- }
- return true;
- }
+Error PlatformRemoteAppleTV::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ Error error;
+ char platform_file_path[PATH_MAX];
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ char resolved_path[PATH_MAX];
+
+ const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
+ if (os_version_dir) {
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
+ platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s",
+ platform_file_path, os_version_dir);
}
-
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols.Internal%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path);
- }
- return true;
+ return error;
+ }
+
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
+ os_version_dir, platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf(
+ "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
+ platform_file_path, os_version_dir);
}
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path);
- }
- return true;
+ return error;
+ }
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
+ os_version_dir, platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
+ platform_file_path, os_version_dir);
}
+ return error;
+ }
}
- return false;
+ local_file = platform_file;
+ if (local_file.Exists())
+ return error;
+
+ error.SetErrorStringWithFormat(
+ "unable to locate a platform file for '%s' in platform '%s'",
+ platform_file_path, GetPluginName().GetCString());
+ } else {
+ error.SetErrorString("invalid platform file argument");
+ }
+ return error;
}
-Error
-PlatformRemoteAppleTV::GetSymbolFile (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- char resolved_path[PATH_MAX];
-
- const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion();
- if (os_version_dir)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir);
- }
- return error;
- }
+Error PlatformRemoteAppleTV::GetSharedModule(
+ const ModuleSpec &module_spec, lldb_private::Process *process,
+ ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
+ ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
+ // For Apple TV, the SDK files are all cached locally on the host
+ // system. So first we ask for the file in the cached SDK,
+ // then we attempt to get a shared module for the right architecture
+ // with the right UUID.
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_VERBOSE);
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols.Internal/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir);
- }
- return error;
- }
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir);
- }
- return error;
- }
- }
- local_file = platform_file;
- if (local_file.Exists())
- return error;
+ Error error;
+ char platform_file_path[PATH_MAX];
- error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path,
- GetPluginName().GetCString());
- }
- else
- {
- error.SetErrorString ("invalid platform file argument");
- }
- return error;
-}
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ ModuleSpec platform_module_spec(module_spec);
-Error
-PlatformRemoteAppleTV::GetSharedModule (const ModuleSpec &module_spec,
- lldb_private::Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- // For Apple TV, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- const FileSpec &platform_file = module_spec.GetFileSpec();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
-
- Error error;
- char platform_file_path[PATH_MAX];
-
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- ModuleSpec platform_module_spec(module_spec);
-
- UpdateSDKDirectoryInfosIfNeeded();
+ UpdateSDKDirectoryInfosIfNeeded();
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // If we are connected we migth be able to correctly deduce the SDK directory
- // using the OS build.
- const uint32_t connected_sdk_idx = GetConnectedSDKIndex ();
- if (connected_sdk_idx < num_sdk_infos)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec()))
- {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec,
- module_sp,
- nullptr);
- if (module_sp)
- {
- m_last_module_sdk_idx = connected_sdk_idx;
- error.Clear();
- return error;
- }
- }
+ // If we are connected we migth be able to correctly deduce the SDK
+ // directory
+ // using the OS build.
+ const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
+ if (connected_sdk_idx < num_sdk_infos) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[connected_sdk_idx]
+ .directory.GetPath()
+ .c_str());
+ }
+ if (GetFileInSDK(platform_file_path, connected_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
+ if (module_sp) {
+ m_last_module_sdk_idx = connected_sdk_idx;
+ error.Clear();
+ return error;
}
+ }
+ }
- // Try the last SDK index if it is set as most files from an SDK
- // will tend to be valid in that same SDK.
- if (m_last_module_sdk_idx < num_sdk_infos)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec()))
- {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec,
- module_sp,
- nullptr);
- if (module_sp)
- {
- error.Clear();
- return error;
- }
- }
- }
-
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
- {
- if (m_last_module_sdk_idx == sdk_idx)
- {
- // Skip the last module SDK index if we already searched
- // it above
- continue;
- }
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec()))
- {
- //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
-
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp)
- {
- // Remember the index of the last SDK that we found a file
- // in in case the wrong SDK was selected.
- m_last_module_sdk_idx = sdk_idx;
- error.Clear();
- return error;
- }
- }
+ // Try the last SDK index if it is set as most files from an SDK
+ // will tend to be valid in that same SDK.
+ if (m_last_module_sdk_idx < num_sdk_infos) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[m_last_module_sdk_idx]
+ .directory.GetPath()
+ .c_str());
+ }
+ if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
+ if (module_sp) {
+ error.Clear();
+ return error;
}
+ }
}
- // Not the module we are looking for... Nothing to see here...
- module_sp.reset();
- // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache.
- error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
- if (error.Success())
- return error;
+ // First try for an exact match of major, minor and update
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ if (m_last_module_sdk_idx == sdk_idx) {
+ // Skip the last module SDK index if we already searched
+ // it above
+ continue;
+ }
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
+ if (GetFileInSDK(platform_file_path, sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
+
+ error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
+ if (module_sp) {
+ // Remember the index of the last SDK that we found a file
+ // in in case the wrong SDK was selected.
+ m_last_module_sdk_idx = sdk_idx;
+ error.Clear();
+ return error;
+ }
+ }
+ }
+ }
+ // Not the module we are looking for... Nothing to see here...
+ module_sp.reset();
+
+ // This may not be an SDK-related module. Try whether we can bring in the
+ // thing to our local cache.
+ error = GetSharedModuleWithLocalCache(module_spec, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+ if (error.Success())
+ return error;
- // See if the file is present in any of the module_search_paths_ptr directories.
- if (!module_sp && module_search_paths_ptr && platform_file)
- {
- // create a vector of all the file / directory names in platform_file
- // e.g. this might be /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // See if the file is present in any of the module_search_paths_ptr
+ // directories.
+ if (!module_sp && module_search_paths_ptr && platform_file) {
+ // create a vector of all the file / directory names in platform_file
+ // e.g. this might be
+ // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ //
+ // We'll need to look in the module_search_paths_ptr directories for
+ // both "UIFoundation" and "UIFoundation.framework" -- most likely the
+ // latter will be the one we find there.
+
+ FileSpec platform_pull_apart(platform_file);
+ std::vector<std::string> path_parts;
+ ConstString unix_root_dir("/");
+ while (true) {
+ ConstString part = platform_pull_apart.GetLastPathComponent();
+ platform_pull_apart.RemoveLastPathComponent();
+ if (part.IsEmpty() || part == unix_root_dir)
+ break;
+ path_parts.push_back(part.AsCString());
+ }
+ const size_t path_parts_size = path_parts.size();
+
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i) {
+ // Create a new FileSpec with this module_search_paths_ptr
+ // plus just the filename ("UIFoundation"), then the parent
+ // dir plus filename ("UIFoundation.framework/UIFoundation")
+ // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+
+ for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
+ FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
+
+ // Add the components backwards. For
+ // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // path_parts is
+ // [0] UIFoundation
+ // [1] UIFoundation.framework
+ // [2] PrivateFrameworks
//
- // We'll need to look in the module_search_paths_ptr directories for
- // both "UIFoundation" and "UIFoundation.framework" -- most likely the
- // latter will be the one we find there.
-
- FileSpec platform_pull_apart (platform_file);
- std::vector<std::string> path_parts;
- ConstString unix_root_dir("/");
- while (true)
- {
- ConstString part = platform_pull_apart.GetLastPathComponent();
- platform_pull_apart.RemoveLastPathComponent();
- if (part.IsEmpty() || part == unix_root_dir)
- break;
- path_parts.push_back (part.AsCString());
+ // and if 'j' is 2, we want to append path_parts[1] and then
+ // path_parts[0], aka
+ // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
+ // path.
+
+ for (int k = j; k >= 0; --k) {
+ path_to_try.AppendPathComponent(path_parts[k]);
}
- const size_t path_parts_size = path_parts.size();
-
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i)
- {
- // Create a new FileSpec with this module_search_paths_ptr
- // plus just the filename ("UIFoundation"), then the parent
- // dir plus filename ("UIFoundation.framework/UIFoundation")
- // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
-
- for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j)
- {
- FileSpec path_to_try (module_search_paths_ptr->GetFileSpecAtIndex (i));
-
- // Add the components backwards. For .../PrivateFrameworks/UIFoundation.framework/UIFoundation
- // path_parts is
- // [0] UIFoundation
- // [1] UIFoundation.framework
- // [2] PrivateFrameworks
- //
- // and if 'j' is 2, we want to append path_parts[1] and then path_parts[0], aka
- // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr path.
-
- for (int k = j; k >= 0; --k)
- {
- path_to_try.AppendPathComponent (path_parts[k]);
- }
-
- if (path_to_try.Exists())
- {
- ModuleSpec new_module_spec (module_spec);
- new_module_spec.GetFileSpec() = path_to_try;
- Error new_error (Platform::GetSharedModule (new_module_spec,
- process,
- module_sp,
- NULL,
- old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
- {
- module_sp->SetPlatformFileSpec (path_to_try);
- return new_error;
- }
- }
- }
+
+ if (path_to_try.Exists()) {
+ ModuleSpec new_module_spec(module_spec);
+ new_module_spec.GetFileSpec() = path_to_try;
+ Error new_error(Platform::GetSharedModule(
+ new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp) {
+ module_sp->SetPlatformFileSpec(path_to_try);
+ return new_error;
+ }
}
+ }
}
+ }
- const bool always_create = false;
- error = ModuleList::GetSharedModule (module_spec,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr,
- always_create);
+ const bool always_create = false;
+ error = ModuleList::GetSharedModule(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr, always_create);
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
- return error;
+ return error;
}
-bool
-PlatformRemoteAppleTV::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- ArchSpec system_arch (GetSystemArchitecture());
-
- const ArchSpec::Core system_core = system_arch.GetCore();
- switch (system_core)
- {
+bool PlatformRemoteAppleTV::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-tvos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7s-apple-tvos");
+ return true;
+ case 2:
+ arch.SetTriple("armv7-apple-tvos");
+ return true;
+ case 3:
+ arch.SetTriple("thumbv7s-apple-tvos");
+ return true;
+ case 4:
+ arch.SetTriple("thumbv7-apple-tvos");
+ return true;
default:
- switch (idx)
- {
- case 0: arch.SetTriple ("arm64-apple-tvos"); return true;
- case 1: arch.SetTriple ("armv7s-apple-tvos"); return true;
- case 2: arch.SetTriple ("armv7-apple-tvos"); return true;
- case 3: arch.SetTriple ("thumbv7s-apple-tvos"); return true;
- case 4: arch.SetTriple ("thumbv7-apple-tvos"); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- switch (idx)
- {
- case 0: arch.SetTriple ("arm64-apple-tvos"); return true;
- case 1: arch.SetTriple ("armv7s-apple-tvos"); return true;
- case 2: arch.SetTriple ("armv7-apple-tvos"); return true;
- case 3: arch.SetTriple ("thumbv7s-apple-tvos"); return true;
- case 4: arch.SetTriple ("thumbv7-apple-tvos"); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7s:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7s-apple-tvos"); return true;
- case 1: arch.SetTriple ("armv7-apple-tvos"); return true;
- case 2: arch.SetTriple ("thumbv7s-apple-tvos"); return true;
- case 3: arch.SetTriple ("thumbv7-apple-tvos"); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7-apple-tvos"); return true;
- case 1: arch.SetTriple ("thumbv7-apple-tvos"); return true;
- default: break;
- }
- break;
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_arm64:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("arm64-apple-tvos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7s-apple-tvos");
+ return true;
+ case 2:
+ arch.SetTriple("armv7-apple-tvos");
+ return true;
+ case 3:
+ arch.SetTriple("thumbv7s-apple-tvos");
+ return true;
+ case 4:
+ arch.SetTriple("thumbv7-apple-tvos");
+ return true;
+ default:
+ break;
}
- arch.Clear();
- return false;
+ break;
+
+ case ArchSpec::eCore_arm_armv7s:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7s-apple-tvos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7-apple-tvos");
+ return true;
+ case 2:
+ arch.SetTriple("thumbv7s-apple-tvos");
+ return true;
+ case 3:
+ arch.SetTriple("thumbv7-apple-tvos");
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7-apple-tvos");
+ return true;
+ case 1:
+ arch.SetTriple("thumbv7-apple-tvos");
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ arch.Clear();
+ return false;
}
-uint32_t
-PlatformRemoteAppleTV::GetConnectedSDKIndex ()
-{
- if (IsConnected())
- {
- if (m_connected_module_sdk_idx == UINT32_MAX)
- {
- std::string build;
- if (GetRemoteOSBuildString(build))
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str()))
- {
- m_connected_module_sdk_idx = i;
- }
- }
- }
+uint32_t PlatformRemoteAppleTV::GetConnectedSDKIndex() {
+ if (IsConnected()) {
+ if (m_connected_module_sdk_idx == UINT32_MAX) {
+ std::string build;
+ if (GetRemoteOSBuildString(build)) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
+ build.c_str())) {
+ m_connected_module_sdk_idx = i;
+ }
}
+ }
}
- else
- {
- m_connected_module_sdk_idx = UINT32_MAX;
- }
- return m_connected_module_sdk_idx;
+ } else {
+ m_connected_module_sdk_idx = UINT32_MAX;
+ }
+ return m_connected_module_sdk_idx;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
index 28bd9df0fad7..388ea578d06b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
@@ -20,152 +20,118 @@
#include "PlatformDarwin.h"
-class PlatformRemoteAppleTV : public PlatformDarwin
-{
+class PlatformRemoteAppleTV : public PlatformDarwin {
public:
- PlatformRemoteAppleTV();
-
- ~PlatformRemoteAppleTV() 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();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Error
- ResolveExecutable (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic();
- }
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override
- {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneOS);
- }
+ PlatformRemoteAppleTV();
+
+ ~PlatformRemoteAppleTV() 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();
+
+ //------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ virtual lldb_private::Error
+ GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::iPhoneOS);
+ }
protected:
- struct SDKDirectoryInfo
- {
- SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir_spec);
- lldb_private::FileSpec directory;
- lldb_private::ConstString build;
- uint32_t version_major;
- uint32_t version_minor;
- uint32_t version_update;
- bool user_cached;
- };
- typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
- SDKDirectoryInfoCollection m_sdk_directory_infos;
- std::string m_device_support_directory;
- std::string m_device_support_directory_for_os_version;
- std::string m_build_update;
- uint32_t m_last_module_sdk_idx;
- uint32_t m_connected_module_sdk_idx;
-
- bool
- UpdateSDKDirectoryInfosIfNeeded();
-
- const char *
- GetDeviceSupportDirectory();
-
- const char *
- GetDeviceSupportDirectoryForOSVersion();
-
- const SDKDirectoryInfo *
- GetSDKDirectoryForLatestOSVersion ();
-
- const SDKDirectoryInfo *
- GetSDKDirectoryForCurrentOSVersion ();
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback (void *baton,
- lldb_private::FileSpec::FileType file_type,
- const lldb_private::FileSpec &file_spec);
-
- uint32_t
- FindFileInAllSDKs (const char *platform_file_path,
- lldb_private::FileSpecList &file_list);
-
- bool
- GetFileInSDK (const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file);
-
- bool
- GetFileInSDKRoot (const char *platform_file_path,
- const char *sdkroot_path,
- bool symbols_dirs_only,
- lldb_private::FileSpec &local_file);
-
- uint32_t
- FindFileInAllSDKs (const lldb_private::FileSpec &platform_file,
- lldb_private::FileSpecList &file_list);
-
- uint32_t
- GetConnectedSDKIndex ();
+ struct SDKDirectoryInfo {
+ SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
+ lldb_private::FileSpec directory;
+ lldb_private::ConstString build;
+ uint32_t version_major;
+ uint32_t version_minor;
+ uint32_t version_update;
+ bool user_cached;
+ };
+ typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
+ std::mutex m_sdk_dir_mutex;
+ SDKDirectoryInfoCollection m_sdk_directory_infos;
+ std::string m_device_support_directory;
+ std::string m_device_support_directory_for_os_version;
+ std::string m_build_update;
+ uint32_t m_last_module_sdk_idx;
+ uint32_t m_connected_module_sdk_idx;
+
+ bool UpdateSDKDirectoryInfosIfNeeded();
+
+ const char *GetDeviceSupportDirectory();
+
+ const char *GetDeviceSupportDirectoryForOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &file_spec);
+
+ uint32_t FindFileInAllSDKs(const char *platform_file_path,
+ lldb_private::FileSpecList &file_list);
+
+ bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file);
+
+ uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
+ lldb_private::FileSpecList &file_list);
+
+ uint32_t GetConnectedSDKIndex();
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformRemoteAppleTV);
+ DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleTV);
};
#endif // liblldb_PlatformRemoteAppleTV_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
index ba59887ccf27..f12fcab3b713 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
@@ -36,38 +36,22 @@ using namespace lldb_private;
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformRemoteAppleWatch::PlatformRemoteAppleWatch () :
- PlatformDarwin (false), // This is a remote platform
- m_sdk_directory_infos(),
- m_device_support_directory(),
- m_device_support_directory_for_os_version (),
- m_build_update(),
- m_last_module_sdk_idx (UINT32_MAX),
- m_connected_module_sdk_idx (UINT32_MAX)
-{
-}
-
-PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir) :
- directory(sdk_dir),
- build(),
- version_major(0),
- version_minor(0),
- version_update(0),
- user_cached(false)
-{
- const char *dirname_cstr = sdk_dir.GetFilename().GetCString();
- const char *pos = Args::StringToVersion (dirname_cstr,
- version_major,
- version_minor,
- version_update);
-
- if (pos && pos[0] == ' ' && pos[1] == '(')
- {
- const char *build_start = pos + 2;
- const char *end_paren = strchr (build_start, ')');
- if (end_paren && build_start < end_paren)
- build.SetCStringWithLength(build_start, end_paren - build_start);
- }
+PlatformRemoteAppleWatch::PlatformRemoteAppleWatch()
+ : PlatformDarwin(false), // This is a remote platform
+ m_sdk_directory_infos(), m_device_support_directory(),
+ m_device_support_directory_for_os_version(), m_build_update(),
+ m_last_module_sdk_idx(UINT32_MAX),
+ m_connected_module_sdk_idx(UINT32_MAX) {}
+
+PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo(
+ const lldb_private::FileSpec &sdk_dir)
+ : directory(sdk_dir), build(), version_major(0), version_minor(0),
+ version_update(0), user_cached(false) {
+ llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
+ llvm::StringRef build_str;
+ std::tie(version_major, version_minor, version_update, build_str) =
+ ParseVersionBuildDir(dirname_str);
+ build.SetString(build_str);
}
//------------------------------------------------------------------
@@ -78,1006 +62,898 @@ static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformRemoteAppleWatch::Initialize ()
-{
- PlatformDarwin::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin (PlatformRemoteAppleWatch::GetPluginNameStatic(),
- PlatformRemoteAppleWatch::GetDescriptionStatic(),
- PlatformRemoteAppleWatch::CreateInstance);
- }
+void PlatformRemoteAppleWatch::Initialize() {
+ PlatformDarwin::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(
+ PlatformRemoteAppleWatch::GetPluginNameStatic(),
+ PlatformRemoteAppleWatch::GetDescriptionStatic(),
+ PlatformRemoteAppleWatch::CreateInstance);
+ }
}
-void
-PlatformRemoteAppleWatch::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformRemoteAppleWatch::CreateInstance);
- }
+void PlatformRemoteAppleWatch::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformRemoteAppleWatch::CreateInstance);
}
+ }
- PlatformDarwin::Terminate ();
+ PlatformDarwin::Terminate();
}
-PlatformSP
-PlatformRemoteAppleWatch::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 ("PlatformRemoteAppleWatch::%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::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb:
- {
- const llvm::Triple &triple = arch->GetTriple();
- llvm::Triple::VendorType vendor = triple.getVendor();
- switch (vendor)
- {
- case llvm::Triple::Apple:
- create = true;
- break;
+PlatformSP PlatformRemoteAppleWatch::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("PlatformRemoteAppleWatch::%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::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::thumb: {
+ 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::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for the vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::WatchOS: // This is the right triple value for Apple Watch debugging
- break;
-
- default:
- create = false;
- break;
- }
- }
- }
- break;
+ default:
+ break;
+ }
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::WatchOS: // This is the right triple value for Apple
+ // Watch debugging
+ break;
+
default:
- break;
+ create = false;
+ break;
}
+ }
+ } break;
+ default:
+ break;
}
-
-#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
- // If lldb is running on a watch, this isn't a RemoteWatch environment; it's a local system environment.
- if (force == false)
- {
- create = false;
- }
+ }
+
+#if defined(__APPLE__) && \
+ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
+ // If lldb is running on a watch, this isn't a RemoteWatch environment; it's a
+ // local system environment.
+ if (force == false) {
+ create = false;
+ }
#endif
- if (create)
- {
- if (log)
- log->Printf ("PlatformRemoteAppleWatch::%s() creating platform", __FUNCTION__);
+ if (create) {
+ if (log)
+ log->Printf("PlatformRemoteAppleWatch::%s() creating platform",
+ __FUNCTION__);
- return lldb::PlatformSP(new PlatformRemoteAppleWatch ());
- }
+ return lldb::PlatformSP(new PlatformRemoteAppleWatch());
+ }
- if (log)
- log->Printf ("PlatformRemoteAppleWatch::%s() aborting creation of platform", __FUNCTION__);
+ if (log)
+ log->Printf("PlatformRemoteAppleWatch::%s() aborting creation of platform",
+ __FUNCTION__);
- return lldb::PlatformSP();
+ return lldb::PlatformSP();
}
-lldb_private::ConstString
-PlatformRemoteAppleWatch::GetPluginNameStatic ()
-{
- static ConstString g_name("remote-watchos");
- return g_name;
+lldb_private::ConstString PlatformRemoteAppleWatch::GetPluginNameStatic() {
+ static ConstString g_name("remote-watchos");
+ return g_name;
}
-const char *
-PlatformRemoteAppleWatch::GetDescriptionStatic()
-{
- return "Remote Apple Watch platform plug-in.";
+const char *PlatformRemoteAppleWatch::GetDescriptionStatic() {
+ return "Remote Apple Watch platform plug-in.";
}
-void
-PlatformRemoteAppleWatch::GetStatus (Stream &strm)
-{
- Platform::GetStatus (strm);
- const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
- if (sdk_directory)
- strm.Printf (" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString (" SDK Path: error: unable to locate SDK\n");
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- strm.Printf (" SDK Roots: [%2u] \"%s\"\n",
- i,
- sdk_dir_info.directory.GetPath().c_str());
- }
+void PlatformRemoteAppleWatch::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
+ if (sdk_directory)
+ strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
+ else
+ strm.PutCString(" SDK Path: error: unable to locate SDK\n");
+
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
+ sdk_dir_info.directory.GetPath().c_str());
+ }
}
-Error
-PlatformRemoteAppleWatch::ResolveExecutable (const ModuleSpec &ms,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(ms);
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one ourselves
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
- {
- error = ModuleList::GetSharedModule(resolved_module_spec,
- exe_module_sp,
- nullptr,
- nullptr,
- nullptr);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule(resolved_module_spec,
- exe_module_sp,
- nullptr,
- nullptr,
- nullptr);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+Error PlatformRemoteAppleWatch::ResolveExecutable(
+ const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(ms);
+
+ // Resolve any executable within a bundle on MacOSX
+ // TODO: verify that this handles shallow bundles, if not then implement one
+ // ourselves
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (resolved_module_spec.GetArchitecture().IsValid() ||
+ resolved_module_spec.GetUUID().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ nullptr, nullptr, nullptr);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
}
- else
- {
- error.SetErrorStringWithFormat ("'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
+ // No valid architecture was specified or the exact ARM slice wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ nullptr, nullptr, nullptr);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
}
- return error;
-}
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' does not exist",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
-FileSpec::EnumerateDirectoryResult
-PlatformRemoteAppleWatch::GetContainedFilesIntoVectorOfStringsCallback (void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- ((PlatformRemoteAppleWatch::SDKDirectoryInfoCollection *)baton)->push_back(PlatformRemoteAppleWatch::SDKDirectoryInfo(file_spec));
- return FileSpec::eEnumerateDirectoryResultNext;
+ return error;
}
-bool
-PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded()
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (m_sdk_directory_infos.empty())
- {
- const char *device_support_dir = GetDeviceSupportDirectory();
- if (log)
- {
- log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded Got DeviceSupport directory %s", device_support_dir);
- }
- if (device_support_dir)
- {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
-
- SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSpec::EnumerateDirectory (m_device_support_directory.c_str(),
- 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 us.
- FileSpec sdk_symbols_symlink_fspec;
- for (const auto &sdk_directory_info : builtin_sdk_directory_infos)
- {
- sdk_symbols_symlink_fspec = sdk_directory_info.directory;
- sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
- if (sdk_symbols_symlink_fspec.Exists())
- {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log)
- {
- log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- else
- {
- sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
- if (sdk_symbols_symlink_fspec.Exists())
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log)
- {
- log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
+FileSpec::EnumerateDirectoryResult
+PlatformRemoteAppleWatch::GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) {
+ ((PlatformRemoteAppleWatch::SDKDirectoryInfoCollection *)baton)
+ ->push_back(PlatformRemoteAppleWatch::SDKDirectoryInfo(file_spec));
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
- const uint32_t num_installed = m_sdk_directory_infos.size();
- FileSpec local_sdk_cache("~/Library/Developer/Xcode/watchOS DeviceSupport", true);
- if (!local_sdk_cache.Exists())
- {
- local_sdk_cache = FileSpec("~/Library/Developer/Xcode/watch OS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists())
- {
- local_sdk_cache = FileSpec("~/Library/Developer/Xcode/WatchOS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists())
- {
- local_sdk_cache = FileSpec("~/Library/Developer/Xcode/Watch OS DeviceSupport", true);
- }
- if (local_sdk_cache.Exists())
- {
- if (log)
- {
- log->Printf ("PlatformRemoteAppleWatch::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)
- {
- m_sdk_directory_infos[i].user_cached = true;
- if (log)
- {
- log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded user SDK directory %s", m_sdk_directory_infos[i].directory.GetPath().c_str());
- }
- }
- }
+bool PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded() {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
+ if (m_sdk_directory_infos.empty()) {
+ const char *device_support_dir = GetDeviceSupportDirectory();
+ if (log) {
+ log->Printf("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded "
+ "Got DeviceSupport directory %s",
+ device_support_dir);
+ }
+ if (device_support_dir) {
+ const bool find_directories = true;
+ const bool find_files = false;
+ 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);
+
+ // Only add SDK directories that have symbols in them, some SDKs only
+ // contain
+ // developer disk images and no symbols, so they aren't useful to us.
+ FileSpec sdk_symbols_symlink_fspec;
+ for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
+ sdk_symbols_symlink_fspec = sdk_directory_info.directory;
+ sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
+ if (sdk_symbols_symlink_fspec.Exists()) {
+ m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteAppleWatch::"
+ "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
+ "directory %s",
+ sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
+ } else {
+ sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
+ if (sdk_symbols_symlink_fspec.Exists())
+ m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteAppleWatch::"
+ "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
+ "directory %s",
+ sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
+ }
+ }
+
+ const uint32_t num_installed = m_sdk_directory_infos.size();
+ FileSpec local_sdk_cache(
+ "~/Library/Developer/Xcode/watchOS DeviceSupport", true);
+ if (!local_sdk_cache.Exists()) {
+ local_sdk_cache =
+ FileSpec("~/Library/Developer/Xcode/watch OS DeviceSupport", true);
+ }
+ if (!local_sdk_cache.Exists()) {
+ local_sdk_cache =
+ FileSpec("~/Library/Developer/Xcode/WatchOS DeviceSupport", true);
+ }
+ if (!local_sdk_cache.Exists()) {
+ local_sdk_cache =
+ FileSpec("~/Library/Developer/Xcode/Watch OS DeviceSupport", true);
+ }
+ if (local_sdk_cache.Exists()) {
+ if (log) {
+ log->Printf("PlatformRemoteAppleWatch::"
+ "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) {
+ m_sdk_directory_infos[i].user_cached = true;
+ if (log) {
+ log->Printf("PlatformRemoteAppleWatch::"
+ "UpdateSDKDirectoryInfosIfNeeded user SDK directory "
+ "%s",
+ m_sdk_directory_infos[i].directory.GetPath().c_str());
}
+ }
}
+ }
}
- return !m_sdk_directory_infos.empty();
+ }
+ return !m_sdk_directory_infos.empty();
}
const PlatformRemoteAppleWatch::SDKDirectoryInfo *
-PlatformRemoteAppleWatch::GetSDKDirectoryForCurrentOSVersion ()
-{
- uint32_t i;
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+PlatformRemoteAppleWatch::GetSDKDirectoryForCurrentOSVersion() {
+ uint32_t i;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // Check to see if the user specified a build string. If they did, then
- // be sure to match it.
- std::vector<bool> check_sdk_info(num_sdk_infos, true);
- ConstString build(m_sdk_build);
- if (build)
- {
- for (i=0; i<num_sdk_infos; ++i)
- check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
- }
-
- // If we are connected we can find the version of the OS the platform
- // us running on and select the right SDK
- uint32_t major, minor, update;
- if (GetOSVersion(major, minor, update))
- {
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- // First try for an exact match of major, minor and update
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor &&
- m_sdk_directory_infos[i].version_update == update)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // First try for an exact match of major and minor
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // Lastly try to match of major version only..
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- }
- }
- else if (build)
- {
- // No version, just a build number, search for the first one that matches
- for (i=0; i<num_sdk_infos; ++i)
- if (check_sdk_info[i])
- return &m_sdk_directory_infos[i];
- }
+ // Check to see if the user specified a build string. If they did, then
+ // be sure to match it.
+ std::vector<bool> check_sdk_info(num_sdk_infos, true);
+ ConstString build(m_sdk_build);
+ if (build) {
+ for (i = 0; i < num_sdk_infos; ++i)
+ check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
}
- return nullptr;
-}
-const PlatformRemoteAppleWatch::SDKDirectoryInfo *
-PlatformRemoteAppleWatch::GetSDKDirectoryForLatestOSVersion ()
-{
- const PlatformRemoteAppleWatch::SDKDirectoryInfo *result = nullptr;
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ // If we are connected we can find the version of the OS the platform
+ // us running on and select the right SDK
+ uint32_t major, minor, update;
+ if (GetOSVersion(major, minor, update)) {
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
// First try for an exact match of major, minor and update
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (sdk_dir_info.version_major != UINT32_MAX)
- {
- if (result == nullptr || sdk_dir_info.version_major > result->version_major)
- {
- result = &sdk_dir_info;
- }
- else if (sdk_dir_info.version_major == result->version_major)
- {
- if (sdk_dir_info.version_minor > result->version_minor)
- {
- result = &sdk_dir_info;
- }
- else if (sdk_dir_info.version_minor == result->version_minor)
- {
- if (sdk_dir_info.version_update > result->version_update)
- {
- result = &sdk_dir_info;
- }
- }
- }
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor &&
+ m_sdk_directory_infos[i].version_update == update) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
+ }
+ // First try for an exact match of major and minor
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor) {
+ return &m_sdk_directory_infos[i];
}
+ }
}
+ // Lastly try to match of major version only..
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
+ }
+ }
+ } else if (build) {
+ // No version, just a build number, search for the first one that matches
+ for (i = 0; i < num_sdk_infos; ++i)
+ if (check_sdk_info[i])
+ return &m_sdk_directory_infos[i];
}
- return result;
+ }
+ return nullptr;
}
-const char *
-PlatformRemoteAppleWatch::GetDeviceSupportDirectory()
-{
- if (m_device_support_directory.empty())
- {
- const char *device_support_dir = GetDeveloperDirectory();
- if (device_support_dir)
- {
- m_device_support_directory.assign (device_support_dir);
- m_device_support_directory.append ("/Platforms/watchOS.platform/DeviceSupport");
- FileSpec platform_device_support_dir (m_device_support_directory.c_str(), true);
- if (!platform_device_support_dir.Exists())
- {
- std::string alt_platform_dirname = device_support_dir;
- alt_platform_dirname.append ("/Platforms/WatchOS.platform/DeviceSupport");
- FileSpec alt_platform_device_support_dir (m_device_support_directory.c_str(), true);
- if (alt_platform_device_support_dir.Exists())
- {
- m_device_support_directory = alt_platform_dirname;
- }
+const PlatformRemoteAppleWatch::SDKDirectoryInfo *
+PlatformRemoteAppleWatch::GetSDKDirectoryForLatestOSVersion() {
+ const PlatformRemoteAppleWatch::SDKDirectoryInfo *result = nullptr;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ // First try for an exact match of major, minor and update
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (sdk_dir_info.version_major != UINT32_MAX) {
+ if (result == nullptr ||
+ sdk_dir_info.version_major > result->version_major) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_major == result->version_major) {
+ if (sdk_dir_info.version_minor > result->version_minor) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_minor == result->version_minor) {
+ if (sdk_dir_info.version_update > result->version_update) {
+ result = &sdk_dir_info;
}
+ }
}
- else
- {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory.assign (1, '\0');
- }
+ }
}
- // We should have put a single NULL character into m_device_support_directory
- // or it should have a valid path if the code gets here
- assert (m_device_support_directory.empty() == false);
- if (m_device_support_directory[0])
- return m_device_support_directory.c_str();
- return nullptr;
+ }
+ return result;
}
-const char *
-PlatformRemoteAppleWatch::GetDeviceSupportDirectoryForOSVersion()
-{
- if (m_sdk_sysroot)
- return m_sdk_sysroot.GetCString();
-
- if (m_device_support_directory_for_os_version.empty())
- {
- const PlatformRemoteAppleWatch::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion ();
- if (sdk_dir_info == nullptr)
- sdk_dir_info = GetSDKDirectoryForLatestOSVersion ();
- if (sdk_dir_info)
- {
- char path[PATH_MAX];
- if (sdk_dir_info->directory.GetPath(path, sizeof(path)))
- {
- m_device_support_directory_for_os_version = path;
- return m_device_support_directory_for_os_version.c_str();
- }
- }
- else
- {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory_for_os_version.assign (1, '\0');
- }
+const char *PlatformRemoteAppleWatch::GetDeviceSupportDirectory() {
+ if (m_device_support_directory.empty()) {
+ const char *device_support_dir = GetDeveloperDirectory();
+ if (device_support_dir) {
+ m_device_support_directory.assign(device_support_dir);
+ m_device_support_directory.append(
+ "/Platforms/watchOS.platform/DeviceSupport");
+ FileSpec platform_device_support_dir(m_device_support_directory, true);
+ if (!platform_device_support_dir.Exists()) {
+ std::string alt_platform_dirname = device_support_dir;
+ alt_platform_dirname.append(
+ "/Platforms/WatchOS.platform/DeviceSupport");
+ FileSpec alt_platform_device_support_dir(m_device_support_directory,
+ true);
+ if (alt_platform_device_support_dir.Exists()) {
+ m_device_support_directory = alt_platform_dirname;
+ }
+ }
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory.assign(1, '\0');
}
- // We should have put a single NULL character into m_device_support_directory_for_os_version
- // or it should have a valid path if the code gets here
- assert (m_device_support_directory_for_os_version.empty() == false);
- if (m_device_support_directory_for_os_version[0])
- return m_device_support_directory_for_os_version.c_str();
- return nullptr;
+ }
+ // We should have put a single NULL character into m_device_support_directory
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory.empty() == false);
+ if (m_device_support_directory[0])
+ return m_device_support_directory.c_str();
+ return nullptr;
}
-uint32_t
-PlatformRemoteAppleWatch::FindFileInAllSDKs (const char *platform_file_path,
- FileSpecList &file_list)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
- if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- lldb_private::FileSpec local_file;
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path,
- sdk_idx,
- local_file))
- {
- file_list.Append(local_file);
- }
- }
+const char *PlatformRemoteAppleWatch::GetDeviceSupportDirectoryForOSVersion() {
+ if (m_sdk_sysroot)
+ return m_sdk_sysroot.GetCString();
+
+ if (m_device_support_directory_for_os_version.empty()) {
+ const PlatformRemoteAppleWatch::SDKDirectoryInfo *sdk_dir_info =
+ GetSDKDirectoryForCurrentOSVersion();
+ if (sdk_dir_info == nullptr)
+ sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
+ if (sdk_dir_info) {
+ char path[PATH_MAX];
+ if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
+ m_device_support_directory_for_os_version = path;
+ return m_device_support_directory_for_os_version.c_str();
+ }
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory_for_os_version.assign(1, '\0');
}
- return file_list.GetSize();
+ }
+ // We should have put a single NULL character into
+ // m_device_support_directory_for_os_version
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory_for_os_version.empty() == false);
+ if (m_device_support_directory_for_os_version[0])
+ return m_device_support_directory_for_os_version.c_str();
+ return nullptr;
}
-bool
-PlatformRemoteAppleWatch::GetFileInSDK (const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file)
-{
- if (sdk_idx < m_sdk_directory_infos.size())
- {
- char sdkroot_path[PATH_MAX];
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx];
- if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path)))
- {
- const bool symbols_dirs_only = true;
-
- return GetFileInSDKRoot (platform_file_path,
- sdkroot_path,
- symbols_dirs_only,
- local_file);
- }
+uint32_t
+PlatformRemoteAppleWatch::FindFileInAllSDKs(const char *platform_file_path,
+ FileSpecList &file_list) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_VERBOSE);
+ if (platform_file_path && platform_file_path[0] &&
+ UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ lldb_private::FileSpec local_file;
+ // First try for an exact match of major, minor and update
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
+ if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
+ file_list.Append(local_file);
+ }
}
- return false;
+ }
+ return file_list.GetSize();
}
-bool
-PlatformRemoteAppleWatch::GetFileInSDKRoot (const char *platform_file_path,
- const char *sdkroot_path,
- bool symbols_dirs_only,
- lldb_private::FileSpec &local_file)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
- {
- char resolved_path[PATH_MAX];
-
- if (!symbols_dirs_only)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path);
- }
- return true;
- }
- }
-
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols.Internal%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path);
- }
- return true;
- }
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path);
- }
- return true;
- }
+bool PlatformRemoteAppleWatch::GetFileInSDK(
+ const char *platform_file_path, uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (sdk_idx < m_sdk_directory_infos.size()) {
+ std::string sdkroot_path =
+ m_sdk_directory_infos[sdk_idx].directory.GetPath();
+ if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
+ // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
+ // the
+ // SDK root directory and the 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);
+ 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()) {
+ if (log)
+ log->Printf("Found a copy of %s in the SDK dir %s/%s",
+ platform_file_path, sdkroot_path.c_str(),
+ paths_to_try[i]);
+ return true;
+ }
+ local_file.Clear();
+ }
}
- return false;
+ }
+ return false;
}
-Error
-PlatformRemoteAppleWatch::GetSymbolFile (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- char resolved_path[PATH_MAX];
-
- const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion();
- if (os_version_dir)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir);
- }
- return error;
- }
+Error PlatformRemoteAppleWatch::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ Error error;
+ char platform_file_path[PATH_MAX];
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ char resolved_path[PATH_MAX];
+
+ const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
+ if (os_version_dir) {
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
+ platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s",
+ platform_file_path, os_version_dir);
+ }
+ return error;
+ }
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols.Internal/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir);
- }
- return error;
- }
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir);
- }
- return error;
- }
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
+ os_version_dir, platform_file_path);
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf(
+ "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
+ platform_file_path, os_version_dir);
}
- local_file = platform_file;
- if (local_file.Exists())
- return error;
+ return error;
+ }
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
+ os_version_dir, platform_file_path);
- error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path,
- GetPluginName().GetCString());
- }
- else
- {
- error.SetErrorString ("invalid platform file argument");
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
+ platform_file_path, os_version_dir);
+ }
+ return error;
+ }
}
- return error;
+ local_file = platform_file;
+ if (local_file.Exists())
+ return error;
+
+ error.SetErrorStringWithFormat(
+ "unable to locate a platform file for '%s' in platform '%s'",
+ platform_file_path, GetPluginName().GetCString());
+ } else {
+ error.SetErrorString("invalid platform file argument");
+ }
+ return error;
}
-Error
-PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec,
- lldb_private::Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- // For Apple Watch, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- const FileSpec &platform_file = module_spec.GetFileSpec();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
-
- Error error;
- char platform_file_path[PATH_MAX];
-
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- ModuleSpec platform_module_spec(module_spec);
-
- UpdateSDKDirectoryInfosIfNeeded();
+Error PlatformRemoteAppleWatch::GetSharedModule(
+ const ModuleSpec &module_spec, lldb_private::Process *process,
+ ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
+ ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
+ // For Apple Watch, the SDK files are all cached locally on the host
+ // system. So first we ask for the file in the cached SDK,
+ // then we attempt to get a shared module for the right architecture
+ // with the right UUID.
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_VERBOSE);
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ Error error;
+ char platform_file_path[PATH_MAX];
- // If we are connected we migth be able to correctly deduce the SDK directory
- // using the OS build.
- const uint32_t connected_sdk_idx = GetConnectedSDKIndex ();
- if (connected_sdk_idx < num_sdk_infos)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec()))
- {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec,
- module_sp,
- nullptr);
- if (module_sp)
- {
- m_last_module_sdk_idx = connected_sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ ModuleSpec platform_module_spec(module_spec);
- // Try the last SDK index if it is set as most files from an SDK
- // will tend to be valid in that same SDK.
- if (m_last_module_sdk_idx < num_sdk_infos)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec()))
- {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec,
- module_sp,
- nullptr);
- if (module_sp)
- {
- error.Clear();
- return error;
- }
- }
- }
-
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
- {
- if (m_last_module_sdk_idx == sdk_idx)
- {
- // Skip the last module SDK index if we already searched
- // it above
- continue;
- }
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec()))
- {
- //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
-
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp)
- {
- // Remember the index of the last SDK that we found a file
- // in in case the wrong SDK was selected.
- m_last_module_sdk_idx = sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
- }
- // Not the module we are looking for... Nothing to see here...
- module_sp.reset();
+ UpdateSDKDirectoryInfosIfNeeded();
- // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache.
- error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
- if (error.Success())
- return error;
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // See if the file is present in any of the module_search_paths_ptr directories.
- if (!module_sp && module_search_paths_ptr && platform_file)
- {
- // create a vector of all the file / directory names in platform_file
- // e.g. this might be /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
- //
- // We'll need to look in the module_search_paths_ptr directories for
- // both "UIFoundation" and "UIFoundation.framework" -- most likely the
- // latter will be the one we find there.
-
- FileSpec platform_pull_apart (platform_file);
- std::vector<std::string> path_parts;
- ConstString unix_root_dir("/");
- while (true)
- {
- ConstString part = platform_pull_apart.GetLastPathComponent();
- platform_pull_apart.RemoveLastPathComponent();
- if (part.IsEmpty() || part == unix_root_dir)
- break;
- path_parts.push_back (part.AsCString());
- }
- const size_t path_parts_size = path_parts.size();
-
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i)
- {
- // Create a new FileSpec with this module_search_paths_ptr
- // plus just the filename ("UIFoundation"), then the parent
- // dir plus filename ("UIFoundation.framework/UIFoundation")
- // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
-
- for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j)
- {
- FileSpec path_to_try (module_search_paths_ptr->GetFileSpecAtIndex (i));
-
- // Add the components backwards. For .../PrivateFrameworks/UIFoundation.framework/UIFoundation
- // path_parts is
- // [0] UIFoundation
- // [1] UIFoundation.framework
- // [2] PrivateFrameworks
- //
- // and if 'j' is 2, we want to append path_parts[1] and then path_parts[0], aka
- // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr path.
-
- for (int k = j; k >= 0; --k)
- {
- path_to_try.AppendPathComponent (path_parts[k]);
- }
-
- if (path_to_try.Exists())
- {
- ModuleSpec new_module_spec (module_spec);
- new_module_spec.GetFileSpec() = path_to_try;
- Error new_error (Platform::GetSharedModule (new_module_spec,
- process,
- module_sp,
- NULL,
- old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
- {
- module_sp->SetPlatformFileSpec (path_to_try);
- return new_error;
- }
- }
- }
- }
+ // If we are connected we migth be able to correctly deduce the SDK
+ // directory
+ // using the OS build.
+ const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
+ if (connected_sdk_idx < num_sdk_infos) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[connected_sdk_idx]
+ .directory.GetPath()
+ .c_str());
+ }
+ if (GetFileInSDK(platform_file_path, connected_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
+ if (module_sp) {
+ m_last_module_sdk_idx = connected_sdk_idx;
+ error.Clear();
+ return error;
+ }
+ }
}
- const bool always_create = false;
- error = ModuleList::GetSharedModule (module_spec,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr,
- always_create);
-
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
+ // Try the last SDK index if it is set as most files from an SDK
+ // will tend to be valid in that same SDK.
+ if (m_last_module_sdk_idx < num_sdk_infos) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[m_last_module_sdk_idx]
+ .directory.GetPath()
+ .c_str());
+ }
+ if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
+ if (module_sp) {
+ error.Clear();
+ return error;
+ }
+ }
+ }
+ // First try for an exact match of major, minor and update
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ if (m_last_module_sdk_idx == sdk_idx) {
+ // Skip the last module SDK index if we already searched
+ // it above
+ continue;
+ }
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
+ if (GetFileInSDK(platform_file_path, sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
+
+ error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
+ if (module_sp) {
+ // Remember the index of the last SDK that we found a file
+ // in in case the wrong SDK was selected.
+ m_last_module_sdk_idx = sdk_idx;
+ error.Clear();
+ return error;
+ }
+ }
+ }
+ }
+ // Not the module we are looking for... Nothing to see here...
+ module_sp.reset();
+
+ // This may not be an SDK-related module. Try whether we can bring in the
+ // thing to our local cache.
+ error = GetSharedModuleWithLocalCache(module_spec, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+ if (error.Success())
return error;
-}
-
-bool
-PlatformRemoteAppleWatch::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-watchos"); return true;
- case 1: arch.SetTriple ("armv7k-apple-watchos"); return true;
- case 2: arch.SetTriple ("armv7s-apple-watchos"); return true;
- case 3: arch.SetTriple ("armv7-apple-watchos"); return true;
- case 4: arch.SetTriple ("thumbv7k-apple-watchos"); return true;
- case 5: arch.SetTriple ("thumbv7-apple-watchos"); return true;
- case 6: arch.SetTriple ("thumbv7s-apple-watchos"); return true;
- default: break;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- switch (idx)
- {
- case 0: arch.SetTriple ("arm64-apple-watchos"); return true;
- case 1: arch.SetTriple ("armv7k-apple-watchos"); return true;
- case 2: arch.SetTriple ("armv7s-apple-watchos"); return true;
- case 3: arch.SetTriple ("armv7-apple-watchos"); return true;
- case 4: arch.SetTriple ("thumbv7k-apple-watchos"); return true;
- case 5: arch.SetTriple ("thumbv7-apple-watchos"); return true;
- case 6: arch.SetTriple ("thumbv7s-apple-watchos"); return true;
- default: break;
- }
+ // See if the file is present in any of the module_search_paths_ptr
+ // directories.
+ if (!module_sp && module_search_paths_ptr && platform_file) {
+ // create a vector of all the file / directory names in platform_file
+ // e.g. this might be
+ // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ //
+ // We'll need to look in the module_search_paths_ptr directories for
+ // both "UIFoundation" and "UIFoundation.framework" -- most likely the
+ // latter will be the one we find there.
+
+ FileSpec platform_pull_apart(platform_file);
+ std::vector<std::string> path_parts;
+ ConstString unix_root_dir("/");
+ while (true) {
+ ConstString part = platform_pull_apart.GetLastPathComponent();
+ platform_pull_apart.RemoveLastPathComponent();
+ if (part.IsEmpty() || part == unix_root_dir)
break;
+ path_parts.push_back(part.AsCString());
+ }
+ const size_t path_parts_size = path_parts.size();
+
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i) {
+ // Create a new FileSpec with this module_search_paths_ptr
+ // plus just the filename ("UIFoundation"), then the parent
+ // dir plus filename ("UIFoundation.framework/UIFoundation")
+ // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+
+ for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
+ FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
+
+ // Add the components backwards. For
+ // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // path_parts is
+ // [0] UIFoundation
+ // [1] UIFoundation.framework
+ // [2] PrivateFrameworks
+ //
+ // and if 'j' is 2, we want to append path_parts[1] and then
+ // path_parts[0], aka
+ // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
+ // path.
- case ArchSpec::eCore_arm_armv7k:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7k-apple-watchos"); return true;
- case 1: arch.SetTriple ("armv7s-apple-watchos"); return true;
- case 2: arch.SetTriple ("armv7-apple-watchos"); return true;
- case 3: arch.SetTriple ("thumbv7k-apple-watchos"); return true;
- case 4: arch.SetTriple ("thumbv7-apple-watchos"); return true;
- case 5: arch.SetTriple ("thumbv7s-apple-watchos"); return true;
- default: break;
+ for (int k = j; k >= 0; --k) {
+ path_to_try.AppendPathComponent(path_parts[k]);
}
- break;
- case ArchSpec::eCore_arm_armv7s:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7s-apple-watchos"); return true;
- case 1: arch.SetTriple ("armv7k-apple-watchos"); return true;
- case 2: arch.SetTriple ("armv7-apple-watchos"); return true;
- case 3: arch.SetTriple ("thumbv7k-apple-watchos"); return true;
- case 4: arch.SetTriple ("thumbv7-apple-watchos"); return true;
- case 5: arch.SetTriple ("thumbv7s-apple-watchos"); return true;
- default: break;
- }
- break;
+ if (path_to_try.Exists()) {
+ ModuleSpec new_module_spec(module_spec);
+ new_module_spec.GetFileSpec() = path_to_try;
+ Error new_error(Platform::GetSharedModule(
+ new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
+ did_create_ptr));
- case ArchSpec::eCore_arm_armv7:
- switch (idx)
- {
- case 0: arch.SetTriple ("armv7-apple-watchos"); return true;
- case 1: arch.SetTriple ("armv7k-apple-watchos"); return true;
- case 2: arch.SetTriple ("thumbv7k-apple-watchos"); return true;
- case 3: arch.SetTriple ("thumbv7-apple-watchos"); return true;
- default: break;
+ if (module_sp) {
+ module_sp->SetPlatformFileSpec(path_to_try);
+ return new_error;
+ }
}
- break;
+ }
}
- arch.Clear();
- return false;
+ }
+
+ const bool always_create = false;
+ error = ModuleList::GetSharedModule(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr, always_create);
+
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
+
+ return error;
}
-uint32_t
-PlatformRemoteAppleWatch::GetConnectedSDKIndex ()
-{
- if (IsConnected())
- {
- if (m_connected_module_sdk_idx == UINT32_MAX)
- {
- std::string build;
- if (GetRemoteOSBuildString(build))
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str()))
- {
- m_connected_module_sdk_idx = i;
- }
- }
- }
- }
+bool PlatformRemoteAppleWatch::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-watchos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7k-apple-watchos");
+ return true;
+ case 2:
+ arch.SetTriple("armv7s-apple-watchos");
+ return true;
+ case 3:
+ arch.SetTriple("armv7-apple-watchos");
+ return true;
+ case 4:
+ arch.SetTriple("thumbv7k-apple-watchos");
+ return true;
+ case 5:
+ arch.SetTriple("thumbv7-apple-watchos");
+ return true;
+ case 6:
+ arch.SetTriple("thumbv7s-apple-watchos");
+ return true;
+ default:
+ break;
}
- else
- {
- m_connected_module_sdk_idx = UINT32_MAX;
+ break;
+
+ case ArchSpec::eCore_arm_arm64:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("arm64-apple-watchos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7k-apple-watchos");
+ return true;
+ case 2:
+ arch.SetTriple("armv7s-apple-watchos");
+ return true;
+ case 3:
+ arch.SetTriple("armv7-apple-watchos");
+ return true;
+ case 4:
+ arch.SetTriple("thumbv7k-apple-watchos");
+ return true;
+ case 5:
+ arch.SetTriple("thumbv7-apple-watchos");
+ return true;
+ case 6:
+ arch.SetTriple("thumbv7s-apple-watchos");
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7k:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7k-apple-watchos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7s-apple-watchos");
+ return true;
+ case 2:
+ arch.SetTriple("armv7-apple-watchos");
+ return true;
+ case 3:
+ arch.SetTriple("thumbv7k-apple-watchos");
+ return true;
+ case 4:
+ arch.SetTriple("thumbv7-apple-watchos");
+ return true;
+ case 5:
+ arch.SetTriple("thumbv7s-apple-watchos");
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7s:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7s-apple-watchos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7k-apple-watchos");
+ return true;
+ case 2:
+ arch.SetTriple("armv7-apple-watchos");
+ return true;
+ case 3:
+ arch.SetTriple("thumbv7k-apple-watchos");
+ return true;
+ case 4:
+ arch.SetTriple("thumbv7-apple-watchos");
+ return true;
+ case 5:
+ arch.SetTriple("thumbv7s-apple-watchos");
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("armv7-apple-watchos");
+ return true;
+ case 1:
+ arch.SetTriple("armv7k-apple-watchos");
+ return true;
+ case 2:
+ arch.SetTriple("thumbv7k-apple-watchos");
+ return true;
+ case 3:
+ arch.SetTriple("thumbv7-apple-watchos");
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ arch.Clear();
+ return false;
+}
+
+uint32_t PlatformRemoteAppleWatch::GetConnectedSDKIndex() {
+ if (IsConnected()) {
+ if (m_connected_module_sdk_idx == UINT32_MAX) {
+ std::string build;
+ if (GetRemoteOSBuildString(build)) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
+ build.c_str())) {
+ m_connected_module_sdk_idx = i;
+ }
+ }
+ }
}
- return m_connected_module_sdk_idx;
+ } else {
+ m_connected_module_sdk_idx = UINT32_MAX;
+ }
+ return m_connected_module_sdk_idx;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
index 891bc5d1c6ef..0b388af329a5 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
@@ -21,153 +21,119 @@
#include "PlatformDarwin.h"
-class PlatformRemoteAppleWatch : public PlatformDarwin
-{
+class PlatformRemoteAppleWatch : public PlatformDarwin {
public:
- PlatformRemoteAppleWatch();
-
- ~PlatformRemoteAppleWatch() 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();
-
- //------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Error
- ResolveExecutable (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic();
- }
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override
- {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneOS);
- }
+ PlatformRemoteAppleWatch();
+
+ ~PlatformRemoteAppleWatch() 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();
+
+ //------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ virtual lldb_private::Error
+ GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::iPhoneOS);
+ }
protected:
- struct SDKDirectoryInfo
- {
- SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir_spec);
- lldb_private::FileSpec directory;
- lldb_private::ConstString build;
- uint32_t version_major;
- uint32_t version_minor;
- uint32_t version_update;
- bool user_cached;
- };
- typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
- SDKDirectoryInfoCollection m_sdk_directory_infos;
- std::string m_device_support_directory;
- std::string m_device_support_directory_for_os_version;
- std::string m_build_update;
- uint32_t m_last_module_sdk_idx;
- uint32_t m_connected_module_sdk_idx;
-
- bool
- UpdateSDKDirectoryInfosIfNeeded();
-
- const char *
- GetDeviceSupportDirectory();
-
- const char *
- GetDeviceSupportDirectoryForOSVersion();
-
- const SDKDirectoryInfo *
- GetSDKDirectoryForLatestOSVersion ();
-
- const SDKDirectoryInfo *
- GetSDKDirectoryForCurrentOSVersion ();
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback (void *baton,
- lldb_private::FileSpec::FileType file_type,
- const lldb_private::FileSpec &file_spec);
-
- uint32_t
- FindFileInAllSDKs (const char *platform_file_path,
- lldb_private::FileSpecList &file_list);
-
- bool
- GetFileInSDK (const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file);
-
- bool
- GetFileInSDKRoot (const char *platform_file_path,
- const char *sdkroot_path,
- bool symbols_dirs_only,
- lldb_private::FileSpec &local_file);
-
- uint32_t
- FindFileInAllSDKs (const lldb_private::FileSpec &platform_file,
- lldb_private::FileSpecList &file_list);
-
- uint32_t
- GetConnectedSDKIndex ();
+ struct SDKDirectoryInfo {
+ SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
+ lldb_private::FileSpec directory;
+ lldb_private::ConstString build;
+ uint32_t version_major;
+ uint32_t version_minor;
+ uint32_t version_update;
+ bool user_cached;
+ };
+ typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
+ std::mutex m_sdk_dir_mutex;
+ SDKDirectoryInfoCollection m_sdk_directory_infos;
+ std::string m_device_support_directory;
+ std::string m_device_support_directory_for_os_version;
+ std::string m_build_update;
+ uint32_t m_last_module_sdk_idx;
+ uint32_t m_connected_module_sdk_idx;
+
+ bool UpdateSDKDirectoryInfosIfNeeded();
+
+ const char *GetDeviceSupportDirectory();
+
+ const char *GetDeviceSupportDirectoryForOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &file_spec);
+
+ uint32_t FindFileInAllSDKs(const char *platform_file_path,
+ lldb_private::FileSpecList &file_list);
+
+ bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file);
+
+ uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
+ lldb_private::FileSpecList &file_list);
+
+ uint32_t GetConnectedSDKIndex();
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformRemoteAppleWatch);
+ DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleWatch);
};
#endif // liblldb_PlatformRemoteAppleWatch_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index abc429a72345..cf4f88d90107 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -30,27 +30,15 @@
using namespace lldb;
using namespace lldb_private;
-PlatformRemoteiOS::SDKDirectoryInfo::SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir) :
- directory(sdk_dir),
- build(),
- version_major(0),
- version_minor(0),
- version_update(0),
- user_cached(false)
-{
- const char *dirname_cstr = sdk_dir.GetFilename().GetCString();
- const char *pos = Args::StringToVersion (dirname_cstr,
- version_major,
- version_minor,
- version_update);
-
- if (pos && pos[0] == ' ' && pos[1] == '(')
- {
- const char *build_start = pos + 2;
- const char *end_paren = strchr (build_start, ')');
- if (end_paren && build_start < end_paren)
- build.SetCStringWithLength(build_start, end_paren - build_start);
- }
+PlatformRemoteiOS::SDKDirectoryInfo::SDKDirectoryInfo(
+ const lldb_private::FileSpec &sdk_dir)
+ : directory(sdk_dir), build(), version_major(0), version_minor(0),
+ version_update(0), user_cached(false) {
+ llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
+ llvm::StringRef build_str;
+ std::tie(version_major, version_minor, version_update, build_str) =
+ ParseVersionBuildDir(dirname_str);
+ build.SetString(build_str);
}
//------------------------------------------------------------------
@@ -61,141 +49,118 @@ static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformRemoteiOS::Initialize ()
-{
- PlatformDarwin::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin (PlatformRemoteiOS::GetPluginNameStatic(),
- PlatformRemoteiOS::GetDescriptionStatic(),
- PlatformRemoteiOS::CreateInstance);
- }
+void PlatformRemoteiOS::Initialize() {
+ PlatformDarwin::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(PlatformRemoteiOS::GetPluginNameStatic(),
+ PlatformRemoteiOS::GetDescriptionStatic(),
+ PlatformRemoteiOS::CreateInstance);
+ }
}
-void
-PlatformRemoteiOS::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformRemoteiOS::CreateInstance);
- }
+void PlatformRemoteiOS::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformRemoteiOS::CreateInstance);
}
+ }
- PlatformDarwin::Terminate ();
+ PlatformDarwin::Terminate();
}
-PlatformSP
-PlatformRemoteiOS::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 ("PlatformRemoteiOS::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
-
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- switch (arch->GetMachine())
- {
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::thumb:
- {
- const llvm::Triple &triple = arch->GetTriple();
- llvm::Triple::VendorType vendor = triple.getVendor();
- switch (vendor)
- {
- case llvm::Triple::Apple:
- create = true;
- break;
+PlatformSP PlatformRemoteiOS::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("PlatformRemoteiOS::%s(force=%s, arch={%s,%s})", __FUNCTION__,
+ force ? "true" : "false", arch_name, triple_cstr);
+ }
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ switch (arch->GetMachine()) {
+ case llvm::Triple::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::thumb: {
+ 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::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for the vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::Darwin: // Deprecated, but still support Darwin for historical reasons
- case llvm::Triple::IOS: // This is the right triple value for iOS debugging
- break;
-
- default:
- create = false;
- break;
- }
- }
- }
- break;
+ default:
+ break;
+ }
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
+ // historical reasons
+ case llvm::Triple::IOS: // This is the right triple value for iOS
+ // debugging
+ break;
+
default:
- break;
+ create = false;
+ break;
}
+ }
+ } break;
+ default:
+ break;
}
+ }
- if (create)
- {
- if (log)
- log->Printf ("PlatformRemoteiOS::%s() creating platform", __FUNCTION__);
-
- return lldb::PlatformSP(new PlatformRemoteiOS ());
- }
-
+ if (create) {
if (log)
- log->Printf ("PlatformRemoteiOS::%s() aborting creation of platform", __FUNCTION__);
+ log->Printf("PlatformRemoteiOS::%s() creating platform", __FUNCTION__);
- return lldb::PlatformSP();
-}
+ return lldb::PlatformSP(new PlatformRemoteiOS());
+ }
+ if (log)
+ log->Printf("PlatformRemoteiOS::%s() aborting creation of platform",
+ __FUNCTION__);
-lldb_private::ConstString
-PlatformRemoteiOS::GetPluginNameStatic ()
-{
- static ConstString g_name("remote-ios");
- return g_name;
+ return lldb::PlatformSP();
}
-const char *
-PlatformRemoteiOS::GetDescriptionStatic()
-{
- return "Remote iOS platform plug-in.";
+lldb_private::ConstString PlatformRemoteiOS::GetPluginNameStatic() {
+ static ConstString g_name("remote-ios");
+ return g_name;
}
+const char *PlatformRemoteiOS::GetDescriptionStatic() {
+ return "Remote iOS platform plug-in.";
+}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformRemoteiOS::PlatformRemoteiOS () :
- PlatformDarwin (false), // This is a remote platform
- m_sdk_directory_infos(),
- m_device_support_directory(),
- m_device_support_directory_for_os_version (),
- m_build_update(),
- m_last_module_sdk_idx (UINT32_MAX),
- m_connected_module_sdk_idx (UINT32_MAX)
-{
-}
+PlatformRemoteiOS::PlatformRemoteiOS()
+ : PlatformDarwin(false), // This is a remote platform
+ m_sdk_directory_infos(), m_device_support_directory(),
+ m_device_support_directory_for_os_version(), m_build_update(),
+ m_last_module_sdk_idx(UINT32_MAX),
+ m_connected_module_sdk_idx(UINT32_MAX) {}
//------------------------------------------------------------------
/// Destructor.
@@ -203,834 +168,673 @@ PlatformRemoteiOS::PlatformRemoteiOS () :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformRemoteiOS::~PlatformRemoteiOS()
-{
+PlatformRemoteiOS::~PlatformRemoteiOS() {}
+
+void PlatformRemoteiOS::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
+ if (sdk_directory)
+ strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
+ else
+ strm.PutCString(" SDK Path: error: unable to locate SDK\n");
+
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
+ sdk_dir_info.directory.GetPath().c_str());
+ }
}
+Error PlatformRemoteiOS::ResolveExecutable(
+ const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
-void
-PlatformRemoteiOS::GetStatus (Stream &strm)
-{
- Platform::GetStatus (strm);
- const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
- if (sdk_directory)
- strm.Printf (" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString (" SDK Path: error: unable to locate SDK\n");
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- strm.Printf (" SDK Roots: [%2u] \"%s\"\n",
- i,
- sdk_dir_info.directory.GetPath().c_str());
- }
-}
+ ModuleSpec resolved_module_spec(ms);
+ // Resolve any executable within a bundle on MacOSX
+ // TODO: verify that this handles shallow bundles, if not then implement one
+ // ourselves
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-Error
-PlatformRemoteiOS::ResolveExecutable (const ModuleSpec &ms,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(ms);
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one ourselves
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (resolved_module_spec.GetArchitecture().IsValid() ||
+ resolved_module_spec.GetUUID().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
}
- else
- {
- error.SetErrorStringWithFormat ("'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
+ // No valid architecture was specified or the exact ARM slice wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
}
- return error;
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' does not exist",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+
+ return error;
}
-FileSpec::EnumerateDirectoryResult
-PlatformRemoteiOS::GetContainedFilesIntoVectorOfStringsCallback (void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- ((PlatformRemoteiOS::SDKDirectoryInfoCollection *)baton)->push_back(PlatformRemoteiOS::SDKDirectoryInfo(file_spec));
- return FileSpec::eEnumerateDirectoryResultNext;
+FileSpec::EnumerateDirectoryResult
+PlatformRemoteiOS::GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) {
+ ((PlatformRemoteiOS::SDKDirectoryInfoCollection *)baton)
+ ->push_back(PlatformRemoteiOS::SDKDirectoryInfo(file_spec));
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-bool
-PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded()
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- 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);
- const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
- m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
- if (log)
- {
- log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added --sysroot SDK directory %s", m_sdk_sysroot.GetCString());
- }
- return true;
+bool PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded() {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
+ 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);
+ const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
+ m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added "
+ "--sysroot SDK directory %s",
+ m_sdk_sysroot.GetCString());
+ }
+ return true;
+ }
+ const char *device_support_dir = GetDeviceSupportDirectory();
+ if (log) {
+ log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded Got "
+ "DeviceSupport directory %s",
+ device_support_dir);
+ }
+ if (device_support_dir) {
+ const bool find_directories = true;
+ const bool find_files = false;
+ 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);
+
+ // Only add SDK directories that have symbols in them, some SDKs only
+ // contain
+ // developer disk images and no symbols, so they aren't useful to us.
+ FileSpec sdk_symbols_symlink_fspec;
+ 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()) {
+ m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
+ "added builtin SDK directory %s",
+ sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
}
- const char *device_support_dir = GetDeviceSupportDirectory();
- if (log)
- {
- log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded Got DeviceSupport directory %s", device_support_dir);
+ }
+
+ const uint32_t num_installed = m_sdk_directory_infos.size();
+ FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport",
+ true);
+ if (local_sdk_cache.Exists()) {
+ if (log) {
+ log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
+ "searching %s for additional SDKs",
+ local_sdk_cache.GetPath().c_str());
}
- if (device_support_dir)
- {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
-
- SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSpec::EnumerateDirectory (m_device_support_directory.c_str(),
- 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 us.
- FileSpec sdk_symbols_symlink_fspec;
- 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())
- {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log)
- {
- log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
-
- const uint32_t num_installed = m_sdk_directory_infos.size();
- FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport", true);
- if (local_sdk_cache.Exists())
- {
- if (log)
- {
- log->Printf ("PlatformRemoteiOS::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)
- {
- m_sdk_directory_infos[i].user_cached = true;
- if (log)
- {
- log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded user SDK directory %s", m_sdk_directory_infos[i].directory.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) {
+ m_sdk_directory_infos[i].user_cached = true;
+ if (log) {
+ log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
+ "user SDK directory %s",
+ m_sdk_directory_infos[i].directory.GetPath().c_str());
}
+ }
}
+ }
}
- return !m_sdk_directory_infos.empty();
+ }
+ return !m_sdk_directory_infos.empty();
}
const PlatformRemoteiOS::SDKDirectoryInfo *
-PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion ()
-{
- uint32_t i;
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion() {
+ uint32_t i;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+
+ // Check to see if the user specified a build string. If they did, then
+ // be sure to match it.
+ std::vector<bool> check_sdk_info(num_sdk_infos, true);
+ ConstString build(m_sdk_build);
+ if (build) {
+ for (i = 0; i < num_sdk_infos; ++i)
+ check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
+ }
- // Check to see if the user specified a build string. If they did, then
- // be sure to match it.
- std::vector<bool> check_sdk_info(num_sdk_infos, true);
- ConstString build(m_sdk_build);
- if (build)
- {
- for (i=0; i<num_sdk_infos; ++i)
- check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
+ // If we are connected we can find the version of the OS the platform
+ // us running on and select the right SDK
+ uint32_t major, minor, update;
+ if (GetOSVersion(major, minor, update)) {
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ // First try for an exact match of major, minor and update
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor &&
+ m_sdk_directory_infos[i].version_update == update) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
}
-
- // If we are connected we can find the version of the OS the platform
- // us running on and select the right SDK
- uint32_t major, minor, update;
- if (GetOSVersion(major, minor, update))
- {
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- // First try for an exact match of major, minor and update
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor &&
- m_sdk_directory_infos[i].version_update == update)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // First try for an exact match of major and minor
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // Lastly try to match of major version only..
- for (i=0; i<num_sdk_infos; ++i)
- {
- if (check_sdk_info[i])
- {
- if (m_sdk_directory_infos[i].version_major == major)
- {
- return &m_sdk_directory_infos[i];
- }
- }
- }
+ // First try for an exact match of major and minor
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor) {
+ return &m_sdk_directory_infos[i];
}
+ }
}
- else if (build)
- {
- // No version, just a build number, search for the first one that matches
- for (i=0; i<num_sdk_infos; ++i)
- if (check_sdk_info[i])
- return &m_sdk_directory_infos[i];
+ // Lastly try to match of major version only..
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
}
+ }
+ } else if (build) {
+ // No version, just a build number, search for the first one that matches
+ for (i = 0; i < num_sdk_infos; ++i)
+ if (check_sdk_info[i])
+ return &m_sdk_directory_infos[i];
}
- return NULL;
+ }
+ return NULL;
}
const PlatformRemoteiOS::SDKDirectoryInfo *
-PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion ()
-{
- const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL;
- if (UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (sdk_dir_info.version_major != UINT32_MAX)
- {
- if (result == NULL || sdk_dir_info.version_major > result->version_major)
- {
- result = &sdk_dir_info;
- }
- else if (sdk_dir_info.version_major == result->version_major)
- {
- if (sdk_dir_info.version_minor > result->version_minor)
- {
- result = &sdk_dir_info;
- }
- else if (sdk_dir_info.version_minor == result->version_minor)
- {
- if (sdk_dir_info.version_update > result->version_update)
- {
- result = &sdk_dir_info;
- }
- }
- }
+PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion() {
+ const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ // First try for an exact match of major, minor and update
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (sdk_dir_info.version_major != UINT32_MAX) {
+ if (result == NULL ||
+ sdk_dir_info.version_major > result->version_major) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_major == result->version_major) {
+ if (sdk_dir_info.version_minor > result->version_minor) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_minor == result->version_minor) {
+ if (sdk_dir_info.version_update > result->version_update) {
+ result = &sdk_dir_info;
}
+ }
}
+ }
}
- return result;
+ }
+ return result;
}
-
-
-const char *
-PlatformRemoteiOS::GetDeviceSupportDirectory()
-{
- if (m_device_support_directory.empty())
- {
- const char *device_support_dir = GetDeveloperDirectory();
- if (device_support_dir)
- {
- m_device_support_directory.assign (device_support_dir);
- m_device_support_directory.append ("/Platforms/iPhoneOS.platform/DeviceSupport");
- }
- else
- {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory.assign (1, '\0');
- }
+const char *PlatformRemoteiOS::GetDeviceSupportDirectory() {
+ if (m_device_support_directory.empty()) {
+ const char *device_support_dir = GetDeveloperDirectory();
+ if (device_support_dir) {
+ m_device_support_directory.assign(device_support_dir);
+ m_device_support_directory.append(
+ "/Platforms/iPhoneOS.platform/DeviceSupport");
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory.assign(1, '\0');
}
- // We should have put a single NULL character into m_device_support_directory
- // or it should have a valid path if the code gets here
- assert (m_device_support_directory.empty() == false);
- if (m_device_support_directory[0])
- return m_device_support_directory.c_str();
- return NULL;
+ }
+ // We should have put a single NULL character into m_device_support_directory
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory.empty() == false);
+ if (m_device_support_directory[0])
+ return m_device_support_directory.c_str();
+ return NULL;
}
-
-
-const char *
-PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion()
-{
- if (m_sdk_sysroot)
- return m_sdk_sysroot.GetCString();
-
- if (m_device_support_directory_for_os_version.empty())
- {
- const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion ();
- if (sdk_dir_info == NULL)
- sdk_dir_info = GetSDKDirectoryForLatestOSVersion ();
- if (sdk_dir_info)
- {
- char path[PATH_MAX];
- if (sdk_dir_info->directory.GetPath(path, sizeof(path)))
- {
- m_device_support_directory_for_os_version = path;
- return m_device_support_directory_for_os_version.c_str();
- }
- }
- else
- {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory_for_os_version.assign (1, '\0');
- }
- }
- // We should have put a single NULL character into m_device_support_directory_for_os_version
- // or it should have a valid path if the code gets here
- assert (m_device_support_directory_for_os_version.empty() == false);
- if (m_device_support_directory_for_os_version[0])
+
+const char *PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion() {
+ if (m_sdk_sysroot)
+ return m_sdk_sysroot.GetCString();
+
+ if (m_device_support_directory_for_os_version.empty()) {
+ const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info =
+ GetSDKDirectoryForCurrentOSVersion();
+ if (sdk_dir_info == NULL)
+ sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
+ if (sdk_dir_info) {
+ char path[PATH_MAX];
+ if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
+ m_device_support_directory_for_os_version = path;
return m_device_support_directory_for_os_version.c_str();
- return NULL;
+ }
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory_for_os_version.assign(1, '\0');
+ }
+ }
+ // We should have put a single NULL character into
+ // m_device_support_directory_for_os_version
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory_for_os_version.empty() == false);
+ if (m_device_support_directory_for_os_version[0])
+ return m_device_support_directory_for_os_version.c_str();
+ return NULL;
}
-uint32_t
-PlatformRemoteiOS::FindFileInAllSDKs (const char *platform_file_path,
- FileSpecList &file_list)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
- if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded())
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- lldb_private::FileSpec local_file;
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path,
- sdk_idx,
- local_file))
- {
- file_list.Append(local_file);
- }
- }
+uint32_t PlatformRemoteiOS::FindFileInAllSDKs(const char *platform_file_path,
+ FileSpecList &file_list) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_VERBOSE);
+ if (platform_file_path && platform_file_path[0] &&
+ UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ lldb_private::FileSpec local_file;
+ // First try for an exact match of major, minor and update
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
+ if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
+ file_list.Append(local_file);
+ }
}
- return file_list.GetSize();
+ }
+ return file_list.GetSize();
}
-bool
-PlatformRemoteiOS::GetFileInSDK (const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file)
-{
- if (sdk_idx < m_sdk_directory_infos.size())
- {
- char sdkroot_path[PATH_MAX];
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx];
- if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path)))
- {
- const bool symbols_dirs_only = true;
-
- return GetFileInSDKRoot (platform_file_path,
- sdkroot_path,
- symbols_dirs_only,
- local_file);
+bool PlatformRemoteiOS::GetFileInSDK(const char *platform_file_path,
+ uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (sdk_idx < m_sdk_directory_infos.size()) {
+ std::string sdkroot_path =
+ m_sdk_directory_infos[sdk_idx].directory.GetPath();
+ local_file.Clear();
+
+ if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
+ // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
+ // the
+ // SDK root directory and the 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);
+ 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()) {
+ if (log)
+ log->Printf("Found a copy of %s in the SDK dir %s/%s",
+ platform_file_path, sdkroot_path.c_str(),
+ paths_to_try[i]);
+ return true;
}
+ local_file.Clear();
+ }
}
- return false;
+ }
+ return false;
}
-
-bool
-PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path,
- const char *sdkroot_path,
- bool symbols_dirs_only,
- lldb_private::FileSpec &local_file)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
- {
- char resolved_path[PATH_MAX];
-
- if (!symbols_dirs_only)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path);
- }
- return true;
- }
+Error PlatformRemoteiOS::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ Error error;
+ char platform_file_path[PATH_MAX];
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ char resolved_path[PATH_MAX];
+
+ const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
+ if (os_version_dir) {
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
+ platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s",
+ platform_file_path, os_version_dir);
}
-
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols.Internal%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path);
- }
- return true;
+ return error;
+ }
+
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
+ os_version_dir, platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf(
+ "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
+ platform_file_path, os_version_dir);
}
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols%s",
- sdkroot_path,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path);
- }
- return true;
+ return error;
+ }
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
+ os_version_dir, platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
+ platform_file_path, os_version_dir);
}
+ return error;
+ }
}
- return false;
+ local_file = platform_file;
+ if (local_file.Exists())
+ return error;
+
+ error.SetErrorStringWithFormat(
+ "unable to locate a platform file for '%s' in platform '%s'",
+ platform_file_path, GetPluginName().GetCString());
+ } else {
+ error.SetErrorString("invalid platform file argument");
+ }
+ return error;
}
+Error PlatformRemoteiOS::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ // For iOS, the SDK files are all cached locally on the host
+ // system. So first we ask for the file in the cached SDK,
+ // then we attempt to get a shared module for the right architecture
+ // with the right UUID.
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_VERBOSE);
-Error
-PlatformRemoteiOS::GetSymbolFile (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- char resolved_path[PATH_MAX];
-
- const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion();
- if (os_version_dir)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir);
- }
- return error;
- }
-
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols.Internal/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir);
- }
- return error;
- }
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/Symbols/%s",
- os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- {
- if (log)
- {
- log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir);
- }
- return error;
- }
-
- }
- local_file = platform_file;
- if (local_file.Exists())
- return error;
+ Error error;
+ char platform_file_path[PATH_MAX];
- error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path,
- GetPluginName().GetCString());
- }
- else
- {
- error.SetErrorString ("invalid platform file argument");
- }
- return error;
-}
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ ModuleSpec platform_module_spec(module_spec);
-Error
-PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec,
- Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- // For iOS, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- const FileSpec &platform_file = module_spec.GetFileSpec();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE);
-
- Error error;
- char platform_file_path[PATH_MAX];
-
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- ModuleSpec platform_module_spec(module_spec);
-
- UpdateSDKDirectoryInfosIfNeeded();
+ UpdateSDKDirectoryInfosIfNeeded();
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // If we are connected we migth be able to correctly deduce the SDK directory
- // using the OS build.
- const uint32_t connected_sdk_idx = GetConnectedSDKIndex ();
- if (connected_sdk_idx < num_sdk_infos)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec()))
- {
- module_sp.reset();
- error = ResolveExecutable (platform_module_spec,
- module_sp,
- NULL);
- if (module_sp)
- {
- m_last_module_sdk_idx = connected_sdk_idx;
- error.Clear();
- return error;
- }
- }
+ // If we are connected we migth be able to correctly deduce the SDK
+ // directory
+ // using the OS build.
+ const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
+ if (connected_sdk_idx < num_sdk_infos) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[connected_sdk_idx]
+ .directory.GetPath()
+ .c_str());
+ }
+ if (GetFileInSDK(platform_file_path, connected_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ m_last_module_sdk_idx = connected_sdk_idx;
+ error.Clear();
+ return error;
}
+ }
+ }
- // Try the last SDK index if it is set as most files from an SDK
- // will tend to be valid in that same SDK.
- if (m_last_module_sdk_idx < num_sdk_infos)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec()))
- {
- module_sp.reset();
- error = ResolveExecutable (platform_module_spec,
- module_sp,
- NULL);
- if (module_sp)
- {
- error.Clear();
- return error;
- }
- }
- }
-
- // First try for an exact match of major, minor and update:
- // If a particalar SDK version was specified via --version or --build, look for a match on disk.
- const SDKDirectoryInfo *current_sdk_info = GetSDKDirectoryForCurrentOSVersion();
- const uint32_t current_sdk_idx = GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
- if (current_sdk_idx < num_sdk_infos && current_sdk_idx != m_last_module_sdk_idx)
- {
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[current_sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, current_sdk_idx, platform_module_spec.GetFileSpec()))
- {
- module_sp.reset();
- error = ResolveExecutable (platform_module_spec,
- module_sp,
- NULL);
- if (module_sp)
- {
- m_last_module_sdk_idx = current_sdk_idx;
- error.Clear();
- return error;
- }
- }
+ // Try the last SDK index if it is set as most files from an SDK
+ // will tend to be valid in that same SDK.
+ if (m_last_module_sdk_idx < num_sdk_infos) {
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[m_last_module_sdk_idx]
+ .directory.GetPath()
+ .c_str());
+ }
+ if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ error.Clear();
+ return error;
}
+ }
+ }
- // Second try all SDKs that were found.
- for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
- {
- if (m_last_module_sdk_idx == sdk_idx)
- {
- // Skip the last module SDK index if we already searched
- // it above
- continue;
- }
- if (log)
- {
- log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
- }
- if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec()))
- {
- //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
-
- error = ResolveExecutable (platform_module_spec, module_sp, NULL);
- if (module_sp)
- {
- // Remember the index of the last SDK that we found a file
- // in in case the wrong SDK was selected.
- m_last_module_sdk_idx = sdk_idx;
- error.Clear();
- return error;
- }
- }
+ // First try for an exact match of major, minor and update:
+ // If a particalar SDK version was specified via --version or --build, look
+ // for a match on disk.
+ const SDKDirectoryInfo *current_sdk_info =
+ GetSDKDirectoryForCurrentOSVersion();
+ const uint32_t current_sdk_idx =
+ GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
+ if (current_sdk_idx < num_sdk_infos &&
+ current_sdk_idx != m_last_module_sdk_idx) {
+ if (log) {
+ log->Printf(
+ "Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[current_sdk_idx].directory.GetPath().c_str());
+ }
+ if (GetFileInSDK(platform_file_path, current_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ m_last_module_sdk_idx = current_sdk_idx;
+ error.Clear();
+ return error;
}
+ }
}
- // Not the module we are looking for... Nothing to see here...
- module_sp.reset();
- // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache.
- error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
- if (error.Success())
- return error;
+ // Second try all SDKs that were found.
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ if (m_last_module_sdk_idx == sdk_idx) {
+ // Skip the last module SDK index if we already searched
+ // it above
+ continue;
+ }
+ if (log) {
+ log->Printf("Searching for %s in sdk path %s", platform_file_path,
+ m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
+ }
+ if (GetFileInSDK(platform_file_path, sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
+
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ // Remember the index of the last SDK that we found a file
+ // in in case the wrong SDK was selected.
+ m_last_module_sdk_idx = sdk_idx;
+ error.Clear();
+ return error;
+ }
+ }
+ }
+ }
+ // Not the module we are looking for... Nothing to see here...
+ module_sp.reset();
+
+ // This may not be an SDK-related module. Try whether we can bring in the
+ // thing to our local cache.
+ error = GetSharedModuleWithLocalCache(module_spec, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+ if (error.Success())
+ return error;
- // See if the file is present in any of the module_search_paths_ptr directories.
- if (!module_sp && module_search_paths_ptr && platform_file)
- {
- // create a vector of all the file / directory names in platform_file
- // e.g. this might be /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // See if the file is present in any of the module_search_paths_ptr
+ // directories.
+ if (!module_sp && module_search_paths_ptr && platform_file) {
+ // create a vector of all the file / directory names in platform_file
+ // e.g. this might be
+ // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ //
+ // We'll need to look in the module_search_paths_ptr directories for
+ // both "UIFoundation" and "UIFoundation.framework" -- most likely the
+ // latter will be the one we find there.
+
+ FileSpec platform_pull_apart(platform_file);
+ std::vector<std::string> path_parts;
+ ConstString unix_root_dir("/");
+ while (true) {
+ ConstString part = platform_pull_apart.GetLastPathComponent();
+ platform_pull_apart.RemoveLastPathComponent();
+ if (part.IsEmpty() || part == unix_root_dir)
+ break;
+ path_parts.push_back(part.AsCString());
+ }
+ const size_t path_parts_size = path_parts.size();
+
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i) {
+ Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
+ LIBLLDB_LOG_VERBOSE);
+ if (log_verbose)
+ log_verbose->Printf ("PlatformRemoteiOS::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
+ // Create a new FileSpec with this module_search_paths_ptr
+ // plus just the filename ("UIFoundation"), then the parent
+ // dir plus filename ("UIFoundation.framework/UIFoundation")
+ // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+
+ for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
+ FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
+
+ // Add the components backwards. For
+ // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // path_parts is
+ // [0] UIFoundation
+ // [1] UIFoundation.framework
+ // [2] PrivateFrameworks
//
- // We'll need to look in the module_search_paths_ptr directories for
- // both "UIFoundation" and "UIFoundation.framework" -- most likely the
- // latter will be the one we find there.
-
- FileSpec platform_pull_apart (platform_file);
- std::vector<std::string> path_parts;
- ConstString unix_root_dir("/");
- while (true)
- {
- ConstString part = platform_pull_apart.GetLastPathComponent();
- platform_pull_apart.RemoveLastPathComponent();
- if (part.IsEmpty() || part == unix_root_dir)
- break;
- path_parts.push_back (part.AsCString());
+ // and if 'j' is 2, we want to append path_parts[1] and then
+ // path_parts[0], aka
+ // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
+ // path.
+
+ for (int k = j; k >= 0; --k) {
+ path_to_try.AppendPathComponent(path_parts[k]);
}
- const size_t path_parts_size = path_parts.size();
-
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i)
- {
- // Create a new FileSpec with this module_search_paths_ptr
- // plus just the filename ("UIFoundation"), then the parent
- // dir plus filename ("UIFoundation.framework/UIFoundation")
- // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
-
- for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j)
- {
- FileSpec path_to_try (module_search_paths_ptr->GetFileSpecAtIndex (i));
-
- // Add the components backwards. For .../PrivateFrameworks/UIFoundation.framework/UIFoundation
- // path_parts is
- // [0] UIFoundation
- // [1] UIFoundation.framework
- // [2] PrivateFrameworks
- //
- // and if 'j' is 2, we want to append path_parts[1] and then path_parts[0], aka
- // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr path.
-
- for (int k = j; k >= 0; --k)
- {
- path_to_try.AppendPathComponent (path_parts[k]);
- }
-
- if (path_to_try.Exists())
- {
- ModuleSpec new_module_spec (module_spec);
- new_module_spec.GetFileSpec() = path_to_try;
- Error new_error (Platform::GetSharedModule (new_module_spec,
- process,
- module_sp,
- NULL,
- old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
- {
- module_sp->SetPlatformFileSpec (path_to_try);
- return new_error;
- }
- }
- }
+
+ if (path_to_try.Exists()) {
+ ModuleSpec new_module_spec(module_spec);
+ new_module_spec.GetFileSpec() = path_to_try;
+ Error new_error(Platform::GetSharedModule(
+ new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp) {
+ module_sp->SetPlatformFileSpec(path_to_try);
+ return new_error;
+ }
}
+ }
}
+ }
- const bool always_create = false;
- error = ModuleList::GetSharedModule (module_spec,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr,
- always_create);
+ const bool always_create = false;
+ error = ModuleList::GetSharedModule(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr, always_create);
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
- return error;
+ return error;
}
-bool
-PlatformRemoteiOS::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- return ARMGetSupportedArchitectureAtIndex (idx, arch);
+bool PlatformRemoteiOS::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ return ARMGetSupportedArchitectureAtIndex(idx, arch);
}
-uint32_t
-PlatformRemoteiOS::GetConnectedSDKIndex ()
-{
- if (IsConnected())
- {
- if (m_connected_module_sdk_idx == UINT32_MAX)
- {
- std::string build;
- if (GetRemoteOSBuildString(build))
- {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i=0; i<num_sdk_infos; ++i)
- {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str()))
- {
- m_connected_module_sdk_idx = i;
- }
- }
- }
+uint32_t PlatformRemoteiOS::GetConnectedSDKIndex() {
+ if (IsConnected()) {
+ if (m_connected_module_sdk_idx == UINT32_MAX) {
+ std::string build;
+ if (GetRemoteOSBuildString(build)) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
+ build.c_str())) {
+ m_connected_module_sdk_idx = i;
+ }
}
+ }
}
- else
- {
- m_connected_module_sdk_idx = UINT32_MAX;
- }
- return m_connected_module_sdk_idx;
+ } else {
+ m_connected_module_sdk_idx = UINT32_MAX;
+ }
+ return m_connected_module_sdk_idx;
}
-uint32_t
-PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo (const SDKDirectoryInfo *sdk_info)
-{
- if (sdk_info == NULL)
- {
- return UINT32_MAX;
- }
+uint32_t PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo(
+ const SDKDirectoryInfo *sdk_info) {
+ if (sdk_info == NULL) {
+ return UINT32_MAX;
+ }
- return sdk_info - &m_sdk_directory_infos[0];
+ return sdk_info - &m_sdk_directory_infos[0];
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index 9726d8238e13..4d88a9e4103a 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -16,158 +16,124 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Host/FileSpec.h"
#include "PlatformDarwin.h"
+#include "lldb/Host/FileSpec.h"
-class PlatformRemoteiOS : public PlatformDarwin
-{
+class PlatformRemoteiOS : public PlatformDarwin {
public:
- PlatformRemoteiOS ();
-
- ~PlatformRemoteiOS() override;
-
- //------------------------------------------------------------
- // 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
- //------------------------------------------------------------
- lldb_private::Error
- ResolveExecutable (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic();
- }
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override
- {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneOS);
- }
+ PlatformRemoteiOS();
+
+ ~PlatformRemoteiOS() override;
+
+ //------------------------------------------------------------
+ // 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
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ virtual lldb_private::Error
+ GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::iPhoneOS);
+ }
protected:
- struct SDKDirectoryInfo
- {
- SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir_spec);
- lldb_private::FileSpec directory;
- lldb_private::ConstString build;
- uint32_t version_major;
- uint32_t version_minor;
- uint32_t version_update;
- bool user_cached;
- };
-
- typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
-
- SDKDirectoryInfoCollection m_sdk_directory_infos;
- std::string m_device_support_directory;
- std::string m_device_support_directory_for_os_version;
- std::string m_build_update;
- uint32_t m_last_module_sdk_idx;
- uint32_t m_connected_module_sdk_idx;
-
- bool
- UpdateSDKDirectoryInfosIfNeeded();
-
- const char *
- GetDeviceSupportDirectory();
-
- const char *
- GetDeviceSupportDirectoryForOSVersion();
-
- const SDKDirectoryInfo *
- GetSDKDirectoryForLatestOSVersion ();
-
- const SDKDirectoryInfo *
- GetSDKDirectoryForCurrentOSVersion ();
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback (void *baton,
- lldb_private::FileSpec::FileType file_type,
- const lldb_private::FileSpec &file_spec);
-
- uint32_t
- FindFileInAllSDKs (const char *platform_file_path,
- lldb_private::FileSpecList &file_list);
-
- bool
- GetFileInSDK (const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file);
-
- bool
- GetFileInSDKRoot (const char *platform_file_path,
- const char *sdkroot_path,
- bool symbols_dirs_only,
- lldb_private::FileSpec &local_file);
-
- uint32_t
- FindFileInAllSDKs (const lldb_private::FileSpec &platform_file,
- lldb_private::FileSpecList &file_list);
-
- uint32_t
- GetConnectedSDKIndex ();
-
- // Get index of SDK in SDKDirectoryInfoCollection by its pointer and return UINT32_MAX if that SDK not found.
- uint32_t
- GetSDKIndexBySDKDirectoryInfo (const SDKDirectoryInfo *sdk_info);
+ struct SDKDirectoryInfo {
+ SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
+ lldb_private::FileSpec directory;
+ lldb_private::ConstString build;
+ uint32_t version_major;
+ uint32_t version_minor;
+ uint32_t version_update;
+ bool user_cached;
+ };
+
+ typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
+
+ std::mutex m_sdk_dir_mutex;
+ SDKDirectoryInfoCollection m_sdk_directory_infos;
+ std::string m_device_support_directory;
+ std::string m_device_support_directory_for_os_version;
+ std::string m_build_update;
+ uint32_t m_last_module_sdk_idx;
+ uint32_t m_connected_module_sdk_idx;
+
+ bool UpdateSDKDirectoryInfosIfNeeded();
+
+ const char *GetDeviceSupportDirectory();
+
+ const char *GetDeviceSupportDirectoryForOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, lldb_private::FileSpec::FileType file_type,
+ const lldb_private::FileSpec &file_spec);
+
+ uint32_t FindFileInAllSDKs(const char *platform_file_path,
+ lldb_private::FileSpecList &file_list);
+
+ bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file);
+
+ uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
+ lldb_private::FileSpecList &file_list);
+
+ uint32_t GetConnectedSDKIndex();
+
+ // Get index of SDK in SDKDirectoryInfoCollection by its pointer and return
+ // UINT32_MAX if that SDK not found.
+ uint32_t GetSDKIndexBySDKDirectoryInfo(const SDKDirectoryInfo *sdk_info);
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformRemoteiOS);
+ DISALLOW_COPY_AND_ASSIGN(PlatformRemoteiOS);
};
#endif // liblldb_PlatformRemoteiOS_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
index 99b9324417b5..b4ce0830598b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
@@ -1,4 +1,5 @@
-//===-- PlatformiOSSimulator.cpp -----------------------------------*- C++ -*-===//
+//===-- PlatformiOSSimulator.cpp -----------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -39,142 +40,122 @@ static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-void
-PlatformiOSSimulator::Initialize ()
-{
- PlatformAppleSimulator::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
- PluginManager::RegisterPlugin (PlatformiOSSimulator::GetPluginNameStatic(),
- PlatformiOSSimulator::GetDescriptionStatic(),
- PlatformiOSSimulator::CreateInstance);
- }
+void PlatformiOSSimulator::Initialize() {
+ PlatformAppleSimulator::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(PlatformiOSSimulator::GetPluginNameStatic(),
+ PlatformiOSSimulator::GetDescriptionStatic(),
+ PlatformiOSSimulator::CreateInstance);
+ }
}
-void
-PlatformiOSSimulator::Terminate ()
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
- PluginManager::UnregisterPlugin (PlatformiOSSimulator::CreateInstance);
- }
+void PlatformiOSSimulator::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformiOSSimulator::CreateInstance);
}
-
- PlatformAppleSimulator::Terminate ();
-}
+ }
-PlatformSP
-PlatformiOSSimulator::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>";
+ PlatformAppleSimulator::Terminate();
+}
- log->Printf ("PlatformiOSSimulator::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
- }
+PlatformSP PlatformiOSSimulator::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("PlatformiOSSimulator::%s(force=%s, arch={%s,%s})",
+ __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
+ }
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ switch (arch->GetMachine()) {
+ case llvm::Triple::x86_64:
+ case llvm::Triple::x86: {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::Apple:
+ create = true;
+ break;
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- switch (arch->GetMachine())
- {
- case llvm::Triple::x86_64:
- case llvm::Triple::x86:
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- 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::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ // Only accept "unknown" for the vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
#endif
- default:
- break;
- }
-
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::Darwin: // Deprecated, but still support Darwin for historical reasons
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS: // IOS is not used for simulator triples, but accept it just in case
- break;
-
+ default:
+ break;
+ }
+
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
+ // historical reasons
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS: // IOS is not used for simulator triples, but
+ // accept it just in case
+ break;
+
#if defined(__APPLE__)
- // Only accept "unknown" for the OS if the host is Apple and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
- case llvm::Triple::UnknownOS:
- create = !arch->TripleOSWasSpecified();
- break;
+ // Only accept "unknown" for the OS if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownOS:
+ create = !arch->TripleOSWasSpecified();
+ break;
#endif
- default:
- create = false;
- break;
- }
- }
- }
- break;
- default:
- break;
+ default:
+ create = false;
+ break;
}
+ }
+ } break;
+ default:
+ break;
}
- if (create)
- {
- if (log)
- log->Printf ("PlatformiOSSimulator::%s() creating platform", __FUNCTION__);
-
- return PlatformSP(new PlatformiOSSimulator ());
- }
-
+ }
+ if (create) {
if (log)
- log->Printf ("PlatformiOSSimulator::%s() aborting creation of platform", __FUNCTION__);
+ log->Printf("PlatformiOSSimulator::%s() creating platform", __FUNCTION__);
- return PlatformSP();
-}
+ return PlatformSP(new PlatformiOSSimulator());
+ }
+ if (log)
+ log->Printf("PlatformiOSSimulator::%s() aborting creation of platform",
+ __FUNCTION__);
-lldb_private::ConstString
-PlatformiOSSimulator::GetPluginNameStatic ()
-{
- static ConstString g_name("ios-simulator");
- return g_name;
+ return PlatformSP();
}
-const char *
-PlatformiOSSimulator::GetDescriptionStatic()
-{
- return "iOS simulator platform plug-in.";
+lldb_private::ConstString PlatformiOSSimulator::GetPluginNameStatic() {
+ static ConstString g_name("ios-simulator");
+ return g_name;
}
+const char *PlatformiOSSimulator::GetDescriptionStatic() {
+ return "iOS simulator platform plug-in.";
+}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformiOSSimulator::PlatformiOSSimulator () :
-PlatformAppleSimulator (),
-m_sdk_directory ()
-{
-}
+PlatformiOSSimulator::PlatformiOSSimulator()
+ : PlatformAppleSimulator(), m_sdk_dir_mutex(), m_sdk_directory(),
+ m_build_update() {}
//------------------------------------------------------------------
/// Destructor.
@@ -182,321 +163,261 @@ m_sdk_directory ()
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformiOSSimulator::~PlatformiOSSimulator()
-{
+PlatformiOSSimulator::~PlatformiOSSimulator() {}
+
+void PlatformiOSSimulator::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ const char *sdk_directory = GetSDKDirectoryAsCString();
+ if (sdk_directory)
+ strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
+ else
+ strm.PutCString(" SDK Path: error: unable to locate SDK\n");
+ PlatformAppleSimulator::GetStatus(strm);
}
-
-void
-PlatformiOSSimulator::GetStatus (Stream &strm)
-{
- Platform::GetStatus (strm);
- const char *sdk_directory = GetSDKDirectoryAsCString();
- if (sdk_directory)
- strm.Printf (" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString (" SDK Path: error: unable to locate SDK\n");
- PlatformAppleSimulator::GetStatus(strm);
-}
-
-
-Error
-PlatformiOSSimulator::ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(module_spec);
-
- // If we have "ls" as the exe_file, resolve the executable loation based on
- // the current path variables
- // TODO: resolve bare executables in the Platform SDK
- // if (!resolved_exe_file.Exists())
- // resolved_exe_file.ResolveExecutableLocation ();
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one ourselves
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- ArchSpec platform_arch;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- // Only match x86 with x86 and x86_64 with x86_64...
- if (!module_spec.GetArchitecture().IsValid() || module_spec.GetArchitecture().GetCore() == resolved_module_spec.GetArchitecture().GetCore())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- NULL,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (platform_arch.GetArchitectureName());
- }
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
+Error PlatformiOSSimulator::ResolveExecutable(
+ const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(module_spec);
+
+ // If we have "ls" as the exe_file, resolve the executable loation based on
+ // the current path variables
+ // TODO: resolve bare executables in the Platform SDK
+ // if (!resolved_exe_file.Exists())
+ // resolved_exe_file.ResolveExecutableLocation ();
+
+ // Resolve any executable within a bundle on MacOSX
+ // TODO: verify that this handles shallow bundles, if not then implement one
+ // ourselves
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
+ }
+ // No valid architecture was specified or the exact ARM slice wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ ArchSpec platform_arch;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ // Only match x86 with x86 and x86_64 with x86_64...
+ if (!module_spec.GetArchitecture().IsValid() ||
+ module_spec.GetArchitecture().GetCore() ==
+ resolved_module_spec.GetArchitecture().GetCore()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(platform_arch.GetArchitectureName());
+ }
}
- else
- {
- error.SetErrorStringWithFormat ("'%s' does not exist",
- module_spec.GetFileSpec().GetPath().c_str());
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetString().str().c_str());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
}
-
- return error;
+ } else {
+ error.SetErrorStringWithFormat("'%s' does not exist",
+ module_spec.GetFileSpec().GetPath().c_str());
+ }
+
+ return error;
}
static FileSpec::EnumerateDirectoryResult
-EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec)
-{
- if (file_type == FileSpec::eFileTypeDirectory)
- {
- 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;
- }
+EnumerateDirectoryCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ if (file_type == FileSpec::eFileTypeDirectory) {
+ 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 FileSpec::eEnumerateDirectoryResultNext;
+ }
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-
-
-const char *
-PlatformiOSSimulator::GetSDKDirectoryAsCString()
-{
- std::lock_guard<std::mutex> guard(m_mutex);
- if (m_sdk_directory.empty())
- {
- const char *developer_dir = GetDeveloperDirectory();
- if (developer_dir)
- {
- char sdks_directory[PATH_MAX];
- char sdk_dirname[PATH_MAX];
- sdk_dirname[0] = '\0';
- snprintf (sdks_directory,
- sizeof(sdks_directory),
- "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs",
- developer_dir);
- FileSpec simulator_sdk_spec;
- 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);
-
- if (sdk_dirname[0])
- {
- m_sdk_directory = sdks_directory;
- m_sdk_directory.append (1, '/');
- m_sdk_directory.append (sdk_dirname);
- return m_sdk_directory.c_str();
- }
- }
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_sdk_directory.assign (1, '\0');
- }
-
- // We should have put a single NULL character into m_sdk_directory
- // or it should have a valid path if the code gets here
- assert (m_sdk_directory.empty() == false);
- if (m_sdk_directory[0])
+const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() {
+ std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
+ if (m_sdk_directory.empty()) {
+ const char *developer_dir = GetDeveloperDirectory();
+ if (developer_dir) {
+ char sdks_directory[PATH_MAX];
+ char sdk_dirname[PATH_MAX];
+ sdk_dirname[0] = '\0';
+ snprintf(sdks_directory, sizeof(sdks_directory),
+ "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs",
+ developer_dir);
+ FileSpec simulator_sdk_spec;
+ 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);
+
+ if (sdk_dirname[0]) {
+ m_sdk_directory = sdks_directory;
+ m_sdk_directory.append(1, '/');
+ m_sdk_directory.append(sdk_dirname);
return m_sdk_directory.c_str();
- return NULL;
-}
-
-Error
-PlatformiOSSimulator::GetSymbolFile (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
- {
- char resolved_path[PATH_MAX];
-
- const char * sdk_dir = GetSDKDirectoryAsCString();
- if (sdk_dir)
- {
- ::snprintf (resolved_path,
- sizeof(resolved_path),
- "%s/%s",
- sdk_dir,
- platform_file_path);
-
- // First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists())
- return error;
-
- // Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true);
- if (local_file.Exists())
- return error;
-
- }
- error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path,
- GetPluginName().GetCString());
- }
- else
- {
- error.SetErrorString ("invalid platform file argument");
+ }
}
- return error;
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_sdk_directory.assign(1, '\0');
+ }
+
+ // We should have put a single NULL character into m_sdk_directory
+ // or it should have a valid path if the code gets here
+ assert(m_sdk_directory.empty() == false);
+ if (m_sdk_directory[0])
+ return m_sdk_directory.c_str();
+ return NULL;
}
-Error
-PlatformiOSSimulator::GetSharedModule (const ModuleSpec &module_spec,
- Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- // For iOS, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- Error error;
- ModuleSpec platform_module_spec (module_spec);
- const FileSpec &platform_file = module_spec.GetFileSpec();
- error = GetSymbolFile (platform_file, module_spec.GetUUIDPtr(), platform_module_spec.GetFileSpec());
- if (error.Success())
- {
- error = ResolveExecutable (platform_module_spec, module_sp, module_search_paths_ptr);
- }
- else
- {
- const bool always_create = false;
- error = ModuleList::GetSharedModule (module_spec,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr,
- always_create);
-
+Error PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ Error error;
+ char platform_file_path[PATH_MAX];
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ char resolved_path[PATH_MAX];
+
+ const char *sdk_dir = GetSDKDirectoryAsCString();
+ if (sdk_dir) {
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
+ platform_file_path);
+
+ // First try in the SDK and see if the file is in there
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists())
+ return error;
+
+ // Else fall back to the actual path itself
+ local_file.SetFile(platform_file_path, true);
+ if (local_file.Exists())
+ return error;
}
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
+ error.SetErrorStringWithFormat(
+ "unable to locate a platform file for '%s' in platform '%s'",
+ platform_file_path, GetPluginName().GetCString());
+ } else {
+ error.SetErrorString("invalid platform file argument");
+ }
+ return error;
}
+Error PlatformiOSSimulator::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ // For iOS, the SDK files are all cached locally on the host
+ // system. So first we ask for the file in the cached SDK,
+ // then we attempt to get a shared module for the right architecture
+ // with the right UUID.
+ Error error;
+ ModuleSpec platform_module_spec(module_spec);
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
+ platform_module_spec.GetFileSpec());
+ if (error.Success()) {
+ error = ResolveExecutable(platform_module_spec, module_sp,
+ module_search_paths_ptr);
+ } else {
+ const bool always_create = false;
+ error = ModuleList::GetSharedModule(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr, always_create);
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
+
+ return error;
+}
uint32_t
-PlatformiOSSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- ProcessInstanceInfoList all_osx_process_infos;
- // First we get all OSX processes
- const uint32_t n = Host::FindProcesses (match_info, all_osx_process_infos);
-
- // Now we filter them down to only the iOS triples
- for (uint32_t i=0; i<n; ++i)
- {
- const ProcessInstanceInfo &proc_info = all_osx_process_infos.GetProcessInfoAtIndex(i);
- if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::IOS) {
- process_infos.Append(proc_info);
- }
+PlatformiOSSimulator::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ ProcessInstanceInfoList all_osx_process_infos;
+ // First we get all OSX processes
+ const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
+
+ // Now we filter them down to only the iOS triples
+ for (uint32_t i = 0; i < n; ++i) {
+ const ProcessInstanceInfo &proc_info =
+ all_osx_process_infos.GetProcessInfoAtIndex(i);
+ if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::IOS) {
+ process_infos.Append(proc_info);
}
- return process_infos.GetSize();
+ }
+ return process_infos.GetSize();
}
-bool
-PlatformiOSSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- static const ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
- static const ArchSpec platform_arch64(HostInfo::GetArchitecture(HostInfo::eArchKind64));
-
- if (idx == 0)
- {
- arch = platform_arch;
- if (arch.IsValid())
- {
- arch.GetTriple().setOS (llvm::Triple::IOS);
- return true;
- }
+bool PlatformiOSSimulator::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ static const ArchSpec platform_arch(
+ HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
+ static const ArchSpec platform_arch64(
+ HostInfo::GetArchitecture(HostInfo::eArchKind64));
+
+ if (idx == 0) {
+ arch = platform_arch;
+ if (arch.IsValid()) {
+ arch.GetTriple().setOS(llvm::Triple::IOS);
+ return true;
}
- else
- {
- if (platform_arch.IsExactMatch(platform_arch64))
- {
- // This macosx platform supports both 32 and 64 bit.
- if (idx == 1)
- {
- // 32/64: return "x86_64-apple-macosx" for architecture 1
- arch = platform_arch64;
- return true;
- }
- else if (idx == 2 || idx == 3)
- {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- if (arch.IsValid())
- {
- if (idx == 2)
- arch.GetTriple().setOS (llvm::Triple::IOS);
- // 32/64: return "i386-apple-ios" for architecture 2
- // 32/64: return "i386-apple-macosx" for architecture 3
- return true;
- }
- }
- }
- else if (idx == 1)
- {
- // This macosx platform supports only 32 bit, so return the *-apple-macosx version
- arch = platform_arch;
- return true;
+ } else {
+ if (platform_arch.IsExactMatch(platform_arch64)) {
+ // This macosx platform supports both 32 and 64 bit.
+ if (idx == 1) {
+ // 32/64: return "x86_64-apple-macosx" for architecture 1
+ arch = platform_arch64;
+ return true;
+ } else if (idx == 2 || idx == 3) {
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ if (arch.IsValid()) {
+ if (idx == 2)
+ arch.GetTriple().setOS(llvm::Triple::IOS);
+ // 32/64: return "i386-apple-ios" for architecture 2
+ // 32/64: return "i386-apple-macosx" for architecture 3
+ return true;
}
+ }
+ } else if (idx == 1) {
+ // This macosx platform supports only 32 bit, so return the *-apple-macosx
+ // version
+ arch = platform_arch;
+ return true;
}
- return false;
+ }
+ return false;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
index f84d04b9c485..c8c7872b530d 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
@@ -12,105 +12,88 @@
// C Includes
// C++ Includes
+#include <mutex>
#include <string>
// Other libraries and framework includes
// Project includes
#include "PlatformAppleSimulator.h"
-class PlatformiOSSimulator : public PlatformAppleSimulator
-{
+class PlatformiOSSimulator : public PlatformAppleSimulator {
public:
- PlatformiOSSimulator ();
-
- ~PlatformiOSSimulator() override;
-
- //------------------------------------------------------------
- // 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
- //------------------------------------------------------------
- lldb_private::Error
- ResolveExecutable (const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic();
- }
-
- void
- GetStatus (lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile (const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule (const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
- uint32_t
- FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx,
- lldb_private::ArchSpec &arch) override;
-
- void
- AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override
- {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneSimulator);
- }
-
+ PlatformiOSSimulator();
+
+ ~PlatformiOSSimulator() override;
+
+ //------------------------------------------------------------
+ // 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
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ virtual lldb_private::Error
+ GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ uint32_t
+ FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
+ lldb_private::ProcessInstanceInfoList &process_infos) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::iPhoneSimulator);
+ }
+
protected:
- std::string m_sdk_directory;
- std::string m_build_update;
-
- const char *
- GetSDKDirectoryAsCString();
-
+ std::mutex m_sdk_dir_mutex;
+ std::string m_sdk_directory;
+ std::string m_build_update;
+
+ const char *GetSDKDirectoryAsCString();
+
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformiOSSimulator);
+ DISALLOW_COPY_AND_ASSIGN(PlatformiOSSimulator);
};
#endif // liblldb_PlatformiOSSimulator_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h b/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h
index 8393ea304906..c132dc6fa433 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.h
@@ -1,4 +1,5 @@
-//===-- PlatformiOSSimulatorCoreSimulatorSupport.h ----------------*- C++ -*-===//
+//===-- PlatformiOSSimulatorCoreSimulatorSupport.h ----------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,8 +14,8 @@
// C Includes
// C++ Includes
#include <functional>
-#include <string>
#include <ostream>
+#include <string>
#include <vector>
// Other libraries and framework includes
#ifdef __APPLE__
@@ -31,285 +32,194 @@ typedef void *id;
#include "llvm/ADT/Optional.h"
// And now the actual magic
-namespace CoreSimulatorSupport
-{
- class Process
- {
- public:
- lldb::pid_t
- GetPID ()
- {
- return m_pid;
- }
-
- explicit operator bool ()
- {
- return m_pid != LLDB_INVALID_PROCESS_ID;
- }
-
- lldb_private::Error
- GetError ()
- {
- return m_error;
- }
-
- private:
- Process (lldb::pid_t p);
-
- Process(lldb_private::Error error);
-
- Process (lldb::pid_t p, lldb_private::Error error);
-
- lldb::pid_t m_pid;
- lldb_private::Error m_error;
-
- friend class Device;
- };
-
- class ModelIdentifier {
- public:
- ModelIdentifier (const std::string& mi);
- ModelIdentifier ();
-
- explicit operator bool () const
- {
- return !m_versions.empty();
- }
-
- size_t
- GetNumVersions () const
- {
- return m_versions.size();
- }
-
- unsigned int
- GetVersionAtIndex (size_t idx) const
- {
- return m_versions[idx];
- }
-
- std::string
- GetFamily () const
- {
- return m_family.c_str();
- }
-
- private:
- std::string m_family;
- std::vector<unsigned int> m_versions;
- };
-
- class DeviceType
- {
- public:
- enum class ProductFamilyID : int32_t
- {
- iPhone = 1,
- iPad = 2,
- appleTV = 3,
- appleWatch = 4
- };
-
- DeviceType ();
-
- DeviceType (id d);
-
- explicit operator bool ();
-
- std::string
- GetName ();
-
- lldb_private::ConstString
- GetIdentifier ();
-
- ModelIdentifier
- GetModelIdentifier ();
-
- lldb_private::ConstString
- GetProductFamily ();
-
- ProductFamilyID
- GetProductFamilyID ();
-
- private:
- id m_dev;
- llvm::Optional<ModelIdentifier> m_model_identifier;
- };
-
- class OSVersion {
- public:
- OSVersion (const std::string& ver,
- const std::string& build);
-
- OSVersion ();
-
- explicit operator bool () const
- {
- return !m_versions.empty();
- }
-
- size_t
- GetNumVersions () const
- {
- return m_versions.size();
- }
-
- unsigned int
- GetVersionAtIndex (size_t idx) const
- {
- return m_versions[idx];
- }
-
- const char*
- GetBuild () const
- {
- return m_build.c_str();
- }
-
- private:
- std::vector<unsigned int> m_versions;
- std::string m_build;
- };
-
- class DeviceRuntime
- {
- public:
- DeviceRuntime ();
-
- DeviceRuntime (id d);
-
- explicit operator bool ();
-
- OSVersion
- GetVersion ();
-
- bool
- IsAvailable ();
-
- private:
- id m_dev;
- llvm::Optional<OSVersion> m_os_version;
- };
-
- class Device
- {
- private:
- typedef unsigned long int NSUInteger;
-
- public:
- enum class State : NSUInteger
- {
- Creating,
- Shutdown,
- Booting,
- Booted,
- ShuttingDown
- };
-
- Device ();
-
- Device (id d);
-
- explicit operator bool ();
-
- std::string
- GetName () const;
-
- DeviceType
- GetDeviceType ();
-
- DeviceRuntime
- GetDeviceRuntime ();
-
- State
- GetState ();
-
- bool
- Boot (lldb_private::Error &err);
-
- bool
- Shutdown (lldb_private::Error &err);
-
- std::string
- GetUDID () const;
-
- Process
- Spawn (lldb_private::ProcessLaunchInfo& launch_info);
-
- private:
- id m_dev;
- llvm::Optional<DeviceType> m_dev_type;
- llvm::Optional<DeviceRuntime> m_dev_runtime;
-
- friend class DeviceSet;
- };
-
- bool
- operator > (const OSVersion& lhs,
- const OSVersion& rhs);
-
- bool
- operator > (const ModelIdentifier& lhs,
- const ModelIdentifier& rhs);
-
- bool
- operator < (const OSVersion& lhs,
- const OSVersion& rhs);
-
- bool
- operator < (const ModelIdentifier& lhs,
- const ModelIdentifier& rhs);
-
- bool
- operator == (const OSVersion& lhs,
- const OSVersion& rhs);
-
- bool
- operator == (const ModelIdentifier& lhs,
- const ModelIdentifier& rhs);
-
- bool
- operator != (const OSVersion& lhs,
- const OSVersion& rhs);
-
- bool
- operator != (const ModelIdentifier& lhs,
- const ModelIdentifier& rhs);
-
- class DeviceSet
- {
- public:
- static DeviceSet
- GetAllDevices ();
-
- static DeviceSet
- GetAvailableDevices ();
-
- size_t
- GetNumDevices ();
-
- Device
- GetDeviceAtIndex (size_t idx);
-
- void
- ForEach (std::function<bool(const Device &)> f);
-
- DeviceSet
- GetDevicesIf (std::function<bool(Device)> f);
-
- DeviceSet
- GetDevices (DeviceType::ProductFamilyID dev_id);
-
- Device
- GetFanciest (DeviceType::ProductFamilyID dev_id);
-
- private:
- DeviceSet (id arr) : m_dev(arr)
- {
- }
-
- id m_dev;
- };
+namespace CoreSimulatorSupport {
+class Process {
+public:
+ lldb::pid_t GetPID() { return m_pid; }
+
+ explicit operator bool() { return m_pid != LLDB_INVALID_PROCESS_ID; }
+
+ lldb_private::Error GetError() { return m_error; }
+
+private:
+ Process(lldb::pid_t p);
+
+ Process(lldb_private::Error error);
+
+ Process(lldb::pid_t p, lldb_private::Error error);
+
+ lldb::pid_t m_pid;
+ lldb_private::Error m_error;
+
+ friend class Device;
+};
+
+class ModelIdentifier {
+public:
+ ModelIdentifier(const std::string &mi);
+ ModelIdentifier();
+
+ explicit operator bool() const { return !m_versions.empty(); }
+
+ size_t GetNumVersions() const { return m_versions.size(); }
+
+ unsigned int GetVersionAtIndex(size_t idx) const { return m_versions[idx]; }
+
+ std::string GetFamily() const { return m_family.c_str(); }
+
+private:
+ std::string m_family;
+ std::vector<unsigned int> m_versions;
+};
+
+class DeviceType {
+public:
+ enum class ProductFamilyID : int32_t {
+ iPhone = 1,
+ iPad = 2,
+ appleTV = 3,
+ appleWatch = 4
+ };
+
+ DeviceType();
+
+ DeviceType(id d);
+
+ explicit operator bool();
+
+ std::string GetName();
+
+ lldb_private::ConstString GetIdentifier();
+
+ ModelIdentifier GetModelIdentifier();
+
+ lldb_private::ConstString GetProductFamily();
+
+ ProductFamilyID GetProductFamilyID();
+
+private:
+ id m_dev;
+ llvm::Optional<ModelIdentifier> m_model_identifier;
+};
+
+class OSVersion {
+public:
+ OSVersion(const std::string &ver, const std::string &build);
+
+ OSVersion();
+
+ explicit operator bool() const { return !m_versions.empty(); }
+
+ size_t GetNumVersions() const { return m_versions.size(); }
+
+ unsigned int GetVersionAtIndex(size_t idx) const { return m_versions[idx]; }
+
+ const char *GetBuild() const { return m_build.c_str(); }
+
+private:
+ std::vector<unsigned int> m_versions;
+ std::string m_build;
+};
+
+class DeviceRuntime {
+public:
+ DeviceRuntime();
+
+ DeviceRuntime(id d);
+
+ explicit operator bool();
+
+ OSVersion GetVersion();
+
+ bool IsAvailable();
+
+private:
+ id m_dev;
+ llvm::Optional<OSVersion> m_os_version;
+};
+
+class Device {
+private:
+ typedef unsigned long int NSUInteger;
+
+public:
+ enum class State : NSUInteger {
+ Creating,
+ Shutdown,
+ Booting,
+ Booted,
+ ShuttingDown
+ };
+
+ Device();
+
+ Device(id d);
+
+ explicit operator bool();
+
+ std::string GetName() const;
+
+ DeviceType GetDeviceType();
+
+ DeviceRuntime GetDeviceRuntime();
+
+ State GetState();
+
+ bool Boot(lldb_private::Error &err);
+
+ bool Shutdown(lldb_private::Error &err);
+
+ std::string GetUDID() const;
+
+ Process Spawn(lldb_private::ProcessLaunchInfo &launch_info);
+
+private:
+ id m_dev;
+ llvm::Optional<DeviceType> m_dev_type;
+ llvm::Optional<DeviceRuntime> m_dev_runtime;
+
+ friend class DeviceSet;
+};
+
+bool operator>(const OSVersion &lhs, const OSVersion &rhs);
+
+bool operator>(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
+
+bool operator<(const OSVersion &lhs, const OSVersion &rhs);
+
+bool operator<(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
+
+bool operator==(const OSVersion &lhs, const OSVersion &rhs);
+
+bool operator==(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
+
+bool operator!=(const OSVersion &lhs, const OSVersion &rhs);
+
+bool operator!=(const ModelIdentifier &lhs, const ModelIdentifier &rhs);
+
+class DeviceSet {
+public:
+ static DeviceSet GetAllDevices(const char *developer_dir);
+
+ static DeviceSet GetAvailableDevices(const char *developer_dir);
+
+ size_t GetNumDevices();
+
+ Device GetDeviceAtIndex(size_t idx);
+
+ void ForEach(std::function<bool(const Device &)> f);
+
+ DeviceSet GetDevicesIf(std::function<bool(Device)> f);
+
+ DeviceSet GetDevices(DeviceType::ProductFamilyID dev_id);
+
+ Device GetFanciest(DeviceType::ProductFamilyID dev_id);
+
+private:
+ DeviceSet(id arr) : m_dev(arr) {}
+
+ id m_dev;
+};
}
-#endif // liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_
+#endif // liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm b/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
index 7075de552529..233c548eb37b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -1,4 +1,5 @@
-//===-- PlatformiOSSimulatorCoreSimulatorSupport.cpp ---------------*- C++ -*-===//
+//===-- PlatformiOSSimulatorCoreSimulatorSupport.cpp ---------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,635 +23,503 @@
using namespace lldb_private;
using namespace lldb_utility;
-// CoreSimulator lives as part of Xcode, which means we can't really link against it, so we dlopen()
+// CoreSimulator lives as part of Xcode, which means we can't really link
+// against it, so we dlopen()
// it at runtime, and error out nicely if that fails
-@interface SimDeviceSet
-{}
-+ (id) defaultSet;
+@interface SimServiceContext {
+}
++ (id)sharedServiceContextForDeveloperDir:(NSString *)dir
+ error:(NSError **)error;
@end
-// However, the drawback is that the compiler will not know about the selectors we're trying to use
-// until runtime; to appease clang in this regard, define a fake protocol on NSObject that exposes
+// However, the drawback is that the compiler will not know about the selectors
+// we're trying to use
+// until runtime; to appease clang in this regard, define a fake protocol on
+// NSObject that exposes
// the needed interface names for us
@protocol LLDBCoreSimulatorSupport <NSObject>
-- (NSArray *) devices;
-- (id) deviceType;
-- (NSString *) name;
-- (NSString *) identifier;
-- (NSString *) modelIdentifier;
-- (NSString *) productFamily;
-- (int32_t) productFamilyID;
-- (id) runtime;
-- (BOOL) available;
-- (NSString *) versionString;
-- (NSString *) buildVersionString;
-- (BOOL) bootWithOptions:(NSDictionary *)options error:(NSError**)error;
-- (NSUInteger) state;
-- (BOOL) shutdownWithError:(NSError **)error;
-- (NSUUID *) UDID;
-- (pid_t) spawnWithPath:(NSString *)path options:(NSDictionary *)options terminationHandler:(void (^)(int status)) terminationHandler error:(NSError **)error;
+- (id)defaultDeviceSetWithError:(NSError **)error;
+- (NSArray *)devices;
+- (id)deviceType;
+- (NSString *)name;
+- (NSString *)identifier;
+- (NSString *)modelIdentifier;
+- (NSString *)productFamily;
+- (int32_t)productFamilyID;
+- (id)runtime;
+- (BOOL)available;
+- (NSString *)versionString;
+- (NSString *)buildVersionString;
+- (BOOL)bootWithOptions:(NSDictionary *)options error:(NSError **)error;
+- (NSUInteger)state;
+- (BOOL)shutdownWithError:(NSError **)error;
+- (NSUUID *)UDID;
+- (pid_t)spawnWithPath:(NSString *)path
+ options:(NSDictionary *)options
+ terminationHandler:(void (^)(int status))terminationHandler
+ error:(NSError **)error;
@end
-CoreSimulatorSupport::Process::Process (lldb::pid_t p) :
- m_pid (p),
- m_error ()
-{
-}
-
-CoreSimulatorSupport::Process::Process(Error error) :
- m_pid (LLDB_INVALID_PROCESS_ID),
- m_error (error)
-{
-}
+CoreSimulatorSupport::Process::Process(lldb::pid_t p) : m_pid(p), m_error() {}
-CoreSimulatorSupport::Process::Process (lldb::pid_t p, Error error) :
- m_pid (p),
- m_error (error)
-{
-}
+CoreSimulatorSupport::Process::Process(Error error)
+ : m_pid(LLDB_INVALID_PROCESS_ID), m_error(error) {}
+CoreSimulatorSupport::Process::Process(lldb::pid_t p, Error error)
+ : m_pid(p), m_error(error) {}
-CoreSimulatorSupport::DeviceType::DeviceType () :
- m_dev (nil),
- m_model_identifier ()
-{
-}
+CoreSimulatorSupport::DeviceType::DeviceType()
+ : m_dev(nil), m_model_identifier() {}
-CoreSimulatorSupport::DeviceType::DeviceType (id d) :
- m_dev (d),
- m_model_identifier ()
-{
-}
+CoreSimulatorSupport::DeviceType::DeviceType(id d)
+ : m_dev(d), m_model_identifier() {}
-CoreSimulatorSupport::DeviceType::operator bool ()
-{
- return m_dev != nil;
-}
+CoreSimulatorSupport::DeviceType::operator bool() { return m_dev != nil; }
-ConstString
-CoreSimulatorSupport::DeviceType::GetIdentifier ()
-{
- return ConstString( [[m_dev identifier] UTF8String] );
+ConstString CoreSimulatorSupport::DeviceType::GetIdentifier() {
+ return ConstString([[m_dev identifier] UTF8String]);
}
-ConstString
-CoreSimulatorSupport::DeviceType::GetProductFamily ()
-{
- return ConstString( [[m_dev productFamily] UTF8String] );
+ConstString CoreSimulatorSupport::DeviceType::GetProductFamily() {
+ return ConstString([[m_dev productFamily] UTF8String]);
}
CoreSimulatorSupport::DeviceType::ProductFamilyID
-CoreSimulatorSupport::DeviceType::GetProductFamilyID ()
-{
- return ProductFamilyID([m_dev productFamilyID]);
+CoreSimulatorSupport::DeviceType::GetProductFamilyID() {
+ return ProductFamilyID([m_dev productFamilyID]);
}
-CoreSimulatorSupport::DeviceRuntime::DeviceRuntime () :
- m_dev (nil),
- m_os_version ()
-{
-}
+CoreSimulatorSupport::DeviceRuntime::DeviceRuntime()
+ : m_dev(nil), m_os_version() {}
-CoreSimulatorSupport::DeviceRuntime::DeviceRuntime (id d) :
- m_dev (d),
- m_os_version ()
-{
-}
+CoreSimulatorSupport::DeviceRuntime::DeviceRuntime(id d)
+ : m_dev(d), m_os_version() {}
-CoreSimulatorSupport::DeviceRuntime::operator bool ()
-{
- return m_dev != nil;
-}
+CoreSimulatorSupport::DeviceRuntime::operator bool() { return m_dev != nil; }
-bool
-CoreSimulatorSupport::DeviceRuntime::IsAvailable ()
-{
- return [m_dev available];
+bool CoreSimulatorSupport::DeviceRuntime::IsAvailable() {
+ return [m_dev available];
}
-CoreSimulatorSupport::Device::Device () :
- m_dev (nil),
- m_dev_type (),
- m_dev_runtime ()
-{
-}
+CoreSimulatorSupport::Device::Device()
+ : m_dev(nil), m_dev_type(), m_dev_runtime() {}
-CoreSimulatorSupport::Device::Device (id d) :
- m_dev (d),
- m_dev_type (),
- m_dev_runtime ()
-{
-}
+CoreSimulatorSupport::Device::Device(id d)
+ : m_dev(d), m_dev_type(), m_dev_runtime() {}
-CoreSimulatorSupport::Device::operator bool ()
-{
- return m_dev != nil;
-}
+CoreSimulatorSupport::Device::operator bool() { return m_dev != nil; }
-CoreSimulatorSupport::Device::State
-CoreSimulatorSupport::Device::GetState ()
-{
- return (State)([m_dev state]);
+CoreSimulatorSupport::Device::State CoreSimulatorSupport::Device::GetState() {
+ return (State)([m_dev state]);
}
-CoreSimulatorSupport::ModelIdentifier::ModelIdentifier (const std::string& mi) :
- m_family (),
- m_versions ()
-{
- bool any = false;
- bool first_digit = false;
- unsigned int val = 0;
-
- for (char c : mi)
- {
- any = true;
- if (::isdigit(c))
- {
- if (!first_digit)
- first_digit = true;
- val = 10*val + (c - '0');
- }
- else if (c == ',')
- {
- if (first_digit)
- {
- m_versions.push_back(val);
- val = 0;
- }
- else
- m_family.push_back(c);
- }
- else
- {
- if (first_digit)
- {
- m_family.clear();
- m_versions.clear();
- return;
- }
- else
- {
- m_family.push_back(c);
- }
- }
- }
-
- if (first_digit)
- m_versions.push_back(val);
-}
+CoreSimulatorSupport::ModelIdentifier::ModelIdentifier(const std::string &mi)
+ : m_family(), m_versions() {
+ bool any = false;
+ bool first_digit = false;
+ unsigned int val = 0;
-CoreSimulatorSupport::ModelIdentifier::ModelIdentifier () :
-ModelIdentifier("")
-{
-}
-
-CoreSimulatorSupport::OSVersion::OSVersion (const std::string& ver,
- const std::string& build) :
- m_versions (),
- m_build (build)
-{
- bool any = false;
- unsigned int val = 0;
- for (char c : ver)
- {
- if (c == '.')
- {
- m_versions.push_back(val);
- val = 0;
- }
- else if (::isdigit(c))
- {
- val = 10*val + (c - '0');
- any = true;
- }
- else
- {
- m_versions.clear();
- return;
- }
- }
- if (any)
+ for (char c : mi) {
+ any = true;
+ if (::isdigit(c)) {
+ if (!first_digit)
+ first_digit = true;
+ val = 10 * val + (c - '0');
+ } else if (c == ',') {
+ if (first_digit) {
m_versions.push_back(val);
+ val = 0;
+ } else
+ m_family.push_back(c);
+ } else {
+ if (first_digit) {
+ m_family.clear();
+ m_versions.clear();
+ return;
+ } else {
+ m_family.push_back(c);
+ }
+ }
+ }
+
+ if (first_digit)
+ m_versions.push_back(val);
+}
+
+CoreSimulatorSupport::ModelIdentifier::ModelIdentifier()
+ : ModelIdentifier("") {}
+
+CoreSimulatorSupport::OSVersion::OSVersion(const std::string &ver,
+ const std::string &build)
+ : m_versions(), m_build(build) {
+ bool any = false;
+ unsigned int val = 0;
+ for (char c : ver) {
+ if (c == '.') {
+ m_versions.push_back(val);
+ val = 0;
+ } else if (::isdigit(c)) {
+ val = 10 * val + (c - '0');
+ any = true;
+ } else {
+ m_versions.clear();
+ return;
+ }
+ }
+ if (any)
+ m_versions.push_back(val);
}
-CoreSimulatorSupport::OSVersion::OSVersion () :
- OSVersion("","")
-{
-}
+CoreSimulatorSupport::OSVersion::OSVersion() : OSVersion("", "") {}
CoreSimulatorSupport::ModelIdentifier
-CoreSimulatorSupport::DeviceType::GetModelIdentifier ()
-{
- if (!m_model_identifier.hasValue())
- {
- auto utf8_model_id = [[m_dev modelIdentifier] UTF8String];
- if (utf8_model_id && *utf8_model_id)
- m_model_identifier = ModelIdentifier (utf8_model_id);
- }
-
- if (m_model_identifier.hasValue())
- return m_model_identifier.getValue();
- else
- return ModelIdentifier();
+CoreSimulatorSupport::DeviceType::GetModelIdentifier() {
+ if (!m_model_identifier.hasValue()) {
+ auto utf8_model_id = [[m_dev modelIdentifier] UTF8String];
+ if (utf8_model_id && *utf8_model_id)
+ m_model_identifier = ModelIdentifier(utf8_model_id);
+ }
+
+ if (m_model_identifier.hasValue())
+ return m_model_identifier.getValue();
+ else
+ return ModelIdentifier();
}
CoreSimulatorSupport::OSVersion
-CoreSimulatorSupport::DeviceRuntime::GetVersion ()
-{
- if (!m_os_version.hasValue())
- {
- auto utf8_ver_string = [[m_dev versionString] UTF8String];
- auto utf8_build_ver = [[m_dev buildVersionString] UTF8String];
- if (utf8_ver_string && *utf8_ver_string &&
- utf8_build_ver && *utf8_build_ver)
- {
- m_os_version = OSVersion(utf8_ver_string, utf8_build_ver);
- }
+CoreSimulatorSupport::DeviceRuntime::GetVersion() {
+ if (!m_os_version.hasValue()) {
+ auto utf8_ver_string = [[m_dev versionString] UTF8String];
+ auto utf8_build_ver = [[m_dev buildVersionString] UTF8String];
+ if (utf8_ver_string && *utf8_ver_string && utf8_build_ver &&
+ *utf8_build_ver) {
+ m_os_version = OSVersion(utf8_ver_string, utf8_build_ver);
}
-
- if (m_os_version.hasValue())
- return m_os_version.getValue();
- return OSVersion();
+ }
+
+ if (m_os_version.hasValue())
+ return m_os_version.getValue();
+ return OSVersion();
}
-std::string
-CoreSimulatorSupport::DeviceType::GetName ()
-{
- auto utf8_name = [[m_dev name] UTF8String];
- if (utf8_name)
- return std::string(utf8_name);
- return "";
+std::string CoreSimulatorSupport::DeviceType::GetName() {
+ auto utf8_name = [[m_dev name] UTF8String];
+ if (utf8_name)
+ return std::string(utf8_name);
+ return "";
}
-std::string
-CoreSimulatorSupport::Device::GetName () const
-{
- auto utf8_name = [[m_dev name] UTF8String];
- if (utf8_name)
- return std::string(utf8_name);
- return "";
+std::string CoreSimulatorSupport::Device::GetName() const {
+ auto utf8_name = [[m_dev name] UTF8String];
+ if (utf8_name)
+ return std::string(utf8_name);
+ return "";
}
-std::string
-CoreSimulatorSupport::Device::GetUDID () const
-{
- auto utf8_udid = [ [[m_dev UDID] UUIDString] UTF8String];
- if (utf8_udid)
- return std::string(utf8_udid);
- else
- return std::string();
+std::string CoreSimulatorSupport::Device::GetUDID() const {
+ auto utf8_udid = [[[m_dev UDID] UUIDString] UTF8String];
+ if (utf8_udid)
+ return std::string(utf8_udid);
+ else
+ return std::string();
}
-CoreSimulatorSupport::DeviceType
-CoreSimulatorSupport::Device::GetDeviceType ()
-{
- if (!m_dev_type.hasValue())
- m_dev_type = DeviceType([m_dev deviceType]);
-
- return m_dev_type.getValue();
+CoreSimulatorSupport::DeviceType CoreSimulatorSupport::Device::GetDeviceType() {
+ if (!m_dev_type.hasValue())
+ m_dev_type = DeviceType([m_dev deviceType]);
+
+ return m_dev_type.getValue();
}
CoreSimulatorSupport::DeviceRuntime
-CoreSimulatorSupport::Device::GetDeviceRuntime ()
-{
- if (!m_dev_runtime.hasValue())
- m_dev_runtime = DeviceRuntime([m_dev runtime]);
-
- return m_dev_runtime.getValue();
-}
-
-bool
-CoreSimulatorSupport::operator > (const CoreSimulatorSupport::OSVersion& lhs,
- const CoreSimulatorSupport::OSVersion& rhs)
-{
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l > r)
- return true;
- }
- return false;
+CoreSimulatorSupport::Device::GetDeviceRuntime() {
+ if (!m_dev_runtime.hasValue())
+ m_dev_runtime = DeviceRuntime([m_dev runtime]);
+
+ return m_dev_runtime.getValue();
}
-bool
-CoreSimulatorSupport::operator > (const CoreSimulatorSupport::ModelIdentifier& lhs,
- const CoreSimulatorSupport::ModelIdentifier& rhs)
-{
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l > r)
- return true;
- }
- return false;
+bool CoreSimulatorSupport::
+operator>(const CoreSimulatorSupport::OSVersion &lhs,
+ const CoreSimulatorSupport::OSVersion &rhs) {
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l > r)
+ return true;
+ }
+ return false;
}
-bool
-CoreSimulatorSupport::operator < (const CoreSimulatorSupport::OSVersion& lhs,
- const CoreSimulatorSupport::OSVersion& rhs)
-{
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l < r)
- return true;
- }
+bool CoreSimulatorSupport::
+operator>(const CoreSimulatorSupport::ModelIdentifier &lhs,
+ const CoreSimulatorSupport::ModelIdentifier &rhs) {
+ if (lhs.GetFamily() != rhs.GetFamily())
+ return false;
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l > r)
+ return true;
+ }
+ return false;
+}
+
+bool CoreSimulatorSupport::
+operator<(const CoreSimulatorSupport::OSVersion &lhs,
+ const CoreSimulatorSupport::OSVersion &rhs) {
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l < r)
+ return true;
+ }
+ return false;
+}
+
+bool CoreSimulatorSupport::
+operator<(const CoreSimulatorSupport::ModelIdentifier &lhs,
+ const CoreSimulatorSupport::ModelIdentifier &rhs) {
+ if (lhs.GetFamily() != rhs.GetFamily())
return false;
-}
-bool
-CoreSimulatorSupport::operator < (const CoreSimulatorSupport::ModelIdentifier& lhs,
- const CoreSimulatorSupport::ModelIdentifier& rhs)
-{
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
-
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l < r)
- return true;
- }
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l < r)
+ return true;
+ }
+ return false;
+}
+
+bool CoreSimulatorSupport::
+operator==(const CoreSimulatorSupport::OSVersion &lhs,
+ const CoreSimulatorSupport::OSVersion &rhs) {
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l != r)
+ return false;
+ }
+ return true;
+}
+
+bool CoreSimulatorSupport::
+operator==(const CoreSimulatorSupport::ModelIdentifier &lhs,
+ const CoreSimulatorSupport::ModelIdentifier &rhs) {
+ if (lhs.GetFamily() != rhs.GetFamily())
return false;
-}
-bool
-CoreSimulatorSupport::operator == (const CoreSimulatorSupport::OSVersion& lhs,
- const CoreSimulatorSupport::OSVersion& rhs)
-{
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return false;
- }
- return true;
-}
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l != r)
+ return false;
+ }
+ return true;
+}
+
+bool CoreSimulatorSupport::
+operator!=(const CoreSimulatorSupport::OSVersion &lhs,
+ const CoreSimulatorSupport::OSVersion &rhs) {
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l != r)
+ return true;
+ }
+ return false;
+}
+
+bool CoreSimulatorSupport::
+operator!=(const CoreSimulatorSupport::ModelIdentifier &lhs,
+ const CoreSimulatorSupport::ModelIdentifier &rhs) {
+ if (lhs.GetFamily() != rhs.GetFamily())
+ return false;
-bool
-CoreSimulatorSupport::operator == (const CoreSimulatorSupport::ModelIdentifier& lhs,
- const CoreSimulatorSupport::ModelIdentifier& rhs)
-{
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
-
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return false;
- }
- return true;
+ for (size_t i = 0; i < rhs.GetNumVersions(); i++) {
+ unsigned int l = lhs.GetVersionAtIndex(i);
+ unsigned int r = rhs.GetVersionAtIndex(i);
+ if (l != r)
+ return true;
+ }
+ return false;
}
-bool
-CoreSimulatorSupport::operator != (const CoreSimulatorSupport::OSVersion& lhs,
- const CoreSimulatorSupport::OSVersion& rhs)
-{
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return true;
- }
+bool CoreSimulatorSupport::Device::Boot(Error &err) {
+ if (m_dev == nil) {
+ err.SetErrorString("no valid simulator instance");
return false;
-}
+ }
-bool
-CoreSimulatorSupport::operator != (const CoreSimulatorSupport::ModelIdentifier& lhs,
- const CoreSimulatorSupport::ModelIdentifier& rhs)
-{
- if (lhs.GetFamily() != rhs.GetFamily())
- return false;
-
- for (size_t i = 0;
- i < rhs.GetNumVersions();
- i++)
- {
- unsigned int l = lhs.GetVersionAtIndex(i);
- unsigned int r = rhs.GetVersionAtIndex(i);
- if (l != r)
- return true;
- }
- return false;
-}
+#define kSimDeviceBootPersist \
+ @"persist" /* An NSNumber (boolean) indicating whether or not the session \
+ should outlive the calling process (default false) */
-bool
-CoreSimulatorSupport::Device::Boot (Error &err)
-{
- if (m_dev == nil)
- {
- err.SetErrorString("no valid simulator instance");
- return false;
- }
+ NSDictionary *options = @{
+ kSimDeviceBootPersist : @NO,
+ };
-#define kSimDeviceBootEnv @"env" /* An NSDictionary of "extra" environment key/values */
-#define kSimDeviceBootPersist @"persist" /* An NSNumber (boolean) indicating whether or not the session should outlive the calling process (default false) */
-#define kSimDeviceBootDisabledJobs @"disabled_jobs" /* An NSDictionary of NSStrings -> NSNumbers, each string is the name of a job, and the value is the corresponding state (true if disabled) */
-
- NSDictionary *options = @{
- kSimDeviceBootPersist : @NO,
- kSimDeviceBootDisabledJobs : @{@"com.apple.backboardd" : @YES}
- };
-
-#undef kSimDeviceBootEnv
#undef kSimDeviceBootPersist
-#undef kSimDeviceBootDisabledJobs
-
- NSError* nserror;
- if ([m_dev bootWithOptions:options error:&nserror])
- {
- err.Clear();
- return true;
- }
- else
- {
- err.SetErrorString([[nserror description] UTF8String]);
- return false;
- }
-}
-bool
-CoreSimulatorSupport::Device::Shutdown (Error &err)
-{
- NSError* nserror;
- if ([m_dev shutdownWithError:&nserror])
- {
- err.Clear();
- return true;
- }
- else
- {
- err.SetErrorString([[nserror description] UTF8String]);
- return false;
- }
+ NSError *nserror;
+ if ([m_dev bootWithOptions:options error:&nserror]) {
+ err.Clear();
+ return true;
+ } else {
+ err.SetErrorString([[nserror description] UTF8String]);
+ return false;
+ }
}
-
-static Error
-HandleFileAction(ProcessLaunchInfo& launch_info,
- NSMutableDictionary *options,
- NSString *key,
- const int fd,
- File &file)
-{
- Error error;
- const FileAction *file_action = launch_info.GetFileActionForFD (fd);
- if (file_action)
- {
- switch (file_action->GetAction())
- {
- case FileAction::eFileActionNone:
- break;
-
- case FileAction::eFileActionClose:
- error.SetErrorStringWithFormat ("close file action for %i not supported", fd);
- break;
-
- case FileAction::eFileActionDuplicate:
- error.SetErrorStringWithFormat ("duplication file action for %i not supported", fd);
- break;
-
- case FileAction::eFileActionOpen:
- {
- FileSpec file_spec = file_action->GetFileSpec();
- if (file_spec)
- {
- const int master_fd = launch_info.GetPTY().GetMasterFileDescriptor();
- if (master_fd != PseudoTerminal::invalid_fd)
- {
- // 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);
- if (file_spec == slave_spec)
- {
- int slave_fd = launch_info.GetPTY().GetSlaveFileDescriptor();
- if (slave_fd == PseudoTerminal::invalid_fd)
- slave_fd = launch_info.GetPTY().OpenSlave(O_RDWR, nullptr, 0);
- if (slave_fd == PseudoTerminal::invalid_fd)
- {
- error.SetErrorStringWithFormat("unable to open slave pty '%s'", slave_path);
- return error; // Failure
- }
- [options setValue:[NSNumber numberWithInteger:slave_fd] forKey:key];
- return error; // Success
- }
- }
- }
- Error posix_error;
- int created_fd = open(file_spec.GetPath().c_str(), file_action->GetActionArgument(), S_IRUSR | S_IWUSR);
- if (created_fd >= 0)
- {
- file.SetDescriptor(created_fd, true);
- [options setValue:[NSNumber numberWithInteger:created_fd] forKey:key];
- return error; // Success
- }
- else
- {
- posix_error.SetErrorToErrno();
- error.SetErrorStringWithFormat("unable to open file '%s': %s", file_spec.GetPath().c_str(), posix_error.AsCString());
- }
- }
- }
- break;
+bool CoreSimulatorSupport::Device::Shutdown(Error &err) {
+ NSError *nserror;
+ if ([m_dev shutdownWithError:&nserror]) {
+ err.Clear();
+ return true;
+ } else {
+ err.SetErrorString([[nserror description] UTF8String]);
+ return false;
+ }
+}
+
+static Error HandleFileAction(ProcessLaunchInfo &launch_info,
+ NSMutableDictionary *options, NSString *key,
+ const int fd, File &file) {
+ Error error;
+ const FileAction *file_action = launch_info.GetFileActionForFD(fd);
+ if (file_action) {
+ switch (file_action->GetAction()) {
+ case FileAction::eFileActionNone:
+ break;
+
+ case FileAction::eFileActionClose:
+ error.SetErrorStringWithFormat("close file action for %i not supported",
+ fd);
+ break;
+
+ case FileAction::eFileActionDuplicate:
+ error.SetErrorStringWithFormat(
+ "duplication file action for %i not supported", fd);
+ break;
+
+ case FileAction::eFileActionOpen: {
+ FileSpec file_spec = file_action->GetFileSpec();
+ if (file_spec) {
+ const int master_fd = launch_info.GetPTY().GetMasterFileDescriptor();
+ if (master_fd != PseudoTerminal::invalid_fd) {
+ // 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);
+ if (file_spec == slave_spec) {
+ int slave_fd = launch_info.GetPTY().GetSlaveFileDescriptor();
+ if (slave_fd == PseudoTerminal::invalid_fd)
+ slave_fd = launch_info.GetPTY().OpenSlave(O_RDWR, nullptr, 0);
+ if (slave_fd == PseudoTerminal::invalid_fd) {
+ error.SetErrorStringWithFormat("unable to open slave pty '%s'",
+ slave_path);
+ return error; // Failure
+ }
+ [options setValue:[NSNumber numberWithInteger:slave_fd]
+ forKey:key];
+ return error; // Success
+ }
+ }
+ }
+ Error posix_error;
+ int created_fd =
+ open(file_spec.GetPath().c_str(), file_action->GetActionArgument(),
+ S_IRUSR | S_IWUSR);
+ if (created_fd >= 0) {
+ file.SetDescriptor(created_fd, true);
+ [options setValue:[NSNumber numberWithInteger:created_fd] forKey:key];
+ return error; // Success
+ } else {
+ posix_error.SetErrorToErrno();
+ error.SetErrorStringWithFormat("unable to open file '%s': %s",
+ file_spec.GetPath().c_str(),
+ posix_error.AsCString());
}
+ }
+ } break;
}
- return error; // Success, no file action, nothing to do
+ }
+ return error; // Success, no file action, nothing to do
}
CoreSimulatorSupport::Process
-CoreSimulatorSupport::Device::Spawn (ProcessLaunchInfo& launch_info)
-{
-#define kSimDeviceSpawnEnvironment @"environment" /* An NSDictionary (NSStrings -> NSStrings) of environment key/values */
-#define kSimDeviceSpawnStdin @"stdin" /* An NSNumber corresponding to a fd */
-#define kSimDeviceSpawnStdout @"stdout" /* An NSNumber corresponding to a fd */
-#define kSimDeviceSpawnStderr @"stderr" /* An NSNumber corresponding to a fd */
-#define kSimDeviceSpawnArguments @"arguments" /* An NSArray of strings to use as the argv array. If not provided, path will be argv[0] */
-#define kSimDeviceSpawnWaitForDebugger @"wait_for_debugger" /* An NSNumber (bool) */
-
- NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
-
- if (launch_info.GetFlags().Test(lldb::eLaunchFlagDebug))
- [options setObject:@YES forKey:kSimDeviceSpawnWaitForDebugger];
-
- if (launch_info.GetArguments().GetArgumentCount())
- {
- const Args& args(launch_info.GetArguments());
- NSMutableArray *args_array = [[NSMutableArray alloc] init];
- for (size_t idx = 0;
- idx < args.GetArgumentCount();
- idx++)
- [args_array addObject:[NSString stringWithUTF8String:args.GetArgumentAtIndex(idx)]];
-
- [options setObject:args_array forKey:kSimDeviceSpawnArguments];
- }
-
- if (launch_info.GetEnvironmentEntries().GetArgumentCount())
- {
- const Args& envs(launch_info.GetEnvironmentEntries());
- NSMutableDictionary *env_dict = [[NSMutableDictionary alloc] init];
- for (size_t idx = 0;
- idx < envs.GetArgumentCount();
- idx++)
- {
- llvm::StringRef arg_sr(envs.GetArgumentAtIndex(idx));
- auto first_eq = arg_sr.find('=');
- if (first_eq == llvm::StringRef::npos)
- continue;
- llvm::StringRef key = arg_sr.substr(0, first_eq);
- llvm::StringRef value = arg_sr.substr(first_eq+1);
-
- NSString *key_ns = [NSString stringWithUTF8String:key.str().c_str()];
- NSString *value_ns = [NSString stringWithUTF8String:value.str().c_str()];
-
- [env_dict setValue:value_ns forKey:key_ns];
- }
-
- [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment];
+CoreSimulatorSupport::Device::Spawn(ProcessLaunchInfo &launch_info) {
+#define kSimDeviceSpawnEnvironment \
+ @"environment" /* An NSDictionary (NSStrings -> NSStrings) of environment \
+ key/values */
+#define kSimDeviceSpawnStdin @"stdin" /* An NSNumber corresponding to a fd */
+#define kSimDeviceSpawnStdout @"stdout" /* An NSNumber corresponding to a fd \
+ */
+#define kSimDeviceSpawnStderr @"stderr" /* An NSNumber corresponding to a fd \
+ */
+#define kSimDeviceSpawnArguments \
+ @"arguments" /* An NSArray of strings to use as the argv array. If not \
+ provided, path will be argv[0] */
+#define kSimDeviceSpawnWaitForDebugger \
+ @"wait_for_debugger" /* An NSNumber (bool) */
+
+ NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
+
+ if (launch_info.GetFlags().Test(lldb::eLaunchFlagDebug))
+ [options setObject:@YES forKey:kSimDeviceSpawnWaitForDebugger];
+
+ if (launch_info.GetArguments().GetArgumentCount()) {
+ const Args &args(launch_info.GetArguments());
+ NSMutableArray *args_array = [[NSMutableArray alloc] init];
+ for (size_t idx = 0; idx < args.GetArgumentCount(); idx++)
+ [args_array
+ addObject:[NSString
+ stringWithUTF8String:args.GetArgumentAtIndex(idx)]];
+
+ [options setObject:args_array forKey:kSimDeviceSpawnArguments];
+ }
+
+ if (launch_info.GetEnvironmentEntries().GetArgumentCount()) {
+ const Args &envs(launch_info.GetEnvironmentEntries());
+ NSMutableDictionary *env_dict = [[NSMutableDictionary alloc] init];
+ for (size_t idx = 0; idx < envs.GetArgumentCount(); idx++) {
+ llvm::StringRef arg_sr(envs.GetArgumentAtIndex(idx));
+ auto first_eq = arg_sr.find('=');
+ if (first_eq == llvm::StringRef::npos)
+ continue;
+ llvm::StringRef key = arg_sr.substr(0, first_eq);
+ llvm::StringRef value = arg_sr.substr(first_eq + 1);
+
+ NSString *key_ns = [NSString stringWithUTF8String:key.str().c_str()];
+ NSString *value_ns = [NSString stringWithUTF8String:value.str().c_str()];
+
+ [env_dict setValue:value_ns forKey:key_ns];
}
- Error error;
- File stdin_file;
- File stdout_file;
- File stderr_file;
- error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdin, STDIN_FILENO, stdin_file);
+ [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment];
+ }
+
+ Error error;
+ File stdin_file;
+ File stdout_file;
+ File stderr_file;
+ error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdin,
+ STDIN_FILENO, stdin_file);
- if (error.Fail())
- return CoreSimulatorSupport::Process(error);
+ if (error.Fail())
+ return CoreSimulatorSupport::Process(error);
- error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdout, STDOUT_FILENO, stdout_file);
+ error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdout,
+ STDOUT_FILENO, stdout_file);
- if (error.Fail())
- return CoreSimulatorSupport::Process(error);
+ if (error.Fail())
+ return CoreSimulatorSupport::Process(error);
- error = HandleFileAction(launch_info, options, kSimDeviceSpawnStderr, STDERR_FILENO, stderr_file);
+ error = HandleFileAction(launch_info, options, kSimDeviceSpawnStderr,
+ STDERR_FILENO, stderr_file);
- if (error.Fail())
- return CoreSimulatorSupport::Process(error);
+ if (error.Fail())
+ return CoreSimulatorSupport::Process(error);
#undef kSimDeviceSpawnEnvironment
#undef kSimDeviceSpawnStdin
@@ -658,116 +527,118 @@ CoreSimulatorSupport::Device::Spawn (ProcessLaunchInfo& launch_info)
#undef kSimDeviceSpawnStderr
#undef kSimDeviceSpawnWaitForDebugger
#undef kSimDeviceSpawnArguments
-
- NSError* nserror;
-
- pid_t pid = [m_dev spawnWithPath: [NSString stringWithUTF8String: launch_info.GetExecutableFile().GetPath().c_str()]
- options: options
- terminationHandler: nil
- error: &nserror];
-
-
- if (pid < 0)
- {
- const char* nserror_string = [[nserror description] UTF8String];
- error.SetErrorString(nserror_string ? nserror_string : "unable to launch");
- }
-
- return CoreSimulatorSupport::Process (pid, error);
-}
-CoreSimulatorSupport::DeviceSet
-CoreSimulatorSupport::DeviceSet::GetAllDevices ()
-{
- return DeviceSet([[NSClassFromString(@"SimDeviceSet") defaultSet] devices]);
+ NSError *nserror;
+
+ pid_t pid = [m_dev
+ spawnWithPath:[NSString stringWithUTF8String:launch_info
+ .GetExecutableFile()
+ .GetPath()
+ .c_str()]
+ options:options
+ terminationHandler:nil
+ error:&nserror];
+
+ if (pid < 0) {
+ const char *nserror_string = [[nserror description] UTF8String];
+ error.SetErrorString(nserror_string ? nserror_string : "unable to launch");
+ }
+
+ return CoreSimulatorSupport::Process(pid, error);
}
CoreSimulatorSupport::DeviceSet
-CoreSimulatorSupport::DeviceSet::GetAvailableDevices ()
-{
- return GetAllDevices().GetDevicesIf( [] (Device d) -> bool {
- return (d && d.GetDeviceType() && d.GetDeviceRuntime() && d.GetDeviceRuntime().IsAvailable());
- });
-}
+CoreSimulatorSupport::DeviceSet::GetAllDevices(const char *developer_dir) {
+ if (!developer_dir || !developer_dir[0])
+ return DeviceSet([NSArray new]);
-size_t
-CoreSimulatorSupport::DeviceSet::GetNumDevices ()
-{
- return [m_dev count];
-}
+ Class SimServiceContextClass = NSClassFromString(@"SimServiceContext");
+ NSString *dev_dir = @(developer_dir);
+ NSError *error = nil;
-CoreSimulatorSupport::Device
-CoreSimulatorSupport::DeviceSet::GetDeviceAtIndex (size_t idx)
-{
- if (idx < GetNumDevices())
- return Device([m_dev objectAtIndex:idx]);
- return Device();
+ id serviceContext =
+ [SimServiceContextClass sharedServiceContextForDeveloperDir:dev_dir
+ error:&error];
+ if (!serviceContext)
+ return DeviceSet([NSArray new]);
+
+ return DeviceSet([[serviceContext defaultDeviceSetWithError:&error] devices]);
}
CoreSimulatorSupport::DeviceSet
-CoreSimulatorSupport::DeviceSet::GetDevicesIf (std::function<bool(CoreSimulatorSupport::Device)> f)
-{
- NSMutableArray *array = [[NSMutableArray alloc] init];
- for (NSUInteger i = 0;
- i < GetNumDevices();
- i++)
- {
- Device d(GetDeviceAtIndex(i));
- if (f(d))
- [array addObject:(id)d.m_dev];
- }
-
- return DeviceSet(array);
-}
-
-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)
- break;
- }
+CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
+ const char *developer_dir) {
+ return GetAllDevices(developer_dir).GetDevicesIf([](Device d) -> bool {
+ return (d && d.GetDeviceType() && d.GetDeviceRuntime() &&
+ d.GetDeviceRuntime().IsAvailable());
+ });
}
-CoreSimulatorSupport::DeviceSet
-CoreSimulatorSupport::DeviceSet::GetDevices (CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id)
-{
- NSMutableArray *array = [[NSMutableArray alloc] init];
- const size_t n = GetNumDevices();
- for (NSUInteger i = 0; i < n; ++i)
- {
- Device d(GetDeviceAtIndex(i));
- if (d && d.GetDeviceType() && d.GetDeviceType().GetProductFamilyID() == dev_id)
- [array addObject:(id)d.m_dev];
- }
-
- return DeviceSet(array);
+size_t CoreSimulatorSupport::DeviceSet::GetNumDevices() {
+ return [m_dev count];
}
CoreSimulatorSupport::Device
-CoreSimulatorSupport::DeviceSet::GetFanciest (CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id)
-{
- Device dev;
-
- for (NSUInteger i = 0;
- i < GetNumDevices();
- i++)
- {
- Device d(GetDeviceAtIndex(i));
- if (d && d.GetDeviceType() && d.GetDeviceType().GetProductFamilyID() == dev_id)
- {
- if (!dev)
- dev = d;
- else
- {
- if ((d.GetDeviceType().GetModelIdentifier() > dev.GetDeviceType().GetModelIdentifier()) ||
- d.GetDeviceRuntime().GetVersion() > dev.GetDeviceRuntime().GetVersion())
- dev = d;
- }
- }
+CoreSimulatorSupport::DeviceSet::GetDeviceAtIndex(size_t idx) {
+ if (idx < GetNumDevices())
+ return Device([m_dev objectAtIndex:idx]);
+ return Device();
+}
+
+CoreSimulatorSupport::DeviceSet CoreSimulatorSupport::DeviceSet::GetDevicesIf(
+ std::function<bool(CoreSimulatorSupport::Device)> f) {
+ NSMutableArray *array = [[NSMutableArray alloc] init];
+ for (NSUInteger i = 0; i < GetNumDevices(); i++) {
+ Device d(GetDeviceAtIndex(i));
+ if (f(d))
+ [array addObject:(id)d.m_dev];
+ }
+
+ return DeviceSet(array);
+}
+
+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)
+ break;
+ }
+}
+
+CoreSimulatorSupport::DeviceSet CoreSimulatorSupport::DeviceSet::GetDevices(
+ CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id) {
+ NSMutableArray *array = [[NSMutableArray alloc] init];
+ const size_t n = GetNumDevices();
+ for (NSUInteger i = 0; i < n; ++i) {
+ Device d(GetDeviceAtIndex(i));
+ if (d && d.GetDeviceType() &&
+ d.GetDeviceType().GetProductFamilyID() == dev_id)
+ [array addObject:(id)d.m_dev];
+ }
+
+ return DeviceSet(array);
+}
+
+CoreSimulatorSupport::Device CoreSimulatorSupport::DeviceSet::GetFanciest(
+ CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id) {
+ Device dev;
+
+ for (NSUInteger i = 0; i < GetNumDevices(); i++) {
+ Device d(GetDeviceAtIndex(i));
+ if (d && d.GetDeviceType() &&
+ d.GetDeviceType().GetProductFamilyID() == dev_id) {
+ if (!dev)
+ dev = d;
+ else {
+ if ((d.GetDeviceType().GetModelIdentifier() >
+ dev.GetDeviceType().GetModelIdentifier()) ||
+ d.GetDeviceRuntime().GetVersion() >
+ dev.GetDeviceRuntime().GetVersion())
+ dev = d;
+ }
}
-
- return dev;
+ }
+
+ return dev;
}
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index 3482d2ae5e20..bc4bfd32aad7 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -21,8 +21,8 @@
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -34,624 +34,516 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_netbsd;
-PlatformSP
-PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch)
-{
- // The only time we create an instance is when we are creating a remote
- // netbsd platform
- const bool is_host = false;
-
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getOS())
- {
- case llvm::Triple::NetBSD:
- create = true;
- break;
-
- default:
- break;
- }
+PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) {
+ // The only time we create an instance is when we are creating a remote
+ // netbsd platform
+ const bool is_host = false;
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getOS()) {
+ case llvm::Triple::NetBSD:
+ create = true;
+ break;
+
+ default:
+ break;
}
- if (create)
- return PlatformSP(new PlatformNetBSD (is_host));
- return PlatformSP();
-
+ }
+ if (create)
+ return PlatformSP(new PlatformNetBSD(is_host));
+ return PlatformSP();
}
-ConstString
-PlatformNetBSD::GetPluginNameStatic(bool is_host)
-{
- if (is_host)
- {
- static ConstString g_host_name(Platform::GetHostPlatformName ());
- return g_host_name;
- }
- else
- {
- static ConstString g_remote_name("remote-netbsd");
- return g_remote_name;
- }
+ConstString PlatformNetBSD::GetPluginNameStatic(bool is_host) {
+ if (is_host) {
+ static ConstString g_host_name(Platform::GetHostPlatformName());
+ return g_host_name;
+ } else {
+ static ConstString g_remote_name("remote-netbsd");
+ return g_remote_name;
+ }
}
-const char *
-PlatformNetBSD::GetDescriptionStatic (bool is_host)
-{
- if (is_host)
- return "Local NetBSD user platform plug-in.";
- else
- return "Remote NetBSD user platform plug-in.";
+const char *PlatformNetBSD::GetDescriptionStatic(bool is_host) {
+ if (is_host)
+ return "Local NetBSD user platform plug-in.";
+ else
+ return "Remote NetBSD user platform plug-in.";
}
static uint32_t g_initialize_count = 0;
-void
-PlatformNetBSD::Initialize ()
-{
- Platform::Initialize ();
+void PlatformNetBSD::Initialize() {
+ Platform::Initialize();
- if (g_initialize_count++ == 0)
- {
+ if (g_initialize_count++ == 0) {
#if defined(__NetBSD__)
- // Force a host flag to true for the default platform object.
- PlatformSP default_platform_sp (new PlatformNetBSD(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform (default_platform_sp);
+ // Force a host flag to true for the default platform object.
+ PlatformSP default_platform_sp(new PlatformNetBSD(true));
+ default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+ Platform::SetHostPlatform(default_platform_sp);
#endif
- PluginManager::RegisterPlugin(PlatformNetBSD::GetPluginNameStatic(false),
- PlatformNetBSD::GetDescriptionStatic(false),
- PlatformNetBSD::CreateInstance);
- }
+ PluginManager::RegisterPlugin(PlatformNetBSD::GetPluginNameStatic(false),
+ PlatformNetBSD::GetDescriptionStatic(false),
+ PlatformNetBSD::CreateInstance);
+ }
}
-void
-PlatformNetBSD::Terminate ()
-{
- if (g_initialize_count > 0 && --g_initialize_count == 0)
- PluginManager::UnregisterPlugin (PlatformNetBSD::CreateInstance);
+void PlatformNetBSD::Terminate() {
+ if (g_initialize_count > 0 && --g_initialize_count == 0)
+ PluginManager::UnregisterPlugin(PlatformNetBSD::CreateInstance);
- Platform::Terminate ();
+ Platform::Terminate();
}
-bool
-PlatformNetBSD::GetModuleSpec (const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
+bool PlatformNetBSD::GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch,
+ ModuleSpec &module_spec) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
+ module_spec);
- return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
+ return Platform::GetModuleSpec(module_file_spec, arch, module_spec);
}
-Error
-PlatformNetBSD::RunShellCommand(const char *command,
- const FileSpec &working_dir,
- int *status_ptr,
- int *signo_ptr,
- std::string *command_output,
- uint32_t timeout_sec)
-{
- if (IsHost())
- return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
+Error PlatformNetBSD::RunShellCommand(const char *command,
+ const FileSpec &working_dir,
+ int *status_ptr, int *signo_ptr,
+ std::string *command_output,
+ uint32_t timeout_sec) {
+ if (IsHost())
+ return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
+ command_output, timeout_sec);
+ else {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->RunShellCommand(command, working_dir,
+ status_ptr, signo_ptr,
+ command_output, timeout_sec);
else
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
- else
- return Error("unable to run a remote command without a platform");
- }
+ return Error("unable to run a remote command without a platform");
+ }
}
-Error
-PlatformNetBSD::ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec(module_spec);
-
- if (IsHost())
- {
- // If we have "ls" as the module_spec's file, resolve the executable location based on
- // the current path variables
- if (!resolved_module_spec.GetFileSpec().Exists())
- {
- module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
- }
+Error PlatformNetBSD::ResolveExecutable(
+ const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ char exe_path[PATH_MAX];
+ ModuleSpec resolved_module_spec(module_spec);
+
+ if (IsHost()) {
+ // If we have "ls" as the module_spec's file, resolve the executable
+ // location based on
+ // the current path variables
+ if (!resolved_module_spec.GetFileSpec().Exists()) {
+ module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+ resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
+ }
- if (!resolved_module_spec.GetFileSpec().Exists())
- resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();
+ if (!resolved_module_spec.GetFileSpec().Exists())
+ resolved_module_spec.GetFileSpec().ResolveExecutableLocation();
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- {
- error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else {
+ error.SetErrorStringWithFormat(
+ "unable to find executable for '%s'",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
- else
- {
- if (m_remote_platform_sp)
- {
- error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
- }
- else
- {
- // We may connect to a process and use the provided executable (Don't use local $PATH).
-
- // Resolve any executable within a bundle on MacOSX
- Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists())
- {
- error.Clear();
- }
- else
- {
- error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+ } else {
+ if (m_remote_platform_sp) {
+ error =
+ GetCachedExecutable(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, *m_remote_platform_sp);
+ } else {
+ // We may connect to a process and use the provided executable (Don't use
+ // local $PATH).
+
+ // Resolve any executable within a bundle on MacOSX
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ error.Clear();
+ } else {
+ error.SetErrorStringWithFormat(
+ "the platform is not currently connected, and '%s' doesn't exist "
+ "in the system root.",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
}
-
- if (error.Success())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
-
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
- {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
+ }
+
+ if (error.Success()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+
+ if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) {
+ exe_module_sp.reset();
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain the architecture %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+ } else {
+ // No valid architecture was specified, ask the platform for
+ // the architectures that we should be using (in the correct order)
+ // and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error =
+ ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
- else
- {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
+ }
}
+ }
- return error;
+ return error;
}
// From PlatformMacOSX only
-Error
-PlatformNetBSD::GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
- }
+Error PlatformNetBSD::GetFileWithUUID(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ if (IsRemote()) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
+ local_file);
+ }
- // Default to the local case
- local_file = platform_file;
- return Error();
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
}
-
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformNetBSD::PlatformNetBSD (bool is_host) :
- Platform(is_host),
- m_remote_platform_sp()
-{
+PlatformNetBSD::PlatformNetBSD(bool is_host)
+ : Platform(is_host), m_remote_platform_sp() {}
+
+bool PlatformNetBSD::GetRemoteOSVersion() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetOSVersion(
+ m_major_os_version, m_minor_os_version, m_update_os_version);
+ return false;
}
-bool
-PlatformNetBSD::GetRemoteOSVersion ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetOSVersion (m_major_os_version,
- m_minor_os_version,
- m_update_os_version);
- return false;
-}
-
-bool
-PlatformNetBSD::GetRemoteOSBuildString (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSBuildString (s);
- s.clear();
- return false;
+bool PlatformNetBSD::GetRemoteOSBuildString(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSBuildString(s);
+ s.clear();
+ return false;
}
-bool
-PlatformNetBSD::GetRemoteOSKernelDescription (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSKernelDescription (s);
- s.clear();
- return false;
+bool PlatformNetBSD::GetRemoteOSKernelDescription(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
+ s.clear();
+ return false;
}
// Remote Platform subclasses need to override this function
-ArchSpec
-PlatformNetBSD::GetRemoteSystemArchitecture ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteSystemArchitecture ();
- return ArchSpec();
+ArchSpec PlatformNetBSD::GetRemoteSystemArchitecture() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteSystemArchitecture();
+ return ArchSpec();
}
+const char *PlatformNetBSD::GetHostname() {
+ if (IsHost())
+ return Platform::GetHostname();
-const char *
-PlatformNetBSD::GetHostname ()
-{
- if (IsHost())
- return Platform::GetHostname();
-
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetHostname ();
- return NULL;
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetHostname();
+ return NULL;
}
-bool
-PlatformNetBSD::IsConnected () const
-{
- if (IsHost())
- return true;
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->IsConnected();
- return false;
+bool PlatformNetBSD::IsConnected() const {
+ if (IsHost())
+ return true;
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->IsConnected();
+ return false;
}
-Error
-PlatformNetBSD::ConnectRemote (Args& args)
-{
- Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString());
- }
- else
- {
- if (!m_remote_platform_sp)
- m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error);
-
- if (m_remote_platform_sp)
- {
- if (error.Success())
- {
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->ConnectRemote (args);
- }
- else
- {
- error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
- }
- }
+Error PlatformNetBSD::ConnectRemote(Args &args) {
+ Error error;
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't connect to the host platform '%s', always connected",
+ GetPluginName().GetCString());
+ } else {
+ if (!m_remote_platform_sp)
+ m_remote_platform_sp =
+ Platform::Create(ConstString("remote-gdb-server"), error);
+
+ if (m_remote_platform_sp) {
+ if (error.Success()) {
+ if (m_remote_platform_sp) {
+ error = m_remote_platform_sp->ConnectRemote(args);
+ } else {
+ error.SetErrorString(
+ "\"platform connect\" takes a single argument: <connect-url>");
}
- else
- error.SetErrorString ("failed to create a 'remote-gdb-server' platform");
+ }
+ } else
+ error.SetErrorString("failed to create a 'remote-gdb-server' platform");
- if (error.Fail())
- m_remote_platform_sp.reset();
- }
+ if (error.Fail())
+ m_remote_platform_sp.reset();
+ }
- return error;
+ return error;
}
-Error
-PlatformNetBSD::DisconnectRemote ()
-{
- Error error;
+Error PlatformNetBSD::DisconnectRemote() {
+ Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString());
- }
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't disconnect from the host platform '%s', always connected",
+ GetPluginName().GetCString());
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->DisconnectRemote();
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->DisconnectRemote ();
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-bool
-PlatformNetBSD::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- bool success = false;
- if (IsHost())
- {
- success = Platform::GetProcessInfo (pid, process_info);
- }
- else if (m_remote_platform_sp)
- {
- success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
- }
- return success;
+bool PlatformNetBSD::GetProcessInfo(lldb::pid_t pid,
+ ProcessInstanceInfo &process_info) {
+ bool success = false;
+ if (IsHost()) {
+ success = Platform::GetProcessInfo(pid, process_info);
+ } else if (m_remote_platform_sp) {
+ success = m_remote_platform_sp->GetProcessInfo(pid, process_info);
+ }
+ return success;
}
uint32_t
-PlatformNetBSD::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- uint32_t match_count = 0;
- if (IsHost())
- {
- // Let the base class figure out the host details
- match_count = Platform::FindProcesses (match_info, process_infos);
- }
- else
- {
- // If we are remote, we can only return results if we are connected
- if (m_remote_platform_sp)
- match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
- }
- return match_count;
-}
-
-const char *
-PlatformNetBSD::GetUserName (uint32_t uid)
-{
- // Check the cache in Platform in case we have already looked this uid up
- const char *user_name = Platform::GetUserName(uid);
- if (user_name)
- return user_name;
-
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetUserName(uid);
- return NULL;
+PlatformNetBSD::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ uint32_t match_count = 0;
+ if (IsHost()) {
+ // Let the base class figure out the host details
+ match_count = Platform::FindProcesses(match_info, process_infos);
+ } else {
+ // If we are remote, we can only return results if we are connected
+ if (m_remote_platform_sp)
+ match_count =
+ m_remote_platform_sp->FindProcesses(match_info, process_infos);
+ }
+ return match_count;
}
-const char *
-PlatformNetBSD::GetGroupName (uint32_t gid)
-{
- const char *group_name = Platform::GetGroupName(gid);
- if (group_name)
- return group_name;
+const char *PlatformNetBSD::GetUserName(uint32_t uid) {
+ // Check the cache in Platform in case we have already looked this uid up
+ const char *user_name = Platform::GetUserName(uid);
+ if (user_name)
+ return user_name;
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetGroupName(gid);
- return NULL;
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetUserName(uid);
+ return NULL;
}
+const char *PlatformNetBSD::GetGroupName(uint32_t gid) {
+ const char *group_name = Platform::GetGroupName(gid);
+ if (group_name)
+ return group_name;
-Error
-PlatformNetBSD::GetSharedModule (const ModuleSpec &module_spec,
- Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- Error error;
- module_sp.reset();
-
- if (IsRemote())
- {
- // If we have a remote platform always, let it try and locate
- // the shared module first.
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
- }
- }
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetGroupName(gid);
+ return NULL;
+}
- if (!module_sp)
- {
- // Fall back to the local platform and find the file locally
- error = Platform::GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
+Error PlatformNetBSD::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ Error error;
+ module_sp.reset();
+
+ if (IsRemote()) {
+ // If we have a remote platform always, let it try and locate
+ // the shared module first.
+ if (m_remote_platform_sp) {
+ error = m_remote_platform_sp->GetSharedModule(
+ module_spec, process, module_sp, module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
}
- if (module_sp)
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return error;
+ }
+
+ if (!module_sp) {
+ // Fall back to the local platform and find the file locally
+ error = Platform::GetSharedModule(module_spec, process, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
+ return error;
}
-
-bool
-PlatformNetBSD::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- if (IsHost())
- {
- ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- if (hostArch.GetTriple().isOSNetBSD())
- {
- if (idx == 0)
- {
- arch = hostArch;
- return arch.IsValid();
- }
- else if (idx == 1)
- {
- // If the default host architecture is 64-bit, look for a 32-bit variant
- if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
- {
- arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- return arch.IsValid();
- }
- }
+bool PlatformNetBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ if (IsHost()) {
+ ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ if (hostArch.GetTriple().isOSNetBSD()) {
+ if (idx == 0) {
+ arch = hostArch;
+ return arch.IsValid();
+ } else if (idx == 1) {
+ // If the default host architecture is 64-bit, look for a 32-bit variant
+ if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) {
+ arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ return arch.IsValid();
}
+ }
}
- else
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
-
- llvm::Triple triple;
- // Set the OS to NetBSD
- triple.setOS(llvm::Triple::NetBSD);
- // Set the architecture
- switch (idx)
- {
- case 0: triple.setArchName("x86_64"); break;
- case 1: triple.setArchName("i386"); break;
- default: return false;
- }
- // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified unknown".
- // This means when someone calls triple.GetVendorName() it will return an empty string
- // which indicates that the vendor can be set when two architectures are merged
-
- // Now set the triple into "arch" and return true
- arch.SetTriple(triple);
- return true;
+ } else {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
+
+ llvm::Triple triple;
+ // Set the OS to NetBSD
+ triple.setOS(llvm::Triple::NetBSD);
+ // Set the architecture
+ switch (idx) {
+ case 0:
+ triple.setArchName("x86_64");
+ break;
+ case 1:
+ triple.setArchName("i386");
+ break;
+ default:
+ return false;
}
- return false;
+ // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
+ // vendor by
+ // calling triple.SetVendorName("unknown") so that it is a "unspecified
+ // unknown".
+ // This means when someone calls triple.GetVendorName() it will return an
+ // empty string
+ // which indicates that the vendor can be set when two architectures are
+ // merged
+
+ // Now set the triple into "arch" and return true
+ arch.SetTriple(triple);
+ return true;
+ }
+ return false;
}
-void
-PlatformNetBSD::GetStatus (Stream &strm)
-{
+void PlatformNetBSD::GetStatus(Stream &strm) {
#ifndef LLDB_DISABLE_POSIX
- struct ::utsname un;
-
- strm << " Host: ";
-
- ::memset(&un, 0, sizeof(utsname));
- if (::uname(&un) == -1) {
- strm << "NetBSD" << '\n';
- } else {
- strm << un.sysname << ' ' << un.release;
- if (un.nodename[0] != '\0')
- strm << " (" << un.nodename << ')';
- strm << '\n';
-
- // Dump a common information about the platform status.
- strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version << '\n';
- }
+ struct ::utsname un;
+
+ strm << " Host: ";
+
+ ::memset(&un, 0, sizeof(utsname));
+ if (::uname(&un) == -1) {
+ strm << "NetBSD" << '\n';
+ } else {
+ strm << un.sysname << ' ' << un.release;
+ if (un.nodename[0] != '\0')
+ strm << " (" << un.nodename << ')';
+ strm << '\n';
+
+ // Dump a common information about the platform status.
+ strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version
+ << '\n';
+ }
#endif
- Platform::GetStatus(strm);
+ Platform::GetStatus(strm);
}
-void
-PlatformNetBSD::CalculateTrapHandlerSymbolNames ()
-{
- m_trap_handlers.push_back (ConstString ("_sigtramp"));
+void PlatformNetBSD::CalculateTrapHandlerSymbolNames() {
+ m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-Error
-PlatformNetBSD::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Error error;
- if (IsHost())
- {
- error = Platform::LaunchProcess (launch_info);
- }
+Error PlatformNetBSD::LaunchProcess(ProcessLaunchInfo &launch_info) {
+ Error error;
+ if (IsHost()) {
+ error = Platform::LaunchProcess(launch_info);
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->LaunchProcess(launch_info);
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->LaunchProcess (launch_info);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-lldb::ProcessSP
-PlatformNetBSD::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error)
-{
- lldb::ProcessSP process_sp;
- if (IsHost())
- {
- if (target == NULL)
- {
- TargetSP new_target_sp;
- ArchSpec emptyArchSpec;
-
- error = debugger.GetTargetList().CreateTarget (debugger,
- NULL,
- emptyArchSpec,
- false,
- m_remote_platform_sp,
- new_target_sp);
- target = new_target_sp.get();
- }
- else
- error.Clear();
-
- if (target && error.Success())
- {
- debugger.GetTargetList().SetSelectedTarget(target);
- // The netbsd always currently uses the GDB remote debugger plug-in
- // so even when debugging locally we are debugging remotely!
- // Just like the darwin plugin.
- process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
-
- if (process_sp)
- error = process_sp->Attach (attach_info);
- }
+lldb::ProcessSP PlatformNetBSD::Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger, Target *target,
+ Error &error) {
+ lldb::ProcessSP process_sp;
+ if (IsHost()) {
+ if (target == NULL) {
+ TargetSP new_target_sp;
+ ArchSpec emptyArchSpec;
+
+ error = debugger.GetTargetList().CreateTarget(debugger, "", emptyArchSpec,
+ false, m_remote_platform_sp,
+ new_target_sp);
+ target = new_target_sp.get();
+ } else
+ error.Clear();
+
+ if (target && error.Success()) {
+ debugger.GetTargetList().SetSelectedTarget(target);
+ // The netbsd always currently uses the GDB remote debugger plug-in
+ // so even when debugging locally we are debugging remotely!
+ // Just like the darwin plugin.
+ process_sp = target->CreateProcess(
+ attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
+
+ if (process_sp)
+ error = process_sp->Attach(attach_info);
}
+ } else {
+ if (m_remote_platform_sp)
+ process_sp =
+ m_remote_platform_sp->Attach(attach_info, debugger, target, error);
else
- {
- if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return process_sp;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return process_sp;
}
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
index 46d1d1843c63..ddca5eb5be3e 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -19,153 +19,108 @@
namespace lldb_private {
namespace platform_netbsd {
- class PlatformNetBSD : public Platform
- {
- public:
- PlatformNetBSD (bool is_host);
-
- ~PlatformNetBSD() override = default;
-
- //------------------------------------------------------------
- // Class functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance(bool force, const ArchSpec *arch);
-
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static ConstString
- GetPluginNameStatic (bool is_host);
-
- static const char *
- GetDescriptionStatic (bool is_host);
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic (IsHost());
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
- const char *
- GetDescription () override
- {
- return GetDescriptionStatic(IsHost());
- }
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- bool
- GetModuleSpec(const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec) override;
-
- Error
- RunShellCommand(const char *command,
- const FileSpec &working_dir,
- int *status_ptr,
- int *signo_ptr,
+class PlatformNetBSD : public Platform {
+public:
+ PlatformNetBSD(bool is_host);
+
+ ~PlatformNetBSD() override = default;
+
+ //------------------------------------------------------------
+ // Class functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic(bool is_host);
+
+ static const char *GetDescriptionStatic(bool is_host);
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ ConstString GetPluginName() override { return GetPluginNameStatic(IsHost()); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ const char *GetDescription() override {
+ return GetDescriptionStatic(IsHost());
+ }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
+ ModuleSpec &module_spec) override;
+
+ Error RunShellCommand(const char *command, const FileSpec &working_dir,
+ int *status_ptr, int *signo_ptr,
std::string *command_output,
uint32_t timeout_sec) override;
- Error
- ResolveExecutable(const ModuleSpec &module_spec,
+ Error ResolveExecutable(const ModuleSpec &module_spec,
lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr) override;
- bool
- GetRemoteOSVersion () override;
+ bool GetRemoteOSVersion() override;
- bool
- GetRemoteOSBuildString (std::string &s) override;
+ bool GetRemoteOSBuildString(std::string &s) override;
- bool
- GetRemoteOSKernelDescription (std::string &s) override;
+ bool GetRemoteOSKernelDescription(std::string &s) override;
- // Remote Platform subclasses need to override this function
- ArchSpec
- GetRemoteSystemArchitecture() override;
+ // Remote Platform subclasses need to override this function
+ ArchSpec GetRemoteSystemArchitecture() override;
- bool
- IsConnected () const override;
+ bool IsConnected() const override;
- Error
- ConnectRemote(Args& args) override;
+ Error ConnectRemote(Args &args) override;
- Error
- DisconnectRemote() override;
+ Error DisconnectRemote() override;
- const char *
- GetHostname () override;
+ const char *GetHostname() override;
- const char *
- GetUserName (uint32_t uid) override;
+ const char *GetUserName(uint32_t uid) override;
- const char *
- GetGroupName (uint32_t gid) override;
+ const char *GetGroupName(uint32_t gid) override;
- bool
- GetProcessInfo(lldb::pid_t pid,
- ProcessInstanceInfo &proc_info) override;
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
- uint32_t
- FindProcesses(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) override;
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) override;
- Error
- LaunchProcess(ProcessLaunchInfo &launch_info) override;
+ Error LaunchProcess(ProcessLaunchInfo &launch_info) override;
- lldb::ProcessSP
- Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error) override;
+ lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, Error &error) override;
- // NetBSD processes can not be launched by spawning and attaching.
- bool
- CanDebugProcess () override { return false; }
+ // NetBSD processes can not be launched by spawning and attaching.
+ bool CanDebugProcess() override { return false; }
- // Only on PlatformMacOSX:
- Error
- GetFileWithUUID(const FileSpec &platform_file,
- const UUID* uuid, FileSpec &local_file) override;
+ // Only on PlatformMacOSX:
+ Error GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid,
+ FileSpec &local_file) override;
- Error
- GetSharedModule(const ModuleSpec &module_spec,
- Process* process,
+ Error GetSharedModule(const ModuleSpec &module_spec, Process *process,
lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr,
lldb::ModuleSP *old_module_sp_ptr,
bool *did_create_ptr) override;
- bool
- GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
+ bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
- void
- GetStatus(Stream &strm) override;
+ void GetStatus(Stream &strm) override;
- void
- CalculateTrapHandlerSymbolNames () override;
+ void CalculateTrapHandlerSymbolNames() override;
- protected:
- lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote netbsd OS
+protected:
+ lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a
+ // remote netbsd OS
- private:
- DISALLOW_COPY_AND_ASSIGN (PlatformNetBSD);
- };
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformNetBSD);
+};
} // namespace platform_netbsd
} // namespace lldb_private
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index bc890695f0ce..e51029c3630b 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -35,18 +35,15 @@
using namespace lldb;
using namespace lldb_private;
-
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformPOSIX::PlatformPOSIX (bool is_host) :
-Platform(is_host), // This is the local host platform
-m_option_group_platform_rsync(new OptionGroupPlatformRSync()),
-m_option_group_platform_ssh(new OptionGroupPlatformSSH()),
-m_option_group_platform_caching(new OptionGroupPlatformCaching()),
-m_remote_platform_sp ()
-{
-}
+PlatformPOSIX::PlatformPOSIX(bool is_host)
+ : Platform(is_host), // This is the local host platform
+ m_option_group_platform_rsync(new OptionGroupPlatformRSync()),
+ m_option_group_platform_ssh(new OptionGroupPlatformSSH()),
+ m_option_group_platform_caching(new OptionGroupPlatformCaching()),
+ m_remote_platform_sp() {}
//------------------------------------------------------------------
/// Destructor.
@@ -54,858 +51,711 @@ m_remote_platform_sp ()
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformPOSIX::~PlatformPOSIX()
-{
-}
-
-bool
-PlatformPOSIX::GetModuleSpec (const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
-
- return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
-}
-
-lldb_private::OptionGroupOptions*
-PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter)
-{
- auto iter = m_options.find(&interpreter), end = m_options.end();
- if (iter == end)
- {
- std::unique_ptr<lldb_private::OptionGroupOptions> options(new OptionGroupOptions(interpreter));
- options->Append(m_option_group_platform_rsync.get());
- options->Append(m_option_group_platform_ssh.get());
- options->Append(m_option_group_platform_caching.get());
- m_options[&interpreter] = std::move(options);
- }
-
- return m_options.at(&interpreter).get();
-}
-
-bool
-PlatformPOSIX::IsConnected () const
-{
- if (IsHost())
- return true;
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->IsConnected();
- return false;
-}
-
-lldb_private::Error
-PlatformPOSIX::RunShellCommand(const char *command, // Shouldn't be NULL
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass NULL if you don't want the process exit status
- int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass NULL if you don't want the command output
- uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
-{
- if (IsHost())
- return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
- else
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
- else
- return Error("unable to run a remote command without a platform");
- }
-}
-
-Error
-PlatformPOSIX::MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions)
-{
+PlatformPOSIX::~PlatformPOSIX() {}
+
+bool PlatformPOSIX::GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch,
+ ModuleSpec &module_spec) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
+ module_spec);
+
+ return Platform::GetModuleSpec(module_file_spec, arch, module_spec);
+}
+
+lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions(
+ lldb_private::CommandInterpreter &interpreter) {
+ auto iter = m_options.find(&interpreter), end = m_options.end();
+ if (iter == end) {
+ std::unique_ptr<lldb_private::OptionGroupOptions> options(
+ new OptionGroupOptions());
+ options->Append(m_option_group_platform_rsync.get());
+ options->Append(m_option_group_platform_ssh.get());
+ options->Append(m_option_group_platform_caching.get());
+ m_options[&interpreter] = std::move(options);
+ }
+
+ return m_options.at(&interpreter).get();
+}
+
+bool PlatformPOSIX::IsConnected() const {
+ if (IsHost())
+ return true;
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->IsConnected();
+ return false;
+}
+
+lldb_private::Error PlatformPOSIX::RunShellCommand(
+ const char *command, // Shouldn't be NULL
+ const FileSpec &
+ working_dir, // Pass empty FileSpec to use the current working directory
+ int *status_ptr, // Pass NULL if you don't want the process exit status
+ int *signo_ptr, // Pass NULL if you don't want the signal that caused the
+ // process to exit
+ std::string
+ *command_output, // Pass NULL if you don't want the command output
+ uint32_t
+ timeout_sec) // Timeout in seconds to wait for shell program to finish
+{
+ if (IsHost())
+ return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
+ command_output, timeout_sec);
+ else {
if (m_remote_platform_sp)
- return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
- else
- return Platform::MakeDirectory(file_spec ,file_permissions);
-}
-
-Error
-PlatformPOSIX::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFilePermissions(file_spec, file_permissions);
- else
- return Platform::GetFilePermissions(file_spec ,file_permissions);
-}
-
-Error
-PlatformPOSIX::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->SetFilePermissions(file_spec, file_permissions);
- else
- return Platform::SetFilePermissions(file_spec, file_permissions);
-}
-
-lldb::user_id_t
-PlatformPOSIX::OpenFile (const FileSpec& file_spec,
- uint32_t flags,
- uint32_t mode,
- Error &error)
-{
- if (IsHost())
- return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
- else
- return Platform::OpenFile(file_spec, flags, mode, error);
-}
-
-bool
-PlatformPOSIX::CloseFile (lldb::user_id_t fd, Error &error)
-{
- if (IsHost())
- return FileCache::GetInstance().CloseFile(fd, error);
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->CloseFile(fd, error);
- else
- return Platform::CloseFile(fd, error);
-}
-
-uint64_t
-PlatformPOSIX::ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- Error &error)
-{
- if (IsHost())
- return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error);
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
- else
- return Platform::ReadFile(fd, offset, dst, dst_len, error);
-}
-
-uint64_t
-PlatformPOSIX::WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- Error &error)
-{
- if (IsHost())
- return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error);
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
+ return m_remote_platform_sp->RunShellCommand(command, working_dir,
+ status_ptr, signo_ptr,
+ command_output, timeout_sec);
else
- return Platform::WriteFile(fd, offset, src, src_len, error);
+ return Error("unable to run a remote command without a platform");
+ }
+}
+
+Error PlatformPOSIX::MakeDirectory(const FileSpec &file_spec,
+ uint32_t file_permissions) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
+ else
+ return Platform::MakeDirectory(file_spec, file_permissions);
+}
+
+Error PlatformPOSIX::GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFilePermissions(file_spec,
+ file_permissions);
+ else
+ return Platform::GetFilePermissions(file_spec, file_permissions);
+}
+
+Error PlatformPOSIX::SetFilePermissions(const FileSpec &file_spec,
+ uint32_t file_permissions) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->SetFilePermissions(file_spec,
+ file_permissions);
+ else
+ return Platform::SetFilePermissions(file_spec, file_permissions);
+}
+
+lldb::user_id_t PlatformPOSIX::OpenFile(const FileSpec &file_spec,
+ uint32_t flags, uint32_t mode,
+ Error &error) {
+ if (IsHost())
+ return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
+ else
+ return Platform::OpenFile(file_spec, flags, mode, error);
+}
+
+bool PlatformPOSIX::CloseFile(lldb::user_id_t fd, Error &error) {
+ if (IsHost())
+ return FileCache::GetInstance().CloseFile(fd, error);
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->CloseFile(fd, error);
+ else
+ return Platform::CloseFile(fd, error);
+}
+
+uint64_t PlatformPOSIX::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+ uint64_t dst_len, Error &error) {
+ if (IsHost())
+ return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error);
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
+ else
+ return Platform::ReadFile(fd, offset, dst, dst_len, error);
+}
+
+uint64_t PlatformPOSIX::WriteFile(lldb::user_id_t fd, uint64_t offset,
+ const void *src, uint64_t src_len,
+ Error &error) {
+ if (IsHost())
+ return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error);
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
+ else
+ return Platform::WriteFile(fd, offset, src, src_len, error);
+}
+
+static uint32_t chown_file(Platform *platform, const char *path,
+ uint32_t uid = UINT32_MAX,
+ uint32_t gid = UINT32_MAX) {
+ if (!platform || !path || *path == 0)
+ return UINT32_MAX;
+
+ if (uid == UINT32_MAX && gid == UINT32_MAX)
+ return 0; // pretend I did chown correctly - actually I just didn't care
+
+ StreamString command;
+ command.PutCString("chown ");
+ if (uid != UINT32_MAX)
+ command.Printf("%d", uid);
+ if (gid != UINT32_MAX)
+ command.Printf(":%d", gid);
+ command.Printf("%s", path);
+ int status;
+ platform->RunShellCommand(command.GetData(), NULL, &status, NULL, NULL, 10);
+ return status;
}
-static uint32_t
-chown_file(Platform *platform,
- const char* path,
- uint32_t uid = UINT32_MAX,
- uint32_t gid = UINT32_MAX)
-{
- if (!platform || !path || *path == 0)
- return UINT32_MAX;
-
- if (uid == UINT32_MAX && gid == UINT32_MAX)
- return 0; // pretend I did chown correctly - actually I just didn't care
-
+lldb_private::Error
+PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,
+ const lldb_private::FileSpec &destination, uint32_t uid,
+ uint32_t gid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
+ if (IsHost()) {
+ if (FileSpec::Equal(source, destination, true))
+ return Error();
+ // cp src dst
+ // chown uid:gid dst
+ std::string src_path(source.GetPath());
+ if (src_path.empty())
+ return Error("unable to get file path for source");
+ std::string dst_path(destination.GetPath());
+ if (dst_path.empty())
+ return Error("unable to get file path for destination");
StreamString command;
- command.PutCString("chown ");
- if (uid != UINT32_MAX)
- command.Printf("%d",uid);
- if (gid != UINT32_MAX)
- command.Printf(":%d",gid);
- command.Printf("%s",path);
+ command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
int status;
- platform->RunShellCommand(command.GetData(),
- NULL,
- &status,
- NULL,
- NULL,
- 10);
- return status;
-}
-
-lldb_private::Error
-PlatformPOSIX::PutFile (const lldb_private::FileSpec& source,
- const lldb_private::FileSpec& destination,
- uint32_t uid,
- uint32_t gid)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
-
- if (IsHost())
- {
- if (FileSpec::Equal(source, destination, true))
- return Error();
- // cp src dst
- // chown uid:gid dst
- std::string src_path (source.GetPath());
- if (src_path.empty())
- return Error("unable to get file path for source");
- std::string dst_path (destination.GetPath());
- if (dst_path.empty())
- return Error("unable to get file path for destination");
- StreamString command;
- command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
- int status;
- RunShellCommand(command.GetData(),
- NULL,
- &status,
- NULL,
- NULL,
- 10);
- if (status != 0)
- return Error("unable to perform copy");
- if (uid == UINT32_MAX && gid == UINT32_MAX)
- return Error();
- if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
- return Error("unable to perform chown");
+ RunShellCommand(command.GetData(), NULL, &status, NULL, NULL, 10);
+ if (status != 0)
+ return Error("unable to perform copy");
+ if (uid == UINT32_MAX && gid == UINT32_MAX)
+ return Error();
+ if (chown_file(this, dst_path.c_str(), uid, gid) != 0)
+ return Error("unable to perform chown");
+ return Error();
+ } else if (m_remote_platform_sp) {
+ if (GetSupportsRSync()) {
+ std::string src_path(source.GetPath());
+ if (src_path.empty())
+ return Error("unable to get file path for source");
+ std::string dst_path(destination.GetPath());
+ if (dst_path.empty())
+ return Error("unable to get file path for destination");
+ StreamString command;
+ if (GetIgnoresRemoteHostname()) {
+ if (!GetRSyncPrefix())
+ command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(),
+ dst_path.c_str());
+ else
+ command.Printf("rsync %s %s %s%s", GetRSyncOpts(), src_path.c_str(),
+ GetRSyncPrefix(), dst_path.c_str());
+ } else
+ command.Printf("rsync %s %s %s:%s", GetRSyncOpts(), src_path.c_str(),
+ GetHostname(), dst_path.c_str());
+ if (log)
+ log->Printf("[PutFile] Running command: %s\n", command.GetData());
+ int retcode;
+ Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL, 60);
+ if (retcode == 0) {
+ // Don't chown a local file for a remote system
+ // if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
+ // return Error("unable to perform chown");
return Error();
+ }
+ // if we are still here rsync has failed - let's try the slow way before
+ // giving up
}
- else if (m_remote_platform_sp)
- {
- if (GetSupportsRSync())
- {
- std::string src_path (source.GetPath());
- if (src_path.empty())
- return Error("unable to get file path for source");
- std::string dst_path (destination.GetPath());
- if (dst_path.empty())
- return Error("unable to get file path for destination");
- StreamString command;
- if (GetIgnoresRemoteHostname())
- {
- if (!GetRSyncPrefix())
- command.Printf("rsync %s %s %s",
- GetRSyncOpts(),
- src_path.c_str(),
- dst_path.c_str());
- else
- command.Printf("rsync %s %s %s%s",
- GetRSyncOpts(),
- src_path.c_str(),
- GetRSyncPrefix(),
- dst_path.c_str());
- }
- else
- command.Printf("rsync %s %s %s:%s",
- GetRSyncOpts(),
- src_path.c_str(),
- GetHostname(),
- dst_path.c_str());
- if (log)
- log->Printf("[PutFile] Running command: %s\n", command.GetData());
- int retcode;
- Host::RunShellCommand(command.GetData(),
- NULL,
- &retcode,
- NULL,
- NULL,
- 60);
- if (retcode == 0)
- {
- // Don't chown a local file for a remote system
-// if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
-// return Error("unable to perform chown");
- return Error();
- }
- // if we are still here rsync has failed - let's try the slow way before giving up
- }
+ }
+ return Platform::PutFile(source, destination, uid, gid);
+}
+
+lldb::user_id_t PlatformPOSIX::GetFileSize(const FileSpec &file_spec) {
+ if (IsHost())
+ return FileSystem::GetFileSize(file_spec);
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileSize(file_spec);
+ else
+ return Platform::GetFileSize(file_spec);
+}
+
+Error PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) {
+ if (IsHost())
+ return FileSystem::Symlink(src, dst);
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->CreateSymlink(src, dst);
+ else
+ return Platform::CreateSymlink(src, dst);
+}
+
+bool PlatformPOSIX::GetFileExists(const FileSpec &file_spec) {
+ if (IsHost())
+ return file_spec.Exists();
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileExists(file_spec);
+ else
+ return Platform::GetFileExists(file_spec);
+}
+
+Error PlatformPOSIX::Unlink(const FileSpec &file_spec) {
+ if (IsHost())
+ return FileSystem::Unlink(file_spec);
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->Unlink(file_spec);
+ else
+ return Platform::Unlink(file_spec);
+}
+
+lldb_private::Error PlatformPOSIX::GetFile(
+ const lldb_private::FileSpec &source, // remote file path
+ const lldb_private::FileSpec &destination) // local file path
+{
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
+ // Check the args, first.
+ std::string src_path(source.GetPath());
+ if (src_path.empty())
+ return Error("unable to get file path for source");
+ std::string dst_path(destination.GetPath());
+ if (dst_path.empty())
+ return Error("unable to get file path for destination");
+ if (IsHost()) {
+ if (FileSpec::Equal(source, destination, true))
+ return Error("local scenario->source and destination are the same file "
+ "path: no operation performed");
+ // cp src dst
+ StreamString cp_command;
+ cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
+ int status;
+ RunShellCommand(cp_command.GetData(), NULL, &status, NULL, NULL, 10);
+ if (status != 0)
+ return Error("unable to perform copy");
+ return Error();
+ } else if (m_remote_platform_sp) {
+ if (GetSupportsRSync()) {
+ StreamString command;
+ if (GetIgnoresRemoteHostname()) {
+ if (!GetRSyncPrefix())
+ command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(),
+ dst_path.c_str());
+ else
+ command.Printf("rsync %s %s%s %s", GetRSyncOpts(), GetRSyncPrefix(),
+ src_path.c_str(), dst_path.c_str());
+ } else
+ command.Printf("rsync %s %s:%s %s", GetRSyncOpts(),
+ m_remote_platform_sp->GetHostname(), src_path.c_str(),
+ dst_path.c_str());
+ if (log)
+ log->Printf("[GetFile] Running command: %s\n", command.GetData());
+ int retcode;
+ Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL, 60);
+ if (retcode == 0)
+ return Error();
+ // If we are here, rsync has failed - let's try the slow way before giving
+ // up
}
- return Platform::PutFile(source,destination,uid,gid);
-}
+ // open src and dst
+ // read/write, read/write, read/write, ...
+ // close src
+ // close dst
+ if (log)
+ log->Printf("[GetFile] Using block by block transfer....\n");
+ Error error;
+ user_id_t fd_src = OpenFile(source, File::eOpenOptionRead,
+ lldb::eFilePermissionsFileDefault, error);
-lldb::user_id_t
-PlatformPOSIX::GetFileSize (const FileSpec& file_spec)
-{
- if (IsHost())
- return FileSystem::GetFileSize(file_spec);
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileSize(file_spec);
- else
- return Platform::GetFileSize(file_spec);
-}
+ if (fd_src == UINT64_MAX)
+ return Error("unable to open source file");
-Error
-PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst)
-{
- if (IsHost())
- return FileSystem::Symlink(src, dst);
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->CreateSymlink(src, dst);
- else
- return Platform::CreateSymlink(src, dst);
-}
+ uint32_t permissions = 0;
+ error = GetFilePermissions(source, permissions);
-bool
-PlatformPOSIX::GetFileExists (const FileSpec& file_spec)
-{
- if (IsHost())
- return file_spec.Exists();
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileExists(file_spec);
- else
- return Platform::GetFileExists(file_spec);
-}
+ if (permissions == 0)
+ permissions = lldb::eFilePermissionsFileDefault;
-Error
-PlatformPOSIX::Unlink(const FileSpec &file_spec)
-{
- if (IsHost())
- return FileSystem::Unlink(file_spec);
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->Unlink(file_spec);
- else
- return Platform::Unlink(file_spec);
-}
+ user_id_t fd_dst = FileCache::GetInstance().OpenFile(
+ destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite |
+ File::eOpenOptionTruncate,
+ permissions, error);
-lldb_private::Error
-PlatformPOSIX::GetFile(const lldb_private::FileSpec &source, // remote file path
- const lldb_private::FileSpec &destination) // local file path
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
-
- // Check the args, first.
- std::string src_path (source.GetPath());
- if (src_path.empty())
- return Error("unable to get file path for source");
- std::string dst_path (destination.GetPath());
- if (dst_path.empty())
- return Error("unable to get file path for destination");
- if (IsHost())
- {
- if (FileSpec::Equal(source, destination, true))
- return Error("local scenario->source and destination are the same file path: no operation performed");
- // cp src dst
- StreamString cp_command;
- cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
- int status;
- RunShellCommand(cp_command.GetData(),
- NULL,
- &status,
- NULL,
- NULL,
- 10);
- if (status != 0)
- return Error("unable to perform copy");
- return Error();
+ if (fd_dst == UINT64_MAX) {
+ if (error.Success())
+ error.SetErrorString("unable to open destination file");
}
- else if (m_remote_platform_sp)
- {
- if (GetSupportsRSync())
- {
- StreamString command;
- if (GetIgnoresRemoteHostname())
- {
- if (!GetRSyncPrefix())
- command.Printf("rsync %s %s %s",
- GetRSyncOpts(),
- src_path.c_str(),
- dst_path.c_str());
- else
- command.Printf("rsync %s %s%s %s",
- GetRSyncOpts(),
- GetRSyncPrefix(),
- src_path.c_str(),
- dst_path.c_str());
- }
- else
- command.Printf("rsync %s %s:%s %s",
- GetRSyncOpts(),
- m_remote_platform_sp->GetHostname(),
- src_path.c_str(),
- dst_path.c_str());
- if (log)
- log->Printf("[GetFile] Running command: %s\n", command.GetData());
- int retcode;
- Host::RunShellCommand(command.GetData(),
- NULL,
- &retcode,
- NULL,
- NULL,
- 60);
- if (retcode == 0)
- return Error();
- // If we are here, rsync has failed - let's try the slow way before giving up
- }
- // open src and dst
- // read/write, read/write, read/write, ...
- // close src
- // close dst
- if (log)
- log->Printf("[GetFile] Using block by block transfer....\n");
- Error error;
- user_id_t fd_src = OpenFile (source,
- File::eOpenOptionRead,
- lldb::eFilePermissionsFileDefault,
- error);
-
- if (fd_src == UINT64_MAX)
- return Error("unable to open source file");
-
- uint32_t permissions = 0;
- error = GetFilePermissions(source, permissions);
-
- if (permissions == 0)
- permissions = lldb::eFilePermissionsFileDefault;
-
- user_id_t fd_dst = FileCache::GetInstance().OpenFile(
- destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, permissions,
- error);
-
- if (fd_dst == UINT64_MAX)
- {
- if (error.Success())
- error.SetErrorString("unable to open destination file");
- }
-
- if (error.Success())
- {
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
- uint64_t offset = 0;
- error.Clear();
- while (error.Success())
- {
- const uint64_t n_read = ReadFile (fd_src,
- offset,
- buffer_sp->GetBytes(),
- buffer_sp->GetByteSize(),
- error);
- if (error.Fail())
- break;
- if (n_read == 0)
- break;
- if (FileCache::GetInstance().WriteFile(fd_dst, offset, buffer_sp->GetBytes(), n_read, error) != n_read)
- {
- if (!error.Fail())
- error.SetErrorString("unable to write to destination file");
- break;
- }
- offset += n_read;
- }
- }
- // Ignore the close error of src.
- if (fd_src != UINT64_MAX)
- CloseFile(fd_src, error);
- // And close the dst file descriptot.
- if (fd_dst != UINT64_MAX && !FileCache::GetInstance().CloseFile(fd_dst, error))
- {
- if (!error.Fail())
- error.SetErrorString("unable to close destination file");
+ if (error.Success()) {
+ lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
+ uint64_t offset = 0;
+ error.Clear();
+ while (error.Success()) {
+ const uint64_t n_read = ReadFile(fd_src, offset, buffer_sp->GetBytes(),
+ buffer_sp->GetByteSize(), error);
+ if (error.Fail())
+ break;
+ if (n_read == 0)
+ break;
+ if (FileCache::GetInstance().WriteFile(fd_dst, offset,
+ buffer_sp->GetBytes(), n_read,
+ error) != n_read) {
+ if (!error.Fail())
+ error.SetErrorString("unable to write to destination file");
+ break;
}
- return error;
+ offset += n_read;
+ }
}
- return Platform::GetFile(source,destination);
-}
-
-std::string
-PlatformPOSIX::GetPlatformSpecificConnectionInformation()
-{
- StreamString stream;
- if (GetSupportsRSync())
- {
- stream.PutCString("rsync");
- if ( (GetRSyncOpts() && *GetRSyncOpts()) ||
- (GetRSyncPrefix() && *GetRSyncPrefix()) ||
- GetIgnoresRemoteHostname())
- {
- stream.Printf(", options: ");
- if (GetRSyncOpts() && *GetRSyncOpts())
- stream.Printf("'%s' ",GetRSyncOpts());
- stream.Printf(", prefix: ");
- if (GetRSyncPrefix() && *GetRSyncPrefix())
- stream.Printf("'%s' ",GetRSyncPrefix());
- if (GetIgnoresRemoteHostname())
- stream.Printf("ignore remote-hostname ");
- }
+ // Ignore the close error of src.
+ if (fd_src != UINT64_MAX)
+ CloseFile(fd_src, error);
+ // And close the dst file descriptot.
+ if (fd_dst != UINT64_MAX &&
+ !FileCache::GetInstance().CloseFile(fd_dst, error)) {
+ if (!error.Fail())
+ error.SetErrorString("unable to close destination file");
}
- if (GetSupportsSSH())
- {
- stream.PutCString("ssh");
- if (GetSSHOpts() && *GetSSHOpts())
- stream.Printf(", options: '%s' ",GetSSHOpts());
+ return error;
+ }
+ return Platform::GetFile(source, destination);
+}
+
+std::string PlatformPOSIX::GetPlatformSpecificConnectionInformation() {
+ StreamString stream;
+ if (GetSupportsRSync()) {
+ stream.PutCString("rsync");
+ if ((GetRSyncOpts() && *GetRSyncOpts()) ||
+ (GetRSyncPrefix() && *GetRSyncPrefix()) || GetIgnoresRemoteHostname()) {
+ stream.Printf(", options: ");
+ if (GetRSyncOpts() && *GetRSyncOpts())
+ stream.Printf("'%s' ", GetRSyncOpts());
+ stream.Printf(", prefix: ");
+ if (GetRSyncPrefix() && *GetRSyncPrefix())
+ stream.Printf("'%s' ", GetRSyncPrefix());
+ if (GetIgnoresRemoteHostname())
+ stream.Printf("ignore remote-hostname ");
}
- if (GetLocalCacheDirectory() && *GetLocalCacheDirectory())
- stream.Printf("cache dir: %s",GetLocalCacheDirectory());
- if (stream.GetSize())
- return stream.GetData();
- else
- return "";
+ }
+ if (GetSupportsSSH()) {
+ stream.PutCString("ssh");
+ if (GetSSHOpts() && *GetSSHOpts())
+ stream.Printf(", options: '%s' ", GetSSHOpts());
+ }
+ if (GetLocalCacheDirectory() && *GetLocalCacheDirectory())
+ stream.Printf("cache dir: %s", GetLocalCacheDirectory());
+ if (stream.GetSize())
+ return stream.GetString();
+ else
+ return "";
}
-bool
-PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec,
- uint64_t &low,
- uint64_t &high)
-{
- if (IsHost())
- return Platform::CalculateMD5 (file_spec, low, high);
- if (m_remote_platform_sp)
- return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
- return false;
+bool PlatformPOSIX::CalculateMD5(const FileSpec &file_spec, uint64_t &low,
+ uint64_t &high) {
+ if (IsHost())
+ return Platform::CalculateMD5(file_spec, low, high);
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
+ return false;
}
-const lldb::UnixSignalsSP &
-PlatformPOSIX::GetRemoteUnixSignals() {
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteUnixSignals();
- return Platform::GetRemoteUnixSignals();
+const lldb::UnixSignalsSP &PlatformPOSIX::GetRemoteUnixSignals() {
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteUnixSignals();
+ return Platform::GetRemoteUnixSignals();
}
-
-FileSpec
-PlatformPOSIX::GetRemoteWorkingDirectory()
-{
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteWorkingDirectory();
- else
- return Platform::GetRemoteWorkingDirectory();
+FileSpec PlatformPOSIX::GetRemoteWorkingDirectory() {
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteWorkingDirectory();
+ else
+ return Platform::GetRemoteWorkingDirectory();
}
-bool
-PlatformPOSIX::SetRemoteWorkingDirectory(const FileSpec &working_dir)
-{
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
- else
- return Platform::SetRemoteWorkingDirectory(working_dir);
+bool PlatformPOSIX::SetRemoteWorkingDirectory(const FileSpec &working_dir) {
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
+ else
+ return Platform::SetRemoteWorkingDirectory(working_dir);
}
-bool
-PlatformPOSIX::GetRemoteOSVersion ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetOSVersion (m_major_os_version,
- m_minor_os_version,
- m_update_os_version);
- return false;
+bool PlatformPOSIX::GetRemoteOSVersion() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetOSVersion(
+ m_major_os_version, m_minor_os_version, m_update_os_version);
+ return false;
}
-bool
-PlatformPOSIX::GetRemoteOSBuildString (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSBuildString (s);
- s.clear();
- return false;
+bool PlatformPOSIX::GetRemoteOSBuildString(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSBuildString(s);
+ s.clear();
+ return false;
}
-size_t
-PlatformPOSIX::GetEnvironment (StringList &env)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetEnvironment(env);
- return 0;
- }
- return Host::GetEnvironment(env);
+size_t PlatformPOSIX::GetEnvironment(StringList &env) {
+ if (IsRemote()) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetEnvironment(env);
+ return 0;
+ }
+ return Host::GetEnvironment(env);
}
-bool
-PlatformPOSIX::GetRemoteOSKernelDescription (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSKernelDescription (s);
- s.clear();
- return false;
+bool PlatformPOSIX::GetRemoteOSKernelDescription(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
+ s.clear();
+ return false;
}
// Remote Platform subclasses need to override this function
-ArchSpec
-PlatformPOSIX::GetRemoteSystemArchitecture ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteSystemArchitecture ();
- return ArchSpec();
+ArchSpec PlatformPOSIX::GetRemoteSystemArchitecture() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteSystemArchitecture();
+ return ArchSpec();
}
-const char *
-PlatformPOSIX::GetHostname ()
-{
- if (IsHost())
- return Platform::GetHostname();
+const char *PlatformPOSIX::GetHostname() {
+ if (IsHost())
+ return Platform::GetHostname();
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetHostname ();
- return NULL;
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetHostname();
+ return NULL;
}
-const char *
-PlatformPOSIX::GetUserName (uint32_t uid)
-{
- // Check the cache in Platform in case we have already looked this uid up
- const char *user_name = Platform::GetUserName(uid);
- if (user_name)
- return user_name;
-
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetUserName(uid);
- return NULL;
+const char *PlatformPOSIX::GetUserName(uint32_t uid) {
+ // Check the cache in Platform in case we have already looked this uid up
+ const char *user_name = Platform::GetUserName(uid);
+ if (user_name)
+ return user_name;
+
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetUserName(uid);
+ return NULL;
}
-const char *
-PlatformPOSIX::GetGroupName (uint32_t gid)
-{
- const char *group_name = Platform::GetGroupName(gid);
- if (group_name)
- return group_name;
+const char *PlatformPOSIX::GetGroupName(uint32_t gid) {
+ const char *group_name = Platform::GetGroupName(gid);
+ if (group_name)
+ return group_name;
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetGroupName(gid);
- return NULL;
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetGroupName(gid);
+ return NULL;
}
-Error
-PlatformPOSIX::ConnectRemote (Args& args)
-{
- Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString());
- }
- else
- {
- if (!m_remote_platform_sp)
- m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error);
-
- if (m_remote_platform_sp && error.Success())
- error = m_remote_platform_sp->ConnectRemote (args);
- else
- error.SetErrorString ("failed to create a 'remote-gdb-server' platform");
+Error PlatformPOSIX::ConnectRemote(Args &args) {
+ Error error;
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't connect to the host platform '%s', always connected",
+ GetPluginName().GetCString());
+ } else {
+ if (!m_remote_platform_sp)
+ m_remote_platform_sp =
+ Platform::Create(ConstString("remote-gdb-server"), error);
- if (error.Fail())
- m_remote_platform_sp.reset();
- }
+ if (m_remote_platform_sp && error.Success())
+ error = m_remote_platform_sp->ConnectRemote(args);
+ else
+ error.SetErrorString("failed to create a 'remote-gdb-server' platform");
- if (error.Success() && m_remote_platform_sp)
- {
- if (m_option_group_platform_rsync.get() && m_option_group_platform_ssh.get() && m_option_group_platform_caching.get())
- {
- if (m_option_group_platform_rsync->m_rsync)
- {
- SetSupportsRSync(true);
- SetRSyncOpts(m_option_group_platform_rsync->m_rsync_opts.c_str());
- SetRSyncPrefix(m_option_group_platform_rsync->m_rsync_prefix.c_str());
- SetIgnoresRemoteHostname(m_option_group_platform_rsync->m_ignores_remote_hostname);
- }
- if (m_option_group_platform_ssh->m_ssh)
- {
- SetSupportsSSH(true);
- SetSSHOpts(m_option_group_platform_ssh->m_ssh_opts.c_str());
- }
- SetLocalCacheDirectory(m_option_group_platform_caching->m_cache_dir.c_str());
- }
+ if (error.Fail())
+ m_remote_platform_sp.reset();
+ }
+
+ if (error.Success() && m_remote_platform_sp) {
+ if (m_option_group_platform_rsync.get() &&
+ m_option_group_platform_ssh.get() &&
+ m_option_group_platform_caching.get()) {
+ if (m_option_group_platform_rsync->m_rsync) {
+ SetSupportsRSync(true);
+ SetRSyncOpts(m_option_group_platform_rsync->m_rsync_opts.c_str());
+ SetRSyncPrefix(m_option_group_platform_rsync->m_rsync_prefix.c_str());
+ SetIgnoresRemoteHostname(
+ m_option_group_platform_rsync->m_ignores_remote_hostname);
+ }
+ if (m_option_group_platform_ssh->m_ssh) {
+ SetSupportsSSH(true);
+ SetSSHOpts(m_option_group_platform_ssh->m_ssh_opts.c_str());
+ }
+ SetLocalCacheDirectory(
+ m_option_group_platform_caching->m_cache_dir.c_str());
}
+ }
- return error;
+ return error;
}
-Error
-PlatformPOSIX::DisconnectRemote ()
-{
- Error error;
+Error PlatformPOSIX::DisconnectRemote() {
+ Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString());
- }
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't disconnect from the host platform '%s', always connected",
+ GetPluginName().GetCString());
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->DisconnectRemote();
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->DisconnectRemote ();
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-Error
-PlatformPOSIX::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Error error;
+Error PlatformPOSIX::LaunchProcess(ProcessLaunchInfo &launch_info) {
+ Error error;
- if (IsHost())
- {
- error = Platform::LaunchProcess (launch_info);
- }
+ if (IsHost()) {
+ error = Platform::LaunchProcess(launch_info);
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->LaunchProcess(launch_info);
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->LaunchProcess (launch_info);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-lldb_private::Error
-PlatformPOSIX::KillProcess (const lldb::pid_t pid)
-{
- if (IsHost())
- return Platform::KillProcess (pid);
+lldb_private::Error PlatformPOSIX::KillProcess(const lldb::pid_t pid) {
+ if (IsHost())
+ return Platform::KillProcess(pid);
- if (m_remote_platform_sp)
- return m_remote_platform_sp->KillProcess (pid);
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->KillProcess(pid);
- return Error ("the platform is not currently connected");
+ return Error("the platform is not currently connected");
}
-lldb::ProcessSP
-PlatformPOSIX::Attach (ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error)
-{
- lldb::ProcessSP process_sp;
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
-
- if (IsHost())
- {
- if (target == NULL)
- {
- TargetSP new_target_sp;
-
- error = debugger.GetTargetList().CreateTarget (debugger,
- NULL,
- NULL,
- false,
- NULL,
- new_target_sp);
- target = new_target_sp.get();
- if (log)
- log->Printf ("PlatformPOSIX::%s created new target", __FUNCTION__);
- }
- else
- {
- error.Clear();
- if (log)
- log->Printf ("PlatformPOSIX::%s target already existed, setting target", __FUNCTION__);
- }
+lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger, Target *target,
+ Error &error) {
+ lldb::ProcessSP process_sp;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
+ if (IsHost()) {
+ if (target == NULL) {
+ TargetSP new_target_sp;
- if (target && error.Success())
- {
- debugger.GetTargetList().SetSelectedTarget(target);
- if (log)
- {
- ModuleSP exe_module_sp = target->GetExecutableModule ();
- log->Printf("PlatformPOSIX::%s set selected target to %p %s", __FUNCTION__, (void *)target,
- exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str() : "<null>");
- }
-
-
- process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), attach_info.GetProcessPluginName(), NULL);
-
- if (process_sp)
- {
- ListenerSP listener_sp = attach_info.GetHijackListener();
- if (listener_sp == nullptr)
- {
- listener_sp = Listener::MakeListener("lldb.PlatformPOSIX.attach.hijack");
- attach_info.SetHijackListener(listener_sp);
- }
- process_sp->HijackProcessEvents(listener_sp);
- error = process_sp->Attach (attach_info);
- }
+ error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
+ NULL, new_target_sp);
+ target = new_target_sp.get();
+ if (log)
+ log->Printf("PlatformPOSIX::%s created new target", __FUNCTION__);
+ } else {
+ error.Clear();
+ if (log)
+ log->Printf("PlatformPOSIX::%s target already existed, setting target",
+ __FUNCTION__);
+ }
+
+ if (target && error.Success()) {
+ debugger.GetTargetList().SetSelectedTarget(target);
+ if (log) {
+ ModuleSP exe_module_sp = target->GetExecutableModule();
+ log->Printf("PlatformPOSIX::%s set selected target to %p %s",
+ __FUNCTION__, (void *)target,
+ exe_module_sp
+ ? exe_module_sp->GetFileSpec().GetPath().c_str()
+ : "<null>");
+ }
+
+ process_sp =
+ target->CreateProcess(attach_info.GetListenerForProcess(debugger),
+ attach_info.GetProcessPluginName(), NULL);
+
+ if (process_sp) {
+ ListenerSP listener_sp = attach_info.GetHijackListener();
+ if (listener_sp == nullptr) {
+ listener_sp =
+ Listener::MakeListener("lldb.PlatformPOSIX.attach.hijack");
+ attach_info.SetHijackListener(listener_sp);
}
+ process_sp->HijackProcessEvents(listener_sp);
+ error = process_sp->Attach(attach_info);
+ }
}
+ } else {
+ if (m_remote_platform_sp)
+ process_sp =
+ m_remote_platform_sp->Attach(attach_info, debugger, target, error);
else
- {
- if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return process_sp;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return process_sp;
}
lldb::ProcessSP
-PlatformPOSIX::DebugProcess (ProcessLaunchInfo &launch_info,
- Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
- Error &error)
-{
- ProcessSP process_sp;
-
- if (IsHost())
- {
- // We are going to hand this process off to debugserver which will be in charge of setting the exit status.
- // We still need to reap it from lldb but if we let the monitor thread also set the exit status, we set up a
- // race between debugserver & us for who will find out about the debugged process's death.
- launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus);
- process_sp = Platform::DebugProcess (launch_info, debugger, target, error);
- }
+PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new
+ // target, else use existing one
+ Error &error) {
+ ProcessSP process_sp;
+
+ if (IsHost()) {
+ // We are going to hand this process off to debugserver which will be in
+ // charge of setting the exit status.
+ // We still need to reap it from lldb but if we let the monitor thread also
+ // set the exit status, we set up a
+ // race between debugserver & us for who will find out about the debugged
+ // process's death.
+ launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus);
+ process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
+ } else {
+ if (m_remote_platform_sp)
+ process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
+ target, error);
else
- {
- if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, error);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return process_sp;
-
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return process_sp;
}
-void
-PlatformPOSIX::CalculateTrapHandlerSymbolNames ()
-{
- m_trap_handlers.push_back (ConstString ("_sigtramp"));
-}
-
-Error
-PlatformPOSIX::EvaluateLibdlExpression(lldb_private::Process* process,
- const char* expr_cstr,
- const char* expr_prefix,
- lldb::ValueObjectSP& result_valobj_sp)
-{
- DynamicLoader *loader = process->GetDynamicLoader();
- if (loader)
- {
- Error error = loader->CanLoadImage();
- if (error.Fail())
- return error;
- }
-
- ThreadSP thread_sp(process->GetThreadList().GetExpressionExecutionThread());
- if (!thread_sp)
- return Error("Selected thread isn't valid");
-
- StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
- if (!frame_sp)
- return Error("Frame 0 isn't valid");
-
- ExecutionContext exe_ctx;
- frame_sp->CalculateExecutionContext(exe_ctx);
- EvaluateExpressionOptions expr_options;
- expr_options.SetUnwindOnError(true);
- expr_options.SetIgnoreBreakpoints(true);
- expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
- expr_options.SetLanguage(eLanguageTypeC_plus_plus);
- expr_options.SetTimeoutUsec(2000000); // 2 seconds
-
- Error expr_error;
- UserExpression::Evaluate(exe_ctx,
- expr_options,
- expr_cstr,
- expr_prefix,
- result_valobj_sp,
- expr_error);
- if (result_valobj_sp->GetError().Fail())
- return result_valobj_sp->GetError();
- return Error();
+void PlatformPOSIX::CalculateTrapHandlerSymbolNames() {
+ m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-uint32_t
-PlatformPOSIX::DoLoadImage(lldb_private::Process* process,
- const lldb_private::FileSpec& remote_file,
- lldb_private::Error& error)
-{
- char path[PATH_MAX];
- remote_file.GetPath(path, sizeof(path));
-
- StreamString expr;
- expr.Printf(R"(
+Error PlatformPOSIX::EvaluateLibdlExpression(
+ lldb_private::Process *process, const char *expr_cstr,
+ const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp) {
+ DynamicLoader *loader = process->GetDynamicLoader();
+ if (loader) {
+ Error error = loader->CanLoadImage();
+ if (error.Fail())
+ return error;
+ }
+
+ ThreadSP thread_sp(process->GetThreadList().GetExpressionExecutionThread());
+ if (!thread_sp)
+ return Error("Selected thread isn't valid");
+
+ StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
+ if (!frame_sp)
+ return Error("Frame 0 isn't valid");
+
+ ExecutionContext exe_ctx;
+ frame_sp->CalculateExecutionContext(exe_ctx);
+ EvaluateExpressionOptions expr_options;
+ expr_options.SetUnwindOnError(true);
+ expr_options.SetIgnoreBreakpoints(true);
+ expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
+ expr_options.SetLanguage(eLanguageTypeC_plus_plus);
+ expr_options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
+ // don't do the work to trap them.
+ expr_options.SetTimeout(std::chrono::seconds(2));
+
+ Error expr_error;
+ ExpressionResults result =
+ UserExpression::Evaluate(exe_ctx, expr_options, expr_cstr, expr_prefix,
+ result_valobj_sp, expr_error);
+ if (result != eExpressionCompleted)
+ return expr_error;
+
+ if (result_valobj_sp->GetError().Fail())
+ return result_valobj_sp->GetError();
+ return Error();
+}
+
+uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
+ const lldb_private::FileSpec &remote_file,
+ lldb_private::Error &error) {
+ char path[PATH_MAX];
+ remote_file.GetPath(path, sizeof(path));
+
+ StreamString expr;
+ expr.Printf(R"(
struct __lldb_dlopen_result { void *image_ptr; const char *error_str; } the_result;
the_result.image_ptr = dlopen ("%s", 2);
if (the_result.image_ptr == (void *) 0x0)
@@ -918,96 +768,89 @@ PlatformPOSIX::DoLoadImage(lldb_private::Process* process,
}
the_result;
)",
- path);
- const char *prefix = GetLibdlFunctionDeclarations();
- lldb::ValueObjectSP result_valobj_sp;
- error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp);
- if (error.Fail())
- return LLDB_INVALID_IMAGE_TOKEN;
+ path);
+ const char *prefix = GetLibdlFunctionDeclarations();
+ lldb::ValueObjectSP result_valobj_sp;
+ error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
+ result_valobj_sp);
+ if (error.Fail())
+ return LLDB_INVALID_IMAGE_TOKEN;
- error = result_valobj_sp->GetError();
- if (error.Fail())
- return LLDB_INVALID_IMAGE_TOKEN;
-
- Scalar scalar;
- ValueObjectSP image_ptr_sp = result_valobj_sp->GetChildAtIndex(0, true);
- if (!image_ptr_sp || !image_ptr_sp->ResolveValue(scalar))
- {
- error.SetErrorStringWithFormat("unable to load '%s'", path);
- return LLDB_INVALID_IMAGE_TOKEN;
- }
+ error = result_valobj_sp->GetError();
+ if (error.Fail())
+ return LLDB_INVALID_IMAGE_TOKEN;
- addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
- if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS)
- return process->AddImageToken(image_ptr);
-
- if (image_ptr == 0)
- {
- ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true);
- if (error_str_sp)
- {
- DataBufferSP buffer_sp(new DataBufferHeap(10240,0));
- size_t num_chars = error_str_sp->ReadPointedString (buffer_sp, error, 10240).first;
- if (error.Success() && num_chars > 0)
- error.SetErrorStringWithFormat("dlopen error: %s", buffer_sp->GetBytes());
- else
- error.SetErrorStringWithFormat("dlopen failed for unknown reasons.");
- return LLDB_INVALID_IMAGE_TOKEN;
- }
- }
+ Scalar scalar;
+ ValueObjectSP image_ptr_sp = result_valobj_sp->GetChildAtIndex(0, true);
+ if (!image_ptr_sp || !image_ptr_sp->ResolveValue(scalar)) {
error.SetErrorStringWithFormat("unable to load '%s'", path);
return LLDB_INVALID_IMAGE_TOKEN;
-}
-
-Error
-PlatformPOSIX::UnloadImage (lldb_private::Process* process, uint32_t image_token)
-{
- const addr_t image_addr = process->GetImagePtrFromToken(image_token);
- if (image_addr == LLDB_INVALID_ADDRESS)
- return Error("Invalid image token");
-
- StreamString expr;
- expr.Printf("dlclose((void *)0x%" PRIx64 ")", image_addr);
- const char *prefix = GetLibdlFunctionDeclarations();
- lldb::ValueObjectSP result_valobj_sp;
- Error error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp);
- if (error.Fail())
- return error;
+ }
+
+ addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
+ if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS)
+ return process->AddImageToken(image_ptr);
+
+ if (image_ptr == 0) {
+ ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true);
+ if (error_str_sp) {
+ DataBufferSP buffer_sp(new DataBufferHeap(10240, 0));
+ size_t num_chars =
+ error_str_sp->ReadPointedString(buffer_sp, error, 10240).first;
+ if (error.Success() && num_chars > 0)
+ error.SetErrorStringWithFormat("dlopen error: %s",
+ buffer_sp->GetBytes());
+ else
+ error.SetErrorStringWithFormat("dlopen failed for unknown reasons.");
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+ }
+ error.SetErrorStringWithFormat("unable to load '%s'", path);
+ return LLDB_INVALID_IMAGE_TOKEN;
+}
+
+Error PlatformPOSIX::UnloadImage(lldb_private::Process *process,
+ uint32_t image_token) {
+ const addr_t image_addr = process->GetImagePtrFromToken(image_token);
+ if (image_addr == LLDB_INVALID_ADDRESS)
+ return Error("Invalid image token");
+
+ StreamString expr;
+ expr.Printf("dlclose((void *)0x%" PRIx64 ")", image_addr);
+ const char *prefix = GetLibdlFunctionDeclarations();
+ lldb::ValueObjectSP result_valobj_sp;
+ Error error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
+ result_valobj_sp);
+ if (error.Fail())
+ return error;
- if (result_valobj_sp->GetError().Fail())
- return result_valobj_sp->GetError();
+ if (result_valobj_sp->GetError().Fail())
+ return result_valobj_sp->GetError();
- Scalar scalar;
- if (result_valobj_sp->ResolveValue(scalar))
- {
- if (scalar.UInt(1))
- return Error("expression failed: \"%s\"", expr.GetData());
- process->ResetImageToken(image_token);
- }
- return Error();
-}
+ Scalar scalar;
+ if (result_valobj_sp->ResolveValue(scalar)) {
+ if (scalar.UInt(1))
+ return Error("expression failed: \"%s\"", expr.GetData());
+ process->ResetImageToken(image_token);
+ }
+ return Error();
+}
-lldb::ProcessSP
-PlatformPOSIX::ConnectProcess (const char* connect_url,
- const char* plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->ConnectProcess(connect_url,
- plugin_name,
- debugger,
- target,
- error);
+lldb::ProcessSP PlatformPOSIX::ConnectProcess(llvm::StringRef connect_url,
+ llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name,
+ debugger, target, error);
- return Platform::ConnectProcess(connect_url, plugin_name, debugger, target, error);
+ return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
+ error);
}
-const char*
-PlatformPOSIX::GetLibdlFunctionDeclarations() const
-{
- return R"(
+const char *PlatformPOSIX::GetLibdlFunctionDeclarations() const {
+ return R"(
extern "C" void* dlopen(const char*, int);
extern "C" void* dlsym(void*, const char*);
extern "C" int dlclose(void*);
@@ -1015,10 +858,9 @@ PlatformPOSIX::GetLibdlFunctionDeclarations() const
)";
}
-size_t
-PlatformPOSIX::ConnectToWaitingProcesses(Debugger& debugger, Error& error)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
- return Platform::ConnectToWaitingProcesses(debugger, error);
+size_t PlatformPOSIX::ConnectToWaitingProcesses(Debugger &debugger,
+ Error &error) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
+ return Platform::ConnectToWaitingProcesses(debugger, error);
}
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 4f1f22002816..93213b295ca1 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -20,197 +20,174 @@
#include "lldb/Interpreter/Options.h"
#include "lldb/Target/Platform.h"
-class PlatformPOSIX : public lldb_private::Platform
-{
+class PlatformPOSIX : public lldb_private::Platform {
public:
- PlatformPOSIX(bool is_host);
-
- ~PlatformPOSIX() override;
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
-
- bool
- GetModuleSpec (const lldb_private::FileSpec& module_file_spec,
- const lldb_private::ArchSpec& arch,
- lldb_private::ModuleSpec &module_spec) override;
-
- lldb_private::OptionGroupOptions*
- GetConnectionOptions(lldb_private::CommandInterpreter &interpreter) override;
-
- const char *
- GetHostname () override;
-
- const char *
- GetUserName (uint32_t uid) override;
-
- const char *
- GetGroupName (uint32_t gid) override;
-
- lldb_private::Error
- PutFile (const lldb_private::FileSpec& source,
- const lldb_private::FileSpec& destination,
- uint32_t uid = UINT32_MAX,
- uint32_t gid = UINT32_MAX) override;
-
- lldb::user_id_t
- OpenFile (const lldb_private::FileSpec& file_spec,
- uint32_t flags,
- uint32_t mode,
- lldb_private::Error &error) override;
-
- bool
- CloseFile (lldb::user_id_t fd,
- lldb_private::Error &error) override;
-
- uint64_t
- ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- lldb_private::Error &error) override;
-
- uint64_t
- WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- lldb_private::Error &error) override;
-
- lldb::user_id_t
- GetFileSize (const lldb_private::FileSpec& file_spec) override;
-
- lldb_private::Error
- CreateSymlink(const lldb_private::FileSpec &src,
- const lldb_private::FileSpec &dst) override;
-
- lldb_private::Error
- GetFile(const lldb_private::FileSpec &source,
- const lldb_private::FileSpec &destination) override;
-
- lldb_private::FileSpec
- GetRemoteWorkingDirectory() override;
-
- bool
- SetRemoteWorkingDirectory(const lldb_private::FileSpec &working_dir) override;
-
- bool
- GetRemoteOSVersion () override;
-
- bool
- GetRemoteOSBuildString (std::string &s) override;
-
- bool
- GetRemoteOSKernelDescription (std::string &s) override;
-
- lldb_private::ArchSpec
- GetRemoteSystemArchitecture () override;
-
- const lldb::UnixSignalsSP &
- GetRemoteUnixSignals() override;
-
- size_t
- GetEnvironment (lldb_private::StringList &environment) override;
-
- bool
- IsConnected () const override;
-
- lldb_private::Error
- RunShellCommand(const char *command, // Shouldn't be nullptr
- const lldb_private::FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass nullptr if you don't want the process exit status
- int *signo_ptr, // Pass nullptr if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass nullptr if you don't want the command output
- uint32_t timeout_sec) override; // Timeout in seconds to wait for shell program to finish
-
- lldb_private::Error
- MakeDirectory(const lldb_private::FileSpec &file_spec, uint32_t mode) override;
-
- lldb_private::Error
- GetFilePermissions(const lldb_private::FileSpec &file_spec, uint32_t &file_permissions) override;
-
- lldb_private::Error
- SetFilePermissions(const lldb_private::FileSpec &file_spec, uint32_t file_permissions) override;
-
- bool
- GetFileExists (const lldb_private::FileSpec& file_spec) override;
-
- lldb_private::Error
- Unlink(const lldb_private::FileSpec &file_spec) override;
-
- lldb_private::Error
- LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info) override;
-
- lldb_private::Error
- KillProcess (const lldb::pid_t pid) override;
-
- lldb::ProcessSP
- Attach (lldb_private::ProcessAttachInfo &attach_info,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target, // Can be nullptr, if nullptr create a new target, else use existing one
- lldb_private::Error &error) override;
-
- lldb::ProcessSP
- DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target, // Can be nullptr, if nullptr create a new target, else use existing one
- lldb_private::Error &error) override;
-
- std::string
- GetPlatformSpecificConnectionInformation() override;
-
- bool
- CalculateMD5 (const lldb_private::FileSpec& file_spec,
- uint64_t &low,
- uint64_t &high) override;
-
- void
- CalculateTrapHandlerSymbolNames () override;
-
- lldb_private::Error
- ConnectRemote (lldb_private::Args& args) override;
-
- lldb_private::Error
- DisconnectRemote () override;
-
- uint32_t
- DoLoadImage (lldb_private::Process* process,
- const lldb_private::FileSpec& remote_file,
- lldb_private::Error& error) override;
-
- lldb_private::Error
- UnloadImage (lldb_private::Process* process, uint32_t image_token) override;
-
- lldb::ProcessSP
- ConnectProcess (const char* connect_url,
- const char* plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error) override;
-
- size_t
- ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
+ PlatformPOSIX(bool is_host);
+
+ ~PlatformPOSIX() override;
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+
+ bool GetModuleSpec(const lldb_private::FileSpec &module_file_spec,
+ const lldb_private::ArchSpec &arch,
+ lldb_private::ModuleSpec &module_spec) override;
+
+ lldb_private::OptionGroupOptions *
+ GetConnectionOptions(lldb_private::CommandInterpreter &interpreter) override;
+
+ const char *GetHostname() override;
+
+ const char *GetUserName(uint32_t uid) override;
+
+ const char *GetGroupName(uint32_t gid) override;
+
+ lldb_private::Error PutFile(const lldb_private::FileSpec &source,
+ const lldb_private::FileSpec &destination,
+ uint32_t uid = UINT32_MAX,
+ uint32_t gid = UINT32_MAX) override;
+
+ lldb::user_id_t OpenFile(const lldb_private::FileSpec &file_spec,
+ uint32_t flags, uint32_t mode,
+ lldb_private::Error &error) override;
+
+ bool CloseFile(lldb::user_id_t fd, lldb_private::Error &error) override;
+
+ uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+ uint64_t dst_len, lldb_private::Error &error) override;
+
+ uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
+ uint64_t src_len, lldb_private::Error &error) override;
+
+ lldb::user_id_t GetFileSize(const lldb_private::FileSpec &file_spec) override;
+
+ lldb_private::Error CreateSymlink(const lldb_private::FileSpec &src,
+ const lldb_private::FileSpec &dst) override;
+
+ lldb_private::Error
+ GetFile(const lldb_private::FileSpec &source,
+ const lldb_private::FileSpec &destination) override;
+
+ lldb_private::FileSpec GetRemoteWorkingDirectory() override;
+
+ bool
+ SetRemoteWorkingDirectory(const lldb_private::FileSpec &working_dir) override;
+
+ bool GetRemoteOSVersion() override;
+
+ bool GetRemoteOSBuildString(std::string &s) override;
+
+ bool GetRemoteOSKernelDescription(std::string &s) override;
+
+ lldb_private::ArchSpec GetRemoteSystemArchitecture() override;
+
+ const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;
+
+ size_t GetEnvironment(lldb_private::StringList &environment) override;
+
+ bool IsConnected() const override;
+
+ lldb_private::Error RunShellCommand(
+ const char *command, // Shouldn't be nullptr
+ const lldb_private::FileSpec &working_dir, // Pass empty FileSpec to use
+ // the current working
+ // directory
+ int *status_ptr, // Pass nullptr if you don't want the process exit status
+ int *signo_ptr, // Pass nullptr if you don't want the signal that caused
+ // the process to exit
+ std::string
+ *command_output, // Pass nullptr if you don't want the command output
+ uint32_t timeout_sec)
+ override; // Timeout in seconds to wait for shell program to finish
+
+ lldb_private::Error MakeDirectory(const lldb_private::FileSpec &file_spec,
+ uint32_t mode) override;
+
+ lldb_private::Error
+ GetFilePermissions(const lldb_private::FileSpec &file_spec,
+ uint32_t &file_permissions) override;
+
+ lldb_private::Error
+ SetFilePermissions(const lldb_private::FileSpec &file_spec,
+ uint32_t file_permissions) override;
+
+ bool GetFileExists(const lldb_private::FileSpec &file_spec) override;
+
+ lldb_private::Error Unlink(const lldb_private::FileSpec &file_spec) override;
+
+ lldb_private::Error
+ LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
+
+ lldb_private::Error KillProcess(const lldb::pid_t pid) override;
+
+ lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target, // Can be nullptr, if
+ // nullptr create a new
+ // target, else use
+ // existing one
+ lldb_private::Error &error) override;
+
+ lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target, // Can be nullptr,
+ // if nullptr
+ // create a new
+ // target, else use
+ // existing one
+ lldb_private::Error &error) override;
+
+ std::string GetPlatformSpecificConnectionInformation() override;
+
+ bool CalculateMD5(const lldb_private::FileSpec &file_spec, uint64_t &low,
+ uint64_t &high) override;
+
+ void CalculateTrapHandlerSymbolNames() override;
+
+ lldb_private::Error ConnectRemote(lldb_private::Args &args) override;
+
+ lldb_private::Error DisconnectRemote() override;
+
+ uint32_t DoLoadImage(lldb_private::Process *process,
+ const lldb_private::FileSpec &remote_file,
+ lldb_private::Error &error) override;
+
+ lldb_private::Error UnloadImage(lldb_private::Process *process,
+ uint32_t image_token) override;
+
+ lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
+ llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
+
+ size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
+ lldb_private::Error &error) override;
protected:
- std::unique_ptr<lldb_private::OptionGroupPlatformRSync> m_option_group_platform_rsync;
- std::unique_ptr<lldb_private::OptionGroupPlatformSSH> m_option_group_platform_ssh;
- std::unique_ptr<lldb_private::OptionGroupPlatformCaching> m_option_group_platform_caching;
-
- std::map<lldb_private::CommandInterpreter*,std::unique_ptr<lldb_private::OptionGroupOptions>> m_options;
- lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS
-
- lldb_private::Error
- EvaluateLibdlExpression(lldb_private::Process* process,
- const char *expr_cstr,
- const char *expr_prefix,
- lldb::ValueObjectSP& result_valobj_sp);
-
- virtual const char*
- GetLibdlFunctionDeclarations() const;
+ std::unique_ptr<lldb_private::OptionGroupPlatformRSync>
+ m_option_group_platform_rsync;
+ std::unique_ptr<lldb_private::OptionGroupPlatformSSH>
+ m_option_group_platform_ssh;
+ std::unique_ptr<lldb_private::OptionGroupPlatformCaching>
+ m_option_group_platform_caching;
+
+ std::map<lldb_private::CommandInterpreter *,
+ std::unique_ptr<lldb_private::OptionGroupOptions>>
+ m_options;
+ lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a
+ // remote POSIX-compliant OS
+
+ lldb_private::Error
+ EvaluateLibdlExpression(lldb_private::Process *process, const char *expr_cstr,
+ const char *expr_prefix,
+ lldb::ValueObjectSP &result_valobj_sp);
+
+ virtual const char *GetLibdlFunctionDeclarations() const;
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformPOSIX);
+ DISALLOW_COPY_AND_ASSIGN(PlatformPOSIX);
};
#endif // liblldb_PlatformPOSIX_h_
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.cpp b/source/Plugins/Platform/Windows/PlatformWindows.cpp
index cef5684d9bac..290d8eab792f 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -11,7 +11,7 @@
// C Includes
#include <stdio.h>
-#if defined (_WIN32)
+#if defined(_WIN32)
#include "lldb/Host/windows/windows.h"
#include <winsock2.h>
#endif
@@ -19,14 +19,14 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Error.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Target/Process.h"
using namespace lldb;
@@ -34,161 +34,133 @@ using namespace lldb_private;
static uint32_t g_initialize_count = 0;
-namespace
-{
- class SupportedArchList
- {
- public:
- SupportedArchList()
- {
- AddArch(ArchSpec("i686-pc-windows"));
- AddArch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
- AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind32));
- AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind64));
- AddArch(ArchSpec("i386-pc-windows"));
- }
-
- size_t Count() const { return m_archs.size(); }
-
- const ArchSpec& operator[](int idx) { return m_archs[idx]; }
-
- private:
- void AddArch(const ArchSpec& spec)
- {
- auto iter = std::find_if(
- m_archs.begin(), m_archs.end(),
- [spec](const ArchSpec& rhs) { return spec.IsExactMatch(rhs); });
- if (iter != m_archs.end())
- return;
- if (spec.IsValid())
- m_archs.push_back(spec);
- }
-
- std::vector<ArchSpec> m_archs;
- };
+namespace {
+class SupportedArchList {
+public:
+ SupportedArchList() {
+ AddArch(ArchSpec("i686-pc-windows"));
+ AddArch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
+ AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind32));
+ AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind64));
+ AddArch(ArchSpec("i386-pc-windows"));
+ }
+
+ size_t Count() const { return m_archs.size(); }
+
+ const ArchSpec &operator[](int idx) { return m_archs[idx]; }
+
+private:
+ void AddArch(const ArchSpec &spec) {
+ auto iter = std::find_if(
+ m_archs.begin(), m_archs.end(),
+ [spec](const ArchSpec &rhs) { return spec.IsExactMatch(rhs); });
+ if (iter != m_archs.end())
+ return;
+ if (spec.IsValid())
+ m_archs.push_back(spec);
+ }
+
+ std::vector<ArchSpec> m_archs;
+};
} // anonymous namespace
-PlatformSP
-PlatformWindows::CreateInstance (bool force, const lldb_private::ArchSpec *arch)
-{
- // The only time we create an instance is when we are creating a remote
- // windows platform
- const bool is_host = false;
-
- bool create = force;
- if (create == false && arch && arch->IsValid())
- {
- const llvm::Triple &triple = arch->GetTriple();
- switch (triple.getVendor())
- {
- case llvm::Triple::PC:
- create = true;
- break;
+PlatformSP PlatformWindows::CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch) {
+ // The only time we create an instance is when we are creating a remote
+ // windows platform
+ const bool is_host = false;
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid()) {
+ const llvm::Triple &triple = arch->GetTriple();
+ switch (triple.getVendor()) {
+ case llvm::Triple::PC:
+ create = true;
+ break;
+
+ case llvm::Triple::UnknownArch:
+ create = !arch->TripleVendorWasSpecified();
+ break;
+
+ default:
+ break;
+ }
- case llvm::Triple::UnknownArch:
- create = !arch->TripleVendorWasSpecified();
- break;
+ if (create) {
+ switch (triple.getOS()) {
+ case llvm::Triple::Win32:
+ break;
- default:
- break;
- }
+ case llvm::Triple::UnknownOS:
+ create = arch->TripleOSWasSpecified();
+ break;
- if (create)
- {
- switch (triple.getOS())
- {
- case llvm::Triple::Win32:
- break;
-
- case llvm::Triple::UnknownOS:
- create = arch->TripleOSWasSpecified();
- break;
-
- default:
- create = false;
- break;
- }
- }
+ default:
+ create = false;
+ break;
+ }
}
- if (create)
- return PlatformSP(new PlatformWindows (is_host));
- return PlatformSP();
+ }
+ if (create)
+ return PlatformSP(new PlatformWindows(is_host));
+ return PlatformSP();
}
-lldb_private::ConstString
-PlatformWindows::GetPluginNameStatic(bool is_host)
-{
- if (is_host)
- {
- static ConstString g_host_name(Platform::GetHostPlatformName ());
- return g_host_name;
- }
- else
- {
- static ConstString g_remote_name("remote-windows");
- return g_remote_name;
- }
+lldb_private::ConstString PlatformWindows::GetPluginNameStatic(bool is_host) {
+ if (is_host) {
+ static ConstString g_host_name(Platform::GetHostPlatformName());
+ return g_host_name;
+ } else {
+ static ConstString g_remote_name("remote-windows");
+ return g_remote_name;
+ }
}
-const char *
-PlatformWindows::GetPluginDescriptionStatic(bool is_host)
-{
- return is_host ?
- "Local Windows user platform plug-in." :
- "Remote Windows user platform plug-in.";
+const char *PlatformWindows::GetPluginDescriptionStatic(bool is_host) {
+ return is_host ? "Local Windows user platform plug-in."
+ : "Remote Windows user platform plug-in.";
}
-lldb_private::ConstString
-PlatformWindows::GetPluginName()
-{
- return GetPluginNameStatic(IsHost());
+lldb_private::ConstString PlatformWindows::GetPluginName() {
+ return GetPluginNameStatic(IsHost());
}
-void
-PlatformWindows::Initialize()
-{
- Platform::Initialize ();
-
- if (g_initialize_count++ == 0)
- {
-#if defined (_WIN32)
- WSADATA dummy;
- WSAStartup(MAKEWORD(2,2), &dummy);
- // Force a host flag to true for the default platform object.
- PlatformSP default_platform_sp (new PlatformWindows(true));
- default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
- Platform::SetHostPlatform (default_platform_sp);
+void PlatformWindows::Initialize() {
+ Platform::Initialize();
+
+ if (g_initialize_count++ == 0) {
+#if defined(_WIN32)
+ WSADATA dummy;
+ WSAStartup(MAKEWORD(2, 2), &dummy);
+ // Force a host flag to true for the default platform object.
+ PlatformSP default_platform_sp(new PlatformWindows(true));
+ default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+ Platform::SetHostPlatform(default_platform_sp);
#endif
- PluginManager::RegisterPlugin(PlatformWindows::GetPluginNameStatic(false),
- PlatformWindows::GetPluginDescriptionStatic(false),
- PlatformWindows::CreateInstance);
- }
+ PluginManager::RegisterPlugin(
+ PlatformWindows::GetPluginNameStatic(false),
+ PlatformWindows::GetPluginDescriptionStatic(false),
+ PlatformWindows::CreateInstance);
+ }
}
-void
-PlatformWindows::Terminate( void )
-{
- if (g_initialize_count > 0)
- {
- if (--g_initialize_count == 0)
- {
+void PlatformWindows::Terminate(void) {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
#ifdef _WIN32
- WSACleanup();
+ WSACleanup();
#endif
- PluginManager::UnregisterPlugin (PlatformWindows::CreateInstance);
- }
+ PluginManager::UnregisterPlugin(PlatformWindows::CreateInstance);
}
+ }
- Platform::Terminate ();
+ Platform::Terminate();
}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformWindows::PlatformWindows (bool is_host) :
- Platform(is_host)
-{
-}
+PlatformWindows::PlatformWindows(bool is_host) : Platform(is_host) {}
//------------------------------------------------------------------
/// Destructor.
@@ -198,520 +170,438 @@ PlatformWindows::PlatformWindows (bool is_host) :
//------------------------------------------------------------------
PlatformWindows::~PlatformWindows() = default;
-bool
-PlatformWindows::GetModuleSpec (const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
+bool PlatformWindows::GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch,
+ ModuleSpec &module_spec) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
+ module_spec);
- return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
+ return Platform::GetModuleSpec(module_file_spec, arch, module_spec);
}
-Error
-PlatformWindows::ResolveExecutable (const ModuleSpec &ms,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec(ms);
-
- if (IsHost())
- {
- // if we cant resolve the executable loation based on the current path variables
- if (!resolved_module_spec.GetFileSpec().Exists())
- {
- resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
- }
+Error PlatformWindows::ResolveExecutable(
+ const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ char exe_path[PATH_MAX];
+ ModuleSpec resolved_module_spec(ms);
+
+ if (IsHost()) {
+ // if we cant resolve the executable loation based on the current path
+ // variables
+ if (!resolved_module_spec.GetFileSpec().Exists()) {
+ resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+ resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
+ }
- if (!resolved_module_spec.GetFileSpec().Exists())
- resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();
+ if (!resolved_module_spec.GetFileSpec().Exists())
+ resolved_module_spec.GetFileSpec().ResolveExecutableLocation();
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- {
- ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
- }
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else {
+ ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+ error.SetErrorStringWithFormat("unable to find executable for '%s'",
+ exe_path);
}
- else
- {
- if (m_remote_platform_sp)
- {
- error = GetCachedExecutable (resolved_module_spec, exe_module_sp, nullptr, *m_remote_platform_sp);
- }
- else
- {
- // We may connect to a process and use the provided executable (Don't use local $PATH).
- if (resolved_module_spec.GetFileSpec().Exists())
- error.Clear();
- else
- error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
- }
+ } else {
+ if (m_remote_platform_sp) {
+ error = GetCachedExecutable(resolved_module_spec, exe_module_sp, nullptr,
+ *m_remote_platform_sp);
+ } else {
+ // We may connect to a process and use the provided executable (Don't use
+ // local $PATH).
+ if (resolved_module_spec.GetFileSpec().Exists())
+ error.Clear();
+ else
+ error.SetErrorStringWithFormat("the platform is not currently "
+ "connected, and '%s' doesn't exist in "
+ "the system root.",
+ exe_path);
}
-
- if (error.Success())
- {
- if (resolved_module_spec.GetArchitecture().IsValid())
- {
- error = ModuleList::GetSharedModule(resolved_module_spec,
- exe_module_sp,
- nullptr,
- nullptr,
- nullptr);
-
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == nullptr)
- {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
+ }
+
+ if (error.Success()) {
+ if (resolved_module_spec.GetArchitecture().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ nullptr, nullptr, nullptr);
+
+ if (!exe_module_sp || exe_module_sp->GetObjectFile() == nullptr) {
+ exe_module_sp.reset();
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain the architecture %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+ } else {
+ // No valid architecture was specified, ask the platform for
+ // the architectures that we should be using (in the correct order)
+ // and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ nullptr, nullptr, nullptr);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
}
- else
- {
- // No valid architecture was specified, ask the platform for
- // the architectures that we should be using (in the correct order)
- // and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule(resolved_module_spec,
- exe_module_sp,
- nullptr,
- nullptr,
- nullptr);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
}
+ }
}
+ }
- return error;
+ return error;
}
-bool
-PlatformWindows::GetRemoteOSVersion ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetOSVersion (m_major_os_version,
- m_minor_os_version,
- m_update_os_version);
- return false;
+bool PlatformWindows::GetRemoteOSVersion() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetOSVersion(
+ m_major_os_version, m_minor_os_version, m_update_os_version);
+ return false;
}
-bool
-PlatformWindows::GetRemoteOSBuildString (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSBuildString (s);
- s.clear();
- return false;
+bool PlatformWindows::GetRemoteOSBuildString(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSBuildString(s);
+ s.clear();
+ return false;
}
-bool
-PlatformWindows::GetRemoteOSKernelDescription (std::string &s)
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteOSKernelDescription (s);
- s.clear();
- return false;
+bool PlatformWindows::GetRemoteOSKernelDescription(std::string &s) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
+ s.clear();
+ return false;
}
// Remote Platform subclasses need to override this function
-ArchSpec
-PlatformWindows::GetRemoteSystemArchitecture ()
-{
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetRemoteSystemArchitecture ();
- return ArchSpec();
+ArchSpec PlatformWindows::GetRemoteSystemArchitecture() {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetRemoteSystemArchitecture();
+ return ArchSpec();
}
-const char *
-PlatformWindows::GetHostname ()
-{
- if (IsHost())
- return Platform::GetHostname();
+const char *PlatformWindows::GetHostname() {
+ if (IsHost())
+ return Platform::GetHostname();
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetHostname ();
- return nullptr;
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetHostname();
+ return nullptr;
}
-bool
-PlatformWindows::IsConnected () const
-{
- if (IsHost())
- return true;
- else if (m_remote_platform_sp)
- return m_remote_platform_sp->IsConnected();
- return false;
+bool PlatformWindows::IsConnected() const {
+ if (IsHost())
+ return true;
+ else if (m_remote_platform_sp)
+ return m_remote_platform_sp->IsConnected();
+ return false;
}
-Error
-PlatformWindows::ConnectRemote (Args& args)
-{
- Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().AsCString() );
- }
- else
- {
- if (!m_remote_platform_sp)
- m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error);
-
- if (m_remote_platform_sp)
- {
- if (error.Success())
- {
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->ConnectRemote (args);
- }
- else
- {
- error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
- }
- }
+Error PlatformWindows::ConnectRemote(Args &args) {
+ Error error;
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't connect to the host platform '%s', always connected",
+ GetPluginName().AsCString());
+ } else {
+ if (!m_remote_platform_sp)
+ m_remote_platform_sp =
+ Platform::Create(ConstString("remote-gdb-server"), error);
+
+ if (m_remote_platform_sp) {
+ if (error.Success()) {
+ if (m_remote_platform_sp) {
+ error = m_remote_platform_sp->ConnectRemote(args);
+ } else {
+ error.SetErrorString(
+ "\"platform connect\" takes a single argument: <connect-url>");
}
- else
- error.SetErrorString ("failed to create a 'remote-gdb-server' platform");
+ }
+ } else
+ error.SetErrorString("failed to create a 'remote-gdb-server' platform");
- if (error.Fail())
- m_remote_platform_sp.reset();
- }
+ if (error.Fail())
+ m_remote_platform_sp.reset();
+ }
- return error;
+ return error;
}
-Error
-PlatformWindows::DisconnectRemote ()
-{
- Error error;
+Error PlatformWindows::DisconnectRemote() {
+ Error error;
- if (IsHost())
- {
- error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().AsCString() );
- }
+ if (IsHost()) {
+ error.SetErrorStringWithFormat(
+ "can't disconnect from the host platform '%s', always connected",
+ GetPluginName().AsCString());
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->DisconnectRemote();
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->DisconnectRemote ();
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-bool
-PlatformWindows::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- bool success = false;
- if (IsHost())
- {
- success = Platform::GetProcessInfo (pid, process_info);
- }
- else if (m_remote_platform_sp)
- {
- success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
- }
- return success;
+bool PlatformWindows::GetProcessInfo(lldb::pid_t pid,
+ ProcessInstanceInfo &process_info) {
+ bool success = false;
+ if (IsHost()) {
+ success = Platform::GetProcessInfo(pid, process_info);
+ } else if (m_remote_platform_sp) {
+ success = m_remote_platform_sp->GetProcessInfo(pid, process_info);
+ }
+ return success;
}
uint32_t
-PlatformWindows::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- uint32_t match_count = 0;
- if (IsHost())
- {
- // Let the base class figure out the host details
- match_count = Platform::FindProcesses (match_info, process_infos);
- }
- else
- {
- // If we are remote, we can only return results if we are connected
- if (m_remote_platform_sp)
- match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
- }
- return match_count;
+PlatformWindows::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ uint32_t match_count = 0;
+ if (IsHost()) {
+ // Let the base class figure out the host details
+ match_count = Platform::FindProcesses(match_info, process_infos);
+ } else {
+ // If we are remote, we can only return results if we are connected
+ if (m_remote_platform_sp)
+ match_count =
+ m_remote_platform_sp->FindProcesses(match_info, process_infos);
+ }
+ return match_count;
}
-Error
-PlatformWindows::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Error error;
- if (IsHost())
- {
- error = Platform::LaunchProcess (launch_info);
- }
+Error PlatformWindows::LaunchProcess(ProcessLaunchInfo &launch_info) {
+ Error error;
+ if (IsHost()) {
+ error = Platform::LaunchProcess(launch_info);
+ } else {
+ if (m_remote_platform_sp)
+ error = m_remote_platform_sp->LaunchProcess(launch_info);
else
- {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->LaunchProcess (launch_info);
- else
- error.SetErrorString ("the platform is not currently connected");
- }
- return error;
+ error.SetErrorString("the platform is not currently connected");
+ }
+ return error;
}
-ProcessSP
-PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target *target, Error &error)
-{
- // Windows has special considerations that must be followed when launching or attaching to a process. The
- // key requirement is that when launching or attaching to a process, you must do it from the same the thread
- // that will go into a permanent loop which will then receive debug events from the process. In particular,
- // this means we can't use any of LLDB's generic mechanisms to do it for us, because it doesn't have the
- // special knowledge required for setting up the background thread or passing the right flags.
- //
- // Another problem is that that LLDB's standard model for debugging a process is to first launch it, have
- // it stop at the entry point, and then attach to it. In Windows this doesn't quite work, you have to
- // specify as an argument to CreateProcess() that you're going to debug the process. So we override DebugProcess
- // here to handle this. Launch operations go directly to the process plugin, and attach operations almost go
- // directly to the process plugin (but we hijack the events first). In essence, we encapsulate all the logic
- // of Launching and Attaching in the process plugin, and PlatformWindows::DebugProcess is just a pass-through
- // to get to the process plugin.
-
- if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- {
- // This is a process attach. Don't need to launch anything.
- 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);
-
- // We need to launch and attach to the process.
- launch_info.GetFlags().Set(eLaunchFlagDebug);
- if (process_sp)
- error = process_sp->Launch(launch_info);
+ProcessSP PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger, Target *target,
+ Error &error) {
+ // Windows has special considerations that must be followed when launching or
+ // attaching to a process. The
+ // key requirement is that when launching or attaching to a process, you must
+ // do it from the same the thread
+ // that will go into a permanent loop which will then receive debug events
+ // from the process. In particular,
+ // this means we can't use any of LLDB's generic mechanisms to do it for us,
+ // because it doesn't have the
+ // special knowledge required for setting up the background thread or passing
+ // the right flags.
+ //
+ // Another problem is that that LLDB's standard model for debugging a process
+ // is to first launch it, have
+ // it stop at the entry point, and then attach to it. In Windows this doesn't
+ // quite work, you have to
+ // specify as an argument to CreateProcess() that you're going to debug the
+ // process. So we override DebugProcess
+ // here to handle this. Launch operations go directly to the process plugin,
+ // and attach operations almost go
+ // directly to the process plugin (but we hijack the events first). In
+ // essence, we encapsulate all the logic
+ // of Launching and Attaching in the process plugin, and
+ // PlatformWindows::DebugProcess is just a pass-through
+ // to get to the process plugin.
+
+ if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
+ // This is a process attach. Don't need to launch anything.
+ 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);
+
+ // We need to launch and attach to the process.
+ launch_info.GetFlags().Set(eLaunchFlagDebug);
+ if (process_sp)
+ error = process_sp->Launch(launch_info);
- return process_sp;
- }
+ return process_sp;
+ }
}
-lldb::ProcessSP
-PlatformWindows::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target,
- Error &error)
-{
- error.Clear();
- lldb::ProcessSP process_sp;
- if (!IsHost())
- {
- if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
- else
- error.SetErrorString ("the platform is not currently connected");
- return process_sp;
- }
+lldb::ProcessSP PlatformWindows::Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger, Target *target,
+ Error &error) {
+ error.Clear();
+ lldb::ProcessSP process_sp;
+ if (!IsHost()) {
+ if (m_remote_platform_sp)
+ process_sp =
+ m_remote_platform_sp->Attach(attach_info, debugger, target, error);
+ else
+ error.SetErrorString("the platform is not currently connected");
+ return process_sp;
+ }
- if (target == nullptr)
- {
- TargetSP new_target_sp;
- FileSpec emptyFileSpec;
- ArchSpec emptyArchSpec;
-
- error = debugger.GetTargetList().CreateTarget(debugger,
- nullptr,
- nullptr,
- false,
- nullptr,
- new_target_sp);
- target = new_target_sp.get();
- }
+ if (target == nullptr) {
+ TargetSP new_target_sp;
+ FileSpec emptyFileSpec;
+ ArchSpec emptyArchSpec;
- if (!target || error.Fail())
- return process_sp;
+ error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
+ nullptr, new_target_sp);
+ target = new_target_sp.get();
+ }
- debugger.GetTargetList().SetSelectedTarget(target);
+ if (!target || error.Fail())
+ return process_sp;
- const char *plugin_name = attach_info.GetProcessPluginName();
- process_sp = target->CreateProcess(attach_info.GetListenerForProcess(debugger), plugin_name, nullptr);
+ debugger.GetTargetList().SetSelectedTarget(target);
- process_sp->HijackProcessEvents(attach_info.GetHijackListener());
- if (process_sp)
- error = process_sp->Attach (attach_info);
+ const char *plugin_name = attach_info.GetProcessPluginName();
+ process_sp = target->CreateProcess(
+ attach_info.GetListenerForProcess(debugger), plugin_name, nullptr);
- return process_sp;
-}
+ process_sp->HijackProcessEvents(attach_info.GetHijackListener());
+ if (process_sp)
+ error = process_sp->Attach(attach_info);
-const char *
-PlatformWindows::GetUserName (uint32_t uid)
-{
- // Check the cache in Platform in case we have already looked this uid up
- const char *user_name = Platform::GetUserName(uid);
- if (user_name)
- return user_name;
-
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetUserName(uid);
- return nullptr;
+ return process_sp;
}
-const char *
-PlatformWindows::GetGroupName (uint32_t gid)
-{
- const char *group_name = Platform::GetGroupName(gid);
- if (group_name)
- return group_name;
+const char *PlatformWindows::GetUserName(uint32_t uid) {
+ // Check the cache in Platform in case we have already looked this uid up
+ const char *user_name = Platform::GetUserName(uid);
+ if (user_name)
+ return user_name;
- if (IsRemote() && m_remote_platform_sp)
- return m_remote_platform_sp->GetGroupName(gid);
- return nullptr;
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetUserName(uid);
+ return nullptr;
}
-Error
-PlatformWindows::GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
- }
+const char *PlatformWindows::GetGroupName(uint32_t gid) {
+ const char *group_name = Platform::GetGroupName(gid);
+ if (group_name)
+ return group_name;
- // Default to the local case
- local_file = platform_file;
- return Error();
+ if (IsRemote() && m_remote_platform_sp)
+ return m_remote_platform_sp->GetGroupName(gid);
+ return nullptr;
}
-Error
-PlatformWindows::GetSharedModule (const ModuleSpec &module_spec,
- Process* process,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- Error error;
- module_sp.reset();
-
- if (IsRemote())
- {
- // If we have a remote platform always, let it try and locate
- // the shared module first.
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
- }
- }
+Error PlatformWindows::GetFileWithUUID(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ if (IsRemote()) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
+ local_file);
+ }
- if (!module_sp)
- {
- // Fall back to the local platform and find the file locally
- error = Platform::GetSharedModule (module_spec,
- process,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr);
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
+}
+
+Error PlatformWindows::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ Error error;
+ module_sp.reset();
+
+ if (IsRemote()) {
+ // If we have a remote platform always, let it try and locate
+ // the shared module first.
+ if (m_remote_platform_sp) {
+ error = m_remote_platform_sp->GetSharedModule(
+ module_spec, process, module_sp, module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
}
- if (module_sp)
- module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
- return error;
+ }
+
+ if (!module_sp) {
+ // Fall back to the local platform and find the file locally
+ error = Platform::GetSharedModule(module_spec, process, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
+ return error;
}
-bool
-PlatformWindows::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- static SupportedArchList architectures;
+bool PlatformWindows::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ static SupportedArchList architectures;
- if (idx >= architectures.Count())
- return false;
- arch = architectures[idx];
- return true;
+ if (idx >= architectures.Count())
+ return false;
+ arch = architectures[idx];
+ return true;
}
-void
-PlatformWindows::GetStatus (Stream &strm)
-{
- Platform::GetStatus(strm);
+void PlatformWindows::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
#ifdef _WIN32
- uint32_t major;
- uint32_t minor;
- uint32_t update;
- if (!HostInfo::GetOSVersion(major, minor, update))
- {
- strm << "Windows";
- return;
- }
-
- strm << "Host: Windows " << major
- << '.' << minor
- << " Build: " << update << '\n';
+ uint32_t major;
+ uint32_t minor;
+ uint32_t update;
+ if (!HostInfo::GetOSVersion(major, minor, update)) {
+ strm << "Windows";
+ return;
+ }
+
+ strm << "Host: Windows " << major << '.' << minor << " Build: " << update
+ << '\n';
#endif
}
-bool
-PlatformWindows::CanDebugProcess()
-{
- return true;
-}
+bool PlatformWindows::CanDebugProcess() { return true; }
-size_t
-PlatformWindows::GetEnvironment(StringList &env)
-{
- if (IsRemote())
- {
- if (m_remote_platform_sp)
- return m_remote_platform_sp->GetEnvironment(env);
- return 0;
- }
+size_t PlatformWindows::GetEnvironment(StringList &env) {
+ if (IsRemote()) {
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->GetEnvironment(env);
+ return 0;
+ }
- return Host::GetEnvironment(env);
+ return Host::GetEnvironment(env);
}
-ConstString
-PlatformWindows::GetFullNameForDylib (ConstString basename)
-{
- if (basename.IsEmpty())
- return basename;
-
- StreamString stream;
- stream.Printf("%s.dll", basename.GetCString());
- return ConstString(stream.GetData());
+ConstString PlatformWindows::GetFullNameForDylib(ConstString basename) {
+ if (basename.IsEmpty())
+ return basename;
+
+ StreamString stream;
+ stream.Printf("%s.dll", basename.GetCString());
+ return ConstString(stream.GetString());
}
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.h b/source/Plugins/Platform/Windows/PlatformWindows.h
index 6af178bb8c26..375d5c5dad2f 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.h
+++ b/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -16,148 +16,119 @@
// Project includes
#include "lldb/Target/Platform.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class PlatformWindows : public Platform
-{
+class PlatformWindows : public Platform {
public:
- PlatformWindows(bool is_host);
+ PlatformWindows(bool is_host);
- ~PlatformWindows() override;
+ ~PlatformWindows() override;
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- static lldb::PlatformSP
- CreateInstance (bool force, const lldb_private::ArchSpec *arch);
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch);
- static lldb_private::ConstString
- GetPluginNameStatic(bool is_host);
+ static lldb_private::ConstString GetPluginNameStatic(bool is_host);
- static const char *
- GetPluginDescriptionStatic(bool is_host);
+ static const char *GetPluginDescriptionStatic(bool is_host);
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
+ uint32_t GetPluginVersion() override { return 1; }
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- bool
- GetModuleSpec (const lldb_private::FileSpec& module_file_spec,
- const lldb_private::ArchSpec& arch,
- lldb_private::ModuleSpec &module_spec) override;
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ bool GetModuleSpec(const lldb_private::FileSpec &module_file_spec,
+ const lldb_private::ArchSpec &arch,
+ lldb_private::ModuleSpec &module_spec) override;
- Error
- ResolveExecutable(const lldb_private::ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr) override;
+ Error ResolveExecutable(const lldb_private::ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr) override;
- const char *
- GetDescription() override
- {
- return GetPluginDescriptionStatic(IsHost());
- }
+ const char *GetDescription() override {
+ return GetPluginDescriptionStatic(IsHost());
+ }
- bool
- GetRemoteOSVersion() override;
+ bool GetRemoteOSVersion() override;
- bool
- GetRemoteOSBuildString(std::string &s) override;
+ bool GetRemoteOSBuildString(std::string &s) override;
- bool
- GetRemoteOSKernelDescription(std::string &s) override;
+ bool GetRemoteOSKernelDescription(std::string &s) override;
- // Remote Platform subclasses need to override this function
- lldb_private::ArchSpec
- GetRemoteSystemArchitecture() override;
+ // Remote Platform subclasses need to override this function
+ lldb_private::ArchSpec GetRemoteSystemArchitecture() override;
- bool
- IsConnected() const override;
+ bool IsConnected() const override;
- lldb_private::Error
- ConnectRemote(lldb_private::Args& args) override;
+ lldb_private::Error ConnectRemote(lldb_private::Args &args) override;
- lldb_private::Error
- DisconnectRemote() override;
+ lldb_private::Error DisconnectRemote() override;
- const char *
- GetHostname() override;
+ const char *GetHostname() override;
- const char *
- GetUserName(uint32_t uid) override;
+ const char *GetUserName(uint32_t uid) override;
- const char *
- GetGroupName(uint32_t gid) override;
+ const char *GetGroupName(uint32_t gid) override;
- bool
- GetProcessInfo(lldb::pid_t pid,
- lldb_private::ProcessInstanceInfo &proc_info) override;
+ bool GetProcessInfo(lldb::pid_t pid,
+ lldb_private::ProcessInstanceInfo &proc_info) override;
- uint32_t
- FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
- lldb_private::ProcessInstanceInfoList &process_infos) override;
+ uint32_t
+ FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info,
+ lldb_private::ProcessInstanceInfoList &process_infos) override;
- lldb_private::Error
- LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
+ lldb_private::Error
+ LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) override;
- lldb::ProcessSP
- DebugProcess(lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Debugger &debugger,
- lldb_private::Target *target, lldb_private::Error &error) override;
+ lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
- lldb::ProcessSP
- Attach(lldb_private::ProcessAttachInfo &attach_info, lldb_private::Debugger &debugger,
- lldb_private::Target *target, lldb_private::Error &error) override;
+ lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
- lldb_private::Error
- GetFileWithUUID(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID* uuid, lldb_private::FileSpec &local_file) override;
+ lldb_private::Error
+ GetFileWithUUID(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid,
+ lldb_private::FileSpec &local_file) override;
- lldb_private::Error
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process* process,
- lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
- bool
- GetSupportedArchitectureAtIndex(uint32_t idx, lldb_private::ArchSpec &arch) override;
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
- void
- GetStatus(lldb_private::Stream &strm) override;
+ void GetStatus(lldb_private::Stream &strm) override;
- bool CanDebugProcess() override;
+ bool CanDebugProcess() override;
- size_t GetEnvironment(StringList &env) override;
+ size_t GetEnvironment(StringList &env) override;
- // FIXME not sure what the _sigtramp equivalent would be on this platform
- void
- CalculateTrapHandlerSymbolNames () override
- {
- }
-
- ConstString
- GetFullNameForDylib (ConstString basename) override;
+ // FIXME not sure what the _sigtramp equivalent would be on this platform
+ void CalculateTrapHandlerSymbolNames() override {}
+
+ ConstString GetFullNameForDylib(ConstString basename) override;
protected:
- lldb::PlatformSP m_remote_platform_sp;
+ lldb::PlatformSP m_remote_platform_sp;
private:
- DISALLOW_COPY_AND_ASSIGN (PlatformWindows);
+ DISALLOW_COPY_AND_ASSIGN(PlatformWindows);
};
} // namespace lldb_private
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index e64ed66be3ca..43f7a53d0f7c 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -41,200 +41,170 @@ using namespace lldb_private::platform_gdb_server;
static bool g_initialized = false;
-void
-PlatformRemoteGDBServer::Initialize ()
-{
- Platform::Initialize ();
-
- if (g_initialized == false)
- {
- g_initialized = true;
- PluginManager::RegisterPlugin (PlatformRemoteGDBServer::GetPluginNameStatic(),
- PlatformRemoteGDBServer::GetDescriptionStatic(),
- PlatformRemoteGDBServer::CreateInstance);
- }
+void PlatformRemoteGDBServer::Initialize() {
+ Platform::Initialize();
+
+ if (g_initialized == false) {
+ g_initialized = true;
+ PluginManager::RegisterPlugin(
+ PlatformRemoteGDBServer::GetPluginNameStatic(),
+ PlatformRemoteGDBServer::GetDescriptionStatic(),
+ PlatformRemoteGDBServer::CreateInstance);
+ }
}
-void
-PlatformRemoteGDBServer::Terminate ()
-{
- if (g_initialized)
- {
- g_initialized = false;
- PluginManager::UnregisterPlugin (PlatformRemoteGDBServer::CreateInstance);
- }
+void PlatformRemoteGDBServer::Terminate() {
+ if (g_initialized) {
+ g_initialized = false;
+ PluginManager::UnregisterPlugin(PlatformRemoteGDBServer::CreateInstance);
+ }
- Platform::Terminate ();
+ Platform::Terminate();
}
-PlatformSP
-PlatformRemoteGDBServer::CreateInstance (bool force, const ArchSpec *arch)
-{
- bool create = force;
- if (!create)
- {
- create = !arch->TripleVendorWasSpecified() && !arch->TripleOSWasSpecified();
- }
- if (create)
- return PlatformSP(new PlatformRemoteGDBServer());
- return PlatformSP();
+PlatformSP PlatformRemoteGDBServer::CreateInstance(bool force,
+ const ArchSpec *arch) {
+ bool create = force;
+ if (!create) {
+ create = !arch->TripleVendorWasSpecified() && !arch->TripleOSWasSpecified();
+ }
+ if (create)
+ return PlatformSP(new PlatformRemoteGDBServer());
+ return PlatformSP();
}
-
-ConstString
-PlatformRemoteGDBServer::GetPluginNameStatic()
-{
- static ConstString g_name("remote-gdb-server");
- return g_name;
+ConstString PlatformRemoteGDBServer::GetPluginNameStatic() {
+ static ConstString g_name("remote-gdb-server");
+ return g_name;
}
-const char *
-PlatformRemoteGDBServer::GetDescriptionStatic()
-{
- return "A platform that uses the GDB remote protocol as the communication transport.";
+const char *PlatformRemoteGDBServer::GetDescriptionStatic() {
+ return "A platform that uses the GDB remote protocol as the communication "
+ "transport.";
}
-const char *
-PlatformRemoteGDBServer::GetDescription ()
-{
- if (m_platform_description.empty())
- {
- if (IsConnected())
- {
- // Send the get description packet
- }
+const char *PlatformRemoteGDBServer::GetDescription() {
+ if (m_platform_description.empty()) {
+ if (IsConnected()) {
+ // Send the get description packet
}
-
- if (!m_platform_description.empty())
- return m_platform_description.c_str();
- return GetDescriptionStatic();
+ }
+
+ if (!m_platform_description.empty())
+ return m_platform_description.c_str();
+ return GetDescriptionStatic();
}
-Error
-PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr)
-{
- // copied from PlatformRemoteiOS
-
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(module_spec);
-
- // Resolve any executable within an apk on Android?
- //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists() ||
- module_spec.GetUUID().IsValid())
- {
- if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact arch wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
- {
- error = ModuleList::GetSharedModule (resolved_module_spec,
- exe_module_sp,
- module_search_paths_ptr,
- NULL,
- NULL);
- // Did we find an executable using one of the
- if (error.Success())
- {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
+Error PlatformRemoteGDBServer::ResolveExecutable(
+ const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ // copied from PlatformRemoteiOS
- if (idx > 0)
- arch_names.PutCString (", ");
- arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
- if (error.Fail() || !exe_module_sp)
- {
- if (resolved_module_spec.GetFileSpec().Readable())
- {
- error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(),
- arch_names.GetString().c_str());
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
+ ModuleSpec resolved_module_spec(module_spec);
+
+ // Resolve any executable within an apk on Android?
+ // Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists() ||
+ module_spec.GetUUID().IsValid()) {
+ if (resolved_module_spec.GetArchitecture().IsValid() ||
+ resolved_module_spec.GetUUID().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
}
- else
- {
- error.SetErrorStringWithFormat ("'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
+ // No valid architecture was specified or the exact arch wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
}
- return error;
-}
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' does not exist",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
-bool
-PlatformRemoteGDBServer::GetModuleSpec (const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec)
-{
- Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+ return error;
+}
- const auto module_path = module_file_spec.GetPath (false);
+bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch,
+ ModuleSpec &module_spec) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (!m_gdb_client.GetModuleInfo (module_file_spec, arch, module_spec))
- {
- if (log)
- log->Printf ("PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
- __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str ());
- return false;
- }
+ const auto module_path = module_file_spec.GetPath(false);
+ if (!m_gdb_client.GetModuleInfo(module_file_spec, arch, module_spec)) {
if (log)
- {
- StreamString stream;
- module_spec.Dump (stream);
- log->Printf ("PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
- __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ());
- }
+ log->Printf(
+ "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
+ __FUNCTION__, module_path.c_str(),
+ arch.GetTriple().getTriple().c_str());
+ return false;
+ }
- return true;
+ if (log) {
+ StreamString stream;
+ module_spec.Dump(stream);
+ log->Printf(
+ "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
+ __FUNCTION__, module_path.c_str(), arch.GetTriple().getTriple().c_str(),
+ stream.GetData());
+ }
+
+ return true;
}
-Error
-PlatformRemoteGDBServer::GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file)
-{
- // Default to the local case
- local_file = platform_file;
- return Error();
+Error PlatformRemoteGDBServer::GetFileWithUUID(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
}
//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
-PlatformRemoteGDBServer::PlatformRemoteGDBServer () :
- Platform (false), // This is a remote platform
- m_gdb_client ()
-{
-}
+PlatformRemoteGDBServer::PlatformRemoteGDBServer()
+ : Platform(false), // This is a remote platform
+ m_gdb_client() {}
//------------------------------------------------------------------
/// Destructor.
@@ -242,793 +212,680 @@ PlatformRemoteGDBServer::PlatformRemoteGDBServer () :
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
-PlatformRemoteGDBServer::~PlatformRemoteGDBServer()
-{
-}
-
-bool
-PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
-{
- ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
-
- if (idx == 0)
- {
- arch = remote_arch;
- return arch.IsValid();
- }
- else if (idx == 1 && remote_arch.IsValid() && remote_arch.GetTriple().isArch64Bit())
- {
- arch.SetTriple(remote_arch.GetTriple().get32BitArchVariant());
- return arch.IsValid();
- }
- return false;
-}
-
-size_t
-PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
-{
- // This isn't needed if the z/Z packets are supported in the GDB remote
- // server. But we might need a packet to detect this.
- return 0;
-}
-
-bool
-PlatformRemoteGDBServer::GetRemoteOSVersion ()
-{
- uint32_t major, minor, update;
- if (m_gdb_client.GetOSVersion (major, minor, update))
- {
- m_major_os_version = major;
- m_minor_os_version = minor;
- m_update_os_version = update;
- return true;
- }
- return false;
+PlatformRemoteGDBServer::~PlatformRemoteGDBServer() {}
+
+bool PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
+
+ if (idx == 0) {
+ arch = remote_arch;
+ return arch.IsValid();
+ } else if (idx == 1 && remote_arch.IsValid() &&
+ remote_arch.GetTriple().isArch64Bit()) {
+ arch.SetTriple(remote_arch.GetTriple().get32BitArchVariant());
+ return arch.IsValid();
+ }
+ return false;
+}
+
+size_t PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode(
+ Target &target, BreakpointSite *bp_site) {
+ // This isn't needed if the z/Z packets are supported in the GDB remote
+ // server. But we might need a packet to detect this.
+ return 0;
+}
+
+bool PlatformRemoteGDBServer::GetRemoteOSVersion() {
+ uint32_t major, minor, update;
+ if (m_gdb_client.GetOSVersion(major, minor, update)) {
+ m_major_os_version = major;
+ m_minor_os_version = minor;
+ m_update_os_version = update;
+ return true;
+ }
+ return false;
}
-bool
-PlatformRemoteGDBServer::GetRemoteOSBuildString (std::string &s)
-{
- return m_gdb_client.GetOSBuildString (s);
+bool PlatformRemoteGDBServer::GetRemoteOSBuildString(std::string &s) {
+ return m_gdb_client.GetOSBuildString(s);
}
-bool
-PlatformRemoteGDBServer::GetRemoteOSKernelDescription (std::string &s)
-{
- return m_gdb_client.GetOSKernelDescription (s);
+bool PlatformRemoteGDBServer::GetRemoteOSKernelDescription(std::string &s) {
+ return m_gdb_client.GetOSKernelDescription(s);
}
// Remote Platform subclasses need to override this function
-ArchSpec
-PlatformRemoteGDBServer::GetRemoteSystemArchitecture ()
-{
- return m_gdb_client.GetSystemArchitecture();
-}
-
-FileSpec
-PlatformRemoteGDBServer::GetRemoteWorkingDirectory()
-{
- if (IsConnected())
- {
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- FileSpec working_dir;
- if (m_gdb_client.GetWorkingDir(working_dir) && log)
- log->Printf("PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
- working_dir.GetCString());
- return working_dir;
- }
- else
- {
- return Platform::GetRemoteWorkingDirectory();
- }
-}
-
-bool
-PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const FileSpec &working_dir)
-{
- if (IsConnected())
- {
- // Clear the working directory it case it doesn't get set correctly. This will
- // for use to re-read it
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
- working_dir.GetCString());
- return m_gdb_client.SetWorkingDir(working_dir) == 0;
- }
- else
- return Platform::SetRemoteWorkingDirectory(working_dir);
+ArchSpec PlatformRemoteGDBServer::GetRemoteSystemArchitecture() {
+ return m_gdb_client.GetSystemArchitecture();
}
-bool
-PlatformRemoteGDBServer::IsConnected () const
-{
- return m_gdb_client.IsConnected();
-}
-
-Error
-PlatformRemoteGDBServer::ConnectRemote (Args& args)
-{
- Error error;
- if (IsConnected())
- {
- error.SetErrorStringWithFormat ("the platform is already connected to '%s', execute 'platform disconnect' to close the current connection",
- GetHostname());
- }
- else
- {
- if (args.GetArgumentCount() == 1)
- {
- m_gdb_client.SetConnection(new ConnectionFileDescriptor());
- // we're going to reuse the hostname when we connect to the debugserver
- int port;
- std::string path;
- const char *url = args.GetArgumentAtIndex(0);
- if (!url)
- return Error("URL is null.");
- if (!UriParser::Parse(url, m_platform_scheme, m_platform_hostname, port, path))
- return Error("Invalid URL: %s", url);
-
- const ConnectionStatus status = m_gdb_client.Connect(url, &error);
- if (status == eConnectionStatusSuccess)
- {
- if (m_gdb_client.HandshakeWithServer(&error))
- {
- m_gdb_client.GetHostInfo();
- // If a working directory was set prior to connecting, send it down now
- if (m_working_dir)
- m_gdb_client.SetWorkingDir(m_working_dir);
- }
- else
- {
- m_gdb_client.Disconnect();
- if (error.Success())
- error.SetErrorString("handshake failed");
- }
- }
- }
- else
- {
- error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
+FileSpec PlatformRemoteGDBServer::GetRemoteWorkingDirectory() {
+ if (IsConnected()) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ FileSpec working_dir;
+ if (m_gdb_client.GetWorkingDir(working_dir) && log)
+ log->Printf(
+ "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
+ working_dir.GetCString());
+ return working_dir;
+ } else {
+ return Platform::GetRemoteWorkingDirectory();
+ }
+}
+
+bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory(
+ const FileSpec &working_dir) {
+ if (IsConnected()) {
+ // Clear the working directory it case it doesn't get set correctly. This
+ // will
+ // for use to re-read it
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
+ working_dir.GetCString());
+ return m_gdb_client.SetWorkingDir(working_dir) == 0;
+ } else
+ return Platform::SetRemoteWorkingDirectory(working_dir);
+}
+
+bool PlatformRemoteGDBServer::IsConnected() const {
+ return m_gdb_client.IsConnected();
+}
+
+Error PlatformRemoteGDBServer::ConnectRemote(Args &args) {
+ Error error;
+ if (IsConnected()) {
+ error.SetErrorStringWithFormat("the platform is already connected to '%s', "
+ "execute 'platform disconnect' to close the "
+ "current connection",
+ GetHostname());
+ } else {
+ if (args.GetArgumentCount() == 1) {
+ m_gdb_client.SetConnection(new ConnectionFileDescriptor());
+ // we're going to reuse the hostname when we connect to the debugserver
+ int port;
+ std::string path;
+ const char *url = args.GetArgumentAtIndex(0);
+ if (!url)
+ return Error("URL is null.");
+ llvm::StringRef scheme, hostname, pathname;
+ if (!UriParser::Parse(url, scheme, hostname, port, pathname))
+ return Error("Invalid URL: %s", url);
+ m_platform_scheme = scheme;
+ m_platform_hostname = hostname;
+ path = pathname;
+
+ const ConnectionStatus status = m_gdb_client.Connect(url, &error);
+ if (status == eConnectionStatusSuccess) {
+ if (m_gdb_client.HandshakeWithServer(&error)) {
+ m_gdb_client.GetHostInfo();
+ // If a working directory was set prior to connecting, send it down
+ // now
+ if (m_working_dir)
+ m_gdb_client.SetWorkingDir(m_working_dir);
+ } else {
+ m_gdb_client.Disconnect();
+ if (error.Success())
+ error.SetErrorString("handshake failed");
}
+ }
+ } else {
+ error.SetErrorString(
+ "\"platform connect\" takes a single argument: <connect-url>");
}
- return error;
+ }
+ return error;
}
-Error
-PlatformRemoteGDBServer::DisconnectRemote ()
-{
- Error error;
- m_gdb_client.Disconnect(&error);
- m_remote_signals_sp.reset();
- return error;
+Error PlatformRemoteGDBServer::DisconnectRemote() {
+ Error error;
+ m_gdb_client.Disconnect(&error);
+ m_remote_signals_sp.reset();
+ return error;
}
-const char *
-PlatformRemoteGDBServer::GetHostname ()
-{
- m_gdb_client.GetHostname (m_name);
- if (m_name.empty())
- return NULL;
- return m_name.c_str();
-}
-
-const char *
-PlatformRemoteGDBServer::GetUserName (uint32_t uid)
-{
- // Try and get a cache user name first
- const char *cached_user_name = Platform::GetUserName(uid);
- if (cached_user_name)
- return cached_user_name;
- std::string name;
- if (m_gdb_client.GetUserName(uid, name))
- return SetCachedUserName(uid, name.c_str(), name.size());
-
- SetUserNameNotFound(uid); // Negative cache so we don't keep sending packets
+const char *PlatformRemoteGDBServer::GetHostname() {
+ m_gdb_client.GetHostname(m_name);
+ if (m_name.empty())
return NULL;
-}
-
-const char *
-PlatformRemoteGDBServer::GetGroupName (uint32_t gid)
-{
- const char *cached_group_name = Platform::GetGroupName(gid);
- if (cached_group_name)
- return cached_group_name;
- std::string name;
- if (m_gdb_client.GetGroupName(gid, name))
- return SetCachedGroupName(gid, name.c_str(), name.size());
-
- SetGroupNameNotFound(gid); // Negative cache so we don't keep sending packets
- return NULL;
-}
-
-uint32_t
-PlatformRemoteGDBServer::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- return m_gdb_client.FindProcesses (match_info, process_infos);
-}
-
-bool
-PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- return m_gdb_client.GetProcessInfo (pid, process_info);
-}
-
-
-Error
-PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
- Error error;
-
- if (log)
- log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
-
- auto num_file_actions = launch_info.GetNumFileActions ();
- for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i)
- {
- const auto file_action = launch_info.GetFileActionAtIndex (i);
- if (file_action->GetAction () != FileAction::eFileActionOpen)
- continue;
- switch(file_action->GetFD())
- {
- case STDIN_FILENO:
- m_gdb_client.SetSTDIN(file_action->GetFileSpec());
- break;
- case STDOUT_FILENO:
- m_gdb_client.SetSTDOUT(file_action->GetFileSpec());
- break;
- case STDERR_FILENO:
- m_gdb_client.SetSTDERR(file_action->GetFileSpec());
- break;
- }
+ return m_name.c_str();
+}
+
+const char *PlatformRemoteGDBServer::GetUserName(uint32_t uid) {
+ // Try and get a cache user name first
+ const char *cached_user_name = Platform::GetUserName(uid);
+ if (cached_user_name)
+ return cached_user_name;
+ std::string name;
+ if (m_gdb_client.GetUserName(uid, name))
+ return SetCachedUserName(uid, name.c_str(), name.size());
+
+ SetUserNameNotFound(uid); // Negative cache so we don't keep sending packets
+ return NULL;
+}
+
+const char *PlatformRemoteGDBServer::GetGroupName(uint32_t gid) {
+ const char *cached_group_name = Platform::GetGroupName(gid);
+ if (cached_group_name)
+ return cached_group_name;
+ std::string name;
+ if (m_gdb_client.GetGroupName(gid, name))
+ return SetCachedGroupName(gid, name.c_str(), name.size());
+
+ SetGroupNameNotFound(gid); // Negative cache so we don't keep sending packets
+ return NULL;
+}
+
+uint32_t PlatformRemoteGDBServer::FindProcesses(
+ const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ return m_gdb_client.FindProcesses(match_info, process_infos);
+}
+
+bool PlatformRemoteGDBServer::GetProcessInfo(
+ lldb::pid_t pid, ProcessInstanceInfo &process_info) {
+ return m_gdb_client.GetProcessInfo(pid, process_info);
+}
+
+Error PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ Error error;
+
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
+
+ auto num_file_actions = launch_info.GetNumFileActions();
+ for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) {
+ const auto file_action = launch_info.GetFileActionAtIndex(i);
+ if (file_action->GetAction() != FileAction::eFileActionOpen)
+ continue;
+ switch (file_action->GetFD()) {
+ case STDIN_FILENO:
+ m_gdb_client.SetSTDIN(file_action->GetFileSpec());
+ break;
+ case STDOUT_FILENO:
+ m_gdb_client.SetSTDOUT(file_action->GetFileSpec());
+ break;
+ case STDERR_FILENO:
+ m_gdb_client.SetSTDERR(file_action->GetFileSpec());
+ break;
}
-
- m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
- m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError));
-
- FileSpec working_dir = launch_info.GetWorkingDirectory();
- if (working_dir)
- {
- m_gdb_client.SetWorkingDir(working_dir);
- }
-
- // Send the environment and the program + arguments after we connect
- const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
-
- if (envp)
- {
- const char *env_entry;
- for (int i=0; (env_entry = envp[i]); ++i)
- {
- if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0)
- break;
- }
+ }
+
+ m_gdb_client.SetDisableASLR(
+ launch_info.GetFlags().Test(eLaunchFlagDisableASLR));
+ m_gdb_client.SetDetachOnError(
+ launch_info.GetFlags().Test(eLaunchFlagDetachOnError));
+
+ FileSpec working_dir = launch_info.GetWorkingDirectory();
+ if (working_dir) {
+ m_gdb_client.SetWorkingDir(working_dir);
+ }
+
+ // Send the environment and the program + arguments after we connect
+ const char **envp =
+ launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+
+ if (envp) {
+ const char *env_entry;
+ for (int i = 0; (env_entry = envp[i]); ++i) {
+ if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0)
+ break;
}
-
- ArchSpec arch_spec = launch_info.GetArchitecture();
- const char *arch_triple = arch_spec.GetTriple().str().c_str();
-
- m_gdb_client.SendLaunchArchPacket(arch_triple);
- if (log)
- log->Printf ("PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
-
- int arg_packet_err;
- {
- // Scope for the scoped timeout object
- process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_client, 5);
- arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info);
+ }
+
+ ArchSpec arch_spec = launch_info.GetArchitecture();
+ const char *arch_triple = arch_spec.GetTriple().str().c_str();
+
+ m_gdb_client.SendLaunchArchPacket(arch_triple);
+ if (log)
+ log->Printf(
+ "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
+ __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
+
+ int arg_packet_err;
+ {
+ // Scope for the scoped timeout object
+ process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(
+ m_gdb_client, std::chrono::seconds(5));
+ arg_packet_err = m_gdb_client.SendArgumentsPacket(launch_info);
+ }
+
+ if (arg_packet_err == 0) {
+ std::string error_str;
+ if (m_gdb_client.GetLaunchSuccess(error_str)) {
+ const auto pid = m_gdb_client.GetCurrentProcessID(false);
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ launch_info.SetProcessID(pid);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::%s() pid %" PRIu64
+ " launched successfully",
+ __FUNCTION__, pid);
+ } else {
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::%s() launch succeeded but we "
+ "didn't get a valid process id back!",
+ __FUNCTION__);
+ error.SetErrorString("failed to get PID");
+ }
+ } else {
+ error.SetErrorString(error_str.c_str());
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::%s() launch failed: %s",
+ __FUNCTION__, error.AsCString());
}
-
- if (arg_packet_err == 0)
- {
- std::string error_str;
- if (m_gdb_client.GetLaunchSuccess (error_str))
- {
- const auto pid = m_gdb_client.GetCurrentProcessID (false);
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- launch_info.SetProcessID (pid);
- if (log)
- log->Printf ("PlatformRemoteGDBServer::%s() pid %" PRIu64 " launched successfully", __FUNCTION__, pid);
- }
- else
- {
- if (log)
- log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__);
- error.SetErrorString ("failed to get PID");
+ } else {
+ error.SetErrorStringWithFormat("'A' packet returned an error: %i",
+ arg_packet_err);
+ }
+ return error;
+}
+
+Error PlatformRemoteGDBServer::KillProcess(const lldb::pid_t pid) {
+ if (!KillSpawnedProcess(pid))
+ return Error("failed to kill remote spawned process");
+ return Error();
+}
+
+lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess(
+ ProcessLaunchInfo &launch_info, Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new target, else use
+ // existing one
+ Error &error) {
+ lldb::ProcessSP process_sp;
+ if (IsRemote()) {
+ if (IsConnected()) {
+ lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ std::string connect_url;
+ if (!LaunchGDBServer(debugserver_pid, connect_url)) {
+ error.SetErrorStringWithFormat("unable to launch a GDB server on '%s'",
+ GetHostname());
+ } else {
+ if (target == NULL) {
+ TargetSP new_target_sp;
+
+ error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
+ NULL, new_target_sp);
+ target = new_target_sp.get();
+ } else
+ error.Clear();
+
+ if (target && error.Success()) {
+ debugger.GetTargetList().SetSelectedTarget(target);
+
+ // 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);
+
+ if (process_sp) {
+ error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ // Retry the connect remote one time...
+ if (error.Fail())
+ error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ if (error.Success())
+ error = process_sp->Launch(launch_info);
+ else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+ printf("error: connect remote failed (%s)\n", error.AsCString());
+ KillSpawnedProcess(debugserver_pid);
}
+ }
}
- else
- {
- error.SetErrorString (error_str.c_str());
- if (log)
- log->Printf ("PlatformRemoteGDBServer::%s() launch failed: %s", __FUNCTION__, error.AsCString ());
- }
+ }
+ } else {
+ error.SetErrorString("not connected to remote gdb server");
}
- else
- {
- error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err);
- }
- return error;
-}
-
-Error
-PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid)
-{
- if (!KillSpawnedProcess(pid))
- return Error("failed to kill remote spawned process");
- return Error();
-}
+ }
+ return process_sp;
+}
+
+bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
+ std::string &connect_url) {
+ ArchSpec remote_arch = GetRemoteSystemArchitecture();
+ llvm::Triple &remote_triple = remote_arch.GetTriple();
+
+ uint16_t port = 0;
+ std::string socket_name;
+ bool launch_result = false;
+ if (remote_triple.getVendor() == llvm::Triple::Apple &&
+ remote_triple.getOS() == llvm::Triple::IOS) {
+ // When remote debugging to iOS, we use a USB mux that always talks
+ // to localhost, so we will need the remote debugserver to accept
+ // connections
+ // only from localhost, no matter what our current hostname is
+ launch_result =
+ m_gdb_client.LaunchGDBServer("127.0.0.1", pid, port, socket_name);
+ } else {
+ // All other hosts should use their actual hostname
+ launch_result =
+ m_gdb_client.LaunchGDBServer(nullptr, pid, port, socket_name);
+ }
+
+ if (!launch_result)
+ return false;
-lldb::ProcessSP
-PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info,
- Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
- Error &error)
-{
- lldb::ProcessSP process_sp;
- if (IsRemote())
- {
- if (IsConnected())
- {
- lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
- std::string connect_url;
- if (!LaunchGDBServer(debugserver_pid, connect_url))
- {
- error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
- }
- else
- {
- if (target == NULL)
- {
- TargetSP new_target_sp;
-
- error = debugger.GetTargetList().CreateTarget (debugger,
- NULL,
- NULL,
- false,
- NULL,
- new_target_sp);
- target = new_target_sp.get();
- }
- else
- error.Clear();
-
- if (target && error.Success())
- {
- debugger.GetTargetList().SetSelectedTarget(target);
-
- // 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);
-
- if (process_sp)
- {
- error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
- // Retry the connect remote one time...
- if (error.Fail())
- error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
- if (error.Success())
- error = process_sp->Launch(launch_info);
- else if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
- {
- printf ("error: connect remote failed (%s)\n", error.AsCString());
- KillSpawnedProcess(debugserver_pid);
- }
- }
- }
+ connect_url =
+ MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port,
+ (socket_name.empty()) ? nullptr : socket_name.c_str());
+ return true;
+}
+
+bool PlatformRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) {
+ return m_gdb_client.KillSpawnedProcess(pid);
+}
+
+lldb::ProcessSP PlatformRemoteGDBServer::Attach(
+ ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new target, else use
+ // existing one
+ Error &error) {
+ lldb::ProcessSP process_sp;
+ if (IsRemote()) {
+ if (IsConnected()) {
+ lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ std::string connect_url;
+ if (!LaunchGDBServer(debugserver_pid, connect_url)) {
+ error.SetErrorStringWithFormat("unable to launch a GDB server on '%s'",
+ GetHostname());
+ } else {
+ if (target == NULL) {
+ TargetSP new_target_sp;
+
+ error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
+ NULL, new_target_sp);
+ target = new_target_sp.get();
+ } else
+ error.Clear();
+
+ if (target && error.Success()) {
+ debugger.GetTargetList().SetSelectedTarget(target);
+
+ // The darwin always currently uses the GDB remote debugger plug-in
+ // so even when debugging locally we are debugging remotely!
+ process_sp = target->CreateProcess(
+ attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
+ if (process_sp) {
+ error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ if (error.Success()) {
+ ListenerSP listener_sp = attach_info.GetHijackListener();
+ if (listener_sp)
+ process_sp->HijackProcessEvents(listener_sp);
+ error = process_sp->Attach(attach_info);
}
- }
- else
- {
- error.SetErrorString("not connected to remote gdb server");
- }
- }
- return process_sp;
-}
-
-bool
-PlatformRemoteGDBServer::LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url)
-{
- ArchSpec remote_arch = GetRemoteSystemArchitecture ();
- llvm::Triple &remote_triple = remote_arch.GetTriple ();
-
- uint16_t port = 0;
- std::string socket_name;
- bool launch_result = false;
- if (remote_triple.getVendor () == llvm::Triple::Apple && remote_triple.getOS () == llvm::Triple::IOS)
- {
- // When remote debugging to iOS, we use a USB mux that always talks
- // to localhost, so we will need the remote debugserver to accept connections
- // only from localhost, no matter what our current hostname is
- launch_result = m_gdb_client.LaunchGDBServer ("127.0.0.1", pid, port, socket_name);
- }
- else
- {
- // All other hosts should use their actual hostname
- launch_result = m_gdb_client.LaunchGDBServer (nullptr, pid, port, socket_name);
- }
-
- if (!launch_result)
- return false;
-
- connect_url = MakeGdbServerUrl(m_platform_scheme,
- m_platform_hostname,
- port,
- (socket_name.empty()) ? nullptr : socket_name.c_str());
- return true;
-}
-
-bool
-PlatformRemoteGDBServer::KillSpawnedProcess (lldb::pid_t pid)
-{
- return m_gdb_client.KillSpawnedProcess (pid);
-}
-
-lldb::ProcessSP
-PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
- Error &error)
-{
- lldb::ProcessSP process_sp;
- if (IsRemote())
- {
- if (IsConnected())
- {
- lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
- std::string connect_url;
- if (!LaunchGDBServer(debugserver_pid, connect_url))
- {
- error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
+ if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+ KillSpawnedProcess(debugserver_pid);
}
- else
- {
- if (target == NULL)
- {
- TargetSP new_target_sp;
-
- error = debugger.GetTargetList().CreateTarget (debugger,
- NULL,
- NULL,
- false,
- NULL,
- new_target_sp);
- target = new_target_sp.get();
- }
- else
- error.Clear();
-
- if (target && error.Success())
- {
- debugger.GetTargetList().SetSelectedTarget(target);
-
- // The darwin always currently uses the GDB remote debugger plug-in
- // so even when debugging locally we are debugging remotely!
- process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
- if (process_sp)
- {
- error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
- if (error.Success())
- {
- ListenerSP listener_sp = attach_info.GetHijackListener();
- if (listener_sp)
- process_sp->HijackProcessEvents(listener_sp);
- error = process_sp->Attach(attach_info);
- }
-
- if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID)
- {
- KillSpawnedProcess(debugserver_pid);
- }
- }
- }
- }
- }
- else
- {
- error.SetErrorString("not connected to remote gdb server");
+ }
}
+ }
+ } else {
+ error.SetErrorString("not connected to remote gdb server");
}
- return process_sp;
+ }
+ return process_sp;
}
-Error
-PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, uint32_t mode)
-{
- Error error = m_gdb_client.MakeDirectory(file_spec, mode);
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)",
- file_spec.GetCString(), mode, error.GetError(), error.AsCString());
- return error;
+Error PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec,
+ uint32_t mode) {
+ Error error = m_gdb_client.MakeDirectory(file_spec, mode);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
+ "error = %u (%s)",
+ file_spec.GetCString(), mode, error.GetError(),
+ error.AsCString());
+ return error;
}
-
-Error
-PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
- uint32_t &file_permissions)
-{
- Error error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)",
- file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString());
- return error;
+Error PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions) {
+ Error error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
+ "file_permissions=%o) error = %u (%s)",
+ file_spec.GetCString(), file_permissions, error.GetError(),
+ error.AsCString());
+ return error;
}
-Error
-PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
- uint32_t file_permissions)
-{
- Error error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)",
- file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString());
- return error;
+Error PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
+ uint32_t file_permissions) {
+ Error error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
+ "file_permissions=%o) error = %u (%s)",
+ file_spec.GetCString(), file_permissions, error.GetError(),
+ error.AsCString());
+ return error;
}
-
-lldb::user_id_t
-PlatformRemoteGDBServer::OpenFile (const FileSpec& file_spec,
- uint32_t flags,
- uint32_t mode,
- Error &error)
-{
- return m_gdb_client.OpenFile (file_spec, flags, mode, error);
+lldb::user_id_t PlatformRemoteGDBServer::OpenFile(const FileSpec &file_spec,
+ uint32_t flags, uint32_t mode,
+ Error &error) {
+ return m_gdb_client.OpenFile(file_spec, flags, mode, error);
}
-bool
-PlatformRemoteGDBServer::CloseFile (lldb::user_id_t fd, Error &error)
-{
- return m_gdb_client.CloseFile (fd, error);
+bool PlatformRemoteGDBServer::CloseFile(lldb::user_id_t fd, Error &error) {
+ return m_gdb_client.CloseFile(fd, error);
}
lldb::user_id_t
-PlatformRemoteGDBServer::GetFileSize (const FileSpec& file_spec)
-{
- return m_gdb_client.GetFileSize(file_spec);
+PlatformRemoteGDBServer::GetFileSize(const FileSpec &file_spec) {
+ return m_gdb_client.GetFileSize(file_spec);
}
-uint64_t
-PlatformRemoteGDBServer::ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- Error &error)
-{
- return m_gdb_client.ReadFile (fd, offset, dst, dst_len, error);
+uint64_t PlatformRemoteGDBServer::ReadFile(lldb::user_id_t fd, uint64_t offset,
+ void *dst, uint64_t dst_len,
+ Error &error) {
+ return m_gdb_client.ReadFile(fd, offset, dst, dst_len, error);
}
-uint64_t
-PlatformRemoteGDBServer::WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- Error &error)
-{
- return m_gdb_client.WriteFile (fd, offset, src, src_len, error);
+uint64_t PlatformRemoteGDBServer::WriteFile(lldb::user_id_t fd, uint64_t offset,
+ const void *src, uint64_t src_len,
+ Error &error) {
+ return m_gdb_client.WriteFile(fd, offset, src, src_len, error);
}
-Error
-PlatformRemoteGDBServer::PutFile (const FileSpec& source,
- const FileSpec& destination,
- uint32_t uid,
- uint32_t gid)
-{
- return Platform::PutFile(source,destination,uid,gid);
+Error PlatformRemoteGDBServer::PutFile(const FileSpec &source,
+ const FileSpec &destination,
+ uint32_t uid, uint32_t gid) {
+ return Platform::PutFile(source, destination, uid, gid);
}
-Error
-PlatformRemoteGDBServer::CreateSymlink(const FileSpec &src, // The name of the link is in src
- const FileSpec &dst) // The symlink points to dst
+Error PlatformRemoteGDBServer::CreateSymlink(
+ const FileSpec &src, // The name of the link is in src
+ const FileSpec &dst) // The symlink points to dst
{
- Error error = m_gdb_client.CreateSymlink(src, dst);
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)",
- src.GetCString(), dst.GetCString(), error.GetError(), error.AsCString());
- return error;
+ Error error = m_gdb_client.CreateSymlink(src, dst);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
+ "error = %u (%s)",
+ src.GetCString(), dst.GetCString(), error.GetError(),
+ error.AsCString());
+ return error;
}
-Error
-PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec)
-{
- Error error = m_gdb_client.Unlink(file_spec);
- Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
+Error PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) {
+ Error error = m_gdb_client.Unlink(file_spec);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
file_spec.GetCString(), error.GetError(), error.AsCString());
- return error;
+ return error;
}
-bool
-PlatformRemoteGDBServer::GetFileExists (const FileSpec& file_spec)
-{
- return m_gdb_client.GetFileExists (file_spec);
+bool PlatformRemoteGDBServer::GetFileExists(const FileSpec &file_spec) {
+ return m_gdb_client.GetFileExists(file_spec);
}
-Error
-PlatformRemoteGDBServer::RunShellCommand(const char *command, // Shouldn't be NULL
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass NULL if you don't want the process exit status
- int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass NULL if you don't want the command output
- uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
+Error PlatformRemoteGDBServer::RunShellCommand(
+ const char *command, // Shouldn't be NULL
+ const FileSpec &
+ working_dir, // Pass empty FileSpec to use the current working directory
+ int *status_ptr, // Pass NULL if you don't want the process exit status
+ int *signo_ptr, // Pass NULL if you don't want the signal that caused the
+ // process to exit
+ std::string
+ *command_output, // Pass NULL if you don't want the command output
+ uint32_t
+ timeout_sec) // Timeout in seconds to wait for shell program to finish
{
- return m_gdb_client.RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
+ return m_gdb_client.RunShellCommand(command, working_dir, status_ptr,
+ signo_ptr, command_output, timeout_sec);
}
-void
-PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames ()
-{
- m_trap_handlers.push_back (ConstString ("_sigtramp"));
+void PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames() {
+ m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-const UnixSignalsSP &
-PlatformRemoteGDBServer::GetRemoteUnixSignals()
-{
- if (!IsConnected())
- return Platform::GetRemoteUnixSignals();
-
- if (m_remote_signals_sp)
- return m_remote_signals_sp;
-
- // If packet not implemented or JSON failed to parse,
- // we'll guess the signal set based on the remote architecture.
- m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture());
-
- const char packet[] = "jSignalsInfo";
- StringExtractorGDBRemote response;
- auto result = m_gdb_client.SendPacketAndWaitForResponse(
- packet, strlen(packet), response, false);
-
- if (result != decltype(result)::Success ||
- response.GetResponseType() != response.eResponse)
- return m_remote_signals_sp;
-
- auto object_sp = StructuredData::ParseJSON(response.GetStringRef());
- if (!object_sp || !object_sp->IsValid())
- return m_remote_signals_sp;
-
- auto array_sp = object_sp->GetAsArray();
- if (!array_sp || !array_sp->IsValid())
- return m_remote_signals_sp;
-
- auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>();
-
- bool done = array_sp->ForEach(
- [&remote_signals_sp](StructuredData::Object *object) -> bool
- {
- if (!object || !object->IsValid())
- return false;
-
- auto dict = object->GetAsDictionary();
- if (!dict || !dict->IsValid())
- return false;
-
- // Signal number and signal name are required.
- int signo;
- if (!dict->GetValueForKeyAsInteger("signo", signo))
- return false;
-
- std::string name;
- if (!dict->GetValueForKeyAsString("name", name))
- return false;
-
- // We can live without short_name, description, etc.
- bool suppress{false};
- auto object_sp = dict->GetValueForKey("suppress");
- if (object_sp && object_sp->IsValid())
- suppress = object_sp->GetBooleanValue();
-
- bool stop{false};
- object_sp = dict->GetValueForKey("stop");
- if (object_sp && object_sp->IsValid())
- stop = object_sp->GetBooleanValue();
-
- bool notify{false};
- object_sp = dict->GetValueForKey("notify");
- if (object_sp && object_sp->IsValid())
- notify = object_sp->GetBooleanValue();
-
- std::string description{""};
- object_sp = dict->GetValueForKey("description");
- if (object_sp && object_sp->IsValid())
- description = object_sp->GetStringValue();
-
- remote_signals_sp->AddSignal(signo,
- name.c_str(),
- suppress, stop, notify,
- description.c_str());
- return true;
- });
-
- if (done)
- m_remote_signals_sp = std::move(remote_signals_sp);
+const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
+ if (!IsConnected())
+ return Platform::GetRemoteUnixSignals();
+ if (m_remote_signals_sp)
return m_remote_signals_sp;
-}
-std::string
-PlatformRemoteGDBServer::MakeGdbServerUrl(const std::string &platform_scheme,
- const std::string &platform_hostname,
- uint16_t port,
- const char* socket_name)
-{
- const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
- const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
- const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
- int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
-
- return MakeUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
- override_hostname ? override_hostname : platform_hostname.c_str(),
- port + port_offset,
- socket_name);
-}
+ // If packet not implemented or JSON failed to parse,
+ // we'll guess the signal set based on the remote architecture.
+ m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture());
-std::string
-PlatformRemoteGDBServer::MakeUrl(const char* scheme,
- const char* hostname,
- uint16_t port,
- const char* path)
-{
- StreamString result;
- result.Printf("%s://%s", scheme, hostname);
- if (port != 0)
- result.Printf(":%u", port);
- if (path)
- result.Write(path, strlen(path));
- return result.GetString();
-}
+ StringExtractorGDBRemote response;
+ auto result = m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo",
+ response, false);
-lldb::ProcessSP
-PlatformRemoteGDBServer::ConnectProcess(const char* connect_url,
- const char* plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error)
-{
- if (!IsRemote() || !IsConnected())
- {
- error.SetErrorString("Not connected to remote gdb server");
- return nullptr;
- }
- return Platform::ConnectProcess(connect_url, plugin_name, debugger, target, error);
-}
+ if (result != decltype(result)::Success ||
+ response.GetResponseType() != response.eResponse)
+ return m_remote_signals_sp;
-size_t
-PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger& debugger, Error& error)
-{
- std::vector<std::string> connection_urls;
- GetPendingGdbServerList(connection_urls);
-
- for (size_t i = 0; i < connection_urls.size(); ++i)
- {
- ConnectProcess(connection_urls[i].c_str(), nullptr, debugger, nullptr, error);
- if (error.Fail())
- return i; // We already connected to i process succsessfully
- }
- return connection_urls.size();
+ auto object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ if (!object_sp || !object_sp->IsValid())
+ return m_remote_signals_sp;
-}
+ auto array_sp = object_sp->GetAsArray();
+ if (!array_sp || !array_sp->IsValid())
+ return m_remote_signals_sp;
-size_t
-PlatformRemoteGDBServer::GetPendingGdbServerList(std::vector<std::string>& connection_urls)
-{
- std::vector<std::pair<uint16_t, std::string>> remote_servers;
- m_gdb_client.QueryGDBServer(remote_servers);
- for (const auto& gdbserver : remote_servers)
- {
- const char* socket_name_cstr = gdbserver.second.empty() ? nullptr : gdbserver.second.c_str();
- connection_urls.emplace_back(MakeGdbServerUrl(m_platform_scheme,
- m_platform_hostname,
- gdbserver.first,
- socket_name_cstr));
- }
- return connection_urls.size();
+ auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>();
+
+ bool done = array_sp->ForEach(
+ [&remote_signals_sp](StructuredData::Object *object) -> bool {
+ if (!object || !object->IsValid())
+ return false;
+
+ auto dict = object->GetAsDictionary();
+ if (!dict || !dict->IsValid())
+ return false;
+
+ // Signal number and signal name are required.
+ int signo;
+ if (!dict->GetValueForKeyAsInteger("signo", signo))
+ return false;
+
+ std::string name;
+ if (!dict->GetValueForKeyAsString("name", name))
+ return false;
+
+ // We can live without short_name, description, etc.
+ bool suppress{false};
+ auto object_sp = dict->GetValueForKey("suppress");
+ if (object_sp && object_sp->IsValid())
+ suppress = object_sp->GetBooleanValue();
+
+ bool stop{false};
+ object_sp = dict->GetValueForKey("stop");
+ if (object_sp && object_sp->IsValid())
+ stop = object_sp->GetBooleanValue();
+
+ bool notify{false};
+ object_sp = dict->GetValueForKey("notify");
+ if (object_sp && object_sp->IsValid())
+ notify = object_sp->GetBooleanValue();
+
+ std::string description{""};
+ object_sp = dict->GetValueForKey("description");
+ if (object_sp && object_sp->IsValid())
+ description = object_sp->GetStringValue();
+
+ remote_signals_sp->AddSignal(signo, name.c_str(), suppress, stop,
+ notify, description.c_str());
+ return true;
+ });
+
+ if (done)
+ m_remote_signals_sp = std::move(remote_signals_sp);
+
+ return m_remote_signals_sp;
+}
+
+std::string PlatformRemoteGDBServer::MakeGdbServerUrl(
+ const std::string &platform_scheme, const std::string &platform_hostname,
+ uint16_t port, const char *socket_name) {
+ const char *override_scheme =
+ getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
+ const char *override_hostname =
+ getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
+ const char *port_offset_c_str =
+ getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
+ int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
+
+ return MakeUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
+ override_hostname ? override_hostname
+ : platform_hostname.c_str(),
+ port + port_offset, socket_name);
+}
+
+std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme,
+ const char *hostname,
+ uint16_t port, const char *path) {
+ StreamString result;
+ result.Printf("%s://%s", scheme, hostname);
+ if (port != 0)
+ result.Printf(":%u", port);
+ if (path)
+ result.Write(path, strlen(path));
+ return result.GetString();
+}
+
+lldb::ProcessSP PlatformRemoteGDBServer::ConnectProcess(
+ llvm::StringRef connect_url, llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger, lldb_private::Target *target,
+ lldb_private::Error &error) {
+ if (!IsRemote() || !IsConnected()) {
+ error.SetErrorString("Not connected to remote gdb server");
+ return nullptr;
+ }
+ return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
+ error);
+}
+
+size_t PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger &debugger,
+ Error &error) {
+ std::vector<std::string> connection_urls;
+ GetPendingGdbServerList(connection_urls);
+
+ for (size_t i = 0; i < connection_urls.size(); ++i) {
+ ConnectProcess(connection_urls[i].c_str(), "", debugger, nullptr, error);
+ if (error.Fail())
+ return i; // We already connected to i process succsessfully
+ }
+ return connection_urls.size();
+}
+
+size_t PlatformRemoteGDBServer::GetPendingGdbServerList(
+ std::vector<std::string> &connection_urls) {
+ std::vector<std::pair<uint16_t, std::string>> remote_servers;
+ m_gdb_client.QueryGDBServer(remote_servers);
+ for (const auto &gdbserver : remote_servers) {
+ const char *socket_name_cstr =
+ gdbserver.second.empty() ? nullptr : gdbserver.second.c_str();
+ connection_urls.emplace_back(
+ MakeGdbServerUrl(m_platform_scheme, m_platform_hostname,
+ gdbserver.first, socket_name_cstr));
+ }
+ return connection_urls.size();
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 9d640f3c174b..edc223a2d7fb 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -1,4 +1,5 @@
-//===-- PlatformRemoteGDBServer.h ----------------------------------------*- C++ -*-===//
+//===-- PlatformRemoteGDBServer.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,256 +17,194 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/Platform.h"
#include "../../Process/gdb-remote/GDBRemoteCommunicationClient.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
+#include "lldb/Target/Platform.h"
namespace lldb_private {
namespace platform_gdb_server {
-class PlatformRemoteGDBServer : public Platform
-{
+class PlatformRemoteGDBServer : public Platform {
public:
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetDescriptionStatic();
+
+ PlatformRemoteGDBServer();
+
+ virtual ~PlatformRemoteGDBServer();
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ ConstString GetPluginName() override { return GetPluginNameStatic(); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ Error ResolveExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr) override;
+
+ bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
+ ModuleSpec &module_spec) override;
+
+ const char *GetDescription() override;
+
+ Error GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid_ptr,
+ FileSpec &local_file) override;
+
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
+
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) override;
+
+ Error LaunchProcess(ProcessLaunchInfo &launch_info) override;
+
+ Error KillProcess(const lldb::pid_t pid) override;
+
+ lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a
+ // new target, else use existing
+ // one
+ Error &error) override;
+
+ lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new
+ // target, else use existing one
+ Error &error) override;
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
+
+ size_t GetSoftwareBreakpointTrapOpcode(Target &target,
+ BreakpointSite *bp_site) override;
+
+ bool GetRemoteOSVersion() override;
+
+ bool GetRemoteOSBuildString(std::string &s) override;
+
+ bool GetRemoteOSKernelDescription(std::string &s) override;
+
+ // Remote Platform subclasses need to override this function
+ ArchSpec GetRemoteSystemArchitecture() override;
- static void
- Initialize ();
-
- static void
- Terminate ();
-
- static lldb::PlatformSP
- CreateInstance (bool force, const ArchSpec *arch);
-
- static ConstString
- GetPluginNameStatic();
-
- static const char *
- GetDescriptionStatic();
-
-
- PlatformRemoteGDBServer ();
-
- virtual
- ~PlatformRemoteGDBServer();
-
- //------------------------------------------------------------
- // lldb_private::PluginInterface functions
- //------------------------------------------------------------
- ConstString
- GetPluginName() override
- {
- return GetPluginNameStatic();
- }
-
- uint32_t
- GetPluginVersion() override
- {
- return 1;
- }
-
-
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- Error
- ResolveExecutable (const ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr) override;
-
- bool
- GetModuleSpec (const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec) override;
-
- const char *
- GetDescription () override;
-
- Error
- GetFileWithUUID (const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) override;
-
- bool
- GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
-
- uint32_t
- FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) override;
-
- Error
- LaunchProcess (ProcessLaunchInfo &launch_info) override;
-
- Error
- KillProcess (const lldb::pid_t pid) override;
-
- lldb::ProcessSP
- DebugProcess (ProcessLaunchInfo &launch_info,
- Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
- Error &error) override;
-
- lldb::ProcessSP
- Attach (ProcessAttachInfo &attach_info,
- Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new target, else use existing one
- Error &error) override;
-
- bool
- GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) override;
-
- size_t
- GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) override;
-
- bool
- GetRemoteOSVersion () override;
-
- bool
- GetRemoteOSBuildString (std::string &s) override;
-
- bool
- GetRemoteOSKernelDescription (std::string &s) override;
-
- // Remote Platform subclasses need to override this function
- ArchSpec
- GetRemoteSystemArchitecture () override;
-
- FileSpec
- GetRemoteWorkingDirectory() override;
-
- bool
- SetRemoteWorkingDirectory(const FileSpec &working_dir) override;
-
- // Remote subclasses should override this and return a valid instance
- // name if connected.
- const char *
- GetHostname () override;
-
- const char *
- GetUserName (uint32_t uid) override;
-
- const char *
- GetGroupName (uint32_t gid) override;
-
- bool
- IsConnected () const override;
-
- Error
- ConnectRemote (Args& args) override;
-
- Error
- DisconnectRemote () override;
-
- Error
- MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions) override;
-
- Error
- GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) override;
-
- Error
- SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) override;
-
-
- lldb::user_id_t
- OpenFile (const FileSpec& file_spec, uint32_t flags, uint32_t mode, Error &error) override;
-
- bool
- CloseFile (lldb::user_id_t fd, Error &error) override;
-
- uint64_t
- ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *data_ptr,
- uint64_t len,
- Error &error) override;
-
- uint64_t
- WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* data,
- uint64_t len,
- Error &error) override;
-
- lldb::user_id_t
- GetFileSize (const FileSpec& file_spec) override;
-
- Error
- PutFile (const FileSpec& source,
- const FileSpec& destination,
- uint32_t uid = UINT32_MAX,
- uint32_t gid = UINT32_MAX) override;
-
- Error
- CreateSymlink(const FileSpec &src, const FileSpec &dst) override;
-
- bool
- GetFileExists (const FileSpec& file_spec) override;
-
- Error
- Unlink(const FileSpec &path) override;
-
- Error
- RunShellCommand(const char *command, // Shouldn't be NULL
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass NULL if you don't want the process exit status
- int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass NULL if you don't want the command output
- uint32_t timeout_sec) override; // Timeout in seconds to wait for shell program to finish
-
- void
- CalculateTrapHandlerSymbolNames () override;
-
- const lldb::UnixSignalsSP &
- GetRemoteUnixSignals() override;
-
- lldb::ProcessSP
- ConnectProcess (const char* connect_url,
- const char* plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Error &error) override;
-
- size_t
- ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
-
- virtual size_t
- GetPendingGdbServerList(std::vector<std::string>& connection_urls);
+ FileSpec GetRemoteWorkingDirectory() override;
+
+ bool SetRemoteWorkingDirectory(const FileSpec &working_dir) override;
+
+ // Remote subclasses should override this and return a valid instance
+ // name if connected.
+ const char *GetHostname() override;
+
+ const char *GetUserName(uint32_t uid) override;
+
+ const char *GetGroupName(uint32_t gid) override;
+
+ bool IsConnected() const override;
+
+ Error ConnectRemote(Args &args) override;
+
+ Error DisconnectRemote() override;
+
+ Error MakeDirectory(const FileSpec &file_spec,
+ uint32_t file_permissions) override;
+
+ Error GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions) override;
+
+ Error SetFilePermissions(const FileSpec &file_spec,
+ uint32_t file_permissions) override;
+
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ uint32_t mode, Error &error) override;
+
+ bool CloseFile(lldb::user_id_t fd, Error &error) override;
+
+ uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *data_ptr,
+ uint64_t len, Error &error) override;
+
+ uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *data,
+ uint64_t len, Error &error) override;
+
+ lldb::user_id_t GetFileSize(const FileSpec &file_spec) override;
+
+ Error PutFile(const FileSpec &source, const FileSpec &destination,
+ uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override;
+
+ Error CreateSymlink(const FileSpec &src, const FileSpec &dst) override;
+
+ bool GetFileExists(const FileSpec &file_spec) override;
+
+ Error Unlink(const FileSpec &path) override;
+
+ Error RunShellCommand(
+ const char *command, // Shouldn't be NULL
+ const FileSpec &working_dir, // Pass empty FileSpec to use the current
+ // working directory
+ int *status_ptr, // Pass NULL if you don't want the process exit status
+ int *signo_ptr, // Pass NULL if you don't want the signal that caused the
+ // process to exit
+ std::string
+ *command_output, // Pass NULL if you don't want the command output
+ uint32_t timeout_sec)
+ override; // Timeout in seconds to wait for shell program to finish
+
+ void CalculateTrapHandlerSymbolNames() override;
+
+ const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;
+
+ lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
+ llvm::StringRef plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
+
+ size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
+ lldb_private::Error &error) override;
+
+ virtual size_t
+ GetPendingGdbServerList(std::vector<std::string> &connection_urls);
protected:
- process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client;
- std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to
- std::string m_platform_scheme;
- std::string m_platform_hostname;
+ process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client;
+ std::string m_platform_description; // After we connect we can get a more
+ // complete description of what we are
+ // connected to
+ std::string m_platform_scheme;
+ std::string m_platform_hostname;
- lldb::UnixSignalsSP m_remote_signals_sp;
+ lldb::UnixSignalsSP m_remote_signals_sp;
- // Launch the debug server on the remote host - caller connects to launched
- // debug server using connect_url.
- // Subclasses should override this method if they want to do extra actions before or
- // after launching the debug server.
- virtual bool
- LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url);
+ // Launch the debug server on the remote host - caller connects to launched
+ // debug server using connect_url.
+ // Subclasses should override this method if they want to do extra actions
+ // before or
+ // after launching the debug server.
+ virtual bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url);
- virtual bool
- KillSpawnedProcess (lldb::pid_t pid);
+ virtual bool KillSpawnedProcess(lldb::pid_t pid);
- virtual std::string
- MakeUrl(const char* scheme,
- const char* hostname,
- uint16_t port,
- const char* path);
+ virtual std::string MakeUrl(const char *scheme, const char *hostname,
+ uint16_t port, const char *path);
private:
- std::string
- MakeGdbServerUrl(const std::string &platform_scheme,
- const std::string &platform_hostname,
- uint16_t port,
- const char* socket_name);
-
- DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
+ std::string MakeGdbServerUrl(const std::string &platform_scheme,
+ const std::string &platform_hostname,
+ uint16_t port, const char *socket_name);
+ DISALLOW_COPY_AND_ASSIGN(PlatformRemoteGDBServer);
};
} // namespace platform_gdb_server
} // namespace lldb_private
-#endif // liblldb_PlatformRemoteGDBServer_h_
+#endif // liblldb_PlatformRemoteGDBServer_h_
diff --git a/source/Plugins/Process/CMakeLists.txt b/source/Plugins/Process/CMakeLists.txt
index d15df94414b3..defa493088b6 100644
--- a/source/Plugins/Process/CMakeLists.txt
+++ b/source/Plugins/Process/CMakeLists.txt
@@ -7,8 +7,6 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
add_subdirectory(POSIX)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
- add_subdirectory(Windows/Live)
- add_subdirectory(Windows/MiniDump)
add_subdirectory(Windows/Common)
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_subdirectory(MacOSX-Kernel)
@@ -17,3 +15,4 @@ add_subdirectory(gdb-remote)
add_subdirectory(Utility)
add_subdirectory(mach-core)
add_subdirectory(elf-core)
+add_subdirectory(minidump)
diff --git a/source/Plugins/Process/Darwin/CFBundle.cpp b/source/Plugins/Process/Darwin/CFBundle.cpp
new file mode 100644
index 000000000000..7b080e60cdb3
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFBundle.cpp
@@ -0,0 +1,79 @@
+//===-- CFBundle.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CFBundle.h"
+#include "CFString.h"
+
+//----------------------------------------------------------------------
+// CFBundle constructor
+//----------------------------------------------------------------------
+CFBundle::CFBundle(const char *path)
+ : CFReleaser<CFBundleRef>(), m_bundle_url() {
+ if (path && path[0])
+ SetPath(path);
+}
+
+//----------------------------------------------------------------------
+// CFBundle copy constructor
+//----------------------------------------------------------------------
+CFBundle::CFBundle(const CFBundle &rhs)
+ : CFReleaser<CFBundleRef>(rhs), m_bundle_url(rhs.m_bundle_url) {}
+
+//----------------------------------------------------------------------
+// CFBundle copy constructor
+//----------------------------------------------------------------------
+CFBundle &CFBundle::operator=(const CFBundle &rhs) {
+ *this = rhs;
+ return *this;
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+CFBundle::~CFBundle() {}
+
+//----------------------------------------------------------------------
+// Set the path for a bundle by supplying a
+//----------------------------------------------------------------------
+bool CFBundle::SetPath(const char *path) {
+ CFAllocatorRef alloc = kCFAllocatorDefault;
+ // Release our old bundle and ULR
+ reset(); // This class is a CFReleaser<CFBundleRef>
+ m_bundle_url.reset();
+ // Make a CFStringRef from the supplied path
+ CFString cf_path;
+ cf_path.SetFileSystemRepresentation(path);
+ if (cf_path.get()) {
+ // Make our Bundle URL
+ m_bundle_url.reset(::CFURLCreateWithFileSystemPath(
+ alloc, cf_path.get(), kCFURLPOSIXPathStyle, true));
+ if (m_bundle_url.get()) {
+ reset(::CFBundleCreate(alloc, m_bundle_url.get()));
+ }
+ }
+ return get() != NULL;
+}
+
+CFStringRef CFBundle::GetIdentifier() const {
+ CFBundleRef bundle = get();
+ if (bundle != NULL)
+ return ::CFBundleGetIdentifier(bundle);
+ return NULL;
+}
+
+CFURLRef CFBundle::CopyExecutableURL() const {
+ CFBundleRef bundle = get();
+ if (bundle != NULL)
+ return CFBundleCopyExecutableURL(bundle);
+ return NULL;
+}
diff --git a/source/Plugins/Process/Darwin/CFBundle.h b/source/Plugins/Process/Darwin/CFBundle.h
new file mode 100644
index 000000000000..09957af534b3
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFBundle.h
@@ -0,0 +1,38 @@
+//===-- CFBundle.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CFBundle_h__
+#define __CFBundle_h__
+
+#include "CFUtils.h"
+
+class CFBundle : public CFReleaser<CFBundleRef> {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CFBundle(const char *path = NULL);
+ CFBundle(const CFBundle &rhs);
+ CFBundle &operator=(const CFBundle &rhs);
+ virtual ~CFBundle();
+ bool SetPath(const char *path);
+
+ CFStringRef GetIdentifier() const;
+
+ CFURLRef CopyExecutableURL() const;
+
+protected:
+ CFReleaser<CFURLRef> m_bundle_url;
+};
+
+#endif // #ifndef __CFBundle_h__
diff --git a/source/Plugins/Process/Darwin/CFString.cpp b/source/Plugins/Process/Darwin/CFString.cpp
new file mode 100644
index 000000000000..84ad56774d7c
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFString.cpp
@@ -0,0 +1,163 @@
+//===-- CFString.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CFString.h"
+#include <glob.h>
+#include <string>
+
+//----------------------------------------------------------------------
+// CFString constructor
+//----------------------------------------------------------------------
+CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}
+
+//----------------------------------------------------------------------
+// CFString copy constructor
+//----------------------------------------------------------------------
+CFString::CFString(const CFString &rhs) : CFReleaser<CFStringRef>(rhs) {}
+
+//----------------------------------------------------------------------
+// CFString copy constructor
+//----------------------------------------------------------------------
+CFString &CFString::operator=(const CFString &rhs) {
+ if (this != &rhs)
+ *this = rhs;
+ return *this;
+}
+
+CFString::CFString(const char *cstr, CFStringEncoding cstr_encoding)
+ : CFReleaser<CFStringRef>() {
+ if (cstr && cstr[0]) {
+ reset(
+ ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
+ }
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+CFString::~CFString() {}
+
+const char *CFString::GetFileSystemRepresentation(std::string &s) {
+ return CFString::FileSystemRepresentation(get(), s);
+}
+
+CFStringRef CFString::SetFileSystemRepresentation(const char *path) {
+ CFStringRef new_value = NULL;
+ if (path && path[0])
+ new_value =
+ ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
+ reset(new_value);
+ return get();
+}
+
+CFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
+ CFStringRef new_value = NULL;
+ if (cf_type != NULL) {
+ CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
+
+ if (cf_type_id == ::CFStringGetTypeID()) {
+ // Retain since we are using the existing object
+ new_value = (CFStringRef)::CFRetain(cf_type);
+ } else if (cf_type_id == ::CFURLGetTypeID()) {
+ new_value =
+ ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
+ }
+ }
+ reset(new_value);
+ return get();
+}
+
+CFStringRef
+CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
+ std::string expanded_path;
+ if (CFString::GlobPath(path, expanded_path))
+ SetFileSystemRepresentation(expanded_path.c_str());
+ else
+ reset();
+ return get();
+}
+
+const char *CFString::UTF8(std::string &str) {
+ return CFString::UTF8(get(), str);
+}
+
+// Static function that puts a copy of the UTF8 contents of CF_STR into STR
+// and returns the C string pointer that is contained in STR when successful,
+// else
+// NULL is returned. This allows the std::string parameter to own the extracted
+// string,
+// and also allows that string to be returned as a C string pointer that can be
+// used.
+
+const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
+ if (cf_str) {
+ const CFStringEncoding encoding = kCFStringEncodingUTF8;
+ CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
+ max_utf8_str_len =
+ CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
+ if (max_utf8_str_len > 0) {
+ str.resize(max_utf8_str_len);
+ if (!str.empty()) {
+ if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
+ str.resize(strlen(str.c_str()));
+ return str.c_str();
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+// Static function that puts a copy of the file system representation of CF_STR
+// into STR and returns the C string pointer that is contained in STR when
+// successful, else NULL is returned. This allows the std::string parameter
+// to own the extracted string, and also allows that string to be returned as
+// a C string pointer that can be used.
+
+const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
+ std::string &str) {
+ if (cf_str) {
+ CFIndex max_length =
+ ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
+ if (max_length > 0) {
+ str.resize(max_length);
+ if (!str.empty()) {
+ if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
+ str.size())) {
+ str.erase(::strlen(str.c_str()));
+ return str.c_str();
+ }
+ }
+ }
+ }
+ str.erase();
+ return NULL;
+}
+
+CFIndex CFString::GetLength() const {
+ CFStringRef str = get();
+ if (str)
+ return CFStringGetLength(str);
+ return 0;
+}
+
+const char *CFString::GlobPath(const char *path, std::string &expanded_path) {
+ glob_t globbuf;
+ if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
+ expanded_path = globbuf.gl_pathv[0];
+ ::globfree(&globbuf);
+ } else
+ expanded_path.clear();
+
+ return expanded_path.c_str();
+}
diff --git a/source/Plugins/Process/Darwin/CFString.h b/source/Plugins/Process/Darwin/CFString.h
new file mode 100644
index 000000000000..18d60a5a74bd
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFString.h
@@ -0,0 +1,43 @@
+//===-- CFString.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CFString_h__
+#define __CFString_h__
+
+#include "CFUtils.h"
+#include <iosfwd>
+
+class CFString : public CFReleaser<CFStringRef> {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CFString(CFStringRef cf_str = NULL);
+ CFString(const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8);
+ CFString(const CFString &rhs);
+ CFString &operator=(const CFString &rhs);
+ virtual ~CFString();
+
+ const char *GetFileSystemRepresentation(std::string &str);
+ CFStringRef SetFileSystemRepresentation(const char *path);
+ CFStringRef SetFileSystemRepresentationFromCFType(CFTypeRef cf_type);
+ CFStringRef SetFileSystemRepresentationAndExpandTilde(const char *path);
+ const char *UTF8(std::string &str);
+ CFIndex GetLength() const;
+ static const char *UTF8(CFStringRef cf_str, std::string &str);
+ static const char *FileSystemRepresentation(CFStringRef cf_str,
+ std::string &str);
+ static const char *GlobPath(const char *path, std::string &expanded_path);
+};
+
+#endif // #ifndef __CFString_h__
diff --git a/source/Plugins/Process/Darwin/CFUtils.h b/source/Plugins/Process/Darwin/CFUtils.h
new file mode 100644
index 000000000000..a904cd0ea6f0
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFUtils.h
@@ -0,0 +1,78 @@
+//===-- CFUtils.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 3/5/07.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CFUtils_h__
+#define __CFUtils_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#ifdef __cplusplus
+
+//----------------------------------------------------------------------
+// Templatized CF helper class that can own any CF pointer and will
+// call CFRelease() on any valid pointer it owns unless that pointer is
+// explicitly released using the release() member function.
+//----------------------------------------------------------------------
+template <class T> class CFReleaser {
+public:
+ // Type names for the avlue
+ typedef T element_type;
+
+ // Constructors and destructors
+ CFReleaser(T ptr = NULL) : _ptr(ptr) {}
+ CFReleaser(const CFReleaser &copy) : _ptr(copy.get()) {
+ if (get())
+ ::CFRetain(get());
+ }
+ virtual ~CFReleaser() { reset(); }
+
+ // Assignments
+ CFReleaser &operator=(const CFReleaser<T> &copy) {
+ if (copy != *this) {
+ // Replace our owned pointer with the new one
+ reset(copy.get());
+ // Retain the current pointer that we own
+ if (get())
+ ::CFRetain(get());
+ }
+ }
+ // Get the address of the contained type
+ T *ptr_address() { return &_ptr; }
+
+ // Access the pointer itself
+ const T get() const { return _ptr; }
+ T get() { return _ptr; }
+
+ // Set a new value for the pointer and CFRelease our old
+ // value if we had a valid one.
+ void reset(T ptr = NULL) {
+ if (ptr != _ptr) {
+ if (_ptr != NULL)
+ ::CFRelease(_ptr);
+ _ptr = ptr;
+ }
+ }
+
+ // Release ownership without calling CFRelease
+ T release() {
+ T tmp = _ptr;
+ _ptr = NULL;
+ return tmp;
+ }
+
+private:
+ element_type _ptr;
+};
+
+#endif // #ifdef __cplusplus
+#endif // #ifndef __CFUtils_h__
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
new file mode 100644
index 000000000000..63b1ae6da968
--- /dev/null
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -0,0 +1,653 @@
+//===-- DarwinProcessLauncher.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//
+// DarwinProcessLauncher.cpp
+// lldb
+//
+// Created by Todd Fiala on 8/30/16.
+//
+//
+
+#include "DarwinProcessLauncher.h"
+
+// C includes
+#include <spawn.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+
+#ifndef _POSIX_SPAWN_DISABLE_ASLR
+#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
+#endif
+
+// LLDB includes
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/PseudoTerminal.h"
+
+#include "CFBundle.h"
+#include "CFString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+using namespace lldb_private::darwin_process_launcher;
+
+namespace {
+static LaunchFlavor g_launch_flavor = LaunchFlavor::Default;
+}
+
+namespace lldb_private {
+namespace darwin_process_launcher {
+
+static uint32_t GetCPUTypeForLocalProcess(::pid_t pid) {
+ int mib[CTL_MAXNAME] = {
+ 0,
+ };
+ size_t len = CTL_MAXNAME;
+ if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
+ return 0;
+
+ mib[len] = pid;
+ len++;
+
+ cpu_type_t cpu;
+ size_t cpu_len = sizeof(cpu);
+ if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
+ cpu = 0;
+ return cpu;
+}
+
+static bool ResolveExecutablePath(const char *path, char *resolved_path,
+ size_t resolved_path_size) {
+ if (path == NULL || path[0] == '\0')
+ return false;
+
+ char max_path[PATH_MAX];
+ std::string result;
+ CFString::GlobPath(path, result);
+
+ if (result.empty())
+ result = path;
+
+ struct stat path_stat;
+ if (::stat(path, &path_stat) == 0) {
+ if ((path_stat.st_mode & S_IFMT) == S_IFDIR) {
+ CFBundle bundle(path);
+ CFReleaser<CFURLRef> url(bundle.CopyExecutableURL());
+ if (url.get()) {
+ if (::CFURLGetFileSystemRepresentation(
+ url.get(), true, (UInt8 *)resolved_path, resolved_path_size))
+ return true;
+ }
+ }
+ }
+
+ if (realpath(path, max_path)) {
+ // Found the path relatively...
+ ::strncpy(resolved_path, max_path, resolved_path_size);
+ return strlen(resolved_path) + 1 < resolved_path_size;
+ } else {
+ // Not a relative path, check the PATH environment variable if the
+ const char *PATH = getenv("PATH");
+ if (PATH) {
+ const char *curr_path_start = PATH;
+ const char *curr_path_end;
+ while (curr_path_start && *curr_path_start) {
+ curr_path_end = strchr(curr_path_start, ':');
+ if (curr_path_end == NULL) {
+ result.assign(curr_path_start);
+ curr_path_start = NULL;
+ } else if (curr_path_end > curr_path_start) {
+ size_t len = curr_path_end - curr_path_start;
+ result.assign(curr_path_start, len);
+ curr_path_start += len + 1;
+ } else
+ break;
+
+ result += '/';
+ result += path;
+ struct stat s;
+ if (stat(result.c_str(), &s) == 0) {
+ ::strncpy(resolved_path, result.c_str(), resolved_path_size);
+ return result.size() + 1 < resolved_path_size;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+// TODO check if we have a general purpose fork and exec. We may be
+// able to get rid of this entirely.
+static Error ForkChildForPTraceDebugging(const char *path, char const *argv[],
+ char const *envp[], ::pid_t *pid,
+ int *pty_fd) {
+ Error error;
+ if (!path || !argv || !envp || !pid || !pty_fd) {
+ error.SetErrorString("invalid arguments");
+ return error;
+ }
+
+ // Use a fork that ties the child process's stdin/out/err to a pseudo
+ // terminal so we can read it in our MachProcess::STDIOThread
+ // as unbuffered io.
+ lldb_utility::PseudoTerminal pty;
+ char fork_error[256];
+ memset(fork_error, 0, sizeof(fork_error));
+ *pid = static_cast<::pid_t>(pty.Fork(fork_error, sizeof(fork_error)));
+ if (*pid < 0) {
+ //--------------------------------------------------------------
+ // Error during fork.
+ //--------------------------------------------------------------
+ *pid = static_cast<::pid_t>(LLDB_INVALID_PROCESS_ID);
+ error.SetErrorStringWithFormat("%s(): fork failed: %s", __FUNCTION__,
+ fork_error);
+ return error;
+ } else if (pid == 0) {
+ //--------------------------------------------------------------
+ // Child process
+ //--------------------------------------------------------------
+
+ // Debug this process.
+ ::ptrace(PT_TRACE_ME, 0, 0, 0);
+
+ // Get BSD signals as mach exceptions.
+ ::ptrace(PT_SIGEXC, 0, 0, 0);
+
+ // If our parent is setgid, lets make sure we don't inherit those
+ // extra powers due to nepotism.
+ if (::setgid(getgid()) == 0) {
+ // Let the child have its own process group. We need to execute
+ // this call in both the child and parent to avoid a race
+ // condition between the two processes.
+
+ // Set the child process group to match its pid.
+ ::setpgid(0, 0);
+
+ // Sleep a bit to before the exec call.
+ ::sleep(1);
+
+ // Turn this process into the given executable.
+ ::execv(path, (char *const *)argv);
+ }
+ // Exit with error code. Child process should have taken
+ // over in above exec call and if the exec fails it will
+ // exit the child process below.
+ ::exit(127);
+ } else {
+ //--------------------------------------------------------------
+ // Parent process
+ //--------------------------------------------------------------
+ // Let the child have its own process group. We need to execute
+ // this call in both the child and parent to avoid a race condition
+ // between the two processes.
+
+ // Set the child process group to match its pid
+ ::setpgid(*pid, *pid);
+ if (pty_fd) {
+ // Release our master pty file descriptor so the pty class doesn't
+ // close it and so we can continue to use it in our STDIO thread
+ *pty_fd = pty.ReleaseMasterFileDescriptor();
+ }
+ }
+ return error;
+}
+
+static Error
+CreatePosixSpawnFileAction(const FileAction &action,
+ posix_spawn_file_actions_t *file_actions) {
+ Error error;
+
+ // Log it.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ StreamString stream;
+ stream.PutCString("converting file action for posix_spawn(): ");
+ action.Dump(stream);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ // Validate args.
+ if (!file_actions) {
+ error.SetErrorString("mandatory file_actions arg is null");
+ return error;
+ }
+
+ // Build the posix file action.
+ switch (action.GetAction()) {
+ case FileAction::eFileActionOpen: {
+ const int error_code = ::posix_spawn_file_actions_addopen(
+ file_actions, action.GetFD(), action.GetPath(),
+ action.GetActionArgument(), 0);
+ if (error_code != 0) {
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ break;
+ }
+
+ case FileAction::eFileActionClose: {
+ const int error_code =
+ ::posix_spawn_file_actions_addclose(file_actions, action.GetFD());
+ if (error_code != 0) {
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ break;
+ }
+
+ case FileAction::eFileActionDuplicate: {
+ const int error_code = ::posix_spawn_file_actions_adddup2(
+ file_actions, action.GetFD(), action.GetActionArgument());
+ if (error_code != 0) {
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ break;
+ }
+
+ case FileAction::eFileActionNone:
+ default:
+ if (log)
+ log->Printf("%s(): unsupported file action %u", __FUNCTION__,
+ action.GetAction());
+ break;
+ }
+
+ return error;
+}
+
+static Error PosixSpawnChildForPTraceDebugging(const char *path,
+ ProcessLaunchInfo &launch_info,
+ ::pid_t *pid,
+ cpu_type_t *actual_cpu_type) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!pid) {
+ error.SetErrorStringWithFormat("%s(): pid arg cannot be null",
+ __FUNCTION__);
+ return error;
+ }
+
+ posix_spawnattr_t attr;
+ short flags;
+ if (log) {
+ StreamString stream;
+ stream.Printf("%s(path='%s',...)\n", __FUNCTION__, path);
+ launch_info.Dump(stream, nullptr);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ int error_code;
+ if ((error_code = ::posix_spawnattr_init(&attr)) != 0) {
+ if (log)
+ log->Printf("::posix_spawnattr_init(&attr) failed");
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+ // Ensure we clean up the spawnattr structure however we exit this
+ // function.
+ std::unique_ptr<posix_spawnattr_t, int (*)(posix_spawnattr_t *)> spawnattr_up(
+ &attr, ::posix_spawnattr_destroy);
+
+ flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETSIGDEF |
+ POSIX_SPAWN_SETSIGMASK;
+ if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR))
+ flags |= _POSIX_SPAWN_DISABLE_ASLR;
+
+ sigset_t no_signals;
+ sigset_t all_signals;
+ sigemptyset(&no_signals);
+ sigfillset(&all_signals);
+ ::posix_spawnattr_setsigmask(&attr, &no_signals);
+ ::posix_spawnattr_setsigdefault(&attr, &all_signals);
+
+ if ((error_code = ::posix_spawnattr_setflags(&attr, flags)) != 0) {
+ if (log)
+ log->Printf("::posix_spawnattr_setflags(&attr, "
+ "POSIX_SPAWN_START_SUSPENDED%s) failed: %s",
+ flags & _POSIX_SPAWN_DISABLE_ASLR
+ ? " | _POSIX_SPAWN_DISABLE_ASLR"
+ : "",
+ strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+#if !defined(__arm__)
+
+ // We don't need to do this for ARM, and we really shouldn't now that we
+ // have multiple CPU subtypes and no posix_spawnattr call that allows us
+ // to set which CPU subtype to launch...
+ cpu_type_t desired_cpu_type = launch_info.GetArchitecture().GetMachOCPUType();
+ if (desired_cpu_type != LLDB_INVALID_CPUTYPE) {
+ size_t ocount = 0;
+ error_code =
+ ::posix_spawnattr_setbinpref_np(&attr, 1, &desired_cpu_type, &ocount);
+ if (error_code != 0) {
+ if (log)
+ log->Printf("::posix_spawnattr_setbinpref_np(&attr, 1, "
+ "cpu_type = 0x%8.8x, count => %llu): %s",
+ desired_cpu_type, (uint64_t)ocount, strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ if (ocount != 1) {
+ error.SetErrorStringWithFormat("posix_spawnattr_setbinpref_np "
+ "did not set the expected number "
+ "of cpu_type entries: expected 1 "
+ "but was %zu",
+ ocount);
+ return error;
+ }
+ }
+#endif
+
+ posix_spawn_file_actions_t file_actions;
+ if ((error_code = ::posix_spawn_file_actions_init(&file_actions)) != 0) {
+ if (log)
+ log->Printf("::posix_spawn_file_actions_init(&file_actions) "
+ "failed: %s",
+ strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+ // Ensure we clean up file actions however we exit this. When the
+ // file_actions_up below goes out of scope, we'll get our file action
+ // cleanup.
+ std::unique_ptr<posix_spawn_file_actions_t,
+ int (*)(posix_spawn_file_actions_t *)>
+ file_actions_up(&file_actions, ::posix_spawn_file_actions_destroy);
+
+ // We assume the caller has setup the file actions appropriately. We
+ // are not in the business of figuring out what we really need here.
+ // lldb-server will have already called FinalizeFileActions() as well
+ // to button these up properly.
+ const size_t num_actions = launch_info.GetNumFileActions();
+ for (size_t action_index = 0; action_index < num_actions; ++action_index) {
+ const FileAction *const action =
+ launch_info.GetFileActionAtIndex(action_index);
+ if (!action)
+ continue;
+
+ error = CreatePosixSpawnFileAction(*action, &file_actions);
+ if (!error.Success()) {
+ if (log)
+ log->Printf("%s(): error converting FileAction to posix_spawn "
+ "file action: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ }
+
+ // TODO: Verify if we can set the working directory back immediately
+ // after the posix_spawnp call without creating a race condition???
+ const char *const working_directory =
+ launch_info.GetWorkingDirectory().GetCString();
+ if (working_directory && working_directory[0])
+ ::chdir(working_directory);
+
+ auto argv = launch_info.GetArguments().GetArgumentVector();
+ auto envp = launch_info.GetEnvironmentEntries().GetArgumentVector();
+ error_code = ::posix_spawnp(pid, path, &file_actions, &attr,
+ (char *const *)argv, (char *const *)envp);
+ if (error_code != 0) {
+ if (log)
+ log->Printf("::posix_spawnp(pid => %p, path = '%s', file_actions "
+ "= %p, attr = %p, argv = %p, envp = %p) failed: %s",
+ pid, path, &file_actions, &attr, argv, envp,
+ strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+ // Validate we got a pid.
+ if (pid == LLDB_INVALID_PROCESS_ID) {
+ error.SetErrorString("posix_spawn() did not indicate a failure but it "
+ "failed to return a pid, aborting.");
+ return error;
+ }
+
+ if (actual_cpu_type) {
+ *actual_cpu_type = GetCPUTypeForLocalProcess(*pid);
+ if (log)
+ log->Printf("%s(): cpu type for launched process pid=%i: "
+ "cpu_type=0x%8.8x",
+ __FUNCTION__, *pid, *actual_cpu_type);
+ }
+
+ return error;
+}
+
+Error LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
+ LaunchFlavor *launch_flavor) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!launch_flavor) {
+ error.SetErrorString("mandatory launch_flavor field was null");
+ return error;
+ }
+
+ if (log) {
+ StreamString stream;
+ stream.Printf("NativeProcessDarwin::%s(): launching with the "
+ "following launch info:",
+ __FUNCTION__);
+ launch_info.Dump(stream, nullptr);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ // Retrieve the binary name given to us.
+ char given_path[PATH_MAX];
+ given_path[0] = '\0';
+ launch_info.GetExecutableFile().GetPath(given_path, sizeof(given_path));
+
+ // Determine the manner in which we'll launch.
+ *launch_flavor = g_launch_flavor;
+ if (*launch_flavor == LaunchFlavor::Default) {
+ // Our default launch method is posix spawn
+ *launch_flavor = LaunchFlavor::PosixSpawn;
+#if defined WITH_FBS
+ // Check if we have an app bundle, if so launch using BackBoard Services.
+ if (strstr(given_path, ".app")) {
+ *launch_flavor = eLaunchFlavorFBS;
+ }
+#elif defined WITH_BKS
+ // Check if we have an app bundle, if so launch using BackBoard Services.
+ if (strstr(given_path, ".app")) {
+ *launch_flavor = eLaunchFlavorBKS;
+ }
+#elif defined WITH_SPRINGBOARD
+ // Check if we have an app bundle, if so launch using SpringBoard.
+ if (strstr(given_path, ".app")) {
+ *launch_flavor = eLaunchFlavorSpringBoard;
+ }
+#endif
+ }
+
+ // Attempt to resolve the binary name to an absolute path.
+ char resolved_path[PATH_MAX];
+ resolved_path[0] = '\0';
+
+ if (log)
+ log->Printf("%s(): attempting to resolve given binary path: \"%s\"",
+ __FUNCTION__, given_path);
+
+ // If we fail to resolve the path to our executable, then just use what we
+ // were given and hope for the best
+ if (!ResolveExecutablePath(given_path, resolved_path,
+ sizeof(resolved_path))) {
+ if (log)
+ log->Printf("%s(): failed to resolve binary path, using "
+ "what was given verbatim and hoping for the best",
+ __FUNCTION__);
+ ::strncpy(resolved_path, given_path, sizeof(resolved_path));
+ } else {
+ if (log)
+ log->Printf("%s(): resolved given binary path to: \"%s\"", __FUNCTION__,
+ resolved_path);
+ }
+
+ char launch_err_str[PATH_MAX];
+ launch_err_str[0] = '\0';
+
+ // TODO figure out how to handle QSetProcessEvent
+ // const char *process_event = ctx.GetProcessEvent();
+
+ // Ensure the binary is there.
+ struct stat path_stat;
+ if (::stat(resolved_path, &path_stat) == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ // Fork a child process for debugging
+ // state_callback(eStateLaunching);
+
+ const auto argv = launch_info.GetArguments().GetConstArgumentVector();
+ const auto envp =
+ launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+
+ switch (*launch_flavor) {
+ case LaunchFlavor::ForkExec: {
+ ::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ error = ForkChildForPTraceDebugging(resolved_path, argv, envp, &pid,
+ pty_master_fd);
+ if (error.Success()) {
+ launch_info.SetProcessID(static_cast<lldb::pid_t>(pid));
+ } else {
+ // Reset any variables that might have been set during a failed
+ // launch attempt.
+ if (pty_master_fd)
+ *pty_master_fd = -1;
+
+ // We're done.
+ return error;
+ }
+ } break;
+
+#ifdef WITH_FBS
+ case LaunchFlavor::FBS: {
+ const char *app_ext = strstr(path, ".app");
+ if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
+ std::string app_bundle_path(path, app_ext + strlen(".app"));
+ m_flags |= eMachProcessFlagsUsingFBS;
+ if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
+ no_stdio, disable_aslr, event_data,
+ launch_err) != 0)
+ return m_pid; // A successful SBLaunchForDebug() returns and assigns a
+ // non-zero m_pid.
+ else
+ break; // We tried a FBS launch, but didn't succeed lets get out
+ }
+ } break;
+#endif
+
+#ifdef WITH_BKS
+ case LaunchFlavor::BKS: {
+ const char *app_ext = strstr(path, ".app");
+ if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
+ std::string app_bundle_path(path, app_ext + strlen(".app"));
+ m_flags |= eMachProcessFlagsUsingBKS;
+ if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
+ no_stdio, disable_aslr, event_data,
+ launch_err) != 0)
+ return m_pid; // A successful SBLaunchForDebug() returns and assigns a
+ // non-zero m_pid.
+ else
+ break; // We tried a BKS launch, but didn't succeed lets get out
+ }
+ } break;
+#endif
+
+#ifdef WITH_SPRINGBOARD
+ case LaunchFlavor::SpringBoard: {
+ // .../whatever.app/whatever ?
+ // Or .../com.apple.whatever.app/whatever -- be careful of ".app" in
+ // "com.apple.whatever" here
+ const char *app_ext = strstr(path, ".app/");
+ if (app_ext == NULL) {
+ // .../whatever.app ?
+ int len = strlen(path);
+ if (len > 5) {
+ if (strcmp(path + len - 4, ".app") == 0) {
+ app_ext = path + len - 4;
+ }
+ }
+ }
+ if (app_ext) {
+ std::string app_bundle_path(path, app_ext + strlen(".app"));
+ if (SBLaunchForDebug(app_bundle_path.c_str(), argv, envp, no_stdio,
+ disable_aslr, launch_err) != 0)
+ return m_pid; // A successful SBLaunchForDebug() returns and assigns a
+ // non-zero m_pid.
+ else
+ break; // We tried a springboard launch, but didn't succeed lets get out
+ }
+ } break;
+#endif
+
+ case LaunchFlavor::PosixSpawn: {
+ ::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+ // Retrieve paths for stdin/stdout/stderr.
+ cpu_type_t actual_cpu_type = 0;
+ error = PosixSpawnChildForPTraceDebugging(resolved_path, launch_info, &pid,
+ &actual_cpu_type);
+ if (error.Success()) {
+ launch_info.SetProcessID(static_cast<lldb::pid_t>(pid));
+ if (pty_master_fd)
+ *pty_master_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+ } else {
+ // Reset any variables that might have been set during a failed
+ // launch attempt.
+ if (pty_master_fd)
+ *pty_master_fd = -1;
+
+ // We're done.
+ return error;
+ }
+ break;
+ }
+
+ default:
+ // Invalid launch flavor.
+ error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): unknown "
+ "launch flavor %d",
+ __FUNCTION__, (int)*launch_flavor);
+ return error;
+ }
+
+ if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
+ // If we don't have a valid process ID and no one has set the error,
+ // then return a generic error.
+ if (error.Success())
+ error.SetErrorStringWithFormat("%s(): failed to launch, no reason "
+ "specified",
+ __FUNCTION__);
+ }
+
+ // We're done with the launch side of the operation.
+ return error;
+}
+}
+} // namespaces
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.h b/source/Plugins/Process/Darwin/DarwinProcessLauncher.h
new file mode 100644
index 000000000000..d1af4d09f8b7
--- /dev/null
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.h
@@ -0,0 +1,48 @@
+//===-- DarwinProcessLauncher.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DarwinProcessLauncher_h
+#define DarwinProcessLauncher_h
+
+// C headers
+#include <mach/machine.h>
+#include <sys/types.h>
+
+// C++ headers
+#include <functional>
+
+// LLDB headers
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+
+#include "LaunchFlavor.h"
+
+namespace lldb_private {
+namespace darwin_process_launcher {
+// =============================================================================
+/// Launches a process for debugging.
+///
+/// @param[inout] launch_info
+/// Specifies details about the process to launch (e.g. path, architecture,
+/// etc.). On output, includes the launched ProcessID (pid).
+///
+/// @param[out] pty_master_fd
+/// Returns the master side of the pseudo-terminal used to communicate
+/// with stdin/stdout from the launched process. May be nullptr.
+///
+/// @param[out] launch_flavor
+/// Contains the launch flavor used when launching the process.
+// =============================================================================
+Error LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
+ lldb_private::process_darwin::LaunchFlavor *launch_flavor);
+
+} // darwin_process_launcher
+} // lldb_private
+
+#endif /* DarwinProcessLauncher_h */
diff --git a/source/Plugins/Process/Darwin/LaunchFlavor.h b/source/Plugins/Process/Darwin/LaunchFlavor.h
new file mode 100644
index 000000000000..7b161712cffd
--- /dev/null
+++ b/source/Plugins/Process/Darwin/LaunchFlavor.h
@@ -0,0 +1,33 @@
+//===-- LaunchFlavor.h ---------------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LaunchFlavor_h
+#define LaunchFlavor_h
+
+namespace lldb_private {
+namespace process_darwin {
+
+enum class LaunchFlavor {
+ Default = 0,
+ PosixSpawn = 1,
+ ForkExec = 2,
+#ifdef WITH_SPRINGBOARD
+ SpringBoard = 3,
+#endif
+#ifdef WITH_BKS
+ BKS = 4,
+#endif
+#ifdef WITH_FBS
+ FBS = 5
+#endif
+};
+}
+} // namespaces
+
+#endif /* LaunchFlavor_h */
diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp
new file mode 100644
index 000000000000..81706441494a
--- /dev/null
+++ b/source/Plugins/Process/Darwin/MachException.cpp
@@ -0,0 +1,543 @@
+//===-- MachException.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/18/07.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MachException.h"
+
+// C includes
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+
+// C++ includes
+#include <mutex>
+
+// LLDB includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+
+// Routine mach_exception_raise
+extern "C" kern_return_t
+catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread,
+ mach_port_t task, exception_type_t exception,
+ mach_exception_data_t code,
+ mach_msg_type_number_t codeCnt);
+
+extern "C" kern_return_t catch_mach_exception_raise_state(
+ mach_port_t exception_port, exception_type_t exception,
+ const mach_exception_data_t code, mach_msg_type_number_t codeCnt,
+ int *flavor, const thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt);
+
+// Routine mach_exception_raise_state_identity
+extern "C" kern_return_t catch_mach_exception_raise_state_identity(
+ mach_port_t exception_port, mach_port_t thread, mach_port_t task,
+ exception_type_t exception, mach_exception_data_t code,
+ mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt);
+
+extern "C" boolean_t mach_exc_server(mach_msg_header_t *InHeadP,
+ mach_msg_header_t *OutHeadP);
+
+// Any access to the g_message variable should be done by locking the
+// g_message_mutex first, using the g_message variable, then unlocking
+// the g_message_mutex. See MachException::Message::CatchExceptionRaise()
+// for sample code.
+
+static MachException::Data *g_message = NULL;
+
+extern "C" kern_return_t catch_mach_exception_raise_state(
+ mach_port_t exc_port, exception_type_t exc_type,
+ const mach_exception_data_t exc_data, mach_msg_type_number_t exc_data_count,
+ int *flavor, const thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt) {
+ // TODO change to LIBLLDB_LOG_EXCEPTION
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("::%s(exc_port = 0x%4.4x, exc_type = %d (%s), "
+ "exc_data = 0x%llx, exc_data_count = %d)",
+ __FUNCTION__, exc_port, exc_type, MachException::Name(exc_type),
+ (uint64_t)exc_data, exc_data_count);
+ }
+ return KERN_FAILURE;
+}
+
+extern "C" kern_return_t catch_mach_exception_raise_state_identity(
+ mach_port_t exc_port, mach_port_t thread_port, mach_port_t task_port,
+ exception_type_t exc_type, mach_exception_data_t exc_data,
+ mach_msg_type_number_t exc_data_count, int *flavor,
+ thread_state_t old_state, mach_msg_type_number_t old_stateCnt,
+ thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
+ "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] = "
+ "{ 0x%llx, 0x%llx })",
+ __FUNCTION__, exc_port, thread_port, task_port, exc_type,
+ MachException::Name(exc_type), exc_data_count,
+ (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
+ (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
+ }
+ mach_port_deallocate(mach_task_self(), task_port);
+ mach_port_deallocate(mach_task_self(), thread_port);
+
+ return KERN_FAILURE;
+}
+
+extern "C" kern_return_t
+catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
+ mach_port_t task_port, exception_type_t exc_type,
+ mach_exception_data_t exc_data,
+ mach_msg_type_number_t exc_data_count) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
+ "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] "
+ "= { 0x%llx, 0x%llx })",
+ __FUNCTION__, exc_port, thread_port, task_port, exc_type,
+ MachException::Name(exc_type), exc_data_count,
+ (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
+ (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
+ }
+
+ if (task_port == g_message->task_port) {
+ g_message->task_port = task_port;
+ g_message->thread_port = thread_port;
+ g_message->exc_type = exc_type;
+ g_message->exc_data.resize(exc_data_count);
+ ::memcpy(&g_message->exc_data[0], exc_data,
+ g_message->exc_data.size() * sizeof(mach_exception_data_type_t));
+ return KERN_SUCCESS;
+ }
+ return KERN_FAILURE;
+}
+
+#if 0
+void
+MachException::Message::Dump(Stream &stream) const
+{
+ stream.Printf("exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
+ "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
+ "id = 0x%8.8x }\n",
+ exc_msg.hdr.msgh_bits,
+ exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port,
+ exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved,
+ exc_msg.hdr.msgh_id);
+
+ stream.Printf("reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port "
+ "= 0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
+ "id = 0x%8.8x }",
+ reply_msg.hdr.msgh_bits,
+ reply_msg.hdr.msgh_size,
+ reply_msg.hdr.msgh_remote_port,
+ reply_msg.hdr.msgh_local_port,
+ reply_msg.hdr.msgh_reserved,
+ reply_msg.hdr.msgh_id);
+ stream.Flush();
+}
+#endif
+
+bool MachException::Data::GetStopInfo(struct ThreadStopInfo *stop_info,
+ const UnixSignals &signals,
+ Stream &stream) const {
+ if (!stop_info)
+ return false;
+
+ // Zero out the structure.
+ memset(stop_info, 0, sizeof(struct ThreadStopInfo));
+
+ if (exc_type == 0) {
+ stop_info->reason = eStopReasonInvalid;
+ return true;
+ }
+
+ // We always stop with a mach exception.
+ stop_info->reason = eStopReasonException;
+ // Save the EXC_XXXX exception type.
+ stop_info->details.exception.type = exc_type;
+
+ // Fill in a text description
+ const char *exc_name = MachException::Name(exc_type);
+ if (exc_name)
+ stream.Printf("%s", exc_name);
+ else
+ stream.Printf("%i", exc_type);
+
+ stop_info->details.exception.data_count = exc_data.size();
+
+ int soft_signal = SoftSignal();
+ if (soft_signal) {
+ const char *sig_str = signals.GetSignalAsCString(soft_signal);
+ stream.Printf(" EXC_SOFT_SIGNAL( %i ( %s ))", soft_signal,
+ sig_str ? sig_str : "unknown signal");
+ } else {
+ // No special disassembly for exception data, just print it.
+ size_t idx;
+ stream.Printf(" data[%llu] = {",
+ (uint64_t)stop_info->details.exception.data_count);
+
+ for (idx = 0; idx < stop_info->details.exception.data_count; ++idx) {
+ stream.Printf(
+ "0x%llx%c", (uint64_t)exc_data[idx],
+ ((idx + 1 == stop_info->details.exception.data_count) ? '}' : ','));
+ }
+ }
+
+ // Copy the exception data
+ for (size_t i = 0; i < stop_info->details.exception.data_count; i++)
+ stop_info->details.exception.data[i] = exc_data[i];
+
+ return true;
+}
+
+Error MachException::Message::Receive(mach_port_t port,
+ mach_msg_option_t options,
+ mach_msg_timeout_t timeout,
+ mach_port_t notify_port) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ mach_msg_timeout_t mach_msg_timeout =
+ options & MACH_RCV_TIMEOUT ? timeout : 0;
+ if (log && ((options & MACH_RCV_TIMEOUT) == 0)) {
+ // Dump this log message if we have no timeout in case it never returns
+ log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
+ "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = 0, rcv_size = %llu, "
+ "rcv_name = %#x, timeout = %u, notify = %#x)",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options,
+ (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout,
+ notify_port);
+ }
+
+ mach_msg_return_t mach_err =
+ ::mach_msg(&exc_msg.hdr,
+ options, // options
+ 0, // Send size
+ sizeof(exc_msg.data), // Receive size
+ port, // exception port to watch for
+ // exception on
+ mach_msg_timeout, // timeout in msec (obeyed only
+ // if MACH_RCV_TIMEOUT is ORed
+ // into the options parameter)
+ notify_port);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+
+ // Dump any errors we get
+ if (error.Fail() && log) {
+ log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
+ "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = %u, rcv_size = %lu, rcv_name "
+ "= %#x, timeout = %u, notify = %#x) failed: %s",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0,
+ sizeof(exc_msg.data), port, mach_msg_timeout, notify_port,
+ error.AsCString());
+ }
+ return error;
+}
+
+void MachException::Message::Dump(Stream &stream) const {
+ stream.Printf(" exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
+ "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = "
+ "0x%8.8x }\n",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id);
+
+ stream.Printf(" reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
+ "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = "
+ "0x%8.8x }",
+ reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
+ reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
+ reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id);
+}
+
+bool MachException::Message::CatchExceptionRaise(task_t task) {
+ bool success = false;
+ // locker will keep a mutex locked until it goes out of scope
+ // PThreadMutex::Locker locker(&g_message_mutex);
+ // DNBLogThreaded("calling mach_exc_server");
+ state.task_port = task;
+ g_message = &state;
+ // The exc_server function is the MIG generated server handling function
+ // to handle messages from the kernel relating to the occurrence of an
+ // exception in a thread. Such messages are delivered to the exception port
+ // set via thread_set_exception_ports or task_set_exception_ports. When an
+ // exception occurs in a thread, the thread sends an exception message to
+ // its exception port, blocking in the kernel waiting for the receipt of a
+ // reply. The exc_server function performs all necessary argument handling
+ // for this kernel message and calls catch_exception_raise,
+ // catch_exception_raise_state or catch_exception_raise_state_identity,
+ // which should handle the exception. If the called routine returns
+ // KERN_SUCCESS, a reply message will be sent, allowing the thread to
+ // continue from the point of the exception; otherwise, no reply message
+ // is sent and the called routine must have dealt with the exception
+ // thread directly.
+ if (mach_exc_server(&exc_msg.hdr, &reply_msg.hdr)) {
+ success = true;
+ } else {
+ Log *log(
+ GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log)
+ log->Printf("MachException::Message::%s(): mach_exc_server "
+ "returned zero...",
+ __FUNCTION__);
+ }
+ g_message = NULL;
+ return success;
+}
+
+Error MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
+ int signal) {
+ // Reply to the exception...
+ Error error;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ // If we had a soft signal, we need to update the thread first so it can
+ // continue without signaling
+ int soft_signal = state.SoftSignal();
+ if (soft_signal) {
+ int state_pid = -1;
+ if (inferior_task == state.task_port) {
+ // This is our task, so we can update the signal to send to it
+ state_pid = inferior_pid;
+ soft_signal = signal;
+ } else {
+ auto mach_err = ::pid_for_task(state.task_port, &state_pid);
+ if (mach_err) {
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log)
+ log->Printf("MachException::Message::%s(): pid_for_task() "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ }
+
+ lldbassert(state_pid != -1);
+ if (state_pid != -1) {
+ errno = 0;
+ caddr_t thread_port_caddr = (caddr_t)(uintptr_t)state.thread_port;
+ if (::ptrace(PT_THUPDATE, state_pid, thread_port_caddr, soft_signal) != 0)
+ error.SetError(errno, eErrorTypePOSIX);
+
+ if (!error.Success()) {
+ if (log)
+ log->Printf("::ptrace(request = PT_THUPDATE, pid = "
+ "0x%4.4x, tid = 0x%4.4x, signal = %i)",
+ state_pid, state.thread_port, soft_signal);
+ return error;
+ }
+ }
+ }
+
+ if (log)
+ log->Printf("::mach_msg ( msg->{bits = %#x, size = %u, remote_port "
+ "= %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = %u, rcv_size = %u, rcv_name "
+ "= %#x, timeout = %u, notify = %#x)",
+ reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
+ reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
+ reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id,
+ MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0,
+ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+ auto mach_err =
+ ::mach_msg(&reply_msg.hdr, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
+ reply_msg.hdr.msgh_size, 0, MACH_PORT_NULL,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ if (mach_err)
+ error.SetError(mach_err, eErrorTypeMachKernel);
+
+ // Log our error if we have one.
+ if (error.Fail() && log) {
+ if (error.GetError() == MACH_SEND_INTERRUPTED) {
+ log->PutCString("::mach_msg() - send interrupted");
+ // TODO: keep retrying to reply???
+ } else if (state.task_port == inferior_task) {
+ log->Printf("mach_msg(): returned an error when replying "
+ "to a mach exception: error = %u (%s)",
+ error.GetError(), error.AsCString());
+ } else {
+ log->Printf("::mach_msg() - failed (child of task): %u (%s)",
+ error.GetError(), error.AsCString());
+ }
+ }
+
+ return error;
+}
+
+#define PREV_EXC_MASK_ALL \
+ (EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | \
+ EXC_MASK_EMULATION | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT | \
+ EXC_MASK_SYSCALL | EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT | \
+ EXC_MASK_MACHINE)
+
+// Don't listen for EXC_RESOURCE, it should really get handled by the system
+// handler.
+
+#ifndef EXC_RESOURCE
+#define EXC_RESOURCE 11
+#endif
+
+#ifndef EXC_MASK_RESOURCE
+#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
+#endif
+
+#define LLDB_EXC_MASK (EXC_MASK_ALL & ~EXC_MASK_RESOURCE)
+
+Error MachException::PortInfo::Save(task_t task) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ if (log)
+ log->Printf("MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__,
+ task);
+
+ // Be careful to be able to have debugserver built on a newer OS than what
+ // it is currently running on by being able to start with all exceptions
+ // and back off to just what is supported on the current system
+ mask = LLDB_EXC_MASK;
+
+ count = (sizeof(ports) / sizeof(ports[0]));
+ auto mach_err = ::task_get_exception_ports(task, mask, masks, &count, ports,
+ behaviors, flavors);
+ if (mach_err)
+ error.SetError(mach_err, eErrorTypeMachKernel);
+
+ if (log) {
+ if (error.Success()) {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = "
+ "0x%x, maskCnt => %u, ports, behaviors, flavors)",
+ task, mask, count);
+ } else {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = 0x%x, "
+ "maskCnt => %u, ports, behaviors, flavors) error: %u (%s)",
+ task, mask, count, error.GetError(), error.AsCString());
+ }
+ }
+
+ if ((error.GetError() == KERN_INVALID_ARGUMENT) &&
+ (mask != PREV_EXC_MASK_ALL)) {
+ mask = PREV_EXC_MASK_ALL;
+ count = (sizeof(ports) / sizeof(ports[0]));
+ mach_err = ::task_get_exception_ports(task, mask, masks, &count, ports,
+ behaviors, flavors);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log) {
+ if (error.Success()) {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, "
+ "mask = 0x%x, maskCnt => %u, ports, behaviors, "
+ "flavors)",
+ task, mask, count);
+ } else {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = "
+ "0x%x, maskCnt => %u, ports, behaviors, flavors) "
+ "error: %u (%s)",
+ task, mask, count, error.GetError(), error.AsCString());
+ }
+ }
+ }
+ if (error.Fail()) {
+ mask = 0;
+ count = 0;
+ }
+ return error;
+}
+
+Error MachException::PortInfo::Restore(task_t task) {
+ Error error;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ if (log)
+ log->Printf("MachException::PortInfo::Restore(task = 0x%4.4x)", task);
+
+ uint32_t i = 0;
+ if (count > 0) {
+ for (i = 0; i < count; i++) {
+ auto mach_err = ::task_set_exception_ports(task, masks[i], ports[i],
+ behaviors[i], flavors[i]);
+ if (mach_err)
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log) {
+ if (error.Success()) {
+ log->Printf("::task_set_exception_ports(task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x)",
+ task, masks[i], ports[i], behaviors[i], flavors[i]);
+ } else {
+ log->Printf("::task_set_exception_ports(task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x): "
+ "error %u (%s)",
+ task, masks[i], ports[i], behaviors[i], flavors[i],
+ error.GetError(), error.AsCString());
+ }
+ }
+
+ // Bail if we encounter any errors
+ if (error.Fail())
+ break;
+ }
+ }
+
+ count = 0;
+ return error;
+}
+
+const char *MachException::Name(exception_type_t exc_type) {
+ switch (exc_type) {
+ case EXC_BAD_ACCESS:
+ return "EXC_BAD_ACCESS";
+ case EXC_BAD_INSTRUCTION:
+ return "EXC_BAD_INSTRUCTION";
+ case EXC_ARITHMETIC:
+ return "EXC_ARITHMETIC";
+ case EXC_EMULATION:
+ return "EXC_EMULATION";
+ case EXC_SOFTWARE:
+ return "EXC_SOFTWARE";
+ case EXC_BREAKPOINT:
+ return "EXC_BREAKPOINT";
+ case EXC_SYSCALL:
+ return "EXC_SYSCALL";
+ case EXC_MACH_SYSCALL:
+ return "EXC_MACH_SYSCALL";
+ case EXC_RPC_ALERT:
+ return "EXC_RPC_ALERT";
+#ifdef EXC_CRASH
+ case EXC_CRASH:
+ return "EXC_CRASH";
+#endif
+ default:
+ break;
+ }
+ return NULL;
+}
diff --git a/source/Plugins/Process/Darwin/MachException.h b/source/Plugins/Process/Darwin/MachException.h
new file mode 100644
index 000000000000..ac8cd7030c55
--- /dev/null
+++ b/source/Plugins/Process/Darwin/MachException.h
@@ -0,0 +1,140 @@
+//===-- MachException.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/18/07.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __MachException_h__
+#define __MachException_h__
+
+#include <mach/mach.h>
+#include <vector>
+
+#include "lldb/Host/Debug.h"
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+namespace process_darwin {
+
+typedef union MachMessageTag {
+ mach_msg_header_t hdr;
+ char data[1024];
+} MachMessage;
+
+class MachException {
+public:
+ struct PortInfo {
+ exception_mask_t mask; // the exception mask for this device which may be a
+ // subset of EXC_MASK_ALL...
+ exception_mask_t masks[EXC_TYPES_COUNT];
+ mach_port_t ports[EXC_TYPES_COUNT];
+ exception_behavior_t behaviors[EXC_TYPES_COUNT];
+ thread_state_flavor_t flavors[EXC_TYPES_COUNT];
+ mach_msg_type_number_t count;
+
+ Error Save(task_t task);
+
+ Error Restore(task_t task);
+ };
+
+ struct Data {
+ task_t task_port;
+ thread_t thread_port;
+ exception_type_t exc_type;
+ std::vector<mach_exception_data_type_t> exc_data;
+ Data()
+ : task_port(TASK_NULL), thread_port(THREAD_NULL), exc_type(0),
+ exc_data() {}
+
+ void Clear() {
+ task_port = TASK_NULL;
+ thread_port = THREAD_NULL;
+ exc_type = 0;
+ exc_data.clear();
+ }
+
+ bool IsValid() const {
+ return task_port != TASK_NULL && thread_port != THREAD_NULL &&
+ exc_type != 0;
+ }
+
+ // Return the SoftSignal for this MachException data, or zero if there is
+ // none
+ int SoftSignal() const {
+ if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 &&
+ exc_data[0] == EXC_SOFT_SIGNAL)
+ return static_cast<int>(exc_data[1]);
+ return 0;
+ }
+
+ bool IsBreakpoint() const {
+ return (exc_type == EXC_BREAKPOINT ||
+ ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1));
+ }
+
+ bool GetStopInfo(ThreadStopInfo *stop_info, const UnixSignals &signals,
+ Stream &stream) const;
+ };
+
+ struct Message {
+ MachMessage exc_msg;
+ MachMessage reply_msg;
+ Data state;
+
+ Message() : state() {
+ memset(&exc_msg, 0, sizeof(exc_msg));
+ memset(&reply_msg, 0, sizeof(reply_msg));
+ }
+
+ bool CatchExceptionRaise(task_t task);
+
+ Error Reply(::pid_t inferior_pid, task_t inferior_task, int signal);
+
+ Error Receive(mach_port_t receive_port, mach_msg_option_t options,
+ mach_msg_timeout_t timeout,
+ mach_port_t notify_port = MACH_PORT_NULL);
+
+ void Dump(Stream &stream) const;
+
+ typedef std::vector<Message> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ };
+
+ enum {
+ e_actionForward, // Forward signal to inferior process
+ e_actionStop, // Stop when this signal is received
+ };
+ struct Action {
+ task_t task_port; // Set to TASK_NULL for any TASK
+ thread_t thread_port; // Set to THREAD_NULL for any thread
+ exception_type_t exc_mask; // Mach exception mask to watch for
+ std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to
+ // exception data, or
+ // empty to ignore
+ // exc_data value for
+ // exception
+ std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare
+ // to exception data
+ // after masking, or
+ // empty to ignore
+ // exc_data value
+ // for exception
+ uint8_t flags; // Action flags describing what to do with the exception
+ };
+
+ static const char *Name(exception_type_t exc_type);
+};
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
new file mode 100644
index 000000000000..e56375ebaa49
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
@@ -0,0 +1,1576 @@
+//===-- NativeProcessDarwin.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeProcessDarwin.h"
+
+// C includes
+#include <mach/mach_init.h>
+#include <mach/mach_traps.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+// C++ includes
+// LLDB includes
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/PseudoTerminal.h"
+
+#include "CFBundle.h"
+#include "CFString.h"
+#include "DarwinProcessLauncher.h"
+
+#include "MachException.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+using namespace lldb_private::darwin_process_launcher;
+
+// -----------------------------------------------------------------------------
+// Hidden Impl
+// -----------------------------------------------------------------------------
+
+namespace {
+struct hack_task_dyld_info {
+ mach_vm_address_t all_image_info_addr;
+ mach_vm_size_t all_image_info_size;
+};
+}
+
+// -----------------------------------------------------------------------------
+// Public Static Methods
+// -----------------------------------------------------------------------------
+
+Error NativeProcessProtocol::Launch(
+ ProcessLaunchInfo &launch_info,
+ NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
+ NativeProcessProtocolSP &native_process_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ Error error;
+
+ // Verify the working directory is valid if one was specified.
+ FileSpec working_dir(launch_info.GetWorkingDirectory());
+ if (working_dir &&
+ (!working_dir.ResolvePath() ||
+ working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ return error;
+ }
+
+ // Launch the inferior.
+ int pty_master_fd = -1;
+ LaunchFlavor launch_flavor = LaunchFlavor::Default;
+
+ error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor);
+
+ // Handle launch failure.
+ if (!error.Success()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() failed to launch process: "
+ "%s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Handle failure to return a pid.
+ if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
+ "pid was returned! Aborting.",
+ __FUNCTION__);
+ return error;
+ }
+
+ // Create the Darwin native process impl.
+ std::shared_ptr<NativeProcessDarwin> np_darwin_sp(
+ new NativeProcessDarwin(launch_info.GetProcessID(), pty_master_fd));
+ if (!np_darwin_sp->RegisterNativeDelegate(native_delegate)) {
+ native_process_sp.reset();
+ error.SetErrorStringWithFormat("failed to register the native delegate");
+ return error;
+ }
+
+ // Finalize the processing needed to debug the launched process with
+ // a NativeProcessDarwin instance.
+ error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
+ if (!error.Success()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
+ " the launching of the process: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Return the process and process id to the caller through the launch args.
+ native_process_sp = np_darwin_sp;
+ return error;
+}
+
+Error NativeProcessProtocol::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
+ pid);
+
+ // Retrieve the architecture for the running process.
+ ArchSpec process_arch;
+ Error error = ResolveProcessArchitecture(pid, process_arch);
+ if (!error.Success())
+ return error;
+
+ // TODO get attach to return this value.
+ const int pty_master_fd = -1;
+ std::shared_ptr<NativeProcessDarwin> native_process_darwin_sp(
+ new NativeProcessDarwin(pid, pty_master_fd));
+
+ if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) {
+ error.SetErrorStringWithFormat("failed to register the native "
+ "delegate");
+ return error;
+ }
+
+ native_process_darwin_sp->AttachToInferior(mainloop, pid, error);
+ if (!error.Success())
+ return error;
+
+ native_process_sp = native_process_darwin_sp;
+ return error;
+}
+
+// -----------------------------------------------------------------------------
+// ctor/dtor
+// -----------------------------------------------------------------------------
+
+NativeProcessDarwin::NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd)
+ : NativeProcessProtocol(pid), m_task(TASK_NULL), m_did_exec(false),
+ m_cpu_type(0), m_exception_port(MACH_PORT_NULL), m_exc_port_info(),
+ m_exception_thread(nullptr), m_exception_messages_mutex(),
+ m_sent_interrupt_signo(0), m_auto_resume_signo(0), m_thread_list(),
+ m_thread_actions(), m_waitpid_pipe(), m_waitpid_thread(nullptr),
+ m_waitpid_reader_handle() {
+ // TODO add this to the NativeProcessProtocol constructor.
+ m_terminal_fd = pty_master_fd;
+}
+
+NativeProcessDarwin::~NativeProcessDarwin() {}
+
+// -----------------------------------------------------------------------------
+// Instance methods
+// -----------------------------------------------------------------------------
+
+Error NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
+ MainLoop &main_loop) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+#if 0
+ m_path = path;
+ size_t i;
+ char const *arg;
+ for (i=0; (arg = argv[i]) != NULL; i++)
+ m_args.push_back(arg);
+#endif
+
+ error = StartExceptionThread();
+ if (!error.Success()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failure starting the "
+ "mach exception port monitor thread: %s",
+ __FUNCTION__, error.AsCString());
+
+ // Terminate the inferior process. There's nothing meaningful we can
+ // do if we can't receive signals and exceptions. Since we launched
+ // the process, it's fair game for us to kill it.
+ ::ptrace(PT_KILL, m_pid, 0, 0);
+ SetState(eStateExited);
+
+ return error;
+ }
+
+ StartSTDIOThread();
+
+ if (launch_flavor == LaunchFlavor::PosixSpawn) {
+ SetState(eStateAttaching);
+ errno = 0;
+ int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
+ if (err == 0) {
+ // m_flags |= eMachProcessFlagsAttached;
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): successfully spawned "
+ "process with pid %" PRIu64,
+ __FUNCTION__, m_pid);
+ } else {
+ error.SetErrorToErrno();
+ SetState(eStateExited);
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): error: failed to "
+ "attach to spawned pid %" PRIu64 " (error=%d (%s))",
+ __FUNCTION__, m_pid, (int)error.GetError(),
+ error.AsCString());
+ return error;
+ }
+ }
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
+ __FUNCTION__, m_pid);
+
+ // Spawn a thread to reap our child inferior process...
+ error = StartWaitpidThread(main_loop);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
+ kill(SIGKILL, static_cast<::pid_t>(m_pid));
+ return error;
+ }
+
+ if (TaskPortForProcessID(error) == TASK_NULL) {
+ // We failed to get the task for our process ID which is bad.
+ // Kill our process; otherwise, it will be stopped at the entry
+ // point and get reparented to someone else and never go away.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): could not get task port "
+ "for process, sending SIGKILL and exiting: %s",
+ __FUNCTION__, error.AsCString());
+ kill(SIGKILL, static_cast<::pid_t>(m_pid));
+ return error;
+ }
+
+ // Indicate that we're stopped, as we always launch suspended.
+ SetState(eStateStopped);
+
+ // Success.
+ return error;
+}
+
+Error NativeProcessDarwin::SaveExceptionPortInfo() {
+ return m_exc_port_info.Save(m_task);
+}
+
+bool NativeProcessDarwin::ProcessUsingSpringBoard() const {
+ // TODO implement flags
+ // return (m_flags & eMachProcessFlagsUsingSBS) != 0;
+ return false;
+}
+
+bool NativeProcessDarwin::ProcessUsingBackBoard() const {
+ // TODO implement flags
+ // return (m_flags & eMachProcessFlagsUsingBKS) != 0;
+ return false;
+}
+
+// Called by the exception thread when an exception has been received from
+// our process. The exception message is completely filled and the exception
+// data has already been copied.
+void NativeProcessDarwin::ExceptionMessageReceived(
+ const MachException::Message &message) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ if (m_exception_messages.empty()) {
+ // Suspend the task the moment we receive our first exception message.
+ SuspendTask();
+ }
+
+ // Use a locker to automatically unlock our mutex in case of exceptions
+ // Add the exception to our internal exception stack
+ m_exception_messages.push_back(message);
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
+ __FUNCTION__, m_exception_messages.size());
+}
+
+void *NativeProcessDarwin::ExceptionThread(void *arg) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (!arg) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread();
+}
+
+void *NativeProcessDarwin::DoExceptionThread() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
+ __FUNCTION__, this);
+
+ pthread_setname_np("exception monitoring thread");
+
+ // Ensure we don't get CPU starved.
+ MaybeRaiseThreadPriority();
+
+ // We keep a count of the number of consecutive exceptions received so
+ // we know to grab all exceptions without a timeout. We do this to get a
+ // bunch of related exceptions on our exception port so we can process
+ // then together. When we have multiple threads, we can get an exception
+ // per thread and they will come in consecutively. The main loop in this
+ // thread can stop periodically if needed to service things related to this
+ // process.
+ //
+ // [did we lose some words here?]
+ //
+ // flag set in the options, so we will wait forever for an exception on
+ // 0 our exception port. After we get one exception, we then will use the
+ // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
+ // exceptions for our process. After we have received the last pending
+ // exception, we will get a timeout which enables us to then notify
+ // our main thread that we have an exception bundle available. We then wait
+ // for the main thread to tell this exception thread to start trying to get
+ // exceptions messages again and we start again with a mach_msg read with
+ // infinite timeout.
+ //
+ // We choose to park a thread on this, rather than polling, because the
+ // polling is expensive. On devices, we need to minimize overhead caused
+ // by the process monitor.
+ uint32_t num_exceptions_received = 0;
+ Error error;
+ task_t task = m_task;
+ mach_msg_timeout_t periodic_timeout = 0;
+
+#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
+ mach_msg_timeout_t watchdog_elapsed = 0;
+ mach_msg_timeout_t watchdog_timeout = 60 * 1000;
+ ::pid_t pid = (::pid_t)process->GetID();
+ CFReleaser<SBSWatchdogAssertionRef> watchdog;
+
+ if (process->ProcessUsingSpringBoard()) {
+ // Request a renewal for every 60 seconds if we attached using
+ // SpringBoard.
+ watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
+ if (log)
+ log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
+ "=> %p",
+ pid, watchdog.get());
+
+ if (watchdog.get()) {
+ ::SBSWatchdogAssertionRenew(watchdog.get());
+
+ CFTimeInterval watchdogRenewalInterval =
+ ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
+ if (log)
+ log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
+ "%g seconds",
+ watchdog.get(), watchdogRenewalInterval);
+ if (watchdogRenewalInterval > 0.0) {
+ watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
+ if (watchdog_timeout > 3000) {
+ // Give us a second to renew our timeout.
+ watchdog_timeout -= 1000;
+ } else if (watchdog_timeout > 1000) {
+ // Give us a quarter of a second to renew our timeout.
+ watchdog_timeout -= 250;
+ }
+ }
+ }
+ if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
+ periodic_timeout = watchdog_timeout;
+ }
+#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
+
+#ifdef WITH_BKS
+ CFReleaser<BKSWatchdogAssertionRef> watchdog;
+ if (process->ProcessUsingBackBoard()) {
+ ::pid_t pid = process->GetID();
+ CFAllocatorRef alloc = kCFAllocatorDefault;
+ watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid));
+ }
+#endif // #ifdef WITH_BKS
+
+ // Do we want to use a weak pointer to the NativeProcessDarwin here, in
+ // which case we can guarantee we don't whack the process monitor if we
+ // race between this thread and the main one on shutdown?
+ while (IsExceptionPortValid()) {
+ ::pthread_testcancel();
+
+ MachException::Message exception_message;
+
+ if (num_exceptions_received > 0) {
+ // We don't want a timeout here, just receive as many exceptions as
+ // we can since we already have one. We want to get all currently
+ // available exceptions for this task at once.
+ error = exception_message.Receive(
+ GetExceptionPort(),
+ MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
+ } else if (periodic_timeout > 0) {
+ // We need to stop periodically in this loop, so try and get a mach
+ // message with a valid timeout (ms).
+ error = exception_message.Receive(GetExceptionPort(),
+ MACH_RCV_MSG | MACH_RCV_INTERRUPT |
+ MACH_RCV_TIMEOUT,
+ periodic_timeout);
+ } else {
+ // We don't need to parse all current exceptions or stop
+ // periodically, just wait for an exception forever.
+ error = exception_message.Receive(GetExceptionPort(),
+ MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
+ }
+
+ if (error.Success()) {
+ // We successfully received an exception.
+ if (exception_message.CatchExceptionRaise(task)) {
+ ++num_exceptions_received;
+ ExceptionMessageReceived(exception_message);
+ }
+ } else {
+ if (error.GetError() == MACH_RCV_INTERRUPTED) {
+ // We were interrupted.
+
+ // If we have no task port we should exit this thread, as it implies
+ // the inferior went down.
+ if (!IsExceptionPortValid()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): the inferior "
+ "exception port is no longer valid, "
+ "canceling exception thread...",
+ __FUNCTION__);
+ // Should we be setting a process state here?
+ break;
+ }
+
+ // Make sure the inferior task is still valid.
+ if (IsTaskValid()) {
+ // Task is still ok.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): interrupted, but "
+ "the inferior task iss till valid, "
+ "continuing...",
+ __FUNCTION__);
+ continue;
+ } else {
+ // The inferior task is no longer valid. Time to exit as
+ // the process has gone away.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): the inferior task "
+ "has exited, and so will we...",
+ __FUNCTION__);
+ // Does this race at all with our waitpid()?
+ SetState(eStateExited);
+ break;
+ }
+ } else if (error.GetError() == MACH_RCV_TIMED_OUT) {
+ // We timed out when waiting for exceptions.
+
+ if (num_exceptions_received > 0) {
+ // We were receiving all current exceptions with a timeout of
+ // zero. It is time to go back to our normal looping mode.
+ num_exceptions_received = 0;
+
+ // Notify our main thread we have a complete exception message
+ // bundle available. Get the possibly updated task port back
+ // from the process in case we exec'ed and our task port
+ // changed.
+ task = ExceptionMessageBundleComplete();
+
+ // In case we use a timeout value when getting exceptions,
+ // make sure our task is still valid.
+ if (IsTaskValid(task)) {
+ // Task is still ok.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): got a timeout, "
+ "continuing...",
+ __FUNCTION__);
+ continue;
+ } else {
+ // The inferior task is no longer valid. Time to exit as
+ // the process has gone away.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): the inferior "
+ "task has exited, and so will we...",
+ __FUNCTION__);
+ // Does this race at all with our waitpid()?
+ SetState(eStateExited);
+ break;
+ }
+ }
+
+#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
+ if (watchdog.get()) {
+ watchdog_elapsed += periodic_timeout;
+ if (watchdog_elapsed >= watchdog_timeout) {
+ if (log)
+ log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get());
+ ::SBSWatchdogAssertionRenew(watchdog.get());
+ watchdog_elapsed = 0;
+ }
+ }
+#endif
+ } else {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): continuing after "
+ "receiving an unexpected error: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
+ // TODO: notify of error?
+ }
+ }
+ }
+
+#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
+ if (watchdog.get()) {
+ // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel
+ // when we
+ // all are up and running on systems that support it. The SBS framework has
+ // a #define
+ // that will forward SBSWatchdogAssertionRelease to
+ // SBSWatchdogAssertionCancel for now
+ // so it should still build either way.
+ DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)",
+ watchdog.get());
+ ::SBSWatchdogAssertionRelease(watchdog.get());
+ }
+#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
+ this);
+ return nullptr;
+}
+
+Error NativeProcessDarwin::StartExceptionThread() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+
+ // Make sure we've looked up the inferior port.
+ TaskPortForProcessID(error);
+
+ // Ensure the inferior task is valid.
+ if (!IsTaskValid()) {
+ error.SetErrorStringWithFormat("cannot start exception thread: "
+ "task 0x%4.4x is not valid",
+ m_task);
+ return error;
+ }
+
+ // Get the mach port for the process monitor.
+ mach_port_t task_self = mach_task_self();
+
+ // Allocate an exception port that we will use to track our child process
+ auto mach_err = ::mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE,
+ &m_exception_port);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): mach_port_allocate("
+ "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
+ "&m_exception_port) failed: %u (%s)",
+ __FUNCTION__, task_self, error.GetError(), error.AsCString());
+ return error;
+ }
+
+ // Add the ability to send messages on the new exception port
+ mach_err = ::mach_port_insert_right(
+ task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right("
+ "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
+ "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
+ "failed: %u (%s)",
+ __FUNCTION__, task_self, m_exception_port, m_exception_port,
+ error.GetError(), error.AsCString());
+ return error;
+ }
+
+ // Save the original state of the exception ports for our child process.
+ error = SaveExceptionPortInfo();
+ if (error.Fail() || (m_exc_port_info.mask == 0)) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
+ "failed, cannot install exception handler: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Set the ability to get all exceptions on this port.
+ mach_err = ::task_set_exception_ports(
+ m_task, m_exc_port_info.mask, m_exception_port,
+ EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("::task_set_exception_ports (task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
+ "%u (%s)",
+ m_task, m_exc_port_info.mask, m_exception_port,
+ (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
+ error.GetError(), error.AsCString());
+ return error;
+ }
+
+ // Create the exception thread.
+ auto pthread_err =
+ ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
+ error.SetError(pthread_err, eErrorTypePOSIX);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
+ "exception-handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
+ }
+
+ return error;
+}
+
+lldb::addr_t
+NativeProcessDarwin::GetDYLDAllImageInfosAddress(Error &error) const {
+ error.Clear();
+
+ struct hack_task_dyld_info dyld_info;
+ mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
+ // Make sure that COUNT isn't bigger than our hacked up struct
+ // hack_task_dyld_info. If it is, then make COUNT smaller to match.
+ if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t))) {
+ count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t));
+ }
+
+ TaskPortForProcessID(error);
+ if (error.Fail())
+ return LLDB_INVALID_ADDRESS;
+
+ auto mach_err =
+ ::task_info(m_task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Success()) {
+ // We now have the address of the all image infos structure.
+ return dyld_info.all_image_info_addr;
+ }
+
+ // We don't have it.
+ return LLDB_INVALID_ADDRESS;
+}
+
+uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) {
+ int mib[CTL_MAXNAME] = {
+ 0,
+ };
+ size_t len = CTL_MAXNAME;
+
+ if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
+ return 0;
+
+ mib[len] = pid;
+ len++;
+
+ cpu_type_t cpu;
+ size_t cpu_len = sizeof(cpu);
+ if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
+ cpu = 0;
+ return cpu;
+}
+
+uint32_t NativeProcessDarwin::GetCPUType() const {
+ if (m_cpu_type == 0 && m_pid != 0)
+ m_cpu_type = GetCPUTypeForLocalProcess(m_pid);
+ return m_cpu_type;
+}
+
+task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
+ // We have a complete bundle of exceptions for our child process.
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
+ "messages.",
+ __FUNCTION__, m_exception_messages.size());
+
+ if (m_exception_messages.empty()) {
+ // Not particularly useful...
+ return m_task;
+ }
+
+ bool auto_resume = false;
+ m_did_exec = false;
+
+ // First check for any SIGTRAP and make sure we didn't exec
+ const task_t task = m_task;
+ size_t i;
+ if (m_pid != 0) {
+ bool received_interrupt = false;
+ uint32_t num_task_exceptions = 0;
+ for (i = 0; i < m_exception_messages.size(); ++i) {
+ if (m_exception_messages[i].state.task_port != task) {
+ // This is an exception that is not for our inferior, ignore.
+ continue;
+ }
+
+ // This is an exception for the inferior.
+ ++num_task_exceptions;
+ const int signo = m_exception_messages[i].state.SoftSignal();
+ if (signo == SIGTRAP) {
+ // SIGTRAP could mean that we exec'ed. We need to check the
+ // dyld all_image_infos.infoArray to see if it is NULL and if
+ // so, say that we exec'ed.
+ const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
+ if (aii_addr == LLDB_INVALID_ADDRESS)
+ break;
+
+ const addr_t info_array_count_addr = aii_addr + 4;
+ uint32_t info_array_count = 0;
+ size_t bytes_read = 0;
+ Error read_error;
+ read_error = ReadMemory(info_array_count_addr, // source addr
+ &info_array_count, // dest addr
+ 4, // byte count
+ bytes_read); // #bytes read
+ if (read_error.Success() && (bytes_read == 4)) {
+ if (info_array_count == 0) {
+ // We got the all infos address, and there are zero
+ // entries. We think we exec'd.
+ m_did_exec = true;
+
+ // Force the task port to update itself in case the
+ // task port changed after exec
+ const task_t old_task = m_task;
+ const bool force_update = true;
+ const task_t new_task = TaskPortForProcessID(error, force_update);
+ if (old_task != new_task) {
+ if (log)
+ log->Printf("exec: inferior task port changed "
+ "from 0x%4.4x to 0x%4.4x",
+ old_task, new_task);
+ }
+ }
+ } else {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() warning: "
+ "failed to read all_image_infos."
+ "infoArrayCount from 0x%8.8llx",
+ __FUNCTION__, info_array_count_addr);
+ }
+ } else if ((m_sent_interrupt_signo != 0) &&
+ (signo == m_sent_interrupt_signo)) {
+ // We just received the interrupt that we sent to ourselves.
+ received_interrupt = true;
+ }
+ }
+
+ if (m_did_exec) {
+ cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
+ if (m_cpu_type != process_cpu_type) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): arch changed from "
+ "0x%8.8x to 0x%8.8x",
+ __FUNCTION__, m_cpu_type, process_cpu_type);
+ m_cpu_type = process_cpu_type;
+ // TODO figure out if we need to do something here.
+ // DNBArchProtocol::SetArchitecture (process_cpu_type);
+ }
+ m_thread_list.Clear();
+
+ // TODO hook up breakpoints.
+ // m_breakpoints.DisableAll();
+ }
+
+ if (m_sent_interrupt_signo != 0) {
+ if (received_interrupt) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): process "
+ "successfully interrupted with signal %i",
+ __FUNCTION__, m_sent_interrupt_signo);
+
+ // Mark that we received the interrupt signal
+ m_sent_interrupt_signo = 0;
+ // Now check if we had a case where:
+ // 1 - We called NativeProcessDarwin::Interrupt() but we stopped
+ // for another reason.
+ // 2 - We called NativeProcessDarwin::Resume() (but still
+ // haven't gotten the interrupt signal).
+ // 3 - We are now incorrectly stopped because we are handling
+ // the interrupt signal we missed.
+ // 4 - We might need to resume if we stopped only with the
+ // interrupt signal that we never handled.
+ if (m_auto_resume_signo != 0) {
+ // Only auto_resume if we stopped with _only_ the interrupt
+ // signal.
+ if (num_task_exceptions == 1) {
+ auto_resume = true;
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): auto "
+ "resuming due to unhandled interrupt "
+ "signal %i",
+ __FUNCTION__, m_auto_resume_signo);
+ }
+ m_auto_resume_signo = 0;
+ }
+ } else {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): didn't get signal "
+ "%i after MachProcess::Interrupt()",
+ __FUNCTION__, m_sent_interrupt_signo);
+ }
+ }
+ }
+
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list.ProcessDidStop(*this);
+
+ // Let each thread know of any exceptions
+ for (i = 0; i < m_exception_messages.size(); ++i) {
+ // Let the thread list forward all exceptions on down to each thread.
+ if (m_exception_messages[i].state.task_port == task) {
+ // This exception is for our inferior.
+ m_thread_list.NotifyException(m_exception_messages[i].state);
+ }
+
+ if (log) {
+ StreamString stream;
+ m_exception_messages[i].Dump(stream);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+ }
+
+ if (log) {
+ StreamString stream;
+ m_thread_list.Dump(stream);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ bool step_more = false;
+ if (m_thread_list.ShouldStop(step_more) && (auto_resume == false)) {
+// TODO - need to hook up event system here. !!!!
+#if 0
+ // Wait for the eEventProcessRunningStateChanged event to be reset
+ // before changing state to stopped to avoid race condition with
+ // very fast start/stops.
+ struct timespec timeout;
+
+ //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000); // Wait for 250 ms
+ DNBTimer::OffsetTimeOfDay(&timeout, 1, 0); // Wait for 250 ms
+ m_events.WaitForEventsToReset(eEventProcessRunningStateChanged,
+ &timeout);
+#endif
+ SetState(eStateStopped);
+ } else {
+ // Resume without checking our current state.
+ PrivateResume();
+ }
+
+ return m_task;
+}
+
+void NativeProcessDarwin::StartSTDIOThread() {
+ // TODO implement
+}
+
+Error NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Strategy: create a thread that sits on waitpid(), waiting for the
+ // inferior process to die, reaping it in the process. Arrange for
+ // the thread to have a pipe file descriptor that it can send a byte
+ // over when the waitpid completes. Have the main loop have a read
+ // object for the other side of the pipe, and have the callback for
+ // the read do the process termination message sending.
+
+ // Create a single-direction communication channel.
+ const bool child_inherits = false;
+ error = m_waitpid_pipe.CreateNew(child_inherits);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
+ "communication pipe: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Hook up the waitpid reader callback.
+
+ // TODO make PipePOSIX derive from IOObject. This is goofy here.
+ const bool transfer_ownership = false;
+ auto io_sp = IOObjectSP(
+ new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership));
+ m_waitpid_reader_handle = main_loop.RegisterReadObject(
+ io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error);
+
+ // Create the thread.
+ auto pthread_err =
+ ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
+ error.SetError(pthread_err, eErrorTypePOSIX);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
+ "handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
+ return error;
+ }
+
+ return error;
+}
+
+void *NativeProcessDarwin::WaitpidThread(void *arg) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (!arg) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread();
+}
+
+void NativeProcessDarwin::MaybeRaiseThreadPriority() {
+#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ struct sched_param thread_param;
+ int thread_sched_policy;
+ if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
+ &thread_param) == 0) {
+ thread_param.sched_priority = 47;
+ pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
+ }
+#endif
+}
+
+void *NativeProcessDarwin::DoWaitpidThread() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (m_pid == LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
+ "not set, cannot waitpid on it",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ // Name the thread.
+ pthread_setname_np("waitpid thread");
+
+ // Ensure we don't get CPU starved.
+ MaybeRaiseThreadPriority();
+
+ Error error;
+ int status = -1;
+
+ while (1) {
+ // Do a waitpid.
+ ::pid_t child_pid = ::waitpid(m_pid, &status, 0);
+ if (child_pid < 0)
+ error.SetErrorToErrno();
+ if (error.Fail()) {
+ if (error.GetError() == EINTR) {
+ // This is okay, we can keep going.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) interrupted, continuing",
+ __FUNCTION__, m_pid);
+ continue;
+ }
+
+ // This error is not okay, abort.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) aborting due to error: %u (%s)",
+ __FUNCTION__, m_pid, error.GetError(), error.AsCString());
+ break;
+ }
+
+ // Log the successful result.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) => %i, status = %i",
+ __FUNCTION__, m_pid, child_pid, status);
+
+ // Handle the result.
+ if (WIFSTOPPED(status)) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ") received a stop, continuing waitpid() loop",
+ __FUNCTION__, m_pid);
+ continue;
+ } else // if (WIFEXITED(status) || WIFSIGNALED(status))
+ {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
+ "waitpid thread is setting exit status for pid = "
+ "%i to %i",
+ __FUNCTION__, m_pid, child_pid, status);
+
+ error = SendInferiorExitStatusToMainLoop(child_pid, status);
+ return nullptr;
+ }
+ }
+
+ // We should never exit as long as our child process is alive. If we
+ // get here, something completely unexpected went wrong and we should exit.
+ if (log)
+ log->Printf(
+ "NativeProcessDarwin::%s(): internal error: waitpid thread "
+ "exited out of its main loop in an unexpected way. pid = %" PRIu64
+ ". Sending exit status of -1.",
+ __FUNCTION__, m_pid);
+
+ error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
+ return nullptr;
+}
+
+Error NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
+ int status) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ size_t bytes_written = 0;
+
+ // Send the pid.
+ error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
+ if (error.Fail() || (bytes_written < sizeof(pid))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to write "
+ "waitpid exiting pid to the pipe. Client will not "
+ "hear about inferior exit status!",
+ __FUNCTION__);
+ return error;
+ }
+
+ // Send the status.
+ bytes_written = 0;
+ error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
+ if (error.Fail() || (bytes_written < sizeof(status))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to write "
+ "waitpid exit result to the pipe. Client will not "
+ "hear about inferior exit status!",
+ __FUNCTION__);
+ }
+ return error;
+}
+
+Error NativeProcessDarwin::HandleWaitpidResult() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Read the pid.
+ const bool notify_status = true;
+
+ ::pid_t pid = -1;
+ size_t bytes_read = 0;
+ error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
+ if (error.Fail() || (bytes_read < sizeof(pid))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to read "
+ "waitpid exiting pid from the pipe. Will notify "
+ "as if parent process died with exit status -1.",
+ __FUNCTION__);
+ SetExitStatus(eExitTypeInvalid, -1, "failed to receive waitpid result",
+ notify_status);
+ return error;
+ }
+
+ // Read the status.
+ int status = -1;
+ error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
+ if (error.Fail() || (bytes_read < sizeof(status))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to read "
+ "waitpid exit status from the pipe. Will notify "
+ "as if parent process died with exit status -1.",
+ __FUNCTION__);
+ SetExitStatus(eExitTypeInvalid, -1, "failed to receive waitpid result",
+ notify_status);
+ return error;
+ }
+
+ // Notify the monitor that our state has changed.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): main loop received waitpid "
+ "exit status info: pid=%i (%s), status=%i",
+ __FUNCTION__, pid,
+ (pid == m_pid) ? "the inferior" : "not the inferior", status);
+
+ ExitType exit_type = eExitTypeInvalid;
+ int exit_status = -1;
+
+ if (WIFEXITED(status)) {
+ exit_type = eExitTypeExit;
+ exit_status = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ exit_type = eExitTypeSignal;
+ exit_status = WTERMSIG(status);
+ }
+
+ SetExitStatus(exit_type, exit_status, nullptr, notify_status);
+ return error;
+}
+
+task_t NativeProcessDarwin::TaskPortForProcessID(Error &error,
+ bool force) const {
+ if ((m_task == TASK_NULL) || force) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (m_pid == LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): cannot get task due "
+ "to invalid pid",
+ __FUNCTION__);
+ return TASK_NULL;
+ }
+
+ const uint32_t num_retries = 10;
+ const uint32_t usec_interval = 10000;
+
+ mach_port_t task_self = mach_task_self();
+ task_t task = TASK_NULL;
+
+ for (uint32_t i = 0; i < num_retries; i++) {
+ kern_return_t err = ::task_for_pid(task_self, m_pid, &task);
+ if (err == 0) {
+ // Succeeded. Save and return it.
+ error.Clear();
+ m_task = task;
+ log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
+ "stub_port = 0x%4.4x, pid = %llu, &task) "
+ "succeeded: inferior task port = 0x%4.4x",
+ __FUNCTION__, task_self, m_pid, m_task);
+ return m_task;
+ } else {
+ // Failed to get the task for the inferior process.
+ error.SetError(err, eErrorTypeMachKernel);
+ if (log) {
+ log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
+ "stub_port = 0x%4.4x, pid = %llu, &task) "
+ "failed, err = 0x%8.8x (%s)",
+ __FUNCTION__, task_self, m_pid, err, error.AsCString());
+ }
+ }
+
+ // Sleep a bit and try again
+ ::usleep(usec_interval);
+ }
+
+ // We failed to get the task for the inferior process.
+ // Ensure that it is cleared out.
+ m_task = TASK_NULL;
+ }
+ return m_task;
+}
+
+void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
+ Error &error) {
+ error.SetErrorString("TODO: implement");
+}
+
+Error NativeProcessDarwin::PrivateResume() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ m_auto_resume_signo = m_sent_interrupt_signo;
+
+ if (log) {
+ if (m_auto_resume_signo)
+ log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with "
+ "unhandled interrupt signal %i)...",
+ __FUNCTION__, m_task, m_auto_resume_signo);
+ else
+ log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
+ __FUNCTION__, m_task);
+ }
+
+ error = ReplyToAllExceptions();
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
+ "reply to exceptions: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ // bool stepOverBreakInstruction = step;
+
+ // Let the thread prepare to resume and see if any threads want us to
+ // step over a breakpoint instruction (ProcessWillResume will modify
+ // the value of stepOverBreakInstruction).
+ m_thread_list.ProcessWillResume(*this, m_thread_actions);
+
+ // Set our state accordingly
+ if (m_thread_actions.NumActionsWithState(eStateStepping))
+ SetState(eStateStepping);
+ else
+ SetState(eStateRunning);
+
+ // Now resume our task.
+ error = ResumeTask();
+ return error;
+}
+
+Error NativeProcessDarwin::ReplyToAllExceptions() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ TaskPortForProcessID(error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
+ __FUNCTION__);
+ return error;
+ }
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ if (m_exception_messages.empty()) {
+ // We're done.
+ return error;
+ }
+
+ size_t index = 0;
+ for (auto &message : m_exception_messages) {
+ if (log) {
+ log->Printf("NativeProcessDarwin::%s(): replying to exception "
+ "%zu...",
+ __FUNCTION__, index++);
+ }
+
+ int thread_reply_signal = 0;
+
+ const tid_t tid =
+ m_thread_list.GetThreadIDByMachPortNumber(message.state.thread_port);
+ const ResumeAction *action = nullptr;
+ if (tid != LLDB_INVALID_THREAD_ID)
+ action = m_thread_actions.GetActionForThread(tid, false);
+
+ if (action) {
+ thread_reply_signal = action->signal;
+ if (thread_reply_signal)
+ m_thread_actions.SetSignalHandledForThread(tid);
+ }
+
+ error = message.Reply(m_pid, m_task, thread_reply_signal);
+ if (error.Fail() && log) {
+ // We log any error here, but we don't stop the exception
+ // response handling.
+ log->Printf("NativeProcessDarwin::%s(): failed to reply to "
+ "exception: %s",
+ __FUNCTION__, error.AsCString());
+ error.Clear();
+ }
+ }
+
+ // Erase all exception message as we should have used and replied
+ // to them all already.
+ m_exception_messages.clear();
+ return error;
+}
+
+Error NativeProcessDarwin::ResumeTask() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ TaskPortForProcessID(error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to get task port "
+ "for process when attempting to resume: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ if (m_task == TASK_NULL) {
+ error.SetErrorString("task port retrieval succeeded but task port is "
+ "null when attempting to resume the task");
+ return error;
+ }
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
+ "0x%4.4x",
+ __FUNCTION__, m_task);
+
+ // Get the BasicInfo struct to verify that we're suspended before we try
+ // to resume the task.
+ struct task_basic_info task_info;
+ error = GetTaskBasicInfo(m_task, &task_info);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to get task "
+ "BasicInfo when attempting to resume: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // task_resume isn't counted like task_suspend calls are, so if the
+ // task is not suspended, don't try and resume it since it is already
+ // running
+ if (task_info.suspend_count > 0) {
+ auto mach_err = ::task_resume(m_task);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log) {
+ if (error.Success())
+ log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
+ else
+ log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
+ error.AsCString());
+ }
+ } else {
+ if (log)
+ log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
+ "already running",
+ m_task);
+ }
+
+ return error;
+}
+
+bool NativeProcessDarwin::IsTaskValid() const {
+ if (m_task == TASK_NULL)
+ return false;
+
+ struct task_basic_info task_info;
+ return GetTaskBasicInfo(m_task, &task_info).Success();
+}
+
+bool NativeProcessDarwin::IsTaskValid(task_t task) const {
+ if (task == TASK_NULL)
+ return false;
+
+ struct task_basic_info task_info;
+ return GetTaskBasicInfo(task, &task_info).Success();
+}
+
+mach_port_t NativeProcessDarwin::GetExceptionPort() const {
+ return m_exception_port;
+}
+
+bool NativeProcessDarwin::IsExceptionPortValid() const {
+ return MACH_PORT_VALID(m_exception_port);
+}
+
+Error NativeProcessDarwin::GetTaskBasicInfo(
+ task_t task, struct task_basic_info *info) const {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Validate args.
+ if (info == NULL) {
+ error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory "
+ "info arg is null",
+ __FUNCTION__);
+ return error;
+ }
+
+ // Grab the task if we don't already have it.
+ if (task == TASK_NULL) {
+ error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task "
+ "is invalid",
+ __FUNCTION__);
+ }
+
+ mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
+ auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
+ error.SetError(err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("::task_info(target_task = 0x%4.4x, "
+ "flavor = TASK_BASIC_INFO, task_info_out => %p, "
+ "task_info_outCnt => %u) failed: %u (%s)",
+ m_task, info, count, error.GetError(), error.AsCString());
+ return error;
+ }
+
+ Log *verbose_log(
+ GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (verbose_log) {
+ float user = (float)info->user_time.seconds +
+ (float)info->user_time.microseconds / 1000000.0f;
+ float system = (float)info->user_time.seconds +
+ (float)info->user_time.microseconds / 1000000.0f;
+ verbose_log->Printf("task_basic_info = { suspend_count = %i, "
+ "virtual_size = 0x%8.8llx, resident_size = "
+ "0x%8.8llx, user_time = %f, system_time = %f }",
+ info->suspend_count, (uint64_t)info->virtual_size,
+ (uint64_t)info->resident_size, user, system);
+ }
+ return error;
+}
+
+Error NativeProcessDarwin::SuspendTask() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (m_task == TASK_NULL) {
+ error.SetErrorString("task port is null, cannot suspend task");
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
+ return error;
+ }
+
+ auto mach_err = ::task_suspend(m_task);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail() && log)
+ log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task);
+
+ return error;
+}
+
+Error NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+
+ if (CanResume()) {
+ m_thread_actions = resume_actions;
+ error = PrivateResume();
+ return error;
+ }
+
+ auto state = GetState();
+ if (state == eStateRunning) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
+ "running, ignoring...",
+ __FUNCTION__, TaskPortForProcessID(error));
+ return error;
+ }
+
+ // We can't resume from this state.
+ error.SetErrorStringWithFormat("task 0x%x has state %s, can't resume",
+ TaskPortForProcessID(error),
+ StateAsCString(state));
+ return error;
+}
+
+Error NativeProcessDarwin::Halt() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Detach() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Signal(int signo) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Interrupt() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Kill() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
+ size_t size,
+ size_t &bytes_read) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf,
+ size_t size, size_t &bytes_written) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() {
+ return LLDB_INVALID_ADDRESS;
+}
+
+size_t NativeProcessDarwin::UpdateThreads() { return 0; }
+
+bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const {
+ return false;
+}
+
+Error NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {}
+
+Error NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+// -----------------------------------------------------------------
+// NativeProcessProtocol protected interface
+// -----------------------------------------------------------------
+Error NativeProcessDarwin::GetSoftwareBreakpointTrapOpcode(
+ size_t trap_opcode_size_hint, size_t &actual_opcode_size,
+ const uint8_t *&trap_opcode_bytes) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
new file mode 100644
index 000000000000..69c1b8d9e4cc
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
@@ -0,0 +1,384 @@
+//===-- NativeProcessDarwin.h --------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef NativeProcessDarwin_h
+#define NativeProcessDarwin_h
+
+// NOTE: this code should only be compiled on Apple Darwin systems. It is
+// not cross-platform code and is not intended to build on any other platform.
+// Therefore, platform-specific headers and code are okay here.
+
+// C includes
+#include <mach/mach_types.h>
+
+// C++ includes
+#include <mutex>
+#include <unordered_set>
+
+// Other libraries and framework includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Host/Debug.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/Pipe.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/lldb-types.h"
+
+#include "LaunchFlavor.h"
+#include "MachException.h"
+#include "NativeThreadDarwin.h"
+#include "NativeThreadListDarwin.h"
+
+namespace lldb_private {
+class Error;
+class Scalar;
+
+namespace process_darwin {
+
+/// @class NativeProcessDarwin
+/// @brief Manages communication with the inferior (debugee) process.
+///
+/// Upon construction, this class prepares and launches an inferior
+/// process for debugging.
+///
+/// Changes in the inferior process state are broadcasted.
+class NativeProcessDarwin : public NativeProcessProtocol {
+ friend Error NativeProcessProtocol::Launch(
+ ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+
+ friend Error NativeProcessProtocol::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+
+public:
+ ~NativeProcessDarwin() override;
+
+ // -----------------------------------------------------------------
+ // NativeProcessProtocol Interface
+ // -----------------------------------------------------------------
+ Error Resume(const ResumeActionList &resume_actions) override;
+
+ Error Halt() override;
+
+ Error Detach() override;
+
+ Error Signal(int signo) override;
+
+ Error Interrupt() override;
+
+ Error Kill() override;
+
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
+ Error ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
+
+ Error ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
+
+ Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ size_t &bytes_written) override;
+
+ Error AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) override;
+
+ Error DeallocateMemory(lldb::addr_t addr) override;
+
+ lldb::addr_t GetSharedLibraryInfoAddress() override;
+
+ size_t UpdateThreads() override;
+
+ bool GetArchitecture(ArchSpec &arch) const override;
+
+ Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override;
+
+ void DoStopIDBumped(uint32_t newBumpId) override;
+
+ Error GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) override;
+
+ Error GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) override;
+
+ NativeThreadDarwinSP GetThreadByID(lldb::tid_t id);
+
+ task_t GetTask() const { return m_task; }
+
+ // -----------------------------------------------------------------
+ // Interface used by NativeRegisterContext-derived classes.
+ // -----------------------------------------------------------------
+ static Error PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
+ void *data = nullptr, size_t data_size = 0,
+ long *result = nullptr);
+
+ bool SupportHardwareSingleStepping() const;
+
+protected:
+ // -----------------------------------------------------------------
+ // NativeProcessProtocol protected interface
+ // -----------------------------------------------------------------
+ Error
+ GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
+ size_t &actual_opcode_size,
+ const uint8_t *&trap_opcode_bytes) override;
+
+private:
+ // -----------------------------------------------------------------
+ /// Mach task-related Member Variables
+ // -----------------------------------------------------------------
+
+ // The task port for the inferior process.
+ mutable task_t m_task;
+
+ // True if the inferior process did an exec since we started
+ // monitoring it.
+ bool m_did_exec;
+
+ // The CPU type of this process.
+ mutable cpu_type_t m_cpu_type;
+
+ // -----------------------------------------------------------------
+ /// Exception/Signal Handling Member Variables
+ // -----------------------------------------------------------------
+
+ // Exception port on which we will receive child exceptions
+ mach_port_t m_exception_port;
+
+ // Saved state of the child exception port prior to us installing
+ // our own intercepting port.
+ MachException::PortInfo m_exc_port_info;
+
+ // The thread that runs the Mach exception read and reply handler.
+ pthread_t m_exception_thread;
+
+ // TODO see if we can remove this if we get the exception collection
+ // and distribution to happen in a single-threaded fashion.
+ std::recursive_mutex m_exception_messages_mutex;
+
+ // A collection of exception messages caught when listening to the
+ // exception port.
+ MachException::Message::collection m_exception_messages;
+
+ // When we call MachProcess::Interrupt(), we want to send this
+ // signal (if non-zero).
+ int m_sent_interrupt_signo;
+
+ // If we resume the process and still haven't received our
+ // interrupt signal (if this is non-zero).
+ int m_auto_resume_signo;
+
+ // -----------------------------------------------------------------
+ /// Thread-related Member Variables
+ // -----------------------------------------------------------------
+ NativeThreadListDarwin m_thread_list;
+ ResumeActionList m_thread_actions;
+
+ // -----------------------------------------------------------------
+ /// Process Lifetime Member Variable
+ // -----------------------------------------------------------------
+
+ // The pipe over which the waitpid thread and the main loop will
+ // communicate.
+ Pipe m_waitpid_pipe;
+
+ // The thread that runs the waitpid handler.
+ pthread_t m_waitpid_thread;
+
+ // waitpid reader callback handle.
+ MainLoop::ReadHandleUP m_waitpid_reader_handle;
+
+#if 0
+ ArchSpec m_arch;
+
+ LazyBool m_supports_mem_region;
+ std::vector<MemoryRegionInfo> m_mem_region_cache;
+
+ lldb::tid_t m_pending_notification_tid;
+
+ // List of thread ids stepping with a breakpoint with the address of
+ // the relevan breakpoint
+ std::map<lldb::tid_t, lldb::addr_t>
+ m_threads_stepping_with_breakpoint;
+#endif
+
+ // -----------------------------------------------------------------
+ // Private Instance Methods
+ // -----------------------------------------------------------------
+ NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd);
+
+ // -----------------------------------------------------------------
+ /// Finalize the launch.
+ ///
+ /// This method associates the NativeProcessDarwin instance with
+ /// the host process that was just launched. It peforms actions
+ /// like attaching a listener to the inferior exception port,
+ /// ptracing the process, and the like.
+ ///
+ /// @param[in] launch_flavor
+ /// The launch flavor that was used to launch the process.
+ ///
+ /// @param[in] main_loop
+ /// The main loop that will run the process monitor. Work
+ /// that needs to be done (e.g. reading files) gets registered
+ /// here along with callbacks to process the work.
+ ///
+ /// @return
+ /// Any error that occurred during the aforementioned
+ /// operations. Failure here will force termination of the
+ /// launched process and debugging session.
+ // -----------------------------------------------------------------
+ Error FinalizeLaunch(LaunchFlavor launch_flavor, MainLoop &main_loop);
+
+ Error SaveExceptionPortInfo();
+
+ void ExceptionMessageReceived(const MachException::Message &message);
+
+ void MaybeRaiseThreadPriority();
+
+ Error StartExceptionThread();
+
+ Error SendInferiorExitStatusToMainLoop(::pid_t pid, int status);
+
+ Error HandleWaitpidResult();
+
+ bool ProcessUsingSpringBoard() const;
+
+ bool ProcessUsingBackBoard() const;
+
+ static void *ExceptionThread(void *arg);
+
+ void *DoExceptionThread();
+
+ lldb::addr_t GetDYLDAllImageInfosAddress(Error &error) const;
+
+ static uint32_t GetCPUTypeForLocalProcess(::pid_t pid);
+
+ uint32_t GetCPUType() const;
+
+ task_t ExceptionMessageBundleComplete();
+
+ void StartSTDIOThread();
+
+ Error StartWaitpidThread(MainLoop &main_loop);
+
+ static void *WaitpidThread(void *arg);
+
+ void *DoWaitpidThread();
+
+ task_t TaskPortForProcessID(Error &error, bool force = false) const;
+
+ /// Attaches to an existing process. Forms the
+ /// implementation of Process::DoAttach.
+ void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error);
+
+ ::pid_t Attach(lldb::pid_t pid, Error &error);
+
+ Error PrivateResume();
+
+ Error ReplyToAllExceptions();
+
+ Error ResumeTask();
+
+ bool IsTaskValid() const;
+
+ bool IsTaskValid(task_t task) const;
+
+ mach_port_t GetExceptionPort() const;
+
+ bool IsExceptionPortValid() const;
+
+ Error GetTaskBasicInfo(task_t task, struct task_basic_info *info) const;
+
+ Error SuspendTask();
+
+ static Error SetDefaultPtraceOpts(const lldb::pid_t);
+
+ static void *MonitorThread(void *baton);
+
+ void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
+
+ void WaitForNewThread(::pid_t tid);
+
+ void MonitorSIGTRAP(const siginfo_t &info, NativeThreadDarwin &thread);
+
+ void MonitorTrace(NativeThreadDarwin &thread);
+
+ void MonitorBreakpoint(NativeThreadDarwin &thread);
+
+ void MonitorWatchpoint(NativeThreadDarwin &thread, uint32_t wp_index);
+
+ void MonitorSignal(const siginfo_t &info, NativeThreadDarwin &thread,
+ bool exited);
+
+ Error SetupSoftwareSingleStepping(NativeThreadDarwin &thread);
+
+#if 0
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGSEGV(const siginfo_t *info);
+
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGILL(const siginfo_t *info);
+
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGFPE(const siginfo_t *info);
+
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGBUS(const siginfo_t *info);
+#endif
+
+ bool HasThreadNoLock(lldb::tid_t thread_id);
+
+ bool StopTrackingThread(lldb::tid_t thread_id);
+
+ NativeThreadDarwinSP AddThread(lldb::tid_t thread_id);
+
+ Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
+
+ Error FixupBreakpointPCAsNeeded(NativeThreadDarwin &thread);
+
+ /// Writes a siginfo_t structure corresponding to the given thread
+ /// ID to the memory region pointed to by @p siginfo.
+ Error GetSignalInfo(lldb::tid_t tid, void *siginfo);
+
+ /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
+ /// corresponding to the given thread ID to the memory pointed to
+ /// by @p message.
+ Error GetEventMessage(lldb::tid_t tid, unsigned long *message);
+
+ void NotifyThreadDeath(lldb::tid_t tid);
+
+ Error Detach(lldb::tid_t tid);
+
+ // This method is requests a stop on all threads which are still
+ // running. It sets up a deferred delegate notification, which will
+ // fire once threads report as stopped. The triggerring_tid will be
+ // set as the current thread (main stop reason).
+ void StopRunningThreads(lldb::tid_t triggering_tid);
+
+ // Notify the delegate if all threads have stopped.
+ void SignalIfAllThreadsStopped();
+
+ // Resume the given thread, optionally passing it the given signal.
+ // The type of resume operation (continue, single-step) depends on
+ // the state parameter.
+ Error ResumeThread(NativeThreadDarwin &thread, lldb::StateType state,
+ int signo);
+
+ void ThreadWasCreated(NativeThreadDarwin &thread);
+
+ void SigchldHandler();
+};
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif /* NativeProcessDarwin_h */
diff --git a/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
new file mode 100644
index 000000000000..5e7f9ae7e6f9
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
@@ -0,0 +1,284 @@
+//===-- NativeThreadDarwin.cpp -------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeThreadDarwin.h"
+
+// C includes
+#include <libproc.h>
+
+// LLDB includes
+#include "lldb/Core/Stream.h"
+
+#include "NativeProcessDarwin.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+
+uint64_t NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
+ ::thread_t mach_port_id) {
+ thread_identifier_info_data_t tident;
+ mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
+
+ auto mach_err = ::thread_info(mach_port_id, THREAD_IDENTIFIER_INFO,
+ (thread_info_t)&tident, &tident_count);
+ if (mach_err != KERN_SUCCESS) {
+ // When we fail to get thread info for the supposed port, assume it is
+ // really a globally unique thread id already, or return the best thing
+ // we can, which is the thread port.
+ return mach_port_id;
+ }
+ return tident.thread_id;
+}
+
+NativeThreadDarwin::NativeThreadDarwin(NativeProcessDarwin *process,
+ bool is_64_bit,
+ lldb::tid_t unique_thread_id,
+ ::thread_t mach_thread_port)
+ : NativeThreadProtocol(process, unique_thread_id),
+ m_mach_thread_port(mach_thread_port), m_basic_info(),
+ m_proc_threadinfo() {}
+
+bool NativeThreadDarwin::GetIdentifierInfo() {
+ // Don't try to get the thread info once and cache it for the life of the
+ // thread. It changes over time, for instance
+ // if the thread name changes, then the thread_handle also changes... So you
+ // have to refetch it every time.
+ mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
+ kern_return_t kret = ::thread_info(m_mach_thread_port, THREAD_IDENTIFIER_INFO,
+ (thread_info_t)&m_ident_info, &count);
+ return kret == KERN_SUCCESS;
+
+ return false;
+}
+
+std::string NativeThreadDarwin::GetName() {
+ std::string name;
+
+ if (GetIdentifierInfo()) {
+ auto process_sp = GetProcess();
+ if (!process_sp) {
+ name = "<unavailable>";
+ return name;
+ }
+
+ int len = ::proc_pidinfo(process_sp->GetID(), PROC_PIDTHREADINFO,
+ m_ident_info.thread_handle, &m_proc_threadinfo,
+ sizeof(m_proc_threadinfo));
+
+ if (len && m_proc_threadinfo.pth_name[0])
+ name = m_proc_threadinfo.pth_name;
+ }
+ return name;
+}
+
+lldb::StateType NativeThreadDarwin::GetState() {
+ // TODO implement
+ return eStateInvalid;
+}
+
+bool NativeThreadDarwin::GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) {
+ // TODO implement
+ return false;
+}
+
+NativeRegisterContextSP NativeThreadDarwin::GetRegisterContext() {
+ // TODO implement
+ return NativeRegisterContextSP();
+}
+
+Error NativeThreadDarwin::SetWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, bool hardware) {
+ Error error;
+ error.SetErrorString("not yet implemented");
+ return error;
+}
+
+Error NativeThreadDarwin::RemoveWatchpoint(lldb::addr_t addr) {
+ Error error;
+ error.SetErrorString("not yet implemented");
+ return error;
+}
+
+void NativeThreadDarwin::Dump(Stream &stream) const {
+// This is what we really want once we have the thread class wired up.
+#if 0
+ DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
+ index,
+ m_seq_id,
+ m_unique_id,
+ GetPC(INVALID_NUB_ADDRESS),
+ GetSP(INVALID_NUB_ADDRESS),
+ m_basic_info.user_time.seconds, m_basic_info.user_time.microseconds,
+ m_basic_info.system_time.seconds, m_basic_info.system_time.microseconds,
+ m_basic_info.cpu_usage,
+ m_basic_info.policy,
+ m_basic_info.run_state,
+ thread_run_state,
+ m_basic_info.flags,
+ m_basic_info.suspend_count, m_suspend_count,
+ m_basic_info.sleep_time);
+
+#else
+ // Here's all we have right now.
+ stream.Printf("tid: 0x%8.8" PRIx64 ", thread port: 0x%4.4x", GetID(),
+ m_mach_thread_port);
+#endif
+}
+
+bool NativeThreadDarwin::NotifyException(MachException::Data &exc) {
+// TODO implement this.
+#if 0
+ // Allow the arch specific protocol to process (MachException::Data &)exc
+ // first before possible reassignment of m_stop_exception with exc.
+ // See also MachThread::GetStopException().
+ bool handled = m_arch_ap->NotifyException(exc);
+
+ if (m_stop_exception.IsValid())
+ {
+ // We may have more than one exception for a thread, but we need to
+ // only remember the one that we will say is the reason we stopped.
+ // We may have been single stepping and also gotten a signal exception,
+ // so just remember the most pertinent one.
+ if (m_stop_exception.IsBreakpoint())
+ m_stop_exception = exc;
+ }
+ else
+ {
+ m_stop_exception = exc;
+ }
+
+ return handled;
+#else
+ // Pretend we handled it.
+ return true;
+#endif
+}
+
+bool NativeThreadDarwin::ShouldStop(bool &step_more) const {
+// TODO: implement this
+#if 0
+ // See if this thread is at a breakpoint?
+ DNBBreakpoint *bp = CurrentBreakpoint();
+
+ if (bp)
+ {
+ // This thread is sitting at a breakpoint, ask the breakpoint
+ // if we should be stopping here.
+ return true;
+ }
+ else
+ {
+ if (m_arch_ap->StepNotComplete())
+ {
+ step_more = true;
+ return false;
+ }
+ // The thread state is used to let us know what the thread was
+ // trying to do. MachThread::ThreadWillResume() will set the
+ // thread state to various values depending if the thread was
+ // the current thread and if it was to be single stepped, or
+ // resumed.
+ if (GetState() == eStateRunning)
+ {
+ // If our state is running, then we should continue as we are in
+ // the process of stepping over a breakpoint.
+ return false;
+ }
+ else
+ {
+ // Stop if we have any kind of valid exception for this
+ // thread.
+ if (GetStopException().IsValid())
+ return true;
+ }
+ }
+ return false;
+#else
+ return false;
+#endif
+}
+
+void NativeThreadDarwin::ThreadDidStop() {
+// TODO implement this.
+#if 0
+ // This thread has existed prior to resuming under debug nub control,
+ // and has just been stopped. Do any cleanup that needs to be done
+ // after running.
+
+ // The thread state and breakpoint will still have the same values
+ // as they had prior to resuming the thread, so it makes it easy to check
+ // if we were trying to step a thread, or we tried to resume while being
+ // at a breakpoint.
+
+ // When this method gets called, the process state is still in the
+ // state it was in while running so we can act accordingly.
+ m_arch_ap->ThreadDidStop();
+
+
+ // We may have suspended this thread so the primary thread could step
+ // without worrying about race conditions, so lets restore our suspend
+ // count.
+ RestoreSuspendCountAfterStop();
+
+ // Update the basic information for a thread
+ MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);
+
+ if (m_basic_info.suspend_count > 0)
+ SetState(eStateSuspended);
+ else
+ SetState(eStateStopped);
+#endif
+}
+
+bool NativeThreadDarwin::MachPortNumberIsValid(::thread_t thread) {
+ return thread != (::thread_t)(0);
+}
+
+const struct thread_basic_info *NativeThreadDarwin::GetBasicInfo() const {
+ if (GetBasicInfo(m_mach_thread_port, &m_basic_info))
+ return &m_basic_info;
+ return NULL;
+}
+
+bool NativeThreadDarwin::GetBasicInfo(::thread_t thread,
+ struct thread_basic_info *basicInfoPtr) {
+ if (MachPortNumberIsValid(thread)) {
+ unsigned int info_count = THREAD_BASIC_INFO_COUNT;
+ kern_return_t err = ::thread_info(thread, THREAD_BASIC_INFO,
+ (thread_info_t)basicInfoPtr, &info_count);
+ if (err == KERN_SUCCESS)
+ return true;
+ }
+ ::memset(basicInfoPtr, 0, sizeof(struct thread_basic_info));
+ return false;
+}
+
+bool NativeThreadDarwin::IsUserReady() const {
+ if (m_basic_info.run_state == 0)
+ GetBasicInfo();
+
+ switch (m_basic_info.run_state) {
+ default:
+ case TH_STATE_UNINTERRUPTIBLE:
+ break;
+
+ case TH_STATE_RUNNING:
+ case TH_STATE_STOPPED:
+ case TH_STATE_WAITING:
+ case TH_STATE_HALTED:
+ return true;
+ }
+ return false;
+}
+
+NativeProcessDarwinSP NativeThreadDarwin::GetNativeProcessDarwinSP() {
+ return std::static_pointer_cast<NativeProcessDarwin>(GetProcess());
+}
diff --git a/source/Plugins/Process/Darwin/NativeThreadDarwin.h b/source/Plugins/Process/Darwin/NativeThreadDarwin.h
new file mode 100644
index 000000000000..b8d9089e673e
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadDarwin.h
@@ -0,0 +1,178 @@
+//===-- NativeThreadDarwin.h ---------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef NativeThreadDarwin_H
+#define NativeThreadDarwin_H
+
+// C includes
+#include <mach/mach_types.h>
+#include <sched.h>
+#include <sys/proc_info.h>
+
+// C++ includes
+#include <map>
+#include <memory>
+#include <string>
+
+// LLDB includes
+#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/lldb-private-forward.h"
+
+#include "MachException.h"
+
+namespace lldb_private {
+namespace process_darwin {
+
+class NativeProcessDarwin;
+using NativeProcessDarwinSP = std::shared_ptr<NativeProcessDarwin>;
+
+class NativeThreadListDarwin;
+
+class NativeThreadDarwin : public NativeThreadProtocol {
+ friend class NativeProcessDarwin;
+ friend class NativeThreadListDarwin;
+
+public:
+ static uint64_t
+ GetGloballyUniqueThreadIDForMachPortID(::thread_t mach_port_id);
+
+ NativeThreadDarwin(NativeProcessDarwin *process, bool is_64_bit,
+ lldb::tid_t unique_thread_id = 0,
+ ::thread_t mach_thread_port = 0);
+
+ // -----------------------------------------------------------------
+ // NativeThreadProtocol Interface
+ // -----------------------------------------------------------------
+ std::string GetName() override;
+
+ lldb::StateType GetState() override;
+
+ bool GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) override;
+
+ NativeRegisterContextSP GetRegisterContext() override;
+
+ Error SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
+ bool hardware) override;
+
+ Error RemoveWatchpoint(lldb::addr_t addr) override;
+
+ // -----------------------------------------------------------------
+ // New methods that are fine for others to call.
+ // -----------------------------------------------------------------
+ void Dump(Stream &stream) const;
+
+private:
+ // -----------------------------------------------------------------
+ // Interface for friend classes
+ // -----------------------------------------------------------------
+
+ /// Resumes the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error Resume(uint32_t signo);
+
+ /// Single steps the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error SingleStep(uint32_t signo);
+
+ bool NotifyException(MachException::Data &exc);
+
+ bool ShouldStop(bool &step_more) const;
+
+ void ThreadDidStop();
+
+ void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
+
+ /// Return true if the thread is stopped.
+ /// If stopped by a signal, indicate the signo in the signo
+ /// argument. Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
+ bool IsStopped(int *signo);
+
+ const struct thread_basic_info *GetBasicInfo() const;
+
+ static bool GetBasicInfo(::thread_t thread,
+ struct thread_basic_info *basicInfoPtr);
+
+ bool IsUserReady() const;
+
+ void SetStoppedByExec();
+
+ void SetStoppedByBreakpoint();
+
+ void SetStoppedByWatchpoint(uint32_t wp_index);
+
+ bool IsStoppedAtBreakpoint();
+
+ bool IsStoppedAtWatchpoint();
+
+ void SetStoppedByTrace();
+
+ void SetStoppedWithNoReason();
+
+ void SetExited();
+
+ Error RequestStop();
+
+ // -------------------------------------------------------------------------
+ /// Return the mach thread port number for this thread.
+ ///
+ /// @return
+ /// The mach port number for this thread. Returns NULL_THREAD
+ /// when the thread is invalid.
+ // -------------------------------------------------------------------------
+ thread_t GetMachPortNumber() const { return m_mach_thread_port; }
+
+ static bool MachPortNumberIsValid(::thread_t thread);
+
+ // ---------------------------------------------------------------------
+ // Private interface
+ // ---------------------------------------------------------------------
+ bool GetIdentifierInfo();
+
+ void MaybeLogStateChange(lldb::StateType new_state);
+
+ NativeProcessDarwinSP GetNativeProcessDarwinSP();
+
+ void SetStopped();
+
+ inline void MaybePrepareSingleStepWorkaround();
+
+ inline void MaybeCleanupSingleStepWorkaround();
+
+ // -----------------------------------------------------------------
+ // Member Variables
+ // -----------------------------------------------------------------
+
+ // The mach thread port for the thread.
+ ::thread_t m_mach_thread_port;
+
+ // The most recently-retrieved thread basic info.
+ mutable ::thread_basic_info m_basic_info;
+
+ struct proc_threadinfo m_proc_threadinfo;
+
+ thread_identifier_info_data_t m_ident_info;
+
+#if 0
+ lldb::StateType m_state;
+ ThreadStopInfo m_stop_info;
+ NativeRegisterContextSP m_reg_context_sp;
+ std::string m_stop_description;
+ using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
+ WatchpointIndexMap m_watchpoint_index_map;
+ // cpu_set_t m_original_cpu_set; // For single-step workaround.
+#endif
+};
+
+typedef std::shared_ptr<NativeThreadDarwin> NativeThreadDarwinSP;
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif // #ifndef NativeThreadDarwin_H
diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
new file mode 100644
index 000000000000..aa9b04157658
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
@@ -0,0 +1,698 @@
+//===-- NativeThreadListDarwin.cpp ------------------------------------*- C++
+//-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/19/07.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeThreadListDarwin.h"
+
+// C includes
+#include <inttypes.h>
+#include <mach/vm_map.h>
+#include <sys/sysctl.h>
+
+// LLDB includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "NativeProcessDarwin.h"
+#include "NativeThreadDarwin.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+
+NativeThreadListDarwin::NativeThreadListDarwin()
+ : m_threads(), m_threads_mutex(), m_is_64_bit(false) {}
+
+NativeThreadListDarwin::~NativeThreadListDarwin() {}
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+nub_state_t
+NativeThreadListDarwin::GetState(nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetState();
+ return eStateInvalid;
+}
+
+const char *
+NativeThreadListDarwin::GetName (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetName();
+ return NULL;
+}
+#endif
+
+// TODO: figure out if we need to add this to NativeThreadDarwin yet.
+#if 0
+ThreadInfo::QoS
+NativeThreadListDarwin::GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetRequestedQoS(tsd, dti_qos_class_index);
+ return ThreadInfo::QoS();
+}
+
+nub_addr_t
+NativeThreadListDarwin::GetPThreadT (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetPThreadT();
+ return INVALID_NUB_ADDRESS;
+}
+
+nub_addr_t
+NativeThreadListDarwin::GetDispatchQueueT (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetDispatchQueueT();
+ return INVALID_NUB_ADDRESS;
+}
+
+nub_addr_t
+NativeThreadListDarwin::GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetTSDAddressForThread(plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
+ return INVALID_NUB_ADDRESS;
+}
+#endif
+
+// TODO implement these
+#if 0
+nub_thread_t
+NativeThreadListDarwin::SetCurrentThread(nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ {
+ m_current_thread = thread_sp;
+ return tid;
+ }
+ return INVALID_NUB_THREAD;
+}
+
+
+bool
+NativeThreadListDarwin::GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetStopException().GetStopInfo(stop_info);
+ return false;
+}
+
+bool
+NativeThreadListDarwin::GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info)
+{
+ thread_t mach_port_number = GetMachPortNumberByThreadID (tid);
+
+ mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
+ return ::thread_info (mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
+}
+
+void
+NativeThreadListDarwin::DumpThreadStoppedReason (nub_thread_t tid) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ thread_sp->GetStopException().DumpStopReason();
+}
+
+const char *
+NativeThreadListDarwin::GetThreadInfo (nub_thread_t tid) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetBasicInfoAsString();
+ return NULL;
+}
+
+#endif
+
+NativeThreadDarwinSP
+NativeThreadListDarwin::GetThreadByID(lldb::tid_t tid) const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && (thread_sp->GetID() == tid))
+ return thread_sp;
+ }
+ return NativeThreadDarwinSP();
+}
+
+NativeThreadDarwinSP NativeThreadListDarwin::GetThreadByMachPortNumber(
+ ::thread_t mach_port_number) const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
+ return thread_sp;
+ }
+ return NativeThreadDarwinSP();
+}
+
+lldb::tid_t NativeThreadListDarwin::GetThreadIDByMachPortNumber(
+ ::thread_t mach_port_number) const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
+ return thread_sp->GetID();
+ }
+ return LLDB_INVALID_THREAD_ID;
+}
+
+// TODO implement
+#if 0
+thread_t
+NativeThreadListDarwin::GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->ThreadID() == globally_unique_id)
+ {
+ return m_threads[idx]->MachPortNumber();
+ }
+ }
+ return 0;
+}
+
+bool
+NativeThreadListDarwin::GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value ) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetRegisterValue(set, reg, reg_value);
+
+ return false;
+}
+
+bool
+NativeThreadListDarwin::SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *reg_value ) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->SetRegisterValue(set, reg, reg_value);
+
+ return false;
+}
+
+nub_size_t
+NativeThreadListDarwin::GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetRegisterContext (buf, buf_len);
+ return 0;
+}
+
+nub_size_t
+NativeThreadListDarwin::SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->SetRegisterContext (buf, buf_len);
+ return 0;
+}
+
+uint32_t
+NativeThreadListDarwin::SaveRegisterState (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->SaveRegisterState ();
+ return 0;
+}
+
+bool
+NativeThreadListDarwin::RestoreRegisterState (nub_thread_t tid, uint32_t save_id)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->RestoreRegisterState (save_id);
+ return 0;
+}
+#endif
+
+size_t NativeThreadListDarwin::GetNumberOfThreads() const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ return static_cast<size_t>(m_threads.size());
+}
+
+// TODO implement
+#if 0
+nub_thread_t
+NativeThreadListDarwin::ThreadIDAtIndex (nub_size_t idx) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ if (idx < m_threads.size())
+ return m_threads[idx]->ThreadID();
+ return INVALID_NUB_THREAD;
+}
+
+nub_thread_t
+NativeThreadListDarwin::CurrentThreadID ( )
+{
+ MachThreadSP thread_sp;
+ CurrentThread(thread_sp);
+ if (thread_sp.get())
+ return thread_sp->ThreadID();
+ return INVALID_NUB_THREAD;
+}
+
+#endif
+
+bool NativeThreadListDarwin::NotifyException(MachException::Data &exc) {
+ auto thread_sp = GetThreadByMachPortNumber(exc.thread_port);
+ if (thread_sp) {
+ thread_sp->NotifyException(exc);
+ return true;
+ }
+ return false;
+}
+
+void NativeThreadListDarwin::Clear() {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ m_threads.clear();
+}
+
+uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
+ bool update,
+ collection *new_threads) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ if (log)
+ log->Printf("NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = "
+ "%u) process stop count = %u",
+ __FUNCTION__, process.GetID(), update, process.GetStopID());
+
+ if (process.GetStopID() == 0) {
+ // On our first stop, we'll record details like 32/64 bitness and
+ // select the proper architecture implementation.
+ //
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)process.GetID()};
+
+ struct kinfo_proc processInfo;
+ size_t bufsize = sizeof(processInfo);
+ if ((sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo,
+ &bufsize, NULL, 0) == 0) &&
+ (bufsize > 0)) {
+ if (processInfo.kp_proc.p_flag & P_LP64)
+ m_is_64_bit = true;
+ }
+
+// TODO implement architecture selection and abstraction.
+#if 0
+#if defined(__i386__) || defined(__x86_64__)
+ if (m_is_64_bit)
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_X86_64);
+ else
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_I386);
+#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ if (m_is_64_bit)
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM64);
+ else
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM);
+#endif
+#endif
+ }
+
+ if (m_threads.empty() || update) {
+ thread_array_t thread_list = nullptr;
+ mach_msg_type_number_t thread_list_count = 0;
+ task_t task = process.GetTask();
+
+ Error error;
+ auto mach_err = ::task_threads(task, &thread_list, &thread_list_count);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("::task_threads(task = 0x%4.4x, thread_list => %p, "
+ "thread_list_count => %u) failed: %u (%s)",
+ task, thread_list, thread_list_count, error.GetError(),
+ error.AsCString());
+ return 0;
+ }
+
+ if (thread_list_count > 0) {
+ collection currThreads;
+ size_t idx;
+ // Iterator through the current thread list and see which threads
+ // we already have in our list (keep them), which ones we don't
+ // (add them), and which ones are not around anymore (remove them).
+ for (idx = 0; idx < thread_list_count; ++idx) {
+ // Get the Mach thread port.
+ const ::thread_t mach_port_num = thread_list[idx];
+
+ // Get the unique thread id for the mach port number.
+ uint64_t unique_thread_id =
+ NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
+ mach_port_num);
+
+ // Retrieve the thread if it exists.
+ auto thread_sp = GetThreadByID(unique_thread_id);
+ if (thread_sp) {
+ // We are already tracking it. Keep the existing native
+ // thread instance.
+ currThreads.push_back(thread_sp);
+ } else {
+ // We don't have a native thread instance for this thread.
+ // Create it now.
+ thread_sp.reset(new NativeThreadDarwin(
+ &process, m_is_64_bit, unique_thread_id, mach_port_num));
+
+ // Add the new thread regardless of its is user ready state.
+ // Make sure the thread is ready to be displayed and shown
+ // to users before we add this thread to our list...
+ if (thread_sp->IsUserReady()) {
+ if (new_threads)
+ new_threads->push_back(thread_sp);
+
+ currThreads.push_back(thread_sp);
+ }
+ }
+ }
+
+ m_threads.swap(currThreads);
+ m_current_thread.reset();
+
+ // Free the vm memory given to us by ::task_threads()
+ vm_size_t thread_list_size =
+ (vm_size_t)(thread_list_count * sizeof(::thread_t));
+ ::vm_deallocate(::mach_task_self(), (vm_address_t)thread_list,
+ thread_list_size);
+ }
+ }
+ return static_cast<uint32_t>(m_threads.size());
+}
+
+// TODO implement
+#if 0
+
+void
+NativeThreadListDarwin::CurrentThread (MachThreadSP& thread_sp)
+{
+ // locker will keep a mutex locked until it goes out of scope
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ if (m_current_thread.get() == NULL)
+ {
+ // Figure out which thread is going to be our current thread.
+ // This is currently done by finding the first thread in the list
+ // that has a valid exception.
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->GetStopException().IsValid())
+ {
+ m_current_thread = m_threads[idx];
+ break;
+ }
+ }
+ }
+ thread_sp = m_current_thread;
+}
+
+#endif
+
+void NativeThreadListDarwin::Dump(Stream &stream) const {
+ bool first = true;
+
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp) {
+ // Handle newlines between thread entries.
+ if (first)
+ first = false;
+ else
+ stream.PutChar('\n');
+ thread_sp->Dump(stream);
+ }
+ }
+}
+
+void NativeThreadListDarwin::ProcessWillResume(
+ NativeProcessDarwin &process, const ResumeActionList &thread_actions) {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+
+ // Update our thread list, because sometimes libdispatch or the kernel
+ // will spawn threads while a task is suspended.
+ NativeThreadListDarwin::collection new_threads;
+
+// TODO implement this.
+#if 0
+ // First figure out if we were planning on running only one thread, and if
+ // so, force that thread to resume.
+ bool run_one_thread;
+ thread_t solo_thread = THREAD_NULL;
+ if ((thread_actions.GetSize() > 0) &&
+ (thread_actions.NumActionsWithState(eStateStepping) +
+ thread_actions.NumActionsWithState (eStateRunning) == 1))
+ {
+ run_one_thread = true;
+ const DNBThreadResumeAction *action_ptr = thread_actions.GetFirst();
+ size_t num_actions = thread_actions.GetSize();
+ for (size_t i = 0; i < num_actions; i++, action_ptr++)
+ {
+ if (action_ptr->state == eStateStepping || action_ptr->state == eStateRunning)
+ {
+ solo_thread = action_ptr->tid;
+ break;
+ }
+ }
+ }
+ else
+ run_one_thread = false;
+#endif
+
+ UpdateThreadList(process, true, &new_threads);
+
+#if 0
+ DNBThreadResumeAction resume_new_threads = { -1U, eStateRunning, 0, INVALID_NUB_ADDRESS };
+ // If we are planning to run only one thread, any new threads should be suspended.
+ if (run_one_thread)
+ resume_new_threads.state = eStateSuspended;
+
+ const size_t num_new_threads = new_threads.size();
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ MachThread *thread = m_threads[idx].get();
+ bool handled = false;
+ for (uint32_t new_idx = 0; new_idx < num_new_threads; ++new_idx)
+ {
+ if (thread == new_threads[new_idx].get())
+ {
+ thread->ThreadWillResume(&resume_new_threads);
+ handled = true;
+ break;
+ }
+ }
+
+ if (!handled)
+ {
+ const DNBThreadResumeAction *thread_action = thread_actions.GetActionForThread (thread->ThreadID(), true);
+ // There must always be a thread action for every thread.
+ assert (thread_action);
+ bool others_stopped = false;
+ if (solo_thread == thread->ThreadID())
+ others_stopped = true;
+ thread->ThreadWillResume (thread_action, others_stopped);
+ }
+ }
+
+ if (new_threads.size())
+ {
+ for (uint32_t idx = 0; idx < num_new_threads; ++idx)
+ {
+ DNBLogThreadedIf (LOG_THREAD, "NativeThreadListDarwin::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%8.8" PRIx64 ", thread-is-user-ready=%i)",
+ process->ProcessID(),
+ process->StopCount(),
+ new_threads[idx]->ThreadID(),
+ new_threads[idx]->IsUserReady());
+ }
+ }
+#endif
+}
+
+uint32_t NativeThreadListDarwin::ProcessDidStop(NativeProcessDarwin &process) {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+
+ // Update our thread list.
+ UpdateThreadList(process, true);
+
+ for (auto thread_sp : m_threads) {
+ if (thread_sp)
+ thread_sp->ThreadDidStop();
+ }
+ return (uint32_t)m_threads.size();
+}
+
+//----------------------------------------------------------------------
+// Check each thread in our thread list to see if we should notify our
+// client of the current halt in execution.
+//
+// Breakpoints can have callback functions associated with them than
+// can return true to stop, or false to continue executing the inferior.
+//
+// RETURNS
+// true if we should stop and notify our clients
+// false if we should resume our child process and skip notification
+//----------------------------------------------------------------------
+bool NativeThreadListDarwin::ShouldStop(bool &step_more) {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && thread_sp->ShouldStop(step_more))
+ return true;
+ }
+ return false;
+}
+
+// Implement.
+#if 0
+
+void
+NativeThreadListDarwin::NotifyBreakpointChanged (const DNBBreakpoint *bp)
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ m_threads[idx]->NotifyBreakpointChanged(bp);
+ }
+}
+
+
+uint32_t
+NativeThreadListDarwin::EnableHardwareBreakpoint (const DNBBreakpoint* bp) const
+{
+ if (bp != NULL)
+ {
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->EnableHardwareBreakpoint(bp);
+ }
+ return INVALID_NUB_HW_INDEX;
+}
+
+bool
+NativeThreadListDarwin::DisableHardwareBreakpoint (const DNBBreakpoint* bp) const
+{
+ if (bp != NULL)
+ {
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->DisableHardwareBreakpoint(bp);
+ }
+ return false;
+}
+
+// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() -> MachProcess::EnableWatchpoint()
+// -> NativeThreadListDarwin::EnableHardwareWatchpoint().
+uint32_t
+NativeThreadListDarwin::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const
+{
+ uint32_t hw_index = INVALID_NUB_HW_INDEX;
+ if (wp != NULL)
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+ // On Mac OS X we have to prime the control registers for new threads. We do this
+ // using the control register data for the first thread, for lack of a better way of choosing.
+ bool also_set_on_task = true;
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task)) == INVALID_NUB_HW_INDEX)
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
+ return INVALID_NUB_HW_INDEX;
+ }
+ also_set_on_task = false;
+ }
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
+ }
+ return hw_index;
+}
+
+bool
+NativeThreadListDarwin::DisableHardwareWatchpoint (const DNBBreakpoint* wp) const
+{
+ if (wp != NULL)
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+
+ // On Mac OS X we have to prime the control registers for new threads. We do this
+ // using the control register data for the first thread, for lack of a better way of choosing.
+ bool also_set_on_task = true;
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task))
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
+ return false;
+ }
+ also_set_on_task = false;
+ }
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
+ return true;
+ }
+ return false;
+}
+
+uint32_t
+NativeThreadListDarwin::NumSupportedHardwareWatchpoints () const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+ // Use an arbitrary thread to retrieve the number of supported hardware watchpoints.
+ if (num_threads)
+ return m_threads[0]->NumSupportedHardwareWatchpoints();
+ return 0;
+}
+
+uint32_t
+NativeThreadListDarwin::GetThreadIndexForThreadStoppedWithSignal (const int signo) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ uint32_t should_stop = false;
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->GetStopException().SoftSignal () == signo)
+ return idx;
+ }
+ return UINT32_MAX;
+}
+
+#endif
diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.h b/source/Plugins/Process/Darwin/NativeThreadListDarwin.h
new file mode 100644
index 000000000000..2b194bcc1537
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.h
@@ -0,0 +1,139 @@
+//===-- NativeThreadListDarwin.h --------------------------------------*- C++
+//-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/19/07.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __NativeThreadListDarwin_h__
+#define __NativeThreadListDarwin_h__
+
+#include <memory>
+#include <mutex>
+#include <vector>
+
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-types.h"
+
+#include "MachException.h"
+
+// #include "ThreadInfo.h"
+
+namespace lldb_private {
+namespace process_darwin {
+
+class NativeBreakpointDarwin;
+class NativeProcessDarwin;
+
+class NativeThreadDarwin;
+using NativeThreadDarwinSP = std::shared_ptr<NativeThreadDarwin>;
+
+class NativeThreadListDarwin {
+public:
+ NativeThreadListDarwin();
+ ~NativeThreadListDarwin();
+
+ void Clear();
+
+ void Dump(Stream &stream) const;
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+ bool GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value) const;
+ bool SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *reg_value) const;
+ nub_size_t GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len);
+ nub_size_t SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len);
+ uint32_t SaveRegisterState (nub_thread_t tid);
+ bool RestoreRegisterState (nub_thread_t tid, uint32_t save_id);
+#endif
+
+ const char *GetThreadInfo(lldb::tid_t tid) const;
+
+ void ProcessWillResume(NativeProcessDarwin &process,
+ const ResumeActionList &thread_actions);
+
+ uint32_t ProcessDidStop(NativeProcessDarwin &process);
+
+ bool NotifyException(MachException::Data &exc);
+
+ bool ShouldStop(bool &step_more);
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+ const char * GetName (nub_thread_t tid);
+ nub_state_t GetState (nub_thread_t tid);
+ nub_thread_t SetCurrentThread (nub_thread_t tid);
+#endif
+
+// TODO: figure out if we need to add this to NativeThreadDarwin yet.
+#if 0
+ ThreadInfo::QoS GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index);
+ nub_addr_t GetPThreadT (nub_thread_t tid);
+ nub_addr_t GetDispatchQueueT (nub_thread_t tid);
+ nub_addr_t GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size);
+#endif
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+ bool GetThreadStoppedReason (nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const;
+ void DumpThreadStoppedReason (nub_thread_t tid) const;
+ bool GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info);
+#endif
+
+ size_t GetNumberOfThreads() const;
+
+ lldb::tid_t ThreadIDAtIndex(size_t idx) const;
+
+ lldb::tid_t GetCurrentThreadID();
+
+ NativeThreadDarwinSP GetCurrentThread();
+
+ void NotifyBreakpointChanged(const NativeBreakpointDarwin *bp);
+
+ uint32_t EnableHardwareBreakpoint(const NativeBreakpointDarwin *bp) const;
+
+ bool DisableHardwareBreakpoint(const NativeBreakpointDarwin *bp) const;
+
+ uint32_t EnableHardwareWatchpoint(const NativeBreakpointDarwin *wp) const;
+
+ bool DisableHardwareWatchpoint(const NativeBreakpointDarwin *wp) const;
+
+ uint32_t GetNumberOfSupportedHardwareWatchpoints() const;
+
+ size_t GetThreadIndexForThreadStoppedWithSignal(const int signo) const;
+
+ NativeThreadDarwinSP GetThreadByID(lldb::tid_t tid) const;
+
+ NativeThreadDarwinSP
+ GetThreadByMachPortNumber(::thread_t mach_port_number) const;
+
+ lldb::tid_t GetThreadIDByMachPortNumber(::thread_t mach_port_number) const;
+
+ thread_t GetMachPortNumberByThreadID(lldb::tid_t globally_unique_id) const;
+
+protected:
+ typedef std::vector<NativeThreadDarwinSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ // Consider having this return an lldb_private::Error.
+ uint32_t UpdateThreadList(NativeProcessDarwin &process, bool update,
+ collection *num_threads = nullptr);
+
+ collection m_threads;
+ mutable std::recursive_mutex m_threads_mutex;
+ NativeThreadDarwinSP m_current_thread;
+ bool m_is_64_bit;
+};
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif // #ifndef __NativeThreadListDarwin_h__
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index 3cb1cec6983f..0b09296cb7fd 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -16,684 +16,603 @@
#include "lldb/Target/UnixSignals.h"
// Project includes
-#include "lldb/Breakpoint/Watchpoint.h"
+#include "FreeBSDThread.h"
+#include "POSIXStopInfo.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/UnwindLLDB.h"
+#include "ProcessFreeBSD.h"
+#include "ProcessMonitor.h"
+#include "ProcessPOSIXLog.h"
+#include "RegisterContextPOSIXProcessMonitor_arm.h"
+#include "RegisterContextPOSIXProcessMonitor_arm64.h"
+#include "RegisterContextPOSIXProcessMonitor_mips64.h"
+#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
+#include "RegisterContextPOSIXProcessMonitor_x86.h"
#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/HostNativeThread.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/HostNativeThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
#include "llvm/ADT/SmallString.h"
-#include "POSIXStopInfo.h"
-#include "FreeBSDThread.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessPOSIXLog.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
-#include "RegisterContextPOSIXProcessMonitor_arm64.h"
-#include "RegisterContextPOSIXProcessMonitor_mips64.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
-#include "Plugins/Process/Utility/UnwindLLDB.h"
using namespace lldb;
using namespace lldb_private;
FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
- : Thread(process, tid),
- m_frame_ap (),
- m_breakpoint (),
- m_thread_name_valid (false),
- m_thread_name (),
- m_posix_thread(NULL)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("FreeBSDThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
-
- // Set the current watchpoints for this thread.
- Target &target = GetProcess()->GetTarget();
- const WatchpointList &wp_list = target.GetWatchpointList();
- size_t wp_size = wp_list.GetSize();
-
- for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++)
- {
- lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
- if (wp.get() && wp->IsEnabled())
- {
- // This watchpoint as been enabled; obviously this "new" thread
- // has been created since that watchpoint was enabled. Since
- // the POSIXBreakpointProtocol has yet to be initialized, its
- // m_watchpoints_initialized member will be FALSE. Attempting to
- // read the debug status register to determine if a watchpoint
- // has been hit would result in the zeroing of that register.
- // Since the active debug registers would have been cloned when
- // this thread was created, simply force the m_watchpoints_initized
- // member to TRUE and avoid resetting dr6 and dr7.
- GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
- }
+ : Thread(process, tid), m_frame_ap(), m_breakpoint(),
+ m_thread_name_valid(false), m_thread_name(), m_posix_thread(NULL) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("FreeBSDThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
+
+ // Set the current watchpoints for this thread.
+ Target &target = GetProcess()->GetTarget();
+ const WatchpointList &wp_list = target.GetWatchpointList();
+ size_t wp_size = wp_list.GetSize();
+
+ for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) {
+ lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
+ if (wp.get() && wp->IsEnabled()) {
+ // This watchpoint as been enabled; obviously this "new" thread
+ // has been created since that watchpoint was enabled. Since
+ // the POSIXBreakpointProtocol has yet to be initialized, its
+ // m_watchpoints_initialized member will be FALSE. Attempting to
+ // read the debug status register to determine if a watchpoint
+ // has been hit would result in the zeroing of that register.
+ // Since the active debug registers would have been cloned when
+ // this thread was created, simply force the m_watchpoints_initized
+ // member to TRUE and avoid resetting dr6 and dr7.
+ GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
}
+ }
}
-FreeBSDThread::~FreeBSDThread()
-{
- DestroyThread();
-}
+FreeBSDThread::~FreeBSDThread() { DestroyThread(); }
-ProcessMonitor &
-FreeBSDThread::GetMonitor()
-{
- ProcessSP base = GetProcess();
- ProcessFreeBSD &process = static_cast<ProcessFreeBSD&>(*base);
- return process.GetMonitor();
+ProcessMonitor &FreeBSDThread::GetMonitor() {
+ ProcessSP base = GetProcess();
+ ProcessFreeBSD &process = static_cast<ProcessFreeBSD &>(*base);
+ return process.GetMonitor();
}
-void
-FreeBSDThread::RefreshStateAfterStop()
-{
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The KDPRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
- //if (StateIsStoppedState(GetState())
- {
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded (force);
- }
+void FreeBSDThread::RefreshStateAfterStop() {
+ // Invalidate all registers in our register context. We don't set "force" to
+ // true because the stop reply packet might have had some register values
+ // that were expedited and these will already be copied into the register
+ // context by the time this function gets called. The KDPRegisterContext
+ // class has been made smart enough to detect when it needs to invalidate
+ // which registers are valid by putting hooks in the register read and
+ // register supply functions where they check the process stop ID and do
+ // the right thing.
+ // if (StateIsStoppedState(GetState())
+ {
+ const bool force = false;
+ GetRegisterContext()->InvalidateIfNeeded(force);
+ }
}
-const char *
-FreeBSDThread::GetInfo()
-{
- return NULL;
-}
+const char *FreeBSDThread::GetInfo() { return NULL; }
-void
-FreeBSDThread::SetName (const char *name)
-{
- m_thread_name_valid = (name && name[0]);
- if (m_thread_name_valid)
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
+void FreeBSDThread::SetName(const char *name) {
+ m_thread_name_valid = (name && name[0]);
+ if (m_thread_name_valid)
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
}
-const char *
-FreeBSDThread::GetName ()
-{
- if (!m_thread_name_valid)
- {
- llvm::SmallString<32> thread_name;
- HostNativeThread::GetName(GetID(), thread_name);
- m_thread_name = thread_name.c_str();
- m_thread_name_valid = true;
- }
+const char *FreeBSDThread::GetName() {
+ if (!m_thread_name_valid) {
+ llvm::SmallString<32> thread_name;
+ HostNativeThread::GetName(GetID(), thread_name);
+ m_thread_name = thread_name.c_str();
+ m_thread_name_valid = true;
+ }
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
}
-lldb::RegisterContextSP
-FreeBSDThread::GetRegisterContext()
-{
- if (!m_reg_context_sp)
- {
- m_posix_thread = NULL;
-
- RegisterInfoInterface *reg_interface = NULL;
- const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
-
- assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextFreeBSD_arm64(target_arch);
- break;
- case llvm::Triple::arm:
- reg_interface = new RegisterContextFreeBSD_arm(target_arch);
- break;
- case llvm::Triple::ppc:
+lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
+ if (!m_reg_context_sp) {
+ m_posix_thread = NULL;
+
+ RegisterInfoInterface *reg_interface = NULL;
+ const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
+
+ assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(target_arch);
+ break;
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextFreeBSD_arm(target_arch);
+ break;
+ case llvm::Triple::ppc:
#ifndef __powerpc64__
- reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
- break;
+ reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
+ break;
#endif
- case llvm::Triple::ppc64:
- reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
- break;
- case llvm::Triple::mips64:
- reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
- break;
- case llvm::Triple::x86:
- reg_interface = new RegisterContextFreeBSD_i386(target_arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
- break;
- default:
- llvm_unreachable("CPU not supported");
- }
+ case llvm::Triple::ppc64:
+ reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
+ break;
+ case llvm::Triple::mips64:
+ reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextFreeBSD_i386(target_arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
+ break;
+ default:
+ llvm_unreachable("CPU not supported");
+ }
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- {
- RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::arm:
- {
- RegisterContextPOSIXProcessMonitor_arm *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::mips64:
- {
- RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- {
- RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx = new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- default:
- break;
- }
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64: {
+ RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ case llvm::Triple::arm: {
+ RegisterContextPOSIXProcessMonitor_arm *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
}
- return m_reg_context_sp;
+ case llvm::Triple::mips64: {
+ RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_mips64(*this, 0,
+ reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64: {
+ RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0,
+ reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64: {
+ RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0,
+ reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("FreeBSDThread::%s ()", __FUNCTION__);
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex();
-
- if (concrete_frame_idx == 0)
- reg_ctx_sp = GetRegisterContext();
- else
- {
- assert(GetUnwinder());
- reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
- }
+FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
- return reg_ctx_sp;
-}
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("FreeBSDThread::%s ()", __FUNCTION__);
-lldb::addr_t
-FreeBSDThread::GetThreadPointer ()
-{
- ProcessMonitor &monitor = GetMonitor();
- addr_t addr;
- if (monitor.ReadThreadPointer (GetID(), addr))
- return addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
-bool
-FreeBSDThread::CalculateStopInfo()
-{
- SetStopInfo (m_stop_info_sp);
- return true;
-}
-
-Unwind *
-FreeBSDThread::GetUnwinder()
-{
- if (m_unwinder_ap.get() == NULL)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
+ if (concrete_frame_idx == 0)
+ reg_ctx_sp = GetRegisterContext();
+ else {
+ assert(GetUnwinder());
+ reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
+ }
- return m_unwinder_ap.get();
+ return reg_ctx_sp;
}
-void
-FreeBSDThread::DidStop()
-{
- // Don't set the thread state to stopped unless we really stopped.
+lldb::addr_t FreeBSDThread::GetThreadPointer() {
+ ProcessMonitor &monitor = GetMonitor();
+ addr_t addr;
+ if (monitor.ReadThreadPointer(GetID(), addr))
+ return addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
-void
-FreeBSDThread::WillResume(lldb::StateType resume_state)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf("tid %lu resume_state = %s", GetID(),
- lldb_private::StateAsCString(resume_state));
- ProcessSP process_sp(GetProcess());
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
- int signo = GetResumeSignal();
- bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
-
- switch (resume_state)
- {
- case eStateSuspended:
- case eStateStopped:
- process->m_suspend_tids.push_back(GetID());
- break;
- case eStateRunning:
- process->m_run_tids.push_back(GetID());
- if (signo_valid)
- process->m_resume_signo = signo;
- break;
- case eStateStepping:
- process->m_step_tids.push_back(GetID());
- if (signo_valid)
- process->m_resume_signo = signo;
- break;
- default:
- break;
- }
+bool FreeBSDThread::CalculateStopInfo() {
+ SetStopInfo(m_stop_info_sp);
+ return true;
}
-bool
-FreeBSDThread::Resume()
-{
- lldb::StateType resume_state = GetResumeState();
- ProcessMonitor &monitor = GetMonitor();
- bool status;
+Unwind *FreeBSDThread::GetUnwinder() {
+ if (m_unwinder_ap.get() == NULL)
+ m_unwinder_ap.reset(new UnwindLLDB(*this));
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf ("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
- StateAsCString(resume_state));
-
- switch (resume_state)
- {
- default:
- assert(false && "Unexpected state for resume!");
- status = false;
- break;
-
- case lldb::eStateRunning:
- SetState(resume_state);
- status = monitor.Resume(GetID(), GetResumeSignal());
- break;
-
- case lldb::eStateStepping:
- SetState(resume_state);
- status = monitor.SingleStep(GetID(), GetResumeSignal());
- break;
- case lldb::eStateStopped:
- case lldb::eStateSuspended:
- status = true;
- break;
- }
-
- return status;
+ return m_unwinder_ap.get();
}
-void
-FreeBSDThread::Notify(const ProcessMessage &message)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf ("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
- __FUNCTION__, message.PrintKind(), GetID());
-
- switch (message.GetKind())
- {
- default:
- assert(false && "Unexpected message kind!");
- break;
-
- case ProcessMessage::eExitMessage:
- // Nothing to be done.
- break;
-
- case ProcessMessage::eLimboMessage:
- LimboNotify(message);
- break;
-
- case ProcessMessage::eSignalMessage:
- SignalNotify(message);
- break;
-
- case ProcessMessage::eSignalDeliveredMessage:
- SignalDeliveredNotify(message);
- break;
-
- case ProcessMessage::eTraceMessage:
- TraceNotify(message);
- break;
-
- case ProcessMessage::eBreakpointMessage:
- BreakNotify(message);
- break;
-
- case ProcessMessage::eWatchpointMessage:
- WatchNotify(message);
- break;
+void FreeBSDThread::DidStop() {
+ // Don't set the thread state to stopped unless we really stopped.
+}
- case ProcessMessage::eCrashMessage:
- CrashNotify(message);
- break;
+void FreeBSDThread::WillResume(lldb::StateType resume_state) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("tid %lu resume_state = %s", GetID(),
+ lldb_private::StateAsCString(resume_state));
+ ProcessSP process_sp(GetProcess());
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
+ int signo = GetResumeSignal();
+ bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
+
+ switch (resume_state) {
+ case eStateSuspended:
+ case eStateStopped:
+ process->m_suspend_tids.push_back(GetID());
+ break;
+ case eStateRunning:
+ process->m_run_tids.push_back(GetID());
+ if (signo_valid)
+ process->m_resume_signo = signo;
+ break;
+ case eStateStepping:
+ process->m_step_tids.push_back(GetID());
+ if (signo_valid)
+ process->m_resume_signo = signo;
+ break;
+ default:
+ break;
+ }
+}
- case ProcessMessage::eExecMessage:
- ExecNotify(message);
- break;
- }
+bool FreeBSDThread::Resume() {
+ lldb::StateType resume_state = GetResumeState();
+ ProcessMonitor &monitor = GetMonitor();
+ bool status;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
+ StateAsCString(resume_state));
+
+ switch (resume_state) {
+ default:
+ assert(false && "Unexpected state for resume!");
+ status = false;
+ break;
+
+ case lldb::eStateRunning:
+ SetState(resume_state);
+ status = monitor.Resume(GetID(), GetResumeSignal());
+ break;
+
+ case lldb::eStateStepping:
+ SetState(resume_state);
+ status = monitor.SingleStep(GetID(), GetResumeSignal());
+ break;
+ case lldb::eStateStopped:
+ case lldb::eStateSuspended:
+ status = true;
+ break;
+ }
+
+ return status;
}
-bool
-FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp)
-{
- bool wp_set = false;
- if (wp)
- {
- addr_t wp_addr = wp->GetLoadAddress();
- size_t wp_size = wp->GetByteSize();
- bool wp_read = wp->WatchpointRead();
- bool wp_write = wp->WatchpointWrite();
- uint32_t wp_hw_index = wp->GetHardwareIndex();
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size,
- wp_read, wp_write,
- wp_hw_index);
- }
- return wp_set;
+void FreeBSDThread::Notify(const ProcessMessage &message) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
+ __FUNCTION__, message.PrintKind(), GetID());
+
+ switch (message.GetKind()) {
+ default:
+ assert(false && "Unexpected message kind!");
+ break;
+
+ case ProcessMessage::eExitMessage:
+ // Nothing to be done.
+ break;
+
+ case ProcessMessage::eLimboMessage:
+ LimboNotify(message);
+ break;
+
+ case ProcessMessage::eSignalMessage:
+ SignalNotify(message);
+ break;
+
+ case ProcessMessage::eSignalDeliveredMessage:
+ SignalDeliveredNotify(message);
+ break;
+
+ case ProcessMessage::eTraceMessage:
+ TraceNotify(message);
+ break;
+
+ case ProcessMessage::eBreakpointMessage:
+ BreakNotify(message);
+ break;
+
+ case ProcessMessage::eWatchpointMessage:
+ WatchNotify(message);
+ break;
+
+ case ProcessMessage::eCrashMessage:
+ CrashNotify(message);
+ break;
+
+ case ProcessMessage::eExecMessage:
+ ExecNotify(message);
+ break;
+ }
}
-bool
-FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp)
-{
- bool result = false;
- if (wp)
- {
- lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
- if (reg_ctx_sp.get())
- result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
- }
- return result;
+bool FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) {
+ bool wp_set = false;
+ if (wp) {
+ addr_t wp_addr = wp->GetLoadAddress();
+ size_t wp_size = wp->GetByteSize();
+ bool wp_read = wp->WatchpointRead();
+ bool wp_write = wp->WatchpointWrite();
+ uint32_t wp_hw_index = wp->GetHardwareIndex();
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx)
+ wp_set = reg_ctx->SetHardwareWatchpointWithIndex(
+ wp_addr, wp_size, wp_read, wp_write, wp_hw_index);
+ }
+ return wp_set;
}
-uint32_t
-FreeBSDThread::NumSupportedHardwareWatchpoints()
-{
+bool FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) {
+ bool result = false;
+ if (wp) {
lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
if (reg_ctx_sp.get())
- return reg_ctx_sp->NumSupportedHardwareWatchpoints();
- return 0;
+ result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
+ }
+ return result;
}
-uint32_t
-FreeBSDThread::FindVacantWatchpointIndex()
-{
- uint32_t hw_index = LLDB_INVALID_INDEX32;
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- {
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
- {
- if (reg_ctx->IsWatchpointVacant(wp_idx))
- {
- hw_index = wp_idx;
- break;
- }
- }
+uint32_t FreeBSDThread::NumSupportedHardwareWatchpoints() {
+ lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
+ if (reg_ctx_sp.get())
+ return reg_ctx_sp->NumSupportedHardwareWatchpoints();
+ return 0;
+}
+
+uint32_t FreeBSDThread::FindVacantWatchpointIndex() {
+ uint32_t hw_index = LLDB_INVALID_INDEX32;
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ uint32_t wp_idx;
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx) {
+ for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
+ if (reg_ctx->IsWatchpointVacant(wp_idx)) {
+ hw_index = wp_idx;
+ break;
+ }
}
- return hw_index;
+ }
+ return hw_index;
}
-void
-FreeBSDThread::BreakNotify(const ProcessMessage &message)
-{
- bool status;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
-
- assert(GetRegisterContext());
- status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
- assert(status && "Breakpoint update failed!");
-
- // With our register state restored, resolve the breakpoint object
- // corresponding to our current PC.
- assert(GetRegisterContext());
- lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
- lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
-
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we create a stop reason with should_stop=false. If there is no breakpoint location, then report
- // an invalid stop reason. We don't need to worry about stepping over the breakpoint here, that will
- // be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- if (bp_site)
- {
- lldb::break_id_t bp_id = bp_site->GetID();
- // If we have an operating system plug-in, we might have set a thread specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about the thread ID so we must always
- // report the breakpoint regardless of the thread.
- if (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL)
- SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
- else
- {
- const bool should_stop = false;
- SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id, should_stop));
- }
+void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
+ bool status;
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+
+ assert(GetRegisterContext());
+ status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
+ assert(status && "Breakpoint update failed!");
+
+ // With our register state restored, resolve the breakpoint object
+ // corresponding to our current PC.
+ assert(GetRegisterContext());
+ lldb::addr_t pc = GetRegisterContext()->GetPC();
+ if (log)
+ log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ lldb::BreakpointSiteSP bp_site(
+ GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
+
+ // If the breakpoint is for this thread, then we'll report the hit, but if it
+ // is for another thread,
+ // we create a stop reason with should_stop=false. If there is no breakpoint
+ // location, then report
+ // an invalid stop reason. We don't need to worry about stepping over the
+ // breakpoint here, that will
+ // be taken care of when the thread resumes and notices that there's a
+ // breakpoint under the pc.
+ if (bp_site) {
+ lldb::break_id_t bp_id = bp_site->GetID();
+ // If we have an operating system plug-in, we might have set a thread
+ // specific breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about the
+ // thread ID so we must always
+ // report the breakpoint regardless of the thread.
+ if (bp_site->ValidForThisThread(this) ||
+ GetProcess()->GetOperatingSystem() != NULL)
+ SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
+ else {
+ const bool should_stop = false;
+ SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id,
+ should_stop));
}
- else
- SetStopInfo(StopInfoSP());
+ } else
+ SetStopInfo(StopInfoSP());
}
-void
-FreeBSDThread::WatchNotify(const ProcessMessage &message)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- lldb::addr_t halt_addr = message.GetHWAddress();
- if (log)
- log->Printf ("FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8"
- PRIx64, __FUNCTION__, halt_addr);
+ lldb::addr_t halt_addr = message.GetHWAddress();
+ if (log)
+ log->Printf(
+ "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
+ __FUNCTION__, halt_addr);
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- {
- uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
- {
- if (reg_ctx->IsWatchpointHit(wp_idx))
- {
- // Clear the watchpoint hit here
- reg_ctx->ClearWatchpointHits();
- break;
- }
- }
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx) {
+ uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
+ uint32_t wp_idx;
+ for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
+ if (reg_ctx->IsWatchpointHit(wp_idx)) {
+ // Clear the watchpoint hit here
+ reg_ctx->ClearWatchpointHits();
+ break;
+ }
+ }
- if (wp_idx == num_hw_wps)
- return;
+ if (wp_idx == num_hw_wps)
+ return;
- Target &target = GetProcess()->GetTarget();
- lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
- const WatchpointList &wp_list = target.GetWatchpointList();
- lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
+ Target &target = GetProcess()->GetTarget();
+ lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
+ const WatchpointList &wp_list = target.GetWatchpointList();
+ lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
- assert(wp_sp.get() && "No watchpoint found");
- SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID(*this,
- wp_sp->GetID()));
- }
+ assert(wp_sp.get() && "No watchpoint found");
+ SetStopInfo(
+ StopInfo::CreateStopReasonWithWatchpointID(*this, wp_sp->GetID()));
+ }
}
-void
-FreeBSDThread::TraceNotify(const ProcessMessage &message)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
-
- // Try to resolve the breakpoint object corresponding to the current PC.
- assert(GetRegisterContext());
- lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
- lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
-
- // If the current pc is a breakpoint site then set the StopInfo to Breakpoint.
- // Otherwise, set the StopInfo to Watchpoint or Trace.
- // If we have an operating system plug-in, we might have set a thread specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about the thread ID so we must always
- // report the breakpoint regardless of the thread.
- if (bp_site && (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL))
- SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_site->GetID()));
- else
- {
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- {
- uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
- {
- if (reg_ctx->IsWatchpointHit(wp_idx))
- {
- WatchNotify(message);
- return;
- }
- }
+void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+
+ // Try to resolve the breakpoint object corresponding to the current PC.
+ assert(GetRegisterContext());
+ lldb::addr_t pc = GetRegisterContext()->GetPC();
+ if (log)
+ log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ lldb::BreakpointSiteSP bp_site(
+ GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
+
+ // If the current pc is a breakpoint site then set the StopInfo to Breakpoint.
+ // Otherwise, set the StopInfo to Watchpoint or Trace.
+ // If we have an operating system plug-in, we might have set a thread specific
+ // breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about the
+ // thread ID so we must always
+ // report the breakpoint regardless of the thread.
+ if (bp_site && (bp_site->ValidForThisThread(this) ||
+ GetProcess()->GetOperatingSystem() != NULL))
+ SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *this, bp_site->GetID()));
+ else {
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx) {
+ uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
+ uint32_t wp_idx;
+ for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
+ if (reg_ctx->IsWatchpointHit(wp_idx)) {
+ WatchNotify(message);
+ return;
}
- SetStopInfo (StopInfo::CreateStopReasonToTrace(*this));
+ }
}
+ SetStopInfo(StopInfo::CreateStopReasonToTrace(*this));
+ }
}
-void
-FreeBSDThread::LimboNotify(const ProcessMessage &message)
-{
- SetStopInfo (lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
+void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
+ SetStopInfo(lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
}
-void
-FreeBSDThread::SignalNotify(const ProcessMessage &message)
-{
- int signo = message.GetSignal();
- SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
+void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
+ int signo = message.GetSignal();
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
}
-void
-FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message)
-{
- int signo = message.GetSignal();
- SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
+void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
+ int signo = message.GetSignal();
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
}
-void
-FreeBSDThread::CrashNotify(const ProcessMessage &message)
-{
- // FIXME: Update stop reason as per bugzilla 14598
- int signo = message.GetSignal();
+void FreeBSDThread::CrashNotify(const ProcessMessage &message) {
+ // FIXME: Update stop reason as per bugzilla 14598
+ int signo = message.GetSignal();
- assert(message.GetKind() == ProcessMessage::eCrashMessage);
+ assert(message.GetKind() == ProcessMessage::eCrashMessage);
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf ("FreeBSDThread::%s () signo = %i, reason = '%s'",
- __FUNCTION__, signo, message.PrintCrashReason());
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("FreeBSDThread::%s () signo = %i, reason = '%s'", __FUNCTION__,
+ signo, message.PrintCrashReason());
- SetStopInfo (lldb::StopInfoSP(new POSIXCrashStopInfo(*this, signo,
- message.GetCrashReason(),
- message.GetFaultAddress())));
+ SetStopInfo(lldb::StopInfoSP(new POSIXCrashStopInfo(
+ *this, signo, message.GetCrashReason(), message.GetFaultAddress())));
}
-unsigned
-FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg = LLDB_INVALID_REGNUM;
- ArchSpec arch = HostInfo::GetArchitecture();
-
- switch (arch.GetMachine())
- {
- default:
- llvm_unreachable("CPU type not supported!");
- break;
-
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::mips64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- reg = reg_ctx->GetRegisterIndexFromOffset(offset);
- }
- break;
- }
- return reg;
+unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
+ unsigned reg = LLDB_INVALID_REGNUM;
+ ArchSpec arch = HostInfo::GetArchitecture();
+
+ switch (arch.GetMachine()) {
+ default:
+ llvm_unreachable("CPU type not supported!");
+ break;
+
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::mips64:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64: {
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ reg = reg_ctx->GetRegisterIndexFromOffset(offset);
+ } break;
+ }
+ return reg;
}
-void
-FreeBSDThread::ExecNotify(const ProcessMessage &message)
-{
- SetStopInfo (StopInfo::CreateStopReasonWithExec(*this));
+void FreeBSDThread::ExecNotify(const ProcessMessage &message) {
+ SetStopInfo(StopInfo::CreateStopReasonWithExec(*this));
}
-const char *
-FreeBSDThread::GetRegisterName(unsigned reg)
-{
- const char * name = nullptr;
- ArchSpec arch = HostInfo::GetArchitecture();
-
- switch (arch.GetMachine())
- {
- default:
- assert(false && "CPU type not supported!");
- break;
-
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::mips64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- name = GetRegisterContext()->GetRegisterName(reg);
- break;
- }
- return name;
+const char *FreeBSDThread::GetRegisterName(unsigned reg) {
+ const char *name = nullptr;
+ ArchSpec arch = HostInfo::GetArchitecture();
+
+ switch (arch.GetMachine()) {
+ default:
+ assert(false && "CPU type not supported!");
+ break;
+
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::mips64:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ name = GetRegisterContext()->GetRegisterName(reg);
+ break;
+ }
+ return name;
}
-const char *
-FreeBSDThread::GetRegisterNameFromOffset(unsigned offset)
-{
- return GetRegisterName(GetRegisterIndexFromOffset(offset));
+const char *FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) {
+ return GetRegisterName(GetRegisterIndexFromOffset(offset));
}
-
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
index 90c11dbefcb0..72e846459552 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.h
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
@@ -15,8 +15,8 @@
#include <string>
// Other libraries and framework includes
-#include "lldb/Target/Thread.h"
#include "RegisterContextPOSIX.h"
+#include "lldb/Target/Thread.h"
class ProcessMessage;
class ProcessMonitor;
@@ -25,118 +25,99 @@ class POSIXBreakpointProtocol;
//------------------------------------------------------------------------------
// @class FreeBSDThread
// @brief Abstraction of a FreeBSD thread.
-class FreeBSDThread
- : public lldb_private::Thread
-{
+class FreeBSDThread : public lldb_private::Thread {
public:
+ //------------------------------------------------------------------
+ // Constructors and destructors
+ //------------------------------------------------------------------
+ FreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- FreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
-
- virtual ~FreeBSDThread();
+ virtual ~FreeBSDThread();
- // POSIXThread
- void
- RefreshStateAfterStop() override;
+ // POSIXThread
+ void RefreshStateAfterStop() override;
- // This notifies the thread when a private stop occurs.
- void
- DidStop () override;
+ // This notifies the thread when a private stop occurs.
+ void DidStop() override;
- const char *
- GetInfo() override;
+ const char *GetInfo() override;
- void
- SetName (const char *name) override;
+ void SetName(const char *name) override;
- const char *
- GetName () override;
+ const char *GetName() override;
- lldb::RegisterContextSP
- GetRegisterContext() override;
+ lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame (lldb_private::StackFrame *frame) override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
- lldb::addr_t
- GetThreadPointer () override;
+ lldb::addr_t GetThreadPointer() override;
- //--------------------------------------------------------------------------
- // These functions provide a mapping from the register offset
- // back to the register index or name for use in debugging or log
- // output.
+ //--------------------------------------------------------------------------
+ // These functions provide a mapping from the register offset
+ // back to the register index or name for use in debugging or log
+ // output.
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- const char *
- GetRegisterNameFromOffset(unsigned offset);
+ const char *GetRegisterNameFromOffset(unsigned offset);
- //--------------------------------------------------------------------------
- // These methods form a specialized interface to POSIX threads.
- //
- bool Resume();
+ //--------------------------------------------------------------------------
+ // These methods form a specialized interface to POSIX threads.
+ //
+ bool Resume();
- void Notify(const ProcessMessage &message);
+ void Notify(const ProcessMessage &message);
- //--------------------------------------------------------------------------
- // These methods provide an interface to watchpoints
- //
- bool EnableHardwareWatchpoint(lldb_private::Watchpoint *wp);
+ //--------------------------------------------------------------------------
+ // These methods provide an interface to watchpoints
+ //
+ bool EnableHardwareWatchpoint(lldb_private::Watchpoint *wp);
- bool DisableHardwareWatchpoint(lldb_private::Watchpoint *wp);
+ bool DisableHardwareWatchpoint(lldb_private::Watchpoint *wp);
- uint32_t NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
- uint32_t FindVacantWatchpointIndex();
+ uint32_t FindVacantWatchpointIndex();
protected:
- POSIXBreakpointProtocol *
- GetPOSIXBreakpointProtocol ()
- {
- if (!m_reg_context_sp)
- m_reg_context_sp = GetRegisterContext();
- return m_posix_thread;
- }
-
- std::unique_ptr<lldb_private::StackFrame> m_frame_ap;
-
- lldb::BreakpointSiteSP m_breakpoint;
-
- bool m_thread_name_valid;
- std::string m_thread_name;
- POSIXBreakpointProtocol *m_posix_thread;
-
- ProcessMonitor &
- GetMonitor();
-
- bool
- CalculateStopInfo() override;
-
- void BreakNotify(const ProcessMessage &message);
- void WatchNotify(const ProcessMessage &message);
- virtual void TraceNotify(const ProcessMessage &message);
- void LimboNotify(const ProcessMessage &message);
- void SignalNotify(const ProcessMessage &message);
- void SignalDeliveredNotify(const ProcessMessage &message);
- void CrashNotify(const ProcessMessage &message);
- void ExitNotify(const ProcessMessage &message);
- void ExecNotify(const ProcessMessage &message);
-
- lldb_private::Unwind *
- GetUnwinder() override;
-
- //--------------------------------------------------------------------------
- // FreeBSDThread internal API.
-
- // POSIXThread override
- virtual void
- WillResume(lldb::StateType resume_state) override;
+ POSIXBreakpointProtocol *GetPOSIXBreakpointProtocol() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = GetRegisterContext();
+ return m_posix_thread;
+ }
+
+ std::unique_ptr<lldb_private::StackFrame> m_frame_ap;
+
+ lldb::BreakpointSiteSP m_breakpoint;
+
+ bool m_thread_name_valid;
+ std::string m_thread_name;
+ POSIXBreakpointProtocol *m_posix_thread;
+
+ ProcessMonitor &GetMonitor();
+
+ bool CalculateStopInfo() override;
+
+ void BreakNotify(const ProcessMessage &message);
+ void WatchNotify(const ProcessMessage &message);
+ virtual void TraceNotify(const ProcessMessage &message);
+ void LimboNotify(const ProcessMessage &message);
+ void SignalNotify(const ProcessMessage &message);
+ void SignalDeliveredNotify(const ProcessMessage &message);
+ void CrashNotify(const ProcessMessage &message);
+ void ExitNotify(const ProcessMessage &message);
+ void ExecNotify(const ProcessMessage &message);
+
+ lldb_private::Unwind *GetUnwinder() override;
+
+ //--------------------------------------------------------------------------
+ // FreeBSDThread internal API.
+
+ // POSIXThread override
+ virtual void WillResume(lldb::StateType resume_state) override;
};
#endif // #ifndef liblldb_FreeBSDThread_H_
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
index 409cf8c46b03..dfbd695899ff 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
@@ -12,81 +12,50 @@
using namespace lldb;
using namespace lldb_private;
-
//===----------------------------------------------------------------------===//
// POSIXLimboStopInfo
-POSIXLimboStopInfo::~POSIXLimboStopInfo() { }
+POSIXLimboStopInfo::~POSIXLimboStopInfo() {}
-lldb::StopReason
-POSIXLimboStopInfo::GetStopReason() const
-{
- return lldb::eStopReasonThreadExiting;
+lldb::StopReason POSIXLimboStopInfo::GetStopReason() const {
+ return lldb::eStopReasonThreadExiting;
}
-const char *
-POSIXLimboStopInfo::GetDescription()
-{
- return "thread exiting";
-}
+const char *POSIXLimboStopInfo::GetDescription() { return "thread exiting"; }
-bool
-POSIXLimboStopInfo::ShouldStop(Event *event_ptr)
-{
- return false;
-}
+bool POSIXLimboStopInfo::ShouldStop(Event *event_ptr) { return false; }
-bool
-POSIXLimboStopInfo::ShouldNotify(Event *event_ptr)
-{
- return false;
-}
+bool POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) { return false; }
//===----------------------------------------------------------------------===//
// POSIXCrashStopInfo
-POSIXCrashStopInfo::POSIXCrashStopInfo(FreeBSDThread &thread,
- uint32_t status,
+POSIXCrashStopInfo::POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status,
CrashReason reason,
lldb::addr_t fault_addr)
- : POSIXStopInfo(thread, status)
-{
- m_description = ::GetCrashReasonString(reason, fault_addr);
+ : POSIXStopInfo(thread, status) {
+ m_description = ::GetCrashReasonString(reason, fault_addr);
}
-POSIXCrashStopInfo::~POSIXCrashStopInfo() { }
+POSIXCrashStopInfo::~POSIXCrashStopInfo() {}
-lldb::StopReason
-POSIXCrashStopInfo::GetStopReason() const
-{
- return lldb::eStopReasonException;
+lldb::StopReason POSIXCrashStopInfo::GetStopReason() const {
+ return lldb::eStopReasonException;
}
//===----------------------------------------------------------------------===//
// POSIXNewThreadStopInfo
-POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() { }
+POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() {}
-lldb::StopReason
-POSIXNewThreadStopInfo::GetStopReason() const
-{
- return lldb::eStopReasonNone;
+lldb::StopReason POSIXNewThreadStopInfo::GetStopReason() const {
+ return lldb::eStopReasonNone;
}
-const char *
-POSIXNewThreadStopInfo::GetDescription()
-{
- return "thread spawned";
+const char *POSIXNewThreadStopInfo::GetDescription() {
+ return "thread spawned";
}
-bool
-POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr)
-{
- return false;
-}
+bool POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr) { return false; }
-bool
-POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr)
-{
- return false;
-}
+bool POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr) { return false; }
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
index ace6c98017b7..1ee16dd5f8f4 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
@@ -25,58 +25,42 @@
/// @class POSIXStopInfo
/// @brief Simple base class for all POSIX-specific StopInfo objects.
///
-class POSIXStopInfo
- : public lldb_private::StopInfo
-{
+class POSIXStopInfo : public lldb_private::StopInfo {
public:
- POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
- : StopInfo(thread, status)
- { }
+ POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
+ : StopInfo(thread, status) {}
};
//===----------------------------------------------------------------------===//
/// @class POSIXLimboStopInfo
/// @brief Represents the stop state of a process ready to exit.
///
-class POSIXLimboStopInfo
- : public POSIXStopInfo
-{
+class POSIXLimboStopInfo : public POSIXStopInfo {
public:
- POSIXLimboStopInfo(FreeBSDThread &thread)
- : POSIXStopInfo(thread, 0)
- { }
+ POSIXLimboStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
- ~POSIXLimboStopInfo();
+ ~POSIXLimboStopInfo();
- lldb::StopReason
- GetStopReason() const;
+ lldb::StopReason GetStopReason() const;
- const char *
- GetDescription();
+ const char *GetDescription();
- bool
- ShouldStop(lldb_private::Event *event_ptr);
+ bool ShouldStop(lldb_private::Event *event_ptr);
- bool
- ShouldNotify(lldb_private::Event *event_ptr);
+ bool ShouldNotify(lldb_private::Event *event_ptr);
};
-
//===----------------------------------------------------------------------===//
/// @class POSIXCrashStopInfo
/// @brief Represents the stop state of process that is ready to crash.
///
-class POSIXCrashStopInfo
- : public POSIXStopInfo
-{
+class POSIXCrashStopInfo : public POSIXStopInfo {
public:
- POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status,
- CrashReason reason,
- lldb::addr_t fault_addr);
- ~POSIXCrashStopInfo();
+ POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status, CrashReason reason,
+ lldb::addr_t fault_addr);
+ ~POSIXCrashStopInfo();
- lldb::StopReason
- GetStopReason() const;
+ lldb::StopReason GetStopReason() const;
};
//===----------------------------------------------------------------------===//
@@ -84,27 +68,19 @@ public:
/// @brief Represents the stop state of process when a new thread is spawned.
///
-class POSIXNewThreadStopInfo
- : public POSIXStopInfo
-{
+class POSIXNewThreadStopInfo : public POSIXStopInfo {
public:
- POSIXNewThreadStopInfo (FreeBSDThread &thread)
- : POSIXStopInfo (thread, 0)
- { }
+ POSIXNewThreadStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
- ~POSIXNewThreadStopInfo();
+ ~POSIXNewThreadStopInfo();
- lldb::StopReason
- GetStopReason() const;
+ lldb::StopReason GetStopReason() const;
- const char *
- GetDescription();
+ const char *GetDescription();
- bool
- ShouldStop(lldb_private::Event *event_ptr);
+ bool ShouldStop(lldb_private::Event *event_ptr);
- bool
- ShouldNotify(lldb_private::Event *event_ptr);
+ bool ShouldNotify(lldb_private::Event *event_ptr);
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 3a72a65da696..82e45a5d5fc1 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -1,4 +1,5 @@
-//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ -*-===//
+//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,12 +22,12 @@
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Target.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
+#include "FreeBSDThread.h"
#include "Plugins/Process/Utility/FreeBSDSignals.h"
+#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
+#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
-#include "FreeBSDThread.h"
+#include "ProcessPOSIXLog.h"
// Other libraries and framework includes
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -44,18 +45,14 @@
#include "lldb/Host/posix/Fcntl.h"
-
using namespace lldb;
using namespace lldb_private;
-namespace
-{
- UnixSignalsSP&
- GetFreeBSDSignals ()
- {
- static UnixSignalsSP s_freebsd_signals_sp (new FreeBSDSignals ());
- return s_freebsd_signals_sp;
- }
+namespace {
+UnixSignalsSP &GetFreeBSDSignals() {
+ static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals());
+ return s_freebsd_signals_sp;
+}
}
//------------------------------------------------------------------------------
@@ -64,869 +61,756 @@ namespace
lldb::ProcessSP
ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path)
-{
- lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset(new ProcessFreeBSD (target_sp, listener_sp, GetFreeBSDSignals()));
- return process_sp;
+ const FileSpec *crash_file_path) {
+ lldb::ProcessSP process_sp;
+ if (crash_file_path == NULL)
+ process_sp.reset(
+ new ProcessFreeBSD(target_sp, listener_sp, GetFreeBSDSignals()));
+ return process_sp;
}
-void
-ProcessFreeBSD::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- ProcessPOSIXLog::Initialize(GetPluginNameStatic());
- });
+void ProcessFreeBSD::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ ProcessPOSIXLog::Initialize(GetPluginNameStatic());
+ });
}
-lldb_private::ConstString
-ProcessFreeBSD::GetPluginNameStatic()
-{
- static ConstString g_name("freebsd");
- return g_name;
+lldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() {
+ static ConstString g_name("freebsd");
+ return g_name;
}
-const char *
-ProcessFreeBSD::GetPluginDescriptionStatic()
-{
- return "Process plugin for FreeBSD";
+const char *ProcessFreeBSD::GetPluginDescriptionStatic() {
+ return "Process plugin for FreeBSD";
}
//------------------------------------------------------------------------------
// ProcessInterface protocol.
-lldb_private::ConstString
-ProcessFreeBSD::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ProcessFreeBSD::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ProcessFreeBSD::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ProcessFreeBSD::GetPluginVersion() { return 1; }
-void
-ProcessFreeBSD::Terminate()
-{
-}
-
-Error
-ProcessFreeBSD::DoDetach(bool keep_stopped)
-{
- Error error;
- if (keep_stopped)
- {
- error.SetErrorString("Detaching with keep_stopped true is not currently supported on FreeBSD.");
- return error;
- }
-
- error = m_monitor->Detach(GetID());
-
- if (error.Success())
- SetPrivateState(eStateDetached);
+void ProcessFreeBSD::Terminate() {}
+Error ProcessFreeBSD::DoDetach(bool keep_stopped) {
+ Error error;
+ if (keep_stopped) {
+ error.SetErrorString("Detaching with keep_stopped true is not currently "
+ "supported on FreeBSD.");
return error;
-}
-
-Error
-ProcessFreeBSD::DoResume()
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- SetPrivateState(eStateRunning);
-
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- bool do_step = false;
+ }
+
+ error = m_monitor->Detach(GetID());
+
+ if (error.Success())
+ SetPrivateState(eStateDetached);
+
+ return error;
+}
+
+Error ProcessFreeBSD::DoResume() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ SetPrivateState(eStateRunning);
+
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ bool do_step = false;
+
+ for (tid_collection::const_iterator t_pos = m_run_tids.begin(),
+ t_end = m_run_tids.end();
+ t_pos != t_end; ++t_pos) {
+ m_monitor->ThreadSuspend(*t_pos, false);
+ }
+ for (tid_collection::const_iterator t_pos = m_step_tids.begin(),
+ t_end = m_step_tids.end();
+ t_pos != t_end; ++t_pos) {
+ m_monitor->ThreadSuspend(*t_pos, false);
+ do_step = true;
+ }
+ for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(),
+ t_end = m_suspend_tids.end();
+ t_pos != t_end; ++t_pos) {
+ m_monitor->ThreadSuspend(*t_pos, true);
+ // XXX Cannot PT_CONTINUE properly with suspended threads.
+ do_step = true;
+ }
+
+ if (log)
+ log->Printf("process %" PRIu64 " resuming (%s)", GetID(),
+ do_step ? "step" : "continue");
+ if (do_step)
+ m_monitor->SingleStep(GetID(), m_resume_signo);
+ else
+ m_monitor->Resume(GetID(), m_resume_signo);
+
+ return Error();
+}
+
+bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
+ GetID());
+
+ std::vector<lldb::pid_t> tds;
+ if (!GetMonitor().GetCurrentThreadIDs(tds)) {
+ return false;
+ }
- for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos)
- {
- m_monitor->ThreadSuspend(*t_pos, false);
- }
- for (tid_collection::const_iterator t_pos = m_step_tids.begin(), t_end = m_step_tids.end(); t_pos != t_end; ++t_pos)
- {
- m_monitor->ThreadSuspend(*t_pos, false);
- do_step = true;
+ ThreadList old_thread_list_copy(old_thread_list);
+ for (size_t i = 0; i < tds.size(); ++i) {
+ tid_t tid = tds[i];
+ ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
+ if (!thread_sp) {
+ thread_sp.reset(new FreeBSDThread(*this, tid));
+ if (log)
+ log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
+ } else {
+ if (log)
+ log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
+ tid);
}
- for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); t_pos != t_end; ++t_pos)
- {
- m_monitor->ThreadSuspend(*t_pos, true);
- // XXX Cannot PT_CONTINUE properly with suspended threads.
- do_step = true;
+ new_thread_list.AddThread(thread_sp);
+ }
+ for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
+ ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
+ if (old_thread_sp) {
+ if (log)
+ log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
}
+ }
- if (log)
- log->Printf("process %" PRIu64 " resuming (%s)", GetID(), do_step ? "step" : "continue");
- if (do_step)
- m_monitor->SingleStep(GetID(), m_resume_signo);
- else
- m_monitor->Resume(GetID(), m_resume_signo);
-
- return Error();
+ return true;
}
-bool
-ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
- if (log)
- log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- std::vector<lldb::pid_t> tds;
- if (!GetMonitor().GetCurrentThreadIDs(tds))
- {
- return false;
- }
+Error ProcessFreeBSD::WillResume() {
+ m_resume_signo = 0;
+ m_suspend_tids.clear();
+ m_run_tids.clear();
+ m_step_tids.clear();
+ return Process::WillResume();
+}
- ThreadList old_thread_list_copy(old_thread_list);
- for (size_t i = 0; i < tds.size(); ++i)
- {
- tid_t tid = tds[i];
- ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID(tid, false));
- if (!thread_sp)
- {
- thread_sp.reset(new FreeBSDThread(*this, tid));
- if (log)
- log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
- }
- else
- {
- if (log)
- log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, tid);
- }
- new_thread_list.AddThread(thread_sp);
- }
- for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i)
- {
- ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
- if (old_thread_sp)
- {
- if (log)
- log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
- }
- }
+void ProcessFreeBSD::SendMessage(const ProcessMessage &message) {
+ std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
- return true;
-}
+ switch (message.GetKind()) {
+ case ProcessMessage::eInvalidMessage:
+ return;
-Error
-ProcessFreeBSD::WillResume()
-{
- m_resume_signo = 0;
- m_suspend_tids.clear();
- m_run_tids.clear();
- m_step_tids.clear();
- return Process::WillResume();
-}
+ case ProcessMessage::eAttachMessage:
+ SetPrivateState(eStateStopped);
+ return;
-void
-ProcessFreeBSD::SendMessage(const ProcessMessage &message)
-{
- std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
+ case ProcessMessage::eLimboMessage:
+ case ProcessMessage::eExitMessage:
+ SetExitStatus(message.GetExitStatus(), NULL);
+ break;
- switch (message.GetKind())
- {
- case ProcessMessage::eInvalidMessage:
- return;
+ case ProcessMessage::eSignalMessage:
+ case ProcessMessage::eSignalDeliveredMessage:
+ case ProcessMessage::eBreakpointMessage:
+ case ProcessMessage::eTraceMessage:
+ case ProcessMessage::eWatchpointMessage:
+ case ProcessMessage::eCrashMessage:
+ SetPrivateState(eStateStopped);
+ break;
- case ProcessMessage::eAttachMessage:
- SetPrivateState(eStateStopped);
- return;
+ case ProcessMessage::eNewThreadMessage:
+ llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
+ break;
- case ProcessMessage::eLimboMessage:
- case ProcessMessage::eExitMessage:
- SetExitStatus(message.GetExitStatus(), NULL);
- break;
-
- case ProcessMessage::eSignalMessage:
- case ProcessMessage::eSignalDeliveredMessage:
- case ProcessMessage::eBreakpointMessage:
- case ProcessMessage::eTraceMessage:
- case ProcessMessage::eWatchpointMessage:
- case ProcessMessage::eCrashMessage:
- SetPrivateState(eStateStopped);
- break;
-
- case ProcessMessage::eNewThreadMessage:
- llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
- break;
-
- case ProcessMessage::eExecMessage:
- SetPrivateState(eStateStopped);
- break;
- }
+ case ProcessMessage::eExecMessage:
+ SetPrivateState(eStateStopped);
+ break;
+ }
- m_message_queue.push(message);
+ m_message_queue.push(message);
}
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, UnixSignalsSP &unix_signals_sp)
+ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ UnixSignalsSP &unix_signals_sp)
: Process(target_sp, listener_sp, unix_signals_sp),
- m_byte_order(endian::InlHostByteOrder()),
- m_monitor(NULL),
- m_module(NULL),
- m_message_mutex(),
- m_exit_now(false),
- m_seen_initial_stop(),
- m_resume_signo(0)
-{
- // FIXME: Putting this code in the ctor and saving the byte order in a
- // member variable is a hack to avoid const qual issues in GetByteOrder.
- lldb::ModuleSP module = GetTarget().GetExecutableModule();
- if (module && module->GetObjectFile())
- m_byte_order = module->GetObjectFile()->GetByteOrder();
+ m_byte_order(endian::InlHostByteOrder()), m_monitor(NULL), m_module(NULL),
+ m_message_mutex(), m_exit_now(false), m_seen_initial_stop(),
+ m_resume_signo(0) {
+ // FIXME: Putting this code in the ctor and saving the byte order in a
+ // member variable is a hack to avoid const qual issues in GetByteOrder.
+ lldb::ModuleSP module = GetTarget().GetExecutableModule();
+ if (module && module->GetObjectFile())
+ m_byte_order = module->GetObjectFile()->GetByteOrder();
}
-ProcessFreeBSD::~ProcessFreeBSD()
-{
- delete m_monitor;
-}
+ProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; }
//------------------------------------------------------------------------------
// Process protocol.
-void
-ProcessFreeBSD::Finalize()
-{
+void ProcessFreeBSD::Finalize() {
Process::Finalize();
if (m_monitor)
m_monitor->StopMonitor();
}
-bool
-ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- // 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();
- // If there is no executable module, we return true since we might be preparing to attach.
- return true;
+bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ // 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();
+ // If there is no executable module, we return true since we might be
+ // preparing to attach.
+ return true;
}
-Error
-ProcessFreeBSD::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- Error error;
- assert(m_monitor == NULL);
+Error ProcessFreeBSD::DoAttachToProcessWithID(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
+ Error error;
+ assert(m_monitor == NULL);
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
- m_monitor = new ProcessMonitor(this, pid, error);
+ m_monitor = new ProcessMonitor(this, pid, error);
- if (!error.Success())
- return error;
+ if (!error.Success())
+ return error;
- PlatformSP platform_sp (GetTarget().GetPlatform ());
- assert (platform_sp.get());
- if (!platform_sp)
- return error; // FIXME: Detatch?
-
- // Find out what we can about this process
- ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo (pid, process_info);
-
- // Resolve the executable module
- ModuleSP exe_module_sp;
- FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(), GetTarget().GetArchitecture());
- error = platform_sp->ResolveExecutable(exe_module_spec,
- exe_module_sp,
- executable_search_paths.GetSize() ? &executable_search_paths : NULL);
- if (!error.Success())
- return error;
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ assert(platform_sp.get());
+ if (!platform_sp)
+ return error; // FIXME: Detatch?
+
+ // Find out what we can about this process
+ ProcessInstanceInfo process_info;
+ platform_sp->GetProcessInfo(pid, process_info);
+
+ // Resolve the executable module
+ ModuleSP exe_module_sp;
+ FileSpecList executable_search_paths(
+ Target::GetDefaultExecutableSearchPaths());
+ ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
+ GetTarget().GetArchitecture());
+ error = platform_sp->ResolveExecutable(
+ exe_module_spec, exe_module_sp,
+ executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+ if (!error.Success())
+ return error;
- // Fix the target architecture if necessary
- const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
- if (module_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(module_arch))
- GetTarget().SetArchitecture(module_arch);
+ // Fix the target architecture if necessary
+ const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
+ if (module_arch.IsValid() &&
+ !GetTarget().GetArchitecture().IsExactMatch(module_arch))
+ GetTarget().SetArchitecture(module_arch);
- // Initialize the target module list
- GetTarget().SetExecutableModule (exe_module_sp, true);
+ // Initialize the target module list
+ GetTarget().SetExecutableModule(exe_module_sp, true);
- SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
+ SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
- SetID(pid);
+ SetID(pid);
- return error;
+ return error;
}
-Error
-ProcessFreeBSD::WillLaunch(Module* module)
-{
- Error error;
- return error;
+Error ProcessFreeBSD::WillLaunch(Module *module) {
+ Error error;
+ return error;
}
FileSpec
ProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
- const FileSpec &default_file_spec,
- const FileSpec &dbg_pts_file_spec)
-{
- FileSpec file_spec{};
-
- if (file_action && file_action->GetAction() == FileAction::eFileActionOpen)
- {
- file_spec = file_action->GetFileSpec();
- // By default the stdio paths passed in will be pseudo-terminal
- // (/dev/pts). If so, convert to using a different default path
- // instead to redirect I/O to the debugger console. This should
- // also handle user overrides to /dev/null or a different file.
- if (!file_spec || file_spec == dbg_pts_file_spec)
- file_spec = default_file_spec;
- }
- return file_spec;
-}
-
-Error
-ProcessFreeBSD::DoLaunch (Module *module,
- ProcessLaunchInfo &launch_info)
-{
- Error error;
- assert(m_monitor == NULL);
-
- FileSpec working_dir = launch_info.GetWorkingDirectory();
- if (working_dir &&
- (!working_dir.ResolvePath() ||
- working_dir.GetFileType() != FileSpec::eFileTypeDirectory))
- {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return error;
- }
+ const FileSpec &default_file_spec,
+ const FileSpec &dbg_pts_file_spec) {
+ FileSpec file_spec{};
+
+ if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) {
+ file_spec = file_action->GetFileSpec();
+ // By default the stdio paths passed in will be pseudo-terminal
+ // (/dev/pts). If so, convert to using a different default path
+ // instead to redirect I/O to the debugger console. This should
+ // also handle user overrides to /dev/null or a different file.
+ if (!file_spec || file_spec == dbg_pts_file_spec)
+ file_spec = default_file_spec;
+ }
+ return file_spec;
+}
+
+Error ProcessFreeBSD::DoLaunch(Module *module, ProcessLaunchInfo &launch_info) {
+ Error error;
+ assert(m_monitor == NULL);
+
+ FileSpec working_dir = launch_info.GetWorkingDirectory();
+ if (working_dir &&
+ (!working_dir.ResolvePath() ||
+ working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ return error;
+ }
- SetPrivateState(eStateLaunching);
+ SetPrivateState(eStateLaunching);
- const lldb_private::FileAction *file_action;
+ const lldb_private::FileAction *file_action;
- // Default of empty will mean to use existing open file descriptors
- FileSpec stdin_file_spec{};
- FileSpec stdout_file_spec{};
- FileSpec stderr_file_spec{};
+ // Default of empty will mean to use existing open file descriptors
+ FileSpec stdin_file_spec{};
+ 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),
+ false};
- file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
- stdin_file_spec = GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
+ file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
+ stdin_file_spec =
+ GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
- file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
- stdout_file_spec = GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
+ file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
+ stdout_file_spec =
+ GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
- file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
- stderr_file_spec = GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
+ file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
+ stderr_file_spec =
+ GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
- m_monitor = new ProcessMonitor(this,
- module,
- launch_info.GetArguments().GetConstArgumentVector(),
- launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
- stdin_file_spec,
- stdout_file_spec,
- stderr_file_spec,
- working_dir,
- launch_info,
- error);
+ m_monitor = new ProcessMonitor(
+ this, module, launch_info.GetArguments().GetConstArgumentVector(),
+ launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
+ stdin_file_spec, stdout_file_spec, stderr_file_spec, working_dir,
+ launch_info, error);
- m_module = module;
+ m_module = module;
- if (!error.Success())
- return error;
+ if (!error.Success())
+ return error;
- int terminal = m_monitor->GetTerminalFD();
- if (terminal >= 0) {
- // The reader thread will close the file descriptor when done, so we pass it a copy.
+ int terminal = m_monitor->GetTerminalFD();
+ if (terminal >= 0) {
+// The reader thread will close the file descriptor when done, so we pass it a
+// copy.
#ifdef F_DUPFD_CLOEXEC
- int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
+ int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
#else
- // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
- int stdio = fcntl(terminal, F_DUPFD, 0);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
- stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
-#endif
- SetSTDIOFileDescriptor(stdio);
+ // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
+ int stdio = fcntl(terminal, F_DUPFD, 0);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+ stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
}
+#endif
+ SetSTDIOFileDescriptor(stdio);
+ }
- SetID(m_monitor->GetPID());
- return error;
+ SetID(m_monitor->GetPID());
+ return error;
}
-void
-ProcessFreeBSD::DidLaunch()
-{
-}
+void ProcessFreeBSD::DidLaunch() {}
-addr_t
-ProcessFreeBSD::GetImageInfoAddress()
-{
- Target *target = &GetTarget();
- ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(target);
+addr_t ProcessFreeBSD::GetImageInfoAddress() {
+ Target *target = &GetTarget();
+ ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(target);
- if (addr.IsValid())
- return addr.GetLoadAddress(target);
- return LLDB_INVALID_ADDRESS;
+ if (addr.IsValid())
+ return addr.GetLoadAddress(target);
+ return LLDB_INVALID_ADDRESS;
}
-Error
-ProcessFreeBSD::DoHalt(bool &caused_stop)
-{
- Error error;
+Error ProcessFreeBSD::DoHalt(bool &caused_stop) {
+ Error error;
- if (IsStopped())
- {
- caused_stop = false;
- }
- else if (kill(GetID(), SIGSTOP))
- {
- caused_stop = false;
- error.SetErrorToErrno();
- }
- else
- {
- caused_stop = true;
- }
- return error;
+ if (IsStopped()) {
+ caused_stop = false;
+ } else if (kill(GetID(), SIGSTOP)) {
+ caused_stop = false;
+ error.SetErrorToErrno();
+ } else {
+ caused_stop = true;
+ }
+ return error;
}
-Error
-ProcessFreeBSD::DoSignal(int signal)
-{
- Error error;
+Error ProcessFreeBSD::DoSignal(int signal) {
+ Error error;
- if (kill(GetID(), signal))
- error.SetErrorToErrno();
+ if (kill(GetID(), signal))
+ error.SetErrorToErrno();
- return error;
+ return error;
}
-Error
-ProcessFreeBSD::DoDestroy()
-{
- Error error;
-
- if (!HasExited())
- {
- assert(m_monitor);
- m_exit_now = true;
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- {
- error.SetErrorString("invalid process id");
- return error;
- }
- if (!m_monitor->Kill())
- {
- error.SetErrorToErrno();
- return error;
- }
-
- SetPrivateState(eStateExited);
- }
+Error ProcessFreeBSD::DoDestroy() {
+ Error error;
- return error;
-}
+ if (!HasExited()) {
+ assert(m_monitor);
+ m_exit_now = true;
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
+ error.SetErrorString("invalid process id");
+ return error;
+ }
+ if (!m_monitor->Kill()) {
+ error.SetErrorToErrno();
+ return error;
+ }
-void
-ProcessFreeBSD::DoDidExec()
-{
- Target *target = &GetTarget();
- if (target)
- {
- PlatformSP platform_sp (target->GetPlatform());
- assert (platform_sp.get());
- if (platform_sp)
- {
- ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo(GetID(), process_info);
- ModuleSP exe_module_sp;
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(), target->GetArchitecture());
- FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
- Error error = platform_sp->ResolveExecutable(exe_module_spec,
- exe_module_sp,
- executable_search_paths.GetSize() ? &executable_search_paths : NULL);
- if (!error.Success())
- return;
- target->SetExecutableModule(exe_module_sp, true);
- }
+ SetPrivateState(eStateExited);
+ }
+
+ return error;
+}
+
+void ProcessFreeBSD::DoDidExec() {
+ Target *target = &GetTarget();
+ if (target) {
+ PlatformSP platform_sp(target->GetPlatform());
+ assert(platform_sp.get());
+ if (platform_sp) {
+ ProcessInstanceInfo process_info;
+ platform_sp->GetProcessInfo(GetID(), process_info);
+ ModuleSP exe_module_sp;
+ ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
+ target->GetArchitecture());
+ FileSpecList executable_search_paths(
+ Target::GetDefaultExecutableSearchPaths());
+ Error error = platform_sp->ResolveExecutable(
+ exe_module_spec, exe_module_sp,
+ executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+ if (!error.Success())
+ return;
+ target->SetExecutableModule(exe_module_sp, true);
}
+ }
}
-bool
-ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
-{
- bool added_to_set = false;
- ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
- if (it == m_seen_initial_stop.end())
- {
- m_seen_initial_stop.insert(stop_tid);
- added_to_set = true;
- }
- return added_to_set;
+bool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) {
+ bool added_to_set = false;
+ ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
+ if (it == m_seen_initial_stop.end()) {
+ m_seen_initial_stop.insert(stop_tid);
+ added_to_set = true;
+ }
+ return added_to_set;
}
-bool
-ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid)
-{
- return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
+bool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) {
+ return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
}
FreeBSDThread *
-ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid)
-{
- return new FreeBSDThread(process, tid);
+ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process,
+ lldb::tid_t tid) {
+ return new FreeBSDThread(process, tid);
}
-void
-ProcessFreeBSD::RefreshStateAfterStop()
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
-
- std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
+void ProcessFreeBSD::RefreshStateAfterStop() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__,
+ (int)m_message_queue.size());
- // This method used to only handle one message. Changing it to loop allows
- // it to handle the case where we hit a breakpoint while handling a different
- // breakpoint.
- while (!m_message_queue.empty())
- {
- ProcessMessage &message = m_message_queue.front();
+ std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
- // Resolve the thread this message corresponds to and pass it along.
- lldb::tid_t tid = message.GetTID();
- if (log)
- log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
+ // This method used to only handle one message. Changing it to loop allows
+ // it to handle the case where we hit a breakpoint while handling a different
+ // breakpoint.
+ while (!m_message_queue.empty()) {
+ ProcessMessage &message = m_message_queue.front();
- m_thread_list.RefreshStateAfterStop();
+ // Resolve the thread this message corresponds to and pass it along.
+ lldb::tid_t tid = message.GetTID();
+ if (log)
+ log->Printf(
+ "ProcessFreeBSD::%s(), message_queue size = %d, pid = %" PRIi64,
+ __FUNCTION__, (int)m_message_queue.size(), tid);
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- GetThreadList().FindThreadByID(tid, false).get());
- if (thread)
- thread->Notify(message);
+ m_thread_list.RefreshStateAfterStop();
- if (message.GetKind() == ProcessMessage::eExitMessage)
- {
- // FIXME: We should tell the user about this, but the limbo message is probably better for that.
- if (log)
- log->Printf ("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ GetThreadList().FindThreadByID(tid, false).get());
+ if (thread)
+ thread->Notify(message);
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ if (message.GetKind() == ProcessMessage::eExitMessage) {
+ // FIXME: We should tell the user about this, but the limbo message is
+ // probably better for that.
+ if (log)
+ log->Printf("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64,
+ __FUNCTION__, tid);
- ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
- thread_sp.reset();
- m_seen_initial_stop.erase(tid);
- }
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- m_message_queue.pop();
+ ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
+ thread_sp.reset();
+ m_seen_initial_stop.erase(tid);
}
+
+ m_message_queue.pop();
+ }
}
-bool
-ProcessFreeBSD::IsAlive()
-{
- StateType state = GetPrivateState();
- return state != eStateDetached
- && state != eStateExited
- && state != eStateInvalid
- && state != eStateUnloaded;
+bool ProcessFreeBSD::IsAlive() {
+ StateType state = GetPrivateState();
+ return state != eStateDetached && state != eStateExited &&
+ state != eStateInvalid && state != eStateUnloaded;
}
-size_t
-ProcessFreeBSD::DoReadMemory(addr_t vm_addr,
- void *buf, size_t size, Error &error)
-{
- assert(m_monitor);
- return m_monitor->ReadMemory(vm_addr, buf, size, error);
+size_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size,
+ Error &error) {
+ assert(m_monitor);
+ return m_monitor->ReadMemory(vm_addr, buf, size, error);
}
-size_t
-ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
- Error &error)
-{
- assert(m_monitor);
- return m_monitor->WriteMemory(vm_addr, buf, size, error);
+size_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf,
+ size_t size, Error &error) {
+ assert(m_monitor);
+ return m_monitor->WriteMemory(vm_addr, buf, size, error);
}
-addr_t
-ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
- Error &error)
-{
- addr_t allocated_addr = LLDB_INVALID_ADDRESS;
-
- unsigned prot = 0;
- if (permissions & lldb::ePermissionsReadable)
- prot |= eMmapProtRead;
- if (permissions & lldb::ePermissionsWritable)
- prot |= eMmapProtWrite;
- if (permissions & lldb::ePermissionsExecutable)
- prot |= eMmapProtExec;
-
- if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
- eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
- m_addr_to_mmap_size[allocated_addr] = size;
- error.Clear();
- } else {
- allocated_addr = LLDB_INVALID_ADDRESS;
- error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
- }
+addr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
+ Error &error) {
+ addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+
+ unsigned prot = 0;
+ if (permissions & lldb::ePermissionsReadable)
+ prot |= eMmapProtRead;
+ if (permissions & lldb::ePermissionsWritable)
+ prot |= eMmapProtWrite;
+ if (permissions & lldb::ePermissionsExecutable)
+ prot |= eMmapProtExec;
- return allocated_addr;
+ if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
+ eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
+ m_addr_to_mmap_size[allocated_addr] = size;
+ error.Clear();
+ } else {
+ allocated_addr = LLDB_INVALID_ADDRESS;
+ error.SetErrorStringWithFormat(
+ "unable to allocate %zu bytes of memory with permissions %s", size,
+ GetPermissionsAsCString(permissions));
+ }
+
+ return allocated_addr;
}
-Error
-ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr)
-{
- Error error;
- MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
- if (pos != m_addr_to_mmap_size.end() &&
- InferiorCallMunmap(this, addr, pos->second))
- m_addr_to_mmap_size.erase (pos);
- else
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
+Error ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
+ if (pos != m_addr_to_mmap_size.end() &&
+ InferiorCallMunmap(this, addr, pos->second))
+ m_addr_to_mmap_size.erase(pos);
+ else
+ error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64,
+ addr);
- return error;
+ return error;
}
size_t
-ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
-{
- static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xD4 };
- static const uint8_t g_i386_opcode[] = { 0xCC };
-
- ArchSpec arch = GetTarget().GetArchitecture();
- const uint8_t *opcode = NULL;
- size_t opcode_size = 0;
-
- switch (arch.GetMachine())
- {
- default:
- assert(false && "CPU type not supported!");
- break;
-
- case llvm::Triple::arm:
- {
- // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
- // but the linux kernel does otherwise.
- static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
- static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
-
- lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
- AddressClass addr_class = eAddressClassUnknown;
-
- if (bp_loc_sp)
- addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();
-
- if (addr_class == eAddressClassCodeAlternateISA
- || (addr_class == eAddressClassUnknown
- && bp_loc_sp->GetAddress().GetOffset() & 1))
- {
- opcode = g_thumb_breakpoint_opcode;
- opcode_size = sizeof(g_thumb_breakpoint_opcode);
- }
- else
- {
- opcode = g_arm_breakpoint_opcode;
- opcode_size = sizeof(g_arm_breakpoint_opcode);
- }
- }
- break;
- case llvm::Triple::aarch64:
- opcode = g_aarch64_opcode;
- opcode_size = sizeof(g_aarch64_opcode);
- break;
-
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- opcode = g_i386_opcode;
- opcode_size = sizeof(g_i386_opcode);
- break;
+ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
+ static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4};
+ static const uint8_t g_i386_opcode[] = {0xCC};
+
+ ArchSpec arch = GetTarget().GetArchitecture();
+ const uint8_t *opcode = NULL;
+ size_t opcode_size = 0;
+
+ switch (arch.GetMachine()) {
+ default:
+ assert(false && "CPU type not supported!");
+ break;
+
+ case llvm::Triple::arm: {
+ // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
+ // but the linux kernel does otherwise.
+ static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
+ static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
+
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ AddressClass addr_class = eAddressClassUnknown;
+
+ if (bp_loc_sp)
+ addr_class = bp_loc_sp->GetAddress().GetAddressClass();
+
+ if (addr_class == eAddressClassCodeAlternateISA ||
+ (addr_class == eAddressClassUnknown &&
+ bp_loc_sp->GetAddress().GetOffset() & 1)) {
+ opcode = g_thumb_breakpoint_opcode;
+ opcode_size = sizeof(g_thumb_breakpoint_opcode);
+ } else {
+ opcode = g_arm_breakpoint_opcode;
+ opcode_size = sizeof(g_arm_breakpoint_opcode);
}
+ } break;
+ case llvm::Triple::aarch64:
+ opcode = g_aarch64_opcode;
+ opcode_size = sizeof(g_aarch64_opcode);
+ break;
+
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ opcode = g_i386_opcode;
+ opcode_size = sizeof(g_i386_opcode);
+ break;
+ }
- bp_site->SetTrapOpcode(opcode, opcode_size);
- return opcode_size;
+ bp_site->SetTrapOpcode(opcode, opcode_size);
+ return opcode_size;
}
-Error
-ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site)
-{
- return EnableSoftwareBreakpoint(bp_site);
+Error ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) {
+ return EnableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site)
-{
- return DisableSoftwareBreakpoint(bp_site);
+Error ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) {
+ return DisableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (wp->IsEnabled())
- {
- if (log)
- log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
- return error;
- }
-
- // Try to find a vacant watchpoint slot in the inferiors' main thread
- uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(0, false).get());
+Error ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
+ addr_t addr = wp->GetLoadAddress();
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
+ return error;
+ }
- if (thread)
- wp_hw_index = thread->FindVacantWatchpointIndex();
+ // Try to find a vacant watchpoint slot in the inferiors' main thread
+ uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(0, false).get());
+
+ if (thread)
+ wp_hw_index = thread->FindVacantWatchpointIndex();
- if (wp_hw_index == LLDB_INVALID_INDEX32)
- {
- error.SetErrorString("Setting hardware watchpoint failed.");
- }
+ if (wp_hw_index == LLDB_INVALID_INDEX32) {
+ error.SetErrorString("Setting hardware watchpoint failed.");
+ } else {
+ wp->SetHardwareIndex(wp_hw_index);
+ bool wp_enabled = true;
+ uint32_t thread_count = m_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < thread_count; ++i) {
+ thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(i, false).get());
+ if (thread)
+ wp_enabled &= thread->EnableHardwareWatchpoint(wp);
else
- {
- wp->SetHardwareIndex(wp_hw_index);
- bool wp_enabled = true;
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i)
- {
- thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- if (thread)
- wp_enabled &= thread->EnableHardwareWatchpoint(wp);
- else
- wp_enabled = false;
- }
- if (wp_enabled)
- {
- wp->SetEnabled(true, notify);
- return error;
- }
- else
- {
- // Watchpoint enabling failed on at least one
- // of the threads so roll back all of them
- DisableWatchpoint(wp, false);
- error.SetErrorString("Setting hardware watchpoint failed");
- }
- }
+ wp_enabled = false;
+ }
+ if (wp_enabled) {
+ wp->SetEnabled(true, notify);
+ return error;
+ } else {
+ // Watchpoint enabling failed on at least one
+ // of the threads so roll back all of them
+ DisableWatchpoint(wp, false);
+ error.SetErrorString("Setting hardware watchpoint failed");
+ }
}
- else
- error.SetErrorString("Watchpoint argument was NULL.");
- return error;
+ } else
+ error.SetErrorString("Watchpoint argument was NULL.");
+ return error;
}
-Error
-ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (!wp->IsEnabled())
- {
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
- watchID, (uint64_t)addr);
- // This is needed (for now) to keep watchpoints disabled correctly
- wp->SetEnabled(false, notify);
- return error;
- }
-
- if (wp->IsHardware())
- {
- bool wp_disabled = true;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i)
- {
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- if (thread)
- wp_disabled &= thread->DisableHardwareWatchpoint(wp);
- else
- wp_disabled = false;
- }
- if (wp_disabled)
- {
- wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
- wp->SetEnabled(false, notify);
- return error;
- }
- else
- error.SetErrorString("Disabling hardware watchpoint failed");
- }
+Error ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
+ addr_t addr = wp->GetLoadAddress();
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (!wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
+ watchID, (uint64_t)addr);
+ // This is needed (for now) to keep watchpoints disabled correctly
+ wp->SetEnabled(false, notify);
+ return error;
}
- else
- error.SetErrorString("Watchpoint argument was NULL.");
- return error;
+
+ if (wp->IsHardware()) {
+ bool wp_disabled = true;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ uint32_t thread_count = m_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < thread_count; ++i) {
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(i, false).get());
+ if (thread)
+ wp_disabled &= thread->DisableHardwareWatchpoint(wp);
+ else
+ wp_disabled = false;
+ }
+ if (wp_disabled) {
+ wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
+ wp->SetEnabled(false, notify);
+ return error;
+ } else
+ error.SetErrorString("Disabling hardware watchpoint failed");
+ }
+ } else
+ error.SetErrorString("Watchpoint argument was NULL.");
+ return error;
}
-Error
-ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num)
-{
- Error error;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(0, false).get());
- if (thread)
- num = thread->NumSupportedHardwareWatchpoints();
- else
- error.SetErrorString("Process does not exist.");
- return error;
+Error ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) {
+ Error error;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(0, false).get());
+ if (thread)
+ num = thread->NumSupportedHardwareWatchpoints();
+ else
+ error.SetErrorString("Process does not exist.");
+ return error;
}
-Error
-ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after)
-{
- Error error = GetWatchpointSupportInfo(num);
- // Watchpoints trigger and halt the inferior after
- // the corresponding instruction has been executed.
- after = true;
- return error;
+Error ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+ Error error = GetWatchpointSupportInfo(num);
+ // Watchpoints trigger and halt the inferior after
+ // the corresponding instruction has been executed.
+ after = true;
+ return error;
}
-uint32_t
-ProcessFreeBSD::UpdateThreadListIfNeeded()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- // Do not allow recursive updates.
- return m_thread_list.GetSize(false);
+uint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ // Do not allow recursive updates.
+ return m_thread_list.GetSize(false);
}
#if 0
@@ -955,91 +839,77 @@ ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_th
}
#endif
-ByteOrder
-ProcessFreeBSD::GetByteOrder() const
-{
- // FIXME: We should be able to extract this value directly. See comment in
- // ProcessFreeBSD().
- return m_byte_order;
+ByteOrder ProcessFreeBSD::GetByteOrder() const {
+ // FIXME: We should be able to extract this value directly. See comment in
+ // ProcessFreeBSD().
+ return m_byte_order;
}
-size_t
-ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Error &error)
-{
- ssize_t status;
- if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
- {
- error.SetErrorToErrno();
- return 0;
- }
- return status;
+size_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Error &error) {
+ ssize_t status;
+ if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) {
+ error.SetErrorToErrno();
+ return 0;
+ }
+ return status;
}
//------------------------------------------------------------------------------
// Utility functions.
-bool
-ProcessFreeBSD::HasExited()
-{
- switch (GetPrivateState())
- {
- default:
- break;
-
- case eStateDetached:
- case eStateExited:
- return true;
- }
-
- return false;
-}
+bool ProcessFreeBSD::HasExited() {
+ switch (GetPrivateState()) {
+ default:
+ break;
-bool
-ProcessFreeBSD::IsStopped()
-{
- switch (GetPrivateState())
- {
- default:
- break;
-
- case eStateStopped:
- case eStateCrashed:
- case eStateSuspended:
- return true;
- }
+ case eStateDetached:
+ case eStateExited:
+ return true;
+ }
- return false;
+ return false;
}
-bool
-ProcessFreeBSD::IsAThreadRunning()
-{
- bool is_running = false;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i)
- {
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- StateType thread_state = thread->GetState();
- if (thread_state == eStateRunning || thread_state == eStateStepping)
- {
- is_running = true;
- break;
- }
- }
- return is_running;
-}
+bool ProcessFreeBSD::IsStopped() {
+ switch (GetPrivateState()) {
+ default:
+ break;
-const DataBufferSP
-ProcessFreeBSD::GetAuxvData ()
-{
- // If we're the local platform, we can ask the host for auxv data.
- PlatformSP platform_sp = GetTarget().GetPlatform ();
- if (platform_sp && platform_sp->IsHost ())
- return lldb_private::Host::GetAuxvData(this);
-
- // Somewhat unexpected - the process is not running locally or we don't have a platform.
- assert (false && "no platform or not the host - how did we get here with ProcessFreeBSD?");
- return DataBufferSP ();
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ return true;
+ }
+
+ return false;
+}
+
+bool ProcessFreeBSD::IsAThreadRunning() {
+ bool is_running = false;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ uint32_t thread_count = m_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < thread_count; ++i) {
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(i, false).get());
+ StateType thread_state = thread->GetState();
+ if (thread_state == eStateRunning || thread_state == eStateStepping) {
+ is_running = true;
+ break;
+ }
+ }
+ return is_running;
+}
+
+const DataBufferSP ProcessFreeBSD::GetAuxvData() {
+ // If we're the local platform, we can ask the host for auxv data.
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+ if (platform_sp && platform_sp->IsHost())
+ return lldb_private::Host::GetAuxvData(this);
+
+ // Somewhat unexpected - the process is not running locally or we don't have a
+ // platform.
+ assert(
+ false &&
+ "no platform or not the host - how did we get here with ProcessFreeBSD?");
+ return DataBufferSP();
}
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
index 888e2a90ad76..cd38989f973c 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
@@ -1,4 +1,5 @@
-//===-- ProcessFreeBSD.h ------------------------------------------*- C++ -*-===//
+//===-- ProcessFreeBSD.h ------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,233 +19,200 @@
#include <set>
// Other libraries and framework includes
+#include "ProcessFreeBSD.h"
+#include "ProcessMessage.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ThreadList.h"
-#include "ProcessMessage.h"
-#include "ProcessFreeBSD.h"
class ProcessMonitor;
class FreeBSDThread;
-class ProcessFreeBSD :
- public lldb_private::Process
-{
+class ProcessFreeBSD : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Static functions.
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
+ //------------------------------------------------------------------
+ // Static functions.
+ //------------------------------------------------------------------
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec *crash_file_path);
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessFreeBSD(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- lldb::UnixSignalsSP &unix_signals_sp);
+ //------------------------------------------------------------------
+ // Constructors and destructors
+ //------------------------------------------------------------------
+ ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ lldb::UnixSignalsSP &unix_signals_sp);
- ~ProcessFreeBSD();
+ ~ProcessFreeBSD();
- virtual lldb_private::Error
- WillResume() override;
+ virtual lldb_private::Error WillResume() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual lldb_private::ConstString GetPluginName() override;
- virtual uint32_t
- GetPluginVersion() override;
+ virtual uint32_t GetPluginVersion() override;
public:
- //------------------------------------------------------------------
- // Process protocol.
- //------------------------------------------------------------------
- void
- Finalize() override;
+ //------------------------------------------------------------------
+ // Process protocol.
+ //------------------------------------------------------------------
+ void Finalize() override;
- bool
- CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
- lldb_private::Error
- WillLaunch(lldb_private::Module *module) override;
+ lldb_private::Error WillLaunch(lldb_private::Module *module) override;
- lldb_private::Error
- DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override;
+ lldb_private::Error DoAttachToProcessWithID(
+ lldb::pid_t pid,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
- lldb_private::Error
- DoLaunch (lldb_private::Module *exe_module,
- lldb_private::ProcessLaunchInfo &launch_info) override;
+ lldb_private::Error
+ DoLaunch(lldb_private::Module *exe_module,
+ lldb_private::ProcessLaunchInfo &launch_info) override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb_private::Error
- DoResume() override;
+ lldb_private::Error DoResume() override;
- lldb_private::Error
- DoHalt(bool &caused_stop) override;
+ lldb_private::Error DoHalt(bool &caused_stop) override;
- lldb_private::Error
- DoDetach(bool keep_stopped) override;
+ lldb_private::Error DoDetach(bool keep_stopped) override;
- lldb_private::Error
- DoSignal(int signal) override;
+ lldb_private::Error DoSignal(int signal) override;
- lldb_private::Error
- DoDestroy() override;
+ lldb_private::Error DoDestroy() override;
- void
- DoDidExec() override;
+ void DoDidExec() override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- bool
- IsAlive() override;
+ bool IsAlive() override;
- size_t
- DoReadMemory(lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- lldb_private::Error &error) override;
+ size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
- size_t
- DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Error &error) override;
+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ lldb_private::Error &error) override;
- lldb::addr_t
- DoAllocateMemory(size_t size, uint32_t permissions,
- lldb_private::Error &error) override;
+ lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+ lldb_private::Error &error) override;
- lldb_private::Error
- DoDeallocateMemory(lldb::addr_t ptr) override;
+ lldb_private::Error DoDeallocateMemory(lldb::addr_t ptr) override;
- virtual size_t
- GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site);
+ virtual size_t
+ GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite *bp_site);
- lldb_private::Error
- EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+ lldb_private::Error
+ EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- lldb_private::Error
- DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+ lldb_private::Error
+ DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- lldb_private::Error
- EnableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override;
+ lldb_private::Error EnableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
- lldb_private::Error
- DisableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override;
+ lldb_private::Error DisableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
- lldb_private::Error
- GetWatchpointSupportInfo(uint32_t &num) override;
+ lldb_private::Error GetWatchpointSupportInfo(uint32_t &num) override;
- lldb_private::Error
- GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
+ lldb_private::Error GetWatchpointSupportInfo(uint32_t &num,
+ bool &after) override;
- virtual uint32_t
- UpdateThreadListIfNeeded();
+ virtual uint32_t UpdateThreadListIfNeeded();
- bool
- UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
- virtual lldb::ByteOrder
- GetByteOrder() const;
+ virtual lldb::ByteOrder GetByteOrder() const;
- lldb::addr_t
- GetImageInfoAddress() override;
+ lldb::addr_t GetImageInfoAddress() override;
- size_t
- PutSTDIN(const char *buf, size_t len, lldb_private::Error &error) override;
+ size_t PutSTDIN(const char *buf, size_t len,
+ lldb_private::Error &error) override;
- const lldb::DataBufferSP
- GetAuxvData () override;
+ const lldb::DataBufferSP GetAuxvData() override;
- //--------------------------------------------------------------------------
- // ProcessFreeBSD internal API.
+ //--------------------------------------------------------------------------
+ // ProcessFreeBSD internal API.
- /// Registers the given message with this process.
- virtual void
- SendMessage(const ProcessMessage &message);
+ /// Registers the given message with this process.
+ virtual void SendMessage(const ProcessMessage &message);
- ProcessMonitor &
- GetMonitor() { assert(m_monitor); return *m_monitor; }
+ ProcessMonitor &GetMonitor() {
+ assert(m_monitor);
+ return *m_monitor;
+ }
- lldb_private::FileSpec
- GetFileSpec(const lldb_private::FileAction *file_action,
- const lldb_private::FileSpec &default_file_spec,
- const lldb_private::FileSpec &dbg_pts_file_spec);
+ lldb_private::FileSpec
+ GetFileSpec(const lldb_private::FileAction *file_action,
+ const lldb_private::FileSpec &default_file_spec,
+ const lldb_private::FileSpec &dbg_pts_file_spec);
- /// Adds the thread to the list of threads for which we have received the initial stopping signal.
- /// The \p stop_tid parameter indicates the thread which the stop happened for.
- bool
- AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
+ /// Adds the thread to the list of threads for which we have received the
+ /// initial stopping signal.
+ /// The \p stop_tid parameter indicates the thread which the stop happened
+ /// for.
+ bool AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
- bool
- WaitingForInitialStop(lldb::tid_t stop_tid);
+ bool WaitingForInitialStop(lldb::tid_t stop_tid);
- virtual FreeBSDThread *
- CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
+ virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process,
+ lldb::tid_t tid);
protected:
- /// Target byte order.
- lldb::ByteOrder m_byte_order;
-
- /// Process monitor;
- ProcessMonitor *m_monitor;
+ /// Target byte order.
+ lldb::ByteOrder m_byte_order;
- /// The module we are executing.
- lldb_private::Module *m_module;
+ /// Process monitor;
+ ProcessMonitor *m_monitor;
- /// Message queue notifying this instance of inferior process state changes.
- std::recursive_mutex m_message_mutex;
- std::queue<ProcessMessage> m_message_queue;
+ /// The module we are executing.
+ lldb_private::Module *m_module;
- /// Drive any exit events to completion.
- bool m_exit_now;
+ /// Message queue notifying this instance of inferior process state changes.
+ std::recursive_mutex m_message_mutex;
+ std::queue<ProcessMessage> m_message_queue;
- /// Returns true if the process has exited.
- bool HasExited();
+ /// Drive any exit events to completion.
+ bool m_exit_now;
- /// Returns true if the process is stopped.
- bool IsStopped();
+ /// Returns true if the process has exited.
+ bool HasExited();
- /// Returns true if at least one running is currently running
- bool IsAThreadRunning();
+ /// Returns true if the process is stopped.
+ bool IsStopped();
- typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
- MMapMap m_addr_to_mmap_size;
+ /// Returns true if at least one running is currently running
+ bool IsAThreadRunning();
- typedef std::set<lldb::tid_t> ThreadStopSet;
- /// Every thread begins with a stop signal. This keeps track
- /// of the threads for which we have received the stop signal.
- ThreadStopSet m_seen_initial_stop;
+ typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+ MMapMap m_addr_to_mmap_size;
- friend class FreeBSDThread;
+ typedef std::set<lldb::tid_t> ThreadStopSet;
+ /// Every thread begins with a stop signal. This keeps track
+ /// of the threads for which we have received the stop signal.
+ ThreadStopSet m_seen_initial_stop;
- typedef std::vector<lldb::tid_t> tid_collection;
- tid_collection m_suspend_tids;
- tid_collection m_run_tids;
- tid_collection m_step_tids;
+ friend class FreeBSDThread;
- int m_resume_signo;
+ typedef std::vector<lldb::tid_t> tid_collection;
+ tid_collection m_suspend_tids;
+ tid_collection m_run_tids;
+ tid_collection m_step_tids;
+ int m_resume_signo;
};
-#endif // liblldb_ProcessFreeBSD_H_
+#endif // liblldb_ProcessFreeBSD_H_
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 16707a5c8b97..afc649de3b65 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -10,14 +10,14 @@
// C Includes
#include <errno.h>
#include <poll.h>
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
#include <signal.h>
+#include <stdint.h>
+#include <string.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <unistd.h>
// C++ Includes
// Other libraries and framework includes
@@ -26,20 +26,20 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/PseudoTerminal.h"
-#include "Plugins/Process/POSIX/CrashReason.h"
#include "FreeBSDThread.h"
+#include "Plugins/Process/POSIX/CrashReason.h"
#include "ProcessFreeBSD.h"
-#include "ProcessPOSIXLog.h"
#include "ProcessMonitor.h"
+#include "ProcessPOSIXLog.h"
extern "C" {
- extern char ** environ;
- }
+extern char **environ;
+}
using namespace lldb;
using namespace lldb_private;
@@ -49,96 +49,103 @@ using namespace lldb_private;
#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
// Wrapper for ptrace to catch errors and log calls.
-const char *
-Get_PT_IO_OP(int op)
-{
- switch (op) {
- case PIOD_READ_D: return "READ_D";
- case PIOD_WRITE_D: return "WRITE_D";
- case PIOD_READ_I: return "READ_I";
- case PIOD_WRITE_I: return "WRITE_I";
- default: return "Unknown op";
- }
+const char *Get_PT_IO_OP(int op) {
+ switch (op) {
+ case PIOD_READ_D:
+ return "READ_D";
+ case PIOD_WRITE_D:
+ return "WRITE_D";
+ case PIOD_READ_I:
+ return "READ_I";
+ case PIOD_WRITE_I:
+ return "WRITE_I";
+ default:
+ return "Unknown op";
+ }
}
// Wrapper for ptrace to catch errors and log calls.
-// Note that ptrace sets errno on error because -1 is reserved as a valid result.
-extern long
-PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
- const char* reqName, const char* file, int line)
-{
- long int result;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- if (log) {
- log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
- reqName, pid, addr, data, file, line);
- if (req == PT_IO) {
- struct ptrace_io_desc *pi = (struct ptrace_io_desc *) addr;
-
- log->Printf("PT_IO: op=%s offs=%zx size=%zu",
- Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len);
- }
+// Note that ptrace sets errno on error because -1 is reserved as a valid
+// result.
+extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
+ const char *reqName, const char *file, int line) {
+ long int result;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+
+ if (log) {
+ log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
+ reqName, pid, addr, data, file, line);
+ if (req == PT_IO) {
+ struct ptrace_io_desc *pi = (struct ptrace_io_desc *)addr;
+
+ log->Printf("PT_IO: op=%s offs=%zx size=%zu", Get_PT_IO_OP(pi->piod_op),
+ (size_t)pi->piod_offs, pi->piod_len);
}
-
- //PtraceDisplayBytes(req, data);
-
- errno = 0;
- result = ptrace(req, pid, (caddr_t) addr, data);
-
- //PtraceDisplayBytes(req, data);
-
- if (log && errno != 0)
- {
- const char* str;
- switch (errno)
- {
- case ESRCH: str = "ESRCH"; break;
- case EINVAL: str = "EINVAL"; break;
- case EBUSY: str = "EBUSY"; break;
- case EPERM: str = "EPERM"; break;
- default: str = "<unknown>";
- }
- log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
+ }
+
+ // PtraceDisplayBytes(req, data);
+
+ errno = 0;
+ result = ptrace(req, pid, (caddr_t)addr, data);
+
+ // PtraceDisplayBytes(req, data);
+
+ if (log && errno != 0) {
+ const char *str;
+ switch (errno) {
+ case ESRCH:
+ str = "ESRCH";
+ break;
+ case EINVAL:
+ str = "EINVAL";
+ break;
+ case EBUSY:
+ str = "EBUSY";
+ break;
+ case EPERM:
+ str = "EPERM";
+ break;
+ default:
+ str = "<unknown>";
}
+ log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
+ }
- if (log) {
+ if (log) {
#ifdef __amd64__
- if (req == PT_GETREGS) {
- struct reg *r = (struct reg *) addr;
-
- log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
- r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
- }
- if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
- struct dbreg *r = (struct dbreg *) addr;
- char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
-
- for (int i = 0; i <= 7; i++)
- log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
- }
-#endif
+ if (req == PT_GETREGS) {
+ struct reg *r = (struct reg *)addr;
+
+ log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
+ r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
}
-
- return result;
+ if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
+ struct dbreg *r = (struct dbreg *)addr;
+ char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
+
+ for (int i = 0; i <= 7; i++)
+ log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
+ }
+#endif
+ }
+
+ return result;
}
// Wrapper for ptrace when logging is not required.
// Sets errno to 0 prior to calling ptrace.
-extern long
-PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data)
-{
- long result = 0;
- errno = 0;
- result = ptrace(req, pid, (caddr_t)addr, data);
- return result;
+extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) {
+ long result = 0;
+ errno = 0;
+ result = ptrace(req, pid, (caddr_t)addr, data);
+ return result;
}
-#define PTRACE(req, pid, addr, data) \
- PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
+#define PTRACE(req, pid, addr, data) \
+ PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
#else
- PtraceWrapper((req), (pid), (addr), (data))
+PtraceWrapper((req), (pid), (addr), (data))
#endif
//------------------------------------------------------------------------------
@@ -146,58 +153,50 @@ PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data)
// ProcessMonitor::WriteMemory. This enables mutual recursion between these
// functions without needed to go thru the thread funnel.
-static size_t
-DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf, size_t size,
- Error &error)
-{
- struct ptrace_io_desc pi_desc;
+static size_t DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf,
+ size_t size, Error &error) {
+ struct ptrace_io_desc pi_desc;
- pi_desc.piod_op = PIOD_READ_D;
- pi_desc.piod_offs = (void *)vm_addr;
- pi_desc.piod_addr = buf;
- pi_desc.piod_len = size;
+ pi_desc.piod_op = PIOD_READ_D;
+ pi_desc.piod_offs = (void *)vm_addr;
+ pi_desc.piod_addr = buf;
+ pi_desc.piod_len = size;
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
- error.SetErrorToErrno();
- return pi_desc.piod_len;
+ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
+ error.SetErrorToErrno();
+ return pi_desc.piod_len;
}
-static size_t
-DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr, const void *buf,
- size_t size, Error &error)
-{
- struct ptrace_io_desc pi_desc;
+static size_t DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr,
+ const void *buf, size_t size, Error &error) {
+ struct ptrace_io_desc pi_desc;
- pi_desc.piod_op = PIOD_WRITE_D;
- pi_desc.piod_offs = (void *)vm_addr;
- pi_desc.piod_addr = (void *)buf;
- pi_desc.piod_len = size;
+ pi_desc.piod_op = PIOD_WRITE_D;
+ pi_desc.piod_offs = (void *)vm_addr;
+ pi_desc.piod_addr = (void *)buf;
+ pi_desc.piod_len = size;
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
- error.SetErrorToErrno();
- return pi_desc.piod_len;
+ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
+ error.SetErrorToErrno();
+ return pi_desc.piod_len;
}
// Simple helper function to ensure flags are enabled on the given file
// descriptor.
-static bool
-EnsureFDFlags(int fd, int flags, Error &error)
-{
- int status;
-
- if ((status = fcntl(fd, F_GETFL)) == -1)
- {
- error.SetErrorToErrno();
- return false;
- }
+static bool EnsureFDFlags(int fd, int flags, Error &error) {
+ int status;
- if (fcntl(fd, F_SETFL, status | flags) == -1)
- {
- error.SetErrorToErrno();
- return false;
- }
+ if ((status = fcntl(fd, F_GETFL)) == -1) {
+ error.SetErrorToErrno();
+ return false;
+ }
+
+ if (fcntl(fd, F_SETFL, status | flags) == -1) {
+ error.SetErrorToErrno();
+ return false;
+ }
- return true;
+ return true;
}
//------------------------------------------------------------------------------
@@ -211,1383 +210,1216 @@ EnsureFDFlags(int fd, int flags, Error &error)
/// task. The Operation class provides an abstract base for all services the
/// ProcessMonitor must perform via the single virtual function Execute, thus
/// encapsulating the code that needs to run in the privileged context.
-class Operation
-{
+class Operation {
public:
- virtual ~Operation() {}
- virtual void Execute(ProcessMonitor *monitor) = 0;
+ virtual ~Operation() {}
+ virtual void Execute(ProcessMonitor *monitor) = 0;
};
//------------------------------------------------------------------------------
/// @class ReadOperation
/// @brief Implements ProcessMonitor::ReadMemory.
-class ReadOperation : public Operation
-{
+class ReadOperation : public Operation {
public:
- ReadOperation(lldb::addr_t addr, void *buff, size_t size,
- Error &error, size_t &result)
- : m_addr(addr), m_buff(buff), m_size(size),
- m_error(error), m_result(result)
- { }
+ ReadOperation(lldb::addr_t addr, void *buff, size_t size, Error &error,
+ size_t &result)
+ : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::addr_t m_addr;
- void *m_buff;
- size_t m_size;
- Error &m_error;
- size_t &m_result;
+ lldb::addr_t m_addr;
+ void *m_buff;
+ size_t m_size;
+ Error &m_error;
+ size_t &m_result;
};
-void
-ReadOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void ReadOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
+ m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
}
//------------------------------------------------------------------------------
/// @class WriteOperation
/// @brief Implements ProcessMonitor::WriteMemory.
-class WriteOperation : public Operation
-{
+class WriteOperation : public Operation {
public:
- WriteOperation(lldb::addr_t addr, const void *buff, size_t size,
- Error &error, size_t &result)
- : m_addr(addr), m_buff(buff), m_size(size),
- m_error(error), m_result(result)
- { }
+ WriteOperation(lldb::addr_t addr, const void *buff, size_t size, Error &error,
+ size_t &result)
+ : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::addr_t m_addr;
- const void *m_buff;
- size_t m_size;
- Error &m_error;
- size_t &m_result;
+ lldb::addr_t m_addr;
+ const void *m_buff;
+ size_t m_size;
+ Error &m_error;
+ size_t &m_result;
};
-void
-WriteOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void WriteOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
+ m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
}
//------------------------------------------------------------------------------
/// @class ReadRegOperation
/// @brief Implements ProcessMonitor::ReadRegisterValue.
-class ReadRegOperation : public Operation
-{
+class ReadRegOperation : public Operation {
public:
- ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
- RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_size(size),
- m_value(value), m_result(result)
- { }
+ ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
+ RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- unsigned m_size;
- RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ unsigned m_size;
+ RegisterValue &m_value;
+ bool &m_result;
};
-void
-ReadRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct reg regs;
- int rc;
-
- if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
- m_result = false;
- } else {
- // 'struct reg' contains only 32- or 64-bit register values. Punt on
- // others. Also, not all entries may be uintptr_t sized, such as 32-bit
- // processes on powerpc64 (probably the same for i386 on amd64)
- if (m_size == sizeof(uint32_t))
- m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
- else if (m_size == sizeof(uint64_t))
- m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
- else
- memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
- m_result = true;
- }
+void ReadRegOperation::Execute(ProcessMonitor *monitor) {
+ struct reg regs;
+ int rc;
+
+ if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
+ m_result = false;
+ } else {
+ // 'struct reg' contains only 32- or 64-bit register values. Punt on
+ // others. Also, not all entries may be uintptr_t sized, such as 32-bit
+ // processes on powerpc64 (probably the same for i386 on amd64)
+ if (m_size == sizeof(uint32_t))
+ m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
+ else if (m_size == sizeof(uint64_t))
+ m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
+ else
+ memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
+ m_result = true;
+ }
}
//------------------------------------------------------------------------------
/// @class WriteRegOperation
/// @brief Implements ProcessMonitor::WriteRegisterValue.
-class WriteRegOperation : public Operation
-{
+class WriteRegOperation : public Operation {
public:
- WriteRegOperation(lldb::tid_t tid, unsigned offset,
- const RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset),
- m_value(value), m_result(result)
- { }
+ WriteRegOperation(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- const RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ const RegisterValue &m_value;
+ bool &m_result;
};
-void
-WriteRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct reg regs;
+void WriteRegOperation::Execute(ProcessMonitor *monitor) {
+ struct reg regs;
- if (PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0) < 0) {
- m_result = false;
- return;
- }
- *(uintptr_t *)(((caddr_t)&regs) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
- if (PTRACE(PT_SETREGS, m_tid, (caddr_t)&regs, 0) < 0)
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0) < 0) {
+ m_result = false;
+ return;
+ }
+ *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
+ (uintptr_t)m_value.GetAsUInt64();
+ if (PTRACE(PT_SETREGS, m_tid, (caddr_t)&regs, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadDebugRegOperation
/// @brief Implements ProcessMonitor::ReadDebugRegisterValue.
-class ReadDebugRegOperation : public Operation
-{
+class ReadDebugRegOperation : public Operation {
public:
- ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
- RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_size(size),
- m_value(value), m_result(result)
- { }
+ ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
+ RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- unsigned m_size;
- RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ unsigned m_size;
+ RegisterValue &m_value;
+ bool &m_result;
};
-void
-ReadDebugRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct dbreg regs;
- int rc;
-
- if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
- m_result = false;
- } else {
- if (m_size == sizeof(uintptr_t))
- m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
- else
- memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
- m_result = true;
- }
+void ReadDebugRegOperation::Execute(ProcessMonitor *monitor) {
+ struct dbreg regs;
+ int rc;
+
+ if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
+ m_result = false;
+ } else {
+ if (m_size == sizeof(uintptr_t))
+ m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
+ else
+ memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
+ m_result = true;
+ }
}
//------------------------------------------------------------------------------
/// @class WriteDebugRegOperation
/// @brief Implements ProcessMonitor::WriteDebugRegisterValue.
-class WriteDebugRegOperation : public Operation
-{
+class WriteDebugRegOperation : public Operation {
public:
- WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
- const RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset),
- m_value(value), m_result(result)
- { }
+ WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- const RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ const RegisterValue &m_value;
+ bool &m_result;
};
-void
-WriteDebugRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct dbreg regs;
+void WriteDebugRegOperation::Execute(ProcessMonitor *monitor) {
+ struct dbreg regs;
- if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0) < 0) {
- m_result = false;
- return;
- }
- *(uintptr_t *)(((caddr_t)&regs) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
- if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)&regs, 0) < 0)
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0) < 0) {
+ m_result = false;
+ return;
+ }
+ *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
+ (uintptr_t)m_value.GetAsUInt64();
+ if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)&regs, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadGPROperation
/// @brief Implements ProcessMonitor::ReadGPR.
-class ReadGPROperation : public Operation
-{
+class ReadGPROperation : public Operation {
public:
- ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-ReadGPROperation::Execute(ProcessMonitor *monitor)
-{
- int rc;
+void ReadGPROperation::Execute(ProcessMonitor *monitor) {
+ int rc;
- errno = 0;
- rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
- if (errno != 0)
- m_result = false;
- else
- m_result = true;
+ errno = 0;
+ rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
+ if (errno != 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadFPROperation
/// @brief Implements ProcessMonitor::ReadFPR.
-class ReadFPROperation : public Operation
-{
+class ReadFPROperation : public Operation {
public:
- ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-ReadFPROperation::Execute(ProcessMonitor *monitor)
-{
- if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
+void ReadFPROperation::Execute(ProcessMonitor *monitor) {
+ if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteGPROperation
/// @brief Implements ProcessMonitor::WriteGPR.
-class WriteGPROperation : public Operation
-{
+class WriteGPROperation : public Operation {
public:
- WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-WriteGPROperation::Execute(ProcessMonitor *monitor)
-{
- if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
+void WriteGPROperation::Execute(ProcessMonitor *monitor) {
+ if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteFPROperation
/// @brief Implements ProcessMonitor::WriteFPR.
-class WriteFPROperation : public Operation
-{
+class WriteFPROperation : public Operation {
public:
- WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-WriteFPROperation::Execute(ProcessMonitor *monitor)
-{
- if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
+void WriteFPROperation::Execute(ProcessMonitor *monitor) {
+ if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ResumeOperation
/// @brief Implements ProcessMonitor::Resume.
-class ResumeOperation : public Operation
-{
+class ResumeOperation : public Operation {
public:
- ResumeOperation(uint32_t signo, bool &result) :
- m_signo(signo), m_result(result) { }
+ ResumeOperation(uint32_t signo, bool &result)
+ : m_signo(signo), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- uint32_t m_signo;
- bool &m_result;
+ uint32_t m_signo;
+ bool &m_result;
};
-void
-ResumeOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
- int data = 0;
+void ResumeOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
+ int data = 0;
- if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = m_signo;
+ if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = m_signo;
- if (PTRACE(PT_CONTINUE, pid, (caddr_t)1, data))
- {
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ if (PTRACE(PT_CONTINUE, pid, (caddr_t)1, data)) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- if (log)
- log->Printf ("ResumeOperation (%" PRIu64 ") failed: %s", pid, strerror(errno));
- m_result = false;
- }
- else
- m_result = true;
+ if (log)
+ log->Printf("ResumeOperation (%" PRIu64 ") failed: %s", pid,
+ strerror(errno));
+ m_result = false;
+ } else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class SingleStepOperation
/// @brief Implements ProcessMonitor::SingleStep.
-class SingleStepOperation : public Operation
-{
+class SingleStepOperation : public Operation {
public:
- SingleStepOperation(uint32_t signo, bool &result)
- : m_signo(signo), m_result(result) { }
+ SingleStepOperation(uint32_t signo, bool &result)
+ : m_signo(signo), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- uint32_t m_signo;
- bool &m_result;
+ uint32_t m_signo;
+ bool &m_result;
};
-void
-SingleStepOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
- int data = 0;
+void SingleStepOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
+ int data = 0;
- if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = m_signo;
+ if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = m_signo;
- if (PTRACE(PT_STEP, pid, NULL, data))
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_STEP, pid, NULL, data))
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class LwpInfoOperation
/// @brief Implements ProcessMonitor::GetLwpInfo.
-class LwpInfoOperation : public Operation
-{
+class LwpInfoOperation : public Operation {
public:
- LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
- : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { }
+ LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
+ : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_info;
- bool &m_result;
- int &m_err;
+ lldb::tid_t m_tid;
+ void *m_info;
+ bool &m_result;
+ int &m_err;
};
-void
-LwpInfoOperation::Execute(ProcessMonitor *monitor)
-{
- struct ptrace_lwpinfo plwp;
-
- if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
- m_result = false;
- m_err = errno;
- } else {
- memcpy(m_info, &plwp, sizeof(plwp));
- m_result = true;
- }
+void LwpInfoOperation::Execute(ProcessMonitor *monitor) {
+ struct ptrace_lwpinfo plwp;
+
+ if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
+ m_result = false;
+ m_err = errno;
+ } else {
+ memcpy(m_info, &plwp, sizeof(plwp));
+ m_result = true;
+ }
}
//------------------------------------------------------------------------------
/// @class ThreadSuspendOperation
/// @brief Implements ProcessMonitor::ThreadSuspend.
-class ThreadSuspendOperation : public Operation
-{
+class ThreadSuspendOperation : public Operation {
public:
- ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
- : m_tid(tid), m_suspend(suspend), m_result(result) { }
+ ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
+ : m_tid(tid), m_suspend(suspend), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- bool m_suspend;
- bool &m_result;
-} ;
-
-void
-ThreadSuspendOperation::Execute(ProcessMonitor *monitor)
-{
- m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
-}
-
+ lldb::tid_t m_tid;
+ bool m_suspend;
+ bool &m_result;
+};
+void ThreadSuspendOperation::Execute(ProcessMonitor *monitor) {
+ m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
+}
//------------------------------------------------------------------------------
/// @class EventMessageOperation
/// @brief Implements ProcessMonitor::GetEventMessage.
-class EventMessageOperation : public Operation
-{
+class EventMessageOperation : public Operation {
public:
- EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
- : m_tid(tid), m_message(message), m_result(result) { }
+ EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
+ : m_tid(tid), m_message(message), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned long *m_message;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned long *m_message;
+ bool &m_result;
};
-void
-EventMessageOperation::Execute(ProcessMonitor *monitor)
-{
- struct ptrace_lwpinfo plwp;
+void EventMessageOperation::Execute(ProcessMonitor *monitor) {
+ struct ptrace_lwpinfo plwp;
- if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
- m_result = false;
- else {
- if (plwp.pl_flags & PL_FLAG_FORKED) {
- *m_message = plwp.pl_child_pid;
- m_result = true;
- } else
- m_result = false;
- }
+ if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
+ m_result = false;
+ else {
+ if (plwp.pl_flags & PL_FLAG_FORKED) {
+ *m_message = plwp.pl_child_pid;
+ m_result = true;
+ } else
+ m_result = false;
+ }
}
//------------------------------------------------------------------------------
/// @class KillOperation
/// @brief Implements ProcessMonitor::Kill.
-class KillOperation : public Operation
-{
+class KillOperation : public Operation {
public:
- KillOperation(bool &result) : m_result(result) { }
+ KillOperation(bool &result) : m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- bool &m_result;
+ bool &m_result;
};
-void
-KillOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void KillOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- if (PTRACE(PT_KILL, pid, NULL, 0))
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_KILL, pid, NULL, 0))
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class DetachOperation
/// @brief Implements ProcessMonitor::Detach.
-class DetachOperation : public Operation
-{
+class DetachOperation : public Operation {
public:
- DetachOperation(Error &result) : m_error(result) { }
+ DetachOperation(Error &result) : m_error(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- Error &m_error;
+ Error &m_error;
};
-void
-DetachOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void DetachOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
- m_error.SetErrorToErrno();
-
+ if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
+ m_error.SetErrorToErrno();
}
ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
- : m_monitor(monitor)
-{
- sem_init(&m_semaphore, 0, 0);
+ : m_monitor(monitor) {
+ sem_init(&m_semaphore, 0, 0);
}
-ProcessMonitor::OperationArgs::~OperationArgs()
-{
- sem_destroy(&m_semaphore);
-}
+ProcessMonitor::OperationArgs::~OperationArgs() { sem_destroy(&m_semaphore); }
ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
lldb_private::Module *module,
- char const **argv,
- char const **envp,
+ char const **argv, char const **envp,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir)
- : OperationArgs(monitor),
- m_module(module),
- m_argv(argv),
- m_envp(envp),
- m_stdin_file_spec(stdin_file_spec),
- m_stdout_file_spec(stdout_file_spec),
- m_stderr_file_spec(stderr_file_spec),
- m_working_dir(working_dir) { }
+ : OperationArgs(monitor), m_module(module), m_argv(argv), m_envp(envp),
+ m_stdin_file_spec(stdin_file_spec), m_stdout_file_spec(stdout_file_spec),
+ m_stderr_file_spec(stderr_file_spec), m_working_dir(working_dir) {}
-ProcessMonitor::LaunchArgs::~LaunchArgs()
-{ }
+ProcessMonitor::LaunchArgs::~LaunchArgs() {}
-ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor,
- lldb::pid_t pid)
- : OperationArgs(monitor), m_pid(pid) { }
+ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid)
+ : OperationArgs(monitor), m_pid(pid) {}
-ProcessMonitor::AttachArgs::~AttachArgs()
-{ }
+ProcessMonitor::AttachArgs::~AttachArgs() {}
//------------------------------------------------------------------------------
/// The basic design of the ProcessMonitor is built around two threads.
///
/// One thread (@see SignalThread) simply blocks on a call to waitpid() looking
/// for changes in the debugee state. When a change is detected a
-/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This thread
+/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This
+/// thread
/// "drives" state changes in the debugger.
///
/// The second thread (@see OperationThread) is responsible for two things 1)
/// launching or attaching to the inferior process, and then 2) servicing
/// operations such as register reads/writes, stepping, etc. See the comments
/// on the Operation class for more info as to why this is needed.
-ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process,
- Module *module,
- const char *argv[],
- const char *envp[],
- const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- const lldb_private::ProcessLaunchInfo & /* launch_info */,
- lldb_private::Error &error)
+ProcessMonitor::ProcessMonitor(
+ ProcessFreeBSD *process, Module *module, const char *argv[],
+ const char *envp[], const FileSpec &stdin_file_spec,
+ const FileSpec &stdout_file_spec, const FileSpec &stderr_file_spec,
+ const FileSpec &working_dir,
+ const lldb_private::ProcessLaunchInfo & /* launch_info */,
+ lldb_private::Error &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
- m_pid(LLDB_INVALID_PROCESS_ID),
- m_terminal_fd(-1),
- m_operation(0)
-{
- using namespace std::placeholders;
-
- std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp,
- stdin_file_spec,
- stdout_file_spec,
- stderr_file_spec,
- working_dir));
-
-
- sem_init(&m_operation_pending, 0, 0);
- sem_init(&m_operation_done, 0, 0);
-
- StartLaunchOpThread(args.get(), error);
- if (!error.Success())
- return;
+ m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
+ using namespace std::placeholders;
-WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore))
- {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else
- {
- error.SetErrorToErrno();
- return;
- }
- }
+ std::unique_ptr<LaunchArgs> args(
+ new LaunchArgs(this, module, argv, envp, stdin_file_spec,
+ stdout_file_spec, stderr_file_spec, working_dir));
- // Check that the launch was a success.
- if (!args->m_error.Success())
- {
- StopOpThread();
- error = args->m_error;
- return;
- }
+ sem_init(&m_operation_pending, 0, 0);
+ sem_init(&m_operation_done, 0, 0);
+
+ StartLaunchOpThread(args.get(), error);
+ if (!error.Success())
+ return;
- // Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
- std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true);
- if (!m_monitor_thread.IsJoinable())
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Process launch failed.");
- return;
+WAIT_AGAIN:
+ // Wait for the operation thread to initialize.
+ if (sem_wait(&args->m_semaphore)) {
+ if (errno == EINTR)
+ goto WAIT_AGAIN;
+ else {
+ error.SetErrorToErrno();
+ return;
}
-}
+ }
-ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process,
- lldb::pid_t pid,
+ // Check that the launch was a success.
+ if (!args->m_error.Success()) {
+ StopOpThread();
+ error = args->m_error;
+ return;
+ }
+
+ // Finally, start monitoring the child process for change in state.
+ m_monitor_thread = Host::StartMonitoringChildProcess(
+ std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
+ GetPID(), true);
+ if (!m_monitor_thread.IsJoinable()) {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Process launch failed.");
+ return;
+ }
+}
+
+ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
lldb_private::Error &error)
- : m_process(static_cast<ProcessFreeBSD *>(process)),
- m_pid(pid),
- m_terminal_fd(-1),
- m_operation(0)
-{
- using namespace std::placeholders;
-
- sem_init(&m_operation_pending, 0, 0);
- sem_init(&m_operation_done, 0, 0);
+ : m_process(static_cast<ProcessFreeBSD *>(process)), m_pid(pid),
+ m_terminal_fd(-1), m_operation(0) {
+ using namespace std::placeholders;
+ sem_init(&m_operation_pending, 0, 0);
+ sem_init(&m_operation_done, 0, 0);
- std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid));
+ std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid));
- StartAttachOpThread(args.get(), error);
- if (!error.Success())
- return;
+ StartAttachOpThread(args.get(), error);
+ if (!error.Success())
+ return;
WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore))
- {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else
- {
- error.SetErrorToErrno();
- return;
- }
+ // Wait for the operation thread to initialize.
+ if (sem_wait(&args->m_semaphore)) {
+ if (errno == EINTR)
+ goto WAIT_AGAIN;
+ else {
+ error.SetErrorToErrno();
+ return;
}
+ }
- // Check that the attach was a success.
- if (!args->m_error.Success())
- {
- StopOpThread();
- error = args->m_error;
- return;
- }
+ // Check that the attach was a success.
+ if (!args->m_error.Success()) {
+ StopOpThread();
+ error = args->m_error;
+ return;
+ }
- // Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
- std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true);
- if (!m_monitor_thread.IsJoinable())
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Process attach failed.");
- return;
- }
+ // Finally, start monitoring the child process for change in state.
+ m_monitor_thread = Host::StartMonitoringChildProcess(
+ std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
+ GetPID(), true);
+ if (!m_monitor_thread.IsJoinable()) {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Process attach failed.");
+ return;
+ }
}
-ProcessMonitor::~ProcessMonitor()
-{
- StopMonitor();
-}
+ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
//------------------------------------------------------------------------------
// Thread setup and tear down.
-void
-ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error)
-{
- static const char *g_thread_name = "lldb.process.freebsd.operation";
+void ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error) {
+ static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread.IsJoinable())
- return;
+ if (m_operation_thread.IsJoinable())
+ return;
- m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error);
+ m_operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error);
}
-void *
-ProcessMonitor::LaunchOpThread(void *arg)
-{
- LaunchArgs *args = static_cast<LaunchArgs*>(arg);
+void *ProcessMonitor::LaunchOpThread(void *arg) {
+ LaunchArgs *args = static_cast<LaunchArgs *>(arg);
- if (!Launch(args)) {
- sem_post(&args->m_semaphore);
- return NULL;
- }
-
- ServeOperation(args);
+ if (!Launch(args)) {
+ sem_post(&args->m_semaphore);
return NULL;
-}
-
-bool
-ProcessMonitor::Launch(LaunchArgs *args)
-{
- ProcessMonitor *monitor = args->m_monitor;
- ProcessFreeBSD &process = monitor->GetProcess();
- const char **argv = args->m_argv;
- const char **envp = args->m_envp;
- const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
- const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
- const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
- const FileSpec &working_dir = args->m_working_dir;
-
- lldb_utility::PseudoTerminal terminal;
- const size_t err_len = 1024;
- char err_str[err_len];
- ::pid_t pid;
-
- // Propagate the environment if one is not supplied.
- if (envp == NULL || envp[0] == NULL)
- envp = const_cast<const char **>(environ);
-
- if ((pid = terminal.Fork(err_str, err_len)) == -1)
- {
- args->m_error.SetErrorToGenericError();
- args->m_error.SetErrorString("Process fork failed.");
- goto FINISH;
- }
-
- // Recognized child exit status codes.
- enum {
- ePtraceFailed = 1,
- eDupStdinFailed,
- eDupStdoutFailed,
- eDupStderrFailed,
- eChdirFailed,
- eExecFailed,
- eSetGidFailed
- };
-
- // Child process.
- if (pid == 0)
- {
- // Trace this process.
- if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
- exit(ePtraceFailed);
-
- // terminal has already dupped the tty descriptors to stdin/out/err.
- // This closes original fd from which they were copied (and avoids
- // leaking descriptors to the debugged process.
- terminal.CloseSlaveFileDescriptor();
-
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- exit(eSetGidFailed);
-
- // Let us have our own process group.
- setpgid(0, 0);
-
- // Dup file descriptors if needed.
- //
- // FIXME: If two or more of the paths are the same we needlessly open
- // the same file multiple times.
- if (stdin_file_spec)
- if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
- exit(eDupStdinFailed);
-
- if (stdout_file_spec)
- if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
- exit(eDupStdoutFailed);
-
- if (stderr_file_spec)
- if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
- exit(eDupStderrFailed);
-
- // Change working directory
- if (working_dir && 0 != ::chdir(working_dir.GetCString()))
- exit(eChdirFailed);
-
- // Execute. We should never return.
- execve(argv[0],
- const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
- exit(eExecFailed);
- }
-
- // Wait for the child process to to trap on its call to execve.
- ::pid_t wpid;
- int status;
- if ((wpid = waitpid(pid, &status, 0)) < 0)
- {
- args->m_error.SetErrorToErrno();
- goto FINISH;
- }
- else if (WIFEXITED(status))
- {
- // open, dup or execve likely failed for some reason.
- args->m_error.SetErrorToGenericError();
- switch (WEXITSTATUS(status))
- {
- case ePtraceFailed:
- args->m_error.SetErrorString("Child ptrace failed.");
- break;
- case eDupStdinFailed:
- args->m_error.SetErrorString("Child open stdin failed.");
- break;
- case eDupStdoutFailed:
- args->m_error.SetErrorString("Child open stdout failed.");
- break;
- case eDupStderrFailed:
- args->m_error.SetErrorString("Child open stderr failed.");
- break;
- case eChdirFailed:
- args->m_error.SetErrorString("Child failed to set working directory.");
- break;
- case eExecFailed:
- args->m_error.SetErrorString("Child exec failed.");
- break;
- case eSetGidFailed:
- args->m_error.SetErrorString("Child setgid failed.");
- break;
- default:
- args->m_error.SetErrorString("Child returned unknown exit status.");
- break;
- }
- goto FINISH;
+ }
+
+ ServeOperation(args);
+ return NULL;
+}
+
+bool ProcessMonitor::Launch(LaunchArgs *args) {
+ ProcessMonitor *monitor = args->m_monitor;
+ ProcessFreeBSD &process = monitor->GetProcess();
+ const char **argv = args->m_argv;
+ const char **envp = args->m_envp;
+ const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
+ const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
+ const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
+ const FileSpec &working_dir = args->m_working_dir;
+
+ lldb_utility::PseudoTerminal terminal;
+ const size_t err_len = 1024;
+ char err_str[err_len];
+ ::pid_t pid;
+
+ // Propagate the environment if one is not supplied.
+ if (envp == NULL || envp[0] == NULL)
+ envp = const_cast<const char **>(environ);
+
+ if ((pid = terminal.Fork(err_str, err_len)) == -1) {
+ args->m_error.SetErrorToGenericError();
+ args->m_error.SetErrorString("Process fork failed.");
+ goto FINISH;
+ }
+
+ // Recognized child exit status codes.
+ enum {
+ ePtraceFailed = 1,
+ eDupStdinFailed,
+ eDupStdoutFailed,
+ eDupStderrFailed,
+ eChdirFailed,
+ eExecFailed,
+ eSetGidFailed
+ };
+
+ // Child process.
+ if (pid == 0) {
+ // Trace this process.
+ if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
+ exit(ePtraceFailed);
+
+ // terminal has already dupped the tty descriptors to stdin/out/err.
+ // This closes original fd from which they were copied (and avoids
+ // leaking descriptors to the debugged process.
+ terminal.CloseSlaveFileDescriptor();
+
+ // Do not inherit setgid powers.
+ if (setgid(getgid()) != 0)
+ exit(eSetGidFailed);
+
+ // Let us have our own process group.
+ setpgid(0, 0);
+
+ // Dup file descriptors if needed.
+ //
+ // FIXME: If two or more of the paths are the same we needlessly open
+ // the same file multiple times.
+ if (stdin_file_spec)
+ if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
+ exit(eDupStdinFailed);
+
+ if (stdout_file_spec)
+ if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
+ exit(eDupStdoutFailed);
+
+ if (stderr_file_spec)
+ if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
+ exit(eDupStderrFailed);
+
+ // Change working directory
+ if (working_dir && 0 != ::chdir(working_dir.GetCString()))
+ exit(eChdirFailed);
+
+ // Execute. We should never return.
+ execve(argv[0], const_cast<char *const *>(argv),
+ const_cast<char *const *>(envp));
+ exit(eExecFailed);
+ }
+
+ // Wait for the child process to to trap on its call to execve.
+ ::pid_t wpid;
+ int status;
+ if ((wpid = waitpid(pid, &status, 0)) < 0) {
+ args->m_error.SetErrorToErrno();
+ goto FINISH;
+ } else if (WIFEXITED(status)) {
+ // open, dup or execve likely failed for some reason.
+ args->m_error.SetErrorToGenericError();
+ switch (WEXITSTATUS(status)) {
+ case ePtraceFailed:
+ args->m_error.SetErrorString("Child ptrace failed.");
+ break;
+ case eDupStdinFailed:
+ args->m_error.SetErrorString("Child open stdin failed.");
+ break;
+ case eDupStdoutFailed:
+ args->m_error.SetErrorString("Child open stdout failed.");
+ break;
+ case eDupStderrFailed:
+ args->m_error.SetErrorString("Child open stderr failed.");
+ break;
+ case eChdirFailed:
+ args->m_error.SetErrorString("Child failed to set working directory.");
+ break;
+ case eExecFailed:
+ args->m_error.SetErrorString("Child exec failed.");
+ break;
+ case eSetGidFailed:
+ args->m_error.SetErrorString("Child setgid failed.");
+ break;
+ default:
+ args->m_error.SetErrorString("Child returned unknown exit status.");
+ break;
}
- assert(WIFSTOPPED(status) && wpid == (::pid_t)pid &&
- "Could not sync with inferior process.");
+ goto FINISH;
+ }
+ assert(WIFSTOPPED(status) && wpid == (::pid_t)pid &&
+ "Could not sync with inferior process.");
#ifdef notyet
- // Have the child raise an event on exit. This is used to keep the child in
- // limbo until it is destroyed.
- if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0)
- {
- args->m_error.SetErrorToErrno();
- goto FINISH;
- }
+ // Have the child raise an event on exit. This is used to keep the child in
+ // limbo until it is destroyed.
+ if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0) {
+ args->m_error.SetErrorToErrno();
+ goto FINISH;
+ }
#endif
- // Release the master terminal descriptor and pass it off to the
- // ProcessMonitor instance. Similarly stash the inferior pid.
- monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
- monitor->m_pid = pid;
+ // Release the master terminal descriptor and pass it off to the
+ // ProcessMonitor instance. Similarly stash the inferior pid.
+ monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
+ monitor->m_pid = pid;
- // Set the terminal fd to be in non blocking mode (it simplifies the
- // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
- // descriptor to read from).
- if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
- goto FINISH;
+ // Set the terminal fd to be in non blocking mode (it simplifies the
+ // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
+ // descriptor to read from).
+ if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
+ goto FINISH;
- process.SendMessage(ProcessMessage::Attach(pid));
+ process.SendMessage(ProcessMessage::Attach(pid));
FINISH:
- return args->m_error.Success();
+ return args->m_error.Success();
}
-void
-ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error)
-{
- static const char *g_thread_name = "lldb.process.freebsd.operation";
+void ProcessMonitor::StartAttachOpThread(AttachArgs *args,
+ lldb_private::Error &error) {
+ static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread.IsJoinable())
- return;
+ if (m_operation_thread.IsJoinable())
+ return;
- m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error);
+ m_operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error);
}
-void *
-ProcessMonitor::AttachOpThread(void *arg)
-{
- AttachArgs *args = static_cast<AttachArgs*>(arg);
+void *ProcessMonitor::AttachOpThread(void *arg) {
+ AttachArgs *args = static_cast<AttachArgs *>(arg);
- Attach(args);
+ Attach(args);
- ServeOperation(args);
- return NULL;
+ ServeOperation(args);
+ return NULL;
}
-void
-ProcessMonitor::Attach(AttachArgs *args)
-{
- lldb::pid_t pid = args->m_pid;
+void ProcessMonitor::Attach(AttachArgs *args) {
+ lldb::pid_t pid = args->m_pid;
- ProcessMonitor *monitor = args->m_monitor;
- ProcessFreeBSD &process = monitor->GetProcess();
+ ProcessMonitor *monitor = args->m_monitor;
+ ProcessFreeBSD &process = monitor->GetProcess();
- if (pid <= 1)
- {
- args->m_error.SetErrorToGenericError();
- args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
- return;
- }
+ if (pid <= 1) {
+ args->m_error.SetErrorToGenericError();
+ args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
+ return;
+ }
- // Attach to the requested process.
- if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0)
- {
- args->m_error.SetErrorToErrno();
- return;
- }
+ // Attach to the requested process.
+ if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0) {
+ args->m_error.SetErrorToErrno();
+ return;
+ }
- int status;
- if ((status = waitpid(pid, NULL, 0)) < 0)
- {
- args->m_error.SetErrorToErrno();
- return;
- }
+ int status;
+ if ((status = waitpid(pid, NULL, 0)) < 0) {
+ args->m_error.SetErrorToErrno();
+ return;
+ }
- process.SendMessage(ProcessMessage::Attach(pid));
+ process.SendMessage(ProcessMessage::Attach(pid));
}
size_t
-ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t>&thread_ids)
-{
- lwpid_t *tids;
- int tdcnt;
-
- thread_ids.clear();
-
- tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
- if (tdcnt <= 0)
- return 0;
- tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
- if (tids == NULL)
- return 0;
- if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
- free(tids);
- return 0;
- }
- thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
+ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids) {
+ lwpid_t *tids;
+ int tdcnt;
+
+ thread_ids.clear();
+
+ tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
+ if (tdcnt <= 0)
+ return 0;
+ tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
+ if (tids == NULL)
+ return 0;
+ if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
free(tids);
- return thread_ids.size();
+ return 0;
+ }
+ thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
+ free(tids);
+ return thread_ids.size();
}
-bool
-ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid, bool exited, int signal, int status)
-{
- ProcessMessage message;
- ProcessFreeBSD *process = monitor->m_process;
- assert(process);
- bool stop_monitoring;
- struct ptrace_lwpinfo plwp;
- int ptrace_err;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- if (exited)
- {
- if (log)
- log->Printf ("ProcessMonitor::%s() got exit signal, tid = %" PRIu64, __FUNCTION__, pid);
- message = ProcessMessage::Exit(pid, status);
- process->SendMessage(message);
- return pid == process->GetID();
- }
+bool ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
+ bool exited, int signal, int status) {
+ ProcessMessage message;
+ ProcessFreeBSD *process = monitor->m_process;
+ assert(process);
+ bool stop_monitoring;
+ struct ptrace_lwpinfo plwp;
+ int ptrace_err;
- if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
- stop_monitoring = true; // pid is gone. Bail.
- else {
- switch (plwp.pl_siginfo.si_signo)
- {
- case SIGTRAP:
- message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
- break;
-
- default:
- message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
- break;
- }
-
- process->SendMessage(message);
- stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
- }
-
- return stop_monitoring;
-}
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-ProcessMessage
-ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::tid_t tid)
-{
- ProcessMessage message;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- assert(monitor);
- assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
+ if (exited) {
+ if (log)
+ log->Printf("ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
+ __FUNCTION__, pid);
+ message = ProcessMessage::Exit(pid, status);
+ process->SendMessage(message);
+ return pid == process->GetID();
+ }
+
+ if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
+ stop_monitoring = true; // pid is gone. Bail.
+ else {
+ switch (plwp.pl_siginfo.si_signo) {
+ case SIGTRAP:
+ message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
+ break;
- switch (info->si_code)
- {
default:
- assert(false && "Unexpected SIGTRAP code!");
- break;
-
- case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */):
- {
- // The inferior process is about to exit. Maintain the process in a
- // state of "limbo" until we are explicitly commanded to detach,
- // destroy, resume, etc.
- unsigned long data = 0;
- if (!monitor->GetEventMessage(tid, &data))
- data = -1;
- if (log)
- log->Printf ("ProcessMonitor::%s() received exit? event, data = %lx, tid = %" PRIu64, __FUNCTION__, data, tid);
- message = ProcessMessage::Limbo(tid, (data >> 8));
- break;
+ message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
+ break;
}
- case 0:
- case TRAP_TRACE:
- if (log)
- log->Printf ("ProcessMonitor::%s() received trace event, tid = %" PRIu64 " : si_code = %d", __FUNCTION__, tid, info->si_code);
- message = ProcessMessage::Trace(tid);
- break;
-
- case SI_KERNEL:
- case TRAP_BRKPT:
- if (log)
- log->Printf ("ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64, __FUNCTION__, tid);
- message = ProcessMessage::Break(tid);
- break;
- }
+ process->SendMessage(message);
+ stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
+ }
- return message;
+ return stop_monitoring;
}
-ProcessMessage
-ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::tid_t tid)
-{
- ProcessMessage message;
- int signo = info->si_signo;
+ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
+ const siginfo_t *info,
+ lldb::tid_t tid) {
+ ProcessMessage message;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
- // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
- // kill(2) or raise(3). Similarly for tgkill(2) on FreeBSD.
- //
- // IOW, user generated signals never generate what we consider to be a
- // "crash".
- //
- // Similarly, ACK signals generated by this monitor.
- if (info->si_code == SI_USER)
- {
- if (log)
- log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d",
- __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo),
- "SI_USER",
- info->si_pid);
- if (info->si_pid == getpid())
- return ProcessMessage::SignalDelivered(tid, signo);
- else
- return ProcessMessage::Signal(tid, signo);
- }
+ assert(monitor);
+ assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
+ switch (info->si_code) {
+ default:
+ assert(false && "Unexpected SIGTRAP code!");
+ break;
+
+ case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */): {
+ // The inferior process is about to exit. Maintain the process in a
+ // state of "limbo" until we are explicitly commanded to detach,
+ // destroy, resume, etc.
+ unsigned long data = 0;
+ if (!monitor->GetEventMessage(tid, &data))
+ data = -1;
if (log)
- log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo));
-
- switch (signo)
- {
- case SIGSEGV:
- case SIGILL:
- case SIGFPE:
- case SIGBUS:
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- const auto reason = GetCrashReason(*info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
+ log->Printf("ProcessMonitor::%s() received exit? event, data = %lx, tid "
+ "= %" PRIu64,
+ __FUNCTION__, data, tid);
+ message = ProcessMessage::Limbo(tid, (data >> 8));
+ break;
+ }
+
+ case 0:
+ case TRAP_TRACE:
+ if (log)
+ log->Printf("ProcessMonitor::%s() received trace event, tid = %" PRIu64
+ " : si_code = %d",
+ __FUNCTION__, tid, info->si_code);
+ message = ProcessMessage::Trace(tid);
+ break;
+
+ case SI_KERNEL:
+ case TRAP_BRKPT:
+ if (log)
+ log->Printf(
+ "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
+ __FUNCTION__, tid);
+ message = ProcessMessage::Break(tid);
+ break;
+ }
+
+ return message;
+}
+
+ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
+ const siginfo_t *info,
+ lldb::tid_t tid) {
+ ProcessMessage message;
+ int signo = info->si_signo;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
+ // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
+ // kill(2) or raise(3). Similarly for tgkill(2) on FreeBSD.
+ //
+ // IOW, user generated signals never generate what we consider to be a
+ // "crash".
+ //
+ // Similarly, ACK signals generated by this monitor.
+ if (info->si_code == SI_USER) {
+ if (log)
+ log->Printf(
+ "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
+ __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
+ "SI_USER", info->si_pid);
+ if (info->si_pid == getpid())
+ return ProcessMessage::SignalDelivered(tid, signo);
+ else
+ return ProcessMessage::Signal(tid, signo);
+ }
+
+ if (log)
+ log->Printf(
+ "ProcessMonitor::%s() received signal %s", __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
- // Everything else is "normal" and does not require any special action on
- // our part.
- return ProcessMessage::Signal(tid, signo);
+ switch (signo) {
+ case SIGSEGV:
+ case SIGILL:
+ case SIGFPE:
+ case SIGBUS:
+ lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
+ const auto reason = GetCrashReason(*info);
+ return ProcessMessage::Crash(tid, reason, signo, fault_addr);
+ }
+
+ // Everything else is "normal" and does not require any special action on
+ // our part.
+ return ProcessMessage::Signal(tid, signo);
}
-void
-ProcessMonitor::ServeOperation(OperationArgs *args)
-{
- ProcessMonitor *monitor = args->m_monitor;
+void ProcessMonitor::ServeOperation(OperationArgs *args) {
+ ProcessMonitor *monitor = args->m_monitor;
- // We are finised with the arguments and are ready to go. Sync with the
- // parent thread and start serving operations on the inferior.
- sem_post(&args->m_semaphore);
+ // We are finised with the arguments and are ready to go. Sync with the
+ // parent thread and start serving operations on the inferior.
+ sem_post(&args->m_semaphore);
- for (;;)
- {
- // wait for next pending operation
- sem_wait(&monitor->m_operation_pending);
+ for (;;) {
+ // wait for next pending operation
+ sem_wait(&monitor->m_operation_pending);
- monitor->m_operation->Execute(monitor);
+ monitor->m_operation->Execute(monitor);
- // notify calling thread that operation is complete
- sem_post(&monitor->m_operation_done);
- }
+ // notify calling thread that operation is complete
+ sem_post(&monitor->m_operation_done);
+ }
}
-void
-ProcessMonitor::DoOperation(Operation *op)
-{
- std::lock_guard<std::mutex> guard(m_operation_mutex);
+void ProcessMonitor::DoOperation(Operation *op) {
+ std::lock_guard<std::mutex> guard(m_operation_mutex);
- m_operation = op;
+ m_operation = op;
- // notify operation thread that an operation is ready to be processed
- sem_post(&m_operation_pending);
+ // notify operation thread that an operation is ready to be processed
+ sem_post(&m_operation_pending);
- // wait for operation to complete
- sem_wait(&m_operation_done);
+ // wait for operation to complete
+ sem_wait(&m_operation_done);
}
-size_t
-ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- Error &error)
-{
- size_t result;
- ReadOperation op(vm_addr, buf, size, error, result);
- DoOperation(&op);
- return result;
+size_t ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Error &error) {
+ size_t result;
+ ReadOperation op(vm_addr, buf, size, error, result);
+ DoOperation(&op);
+ return result;
}
-size_t
-ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Error &error)
-{
- size_t result;
- WriteOperation op(vm_addr, buf, size, error, result);
- DoOperation(&op);
- return result;
+size_t ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf,
+ size_t size, lldb_private::Error &error) {
+ size_t result;
+ WriteOperation op(vm_addr, buf, size, error, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char* reg_name,
- unsigned size, RegisterValue &value)
-{
- bool result;
- ReadRegOperation op(tid, offset, size, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name, unsigned size,
+ RegisterValue &value) {
+ bool result;
+ ReadRegOperation op(tid, offset, size, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
- const char* reg_name, const RegisterValue &value)
-{
- bool result;
- WriteRegOperation op(tid, offset, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name,
+ const RegisterValue &value) {
+ bool result;
+ WriteRegOperation op(tid, offset, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name, unsigned size,
- lldb_private::RegisterValue &value)
-{
- bool result;
- ReadDebugRegOperation op(tid, offset, size, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadDebugRegisterValue(
+ lldb::tid_t tid, unsigned offset, const char *reg_name, unsigned size,
+ lldb_private::RegisterValue &value) {
+ bool result;
+ ReadDebugRegOperation op(tid, offset, size, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name,
- const lldb_private::RegisterValue &value)
-{
- bool result;
- WriteDebugRegOperation op(tid, offset, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteDebugRegisterValue(
+ lldb::tid_t tid, unsigned offset, const char *reg_name,
+ const lldb_private::RegisterValue &value) {
+ bool result;
+ WriteDebugRegOperation op(tid, offset, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- ReadGPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ ReadGPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- ReadFPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ ReadFPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-{
- return false;
+bool ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf,
+ size_t buf_size, unsigned int regset) {
+ return false;
}
-bool
-ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- WriteGPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ WriteGPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- WriteFPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ WriteFPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-{
- return false;
+bool ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf,
+ size_t buf_size, unsigned int regset) {
+ return false;
}
-bool
-ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value)
-{
- return false;
+bool ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value) {
+ return false;
}
-bool
-ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo)
-{
- bool result;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- if (log) {
- const char *signame = m_process->GetUnixSignals()->GetSignalAsCString (signo);
- if (signame == nullptr)
- signame = "<none>";
- log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
- __FUNCTION__, GetPID(), signame);
- }
- ResumeOperation op(signo, result);
- DoOperation(&op);
- if (log)
- log->Printf ("ProcessMonitor::%s() resuming result = %s", __FUNCTION__, result ? "true" : "false");
- return result;
+bool ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) {
+ bool result;
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ if (log) {
+ const char *signame =
+ m_process->GetUnixSignals()->GetSignalAsCString(signo);
+ if (signame == nullptr)
+ signame = "<none>";
+ log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
+ __FUNCTION__, GetPID(), signame);
+ }
+ ResumeOperation op(signo, result);
+ DoOperation(&op);
+ if (log)
+ log->Printf("ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
+ result ? "true" : "false");
+ return result;
}
-bool
-ProcessMonitor::SingleStep(lldb::tid_t unused, uint32_t signo)
-{
- bool result;
- SingleStepOperation op(signo, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::SingleStep(lldb::tid_t unused, uint32_t signo) {
+ bool result;
+ SingleStepOperation op(signo, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::Kill()
-{
- bool result;
- KillOperation op(result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::Kill() {
+ bool result;
+ KillOperation op(result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &ptrace_err)
-{
- bool result;
- LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo,
+ int &ptrace_err) {
+ bool result;
+ LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend)
-{
- bool result;
- ThreadSuspendOperation op(tid, suspend, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend) {
+ bool result;
+ ThreadSuspendOperation op(tid, suspend, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message)
-{
- bool result;
- EventMessageOperation op(tid, message, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message) {
+ bool result;
+ EventMessageOperation op(tid, message, result);
+ DoOperation(&op);
+ return result;
}
-lldb_private::Error
-ProcessMonitor::Detach(lldb::tid_t tid)
-{
- lldb_private::Error error;
- if (tid != LLDB_INVALID_THREAD_ID)
- {
- DetachOperation op(error);
- DoOperation(&op);
- }
- return error;
-}
+lldb_private::Error ProcessMonitor::Detach(lldb::tid_t tid) {
+ lldb_private::Error error;
+ if (tid != LLDB_INVALID_THREAD_ID) {
+ DetachOperation op(error);
+ DoOperation(&op);
+ }
+ return error;
+}
-bool
-ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd, int flags)
-{
- int target_fd = open(file_spec.GetCString(), flags, 0666);
+bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd,
+ int flags) {
+ int target_fd = open(file_spec.GetCString(), flags, 0666);
- if (target_fd == -1)
- return false;
+ if (target_fd == -1)
+ return false;
- if (dup2(target_fd, fd) == -1)
- return false;
+ if (dup2(target_fd, fd) == -1)
+ return false;
- return (close(target_fd) == -1) ? false : true;
+ return (close(target_fd) == -1) ? false : true;
}
-void
-ProcessMonitor::StopMonitoringChildProcess()
-{
- if (m_monitor_thread.IsJoinable())
- {
- m_monitor_thread.Cancel();
- m_monitor_thread.Join(nullptr);
- m_monitor_thread.Reset();
- }
+void ProcessMonitor::StopMonitoringChildProcess() {
+ if (m_monitor_thread.IsJoinable()) {
+ m_monitor_thread.Cancel();
+ m_monitor_thread.Join(nullptr);
+ m_monitor_thread.Reset();
+ }
}
-void
-ProcessMonitor::StopMonitor()
-{
- StopMonitoringChildProcess();
- StopOpThread();
- sem_destroy(&m_operation_pending);
- sem_destroy(&m_operation_done);
- if (m_terminal_fd >= 0) {
- close(m_terminal_fd);
- m_terminal_fd = -1;
- }
+void ProcessMonitor::StopMonitor() {
+ StopMonitoringChildProcess();
+ StopOpThread();
+ sem_destroy(&m_operation_pending);
+ sem_destroy(&m_operation_done);
+ if (m_terminal_fd >= 0) {
+ close(m_terminal_fd);
+ m_terminal_fd = -1;
+ }
}
// FIXME: On Linux, when a new thread is created, we receive to notifications,
@@ -1607,19 +1439,13 @@ ProcessMonitor::StopMonitor()
// We really should figure out what actually happens on FreeBSD and move the
// Linux-specific logic out of ProcessPOSIX as needed.
-bool
-ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid)
-{
- return true;
-}
+bool ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) { return true; }
-void
-ProcessMonitor::StopOpThread()
-{
- if (!m_operation_thread.IsJoinable())
- return;
+void ProcessMonitor::StopOpThread() {
+ if (!m_operation_thread.IsJoinable())
+ return;
- m_operation_thread.Cancel();
- m_operation_thread.Join(nullptr);
- m_operation_thread.Reset();
+ m_operation_thread.Cancel();
+ m_operation_thread.Join(nullptr);
+ m_operation_thread.Reset();
}
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 93f6be111361..4c2594e9da6a 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -18,12 +18,11 @@
#include <mutex>
// Other libraries and framework includes
-#include "lldb/lldb-types.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
+#include "lldb/lldb-types.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Error;
class Module;
class Scalar;
@@ -44,285 +43,242 @@ class Operation;
///
/// A purposely minimal set of operations are provided to interrogate and change
/// the inferior process state.
-class ProcessMonitor
-{
+class ProcessMonitor {
public:
-
- /// Launches an inferior process ready for debugging. Forms the
- /// implementation of Process::DoLaunch.
- ProcessMonitor(ProcessFreeBSD *process,
- lldb_private::Module *module,
- char const *argv[],
- char const *envp[],
- const lldb_private::FileSpec &stdin_file_spec,
- const lldb_private::FileSpec &stdout_file_spec,
- const lldb_private::FileSpec &stderr_file_spec,
- const lldb_private::FileSpec &working_dir,
- const lldb_private::ProcessLaunchInfo &launch_info,
- lldb_private::Error &error);
-
- ProcessMonitor(ProcessFreeBSD *process,
- lldb::pid_t pid,
- lldb_private::Error &error);
-
- ~ProcessMonitor();
-
- /// Provides the process number of debugee.
- lldb::pid_t
- GetPID() const { return m_pid; }
-
- /// Returns the process associated with this ProcessMonitor.
- ProcessFreeBSD &
- GetProcess() { return *m_process; }
-
- /// Returns a file descriptor to the controlling terminal of the inferior
- /// process.
- ///
- /// Reads from this file descriptor yield both the standard output and
- /// standard error of this debugee. Even if stderr and stdout were
- /// redirected on launch it may still happen that data is available on this
- /// descriptor (if the inferior process opens /dev/tty, for example). This descriptor is
- /// closed after a call to StopMonitor().
- ///
- /// If this monitor was attached to an existing process this method returns
- /// -1.
- int
- GetTerminalFD() const { return m_terminal_fd; }
-
- /// Reads @p size bytes from address @vm_adder in the inferior process
- /// address space.
- ///
- /// This method is provided to implement Process::DoReadMemory.
- size_t
- ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- lldb_private::Error &error);
-
- /// Writes @p size bytes from address @p vm_adder in the inferior process
- /// address space.
- ///
- /// This method is provided to implement Process::DoWriteMemory.
- size_t
- WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Error &error);
-
- /// Reads the contents from the register identified by the given (architecture
- /// dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
- unsigned size, lldb_private::RegisterValue &value);
-
- /// Writes the given value to the register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
- const lldb_private::RegisterValue &value);
-
- /// Reads the contents from the debug register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name, unsigned size,
- lldb_private::RegisterValue &value);
-
- /// Writes the given value to the debug register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name,
- const lldb_private::RegisterValue &value);
- /// Reads all general purpose registers into the specified buffer.
- bool
- ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Reads all floating point registers into the specified buffer.
- bool
- ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Reads the specified register set into the specified buffer.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
-
- /// Writes all general purpose registers into the specified buffer.
- bool
- WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Writes all floating point registers into the specified buffer.
- bool
- WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Writes the specified register set into the specified buffer.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
-
- /// Reads the value of the thread-specific pointer for a given thread ID.
- bool
- ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
-
- /// Returns current thread IDs in process
- size_t
- GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
-
- /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
- /// to the memory region pointed to by @p lwpinfo.
- bool
- GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
-
- /// Suspends or unsuspends a thread prior to process resume or step.
- bool
- ThreadSuspend(lldb::tid_t tid, bool suspend);
-
- /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
- /// corresponding to the given thread IDto the memory pointed to by @p
- /// message.
- bool
- GetEventMessage(lldb::tid_t tid, unsigned long *message);
-
- /// Resumes the process. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
- bool
- Resume(lldb::tid_t unused, uint32_t signo);
-
- /// Single steps the process. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
- bool
- SingleStep(lldb::tid_t unused, uint32_t signo);
-
- /// Terminate the traced process.
- bool
- Kill();
-
- lldb_private::Error
- Detach(lldb::tid_t tid);
-
- void
- StopMonitor();
-
- // Waits for the initial stop message from a new thread.
- bool
- WaitForInitialTIDStop(lldb::tid_t tid);
+ /// Launches an inferior process ready for debugging. Forms the
+ /// implementation of Process::DoLaunch.
+ ProcessMonitor(ProcessFreeBSD *process, lldb_private::Module *module,
+ char const *argv[], char const *envp[],
+ const lldb_private::FileSpec &stdin_file_spec,
+ const lldb_private::FileSpec &stdout_file_spec,
+ const lldb_private::FileSpec &stderr_file_spec,
+ const lldb_private::FileSpec &working_dir,
+ const lldb_private::ProcessLaunchInfo &launch_info,
+ lldb_private::Error &error);
+
+ ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
+ lldb_private::Error &error);
+
+ ~ProcessMonitor();
+
+ /// Provides the process number of debugee.
+ lldb::pid_t GetPID() const { return m_pid; }
+
+ /// Returns the process associated with this ProcessMonitor.
+ ProcessFreeBSD &GetProcess() { return *m_process; }
+
+ /// Returns a file descriptor to the controlling terminal of the inferior
+ /// process.
+ ///
+ /// Reads from this file descriptor yield both the standard output and
+ /// standard error of this debugee. Even if stderr and stdout were
+ /// redirected on launch it may still happen that data is available on this
+ /// descriptor (if the inferior process opens /dev/tty, for example). This
+ /// descriptor is
+ /// closed after a call to StopMonitor().
+ ///
+ /// If this monitor was attached to an existing process this method returns
+ /// -1.
+ int GetTerminalFD() const { return m_terminal_fd; }
+
+ /// Reads @p size bytes from address @vm_adder in the inferior process
+ /// address space.
+ ///
+ /// This method is provided to implement Process::DoReadMemory.
+ size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ lldb_private::Error &error);
+
+ /// Writes @p size bytes from address @p vm_adder in the inferior process
+ /// address space.
+ ///
+ /// This method is provided to implement Process::DoWriteMemory.
+ size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ lldb_private::Error &error);
+
+ /// Reads the contents from the register identified by the given (architecture
+ /// dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
+ unsigned size, lldb_private::RegisterValue &value);
+
+ /// Writes the given value to the register identified by the given
+ /// (architecture dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name,
+ const lldb_private::RegisterValue &value);
+
+ /// Reads the contents from the debug register identified by the given
+ /// (architecture dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name, unsigned size,
+ lldb_private::RegisterValue &value);
+
+ /// Writes the given value to the debug register identified by the given
+ /// (architecture dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name,
+ const lldb_private::RegisterValue &value);
+ /// Reads all general purpose registers into the specified buffer.
+ bool ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Reads all floating point registers into the specified buffer.
+ bool ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Reads the specified register set into the specified buffer.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
+ unsigned int regset);
+
+ /// Writes all general purpose registers into the specified buffer.
+ bool WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Writes all floating point registers into the specified buffer.
+ bool WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Writes the specified register set into the specified buffer.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
+ unsigned int regset);
+
+ /// Reads the value of the thread-specific pointer for a given thread ID.
+ bool ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
+
+ /// Returns current thread IDs in process
+ size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
+
+ /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
+ /// to the memory region pointed to by @p lwpinfo.
+ bool GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
+
+ /// Suspends or unsuspends a thread prior to process resume or step.
+ bool ThreadSuspend(lldb::tid_t tid, bool suspend);
+
+ /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
+ /// corresponding to the given thread IDto the memory pointed to by @p
+ /// message.
+ bool GetEventMessage(lldb::tid_t tid, unsigned long *message);
+
+ /// Resumes the process. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
+ bool Resume(lldb::tid_t unused, uint32_t signo);
+
+ /// Single steps the process. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
+ bool SingleStep(lldb::tid_t unused, uint32_t signo);
+
+ /// Terminate the traced process.
+ bool Kill();
+
+ lldb_private::Error Detach(lldb::tid_t tid);
+
+ void StopMonitor();
+
+ // Waits for the initial stop message from a new thread.
+ bool WaitForInitialTIDStop(lldb::tid_t tid);
private:
- ProcessFreeBSD *m_process;
+ ProcessFreeBSD *m_process;
- lldb_private::HostThread m_operation_thread;
- lldb_private::HostThread m_monitor_thread;
- lldb::pid_t m_pid;
+ lldb_private::HostThread m_operation_thread;
+ lldb_private::HostThread m_monitor_thread;
+ lldb::pid_t m_pid;
- int m_terminal_fd;
+ int m_terminal_fd;
- // current operation which must be executed on the privileged thread
- Operation *m_operation;
- std::mutex m_operation_mutex;
+ // current operation which must be executed on the privileged thread
+ Operation *m_operation;
+ std::mutex m_operation_mutex;
- // semaphores notified when Operation is ready to be processed and when
- // the operation is complete.
- sem_t m_operation_pending;
- sem_t m_operation_done;
+ // semaphores notified when Operation is ready to be processed and when
+ // the operation is complete.
+ sem_t m_operation_pending;
+ sem_t m_operation_done;
- struct OperationArgs
- {
- OperationArgs(ProcessMonitor *monitor);
+ struct OperationArgs {
+ OperationArgs(ProcessMonitor *monitor);
- ~OperationArgs();
+ ~OperationArgs();
- ProcessMonitor *m_monitor; // The monitor performing the attach.
- sem_t m_semaphore; // Posted to once operation complete.
- lldb_private::Error m_error; // Set if process operation failed.
- };
+ ProcessMonitor *m_monitor; // The monitor performing the attach.
+ sem_t m_semaphore; // Posted to once operation complete.
+ lldb_private::Error m_error; // Set if process operation failed.
+ };
- /// @class LauchArgs
- ///
- /// @brief Simple structure to pass data to the thread responsible for
- /// launching a child process.
- struct LaunchArgs : OperationArgs
- {
- LaunchArgs(ProcessMonitor *monitor,
- lldb_private::Module *module,
- char const **argv,
- char const **envp,
- const lldb_private::FileSpec &stdin_file_spec,
- const lldb_private::FileSpec &stdout_file_spec,
- const lldb_private::FileSpec &stderr_file_spec,
- const lldb_private::FileSpec &working_dir);
+ /// @class LauchArgs
+ ///
+ /// @brief Simple structure to pass data to the thread responsible for
+ /// launching a child process.
+ struct LaunchArgs : OperationArgs {
+ LaunchArgs(ProcessMonitor *monitor, lldb_private::Module *module,
+ char const **argv, char const **envp,
+ const lldb_private::FileSpec &stdin_file_spec,
+ const lldb_private::FileSpec &stdout_file_spec,
+ const lldb_private::FileSpec &stderr_file_spec,
+ const lldb_private::FileSpec &working_dir);
- ~LaunchArgs();
+ ~LaunchArgs();
- lldb_private::Module *m_module; // The executable image to launch.
- char const **m_argv; // Process arguments.
- char const **m_envp; // Process environment.
- const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
- const lldb_private::FileSpec m_stdout_file_spec; // Redirect stdout or empty.
- const lldb_private::FileSpec m_stderr_file_spec; // Redirect stderr or empty.
- const lldb_private::FileSpec m_working_dir; // Working directory or empty.
- };
+ lldb_private::Module *m_module; // The executable image to launch.
+ char const **m_argv; // Process arguments.
+ char const **m_envp; // Process environment.
+ const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
+ const lldb_private::FileSpec
+ m_stdout_file_spec; // Redirect stdout or empty.
+ const lldb_private::FileSpec
+ m_stderr_file_spec; // Redirect stderr or empty.
+ const lldb_private::FileSpec m_working_dir; // Working directory or empty.
+ };
- void
- StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
+ void StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
- static void *
- LaunchOpThread(void *arg);
+ static void *LaunchOpThread(void *arg);
- static bool
- Launch(LaunchArgs *args);
+ static bool Launch(LaunchArgs *args);
- struct AttachArgs : OperationArgs
- {
- AttachArgs(ProcessMonitor *monitor,
- lldb::pid_t pid);
+ struct AttachArgs : OperationArgs {
+ AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid);
- ~AttachArgs();
+ ~AttachArgs();
- lldb::pid_t m_pid; // pid of the process to be attached.
- };
+ lldb::pid_t m_pid; // pid of the process to be attached.
+ };
- void
- StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
+ void StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
- static void *
- AttachOpThread(void *args);
+ static void *AttachOpThread(void *args);
- static void
- Attach(AttachArgs *args);
+ static void Attach(AttachArgs *args);
- static void
- ServeOperation(OperationArgs *args);
+ static void ServeOperation(OperationArgs *args);
- static bool
- DupDescriptor(const lldb_private::FileSpec &file_spec, int fd, int flags);
+ static bool DupDescriptor(const lldb_private::FileSpec &file_spec, int fd,
+ int flags);
- static bool
- MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid, bool exited, int signal, int status);
+ static bool MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
+ bool exited, int signal, int status);
- static ProcessMessage
- MonitorSIGTRAP(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::pid_t pid);
+ static ProcessMessage MonitorSIGTRAP(ProcessMonitor *monitor,
+ const siginfo_t *info, lldb::pid_t pid);
- static ProcessMessage
- MonitorSignal(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::pid_t pid);
+ static ProcessMessage MonitorSignal(ProcessMonitor *monitor,
+ const siginfo_t *info, lldb::pid_t pid);
- void
- DoOperation(Operation *op);
+ void DoOperation(Operation *op);
- /// Stops the child monitor thread.
- void
- StopMonitoringChildProcess();
+ /// Stops the child monitor thread.
+ void StopMonitoringChildProcess();
- /// Stops the operation thread used to attach/launch a process.
- void
- StopOpThread();
+ /// Stops the operation thread used to attach/launch a process.
+ void StopOpThread();
};
#endif // #ifndef liblldb_ProcessMonitor_H_
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
index 6ddd9cfe4c21..c0b9b2f4a2d3 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
@@ -13,67 +13,56 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "RegisterInfoInterface.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
//------------------------------------------------------------------------------
/// @class POSIXBreakpointProtocol
///
/// @brief Extends RegisterClass with a few virtual operations useful on POSIX.
-class POSIXBreakpointProtocol
-{
+class POSIXBreakpointProtocol {
public:
- POSIXBreakpointProtocol()
- { m_watchpoints_initialized = false; }
- virtual ~POSIXBreakpointProtocol() {}
+ POSIXBreakpointProtocol() { m_watchpoints_initialized = false; }
+ virtual ~POSIXBreakpointProtocol() {}
- /// Updates the register state of the associated thread after hitting a
- /// breakpoint (if that make sense for the architecture). Default
- /// implementation simply returns true for architectures which do not
- /// require any update.
- ///
- /// @return
- /// True if the operation succeeded and false otherwise.
- virtual bool UpdateAfterBreakpoint() = 0;
+ /// Updates the register state of the associated thread after hitting a
+ /// breakpoint (if that make sense for the architecture). Default
+ /// implementation simply returns true for architectures which do not
+ /// require any update.
+ ///
+ /// @return
+ /// True if the operation succeeded and false otherwise.
+ virtual bool UpdateAfterBreakpoint() = 0;
- /// Determines the index in lldb's register file given a kernel byte offset.
- virtual unsigned
- GetRegisterIndexFromOffset(unsigned offset) = 0;
+ /// Determines the index in lldb's register file given a kernel byte offset.
+ virtual unsigned GetRegisterIndexFromOffset(unsigned offset) = 0;
- // Checks to see if a watchpoint specified by hw_index caused the inferior
- // to stop.
- virtual bool
- IsWatchpointHit (uint32_t hw_index) = 0;
+ // Checks to see if a watchpoint specified by hw_index caused the inferior
+ // to stop.
+ virtual bool IsWatchpointHit(uint32_t hw_index) = 0;
- // Resets any watchpoints that have been hit.
- virtual bool
- ClearWatchpointHits () = 0;
+ // Resets any watchpoints that have been hit.
+ virtual bool ClearWatchpointHits() = 0;
- // Returns the watchpoint address associated with a watchpoint hardware
- // index.
- virtual lldb::addr_t
- GetWatchpointAddress (uint32_t hw_index) = 0;
+ // Returns the watchpoint address associated with a watchpoint hardware
+ // index.
+ virtual lldb::addr_t GetWatchpointAddress(uint32_t hw_index) = 0;
- virtual bool
- IsWatchpointVacant (uint32_t hw_index) = 0;
+ virtual bool IsWatchpointVacant(uint32_t hw_index) = 0;
- virtual bool
- SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index) = 0;
+ virtual bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ bool read, bool write,
+ uint32_t hw_index) = 0;
- // From lldb_private::RegisterContext
- virtual uint32_t
- NumSupportedHardwareWatchpoints () = 0;
+ // From lldb_private::RegisterContext
+ virtual uint32_t NumSupportedHardwareWatchpoints() = 0;
- // Force m_watchpoints_initialized to TRUE
- void
- ForceWatchpointsInitialized () {m_watchpoints_initialized = true;}
+ // Force m_watchpoints_initialized to TRUE
+ void ForceWatchpointsInitialized() { m_watchpoints_initialized = true; }
protected:
- bool m_watchpoints_initialized;
+ bool m_watchpoints_initialized;
};
#endif // #ifndef liblldb_RegisterContextPOSIX_H_
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
index 9922311fd9db..f8d5f2edd3a3 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
@@ -11,312 +11,250 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIX_arm.h"
#include "ProcessFreeBSD.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
#include "ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_arm.h"
+#include "RegisterContextPOSIX_arm.h"
using namespace lldb_private;
using namespace lldb;
#define REG_CONTEXT_SIZE (GetGPRSize())
-RegisterContextPOSIXProcessMonitor_arm::RegisterContextPOSIXProcessMonitor_arm(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_arm(thread, concrete_frame_idx, register_info)
-{
-}
+RegisterContextPOSIXProcessMonitor_arm::RegisterContextPOSIXProcessMonitor_arm(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_arm(thread, concrete_frame_idx, register_info) {}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_arm::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
+bool RegisterContextPOSIXProcessMonitor_arm::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
+bool RegisterContextPOSIXProcessMonitor_arm::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
- }
- else
- {
- return ReadRegister(reg, value);
- }
+bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- // Get pointer to m_fpr variable and set the data from it.
- assert (reg_info->byte_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ return ReadRegister(reg, value);
+ }
+
+ // Get pointer to m_fpr variable and set the data from it.
+ assert(reg_info->byte_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ value.SetUInt16(*(uint16_t *)src);
+ return true;
+ case 4:
+ value.SetUInt32(*(uint32_t *)src);
+ return true;
+ case 8:
+ value.SetUInt64(*(uint64_t *)src);
+ return true;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg))
- {
- return WriteRegister(reg, value);
- }
- else if (IsFPR(reg))
- {
- return WriteFPR();
- }
+ if (IsGPR(reg)) {
+ return WriteRegister(reg, value);
+ } else if (IsFPR(reg)) {
+ return WriteFPR();
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_arm, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
- }
+bool RegisterContextPOSIXProcessMonitor_arm::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_arm, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_arm, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- ::memcpy (&m_fpr, src, sizeof(m_fpr));
-
- success = WriteFPR();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_arm, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof(m_fpr));
+
+ success = WriteFPR();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::HardwareSingleStep(bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::UpdateAfterBreakpoint()
-{
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_arm::UpdateAfterBreakpoint() {
+ lldb::addr_t pc;
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
- return true;
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_arm::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_arm; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_arm && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_arm::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_arm; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_arm && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::ClearWatchpointHits() {
+ return false;
}
-addr_t
-RegisterContextPOSIXProcessMonitor_arm::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_arm::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_arm::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_arm::NumSupportedHardwareWatchpoints() {
+ return 0;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
index 3787502a390c..6aa71c24f1cd 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
@@ -10,87 +10,68 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_arm:
- public RegisterContextPOSIX_arm,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_arm : public RegisterContextPOSIX_arm,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_arm(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_arm(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
index a1a0cab82a15..98a213a370fe 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
@@ -21,298 +21,245 @@
using namespace lldb;
using namespace lldb_private;
-RegisterContextPOSIXProcessMonitor_arm64::RegisterContextPOSIXProcessMonitor_arm64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info)
-{
+RegisterContextPOSIXProcessMonitor_arm64::
+ RegisterContextPOSIXProcessMonitor_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info) {}
+
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() {
+ lldb::ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_arm64::GetMonitor()
-{
- lldb::ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
+ const unsigned reg, lldb_private::RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(const unsigned reg,
- lldb_private::RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
-}
-
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(const unsigned reg,
- const lldb_private::RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- lldb_private::RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- lldb_private::RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const lldb_private::RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- lldb_private::Error error;
- lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t dst[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- ::memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
+ const unsigned reg, const lldb_private::RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ lldb_private::RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ lldb_private::RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const lldb_private::RegisterInfo *full_reg_info =
+ GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ lldb_private::Error error;
+ lldb::ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[lldb_private::RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[lldb_private::RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ ::memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
-{
- if (!reg_info)
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) {
+ if (!reg_info)
+ return false;
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
- }
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- return ReadRegister(full_reg, value);
- }
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
- // Get pointer to m_fpr variable and set the data from it.
- assert (reg_info->byte_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
+ return ReadRegister(full_reg, value);
+ }
+
+ // Get pointer to m_fpr variable and set the data from it.
+ assert(reg_info->byte_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ value.SetUInt16(*(uint16_t *)src);
+ return true;
+ case 4:
+ value.SetUInt32(*(uint32_t *)src);
+ return true;
+ case 8:
+ value.SetUInt64(*(uint64_t *)src);
+ return true;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (IsGPR(reg))
- return WriteRegister(reg, value);
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new lldb_private::DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_arm64, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof m_fpr);
- }
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new lldb_private::DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof m_fpr);
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_arm64, src, GetGPRSize());
- if (WriteGPR()) {
- src += GetGPRSize();
- ::memcpy (&m_fpr, src, sizeof m_fpr);
- success = WriteFPR();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_arm64, src, GetGPRSize());
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof m_fpr);
+ success = WriteFPR();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::HardwareSingleStep(bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::UpdateAfterBreakpoint()
-{
- if (GetPC() == LLDB_INVALID_ADDRESS)
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::UpdateAfterBreakpoint() {
+ if (GetPC() == LLDB_INVALID_ADDRESS)
+ return false;
- return true;
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_arm64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_arm64; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_arm64 && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_arm64::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_arm64; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_arm64 && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::ClearWatchpointHits() {
+ return false;
}
-lldb::addr_t
-RegisterContextPOSIXProcessMonitor_arm64::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+lldb::addr_t RegisterContextPOSIXProcessMonitor_arm64::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_arm64::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_arm64::NumSupportedHardwareWatchpoints() {
+ return 0;
}
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
index 729385c4a76e..8591c83be541 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
@@ -10,87 +10,69 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_arm64:
- public RegisterContextPOSIX_arm64,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_arm64
+ : public RegisterContextPOSIX_arm64,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_arm64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
index eeada4b16337..020636eb0a6b 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
@@ -1,11 +1,11 @@
-//===-- RegisterContextPOSIXProcessMonitor_mips64.h ------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_mips64.cpp -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
@@ -21,298 +21,243 @@ using namespace lldb;
#define REG_CONTEXT_SIZE (GetGPRSize())
-RegisterContextPOSIXProcessMonitor_mips64::RegisterContextPOSIXProcessMonitor_mips64(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info)
-{
-}
+RegisterContextPOSIXProcessMonitor_mips64::
+ RegisterContextPOSIXProcessMonitor_mips64(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info) {}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_mips64::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_mips64::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadFPR()
-{
- // XXX not yet implemented
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadFPR() {
+ // XXX not yet implemented
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteFPR()
-{
- // XXX not yet implemented
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteFPR() {
+ // XXX not yet implemented
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- bool success = ReadRegister(full_reg, value);
+ bool success = ReadRegister(full_reg, value);
- if (success)
- {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- value.SetUInt64(value.GetAsUInt64() >> 8);
+ if (success) {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
+ // one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ value.SetUInt64(value.GetAsUInt64() >> 8);
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
}
+ return success;
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg))
- return WriteRegister(reg, value);
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_mips64, GetGPRSize());
- }
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_mips64, GetGPRSize());
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_mips64, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_mips64, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(
+ bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::UpdateAfterBreakpoint()
-{
- // PC points one byte past the int3 responsible for the breakpoint.
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_mips64::UpdateAfterBreakpoint() {
+ // PC points one byte past the int3 responsible for the breakpoint.
+ lldb::addr_t pc;
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
- SetPC(pc - 1);
- return true;
+ SetPC(pc - 1);
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_mips64; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_mips64 && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_mips64; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_mips64 && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits() {
+ return false;
}
-addr_t
-RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints() {
+ return 0;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
index e61621bec197..2f75e6058fbc 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
@@ -10,87 +10,69 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_mips64:
- public RegisterContextPOSIX_mips64,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_mips64
+ : public RegisterContextPOSIX_mips64,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_mips64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_mips64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
index 321e6ea262ce..e7b01fa8634a 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
@@ -1,337 +1,275 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.h ------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_powerpc.cpp ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIX_powerpc.h"
#include "ProcessFreeBSD.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
#include "ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
+#include "RegisterContextPOSIX_powerpc.h"
using namespace lldb_private;
using namespace lldb;
#define REG_CONTEXT_SIZE (GetGPRSize())
-RegisterContextPOSIXProcessMonitor_powerpc::RegisterContextPOSIXProcessMonitor_powerpc(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info)
-{
-}
+RegisterContextPOSIXProcessMonitor_powerpc::
+ RegisterContextPOSIXProcessMonitor_powerpc(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info) {}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc,
+ sizeof(m_fpr_powerpc));
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX()
-{
- // XXX: Need a way to read/write process VMX registers with ptrace.
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX() {
+ // XXX: Need a way to read/write process VMX registers with ptrace.
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc,
+ sizeof(m_fpr_powerpc));
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX()
-{
- // XXX: Need a way to read/write process VMX registers with ptrace.
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX() {
+ // XXX: Need a way to read/write process VMX registers with ptrace.
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
-
- ProcessMonitor &monitor = GetMonitor();
- // Account for the fact that 32-bit targets on powerpc64 really use 64-bit
- // registers in ptrace, but expose here 32-bit registers with a higher
- // offset.
- uint64_t offset = GetRegisterOffset(reg_to_write);
- offset &= ~(sizeof(uintptr_t) - 1);
- return monitor.WriteRegisterValue(m_thread.GetID(),
- offset,
- GetRegisterName(reg_to_write),
- value_to_write);
+ }
+
+ ProcessMonitor &monitor = GetMonitor();
+ // Account for the fact that 32-bit targets on powerpc64 really use 64-bit
+ // registers in ptrace, but expose here 32-bit registers with a higher
+ // offset.
+ uint64_t offset = GetRegisterOffset(reg_to_write);
+ offset &= ~(sizeof(uintptr_t) - 1);
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), offset, GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
- uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
- value.SetUInt64(*(uint64_t*)src);
- }
- else if (IsGPR(reg))
- {
- bool success = ReadRegister(reg, value);
-
- if (success)
- {
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
+ value.SetUInt64(*(uint64_t *)src);
+ } else if (IsGPR(reg)) {
+ bool success = ReadRegister(reg, value);
+
+ if (success) {
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
}
+ return success;
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg))
- {
- return WriteRegister(reg, value);
- }
- else if (IsFPR(reg))
- {
- assert (reg_info->byte_offset < sizeof(m_fpr_powerpc));
- uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
- *(uint64_t *)dst = value.GetAsUInt64();
- return WriteFPR();
- }
+ if (IsGPR(reg)) {
+ return WriteRegister(reg, value);
+ } else if (IsFPR(reg)) {
+ assert(reg_info->byte_offset < sizeof(m_fpr_powerpc));
+ uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
+ *(uint64_t *)dst = value.GetAsUInt64();
+ return WriteFPR();
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_powerpc, GetGPRSize());
- dst += GetGPRSize();
- }
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_powerpc, GetGPRSize());
+ dst += GetGPRSize();
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_powerpc, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- ::memcpy (&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
-
- success = WriteFPR();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_powerpc, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ ::memcpy(&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
+
+ success = WriteFPR();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
- return LLDB_INVALID_INDEX32;
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
+
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(
+ bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint()
-{
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint() {
+ lldb::addr_t pc;
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
- return true;
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_powerpc; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_powerpc && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_powerpc; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_powerpc && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits() {
+ return false;
}
-addr_t
-RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints() {
+ return 0;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
index ff1d0f36171b..188ddea7d473 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.h -------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_powerpc.h -------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,96 +11,75 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_powerpc:
- public RegisterContextPOSIX_powerpc,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_powerpc
+ : public RegisterContextPOSIX_powerpc,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_powerpc(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_powerpc(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- IsVMX();
+ bool IsVMX();
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- ReadVMX();
+ bool ReadVMX();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- bool
- WriteVMX();
+ bool WriteVMX();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
index 31b9e7a38b21..976b190b2355 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -1,673 +1,614 @@
-//===-- RegisterContextPOSIXProcessMonitor_x86.h ---------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_x86.cpp --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
#include "Plugins/Process/FreeBSD/ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_x86.h"
using namespace lldb_private;
using namespace lldb;
// Support ptrace extensions even when compiled without required kernel support
#ifndef NT_X86_XSTATE
- #define NT_X86_XSTATE 0x202
+#define NT_X86_XSTATE 0x202
#endif
#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(FPR))
-static uint32_t
-size_and_rw_bits(size_t size, bool read, bool write)
-{
- uint32_t rw;
-
- if (read)
- rw = 0x3; // READ or READ/WRITE
- else if (write)
- rw = 0x1; // WRITE
- else
- assert(0 && "read and write cannot both be false");
-
- switch (size)
- {
- case 1:
- return rw;
- case 2:
- return (0x1 << 2) | rw;
- case 4:
- return (0x3 << 2) | rw;
- case 8:
- return (0x2 << 2) | rw;
- default:
- assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
- return 0; // Unreachable. Just to silence compiler.
- }
+static uint32_t size_and_rw_bits(size_t size, bool read, bool write) {
+ uint32_t rw;
+
+ if (read)
+ rw = 0x3; // READ or READ/WRITE
+ else if (write)
+ rw = 0x1; // WRITE
+ else
+ assert(0 && "read and write cannot both be false");
+
+ switch (size) {
+ case 1:
+ return rw;
+ case 2:
+ return (0x1 << 2) | rw;
+ case 4:
+ return (0x3 << 2) | rw;
+ case 8:
+ return (0x2 << 2) | rw;
+ default:
+ assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
+ return 0; // Unreachable. Just to silence compiler.
+ }
}
-RegisterContextPOSIXProcessMonitor_x86_64::RegisterContextPOSIXProcessMonitor_x86_64(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info)
-{
- // Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
- const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
- m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
+RegisterContextPOSIXProcessMonitor_x86_64::
+ RegisterContextPOSIXProcessMonitor_x86_64(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info) {
+ // Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
+ const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
+ m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- if (GetFPRType() == eFXSAVE)
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ if (GetFPRType() == eFXSAVE)
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
+ sizeof(m_fpr.xstate.fxsave));
- if (GetFPRType() == eXSAVE)
- return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- return false;
+ if (GetFPRType() == eXSAVE)
+ return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec,
+ sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- if (GetFPRType() == eFXSAVE)
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ if (GetFPRType() == eFXSAVE)
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
+ sizeof(m_fpr.xstate.fxsave));
- if (GetFPRType() == eXSAVE)
- return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- return false;
+ if (GetFPRType() == eXSAVE)
+ return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec,
+ sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
#if defined(__FreeBSD__)
- if (reg >= m_reg_info.first_dr)
- return monitor.ReadDebugRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+ if (reg >= m_reg_info.first_dr)
+ return monitor.ReadDebugRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg), GetRegisterName(reg),
+ GetRegisterSize(reg), value);
#endif
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
+ ProcessMonitor &monitor = GetMonitor();
#if defined(__FreeBSD__)
- if (reg >= m_reg_info.first_dr)
- return monitor.WriteDebugRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ if (reg >= m_reg_info.first_dr)
+ return monitor.WriteDebugRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
#endif
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsFPR(reg, GetFPRType()))
- {
- if (!ReadFPR())
- return false;
+ if (IsFPR(reg, GetFPRType())) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- bool success = ReadRegister(full_reg, value);
+ bool success = ReadRegister(full_reg, value);
- if (success)
- {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- value.SetUInt64(value.GetAsUInt64() >> 8);
+ if (success) {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
+ // one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ value.SetUInt64(value.GetAsUInt64() >> 8);
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
}
+ return success;
+ }
+
+ if (reg_info->encoding == eEncodingVector) {
+ ByteOrder byte_order = GetByteOrder();
+
+ if (byte_order != ByteOrder::eByteOrderInvalid) {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ value.SetBytes(
+ m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
+ value.SetBytes(
+ m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
+ value.SetBytes(
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
+ // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
+ if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
+ value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ reg_info->byte_size, byte_order);
+ else
+ return false;
+ }
+ return value.GetType() == RegisterValue::eTypeBytes;
+ }
+ return false;
+ }
+
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ // Byte offsets of all registers are calculated wrt 'UserArea' structure.
+ // However, ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)}
+ // and stores them in 'm_fpr' (of type FPR structure). To extract values of
+ // fpu
+ // registers, m_fpr should be read at byte offsets calculated wrt to FPR
+ // structure.
+
+ // Since, FPR structure is also one of the member of UserArea structure.
+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
+ // byte_offset(fctrl wrt UserArea)
+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
+ uint8_t *src =
+ (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
+ switch (reg_info->byte_size) {
+ case 1:
+ value.SetUInt8(*(uint8_t *)src);
+ return true;
+ case 2:
+ value.SetUInt16(*(uint16_t *)src);
+ return true;
+ case 4:
+ value.SetUInt32(*(uint32_t *)src);
+ return true;
+ case 8:
+ value.SetUInt64(*(uint64_t *)src);
+ return true;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
+}
- if (reg_info->encoding == eEncodingVector)
- {
- ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != ByteOrder::eByteOrderInvalid)
- {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
- {
- // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
- if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
- value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order);
- else
- return false;
- }
- return value.GetType() == RegisterValue::eTypeBytes;
- }
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
+
+ if (IsFPR(reg, GetFPRType())) {
+ if (reg_info->encoding == eEncodingVector) {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
+ ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
+ if (GetFPRType() != eXSAVE)
+ return false; // the target processor does not support AVX
+
+ // Store ymm register content, and split into the register halves in
+ // xmm.bytes and ymmh.bytes
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ value.GetBytes(), value.GetByteSize());
+ if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
+ return false;
+ }
+ } else {
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ // Byte offsets of all registers are calculated wrt 'UserArea' structure.
+ // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
+ // fpu
+ // registers using ptrace(PT_SETFPREGS,..) API. Hence fpu registers should
+ // be written in m_fpr at byte offsets calculated wrt FPR structure.
+
+ // Since, FPR structure is also one of the member of UserArea structure.
+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
+ // byte_offset(fctrl wrt UserArea)
+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
+ sizeof(m_fpr));
+ uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset -
+ m_fctrl_offset_in_userarea;
+ switch (reg_info->byte_size) {
+ case 1:
+ *(uint8_t *)dst = value.GetAsUInt8();
+ break;
+ case 2:
+ *(uint16_t *)dst = value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
return false;
+ }
}
- // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)}
- // and stores them in 'm_fpr' (of type FPR structure). To extract values of fpu
- // registers, m_fpr should be read at byte offsets calculated wrt to FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
- assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size)
- {
- case 1:
- value.SetUInt8(*(uint8_t *)src);
- return true;
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
+ if (WriteFPR()) {
+ if (IsAVX(reg))
+ return CopyYMMtoXSTATE(reg, GetByteOrder());
+ return true;
}
+ }
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsGPR(reg))
- return WriteRegister(reg, value);
-
- if (IsFPR(reg, GetFPRType()))
- {
- if (reg_info->encoding == eEncodingVector)
- {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- ::memcpy (m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
- {
- if (GetFPRType() != eXSAVE)
- return false; // the target processor does not support AVX
-
- // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
- ::memcpy (m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, value.GetBytes(), value.GetByteSize());
- if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
- return false;
- }
- }
- else
- {
- // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only fpu
- // registers using ptrace(PT_SETFPREGS,..) API. Hence fpu registers should
- // be written in m_fpr at byte offsets calculated wrt FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
- assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size)
- {
- case 1:
- *(uint8_t *)dst = value.GetAsUInt8();
- break;
- case 2:
- *(uint16_t *)dst = value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_x86_64, GetGPRSize());
+ dst += GetGPRSize();
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ }
- if (WriteFPR())
- {
- if (IsAVX(reg))
- return CopyYMMtoXSTATE(reg, GetByteOrder());
- return true;
- }
+ if (GetFPRType() == eXSAVE) {
+ ByteOrder byte_order = GetByteOrder();
+
+ // Assemble the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm;
+ success && reg <= m_reg_info.last_ymm; ++reg)
+ success = CopyXSTATEtoYMM(reg, byte_order);
+
+ if (success) {
+ // Copy the extended register state including the assembled ymm
+ // registers.
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
+ }
}
- return false;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_x86_64, GetGPRSize());
- dst += GetGPRSize();
- if (GetFPRType() == eFXSAVE)
- ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
- }
-
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_x86_64, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
if (GetFPRType() == eXSAVE)
- {
- ByteOrder byte_order = GetByteOrder();
+ ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
- success = CopyXSTATEtoYMM(reg, byte_order);
+ success = WriteFPR();
+ if (success) {
+ if (GetFPRType() == eXSAVE) {
+ ByteOrder byte_order = GetByteOrder();
- if (success)
- {
- // Copy the extended register state including the assembled ymm registers.
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
- }
+ // Parse the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm;
+ success && reg <= m_reg_info.last_ymm; ++reg)
+ success = CopyYMMtoXSTATE(reg, byte_order);
+ }
}
+ }
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_x86_64, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- if (GetFPRType() == eFXSAVE)
- ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
- if (GetFPRType() == eXSAVE)
- ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
-
- success = WriteFPR();
- if (success)
- {
- if (GetFPRType() == eXSAVE)
- {
- ByteOrder byte_order = GetByteOrder();
-
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
- success = CopyYMMtoXSTATE(reg, byte_order);
- }
- }
- }
- }
- }
- return success;
-}
+uint32_t RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
-uint32_t
-RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue current_dr7_bits;
+bool RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ if (hw_index < NumSupportedHardwareWatchpoints()) {
+ RegisterValue current_dr7_bits;
- if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index));
+ if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
+ uint64_t new_dr7_bits =
+ current_dr7_bits.GetAsUInt64() & ~(3 << (2 * hw_index));
- if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
- return true;
- }
+ if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
+ return true;
}
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(bool enable)
-{
- enum { TRACE_BIT = 0x100 };
- uint64_t rflags;
+bool RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(
+ bool enable) {
+ enum { TRACE_BIT = 0x100 };
+ uint64_t rflags;
- if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
- return false;
-
- if (enable)
- {
- if (rflags & TRACE_BIT)
- return true;
+ if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
+ return false;
- rflags |= TRACE_BIT;
- }
- else
- {
- if (!(rflags & TRACE_BIT))
- return false;
+ if (enable) {
+ if (rflags & TRACE_BIT)
+ return true;
- rflags &= ~TRACE_BIT;
- }
+ rflags |= TRACE_BIT;
+ } else {
+ if (!(rflags & TRACE_BIT))
+ return false;
+
+ rflags &= ~TRACE_BIT;
+ }
- return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
+ return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::UpdateAfterBreakpoint()
-{
- // PC points one byte past the int3 responsible for the breakpoint.
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_x86_64::UpdateAfterBreakpoint() {
+ // PC points one byte past the int3 responsible for the breakpoint.
+ lldb::addr_t pc;
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
- SetPC(pc - 1);
- return true;
+ SetPC(pc - 1);
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < m_reg_info.num_registers; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < m_reg_info.num_registers; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index)
-{
- bool is_hit = false;
-
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue value;
-
- if (ReadRegister(m_reg_info.first_dr + 6, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_hit = val & (1 << hw_index);
- }
- }
-
- return is_hit;
+bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(
+ uint32_t hw_index) {
+ bool is_hit = false;
+
+ if (m_watchpoints_initialized == false) {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
+ !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
+
+ if (hw_index < NumSupportedHardwareWatchpoints()) {
+ RegisterValue value;
+
+ if (ReadRegister(m_reg_info.first_dr + 6, value)) {
+ uint64_t val = value.GetAsUInt64();
+ is_hit = val & (1 << hw_index);
+ }
+ }
+
+ return is_hit;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits()
-{
- return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
+bool RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits() {
+ return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
}
-addr_t
-RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(uint32_t hw_index)
-{
- addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(
+ uint32_t hw_index) {
+ addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- if (!IsWatchpointVacant(hw_index))
- {
- RegisterValue value;
+ if (hw_index < NumSupportedHardwareWatchpoints()) {
+ if (!IsWatchpointVacant(hw_index)) {
+ RegisterValue value;
- if (ReadRegister(m_reg_info.first_dr + hw_index, value))
- wp_monitor_addr = value.GetAsUInt64();
- }
+ if (ReadRegister(m_reg_info.first_dr + hw_index, value))
+ wp_monitor_addr = value.GetAsUInt64();
}
+ }
- return wp_monitor_addr;
+ return wp_monitor_addr;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(uint32_t hw_index)
-{
- bool is_vacant = false;
- RegisterValue value;
+bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(
+ uint32_t hw_index) {
+ bool is_vacant = false;
+ RegisterValue value;
- assert(hw_index < NumSupportedHardwareWatchpoints());
+ assert(hw_index < NumSupportedHardwareWatchpoints());
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
+ if (m_watchpoints_initialized == false) {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
+ !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
- if (ReadRegister(m_reg_info.first_dr + 7, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_vacant = (val & (3 << 2*hw_index)) == 0;
- }
+ if (ReadRegister(m_reg_info.first_dr + 7, value)) {
+ uint64_t val = value.GetAsUInt64();
+ is_vacant = (val & (3 << 2 * hw_index)) == 0;
+ }
- return is_vacant;
+ return is_vacant;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+bool RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
- return false;
+ if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
+ return false;
- if (!(size == 1 || size == 2 || size == 4 || size == 8))
- return false;
+ if (!(size == 1 || size == 2 || size == 4 || size == 8))
+ return false;
- if (read == false && write == false)
- return false;
+ if (read == false && write == false)
+ return false;
- if (!IsWatchpointVacant(hw_index))
- return false;
+ if (!IsWatchpointVacant(hw_index))
+ return false;
- // Set both dr7 (debug control register) and dri (debug address register).
-
- // dr7{7-0} encodes the local/global enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- //
- // dr7{31-16} encodes the rw/len bits:
- // b_x+3, b_x+2, b_x+1, b_x
- // where bits{x+1, x} => rw
- // 0b00: execute, 0b01: write, 0b11: read-or-write,
- // 0b10: io read-or-write (unused)
- // and bits{x+3, x+2} => len
- // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
- //
- // dr0 -> bits{19-16}
- // dr1 -> bits{23-20}
- // dr2 -> bits{27-24}
- // dr3 -> bits{31-28}
- if (hw_index < num_hw_watchpoints)
- {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() |
- (1 << (2*hw_index) |
- size_and_rw_bits(size, read, write) <<
- (16+4*hw_index));
-
- if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
- WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
- return true;
- }
+ // Set both dr7 (debug control register) and dri (debug address register).
+
+ // dr7{7-0} encodes the local/global enable bits:
+ // global enable --. .-- local enable
+ // | |
+ // v v
+ // dr0 -> bits{1-0}
+ // dr1 -> bits{3-2}
+ // dr2 -> bits{5-4}
+ // dr3 -> bits{7-6}
+ //
+ // dr7{31-16} encodes the rw/len bits:
+ // b_x+3, b_x+2, b_x+1, b_x
+ // where bits{x+1, x} => rw
+ // 0b00: execute, 0b01: write, 0b11: read-or-write,
+ // 0b10: io read-or-write (unused)
+ // and bits{x+3, x+2} => len
+ // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
+ //
+ // dr0 -> bits{19-16}
+ // dr1 -> bits{23-20}
+ // dr2 -> bits{27-24}
+ // dr3 -> bits{31-28}
+ if (hw_index < num_hw_watchpoints) {
+ RegisterValue current_dr7_bits;
+
+ if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
+ uint64_t new_dr7_bits =
+ current_dr7_bits.GetAsUInt64() |
+ (1 << (2 * hw_index) |
+ size_and_rw_bits(size, read, write) << (16 + 4 * hw_index));
+
+ if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
+ WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
+ return true;
}
+ }
- return false;
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints()
-{
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
+RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
index f55d917ee75d..57e2d00e668f 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
@@ -10,88 +10,71 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_x86_64:
- public RegisterContextPOSIX_x86,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_x86_64
+ : public RegisterContextPOSIX_x86,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_x86_64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_x86_64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
- uint32_t m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
+ ProcessMonitor &GetMonitor();
+ uint32_t
+ m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
};
#endif
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 00f4010742b0..94b9efc2b2b0 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -11,8 +11,8 @@
// C Includes
#include <errno.h>
-#include <string.h>
#include <stdint.h>
+#include <string.h>
#include <unistd.h>
// C++ Includes
@@ -29,9 +29,11 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/common/NativeBreakpoint.h"
#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/linux/ProcessLauncherLinux.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
@@ -40,12 +42,13 @@
#include "lldb/Utility/PseudoTerminal.h"
#include "lldb/Utility/StringExtractor.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "NativeThreadLinux.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "ProcFileReader.h"
#include "Procfs.h"
-// System includes - They have to be included after framework includes because they define some
+// System includes - They have to be included after framework includes because
+// they define some
// macros which collide with variable names in other modules
#include <linux/unistd.h>
#include <sys/socket.h>
@@ -55,15 +58,12 @@
#include <sys/user.h>
#include <sys/wait.h>
-#include "lldb/Host/linux/Personality.h"
#include "lldb/Host/linux/Ptrace.h"
#include "lldb/Host/linux/Uio.h"
-#define LLDB_PERSONALITY_GET_CURRENT_SETTINGS 0xffffffff
-
// Support hardware breakpoints in case it has not been defined
#ifndef TRAP_HWBKPT
- #define TRAP_HWBKPT 4
+#define TRAP_HWBKPT 4
#endif
using namespace lldb;
@@ -73,2113 +73,1911 @@ using namespace llvm;
// Private bits we only need internally.
-static bool ProcessVmReadvSupported()
-{
- static bool is_supported;
- static std::once_flag flag;
-
- std::call_once(flag, [] {
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- uint32_t source = 0x47424742;
- uint32_t dest = 0;
-
- struct iovec local, remote;
- remote.iov_base = &source;
- local.iov_base = &dest;
- remote.iov_len = local.iov_len = sizeof source;
-
- // We shall try if cross-process-memory reads work by attempting to read a value from our own process.
- ssize_t res = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
- is_supported = (res == sizeof(source) && source == dest);
- if (log)
- {
- if (is_supported)
- log->Printf("%s: Detected kernel support for process_vm_readv syscall. Fast memory reads enabled.",
- __FUNCTION__);
- else
- log->Printf("%s: syscall process_vm_readv failed (error: %s). Fast memory reads disabled.",
- __FUNCTION__, strerror(errno));
- }
- });
+static bool ProcessVmReadvSupported() {
+ static bool is_supported;
+ static std::once_flag flag;
- return is_supported;
-}
-
-namespace
-{
-Error
-ResolveProcessArchitecture(lldb::pid_t pid, ArchSpec &arch)
-{
- // Grab process info for the running process.
- ProcessInstanceInfo process_info;
- if (!Host::GetProcessInfo(pid, process_info))
- return Error("failed to get process info");
-
- // Resolve the executable module.
- ModuleSpecList module_specs;
- if (!ObjectFile::GetModuleSpecifications(process_info.GetExecutableFile(), 0, 0, module_specs))
- return Error("failed to get module specifications");
- assert(module_specs.GetSize() == 1);
-
- arch = module_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
- if (arch.IsValid())
- return Error();
- else
- return Error("failed to retrieve a valid architecture from the exe module");
-}
-
-// Used to notify the parent about which part of the launch sequence failed.
-enum LaunchCallSpecifier
-{
- ePtraceFailed,
- eDupStdinFailed,
- eDupStdoutFailed,
- eDupStderrFailed,
- eChdirFailed,
- eExecFailed,
- eSetGidFailed,
- eSetSigMaskFailed,
- eLaunchCallMax = eSetSigMaskFailed
-};
-
-static uint8_t LLVM_ATTRIBUTE_NORETURN
-ExitChildAbnormally(LaunchCallSpecifier spec)
-{
- static_assert(eLaunchCallMax < 0x8, "Have more launch calls than we are able to represent");
- // This may truncate the topmost bits of the errno because the exit code is only 8 bits wide.
- // However, it should still give us a pretty good indication of what went wrong. (And the
- // most common errors have small numbers anyway).
- _exit(unsigned(spec) | (errno << 3));
-}
-
-// The second member is the errno (or its 5 lowermost bits anyway).
-inline std::pair<LaunchCallSpecifier, uint8_t>
-DecodeChildExitCode(int exit_code)
-{
- return std::make_pair(LaunchCallSpecifier(exit_code & 0x7), exit_code >> 3);
-}
-
-void
-MaybeLogLaunchInfo(const ProcessLaunchInfo &info)
-{
+ std::call_once(flag, [] {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (!log)
- return;
- if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
- log->Printf("%s: setting STDIN to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
- else
- log->Printf("%s leaving STDIN as is", __FUNCTION__);
-
- if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
- log->Printf("%s setting STDOUT to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
- else
- log->Printf("%s leaving STDOUT as is", __FUNCTION__);
-
- if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
- log->Printf("%s setting STDERR to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
- else
- log->Printf("%s leaving STDERR as is", __FUNCTION__);
+ uint32_t source = 0x47424742;
+ uint32_t dest = 0;
- int i = 0;
- for (const char **args = info.GetArguments().GetConstArgumentVector(); *args; ++args, ++i)
- log->Printf("%s arg %d: \"%s\"", __FUNCTION__, i, *args ? *args : "nullptr");
-}
+ struct iovec local, remote;
+ remote.iov_base = &source;
+ local.iov_base = &dest;
+ remote.iov_len = local.iov_len = sizeof source;
-void
-DisplayBytes(StreamString &s, void *bytes, uint32_t count)
-{
- uint8_t *ptr = (uint8_t *)bytes;
- const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
- for (uint32_t i = 0; i < loop_count; i++)
- {
- s.Printf("[%x]", *ptr);
- ptr++;
+ // We shall try if cross-process-memory reads work by attempting to read a
+ // value from our own process.
+ ssize_t res = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
+ is_supported = (res == sizeof(source) && source == dest);
+ if (log) {
+ if (is_supported)
+ log->Printf("%s: Detected kernel support for process_vm_readv syscall. "
+ "Fast memory reads enabled.",
+ __FUNCTION__);
+ else
+ log->Printf("%s: syscall process_vm_readv failed (error: %s). Fast "
+ "memory reads disabled.",
+ __FUNCTION__, strerror(errno));
}
-}
+ });
- void
- PtraceDisplayBytes(int &req, void *data, size_t data_size)
- {
- StreamString buf;
- Log *verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (
- POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE));
-
- if (verbose_log)
- {
- switch(req)
- {
- case PTRACE_POKETEXT:
- {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData());
- break;
- }
- case PTRACE_POKEDATA:
- {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData());
- break;
- }
- case PTRACE_POKEUSER:
- {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData());
- break;
- }
- case PTRACE_SETREGS:
- {
- DisplayBytes(buf, data, data_size);
- verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
- break;
- }
- case PTRACE_SETFPREGS:
- {
- DisplayBytes(buf, data, data_size);
- verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
- break;
- }
- case PTRACE_SETSIGINFO:
- {
- DisplayBytes(buf, data, sizeof(siginfo_t));
- verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
- break;
- }
- case PTRACE_SETREGSET:
- {
- // Extract iov_base from data, which is a pointer to the struct IOVEC
- DisplayBytes(buf, *(void **)data, data_size);
- verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
- break;
- }
- default:
- {
- }
- }
- }
- }
+ return is_supported;
+}
- static constexpr unsigned k_ptrace_word_size = sizeof(void*);
- static_assert(sizeof(long) >= k_ptrace_word_size, "Size of long must be larger than ptrace word size");
+namespace {
+void MaybeLogLaunchInfo(const ProcessLaunchInfo &info) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (!log)
+ return;
+
+ if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
+ log->Printf("%s: setting STDIN to '%s'", __FUNCTION__,
+ action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDIN as is", __FUNCTION__);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
+ log->Printf("%s setting STDOUT to '%s'", __FUNCTION__,
+ action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDOUT as is", __FUNCTION__);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
+ log->Printf("%s setting STDERR to '%s'", __FUNCTION__,
+ action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDERR as is", __FUNCTION__);
+
+ int i = 0;
+ for (const char **args = info.GetArguments().GetConstArgumentVector(); *args;
+ ++args, ++i)
+ log->Printf("%s arg %d: \"%s\"", __FUNCTION__, i,
+ *args ? *args : "nullptr");
+}
+
+void DisplayBytes(StreamString &s, void *bytes, uint32_t count) {
+ uint8_t *ptr = (uint8_t *)bytes;
+ const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
+ for (uint32_t i = 0; i < loop_count; i++) {
+ s.Printf("[%x]", *ptr);
+ ptr++;
+ }
+}
+
+void PtraceDisplayBytes(int &req, void *data, size_t data_size) {
+ StreamString buf;
+ Log *verbose_log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(
+ POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE));
+
+ if (verbose_log) {
+ switch (req) {
+ case PTRACE_POKETEXT: {
+ DisplayBytes(buf, &data, 8);
+ verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData());
+ break;
+ }
+ case PTRACE_POKEDATA: {
+ DisplayBytes(buf, &data, 8);
+ verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData());
+ break;
+ }
+ case PTRACE_POKEUSER: {
+ DisplayBytes(buf, &data, 8);
+ verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETREGS: {
+ DisplayBytes(buf, data, data_size);
+ verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETFPREGS: {
+ DisplayBytes(buf, data, data_size);
+ verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETSIGINFO: {
+ DisplayBytes(buf, data, sizeof(siginfo_t));
+ verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETREGSET: {
+ // Extract iov_base from data, which is a pointer to the struct IOVEC
+ DisplayBytes(buf, *(void **)data, data_size);
+ verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
+ break;
+ }
+ default: {}
+ }
+ }
+}
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+ "Size of long must be larger than ptrace word size");
} // end of anonymous namespace
// Simple helper function to ensure flags are enabled on the given file
// descriptor.
-static Error
-EnsureFDFlags(int fd, int flags)
-{
- Error error;
+static Error EnsureFDFlags(int fd, int flags) {
+ Error error;
- int status = fcntl(fd, F_GETFL);
- if (status == -1)
- {
- error.SetErrorToErrno();
- return error;
- }
-
- if (fcntl(fd, F_SETFL, status | flags) == -1)
- {
- error.SetErrorToErrno();
- return error;
- }
+ int status = fcntl(fd, F_GETFL);
+ if (status == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+ if (fcntl(fd, F_SETFL, status | flags) == -1) {
+ error.SetErrorToErrno();
return error;
+ }
+
+ return error;
}
// -----------------------------------------------------------------------------
// Public Static Methods
// -----------------------------------------------------------------------------
-Error
-NativeProcessProtocol::Launch (
+Error NativeProcessProtocol::Launch(
ProcessLaunchInfo &launch_info,
- NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop,
- NativeProcessProtocolSP &native_process_sp)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- Error error;
-
- // Verify the working directory is valid if one was specified.
- FileSpec working_dir{launch_info.GetWorkingDirectory()};
- if (working_dir &&
- (!working_dir.ResolvePath() ||
- working_dir.GetFileType() != FileSpec::eFileTypeDirectory))
- {
- error.SetErrorStringWithFormat ("No such file or directory: %s",
- working_dir.GetCString());
- return error;
- }
+ NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
+ NativeProcessProtocolSP &native_process_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ Error error;
+
+ // Verify the working directory is valid if one was specified.
+ FileSpec working_dir{launch_info.GetWorkingDirectory()};
+ if (working_dir &&
+ (!working_dir.ResolvePath() ||
+ working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ return error;
+ }
- // Create the NativeProcessLinux in launch mode.
- native_process_sp.reset (new NativeProcessLinux ());
+ // Create the NativeProcessLinux in launch mode.
+ native_process_sp.reset(new NativeProcessLinux());
- if (!native_process_sp->RegisterNativeDelegate (native_delegate))
- {
- native_process_sp.reset ();
- error.SetErrorStringWithFormat ("failed to register the native delegate");
- return error;
- }
+ if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
+ native_process_sp.reset();
+ error.SetErrorStringWithFormat("failed to register the native delegate");
+ return error;
+ }
- error = std::static_pointer_cast<NativeProcessLinux>(native_process_sp)->LaunchInferior(mainloop, launch_info);
+ error = std::static_pointer_cast<NativeProcessLinux>(native_process_sp)
+ ->LaunchInferior(mainloop, launch_info);
- if (error.Fail ())
- {
- native_process_sp.reset ();
- if (log)
- log->Printf ("NativeProcessLinux::%s failed to launch process: %s", __FUNCTION__, error.AsCString ());
- return error;
- }
+ if (error.Fail()) {
+ native_process_sp.reset();
+ if (log)
+ log->Printf("NativeProcessLinux::%s failed to launch process: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
- launch_info.SetProcessID (native_process_sp->GetID ());
+ launch_info.SetProcessID(native_process_sp->GetID());
- return error;
+ return error;
}
-Error
-NativeProcessProtocol::Attach (
- lldb::pid_t pid,
- NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop,
- NativeProcessProtocolSP &native_process_sp)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log && log->GetMask ().Test (POSIX_LOG_VERBOSE))
- log->Printf ("NativeProcessLinux::%s(pid = %" PRIi64 ")", __FUNCTION__, pid);
-
- // Retrieve the architecture for the running process.
- ArchSpec process_arch;
- Error error = ResolveProcessArchitecture(pid, process_arch);
- if (!error.Success ())
- return error;
+Error NativeProcessProtocol::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("NativeProcessLinux::%s(pid = %" PRIi64 ")", __FUNCTION__, pid);
- std::shared_ptr<NativeProcessLinux> native_process_linux_sp (new NativeProcessLinux ());
+ // Retrieve the architecture for the running process.
+ ArchSpec process_arch;
+ Error error = ResolveProcessArchitecture(pid, process_arch);
+ if (!error.Success())
+ return error;
- if (!native_process_linux_sp->RegisterNativeDelegate (native_delegate))
- {
- error.SetErrorStringWithFormat ("failed to register the native delegate");
- return error;
- }
+ std::shared_ptr<NativeProcessLinux> native_process_linux_sp(
+ new NativeProcessLinux());
- native_process_linux_sp->AttachToInferior (mainloop, pid, error);
- if (!error.Success ())
- return error;
+ if (!native_process_linux_sp->RegisterNativeDelegate(native_delegate)) {
+ error.SetErrorStringWithFormat("failed to register the native delegate");
+ return error;
+ }
- native_process_sp = native_process_linux_sp;
+ native_process_linux_sp->AttachToInferior(mainloop, pid, error);
+ if (!error.Success())
return error;
+
+ native_process_sp = native_process_linux_sp;
+ return error;
}
// -----------------------------------------------------------------------------
// Public Instance Methods
// -----------------------------------------------------------------------------
-NativeProcessLinux::NativeProcessLinux () :
- NativeProcessProtocol (LLDB_INVALID_PROCESS_ID),
- m_arch (),
- m_supports_mem_region (eLazyBoolCalculate),
- m_mem_region_cache (),
- m_pending_notification_tid(LLDB_INVALID_THREAD_ID)
-{
-}
-
-void
-NativeProcessLinux::AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__, pid);
-
- m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD,
- [this] (MainLoopBase &) { SigchldHandler(); }, error);
- if (! m_sigchld_handle)
- return;
-
- error = ResolveProcessArchitecture(pid, m_arch);
- if (!error.Success())
- return;
-
- // Set the architecture to the exe architecture.
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ") detected architecture %s", __FUNCTION__, pid, m_arch.GetArchitectureName ());
-
- m_pid = pid;
- SetState(eStateAttaching);
-
- Attach(pid, error);
-}
-
-void
-NativeProcessLinux::ChildFunc(const ProcessLaunchInfo &info)
-{
- // Start tracing this child that is about to exec.
- if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
- ExitChildAbnormally(ePtraceFailed);
-
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- ExitChildAbnormally(eSetGidFailed);
-
- // Attempt to have our own process group.
- if (setpgid(0, 0) != 0)
- {
- // FIXME log that this failed. This is common.
- // Don't allow this to prevent an inferior exec.
- }
-
- // Dup file descriptors if needed.
- if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
- if (!DupDescriptor(action->GetFileSpec(), STDIN_FILENO, O_RDONLY))
- ExitChildAbnormally(eDupStdinFailed);
-
- if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
- if (!DupDescriptor(action->GetFileSpec(), STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
- ExitChildAbnormally(eDupStdoutFailed);
-
- if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
- if (!DupDescriptor(action->GetFileSpec(), STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
- ExitChildAbnormally(eDupStderrFailed);
+NativeProcessLinux::NativeProcessLinux()
+ : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(),
+ m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache(),
+ m_pending_notification_tid(LLDB_INVALID_THREAD_ID) {}
+
+void NativeProcessLinux::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
+ Error &error) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__,
+ pid);
+
+ m_sigchld_handle = mainloop.RegisterSignal(
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
+ if (!m_sigchld_handle)
+ return;
+
+ error = ResolveProcessArchitecture(pid, m_arch);
+ if (!error.Success())
+ return;
+
+ // Set the architecture to the exe architecture.
+ if (log)
+ log->Printf("NativeProcessLinux::%s (pid = %" PRIi64
+ ") detected architecture %s",
+ __FUNCTION__, pid, m_arch.GetArchitectureName());
+
+ m_pid = pid;
+ SetState(eStateAttaching);
+
+ Attach(pid, error);
+}
+
+Error NativeProcessLinux::LaunchInferior(MainLoop &mainloop,
+ ProcessLaunchInfo &launch_info) {
+ Error error;
+ m_sigchld_handle = mainloop.RegisterSignal(
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
+ if (!m_sigchld_handle)
+ return error;
- // Close everything besides stdin, stdout, and stderr that has no file
- // action to avoid leaking
- for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
- if (!info.GetFileActionForFD(fd))
- close(fd);
+ SetState(eStateLaunching);
- // Change working directory
- if (info.GetWorkingDirectory() && 0 != ::chdir(info.GetWorkingDirectory().GetCString()))
- ExitChildAbnormally(eChdirFailed);
+ MaybeLogLaunchInfo(launch_info);
- // Disable ASLR if requested.
- if (info.GetFlags().Test(lldb::eLaunchFlagDisableASLR))
- {
- const int old_personality = personality(LLDB_PERSONALITY_GET_CURRENT_SETTINGS);
- if (old_personality == -1)
- {
- // Can't retrieve Linux personality. Cannot disable ASLR.
- }
- else
- {
- const int new_personality = personality(ADDR_NO_RANDOMIZE | old_personality);
- if (new_personality == -1)
- {
- // Disabling ASLR failed.
- }
- else
- {
- // Disabling ASLR succeeded.
- }
- }
- }
-
- // Clear the signal mask to prevent the child from being affected by
- // any masking done by the parent.
- sigset_t set;
- if (sigemptyset(&set) != 0 || pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
- ExitChildAbnormally(eSetSigMaskFailed);
+ ::pid_t pid =
+ ProcessLauncherLinux().LaunchProcess(launch_info, error).GetProcessId();
+ if (error.Fail())
+ return error;
- const char **argv = info.GetArguments().GetConstArgumentVector();
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Propagate the environment if one is not supplied.
- const char **envp = info.GetEnvironmentEntries().GetConstArgumentVector();
- if (envp == NULL || envp[0] == NULL)
- envp = const_cast<const char **>(environ);
+ // Wait for the child process to trap on its call to execve.
+ ::pid_t wpid;
+ int status;
+ if ((wpid = waitpid(pid, &status, 0)) < 0) {
+ error.SetErrorToErrno();
+ if (log)
+ log->Printf("NativeProcessLinux::%s waitpid for inferior failed with %s",
+ __FUNCTION__, error.AsCString());
- // Execute. We should never return...
- execve(argv[0], const_cast<char *const *>(argv), const_cast<char *const *>(envp));
+ // Mark the inferior as invalid.
+ // FIXME this could really use a new state - eStateLaunchFailure. For now,
+ // using eStateInvalid.
+ SetState(StateType::eStateInvalid);
- if (errno == ETXTBSY)
- {
- // On android M and earlier we can get this error because the adb deamon can hold a write
- // handle on the executable even after it has finished uploading it. This state lasts
- // only a short time and happens only when there are many concurrent adb commands being
- // issued, such as when running the test suite. (The file remains open when someone does
- // an "adb shell" command in the fork() child before it has had a chance to exec.) Since
- // this state should clear up quickly, wait a while and then give it one more go.
- usleep(50000);
- execve(argv[0], const_cast<char *const *>(argv), const_cast<char *const *>(envp));
- }
-
- // ...unless exec fails. In which case we definitely need to end the child here.
- ExitChildAbnormally(eExecFailed);
-}
+ return error;
+ }
+ assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
+ "Could not sync with inferior process.");
-Error
-NativeProcessLinux::LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info)
-{
- Error error;
- m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
- if (!m_sigchld_handle)
- return error;
+ if (log)
+ log->Printf("NativeProcessLinux::%s inferior started, now in stopped state",
+ __FUNCTION__);
- SetState(eStateLaunching);
+ error = SetDefaultPtraceOpts(pid);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s inferior failed to set default "
+ "ptrace options: %s",
+ __FUNCTION__, error.AsCString());
- lldb_utility::PseudoTerminal terminal;
- const size_t err_len = 1024;
- char err_str[err_len];
- lldb::pid_t pid;
+ // Mark the inferior as invalid.
+ // FIXME this could really use a new state - eStateLaunchFailure. For now,
+ // using eStateInvalid.
+ SetState(StateType::eStateInvalid);
- MaybeLogLaunchInfo(launch_info);
+ return error;
+ }
- if ((pid = terminal.Fork(err_str, err_len)) == static_cast<lldb::pid_t> (-1))
- {
- error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("Process fork failed: %s", err_str);
- return error;
- }
+ // Release the master terminal descriptor and pass it off to the
+ // NativeProcessLinux instance. Similarly stash the inferior pid.
+ m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+ m_pid = pid;
+ launch_info.SetProcessID(pid);
- // Child process.
- if (pid == 0)
- {
- // First, make sure we disable all logging. If we are logging to stdout, our logs can be
- // mistaken for inferior output.
- Log::DisableAllLogChannels(nullptr);
+ if (m_terminal_fd != -1) {
+ error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s inferior EnsureFDFlags failed for "
+ "ensuring terminal O_NONBLOCK setting: %s",
+ __FUNCTION__, error.AsCString());
- // terminal has already dupped the tty descriptors to stdin/out/err.
- // This closes original fd from which they were copied (and avoids
- // leaking descriptors to the debugged process.
- terminal.CloseSlaveFileDescriptor();
+ // Mark the inferior as invalid.
+ // FIXME this could really use a new state - eStateLaunchFailure. For
+ // now, using eStateInvalid.
+ SetState(StateType::eStateInvalid);
- ChildFunc(launch_info);
+ return error;
}
+ }
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__,
+ uint64_t(pid));
- // Wait for the child process to trap on its call to execve.
- ::pid_t wpid;
- int status;
- if ((wpid = waitpid(pid, &status, 0)) < 0)
- {
- error.SetErrorToErrno();
- if (log)
- log->Printf ("NativeProcessLinux::%s waitpid for inferior failed with %s",
- __FUNCTION__, error.AsCString ());
+ ResolveProcessArchitecture(m_pid, m_arch);
+ NativeThreadLinuxSP thread_sp = AddThread(pid);
+ assert(thread_sp && "AddThread() returned a nullptr thread");
+ thread_sp->SetStoppedBySignal(SIGSTOP);
+ ThreadWasCreated(*thread_sp);
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
+ // Let our process instance know the thread has stopped.
+ SetCurrentThreadID(thread_sp->GetID());
+ SetState(StateType::eStateStopped);
- return error;
- }
- else if (WIFEXITED(status))
- {
- auto p = DecodeChildExitCode(WEXITSTATUS(status));
- Error child_error(p.second, eErrorTypePOSIX);
- const char *failure_reason;
- switch (p.first)
- {
- case ePtraceFailed:
- failure_reason = "Child ptrace failed";
- break;
- case eDupStdinFailed:
- failure_reason = "Child open stdin failed";
- break;
- case eDupStdoutFailed:
- failure_reason = "Child open stdout failed";
- break;
- case eDupStderrFailed:
- failure_reason = "Child open stderr failed";
- break;
- case eChdirFailed:
- failure_reason = "Child failed to set working directory";
- break;
- case eExecFailed:
- failure_reason = "Child exec failed";
- break;
- case eSetGidFailed:
- failure_reason = "Child setgid failed";
- break;
- case eSetSigMaskFailed:
- failure_reason = "Child failed to set signal mask";
- break;
+ if (log) {
+ if (error.Success())
+ log->Printf("NativeProcessLinux::%s inferior launching succeeded",
+ __FUNCTION__);
+ else
+ log->Printf("NativeProcessLinux::%s inferior launching failed: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ return error;
+}
+
+::pid_t NativeProcessLinux::Attach(lldb::pid_t pid, Error &error) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Use a map to keep track of the threads which we have attached/need to
+ // attach.
+ Host::TidMap tids_to_attach;
+ if (pid <= 1) {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Attaching to process 1 is not allowed.");
+ return -1;
+ }
+
+ while (Host::FindProcessThreads(pid, tids_to_attach)) {
+ for (Host::TidMap::iterator it = tids_to_attach.begin();
+ it != tids_to_attach.end();) {
+ if (it->second == false) {
+ lldb::tid_t tid = it->first;
+
+ // Attach to the requested process.
+ // An attach will cause the thread to stop with a SIGSTOP.
+ error = PtraceWrapper(PTRACE_ATTACH, tid);
+ if (error.Fail()) {
+ // No such thread. The thread may have exited.
+ // More error handling may be needed.
+ if (error.GetError() == ESRCH) {
+ it = tids_to_attach.erase(it);
+ continue;
+ } else
+ return -1;
}
- error.SetErrorStringWithFormat("%s: %d - %s (error code truncated)", failure_reason, child_error.GetError(), child_error.AsCString());
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s inferior exited with status %d before issuing a STOP",
- __FUNCTION__,
- WEXITSTATUS(status));
+ int status;
+ // Need to use __WALL otherwise we receive an error with errno=ECHLD
+ // At this point we should have a thread stopped if waitpid succeeds.
+ if ((status = waitpid(tid, NULL, __WALL)) < 0) {
+ // No such thread. The thread may have exited.
+ // More error handling may be needed.
+ if (errno == ESRCH) {
+ it = tids_to_attach.erase(it);
+ continue;
+ } else {
+ error.SetErrorToErrno();
+ return -1;
+ }
}
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
-
- return error;
- }
- assert(WIFSTOPPED(status) && (wpid == static_cast< ::pid_t> (pid)) &&
- "Could not sync with inferior process.");
-
- if (log)
- log->Printf ("NativeProcessLinux::%s inferior started, now in stopped state", __FUNCTION__);
+ error = SetDefaultPtraceOpts(tid);
+ if (error.Fail())
+ return -1;
- error = SetDefaultPtraceOpts(pid);
- if (error.Fail())
- {
if (log)
- log->Printf ("NativeProcessLinux::%s inferior failed to set default ptrace options: %s",
- __FUNCTION__, error.AsCString ());
+ log->Printf("NativeProcessLinux::%s() adding tid = %" PRIu64,
+ __FUNCTION__, tid);
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
+ it->second = true;
- return error;
- }
+ // Create the thread, mark it as stopped.
+ NativeThreadLinuxSP thread_sp(AddThread(static_cast<lldb::tid_t>(tid)));
+ assert(thread_sp && "AddThread() returned a nullptr");
- // Release the master terminal descriptor and pass it off to the
- // NativeProcessLinux instance. Similarly stash the inferior pid.
- m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
- m_pid = pid;
- launch_info.SetProcessID(pid);
-
- // Set the terminal fd to be in non blocking mode (it simplifies the
- // implementation of ProcessLinux::GetSTDOUT to have a non-blocking
- // descriptor to read from).
- error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
- if (error.Fail())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s inferior EnsureFDFlags failed for ensuring terminal O_NONBLOCK setting: %s",
- __FUNCTION__, error.AsCString ());
-
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
+ // This will notify this is a new thread and tell the system it is
+ // stopped.
+ thread_sp->SetStoppedBySignal(SIGSTOP);
+ ThreadWasCreated(*thread_sp);
+ SetCurrentThreadID(thread_sp->GetID());
+ }
- return error;
+ // move the loop forward
+ ++it;
}
+ }
- if (log)
- log->Printf ("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
-
- ResolveProcessArchitecture(m_pid, m_arch);
- NativeThreadLinuxSP thread_sp = AddThread(pid);
- assert (thread_sp && "AddThread() returned a nullptr thread");
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
-
+ if (tids_to_attach.size() > 0) {
+ m_pid = pid;
// Let our process instance know the thread has stopped.
- SetCurrentThreadID (thread_sp->GetID ());
- SetState (StateType::eStateStopped);
+ SetState(StateType::eStateStopped);
+ } else {
+ error.SetErrorToGenericError();
+ error.SetErrorString("No such process.");
+ return -1;
+ }
- if (log)
- {
- if (error.Success ())
- log->Printf("NativeProcessLinux::%s inferior launching succeeded", __FUNCTION__);
- else
- log->Printf("NativeProcessLinux::%s inferior launching failed: %s", __FUNCTION__, error.AsCString());
- }
- return error;
+ return pid;
}
-::pid_t
-NativeProcessLinux::Attach(lldb::pid_t pid, Error &error)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+Error NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {
+ long ptrace_opts = 0;
- // Use a map to keep track of the threads which we have attached/need to attach.
- Host::TidMap tids_to_attach;
- if (pid <= 1)
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Attaching to process 1 is not allowed.");
- return -1;
- }
+ // Have the child raise an event on exit. This is used to keep the child in
+ // limbo until it is destroyed.
+ ptrace_opts |= PTRACE_O_TRACEEXIT;
- while (Host::FindProcessThreads(pid, tids_to_attach))
- {
- for (Host::TidMap::iterator it = tids_to_attach.begin();
- it != tids_to_attach.end();)
- {
- if (it->second == false)
- {
- lldb::tid_t tid = it->first;
-
- // Attach to the requested process.
- // An attach will cause the thread to stop with a SIGSTOP.
- error = PtraceWrapper(PTRACE_ATTACH, tid);
- if (error.Fail())
- {
- // No such thread. The thread may have exited.
- // More error handling may be needed.
- if (error.GetError() == ESRCH)
- {
- it = tids_to_attach.erase(it);
- continue;
- }
- else
- return -1;
- }
-
- int status;
- // Need to use __WALL otherwise we receive an error with errno=ECHLD
- // At this point we should have a thread stopped if waitpid succeeds.
- if ((status = waitpid(tid, NULL, __WALL)) < 0)
- {
- // No such thread. The thread may have exited.
- // More error handling may be needed.
- if (errno == ESRCH)
- {
- it = tids_to_attach.erase(it);
- continue;
- }
- else
- {
- error.SetErrorToErrno();
- return -1;
- }
- }
-
- error = SetDefaultPtraceOpts(tid);
- if (error.Fail())
- return -1;
-
- if (log)
- log->Printf ("NativeProcessLinux::%s() adding tid = %" PRIu64, __FUNCTION__, tid);
-
- it->second = true;
-
- // Create the thread, mark it as stopped.
- NativeThreadLinuxSP thread_sp (AddThread(static_cast<lldb::tid_t>(tid)));
- assert (thread_sp && "AddThread() returned a nullptr");
-
- // This will notify this is a new thread and tell the system it is stopped.
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
- SetCurrentThreadID (thread_sp->GetID ());
- }
-
- // move the loop forward
- ++it;
- }
- }
+ // Have the tracer trace threads which spawn in the inferior process.
+ // TODO: if we want to support tracing the inferiors' child, add the
+ // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
+ ptrace_opts |= PTRACE_O_TRACECLONE;
- if (tids_to_attach.size() > 0)
- {
- m_pid = pid;
- // Let our process instance know the thread has stopped.
- SetState (StateType::eStateStopped);
- }
- else
- {
- error.SetErrorToGenericError();
- error.SetErrorString("No such process.");
- return -1;
- }
+ // Have the tracer notify us before execve returns
+ // (needed to disable legacy SIGTRAP generation)
+ ptrace_opts |= PTRACE_O_TRACEEXEC;
- return pid;
+ return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void *)ptrace_opts);
}
-Error
-NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid)
-{
- long ptrace_opts = 0;
-
- // Have the child raise an event on exit. This is used to keep the child in
- // limbo until it is destroyed.
- ptrace_opts |= PTRACE_O_TRACEEXIT;
-
- // Have the tracer trace threads which spawn in the inferior process.
- // TODO: if we want to support tracing the inferiors' child, add the
- // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
- ptrace_opts |= PTRACE_O_TRACECLONE;
-
- // Have the tracer notify us before execve returns
- // (needed to disable legacy SIGTRAP generation)
- ptrace_opts |= PTRACE_O_TRACEEXEC;
-
- return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void*)ptrace_opts);
-}
-
-static ExitType convert_pid_status_to_exit_type (int status)
-{
- if (WIFEXITED (status))
- return ExitType::eExitTypeExit;
- else if (WIFSIGNALED (status))
- return ExitType::eExitTypeSignal;
- else if (WIFSTOPPED (status))
- return ExitType::eExitTypeStop;
- else
- {
- // We don't know what this is.
- return ExitType::eExitTypeInvalid;
- }
+static ExitType convert_pid_status_to_exit_type(int status) {
+ if (WIFEXITED(status))
+ return ExitType::eExitTypeExit;
+ else if (WIFSIGNALED(status))
+ return ExitType::eExitTypeSignal;
+ else if (WIFSTOPPED(status))
+ return ExitType::eExitTypeStop;
+ else {
+ // We don't know what this is.
+ return ExitType::eExitTypeInvalid;
+ }
}
-static int convert_pid_status_to_return_code (int status)
-{
- if (WIFEXITED (status))
- return WEXITSTATUS (status);
- else if (WIFSIGNALED (status))
- return WTERMSIG (status);
- else if (WIFSTOPPED (status))
- return WSTOPSIG (status);
- else
- {
- // We don't know what this is.
- return ExitType::eExitTypeInvalid;
- }
+static int convert_pid_status_to_return_code(int status) {
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else if (WIFSIGNALED(status))
+ return WTERMSIG(status);
+ else if (WIFSTOPPED(status))
+ return WSTOPSIG(status);
+ else {
+ // We don't know what this is.
+ return ExitType::eExitTypeInvalid;
+ }
}
// Handles all waitpid events from the inferior process.
-void
-NativeProcessLinux::MonitorCallback(lldb::pid_t pid,
- bool exited,
- int signal,
- int status)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
+ int signal, int status) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Certain activities differ based on whether the pid is the tid of the main thread.
- const bool is_main_thread = (pid == GetID ());
+ // Certain activities differ based on whether the pid is the tid of the main
+ // thread.
+ const bool is_main_thread = (pid == GetID());
- // Handle when the thread exits.
- if (exited)
- {
+ // Handle when the thread exits.
+ if (exited) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() got exit signal(%d) , tid = %" PRIu64
+ " (%s main thread)",
+ __FUNCTION__, signal, pid, is_main_thread ? "is" : "is not");
+
+ // This is a thread that exited. Ensure we're not tracking it anymore.
+ const bool thread_found = StopTrackingThread(pid);
+
+ if (is_main_thread) {
+ // We only set the exit status and notify the delegate if we haven't
+ // already set the process
+ // state to an exited state. We normally should have received a SIGTRAP |
+ // (PTRACE_EVENT_EXIT << 8)
+ // for the main thread.
+ const bool already_notified = (GetState() == StateType::eStateExited) ||
+ (GetState() == StateType::eStateCrashed);
+ if (!already_notified) {
if (log)
- log->Printf ("NativeProcessLinux::%s() got exit signal(%d) , tid = %" PRIu64 " (%s main thread)", __FUNCTION__, signal, pid, is_main_thread ? "is" : "is not");
-
- // This is a thread that exited. Ensure we're not tracking it anymore.
- const bool thread_found = StopTrackingThread (pid);
-
- if (is_main_thread)
- {
- // We only set the exit status and notify the delegate if we haven't already set the process
- // state to an exited state. We normally should have received a SIGTRAP | (PTRACE_EVENT_EXIT << 8)
- // for the main thread.
- const bool already_notified = (GetState() == StateType::eStateExited) || (GetState () == StateType::eStateCrashed);
- if (!already_notified)
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " handling main thread exit (%s), expected exit state already set but state was %s instead, setting exit state now", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found", StateAsCString (GetState ()));
- // The main thread exited. We're done monitoring. Report to delegate.
- SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true);
-
- // Notify delegate that our process has exited.
- SetState (StateType::eStateExited, true);
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " main thread now exited (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found");
- }
- }
- else
- {
- // Do we want to report to the delegate in this case? I think not. If this was an orderly
- // thread exit, we would already have received the SIGTRAP | (PTRACE_EVENT_EXIT << 8) signal,
- // and we would have done an all-stop then.
- if (log)
- log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " handling non-main thread exit (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found");
- }
- return;
- }
-
- siginfo_t info;
- const auto info_err = GetSignalInfo(pid, &info);
- auto thread_sp = GetThreadByID(pid);
-
- if (! thread_sp)
- {
- // Normally, the only situation when we cannot find the thread is if we have just
- // received a new thread notification. This is indicated by GetSignalInfo() returning
- // si_code == SI_USER and si_pid == 0
+ log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
+ " handling main thread exit (%s), expected exit state "
+ "already set but state was %s instead, setting exit "
+ "state now",
+ __FUNCTION__, pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found",
+ StateAsCString(GetState()));
+ // The main thread exited. We're done monitoring. Report to delegate.
+ SetExitStatus(convert_pid_status_to_exit_type(status),
+ convert_pid_status_to_return_code(status), nullptr, true);
+
+ // Notify delegate that our process has exited.
+ SetState(StateType::eStateExited, true);
+ } else {
if (log)
- log->Printf("NativeProcessLinux::%s received notification about an unknown tid %" PRIu64 ".", __FUNCTION__, pid);
-
- if (info_err.Fail())
- {
- if (log)
- log->Printf("NativeProcessLinux::%s (tid %" PRIu64 ") GetSignalInfo failed (%s). Ingoring this notification.", __FUNCTION__, pid, info_err.AsCString());
- return;
- }
-
- if (log && (info.si_code != SI_USER || info.si_pid != 0))
- log->Printf("NativeProcessLinux::%s (tid %" PRIu64 ") unexpected signal info (si_code: %d, si_pid: %d). Treating as a new thread notification anyway.", __FUNCTION__, pid, info.si_code, info.si_pid);
-
- auto thread_sp = AddThread(pid);
- // Resume the newly created thread.
- ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*thread_sp);
- return;
- }
-
- // Get details on the signal raised.
- if (info_err.Success())
- {
- // We have retrieved the signal info. Dispatch appropriately.
- if (info.si_signo == SIGTRAP)
- MonitorSIGTRAP(info, *thread_sp);
- else
- MonitorSignal(info, *thread_sp, exited);
- }
+ log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
+ " main thread now exited (%s)",
+ __FUNCTION__, pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found");
+ }
+ } else {
+ // Do we want to report to the delegate in this case? I think not. If
+ // this was an orderly
+ // thread exit, we would already have received the SIGTRAP |
+ // (PTRACE_EVENT_EXIT << 8) signal,
+ // and we would have done an all-stop then.
+ if (log)
+ log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
+ " handling non-main thread exit (%s)",
+ __FUNCTION__, pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found");
+ }
+ return;
+ }
+
+ siginfo_t info;
+ const auto info_err = GetSignalInfo(pid, &info);
+ auto thread_sp = GetThreadByID(pid);
+
+ if (!thread_sp) {
+ // Normally, the only situation when we cannot find the thread is if we have
+ // just
+ // received a new thread notification. This is indicated by GetSignalInfo()
+ // returning
+ // si_code == SI_USER and si_pid == 0
+ if (log)
+ log->Printf("NativeProcessLinux::%s received notification about an "
+ "unknown tid %" PRIu64 ".",
+ __FUNCTION__, pid);
+
+ if (info_err.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid %" PRIu64
+ ") GetSignalInfo failed (%s). Ingoring this notification.",
+ __FUNCTION__, pid, info_err.AsCString());
+ return;
+ }
+
+ if (log && (info.si_code != SI_USER || info.si_pid != 0))
+ log->Printf("NativeProcessLinux::%s (tid %" PRIu64
+ ") unexpected signal info (si_code: %d, si_pid: %d). "
+ "Treating as a new thread notification anyway.",
+ __FUNCTION__, pid, info.si_code, info.si_pid);
+
+ auto thread_sp = AddThread(pid);
+ // Resume the newly created thread.
+ ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(*thread_sp);
+ return;
+ }
+
+ // Get details on the signal raised.
+ if (info_err.Success()) {
+ // We have retrieved the signal info. Dispatch appropriately.
+ if (info.si_signo == SIGTRAP)
+ MonitorSIGTRAP(info, *thread_sp);
else
- {
- if (info_err.GetError() == EINVAL)
- {
- // This is a group stop reception for this tid.
- // We can reach here if we reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU into the
- // tracee, triggering the group-stop mechanism. Normally receiving these would stop
- // the process, pending a SIGCONT. Simulating this state in a debugger is hard and is
- // generally not needed (one use case is debugging background task being managed by a
- // shell). For general use, it is sufficient to stop the process in a signal-delivery
- // stop which happens before the group stop. This done by MonitorSignal and works
- // correctly for all signals.
- if (log)
- log->Printf("NativeProcessLinux::%s received a group stop for pid %" PRIu64 " tid %" PRIu64 ". Transparent handling of group stops not supported, resuming the thread.", __FUNCTION__, GetID (), pid);
- ResumeThread(*thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- }
- else
- {
- // ptrace(GETSIGINFO) failed (but not due to group-stop).
-
- // A return value of ESRCH means the thread/process is no longer on the system,
- // so it was killed somehow outside of our control. Either way, we can't do anything
- // with it anymore.
-
- // Stop tracking the metadata for the thread since it's entirely off the system now.
- const bool thread_found = StopTrackingThread (pid);
-
- if (log)
- log->Printf ("NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64 ", signal = %d, status = %d (%s, %s, %s)",
- __FUNCTION__, info_err.AsCString(), pid, signal, status, info_err.GetError() == ESRCH ? "thread/process killed" : "unknown reason", is_main_thread ? "is main thread" : "is not main thread", thread_found ? "thread metadata removed" : "thread metadata not found");
-
- if (is_main_thread)
- {
- // Notify the delegate - our process is not available but appears to have been killed outside
- // our control. Is eStateExited the right exit state in this case?
- SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true);
- SetState (StateType::eStateExited, true);
- }
- else
- {
- // This thread was pulled out from underneath us. Anything to do here? Do we want to do an all stop?
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 " non-main thread exit occurred, didn't tell delegate anything since thread disappeared out from underneath us", __FUNCTION__, GetID (), pid);
- }
- }
- }
-}
-
-void
-NativeProcessLinux::WaitForNewThread(::pid_t tid)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- NativeThreadLinuxSP new_thread_sp = GetThreadByID(tid);
-
- if (new_thread_sp)
- {
- // We are already tracking the thread - we got the event on the new thread (see
- // MonitorSignal) before this one. We are done.
- return;
- }
-
- // The thread is not tracked yet, let's wait for it to appear.
- int status = -1;
- ::pid_t wait_pid;
- do
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() received thread creation event for tid %" PRIu32 ". tid not tracked yet, waiting for thread to appear...", __FUNCTION__, tid);
- wait_pid = waitpid(tid, &status, __WALL);
- }
- while (wait_pid == -1 && errno == EINTR);
- // Since we are waiting on a specific tid, this must be the creation event. But let's do
- // some checks just in case.
- if (wait_pid != tid) {
- if (log)
- log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime", __FUNCTION__, tid);
- // The only way I know of this could happen is if the whole process was
- // SIGKILLed in the mean time. In any case, we can't do anything about that now.
- return;
- }
- if (WIFEXITED(status))
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " returned an 'exited' event. Not tracking the thread.", __FUNCTION__, tid);
- // Also a very improbable event.
- return;
- }
-
- siginfo_t info;
- Error error = GetSignalInfo(tid, &info);
- if (error.Fail())
- {
+ MonitorSignal(info, *thread_sp, exited);
+ } else {
+ if (info_err.GetError() == EINVAL) {
+ // This is a group stop reception for this tid.
+ // We can reach here if we reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU
+ // into the
+ // tracee, triggering the group-stop mechanism. Normally receiving these
+ // would stop
+ // the process, pending a SIGCONT. Simulating this state in a debugger is
+ // hard and is
+ // generally not needed (one use case is debugging background task being
+ // managed by a
+ // shell). For general use, it is sufficient to stop the process in a
+ // signal-delivery
+ // stop which happens before the group stop. This done by MonitorSignal
+ // and works
+ // correctly for all signals.
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s received a group stop for pid %" PRIu64
+ " tid %" PRIu64 ". Transparent handling of group stops not "
+ "supported, resuming the thread.",
+ __FUNCTION__, GetID(), pid);
+ ResumeThread(*thread_sp, thread_sp->GetState(),
+ LLDB_INVALID_SIGNAL_NUMBER);
+ } else {
+ // ptrace(GETSIGINFO) failed (but not due to group-stop).
+
+ // A return value of ESRCH means the thread/process is no longer on the
+ // system,
+ // so it was killed somehow outside of our control. Either way, we can't
+ // do anything
+ // with it anymore.
+
+ // Stop tracking the metadata for the thread since it's entirely off the
+ // system now.
+ const bool thread_found = StopTrackingThread(pid);
+
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64
+ ", signal = %d, status = %d (%s, %s, %s)",
+ __FUNCTION__, info_err.AsCString(), pid, signal, status,
+ info_err.GetError() == ESRCH ? "thread/process killed"
+ : "unknown reason",
+ is_main_thread ? "is main thread" : "is not main thread",
+ thread_found ? "thread metadata removed"
+ : "thread metadata not found");
+
+ if (is_main_thread) {
+ // Notify the delegate - our process is not available but appears to
+ // have been killed outside
+ // our control. Is eStateExited the right exit state in this case?
+ SetExitStatus(convert_pid_status_to_exit_type(status),
+ convert_pid_status_to_return_code(status), nullptr, true);
+ SetState(StateType::eStateExited, true);
+ } else {
+ // This thread was pulled out from underneath us. Anything to do here?
+ // Do we want to do an all stop?
if (log)
- log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime.", __FUNCTION__, tid);
- return;
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64
+ " non-main thread exit occurred, didn't tell delegate "
+ "anything since thread disappeared out from underneath "
+ "us",
+ __FUNCTION__, GetID(), pid);
+ }
}
-
- if (((info.si_pid != 0) || (info.si_code != SI_USER)) && log)
- {
- // We should be getting a thread creation signal here, but we received something
- // else. There isn't much we can do about it now, so we will just log that. Since the
- // thread is alive and we are receiving events from it, we shall pretend that it was
- // created properly.
- log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " received unexpected signal with code %d from pid %d.", __FUNCTION__, tid, info.si_code, info.si_pid);
- }
-
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 ": tracking new thread tid %" PRIu32,
- __FUNCTION__, GetID (), tid);
-
- new_thread_sp = AddThread(tid);
- ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*new_thread_sp);
+ }
}
-void
-NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- const bool is_main_thread = (thread.GetID() == GetID ());
+void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
+ NativeThreadLinuxSP new_thread_sp = GetThreadByID(tid);
- switch (info.si_code)
- {
- // TODO: these two cases are required if we want to support tracing of the inferiors' children. We'd need this to debug a monitor.
- // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
- // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+ if (new_thread_sp) {
+ // We are already tracking the thread - we got the event on the new thread
+ // (see
+ // MonitorSignal) before this one. We are done.
+ return;
+ }
- case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
- {
- // This is the notification on the parent thread which informs us of new thread
- // creation.
- // We don't want to do anything with the parent thread so we just resume it. In case we
- // want to implement "break on thread creation" functionality, we would need to stop
- // here.
-
- unsigned long event_message = 0;
- if (GetEventMessage(thread.GetID(), &event_message).Fail())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event but GetEventMessage failed so we don't know the new tid", __FUNCTION__, thread.GetID());
- } else
- WaitForNewThread(event_message);
+ // The thread is not tracked yet, let's wait for it to appear.
+ int status = -1;
+ ::pid_t wait_pid;
+ do {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received thread creation event for "
+ "tid %" PRIu32
+ ". tid not tracked yet, waiting for thread to appear...",
+ __FUNCTION__, tid);
+ wait_pid = waitpid(tid, &status, __WALL);
+ } while (wait_pid == -1 && errno == EINTR);
+ // Since we are waiting on a specific tid, this must be the creation event.
+ // But let's do
+ // some checks just in case.
+ if (wait_pid != tid) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() waiting for tid %" PRIu32
+ " failed. Assuming the thread has disappeared in the meantime",
+ __FUNCTION__, tid);
+ // The only way I know of this could happen is if the whole process was
+ // SIGKILLed in the mean time. In any case, we can't do anything about that
+ // now.
+ return;
+ }
+ if (WIFEXITED(status)) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() waiting for tid %" PRIu32
+ " returned an 'exited' event. Not tracking the thread.",
+ __FUNCTION__, tid);
+ // Also a very improbable event.
+ return;
+ }
+
+ siginfo_t info;
+ Error error = GetSignalInfo(tid, &info);
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32
+ " failed. Assuming the thread has disappeared in the meantime.",
+ __FUNCTION__, tid);
+ return;
+ }
+
+ if (((info.si_pid != 0) || (info.si_code != SI_USER)) && log) {
+ // We should be getting a thread creation signal here, but we received
+ // something
+ // else. There isn't much we can do about it now, so we will just log that.
+ // Since the
+ // thread is alive and we are receiving events from it, we shall pretend
+ // that it was
+ // created properly.
+ log->Printf("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32
+ " received unexpected signal with code %d from pid %d.",
+ __FUNCTION__, tid, info.si_code, info.si_pid);
+ }
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64
+ ": tracking new thread tid %" PRIu32,
+ __FUNCTION__, GetID(), tid);
+
+ new_thread_sp = AddThread(tid);
+ ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(*new_thread_sp);
+}
+
+void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
+ NativeThreadLinux &thread) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ const bool is_main_thread = (thread.GetID() == GetID());
+
+ assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
+
+ switch (info.si_code) {
+ // TODO: these two cases are required if we want to support tracing of the
+ // inferiors' children. We'd need this to debug a monitor.
+ // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
+ // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+
+ case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
+ // This is the notification on the parent thread which informs us of new
+ // thread
+ // creation.
+ // We don't want to do anything with the parent thread so we just resume it.
+ // In case we
+ // want to implement "break on thread creation" functionality, we would need
+ // to stop
+ // here.
+
+ unsigned long event_message = 0;
+ if (GetEventMessage(thread.GetID(), &event_message).Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64
+ " received thread creation event but GetEventMessage "
+ "failed so we don't know the new tid",
+ __FUNCTION__, thread.GetID());
+ } else
+ WaitForNewThread(event_message);
+
+ ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+ break;
+ }
+
+ case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
+ NativeThreadLinuxSP main_thread_sp;
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received exec event, code = %d",
+ __FUNCTION__, info.si_code ^ SIGTRAP);
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
- }
+ // Exec clears any pending notifications.
+ m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
- case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)):
- {
- NativeThreadLinuxSP main_thread_sp;
+ // Remove all but the main thread here. Linux fork creates a new process
+ // which only copies the main thread.
+ if (log)
+ log->Printf("NativeProcessLinux::%s exec received, stop tracking all but "
+ "main thread",
+ __FUNCTION__);
+
+ for (auto thread_sp : m_threads) {
+ const bool is_main_thread = thread_sp && thread_sp->GetID() == GetID();
+ if (is_main_thread) {
+ main_thread_sp = std::static_pointer_cast<NativeThreadLinux>(thread_sp);
if (log)
- log->Printf ("NativeProcessLinux::%s() received exec event, code = %d", __FUNCTION__, info.si_code ^ SIGTRAP);
-
- // Exec clears any pending notifications.
- m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-
- // Remove all but the main thread here. Linux fork creates a new process which only copies the main thread.
+ log->Printf(
+ "NativeProcessLinux::%s found main thread with tid %" PRIu64
+ ", keeping",
+ __FUNCTION__, main_thread_sp->GetID());
+ } else {
if (log)
- log->Printf ("NativeProcessLinux::%s exec received, stop tracking all but main thread", __FUNCTION__);
-
- for (auto thread_sp : m_threads)
- {
- const bool is_main_thread = thread_sp && thread_sp->GetID () == GetID ();
- if (is_main_thread)
- {
- main_thread_sp = std::static_pointer_cast<NativeThreadLinux>(thread_sp);
- if (log)
- log->Printf ("NativeProcessLinux::%s found main thread with tid %" PRIu64 ", keeping", __FUNCTION__, main_thread_sp->GetID ());
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s discarding non-main-thread tid %" PRIu64 " due to exec", __FUNCTION__, thread_sp->GetID ());
- }
- }
-
- m_threads.clear ();
-
- if (main_thread_sp)
- {
- m_threads.push_back (main_thread_sp);
- SetCurrentThreadID (main_thread_sp->GetID ());
- main_thread_sp->SetStoppedByExec();
- }
- else
- {
- SetCurrentThreadID (LLDB_INVALID_THREAD_ID);
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 "no main thread found, discarded all threads, we're in a no-thread state!", __FUNCTION__, GetID ());
- }
-
- // Tell coordinator about about the "new" (since exec) stopped main thread.
- ThreadWasCreated(*main_thread_sp);
-
- // Let our delegate know we have just exec'd.
- NotifyDidExec ();
-
- // If we have a main thread, indicate we are stopped.
- assert (main_thread_sp && "exec called during ptraced process but no main thread metadata tracked");
-
- // Let the process know we're stopped.
- StopRunningThreads(main_thread_sp->GetID());
-
- break;
+ log->Printf(
+ "NativeProcessLinux::%s discarding non-main-thread tid %" PRIu64
+ " due to exec",
+ __FUNCTION__, thread_sp->GetID());
+ }
}
- case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
- {
- // The inferior process or one of its threads is about to exit.
- // We don't want to do anything with the thread so we just resume it. In case we
- // want to implement "break on thread exit" functionality, we would need to stop
- // here.
-
- unsigned long data = 0;
- if (GetEventMessage(thread.GetID(), &data).Fail())
- data = -1;
-
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s() received PTRACE_EVENT_EXIT, data = %lx (WIFEXITED=%s,WIFSIGNALED=%s), pid = %" PRIu64 " (%s)",
- __FUNCTION__,
- data, WIFEXITED (data) ? "true" : "false", WIFSIGNALED (data) ? "true" : "false",
- thread.GetID(),
- is_main_thread ? "is main thread" : "not main thread");
- }
+ m_threads.clear();
- if (is_main_thread)
- {
- SetExitStatus (convert_pid_status_to_exit_type (data), convert_pid_status_to_return_code (data), nullptr, true);
- }
-
- StateType state = thread.GetState();
- if (! StateIsRunningState(state))
- {
- // Due to a kernel bug, we may sometimes get this stop after the inferior gets a
- // SIGKILL. This confuses our state tracking logic in ResumeThread(), since normally,
- // we should not be receiving any ptrace events while the inferior is stopped. This
- // makes sure that the inferior is resumed and exits normally.
- state = eStateRunning;
- }
- ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
-
- break;
- }
-
- case 0:
- case TRAP_TRACE: // We receive this on single stepping.
- case TRAP_HWBKPT: // We receive this on watchpoint hit
- {
- // If a watchpoint was hit, report it
- uint32_t wp_index;
- Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(wp_index, (uintptr_t)info.si_addr);
- if (error.Fail() && log)
- log->Printf("NativeProcessLinux::%s() "
- "received error while checking for watchpoint hits, "
- "pid = %" PRIu64 " error = %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
- if (wp_index != LLDB_INVALID_INDEX32)
- {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
-
- // Otherwise, report step over
- MonitorTrace(thread);
- break;
- }
-
- case SI_KERNEL:
+ if (main_thread_sp) {
+ m_threads.push_back(main_thread_sp);
+ SetCurrentThreadID(main_thread_sp->GetID());
+ main_thread_sp->SetStoppedByExec();
+ } else {
+ SetCurrentThreadID(LLDB_INVALID_THREAD_ID);
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64
+ "no main thread found, discarded all threads, we're in a "
+ "no-thread state!",
+ __FUNCTION__, GetID());
+ }
+
+ // Tell coordinator about about the "new" (since exec) stopped main thread.
+ ThreadWasCreated(*main_thread_sp);
+
+ // Let our delegate know we have just exec'd.
+ NotifyDidExec();
+
+ // If we have a main thread, indicate we are stopped.
+ assert(main_thread_sp && "exec called during ptraced process but no main "
+ "thread metadata tracked");
+
+ // Let the process know we're stopped.
+ StopRunningThreads(main_thread_sp->GetID());
+
+ break;
+ }
+
+ case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)): {
+ // The inferior process or one of its threads is about to exit.
+ // We don't want to do anything with the thread so we just resume it. In
+ // case we
+ // want to implement "break on thread exit" functionality, we would need to
+ // stop
+ // here.
+
+ unsigned long data = 0;
+ if (GetEventMessage(thread.GetID(), &data).Fail())
+ data = -1;
+
+ if (log) {
+ log->Printf("NativeProcessLinux::%s() received PTRACE_EVENT_EXIT, data = "
+ "%lx (WIFEXITED=%s,WIFSIGNALED=%s), pid = %" PRIu64 " (%s)",
+ __FUNCTION__, data, WIFEXITED(data) ? "true" : "false",
+ WIFSIGNALED(data) ? "true" : "false", thread.GetID(),
+ is_main_thread ? "is main thread" : "not main thread");
+ }
+
+ if (is_main_thread) {
+ SetExitStatus(convert_pid_status_to_exit_type(data),
+ convert_pid_status_to_return_code(data), nullptr, true);
+ }
+
+ StateType state = thread.GetState();
+ if (!StateIsRunningState(state)) {
+ // Due to a kernel bug, we may sometimes get this stop after the inferior
+ // gets a
+ // SIGKILL. This confuses our state tracking logic in ResumeThread(),
+ // since normally,
+ // we should not be receiving any ptrace events while the inferior is
+ // stopped. This
+ // makes sure that the inferior is resumed and exits normally.
+ state = eStateRunning;
+ }
+ ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
+
+ break;
+ }
+
+ case 0:
+ case TRAP_TRACE: // We receive this on single stepping.
+ case TRAP_HWBKPT: // We receive this on watchpoint hit
+ {
+ // If a watchpoint was hit, report it
+ uint32_t wp_index;
+ Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ wp_index, (uintptr_t)info.si_addr);
+ if (error.Fail() && log)
+ log->Printf("NativeProcessLinux::%s() "
+ "received error while checking for watchpoint hits, "
+ "pid = %" PRIu64 " error = %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
+ if (wp_index != LLDB_INVALID_INDEX32) {
+ MonitorWatchpoint(thread, wp_index);
+ break;
+ }
+
+ // Otherwise, report step over
+ MonitorTrace(thread);
+ break;
+ }
+
+ case SI_KERNEL:
#if defined __mips__
- // For mips there is no special signal for watchpoint
- // So we check for watchpoint in kernel trap
- {
- // If a watchpoint was hit, report it
- uint32_t wp_index;
- Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(wp_index, LLDB_INVALID_ADDRESS);
- if (error.Fail() && log)
- log->Printf("NativeProcessLinux::%s() "
- "received error while checking for watchpoint hits, "
- "pid = %" PRIu64 " error = %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
- if (wp_index != LLDB_INVALID_INDEX32)
- {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
+ // For mips there is no special signal for watchpoint
+ // So we check for watchpoint in kernel trap
+ {
+ // If a watchpoint was hit, report it
+ uint32_t wp_index;
+ Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ wp_index, LLDB_INVALID_ADDRESS);
+ if (error.Fail() && log)
+ log->Printf("NativeProcessLinux::%s() "
+ "received error while checking for watchpoint hits, "
+ "pid = %" PRIu64 " error = %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
+ if (wp_index != LLDB_INVALID_INDEX32) {
+ MonitorWatchpoint(thread, wp_index);
+ break;
+ }
}
- // NO BREAK
+// NO BREAK
#endif
- case TRAP_BRKPT:
- MonitorBreakpoint(thread);
- break;
+ case TRAP_BRKPT:
+ MonitorBreakpoint(thread);
+ break;
- case SIGTRAP:
- case (SIGTRAP | 0x80):
- if (log)
- log->Printf ("NativeProcessLinux::%s() received unknown SIGTRAP system call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming", __FUNCTION__, GetID (), thread.GetID());
+ case SIGTRAP:
+ case (SIGTRAP | 0x80):
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received unknown SIGTRAP system "
+ "call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming",
+ __FUNCTION__, GetID(), thread.GetID());
- // Ignore these signals until we know more about them.
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
+ // Ignore these signals until we know more about them.
+ ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+ break;
- default:
- assert(false && "Unexpected SIGTRAP code!");
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 "tid %" PRIu64 " received unhandled SIGTRAP code: 0x%d",
- __FUNCTION__, GetID(), thread.GetID(), info.si_code);
- break;
-
- }
-}
-
-void
-NativeProcessLinux::MonitorTrace(NativeThreadLinux &thread)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ default:
+ assert(false && "Unexpected SIGTRAP code!");
if (log)
- log->Printf("NativeProcessLinux::%s() received trace event, pid = %" PRIu64 " (single stepping)",
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64 "tid %" PRIu64
+ " received unhandled SIGTRAP code: 0x%d",
+ __FUNCTION__, GetID(), thread.GetID(), info.si_code);
+ break;
+ }
+}
+
+void NativeProcessLinux::MonitorTrace(NativeThreadLinux &thread) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received trace event, pid = %" PRIu64
+ " (single stepping)",
__FUNCTION__, thread.GetID());
- // This thread is currently stopped.
- thread.SetStoppedByTrace();
+ // This thread is currently stopped.
+ thread.SetStoppedByTrace();
- StopRunningThreads(thread.GetID());
+ StopRunningThreads(thread.GetID());
}
-void
-NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64,
- __FUNCTION__, thread.GetID());
+void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64,
+ __FUNCTION__, thread.GetID());
- // Mark the thread as stopped at breakpoint.
- thread.SetStoppedByBreakpoint();
- Error error = FixupBreakpointPCAsNeeded(thread);
- if (error.Fail())
- if (log)
- log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
+ // Mark the thread as stopped at breakpoint.
+ thread.SetStoppedByBreakpoint();
+ Error error = FixupBreakpointPCAsNeeded(thread);
+ if (error.Fail())
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
- if (m_threads_stepping_with_breakpoint.find(thread.GetID()) != m_threads_stepping_with_breakpoint.end())
- thread.SetStoppedByTrace();
+ if (m_threads_stepping_with_breakpoint.find(thread.GetID()) !=
+ m_threads_stepping_with_breakpoint.end())
+ thread.SetStoppedByTrace();
- StopRunningThreads(thread.GetID());
+ StopRunningThreads(thread.GetID());
}
-void
-NativeProcessLinux::MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("NativeProcessLinux::%s() received watchpoint event, "
- "pid = %" PRIu64 ", wp_index = %" PRIu32,
- __FUNCTION__, thread.GetID(), wp_index);
+void NativeProcessLinux::MonitorWatchpoint(NativeThreadLinux &thread,
+ uint32_t wp_index) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received watchpoint event, "
+ "pid = %" PRIu64 ", wp_index = %" PRIu32,
+ __FUNCTION__, thread.GetID(), wp_index);
- // Mark the thread as stopped at watchpoint.
- // The address is at (lldb::addr_t)info->si_addr if we need it.
- thread.SetStoppedByWatchpoint(wp_index);
+ // Mark the thread as stopped at watchpoint.
+ // The address is at (lldb::addr_t)info->si_addr if we need it.
+ thread.SetStoppedByWatchpoint(wp_index);
- // We need to tell all other running threads before we notify the delegate about this stop.
- StopRunningThreads(thread.GetID());
+ // We need to tell all other running threads before we notify the delegate
+ // about this stop.
+ StopRunningThreads(thread.GetID());
}
-void
-NativeProcessLinux::MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited)
-{
- const int signo = info.si_signo;
- const bool is_from_llgs = info.si_pid == getpid ();
-
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
- // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
- // kill(2) or raise(3). Similarly for tgkill(2) on Linux.
- //
- // IOW, user generated signals never generate what we consider to be a
- // "crash".
- //
- // Similarly, ACK signals generated by this monitor.
-
- // Handle the signal.
- if (info.si_code == SI_TKILL || info.si_code == SI_USER)
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() received signal %s (%d) with code %s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")",
- __FUNCTION__,
- Host::GetSignalAsCString(signo),
- signo,
- (info.si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
- info.si_pid,
- is_from_llgs ? "from llgs" : "not from llgs",
- thread.GetID());
- }
+void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
+ NativeThreadLinux &thread, bool exited) {
+ const int signo = info.si_signo;
+ const bool is_from_llgs = info.si_pid == getpid();
- // Check for thread stop notification.
- if (is_from_llgs && (info.si_code == SI_TKILL) && (signo == SIGSTOP))
- {
- // This is a tgkill()-based stop.
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread stopped",
- __FUNCTION__,
- GetID (),
- thread.GetID());
-
- // Check that we're not already marked with a stop reason.
- // Note this thread really shouldn't already be marked as stopped - if we were, that would imply that
- // the kernel signaled us with the thread stopping which we handled and marked as stopped,
- // and that, without an intervening resume, we received another stop. It is more likely
- // that we are missing the marking of a run state somewhere if we find that the thread was
- // marked as stopped.
- const StateType thread_state = thread.GetState();
- if (!StateIsStoppedState (thread_state, false))
- {
- // An inferior thread has stopped because of a SIGSTOP we have sent it.
- // Generally, these are not important stops and we don't want to report them as
- // they are just used to stop other threads when one thread (the one with the
- // *real* stop reason) hits a breakpoint (watchpoint, etc...). However, in the
- // case of an asynchronous Interrupt(), this *is* the real stop reason, so we
- // leave the signal intact if this is the thread that was chosen as the
- // triggering thread.
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID)
- {
- if (m_pending_notification_tid == thread.GetID())
- thread.SetStoppedBySignal(SIGSTOP, &info);
- else
- thread.SetStoppedWithNoReason();
-
- SetCurrentThreadID (thread.GetID ());
- SignalIfAllThreadsStopped();
- }
- else
- {
- // We can end up here if stop was initiated by LLGS but by this time a
- // thread stop has occurred - maybe initiated by another event.
- Error error = ResumeThread(thread, thread.GetState(), 0);
- if (error.Fail() && log)
- {
- log->Printf("NativeProcessLinux::%s failed to resume thread tid %" PRIu64 ": %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
- }
- }
- }
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
+ // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
+ // kill(2) or raise(3). Similarly for tgkill(2) on Linux.
+ //
+ // IOW, user generated signals never generate what we consider to be a
+ // "crash".
+ //
+ // Similarly, ACK signals generated by this monitor.
+
+ // Handle the signal.
+ if (info.si_code == SI_TKILL || info.si_code == SI_USER) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received signal %s (%d) with code "
+ "%s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")",
+ __FUNCTION__, Host::GetSignalAsCString(signo), signo,
+ (info.si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
+ info.si_pid, is_from_llgs ? "from llgs" : "not from llgs",
+ thread.GetID());
+ }
+
+ // Check for thread stop notification.
+ if (is_from_llgs && (info.si_code == SI_TKILL) && (signo == SIGSTOP)) {
+ // This is a tgkill()-based stop.
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64
+ ", thread stopped",
+ __FUNCTION__, GetID(), thread.GetID());
+
+ // Check that we're not already marked with a stop reason.
+ // Note this thread really shouldn't already be marked as stopped - if we
+ // were, that would imply that
+ // the kernel signaled us with the thread stopping which we handled and
+ // marked as stopped,
+ // and that, without an intervening resume, we received another stop. It is
+ // more likely
+ // that we are missing the marking of a run state somewhere if we find that
+ // the thread was
+ // marked as stopped.
+ const StateType thread_state = thread.GetState();
+ if (!StateIsStoppedState(thread_state, false)) {
+ // An inferior thread has stopped because of a SIGSTOP we have sent it.
+ // Generally, these are not important stops and we don't want to report
+ // them as
+ // they are just used to stop other threads when one thread (the one with
+ // the
+ // *real* stop reason) hits a breakpoint (watchpoint, etc...). However, in
+ // the
+ // case of an asynchronous Interrupt(), this *is* the real stop reason, so
+ // we
+ // leave the signal intact if this is the thread that was chosen as the
+ // triggering thread.
+ if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID) {
+ if (m_pending_notification_tid == thread.GetID())
+ thread.SetStoppedBySignal(SIGSTOP, &info);
else
- {
- if (log)
- {
- // Retrieve the signal name if the thread was stopped by a signal.
- int stop_signo = 0;
- const bool stopped_by_signal = thread.IsStopped(&stop_signo);
- const char *signal_name = stopped_by_signal ? Host::GetSignalAsCString(stop_signo) : "<not stopped by signal>";
- if (!signal_name)
- signal_name = "<no-signal-name>";
-
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread was already marked as a stopped state (state=%s, signal=%d (%s)), leaving stop signal as is",
- __FUNCTION__,
- GetID (),
- thread.GetID(),
- StateAsCString (thread_state),
- stop_signo,
- signal_name);
- }
- SignalIfAllThreadsStopped();
+ thread.SetStoppedWithNoReason();
+
+ SetCurrentThreadID(thread.GetID());
+ SignalIfAllThreadsStopped();
+ } else {
+ // We can end up here if stop was initiated by LLGS but by this time a
+ // thread stop has occurred - maybe initiated by another event.
+ Error error = ResumeThread(thread, thread.GetState(), 0);
+ if (error.Fail() && log) {
+ log->Printf(
+ "NativeProcessLinux::%s failed to resume thread tid %" PRIu64
+ ": %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
}
+ }
+ } else {
+ if (log) {
+ // Retrieve the signal name if the thread was stopped by a signal.
+ int stop_signo = 0;
+ const bool stopped_by_signal = thread.IsStopped(&stop_signo);
+ const char *signal_name = stopped_by_signal
+ ? Host::GetSignalAsCString(stop_signo)
+ : "<not stopped by signal>";
+ if (!signal_name)
+ signal_name = "<no-signal-name>";
- // Done handling.
- return;
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64
+ ", thread was already marked as a stopped state (state=%s, "
+ "signal=%d (%s)), leaving stop signal as is",
+ __FUNCTION__, GetID(), thread.GetID(),
+ StateAsCString(thread_state), stop_signo, signal_name);
+ }
+ SignalIfAllThreadsStopped();
}
- if (log)
- log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, Host::GetSignalAsCString(signo));
+ // Done handling.
+ return;
+ }
- // This thread is stopped.
- thread.SetStoppedBySignal(signo, &info);
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received signal %s", __FUNCTION__,
+ Host::GetSignalAsCString(signo));
- // Send a stop to the debugger after we get all other threads to stop.
- StopRunningThreads(thread.GetID());
+ // This thread is stopped.
+ thread.SetStoppedBySignal(signo, &info);
+
+ // Send a stop to the debugger after we get all other threads to stop.
+ StopRunningThreads(thread.GetID());
}
namespace {
-struct EmulatorBaton
-{
- NativeProcessLinux* m_process;
- NativeRegisterContext* m_reg_context;
+struct EmulatorBaton {
+ NativeProcessLinux *m_process;
+ NativeRegisterContext *m_reg_context;
- // eRegisterKindDWARF -> RegsiterValue
- std::unordered_map<uint32_t, RegisterValue> m_register_values;
+ // eRegisterKindDWARF -> RegsiterValue
+ std::unordered_map<uint32_t, RegisterValue> m_register_values;
- EmulatorBaton(NativeProcessLinux* process, NativeRegisterContext* reg_context) :
- m_process(process), m_reg_context(reg_context) {}
+ EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
+ : m_process(process), m_reg_context(reg_context) {}
};
} // anonymous namespace
-static size_t
-ReadMemoryCallback (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- size_t bytes_read;
- emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
- return bytes_read;
+ size_t bytes_read;
+ emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
+ return bytes_read;
}
-static bool
-ReadRegisterCallback (EmulateInstruction *instruction,
- void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
-
- auto it = emulator_baton->m_register_values.find(reg_info->kinds[eRegisterKindDWARF]);
- if (it != emulator_baton->m_register_values.end())
- {
- reg_value = it->second;
- return true;
- }
+static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- // The emulator only fill in the dwarf regsiter numbers (and in some case
- // the generic register numbers). Get the full register info from the
- // register context based on the dwarf register numbers.
- const RegisterInfo* full_reg_info = emulator_baton->m_reg_context->GetRegisterInfo(
- eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
-
- Error error = emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
+ auto it = emulator_baton->m_register_values.find(
+ reg_info->kinds[eRegisterKindDWARF]);
+ if (it != emulator_baton->m_register_values.end()) {
+ reg_value = it->second;
+ return true;
+ }
+
+ // The emulator only fill in the dwarf regsiter numbers (and in some case
+ // the generic register numbers). Get the full register info from the
+ // register context based on the dwarf register numbers.
+ const RegisterInfo *full_reg_info =
+ emulator_baton->m_reg_context->GetRegisterInfo(
+ eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
+
+ Error error =
+ emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
+ if (error.Success())
+ return true;
- return false;
+ return false;
}
-static bool
-WriteRegisterCallback (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
- emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] = reg_value;
- return true;
+static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
+ reg_value;
+ return true;
}
-static size_t
-WriteMemoryCallback (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length)
-{
- return length;
+static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst,
+ size_t length) {
+ return length;
}
-static lldb::addr_t
-ReadFlags (NativeRegisterContext* regsiter_context)
-{
- const RegisterInfo* flags_info = regsiter_context->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- return regsiter_context->ReadRegisterAsUnsigned(flags_info, LLDB_INVALID_ADDRESS);
+static lldb::addr_t ReadFlags(NativeRegisterContext *regsiter_context) {
+ const RegisterInfo *flags_info = regsiter_context->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ return regsiter_context->ReadRegisterAsUnsigned(flags_info,
+ LLDB_INVALID_ADDRESS);
}
-Error
-NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread)
-{
- Error error;
- NativeRegisterContextSP register_context_sp = thread.GetRegisterContext();
+Error NativeProcessLinux::SetupSoftwareSingleStepping(
+ NativeThreadLinux &thread) {
+ Error error;
+ NativeRegisterContextSP register_context_sp = thread.GetRegisterContext();
- std::unique_ptr<EmulateInstruction> emulator_ap(
- EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying, nullptr));
+ std::unique_ptr<EmulateInstruction> emulator_ap(
+ EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying,
+ nullptr));
- if (emulator_ap == nullptr)
- return Error("Instruction emulator not found!");
+ if (emulator_ap == nullptr)
+ return Error("Instruction emulator not found!");
- EmulatorBaton baton(this, register_context_sp.get());
- emulator_ap->SetBaton(&baton);
- emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
- emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
- emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
- emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
+ EmulatorBaton baton(this, register_context_sp.get());
+ emulator_ap->SetBaton(&baton);
+ emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
+ emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
+ emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
+ emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
- if (!emulator_ap->ReadInstruction())
- return Error("Read instruction failed!");
+ if (!emulator_ap->ReadInstruction())
+ return Error("Read instruction failed!");
- bool emulation_result = emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
+ bool emulation_result =
+ emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
- const RegisterInfo* reg_info_pc = register_context_sp->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo* reg_info_flags = register_context_sp->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *reg_info_flags = register_context_sp->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- auto pc_it = baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
- auto flags_it = baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
+ auto pc_it =
+ baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
+ auto flags_it =
+ baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
- lldb::addr_t next_pc;
- lldb::addr_t next_flags;
- if (emulation_result)
- {
- assert(pc_it != baton.m_register_values.end() && "Emulation was successfull but PC wasn't updated");
- next_pc = pc_it->second.GetAsUInt64();
+ lldb::addr_t next_pc;
+ lldb::addr_t next_flags;
+ if (emulation_result) {
+ assert(pc_it != baton.m_register_values.end() &&
+ "Emulation was successfull but PC wasn't updated");
+ next_pc = pc_it->second.GetAsUInt64();
- if (flags_it != baton.m_register_values.end())
- next_flags = flags_it->second.GetAsUInt64();
- else
- next_flags = ReadFlags (register_context_sp.get());
- }
- else if (pc_it == baton.m_register_values.end())
- {
- // Emulate instruction failed and it haven't changed PC. Advance PC
- // with the size of the current opcode because the emulation of all
- // PC modifying instruction should be successful. The failure most
- // likely caused by a not supported instruction which don't modify PC.
- next_pc = register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
- next_flags = ReadFlags (register_context_sp.get());
- }
+ if (flags_it != baton.m_register_values.end())
+ next_flags = flags_it->second.GetAsUInt64();
else
- {
- // The instruction emulation failed after it modified the PC. It is an
- // unknown error where we can't continue because the next instruction is
- // modifying the PC but we don't know how.
- return Error ("Instruction emulation failed unexpectedly.");
- }
-
- if (m_arch.GetMachine() == llvm::Triple::arm)
- {
- if (next_flags & 0x20)
- {
- // Thumb mode
- error = SetSoftwareBreakpoint(next_pc, 2);
- }
- else
- {
- // Arm mode
- error = SetSoftwareBreakpoint(next_pc, 4);
- }
- }
- else if (m_arch.GetMachine() == llvm::Triple::mips64
- || m_arch.GetMachine() == llvm::Triple::mips64el
- || m_arch.GetMachine() == llvm::Triple::mips
- || m_arch.GetMachine() == llvm::Triple::mipsel)
- error = SetSoftwareBreakpoint(next_pc, 4);
- else
- {
- // No size hint is given for the next breakpoint
- error = SetSoftwareBreakpoint(next_pc, 0);
- }
-
- if (error.Fail())
- return error;
+ next_flags = ReadFlags(register_context_sp.get());
+ } else if (pc_it == baton.m_register_values.end()) {
+ // Emulate instruction failed and it haven't changed PC. Advance PC
+ // with the size of the current opcode because the emulation of all
+ // PC modifying instruction should be successful. The failure most
+ // likely caused by a not supported instruction which don't modify PC.
+ next_pc =
+ register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
+ next_flags = ReadFlags(register_context_sp.get());
+ } else {
+ // The instruction emulation failed after it modified the PC. It is an
+ // unknown error where we can't continue because the next instruction is
+ // modifying the PC but we don't know how.
+ return Error("Instruction emulation failed unexpectedly.");
+ }
+
+ if (m_arch.GetMachine() == llvm::Triple::arm) {
+ if (next_flags & 0x20) {
+ // Thumb mode
+ error = SetSoftwareBreakpoint(next_pc, 2);
+ } else {
+ // Arm mode
+ error = SetSoftwareBreakpoint(next_pc, 4);
+ }
+ } else if (m_arch.GetMachine() == llvm::Triple::mips64 ||
+ m_arch.GetMachine() == llvm::Triple::mips64el ||
+ m_arch.GetMachine() == llvm::Triple::mips ||
+ m_arch.GetMachine() == llvm::Triple::mipsel)
+ error = SetSoftwareBreakpoint(next_pc, 4);
+ else {
+ // No size hint is given for the next breakpoint
+ error = SetSoftwareBreakpoint(next_pc, 0);
+ }
+
+ // If setting the breakpoint fails because next_pc is out of
+ // the address space, ignore it and let the debugee segfault.
+ if (error.GetError() == EIO || error.GetError() == EFAULT) {
+ return Error();
+ } else if (error.Fail())
+ return error;
- m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
+ m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
- return Error();
+ return Error();
}
-bool
-NativeProcessLinux::SupportHardwareSingleStepping() const
-{
- if (m_arch.GetMachine() == llvm::Triple::arm
- || m_arch.GetMachine() == llvm::Triple::mips64 || m_arch.GetMachine() == llvm::Triple::mips64el
- || m_arch.GetMachine() == llvm::Triple::mips || m_arch.GetMachine() == llvm::Triple::mipsel)
- return false;
- return true;
+bool NativeProcessLinux::SupportHardwareSingleStepping() const {
+ if (m_arch.GetMachine() == llvm::Triple::arm ||
+ m_arch.GetMachine() == llvm::Triple::mips64 ||
+ m_arch.GetMachine() == llvm::Triple::mips64el ||
+ m_arch.GetMachine() == llvm::Triple::mips ||
+ m_arch.GetMachine() == llvm::Triple::mipsel)
+ return false;
+ return true;
}
-Error
-NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__, GetID ());
+Error NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__,
+ GetID());
- bool software_single_step = !SupportHardwareSingleStepping();
+ bool software_single_step = !SupportHardwareSingleStepping();
- if (software_single_step)
- {
- for (auto thread_sp : m_threads)
- {
- assert (thread_sp && "thread list should not contain NULL threads");
-
- const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true);
- if (action == nullptr)
- continue;
-
- if (action->state == eStateStepping)
- {
- Error error = SetupSoftwareSingleStepping(static_cast<NativeThreadLinux &>(*thread_sp));
- if (error.Fail())
- return error;
- }
- }
+ if (software_single_step) {
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not contain NULL threads");
+
+ const ResumeAction *const action =
+ resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ if (action == nullptr)
+ continue;
+
+ if (action->state == eStateStepping) {
+ Error error = SetupSoftwareSingleStepping(
+ static_cast<NativeThreadLinux &>(*thread_sp));
+ if (error.Fail())
+ return error;
+ }
}
+ }
- for (auto thread_sp : m_threads)
- {
- assert (thread_sp && "thread list should not contain NULL threads");
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not contain NULL threads");
- const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true);
+ const ResumeAction *const action =
+ resume_actions.GetActionForThread(thread_sp->GetID(), true);
- if (action == nullptr)
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s no action specified for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, GetID (), thread_sp->GetID ());
- continue;
- }
+ if (action == nullptr) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s no action specified for pid %" PRIu64
+ " tid %" PRIu64,
+ __FUNCTION__, GetID(), thread_sp->GetID());
+ continue;
+ }
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s processing resume action state %s for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
- }
+ if (log) {
+ log->Printf("NativeProcessLinux::%s processing resume action state %s "
+ "for pid %" PRIu64 " tid %" PRIu64,
+ __FUNCTION__, StateAsCString(action->state), GetID(),
+ thread_sp->GetID());
+ }
- switch (action->state)
- {
- case eStateRunning:
- case eStateStepping:
- {
- // Run the thread, possibly feeding it the signal.
- const int signo = action->signal;
- ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state, signo);
- break;
- }
+ switch (action->state) {
+ case eStateRunning:
+ case eStateStepping: {
+ // Run the thread, possibly feeding it the signal.
+ const int signo = action->signal;
+ ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state,
+ signo);
+ break;
+ }
- case eStateSuspended:
- case eStateStopped:
- lldbassert(0 && "Unexpected state");
+ case eStateSuspended:
+ case eStateStopped:
+ lldbassert(0 && "Unexpected state");
- default:
- return Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64,
- __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
- }
+ default:
+ return Error("NativeProcessLinux::%s (): unexpected state %s specified "
+ "for pid %" PRIu64 ", tid %" PRIu64,
+ __FUNCTION__, StateAsCString(action->state), GetID(),
+ thread_sp->GetID());
}
+ }
- return Error();
+ return Error();
}
-Error
-NativeProcessLinux::Halt ()
-{
- Error error;
+Error NativeProcessLinux::Halt() {
+ Error error;
- if (kill (GetID (), SIGSTOP) != 0)
- error.SetErrorToErrno ();
+ if (kill(GetID(), SIGSTOP) != 0)
+ error.SetErrorToErrno();
- return error;
+ return error;
}
-Error
-NativeProcessLinux::Detach ()
-{
- Error error;
+Error NativeProcessLinux::Detach() {
+ Error error;
- // Stop monitoring the inferior.
- m_sigchld_handle.reset();
+ // Stop monitoring the inferior.
+ m_sigchld_handle.reset();
- // Tell ptrace to detach from the process.
- if (GetID () == LLDB_INVALID_PROCESS_ID)
- return error;
+ // Tell ptrace to detach from the process.
+ if (GetID() == LLDB_INVALID_PROCESS_ID)
+ return error;
- for (auto thread_sp : m_threads)
- {
- Error e = Detach(thread_sp->GetID());
- if (e.Fail())
- error = e; // Save the error, but still attempt to detach from other threads.
- }
+ for (auto thread_sp : m_threads) {
+ Error e = Detach(thread_sp->GetID());
+ if (e.Fail())
+ error =
+ e; // Save the error, but still attempt to detach from other threads.
+ }
- return error;
+ return error;
}
-Error
-NativeProcessLinux::Signal (int signo)
-{
- Error error;
+Error NativeProcessLinux::Signal(int signo) {
+ Error error;
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64,
- __FUNCTION__, signo, Host::GetSignalAsCString(signo), GetID());
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64,
+ __FUNCTION__, signo, Host::GetSignalAsCString(signo), GetID());
- if (kill(GetID(), signo))
- error.SetErrorToErrno();
+ if (kill(GetID(), signo))
+ error.SetErrorToErrno();
- return error;
+ return error;
}
-Error
-NativeProcessLinux::Interrupt ()
-{
- // Pick a running thread (or if none, a not-dead stopped thread) as
- // the chosen thread that will be the stop-reason thread.
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+Error NativeProcessLinux::Interrupt() {
+ // Pick a running thread (or if none, a not-dead stopped thread) as
+ // the chosen thread that will be the stop-reason thread.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- NativeThreadProtocolSP running_thread_sp;
- NativeThreadProtocolSP stopped_thread_sp;
-
- if (log)
- log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__);
+ NativeThreadProtocolSP running_thread_sp;
+ NativeThreadProtocolSP stopped_thread_sp;
- for (auto thread_sp : m_threads)
- {
- // The thread shouldn't be null but lets just cover that here.
- if (!thread_sp)
- continue;
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s selecting running thread for interrupt target",
+ __FUNCTION__);
- // If we have a running or stepping thread, we'll call that the
- // target of the interrupt.
- const auto thread_state = thread_sp->GetState ();
- if (thread_state == eStateRunning ||
- thread_state == eStateStepping)
- {
- running_thread_sp = thread_sp;
- break;
- }
- else if (!stopped_thread_sp && StateIsStoppedState (thread_state, true))
- {
- // Remember the first non-dead stopped thread. We'll use that as a backup if there are no running threads.
- stopped_thread_sp = thread_sp;
- }
- }
+ for (auto thread_sp : m_threads) {
+ // The thread shouldn't be null but lets just cover that here.
+ if (!thread_sp)
+ continue;
- if (!running_thread_sp && !stopped_thread_sp)
- {
- Error error("found no running/stepping or live stopped threads as target for interrupt");
- if (log)
- log->Printf ("NativeProcessLinux::%s skipping due to error: %s", __FUNCTION__, error.AsCString ());
-
- return error;
+ // If we have a running or stepping thread, we'll call that the
+ // target of the interrupt.
+ const auto thread_state = thread_sp->GetState();
+ if (thread_state == eStateRunning || thread_state == eStateStepping) {
+ running_thread_sp = thread_sp;
+ break;
+ } else if (!stopped_thread_sp && StateIsStoppedState(thread_state, true)) {
+ // Remember the first non-dead stopped thread. We'll use that as a backup
+ // if there are no running threads.
+ stopped_thread_sp = thread_sp;
}
+ }
- NativeThreadProtocolSP deferred_signal_thread_sp = running_thread_sp ? running_thread_sp : stopped_thread_sp;
-
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " %s tid %" PRIu64 " chosen for interrupt target",
- __FUNCTION__,
- GetID (),
- running_thread_sp ? "running" : "stopped",
- deferred_signal_thread_sp->GetID ());
-
- StopRunningThreads(deferred_signal_thread_sp->GetID());
-
- return Error();
-}
-
-Error
-NativeProcessLinux::Kill ()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (!running_thread_sp && !stopped_thread_sp) {
+ Error error("found no running/stepping or live stopped threads as target "
+ "for interrupt");
if (log)
- log->Printf ("NativeProcessLinux::%s called for PID %" PRIu64, __FUNCTION__, GetID ());
-
- Error error;
-
- switch (m_state)
- {
- case StateType::eStateInvalid:
- case StateType::eStateExited:
- case StateType::eStateCrashed:
- case StateType::eStateDetached:
- case StateType::eStateUnloaded:
- // Nothing to do - the process is already dead.
- if (log)
- log->Printf ("NativeProcessLinux::%s ignored for PID %" PRIu64 " due to current state: %s", __FUNCTION__, GetID (), StateAsCString (m_state));
- return error;
-
- case StateType::eStateConnected:
- case StateType::eStateAttaching:
- case StateType::eStateLaunching:
- case StateType::eStateStopped:
- case StateType::eStateRunning:
- case StateType::eStateStepping:
- case StateType::eStateSuspended:
- // We can try to kill a process in these states.
- break;
- }
-
- if (kill (GetID (), SIGKILL) != 0)
- {
- error.SetErrorToErrno ();
- return error;
- }
+ log->Printf("NativeProcessLinux::%s skipping due to error: %s",
+ __FUNCTION__, error.AsCString());
return error;
-}
+ }
-static Error
-ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegionInfo &memory_region_info)
-{
- memory_region_info.Clear();
-
- StringExtractor line_extractor (maps_line.c_str ());
+ NativeThreadProtocolSP deferred_signal_thread_sp =
+ running_thread_sp ? running_thread_sp : stopped_thread_sp;
- // 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).
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " %s tid %" PRIu64
+ " chosen for interrupt target",
+ __FUNCTION__, GetID(),
+ running_thread_sp ? "running" : "stopped",
+ deferred_signal_thread_sp->GetID());
- // Parse out the starting address
- lldb::addr_t start_address = line_extractor.GetHexMaxU64 (false, 0);
+ StopRunningThreads(deferred_signal_thread_sp->GetID());
- // Parse out hyphen separating start and end address from range.
- if (!line_extractor.GetBytesLeft () || (line_extractor.GetChar () != '-'))
- return Error ("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 Error ("malformed /proc/{pid}/maps entry, missing space after range");
+ return Error();
+}
- // Save the range.
- memory_region_info.GetRange ().SetRangeBase (start_address);
- memory_region_info.GetRange ().SetRangeEnd (end_address);
+Error NativeProcessLinux::Kill() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s called for PID %" PRIu64, __FUNCTION__,
+ GetID());
- // Any memory region in /proc/{pid}/maps is by definition mapped into the process.
- memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+ Error error;
- // Parse out each permission entry.
- if (line_extractor.GetBytesLeft () < 4)
- return Error ("malformed /proc/{pid}/maps entry, missing some portion of permissions");
+ switch (m_state) {
+ case StateType::eStateInvalid:
+ case StateType::eStateExited:
+ case StateType::eStateCrashed:
+ case StateType::eStateDetached:
+ case StateType::eStateUnloaded:
+ // Nothing to do - the process is already dead.
+ if (log)
+ log->Printf("NativeProcessLinux::%s ignored for PID %" PRIu64
+ " due to current state: %s",
+ __FUNCTION__, GetID(), StateAsCString(m_state));
+ return error;
- // 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 Error ("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 Error ("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 Error ("unexpected /proc/{pid}/maps exec permission char");
+ case StateType::eStateConnected:
+ case StateType::eStateAttaching:
+ case StateType::eStateLaunching:
+ case StateType::eStateStopped:
+ case StateType::eStateRunning:
+ case StateType::eStateStepping:
+ case StateType::eStateSuspended:
+ // We can try to kill a process in these states.
+ break;
+ }
+
+ if (kill(GetID(), SIGKILL) != 0) {
+ error.SetErrorToErrno();
+ return error;
+ }
- return Error ();
+ return error;
}
-Error
-NativeProcessLinux::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info)
-{
- // FIXME review that the final memory region returned extends to the end of the virtual address space,
- // with no perms if it is not mapped.
-
- // Use an approach that reads memory regions from /proc/{pid}/maps.
- // Assume proc maps entries are in ascending order.
- // FIXME assert if we find differently.
-
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- Error error;
-
- if (m_supports_mem_region == LazyBool::eLazyBoolNo)
- {
- // We're done.
- error.SetErrorString ("unsupported");
- return error;
- }
-
- // If our cache is empty, pull the latest. There should always be at least one memory region
- // if memory region handling is supported.
- if (m_mem_region_cache.empty ())
- {
- error = ProcFileReader::ProcessLineByLine (GetID (), "maps",
- [&] (const std::string &line) -> bool
- {
- MemoryRegionInfo info;
- const Error parse_error = ParseMemoryRegionInfoFromProcMapsLine (line, info);
- if (parse_error.Success ())
- {
- m_mem_region_cache.push_back (info);
- return true;
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s failed to parse proc maps line '%s': %s", __FUNCTION__, line.c_str (), error.AsCString ());
- return false;
- }
- });
-
- // If we had an error, we'll mark unsupported.
- if (error.Fail ())
- {
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- return error;
- }
- else if (m_mem_region_cache.empty ())
- {
- // No entries after attempting to read them. This shouldn't happen if /proc/{pid}/maps
- // is supported. Assume we don't support map entries via procfs.
+static Error
+ParseMemoryRegionInfoFromProcMapsLine(const std::string &maps_line,
+ MemoryRegionInfo &memory_region_info) {
+ memory_region_info.Clear();
+
+ StringExtractor line_extractor(maps_line.c_str());
+
+ // 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 Error(
+ "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 Error("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 Error("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 Error("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 Error("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 Error("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 Error();
+}
+
+Error NativeProcessLinux::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ // FIXME review that the final memory region returned extends to the end of
+ // the virtual address space,
+ // with no perms if it is not mapped.
+
+ // Use an approach that reads memory regions from /proc/{pid}/maps.
+ // Assume proc maps entries are in ascending order.
+ // FIXME assert if we find differently.
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Error error;
+
+ if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
+ // We're done.
+ error.SetErrorString("unsupported");
+ return error;
+ }
+
+ // If our cache is empty, pull the latest. There should always be at least
+ // one memory region
+ // if memory region handling is supported.
+ if (m_mem_region_cache.empty()) {
+ error = ProcFileReader::ProcessLineByLine(
+ GetID(), "maps", [&](const std::string &line) -> bool {
+ MemoryRegionInfo info;
+ const Error parse_error =
+ ParseMemoryRegionInfoFromProcMapsLine(line, info);
+ if (parse_error.Success()) {
+ m_mem_region_cache.push_back(info);
+ return true;
+ } else {
if (log)
- log->Printf ("NativeProcessLinux::%s failed to find any procfs maps entries, assuming no support for memory region metadata retrieval", __FUNCTION__);
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- error.SetErrorString ("not supported");
- return error;
- }
-
- if (log)
- log->Printf ("NativeProcessLinux::%s read %" PRIu64 " memory region entries from /proc/%" PRIu64 "/maps", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()), GetID ());
-
- // We support memory retrieval, remember that.
- m_supports_mem_region = LazyBool::eLazyBoolYes;
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s reusing %" PRIu64 " cached memory region entries", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()));
- }
-
- lldb::addr_t prev_base_address = 0;
-
- // FIXME start by finding the last region that is <= target address using binary search. Data is sorted.
- // There can be a ton of regions on pthreads apps with lots of threads.
- for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end (); ++it)
- {
- MemoryRegionInfo &proc_entry_info = *it;
-
- // Sanity check assumption that /proc/{pid}/maps entries are ascending.
- assert ((proc_entry_info.GetRange ().GetRangeBase () >= prev_base_address) && "descending /proc/pid/maps entries detected, unexpected");
- prev_base_address = proc_entry_info.GetRange ().GetRangeBase ();
-
- // If the target address comes before this entry, indicate distance to next region.
- if (load_addr < proc_entry_info.GetRange ().GetRangeBase ())
- {
- range_info.GetRange ().SetRangeBase (load_addr);
- range_info.GetRange ().SetByteSize (proc_entry_info.GetRange ().GetRangeBase () - load_addr);
- range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
-
- return error;
- }
- else if (proc_entry_info.GetRange ().Contains (load_addr))
- {
- // The target address is within the memory region we're processing here.
- range_info = proc_entry_info;
- return error;
- }
+ log->Printf("NativeProcessLinux::%s failed to parse proc maps "
+ "line '%s': %s",
+ __FUNCTION__, line.c_str(), error.AsCString());
+ return false;
+ }
+ });
- // The target memory address comes somewhere after the region we just parsed.
+ // If we had an error, we'll mark unsupported.
+ if (error.Fail()) {
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ return error;
+ } else if (m_mem_region_cache.empty()) {
+ // No entries after attempting to read them. This shouldn't happen if
+ // /proc/{pid}/maps
+ // is supported. Assume we don't support map entries via procfs.
+ if (log)
+ log->Printf("NativeProcessLinux::%s failed to find any procfs maps "
+ "entries, assuming no support for memory region metadata "
+ "retrieval",
+ __FUNCTION__);
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ error.SetErrorString("not supported");
+ return error;
}
- // If we made it here, we didn't find an entry that contained the given address. Return the
- // load_addr as start and the amount of bytes betwwen load address and the end of the memory as
- // size.
- range_info.GetRange ().SetRangeBase (load_addr);
- range_info.GetRange ().SetRangeEnd(LLDB_INVALID_ADDRESS);
- range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
- return error;
-}
-
-void
-NativeProcessLinux::DoStopIDBumped (uint32_t newBumpId)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("NativeProcessLinux::%s(newBumpId=%" PRIu32 ") called", __FUNCTION__, newBumpId);
-
- if (log)
- log->Printf ("NativeProcessLinux::%s clearing %" PRIu64 " entries from the cache", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()));
- m_mem_region_cache.clear ();
-}
-
-Error
-NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr)
-{
- // FIXME implementing this requires the equivalent of
- // InferiorCallPOSIX::InferiorCallMmap, which depends on
- // functional ThreadPlans working with Native*Protocol.
+ log->Printf("NativeProcessLinux::%s read %" PRIu64
+ " memory region entries from /proc/%" PRIu64 "/maps",
+ __FUNCTION__,
+ static_cast<uint64_t>(m_mem_region_cache.size()), GetID());
+
+ // We support memory retrieval, remember that.
+ m_supports_mem_region = LazyBool::eLazyBoolYes;
+ } else {
+ if (log)
+ log->Printf("NativeProcessLinux::%s reusing %" PRIu64
+ " cached memory region entries",
+ __FUNCTION__,
+ static_cast<uint64_t>(m_mem_region_cache.size()));
+ }
+
+ lldb::addr_t prev_base_address = 0;
+
+ // FIXME start by finding the last region that is <= target address using
+ // binary search. Data is sorted.
+ // There can be a ton of regions on pthreads apps with lots of threads.
+ for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
+ ++it) {
+ MemoryRegionInfo &proc_entry_info = *it;
+
+ // Sanity check assumption that /proc/{pid}/maps entries are ascending.
+ assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
+ "descending /proc/pid/maps entries detected, unexpected");
+ prev_base_address = proc_entry_info.GetRange().GetRangeBase();
+
+ // If the target address comes before this entry, indicate distance to next
+ // region.
+ if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
+ range_info.GetRange().SetRangeBase(load_addr);
+ range_info.GetRange().SetByteSize(
+ proc_entry_info.GetRange().GetRangeBase() - load_addr);
+ range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
+
+ return error;
+ } else if (proc_entry_info.GetRange().Contains(load_addr)) {
+ // The target address is within the memory region we're processing here.
+ range_info = proc_entry_info;
+ return error;
+ }
+
+ // The target memory address comes somewhere after the region we just
+ // parsed.
+ }
+
+ // If we made it here, we didn't find an entry that contained the given
+ // address. Return the
+ // load_addr as start and the amount of bytes betwwen load address and the end
+ // of the memory as
+ // size.
+ range_info.GetRange().SetRangeBase(load_addr);
+ range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
+ return error;
+}
+
+void NativeProcessLinux::DoStopIDBumped(uint32_t newBumpId) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s(newBumpId=%" PRIu32 ") called",
+ __FUNCTION__, newBumpId);
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s clearing %" PRIu64
+ " entries from the cache",
+ __FUNCTION__, static_cast<uint64_t>(m_mem_region_cache.size()));
+ m_mem_region_cache.clear();
+}
+
+Error NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) {
+// FIXME implementing this requires the equivalent of
+// InferiorCallPOSIX::InferiorCallMmap, which depends on
+// functional ThreadPlans working with Native*Protocol.
#if 1
- return Error ("not implemented yet");
+ return Error("not implemented yet");
#else
+ addr = LLDB_INVALID_ADDRESS;
+
+ unsigned prot = 0;
+ if (permissions & lldb::ePermissionsReadable)
+ prot |= eMmapProtRead;
+ if (permissions & lldb::ePermissionsWritable)
+ prot |= eMmapProtWrite;
+ if (permissions & lldb::ePermissionsExecutable)
+ prot |= eMmapProtExec;
+
+ // TODO implement this directly in NativeProcessLinux
+ // (and lift to NativeProcessPOSIX if/when that class is
+ // refactored out).
+ if (InferiorCallMmap(this, addr, 0, size, prot,
+ eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
+ m_addr_to_mmap_size[addr] = size;
+ return Error();
+ } else {
addr = LLDB_INVALID_ADDRESS;
-
- unsigned prot = 0;
- if (permissions & lldb::ePermissionsReadable)
- prot |= eMmapProtRead;
- if (permissions & lldb::ePermissionsWritable)
- prot |= eMmapProtWrite;
- if (permissions & lldb::ePermissionsExecutable)
- prot |= eMmapProtExec;
-
- // TODO implement this directly in NativeProcessLinux
- // (and lift to NativeProcessPOSIX if/when that class is
- // refactored out).
- if (InferiorCallMmap(this, addr, 0, size, prot,
- eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
- m_addr_to_mmap_size[addr] = size;
- return Error ();
- } else {
- addr = LLDB_INVALID_ADDRESS;
- return Error("unable to allocate %" PRIu64 " bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
- }
+ return Error("unable to allocate %" PRIu64
+ " bytes of memory with permissions %s",
+ size, GetPermissionsAsCString(permissions));
+ }
#endif
}
-Error
-NativeProcessLinux::DeallocateMemory (lldb::addr_t addr)
-{
- // FIXME see comments in AllocateMemory - required lower-level
- // bits not in place yet (ThreadPlans)
- return Error ("not implemented");
+Error NativeProcessLinux::DeallocateMemory(lldb::addr_t addr) {
+ // FIXME see comments in AllocateMemory - required lower-level
+ // bits not in place yet (ThreadPlans)
+ return Error("not implemented");
}
-lldb::addr_t
-NativeProcessLinux::GetSharedLibraryInfoAddress ()
-{
- // punt on this for now
- return LLDB_INVALID_ADDRESS;
+lldb::addr_t NativeProcessLinux::GetSharedLibraryInfoAddress() {
+ // punt on this for now
+ return LLDB_INVALID_ADDRESS;
}
-size_t
-NativeProcessLinux::UpdateThreads ()
-{
- // The NativeProcessLinux monitoring threads are always up to date
- // with respect to thread state and they keep the thread list
- // populated properly. All this method needs to do is return the
- // thread count.
- return m_threads.size ();
+size_t NativeProcessLinux::UpdateThreads() {
+ // The NativeProcessLinux monitoring threads are always up to date
+ // with respect to thread state and they keep the thread list
+ // populated properly. All this method needs to do is return the
+ // thread count.
+ return m_threads.size();
}
-bool
-NativeProcessLinux::GetArchitecture (ArchSpec &arch) const
-{
- arch = m_arch;
- return true;
+bool NativeProcessLinux::GetArchitecture(ArchSpec &arch) const {
+ arch = m_arch;
+ return true;
}
-Error
-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 };
+Error 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 Error ();
-
- case llvm::Triple::systemz:
- actual_opcode_size = static_cast<uint32_t> (sizeof(g_s390x_opcode));
- return Error ();
-
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- // On these architectures the PC don't get updated for breakpoint hits
- actual_opcode_size = 0;
- return Error ();
-
- default:
- assert(false && "CPU type not supported!");
- return Error ("CPU type not supported");
- }
-}
+ 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 Error();
-Error
-NativeProcessLinux::SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware)
-{
- if (hardware)
- return Error ("NativeProcessLinux does not support hardware breakpoints");
- else
- return SetSoftwareBreakpoint (addr, size);
-}
+ case llvm::Triple::systemz:
+ actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode));
+ return Error();
-Error
-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 };
- // 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 };
-
- switch (m_arch.GetMachine ())
- {
- case llvm::Triple::aarch64:
- trap_opcode_bytes = g_aarch64_opcode;
- actual_opcode_size = sizeof(g_aarch64_opcode);
- return Error ();
-
- case llvm::Triple::arm:
- switch (trap_opcode_size_hint)
- {
- case 2:
- trap_opcode_bytes = g_thumb_breakpoint_opcode;
- actual_opcode_size = sizeof(g_thumb_breakpoint_opcode);
- return Error ();
- case 4:
- trap_opcode_bytes = g_arm_breakpoint_opcode;
- actual_opcode_size = sizeof(g_arm_breakpoint_opcode);
- return Error ();
- default:
- assert(false && "Unrecognised trap opcode size hint!");
- return Error ("Unrecognised trap opcode size hint!");
- }
+ case llvm::Triple::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ // On these architectures the PC don't get updated for breakpoint hits
+ actual_opcode_size = 0;
+ return Error();
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- trap_opcode_bytes = g_i386_opcode;
- actual_opcode_size = sizeof(g_i386_opcode);
- return Error ();
-
- case llvm::Triple::mips:
- case llvm::Triple::mips64:
- trap_opcode_bytes = g_mips64_opcode;
- actual_opcode_size = sizeof(g_mips64_opcode);
- return Error ();
-
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64el:
- trap_opcode_bytes = g_mips64el_opcode;
- actual_opcode_size = sizeof(g_mips64el_opcode);
- return Error ();
-
- case llvm::Triple::systemz:
- trap_opcode_bytes = g_s390x_opcode;
- actual_opcode_size = sizeof(g_s390x_opcode);
- return Error ();
+ default:
+ assert(false && "CPU type not supported!");
+ return Error("CPU type not supported");
+ }
+}
+
+Error NativeProcessLinux::SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) {
+ if (hardware)
+ return Error("NativeProcessLinux does not support hardware breakpoints");
+ else
+ return SetSoftwareBreakpoint(addr, size);
+}
+
+Error 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};
+ // 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};
+
+ switch (m_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ trap_opcode_bytes = g_aarch64_opcode;
+ actual_opcode_size = sizeof(g_aarch64_opcode);
+ return Error();
+ case llvm::Triple::arm:
+ switch (trap_opcode_size_hint) {
+ case 2:
+ trap_opcode_bytes = g_thumb_breakpoint_opcode;
+ actual_opcode_size = sizeof(g_thumb_breakpoint_opcode);
+ return Error();
+ case 4:
+ trap_opcode_bytes = g_arm_breakpoint_opcode;
+ actual_opcode_size = sizeof(g_arm_breakpoint_opcode);
+ return Error();
default:
- assert(false && "CPU type not supported!");
- return Error ("CPU type not supported");
+ assert(false && "Unrecognised trap opcode size hint!");
+ return Error("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 Error();
+
+ case llvm::Triple::mips:
+ case llvm::Triple::mips64:
+ trap_opcode_bytes = g_mips64_opcode;
+ actual_opcode_size = sizeof(g_mips64_opcode);
+ return Error();
+
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64el:
+ trap_opcode_bytes = g_mips64el_opcode;
+ actual_opcode_size = sizeof(g_mips64el_opcode);
+ return Error();
+
+ case llvm::Triple::systemz:
+ trap_opcode_bytes = g_s390x_opcode;
+ actual_opcode_size = sizeof(g_s390x_opcode);
+ return Error();
+
+ default:
+ assert(false && "CPU type not supported!");
+ return Error("CPU type not supported");
+ }
}
#if 0
@@ -2214,7 +2012,6 @@ NativeProcessLinux::GetCrashReasonForSIGSEGV(const siginfo_t *info)
}
#endif
-
#if 0
ProcessMessage::CrashReason
NativeProcessLinux::GetCrashReasonForSIGILL(const siginfo_t *info)
@@ -2332,654 +2129,628 @@ NativeProcessLinux::GetCrashReasonForSIGBUS(const siginfo_t *info)
}
#endif
-Error
-NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
-{
- if (ProcessVmReadvSupported()) {
- // The process_vm_readv path is about 50 times faster than ptrace api. We want to use
- // this syscall if it is supported.
+Error NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) {
+ if (ProcessVmReadvSupported()) {
+ // The process_vm_readv path is about 50 times faster than ptrace api. We
+ // want to use
+ // this syscall if it is supported.
- const ::pid_t pid = GetID();
+ const ::pid_t pid = GetID();
- struct iovec local_iov, remote_iov;
- local_iov.iov_base = buf;
- local_iov.iov_len = size;
- remote_iov.iov_base = reinterpret_cast<void *>(addr);
- remote_iov.iov_len = size;
+ struct iovec local_iov, remote_iov;
+ local_iov.iov_base = buf;
+ local_iov.iov_len = size;
+ remote_iov.iov_base = reinterpret_cast<void *>(addr);
+ remote_iov.iov_len = size;
- bytes_read = process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0);
- const bool success = bytes_read == size;
+ bytes_read = process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0);
+ const bool success = bytes_read == size;
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("NativeProcessLinux::%s using process_vm_readv to read %zd bytes from inferior address 0x%" PRIx64": %s",
- __FUNCTION__, size, addr, success ? "Success" : strerror(errno));
-
- if (success)
- return Error();
- // else
- // the call failed for some reason, let's retry the read using ptrace api.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s using process_vm_readv to read %zd "
+ "bytes from inferior address 0x%" PRIx64 ": %s",
+ __FUNCTION__, size, addr,
+ success ? "Success" : strerror(errno));
+
+ if (success)
+ return Error();
+ // else
+ // the call failed for some reason, let's retry the read using ptrace
+ // api.
+ }
+
+ unsigned char *dst = static_cast<unsigned char *>(buf);
+ size_t remainder;
+ long data;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
+ if (log)
+ ProcessPOSIXLog::IncNestLevel();
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ log->GetMask().Test(POSIX_LOG_MEMORY))
+ log->Printf("NativeProcessLinux::%s(%p, %p, %zd, _)", __FUNCTION__,
+ (void *)addr, buf, size);
+
+ for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_PEEKDATA, GetID(), (void *)addr, nullptr, 0, &data);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
}
- unsigned char *dst = static_cast<unsigned char*>(buf);
- size_t remainder;
- long data;
+ remainder = size - bytes_read;
+ remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
- if (log)
- ProcessPOSIXLog::IncNestLevel();
- if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
- log->Printf ("NativeProcessLinux::%s(%p, %p, %zd, _)", __FUNCTION__, (void*)addr, buf, size);
-
- for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
- {
- Error error = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, GetID(), (void*)addr, nullptr, 0, &data);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
+ // Copy the data into our buffer
+ memcpy(dst, &data, remainder);
- remainder = size - bytes_read;
- remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
-
- // Copy the data into our buffer
- memcpy(dst, &data, remainder);
-
- if (log && ProcessPOSIXLog::AtTopNestLevel() &&
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
- size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
- {
- uintptr_t print_dst = 0;
- // Format bytes from data by moving into print_dst for log output
- for (unsigned i = 0; i < remainder; ++i)
- print_dst |= (((data >> i*8) & 0xFF) << i*8);
- log->Printf ("NativeProcessLinux::%s() [0x%" PRIx64 "]:0x%" PRIx64 " (0x%" PRIx64 ")",
- __FUNCTION__, addr, uint64_t(print_dst), uint64_t(data));
- }
- addr += k_ptrace_word_size;
- dst += k_ptrace_word_size;
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+ size <= POSIX_LOG_MEMORY_SHORT_BYTES))) {
+ uintptr_t print_dst = 0;
+ // Format bytes from data by moving into print_dst for log output
+ for (unsigned i = 0; i < remainder; ++i)
+ print_dst |= (((data >> i * 8) & 0xFF) << i * 8);
+ log->Printf("NativeProcessLinux::%s() [0x%" PRIx64 "]:0x%" PRIx64
+ " (0x%" PRIx64 ")",
+ __FUNCTION__, addr, uint64_t(print_dst), uint64_t(data));
}
+ addr += k_ptrace_word_size;
+ dst += k_ptrace_word_size;
+ }
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return Error();
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return Error();
}
-Error
-NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
-{
- Error error = ReadMemory(addr, buf, size, bytes_read);
- if (error.Fail()) return error;
- return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
-}
-
-Error
-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);
- size_t remainder;
- Error error;
+Error NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
+ size_t size,
+ size_t &bytes_read) {
+ Error error = ReadMemory(addr, buf, size, bytes_read);
+ if (error.Fail())
+ return error;
+ return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
+}
+
+Error 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);
+ size_t remainder;
+ Error error;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
+ if (log)
+ ProcessPOSIXLog::IncNestLevel();
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ log->GetMask().Test(POSIX_LOG_MEMORY))
+ log->Printf("NativeProcessLinux::%s(0x%" PRIx64 ", %p, %zu)", __FUNCTION__,
+ addr, buf, size);
+
+ for (bytes_written = 0; bytes_written < size; bytes_written += remainder) {
+ remainder = size - bytes_written;
+ remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
+
+ if (remainder == k_ptrace_word_size) {
+ unsigned long data = 0;
+ memcpy(&data, src, k_ptrace_word_size);
+
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+ size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
+ log->Printf("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+ (void *)addr, *(const unsigned long *)src, data);
+
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(),
+ (void *)addr, (void *)data);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
+ }
+ } else {
+ unsigned char buff[8];
+ size_t bytes_read;
+ error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
+ }
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
- if (log)
- ProcessPOSIXLog::IncNestLevel();
- if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
- log->Printf ("NativeProcessLinux::%s(0x%" PRIx64 ", %p, %zu)", __FUNCTION__, addr, buf, size);
+ memcpy(buff, src, remainder);
- for (bytes_written = 0; bytes_written < size; bytes_written += remainder)
- {
- remainder = size - bytes_written;
- remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
-
- if (remainder == k_ptrace_word_size)
- {
- unsigned long data = 0;
- memcpy(&data, src, k_ptrace_word_size);
-
- if (log && ProcessPOSIXLog::AtTopNestLevel() &&
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
- size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
- log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
- (void*)addr, *(const unsigned long*)src, data);
-
- error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(), (void*)addr, (void*)data);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
- }
- else
- {
- unsigned char buff[8];
- size_t bytes_read;
- error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
-
- memcpy(buff, src, remainder);
-
- size_t bytes_written_rec;
- error = WriteMemory(addr, buff, k_ptrace_word_size, bytes_written_rec);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
-
- if (log && ProcessPOSIXLog::AtTopNestLevel() &&
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
- size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
- log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
- (void*)addr, *(const unsigned long*)src, *(unsigned long*)buff);
- }
+ size_t bytes_written_rec;
+ error = WriteMemory(addr, buff, k_ptrace_word_size, bytes_written_rec);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
+ }
- addr += k_ptrace_word_size;
- src += k_ptrace_word_size;
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+ size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
+ log->Printf("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+ (void *)addr, *(const unsigned long *)src,
+ *(unsigned long *)buff);
}
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
-}
-Error
-NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo)
-{
- return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
+ addr += k_ptrace_word_size;
+ src += k_ptrace_word_size;
+ }
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
}
-Error
-NativeProcessLinux::GetEventMessage(lldb::tid_t tid, unsigned long *message)
-{
- return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message);
+Error NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo) {
+ return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
}
-Error
-NativeProcessLinux::Detach(lldb::tid_t tid)
-{
- if (tid == LLDB_INVALID_THREAD_ID)
- return Error();
-
- return PtraceWrapper(PTRACE_DETACH, tid);
+Error NativeProcessLinux::GetEventMessage(lldb::tid_t tid,
+ unsigned long *message) {
+ return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message);
}
-bool
-NativeProcessLinux::DupDescriptor(const FileSpec &file_spec, int fd, int flags)
-{
- int target_fd = open(file_spec.GetCString(), flags, 0666);
-
- if (target_fd == -1)
- return false;
-
- if (dup2(target_fd, fd) == -1)
- return false;
+Error NativeProcessLinux::Detach(lldb::tid_t tid) {
+ if (tid == LLDB_INVALID_THREAD_ID)
+ return Error();
- return (close(target_fd) == -1) ? false : true;
+ return PtraceWrapper(PTRACE_DETACH, tid);
}
-bool
-NativeProcessLinux::HasThreadNoLock (lldb::tid_t thread_id)
-{
- for (auto thread_sp : m_threads)
- {
- assert (thread_sp && "thread list should not contain NULL threads");
- if (thread_sp->GetID () == thread_id)
- {
- // We have this thread.
- return true;
- }
+bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not contain NULL threads");
+ if (thread_sp->GetID() == thread_id) {
+ // We have this thread.
+ return true;
}
+ }
- // We don't have this thread.
- return false;
+ // We don't have this thread.
+ return false;
}
-bool
-NativeProcessLinux::StopTrackingThread (lldb::tid_t thread_id)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+bool NativeProcessLinux::StopTrackingThread(lldb::tid_t thread_id) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
- if (log)
- log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, thread_id);
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__,
+ thread_id);
- bool found = false;
+ bool found = false;
- for (auto it = m_threads.begin (); it != m_threads.end (); ++it)
- {
- if (*it && ((*it)->GetID () == thread_id))
- {
- m_threads.erase (it);
- found = true;
- break;
- }
+ for (auto it = m_threads.begin(); it != m_threads.end(); ++it) {
+ if (*it && ((*it)->GetID() == thread_id)) {
+ m_threads.erase(it);
+ found = true;
+ break;
}
+ }
- SignalIfAllThreadsStopped();
+ SignalIfAllThreadsStopped();
- return found;
+ return found;
}
-NativeThreadLinuxSP
-NativeProcessLinux::AddThread (lldb::tid_t thread_id)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " adding thread with tid %" PRIu64,
- __FUNCTION__,
- GetID (),
- thread_id);
- }
+ if (log) {
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64
+ " adding thread with tid %" PRIu64,
+ __FUNCTION__, GetID(), thread_id);
+ }
- assert (!HasThreadNoLock (thread_id) && "attempted to add a thread by id that already exists");
+ assert(!HasThreadNoLock(thread_id) &&
+ "attempted to add a thread by id that already exists");
- // If this is the first thread, save it as the current thread
- if (m_threads.empty ())
- SetCurrentThreadID (thread_id);
+ // If this is the first thread, save it as the current thread
+ if (m_threads.empty())
+ SetCurrentThreadID(thread_id);
- auto thread_sp = std::make_shared<NativeThreadLinux>(this, thread_id);
- m_threads.push_back (thread_sp);
- return thread_sp;
+ auto thread_sp = std::make_shared<NativeThreadLinux>(this, thread_id);
+ m_threads.push_back(thread_sp);
+ return thread_sp;
}
-Error
-NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+Error NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- Error error;
+ Error error;
- // Find out the size of a breakpoint (might depend on where we are in the code).
- NativeRegisterContextSP context_sp = thread.GetRegisterContext();
- if (!context_sp)
- {
- error.SetErrorString ("cannot get a NativeRegisterContext for the thread");
- if (log)
- log->Printf ("NativeProcessLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
- return error;
- }
-
- uint32_t breakpoint_size = 0;
- error = GetSoftwareBreakpointPCOffset(breakpoint_size);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s GetBreakpointSize() failed: %s", __FUNCTION__, error.AsCString ());
- return error;
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s breakpoint size: %" PRIu32, __FUNCTION__, breakpoint_size);
- }
-
- // First try probing for a breakpoint at a software breakpoint location: PC - breakpoint size.
- const lldb::addr_t initial_pc_addr = context_sp->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.
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " no lldb breakpoint found at current pc with adjustment: 0x%" PRIx64, __FUNCTION__, GetID (), breakpoint_addr);
- return Error ();
- }
-
- // If the breakpoint is not a software breakpoint, nothing to do.
- if (!breakpoint_sp->IsSoftwareBreakpoint ())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", not software, nothing to adjust", __FUNCTION__, GetID (), breakpoint_addr);
- return Error ();
- }
-
- //
- // 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?
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", it is software, but the size is zero, nothing to do (unexpected)", __FUNCTION__, GetID (), breakpoint_addr);
- return Error ();
- }
-
- // Change the program counter.
+ // Find out the size of a breakpoint (might depend on where we are in the
+ // code).
+ NativeRegisterContextSP context_sp = thread.GetRegisterContext();
+ if (!context_sp) {
+ error.SetErrorString("cannot get a NativeRegisterContext for the thread");
if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64, __FUNCTION__, GetID(), thread.GetID(), initial_pc_addr, breakpoint_addr);
-
- error = context_sp->SetPC (breakpoint_addr);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": failed to set PC: %s", __FUNCTION__, GetID(), thread.GetID(), error.AsCString ());
- return error;
- }
-
+ log->Printf("NativeProcessLinux::%s failed: %s", __FUNCTION__,
+ error.AsCString());
return error;
-}
-
-Error
-NativeProcessLinux::GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec)
-{
- FileSpec module_file_spec(module_path, true);
-
- bool found = false;
- file_spec.Clear();
- ProcFileReader::ProcessLineByLine(GetID(), "maps",
- [&] (const std::string &line)
- {
- SmallVector<StringRef, 16> columns;
- StringRef(line).split(columns, " ", -1, false);
- if (columns.size() < 6)
- return true; // continue searching
-
- FileSpec this_file_spec(columns[5].str().c_str(), false);
- if (this_file_spec.GetFilename() != module_file_spec.GetFilename())
- return true; // continue searching
-
- file_spec = this_file_spec;
- found = true;
- return false; // we are done
- });
+ }
- if (! found)
- return Error("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
- module_file_spec.GetFilename().AsCString(), GetID());
+ uint32_t breakpoint_size = 0;
+ error = GetSoftwareBreakpointPCOffset(breakpoint_size);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s GetBreakpointSize() failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ } else {
+ if (log)
+ log->Printf("NativeProcessLinux::%s breakpoint size: %" PRIu32,
+ __FUNCTION__, breakpoint_size);
+ }
+
+ // First try probing for a breakpoint at a software breakpoint location: PC -
+ // breakpoint size.
+ const lldb::addr_t initial_pc_addr =
+ context_sp->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.
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s pid %" PRIu64
+ " no lldb breakpoint found at current pc with adjustment: 0x%" PRIx64,
+ __FUNCTION__, GetID(), breakpoint_addr);
+ return Error();
+ }
+ // If the breakpoint is not a software breakpoint, nothing to do.
+ if (!breakpoint_sp->IsSoftwareBreakpoint()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64
+ " breakpoint found at 0x%" PRIx64
+ ", not software, nothing to adjust",
+ __FUNCTION__, GetID(), breakpoint_addr);
return Error();
-}
+ }
-Error
-NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr)
-{
- load_addr = LLDB_INVALID_ADDRESS;
- Error error = ProcFileReader::ProcessLineByLine (GetID (), "maps",
- [&] (const std::string &line) -> bool
- {
- StringRef maps_row(line);
-
- SmallVector<StringRef, 16> maps_columns;
- maps_row.split(maps_columns, StringRef(" "), -1, false);
-
- if (maps_columns.size() < 6)
- {
- // Return true to continue reading the proc file
- return true;
- }
-
- if (maps_columns[5] == file_name)
- {
- StringExtractor addr_extractor(maps_columns[0].str().c_str());
- load_addr = addr_extractor.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
-
- // Return false to stop reading the proc file further
- return false;
- }
-
- // Return true to continue reading the proc file
- return true;
- });
- return error;
-}
+ //
+ // We have a software breakpoint and need to adjust the PC.
+ //
-NativeThreadLinuxSP
-NativeProcessLinux::GetThreadByID(lldb::tid_t tid)
-{
- return std::static_pointer_cast<NativeThreadLinux>(NativeProcessProtocol::GetThreadByID(tid));
-}
+ // Sanity check.
+ if (breakpoint_size == 0) {
+ // Nothing to do! How did we get here?
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s pid %" PRIu64
+ " breakpoint found at 0x%" PRIx64
+ ", it is software, but the size is zero, nothing to do (unexpected)",
+ __FUNCTION__, GetID(), breakpoint_addr);
+ return Error();
+ }
-Error
-NativeProcessLinux::ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+ // Change the program counter.
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64
+ ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64,
+ __FUNCTION__, GetID(), thread.GetID(), initial_pc_addr,
+ breakpoint_addr);
+ error = context_sp->SetPC(breakpoint_addr);
+ if (error.Fail()) {
if (log)
- log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")",
- __FUNCTION__, thread.GetID());
-
- // Before we do the resume below, first check if we have a pending
- // stop notification that is currently waiting for
- // all threads to stop. This is potentially a buggy situation since
- // we're ostensibly waiting for threads to stop before we send out the
- // pending notification, and here we are resuming one before we send
- // out the pending stop notification.
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && log)
- {
- log->Printf("NativeProcessLinux::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that is actively waiting for this thread to stop. Valid sequence of events?", __FUNCTION__, thread.GetID(), m_pending_notification_tid);
- }
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64
+ ": failed to set PC: %s",
+ __FUNCTION__, GetID(), thread.GetID(), error.AsCString());
+ return error;
+ }
- // Request a resume. We expect this to be synchronous and the system
- // to reflect it is running after this completes.
- switch (state)
- {
- case eStateRunning:
- {
- const auto resume_result = thread.Resume(signo);
- if (resume_result.Success())
- SetState(eStateRunning, true);
- return resume_result;
- }
- case eStateStepping:
- {
- const auto step_result = thread.SingleStep(signo);
- if (step_result.Success())
- SetState(eStateRunning, true);
- return step_result;
- }
- default:
- if (log)
- log->Printf("NativeProcessLinux::%s Unhandled state %s.",
- __FUNCTION__, StateAsCString(state));
- llvm_unreachable("Unhandled state for resume");
- }
+ return error;
}
-//===----------------------------------------------------------------------===//
+Error NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) {
+ FileSpec module_file_spec(module_path, true);
-void
-NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+ bool found = false;
+ file_spec.Clear();
+ ProcFileReader::ProcessLineByLine(
+ GetID(), "maps", [&](const std::string &line) {
+ SmallVector<StringRef, 16> columns;
+ StringRef(line).split(columns, " ", -1, false);
+ if (columns.size() < 6)
+ return true; // continue searching
- if (log)
- {
- log->Printf("NativeProcessLinux::%s about to process event: (triggering_tid: %" PRIu64 ")",
- __FUNCTION__, triggering_tid);
- }
+ FileSpec this_file_spec(columns[5].str(), false);
+ if (this_file_spec.GetFilename() != module_file_spec.GetFilename())
+ return true; // continue searching
- m_pending_notification_tid = triggering_tid;
+ file_spec = this_file_spec;
+ found = true;
+ return false; // we are done
+ });
- // Request a stop for all the thread stops that need to be stopped
- // and are not already known to be stopped.
- for (const auto &thread_sp: m_threads)
- {
- if (StateIsRunningState(thread_sp->GetState()))
- static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop();
- }
-
- SignalIfAllThreadsStopped();
+ if (!found)
+ return Error("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
+ module_file_spec.GetFilename().AsCString(), GetID());
- if (log)
- {
- log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__);
- }
+ return Error();
}
-void
-NativeProcessLinux::SignalIfAllThreadsStopped()
-{
- if (m_pending_notification_tid == LLDB_INVALID_THREAD_ID)
- return; // No pending notification. Nothing to do.
-
- for (const auto &thread_sp: m_threads)
- {
- if (StateIsRunningState(thread_sp->GetState()))
- return; // Some threads are still running. Don't signal yet.
- }
+Error NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) {
+ load_addr = LLDB_INVALID_ADDRESS;
+ Error error = ProcFileReader::ProcessLineByLine(
+ GetID(), "maps", [&](const std::string &line) -> bool {
+ StringRef maps_row(line);
- // We have a pending notification and all threads have stopped.
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
+ SmallVector<StringRef, 16> maps_columns;
+ maps_row.split(maps_columns, StringRef(" "), -1, false);
- // Clear any temporary breakpoints we used to implement software single stepping.
- for (const auto &thread_info: m_threads_stepping_with_breakpoint)
- {
- Error error = RemoveBreakpoint (thread_info.second);
- if (error.Fail())
- if (log)
- log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " remove stepping breakpoint: %s",
- __FUNCTION__, thread_info.first, error.AsCString());
- }
- m_threads_stepping_with_breakpoint.clear();
+ if (maps_columns.size() < 6) {
+ // Return true to continue reading the proc file
+ return true;
+ }
- // Notify the delegate about the stop
- SetCurrentThreadID(m_pending_notification_tid);
- SetState(StateType::eStateStopped, true);
- m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-}
+ if (maps_columns[5] == file_name) {
+ StringExtractor addr_extractor(maps_columns[0].str().c_str());
+ load_addr = addr_extractor.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
-void
-NativeProcessLinux::ThreadWasCreated(NativeThreadLinux &thread)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+ // Return false to stop reading the proc file further
+ return false;
+ }
+ // Return true to continue reading the proc file
+ return true;
+ });
+ return error;
+}
+
+NativeThreadLinuxSP NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
+ return std::static_pointer_cast<NativeThreadLinux>(
+ NativeProcessProtocol::GetThreadByID(tid));
+}
+
+Error NativeProcessLinux::ResumeThread(NativeThreadLinux &thread,
+ lldb::StateType state, int signo) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__,
+ thread.GetID());
+
+ // Before we do the resume below, first check if we have a pending
+ // stop notification that is currently waiting for
+ // all threads to stop. This is potentially a buggy situation since
+ // we're ostensibly waiting for threads to stop before we send out the
+ // pending notification, and here we are resuming one before we send
+ // out the pending stop notification.
+ if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && log) {
+ log->Printf("NativeProcessLinux::%s about to resume tid %" PRIu64
+ " per explicit request but we have a pending stop notification "
+ "(tid %" PRIu64 ") that is actively waiting for this thread to "
+ "stop. Valid sequence of events?",
+ __FUNCTION__, thread.GetID(), m_pending_notification_tid);
+ }
+
+ // Request a resume. We expect this to be synchronous and the system
+ // to reflect it is running after this completes.
+ switch (state) {
+ case eStateRunning: {
+ const auto resume_result = thread.Resume(signo);
+ if (resume_result.Success())
+ SetState(eStateRunning, true);
+ return resume_result;
+ }
+ case eStateStepping: {
+ const auto step_result = thread.SingleStep(signo);
+ if (step_result.Success())
+ SetState(eStateRunning, true);
+ return step_result;
+ }
+ default:
if (log)
- log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, thread.GetID());
-
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && StateIsRunningState(thread.GetState()))
- {
- // We will need to wait for this new thread to stop as well before firing the
- // notification.
- thread.RequestStop();
- }
+ log->Printf("NativeProcessLinux::%s Unhandled state %s.", __FUNCTION__,
+ StateAsCString(state));
+ llvm_unreachable("Unhandled state for resume");
+ }
}
-void
-NativeProcessLinux::SigchldHandler()
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Process all pending waitpid notifications.
- while (true)
- {
- int status = -1;
- ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
+//===----------------------------------------------------------------------===//
- if (wait_pid == 0)
- break; // We are done.
+void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
- if (wait_pid == -1)
- {
- if (errno == EINTR)
- continue;
+ if (log) {
+ log->Printf("NativeProcessLinux::%s about to process event: "
+ "(triggering_tid: %" PRIu64 ")",
+ __FUNCTION__, triggering_tid);
+ }
- Error error(errno, eErrorTypePOSIX);
- if (log)
- log->Printf("NativeProcessLinux::%s waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG) failed: %s",
- __FUNCTION__, error.AsCString());
- break;
- }
+ m_pending_notification_tid = triggering_tid;
- bool exited = false;
- int signal = 0;
- int exit_status = 0;
- const char *status_cstr = nullptr;
- if (WIFSTOPPED(status))
- {
- signal = WSTOPSIG(status);
- status_cstr = "STOPPED";
- }
- else if (WIFEXITED(status))
- {
- exit_status = WEXITSTATUS(status);
- status_cstr = "EXITED";
- exited = true;
- }
- else if (WIFSIGNALED(status))
- {
- signal = WTERMSIG(status);
- status_cstr = "SIGNALED";
- if (wait_pid == static_cast< ::pid_t>(GetID())) {
- exited = true;
- exit_status = -1;
- }
- }
- else
- status_cstr = "(\?\?\?)";
+ // Request a stop for all the thread stops that need to be stopped
+ // and are not already known to be stopped.
+ for (const auto &thread_sp : m_threads) {
+ if (StateIsRunningState(thread_sp->GetState()))
+ static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop();
+ }
- if (log)
- log->Printf("NativeProcessLinux::%s: waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG)"
- "=> pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
- __FUNCTION__, wait_pid, status, status_cstr, signal, exit_status);
+ SignalIfAllThreadsStopped();
- MonitorCallback (wait_pid, exited, signal, exit_status);
- }
+ if (log) {
+ log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__);
+ }
}
-// Wrapper for ptrace to catch errors and log calls.
-// Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
-Error
-NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, long *result)
-{
- Error error;
- long int ret;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
-
- PtraceDisplayBytes(req, data, data_size);
+void NativeProcessLinux::SignalIfAllThreadsStopped() {
+ if (m_pending_notification_tid == LLDB_INVALID_THREAD_ID)
+ return; // No pending notification. Nothing to do.
- errno = 0;
- if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
- ret = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data);
- else
- ret = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data);
+ for (const auto &thread_sp : m_threads) {
+ if (StateIsRunningState(thread_sp->GetState()))
+ return; // Some threads are still running. Don't signal yet.
+ }
- if (ret == -1)
- error.SetErrorToErrno();
+ // We have a pending notification and all threads have stopped.
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
- if (result)
- *result = ret;
+ // Clear any temporary breakpoints we used to implement software single
+ // stepping.
+ for (const auto &thread_info : m_threads_stepping_with_breakpoint) {
+ Error error = RemoveBreakpoint(thread_info.second);
+ if (error.Fail())
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64
+ " remove stepping breakpoint: %s",
+ __FUNCTION__, thread_info.first, error.AsCString());
+ }
+ m_threads_stepping_with_breakpoint.clear();
+
+ // Notify the delegate about the stop
+ SetCurrentThreadID(m_pending_notification_tid);
+ SetState(StateType::eStateStopped, true);
+ m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
+}
+
+void NativeProcessLinux::ThreadWasCreated(NativeThreadLinux &thread) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__,
+ thread.GetID());
+
+ if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID &&
+ StateIsRunningState(thread.GetState())) {
+ // We will need to wait for this new thread to stop as well before firing
+ // the
+ // notification.
+ thread.RequestStop();
+ }
+}
+
+void NativeProcessLinux::SigchldHandler() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ // Process all pending waitpid notifications.
+ while (true) {
+ int status = -1;
+ ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
+
+ if (wait_pid == 0)
+ break; // We are done.
+
+ if (wait_pid == -1) {
+ if (errno == EINTR)
+ continue;
+
+ Error error(errno, eErrorTypePOSIX);
+ if (log)
+ log->Printf("NativeProcessLinux::%s waitpid (-1, &status, __WALL | "
+ "__WNOTHREAD | WNOHANG) failed: %s",
+ __FUNCTION__, error.AsCString());
+ break;
+ }
+
+ bool exited = false;
+ int signal = 0;
+ int exit_status = 0;
+ const char *status_cstr = nullptr;
+ if (WIFSTOPPED(status)) {
+ signal = WSTOPSIG(status);
+ status_cstr = "STOPPED";
+ } else if (WIFEXITED(status)) {
+ exit_status = WEXITSTATUS(status);
+ status_cstr = "EXITED";
+ exited = true;
+ } else if (WIFSIGNALED(status)) {
+ signal = WTERMSIG(status);
+ status_cstr = "SIGNALED";
+ if (wait_pid == static_cast<::pid_t>(GetID())) {
+ exited = true;
+ exit_status = -1;
+ }
+ } else
+ status_cstr = "(\?\?\?)";
if (log)
- log->Printf("ptrace(%d, %" PRIu64 ", %p, %p, %zu)=%lX", req, pid, addr, data, data_size, ret);
+ log->Printf("NativeProcessLinux::%s: waitpid (-1, &status, __WALL | "
+ "__WNOTHREAD | WNOHANG)"
+ "=> pid = %" PRIi32
+ ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
+ __FUNCTION__, wait_pid, status, status_cstr, signal,
+ exit_status);
- PtraceDisplayBytes(req, data, data_size);
+ MonitorCallback(wait_pid, exited, signal, exit_status);
+ }
+}
- if (log && error.GetError() != 0)
- {
- const char* str;
- switch (error.GetError())
- {
- case ESRCH: str = "ESRCH"; break;
- case EINVAL: str = "EINVAL"; break;
- case EBUSY: str = "EBUSY"; break;
- case EPERM: str = "EPERM"; break;
- default: str = error.AsCString();
- }
- log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str);
+// Wrapper for ptrace to catch errors and log calls.
+// Note that ptrace sets errno on error because -1 can be a valid result (i.e.
+// for PTRACE_PEEK*)
+Error NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
+ void *data, size_t data_size,
+ long *result) {
+ Error error;
+ long int ret;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+
+ PtraceDisplayBytes(req, data, data_size);
+
+ errno = 0;
+ if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
+ ret = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid),
+ *(unsigned int *)addr, data);
+ else
+ ret = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid),
+ addr, data);
+
+ if (ret == -1)
+ error.SetErrorToErrno();
+
+ if (result)
+ *result = ret;
+
+ if (log)
+ log->Printf("ptrace(%d, %" PRIu64 ", %p, %p, %zu)=%lX", req, pid, addr,
+ data, data_size, ret);
+
+ PtraceDisplayBytes(req, data, data_size);
+
+ if (log && error.GetError() != 0) {
+ const char *str;
+ switch (error.GetError()) {
+ case ESRCH:
+ str = "ESRCH";
+ break;
+ case EINVAL:
+ str = "EINVAL";
+ break;
+ case EBUSY:
+ str = "EBUSY";
+ break;
+ case EPERM:
+ str = "EPERM";
+ break;
+ default:
+ str = error.AsCString();
}
+ log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str);
+ }
- return error;
+ return error;
}
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index d5be06f0cb58..fcb13c8b016b 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -15,192 +15,151 @@
// Other libraries and framework includes
#include "lldb/Core/ArchSpec.h"
-#include "lldb/lldb-types.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/lldb-types.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
#include "NativeThreadLinux.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
namespace lldb_private {
- class Error;
- class Scalar;
+class Error;
+class Scalar;
namespace process_linux {
- /// @class NativeProcessLinux
- /// @brief Manages communication with the inferior (debugee) process.
- ///
- /// Upon construction, this class prepares and launches an inferior process for
- /// debugging.
- ///
- /// Changes in the inferior process state are broadcasted.
- class NativeProcessLinux: public NativeProcessProtocol
- {
- friend Error
- NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info,
- NativeDelegate &native_delegate,
- MainLoop &mainloop,
- NativeProcessProtocolSP &process_sp);
-
- friend Error
- NativeProcessProtocol::Attach (lldb::pid_t pid,
- NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop,
- NativeProcessProtocolSP &process_sp);
+/// @class NativeProcessLinux
+/// @brief Manages communication with the inferior (debugee) process.
+///
+/// Upon construction, this class prepares and launches an inferior process for
+/// debugging.
+///
+/// Changes in the inferior process state are broadcasted.
+class NativeProcessLinux : public NativeProcessProtocol {
+ friend Error NativeProcessProtocol::Launch(
+ ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
- public:
- // ---------------------------------------------------------------------
- // NativeProcessProtocol Interface
- // ---------------------------------------------------------------------
- Error
- Resume (const ResumeActionList &resume_actions) override;
+ friend Error NativeProcessProtocol::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
- Error
- Halt () override;
+public:
+ // ---------------------------------------------------------------------
+ // NativeProcessProtocol Interface
+ // ---------------------------------------------------------------------
+ Error Resume(const ResumeActionList &resume_actions) override;
- Error
- Detach () override;
+ Error Halt() override;
- Error
- Signal (int signo) override;
+ Error Detach() override;
- Error
- Interrupt () override;
+ Error Signal(int signo) override;
- Error
- Kill () override;
+ Error Interrupt() override;
- Error
- GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) override;
+ Error Kill() override;
- Error
- ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
- Error
- ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
+ Error ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
- Error
- WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override;
+ Error ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
- Error
- AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr) override;
+ Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ size_t &bytes_written) override;
- Error
- DeallocateMemory (lldb::addr_t addr) override;
+ Error AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) override;
- lldb::addr_t
- GetSharedLibraryInfoAddress () override;
+ Error DeallocateMemory(lldb::addr_t addr) override;
- size_t
- UpdateThreads () override;
+ lldb::addr_t GetSharedLibraryInfoAddress() override;
- bool
- GetArchitecture (ArchSpec &arch) const override;
+ size_t UpdateThreads() override;
- Error
- SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override;
+ bool GetArchitecture(ArchSpec &arch) const override;
- void
- DoStopIDBumped (uint32_t newBumpId) override;
+ Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override;
- Error
- GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
+ void DoStopIDBumped(uint32_t newBumpId) override;
- Error
- GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) override;
+ Error GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) override;
- NativeThreadLinuxSP
- GetThreadByID(lldb::tid_t id);
+ Error GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) override;
- // ---------------------------------------------------------------------
- // Interface used by NativeRegisterContext-derived classes.
- // ---------------------------------------------------------------------
- static Error
- PtraceWrapper(int req,
- lldb::pid_t pid,
- void *addr = nullptr,
- void *data = nullptr,
- size_t data_size = 0,
- long *result = nullptr);
+ NativeThreadLinuxSP GetThreadByID(lldb::tid_t id);
- bool
- SupportHardwareSingleStepping() const;
+ // ---------------------------------------------------------------------
+ // Interface used by NativeRegisterContext-derived classes.
+ // ---------------------------------------------------------------------
+ static Error PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
+ void *data = nullptr, size_t data_size = 0,
+ long *result = nullptr);
- protected:
- // ---------------------------------------------------------------------
- // NativeProcessProtocol protected interface
- // ---------------------------------------------------------------------
- Error
- GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override;
+ bool SupportHardwareSingleStepping() const;
- private:
+protected:
+ // ---------------------------------------------------------------------
+ // NativeProcessProtocol protected interface
+ // ---------------------------------------------------------------------
+ Error
+ GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
+ size_t &actual_opcode_size,
+ const uint8_t *&trap_opcode_bytes) override;
- MainLoop::SignalHandleUP m_sigchld_handle;
- ArchSpec m_arch;
+private:
+ MainLoop::SignalHandleUP m_sigchld_handle;
+ ArchSpec m_arch;
- LazyBool m_supports_mem_region;
- std::vector<MemoryRegionInfo> m_mem_region_cache;
+ LazyBool m_supports_mem_region;
+ std::vector<MemoryRegionInfo> m_mem_region_cache;
- lldb::tid_t m_pending_notification_tid;
+ lldb::tid_t m_pending_notification_tid;
- // List of thread ids stepping with a breakpoint with the address of
- // the relevan breakpoint
- std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
+ // List of thread ids stepping with a breakpoint with the address of
+ // the relevan breakpoint
+ std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
+ // ---------------------------------------------------------------------
+ // Private Instance Methods
+ // ---------------------------------------------------------------------
+ NativeProcessLinux();
- // ---------------------------------------------------------------------
- // Private Instance Methods
- // ---------------------------------------------------------------------
- NativeProcessLinux ();
+ Error LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
- Error
- LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
+ /// Attaches to an existing process. Forms the
+ /// implementation of Process::DoAttach
+ void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error);
- /// Attaches to an existing process. Forms the
- /// implementation of Process::DoAttach
- void
- AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error);
+ ::pid_t Attach(lldb::pid_t pid, Error &error);
- ::pid_t
- Attach(lldb::pid_t pid, Error &error);
+ static Error SetDefaultPtraceOpts(const lldb::pid_t);
- static void
- ChildFunc(const ProcessLaunchInfo &launch_info) LLVM_ATTRIBUTE_NORETURN;
+ static void *MonitorThread(void *baton);
- static Error
- SetDefaultPtraceOpts(const lldb::pid_t);
+ void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
- static bool
- DupDescriptor(const FileSpec &file_spec, int fd, int flags);
+ void WaitForNewThread(::pid_t tid);
- static void *
- MonitorThread(void *baton);
+ void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
- void
- MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
+ void MonitorTrace(NativeThreadLinux &thread);
- void
- WaitForNewThread(::pid_t tid);
+ void MonitorBreakpoint(NativeThreadLinux &thread);
- void
- MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
+ void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
- void
- MonitorTrace(NativeThreadLinux &thread);
+ void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread,
+ bool exited);
- void
- MonitorBreakpoint(NativeThreadLinux &thread);
-
- void
- MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
-
- void
- MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
-
- Error
- SetupSoftwareSingleStepping(NativeThreadLinux &thread);
+ Error SetupSoftwareSingleStepping(NativeThreadLinux &thread);
#if 0
static ::ProcessMessage::CrashReason
@@ -216,59 +175,49 @@ namespace process_linux {
GetCrashReasonForSIGBUS(const siginfo_t *info);
#endif
- bool
- HasThreadNoLock (lldb::tid_t thread_id);
-
- bool
- StopTrackingThread (lldb::tid_t thread_id);
+ bool HasThreadNoLock(lldb::tid_t thread_id);
- NativeThreadLinuxSP
- AddThread (lldb::tid_t thread_id);
+ bool StopTrackingThread(lldb::tid_t thread_id);
- Error
- GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
+ NativeThreadLinuxSP AddThread(lldb::tid_t thread_id);
- Error
- FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
+ Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
- /// Writes a siginfo_t structure corresponding to the given thread ID to the
- /// memory region pointed to by @p siginfo.
- Error
- GetSignalInfo(lldb::tid_t tid, void *siginfo);
+ Error FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
- /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
- /// corresponding to the given thread ID to the memory pointed to by @p
- /// message.
- Error
- GetEventMessage(lldb::tid_t tid, unsigned long *message);
+ /// Writes a siginfo_t structure corresponding to the given thread ID to the
+ /// memory region pointed to by @p siginfo.
+ Error GetSignalInfo(lldb::tid_t tid, void *siginfo);
- void
- NotifyThreadDeath (lldb::tid_t tid);
+ /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
+ /// corresponding to the given thread ID to the memory pointed to by @p
+ /// message.
+ Error GetEventMessage(lldb::tid_t tid, unsigned long *message);
- Error
- Detach(lldb::tid_t tid);
+ void NotifyThreadDeath(lldb::tid_t tid);
+ Error Detach(lldb::tid_t tid);
- // This method is requests a stop on all threads which are still running. It sets up a
- // deferred delegate notification, which will fire once threads report as stopped. The
- // triggerring_tid will be set as the current thread (main stop reason).
- void
- StopRunningThreads(lldb::tid_t triggering_tid);
+ // This method is requests a stop on all threads which are still running. It
+ // sets up a
+ // deferred delegate notification, which will fire once threads report as
+ // stopped. The
+ // triggerring_tid will be set as the current thread (main stop reason).
+ void StopRunningThreads(lldb::tid_t triggering_tid);
- // Notify the delegate if all threads have stopped.
- void SignalIfAllThreadsStopped();
+ // Notify the delegate if all threads have stopped.
+ void SignalIfAllThreadsStopped();
- // Resume the given thread, optionally passing it the given signal. The type of resume
- // operation (continue, single-step) depends on the state parameter.
- Error
- ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo);
+ // Resume the given thread, optionally passing it the given signal. The type
+ // of resume
+ // operation (continue, single-step) depends on the state parameter.
+ Error ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
+ int signo);
- void
- ThreadWasCreated(NativeThreadLinux &thread);
+ void ThreadWasCreated(NativeThreadLinux &thread);
- void
- SigchldHandler();
- };
+ void SigchldHandler();
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
index 0188c5d30724..580d2f952ad1 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -19,212 +19,195 @@
using namespace lldb_private;
using namespace lldb_private::process_linux;
-NativeRegisterContextLinux::NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *reg_info_interface_p) :
- NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx, reg_info_interface_p)
-{}
-
-lldb::ByteOrder
-NativeRegisterContextLinux::GetByteOrder() const
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return byte_order;
-
- if (!process_sp->GetByteOrder (byte_order))
- {
- // FIXME log here
- }
-
+NativeRegisterContextLinux::NativeRegisterContextLinux(
+ NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *reg_info_interface_p)
+ : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx,
+ reg_info_interface_p) {}
+
+lldb::ByteOrder NativeRegisterContextLinux::GetByteOrder() const {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+
+ NativeProcessProtocolSP process_sp(m_thread.GetProcess());
+ if (!process_sp)
return byte_order;
-}
-Error
-NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value)
-{
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Error("register %" PRIu32 " not found", reg_index);
+ if (!process_sp->GetByteOrder(byte_order)) {
+ // FIXME log here
+ }
- return DoReadRegisterValue(reg_info->byte_offset, reg_info->name, reg_info->byte_size, reg_value);
+ return byte_order;
}
-Error
-NativeRegisterContextLinux::WriteRegisterRaw(uint32_t reg_index, const RegisterValue &reg_value)
-{
- uint32_t reg_to_write = reg_index;
- RegisterValue value_to_write = reg_value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- Error error;
-
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- error = ReadRegister(full_reg_info, full_value);
- if (error.Fail ())
- return error;
-
- lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = reg_value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
+Error NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index,
+ RegisterValue &reg_value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
- const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
- assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
- if (!register_to_write_info_p)
- return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
+ return DoReadRegisterValue(reg_info->byte_offset, reg_info->name,
+ reg_info->byte_size, reg_value);
+}
- return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
+Error NativeRegisterContextLinux::WriteRegisterRaw(
+ uint32_t reg_index, const RegisterValue &reg_value) {
+ uint32_t reg_to_write = reg_index;
+ RegisterValue value_to_write = reg_value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ Error error;
+
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ error = ReadRegister(full_reg_info, full_value);
+ if (error.Fail())
+ return error;
+
+ lldb::ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = reg_value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
+ }
+ }
+ }
+
+ const RegisterInfo *const register_to_write_info_p =
+ GetRegisterInfoAtIndex(reg_to_write);
+ assert(register_to_write_info_p &&
+ "register to write does not have valid RegisterInfo");
+ if (!register_to_write_info_p)
+ return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo "
+ "for write register index %" PRIu32,
+ __FUNCTION__, reg_to_write);
+
+ return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
}
-Error
-NativeRegisterContextLinux::ReadGPR()
-{
- void* buf = GetGPRBuffer();
- if (!buf)
- return Error("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
+Error NativeRegisterContextLinux::ReadGPR() {
+ void *buf = GetGPRBuffer();
+ if (!buf)
+ return Error("GPR buffer is NULL");
+ size_t buf_size = GetGPRSize();
- return DoReadGPR(buf, buf_size);
+ return DoReadGPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::WriteGPR()
-{
- void* buf = GetGPRBuffer();
- if (!buf)
- return Error("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
+Error NativeRegisterContextLinux::WriteGPR() {
+ void *buf = GetGPRBuffer();
+ if (!buf)
+ return Error("GPR buffer is NULL");
+ size_t buf_size = GetGPRSize();
- return DoWriteGPR(buf, buf_size);
+ return DoWriteGPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::ReadFPR()
-{
- void* buf = GetFPRBuffer();
- if (!buf)
- return Error("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
+Error NativeRegisterContextLinux::ReadFPR() {
+ void *buf = GetFPRBuffer();
+ if (!buf)
+ return Error("FPR buffer is NULL");
+ size_t buf_size = GetFPRSize();
- return DoReadFPR(buf, buf_size);
+ return DoReadFPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::WriteFPR()
-{
- void* buf = GetFPRBuffer();
- if (!buf)
- return Error("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
+Error NativeRegisterContextLinux::WriteFPR() {
+ void *buf = GetFPRBuffer();
+ if (!buf)
+ return Error("FPR buffer is NULL");
+ size_t buf_size = GetFPRSize();
- return DoWriteFPR(buf, buf_size);
+ return DoWriteFPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
- static_cast<void *>(&regset), buf, buf_size);
+Error NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
+ static_cast<void *>(&regset), buf,
+ buf_size);
}
-Error
-NativeRegisterContextLinux::WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- static_cast<void *>(&regset), buf, buf_size);
+Error NativeRegisterContextLinux::WriteRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ static_cast<void *>(&regset), buf,
+ buf_size);
}
-Error
-NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+Error NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset,
+ const char *reg_name,
+ uint32_t size,
+ RegisterValue &value) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
- long data;
- Error error = NativeProcessLinux::PtraceWrapper(
- PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), nullptr, 0, &data);
+ long data;
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast<void *>(offset),
+ nullptr, 0, &data);
- if (error.Success())
- // First cast to an unsigned of the same size to avoid sign extension.
- value.SetUInt(static_cast<unsigned long>(data), size);
+ if (error.Success())
+ // First cast to an unsigned of the same size to avoid sign extension.
+ value.SetUInt(static_cast<unsigned long>(data), size);
- if (log)
- log->Printf ("NativeRegisterContextLinux::%s() reg %s: 0x%lx", __FUNCTION__, reg_name, data);
+ if (log)
+ log->Printf("NativeRegisterContextLinux::%s() reg %s: 0x%lx", __FUNCTION__,
+ reg_name, data);
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux::DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+Error NativeRegisterContextLinux::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
- void* buf = reinterpret_cast<void *>(value.GetAsUInt64());
+ void *buf = reinterpret_cast<void *>(value.GetAsUInt64());
- if (log)
- log->Printf ("NativeRegisterContextLinux::%s() reg %s: %p", __FUNCTION__, reg_name, buf);
+ if (log)
+ log->Printf("NativeRegisterContextLinux::%s() reg %s: %p", __FUNCTION__,
+ reg_name, buf);
- return NativeProcessLinux::PtraceWrapper(
- PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
+ return NativeProcessLinux::PtraceWrapper(
+ PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
}
-Error
-NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
-Error
-NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
-Error
-NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
-Error
-NativeRegisterContextLinux::DoWriteFPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoWriteFPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
index 0b0b747984b4..a16c65b64a07 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -18,87 +18,72 @@
namespace lldb_private {
namespace process_linux {
-class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo
-{
+class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
public:
- NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *reg_info_interface_p);
-
- // This function is implemented in the NativeRegisterContextLinux_* subclasses to create a new
- // instance of the host specific NativeRegisterContextLinux. The implementations can't collide
- // as only one NativeRegisterContextLinux_* variant should be compiled into the final
- // executable.
- static NativeRegisterContextLinux*
- CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *reg_info_interface_p);
+
+ // This function is implemented in the NativeRegisterContextLinux_* subclasses
+ // to create a new
+ // instance of the host specific NativeRegisterContextLinux. The
+ // implementations can't collide
+ // as only one NativeRegisterContextLinux_* variant should be compiled into
+ // the final
+ // executable.
+ static NativeRegisterContextLinux *
+ CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
protected:
- lldb::ByteOrder
- GetByteOrder() const;
+ lldb::ByteOrder GetByteOrder() const;
- virtual Error
- ReadRegisterRaw(uint32_t reg_index, RegisterValue& reg_value);
+ virtual Error ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value);
- virtual Error
- WriteRegisterRaw(uint32_t reg_index, const RegisterValue& reg_value);
+ virtual Error WriteRegisterRaw(uint32_t reg_index,
+ const RegisterValue &reg_value);
- virtual Error
- ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset);
+ virtual Error ReadRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset);
- virtual Error
- WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset);
+ virtual Error WriteRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset);
- virtual Error
- ReadGPR();
+ virtual Error ReadGPR();
- virtual Error
- WriteGPR();
+ virtual Error WriteGPR();
- virtual Error
- ReadFPR();
+ virtual Error ReadFPR();
- virtual Error
- WriteFPR();
+ virtual Error WriteFPR();
- virtual void*
- GetGPRBuffer() { return nullptr; }
+ virtual void *GetGPRBuffer() { return nullptr; }
- virtual size_t
- GetGPRSize() { return GetRegisterInfoInterface().GetGPRSize(); }
+ virtual size_t GetGPRSize() {
+ return GetRegisterInfoInterface().GetGPRSize();
+ }
- virtual void*
- GetFPRBuffer() { return nullptr; }
+ virtual void *GetFPRBuffer() { return nullptr; }
- virtual size_t
- GetFPRSize() { return 0; }
+ virtual size_t GetFPRSize() { return 0; }
+ // The Do*** functions are executed on the privileged thread and can perform
+ // ptrace
+ // operations directly.
+ virtual Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value);
- // The Do*** functions are executed on the privileged thread and can perform ptrace
- // operations directly.
- virtual Error
- DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value);
+ virtual Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
+ const RegisterValue &value);
- virtual Error
- DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value);
+ virtual Error DoReadGPR(void *buf, size_t buf_size);
- virtual Error
- DoReadGPR(void *buf, size_t buf_size);
+ virtual Error DoWriteGPR(void *buf, size_t buf_size);
- virtual Error
- DoWriteGPR(void *buf, size_t buf_size);
+ virtual Error DoReadFPR(void *buf, size_t buf_size);
- virtual Error
- DoReadFPR(void *buf, size_t buf_size);
-
- virtual Error
- DoWriteFPR(void *buf, size_t buf_size);
+ virtual Error DoWriteFPR(void *buf, size_t buf_size);
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index 5dfbaff90891..9e857139cfca 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -22,21 +22,21 @@
#include <elf.h>
#include <sys/socket.h>
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
+#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(m_fpr))
#ifndef PTRACE_GETVFPREGS
- #define PTRACE_GETVFPREGS 27
- #define PTRACE_SETVFPREGS 28
+#define PTRACE_GETVFPREGS 27
+#define PTRACE_SETVFPREGS 28
#endif
#ifndef PTRACE_GETHBPREGS
- #define PTRACE_GETHBPREGS 29
- #define PTRACE_SETHBPREGS 30
+#define PTRACE_GETHBPREGS 29
+#define PTRACE_SETHBPREGS 30
#endif
#if !defined(PTRACE_TYPE_ARG3)
- #define PTRACE_TYPE_ARG3 void *
+#define PTRACE_TYPE_ARG3 void *
#endif
#if !defined(PTRACE_TYPE_ARG4)
- #define PTRACE_TYPE_ARG4 void *
+#define PTRACE_TYPE_ARG4 void *
#endif
using namespace lldb;
@@ -44,1084 +44,910 @@ using namespace lldb_private;
using namespace lldb_private::process_linux;
// arm general purpose registers.
-static const uint32_t g_gpr_regnums_arm[] =
-{
- gpr_r0_arm,
- gpr_r1_arm,
- gpr_r2_arm,
- gpr_r3_arm,
- gpr_r4_arm,
- gpr_r5_arm,
- gpr_r6_arm,
- gpr_r7_arm,
- gpr_r8_arm,
- gpr_r9_arm,
- gpr_r10_arm,
- gpr_r11_arm,
- gpr_r12_arm,
- gpr_sp_arm,
- gpr_lr_arm,
- gpr_pc_arm,
- gpr_cpsr_arm,
+static const uint32_t g_gpr_regnums_arm[] = {
+ gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm,
+ gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm,
+ gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm,
+ gpr_pc_arm, gpr_cpsr_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
+ k_num_gpr_registers_arm,
"g_gpr_regnums_arm has wrong number of register infos");
// arm floating point registers.
-static const uint32_t g_fpu_regnums_arm[] =
-{
- fpu_s0_arm,
- fpu_s1_arm,
- fpu_s2_arm,
- fpu_s3_arm,
- fpu_s4_arm,
- fpu_s5_arm,
- fpu_s6_arm,
- fpu_s7_arm,
- fpu_s8_arm,
- fpu_s9_arm,
- fpu_s10_arm,
- fpu_s11_arm,
- fpu_s12_arm,
- fpu_s13_arm,
- fpu_s14_arm,
- fpu_s15_arm,
- fpu_s16_arm,
- fpu_s17_arm,
- fpu_s18_arm,
- fpu_s19_arm,
- fpu_s20_arm,
- fpu_s21_arm,
- fpu_s22_arm,
- fpu_s23_arm,
- fpu_s24_arm,
- fpu_s25_arm,
- fpu_s26_arm,
- fpu_s27_arm,
- fpu_s28_arm,
- fpu_s29_arm,
- fpu_s30_arm,
- fpu_s31_arm,
- fpu_fpscr_arm,
- fpu_d0_arm,
- fpu_d1_arm,
- fpu_d2_arm,
- fpu_d3_arm,
- fpu_d4_arm,
- fpu_d5_arm,
- fpu_d6_arm,
- fpu_d7_arm,
- fpu_d8_arm,
- fpu_d9_arm,
- fpu_d10_arm,
- fpu_d11_arm,
- fpu_d12_arm,
- fpu_d13_arm,
- fpu_d14_arm,
- fpu_d15_arm,
- fpu_d16_arm,
- fpu_d17_arm,
- fpu_d18_arm,
- fpu_d19_arm,
- fpu_d20_arm,
- fpu_d21_arm,
- fpu_d22_arm,
- fpu_d23_arm,
- fpu_d24_arm,
- fpu_d25_arm,
- fpu_d26_arm,
- fpu_d27_arm,
- fpu_d28_arm,
- fpu_d29_arm,
- fpu_d30_arm,
- fpu_d31_arm,
- fpu_q0_arm,
- fpu_q1_arm,
- fpu_q2_arm,
- fpu_q3_arm,
- fpu_q4_arm,
- fpu_q5_arm,
- fpu_q6_arm,
- fpu_q7_arm,
- fpu_q8_arm,
- fpu_q9_arm,
- fpu_q10_arm,
- fpu_q11_arm,
- fpu_q12_arm,
- fpu_q13_arm,
- fpu_q14_arm,
+static const uint32_t g_fpu_regnums_arm[] = {
+ fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm,
+ fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm,
+ fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm,
+ fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm,
+ fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm,
+ fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm,
+ fpu_s30_arm, fpu_s31_arm, fpu_fpscr_arm, fpu_d0_arm, fpu_d1_arm,
+ fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, fpu_d5_arm, fpu_d6_arm,
+ fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, fpu_d10_arm, fpu_d11_arm,
+ fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, fpu_d15_arm, fpu_d16_arm,
+ fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, fpu_d20_arm, fpu_d21_arm,
+ fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, fpu_d25_arm, fpu_d26_arm,
+ fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, fpu_d30_arm, fpu_d31_arm,
+ fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm,
+ fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm,
+ fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm,
fpu_q15_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
+ k_num_fpr_registers_arm,
"g_fpu_regnums_arm has wrong number of register infos");
namespace {
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 2
- };
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
}
// Register sets for arm.
-static const RegisterSet
-g_reg_sets_arm[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
-};
+static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
+ g_gpr_regnums_arm},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
+ g_fpu_regnums_arm}};
#if defined(__arm__)
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx);
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_arm(target_arch, native_thread,
+ concrete_frame_idx);
}
#endif // defined(__arm__)
-NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm(target_arch))
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- m_reg_info.num_registers = k_num_registers_arm;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
- m_reg_info.last_gpr = k_last_gpr_arm;
- m_reg_info.first_fpr = k_first_fpr_arm;
- m_reg_info.last_fpr = k_last_fpr_arm;
- m_reg_info.first_fpr_v = fpu_s0_arm;
- m_reg_info.last_fpr_v = fpu_s31_arm;
- m_reg_info.gpr_flags = gpr_cpsr_arm;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof (m_fpr));
- ::memset(&m_gpr_arm, 0, sizeof (m_gpr_arm));
- ::memset(&m_hwp_regs, 0, sizeof (m_hwp_regs));
-
- // 16 is just a maximum value, query hardware for actual watchpoint count
- m_max_hwp_supported = 16;
- m_max_hbp_supported = 16;
- m_refresh_hwdebug_info = true;
+NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ new RegisterContextLinux_arm(target_arch)) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ m_reg_info.num_registers = k_num_registers_arm;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
+ m_reg_info.last_gpr = k_last_gpr_arm;
+ m_reg_info.first_fpr = k_first_fpr_arm;
+ m_reg_info.last_fpr = k_last_fpr_arm;
+ m_reg_info.first_fpr_v = fpu_s0_arm;
+ m_reg_info.last_fpr_v = fpu_s31_arm;
+ m_reg_info.gpr_flags = gpr_cpsr_arm;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ ::memset(&m_fpr, 0, sizeof(m_fpr));
+ ::memset(&m_gpr_arm, 0, sizeof(m_gpr_arm));
+ ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+
+ // 16 is just a maximum value, query hardware for actual watchpoint count
+ m_max_hwp_supported = 16;
+ m_max_hbp_supported = 16;
+ m_refresh_hwdebug_info = true;
+}
+
+uint32_t NativeRegisterContextLinux_arm::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+uint32_t NativeRegisterContextLinux_arm::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_arm[set_index].num_registers;
+ return count;
}
-uint32_t
-NativeRegisterContextLinux_arm::GetRegisterSetCount () const
-{
- return k_num_register_sets;
-}
+const RegisterSet *
+NativeRegisterContextLinux_arm::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_arm[set_index];
-uint32_t
-NativeRegisterContextLinux_arm::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_arm[set_index].num_registers;
- return count;
+ return nullptr;
}
-const RegisterSet *
-NativeRegisterContextLinux_arm::GetRegisterSet (uint32_t set_index) const
-{
- if (set_index < k_num_register_sets)
- return &g_reg_sets_arm[set_index];
+Error NativeRegisterContextLinux_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Error error;
- return nullptr;
-}
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
-Error
-NativeRegisterContextLinux_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
+ if (IsFPR(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ error = ReadRegisterRaw(full_reg, reg_value);
- if (IsFPR(reg))
- {
- error = ReadFPR();
- if (error.Fail())
- return error;
- }
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- error = ReadRegisterRaw(full_reg, reg_value);
-
- if (error.Success ())
- {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
-
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
- }
+ if (error.Success()) {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
+ // one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
- // Get pointer to m_fpr variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- reg_value.SetUInt16(*(uint16_t *)src);
- break;
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- case 16:
- reg_value.SetBytes(src, 16, GetByteOrder());
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
- break;
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (reg_value.GetByteSize() > reg_info->byte_size)
+ reg_value.SetType(reg_info);
}
-
return error;
-}
-
-Error
-NativeRegisterContextLinux_arm::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error ("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index))
- {
- // Get pointer to m_fpr variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
- }
-
- Error error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Error ();
+ }
+
+ // Get pointer to m_fpr variable and set the data from it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ reg_value.SetUInt16(*(uint16_t *)src);
+ break;
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ case 16:
+ reg_value.SetBytes(src, 16, GetByteOrder());
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
+ }
+
+ return error;
+}
+
+Error NativeRegisterContextLinux_arm::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ if (IsGPR(reg_index))
+ return WriteRegisterRaw(reg_index, reg_value);
+
+ if (IsFPR(reg_index)) {
+ // Get pointer to m_fpr variable and set the data to it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ *(uint16_t *)dst = reg_value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled register data size %" PRIu32,
+ reg_info->byte_size);
}
- return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
-}
-
-Error
-NativeRegisterContextLinux_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+ Error error = WriteFPR();
+ if (error.Fail())
+ return error;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, (uint64_t)REG_CONTEXT_SIZE);
+ return Error();
+ }
- error = ReadGPR();
- if (error.Fail())
- return error;
+ return Error("failed - register wasn't recognized to be a GPR or an FPR, "
+ "write strategy unknown");
+}
- error = ReadFPR();
- if (error.Fail())
- return error;
+Error NativeRegisterContextLinux_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", (uint64_t)REG_CONTEXT_SIZE);
- return error;
- }
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ return Error("failed to allocate DataBufferHeap instance of size %" PRIu64,
+ (uint64_t)REG_CONTEXT_SIZE);
- ::memcpy (dst, &m_gpr_arm, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+ error = ReadFPR();
+ if (error.Fail())
return error;
-}
-Error
-NativeRegisterContextLinux_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ (uint64_t)REG_CONTEXT_SIZE);
+ return error;
+ }
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ ::memcpy(dst, &m_gpr_arm, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ return error;
+}
+Error NativeRegisterContextLinux_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
- ::memcpy (&m_gpr_arm, src, GetRegisterInfoInterface ().GetGPRSize ());
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
- error = WriteGPR();
- if (error.Fail())
- return error;
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr_arm, src, GetRegisterInfoInterface().GetGPRSize());
- src += GetRegisterInfoInterface ().GetGPRSize ();
- ::memcpy (&m_fpr, src, sizeof(m_fpr));
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
- error = WriteFPR();
- if (error.Fail())
- return error;
+ src += GetRegisterInfoInterface().GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof(m_fpr));
+ error = WriteFPR();
+ if (error.Fail())
return error;
+
+ return error;
}
-bool
-NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool
-NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
uint32_t
-NativeRegisterContextLinux_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+NativeRegisterContextLinux_arm::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, bp_index = 0;
-
- // Check if size has a valid hardware breakpoint length.
- // Thumb instructions are 2-bytes but we have no way here to determine
- // if target address is a thumb or arm instruction.
- // TODO: Add support for setting thumb mode hardware breakpoints
- if (size != 4 && size != 2)
- return LLDB_INVALID_INDEX32;
-
- // Setup control value
- // Make the byte_mask into a valid Byte Address Select mask
- control_value = 0xfu << 5;
-
- // Enable this breakpoint and make it stop in privileged or user mode;
- control_value |= 7;
-
- // Make sure bits 1:0 are clear in our address
- // This should be different once we support thumb here.
- addr &= ~((lldb::addr_t)3);
-
- // Iterate over stored hardware breakpoints
- // Find a free bp_index or update reference count if duplicate.
- bp_index = LLDB_INVALID_INDEX32;
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++)
- {
- if ((m_hbr_regs[i].control & 1) == 0)
- {
- bp_index = i; // Mark last free slot
- }
- else if (m_hbr_regs[i].address == addr && m_hbr_regs[i].control == control_value)
- {
- bp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ uint32_t control_value = 0, bp_index = 0;
+
+ // Check if size has a valid hardware breakpoint length.
+ // Thumb instructions are 2-bytes but we have no way here to determine
+ // if target address is a thumb or arm instruction.
+ // TODO: Add support for setting thumb mode hardware breakpoints
+ if (size != 4 && size != 2)
+ return LLDB_INVALID_INDEX32;
+
+ // Setup control value
+ // Make the byte_mask into a valid Byte Address Select mask
+ control_value = 0xfu << 5;
+
+ // Enable this breakpoint and make it stop in privileged or user mode;
+ control_value |= 7;
+
+ // Make sure bits 1:0 are clear in our address
+ // This should be different once we support thumb here.
+ addr &= ~((lldb::addr_t)3);
+
+ // Iterate over stored hardware breakpoints
+ // Find a free bp_index or update reference count if duplicate.
+ bp_index = LLDB_INVALID_INDEX32;
+
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if ((m_hbr_regs[i].control & 1) == 0) {
+ bp_index = i; // Mark last free slot
+ } else if (m_hbr_regs[i].address == addr &&
+ m_hbr_regs[i].control == control_value) {
+ bp_index = i; // Mark duplicate index
+ break; // Stop searching here
}
+ }
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
- // Add new or update existing breakpoint
- if ((m_hbr_regs[bp_index].control & 1) == 0)
- {
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
- m_hbr_regs[bp_index].refcount = 1;
+ // Add new or update existing breakpoint
+ if ((m_hbr_regs[bp_index].control & 1) == 0) {
+ m_hbr_regs[bp_index].address = addr;
+ m_hbr_regs[bp_index].control = control_value;
+ m_hbr_regs[bp_index].refcount = 1;
- // PTRACE call to set corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index);
+ // PTRACE call to set corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index);
- if (error.Fail())
- {
- m_hbr_regs[bp_index].address = 0;
- m_hbr_regs[bp_index].control &= ~1;
- m_hbr_regs[bp_index].refcount = 0;
+ if (error.Fail()) {
+ m_hbr_regs[bp_index].address = 0;
+ m_hbr_regs[bp_index].control &= ~1;
+ m_hbr_regs[bp_index].refcount = 0;
- return LLDB_INVALID_INDEX32;
- }
+ return LLDB_INVALID_INDEX32;
}
- else
- m_hbr_regs[bp_index].refcount++;
+ } else
+ m_hbr_regs[bp_index].refcount++;
- return bp_index;
+ return bp_index;
}
-bool
-NativeRegisterContextLinux_arm::ClearHardwareBreakpoint (uint32_t hw_idx)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm::ClearHardwareBreakpoint(uint32_t hw_idx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return false;
+ if (error.Fail())
+ return false;
- if (hw_idx >= m_max_hbp_supported)
- return false;
+ if (hw_idx >= m_max_hbp_supported)
+ return false;
- // Update reference count if multiple references.
- if (m_hbr_regs[hw_idx].refcount > 1)
- {
- m_hbr_regs[hw_idx].refcount--;
- return true;
- }
- else if (m_hbr_regs[hw_idx].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
- uint32_t tempControl = m_hbr_regs[hw_idx].control;
- uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
- m_hbr_regs[hw_idx].refcount = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
-
- if (error.Fail())
- {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
- m_hbr_regs[hw_idx].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
+ // Update reference count if multiple references.
+ if (m_hbr_regs[hw_idx].refcount > 1) {
+ m_hbr_regs[hw_idx].refcount--;
+ return true;
+ } else if (m_hbr_regs[hw_idx].refcount == 1) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
+ uint32_t tempControl = m_hbr_regs[hw_idx].control;
+ uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
+
+ m_hbr_regs[hw_idx].control &= ~1;
+ m_hbr_regs[hw_idx].address = 0;
+ m_hbr_regs[hw_idx].refcount = 0;
+
+ // PTRACE call to clear corresponding hardware breakpoint register.
+ WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
+
+ if (error.Fail()) {
+ m_hbr_regs[hw_idx].control = tempControl;
+ m_hbr_regs[hw_idx].address = tempAddr;
+ m_hbr_regs[hw_idx].refcount = tempRefCount;
+
+ return false;
}
- return false;
+ return true;
+ }
+
+ return false;
}
-uint32_t
-NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return 0;
+ if (error.Fail())
+ return 0;
- return m_max_hwp_supported;
+ return m_max_hwp_supported;
}
-uint32_t
-NativeRegisterContextLinux_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- Error error;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ Error error;
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
- lldb::addr_t real_addr = addr;
-
- // Check if we are setting watchpoint other than read/write/access
- // Also update watchpoint flag to match Arm write-read bit configuration.
- switch (watch_flags)
- {
- case 1:
- watch_flags = 2;
- break;
- case 2:
- watch_flags = 1;
- break;
- case 3:
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- // Can't watch zero bytes
- // Can't watch more than 4 bytes per WVR/WCR pair
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- if (size == 0 || size > 4)
- return LLDB_INVALID_INDEX32;
+ uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
+ lldb::addr_t real_addr = addr;
- // Check 4-byte alignment for hardware watchpoint target address.
- // Below is a hack to recalculate address and size in order to
- // make sure we can watch non 4-byte alligned addresses as well.
- if (addr & 0x03)
- {
- uint8_t watch_mask = (addr & 0x03) + size;
+ // Check if we are setting watchpoint other than read/write/access
+ // Also update watchpoint flag to match Arm write-read bit configuration.
+ switch (watch_flags) {
+ case 1:
+ watch_flags = 2;
+ break;
+ case 2:
+ watch_flags = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
- if (watch_mask > 0x04)
- return LLDB_INVALID_INDEX32;
- else if (watch_mask <= 0x02)
- size = 2;
- else if (watch_mask <= 0x04)
- size = 4;
+ // Can't watch zero bytes
+ // Can't watch more than 4 bytes per WVR/WCR pair
- addr = addr & (~0x03);
- }
+ if (size == 0 || size > 4)
+ return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
- // per watchpoint register pair, so make sure we can properly encode this.
- addr_word_offset = addr % 4;
- byte_mask = ((1u << size) - 1u) << addr_word_offset;
-
- // Check if we need multiple watchpoint register
- if (byte_mask > 0xfu)
- return LLDB_INVALID_INDEX32;
-
- // Setup control value
- // Make the byte_mask into a valid Byte Address Select mask
- control_value = byte_mask << 5;
-
- //Turn on appropriate watchpoint flags read or write
- control_value |= (watch_flags << 3);
-
- // Enable this watchpoint and make it stop in privileged or user mode;
- control_value |= 7;
-
- // Make sure bits 1:0 are clear in our address
- addr &= ~((lldb::addr_t)3);
-
- // Iterate over stored watchpoints
- // Find a free wp_index or update reference count if duplicate.
- wp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if ((m_hwp_regs[i].control & 1) == 0)
- {
- wp_index = i; // Mark last free slot
- }
- else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value)
- {
- wp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
- }
+ // Check 4-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 4-byte alligned addresses as well.
+ if (addr & 0x03) {
+ uint8_t watch_mask = (addr & 0x03) + size;
- if (wp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Add new or update existing watchpoint
- if ((m_hwp_regs[wp_index].control & 1) == 0)
- {
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].real_addr = real_addr;
- m_hwp_regs[wp_index].address = addr;
- m_hwp_regs[wp_index].control = control_value;
- m_hwp_regs[wp_index].refcount = 1;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].refcount = 0;
-
- return LLDB_INVALID_INDEX32;
- }
- }
- else
- m_hwp_regs[wp_index].refcount++;
+ if (watch_mask > 0x04)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
- return wp_index;
-}
+ addr = addr & (~0x03);
+ }
-bool
-NativeRegisterContextLinux_arm::ClearHardwareWatchpoint (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ // We can only watch up to four bytes that follow a 4 byte aligned address
+ // per watchpoint register pair, so make sure we can properly encode this.
+ addr_word_offset = addr % 4;
+ byte_mask = ((1u << size) - 1u) << addr_word_offset;
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ // Check if we need multiple watchpoint register
+ if (byte_mask > 0xfu)
+ return LLDB_INVALID_INDEX32;
- Error error;
+ // Setup control value
+ // Make the byte_mask into a valid Byte Address Select mask
+ control_value = byte_mask << 5;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Turn on appropriate watchpoint flags read or write
+ control_value |= (watch_flags << 3);
- if (error.Fail())
- return false;
+ // Enable this watchpoint and make it stop in privileged or user mode;
+ control_value |= 7;
- if (wp_index >= m_max_hwp_supported)
- return false;
+ // Make sure bits 1:0 are clear in our address
+ addr &= ~((lldb::addr_t)3);
- // Update reference count if multiple references.
- if (m_hwp_regs[wp_index].refcount > 1)
- {
- m_hwp_regs[wp_index].refcount--;
- return true;
- }
- else if (m_hwp_regs[wp_index].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
- uint32_t tempControl = m_hwp_regs[wp_index].control;
- uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
- m_hwp_regs[wp_index].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if ((m_hwp_regs[i].control & 1) == 0) {
+ wp_index = i; // Mark last free slot
+ } else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
}
+ }
- return false;
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
+ m_hwp_regs[wp_index].address = addr;
+ m_hwp_regs[wp_index].control = control_value;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= ~1;
+
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
}
-Error
-NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return error;
+ if (error.Fail())
+ return false;
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0, tempRefCount = 0;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if (m_hwp_regs[i].control & 0x01)
- {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hwp_regs[i].address;
- tempControl = m_hwp_regs[i].control;
- tempRefCount = m_hwp_regs[i].refcount;
-
- // Clear watchpoints in local cache
- m_hwp_regs[i].control &= ~1;
- m_hwp_regs[i].address = 0;
- m_hwp_regs[i].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
-
- if (error.Fail())
- {
- m_hwp_regs[i].control = tempControl;
- m_hwp_regs[i].address = tempAddr;
- m_hwp_regs[i].refcount = tempRefCount;
-
- return error;
- }
- }
- }
+ if (wp_index >= m_max_hwp_supported)
+ return false;
- return Error();
-}
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
-uint32_t
-NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f)
- {
- case 0x01:
- return 1;
- case 0x03:
- return 2;
- case 0x07:
- return 3;
- case 0x0f:
- return 4;
- default:
- return 0;
- }
-}
-bool
-NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= ~1;
+ m_hwp_regs[wp_index].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
+
+ return false;
+ }
+
+ return true;
}
-Error
-NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+Error NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- uint32_t watch_size;
- lldb::addr_t watch_addr;
+ Error error;
- for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index)
- {
- watch_size = GetWatchpointSize (wp_index);
- watch_addr = m_hwp_regs[wp_index].address;
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
- && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
- {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Error();
- }
- }
+ if (error.Fail())
+ return error;
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
-}
+ lldb::addr_t tempAddr = 0;
+ uint32_t tempControl = 0;
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (m_hwp_regs[i].control & 0x01) {
+ // Create a backup we can revert to in case of failure.
+ tempAddr = m_hwp_regs[i].address;
+ tempControl = m_hwp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hwp_regs[i].control &= ~1;
+ m_hwp_regs[i].address = 0;
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ if (error.Fail()) {
+ m_hwp_regs[i].control = tempControl;
+ m_hwp_regs[i].address = tempAddr;
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].real_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ return error;
+ }
+ }
+ }
+
+ return Error();
}
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointHitAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) {
+ case 0x01:
+ return 1;
+ case 0x03:
+ return 2;
+ case 0x07:
+ return 3;
+ case 0x0f:
+ return 4;
+ default:
+ return 0;
+ }
+}
+bool NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+
+ if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
+ return true;
+ else
+ return false;
}
-Error
-NativeRegisterContextLinux_arm::ReadHardwareDebugInfo()
-{
- Error error;
+Error NativeRegisterContextLinux_arm::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
- if (!m_refresh_hwdebug_info)
- {
- return Error();
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr < watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Error();
}
+ }
- unsigned int cap_val;
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
+}
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), nullptr, &cap_val, sizeof(unsigned int));
+lldb::addr_t
+NativeRegisterContextLinux_arm::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (error.Fail())
- return error;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- m_max_hwp_supported = (cap_val >> 8) & 0xff;
- m_max_hbp_supported = cap_val & 0xff;
- m_refresh_hwdebug_info = false;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- return error;
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
-Error
-NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_index)
-{
- Error error;
+lldb::addr_t
+NativeRegisterContextLinux_arm::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- lldb::addr_t *addr_buf;
- uint32_t *ctrl_buf;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- if (hwbType == eDREGTypeWATCH)
- {
- addr_buf = &m_hwp_regs[hwb_index].address;
- ctrl_buf = &m_hwp_regs[hwb_index].control;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 1),
- addr_buf, sizeof(unsigned int));
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
- if (error.Fail())
- return error;
+Error NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() {
+ Error error;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 2),
- ctrl_buf, sizeof(unsigned int));
- }
- else
- {
- addr_buf = &m_hwp_regs[hwb_index].address;
- ctrl_buf = &m_hwp_regs[hwb_index].control;
+ if (!m_refresh_hwdebug_info) {
+ return Error();
+ }
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 1),
- addr_buf, sizeof(unsigned int));
+ unsigned int cap_val;
- if (error.Fail())
- return error;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(),
+ nullptr, &cap_val,
+ sizeof(unsigned int));
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 2),
- ctrl_buf, sizeof(unsigned int));
+ if (error.Fail())
+ return error;
- }
+ m_max_hwp_supported = (cap_val >> 8) & 0xff;
+ m_max_hbp_supported = cap_val & 0xff;
+ m_refresh_hwdebug_info = false;
- return error;
+ return error;
}
-uint32_t
-NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info) const
-{
- return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
-}
+Error NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType,
+ int hwb_index) {
+ Error error;
+
+ lldb::addr_t *addr_buf;
+ uint32_t *ctrl_buf;
+
+ if (hwbType == eDREGTypeWATCH) {
+ addr_buf = &m_hwp_regs[hwb_index].address;
+ ctrl_buf = &m_hwp_regs[hwb_index].control;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 1), addr_buf,
+ sizeof(unsigned int));
-Error
-NativeRegisterContextLinux_arm::DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value)
-{
- // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android devices (always return
- // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR register set instead.
- // This approach is about 4 times slower but the performance overhead is negligible in
- // comparision to processing time in lldb-server.
- assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
- if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
- return Error("Register isn't fit into the size of the GPR area");
-
- Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
if (error.Fail())
- return error;
+ return error;
- value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
- return Error();
-}
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 2), ctrl_buf,
+ sizeof(unsigned int));
+ } else {
+ addr_buf = &m_hwp_regs[hwb_index].address;
+ ctrl_buf = &m_hwp_regs[hwb_index].control;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 1), addr_buf,
+ sizeof(unsigned int));
-Error
-NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value)
-{
- // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android devices (always return
- // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify
- // the requested register and write it back. This approach is about 4 times slower but the
- // performance overhead is negligible in comparision to processing time in lldb-server.
- assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
- if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
- return Error("Register isn't fit into the size of the GPR area");
-
- Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
if (error.Fail())
- return error;
+ return error;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 2), ctrl_buf,
+ sizeof(unsigned int));
+ }
+
+ return error;
+}
+
+uint32_t NativeRegisterContextLinux_arm::CalculateFprOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
+}
+
+Error NativeRegisterContextLinux_arm::DoReadRegisterValue(
+ uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value) {
+ // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android
+ // devices (always return
+ // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR
+ // register set instead.
+ // This approach is about 4 times slower but the performance overhead is
+ // negligible in
+ // comparision to processing time in lldb-server.
+ assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
+ if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
+ return Error("Register isn't fit into the size of the GPR area");
+
+ Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
+ if (error.Fail())
+ return error;
+
+ value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
+ return Error();
+}
+
+Error NativeRegisterContextLinux_arm::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android
+ // devices (always return
+ // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR
+ // register set, modify
+ // the requested register and write it back. This approach is about 4 times
+ // slower but the
+ // performance overhead is negligible in comparision to processing time in
+ // lldb-server.
+ assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
+ if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
+ return Error("Register isn't fit into the size of the GPR area");
+
+ Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
+ if (error.Fail())
+ return error;
- uint32_t reg_value = value.GetAsUInt32();
- // As precaution for an undefined behavior encountered while setting PC we
- // will clear thumb bit of new PC if we are already in thumb mode; that is
- // CPSR thumb mode bit is set.
- if (offset / sizeof(uint32_t) == gpr_pc_arm)
- {
- // Check if we are already in thumb mode and
- // thumb bit of current PC is read out to be zero and
- // thumb bit of next PC is read out to be one.
- if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) &&
- !(m_gpr_arm[gpr_pc_arm] & 0x01) &&
- (value.GetAsUInt32() & 0x01))
- {
- reg_value &= (~1ull);
- }
+ uint32_t reg_value = value.GetAsUInt32();
+ // As precaution for an undefined behavior encountered while setting PC we
+ // will clear thumb bit of new PC if we are already in thumb mode; that is
+ // CPSR thumb mode bit is set.
+ if (offset / sizeof(uint32_t) == gpr_pc_arm) {
+ // Check if we are already in thumb mode and
+ // thumb bit of current PC is read out to be zero and
+ // thumb bit of next PC is read out to be one.
+ if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) && !(m_gpr_arm[gpr_pc_arm] & 0x01) &&
+ (value.GetAsUInt32() & 0x01)) {
+ reg_value &= (~1ull);
}
+ }
- m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
- return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
+ m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
+ return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
}
-Error
-NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
+ return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
- return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
+ return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
#endif // __arm__
}
-Error
-NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
+ return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
- return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
+ return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
#endif // __arm__
}
-Error
-NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS,
- m_thread.GetID(),
- nullptr,
- buf,
- buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+
+ return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
#endif // __arm__
}
-Error
-NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS,
- m_thread.GetID(),
- nullptr,
- buf,
- buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+
+ return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
#endif // __arm__
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index 452f13258c2b..f979811216dc 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -18,181 +18,142 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_arm (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_arm(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint mangement functions
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Hardware breakpoints/watchpoint mangement functions
+ //------------------------------------------------------------------
- uint32_t
- SetHardwareBreakpoint (lldb::addr_t addr, size_t size) override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- bool
- ClearHardwareBreakpoint (uint32_t hw_idx) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- uint32_t
- NumSupportedHardwareWatchpoints () override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t
- SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- bool
- ClearHardwareWatchpoint (uint32_t hw_index) override;
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- lldb::addr_t
- GetWatchpointHitAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
- lldb::addr_t
- GetWatchpointAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- GetWatchpointSize(uint32_t wp_index);
+ uint32_t GetWatchpointSize(uint32_t wp_index);
- bool
- WatchpointIsEnabled(uint32_t wp_index);
+ bool WatchpointIsEnabled(uint32_t wp_index);
- // Debug register type select
- enum DREGType
- {
- eDREGTypeWATCH = 0,
- eDREGTypeBREAK
- };
+ // Debug register type select
+ enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
- protected:
- Error
- DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value) override;
+protected:
+ Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value) override;
- Error
- DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
+ Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value) override;
- Error
- DoReadGPR(void *buf, size_t buf_size) override;
+ Error DoReadGPR(void *buf, size_t buf_size) override;
- Error
- DoWriteGPR(void *buf, size_t buf_size) override;
+ Error DoWriteGPR(void *buf, size_t buf_size) override;
- Error
- DoReadFPR(void *buf, size_t buf_size) override;
+ Error DoReadFPR(void *buf, size_t buf_size) override;
- Error
- DoWriteFPR(void *buf, size_t buf_size) override;
+ Error DoWriteFPR(void *buf, size_t buf_size) override;
- void*
- GetGPRBuffer() override { return &m_gpr_arm; }
+ void *GetGPRBuffer() override { return &m_gpr_arm; }
- void*
- GetFPRBuffer() override { return &m_fpr; }
+ void *GetFPRBuffer() override { return &m_fpr; }
- size_t
- GetFPRSize() override { return sizeof(m_fpr); }
+ size_t GetFPRSize() override { return sizeof(m_fpr); }
- private:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+private:
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
- uint32_t gpr_flags;
- };
+ uint32_t gpr_flags;
+ };
- struct QReg
- {
- uint8_t bytes[16];
- };
+ struct QReg {
+ uint8_t bytes[16];
+ };
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
- uint32_t m_gpr_arm[k_num_gpr_registers_arm];
- RegInfo m_reg_info;
- FPU m_fpr;
+ uint32_t m_gpr_arm[k_num_gpr_registers_arm];
+ RegInfo m_reg_info;
+ FPU m_fpr;
- // Debug register info for hardware breakpoints and watchpoints management.
- struct DREG
- {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and refernce counter.
- };
+ // Debug register info for hardware breakpoints and watchpoints management.
+ struct DREG {
+ lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
+ // occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
+ uint32_t control; // Breakpoint/watchpoint control value.
+ uint32_t refcount; // Serves as enable/disable and refernce counter.
+ };
- struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
- struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
+ struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
+ struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
- uint32_t m_max_hwp_supported;
- uint32_t m_max_hbp_supported;
- bool m_refresh_hwdebug_info;
+ uint32_t m_max_hwp_supported;
+ uint32_t m_max_hbp_supported;
+ bool m_refresh_hwdebug_info;
- bool
- IsGPR(unsigned reg) const;
+ bool IsGPR(unsigned reg) const;
- bool
- IsFPR(unsigned reg) const;
+ bool IsFPR(unsigned reg) const;
- Error
- ReadHardwareDebugInfo();
+ Error ReadHardwareDebugInfo();
- Error
- WriteHardwareDebugRegs(int hwbType, int hwb_index);
+ Error WriteHardwareDebugRegs(int hwbType, int hwb_index);
- uint32_t
- CalculateFprOffset(const RegisterInfo* reg_info) const;
- };
+ uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 9489f00c1afe..786778e25a24 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__arm64__) || defined (__aarch64__)
+#if defined(__arm64__) || defined(__aarch64__)
#include "NativeRegisterContextLinux_arm.h"
#include "NativeRegisterContextLinux_arm64.h"
@@ -25,9 +25,10 @@
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Linux/Procfs.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
-// System includes - They have to be included after framework includes because they define some
+// System includes - They have to be included after framework includes because
+// they define some
// macros which collide with variable names in other modules
#include <sys/socket.h>
// NT_PRSTATUS and NT_FPREGSET definition
@@ -42,1051 +43,931 @@ using namespace lldb_private;
using namespace lldb_private::process_linux;
// ARM64 general purpose registers.
-static const uint32_t g_gpr_regnums_arm64[] =
-{
- gpr_x0_arm64,
- gpr_x1_arm64,
- gpr_x2_arm64,
- gpr_x3_arm64,
- gpr_x4_arm64,
- gpr_x5_arm64,
- gpr_x6_arm64,
- gpr_x7_arm64,
- gpr_x8_arm64,
- gpr_x9_arm64,
- gpr_x10_arm64,
- gpr_x11_arm64,
- gpr_x12_arm64,
- gpr_x13_arm64,
- gpr_x14_arm64,
- gpr_x15_arm64,
- gpr_x16_arm64,
- gpr_x17_arm64,
- gpr_x18_arm64,
- gpr_x19_arm64,
- gpr_x20_arm64,
- gpr_x21_arm64,
- gpr_x22_arm64,
- gpr_x23_arm64,
- gpr_x24_arm64,
- gpr_x25_arm64,
- gpr_x26_arm64,
- gpr_x27_arm64,
- gpr_x28_arm64,
- gpr_fp_arm64,
- gpr_lr_arm64,
- gpr_sp_arm64,
- gpr_pc_arm64,
- gpr_cpsr_arm64,
+static const uint32_t g_gpr_regnums_arm64[] = {
+ gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,
+ gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,
+ gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,
+ gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,
+ gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,
+ gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,
+ gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,
+ gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,
+ gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,
+ gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,
+ gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,
+ gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,
+ gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,
+ gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,
+ gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,
+ gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - 1) == k_num_gpr_registers_arm64, \
+static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
+ 1) == k_num_gpr_registers_arm64,
"g_gpr_regnums_arm64 has wrong number of register infos");
// ARM64 floating point registers.
-static const uint32_t g_fpu_regnums_arm64[] =
-{
- fpu_v0_arm64,
- fpu_v1_arm64,
- fpu_v2_arm64,
- fpu_v3_arm64,
- fpu_v4_arm64,
- fpu_v5_arm64,
- fpu_v6_arm64,
- fpu_v7_arm64,
- fpu_v8_arm64,
- fpu_v9_arm64,
- fpu_v10_arm64,
- fpu_v11_arm64,
- fpu_v12_arm64,
- fpu_v13_arm64,
- fpu_v14_arm64,
- fpu_v15_arm64,
- fpu_v16_arm64,
- fpu_v17_arm64,
- fpu_v18_arm64,
- fpu_v19_arm64,
- fpu_v20_arm64,
- fpu_v21_arm64,
- fpu_v22_arm64,
- fpu_v23_arm64,
- fpu_v24_arm64,
- fpu_v25_arm64,
- fpu_v26_arm64,
- fpu_v27_arm64,
- fpu_v28_arm64,
- fpu_v29_arm64,
- fpu_v30_arm64,
- fpu_v31_arm64,
- fpu_fpsr_arm64,
- fpu_fpcr_arm64,
+static const uint32_t g_fpu_regnums_arm64[] = {
+ fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,
+ fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,
+ fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,
+ fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,
+ fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,
+ fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,
+ fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,
+ fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,
+ fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,
+ fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,
+ fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,
+ fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,
+ fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,
+ fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,
+ fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,
+ fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,
+
+ fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,
+ fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,
+ fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,
+ fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,
+ fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,
+ fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,
+ fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,
+ fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,
+ fpu_fpsr_arm64, fpu_fpcr_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - 1) == k_num_fpr_registers_arm64, \
+static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
+ 1) == k_num_fpr_registers_arm64,
"g_fpu_regnums_arm64 has wrong number of register infos");
namespace {
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 2
- };
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
}
// Register sets for ARM64.
-static const RegisterSet
-g_reg_sets_arm64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm64, g_gpr_regnums_arm64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 }
-};
-
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS);
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx);
- case llvm::Triple::aarch64:
- return new NativeRegisterContextLinux_arm64(target_arch, native_thread, concrete_frame_idx);
- default:
- if (log)
- log->Printf("NativeRegisterContextLinux::%s() have no register context for architecture: %s\n", __FUNCTION__,
- target_arch.GetTriple().getArchName().str().c_str());
- return nullptr;
- }
+static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
+ g_gpr_regnums_arm64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
+ g_fpu_regnums_arm64}};
+
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS);
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return new NativeRegisterContextLinux_arm(target_arch, native_thread,
+ concrete_frame_idx);
+ case llvm::Triple::aarch64:
+ return new NativeRegisterContextLinux_arm64(target_arch, native_thread,
+ concrete_frame_idx);
+ default:
+ if (log)
+ log->Printf("NativeRegisterContextLinux::%s() have no register context "
+ "for architecture: %s\n",
+ __FUNCTION__,
+ target_arch.GetTriple().getArchName().str().c_str());
+ return nullptr;
+ }
+}
+
+NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ new RegisterInfoPOSIX_arm64(target_arch)) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_reg_info.num_registers = k_num_registers_arm64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
+ m_reg_info.last_gpr = k_last_gpr_arm64;
+ m_reg_info.first_fpr = k_first_fpr_arm64;
+ m_reg_info.last_fpr = k_last_fpr_arm64;
+ m_reg_info.first_fpr_v = fpu_v0_arm64;
+ m_reg_info.last_fpr_v = fpu_v31_arm64;
+ m_reg_info.gpr_flags = gpr_cpsr_arm64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ ::memset(&m_fpr, 0, sizeof(m_fpr));
+ ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64));
+ ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+
+ // 16 is just a maximum value, query hardware for actual watchpoint count
+ m_max_hwp_supported = 16;
+ m_max_hbp_supported = 16;
+ m_refresh_hwdebug_info = true;
+}
+
+uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const {
+ return k_num_register_sets;
}
-NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm64(target_arch))
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- m_reg_info.num_registers = k_num_registers_arm64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
- m_reg_info.last_gpr = k_last_gpr_arm64;
- m_reg_info.first_fpr = k_first_fpr_arm64;
- m_reg_info.last_fpr = k_last_fpr_arm64;
- m_reg_info.first_fpr_v = fpu_v0_arm64;
- m_reg_info.last_fpr_v = fpu_v31_arm64;
- m_reg_info.gpr_flags = gpr_cpsr_arm64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof (m_fpr));
- ::memset(&m_gpr_arm64, 0, sizeof (m_gpr_arm64));
- ::memset(&m_hwp_regs, 0, sizeof (m_hwp_regs));
+const RegisterSet *
+NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_arm64[set_index];
- // 16 is just a maximum value, query hardware for actual watchpoint count
- m_max_hwp_supported = 16;
- m_max_hbp_supported = 16;
- m_refresh_hwdebug_info = true;
+ return nullptr;
}
-uint32_t
-NativeRegisterContextLinux_arm64::GetRegisterSetCount () const
-{
- return k_num_register_sets;
+uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_arm64[set_index].num_registers;
+ return count;
}
-const RegisterSet *
-NativeRegisterContextLinux_arm64::GetRegisterSet (uint32_t set_index) const
-{
- if (set_index < k_num_register_sets)
- return &g_reg_sets_arm64[set_index];
-
- return nullptr;
-}
+Error NativeRegisterContextLinux_arm64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ Error error;
-uint32_t
-NativeRegisterContextLinux_arm64::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_arm64[set_index].num_registers;
- return count;
-}
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
-Error
-NativeRegisterContextLinux_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
+ if (IsFPR(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ error = ReadRegisterRaw(full_reg, reg_value);
- if (IsFPR(reg))
- {
- error = ReadFPR();
- if (error.Fail())
- return error;
- }
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- error = ReadRegisterRaw(full_reg, reg_value);
-
- if (error.Success ())
- {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
-
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
+ if (error.Success()) {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
+ // one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
+
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (reg_value.GetByteSize() > reg_info->byte_size)
+ reg_value.SetType(reg_info);
}
+ return error;
+ }
- // Get pointer to m_fpr variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size, eByteOrderLittle, error);
+ // Get pointer to m_fpr variable and set the data from it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_arm64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error ("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index))
- {
- // Get pointer to m_fpr variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
- }
-
- Error error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Error ();
- }
+Error NativeRegisterContextLinux_arm64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
- return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
-}
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
-Error
-NativeRegisterContextLinux_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+ if (IsGPR(reg_index))
+ return WriteRegisterRaw(reg_index, reg_value);
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
+ if (IsFPR(reg_index)) {
+ // Get pointer to m_fpr variable and set the data to it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ *(uint16_t *)dst = reg_value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled register data size %" PRIu32,
+ reg_info->byte_size);
+ }
- error = ReadGPR();
+ Error error = WriteFPR();
if (error.Fail())
- return error;
+ return error;
- error = ReadFPR();
- if (error.Fail())
- return error;
+ return Error();
+ }
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
- return error;
- }
+ return Error("failed - register wasn't recognized to be a GPR or an FPR, "
+ "write strategy unknown");
+}
- ::memcpy (dst, &m_gpr_arm64, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+Error NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ return Error("failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+
+ error = ReadGPR();
+ if (error.Fail())
return error;
-}
-Error
-NativeRegisterContextLinux_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
+ return error;
+}
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
- ::memcpy (&m_gpr_arm64, src, GetRegisterInfoInterface ().GetGPRSize ());
+Error NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
- error = WriteGPR();
- if (error.Fail())
- return error;
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
- src += GetRegisterInfoInterface ().GetGPRSize ();
- ::memcpy (&m_fpr, src, sizeof(m_fpr));
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr_arm64, src, GetRegisterInfoInterface().GetGPRSize());
- error = WriteFPR();
- if (error.Fail())
- return error;
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
+ src += GetRegisterInfoInterface().GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof(m_fpr));
+
+ error = WriteFPR();
+ if (error.Fail())
return error;
+
+ return error;
}
-bool
-NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool
-NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
uint32_t
-NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Error error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, bp_index = 0;
-
- // Check if size has a valid hardware breakpoint length.
- if (size != 4)
- return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware breakpoint
-
- // Check 4-byte alignment for hardware breakpoint target address.
- if (addr & 0x03)
- return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
-
- // Setup control value
- control_value = 0;
- control_value |= ((1 << size) - 1) << 5;
- control_value |= (2 << 1) | 1;
-
- // Iterate over stored hardware breakpoints
- // Find a free bp_index or update reference count if duplicate.
- bp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hbp_supported; i++)
- {
- if ((m_hbr_regs[i].control & 1) == 0)
- {
- bp_index = i; // Mark last free slot
- }
- else if (m_hbr_regs[i].address == addr && m_hbr_regs[i].control == control_value)
- {
- bp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
+NativeRegisterContextLinux_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+
+ Error error;
+
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ uint32_t control_value = 0, bp_index = 0;
+
+ // Check if size has a valid hardware breakpoint length.
+ if (size != 4)
+ return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware
+ // breakpoint
+
+ // Check 4-byte alignment for hardware breakpoint target address.
+ if (addr & 0x03)
+ return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
+
+ // Setup control value
+ control_value = 0;
+ control_value |= ((1 << size) - 1) << 5;
+ control_value |= (2 << 1) | 1;
+
+ // Iterate over stored hardware breakpoints
+ // Find a free bp_index or update reference count if duplicate.
+ bp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if ((m_hbr_regs[i].control & 1) == 0) {
+ bp_index = i; // Mark last free slot
+ } else if (m_hbr_regs[i].address == addr &&
+ m_hbr_regs[i].control == control_value) {
+ bp_index = i; // Mark duplicate index
+ break; // Stop searching here
}
+ }
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
- // Add new or update existing breakpoint
- if ((m_hbr_regs[bp_index].control & 1) == 0)
- {
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
- m_hbr_regs[bp_index].refcount = 1;
+ // Add new or update existing breakpoint
+ if ((m_hbr_regs[bp_index].control & 1) == 0) {
+ m_hbr_regs[bp_index].address = addr;
+ m_hbr_regs[bp_index].control = control_value;
+ m_hbr_regs[bp_index].refcount = 1;
- // PTRACE call to set corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+ // PTRACE call to set corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
- if (error.Fail())
- {
- m_hbr_regs[bp_index].address = 0;
- m_hbr_regs[bp_index].control &= ~1;
- m_hbr_regs[bp_index].refcount = 0;
+ if (error.Fail()) {
+ m_hbr_regs[bp_index].address = 0;
+ m_hbr_regs[bp_index].control &= ~1;
+ m_hbr_regs[bp_index].refcount = 0;
- return LLDB_INVALID_INDEX32;
- }
+ return LLDB_INVALID_INDEX32;
}
- else
- m_hbr_regs[bp_index].refcount++;
+ } else
+ m_hbr_regs[bp_index].refcount++;
- return bp_index;
+ return bp_index;
}
-bool
-NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint (uint32_t hw_idx)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint(
+ uint32_t hw_idx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return false;
+ if (error.Fail())
+ return false;
- if (hw_idx >= m_max_hbp_supported)
- return false;
+ if (hw_idx >= m_max_hbp_supported)
+ return false;
- // Update reference count if multiple references.
- if (m_hbr_regs[hw_idx].refcount > 1)
- {
- m_hbr_regs[hw_idx].refcount--;
- return true;
- }
- else if (m_hbr_regs[hw_idx].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
- uint32_t tempControl = m_hbr_regs[hw_idx].control;
- uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
- m_hbr_regs[hw_idx].refcount = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- WriteHardwareDebugRegs(eDREGTypeBREAK);
-
- if (error.Fail())
- {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
- m_hbr_regs[hw_idx].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
+ // Update reference count if multiple references.
+ if (m_hbr_regs[hw_idx].refcount > 1) {
+ m_hbr_regs[hw_idx].refcount--;
+ return true;
+ } else if (m_hbr_regs[hw_idx].refcount == 1) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
+ uint32_t tempControl = m_hbr_regs[hw_idx].control;
+ uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
+
+ m_hbr_regs[hw_idx].control &= ~1;
+ m_hbr_regs[hw_idx].address = 0;
+ m_hbr_regs[hw_idx].refcount = 0;
+
+ // PTRACE call to clear corresponding hardware breakpoint register.
+ WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error.Fail()) {
+ m_hbr_regs[hw_idx].control = tempControl;
+ m_hbr_regs[hw_idx].address = tempAddr;
+ m_hbr_regs[hw_idx].refcount = tempRefCount;
+
+ return false;
}
- return false;
+ return true;
+ }
+
+ return false;
}
-uint32_t
-NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return 0;
+ if (error.Fail())
+ return 0;
- return m_max_hwp_supported;
+ return m_max_hwp_supported;
}
-uint32_t
-NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Error error;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ Error error;
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0;
- lldb::addr_t real_addr = addr;
-
- // Check if we are setting watchpoint other than read/write/access
- // Also update watchpoint flag to match AArch64 write-read bit configuration.
- switch (watch_flags)
- {
- case 1:
- watch_flags = 2;
- break;
- case 2:
- watch_flags = 1;
- break;
- case 3:
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- // Check if size has a valid hardware watchpoint length.
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return LLDB_INVALID_INDEX32;
-
- // Check 8-byte alignment for hardware watchpoint target address.
- // Below is a hack to recalculate address and size in order to
- // make sure we can watch non 8-byte alligned addresses as well.
- if (addr & 0x07)
- {
- uint8_t watch_mask = (addr & 0x07) + size;
-
- if (watch_mask > 0x08)
- return LLDB_INVALID_INDEX32;
- else if (watch_mask <= 0x02)
- size = 2;
- else if (watch_mask <= 0x04)
- size = 4;
- else
- size = 8;
-
- addr = addr & (~0x07);
- }
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- // Setup control value
- control_value = watch_flags << 3;
- control_value |= ((1 << size) - 1) << 5;
- control_value |= (2 << 1) | 1;
-
- // Iterate over stored watchpoints
- // Find a free wp_index or update reference count if duplicate.
- wp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if ((m_hwp_regs[i].control & 1) == 0)
- {
- wp_index = i; // Mark last free slot
- }
- else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value)
- {
- wp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
- }
+ uint32_t control_value = 0, wp_index = 0;
+ lldb::addr_t real_addr = addr;
- if (wp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Add new or update existing watchpoint
- if ((m_hwp_regs[wp_index].control & 1) == 0)
- {
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].real_addr = real_addr;
- m_hwp_regs[wp_index].address = addr;
- m_hwp_regs[wp_index].control = control_value;
- m_hwp_regs[wp_index].refcount = 1;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].refcount = 0;
-
- return LLDB_INVALID_INDEX32;
- }
- }
+ // Check if we are setting watchpoint other than read/write/access
+ // Also update watchpoint flag to match AArch64 write-read bit configuration.
+ switch (watch_flags) {
+ case 1:
+ watch_flags = 2;
+ break;
+ case 2:
+ watch_flags = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
+
+ // Check if size has a valid hardware watchpoint length.
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return LLDB_INVALID_INDEX32;
+
+ // Check 8-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 8-byte alligned addresses as well.
+ if (addr & 0x07) {
+ uint8_t watch_mask = (addr & 0x07) + size;
+
+ if (watch_mask > 0x08)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
else
- m_hwp_regs[wp_index].refcount++;
+ size = 8;
+
+ addr = addr & (~0x07);
+ }
+
+ // Setup control value
+ control_value = watch_flags << 3;
+ control_value |= ((1 << size) - 1) << 5;
+ control_value |= (2 << 1) | 1;
+
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if ((m_hwp_regs[i].control & 1) == 0) {
+ wp_index = i; // Mark last free slot
+ } else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
+ }
+ }
+
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
+ m_hwp_regs[wp_index].address = addr;
+ m_hwp_regs[wp_index].control = control_value;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= ~1;
- return wp_index;
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
}
-bool
-NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return false;
+ if (error.Fail())
+ return false;
- if (wp_index >= m_max_hwp_supported)
- return false;
+ if (wp_index >= m_max_hwp_supported)
+ return false;
- // Update reference count if multiple references.
- if (m_hwp_regs[wp_index].refcount > 1)
- {
- m_hwp_regs[wp_index].refcount--;
- return true;
- }
- else if (m_hwp_regs[wp_index].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
- uint32_t tempControl = m_hwp_regs[wp_index].control;
- uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
- m_hwp_regs[wp_index].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
- }
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= ~1;
+ m_hwp_regs[wp_index].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
return false;
+ }
+
+ return true;
}
-Error
-NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+Error NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return error;
+ if (error.Fail())
+ return error;
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0, tempRefCount = 0;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if (m_hwp_regs[i].control & 0x01)
- {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hwp_regs[i].address;
- tempControl = m_hwp_regs[i].control;
- tempRefCount = m_hwp_regs[i].refcount;
-
- // Clear watchpoints in local cache
- m_hwp_regs[i].control &= ~1;
- m_hwp_regs[i].address = 0;
- m_hwp_regs[i].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail())
- {
- m_hwp_regs[i].control = tempControl;
- m_hwp_regs[i].address = tempAddr;
- m_hwp_regs[i].refcount = tempRefCount;
-
- return error;
- }
- }
+ lldb::addr_t tempAddr = 0;
+ uint32_t tempControl = 0, tempRefCount = 0;
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (m_hwp_regs[i].control & 0x01) {
+ // Create a backup we can revert to in case of failure.
+ tempAddr = m_hwp_regs[i].address;
+ tempControl = m_hwp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hwp_regs[i].control &= ~1;
+ m_hwp_regs[i].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error.Fail()) {
+ m_hwp_regs[i].control = tempControl;
+ m_hwp_regs[i].address = tempAddr;
+
+ return error;
+ }
}
+ }
- return Error();
+ return Error();
}
uint32_t
-NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- switch ((m_hwp_regs[wp_index].control >> 5) & 0xff)
- {
- case 0x01:
- return 1;
- case 0x03:
- return 2;
- case 0x0f:
- return 4;
- case 0xff:
- return 8;
- default:
- return 0;
- }
+NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
+ case 0x01:
+ return 1;
+ case 0x03:
+ return 2;
+ case 0x0f:
+ return 4;
+ case 0xff:
+ return 8;
+ default:
+ return 0;
+ }
+}
+bool NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+
+ if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
+ return true;
+ else
+ return false;
}
-bool
-NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+Error NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
-}
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-Error
-NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- uint32_t watch_size;
- lldb::addr_t watch_addr;
-
- for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index)
- {
- watch_size = GetWatchpointSize (wp_index);
- watch_addr = m_hwp_regs[wp_index].address;
-
- if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
- && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
- {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Error();
- }
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr < watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Error();
}
+ }
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+NativeRegisterContextLinux_arm64::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].real_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointHitAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+NativeRegisterContextLinux_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
-Error
-NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo()
-{
- if (!m_refresh_hwdebug_info)
- {
- return Error();
- }
-
- ::pid_t tid = m_thread.GetID();
+Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
+ if (!m_refresh_hwdebug_info) {
+ return Error();
+ }
- int regset = NT_ARM_HW_WATCH;
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Error error;
+ ::pid_t tid = m_thread.GetID();
- ioVec.iov_base = &dreg_state;
- ioVec.iov_len = sizeof (dreg_state);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
+ int regset = NT_ARM_HW_WATCH;
+ struct iovec ioVec;
+ struct user_hwdebug_state dreg_state;
+ Error error;
- if (error.Fail())
- return error;
+ ioVec.iov_base = &dreg_state;
+ ioVec.iov_len = sizeof(dreg_state);
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, ioVec.iov_len);
- m_max_hwp_supported = dreg_state.dbg_info & 0xff;
+ if (error.Fail())
+ return error;
- regset = NT_ARM_HW_BREAK;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
+ m_max_hwp_supported = dreg_state.dbg_info & 0xff;
- if (error.Fail())
- return error;
-
- m_max_hbp_supported = dreg_state.dbg_info & 0xff;
- m_refresh_hwdebug_info = false;
+ regset = NT_ARM_HW_BREAK;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, ioVec.iov_len);
+ if (error.Fail())
return error;
+
+ m_max_hbp_supported = dreg_state.dbg_info & 0xff;
+ m_refresh_hwdebug_info = false;
+
+ return error;
}
-Error
-NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType)
-{
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Error error;
-
- memset (&dreg_state, 0, sizeof (dreg_state));
- ioVec.iov_base = &dreg_state;
-
- if (hwbType == eDREGTypeWATCH)
- {
- hwbType = NT_ARM_HW_WATCH;
- ioVec.iov_len = sizeof (dreg_state.dbg_info) + sizeof (dreg_state.pad)
- + (sizeof (dreg_state.dbg_regs [0]) * m_max_hwp_supported);
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
- }
+Error NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType) {
+ struct iovec ioVec;
+ struct user_hwdebug_state dreg_state;
+ Error error;
+
+ memset(&dreg_state, 0, sizeof(dreg_state));
+ ioVec.iov_base = &dreg_state;
+
+ if (hwbType == eDREGTypeWATCH) {
+ hwbType = NT_ARM_HW_WATCH;
+ ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
+ (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
+ dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
}
- else
- {
- hwbType = NT_ARM_HW_BREAK;
- ioVec.iov_len = sizeof (dreg_state.dbg_info) + sizeof (dreg_state.pad)
- + (sizeof (dreg_state.dbg_regs [0]) * m_max_hbp_supported);
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++)
- {
- dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control;
- }
+ } else {
+ hwbType = NT_ARM_HW_BREAK;
+ ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
+ (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
+
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address;
+ dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control;
}
+ }
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &hwbType, &ioVec, ioVec.iov_len);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ &hwbType, &ioVec, ioVec.iov_len);
}
-Error
-NativeRegisterContextLinux_arm64::DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value)
-{
- Error error;
- if (offset > sizeof(struct user_pt_regs))
- {
- uintptr_t offset = offset - sizeof(struct user_pt_regs);
- if (offset > sizeof(struct user_fpsimd_state))
- {
- error.SetErrorString("invalid offset value");
- return error;
- }
- elf_fpregset_t regs;
- int regset = NT_FPREGSET;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
- if (error.Success())
- {
- ArchSpec arch;
- if (m_thread.GetProcess()->GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16, arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
- }
+Error NativeRegisterContextLinux_arm64::DoReadRegisterValue(
+ uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value) {
+ Error error;
+ if (offset > sizeof(struct user_pt_regs)) {
+ uintptr_t offset = offset - sizeof(struct user_pt_regs);
+ if (offset > sizeof(struct user_fpsimd_state)) {
+ error.SetErrorString("invalid offset value");
+ return error;
}
- else
- {
- elf_gregset_t regs;
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
- if (error.Success())
- {
- ArchSpec arch;
- if (m_thread.GetProcess()->GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8, arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
- }
+ elf_fpregset_t regs;
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
+ if (error.Success()) {
+ ArchSpec arch;
+ if (m_thread.GetProcess()->GetArchitecture(arch))
+ value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
+ arch.GetByteOrder());
+ else
+ error.SetErrorString("failed to get architecture");
}
- return error;
-}
+ } else {
+ elf_gregset_t regs;
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
-Error
-NativeRegisterContextLinux_arm64::DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value)
-{
- Error error;
- ::pid_t tid = m_thread.GetID();
- if (offset > sizeof(struct user_pt_regs))
- {
- uintptr_t offset = offset - sizeof(struct user_pt_regs);
- if (offset > sizeof(struct user_fpsimd_state))
- {
- error.SetErrorString("invalid offset value");
- return error;
- }
- elf_fpregset_t regs;
- int regset = NT_FPREGSET;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper( PTRACE_GETREGSET, tid, &regset, &ioVec, sizeof regs);
-
- if (error.Success())
- {
- ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(), 16);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset, &ioVec, sizeof regs);
- }
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
+ if (error.Success()) {
+ ArchSpec arch;
+ if (m_thread.GetProcess()->GetArchitecture(arch))
+ value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
+ arch.GetByteOrder());
+ else
+ error.SetErrorString("failed to get architecture");
}
- else
- {
- elf_gregset_t regs;
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, sizeof regs);
- if (error.Success())
- {
- ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(), 8);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset, &ioVec, sizeof regs);
- }
+ }
+ return error;
+}
+
+Error NativeRegisterContextLinux_arm64::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ Error error;
+ ::pid_t tid = m_thread.GetID();
+ if (offset > sizeof(struct user_pt_regs)) {
+ uintptr_t offset = offset - sizeof(struct user_pt_regs);
+ if (offset > sizeof(struct user_fpsimd_state)) {
+ error.SetErrorString("invalid offset value");
+ return error;
}
- return error;
-}
+ elf_fpregset_t regs;
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
-Error
-NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size)
-{
+ if (error.Success()) {
+ ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(),
+ 16);
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
+ }
+ } else {
+ elf_gregset_t regs;
int regset = NT_PRSTATUS;
struct iovec ioVec;
- Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
+ if (error.Success()) {
+ ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(),
+ 8);
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
+ }
+ }
+ return error;
}
-Error
-NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf, size_t buf_size)
-{
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
- Error error;
+Error NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+ Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
}
-Error
-NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size)
-{
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Error error;
+Error NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+ Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
}
-Error
-NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf, size_t buf_size)
-{
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Error error;
+Error NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) {
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+ Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
}
-uint32_t
-NativeRegisterContextLinux_arm64::CalculateFprOffset(const RegisterInfo* reg_info) const
-{
- return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
+Error NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf, size_t buf_size) {
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+ Error error;
+
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
+}
+
+uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
}
#endif // defined (__arm64__) || defined (__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 4d9a9902ac3c..c46c375acfe7 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__arm64__) || defined (__aarch64__)
+#if defined(__arm64__) || defined(__aarch64__)
#ifndef lldb_NativeRegisterContextLinux_arm64_h
#define lldb_NativeRegisterContextLinux_arm64_h
@@ -18,180 +18,142 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint mangement functions
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Hardware breakpoints/watchpoint mangement functions
+ //------------------------------------------------------------------
- uint32_t
- SetHardwareBreakpoint (lldb::addr_t addr, size_t size) override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- bool
- ClearHardwareBreakpoint (uint32_t hw_idx) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- uint32_t
- NumSupportedHardwareWatchpoints () override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t
- SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- bool
- ClearHardwareWatchpoint (uint32_t hw_index) override;
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- lldb::addr_t
- GetWatchpointHitAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
- lldb::addr_t
- GetWatchpointAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- GetWatchpointSize(uint32_t wp_index);
+ uint32_t GetWatchpointSize(uint32_t wp_index);
- bool
- WatchpointIsEnabled(uint32_t wp_index);
+ bool WatchpointIsEnabled(uint32_t wp_index);
- // Debug register type select
- enum DREGType
- {
- eDREGTypeWATCH = 0,
- eDREGTypeBREAK
- };
+ // Debug register type select
+ enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
- protected:
- Error
- DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value) override;
+protected:
+ Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value) override;
- Error
- DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
+ Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value) override;
- Error
- DoReadGPR(void *buf, size_t buf_size) override;
+ Error DoReadGPR(void *buf, size_t buf_size) override;
- Error
- DoWriteGPR(void *buf, size_t buf_size) override;
+ Error DoWriteGPR(void *buf, size_t buf_size) override;
- Error
- DoReadFPR(void *buf, size_t buf_size) override;
+ Error DoReadFPR(void *buf, size_t buf_size) override;
- Error
- DoWriteFPR(void *buf, size_t buf_size) override;
+ Error DoWriteFPR(void *buf, size_t buf_size) override;
- void*
- GetGPRBuffer() override { return &m_gpr_arm64; }
+ void *GetGPRBuffer() override { return &m_gpr_arm64; }
- void*
- GetFPRBuffer() override { return &m_fpr; }
+ void *GetFPRBuffer() override { return &m_fpr; }
- size_t
- GetFPRSize() override { return sizeof(m_fpr); }
+ size_t GetFPRSize() override { return sizeof(m_fpr); }
- private:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+private:
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
- uint32_t gpr_flags;
- };
+ uint32_t gpr_flags;
+ };
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
+ // based on RegisterContextDarwin_arm64.h
+ struct VReg {
+ uint8_t bytes[16];
+ };
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
+ // based on RegisterContextDarwin_arm64.h
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
- uint64_t m_gpr_arm64[k_num_gpr_registers_arm64]; // 64-bit general purpose registers.
- RegInfo m_reg_info;
- FPU m_fpr; // floating-point registers including extended register sets.
+ uint64_t m_gpr_arm64[k_num_gpr_registers_arm64]; // 64-bit general purpose
+ // registers.
+ RegInfo m_reg_info;
+ FPU m_fpr; // floating-point registers including extended register sets.
- // Debug register info for hardware breakpoints and watchpoints management.
- struct DREG
- {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and refernce counter.
- };
+ // Debug register info for hardware breakpoints and watchpoints management.
+ struct DREG {
+ lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
+ // occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
+ uint32_t control; // Breakpoint/watchpoint control value.
+ uint32_t refcount; // Serves as enable/disable and refernce counter.
+ };
- struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
- struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
+ struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
+ struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
- uint32_t m_max_hwp_supported;
- uint32_t m_max_hbp_supported;
- bool m_refresh_hwdebug_info;
+ uint32_t m_max_hwp_supported;
+ uint32_t m_max_hbp_supported;
+ bool m_refresh_hwdebug_info;
- bool
- IsGPR(unsigned reg) const;
+ bool IsGPR(unsigned reg) const;
- bool
- IsFPR(unsigned reg) const;
+ bool IsFPR(unsigned reg) const;
- Error
- ReadHardwareDebugInfo();
+ Error ReadHardwareDebugInfo();
- Error
- WriteHardwareDebugRegs(int hwbType);
+ Error WriteHardwareDebugRegs(int hwbType);
- uint32_t
- CalculateFprOffset(const RegisterInfo* reg_info) const;
- };
+ uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index 892ce4e24afc..c050a2ec0cc6 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
#include "NativeRegisterContextLinux_mips64.h"
@@ -15,58 +15,50 @@
// C++ Includes
// Other libraries and framework includes
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Log.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Host/HostInfo.h"
+#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/Host.h"
-#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-enumerations.h"
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
#define NT_MIPS_MSA 0x600
#define CONFIG5_FRE (1 << 8)
#define SR_FR (1 << 26)
#define NUM_REGISTERS 32
-#include <sys/ptrace.h>
#include <asm/ptrace.h>
+#include <sys/ptrace.h>
#ifndef PTRACE_GET_WATCH_REGS
-enum pt_watch_style
-{
- pt_watch_style_mips32,
- pt_watch_style_mips64
-};
-struct mips32_watch_regs
-{
- uint32_t watchlo[8];
- uint16_t watchhi[8];
- uint16_t watch_masks[8];
- uint32_t num_valid;
+enum pt_watch_style { pt_watch_style_mips32, pt_watch_style_mips64 };
+struct mips32_watch_regs {
+ uint32_t watchlo[8];
+ uint16_t watchhi[8];
+ uint16_t watch_masks[8];
+ uint32_t num_valid;
} __attribute__((aligned(8)));
-struct mips64_watch_regs
-{
- uint64_t watchlo[8];
- uint16_t watchhi[8];
- uint16_t watch_masks[8];
- uint32_t num_valid;
+struct mips64_watch_regs {
+ uint64_t watchlo[8];
+ uint16_t watchhi[8];
+ uint16_t watch_masks[8];
+ uint32_t num_valid;
} __attribute__((aligned(8)));
-struct pt_watch_regs
-{
- enum pt_watch_style style;
- union
- {
- struct mips32_watch_regs mips32;
- struct mips64_watch_regs mips64;
- };
+struct pt_watch_regs {
+ enum pt_watch_style style;
+ union {
+ struct mips32_watch_regs mips32;
+ struct mips64_watch_regs mips64;
+ };
};
#define PTRACE_GET_WATCH_REGS 0xd0
@@ -77,7 +69,7 @@ struct pt_watch_regs
#define R (1 << 1)
#define I (1 << 2)
-#define IRW (I | R | W)
+#define IRW (I | R | W)
struct pt_watch_regs default_watch_regs;
@@ -88,1240 +80,998 @@ using namespace lldb_private::process_linux;
// Private namespace.
// ----------------------------------------------------------------------------
-namespace
-{
- // mips general purpose registers.
- const uint32_t
- g_gp_regnums_mips[] =
- {
- gpr_zero_mips,
- gpr_r1_mips,
- gpr_r2_mips,
- gpr_r3_mips,
- gpr_r4_mips,
- gpr_r5_mips,
- gpr_r6_mips,
- gpr_r7_mips,
- gpr_r8_mips,
- gpr_r9_mips,
- gpr_r10_mips,
- gpr_r11_mips,
- gpr_r12_mips,
- gpr_r13_mips,
- gpr_r14_mips,
- gpr_r15_mips,
- gpr_r16_mips,
- gpr_r17_mips,
- gpr_r18_mips,
- gpr_r19_mips,
- gpr_r20_mips,
- gpr_r21_mips,
- gpr_r22_mips,
- gpr_r23_mips,
- gpr_r24_mips,
- gpr_r25_mips,
- gpr_r26_mips,
- gpr_r27_mips,
- gpr_gp_mips,
- gpr_sp_mips,
- gpr_r30_mips,
- gpr_ra_mips,
- gpr_sr_mips,
- gpr_mullo_mips,
- gpr_mulhi_mips,
- gpr_badvaddr_mips,
- gpr_cause_mips,
- gpr_pc_mips,
- gpr_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 == k_num_gpr_registers_mips,
- "g_gp_regnums_mips has wrong number of register infos");
-
- // mips floating point registers.
- const uint32_t
- g_fp_regnums_mips[] =
- {
- fpr_f0_mips,
- fpr_f1_mips,
- fpr_f2_mips,
- fpr_f3_mips,
- fpr_f4_mips,
- fpr_f5_mips,
- fpr_f6_mips,
- fpr_f7_mips,
- fpr_f8_mips,
- fpr_f9_mips,
- fpr_f10_mips,
- fpr_f11_mips,
- fpr_f12_mips,
- fpr_f13_mips,
- fpr_f14_mips,
- fpr_f15_mips,
- fpr_f16_mips,
- fpr_f17_mips,
- fpr_f18_mips,
- fpr_f19_mips,
- fpr_f20_mips,
- fpr_f21_mips,
- fpr_f22_mips,
- fpr_f23_mips,
- fpr_f24_mips,
- fpr_f25_mips,
- fpr_f26_mips,
- fpr_f27_mips,
- fpr_f28_mips,
- fpr_f29_mips,
- fpr_f30_mips,
- fpr_f31_mips,
- fpr_fcsr_mips,
- fpr_fir_mips,
- fpr_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 == k_num_fpr_registers_mips,
- "g_fp_regnums_mips has wrong number of register infos");
-
- // mips MSA registers.
- const uint32_t
- g_msa_regnums_mips[] =
- {
- msa_w0_mips,
- msa_w1_mips,
- msa_w2_mips,
- msa_w3_mips,
- msa_w4_mips,
- msa_w5_mips,
- msa_w6_mips,
- msa_w7_mips,
- msa_w8_mips,
- msa_w9_mips,
- msa_w10_mips,
- msa_w11_mips,
- msa_w12_mips,
- msa_w13_mips,
- msa_w14_mips,
- msa_w15_mips,
- msa_w16_mips,
- msa_w17_mips,
- msa_w18_mips,
- msa_w19_mips,
- msa_w20_mips,
- msa_w21_mips,
- msa_w22_mips,
- msa_w23_mips,
- msa_w24_mips,
- msa_w25_mips,
- msa_w26_mips,
- msa_w27_mips,
- msa_w28_mips,
- msa_w29_mips,
- msa_w30_mips,
- msa_w31_mips,
- msa_fcsr_mips,
- msa_fir_mips,
- msa_mcsr_mips,
- msa_mir_mips,
- msa_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) - 1 == k_num_msa_registers_mips,
- "g_msa_regnums_mips has wrong number of register infos");
-
- // mips64 general purpose registers.
- const uint32_t
- g_gp_regnums_mips64[] =
- {
- gpr_zero_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) - 1 == k_num_gpr_registers_mips64,
- "g_gp_regnums_mips64 has wrong number of register infos");
-
- // mips64 floating point registers.
- const uint32_t
- g_fp_regnums_mips64[] =
- {
- fpr_f0_mips64,
- fpr_f1_mips64,
- fpr_f2_mips64,
- fpr_f3_mips64,
- fpr_f4_mips64,
- fpr_f5_mips64,
- fpr_f6_mips64,
- fpr_f7_mips64,
- fpr_f8_mips64,
- fpr_f9_mips64,
- fpr_f10_mips64,
- fpr_f11_mips64,
- fpr_f12_mips64,
- fpr_f13_mips64,
- fpr_f14_mips64,
- fpr_f15_mips64,
- fpr_f16_mips64,
- fpr_f17_mips64,
- fpr_f18_mips64,
- fpr_f19_mips64,
- fpr_f20_mips64,
- fpr_f21_mips64,
- fpr_f22_mips64,
- fpr_f23_mips64,
- fpr_f24_mips64,
- fpr_f25_mips64,
- fpr_f26_mips64,
- fpr_f27_mips64,
- fpr_f28_mips64,
- fpr_f29_mips64,
- fpr_f30_mips64,
- fpr_f31_mips64,
- fpr_fcsr_mips64,
- fpr_fir_mips64,
- fpr_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) - 1 == k_num_fpr_registers_mips64,
- "g_fp_regnums_mips64 has wrong number of register infos");
-
- // mips64 MSA registers.
- const uint32_t
- g_msa_regnums_mips64[] =
- {
- msa_w0_mips64,
- msa_w1_mips64,
- msa_w2_mips64,
- msa_w3_mips64,
- msa_w4_mips64,
- msa_w5_mips64,
- msa_w6_mips64,
- msa_w7_mips64,
- msa_w8_mips64,
- msa_w9_mips64,
- msa_w10_mips64,
- msa_w11_mips64,
- msa_w12_mips64,
- msa_w13_mips64,
- msa_w14_mips64,
- msa_w15_mips64,
- msa_w16_mips64,
- msa_w17_mips64,
- msa_w18_mips64,
- msa_w19_mips64,
- msa_w20_mips64,
- msa_w21_mips64,
- msa_w22_mips64,
- msa_w23_mips64,
- msa_w24_mips64,
- msa_w25_mips64,
- msa_w26_mips64,
- msa_w27_mips64,
- msa_w28_mips64,
- msa_w29_mips64,
- msa_w30_mips64,
- msa_w31_mips64,
- msa_fcsr_mips64,
- msa_fir_mips64,
- msa_mcsr_mips64,
- msa_mir_mips64,
- msa_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) - 1 == k_num_msa_registers_mips64,
- "g_msa_regnums_mips64 has wrong number of register infos");
-
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 3
- };
-
- // Register sets for mips.
- static const RegisterSet
- g_reg_sets_mips[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_mips, g_gp_regnums_mips },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_mips, g_fp_regnums_mips },
- { "MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips }
- };
-
- // Register sets for mips64.
- static const RegisterSet
- g_reg_sets_mips64[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_mips64, g_gp_regnums_mips64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_mips64, g_fp_regnums_mips64 },
- { "MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64 },
- };
+namespace {
+// mips general purpose registers.
+const uint32_t g_gp_regnums_mips[] = {
+ gpr_zero_mips, gpr_r1_mips, gpr_r2_mips, gpr_r3_mips,
+ gpr_r4_mips, gpr_r5_mips, gpr_r6_mips, gpr_r7_mips,
+ gpr_r8_mips, gpr_r9_mips, gpr_r10_mips, gpr_r11_mips,
+ gpr_r12_mips, gpr_r13_mips, gpr_r14_mips, gpr_r15_mips,
+ gpr_r16_mips, gpr_r17_mips, gpr_r18_mips, gpr_r19_mips,
+ gpr_r20_mips, gpr_r21_mips, gpr_r22_mips, gpr_r23_mips,
+ gpr_r24_mips, gpr_r25_mips, gpr_r26_mips, gpr_r27_mips,
+ gpr_gp_mips, gpr_sp_mips, gpr_r30_mips, gpr_ra_mips,
+ gpr_sr_mips, gpr_mullo_mips, gpr_mulhi_mips, gpr_badvaddr_mips,
+ gpr_cause_mips, gpr_pc_mips, gpr_config5_mips,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 ==
+ k_num_gpr_registers_mips,
+ "g_gp_regnums_mips has wrong number of register infos");
+
+// mips floating point registers.
+const uint32_t g_fp_regnums_mips[] = {
+ fpr_f0_mips, fpr_f1_mips, fpr_f2_mips, fpr_f3_mips,
+ fpr_f4_mips, fpr_f5_mips, fpr_f6_mips, fpr_f7_mips,
+ fpr_f8_mips, fpr_f9_mips, fpr_f10_mips, fpr_f11_mips,
+ fpr_f12_mips, fpr_f13_mips, fpr_f14_mips, fpr_f15_mips,
+ fpr_f16_mips, fpr_f17_mips, fpr_f18_mips, fpr_f19_mips,
+ fpr_f20_mips, fpr_f21_mips, fpr_f22_mips, fpr_f23_mips,
+ fpr_f24_mips, fpr_f25_mips, fpr_f26_mips, fpr_f27_mips,
+ fpr_f28_mips, fpr_f29_mips, fpr_f30_mips, fpr_f31_mips,
+ fpr_fcsr_mips, fpr_fir_mips, fpr_config5_mips,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 ==
+ k_num_fpr_registers_mips,
+ "g_fp_regnums_mips has wrong number of register infos");
+
+// mips MSA registers.
+const uint32_t g_msa_regnums_mips[] = {
+ msa_w0_mips, msa_w1_mips, msa_w2_mips, msa_w3_mips,
+ msa_w4_mips, msa_w5_mips, msa_w6_mips, msa_w7_mips,
+ msa_w8_mips, msa_w9_mips, msa_w10_mips, msa_w11_mips,
+ msa_w12_mips, msa_w13_mips, msa_w14_mips, msa_w15_mips,
+ msa_w16_mips, msa_w17_mips, msa_w18_mips, msa_w19_mips,
+ msa_w20_mips, msa_w21_mips, msa_w22_mips, msa_w23_mips,
+ msa_w24_mips, msa_w25_mips, msa_w26_mips, msa_w27_mips,
+ msa_w28_mips, msa_w29_mips, msa_w30_mips, msa_w31_mips,
+ msa_fcsr_mips, msa_fir_mips, msa_mcsr_mips, msa_mir_mips,
+ msa_config5_mips,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) -
+ 1 ==
+ k_num_msa_registers_mips,
+ "g_msa_regnums_mips has wrong number of register infos");
+
+// mips64 general purpose registers.
+const uint32_t g_gp_regnums_mips64[] = {
+ gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64,
+ gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64,
+ gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64,
+ gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
+ gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64,
+ gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64,
+ gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64,
+ gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
+ gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64,
+ gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64,
+ gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64,
+ gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
+ gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
+ 1 ==
+ k_num_gpr_registers_mips64,
+ "g_gp_regnums_mips64 has wrong number of register infos");
+
+// mips64 floating point registers.
+const uint32_t g_fp_regnums_mips64[] = {
+ fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64,
+ fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64,
+ fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64,
+ fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
+ fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
+ fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
+ fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
+ fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
+ fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
+ 1 ==
+ k_num_fpr_registers_mips64,
+ "g_fp_regnums_mips64 has wrong number of register infos");
+
+// mips64 MSA registers.
+const uint32_t g_msa_regnums_mips64[] = {
+ msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64,
+ msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64,
+ msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64,
+ msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64,
+ msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64,
+ msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64,
+ msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64,
+ msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64,
+ msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
+ msa_config5_mips64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
+ 1 ==
+ k_num_msa_registers_mips64,
+ "g_msa_regnums_mips64 has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 3 };
+
+// Register sets for mips.
+static const RegisterSet g_reg_sets_mips[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_mips,
+ g_gp_regnums_mips},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_mips,
+ g_fp_regnums_mips},
+ {"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}};
+
+// Register sets for mips64.
+static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
+ g_gp_regnums_mips64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
+ g_fp_regnums_mips64},
+ {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
+};
} // end of anonymous namespace
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_mips64(target_arch, native_thread, concrete_frame_idx);
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_mips64(target_arch, native_thread,
+ concrete_frame_idx);
}
-#define REG_CONTEXT_SIZE (GetRegisterInfoInterface ().GetGPRSize () + sizeof(FPR_linux_mips) + sizeof(MSA_linux_mips))
+#define REG_CONTEXT_SIZE \
+ (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR_linux_mips) + \
+ sizeof(MSA_linux_mips))
// ----------------------------------------------------------------------------
// NativeRegisterContextLinux_mips64 members.
// ----------------------------------------------------------------------------
-static RegisterInfoInterface*
-CreateRegisterInfoInterface(const ArchSpec& target_arch)
-{
- if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
- {
- // 32-bit hosts run with a RegisterContextLinux_mips context.
- return new RegisterContextLinux_mips(target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- }
- else
- {
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- // mips64 hosts know how to work with 64-bit and 32-bit EXEs using the mips64 register context.
- return new RegisterContextLinux_mips64 (target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- }
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ // 32-bit hosts run with a RegisterContextLinux_mips context.
+ return new RegisterContextLinux_mips(
+ target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ // mips64 hosts know how to work with 64-bit and 32-bit EXEs using the
+ // mips64 register context.
+ return new RegisterContextLinux_mips64(
+ target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
+ }
}
-NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch))
-{
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- m_reg_info.num_registers = k_num_registers_mips;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_mips;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_mips;
- m_reg_info.last_gpr = k_last_gpr_mips;
- m_reg_info.first_fpr = k_first_fpr_mips;
- m_reg_info.last_fpr = k_last_fpr_mips;
- m_reg_info.first_msa = k_first_msa_mips;
- m_reg_info.last_msa = k_last_msa_mips;
- break;
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- m_reg_info.num_registers = k_num_registers_mips64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_mips64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_mips64;
- m_reg_info.last_gpr = k_last_gpr_mips64;
- m_reg_info.first_fpr = k_first_fpr_mips64;
- m_reg_info.last_fpr = k_last_fpr_mips64;
- m_reg_info.first_msa = k_first_msa_mips64;
- m_reg_info.last_msa = k_last_msa_mips64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ CreateRegisterInfoInterface(target_arch)) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ m_reg_info.num_registers = k_num_registers_mips;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_mips;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_mips;
+ m_reg_info.last_gpr = k_last_gpr_mips;
+ m_reg_info.first_fpr = k_first_fpr_mips;
+ m_reg_info.last_fpr = k_last_fpr_mips;
+ m_reg_info.first_msa = k_first_msa_mips;
+ m_reg_info.last_msa = k_last_msa_mips;
+ break;
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ m_reg_info.num_registers = k_num_registers_mips64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_mips64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_mips64;
+ m_reg_info.last_gpr = k_last_gpr_mips64;
+ m_reg_info.first_fpr = k_first_fpr_mips64;
+ m_reg_info.last_fpr = k_last_fpr_mips64;
+ m_reg_info.first_msa = k_first_msa_mips64;
+ m_reg_info.last_msa = k_last_msa_mips64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_msa;
+ m_iovec.iov_len = sizeof(MSA_linux_mips);
+
+ // init h/w watchpoint addr map
+ for (int index = 0; index <= MAX_NUM_WP; index++)
+ hw_addr_map[index] = LLDB_INVALID_ADDRESS;
+
+ ::memset(&m_gpr, 0, sizeof(GPR_linux_mips));
+ ::memset(&m_fpr, 0, sizeof(FPR_linux_mips));
+ ::memset(&m_msa, 0, sizeof(MSA_linux_mips));
+}
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_msa;
- m_iovec.iov_len = sizeof(MSA_linux_mips);
+uint32_t NativeRegisterContextLinux_mips64::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
- // init h/w watchpoint addr map
- for (int index = 0;index <= MAX_NUM_WP; index++)
- hw_addr_map[index] = LLDB_INVALID_ADDRESS;
+lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
+ lldb::addr_t fail_value) {
+ Error error;
+ RegisterValue pc_value;
+ lldb::addr_t pc = fail_value;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- ::memset(&m_gpr, 0, sizeof(GPR_linux_mips));
- ::memset(&m_fpr, 0, sizeof(FPR_linux_mips));
- ::memset(&m_msa, 0, sizeof(MSA_linux_mips));
-}
+ if (log)
+ log->Printf("NativeRegisterContextLinux_mips64::%s Reading PC from "
+ "breakpoint location",
+ __FUNCTION__);
-uint32_t
-NativeRegisterContextLinux_mips64::GetRegisterSetCount () const
-{
- return k_num_register_sets;
-}
+ // PC register is at index 34 of the register array
+ const RegisterInfo *const pc_info_p = GetRegisterInfoAtIndex(gpr_pc_mips64);
+
+ error = ReadRegister(pc_info_p, pc_value);
+ if (error.Success()) {
+ pc = pc_value.GetAsUInt64();
+
+ // CAUSE register is at index 37 of the register array
+ const RegisterInfo *const cause_info_p =
+ GetRegisterInfoAtIndex(gpr_cause_mips64);
+ RegisterValue cause_value;
+
+ ReadRegister(cause_info_p, cause_value);
+
+ uint64_t cause = cause_value.GetAsUInt64();
-lldb::addr_t
-NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation (lldb::addr_t fail_value)
-{
- Error error;
- RegisterValue pc_value;
- lldb::addr_t pc = fail_value;
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-
if (log)
- log->Printf ("NativeRegisterContextLinux_mips64::%s Reading PC from breakpoint location", __FUNCTION__);
-
- // PC register is at index 34 of the register array
- const RegisterInfo *const pc_info_p = GetRegisterInfoAtIndex (gpr_pc_mips64);
-
- error = ReadRegister (pc_info_p, pc_value);
- if (error.Success ())
- {
- pc = pc_value.GetAsUInt64 ();
-
- // CAUSE register is at index 37 of the register array
- const RegisterInfo *const cause_info_p = GetRegisterInfoAtIndex (gpr_cause_mips64);
- RegisterValue cause_value;
-
- ReadRegister (cause_info_p, cause_value);
-
- uint64_t cause = cause_value.GetAsUInt64 ();
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_mips64::%s PC 0x%" PRIx64 " Cause 0x%" PRIx64, __FUNCTION__, pc, cause);
-
- /*
- * The breakpoint might be in a delay slot. In this case PC points
- * to the delayed branch instruction rather then the instruction
- * in the delay slot. If the CAUSE.BD flag is set then adjust the
- * PC based on the size of the branch instruction.
- */
- if ((cause & (1 << 31)) != 0)
- {
- lldb::addr_t branch_delay = 0;
- branch_delay = 4; // FIXME - Adjust according to size of branch instruction at PC
- pc = pc + branch_delay;
- pc_value.SetUInt64 (pc);
- WriteRegister (pc_info_p, pc_value);
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_mips64::%s New PC 0x%" PRIx64, __FUNCTION__, pc);
- }
+ log->Printf("NativeRegisterContextLinux_mips64::%s PC 0x%" PRIx64
+ " Cause 0x%" PRIx64,
+ __FUNCTION__, pc, cause);
+
+ /*
+ * The breakpoint might be in a delay slot. In this case PC points
+ * to the delayed branch instruction rather then the instruction
+ * in the delay slot. If the CAUSE.BD flag is set then adjust the
+ * PC based on the size of the branch instruction.
+ */
+ if ((cause & (1 << 31)) != 0) {
+ lldb::addr_t branch_delay = 0;
+ branch_delay =
+ 4; // FIXME - Adjust according to size of branch instruction at PC
+ pc = pc + branch_delay;
+ pc_value.SetUInt64(pc);
+ WriteRegister(pc_info_p, pc_value);
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_mips64::%s New PC 0x%" PRIx64,
+ __FUNCTION__, pc);
}
+ }
- return pc;
+ return pc;
}
const RegisterSet *
-NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const
-{
- if (set_index >= k_num_register_sets)
- return nullptr;
-
- switch (GetRegisterInfoInterface ().GetTargetArchitecture ().GetMachine ())
- {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return &g_reg_sets_mips64[set_index];
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return &g_reg_sets_mips[set_index];
- default:
- assert (false && "Unhandled target architecture.");
- return nullptr;
- }
+NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const {
+ if (set_index >= k_num_register_sets)
+ return nullptr;
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return &g_reg_sets_mips64[set_index];
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return &g_reg_sets_mips[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
return nullptr;
+ }
+
+ return nullptr;
}
lldb_private::Error
-NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
-
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- uint8_t byte_size = reg_info->byte_size;
- if (reg == LLDB_INVALID_REGNUM)
- {
- // This is likely an internal register for lldb use only and should not be
- // directly queried.
- error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
- "register, cannot read directly",
- reg_info->name);
- return error;
- }
+NativeRegisterContextLinux_mips64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Error error;
- if (IsMSA(reg) && !IsMSAAvailable())
- {
- error.SetErrorString ("MSA not available on this processor");
- return error;
- }
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ uint8_t byte_size = reg_info->byte_size;
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
- if (IsMSA(reg) || IsFPR(reg))
- {
- uint8_t *src = nullptr;
- lldbassert(reg_info->byte_offset < sizeof(UserArea));
+ if (IsMSA(reg) && !IsMSAAvailable()) {
+ error.SetErrorString("MSA not available on this processor");
+ return error;
+ }
- error = ReadCP1();
+ if (IsMSA(reg) || IsFPR(reg)) {
+ uint8_t *src = nullptr;
+ lldbassert(reg_info->byte_offset < sizeof(UserArea));
- if (!error.Success())
- {
- error.SetErrorString ("failed to read co-processor 1 register");
- return error;
- }
+ error = ReadCP1();
- if (IsFPR(reg))
- {
- if (IsFR0() && (byte_size != 4))
- {
- byte_size = 4;
- uint8_t ptrace_index;
- ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- src = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
- }
- else
- src = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
- }
- else
- src = (uint8_t *)&m_msa + reg_info->byte_offset -
- (sizeof(m_gpr) + sizeof(m_fpr));
- switch (byte_size)
- {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- case 16:
- reg_value.SetBytes((const void *)src, 16, GetByteOrder());
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
+ if (!error.Success()) {
+ error.SetErrorString("failed to read co-processor 1 register");
+ return error;
}
- else
- {
- error = ReadRegisterRaw(reg, reg_value);
+
+ if (IsFPR(reg)) {
+ if (IsFR0() && (byte_size != 4)) {
+ byte_size = 4;
+ uint8_t ptrace_index;
+ ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ src = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
+ } else
+ src = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
+ } else
+ src = (uint8_t *)&m_msa + reg_info->byte_offset -
+ (sizeof(m_gpr) + sizeof(m_fpr));
+ switch (byte_size) {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ case 16:
+ reg_value.SetBytes((const void *)src, 16, GetByteOrder());
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
}
+ } else {
+ error = ReadRegisterRaw(reg, reg_value);
+ }
- return error;
+ return error;
}
-lldb_private::Error
-NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- Error error;
+lldb_private::Error NativeRegisterContextLinux_mips64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Error error;
- assert (reg_info && "reg_info is null");
+ assert(reg_info && "reg_info is null");
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
- if (IsMSA(reg_index) && !IsMSAAvailable())
- {
- error.SetErrorString ("MSA not available on this processor");
- return error;
- }
+ if (IsMSA(reg_index) && !IsMSAAvailable()) {
+ error.SetErrorString("MSA not available on this processor");
+ return error;
+ }
- if (IsFPR(reg_index) || IsMSA(reg_index))
- {
- uint8_t *dst = nullptr;
- uint64_t *src = nullptr;
- uint8_t byte_size = reg_info->byte_size;
- lldbassert(reg_info->byte_offset < sizeof(UserArea));
-
- // Initialise the FP and MSA buffers by reading all co-processor 1 registers
- ReadCP1();
-
- if (IsFPR(reg_index))
- {
- if (IsFR0() && (byte_size != 4))
- {
- byte_size = 4;
- uint8_t ptrace_index;
- ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- dst = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
- }
- else
- dst = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
- }
- else
- dst = (uint8_t *)&m_msa + reg_info->byte_offset -
- (sizeof(m_gpr) + sizeof(m_fpr));
- switch (byte_size)
- {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- case 16:
- src = (uint64_t *)reg_value.GetBytes();
- *(uint64_t *)dst = *src;
- *(uint64_t *)(dst + 8) = *(src + 1);
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
- error = WriteCP1();
- if (!error.Success())
- {
- error.SetErrorString("failed to write co-processor 1 register");
- return error;
- }
+ if (IsFPR(reg_index) || IsMSA(reg_index)) {
+ uint8_t *dst = nullptr;
+ uint64_t *src = nullptr;
+ uint8_t byte_size = reg_info->byte_size;
+ lldbassert(reg_info->byte_offset < sizeof(UserArea));
+
+ // Initialise the FP and MSA buffers by reading all co-processor 1 registers
+ ReadCP1();
+
+ if (IsFPR(reg_index)) {
+ if (IsFR0() && (byte_size != 4)) {
+ byte_size = 4;
+ uint8_t ptrace_index;
+ ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ dst = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
+ } else
+ dst = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
+ } else
+ dst = (uint8_t *)&m_msa + reg_info->byte_offset -
+ (sizeof(m_gpr) + sizeof(m_fpr));
+ switch (byte_size) {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ case 16:
+ src = (uint64_t *)reg_value.GetBytes();
+ *(uint64_t *)dst = *src;
+ *(uint64_t *)(dst + 8) = *(src + 1);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
}
- else
- {
- error = WriteRegisterRaw(reg_index, reg_value);
+ error = WriteCP1();
+ if (!error.Success()) {
+ error.SetErrorString("failed to write co-processor 1 register");
+ return error;
}
+ } else {
+ error = WriteRegisterRaw(reg_index, reg_value);
+ }
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_mips64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
- return error;
- }
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- error = ReadGPR();
- if (!error.Success())
- {
- error.SetErrorString ("ReadGPR() failed");
- return error;
- }
+ error = ReadGPR();
+ if (!error.Success()) {
+ error.SetErrorString("ReadGPR() failed");
+ return error;
+ }
- error = ReadCP1();
- if (!error.Success())
- {
- error.SetErrorString ("ReadCP1() failed");
- return error;
- }
+ error = ReadCP1();
+ if (!error.Success()) {
+ error.SetErrorString("ReadCP1() failed");
+ return error;
+ }
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
- return error;
- }
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- ::memcpy (dst, &m_gpr, GetRegisterInfoInterface ().GetGPRSize ());
- dst += GetRegisterInfoInterface ().GetGPRSize ();
+ ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
+ dst += GetRegisterInfoInterface().GetGPRSize();
- ::memcpy (dst, &m_fpr, GetFPRSize ());
- dst += GetFPRSize ();
+ ::memcpy(dst, &m_fpr, GetFPRSize());
+ dst += GetFPRSize();
- ::memcpy (dst, &m_msa, sizeof(MSA_linux_mips));
+ ::memcpy(dst, &m_msa, sizeof(MSA_linux_mips));
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_mips64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_mips64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
+ src += GetRegisterInfoInterface().GetGPRSize();
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
+ ::memcpy(&m_fpr, src, GetFPRSize());
+ src += GetFPRSize();
- ::memcpy (&m_gpr, src, GetRegisterInfoInterface ().GetGPRSize ());
- src += GetRegisterInfoInterface ().GetGPRSize ();
+ ::memcpy(&m_msa, src, sizeof(MSA_linux_mips));
- ::memcpy (&m_fpr, src, GetFPRSize ());
- src += GetFPRSize ();
+ error = WriteGPR();
+ if (!error.Success()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s WriteGPR() failed",
+ __FUNCTION__);
+ return error;
+ }
- ::memcpy (&m_msa, src, sizeof(MSA_linux_mips));
+ error = WriteCP1();
+ if (!error.Success()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s WriteCP1() failed",
+ __FUNCTION__);
+ return error;
+ }
- error = WriteGPR();
- if (!error.Success())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s WriteGPR() failed", __FUNCTION__);
- return error;
- }
+ return error;
+}
- error = WriteCP1();
- if (!error.Success())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s WriteCP1() failed", __FUNCTION__);
- return error;
- }
+Error NativeRegisterContextLinux_mips64::ReadCP1() {
+ Error error;
- return error;
-}
+ uint8_t *src = nullptr;
+ uint8_t *dst = nullptr;
-Error
-NativeRegisterContextLinux_mips64::ReadCP1()
-{
- Error error;
+ lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
- lldb::ByteOrder byte_order = GetByteOrder();
-
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
-
- if (IsMSAAvailable())
- {
- error = NativeRegisterContextLinux::ReadRegisterSet(&m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
- src = (uint8_t *)&m_msa + (IsBigEndian * 8);
- dst = (uint8_t *)&m_fpr;
- for ( int i = 0; i < NUM_REGISTERS; i++)
- {
- // Copy fp values from msa buffer fetched via ptrace
- *(uint64_t *) dst = *(uint64_t *) src;
- src = src + 16;
- dst = dst + 8;
- }
- m_fpr.fir = m_msa.fir;
- m_fpr.fcsr = m_msa.fcsr;
- m_fpr.config5 = m_msa.config5;
- }
- else
- {
- error = NativeRegisterContextLinux::ReadFPR();
+ if (IsMSAAvailable()) {
+ error = NativeRegisterContextLinux::ReadRegisterSet(
+ &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
+ src = (uint8_t *)&m_msa + (IsBigEndian * 8);
+ dst = (uint8_t *)&m_fpr;
+ for (int i = 0; i < NUM_REGISTERS; i++) {
+ // Copy fp values from msa buffer fetched via ptrace
+ *(uint64_t *)dst = *(uint64_t *)src;
+ src = src + 16;
+ dst = dst + 8;
}
+ m_fpr.fir = m_msa.fir;
+ m_fpr.fcsr = m_msa.fcsr;
+ m_fpr.config5 = m_msa.config5;
+ } else {
+ error = NativeRegisterContextLinux::ReadFPR();
+ }
return error;
}
uint8_t *
NativeRegisterContextLinux_mips64::ReturnFPOffset(uint8_t reg_index,
- uint32_t byte_offset)
-{
- uint8_t *fp_buffer_ptr = nullptr;
- lldb::ByteOrder byte_order = GetByteOrder();
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
- if (reg_index % 2)
- {
- uint8_t offset_diff = (IsBigEndian) ? 8 : 4;
- fp_buffer_ptr = (uint8_t *)&m_fpr + byte_offset
- - offset_diff - sizeof(m_gpr);
- }
- else
- {
- fp_buffer_ptr = (uint8_t *)&m_fpr + byte_offset +
- 4 * (IsBigEndian) - sizeof(m_gpr);
- }
- return fp_buffer_ptr;
+ uint32_t byte_offset) {
+
+ uint8_t *fp_buffer_ptr = nullptr;
+ lldb::ByteOrder byte_order = GetByteOrder();
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
+ if (reg_index % 2) {
+ uint8_t offset_diff = (IsBigEndian) ? 8 : 4;
+ fp_buffer_ptr =
+ (uint8_t *)&m_fpr + byte_offset - offset_diff - sizeof(m_gpr);
+ } else {
+ fp_buffer_ptr =
+ (uint8_t *)&m_fpr + byte_offset + 4 * (IsBigEndian) - sizeof(m_gpr);
+ }
+ return fp_buffer_ptr;
}
-Error
-NativeRegisterContextLinux_mips64::WriteCP1()
-{
- Error error;
+Error NativeRegisterContextLinux_mips64::WriteCP1() {
+ Error error;
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
+ uint8_t *src = nullptr;
+ uint8_t *dst = nullptr;
- lldb::ByteOrder byte_order = GetByteOrder();
+ lldb::ByteOrder byte_order = GetByteOrder();
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
- if (IsMSAAvailable())
- {
- dst = (uint8_t *)&m_msa + (IsBigEndian * 8);
- src = (uint8_t *)&m_fpr;
- for (int i = 0; i < NUM_REGISTERS; i++)
- {
- // Copy fp values to msa buffer for ptrace
- *(uint64_t *) dst = *(uint64_t *) src;
- dst = dst + 16;
- src = src + 8;
- }
- m_msa.fir = m_fpr.fir;
- m_msa.fcsr = m_fpr.fcsr;
- m_msa.config5 = m_fpr.config5;
- error = NativeRegisterContextLinux::WriteRegisterSet(&m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
- }
- else
- {
- error = NativeRegisterContextLinux::WriteFPR();
+ if (IsMSAAvailable()) {
+ dst = (uint8_t *)&m_msa + (IsBigEndian * 8);
+ src = (uint8_t *)&m_fpr;
+ for (int i = 0; i < NUM_REGISTERS; i++) {
+ // Copy fp values to msa buffer for ptrace
+ *(uint64_t *)dst = *(uint64_t *)src;
+ dst = dst + 16;
+ src = src + 8;
}
+ m_msa.fir = m_fpr.fir;
+ m_msa.fcsr = m_fpr.fcsr;
+ m_msa.config5 = m_fpr.config5;
+ error = NativeRegisterContextLinux::WriteRegisterSet(
+ &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
+ } else {
+ error = NativeRegisterContextLinux::WriteFPR();
+ }
- return error;
+ return error;
}
-bool
-NativeRegisterContextLinux_mips64::IsFR0()
-{
- const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex (gpr_sr_mips64);
+bool NativeRegisterContextLinux_mips64::IsFR0() {
+ const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex(gpr_sr_mips64);
- RegisterValue reg_value;
- ReadRegister (reg_info_p, reg_value);
+ RegisterValue reg_value;
+ ReadRegister(reg_info_p, reg_value);
- uint64_t value = reg_value.GetAsUInt64();
+ uint64_t value = reg_value.GetAsUInt64();
- return (!(value & SR_FR));
+ return (!(value & SR_FR));
}
-bool
-NativeRegisterContextLinux_mips64::IsFRE()
-{
- const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex (gpr_config5_mips64);
+bool NativeRegisterContextLinux_mips64::IsFRE() {
+ const RegisterInfo *const reg_info_p =
+ GetRegisterInfoAtIndex(gpr_config5_mips64);
- RegisterValue reg_value;
- ReadRegister (reg_info_p, reg_value);
+ RegisterValue reg_value;
+ ReadRegister(reg_info_p, reg_value);
- uint64_t config5 = reg_value.GetAsUInt64();
+ uint64_t config5 = reg_value.GetAsUInt64();
- return (config5 & CONFIG5_FRE);
+ return (config5 & CONFIG5_FRE);
}
-bool
-NativeRegisterContextLinux_mips64::IsFPR(uint32_t reg_index) const
-{
- return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
+bool NativeRegisterContextLinux_mips64::IsFPR(uint32_t reg_index) const {
+ return (m_reg_info.first_fpr <= reg_index &&
+ reg_index <= m_reg_info.last_fpr);
}
-static uint32_t
-GetWatchHi (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watchhi[index];
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watchhi[index];
- if(log)
- log->Printf("Invalid watch register style");
- return 0;
+static uint32_t GetWatchHi(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watchhi[index];
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watchhi[index];
+ if (log)
+ log->Printf("Invalid watch register style");
+ return 0;
}
-static void
-SetWatchHi (struct pt_watch_regs *regs, uint32_t index, uint16_t value)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- regs->mips32.watchhi[index] = value;
- else if (regs->style == pt_watch_style_mips64)
- regs->mips64.watchhi[index] = value;
- if(log)
- log->Printf("Invalid watch register style");
- return;
+static void SetWatchHi(struct pt_watch_regs *regs, uint32_t index,
+ uint16_t value) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ regs->mips32.watchhi[index] = value;
+ else if (regs->style == pt_watch_style_mips64)
+ regs->mips64.watchhi[index] = value;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return;
}
-static lldb::addr_t
-GetWatchLo (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watchlo[index];
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watchlo[index];
- if(log)
- log->Printf("Invalid watch register style");
- return LLDB_INVALID_ADDRESS;
+static lldb::addr_t GetWatchLo(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watchlo[index];
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watchlo[index];
+ if (log)
+ log->Printf("Invalid watch register style");
+ return LLDB_INVALID_ADDRESS;
}
-static void
-SetWatchLo (struct pt_watch_regs *regs, uint32_t index, uint64_t value)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- regs->mips32.watchlo[index] = (uint32_t) value;
- else if (regs->style == pt_watch_style_mips64)
- regs->mips64.watchlo[index] = value;
- if(log)
- log->Printf("Invalid watch register style");
- return;
+static void SetWatchLo(struct pt_watch_regs *regs, uint32_t index,
+ uint64_t value) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ regs->mips32.watchlo[index] = (uint32_t)value;
+ else if (regs->style == pt_watch_style_mips64)
+ regs->mips64.watchlo[index] = value;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return;
}
-static uint32_t
-GetIRWMask (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watch_masks[index] & IRW;
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watch_masks[index] & IRW;
- if(log)
- log->Printf("Invalid watch register style");
- return 0;
+static uint32_t GetIRWMask(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watch_masks[index] & IRW;
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watch_masks[index] & IRW;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return 0;
}
-static uint32_t
-GetRegMask (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watch_masks[index] & ~IRW;
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watch_masks[index] & ~IRW;
- if(log)
- log->Printf("Invalid watch register style");
- return 0;
+static uint32_t GetRegMask(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watch_masks[index] & ~IRW;
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watch_masks[index] & ~IRW;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return 0;
}
-static lldb::addr_t
-GetRangeMask (lldb::addr_t mask)
-{
- lldb::addr_t mask_bit = 1;
- while (mask_bit < mask)
- {
- mask = mask | mask_bit;
- mask_bit <<= 1;
- }
- return mask;
+static lldb::addr_t GetRangeMask(lldb::addr_t mask) {
+ lldb::addr_t mask_bit = 1;
+ while (mask_bit < mask) {
+ mask = mask | mask_bit;
+ mask_bit <<= 1;
+ }
+ return mask;
}
-static int
-GetVacantWatchIndex (struct pt_watch_regs *regs, lldb::addr_t addr, uint32_t size, uint32_t irw, uint32_t num_valid)
-{
- lldb::addr_t last_byte = addr + size - 1;
- lldb::addr_t mask = GetRangeMask (addr ^ last_byte) | IRW;
- lldb::addr_t base_addr = addr & ~mask;
-
- // Check if this address is already watched by previous watch points.
- lldb::addr_t lo;
- uint16_t hi;
- uint32_t vacant_watches = 0;
- for (uint32_t index = 0; index < num_valid; index++)
- {
- lo = GetWatchLo (regs, index);
- if (lo != 0 && irw == ((uint32_t) lo & irw))
- {
- hi = GetWatchHi (regs, index) | IRW;
- lo &= ~(lldb::addr_t) hi;
- if (addr >= lo && last_byte <= (lo + hi))
- return index;
+static int GetVacantWatchIndex(struct pt_watch_regs *regs, lldb::addr_t addr,
+ uint32_t size, uint32_t irw,
+ uint32_t num_valid) {
+ lldb::addr_t last_byte = addr + size - 1;
+ lldb::addr_t mask = GetRangeMask(addr ^ last_byte) | IRW;
+ lldb::addr_t base_addr = addr & ~mask;
+
+ // Check if this address is already watched by previous watch points.
+ lldb::addr_t lo;
+ uint16_t hi;
+ uint32_t vacant_watches = 0;
+ for (uint32_t index = 0; index < num_valid; index++) {
+ lo = GetWatchLo(regs, index);
+ if (lo != 0 && irw == ((uint32_t)lo & irw)) {
+ hi = GetWatchHi(regs, index) | IRW;
+ lo &= ~(lldb::addr_t)hi;
+ if (addr >= lo && last_byte <= (lo + hi))
+ return index;
+ } else
+ vacant_watches++;
+ }
+
+ // Now try to find a vacant index
+ if (vacant_watches > 0) {
+ vacant_watches = 0;
+ for (uint32_t index = 0; index < num_valid; index++) {
+ lo = GetWatchLo(regs, index);
+ if (lo == 0 && irw == (GetIRWMask(regs, index) & irw)) {
+ if (mask <= (GetRegMask(regs, index) | IRW)) {
+ // It fits, we can use it.
+ SetWatchLo(regs, index, base_addr | irw);
+ SetWatchHi(regs, index, mask & ~IRW);
+ return index;
+ } else {
+ // It doesn't fit, but has the proper IRW capabilities
+ vacant_watches++;
}
- else
- vacant_watches++;
+ }
}
- // Now try to find a vacant index
- if(vacant_watches > 0)
- {
- vacant_watches = 0;
- for (uint32_t index = 0; index < num_valid; index++)
- {
- lo = GetWatchLo (regs, index);
- if (lo == 0
- && irw == (GetIRWMask (regs, index) & irw))
- {
- if (mask <= (GetRegMask (regs, index) | IRW))
- {
- // It fits, we can use it.
- SetWatchLo (regs, index, base_addr | irw);
- SetWatchHi (regs, index, mask & ~IRW);
- return index;
- }
- else
- {
- // It doesn't fit, but has the proper IRW capabilities
- vacant_watches++;
- }
- }
- }
-
- if (vacant_watches > 1)
- {
- // Split this watchpoint accross several registers
- struct pt_watch_regs regs_copy;
- regs_copy = *regs;
- lldb::addr_t break_addr;
- uint32_t segment_size;
- for (uint32_t index = 0; index < num_valid; index++)
- {
- lo = GetWatchLo (&regs_copy, index);
- hi = GetRegMask (&regs_copy, index) | IRW;
- if (lo == 0 && irw == (hi & irw))
- {
- lo = addr & ~(lldb::addr_t) hi;
- break_addr = lo + hi + 1;
- if (break_addr >= addr + size)
- segment_size = size;
- else
- segment_size = break_addr - addr;
- mask = GetRangeMask (addr ^ (addr + segment_size - 1));
- SetWatchLo (&regs_copy, index, (addr & ~mask) | irw);
- SetWatchHi (&regs_copy, index, mask & ~IRW);
- if (break_addr >= addr + size)
- {
- *regs = regs_copy;
- return index;
- }
- size = addr + size - break_addr;
- addr = break_addr;
- }
- }
+ if (vacant_watches > 1) {
+ // Split this watchpoint accross several registers
+ struct pt_watch_regs regs_copy;
+ regs_copy = *regs;
+ lldb::addr_t break_addr;
+ uint32_t segment_size;
+ for (uint32_t index = 0; index < num_valid; index++) {
+ lo = GetWatchLo(&regs_copy, index);
+ hi = GetRegMask(&regs_copy, index) | IRW;
+ if (lo == 0 && irw == (hi & irw)) {
+ lo = addr & ~(lldb::addr_t)hi;
+ break_addr = lo + hi + 1;
+ if (break_addr >= addr + size)
+ segment_size = size;
+ else
+ segment_size = break_addr - addr;
+ mask = GetRangeMask(addr ^ (addr + segment_size - 1));
+ SetWatchLo(&regs_copy, index, (addr & ~mask) | irw);
+ SetWatchHi(&regs_copy, index, mask & ~IRW);
+ if (break_addr >= addr + size) {
+ *regs = regs_copy;
+ return index;
+ }
+ size = addr + size - break_addr;
+ addr = break_addr;
}
+ }
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
-bool
-NativeRegisterContextLinux_mips64::IsMSA(uint32_t reg_index) const
-{
- return (m_reg_info.first_msa <= reg_index && reg_index <= m_reg_info.last_msa);
+bool NativeRegisterContextLinux_mips64::IsMSA(uint32_t reg_index) const {
+ return (m_reg_info.first_msa <= reg_index &&
+ reg_index <= m_reg_info.last_msa);
}
-bool
-NativeRegisterContextLinux_mips64::IsMSAAvailable()
-{
- MSA_linux_mips msa_buf;
- unsigned int regset = NT_MIPS_MSA;
+bool NativeRegisterContextLinux_mips64::IsMSAAvailable() {
+ MSA_linux_mips msa_buf;
+ unsigned int regset = NT_MIPS_MSA;
- Error error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, Host::GetCurrentProcessID(), static_cast<void *>(&regset), &msa_buf, sizeof(MSA_linux_mips));
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGSET, Host::GetCurrentProcessID(),
+ static_cast<void *>(&regset), &msa_buf, sizeof(MSA_linux_mips));
- if (error.Success() && msa_buf.mir)
- {
- return true;
- }
+ if (error.Success() && msa_buf.mir) {
+ return true;
+ }
- return false;
+ return false;
}
-Error
-NativeRegisterContextLinux_mips64::IsWatchpointHit (uint32_t wp_index, bool &is_hit)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
-
- // reading the current state of watch regs
- struct pt_watch_regs watch_readback;
- Error error = DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
-
- if (GetWatchHi (&watch_readback, wp_index) & (IRW))
- {
- // clear hit flag in watchhi
- SetWatchHi (&watch_readback, wp_index, (GetWatchHi (&watch_readback, wp_index) & ~(IRW)));
- DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
-
- is_hit = true;
- return error;
- }
- is_hit = false;
+Error NativeRegisterContextLinux_mips64::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+
+ // reading the current state of watch regs
+ struct pt_watch_regs watch_readback;
+ Error error = DoReadWatchPointRegisterValue(
+ m_thread.GetID(), static_cast<void *>(&watch_readback));
+
+ if (GetWatchHi(&watch_readback, wp_index) & (IRW)) {
+ // clear hit flag in watchhi
+ SetWatchHi(&watch_readback, wp_index,
+ (GetWatchHi(&watch_readback, wp_index) & ~(IRW)));
+ DoWriteWatchPointRegisterValue(m_thread.GetID(),
+ static_cast<void *>(&watch_readback));
+
+ is_hit = true;
return error;
+ }
+ is_hit = false;
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) {
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
- {
- bool is_hit;
- Error error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail()) {
- wp_index = LLDB_INVALID_INDEX32;
- } else if (is_hit) {
- return error;
- }
+Error NativeRegisterContextLinux_mips64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ } else if (is_hit) {
+ return error;
}
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
-Error
-NativeRegisterContextLinux_mips64::IsWatchpointVacant (uint32_t wp_index, bool &is_vacant)
-{
- is_vacant = false;
- return Error("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointVacant not implemented");
+Error NativeRegisterContextLinux_mips64::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ is_vacant = false;
+ return Error("MIPS TODO: "
+ "NativeRegisterContextLinux_mips64::IsWatchpointVacant not "
+ "implemented");
}
-bool
-NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- struct pt_watch_regs regs;
- // First reading the current state of watch regs
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void*>(&regs));
-
- if (regs.style == pt_watch_style_mips32)
- {
- regs.mips32.watchlo[wp_index] = default_watch_regs.mips32.watchlo[wp_index];
- regs.mips32.watchhi[wp_index] = default_watch_regs.mips32.watchhi[wp_index];
- regs.mips32.watch_masks[wp_index] = default_watch_regs.mips32.watch_masks[wp_index];
- }
- else // pt_watch_style_mips64
- {
- regs.mips64.watchlo[wp_index] = default_watch_regs.mips64.watchlo[wp_index];
- regs.mips64.watchhi[wp_index] = default_watch_regs.mips64.watchhi[wp_index];
- regs.mips64.watch_masks[wp_index] = default_watch_regs.mips64.watch_masks[wp_index];
- }
-
- Error error = DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- if(!error.Fail())
- {
- hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
- return true;
- }
+bool NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
return false;
+
+ struct pt_watch_regs regs;
+ // First reading the current state of watch regs
+ DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
+
+ if (regs.style == pt_watch_style_mips32) {
+ regs.mips32.watchlo[wp_index] = default_watch_regs.mips32.watchlo[wp_index];
+ regs.mips32.watchhi[wp_index] = default_watch_regs.mips32.watchhi[wp_index];
+ regs.mips32.watch_masks[wp_index] =
+ default_watch_regs.mips32.watch_masks[wp_index];
+ } else // pt_watch_style_mips64
+ {
+ regs.mips64.watchlo[wp_index] = default_watch_regs.mips64.watchlo[wp_index];
+ regs.mips64.watchhi[wp_index] = default_watch_regs.mips64.watchhi[wp_index];
+ regs.mips64.watch_masks[wp_index] =
+ default_watch_regs.mips64.watch_masks[wp_index];
+ }
+
+ Error error = DoWriteWatchPointRegisterValue(m_thread.GetID(),
+ static_cast<void *>(&regs));
+ if (!error.Fail()) {
+ hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
+ return true;
+ }
+ return false;
}
-Error
-NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints()
-{
- return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&default_watch_regs));
+Error NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints() {
+ return DoWriteWatchPointRegisterValue(
+ m_thread.GetID(), static_cast<void *>(&default_watch_regs));
}
-Error
-NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex (
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index)
-{
- Error error;
- error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex not implemented");
- return error;
+Error NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+ Error error;
+ error.SetErrorString("MIPS TODO: "
+ "NativeRegisterContextLinux_mips64::"
+ "SetHardwareWatchpointWithIndex not implemented");
+ return error;
}
-uint32_t
-NativeRegisterContextLinux_mips64::SetHardwareWatchpoint (
- lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- struct pt_watch_regs regs;
+uint32_t NativeRegisterContextLinux_mips64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ struct pt_watch_regs regs;
- // First reading the current state of watch regs
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
+ // First reading the current state of watch regs
+ DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- // Try if a new watch point fits in this state
- int index = GetVacantWatchIndex (&regs, addr, size, watch_flags, NumSupportedHardwareWatchpoints());
+ // Try if a new watch point fits in this state
+ int index = GetVacantWatchIndex(&regs, addr, size, watch_flags,
+ NumSupportedHardwareWatchpoints());
- // New watchpoint doesn't fit
- if (index == LLDB_INVALID_INDEX32)
+ // New watchpoint doesn't fit
+ if (index == LLDB_INVALID_INDEX32)
return LLDB_INVALID_INDEX32;
+ // It fits, so we go ahead with updating the state of watch regs
+ DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- // It fits, so we go ahead with updating the state of watch regs
- DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
- // Storing exact address
- hw_addr_map[index] = addr;
- return index;
+ // Storing exact address
+ hw_addr_map[index] = addr;
+ return index;
}
lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointAddress (uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
+NativeRegisterContextLinux_mips64::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
- return hw_addr_map[wp_index];
+ return hw_addr_map[wp_index];
}
-struct EmulatorBaton
-{
- lldb::addr_t m_watch_hit_addr;
- NativeProcessLinux* m_process;
- NativeRegisterContext* m_reg_context;
-
- EmulatorBaton(NativeProcessLinux* process, NativeRegisterContext* reg_context) :
- m_watch_hit_addr(LLDB_INVALID_ADDRESS),
- m_process(process),
- m_reg_context(reg_context)
- {}
+struct EmulatorBaton {
+ lldb::addr_t m_watch_hit_addr;
+ NativeProcessLinux *m_process;
+ NativeRegisterContext *m_reg_context;
+
+ EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
+ : m_watch_hit_addr(LLDB_INVALID_ADDRESS), m_process(process),
+ m_reg_context(reg_context) {}
};
-static size_t
-ReadMemoryCallback (EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context, lldb::addr_t addr,
- void *dst, size_t length)
-{
- size_t bytes_read;
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
- emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
- return bytes_read;
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length) {
+ size_t bytes_read;
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
+ return bytes_read;
}
-static size_t
-WriteMemoryCallback (EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, const void *dst, size_t length)
-{
- return length;
+static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst,
+ size_t length) {
+ return length;
}
-static bool
-ReadRegisterCallback (EmulateInstruction *instruction, void *baton,
- const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
+static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- const RegisterInfo* full_reg_info = emulator_baton->m_reg_context->GetRegisterInfo(
- lldb::eRegisterKindDWARF, reg_info->kinds[lldb::eRegisterKindDWARF]);
+ const RegisterInfo *full_reg_info =
+ emulator_baton->m_reg_context->GetRegisterInfo(
+ lldb::eRegisterKindDWARF, reg_info->kinds[lldb::eRegisterKindDWARF]);
- Error error = emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
+ Error error =
+ emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
+ if (error.Success())
+ return true;
- return false;
+ return false;
}
-static bool
-WriteRegisterCallback (EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (reg_info->kinds[lldb::eRegisterKindDWARF] == dwarf_bad_mips64)
- {
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
- emulator_baton->m_watch_hit_addr = reg_value.GetAsUInt64 ();
- }
+static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ if (reg_info->kinds[lldb::eRegisterKindDWARF] == dwarf_bad_mips64) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_watch_hit_addr = reg_value.GetAsUInt64();
+ }
- return true;
+ return true;
}
/*
@@ -1333,130 +1083,124 @@ WriteRegisterCallback (EmulateInstruction *instruction, void *baton,
* it can decide to stop or continue the thread.
*/
lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointHitAddress (uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
+NativeRegisterContextLinux_mips64::GetWatchpointHitAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
- lldb_private::ArchSpec arch;
- arch = GetRegisterInfoInterface().GetTargetArchitecture();
- std::unique_ptr<EmulateInstruction> emulator_ap(
- EmulateInstruction::FindPlugin(arch, lldb_private::eInstructionTypeAny, nullptr));
-
- if (emulator_ap == nullptr)
- return LLDB_INVALID_ADDRESS;
-
- EmulatorBaton baton(static_cast<NativeProcessLinux*>(m_thread.GetProcess().get()), this);
- emulator_ap->SetBaton (&baton);
- emulator_ap->SetReadMemCallback (&ReadMemoryCallback);
- emulator_ap->SetReadRegCallback (&ReadRegisterCallback);
- emulator_ap->SetWriteMemCallback (&WriteMemoryCallback);
- emulator_ap->SetWriteRegCallback (&WriteRegisterCallback);
-
- if (!emulator_ap->ReadInstruction())
- return LLDB_INVALID_ADDRESS;
-
- if (emulator_ap->EvaluateInstruction(lldb::eEmulateInstructionOptionNone))
- return baton.m_watch_hit_addr;
+ lldb_private::ArchSpec arch;
+ arch = GetRegisterInfoInterface().GetTargetArchitecture();
+ std::unique_ptr<EmulateInstruction> emulator_ap(
+ EmulateInstruction::FindPlugin(arch, lldb_private::eInstructionTypeAny,
+ nullptr));
+ if (emulator_ap == nullptr)
return LLDB_INVALID_ADDRESS;
+
+ EmulatorBaton baton(
+ static_cast<NativeProcessLinux *>(m_thread.GetProcess().get()), this);
+ emulator_ap->SetBaton(&baton);
+ emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
+ emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
+ emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
+ emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
+
+ if (!emulator_ap->ReadInstruction())
+ return LLDB_INVALID_ADDRESS;
+
+ if (emulator_ap->EvaluateInstruction(lldb::eEmulateInstructionOptionNone))
+ return baton.m_watch_hit_addr;
+
+ return LLDB_INVALID_ADDRESS;
}
-uint32_t
-NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints ()
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- struct pt_watch_regs regs;
- static int num_valid = 0;
- if (!num_valid)
- {
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- default_watch_regs = regs; // Keeping default watch regs values for future use
- switch (regs.style)
- {
- case pt_watch_style_mips32:
- num_valid = regs.mips32.num_valid; // Using num_valid as cache
- return num_valid;
- case pt_watch_style_mips64:
- num_valid = regs.mips64.num_valid;
- return num_valid;
- default:
- if(log)
- log->Printf("NativeRegisterContextLinux_mips64::%s Error: Unrecognized watch register style", __FUNCTION__);
- }
- return 0;
+uint32_t NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ struct pt_watch_regs regs;
+ static int num_valid = 0;
+ if (!num_valid) {
+ DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
+ default_watch_regs =
+ regs; // Keeping default watch regs values for future use
+ switch (regs.style) {
+ case pt_watch_style_mips32:
+ num_valid = regs.mips32.num_valid; // Using num_valid as cache
+ return num_valid;
+ case pt_watch_style_mips64:
+ num_valid = regs.mips64.num_valid;
+ return num_valid;
+ default:
+ if (log)
+ log->Printf("NativeRegisterContextLinux_mips64::%s Error: Unrecognized "
+ "watch register style",
+ __FUNCTION__);
}
- return num_valid;
+ return 0;
+ }
+ return num_valid;
}
Error NativeRegisterContextLinux_mips64::ReadRegisterRaw(uint32_t reg_index,
- RegisterValue &value)
-{
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+ RegisterValue &value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Error("register %" PRIu32 " not found", reg_index);
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
- uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- if ((offset == ptrace_sr_mips) || (offset == ptrace_config5_mips))
- return Read_SR_Config(reg_info->byte_offset, reg_info->name,
- reg_info->byte_size, value);
+ if ((offset == ptrace_sr_mips) || (offset == ptrace_config5_mips))
+ return Read_SR_Config(reg_info->byte_offset, reg_info->name,
+ reg_info->byte_size, value);
- return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
- value);
+ return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
+ value);
}
Error NativeRegisterContextLinux_mips64::WriteRegisterRaw(
- uint32_t reg_index, const RegisterValue &value)
-{
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+ uint32_t reg_index, const RegisterValue &value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Error("register %" PRIu32 " not found", reg_index);
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
- if (reg_info->invalidate_regs)
- lldbassert(false && "reg_info->invalidate_regs is unhandled");
+ if (reg_info->invalidate_regs)
+ lldbassert(false && "reg_info->invalidate_regs is unhandled");
- uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- return DoWriteRegisterValue(offset, reg_info->name, value);
+ uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ return DoWriteRegisterValue(offset, reg_info->name, value);
}
Error NativeRegisterContextLinux_mips64::Read_SR_Config(uint32_t offset,
const char *reg_name,
uint32_t size,
- RegisterValue &value)
-{
- GPR_linux_mips regs;
- ::memset(&regs, 0, sizeof(GPR_linux_mips));
-
- Error error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
- NULL, &regs, sizeof regs);
- if (error.Success())
- {
- lldb_private::ArchSpec arch;
- if (m_thread.GetProcess()->GetArchitecture(arch))
- {
- void *target_address = ((uint8_t *)&regs) + offset +
- 4 * (arch.GetMachine() == llvm::Triple::mips);
- value.SetUInt(*(uint32_t *)target_address, size);
- }
- else
- error.SetErrorString("failed to get architecture");
- }
- return error;
+ RegisterValue &value) {
+ GPR_linux_mips regs;
+ ::memset(&regs, 0, sizeof(GPR_linux_mips));
+
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
+ if (error.Success()) {
+ lldb_private::ArchSpec arch;
+ if (m_thread.GetProcess()->GetArchitecture(arch)) {
+ void *target_address = ((uint8_t *)&regs) + offset +
+ 4 * (arch.GetMachine() == llvm::Triple::mips);
+ value.SetUInt(*(uint32_t *)target_address, size);
+ } else
+ error.SetErrorString("failed to get architecture");
+ }
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback)
-{
- return NativeProcessLinux::PtraceWrapper( PTRACE_GET_WATCH_REGS, m_thread.GetID(), watch_readback);
+Error NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(
+ lldb::tid_t tid, void *watch_readback) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GET_WATCH_REGS,
+ m_thread.GetID(), watch_readback);
}
-Error
-NativeRegisterContextLinux_mips64::DoWriteWatchPointRegisterValue(lldb::tid_t tid, void* watch_reg_value)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS, m_thread.GetID(), watch_reg_value);
+Error NativeRegisterContextLinux_mips64::DoWriteWatchPointRegisterValue(
+ lldb::tid_t tid, void *watch_reg_value) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS,
+ m_thread.GetID(), watch_reg_value);
}
#endif // defined (__mips__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
index 20c32075379c..1b25609205df 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
#ifndef lldb_NativeRegisterContextLinux_mips64_h
#define lldb_NativeRegisterContextLinux_mips64_h
@@ -21,147 +21,115 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_mips64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_mips64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- lldb::addr_t
- GetPCfromBreakpointLocation (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
+ lldb::addr_t GetPCfromBreakpointLocation(
+ lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
- lldb::addr_t
- GetWatchpointHitAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Error
- ReadCP1();
+ Error ReadCP1();
- Error
- WriteCP1();
+ Error WriteCP1();
- Error
- IsWatchpointHit (uint32_t wp_index, bool &is_hit) override;
+ uint8_t *ReturnFPOffset(uint8_t reg_index, uint32_t byte_offset);
- uint8_t *ReturnFPOffset(uint8_t reg_index, uint32_t byte_offset);
+ Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
- Error
- IsWatchpointVacant (uint32_t wp_index, bool &is_vacant) override;
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
- bool
- ClearHardwareWatchpoint (uint32_t wp_index) override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, uint32_t wp_index);
- Error
- SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size,
- uint32_t watch_flags, uint32_t wp_index);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- uint32_t
- SetHardwareWatchpoint (lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- lldb::addr_t
- GetWatchpointAddress (uint32_t wp_index) override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t
- NumSupportedHardwareWatchpoints () override;
+ static bool IsMSAAvailable();
- static bool
- IsMSAAvailable();
-
- protected:
-
- Error
- Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
+protected:
+ Error Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
RegisterValue &value);
- Error
- ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
+ Error ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
- Error
- DoReadWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback);
-
- Error
- WriteRegisterRaw(uint32_t reg_index,
+ Error WriteRegisterRaw(uint32_t reg_index,
const RegisterValue &value) override;
- Error
- DoWriteWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback);
+ Error DoReadWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
+
+ Error DoWriteWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
- bool
- IsFR0();
+ bool IsFR0();
- bool
- IsFRE();
+ bool IsFRE();
- bool
- IsFPR(uint32_t reg_index) const;
+ bool IsFPR(uint32_t reg_index) const;
- bool
- IsMSA(uint32_t reg_index) const;
+ bool IsMSA(uint32_t reg_index) const;
- void*
- GetGPRBuffer() override { return &m_gpr; }
+ void *GetGPRBuffer() override { return &m_gpr; }
- void*
- GetFPRBuffer() override { return &m_fpr; }
+ void *GetFPRBuffer() override { return &m_fpr; }
- size_t
- GetFPRSize() override { return sizeof(FPR_linux_mips); }
+ size_t GetFPRSize() override { return sizeof(FPR_linux_mips); }
- private:
- // Info about register ranges.
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+private:
+ // Info about register ranges.
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- uint32_t first_msa;
- uint32_t last_msa;
- };
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ uint32_t first_msa;
+ uint32_t last_msa;
+ };
- RegInfo m_reg_info;
+ RegInfo m_reg_info;
- GPR_linux_mips m_gpr;
+ GPR_linux_mips m_gpr;
- FPR_linux_mips m_fpr;
+ FPR_linux_mips m_fpr;
- MSA_linux_mips m_msa;
+ MSA_linux_mips m_msa;
- lldb::addr_t hw_addr_map[MAX_NUM_WP];
+ lldb::addr_t hw_addr_map[MAX_NUM_WP];
- IOVEC_mips m_iovec;
- };
+ IOVEC_mips m_iovec;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
index b09ad400d909..7ec4dc551fac 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -30,99 +30,62 @@ using namespace lldb_private::process_linux;
// Private namespace.
// ----------------------------------------------------------------------------
-namespace
-{
- // s390x 64-bit general purpose registers.
- static const uint32_t g_gpr_regnums_s390x[] =
- {
- lldb_r0_s390x,
- lldb_r1_s390x,
- lldb_r2_s390x,
- lldb_r3_s390x,
- lldb_r4_s390x,
- lldb_r5_s390x,
- lldb_r6_s390x,
- lldb_r7_s390x,
- lldb_r8_s390x,
- lldb_r9_s390x,
- lldb_r10_s390x,
- lldb_r11_s390x,
- lldb_r12_s390x,
- lldb_r13_s390x,
- lldb_r14_s390x,
- lldb_r15_s390x,
- lldb_acr0_s390x,
- lldb_acr1_s390x,
- lldb_acr2_s390x,
- lldb_acr3_s390x,
- lldb_acr4_s390x,
- lldb_acr5_s390x,
- lldb_acr6_s390x,
- lldb_acr7_s390x,
- lldb_acr8_s390x,
- lldb_acr9_s390x,
- lldb_acr10_s390x,
- lldb_acr11_s390x,
- lldb_acr12_s390x,
- lldb_acr13_s390x,
- lldb_acr14_s390x,
- lldb_acr15_s390x,
- lldb_pswm_s390x,
- lldb_pswa_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 1 == k_num_gpr_registers_s390x,
- "g_gpr_regnums_s390x has wrong number of register infos");
-
- // s390x 64-bit floating point registers.
- static const uint32_t g_fpu_regnums_s390x[] =
- {
- lldb_f0_s390x,
- lldb_f1_s390x,
- lldb_f2_s390x,
- lldb_f3_s390x,
- lldb_f4_s390x,
- lldb_f5_s390x,
- lldb_f6_s390x,
- lldb_f7_s390x,
- lldb_f8_s390x,
- lldb_f9_s390x,
- lldb_f10_s390x,
- lldb_f11_s390x,
- lldb_f12_s390x,
- lldb_f13_s390x,
- lldb_f14_s390x,
- lldb_f15_s390x,
- lldb_fpc_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 1 == k_num_fpr_registers_s390x,
- "g_fpu_regnums_s390x has wrong number of register infos");
-
- // s390x Linux operating-system information.
- static const uint32_t g_linux_regnums_s390x[] =
- {
- lldb_orig_r2_s390x,
- lldb_last_break_s390x,
- lldb_system_call_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_linux_regnums_s390x) / sizeof(g_linux_regnums_s390x[0])) - 1 == k_num_linux_registers_s390x,
- "g_linux_regnums_s390x has wrong number of register infos");
-
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 3
- };
-
- // Register sets for s390x 64-bit.
- static const RegisterSet g_reg_sets_s390x[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_s390x, g_gpr_regnums_s390x },
- { "Floating Point Registers", "fpr", k_num_fpr_registers_s390x, g_fpu_regnums_s390x },
- { "Linux Operating System Data", "linux", k_num_linux_registers_s390x, g_linux_regnums_s390x },
- };
+namespace {
+// s390x 64-bit general purpose registers.
+static const uint32_t g_gpr_regnums_s390x[] = {
+ lldb_r0_s390x, lldb_r1_s390x, lldb_r2_s390x, lldb_r3_s390x,
+ lldb_r4_s390x, lldb_r5_s390x, lldb_r6_s390x, lldb_r7_s390x,
+ lldb_r8_s390x, lldb_r9_s390x, lldb_r10_s390x, lldb_r11_s390x,
+ lldb_r12_s390x, lldb_r13_s390x, lldb_r14_s390x, lldb_r15_s390x,
+ lldb_acr0_s390x, lldb_acr1_s390x, lldb_acr2_s390x, lldb_acr3_s390x,
+ lldb_acr4_s390x, lldb_acr5_s390x, lldb_acr6_s390x, lldb_acr7_s390x,
+ lldb_acr8_s390x, lldb_acr9_s390x, lldb_acr10_s390x, lldb_acr11_s390x,
+ lldb_acr12_s390x, lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x,
+ lldb_pswm_s390x, lldb_pswa_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
+ 1 ==
+ k_num_gpr_registers_s390x,
+ "g_gpr_regnums_s390x has wrong number of register infos");
+
+// s390x 64-bit floating point registers.
+static const uint32_t g_fpu_regnums_s390x[] = {
+ lldb_f0_s390x, lldb_f1_s390x, lldb_f2_s390x, lldb_f3_s390x,
+ lldb_f4_s390x, lldb_f5_s390x, lldb_f6_s390x, lldb_f7_s390x,
+ lldb_f8_s390x, lldb_f9_s390x, lldb_f10_s390x, lldb_f11_s390x,
+ lldb_f12_s390x, lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x,
+ lldb_fpc_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
+ 1 ==
+ k_num_fpr_registers_s390x,
+ "g_fpu_regnums_s390x has wrong number of register infos");
+
+// s390x Linux operating-system information.
+static const uint32_t g_linux_regnums_s390x[] = {
+ lldb_orig_r2_s390x, lldb_last_break_s390x, lldb_system_call_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_linux_regnums_s390x) /
+ sizeof(g_linux_regnums_s390x[0])) -
+ 1 ==
+ k_num_linux_registers_s390x,
+ "g_linux_regnums_s390x has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 3 };
+
+// Register sets for s390x 64-bit.
+static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
+ g_gpr_regnums_s390x},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
+ g_fpu_regnums_s390x},
+ {"Linux Operating System Data", "linux", k_num_linux_registers_s390x,
+ g_linux_regnums_s390x},
+};
}
#define REG_CONTEXT_SIZE (sizeof(s390_regs) + sizeof(s390_fp_regs) + 4)
@@ -131,15 +94,15 @@ namespace
// Required ptrace defines.
// ----------------------------------------------------------------------------
-#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
+#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
NativeRegisterContextLinux *
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_s390x(target_arch, native_thread, concrete_frame_idx);
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_s390x(target_arch, native_thread,
+ concrete_frame_idx);
}
// ----------------------------------------------------------------------------
@@ -147,570 +110,527 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec
// ----------------------------------------------------------------------------
static RegisterInfoInterface *
-CreateRegisterInfoInterface(const ArchSpec &target_arch)
-{
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- return new RegisterContextLinux_s390x(target_arch);
-}
-
-NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch))
-{
- // Set up data about ranges of valid registers.
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- m_reg_info.num_registers = k_num_registers_s390x;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
- m_reg_info.last_gpr = k_last_gpr_s390x;
- m_reg_info.first_fpr = k_first_fpr_s390x;
- m_reg_info.last_fpr = k_last_fpr_s390x;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- // Clear out the watchpoint state.
- m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ return new RegisterContextLinux_s390x(target_arch);
+}
+
+NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ CreateRegisterInfoInterface(target_arch)) {
+ // Set up data about ranges of valid registers.
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ m_reg_info.num_registers = k_num_registers_s390x;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
+ m_reg_info.last_gpr = k_last_gpr_s390x;
+ m_reg_info.first_fpr = k_first_fpr_s390x;
+ m_reg_info.last_fpr = k_last_fpr_s390x;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Clear out the watchpoint state.
+ m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+}
+
+uint32_t NativeRegisterContextLinux_s390x::GetRegisterSetCount() const {
+ uint32_t sets = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ if (IsRegisterSetAvailable(set_index))
+ ++sets;
+ }
+
+ return sets;
+}
+
+uint32_t NativeRegisterContextLinux_s390x::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ const RegisterSet *set = GetRegisterSet(set_index);
+ if (set)
+ count += set->num_registers;
+ }
+ return count;
}
-uint32_t
-NativeRegisterContextLinux_s390x::GetRegisterSetCount() const
-{
- uint32_t sets = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- if (IsRegisterSetAvailable(set_index))
- ++sets;
- }
+const RegisterSet *
+NativeRegisterContextLinux_s390x::GetRegisterSet(uint32_t set_index) const {
+ if (!IsRegisterSetAvailable(set_index))
+ return nullptr;
- return sets;
-}
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::systemz:
+ return &g_reg_sets_s390x[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
-uint32_t
-NativeRegisterContextLinux_s390x::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- const RegisterSet *set = GetRegisterSet(set_index);
- if (set)
- count += set->num_registers;
- }
- return count;
+ return nullptr;
}
-const RegisterSet *
-NativeRegisterContextLinux_s390x::GetRegisterSet(uint32_t set_index) const
-{
- if (!IsRegisterSetAvailable(set_index))
- return nullptr;
-
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine())
- {
- case llvm::Triple::systemz:
- return &g_reg_sets_s390x[set_index];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+bool NativeRegisterContextLinux_s390x::IsRegisterSetAvailable(
+ uint32_t set_index) const {
+ return set_index < k_num_register_sets;
+}
- return nullptr;
+bool NativeRegisterContextLinux_s390x::IsGPR(uint32_t reg_index) const {
+ // GPRs come first. "orig_r2" counts as GPR since it is part of the GPR
+ // register area.
+ return reg_index <= m_reg_info.last_gpr || reg_index == lldb_orig_r2_s390x;
}
-bool
-NativeRegisterContextLinux_s390x::IsRegisterSetAvailable(uint32_t set_index) const
-{
- return set_index < k_num_register_sets;
-}
-
-bool
-NativeRegisterContextLinux_s390x::IsGPR(uint32_t reg_index) const
-{
- // GPRs come first. "orig_r2" counts as GPR since it is part of the GPR register area.
- return reg_index <= m_reg_info.last_gpr || reg_index == lldb_orig_r2_s390x;
-}
-
-bool
-NativeRegisterContextLinux_s390x::IsFPR(uint32_t reg_index) const
-{
- return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
-}
-
-Error
-NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Error("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
-
- if (IsGPR(reg))
- {
- s390_regs regs;
- Error error = DoReadGPR(&regs, sizeof(regs));
- if (error.Fail())
- return error;
-
- uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
- switch (reg_info->byte_size)
- {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Error();
- }
+bool NativeRegisterContextLinux_s390x::IsFPR(uint32_t reg_index) const {
+ return (m_reg_info.first_fpr <= reg_index &&
+ reg_index <= m_reg_info.last_fpr);
+}
- if (IsFPR(reg))
- {
- s390_fp_regs fp_regs;
- Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
- if (error.Fail())
- return error;
-
- // byte_offset is just the offset within FPR, not the whole user area.
- uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
- switch (reg_info->byte_size)
- {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Error();
- }
+Error NativeRegisterContextLinux_s390x::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
- if (reg == lldb_last_break_s390x)
- {
- uint64_t last_break;
- Error error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
- if (error.Fail())
- return error;
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return Error("register \"%s\" is an internal-only lldb register, cannot "
+ "read directly",
+ reg_info->name);
- reg_value.SetUInt64(last_break);
- return Error();
+ if (IsGPR(reg)) {
+ s390_regs regs;
+ Error error = DoReadGPR(&regs, sizeof(regs));
+ if (error.Fail())
+ return error;
+
+ uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
+ return Error();
+ }
- if (reg == lldb_system_call_s390x)
- {
- uint32_t system_call;
- Error error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- if (error.Fail())
- return error;
-
- reg_value.SetUInt32(system_call);
- return Error();
+ if (IsFPR(reg)) {
+ s390_fp_regs fp_regs;
+ Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
+ if (error.Fail())
+ return error;
+
+ // byte_offset is just the offset within FPR, not the whole user area.
+ uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
+ return Error();
+ }
- return Error("failed - register wasn't recognized");
-}
-
-Error
-NativeRegisterContextLinux_s390x::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Error("register \"%s\" is an internal-only lldb register, cannot write directly", reg_info->name);
-
- if (IsGPR(reg))
- {
- s390_regs regs;
- Error error = DoReadGPR(&regs, sizeof(regs));
- if (error.Fail())
- return error;
-
- uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
- switch (reg_info->byte_size)
- {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteGPR(&regs, sizeof(regs));
- }
+ if (reg == lldb_last_break_s390x) {
+ uint64_t last_break;
+ Error error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
+ if (error.Fail())
+ return error;
- if (IsFPR(reg))
- {
- s390_fp_regs fp_regs;
- Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
- if (error.Fail())
- return error;
-
- // byte_offset is just the offset within fp_regs, not the whole user area.
- uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
- switch (reg_info->byte_size)
- {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteFPR(&fp_regs, sizeof(fp_regs));
- }
+ reg_value.SetUInt64(last_break);
+ return Error();
+ }
- if (reg == lldb_last_break_s390x)
- {
- return Error("The last break address is read-only");
- }
+ if (reg == lldb_system_call_s390x) {
+ uint32_t system_call;
+ Error error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+ if (error.Fail())
+ return error;
- if (reg == lldb_system_call_s390x)
- {
- uint32_t system_call = reg_value.GetAsUInt32();
- return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- }
+ reg_value.SetUInt32(system_call);
+ return Error();
+ }
- return Error("failed - register wasn't recognized");
+ return Error("failed - register wasn't recognized");
}
-Error
-NativeRegisterContextLinux_s390x::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_s390x::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- {
- error.SetErrorStringWithFormat("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
- return error;
- }
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return Error("register \"%s\" is an internal-only lldb register, cannot "
+ "write directly",
+ reg_info->name);
- uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64 " returned a null pointer",
- REG_CONTEXT_SIZE);
- return error;
+ if (IsGPR(reg)) {
+ s390_regs regs;
+ Error error = DoReadGPR(&regs, sizeof(regs));
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
+ return DoWriteGPR(&regs, sizeof(regs));
+ }
- error = DoReadGPR(dst, sizeof(s390_regs));
- dst += sizeof(s390_regs);
+ if (IsFPR(reg)) {
+ s390_fp_regs fp_regs;
+ Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
if (error.Fail())
- return error;
+ return error;
+
+ // byte_offset is just the offset within fp_regs, not the whole user area.
+ uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
+ }
+ return DoWriteFPR(&fp_regs, sizeof(fp_regs));
+ }
- error = DoReadFPR(dst, sizeof(s390_fp_regs));
- dst += sizeof(s390_fp_regs);
- if (error.Fail())
- return error;
+ if (reg == lldb_last_break_s390x) {
+ return Error("The last break address is read-only");
+ }
+
+ if (reg == lldb_system_call_s390x) {
+ uint32_t system_call = reg_value.GetAsUInt32();
+ return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+ }
- // Ignore errors if the regset is unsupported (happens on older kernels).
- DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
- dst += 4;
+ return Error("failed - register wasn't recognized");
+}
- // To enable inferior function calls while the process is stopped in
- // an interrupted system call, we need to clear the system call flag.
- // It will be restored to its original value by WriteAllRegisterValues.
- // Again we ignore error if the regset is unsupported.
- uint32_t system_call = 0;
- DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+Error NativeRegisterContextLinux_s390x::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
return error;
-}
+ }
-Error
-NativeRegisterContextLinux_s390x::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- if (!data_sp)
- {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ error = DoReadGPR(dst, sizeof(s390_regs));
+ dst += sizeof(s390_regs);
+ if (error.Fail())
+ return error;
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_s390x::%s data_sp contained mismatched data size, expected %" PRIu64
- ", actual %" PRIu64,
- __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
+ error = DoReadFPR(dst, sizeof(s390_fp_regs));
+ dst += sizeof(s390_fp_regs);
+ if (error.Fail())
+ return error;
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_s390x::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
+ // Ignore errors if the regset is unsupported (happens on older kernels).
+ DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
+ dst += 4;
- error = DoWriteGPR(src, sizeof(s390_regs));
- src += sizeof(s390_regs);
- if (error.Fail())
- return error;
+ // To enable inferior function calls while the process is stopped in
+ // an interrupted system call, we need to clear the system call flag.
+ // It will be restored to its original value by WriteAllRegisterValues.
+ // Again we ignore error if the regset is unsupported.
+ uint32_t system_call = 0;
+ DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- error = DoWriteFPR(src, sizeof(s390_fp_regs));
- src += sizeof(s390_fp_regs);
- if (error.Fail())
- return error;
+ return error;
+}
- // Ignore errors if the regset is unsupported (happens on older kernels).
- DoWriteRegisterSet(NT_S390_SYSTEM_CALL, src, 4);
- src += 4;
+Error NativeRegisterContextLinux_s390x::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_s390x::%s invalid data_sp provided",
+ __FUNCTION__);
return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_s390x::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+
+ error = DoWriteGPR(src, sizeof(s390_regs));
+ src += sizeof(s390_regs);
+ if (error.Fail())
+ return error;
+
+ error = DoWriteFPR(src, sizeof(s390_fp_regs));
+ src += sizeof(s390_fp_regs);
+ if (error.Fail())
+ return error;
+
+ // Ignore errors if the regset is unsupported (happens on older kernels).
+ DoWriteRegisterSet(NT_S390_SYSTEM_CALL, src, 4);
+ src += 4;
+
+ return error;
}
-Error
-NativeRegisterContextLinux_s390x::DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value)
-{
- return Error("DoReadRegisterValue unsupported");
+Error NativeRegisterContextLinux_s390x::DoReadRegisterValue(
+ uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value) {
+ return Error("DoReadRegisterValue unsupported");
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value)
-{
- return Error("DoWriteRegisterValue unsupported");
+Error NativeRegisterContextLinux_s390x::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ return Error("DoWriteRegisterValue unsupported");
}
-Error
-NativeRegisterContextLinux_s390x::PeekUserArea(uint32_t offset, void *buf, size_t buf_size)
-{
- ptrace_area parea;
- parea.len = buf_size;
- parea.process_addr = (addr_t)buf;
- parea.kernel_addr = offset;
+Error NativeRegisterContextLinux_s390x::PeekUserArea(uint32_t offset, void *buf,
+ size_t buf_size) {
+ ptrace_area parea;
+ parea.len = buf_size;
+ parea.process_addr = (addr_t)buf;
+ parea.kernel_addr = offset;
- return NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSR_AREA, m_thread.GetID(), &parea);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSR_AREA,
+ m_thread.GetID(), &parea);
}
-Error
-NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset, const void *buf, size_t buf_size)
-{
- ptrace_area parea;
- parea.len = buf_size;
- parea.process_addr = (addr_t)buf;
- parea.kernel_addr = offset;
+Error NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset,
+ const void *buf,
+ size_t buf_size) {
+ ptrace_area parea;
+ parea.len = buf_size;
+ parea.process_addr = (addr_t)buf;
+ parea.kernel_addr = offset;
- return NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSR_AREA, m_thread.GetID(), &parea);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSR_AREA,
+ m_thread.GetID(), &parea);
}
-Error
-NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_regs));
- return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_regs));
+ return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_regs));
- return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_regs));
+ return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_fp_regs));
- return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_fp_regs));
+ return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_fp_regs));
- return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_fp_regs));
+ return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size)
-{
- struct iovec iov;
- iov.iov_base = buf;
- iov.iov_len = buf_size;
+Error NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset,
+ void *buf,
+ size_t buf_size) {
+ struct iovec iov;
+ iov.iov_base = buf;
+ iov.iov_len = buf_size;
- return ReadRegisterSet(&iov, buf_size, regset);
+ return ReadRegisterSet(&iov, buf_size, regset);
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size)
-{
- struct iovec iov;
- iov.iov_base = const_cast<void *>(buf);
- iov.iov_len = buf_size;
+Error NativeRegisterContextLinux_s390x::DoWriteRegisterSet(uint32_t regset,
+ const void *buf,
+ size_t buf_size) {
+ struct iovec iov;
+ iov.iov_base = const_cast<void *>(buf);
+ iov.iov_len = buf_size;
- return WriteRegisterSet(&iov, buf_size, regset);
+ return WriteRegisterSet(&iov, buf_size, regset);
}
-Error
-NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
-{
- per_lowcore_bits per_lowcore;
+Error NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ per_lowcore_bits per_lowcore;
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
-
- if (m_watchpoint_addr == LLDB_INVALID_ADDRESS)
- {
- is_hit = false;
- return Error();
- }
-
- Error error = PeekUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore, sizeof(per_lowcore));
- if (error.Fail())
- {
- is_hit = false;
- return error;
- }
-
- is_hit = (per_lowcore.perc_storage_alteration == 1 && per_lowcore.perc_store_real_address == 0);
-
- if (is_hit)
- {
- // Do not report this watchpoint again.
- memset(&per_lowcore, 0, sizeof(per_lowcore));
- PokeUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore, sizeof(per_lowcore));
- }
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+ if (m_watchpoint_addr == LLDB_INVALID_ADDRESS) {
+ is_hit = false;
return Error();
-}
+ }
-Error
-NativeRegisterContextLinux_s390x::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
-{
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
- {
- bool is_hit;
- Error error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail())
- {
- wp_index = LLDB_INVALID_INDEX32;
- return error;
- }
- else if (is_hit)
- {
- return error;
- }
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info.lowcore),
+ &per_lowcore, sizeof(per_lowcore));
+ if (error.Fail()) {
+ is_hit = false;
+ return error;
+ }
+
+ is_hit = (per_lowcore.perc_storage_alteration == 1 &&
+ per_lowcore.perc_store_real_address == 0);
+
+ if (is_hit) {
+ // Do not report this watchpoint again.
+ memset(&per_lowcore, 0, sizeof(per_lowcore));
+ PokeUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore,
+ sizeof(per_lowcore));
+ }
+
+ return Error();
+}
+
+Error NativeRegisterContextLinux_s390x::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
}
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
-Error
-NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index, bool &is_vacant)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
+Error NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;
+ is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;
- return Error();
+ return Error();
}
-bool
-NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(uint32_t wp_index)
-{
- per_struct per_info;
+bool NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ per_struct per_info;
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
- Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return false;
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return false;
- per_info.control_regs.bits.em_storage_alteration = 0;
- per_info.control_regs.bits.storage_alt_space_ctl = 0;
- per_info.starting_addr = 0;
- per_info.ending_addr = 0;
+ per_info.control_regs.bits.em_storage_alteration = 0;
+ per_info.control_regs.bits.storage_alt_space_ctl = 0;
+ per_info.starting_addr = 0;
+ per_info.ending_addr = 0;
- error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return false;
+ error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return false;
- m_watchpoint_addr = LLDB_INVALID_ADDRESS;
- return true;
+ m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+ return true;
}
-Error
-NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints()
-{
- if (ClearHardwareWatchpoint(0))
- return Error();
- return Error("Clearing all hardware watchpoints failed.");
+Error NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints() {
+ if (ClearHardwareWatchpoint(0))
+ return Error();
+ return Error("Clearing all hardware watchpoints failed.");
}
-uint32_t
-NativeRegisterContextLinux_s390x::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- per_struct per_info;
+uint32_t NativeRegisterContextLinux_s390x::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ per_struct per_info;
- if (watch_flags != 0x1)
- return LLDB_INVALID_INDEX32;
+ if (watch_flags != 0x1)
+ return LLDB_INVALID_INDEX32;
- if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_INDEX32;
+ if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_INDEX32;
- Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- per_info.control_regs.bits.em_storage_alteration = 1;
- per_info.control_regs.bits.storage_alt_space_ctl = 1;
- per_info.starting_addr = addr;
- per_info.ending_addr = addr + size - 1;
+ per_info.control_regs.bits.em_storage_alteration = 1;
+ per_info.control_regs.bits.storage_alt_space_ctl = 1;
+ per_info.starting_addr = addr;
+ per_info.ending_addr = addr + size - 1;
- error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
+ error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- m_watchpoint_addr = addr;
- return 0;
+ m_watchpoint_addr = addr;
+ return 0;
}
lldb::addr_t
-NativeRegisterContextLinux_s390x::GetWatchpointAddress(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
- return m_watchpoint_addr;
+NativeRegisterContextLinux_s390x::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ return m_watchpoint_addr;
}
-uint32_t
-NativeRegisterContextLinux_s390x::NumSupportedHardwareWatchpoints()
-{
- return 1;
+uint32_t NativeRegisterContextLinux_s390x::NumSupportedHardwareWatchpoints() {
+ return 1;
}
#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
index 8cd4ab7f1242..4bd737767fa4 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
@@ -16,121 +16,96 @@
#include "Plugins/Process/Utility/RegisterContext_s390x.h"
#include "Plugins/Process/Utility/lldb-s390x-register-enums.h"
-namespace lldb_private
-{
-namespace process_linux
-{
+namespace lldb_private {
+namespace process_linux {
class NativeProcessLinux;
-class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux
-{
+class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux {
public:
- NativeRegisterContextLinux_s390x(const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount() const override;
+ uint32_t GetRegisterSetCount() const override;
- const RegisterSet *
- GetRegisterSet(uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- Error
- ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Error
- IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+ Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- Error
- IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+ Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
- bool
- ClearHardwareWatchpoint(uint32_t wp_index) override;
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
- Error
- ClearAllHardwareWatchpoints() override;
+ Error ClearAllHardwareWatchpoints() override;
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- lldb::addr_t
- GetWatchpointAddress(uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- NumSupportedHardwareWatchpoints() override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
protected:
- Error
- DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size, RegisterValue &value) override;
+ Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value) override;
- Error
- DoWriteRegisterValue(uint32_t offset, const char *reg_name, const RegisterValue &value) override;
+ Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
+ const RegisterValue &value) override;
- Error
- DoReadGPR(void *buf, size_t buf_size) override;
+ Error DoReadGPR(void *buf, size_t buf_size) override;
- Error
- DoWriteGPR(void *buf, size_t buf_size) override;
+ Error DoWriteGPR(void *buf, size_t buf_size) override;
- Error
- DoReadFPR(void *buf, size_t buf_size) override;
+ Error DoReadFPR(void *buf, size_t buf_size) override;
- Error
- DoWriteFPR(void *buf, size_t buf_size) override;
+ Error DoWriteFPR(void *buf, size_t buf_size) override;
private:
- // Info about register ranges.
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+ // Info about register ranges.
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- };
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ };
- // Private member variables.
- RegInfo m_reg_info;
- lldb::addr_t m_watchpoint_addr;
+ // Private member variables.
+ RegInfo m_reg_info;
+ lldb::addr_t m_watchpoint_addr;
- // Private member methods.
- bool
- IsRegisterSetAvailable(uint32_t set_index) const;
+ // Private member methods.
+ bool IsRegisterSetAvailable(uint32_t set_index) const;
- bool
- IsGPR(uint32_t reg_index) const;
+ bool IsGPR(uint32_t reg_index) const;
- bool
- IsFPR(uint32_t reg_index) const;
+ bool IsFPR(uint32_t reg_index) const;
- Error
- PeekUserArea(uint32_t offset, void *buf, size_t buf_size);
+ Error PeekUserArea(uint32_t offset, void *buf, size_t buf_size);
- Error
- PokeUserArea(uint32_t offset, const void *buf, size_t buf_size);
+ Error PokeUserArea(uint32_t offset, const void *buf, size_t buf_size);
- Error
- DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size);
+ Error DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size);
- Error
- DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size);
+ Error DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size);
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 2080d2ede372..2bd819b456ab 100755
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -11,15 +11,17 @@
#include "NativeRegisterContextLinux_x86_64.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+#include <linux/elf.h>
+
using namespace lldb_private;
using namespace lldb_private::process_linux;
@@ -27,297 +29,184 @@ using namespace lldb_private::process_linux;
// Private namespace.
// ----------------------------------------------------------------------------
-namespace
-{
- // x86 32-bit general purpose registers.
- const uint32_t
- g_gpr_regnums_i386[] =
- {
- lldb_eax_i386,
- lldb_ebx_i386,
- lldb_ecx_i386,
- lldb_edx_i386,
- lldb_edi_i386,
- lldb_esi_i386,
- lldb_ebp_i386,
- lldb_esp_i386,
- lldb_eip_i386,
- lldb_eflags_i386,
- lldb_cs_i386,
- lldb_fs_i386,
- lldb_gs_i386,
- lldb_ss_i386,
- lldb_ds_i386,
- lldb_es_i386,
- lldb_ax_i386,
- lldb_bx_i386,
- lldb_cx_i386,
- lldb_dx_i386,
- lldb_di_i386,
- lldb_si_i386,
- lldb_bp_i386,
- lldb_sp_i386,
- lldb_ah_i386,
- lldb_bh_i386,
- lldb_ch_i386,
- lldb_dh_i386,
- lldb_al_i386,
- lldb_bl_i386,
- lldb_cl_i386,
- lldb_dl_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 1 == k_num_gpr_registers_i386,
- "g_gpr_regnums_i386 has wrong number of register infos");
-
- // x86 32-bit floating point registers.
- const uint32_t
- g_fpu_regnums_i386[] =
- {
- lldb_fctrl_i386,
- lldb_fstat_i386,
- lldb_ftag_i386,
- lldb_fop_i386,
- lldb_fiseg_i386,
- lldb_fioff_i386,
- lldb_foseg_i386,
- lldb_fooff_i386,
- lldb_mxcsr_i386,
- lldb_mxcsrmask_i386,
- lldb_st0_i386,
- lldb_st1_i386,
- lldb_st2_i386,
- lldb_st3_i386,
- lldb_st4_i386,
- lldb_st5_i386,
- lldb_st6_i386,
- lldb_st7_i386,
- lldb_mm0_i386,
- lldb_mm1_i386,
- lldb_mm2_i386,
- lldb_mm3_i386,
- lldb_mm4_i386,
- lldb_mm5_i386,
- lldb_mm6_i386,
- lldb_mm7_i386,
- lldb_xmm0_i386,
- lldb_xmm1_i386,
- lldb_xmm2_i386,
- lldb_xmm3_i386,
- lldb_xmm4_i386,
- lldb_xmm5_i386,
- lldb_xmm6_i386,
- lldb_xmm7_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - 1 == k_num_fpr_registers_i386,
- "g_fpu_regnums_i386 has wrong number of register infos");
-
- // x86 32-bit AVX registers.
- const uint32_t
- g_avx_regnums_i386[] =
- {
- lldb_ymm0_i386,
- lldb_ymm1_i386,
- lldb_ymm2_i386,
- lldb_ymm3_i386,
- lldb_ymm4_i386,
- lldb_ymm5_i386,
- lldb_ymm6_i386,
- lldb_ymm7_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 == k_num_avx_registers_i386,
- " g_avx_regnums_i386 has wrong number of register infos");
-
- // x86 64-bit general purpose registers.
- static const
- uint32_t g_gpr_regnums_x86_64[] =
- {
- lldb_rax_x86_64,
- lldb_rbx_x86_64,
- lldb_rcx_x86_64,
- lldb_rdx_x86_64,
- lldb_rdi_x86_64,
- lldb_rsi_x86_64,
- lldb_rbp_x86_64,
- lldb_rsp_x86_64,
- lldb_r8_x86_64,
- lldb_r9_x86_64,
- lldb_r10_x86_64,
- lldb_r11_x86_64,
- lldb_r12_x86_64,
- lldb_r13_x86_64,
- lldb_r14_x86_64,
- lldb_r15_x86_64,
- lldb_rip_x86_64,
- lldb_rflags_x86_64,
- lldb_cs_x86_64,
- lldb_fs_x86_64,
- lldb_gs_x86_64,
- lldb_ss_x86_64,
- lldb_ds_x86_64,
- lldb_es_x86_64,
- lldb_eax_x86_64,
- lldb_ebx_x86_64,
- lldb_ecx_x86_64,
- lldb_edx_x86_64,
- lldb_edi_x86_64,
- lldb_esi_x86_64,
- lldb_ebp_x86_64,
- lldb_esp_x86_64,
- lldb_r8d_x86_64, // Low 32 bits or r8
- lldb_r9d_x86_64, // Low 32 bits or r9
- lldb_r10d_x86_64, // Low 32 bits or r10
- lldb_r11d_x86_64, // Low 32 bits or r11
- lldb_r12d_x86_64, // Low 32 bits or r12
- lldb_r13d_x86_64, // Low 32 bits or r13
- lldb_r14d_x86_64, // Low 32 bits or r14
- lldb_r15d_x86_64, // Low 32 bits or r15
- lldb_ax_x86_64,
- lldb_bx_x86_64,
- lldb_cx_x86_64,
- lldb_dx_x86_64,
- lldb_di_x86_64,
- lldb_si_x86_64,
- lldb_bp_x86_64,
- lldb_sp_x86_64,
- lldb_r8w_x86_64, // Low 16 bits or r8
- lldb_r9w_x86_64, // Low 16 bits or r9
- lldb_r10w_x86_64, // Low 16 bits or r10
- lldb_r11w_x86_64, // Low 16 bits or r11
- lldb_r12w_x86_64, // Low 16 bits or r12
- lldb_r13w_x86_64, // Low 16 bits or r13
- lldb_r14w_x86_64, // Low 16 bits or r14
- lldb_r15w_x86_64, // Low 16 bits or r15
- lldb_ah_x86_64,
- lldb_bh_x86_64,
- lldb_ch_x86_64,
- lldb_dh_x86_64,
- lldb_al_x86_64,
- lldb_bl_x86_64,
- lldb_cl_x86_64,
- lldb_dl_x86_64,
- lldb_dil_x86_64,
- lldb_sil_x86_64,
- lldb_bpl_x86_64,
- lldb_spl_x86_64,
- lldb_r8l_x86_64, // Low 8 bits or r8
- lldb_r9l_x86_64, // Low 8 bits or r9
- lldb_r10l_x86_64, // Low 8 bits or r10
- lldb_r11l_x86_64, // Low 8 bits or r11
- lldb_r12l_x86_64, // Low 8 bits or r12
- lldb_r13l_x86_64, // Low 8 bits or r13
- lldb_r14l_x86_64, // Low 8 bits or r14
- lldb_r15l_x86_64, // Low 8 bits or r15
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 1 == k_num_gpr_registers_x86_64,
- "g_gpr_regnums_x86_64 has wrong number of register infos");
-
- // x86 64-bit floating point registers.
- static const uint32_t
- g_fpu_regnums_x86_64[] =
- {
- lldb_fctrl_x86_64,
- lldb_fstat_x86_64,
- lldb_ftag_x86_64,
- lldb_fop_x86_64,
- lldb_fiseg_x86_64,
- lldb_fioff_x86_64,
- lldb_foseg_x86_64,
- lldb_fooff_x86_64,
- lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64,
- lldb_st0_x86_64,
- lldb_st1_x86_64,
- lldb_st2_x86_64,
- lldb_st3_x86_64,
- lldb_st4_x86_64,
- lldb_st5_x86_64,
- lldb_st6_x86_64,
- lldb_st7_x86_64,
- lldb_mm0_x86_64,
- lldb_mm1_x86_64,
- lldb_mm2_x86_64,
- lldb_mm3_x86_64,
- lldb_mm4_x86_64,
- lldb_mm5_x86_64,
- lldb_mm6_x86_64,
- lldb_mm7_x86_64,
- lldb_xmm0_x86_64,
- lldb_xmm1_x86_64,
- lldb_xmm2_x86_64,
- lldb_xmm3_x86_64,
- lldb_xmm4_x86_64,
- lldb_xmm5_x86_64,
- lldb_xmm6_x86_64,
- lldb_xmm7_x86_64,
- lldb_xmm8_x86_64,
- lldb_xmm9_x86_64,
- lldb_xmm10_x86_64,
- lldb_xmm11_x86_64,
- lldb_xmm12_x86_64,
- lldb_xmm13_x86_64,
- lldb_xmm14_x86_64,
- lldb_xmm15_x86_64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 1 == k_num_fpr_registers_x86_64,
- "g_fpu_regnums_x86_64 has wrong number of register infos");
-
- // x86 64-bit AVX registers.
- static const uint32_t
- g_avx_regnums_x86_64[] =
- {
- lldb_ymm0_x86_64,
- lldb_ymm1_x86_64,
- lldb_ymm2_x86_64,
- lldb_ymm3_x86_64,
- lldb_ymm4_x86_64,
- lldb_ymm5_x86_64,
- lldb_ymm6_x86_64,
- lldb_ymm7_x86_64,
- lldb_ymm8_x86_64,
- lldb_ymm9_x86_64,
- lldb_ymm10_x86_64,
- lldb_ymm11_x86_64,
- lldb_ymm12_x86_64,
- lldb_ymm13_x86_64,
- lldb_ymm14_x86_64,
- lldb_ymm15_x86_64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == k_num_avx_registers_x86_64,
- "g_avx_regnums_x86_64 has wrong number of register infos");
-
- // Number of register sets provided by this context.
- enum
- {
- k_num_extended_register_sets = 1,
- k_num_register_sets = 3
- };
-
- // Register sets for x86 32-bit.
- static const RegisterSet
- g_reg_sets_i386[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_fpu_regnums_i386 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
- };
-
- // Register sets for x86 64-bit.
- static const RegisterSet
- g_reg_sets_x86_64[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 }
- };
+namespace {
+// x86 32-bit general purpose registers.
+const uint32_t g_gpr_regnums_i386[] = {
+ lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
+ lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
+ lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
+ lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
+ lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
+ lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
+ lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
+ lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
+ 1 ==
+ k_num_gpr_registers_i386,
+ "g_gpr_regnums_i386 has wrong number of register infos");
+
+// x86 32-bit floating point registers.
+const uint32_t g_fpu_regnums_i386[] = {
+ lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
+ lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
+ lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
+ lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
+ lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
+ lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
+ lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
+ lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
+ lldb_xmm6_i386, lldb_xmm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
+ 1 ==
+ k_num_fpr_registers_i386,
+ "g_fpu_regnums_i386 has wrong number of register infos");
+
+// x86 32-bit AVX registers.
+const uint32_t g_avx_regnums_i386[] = {
+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
+ 1 ==
+ k_num_avx_registers_i386,
+ " g_avx_regnums_i386 has wrong number of register infos");
+
+// x64 32-bit MPX registers.
+static const uint32_t g_mpx_regnums_i386[] = {
+ lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386, lldb_bnd3_i386,
+ lldb_bndcfgu_i386, lldb_bndstatus_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
+ 1 ==
+ k_num_mpx_registers_i386,
+ "g_mpx_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit general purpose registers.
+static const uint32_t g_gpr_regnums_x86_64[] = {
+ lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
+ lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
+ lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
+ lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
+ lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
+ lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
+ lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
+ lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits or r8
+ lldb_r9d_x86_64, // Low 32 bits or r9
+ lldb_r10d_x86_64, // Low 32 bits or r10
+ lldb_r11d_x86_64, // Low 32 bits or r11
+ lldb_r12d_x86_64, // Low 32 bits or r12
+ lldb_r13d_x86_64, // Low 32 bits or r13
+ lldb_r14d_x86_64, // Low 32 bits or r14
+ lldb_r15d_x86_64, // Low 32 bits or r15
+ lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
+ lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits or r8
+ lldb_r9w_x86_64, // Low 16 bits or r9
+ lldb_r10w_x86_64, // Low 16 bits or r10
+ lldb_r11w_x86_64, // Low 16 bits or r11
+ lldb_r12w_x86_64, // Low 16 bits or r12
+ lldb_r13w_x86_64, // Low 16 bits or r13
+ lldb_r14w_x86_64, // Low 16 bits or r14
+ lldb_r15w_x86_64, // Low 16 bits or r15
+ lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
+ lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
+ lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
+ lldb_r8l_x86_64, // Low 8 bits or r8
+ lldb_r9l_x86_64, // Low 8 bits or r9
+ lldb_r10l_x86_64, // Low 8 bits or r10
+ lldb_r11l_x86_64, // Low 8 bits or r11
+ lldb_r12l_x86_64, // Low 8 bits or r12
+ lldb_r13l_x86_64, // Low 8 bits or r13
+ lldb_r14l_x86_64, // Low 8 bits or r14
+ lldb_r15l_x86_64, // Low 8 bits or r15
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
+ 1 ==
+ k_num_gpr_registers_x86_64,
+ "g_gpr_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit floating point registers.
+static const uint32_t g_fpu_regnums_x86_64[] = {
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+ lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
+ lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
+ lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
+ lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
+ lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
+ lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
+ lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
+ lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
+ lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
+ lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
+ lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
+ 1 ==
+ k_num_fpr_registers_x86_64,
+ "g_fpu_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit AVX registers.
+static const uint32_t g_avx_regnums_x86_64[] = {
+ lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
+ lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
+ lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
+ lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit MPX registers.
+static const uint32_t g_mpx_regnums_x86_64[] = {
+ lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64,
+ lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_mpx_registers_x86_64,
+ "g_mpx_regnums_x86_64 has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 };
+
+// Register sets for x86 32-bit.
+static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
+ g_gpr_regnums_i386},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
+ g_fpu_regnums_i386},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
+ g_avx_regnums_i386},
+ { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
+ g_mpx_regnums_i386}};
+
+// Register sets for x86 64-bit.
+static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
+ g_gpr_regnums_x86_64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
+ g_fpu_regnums_x86_64},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
+ g_avx_regnums_x86_64},
+ { "Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64,
+ g_mpx_regnums_x86_64}};
}
-#define REG_CONTEXT_SIZE (GetRegisterInfoInterface ().GetGPRSize () + sizeof(FPR))
+#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
// ----------------------------------------------------------------------------
// Required ptrace defines.
@@ -331,909 +220,1002 @@ namespace
#define NT_PRXFPREG 0x46e62b7f
#endif
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_x86_64(target_arch, native_thread, concrete_frame_idx);
+// On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to
+// use NT_PRXFPREG.
+static inline unsigned int fxsr_regset(const ArchSpec &arch) {
+ return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
}
// ----------------------------------------------------------------------------
-// NativeRegisterContextLinux_x86_64 members.
+// Required MPX define.
// ----------------------------------------------------------------------------
-static RegisterInfoInterface*
-CreateRegisterInfoInterface(const ArchSpec& target_arch)
-{
- if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
- {
- // 32-bit hosts run with a RegisterContextLinux_i386 context.
- return new RegisterContextLinux_i386(target_arch);
- }
- else
- {
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
- return new RegisterContextLinux_x86_64 (target_arch);
- }
-}
+// Support MPX extensions also if compiled with compiler without MPX support.
+#ifndef bit_MPX
+#define bit_MPX 0x4000
+#endif
-NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch)),
- m_fpr_type (eFPRTypeNotValid),
- m_fpr (),
- m_iovec (),
- m_ymm_set (),
- m_reg_info (),
- m_gpr_x86_64 ()
-{
- // Set up data about ranges of valid registers.
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::x86:
- m_reg_info.num_registers = k_num_registers_i386;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
- m_reg_info.num_avx_registers = k_num_avx_registers_i386;
- m_reg_info.last_gpr = k_last_gpr_i386;
- m_reg_info.first_fpr = k_first_fpr_i386;
- m_reg_info.last_fpr = k_last_fpr_i386;
- m_reg_info.first_st = lldb_st0_i386;
- m_reg_info.last_st = lldb_st7_i386;
- m_reg_info.first_mm = lldb_mm0_i386;
- m_reg_info.last_mm = lldb_mm7_i386;
- m_reg_info.first_xmm = lldb_xmm0_i386;
- m_reg_info.last_xmm = lldb_xmm7_i386;
- m_reg_info.first_ymm = lldb_ymm0_i386;
- m_reg_info.last_ymm = lldb_ymm7_i386;
- m_reg_info.first_dr = lldb_dr0_i386;
- m_reg_info.gpr_flags = lldb_eflags_i386;
- break;
- case llvm::Triple::x86_64:
- m_reg_info.num_registers = k_num_registers_x86_64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
- m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
- m_reg_info.last_gpr = k_last_gpr_x86_64;
- m_reg_info.first_fpr = k_first_fpr_x86_64;
- m_reg_info.last_fpr = k_last_fpr_x86_64;
- m_reg_info.first_st = lldb_st0_x86_64;
- m_reg_info.last_st = lldb_st7_x86_64;
- m_reg_info.first_mm = lldb_mm0_x86_64;
- m_reg_info.last_mm = lldb_mm7_x86_64;
- m_reg_info.first_xmm = lldb_xmm0_x86_64;
- m_reg_info.last_xmm = lldb_xmm15_x86_64;
- m_reg_info.first_ymm = lldb_ymm0_x86_64;
- m_reg_info.last_ymm = lldb_ymm15_x86_64;
- m_reg_info.first_dr = lldb_dr0_x86_64;
- m_reg_info.gpr_flags = lldb_rflags_x86_64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+// ----------------------------------------------------------------------------
+// XCR0 extended register sets masks.
+// ----------------------------------------------------------------------------
+#define mask_XSTATE_AVX (1ULL << 2)
+#define mask_XSTATE_BNDREGS (1ULL << 3)
+#define mask_XSTATE_BNDCFG (1ULL << 4)
+#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
+
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_x86_64(target_arch, native_thread,
+ concrete_frame_idx);
+}
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+// ----------------------------------------------------------------------------
+// NativeRegisterContextLinux_x86_64 members.
+// ----------------------------------------------------------------------------
- // Clear out the FPR state.
- ::memset(&m_fpr, 0, sizeof(FPR));
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ // 32-bit hosts run with a RegisterContextLinux_i386 context.
+ return new RegisterContextLinux_i386(target_arch);
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
+ // x86_64 register context.
+ return new RegisterContextLinux_x86_64(target_arch);
+ }
+}
- // Store byte offset of fctrl (i.e. first register of FPR)
- const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
- m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
+NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ CreateRegisterInfoInterface(target_arch)),
+ m_xstate_type(XStateType::Invalid), m_fpr(), m_iovec(), m_ymm_set(),
+ m_mpx_set(), m_reg_info(), m_gpr_x86_64() {
+ // Set up data about ranges of valid registers.
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ m_reg_info.num_registers = k_num_registers_i386;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
+ m_reg_info.num_avx_registers = k_num_avx_registers_i386;
+ m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
+ m_reg_info.last_gpr = k_last_gpr_i386;
+ m_reg_info.first_fpr = k_first_fpr_i386;
+ m_reg_info.last_fpr = k_last_fpr_i386;
+ m_reg_info.first_st = lldb_st0_i386;
+ m_reg_info.last_st = lldb_st7_i386;
+ m_reg_info.first_mm = lldb_mm0_i386;
+ m_reg_info.last_mm = lldb_mm7_i386;
+ m_reg_info.first_xmm = lldb_xmm0_i386;
+ m_reg_info.last_xmm = lldb_xmm7_i386;
+ m_reg_info.first_ymm = lldb_ymm0_i386;
+ m_reg_info.last_ymm = lldb_ymm7_i386;
+ m_reg_info.first_mpxr = lldb_bnd0_i386;
+ m_reg_info.last_mpxr = lldb_bnd3_i386;
+ m_reg_info.first_mpxc = lldb_bndcfgu_i386;
+ m_reg_info.last_mpxc = lldb_bndstatus_i386;
+ m_reg_info.first_dr = lldb_dr0_i386;
+ m_reg_info.gpr_flags = lldb_eflags_i386;
+ break;
+ case llvm::Triple::x86_64:
+ m_reg_info.num_registers = k_num_registers_x86_64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
+ m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
+ m_reg_info.num_mpx_registers = k_num_mpx_registers_x86_64;
+ m_reg_info.last_gpr = k_last_gpr_x86_64;
+ m_reg_info.first_fpr = k_first_fpr_x86_64;
+ m_reg_info.last_fpr = k_last_fpr_x86_64;
+ m_reg_info.first_st = lldb_st0_x86_64;
+ m_reg_info.last_st = lldb_st7_x86_64;
+ m_reg_info.first_mm = lldb_mm0_x86_64;
+ m_reg_info.last_mm = lldb_mm7_x86_64;
+ m_reg_info.first_xmm = lldb_xmm0_x86_64;
+ m_reg_info.last_xmm = lldb_xmm15_x86_64;
+ m_reg_info.first_ymm = lldb_ymm0_x86_64;
+ m_reg_info.last_ymm = lldb_ymm15_x86_64;
+ m_reg_info.first_mpxr = lldb_bnd0_x86_64;
+ m_reg_info.last_mpxr = lldb_bnd3_x86_64;
+ m_reg_info.first_mpxc = lldb_bndcfgu_x86_64;
+ m_reg_info.last_mpxc = lldb_bndstatus_x86_64;
+ m_reg_info.first_dr = lldb_dr0_x86_64;
+ m_reg_info.gpr_flags = lldb_rflags_x86_64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_fpr.xstate.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+
+ // Clear out the FPR state.
+ ::memset(&m_fpr, 0, sizeof(FPR));
+
+ // Store byte offset of fctrl (i.e. first register of FPR)
+ const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
+ m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
}
// CONSIDER after local and llgs debugging are merged, register set support can
// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
-uint32_t
-NativeRegisterContextLinux_x86_64::GetRegisterSetCount () const
-{
- uint32_t sets = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- if (IsRegisterSetAvailable (set_index))
- ++sets;
- }
-
- return sets;
+uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {
+ uint32_t sets = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ if (IsRegisterSetAvailable(set_index))
+ ++sets;
+ }
+
+ return sets;
}
-uint32_t
-NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- const RegisterSet* set = GetRegisterSet(set_index);
- if (set)
- count += set->num_registers;
- }
- return count;
+uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ const RegisterSet *set = GetRegisterSet(set_index);
+ if (set)
+ count += set->num_registers;
+ }
+ return count;
}
const RegisterSet *
-NativeRegisterContextLinux_x86_64::GetRegisterSet (uint32_t set_index) const
-{
- if (!IsRegisterSetAvailable (set_index))
- return nullptr;
-
- switch (GetRegisterInfoInterface ().GetTargetArchitecture ().GetMachine ())
- {
- case llvm::Triple::x86:
- return &g_reg_sets_i386[set_index];
- case llvm::Triple::x86_64:
- return &g_reg_sets_x86_64[set_index];
- default:
- assert (false && "Unhandled target architecture.");
- return nullptr;
- }
+NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const {
+ if (!IsRegisterSetAvailable(set_index))
+ return nullptr;
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ return &g_reg_sets_i386[set_index];
+ case llvm::Triple::x86_64:
+ return &g_reg_sets_x86_64[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
return nullptr;
-}
+ }
-Error
-NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
+ return nullptr;
+}
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
- }
+Error NativeRegisterContextLinux_x86_64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ Error error;
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- {
- // This is likely an internal register for lldb use only and should not be directly queried.
- error.SetErrorStringWithFormat ("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
- return error;
- }
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
- if (IsFPR(reg, GetFPRType()))
- {
- error = ReadFPR();
- if (error.Fail())
- return error;
+ if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- error = ReadRegisterRaw(full_reg, reg_value);
+ error = ReadRegisterRaw(full_reg, reg_value);
- if (error.Success ())
- {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
+ if (error.Success()) {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
+ // one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (reg_value.GetByteSize() > reg_info->byte_size)
+ reg_value.SetType(reg_info);
}
-
- if (reg_info->encoding == lldb::eEncodingVector)
- {
- lldb::ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != lldb::eByteOrderInvalid)
- {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- reg_value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- reg_value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- reg_value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
- {
- // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
- if (GetFPRType() == eFPRTypeXSAVE && CopyXSTATEtoYMM(reg, byte_order))
- reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order);
- else
- {
- error.SetErrorString ("failed to copy ymm register value");
- return error;
- }
- }
-
- if (reg_value.GetType() != RegisterValue::eTypeBytes)
- error.SetErrorString ("write failed - type was expected to be RegisterValue::eTypeBytes");
-
- return error;
+ return error;
+ }
+
+ if (reg_info->encoding == lldb::eEncodingVector) {
+ lldb::ByteOrder byte_order = GetByteOrder();
+
+ if (byte_order != lldb::eByteOrderInvalid) {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ reg_value.SetBytes(
+ m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
+ reg_value.SetBytes(
+ m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
+ reg_value.SetBytes(
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
+ // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
+ if (CopyXSTATEtoYMM(reg, byte_order))
+ reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ reg_info->byte_size, byte_order);
+ else {
+ error.SetErrorString("failed to copy ymm register value");
+ return error;
}
+ }
+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
+ if (CopyXSTATEtoMPX(reg))
+ reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ reg_info->byte_size, byte_order);
+ else {
+ error.SetErrorString("failed to copy mpx register value");
+ return error;
+ }
+ }
+ if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
+ if (CopyXSTATEtoMPX(reg))
+ reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ reg_info->byte_size, byte_order);
+ else {
+ error.SetErrorString("failed to copy mpx register value");
+ return error;
+ }
+ }
- error.SetErrorString ("byte order is invalid");
- return error;
- }
+ if (reg_value.GetType() != RegisterValue::eTypeBytes)
+ error.SetErrorString(
+ "write failed - type was expected to be RegisterValue::eTypeBytes");
- // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
-
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
- // and stores them in 'm_fpr' (of type FPR structure). To extract values of fpu
- // registers, m_fpr should be read at byte offsets calculated wrt to FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
- assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size)
- {
- case 1:
- reg_value.SetUInt8(*(uint8_t *)src);
- break;
- case 2:
- reg_value.SetUInt16(*(uint16_t *)src);
- break;
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
- break;
+ return error;
}
+ error.SetErrorString("byte order is invalid");
return error;
+ }
+
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+
+ // Byte offsets of all registers are calculated wrt 'UserArea' structure.
+ // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
+ // and stores them in 'm_fpr' (of type FPR structure). To extract values of
+ // fpu
+ // registers, m_fpr should be read at byte offsets calculated wrt to FPR
+ // structure.
+
+ // Since, FPR structure is also one of the member of UserArea structure.
+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
+ // byte_offset(fctrl wrt UserArea)
+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
+ uint8_t *src =
+ (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
+ switch (reg_info->byte_size) {
+ case 1:
+ reg_value.SetUInt8(*(uint8_t *)src);
+ break;
+ case 2:
+ reg_value.SetUInt16(*(uint16_t *)src);
+ break;
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
+ }
+
+ return error;
}
-Error
-NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- assert (reg_info && "reg_info is null");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index, GetFPRType()))
- {
- if (reg_info->encoding == lldb::eEncodingVector)
- {
- if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
- ::memcpy (m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_ymm && reg_index <= m_reg_info.last_ymm)
- {
- if (GetFPRType() != eFPRTypeXSAVE)
- return Error ("target processor does not support AVX");
-
- // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
- ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Error ("CopyYMMtoXSTATE() failed");
- }
- }
- else
- {
- // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
-
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only fpu
- // registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu registers should
- // be written in m_fpr at byte offsets calculated wrt FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
- assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size)
- {
- case 1:
- *(uint8_t *)dst = reg_value.GetAsUInt8();
- break;
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
- }
- }
+Error NativeRegisterContextLinux_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ assert(reg_info && "reg_info is null");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ if (IsGPR(reg_index))
+ return WriteRegisterRaw(reg_index, reg_value);
+
+ if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
+ if (reg_info->encoding == lldb::eEncodingVector) {
+ if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
+ ::memcpy(
+ m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+
+ if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
+ ::memcpy(
+ m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+
+ if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
+ ::memcpy(
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+
+ if (reg_index >= m_reg_info.first_ymm &&
+ reg_index <= m_reg_info.last_ymm) {
+ // Store ymm register content, and split into the register halves in
+ // xmm.bytes and ymmh.bytes
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
+ return Error("CopyYMMtoXSTATE() failed");
+ }
+
+ if (reg_index >= m_reg_info.first_mpxr &&
+ reg_index <= m_reg_info.last_mpxr) {
+ ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ if (!CopyMPXtoXSTATE(reg_index))
+ return Error("CopyMPXtoXSTATE() failed");
+ }
+
+ if (reg_index >= m_reg_info.first_mpxc &&
+ reg_index <= m_reg_info.last_mpxc) {
+ ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ if (!CopyMPXtoXSTATE(reg_index))
+ return Error("CopyMPXtoXSTATE() failed");
+ }
+ } else {
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+
+ // Byte offsets of all registers are calculated wrt 'UserArea' structure.
+ // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
+ // fpu
+ // registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu registers
+ // should
+ // be written in m_fpr at byte offsets calculated wrt FPR structure.
+
+ // Since, FPR structure is also one of the member of UserArea structure.
+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
+ // byte_offset(fctrl wrt UserArea)
+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
+ sizeof(m_fpr));
+ uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset -
+ m_fctrl_offset_in_userarea;
+ switch (reg_info->byte_size) {
+ case 1:
+ *(uint8_t *)dst = reg_value.GetAsUInt8();
+ break;
+ case 2:
+ *(uint16_t *)dst = reg_value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled register data size %" PRIu32,
+ reg_info->byte_size);
+ }
+ }
- Error error = WriteFPR();
- if (error.Fail())
- return error;
+ Error error = WriteFPR();
+ if (error.Fail())
+ return error;
- if (IsAVX(reg_index))
- {
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Error ("CopyYMMtoXSTATE() failed");
- }
- return Error ();
+ if (IsAVX(reg_index)) {
+ if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
+ return Error("CopyYMMtoXSTATE() failed");
+ }
+
+ if (IsMPX(reg_index)) {
+ if (!CopyMPXtoXSTATE(reg_index))
+ return Error("CopyMPXtoXSTATE() failed");
}
- return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
+ return Error();
+ }
+ return Error("failed - register wasn't recognized to be a GPR or an FPR, "
+ "write strategy unknown");
}
-Error
-NativeRegisterContextLinux_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
- return error;
- }
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- error = ReadGPR();
- if (error.Fail())
- return error;
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
- error = ReadFPR();
- if (error.Fail())
- return error;
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
- return error;
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
+ dst += GetRegisterInfoInterface().GetGPRSize();
+ if (m_xstate_type == XStateType::FXSAVE)
+ ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ else if (m_xstate_type == XStateType::XSAVE) {
+ lldb::ByteOrder byte_order = GetByteOrder();
+
+ if (IsCPUFeatureAvailable(RegSet::avx)) {
+ // Assemble the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
+ ++reg) {
+ if (!CopyXSTATEtoYMM(reg, byte_order)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyXSTATEtoYMM() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
+ }
+ }
}
- ::memcpy (dst, &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
- dst += GetRegisterInfoInterface ().GetGPRSize ();
- if (GetFPRType () == eFPRTypeFXSAVE)
- ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
- else if (GetFPRType () == eFPRTypeXSAVE)
- {
- lldb::ByteOrder byte_order = GetByteOrder ();
-
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; ++reg)
- {
- if (!CopyXSTATEtoYMM (reg, byte_order))
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyXSTATEtoYMM() failed for reg num %" PRIu32, __FUNCTION__, reg);
- return error;
- }
+ if (IsCPUFeatureAvailable(RegSet::mpx)) {
+ for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
+ ++reg) {
+ if (!CopyXSTATEtoMPX(reg)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyXSTATEtoMPX() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
}
-
- // Copy the extended register state including the assembled ymm registers.
- ::memcpy (dst, &m_fpr, sizeof (m_fpr));
+ }
}
- else
- {
- assert (false && "how do we save the floating point registers?");
- error.SetErrorString ("unsure how to save the floating point registers");
- }
- /** The following code is specific to Linux x86 based architectures,
- * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
- * -1 to solve the bug 23659, such a setting prevents the automatic
- * decrement of the instruction pointer which was causing the SIGILL
- * exception.
- * **/
-
- RegisterValue value((uint64_t) -1);
- const RegisterInfo *reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
- if (reg_info == nullptr)
- reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
+ // Copy the extended register state including the assembled ymm registers.
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
+ } else {
+ assert(false && "how do we save the floating point registers?");
+ error.SetErrorString("unsure how to save the floating point registers");
+ }
+ /** The following code is specific to Linux x86 based architectures,
+ * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
+ * -1 to solve the bug 23659, such a setting prevents the automatic
+ * decrement of the instruction pointer which was causing the SIGILL
+ * exception.
+ * **/
+
+ RegisterValue value((uint64_t)-1);
+ const RegisterInfo *reg_info =
+ GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
+ if (reg_info == nullptr)
+ reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
+
+ if (reg_info != nullptr)
+ return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
+
+ return error;
+}
- if (reg_info != nullptr)
- return DoWriteRegisterValue(reg_info->byte_offset,reg_info->name,value);
+Error NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
return error;
-}
+ }
-Error
-NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ src += GetRegisterInfoInterface().GetGPRSize();
+ if (m_xstate_type == XStateType::FXSAVE)
+ ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ else if (m_xstate_type == XStateType::XSAVE)
+ ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+ error = WriteFPR();
+ if (error.Fail())
+ return error;
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
+ if (m_xstate_type == XStateType::XSAVE) {
+ lldb::ByteOrder byte_order = GetByteOrder();
+
+ if (IsCPUFeatureAvailable(RegSet::avx)) {
+ // Parse the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
+ ++reg) {
+ if (!CopyYMMtoXSTATE(reg, byte_order)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyYMMtoXSTATE() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
+ }
+ }
}
- ::memcpy (&m_gpr_x86_64, src, GetRegisterInfoInterface ().GetGPRSize ());
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- src += GetRegisterInfoInterface ().GetGPRSize ();
- if (GetFPRType () == eFPRTypeFXSAVE)
- ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
- else if (GetFPRType () == eFPRTypeXSAVE)
- ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- if (GetFPRType() == eFPRTypeXSAVE)
- {
- lldb::ByteOrder byte_order = GetByteOrder();
-
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; ++reg)
- {
- if (!CopyYMMtoXSTATE (reg, byte_order))
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyYMMtoXSTATE() failed for reg num %" PRIu32, __FUNCTION__, reg);
- return error;
- }
+ if (IsCPUFeatureAvailable(RegSet::mpx)) {
+ for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
+ ++reg) {
+ if (!CopyMPXtoXSTATE(reg)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyMPXtoXSTATE() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
}
+ }
}
+ }
- return error;
+ return error;
}
-bool
-NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable (uint32_t set_index) const
-{
- // Note: Extended register sets are assumed to be at the end of g_reg_sets.
- uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
+ RegSet feature_code) const {
+ if (m_xstate_type == XStateType::Invalid) {
+ if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail())
+ return false;
+ }
+ switch (feature_code) {
+ case RegSet::gpr:
+ case RegSet::fpu:
+ return true;
+ case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
+ // reading in the XCR0 area of XSAVE.
+ if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
+ return true;
+ break;
+ case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
+ // reading in the XCR0 area of XSAVE.
+ if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
+ return true;
+ break;
+ }
+ return false;
+}
- if (GetFPRType () == eFPRTypeXSAVE)
- {
- // AVX is the first extended register set.
- ++num_sets;
- }
+bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
+ uint32_t set_index) const {
+ uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+
+ switch (static_cast<RegSet>(set_index)) {
+ case RegSet::gpr:
+ case RegSet::fpu:
return (set_index < num_sets);
+ case RegSet::avx:
+ return IsCPUFeatureAvailable(RegSet::avx);
+ case RegSet::mpx:
+ return IsCPUFeatureAvailable(RegSet::mpx);
+ }
+ return false;
}
-bool
-NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const
-{
- // GPRs come first.
- return reg_index <= m_reg_info.last_gpr;
+bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
+ // GPRs come first.
+ return reg_index <= m_reg_info.last_gpr;
}
-NativeRegisterContextLinux_x86_64::FPRType
-NativeRegisterContextLinux_x86_64::GetFPRType () const
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (m_fpr_type == eFPRTypeNotValid)
- {
- // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx.
-
- // Try and see if AVX register retrieval works.
- m_fpr_type = eFPRTypeXSAVE;
- if (const_cast<NativeRegisterContextLinux_x86_64*>(this)->ReadFPR().Fail())
- {
- // Fall back to general floating point with no AVX support.
- m_fpr_type = eFPRTypeFXSAVE;
-
- // Check if FXSAVE area can be read.
- if (const_cast<NativeRegisterContextLinux_x86_64*>(this)->ReadFPR().Fail())
- {
- if (log)
- log->Printf("NativeRegisterContextLinux_x86_64::%s ptrace APIs failed to read XSAVE/FXSAVE area", __FUNCTION__);
- }
- }
- }
- return m_fpr_type;
+bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
+ return (m_reg_info.first_fpr <= reg_index &&
+ reg_index <= m_reg_info.last_fpr);
}
-bool
-NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const
-{
- return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
+Error NativeRegisterContextLinux_x86_64::WriteFPR() {
+ switch (m_xstate_type) {
+ case XStateType::FXSAVE:
+ return WriteRegisterSet(
+ &m_iovec, sizeof(m_fpr.xstate.xsave),
+ fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
+ case XStateType::XSAVE:
+ return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
+ NT_X86_XSTATE);
+ default:
+ return Error("Unrecognized FPR type.");
+ }
}
-bool
-NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, FPRType fpr_type) const
-{
- bool generic_fpr = IsFPR(reg_index);
-
- if (fpr_type == eFPRTypeXSAVE)
- return generic_fpr || IsAVX(reg_index);
- return generic_fpr;
+bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {
+ if (!IsCPUFeatureAvailable(RegSet::avx))
+ return false;
+ return (m_reg_info.first_ymm <= reg_index &&
+ reg_index <= m_reg_info.last_ymm);
}
-Error
-NativeRegisterContextLinux_x86_64::WriteFPR()
-{
- const FPRType fpr_type = GetFPRType ();
- const lldb_private::ArchSpec& target_arch = GetRegisterInfoInterface().GetTargetArchitecture();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- // For 32-bit inferiors on x86_32/x86_64 architectures,
- // FXSAVE area can be written using PTRACE_SETREGSET ptrace api
- // For 64-bit inferiors on x86_64 architectures,
- // FXSAVE area can be written using PTRACE_SETFPREGS ptrace api
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::x86:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
- case llvm::Triple::x86_64:
- return NativeRegisterContextLinux::WriteFPR();
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
- case FPRType::eFPRTypeXSAVE:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- default:
- return Error("Unrecognized FPR type");
- }
+bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
+ uint32_t reg_index, lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg_index))
+ return false;
+
+ if (byte_order == lldb::eByteOrderLittle) {
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
+ sizeof(XMMReg),
+ m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == lldb::eByteOrderBig) {
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
+ sizeof(XMMReg),
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
-bool
-NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const
-{
- return (m_reg_info.first_ymm <= reg_index && reg_index <= m_reg_info.last_ymm);
+bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
+ uint32_t reg, lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == lldb::eByteOrderLittle) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == lldb::eByteOrderBig) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
-bool
-NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order)
-{
- if (!IsAVX (reg_index))
- return false;
-
- if (byte_order == lldb::eByteOrderLittle)
- {
- ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (XMMReg));
- ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (YMMHReg));
- return true;
- }
-
- if (byte_order == lldb::eByteOrderBig)
- {
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (XMMReg));
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
+void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
+ switch (m_xstate_type) {
+ case XStateType::FXSAVE:
+ return &m_fpr.xstate.fxsave;
+ case XStateType::XSAVE:
+ return &m_iovec;
+ default:
+ return nullptr;
+ }
+}
+size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
+ switch (m_xstate_type) {
+ case XStateType::FXSAVE:
+ return sizeof(m_fpr.xstate.fxsave);
+ case XStateType::XSAVE:
+ return sizeof(m_iovec);
+ default:
+ return 0;
+ }
}
-bool
-NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == lldb::eByteOrderLittle)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(YMMHReg));
- return true;
- }
+Error NativeRegisterContextLinux_x86_64::ReadFPR() {
+ Error error;
- if (byte_order == lldb::eByteOrderBig)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
+ // Probe XSAVE and if it is not supported fall back to FXSAVE.
+ if (m_xstate_type != XStateType::FXSAVE) {
+ error =
+ ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ if (!error.Fail()) {
+ m_xstate_type = XStateType::XSAVE;
+ return error;
}
- return false; // unsupported or invalid byte order
+ }
+ error = ReadRegisterSet(
+ &m_iovec, sizeof(m_fpr.xstate.xsave),
+ fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
+ if (!error.Fail()) {
+ m_xstate_type = XStateType::FXSAVE;
+ return error;
+ }
+ return Error("Unrecognized FPR type.");
}
-void*
-NativeRegisterContextLinux_x86_64::GetFPRBuffer()
-{
- const FPRType fpr_type = GetFPRType ();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- return &m_fpr.xstate.fxsave;
- case FPRType::eFPRTypeXSAVE:
- return &m_iovec;
- default:
- return nullptr;
- }
+bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {
+ if (!IsCPUFeatureAvailable(RegSet::mpx))
+ return false;
+ return (m_reg_info.first_mpxr <= reg_index &&
+ reg_index <= m_reg_info.last_mpxc);
}
-size_t
-NativeRegisterContextLinux_x86_64::GetFPRSize()
-{
- const FPRType fpr_type = GetFPRType ();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- return sizeof(m_fpr.xstate.fxsave);
- case FPRType::eFPRTypeXSAVE:
- return sizeof(m_iovec);
- default:
- return 0;
- }
+bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
+ if (!IsMPX(reg))
+ return false;
+
+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
+ ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ sizeof(MPXReg));
+ } else {
+ ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ sizeof(MPXCsr));
+ }
+ return true;
}
-Error
-NativeRegisterContextLinux_x86_64::ReadFPR ()
-{
- const FPRType fpr_type = GetFPRType ();
- const lldb_private::ArchSpec& target_arch = GetRegisterInfoInterface().GetTargetArchitecture();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- // For 32-bit inferiors on x86_32/x86_64 architectures,
- // FXSAVE area can be read using PTRACE_GETREGSET ptrace api
- // For 64-bit inferiors on x86_64 architectures,
- // FXSAVE area can be read using PTRACE_GETFPREGS ptrace api
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::x86:
- return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
- case llvm::Triple::x86_64:
- return NativeRegisterContextLinux::ReadFPR();
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
- case FPRType::eFPRTypeXSAVE:
- return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- default:
- return Error("Unrecognized FPR type");
- }
+bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
+ if (!IsMPX(reg))
+ return false;
+
+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
+ ::memcpy(m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
+ } else {
+ ::memcpy(m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
+ }
+ return true;
}
-Error
-NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
+Error NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- RegisterValue reg_value;
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail())
- {
- is_hit = false;
- return error;
- }
+ RegisterValue reg_value;
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
+ if (error.Fail()) {
+ is_hit = false;
+ return error;
+ }
- uint64_t status_bits = reg_value.GetAsUInt64();
+ uint64_t status_bits = reg_value.GetAsUInt64();
- is_hit = status_bits & (1 << wp_index);
+ is_hit = status_bits & (1 << wp_index);
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) {
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
- {
- bool is_hit;
- Error error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail()) {
- wp_index = LLDB_INVALID_INDEX32;
- return error;
- } else if (is_hit) {
- return error;
- }
+Error NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
}
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
-Error
-NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index, bool &is_vacant)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error ("Watchpoint index out of range");
+Error NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- RegisterValue reg_value;
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail())
- {
- is_vacant = false;
- return error;
- }
+ RegisterValue reg_value;
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail()) {
+ is_vacant = false;
+ return error;
+ }
- uint64_t control_bits = reg_value.GetAsUInt64();
+ uint64_t control_bits = reg_value.GetAsUInt64();
- is_vacant = !(control_bits & (1 << (2 * wp_index)));
+ is_vacant = !(control_bits & (1 << (2 * wp_index)));
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+Error NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error ("Watchpoint index out of range");
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- // Read only watchpoints aren't supported on x86_64. Fall back to read/write waitchpoints instead.
- // TODO: Add logic to detect when a write happens and ignore that watchpoint hit.
- if (watch_flags == 0x2)
- watch_flags = 0x3;
+ // Read only watchpoints aren't supported on x86_64. Fall back to read/write
+ // waitchpoints instead.
+ // TODO: Add logic to detect when a write happens and ignore that watchpoint
+ // hit.
+ if (watch_flags == 0x2)
+ watch_flags = 0x3;
- if (watch_flags != 0x1 && watch_flags != 0x3)
- return Error ("Invalid read/write bits for watchpoint");
+ if (watch_flags != 0x1 && watch_flags != 0x3)
+ return Error("Invalid read/write bits for watchpoint");
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return Error ("Invalid size for watchpoint");
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return Error("Invalid size for watchpoint");
- bool is_vacant;
- Error error = IsWatchpointVacant (wp_index, is_vacant);
- if (error.Fail()) return error;
- if (!is_vacant) return Error("Watchpoint index not vacant");
-
- RegisterValue reg_value;
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return error;
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (error.Fail())
+ return error;
+ if (!is_vacant)
+ return Error("Watchpoint index not vacant");
- // for watchpoints 0, 1, 2, or 3, respectively,
- // set bits 1, 3, 5, or 7
- uint64_t enable_bit = 1 << (2 * wp_index);
+ RegisterValue reg_value;
+ error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail())
+ return error;
- // set bits 16-17, 20-21, 24-25, or 28-29
- // with 0b01 for write, and 0b11 for read/write
- uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // set bits 1, 3, 5, or 7
+ uint64_t enable_bit = 1 << (2 * wp_index);
- // set bits 18-19, 22-23, 26-27, or 30-31
- // with 0b00, 0b01, 0b10, or 0b11
- // for 1, 2, 8 (if supported), or 4 bytes, respectively
- uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
+ // set bits 16-17, 20-21, 24-25, or 28-29
+ // with 0b01 for write, and 0b11 for read/write
+ uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
- uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+ // set bits 18-19, 22-23, 26-27, or 30-31
+ // with 0b00, 0b01, 0b10, or 0b11
+ // for 1, 2, 8 (if supported), or 4 bytes, respectively
+ uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
- control_bits |= enable_bit | rw_bits | size_bits;
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
- if (error.Fail()) return error;
+ control_bits |= enable_bit | rw_bits | size_bits;
- error = WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
- if (error.Fail()) return error;
+ error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
+ if (error.Fail())
+ return error;
- error.Clear();
+ error =
+ WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+ if (error.Fail())
return error;
+
+ error.Clear();
+ return error;
}
-bool
-NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- RegisterValue reg_value;
-
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail()) return false;
- uint64_t bit_mask = 1 << wp_index;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
- if (error.Fail()) return false;
-
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
- // of the debug control register (DR7)
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return false;
- bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits)).Success();
+bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
+
+ RegisterValue reg_value;
+
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
+ if (error.Fail())
+ return false;
+ uint64_t bit_mask = 1 << wp_index;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+ if (error.Fail())
+ return false;
+
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
+ // of the debug control register (DR7)
+ error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail())
+ return false;
+ bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits))
+ .Success();
}
-Error
-NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints()
-{
- RegisterValue reg_value;
-
- // clear bits {0-4} of the debug status register (DR6)
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail()) return error;
- uint64_t bit_mask = 0xF;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
- if (error.Fail()) return error;
-
- // clear bits {0-7,16-31} of the debug control register (DR7)
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return error;
- bit_mask = 0xFF | (0xFFFF << 16);
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+Error NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() {
+ RegisterValue reg_value;
+
+ // clear bits {0-4} of the debug status register (DR6)
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
+ if (error.Fail())
+ return error;
+ uint64_t bit_mask = 0xF;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+ if (error.Fail())
+ return error;
+
+ // clear bits {0-7,16-31} of the debug control register (DR7)
+ error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail())
+ return error;
+ bit_mask = 0xFF | (0xFFFF << 16);
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
}
-uint32_t
-NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index)
- {
- bool is_vacant;
- Error error = IsWatchpointVacant(wp_index, is_vacant);
- if (is_vacant)
- {
- error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
- if (error.Success())
- return wp_index;
- }
- if (error.Fail() && log)
- {
- log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
- __FUNCTION__, error.AsCString());
- }
+uint32_t NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant) {
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
+ }
+ if (error.Fail() && log) {
+ log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
lldb::addr_t
-NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
- RegisterValue reg_value;
- if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
- return LLDB_INVALID_ADDRESS;
- return reg_value.GetAsUInt64();
+NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ RegisterValue reg_value;
+ if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
+ return LLDB_INVALID_ADDRESS;
+ return reg_value.GetAsUInt64();
}
-uint32_t
-NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints ()
-{
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
+uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
}
#endif // defined(__i386__) || defined(__x86_64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
index b04be4bb7688..cc05ec06b297 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -19,149 +19,124 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_x86_64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Error
- IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+ Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- Error
- IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+ Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
- bool
- ClearHardwareWatchpoint(uint32_t wp_index) override;
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- uint32_t watch_flags, uint32_t wp_index);
+ Error SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, uint32_t wp_index);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- lldb::addr_t
- GetWatchpointAddress(uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- NumSupportedHardwareWatchpoints() override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- protected:
- void*
- GetGPRBuffer() override { return &m_gpr_x86_64; }
+protected:
+ void *GetGPRBuffer() override { return &m_gpr_x86_64; }
- void*
- GetFPRBuffer() override;
+ void *GetFPRBuffer() override;
- size_t
- GetFPRSize() override;
+ size_t GetFPRSize() override;
- Error
- ReadFPR() override;
+ Error ReadFPR() override;
- Error
- WriteFPR() override;
+ Error WriteFPR() override;
- private:
+private:
+ // Private member types.
+ enum class XStateType { Invalid, FXSAVE, XSAVE };
+ enum class RegSet { gpr, fpu, avx, mpx };
- // Private member types.
- enum FPRType
- {
- eFPRTypeNotValid = 0,
- eFPRTypeFXSAVE,
- eFPRTypeXSAVE
- };
+ // Info about register ranges.
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+ uint32_t num_avx_registers;
+ uint32_t num_mpx_registers;
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ uint32_t first_st;
+ uint32_t last_st;
+ uint32_t first_mm;
+ uint32_t last_mm;
+ uint32_t first_xmm;
+ uint32_t last_xmm;
+ uint32_t first_ymm;
+ uint32_t last_ymm;
+ uint32_t first_mpxr;
+ uint32_t last_mpxr;
+ uint32_t first_mpxc;
+ uint32_t last_mpxc;
+ uint32_t first_dr;
+ uint32_t gpr_flags;
+ };
- // Info about register ranges.
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
- uint32_t num_avx_registers;
+ // Private member variables.
+ mutable XStateType m_xstate_type;
+ FPR m_fpr; // Extended States Area, named FPR for historical reasons.
+ IOVEC m_iovec;
+ YMM m_ymm_set;
+ MPX m_mpx_set;
+ RegInfo m_reg_info;
+ uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];
+ uint32_t m_fctrl_offset_in_userarea;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ // Private member methods.
+ bool IsCPUFeatureAvailable(RegSet feature_code) const;
- uint32_t first_st;
- uint32_t last_st;
- uint32_t first_mm;
- uint32_t last_mm;
- uint32_t first_xmm;
- uint32_t last_xmm;
- uint32_t first_ymm;
- uint32_t last_ymm;
+ bool IsRegisterSetAvailable(uint32_t set_index) const;
- uint32_t first_dr;
- uint32_t gpr_flags;
- };
+ bool IsGPR(uint32_t reg_index) const;
- // Private member variables.
- mutable FPRType m_fpr_type;
- FPR m_fpr;
- IOVEC m_iovec;
- YMM m_ymm_set;
- RegInfo m_reg_info;
- uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];
- uint32_t m_fctrl_offset_in_userarea;
+ bool IsFPR(uint32_t reg_index) const;
- // Private member methods.
- bool IsRegisterSetAvailable (uint32_t set_index) const;
+ bool CopyXSTATEtoYMM(uint32_t reg_index, lldb::ByteOrder byte_order);
- bool
- IsGPR(uint32_t reg_index) const;
+ bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
- FPRType
- GetFPRType () const;
+ bool IsAVX(uint32_t reg_index) const;
- bool
- IsFPR(uint32_t reg_index) const;
+ bool CopyXSTATEtoMPX(uint32_t reg);
- bool
- IsFPR(uint32_t reg_index, FPRType fpr_type) const;
+ bool CopyMPXtoXSTATE(uint32_t reg);
- bool
- CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order);
-
- bool
- CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
-
- bool
- IsAVX (uint32_t reg_index) const;
- };
+ bool IsMPX(uint32_t reg_index) const;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 6509022b6c6e..d18d3c16d2c9 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -29,481 +29,453 @@
#include <sys/syscall.h>
// Try to define a macro to encapsulate the tgkill syscall
-#define tgkill(pid, tid, sig) \
- syscall(__NR_tgkill, static_cast< ::pid_t>(pid), static_cast< ::pid_t>(tid), sig)
+#define tgkill(pid, tid, sig) \
+ syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
+ sig)
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_linux;
-namespace
-{
- void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
- {
- switch (stop_info.reason)
- {
- case eStopReasonNone:
- log.Printf ("%s: %s no stop reason", __FUNCTION__, header);
- return;
- case eStopReasonTrace:
- log.Printf ("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonBreakpoint:
- log.Printf ("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonWatchpoint:
- log.Printf ("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonSignal:
- log.Printf ("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonException:
- log.Printf ("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
- return;
- case eStopReasonExec:
- log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonPlanComplete:
- log.Printf ("%s: %s plan complete", __FUNCTION__, header);
- return;
- case eStopReasonThreadExiting:
- log.Printf ("%s: %s thread exiting", __FUNCTION__, header);
- return;
- case eStopReasonInstrumentation:
- log.Printf ("%s: %s instrumentation", __FUNCTION__, header);
- return;
- default:
- log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
- }
- }
+namespace {
+void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
+ const char *const header) {
+ switch (stop_info.reason) {
+ case eStopReasonNone:
+ log.Printf("%s: %s no stop reason", __FUNCTION__, header);
+ return;
+ case eStopReasonTrace:
+ log.Printf("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
+ stop_info.details.signal.signo);
+ return;
+ case eStopReasonBreakpoint:
+ log.Printf("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
+ header, stop_info.details.signal.signo);
+ return;
+ case eStopReasonWatchpoint:
+ log.Printf("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
+ header, stop_info.details.signal.signo);
+ return;
+ case eStopReasonSignal:
+ log.Printf("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
+ stop_info.details.signal.signo);
+ return;
+ case eStopReasonException:
+ log.Printf("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
+ stop_info.details.exception.type);
+ return;
+ case eStopReasonExec:
+ log.Printf("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
+ stop_info.details.signal.signo);
+ return;
+ case eStopReasonPlanComplete:
+ log.Printf("%s: %s plan complete", __FUNCTION__, header);
+ return;
+ case eStopReasonThreadExiting:
+ log.Printf("%s: %s thread exiting", __FUNCTION__, header);
+ return;
+ case eStopReasonInstrumentation:
+ log.Printf("%s: %s instrumentation", __FUNCTION__, header);
+ return;
+ default:
+ log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
+ static_cast<uint32_t>(stop_info.reason));
+ }
}
-
-NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
- NativeThreadProtocol (process, tid),
- m_state (StateType::eStateInvalid),
- m_stop_info (),
- m_reg_context_sp (),
- m_stop_description ()
-{
}
-std::string
-NativeThreadLinux::GetName()
-{
- NativeProcessProtocolSP process_sp = m_process_wp.lock ();
- if (!process_sp)
- return "<unknown: no process>";
-
- // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
- llvm::SmallString<32> thread_name;
- HostNativeThread::GetName(GetID(), thread_name);
- return thread_name.c_str();
+NativeThreadLinux::NativeThreadLinux(NativeProcessLinux *process,
+ lldb::tid_t tid)
+ : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
+ m_stop_info(), m_reg_context_sp(), m_stop_description() {}
+
+std::string NativeThreadLinux::GetName() {
+ NativeProcessProtocolSP process_sp = m_process_wp.lock();
+ if (!process_sp)
+ return "<unknown: no process>";
+
+ // const NativeProcessLinux *const process =
+ // reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
+ llvm::SmallString<32> thread_name;
+ HostNativeThread::GetName(GetID(), thread_name);
+ return thread_name.c_str();
}
-lldb::StateType
-NativeThreadLinux::GetState ()
-{
- return m_state;
-}
+lldb::StateType NativeThreadLinux::GetState() { return m_state; }
+
+bool NativeThreadLinux::GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ description.clear();
+
+ switch (m_state) {
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateExited:
+ case eStateSuspended:
+ case eStateUnloaded:
+ if (log)
+ LogThreadStopInfo(*log, m_stop_info, "m_stop_info in thread:");
+ stop_info = m_stop_info;
+ description = m_stop_description;
+ if (log)
+ LogThreadStopInfo(*log, stop_info, "returned stop_info:");
+ return true;
-bool
-NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& description)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
-
- description.clear();
-
- switch (m_state)
- {
- case eStateStopped:
- case eStateCrashed:
- case eStateExited:
- case eStateSuspended:
- case eStateUnloaded:
- if (log)
- LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
- stop_info = m_stop_info;
- description = m_stop_description;
- if (log)
- LogThreadStopInfo (*log, stop_info, "returned stop_info:");
-
- return true;
-
- case eStateInvalid:
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateDetached:
- if (log)
- {
- log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
- __FUNCTION__, GetID (), StateAsCString (m_state));
- }
- return false;
+ case eStateInvalid:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ if (log) {
+ log->Printf("NativeThreadLinux::%s tid %" PRIu64
+ " in state %s cannot answer stop reason",
+ __FUNCTION__, GetID(), StateAsCString(m_state));
}
- llvm_unreachable("unhandled StateType!");
+ return false;
+ }
+ llvm_unreachable("unhandled StateType!");
}
-NativeRegisterContextSP
-NativeThreadLinux::GetRegisterContext ()
-{
- // Return the register context if we already created it.
- if (m_reg_context_sp)
- return m_reg_context_sp;
+NativeRegisterContextSP NativeThreadLinux::GetRegisterContext() {
+ // Return the register context if we already created it.
+ if (m_reg_context_sp)
+ return m_reg_context_sp;
- NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
- if (!m_process_sp)
- return NativeRegisterContextSP ();
+ NativeProcessProtocolSP m_process_sp = m_process_wp.lock();
+ if (!m_process_sp)
+ return NativeRegisterContextSP();
- ArchSpec target_arch;
- if (!m_process_sp->GetArchitecture (target_arch))
- return NativeRegisterContextSP ();
+ ArchSpec target_arch;
+ if (!m_process_sp->GetArchitecture(target_arch))
+ return NativeRegisterContextSP();
- const uint32_t concrete_frame_idx = 0;
- m_reg_context_sp.reset (NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(target_arch,
- *this,
- concrete_frame_idx));
+ const uint32_t concrete_frame_idx = 0;
+ m_reg_context_sp.reset(
+ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ target_arch, *this, concrete_frame_idx));
- return m_reg_context_sp;
+ return m_reg_context_sp;
}
-Error
-NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
-{
- if (!hardware)
- return Error ("not implemented");
- if (m_state == eStateLaunching)
- return Error ();
- Error error = RemoveWatchpoint(addr);
- if (error.Fail()) return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext ();
- uint32_t wp_index =
- reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags);
- if (wp_index == LLDB_INVALID_INDEX32)
- return Error ("Setting hardware watchpoint failed.");
- m_watchpoint_index_map.insert({addr, wp_index});
- return Error ();
+Error NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, bool hardware) {
+ if (!hardware)
+ return Error("not implemented");
+ if (m_state == eStateLaunching)
+ return Error();
+ Error error = RemoveWatchpoint(addr);
+ if (error.Fail())
+ return error;
+ NativeRegisterContextSP reg_ctx = GetRegisterContext();
+ uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return Error("Setting hardware watchpoint failed.");
+ m_watchpoint_index_map.insert({addr, wp_index});
+ return Error();
}
-Error
-NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
-{
- auto wp = m_watchpoint_index_map.find(addr);
- if (wp == m_watchpoint_index_map.end())
- return Error ();
- uint32_t wp_index = wp->second;
- m_watchpoint_index_map.erase(wp);
- if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
- return Error ();
- return Error ("Clearing hardware watchpoint failed.");
+Error NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
+ auto wp = m_watchpoint_index_map.find(addr);
+ if (wp == m_watchpoint_index_map.end())
+ return Error();
+ uint32_t wp_index = wp->second;
+ m_watchpoint_index_map.erase(wp);
+ if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
+ return Error();
+ return Error("Clearing hardware watchpoint failed.");
}
-Error
-NativeThreadLinux::Resume(uint32_t signo)
-{
- const StateType new_state = StateType::eStateRunning;
- MaybeLogStateChange (new_state);
- m_state = new_state;
-
- m_stop_info.reason = StopReason::eStopReasonNone;
- m_stop_description.clear();
-
- // If watchpoints have been set, but none on this thread,
- // then this is a new thread. So set all existing watchpoints.
- if (m_watchpoint_index_map.empty())
- {
- NativeProcessLinux &process = GetProcess();
-
- const auto &watchpoint_map = process.GetWatchpointMap();
- GetRegisterContext()->ClearAllHardwareWatchpoints();
- for (const auto &pair : watchpoint_map)
- {
- const auto &wp = pair.second;
- SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
- }
- }
+Error NativeThreadLinux::Resume(uint32_t signo) {
+ const StateType new_state = StateType::eStateRunning;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
- intptr_t data = 0;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+ m_stop_description.clear();
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
+ // If watchpoints have been set, but none on this thread,
+ // then this is a new thread. So set all existing watchpoints.
+ if (m_watchpoint_index_map.empty()) {
+ NativeProcessLinux &process = GetProcess();
- return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr, reinterpret_cast<void *>(data));
-}
+ const auto &watchpoint_map = process.GetWatchpointMap();
+ GetRegisterContext()->ClearAllHardwareWatchpoints();
+ for (const auto &pair : watchpoint_map) {
+ const auto &wp = pair.second;
+ SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
+ }
+ }
-void
-NativeThreadLinux::MaybePrepareSingleStepWorkaround()
-{
- if (!SingleStepWorkaroundNeeded())
- return;
+ intptr_t data = 0;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = signo;
- if (sched_getaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
- {
- // This should really not fail. But, just in case...
- if (log)
- {
- Error error(errno, eErrorTypePOSIX);
- log->Printf("NativeThreadLinux::%s Unable to get cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
- m_tid, error.AsCString());
- }
- return;
- }
+ return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr,
+ reinterpret_cast<void *>(data));
+}
- cpu_set_t set;
- CPU_ZERO(&set);
- CPU_SET(0, &set);
- if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof set, &set) != 0 && log)
- {
- // This may fail in very locked down systems, if the thread is not allowed to run on
- // cpu 0. If that happens, only thing we can do is it log it and continue...
- Error error(errno, eErrorTypePOSIX);
- log->Printf("NativeThreadLinux::%s Unable to set cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__, m_tid,
- error.AsCString());
+void NativeThreadLinux::MaybePrepareSingleStepWorkaround() {
+ if (!SingleStepWorkaroundNeeded())
+ return;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ if (sched_getaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set,
+ &m_original_cpu_set) != 0) {
+ // This should really not fail. But, just in case...
+ if (log) {
+ Error error(errno, eErrorTypePOSIX);
+ log->Printf(
+ "NativeThreadLinux::%s Unable to get cpu affinity for thread %" PRIx64
+ ": %s",
+ __FUNCTION__, m_tid, error.AsCString());
}
+ return;
+ }
+
+ cpu_set_t set;
+ CPU_ZERO(&set);
+ CPU_SET(0, &set);
+ if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof set, &set) != 0 &&
+ log) {
+ // This may fail in very locked down systems, if the thread is not allowed
+ // to run on
+ // cpu 0. If that happens, only thing we can do is it log it and continue...
+ Error error(errno, eErrorTypePOSIX);
+ log->Printf(
+ "NativeThreadLinux::%s Unable to set cpu affinity for thread %" PRIx64
+ ": %s",
+ __FUNCTION__, m_tid, error.AsCString());
+ }
}
-void
-NativeThreadLinux::MaybeCleanupSingleStepWorkaround()
-{
- if (!SingleStepWorkaroundNeeded())
- return;
-
- if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
- {
- Error error(errno, eErrorTypePOSIX);
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- log->Printf("NativeThreadLinux::%s Unable to reset cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
- m_tid, error.AsCString());
- }
+void NativeThreadLinux::MaybeCleanupSingleStepWorkaround() {
+ if (!SingleStepWorkaroundNeeded())
+ return;
+
+ if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set,
+ &m_original_cpu_set) != 0) {
+ Error error(errno, eErrorTypePOSIX);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ log->Printf(
+ "NativeThreadLinux::%s Unable to reset cpu affinity for thread %" PRIx64
+ ": %s",
+ __FUNCTION__, m_tid, error.AsCString());
+ }
}
-Error
-NativeThreadLinux::SingleStep(uint32_t signo)
-{
- const StateType new_state = StateType::eStateStepping;
- MaybeLogStateChange (new_state);
- m_state = new_state;
- m_stop_info.reason = StopReason::eStopReasonNone;
-
- MaybePrepareSingleStepWorkaround();
-
- intptr_t data = 0;
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
-
- // If hardware single-stepping is not supported, we just do a continue. The breakpoint on the
- // next instruction has been setup in NativeProcessLinux::Resume.
- return NativeProcessLinux::PtraceWrapper(GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
- : PTRACE_CONT,
- m_tid, nullptr, reinterpret_cast<void *>(data));
+Error NativeThreadLinux::SingleStep(uint32_t signo) {
+ const StateType new_state = StateType::eStateStepping;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+
+ MaybePrepareSingleStepWorkaround();
+
+ intptr_t data = 0;
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = signo;
+
+ // If hardware single-stepping is not supported, we just do a continue. The
+ // breakpoint on the
+ // next instruction has been setup in NativeProcessLinux::Resume.
+ return NativeProcessLinux::PtraceWrapper(
+ GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
+ : PTRACE_CONT,
+ m_tid, nullptr, reinterpret_cast<void *>(data));
}
-void
-NativeThreadLinux::SetStoppedBySignal(uint32_t signo, const siginfo_t *info)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
-
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonSignal;
- m_stop_info.details.signal.signo = signo;
-
- m_stop_description.clear();
- if (info)
- {
- switch (signo)
- {
- case SIGSEGV:
- case SIGBUS:
- case SIGFPE:
- case SIGILL:
- //In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit address.
- const auto reason = (info->si_signo == SIGBUS && info->si_code == SI_KERNEL) ?
- CrashReason::eInvalidAddress : GetCrashReason(*info);
- m_stop_description = GetCrashReasonString(reason, reinterpret_cast<uintptr_t>(info->si_addr));
- break;
- }
+void NativeThreadLinux::SetStoppedBySignal(uint32_t signo,
+ const siginfo_t *info) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("NativeThreadLinux::%s called with signal 0x%02" PRIx32,
+ __FUNCTION__, signo);
+
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonSignal;
+ m_stop_info.details.signal.signo = signo;
+
+ m_stop_description.clear();
+ if (info) {
+ switch (signo) {
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGFPE:
+ case SIGILL:
+ // In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit
+ // address.
+ const auto reason =
+ (info->si_signo == SIGBUS && info->si_code == SI_KERNEL)
+ ? CrashReason::eInvalidAddress
+ : GetCrashReason(*info);
+ m_stop_description = GetCrashReasonString(reason, *info);
+ break;
}
+ }
}
-bool
-NativeThreadLinux::IsStopped (int *signo)
-{
- if (!StateIsStoppedState (m_state, false))
- return false;
-
- // If we are stopped by a signal, return the signo.
- if (signo &&
- m_state == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonSignal)
- {
- *signo = m_stop_info.details.signal.signo;
- }
+bool NativeThreadLinux::IsStopped(int *signo) {
+ if (!StateIsStoppedState(m_state, false))
+ return false;
- // Regardless, we are stopped.
- return true;
+ // If we are stopped by a signal, return the signo.
+ if (signo && m_state == StateType::eStateStopped &&
+ m_stop_info.reason == StopReason::eStopReasonSignal) {
+ *signo = m_stop_info.details.signal.signo;
+ }
+
+ // Regardless, we are stopped.
+ return true;
}
-void
-NativeThreadLinux::SetStopped()
-{
- if (m_state == StateType::eStateStepping)
- MaybeCleanupSingleStepWorkaround();
+void NativeThreadLinux::SetStopped() {
+ if (m_state == StateType::eStateStepping)
+ MaybeCleanupSingleStepWorkaround();
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange(new_state);
- m_state = new_state;
- m_stop_description.clear();
+ const StateType new_state = StateType::eStateStopped;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
+ m_stop_description.clear();
}
-void
-NativeThreadLinux::SetStoppedByExec ()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
+void NativeThreadLinux::SetStoppedByExec() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("NativeThreadLinux::%s()", __FUNCTION__);
- SetStopped();
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonExec;
- m_stop_info.details.signal.signo = SIGSTOP;
+ m_stop_info.reason = StopReason::eStopReasonExec;
+ m_stop_info.details.signal.signo = SIGSTOP;
}
-void
-NativeThreadLinux::SetStoppedByBreakpoint ()
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedByBreakpoint() {
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonBreakpoint;
- m_stop_info.details.signal.signo = SIGTRAP;
- m_stop_description.clear();
+ m_stop_info.reason = StopReason::eStopReasonBreakpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
+ m_stop_description.clear();
}
-void
-NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
+ SetStopped();
- lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
- "wp_index cannot be invalid");
+ lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
- std::ostringstream ostr;
- ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
- ostr << wp_index;
+ std::ostringstream ostr;
+ ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << wp_index;
- /*
- * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For example:
- * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at 'm', then
- * watch exception is generated even when 'n' is read/written. To handle this case,
- * find the base address of the load/store instruction and append it in the stop-info
- * packet.
- */
- ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
+ /*
+ * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
+ * example:
+ * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
+ * 'm', then
+ * watch exception is generated even when 'n' is read/written. To handle this
+ * case,
+ * find the base address of the load/store instruction and append it in the
+ * stop-info
+ * packet.
+ */
+ ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
- m_stop_description = ostr.str();
+ m_stop_description = ostr.str();
- m_stop_info.reason = StopReason::eStopReasonWatchpoint;
- m_stop_info.details.signal.signo = SIGTRAP;
+ m_stop_info.reason = StopReason::eStopReasonWatchpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
}
-bool
-NativeThreadLinux::IsStoppedAtBreakpoint ()
-{
- return GetState () == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonBreakpoint;
+bool NativeThreadLinux::IsStoppedAtBreakpoint() {
+ return GetState() == StateType::eStateStopped &&
+ m_stop_info.reason == StopReason::eStopReasonBreakpoint;
}
-bool
-NativeThreadLinux::IsStoppedAtWatchpoint ()
-{
- return GetState () == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonWatchpoint;
+bool NativeThreadLinux::IsStoppedAtWatchpoint() {
+ return GetState() == StateType::eStateStopped &&
+ m_stop_info.reason == StopReason::eStopReasonWatchpoint;
}
-void
-NativeThreadLinux::SetStoppedByTrace ()
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedByTrace() {
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonTrace;
- m_stop_info.details.signal.signo = SIGTRAP;
+ m_stop_info.reason = StopReason::eStopReasonTrace;
+ m_stop_info.details.signal.signo = SIGTRAP;
}
-void
-NativeThreadLinux::SetStoppedWithNoReason ()
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedWithNoReason() {
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonNone;
- m_stop_info.details.signal.signo = 0;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+ m_stop_info.details.signal.signo = 0;
}
-void
-NativeThreadLinux::SetExited ()
-{
- const StateType new_state = StateType::eStateExited;
- MaybeLogStateChange (new_state);
- m_state = new_state;
+void NativeThreadLinux::SetExited() {
+ const StateType new_state = StateType::eStateExited;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
- m_stop_info.reason = StopReason::eStopReasonThreadExiting;
+ m_stop_info.reason = StopReason::eStopReasonThreadExiting;
}
-Error
-NativeThreadLinux::RequestStop ()
-{
- Log* log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+Error NativeThreadLinux::RequestStop() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- NativeProcessLinux &process = GetProcess();
+ NativeProcessLinux &process = GetProcess();
+
+ lldb::pid_t pid = process.GetID();
+ lldb::tid_t tid = GetID();
- lldb::pid_t pid = process.GetID();
- lldb::tid_t tid = GetID();
+ if (log)
+ log->Printf("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
+ ", tid: %" PRIu64 ")",
+ __FUNCTION__, pid, tid);
+ Error err;
+ errno = 0;
+ if (::tgkill(pid, tid, SIGSTOP) != 0) {
+ err.SetErrorToErrno();
if (log)
- log->Printf ("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64 ", tid: %" PRIu64 ")", __FUNCTION__, pid, tid);
-
- Error err;
- errno = 0;
- if (::tgkill (pid, tid, SIGSTOP) != 0)
- {
- err.SetErrorToErrno ();
- if (log)
- log->Printf ("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64 ", SIGSTOP) failed: %s", __FUNCTION__, pid, tid, err.AsCString ());
- }
+ log->Printf("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
+ ", SIGSTOP) failed: %s",
+ __FUNCTION__, pid, tid, err.AsCString());
+ }
- return err;
+ return err;
}
-void
-NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- // If we're not logging, we're done.
- if (!log)
- return;
-
- // If this is a state change to the same state, we're done.
- lldb::StateType old_state = m_state;
- if (new_state == old_state)
- return;
-
- NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
- lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
-
- // Log it.
- log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
+void NativeThreadLinux::MaybeLogStateChange(lldb::StateType new_state) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ // If we're not logging, we're done.
+ if (!log)
+ return;
+
+ // If this is a state change to the same state, we're done.
+ lldb::StateType old_state = m_state;
+ if (new_state == old_state)
+ return;
+
+ NativeProcessProtocolSP m_process_sp = m_process_wp.lock();
+ lldb::pid_t pid =
+ m_process_sp ? m_process_sp->GetID() : LLDB_INVALID_PROCESS_ID;
+
+ // Log it.
+ log->Printf("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64
+ ") changing from state %s to %s",
+ pid, GetID(), StateAsCString(old_state),
+ StateAsCString(new_state));
}
-NativeProcessLinux &
-NativeThreadLinux::GetProcess()
-{
- auto process_sp = std::static_pointer_cast<NativeProcessLinux>(NativeThreadProtocol::GetProcess());
- assert(process_sp);
- return *process_sp;
+NativeProcessLinux &NativeThreadLinux::GetProcess() {
+ auto process_sp = std::static_pointer_cast<NativeProcessLinux>(
+ NativeThreadProtocol::GetProcess());
+ assert(process_sp);
+ return *process_sp;
}
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.h b/source/Plugins/Process/Linux/NativeThreadLinux.h
index f1b6a6e44782..f170bb1e8508 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -10,8 +10,8 @@
#ifndef liblldb_NativeThreadLinux_H_
#define liblldb_NativeThreadLinux_H_
-#include "lldb/lldb-private-forward.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/lldb-private-forward.h"
#include <sched.h>
@@ -22,118 +22,95 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeThreadLinux : public NativeThreadProtocol
- {
- friend class NativeProcessLinux;
+class NativeThreadLinux : public NativeThreadProtocol {
+ friend class NativeProcessLinux;
- public:
- NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid);
+public:
+ NativeThreadLinux(NativeProcessLinux *process, lldb::tid_t tid);
- // ---------------------------------------------------------------------
- // NativeThreadProtocol Interface
- // ---------------------------------------------------------------------
- std::string
- GetName() override;
+ // ---------------------------------------------------------------------
+ // NativeThreadProtocol Interface
+ // ---------------------------------------------------------------------
+ std::string GetName() override;
- lldb::StateType
- GetState () override;
+ lldb::StateType GetState() override;
- bool
- GetStopReason (ThreadStopInfo &stop_info, std::string& description) override;
+ bool GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) override;
- NativeRegisterContextSP
- GetRegisterContext () override;
+ NativeRegisterContextSP GetRegisterContext() override;
- Error
- SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override;
+ Error SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
+ bool hardware) override;
- Error
- RemoveWatchpoint (lldb::addr_t addr) override;
+ Error RemoveWatchpoint(lldb::addr_t addr) override;
- private:
- // ---------------------------------------------------------------------
- // Interface for friend classes
- // ---------------------------------------------------------------------
+private:
+ // ---------------------------------------------------------------------
+ // Interface for friend classes
+ // ---------------------------------------------------------------------
- /// Resumes the thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Error
- Resume(uint32_t signo);
+ /// Resumes the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error Resume(uint32_t signo);
- /// Single steps the thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Error
- SingleStep(uint32_t signo);
+ /// Single steps the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error SingleStep(uint32_t signo);
- void
- SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
+ void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
- /// Return true if the thread is stopped.
- /// If stopped by a signal, indicate the signo in the signo argument.
- /// Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
- bool
- IsStopped (int *signo);
+ /// Return true if the thread is stopped.
+ /// If stopped by a signal, indicate the signo in the signo argument.
+ /// Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
+ bool IsStopped(int *signo);
- void
- SetStoppedByExec ();
+ void SetStoppedByExec();
- void
- SetStoppedByBreakpoint ();
+ void SetStoppedByBreakpoint();
- void
- SetStoppedByWatchpoint (uint32_t wp_index);
+ void SetStoppedByWatchpoint(uint32_t wp_index);
- bool
- IsStoppedAtBreakpoint ();
+ bool IsStoppedAtBreakpoint();
- bool
- IsStoppedAtWatchpoint ();
+ bool IsStoppedAtWatchpoint();
- void
- SetStoppedByTrace ();
+ void SetStoppedByTrace();
- void
- SetStoppedWithNoReason ();
+ void SetStoppedWithNoReason();
- void
- SetExited ();
+ void SetExited();
- Error
- RequestStop ();
+ Error RequestStop();
- // ---------------------------------------------------------------------
- // Private interface
- // ---------------------------------------------------------------------
- void
- MaybeLogStateChange (lldb::StateType new_state);
+ // ---------------------------------------------------------------------
+ // Private interface
+ // ---------------------------------------------------------------------
+ void MaybeLogStateChange(lldb::StateType new_state);
- NativeProcessLinux &
- GetProcess();
+ NativeProcessLinux &GetProcess();
- void
- SetStopped();
+ void SetStopped();
- inline void
- MaybePrepareSingleStepWorkaround();
+ inline void MaybePrepareSingleStepWorkaround();
- inline void
- MaybeCleanupSingleStepWorkaround();
+ inline void MaybeCleanupSingleStepWorkaround();
- // ---------------------------------------------------------------------
- // Member Variables
- // ---------------------------------------------------------------------
- lldb::StateType m_state;
- ThreadStopInfo m_stop_info;
- NativeRegisterContextSP m_reg_context_sp;
- std::string m_stop_description;
- using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
- WatchpointIndexMap m_watchpoint_index_map;
- cpu_set_t m_original_cpu_set; // For single-step workaround.
- };
+ // ---------------------------------------------------------------------
+ // Member Variables
+ // ---------------------------------------------------------------------
+ lldb::StateType m_state;
+ ThreadStopInfo m_stop_info;
+ NativeRegisterContextSP m_reg_context_sp;
+ std::string m_stop_description;
+ using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
+ WatchpointIndexMap m_watchpoint_index_map;
+ cpu_set_t m_original_cpu_set; // For single-step workaround.
+};
- typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
+typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/ProcFileReader.cpp b/source/Plugins/Process/Linux/ProcFileReader.cpp
index 4d1f231f4f9b..a1bb7a6e09d5 100644
--- a/source/Plugins/Process/Linux/ProcFileReader.cpp
+++ b/source/Plugins/Process/Linux/ProcFileReader.cpp
@@ -26,83 +26,78 @@
using namespace lldb_private;
using namespace lldb_private::process_linux;
-lldb::DataBufferSP
-ProcFileReader::ReadIntoDataBuffer (lldb::pid_t pid, const char *name)
-{
- int fd;
- char path[PATH_MAX];
-
- // Make sure we've got a nil terminated buffer for all the folks calling
- // GetBytes() directly off our returned DataBufferSP if we hit an error.
- lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));
-
- // Ideally, we would simply create a FileSpec and call ReadFileContents.
- // However, files in procfs have zero size (since they are, in general,
- // dynamically generated by the kernel) which is incompatible with the
- // current ReadFileContents implementation. Therefore we simply stream the
- // data into a DataBuffer ourselves.
- if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
- {
- if ((fd = open (path, O_RDONLY, 0)) >= 0)
- {
- size_t bytes_read = 0;
- std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
-
- for (;;)
- {
- size_t avail = buf_ap->GetByteSize() - bytes_read;
- ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);
-
- if (status < 0)
- break;
-
- if (status == 0)
- {
- buf_ap->SetByteSize (bytes_read);
- buf_sp.reset (buf_ap.release());
- break;
- }
-
- bytes_read += status;
-
- if (avail - status == 0)
- buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
- }
-
- close (fd);
+lldb::DataBufferSP ProcFileReader::ReadIntoDataBuffer(lldb::pid_t pid,
+ const char *name) {
+ int fd;
+ char path[PATH_MAX];
+
+ // Make sure we've got a nil terminated buffer for all the folks calling
+ // GetBytes() directly off our returned DataBufferSP if we hit an error.
+ lldb::DataBufferSP buf_sp(new DataBufferHeap(1, 0));
+
+ // Ideally, we would simply create a FileSpec and call ReadFileContents.
+ // However, files in procfs have zero size (since they are, in general,
+ // dynamically generated by the kernel) which is incompatible with the
+ // current ReadFileContents implementation. Therefore we simply stream the
+ // data into a DataBuffer ourselves.
+ if (snprintf(path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0) {
+ if ((fd = open(path, O_RDONLY, 0)) >= 0) {
+ size_t bytes_read = 0;
+ std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+
+ for (;;) {
+ size_t avail = buf_ap->GetByteSize() - bytes_read;
+ ssize_t status = read(fd, buf_ap->GetBytes() + bytes_read, avail);
+
+ if (status < 0)
+ break;
+
+ if (status == 0) {
+ buf_ap->SetByteSize(bytes_read);
+ buf_sp.reset(buf_ap.release());
+ break;
}
- }
-
- return buf_sp;
-}
-Error
-ProcFileReader::ProcessLineByLine (lldb::pid_t pid, const char *name, std::function<bool (const std::string &line)> line_parser)
-{
- Error error;
-
- // Try to open the /proc/{pid}/maps entry.
- char filename [PATH_MAX];
- snprintf (filename, sizeof(filename), "/proc/%" PRIu64 "/%s", pid, name);
- filename[sizeof (filename) - 1] = '\0';
-
- std::ifstream proc_file (filename);
- if (proc_file.fail ())
- {
- error.SetErrorStringWithFormat ("failed to open file '%s'", filename);
- return error;
- }
+ bytes_read += status;
- // Read the file line by line, processing until either end of file or when the line_parser returns false.
- std::string line;
- bool should_continue = true;
+ if (avail - status == 0)
+ buf_ap->SetByteSize(2 * buf_ap->GetByteSize());
+ }
- while (should_continue && std::getline (proc_file, line))
- {
- // Pass the line over to the line_parser for processing. If the line_parser returns false, we
- // stop processing.
- should_continue = line_parser (line);
+ close(fd);
}
+ }
+
+ return buf_sp;
+}
+Error ProcFileReader::ProcessLineByLine(
+ lldb::pid_t pid, const char *name,
+ std::function<bool(const std::string &line)> line_parser) {
+ Error error;
+
+ // Try to open the /proc/{pid}/maps entry.
+ char filename[PATH_MAX];
+ snprintf(filename, sizeof(filename), "/proc/%" PRIu64 "/%s", pid, name);
+ filename[sizeof(filename) - 1] = '\0';
+
+ std::ifstream proc_file(filename);
+ if (proc_file.fail()) {
+ error.SetErrorStringWithFormat("failed to open file '%s'", filename);
return error;
+ }
+
+ // Read the file line by line, processing until either end of file or when the
+ // line_parser returns false.
+ std::string line;
+ bool should_continue = true;
+
+ while (should_continue && std::getline(proc_file, line)) {
+ // Pass the line over to the line_parser for processing. If the line_parser
+ // returns false, we
+ // stop processing.
+ should_continue = line_parser(line);
+ }
+
+ return error;
}
diff --git a/source/Plugins/Process/Linux/ProcFileReader.h b/source/Plugins/Process/Linux/ProcFileReader.h
index 7b3812433068..dcdb3553d8c3 100644
--- a/source/Plugins/Process/Linux/ProcFileReader.h
+++ b/source/Plugins/Process/Linux/ProcFileReader.h
@@ -18,18 +18,18 @@
namespace lldb_private {
namespace process_linux {
- class ProcFileReader
- {
- public:
-
- static lldb::DataBufferSP
- ReadIntoDataBuffer (lldb::pid_t pid, const char *name);
-
- /// Parse the /proc/{@a pid}/{@a name} file line by line, passing each line to line_parser, until
- /// either end of file or until line_parser returns false.
- static Error
- ProcessLineByLine (lldb::pid_t pid, const char *name, std::function<bool (const std::string &line)> line_parser);
- };
+class ProcFileReader {
+public:
+ static lldb::DataBufferSP ReadIntoDataBuffer(lldb::pid_t pid,
+ const char *name);
+
+ /// Parse the /proc/{@a pid}/{@a name} file line by line, passing each line to
+ /// line_parser, until
+ /// either end of file or until line_parser returns false.
+ static Error
+ ProcessLineByLine(lldb::pid_t pid, const char *name,
+ std::function<bool(const std::string &line)> line_parser);
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/Procfs.h b/source/Plugins/Process/Linux/Procfs.h
index cad433fb095d..1d9c9dbe273f 100644
--- a/source/Plugins/Process/Linux/Procfs.h
+++ b/source/Plugins/Process/Linux/Procfs.h
@@ -13,19 +13,19 @@
#include <sys/ptrace.h>
#ifdef __ANDROID__
-#if defined (__arm64__) || defined (__aarch64__)
+#if defined(__arm64__) || defined(__aarch64__)
typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[(sizeof (struct user_pt_regs) / sizeof(elf_greg_t))];
+typedef elf_greg_t
+ elf_gregset_t[(sizeof(struct user_pt_regs) / sizeof(elf_greg_t))];
typedef struct user_fpsimd_state elf_fpregset_t;
#ifndef NT_FPREGSET
- #define NT_FPREGSET NT_PRFPREG
+#define NT_FPREGSET NT_PRFPREG
#endif // NT_FPREGSET
-#elif defined (__mips__)
+#elif defined(__mips__)
#ifndef NT_FPREGSET
- #define NT_FPREGSET NT_PRFPREG
+#define NT_FPREGSET NT_PRFPREG
#endif // NT_FPREGSET
#endif
-#else // __ANDROID__
+#else // __ANDROID__
#include <sys/procfs.h>
#endif // __ANDROID__
-
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.cpp b/source/Plugins/Process/Linux/SingleStepCheck.cpp
index 8c557d4b6ff8..b23c1bd245d5 100644
--- a/source/Plugins/Process/Linux/SingleStepCheck.cpp
+++ b/source/Plugins/Process/Linux/SingleStepCheck.cpp
@@ -25,153 +25,142 @@
using namespace lldb_private::process_linux;
#if defined(__arm64__) || defined(__aarch64__)
-namespace
-{
-
-void LLVM_ATTRIBUTE_NORETURN
-Child()
-{
- if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
- _exit(1);
-
- // We just do an endless loop SIGSTOPPING ourselves until killed. The tracer will fiddle with our cpu
- // affinities and monitor the behaviour.
- for (;;)
- {
- raise(SIGSTOP);
-
- // Generate a bunch of instructions here, so that a single-step does not land in the
- // raise() accidentally. If single-stepping works, we will be spinning in this loop. If
- // it doesn't, we'll land in the raise() call above.
- for (volatile unsigned i = 0; i < CPU_SETSIZE; ++i)
- ;
- }
+namespace {
+
+void LLVM_ATTRIBUTE_NORETURN Child() {
+ if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
+ _exit(1);
+
+ // We just do an endless loop SIGSTOPPING ourselves until killed. The tracer
+ // will fiddle with our cpu
+ // affinities and monitor the behaviour.
+ for (;;) {
+ raise(SIGSTOP);
+
+ // Generate a bunch of instructions here, so that a single-step does not
+ // land in the
+ // raise() accidentally. If single-stepping works, we will be spinning in
+ // this loop. If
+ // it doesn't, we'll land in the raise() call above.
+ for (volatile unsigned i = 0; i < CPU_SETSIZE; ++i)
+ ;
+ }
}
-struct ChildDeleter
-{
- ::pid_t pid;
+struct ChildDeleter {
+ ::pid_t pid;
- ~ChildDeleter()
- {
- int status;
- kill(pid, SIGKILL); // Kill the child.
- waitpid(pid, &status, __WALL); // Pick up the remains.
- }
+ ~ChildDeleter() {
+ int status;
+ kill(pid, SIGKILL); // Kill the child.
+ waitpid(pid, &status, __WALL); // Pick up the remains.
+ }
};
} // end anonymous namespace
-bool
-impl::SingleStepWorkaroundNeeded()
-{
- // We shall spawn a child, and use it to verify the debug capabilities of the cpu. We shall
- // iterate through the cpus, bind the child to each one in turn, and verify that
- // single-stepping works on that cpu. A workaround is needed if we find at least one broken
- // cpu.
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- Error error;
- ::pid_t child_pid = fork();
- if (child_pid == -1)
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s failed to fork(): %s", __FUNCTION__, error.AsCString());
- }
- return false;
+bool impl::SingleStepWorkaroundNeeded() {
+ // We shall spawn a child, and use it to verify the debug capabilities of the
+ // cpu. We shall
+ // iterate through the cpus, bind the child to each one in turn, and verify
+ // that
+ // single-stepping works on that cpu. A workaround is needed if we find at
+ // least one broken
+ // cpu.
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ Error error;
+ ::pid_t child_pid = fork();
+ if (child_pid == -1) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to fork(): %s", __FUNCTION__, error.AsCString());
+ }
+ return false;
+ }
+ if (child_pid == 0)
+ Child();
+
+ ChildDeleter child_deleter{child_pid};
+ cpu_set_t available_cpus;
+ if (sched_getaffinity(child_pid, sizeof available_cpus, &available_cpus) ==
+ -1) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to get available cpus: %s", __FUNCTION__,
+ error.AsCString());
+ }
+ return false;
+ }
+
+ int status;
+ ::pid_t wpid = waitpid(child_pid, &status, __WALL);
+ if (wpid != child_pid || !WIFSTOPPED(status)) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status,
+ error.AsCString());
}
- if (child_pid == 0)
- Child();
-
- ChildDeleter child_deleter{child_pid};
- cpu_set_t available_cpus;
- if (sched_getaffinity(child_pid, sizeof available_cpus, &available_cpus) == -1)
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s failed to get available cpus: %s", __FUNCTION__, error.AsCString());
- }
- return false;
+ return false;
+ }
+
+ unsigned cpu;
+ for (cpu = 0; cpu < CPU_SETSIZE; ++cpu) {
+ if (!CPU_ISSET(cpu, &available_cpus))
+ continue;
+
+ cpu_set_t cpus;
+ CPU_ZERO(&cpus);
+ CPU_SET(cpu, &cpus);
+ if (sched_setaffinity(child_pid, sizeof cpus, &cpus) == -1) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to switch to cpu %u: %s", __FUNCTION__, cpu,
+ error.AsCString());
+ }
+ continue;
}
int status;
- ::pid_t wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status))
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status, error.AsCString());
- }
- return false;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, child_pid);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("%s single step failed: %s", __FUNCTION__,
+ error.AsCString());
+ break;
}
- unsigned cpu;
- for (cpu = 0; cpu < CPU_SETSIZE; ++cpu)
- {
- if (!CPU_ISSET(cpu, &available_cpus))
- continue;
-
- cpu_set_t cpus;
- CPU_ZERO(&cpus);
- CPU_SET(cpu, &cpus);
- if (sched_setaffinity(child_pid, sizeof cpus, &cpus) == -1)
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s failed to switch to cpu %u: %s", __FUNCTION__, cpu, error.AsCString());
- }
- continue;
- }
-
- int status;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, child_pid);
- if (error.Fail())
- {
- if (log)
- log->Printf("%s single step failed: %s", __FUNCTION__, error.AsCString());
- break;
- }
-
- wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status))
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status, error.AsCString());
- }
- break;
- }
- if (WSTOPSIG(status) != SIGTRAP)
- {
- if (log)
- log->Printf("%s single stepping on cpu %d failed with status %x", __FUNCTION__, cpu, status);
- break;
- }
+ wpid = waitpid(child_pid, &status, __WALL);
+ if (wpid != child_pid || !WIFSTOPPED(status)) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__,
+ status, error.AsCString());
+ }
+ break;
}
-
- // cpu is either the index of the first broken cpu, or CPU_SETSIZE.
- if (cpu == 0)
- {
- if (log)
- log->Printf("%s SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING LIKELY TO BE UNRELIABLE.",
- __FUNCTION__);
- // No point in trying to fiddle with the affinities, just give it our best shot and see how it goes.
- return false;
+ if (WSTOPSIG(status) != SIGTRAP) {
+ if (log)
+ log->Printf("%s single stepping on cpu %d failed with status %x",
+ __FUNCTION__, cpu, status);
+ break;
}
+ }
+
+ // cpu is either the index of the first broken cpu, or CPU_SETSIZE.
+ if (cpu == 0) {
+ if (log)
+ log->Printf("%s SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING "
+ "LIKELY TO BE UNRELIABLE.",
+ __FUNCTION__);
+ // No point in trying to fiddle with the affinities, just give it our best
+ // shot and see how it goes.
+ return false;
+ }
- return cpu != CPU_SETSIZE;
+ return cpu != CPU_SETSIZE;
}
#else // !arm64
-bool
-impl::SingleStepWorkaroundNeeded()
-{
- return false;
-}
+bool impl::SingleStepWorkaroundNeeded() { return false; }
#endif
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.h b/source/Plugins/Process/Linux/SingleStepCheck.h
index f83f7c973f8d..6e3310da840b 100644
--- a/source/Plugins/Process/Linux/SingleStepCheck.h
+++ b/source/Plugins/Process/Linux/SingleStepCheck.h
@@ -10,30 +10,29 @@
#ifndef liblldb_SingleStepCheck_H_
#define liblldb_SingleStepCheck_H_
-namespace lldb_private
-{
-namespace process_linux
-{
+namespace lldb_private {
+namespace process_linux {
-namespace impl
-{
-extern bool
-SingleStepWorkaroundNeeded();
+namespace impl {
+extern bool SingleStepWorkaroundNeeded();
}
-// arm64 linux had a bug which prevented single-stepping and watchpoints from working on non-boot
-// cpus, due to them being incorrectly initialized after coming out of suspend. This issue is
-// particularly affecting android M, which uses suspend ("doze mode") quite aggressively. This
-// code detects that situation and makes single-stepping work by doing all the step operations on
+// arm64 linux had a bug which prevented single-stepping and watchpoints from
+// working on non-boot
+// cpus, due to them being incorrectly initialized after coming out of suspend.
+// This issue is
+// particularly affecting android M, which uses suspend ("doze mode") quite
+// aggressively. This
+// code detects that situation and makes single-stepping work by doing all the
+// step operations on
// the boot cpu.
//
-// The underlying issue has been fixed in android N and linux 4.4. This code can be removed once
+// The underlying issue has been fixed in android N and linux 4.4. This code can
+// be removed once
// these systems become obsolete.
-inline bool
-SingleStepWorkaroundNeeded()
-{
- static bool value = impl::SingleStepWorkaroundNeeded();
- return value;
+inline bool SingleStepWorkaroundNeeded() {
+ static bool value = impl::SingleStepWorkaroundNeeded();
+ return value;
}
} // end namespace process_linux
} // end namespace lldb_private
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index 29a0d58f7080..43e4617feafc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "CommunicationKDP.h"
// C Includes
@@ -25,7 +24,6 @@
#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
// Project includes
@@ -38,39 +36,26 @@ using namespace lldb_private;
// CommunicationKDP constructor
//----------------------------------------------------------------------
CommunicationKDP::CommunicationKDP(const char *comm_name)
- : Communication(comm_name),
- m_addr_byte_size(4),
- m_byte_order(eByteOrderLittle),
- m_packet_timeout(5),
- m_sequence_mutex(),
- m_is_running(false),
- m_session_key(0u),
- m_request_sequence_id(0u),
- m_exception_sequence_id(0u),
- m_kdp_version_version(0u),
- m_kdp_version_feature(0u),
- m_kdp_hostinfo_cpu_mask(0u),
- m_kdp_hostinfo_cpu_type(0u),
- m_kdp_hostinfo_cpu_subtype(0u)
-{
-}
+ : Communication(comm_name), m_addr_byte_size(4),
+ m_byte_order(eByteOrderLittle), m_packet_timeout(5), m_sequence_mutex(),
+ m_is_running(false), m_session_key(0u), m_request_sequence_id(0u),
+ m_exception_sequence_id(0u), m_kdp_version_version(0u),
+ m_kdp_version_feature(0u), m_kdp_hostinfo_cpu_mask(0u),
+ m_kdp_hostinfo_cpu_type(0u), m_kdp_hostinfo_cpu_subtype(0u) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-CommunicationKDP::~CommunicationKDP()
-{
- if (IsConnected())
- {
- Disconnect();
- }
+CommunicationKDP::~CommunicationKDP() {
+ if (IsConnected()) {
+ Disconnect();
+ }
}
-bool
-CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet)
-{
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
- return SendRequestPacketNoLock (request_packet);
+bool CommunicationKDP::SendRequestPacket(
+ const PacketStreamType &request_packet) {
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
+ return SendRequestPacketNoLock(request_packet);
}
#if 0
@@ -82,409 +67,374 @@ typedef struct {
} kdp_hdr_t;
#endif
-void
-CommunicationKDP::MakeRequestPacketHeader (CommandType request_type,
- PacketStreamType &request_packet,
- uint16_t request_length)
-{
- request_packet.Clear();
- request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type
- request_packet.PutHex8 (m_request_sequence_id++); // Sequence number
- request_packet.PutHex16 (request_length); // Length of the packet including this header
- request_packet.PutHex32 (m_session_key); // Session key
+void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type,
+ PacketStreamType &request_packet,
+ uint16_t request_length) {
+ request_packet.Clear();
+ request_packet.PutHex8(request_type |
+ ePacketTypeRequest); // Set the request type
+ request_packet.PutHex8(m_request_sequence_id++); // Sequence number
+ request_packet.PutHex16(
+ request_length); // Length of the packet including this header
+ request_packet.PutHex32(m_session_key); // Session key
}
-bool
-CommunicationKDP::SendRequestAndGetReply (const CommandType command,
- const PacketStreamType &request_packet,
- DataExtractor &reply_packet)
-{
- if (IsRunning())
- {
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
- if (log)
- {
- PacketStreamType log_strm;
- DumpPacket (log_strm, request_packet.GetData(), request_packet.GetSize());
- log->Printf("error: kdp running, not sending packet: %.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- return false;
+bool CommunicationKDP::SendRequestAndGetReply(
+ const CommandType command, const PacketStreamType &request_packet,
+ DataExtractor &reply_packet) {
+ if (IsRunning()) {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
+ if (log) {
+ PacketStreamType log_strm;
+ DumpPacket(log_strm, request_packet.GetData(), request_packet.GetSize());
+ log->Printf("error: kdp running, not sending packet: %.*s",
+ (uint32_t)log_strm.GetSize(), log_strm.GetData());
}
+ return false;
+ }
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
#ifdef LLDB_CONFIGURATION_DEBUG
- // NOTE: this only works for packets that are in native endian byte order
- assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
+ // NOTE: this only works for packets that are in native endian byte order
+ assert(request_packet.GetSize() ==
+ *((uint16_t *)(request_packet.GetData() + 2)));
#endif
- lldb::offset_t offset = 1;
- const uint32_t num_retries = 3;
- for (uint32_t i=0; i<num_retries; ++i)
- {
- if (SendRequestPacketNoLock(request_packet))
- {
- const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
- while (1)
- {
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
- {
- offset = 0;
- const uint8_t reply_command = reply_packet.GetU8 (&offset);
- const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
- if (request_sequence_id == reply_sequence_id)
- {
- // The sequent ID was correct, now verify we got the response we were looking for
- if ((reply_command & eCommandTypeMask) == command)
- {
- // Success
- if (command == KDP_RESUMECPUS)
- m_is_running.SetValue(true, eBroadcastAlways);
- return true;
- }
- else
- {
- // Failed to get the correct response, bail
- reply_packet.Clear();
- return false;
- }
- }
- else if (reply_sequence_id > request_sequence_id)
- {
- // Sequence ID was greater than the sequence ID of the packet we sent, something
- // is really wrong...
- reply_packet.Clear();
- return false;
- }
- else
- {
- // The reply sequence ID was less than our current packet's sequence ID
- // so we should keep trying to get a response because this was a response
- // for a previous packet that we must have retried.
- }
- }
- else
- {
- // Break and retry sending the packet as we didn't get a response due to timeout
- break;
- }
+ lldb::offset_t offset = 1;
+ const uint32_t num_retries = 3;
+ for (uint32_t i = 0; i < num_retries; ++i) {
+ if (SendRequestPacketNoLock(request_packet)) {
+ const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
+ while (1) {
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock(
+ reply_packet,
+ std::chrono::microseconds(GetPacketTimeout()).count())) {
+ offset = 0;
+ const uint8_t reply_command = reply_packet.GetU8(&offset);
+ const uint8_t reply_sequence_id = reply_packet.GetU8(&offset);
+ if (request_sequence_id == reply_sequence_id) {
+ // The sequent ID was correct, now verify we got the response we
+ // were looking for
+ if ((reply_command & eCommandTypeMask) == command) {
+ // Success
+ if (command == KDP_RESUMECPUS)
+ m_is_running.SetValue(true, eBroadcastAlways);
+ return true;
+ } else {
+ // Failed to get the correct response, bail
+ reply_packet.Clear();
+ return false;
}
+ } else if (reply_sequence_id > request_sequence_id) {
+ // Sequence ID was greater than the sequence ID of the packet we
+ // sent, something
+ // is really wrong...
+ reply_packet.Clear();
+ return false;
+ } else {
+ // The reply sequence ID was less than our current packet's sequence
+ // ID
+ // so we should keep trying to get a response because this was a
+ // response
+ // for a previous packet that we must have retried.
+ }
+ } else {
+ // Break and retry sending the packet as we didn't get a response due
+ // to timeout
+ break;
}
+ }
}
- reply_packet.Clear();
- return false;
+ }
+ reply_packet.Clear();
+ return false;
}
-bool
-CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet)
-{
- if (IsConnected())
- {
- const char *packet_data = request_packet.GetData();
- const size_t packet_size = request_packet.GetSize();
-
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
- if (log)
- {
- PacketStreamType log_strm;
- DumpPacket (log_strm, packet_data, packet_size);
- log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- ConnectionStatus status = eConnectionStatusSuccess;
-
- size_t bytes_written = Write (packet_data,
- packet_size,
- status,
- NULL);
-
- if (bytes_written == packet_size)
- return true;
-
- if (log)
- log->Printf ("error: failed to send packet entire packet %" PRIu64 " of %" PRIu64 " bytes sent", (uint64_t)bytes_written, (uint64_t)packet_size);
+bool CommunicationKDP::SendRequestPacketNoLock(
+ const PacketStreamType &request_packet) {
+ if (IsConnected()) {
+ const char *packet_data = request_packet.GetData();
+ const size_t packet_size = request_packet.GetSize();
+
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
+ if (log) {
+ PacketStreamType log_strm;
+ DumpPacket(log_strm, packet_data, packet_size);
+ log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
}
- return false;
-}
+ ConnectionStatus status = eConnectionStatusSuccess;
-bool
-CommunicationKDP::GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock)
-{
- return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex, std::try_to_lock)).owns_lock();
-}
+ size_t bytes_written = Write(packet_data, packet_size, status, NULL);
+ if (bytes_written == packet_size)
+ return true;
-bool
-CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
-{
- return m_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
+ if (log)
+ log->Printf("error: failed to send packet entire packet %" PRIu64
+ " of %" PRIu64 " bytes sent",
+ (uint64_t)bytes_written, (uint64_t)packet_size);
+ }
+ return false;
}
-size_t
-CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec)
-{
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
- return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
+bool CommunicationKDP::GetSequenceMutex(
+ std::unique_lock<std::recursive_mutex> &lock) {
+ return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex,
+ std::try_to_lock))
+ .owns_lock();
}
-size_t
-CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec)
-{
- uint8_t buffer[8192];
- Error error;
+bool CommunicationKDP::WaitForNotRunningPrivate(
+ const std::chrono::microseconds &timeout) {
+ return m_is_running.WaitForValueEqualTo(false, timeout, NULL);
+}
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
+size_t
+CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds(DataExtractor &packet,
+ uint32_t timeout_usec) {
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
+ return WaitForPacketWithTimeoutMicroSecondsNoLock(packet, timeout_usec);
+}
- // Check for a packet from our cache first without trying any reading...
- if (CheckForPacket (NULL, 0, packet))
+size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock(
+ DataExtractor &packet, uint32_t timeout_usec) {
+ uint8_t buffer[8192];
+ Error error;
+
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS |
+ KDP_LOG_VERBOSE));
+
+ // Check for a packet from our cache first without trying any reading...
+ if (CheckForPacket(NULL, 0, packet))
+ return packet.GetByteSize();
+
+ bool timed_out = false;
+ while (IsConnected() && !timed_out) {
+ lldb::ConnectionStatus status = eConnectionStatusNoConnection;
+ size_t bytes_read = Read(buffer, sizeof(buffer),
+ timeout_usec == UINT32_MAX
+ ? Timeout<std::micro>(llvm::None)
+ : std::chrono::microseconds(timeout_usec),
+ status, &error);
+
+ if (log)
+ log->Printf("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, "
+ "status = %s, error = %s) => bytes_read = %" PRIu64,
+ LLVM_PRETTY_FUNCTION, timeout_usec,
+ Communication::ConnectionStatusAsCString(status),
+ error.AsCString(), (uint64_t)bytes_read);
+
+ if (bytes_read > 0) {
+ if (CheckForPacket(buffer, bytes_read, packet))
return packet.GetByteSize();
-
- bool timed_out = false;
- while (IsConnected() && !timed_out)
- {
- lldb::ConnectionStatus status = eConnectionStatusNoConnection;
- size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
-
- if (log)
- log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
- __PRETTY_FUNCTION__,
- timeout_usec,
- Communication::ConnectionStatusAsCString (status),
- error.AsCString(),
- (uint64_t)bytes_read);
-
- if (bytes_read > 0)
- {
- if (CheckForPacket (buffer, bytes_read, packet))
- return packet.GetByteSize();
- }
- else
- {
- switch (status)
- {
- case eConnectionStatusInterrupted:
- case eConnectionStatusTimedOut:
- timed_out = true;
- break;
- case eConnectionStatusSuccess:
- //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
- break;
-
- case eConnectionStatusEndOfFile:
- case eConnectionStatusNoConnection:
- case eConnectionStatusLostConnection:
- case eConnectionStatusError:
- Disconnect();
- break;
- }
- }
+ } else {
+ switch (status) {
+ case eConnectionStatusInterrupted:
+ case eConnectionStatusTimedOut:
+ timed_out = true;
+ break;
+ case eConnectionStatusSuccess:
+ // printf ("status = success but error = %s\n",
+ // error.AsCString("<invalid>"));
+ break;
+
+ case eConnectionStatusEndOfFile:
+ case eConnectionStatusNoConnection:
+ case eConnectionStatusLostConnection:
+ case eConnectionStatusError:
+ Disconnect();
+ break;
+ }
}
- packet.Clear ();
- return 0;
+ }
+ packet.Clear();
+ return 0;
}
-bool
-CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
-{
- // Put the packet data into the buffer in a thread safe fashion
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len,
+ DataExtractor &packet) {
+ // Put the packet data into the buffer in a thread safe fashion
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
- if (src && src_len > 0)
- {
- if (log && log->GetVerbose())
- {
- PacketStreamType log_strm;
- DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
- log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
- __FUNCTION__,
- (uint32_t)src_len,
- log_strm.GetData());
- }
- m_bytes.append ((const char *)src, src_len);
+ if (src && src_len > 0) {
+ if (log && log->GetVerbose()) {
+ PacketStreamType log_strm;
+ DataExtractor::DumpHexBytes(&log_strm, src, src_len, UINT32_MAX,
+ LLDB_INVALID_ADDRESS);
+ log->Printf("CommunicationKDP::%s adding %u bytes: %s", __FUNCTION__,
+ (uint32_t)src_len, log_strm.GetData());
}
-
- // Make sure we at least have enough bytes for a packet header
- const size_t bytes_available = m_bytes.size();
- if (bytes_available >= 8)
- {
- packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
- lldb::offset_t offset = 0;
- uint8_t reply_command = packet.GetU8(&offset);
- switch (reply_command)
- {
- case ePacketTypeRequest | KDP_EXCEPTION:
- case ePacketTypeRequest | KDP_TERMINATION:
- // We got an exception request, so be sure to send an ACK
- {
- PacketStreamType request_ack_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- // Set the reply but and make the ACK packet
- request_ack_packet.PutHex8 (reply_command | ePacketTypeReply);
- request_ack_packet.PutHex8 (packet.GetU8(&offset));
- request_ack_packet.PutHex16 (packet.GetU16(&offset));
- request_ack_packet.PutHex32 (packet.GetU32(&offset));
- m_is_running.SetValue(false, eBroadcastAlways);
- // Ack to the exception or termination
- SendRequestPacketNoLock (request_ack_packet);
- }
- // Fall through to case below to get packet contents
- LLVM_FALLTHROUGH;
- case ePacketTypeReply | KDP_CONNECT:
- case ePacketTypeReply | KDP_DISCONNECT:
- case ePacketTypeReply | KDP_HOSTINFO:
- case ePacketTypeReply | KDP_VERSION:
- case ePacketTypeReply | KDP_MAXBYTES:
- case ePacketTypeReply | KDP_READMEM:
- case ePacketTypeReply | KDP_WRITEMEM:
- case ePacketTypeReply | KDP_READREGS:
- case ePacketTypeReply | KDP_WRITEREGS:
- case ePacketTypeReply | KDP_LOAD:
- case ePacketTypeReply | KDP_IMAGEPATH:
- case ePacketTypeReply | KDP_SUSPEND:
- case ePacketTypeReply | KDP_RESUMECPUS:
- case ePacketTypeReply | KDP_BREAKPOINT_SET:
- case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
- case ePacketTypeReply | KDP_REGIONS:
- case ePacketTypeReply | KDP_REATTACH:
- case ePacketTypeReply | KDP_HOSTREBOOT:
- case ePacketTypeReply | KDP_READMEM64:
- case ePacketTypeReply | KDP_WRITEMEM64:
- case ePacketTypeReply | KDP_BREAKPOINT_SET64:
- case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
- case ePacketTypeReply | KDP_KERNELVERSION:
- case ePacketTypeReply | KDP_READPHYSMEM64:
- case ePacketTypeReply | KDP_WRITEPHYSMEM64:
- case ePacketTypeReply | KDP_READIOPORT:
- case ePacketTypeReply | KDP_WRITEIOPORT:
- case ePacketTypeReply | KDP_READMSR64:
- case ePacketTypeReply | KDP_WRITEMSR64:
- case ePacketTypeReply | KDP_DUMPINFO:
- {
- offset = 2;
- const uint16_t length = packet.GetU16 (&offset);
- if (length <= bytes_available)
- {
- // We have an entire packet ready, we need to copy the data
- // bytes into a buffer that will be owned by the packet and
- // erase the bytes from our communcation buffer "m_bytes"
- packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
- m_bytes.erase (0, length);
-
- if (log)
- {
- PacketStreamType log_strm;
- DumpPacket (log_strm, packet);
-
- log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- return true;
- }
- }
- break;
-
- default:
- // Unrecognized reply command byte, erase this byte and try to get back on track
- if (log)
- log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
- __FUNCTION__,
- (uint8_t)m_bytes[0]);
- m_bytes.erase(0, 1);
- break;
+ m_bytes.append((const char *)src, src_len);
+ }
+
+ // Make sure we at least have enough bytes for a packet header
+ const size_t bytes_available = m_bytes.size();
+ if (bytes_available >= 8) {
+ packet.SetData(&m_bytes[0], bytes_available, m_byte_order);
+ lldb::offset_t offset = 0;
+ uint8_t reply_command = packet.GetU8(&offset);
+ switch (reply_command) {
+ case ePacketTypeRequest | KDP_EXCEPTION:
+ case ePacketTypeRequest | KDP_TERMINATION:
+ // We got an exception request, so be sure to send an ACK
+ {
+ PacketStreamType request_ack_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ // Set the reply but and make the ACK packet
+ request_ack_packet.PutHex8(reply_command | ePacketTypeReply);
+ request_ack_packet.PutHex8(packet.GetU8(&offset));
+ request_ack_packet.PutHex16(packet.GetU16(&offset));
+ request_ack_packet.PutHex32(packet.GetU32(&offset));
+ m_is_running.SetValue(false, eBroadcastAlways);
+ // Ack to the exception or termination
+ SendRequestPacketNoLock(request_ack_packet);
+ }
+ // Fall through to case below to get packet contents
+ LLVM_FALLTHROUGH;
+ case ePacketTypeReply | KDP_CONNECT:
+ case ePacketTypeReply | KDP_DISCONNECT:
+ case ePacketTypeReply | KDP_HOSTINFO:
+ case ePacketTypeReply | KDP_VERSION:
+ case ePacketTypeReply | KDP_MAXBYTES:
+ case ePacketTypeReply | KDP_READMEM:
+ case ePacketTypeReply | KDP_WRITEMEM:
+ case ePacketTypeReply | KDP_READREGS:
+ case ePacketTypeReply | KDP_WRITEREGS:
+ case ePacketTypeReply | KDP_LOAD:
+ case ePacketTypeReply | KDP_IMAGEPATH:
+ case ePacketTypeReply | KDP_SUSPEND:
+ case ePacketTypeReply | KDP_RESUMECPUS:
+ case ePacketTypeReply | KDP_BREAKPOINT_SET:
+ case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
+ case ePacketTypeReply | KDP_REGIONS:
+ case ePacketTypeReply | KDP_REATTACH:
+ case ePacketTypeReply | KDP_HOSTREBOOT:
+ case ePacketTypeReply | KDP_READMEM64:
+ case ePacketTypeReply | KDP_WRITEMEM64:
+ case ePacketTypeReply | KDP_BREAKPOINT_SET64:
+ case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
+ case ePacketTypeReply | KDP_KERNELVERSION:
+ case ePacketTypeReply | KDP_READPHYSMEM64:
+ case ePacketTypeReply | KDP_WRITEPHYSMEM64:
+ case ePacketTypeReply | KDP_READIOPORT:
+ case ePacketTypeReply | KDP_WRITEIOPORT:
+ case ePacketTypeReply | KDP_READMSR64:
+ case ePacketTypeReply | KDP_WRITEMSR64:
+ case ePacketTypeReply | KDP_DUMPINFO: {
+ offset = 2;
+ const uint16_t length = packet.GetU16(&offset);
+ if (length <= bytes_available) {
+ // We have an entire packet ready, we need to copy the data
+ // bytes into a buffer that will be owned by the packet and
+ // erase the bytes from our communcation buffer "m_bytes"
+ packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length)));
+ m_bytes.erase(0, length);
+
+ if (log) {
+ PacketStreamType log_strm;
+ DumpPacket(log_strm, packet);
+
+ log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
}
+ return true;
+ }
+ } break;
+
+ default:
+ // Unrecognized reply command byte, erase this byte and try to get back on
+ // track
+ if (log)
+ log->Printf("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
+ __FUNCTION__, (uint8_t)m_bytes[0]);
+ m_bytes.erase(0, 1);
+ break;
}
- packet.Clear();
- return false;
+ }
+ packet.Clear();
+ return false;
}
-
-bool
-CommunicationKDP::SendRequestConnect (uint16_t reply_port,
- uint16_t exc_port,
- const char *greeting)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- if (greeting == NULL)
- greeting = "";
-
- const CommandType command = KDP_CONNECT;
- // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
- const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
- MakeRequestPacketHeader (command, request_packet, command_length);
- // Always send connect ports as little endian
- request_packet.SetByteOrder (eByteOrderLittle);
- request_packet.PutHex16 (htons(reply_port));
- request_packet.PutHex16 (htons(exc_port));
- request_packet.SetByteOrder (m_byte_order);
- request_packet.PutCString (greeting);
- DataExtractor reply_packet;
- return SendRequestAndGetReply (command, request_packet, reply_packet);
+bool CommunicationKDP::SendRequestConnect(uint16_t reply_port,
+ uint16_t exc_port,
+ const char *greeting) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ if (greeting == NULL)
+ greeting = "";
+
+ const CommandType command = KDP_CONNECT;
+ // Length is 82 uint16_t and the length of the greeting C string with the
+ // terminating NULL
+ const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ // Always send connect ports as little endian
+ request_packet.SetByteOrder(eByteOrderLittle);
+ request_packet.PutHex16(htons(reply_port));
+ request_packet.PutHex16(htons(exc_port));
+ request_packet.SetByteOrder(m_byte_order);
+ request_packet.PutCString(greeting);
+ DataExtractor reply_packet;
+ return SendRequestAndGetReply(command, request_packet, reply_packet);
}
-void
-CommunicationKDP::ClearKDPSettings ()
-{
- m_request_sequence_id = 0;
- m_kdp_version_version = 0;
- m_kdp_version_feature = 0;
- m_kdp_hostinfo_cpu_mask = 0;
- m_kdp_hostinfo_cpu_type = 0;
- m_kdp_hostinfo_cpu_subtype = 0;
+void CommunicationKDP::ClearKDPSettings() {
+ m_request_sequence_id = 0;
+ m_kdp_version_version = 0;
+ m_kdp_version_feature = 0;
+ m_kdp_hostinfo_cpu_mask = 0;
+ m_kdp_hostinfo_cpu_type = 0;
+ m_kdp_hostinfo_cpu_subtype = 0;
}
-bool
-CommunicationKDP::SendRequestReattach (uint16_t reply_port)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_REATTACH;
- // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
- const uint32_t command_length = 8 + 2;
- MakeRequestPacketHeader (command, request_packet, command_length);
- // Always send connect ports as little endian
- request_packet.SetByteOrder (eByteOrderLittle);
- request_packet.PutHex16(htons(reply_port));
- request_packet.SetByteOrder (m_byte_order);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- // Reset the sequence ID to zero for reattach
- ClearKDPSettings ();
- lldb::offset_t offset = 4;
- m_session_key = reply_packet.GetU32 (&offset);
- return true;
- }
- return false;
+bool CommunicationKDP::SendRequestReattach(uint16_t reply_port) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_REATTACH;
+ // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
+ const uint32_t command_length = 8 + 2;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ // Always send connect ports as little endian
+ request_packet.SetByteOrder(eByteOrderLittle);
+ request_packet.PutHex16(htons(reply_port));
+ request_packet.SetByteOrder(m_byte_order);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ // Reset the sequence ID to zero for reattach
+ ClearKDPSettings();
+ lldb::offset_t offset = 4;
+ m_session_key = reply_packet.GetU32(&offset);
+ return true;
+ }
+ return false;
}
-uint32_t
-CommunicationKDP::GetVersion ()
-{
- if (!VersionIsValid())
- SendRequestVersion();
- return m_kdp_version_version;
+uint32_t CommunicationKDP::GetVersion() {
+ if (!VersionIsValid())
+ SendRequestVersion();
+ return m_kdp_version_version;
}
-uint32_t
-CommunicationKDP::GetFeatureFlags ()
-{
- if (!VersionIsValid())
- SendRequestVersion();
- return m_kdp_version_feature;
+uint32_t CommunicationKDP::GetFeatureFlags() {
+ if (!VersionIsValid())
+ SendRequestVersion();
+ return m_kdp_version_feature;
}
-bool
-CommunicationKDP::SendRequestVersion ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_VERSION;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- m_kdp_version_version = reply_packet.GetU32 (&offset);
- m_kdp_version_feature = reply_packet.GetU32 (&offset);
- return true;
- }
- return false;
+bool CommunicationKDP::SendRequestVersion() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_VERSION;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ m_kdp_version_version = reply_packet.GetU32(&offset);
+ m_kdp_version_feature = reply_packet.GetU32(&offset);
+ return true;
+ }
+ return false;
}
#if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
@@ -515,932 +465,863 @@ CommunicationKDP::SendRequestImagePath ()
}
#endif
-uint32_t
-CommunicationKDP::GetCPUMask ()
-{
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_mask;
+uint32_t CommunicationKDP::GetCPUMask() {
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_mask;
}
-uint32_t
-CommunicationKDP::GetCPUType ()
-{
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_type;
+uint32_t CommunicationKDP::GetCPUType() {
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_type;
}
-uint32_t
-CommunicationKDP::GetCPUSubtype ()
-{
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_subtype;
+uint32_t CommunicationKDP::GetCPUSubtype() {
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_subtype;
}
-lldb_private::UUID
-CommunicationKDP::GetUUID ()
-{
- UUID uuid;
- if (GetKernelVersion() == NULL)
- return uuid;
-
- if (m_kernel_version.find("UUID=") == std::string::npos)
- return uuid;
-
- size_t p = m_kernel_version.find("UUID=") + strlen ("UUID=");
- std::string uuid_str = m_kernel_version.substr(p, 36);
- if (uuid_str.size() < 32)
- return uuid;
+lldb_private::UUID CommunicationKDP::GetUUID() {
+ UUID uuid;
+ if (GetKernelVersion() == NULL)
+ return uuid;
- if (uuid.SetFromCString (uuid_str.c_str()) == 0)
- {
- UUID invalid_uuid;
- return invalid_uuid;
- }
+ if (m_kernel_version.find("UUID=") == std::string::npos)
+ return uuid;
+ size_t p = m_kernel_version.find("UUID=") + strlen("UUID=");
+ std::string uuid_str = m_kernel_version.substr(p, 36);
+ if (uuid_str.size() < 32)
return uuid;
-}
-bool
-CommunicationKDP::RemoteIsEFI ()
-{
- if (GetKernelVersion() == NULL)
- return false;
- if (strncmp (m_kernel_version.c_str(), "EFI", 3) == 0)
- return true;
- else
- return false;
-}
+ if (uuid.SetFromCString(uuid_str.c_str()) == 0) {
+ UUID invalid_uuid;
+ return invalid_uuid;
+ }
-bool
-CommunicationKDP::RemoteIsDarwinKernel ()
-{
- if (GetKernelVersion() == NULL)
- return false;
- if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
- return true;
- else
- return false;
+ return uuid;
}
-lldb::addr_t
-CommunicationKDP::GetLoadAddress ()
-{
- if (GetKernelVersion() == NULL)
- return LLDB_INVALID_ADDRESS;
-
- if (m_kernel_version.find("stext=") == std::string::npos)
- return LLDB_INVALID_ADDRESS;
- size_t p = m_kernel_version.find("stext=") + strlen ("stext=");
- if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
- return LLDB_INVALID_ADDRESS;
-
- addr_t kernel_load_address;
- errno = 0;
- kernel_load_address = ::strtoul (m_kernel_version.c_str() + p, NULL, 16);
- if (errno != 0 || kernel_load_address == 0)
- return LLDB_INVALID_ADDRESS;
-
- return kernel_load_address;
+bool CommunicationKDP::RemoteIsEFI() {
+ if (GetKernelVersion() == NULL)
+ return false;
+ if (strncmp(m_kernel_version.c_str(), "EFI", 3) == 0)
+ return true;
+ else
+ return false;
}
-bool
-CommunicationKDP::SendRequestHostInfo ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_HOSTINFO;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- m_kdp_hostinfo_cpu_mask = reply_packet.GetU32 (&offset);
- m_kdp_hostinfo_cpu_type = reply_packet.GetU32 (&offset);
- m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32 (&offset);
-
- ArchSpec kernel_arch;
- kernel_arch.SetArchitecture (eArchTypeMachO,
- m_kdp_hostinfo_cpu_type,
- m_kdp_hostinfo_cpu_subtype);
-
- m_addr_byte_size = kernel_arch.GetAddressByteSize();
- m_byte_order = kernel_arch.GetByteOrder();
- return true;
- }
+bool CommunicationKDP::RemoteIsDarwinKernel() {
+ if (GetKernelVersion() == NULL)
+ return false;
+ if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
+ return true;
+ else
return false;
}
-const char *
-CommunicationKDP::GetKernelVersion ()
-{
- if (m_kernel_version.empty())
- SendRequestKernelVersion ();
- return m_kernel_version.c_str();
-}
+lldb::addr_t CommunicationKDP::GetLoadAddress() {
+ if (GetKernelVersion() == NULL)
+ return LLDB_INVALID_ADDRESS;
-bool
-CommunicationKDP::SendRequestKernelVersion ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_KERNELVERSION;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- const char *kernel_version_cstr = reply_packet.PeekCStr(8);
- if (kernel_version_cstr && kernel_version_cstr[0])
- m_kernel_version.assign (kernel_version_cstr);
- return true;
- }
- return false;
+ if (m_kernel_version.find("stext=") == std::string::npos)
+ return LLDB_INVALID_ADDRESS;
+ size_t p = m_kernel_version.find("stext=") + strlen("stext=");
+ if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t kernel_load_address;
+ errno = 0;
+ kernel_load_address = ::strtoul(m_kernel_version.c_str() + p, NULL, 16);
+ if (errno != 0 || kernel_load_address == 0)
+ return LLDB_INVALID_ADDRESS;
+
+ return kernel_load_address;
}
-bool
-CommunicationKDP::SendRequestDisconnect ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_DISCONNECT;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- // Are we supposed to get a reply for disconnect?
- }
- ClearKDPSettings ();
+bool CommunicationKDP::SendRequestHostInfo() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_HOSTINFO;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ m_kdp_hostinfo_cpu_mask = reply_packet.GetU32(&offset);
+ m_kdp_hostinfo_cpu_type = reply_packet.GetU32(&offset);
+ m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32(&offset);
+
+ ArchSpec kernel_arch;
+ kernel_arch.SetArchitecture(eArchTypeMachO, m_kdp_hostinfo_cpu_type,
+ m_kdp_hostinfo_cpu_subtype);
+
+ m_addr_byte_size = kernel_arch.GetAddressByteSize();
+ m_byte_order = kernel_arch.GetByteOrder();
return true;
+ }
+ return false;
}
-uint32_t
-CommunicationKDP::SendRequestReadMemory (lldb::addr_t addr,
- void *dst,
- uint32_t dst_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + command_addr_byte_size + 4;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutMaxHex64 (addr, command_addr_byte_size);
- request_packet.PutHex32 (dst_len);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- uint32_t src_len = reply_packet.GetByteSize() - 12;
-
- if (src_len > 0)
- {
- const void *src = reply_packet.GetData(&offset, src_len);
- if (src)
- {
- ::memcpy (dst, src, src_len);
- error.Clear();
- return src_len;
- }
- }
- if (kdp_error)
- error.SetErrorStringWithFormat ("kdp read memory failed (error %u)", kdp_error);
- else
- error.SetErrorString ("kdp read memory failed");
- }
- else
- {
- error.SetErrorString ("failed to send packet");
- }
- return 0;
+const char *CommunicationKDP::GetKernelVersion() {
+ if (m_kernel_version.empty())
+ SendRequestKernelVersion();
+ return m_kernel_version.c_str();
}
+bool CommunicationKDP::SendRequestKernelVersion() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_KERNELVERSION;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ const char *kernel_version_cstr = reply_packet.PeekCStr(8);
+ if (kernel_version_cstr && kernel_version_cstr[0])
+ m_kernel_version.assign(kernel_version_cstr);
+ return true;
+ }
+ return false;
+}
-uint32_t
-CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr,
- const void *src,
- uint32_t src_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutMaxHex64 (addr, command_addr_byte_size);
- request_packet.PutHex32 (src_len);
- request_packet.PutRawBytes(src, src_len);
+bool CommunicationKDP::SendRequestDisconnect() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_DISCONNECT;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ // Are we supposed to get a reply for disconnect?
+ }
+ ClearKDPSettings();
+ return true;
+}
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error)
- error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error);
- else
- {
- error.Clear();
- return src_len;
- }
+uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst,
+ uint32_t dst_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ bool use_64 = (GetVersion() >= 11);
+ uint32_t command_addr_byte_size = use_64 ? 8 : 4;
+ const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
+ // Size is header + address size + uint32_t length
+ const uint32_t command_length = 8 + command_addr_byte_size + 4;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutMaxHex64(addr, command_addr_byte_size);
+ request_packet.PutHex32(dst_len);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ uint32_t src_len = reply_packet.GetByteSize() - 12;
+
+ if (src_len > 0) {
+ const void *src = reply_packet.GetData(&offset, src_len);
+ if (src) {
+ ::memcpy(dst, src, src_len);
+ error.Clear();
+ return src_len;
+ }
}
+ if (kdp_error)
+ error.SetErrorStringWithFormat("kdp read memory failed (error %u)",
+ kdp_error);
else
- {
- error.SetErrorString ("failed to send packet");
- }
- return 0;
+ error.SetErrorString("kdp read memory failed");
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-bool
-CommunicationKDP::SendRawRequest (uint8_t command_byte,
- const void *src, // Raw packet payload bytes
- uint32_t src_len, // Raw packet payload length
- DataExtractor &reply_packet,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + src_len;
- const CommandType command = (CommandType)command_byte;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutRawBytes(src, src_len);
-
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error && (command_byte != KDP_DUMPINFO))
- error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error);
- else
- {
- error.Clear();
- return true;
- }
+uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr,
+ const void *src,
+ uint32_t src_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ bool use_64 = (GetVersion() >= 11);
+ uint32_t command_addr_byte_size = use_64 ? 8 : 4;
+ const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
+ // Size is header + address size + uint32_t length
+ const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutMaxHex64(addr, command_addr_byte_size);
+ request_packet.PutHex32(src_len);
+ request_packet.PutRawBytes(src, src_len);
+
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error)
+ error.SetErrorStringWithFormat("kdp write memory failed (error %u)",
+ kdp_error);
+ else {
+ error.Clear();
+ return src_len;
}
- else
- {
- error.SetErrorString ("failed to send packet");
- }
- return false;
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-
-const char *
-CommunicationKDP::GetCommandAsCString (uint8_t command)
-{
- switch (command)
- {
- case KDP_CONNECT: return "KDP_CONNECT";
- case KDP_DISCONNECT: return "KDP_DISCONNECT";
- case KDP_HOSTINFO: return "KDP_HOSTINFO";
- case KDP_VERSION: return "KDP_VERSION";
- case KDP_MAXBYTES: return "KDP_MAXBYTES";
- case KDP_READMEM: return "KDP_READMEM";
- case KDP_WRITEMEM: return "KDP_WRITEMEM";
- case KDP_READREGS: return "KDP_READREGS";
- case KDP_WRITEREGS: return "KDP_WRITEREGS";
- case KDP_LOAD: return "KDP_LOAD";
- case KDP_IMAGEPATH: return "KDP_IMAGEPATH";
- case KDP_SUSPEND: return "KDP_SUSPEND";
- case KDP_RESUMECPUS: return "KDP_RESUMECPUS";
- case KDP_EXCEPTION: return "KDP_EXCEPTION";
- case KDP_TERMINATION: return "KDP_TERMINATION";
- case KDP_BREAKPOINT_SET: return "KDP_BREAKPOINT_SET";
- case KDP_BREAKPOINT_REMOVE: return "KDP_BREAKPOINT_REMOVE";
- case KDP_REGIONS: return "KDP_REGIONS";
- case KDP_REATTACH: return "KDP_REATTACH";
- case KDP_HOSTREBOOT: return "KDP_HOSTREBOOT";
- case KDP_READMEM64: return "KDP_READMEM64";
- case KDP_WRITEMEM64: return "KDP_WRITEMEM64";
- case KDP_BREAKPOINT_SET64: return "KDP_BREAKPOINT64_SET";
- case KDP_BREAKPOINT_REMOVE64: return "KDP_BREAKPOINT64_REMOVE";
- case KDP_KERNELVERSION: return "KDP_KERNELVERSION";
- case KDP_READPHYSMEM64: return "KDP_READPHYSMEM64";
- case KDP_WRITEPHYSMEM64: return "KDP_WRITEPHYSMEM64";
- case KDP_READIOPORT: return "KDP_READIOPORT";
- case KDP_WRITEIOPORT: return "KDP_WRITEIOPORT";
- case KDP_READMSR64: return "KDP_READMSR64";
- case KDP_WRITEMSR64: return "KDP_WRITEMSR64";
- case KDP_DUMPINFO: return "KDP_DUMPINFO";
+bool CommunicationKDP::SendRawRequest(
+ uint8_t command_byte,
+ const void *src, // Raw packet payload bytes
+ uint32_t src_len, // Raw packet payload length
+ DataExtractor &reply_packet, Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ // Size is header + address size + uint32_t length
+ const uint32_t command_length = 8 + src_len;
+ const CommandType command = (CommandType)command_byte;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutRawBytes(src, src_len);
+
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error && (command_byte != KDP_DUMPINFO))
+ error.SetErrorStringWithFormat("request packet 0x%8.8x failed (error %u)",
+ command_byte, kdp_error);
+ else {
+ error.Clear();
+ return true;
}
- return NULL;
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return false;
}
-void
-CommunicationKDP::DumpPacket (Stream &s, const void *data, uint32_t data_len)
-{
- DataExtractor extractor (data, data_len, m_byte_order, m_addr_byte_size);
- DumpPacket (s, extractor);
+const char *CommunicationKDP::GetCommandAsCString(uint8_t command) {
+ switch (command) {
+ case KDP_CONNECT:
+ return "KDP_CONNECT";
+ case KDP_DISCONNECT:
+ return "KDP_DISCONNECT";
+ case KDP_HOSTINFO:
+ return "KDP_HOSTINFO";
+ case KDP_VERSION:
+ return "KDP_VERSION";
+ case KDP_MAXBYTES:
+ return "KDP_MAXBYTES";
+ case KDP_READMEM:
+ return "KDP_READMEM";
+ case KDP_WRITEMEM:
+ return "KDP_WRITEMEM";
+ case KDP_READREGS:
+ return "KDP_READREGS";
+ case KDP_WRITEREGS:
+ return "KDP_WRITEREGS";
+ case KDP_LOAD:
+ return "KDP_LOAD";
+ case KDP_IMAGEPATH:
+ return "KDP_IMAGEPATH";
+ case KDP_SUSPEND:
+ return "KDP_SUSPEND";
+ case KDP_RESUMECPUS:
+ return "KDP_RESUMECPUS";
+ case KDP_EXCEPTION:
+ return "KDP_EXCEPTION";
+ case KDP_TERMINATION:
+ return "KDP_TERMINATION";
+ case KDP_BREAKPOINT_SET:
+ return "KDP_BREAKPOINT_SET";
+ case KDP_BREAKPOINT_REMOVE:
+ return "KDP_BREAKPOINT_REMOVE";
+ case KDP_REGIONS:
+ return "KDP_REGIONS";
+ case KDP_REATTACH:
+ return "KDP_REATTACH";
+ case KDP_HOSTREBOOT:
+ return "KDP_HOSTREBOOT";
+ case KDP_READMEM64:
+ return "KDP_READMEM64";
+ case KDP_WRITEMEM64:
+ return "KDP_WRITEMEM64";
+ case KDP_BREAKPOINT_SET64:
+ return "KDP_BREAKPOINT64_SET";
+ case KDP_BREAKPOINT_REMOVE64:
+ return "KDP_BREAKPOINT64_REMOVE";
+ case KDP_KERNELVERSION:
+ return "KDP_KERNELVERSION";
+ case KDP_READPHYSMEM64:
+ return "KDP_READPHYSMEM64";
+ case KDP_WRITEPHYSMEM64:
+ return "KDP_WRITEPHYSMEM64";
+ case KDP_READIOPORT:
+ return "KDP_READIOPORT";
+ case KDP_WRITEIOPORT:
+ return "KDP_WRITEIOPORT";
+ case KDP_READMSR64:
+ return "KDP_READMSR64";
+ case KDP_WRITEMSR64:
+ return "KDP_WRITEMSR64";
+ case KDP_DUMPINFO:
+ return "KDP_DUMPINFO";
+ }
+ return NULL;
}
-void
-CommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet)
-{
- const char *error_desc = NULL;
- if (packet.GetByteSize() < 8)
- {
- error_desc = "error: invalid packet (too short): ";
- }
- else
- {
- lldb::offset_t offset = 0;
- const uint8_t first_packet_byte = packet.GetU8 (&offset);
- const uint8_t sequence_id = packet.GetU8 (&offset);
- const uint16_t length = packet.GetU16 (&offset);
- const uint32_t key = packet.GetU32 (&offset);
- const CommandType command = ExtractCommand (first_packet_byte);
- const char *command_name = GetCommandAsCString (command);
- if (command_name)
- {
- const bool is_reply = ExtractIsReply(first_packet_byte);
- s.Printf ("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
- IsRunning(),
- is_reply ? "<--" : "-->",
- command_name,
- first_packet_byte,
- sequence_id,
- length,
- key);
-
- if (is_reply)
- {
- // Dump request reply packets
- switch (command)
- {
- // Commands that return a single 32 bit error
- case KDP_CONNECT:
- case KDP_WRITEMEM:
- case KDP_WRITEMEM64:
- case KDP_BREAKPOINT_SET:
- case KDP_BREAKPOINT_REMOVE:
- case KDP_BREAKPOINT_SET64:
- case KDP_BREAKPOINT_REMOVE64:
- case KDP_WRITEREGS:
- case KDP_LOAD:
- case KDP_WRITEIOPORT:
- case KDP_WRITEMSR64:
- {
- const uint32_t error = packet.GetU32 (&offset);
- s.Printf(" (error=0x%8.8x)", error);
- }
- break;
-
- case KDP_DISCONNECT:
- case KDP_REATTACH:
- case KDP_HOSTREBOOT:
- case KDP_SUSPEND:
- case KDP_RESUMECPUS:
- case KDP_EXCEPTION:
- case KDP_TERMINATION:
- // No return value for the reply, just the header to ack
- s.PutCString(" ()");
- break;
-
- case KDP_HOSTINFO:
- {
- const uint32_t cpu_mask = packet.GetU32 (&offset);
- const uint32_t cpu_type = packet.GetU32 (&offset);
- const uint32_t cpu_subtype = packet.GetU32 (&offset);
- s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype);
- }
- break;
-
- case KDP_VERSION:
- {
- const uint32_t version = packet.GetU32 (&offset);
- const uint32_t feature = packet.GetU32 (&offset);
- s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
- }
- break;
-
- case KDP_REGIONS:
- {
- const uint32_t region_count = packet.GetU32 (&offset);
- s.Printf(" (count = %u", region_count);
- for (uint32_t i=0; i<region_count; ++i)
- {
- const addr_t region_addr = packet.GetPointer (&offset);
- const uint32_t region_size = packet.GetU32 (&offset);
- const uint32_t region_prot = packet.GetU32 (&offset);
- s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
- }
- }
- break;
-
- case KDP_READMEM:
- case KDP_READMEM64:
- case KDP_READPHYSMEM64:
- {
- const uint32_t error = packet.GetU32 (&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x:\n", error);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatBytesWithASCII, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- m_last_read_memory_addr, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_READREGS:
- {
- const uint32_t error = packet.GetU32 (&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x regs:\n", error);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- m_addr_byte_size, // Size of each item in bytes
- count / m_addr_byte_size, // Number of items
- 16 / m_addr_byte_size, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_KERNELVERSION:
- {
- const char *kernel_version = packet.PeekCStr(8);
- s.Printf(" (version = \"%s\")", kernel_version);
- }
- break;
-
- case KDP_MAXBYTES:
- {
- const uint32_t max_bytes = packet.GetU32 (&offset);
- s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
- }
- break;
- case KDP_IMAGEPATH:
- {
- const char *path = packet.GetCStr(&offset);
- s.Printf(" (path = \"%s\")", path);
- }
- break;
-
- case KDP_READIOPORT:
- case KDP_READMSR64:
- {
- const uint32_t error = packet.GetU32 (&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x io:\n", error);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
- case KDP_DUMPINFO:
- {
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (count = %u, bytes = \n", count);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
-
- }
- break;
-
- default:
- s.Printf(" (add support for dumping this packet reply!!!");
- break;
-
- }
- }
- else
- {
- // Dump request packets
- switch (command)
- {
- case KDP_CONNECT:
- {
- const uint16_t reply_port = ntohs(packet.GetU16 (&offset));
- const uint16_t exc_port = ntohs(packet.GetU16 (&offset));
- s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset));
- }
- break;
-
- case KDP_DISCONNECT:
- case KDP_HOSTREBOOT:
- case KDP_HOSTINFO:
- case KDP_VERSION:
- case KDP_REGIONS:
- case KDP_KERNELVERSION:
- case KDP_MAXBYTES:
- case KDP_IMAGEPATH:
- case KDP_SUSPEND:
- // No args, just the header in the request...
- s.PutCString(" ()");
- break;
-
- case KDP_RESUMECPUS:
- {
- const uint32_t cpu_mask = packet.GetU32 (&offset);
- s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
- }
- break;
-
- case KDP_READMEM:
- {
- const uint32_t addr = packet.GetU32 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
- m_last_read_memory_addr = addr;
- }
- break;
-
- case KDP_WRITEMEM:
- {
- const uint32_t addr = packet.GetU32 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
- if (size > 0)
- DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- }
- break;
-
- case KDP_READMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
- m_last_read_memory_addr = addr;
- }
- break;
-
- case KDP_READPHYSMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- const uint32_t lcpu = packet.GetU16 (&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu);
- m_last_read_memory_addr = addr;
- }
- break;
-
- case KDP_WRITEMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, size);
- if (size > 0)
- DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- }
- break;
-
- case KDP_WRITEPHYSMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- const uint32_t lcpu = packet.GetU16 (&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu);
- if (size > 0)
- DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- }
- break;
-
- case KDP_READREGS:
- {
- const uint32_t cpu = packet.GetU32 (&offset);
- const uint32_t flavor = packet.GetU32 (&offset);
- s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
- }
- break;
-
- case KDP_WRITEREGS:
- {
- const uint32_t cpu = packet.GetU32 (&offset);
- const uint32_t flavor = packet.GetU32 (&offset);
- const uint32_t nbytes = packet.GetByteSize() - offset;
- s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
- if (nbytes > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- m_addr_byte_size, // Size of each item in bytes
- nbytes / m_addr_byte_size, // Number of items
- 16 / m_addr_byte_size, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
-
- case KDP_BREAKPOINT_SET:
- case KDP_BREAKPOINT_REMOVE:
- {
- const uint32_t addr = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%8.8x)", addr);
- }
- break;
-
- case KDP_BREAKPOINT_SET64:
- case KDP_BREAKPOINT_REMOVE64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
- }
- break;
-
-
- case KDP_LOAD:
- {
- const char *path = packet.GetCStr(&offset);
- s.Printf(" (path = \"%s\")", path);
- }
- break;
-
- case KDP_EXCEPTION:
- {
- const uint32_t count = packet.GetU32 (&offset);
-
- for (uint32_t i=0; i<count; ++i)
- {
- const uint32_t cpu = packet.GetU32 (&offset);
- const uint32_t exc = packet.GetU32 (&offset);
- const uint32_t code = packet.GetU32 (&offset);
- const uint32_t subcode = packet.GetU32 (&offset);
- const char *exc_cstr = NULL;
- switch (exc)
- {
- case 1: exc_cstr = "EXC_BAD_ACCESS"; break;
- case 2: exc_cstr = "EXC_BAD_INSTRUCTION"; break;
- case 3: exc_cstr = "EXC_ARITHMETIC"; break;
- case 4: exc_cstr = "EXC_EMULATION"; break;
- case 5: exc_cstr = "EXC_SOFTWARE"; break;
- case 6: exc_cstr = "EXC_BREAKPOINT"; break;
- case 7: exc_cstr = "EXC_SYSCALL"; break;
- case 8: exc_cstr = "EXC_MACH_SYSCALL"; break;
- case 9: exc_cstr = "EXC_RPC_ALERT"; break;
- case 10: exc_cstr = "EXC_CRASH"; break;
- default:
- break;
- }
-
- s.Printf ("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)} ",
- cpu, exc_cstr, exc, code, code, subcode, subcode);
- }
- }
- break;
-
- case KDP_TERMINATION:
- {
- const uint32_t term_code = packet.GetU32 (&offset);
- const uint32_t exit_code = packet.GetU32 (&offset);
- s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code);
- }
- break;
-
- case KDP_REATTACH:
- {
- const uint16_t reply_port = ntohs(packet.GetU16 (&offset));
- s.Printf(" (reply_port = %u)", reply_port);
- }
- break;
-
- case KDP_READMSR64:
- {
- const uint32_t address = packet.GetU32 (&offset);
- const uint16_t lcpu = packet.GetU16 (&offset);
- s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
- }
- break;
-
- case KDP_WRITEMSR64:
- {
- const uint32_t address = packet.GetU32 (&offset);
- const uint16_t lcpu = packet.GetU16 (&offset);
- const uint32_t nbytes = packet.GetByteSize() - offset;
- s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes);
- if (nbytes > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- nbytes, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_READIOPORT:
- {
- const uint16_t lcpu = packet.GetU16 (&offset);
- const uint16_t address = packet.GetU16 (&offset);
- const uint16_t nbytes = packet.GetU16 (&offset);
- s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes);
- }
- break;
-
- case KDP_WRITEIOPORT:
- {
- const uint16_t lcpu = packet.GetU16 (&offset);
- const uint16_t address = packet.GetU16 (&offset);
- const uint16_t nbytes = packet.GetU16 (&offset);
- s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes);
- if (nbytes > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- nbytes, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_DUMPINFO:
- {
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (count = %u, bytes = \n", count);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
-
- }
- break;
-
- }
- }
- }
- else
- {
- error_desc = "error: invalid packet command: ";
- }
- }
-
- if (error_desc)
- {
- s.PutCString (error_desc);
-
- packet.Dump (&s, // Stream to dump to
- 0, // Offset into "packet"
- eFormatBytes, // Dump as hex bytes
- 1, // Size of each item is 1 for single bytes
- packet.GetByteSize(), // Number of bytes
- UINT32_MAX, // Num bytes per line
- LLDB_INVALID_ADDRESS, // Base address
- 0, 0); // Bitfield info set to not do anything bitfield related
- }
+void CommunicationKDP::DumpPacket(Stream &s, const void *data,
+ uint32_t data_len) {
+ DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size);
+ DumpPacket(s, extractor);
}
-uint32_t
-CommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
- uint32_t flavor,
- void *dst,
- uint32_t dst_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_READREGS;
- // Size is header + 4 byte cpu and 4 byte flavor
- const uint32_t command_length = 8 + 4 + 4;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutHex32 (cpu);
- request_packet.PutHex32 (flavor);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- uint32_t src_len = reply_packet.GetByteSize() - 12;
-
- if (src_len > 0)
- {
- const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
- const void *src = reply_packet.GetData(&offset, bytes_to_copy);
- if (src)
- {
- ::memcpy (dst, src, bytes_to_copy);
- error.Clear();
- // Return the number of bytes we could have returned regardless if
- // we copied them or not, just so we know when things don't match up
- return src_len;
+void CommunicationKDP::DumpPacket(Stream &s, const DataExtractor &packet) {
+ const char *error_desc = NULL;
+ if (packet.GetByteSize() < 8) {
+ error_desc = "error: invalid packet (too short): ";
+ } else {
+ lldb::offset_t offset = 0;
+ const uint8_t first_packet_byte = packet.GetU8(&offset);
+ const uint8_t sequence_id = packet.GetU8(&offset);
+ const uint16_t length = packet.GetU16(&offset);
+ const uint32_t key = packet.GetU32(&offset);
+ const CommandType command = ExtractCommand(first_packet_byte);
+ const char *command_name = GetCommandAsCString(command);
+ if (command_name) {
+ const bool is_reply = ExtractIsReply(first_packet_byte);
+ s.Printf("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
+ IsRunning(), is_reply ? "<--" : "-->", command_name,
+ first_packet_byte, sequence_id, length, key);
+
+ if (is_reply) {
+ // Dump request reply packets
+ switch (command) {
+ // Commands that return a single 32 bit error
+ case KDP_CONNECT:
+ case KDP_WRITEMEM:
+ case KDP_WRITEMEM64:
+ case KDP_BREAKPOINT_SET:
+ case KDP_BREAKPOINT_REMOVE:
+ case KDP_BREAKPOINT_SET64:
+ case KDP_BREAKPOINT_REMOVE64:
+ case KDP_WRITEREGS:
+ case KDP_LOAD:
+ case KDP_WRITEIOPORT:
+ case KDP_WRITEMSR64: {
+ const uint32_t error = packet.GetU32(&offset);
+ s.Printf(" (error=0x%8.8x)", error);
+ } break;
+
+ case KDP_DISCONNECT:
+ case KDP_REATTACH:
+ case KDP_HOSTREBOOT:
+ case KDP_SUSPEND:
+ case KDP_RESUMECPUS:
+ case KDP_EXCEPTION:
+ case KDP_TERMINATION:
+ // No return value for the reply, just the header to ack
+ s.PutCString(" ()");
+ break;
+
+ case KDP_HOSTINFO: {
+ const uint32_t cpu_mask = packet.GetU32(&offset);
+ const uint32_t cpu_type = packet.GetU32(&offset);
+ const uint32_t cpu_subtype = packet.GetU32(&offset);
+ s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)",
+ cpu_mask, cpu_type, cpu_subtype);
+ } break;
+
+ case KDP_VERSION: {
+ const uint32_t version = packet.GetU32(&offset);
+ const uint32_t feature = packet.GetU32(&offset);
+ s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
+ } break;
+
+ case KDP_REGIONS: {
+ const uint32_t region_count = packet.GetU32(&offset);
+ s.Printf(" (count = %u", region_count);
+ for (uint32_t i = 0; i < region_count; ++i) {
+ const addr_t region_addr = packet.GetPointer(&offset);
+ const uint32_t region_size = packet.GetU32(&offset);
+ const uint32_t region_prot = packet.GetU32(&offset);
+ s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64
+ " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }",
+ region_addr, region_addr, region_addr + region_size,
+ region_size, GetPermissionsAsCString(region_prot));
+ }
+ } break;
+
+ case KDP_READMEM:
+ case KDP_READMEM64:
+ case KDP_READPHYSMEM64: {
+ const uint32_t error = packet.GetU32(&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x:\n", error);
+ if (count > 0)
+ packet.Dump(&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatBytesWithASCII, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ m_last_read_memory_addr, // Don't show addresses before
+ // each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_READREGS: {
+ const uint32_t error = packet.GetU32(&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x regs:\n", error);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ m_addr_byte_size, // Size of each item in bytes
+ count / m_addr_byte_size, // Number of items
+ 16 / m_addr_byte_size, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_KERNELVERSION: {
+ const char *kernel_version = packet.PeekCStr(8);
+ s.Printf(" (version = \"%s\")", kernel_version);
+ } break;
+
+ case KDP_MAXBYTES: {
+ const uint32_t max_bytes = packet.GetU32(&offset);
+ s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
+ } break;
+ case KDP_IMAGEPATH: {
+ const char *path = packet.GetCStr(&offset);
+ s.Printf(" (path = \"%s\")", path);
+ } break;
+
+ case KDP_READIOPORT:
+ case KDP_READMSR64: {
+ const uint32_t error = packet.GetU32(&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x io:\n", error);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+ case KDP_DUMPINFO: {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ } break;
+
+ default:
+ s.Printf(" (add support for dumping this packet reply!!!");
+ break;
+ }
+ } else {
+ // Dump request packets
+ switch (command) {
+ case KDP_CONNECT: {
+ const uint16_t reply_port = ntohs(packet.GetU16(&offset));
+ const uint16_t exc_port = ntohs(packet.GetU16(&offset));
+ s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")",
+ reply_port, exc_port, packet.GetCStr(&offset));
+ } break;
+
+ case KDP_DISCONNECT:
+ case KDP_HOSTREBOOT:
+ case KDP_HOSTINFO:
+ case KDP_VERSION:
+ case KDP_REGIONS:
+ case KDP_KERNELVERSION:
+ case KDP_MAXBYTES:
+ case KDP_IMAGEPATH:
+ case KDP_SUSPEND:
+ // No args, just the header in the request...
+ s.PutCString(" ()");
+ break;
+
+ case KDP_RESUMECPUS: {
+ const uint32_t cpu_mask = packet.GetU32(&offset);
+ s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
+ } break;
+
+ case KDP_READMEM: {
+ const uint32_t addr = packet.GetU32(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
+ m_last_read_memory_addr = addr;
+ } break;
+
+ case KDP_WRITEMEM: {
+ const uint32_t addr = packet.GetU32(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
+ 32, addr);
+ } break;
+
+ case KDP_READMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
+ m_last_read_memory_addr = addr;
+ } break;
+
+ case KDP_READPHYSMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ const uint32_t lcpu = packet.GetU16(&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size,
+ lcpu);
+ m_last_read_memory_addr = addr;
+ } break;
+
+ case KDP_WRITEMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr,
+ size);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
+ 32, addr);
+ } break;
+
+ case KDP_WRITEPHYSMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ const uint32_t lcpu = packet.GetU16(&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n",
+ addr, size, lcpu);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
+ 32, addr);
+ } break;
+
+ case KDP_READREGS: {
+ const uint32_t cpu = packet.GetU32(&offset);
+ const uint32_t flavor = packet.GetU32(&offset);
+ s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
+ } break;
+
+ case KDP_WRITEREGS: {
+ const uint32_t cpu = packet.GetU32(&offset);
+ const uint32_t flavor = packet.GetU32(&offset);
+ const uint32_t nbytes = packet.GetByteSize() - offset;
+ s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
+ if (nbytes > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ m_addr_byte_size, // Size of each item in bytes
+ nbytes / m_addr_byte_size, // Number of items
+ 16 / m_addr_byte_size, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_BREAKPOINT_SET:
+ case KDP_BREAKPOINT_REMOVE: {
+ const uint32_t addr = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%8.8x)", addr);
+ } break;
+
+ case KDP_BREAKPOINT_SET64:
+ case KDP_BREAKPOINT_REMOVE64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
+ } break;
+
+ case KDP_LOAD: {
+ const char *path = packet.GetCStr(&offset);
+ s.Printf(" (path = \"%s\")", path);
+ } break;
+
+ case KDP_EXCEPTION: {
+ const uint32_t count = packet.GetU32(&offset);
+
+ for (uint32_t i = 0; i < count; ++i) {
+ const uint32_t cpu = packet.GetU32(&offset);
+ const uint32_t exc = packet.GetU32(&offset);
+ const uint32_t code = packet.GetU32(&offset);
+ const uint32_t subcode = packet.GetU32(&offset);
+ const char *exc_cstr = NULL;
+ switch (exc) {
+ case 1:
+ exc_cstr = "EXC_BAD_ACCESS";
+ break;
+ case 2:
+ exc_cstr = "EXC_BAD_INSTRUCTION";
+ break;
+ case 3:
+ exc_cstr = "EXC_ARITHMETIC";
+ break;
+ case 4:
+ exc_cstr = "EXC_EMULATION";
+ break;
+ case 5:
+ exc_cstr = "EXC_SOFTWARE";
+ break;
+ case 6:
+ exc_cstr = "EXC_BREAKPOINT";
+ break;
+ case 7:
+ exc_cstr = "EXC_SYSCALL";
+ break;
+ case 8:
+ exc_cstr = "EXC_MACH_SYSCALL";
+ break;
+ case 9:
+ exc_cstr = "EXC_RPC_ALERT";
+ break;
+ case 10:
+ exc_cstr = "EXC_CRASH";
+ break;
+ default:
+ break;
}
+
+ s.Printf("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), "
+ "subcode = %u (0x%8.8x)} ",
+ cpu, exc_cstr, exc, code, code, subcode, subcode);
+ }
+ } break;
+
+ case KDP_TERMINATION: {
+ const uint32_t term_code = packet.GetU32(&offset);
+ const uint32_t exit_code = packet.GetU32(&offset);
+ s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))",
+ term_code, term_code, exit_code, exit_code);
+ } break;
+
+ case KDP_REATTACH: {
+ const uint16_t reply_port = ntohs(packet.GetU16(&offset));
+ s.Printf(" (reply_port = %u)", reply_port);
+ } break;
+
+ case KDP_READMSR64: {
+ const uint32_t address = packet.GetU32(&offset);
+ const uint16_t lcpu = packet.GetU16(&offset);
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
+ } break;
+
+ case KDP_WRITEMSR64: {
+ const uint32_t address = packet.GetU32(&offset);
+ const uint16_t lcpu = packet.GetU16(&offset);
+ const uint32_t nbytes = packet.GetByteSize() - offset;
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu,
+ address, nbytes);
+ if (nbytes > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_READIOPORT: {
+ const uint16_t lcpu = packet.GetU16(&offset);
+ const uint16_t address = packet.GetU16(&offset);
+ const uint16_t nbytes = packet.GetU16(&offset);
+ s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address,
+ nbytes);
+ } break;
+
+ case KDP_WRITEIOPORT: {
+ const uint16_t lcpu = packet.GetU16(&offset);
+ const uint16_t address = packet.GetU16(&offset);
+ const uint16_t nbytes = packet.GetU16(&offset);
+ s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu,
+ address, nbytes);
+ if (nbytes > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_DUMPINFO: {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ } break;
}
- if (kdp_error)
- error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
- else
- error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
- }
- else
- {
- error.SetErrorString ("failed to send packet");
+ }
+ } else {
+ error_desc = "error: invalid packet command: ";
}
- return 0;
+ }
+
+ if (error_desc) {
+ s.PutCString(error_desc);
+
+ packet.Dump(&s, // Stream to dump to
+ 0, // Offset into "packet"
+ eFormatBytes, // Dump as hex bytes
+ 1, // Size of each item is 1 for single bytes
+ packet.GetByteSize(), // Number of bytes
+ UINT32_MAX, // Num bytes per line
+ LLDB_INVALID_ADDRESS, // Base address
+ 0, 0); // Bitfield info set to not do anything bitfield related
+ }
}
-uint32_t
-CommunicationKDP::SendRequestWriteRegisters (uint32_t cpu,
- uint32_t flavor,
- const void *src,
- uint32_t src_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_WRITEREGS;
- // Size is header + 4 byte cpu and 4 byte flavor
- const uint32_t command_length = 8 + 4 + 4 + src_len;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutHex32 (cpu);
- request_packet.PutHex32 (flavor);
- request_packet.Write(src, src_len);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error == 0)
- return src_len;
- error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
+uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu,
+ uint32_t flavor, void *dst,
+ uint32_t dst_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_READREGS;
+ // Size is header + 4 byte cpu and 4 byte flavor
+ const uint32_t command_length = 8 + 4 + 4;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutHex32(cpu);
+ request_packet.PutHex32(flavor);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ uint32_t src_len = reply_packet.GetByteSize() - 12;
+
+ if (src_len > 0) {
+ const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
+ const void *src = reply_packet.GetData(&offset, bytes_to_copy);
+ if (src) {
+ ::memcpy(dst, src, bytes_to_copy);
+ error.Clear();
+ // Return the number of bytes we could have returned regardless if
+ // we copied them or not, just so we know when things don't match up
+ return src_len;
+ }
}
+ if (kdp_error)
+ error.SetErrorStringWithFormat(
+ "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
+ flavor, kdp_error);
else
- {
- error.SetErrorString ("failed to send packet");
- }
- return 0;
+ error.SetErrorStringWithFormat(
+ "failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-
-bool
-CommunicationKDP::SendRequestResume ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_RESUMECPUS;
- const uint32_t command_length = 12;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutHex32(GetCPUMask());
-
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- return true;
- return false;
+uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu,
+ uint32_t flavor,
+ const void *src,
+ uint32_t src_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_WRITEREGS;
+ // Size is header + 4 byte cpu and 4 byte flavor
+ const uint32_t command_length = 8 + 4 + 4 + src_len;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutHex32(cpu);
+ request_packet.PutHex32(flavor);
+ request_packet.Write(src, src_len);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error == 0)
+ return src_len;
+ error.SetErrorStringWithFormat(
+ "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
+ flavor, kdp_error);
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-bool
-CommunicationKDP::SendRequestBreakpoint (bool set, addr_t addr)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET ):
- (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
+bool CommunicationKDP::SendRequestResume() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_RESUMECPUS;
+ const uint32_t command_length = 12;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutHex32(GetCPUMask());
- const uint32_t command_length = 8 + command_addr_byte_size;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutMaxHex64 (addr, command_addr_byte_size);
-
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error == 0)
- return true;
- }
- return false;
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet))
+ return true;
+ return false;
}
-bool
-CommunicationKDP::SendRequestSuspend ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_SUSPEND;
- 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;
+bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ bool use_64 = (GetVersion() >= 11);
+ uint32_t command_addr_byte_size = use_64 ? 8 : 4;
+ const CommandType command =
+ set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET)
+ : (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
+
+ const uint32_t command_length = 8 + command_addr_byte_size;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutMaxHex64(addr, command_addr_byte_size);
+
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error == 0)
+ return true;
+ }
+ return false;
}
+bool CommunicationKDP::SendRequestSuspend() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_SUSPEND;
+ 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;
+}
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
index 89e55a561e74..eed3daa4647e 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
@@ -18,330 +18,245 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Host/Predicate.h"
-#include "lldb/Host/TimeValue.h"
+#include "lldb/lldb-private.h"
-class CommunicationKDP : public lldb_private::Communication
-{
+class CommunicationKDP : public lldb_private::Communication {
public:
- enum
- {
- eBroadcastBitRunPacketSent = kLoUserBroadcastBit
- };
-
- const static uint32_t kMaxPacketSize = 1200;
- const static uint32_t kMaxDataSize = 1024;
- typedef lldb_private::StreamBuffer<1024> PacketStreamType;
- typedef enum
- {
- KDP_CONNECT = 0u,
- KDP_DISCONNECT,
- KDP_HOSTINFO,
- KDP_VERSION,
- KDP_MAXBYTES,
- KDP_READMEM,
- KDP_WRITEMEM,
- KDP_READREGS,
- KDP_WRITEREGS,
- KDP_LOAD,
- KDP_IMAGEPATH,
- KDP_SUSPEND,
- KDP_RESUMECPUS,
- KDP_EXCEPTION,
- KDP_TERMINATION,
- KDP_BREAKPOINT_SET,
- KDP_BREAKPOINT_REMOVE,
- KDP_REGIONS,
- KDP_REATTACH,
- KDP_HOSTREBOOT,
- KDP_READMEM64,
- KDP_WRITEMEM64,
- KDP_BREAKPOINT_SET64,
- KDP_BREAKPOINT_REMOVE64,
- KDP_KERNELVERSION,
- KDP_READPHYSMEM64,
- KDP_WRITEPHYSMEM64,
- KDP_READIOPORT,
- KDP_WRITEIOPORT,
- KDP_READMSR64,
- KDP_WRITEMSR64,
- KDP_DUMPINFO
- } CommandType;
-
- enum
- {
- KDP_FEATURE_BP = (1u << 0)
- };
-
- typedef enum
- {
- KDP_PROTERR_SUCCESS = 0,
- KDP_PROTERR_ALREADY_CONNECTED,
- KDP_PROTERR_BAD_NBYTES,
- KDP_PROTERR_BADFLAVOR
- } KDPError;
-
- typedef enum
- {
- ePacketTypeRequest = 0x00u,
- ePacketTypeReply = 0x80u,
- ePacketTypeMask = 0x80u,
- eCommandTypeMask = 0x7fu
- } PacketType;
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommunicationKDP (const char *comm_name);
-
- virtual
- ~CommunicationKDP();
-
- bool
- SendRequestPacket (const PacketStreamType &request_packet);
-
- // Wait for a packet within 'nsec' seconds
- size_t
- WaitForPacketWithTimeoutMicroSeconds (lldb_private::DataExtractor &response,
- uint32_t usec);
-
- bool
- GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
-
- bool
- CheckForPacket (const uint8_t *src,
- size_t src_len,
- lldb_private::DataExtractor &packet);
- bool
- IsRunning() const
- {
- return m_is_running.GetValue();
- }
-
- //------------------------------------------------------------------
- // Set the global packet timeout.
- //
- // For clients, this is the timeout that gets used when sending
- // packets and waiting for responses. For servers, this might not
- // get used, and if it doesn't this should be moved to the
- // CommunicationKDPClient.
- //------------------------------------------------------------------
- uint32_t
- SetPacketTimeout (uint32_t packet_timeout)
- {
- const uint32_t old_packet_timeout = m_packet_timeout;
- m_packet_timeout = packet_timeout;
- return old_packet_timeout;
- }
-
- uint32_t
- GetPacketTimeoutInMicroSeconds () const
- {
- return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
- }
-
- //------------------------------------------------------------------
- // Public Request Packets
- //------------------------------------------------------------------
- bool
- SendRequestConnect (uint16_t reply_port,
- uint16_t exc_port,
- const char *greeting);
-
- bool
- SendRequestReattach (uint16_t reply_port);
-
- bool
- SendRequestDisconnect ();
-
- uint32_t
- SendRequestReadMemory (lldb::addr_t addr,
- void *dst,
- uint32_t dst_size,
- lldb_private::Error &error);
-
- uint32_t
- SendRequestWriteMemory (lldb::addr_t addr,
- const void *src,
- uint32_t src_len,
- lldb_private::Error &error);
-
- bool
- SendRawRequest (uint8_t command_byte,
- const void *src,
- uint32_t src_len,
- lldb_private::DataExtractor &reply,
- lldb_private::Error &error);
-
- uint32_t
- SendRequestReadRegisters (uint32_t cpu,
- uint32_t flavor,
- void *dst,
- uint32_t dst_size,
- lldb_private::Error &error);
-
- uint32_t
- SendRequestWriteRegisters (uint32_t cpu,
- uint32_t flavor,
- const void *src,
- uint32_t src_size,
- lldb_private::Error &error);
-
- const char *
- GetKernelVersion ();
-
- // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- // const char *
- // GetImagePath ();
-
- uint32_t
- GetVersion ();
-
- uint32_t
- GetFeatureFlags ();
-
- bool
- LocalBreakpointsAreSupported ()
- {
- return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
- }
-
- uint32_t
- GetCPUMask ();
-
- uint32_t
- GetCPUType ();
-
- uint32_t
- GetCPUSubtype ();
-
- lldb_private::UUID
- GetUUID ();
-
- bool
- RemoteIsEFI ();
-
- bool
- RemoteIsDarwinKernel ();
-
- lldb::addr_t
- GetLoadAddress ();
-
- bool
- SendRequestResume ();
-
- bool
- SendRequestSuspend ();
-
- bool
- SendRequestBreakpoint (bool set, lldb::addr_t addr);
+ enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit };
+
+ const static uint32_t kMaxPacketSize = 1200;
+ const static uint32_t kMaxDataSize = 1024;
+ typedef lldb_private::StreamBuffer<1024> PacketStreamType;
+ typedef enum {
+ KDP_CONNECT = 0u,
+ KDP_DISCONNECT,
+ KDP_HOSTINFO,
+ KDP_VERSION,
+ KDP_MAXBYTES,
+ KDP_READMEM,
+ KDP_WRITEMEM,
+ KDP_READREGS,
+ KDP_WRITEREGS,
+ KDP_LOAD,
+ KDP_IMAGEPATH,
+ KDP_SUSPEND,
+ KDP_RESUMECPUS,
+ KDP_EXCEPTION,
+ KDP_TERMINATION,
+ KDP_BREAKPOINT_SET,
+ KDP_BREAKPOINT_REMOVE,
+ KDP_REGIONS,
+ KDP_REATTACH,
+ KDP_HOSTREBOOT,
+ KDP_READMEM64,
+ KDP_WRITEMEM64,
+ KDP_BREAKPOINT_SET64,
+ KDP_BREAKPOINT_REMOVE64,
+ KDP_KERNELVERSION,
+ KDP_READPHYSMEM64,
+ KDP_WRITEPHYSMEM64,
+ KDP_READIOPORT,
+ KDP_WRITEIOPORT,
+ KDP_READMSR64,
+ KDP_WRITEMSR64,
+ KDP_DUMPINFO
+ } CommandType;
+
+ enum { KDP_FEATURE_BP = (1u << 0) };
+
+ typedef enum {
+ KDP_PROTERR_SUCCESS = 0,
+ KDP_PROTERR_ALREADY_CONNECTED,
+ KDP_PROTERR_BAD_NBYTES,
+ KDP_PROTERR_BADFLAVOR
+ } KDPError;
+
+ typedef enum {
+ ePacketTypeRequest = 0x00u,
+ ePacketTypeReply = 0x80u,
+ ePacketTypeMask = 0x80u,
+ eCommandTypeMask = 0x7fu
+ } PacketType;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommunicationKDP(const char *comm_name);
+
+ virtual ~CommunicationKDP();
+
+ bool SendRequestPacket(const PacketStreamType &request_packet);
+
+ // Wait for a packet within 'nsec' seconds
+ size_t
+ WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response,
+ uint32_t usec);
+
+ bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
+
+ bool CheckForPacket(const uint8_t *src, size_t src_len,
+ lldb_private::DataExtractor &packet);
+ bool IsRunning() const { return m_is_running.GetValue(); }
+
+ //------------------------------------------------------------------
+ // Set the global packet timeout.
+ //
+ // For clients, this is the timeout that gets used when sending
+ // packets and waiting for responses. For servers, this might not
+ // get used, and if it doesn't this should be moved to the
+ // CommunicationKDPClient.
+ //------------------------------------------------------------------
+ std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
+ const auto old_packet_timeout = m_packet_timeout;
+ m_packet_timeout = packet_timeout;
+ return old_packet_timeout;
+ }
+
+ std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
+
+ //------------------------------------------------------------------
+ // Public Request Packets
+ //------------------------------------------------------------------
+ bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port,
+ const char *greeting);
+
+ bool SendRequestReattach(uint16_t reply_port);
+
+ bool SendRequestDisconnect();
+
+ uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst,
+ uint32_t dst_size, lldb_private::Error &error);
+
+ uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
+ uint32_t src_len, lldb_private::Error &error);
+
+ bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
+ lldb_private::DataExtractor &reply,
+ lldb_private::Error &error);
+
+ uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
+ uint32_t dst_size,
+ lldb_private::Error &error);
-protected:
+ uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
+ const void *src, uint32_t src_size,
+ lldb_private::Error &error);
+
+ const char *GetKernelVersion();
+
+ // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
+ // const char *
+ // GetImagePath ();
+
+ uint32_t GetVersion();
+
+ uint32_t GetFeatureFlags();
+
+ bool LocalBreakpointsAreSupported() {
+ return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
+ }
+
+ uint32_t GetCPUMask();
+
+ uint32_t GetCPUType();
- bool
- SendRequestPacketNoLock (const PacketStreamType &request_packet);
-
- size_t
- WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response,
- uint32_t timeout_usec);
-
- bool
- WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
-
- void
- MakeRequestPacketHeader (CommandType request_type,
- PacketStreamType &request_packet,
- uint16_t request_length);
-
- //------------------------------------------------------------------
- // Protected Request Packets (use public accessors which will cache
- // results.
- //------------------------------------------------------------------
- bool
- SendRequestVersion ();
-
- bool
- SendRequestHostInfo ();
-
- bool
- SendRequestKernelVersion ();
-
- // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- //bool
- //SendRequestImagePath ();
-
- void
- DumpPacket (lldb_private::Stream &s,
- const void *data,
- uint32_t data_len);
-
- void
- DumpPacket (lldb_private::Stream &s,
- const lldb_private::DataExtractor& extractor);
-
- bool
- VersionIsValid() const
- {
- return m_kdp_version_version != 0;
- }
-
- bool
- HostInfoIsValid() const
- {
- return m_kdp_hostinfo_cpu_type != 0;
- }
-
- bool
- ExtractIsReply (uint8_t first_packet_byte) const
- {
- // TODO: handle big endian...
- return (first_packet_byte & ePacketTypeMask) != 0;
- }
-
- CommandType
- ExtractCommand (uint8_t first_packet_byte) const
- {
- // TODO: handle big endian...
- return (CommandType)(first_packet_byte & eCommandTypeMask);
- }
-
- static const char *
- GetCommandAsCString (uint8_t command);
-
- void
- ClearKDPSettings ();
-
- bool
- SendRequestAndGetReply (const CommandType command,
- const PacketStreamType &request_packet,
- lldb_private::DataExtractor &reply_packet);
- //------------------------------------------------------------------
- // Classes that inherit from CommunicationKDP can see and modify these
- //------------------------------------------------------------------
- uint32_t m_addr_byte_size;
- lldb::ByteOrder m_byte_order;
- uint32_t m_packet_timeout;
- std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
- lldb_private::Predicate<bool> m_is_running;
- uint32_t m_session_key;
- uint8_t m_request_sequence_id;
- uint8_t m_exception_sequence_id;
- uint32_t m_kdp_version_version;
- uint32_t m_kdp_version_feature;
- uint32_t m_kdp_hostinfo_cpu_mask;
- uint32_t m_kdp_hostinfo_cpu_type;
- uint32_t m_kdp_hostinfo_cpu_subtype;
- std::string m_kernel_version;
- //std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
+ uint32_t GetCPUSubtype();
+
+ lldb_private::UUID GetUUID();
+
+ bool RemoteIsEFI();
+
+ bool RemoteIsDarwinKernel();
+
+ lldb::addr_t GetLoadAddress();
+
+ bool SendRequestResume();
+
+ bool SendRequestSuspend();
+
+ bool SendRequestBreakpoint(bool set, lldb::addr_t addr);
+
+protected:
+ bool SendRequestPacketNoLock(const PacketStreamType &request_packet);
+
+ size_t WaitForPacketWithTimeoutMicroSecondsNoLock(
+ lldb_private::DataExtractor &response, uint32_t timeout_usec);
+
+ bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout);
+
+ void MakeRequestPacketHeader(CommandType request_type,
+ PacketStreamType &request_packet,
+ uint16_t request_length);
+
+ //------------------------------------------------------------------
+ // Protected Request Packets (use public accessors which will cache
+ // results.
+ //------------------------------------------------------------------
+ bool SendRequestVersion();
+
+ bool SendRequestHostInfo();
+
+ bool SendRequestKernelVersion();
+
+ // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
+ // bool
+ // SendRequestImagePath ();
+
+ void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len);
+
+ void DumpPacket(lldb_private::Stream &s,
+ const lldb_private::DataExtractor &extractor);
+
+ bool VersionIsValid() const { return m_kdp_version_version != 0; }
+
+ bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
+
+ bool ExtractIsReply(uint8_t first_packet_byte) const {
+ // TODO: handle big endian...
+ return (first_packet_byte & ePacketTypeMask) != 0;
+ }
+
+ CommandType ExtractCommand(uint8_t first_packet_byte) const {
+ // TODO: handle big endian...
+ return (CommandType)(first_packet_byte & eCommandTypeMask);
+ }
+
+ static const char *GetCommandAsCString(uint8_t command);
+
+ void ClearKDPSettings();
+
+ bool SendRequestAndGetReply(const CommandType command,
+ const PacketStreamType &request_packet,
+ lldb_private::DataExtractor &reply_packet);
+ //------------------------------------------------------------------
+ // Classes that inherit from CommunicationKDP can see and modify these
+ //------------------------------------------------------------------
+ uint32_t m_addr_byte_size;
+ lldb::ByteOrder m_byte_order;
+ std::chrono::seconds m_packet_timeout;
+ std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving
+ // packets to a single thread at a time
+ lldb_private::Predicate<bool> m_is_running;
+ uint32_t m_session_key;
+ uint8_t m_request_sequence_id;
+ uint8_t m_exception_sequence_id;
+ uint32_t m_kdp_version_version;
+ uint32_t m_kdp_version_feature;
+ uint32_t m_kdp_hostinfo_cpu_mask;
+ uint32_t m_kdp_hostinfo_cpu_type;
+ uint32_t m_kdp_hostinfo_cpu_subtype;
+ std::string m_kernel_version;
+ // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to
+ // hang the KDP connection...
+ lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
private:
- //------------------------------------------------------------------
- // For CommunicationKDP only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommunicationKDP);
+ //------------------------------------------------------------------
+ // For CommunicationKDP only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommunicationKDP);
};
-#endif // liblldb_CommunicationKDP_h_
+#endif // liblldb_CommunicationKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 898677df616b..dae33f6257d1 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -16,9 +16,9 @@
// Other libraries and framework includes
#include "lldb/Core/Debugger.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
@@ -42,1168 +42,1002 @@
#define USEC_PER_SEC 1000000
// Project includes
+#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
+#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
#include "ProcessKDP.h"
#include "ProcessKDPLog.h"
#include "ThreadKDP.h"
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
-#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
using namespace lldb;
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 }
- };
-
- enum
- {
- ePropertyPacketTimeout
- };
-
- class PluginProperties : public Properties
- {
- public:
-
- static ConstString
- GetSettingName ()
- {
- return ProcessKDP::GetPluginNameStatic();
- }
+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}};
- PluginProperties() :
- Properties ()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual
- ~PluginProperties()
- {
- }
-
- uint64_t
- GetPacketTimeout()
- {
- const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
- }
- };
+enum { ePropertyPacketTimeout };
- typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+class PluginProperties : public Properties {
+public:
+ static ConstString GetSettingName() {
+ return ProcessKDP::GetPluginNameStatic();
+ }
+
+ PluginProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~PluginProperties() {}
+
+ uint64_t GetPacketTimeout() {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ NULL, idx, g_properties[idx].default_uint_value);
+ }
+};
+
+typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+
+static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
+ static ProcessKDPPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new PluginProperties());
+ return g_settings_sp;
+}
- static const ProcessKDPPropertiesSP &
- GetGlobalPluginProperties()
- {
- static ProcessKDPPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new PluginProperties ());
- return g_settings_sp;
- }
-
} // anonymous namespace end
static const lldb::tid_t g_kernel_tid = 1;
-ConstString
-ProcessKDP::GetPluginNameStatic()
-{
- static ConstString g_name("kdp-remote");
- return g_name;
+ConstString ProcessKDP::GetPluginNameStatic() {
+ static ConstString g_name("kdp-remote");
+ return g_name;
}
-const char *
-ProcessKDP::GetPluginDescriptionStatic()
-{
- return "KDP Remote protocol based debugging plug-in for darwin kernel debugging.";
+const char *ProcessKDP::GetPluginDescriptionStatic() {
+ return "KDP Remote protocol based debugging plug-in for darwin kernel "
+ "debugging.";
}
-void
-ProcessKDP::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance);
+void ProcessKDP::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance);
}
-
-lldb::ProcessSP
-ProcessKDP::CreateInstance (TargetSP target_sp,
- ListenerSP listener_sp,
- const FileSpec *crash_file_path)
-{
- lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset(new ProcessKDP (target_sp, listener_sp));
- return process_sp;
+lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file_path) {
+ lldb::ProcessSP process_sp;
+ if (crash_file_path == NULL)
+ process_sp.reset(new ProcessKDP(target_sp, listener_sp));
+ return process_sp;
}
-bool
-ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- Module *exe_module = target_sp->GetExecutableModulePointer();
- if (exe_module)
- {
- const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for iOS, but accept darwin just in case
- case llvm::Triple::MacOSX: // For desktop targets
- case llvm::Triple::IOS: // For arm targets
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- if (triple_ref.getVendor() == llvm::Triple::Apple)
- {
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
- exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
- return true;
- }
- break;
-
- default:
- break;
- }
+bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ return true;
+
+ // For now we are just making sure the file exists for a given module
+ Module *exe_module = target_sp->GetExecutableModulePointer();
+ if (exe_module) {
+ const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for
+ // iOS, but accept darwin just in case
+ case llvm::Triple::MacOSX: // For desktop targets
+ case llvm::Triple::IOS: // For arm targets
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ if (triple_ref.getVendor() == llvm::Triple::Apple) {
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
+ exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
+ return true;
+ }
+ break;
+
+ default:
+ break;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// ProcessKDP constructor
//----------------------------------------------------------------------
-ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp) :
- Process (target_sp, listener_sp),
- m_comm("lldb.process.kdp-remote.communication"),
- m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
- m_dyld_plugin_name (),
- m_kernel_load_addr (LLDB_INVALID_ADDRESS),
- m_command_sp(),
- m_kernel_thread_wp()
-{
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
- const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
- if (timeout_seconds > 0)
- m_comm.SetPacketTimeout(timeout_seconds);
+ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp)
+ : Process(target_sp, listener_sp),
+ m_comm("lldb.process.kdp-remote.communication"),
+ m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"),
+ m_dyld_plugin_name(), m_kernel_load_addr(LLDB_INVALID_ADDRESS),
+ m_command_sp(), m_kernel_thread_wp() {
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
+ "async thread should exit");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
+ "async thread continue");
+ const uint64_t timeout_seconds =
+ GetGlobalPluginProperties()->GetPacketTimeout();
+ if (timeout_seconds > 0)
+ m_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessKDP::~ProcessKDP()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
+ProcessKDP::~ProcessKDP() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-lldb_private::ConstString
-ProcessKDP::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ProcessKDP::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ProcessKDP::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ProcessKDP::GetPluginVersion() { return 1; }
-Error
-ProcessKDP::WillLaunch (Module* module)
-{
- Error error;
- error.SetErrorString ("launching not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::WillLaunch(Module *module) {
+ Error error;
+ error.SetErrorString("launching not supported in kdp-remote plug-in");
+ return error;
}
-Error
-ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid)
-{
- Error error;
- error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::WillAttachToProcessWithID(lldb::pid_t pid) {
+ Error error;
+ error.SetErrorString(
+ "attaching to a by process ID not supported in kdp-remote plug-in");
+ return error;
}
-Error
-ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
-{
- Error error;
- error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) {
+ Error error;
+ error.SetErrorString(
+ "attaching to a by process name not supported in kdp-remote plug-in");
+ return error;
}
-bool
-ProcessKDP::GetHostArchitecture(ArchSpec &arch)
-{
- uint32_t cpu = m_comm.GetCPUType();
- if (cpu)
- {
- uint32_t sub = m_comm.GetCPUSubtype();
- arch.SetArchitecture(eArchTypeMachO, cpu, sub);
- // Leave architecture vendor as unspecified unknown
- arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
- arch.GetTriple().setVendorName(llvm::StringRef());
- return true;
- }
- arch.Clear();
- return false;
+bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) {
+ uint32_t cpu = m_comm.GetCPUType();
+ if (cpu) {
+ uint32_t sub = m_comm.GetCPUSubtype();
+ arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ // Leave architecture vendor as unspecified unknown
+ arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
+ arch.GetTriple().setVendorName(llvm::StringRef());
+ return true;
+ }
+ arch.Clear();
+ return false;
}
-Error
-ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url)
-{
- Error error;
-
- // Don't let any JIT happen when doing KDP as we can't allocate
- // memory and we don't want to be mucking with threads that might
- // already be handling exceptions
- SetCanJIT(false);
+Error ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
+ Error error;
- if (remote_url == NULL || remote_url[0] == '\0')
- {
- error.SetErrorStringWithFormat ("invalid connection URL '%s'", remote_url);
- return error;
- }
+ // Don't let any JIT happen when doing KDP as we can't allocate
+ // memory and we don't want to be mucking with threads that might
+ // already be handling exceptions
+ SetCanJIT(false);
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- if (conn_ap.get())
- {
- // Only try once for now.
- // TODO: check if we should be retrying?
- const uint32_t max_retry_count = 1;
- for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
- {
- if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
- break;
- usleep (100000);
- }
+ if (remote_url.empty()) {
+ error.SetErrorStringWithFormat("empty connection URL");
+ return error;
+ }
+
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ new ConnectionFileDescriptor());
+ if (conn_ap.get()) {
+ // Only try once for now.
+ // TODO: check if we should be retrying?
+ const uint32_t max_retry_count = 1;
+ for (uint32_t retry_count = 0; retry_count < max_retry_count;
+ ++retry_count) {
+ if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
+ break;
+ usleep(100000);
}
-
- if (conn_ap->IsConnected())
- {
- const TCPSocket& socket = static_cast<const TCPSocket&>(*conn_ap->GetReadObject());
- const uint16_t reply_port = socket.GetLocalPortNumber();
-
- if (reply_port != 0)
- {
- m_comm.SetConnection(conn_ap.release());
-
- if (m_comm.SendRequestReattach(reply_port))
- {
- if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
- {
- m_comm.GetVersion();
-
- Target &target = GetTarget();
- ArchSpec kernel_arch;
- // The host architecture
- GetHostArchitecture(kernel_arch);
- ArchSpec target_arch = target.GetArchitecture();
- // Merge in any unspecified stuff into the target architecture in
- // case the target arch isn't set at all or incompletely.
- target_arch.MergeFrom(kernel_arch);
- target.SetArchitecture(target_arch);
-
- /* Get the kernel's UUID and load address via KDP_KERNELVERSION packet. */
- /* An EFI kdp session has neither UUID nor load address. */
-
- UUID kernel_uuid = m_comm.GetUUID ();
- addr_t kernel_load_addr = m_comm.GetLoadAddress ();
-
- if (m_comm.RemoteIsEFI ())
- {
- // Select an invalid plugin name for the dynamic loader so one doesn't get used
- // since EFI does its own manual loading via python scripting
- static ConstString g_none_dynamic_loader("none");
- m_dyld_plugin_name = g_none_dynamic_loader;
-
- if (kernel_uuid.IsValid()) {
- // If EFI passed in a UUID= try to lookup UUID
- // The slide will not be provided. But the UUID
- // lookup will be used to launch EFI debug scripts
- // from the dSYM, that can load all of the symbols.
- ModuleSpec module_spec;
- module_spec.GetUUID() = kernel_uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
-
- // Lookup UUID locally, before attempting dsymForUUID like action
- module_spec.GetSymbolFileSpec() = Symbols::LocateExecutableSymbolFile(module_spec);
- if (module_spec.GetSymbolFileSpec())
- {
- ModuleSpec executable_module_spec = Symbols::LocateExecutableObjectFile (module_spec);
- if (executable_module_spec.GetFileSpec().Exists())
- {
- module_spec.GetFileSpec() = executable_module_spec.GetFileSpec();
- }
- }
- if (!module_spec.GetSymbolFileSpec() || !module_spec.GetSymbolFileSpec())
- Symbols::DownloadObjectAndSymbolFile (module_spec, true);
-
- if (module_spec.GetFileSpec().Exists())
- {
- ModuleSP module_sp(new Module (module_spec));
- if (module_sp.get() && module_sp->GetObjectFile())
- {
- // Get the current target executable
- ModuleSP exe_module_sp (target.GetExecutableModule ());
-
- // 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);
- }
- }
- }
- }
- else if (m_comm.RemoteIsDarwinKernel ())
- {
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- if (kernel_load_addr != LLDB_INVALID_ADDRESS)
- {
- m_kernel_load_addr = kernel_load_addr;
- }
- }
-
- // Set the thread ID
- UpdateThreadListIfNeeded ();
- SetID (1);
- GetThreadList ();
- SetPrivateState (eStateStopped);
- StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
- if (async_strm_sp)
- {
- const char *cstr;
- if ((cstr = m_comm.GetKernelVersion ()) != NULL)
- {
- async_strm_sp->Printf ("Version: %s\n", cstr);
- async_strm_sp->Flush();
- }
-// if ((cstr = m_comm.GetImagePath ()) != NULL)
-// {
-// async_strm_sp->Printf ("Image Path: %s\n", cstr);
-// async_strm_sp->Flush();
-// }
- }
+ }
+
+ if (conn_ap->IsConnected()) {
+ const TCPSocket &socket =
+ static_cast<const TCPSocket &>(*conn_ap->GetReadObject());
+ const uint16_t reply_port = socket.GetLocalPortNumber();
+
+ if (reply_port != 0) {
+ m_comm.SetConnection(conn_ap.release());
+
+ if (m_comm.SendRequestReattach(reply_port)) {
+ if (m_comm.SendRequestConnect(reply_port, reply_port,
+ "Greetings from LLDB...")) {
+ m_comm.GetVersion();
+
+ Target &target = GetTarget();
+ ArchSpec kernel_arch;
+ // The host architecture
+ GetHostArchitecture(kernel_arch);
+ ArchSpec target_arch = target.GetArchitecture();
+ // Merge in any unspecified stuff into the target architecture in
+ // case the target arch isn't set at all or incompletely.
+ target_arch.MergeFrom(kernel_arch);
+ target.SetArchitecture(target_arch);
+
+ /* Get the kernel's UUID and load address via KDP_KERNELVERSION
+ * packet. */
+ /* An EFI kdp session has neither UUID nor load address. */
+
+ UUID kernel_uuid = m_comm.GetUUID();
+ addr_t kernel_load_addr = m_comm.GetLoadAddress();
+
+ if (m_comm.RemoteIsEFI()) {
+ // Select an invalid plugin name for the dynamic loader so one
+ // doesn't get used
+ // since EFI does its own manual loading via python scripting
+ static ConstString g_none_dynamic_loader("none");
+ m_dyld_plugin_name = g_none_dynamic_loader;
+
+ if (kernel_uuid.IsValid()) {
+ // If EFI passed in a UUID= try to lookup UUID
+ // The slide will not be provided. But the UUID
+ // lookup will be used to launch EFI debug scripts
+ // from the dSYM, that can load all of the symbols.
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = kernel_uuid;
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ // Lookup UUID locally, before attempting dsymForUUID like action
+ module_spec.GetSymbolFileSpec() =
+ Symbols::LocateExecutableSymbolFile(module_spec);
+ if (module_spec.GetSymbolFileSpec()) {
+ ModuleSpec executable_module_spec =
+ Symbols::LocateExecutableObjectFile(module_spec);
+ if (executable_module_spec.GetFileSpec().Exists()) {
+ module_spec.GetFileSpec() =
+ executable_module_spec.GetFileSpec();
}
- else
- {
- error.SetErrorString("KDP_REATTACH failed");
+ }
+ if (!module_spec.GetSymbolFileSpec() ||
+ !module_spec.GetSymbolFileSpec())
+ Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+
+ if (module_spec.GetFileSpec().Exists()) {
+ ModuleSP module_sp(new Module(module_spec));
+ if (module_sp.get() && module_sp->GetObjectFile()) {
+ // Get the current target executable
+ ModuleSP exe_module_sp(target.GetExecutableModule());
+
+ // 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);
}
+ }
}
- else
- {
- error.SetErrorString("KDP_REATTACH failed");
+ } else if (m_comm.RemoteIsDarwinKernel()) {
+ m_dyld_plugin_name =
+ DynamicLoaderDarwinKernel::GetPluginNameStatic();
+ if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
+ m_kernel_load_addr = kernel_load_addr;
}
+ }
+
+ // Set the thread ID
+ UpdateThreadListIfNeeded();
+ SetID(1);
+ GetThreadList();
+ SetPrivateState(eStateStopped);
+ StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
+ if (async_strm_sp) {
+ const char *cstr;
+ if ((cstr = m_comm.GetKernelVersion()) != NULL) {
+ async_strm_sp->Printf("Version: %s\n", cstr);
+ async_strm_sp->Flush();
+ }
+ // if ((cstr = m_comm.GetImagePath ()) != NULL)
+ // {
+ // async_strm_sp->Printf ("Image Path:
+ // %s\n", cstr);
+ // async_strm_sp->Flush();
+ // }
+ }
+ } else {
+ error.SetErrorString("KDP_REATTACH failed");
}
- else
- {
- error.SetErrorString("invalid reply port from UDP connection");
- }
- }
- else
- {
- if (error.Success())
- error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
+ } else {
+ error.SetErrorString("KDP_REATTACH failed");
+ }
+ } else {
+ error.SetErrorString("invalid reply port from UDP connection");
}
- if (error.Fail())
- m_comm.Disconnect();
-
- return error;
+ } else {
+ if (error.Success())
+ error.SetErrorStringWithFormat("failed to connect to '%s'",
+ remote_url.str().c_str());
+ }
+ if (error.Fail())
+ m_comm.Disconnect();
+
+ return error;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
-Error
-ProcessKDP::DoLaunch (Module *exe_module,
- ProcessLaunchInfo &launch_info)
-{
- Error error;
- error.SetErrorString ("launching not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) {
+ Error error;
+ error.SetErrorString("launching not supported in kdp-remote plug-in");
+ return error;
}
-Error
-ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info)
-{
- Error error;
- error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging");
- return error;
+Error ProcessKDP::DoAttachToProcessWithID(
+ lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) {
+ Error error;
+ error.SetErrorString(
+ "attach to process by ID is not suppported in kdp remote debugging");
+ return error;
}
-Error
-ProcessKDP::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
-{
- Error error;
- error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging");
- return error;
+Error ProcessKDP::DoAttachToProcessWithName(
+ const char *process_name, const ProcessAttachInfo &attach_info) {
+ Error error;
+ error.SetErrorString(
+ "attach to process by name is not suppported in kdp remote debugging");
+ return error;
}
+void ProcessKDP::DidAttach(ArchSpec &process_arch) {
+ Process::DidAttach(process_arch);
-void
-ProcessKDP::DidAttach (ArchSpec &process_arch)
-{
- Process::DidAttach(process_arch);
-
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessKDP::DidAttach()");
- if (GetID() != LLDB_INVALID_PROCESS_ID)
- {
- GetHostArchitecture(process_arch);
- }
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessKDP::DidAttach()");
+ if (GetID() != LLDB_INVALID_PROCESS_ID) {
+ GetHostArchitecture(process_arch);
+ }
}
-addr_t
-ProcessKDP::GetImageInfoAddress()
-{
- return m_kernel_load_addr;
-}
+addr_t ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr; }
-lldb_private::DynamicLoader *
-ProcessKDP::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
- return m_dyld_ap.get();
+lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(
+ this,
+ m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
+ return m_dyld_ap.get();
}
-Error
-ProcessKDP::WillResume ()
-{
- return Error();
-}
+Error ProcessKDP::WillResume() { return Error(); }
-Error
-ProcessKDP::DoResume ()
-{
- Error error;
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
- // Only start the async thread if we try to do any process control
- if (!m_async_thread.IsJoinable())
- StartAsyncThread();
-
- bool resume = false;
-
- // With KDP there is only one thread we can tell what to do
- ThreadSP kernel_thread_sp (m_thread_list.FindThreadByProtocolID(g_kernel_tid));
-
- if (kernel_thread_sp)
- {
- const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState();
-
- if (log)
- log->Printf ("ProcessKDP::DoResume() thread_resume_state = %s", StateAsCString(thread_resume_state));
- switch (thread_resume_state)
- {
- case eStateSuspended:
- // Nothing to do here when a thread will stay suspended
- // we just leave the CPU mask bit set to zero for the thread
- if (log)
- log->Printf ("ProcessKDP::DoResume() = suspended???");
- break;
-
- case eStateStepping:
- {
- lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
-
- if (reg_ctx_sp)
- {
- if (log)
- log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
- reg_ctx_sp->HardwareSingleStep (true);
- resume = true;
- }
- else
- {
- error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
- }
- }
- break;
-
- case eStateRunning:
- {
- lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
-
- if (reg_ctx_sp)
- {
- if (log)
- log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (false);");
- reg_ctx_sp->HardwareSingleStep (false);
- resume = true;
- }
- else
- {
- error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
- }
- }
- break;
+Error ProcessKDP::DoResume() {
+ Error error;
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ // Only start the async thread if we try to do any process control
+ if (!m_async_thread.IsJoinable())
+ StartAsyncThread();
- default:
- // The only valid thread resume states are listed above
- assert (!"invalid thread resume state");
- break;
- }
- }
+ bool resume = false;
+
+ // With KDP there is only one thread we can tell what to do
+ ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));
+
+ if (kernel_thread_sp) {
+ const StateType thread_resume_state =
+ kernel_thread_sp->GetTemporaryResumeState();
- if (resume)
- {
+ if (log)
+ log->Printf("ProcessKDP::DoResume() thread_resume_state = %s",
+ StateAsCString(thread_resume_state));
+ switch (thread_resume_state) {
+ case eStateSuspended:
+ // Nothing to do here when a thread will stay suspended
+ // we just leave the CPU mask bit set to zero for the thread
+ if (log)
+ log->Printf("ProcessKDP::DoResume() = suspended???");
+ break;
+
+ case eStateStepping: {
+ lldb::RegisterContextSP reg_ctx_sp(
+ kernel_thread_sp->GetRegisterContext());
+
+ if (reg_ctx_sp) {
if (log)
- log->Printf ("ProcessKDP::DoResume () sending resume");
-
- if (m_comm.SendRequestResume ())
- {
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue);
- SetPrivateState(eStateRunning);
- }
- else
- error.SetErrorString ("KDP resume failed");
- }
- else
- {
- error.SetErrorString ("kernel thread is suspended");
+ log->Printf(
+ "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
+ reg_ctx_sp->HardwareSingleStep(true);
+ resume = true;
+ } else {
+ error.SetErrorStringWithFormat(
+ "KDP thread 0x%llx has no register context",
+ kernel_thread_sp->GetID());
+ }
+ } break;
+
+ case eStateRunning: {
+ lldb::RegisterContextSP reg_ctx_sp(
+ kernel_thread_sp->GetRegisterContext());
+
+ if (reg_ctx_sp) {
+ if (log)
+ log->Printf("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
+ "(false);");
+ reg_ctx_sp->HardwareSingleStep(false);
+ resume = true;
+ } else {
+ error.SetErrorStringWithFormat(
+ "KDP thread 0x%llx has no register context",
+ kernel_thread_sp->GetID());
+ }
+ } break;
+
+ default:
+ // The only valid thread resume states are listed above
+ assert(!"invalid thread resume state");
+ break;
}
-
- return error;
-}
+ }
-lldb::ThreadSP
-ProcessKDP::GetKernelThread()
-{
- // KDP only tells us about one thread/core. Any other threads will usually
- // be the ones that are read from memory by the OS plug-ins.
-
- ThreadSP thread_sp (m_kernel_thread_wp.lock());
- if (!thread_sp)
- {
- thread_sp.reset(new ThreadKDP (*this, g_kernel_tid));
- m_kernel_thread_wp = thread_sp;
- }
- return thread_sp;
+ if (resume) {
+ if (log)
+ log->Printf("ProcessKDP::DoResume () sending resume");
+
+ if (m_comm.SendRequestResume()) {
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
+ SetPrivateState(eStateRunning);
+ } else
+ error.SetErrorString("KDP resume failed");
+ } else {
+ error.SetErrorString("kernel thread is suspended");
+ }
+
+ return error;
}
+lldb::ThreadSP ProcessKDP::GetKernelThread() {
+ // KDP only tells us about one thread/core. Any other threads will usually
+ // be the ones that are read from memory by the OS plug-ins.
+ ThreadSP thread_sp(m_kernel_thread_wp.lock());
+ if (!thread_sp) {
+ thread_sp.reset(new ThreadKDP(*this, g_kernel_tid));
+ m_kernel_thread_wp = thread_sp;
+ }
+ return thread_sp;
+}
-
-bool
-ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- // locker will keep a mutex locked until it goes out of scope
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
- if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
- log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- // Even though there is a CPU mask, it doesn't mean we can see each CPU
- // individually, there is really only one. Lets call this thread 1.
- ThreadSP thread_sp (old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
- if (!thread_sp)
- thread_sp = GetKernelThread ();
- new_thread_list.AddThread(thread_sp);
-
- return new_thread_list.GetSize(false) > 0;
+bool ProcessKDP::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // locker will keep a mutex locked until it goes out of scope
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD));
+ if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
+ log->Printf("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
+
+ // Even though there is a CPU mask, it doesn't mean we can see each CPU
+ // individually, there is really only one. Lets call this thread 1.
+ ThreadSP thread_sp(
+ old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
+ if (!thread_sp)
+ thread_sp = GetKernelThread();
+ new_thread_list.AddThread(thread_sp);
+
+ return new_thread_list.GetSize(false) > 0;
}
-void
-ProcessKDP::RefreshStateAfterStop ()
-{
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
+void ProcessKDP::RefreshStateAfterStop() {
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list.RefreshStateAfterStop();
}
-Error
-ProcessKDP::DoHalt (bool &caused_stop)
-{
- Error error;
-
- if (m_comm.IsRunning())
- {
- if (m_destroy_in_process)
- {
- // If we are attemping to destroy, we need to not return an error to
- // Halt or DoDestroy won't get called.
- // We are also currently running, so send a process stopped event
- SetPrivateState (eStateStopped);
- }
- else
- {
- error.SetErrorString ("KDP cannot interrupt a running kernel");
- }
+Error ProcessKDP::DoHalt(bool &caused_stop) {
+ Error error;
+
+ if (m_comm.IsRunning()) {
+ if (m_destroy_in_process) {
+ // If we are attemping to destroy, we need to not return an error to
+ // Halt or DoDestroy won't get called.
+ // We are also currently running, so send a process stopped event
+ SetPrivateState(eStateStopped);
+ } else {
+ error.SetErrorString("KDP cannot interrupt a running kernel");
}
- return error;
+ }
+ return error;
}
-Error
-ProcessKDP::DoDetach(bool keep_stopped)
-{
- Error error;
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
-
- if (m_comm.IsRunning())
- {
- // We are running and we can't interrupt a running kernel, so we need
- // to just close the connection to the kernel and hope for the best
- }
- else
- {
- // If we are going to keep the target stopped, then don't send the disconnect message.
- if (!keep_stopped && m_comm.IsConnected())
- {
- const bool success = m_comm.SendRequestDisconnect();
- if (log)
- {
- if (success)
- log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
- else
- log->PutCString ("ProcessKDP::DoDetach() connection channel shutdown failed");
- }
- m_comm.Disconnect ();
- }
+Error ProcessKDP::DoDetach(bool keep_stopped) {
+ Error error;
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
+
+ if (m_comm.IsRunning()) {
+ // We are running and we can't interrupt a running kernel, so we need
+ // to just close the connection to the kernel and hope for the best
+ } else {
+ // If we are going to keep the target stopped, then don't send the
+ // disconnect message.
+ if (!keep_stopped && m_comm.IsConnected()) {
+ const bool success = m_comm.SendRequestDisconnect();
+ if (log) {
+ if (success)
+ log->PutCString(
+ "ProcessKDP::DoDetach() detach packet sent successfully");
+ else
+ log->PutCString(
+ "ProcessKDP::DoDetach() connection channel shutdown failed");
+ }
+ m_comm.Disconnect();
}
- StopAsyncThread ();
- m_comm.Clear();
-
- SetPrivateState (eStateDetached);
- ResumePrivateStateThread();
-
- //KillDebugserverProcess ();
- return error;
+ }
+ StopAsyncThread();
+ m_comm.Clear();
+
+ SetPrivateState(eStateDetached);
+ ResumePrivateStateThread();
+
+ // KillDebugserverProcess ();
+ return error;
}
-Error
-ProcessKDP::DoDestroy ()
-{
- // For KDP there really is no difference between destroy and detach
- bool keep_stopped = false;
- return DoDetach(keep_stopped);
+Error ProcessKDP::DoDestroy() {
+ // For KDP there really is no difference between destroy and detach
+ bool keep_stopped = false;
+ return DoDetach(keep_stopped);
}
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessKDP::IsAlive ()
-{
- return m_comm.IsConnected() && Process::IsAlive();
+bool ProcessKDP::IsAlive() {
+ return m_comm.IsConnected() && Process::IsAlive();
}
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- uint8_t *data_buffer = (uint8_t *) buf;
- if (m_comm.IsConnected())
- {
- const size_t max_read_size = 512;
- size_t total_bytes_read = 0;
-
- // Read the requested amount of memory in 512 byte chunks
- while (total_bytes_read < size)
- {
- size_t bytes_to_read_this_request = size - total_bytes_read;
- if (bytes_to_read_this_request > max_read_size)
- {
- bytes_to_read_this_request = max_read_size;
- }
- size_t bytes_read = m_comm.SendRequestReadMemory (addr + total_bytes_read,
- data_buffer + total_bytes_read,
- bytes_to_read_this_request, error);
- total_bytes_read += bytes_read;
- if (error.Fail() || bytes_read == 0)
- {
- return total_bytes_read;
- }
- }
-
+size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ uint8_t *data_buffer = (uint8_t *)buf;
+ if (m_comm.IsConnected()) {
+ const size_t max_read_size = 512;
+ size_t total_bytes_read = 0;
+
+ // Read the requested amount of memory in 512 byte chunks
+ while (total_bytes_read < size) {
+ size_t bytes_to_read_this_request = size - total_bytes_read;
+ if (bytes_to_read_this_request > max_read_size) {
+ bytes_to_read_this_request = max_read_size;
+ }
+ size_t bytes_read = m_comm.SendRequestReadMemory(
+ addr + total_bytes_read, data_buffer + total_bytes_read,
+ bytes_to_read_this_request, error);
+ total_bytes_read += bytes_read;
+ if (error.Fail() || bytes_read == 0) {
return total_bytes_read;
+ }
}
- error.SetErrorString ("not connected");
- return 0;
-}
-size_t
-ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
-{
- if (m_comm.IsConnected())
- return m_comm.SendRequestWriteMemory (addr, buf, size, error);
- error.SetErrorString ("not connected");
- return 0;
+ return total_bytes_read;
+ }
+ error.SetErrorString("not connected");
+ return 0;
}
-lldb::addr_t
-ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
-{
- error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
- return LLDB_INVALID_ADDRESS;
+size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
+ Error &error) {
+ if (m_comm.IsConnected())
+ return m_comm.SendRequestWriteMemory(addr, buf, size, error);
+ error.SetErrorString("not connected");
+ return 0;
}
-Error
-ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
-{
- Error error;
- error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
- return error;
+lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
+ Error &error) {
+ error.SetErrorString(
+ "memory allocation not suppported in kdp remote debugging");
+ return LLDB_INVALID_ADDRESS;
}
-Error
-ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site)
-{
- if (m_comm.LocalBreakpointsAreSupported ())
- {
- Error error;
- if (!bp_site->IsEnabled())
- {
- if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress()))
- {
- bp_site->SetEnabled(true);
- bp_site->SetType (BreakpointSite::eExternal);
- }
- else
- {
- error.SetErrorString ("KDP set breakpoint failed");
- }
- }
- return error;
- }
- return EnableSoftwareBreakpoint (bp_site);
+Error ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ error.SetErrorString(
+ "memory deallocation not suppported in kdp remote debugging");
+ return error;
}
-Error
-ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site)
-{
- if (m_comm.LocalBreakpointsAreSupported ())
- {
- Error error;
- if (bp_site->IsEnabled())
- {
- BreakpointSite::Type bp_type = bp_site->GetType();
- if (bp_type == BreakpointSite::eExternal)
- {
- if (m_destroy_in_process && m_comm.IsRunning())
- {
- // We are trying to destroy our connection and we are running
- bp_site->SetEnabled(false);
- }
- else
- {
- if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
- bp_site->SetEnabled(false);
- else
- error.SetErrorString ("KDP remove breakpoint failed");
- }
- }
- else
- {
- error = DisableSoftwareBreakpoint (bp_site);
- }
- }
- return error;
+Error ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {
+ if (m_comm.LocalBreakpointsAreSupported()) {
+ Error error;
+ if (!bp_site->IsEnabled()) {
+ if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
+ bp_site->SetEnabled(true);
+ bp_site->SetType(BreakpointSite::eExternal);
+ } else {
+ error.SetErrorString("KDP set breakpoint failed");
+ }
}
- return DisableSoftwareBreakpoint (bp_site);
+ return error;
+ }
+ return EnableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessKDP::EnableWatchpoint (Watchpoint *wp, bool notify)
-{
+Error ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
+ if (m_comm.LocalBreakpointsAreSupported()) {
Error error;
- error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
+ if (bp_site->IsEnabled()) {
+ BreakpointSite::Type bp_type = bp_site->GetType();
+ if (bp_type == BreakpointSite::eExternal) {
+ if (m_destroy_in_process && m_comm.IsRunning()) {
+ // We are trying to destroy our connection and we are running
+ bp_site->SetEnabled(false);
+ } else {
+ if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
+ bp_site->SetEnabled(false);
+ else
+ error.SetErrorString("KDP remove breakpoint failed");
+ }
+ } else {
+ error = DisableSoftwareBreakpoint(bp_site);
+ }
+ }
return error;
+ }
+ return DisableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessKDP::DisableWatchpoint (Watchpoint *wp, bool notify)
-{
- Error error;
- error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
- return error;
+Error ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ error.SetErrorString(
+ "watchpoints are not suppported in kdp remote debugging");
+ return error;
}
-void
-ProcessKDP::Clear()
-{
- m_thread_list.Clear();
+Error ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ error.SetErrorString(
+ "watchpoints are not suppported in kdp remote debugging");
+ return error;
}
-Error
-ProcessKDP::DoSignal (int signo)
-{
- Error error;
- error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
- return error;
+void ProcessKDP::Clear() { m_thread_list.Clear(); }
+
+Error ProcessKDP::DoSignal(int signo) {
+ Error error;
+ error.SetErrorString(
+ "sending signals is not suppported in kdp remote debugging");
+ return error;
}
-void
-ProcessKDP::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
-
- Log::Callbacks log_callbacks = {
- ProcessKDPLog::DisableLog,
- ProcessKDPLog::EnableLog,
- ProcessKDPLog::ListLogCategories
- };
-
- Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
- });
+void ProcessKDP::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+
+ Log::Callbacks log_callbacks = {ProcessKDPLog::DisableLog,
+ ProcessKDPLog::EnableLog,
+ ProcessKDPLog::ListLogCategories};
+
+ Log::RegisterLogChannel(ProcessKDP::GetPluginNameStatic(), log_callbacks);
+ });
}
-void
-ProcessKDP::DebuggerInitialize (lldb_private::Debugger &debugger)
-{
- if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForProcessPlugin (debugger,
- GetGlobalPluginProperties()->GetValueProperties(),
- ConstString ("Properties for the kdp-remote process plug-in."),
- is_global_setting);
- }
+void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) {
+ if (!PluginManager::GetSettingForProcessPlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForProcessPlugin(
+ debugger, GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString("Properties for the kdp-remote process plug-in."),
+ is_global_setting);
+ }
}
-bool
-ProcessKDP::StartAsyncThread ()
-{
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-
- if (log)
- log->Printf ("ProcessKDP::StartAsyncThread ()");
+bool ProcessKDP::StartAsyncThread() {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- if (m_async_thread.IsJoinable())
- return true;
+ if (log)
+ log->Printf("ProcessKDP::StartAsyncThread ()");
- m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
- return m_async_thread.IsJoinable();
-}
+ if (m_async_thread.IsJoinable())
+ return true;
-void
-ProcessKDP::StopAsyncThread ()
-{
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-
- if (log)
- log->Printf ("ProcessKDP::StopAsyncThread ()");
-
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
-
- // Stop the stdio thread
- if (m_async_thread.IsJoinable())
- m_async_thread.Join(nullptr);
+ m_async_thread = ThreadLauncher::LaunchThread(
+ "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
+ return m_async_thread.IsJoinable();
}
+void ProcessKDP::StopAsyncThread() {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-void *
-ProcessKDP::AsyncThread (void *arg)
-{
- ProcessKDP *process = (ProcessKDP*) arg;
-
- const lldb::pid_t pid = process->GetID();
+ if (log)
+ log->Printf("ProcessKDP::StopAsyncThread ()");
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
-
- ListenerSP listener_sp (Listener::MakeListener("ProcessKDP::AsyncThread"));
- EventSP event_sp;
- const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
- eBroadcastBitAsyncThreadShouldExit;
-
-
- if (listener_sp->StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
- {
- bool done = false;
- while (!done)
- {
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...",
- pid);
- if (listener_sp->WaitForEvent (NULL, event_sp))
- {
- uint32_t event_type = event_sp->GetType();
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") Got an event of type: %d...",
- pid,
- event_type);
-
- // When we are running, poll for 1 second to try and get an exception
- // to indicate the process has stopped. If we don't get one, check to
- // make sure no one asked us to exit
- bool is_running = false;
- DataExtractor exc_reply_packet;
- do
- {
- switch (event_type)
- {
- case eBroadcastBitAsyncContinue:
- {
- is_running = true;
- if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC))
- {
- ThreadSP thread_sp (process->GetKernelThread());
- if (thread_sp)
- {
- lldb::RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
- if (reg_ctx_sp)
- reg_ctx_sp->InvalidateAllRegisters();
- static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet);
- }
-
- // TODO: parse the stop reply packet
- is_running = false;
- process->SetPrivateState(eStateStopped);
- }
- else
- {
- // Check to see if we are supposed to exit. There is no way to
- // interrupt a running kernel, so all we can do is wait for an
- // exception or detach...
- if (listener_sp->GetNextEvent(event_sp))
- {
- // We got an event, go through the loop again
- event_type = event_sp->GetType();
- }
- }
- }
- break;
-
- case eBroadcastBitAsyncThreadShouldExit:
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...",
- pid);
- done = true;
- is_running = false;
- break;
-
- default:
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got unknown event 0x%8.8x",
- pid,
- event_type);
- done = true;
- is_running = false;
- break;
- }
- } while (is_running);
- }
- else
- {
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false",
- pid);
- done = true;
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
+
+ // Stop the stdio thread
+ if (m_async_thread.IsJoinable())
+ m_async_thread.Join(nullptr);
+}
+
+void *ProcessKDP::AsyncThread(void *arg) {
+ ProcessKDP *process = (ProcessKDP *)arg;
+
+ const lldb::pid_t pid = process->GetID();
+
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
+ ") thread starting...",
+ arg, pid);
+
+ ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
+ EventSP event_sp;
+ const uint32_t desired_event_mask =
+ eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
+
+ if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster,
+ desired_event_mask) ==
+ desired_event_mask) {
+ bool done = false;
+ while (!done) {
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp)...",
+ pid);
+ if (listener_sp->GetEvent(event_sp, llvm::None)) {
+ uint32_t event_type = event_sp->GetType();
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") Got an event of type: %d...",
+ pid, event_type);
+
+ // When we are running, poll for 1 second to try and get an exception
+ // to indicate the process has stopped. If we don't get one, check to
+ // make sure no one asked us to exit
+ bool is_running = false;
+ DataExtractor exc_reply_packet;
+ do {
+ switch (event_type) {
+ case eBroadcastBitAsyncContinue: {
+ is_running = true;
+ if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds(
+ exc_reply_packet, 1 * USEC_PER_SEC)) {
+ ThreadSP thread_sp(process->GetKernelThread());
+ if (thread_sp) {
+ lldb::RegisterContextSP reg_ctx_sp(
+ thread_sp->GetRegisterContext());
+ if (reg_ctx_sp)
+ reg_ctx_sp->InvalidateAllRegisters();
+ static_cast<ThreadKDP *>(thread_sp.get())
+ ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
+ }
+
+ // TODO: parse the stop reply packet
+ is_running = false;
+ process->SetPrivateState(eStateStopped);
+ } else {
+ // Check to see if we are supposed to exit. There is no way to
+ // interrupt a running kernel, so all we can do is wait for an
+ // exception or detach...
+ if (listener_sp->GetEvent(event_sp,
+ std::chrono::microseconds(0))) {
+ // We got an event, go through the loop again
+ event_type = event_sp->GetType();
+ }
}
- }
+ } break;
+
+ case eBroadcastBitAsyncThreadShouldExit:
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") got eBroadcastBitAsyncThreadShouldExit...",
+ pid);
+ done = true;
+ is_running = false;
+ break;
+
+ default:
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ pid, event_type);
+ done = true;
+ is_running = false;
+ break;
+ }
+ } while (is_running);
+ } else {
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp) => false",
+ pid);
+ done = true;
+ }
}
-
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread exiting...",
- arg,
- pid);
+ }
- process->m_async_thread.Reset();
- return NULL;
-}
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
+ ") thread exiting...",
+ arg, pid);
+ process->m_async_thread.Reset();
+ return NULL;
+}
-class CommandObjectProcessKDPPacketSend : public CommandObjectParsed
-{
+class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {
private:
-
- OptionGroupOptions m_option_group;
- OptionGroupUInt64 m_command_byte;
- OptionGroupString m_packet_data;
-
- virtual Options *
- GetOptions ()
- {
- return &m_option_group;
- }
-
+ OptionGroupOptions m_option_group;
+ OptionGroupUInt64 m_command_byte;
+ OptionGroupString m_packet_data;
+
+ virtual Options *GetOptions() { return &m_option_group; }
public:
- CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet send",
- "Send a custom packet through the KDP protocol by specifying the command byte and the packet payload data. A packet will be sent with a correct header and payload, and the raw result bytes will be displayed as a string value. ",
- NULL),
- m_option_group (interpreter),
- m_command_byte(LLDB_OPT_SET_1, true , "command", 'c', 0, eArgTypeNone, "Specify the command byte to use when sending the KDP request packet.", 0),
- m_packet_data (LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone, "Specify packet payload bytes as a hex ASCII string with no spaces or hex prefixes.", NULL)
- {
- m_option_group.Append (&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_packet_data , LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectProcessKDPPacketSend ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result)
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- if (!m_command_byte.GetOptionValue().OptionWasSet())
- {
- result.AppendError ("the --command option must be set to a valid command byte");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0);
- if (command_byte > 0 && command_byte <= UINT8_MAX)
- {
- ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- const StateType state = process->GetState();
-
- if (StateIsStoppedState (state, true))
- {
- std::vector<uint8_t> payload_bytes;
- const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue();
- if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0])
- {
- StringExtractor extractor(ascii_hex_bytes_cstr);
- const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size();
- if (ascii_hex_bytes_cstr_len & 1)
- {
- result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- payload_bytes.resize(ascii_hex_bytes_cstr_len/2);
- if (extractor.GetHexBytes(&payload_bytes[0], payload_bytes.size(), '\xdd') != payload_bytes.size())
- {
- result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- Error error;
- DataExtractor reply;
- process->GetCommunication().SendRawRequest (command_byte,
- payload_bytes.empty() ? NULL : payload_bytes.data(),
- payload_bytes.size(),
- reply,
- error);
-
- if (error.Success())
- {
- // Copy the binary bytes into a hex ASCII string for the result
- StreamString packet;
- packet.PutBytesAsRawHex8(reply.GetDataStart(),
- reply.GetByteSize(),
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
- result.AppendMessage(packet.GetString().c_str());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- else
- {
- const char *error_cstr = error.AsCString();
- if (error_cstr && error_cstr[0])
- result.AppendError (error_cstr);
- else
- result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state));
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("invalid process");
- result.SetStatus (eReturnStatusFailed);
- }
+ CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet send",
+ "Send a custom packet through the KDP protocol by "
+ "specifying the command byte and the packet "
+ "payload data. A packet will be sent with a "
+ "correct header and payload, and the raw result "
+ "bytes will be displayed as a string value. ",
+ NULL),
+ m_option_group(),
+ m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
+ "Specify the command byte to use when sending the KDP "
+ "request packet.",
+ 0),
+ m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
+ "Specify packet payload bytes as a hex ASCII string with "
+ "no spaces or hex prefixes.",
+ NULL) {
+ m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectProcessKDPPacketSend() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ if (!m_command_byte.GetOptionValue().OptionWasSet()) {
+ result.AppendError(
+ "the --command option must be set to a valid command byte");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ const uint64_t command_byte =
+ m_command_byte.GetOptionValue().GetUInt64Value(0);
+ if (command_byte > 0 && command_byte <= UINT8_MAX) {
+ ProcessKDP *process =
+ (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ const StateType state = process->GetState();
+
+ if (StateIsStoppedState(state, true)) {
+ std::vector<uint8_t> payload_bytes;
+ const char *ascii_hex_bytes_cstr =
+ m_packet_data.GetOptionValue().GetCurrentValue();
+ if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
+ StringExtractor extractor(ascii_hex_bytes_cstr);
+ const size_t ascii_hex_bytes_cstr_len =
+ extractor.GetStringRef().size();
+ if (ascii_hex_bytes_cstr_len & 1) {
+ result.AppendErrorWithFormat("payload data must contain an "
+ "even number of ASCII hex "
+ "characters: '%s'",
+ ascii_hex_bytes_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte);
- result.SetStatus (eReturnStatusFailed);
+ payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
+ if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
+ payload_bytes.size()) {
+ result.AppendErrorWithFormat("payload data must only contain "
+ "ASCII hex characters (no "
+ "spaces or hex prefixes): '%s'",
+ ascii_hex_bytes_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
+ Error error;
+ DataExtractor reply;
+ process->GetCommunication().SendRawRequest(
+ command_byte,
+ payload_bytes.empty() ? NULL : payload_bytes.data(),
+ payload_bytes.size(), reply, error);
+
+ if (error.Success()) {
+ // Copy the binary bytes into a hex ASCII string for the result
+ StreamString packet;
+ packet.PutBytesAsRawHex8(
+ reply.GetDataStart(), reply.GetByteSize(),
+ endian::InlHostByteOrder(), endian::InlHostByteOrder());
+ result.AppendMessage(packet.GetString());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ } else {
+ const char *error_cstr = error.AsCString();
+ if (error_cstr && error_cstr[0])
+ result.AppendError(error_cstr);
+ else
+ result.AppendErrorWithFormat("unknown error 0x%8.8x",
+ error.GetError());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ result.AppendErrorWithFormat("process must be stopped in order "
+ "to send KDP packets, state is %s",
+ StateAsCString(state));
+ result.SetStatus(eReturnStatusFailed);
}
+ } else {
+ result.AppendError("invalid process");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
+ ", valid values are 1 - 255",
+ command_byte);
+ result.SetStatus(eReturnStatusFailed);
}
- else
- {
- result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- return false;
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments, only options.",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
}
+ return false;
+ }
};
-class CommandObjectProcessKDPPacket : public CommandObjectMultiword
-{
+class CommandObjectProcessKDPPacket : public CommandObjectMultiword {
private:
-
public:
- CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "process plugin packet",
- "Commands that deal with KDP remote packets.",
- NULL)
- {
- LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessKDPPacketSend (interpreter)));
- }
-
- ~CommandObjectProcessKDPPacket ()
- {
- }
+ CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process plugin packet",
+ "Commands that deal with KDP remote packets.",
+ NULL) {
+ LoadSubCommand(
+ "send",
+ CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));
+ }
+
+ ~CommandObjectProcessKDPPacket() {}
};
-class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword
-{
+class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {
public:
- CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessKDP process.",
- "process plugin <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket (interpreter)));
- }
-
- ~CommandObjectMultiwordProcessKDP ()
- {
- }
+ CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "process plugin",
+ "Commands for operating on a ProcessKDP process.",
+ "process plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(
+ interpreter)));
+ }
+
+ ~CommandObjectMultiwordProcessKDP() {}
};
-CommandObject *
-ProcessKDP::GetPluginCommandObject()
-{
- if (!m_command_sp)
- m_command_sp.reset (new CommandObjectMultiwordProcessKDP (GetTarget().GetDebugger().GetCommandInterpreter()));
- return m_command_sp.get();
+CommandObject *ProcessKDP::GetPluginCommandObject() {
+ if (!m_command_sp)
+ m_command_sp.reset(new CommandObjectMultiwordProcessKDP(
+ GetTarget().GetDebugger().GetCommandInterpreter()));
+ return m_command_sp.get();
}
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 49f636242510..fa5d2bd27feb 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -32,243 +32,192 @@
class ThreadKDP;
-class ProcessKDP : public lldb_private::Process
-{
+class ProcessKDP : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
-
- static void
- Initialize();
-
- static void
- DebuggerInitialize (lldb_private::Debugger &debugger);
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
-
- virtual
- ~ProcessKDP();
-
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- virtual bool
- CanDebug (lldb::TargetSP target_sp,
- bool plugin_specified_by_name);
-
- virtual lldb_private::CommandObject *
- GetPluginCommandObject();
-
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- virtual lldb_private::Error
- WillLaunch (lldb_private::Module* module);
-
- virtual lldb_private::Error
- DoLaunch (lldb_private::Module *exe_module,
- lldb_private::ProcessLaunchInfo &launch_info);
-
- virtual lldb_private::Error
- WillAttachToProcessWithID (lldb::pid_t pid);
-
- virtual lldb_private::Error
- WillAttachToProcessWithName (const char *process_name, bool wait_for_launch);
-
- virtual lldb_private::Error
- DoConnectRemote (lldb_private::Stream *strm, const char *remote_url);
-
- virtual lldb_private::Error
- DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info);
-
- virtual lldb_private::Error
- DoAttachToProcessWithName (const char *process_name, const lldb_private::ProcessAttachInfo &attach_info);
-
- virtual void
- DidAttach (lldb_private::ArchSpec &process_arch);
-
- lldb::addr_t
- GetImageInfoAddress();
-
- lldb_private::DynamicLoader *
- GetDynamicLoader ();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual lldb_private::ConstString
- GetPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- virtual lldb_private::Error
- WillResume ();
-
- virtual lldb_private::Error
- DoResume ();
-
- virtual lldb_private::Error
- DoHalt (bool &caused_stop);
-
- virtual lldb_private::Error
- DoDetach (bool keep_stopped);
-
- virtual lldb_private::Error
- DoSignal (int signal);
-
- virtual lldb_private::Error
- DoDestroy ();
-
- virtual void
- RefreshStateAfterStop();
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- virtual bool
- IsAlive ();
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- virtual size_t
- DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
-
- virtual size_t
- DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error);
-
- virtual lldb::addr_t
- DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error);
-
- virtual lldb_private::Error
- DoDeallocateMemory (lldb::addr_t ptr);
-
- //----------------------------------------------------------------------
- // Process Breakpoints
- //----------------------------------------------------------------------
- virtual lldb_private::Error
- EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
-
- virtual lldb_private::Error
- DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
-
- //----------------------------------------------------------------------
- // Process Watchpoints
- //----------------------------------------------------------------------
- virtual lldb_private::Error
- EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
-
- virtual lldb_private::Error
- DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
-
- CommunicationKDP &
- GetCommunication()
- {
- return m_comm;
- }
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec *crash_file_path);
+
+ static void Initialize();
+
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
+
+ ~ProcessKDP() override;
+
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+ lldb_private::CommandObject *GetPluginCommandObject() override;
+
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ lldb_private::Error WillLaunch(lldb_private::Module *module) override;
+
+ lldb_private::Error
+ DoLaunch(lldb_private::Module *exe_module,
+ lldb_private::ProcessLaunchInfo &launch_info) override;
+
+ lldb_private::Error WillAttachToProcessWithID(lldb::pid_t pid) override;
+
+ lldb_private::Error
+ WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) override;
+
+ lldb_private::Error DoConnectRemote(lldb_private::Stream *strm,
+ llvm::StringRef remote_url) override;
+
+ lldb_private::Error DoAttachToProcessWithID(
+ lldb::pid_t pid,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
+
+ lldb_private::Error DoAttachToProcessWithName(
+ const char *process_name,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
+
+ void DidAttach(lldb_private::ArchSpec &process_arch) override;
+
+ lldb::addr_t GetImageInfoAddress() override;
+
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ lldb_private::Error WillResume() override;
+
+ lldb_private::Error DoResume() override;
+
+ lldb_private::Error DoHalt(bool &caused_stop) override;
+
+ lldb_private::Error DoDetach(bool keep_stopped) override;
+
+ lldb_private::Error DoSignal(int signal) override;
+
+ lldb_private::Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
+
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
+
+ size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ lldb_private::Error &error) override;
+
+ lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+ lldb_private::Error &error) override;
+
+ lldb_private::Error DoDeallocateMemory(lldb::addr_t ptr) override;
+
+ //----------------------------------------------------------------------
+ // Process Breakpoints
+ //----------------------------------------------------------------------
+ lldb_private::Error
+ EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+
+ lldb_private::Error
+ DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+
+ //----------------------------------------------------------------------
+ // Process Watchpoints
+ //----------------------------------------------------------------------
+ lldb_private::Error EnableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
+
+ lldb_private::Error DisableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
+
+ CommunicationKDP &GetCommunication() { return m_comm; }
protected:
- friend class ThreadKDP;
- friend class CommunicationKDP;
-
- //----------------------------------------------------------------------
- // Accessors
- //----------------------------------------------------------------------
- bool
- IsRunning ( lldb::StateType state )
- {
- return state == lldb::eStateRunning || IsStepping(state);
- }
-
- bool
- IsStepping ( lldb::StateType state)
- {
- return state == lldb::eStateStepping;
- }
-
- bool
- CanResume ( lldb::StateType state)
- {
- return state == lldb::eStateStopped;
- }
-
- bool
- HasExited (lldb::StateType state)
- {
- return state == lldb::eStateExited;
- }
-
- bool
- GetHostArchitecture (lldb_private::ArchSpec &arch);
-
- bool
- ProcessIDIsValid ( ) const;
-
- void
- Clear ( );
-
- virtual bool
- UpdateThreadList (lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list);
-
- enum
- {
- eBroadcastBitAsyncContinue = (1 << 0),
- eBroadcastBitAsyncThreadShouldExit = (1 << 1)
- };
-
- lldb::ThreadSP
- GetKernelThread ();
-
- //------------------------------------------------------------------
- /// Broadcaster event bits definitions.
- //------------------------------------------------------------------
- CommunicationKDP m_comm;
- lldb_private::Broadcaster m_async_broadcaster;
- lldb_private::HostThread m_async_thread;
- lldb_private::ConstString m_dyld_plugin_name;
- lldb::addr_t m_kernel_load_addr;
- lldb::CommandObjectSP m_command_sp;
- lldb::ThreadWP m_kernel_thread_wp;
-
-
- bool
- StartAsyncThread ();
-
- void
- StopAsyncThread ();
-
- static void *
- AsyncThread (void *arg);
-
+ friend class ThreadKDP;
+ friend class CommunicationKDP;
+
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+ bool IsRunning(lldb::StateType state) {
+ return state == lldb::eStateRunning || IsStepping(state);
+ }
+
+ bool IsStepping(lldb::StateType state) {
+ return state == lldb::eStateStepping;
+ }
+
+ bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }
+
+ bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }
+
+ bool GetHostArchitecture(lldb_private::ArchSpec &arch);
+
+ bool ProcessIDIsValid() const;
+
+ void Clear();
+
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
+
+ enum {
+ eBroadcastBitAsyncContinue = (1 << 0),
+ eBroadcastBitAsyncThreadShouldExit = (1 << 1)
+ };
+
+ lldb::ThreadSP GetKernelThread();
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ CommunicationKDP m_comm;
+ lldb_private::Broadcaster m_async_broadcaster;
+ lldb_private::HostThread m_async_thread;
+ lldb_private::ConstString m_dyld_plugin_name;
+ lldb::addr_t m_kernel_load_addr;
+ lldb::CommandObjectSP m_command_sp;
+ lldb::ThreadWP m_kernel_thread_wp;
+
+ bool StartAsyncThread();
+
+ void StopAsyncThread();
+
+ static void *AsyncThread(void *arg);
+
private:
- //------------------------------------------------------------------
- // For ProcessKDP only
- //------------------------------------------------------------------
-
- DISALLOW_COPY_AND_ASSIGN (ProcessKDP);
-
+ //------------------------------------------------------------------
+ // For ProcessKDP only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessKDP);
};
-#endif // liblldb_ProcessKDP_h_
+#endif // liblldb_ProcessKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
index 79cb62aa0066..479f09aa8981 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
@@ -9,178 +9,184 @@
#include "ProcessKDPLog.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
#include "ProcessKDP.h"
using namespace lldb;
using namespace lldb_private;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_log_sp the first time this function is
+// that will construct the static g_log_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = NULL;
-static Log *
-GetLog ()
-{
- if (!g_log_enabled)
- return NULL;
- return g_log;
+static Log *g_log = NULL;
+static Log *GetLog() {
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-Log *
-ProcessKDPLog::GetLogIfAllCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && mask)
- {
- uint32_t log_mask = log->GetMask().Get();
- if ((log_mask & mask) != mask)
- return NULL;
- }
- return log;
+Log *ProcessKDPLog::GetLogIfAllCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && mask) {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return NULL;
+ }
+ return log;
}
-void
-ProcessKDPLog::DisableLog (const char **categories, Stream *feedback_strm)
-{
- Log *log (GetLog ());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- if (categories[0] != NULL)
- {
- flag_bits = log->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~KDP_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~KDP_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~KDP_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~KDP_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~KDP_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~KDP_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~KDP_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~KDP_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~KDP_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~KDP_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~KDP_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~KDP_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- }
-
- }
+void ProcessKDPLog::DisableLog(const char **categories, Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
+ uint32_t flag_bits = 0;
+
+ if (categories[0] != NULL) {
+ flag_bits = log->GetMask().Get();
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits &= ~KDP_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits &= ~KDP_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits &= ~KDP_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits &= ~KDP_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits &= ~KDP_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits &= ~KDP_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits &= ~KDP_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits &= ~KDP_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits &= ~KDP_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits &= ~KDP_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits &= ~KDP_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits &= ~KDP_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
}
-
- log->GetMask().Reset (flag_bits);
- if (flag_bits == 0)
- g_log_enabled = false;
+ }
}
-
- return;
-}
-Log *
-ProcessKDPLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
- uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
- }
+ log->GetMask().Reset(flag_bits);
+ if (flag_bits == 0)
+ g_log_enabled = false;
+ }
+ return;
+}
+
+Log *ProcessKDPLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **categories, Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (size_t i=0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits |= KDP_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= KDP_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= KDP_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= KDP_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= KDP_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= KDP_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= KDP_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= KDP_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= KDP_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= KDP_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= KDP_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= KDP_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits |= KDP_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits |= KDP_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits |= KDP_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits |= KDP_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits |= KDP_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits |= KDP_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits |= KDP_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits |= KDP_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits |= KDP_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits |= KDP_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits |= KDP_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits |= KDP_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits |= KDP_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits |= KDP_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = KDP_LOG_DEFAULT;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
+ }
}
- g_log_enabled = true;
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = KDP_LOG_DEFAULT;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ }
+ g_log_enabled = true;
+ return g_log;
}
-void
-ProcessKDPLog::ListLogCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " async - log asynchronous activity\n"
- " break - log breakpoints\n"
- " communication - log communication activity\n"
- " default - enable the default set of logging categories for liblldb\n"
- " packets - log gdb remote packets\n"
- " memory - log memory reads and writes\n"
- " data-short - log memory bytes for memory reads and writes for short transactions only\n"
- " data-long - log memory bytes for memory reads and writes for all transactions\n"
- " process - log process events and activities\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n",
- ProcessKDP::GetPluginNameStatic().GetCString());
+void ProcessKDPLog::ListLogCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " async - log asynchronous activity\n"
+ " break - log breakpoints\n"
+ " communication - log communication activity\n"
+ " default - enable the default set of logging categories for liblldb\n"
+ " packets - log gdb remote packets\n"
+ " memory - log memory reads and writes\n"
+ " data-short - log memory bytes for memory reads and writes for short "
+ "transactions only\n"
+ " data-long - log memory bytes for memory reads and writes for all "
+ "transactions\n"
+ " process - log process events and activities\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n"
+ " watch - log watchpoint related activities\n",
+ ProcessKDP::GetPluginNameStatic().GetCString());
}
-
-void
-ProcessKDPLog::LogIf (uint32_t mask, const char *format, ...)
-{
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (mask));
- if (log)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void ProcessKDPLog::LogIf(uint32_t mask, const char *format, ...) {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(mask));
+ if (log) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
index 0cb32d9b2dcf..703c775268d2 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
@@ -17,38 +17,37 @@
// Project includes
#include "lldb/Core/Log.h"
-#define KDP_LOG_VERBOSE (1u << 0)
-#define KDP_LOG_PROCESS (1u << 1)
-#define KDP_LOG_THREAD (1u << 2)
-#define KDP_LOG_PACKETS (1u << 3)
-#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define KDP_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
-#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define KDP_LOG_BREAKPOINTS (1u << 7)
-#define KDP_LOG_WATCHPOINTS (1u << 8)
-#define KDP_LOG_STEP (1u << 9)
-#define KDP_LOG_COMM (1u << 10)
-#define KDP_LOG_ASYNC (1u << 11)
-#define KDP_LOG_ALL (UINT32_MAX)
-#define KDP_LOG_DEFAULT KDP_LOG_PACKETS
-
-class ProcessKDPLog
-{
+#define KDP_LOG_VERBOSE (1u << 0)
+#define KDP_LOG_PROCESS (1u << 1)
+#define KDP_LOG_THREAD (1u << 2)
+#define KDP_LOG_PACKETS (1u << 3)
+#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define KDP_LOG_MEMORY_DATA_SHORT \
+ (1u << 5) // Log short memory reads/writes bytes
+#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
+#define KDP_LOG_BREAKPOINTS (1u << 7)
+#define KDP_LOG_WATCHPOINTS (1u << 8)
+#define KDP_LOG_STEP (1u << 9)
+#define KDP_LOG_COMM (1u << 10)
+#define KDP_LOG_ASYNC (1u << 11)
+#define KDP_LOG_ALL (UINT32_MAX)
+#define KDP_LOG_DEFAULT KDP_LOG_PACKETS
+
+class ProcessKDPLog {
public:
- static lldb_private::Log *
- GetLogIfAllCategoriesSet(uint32_t mask = 0);
+ static lldb_private::Log *GetLogIfAllCategoriesSet(uint32_t mask = 0);
- static void
- DisableLog (const char **categories, lldb_private::Stream *feedback_strm);
+ static void DisableLog(const char **categories,
+ lldb_private::Stream *feedback_strm);
- static lldb_private::Log *
- EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm);
+ static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp,
+ uint32_t log_options,
+ const char **categories,
+ lldb_private::Stream *feedback_strm);
- static void
- ListLogCategories (lldb_private::Stream *strm);
+ static void ListLogCategories(lldb_private::Stream *strm);
- static void
- LogIf (uint32_t mask, const char *format, ...);
+ static void LogIf(uint32_t mask, const char *format, ...);
};
-#endif // liblldb_ProcessKDPLog_h_
+#endif // liblldb_ProcessKDPLog_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
index 449ac646ab3c..06c33dba8576 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
@@ -19,143 +19,133 @@
using namespace lldb;
using namespace lldb_private;
-
-RegisterContextKDP_arm::RegisterContextKDP_arm (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_arm (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_arm::~RegisterContextKDP_arm()
-{
-}
-
-int
-RegisterContextKDP_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+RegisterContextKDP_arm::RegisterContextKDP_arm(ThreadKDP &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_arm(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
+
+RegisterContextKDP_arm::~RegisterContextKDP_arm() {}
+
+int RegisterContextKDP_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
+ const DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
index 1e547289d9ce..fe02b0648221 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
@@ -19,43 +19,30 @@
class ThreadKDP;
-class RegisterContextKDP_arm : public RegisterContextDarwin_arm
-{
+class RegisterContextKDP_arm : public RegisterContextDarwin_arm {
public:
+ RegisterContextKDP_arm(ThreadKDP &thread, uint32_t concrete_frame_idx);
- RegisterContextKDP_arm (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_arm();
+ virtual ~RegisterContextKDP_arm();
protected:
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
-
- ThreadKDP &m_kdp_thread;
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_arm_h_
+#endif // liblldb_RegisterContextKDP_arm_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
index ed62f1982d3c..6a2733e62759 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++ -*-===//
+//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,143 +20,133 @@
using namespace lldb;
using namespace lldb_private;
-
-RegisterContextKDP_arm64::RegisterContextKDP_arm64 (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_arm64 (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_arm64::~RegisterContextKDP_arm64()
-{
-}
-
-int
-RegisterContextKDP_arm64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+RegisterContextKDP_arm64::RegisterContextKDP_arm64(ThreadKDP &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_arm64(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
+
+RegisterContextKDP_arm64::~RegisterContextKDP_arm64() {}
+
+int RegisterContextKDP_arm64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteDBG(lldb::tid_t tid, int flavor,
+ const DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
index 8780b7be4a9a..0922654de2cc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextKDP_arm64.h --------------------------------*- C++ -*-===//
+//===-- RegisterContextKDP_arm64.h --------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,43 +20,30 @@
class ThreadKDP;
-class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64
-{
+class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 {
public:
+ RegisterContextKDP_arm64(ThreadKDP &thread, uint32_t concrete_frame_idx);
- RegisterContextKDP_arm64 (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_arm64();
+ virtual ~RegisterContextKDP_arm64();
protected:
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
-
- ThreadKDP &m_kdp_thread;
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_arm64_h_
+#endif // liblldb_RegisterContextKDP_arm64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
index 882b0c2e931d..4a130c18d075 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
// C++ Includes
// Other libraries and framework includes
@@ -19,111 +18,102 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextKDP_i386::RegisterContextKDP_i386(ThreadKDP &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_i386(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
-RegisterContextKDP_i386::RegisterContextKDP_i386 (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_i386 (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_i386::~RegisterContextKDP_i386()
-{
-}
+RegisterContextKDP_i386::~RegisterContextKDP_i386() {}
-int
-RegisterContextKDP_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
index 4b6bc5b262f7..5803670a08b4 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
@@ -18,36 +18,26 @@
class ThreadKDP;
-class RegisterContextKDP_i386 : public RegisterContextDarwin_i386
-{
+class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 {
public:
- RegisterContextKDP_i386 (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_i386();
-
+ RegisterContextKDP_i386(ThreadKDP &thread, uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextKDP_i386();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- ThreadKDP &m_kdp_thread;
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_i386_h_
+#endif // liblldb_RegisterContextKDP_i386_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
index f4247a5da272..ad10d3f6be52 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
// C++ Includes
// Other libraries and framework includes
@@ -19,109 +18,105 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextKDP_x86_64::RegisterContextKDP_x86_64(
+ ThreadKDP &thread, uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_x86_64(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
-RegisterContextKDP_x86_64::RegisterContextKDP_x86_64 (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_x86_64 (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64()
-{
-}
+RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64() {}
-int
-RegisterContextKDP_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
+ GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoReadFPU(lldb::tid_t tid, int flavor,
+ FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
+ EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
index a426349198ff..7a40bb626385 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
@@ -18,37 +18,26 @@
class ThreadKDP;
-class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64
-{
+class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 {
public:
-
- RegisterContextKDP_x86_64 (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_x86_64();
-
+ RegisterContextKDP_x86_64(ThreadKDP &thread, uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextKDP_x86_64();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- ThreadKDP &m_kdp_thread;
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_x86_64_h_
+#endif // liblldb_RegisterContextKDP_x86_64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index 3b8bed101a8a..273e1966f3fc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -7,29 +7,28 @@
//
//===----------------------------------------------------------------------===//
-
#include "ThreadKDP.h"
#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
-#include "lldb/Breakpoint/Watchpoint.h"
+#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "ProcessKDP.h"
#include "ProcessKDPLog.h"
#include "RegisterContextKDP_arm.h"
#include "RegisterContextKDP_arm64.h"
#include "RegisterContextKDP_i386.h"
#include "RegisterContextKDP_x86_64.h"
-#include "Plugins/Process/Utility/StopInfoMachException.h"
using namespace lldb;
using namespace lldb_private;
@@ -38,174 +37,137 @@ using namespace lldb_private;
// Thread Registers
//----------------------------------------------------------------------
-ThreadKDP::ThreadKDP (Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_thread_name (),
- m_dispatch_queue_name (),
- m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
-{
- ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID());
-}
-
-ThreadKDP::~ThreadKDP ()
-{
- ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID());
- DestroyThread();
+ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid)
+ : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
+ m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
+ ProcessKDPLog::LogIf(KDP_LOG_THREAD,
+ "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this,
+ GetID());
}
-const char *
-ThreadKDP::GetName ()
-{
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+ThreadKDP::~ThreadKDP() {
+ ProcessKDPLog::LogIf(KDP_LOG_THREAD,
+ "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this,
+ GetID());
+ DestroyThread();
}
-const char *
-ThreadKDP::GetQueueName ()
-{
+const char *ThreadKDP::GetName() {
+ if (m_thread_name.empty())
return NULL;
+ return m_thread_name.c_str();
}
-void
-ThreadKDP::RefreshStateAfterStop()
-{
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The KDPRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
- const bool force = false;
- lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
- if (reg_ctx_sp)
- reg_ctx_sp->InvalidateIfNeeded (force);
+const char *ThreadKDP::GetQueueName() { return NULL; }
+
+void ThreadKDP::RefreshStateAfterStop() {
+ // Invalidate all registers in our register context. We don't set "force" to
+ // true because the stop reply packet might have had some register values
+ // that were expedited and these will already be copied into the register
+ // context by the time this function gets called. The KDPRegisterContext
+ // class has been made smart enough to detect when it needs to invalidate
+ // which registers are valid by putting hooks in the register read and
+ // register supply functions where they check the process stop ID and do
+ // the right thing.
+ const bool force = false;
+ lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
+ if (reg_ctx_sp)
+ reg_ctx_sp->InvalidateIfNeeded(force);
}
-bool
-ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
-{
- return thread != 0;
-}
-
-void
-ThreadKDP::Dump(Log *log, uint32_t index)
-{
-}
+bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
+void ThreadKDP::Dump(Log *log, uint32_t index) {}
-bool
-ThreadKDP::ShouldStop (bool &step_more)
-{
- return true;
-}
-lldb::RegisterContextSP
-ThreadKDP::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- return m_reg_context_sp;
+bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
+lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL)
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType())
- {
- case llvm::MachO::CPU_TYPE_ARM:
- reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_ARM64:
- reg_ctx_sp.reset (new RegisterContextKDP_arm64 (*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_I386:
- reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_X86_64:
- reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
- break;
- default:
- assert (!"Add CPU type support in KDP");
- break;
- }
- }
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ switch (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .GetCPUType()) {
+ case llvm::MachO::CPU_TYPE_ARM:
+ reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx));
+ break;
+ case llvm::MachO::CPU_TYPE_ARM64:
+ reg_ctx_sp.reset(
+ new RegisterContextKDP_arm64(*this, concrete_frame_idx));
+ break;
+ case llvm::MachO::CPU_TYPE_I386:
+ reg_ctx_sp.reset(
+ new RegisterContextKDP_i386(*this, concrete_frame_idx));
+ break;
+ case llvm::MachO::CPU_TYPE_X86_64:
+ reg_ctx_sp.reset(
+ new RegisterContextKDP_x86_64(*this, concrete_frame_idx));
+ break;
+ default:
+ assert(!"Add CPU type support in KDP");
+ break;
+ }
}
- return reg_ctx_sp;
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadKDP::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- if (m_cached_stop_info_sp)
- {
- SetStopInfo (m_cached_stop_info_sp);
- }
- else
- {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
- }
- return true;
+bool ThreadKDP::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ if (m_cached_stop_info_sp) {
+ SetStopInfo(m_cached_stop_info_sp);
+ } else {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
}
- return false;
+ return true;
+ }
+ return false;
}
-void
-ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
-{
- lldb::offset_t offset = 0;
- uint8_t reply_command = exc_reply_packet.GetU8(&offset);
- if (reply_command == CommunicationKDP::KDP_EXCEPTION)
- {
- offset = 8;
- const uint32_t count = exc_reply_packet.GetU32 (&offset);
- if (count >= 1)
- {
- //const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
- offset += 4; // Skip the useless CPU field
- const uint32_t exc_type = exc_reply_packet.GetU32 (&offset);
- const uint32_t exc_code = exc_reply_packet.GetU32 (&offset);
- const uint32_t exc_subcode = exc_reply_packet.GetU32 (&offset);
- // We have to make a copy of the stop info because the thread list
- // will iterate through the threads and clear all stop infos..
-
- // Let the StopInfoMachException::CreateStopReasonWithMachException()
- // function update the PC if needed as we might hit a software breakpoint
- // and need to decrement the PC (i386 and x86_64 need this) and KDP
- // doesn't do this for us.
- const bool pc_already_adjusted = false;
- const bool adjust_pc_if_needed = true;
-
- m_cached_stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException (*this,
- exc_type,
- 2,
- exc_code,
- exc_subcode,
- 0,
- pc_already_adjusted,
- adjust_pc_if_needed);
- }
+void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
+ const DataExtractor &exc_reply_packet) {
+ lldb::offset_t offset = 0;
+ uint8_t reply_command = exc_reply_packet.GetU8(&offset);
+ if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
+ offset = 8;
+ const uint32_t count = exc_reply_packet.GetU32(&offset);
+ if (count >= 1) {
+ // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
+ offset += 4; // Skip the useless CPU field
+ const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
+ const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
+ const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
+ // We have to make a copy of the stop info because the thread list
+ // will iterate through the threads and clear all stop infos..
+
+ // Let the StopInfoMachException::CreateStopReasonWithMachException()
+ // function update the PC if needed as we might hit a software breakpoint
+ // and need to decrement the PC (i386 and x86_64 need this) and KDP
+ // doesn't do this for us.
+ const bool pc_already_adjusted = false;
+ const bool adjust_pc_if_needed = true;
+
+ m_cached_stop_info_sp =
+ StopInfoMachException::CreateStopReasonWithMachException(
+ *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
+ adjust_pc_if_needed);
}
+ }
}
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
index 7dc373f03550..ea517b4254fc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
@@ -17,82 +17,61 @@
class ProcessKDP;
-class ThreadKDP : public lldb_private::Thread
-{
+class ThreadKDP : public lldb_private::Thread {
public:
- ThreadKDP (lldb_private::Process &process,
- lldb::tid_t tid);
+ ThreadKDP(lldb_private::Process &process, lldb::tid_t tid);
- virtual
- ~ThreadKDP ();
+ virtual ~ThreadKDP();
- virtual void
- RefreshStateAfterStop();
+ virtual void RefreshStateAfterStop();
- virtual const char *
- GetName ();
+ virtual const char *GetName();
- virtual const char *
- GetQueueName ();
+ virtual const char *GetQueueName();
- virtual lldb::RegisterContextSP
- GetRegisterContext ();
+ virtual lldb::RegisterContextSP GetRegisterContext();
- virtual lldb::RegisterContextSP
- CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
+ virtual lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame);
- void
- Dump (lldb_private::Log *log, uint32_t index);
+ void Dump(lldb_private::Log *log, uint32_t index);
- static bool
- ThreadIDIsValid (lldb::tid_t thread);
+ static bool ThreadIDIsValid(lldb::tid_t thread);
- bool
- ShouldStop (bool &step_more);
+ bool ShouldStop(bool &step_more);
- const char *
- GetBasicInfoAsString ();
+ const char *GetBasicInfoAsString();
- void
- SetName (const char *name)
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
- lldb::addr_t
- GetThreadDispatchQAddr ()
- {
- return m_thread_dispatch_qaddr;
- }
+ lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
- void
- SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
- {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
-
- void
- SetStopInfoFrom_KDP_EXCEPTION (const lldb_private::DataExtractor &exc_reply_packet);
+ void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
+ m_thread_dispatch_qaddr = thread_dispatch_qaddr;
+ }
+
+ void SetStopInfoFrom_KDP_EXCEPTION(
+ const lldb_private::DataExtractor &exc_reply_packet);
protected:
-
- friend class ProcessKDP;
-
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::StopInfoSP m_cached_stop_info_sp;
- //------------------------------------------------------------------
- // Protected member functions.
- //------------------------------------------------------------------
- virtual bool
- CalculateStopInfo ();
+ friend class ProcessKDP;
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ std::string m_thread_name;
+ std::string m_dispatch_queue_name;
+ lldb::addr_t m_thread_dispatch_qaddr;
+ lldb::StopInfoSP m_cached_stop_info_sp;
+ //------------------------------------------------------------------
+ // Protected member functions.
+ //------------------------------------------------------------------
+ virtual bool CalculateStopInfo();
};
-#endif // liblldb_ThreadKDP_h_
+#endif // liblldb_ThreadKDP_h_
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp
index 44409a4ce552..debdd7808e63 100644
--- a/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -9,308 +9,333 @@
#include "CrashReason.h"
+#include "llvm/Support/raw_ostream.h"
+
#include <sstream>
namespace {
-void
-AppendFaultAddr (std::string& str, lldb::addr_t addr)
-{
- std::stringstream ss;
- ss << " (fault address: 0x" << std::hex << addr << ")";
- str += ss.str();
+void AppendFaultAddr(std::string &str, lldb::addr_t addr) {
+ std::stringstream ss;
+ ss << " (fault address: 0x" << std::hex << addr << ")";
+ str += ss.str();
+}
+
+void AppendBounds(std::string &str, lldb::addr_t lower_bound,
+ lldb::addr_t upper_bound, lldb::addr_t addr) {
+ llvm::raw_string_ostream stream(str);
+ if ((unsigned long)addr < lower_bound)
+ stream << ": lower bound violation ";
+ else
+ stream << ": upper bound violation ";
+ stream << "(fault address: 0x";
+ stream.write_hex(addr);
+ stream << ", lower bound: 0x";
+ stream.write_hex(lower_bound);
+ stream << ", upper bound: 0x";
+ stream.write_hex(upper_bound);
+ stream << ")";
+ stream.flush();
}
-CrashReason
-GetCrashReasonForSIGSEGV(const siginfo_t& info)
-{
- assert(info.si_signo == SIGSEGV);
+CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
+ assert(info.si_signo == SIGSEGV);
- switch (info.si_code)
- {
+ switch (info.si_code) {
#ifdef SI_KERNEL
- case SI_KERNEL:
- // Some platforms will occasionally send nonstandard spurious SI_KERNEL codes.
- // One way to get this is via unaligned SIMD loads.
- return CrashReason::eInvalidAddress; // for lack of anything better
+ case SI_KERNEL:
+ // Some platforms will occasionally send nonstandard spurious SI_KERNEL
+ // codes.
+ // One way to get this is via unaligned SIMD loads.
+ return CrashReason::eInvalidAddress; // for lack of anything better
#endif
- case SEGV_MAPERR:
- return CrashReason::eInvalidAddress;
- case SEGV_ACCERR:
- return CrashReason::ePrivilegedAddress;
- }
-
- assert(false && "unexpected si_code for SIGSEGV");
- return CrashReason::eInvalidCrashReason;
-}
+ case SEGV_MAPERR:
+ return CrashReason::eInvalidAddress;
+ case SEGV_ACCERR:
+ return CrashReason::ePrivilegedAddress;
+#ifndef SEGV_BNDERR
+#define SEGV_BNDERR 3
+#endif
+ case SEGV_BNDERR:
+ return CrashReason::eBoundViolation;
+ }
-CrashReason
-GetCrashReasonForSIGILL(const siginfo_t& info)
-{
- assert(info.si_signo == SIGILL);
-
- switch (info.si_code)
- {
- case ILL_ILLOPC:
- return CrashReason::eIllegalOpcode;
- case ILL_ILLOPN:
- return CrashReason::eIllegalOperand;
- case ILL_ILLADR:
- return CrashReason::eIllegalAddressingMode;
- case ILL_ILLTRP:
- return CrashReason::eIllegalTrap;
- case ILL_PRVOPC:
- return CrashReason::ePrivilegedOpcode;
- case ILL_PRVREG:
- return CrashReason::ePrivilegedRegister;
- case ILL_COPROC:
- return CrashReason::eCoprocessorError;
- case ILL_BADSTK:
- return CrashReason::eInternalStackError;
- }
-
- assert(false && "unexpected si_code for SIGILL");
- return CrashReason::eInvalidCrashReason;
+ assert(false && "unexpected si_code for SIGSEGV");
+ return CrashReason::eInvalidCrashReason;
}
-CrashReason
-GetCrashReasonForSIGFPE(const siginfo_t& info)
-{
- assert(info.si_signo == SIGFPE);
-
- switch (info.si_code)
- {
- case FPE_INTDIV:
- return CrashReason::eIntegerDivideByZero;
- case FPE_INTOVF:
- return CrashReason::eIntegerOverflow;
- case FPE_FLTDIV:
- return CrashReason::eFloatDivideByZero;
- case FPE_FLTOVF:
- return CrashReason::eFloatOverflow;
- case FPE_FLTUND:
- return CrashReason::eFloatUnderflow;
- case FPE_FLTRES:
- return CrashReason::eFloatInexactResult;
- case FPE_FLTINV:
- return CrashReason::eFloatInvalidOperation;
- case FPE_FLTSUB:
- return CrashReason::eFloatSubscriptRange;
- }
-
- assert(false && "unexpected si_code for SIGFPE");
- return CrashReason::eInvalidCrashReason;
+CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) {
+ assert(info.si_signo == SIGILL);
+
+ switch (info.si_code) {
+ case ILL_ILLOPC:
+ return CrashReason::eIllegalOpcode;
+ case ILL_ILLOPN:
+ return CrashReason::eIllegalOperand;
+ case ILL_ILLADR:
+ return CrashReason::eIllegalAddressingMode;
+ case ILL_ILLTRP:
+ return CrashReason::eIllegalTrap;
+ case ILL_PRVOPC:
+ return CrashReason::ePrivilegedOpcode;
+ case ILL_PRVREG:
+ return CrashReason::ePrivilegedRegister;
+ case ILL_COPROC:
+ return CrashReason::eCoprocessorError;
+ case ILL_BADSTK:
+ return CrashReason::eInternalStackError;
+ }
+
+ assert(false && "unexpected si_code for SIGILL");
+ return CrashReason::eInvalidCrashReason;
}
-CrashReason
-GetCrashReasonForSIGBUS(const siginfo_t& info)
-{
- assert(info.si_signo == SIGBUS);
-
- switch (info.si_code)
- {
- case BUS_ADRALN:
- return CrashReason::eIllegalAlignment;
- case BUS_ADRERR:
- return CrashReason::eIllegalAddress;
- case BUS_OBJERR:
- return CrashReason::eHardwareError;
- }
-
- assert(false && "unexpected si_code for SIGBUS");
- return CrashReason::eInvalidCrashReason;
+CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) {
+ assert(info.si_signo == SIGFPE);
+
+ switch (info.si_code) {
+ case FPE_INTDIV:
+ return CrashReason::eIntegerDivideByZero;
+ case FPE_INTOVF:
+ return CrashReason::eIntegerOverflow;
+ case FPE_FLTDIV:
+ return CrashReason::eFloatDivideByZero;
+ case FPE_FLTOVF:
+ return CrashReason::eFloatOverflow;
+ case FPE_FLTUND:
+ return CrashReason::eFloatUnderflow;
+ case FPE_FLTRES:
+ return CrashReason::eFloatInexactResult;
+ case FPE_FLTINV:
+ return CrashReason::eFloatInvalidOperation;
+ case FPE_FLTSUB:
+ return CrashReason::eFloatSubscriptRange;
+ }
+
+ assert(false && "unexpected si_code for SIGFPE");
+ return CrashReason::eInvalidCrashReason;
}
+CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) {
+ assert(info.si_signo == SIGBUS);
+
+ switch (info.si_code) {
+ case BUS_ADRALN:
+ return CrashReason::eIllegalAlignment;
+ case BUS_ADRERR:
+ return CrashReason::eIllegalAddress;
+ case BUS_OBJERR:
+ return CrashReason::eHardwareError;
+ }
+
+ assert(false && "unexpected si_code for SIGBUS");
+ return CrashReason::eInvalidCrashReason;
+}
}
-std::string
-GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr)
-{
- std::string str;
-
- switch (reason)
- {
- default:
- assert(false && "invalid CrashReason");
- break;
-
- case CrashReason::eInvalidAddress:
- str = "signal SIGSEGV: invalid address";
- AppendFaultAddr (str, fault_addr);
- break;
- case CrashReason::ePrivilegedAddress:
- str = "signal SIGSEGV: address access protected";
- AppendFaultAddr (str, fault_addr);
- break;
- case CrashReason::eIllegalOpcode:
- str = "signal SIGILL: illegal instruction";
- break;
- case CrashReason::eIllegalOperand:
- str = "signal SIGILL: illegal instruction operand";
- break;
- case CrashReason::eIllegalAddressingMode:
- str = "signal SIGILL: illegal addressing mode";
- break;
- case CrashReason::eIllegalTrap:
- str = "signal SIGILL: illegal trap";
- break;
- case CrashReason::ePrivilegedOpcode:
- str = "signal SIGILL: privileged instruction";
- break;
- case CrashReason::ePrivilegedRegister:
- str = "signal SIGILL: privileged register";
- break;
- case CrashReason::eCoprocessorError:
- str = "signal SIGILL: coprocessor error";
- break;
- case CrashReason::eInternalStackError:
- str = "signal SIGILL: internal stack error";
- break;
- case CrashReason::eIllegalAlignment:
- str = "signal SIGBUS: illegal alignment";
- break;
- case CrashReason::eIllegalAddress:
- str = "signal SIGBUS: illegal address";
- break;
- case CrashReason::eHardwareError:
- str = "signal SIGBUS: hardware error";
- break;
- case CrashReason::eIntegerDivideByZero:
- str = "signal SIGFPE: integer divide by zero";
- break;
- case CrashReason::eIntegerOverflow:
- str = "signal SIGFPE: integer overflow";
- break;
- case CrashReason::eFloatDivideByZero:
- str = "signal SIGFPE: floating point divide by zero";
- break;
- case CrashReason::eFloatOverflow:
- str = "signal SIGFPE: floating point overflow";
- break;
- case CrashReason::eFloatUnderflow:
- str = "signal SIGFPE: floating point underflow";
- break;
- case CrashReason::eFloatInexactResult:
- str = "signal SIGFPE: inexact floating point result";
- break;
- case CrashReason::eFloatInvalidOperation:
- str = "signal SIGFPE: invalid floating point operation";
- break;
- case CrashReason::eFloatSubscriptRange:
- str = "signal SIGFPE: invalid floating point subscript range";
- break;
- }
+std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) {
+ std::string str;
+// make sure that siginfo_t has the bound fields available.
+#if defined(si_lower) && defined(si_upper)
+ if (reason == CrashReason::eBoundViolation) {
+ str = "signal SIGSEGV";
+ AppendBounds(str, reinterpret_cast<lldb::addr_t>(info.si_lower),
+ reinterpret_cast<lldb::addr_t>(info.si_upper),
+ reinterpret_cast<lldb::addr_t>(info.si_addr));
return str;
+ }
+#endif
+
+ return GetCrashReasonString(reason,
+ reinterpret_cast<lldb::addr_t>(info.si_addr));
}
-const char *
-CrashReasonAsString (CrashReason reason)
-{
+std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
+ std::string str;
+
+ switch (reason) {
+ default:
+ assert(false && "invalid CrashReason");
+ break;
+
+ case CrashReason::eInvalidAddress:
+ str = "signal SIGSEGV: invalid address";
+ AppendFaultAddr(str, fault_addr);
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "signal SIGSEGV: address access protected";
+ AppendFaultAddr(str, fault_addr);
+ break;
+ case CrashReason::eBoundViolation:
+ str = "signal SIGSEGV: bound violation";
+ break;
+ case CrashReason::eIllegalOpcode:
+ str = "signal SIGILL: illegal instruction";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "signal SIGILL: illegal instruction operand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "signal SIGILL: illegal addressing mode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "signal SIGILL: illegal trap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "signal SIGILL: privileged instruction";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "signal SIGILL: privileged register";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "signal SIGILL: coprocessor error";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "signal SIGILL: internal stack error";
+ break;
+ case CrashReason::eIllegalAlignment:
+ str = "signal SIGBUS: illegal alignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "signal SIGBUS: illegal address";
+ break;
+ case CrashReason::eHardwareError:
+ str = "signal SIGBUS: hardware error";
+ break;
+ case CrashReason::eIntegerDivideByZero:
+ str = "signal SIGFPE: integer divide by zero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "signal SIGFPE: integer overflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "signal SIGFPE: floating point divide by zero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "signal SIGFPE: floating point overflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "signal SIGFPE: floating point underflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "signal SIGFPE: inexact floating point result";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "signal SIGFPE: invalid floating point operation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "signal SIGFPE: invalid floating point subscript range";
+ break;
+ }
+
+ return str;
+}
+
+const char *CrashReasonAsString(CrashReason reason) {
#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
+ // Just return the code in ascii for integration builds.
+ chcar str[8];
+ sprintf(str, "%d", reason);
#else
- const char *str = nullptr;
-
- switch (reason)
- {
- case CrashReason::eInvalidCrashReason:
- str = "eInvalidCrashReason";
- break;
-
- // SIGSEGV crash reasons.
- case CrashReason::eInvalidAddress:
- str = "eInvalidAddress";
- break;
- case CrashReason::ePrivilegedAddress:
- str = "ePrivilegedAddress";
- break;
-
- // SIGILL crash reasons.
- case CrashReason::eIllegalOpcode:
- str = "eIllegalOpcode";
- break;
- case CrashReason::eIllegalOperand:
- str = "eIllegalOperand";
- break;
- case CrashReason::eIllegalAddressingMode:
- str = "eIllegalAddressingMode";
- break;
- case CrashReason::eIllegalTrap:
- str = "eIllegalTrap";
- break;
- case CrashReason::ePrivilegedOpcode:
- str = "ePrivilegedOpcode";
- break;
- case CrashReason::ePrivilegedRegister:
- str = "ePrivilegedRegister";
- break;
- case CrashReason::eCoprocessorError:
- str = "eCoprocessorError";
- break;
- case CrashReason::eInternalStackError:
- str = "eInternalStackError";
- break;
-
- // SIGBUS crash reasons:
- case CrashReason::eIllegalAlignment:
- str = "eIllegalAlignment";
- break;
- case CrashReason::eIllegalAddress:
- str = "eIllegalAddress";
- break;
- case CrashReason::eHardwareError:
- str = "eHardwareError";
- break;
-
- // SIGFPE crash reasons:
- case CrashReason::eIntegerDivideByZero:
- str = "eIntegerDivideByZero";
- break;
- case CrashReason::eIntegerOverflow:
- str = "eIntegerOverflow";
- break;
- case CrashReason::eFloatDivideByZero:
- str = "eFloatDivideByZero";
- break;
- case CrashReason::eFloatOverflow:
- str = "eFloatOverflow";
- break;
- case CrashReason::eFloatUnderflow:
- str = "eFloatUnderflow";
- break;
- case CrashReason::eFloatInexactResult:
- str = "eFloatInexactResult";
- break;
- case CrashReason::eFloatInvalidOperation:
- str = "eFloatInvalidOperation";
- break;
- case CrashReason::eFloatSubscriptRange:
- str = "eFloatSubscriptRange";
- break;
- }
+ const char *str = nullptr;
+
+ switch (reason) {
+ case CrashReason::eInvalidCrashReason:
+ str = "eInvalidCrashReason";
+ break;
+
+ // SIGSEGV crash reasons.
+ case CrashReason::eInvalidAddress:
+ str = "eInvalidAddress";
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "ePrivilegedAddress";
+ break;
+ case CrashReason::eBoundViolation:
+ str = "eBoundViolation";
+ break;
+
+ // SIGILL crash reasons.
+ case CrashReason::eIllegalOpcode:
+ str = "eIllegalOpcode";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "eIllegalOperand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "eIllegalAddressingMode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "eIllegalTrap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "ePrivilegedOpcode";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "ePrivilegedRegister";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "eCoprocessorError";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "eInternalStackError";
+ break;
+
+ // SIGBUS crash reasons:
+ case CrashReason::eIllegalAlignment:
+ str = "eIllegalAlignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "eIllegalAddress";
+ break;
+ case CrashReason::eHardwareError:
+ str = "eHardwareError";
+ break;
+
+ // SIGFPE crash reasons:
+ case CrashReason::eIntegerDivideByZero:
+ str = "eIntegerDivideByZero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "eIntegerOverflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "eFloatDivideByZero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "eFloatOverflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "eFloatUnderflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "eFloatInexactResult";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "eFloatInvalidOperation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "eFloatSubscriptRange";
+ break;
+ }
#endif
- return str;
+ return str;
}
-CrashReason
-GetCrashReason(const siginfo_t& info)
-{
- switch(info.si_signo)
- {
- case SIGSEGV:
- return GetCrashReasonForSIGSEGV(info);
- case SIGBUS:
- return GetCrashReasonForSIGBUS(info);
- case SIGFPE:
- return GetCrashReasonForSIGFPE(info);
- case SIGILL:
- return GetCrashReasonForSIGILL(info);
- }
-
- assert(false && "unexpected signal");
- return CrashReason::eInvalidCrashReason;
+CrashReason GetCrashReason(const siginfo_t &info) {
+ switch (info.si_signo) {
+ case SIGSEGV:
+ return GetCrashReasonForSIGSEGV(info);
+ case SIGBUS:
+ return GetCrashReasonForSIGBUS(info);
+ case SIGFPE:
+ return GetCrashReasonForSIGFPE(info);
+ case SIGILL:
+ return GetCrashReasonForSIGILL(info);
+ }
+
+ assert(false && "unexpected signal");
+ return CrashReason::eInvalidCrashReason;
}
diff --git a/source/Plugins/Process/POSIX/CrashReason.h b/source/Plugins/Process/POSIX/CrashReason.h
index f6d9ba553e4a..57abe47b46b2 100644
--- a/source/Plugins/Process/POSIX/CrashReason.h
+++ b/source/Plugins/Process/POSIX/CrashReason.h
@@ -16,47 +16,45 @@
#include <string>
-enum class CrashReason
-{
- eInvalidCrashReason,
-
- // SIGSEGV crash reasons.
- eInvalidAddress,
- ePrivilegedAddress,
-
- // SIGILL crash reasons.
- eIllegalOpcode,
- eIllegalOperand,
- eIllegalAddressingMode,
- eIllegalTrap,
- ePrivilegedOpcode,
- ePrivilegedRegister,
- eCoprocessorError,
- eInternalStackError,
-
- // SIGBUS crash reasons,
- eIllegalAlignment,
- eIllegalAddress,
- eHardwareError,
-
- // SIGFPE crash reasons,
- eIntegerDivideByZero,
- eIntegerOverflow,
- eFloatDivideByZero,
- eFloatOverflow,
- eFloatUnderflow,
- eFloatInexactResult,
- eFloatInvalidOperation,
- eFloatSubscriptRange
+enum class CrashReason {
+ eInvalidCrashReason,
+
+ // SIGSEGV crash reasons.
+ eInvalidAddress,
+ ePrivilegedAddress,
+ eBoundViolation,
+
+ // SIGILL crash reasons.
+ eIllegalOpcode,
+ eIllegalOperand,
+ eIllegalAddressingMode,
+ eIllegalTrap,
+ ePrivilegedOpcode,
+ ePrivilegedRegister,
+ eCoprocessorError,
+ eInternalStackError,
+
+ // SIGBUS crash reasons,
+ eIllegalAlignment,
+ eIllegalAddress,
+ eHardwareError,
+
+ // SIGFPE crash reasons,
+ eIntegerDivideByZero,
+ eIntegerOverflow,
+ eFloatDivideByZero,
+ eFloatOverflow,
+ eFloatUnderflow,
+ eFloatInexactResult,
+ eFloatInvalidOperation,
+ eFloatSubscriptRange
};
-std::string
-GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr);
+std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr);
+std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info);
-const char *
-CrashReasonAsString (CrashReason reason);
+const char *CrashReasonAsString(CrashReason reason);
-CrashReason
-GetCrashReason(const siginfo_t& info);
+CrashReason GetCrashReason(const siginfo_t &info);
#endif // #ifndef liblldb_CrashReason_H_
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index 02049a2af953..48f2a7844cf7 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -11,68 +11,59 @@
using namespace lldb_private;
-const char *
-ProcessMessage::PrintCrashReason() const
-{
- return CrashReasonAsString(m_crash_reason);
+const char *ProcessMessage::PrintCrashReason() const {
+ return CrashReasonAsString(m_crash_reason);
}
-const char *
-ProcessMessage::PrintKind(Kind kind)
-{
+const char *ProcessMessage::PrintKind(Kind kind) {
#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
+ // Just return the code in ascii for integration builds.
+ chcar str[8];
+ sprintf(str, "%d", reason);
#else
- const char *str = NULL;
+ const char *str = NULL;
- switch (kind)
- {
- case eInvalidMessage:
- str = "eInvalidMessage";
- break;
- case eAttachMessage:
- str = "eAttachMessage";
- break;
- case eExitMessage:
- str = "eExitMessage";
- break;
- case eLimboMessage:
- str = "eLimboMessage";
- break;
- case eSignalMessage:
- str = "eSignalMessage";
- break;
- case eSignalDeliveredMessage:
- str = "eSignalDeliveredMessage";
- break;
- case eTraceMessage:
- str = "eTraceMessage";
- break;
- case eBreakpointMessage:
- str = "eBreakpointMessage";
- break;
- case eWatchpointMessage:
- str = "eWatchpointMessage";
- break;
- case eCrashMessage:
- str = "eCrashMessage";
- break;
- case eNewThreadMessage:
- str = "eNewThreadMessage";
- break;
- case eExecMessage:
- str = "eExecMessage";
- break;
- }
+ switch (kind) {
+ case eInvalidMessage:
+ str = "eInvalidMessage";
+ break;
+ case eAttachMessage:
+ str = "eAttachMessage";
+ break;
+ case eExitMessage:
+ str = "eExitMessage";
+ break;
+ case eLimboMessage:
+ str = "eLimboMessage";
+ break;
+ case eSignalMessage:
+ str = "eSignalMessage";
+ break;
+ case eSignalDeliveredMessage:
+ str = "eSignalDeliveredMessage";
+ break;
+ case eTraceMessage:
+ str = "eTraceMessage";
+ break;
+ case eBreakpointMessage:
+ str = "eBreakpointMessage";
+ break;
+ case eWatchpointMessage:
+ str = "eWatchpointMessage";
+ break;
+ case eCrashMessage:
+ str = "eCrashMessage";
+ break;
+ case eNewThreadMessage:
+ str = "eNewThreadMessage";
+ break;
+ case eExecMessage:
+ str = "eExecMessage";
+ break;
+ }
#endif
- return str;
+ return str;
}
-const char *
-ProcessMessage::PrintKind() const
-{
- return PrintKind(m_kind);
-}
+const char *ProcessMessage::PrintKind() const { return PrintKind(m_kind); }
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.h b/source/Plugins/Process/POSIX/ProcessMessage.h
index f932e9fff278..3c596ca68549 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.h
+++ b/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -18,165 +18,152 @@
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
-class ProcessMessage
-{
+class ProcessMessage {
public:
-
- /// The type of signal this message can correspond to.
- enum Kind
- {
- eInvalidMessage,
- eAttachMessage,
- eExitMessage,
- eLimboMessage,
- eSignalMessage,
- eSignalDeliveredMessage,
- eTraceMessage,
- eBreakpointMessage,
- eWatchpointMessage,
- eCrashMessage,
- eNewThreadMessage,
- eExecMessage
- };
-
- ProcessMessage()
- : m_tid(LLDB_INVALID_PROCESS_ID),
- m_kind(eInvalidMessage),
- m_crash_reason(CrashReason::eInvalidCrashReason),
- m_status(0),
- m_addr(0) { }
-
- Kind GetKind() const { return m_kind; }
-
- lldb::tid_t GetTID() const { return m_tid; }
-
- /// Indicates that the process @p pid has successfully attached.
- static ProcessMessage Attach(lldb::pid_t pid) {
- return ProcessMessage(pid, eAttachMessage);
- }
-
- /// Indicates that the thread @p tid is about to exit with status @p status.
- static ProcessMessage Limbo(lldb::tid_t tid, int status) {
- return ProcessMessage(tid, eLimboMessage, status);
- }
-
- /// Indicates that the thread @p tid had the signal @p signum delivered.
- static ProcessMessage Signal(lldb::tid_t tid, int signum) {
- return ProcessMessage(tid, eSignalMessage, signum);
- }
-
- /// Indicates that a signal @p signum generated by the debugging process was
- /// delivered to the thread @p tid.
- static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
- return ProcessMessage(tid, eSignalDeliveredMessage, signum);
- }
-
- /// Indicates that the thread @p tid encountered a trace point.
- static ProcessMessage Trace(lldb::tid_t tid) {
- return ProcessMessage(tid, eTraceMessage);
- }
-
- /// Indicates that the thread @p tid encountered a break point.
- static ProcessMessage Break(lldb::tid_t tid) {
- return ProcessMessage(tid, eBreakpointMessage);
- }
-
- static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
- return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
- }
-
- /// Indicates that the thread @p tid crashed.
- static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
- int signo, lldb::addr_t fault_addr) {
- ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
- message.m_crash_reason = reason;
- return message;
- }
-
- /// Indicates that the thread @p child_tid was spawned.
- static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
- return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
- }
-
- /// Indicates that the thread @p tid is about to exit with status @p status.
- static ProcessMessage Exit(lldb::tid_t tid, int status) {
- return ProcessMessage(tid, eExitMessage, status);
- }
-
- /// Indicates that the thread @p pid has exec'd.
- static ProcessMessage Exec(lldb::tid_t tid) {
- return ProcessMessage(tid, eExecMessage);
- }
-
- int GetExitStatus() const {
- assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
- return m_status;
- }
-
- int GetSignal() const {
- assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
- GetKind() == eSignalDeliveredMessage);
- return m_status;
- }
-
- int GetStopStatus() const {
- assert(GetKind() == eSignalMessage);
- return m_status;
- }
-
- CrashReason GetCrashReason() const {
- assert(GetKind() == eCrashMessage);
- return m_crash_reason;
- }
-
- lldb::addr_t GetFaultAddress() const {
- assert(GetKind() == eCrashMessage);
- return m_addr;
- }
-
- lldb::addr_t GetHWAddress() const {
- assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
- return m_addr;
- }
-
- lldb::tid_t GetChildTID() const {
- assert(GetKind() == eNewThreadMessage);
- return m_child_tid;
- }
-
- const char *
- PrintCrashReason() const;
-
- const char *
- PrintKind() const;
-
- static const char *
- PrintKind(Kind);
+ /// The type of signal this message can correspond to.
+ enum Kind {
+ eInvalidMessage,
+ eAttachMessage,
+ eExitMessage,
+ eLimboMessage,
+ eSignalMessage,
+ eSignalDeliveredMessage,
+ eTraceMessage,
+ eBreakpointMessage,
+ eWatchpointMessage,
+ eCrashMessage,
+ eNewThreadMessage,
+ eExecMessage
+ };
+
+ ProcessMessage()
+ : m_tid(LLDB_INVALID_PROCESS_ID), m_kind(eInvalidMessage),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0),
+ m_addr(0) {}
+
+ Kind GetKind() const { return m_kind; }
+
+ lldb::tid_t GetTID() const { return m_tid; }
+
+ /// Indicates that the process @p pid has successfully attached.
+ static ProcessMessage Attach(lldb::pid_t pid) {
+ return ProcessMessage(pid, eAttachMessage);
+ }
+
+ /// Indicates that the thread @p tid is about to exit with status @p status.
+ static ProcessMessage Limbo(lldb::tid_t tid, int status) {
+ return ProcessMessage(tid, eLimboMessage, status);
+ }
+
+ /// Indicates that the thread @p tid had the signal @p signum delivered.
+ static ProcessMessage Signal(lldb::tid_t tid, int signum) {
+ return ProcessMessage(tid, eSignalMessage, signum);
+ }
+
+ /// Indicates that a signal @p signum generated by the debugging process was
+ /// delivered to the thread @p tid.
+ static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
+ return ProcessMessage(tid, eSignalDeliveredMessage, signum);
+ }
+
+ /// Indicates that the thread @p tid encountered a trace point.
+ static ProcessMessage Trace(lldb::tid_t tid) {
+ return ProcessMessage(tid, eTraceMessage);
+ }
+
+ /// Indicates that the thread @p tid encountered a break point.
+ static ProcessMessage Break(lldb::tid_t tid) {
+ return ProcessMessage(tid, eBreakpointMessage);
+ }
+
+ static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
+ return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
+ }
+
+ /// Indicates that the thread @p tid crashed.
+ static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason, int signo,
+ lldb::addr_t fault_addr) {
+ ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
+ message.m_crash_reason = reason;
+ return message;
+ }
+
+ /// Indicates that the thread @p child_tid was spawned.
+ static ProcessMessage NewThread(lldb::tid_t parent_tid,
+ lldb::tid_t child_tid) {
+ return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
+ }
+
+ /// Indicates that the thread @p tid is about to exit with status @p status.
+ static ProcessMessage Exit(lldb::tid_t tid, int status) {
+ return ProcessMessage(tid, eExitMessage, status);
+ }
+
+ /// Indicates that the thread @p pid has exec'd.
+ static ProcessMessage Exec(lldb::tid_t tid) {
+ return ProcessMessage(tid, eExecMessage);
+ }
+
+ int GetExitStatus() const {
+ assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
+ return m_status;
+ }
+
+ int GetSignal() const {
+ assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
+ GetKind() == eSignalDeliveredMessage);
+ return m_status;
+ }
+
+ int GetStopStatus() const {
+ assert(GetKind() == eSignalMessage);
+ return m_status;
+ }
+
+ CrashReason GetCrashReason() const {
+ assert(GetKind() == eCrashMessage);
+ return m_crash_reason;
+ }
+
+ lldb::addr_t GetFaultAddress() const {
+ assert(GetKind() == eCrashMessage);
+ return m_addr;
+ }
+
+ lldb::addr_t GetHWAddress() const {
+ assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
+ return m_addr;
+ }
+
+ lldb::tid_t GetChildTID() const {
+ assert(GetKind() == eNewThreadMessage);
+ return m_child_tid;
+ }
+
+ const char *PrintCrashReason() const;
+
+ const char *PrintKind() const;
+
+ static const char *PrintKind(Kind);
private:
- ProcessMessage(lldb::tid_t tid, Kind kind,
- int status = 0, lldb::addr_t addr = 0)
- : m_tid(tid),
- m_kind(kind),
- m_crash_reason(CrashReason::eInvalidCrashReason),
- m_status(status),
- m_addr(addr),
- m_child_tid(0) { }
-
- ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
- : m_tid(tid),
- m_kind(kind),
- m_crash_reason(CrashReason::eInvalidCrashReason),
- m_status(0),
- m_addr(0),
- m_child_tid(child_tid) { }
-
- lldb::tid_t m_tid;
- Kind m_kind : 8;
- CrashReason m_crash_reason;
- int m_status;
- lldb::addr_t m_addr;
- lldb::tid_t m_child_tid;
+ ProcessMessage(lldb::tid_t tid, Kind kind, int status = 0,
+ lldb::addr_t addr = 0)
+ : m_tid(tid), m_kind(kind),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(status),
+ m_addr(addr), m_child_tid(0) {}
+
+ ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
+ : m_tid(tid), m_kind(kind),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0),
+ m_addr(0), m_child_tid(child_tid) {}
+
+ lldb::tid_t m_tid;
+ Kind m_kind : 8;
+ CrashReason m_crash_reason;
+ int m_status;
+ lldb::addr_t m_addr;
+ lldb::tid_t m_child_tid;
};
#endif // #ifndef liblldb_ProcessMessage_H_
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
index b259804a3a27..9ced11c7ca2a 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
+++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
@@ -1,4 +1,5 @@
-//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -*-===//
+//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,199 +12,185 @@
#include <mutex>
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
#include "ProcessPOSIXLog.h"
using namespace lldb;
using namespace lldb_private;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_log_sp the first time this function is
+// that will construct the static g_log_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = NULL;
-static Log *
-GetLog ()
-{
- if (!g_log_enabled)
- return NULL;
- return g_log;
+static Log *g_log = NULL;
+static Log *GetLog() {
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-void
-ProcessPOSIXLog::Initialize(ConstString name)
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, [name](){
- Log::Callbacks log_callbacks = {
- DisableLog,
- EnableLog,
- ListLogCategories
- };
-
- Log::RegisterLogChannel (name, log_callbacks);
- RegisterPluginName(name);
- });
-}
+void ProcessPOSIXLog::Initialize(ConstString name) {
+ static std::once_flag g_once_flag;
-Log *
-ProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && mask)
- {
- uint32_t log_mask = log->GetMask().Get();
- if ((log_mask & mask) != mask)
- return NULL;
- }
- return log;
+ std::call_once(g_once_flag, [name]() {
+ Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
+
+ Log::RegisterLogChannel(name, log_callbacks);
+ RegisterPluginName(name);
+ });
}
-static uint32_t
-GetFlagBits (const char *arg)
-{
- if (::strcasecmp (arg, "all") == 0 ) return POSIX_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) return POSIX_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) return POSIX_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) return POSIX_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) return POSIX_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) return POSIX_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) return POSIX_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) return POSIX_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) return POSIX_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) return POSIX_LOG_PROCESS;
- else if (::strcasecmp (arg, "ptrace") == 0 ) return POSIX_LOG_PTRACE;
- else if (::strcasecmp (arg, "registers") == 0 ) return POSIX_LOG_REGISTERS;
- else if (::strcasecmp (arg, "step") == 0 ) return POSIX_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) return POSIX_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) return POSIX_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) return POSIX_LOG_WATCHPOINTS;
- return 0;
+Log *ProcessPOSIXLog::GetLogIfAllCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && mask) {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return NULL;
+ }
+ return log;
}
-void
-ProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm)
-{
- Log *log (GetLog ());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- flag_bits = log->GetMask().Get();
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits &= ~bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- }
- }
-
- log->GetMask().Reset (flag_bits);
- if (flag_bits == 0)
- g_log_enabled = false;
- }
-
- return;
+static uint32_t GetFlagBits(const char *arg) {
+ if (::strcasecmp(arg, "all") == 0)
+ return POSIX_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ return POSIX_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ return POSIX_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ return POSIX_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ return POSIX_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ return POSIX_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ return POSIX_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ return POSIX_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ return POSIX_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ return POSIX_LOG_PROCESS;
+ else if (::strcasecmp(arg, "ptrace") == 0)
+ return POSIX_LOG_PTRACE;
+ else if (::strcasecmp(arg, "registers") == 0)
+ return POSIX_LOG_REGISTERS;
+ else if (::strcasecmp(arg, "step") == 0)
+ return POSIX_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ return POSIX_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ return POSIX_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ return POSIX_LOG_WATCHPOINTS;
+ return 0;
}
-Log *
-ProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
+void ProcessPOSIXLog::DisableLog(const char **args, Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
+
+ flag_bits = log->GetMask().Get();
+ for (; args && args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits &= ~bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
+ }
}
+ log->GetMask().Reset(flag_bits);
+ if (flag_bits == 0)
+ g_log_enabled = false;
+ }
+
+ return;
+}
+
+Log *ProcessPOSIXLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **args, Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits |= bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (; args && args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits |= bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = POSIX_LOG_DEFAULT;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
- g_log_enabled = true;
+ }
}
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = POSIX_LOG_DEFAULT;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ g_log_enabled = true;
+ }
+ return g_log;
}
-void
-ProcessPOSIXLog::ListLogCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " async - log asynchronous activity\n"
- " break - log breakpoints\n"
- " communication - log communication activity\n"
- " default - enable the default set of logging categories for liblldb\n"
- " packets - log gdb remote packets\n"
- " memory - log memory reads and writes\n"
- " data-short - log memory bytes for memory reads and writes for short transactions only\n"
- " data-long - log memory bytes for memory reads and writes for all transactions\n"
- " process - log process events and activities\n"
+void ProcessPOSIXLog::ListLogCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " async - log asynchronous activity\n"
+ " break - log breakpoints\n"
+ " communication - log communication activity\n"
+ " default - enable the default set of logging categories for liblldb\n"
+ " packets - log gdb remote packets\n"
+ " memory - log memory reads and writes\n"
+ " data-short - log memory bytes for memory reads and writes for short "
+ "transactions only\n"
+ " data-long - log memory bytes for memory reads and writes for all "
+ "transactions\n"
+ " process - log process events and activities\n"
#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- " ptrace - log all calls to ptrace\n"
+ " ptrace - log all calls to ptrace\n"
#endif
- " registers - log register read/writes\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n", ProcessPOSIXLog::m_pluginname);
+ " registers - log register read/writes\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n"
+ " watch - log watchpoint related activities\n",
+ ProcessPOSIXLog::m_pluginname);
}
-
-void
-ProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask));
- if (log)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void ProcessPOSIXLog::LogIf(uint32_t mask, const char *format, ...) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(mask));
+ if (log) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
int ProcessPOSIXLog::m_nestinglevel;
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
index 7edd839152e6..7d187da4e488 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
+++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
@@ -1,4 +1,5 @@
-//===-- ProcessPOSIXLog.h -----------------------------------------*- C++ -*-===//
+//===-- ProcessPOSIXLog.h -----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,101 +18,85 @@
// Project includes
#include "lldb/Core/Log.h"
-#define POSIX_LOG_VERBOSE (1u << 0)
-#define POSIX_LOG_PROCESS (1u << 1)
-#define POSIX_LOG_THREAD (1u << 2)
-#define POSIX_LOG_PACKETS (1u << 3)
-#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define POSIX_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
-#define POSIX_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define POSIX_LOG_BREAKPOINTS (1u << 7)
-#define POSIX_LOG_WATCHPOINTS (1u << 8)
-#define POSIX_LOG_STEP (1u << 9)
-#define POSIX_LOG_COMM (1u << 10)
-#define POSIX_LOG_ASYNC (1u << 11)
-#define POSIX_LOG_PTRACE (1u << 12)
-#define POSIX_LOG_REGISTERS (1u << 13)
-#define POSIX_LOG_ALL (UINT32_MAX)
-#define POSIX_LOG_DEFAULT POSIX_LOG_PACKETS
+#define POSIX_LOG_VERBOSE (1u << 0)
+#define POSIX_LOG_PROCESS (1u << 1)
+#define POSIX_LOG_THREAD (1u << 2)
+#define POSIX_LOG_PACKETS (1u << 3)
+#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define POSIX_LOG_MEMORY_DATA_SHORT \
+ (1u << 5) // Log short memory reads/writes bytes
+#define POSIX_LOG_MEMORY_DATA_LONG \
+ (1u << 6) // Log all memory reads/writes bytes
+#define POSIX_LOG_BREAKPOINTS (1u << 7)
+#define POSIX_LOG_WATCHPOINTS (1u << 8)
+#define POSIX_LOG_STEP (1u << 9)
+#define POSIX_LOG_COMM (1u << 10)
+#define POSIX_LOG_ASYNC (1u << 11)
+#define POSIX_LOG_PTRACE (1u << 12)
+#define POSIX_LOG_REGISTERS (1u << 13)
+#define POSIX_LOG_ALL (UINT32_MAX)
+#define POSIX_LOG_DEFAULT POSIX_LOG_PACKETS
// The size which determines "short memory reads/writes".
-#define POSIX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t))
+#define POSIX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t))
-class ProcessPOSIXLog
-{
- static int m_nestinglevel;
- static const char *m_pluginname;
+class ProcessPOSIXLog {
+ static int m_nestinglevel;
+ static const char *m_pluginname;
public:
- // ---------------------------------------------------------------------
- // Public Static Methods
- // ---------------------------------------------------------------------
- static void
- Initialize(lldb_private::ConstString name);
-
- static void
- RegisterPluginName(const char *pluginName)
- {
- m_pluginname = pluginName;
- }
-
- static void
- RegisterPluginName(lldb_private::ConstString pluginName)
- {
- m_pluginname = pluginName.GetCString();
- }
-
- static lldb_private::Log *
- GetLogIfAllCategoriesSet(uint32_t mask = 0);
-
- static void
- DisableLog (const char **args, lldb_private::Stream *feedback_strm);
-
- static lldb_private::Log *
- EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options,
- const char **args, lldb_private::Stream *feedback_strm);
-
- static void
- ListLogCategories (lldb_private::Stream *strm);
-
- static void
- LogIf (uint32_t mask, const char *format, ...);
-
- // The following functions can be used to enable the client to limit
- // logging to only the top level function calls. This is useful for
- // recursive functions. FIXME: not thread safe!
- // Example:
- // void NestingFunc() {
- // LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
- // if (log)
- // {
- // ProcessPOSIXLog::IncNestLevel();
- // if (ProcessPOSIXLog::AtTopNestLevel())
- // log->Print(msg);
- // }
- // NestingFunc();
- // if (log)
- // ProcessPOSIXLog::DecNestLevel();
- // }
-
- static bool
- AtTopNestLevel()
- {
- return m_nestinglevel == 1;
- }
-
- static void
- IncNestLevel()
- {
- ++m_nestinglevel;
- }
-
- static void
- DecNestLevel()
- {
- --m_nestinglevel;
- assert(m_nestinglevel >= 0);
- }
+ // ---------------------------------------------------------------------
+ // Public Static Methods
+ // ---------------------------------------------------------------------
+ static void Initialize(lldb_private::ConstString name);
+
+ static void RegisterPluginName(const char *pluginName) {
+ m_pluginname = pluginName;
+ }
+
+ static void RegisterPluginName(lldb_private::ConstString pluginName) {
+ m_pluginname = pluginName.GetCString();
+ }
+
+ static lldb_private::Log *GetLogIfAllCategoriesSet(uint32_t mask = 0);
+
+ static void DisableLog(const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp,
+ uint32_t log_options, const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static void ListLogCategories(lldb_private::Stream *strm);
+
+ static void LogIf(uint32_t mask, const char *format, ...);
+
+ // The following functions can be used to enable the client to limit
+ // logging to only the top level function calls. This is useful for
+ // recursive functions. FIXME: not thread safe!
+ // Example:
+ // void NestingFunc() {
+ // LogSP log
+ // (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
+ // if (log)
+ // {
+ // ProcessPOSIXLog::IncNestLevel();
+ // if (ProcessPOSIXLog::AtTopNestLevel())
+ // log->Print(msg);
+ // }
+ // NestingFunc();
+ // if (log)
+ // ProcessPOSIXLog::DecNestLevel();
+ // }
+
+ static bool AtTopNestLevel() { return m_nestinglevel == 1; }
+
+ static void IncNestLevel() { ++m_nestinglevel; }
+
+ static void DecNestLevel() {
+ --m_nestinglevel;
+ assert(m_nestinglevel >= 0);
+ }
};
-#endif // liblldb_ProcessPOSIXLog_h_
+#endif // liblldb_ProcessPOSIXLog_h_
diff --git a/source/Plugins/Process/Utility/ARMDefines.h b/source/Plugins/Process/Utility/ARMDefines.h
index cfb33beb447a..84c2cf19be7b 100644
--- a/source/Plugins/Process/Utility/ARMDefines.h
+++ b/source/Plugins/Process/Utility/ARMDefines.h
@@ -10,101 +10,150 @@
#ifndef lldb_ARMDefines_h_
#define lldb_ARMDefines_h_
+#include <cassert>
+#include <cstdint>
+
// Common definitions for the ARM/Thumb Instruction Set Architecture.
namespace lldb_private {
// ARM shifter types
-typedef enum
-{
- SRType_LSL,
- SRType_LSR,
- SRType_ASR,
- SRType_ROR,
- SRType_RRX,
- SRType_Invalid
+typedef enum {
+ SRType_LSL,
+ SRType_LSR,
+ SRType_ASR,
+ SRType_ROR,
+ SRType_RRX,
+ SRType_Invalid
} ARM_ShifterType;
-// ARM conditions // Meaning (integer) Meaning (floating-point) Condition flags
-#define COND_EQ 0x0 // Equal Equal Z == 1
-#define COND_NE 0x1 // Not equal Not equal, or unordered Z == 0
-#define COND_CS 0x2 // Carry set >, ==, or unordered C == 1
-#define COND_HS 0x2
-#define COND_CC 0x3 // Carry clear Less than C == 0
-#define COND_LO 0x3
-#define COND_MI 0x4 // Minus, negative Less than N == 1
-#define COND_PL 0x5 // Plus, positive or zero >, ==, or unordered N == 0
-#define COND_VS 0x6 // Overflow Unordered V == 1
-#define COND_VC 0x7 // No overflow Not unordered V == 0
-#define COND_HI 0x8 // Unsigned higher Greater than, or unordered C == 1 and Z == 0
-#define COND_LS 0x9 // Unsigned lower or same Less than or equal C == 0 or Z == 1
-#define COND_GE 0xA // Greater than or equal Greater than or equal N == V
-#define COND_LT 0xB // Less than Less than, or unordered N != V
-#define COND_GT 0xC // Greater than Greater than Z == 0 and N == V
-#define COND_LE 0xD // Less than or equal <, ==, or unordered Z == 1 or N != V
-#define COND_AL 0xE // Always (unconditional) Always (unconditional) Any
+// ARM conditions // Meaning (integer) Meaning (floating-point)
+// Condition flags
+#define COND_EQ \
+ 0x0 // Equal Equal Z == 1
+#define COND_NE \
+ 0x1 // Not equal Not equal, or unordered Z == 0
+#define COND_CS \
+ 0x2 // Carry set >, ==, or unordered C == 1
+#define COND_HS 0x2
+#define COND_CC \
+ 0x3 // Carry clear Less than C == 0
+#define COND_LO 0x3
+#define COND_MI \
+ 0x4 // Minus, negative Less than N == 1
+#define COND_PL \
+ 0x5 // Plus, positive or zero >, ==, or unordered N == 0
+#define COND_VS \
+ 0x6 // Overflow Unordered V == 1
+#define COND_VC \
+ 0x7 // No overflow Not unordered V == 0
+#define COND_HI \
+ 0x8 // Unsigned higher Greater than, or unordered C == 1 and Z ==
+ // 0
+#define COND_LS \
+ 0x9 // Unsigned lower or same Less than or equal C == 0 or Z ==
+ // 1
+#define COND_GE \
+ 0xA // Greater than or equal Greater than or equal N == V
+#define COND_LT \
+ 0xB // Less than Less than, or unordered N != V
+#define COND_GT \
+ 0xC // Greater than Greater than Z == 0 and N ==
+ // V
+#define COND_LE \
+ 0xD // Less than or equal <, ==, or unordered Z == 1 or N !=
+ // V
+#define COND_AL \
+ 0xE // Always (unconditional) Always (unconditional) Any
#define COND_UNCOND 0xF
-static inline const char *
-ARMCondCodeToString(uint32_t CC)
-{
- switch (CC) {
- default: assert(0 && "Unknown condition code");
- case COND_EQ: return "eq";
- case COND_NE: return "ne";
- case COND_HS: return "hs";
- case COND_LO: return "lo";
- case COND_MI: return "mi";
- case COND_PL: return "pl";
- case COND_VS: return "vs";
- case COND_VC: return "vc";
- case COND_HI: return "hi";
- case COND_LS: return "ls";
- case COND_GE: return "ge";
- case COND_LT: return "lt";
- case COND_GT: return "gt";
- case COND_LE: return "le";
- case COND_AL: return "al";
- }
+static inline const char *ARMCondCodeToString(uint32_t CC) {
+ switch (CC) {
+ default:
+ assert(0 && "Unknown condition code");
+ case COND_EQ:
+ return "eq";
+ case COND_NE:
+ return "ne";
+ case COND_HS:
+ return "hs";
+ case COND_LO:
+ return "lo";
+ case COND_MI:
+ return "mi";
+ case COND_PL:
+ return "pl";
+ case COND_VS:
+ return "vs";
+ case COND_VC:
+ return "vc";
+ case COND_HI:
+ return "hi";
+ case COND_LS:
+ return "ls";
+ case COND_GE:
+ return "ge";
+ case COND_LT:
+ return "lt";
+ case COND_GT:
+ return "gt";
+ case COND_LE:
+ return "le";
+ case COND_AL:
+ return "al";
+ }
}
-static inline bool
-ARMConditionPassed(const uint32_t condition, const uint32_t cpsr)
-{
- const uint32_t cpsr_n = (cpsr >> 31) & 1u; // Negative condition code flag
- const uint32_t cpsr_z = (cpsr >> 30) & 1u; // Zero condition code flag
- const uint32_t cpsr_c = (cpsr >> 29) & 1u; // Carry condition code flag
- const uint32_t cpsr_v = (cpsr >> 28) & 1u; // Overflow condition code flag
+static inline bool ARMConditionPassed(const uint32_t condition,
+ const uint32_t cpsr) {
+ const uint32_t cpsr_n = (cpsr >> 31) & 1u; // Negative condition code flag
+ const uint32_t cpsr_z = (cpsr >> 30) & 1u; // Zero condition code flag
+ const uint32_t cpsr_c = (cpsr >> 29) & 1u; // Carry condition code flag
+ const uint32_t cpsr_v = (cpsr >> 28) & 1u; // Overflow condition code flag
- switch (condition) {
- case COND_EQ: return (cpsr_z == 1);
- case COND_NE: return (cpsr_z == 0);
- case COND_CS: return (cpsr_c == 1);
- case COND_CC: return (cpsr_c == 0);
- case COND_MI: return (cpsr_n == 1);
- case COND_PL: return (cpsr_n == 0);
- case COND_VS: return (cpsr_v == 1);
- case COND_VC: return (cpsr_v == 0);
- case COND_HI: return ((cpsr_c == 1) && (cpsr_z == 0));
- case COND_LS: return ((cpsr_c == 0) || (cpsr_z == 1));
- case COND_GE: return (cpsr_n == cpsr_v);
- case COND_LT: return (cpsr_n != cpsr_v);
- case COND_GT: return ((cpsr_z == 0) && (cpsr_n == cpsr_v));
- case COND_LE: return ((cpsr_z == 1) || (cpsr_n != cpsr_v));
- case COND_AL:
- case COND_UNCOND:
- default:
- return true;
- }
- return false;
+ switch (condition) {
+ case COND_EQ:
+ return (cpsr_z == 1);
+ case COND_NE:
+ return (cpsr_z == 0);
+ case COND_CS:
+ return (cpsr_c == 1);
+ case COND_CC:
+ return (cpsr_c == 0);
+ case COND_MI:
+ return (cpsr_n == 1);
+ case COND_PL:
+ return (cpsr_n == 0);
+ case COND_VS:
+ return (cpsr_v == 1);
+ case COND_VC:
+ return (cpsr_v == 0);
+ case COND_HI:
+ return ((cpsr_c == 1) && (cpsr_z == 0));
+ case COND_LS:
+ return ((cpsr_c == 0) || (cpsr_z == 1));
+ case COND_GE:
+ return (cpsr_n == cpsr_v);
+ case COND_LT:
+ return (cpsr_n != cpsr_v);
+ case COND_GT:
+ return ((cpsr_z == 0) && (cpsr_n == cpsr_v));
+ case COND_LE:
+ return ((cpsr_z == 1) || (cpsr_n != cpsr_v));
+ case COND_AL:
+ case COND_UNCOND:
+ default:
+ return true;
+ }
+ return false;
}
// Bit positions for CPSR
-#define CPSR_T_POS 5
-#define CPSR_F_POS 6
-#define CPSR_I_POS 7
-#define CPSR_A_POS 8
-#define CPSR_E_POS 9
+#define CPSR_T_POS 5
+#define CPSR_F_POS 6
+#define CPSR_I_POS 7
+#define CPSR_A_POS 8
+#define CPSR_E_POS 9
#define CPSR_J_POS 24
#define CPSR_Q_POS 27
#define CPSR_V_POS 28
@@ -113,30 +162,30 @@ ARMConditionPassed(const uint32_t condition, const uint32_t cpsr)
#define CPSR_N_POS 31
// CPSR mode definitions
-#define CPSR_MODE_USR 0x10u
-#define CPSR_MODE_FIQ 0x11u
-#define CPSR_MODE_IRQ 0x12u
-#define CPSR_MODE_SVC 0x13u
-#define CPSR_MODE_ABT 0x17u
-#define CPSR_MODE_UND 0x1bu
-#define CPSR_MODE_SYS 0x1fu
-
+#define CPSR_MODE_USR 0x10u
+#define CPSR_MODE_FIQ 0x11u
+#define CPSR_MODE_IRQ 0x12u
+#define CPSR_MODE_SVC 0x13u
+#define CPSR_MODE_ABT 0x17u
+#define CPSR_MODE_UND 0x1bu
+#define CPSR_MODE_SYS 0x1fu
+
// Masks for CPSR
#define MASK_CPSR_MODE_MASK (0x0000001fu)
-#define MASK_CPSR_IT_MASK (0x0600fc00u)
-#define MASK_CPSR_T (1u << CPSR_T_POS)
-#define MASK_CPSR_F (1u << CPSR_F_POS)
-#define MASK_CPSR_I (1u << CPSR_I_POS)
-#define MASK_CPSR_A (1u << CPSR_A_POS)
-#define MASK_CPSR_E (1u << CPSR_E_POS)
-#define MASK_CPSR_GE_MASK (0x000f0000u)
-#define MASK_CPSR_J (1u << CPSR_J_POS)
-#define MASK_CPSR_Q (1u << CPSR_Q_POS)
-#define MASK_CPSR_V (1u << CPSR_V_POS)
-#define MASK_CPSR_C (1u << CPSR_C_POS)
-#define MASK_CPSR_Z (1u << CPSR_Z_POS)
-#define MASK_CPSR_N (1u << CPSR_N_POS)
+#define MASK_CPSR_IT_MASK (0x0600fc00u)
+#define MASK_CPSR_T (1u << CPSR_T_POS)
+#define MASK_CPSR_F (1u << CPSR_F_POS)
+#define MASK_CPSR_I (1u << CPSR_I_POS)
+#define MASK_CPSR_A (1u << CPSR_A_POS)
+#define MASK_CPSR_E (1u << CPSR_E_POS)
+#define MASK_CPSR_GE_MASK (0x000f0000u)
+#define MASK_CPSR_J (1u << CPSR_J_POS)
+#define MASK_CPSR_Q (1u << CPSR_Q_POS)
+#define MASK_CPSR_V (1u << CPSR_V_POS)
+#define MASK_CPSR_C (1u << CPSR_C_POS)
+#define MASK_CPSR_Z (1u << CPSR_Z_POS)
+#define MASK_CPSR_N (1u << CPSR_N_POS)
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_ARMDefines_h_
+#endif // lldb_ARMDefines_h_
diff --git a/source/Plugins/Process/Utility/ARMUtils.h b/source/Plugins/Process/Utility/ARMUtils.h
index b6ba3fea6928..2bbd519b246a 100644
--- a/source/Plugins/Process/Utility/ARMUtils.h
+++ b/source/Plugins/Process/Utility/ARMUtils.h
@@ -18,352 +18,335 @@
namespace lldb_private {
-static inline uint32_t Align(uint32_t val, uint32_t alignment)
-{
- return alignment * (val / alignment);
+static inline uint32_t Align(uint32_t val, uint32_t alignment) {
+ return alignment * (val / alignment);
}
-static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t)
-{
- switch (type)
- {
- default:
- //assert(0 && "Invalid shift type");
- case 0:
- shift_t = SRType_LSL;
- return imm5;
- case 1:
- shift_t = SRType_LSR;
- return (imm5 == 0 ? 32 : imm5);
- case 2:
- shift_t = SRType_ASR;
- return (imm5 == 0 ? 32 : imm5);
- case 3:
- if (imm5 == 0)
- {
- shift_t = SRType_RRX;
- return 1;
- }
- else
- {
- shift_t = SRType_ROR;
- return imm5;
- }
+static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5,
+ ARM_ShifterType &shift_t) {
+ switch (type) {
+ default:
+ // assert(0 && "Invalid shift type");
+ case 0:
+ shift_t = SRType_LSL;
+ return imm5;
+ case 1:
+ shift_t = SRType_LSR;
+ return (imm5 == 0 ? 32 : imm5);
+ case 2:
+ shift_t = SRType_ASR;
+ return (imm5 == 0 ? 32 : imm5);
+ case 3:
+ if (imm5 == 0) {
+ shift_t = SRType_RRX;
+ return 1;
+ } else {
+ shift_t = SRType_ROR;
+ return imm5;
}
- shift_t = SRType_Invalid;
- return UINT32_MAX;
-
+ }
+ shift_t = SRType_Invalid;
+ return UINT32_MAX;
}
// A8.6.35 CMP (register) -- Encoding T3
// Convenience function.
-static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t)
-{
- return DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
+static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode,
+ ARM_ShifterType &shift_t) {
+ return DecodeImmShift(Bits32(opcode, 5, 4),
+ Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6),
+ shift_t);
}
// A8.6.35 CMP (register) -- Encoding A1
// Convenience function.
-static inline uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t)
-{
- return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
+static inline uint32_t DecodeImmShiftARM(const uint32_t opcode,
+ ARM_ShifterType &shift_t) {
+ return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
}
-static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, const uint32_t imm5)
-{
- ARM_ShifterType dont_care;
- return DecodeImmShift(shift_t, imm5, dont_care);
+static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t,
+ const uint32_t imm5) {
+ ARM_ShifterType dont_care;
+ return DecodeImmShift(shift_t, imm5, dont_care);
}
-static inline ARM_ShifterType DecodeRegShift(const uint32_t type)
-{
- switch (type) {
- default:
- //assert(0 && "Invalid shift type");
- return SRType_Invalid;
- case 0:
- return SRType_LSL;
- case 1:
- return SRType_LSR;
- case 2:
- return SRType_ASR;
- case 3:
- return SRType_ROR;
- }
+static inline ARM_ShifterType DecodeRegShift(const uint32_t type) {
+ switch (type) {
+ default:
+ // assert(0 && "Invalid shift type");
+ return SRType_Invalid;
+ case 0:
+ return SRType_LSL;
+ case 1:
+ return SRType_LSR;
+ case 2:
+ return SRType_ASR;
+ case 3:
+ return SRType_ROR;
+ }
}
-static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0) {
- *success = false;
- return 0;
- }
- *success = true;
- carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0;
- return value << amount;
+static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0;
+ return value << amount;
}
-static inline uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = LSL_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
-}
-
-static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0) {
- *success = false;
- return 0;
- }
- *success = true;
- carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0;
- return value >> amount;
+static inline uint32_t LSL(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = LSL_C(value, amount, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = LSR_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0;
+ return value >> amount;
}
-static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0 || amount > 32) {
- *success = false;
- return 0;
- }
- *success = true;
- bool negative = BitIsSet(value, 31);
- if (amount <= 32)
- {
- carry_out = Bit32(value, amount - 1);
- int64_t extended = llvm::SignExtend64<32>(value);
- return UnsignedBits(extended, amount + 31, amount);
- }
- else
- {
- carry_out = (negative ? 1 : 0);
- return (negative ? 0xffffffff : 0);
- }
+static inline uint32_t LSR(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = LSR_C(value, amount, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = ASR_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0 || amount > 32) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ bool negative = BitIsSet(value, 31);
+ if (amount <= 32) {
+ carry_out = Bit32(value, amount - 1);
+ int64_t extended = llvm::SignExtend64<32>(value);
+ return UnsignedBits(extended, amount + 31, amount);
+ } else {
+ carry_out = (negative ? 1 : 0);
+ return (negative ? 0xffffffff : 0);
+ }
}
-static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0) {
- *success = false;
- return 0;
- }
- *success = true;
- uint32_t amt = amount % 32;
- uint32_t result = Rotr32(value, amt);
- carry_out = Bit32(value, 31);
+static inline uint32_t ASR(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = ASR_C(value, amount, dont_care, success);
+ if (*success)
return result;
+ else
+ return 0;
}
-static inline uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = ROR_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ uint32_t amt = amount % 32;
+ uint32_t result = Rotr32(value, amt);
+ carry_out = Bit32(value, 31);
+ return result;
}
-static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success)
-{
- *success = true;
- carry_out = Bit32(value, 0);
- return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1);
+static inline uint32_t ROR(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = ROR_C(value, amount, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success)
-{
- *success = true;
- uint32_t dont_care;
- uint32_t result = RRX_C(value, carry_in, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in,
+ uint32_t &carry_out, bool *success) {
+ *success = true;
+ carry_out = Bit32(value, 0);
+ return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1);
}
-static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
- const uint32_t carry_in, uint32_t &carry_out, bool *success)
-{
- if (type == SRType_RRX && amount != 1) {
- *success = false;
- return 0;
- }
- *success = true;
+static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in,
+ bool *success) {
+ *success = true;
+ uint32_t dont_care;
+ uint32_t result = RRX_C(value, carry_in, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
+}
- if (amount == 0) {
- carry_out = carry_in;
- return value;
- }
- uint32_t result;
- switch (type) {
- case SRType_LSL:
- result = LSL_C(value, amount, carry_out, success);
- break;
- case SRType_LSR:
- result = LSR_C(value, amount, carry_out, success);
- break;
- case SRType_ASR:
- result = ASR_C(value, amount, carry_out, success);
- break;
- case SRType_ROR:
- result = ROR_C(value, amount, carry_out, success);
- break;
- case SRType_RRX:
- result = RRX_C(value, carry_in, carry_out, success);
- break;
- default:
- *success = false;
- break;
- }
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type,
+ const uint32_t amount, const uint32_t carry_in,
+ uint32_t &carry_out, bool *success) {
+ if (type == SRType_RRX && amount != 1) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+
+ if (amount == 0) {
+ carry_out = carry_in;
+ return value;
+ }
+ uint32_t result;
+ switch (type) {
+ case SRType_LSL:
+ result = LSL_C(value, amount, carry_out, success);
+ break;
+ case SRType_LSR:
+ result = LSR_C(value, amount, carry_out, success);
+ break;
+ case SRType_ASR:
+ result = ASR_C(value, amount, carry_out, success);
+ break;
+ case SRType_ROR:
+ result = ROR_C(value, amount, carry_out, success);
+ break;
+ case SRType_RRX:
+ result = RRX_C(value, carry_in, carry_out, success);
+ break;
+ default:
+ *success = false;
+ break;
+ }
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
- const uint32_t carry_in, bool *success)
-{
- // Don't care about carry out in this case.
- uint32_t dont_care;
- uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type,
+ const uint32_t amount, const uint32_t carry_in,
+ bool *success) {
+ // Don't care about carry out in this case.
+ uint32_t dont_care;
+ uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
-{
- return Bits32(val, msbit, lsbit);
+static inline uint32_t bits(const uint32_t val, const uint32_t msbit,
+ const uint32_t lsbit) {
+ return Bits32(val, msbit, lsbit);
}
-static inline uint32_t bit(const uint32_t val, const uint32_t msbit)
-{
- return bits(val, msbit, msbit);
+static inline uint32_t bit(const uint32_t val, const uint32_t msbit) {
+ return bits(val, msbit, msbit);
}
-static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
-{
- uint32_t m = shift % N;
- return (val >> m) | (val << (N - m));
+static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift) {
+ uint32_t m = shift % N;
+ return (val >> m) | (val << (N - m));
}
// (imm32, carry_out) = ARMExpandImm_C(imm12, carry_in)
-static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
-{
- uint32_t imm32; // the expanded result
- uint32_t imm = bits(opcode, 7, 0); // immediate value
- uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount
- if (amt == 0)
- {
- imm32 = imm;
- carry_out = carry_in;
- }
- else
- {
- imm32 = ror(imm, 32, amt);
- carry_out = Bit32(imm32, 31);
- }
- return imm32;
+static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in,
+ uint32_t &carry_out) {
+ uint32_t imm32; // the expanded result
+ uint32_t imm = bits(opcode, 7, 0); // immediate value
+ uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount
+ if (amt == 0) {
+ imm32 = imm;
+ carry_out = carry_in;
+ } else {
+ imm32 = ror(imm, 32, amt);
+ carry_out = Bit32(imm32, 31);
+ }
+ return imm32;
}
-static inline uint32_t ARMExpandImm(uint32_t opcode)
-{
- // 'carry_in' argument to following function call does not affect the imm32 result.
- uint32_t carry_in = 0;
- uint32_t carry_out;
- return ARMExpandImm_C(opcode, carry_in, carry_out);
+static inline uint32_t ARMExpandImm(uint32_t opcode) {
+ // 'carry_in' argument to following function call does not affect the imm32
+ // result.
+ uint32_t carry_in = 0;
+ uint32_t carry_out;
+ return ARMExpandImm_C(opcode, carry_in, carry_out);
}
// (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in)
-static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
-{
- uint32_t imm32; // the expanded result
- const uint32_t i = bit(opcode, 26);
- const uint32_t imm3 = bits(opcode, 14, 12);
- const uint32_t abcdefgh = bits(opcode, 7, 0);
- const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
-
- if (bits(imm12, 11, 10) == 0)
- {
- switch (bits(imm12, 9, 8)) {
- default: // Keep static analyzer happy with a default case
- case 0:
- imm32 = abcdefgh;
- break;
-
- case 1:
- imm32 = abcdefgh << 16 | abcdefgh;
- break;
-
- case 2:
- imm32 = abcdefgh << 24 | abcdefgh << 8;
- break;
-
- case 3:
- imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
- break;
- }
- carry_out = carry_in;
- }
- else
- {
- const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0);
- imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7));
- carry_out = Bit32(imm32, 31);
+static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in,
+ uint32_t &carry_out) {
+ uint32_t imm32; // the expanded result
+ const uint32_t i = bit(opcode, 26);
+ const uint32_t imm3 = bits(opcode, 14, 12);
+ const uint32_t abcdefgh = bits(opcode, 7, 0);
+ const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
+
+ if (bits(imm12, 11, 10) == 0) {
+ switch (bits(imm12, 9, 8)) {
+ default: // Keep static analyzer happy with a default case
+ case 0:
+ imm32 = abcdefgh;
+ break;
+
+ case 1:
+ imm32 = abcdefgh << 16 | abcdefgh;
+ break;
+
+ case 2:
+ imm32 = abcdefgh << 24 | abcdefgh << 8;
+ break;
+
+ case 3:
+ imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
+ break;
}
- return imm32;
+ carry_out = carry_in;
+ } else {
+ const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0);
+ imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7));
+ carry_out = Bit32(imm32, 31);
+ }
+ return imm32;
}
-static inline uint32_t ThumbExpandImm(uint32_t opcode)
-{
- // 'carry_in' argument to following function call does not affect the imm32 result.
- uint32_t carry_in = 0;
- uint32_t carry_out;
- return ThumbExpandImm_C(opcode, carry_in, carry_out);
+static inline uint32_t ThumbExpandImm(uint32_t opcode) {
+ // 'carry_in' argument to following function call does not affect the imm32
+ // result.
+ uint32_t carry_in = 0;
+ uint32_t carry_out;
+ return ThumbExpandImm_C(opcode, carry_in, carry_out);
}
// imm32 = ZeroExtend(i:imm3:imm8, 32)
-static inline uint32_t ThumbImm12(uint32_t opcode)
-{
+static inline uint32_t ThumbImm12(uint32_t opcode) {
const uint32_t i = bit(opcode, 26);
const uint32_t imm3 = bits(opcode, 14, 12);
const uint32_t imm8 = bits(opcode, 7, 0);
@@ -372,15 +355,13 @@ static inline uint32_t ThumbImm12(uint32_t opcode)
}
// imm32 = ZeroExtend(imm7:'00', 32)
-static inline uint32_t ThumbImm7Scaled(uint32_t opcode)
-{
+static inline uint32_t ThumbImm7Scaled(uint32_t opcode) {
const uint32_t imm7 = bits(opcode, 6, 0);
return imm7 * 4;
}
// imm32 = ZeroExtend(imm8:'00', 32)
-static inline uint32_t ThumbImm8Scaled(uint32_t opcode)
-{
+static inline uint32_t ThumbImm8Scaled(uint32_t opcode) {
const uint32_t imm8 = bits(opcode, 7, 0);
return imm8 * 4;
}
@@ -389,6 +370,6 @@ static inline uint32_t ThumbImm8Scaled(uint32_t opcode)
// not permitted for many Thumb register specifiers.
static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_ARMUtils_h_
+#endif // lldb_ARMUtils_h_
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
index eb0c81fd7979..c557667e3910 100644
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/source/Plugins/Process/Utility/CMakeLists.txt
@@ -16,14 +16,12 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextDarwin_x86_64.cpp
RegisterContextDummy.cpp
RegisterContextFreeBSD_arm.cpp
- RegisterContextFreeBSD_arm64.cpp
RegisterContextFreeBSD_i386.cpp
RegisterContextFreeBSD_mips64.cpp
RegisterContextFreeBSD_powerpc.cpp
RegisterContextFreeBSD_x86_64.cpp
RegisterContextHistory.cpp
RegisterContextLinux_arm.cpp
- RegisterContextLinux_arm64.cpp
RegisterContextLinux_i386.cpp
RegisterContextLinux_x86_64.cpp
RegisterContextLinux_mips64.cpp
@@ -43,6 +41,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextPOSIX_s390x.cpp
RegisterContextPOSIX_x86.cpp
RegisterContextThreadMemory.cpp
+ RegisterInfoPOSIX_arm64.cpp
StopInfoMachException.cpp
ThreadMemory.cpp
UnwindLLDB.cpp
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 6efdb468111b..7c8c26047f85 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -24,788 +24,725 @@
using namespace lldb;
using namespace lldb_private;
-DynamicRegisterInfo::DynamicRegisterInfo () :
- m_regs (),
- m_sets (),
- m_set_reg_nums (),
- m_set_names (),
- m_value_regs_map (),
- m_invalidate_regs_map (),
- m_dynamic_reg_size_map (),
- m_reg_data_byte_size (0),
- m_finalized (false)
-{
+DynamicRegisterInfo::DynamicRegisterInfo()
+ : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
+ m_invalidate_regs_map(), m_dynamic_reg_size_map(),
+ m_reg_data_byte_size(0), m_finalized(false) {}
+
+DynamicRegisterInfo::DynamicRegisterInfo(
+ const lldb_private::StructuredData::Dictionary &dict,
+ const lldb_private::ArchSpec &arch)
+ : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
+ m_invalidate_regs_map(), m_dynamic_reg_size_map(),
+ m_reg_data_byte_size(0), m_finalized(false) {
+ SetRegisterInfo(dict, arch);
}
-DynamicRegisterInfo::DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
- const lldb_private::ArchSpec &arch) :
- m_regs (),
- m_sets (),
- m_set_reg_nums (),
- m_set_names (),
- m_value_regs_map (),
- m_invalidate_regs_map (),
- m_dynamic_reg_size_map (),
- m_reg_data_byte_size (0),
- m_finalized (false)
-{
- SetRegisterInfo (dict, arch);
-}
-
-DynamicRegisterInfo::~DynamicRegisterInfo ()
-{
-}
+DynamicRegisterInfo::~DynamicRegisterInfo() {}
size_t
-DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch)
-{
- assert(!m_finalized);
- StructuredData::Array *sets = nullptr;
- if (dict.GetValueForKeyAsArray("sets", sets))
- {
- const uint32_t num_sets = sets->GetSize();
- for (uint32_t i=0; i<num_sets; ++i)
- {
- std::string set_name_str;
- ConstString set_name;
- if (sets->GetItemAtIndexAsString(i, set_name_str))
- set_name.SetCString(set_name_str.c_str());
- if (set_name)
- {
- RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
- m_sets.push_back (new_set);
- }
- else
- {
- Clear();
- printf("error: register sets must have valid names\n");
- return 0;
- }
- }
- m_set_reg_nums.resize(m_sets.size());
- }
- StructuredData::Array *regs = nullptr;
- if (!dict.GetValueForKeyAsArray("registers", regs))
+DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
+ const ArchSpec &arch) {
+ assert(!m_finalized);
+ StructuredData::Array *sets = nullptr;
+ if (dict.GetValueForKeyAsArray("sets", sets)) {
+ const uint32_t num_sets = sets->GetSize();
+ for (uint32_t i = 0; i < num_sets; ++i) {
+ std::string set_name_str;
+ ConstString set_name;
+ if (sets->GetItemAtIndexAsString(i, set_name_str))
+ set_name.SetCString(set_name_str.c_str());
+ if (set_name) {
+ RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
+ m_sets.push_back(new_set);
+ } else {
+ Clear();
+ printf("error: register sets must have valid names\n");
return 0;
+ }
+ }
+ m_set_reg_nums.resize(m_sets.size());
+ }
+ StructuredData::Array *regs = nullptr;
+ if (!dict.GetValueForKeyAsArray("registers", regs))
+ return 0;
+
+ const uint32_t num_regs = regs->GetSize();
+ // typedef std::map<std::string, std::vector<std::string> >
+ // InvalidateNameMap;
+ // InvalidateNameMap invalidate_map;
+ for (uint32_t i = 0; i < num_regs; ++i) {
+ StructuredData::Dictionary *reg_info_dict = nullptr;
+ if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict)) {
+ Clear();
+ printf("error: items in the 'registers' array must be dictionaries\n");
+ regs->DumpToStdout();
+ return 0;
+ }
- const uint32_t num_regs = regs->GetSize();
-// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap;
-// InvalidateNameMap invalidate_map;
- for (uint32_t i = 0; i < num_regs; ++i)
- {
- StructuredData::Dictionary *reg_info_dict = nullptr;
- if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict))
- {
- Clear();
- printf("error: items in the 'registers' array must be dictionaries\n");
- regs->DumpToStdout();
- return 0;
- }
-
- // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2,
- // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
- RegisterInfo reg_info;
- std::vector<uint32_t> value_regs;
- std::vector<uint32_t> invalidate_regs;
- memset(&reg_info, 0, sizeof(reg_info));
-
- ConstString name_val;
- ConstString alt_name_val;
- if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr))
- {
- Clear();
- printf("error: registers must have valid names and offsets\n");
- reg_info_dict->DumpToStdout();
- return 0;
- }
- reg_info.name = name_val.GetCString();
- reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
- reg_info.alt_name = alt_name_val.GetCString();
-
- reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, UINT32_MAX);
-
- const ByteOrder byte_order = arch.GetByteOrder();
-
- if (reg_info.byte_offset == UINT32_MAX)
- {
- // No offset for this register, see if the register has a value expression
- // which indicates this register is part of another register. Value expressions
- // are things like "rax[31:0]" which state that the current register's value
- // is in a concrete register "rax" in bits 31:0. If there is a value expression
- // we can calculate the offset
- bool success = false;
- std::string slice_str;
- if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr))
- {
- // Slices use the following format:
- // REGNAME[MSBIT:LSBIT]
- // REGNAME - name of the register to grab a slice of
- // MSBIT - the most significant bit at which the current register value starts at
- // LSBIT - the least significant bit at which the current register value ends at
- static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
- RegularExpression::Match regex_match(3);
- if (g_bitfield_regex.Execute(slice_str.c_str(), &regex_match))
- {
- llvm::StringRef reg_name_str;
- std::string msbit_str;
- std::string lsbit_str;
- if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
- regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
- regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str))
- {
- const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
- const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
- if (msbit != UINT32_MAX && lsbit != UINT32_MAX)
- {
- if (msbit > lsbit)
- {
- const uint32_t msbyte = msbit / 8;
- const uint32_t lsbyte = lsbit / 8;
-
- ConstString containing_reg_name(reg_name_str);
-
- RegisterInfo *containing_reg_info = GetRegisterInfo(containing_reg_name);
- if (containing_reg_info)
- {
- const uint32_t max_bit = containing_reg_info->byte_size * 8;
- if (msbit < max_bit && lsbit < max_bit)
- {
- m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
- m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
-
- if (byte_order == eByteOrderLittle)
- {
- success = true;
- reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte;
- }
- else if (byte_order == eByteOrderBig)
- {
- success = true;
- reg_info.byte_offset = containing_reg_info->byte_offset + msbyte;
- }
- else
- {
- assert(!"Invalid byte order");
- }
- }
- else
- {
- if (msbit > max_bit)
- printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit,
- max_bit);
- else
- printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit,
- max_bit);
- }
- }
- else
- {
- printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString());
- }
- }
- else
- {
- printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit);
- }
- }
- else
- {
- printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit);
- }
+ // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint'
+ // , 'format':'hex' , 'set': 0, 'ehframe' : 2,
+ // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
+ RegisterInfo reg_info;
+ std::vector<uint32_t> value_regs;
+ std::vector<uint32_t> invalidate_regs;
+ memset(&reg_info, 0, sizeof(reg_info));
+
+ ConstString name_val;
+ ConstString alt_name_val;
+ if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) {
+ Clear();
+ printf("error: registers must have valid names and offsets\n");
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
+ reg_info.name = name_val.GetCString();
+ reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
+ reg_info.alt_name = alt_name_val.GetCString();
+
+ reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset,
+ UINT32_MAX);
+
+ const ByteOrder byte_order = arch.GetByteOrder();
+
+ if (reg_info.byte_offset == UINT32_MAX) {
+ // No offset for this register, see if the register has a value expression
+ // which indicates this register is part of another register. Value
+ // expressions
+ // are things like "rax[31:0]" which state that the current register's
+ // value
+ // is in a concrete register "rax" in bits 31:0. If there is a value
+ // expression
+ // we can calculate the offset
+ bool success = false;
+ std::string slice_str;
+ if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) {
+ // Slices use the following format:
+ // REGNAME[MSBIT:LSBIT]
+ // REGNAME - name of the register to grab a slice of
+ // MSBIT - the most significant bit at which the current register value
+ // starts at
+ // LSBIT - the least significant bit at which the current register value
+ // ends at
+ static RegularExpression g_bitfield_regex(
+ llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"));
+ RegularExpression::Match regex_match(3);
+ if (g_bitfield_regex.Execute(slice_str, &regex_match)) {
+ llvm::StringRef reg_name_str;
+ std::string msbit_str;
+ std::string lsbit_str;
+ if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
+ regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
+ regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str)) {
+ const uint32_t msbit =
+ StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
+ const uint32_t lsbit =
+ StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
+ if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
+ if (msbit > lsbit) {
+ const uint32_t msbyte = msbit / 8;
+ const uint32_t lsbyte = lsbit / 8;
+
+ ConstString containing_reg_name(reg_name_str);
+
+ RegisterInfo *containing_reg_info =
+ GetRegisterInfo(containing_reg_name);
+ if (containing_reg_info) {
+ const uint32_t max_bit = containing_reg_info->byte_size * 8;
+ if (msbit < max_bit && lsbit < max_bit) {
+ m_invalidate_regs_map[containing_reg_info
+ ->kinds[eRegisterKindLLDB]]
+ .push_back(i);
+ m_value_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+
+ if (byte_order == eByteOrderLittle) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + lsbyte;
+ } else if (byte_order == eByteOrderBig) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + msbyte;
+ } else {
+ assert(!"Invalid byte order");
}
+ } else {
+ if (msbit > max_bit)
+ printf("error: msbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ msbit, max_bit);
else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to extract regex matches for parsing the register bitfield regex\n");
- }
- }
- else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to match against register bitfield regex\n");
+ printf("error: lsbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ lsbit, max_bit);
+ }
+ } else {
+ printf("error: invalid concrete register \"%s\"\n",
+ containing_reg_name.GetCString());
}
+ } else {
+ printf("error: msbit (%u) must be greater than lsbit (%u)\n",
+ msbit, lsbit);
+ }
+ } else {
+ printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
+ lsbit);
}
- else
- {
- StructuredData::Array *composite_reg_list = nullptr;
- if (reg_info_dict->GetValueForKeyAsArray("composite", composite_reg_list))
- {
- const size_t num_composite_regs = composite_reg_list->GetSize();
- if (num_composite_regs > 0)
- {
- uint32_t composite_offset = UINT32_MAX;
- for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; ++composite_idx)
- {
- ConstString composite_reg_name;
- if (composite_reg_list->GetItemAtIndexAsString(composite_idx, composite_reg_name, nullptr))
- {
- RegisterInfo *composite_reg_info = GetRegisterInfo(composite_reg_name);
- if (composite_reg_info)
- {
- composite_offset = std::min(composite_offset, composite_reg_info->byte_offset);
- m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
- m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
- }
- else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString());
- }
- }
- else
- {
- printf("error: 'composite' list value wasn't a python string\n");
- }
- }
- if (composite_offset != UINT32_MAX)
- {
- reg_info.byte_offset = composite_offset;
- success = m_value_regs_map.find(i) != m_value_regs_map.end();
- }
- else
- {
- printf("error: 'composite' registers must specify at least one real register\n");
- }
- }
- else
- {
- printf("error: 'composite' list was empty\n");
- }
+ } else {
+ // TODO: print error invalid slice string that doesn't follow the
+ // format
+ printf("error: failed to extract regex matches for parsing the "
+ "register bitfield regex\n");
+ }
+ } else {
+ // TODO: print error invalid slice string that doesn't follow the
+ // format
+ printf("error: failed to match against register bitfield regex\n");
+ }
+ } else {
+ StructuredData::Array *composite_reg_list = nullptr;
+ if (reg_info_dict->GetValueForKeyAsArray("composite",
+ composite_reg_list)) {
+ const size_t num_composite_regs = composite_reg_list->GetSize();
+ if (num_composite_regs > 0) {
+ uint32_t composite_offset = UINT32_MAX;
+ for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
+ ++composite_idx) {
+ ConstString composite_reg_name;
+ if (composite_reg_list->GetItemAtIndexAsString(
+ composite_idx, composite_reg_name, nullptr)) {
+ RegisterInfo *composite_reg_info =
+ GetRegisterInfo(composite_reg_name);
+ if (composite_reg_info) {
+ composite_offset = std::min(composite_offset,
+ composite_reg_info->byte_offset);
+ m_value_regs_map[i].push_back(
+ composite_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[composite_reg_info
+ ->kinds[eRegisterKindLLDB]]
+ .push_back(i);
+ m_invalidate_regs_map[i].push_back(
+ composite_reg_info->kinds[eRegisterKindLLDB]);
+ } else {
+ // TODO: print error invalid slice string that doesn't follow
+ // the format
+ printf("error: failed to find composite register by name: "
+ "\"%s\"\n",
+ composite_reg_name.GetCString());
}
+ } else {
+ printf(
+ "error: 'composite' list value wasn't a python string\n");
+ }
}
-
- if (!success)
- {
- Clear();
- reg_info_dict->DumpToStdout();
- return 0;
+ if (composite_offset != UINT32_MAX) {
+ reg_info.byte_offset = composite_offset;
+ success = m_value_regs_map.find(i) != m_value_regs_map.end();
+ } else {
+ printf("error: 'composite' registers must specify at least one "
+ "real register\n");
}
+ } else {
+ printf("error: 'composite' list was empty\n");
+ }
}
+ }
- int64_t bitsize = 0;
- if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize))
- {
- Clear();
- printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n");
- reg_info_dict->DumpToStdout();
- return 0;
- }
-
- reg_info.byte_size = bitsize / 8;
-
- std::string dwarf_opcode_string;
- if (reg_info_dict->GetValueForKeyAsString ("dynamic_size_dwarf_expr_bytes", dwarf_opcode_string))
- {
- reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.length () / 2;
- assert (reg_info.dynamic_size_dwarf_len > 0);
-
- std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
- uint32_t j;
- StringExtractor opcode_extractor;
- // Swap "dwarf_opcode_string" over into "opcode_extractor"
- opcode_extractor.GetStringRef ().swap (dwarf_opcode_string);
- uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (),
- reg_info.dynamic_size_dwarf_len);
- assert (ret_val == reg_info.dynamic_size_dwarf_len);
-
- for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j)
- m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]);
+ if (!success) {
+ Clear();
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
+ }
- reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data ();
- }
+ int64_t bitsize = 0;
+ if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
+ Clear();
+ printf("error: invalid or missing 'bitsize' key/value pair in register "
+ "dictionary\n");
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
- std::string format_str;
- if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr))
- {
- if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL).Fail())
- {
- Clear();
- printf("error: invalid 'format' value in register dictionary\n");
- reg_info_dict->DumpToStdout();
- return 0;
- }
- }
- else
- {
- reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format, eFormatHex);
- }
+ reg_info.byte_size = bitsize / 8;
- std::string encoding_str;
- if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
- reg_info.encoding = Args::StringToEncoding(encoding_str.c_str(), eEncodingUint);
- else
- reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding, eEncodingUint);
-
- size_t set = 0;
- if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) || set >= m_sets.size())
- {
- Clear();
- printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set);
- reg_info_dict->DumpToStdout();
- return 0;
- }
+ std::string dwarf_opcode_string;
+ if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes",
+ dwarf_opcode_string)) {
+ reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.length() / 2;
+ assert(reg_info.dynamic_size_dwarf_len > 0);
- // Fill in the register numbers
- reg_info.kinds[lldb::eRegisterKindLLDB] = i;
- reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
- uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
- reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno, LLDB_INVALID_REGNUM);
- if (eh_frame_regno == LLDB_INVALID_REGNUM)
- reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno, LLDB_INVALID_REGNUM);
- reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
- reg_info_dict->GetValueForKeyAsInteger("dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
- std::string generic_str;
- if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
- reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_str());
- else
- reg_info_dict->GetValueForKeyAsInteger("generic", reg_info.kinds[lldb::eRegisterKindGeneric], LLDB_INVALID_REGNUM);
-
- // Check if this register invalidates any other register values when it is modified
- StructuredData::Array *invalidate_reg_list = nullptr;
- if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", invalidate_reg_list))
- {
- const size_t num_regs = invalidate_reg_list->GetSize();
- if (num_regs > 0)
- {
- for (uint32_t idx = 0; idx < num_regs; ++idx)
- {
- ConstString invalidate_reg_name;
- uint64_t invalidate_reg_num;
- if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name))
- {
- RegisterInfo *invalidate_reg_info = GetRegisterInfo(invalidate_reg_name);
- if (invalidate_reg_info)
- {
- m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]);
- }
- else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n",
- invalidate_reg_name.GetCString(), reg_info.name);
- }
- }
- else if (invalidate_reg_list->GetItemAtIndexAsInteger(idx, invalidate_reg_num))
- {
- if (invalidate_reg_num != UINT64_MAX)
- m_invalidate_regs_map[i].push_back(invalidate_reg_num);
- else
- printf("error: 'invalidate-regs' list value wasn't a valid integer\n");
- }
- else
- {
- printf("error: 'invalidate-regs' list value wasn't a python string or integer\n");
- }
- }
- }
- else
- {
- printf("error: 'invalidate-regs' contained an empty list\n");
- }
- }
+ std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
+ uint32_t j;
+ StringExtractor opcode_extractor;
+ // Swap "dwarf_opcode_string" over into "opcode_extractor"
+ opcode_extractor.GetStringRef().swap(dwarf_opcode_string);
+ uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+ assert(ret_val == reg_info.dynamic_size_dwarf_len);
- // Calculate the register offset
- const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
- if (m_reg_data_byte_size < end_reg_offset)
- m_reg_data_byte_size = end_reg_offset;
+ for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j)
+ m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]);
- m_regs.push_back(reg_info);
- m_set_reg_nums[set].push_back(i);
+ reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data();
}
- Finalize(arch);
- return m_regs.size();
-}
-
-void
-DynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
- ConstString &reg_name,
- ConstString &reg_alt_name,
- ConstString &set_name)
-{
- assert(!m_finalized);
- const uint32_t reg_num = m_regs.size();
- reg_info.name = reg_name.AsCString();
- assert (reg_info.name);
- reg_info.alt_name = reg_alt_name.AsCString(NULL);
- uint32_t i;
- if (reg_info.value_regs)
- {
- for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
- m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
+ std::string format_str;
+ if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
+ if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL)
+ .Fail()) {
+ Clear();
+ printf("error: invalid 'format' value in register dictionary\n");
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
+ } else {
+ reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format,
+ eFormatHex);
}
- if (reg_info.invalidate_regs)
- {
- for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
- m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
+
+ std::string encoding_str;
+ if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
+ reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint);
+ else
+ reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding,
+ eEncodingUint);
+
+ size_t set = 0;
+ if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) ||
+ set >= m_sets.size()) {
+ Clear();
+ printf("error: invalid 'set' value in register dictionary, valid values "
+ "are 0 - %i\n",
+ (int)set);
+ reg_info_dict->DumpToStdout();
+ return 0;
}
- if (reg_info.dynamic_size_dwarf_expr_bytes)
- {
- for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i)
- m_dynamic_reg_size_map[reg_num].push_back(reg_info.dynamic_size_dwarf_expr_bytes[i]);
- reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[reg_num].data ();
+ // Fill in the register numbers
+ reg_info.kinds[lldb::eRegisterKindLLDB] = i;
+ reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
+ uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
+ reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno,
+ LLDB_INVALID_REGNUM);
+ if (eh_frame_regno == LLDB_INVALID_REGNUM)
+ reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno,
+ LLDB_INVALID_REGNUM);
+ reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
+ reg_info_dict->GetValueForKeyAsInteger(
+ "dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
+ std::string generic_str;
+ if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
+ reg_info.kinds[lldb::eRegisterKindGeneric] =
+ Args::StringToGenericRegister(generic_str);
+ else
+ reg_info_dict->GetValueForKeyAsInteger(
+ "generic", reg_info.kinds[lldb::eRegisterKindGeneric],
+ LLDB_INVALID_REGNUM);
+
+ // Check if this register invalidates any other register values when it is
+ // modified
+ StructuredData::Array *invalidate_reg_list = nullptr;
+ if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs",
+ invalidate_reg_list)) {
+ const size_t num_regs = invalidate_reg_list->GetSize();
+ if (num_regs > 0) {
+ for (uint32_t idx = 0; idx < num_regs; ++idx) {
+ ConstString invalidate_reg_name;
+ uint64_t invalidate_reg_num;
+ if (invalidate_reg_list->GetItemAtIndexAsString(
+ idx, invalidate_reg_name)) {
+ RegisterInfo *invalidate_reg_info =
+ GetRegisterInfo(invalidate_reg_name);
+ if (invalidate_reg_info) {
+ m_invalidate_regs_map[i].push_back(
+ invalidate_reg_info->kinds[eRegisterKindLLDB]);
+ } else {
+ // TODO: print error invalid slice string that doesn't follow the
+ // format
+ printf("error: failed to find a 'invalidate-regs' register for "
+ "\"%s\" while parsing register \"%s\"\n",
+ invalidate_reg_name.GetCString(), reg_info.name);
+ }
+ } else if (invalidate_reg_list->GetItemAtIndexAsInteger(
+ idx, invalidate_reg_num)) {
+ if (invalidate_reg_num != UINT64_MAX)
+ m_invalidate_regs_map[i].push_back(invalidate_reg_num);
+ else
+ printf("error: 'invalidate-regs' list value wasn't a valid "
+ "integer\n");
+ } else {
+ printf("error: 'invalidate-regs' list value wasn't a python string "
+ "or integer\n");
+ }
+ }
+ } else {
+ printf("error: 'invalidate-regs' contained an empty list\n");
+ }
}
- m_regs.push_back (reg_info);
- uint32_t set = GetRegisterSetIndexByName (set_name, true);
- assert (set < m_sets.size());
- assert (set < m_set_reg_nums.size());
- assert (set < m_set_names.size());
- m_set_reg_nums[set].push_back(reg_num);
- size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
+ // Calculate the register offset
+ const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
if (m_reg_data_byte_size < end_reg_offset)
- m_reg_data_byte_size = end_reg_offset;
+ m_reg_data_byte_size = end_reg_offset;
+
+ m_regs.push_back(reg_info);
+ m_set_reg_nums[set].push_back(i);
+ }
+ Finalize(arch);
+ return m_regs.size();
}
-void
-DynamicRegisterInfo::Finalize (const ArchSpec &arch)
-{
- if (m_finalized)
- return;
-
- m_finalized = true;
- const size_t num_sets = m_sets.size();
- for (size_t set = 0; set < num_sets; ++set)
- {
- assert (m_sets.size() == m_set_reg_nums.size());
- m_sets[set].num_registers = m_set_reg_nums[set].size();
- m_sets[set].registers = &m_set_reg_nums[set][0];
- }
-
- // sort and unique all value registers and make sure each is terminated with
- // LLDB_INVALID_REGNUM
-
- for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end();
- pos != end;
- ++pos)
- {
- if (pos->second.size() > 1)
- {
- std::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())
- pos->second.erase(unique_end, pos->second.end());
- }
- assert (!pos->second.empty());
- if (pos->second.back() != LLDB_INVALID_REGNUM)
- pos->second.push_back(LLDB_INVALID_REGNUM);
- }
-
- // Now update all value_regs with each register info as needed
- const size_t num_regs = m_regs.size();
- for (size_t i=0; i<num_regs; ++i)
- {
- if (m_value_regs_map.find(i) != m_value_regs_map.end())
- m_regs[i].value_regs = m_value_regs_map[i].data();
- else
- m_regs[i].value_regs = NULL;
- }
+void DynamicRegisterInfo::AddRegister(RegisterInfo &reg_info,
+ ConstString &reg_name,
+ ConstString &reg_alt_name,
+ ConstString &set_name) {
+ assert(!m_finalized);
+ const uint32_t reg_num = m_regs.size();
+ reg_info.name = reg_name.AsCString();
+ assert(reg_info.name);
+ reg_info.alt_name = reg_alt_name.AsCString(NULL);
+ uint32_t i;
+ if (reg_info.value_regs) {
+ for (i = 0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
+ }
+ if (reg_info.invalidate_regs) {
+ for (i = 0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
+ }
+ if (reg_info.dynamic_size_dwarf_expr_bytes) {
+ for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i)
+ m_dynamic_reg_size_map[reg_num].push_back(
+ reg_info.dynamic_size_dwarf_expr_bytes[i]);
+
+ reg_info.dynamic_size_dwarf_expr_bytes =
+ m_dynamic_reg_size_map[reg_num].data();
+ }
+
+ m_regs.push_back(reg_info);
+ uint32_t set = GetRegisterSetIndexByName(set_name, true);
+ assert(set < m_sets.size());
+ assert(set < m_set_reg_nums.size());
+ assert(set < m_set_names.size());
+ m_set_reg_nums[set].push_back(reg_num);
+ size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
+ if (m_reg_data_byte_size < end_reg_offset)
+ m_reg_data_byte_size = end_reg_offset;
+}
- // Expand all invalidation dependencies
- for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
- pos != end;
- ++pos)
- {
- const uint32_t reg_num = pos->first;
-
- if (m_regs[reg_num].value_regs)
- {
- reg_num_collection extra_invalid_regs;
- for (const uint32_t invalidate_reg_num : pos->second)
- {
- reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num);
- if (invalidate_pos != m_invalidate_regs_map.end())
- {
- for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second)
- {
- if (concrete_invalidate_reg_num != reg_num)
- extra_invalid_regs.push_back(concrete_invalidate_reg_num);
- }
- }
- }
- pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end());
- }
+void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
+ if (m_finalized)
+ return;
+
+ m_finalized = true;
+ const size_t num_sets = m_sets.size();
+ for (size_t set = 0; set < num_sets; ++set) {
+ assert(m_sets.size() == m_set_reg_nums.size());
+ m_sets[set].num_registers = m_set_reg_nums[set].size();
+ m_sets[set].registers = &m_set_reg_nums[set][0];
+ }
+
+ // sort and unique all value registers and make sure each is terminated with
+ // LLDB_INVALID_REGNUM
+
+ for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(),
+ end = m_value_regs_map.end();
+ pos != end; ++pos) {
+ if (pos->second.size() > 1) {
+ std::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())
+ pos->second.erase(unique_end, pos->second.end());
}
-
- // sort and unique all invalidate registers and make sure each is terminated with
- // LLDB_INVALID_REGNUM
- for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
- pos != end;
- ++pos)
- {
- if (pos->second.size() > 1)
- {
- std::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())
- pos->second.erase(unique_end, pos->second.end());
+ assert(!pos->second.empty());
+ if (pos->second.back() != LLDB_INVALID_REGNUM)
+ pos->second.push_back(LLDB_INVALID_REGNUM);
+ }
+
+ // Now update all value_regs with each register info as needed
+ const size_t num_regs = m_regs.size();
+ for (size_t i = 0; i < num_regs; ++i) {
+ if (m_value_regs_map.find(i) != m_value_regs_map.end())
+ m_regs[i].value_regs = m_value_regs_map[i].data();
+ else
+ m_regs[i].value_regs = NULL;
+ }
+
+ // Expand all invalidation dependencies
+ for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
+ end = m_invalidate_regs_map.end();
+ pos != end; ++pos) {
+ const uint32_t reg_num = pos->first;
+
+ if (m_regs[reg_num].value_regs) {
+ reg_num_collection extra_invalid_regs;
+ for (const uint32_t invalidate_reg_num : pos->second) {
+ reg_to_regs_map::iterator invalidate_pos =
+ m_invalidate_regs_map.find(invalidate_reg_num);
+ if (invalidate_pos != m_invalidate_regs_map.end()) {
+ for (const uint32_t concrete_invalidate_reg_num :
+ invalidate_pos->second) {
+ if (concrete_invalidate_reg_num != reg_num)
+ extra_invalid_regs.push_back(concrete_invalidate_reg_num);
+ }
}
- assert (!pos->second.empty());
- if (pos->second.back() != LLDB_INVALID_REGNUM)
- pos->second.push_back(LLDB_INVALID_REGNUM);
+ }
+ pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),
+ extra_invalid_regs.end());
}
-
- // Now update all invalidate_regs with each register info as needed
- for (size_t i=0; i<num_regs; ++i)
- {
- if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
- m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
- else
- m_regs[i].invalidate_regs = NULL;
+ }
+
+ // sort and unique all invalidate registers and make sure each is terminated
+ // with
+ // LLDB_INVALID_REGNUM
+ for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
+ end = m_invalidate_regs_map.end();
+ pos != end; ++pos) {
+ if (pos->second.size() > 1) {
+ std::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())
+ pos->second.erase(unique_end, pos->second.end());
}
-
- // Check if we need to automatically set the generic registers in case
- // they weren't set
- bool generic_regs_specified = false;
- for (const auto &reg: m_regs)
- {
- if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
- {
- generic_regs_specified = true;
- break;
- }
+ assert(!pos->second.empty());
+ if (pos->second.back() != LLDB_INVALID_REGNUM)
+ pos->second.push_back(LLDB_INVALID_REGNUM);
+ }
+
+ // Now update all invalidate_regs with each register info as needed
+ for (size_t i = 0; i < num_regs; ++i) {
+ if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
+ m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
+ else
+ m_regs[i].invalidate_regs = NULL;
+ }
+
+ // Check if we need to automatically set the generic registers in case
+ // they weren't set
+ bool generic_regs_specified = false;
+ for (const auto &reg : m_regs) {
+ if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
+ generic_regs_specified = true;
+ break;
}
-
- if (!generic_regs_specified)
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_be:
- for (auto &reg: m_regs)
- {
- if (strcmp(reg.name, "pc") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "fp") == 0) || (strcmp(reg.name, "x29") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "x30") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
- else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "x31") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if (strcmp(reg.name, "cpsr") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- for (auto &reg: m_regs)
- {
- if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "r13") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "r14") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
- else if ((strcmp(reg.name, "r7") == 0) && arch.GetTriple().getVendor() == llvm::Triple::Apple)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "r11") == 0) && arch.GetTriple().getVendor() != llvm::Triple::Apple)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if (strcmp(reg.name, "fp") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if (strcmp(reg.name, "cpsr") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- case llvm::Triple::x86:
- for (auto &reg: m_regs)
- {
- if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "esp") == 0) || (strcmp(reg.name, "sp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if ((strcmp(reg.name, "ebp") == 0) || (strcmp(reg.name, "fp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "eflags") == 0) || (strcmp(reg.name, "flags") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- case llvm::Triple::x86_64:
- for (auto &reg: m_regs)
- {
- if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "rsp") == 0) || (strcmp(reg.name, "sp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if ((strcmp(reg.name, "rbp") == 0) || (strcmp(reg.name, "fp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "rflags") == 0) || (strcmp(reg.name, "flags") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- default:
- break;
- }
+ }
+
+ if (!generic_regs_specified) {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ for (auto &reg : m_regs) {
+ if (strcmp(reg.name, "pc") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "fp") == 0) ||
+ (strcmp(reg.name, "x29") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "lr") == 0) ||
+ (strcmp(reg.name, "x30") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ else if ((strcmp(reg.name, "sp") == 0) ||
+ (strcmp(reg.name, "x31") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if (strcmp(reg.name, "cpsr") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ for (auto &reg : m_regs) {
+ if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "sp") == 0) ||
+ (strcmp(reg.name, "r13") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if ((strcmp(reg.name, "lr") == 0) ||
+ (strcmp(reg.name, "r14") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ else if ((strcmp(reg.name, "r7") == 0) &&
+ arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "r11") == 0) &&
+ arch.GetTriple().getVendor() != llvm::Triple::Apple)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if (strcmp(reg.name, "fp") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if (strcmp(reg.name, "cpsr") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ case llvm::Triple::x86:
+ for (auto &reg : m_regs) {
+ if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "esp") == 0) ||
+ (strcmp(reg.name, "sp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if ((strcmp(reg.name, "ebp") == 0) ||
+ (strcmp(reg.name, "fp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "eflags") == 0) ||
+ (strcmp(reg.name, "flags") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ case llvm::Triple::x86_64:
+ for (auto &reg : m_regs) {
+ if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "rsp") == 0) ||
+ (strcmp(reg.name, "sp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if ((strcmp(reg.name, "rbp") == 0) ||
+ (strcmp(reg.name, "fp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "rflags") == 0) ||
+ (strcmp(reg.name, "flags") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ default:
+ break;
}
+ }
}
-size_t
-DynamicRegisterInfo::GetNumRegisters() const
-{
- return m_regs.size();
-}
+size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }
-size_t
-DynamicRegisterInfo::GetNumRegisterSets() const
-{
- return m_sets.size();
-}
+size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }
-size_t
-DynamicRegisterInfo::GetRegisterDataByteSize() const
-{
- return m_reg_data_byte_size;
+size_t DynamicRegisterInfo::GetRegisterDataByteSize() const {
+ return m_reg_data_byte_size;
}
const RegisterInfo *
-DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
-{
- if (i < m_regs.size())
- return &m_regs[i];
- return NULL;
+DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) const {
+ if (i < m_regs.size())
+ return &m_regs[i];
+ return NULL;
}
-RegisterInfo *
-DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i)
-{
- if (i < m_regs.size())
- return &m_regs[i];
- return NULL;
+RegisterInfo *DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) {
+ if (i < m_regs.size())
+ return &m_regs[i];
+ return NULL;
}
-const RegisterSet *
-DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
-{
- if (i < m_sets.size())
- return &m_sets[i];
- return NULL;
+const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const {
+ if (i < m_sets.size())
+ return &m_sets[i];
+ return NULL;
}
-uint32_t
-DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create)
-{
- name_collection::iterator pos, end = m_set_names.end();
- for (pos = m_set_names.begin(); pos != end; ++pos)
- {
- if (*pos == set_name)
- return std::distance (m_set_names.begin(), pos);
- }
-
- m_set_names.push_back(set_name);
- m_set_reg_nums.resize(m_set_reg_nums.size()+1);
- RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
- m_sets.push_back (new_set);
- return m_sets.size() - 1;
+uint32_t DynamicRegisterInfo::GetRegisterSetIndexByName(ConstString &set_name,
+ bool can_create) {
+ name_collection::iterator pos, end = m_set_names.end();
+ for (pos = m_set_names.begin(); pos != end; ++pos) {
+ if (*pos == set_name)
+ return std::distance(m_set_names.begin(), pos);
+ }
+
+ m_set_names.push_back(set_name);
+ m_set_reg_nums.resize(m_set_reg_nums.size() + 1);
+ RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
+ m_sets.push_back(new_set);
+ return m_sets.size() - 1;
}
uint32_t
-DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
-{
- reg_collection::const_iterator pos, end = m_regs.end();
- for (pos = m_regs.begin(); pos != end; ++pos)
- {
- if (pos->kinds[kind] == num)
- return std::distance (m_regs.begin(), pos);
- }
-
- return LLDB_INVALID_REGNUM;
+DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber(uint32_t kind,
+ uint32_t num) const {
+ reg_collection::const_iterator pos, end = m_regs.end();
+ for (pos = m_regs.begin(); pos != end; ++pos) {
+ if (pos->kinds[kind] == num)
+ return std::distance(m_regs.begin(), pos);
+ }
+
+ return LLDB_INVALID_REGNUM;
}
-void
-DynamicRegisterInfo::Clear()
-{
- m_regs.clear();
- m_sets.clear();
- m_set_reg_nums.clear();
- m_set_names.clear();
- m_value_regs_map.clear();
- m_invalidate_regs_map.clear();
- m_dynamic_reg_size_map.clear();
- m_reg_data_byte_size = 0;
- m_finalized = false;
+void DynamicRegisterInfo::Clear() {
+ m_regs.clear();
+ m_sets.clear();
+ m_set_reg_nums.clear();
+ m_set_names.clear();
+ m_value_regs_map.clear();
+ m_invalidate_regs_map.clear();
+ m_dynamic_reg_size_map.clear();
+ m_reg_data_byte_size = 0;
+ m_finalized = false;
}
-void
-DynamicRegisterInfo::Dump () const
-{
- StreamFile s(stdout, false);
- const size_t num_regs = m_regs.size();
- s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
- static_cast<const void*>(this), static_cast<uint64_t>(num_regs));
- for (size_t i=0; i<num_regs; ++i)
- {
- s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
- s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
- m_regs[i].byte_size,
- m_regs[i].byte_offset,
- m_regs[i].encoding,
- FormatManager::GetFormatAsCString (m_regs[i].format));
- if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
- s.Printf(", process plugin = %3u", m_regs[i].kinds[eRegisterKindProcessPlugin]);
- if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
- s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
- if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
- s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
- if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
- s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
- if (m_regs[i].alt_name)
- s.Printf(", alt-name = %s", m_regs[i].alt_name);
- if (m_regs[i].value_regs)
- {
- s.Printf(", value_regs = [ ");
- for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j)
- {
- s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
- }
- s.Printf("]");
- }
- if (m_regs[i].invalidate_regs)
- {
- s.Printf(", invalidate_regs = [ ");
- for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j)
- {
- s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
- }
- s.Printf("]");
- }
- s.EOL();
+void DynamicRegisterInfo::Dump() const {
+ StreamFile s(stdout, false);
+ const size_t num_regs = m_regs.size();
+ s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
+ static_cast<const void *>(this), static_cast<uint64_t>(num_regs));
+ for (size_t i = 0; i < num_regs; ++i) {
+ s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
+ s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
+ m_regs[i].byte_size, m_regs[i].byte_offset, m_regs[i].encoding,
+ FormatManager::GetFormatAsCString(m_regs[i].format));
+ if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
+ s.Printf(", process plugin = %3u",
+ m_regs[i].kinds[eRegisterKindProcessPlugin]);
+ if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
+ s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
+ if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
+ s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
+ if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
+ s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
+ if (m_regs[i].alt_name)
+ s.Printf(", alt-name = %s", m_regs[i].alt_name);
+ if (m_regs[i].value_regs) {
+ s.Printf(", value_regs = [ ");
+ for (size_t j = 0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) {
+ s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
+ }
+ s.Printf("]");
}
-
- const size_t num_sets = m_sets.size();
- s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
- static_cast<const void*>(this), static_cast<uint64_t>(num_sets));
- for (size_t i=0; i<num_sets; ++i)
- {
- s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, m_sets[i].name);
- for (size_t idx=0; idx<m_sets[i].num_registers; ++idx)
- {
- s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
- }
- s.Printf("]\n");
+ if (m_regs[i].invalidate_regs) {
+ s.Printf(", invalidate_regs = [ ");
+ for (size_t j = 0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM;
+ ++j) {
+ s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
+ }
+ s.Printf("]");
+ }
+ s.EOL();
+ }
+
+ const size_t num_sets = m_sets.size();
+ s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
+ static_cast<const void *>(this), static_cast<uint64_t>(num_sets));
+ for (size_t i = 0; i < num_sets; ++i) {
+ s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i,
+ m_sets[i].name);
+ for (size_t idx = 0; idx < m_sets[i].num_registers; ++idx) {
+ s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
}
+ s.Printf("]\n");
+ }
}
-
-
-lldb_private::RegisterInfo *
-DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString &reg_name)
-{
- for (auto &reg_info : m_regs)
- {
- // We can use pointer comparison since we used a ConstString to set
- // the "name" member in AddRegister()
- if (reg_info.name == reg_name.GetCString())
- {
- return &reg_info;
- }
+lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
+ const lldb_private::ConstString &reg_name) {
+ for (auto &reg_info : m_regs) {
+ // We can use pointer comparison since we used a ConstString to set
+ // the "name" member in AddRegister()
+ if (reg_info.name == reg_name.GetCString()) {
+ return &reg_info;
}
- return NULL;
+ }
+ return NULL;
}
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index d97dc136bd63..e5c22fe484e9 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -12,93 +12,82 @@
// C Includes
// C++ Includes
-#include <vector>
#include <map>
+#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/StructuredData.h"
+#include "lldb/lldb-private.h"
-class DynamicRegisterInfo
-{
+class DynamicRegisterInfo {
public:
- DynamicRegisterInfo ();
+ DynamicRegisterInfo();
- DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
- const lldb_private::ArchSpec &arch);
+ DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
+ const lldb_private::ArchSpec &arch);
- virtual
- ~DynamicRegisterInfo ();
+ virtual ~DynamicRegisterInfo();
- size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
- const lldb_private::ArchSpec &arch);
+ size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
+ const lldb_private::ArchSpec &arch);
- void
- AddRegister (lldb_private::RegisterInfo &reg_info,
- lldb_private::ConstString &reg_name,
- lldb_private::ConstString &reg_alt_name,
- lldb_private::ConstString &set_name);
+ void AddRegister(lldb_private::RegisterInfo &reg_info,
+ lldb_private::ConstString &reg_name,
+ lldb_private::ConstString &reg_alt_name,
+ lldb_private::ConstString &set_name);
- void
- Finalize (const lldb_private::ArchSpec &arch);
+ void Finalize(const lldb_private::ArchSpec &arch);
- size_t
- GetNumRegisters() const;
+ size_t GetNumRegisters() const;
- size_t
- GetNumRegisterSets() const;
+ size_t GetNumRegisterSets() const;
- size_t
- GetRegisterDataByteSize() const;
+ size_t GetRegisterDataByteSize() const;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t i) const;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i) const;
- lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t i);
+ lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i);
- const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t i) const;
+ const lldb_private::RegisterSet *GetRegisterSet(uint32_t i) const;
- uint32_t
- GetRegisterSetIndexByName (lldb_private::ConstString &set_name, bool can_create);
+ uint32_t GetRegisterSetIndexByName(lldb_private::ConstString &set_name,
+ bool can_create);
- uint32_t
- ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const;
+ uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind,
+ uint32_t num) const;
- void
- Dump () const;
+ void Dump() const;
- void
- Clear();
+ void Clear();
protected:
- //------------------------------------------------------------------
- // Classes that inherit from DynamicRegisterInfo can see and modify these
- //------------------------------------------------------------------
- typedef std::vector <lldb_private::RegisterInfo> reg_collection;
- typedef std::vector <lldb_private::RegisterSet> set_collection;
- typedef std::vector <uint32_t> reg_num_collection;
- typedef std::vector <reg_num_collection> set_reg_num_collection;
- typedef std::vector <lldb_private::ConstString> name_collection;
- typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
- typedef std::vector <uint8_t> dwarf_opcode;
- typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
-
- lldb_private::RegisterInfo *
- GetRegisterInfo (const lldb_private::ConstString &reg_name);
-
- reg_collection m_regs;
- set_collection m_sets;
- set_reg_num_collection m_set_reg_nums;
- name_collection m_set_names;
- reg_to_regs_map m_value_regs_map;
- reg_to_regs_map m_invalidate_regs_map;
- dynamic_reg_size_map m_dynamic_reg_size_map;
- size_t m_reg_data_byte_size; // The number of bytes required to store all registers
- bool m_finalized;
+ //------------------------------------------------------------------
+ // Classes that inherit from DynamicRegisterInfo can see and modify these
+ //------------------------------------------------------------------
+ typedef std::vector<lldb_private::RegisterInfo> reg_collection;
+ typedef std::vector<lldb_private::RegisterSet> set_collection;
+ typedef std::vector<uint32_t> reg_num_collection;
+ typedef std::vector<reg_num_collection> set_reg_num_collection;
+ typedef std::vector<lldb_private::ConstString> name_collection;
+ typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
+ typedef std::vector<uint8_t> dwarf_opcode;
+ typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
+
+ lldb_private::RegisterInfo *
+ GetRegisterInfo(const lldb_private::ConstString &reg_name);
+
+ reg_collection m_regs;
+ set_collection m_sets;
+ set_reg_num_collection m_set_reg_nums;
+ name_collection m_set_names;
+ reg_to_regs_map m_value_regs_map;
+ reg_to_regs_map m_invalidate_regs_map;
+ dynamic_reg_size_map m_dynamic_reg_size_map;
+ size_t m_reg_data_byte_size; // The number of bytes required to store all
+ // registers
+ bool m_finalized;
};
-#endif // lldb_DynamicRegisterInfo_h_
+#endif // lldb_DynamicRegisterInfo_h_
diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/source/Plugins/Process/Utility/FreeBSDSignals.cpp
index e575e2c6a496..f695a11c9759 100644
--- a/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ b/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -15,81 +15,77 @@
using namespace lldb_private;
-FreeBSDSignals::FreeBSDSignals()
- : UnixSignals()
-{
- Reset();
-}
+FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Reset(); }
-void
-FreeBSDSignals::Reset()
-{
- UnixSignals::Reset();
+void FreeBSDSignals::Reset() {
+ UnixSignals::Reset();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
- // ====== ============ ======== ====== ====== ===================================================
- AddSignal (32, "SIGTHR", false, false, false, "thread interrupt");
- AddSignal (33, "SIGLIBRT", false, false, false, "reserved by real-time library");
- AddSignal (65, "SIGRTMIN", false, false, false, "real time signal 0");
- AddSignal (66, "SIGRTMIN+1", false, false, false, "real time signal 1");
- AddSignal (67, "SIGRTMIN+2", false, false, false, "real time signal 2");
- AddSignal (68, "SIGRTMIN+3", false, false, false, "real time signal 3");
- AddSignal (69, "SIGRTMIN+4", false, false, false, "real time signal 4");
- AddSignal (70, "SIGRTMIN+5", false, false, false, "real time signal 5");
- AddSignal (71, "SIGRTMIN+6", false, false, false, "real time signal 6");
- AddSignal (72, "SIGRTMIN+7", false, false, false, "real time signal 7");
- AddSignal (73, "SIGRTMIN+8", false, false, false, "real time signal 8");
- AddSignal (74, "SIGRTMIN+9", false, false, false, "real time signal 9");
- AddSignal (75, "SIGRTMIN+10", false, false, false, "real time signal 10");
- AddSignal (76, "SIGRTMIN+11", false, false, false, "real time signal 11");
- AddSignal (77, "SIGRTMIN+12", false, false, false, "real time signal 12");
- AddSignal (78, "SIGRTMIN+13", false, false, false, "real time signal 13");
- AddSignal (79, "SIGRTMIN+14", false, false, false, "real time signal 14");
- AddSignal (80, "SIGRTMIN+15", false, false, false, "real time signal 15");
- AddSignal (81, "SIGRTMIN+16", false, false, false, "real time signal 16");
- AddSignal (82, "SIGRTMIN+17", false, false, false, "real time signal 17");
- AddSignal (83, "SIGRTMIN+18", false, false, false, "real time signal 18");
- AddSignal (84, "SIGRTMIN+19", false, false, false, "real time signal 19");
- AddSignal (85, "SIGRTMIN+20", false, false, false, "real time signal 20");
- AddSignal (86, "SIGRTMIN+21", false, false, false, "real time signal 21");
- AddSignal (87, "SIGRTMIN+22", false, false, false, "real time signal 22");
- AddSignal (88, "SIGRTMIN+23", false, false, false, "real time signal 23");
- AddSignal (89, "SIGRTMIN+24", false, false, false, "real time signal 24");
- AddSignal (90, "SIGRTMIN+25", false, false, false, "real time signal 25");
- AddSignal (91, "SIGRTMIN+26", false, false, false, "real time signal 26");
- AddSignal (92, "SIGRTMIN+27", false, false, false, "real time signal 27");
- AddSignal (93, "SIGRTMIN+28", false, false, false, "real time signal 28");
- AddSignal (94, "SIGRTMIN+29", false, false, false, "real time signal 29");
- AddSignal (95, "SIGRTMIN+30", false, false, false, "real time signal 30");
- AddSignal (96, "SIGRTMAX-30", false, false, false, "real time signal 31");
- AddSignal (97, "SIGRTMAX-29", false, false, false, "real time signal 32");
- AddSignal (98, "SIGRTMAX-28", false, false, false, "real time signal 33");
- AddSignal (99, "SIGRTMAX-27", false, false, false, "real time signal 34");
- AddSignal (100, "SIGRTMAX-26", false, false, false, "real time signal 35");
- AddSignal (101, "SIGRTMAX-25", false, false, false, "real time signal 36");
- AddSignal (102, "SIGRTMAX-24", false, false, false, "real time signal 37");
- AddSignal (103, "SIGRTMAX-23", false, false, false, "real time signal 38");
- AddSignal (104, "SIGRTMAX-22", false, false, false, "real time signal 39");
- AddSignal (105, "SIGRTMAX-21", false, false, false, "real time signal 40");
- AddSignal (106, "SIGRTMAX-20", false, false, false, "real time signal 41");
- AddSignal (107, "SIGRTMAX-19", false, false, false, "real time signal 42");
- AddSignal (108, "SIGRTMAX-18", false, false, false, "real time signal 43");
- AddSignal (109, "SIGRTMAX-17", false, false, false, "real time signal 44");
- AddSignal (110, "SIGRTMAX-16", false, false, false, "real time signal 45");
- AddSignal (111, "SIGRTMAX-15", false, false, false, "real time signal 46");
- AddSignal (112, "SIGRTMAX-14", false, false, false, "real time signal 47");
- AddSignal (113, "SIGRTMAX-13", false, false, false, "real time signal 48");
- AddSignal (114, "SIGRTMAX-12", false, false, false, "real time signal 49");
- AddSignal (115, "SIGRTMAX-11", false, false, false, "real time signal 50");
- AddSignal (116, "SIGRTMAX-10", false, false, false, "real time signal 51");
- AddSignal (117, "SIGRTMAX-9", false, false, false, "real time signal 52");
- AddSignal (118, "SIGRTMAX-8", false, false, false, "real time signal 53");
- AddSignal (119, "SIGRTMAX-7", false, false, false, "real time signal 54");
- AddSignal (120, "SIGRTMAX-6", false, false, false, "real time signal 55");
- AddSignal (121, "SIGRTMAX-5", false, false, false, "real time signal 56");
- AddSignal (122, "SIGRTMAX-4", false, false, false, "real time signal 57");
- AddSignal (123, "SIGRTMAX-3", false, false, false, "real time signal 58");
- AddSignal (124, "SIGRTMAX-2", false, false, false, "real time signal 59");
- AddSignal (125, "SIGRTMAX-1", false, false, false, "real time signal 60");
- AddSignal (126, "SIGRTMAX", false, false, false, "real time signal 61");
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============ ======== ====== ======
+ // ===================================================
+ AddSignal(32, "SIGTHR", false, false, false, "thread interrupt");
+ AddSignal(33, "SIGLIBRT", false, false, false,
+ "reserved by real-time library");
+ AddSignal(65, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(66, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(67, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(68, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(69, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(70, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(71, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(72, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(73, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(74, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(75, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(76, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(77, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(78, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(79, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(80, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(81, "SIGRTMIN+16", false, false, false, "real time signal 16");
+ AddSignal(82, "SIGRTMIN+17", false, false, false, "real time signal 17");
+ AddSignal(83, "SIGRTMIN+18", false, false, false, "real time signal 18");
+ AddSignal(84, "SIGRTMIN+19", false, false, false, "real time signal 19");
+ AddSignal(85, "SIGRTMIN+20", false, false, false, "real time signal 20");
+ AddSignal(86, "SIGRTMIN+21", false, false, false, "real time signal 21");
+ AddSignal(87, "SIGRTMIN+22", false, false, false, "real time signal 22");
+ AddSignal(88, "SIGRTMIN+23", false, false, false, "real time signal 23");
+ AddSignal(89, "SIGRTMIN+24", false, false, false, "real time signal 24");
+ AddSignal(90, "SIGRTMIN+25", false, false, false, "real time signal 25");
+ AddSignal(91, "SIGRTMIN+26", false, false, false, "real time signal 26");
+ AddSignal(92, "SIGRTMIN+27", false, false, false, "real time signal 27");
+ AddSignal(93, "SIGRTMIN+28", false, false, false, "real time signal 28");
+ AddSignal(94, "SIGRTMIN+29", false, false, false, "real time signal 29");
+ AddSignal(95, "SIGRTMIN+30", false, false, false, "real time signal 30");
+ AddSignal(96, "SIGRTMAX-30", false, false, false, "real time signal 31");
+ AddSignal(97, "SIGRTMAX-29", false, false, false, "real time signal 32");
+ AddSignal(98, "SIGRTMAX-28", false, false, false, "real time signal 33");
+ AddSignal(99, "SIGRTMAX-27", false, false, false, "real time signal 34");
+ AddSignal(100, "SIGRTMAX-26", false, false, false, "real time signal 35");
+ AddSignal(101, "SIGRTMAX-25", false, false, false, "real time signal 36");
+ AddSignal(102, "SIGRTMAX-24", false, false, false, "real time signal 37");
+ AddSignal(103, "SIGRTMAX-23", false, false, false, "real time signal 38");
+ AddSignal(104, "SIGRTMAX-22", false, false, false, "real time signal 39");
+ AddSignal(105, "SIGRTMAX-21", false, false, false, "real time signal 40");
+ AddSignal(106, "SIGRTMAX-20", false, false, false, "real time signal 41");
+ AddSignal(107, "SIGRTMAX-19", false, false, false, "real time signal 42");
+ AddSignal(108, "SIGRTMAX-18", false, false, false, "real time signal 43");
+ AddSignal(109, "SIGRTMAX-17", false, false, false, "real time signal 44");
+ AddSignal(110, "SIGRTMAX-16", false, false, false, "real time signal 45");
+ AddSignal(111, "SIGRTMAX-15", false, false, false, "real time signal 46");
+ AddSignal(112, "SIGRTMAX-14", false, false, false, "real time signal 47");
+ AddSignal(113, "SIGRTMAX-13", false, false, false, "real time signal 48");
+ AddSignal(114, "SIGRTMAX-12", false, false, false, "real time signal 49");
+ AddSignal(115, "SIGRTMAX-11", false, false, false, "real time signal 50");
+ AddSignal(116, "SIGRTMAX-10", false, false, false, "real time signal 51");
+ AddSignal(117, "SIGRTMAX-9", false, false, false, "real time signal 52");
+ AddSignal(118, "SIGRTMAX-8", false, false, false, "real time signal 53");
+ AddSignal(119, "SIGRTMAX-7", false, false, false, "real time signal 54");
+ AddSignal(120, "SIGRTMAX-6", false, false, false, "real time signal 55");
+ AddSignal(121, "SIGRTMAX-5", false, false, false, "real time signal 56");
+ AddSignal(122, "SIGRTMAX-4", false, false, false, "real time signal 57");
+ AddSignal(123, "SIGRTMAX-3", false, false, false, "real time signal 58");
+ AddSignal(124, "SIGRTMAX-2", false, false, false, "real time signal 59");
+ AddSignal(125, "SIGRTMAX-1", false, false, false, "real time signal 60");
+ AddSignal(126, "SIGRTMAX", false, false, false, "real time signal 61");
}
diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.h b/source/Plugins/Process/Utility/FreeBSDSignals.h
index b715c62c81e9..8ec96e824f7a 100644
--- a/source/Plugins/Process/Utility/FreeBSDSignals.h
+++ b/source/Plugins/Process/Utility/FreeBSDSignals.h
@@ -16,14 +16,12 @@
namespace lldb_private {
/// FreeBSD specific set of Unix signals.
-class FreeBSDSignals : public UnixSignals
-{
+class FreeBSDSignals : public UnixSignals {
public:
- FreeBSDSignals();
+ FreeBSDSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
index 4e355c63b3aa..abcc8a38669a 100644
--- a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
+++ b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
@@ -14,19 +14,9 @@
using namespace lldb_private;
-GDBRemoteSignals::GDBRemoteSignals()
- : UnixSignals()
-{
- Reset();
-}
+GDBRemoteSignals::GDBRemoteSignals() : UnixSignals() { Reset(); }
GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs)
- : UnixSignals(*rhs)
-{
-}
+ : UnixSignals(*rhs) {}
-void
-GDBRemoteSignals::Reset()
-{
- m_signals.clear();
-}
+void GDBRemoteSignals::Reset() { m_signals.clear(); }
diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.h b/source/Plugins/Process/Utility/GDBRemoteSignals.h
index bbb631a14090..5900fa75d6f2 100644
--- a/source/Plugins/Process/Utility/GDBRemoteSignals.h
+++ b/source/Plugins/Process/Utility/GDBRemoteSignals.h
@@ -19,16 +19,14 @@
namespace lldb_private {
/// Empty set of Unix signals to be filled by PlatformRemoteGDBServer
-class GDBRemoteSignals : public UnixSignals
-{
+class GDBRemoteSignals : public UnixSignals {
public:
- GDBRemoteSignals();
+ GDBRemoteSignals();
- GDBRemoteSignals(const lldb::UnixSignalsSP &rhs);
+ GDBRemoteSignals(const lldb::UnixSignalsSP &rhs);
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/HistoryThread.cpp b/source/Plugins/Process/Utility/HistoryThread.cpp
index 956539da219c..d27a7b0da943 100644
--- a/source/Plugins/Process/Utility/HistoryThread.cpp
+++ b/source/Plugins/Process/Utility/HistoryThread.cpp
@@ -9,91 +9,75 @@
#include "lldb/lldb-private.h"
-#include "Plugins/Process/Utility/HistoryUnwind.h"
#include "Plugins/Process/Utility/HistoryThread.h"
+#include "Plugins/Process/Utility/HistoryUnwind.h"
#include "Plugins/Process/Utility/RegisterContextHistory.h"
#include "lldb/Core/Log.h"
-#include "lldb/Target/StackFrameList.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrameList.h"
using namespace lldb;
using namespace lldb_private;
// Constructor
-HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, std::vector<lldb::addr_t> pcs,
- uint32_t stop_id, bool stop_id_is_valid)
- : Thread(process, tid, true),
- m_framelist_mutex(),
- m_framelist(),
- m_pcs(pcs),
- m_stop_id(stop_id),
- m_stop_id_is_valid(stop_id_is_valid),
- m_extended_unwind_token(LLDB_INVALID_ADDRESS),
- m_queue_name(),
- m_thread_name(),
- m_originating_unique_thread_id(tid),
- m_queue_id(LLDB_INVALID_QUEUE_ID)
-{
- m_unwinder_ap.reset(new HistoryUnwind(*this, pcs, stop_id_is_valid));
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
+HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
+ std::vector<lldb::addr_t> pcs, uint32_t stop_id,
+ bool stop_id_is_valid)
+ : Thread(process, tid, true), m_framelist_mutex(), m_framelist(),
+ m_pcs(pcs), m_stop_id(stop_id), m_stop_id_is_valid(stop_id_is_valid),
+ m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(),
+ m_thread_name(), m_originating_unique_thread_id(tid),
+ m_queue_id(LLDB_INVALID_QUEUE_ID) {
+ m_unwinder_ap.reset(new HistoryUnwind(*this, pcs, stop_id_is_valid));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
}
// Destructor
-HistoryThread::~HistoryThread ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf ("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
- static_cast<void*>(this), GetID());
- DestroyThread();
+HistoryThread::~HistoryThread() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
+ static_cast<void *>(this), GetID());
+ DestroyThread();
}
-lldb::RegisterContextSP
-HistoryThread::GetRegisterContext ()
-{
- RegisterContextSP rctx ;
- if (m_pcs.size() > 0)
- {
- rctx.reset (new RegisterContextHistory (*this, 0, GetProcess()->GetAddressByteSize(), m_pcs[0]));
- }
- return rctx;
-
+lldb::RegisterContextSP HistoryThread::GetRegisterContext() {
+ RegisterContextSP rctx;
+ if (m_pcs.size() > 0) {
+ rctx.reset(new RegisterContextHistory(
+ *this, 0, GetProcess()->GetAddressByteSize(), m_pcs[0]));
+ }
+ return rctx;
}
lldb::RegisterContextSP
-HistoryThread::CreateRegisterContextForFrame (StackFrame *frame)
-{
- return m_unwinder_ap->CreateRegisterContextForFrame (frame);
+HistoryThread::CreateRegisterContextForFrame(StackFrame *frame) {
+ return m_unwinder_ap->CreateRegisterContextForFrame(frame);
}
-lldb::StackFrameListSP
-HistoryThread::GetStackFrameList ()
-{
- // FIXME do not throw away the lock after we acquire it..
- std::unique_lock<std::mutex> lock(m_framelist_mutex);
- lock.unlock();
- if (m_framelist.get() == NULL)
- {
- m_framelist.reset (new StackFrameList (*this, StackFrameListSP(), true));
- }
+lldb::StackFrameListSP HistoryThread::GetStackFrameList() {
+ // FIXME do not throw away the lock after we acquire it..
+ std::unique_lock<std::mutex> lock(m_framelist_mutex);
+ lock.unlock();
+ if (m_framelist.get() == NULL) {
+ m_framelist.reset(new StackFrameList(*this, StackFrameListSP(), true));
+ }
- return m_framelist;
+ return m_framelist;
}
-uint32_t
-HistoryThread::GetExtendedBacktraceOriginatingIndexID ()
-{
- if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID)
- {
- if (GetProcess()->HasAssignedIndexIDToThread (m_originating_unique_thread_id))
- {
- return GetProcess()->AssignIndexIDToThread (m_originating_unique_thread_id);
- }
+uint32_t HistoryThread::GetExtendedBacktraceOriginatingIndexID() {
+ if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID) {
+ if (GetProcess()->HasAssignedIndexIDToThread(
+ m_originating_unique_thread_id)) {
+ return GetProcess()->AssignIndexIDToThread(
+ m_originating_unique_thread_id);
}
- return LLDB_INVALID_THREAD_ID;
+ }
+ return LLDB_INVALID_THREAD_ID;
}
diff --git a/source/Plugins/Process/Utility/HistoryThread.h b/source/Plugins/Process/Utility/HistoryThread.h
index 43ac13c2d8bc..1a4898a95b7d 100644
--- a/source/Plugins/Process/Utility/HistoryThread.h
+++ b/source/Plugins/Process/Utility/HistoryThread.h
@@ -16,7 +16,6 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/UserID.h"
@@ -24,119 +23,78 @@
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/StackFrameList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
//----------------------------------------------------------------------
/// @class HistoryThread HistoryThread.h "HistoryThread.h"
-/// @brief A thread object representing a backtrace from a previous point in the process execution
+/// @brief A thread object representing a backtrace from a previous point in the
+/// process execution
///
/// This subclass of Thread is used to provide a backtrace from earlier in
-/// process execution. It is given a backtrace list of pc addresses and
+/// process execution. It is given a backtrace list of pc addresses and
/// optionally a stop_id of when those pc addresses were collected, and it will
/// create stack frames for them.
//----------------------------------------------------------------------
-class HistoryThread : public lldb_private::Thread
-{
+class HistoryThread : public lldb_private::Thread {
public:
- HistoryThread (lldb_private::Process &process, lldb::tid_t tid, std::vector<lldb::addr_t> pcs, uint32_t stop_id, bool stop_id_is_valid);
-
- ~HistoryThread() override;
-
- lldb::RegisterContextSP
- GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(StackFrame *frame) override;
-
- void
- RefreshStateAfterStop() override { }
-
- bool
- CalculateStopInfo() override
- {
- return false;
- }
-
- void
- SetExtendedBacktraceToken(uint64_t token) override
- {
- m_extended_unwind_token = token;
- }
-
- uint64_t
- GetExtendedBacktraceToken() override
- {
- return m_extended_unwind_token;
- }
-
- const char *
- GetQueueName() override
- {
- return m_queue_name.c_str();
- }
-
- void
- SetQueueName(const char *name) override
- {
- m_queue_name = name;
- }
-
- lldb::queue_id_t
- GetQueueID() override
- {
- return m_queue_id;
- }
-
- void
- SetQueueID(lldb::queue_id_t queue) override
- {
- m_queue_id = queue;
- }
-
- const char *
- GetThreadName ()
- {
- return m_thread_name.c_str();
- }
-
- uint32_t
- GetExtendedBacktraceOriginatingIndexID() override;
-
- void
- SetThreadName (const char *name)
- {
- m_thread_name = name;
- }
-
- const char *
- GetName() override
- {
- return m_thread_name.c_str();
- }
-
- void
- SetName(const char *name) override
- {
- m_thread_name = name;
- }
+ HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
+ std::vector<lldb::addr_t> pcs, uint32_t stop_id,
+ bool stop_id_is_valid);
+
+ ~HistoryThread() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+
+ void RefreshStateAfterStop() override {}
+
+ bool CalculateStopInfo() override { return false; }
+
+ void SetExtendedBacktraceToken(uint64_t token) override {
+ m_extended_unwind_token = token;
+ }
+
+ uint64_t GetExtendedBacktraceToken() override {
+ return m_extended_unwind_token;
+ }
+
+ const char *GetQueueName() override { return m_queue_name.c_str(); }
+
+ void SetQueueName(const char *name) override { m_queue_name = name; }
+
+ lldb::queue_id_t GetQueueID() override { return m_queue_id; }
+
+ void SetQueueID(lldb::queue_id_t queue) override { m_queue_id = queue; }
+
+ const char *GetThreadName() { return m_thread_name.c_str(); }
+
+ uint32_t GetExtendedBacktraceOriginatingIndexID() override;
+
+ void SetThreadName(const char *name) { m_thread_name = name; }
+
+ const char *GetName() override { return m_thread_name.c_str(); }
+
+ void SetName(const char *name) override { m_thread_name = name; }
protected:
- virtual lldb::StackFrameListSP
- GetStackFrameList ();
-
- mutable std::mutex m_framelist_mutex;
- lldb::StackFrameListSP m_framelist;
- std::vector<lldb::addr_t> m_pcs;
- uint32_t m_stop_id;
- bool m_stop_id_is_valid;
-
- uint64_t m_extended_unwind_token;
- std::string m_queue_name;
- std::string m_thread_name;
- lldb::tid_t m_originating_unique_thread_id;
- lldb::queue_id_t m_queue_id;
+ virtual lldb::StackFrameListSP GetStackFrameList();
+
+ mutable std::mutex m_framelist_mutex;
+ lldb::StackFrameListSP m_framelist;
+ std::vector<lldb::addr_t> m_pcs;
+ uint32_t m_stop_id;
+ bool m_stop_id_is_valid;
+
+ uint64_t m_extended_unwind_token;
+ std::string m_queue_name;
+ std::string m_thread_name;
+ lldb::tid_t m_originating_unique_thread_id;
+ lldb::queue_id_t m_queue_id;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.cpp b/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 01d8c3ebdcd3..4f0ecba613bf 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -9,75 +9,59 @@
#include "lldb/lldb-private.h"
-#include "Plugins/Process/Utility/RegisterContextHistory.h"
#include "Plugins/Process/Utility/HistoryUnwind.h"
+#include "Plugins/Process/Utility/RegisterContextHistory.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-// Constructor
+// Constructor
-HistoryUnwind::HistoryUnwind (Thread &thread,
- std::vector<lldb::addr_t> pcs,
- bool stop_id_is_valid) :
- Unwind (thread),
- m_pcs (pcs),
- m_stop_id_is_valid (stop_id_is_valid)
-{
-}
+HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
+ bool stop_id_is_valid)
+ : Unwind(thread), m_pcs(pcs), m_stop_id_is_valid(stop_id_is_valid) {}
// Destructor
-HistoryUnwind::~HistoryUnwind ()
-{
-}
+HistoryUnwind::~HistoryUnwind() {}
-void
-HistoryUnwind::DoClear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
- m_pcs.clear();
- m_stop_id_is_valid = false;
+void HistoryUnwind::DoClear() {
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ m_pcs.clear();
+ m_stop_id_is_valid = false;
}
lldb::RegisterContextSP
-HistoryUnwind::DoCreateRegisterContextForFrame (StackFrame *frame)
-{
- RegisterContextSP rctx;
- if (frame)
- {
- addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress (&frame->GetThread()->GetProcess()->GetTarget());
- if (pc != LLDB_INVALID_ADDRESS)
- {
- rctx.reset (new RegisterContextHistory (*frame->GetThread().get(), frame->GetConcreteFrameIndex(),
- frame->GetThread()->GetProcess()->GetAddressByteSize(), pc));
- }
+HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP rctx;
+ if (frame) {
+ addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress(
+ &frame->GetThread()->GetProcess()->GetTarget());
+ if (pc != LLDB_INVALID_ADDRESS) {
+ rctx.reset(new RegisterContextHistory(
+ *frame->GetThread().get(), frame->GetConcreteFrameIndex(),
+ frame->GetThread()->GetProcess()->GetAddressByteSize(), pc));
}
- return rctx;
+ }
+ return rctx;
}
-bool
-HistoryUnwind::DoGetFrameInfoAtIndex (uint32_t frame_idx, lldb::addr_t& cfa, lldb::addr_t& pc)
-{
- // FIXME do not throw away the lock after we acquire it..
- std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
- guard.unlock();
- if (frame_idx < m_pcs.size())
- {
- cfa = frame_idx;
- pc = m_pcs[frame_idx];
- return true;
- }
- return false;
+bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) {
+ // FIXME do not throw away the lock after we acquire it..
+ std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
+ guard.unlock();
+ if (frame_idx < m_pcs.size()) {
+ cfa = frame_idx;
+ pc = m_pcs[frame_idx];
+ return true;
+ }
+ return false;
}
-uint32_t
-HistoryUnwind::DoGetFrameCount ()
-{
- return m_pcs.size();
-}
+uint32_t HistoryUnwind::DoGetFrameCount() { return m_pcs.size(); }
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h
index 890604fcb680..3b64e38bfaa7 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -16,36 +16,31 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-class HistoryUnwind : public lldb_private::Unwind
-{
+class HistoryUnwind : public lldb_private::Unwind {
public:
- HistoryUnwind (Thread &thread, std::vector<lldb::addr_t> pcs, bool stop_id_is_valid);
+ HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
+ bool stop_id_is_valid);
- ~HistoryUnwind() override;
+ ~HistoryUnwind() override;
protected:
- void
- DoClear() override;
+ void DoClear() override;
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(StackFrame *frame) override;
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(StackFrame *frame) override;
- bool
- DoGetFrameInfoAtIndex(uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& pc) override;
- uint32_t
- DoGetFrameCount() override;
+ bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) override;
+ uint32_t DoGetFrameCount() override;
private:
-
- std::vector<lldb::addr_t> m_pcs;
- bool m_stop_id_is_valid;
+ std::vector<lldb::addr_t> m_pcs;
+ bool m_stop_id_is_valid;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index b694b833cb48..4e1f10c6ae18 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -34,225 +34,207 @@
using namespace lldb;
using namespace lldb_private;
-bool
-lldb_private::InferiorCallMmap (Process *process,
- addr_t &allocated_addr,
- addr_t addr,
- addr_t length,
- unsigned prot,
- unsigned flags,
- addr_t fd,
- addr_t offset)
-{
- Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == NULL)
- return false;
-
- const bool append = true;
- const bool include_symbols = true;
- const bool include_inlines = false;
- SymbolContextList sc_list;
- const uint32_t count
- = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
- eFunctionNameTypeFull,
- include_symbols,
- include_inlines,
- append,
- sc_list);
- if (count > 0)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
- {
- const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = false;
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug (false);
- options.SetTimeoutUsec(500000);
- options.SetTrapExceptions(false);
-
- addr_t prot_arg, flags_arg = 0;
- if (prot == eMmapProtNone)
- prot_arg = PROT_NONE;
- else {
- prot_arg = 0;
- if (prot & eMmapProtExec)
- prot_arg |= PROT_EXEC;
- if (prot & eMmapProtRead)
- prot_arg |= PROT_READ;
- if (prot & eMmapProtWrite)
- prot_arg |= PROT_WRITE;
- }
-
- const ArchSpec arch = process->GetTarget().GetArchitecture();
- flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags);
-
- AddressRange mmap_range;
- if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
- {
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
- lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
- clang_void_ptr_type, args, options));
- if (call_plan_sp)
- {
- DiagnosticManager diagnostics;
-
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame)
- {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext (exe_ctx);
- ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted)
- {
+bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
+ addr_t addr, addr_t length, unsigned prot,
+ unsigned flags, addr_t fd, addr_t offset) {
+ Thread *thread =
+ process->GetThreadList().GetExpressionExecutionThread().get();
+ if (thread == NULL)
+ return false;
- allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- if (process->GetAddressByteSize() == 4)
- {
- if (allocated_addr == UINT32_MAX)
- return false;
- }
- else if (process->GetAddressByteSize() == 8)
- {
- if (allocated_addr == UINT64_MAX)
- return false;
- }
- return true;
- }
- }
- }
+ const bool append = true;
+ const bool include_symbols = true;
+ const bool include_inlines = false;
+ SymbolContextList sc_list;
+ const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ ConstString("mmap"), eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
+ if (count > 0) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc)) {
+ const uint32_t range_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+ const bool use_inline_block_range = false;
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug(false);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTrapExceptions(false);
+
+ addr_t prot_arg, flags_arg = 0;
+ if (prot == eMmapProtNone)
+ prot_arg = PROT_NONE;
+ else {
+ prot_arg = 0;
+ if (prot & eMmapProtExec)
+ prot_arg |= PROT_EXEC;
+ if (prot & eMmapProtRead)
+ prot_arg |= PROT_READ;
+ if (prot & eMmapProtWrite)
+ prot_arg |= PROT_WRITE;
+ }
+
+ const ArchSpec arch = process->GetTarget().GetArchitecture();
+ flags_arg =
+ process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,
+ flags);
+
+ AddressRange mmap_range;
+ if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
+ mmap_range)) {
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ lldb::addr_t args[] = {addr, length, prot_arg, flags_arg, fd, offset};
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
+ clang_void_ptr_type, args, options));
+ if (call_plan_sp) {
+ DiagnosticManager diagnostics;
+
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ if (frame) {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = process->RunThreadPlan(
+ exe_ctx, call_plan_sp, options, diagnostics);
+ if (result == eExpressionCompleted) {
+
+ allocated_addr =
+ call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
+ LLDB_INVALID_ADDRESS);
+ if (process->GetAddressByteSize() == 4) {
+ if (allocated_addr == UINT32_MAX)
+ return false;
+ } else if (process->GetAddressByteSize() == 8) {
+ if (allocated_addr == UINT64_MAX)
+ return false;
+ }
+ return true;
}
+ }
}
+ }
}
+ }
- return false;
+ return false;
}
-bool
-lldb_private::InferiorCallMunmap (Process *process,
- addr_t addr,
- addr_t length)
-{
- Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == NULL)
- return false;
-
- const bool append = true;
- const bool include_symbols = true;
- const bool include_inlines = false;
- SymbolContextList sc_list;
- const uint32_t count
- = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"),
- eFunctionNameTypeFull,
- include_symbols,
- include_inlines,
- append,
- sc_list);
- if (count > 0)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
- {
- const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = false;
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug (false);
- options.SetTimeoutUsec(500000);
- options.SetTrapExceptions(false);
-
- AddressRange munmap_range;
- if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
- {
- lldb::addr_t args[] = { addr, length };
- lldb::ThreadPlanSP call_plan_sp(
- new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), CompilerType(), args, options));
- if (call_plan_sp)
- {
- DiagnosticManager diagnostics;
+bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
+ addr_t length) {
+ Thread *thread =
+ process->GetThreadList().GetExpressionExecutionThread().get();
+ if (thread == NULL)
+ return false;
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame)
- {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext (exe_ctx);
- ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted)
- {
- return true;
- }
- }
- }
+ const bool append = true;
+ const bool include_symbols = true;
+ const bool include_inlines = false;
+ SymbolContextList sc_list;
+ const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ ConstString("munmap"), eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
+ if (count > 0) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc)) {
+ const uint32_t range_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+ const bool use_inline_block_range = false;
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug(false);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTrapExceptions(false);
+
+ AddressRange munmap_range;
+ if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
+ munmap_range)) {
+ lldb::addr_t args[] = {addr, length};
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(),
+ CompilerType(), args, options));
+ if (call_plan_sp) {
+ DiagnosticManager diagnostics;
+
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ if (frame) {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = process->RunThreadPlan(
+ exe_ctx, call_plan_sp, options, diagnostics);
+ if (result == eExpressionCompleted) {
+ return true;
}
+ }
}
+ }
}
+ }
- return false;
+ return false;
}
-// FIXME: This has nothing to do with Posix, it is just a convenience function that calls a
-// function of the form "void * (*)(void)". We should find a better place to put this.
-
-bool
-lldb_private::InferiorCall (Process *process,
- const Address *address,
- addr_t &returned_func,
- bool trap_exceptions)
-{
- Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == NULL || address == NULL)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug (false);
- options.SetTimeoutUsec(500000);
- options.SetTrapExceptions(trap_exceptions);
-
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::ThreadPlanSP call_plan_sp(
- new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, llvm::ArrayRef<addr_t>(), options));
- if (call_plan_sp)
- {
- DiagnosticManager diagnostics;
+// FIXME: This has nothing to do with Posix, it is just a convenience function
+// that calls a
+// function of the form "void * (*)(void)". We should find a better place to
+// put this.
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame)
- {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext (exe_ctx);
- ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted)
- {
- returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+bool lldb_private::InferiorCall(Process *process, const Address *address,
+ addr_t &returned_func, bool trap_exceptions) {
+ Thread *thread =
+ process->GetThreadList().GetExpressionExecutionThread().get();
+ if (thread == NULL || address == NULL)
+ return false;
- if (process->GetAddressByteSize() == 4)
- {
- if (returned_func == UINT32_MAX)
- return false;
- }
- else if (process->GetAddressByteSize() == 8)
- {
- if (returned_func == UINT64_MAX)
- return false;
- }
- return true;
- }
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug(false);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTrapExceptions(trap_exceptions);
+
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type,
+ llvm::ArrayRef<addr_t>(), options));
+ if (call_plan_sp) {
+ DiagnosticManager diagnostics;
+
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ if (frame) {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result =
+ process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
+ if (result == eExpressionCompleted) {
+ returned_func =
+ call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
+ LLDB_INVALID_ADDRESS);
+
+ if (process->GetAddressByteSize() == 4) {
+ if (returned_func == UINT32_MAX)
+ return false;
+ } else if (process->GetAddressByteSize() == 8) {
+ if (returned_func == UINT64_MAX)
+ return false;
}
+ return true;
+ }
}
+ }
- return false;
+ return false;
}
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
index d10e8490d809..07bde5bf09b3 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.h
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
@@ -31,9 +31,9 @@ bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr,
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
-bool InferiorCall(Process *proc, const Address *address, lldb::addr_t &returned_func,
- bool trap_exceptions = false);
+bool InferiorCall(Process *proc, const Address *address,
+ lldb::addr_t &returned_func, bool trap_exceptions = false);
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_InferiorCallPOSIX_h_
+#endif // lldb_InferiorCallPOSIX_h_
diff --git a/source/Plugins/Process/Utility/InstructionUtils.h b/source/Plugins/Process/Utility/InstructionUtils.h
index 6226fbc04b08..e422a96200c8 100644
--- a/source/Plugins/Process/Utility/InstructionUtils.h
+++ b/source/Plugins/Process/Utility/InstructionUtils.h
@@ -16,123 +16,99 @@ namespace lldb_private {
// Return the bit field(s) from the most significant bit (msbit) to the
// least significant bit (lsbit) of a 64-bit unsigned value.
-static inline uint64_t
-Bits64 (const uint64_t bits, const uint32_t msbit, const uint32_t lsbit)
-{
- assert(msbit < 64 && lsbit <= msbit);
- return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1);
+static inline uint64_t Bits64(const uint64_t bits, const uint32_t msbit,
+ const uint32_t lsbit) {
+ assert(msbit < 64 && lsbit <= msbit);
+ return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1);
}
// Return the bit field(s) from the most significant bit (msbit) to the
// least significant bit (lsbit) of a 32-bit unsigned value.
-static inline uint32_t
-Bits32 (const uint32_t bits, const uint32_t msbit, const uint32_t lsbit)
-{
- assert(msbit < 32 && lsbit <= msbit);
- return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
+static inline uint32_t Bits32(const uint32_t bits, const uint32_t msbit,
+ const uint32_t lsbit) {
+ assert(msbit < 32 && lsbit <= msbit);
+ return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
}
// Return the bit value from the 'bit' position of a 32-bit unsigned value.
-static inline uint32_t
-Bit32 (const uint32_t bits, const uint32_t bit)
-{
- return (bits >> bit) & 1u;
+static inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) {
+ return (bits >> bit) & 1u;
}
-static inline uint64_t
-Bit64 (const uint64_t bits, const uint32_t bit)
-{
- return (bits >> bit) & 1ull;
+static inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) {
+ return (bits >> bit) & 1ull;
}
// Set the bit field(s) from the most significant bit (msbit) to the
// least significant bit (lsbit) of a 32-bit unsigned value to 'val'.
-static inline void
-SetBits32(uint32_t &bits, const uint32_t msbit, const uint32_t lsbit, const uint32_t val)
-{
- assert(msbit < 32 && lsbit < 32 && msbit >= lsbit);
- uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1);
- bits &= ~(mask << lsbit);
- bits |= (val & mask) << lsbit;
+static inline void SetBits32(uint32_t &bits, const uint32_t msbit,
+ const uint32_t lsbit, const uint32_t val) {
+ assert(msbit < 32 && lsbit < 32 && msbit >= lsbit);
+ uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1);
+ bits &= ~(mask << lsbit);
+ bits |= (val & mask) << lsbit;
}
// Set the 'bit' position of a 32-bit unsigned value to 'val'.
-static inline void
-SetBit32(uint32_t &bits, const uint32_t bit, const uint32_t val)
-{
- SetBits32(bits, bit, bit, val);
+static inline void SetBit32(uint32_t &bits, const uint32_t bit,
+ const uint32_t val) {
+ SetBits32(bits, bit, bit, val);
}
// Rotate a 32-bit unsigned value right by the specified amount.
-static inline uint32_t
-Rotr32 (uint32_t bits, uint32_t amt)
-{
- assert(amt < 32 && "Invalid rotate amount");
- return (bits >> amt) | (bits << ((32-amt)&31));
+static inline uint32_t Rotr32(uint32_t bits, uint32_t amt) {
+ assert(amt < 32 && "Invalid rotate amount");
+ return (bits >> amt) | (bits << ((32 - amt) & 31));
}
// Rotate a 32-bit unsigned value left by the specified amount.
-static inline uint32_t
-Rotl32 (uint32_t bits, uint32_t amt)
-{
- assert(amt < 32 && "Invalid rotate amount");
- return (bits << amt) | (bits >> ((32-amt)&31));
+static inline uint32_t Rotl32(uint32_t bits, uint32_t amt) {
+ assert(amt < 32 && "Invalid rotate amount");
+ return (bits << amt) | (bits >> ((32 - amt) & 31));
}
// Create a mask that starts at bit zero and includes "bit"
-static inline uint64_t
-MaskUpToBit (const uint64_t bit)
-{
- if (bit >= 63)
- return -1ll;
- return (1ull << (bit + 1ull)) - 1ull;
+static inline uint64_t MaskUpToBit(const uint64_t bit) {
+ if (bit >= 63)
+ return -1ll;
+ return (1ull << (bit + 1ull)) - 1ull;
}
// Return an integer result equal to the number of bits of x that are ones.
-static inline uint32_t
-BitCount (uint64_t x)
-{
- // c accumulates the total bits set in x
- uint32_t c;
- for (c = 0; x; ++c)
- {
- x &= x - 1; // clear the least significant bit set
- }
- return c;
+static inline uint32_t BitCount(uint64_t x) {
+ // c accumulates the total bits set in x
+ uint32_t c;
+ for (c = 0; x; ++c) {
+ x &= x - 1; // clear the least significant bit set
+ }
+ return c;
}
-static inline bool
-BitIsSet (const uint64_t value, const uint64_t bit)
-{
- return (value & (1ull << bit)) != 0;
+static inline bool BitIsSet(const uint64_t value, const uint64_t bit) {
+ return (value & (1ull << bit)) != 0;
}
-static inline bool
-BitIsClear (const uint64_t value, const uint64_t bit)
-{
- return (value & (1ull << bit)) == 0;
+static inline bool BitIsClear(const uint64_t value, const uint64_t bit) {
+ return (value & (1ull << bit)) == 0;
}
-static inline uint64_t
-UnsignedBits (const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
-{
- uint64_t result = value >> lsbit;
- result &= MaskUpToBit (msbit - lsbit);
- return result;
+static inline uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit,
+ const uint64_t lsbit) {
+ uint64_t result = value >> lsbit;
+ result &= MaskUpToBit(msbit - lsbit);
+ return result;
}
-static inline int64_t
-SignedBits (const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
-{
- uint64_t result = UnsignedBits (value, msbit, lsbit);
- if (BitIsSet(value, msbit))
- {
- // Sign extend
- result |= ~MaskUpToBit (msbit - lsbit);
- }
- return result;
+static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit,
+ const uint64_t lsbit) {
+ uint64_t result = UnsignedBits(value, msbit, lsbit);
+ if (BitIsSet(value, msbit)) {
+ // Sign extend
+ result |= ~MaskUpToBit(msbit - lsbit);
+ }
+ return result;
}
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_InstructionUtils_h_
+#endif // lldb_InstructionUtils_h_
diff --git a/source/Plugins/Process/Utility/LinuxSignals.cpp b/source/Plugins/Process/Utility/LinuxSignals.cpp
index 5687577f9d16..eb01075ed133 100644
--- a/source/Plugins/Process/Utility/LinuxSignals.cpp
+++ b/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -14,80 +14,83 @@
using namespace lldb_private;
-LinuxSignals::LinuxSignals()
- : UnixSignals()
-{
- Reset();
-}
+LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); }
-void
-LinuxSignals::Reset()
-{
- m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ====== ====================================== ======
- AddSignal (1, "SIGHUP", false, true , true , "hangup" );
- AddSignal (2, "SIGINT", true , true , true , "interrupt" );
- AddSignal (3, "SIGQUIT", false, true , true , "quit" );
- AddSignal (4, "SIGILL", false, true , true , "illegal instruction" );
- AddSignal (5, "SIGTRAP", true , true , true , "trace trap (not reset when caught)" );
- AddSignal (6, "SIGABRT", false, true , true , "abort()/IOT trap", "SIGIOT");
- AddSignal (7, "SIGBUS", false, true , true , "bus error" );
- AddSignal (8, "SIGFPE", false, true , true , "floating point exception" );
- AddSignal (9, "SIGKILL", false, true , true , "kill" );
- AddSignal (10, "SIGUSR1", false, true , true , "user defined signal 1" );
- AddSignal (11, "SIGSEGV", false, true , true , "segmentation violation" );
- AddSignal (12, "SIGUSR2", false, true , true , "user defined signal 2" );
- AddSignal (13, "SIGPIPE", false, true , true , "write to pipe with reading end closed" );
- AddSignal (14, "SIGALRM", false, false, false, "alarm" );
- AddSignal (15, "SIGTERM", false, true , true , "termination requested" );
- AddSignal (16, "SIGSTKFLT", false, true , true , "stack fault" );
- AddSignal (17, "SIGCHLD", false, false, true , "child status has changed", "SIGCLD");
- AddSignal (18, "SIGCONT", false, true , true , "process continue" );
- AddSignal (19, "SIGSTOP", true , true , true , "process stop" );
- AddSignal (20, "SIGTSTP", false, true , true , "tty stop" );
- AddSignal (21, "SIGTTIN", false, true , true , "background tty read" );
- AddSignal (22, "SIGTTOU", false, true , true , "background tty write" );
- AddSignal (23, "SIGURG", false, true , true , "urgent data on socket" );
- AddSignal (24, "SIGXCPU", false, true , true , "CPU resource exceeded" );
- AddSignal (25, "SIGXFSZ", false, true , true , "file size limit exceeded" );
- AddSignal (26, "SIGVTALRM", false, true , true , "virtual time alarm" );
- AddSignal (27, "SIGPROF", false, false, false, "profiling time alarm" );
- AddSignal (28, "SIGWINCH", false, true , true , "window size changes" );
- AddSignal (29, "SIGIO", false, true , true , "input/output ready/Pollable event", "SIGPOLL");
- AddSignal (30, "SIGPWR", false, true , true , "power failure" );
- AddSignal (31, "SIGSYS", false, true , true , "invalid system call" );
- AddSignal (32, "SIG32", false, false, false, "threading library internal signal 1" );
- AddSignal (33, "SIG33", false, false, false, "threading library internal signal 2" );
- AddSignal (34, "SIGRTMIN", false, false, false, "real time signal 0" );
- AddSignal (35, "SIGRTMIN+1", false, false, false, "real time signal 1" );
- AddSignal (36, "SIGRTMIN+2", false, false, false, "real time signal 2" );
- AddSignal (37, "SIGRTMIN+3", false, false, false, "real time signal 3" );
- AddSignal (38, "SIGRTMIN+4", false, false, false, "real time signal 4" );
- AddSignal (39, "SIGRTMIN+5", false, false, false, "real time signal 5" );
- AddSignal (40, "SIGRTMIN+6", false, false, false, "real time signal 6" );
- AddSignal (41, "SIGRTMIN+7", false, false, false, "real time signal 7" );
- AddSignal (42, "SIGRTMIN+8", false, false, false, "real time signal 8" );
- AddSignal (43, "SIGRTMIN+9", false, false, false, "real time signal 9" );
- AddSignal (44, "SIGRTMIN+10", false, false, false, "real time signal 10" );
- AddSignal (45, "SIGRTMIN+11", false, false, false, "real time signal 11" );
- AddSignal (46, "SIGRTMIN+12", false, false, false, "real time signal 12" );
- AddSignal (47, "SIGRTMIN+13", false, false, false, "real time signal 13" );
- AddSignal (48, "SIGRTMIN+14", false, false, false, "real time signal 14" );
- AddSignal (49, "SIGRTMIN+15", false, false, false, "real time signal 15" );
- AddSignal (50, "SIGRTMAX-14", false, false, false, "real time signal 16" ); // switching to SIGRTMAX-xxx to match "kill -l" output
- AddSignal (51, "SIGRTMAX-13", false, false, false, "real time signal 17" );
- AddSignal (52, "SIGRTMAX-12", false, false, false, "real time signal 18" );
- AddSignal (53, "SIGRTMAX-11", false, false, false, "real time signal 19" );
- AddSignal (54, "SIGRTMAX-10", false, false, false, "real time signal 20" );
- AddSignal (55, "SIGRTMAX-9", false, false, false, "real time signal 21" );
- AddSignal (56, "SIGRTMAX-8", false, false, false, "real time signal 22" );
- AddSignal (57, "SIGRTMAX-7", false, false, false, "real time signal 23" );
- AddSignal (58, "SIGRTMAX-6", false, false, false, "real time signal 24" );
- AddSignal (59, "SIGRTMAX-5", false, false, false, "real time signal 25" );
- AddSignal (60, "SIGRTMAX-4", false, false, false, "real time signal 26" );
- AddSignal (61, "SIGRTMAX-3", false, false, false, "real time signal 27" );
- AddSignal (62, "SIGRTMAX-2", false, false, false, "real time signal 28" );
- AddSignal (63, "SIGRTMAX-1", false, false, false, "real time signal 29" );
- AddSignal (64, "SIGRTMAX", false, false, false, "real time signal 30" );
+void LinuxSignals::Reset() {
+ m_signals.clear();
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
+ // ===== =========== ======== ===== ======
+ // ====================================== ======
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true,
+ "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGBUS", false, true, true, "bus error");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(13, "SIGPIPE", false, true, true,
+ "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault");
+ AddSignal(17, "SIGCHLD", false, false, true, "child status has changed",
+ "SIGCLD");
+ AddSignal(18, "SIGCONT", false, true, true, "process continue");
+ AddSignal(19, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(20, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(21, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(22, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(23, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(28, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event",
+ "SIGPOLL");
+ AddSignal(30, "SIGPWR", false, true, true, "power failure");
+ AddSignal(31, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(32, "SIG32", false, false, false,
+ "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false,
+ "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false,
+ "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
+ // -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
}
diff --git a/source/Plugins/Process/Utility/LinuxSignals.h b/source/Plugins/Process/Utility/LinuxSignals.h
index dd9062f040a2..e41126225cee 100644
--- a/source/Plugins/Process/Utility/LinuxSignals.h
+++ b/source/Plugins/Process/Utility/LinuxSignals.h
@@ -19,14 +19,12 @@
namespace lldb_private {
/// Linux specific set of Unix signals.
-class LinuxSignals : public UnixSignals
-{
+class LinuxSignals : public UnixSignals {
public:
- LinuxSignals();
+ LinuxSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
index 422fc9b642d0..36231023aa3a 100644
--- a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
+++ b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
@@ -1,4 +1,5 @@
-//===-- MipsLinuxSignals.cpp ----------------------------------------*- C++ -*-===//
+//===-- MipsLinuxSignals.cpp ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,80 +15,83 @@
using namespace lldb_private;
-MipsLinuxSignals::MipsLinuxSignals()
- : UnixSignals()
-{
- Reset();
-}
+MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() { Reset(); }
-void
-MipsLinuxSignals::Reset()
-{
- m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ====== ====================================== ========
- AddSignal (1, "SIGHUP", false, true , true , "hangup" );
- AddSignal (2, "SIGINT", true , true , true , "interrupt" );
- AddSignal (3, "SIGQUIT", false, true , true , "quit" );
- AddSignal (4, "SIGILL", false, true , true , "illegal instruction" );
- AddSignal (5, "SIGTRAP", true , true , true , "trace trap (not reset when caught)" );
- AddSignal (6, "SIGABRT", false, true , true , "abort()/IOT trap", "SIGIOT");
- AddSignal (7, "SIGEMT", false, true , true , "terminate process with core dump" );
- AddSignal (8, "SIGFPE", false, true , true , "floating point exception" );
- AddSignal (9, "SIGKILL", false, true , true , "kill" );
- AddSignal (10, "SIGBUS", false, true , true , "bus error" );
- AddSignal (11, "SIGSEGV", false, true , true , "segmentation violation" );
- AddSignal (12, "SIGSYS", false, true , true , "invalid system call" );
- AddSignal (13, "SIGPIPE", false, true , true , "write to pipe with reading end closed" );
- AddSignal (14, "SIGALRM", false, false, false, "alarm" );
- AddSignal (15, "SIGTERM", false, true , true , "termination requested" );
- AddSignal (16, "SIGUSR1", false, true , true , "user defined signal 1" );
- AddSignal (17, "SIGUSR2", false, true , true , "user defined signal 2" );
- AddSignal (18, "SIGCHLD", false, false, true , "child status has changed", "SIGCLD");
- AddSignal (19, "SIGPWR", false, true , true , "power failure" );
- AddSignal (20, "SIGWINCH", false, true , true , "window size changes" );
- AddSignal (21, "SIGURG", false, true , true , "urgent data on socket" );
- AddSignal (22, "SIGIO", false, true , true , "input/output ready/Pollable event", "SIGPOLL");
- AddSignal (23, "SIGSTOP", true , true , true , "process stop" );
- AddSignal (24, "SIGTSTP", false, true , true , "tty stop" );
- AddSignal (25, "SIGCONT", false, true , true , "process continue" );
- AddSignal (26, "SIGTTIN", false, true , true , "background tty read" );
- AddSignal (27, "SIGTTOU", false, true , true , "background tty write" );
- AddSignal (28, "SIGVTALRM", false, true , true , "virtual time alarm" );
- AddSignal (29, "SIGPROF", false, false, false, "profiling time alarm" );
- AddSignal (30, "SIGXCPU", false, true , true , "CPU resource exceeded" );
- AddSignal (31, "SIGXFSZ", false, true , true , "file size limit exceeded" );
- AddSignal (32, "SIG32", false, false, false, "threading library internal signal 1" );
- AddSignal (33, "SIG33", false, false, false, "threading library internal signal 2" );
- AddSignal (34, "SIGRTMIN", false, false, false, "real time signal 0" );
- AddSignal (35, "SIGRTMIN+1", false, false, false, "real time signal 1" );
- AddSignal (36, "SIGRTMIN+2", false, false, false, "real time signal 2" );
- AddSignal (37, "SIGRTMIN+3", false, false, false, "real time signal 3" );
- AddSignal (38, "SIGRTMIN+4", false, false, false, "real time signal 4" );
- AddSignal (39, "SIGRTMIN+5", false, false, false, "real time signal 5" );
- AddSignal (40, "SIGRTMIN+6", false, false, false, "real time signal 6" );
- AddSignal (41, "SIGRTMIN+7", false, false, false, "real time signal 7" );
- AddSignal (42, "SIGRTMIN+8", false, false, false, "real time signal 8" );
- AddSignal (43, "SIGRTMIN+9", false, false, false, "real time signal 9" );
- AddSignal (44, "SIGRTMIN+10", false, false, false, "real time signal 10" );
- AddSignal (45, "SIGRTMIN+11", false, false, false, "real time signal 11" );
- AddSignal (46, "SIGRTMIN+12", false, false, false, "real time signal 12" );
- AddSignal (47, "SIGRTMIN+13", false, false, false, "real time signal 13" );
- AddSignal (48, "SIGRTMIN+14", false, false, false, "real time signal 14" );
- AddSignal (49, "SIGRTMIN+15", false, false, false, "real time signal 15" );
- AddSignal (50, "SIGRTMAX-14", false, false, false, "real time signal 16" ); // switching to SIGRTMAX-xxx to match "kill -l" output
- AddSignal (51, "SIGRTMAX-13", false, false, false, "real time signal 17" );
- AddSignal (52, "SIGRTMAX-12", false, false, false, "real time signal 18" );
- AddSignal (53, "SIGRTMAX-11", false, false, false, "real time signal 19" );
- AddSignal (54, "SIGRTMAX-10", false, false, false, "real time signal 20" );
- AddSignal (55, "SIGRTMAX-9", false, false, false, "real time signal 21" );
- AddSignal (56, "SIGRTMAX-8", false, false, false, "real time signal 22" );
- AddSignal (57, "SIGRTMAX-7", false, false, false, "real time signal 23" );
- AddSignal (58, "SIGRTMAX-6", false, false, false, "real time signal 24" );
- AddSignal (59, "SIGRTMAX-5", false, false, false, "real time signal 25" );
- AddSignal (60, "SIGRTMAX-4", false, false, false, "real time signal 26" );
- AddSignal (61, "SIGRTMAX-3", false, false, false, "real time signal 27" );
- AddSignal (62, "SIGRTMAX-2", false, false, false, "real time signal 28" );
- AddSignal (63, "SIGRTMAX-1", false, false, false, "real time signal 29" );
- AddSignal (64, "SIGRTMAX", false, false, false, "real time signal 30" );
+void MipsLinuxSignals::Reset() {
+ m_signals.clear();
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
+ // ===== =========== ======== ===== ======
+ // ====================================== ========
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true,
+ "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGBUS", false, true, true, "bus error");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(13, "SIGPIPE", false, true, true,
+ "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(18, "SIGCHLD", false, false, true, "child status has changed",
+ "SIGCLD");
+ AddSignal(19, "SIGPWR", false, true, true, "power failure");
+ AddSignal(20, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(21, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event",
+ "SIGPOLL");
+ AddSignal(23, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(24, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(25, "SIGCONT", false, true, true, "process continue");
+ AddSignal(26, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(27, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(32, "SIG32", false, false, false,
+ "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false,
+ "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false,
+ "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
+ // -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
}
diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.h b/source/Plugins/Process/Utility/MipsLinuxSignals.h
index a5041b50eea3..e48ea5943f2b 100644
--- a/source/Plugins/Process/Utility/MipsLinuxSignals.h
+++ b/source/Plugins/Process/Utility/MipsLinuxSignals.h
@@ -1,4 +1,5 @@
-//===-- MipsLinuxSignals.h ------------------------------------------*- C++ -*-===//
+//===-- MipsLinuxSignals.h ------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,14 +20,12 @@
namespace lldb_private {
/// Linux specific set of Unix signals.
-class MipsLinuxSignals : public UnixSignals
-{
+class MipsLinuxSignals : public UnixSignals {
public:
- MipsLinuxSignals();
+ MipsLinuxSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/NetBSDSignals.cpp b/source/Plugins/Process/Utility/NetBSDSignals.cpp
index 5dce51616c4e..9b9db51e5167 100644
--- a/source/Plugins/Process/Utility/NetBSDSignals.cpp
+++ b/source/Plugins/Process/Utility/NetBSDSignals.cpp
@@ -15,20 +15,16 @@
using namespace lldb_private;
-NetBSDSignals::NetBSDSignals()
- : UnixSignals()
-{
- Reset();
-}
+NetBSDSignals::NetBSDSignals() : UnixSignals() { Reset(); }
-void
-NetBSDSignals::Reset()
-{
- UnixSignals::Reset();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
- // ====== ============ ======== ====== ====== ===================================================
- AddSignal (32, "SIGPWR", false, true , true , "power fail/restart (not reset when caught)");
+void NetBSDSignals::Reset() {
+ UnixSignals::Reset();
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============ ======== ====== ======
+ // ===================================================
+ AddSignal(32, "SIGPWR", false, true, true,
+ "power fail/restart (not reset when caught)");
#ifdef SIGRTMIN /* SIGRTMAX */
- /* Kernel only; not exposed to userland yet */
+ /* Kernel only; not exposed to userland yet */
#endif
}
diff --git a/source/Plugins/Process/Utility/NetBSDSignals.h b/source/Plugins/Process/Utility/NetBSDSignals.h
index 441402b056db..4338f881645e 100644
--- a/source/Plugins/Process/Utility/NetBSDSignals.h
+++ b/source/Plugins/Process/Utility/NetBSDSignals.h
@@ -16,14 +16,12 @@
namespace lldb_private {
/// NetBSD specific set of Unix signals.
-class NetBSDSignals : public UnixSignals
-{
+class NetBSDSignals : public UnixSignals {
public:
- NetBSDSignals();
+ NetBSDSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index 1d0fc4fb7020..52ace5602f49 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -42,403 +42,926 @@
using namespace lldb;
using namespace lldb_private;
-enum
-{
- gpr_r0 = 0,
- gpr_r1,
- gpr_r2,
- gpr_r3,
- gpr_r4,
- gpr_r5,
- gpr_r6,
- gpr_r7,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13, gpr_sp = gpr_r13,
- gpr_r14, gpr_lr = gpr_r14,
- gpr_r15, gpr_pc = gpr_r15,
- gpr_cpsr,
-
- fpu_s0,
- fpu_s1,
- fpu_s2,
- fpu_s3,
- fpu_s4,
- fpu_s5,
- fpu_s6,
- fpu_s7,
- fpu_s8,
- fpu_s9,
- fpu_s10,
- fpu_s11,
- fpu_s12,
- fpu_s13,
- fpu_s14,
- fpu_s15,
- fpu_s16,
- fpu_s17,
- fpu_s18,
- fpu_s19,
- fpu_s20,
- fpu_s21,
- fpu_s22,
- fpu_s23,
- fpu_s24,
- fpu_s25,
- fpu_s26,
- fpu_s27,
- fpu_s28,
- fpu_s29,
- fpu_s30,
- fpu_s31,
- fpu_fpscr,
-
- exc_exception,
- exc_fsr,
- exc_far,
-
- dbg_bvr0,
- dbg_bvr1,
- dbg_bvr2,
- dbg_bvr3,
- dbg_bvr4,
- dbg_bvr5,
- dbg_bvr6,
- dbg_bvr7,
- dbg_bvr8,
- dbg_bvr9,
- dbg_bvr10,
- dbg_bvr11,
- dbg_bvr12,
- dbg_bvr13,
- dbg_bvr14,
- dbg_bvr15,
-
- dbg_bcr0,
- dbg_bcr1,
- dbg_bcr2,
- dbg_bcr3,
- dbg_bcr4,
- dbg_bcr5,
- dbg_bcr6,
- dbg_bcr7,
- dbg_bcr8,
- dbg_bcr9,
- dbg_bcr10,
- dbg_bcr11,
- dbg_bcr12,
- dbg_bcr13,
- dbg_bcr14,
- dbg_bcr15,
-
- dbg_wvr0,
- dbg_wvr1,
- dbg_wvr2,
- dbg_wvr3,
- dbg_wvr4,
- dbg_wvr5,
- dbg_wvr6,
- dbg_wvr7,
- dbg_wvr8,
- dbg_wvr9,
- dbg_wvr10,
- dbg_wvr11,
- dbg_wvr12,
- dbg_wvr13,
- dbg_wvr14,
- dbg_wvr15,
-
- dbg_wcr0,
- dbg_wcr1,
- dbg_wcr2,
- dbg_wcr3,
- dbg_wcr4,
- dbg_wcr5,
- dbg_wcr6,
- dbg_wcr7,
- dbg_wcr8,
- dbg_wcr9,
- dbg_wcr10,
- dbg_wcr11,
- dbg_wcr12,
- dbg_wcr13,
- dbg_wcr14,
- dbg_wcr15,
-
- k_num_registers
+enum {
+ gpr_r0 = 0,
+ gpr_r1,
+ gpr_r2,
+ gpr_r3,
+ gpr_r4,
+ gpr_r5,
+ gpr_r6,
+ gpr_r7,
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_r13,
+ gpr_sp = gpr_r13,
+ gpr_r14,
+ gpr_lr = gpr_r14,
+ gpr_r15,
+ gpr_pc = gpr_r15,
+ gpr_cpsr,
+
+ fpu_s0,
+ fpu_s1,
+ fpu_s2,
+ fpu_s3,
+ fpu_s4,
+ fpu_s5,
+ fpu_s6,
+ fpu_s7,
+ fpu_s8,
+ fpu_s9,
+ fpu_s10,
+ fpu_s11,
+ fpu_s12,
+ fpu_s13,
+ fpu_s14,
+ fpu_s15,
+ fpu_s16,
+ fpu_s17,
+ fpu_s18,
+ fpu_s19,
+ fpu_s20,
+ fpu_s21,
+ fpu_s22,
+ fpu_s23,
+ fpu_s24,
+ fpu_s25,
+ fpu_s26,
+ fpu_s27,
+ fpu_s28,
+ fpu_s29,
+ fpu_s30,
+ fpu_s31,
+ fpu_fpscr,
+
+ exc_exception,
+ exc_fsr,
+ exc_far,
+
+ dbg_bvr0,
+ dbg_bvr1,
+ dbg_bvr2,
+ dbg_bvr3,
+ dbg_bvr4,
+ dbg_bvr5,
+ dbg_bvr6,
+ dbg_bvr7,
+ dbg_bvr8,
+ dbg_bvr9,
+ dbg_bvr10,
+ dbg_bvr11,
+ dbg_bvr12,
+ dbg_bvr13,
+ dbg_bvr14,
+ dbg_bvr15,
+
+ dbg_bcr0,
+ dbg_bcr1,
+ dbg_bcr2,
+ dbg_bcr3,
+ dbg_bcr4,
+ dbg_bcr5,
+ dbg_bcr6,
+ dbg_bcr7,
+ dbg_bcr8,
+ dbg_bcr9,
+ dbg_bcr10,
+ dbg_bcr11,
+ dbg_bcr12,
+ dbg_bcr13,
+ dbg_bcr14,
+ dbg_bcr15,
+
+ dbg_wvr0,
+ dbg_wvr1,
+ dbg_wvr2,
+ dbg_wvr3,
+ dbg_wvr4,
+ dbg_wvr5,
+ dbg_wvr6,
+ dbg_wvr7,
+ dbg_wvr8,
+ dbg_wvr9,
+ dbg_wvr10,
+ dbg_wvr11,
+ dbg_wvr12,
+ dbg_wvr13,
+ dbg_wvr14,
+ dbg_wvr15,
+
+ dbg_wcr0,
+ dbg_wcr1,
+ dbg_wcr2,
+ dbg_wcr3,
+ dbg_wcr4,
+ dbg_wcr5,
+ dbg_wcr6,
+ dbg_wcr7,
+ dbg_wcr8,
+ dbg_wcr9,
+ dbg_wcr10,
+ dbg_wcr11,
+ dbg_wcr12,
+ dbg_wcr13,
+ dbg_wcr14,
+ dbg_wcr15,
+
+ k_num_registers
};
-
-#define GPR_OFFSET(idx) ((idx) * 4)
-#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR))
-#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU))
-#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))
+#define GPR_OFFSET(idx) ((idx)*4)
+#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))
+#define EXC_OFFSET(idx) \
+ ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \
+ sizeof(RegisterContextDarwin_arm::FPU))
+#define DBG_OFFSET(reg) \
+ ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \
+ sizeof(RegisterContextDarwin_arm::GPR) + \
+ sizeof(RegisterContextDarwin_arm::FPU) + \
+ sizeof(RegisterContextDarwin_arm::EXC)))
+
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ nullptr, nullptr, nullptr, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_arm::GPR) + \
+ sizeof(RegisterContextDarwin_arm::FPU) + \
+ sizeof(RegisterContextDarwin_arm::EXC))
static RegisterInfo g_register_infos[] = {
-// General purpose registers
-// NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
-// ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== ===============
-{ "r0", NULL, 4, GPR_OFFSET(0), eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0 }, NULL, NULL},
-{ "r1", NULL, 4, GPR_OFFSET(1), eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1 }, NULL, NULL},
-{ "r2", NULL, 4, GPR_OFFSET(2), eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2 }, NULL, NULL},
-{ "r3", NULL, 4, GPR_OFFSET(3), eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3 }, NULL, NULL},
-{ "r4", NULL, 4, GPR_OFFSET(4), eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4 }, NULL, NULL},
-{ "r5", NULL, 4, GPR_OFFSET(5), eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5 }, NULL, NULL},
-{ "r6", NULL, 4, GPR_OFFSET(6), eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6 }, NULL, NULL},
-{ "r7", NULL, 4, GPR_OFFSET(7), eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_r7 }, NULL, NULL},
-{ "r8", NULL, 4, GPR_OFFSET(8), eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8 }, NULL, NULL},
-{ "r9", NULL, 4, GPR_OFFSET(9), eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9 }, NULL, NULL},
-{ "r10", NULL, 4, GPR_OFFSET(10), eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r10 }, NULL, NULL},
-{ "r11", NULL, 4, GPR_OFFSET(11), eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r11 }, NULL, NULL},
-{ "r12", NULL, 4, GPR_OFFSET(12), eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r12 }, NULL, NULL},
-{ "sp", "r13", 4, GPR_OFFSET(13), eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp }, NULL, NULL},
-{ "lr", "r14", 4, GPR_OFFSET(14), eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr }, NULL, NULL},
-{ "pc", "r15", 4, GPR_OFFSET(15), eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc }, NULL, NULL},
-{ "cpsr", "psr", 4, GPR_OFFSET(16), eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr }, NULL, NULL},
-
-{ "s0", NULL, 4, FPU_OFFSET(0), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0 }, NULL, NULL},
-{ "s1", NULL, 4, FPU_OFFSET(1), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1 }, NULL, NULL},
-{ "s2", NULL, 4, FPU_OFFSET(2), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2 }, NULL, NULL},
-{ "s3", NULL, 4, FPU_OFFSET(3), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3 }, NULL, NULL},
-{ "s4", NULL, 4, FPU_OFFSET(4), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4 }, NULL, NULL},
-{ "s5", NULL, 4, FPU_OFFSET(5), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5 }, NULL, NULL},
-{ "s6", NULL, 4, FPU_OFFSET(6), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6 }, NULL, NULL},
-{ "s7", NULL, 4, FPU_OFFSET(7), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7 }, NULL, NULL},
-{ "s8", NULL, 4, FPU_OFFSET(8), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8 }, NULL, NULL},
-{ "s9", NULL, 4, FPU_OFFSET(9), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9 }, NULL, NULL},
-{ "s10", NULL, 4, FPU_OFFSET(10), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10 }, NULL, NULL},
-{ "s11", NULL, 4, FPU_OFFSET(11), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11 }, NULL, NULL},
-{ "s12", NULL, 4, FPU_OFFSET(12), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12 }, NULL, NULL},
-{ "s13", NULL, 4, FPU_OFFSET(13), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13 }, NULL, NULL},
-{ "s14", NULL, 4, FPU_OFFSET(14), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14 }, NULL, NULL},
-{ "s15", NULL, 4, FPU_OFFSET(15), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15 }, NULL, NULL},
-{ "s16", NULL, 4, FPU_OFFSET(16), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16 }, NULL, NULL},
-{ "s17", NULL, 4, FPU_OFFSET(17), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17 }, NULL, NULL},
-{ "s18", NULL, 4, FPU_OFFSET(18), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18 }, NULL, NULL},
-{ "s19", NULL, 4, FPU_OFFSET(19), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19 }, NULL, NULL},
-{ "s20", NULL, 4, FPU_OFFSET(20), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20 }, NULL, NULL},
-{ "s21", NULL, 4, FPU_OFFSET(21), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21 }, NULL, NULL},
-{ "s22", NULL, 4, FPU_OFFSET(22), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22 }, NULL, NULL},
-{ "s23", NULL, 4, FPU_OFFSET(23), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23 }, NULL, NULL},
-{ "s24", NULL, 4, FPU_OFFSET(24), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24 }, NULL, NULL},
-{ "s25", NULL, 4, FPU_OFFSET(25), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25 }, NULL, NULL},
-{ "s26", NULL, 4, FPU_OFFSET(26), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26 }, NULL, NULL},
-{ "s27", NULL, 4, FPU_OFFSET(27), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27 }, NULL, NULL},
-{ "s28", NULL, 4, FPU_OFFSET(28), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28 }, NULL, NULL},
-{ "s29", NULL, 4, FPU_OFFSET(29), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29 }, NULL, NULL},
-{ "s30", NULL, 4, FPU_OFFSET(30), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30 }, NULL, NULL},
-{ "s31", NULL, 4, FPU_OFFSET(31), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31 }, NULL, NULL},
-{ "fpscr", NULL, 4, FPU_OFFSET(32), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpscr }, NULL, NULL},
-
-{ "exception",NULL, 4, EXC_OFFSET(0), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, NULL, NULL},
-{ "fsr", NULL, 4, EXC_OFFSET(1), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_fsr }, NULL, NULL},
-{ "far", NULL, 4, EXC_OFFSET(2), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, NULL, NULL},
-
-{ DEFINE_DBG (bvr, 0) },
-{ DEFINE_DBG (bvr, 1) },
-{ DEFINE_DBG (bvr, 2) },
-{ DEFINE_DBG (bvr, 3) },
-{ DEFINE_DBG (bvr, 4) },
-{ DEFINE_DBG (bvr, 5) },
-{ DEFINE_DBG (bvr, 6) },
-{ DEFINE_DBG (bvr, 7) },
-{ DEFINE_DBG (bvr, 8) },
-{ DEFINE_DBG (bvr, 9) },
-{ DEFINE_DBG (bvr, 10) },
-{ DEFINE_DBG (bvr, 11) },
-{ DEFINE_DBG (bvr, 12) },
-{ DEFINE_DBG (bvr, 13) },
-{ DEFINE_DBG (bvr, 14) },
-{ DEFINE_DBG (bvr, 15) },
-
-{ DEFINE_DBG (bcr, 0) },
-{ DEFINE_DBG (bcr, 1) },
-{ DEFINE_DBG (bcr, 2) },
-{ DEFINE_DBG (bcr, 3) },
-{ DEFINE_DBG (bcr, 4) },
-{ DEFINE_DBG (bcr, 5) },
-{ DEFINE_DBG (bcr, 6) },
-{ DEFINE_DBG (bcr, 7) },
-{ DEFINE_DBG (bcr, 8) },
-{ DEFINE_DBG (bcr, 9) },
-{ DEFINE_DBG (bcr, 10) },
-{ DEFINE_DBG (bcr, 11) },
-{ DEFINE_DBG (bcr, 12) },
-{ DEFINE_DBG (bcr, 13) },
-{ DEFINE_DBG (bcr, 14) },
-{ DEFINE_DBG (bcr, 15) },
-
-{ DEFINE_DBG (wvr, 0) },
-{ DEFINE_DBG (wvr, 1) },
-{ DEFINE_DBG (wvr, 2) },
-{ DEFINE_DBG (wvr, 3) },
-{ DEFINE_DBG (wvr, 4) },
-{ DEFINE_DBG (wvr, 5) },
-{ DEFINE_DBG (wvr, 6) },
-{ DEFINE_DBG (wvr, 7) },
-{ DEFINE_DBG (wvr, 8) },
-{ DEFINE_DBG (wvr, 9) },
-{ DEFINE_DBG (wvr, 10) },
-{ DEFINE_DBG (wvr, 11) },
-{ DEFINE_DBG (wvr, 12) },
-{ DEFINE_DBG (wvr, 13) },
-{ DEFINE_DBG (wvr, 14) },
-{ DEFINE_DBG (wvr, 15) },
-
-{ DEFINE_DBG (wcr, 0) },
-{ DEFINE_DBG (wcr, 1) },
-{ DEFINE_DBG (wcr, 2) },
-{ DEFINE_DBG (wcr, 3) },
-{ DEFINE_DBG (wcr, 4) },
-{ DEFINE_DBG (wcr, 5) },
-{ DEFINE_DBG (wcr, 6) },
-{ DEFINE_DBG (wcr, 7) },
-{ DEFINE_DBG (wcr, 8) },
-{ DEFINE_DBG (wcr, 9) },
-{ DEFINE_DBG (wcr, 10) },
-{ DEFINE_DBG (wcr, 11) },
-{ DEFINE_DBG (wcr, 12) },
-{ DEFINE_DBG (wcr, 13) },
-{ DEFINE_DBG (wcr, 14) },
-{ DEFINE_DBG (wcr, 15) }
-};
+ // General purpose registers
+ // NAME ALT SZ OFFSET ENCODING FORMAT
+ // EH_FRAME DWARF GENERIC
+ // PROCESS PLUGIN LLDB NATIVE
+ // ====== ======= == ============= ============= ============
+ // =============== =============== =========================
+ // ===================== =============
+ {"r0",
+ NULL,
+ 4,
+ GPR_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ NULL,
+ 4,
+ GPR_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ NULL,
+ 4,
+ GPR_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ NULL,
+ 4,
+ GPR_OFFSET(3),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ NULL,
+ 4,
+ GPR_OFFSET(4),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ NULL,
+ 4,
+ GPR_OFFSET(5),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ NULL,
+ 4,
+ GPR_OFFSET(6),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ NULL,
+ 4,
+ GPR_OFFSET(7),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ gpr_r7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ NULL,
+ 4,
+ GPR_OFFSET(8),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ NULL,
+ 4,
+ GPR_OFFSET(9),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ NULL,
+ 4,
+ GPR_OFFSET(10),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ NULL,
+ 4,
+ GPR_OFFSET(11),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ NULL,
+ 4,
+ GPR_OFFSET(12),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "r13",
+ 4,
+ GPR_OFFSET(13),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ gpr_sp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r14",
+ 4,
+ GPR_OFFSET(14),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ gpr_lr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "r15",
+ 4,
+ GPR_OFFSET(15),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ gpr_pc},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ GPR_OFFSET(16),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ gpr_cpsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"s0",
+ NULL,
+ 4,
+ FPU_OFFSET(0),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s0},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s1",
+ NULL,
+ 4,
+ FPU_OFFSET(1),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s1},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s2",
+ NULL,
+ 4,
+ FPU_OFFSET(2),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s2},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s3",
+ NULL,
+ 4,
+ FPU_OFFSET(3),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s3},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s4",
+ NULL,
+ 4,
+ FPU_OFFSET(4),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s4},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s5",
+ NULL,
+ 4,
+ FPU_OFFSET(5),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s5},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s6",
+ NULL,
+ 4,
+ FPU_OFFSET(6),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s6},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s7",
+ NULL,
+ 4,
+ FPU_OFFSET(7),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s8",
+ NULL,
+ 4,
+ FPU_OFFSET(8),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s9",
+ NULL,
+ 4,
+ FPU_OFFSET(9),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s10",
+ NULL,
+ 4,
+ FPU_OFFSET(10),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s11",
+ NULL,
+ 4,
+ FPU_OFFSET(11),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s12",
+ NULL,
+ 4,
+ FPU_OFFSET(12),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s13",
+ NULL,
+ 4,
+ FPU_OFFSET(13),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s13},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s14",
+ NULL,
+ 4,
+ FPU_OFFSET(14),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s14},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s15",
+ NULL,
+ 4,
+ FPU_OFFSET(15),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s15},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s16",
+ NULL,
+ 4,
+ FPU_OFFSET(16),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s16},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s17",
+ NULL,
+ 4,
+ FPU_OFFSET(17),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s17},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s18",
+ NULL,
+ 4,
+ FPU_OFFSET(18),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s18},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s19",
+ NULL,
+ 4,
+ FPU_OFFSET(19),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s19},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s20",
+ NULL,
+ 4,
+ FPU_OFFSET(20),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s20},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s21",
+ NULL,
+ 4,
+ FPU_OFFSET(21),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s21},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s22",
+ NULL,
+ 4,
+ FPU_OFFSET(22),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s22},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s23",
+ NULL,
+ 4,
+ FPU_OFFSET(23),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s23},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s24",
+ NULL,
+ 4,
+ FPU_OFFSET(24),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s24},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s25",
+ NULL,
+ 4,
+ FPU_OFFSET(25),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s25},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s26",
+ NULL,
+ 4,
+ FPU_OFFSET(26),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s26},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s27",
+ NULL,
+ 4,
+ FPU_OFFSET(27),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s27},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s28",
+ NULL,
+ 4,
+ FPU_OFFSET(28),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s28},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s29",
+ NULL,
+ 4,
+ FPU_OFFSET(29),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s29},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s30",
+ NULL,
+ 4,
+ FPU_OFFSET(30),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s30},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s31",
+ NULL,
+ 4,
+ FPU_OFFSET(31),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s31},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpscr",
+ NULL,
+ 4,
+ FPU_OFFSET(32),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fpscr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"exception",
+ NULL,
+ 4,
+ EXC_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_exception},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fsr",
+ NULL,
+ 4,
+ EXC_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_fsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"far",
+ NULL,
+ 4,
+ EXC_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_far},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_DBG(bvr, 0)},
+ {DEFINE_DBG(bvr, 1)},
+ {DEFINE_DBG(bvr, 2)},
+ {DEFINE_DBG(bvr, 3)},
+ {DEFINE_DBG(bvr, 4)},
+ {DEFINE_DBG(bvr, 5)},
+ {DEFINE_DBG(bvr, 6)},
+ {DEFINE_DBG(bvr, 7)},
+ {DEFINE_DBG(bvr, 8)},
+ {DEFINE_DBG(bvr, 9)},
+ {DEFINE_DBG(bvr, 10)},
+ {DEFINE_DBG(bvr, 11)},
+ {DEFINE_DBG(bvr, 12)},
+ {DEFINE_DBG(bvr, 13)},
+ {DEFINE_DBG(bvr, 14)},
+ {DEFINE_DBG(bvr, 15)},
+
+ {DEFINE_DBG(bcr, 0)},
+ {DEFINE_DBG(bcr, 1)},
+ {DEFINE_DBG(bcr, 2)},
+ {DEFINE_DBG(bcr, 3)},
+ {DEFINE_DBG(bcr, 4)},
+ {DEFINE_DBG(bcr, 5)},
+ {DEFINE_DBG(bcr, 6)},
+ {DEFINE_DBG(bcr, 7)},
+ {DEFINE_DBG(bcr, 8)},
+ {DEFINE_DBG(bcr, 9)},
+ {DEFINE_DBG(bcr, 10)},
+ {DEFINE_DBG(bcr, 11)},
+ {DEFINE_DBG(bcr, 12)},
+ {DEFINE_DBG(bcr, 13)},
+ {DEFINE_DBG(bcr, 14)},
+ {DEFINE_DBG(bcr, 15)},
+
+ {DEFINE_DBG(wvr, 0)},
+ {DEFINE_DBG(wvr, 1)},
+ {DEFINE_DBG(wvr, 2)},
+ {DEFINE_DBG(wvr, 3)},
+ {DEFINE_DBG(wvr, 4)},
+ {DEFINE_DBG(wvr, 5)},
+ {DEFINE_DBG(wvr, 6)},
+ {DEFINE_DBG(wvr, 7)},
+ {DEFINE_DBG(wvr, 8)},
+ {DEFINE_DBG(wvr, 9)},
+ {DEFINE_DBG(wvr, 10)},
+ {DEFINE_DBG(wvr, 11)},
+ {DEFINE_DBG(wvr, 12)},
+ {DEFINE_DBG(wvr, 13)},
+ {DEFINE_DBG(wvr, 14)},
+ {DEFINE_DBG(wvr, 15)},
+
+ {DEFINE_DBG(wcr, 0)},
+ {DEFINE_DBG(wcr, 1)},
+ {DEFINE_DBG(wcr, 2)},
+ {DEFINE_DBG(wcr, 3)},
+ {DEFINE_DBG(wcr, 4)},
+ {DEFINE_DBG(wcr, 5)},
+ {DEFINE_DBG(wcr, 6)},
+ {DEFINE_DBG(wcr, 7)},
+ {DEFINE_DBG(wcr, 8)},
+ {DEFINE_DBG(wcr, 9)},
+ {DEFINE_DBG(wcr, 10)},
+ {DEFINE_DBG(wcr, 11)},
+ {DEFINE_DBG(wcr, 12)},
+ {DEFINE_DBG(wcr, 13)},
+ {DEFINE_DBG(wcr, 14)},
+ {DEFINE_DBG(wcr, 15)}};
// General purpose registers
-static uint32_t
-g_gpr_regnums[] =
-{
- gpr_r0,
- gpr_r1,
- gpr_r2,
- gpr_r3,
- gpr_r4,
- gpr_r5,
- gpr_r6,
- gpr_r7,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_sp,
- gpr_lr,
- gpr_pc,
- gpr_cpsr
-};
+static uint32_t g_gpr_regnums[] = {
+ gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,
+ gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};
// Floating point registers
-static uint32_t
-g_fpu_regnums[] =
-{
- fpu_s0,
- fpu_s1,
- fpu_s2,
- fpu_s3,
- fpu_s4,
- fpu_s5,
- fpu_s6,
- fpu_s7,
- fpu_s8,
- fpu_s9,
- fpu_s10,
- fpu_s11,
- fpu_s12,
- fpu_s13,
- fpu_s14,
- fpu_s15,
- fpu_s16,
- fpu_s17,
- fpu_s18,
- fpu_s19,
- fpu_s20,
- fpu_s21,
- fpu_s22,
- fpu_s23,
- fpu_s24,
- fpu_s25,
- fpu_s26,
- fpu_s27,
- fpu_s28,
- fpu_s29,
- fpu_s30,
- fpu_s31,
- fpu_fpscr,
+static uint32_t g_fpu_regnums[] = {
+ fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6,
+ fpu_s7, fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13,
+ fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20,
+ fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25, fpu_s26, fpu_s27,
+ fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,
};
// Exception registers
-static uint32_t
-g_exc_regnums[] =
-{
- exc_exception,
- exc_fsr,
- exc_far,
+static uint32_t g_exc_regnums[] = {
+ exc_exception, exc_fsr, exc_far,
};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext(thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
-
-RegisterContextDarwin_arm::~RegisterContextDarwin_arm()
-{
+RegisterContextDarwin_arm::RegisterContextDarwin_arm(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_arm::~RegisterContextDarwin_arm() {}
-void
-RegisterContextDarwin_arm::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_arm::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_arm::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_arm::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
const RegisterInfo *
-RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos[reg];
+ return NULL;
}
-size_t
-RegisterContextDarwin_arm::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
-const RegisterInfo *
-RegisterContextDarwin_arm::GetRegisterInfos ()
-{
- return g_register_infos;
+const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {
+ return g_register_infos;
}
-
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
@@ -449,782 +972,799 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_arm::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_arm::GetRegisterSetCount() {
+ return k_num_regsets;
}
-const RegisterSet *
-RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
+const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-
//----------------------------------------------------------------------
// Register information definitions for 32 bit i386.
//----------------------------------------------------------------------
-int
-RegisterContextDarwin_arm::GetSetForNativeRegNum (int reg)
-{
- if (reg < fpu_s0)
- return GPRRegSet;
- else if (reg < exc_exception)
- return FPURegSet;
- else if (reg < k_num_registers)
- return EXCRegSet;
- return -1;
+int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {
+ if (reg < fpu_s0)
+ return GPRRegSet;
+ else if (reg < exc_exception)
+ return FPURegSet;
+ else if (reg < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-int
-RegisterContextDarwin_arm::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
- }
- return GetError(GPRRegSet, Read);
+int RegisterContextDarwin_arm::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(GPRRegSet, Read);
}
-int
-RegisterContextDarwin_arm::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
- }
- return GetError(FPURegSet, Read);
+int RegisterContextDarwin_arm::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(FPURegSet, Read);
}
-int
-RegisterContextDarwin_arm::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(EXCRegSet, Read);
+int RegisterContextDarwin_arm::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(EXCRegSet, Read);
}
-int
-RegisterContextDarwin_arm::ReadDBG (bool force)
-{
- int set = DBGRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
- }
- return GetError(DBGRegSet, Read);
+int RegisterContextDarwin_arm::ReadDBG(bool force) {
+ int set = DBGRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
+ }
+ return GetError(DBGRegSet, Read);
}
-int
-RegisterContextDarwin_arm::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError(GPRRegSet, Write);
-}
-
-int
-RegisterContextDarwin_arm::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError(FPURegSet, Write);
+int RegisterContextDarwin_arm::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(GPRRegSet, Write);
}
-int
-RegisterContextDarwin_arm::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError(EXCRegSet, Write);
+int RegisterContextDarwin_arm::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(FPURegSet, Write);
}
-int
-RegisterContextDarwin_arm::WriteDBG ()
-{
- int set = DBGRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
- SetError (set, Read, -1);
- return GetError(DBGRegSet, Write);
+int RegisterContextDarwin_arm::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(EXCRegSet, Write);
}
-
-int
-RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR(force);
- case GPRAltRegSet: return ReadGPR(force);
- case FPURegSet: return ReadFPU(force);
- case EXCRegSet: return ReadEXC(force);
- case DBGRegSet: return ReadDBG(force);
- default: break;
- }
+int RegisterContextDarwin_arm::WriteDBG() {
+ int set = DBGRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
+ SetError(set, Read, -1);
+ return GetError(DBGRegSet, Write);
}
-int
-RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set)
-{
- // Make sure we have a valid context to set.
- if (RegisterSetIsCached(set))
- {
- switch (set)
- {
- case GPRRegSet: return WriteGPR();
- case GPRAltRegSet: return WriteGPR();
- case FPURegSet: return WriteFPU();
- case EXCRegSet: return WriteEXC();
- case DBGRegSet: return WriteDBG();
- default: break;
- }
- }
- return KERN_INVALID_ARGUMENT;
+int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case GPRAltRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ case DBGRegSet:
+ return ReadDBG(force);
+ default:
+ break;
+ }
+ return KERN_INVALID_ARGUMENT;
}
-void
-RegisterContextDarwin_arm::LogDBGRegisters (Log *log, const DBG& dbg)
-{
- if (log)
- {
- for (uint32_t i=0; i<16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
- i, i, dbg.bvr[i], dbg.bcr[i],
- i, i, dbg.wvr[i], dbg.wcr[i]);
+int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ if (RegisterSetIsCached(set)) {
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case GPRAltRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ case DBGRegSet:
+ return WriteDBG();
+ default:
+ break;
}
+ }
+ return KERN_INVALID_ARGUMENT;
}
+void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
+ if (log) {
+ for (uint32_t i = 0; i < 16; i++)
+ log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
+ "0x%8.8x, 0x%8.8x }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ }
+}
-bool
-RegisterContextDarwin_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_arm::GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
+bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);
- switch (reg)
- {
- case gpr_r0:
- case gpr_r1:
- case gpr_r2:
- case gpr_r3:
- case gpr_r4:
- case gpr_r5:
- case gpr_r6:
- case gpr_r7:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- value.SetUInt32 (gpr.r[reg - gpr_r0]);
- break;
-
- case fpu_s0:
- case fpu_s1:
- case fpu_s2:
- case fpu_s3:
- case fpu_s4:
- case fpu_s5:
- case fpu_s6:
- case fpu_s7:
- case fpu_s8:
- case fpu_s9:
- case fpu_s10:
- case fpu_s11:
- case fpu_s12:
- case fpu_s13:
- case fpu_s14:
- case fpu_s15:
- case fpu_s16:
- case fpu_s17:
- case fpu_s18:
- case fpu_s19:
- case fpu_s20:
- case fpu_s21:
- case fpu_s22:
- case fpu_s23:
- case fpu_s24:
- case fpu_s25:
- case fpu_s26:
- case fpu_s27:
- case fpu_s28:
- case fpu_s29:
- case fpu_s30:
- case fpu_s31:
- value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat);
- break;
-
- case fpu_fpscr:
- value.SetUInt32 (fpu.fpscr);
- break;
-
- case exc_exception:
- value.SetUInt32 (exc.exception);
- break;
- case exc_fsr:
- value.SetUInt32 (exc.fsr);
- break;
- case exc_far:
- value.SetUInt32 (exc.far);
- break;
+ if (set == -1)
+ return false;
- default:
- value.SetValueToInvalid();
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
- }
- return true;
+ switch (reg) {
+ case gpr_r0:
+ case gpr_r1:
+ case gpr_r2:
+ case gpr_r3:
+ case gpr_r4:
+ case gpr_r5:
+ case gpr_r6:
+ case gpr_r7:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ value.SetUInt32(gpr.r[reg - gpr_r0]);
+ break;
+
+ case fpu_s0:
+ case fpu_s1:
+ case fpu_s2:
+ case fpu_s3:
+ case fpu_s4:
+ case fpu_s5:
+ case fpu_s6:
+ case fpu_s7:
+ case fpu_s8:
+ case fpu_s9:
+ case fpu_s10:
+ case fpu_s11:
+ case fpu_s12:
+ case fpu_s13:
+ case fpu_s14:
+ case fpu_s15:
+ case fpu_s16:
+ case fpu_s17:
+ case fpu_s18:
+ case fpu_s19:
+ case fpu_s20:
+ case fpu_s21:
+ case fpu_s22:
+ case fpu_s23:
+ case fpu_s24:
+ case fpu_s25:
+ case fpu_s26:
+ case fpu_s27:
+ case fpu_s28:
+ case fpu_s29:
+ case fpu_s30:
+ case fpu_s31:
+ value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);
+ break;
+
+ case fpu_fpscr:
+ value.SetUInt32(fpu.fpscr);
+ break;
+
+ case exc_exception:
+ value.SetUInt32(exc.exception);
+ break;
+ case exc_fsr:
+ value.SetUInt32(exc.fsr);
+ break;
+ case exc_far:
+ value.SetUInt32(exc.far);
+ break;
+
+ default:
+ value.SetValueToInvalid();
+ return false;
+ }
+ return true;
}
+bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = GetSetForNativeRegNum(reg);
-bool
-RegisterContextDarwin_arm::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
-
- switch (reg)
- {
- case gpr_r0:
- case gpr_r1:
- case gpr_r2:
- case gpr_r3:
- case gpr_r4:
- case gpr_r5:
- case gpr_r6:
- case gpr_r7:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- gpr.r[reg - gpr_r0] = value.GetAsUInt32();
- break;
-
- case fpu_s0:
- case fpu_s1:
- case fpu_s2:
- case fpu_s3:
- case fpu_s4:
- case fpu_s5:
- case fpu_s6:
- case fpu_s7:
- case fpu_s8:
- case fpu_s9:
- case fpu_s10:
- case fpu_s11:
- case fpu_s12:
- case fpu_s13:
- case fpu_s14:
- case fpu_s15:
- case fpu_s16:
- case fpu_s17:
- case fpu_s18:
- case fpu_s19:
- case fpu_s20:
- case fpu_s21:
- case fpu_s22:
- case fpu_s23:
- case fpu_s24:
- case fpu_s25:
- case fpu_s26:
- case fpu_s27:
- case fpu_s28:
- case fpu_s29:
- case fpu_s30:
- case fpu_s31:
- fpu.floats.s[reg] = value.GetAsUInt32();
- break;
-
- case fpu_fpscr:
- fpu.fpscr = value.GetAsUInt32();
- break;
-
- case exc_exception:
- exc.exception = value.GetAsUInt32();
- break;
- case exc_fsr:
- exc.fsr = value.GetAsUInt32();
- break;
- case exc_far:
- exc.far = value.GetAsUInt32();
- break;
+ if (set == -1)
+ return false;
- default:
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
- }
- return WriteRegisterSet(set) == KERN_SUCCESS;
+ switch (reg) {
+ case gpr_r0:
+ case gpr_r1:
+ case gpr_r2:
+ case gpr_r3:
+ case gpr_r4:
+ case gpr_r5:
+ case gpr_r6:
+ case gpr_r7:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ gpr.r[reg - gpr_r0] = value.GetAsUInt32();
+ break;
+
+ case fpu_s0:
+ case fpu_s1:
+ case fpu_s2:
+ case fpu_s3:
+ case fpu_s4:
+ case fpu_s5:
+ case fpu_s6:
+ case fpu_s7:
+ case fpu_s8:
+ case fpu_s9:
+ case fpu_s10:
+ case fpu_s11:
+ case fpu_s12:
+ case fpu_s13:
+ case fpu_s14:
+ case fpu_s15:
+ case fpu_s16:
+ case fpu_s17:
+ case fpu_s18:
+ case fpu_s19:
+ case fpu_s20:
+ case fpu_s21:
+ case fpu_s22:
+ case fpu_s23:
+ case fpu_s24:
+ case fpu_s25:
+ case fpu_s26:
+ case fpu_s27:
+ case fpu_s28:
+ case fpu_s29:
+ case fpu_s30:
+ case fpu_s31:
+ fpu.floats.s[reg] = value.GetAsUInt32();
+ break;
+
+ case fpu_fpscr:
+ fpu.fpscr = value.GetAsUInt32();
+ break;
+
+ case exc_exception:
+ exc.exception = value.GetAsUInt32();
+ break;
+ case exc_fsr:
+ exc.fsr = value.GetAsUInt32();
+ break;
+ case exc_far:
+ exc.far = value.GetAsUInt32();
+ break;
+
+ default:
+ return false;
+ }
+ return WriteRegisterSet(set) == KERN_SUCCESS;
}
-bool
-RegisterContextDarwin_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == KERN_SUCCESS &&
- ReadFPU (false) == KERN_SUCCESS &&
- ReadEXC (false) == KERN_SUCCESS)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+bool RegisterContextDarwin_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
+ ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
- return false;
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextDarwin_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == KERN_SUCCESS)
- ++success_count;
- if (WriteFPU() == KERN_SUCCESS)
- ++success_count;
- if (WriteEXC() == KERN_SUCCESS)
- ++success_count;
- return success_count == 3;
- }
- return false;
+bool RegisterContextDarwin_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteFPU() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteEXC() == KERN_SUCCESS)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
}
-uint32_t
-RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
- case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_r7;
- case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
- default:
- break;
- }
- }
- else if (kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case dwarf_r0: return gpr_r0;
- case dwarf_r1: return gpr_r1;
- case dwarf_r2: return gpr_r2;
- case dwarf_r3: return gpr_r3;
- case dwarf_r4: return gpr_r4;
- case dwarf_r5: return gpr_r5;
- case dwarf_r6: return gpr_r6;
- case dwarf_r7: return gpr_r7;
- case dwarf_r8: return gpr_r8;
- case dwarf_r9: return gpr_r9;
- case dwarf_r10: return gpr_r10;
- case dwarf_r11: return gpr_r11;
- case dwarf_r12: return gpr_r12;
- case dwarf_sp: return gpr_sp;
- case dwarf_lr: return gpr_lr;
- case dwarf_pc: return gpr_pc;
- case dwarf_spsr: return gpr_cpsr;
-
- case dwarf_s0: return fpu_s0;
- case dwarf_s1: return fpu_s1;
- case dwarf_s2: return fpu_s2;
- case dwarf_s3: return fpu_s3;
- case dwarf_s4: return fpu_s4;
- case dwarf_s5: return fpu_s5;
- case dwarf_s6: return fpu_s6;
- case dwarf_s7: return fpu_s7;
- case dwarf_s8: return fpu_s8;
- case dwarf_s9: return fpu_s9;
- case dwarf_s10: return fpu_s10;
- case dwarf_s11: return fpu_s11;
- case dwarf_s12: return fpu_s12;
- case dwarf_s13: return fpu_s13;
- case dwarf_s14: return fpu_s14;
- case dwarf_s15: return fpu_s15;
- case dwarf_s16: return fpu_s16;
- case dwarf_s17: return fpu_s17;
- case dwarf_s18: return fpu_s18;
- case dwarf_s19: return fpu_s19;
- case dwarf_s20: return fpu_s20;
- case dwarf_s21: return fpu_s21;
- case dwarf_s22: return fpu_s22;
- case dwarf_s23: return fpu_s23;
- case dwarf_s24: return fpu_s24;
- case dwarf_s25: return fpu_s25;
- case dwarf_s26: return fpu_s26;
- case dwarf_s27: return fpu_s27;
- case dwarf_s28: return fpu_s28;
- case dwarf_s29: return fpu_s29;
- case dwarf_s30: return fpu_s30;
- case dwarf_s31: return fpu_s31;
-
- default:
- break;
- }
+uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_pc;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_sp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_r7;
+ case LLDB_REGNUM_GENERIC_RA:
+ return gpr_lr;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_cpsr;
+ default:
+ break;
}
- else if (kind == eRegisterKindEHFrame)
- {
- switch (reg)
- {
- case ehframe_r0: return gpr_r0;
- case ehframe_r1: return gpr_r1;
- case ehframe_r2: return gpr_r2;
- case ehframe_r3: return gpr_r3;
- case ehframe_r4: return gpr_r4;
- case ehframe_r5: return gpr_r5;
- case ehframe_r6: return gpr_r6;
- case ehframe_r7: return gpr_r7;
- case ehframe_r8: return gpr_r8;
- case ehframe_r9: return gpr_r9;
- case ehframe_r10: return gpr_r10;
- case ehframe_r11: return gpr_r11;
- case ehframe_r12: return gpr_r12;
- case ehframe_sp: return gpr_sp;
- case ehframe_lr: return gpr_lr;
- case ehframe_pc: return gpr_pc;
- case ehframe_cpsr: return gpr_cpsr;
- }
+ } else if (kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case dwarf_r0:
+ return gpr_r0;
+ case dwarf_r1:
+ return gpr_r1;
+ case dwarf_r2:
+ return gpr_r2;
+ case dwarf_r3:
+ return gpr_r3;
+ case dwarf_r4:
+ return gpr_r4;
+ case dwarf_r5:
+ return gpr_r5;
+ case dwarf_r6:
+ return gpr_r6;
+ case dwarf_r7:
+ return gpr_r7;
+ case dwarf_r8:
+ return gpr_r8;
+ case dwarf_r9:
+ return gpr_r9;
+ case dwarf_r10:
+ return gpr_r10;
+ case dwarf_r11:
+ return gpr_r11;
+ case dwarf_r12:
+ return gpr_r12;
+ case dwarf_sp:
+ return gpr_sp;
+ case dwarf_lr:
+ return gpr_lr;
+ case dwarf_pc:
+ return gpr_pc;
+ case dwarf_spsr:
+ return gpr_cpsr;
+
+ case dwarf_s0:
+ return fpu_s0;
+ case dwarf_s1:
+ return fpu_s1;
+ case dwarf_s2:
+ return fpu_s2;
+ case dwarf_s3:
+ return fpu_s3;
+ case dwarf_s4:
+ return fpu_s4;
+ case dwarf_s5:
+ return fpu_s5;
+ case dwarf_s6:
+ return fpu_s6;
+ case dwarf_s7:
+ return fpu_s7;
+ case dwarf_s8:
+ return fpu_s8;
+ case dwarf_s9:
+ return fpu_s9;
+ case dwarf_s10:
+ return fpu_s10;
+ case dwarf_s11:
+ return fpu_s11;
+ case dwarf_s12:
+ return fpu_s12;
+ case dwarf_s13:
+ return fpu_s13;
+ case dwarf_s14:
+ return fpu_s14;
+ case dwarf_s15:
+ return fpu_s15;
+ case dwarf_s16:
+ return fpu_s16;
+ case dwarf_s17:
+ return fpu_s17;
+ case dwarf_s18:
+ return fpu_s18;
+ case dwarf_s19:
+ return fpu_s19;
+ case dwarf_s20:
+ return fpu_s20;
+ case dwarf_s21:
+ return fpu_s21;
+ case dwarf_s22:
+ return fpu_s22;
+ case dwarf_s23:
+ return fpu_s23;
+ case dwarf_s24:
+ return fpu_s24;
+ case dwarf_s25:
+ return fpu_s25;
+ case dwarf_s26:
+ return fpu_s26;
+ case dwarf_s27:
+ return fpu_s27;
+ case dwarf_s28:
+ return fpu_s28;
+ case dwarf_s29:
+ return fpu_s29;
+ case dwarf_s30:
+ return fpu_s30;
+ case dwarf_s31:
+ return fpu_s31;
+
+ default:
+ break;
}
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
+ } else if (kind == eRegisterKindEHFrame) {
+ switch (reg) {
+ case ehframe_r0:
+ return gpr_r0;
+ case ehframe_r1:
+ return gpr_r1;
+ case ehframe_r2:
+ return gpr_r2;
+ case ehframe_r3:
+ return gpr_r3;
+ case ehframe_r4:
+ return gpr_r4;
+ case ehframe_r5:
+ return gpr_r5;
+ case ehframe_r6:
+ return gpr_r6;
+ case ehframe_r7:
+ return gpr_r7;
+ case ehframe_r8:
+ return gpr_r8;
+ case ehframe_r9:
+ return gpr_r9;
+ case ehframe_r10:
+ return gpr_r10;
+ case ehframe_r11:
+ return gpr_r11;
+ case ehframe_r12:
+ return gpr_r12;
+ case ehframe_sp:
+ return gpr_sp;
+ case ehframe_lr:
+ return gpr_lr;
+ case ehframe_pc:
+ return gpr_pc;
+ case ehframe_cpsr:
+ return gpr_cpsr;
}
- return LLDB_INVALID_REGNUM;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
-
-uint32_t
-RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints ()
-{
-#if defined (__arm__)
- // Set the init value to something that will let us know that we need to
- // autodetect how many breakpoints are supported dynamically...
- static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
- if (g_num_supported_hw_breakpoints == UINT32_MAX)
- {
- // Set this to zero in case we can't tell if there are any HW breakpoints
- g_num_supported_hw_breakpoints = 0;
-
- uint32_t register_DBGDIDR;
-
- asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
- g_num_supported_hw_breakpoints = Bits32 (register_DBGDIDR, 27, 24);
- // Zero is reserved for the BRP count, so don't increment it if it is zero
- if (g_num_supported_hw_breakpoints > 0)
- g_num_supported_hw_breakpoints++;
-// if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints);
-
- }
- return g_num_supported_hw_breakpoints;
+uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
+#if defined(__arm__)
+ // Set the init value to something that will let us know that we need to
+ // autodetect how many breakpoints are supported dynamically...
+ static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
+ if (g_num_supported_hw_breakpoints == UINT32_MAX) {
+ // Set this to zero in case we can't tell if there are any HW breakpoints
+ g_num_supported_hw_breakpoints = 0;
+
+ uint32_t register_DBGDIDR;
+
+ asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
+ g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);
+ // Zero is reserved for the BRP count, so don't increment it if it is zero
+ if (g_num_supported_hw_breakpoints > 0)
+ g_num_supported_hw_breakpoints++;
+ // if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)",
+ // register_DBGDIDR, g_num_supported_hw_breakpoints);
+ }
+ return g_num_supported_hw_breakpoints;
#else
- // TODO: figure out remote case here!
- return 6;
+ // TODO: figure out remote case here!
+ return 6;
#endif
}
-uint32_t
-RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- // Make sure our address isn't bogus
- if (addr & 1)
- return LLDB_INVALID_INDEX32;
+uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ // Make sure our address isn't bogus
+ if (addr & 1)
+ return LLDB_INVALID_INDEX32;
- int kret = ReadDBG (false);
+ int kret = ReadDBG(false);
- if (kret == KERN_SUCCESS)
- {
- const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
- uint32_t i;
- for (i=0; i<num_hw_breakpoints; ++i)
- {
- if ((dbg.bcr[i] & BCR_ENABLE) == 0)
- break; // We found an available hw breakpoint slot (in i)
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_breakpoints)
- {
- // Make sure bits 1:0 are clear in our address
- dbg.bvr[i] = addr & ~((lldb::addr_t)3);
-
- if (size == 2 || addr & 2)
- {
- uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
-
- // We have a thumb breakpoint
- // We have an ARM breakpoint
- dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
- byte_addr_select | // Set the correct byte address select so we only trigger on the correct opcode
- S_USER | // Which modes should this breakpoint stop in?
- BCR_ENABLE; // Enable this hardware breakpoint
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)",
-// addr,
-// size,
-// i,
-// i,
-// dbg.bvr[i],
-// dbg.bcr[i]);
- }
- else if (size == 4)
- {
- // We have an ARM breakpoint
- dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
- BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
- S_USER | // Which modes should this breakpoint stop in?
- BCR_ENABLE; // Enable this hardware breakpoint
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)",
-// addr,
-// size,
-// i,
-// i,
-// dbg.bvr[i],
-// dbg.bcr[i]);
- }
-
- kret = WriteDBG();
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- }
-// else
-// {
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size);
-// }
+ if (kret == KERN_SUCCESS) {
+ const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
+ uint32_t i;
+ for (i = 0; i < num_hw_breakpoints; ++i) {
+ if ((dbg.bcr[i] & BCR_ENABLE) == 0)
+ break; // We found an available hw breakpoint slot (in i)
}
- return LLDB_INVALID_INDEX32;
+ // See if we found an available hw breakpoint slot above
+ if (i < num_hw_breakpoints) {
+ // Make sure bits 1:0 are clear in our address
+ dbg.bvr[i] = addr & ~((lldb::addr_t)3);
+
+ if (size == 2 || addr & 2) {
+ uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
+
+ // We have a thumb breakpoint
+ // We have an ARM breakpoint
+ dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
+ byte_addr_select | // Set the correct byte address select
+ // so we only trigger on the correct
+ // opcode
+ S_USER | // Which modes should this breakpoint stop in?
+ BCR_ENABLE; // Enable this hardware breakpoint
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
+ // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
+ // 0x%8.8x (Thumb)",
+ // addr,
+ // size,
+ // i,
+ // i,
+ // dbg.bvr[i],
+ // dbg.bcr[i]);
+ } else if (size == 4) {
+ // We have an ARM breakpoint
+ dbg.bcr[i] =
+ BCR_M_IMVA_MATCH | // Stop on address mismatch
+ BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
+ S_USER | // Which modes should this breakpoint stop in?
+ BCR_ENABLE; // Enable this hardware breakpoint
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
+ // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
+ // 0x%8.8x (ARM)",
+ // addr,
+ // size,
+ // i,
+ // i,
+ // dbg.bvr[i],
+ // dbg.bcr[i]);
+ }
+
+ kret = WriteDBG();
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()
+ // WriteDBG() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return i;
+ }
+ // else
+ // {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =
+ // %8.8p, size = %u) => all hardware breakpoint resources are
+ // being used.", addr, size);
+ // }
+ }
+
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index)
-{
- int kret = ReadDBG (false);
-
- const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
- if (kret == KERN_SUCCESS)
- {
- if (hw_index < num_hw_points)
- {
- dbg.bcr[hw_index] = 0;
-// if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x",
-// hw_index,
-// hw_index,
-// dbg.bvr[hw_index],
-// hw_index,
-// dbg.bcr[hw_index]);
-
- kret = WriteDBG();
-
- if (kret == KERN_SUCCESS)
- return true;
- }
+bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
+ int kret = ReadDBG(false);
+
+ const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
+ if (kret == KERN_SUCCESS) {
+ if (hw_index < num_hw_points) {
+ dbg.bcr[hw_index] = 0;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -
+ // BVR%u = 0x%8.8x BCR%u = 0x%8.8x",
+ // hw_index,
+ // hw_index,
+ // dbg.bvr[hw_index],
+ // hw_index,
+ // dbg.bcr[hw_index]);
+
+ kret = WriteDBG();
+
+ if (kret == KERN_SUCCESS)
+ return true;
}
- return false;
+ }
+ return false;
}
-uint32_t
-RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints ()
-{
-#if defined (__arm__)
- // Set the init value to something that will let us know that we need to
- // autodetect how many watchpoints are supported dynamically...
- static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
- if (g_num_supported_hw_watchpoints == UINT32_MAX)
- {
- // Set this to zero in case we can't tell if there are any HW breakpoints
- g_num_supported_hw_watchpoints = 0;
-
- uint32_t register_DBGDIDR;
- asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
- g_num_supported_hw_watchpoints = Bits32 (register_DBGDIDR, 31, 28) + 1;
-// if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints);
- }
- return g_num_supported_hw_watchpoints;
+uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
+#if defined(__arm__)
+ // Set the init value to something that will let us know that we need to
+ // autodetect how many watchpoints are supported dynamically...
+ static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
+ if (g_num_supported_hw_watchpoints == UINT32_MAX) {
+ // Set this to zero in case we can't tell if there are any HW breakpoints
+ g_num_supported_hw_watchpoints = 0;
+
+ uint32_t register_DBGDIDR;
+ asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
+ g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
+ // if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)",
+ // register_DBGDIDR, g_num_supported_hw_watchpoints);
+ }
+ return g_num_supported_hw_watchpoints;
#else
- // TODO: figure out remote case here!
- return 2;
+ // TODO: figure out remote case here!
+ return 2;
#endif
}
+uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size,
+ bool read,
+ bool write) {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size
+ // = %u, read = %u, write = %u)", addr, size, read, write);
-uint32_t
-RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
-{
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ // Can't watch zero bytes
+ if (size == 0)
+ return LLDB_INVALID_INDEX32;
- // Can't watch zero bytes
- if (size == 0)
- return LLDB_INVALID_INDEX32;
+ // We must watch for either read or write
+ if (read == false && write == false)
+ return LLDB_INVALID_INDEX32;
- // We must watch for either read or write
- if (read == false && write == false)
- return LLDB_INVALID_INDEX32;
+ // Can't watch more than 4 bytes per WVR/WCR pair
+ if (size > 4)
+ return LLDB_INVALID_INDEX32;
- // Can't watch more than 4 bytes per WVR/WCR pair
- if (size > 4)
- return LLDB_INVALID_INDEX32;
+ // We can only watch up to four bytes that follow a 4 byte aligned address
+ // per watchpoint register pair. Since we have at most so we can only watch
+ // until the next 4 byte boundary and we need to make sure we can properly
+ // encode this.
+ uint32_t addr_word_offset = addr % 4;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -
+ // addr_word_offset = 0x%8.8x", addr_word_offset);
+
+ uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =
+ // 0x%8.8x", byte_mask);
+ if (byte_mask > 0xfu)
+ return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
- // per watchpoint register pair. Since we have at most so we can only watch
- // until the next 4 byte boundary and we need to make sure we can properly
- // encode this.
- uint32_t addr_word_offset = addr % 4;
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
+ // Read the debug state
+ int kret = ReadDBG(false);
- uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
- if (byte_mask > 0xfu)
- return LLDB_INVALID_INDEX32;
+ if (kret == KERN_SUCCESS) {
+ // Check to make sure we have the needed hardware support
+ uint32_t i = 0;
- // Read the debug state
- int kret = ReadDBG (false);
+ for (i = 0; i < num_hw_watchpoints; ++i) {
+ if ((dbg.wcr[i] & WCR_ENABLE) == 0)
+ break; // We found an available hw breakpoint slot (in i)
+ }
- if (kret == KERN_SUCCESS)
- {
- // Check to make sure we have the needed hardware support
- uint32_t i = 0;
-
- for (i=0; i<num_hw_watchpoints; ++i)
- {
- if ((dbg.wcr[i] & WCR_ENABLE) == 0)
- break; // We found an available hw breakpoint slot (in i)
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_watchpoints)
- {
- // Make the byte_mask into a valid Byte Address Select mask
- uint32_t byte_address_select = byte_mask << 5;
- // Make sure bits 1:0 are clear in our address
- dbg.wvr[i] = addr & ~((lldb::addr_t)3);
- dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA that we will watch
- S_USER | // Stop only in user mode
- (read ? WCR_LOAD : 0) | // Stop on read access?
- (write ? WCR_STORE : 0) | // Stop on write access?
- WCR_ENABLE; // Enable this watchpoint;
-
- kret = WriteDBG();
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- }
- else
- {
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
- }
+ // See if we found an available hw breakpoint slot above
+ if (i < num_hw_watchpoints) {
+ // Make the byte_mask into a valid Byte Address Select mask
+ uint32_t byte_address_select = byte_mask << 5;
+ // Make sure bits 1:0 are clear in our address
+ dbg.wvr[i] = addr & ~((lldb::addr_t)3);
+ dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA
+ // that we will watch
+ S_USER | // Stop only in user mode
+ (read ? WCR_LOAD : 0) | // Stop on read access?
+ (write ? WCR_STORE : 0) | // Stop on write access?
+ WCR_ENABLE; // Enable this watchpoint;
+
+ kret = WriteDBG();
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()
+ // WriteDBG() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return i;
+ } else {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All
+ // hardware resources (%u) are in use.", num_hw_watchpoints);
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index)
-{
- int kret = ReadDBG (false);
-
- const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
- if (kret == KERN_SUCCESS)
- {
- if (hw_index < num_hw_points)
- {
- dbg.wcr[hw_index] = 0;
-// if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
-// hw_index,
-// hw_index,
-// dbg.wvr[hw_index],
-// hw_index,
-// dbg.wcr[hw_index]);
-
- kret = WriteDBG();
-
- if (kret == KERN_SUCCESS)
- return true;
- }
+bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
+ int kret = ReadDBG(false);
+
+ const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
+ if (kret == KERN_SUCCESS) {
+ if (hw_index < num_hw_points) {
+ dbg.wcr[hw_index] = 0;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -
+ // WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
+ // hw_index,
+ // hw_index,
+ // dbg.wvr[hw_index],
+ // hw_index,
+ // dbg.wcr[hw_index]);
+
+ kret = WriteDBG();
+
+ if (kret == KERN_SUCCESS)
+ return true;
}
- return false;
+ }
+ return false;
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
index 4e831b5a8da7..cdf3479dff69 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
@@ -14,317 +14,256 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
// BCR address match type
-#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21))
-#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21))
-#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21))
-#define BCR_M_RESERVED ((uint32_t)(3u << 21))
+#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21))
+#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21))
+#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21))
+#define BCR_M_RESERVED ((uint32_t)(3u << 21))
// Link a BVR/BCR or WVR/WCR pair to another
-#define E_ENABLE_LINKING ((uint32_t)(1u << 20))
+#define E_ENABLE_LINKING ((uint32_t)(1u << 20))
// Byte Address Select
-#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5))
-#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6))
-#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7))
-#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8))
-#define BAS_IMVA_0_1 ((uint32_t)(3u << 5))
-#define BAS_IMVA_2_3 ((uint32_t)(3u << 7))
-#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5))
+#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5))
+#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6))
+#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7))
+#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8))
+#define BAS_IMVA_0_1 ((uint32_t)(3u << 5))
+#define BAS_IMVA_2_3 ((uint32_t)(3u << 7))
+#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5))
// Break only in privileged or user mode
-#define S_RSVD ((uint32_t)(0u << 1))
-#define S_PRIV ((uint32_t)(1u << 1))
-#define S_USER ((uint32_t)(2u << 1))
-#define S_PRIV_USER ((S_PRIV) | (S_USER))
+#define S_RSVD ((uint32_t)(0u << 1))
+#define S_PRIV ((uint32_t)(1u << 1))
+#define S_USER ((uint32_t)(2u << 1))
+#define S_PRIV_USER ((S_PRIV) | (S_USER))
-#define BCR_ENABLE ((uint32_t)(1u))
-#define WCR_ENABLE ((uint32_t)(1u))
+#define BCR_ENABLE ((uint32_t)(1u))
+#define WCR_ENABLE ((uint32_t)(1u))
// Watchpoint load/store
-#define WCR_LOAD ((uint32_t)(1u << 3))
-#define WCR_STORE ((uint32_t)(1u << 4))
+#define WCR_LOAD ((uint32_t)(1u << 3))
+#define WCR_STORE ((uint32_t)(1u << 4))
-class RegisterContextDarwin_arm : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_arm : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
+ RegisterContextDarwin_arm(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
- ~RegisterContextDarwin_arm() override;
+ ~RegisterContextDarwin_arm() override;
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- uint32_t
- NumSupportedHardwareBreakpoints() override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- uint32_t
- SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- bool
- ClearHardwareBreakpoint(uint32_t hw_idx) override;
+ uint32_t NumSupportedHardwareBreakpoints() override;
- uint32_t
- NumSupportedHardwareWatchpoints() override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- bool
- ClearHardwareWatchpoint(uint32_t hw_index) override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- struct GPR
- {
- uint32_t r[16]; // R0-R15
- uint32_t cpsr; // CPSR
- };
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
- struct QReg
- {
- uint8_t bytes[16];
- };
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
+ struct GPR {
+ uint32_t r[16]; // R0-R15
+ uint32_t cpsr; // CPSR
+ };
-// struct NeonReg
-// {
-// uint8_t bytes[16];
-// };
-//
-// struct VFPv3
-// {
-// union {
-// uint32_t s[32];
-// uint64_t d[32];
-// NeonReg q[16];
-// } v3;
-// uint32_t fpscr;
-// };
-
- struct EXC
- {
- uint32_t exception;
- uint32_t fsr; /* Fault status */
- uint32_t far; /* Virtual Fault Address */
- };
-
- struct DBG
- {
- uint32_t bvr[16];
- uint32_t bcr[16];
- uint32_t wvr[16];
- uint32_t wcr[16];
- };
-
- static void
- LogDBGRegisters (lldb_private::Log *log, const DBG& dbg);
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+
+ // struct NeonReg
+ // {
+ // uint8_t bytes[16];
+ // };
+ //
+ // struct VFPv3
+ // {
+ // union {
+ // uint32_t s[32];
+ // uint64_t d[32];
+ // NeonReg q[16];
+ // } v3;
+ // uint32_t fpscr;
+ // };
+
+ struct EXC {
+ uint32_t exception;
+ uint32_t fsr; /* Fault status */
+ uint32_t far; /* Virtual Fault Address */
+ };
+
+ struct DBG {
+ uint32_t bvr[16];
+ uint32_t bcr[16];
+ uint32_t wvr[16];
+ uint32_t wcr[16];
+ };
+
+ static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg);
protected:
- enum
- {
- GPRRegSet = 1, // ARM_THREAD_STATE
- GPRAltRegSet = 9, // ARM_THREAD_STATE32
- FPURegSet = 2, // ARM_VFP_STATE
- EXCRegSet = 3, // ARM_EXCEPTION_STATE
- DBGRegSet = 4 // ARM_DEBUG_STATE
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t),
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t),
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t),
- DBGWordCount = sizeof(DBG)/sizeof(uint32_t)
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- DBG dbg;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
- int dbg_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum {
+ GPRRegSet = 1, // ARM_THREAD_STATE
+ GPRAltRegSet = 9, // ARM_THREAD_STATE32
+ FPURegSet = 2, // ARM_VFP_STATE
+ EXCRegSet = 3, // ARM_EXCEPTION_STATE
+ DBGRegSet = 4 // ARM_DEBUG_STATE
+ };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t),
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t),
+ EXCWordCount = sizeof(EXC) / sizeof(uint32_t),
+ DBGWordCount = sizeof(DBG) / sizeof(uint32_t)
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ DBG dbg;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+ int dbg_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ case DBGRegSet:
+ return dbg_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- case DBGRegSet: return dbg_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ case DBGRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- case DBGRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ int ReadGPR(bool force);
- int
- ReadGPR (bool force);
+ int ReadFPU(bool force);
- int
- ReadFPU (bool force);
+ int ReadEXC(bool force);
- int
- ReadEXC (bool force);
+ int ReadDBG(bool force);
- int
- ReadDBG (bool force);
+ int WriteGPR();
- int
- WriteGPR ();
+ int WriteFPU();
- int
- WriteFPU ();
+ int WriteEXC();
- int
- WriteEXC ();
+ int WriteDBG();
- int
- WriteDBG ();
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; }
-
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
- {
- return -1;
- }
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
-
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
+
+ virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
- virtual int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
- virtual int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
+ virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
- int
- ReadRegisterSet (uint32_t set, bool force);
+ int ReadRegisterSet(uint32_t set, bool force);
- int
- WriteRegisterSet (uint32_t set);
+ int WriteRegisterSet(uint32_t set);
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
- static int
- GetSetForNativeRegNum (int reg_num);
+ static int GetSetForNativeRegNum(int reg_num);
- static size_t
- GetRegisterInfosCount ();
+ static size_t GetRegisterInfosCount();
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 53cb9dea0fb2..64983a2404e6 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ -*-===//
+//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -24,6 +25,8 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Host/Endian.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
@@ -41,18 +44,36 @@
using namespace lldb;
using namespace lldb_private;
-
-#define GPR_OFFSET(idx) ((idx) * 8)
-#define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::GPR, reg))
-
-#define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextDarwin_arm64::GPR))
-#define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::FPU, reg))
-
-#define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::EXC, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU))
-#define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::DBG, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextDarwin_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
+#define GPR_OFFSET(idx) ((idx)*8)
+#define GPR_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::GPR, reg))
+
+#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterContextDarwin_arm64::GPR))
+#define FPU_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::FPU, reg))
+
+#define EXC_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::EXC, reg) + \
+ sizeof(RegisterContextDarwin_arm64::GPR) + \
+ sizeof(RegisterContextDarwin_arm64::FPU))
+#define DBG_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::DBG, reg) + \
+ sizeof(RegisterContextDarwin_arm64::GPR) + \
+ sizeof(RegisterContextDarwin_arm64::FPU) + \
+ sizeof(RegisterContextDarwin_arm64::EXC))
+
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, \
+ sizeof(((RegisterContextDarwin_arm64::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_arm64::GPR) + \
+ sizeof(RegisterContextDarwin_arm64::FPU) + \
+ sizeof(RegisterContextDarwin_arm64::EXC))
//-----------------------------------------------------------------------------
// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
@@ -62,153 +83,66 @@ using namespace lldb_private;
#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
// General purpose registers
-static uint32_t
-g_gpr_regnums[] =
-{
- gpr_x0,
- gpr_x1,
- gpr_x2,
- gpr_x3,
- gpr_x4,
- gpr_x5,
- gpr_x6,
- gpr_x7,
- gpr_x8,
- gpr_x9,
- gpr_x10,
- gpr_x11,
- gpr_x12,
- gpr_x13,
- gpr_x14,
- gpr_x15,
- gpr_x16,
- gpr_x17,
- gpr_x18,
- gpr_x19,
- gpr_x20,
- gpr_x21,
- gpr_x22,
- gpr_x23,
- gpr_x24,
- gpr_x25,
- gpr_x26,
- gpr_x27,
- gpr_x28,
- gpr_fp,
- gpr_lr,
- gpr_sp,
- gpr_pc,
- gpr_cpsr
-};
+static uint32_t g_gpr_regnums[] = {
+ gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6,
+ gpr_x7, gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13,
+ gpr_x14, gpr_x15, gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20,
+ gpr_x21, gpr_x22, gpr_x23, gpr_x24, gpr_x25, gpr_x26, gpr_x27,
+ gpr_x28, gpr_fp, gpr_lr, gpr_sp, gpr_pc, gpr_cpsr};
// Floating point registers
-static uint32_t
-g_fpu_regnums[] =
-{
- fpu_v0,
- fpu_v1,
- fpu_v2,
- fpu_v3,
- fpu_v4,
- fpu_v5,
- fpu_v6,
- fpu_v7,
- fpu_v8,
- fpu_v9,
- fpu_v10,
- fpu_v11,
- fpu_v12,
- fpu_v13,
- fpu_v14,
- fpu_v15,
- fpu_v16,
- fpu_v17,
- fpu_v18,
- fpu_v19,
- fpu_v20,
- fpu_v21,
- fpu_v22,
- fpu_v23,
- fpu_v24,
- fpu_v25,
- fpu_v26,
- fpu_v27,
- fpu_v28,
- fpu_v29,
- fpu_v30,
- fpu_v31,
- fpu_fpsr,
- fpu_fpcr
-};
+static uint32_t g_fpu_regnums[] = {
+ fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6,
+ fpu_v7, fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13,
+ fpu_v14, fpu_v15, fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20,
+ fpu_v21, fpu_v22, fpu_v23, fpu_v24, fpu_v25, fpu_v26, fpu_v27,
+ fpu_v28, fpu_v29, fpu_v30, fpu_v31, fpu_fpsr, fpu_fpcr};
// Exception registers
-static uint32_t
-g_exc_regnums[] =
-{
- exc_far,
- exc_esr,
- exc_exception
-};
-
-static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos_arm64);
-
-RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext(thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
+static uint32_t g_exc_regnums[] = {exc_far, exc_esr, exc_exception};
+
+static size_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos_arm64_le);
-RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64()
-{
+RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() {}
-void
-RegisterContextDarwin_arm64::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_arm64::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_arm64::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_arm64::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
const RegisterInfo *
-RegisterContextDarwin_arm64::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos_arm64[reg];
- return NULL;
+RegisterContextDarwin_arm64::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos_arm64_le[reg];
+ return NULL;
}
-size_t
-RegisterContextDarwin_arm64::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_arm64::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
-const RegisterInfo *
-RegisterContextDarwin_arm64::GetRegisterInfos ()
-{
- return g_register_infos_arm64;
+const RegisterInfo *RegisterContextDarwin_arm64::GetRegisterInfos() {
+ return g_register_infos_arm64_le;
}
-
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
@@ -219,726 +153,895 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_arm64::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_arm64::GetRegisterSetCount() {
+ return k_num_regsets;
}
-const RegisterSet *
-RegisterContextDarwin_arm64::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
+const RegisterSet *RegisterContextDarwin_arm64::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-
//----------------------------------------------------------------------
// Register information definitions for arm64
//----------------------------------------------------------------------
-int
-RegisterContextDarwin_arm64::GetSetForNativeRegNum (int reg)
-{
- if (reg < fpu_v0)
- return GPRRegSet;
- else if (reg < exc_far)
- return FPURegSet;
- else if (reg < k_num_registers)
- return EXCRegSet;
- return -1;
+int RegisterContextDarwin_arm64::GetSetForNativeRegNum(int reg) {
+ if (reg < fpu_v0)
+ return GPRRegSet;
+ else if (reg < exc_far)
+ return FPURegSet;
+ else if (reg < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-int
-RegisterContextDarwin_arm64::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
- }
- return GetError(GPRRegSet, Read);
+int RegisterContextDarwin_arm64::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(GPRRegSet, Read);
}
-int
-RegisterContextDarwin_arm64::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
- }
- return GetError(FPURegSet, Read);
+int RegisterContextDarwin_arm64::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(FPURegSet, Read);
}
-int
-RegisterContextDarwin_arm64::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(EXCRegSet, Read);
-}
-
-int
-RegisterContextDarwin_arm64::ReadDBG (bool force)
-{
- int set = DBGRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
- }
- return GetError(DBGRegSet, Read);
+int RegisterContextDarwin_arm64::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(EXCRegSet, Read);
}
-int
-RegisterContextDarwin_arm64::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError(GPRRegSet, Write);
+int RegisterContextDarwin_arm64::ReadDBG(bool force) {
+ int set = DBGRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
+ }
+ return GetError(DBGRegSet, Read);
}
-int
-RegisterContextDarwin_arm64::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError(FPURegSet, Write);
+int RegisterContextDarwin_arm64::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(GPRRegSet, Write);
}
-int
-RegisterContextDarwin_arm64::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError(EXCRegSet, Write);
+int RegisterContextDarwin_arm64::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(FPURegSet, Write);
}
-int
-RegisterContextDarwin_arm64::WriteDBG ()
-{
- int set = DBGRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
- SetError (set, Read, -1);
- return GetError(DBGRegSet, Write);
+int RegisterContextDarwin_arm64::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(EXCRegSet, Write);
}
-
-int
-RegisterContextDarwin_arm64::ReadRegisterSet (uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR(force);
- case FPURegSet: return ReadFPU(force);
- case EXCRegSet: return ReadEXC(force);
- case DBGRegSet: return ReadDBG(force);
- default: break;
- }
+int RegisterContextDarwin_arm64::WriteDBG() {
+ int set = DBGRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
+ SetError(set, Read, -1);
+ return GetError(DBGRegSet, Write);
}
-int
-RegisterContextDarwin_arm64::WriteRegisterSet (uint32_t set)
-{
- // Make sure we have a valid context to set.
- if (RegisterSetIsCached(set))
- {
- switch (set)
- {
- case GPRRegSet: return WriteGPR();
- case FPURegSet: return WriteFPU();
- case EXCRegSet: return WriteEXC();
- case DBGRegSet: return WriteDBG();
- default: break;
- }
- }
- return KERN_INVALID_ARGUMENT;
+int RegisterContextDarwin_arm64::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ case DBGRegSet:
+ return ReadDBG(force);
+ default:
+ break;
+ }
+ return KERN_INVALID_ARGUMENT;
}
-void
-RegisterContextDarwin_arm64::LogDBGRegisters (Log *log, const DBG& dbg)
-{
- if (log)
- {
- for (uint32_t i=0; i<16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u = { 0x%8.8llx, 0x%8.8llx }",
- i, i, dbg.bvr[i], dbg.bcr[i],
- i, i, dbg.wvr[i], dbg.wcr[i]);
+int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ if (RegisterSetIsCached(set)) {
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ case DBGRegSet:
+ return WriteDBG();
+ default:
+ break;
}
+ }
+ return KERN_INVALID_ARGUMENT;
}
+void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) {
+ if (log) {
+ for (uint32_t i = 0; i < 16; i++)
+ log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u "
+ "= { 0x%8.8llx, 0x%8.8llx }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ }
+}
-bool
-RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
+bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum(reg);
- switch (reg)
- {
- case gpr_x0:
- case gpr_x1:
- case gpr_x2:
- case gpr_x3:
- case gpr_x4:
- case gpr_x5:
- case gpr_x6:
- case gpr_x7:
- case gpr_x8:
- case gpr_x9:
- case gpr_x10:
- case gpr_x11:
- case gpr_x12:
- case gpr_x13:
- case gpr_x14:
- case gpr_x15:
- case gpr_x16:
- case gpr_x17:
- case gpr_x18:
- case gpr_x19:
- case gpr_x20:
- case gpr_x21:
- case gpr_x22:
- case gpr_x23:
- case gpr_x24:
- case gpr_x25:
- case gpr_x26:
- case gpr_x27:
- case gpr_x28:
- case gpr_fp:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- value.SetUInt64 (gpr.x[reg - gpr_x0]);
- break;
-
- case fpu_v0:
- case fpu_v1:
- case fpu_v2:
- case fpu_v3:
- case fpu_v4:
- case fpu_v5:
- case fpu_v6:
- case fpu_v7:
- case fpu_v8:
- case fpu_v9:
- case fpu_v10:
- case fpu_v11:
- case fpu_v12:
- case fpu_v13:
- case fpu_v14:
- case fpu_v15:
- case fpu_v16:
- case fpu_v17:
- case fpu_v18:
- case fpu_v19:
- case fpu_v20:
- case fpu_v21:
- case fpu_v22:
- case fpu_v23:
- case fpu_v24:
- case fpu_v25:
- case fpu_v26:
- case fpu_v27:
- case fpu_v28:
- case fpu_v29:
- case fpu_v30:
- case fpu_v31:
- value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, endian::InlHostByteOrder());
- break;
-
- case fpu_fpsr:
- value.SetUInt32 (fpu.fpsr);
- break;
-
- case fpu_fpcr:
- value.SetUInt32 (fpu.fpcr);
- break;
-
- case exc_exception:
- value.SetUInt32 (exc.exception);
- break;
- case exc_esr:
- value.SetUInt32 (exc.esr);
- break;
- case exc_far:
- value.SetUInt64 (exc.far);
- break;
+ if (set == -1)
+ return false;
- default:
- value.SetValueToInvalid();
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
+ switch (reg) {
+ case gpr_x0:
+ case gpr_x1:
+ case gpr_x2:
+ case gpr_x3:
+ case gpr_x4:
+ case gpr_x5:
+ case gpr_x6:
+ case gpr_x7:
+ case gpr_x8:
+ case gpr_x9:
+ case gpr_x10:
+ case gpr_x11:
+ case gpr_x12:
+ case gpr_x13:
+ case gpr_x14:
+ case gpr_x15:
+ case gpr_x16:
+ case gpr_x17:
+ case gpr_x18:
+ case gpr_x19:
+ case gpr_x20:
+ case gpr_x21:
+ case gpr_x22:
+ case gpr_x23:
+ case gpr_x24:
+ case gpr_x25:
+ case gpr_x26:
+ case gpr_x27:
+ case gpr_x28:
+ case gpr_fp:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ value.SetUInt64(gpr.x[reg - gpr_x0]);
+ break;
+
+ case gpr_w0:
+ case gpr_w1:
+ case gpr_w2:
+ case gpr_w3:
+ case gpr_w4:
+ case gpr_w5:
+ case gpr_w6:
+ case gpr_w7:
+ case gpr_w8:
+ case gpr_w9:
+ case gpr_w10:
+ case gpr_w11:
+ case gpr_w12:
+ case gpr_w13:
+ case gpr_w14:
+ case gpr_w15:
+ case gpr_w16:
+ case gpr_w17:
+ case gpr_w18:
+ case gpr_w19:
+ case gpr_w20:
+ case gpr_w21:
+ case gpr_w22:
+ case gpr_w23:
+ case gpr_w24:
+ case gpr_w25:
+ case gpr_w26:
+ case gpr_w27:
+ case gpr_w28: {
+ ProcessSP process_sp(m_thread.GetProcess());
+ if (process_sp.get()) {
+ DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ offset_t offset = 0;
+ uint64_t retval = regdata.GetMaxU64(&offset, 8);
+ uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff);
+ value.SetUInt32(retval_lower32);
}
- return true;
+ } break;
+
+ case fpu_v0:
+ case fpu_v1:
+ case fpu_v2:
+ case fpu_v3:
+ case fpu_v4:
+ case fpu_v5:
+ case fpu_v6:
+ case fpu_v7:
+ case fpu_v8:
+ case fpu_v9:
+ case fpu_v10:
+ case fpu_v11:
+ case fpu_v12:
+ case fpu_v13:
+ case fpu_v14:
+ case fpu_v15:
+ case fpu_v16:
+ case fpu_v17:
+ case fpu_v18:
+ case fpu_v19:
+ case fpu_v20:
+ case fpu_v21:
+ case fpu_v22:
+ case fpu_v23:
+ case fpu_v24:
+ case fpu_v25:
+ case fpu_v26:
+ case fpu_v27:
+ case fpu_v28:
+ case fpu_v29:
+ case fpu_v30:
+ case fpu_v31:
+ value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size,
+ endian::InlHostByteOrder());
+ break;
+
+ case fpu_s0:
+ case fpu_s1:
+ case fpu_s2:
+ case fpu_s3:
+ case fpu_s4:
+ case fpu_s5:
+ case fpu_s6:
+ case fpu_s7:
+ case fpu_s8:
+ case fpu_s9:
+ case fpu_s10:
+ case fpu_s11:
+ case fpu_s12:
+ case fpu_s13:
+ case fpu_s14:
+ case fpu_s15:
+ case fpu_s16:
+ case fpu_s17:
+ case fpu_s18:
+ case fpu_s19:
+ case fpu_s20:
+ case fpu_s21:
+ case fpu_s22:
+ case fpu_s23:
+ case fpu_s24:
+ case fpu_s25:
+ case fpu_s26:
+ case fpu_s27:
+ case fpu_s28:
+ case fpu_s29:
+ case fpu_s30:
+ case fpu_s31: {
+ ProcessSP process_sp(m_thread.GetProcess());
+ if (process_sp.get()) {
+ DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ offset_t offset = 0;
+ value.SetFloat(regdata.GetFloat(&offset));
+ }
+ } break;
+
+ case fpu_d0:
+ case fpu_d1:
+ case fpu_d2:
+ case fpu_d3:
+ case fpu_d4:
+ case fpu_d5:
+ case fpu_d6:
+ case fpu_d7:
+ case fpu_d8:
+ case fpu_d9:
+ case fpu_d10:
+ case fpu_d11:
+ case fpu_d12:
+ case fpu_d13:
+ case fpu_d14:
+ case fpu_d15:
+ case fpu_d16:
+ case fpu_d17:
+ case fpu_d18:
+ case fpu_d19:
+ case fpu_d20:
+ case fpu_d21:
+ case fpu_d22:
+ case fpu_d23:
+ case fpu_d24:
+ case fpu_d25:
+ case fpu_d26:
+ case fpu_d27:
+ case fpu_d28:
+ case fpu_d29:
+ case fpu_d30:
+ case fpu_d31: {
+ ProcessSP process_sp(m_thread.GetProcess());
+ if (process_sp.get()) {
+ DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ offset_t offset = 0;
+ value.SetDouble(regdata.GetDouble(&offset));
+ }
+ } break;
+
+ case fpu_fpsr:
+ value.SetUInt32(fpu.fpsr);
+ break;
+
+ case fpu_fpcr:
+ value.SetUInt32(fpu.fpcr);
+ break;
+
+ case exc_exception:
+ value.SetUInt32(exc.exception);
+ break;
+ case exc_esr:
+ value.SetUInt32(exc.esr);
+ break;
+ case exc_far:
+ value.SetUInt64(exc.far);
+ break;
+
+ default:
+ value.SetValueToInvalid();
+ return false;
+ }
+ return true;
}
+bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = GetSetForNativeRegNum(reg);
-bool
-RegisterContextDarwin_arm64::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
-
- switch (reg)
- {
- case gpr_x0:
- case gpr_x1:
- case gpr_x2:
- case gpr_x3:
- case gpr_x4:
- case gpr_x5:
- case gpr_x6:
- case gpr_x7:
- case gpr_x8:
- case gpr_x9:
- case gpr_x10:
- case gpr_x11:
- case gpr_x12:
- case gpr_x13:
- case gpr_x14:
- case gpr_x15:
- case gpr_x16:
- case gpr_x17:
- case gpr_x18:
- case gpr_x19:
- case gpr_x20:
- case gpr_x21:
- case gpr_x22:
- case gpr_x23:
- case gpr_x24:
- case gpr_x25:
- case gpr_x26:
- case gpr_x27:
- case gpr_x28:
- case gpr_fp:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- gpr.x[reg - gpr_x0] = value.GetAsUInt64();
- break;
-
- case fpu_v0:
- case fpu_v1:
- case fpu_v2:
- case fpu_v3:
- case fpu_v4:
- case fpu_v5:
- case fpu_v6:
- case fpu_v7:
- case fpu_v8:
- case fpu_v9:
- case fpu_v10:
- case fpu_v11:
- case fpu_v12:
- case fpu_v13:
- case fpu_v14:
- case fpu_v15:
- case fpu_v16:
- case fpu_v17:
- case fpu_v18:
- case fpu_v19:
- case fpu_v20:
- case fpu_v21:
- case fpu_v22:
- case fpu_v23:
- case fpu_v24:
- case fpu_v25:
- case fpu_v26:
- case fpu_v27:
- case fpu_v28:
- case fpu_v29:
- case fpu_v30:
- case fpu_v31:
- ::memcpy (fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
- break;
-
- case fpu_fpsr:
- fpu.fpsr = value.GetAsUInt32();
- break;
-
- case fpu_fpcr:
- fpu.fpcr = value.GetAsUInt32();
- break;
-
- case exc_exception:
- exc.exception = value.GetAsUInt32();
- break;
- case exc_esr:
- exc.esr = value.GetAsUInt32();
- break;
- case exc_far:
- exc.far = value.GetAsUInt64();
- break;
+ if (set == -1)
+ return false;
- default:
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
- }
- return WriteRegisterSet(set) == KERN_SUCCESS;
+ switch (reg) {
+ case gpr_x0:
+ case gpr_x1:
+ case gpr_x2:
+ case gpr_x3:
+ case gpr_x4:
+ case gpr_x5:
+ case gpr_x6:
+ case gpr_x7:
+ case gpr_x8:
+ case gpr_x9:
+ case gpr_x10:
+ case gpr_x11:
+ case gpr_x12:
+ case gpr_x13:
+ case gpr_x14:
+ case gpr_x15:
+ case gpr_x16:
+ case gpr_x17:
+ case gpr_x18:
+ case gpr_x19:
+ case gpr_x20:
+ case gpr_x21:
+ case gpr_x22:
+ case gpr_x23:
+ case gpr_x24:
+ case gpr_x25:
+ case gpr_x26:
+ case gpr_x27:
+ case gpr_x28:
+ case gpr_fp:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ gpr.x[reg - gpr_x0] = value.GetAsUInt64();
+ break;
+
+ case fpu_v0:
+ case fpu_v1:
+ case fpu_v2:
+ case fpu_v3:
+ case fpu_v4:
+ case fpu_v5:
+ case fpu_v6:
+ case fpu_v7:
+ case fpu_v8:
+ case fpu_v9:
+ case fpu_v10:
+ case fpu_v11:
+ case fpu_v12:
+ case fpu_v13:
+ case fpu_v14:
+ case fpu_v15:
+ case fpu_v16:
+ case fpu_v17:
+ case fpu_v18:
+ case fpu_v19:
+ case fpu_v20:
+ case fpu_v21:
+ case fpu_v22:
+ case fpu_v23:
+ case fpu_v24:
+ case fpu_v25:
+ case fpu_v26:
+ case fpu_v27:
+ case fpu_v28:
+ case fpu_v29:
+ case fpu_v30:
+ case fpu_v31:
+ ::memcpy(fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
+ break;
+
+ case fpu_fpsr:
+ fpu.fpsr = value.GetAsUInt32();
+ break;
+
+ case fpu_fpcr:
+ fpu.fpcr = value.GetAsUInt32();
+ break;
+
+ case exc_exception:
+ exc.exception = value.GetAsUInt32();
+ break;
+ case exc_esr:
+ exc.esr = value.GetAsUInt32();
+ break;
+ case exc_far:
+ exc.far = value.GetAsUInt64();
+ break;
+
+ default:
+ return false;
+ }
+ return WriteRegisterSet(set) == KERN_SUCCESS;
}
-bool
-RegisterContextDarwin_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == KERN_SUCCESS &&
- ReadFPU (false) == KERN_SUCCESS &&
- ReadEXC (false) == KERN_SUCCESS)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+bool RegisterContextDarwin_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
+ ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
- return false;
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextDarwin_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == KERN_SUCCESS)
- ++success_count;
- if (WriteFPU() == KERN_SUCCESS)
- ++success_count;
- if (WriteEXC() == KERN_SUCCESS)
- ++success_count;
- return success_count == 3;
- }
- return false;
+bool RegisterContextDarwin_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteFPU() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteEXC() == KERN_SUCCESS)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
}
-uint32_t
-RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber (RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
- case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_fp;
- case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
- default:
- break;
- }
- }
- else if (kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case arm64_dwarf::x0: return gpr_x0;
- case arm64_dwarf::x1: return gpr_x1;
- case arm64_dwarf::x2: return gpr_x2;
- case arm64_dwarf::x3: return gpr_x3;
- case arm64_dwarf::x4: return gpr_x4;
- case arm64_dwarf::x5: return gpr_x5;
- case arm64_dwarf::x6: return gpr_x6;
- case arm64_dwarf::x7: return gpr_x7;
- case arm64_dwarf::x8: return gpr_x8;
- case arm64_dwarf::x9: return gpr_x9;
- case arm64_dwarf::x10: return gpr_x10;
- case arm64_dwarf::x11: return gpr_x11;
- case arm64_dwarf::x12: return gpr_x12;
- case arm64_dwarf::x13: return gpr_x13;
- case arm64_dwarf::x14: return gpr_x14;
- case arm64_dwarf::x15: return gpr_x15;
- case arm64_dwarf::x16: return gpr_x16;
- case arm64_dwarf::x17: return gpr_x17;
- case arm64_dwarf::x18: return gpr_x18;
- case arm64_dwarf::x19: return gpr_x19;
- case arm64_dwarf::x20: return gpr_x20;
- case arm64_dwarf::x21: return gpr_x21;
- case arm64_dwarf::x22: return gpr_x22;
- case arm64_dwarf::x23: return gpr_x23;
- case arm64_dwarf::x24: return gpr_x24;
- case arm64_dwarf::x25: return gpr_x25;
- case arm64_dwarf::x26: return gpr_x26;
- case arm64_dwarf::x27: return gpr_x27;
- case arm64_dwarf::x28: return gpr_x28;
-
- case arm64_dwarf::fp: return gpr_fp;
- case arm64_dwarf::sp: return gpr_sp;
- case arm64_dwarf::lr: return gpr_lr;
- case arm64_dwarf::pc: return gpr_pc;
- case arm64_dwarf::cpsr: return gpr_cpsr;
-
- case arm64_dwarf::v0: return fpu_v0;
- case arm64_dwarf::v1: return fpu_v1;
- case arm64_dwarf::v2: return fpu_v2;
- case arm64_dwarf::v3: return fpu_v3;
- case arm64_dwarf::v4: return fpu_v4;
- case arm64_dwarf::v5: return fpu_v5;
- case arm64_dwarf::v6: return fpu_v6;
- case arm64_dwarf::v7: return fpu_v7;
- case arm64_dwarf::v8: return fpu_v8;
- case arm64_dwarf::v9: return fpu_v9;
- case arm64_dwarf::v10: return fpu_v10;
- case arm64_dwarf::v11: return fpu_v11;
- case arm64_dwarf::v12: return fpu_v12;
- case arm64_dwarf::v13: return fpu_v13;
- case arm64_dwarf::v14: return fpu_v14;
- case arm64_dwarf::v15: return fpu_v15;
- case arm64_dwarf::v16: return fpu_v16;
- case arm64_dwarf::v17: return fpu_v17;
- case arm64_dwarf::v18: return fpu_v18;
- case arm64_dwarf::v19: return fpu_v19;
- case arm64_dwarf::v20: return fpu_v20;
- case arm64_dwarf::v21: return fpu_v21;
- case arm64_dwarf::v22: return fpu_v22;
- case arm64_dwarf::v23: return fpu_v23;
- case arm64_dwarf::v24: return fpu_v24;
- case arm64_dwarf::v25: return fpu_v25;
- case arm64_dwarf::v26: return fpu_v26;
- case arm64_dwarf::v27: return fpu_v27;
- case arm64_dwarf::v28: return fpu_v28;
- case arm64_dwarf::v29: return fpu_v29;
- case arm64_dwarf::v30: return fpu_v30;
- case arm64_dwarf::v31: return fpu_v31;
-
- default:
- break;
- }
+uint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber(
+ RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_pc;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_sp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_fp;
+ case LLDB_REGNUM_GENERIC_RA:
+ return gpr_lr;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_cpsr;
+ default:
+ break;
}
- else if (kind == eRegisterKindEHFrame)
- {
- switch (reg)
- {
- case arm64_ehframe::x0: return gpr_x0;
- case arm64_ehframe::x1: return gpr_x1;
- case arm64_ehframe::x2: return gpr_x2;
- case arm64_ehframe::x3: return gpr_x3;
- case arm64_ehframe::x4: return gpr_x4;
- case arm64_ehframe::x5: return gpr_x5;
- case arm64_ehframe::x6: return gpr_x6;
- case arm64_ehframe::x7: return gpr_x7;
- case arm64_ehframe::x8: return gpr_x8;
- case arm64_ehframe::x9: return gpr_x9;
- case arm64_ehframe::x10: return gpr_x10;
- case arm64_ehframe::x11: return gpr_x11;
- case arm64_ehframe::x12: return gpr_x12;
- case arm64_ehframe::x13: return gpr_x13;
- case arm64_ehframe::x14: return gpr_x14;
- case arm64_ehframe::x15: return gpr_x15;
- case arm64_ehframe::x16: return gpr_x16;
- case arm64_ehframe::x17: return gpr_x17;
- case arm64_ehframe::x18: return gpr_x18;
- case arm64_ehframe::x19: return gpr_x19;
- case arm64_ehframe::x20: return gpr_x20;
- case arm64_ehframe::x21: return gpr_x21;
- case arm64_ehframe::x22: return gpr_x22;
- case arm64_ehframe::x23: return gpr_x23;
- case arm64_ehframe::x24: return gpr_x24;
- case arm64_ehframe::x25: return gpr_x25;
- case arm64_ehframe::x26: return gpr_x26;
- case arm64_ehframe::x27: return gpr_x27;
- case arm64_ehframe::x28: return gpr_x28;
- case arm64_ehframe::fp: return gpr_fp;
- case arm64_ehframe::sp: return gpr_sp;
- case arm64_ehframe::lr: return gpr_lr;
- case arm64_ehframe::pc: return gpr_pc;
- case arm64_ehframe::cpsr: return gpr_cpsr;
- }
+ } else if (kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case arm64_dwarf::x0:
+ return gpr_x0;
+ case arm64_dwarf::x1:
+ return gpr_x1;
+ case arm64_dwarf::x2:
+ return gpr_x2;
+ case arm64_dwarf::x3:
+ return gpr_x3;
+ case arm64_dwarf::x4:
+ return gpr_x4;
+ case arm64_dwarf::x5:
+ return gpr_x5;
+ case arm64_dwarf::x6:
+ return gpr_x6;
+ case arm64_dwarf::x7:
+ return gpr_x7;
+ case arm64_dwarf::x8:
+ return gpr_x8;
+ case arm64_dwarf::x9:
+ return gpr_x9;
+ case arm64_dwarf::x10:
+ return gpr_x10;
+ case arm64_dwarf::x11:
+ return gpr_x11;
+ case arm64_dwarf::x12:
+ return gpr_x12;
+ case arm64_dwarf::x13:
+ return gpr_x13;
+ case arm64_dwarf::x14:
+ return gpr_x14;
+ case arm64_dwarf::x15:
+ return gpr_x15;
+ case arm64_dwarf::x16:
+ return gpr_x16;
+ case arm64_dwarf::x17:
+ return gpr_x17;
+ case arm64_dwarf::x18:
+ return gpr_x18;
+ case arm64_dwarf::x19:
+ return gpr_x19;
+ case arm64_dwarf::x20:
+ return gpr_x20;
+ case arm64_dwarf::x21:
+ return gpr_x21;
+ case arm64_dwarf::x22:
+ return gpr_x22;
+ case arm64_dwarf::x23:
+ return gpr_x23;
+ case arm64_dwarf::x24:
+ return gpr_x24;
+ case arm64_dwarf::x25:
+ return gpr_x25;
+ case arm64_dwarf::x26:
+ return gpr_x26;
+ case arm64_dwarf::x27:
+ return gpr_x27;
+ case arm64_dwarf::x28:
+ return gpr_x28;
+
+ case arm64_dwarf::fp:
+ return gpr_fp;
+ case arm64_dwarf::sp:
+ return gpr_sp;
+ case arm64_dwarf::lr:
+ return gpr_lr;
+ case arm64_dwarf::pc:
+ return gpr_pc;
+ case arm64_dwarf::cpsr:
+ return gpr_cpsr;
+
+ case arm64_dwarf::v0:
+ return fpu_v0;
+ case arm64_dwarf::v1:
+ return fpu_v1;
+ case arm64_dwarf::v2:
+ return fpu_v2;
+ case arm64_dwarf::v3:
+ return fpu_v3;
+ case arm64_dwarf::v4:
+ return fpu_v4;
+ case arm64_dwarf::v5:
+ return fpu_v5;
+ case arm64_dwarf::v6:
+ return fpu_v6;
+ case arm64_dwarf::v7:
+ return fpu_v7;
+ case arm64_dwarf::v8:
+ return fpu_v8;
+ case arm64_dwarf::v9:
+ return fpu_v9;
+ case arm64_dwarf::v10:
+ return fpu_v10;
+ case arm64_dwarf::v11:
+ return fpu_v11;
+ case arm64_dwarf::v12:
+ return fpu_v12;
+ case arm64_dwarf::v13:
+ return fpu_v13;
+ case arm64_dwarf::v14:
+ return fpu_v14;
+ case arm64_dwarf::v15:
+ return fpu_v15;
+ case arm64_dwarf::v16:
+ return fpu_v16;
+ case arm64_dwarf::v17:
+ return fpu_v17;
+ case arm64_dwarf::v18:
+ return fpu_v18;
+ case arm64_dwarf::v19:
+ return fpu_v19;
+ case arm64_dwarf::v20:
+ return fpu_v20;
+ case arm64_dwarf::v21:
+ return fpu_v21;
+ case arm64_dwarf::v22:
+ return fpu_v22;
+ case arm64_dwarf::v23:
+ return fpu_v23;
+ case arm64_dwarf::v24:
+ return fpu_v24;
+ case arm64_dwarf::v25:
+ return fpu_v25;
+ case arm64_dwarf::v26:
+ return fpu_v26;
+ case arm64_dwarf::v27:
+ return fpu_v27;
+ case arm64_dwarf::v28:
+ return fpu_v28;
+ case arm64_dwarf::v29:
+ return fpu_v29;
+ case arm64_dwarf::v30:
+ return fpu_v30;
+ case arm64_dwarf::v31:
+ return fpu_v31;
+
+ default:
+ break;
}
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
+ } else if (kind == eRegisterKindEHFrame) {
+ switch (reg) {
+ case arm64_ehframe::x0:
+ return gpr_x0;
+ case arm64_ehframe::x1:
+ return gpr_x1;
+ case arm64_ehframe::x2:
+ return gpr_x2;
+ case arm64_ehframe::x3:
+ return gpr_x3;
+ case arm64_ehframe::x4:
+ return gpr_x4;
+ case arm64_ehframe::x5:
+ return gpr_x5;
+ case arm64_ehframe::x6:
+ return gpr_x6;
+ case arm64_ehframe::x7:
+ return gpr_x7;
+ case arm64_ehframe::x8:
+ return gpr_x8;
+ case arm64_ehframe::x9:
+ return gpr_x9;
+ case arm64_ehframe::x10:
+ return gpr_x10;
+ case arm64_ehframe::x11:
+ return gpr_x11;
+ case arm64_ehframe::x12:
+ return gpr_x12;
+ case arm64_ehframe::x13:
+ return gpr_x13;
+ case arm64_ehframe::x14:
+ return gpr_x14;
+ case arm64_ehframe::x15:
+ return gpr_x15;
+ case arm64_ehframe::x16:
+ return gpr_x16;
+ case arm64_ehframe::x17:
+ return gpr_x17;
+ case arm64_ehframe::x18:
+ return gpr_x18;
+ case arm64_ehframe::x19:
+ return gpr_x19;
+ case arm64_ehframe::x20:
+ return gpr_x20;
+ case arm64_ehframe::x21:
+ return gpr_x21;
+ case arm64_ehframe::x22:
+ return gpr_x22;
+ case arm64_ehframe::x23:
+ return gpr_x23;
+ case arm64_ehframe::x24:
+ return gpr_x24;
+ case arm64_ehframe::x25:
+ return gpr_x25;
+ case arm64_ehframe::x26:
+ return gpr_x26;
+ case arm64_ehframe::x27:
+ return gpr_x27;
+ case arm64_ehframe::x28:
+ return gpr_x28;
+ case arm64_ehframe::fp:
+ return gpr_fp;
+ case arm64_ehframe::sp:
+ return gpr_sp;
+ case arm64_ehframe::lr:
+ return gpr_lr;
+ case arm64_ehframe::pc:
+ return gpr_pc;
+ case arm64_ehframe::cpsr:
+ return gpr_cpsr;
}
- return LLDB_INVALID_REGNUM;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
-
-uint32_t
-RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints ()
-{
-#if defined (__arm64__) || defined (__aarch64__)
- // autodetect how many watchpoints are supported dynamically...
- static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
- if (g_num_supported_hw_watchpoints == UINT32_MAX)
- {
- size_t len;
- uint32_t n = 0;
- len = sizeof (n);
- if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
- {
- g_num_supported_hw_watchpoints = n;
- }
+uint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() {
+#if defined(__arm64__) || defined(__aarch64__)
+ // autodetect how many watchpoints are supported dynamically...
+ static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
+ if (g_num_supported_hw_watchpoints == UINT32_MAX) {
+ size_t len;
+ uint32_t n = 0;
+ len = sizeof(n);
+ if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) {
+ g_num_supported_hw_watchpoints = n;
}
- return g_num_supported_hw_watchpoints;
+ }
+ return g_num_supported_hw_watchpoints;
#else
- // TODO: figure out remote case here!
- return 2;
+ // TODO: figure out remote case here!
+ return 2;
#endif
}
+uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size,
+ bool read,
+ bool write) {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p,
+ // size = %u, read = %u, write = %u)", addr, size, read, write);
-uint32_t
-RegisterContextDarwin_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
-{
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ // Can't watch zero bytes
+ if (size == 0)
+ return LLDB_INVALID_INDEX32;
- // Can't watch zero bytes
- if (size == 0)
- return LLDB_INVALID_INDEX32;
+ // We must watch for either read or write
+ if (read == false && write == false)
+ return LLDB_INVALID_INDEX32;
- // We must watch for either read or write
- if (read == false && write == false)
- return LLDB_INVALID_INDEX32;
+ // Can't watch more than 4 bytes per WVR/WCR pair
+ if (size > 4)
+ return LLDB_INVALID_INDEX32;
- // Can't watch more than 4 bytes per WVR/WCR pair
- if (size > 4)
- return LLDB_INVALID_INDEX32;
+ // We can only watch up to four bytes that follow a 4 byte aligned address
+ // per watchpoint register pair. Since we have at most so we can only watch
+ // until the next 4 byte boundary and we need to make sure we can properly
+ // encode this.
+ uint32_t addr_word_offset = addr % 4;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() -
+ // addr_word_offset = 0x%8.8x", addr_word_offset);
+
+ uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask =
+ // 0x%8.8x", byte_mask);
+ if (byte_mask > 0xfu)
+ return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
- // per watchpoint register pair. Since we have at most so we can only watch
- // until the next 4 byte boundary and we need to make sure we can properly
- // encode this.
- uint32_t addr_word_offset = addr % 4;
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
+ // Read the debug state
+ int kret = ReadDBG(false);
- uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
- if (byte_mask > 0xfu)
- return LLDB_INVALID_INDEX32;
+ if (kret == KERN_SUCCESS) {
+ // Check to make sure we have the needed hardware support
+ uint32_t i = 0;
- // Read the debug state
- int kret = ReadDBG (false);
+ for (i = 0; i < num_hw_watchpoints; ++i) {
+ if ((dbg.wcr[i] & WCR_ENABLE) == 0)
+ break; // We found an available hw breakpoint slot (in i)
+ }
- if (kret == KERN_SUCCESS)
- {
- // Check to make sure we have the needed hardware support
- uint32_t i = 0;
-
- for (i=0; i<num_hw_watchpoints; ++i)
- {
- if ((dbg.wcr[i] & WCR_ENABLE) == 0)
- break; // We found an available hw breakpoint slot (in i)
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_watchpoints)
- {
- // Make the byte_mask into a valid Byte Address Select mask
- uint32_t byte_address_select = byte_mask << 5;
- // Make sure bits 1:0 are clear in our address
- dbg.wvr[i] = addr & ~((lldb::addr_t)3);
- dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA that we will watch
- S_USER | // Stop only in user mode
- (read ? WCR_LOAD : 0) | // Stop on read access?
- (write ? WCR_STORE : 0) | // Stop on write access?
- WCR_ENABLE; // Enable this watchpoint;
-
- kret = WriteDBG();
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- }
- else
- {
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
- }
+ // See if we found an available hw breakpoint slot above
+ if (i < num_hw_watchpoints) {
+ // Make the byte_mask into a valid Byte Address Select mask
+ uint32_t byte_address_select = byte_mask << 5;
+ // Make sure bits 1:0 are clear in our address
+ dbg.wvr[i] = addr & ~((lldb::addr_t)3);
+ dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA
+ // that we will watch
+ S_USER | // Stop only in user mode
+ (read ? WCR_LOAD : 0) | // Stop on read access?
+ (write ? WCR_STORE : 0) | // Stop on write access?
+ WCR_ENABLE; // Enable this watchpoint;
+
+ kret = WriteDBG();
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint()
+ // WriteDBG() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return i;
+ } else {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint():
+ // All hardware resources (%u) are in use.",
+ // num_hw_watchpoints);
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextDarwin_arm64::ClearHardwareWatchpoint (uint32_t hw_index)
-{
- int kret = ReadDBG (false);
-
- const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
- if (kret == KERN_SUCCESS)
- {
- if (hw_index < num_hw_points)
- {
- dbg.wcr[hw_index] = 0;
-// if (log) log->Printf ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
-// hw_index,
-// hw_index,
-// dbg.wvr[hw_index],
-// hw_index,
-// dbg.wcr[hw_index]);
-
- kret = WriteDBG();
-
- if (kret == KERN_SUCCESS)
- return true;
- }
+bool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index) {
+ int kret = ReadDBG(false);
+
+ const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
+ if (kret == KERN_SUCCESS) {
+ if (hw_index < num_hw_points) {
+ dbg.wcr[hw_index] = 0;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u )
+ // - WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
+ // hw_index,
+ // hw_index,
+ // dbg.wvr[hw_index],
+ // hw_index,
+ // dbg.wcr[hw_index]);
+
+ kret = WriteDBG();
+
+ if (kret == KERN_SUCCESS)
+ return true;
}
- return false;
+ }
+ return false;
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index b228c42ade53..2d1fe0555b58 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextDarwin_arm64.h -----------------------------*- C++ -*-===//
+//===-- RegisterContextDarwin_arm64.h -----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,279 +15,222 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
// Break only in privileged or user mode
-#define S_RSVD ((uint32_t)(0u << 1))
-#define S_PRIV ((uint32_t)(1u << 1))
-#define S_USER ((uint32_t)(2u << 1))
-#define S_PRIV_USER ((S_PRIV) | (S_USER))
+#define S_RSVD ((uint32_t)(0u << 1))
+#define S_PRIV ((uint32_t)(1u << 1))
+#define S_USER ((uint32_t)(2u << 1))
+#define S_PRIV_USER ((S_PRIV) | (S_USER))
-#define WCR_ENABLE ((uint32_t)(1u))
+#define WCR_ENABLE ((uint32_t)(1u))
// Watchpoint load/store
-#define WCR_LOAD ((uint32_t)(1u << 3))
-#define WCR_STORE ((uint32_t)(1u << 4))
+#define WCR_LOAD ((uint32_t)(1u << 3))
+#define WCR_STORE ((uint32_t)(1u << 4))
-class RegisterContextDarwin_arm64 : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_arm64 : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_arm64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- ~RegisterContextDarwin_arm64() override;
-
- void
- InvalidateAllRegisters() override;
-
- 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;
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- uint32_t
- NumSupportedHardwareWatchpoints() override;
-
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
-
- bool
- ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- // mirrors <mach/arm/thread_status.h> arm_thread_state64_t
- struct GPR
- {
- uint64_t x[29]; // x0-x28
- uint64_t fp; // x29
- uint64_t lr; // x30
- uint64_t sp; // x31
- uint64_t pc; // pc
- uint32_t cpsr; // cpsr
- };
-
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // mirrors <mach/arm/thread_status.h> arm_neon_state64_t
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- // mirrors <mach/arm/thread_status.h> arm_exception_state64_t
- struct EXC
- {
- uint64_t far; // Virtual Fault Address
- uint32_t esr; // Exception syndrome
- uint32_t exception; // number of arm exception token
- };
-
- // mirrors <mach/arm/thread_status.h> arm_debug_state64_t
- struct DBG
- {
- uint64_t bvr[16];
- uint64_t bcr[16];
- uint64_t wvr[16];
- uint64_t wcr[16];
- uint64_t mdscr_el1;
- };
-
- static void
- LogDBGRegisters (lldb_private::Log *log, const DBG& dbg);
+ RegisterContextDarwin_arm64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ ~RegisterContextDarwin_arm64() override;
+
+ void InvalidateAllRegisters() override;
+
+ 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;
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ // mirrors <mach/arm/thread_status.h> arm_thread_state64_t
+ struct GPR {
+ uint64_t x[29]; // x0-x28
+ uint64_t fp; // x29
+ uint64_t lr; // x30
+ uint64_t sp; // x31
+ uint64_t pc; // pc
+ uint32_t cpsr; // cpsr
+ };
+
+ struct VReg {
+ uint8_t bytes[16];
+ };
+
+ // mirrors <mach/arm/thread_status.h> arm_neon_state64_t
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
+
+ // mirrors <mach/arm/thread_status.h> arm_exception_state64_t
+ struct EXC {
+ uint64_t far; // Virtual Fault Address
+ uint32_t esr; // Exception syndrome
+ uint32_t exception; // number of arm exception token
+ };
+
+ // mirrors <mach/arm/thread_status.h> arm_debug_state64_t
+ struct DBG {
+ uint64_t bvr[16];
+ uint64_t bcr[16];
+ uint64_t wvr[16];
+ uint64_t wcr[16];
+ uint64_t mdscr_el1;
+ };
+
+ static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg);
protected:
- enum
- {
- GPRRegSet = 6, // ARM_THREAD_STATE64
- FPURegSet = 17, // ARM_NEON_STATE64
- EXCRegSet = 7, // ARM_EXCEPTION_STATE64
- DBGRegSet = 15 // ARM_DEBUG_STATE64
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t), // ARM_THREAD_STATE64_COUNT
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t), // ARM_NEON_STATE64_COUNT
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t), // ARM_EXCEPTION_STATE64_COUNT
- DBGWordCount = sizeof(DBG)/sizeof(uint32_t) // ARM_DEBUG_STATE64_COUNT
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- DBG dbg;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
- int dbg_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum {
+ GPRRegSet = 6, // ARM_THREAD_STATE64
+ FPURegSet = 17, // ARM_NEON_STATE64
+ EXCRegSet = 7, // ARM_EXCEPTION_STATE64
+ DBGRegSet = 15 // ARM_DEBUG_STATE64
+ };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t), // ARM_THREAD_STATE64_COUNT
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t), // ARM_NEON_STATE64_COUNT
+ EXCWordCount =
+ sizeof(EXC) / sizeof(uint32_t), // ARM_EXCEPTION_STATE64_COUNT
+ DBGWordCount = sizeof(DBG) / sizeof(uint32_t) // ARM_DEBUG_STATE64_COUNT
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ DBG dbg;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+ int dbg_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ case DBGRegSet:
+ return dbg_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- case DBGRegSet: return dbg_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ case DBGRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- case DBGRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ int ReadGPR(bool force);
- int
- ReadGPR (bool force);
+ int ReadFPU(bool force);
- int
- ReadFPU (bool force);
+ int ReadEXC(bool force);
- int
- ReadEXC (bool force);
+ int ReadDBG(bool force);
- int
- ReadDBG (bool force);
+ int WriteGPR();
- int
- WriteGPR ();
+ int WriteFPU();
- int
- WriteFPU ();
+ int WriteEXC();
- int
- WriteEXC ();
+ int WriteDBG();
- int
- WriteDBG ();
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; }
-
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
- {
- return -1;
- }
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
-
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
+
+ virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
- virtual int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
- virtual int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
+ virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
- int
- ReadRegisterSet (uint32_t set, bool force);
+ int ReadRegisterSet(uint32_t set, bool force);
- int
- WriteRegisterSet (uint32_t set);
+ int WriteRegisterSet(uint32_t set);
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
- static int
- GetSetForNativeRegNum (int reg_num);
+ static int GetSetForNativeRegNum(int reg_num);
- static size_t
- GetRegisterInfosCount ();
+ static size_t GetRegisterInfosCount();
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_arm64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index 1b01c28b5d96..f42fb00b375f 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -7,9 +7,8 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
-#include <stddef.h> // offsetof
+#include <stddef.h> // offsetof
// C++ Includes
// Other libraries and framework includes
@@ -34,302 +33,430 @@
using namespace lldb;
using namespace lldb_private;
-enum
-{
- gpr_eax = 0,
- gpr_ebx,
- gpr_ecx,
- gpr_edx,
- gpr_edi,
- gpr_esi,
- gpr_ebp,
- gpr_esp,
- gpr_ss,
- gpr_eflags,
- gpr_eip,
- gpr_cs,
- gpr_ds,
- gpr_es,
- gpr_fs,
- gpr_gs,
-
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
-
- exc_trapno,
- exc_err,
- exc_faultvaddr,
-
- k_num_registers,
-
- // Aliases
- fpu_fctrl = fpu_fcw,
- fpu_fstat = fpu_fsw,
- fpu_ftag = fpu_ftw,
- fpu_fiseg = fpu_cs,
- fpu_fioff = fpu_ip,
- fpu_foseg = fpu_ds,
- fpu_fooff = fpu_dp
+enum {
+ gpr_eax = 0,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_ss,
+ gpr_eflags,
+ gpr_eip,
+ gpr_cs,
+ gpr_ds,
+ gpr_es,
+ gpr_fs,
+ gpr_gs,
+
+ fpu_fcw,
+ fpu_fsw,
+ fpu_ftw,
+ fpu_fop,
+ fpu_ip,
+ fpu_cs,
+ fpu_dp,
+ fpu_ds,
+ fpu_mxcsr,
+ fpu_mxcsrmask,
+ fpu_stmm0,
+ fpu_stmm1,
+ fpu_stmm2,
+ fpu_stmm3,
+ fpu_stmm4,
+ fpu_stmm5,
+ fpu_stmm6,
+ fpu_stmm7,
+ fpu_xmm0,
+ fpu_xmm1,
+ fpu_xmm2,
+ fpu_xmm3,
+ fpu_xmm4,
+ fpu_xmm5,
+ fpu_xmm6,
+ fpu_xmm7,
+
+ exc_trapno,
+ exc_err,
+ exc_faultvaddr,
+
+ k_num_registers,
+
+ // Aliases
+ fpu_fctrl = fpu_fcw,
+ fpu_fstat = fpu_fsw,
+ fpu_ftag = fpu_ftw,
+ fpu_fiseg = fpu_cs,
+ fpu_fioff = fpu_ip,
+ fpu_foseg = fpu_ds,
+ fpu_fooff = fpu_dp
};
-enum
-{
- ehframe_eax = 0,
- ehframe_ecx,
- ehframe_edx,
- ehframe_ebx,
- ehframe_ebp,
- ehframe_esp,
- ehframe_esi,
- ehframe_edi,
- ehframe_eip,
- ehframe_eflags
+enum {
+ ehframe_eax = 0,
+ ehframe_ecx,
+ ehframe_edx,
+ ehframe_ebx,
+ ehframe_ebp,
+ ehframe_esp,
+ ehframe_esi,
+ ehframe_edi,
+ ehframe_eip,
+ ehframe_eflags
};
-enum
-{
- dwarf_eax = 0,
- dwarf_ecx,
- dwarf_edx,
- dwarf_ebx,
- dwarf_esp,
- dwarf_ebp,
- dwarf_esi,
- dwarf_edi,
- dwarf_eip,
- dwarf_eflags,
- dwarf_stmm0 = 11,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7
+enum {
+ dwarf_eax = 0,
+ dwarf_ecx,
+ dwarf_edx,
+ dwarf_ebx,
+ dwarf_esp,
+ dwarf_ebp,
+ dwarf_esi,
+ dwarf_edi,
+ dwarf_eip,
+ dwarf_eflags,
+ dwarf_stmm0 = 11,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_xmm0 = 21,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7
};
-
-#define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::GPR, reg))
-#define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::FPU, reg) + sizeof (RegisterContextDarwin_i386::GPR))
-#define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::EXC, reg) + sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU))
+#define GPR_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::GPR, reg))
+#define FPU_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::FPU, reg) + \
+ sizeof(RegisterContextDarwin_i386::GPR))
+#define EXC_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::EXC, reg) + \
+ sizeof(RegisterContextDarwin_i386::GPR) + \
+ sizeof(RegisterContextDarwin_i386::FPU))
// These macros will auto define the register name, alt name, register size,
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_##reg##i, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_##reg##i }, NULL, NULL
-
-#define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU) + sizeof (RegisterContextDarwin_i386::EXC))
-
-static RegisterInfo g_register_infos[] =
-{
-// Macro auto defines most stuff eh_frame DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS
-// =============================== ======================= =================== ========================= ================== ================= ========== ===============
- { DEFINE_GPR(eax , NULL) , { ehframe_eax , dwarf_eax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_eax }, NULL, NULL},
- { DEFINE_GPR(ebx , NULL) , { ehframe_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ebx }, NULL, NULL},
- { DEFINE_GPR(ecx , NULL) , { ehframe_ecx , dwarf_ecx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ecx }, NULL, NULL},
- { DEFINE_GPR(edx , NULL) , { ehframe_edx , dwarf_edx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_edx }, NULL, NULL},
- { DEFINE_GPR(edi , NULL) , { ehframe_edi , dwarf_edi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_edi }, NULL, NULL},
- { DEFINE_GPR(esi , NULL) , { ehframe_esi , dwarf_esi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_esi }, NULL, NULL},
- { DEFINE_GPR(ebp , "fp") , { ehframe_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, gpr_ebp }, NULL, NULL},
- { DEFINE_GPR(esp , "sp") , { ehframe_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, gpr_esp }, NULL, NULL},
- { DEFINE_GPR(ss , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ss }, NULL, NULL},
- { DEFINE_GPR(eflags , "flags") , { ehframe_eflags , dwarf_eflags , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, gpr_eflags }, NULL, NULL},
- { DEFINE_GPR(eip , "pc") , { ehframe_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, gpr_eip }, NULL, NULL},
- { DEFINE_GPR(cs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_cs }, NULL, NULL},
- { DEFINE_GPR(ds , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ds }, NULL, NULL},
- { DEFINE_GPR(es , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_es }, NULL, NULL},
- { DEFINE_GPR(fs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_fs }, NULL, NULL},
- { DEFINE_GPR(gs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_gs }, NULL, NULL},
-
- { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fcw }, NULL, NULL},
- { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fsw }, NULL, NULL},
- { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ftw }, NULL, NULL},
- { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fop }, NULL, NULL},
- { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ip }, NULL, NULL},
- { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_cs }, NULL, NULL},
- { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_dp }, NULL, NULL},
- { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ds }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsr }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask}, NULL, NULL},
- { DEFINE_FPU_VECT(stmm,0) },
- { DEFINE_FPU_VECT(stmm,1) },
- { DEFINE_FPU_VECT(stmm,2) },
- { DEFINE_FPU_VECT(stmm,3) },
- { DEFINE_FPU_VECT(stmm,4) },
- { DEFINE_FPU_VECT(stmm,5) },
- { DEFINE_FPU_VECT(stmm,6) },
- { DEFINE_FPU_VECT(stmm,7) },
- { DEFINE_FPU_VECT(xmm,0) },
- { DEFINE_FPU_VECT(xmm,1) },
- { DEFINE_FPU_VECT(xmm,2) },
- { DEFINE_FPU_VECT(xmm,3) },
- { DEFINE_FPU_VECT(xmm,4) },
- { DEFINE_FPU_VECT(xmm,5) },
- { DEFINE_FPU_VECT(xmm,6) },
- { DEFINE_FPU_VECT(xmm,7) },
-
- { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL},
- { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL},
- { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL}
-};
+#define DEFINE_GPR(reg, alt) \
+ #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_UINT(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg), \
+ FPU_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_VECT(reg, i) \
+ #reg #i, NULL, \
+ sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg[i].bytes), \
+ FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, dwarf_##reg##i, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ fpu_##reg##i }, \
+ nullptr, nullptr, nullptr, 0
+
+#define DEFINE_EXC(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \
+ EXC_OFFSET(reg), eEncodingUint, eFormatHex
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_i386::GPR) + \
+ sizeof(RegisterContextDarwin_i386::FPU) + \
+ sizeof(RegisterContextDarwin_i386::EXC))
+
+static RegisterInfo g_register_infos[] = {
+ // Macro auto defines most stuff eh_frame DWARF
+ // GENERIC PROCESS PLUGIN LLDB
+ // =============================== =======================
+ // =================== ========================= ==================
+ // =================
+ {DEFINE_GPR(eax, NULL),
+ {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_eax},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ebx, NULL),
+ {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_ebx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ecx, NULL),
+ {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_ecx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(edx, NULL),
+ {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_edx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(edi, NULL),
+ {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_edi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(esi, NULL),
+ {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_esi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ebp, "fp"),
+ {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ gpr_ebp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(esp, "sp"),
+ {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ gpr_esp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ss, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_ss},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(eflags, "flags"),
+ {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, gpr_eflags},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(eip, "pc"),
+ {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ gpr_eip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(cs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ds, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_ds},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(es, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_es},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(fs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_fs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(gs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_gs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_FPU_UINT(fcw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fcw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fsw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fsw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ftw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ftw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fop),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fop},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ip),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(cs),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(dp),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_dp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ds),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ds},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsrmask),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsrmask},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_VECT(stmm, 0)},
+ {DEFINE_FPU_VECT(stmm, 1)},
+ {DEFINE_FPU_VECT(stmm, 2)},
+ {DEFINE_FPU_VECT(stmm, 3)},
+ {DEFINE_FPU_VECT(stmm, 4)},
+ {DEFINE_FPU_VECT(stmm, 5)},
+ {DEFINE_FPU_VECT(stmm, 6)},
+ {DEFINE_FPU_VECT(stmm, 7)},
+ {DEFINE_FPU_VECT(xmm, 0)},
+ {DEFINE_FPU_VECT(xmm, 1)},
+ {DEFINE_FPU_VECT(xmm, 2)},
+ {DEFINE_FPU_VECT(xmm, 3)},
+ {DEFINE_FPU_VECT(xmm, 4)},
+ {DEFINE_FPU_VECT(xmm, 5)},
+ {DEFINE_FPU_VECT(xmm, 6)},
+ {DEFINE_FPU_VECT(xmm, 7)},
+
+ {DEFINE_EXC(trapno),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_trapno},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(err),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_err},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(faultvaddr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_faultvaddr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-RegisterContextDarwin_i386::RegisterContextDarwin_i386 (Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext(thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
-
-RegisterContextDarwin_i386::~RegisterContextDarwin_i386()
-{
+RegisterContextDarwin_i386::RegisterContextDarwin_i386(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_i386::~RegisterContextDarwin_i386() {}
-void
-RegisterContextDarwin_i386::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_i386::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_i386::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_i386::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
const RegisterInfo *
-RegisterContextDarwin_i386::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos[reg];
+ return NULL;
}
-size_t
-RegisterContextDarwin_i386::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_i386::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
-const RegisterInfo *
-RegisterContextDarwin_i386::GetRegisterInfos ()
-{
- return g_register_infos;
+const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() {
+ return g_register_infos;
}
-
// General purpose registers
-static uint32_t
-g_gpr_regnums[] =
-{
- gpr_eax,
- gpr_ebx,
- gpr_ecx,
- gpr_edx,
- gpr_edi,
- gpr_esi,
- gpr_ebp,
- gpr_esp,
- gpr_ss,
- gpr_eflags,
- gpr_eip,
- gpr_cs,
- gpr_ds,
- gpr_es,
- gpr_fs,
- gpr_gs
-};
+static uint32_t g_gpr_regnums[] = {
+ gpr_eax, gpr_ebx, gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp,
+ gpr_ss, gpr_eflags, gpr_eip, gpr_cs, gpr_ds, gpr_es, gpr_fs, gpr_gs};
// Floating point registers
-static uint32_t
-g_fpu_regnums[] =
-{
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7
-};
+static uint32_t g_fpu_regnums[] = {
+ fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
+ fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
+ fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
+ fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
+ fpu_xmm6, fpu_xmm7};
// Exception registers
-static uint32_t
-g_exc_regnums[] =
-{
- exc_trapno,
- exc_err,
- exc_faultvaddr
-};
+static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
@@ -341,539 +468,514 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_i386::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_i386::GetRegisterSetCount() {
+ return k_num_regsets;
}
-const RegisterSet *
-RegisterContextDarwin_i386::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
+const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-
//----------------------------------------------------------------------
// Register information definitions for 32 bit i386.
//----------------------------------------------------------------------
-int
-RegisterContextDarwin_i386::GetSetForNativeRegNum (int reg_num)
-{
- if (reg_num < fpu_fcw)
- return GPRRegSet;
- else if (reg_num < exc_trapno)
- return FPURegSet;
- else if (reg_num < k_num_registers)
- return EXCRegSet;
- return -1;
+int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
+ if (reg_num < fpu_fcw)
+ return GPRRegSet;
+ else if (reg_num < exc_trapno)
+ return FPURegSet;
+ else if (reg_num < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-
-void
-RegisterContextDarwin_i386::LogGPR(Log *log, const char *title)
-{
- if (log)
- {
- if (title)
- log->Printf ("%s", title);
- for (uint32_t i=0; i<k_num_gpr_registers; i++)
- {
- uint32_t reg = gpr_eax + i;
- log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&gpr.eax)[reg]);
- }
+void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {
+ if (log) {
+ if (title)
+ log->Printf("%s", title);
+ for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
+ uint32_t reg = gpr_eax + i;
+ log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name,
+ (&gpr.eax)[reg]);
}
+ }
}
-
-
-int
-RegisterContextDarwin_i386::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
- }
- return GetError(set, Read);
+int RegisterContextDarwin_i386::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(set, Read);
}
-int
-RegisterContextDarwin_i386::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
- }
- return GetError(set, Read);
+int RegisterContextDarwin_i386::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(set, Read);
}
-int
-RegisterContextDarwin_i386::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(set, Read);
+int RegisterContextDarwin_i386::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(set, Read);
}
-int
-RegisterContextDarwin_i386::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError(set, Write);
+int RegisterContextDarwin_i386::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_i386::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError(set, Write);
+int RegisterContextDarwin_i386::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_i386::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError(set, Write);
+int RegisterContextDarwin_i386::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_i386::ReadRegisterSet (uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR(force);
- case FPURegSet: return ReadFPU(force);
- case EXCRegSet: return ReadEXC(force);
- default: break;
- }
- return -1;
+int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ default:
+ break;
+ }
+ return -1;
}
-int
-RegisterContextDarwin_i386::WriteRegisterSet (uint32_t set)
-{
- // Make sure we have a valid context to set.
- if (RegisterSetIsCached(set))
- {
- switch (set)
- {
- case GPRRegSet: return WriteGPR();
- case FPURegSet: return WriteFPU();
- case EXCRegSet: return WriteEXC();
- default: break;
- }
+int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ if (RegisterSetIsCached(set)) {
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ default:
+ break;
}
- return -1;
+ }
+ return -1;
}
-bool
-RegisterContextDarwin_i386::ReadRegister (const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_i386::GetSetForNativeRegNum (reg);
+bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg);
- if (set == -1)
- return false;
+ if (set == -1)
+ return false;
- if (ReadRegisterSet(set, false) != 0)
- return false;
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- switch (reg)
- {
- case gpr_eax:
- case gpr_ebx:
- case gpr_ecx:
- case gpr_edx:
- case gpr_edi:
- case gpr_esi:
- case gpr_ebp:
- case gpr_esp:
- case gpr_ss:
- case gpr_eflags:
- case gpr_eip:
- case gpr_cs:
- case gpr_ds:
- case gpr_es:
- case gpr_fs:
- case gpr_gs:
- value = (&gpr.eax)[reg - gpr_eax];
- break;
-
- case fpu_fcw:
- value = fpu.fcw;
- break;
-
- case fpu_fsw:
- value = fpu.fsw;
- break;
-
- case fpu_ftw:
- value = fpu.ftw;
- break;
-
- case fpu_fop:
- value = fpu.fop;
- break;
-
- case fpu_ip:
- value = fpu.ip;
- break;
-
- case fpu_cs:
- value = fpu.cs;
- break;
-
- case fpu_dp:
- value = fpu.dp;
- break;
-
- case fpu_ds:
- value = fpu.ds;
- break;
-
- case fpu_mxcsr:
- value = fpu.mxcsr;
- break;
-
- case fpu_mxcsrmask:
- value = fpu.mxcsrmask;
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- // These values don't fit into scalar types,
- // RegisterContext::ReadRegisterBytes() must be used for these
- // registers
- //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes, 10);
- return false;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
- // must be used for these registers
- //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes, 16);
- return false;
-
- case exc_trapno:
- value = exc.trapno;
- break;
-
- case exc_err:
- value = exc.err;
- break;
-
- case exc_faultvaddr:
- value = exc.faultvaddr;
- break;
+ switch (reg) {
+ case gpr_eax:
+ case gpr_ebx:
+ case gpr_ecx:
+ case gpr_edx:
+ case gpr_edi:
+ case gpr_esi:
+ case gpr_ebp:
+ case gpr_esp:
+ case gpr_ss:
+ case gpr_eflags:
+ case gpr_eip:
+ case gpr_cs:
+ case gpr_ds:
+ case gpr_es:
+ case gpr_fs:
+ case gpr_gs:
+ value = (&gpr.eax)[reg - gpr_eax];
+ break;
+
+ case fpu_fcw:
+ value = fpu.fcw;
+ break;
+
+ case fpu_fsw:
+ value = fpu.fsw;
+ break;
+
+ case fpu_ftw:
+ value = fpu.ftw;
+ break;
+
+ case fpu_fop:
+ value = fpu.fop;
+ break;
+
+ case fpu_ip:
+ value = fpu.ip;
+ break;
+
+ case fpu_cs:
+ value = fpu.cs;
+ break;
+
+ case fpu_dp:
+ value = fpu.dp;
+ break;
+
+ case fpu_ds:
+ value = fpu.ds;
+ break;
+
+ case fpu_mxcsr:
+ value = fpu.mxcsr;
+ break;
+
+ case fpu_mxcsrmask:
+ value = fpu.mxcsrmask;
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes() must be used for these
+ // registers
+ //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes,
+ //10);
+ return false;
- default:
- return false;
- }
- return true;
-}
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes()
+ // must be used for these registers
+ //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes,
+ //16);
+ return false;
+ case exc_trapno:
+ value = exc.trapno;
+ break;
-bool
-RegisterContextDarwin_i386::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = GetSetForNativeRegNum (reg);
+ case exc_err:
+ value = exc.err;
+ break;
- if (set == -1)
- return false;
+ case exc_faultvaddr:
+ value = exc.faultvaddr;
+ break;
- if (ReadRegisterSet(set, false) != 0)
- return false;
+ default:
+ return false;
+ }
+ return true;
+}
- switch (reg)
- {
- case gpr_eax:
- case gpr_ebx:
- case gpr_ecx:
- case gpr_edx:
- case gpr_edi:
- case gpr_esi:
- case gpr_ebp:
- case gpr_esp:
- case gpr_ss:
- case gpr_eflags:
- case gpr_eip:
- case gpr_cs:
- case gpr_ds:
- case gpr_es:
- case gpr_fs:
- case gpr_gs:
- (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
- break;
-
- case fpu_fcw:
- fpu.fcw = value.GetAsUInt16();
- break;
-
- case fpu_fsw:
- fpu.fsw = value.GetAsUInt16();
- break;
-
- case fpu_ftw:
- fpu.ftw = value.GetAsUInt8();
- break;
-
- case fpu_fop:
- fpu.fop = value.GetAsUInt16();
- break;
-
- case fpu_ip:
- fpu.ip = value.GetAsUInt32();
- break;
-
- case fpu_cs:
- fpu.cs = value.GetAsUInt16();
- break;
-
- case fpu_dp:
- fpu.dp = value.GetAsUInt32();
- break;
-
- case fpu_ds:
- fpu.ds = value.GetAsUInt16();
- break;
-
- case fpu_mxcsr:
- fpu.mxcsr = value.GetAsUInt32();
- break;
-
- case fpu_mxcsrmask:
- fpu.mxcsrmask = value.GetAsUInt32();
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
- // must be used for these registers
- ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
- return false;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
- // must be used for these registers
- ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
- return false;
-
- case exc_trapno:
- exc.trapno = value.GetAsUInt32();
- break;
-
- case exc_err:
- exc.err = value.GetAsUInt32();
- break;
-
- case exc_faultvaddr:
- exc.faultvaddr = value.GetAsUInt32();
- break;
+bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = GetSetForNativeRegNum(reg);
- default:
- return false;
- }
- return WriteRegisterSet(set) == 0;
-}
+ if (set == -1)
+ return false;
-bool
-RegisterContextDarwin_i386::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == 0 &&
- ReadFPU (false) == 0 &&
- ReadEXC (false) == 0)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ switch (reg) {
+ case gpr_eax:
+ case gpr_ebx:
+ case gpr_ecx:
+ case gpr_edx:
+ case gpr_edi:
+ case gpr_esi:
+ case gpr_ebp:
+ case gpr_esp:
+ case gpr_ss:
+ case gpr_eflags:
+ case gpr_eip:
+ case gpr_cs:
+ case gpr_ds:
+ case gpr_es:
+ case gpr_fs:
+ case gpr_gs:
+ (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
+ break;
+
+ case fpu_fcw:
+ fpu.fcw = value.GetAsUInt16();
+ break;
+
+ case fpu_fsw:
+ fpu.fsw = value.GetAsUInt16();
+ break;
+
+ case fpu_ftw:
+ fpu.ftw = value.GetAsUInt8();
+ break;
+
+ case fpu_fop:
+ fpu.fop = value.GetAsUInt16();
+ break;
+
+ case fpu_ip:
+ fpu.ip = value.GetAsUInt32();
+ break;
+
+ case fpu_cs:
+ fpu.cs = value.GetAsUInt16();
+ break;
+
+ case fpu_dp:
+ fpu.dp = value.GetAsUInt32();
+ break;
+
+ case fpu_ds:
+ fpu.ds = value.GetAsUInt16();
+ break;
+
+ case fpu_mxcsr:
+ fpu.mxcsr = value.GetAsUInt32();
+ break;
+
+ case fpu_mxcsrmask:
+ fpu.mxcsrmask = value.GetAsUInt32();
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes()
+ // must be used for these registers
+ ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
+ return false;
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes()
+ // must be used for these registers
+ ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
return false;
-}
-bool
-RegisterContextDarwin_i386::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == 0)
- ++success_count;
- if (WriteFPU() == 0)
- ++success_count;
- if (WriteEXC() == 0)
- ++success_count;
- return success_count == 3;
- }
+ case exc_trapno:
+ exc.trapno = value.GetAsUInt32();
+ break;
+
+ case exc_err:
+ exc.err = value.GetAsUInt32();
+ break;
+
+ case exc_faultvaddr:
+ exc.faultvaddr = value.GetAsUInt32();
+ break;
+
+ default:
return false;
+ }
+ return WriteRegisterSet(set) == 0;
}
+bool RegisterContextDarwin_i386::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == 0 && ReadFPU(false) == 0 &&
+ ReadEXC(false) == 0) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
-uint32_t
-RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_eip;
- case LLDB_REGNUM_GENERIC_SP: return gpr_esp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_ebp;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
- case LLDB_REGNUM_GENERIC_RA:
- default:
- break;
- }
- }
- else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case dwarf_eax: return gpr_eax;
- case dwarf_ecx: return gpr_ecx;
- case dwarf_edx: return gpr_edx;
- case dwarf_ebx: return gpr_ebx;
- case dwarf_esp: return gpr_esp;
- case dwarf_ebp: return gpr_ebp;
- case dwarf_esi: return gpr_esi;
- case dwarf_edi: return gpr_edi;
- case dwarf_eip: return gpr_eip;
- case dwarf_eflags: return gpr_eflags;
- case dwarf_stmm0: return fpu_stmm0;
- case dwarf_stmm1: return fpu_stmm1;
- case dwarf_stmm2: return fpu_stmm2;
- case dwarf_stmm3: return fpu_stmm3;
- case dwarf_stmm4: return fpu_stmm4;
- case dwarf_stmm5: return fpu_stmm5;
- case dwarf_stmm6: return fpu_stmm6;
- case dwarf_stmm7: return fpu_stmm7;
- case dwarf_xmm0: return fpu_xmm0;
- case dwarf_xmm1: return fpu_xmm1;
- case dwarf_xmm2: return fpu_xmm2;
- case dwarf_xmm3: return fpu_xmm3;
- case dwarf_xmm4: return fpu_xmm4;
- case dwarf_xmm5: return fpu_xmm5;
- case dwarf_xmm6: return fpu_xmm6;
- case dwarf_xmm7: return fpu_xmm7;
- default:
- break;
- }
- }
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
- }
- return LLDB_INVALID_REGNUM;
-}
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
+}
-bool
-RegisterContextDarwin_i386::HardwareSingleStep (bool enable)
-{
- if (ReadGPR(false) != 0)
- return false;
+bool RegisterContextDarwin_i386::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == 0)
+ ++success_count;
+ if (WriteFPU() == 0)
+ ++success_count;
+ if (WriteEXC() == 0)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
+}
- const uint32_t trace_bit = 0x100u;
- if (enable)
- {
- // If the trace bit is already set, there is nothing to do
- if (gpr.eflags & trace_bit)
- return true;
- else
- gpr.eflags |= trace_bit;
+uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_eip;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_esp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_ebp;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_eflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ break;
}
- else
- {
- // If the trace bit is already cleared, there is nothing to do
- if (gpr.eflags & trace_bit)
- gpr.eflags &= ~trace_bit;
- else
- return true;
+ } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case dwarf_eax:
+ return gpr_eax;
+ case dwarf_ecx:
+ return gpr_ecx;
+ case dwarf_edx:
+ return gpr_edx;
+ case dwarf_ebx:
+ return gpr_ebx;
+ case dwarf_esp:
+ return gpr_esp;
+ case dwarf_ebp:
+ return gpr_ebp;
+ case dwarf_esi:
+ return gpr_esi;
+ case dwarf_edi:
+ return gpr_edi;
+ case dwarf_eip:
+ return gpr_eip;
+ case dwarf_eflags:
+ return gpr_eflags;
+ case dwarf_stmm0:
+ return fpu_stmm0;
+ case dwarf_stmm1:
+ return fpu_stmm1;
+ case dwarf_stmm2:
+ return fpu_stmm2;
+ case dwarf_stmm3:
+ return fpu_stmm3;
+ case dwarf_stmm4:
+ return fpu_stmm4;
+ case dwarf_stmm5:
+ return fpu_stmm5;
+ case dwarf_stmm6:
+ return fpu_stmm6;
+ case dwarf_stmm7:
+ return fpu_stmm7;
+ case dwarf_xmm0:
+ return fpu_xmm0;
+ case dwarf_xmm1:
+ return fpu_xmm1;
+ case dwarf_xmm2:
+ return fpu_xmm2;
+ case dwarf_xmm3:
+ return fpu_xmm3;
+ case dwarf_xmm4:
+ return fpu_xmm4;
+ case dwarf_xmm5:
+ return fpu_xmm5;
+ case dwarf_xmm6:
+ return fpu_xmm6;
+ case dwarf_xmm7:
+ return fpu_xmm7;
+ default:
+ break;
}
-
- return WriteGPR() == 0;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
+bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) {
+ if (ReadGPR(false) != 0)
+ return false;
+ const uint32_t trace_bit = 0x100u;
+ if (enable) {
+ // If the trace bit is already set, there is nothing to do
+ if (gpr.eflags & trace_bit)
+ return true;
+ else
+ gpr.eflags |= trace_bit;
+ } else {
+ // If the trace bit is already cleared, there is nothing to do
+ if (gpr.eflags & trace_bit)
+ gpr.eflags &= ~trace_bit;
+ else
+ return true;
+ }
+ return WriteGPR() == 0;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
index 9568b0332b4c..aea8a2900911 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
@@ -14,255 +14,200 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextDarwin_i386 : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_i386 : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_i386(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx);
-
- ~RegisterContextDarwin_i386() override;
-
- void
- InvalidateAllRegisters() override;
-
- 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;
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- bool
- HardwareSingleStep(bool enable) override;
-
- struct GPR
- {
- uint32_t eax;
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
- uint32_t edi;
- uint32_t esi;
- uint32_t ebp;
- uint32_t esp;
- uint32_t ss;
- uint32_t eflags;
- uint32_t eip;
- uint32_t cs;
- uint32_t ds;
- uint32_t es;
- uint32_t fs;
- uint32_t gs;
- };
-
- struct MMSReg
- {
- uint8_t bytes[10];
- uint8_t pad[6];
- };
-
- struct XMMReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- uint32_t pad[2];
- uint16_t fcw;
- uint16_t fsw;
- uint8_t ftw;
- uint8_t pad1;
- uint16_t fop;
- uint32_t ip;
- uint16_t cs;
- uint16_t pad2;
- uint32_t dp;
- uint16_t ds;
- uint16_t pad3;
- uint32_t mxcsr;
- uint32_t mxcsrmask;
- MMSReg stmm[8];
- XMMReg xmm[8];
- uint8_t pad4[14*16];
- int pad5;
- };
-
- struct EXC
- {
- uint32_t trapno;
- uint32_t err;
- uint32_t faultvaddr;
- };
+ RegisterContextDarwin_i386(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ ~RegisterContextDarwin_i386() override;
+
+ void InvalidateAllRegisters() override;
+
+ 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;
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ bool HardwareSingleStep(bool enable) override;
+
+ struct GPR {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t ss;
+ uint32_t eflags;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+ };
+
+ struct MMSReg {
+ uint8_t bytes[10];
+ uint8_t pad[6];
+ };
+
+ struct XMMReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ uint32_t pad[2];
+ uint16_t fcw;
+ uint16_t fsw;
+ uint8_t ftw;
+ uint8_t pad1;
+ uint16_t fop;
+ uint32_t ip;
+ uint16_t cs;
+ uint16_t pad2;
+ uint32_t dp;
+ uint16_t ds;
+ uint16_t pad3;
+ uint32_t mxcsr;
+ uint32_t mxcsrmask;
+ MMSReg stmm[8];
+ XMMReg xmm[8];
+ uint8_t pad4[14 * 16];
+ int pad5;
+ };
+
+ struct EXC {
+ uint32_t trapno;
+ uint32_t err;
+ uint32_t faultvaddr;
+ };
protected:
- enum
- {
- GPRRegSet = 1,
- FPURegSet = 2,
- EXCRegSet = 3
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t),
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t),
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t)
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum { GPRRegSet = 1, FPURegSet = 2, EXCRegSet = 3 };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t),
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t),
+ EXCWordCount = sizeof(EXC) / sizeof(uint32_t)
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ void LogGPR(lldb_private::Log *log, const char *title);
+
+ int ReadGPR(bool force);
+
+ int ReadFPU(bool force);
- void
- LogGPR (lldb_private::Log *log, const char *title);
+ int ReadEXC(bool force);
- int
- ReadGPR (bool force);
+ int WriteGPR();
- int
- ReadFPU (bool force);
+ int WriteFPU();
- int
- ReadEXC (bool force);
+ int WriteEXC();
- int
- WriteGPR ();
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0;
- int
- WriteFPU ();
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
- int
- WriteEXC ();
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) = 0;
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
- int
- ReadRegisterSet (uint32_t set, bool force);
+ int ReadRegisterSet(uint32_t set, bool force);
- int
- WriteRegisterSet (uint32_t set);
+ int WriteRegisterSet(uint32_t set);
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
- static int
- GetSetForNativeRegNum (int reg_num);
+ static int GetSetForNativeRegNum(int reg_num);
- static size_t
- GetRegisterInfosCount ();
+ static size_t GetRegisterInfosCount();
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_i386_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index aee6e1228d2a..7c0bafa68f9e 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -7,11 +7,10 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
#include <inttypes.h> // PRIx64
#include <stdarg.h>
-#include <stddef.h> // offsetof
+#include <stddef.h> // offsetof
// C++ Includes
// Other libraries and framework includes
@@ -36,340 +35,489 @@
using namespace lldb;
using namespace lldb_private;
-enum
-{
- gpr_rax = 0,
- gpr_rbx,
- gpr_rcx,
- gpr_rdx,
- gpr_rdi,
- gpr_rsi,
- gpr_rbp,
- gpr_rsp,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13,
- gpr_r14,
- gpr_r15,
- gpr_rip,
- gpr_rflags,
- gpr_cs,
- gpr_fs,
- gpr_gs,
-
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
- fpu_xmm8,
- fpu_xmm9,
- fpu_xmm10,
- fpu_xmm11,
- fpu_xmm12,
- fpu_xmm13,
- fpu_xmm14,
- fpu_xmm15,
-
- exc_trapno,
- exc_err,
- exc_faultvaddr,
-
- k_num_registers,
-
- // Aliases
- fpu_fctrl = fpu_fcw,
- fpu_fstat = fpu_fsw,
- fpu_ftag = fpu_ftw,
- fpu_fiseg = fpu_cs,
- fpu_fioff = fpu_ip,
- fpu_foseg = fpu_ds,
- fpu_fooff = fpu_dp
+enum {
+ gpr_rax = 0,
+ gpr_rbx,
+ gpr_rcx,
+ gpr_rdx,
+ gpr_rdi,
+ gpr_rsi,
+ gpr_rbp,
+ gpr_rsp,
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_r13,
+ gpr_r14,
+ gpr_r15,
+ gpr_rip,
+ gpr_rflags,
+ gpr_cs,
+ gpr_fs,
+ gpr_gs,
+
+ fpu_fcw,
+ fpu_fsw,
+ fpu_ftw,
+ fpu_fop,
+ fpu_ip,
+ fpu_cs,
+ fpu_dp,
+ fpu_ds,
+ fpu_mxcsr,
+ fpu_mxcsrmask,
+ fpu_stmm0,
+ fpu_stmm1,
+ fpu_stmm2,
+ fpu_stmm3,
+ fpu_stmm4,
+ fpu_stmm5,
+ fpu_stmm6,
+ fpu_stmm7,
+ fpu_xmm0,
+ fpu_xmm1,
+ fpu_xmm2,
+ fpu_xmm3,
+ fpu_xmm4,
+ fpu_xmm5,
+ fpu_xmm6,
+ fpu_xmm7,
+ fpu_xmm8,
+ fpu_xmm9,
+ fpu_xmm10,
+ fpu_xmm11,
+ fpu_xmm12,
+ fpu_xmm13,
+ fpu_xmm14,
+ fpu_xmm15,
+
+ exc_trapno,
+ exc_err,
+ exc_faultvaddr,
+
+ k_num_registers,
+
+ // Aliases
+ fpu_fctrl = fpu_fcw,
+ fpu_fstat = fpu_fsw,
+ fpu_ftag = fpu_ftw,
+ fpu_fiseg = fpu_cs,
+ fpu_fioff = fpu_ip,
+ fpu_foseg = fpu_ds,
+ fpu_fooff = fpu_dp
};
-enum ehframe_dwarf_regnums
-{
- ehframe_dwarf_gpr_rax = 0,
- ehframe_dwarf_gpr_rdx,
- ehframe_dwarf_gpr_rcx,
- ehframe_dwarf_gpr_rbx,
- ehframe_dwarf_gpr_rsi,
- ehframe_dwarf_gpr_rdi,
- ehframe_dwarf_gpr_rbp,
- ehframe_dwarf_gpr_rsp,
- ehframe_dwarf_gpr_r8,
- ehframe_dwarf_gpr_r9,
- ehframe_dwarf_gpr_r10,
- ehframe_dwarf_gpr_r11,
- ehframe_dwarf_gpr_r12,
- ehframe_dwarf_gpr_r13,
- ehframe_dwarf_gpr_r14,
- ehframe_dwarf_gpr_r15,
- ehframe_dwarf_gpr_rip,
- ehframe_dwarf_fpu_xmm0,
- ehframe_dwarf_fpu_xmm1,
- ehframe_dwarf_fpu_xmm2,
- ehframe_dwarf_fpu_xmm3,
- ehframe_dwarf_fpu_xmm4,
- ehframe_dwarf_fpu_xmm5,
- ehframe_dwarf_fpu_xmm6,
- ehframe_dwarf_fpu_xmm7,
- ehframe_dwarf_fpu_xmm8,
- ehframe_dwarf_fpu_xmm9,
- ehframe_dwarf_fpu_xmm10,
- ehframe_dwarf_fpu_xmm11,
- ehframe_dwarf_fpu_xmm12,
- ehframe_dwarf_fpu_xmm13,
- ehframe_dwarf_fpu_xmm14,
- ehframe_dwarf_fpu_xmm15,
- ehframe_dwarf_fpu_stmm0,
- ehframe_dwarf_fpu_stmm1,
- ehframe_dwarf_fpu_stmm2,
- ehframe_dwarf_fpu_stmm3,
- ehframe_dwarf_fpu_stmm4,
- ehframe_dwarf_fpu_stmm5,
- ehframe_dwarf_fpu_stmm6,
- ehframe_dwarf_fpu_stmm7
+enum ehframe_dwarf_regnums {
+ ehframe_dwarf_gpr_rax = 0,
+ ehframe_dwarf_gpr_rdx,
+ ehframe_dwarf_gpr_rcx,
+ ehframe_dwarf_gpr_rbx,
+ ehframe_dwarf_gpr_rsi,
+ ehframe_dwarf_gpr_rdi,
+ ehframe_dwarf_gpr_rbp,
+ ehframe_dwarf_gpr_rsp,
+ ehframe_dwarf_gpr_r8,
+ ehframe_dwarf_gpr_r9,
+ ehframe_dwarf_gpr_r10,
+ ehframe_dwarf_gpr_r11,
+ ehframe_dwarf_gpr_r12,
+ ehframe_dwarf_gpr_r13,
+ ehframe_dwarf_gpr_r14,
+ ehframe_dwarf_gpr_r15,
+ ehframe_dwarf_gpr_rip,
+ ehframe_dwarf_fpu_xmm0,
+ ehframe_dwarf_fpu_xmm1,
+ ehframe_dwarf_fpu_xmm2,
+ ehframe_dwarf_fpu_xmm3,
+ ehframe_dwarf_fpu_xmm4,
+ ehframe_dwarf_fpu_xmm5,
+ ehframe_dwarf_fpu_xmm6,
+ ehframe_dwarf_fpu_xmm7,
+ ehframe_dwarf_fpu_xmm8,
+ ehframe_dwarf_fpu_xmm9,
+ ehframe_dwarf_fpu_xmm10,
+ ehframe_dwarf_fpu_xmm11,
+ ehframe_dwarf_fpu_xmm12,
+ ehframe_dwarf_fpu_xmm13,
+ ehframe_dwarf_fpu_xmm14,
+ ehframe_dwarf_fpu_xmm15,
+ ehframe_dwarf_fpu_stmm0,
+ ehframe_dwarf_fpu_stmm1,
+ ehframe_dwarf_fpu_stmm2,
+ ehframe_dwarf_fpu_stmm3,
+ ehframe_dwarf_fpu_stmm4,
+ ehframe_dwarf_fpu_stmm5,
+ ehframe_dwarf_fpu_stmm6,
+ ehframe_dwarf_fpu_stmm7
};
-#define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::GPR, reg))
-#define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::FPU, reg) + sizeof (RegisterContextDarwin_x86_64::GPR))
-#define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::EXC, reg) + sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU))
+#define GPR_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::GPR, reg))
+#define FPU_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::FPU, reg) + \
+ sizeof(RegisterContextDarwin_x86_64::GPR))
+#define EXC_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::EXC, reg) + \
+ sizeof(RegisterContextDarwin_x86_64::GPR) + \
+ sizeof(RegisterContextDarwin_x86_64::FPU))
// These macros will auto define the register name, alt name, register size,
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { ehframe_dwarf_fpu_##reg##i, ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_##reg##i }, NULL, NULL
-#define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex
-
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU) + sizeof (RegisterContextDarwin_x86_64::EXC))
+#define DEFINE_GPR(reg, alt) \
+ #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_UINT(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg), \
+ FPU_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_VECT(reg, i) \
+ #reg #i, NULL, \
+ sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg[i].bytes), \
+ FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {ehframe_dwarf_fpu_##reg##i, \
+ ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpu_##reg##i }, \
+ nullptr, nullptr, nullptr, 0
+#define DEFINE_EXC(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \
+ EXC_OFFSET(reg), eEncodingUint, eFormatHex
+
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_x86_64::GPR) + \
+ sizeof(RegisterContextDarwin_x86_64::FPU) + \
+ sizeof(RegisterContextDarwin_x86_64::EXC))
// General purpose registers for 64 bit
-static RegisterInfo g_register_infos[] =
-{
-// Macro auto defines most stuff EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS
-// =============================== ====================== =================== ========================== ==================== =================== ========== ===============
- { DEFINE_GPR (rax , NULL) , { ehframe_dwarf_gpr_rax , ehframe_dwarf_gpr_rax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rax }, NULL, NULL},
- { DEFINE_GPR (rbx , NULL) , { ehframe_dwarf_gpr_rbx , ehframe_dwarf_gpr_rbx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rbx }, NULL, NULL},
- { DEFINE_GPR (rcx , NULL) , { ehframe_dwarf_gpr_rcx , ehframe_dwarf_gpr_rcx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rcx }, NULL, NULL},
- { DEFINE_GPR (rdx , NULL) , { ehframe_dwarf_gpr_rdx , ehframe_dwarf_gpr_rdx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rdx }, NULL, NULL},
- { DEFINE_GPR (rdi , NULL) , { ehframe_dwarf_gpr_rdi , ehframe_dwarf_gpr_rdi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rdi }, NULL, NULL},
- { DEFINE_GPR (rsi , NULL) , { ehframe_dwarf_gpr_rsi , ehframe_dwarf_gpr_rsi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rsi }, NULL, NULL},
- { DEFINE_GPR (rbp , "fp") , { ehframe_dwarf_gpr_rbp , ehframe_dwarf_gpr_rbp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, gpr_rbp }, NULL, NULL},
- { DEFINE_GPR (rsp , "sp") , { ehframe_dwarf_gpr_rsp , ehframe_dwarf_gpr_rsp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, gpr_rsp }, NULL, NULL},
- { DEFINE_GPR (r8 , NULL) , { ehframe_dwarf_gpr_r8 , ehframe_dwarf_gpr_r8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r8 }, NULL, NULL},
- { DEFINE_GPR (r9 , NULL) , { ehframe_dwarf_gpr_r9 , ehframe_dwarf_gpr_r9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r9 }, NULL, NULL},
- { DEFINE_GPR (r10 , NULL) , { ehframe_dwarf_gpr_r10 , ehframe_dwarf_gpr_r10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r10 }, NULL, NULL},
- { DEFINE_GPR (r11 , NULL) , { ehframe_dwarf_gpr_r11 , ehframe_dwarf_gpr_r11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r11 }, NULL, NULL},
- { DEFINE_GPR (r12 , NULL) , { ehframe_dwarf_gpr_r12 , ehframe_dwarf_gpr_r12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r12 }, NULL, NULL},
- { DEFINE_GPR (r13 , NULL) , { ehframe_dwarf_gpr_r13 , ehframe_dwarf_gpr_r13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r13 }, NULL, NULL},
- { DEFINE_GPR (r14 , NULL) , { ehframe_dwarf_gpr_r14 , ehframe_dwarf_gpr_r14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r14 }, NULL, NULL},
- { DEFINE_GPR (r15 , NULL) , { ehframe_dwarf_gpr_r15 , ehframe_dwarf_gpr_r15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r15 }, NULL, NULL},
- { DEFINE_GPR (rip , "pc") , { ehframe_dwarf_gpr_rip , ehframe_dwarf_gpr_rip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, gpr_rip }, NULL, NULL},
- { DEFINE_GPR (rflags, "flags") , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_rflags }, NULL, NULL},
- { DEFINE_GPR (cs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_cs }, NULL, NULL},
- { DEFINE_GPR (fs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_fs }, NULL, NULL},
- { DEFINE_GPR (gs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_gs }, NULL, NULL},
-
- { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fcw }, NULL, NULL},
- { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fsw }, NULL, NULL},
- { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ftw }, NULL, NULL},
- { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fop }, NULL, NULL},
- { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ip }, NULL, NULL},
- { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_cs }, NULL, NULL},
- { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_dp }, NULL, NULL},
- { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ds }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsr }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask }, NULL, NULL},
- { DEFINE_FPU_VECT(stmm,0) },
- { DEFINE_FPU_VECT(stmm,1) },
- { DEFINE_FPU_VECT(stmm,2) },
- { DEFINE_FPU_VECT(stmm,3) },
- { DEFINE_FPU_VECT(stmm,4) },
- { DEFINE_FPU_VECT(stmm,5) },
- { DEFINE_FPU_VECT(stmm,6) },
- { DEFINE_FPU_VECT(stmm,7) },
- { DEFINE_FPU_VECT(xmm,0) },
- { DEFINE_FPU_VECT(xmm,1) },
- { DEFINE_FPU_VECT(xmm,2) },
- { DEFINE_FPU_VECT(xmm,3) },
- { DEFINE_FPU_VECT(xmm,4) },
- { DEFINE_FPU_VECT(xmm,5) },
- { DEFINE_FPU_VECT(xmm,6) },
- { DEFINE_FPU_VECT(xmm,7) },
- { DEFINE_FPU_VECT(xmm,8) },
- { DEFINE_FPU_VECT(xmm,9) },
- { DEFINE_FPU_VECT(xmm,10) },
- { DEFINE_FPU_VECT(xmm,11) },
- { DEFINE_FPU_VECT(xmm,12) },
- { DEFINE_FPU_VECT(xmm,13) },
- { DEFINE_FPU_VECT(xmm,14) },
- { DEFINE_FPU_VECT(xmm,15) },
-
- { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL},
- { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL},
- { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL}
-};
+static RegisterInfo g_register_infos[] = {
+ // Macro auto defines most stuff EH_FRAME DWARF
+ // GENERIC PROCESS PLUGIN LLDB
+ // =============================== ======================
+ // =================== ========================== ====================
+ // ===================
+ {DEFINE_GPR(rax, NULL),
+ {ehframe_dwarf_gpr_rax, ehframe_dwarf_gpr_rax, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rax},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rbx, NULL),
+ {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rbx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rcx, NULL),
+ {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rcx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rdx, NULL),
+ {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rdx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rdi, NULL),
+ {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rdi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rsi, NULL),
+ {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rsi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rbp, "fp"),
+ {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, gpr_rbp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rsp, "sp"),
+ {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, gpr_rsp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r8, NULL),
+ {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r9, NULL),
+ {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r10, NULL),
+ {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r11, NULL),
+ {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r12, NULL),
+ {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r13, NULL),
+ {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r13},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r14, NULL),
+ {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r14},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r15, NULL),
+ {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r15},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rip, "pc"),
+ {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, gpr_rip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rflags, "flags"),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, gpr_rflags},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(cs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(fs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_fs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(gs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_gs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_FPU_UINT(fcw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fcw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fsw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fsw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ftw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ftw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fop),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fop},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ip),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(cs),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(dp),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_dp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ds),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ds},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsrmask),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsrmask},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_VECT(stmm, 0)},
+ {DEFINE_FPU_VECT(stmm, 1)},
+ {DEFINE_FPU_VECT(stmm, 2)},
+ {DEFINE_FPU_VECT(stmm, 3)},
+ {DEFINE_FPU_VECT(stmm, 4)},
+ {DEFINE_FPU_VECT(stmm, 5)},
+ {DEFINE_FPU_VECT(stmm, 6)},
+ {DEFINE_FPU_VECT(stmm, 7)},
+ {DEFINE_FPU_VECT(xmm, 0)},
+ {DEFINE_FPU_VECT(xmm, 1)},
+ {DEFINE_FPU_VECT(xmm, 2)},
+ {DEFINE_FPU_VECT(xmm, 3)},
+ {DEFINE_FPU_VECT(xmm, 4)},
+ {DEFINE_FPU_VECT(xmm, 5)},
+ {DEFINE_FPU_VECT(xmm, 6)},
+ {DEFINE_FPU_VECT(xmm, 7)},
+ {DEFINE_FPU_VECT(xmm, 8)},
+ {DEFINE_FPU_VECT(xmm, 9)},
+ {DEFINE_FPU_VECT(xmm, 10)},
+ {DEFINE_FPU_VECT(xmm, 11)},
+ {DEFINE_FPU_VECT(xmm, 12)},
+ {DEFINE_FPU_VECT(xmm, 13)},
+ {DEFINE_FPU_VECT(xmm, 14)},
+ {DEFINE_FPU_VECT(xmm, 15)},
+
+ {DEFINE_EXC(trapno),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_trapno},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(err),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_err},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(faultvaddr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_faultvaddr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64 (Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext (thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
-
-RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64()
-{
+RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() {}
-void
-RegisterContextDarwin_x86_64::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_x86_64::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_x86_64::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
-
const RegisterInfo *
-RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos[reg];
+ return NULL;
}
-
-size_t
-RegisterContextDarwin_x86_64::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
const lldb_private::RegisterInfo *
-RegisterContextDarwin_x86_64::GetRegisterInfos ()
-{
- return g_register_infos;
+RegisterContextDarwin_x86_64::GetRegisterInfos() {
+ return g_register_infos;
}
+static uint32_t g_gpr_regnums[] = {
+ gpr_rax, gpr_rbx, gpr_rcx, gpr_rdx, gpr_rdi, gpr_rsi, gpr_rbp,
+ gpr_rsp, gpr_r8, gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_r13,
+ gpr_r14, gpr_r15, gpr_rip, gpr_rflags, gpr_cs, gpr_fs, gpr_gs};
+static uint32_t g_fpu_regnums[] = {
+ fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
+ fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
+ fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
+ fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
+ fpu_xmm6, fpu_xmm7, fpu_xmm8, fpu_xmm9, fpu_xmm10, fpu_xmm11,
+ fpu_xmm12, fpu_xmm13, fpu_xmm14, fpu_xmm15};
-static uint32_t g_gpr_regnums[] =
-{
- gpr_rax,
- gpr_rbx,
- gpr_rcx,
- gpr_rdx,
- gpr_rdi,
- gpr_rsi,
- gpr_rbp,
- gpr_rsp,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13,
- gpr_r14,
- gpr_r15,
- gpr_rip,
- gpr_rflags,
- gpr_cs,
- gpr_fs,
- gpr_gs
-};
-
-static uint32_t g_fpu_regnums[] =
-{
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
- fpu_xmm8,
- fpu_xmm9,
- fpu_xmm10,
- fpu_xmm11,
- fpu_xmm12,
- fpu_xmm13,
- fpu_xmm14,
- fpu_xmm15
-};
-
-static uint32_t
-g_exc_regnums[] =
-{
- exc_trapno,
- exc_err,
- exc_faultvaddr
-};
+static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
@@ -381,562 +529,556 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_x86_64::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() {
+ return k_num_regsets;
}
const RegisterSet *
-RegisterContextDarwin_x86_64::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
-}
-
-int
-RegisterContextDarwin_x86_64::GetSetForNativeRegNum (int reg_num)
-{
- if (reg_num < fpu_fcw)
- return GPRRegSet;
- else if (reg_num < exc_trapno)
- return FPURegSet;
- else if (reg_num < k_num_registers)
- return EXCRegSet;
- return -1;
+RegisterContextDarwin_x86_64::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-void
-RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...)
-{
- if (log)
- {
- if (format)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
- for (uint32_t i=0; i<k_num_gpr_registers; i++)
- {
- uint32_t reg = gpr_rax + i;
- log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name, (&gpr.rax)[reg]);
- }
- }
+int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) {
+ if (reg_num < fpu_fcw)
+ return GPRRegSet;
+ else if (reg_num < exc_trapno)
+ return FPURegSet;
+ else if (reg_num < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-int
-RegisterContextDarwin_x86_64::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+void RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) {
+ if (log) {
+ if (format) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
}
- return GetError(GPRRegSet, Read);
-}
-
-int
-RegisterContextDarwin_x86_64::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
+ uint32_t reg = gpr_rax + i;
+ log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name,
+ (&gpr.rax)[reg]);
}
- return GetError(FPURegSet, Read);
+ }
}
-int
-RegisterContextDarwin_x86_64::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(EXCRegSet, Read);
+int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(GPRRegSet, Read);
}
-int
-RegisterContextDarwin_x86_64::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError (set, Write);
+int RegisterContextDarwin_x86_64::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(FPURegSet, Read);
}
-int
-RegisterContextDarwin_x86_64::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError (set, Write);
+int RegisterContextDarwin_x86_64::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(EXCRegSet, Read);
}
-int
-RegisterContextDarwin_x86_64::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError (set, Write);
+int RegisterContextDarwin_x86_64::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR (force);
- case FPURegSet: return ReadFPU (force);
- case EXCRegSet: return ReadEXC (force);
- default: break;
- }
+int RegisterContextDarwin_x86_64::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return -1;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set)
-{
- // Make sure we have a valid context to set.
- switch (set)
- {
- case GPRRegSet: return WriteGPR ();
- case FPURegSet: return WriteFPU ();
- case EXCRegSet: return WriteEXC ();
- default: break;
- }
+int RegisterContextDarwin_x86_64::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return -1;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
+int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ default:
+ break;
+ }
+ return -1;
+}
-bool
-RegisterContextDarwin_x86_64::ReadRegister (const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
- if (set == -1)
- return false;
+int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ default:
+ break;
+ }
+ return -1;
+}
- if (ReadRegisterSet(set, false) != 0)
- return false;
+bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
+ if (set == -1)
+ return false;
- switch (reg)
- {
- case gpr_rax:
- case gpr_rbx:
- case gpr_rcx:
- case gpr_rdx:
- case gpr_rdi:
- case gpr_rsi:
- case gpr_rbp:
- case gpr_rsp:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_r13:
- case gpr_r14:
- case gpr_r15:
- case gpr_rip:
- case gpr_rflags:
- case gpr_cs:
- case gpr_fs:
- case gpr_gs:
- value = (&gpr.rax)[reg - gpr_rax];
- break;
-
- case fpu_fcw:
- value = fpu.fcw;
- break;
-
- case fpu_fsw:
- value = fpu.fsw;
- break;
-
- case fpu_ftw:
- value = fpu.ftw;
- break;
-
- case fpu_fop:
- value = fpu.fop;
- break;
-
- case fpu_ip:
- value = fpu.ip;
- break;
-
- case fpu_cs:
- value = fpu.cs;
- break;
-
- case fpu_dp:
- value = fpu.dp;
- break;
-
- case fpu_ds:
- value = fpu.ds;
- break;
-
- case fpu_mxcsr:
- value = fpu.mxcsr;
- break;
-
- case fpu_mxcsrmask:
- value = fpu.mxcsrmask;
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, endian::InlHostByteOrder());
- break;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- case fpu_xmm8:
- case fpu_xmm9:
- case fpu_xmm10:
- case fpu_xmm11:
- case fpu_xmm12:
- case fpu_xmm13:
- case fpu_xmm14:
- case fpu_xmm15:
- value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, endian::InlHostByteOrder());
- break;
-
- case exc_trapno:
- value = exc.trapno;
- break;
-
- case exc_err:
- value = exc.err;
- break;
-
- case exc_faultvaddr:
- value = exc.faultvaddr;
- break;
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- default:
- return false;
- }
- return true;
+ switch (reg) {
+ case gpr_rax:
+ case gpr_rbx:
+ case gpr_rcx:
+ case gpr_rdx:
+ case gpr_rdi:
+ case gpr_rsi:
+ case gpr_rbp:
+ case gpr_rsp:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_r13:
+ case gpr_r14:
+ case gpr_r15:
+ case gpr_rip:
+ case gpr_rflags:
+ case gpr_cs:
+ case gpr_fs:
+ case gpr_gs:
+ value = (&gpr.rax)[reg - gpr_rax];
+ break;
+
+ case fpu_fcw:
+ value = fpu.fcw;
+ break;
+
+ case fpu_fsw:
+ value = fpu.fsw;
+ break;
+
+ case fpu_ftw:
+ value = fpu.ftw;
+ break;
+
+ case fpu_fop:
+ value = fpu.fop;
+ break;
+
+ case fpu_ip:
+ value = fpu.ip;
+ break;
+
+ case fpu_cs:
+ value = fpu.cs;
+ break;
+
+ case fpu_dp:
+ value = fpu.dp;
+ break;
+
+ case fpu_ds:
+ value = fpu.ds;
+ break;
+
+ case fpu_mxcsr:
+ value = fpu.mxcsr;
+ break;
+
+ case fpu_mxcsrmask:
+ value = fpu.mxcsrmask;
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size,
+ endian::InlHostByteOrder());
+ break;
+
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ case fpu_xmm8:
+ case fpu_xmm9:
+ case fpu_xmm10:
+ case fpu_xmm11:
+ case fpu_xmm12:
+ case fpu_xmm13:
+ case fpu_xmm14:
+ case fpu_xmm15:
+ value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size,
+ endian::InlHostByteOrder());
+ break;
+
+ case exc_trapno:
+ value = exc.trapno;
+ break;
+
+ case exc_err:
+ value = exc.err;
+ break;
+
+ case exc_faultvaddr:
+ value = exc.faultvaddr;
+ break;
+
+ default:
+ return false;
+ }
+ return true;
}
+bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
-bool
-RegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
+ if (set == -1)
+ return false;
- if (ReadRegisterSet(set, false) != 0)
- return false;
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- switch (reg)
- {
- case gpr_rax:
- case gpr_rbx:
- case gpr_rcx:
- case gpr_rdx:
- case gpr_rdi:
- case gpr_rsi:
- case gpr_rbp:
- case gpr_rsp:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_r13:
- case gpr_r14:
- case gpr_r15:
- case gpr_rip:
- case gpr_rflags:
- case gpr_cs:
- case gpr_fs:
- case gpr_gs:
- (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
- break;
-
- case fpu_fcw:
- fpu.fcw = value.GetAsUInt16();
- break;
-
- case fpu_fsw:
- fpu.fsw = value.GetAsUInt16();
- break;
-
- case fpu_ftw:
- fpu.ftw = value.GetAsUInt8();
- break;
-
- case fpu_fop:
- fpu.fop = value.GetAsUInt16();
- break;
-
- case fpu_ip:
- fpu.ip = value.GetAsUInt32();
- break;
-
- case fpu_cs:
- fpu.cs = value.GetAsUInt16();
- break;
-
- case fpu_dp:
- fpu.dp = value.GetAsUInt32();
- break;
-
- case fpu_ds:
- fpu.ds = value.GetAsUInt16();
- break;
-
- case fpu_mxcsr:
- fpu.mxcsr = value.GetAsUInt32();
- break;
-
- case fpu_mxcsrmask:
- fpu.mxcsrmask = value.GetAsUInt32();
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
- break;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- case fpu_xmm8:
- case fpu_xmm9:
- case fpu_xmm10:
- case fpu_xmm11:
- case fpu_xmm12:
- case fpu_xmm13:
- case fpu_xmm14:
- case fpu_xmm15:
- ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
- return false;
-
- case exc_trapno:
- exc.trapno = value.GetAsUInt32();
- break;
-
- case exc_err:
- exc.err = value.GetAsUInt32();
- break;
-
- case exc_faultvaddr:
- exc.faultvaddr = value.GetAsUInt64();
- break;
+ switch (reg) {
+ case gpr_rax:
+ case gpr_rbx:
+ case gpr_rcx:
+ case gpr_rdx:
+ case gpr_rdi:
+ case gpr_rsi:
+ case gpr_rbp:
+ case gpr_rsp:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_r13:
+ case gpr_r14:
+ case gpr_r15:
+ case gpr_rip:
+ case gpr_rflags:
+ case gpr_cs:
+ case gpr_fs:
+ case gpr_gs:
+ (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
+ break;
+
+ case fpu_fcw:
+ fpu.fcw = value.GetAsUInt16();
+ break;
+
+ case fpu_fsw:
+ fpu.fsw = value.GetAsUInt16();
+ break;
+
+ case fpu_ftw:
+ fpu.ftw = value.GetAsUInt8();
+ break;
+
+ case fpu_fop:
+ fpu.fop = value.GetAsUInt16();
+ break;
+
+ case fpu_ip:
+ fpu.ip = value.GetAsUInt32();
+ break;
+
+ case fpu_cs:
+ fpu.cs = value.GetAsUInt16();
+ break;
+
+ case fpu_dp:
+ fpu.dp = value.GetAsUInt32();
+ break;
+
+ case fpu_ds:
+ fpu.ds = value.GetAsUInt16();
+ break;
+
+ case fpu_mxcsr:
+ fpu.mxcsr = value.GetAsUInt32();
+ break;
+
+ case fpu_mxcsrmask:
+ fpu.mxcsrmask = value.GetAsUInt32();
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
+ break;
+
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ case fpu_xmm8:
+ case fpu_xmm9:
+ case fpu_xmm10:
+ case fpu_xmm11:
+ case fpu_xmm12:
+ case fpu_xmm13:
+ case fpu_xmm14:
+ case fpu_xmm15:
+ ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
+ return false;
- default:
- return false;
- }
- return WriteRegisterSet(set) == 0;
-}
+ case exc_trapno:
+ exc.trapno = value.GetAsUInt32();
+ break;
-bool
-RegisterContextDarwin_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == 0 &&
- ReadFPU (false) == 0 &&
- ReadEXC (false) == 0)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+ case exc_err:
+ exc.err = value.GetAsUInt32();
+ break;
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ case exc_faultvaddr:
+ exc.faultvaddr = value.GetAsUInt64();
+ break;
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
+ default:
return false;
+ }
+ return WriteRegisterSet(set) == 0;
}
-bool
-RegisterContextDarwin_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == 0)
- ++success_count;
- if (WriteFPU() == 0)
- ++success_count;
- if (WriteEXC() == 0)
- ++success_count;
- return success_count == 3;
- }
- return false;
+bool RegisterContextDarwin_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == 0 && ReadFPU(false) == 0 &&
+ ReadEXC(false) == 0) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
+
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
+
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
}
+bool RegisterContextDarwin_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == 0)
+ ++success_count;
+ if (WriteFPU() == 0)
+ ++success_count;
+ if (WriteEXC() == 0)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
+}
-uint32_t
-RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
- case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
- case LLDB_REGNUM_GENERIC_RA:
- default:
- break;
- }
- }
- else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case ehframe_dwarf_gpr_rax: return gpr_rax;
- case ehframe_dwarf_gpr_rdx: return gpr_rdx;
- case ehframe_dwarf_gpr_rcx: return gpr_rcx;
- case ehframe_dwarf_gpr_rbx: return gpr_rbx;
- case ehframe_dwarf_gpr_rsi: return gpr_rsi;
- case ehframe_dwarf_gpr_rdi: return gpr_rdi;
- case ehframe_dwarf_gpr_rbp: return gpr_rbp;
- case ehframe_dwarf_gpr_rsp: return gpr_rsp;
- case ehframe_dwarf_gpr_r8: return gpr_r8;
- case ehframe_dwarf_gpr_r9: return gpr_r9;
- case ehframe_dwarf_gpr_r10: return gpr_r10;
- case ehframe_dwarf_gpr_r11: return gpr_r11;
- case ehframe_dwarf_gpr_r12: return gpr_r12;
- case ehframe_dwarf_gpr_r13: return gpr_r13;
- case ehframe_dwarf_gpr_r14: return gpr_r14;
- case ehframe_dwarf_gpr_r15: return gpr_r15;
- case ehframe_dwarf_gpr_rip: return gpr_rip;
- case ehframe_dwarf_fpu_xmm0: return fpu_xmm0;
- case ehframe_dwarf_fpu_xmm1: return fpu_xmm1;
- case ehframe_dwarf_fpu_xmm2: return fpu_xmm2;
- case ehframe_dwarf_fpu_xmm3: return fpu_xmm3;
- case ehframe_dwarf_fpu_xmm4: return fpu_xmm4;
- case ehframe_dwarf_fpu_xmm5: return fpu_xmm5;
- case ehframe_dwarf_fpu_xmm6: return fpu_xmm6;
- case ehframe_dwarf_fpu_xmm7: return fpu_xmm7;
- case ehframe_dwarf_fpu_xmm8: return fpu_xmm8;
- case ehframe_dwarf_fpu_xmm9: return fpu_xmm9;
- case ehframe_dwarf_fpu_xmm10: return fpu_xmm10;
- case ehframe_dwarf_fpu_xmm11: return fpu_xmm11;
- case ehframe_dwarf_fpu_xmm12: return fpu_xmm12;
- case ehframe_dwarf_fpu_xmm13: return fpu_xmm13;
- case ehframe_dwarf_fpu_xmm14: return fpu_xmm14;
- case ehframe_dwarf_fpu_xmm15: return fpu_xmm15;
- case ehframe_dwarf_fpu_stmm0: return fpu_stmm0;
- case ehframe_dwarf_fpu_stmm1: return fpu_stmm1;
- case ehframe_dwarf_fpu_stmm2: return fpu_stmm2;
- case ehframe_dwarf_fpu_stmm3: return fpu_stmm3;
- case ehframe_dwarf_fpu_stmm4: return fpu_stmm4;
- case ehframe_dwarf_fpu_stmm5: return fpu_stmm5;
- case ehframe_dwarf_fpu_stmm6: return fpu_stmm6;
- case ehframe_dwarf_fpu_stmm7: return fpu_stmm7;
- default:
- break;
- }
+uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_rip;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_rsp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_rbp;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_rflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ break;
}
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
+ } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case ehframe_dwarf_gpr_rax:
+ return gpr_rax;
+ case ehframe_dwarf_gpr_rdx:
+ return gpr_rdx;
+ case ehframe_dwarf_gpr_rcx:
+ return gpr_rcx;
+ case ehframe_dwarf_gpr_rbx:
+ return gpr_rbx;
+ case ehframe_dwarf_gpr_rsi:
+ return gpr_rsi;
+ case ehframe_dwarf_gpr_rdi:
+ return gpr_rdi;
+ case ehframe_dwarf_gpr_rbp:
+ return gpr_rbp;
+ case ehframe_dwarf_gpr_rsp:
+ return gpr_rsp;
+ case ehframe_dwarf_gpr_r8:
+ return gpr_r8;
+ case ehframe_dwarf_gpr_r9:
+ return gpr_r9;
+ case ehframe_dwarf_gpr_r10:
+ return gpr_r10;
+ case ehframe_dwarf_gpr_r11:
+ return gpr_r11;
+ case ehframe_dwarf_gpr_r12:
+ return gpr_r12;
+ case ehframe_dwarf_gpr_r13:
+ return gpr_r13;
+ case ehframe_dwarf_gpr_r14:
+ return gpr_r14;
+ case ehframe_dwarf_gpr_r15:
+ return gpr_r15;
+ case ehframe_dwarf_gpr_rip:
+ return gpr_rip;
+ case ehframe_dwarf_fpu_xmm0:
+ return fpu_xmm0;
+ case ehframe_dwarf_fpu_xmm1:
+ return fpu_xmm1;
+ case ehframe_dwarf_fpu_xmm2:
+ return fpu_xmm2;
+ case ehframe_dwarf_fpu_xmm3:
+ return fpu_xmm3;
+ case ehframe_dwarf_fpu_xmm4:
+ return fpu_xmm4;
+ case ehframe_dwarf_fpu_xmm5:
+ return fpu_xmm5;
+ case ehframe_dwarf_fpu_xmm6:
+ return fpu_xmm6;
+ case ehframe_dwarf_fpu_xmm7:
+ return fpu_xmm7;
+ case ehframe_dwarf_fpu_xmm8:
+ return fpu_xmm8;
+ case ehframe_dwarf_fpu_xmm9:
+ return fpu_xmm9;
+ case ehframe_dwarf_fpu_xmm10:
+ return fpu_xmm10;
+ case ehframe_dwarf_fpu_xmm11:
+ return fpu_xmm11;
+ case ehframe_dwarf_fpu_xmm12:
+ return fpu_xmm12;
+ case ehframe_dwarf_fpu_xmm13:
+ return fpu_xmm13;
+ case ehframe_dwarf_fpu_xmm14:
+ return fpu_xmm14;
+ case ehframe_dwarf_fpu_xmm15:
+ return fpu_xmm15;
+ case ehframe_dwarf_fpu_stmm0:
+ return fpu_stmm0;
+ case ehframe_dwarf_fpu_stmm1:
+ return fpu_stmm1;
+ case ehframe_dwarf_fpu_stmm2:
+ return fpu_stmm2;
+ case ehframe_dwarf_fpu_stmm3:
+ return fpu_stmm3;
+ case ehframe_dwarf_fpu_stmm4:
+ return fpu_stmm4;
+ case ehframe_dwarf_fpu_stmm5:
+ return fpu_stmm5;
+ case ehframe_dwarf_fpu_stmm6:
+ return fpu_stmm6;
+ case ehframe_dwarf_fpu_stmm7:
+ return fpu_stmm7;
+ default:
+ break;
}
- return LLDB_INVALID_REGNUM;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
-bool
-RegisterContextDarwin_x86_64::HardwareSingleStep (bool enable)
-{
- if (ReadGPR(true) != 0)
- return false;
+bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable) {
+ if (ReadGPR(true) != 0)
+ return false;
- const uint64_t trace_bit = 0x100ull;
- if (enable)
- {
+ const uint64_t trace_bit = 0x100ull;
+ if (enable) {
- if (gpr.rflags & trace_bit)
- return true; // trace bit is already set, there is nothing to do
- else
- gpr.rflags |= trace_bit;
- }
+ if (gpr.rflags & trace_bit)
+ return true; // trace bit is already set, there is nothing to do
else
- {
- if (gpr.rflags & trace_bit)
- gpr.rflags &= ~trace_bit;
- else
- return true; // trace bit is clear, there is nothing to do
- }
+ gpr.rflags |= trace_bit;
+ } else {
+ if (gpr.rflags & trace_bit)
+ gpr.rflags &= ~trace_bit;
+ else
+ return true; // trace bit is clear, there is nothing to do
+ }
- return WriteGPR() == 0;
+ return WriteGPR() == 0;
}
-
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
index ed627e194a26..fdd5e8036dee 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
@@ -14,261 +14,205 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_x86_64 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx);
-
- ~RegisterContextDarwin_x86_64() override;
-
- void
- InvalidateAllRegisters() override;
-
- 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;
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- bool
- HardwareSingleStep(bool enable) override;
-
- struct GPR
- {
- uint64_t rax;
- uint64_t rbx;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rdi;
- uint64_t rsi;
- uint64_t rbp;
- uint64_t rsp;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t rip;
- uint64_t rflags;
- uint64_t cs;
- uint64_t fs;
- uint64_t gs;
- };
-
- struct MMSReg
- {
- uint8_t bytes[10];
- uint8_t pad[6];
- };
-
- struct XMMReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- uint32_t pad[2];
- uint16_t fcw; // "fctrl"
- uint16_t fsw; // "fstat"
- uint8_t ftw; // "ftag"
- uint8_t pad1;
- uint16_t fop; // "fop"
- uint32_t ip; // "fioff"
- uint16_t cs; // "fiseg"
- uint16_t pad2;
- uint32_t dp; // "fooff"
- uint16_t ds; // "foseg"
- uint16_t pad3;
- uint32_t mxcsr;
- uint32_t mxcsrmask;
- MMSReg stmm[8];
- XMMReg xmm[16];
- uint8_t pad4[6*16];
- int pad5;
- };
-
- struct EXC
- {
- uint32_t trapno;
- uint32_t err;
- uint64_t faultvaddr;
- };
+ RegisterContextDarwin_x86_64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ ~RegisterContextDarwin_x86_64() override;
+
+ void InvalidateAllRegisters() override;
+
+ 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;
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ bool HardwareSingleStep(bool enable) override;
+
+ struct GPR {
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rbp;
+ uint64_t rsp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint64_t cs;
+ uint64_t fs;
+ uint64_t gs;
+ };
+
+ struct MMSReg {
+ uint8_t bytes[10];
+ uint8_t pad[6];
+ };
+
+ struct XMMReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ uint32_t pad[2];
+ uint16_t fcw; // "fctrl"
+ uint16_t fsw; // "fstat"
+ uint8_t ftw; // "ftag"
+ uint8_t pad1;
+ uint16_t fop; // "fop"
+ uint32_t ip; // "fioff"
+ uint16_t cs; // "fiseg"
+ uint16_t pad2;
+ uint32_t dp; // "fooff"
+ uint16_t ds; // "foseg"
+ uint16_t pad3;
+ uint32_t mxcsr;
+ uint32_t mxcsrmask;
+ MMSReg stmm[8];
+ XMMReg xmm[16];
+ uint8_t pad4[6 * 16];
+ int pad5;
+ };
+
+ struct EXC {
+ uint32_t trapno;
+ uint32_t err;
+ uint64_t faultvaddr;
+ };
protected:
-
- enum
- {
- GPRRegSet = 4,
- FPURegSet = 5,
- EXCRegSet = 6
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t),
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t),
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t)
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum { GPRRegSet = 4, FPURegSet = 5, EXCRegSet = 6 };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t),
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t),
+ EXCWordCount = sizeof(EXC) / sizeof(uint32_t)
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ void LogGPR(lldb_private::Log *log, const char *format, ...);
+
+ int ReadGPR(bool force);
+
+ int ReadFPU(bool force);
+
+ int ReadEXC(bool force);
+
+ int WriteGPR();
+
+ int WriteFPU();
+
+ int WriteEXC();
+
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0;
+
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
+
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
+
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
+
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+
+ int ReadRegisterSet(uint32_t set, bool force);
+
+ int WriteRegisterSet(uint32_t set);
+
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
+
+ static int GetSetForNativeRegNum(int reg_num);
+
+ static size_t GetRegisterInfosCount();
- void
- LogGPR (lldb_private::Log *log, const char *format, ...);
-
- int
- ReadGPR (bool force);
-
- int
- ReadFPU (bool force);
-
- int
- ReadEXC (bool force);
-
- int
- WriteGPR ();
-
- int
- WriteFPU ();
-
- int
- WriteEXC ();
-
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) = 0;
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
-
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
-
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
-
- int
- ReadRegisterSet (uint32_t set, bool force);
-
- int
- WriteRegisterSet (uint32_t set);
-
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
-
- static int
- GetSetForNativeRegNum (int reg_num);
-
- static size_t
- GetRegisterInfosCount ();
-
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_x86_64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/source/Plugins/Process/Utility/RegisterContextDummy.cpp
index 0859e4e9419c..93bb09b810ac 100644
--- a/source/Plugins/Process/Utility/RegisterContextDummy.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDummy.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextDummy.cpp ---------------------------------*- C++ -*-===//
+//===-- RegisterContextDummy.cpp ---------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +8,6 @@
//
//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -20,118 +19,103 @@
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/DynamicLoader.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextDummy.h"
using namespace lldb;
using namespace lldb_private;
-RegisterContextDummy::RegisterContextDummy (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size) :
-RegisterContext (thread, concrete_frame_idx)
-{
- m_reg_set0.name = "General Purpose Registers";
- m_reg_set0.short_name = "GPR";
- m_reg_set0.num_registers = 1;
- m_reg_set0.registers = new uint32_t(0);
-
- m_pc_reg_info.name = "pc";
- m_pc_reg_info.alt_name = "pc";
- m_pc_reg_info.byte_offset = 0;
- m_pc_reg_info.byte_size = address_byte_size;
- m_pc_reg_info.encoding = eEncodingUint;
- m_pc_reg_info.format = eFormatPointer;
- m_pc_reg_info.invalidate_regs = NULL;
- m_pc_reg_info.value_regs = NULL;
- m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
+RegisterContextDummy::RegisterContextDummy(Thread &thread,
+ uint32_t concrete_frame_idx,
+ uint32_t address_byte_size)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_reg_set0.name = "General Purpose Registers";
+ m_reg_set0.short_name = "GPR";
+ m_reg_set0.num_registers = 1;
+ m_reg_set0.registers = new uint32_t(0);
+
+ m_pc_reg_info.name = "pc";
+ m_pc_reg_info.alt_name = "pc";
+ m_pc_reg_info.byte_offset = 0;
+ m_pc_reg_info.byte_size = address_byte_size;
+ m_pc_reg_info.encoding = eEncodingUint;
+ m_pc_reg_info.format = eFormatPointer;
+ m_pc_reg_info.invalidate_regs = NULL;
+ m_pc_reg_info.value_regs = NULL;
+ m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
}
-RegisterContextDummy::~RegisterContextDummy ()
-{
- delete m_reg_set0.registers;
- delete m_pc_reg_info.invalidate_regs;
- delete m_pc_reg_info.value_regs;
+RegisterContextDummy::~RegisterContextDummy() {
+ delete m_reg_set0.registers;
+ delete m_pc_reg_info.invalidate_regs;
+ delete m_pc_reg_info.value_regs;
}
-void
-RegisterContextDummy::InvalidateAllRegisters () {}
+void RegisterContextDummy::InvalidateAllRegisters() {}
-size_t
-RegisterContextDummy::GetRegisterCount ()
-{
- return 1;
-}
+size_t RegisterContextDummy::GetRegisterCount() { return 1; }
const lldb_private::RegisterInfo *
-RegisterContextDummy::GetRegisterInfoAtIndex (size_t reg)
-{
- if (reg)
- return NULL;
- return &m_pc_reg_info;
+RegisterContextDummy::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg)
+ return NULL;
+ return &m_pc_reg_info;
}
-size_t
-RegisterContextDummy::GetRegisterSetCount ()
-{
- return 1;
-}
+size_t RegisterContextDummy::GetRegisterSetCount() { return 1; }
const lldb_private::RegisterSet *
-RegisterContextDummy::GetRegisterSet (size_t reg_set)
-{
- if (reg_set)
- return NULL;
- return &m_reg_set0;
+RegisterContextDummy::GetRegisterSet(size_t reg_set) {
+ if (reg_set)
+ return NULL;
+ return &m_reg_set0;
}
-bool
-RegisterContextDummy::ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
-{
- if (!reg_info)
- return false;
- uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
- if (reg_number == LLDB_REGNUM_GENERIC_PC)
- {
- value.SetUInt(LLDB_INVALID_ADDRESS, reg_info->byte_size);
- return true;
- }
+bool RegisterContextDummy::ReadRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) {
+ if (!reg_info)
return false;
+ uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_number == LLDB_REGNUM_GENERIC_PC) {
+ value.SetUInt(LLDB_INVALID_ADDRESS, reg_info->byte_size);
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextDummy::WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
-{
- return false;
+bool RegisterContextDummy::WriteRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextDummy::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextDummy::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextDummy::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextDummy::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-uint32_t
-RegisterContextDummy::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
- return 0;
- return LLDB_INVALID_REGNUM;
+uint32_t RegisterContextDummy::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
+ return 0;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.h b/source/Plugins/Process/Utility/RegisterContextDummy.h
index 9f6a8dc347b5..ea70288f3d69 100644
--- a/source/Plugins/Process/Utility/RegisterContextDummy.h
+++ b/source/Plugins/Process/Utility/RegisterContextDummy.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextDummy.h ----------------------------------------*- C++ -*-===//
+//===-- RegisterContextDummy.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,62 +17,53 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class RegisterContextDummy : public lldb_private::RegisterContext
-{
+
+class RegisterContextDummy : public lldb_private::RegisterContext {
public:
- typedef std::shared_ptr<RegisterContextDummy> SharedPtr;
-
- RegisterContextDummy (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size);
-
- ~RegisterContextDummy() override;
+ typedef std::shared_ptr<RegisterContextDummy> SharedPtr;
- void
- InvalidateAllRegisters() override;
+ RegisterContextDummy(Thread &thread, uint32_t concrete_frame_idx,
+ uint32_t address_byte_size);
- size_t
- GetRegisterCount() override;
+ ~RegisterContextDummy() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ size_t GetRegisterSetCount() override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
private:
- //------------------------------------------------------------------
- // For RegisterContextLLDB only
- //------------------------------------------------------------------
-
- lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
- lldb_private::RegisterInfo m_pc_reg_info;
-
- DISALLOW_COPY_AND_ASSIGN (RegisterContextDummy);
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
+ lldb_private::RegisterInfo m_pc_reg_info;
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextDummy);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp
index 588793d5a644..fecfae0b7e66 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp
@@ -7,12 +7,12 @@
//
//===---------------------------------------------------------------------===//
+#include <cassert>
#include <stddef.h>
#include <vector>
-#include <cassert>
-#include "llvm/Support/Compiler.h"
#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
#include "RegisterContextFreeBSD_arm.h"
@@ -21,14 +21,31 @@ using namespace lldb_private;
// Based on RegisterContextLinux_arm.cpp and
// http://svnweb.freebsd.org/base/head/sys/arm/include/reg.h
-#define GPR_OFFSET(idx) ((idx) * 4)
-#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextFreeBSD_arm::GPR))
-#define FPSCR_OFFSET (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm::FPU, fpscr) + sizeof (RegisterContextFreeBSD_arm::GPR))
-#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextFreeBSD_arm::GPR) + sizeof (RegisterContextFreeBSD_arm::FPU))
-#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm::DBG, reg) + sizeof (RegisterContextFreeBSD_arm::GPR) + sizeof (RegisterContextFreeBSD_arm::FPU) + sizeof (RegisterContextFreeBSD_arm::EXC)))
+#define GPR_OFFSET(idx) ((idx)*4)
+#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextFreeBSD_arm::GPR))
+#define FPSCR_OFFSET \
+ (LLVM_EXTENSION offsetof(RegisterContextFreeBSD_arm::FPU, fpscr) + \
+ sizeof(RegisterContextFreeBSD_arm::GPR))
+#define EXC_OFFSET(idx) \
+ ((idx)*4 + sizeof(RegisterContextFreeBSD_arm::GPR) + \
+ sizeof(RegisterContextFreeBSD_arm::FPU))
+#define DBG_OFFSET(reg) \
+ ((LLVM_EXTENSION offsetof(RegisterContextFreeBSD_arm::DBG, reg) + \
+ sizeof(RegisterContextFreeBSD_arm::GPR) + \
+ sizeof(RegisterContextFreeBSD_arm::FPU) + \
+ sizeof(RegisterContextFreeBSD_arm::EXC)))
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextFreeBSD_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextFreeBSD_arm::GPR) + sizeof (RegisterContextFreeBSD_arm::FPU) + sizeof (RegisterContextFreeBSD_arm::EXC))
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, sizeof(((RegisterContextFreeBSD_arm::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ dbg_##reg##i }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextFreeBSD_arm::GPR) + \
+ sizeof(RegisterContextFreeBSD_arm::FPU) + \
+ sizeof(RegisterContextFreeBSD_arm::EXC))
//-----------------------------------------------------------------------------
// Include RegisterInfos_arm to declare our g_register_infos_arm structure.
@@ -38,52 +55,43 @@ using namespace lldb_private;
#undef DECLARE_REGISTER_INFOS_ARM_STRUCT
static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr (const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return g_register_infos_arm;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return g_register_infos_arm;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm) / sizeof(g_register_infos_arm[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return static_cast<uint32_t>(sizeof(g_register_infos_arm) /
+ sizeof(g_register_infos_arm[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextFreeBSD_arm::RegisterContextFreeBSD_arm(const lldb_private::ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
+RegisterContextFreeBSD_arm::RegisterContextFreeBSD_arm(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
-size_t
-RegisterContextFreeBSD_arm::GetGPRSize() const
-{
- return sizeof(struct RegisterContextFreeBSD_arm::GPR);
+size_t RegisterContextFreeBSD_arm::GetGPRSize() const {
+ return sizeof(struct RegisterContextFreeBSD_arm::GPR);
}
const lldb_private::RegisterInfo *
-RegisterContextFreeBSD_arm::GetRegisterInfo() const
-{
- return m_register_info_p;
+RegisterContextFreeBSD_arm::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextFreeBSD_arm::GetRegisterCount() const
-{
- return m_register_info_count;
+uint32_t RegisterContextFreeBSD_arm::GetRegisterCount() const {
+ return m_register_info_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h
index f2d9364b3ce6..422ecb7686dc 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h
@@ -10,65 +10,53 @@
#ifndef liblldb_RegisterContextFreeBSD_arm_h_
#define liblldb_RegisterContextFreeBSD_arm_h_
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextFreeBSD_arm
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_arm : public lldb_private::RegisterInfoInterface {
public:
-
- struct GPR
- {
- uint32_t r[16]; // R0-R15
- uint32_t cpsr; // CPSR
- };
-
-
- struct QReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
- struct EXC
- {
- uint32_t exception;
- uint32_t fsr; /* Fault status */
- uint32_t far; /* Virtual Fault Address */
- };
-
- struct DBG
- {
- uint32_t bvr[16];
- uint32_t bcr[16];
- uint32_t wvr[16];
- uint32_t wcr[16];
- };
-
- RegisterContextFreeBSD_arm(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
+ struct GPR {
+ uint32_t r[16]; // R0-R15
+ uint32_t cpsr; // CPSR
+ };
+
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+ struct EXC {
+ uint32_t exception;
+ uint32_t fsr; /* Fault status */
+ uint32_t far; /* Virtual Fault Address */
+ };
+
+ struct DBG {
+ uint32_t bvr[16];
+ uint32_t bcr[16];
+ uint32_t wvr[16];
+ uint32_t wcr[16];
+ };
+
+ RegisterContextFreeBSD_arm(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
};
-#endif // liblldb_RegisterContextFreeBSD_arm_h_
+#endif // liblldb_RegisterContextFreeBSD_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp
deleted file mode 100644
index 6e7e9e67f524..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-//===-- RegisterContextFreeBSD_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 <vector>
-#include "RegisterContextPOSIX_arm64.h"
-#include "RegisterContextFreeBSD_arm64.h"
-
-using namespace lldb;
-
-// Based on RegisterContextDarwin_arm64.cpp
-#define GPR_OFFSET(idx) ((idx) * 8)
-#define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::GPR, reg))
-
-#define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextFreeBSD_arm64::GPR))
-#define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::FPU, reg))
-
-#define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::EXC, reg) + sizeof (RegisterContextFreeBSD_arm64::GPR) + sizeof (RegisterContextFreeBSD_arm64::FPU))
-#define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::DBG, reg) + sizeof (RegisterContextFreeBSD_arm64::GPR) + sizeof (RegisterContextFreeBSD_arm64::FPU) + sizeof (RegisterContextFreeBSD_arm64::EXC))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextFreeBSD_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextFreeBSD_arm64::GPR) + sizeof (RegisterContextFreeBSD_arm64::FPU) + sizeof (RegisterContextFreeBSD_arm64::EXC))
-
-//-----------------------------------------------------------------------------
-// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
-//-----------------------------------------------------------------------------
-#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
-#include "RegisterInfos_arm64.h"
-#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
-
-static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return g_register_infos_arm64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-}
-
-static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm64) / sizeof(g_register_infos_arm64[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
-}
-
-RegisterContextFreeBSD_arm64::RegisterContextFreeBSD_arm64(const lldb_private::ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
-
-size_t
-RegisterContextFreeBSD_arm64::GetGPRSize() const
-{
- return sizeof(struct RegisterContextFreeBSD_arm64::GPR);
-}
-
-const lldb_private::RegisterInfo *
-RegisterContextFreeBSD_arm64::GetRegisterInfo() const
-{
- return m_register_info_p;
-}
-
-uint32_t
-RegisterContextFreeBSD_arm64::GetRegisterCount() const
-{
- return m_register_info_count;
-}
-
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h
deleted file mode 100644
index cfdae4d2b557..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===-- RegisterContextFreeBSD_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_RegisterContextFreeBSD_arm64_H_
-#define liblldb_RegisterContextFreeBSD_arm64_H_
-
-#include "RegisterInfoInterface.h"
-
-class RegisterContextFreeBSD_arm64:
- public lldb_private::RegisterInfoInterface
-{
-public:
- // based on RegisterContextDarwin_arm64.h
- struct GPR
- {
- uint64_t x[29]; // x0-x28
- uint64_t fp; // x29
- uint64_t lr; // x30
- uint64_t sp; // x31
- uint64_t pc; // pc
- uint32_t cpsr; // cpsr
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct EXC
- {
- uint64_t far; // Virtual Fault Address
- uint32_t esr; // Exception syndrome
- uint32_t exception; // number of arm exception token
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct DBG
- {
- uint64_t bvr[16];
- uint64_t bcr[16];
- uint64_t wvr[16];
- uint64_t wcr[16];
- uint64_t mdscr_el1;
- };
-
- RegisterContextFreeBSD_arm64(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
-
-private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
-};
-
-#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
index 0171da66a199..4ccfa2a16fef 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
@@ -7,55 +7,52 @@
//
//===---------------------------------------------------------------------===//
-#include "RegisterContextPOSIX_x86.h"
#include "RegisterContextFreeBSD_i386.h"
+#include "RegisterContextPOSIX_x86.h"
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h
-struct GPR
-{
- uint32_t fs;
- uint32_t es;
- uint32_t ds;
- uint32_t edi;
- uint32_t esi;
- uint32_t ebp;
- uint32_t isp;
- uint32_t ebx;
- uint32_t edx;
- uint32_t ecx;
- uint32_t eax;
- uint32_t trapno;
- uint32_t err;
- uint32_t eip;
- uint32_t cs;
- uint32_t eflags;
- uint32_t esp;
- uint32_t ss;
- uint32_t gs;
+struct GPR {
+ uint32_t fs;
+ uint32_t es;
+ uint32_t ds;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t isp;
+ uint32_t ebx;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t eax;
+ uint32_t trapno;
+ uint32_t err;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t ss;
+ uint32_t gs;
};
struct dbreg {
- uint32_t dr[8]; /* debug registers */
- /* Index 0-3: debug address registers */
- /* Index 4-5: reserved */
- /* Index 6: debug status */
- /* Index 7: debug control */
+ uint32_t dr[8]; /* debug registers */
+ /* Index 0-3: debug address registers */
+ /* Index 4-5: reserved */
+ /* Index 6: debug status */
+ /* Index 7: debug control */
};
using FPR_i386 = FXSAVE;
-struct UserArea
-{
- GPR gpr;
- FPR_i386 i387;
+struct UserArea {
+ GPR gpr;
+ FPR_i386 i387;
};
#define DR_SIZE sizeof(uint32_t)
-#define DR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(dbreg, dr[reg_index]))
+#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(dbreg, dr[reg_index]))
//---------------------------------------------------------------------------
// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
@@ -64,32 +61,23 @@ struct UserArea
#include "RegisterInfos_i386.h"
#undef DECLARE_REGISTER_INFOS_I386_STRUCT
-RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
-}
+RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
-size_t
-RegisterContextFreeBSD_i386::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextFreeBSD_i386::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextFreeBSD_i386::GetRegisterInfo() const
-{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return g_register_infos_i386;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterInfo *RegisterContextFreeBSD_i386::GetRegisterInfo() const {
+ switch (m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return g_register_infos_i386;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
-uint32_t
-RegisterContextFreeBSD_i386::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
+uint32_t RegisterContextFreeBSD_i386::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
+ sizeof(g_register_infos_i386[0]));
}
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
index 9527fc03f728..35a79c14abfc 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
@@ -12,20 +12,15 @@
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_i386
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_i386 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch);
+ RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
index 53fa4169bffc..c114cfb829f5 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
@@ -7,87 +7,79 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_mips64.h"
#include "RegisterContextFreeBSD_mips64.h"
+#include "RegisterContextPOSIX_mips64.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h
-typedef struct _GPR
-{
- uint64_t zero;
- uint64_t r1;
- uint64_t r2;
- uint64_t r3;
- uint64_t r4;
- uint64_t r5;
- uint64_t r6;
- uint64_t r7;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t r16;
- uint64_t r17;
- uint64_t r18;
- uint64_t r19;
- uint64_t r20;
- uint64_t r21;
- uint64_t r22;
- uint64_t r23;
- uint64_t r24;
- uint64_t r25;
- uint64_t r26;
- uint64_t r27;
- uint64_t gp;
- uint64_t sp;
- uint64_t r30;
- uint64_t ra;
- uint64_t sr;
- uint64_t mullo;
- uint64_t mulhi;
- uint64_t badvaddr;
- uint64_t cause;
- uint64_t pc;
- uint64_t ic;
- uint64_t dummy;
+typedef struct _GPR {
+ uint64_t zero;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t gp;
+ uint64_t sp;
+ uint64_t r30;
+ uint64_t ra;
+ uint64_t sr;
+ uint64_t mullo;
+ uint64_t mulhi;
+ uint64_t badvaddr;
+ uint64_t cause;
+ uint64_t pc;
+ uint64_t ic;
+ uint64_t dummy;
} GPR_freebsd_mips;
//---------------------------------------------------------------------------
-// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 structure.
+// Include RegisterInfos_mips64 to declare our g_register_infos_mips64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
#include "RegisterInfos_mips64.h"
#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
-RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
-}
+RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
-size_t
-RegisterContextFreeBSD_mips64::GetGPRSize() const
-{
- return sizeof(GPR_freebsd_mips);
+size_t RegisterContextFreeBSD_mips64::GetGPRSize() const {
+ return sizeof(GPR_freebsd_mips);
}
-const RegisterInfo *
-RegisterContextFreeBSD_mips64::GetRegisterInfo() const
-{
- assert (m_target_arch.GetCore() == ArchSpec::eCore_mips64);
- return g_register_infos_mips64;
+const RegisterInfo *RegisterContextFreeBSD_mips64::GetRegisterInfo() const {
+ assert(m_target_arch.GetCore() == ArchSpec::eCore_mips64);
+ return g_register_infos_mips64;
}
-uint32_t
-RegisterContextFreeBSD_mips64::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
+uint32_t RegisterContextFreeBSD_mips64::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
+ sizeof(g_register_infos_mips64[0]));
}
-
-
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
index 5c042af20eac..043e638758da 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
@@ -12,20 +12,16 @@
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_mips64:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_mips64
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
index 5133d6088bd3..efa4cc6d8182 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
@@ -7,263 +7,233 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_powerpc.h"
#include "RegisterContextFreeBSD_powerpc.h"
+#include "RegisterContextPOSIX_powerpc.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/powerpc/include/reg.h
-typedef struct _GPR64
-{
- uint64_t r0;
- uint64_t r1;
- uint64_t r2;
- uint64_t r3;
- uint64_t r4;
- uint64_t r5;
- uint64_t r6;
- uint64_t r7;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t r16;
- uint64_t r17;
- uint64_t r18;
- uint64_t r19;
- uint64_t r20;
- uint64_t r21;
- uint64_t r22;
- uint64_t r23;
- uint64_t r24;
- uint64_t r25;
- uint64_t r26;
- uint64_t r27;
- uint64_t r28;
- uint64_t r29;
- uint64_t r30;
- uint64_t r31;
- uint64_t lr;
- uint64_t cr;
- uint64_t xer;
- uint64_t ctr;
- uint64_t pc;
+typedef struct _GPR64 {
+ uint64_t r0;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t r28;
+ uint64_t r29;
+ uint64_t r30;
+ uint64_t r31;
+ uint64_t lr;
+ uint64_t cr;
+ uint64_t xer;
+ uint64_t ctr;
+ uint64_t pc;
} GPR64;
-typedef struct _GPR32
-{
- uint32_t r0;
- uint32_t r1;
- uint32_t r2;
- uint32_t r3;
- uint32_t r4;
- uint32_t r5;
- uint32_t r6;
- uint32_t r7;
- uint32_t r8;
- uint32_t r9;
- uint32_t r10;
- uint32_t r11;
- uint32_t r12;
- uint32_t r13;
- uint32_t r14;
- uint32_t r15;
- uint32_t r16;
- uint32_t r17;
- uint32_t r18;
- uint32_t r19;
- uint32_t r20;
- uint32_t r21;
- uint32_t r22;
- uint32_t r23;
- uint32_t r24;
- uint32_t r25;
- uint32_t r26;
- uint32_t r27;
- uint32_t r28;
- uint32_t r29;
- uint32_t r30;
- uint32_t r31;
- uint32_t lr;
- uint32_t cr;
- uint32_t xer;
- uint32_t ctr;
- uint32_t pc;
+typedef struct _GPR32 {
+ uint32_t r0;
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t r13;
+ uint32_t r14;
+ uint32_t r15;
+ uint32_t r16;
+ uint32_t r17;
+ uint32_t r18;
+ uint32_t r19;
+ uint32_t r20;
+ uint32_t r21;
+ uint32_t r22;
+ uint32_t r23;
+ uint32_t r24;
+ uint32_t r25;
+ uint32_t r26;
+ uint32_t r27;
+ uint32_t r28;
+ uint32_t r29;
+ uint32_t r30;
+ uint32_t r31;
+ uint32_t lr;
+ uint32_t cr;
+ uint32_t xer;
+ uint32_t ctr;
+ uint32_t pc;
} GPR32;
-typedef struct _FPR
-{
- uint64_t f0;
- uint64_t f1;
- uint64_t f2;
- uint64_t f3;
- uint64_t f4;
- uint64_t f5;
- uint64_t f6;
- uint64_t f7;
- uint64_t f8;
- uint64_t f9;
- uint64_t f10;
- uint64_t f11;
- uint64_t f12;
- uint64_t f13;
- uint64_t f14;
- uint64_t f15;
- uint64_t f16;
- uint64_t f17;
- uint64_t f18;
- uint64_t f19;
- uint64_t f20;
- uint64_t f21;
- uint64_t f22;
- uint64_t f23;
- uint64_t f24;
- uint64_t f25;
- uint64_t f26;
- uint64_t f27;
- uint64_t f28;
- uint64_t f29;
- uint64_t f30;
- uint64_t f31;
- uint64_t fpscr;
+typedef struct _FPR {
+ uint64_t f0;
+ uint64_t f1;
+ uint64_t f2;
+ uint64_t f3;
+ uint64_t f4;
+ uint64_t f5;
+ uint64_t f6;
+ uint64_t f7;
+ uint64_t f8;
+ uint64_t f9;
+ uint64_t f10;
+ uint64_t f11;
+ uint64_t f12;
+ uint64_t f13;
+ uint64_t f14;
+ uint64_t f15;
+ uint64_t f16;
+ uint64_t f17;
+ uint64_t f18;
+ uint64_t f19;
+ uint64_t f20;
+ uint64_t f21;
+ uint64_t f22;
+ uint64_t f23;
+ uint64_t f24;
+ uint64_t f25;
+ uint64_t f26;
+ uint64_t f27;
+ uint64_t f28;
+ uint64_t f29;
+ uint64_t f30;
+ uint64_t f31;
+ uint64_t fpscr;
} FPR;
-typedef struct _VMX
-{
- uint32_t v0[4];
- uint32_t v1[4];
- uint32_t v2[4];
- uint32_t v3[4];
- uint32_t v4[4];
- uint32_t v5[4];
- uint32_t v6[4];
- uint32_t v7[4];
- uint32_t v8[4];
- uint32_t v9[4];
- uint32_t v10[4];
- uint32_t v11[4];
- uint32_t v12[4];
- uint32_t v13[4];
- uint32_t v14[4];
- uint32_t v15[4];
- uint32_t v16[4];
- uint32_t v17[4];
- uint32_t v18[4];
- uint32_t v19[4];
- uint32_t v20[4];
- uint32_t v21[4];
- uint32_t v22[4];
- uint32_t v23[4];
- uint32_t v24[4];
- uint32_t v25[4];
- uint32_t v26[4];
- uint32_t v27[4];
- uint32_t v28[4];
- uint32_t v29[4];
- uint32_t v30[4];
- uint32_t v31[4];
- uint32_t pad[2];
- uint32_t vrsave;
- uint32_t vscr;
+typedef struct _VMX {
+ uint32_t v0[4];
+ uint32_t v1[4];
+ uint32_t v2[4];
+ uint32_t v3[4];
+ uint32_t v4[4];
+ uint32_t v5[4];
+ uint32_t v6[4];
+ uint32_t v7[4];
+ uint32_t v8[4];
+ uint32_t v9[4];
+ uint32_t v10[4];
+ uint32_t v11[4];
+ uint32_t v12[4];
+ uint32_t v13[4];
+ uint32_t v14[4];
+ uint32_t v15[4];
+ uint32_t v16[4];
+ uint32_t v17[4];
+ uint32_t v18[4];
+ uint32_t v19[4];
+ uint32_t v20[4];
+ uint32_t v21[4];
+ uint32_t v22[4];
+ uint32_t v23[4];
+ uint32_t v24[4];
+ uint32_t v25[4];
+ uint32_t v26[4];
+ uint32_t v27[4];
+ uint32_t v28[4];
+ uint32_t v29[4];
+ uint32_t v30[4];
+ uint32_t v31[4];
+ uint32_t pad[2];
+ uint32_t vrsave;
+ uint32_t vscr;
} VMX;
//---------------------------------------------------------------------------
-// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
+// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_POWERPC_STRUCT
#include "RegisterInfos_powerpc.h"
#undef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
-RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
-}
+RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
-RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc()
-{
-}
+RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() {}
-size_t
-RegisterContextFreeBSD_powerpc::GetGPRSize() const
-{
- // This is an 'abstract' base, so no GPR struct.
- return 0;
+size_t RegisterContextFreeBSD_powerpc::GetGPRSize() const {
+ // This is an 'abstract' base, so no GPR struct.
+ return 0;
}
-const RegisterInfo *
-RegisterContextFreeBSD_powerpc::GetRegisterInfo() const
-{
- //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
- llvm_unreachable("Abstract class!");
- return NULL;
+const RegisterInfo *RegisterContextFreeBSD_powerpc::GetRegisterInfo() const {
+ // assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+ llvm_unreachable("Abstract class!");
+ return NULL;
}
-uint32_t
-RegisterContextFreeBSD_powerpc::GetRegisterCount () const
-{
- return 0;
-}
+uint32_t RegisterContextFreeBSD_powerpc::GetRegisterCount() const { return 0; }
-RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(const ArchSpec &target_arch) :
- RegisterContextFreeBSD_powerpc(target_arch)
-{
-}
+RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(
+ const ArchSpec &target_arch)
+ : RegisterContextFreeBSD_powerpc(target_arch) {}
-RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32()
-{
-}
+RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() {}
-size_t
-RegisterContextFreeBSD_powerpc32::GetGPRSize() const
-{
- return sizeof(GPR32);
+size_t RegisterContextFreeBSD_powerpc32::GetGPRSize() const {
+ return sizeof(GPR32);
}
-const RegisterInfo *
-RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const
-{
- //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
- return g_register_infos_powerpc32;
+const RegisterInfo *RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const {
+ // assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+ return g_register_infos_powerpc32;
}
-uint32_t
-RegisterContextFreeBSD_powerpc32::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_powerpc32) / sizeof (g_register_infos_powerpc32 [0]));
+uint32_t RegisterContextFreeBSD_powerpc32::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_powerpc32) /
+ sizeof(g_register_infos_powerpc32[0]));
}
-RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(const ArchSpec &target_arch) :
- RegisterContextFreeBSD_powerpc(target_arch)
-{
-}
+RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(
+ const ArchSpec &target_arch)
+ : RegisterContextFreeBSD_powerpc(target_arch) {}
-RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64()
-{
-}
+RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() {}
-size_t
-RegisterContextFreeBSD_powerpc64::GetGPRSize() const
-{
- return sizeof(GPR64);
+size_t RegisterContextFreeBSD_powerpc64::GetGPRSize() const {
+ return sizeof(GPR64);
}
-const RegisterInfo *
-RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const
-{
- //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
- if (m_target_arch.GetMachine() == llvm::Triple::ppc)
- return g_register_infos_powerpc64_32;
- return g_register_infos_powerpc64;
+const RegisterInfo *RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const {
+ // assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+ if (m_target_arch.GetMachine() == llvm::Triple::ppc)
+ return g_register_infos_powerpc64_32;
+ return g_register_infos_powerpc64;
}
-uint32_t
-RegisterContextFreeBSD_powerpc64::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_powerpc64) / sizeof (g_register_infos_powerpc64 [0]));
+uint32_t RegisterContextFreeBSD_powerpc64::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_powerpc64) /
+ sizeof(g_register_infos_powerpc64[0]));
}
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
index 930683f8a870..c9a65b1cacce 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextFreeBSD_powerpc.h -------------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_powerpc.h -------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,55 +17,41 @@
// Project includes
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_powerpc:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_powerpc
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch);
- ~RegisterContextFreeBSD_powerpc() override;
+ RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch);
+ ~RegisterContextFreeBSD_powerpc() override;
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
};
-class RegisterContextFreeBSD_powerpc32:
- public RegisterContextFreeBSD_powerpc
-{
+class RegisterContextFreeBSD_powerpc32 : public RegisterContextFreeBSD_powerpc {
public:
- RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch);
- ~RegisterContextFreeBSD_powerpc32() override;
+ RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch);
+ ~RegisterContextFreeBSD_powerpc32() override;
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
};
-class RegisterContextFreeBSD_powerpc64:
- public RegisterContextFreeBSD_powerpc
-{
+class RegisterContextFreeBSD_powerpc64 : public RegisterContextFreeBSD_powerpc {
public:
- RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch);
- ~RegisterContextFreeBSD_powerpc64() override;
+ RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch);
+ ~RegisterContextFreeBSD_powerpc64() override;
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
};
#endif // liblldb_RegisterContextFreeBSD_powerpc_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
index 34f2d185da8a..4bbbd5c3d0a6 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
@@ -7,158 +7,142 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_x86.h"
-#include "RegisterContextFreeBSD_i386.h"
#include "RegisterContextFreeBSD_x86_64.h"
+#include "RegisterContextFreeBSD_i386.h"
+#include "RegisterContextPOSIX_x86.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h
-typedef struct _GPR
-{
- uint64_t r15;
- uint64_t r14;
- uint64_t r13;
- uint64_t r12;
- uint64_t r11;
- uint64_t r10;
- uint64_t r9;
- uint64_t r8;
- uint64_t rdi;
- uint64_t rsi;
- uint64_t rbp;
- uint64_t rbx;
- uint64_t rdx;
- uint64_t rcx;
- uint64_t rax;
- uint32_t trapno;
- uint16_t fs;
- uint16_t gs;
- uint32_t err;
- uint16_t es;
- uint16_t ds;
- uint64_t rip;
- uint64_t cs;
- uint64_t rflags;
- uint64_t rsp;
- uint64_t ss;
+typedef struct _GPR {
+ uint64_t r15;
+ uint64_t r14;
+ uint64_t r13;
+ uint64_t r12;
+ uint64_t r11;
+ uint64_t r10;
+ uint64_t r9;
+ uint64_t r8;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rbp;
+ uint64_t rbx;
+ uint64_t rdx;
+ uint64_t rcx;
+ uint64_t rax;
+ uint32_t trapno;
+ uint16_t fs;
+ uint16_t gs;
+ uint32_t err;
+ uint16_t es;
+ uint16_t ds;
+ uint64_t rip;
+ uint64_t cs;
+ uint64_t rflags;
+ uint64_t rsp;
+ uint64_t ss;
} GPR;
struct DBG {
- uint64_t dr[16]; /* debug registers */
- /* Index 0-3: debug address registers */
- /* Index 4-5: reserved */
- /* Index 6: debug status */
- /* Index 7: debug control */
- /* Index 8-15: reserved */
+ uint64_t dr[16]; /* debug registers */
+ /* Index 0-3: debug address registers */
+ /* Index 4-5: reserved */
+ /* Index 6: debug status */
+ /* Index 7: debug control */
+ /* Index 8-15: reserved */
};
-struct UserArea
-{
- GPR gpr;
- FPR fpr;
- DBG dbg;
+struct UserArea {
+ GPR gpr;
+ FPR fpr;
+ DBG dbg;
};
-#define DR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
+#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
//---------------------------------------------------------------------------
-// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
+// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_X86_64_STRUCT
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
-static std::vector<lldb_private::RegisterInfo>&
-GetSharedRegisterInfoVector ()
-{
- static std::vector<lldb_private::RegisterInfo> register_infos;
- return register_infos;
+static std::vector<lldb_private::RegisterInfo> &GetSharedRegisterInfoVector() {
+ static std::vector<lldb_private::RegisterInfo> register_infos;
+ return register_infos;
}
static const RegisterInfo *
-GetRegisterInfo_i386(const lldb_private::ArchSpec& arch)
-{
- static std::vector<lldb_private::RegisterInfo> g_register_infos (GetSharedRegisterInfoVector ());
-
- // Allocate RegisterInfo only once
- if (g_register_infos.empty())
- {
- // Copy the register information from base class
- std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface(new RegisterContextFreeBSD_i386 (arch));
- const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
- g_register_infos.insert(g_register_infos.end(), &base_info[0], &base_info[k_num_registers_i386]);
-
- //---------------------------------------------------------------------------
- // Include RegisterInfos_x86_64 to update the g_register_infos structure
- // with x86_64 offsets.
- //---------------------------------------------------------------------------
- #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- #include "RegisterInfos_x86_64.h"
- #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- }
-
- return &g_register_infos[0];
+GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
+ static std::vector<lldb_private::RegisterInfo> g_register_infos(
+ GetSharedRegisterInfoVector());
+
+ // Allocate RegisterInfo only once
+ if (g_register_infos.empty()) {
+ // Copy the register information from base class
+ std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface(
+ new RegisterContextFreeBSD_i386(arch));
+ const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+ g_register_infos.insert(g_register_infos.end(), &base_info[0],
+ &base_info[k_num_registers_i386]);
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_x86_64 to update the g_register_infos structure
+// with x86_64 offsets.
+//---------------------------------------------------------------------------
+#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+#include "RegisterInfos_x86_64.h"
+#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+ }
+
+ return &g_register_infos[0];
}
static const RegisterInfo *
-PrivateGetRegisterInfoPtr (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return GetRegisterInfo_i386 (target_arch);
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return GetRegisterInfo_i386(target_arch);
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
static uint32_t
-PrivateGetRegisterCount (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- // This vector should have already been filled.
- assert (!GetSharedRegisterInfoVector ().empty () && "i386 register info vector not filled.");
- return static_cast<uint32_t> (GetSharedRegisterInfoVector().size ());
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ // This vector should have already been filled.
+ assert(!GetSharedRegisterInfoVector().empty() &&
+ "i386 register info vector not filled.");
+ return static_cast<uint32_t>(GetSharedRegisterInfoVector().size());
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (PrivateGetRegisterInfoPtr (target_arch)),
- m_register_count (PrivateGetRegisterCount (target_arch))
-{
-}
+RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),
+ m_register_count(PrivateGetRegisterCount(target_arch)) {}
-size_t
-RegisterContextFreeBSD_x86_64::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextFreeBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextFreeBSD_x86_64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextFreeBSD_x86_64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextFreeBSD_x86_64::GetRegisterCount () const
-{
- return m_register_count;
+uint32_t RegisterContextFreeBSD_x86_64::GetRegisterCount() const {
+ return m_register_count;
}
-
-
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
index e739fa50ed6c..dc30f1783b41 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
@@ -12,24 +12,20 @@
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_x86_64:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_x86_64
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- const uint32_t m_register_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ const uint32_t m_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
index 9d2181376e09..0fc47fcd8e3a 100644
--- a/source/Plugins/Process/Utility/RegisterContextHistory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextHistory.cpp ---------------------------------*- C++ -*-===//
+//===-- RegisterContextHistory.cpp ---------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +8,6 @@
//
//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -20,119 +19,105 @@
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/DynamicLoader.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextHistory.h"
using namespace lldb;
using namespace lldb_private;
-RegisterContextHistory::RegisterContextHistory (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size, addr_t pc_value) :
-RegisterContext (thread, concrete_frame_idx),
- m_pc_value (pc_value)
-{
- m_reg_set0.name = "General Purpose Registers";
- m_reg_set0.short_name = "GPR";
- m_reg_set0.num_registers = 1;
- m_reg_set0.registers = new uint32_t(0);
-
- m_pc_reg_info.name = "pc";
- m_pc_reg_info.alt_name = "pc";
- m_pc_reg_info.byte_offset = 0;
- m_pc_reg_info.byte_size = address_byte_size;
- m_pc_reg_info.encoding = eEncodingUint;
- m_pc_reg_info.format = eFormatPointer;
- m_pc_reg_info.invalidate_regs = NULL;
- m_pc_reg_info.value_regs = NULL;
- m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
+RegisterContextHistory::RegisterContextHistory(Thread &thread,
+ uint32_t concrete_frame_idx,
+ uint32_t address_byte_size,
+ addr_t pc_value)
+ : RegisterContext(thread, concrete_frame_idx), m_pc_value(pc_value) {
+ m_reg_set0.name = "General Purpose Registers";
+ m_reg_set0.short_name = "GPR";
+ m_reg_set0.num_registers = 1;
+ m_reg_set0.registers = new uint32_t(0);
+
+ m_pc_reg_info.name = "pc";
+ m_pc_reg_info.alt_name = "pc";
+ m_pc_reg_info.byte_offset = 0;
+ m_pc_reg_info.byte_size = address_byte_size;
+ m_pc_reg_info.encoding = eEncodingUint;
+ m_pc_reg_info.format = eFormatPointer;
+ m_pc_reg_info.invalidate_regs = NULL;
+ m_pc_reg_info.value_regs = NULL;
+ m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
}
-RegisterContextHistory::~RegisterContextHistory ()
-{
- delete m_reg_set0.registers;
- delete m_pc_reg_info.invalidate_regs;
- delete m_pc_reg_info.value_regs;
+RegisterContextHistory::~RegisterContextHistory() {
+ delete m_reg_set0.registers;
+ delete m_pc_reg_info.invalidate_regs;
+ delete m_pc_reg_info.value_regs;
}
-void
-RegisterContextHistory::InvalidateAllRegisters () {}
+void RegisterContextHistory::InvalidateAllRegisters() {}
-size_t
-RegisterContextHistory::GetRegisterCount ()
-{
- return 1;
-}
+size_t RegisterContextHistory::GetRegisterCount() { return 1; }
const lldb_private::RegisterInfo *
-RegisterContextHistory::GetRegisterInfoAtIndex (size_t reg)
-{
- if (reg)
- return NULL;
- return &m_pc_reg_info;
+RegisterContextHistory::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg)
+ return NULL;
+ return &m_pc_reg_info;
}
-size_t
-RegisterContextHistory::GetRegisterSetCount ()
-{
- return 1;
-}
+size_t RegisterContextHistory::GetRegisterSetCount() { return 1; }
const lldb_private::RegisterSet *
-RegisterContextHistory::GetRegisterSet (size_t reg_set)
-{
- if (reg_set)
- return NULL;
- return &m_reg_set0;
+RegisterContextHistory::GetRegisterSet(size_t reg_set) {
+ if (reg_set)
+ return NULL;
+ return &m_reg_set0;
}
-bool
-RegisterContextHistory::ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
-{
- if (!reg_info)
- return false;
- uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
- if (reg_number == LLDB_REGNUM_GENERIC_PC)
- {
- value.SetUInt(m_pc_value, reg_info->byte_size);
- return true;
- }
+bool RegisterContextHistory::ReadRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) {
+ if (!reg_info)
return false;
+ uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_number == LLDB_REGNUM_GENERIC_PC) {
+ value.SetUInt(m_pc_value, reg_info->byte_size);
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextHistory::WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
-{
- return false;
+bool RegisterContextHistory::WriteRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextHistory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextHistory::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextHistory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextHistory::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-uint32_t
-RegisterContextHistory::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
- return 0;
- return LLDB_INVALID_REGNUM;
+uint32_t RegisterContextHistory::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
+ return 0;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.h b/source/Plugins/Process/Utility/RegisterContextHistory.h
index 3f44a1fde68b..acaf8fe5c04a 100644
--- a/source/Plugins/Process/Utility/RegisterContextHistory.h
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextHistory.h ----------------------------------------*- C++ -*-===//
+//===-- RegisterContextHistory.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,64 +17,55 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class RegisterContextHistory : public lldb_private::RegisterContext
-{
+
+class RegisterContextHistory : public lldb_private::RegisterContext {
public:
- typedef std::shared_ptr<RegisterContextHistory> SharedPtr;
-
- RegisterContextHistory (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size, lldb::addr_t pc_value);
-
- ~RegisterContextHistory() override;
+ typedef std::shared_ptr<RegisterContextHistory> SharedPtr;
+
+ RegisterContextHistory(Thread &thread, uint32_t concrete_frame_idx,
+ uint32_t address_byte_size, lldb::addr_t pc_value);
- void
- InvalidateAllRegisters() override;
+ ~RegisterContextHistory() override;
- size_t
- GetRegisterCount() override;
+ void InvalidateAllRegisters() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ size_t GetRegisterCount() override;
- size_t
- GetRegisterSetCount() override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ size_t GetRegisterSetCount() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
private:
- //------------------------------------------------------------------
- // For RegisterContextLLDB only
- //------------------------------------------------------------------
-
- lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
- lldb_private::RegisterInfo m_pc_reg_info;
-
- lldb::addr_t m_pc_value;
-
- DISALLOW_COPY_AND_ASSIGN (RegisterContextHistory);
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
+ lldb_private::RegisterInfo m_pc_reg_info;
+
+ lldb::addr_t m_pc_value;
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextHistory);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 8bbaeb8e9a59..3c33ddb335d6 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -33,1829 +31,1824 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextLLDB.h"
using namespace lldb;
using namespace lldb_private;
-static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx)
-{
- if (sym_ctx.symbol)
- return sym_ctx.symbol->GetName();
- else if (sym_ctx.function)
- return sym_ctx.function->GetName();
- return ConstString();
+static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) {
+ if (sym_ctx.symbol)
+ return sym_ctx.symbol->GetName();
+ else if (sym_ctx.function)
+ return sym_ctx.function->GetName();
+ return ConstString();
}
-RegisterContextLLDB::RegisterContextLLDB
-(
- Thread& thread,
- const SharedPtr &next_frame,
- SymbolContext& sym_ctx,
- uint32_t frame_number,
- UnwindLLDB& unwind_lldb
-) :
- 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_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)
-{
- m_sym_ctx.Clear(false);
- m_sym_ctx_valid = false;
-
- if (IsFrameZero ())
- {
- InitializeZerothFrame ();
- }
- else
- {
- InitializeNonZerothFrame ();
- }
-
- // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
- if (IsFrameZero()
- || next_frame->m_frame_type == eTrapHandlerFrame
- || next_frame->m_frame_type == eDebuggerFrame)
- {
- m_all_registers_available = true;
- }
+RegisterContextLLDB::RegisterContextLLDB(Thread &thread,
+ const SharedPtr &next_frame,
+ SymbolContext &sym_ctx,
+ uint32_t frame_number,
+ UnwindLLDB &unwind_lldb)
+ : 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_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) {
+ m_sym_ctx.Clear(false);
+ m_sym_ctx_valid = false;
+
+ if (IsFrameZero()) {
+ InitializeZerothFrame();
+ } else {
+ InitializeNonZerothFrame();
+ }
+
+ // This same code exists over in the GetFullUnwindPlanForFrame() but it may
+ // not have been executed yet
+ if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame ||
+ next_frame->m_frame_type == eDebuggerFrame) {
+ m_all_registers_available = true;
+ }
}
-bool
-RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset)
-{
- if (!unwind_plan_sp)
- return false;
+bool RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(
+ lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) {
+ if (!unwind_plan_sp)
+ return false;
- // check if m_current_pc is valid
- if (unwind_plan_sp->PlanValidAtAddress(m_current_pc))
- {
- // yes - current offset can be used as is
- valid_pc_offset = m_current_offset;
- return true;
- }
+ // check if m_current_pc is valid
+ if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ // yes - current offset can be used as is
+ valid_pc_offset = m_current_offset;
+ return true;
+ }
- // if m_current_offset <= 0, we've got nothing else to try
- if (m_current_offset <= 0)
- return false;
+ // if m_current_offset <= 0, we've got nothing else to try
+ if (m_current_offset <= 0)
+ return false;
- // check pc - 1 to see if it's valid
- Address pc_minus_one (m_current_pc);
- pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1);
- if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one))
- {
- // *valid_pc_offset = m_current_offset - 1;
- valid_pc_offset = m_current_pc.GetOffset() - 1;
- return true;
- }
+ // check pc - 1 to see if it's valid
+ Address pc_minus_one(m_current_pc);
+ pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1);
+ if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) {
+ // *valid_pc_offset = m_current_offset - 1;
+ valid_pc_offset = m_current_pc.GetOffset() - 1;
+ return true;
+ }
- return false;
+ return false;
}
-// Initialize a RegisterContextLLDB which is the first frame of a stack -- the zeroth frame or currently
+// Initialize a RegisterContextLLDB which is the first frame of a stack -- the
+// zeroth frame or currently
// executing frame.
-void
-RegisterContextLLDB::InitializeZerothFrame()
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
-
- if (reg_ctx_sp.get() == NULL)
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("frame does not have a register context");
- return;
- }
-
- addr_t current_pc = reg_ctx_sp->GetPC();
+void RegisterContextLLDB::InitializeZerothFrame() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
- if (current_pc == LLDB_INVALID_ADDRESS)
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("frame does not have a pc");
- return;
- }
-
- Process *process = exe_ctx.GetProcessPtr();
-
- // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
- // this will strip bit zero in case we read a PC from memory or from the LR.
- // (which would be a no-op in frame 0 where we get it from the register set,
- // but still a good idea to make the call here for other ABIs that may exist.)
- ABI *abi = process->GetABI().get();
- if (abi)
- current_pc = abi->FixCodeAddress(current_pc);
-
- // Initialize m_current_pc, an Address object, based on current_pc, an addr_t.
- m_current_pc.SetLoadAddress (current_pc, &process->GetTarget());
-
- // If we don't have a Module for some reason, we're not going to find symbol/function information - just
- // stick in some reasonable defaults and hope we can unwind past this frame.
- ModuleSP pc_module_sp (m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp)
- {
- UnwindLogMsg ("using architectural default unwind method");
- }
+ if (reg_ctx_sp.get() == NULL) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("frame does not have a register context");
+ return;
+ }
- // 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;
- if (pc_module_sp.get()
- && (pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, m_sym_ctx) & resolve_scope))
- {
- m_sym_ctx_valid = true;
- }
+ addr_t current_pc = reg_ctx_sp->GetPC();
- if (m_sym_ctx.symbol)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
- current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else if (m_sym_ctx.function)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'",
- current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", current_pc);
- }
-
- AddressRange addr_range;
- m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range);
+ if (current_pc == LLDB_INVALID_ADDRESS) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("frame does not have a pc");
+ return;
+ }
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
+ // this will strip bit zero in case we read a PC from memory or from the LR.
+ // (which would be a no-op in frame 0 where we get it from the register set,
+ // but still a good idea to make the call here for other ABIs that may exist.)
+ ABI *abi = process->GetABI().get();
+ if (abi)
+ current_pc = abi->FixCodeAddress(current_pc);
+
+ // Initialize m_current_pc, an Address object, based on current_pc, an addr_t.
+ m_current_pc.SetLoadAddress(current_pc, &process->GetTarget());
+
+ // If we don't have a Module for some reason, we're not going to find
+ // symbol/function information - just
+ // stick in some reasonable defaults and hope we can unwind past this frame.
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
+ if (!m_current_pc.IsValid() || !pc_module_sp) {
+ UnwindLogMsg("using architectural default unwind method");
+ }
+
+ // We require either a symbol or function in the symbols context to be
+ // successfully
+ // filled in or this context is of no use to us.
+ const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress(
+ m_current_pc, resolve_scope, m_sym_ctx) &
+ resolve_scope)) {
+ m_sym_ctx_valid = true;
+ }
+
+ if (m_sym_ctx.symbol) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
+ current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else if (m_sym_ctx.function) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'",
+ current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else {
+ UnwindLogMsg("with pc value of 0x%" PRIx64
+ ", no symbol/function name is known.",
+ current_pc);
+ }
+
+ AddressRange addr_range;
+ m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range);
+
+ if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
+ m_frame_type = eTrapHandlerFrame;
+ } else {
+ // FIXME: Detect eDebuggerFrame here.
+ m_frame_type = eNormalFrame;
+ }
+
+ // If we were able to find a symbol/function, set addr_range to the bounds of
+ // that symbol/function.
+ // else treat the current pc value as the start_pc and record no offset.
+ if (addr_range.GetBaseAddress().IsValid()) {
+ m_start_pc = addr_range.GetBaseAddress();
+ if (m_current_pc.GetSection() == m_start_pc.GetSection()) {
+ m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
+ } else if (m_current_pc.GetModule() == m_start_pc.GetModule()) {
+ // This means that whatever symbol we kicked up isn't really correct
+ // --- we should not cross section boundaries ... We really should NULL
+ // out
+ // the function/symbol in this case unless there is a bad assumption
+ // here due to inlined functions?
+ m_current_offset =
+ m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
+ }
+ m_current_offset_backed_up_one = m_current_offset;
+ } else {
+ m_start_pc = m_current_pc;
+ m_current_offset = -1;
+ m_current_offset_backed_up_one = -1;
+ }
+
+ // We've set m_frame_type and m_sym_ctx before these calls.
+
+ m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
+ m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
+
+ UnwindPlan::RowSP active_row;
+ lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
+ if (m_full_unwind_plan_sp &&
+ m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ active_row =
+ m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
+ if (active_row.get() && log) {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread,
+ m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
+ UnwindLogMsg("%s", active_row_strm.GetData());
+ }
+ }
+
+ if (!active_row.get()) {
+ UnwindLogMsg("could not find an unwindplan row for this frame's pc");
+ m_frame_type = eNotAValidFrame;
+ return;
+ }
- if (IsTrapHandlerSymbol (process, m_sym_ctx))
- {
- m_frame_type = eTrapHandlerFrame;
- }
- else
- {
- // FIXME: Detect eDebuggerFrame here.
- m_frame_type = eNormalFrame;
- }
+ if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) {
+ // Try the fall back unwind plan since the
+ // full unwind plan failed.
+ FuncUnwindersSP func_unwinders_sp;
+ UnwindPlanSP call_site_unwind_plan;
+ bool cfa_status = false;
- // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function.
- // else treat the current pc value as the start_pc and record no offset.
- if (addr_range.GetBaseAddress().IsValid())
- {
- m_start_pc = addr_range.GetBaseAddress();
- if (m_current_pc.GetSection() == m_start_pc.GetSection())
- {
- m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
- }
- else if (m_current_pc.GetModule() == m_start_pc.GetModule())
- {
- // This means that whatever symbol we kicked up isn't really correct
- // --- we should not cross section boundaries ... We really should NULL out
- // the function/symbol in this case unless there is a bad assumption
- // here due to inlined functions?
- m_current_offset = m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
- }
- m_current_offset_backed_up_one = m_current_offset;
- }
- else
- {
- m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
+ if (m_sym_ctx_valid) {
+ func_unwinders_sp =
+ pc_module_sp->GetObjectFile()
+ ->GetUnwindTable()
+ .GetFuncUnwindersContainingAddress(m_current_pc, m_sym_ctx);
}
- // We've set m_frame_type and m_sym_ctx before these calls.
+ if (func_unwinders_sp.get() != nullptr)
+ call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
- m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
-
- UnwindPlan::RowSP active_row;
- lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
- if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
- if (active_row.get() && log)
- {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg ("%s", active_row_strm.GetString().c_str());
- }
+ if (call_site_unwind_plan.get() != nullptr) {
+ m_fallback_unwind_plan_sp = call_site_unwind_plan;
+ if (TryFallbackUnwindPlan())
+ cfa_status = true;
}
-
- if (!active_row.get())
- {
- UnwindLogMsg ("could not find an unwindplan row for this frame's pc");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
-
- if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
- {
- // Try the fall back unwind plan since the
- // full unwind plan failed.
- FuncUnwindersSP func_unwinders_sp;
- UnwindPlanSP call_site_unwind_plan;
- bool cfa_status = false;
-
- if (m_sym_ctx_valid)
- {
- func_unwinders_sp = pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
- }
-
- if(func_unwinders_sp.get() != nullptr)
- call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
-
- if (call_site_unwind_plan.get() != nullptr)
- {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- if(TryFallbackUnwindPlan())
- cfa_status = true;
- }
- if (!cfa_status)
- {
- UnwindLogMsg ("could not read CFA value for first frame.");
- m_frame_type = eNotAValidFrame;
- return;
- }
+ if (!cfa_status) {
+ UnwindLogMsg("could not read CFA value for first frame.");
+ m_frame_type = eNotAValidFrame;
+ return;
}
+ }
- UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 " using %s UnwindPlan",
- (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()),
- (uint64_t) m_cfa,
- m_full_unwind_plan_sp->GetSourceName().GetCString());
+ UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64
+ " using %s UnwindPlan",
+ (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
+ (uint64_t)m_cfa,
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
}
-// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the RegisterContextLLDB "below" it
+// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the
+// RegisterContextLLDB "below" it
// to provide things like its current pc value.
-void
-RegisterContextLLDB::InitializeNonZerothFrame()
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (IsFrameZero ())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("non-zeroth frame tests positive for IsFrameZero -- that shouldn't happen.");
- return;
- }
-
- if (!GetNextFrame().get() || !GetNextFrame()->IsValid())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("Could not get next frame, marking this frame as invalid.");
- return;
- }
- if (!m_thread.GetRegisterContext())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("Could not get register context for this thread, marking this frame as invalid.");
- return;
- }
+void RegisterContextLLDB::InitializeNonZerothFrame() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (IsFrameZero()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that "
+ "shouldn't happen.");
+ return;
+ }
- addr_t pc;
- if (!ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc))
- {
- UnwindLogMsg ("could not get pc value");
+ if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("Could not get next frame, marking this frame as invalid.");
+ return;
+ }
+ if (!m_thread.GetRegisterContext()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("Could not get register context for this thread, marking this "
+ "frame as invalid.");
+ return;
+ }
+
+ addr_t pc;
+ if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
+ UnwindLogMsg("could not get pc value");
+ m_frame_type = eNotAValidFrame;
+ return;
+ }
+
+ if (log) {
+ UnwindLogMsg("pc = 0x%" PRIx64, pc);
+ addr_t reg_val;
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
+ UnwindLogMsg("fp = 0x%" PRIx64, reg_val);
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
+ UnwindLogMsg("sp = 0x%" PRIx64, reg_val);
+ }
+
+ // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
+ // handler function
+ bool above_trap_handler = false;
+ if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
+ GetNextFrame()->IsTrapHandlerFrame())
+ above_trap_handler = true;
+
+ if (pc == 0 || pc == 0x1) {
+ if (above_trap_handler == false) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("this frame has a pc of 0x0");
+ return;
+ }
+ }
+
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
+ // this will strip bit zero in case we read a PC from memory or from the LR.
+ ABI *abi = process->GetABI().get();
+ if (abi)
+ pc = abi->FixCodeAddress(pc);
+
+ m_current_pc.SetLoadAddress(pc, &process->GetTarget());
+
+ // If we don't have a Module for some reason, we're not going to find
+ // symbol/function information - just
+ // stick in some reasonable defaults and hope we can unwind past this frame.
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
+ if (!m_current_pc.IsValid() || !pc_module_sp) {
+ UnwindLogMsg("using architectural default unwind method");
+
+ // Test the pc value to see if we know it's in an unmapped/non-executable
+ // region of memory.
+ uint32_t permissions;
+ if (process->GetLoadAddressPermissions(pc, permissions) &&
+ (permissions & ePermissionsExecutable) == 0) {
+ // If this is the second frame off the stack, we may have unwound the
+ // first frame
+ // incorrectly. But using the architecture default unwind plan may get us
+ // back on
+ // track -- albeit possibly skipping a real frame. Give this frame a
+ // clearly-invalid
+ // pc and see if we can get any further.
+ if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
+ GetNextFrame()->IsFrameZero()) {
+ UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable "
+ "memory but on frame 1 -- "
+ "allowing it once.",
+ (uint64_t)pc);
+ m_frame_type = eSkipFrame;
+ } else {
+ // anywhere other than the second frame, a non-executable pc means we're
+ // off in the weeds -- stop now.
m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("pc is in a non-executable section of memory and this "
+ "isn't the 2nd frame in the stack walk.");
return;
+ }
}
- if (log)
- {
- UnwindLogMsg ("pc = 0x%" PRIx64, pc);
- addr_t reg_val;
- if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
- UnwindLogMsg ("fp = 0x%" PRIx64, reg_val);
- if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
- UnwindLogMsg ("sp = 0x%" PRIx64, reg_val);
- }
-
- // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap handler function
- bool above_trap_handler = false;
- if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame())
- above_trap_handler = true;
-
- if (pc == 0 || pc == 0x1)
- {
- if (above_trap_handler == false)
- {
+ if (abi) {
+ m_fast_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
+ if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+ {
+ m_frame_type = eNormalFrame;
+ }
+ m_all_registers_available = false;
+ m_current_offset = -1;
+ m_current_offset_backed_up_one = -1;
+ 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)) {
+ UnwindLogMsg("failed to get cfa value");
+ if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+ {
m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("this frame has a pc of 0x0");
- return;
+ }
+ return;
}
- }
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
- // this will strip bit zero in case we read a PC from memory or from the LR.
- ABI *abi = process->GetABI().get();
- if (abi)
- pc = abi->FixCodeAddress(pc);
-
- m_current_pc.SetLoadAddress (pc, &process->GetTarget());
-
- // If we don't have a Module for some reason, we're not going to find symbol/function information - just
- // stick in some reasonable defaults and hope we can unwind past this frame.
- ModuleSP pc_module_sp (m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp)
- {
- UnwindLogMsg ("using architectural default unwind method");
-
- // Test the pc value to see if we know it's in an unmapped/non-executable region of memory.
- uint32_t permissions;
- if (process->GetLoadAddressPermissions(pc, permissions)
- && (permissions & ePermissionsExecutable) == 0)
- {
- // If this is the second frame off the stack, we may have unwound the first frame
- // incorrectly. But using the architecture default unwind plan may get us back on
- // track -- albeit possibly skipping a real frame. Give this frame a clearly-invalid
- // pc and see if we can get any further.
- if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsFrameZero())
- {
- UnwindLogMsg ("had a pc of 0x%" PRIx64 " which is not in executable memory but on frame 1 -- allowing it once.",
- (uint64_t) pc);
- m_frame_type = eSkipFrame;
- }
- else
- {
- // anywhere other than the second frame, a non-executable pc means we're off in the weeds -- stop now.
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("pc is in a non-executable section of memory and this isn't the 2nd frame in the stack walk.");
- return;
- }
+ // 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");
+ m_frame_type = eNotAValidFrame;
+ return;
}
- if (abi)
- {
- m_fast_unwind_plan_sp.reset ();
- m_full_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNormalFrame;
- }
- m_all_registers_available = false;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
- 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))
- {
- UnwindLogMsg ("failed to get cfa value");
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNotAValidFrame;
- }
- return;
- }
-
- // 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");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- // m_cfa should point into the stack memory; if we can query memory region permissions,
- // see if the memory is allocated & readable.
- if (process->GetLoadAddressPermissions(m_cfa, permissions)
- && (permissions & ePermissionsReadable) == 0)
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("the CFA points to a region of memory that is not readable");
- return;
- }
- }
- else
- {
- UnwindLogMsg ("could not find a row for function offset zero");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- if (CheckIfLoopingStack ())
- {
- TryFallbackUnwindPlan();
- if (CheckIfLoopingStack ())
- {
- UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping");
- m_frame_type = eNotAValidFrame;
- return;
- }
- }
-
- UnwindLogMsg ("initialized frame cfa is 0x%" PRIx64, (uint64_t) m_cfa);
- return;
+ // m_cfa should point into the stack memory; if we can query memory
+ // region permissions,
+ // see if the memory is allocated & readable.
+ if (process->GetLoadAddressPermissions(m_cfa, permissions) &&
+ (permissions & ePermissionsReadable) == 0) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg(
+ "the CFA points to a region of memory that is not readable");
+ return;
}
+ } else {
+ UnwindLogMsg("could not find a row for function offset zero");
m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("could not find any symbol for this pc, or a default unwind plan, to continue unwind.");
return;
- }
-
- bool resolve_tail_call_address = false; // m_current_pc can be one past the address range of the function...
- // If the saved pc does not point to a function/symbol because it is
- // beyond the bounds of the correct function and there's no symbol there,
- // we do *not* want ResolveSymbolContextForAddress to back up the pc by 1,
- // because then we might not find the correct unwind information later.
- // Instead, let ResolveSymbolContextForAddress fail, and handle the case
- // via decr_pc_and_recompute_addr_range below.
- const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
- uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc,
- resolve_scope,
- m_sym_ctx, resolve_tail_call_address);
-
- // We require either a symbol or function in the symbols context to be successfully
- // filled in or this context is of no use to us.
- if (resolve_scope & resolved_scope)
- {
- m_sym_ctx_valid = true;
- }
-
- if (m_sym_ctx.symbol)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
- pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else if (m_sym_ctx.function)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'",
- pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", pc);
- }
+ }
- AddressRange addr_range;
- if (!m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range))
- {
- m_sym_ctx_valid = false;
- }
-
- bool decr_pc_and_recompute_addr_range = false;
-
- // If the symbol lookup failed...
- if (m_sym_ctx_valid == false)
- decr_pc_and_recompute_addr_range = true;
-
- // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp),
- // and our "current" pc is the start of a function...
- if (m_sym_ctx_valid
- && GetNextFrame()->m_frame_type != eTrapHandlerFrame
- && GetNextFrame()->m_frame_type != eDebuggerFrame
- && addr_range.GetBaseAddress().IsValid()
- && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection()
- && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset())
- {
- decr_pc_and_recompute_addr_range = true;
- }
-
- // We need to back up the pc by 1 byte and re-search for the Symbol to handle the case where the "saved pc"
- // value is pointing to the next function, e.g. if a function ends with a CALL instruction.
- // FIXME this may need to be an architectural-dependent behavior; if so we'll need to add a member function
- // to the ABI plugin and consult that.
- if (decr_pc_and_recompute_addr_range)
- {
- UnwindLogMsg ("Backing up the pc value of 0x%" PRIx64 " by 1 and re-doing symbol lookup; old symbol was %s",
- pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- Address temporary_pc;
- temporary_pc.SetLoadAddress (pc - 1, &process->GetTarget());
- m_sym_ctx.Clear (false);
- m_sym_ctx_valid = false;
- uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
-
- ModuleSP temporary_module_sp = temporary_pc.GetModule();
- if (temporary_module_sp &&
- temporary_module_sp->ResolveSymbolContextForAddress (temporary_pc, resolve_scope, m_sym_ctx) & resolve_scope)
- {
- if (m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range))
- m_sym_ctx_valid = true;
- }
- UnwindLogMsg ("Symbol is now %s", GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
-
- // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function.
- // else treat the current pc value as the start_pc and record no offset.
- if (addr_range.GetBaseAddress().IsValid())
- {
- m_start_pc = addr_range.GetBaseAddress();
- m_current_offset = pc - m_start_pc.GetLoadAddress (&process->GetTarget());
- m_current_offset_backed_up_one = m_current_offset;
- if (decr_pc_and_recompute_addr_range && m_current_offset_backed_up_one > 0)
- {
- m_current_offset_backed_up_one--;
- if (m_sym_ctx_valid)
- {
- m_current_pc.SetLoadAddress (pc - 1, &process->GetTarget());
- }
- }
- }
- else
- {
- m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
- }
-
- if (IsTrapHandlerSymbol (process, m_sym_ctx))
- {
- m_frame_type = eTrapHandlerFrame;
- }
- else
- {
- // FIXME: Detect eDebuggerFrame here.
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNormalFrame;
+ if (CheckIfLoopingStack()) {
+ TryFallbackUnwindPlan();
+ if (CheckIfLoopingStack()) {
+ UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
+ "looping - stopping");
+ m_frame_type = eNotAValidFrame;
+ return;
}
- }
-
- // We've set m_frame_type and m_sym_ctx before this call.
- m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
+ }
- UnwindPlan::RowSP active_row;
- RegisterKind row_register_kind = eRegisterKindGeneric;
-
- // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get
- // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.)
-
- if (m_fast_unwind_plan_sp && m_fast_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind ();
- if (active_row.get() && log)
- {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
- }
- }
- else
- {
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset))
- {
- active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (valid_offset);
- row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
- if (active_row.get() && log)
- {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
- }
- }
+ UnwindLogMsg("initialized frame cfa is 0x%" PRIx64, (uint64_t)m_cfa);
+ return;
}
-
- if (!active_row.get())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("could not find unwind row for this pc");
- return;
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("could not find any symbol for this pc, or a default unwind "
+ "plan, to continue unwind.");
+ return;
+ }
+
+ bool resolve_tail_call_address = false; // m_current_pc can be one past the
+ // address range of the function...
+ // If the saved pc does not point to a function/symbol because it is
+ // beyond the bounds of the correct function and there's no symbol there,
+ // we do *not* want ResolveSymbolContextForAddress to back up the pc by 1,
+ // because then we might not find the correct unwind information later.
+ // Instead, let ResolveSymbolContextForAddress fail, and handle the case
+ // via decr_pc_and_recompute_addr_range below.
+ const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress(
+ m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address);
+
+ // We require either a symbol or function in the symbols context to be
+ // successfully
+ // filled in or this context is of no use to us.
+ if (resolve_scope & resolved_scope) {
+ m_sym_ctx_valid = true;
+ }
+
+ if (m_sym_ctx.symbol) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc,
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else if (m_sym_ctx.function) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", pc,
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else {
+ UnwindLogMsg("with pc value of 0x%" PRIx64
+ ", no symbol/function name is known.",
+ pc);
+ }
+
+ AddressRange addr_range;
+ if (!m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range)) {
+ m_sym_ctx_valid = false;
+ }
+
+ bool decr_pc_and_recompute_addr_range = false;
+
+ // If the symbol lookup failed...
+ if (m_sym_ctx_valid == false)
+ decr_pc_and_recompute_addr_range = true;
+
+ // Or if we're in the middle of the stack (and not "above" an asynchronous
+ // event like sigtramp),
+ // and our "current" pc is the start of a function...
+ if (m_sym_ctx_valid && GetNextFrame()->m_frame_type != eTrapHandlerFrame &&
+ GetNextFrame()->m_frame_type != eDebuggerFrame &&
+ addr_range.GetBaseAddress().IsValid() &&
+ addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() &&
+ addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()) {
+ decr_pc_and_recompute_addr_range = true;
+ }
+
+ // We need to back up the pc by 1 byte and re-search for the Symbol to handle
+ // the case where the "saved pc"
+ // value is pointing to the next function, e.g. if a function ends with a CALL
+ // instruction.
+ // FIXME this may need to be an architectural-dependent behavior; if so we'll
+ // need to add a member function
+ // to the ABI plugin and consult that.
+ if (decr_pc_and_recompute_addr_range) {
+ UnwindLogMsg("Backing up the pc value of 0x%" PRIx64
+ " by 1 and re-doing symbol lookup; old symbol was %s",
+ pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ Address temporary_pc;
+ temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
+ m_sym_ctx.Clear(false);
+ m_sym_ctx_valid = false;
+ uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+
+ ModuleSP temporary_module_sp = temporary_pc.GetModule();
+ if (temporary_module_sp &&
+ temporary_module_sp->ResolveSymbolContextForAddress(
+ temporary_pc, resolve_scope, m_sym_ctx) &
+ resolve_scope) {
+ if (m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range))
+ m_sym_ctx_valid = true;
}
+ UnwindLogMsg("Symbol is now %s",
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ }
+
+ // If we were able to find a symbol/function, set addr_range_ptr to the bounds
+ // of that symbol/function.
+ // else treat the current pc value as the start_pc and record no offset.
+ if (addr_range.GetBaseAddress().IsValid()) {
+ m_start_pc = addr_range.GetBaseAddress();
+ m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget());
+ m_current_offset_backed_up_one = m_current_offset;
+ if (decr_pc_and_recompute_addr_range &&
+ m_current_offset_backed_up_one > 0) {
+ m_current_offset_backed_up_one--;
+ if (m_sym_ctx_valid) {
+ m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget());
+ }
+ }
+ } else {
+ m_start_pc = m_current_pc;
+ m_current_offset = -1;
+ m_current_offset_backed_up_one = -1;
+ }
+
+ if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
+ m_frame_type = eTrapHandlerFrame;
+ } else {
+ // FIXME: Detect eDebuggerFrame here.
+ if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+ {
+ m_frame_type = eNormalFrame;
+ }
+ }
+
+ // We've set m_frame_type and m_sym_ctx before this call.
+ m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
+
+ UnwindPlan::RowSP active_row;
+ RegisterKind row_register_kind = eRegisterKindGeneric;
+
+ // Try to get by with just the fast UnwindPlan if possible - the full
+ // UnwindPlan may be expensive to get
+ // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for
+ // the first time.)
+
+ if (m_fast_unwind_plan_sp &&
+ m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ active_row =
+ m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
+ if (active_row.get() && log) {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
+ m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
+ UnwindLogMsg("active row: %s", active_row_strm.GetData());
+ }
+ } else {
+ m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
+ int valid_offset = -1;
+ if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) {
+ active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset);
+ row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
+ if (active_row.get() && log) {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
+ &m_thread,
+ m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
+ UnwindLogMsg("active row: %s", active_row_strm.GetData());
+ }
+ }
+ }
+
+ if (!active_row.get()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("could not find unwind row for this pc");
+ return;
+ }
- if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
- {
- UnwindLogMsg ("failed to get cfa");
- m_frame_type = eNotAValidFrame;
- return;
- }
+ if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) {
+ UnwindLogMsg("failed to get cfa");
+ m_frame_type = eNotAValidFrame;
+ return;
+ }
- UnwindLogMsg ("m_cfa = 0x%" PRIx64, m_cfa);
+ UnwindLogMsg("m_cfa = 0x%" PRIx64, m_cfa);
- if (CheckIfLoopingStack ())
- {
- TryFallbackUnwindPlan();
- if (CheckIfLoopingStack ())
- {
- UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping");
- m_frame_type = eNotAValidFrame;
- return;
- }
+ if (CheckIfLoopingStack()) {
+ TryFallbackUnwindPlan();
+ if (CheckIfLoopingStack()) {
+ UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
+ "looping - stopping");
+ m_frame_type = eNotAValidFrame;
+ return;
}
+ }
- UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64,
- (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
+ UnwindLogMsg("initialized frame current pc is 0x%" PRIx64
+ " cfa is 0x%" PRIx64,
+ (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
+ (uint64_t)m_cfa);
}
-bool
-RegisterContextLLDB::CheckIfLoopingStack ()
-{
- // If we have a bad stack setup, we can get the same CFA value multiple times -- or even
- // more devious, we can actually oscillate between two CFA values. Detect that here and
- // break out to avoid a possible infinite loop in lldb trying to unwind the stack.
- // To detect when we have the same CFA value multiple times, we compare the CFA of the current
- // frame with the 2nd next frame because in some specail case (e.g. signal hanlders, hand
- // written assembly without ABI compiance) we can have 2 frames with the same CFA (in theory we
- // can have arbitrary number of frames with the same CFA, but more then 2 is very very unlikely)
-
- RegisterContextLLDB::SharedPtr next_frame = GetNextFrame();
- if (next_frame)
- {
- RegisterContextLLDB::SharedPtr next_next_frame = next_frame->GetNextFrame();
- addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
- if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa))
- {
- if (next_next_frame_cfa == m_cfa)
- {
- // We have a loop in the stack unwind
- return true;
- }
- }
+bool RegisterContextLLDB::CheckIfLoopingStack() {
+ // If we have a bad stack setup, we can get the same CFA value multiple times
+ // -- or even
+ // more devious, we can actually oscillate between two CFA values. Detect that
+ // here and
+ // break out to avoid a possible infinite loop in lldb trying to unwind the
+ // stack.
+ // To detect when we have the same CFA value multiple times, we compare the
+ // CFA of the current
+ // frame with the 2nd next frame because in some specail case (e.g. signal
+ // hanlders, hand
+ // written assembly without ABI compiance) we can have 2 frames with the same
+ // CFA (in theory we
+ // can have arbitrary number of frames with the same CFA, but more then 2 is
+ // very very unlikely)
+
+ RegisterContextLLDB::SharedPtr next_frame = GetNextFrame();
+ if (next_frame) {
+ RegisterContextLLDB::SharedPtr next_next_frame = next_frame->GetNextFrame();
+ addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
+ if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) {
+ if (next_next_frame_cfa == m_cfa) {
+ // We have a loop in the stack unwind
+ return true;
+ }
}
- return false;
-}
-
-bool
-RegisterContextLLDB::IsFrameZero () const
-{
- return m_frame_number == 0;
+ }
+ return false;
}
+bool RegisterContextLLDB::IsFrameZero() const { return m_frame_number == 0; }
// Find a fast unwind plan for this frame, if possible.
//
// On entry to this method,
//
-// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct,
+// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
+// if either of those are correct,
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
-// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
+// 4. m_current_offset_backed_up_one should have the current byte offset into
+// the function, maybe backed up by 1, -1 if unknown
-UnwindPlanSP
-RegisterContextLLDB::GetFastUnwindPlanForFrame ()
-{
- UnwindPlanSP unwind_plan_sp;
- ModuleSP pc_module_sp (m_current_pc.GetModule());
+UnwindPlanSP RegisterContextLLDB::GetFastUnwindPlanForFrame() {
+ UnwindPlanSP unwind_plan_sp;
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL)
- return unwind_plan_sp;
+ if (!m_current_pc.IsValid() || !pc_module_sp ||
+ pc_module_sp->GetObjectFile() == NULL)
+ return unwind_plan_sp;
- if (IsFrameZero ())
- return unwind_plan_sp;
+ if (IsFrameZero())
+ return unwind_plan_sp;
- FuncUnwindersSP func_unwinders_sp (pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx));
- if (!func_unwinders_sp)
- return unwind_plan_sp;
+ FuncUnwindersSP func_unwinders_sp(
+ pc_module_sp->GetObjectFile()
+ ->GetUnwindTable()
+ .GetFuncUnwindersContainingAddress(m_current_pc, m_sym_ctx));
+ if (!func_unwinders_sp)
+ return unwind_plan_sp;
- // If we're in _sigtramp(), unwinding past this frame requires special knowledge.
- if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
- return unwind_plan_sp;
+ // If we're in _sigtramp(), unwinding past this frame requires special
+ // knowledge.
+ if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
+ return unwind_plan_sp;
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (*m_thread.CalculateTarget(), m_thread);
- if (unwind_plan_sp)
- {
- if (unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log && log->GetVerbose())
- {
- if (m_fast_unwind_plan_sp)
- UnwindLogMsgVerbose ("frame, and has a fast UnwindPlan");
- else
- UnwindLogMsgVerbose ("frame");
- }
- m_frame_type = eNormalFrame;
- return unwind_plan_sp;
- }
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind(
+ *m_thread.CalculateTarget(), m_thread);
+ if (unwind_plan_sp) {
+ if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log && log->GetVerbose()) {
+ if (m_fast_unwind_plan_sp)
+ UnwindLogMsgVerbose("frame, and has a fast UnwindPlan");
else
- {
- unwind_plan_sp.reset();
- }
- }
- return unwind_plan_sp;
+ UnwindLogMsgVerbose("frame");
+ }
+ m_frame_type = eNormalFrame;
+ return unwind_plan_sp;
+ } else {
+ unwind_plan_sp.reset();
+ }
+ }
+ return unwind_plan_sp;
}
// On entry to this method,
//
-// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct,
+// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
+// if either of those are correct,
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
-// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
-
-UnwindPlanSP
-RegisterContextLLDB::GetFullUnwindPlanForFrame ()
-{
- UnwindPlanSP unwind_plan_sp;
- UnwindPlanSP arch_default_unwind_plan_sp;
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- ABI *abi = process ? process->GetABI().get() : NULL;
- if (abi)
- {
- arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
- }
- else
- {
- UnwindLogMsg ("unable to get architectural default UnwindPlan from ABI plugin");
- }
-
- bool behaves_like_zeroth_frame = false;
- if (IsFrameZero ()
- || GetNextFrame()->m_frame_type == eTrapHandlerFrame
- || GetNextFrame()->m_frame_type == eDebuggerFrame)
- {
- behaves_like_zeroth_frame = true;
- // If this frame behaves like a 0th frame (currently executing or
- // interrupted asynchronously), all registers can be retrieved.
- m_all_registers_available = true;
- }
-
- // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) so the pc is 0x0
- // in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan
- // Also, if this Process can report on memory region attributes, any non-executable region means
- // we jumped through a bad function pointer - handle the same way as 0x0.
- // Note, if we have a symbol context & a symbol, we don't want to follow this code path. This is
- // for jumping to memory regions without any information available.
-
- if ((!m_sym_ctx_valid || (m_sym_ctx.function == NULL && m_sym_ctx.symbol == NULL)) && behaves_like_zeroth_frame && m_current_pc.IsValid())
- {
- uint32_t permissions;
- addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr());
- if (current_pc_addr == 0
- || (process &&
- process->GetLoadAddressPermissions (current_pc_addr, permissions)
- && (permissions & ePermissionsExecutable) == 0))
- {
- if (abi)
- {
- unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
- m_frame_type = eNormalFrame;
- return unwind_plan_sp;
- }
- }
- }
-
- // No Module for the current pc, try using the architecture default unwind.
- ModuleSP pc_module_sp (m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL)
- {
+// 4. m_current_offset_backed_up_one should have the current byte offset into
+// the function, maybe backed up by 1, -1 if unknown
+
+UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
+ UnwindPlanSP unwind_plan_sp;
+ UnwindPlanSP arch_default_unwind_plan_sp;
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ ABI *abi = process ? process->GetABI().get() : NULL;
+ if (abi) {
+ arch_default_unwind_plan_sp.reset(
+ new UnwindPlan(lldb::eRegisterKindGeneric));
+ abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
+ } else {
+ UnwindLogMsg(
+ "unable to get architectural default UnwindPlan from ABI plugin");
+ }
+
+ bool behaves_like_zeroth_frame = false;
+ if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
+ GetNextFrame()->m_frame_type == eDebuggerFrame) {
+ behaves_like_zeroth_frame = true;
+ // If this frame behaves like a 0th frame (currently executing or
+ // interrupted asynchronously), all registers can be retrieved.
+ m_all_registers_available = true;
+ }
+
+ // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer)
+ // so the pc is 0x0
+ // in the zeroth frame, we need to use the "unwind at first instruction" arch
+ // default UnwindPlan
+ // Also, if this Process can report on memory region attributes, any
+ // non-executable region means
+ // we jumped through a bad function pointer - handle the same way as 0x0.
+ // Note, if we have a symbol context & a symbol, we don't want to follow this
+ // code path. This is
+ // for jumping to memory regions without any information available.
+
+ if ((!m_sym_ctx_valid ||
+ (m_sym_ctx.function == NULL && m_sym_ctx.symbol == NULL)) &&
+ behaves_like_zeroth_frame && m_current_pc.IsValid()) {
+ uint32_t permissions;
+ addr_t current_pc_addr =
+ m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr());
+ if (current_pc_addr == 0 ||
+ (process &&
+ process->GetLoadAddressPermissions(current_pc_addr, permissions) &&
+ (permissions & ePermissionsExecutable) == 0)) {
+ if (abi) {
+ unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
m_frame_type = eNormalFrame;
- return arch_default_unwind_plan_sp;
- }
-
- FuncUnwindersSP func_unwinders_sp;
- if (m_sym_ctx_valid)
- {
- func_unwinders_sp = pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
- }
-
- // No FuncUnwinders available for this pc (stripped function symbols, lldb could not augment its
- // function table with another source, like LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO).
- // See if eh_frame or the .ARM.exidx tables have unwind information for this address, else fall
- // back to the architectural default unwind.
- if (!func_unwinders_sp)
- {
- m_frame_type = eNormalFrame;
-
- if (!pc_module_sp || !pc_module_sp->GetObjectFile() || !m_current_pc.IsValid())
- return arch_default_unwind_plan_sp;
-
- // Even with -fomit-frame-pointer, we can try eh_frame to get back on track.
- DWARFCallFrameInfo *eh_frame = pc_module_sp->GetObjectFile()->GetUnwindTable().GetEHFrameInfo();
- if (eh_frame)
- {
- unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- if (eh_frame->GetUnwindPlan (m_current_pc, *unwind_plan_sp))
- return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
- }
-
- ArmUnwindInfo *arm_exidx = pc_module_sp->GetObjectFile()->GetUnwindTable().GetArmUnwindInfo();
- if (arm_exidx)
- {
- unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- if (arm_exidx->GetUnwindPlan (exe_ctx.GetTargetRef(), m_current_pc, *unwind_plan_sp))
- return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
- }
-
- return arch_default_unwind_plan_sp;
- }
-
- // If we're in _sigtramp(), unwinding past this frame requires special knowledge. On Mac OS X this knowledge
- // is properly encoded in the eh_frame section, so prefer that if available.
- // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of
- // how to unwind out of sigtramp.
- if (m_frame_type == eTrapHandlerFrame && process)
- {
- m_fast_unwind_plan_sp.reset();
- unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc) && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
- {
- return unwind_plan_sp;
- }
- }
-
- // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame even when it's frame zero
- // This comes up if we have hand-written functions in a Module and hand-written eh_frame. The assembly
- // instruction inspection may fail and the eh_frame CFI were probably written with some care to do the
- // right thing. It'd be nice if there was a way to ask the eh_frame directly if it is asynchronous
- // (can be trusted at every instruction point) or synchronous (the normal case - only at call sites).
- // But there is not.
- if (process && process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
- {
- // We must specifically call the GetEHFrameUnwindPlan() method here -- normally we would
- // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind plan sourced from
- // either eh_frame (that's what we intend) or compact unwind (this won't work)
- unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
- unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
+ return unwind_plan_sp;
+ }
}
+ }
- // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions
- if (behaves_like_zeroth_frame && process)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one);
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo)
- {
- // We probably have an UnwindPlan created by inspecting assembly instructions. The
- // assembly profilers work really well with compiler-generated functions but hand-
- // written assembly can be problematic. We set the eh_frame based unwind plan as our
- // fallback unwind plan if instruction emulation doesn't work out even for non call
- // sites if it is available and use the architecture default unwind plan if it is
- // not available. The eh_frame unwind plan is more reliable even on non call sites
- // then the architecture default plan and for hand written assembly code it is often
- // written in a way that it valid at all location what helps in the most common
- // cases when the instruction emulation fails.
- UnwindPlanSP call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
- if (call_site_unwind_plan &&
- call_site_unwind_plan.get() != unwind_plan_sp.get() &&
- call_site_unwind_plan->GetSourceName() != unwind_plan_sp->GetSourceName())
- {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- }
- else
- {
- m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
- }
- }
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
+ // No Module for the current pc, try using the architecture default unwind.
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
+ if (!m_current_pc.IsValid() || !pc_module_sp ||
+ pc_module_sp->GetObjectFile() == NULL) {
+ m_frame_type = eNormalFrame;
+ return arch_default_unwind_plan_sp;
+ }
+
+ FuncUnwindersSP func_unwinders_sp;
+ if (m_sym_ctx_valid) {
+ func_unwinders_sp =
+ pc_module_sp->GetObjectFile()
+ ->GetUnwindTable()
+ .GetFuncUnwindersContainingAddress(m_current_pc, m_sym_ctx);
+ }
+
+ // No FuncUnwinders available for this pc (stripped function symbols, lldb
+ // could not augment its
+ // function table with another source, like LC_FUNCTION_STARTS or eh_frame in
+ // ObjectFileMachO).
+ // See if eh_frame or the .ARM.exidx tables have unwind information for this
+ // address, else fall
+ // back to the architectural default unwind.
+ if (!func_unwinders_sp) {
+ m_frame_type = eNormalFrame;
+
+ if (!pc_module_sp || !pc_module_sp->GetObjectFile() ||
+ !m_current_pc.IsValid())
+ return arch_default_unwind_plan_sp;
+
+ // Even with -fomit-frame-pointer, we can try eh_frame to get back on track.
+ DWARFCallFrameInfo *eh_frame =
+ pc_module_sp->GetObjectFile()->GetUnwindTable().GetEHFrameInfo();
+ if (eh_frame) {
+ unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
+ return unwind_plan_sp;
+ else
+ unwind_plan_sp.reset();
}
- // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites
- if (process)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one);
- }
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset))
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
+ ArmUnwindInfo *arm_exidx =
+ pc_module_sp->GetObjectFile()->GetUnwindTable().GetArmUnwindInfo();
+ if (arm_exidx) {
+ unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc,
+ *unwind_plan_sp))
return unwind_plan_sp;
+ else
+ unwind_plan_sp.reset();
}
- // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've
- // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible.
- if (process)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one);
- }
- if (unwind_plan_sp && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo)
- {
- // We probably have an UnwindPlan created by inspecting assembly instructions. The assembly
- // profilers work really well with compiler-generated functions but hand- written assembly
- // can be problematic. We set the eh_frame based unwind plan as our fallback unwind plan if
- // instruction emulation doesn't work out even for non call sites if it is available and use
- // the architecture default unwind plan if it is not available. The eh_frame unwind plan is
- // more reliable even on non call sites then the architecture default plan and for hand
- // written assembly code it is often written in a way that it valid at all location what
- // helps in the most common cases when the instruction emulation fails.
- UnwindPlanSP call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
+ return arch_default_unwind_plan_sp;
+ }
+
+ // If we're in _sigtramp(), unwinding past this frame requires special
+ // knowledge. On Mac OS X this knowledge
+ // is properly encoded in the eh_frame section, so prefer that if available.
+ // On other platforms we may need to provide a platform-specific UnwindPlan
+ // which encodes the details of
+ // how to unwind out of sigtramp.
+ if (m_frame_type == eTrapHandlerFrame && process) {
+ m_fast_unwind_plan_sp.reset();
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
+ unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
+ return unwind_plan_sp;
+ }
+ }
+
+ // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame
+ // even when it's frame zero
+ // This comes up if we have hand-written functions in a Module and
+ // hand-written eh_frame. The assembly
+ // instruction inspection may fail and the eh_frame CFI were probably written
+ // with some care to do the
+ // right thing. It'd be nice if there was a way to ask the eh_frame directly
+ // if it is asynchronous
+ // (can be trusted at every instruction point) or synchronous (the normal case
+ // - only at call sites).
+ // But there is not.
+ if (process && process->GetDynamicLoader() &&
+ process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) {
+ // We must specifically call the GetEHFrameUnwindPlan() method here --
+ // normally we would
+ // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind
+ // plan sourced from
+ // either eh_frame (that's what we intend) or compact unwind (this won't
+ // work)
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the "
+ "DynamicLoader suggested we prefer it",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+ }
+
+ // Typically the NonCallSite UnwindPlan is the unwind created by inspecting
+ // the assembly language instructions
+ if (behaves_like_zeroth_frame && process) {
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
+ process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+ if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
+ // We probably have an UnwindPlan created by inspecting assembly
+ // instructions. The
+ // assembly profilers work really well with compiler-generated functions
+ // but hand-
+ // written assembly can be problematic. We set the eh_frame based unwind
+ // plan as our
+ // fallback unwind plan if instruction emulation doesn't work out even
+ // for non call
+ // sites if it is available and use the architecture default unwind plan
+ // if it is
+ // not available. The eh_frame unwind plan is more reliable even on non
+ // call sites
+ // then the architecture default plan and for hand written assembly code
+ // it is often
+ // written in a way that it valid at all location what helps in the most
+ // common
+ // cases when the instruction emulation fails.
+ UnwindPlanSP call_site_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
if (call_site_unwind_plan &&
call_site_unwind_plan.get() != unwind_plan_sp.get() &&
- call_site_unwind_plan->GetSourceName() != unwind_plan_sp->GetSourceName())
- {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- }
- else
- {
- m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
+ call_site_unwind_plan->GetSourceName() !=
+ unwind_plan_sp->GetSourceName()) {
+ m_fallback_unwind_plan_sp = call_site_unwind_plan;
+ } else {
+ m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
}
- }
-
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset))
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
-
- // If we're on the first instruction of a function, and we have an architectural default UnwindPlan
- // for the initial instruction of a function, use that.
- if (m_current_offset_backed_up_one == 0)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry (m_thread);
- if (unwind_plan_sp)
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
- }
-
- // If nothing else, use the architectural default UnwindPlan and hope that does the job.
- if (arch_default_unwind_plan_sp)
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString());
- else
- UnwindLogMsg ("Unable to find any UnwindPlan for full unwind of this frame.");
-
- return arch_default_unwind_plan_sp;
+ }
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+ }
+
+ // Typically this is unwind info from an eh_frame section intended for
+ // exception handling; only valid at call sites
+ if (process) {
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ }
+ int valid_offset = -1;
+ if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+
+ // We'd prefer to use an UnwindPlan intended for call sites when we're at a
+ // call site but if we've
+ // struck out on that, fall back to using the non-call-site assembly
+ // inspection UnwindPlan if possible.
+ if (process) {
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
+ process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+ }
+ if (unwind_plan_sp &&
+ unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
+ // We probably have an UnwindPlan created by inspecting assembly
+ // instructions. The assembly
+ // profilers work really well with compiler-generated functions but hand-
+ // written assembly
+ // can be problematic. We set the eh_frame based unwind plan as our fallback
+ // unwind plan if
+ // instruction emulation doesn't work out even for non call sites if it is
+ // available and use
+ // the architecture default unwind plan if it is not available. The eh_frame
+ // unwind plan is
+ // more reliable even on non call sites then the architecture default plan
+ // and for hand
+ // written assembly code it is often written in a way that it valid at all
+ // location what
+ // helps in the most common cases when the instruction emulation fails.
+ UnwindPlanSP call_site_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ if (call_site_unwind_plan &&
+ call_site_unwind_plan.get() != unwind_plan_sp.get() &&
+ call_site_unwind_plan->GetSourceName() !=
+ unwind_plan_sp->GetSourceName()) {
+ m_fallback_unwind_plan_sp = call_site_unwind_plan;
+ } else {
+ m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
+ }
+ }
+
+ if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+
+ // If we're on the first instruction of a function, and we have an
+ // architectural default UnwindPlan
+ // for the initial instruction of a function, use that.
+ if (m_current_offset_backed_up_one == 0) {
+ unwind_plan_sp =
+ func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry(
+ m_thread);
+ if (unwind_plan_sp) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+ }
+
+ // If nothing else, use the architectural default UnwindPlan and hope that
+ // does the job.
+ if (arch_default_unwind_plan_sp)
+ UnwindLogMsgVerbose(
+ "frame uses %s for full UnwindPlan",
+ arch_default_unwind_plan_sp->GetSourceName().GetCString());
+ else
+ UnwindLogMsg(
+ "Unable to find any UnwindPlan for full unwind of this frame.");
+
+ return arch_default_unwind_plan_sp;
}
-
-void
-RegisterContextLLDB::InvalidateAllRegisters ()
-{
- m_frame_type = eNotAValidFrame;
+void RegisterContextLLDB::InvalidateAllRegisters() {
+ m_frame_type = eNotAValidFrame;
}
-size_t
-RegisterContextLLDB::GetRegisterCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterCount();
+size_t RegisterContextLLDB::GetRegisterCount() {
+ return m_thread.GetRegisterContext()->GetRegisterCount();
}
-const RegisterInfo *
-RegisterContextLLDB::GetRegisterInfoAtIndex (size_t reg)
-{
- return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg);
+const RegisterInfo *RegisterContextLLDB::GetRegisterInfoAtIndex(size_t reg) {
+ return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
-size_t
-RegisterContextLLDB::GetRegisterSetCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterSetCount ();
+size_t RegisterContextLLDB::GetRegisterSetCount() {
+ return m_thread.GetRegisterContext()->GetRegisterSetCount();
}
-const RegisterSet *
-RegisterContextLLDB::GetRegisterSet (size_t reg_set)
-{
- return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
+const RegisterSet *RegisterContextLLDB::GetRegisterSet(size_t reg_set) {
+ return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
}
-uint32_t
-RegisterContextLLDB::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
+uint32_t RegisterContextLLDB::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
+ kind, num);
}
-bool
-RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- if (!IsValid())
- return false;
- bool success = false;
-
- switch (regloc.type)
- {
- case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
-
- if (!other_reg_info)
- return false;
-
- success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value);
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterInRegister:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
-
- if (!other_reg_info)
- return false;
-
- if (IsFrameZero ())
- {
- success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value);
- }
- else
- {
- success = GetNextFrame()->ReadRegister (other_reg_info, value);
- }
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
- success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size);
- break;
-
- case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
- assert ("FIXME debugger inferior function call unwind");
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
- {
- Error error (ReadRegisterValueFromMemory(reg_info,
- regloc.location.target_memory_location,
- reg_info->byte_size,
- value));
- success = error.Success();
- }
- break;
- default:
- assert ("Unknown RegisterLocation type.");
- break;
- }
- return success;
+bool RegisterContextLLDB::ReadRegisterValueFromRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!IsValid())
+ return false;
+ bool success = false;
+
+ switch (regloc.type) {
+ case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+
+ if (!other_reg_info)
+ return false;
+
+ success =
+ m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+
+ if (!other_reg_info)
+ return false;
+
+ if (IsFrameZero()) {
+ success =
+ m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
+ } else {
+ success = GetNextFrame()->ReadRegister(other_reg_info, value);
+ }
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
+ success =
+ value.SetUInt(regloc.location.inferred_value, reg_info->byte_size);
+ break;
+
+ case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
+ assert("FIXME debugger inferior function call unwind");
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
+ Error error(ReadRegisterValueFromMemory(
+ reg_info, regloc.location.target_memory_location, reg_info->byte_size,
+ value));
+ success = error.Success();
+ } break;
+ default:
+ assert("Unknown RegisterLocation type.");
+ break;
+ }
+ return success;
}
-bool
-RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- if (!IsValid())
- return false;
-
- bool success = false;
+bool RegisterContextLLDB::WriteRegisterValueToRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ if (!IsValid())
+ return false;
- switch (regloc.type)
- {
- case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
- success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value);
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterInRegister:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
- if (IsFrameZero ())
- {
- success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value);
- }
- else
- {
- success = GetNextFrame()->WriteRegister (other_reg_info, value);
- }
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
- case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
- assert ("FIXME debugger inferior function call unwind");
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
- {
- Error error (WriteRegisterValueToMemory (reg_info,
- regloc.location.target_memory_location,
- reg_info->byte_size,
- value));
- success = error.Success();
- }
- break;
- default:
- assert ("Unknown RegisterLocation type.");
- break;
- }
- return success;
+ bool success = false;
+
+ switch (regloc.type) {
+ case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+ success =
+ m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+ if (IsFrameZero()) {
+ success =
+ m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
+ } else {
+ success = GetNextFrame()->WriteRegister(other_reg_info, value);
+ }
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
+ case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
+ assert("FIXME debugger inferior function call unwind");
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
+ Error error(WriteRegisterValueToMemory(
+ reg_info, regloc.location.target_memory_location, reg_info->byte_size,
+ value));
+ success = error.Success();
+ } break;
+ default:
+ assert("Unknown RegisterLocation type.");
+ break;
+ }
+ return success;
}
-
-bool
-RegisterContextLLDB::IsValid () const
-{
- return m_frame_type != eNotAValidFrame;
+bool RegisterContextLLDB::IsValid() const {
+ return m_frame_type != eNotAValidFrame;
}
-// After the final stack frame in a stack walk we'll get one invalid (eNotAValidFrame) stack frame --
-// one past the end of the stack walk. But higher-level code will need to tell the differnece between
-// "the unwind plan below this frame failed" versus "we successfully completed the stack walk" so
+// After the final stack frame in a stack walk we'll get one invalid
+// (eNotAValidFrame) stack frame --
+// one past the end of the stack walk. But higher-level code will need to tell
+// the differnece between
+// "the unwind plan below this frame failed" versus "we successfully completed
+// the stack walk" so
// this method helps to disambiguate that.
-bool
-RegisterContextLLDB::IsTrapHandlerFrame () const
-{
- return m_frame_type == eTrapHandlerFrame;
+bool RegisterContextLLDB::IsTrapHandlerFrame() const {
+ return m_frame_type == eTrapHandlerFrame;
}
-// A skip frame is a bogus frame on the stack -- but one where we're likely to find a real frame farther
-// up the stack if we keep looking. It's always the second frame in an unwind (i.e. the first frame after
-// frame zero) where unwinding can be the trickiest. Ideally we'll mark up this frame in some way so the
-// user knows we're displaying bad data and we may have skipped one frame of their real program in the
+// A skip frame is a bogus frame on the stack -- but one where we're likely to
+// find a real frame farther
+// up the stack if we keep looking. It's always the second frame in an unwind
+// (i.e. the first frame after
+// frame zero) where unwinding can be the trickiest. Ideally we'll mark up this
+// frame in some way so the
+// user knows we're displaying bad data and we may have skipped one frame of
+// their real program in the
// process of getting back on track.
-bool
-RegisterContextLLDB::IsSkipFrame () const
-{
- return m_frame_type == eSkipFrame;
+bool RegisterContextLLDB::IsSkipFrame() const {
+ return m_frame_type == eSkipFrame;
}
-bool
-RegisterContextLLDB::IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const
-{
- PlatformSP platform_sp (process->GetTarget().GetPlatform());
- if (platform_sp)
- {
- const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames());
- for (ConstString name : trap_handler_names)
- {
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
- {
- return true;
- }
- }
+bool RegisterContextLLDB::IsTrapHandlerSymbol(
+ lldb_private::Process *process,
+ const lldb_private::SymbolContext &m_sym_ctx) const {
+ PlatformSP platform_sp(process->GetTarget().GetPlatform());
+ if (platform_sp) {
+ const std::vector<ConstString> trap_handler_names(
+ platform_sp->GetTrapHandlerSymbolNames());
+ for (ConstString name : trap_handler_names) {
+ if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+ (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
+ return true;
+ }
}
- const std::vector<ConstString> user_specified_trap_handler_names (m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
- for (ConstString name : user_specified_trap_handler_names)
- {
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
- {
- return true;
- }
- }
+ }
+ const std::vector<ConstString> user_specified_trap_handler_names(
+ m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
+ for (ConstString name : user_specified_trap_handler_names) {
+ if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+ (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
-// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
+// Answer the question: Where did THIS frame save the CALLER frame ("previous"
+// frame)'s register value?
enum UnwindLLDB::RegisterSearchResult
-RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc)
-{
- RegisterNumber regnum (m_thread, eRegisterKindLLDB, lldb_regnum);
-
- // Have we already found this register location?
- if (!m_registers.empty())
- {
- std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator;
- iterator = m_registers.find (regnum.GetAsKind (eRegisterKindLLDB));
- if (iterator != m_registers.end())
- {
- regloc = iterator->second;
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location, cached",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+RegisterContextLLDB::SavedLocationForRegister(
+ uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc) {
+ RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum);
+
+ // Have we already found this register location?
+ if (!m_registers.empty()) {
+ std::map<uint32_t,
+ lldb_private::UnwindLLDB::RegisterLocation>::const_iterator
+ iterator;
+ iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB));
+ if (iterator != m_registers.end()) {
+ regloc = iterator->second;
+ UnwindLogMsg("supplying caller's saved %s (%d)'s location, cached",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+ }
+
+ // Look through the available UnwindPlans for the register location.
+
+ UnwindPlan::Row::RegisterLocation unwindplan_regloc;
+ bool have_unwindplan_regloc = false;
+ RegisterKind unwindplan_registerkind = kNumRegisterKinds;
+
+ if (m_fast_unwind_plan_sp) {
+ UnwindPlan::RowSP active_row =
+ m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind();
+ if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
+ UnwindLogMsg("could not convert lldb regnum %s (%d) into %d RegisterKind "
+ "reg numbering scheme",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ (int)unwindplan_registerkind);
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+ if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
+ unwindplan_regloc)) {
+ UnwindLogMsg(
+ "supplying caller's saved %s (%d)'s location using FastUnwindPlan",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ have_unwindplan_regloc = true;
+ }
+ }
+
+ if (!have_unwindplan_regloc) {
+ // m_full_unwind_plan_sp being NULL means that we haven't tried to find a
+ // full UnwindPlan yet
+ if (!m_full_unwind_plan_sp)
+ m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
+
+ if (m_full_unwind_plan_sp) {
+ RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+
+ UnwindPlan::RowSP active_row =
+ m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
+
+ RegisterNumber return_address_reg;
+
+ // If we're fetching the saved pc and this UnwindPlan defines a
+ // ReturnAddress register (e.g. lr on arm),
+ // look for the return address register number in the UnwindPlan's row.
+ if (pc_regnum.IsValid() && pc_regnum == regnum &&
+ m_full_unwind_plan_sp->GetReturnAddressRegister() !=
+ LLDB_INVALID_REGNUM) {
+
+ return_address_reg.init(
+ m_thread, m_full_unwind_plan_sp->GetRegisterKind(),
+ m_full_unwind_plan_sp->GetReturnAddressRegister());
+ regnum = return_address_reg;
+ UnwindLogMsg("requested caller's saved PC but this UnwindPlan uses a "
+ "RA reg; getting %s (%d) instead",
+ return_address_reg.GetName(),
+ return_address_reg.GetAsKind(eRegisterKindLLDB));
+ } else {
+ if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
+ if (unwindplan_registerkind == eRegisterKindGeneric) {
+ UnwindLogMsg("could not convert lldb regnum %s (%d) into "
+ "eRegisterKindGeneric reg numbering scheme",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ } else {
+ UnwindLogMsg("could not convert lldb regnum %s (%d) into %d "
+ "RegisterKind reg numbering scheme",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ (int)unwindplan_registerkind);
+ }
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
- }
-
- // Look through the available UnwindPlans for the register location.
-
- UnwindPlan::Row::RegisterLocation unwindplan_regloc;
- bool have_unwindplan_regloc = false;
- RegisterKind unwindplan_registerkind = kNumRegisterKinds;
-
- if (m_fast_unwind_plan_sp)
- {
- UnwindPlan::RowSP active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind ();
- if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM)
- {
- UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind);
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- if (active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
- {
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location using FastUnwindPlan",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- have_unwindplan_regloc = true;
+ }
+
+ if (regnum.IsValid() &&
+ active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
+ unwindplan_regloc)) {
+ have_unwindplan_regloc = true;
+ UnwindLogMsg(
+ "supplying caller's saved %s (%d)'s location using %s UnwindPlan",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+ }
+
+ // This is frame 0 and we're retrieving the PC and it's saved in a Return
+ // Address register and
+ // it hasn't been saved anywhere yet -- that is, it's still live in the
+ // actual register.
+ // Handle this specially.
+
+ if (have_unwindplan_regloc == false && return_address_reg.IsValid() &&
+ IsFrameZero()) {
+ if (return_address_reg.GetAsKind(eRegisterKindLLDB) !=
+ LLDB_INVALID_REGNUM) {
+ lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+ new_regloc.type =
+ UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
+ new_regloc.location.register_number =
+ return_address_reg.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
+ regloc = new_regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) from the live "
+ "RegisterContext at frame 0, saved in %d",
+ return_address_reg.GetName(),
+ return_address_reg.GetAsKind(eRegisterKindLLDB),
+ return_address_reg.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
- }
-
- if (!have_unwindplan_regloc)
- {
- // m_full_unwind_plan_sp being NULL means that we haven't tried to find a full UnwindPlan yet
- if (!m_full_unwind_plan_sp)
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
-
- if (m_full_unwind_plan_sp)
- {
- RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
-
- UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
-
- RegisterNumber return_address_reg;
-
- // If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm),
- // look for the return address register number in the UnwindPlan's row.
- if (pc_regnum.IsValid()
- && pc_regnum == regnum
- && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM)
- {
-
- return_address_reg.init (m_thread, m_full_unwind_plan_sp->GetRegisterKind(), m_full_unwind_plan_sp->GetReturnAddressRegister());
- regnum = return_address_reg;
- UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting %s (%d) instead",
- return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB));
- }
- else
- {
- if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM)
- {
- if (unwindplan_registerkind == eRegisterKindGeneric)
- {
- UnwindLogMsg ("could not convert lldb regnum %s (%d) into eRegisterKindGeneric reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- }
- else
- {
- UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind);
- }
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
+ }
+
+ // If this architecture stores the return address in a register (it
+ // defines a Return Address register)
+ // and we're on a non-zero stack frame and the Full UnwindPlan says that
+ // the pc is stored in the
+ // RA registers (e.g. lr on arm), then we know that the full unwindplan is
+ // not trustworthy -- this
+ // is an impossible situation and the instruction emulation code has
+ // likely been misled.
+ // If this stack frame meets those criteria, we need to throw away the
+ // Full UnwindPlan that the
+ // instruction emulation came up with and fall back to the architecture's
+ // Default UnwindPlan so
+ // the stack walk can get past this point.
+
+ // Special note: If the Full UnwindPlan was generated from the compiler,
+ // don't second-guess it
+ // when we're at a call site location.
+
+ // arch_default_ra_regnum is the return address register # in the Full
+ // UnwindPlan register numbering
+ RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA);
+
+ if (arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) !=
+ LLDB_INVALID_REGNUM &&
+ pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() &&
+ unwindplan_regloc.GetRegisterNumber() ==
+ arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) &&
+ m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes &&
+ !m_all_registers_available) {
+ UnwindLogMsg("%s UnwindPlan tried to restore the pc from the link "
+ "register but this is a non-zero frame",
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+
+ // Throw away the full unwindplan; install the arch default unwindplan
+ if (ForceSwitchToFallbackUnwindPlan()) {
+ // Update for the possibly new unwind plan
+ unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
+ UnwindPlan::RowSP active_row =
+ m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+
+ // Sanity check: Verify that we can fetch a pc value and CFA value
+ // with this unwind plan
+
+ RegisterNumber arch_default_pc_reg(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+ bool can_fetch_pc_value = false;
+ bool can_fetch_cfa = false;
+ addr_t cfa_value;
+ if (active_row) {
+ if (arch_default_pc_reg.GetAsKind(unwindplan_registerkind) !=
+ LLDB_INVALID_REGNUM &&
+ active_row->GetRegisterInfo(
+ arch_default_pc_reg.GetAsKind(unwindplan_registerkind),
+ unwindplan_regloc)) {
+ can_fetch_pc_value = true;
}
-
- if (regnum.IsValid()
- && active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
- {
- have_unwindplan_regloc = true;
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location using %s UnwindPlan",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- m_full_unwind_plan_sp->GetSourceName().GetCString());
- }
-
- // This is frame 0 and we're retrieving the PC and it's saved in a Return Address register and
- // it hasn't been saved anywhere yet -- that is, it's still live in the actual register.
- // Handle this specially.
-
- if (have_unwindplan_regloc == false
- && return_address_reg.IsValid()
- && IsFrameZero())
- {
- if (return_address_reg.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM)
- {
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
- new_regloc.location.register_number = return_address_reg.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
- regloc = new_regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0, saved in %d",
- return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB),
- return_address_reg.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
-
- // If this architecture stores the return address in a register (it defines a Return Address register)
- // and we're on a non-zero stack frame and the Full UnwindPlan says that the pc is stored in the
- // RA registers (e.g. lr on arm), then we know that the full unwindplan is not trustworthy -- this
- // is an impossible situation and the instruction emulation code has likely been misled.
- // If this stack frame meets those criteria, we need to throw away the Full UnwindPlan that the
- // instruction emulation came up with and fall back to the architecture's Default UnwindPlan so
- // the stack walk can get past this point.
-
- // Special note: If the Full UnwindPlan was generated from the compiler, don't second-guess it
- // when we're at a call site location.
-
- // arch_default_ra_regnum is the return address register # in the Full UnwindPlan register numbering
- RegisterNumber arch_default_ra_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
-
- if (arch_default_ra_regnum.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM
- && pc_regnum == regnum
- && unwindplan_regloc.IsInOtherRegister()
- && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum.GetAsKind (unwindplan_registerkind)
- && m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes
- && !m_all_registers_available)
- {
- UnwindLogMsg ("%s UnwindPlan tried to restore the pc from the link register but this is a non-zero frame",
- m_full_unwind_plan_sp->GetSourceName().GetCString());
-
- // Throw away the full unwindplan; install the arch default unwindplan
- if (ForceSwitchToFallbackUnwindPlan())
- {
- // Update for the possibly new unwind plan
- unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
- UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
-
- // Sanity check: Verify that we can fetch a pc value and CFA value with this unwind plan
-
- RegisterNumber arch_default_pc_reg (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- bool can_fetch_pc_value = false;
- bool can_fetch_cfa = false;
- addr_t cfa_value;
- if (active_row)
- {
- if (arch_default_pc_reg.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM
- && active_row->GetRegisterInfo (arch_default_pc_reg.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
- {
- can_fetch_pc_value = true;
- }
- if (ReadCFAValueForRow (unwindplan_registerkind, active_row, cfa_value))
- {
- can_fetch_cfa = true;
- }
- }
-
- if (can_fetch_pc_value && can_fetch_cfa)
- {
- have_unwindplan_regloc = true;
- }
- else
- {
- have_unwindplan_regloc = false;
- }
- }
- else
- {
- // We were unable to fall back to another unwind plan
- have_unwindplan_regloc = false;
- }
+ if (ReadCFAValueForRow(unwindplan_registerkind, active_row,
+ cfa_value)) {
+ can_fetch_cfa = true;
}
- }
- }
+ }
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- if (have_unwindplan_regloc == false)
- {
- // If the UnwindPlan failed to give us an unwind location for this register, we may be able to fall back
- // to some ABI-defined default. For example, some ABIs allow to determine the caller's SP via the CFA.
- // Also, the ABI may set volatile registers to the undefined state.
- ABI *abi = process ? process->GetABI().get() : NULL;
- if (abi)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB));
- if (reg_info && abi->GetFallbackRegisterLocation (reg_info, unwindplan_regloc))
- {
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location using ABI default",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- have_unwindplan_regloc = true;
- }
- }
- }
-
- if (have_unwindplan_regloc == false)
- {
- if (IsFrameZero ())
- {
- // This is frame 0 - we should return the actual live register context value
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
- new_regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
- regloc = new_regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- else
- {
- std::string unwindplan_name ("");
- if (m_full_unwind_plan_sp)
- {
- unwindplan_name += "via '";
- unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
- unwindplan_name += "'";
- }
- UnwindLogMsg ("no save location for %s (%d) %s",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- unwindplan_name.c_str());
- }
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- // unwindplan_regloc has valid contents about where to retrieve the register
- if (unwindplan_regloc.IsUnspecified())
- {
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
- UnwindLogMsg ("save location for %s (%d) is unspecified, continue searching",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- if (unwindplan_regloc.IsUndefined())
- {
- UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
- }
-
- if (unwindplan_regloc.IsSame())
- {
- if (IsFrameZero() == false
- && (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 return address reg on a non-zero frame -- treat as if we have no information",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- else
- {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
- regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ if (can_fetch_pc_value && can_fetch_cfa) {
+ have_unwindplan_regloc = true;
+ } else {
+ have_unwindplan_regloc = false;
+ }
+ } else {
+ // We were unable to fall back to another unwind plan
+ have_unwindplan_regloc = false;
}
+ }
+ }
+ }
+
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (have_unwindplan_regloc == false) {
+ // If the UnwindPlan failed to give us an unwind location for this register,
+ // we may be able to fall back
+ // to some ABI-defined default. For example, some ABIs allow to determine
+ // the caller's SP via the CFA.
+ // Also, the ABI may set volatile registers to the undefined state.
+ ABI *abi = process ? process->GetABI().get() : NULL;
+ if (abi) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB));
+ if (reg_info &&
+ abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) {
+ UnwindLogMsg(
+ "supplying caller's saved %s (%d)'s location using ABI default",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ have_unwindplan_regloc = true;
+ }
+ }
+ }
+
+ if (have_unwindplan_regloc == false) {
+ if (IsFrameZero()) {
+ // This is frame 0 - we should return the actual live register context
+ // value
+ lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+ new_regloc.type =
+ UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
+ new_regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
+ regloc = new_regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) from the live "
+ "RegisterContext at frame 0",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ } else {
+ std::string unwindplan_name("");
+ if (m_full_unwind_plan_sp) {
+ unwindplan_name += "via '";
+ unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
+ unwindplan_name += "'";
+ }
+ UnwindLogMsg("no save location for %s (%d) %s", regnum.GetName(),
+ regnum.GetAsKind(eRegisterKindLLDB),
+ unwindplan_name.c_str());
}
-
- if (unwindplan_regloc.IsCFAPlusOffset())
- {
- int offset = unwindplan_regloc.GetOffset();
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+
+ // unwindplan_regloc has valid contents about where to retrieve the register
+ if (unwindplan_regloc.IsUnspecified()) {
+ lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+ new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
+ UnwindLogMsg("save location for %s (%d) is unspecified, continue searching",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+
+ if (unwindplan_regloc.IsUndefined()) {
+ UnwindLogMsg(
+ "did not supply reg location for %s (%d) because it is volatile",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
+ }
+
+ if (unwindplan_regloc.IsSame()) {
+ if (IsFrameZero() == false &&
+ (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 "
+ "return address reg on a non-zero frame -- treat as if we "
+ "have no information",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ } else {
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg(
+ "supplying caller's register %s (%d), saved in register %s (%d)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+ }
+
+ if (unwindplan_regloc.IsCFAPlusOffset()) {
+ int offset = unwindplan_regloc.GetOffset();
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
+ regloc.location.inferred_value = m_cfa + offset;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d), value is CFA plus "
+ "offset %d [value is 0x%" PRIx64 "]",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
+ regloc.location.inferred_value);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
+ if (unwindplan_regloc.IsAtCFAPlusOffset()) {
+ int offset = unwindplan_regloc.GetOffset();
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
+ regloc.location.target_memory_location = m_cfa + offset;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at "
+ "CFA 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,
+ unwindplan_regnum);
+ if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) {
+ UnwindLogMsg("could not supply caller's %s (%d) location - was saved in "
+ "another reg but couldn't convert that regnum",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg(
+ "supplying caller's register %s (%d), saved in register %s (%d)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
+ if (unwindplan_regloc.IsDWARFExpression() ||
+ unwindplan_regloc.IsAtDWARFExpression()) {
+ DataExtractor dwarfdata(unwindplan_regloc.GetDWARFExpressionBytes(),
+ unwindplan_regloc.GetDWARFExpressionLength(),
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+ ModuleSP opcode_ctx;
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
+ unwindplan_regloc.GetDWARFExpressionLength());
+ dwarfexpr.SetRegisterKind(unwindplan_registerkind);
+ Value result;
+ Error error;
+ if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
+ nullptr, result, &error)) {
+ addr_t val;
+ val = result.GetScalar().ULongLong();
+ if (unwindplan_regloc.IsDWARFExpression()) {
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = m_cfa + offset;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d), value is CFA plus offset %d [value is 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- offset, regloc.location.inferred_value);
+ regloc.location.inferred_value = val;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
+ "(IsDWARFExpression)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsAtCFAPlusOffset())
- {
- int offset = unwindplan_regloc.GetOffset();
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = m_cfa + offset;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) from the stack, saved at CFA plus offset %d [saved at 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- offset, regloc.location.target_memory_location);
+ } else {
+ regloc.type =
+ UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
+ regloc.location.target_memory_location = val;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
+ "(IsAtDWARFExpression)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
}
+ UnwindLogMsg("tried to use IsDWARFExpression or IsAtDWARFExpression for %s "
+ "(%d) but failed",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
- if (unwindplan_regloc.IsInOtherRegister())
- {
- uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
- RegisterNumber row_regnum (m_thread, unwindplan_registerkind, unwindplan_regnum);
- if (row_regnum.GetAsKind (eRegisterKindLLDB) == LLDB_INVALID_REGNUM)
- {
- UnwindLogMsg ("could not supply caller's %s (%d) location - was saved in another reg but couldn't convert that regnum",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
- regloc.location.register_number = row_regnum.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- row_regnum.GetName(), row_regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
- {
- DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
- unwindplan_regloc.GetDWARFExpressionLength(),
- process->GetByteOrder(), process->GetAddressByteSize());
- ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr (opcode_ctx,
- dwarfdata,
- nullptr,
- 0,
- unwindplan_regloc.GetDWARFExpressionLength());
- dwarfexpr.SetRegisterKind (unwindplan_registerkind);
- Value result;
- Error error;
- if (dwarfexpr.Evaluate (&exe_ctx, nullptr, nullptr, this, 0, nullptr, nullptr, result, &error))
- {
- addr_t val;
- val = result.GetScalar().ULongLong();
- if (unwindplan_regloc.IsDWARFExpression())
- {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = val;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsDWARFExpression)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- else
- {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = val;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsAtDWARFExpression)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
- UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for %s (%d) but failed",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- UnwindLogMsg ("no save location for %s (%d) in this stack frame",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+ UnwindLogMsg("no save location for %s (%d) in this stack frame",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
+ // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are
+ // unsupported.
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
// TryFallbackUnwindPlan() -- this method is a little tricky.
-//
-// When this is called, the frame above -- the caller frame, the "previous" frame --
-// is invalid or bad.
//
-// Instead of stopping the stack walk here, we'll try a different UnwindPlan and see
-// if we can get a valid frame above us.
+// When this is called, the frame above -- the caller frame, the "previous"
+// frame --
+// is invalid or bad.
+//
+// Instead of stopping the stack walk here, we'll try a different UnwindPlan and
+// see
+// if we can get a valid frame above us.
//
-// This most often happens when an unwind plan based on assembly instruction inspection
-// is not correct -- mostly with hand-written assembly functions or functions where the
-// stack frame is set up "out of band", e.g. the kernel saved the register context and
+// This most often happens when an unwind plan based on assembly instruction
+// inspection
+// is not correct -- mostly with hand-written assembly functions or functions
+// where the
+// stack frame is set up "out of band", e.g. the kernel saved the register
+// context and
// then called an asynchronous trap handler like _sigtramp.
//
-// Often in these cases, if we just do a dumb stack walk we'll get past this tricky
+// Often in these cases, if we just do a dumb stack walk we'll get past this
+// tricky
// frame and our usual techniques can continue to be used.
-bool
-RegisterContextLLDB::TryFallbackUnwindPlan ()
-{
- if (m_fallback_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get()
- || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName())
- {
- return false;
- }
+bool RegisterContextLLDB::TryFallbackUnwindPlan() {
+ if (m_fallback_unwind_plan_sp.get() == nullptr)
+ return false;
- // If a compiler generated unwind plan failed, trying the arch default unwindplan
- // isn't going to do any better.
- if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
- return false;
+ if (m_full_unwind_plan_sp.get() == nullptr)
+ return false;
+ if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
+ m_full_unwind_plan_sp->GetSourceName() ==
+ m_fallback_unwind_plan_sp->GetSourceName()) {
+ return false;
+ }
- // Get the caller's pc value and our own CFA value.
- // Swap in the fallback unwind plan, re-fetch the caller's pc value and CFA value.
- // If they're the same, then the fallback unwind plan provides no benefit.
+ // If a compiler generated unwind plan failed, trying the arch default
+ // unwindplan
+ // isn't going to do any better.
+ if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
+ return false;
- RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ // Get the caller's pc value and our own CFA value.
+ // Swap in the fallback unwind plan, re-fetch the caller's pc value and CFA
+ // value.
+ // If they're the same, then the fallback unwind plan provides no benefit.
+
+ RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+
+ 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) ==
+ UnwindLLDB::RegisterSearchResult::eRegisterFound) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
+ if (reg_info) {
+ RegisterValue reg_value;
+ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
+ old_caller_pc_value = reg_value.GetAsUInt64();
+ }
+ }
+ }
+
+ // This is a tricky wrinkle! If SavedLocationForRegister() detects a really
+ // impossible
+ // register location for the full unwind plan, it may call
+ // ForceSwitchToFallbackUnwindPlan()
+ // which in turn replaces the full unwindplan with the fallback... in short,
+ // we're done,
+ // we're using the fallback UnwindPlan.
+ // We checked if m_fallback_unwind_plan_sp was nullptr at the top -- the only
+ // way it
+ // became nullptr since then is via SavedLocationForRegister().
+ if (m_fallback_unwind_plan_sp.get() == nullptr)
+ return true;
- 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) == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB));
- if (reg_info)
- {
- RegisterValue reg_value;
- if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value))
- {
- old_caller_pc_value = reg_value.GetAsUInt64();
- }
+ // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide
+ // this isn't
+ // working, we need to restore.
+ // We'll also need to save & restore the value of the m_cfa ivar. Save is
+ // down below a bit in 'old_cfa'.
+ UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
+ addr_t old_cfa = m_cfa;
+
+ m_registers.clear();
+
+ m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
+
+ UnwindPlan::RowSP active_row =
+ m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+
+ if (active_row &&
+ active_row->GetCFAValue().GetValueType() !=
+ UnwindPlan::Row::CFAValue::unspecified) {
+ addr_t new_cfa;
+ if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row, 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;
+
+ if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
+ regloc) ==
+ UnwindLLDB::RegisterSearchResult::eRegisterFound) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
+ if (reg_info) {
+ RegisterValue reg_value;
+ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
+ reg_value)) {
+ new_caller_pc_value = reg_value.GetAsUInt64();
}
+ }
}
- // This is a tricky wrinkle! If SavedLocationForRegister() detects a really impossible
- // register location for the full unwind plan, it may call ForceSwitchToFallbackUnwindPlan()
- // which in turn replaces the full unwindplan with the fallback... in short, we're done,
- // we're using the fallback UnwindPlan.
- // We checked if m_fallback_unwind_plan_sp was nullptr at the top -- the only way it
- // became nullptr since then is via SavedLocationForRegister().
- if (m_fallback_unwind_plan_sp.get() == nullptr)
- return true;
-
-
- // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide this isn't
- // working, we need to restore.
- // We'll also need to save & restore the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'.
- UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
- addr_t old_cfa = m_cfa;
-
- m_registers.clear();
-
- m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
-
- UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
-
- if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
- {
- addr_t new_cfa;
- if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, 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;
-
- if (SavedLocationForRegister (pc_regnum.GetAsKind (eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB));
- if (reg_info)
- {
- RegisterValue reg_value;
- if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value))
- {
- new_caller_pc_value = reg_value.GetAsUInt64();
- }
- }
- }
+ if (new_caller_pc_value == LLDB_INVALID_ADDRESS) {
+ UnwindLogMsg("failed to get a pc value for the caller frame with the "
+ "fallback unwind plan");
+ 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 != 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 (new_caller_pc_value == LLDB_INVALID_ADDRESS)
- {
- UnwindLogMsg ("failed to get a pc value for the caller frame with the fallback unwind plan");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
- return false;
- }
+ UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' "
+ "because UnwindPlan '%s' failed.",
+ m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
+ original_full_unwind_plan_sp->GetSourceName().GetCString());
- 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;
- }
- }
+ // We've copied the fallback unwind plan into the full - now clear the
+ // fallback.
+ m_fallback_unwind_plan_sp.reset();
+ }
- UnwindLogMsg ("trying to unwind from this function with the UnwindPlan '%s' because UnwindPlan '%s' failed.",
- m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
- original_full_unwind_plan_sp->GetSourceName().GetCString());
+ return true;
+}
- // We've copied the fallback unwind plan into the full - now clear the fallback.
- m_fallback_unwind_plan_sp.reset();
- }
+bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
+ if (m_fallback_unwind_plan_sp.get() == NULL)
+ return false;
- return true;
-}
+ if (m_full_unwind_plan_sp.get() == NULL)
+ return false;
-bool
-RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan ()
-{
- if (m_fallback_unwind_plan_sp.get() == NULL)
- return false;
+ if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
+ m_full_unwind_plan_sp->GetSourceName() ==
+ m_fallback_unwind_plan_sp->GetSourceName()) {
+ return false;
+ }
- if (m_full_unwind_plan_sp.get() == NULL)
- return false;
+ UnwindPlan::RowSP active_row =
+ m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
- if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get()
- || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName())
- {
- return false;
+ if (active_row &&
+ active_row->GetCFAValue().GetValueType() !=
+ UnwindPlan::Row::CFAValue::unspecified) {
+ addr_t new_cfa;
+ if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row, 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;
}
- UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
-
- if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
- {
- addr_t new_cfa;
- if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, 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;
- }
-
- m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
- m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
+ m_fallback_unwind_plan_sp.reset();
- m_registers.clear();
+ m_registers.clear();
- m_cfa = new_cfa;
+ m_cfa = new_cfa;
- UnwindLogMsg ("switched unconditionally to the fallback unwindplan %s", m_full_unwind_plan_sp->GetSourceName().GetCString());
- return true;
- }
- return false;
+ UnwindLogMsg("switched unconditionally to the fallback unwindplan %s",
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind,
- const UnwindPlan::RowSP &row,
- addr_t &cfa_value)
-{
- RegisterValue reg_value;
-
- cfa_value = LLDB_INVALID_ADDRESS;
- addr_t cfa_reg_contents;
-
- switch (row->GetCFAValue().GetValueType())
- {
- case UnwindPlan::Row::CFAValue::isRegisterDereferenced:
- {
- RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
- if (ReadGPRValue (cfa_reg, cfa_reg_contents))
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (cfa_reg.GetAsKind (eRegisterKindLLDB));
- RegisterValue reg_value;
- if (reg_info)
- {
- Error error = ReadRegisterValueFromMemory(reg_info,
- cfa_reg_contents,
- reg_info->byte_size,
- reg_value);
- if (error.Success ())
- {
- cfa_value = 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);
- return true;
- }
- else
- {
- UnwindLogMsg ("Tried to deref reg %s (%d) [0x%" PRIx64 "] but memory read failed.",
- cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
- cfa_reg_contents);
- }
- }
- }
- break;
- }
- case UnwindPlan::Row::CFAValue::isRegisterPlusOffset:
- {
- RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
- if (ReadGPRValue (cfa_reg, cfa_reg_contents))
- {
- if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1)
- {
- UnwindLogMsg ("Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
- cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
- cfa_reg_contents);
- cfa_reg_contents = LLDB_INVALID_ADDRESS;
- return false;
- }
- cfa_value = cfa_reg_contents + row->GetCFAValue().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());
- return true;
- }
- break;
+bool RegisterContextLLDB::ReadCFAValueForRow(
+ lldb::RegisterKind row_register_kind, const UnwindPlan::RowSP &row,
+ addr_t &cfa_value) {
+ RegisterValue reg_value;
+
+ cfa_value = LLDB_INVALID_ADDRESS;
+ addr_t cfa_reg_contents;
+
+ switch (row->GetCFAValue().GetValueType()) {
+ case UnwindPlan::Row::CFAValue::isRegisterDereferenced: {
+ RegisterNumber cfa_reg(m_thread, row_register_kind,
+ row->GetCFAValue().GetRegisterNumber());
+ if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
+ RegisterValue reg_value;
+ if (reg_info) {
+ Error error = ReadRegisterValueFromMemory(
+ reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
+ if (error.Success()) {
+ cfa_value = 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);
+ return true;
+ } else {
+ UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64
+ "] but memory read failed.",
+ cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
+ cfa_reg_contents);
}
- case UnwindPlan::Row::CFAValue::isDWARFExpression:
- {
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- DataExtractor dwarfdata (row->GetCFAValue().GetDWARFExpressionBytes(),
- row->GetCFAValue().GetDWARFExpressionLength(),
- process->GetByteOrder(), process->GetAddressByteSize());
- ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr (opcode_ctx,
- dwarfdata,
- nullptr,
- 0,
- row->GetCFAValue().GetDWARFExpressionLength());
- dwarfexpr.SetRegisterKind (row_register_kind);
- Value result;
- Error error;
- if (dwarfexpr.Evaluate (&exe_ctx, nullptr, nullptr, this, 0, nullptr, nullptr, result, &error))
- {
- cfa_value = result.GetScalar().ULongLong();
-
- UnwindLogMsg ("CFA value set by DWARF expression is 0x%" PRIx64, cfa_value);
- return true;
- }
- UnwindLogMsg ("Failed to set CFA value via DWARF expression: %s", error.AsCString());
- break;
- }
- default:
+ }
+ }
+ break;
+ }
+ case UnwindPlan::Row::CFAValue::isRegisterPlusOffset: {
+ RegisterNumber cfa_reg(m_thread, row_register_kind,
+ row->GetCFAValue().GetRegisterNumber());
+ if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
+ if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
+ cfa_reg_contents == 1) {
+ UnwindLogMsg(
+ "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
+ cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
+ cfa_reg_contents);
+ cfa_reg_contents = LLDB_INVALID_ADDRESS;
return false;
- }
+ }
+ cfa_value = cfa_reg_contents + row->GetCFAValue().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());
+ return true;
+ }
+ break;
+ }
+ case UnwindPlan::Row::CFAValue::isDWARFExpression: {
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ DataExtractor dwarfdata(row->GetCFAValue().GetDWARFExpressionBytes(),
+ row->GetCFAValue().GetDWARFExpressionLength(),
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+ ModuleSP opcode_ctx;
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
+ row->GetCFAValue().GetDWARFExpressionLength());
+ dwarfexpr.SetRegisterKind(row_register_kind);
+ Value result;
+ Error error;
+ if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
+ nullptr, result, &error)) {
+ cfa_value = result.GetScalar().ULongLong();
+
+ UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
+ cfa_value);
+ return true;
+ }
+ UnwindLogMsg("Failed to set CFA value via DWARF expression: %s",
+ error.AsCString());
+ break;
+ }
+ default:
return false;
+ }
+ return false;
}
-// Retrieve a general purpose register value for THIS frame, as saved by the NEXT frame, i.e. the frame that
+// Retrieve a general purpose register value for THIS frame, as saved by the
+// NEXT frame, i.e. the frame that
// this frame called. e.g.
//
// foo () { }
@@ -1866,278 +1859,241 @@ RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind,
// frame 0 - foo
// frame 1 - bar
// frame 2 - main
-// and this RegisterContext is for frame 1 (bar) - if we want to get the pc value for frame 1, we need to ask
+// and this RegisterContext is for frame 1 (bar) - if we want to get the pc
+// value for frame 1, we need to ask
// where frame 0 (the "next" frame) saved that and retrieve the value.
-bool
-RegisterContextLLDB::ReadGPRValue (lldb::RegisterKind register_kind, uint32_t regnum, addr_t &value)
-{
- if (!IsValid())
- return false;
-
- uint32_t lldb_regnum;
- if (register_kind == eRegisterKindLLDB)
- {
- lldb_regnum = regnum;
- }
- else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindLLDB, lldb_regnum))
- {
- return false;
- }
+bool RegisterContextLLDB::ReadGPRValue(lldb::RegisterKind register_kind,
+ uint32_t regnum, addr_t &value) {
+ if (!IsValid())
+ return false;
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
- RegisterValue reg_value;
- // if this is frame 0 (currently executing frame), get the requested reg contents from the actual thread registers
- if (IsFrameZero ())
- {
- if (m_thread.GetRegisterContext()->ReadRegister (reg_info, reg_value))
- {
- value = reg_value.GetAsUInt64();
- return true;
- }
- return false;
- }
+ uint32_t lldb_regnum;
+ if (register_kind == eRegisterKindLLDB) {
+ lldb_regnum = regnum;
+ } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
+ register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) {
+ return false;
+ }
- bool pc_register = false;
- uint32_t generic_regnum;
- if (register_kind == eRegisterKindGeneric
- && (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA))
- {
- pc_register = true;
- }
- else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindGeneric, generic_regnum)
- && (generic_regnum == LLDB_REGNUM_GENERIC_PC || generic_regnum == LLDB_REGNUM_GENERIC_RA))
- {
- pc_register = true;
- }
-
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, pc_register))
- {
- return false;
- }
- if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value))
- {
- value = reg_value.GetAsUInt64();
- return true;
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
+ RegisterValue reg_value;
+ // if this is frame 0 (currently executing frame), get the requested reg
+ // contents from the actual thread registers
+ if (IsFrameZero()) {
+ if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
+ value = reg_value.GetAsUInt64();
+ return true;
}
return false;
+ }
+
+ bool pc_register = false;
+ uint32_t generic_regnum;
+ if (register_kind == eRegisterKindGeneric &&
+ (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) {
+ pc_register = true;
+ } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
+ register_kind, regnum, eRegisterKindGeneric, generic_regnum) &&
+ (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+ generic_regnum == LLDB_REGNUM_GENERIC_RA)) {
+ pc_register = true;
+ }
+
+ lldb_private::UnwindLLDB::RegisterLocation regloc;
+ if (!m_parent_unwind.SearchForSavedLocationForRegister(
+ lldb_regnum, regloc, m_frame_number - 1, pc_register)) {
+ return false;
+ }
+ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
+ value = reg_value.GetAsUInt64();
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextLLDB::ReadGPRValue (const RegisterNumber &regnum, addr_t &value)
-{
- return ReadGPRValue (regnum.GetRegisterKind(), regnum.GetRegisterNumber(), value);
+bool RegisterContextLLDB::ReadGPRValue(const RegisterNumber &regnum,
+ addr_t &value) {
+ return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(),
+ value);
}
// Find the value of a register in THIS frame
-bool
-RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!IsValid())
- return false;
-
- const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);
-
- // If this is the 0th frame, hand this over to the live register context
- if (IsFrameZero ())
- {
- UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum);
- return m_thread.GetRegisterContext()->ReadRegister (reg_info, value);
- }
-
- bool is_pc_regnum = false;
- if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC
- || reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
- {
- is_pc_regnum = true;
- }
+bool RegisterContextLLDB::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ if (!IsValid())
+ return false;
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- // Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
- return false;
+ const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
+ UnwindLogMsgVerbose("looking for register saved location for reg %d",
+ lldb_regnum);
+
+ // If this is the 0th frame, hand this over to the live register context
+ if (IsFrameZero()) {
+ UnwindLogMsgVerbose("passing along to the live register context for reg %d",
+ lldb_regnum);
+ return m_thread.GetRegisterContext()->ReadRegister(reg_info, value);
+ }
+
+ bool is_pc_regnum = false;
+ if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC ||
+ reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) {
+ is_pc_regnum = true;
+ }
+
+ lldb_private::UnwindLLDB::RegisterLocation regloc;
+ // Find out where the NEXT frame saved THIS frame's register contents
+ if (!m_parent_unwind.SearchForSavedLocationForRegister(
+ lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
+ return false;
- return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);
+ return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
}
-bool
-RegisterContextLLDB::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value)
-{
- if (!IsValid())
- return false;
-
- const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);
-
- // If this is the 0th frame, hand this over to the live register context
- if (IsFrameZero ())
- {
- UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum);
- return m_thread.GetRegisterContext()->WriteRegister (reg_info, value);
- }
+bool RegisterContextLLDB::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ if (!IsValid())
+ return false;
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- // Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false))
- return false;
+ const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
+ UnwindLogMsgVerbose("looking for register saved location for reg %d",
+ lldb_regnum);
+
+ // If this is the 0th frame, hand this over to the live register context
+ if (IsFrameZero()) {
+ UnwindLogMsgVerbose("passing along to the live register context for reg %d",
+ lldb_regnum);
+ return m_thread.GetRegisterContext()->WriteRegister(reg_info, value);
+ }
+
+ lldb_private::UnwindLLDB::RegisterLocation regloc;
+ // Find out where the NEXT frame saved THIS frame's register contents
+ if (!m_parent_unwind.SearchForSavedLocationForRegister(
+ lldb_regnum, regloc, m_frame_number - 1, false))
+ return false;
- return WriteRegisterValueToRegisterLocation (regloc, reg_info, value);
+ return WriteRegisterValueToRegisterLocation(regloc, reg_info, value);
}
// Don't need to implement this one
-bool
-RegisterContextLLDB::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextLLDB::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) {
+ return false;
}
// Don't need to implement this one
-bool
-RegisterContextLLDB::WriteAllRegisterValues (const lldb::DataBufferSP& data_sp)
-{
- return false;
+bool RegisterContextLLDB::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
// Retrieve the pc value for THIS from
-bool
-RegisterContextLLDB::GetCFA (addr_t& cfa)
-{
- if (!IsValid())
- {
- return false;
- }
- if (m_cfa == LLDB_INVALID_ADDRESS)
- {
- return false;
- }
- cfa = m_cfa;
- return true;
+bool RegisterContextLLDB::GetCFA(addr_t &cfa) {
+ if (!IsValid()) {
+ return false;
+ }
+ if (m_cfa == LLDB_INVALID_ADDRESS) {
+ return false;
+ }
+ cfa = m_cfa;
+ return true;
}
-
-RegisterContextLLDB::SharedPtr
-RegisterContextLLDB::GetNextFrame () const
-{
- RegisterContextLLDB::SharedPtr regctx;
- if (m_frame_number == 0)
- return regctx;
- return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number - 1);
+RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetNextFrame() const {
+ RegisterContextLLDB::SharedPtr regctx;
+ if (m_frame_number == 0)
+ return regctx;
+ return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1);
}
-RegisterContextLLDB::SharedPtr
-RegisterContextLLDB::GetPrevFrame () const
-{
- RegisterContextLLDB::SharedPtr regctx;
- return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number + 1);
+RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetPrevFrame() const {
+ RegisterContextLLDB::SharedPtr regctx;
+ return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1);
}
// Retrieve the address of the start of the function of THIS frame
-bool
-RegisterContextLLDB::GetStartPC (addr_t& start_pc)
-{
- if (!IsValid())
- return false;
+bool RegisterContextLLDB::GetStartPC(addr_t &start_pc) {
+ if (!IsValid())
+ return false;
- if (!m_start_pc.IsValid())
- {
- return ReadPC (start_pc);
- }
- start_pc = m_start_pc.GetLoadAddress (CalculateTarget().get());
- return true;
+ if (!m_start_pc.IsValid()) {
+ return ReadPC(start_pc);
+ }
+ start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get());
+ return true;
}
// Retrieve the current pc value for THIS frame, as saved by the NEXT frame.
-bool
-RegisterContextLLDB::ReadPC (addr_t& pc)
-{
- if (!IsValid())
- return false;
-
- bool above_trap_handler = false;
- if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame())
- above_trap_handler = true;
+bool RegisterContextLLDB::ReadPC(addr_t &pc) {
+ if (!IsValid())
+ return false;
- if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc))
- {
- // A pc value of 0 or 1 is impossible in the middle of the stack -- it indicates the end of a stack walk.
- // On the currently executing frame (or such a frame interrupted asynchronously by sigtramp et al) this may
- // occur if code has jumped through a NULL pointer -- we want to be able to unwind past that frame to help
- // find the bug.
-
- if (m_all_registers_available == false
- && above_trap_handler == false
- && (pc == 0 || pc == 1))
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- else
- {
- return false;
- }
+ bool above_trap_handler = false;
+ if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
+ GetNextFrame()->IsTrapHandlerFrame())
+ above_trap_handler = true;
+
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
+ // A pc value of 0 or 1 is impossible in the middle of the stack -- it
+ // indicates the end of a stack walk.
+ // On the currently executing frame (or such a frame interrupted
+ // asynchronously by sigtramp et al) this may
+ // occur if code has jumped through a NULL pointer -- we want to be able to
+ // unwind past that frame to help
+ // find the bug.
+
+ if (m_all_registers_available == false && above_trap_handler == false &&
+ (pc == 0 || pc == 1)) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
}
-
-void
-RegisterContextLLDB::UnwindLogMsg (const char *fmt, ...)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log)
- {
- va_list args;
- va_start (args, fmt);
-
- char *logmsg;
- if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
- {
- if (logmsg)
- free (logmsg);
- va_end (args);
- return;
- }
- va_end (args);
-
- log->Printf ("%*sth%d/fr%u %s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
- logmsg);
- free (logmsg);
- }
+void RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log) {
+ va_list args;
+ va_start(args, fmt);
+
+ char *logmsg;
+ if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == NULL) {
+ if (logmsg)
+ free(logmsg);
+ va_end(args);
+ return;
+ }
+ va_end(args);
+
+ log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
+ "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ free(logmsg);
+ }
}
-void
-RegisterContextLLDB::UnwindLogMsgVerbose (const char *fmt, ...)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log && log->GetVerbose())
- {
- va_list args;
- va_start (args, fmt);
-
- char *logmsg;
- if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
- {
- if (logmsg)
- free (logmsg);
- va_end (args);
- return;
- }
- va_end (args);
-
- log->Printf ("%*sth%d/fr%u %s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
- logmsg);
- free (logmsg);
- }
+void RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log && log->GetVerbose()) {
+ va_list args;
+ va_start(args, fmt);
+
+ char *logmsg;
+ if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == NULL) {
+ if (logmsg)
+ free(logmsg);
+ va_end(args);
+ return;
+ }
+ va_end(args);
+
+ log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
+ "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ free(logmsg);
+ }
}
-
-
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.h b/source/Plugins/Process/Utility/RegisterContextLLDB.h
index 68dca3d4965f..cb22eedd560a 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextLLDB.h --------------------------------------------*- C++ -*-===//
+//===-- RegisterContextLLDB.h --------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,253 +17,247 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Symbol/UnwindPlan.h"
+#include "UnwindLLDB.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/RegisterNumber.h"
-#include "UnwindLLDB.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
class UnwindLLDB;
-class RegisterContextLLDB : public lldb_private::RegisterContext
-{
+class RegisterContextLLDB : public lldb_private::RegisterContext {
public:
- typedef std::shared_ptr<RegisterContextLLDB> SharedPtr;
+ typedef std::shared_ptr<RegisterContextLLDB> SharedPtr;
- RegisterContextLLDB (lldb_private::Thread &thread,
- const SharedPtr& next_frame,
- lldb_private::SymbolContext& sym_ctx,
- uint32_t frame_number, lldb_private::UnwindLLDB& unwind_lldb);
+ RegisterContextLLDB(lldb_private::Thread &thread, const SharedPtr &next_frame,
+ lldb_private::SymbolContext &sym_ctx,
+ uint32_t frame_number,
+ lldb_private::UnwindLLDB &unwind_lldb);
- ~RegisterContextLLDB() override = default;
+ ~RegisterContextLLDB() override = default;
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- bool
- IsValid () const;
+ bool IsValid() const;
- bool
- IsTrapHandlerFrame () const;
+ bool IsTrapHandlerFrame() const;
- bool
- GetCFA (lldb::addr_t& cfa);
+ bool GetCFA(lldb::addr_t &cfa);
- bool
- GetStartPC (lldb::addr_t& start_pc);
+ bool GetStartPC(lldb::addr_t &start_pc);
- bool
- ReadPC (lldb::addr_t& start_pc);
+ bool ReadPC(lldb::addr_t &start_pc);
private:
-
- enum FrameType
- {
- eNormalFrame,
- eTrapHandlerFrame,
- eDebuggerFrame, // a debugger inferior function call frame; we get caller's registers from debugger
- eSkipFrame, // The unwind resulted in a bogus frame but may get back on track so we don't want to give up yet
- eNotAValidFrame // this frame is invalid for some reason - most likely it is past the top (end) of the stack
- };
-
- // UnwindLLDB needs to pass around references to RegisterLocations
- friend class UnwindLLDB;
-
- // Returns true if we have an unwind loop -- the same stack frame unwinding
- // multiple times.
- bool
- CheckIfLoopingStack ();
-
- // Indicates whether this frame is frame zero -- the currently
- // executing frame -- or not.
- bool
- IsFrameZero () const;
-
- void
- InitializeZerothFrame ();
-
- void
- InitializeNonZerothFrame();
-
- SharedPtr
- GetNextFrame () const;
-
- SharedPtr
- GetPrevFrame () const;
-
- // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've got one bogus frame at frame #1.
- // There is a good chance we'll get back on track if we follow the frame pointer chain (or whatever is appropriate
- // on this ABI) so we allow one invalid frame to be in the stack. Ideally we'll mark this frame specially at some
- // point and indicate to the user that the unwinder had a hiccup. Often when this happens we will miss a frame of
- // the program's actual stack in the unwind and we want to flag that for the user somehow.
- bool
- IsSkipFrame () const;
-
- //------------------------------------------------------------------
- /// Determines if a SymbolContext is a trap handler or not
- ///
- /// Given a SymbolContext, determines if this is a trap handler function
- /// aka asynchronous signal handler.
- ///
- /// @return
- /// Returns true if the SymbolContext is a trap handler.
- //------------------------------------------------------------------
- bool
- IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const;
-
- // Provide a location for where THIS function saved the CALLER's register value
- // Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this
- // function didn't modify/use.
- //
- // The RegisterLocation type may be set to eRegisterNotAvailable -- this will happen for a volatile register
- // being queried mid-stack. Instead of floating frame 0's contents of that register up the stack (which may
- // or may not be the value of that reg when the function was executing), we won't return any value.
- //
- // If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested
- // stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
- // as the requesting frame's.
- lldb_private::UnwindLLDB::RegisterSearchResult
- SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc);
-
- bool
- ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool
- WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- //------------------------------------------------------------------
- /// If the unwind has to the caller frame has failed, try something else
- ///
- /// If lldb is using an assembly language based UnwindPlan for a frame and
- /// the unwind to the caller frame fails, try falling back to a generic
- /// UnwindPlan (architecture default unwindplan) to see if that might work
- /// better. This is mostly helping to work around problems where the
- /// assembly language inspection fails on hand-written assembly code.
- ///
- /// @return
- /// Returns true if a fallback unwindplan was found & was installed.
- //------------------------------------------------------------------
- bool
- TryFallbackUnwindPlan ();
-
- //------------------------------------------------------------------
- /// Switch to the fallback unwind plan unconditionally without any safety
- /// checks that it is providing better results than the normal unwind plan.
- ///
- /// The only time it is valid to call this method is if the full unwindplan is
- /// found to be fundamentally incorrect/impossible.
- ///
- /// Returns true if it was able to install the fallback unwind plan.
- //------------------------------------------------------------------
- bool
- ForceSwitchToFallbackUnwindPlan ();
-
- // Get the contents of a general purpose (address-size) register for this frame
- // (usually retrieved from the next frame)
- bool
- ReadGPRValue (lldb::RegisterKind register_kind, uint32_t regnum, lldb::addr_t &value);
-
- 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);
-
- lldb::UnwindPlanSP
- GetFastUnwindPlanForFrame ();
-
- lldb::UnwindPlanSP
- GetFullUnwindPlanForFrame ();
-
- void
- UnwindLogMsg (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-
- void
- UnwindLogMsgVerbose (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-
- bool
- IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset);
-
- lldb_private::Thread& m_thread;
-
- ///
- // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
- // i.e. where THIS frame saved them
- ///
-
- lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL
- lldb::UnwindPlanSP m_full_unwind_plan_sp;
- lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
-
- bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs?
- int m_frame_type; // enum FrameType
-
- lldb::addr_t m_cfa;
- lldb_private::Address m_start_pc;
- lldb_private::Address m_current_pc;
-
- int m_current_offset; // how far into the function we've executed; -1 if unknown
- // 0 if no instructions have been executed yet.
-
- int m_current_offset_backed_up_one; // how far into the function we've executed; -1 if unknown
- // 0 if no instructions have been executed yet.
- // On architectures where the return address on the stack points
- // to the instruction after the CALL, this value will have 1
- // subtracted from it. Else a function that ends in a CALL will
- // have an offset pointing into the next function's address range.
- // m_current_pc has the actual address of the "current" pc.
-
- lldb_private::SymbolContext& m_sym_ctx;
- bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx
-
- uint32_t m_frame_number; // What stack frame this RegisterContext is
-
- std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> m_registers; // where to find reg values for this frame
-
- lldb_private::UnwindLLDB& m_parent_unwind; // The UnwindLLDB that is creating this RegisterContextLLDB
-
- //------------------------------------------------------------------
- // For RegisterContextLLDB only
- //------------------------------------------------------------------
-
- DISALLOW_COPY_AND_ASSIGN (RegisterContextLLDB);
+ enum FrameType {
+ eNormalFrame,
+ eTrapHandlerFrame,
+ eDebuggerFrame, // a debugger inferior function call frame; we get caller's
+ // registers from debugger
+ eSkipFrame, // The unwind resulted in a bogus frame but may get back on
+ // track so we don't want to give up yet
+ eNotAValidFrame // this frame is invalid for some reason - most likely it is
+ // past the top (end) of the stack
+ };
+
+ // UnwindLLDB needs to pass around references to RegisterLocations
+ friend class UnwindLLDB;
+
+ // Returns true if we have an unwind loop -- the same stack frame unwinding
+ // multiple times.
+ bool CheckIfLoopingStack();
+
+ // Indicates whether this frame is frame zero -- the currently
+ // executing frame -- or not.
+ bool IsFrameZero() const;
+
+ void InitializeZerothFrame();
+
+ void InitializeNonZerothFrame();
+
+ SharedPtr GetNextFrame() const;
+
+ SharedPtr GetPrevFrame() const;
+
+ // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've
+ // got one bogus frame at frame #1.
+ // There is a good chance we'll get back on track if we follow the frame
+ // pointer chain (or whatever is appropriate
+ // on this ABI) so we allow one invalid frame to be in the stack. Ideally
+ // we'll mark this frame specially at some
+ // point and indicate to the user that the unwinder had a hiccup. Often when
+ // this happens we will miss a frame of
+ // the program's actual stack in the unwind and we want to flag that for the
+ // user somehow.
+ bool IsSkipFrame() const;
+
+ //------------------------------------------------------------------
+ /// Determines if a SymbolContext is a trap handler or not
+ ///
+ /// Given a SymbolContext, determines if this is a trap handler function
+ /// aka asynchronous signal handler.
+ ///
+ /// @return
+ /// Returns true if the SymbolContext is a trap handler.
+ //------------------------------------------------------------------
+ bool IsTrapHandlerSymbol(lldb_private::Process *process,
+ const lldb_private::SymbolContext &m_sym_ctx) const;
+
+ // Provide a location for where THIS function saved the CALLER's register
+ // value
+ // Or a frame "below" this one saved it, i.e. a function called by this one,
+ // preserved a register that this
+ // function didn't modify/use.
+ //
+ // The RegisterLocation type may be set to eRegisterNotAvailable -- this will
+ // happen for a volatile register
+ // being queried mid-stack. Instead of floating frame 0's contents of that
+ // register up the stack (which may
+ // or may not be the value of that reg when the function was executing), we
+ // won't return any value.
+ //
+ // If a non-volatile register (a "preserved" register) is requested mid-stack
+ // and no frames "below" the requested
+ // stack have saved the register anywhere, it is safe to assume that frame 0's
+ // register values are still the same
+ // as the requesting frame's.
+ lldb_private::UnwindLLDB::RegisterSearchResult
+ SavedLocationForRegister(uint32_t lldb_regnum,
+ lldb_private::UnwindLLDB::RegisterLocation &regloc);
+
+ bool ReadRegisterValueFromRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
+
+ bool WriteRegisterValueToRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
+
+ //------------------------------------------------------------------
+ /// If the unwind has to the caller frame has failed, try something else
+ ///
+ /// If lldb is using an assembly language based UnwindPlan for a frame and
+ /// the unwind to the caller frame fails, try falling back to a generic
+ /// UnwindPlan (architecture default unwindplan) to see if that might work
+ /// better. This is mostly helping to work around problems where the
+ /// assembly language inspection fails on hand-written assembly code.
+ ///
+ /// @return
+ /// Returns true if a fallback unwindplan was found & was installed.
+ //------------------------------------------------------------------
+ bool TryFallbackUnwindPlan();
+
+ //------------------------------------------------------------------
+ /// Switch to the fallback unwind plan unconditionally without any safety
+ /// checks that it is providing better results than the normal unwind plan.
+ ///
+ /// The only time it is valid to call this method is if the full unwindplan is
+ /// found to be fundamentally incorrect/impossible.
+ ///
+ /// Returns true if it was able to install the fallback unwind plan.
+ //------------------------------------------------------------------
+ bool ForceSwitchToFallbackUnwindPlan();
+
+ // Get the contents of a general purpose (address-size) register for this
+ // frame
+ // (usually retrieved from the next frame)
+ bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum,
+ lldb::addr_t &value);
+
+ 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);
+
+ lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
+
+ lldb::UnwindPlanSP GetFullUnwindPlanForFrame();
+
+ void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
+ void UnwindLogMsgVerbose(const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+
+ bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp,
+ int &valid_pc_offset);
+
+ lldb_private::Thread &m_thread;
+
+ ///
+ // The following tell us how to retrieve the CALLER's register values (ie the
+ // "previous" frame, aka the frame above)
+ // i.e. where THIS frame saved them
+ ///
+
+ lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL
+ lldb::UnwindPlanSP m_full_unwind_plan_sp;
+ lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
+
+ bool m_all_registers_available; // Can we retrieve all regs or just
+ // nonvolatile regs?
+ int m_frame_type; // enum FrameType
+
+ lldb::addr_t m_cfa;
+ lldb_private::Address m_start_pc;
+ lldb_private::Address m_current_pc;
+
+ int m_current_offset; // how far into the function we've executed; -1 if
+ // unknown
+ // 0 if no instructions have been executed yet.
+
+ int m_current_offset_backed_up_one; // how far into the function we've
+ // executed; -1 if unknown
+ // 0 if no instructions have been executed yet.
+ // On architectures where the return address on the stack points
+ // to the instruction after the CALL, this value will have 1
+ // subtracted from it. Else a function that ends in a CALL will
+ // have an offset pointing into the next function's address range.
+ // m_current_pc has the actual address of the "current" pc.
+
+ lldb_private::SymbolContext &m_sym_ctx;
+ bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to
+ // use m_sym_ctx
+
+ uint32_t m_frame_number; // What stack frame this RegisterContext is
+
+ std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>
+ m_registers; // where to find reg values for this frame
+
+ lldb_private::UnwindLLDB &m_parent_unwind; // The UnwindLLDB that is creating
+ // this RegisterContextLLDB
+
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextLLDB);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
index a4d8738d79bf..afa105f25404 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
@@ -7,12 +7,12 @@
//
//===---------------------------------------------------------------------===//
+#include <cassert>
#include <stddef.h>
#include <vector>
-#include <cassert>
-#include "llvm/Support/Compiler.h"
#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
#include "RegisterContextLinux_arm.h"
@@ -20,14 +20,31 @@ using namespace lldb;
using namespace lldb_private;
// Based on RegisterContextDarwin_arm.cpp
-#define GPR_OFFSET(idx) ((idx) * 4)
-#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextLinux_arm::GPR))
-#define FPSCR_OFFSET (LLVM_EXTENSION offsetof (RegisterContextLinux_arm::FPU, fpscr) + sizeof (RegisterContextLinux_arm::GPR))
-#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU))
-#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextLinux_arm::DBG, reg) + sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU) + sizeof (RegisterContextLinux_arm::EXC)))
+#define GPR_OFFSET(idx) ((idx)*4)
+#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextLinux_arm::GPR))
+#define FPSCR_OFFSET \
+ (LLVM_EXTENSION offsetof(RegisterContextLinux_arm::FPU, fpscr) + \
+ sizeof(RegisterContextLinux_arm::GPR))
+#define EXC_OFFSET(idx) \
+ ((idx)*4 + sizeof(RegisterContextLinux_arm::GPR) + \
+ sizeof(RegisterContextLinux_arm::FPU))
+#define DBG_OFFSET(reg) \
+ ((LLVM_EXTENSION offsetof(RegisterContextLinux_arm::DBG, reg) + \
+ sizeof(RegisterContextLinux_arm::GPR) + \
+ sizeof(RegisterContextLinux_arm::FPU) + \
+ sizeof(RegisterContextLinux_arm::EXC)))
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextLinux_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU) + sizeof (RegisterContextLinux_arm::EXC))
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, sizeof(((RegisterContextLinux_arm::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ dbg_##reg##i }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextLinux_arm::GPR) + \
+ sizeof(RegisterContextLinux_arm::FPU) + \
+ sizeof(RegisterContextLinux_arm::EXC))
//-----------------------------------------------------------------------------
// Include RegisterInfos_arm to declare our g_register_infos_arm structure.
@@ -37,52 +54,43 @@ using namespace lldb_private;
#undef DECLARE_REGISTER_INFOS_ARM_STRUCT
static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr (const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return g_register_infos_arm;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return g_register_infos_arm;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm) / sizeof(g_register_infos_arm[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return static_cast<uint32_t>(sizeof(g_register_infos_arm) /
+ sizeof(g_register_infos_arm[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_arm::RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
+RegisterContextLinux_arm::RegisterContextLinux_arm(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
-size_t
-RegisterContextLinux_arm::GetGPRSize() const
-{
- return sizeof(struct RegisterContextLinux_arm::GPR);
+size_t RegisterContextLinux_arm::GetGPRSize() const {
+ return sizeof(struct RegisterContextLinux_arm::GPR);
}
const lldb_private::RegisterInfo *
-RegisterContextLinux_arm::GetRegisterInfo() const
-{
- return m_register_info_p;
+RegisterContextLinux_arm::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_arm::GetRegisterCount() const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_arm::GetRegisterCount() const {
+ return m_register_info_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm.h b/source/Plugins/Process/Utility/RegisterContextLinux_arm.h
index c3d41f686dcd..9065bc0e08d2 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_arm.h
@@ -10,66 +10,53 @@
#ifndef liblldb_RegisterContextLinux_arm_h_
#define liblldb_RegisterContextLinux_arm_h_
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextLinux_arm
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_arm : public lldb_private::RegisterInfoInterface {
public:
-
- struct GPR
- {
- uint32_t r[16]; // R0-R15
- uint32_t cpsr; // CPSR
- };
-
-
- struct QReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
- struct EXC
- {
- uint32_t exception;
- uint32_t fsr; /* Fault status */
- uint32_t far; /* Virtual Fault Address */
- };
-
- struct DBG
- {
- uint32_t bvr[16];
- uint32_t bcr[16];
- uint32_t wvr[16];
- uint32_t wcr[16];
- };
-
- RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
+ struct GPR {
+ uint32_t r[16]; // R0-R15
+ uint32_t cpsr; // CPSR
+ };
+
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+ struct EXC {
+ uint32_t exception;
+ uint32_t fsr; /* Fault status */
+ uint32_t far; /* Virtual Fault Address */
+ };
+
+ struct DBG {
+ uint32_t bvr[16];
+ uint32_t bcr[16];
+ uint32_t wvr[16];
+ uint32_t wcr[16];
+ };
+
+ RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
};
-#endif // liblldb_RegisterContextLinux_arm_h_
-
+#endif // liblldb_RegisterContextLinux_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp
deleted file mode 100644
index e65537af729a..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===-- RegisterContextLinux_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 <stddef.h>
-#include <vector>
-#include <cassert>
-
-#include "llvm/Support/Compiler.h"
-#include "lldb/lldb-defines.h"
-
-#include "RegisterContextLinux_arm64.h"
-
-// Based on RegisterContextDarwin_arm64.cpp
-#define GPR_OFFSET(idx) ((idx) * 8)
-#define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::GPR, reg))
-
-#define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextLinux_arm64::GPR))
-#define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::FPU, reg) + sizeof (RegisterContextLinux_arm64::GPR))
-
-#define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::EXC, reg) + sizeof (RegisterContextLinux_arm64::GPR) + sizeof (RegisterContextLinux_arm64::FPU))
-#define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::DBG, reg) + sizeof (RegisterContextLinux_arm64::GPR) + sizeof (RegisterContextLinux_arm64::FPU) + sizeof (RegisterContextLinux_arm64::EXC))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextLinux_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextLinux_arm64::GPR) + sizeof (RegisterContextLinux_arm64::FPU) + sizeof (RegisterContextLinux_arm64::EXC))
-
-
-//-----------------------------------------------------------------------------
-// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
-//-----------------------------------------------------------------------------
-#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
-#include "RegisterInfos_arm64.h"
-#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
-
-static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr (const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return g_register_infos_arm64;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
-}
-
-static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm64) / sizeof(g_register_infos_arm64[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
-}
-
-RegisterContextLinux_arm64::RegisterContextLinux_arm64(const lldb_private::ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
-
-size_t
-RegisterContextLinux_arm64::GetGPRSize() const
-{
- return sizeof(struct RegisterContextLinux_arm64::GPR);
-}
-
-const lldb_private::RegisterInfo *
-RegisterContextLinux_arm64::GetRegisterInfo() const
-{
- return m_register_info_p;
-}
-
-uint32_t
-RegisterContextLinux_arm64::GetRegisterCount() const
-{
- return m_register_info_count;
-}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.h b/source/Plugins/Process/Utility/RegisterContextLinux_arm64.h
deleted file mode 100644
index 3de94b862583..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- RegisterContextLinux_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_RegisterContextLinux_arm64_H_
-#define liblldb_RegisterContextLinux_arm64_H_
-
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
-
-class RegisterContextLinux_arm64
- : public lldb_private::RegisterInfoInterface
-{
-public:
- // based on RegisterContextDarwin_arm64.h
- struct GPR
- {
- uint64_t x[29]; // x0-x28
- uint64_t fp; // x29
- uint64_t lr; // x30
- uint64_t sp; // x31
- uint64_t pc; // pc
- uint32_t cpsr; // cpsr
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct EXC
- {
- uint64_t far; // Virtual Fault Address
- uint32_t esr; // Exception syndrome
- uint32_t exception; // number of arm exception token
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct DBG
- {
- uint64_t bvr[16];
- uint64_t bcr[16];
- uint64_t wvr[16];
- uint64_t wcr[16];
- uint64_t mdscr_el1;
- };
-
- RegisterContextLinux_arm64(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
-
-private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
-};
-
-#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
index e39beef42888..6563796db12c 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -7,87 +7,81 @@
//
//===---------------------------------------------------------------------===//
-#include "RegisterContextPOSIX_x86.h"
#include "RegisterContextLinux_i386.h"
+#include "RegisterContextPOSIX_x86.h"
using namespace lldb_private;
using namespace lldb;
-struct GPR
-{
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
- uint32_t esi;
- uint32_t edi;
- uint32_t ebp;
- uint32_t eax;
- uint32_t ds;
- uint32_t es;
- uint32_t fs;
- uint32_t gs;
- uint32_t orig_eax;
- uint32_t eip;
- uint32_t cs;
- uint32_t eflags;
- uint32_t esp;
- uint32_t ss;
+struct GPR {
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t ebp;
+ uint32_t eax;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+ uint32_t orig_eax;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t ss;
};
-struct FPR_i386
-{
- uint16_t fctrl; // FPU Control Word (fcw)
- uint16_t fstat; // FPU Status Word (fsw)
- uint8_t ftag; // FPU Tag Word (ftw)
- uint8_t reserved_1; // Reserved
- uint16_t fop; // Last Instruction Opcode (fop)
- union
- {
- struct
- {
- uint64_t fip; // Instruction Pointer
- uint64_t fdp; // Data Pointer
- } x86_64;
- struct
- {
- uint32_t fioff; // FPU IP Offset (fip)
- uint32_t fiseg; // FPU IP Selector (fcs)
- uint32_t fooff; // FPU Operand Pointer Offset (foo)
- uint32_t foseg; // FPU Operand Pointer Selector (fos)
- } i386_;// Added _ in the end to avoid error with gcc defining i386 in some cases
- } ptr;
- uint32_t mxcsr; // MXCSR Register State
- uint32_t mxcsrmask; // MXCSR Mask
- MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
- XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes
- uint32_t padding[56];
+struct FPR_i386 {
+ uint16_t fctrl; // FPU Control Word (fcw)
+ uint16_t fstat; // FPU Status Word (fsw)
+ uint8_t ftag; // FPU Tag Word (ftw)
+ uint8_t reserved_1; // Reserved
+ uint16_t fop; // Last Instruction Opcode (fop)
+ union {
+ struct {
+ uint64_t fip; // Instruction Pointer
+ uint64_t fdp; // Data Pointer
+ } x86_64;
+ struct {
+ uint32_t fioff; // FPU IP Offset (fip)
+ uint32_t fiseg; // FPU IP Selector (fcs)
+ uint32_t fooff; // FPU Operand Pointer Offset (foo)
+ uint32_t foseg; // FPU Operand Pointer Selector (fos)
+ } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
+ // cases
+ } ptr;
+ uint32_t mxcsr; // MXCSR Register State
+ uint32_t mxcsrmask; // MXCSR Mask
+ MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
+ XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes
+ uint32_t padding[56];
};
-struct UserArea
-{
- GPR regs; // General purpose registers.
- int32_t fpvalid; // True if FPU is being used.
- FPR_i386 i387; // FPU registers.
- uint32_t tsize; // Text segment size.
- uint32_t dsize; // Data segment size.
- uint32_t ssize; // Stack segment size.
- uint32_t start_code; // VM address of text.
- uint32_t start_stack; // VM address of stack bottom (top in rsp).
- int32_t signal; // Signal causing core dump.
- int32_t reserved; // Unused.
- uint32_t ar0; // Location of GPR's.
- uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this
- // has to be 32-bits even on 64-bit systems.
- uint32_t magic; // Identifier for core dumps.
- char u_comm[32]; // Command causing core dump.
- uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
+struct UserArea {
+ GPR regs; // General purpose registers.
+ int32_t fpvalid; // True if FPU is being used.
+ FPR_i386 i387; // FPU registers.
+ uint32_t tsize; // Text segment size.
+ uint32_t dsize; // Data segment size.
+ uint32_t ssize; // Stack segment size.
+ uint32_t start_code; // VM address of text.
+ uint32_t start_stack; // VM address of stack bottom (top in rsp).
+ int32_t signal; // Signal causing core dump.
+ int32_t reserved; // Unused.
+ uint32_t ar0; // Location of GPR's.
+ uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this
+ // has to be 32-bits even on 64-bit systems.
+ uint32_t magic; // Identifier for core dumps.
+ char u_comm[32]; // Command causing core dump.
+ uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
};
-#define DR_SIZE sizeof(((UserArea*)NULL)->u_debugreg[0])
+#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0])
#define DR_0_OFFSET 0xFC
-#define DR_OFFSET(reg_index) \
- (DR_0_OFFSET + (reg_index * 4))
-#define FPR_SIZE(reg) sizeof(((FPR_i386*)NULL)->reg)
+#define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4))
+#define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg)
//---------------------------------------------------------------------------
// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
@@ -96,48 +90,48 @@ struct UserArea
#include "RegisterInfos_i386.h"
#undef DECLARE_REGISTER_INFOS_I386_STRUCT
-RegisterContextLinux_i386::RegisterContextLinux_i386(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
- RegisterInfo orig_ax = { "orig_eax", NULL, sizeof(((GPR*)NULL)->orig_eax), (LLVM_EXTENSION offsetof(GPR, orig_eax)), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL };
- d_register_infos.push_back(orig_ax);
+RegisterContextLinux_i386::RegisterContextLinux_i386(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {
+ RegisterInfo orig_ax = {"orig_eax",
+ NULL,
+ sizeof(((GPR *)NULL)->orig_eax),
+ (LLVM_EXTENSION offsetof(GPR, orig_eax)),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0};
+ d_register_infos.push_back(orig_ax);
}
-size_t
-RegisterContextLinux_i386::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextLinux_i386::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextLinux_i386::GetRegisterInfo() const
-{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- return g_register_infos_i386;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const {
+ switch (m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return g_register_infos_i386;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
-uint32_t
-RegisterContextLinux_i386::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
+uint32_t RegisterContextLinux_i386::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
+ sizeof(g_register_infos_i386[0]));
}
-uint32_t
-RegisterContextLinux_i386::GetUserRegisterCount () const
-{
- return static_cast<uint32_t> (k_num_user_registers_i386);
+uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const {
+ return static_cast<uint32_t>(k_num_user_registers_i386);
}
const std::vector<lldb_private::RegisterInfo> *
-RegisterContextLinux_i386::GetDynamicRegisterInfoP() const
-{
- return &d_register_infos;
+RegisterContextLinux_i386::GetDynamicRegisterInfoP() const {
+ return &d_register_infos;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
index 6c4768f49ac1..fbf803789cc1 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -12,29 +12,23 @@
#include "RegisterInfoInterface.h"
-class RegisterContextLinux_i386
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_i386 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch);
+ RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
- const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const override;
+ const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const override;
private:
- std::vector<lldb_private::RegisterInfo> d_register_infos;
+ std::vector<lldb_private::RegisterInfo> d_register_infos;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
index 1b2281004d26..982eefea9ba6 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
@@ -7,8 +7,8 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
#include <stddef.h>
+#include <vector>
// For eh_frame and DWARF Register numbers
#include "RegisterContextLinux_mips.h"
@@ -29,48 +29,38 @@ using namespace lldb;
#include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-uint32_t
-GetUserRegisterInfoCount (bool msa_present)
-{
- if (msa_present)
- return static_cast<uint32_t> (k_num_user_registers_mips);
- return static_cast<uint32_t> (k_num_user_registers_mips - k_num_msa_registers_mips);
+uint32_t GetUserRegisterInfoCount(bool msa_present) {
+ if (msa_present)
+ return static_cast<uint32_t>(k_num_user_registers_mips);
+ return static_cast<uint32_t>(k_num_user_registers_mips -
+ k_num_msa_registers_mips);
}
-RegisterContextLinux_mips::RegisterContextLinux_mips(const ArchSpec &target_arch, bool msa_present) :
- RegisterInfoInterface(target_arch),
- m_user_register_count (GetUserRegisterInfoCount (msa_present))
-{
-}
+RegisterContextLinux_mips::RegisterContextLinux_mips(
+ const ArchSpec &target_arch, bool msa_present)
+ : RegisterInfoInterface(target_arch),
+ m_user_register_count(GetUserRegisterInfoCount(msa_present)) {}
-size_t
-RegisterContextLinux_mips::GetGPRSize() const
-{
- return sizeof(GPR_linux_mips);
+size_t RegisterContextLinux_mips::GetGPRSize() const {
+ return sizeof(GPR_linux_mips);
}
-const RegisterInfo *
-RegisterContextLinux_mips::GetRegisterInfo() const
-{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return g_register_infos_mips;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterInfo *RegisterContextLinux_mips::GetRegisterInfo() const {
+ switch (m_target_arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return g_register_infos_mips;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
-uint32_t
-RegisterContextLinux_mips::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_mips) / sizeof (g_register_infos_mips [0]));
+uint32_t RegisterContextLinux_mips::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
+ sizeof(g_register_infos_mips[0]));
}
-uint32_t
-RegisterContextLinux_mips::GetUserRegisterCount () const
-{
- return static_cast<uint32_t> (m_user_register_count);
+uint32_t RegisterContextLinux_mips::GetUserRegisterCount() const {
+ return static_cast<uint32_t>(m_user_register_count);
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
index c0bd5ad4f4f9..cba4ee6cd2b0 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
@@ -10,29 +10,24 @@
#ifndef liblldb_RegisterContextLinux_mips_H_
#define liblldb_RegisterContextLinux_mips_H_
-#include "lldb/lldb-private.h"
#include "RegisterInfoInterface.h"
+#include "lldb/lldb-private.h"
-class RegisterContextLinux_mips
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_mips : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_mips(const lldb_private::ArchSpec &target_arch, bool msa_present = true);
+ RegisterContextLinux_mips(const lldb_private::ArchSpec &target_arch,
+ bool msa_present = true);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
private:
- uint32_t m_user_register_count;
+ uint32_t m_user_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
index f2871e3b7352..c40f69492624 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
@@ -7,10 +7,10 @@
//
//===---------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
-#include <vector>
#include <stddef.h>
+#include <vector>
// For eh_frame and DWARF Register numbers
#include "RegisterContextLinux_mips64.h"
@@ -25,7 +25,8 @@ using namespace lldb;
using namespace lldb_private;
//---------------------------------------------------------------------------
-// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 structure.
+// Include RegisterInfos_mips64 to declare our g_register_infos_mips64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
#define LINUX_MIPS64
@@ -40,91 +41,79 @@ using namespace lldb_private;
#include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-static const RegisterInfo *
-GetRegisterInfoPtr (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return g_register_infos_mips64;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return g_register_infos_mips;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return g_register_infos_mips64;
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return g_register_infos_mips;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-static uint32_t
-GetRegisterInfoCount (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return static_cast<uint32_t> (sizeof (g_register_infos_mips) / sizeof (g_register_infos_mips [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
+ sizeof(g_register_infos_mips64[0]));
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
+ sizeof(g_register_infos_mips[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-uint32_t
-GetUserRegisterInfoCount (const ArchSpec &target_arch, bool msa_present)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- if (msa_present)
- return static_cast<uint32_t> (k_num_user_registers_mips);
- return static_cast<uint32_t> (k_num_user_registers_mips - k_num_msa_registers_mips);
- case llvm::Triple::mips64el:
- case llvm::Triple::mips64:
- if (msa_present)
- return static_cast<uint32_t> (k_num_user_registers_mips64);
- return static_cast<uint32_t> (k_num_user_registers_mips64 - k_num_msa_registers_mips64);
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch,
+ bool msa_present) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ if (msa_present)
+ return static_cast<uint32_t>(k_num_user_registers_mips);
+ return static_cast<uint32_t>(k_num_user_registers_mips -
+ k_num_msa_registers_mips);
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips64:
+ if (msa_present)
+ return static_cast<uint32_t>(k_num_user_registers_mips64);
+ return static_cast<uint32_t>(k_num_user_registers_mips64 -
+ k_num_msa_registers_mips64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_mips64::RegisterContextLinux_mips64(const ArchSpec &target_arch, bool msa_present) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (GetRegisterInfoPtr (target_arch)),
- m_register_info_count (GetRegisterInfoCount (target_arch)),
- m_user_register_count (GetUserRegisterInfoCount (target_arch, msa_present))
-{
-}
+RegisterContextLinux_mips64::RegisterContextLinux_mips64(
+ const ArchSpec &target_arch, bool msa_present)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)),
+ m_user_register_count(
+ GetUserRegisterInfoCount(target_arch, msa_present)) {}
-size_t
-RegisterContextLinux_mips64::GetGPRSize() const
-{
- return sizeof(GPR_linux_mips);
+size_t RegisterContextLinux_mips64::GetGPRSize() const {
+ return sizeof(GPR_linux_mips);
}
-const RegisterInfo *
-RegisterContextLinux_mips64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextLinux_mips64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_mips64::GetRegisterCount () const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_mips64::GetRegisterCount() const {
+ return m_register_info_count;
}
-uint32_t
-RegisterContextLinux_mips64::GetUserRegisterCount () const
-{
- return m_user_register_count;
+uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
+ return m_user_register_count;
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
index 843328c92e43..9669b0d84997 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
@@ -7,36 +7,31 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
#ifndef liblldb_RegisterContextLinux_mips64_H_
#define liblldb_RegisterContextLinux_mips64_H_
-#include "lldb/lldb-private.h"
#include "RegisterInfoInterface.h"
+#include "lldb/lldb-private.h"
-class RegisterContextLinux_mips64
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_mips64 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch, bool msa_present = true);
+ RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch,
+ bool msa_present = true);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
- uint32_t m_user_register_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
index 9aef1e9830e2..5a7f5a125246 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "RegisterContextPOSIX_s390x.h"
#include "RegisterContextLinux_s390x.h"
+#include "RegisterContextPOSIX_s390x.h"
using namespace lldb_private;
using namespace lldb;
@@ -20,79 +20,58 @@ using namespace lldb;
#include "RegisterInfos_s390x.h"
#undef DECLARE_REGISTER_INFOS_S390X_STRUCT
-static const RegisterInfo *
-GetRegisterInfoPtr(const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return g_register_infos_s390x;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return g_register_infos_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-static uint32_t
-GetRegisterInfoCount(const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return k_num_registers_s390x;
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return k_num_registers_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-static uint32_t
-GetUserRegisterInfoCount(const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return k_num_user_registers_s390x + k_num_linux_registers_s390x;
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return k_num_user_registers_s390x + k_num_linux_registers_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_s390x::RegisterContextLinux_s390x(const ArchSpec &target_arch)
+RegisterContextLinux_s390x::RegisterContextLinux_s390x(
+ const ArchSpec &target_arch)
: lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
m_register_info_count(GetRegisterInfoCount(target_arch)),
- m_user_register_count(GetUserRegisterInfoCount(target_arch))
-{
-}
+ m_user_register_count(GetUserRegisterInfoCount(target_arch)) {}
const std::vector<lldb_private::RegisterInfo> *
-RegisterContextLinux_s390x::GetDynamicRegisterInfoP() const
-{
- return &d_register_infos;
+RegisterContextLinux_s390x::GetDynamicRegisterInfoP() const {
+ return &d_register_infos;
}
-const RegisterInfo *
-RegisterContextLinux_s390x::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextLinux_s390x::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_s390x::GetRegisterCount() const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_s390x::GetRegisterCount() const {
+ return m_register_info_count;
}
-uint32_t
-RegisterContextLinux_s390x::GetUserRegisterCount() const
-{
- return m_user_register_count;
+uint32_t RegisterContextLinux_s390x::GetUserRegisterCount() const {
+ return m_user_register_count;
}
-size_t
-RegisterContextLinux_s390x::GetGPRSize() const
-{
- return 0;
-}
+size_t RegisterContextLinux_s390x::GetGPRSize() const { return 0; }
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
index bdc7f34f62e7..556cc2e12484 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
@@ -12,31 +12,26 @@
#include "RegisterInfoInterface.h"
-class RegisterContextLinux_s390x : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_s390x : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_s390x(const lldb_private::ArchSpec &target_arch);
+ RegisterContextLinux_s390x(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const override;
+ const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
- uint32_t m_user_register_count;
- std::vector<lldb_private::RegisterInfo> d_register_infos;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
+ std::vector<lldb_private::RegisterInfo> d_register_infos;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
index 78afe72fcfa9..526b3eca81ae 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -7,201 +7,191 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_x86.h"
-#include "RegisterContextLinux_i386.h"
#include "RegisterContextLinux_x86_64.h"
+#include "RegisterContextLinux_i386.h"
+#include "RegisterContextPOSIX_x86.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
-typedef struct _GPR
-{
- uint64_t r15;
- uint64_t r14;
- uint64_t r13;
- uint64_t r12;
- uint64_t rbp;
- uint64_t rbx;
- uint64_t r11;
- uint64_t r10;
- uint64_t r9;
- uint64_t r8;
- uint64_t rax;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rsi;
- uint64_t rdi;
- uint64_t orig_rax;
- uint64_t rip;
- uint64_t cs;
- uint64_t rflags;
- uint64_t rsp;
- uint64_t ss;
- uint64_t fs_base;
- uint64_t gs_base;
- uint64_t ds;
- uint64_t es;
- uint64_t fs;
- uint64_t gs;
+typedef struct _GPR {
+ uint64_t r15;
+ uint64_t r14;
+ uint64_t r13;
+ uint64_t r12;
+ uint64_t rbp;
+ uint64_t rbx;
+ uint64_t r11;
+ uint64_t r10;
+ uint64_t r9;
+ uint64_t r8;
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t orig_rax;
+ uint64_t rip;
+ uint64_t cs;
+ uint64_t rflags;
+ uint64_t rsp;
+ uint64_t ss;
+ uint64_t fs_base;
+ uint64_t gs_base;
+ uint64_t ds;
+ uint64_t es;
+ uint64_t fs;
+ uint64_t gs;
} GPR;
struct DBG {
- uint64_t dr[8];
+ uint64_t dr[8];
};
-struct UserArea
-{
- GPR gpr; // General purpose registers.
- int32_t fpvalid; // True if FPU is being used.
- int32_t pad0;
- FXSAVE fpr; // General purpose floating point registers (see FPR for extended register sets).
- uint64_t tsize; // Text segment size.
- uint64_t dsize; // Data segment size.
- uint64_t ssize; // Stack segment size.
- uint64_t start_code; // VM address of text.
- uint64_t start_stack; // VM address of stack bottom (top in rsp).
- int64_t signal; // Signal causing core dump.
- int32_t reserved; // Unused.
- int32_t pad1;
- uint64_t ar0; // Location of GPR's.
- FXSAVE* fpstate; // Location of FPR's.
- uint64_t magic; // Identifier for core dumps.
- char u_comm[32]; // Command causing core dump.
- DBG dbg; // Debug registers.
- uint64_t error_code; // CPU error code.
- uint64_t fault_address; // Control register CR3.
+struct UserArea {
+ GPR gpr; // General purpose registers.
+ int32_t fpvalid; // True if FPU is being used.
+ int32_t pad0;
+ FXSAVE fpr; // General purpose floating point registers (see FPR for extended
+ // register sets).
+ uint64_t tsize; // Text segment size.
+ uint64_t dsize; // Data segment size.
+ uint64_t ssize; // Stack segment size.
+ uint64_t start_code; // VM address of text.
+ uint64_t start_stack; // VM address of stack bottom (top in rsp).
+ int64_t signal; // Signal causing core dump.
+ int32_t reserved; // Unused.
+ int32_t pad1;
+ uint64_t ar0; // Location of GPR's.
+ FXSAVE *fpstate; // Location of FPR's.
+ uint64_t magic; // Identifier for core dumps.
+ char u_comm[32]; // Command causing core dump.
+ DBG dbg; // Debug registers.
+ uint64_t error_code; // CPU error code.
+ uint64_t fault_address; // Control register CR3.
};
-
-#define DR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, dbg) + \
- LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, dbg) + \
+ LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
//---------------------------------------------------------------------------
-// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
+// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_X86_64_STRUCT
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
-static std::vector<lldb_private::RegisterInfo>&
-GetPrivateRegisterInfoVector ()
-{
- static std::vector<lldb_private::RegisterInfo> g_register_infos;
- return g_register_infos;
+static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() {
+ static std::vector<lldb_private::RegisterInfo> g_register_infos;
+ return g_register_infos;
}
static const RegisterInfo *
-GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
-{
- std::vector<lldb_private::RegisterInfo> &g_register_infos = GetPrivateRegisterInfoVector ();
-
- // Allocate RegisterInfo only once
- if (g_register_infos.empty())
- {
- // Copy the register information from base class
- std::unique_ptr<RegisterContextLinux_i386> reg_interface(new RegisterContextLinux_i386 (arch));
- const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
- g_register_infos.insert(g_register_infos.end(), &base_info[0], &base_info[k_num_registers_i386]);
-
- //---------------------------------------------------------------------------
- // Include RegisterInfos_x86_64 to update the g_register_infos structure
- // with x86_64 offsets.
- //---------------------------------------------------------------------------
- #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- #include "RegisterInfos_x86_64.h"
- #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- }
-
- return &g_register_infos[0];
-}
+GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
+ std::vector<lldb_private::RegisterInfo> &g_register_infos =
+ GetPrivateRegisterInfoVector();
+
+ // Allocate RegisterInfo only once
+ if (g_register_infos.empty()) {
+ // Copy the register information from base class
+ std::unique_ptr<RegisterContextLinux_i386> reg_interface(
+ new RegisterContextLinux_i386(arch));
+ const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+ g_register_infos.insert(g_register_infos.end(), &base_info[0],
+ &base_info[k_num_registers_i386]);
-static const RegisterInfo *
-GetRegisterInfoPtr (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return GetRegisterInfo_i386 (target_arch);
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+//---------------------------------------------------------------------------
+// Include RegisterInfos_x86_64 to update the g_register_infos structure
+// with x86_64 offsets.
+//---------------------------------------------------------------------------
+#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+#include "RegisterInfos_x86_64.h"
+#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+ }
+
+ return &g_register_infos[0];
}
-static uint32_t
-GetRegisterInfoCount (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- {
- assert (!GetPrivateRegisterInfoVector ().empty () && "i386 register info not yet filled.");
- return static_cast<uint32_t> (GetPrivateRegisterInfoVector ().size ());
- }
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return GetRegisterInfo_i386(target_arch);
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-static uint32_t
-GetUserRegisterInfoCount (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return static_cast<uint32_t> (k_num_user_registers_i386);
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (k_num_user_registers_x86_64);
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86: {
+ assert(!GetPrivateRegisterInfoVector().empty() &&
+ "i386 register info not yet filled.");
+ return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size());
+ }
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (GetRegisterInfoPtr (target_arch)),
- m_register_info_count (GetRegisterInfoCount (target_arch)),
- m_user_register_count (GetUserRegisterInfoCount (target_arch))
-{
- RegisterInfo orig_ax = { "orig_rax", NULL, sizeof(((GPR*)NULL)->orig_rax), (LLVM_EXTENSION offsetof(GPR, orig_rax)), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL };
- d_register_infos.push_back(orig_ax);
+static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return static_cast<uint32_t>(k_num_user_registers_i386);
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(k_num_user_registers_x86_64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-size_t
-RegisterContextLinux_x86_64::GetGPRSize() const
-{
- return sizeof(GPR);
+RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)),
+ m_user_register_count(GetUserRegisterInfoCount(target_arch)) {
+ RegisterInfo orig_ax = {"orig_rax",
+ NULL,
+ sizeof(((GPR *)NULL)->orig_rax),
+ (LLVM_EXTENSION offsetof(GPR, orig_rax)),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0};
+ d_register_infos.push_back(orig_ax);
}
+size_t RegisterContextLinux_x86_64::GetGPRSize() const { return sizeof(GPR); }
+
const std::vector<lldb_private::RegisterInfo> *
-RegisterContextLinux_x86_64::GetDynamicRegisterInfoP() const
-{
- return &d_register_infos;
+RegisterContextLinux_x86_64::GetDynamicRegisterInfoP() const {
+ return &d_register_infos;
}
-const RegisterInfo *
-RegisterContextLinux_x86_64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextLinux_x86_64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_x86_64::GetRegisterCount () const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_x86_64::GetRegisterCount() const {
+ return m_register_info_count;
}
-uint32_t
-RegisterContextLinux_x86_64::GetUserRegisterCount () const
-{
- return m_user_register_count;
+uint32_t RegisterContextLinux_x86_64::GetUserRegisterCount() const {
+ return m_user_register_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
index ed0b7de9aae8..99a4cb736790 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -12,33 +12,26 @@
#include "RegisterInfoInterface.h"
-class RegisterContextLinux_x86_64
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_x86_64 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
- const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const override;
+ const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
- uint32_t m_user_register_count;
- std::vector<lldb_private::RegisterInfo> d_register_infos;
-
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
+ std::vector<lldb_private::RegisterInfo> d_register_infos;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
index a2ab67438b75..95b106d68bb3 100644
--- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
@@ -27,181 +27,143 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// RegisterContextMacOSXFrameBackchain constructor
//----------------------------------------------------------------------
-RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain
-(
- Thread &thread,
- uint32_t concrete_frame_idx,
- const UnwindMacOSXFrameBackchain::Cursor &cursor
-) :
- RegisterContext (thread, concrete_frame_idx),
- m_cursor (cursor),
- m_cursor_is_valid (true)
-{
-}
+RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
+ Thread &thread, uint32_t concrete_frame_idx,
+ const UnwindMacOSXFrameBackchain::Cursor &cursor)
+ : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
+ m_cursor_is_valid(true) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain()
-{
-}
+RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
-void
-RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters ()
-{
- m_cursor_is_valid = false;
+void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
+ m_cursor_is_valid = false;
}
-size_t
-RegisterContextMacOSXFrameBackchain::GetRegisterCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterCount();
+size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
+ return m_thread.GetRegisterContext()->GetRegisterCount();
}
const RegisterInfo *
-RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (size_t reg)
-{
- return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
+RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
+ return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
-size_t
-RegisterContextMacOSXFrameBackchain::GetRegisterSetCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterSetCount();
+size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
+ return m_thread.GetRegisterContext()->GetRegisterSetCount();
}
-
-
const RegisterSet *
-RegisterContextMacOSXFrameBackchain::GetRegisterSet (size_t reg_set)
-{
- return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
+RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
+ return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
}
+bool RegisterContextMacOSXFrameBackchain::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!m_cursor_is_valid)
+ return false;
+
+ uint64_t reg_value = LLDB_INVALID_ADDRESS;
+ switch (reg_info->kinds[eRegisterKindGeneric]) {
+ case LLDB_REGNUM_GENERIC_PC:
+ if (m_cursor.pc == LLDB_INVALID_ADDRESS)
+ return false;
+ reg_value = m_cursor.pc;
+ break;
-bool
-RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- if (!m_cursor_is_valid)
- return false;
-
- uint64_t reg_value = LLDB_INVALID_ADDRESS;
-
- switch (reg_info->kinds[eRegisterKindGeneric])
- {
- case LLDB_REGNUM_GENERIC_PC:
- if (m_cursor.pc == LLDB_INVALID_ADDRESS)
- return false;
- reg_value = m_cursor.pc;
- break;
-
- case LLDB_REGNUM_GENERIC_FP:
- if (m_cursor.fp == LLDB_INVALID_ADDRESS)
- return false;
- reg_value = m_cursor.fp;
- break;
-
- default:
- return false;
- }
-
- switch (reg_info->encoding)
- {
- case eEncodingInvalid:
- case eEncodingVector:
- break;
-
- case eEncodingUint:
- case eEncodingSint:
- value.SetUInt(reg_value, reg_info->byte_size);
+ case LLDB_REGNUM_GENERIC_FP:
+ if (m_cursor.fp == LLDB_INVALID_ADDRESS)
+ return false;
+ reg_value = m_cursor.fp;
+ break;
+
+ default:
+ return false;
+ }
+
+ switch (reg_info->encoding) {
+ case eEncodingInvalid:
+ case eEncodingVector:
+ break;
+
+ case eEncodingUint:
+ case eEncodingSint:
+ value.SetUInt(reg_value, reg_info->byte_size);
+ return true;
+
+ case eEncodingIEEE754:
+ switch (reg_info->byte_size) {
+ case sizeof(float):
+ if (sizeof(float) == sizeof(uint32_t)) {
+ value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
+ return true;
+ } else if (sizeof(float) == sizeof(uint64_t)) {
+ value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
return true;
+ }
+ break;
- case eEncodingIEEE754:
- switch (reg_info->byte_size)
- {
- case sizeof (float):
- if (sizeof (float) == sizeof(uint32_t))
- {
- value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
- return true;
- }
- else if (sizeof (float) == sizeof(uint64_t))
- {
- value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
- return true;
- }
- break;
-
- case sizeof (double):
- if (sizeof (double) == sizeof(uint32_t))
- {
- value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
- return true;
- }
- else if (sizeof (double) == sizeof(uint64_t))
- {
- value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
- return true;
- }
- break;
-
- // TOOD: need a better way to detect when "long double" types are
- // the same bytes size as "double"
-#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && \
- !defined(__mips__) && !defined(__powerpc__) && !defined(__ANDROID_NDK__)
- case sizeof (long double):
- if (sizeof (long double) == sizeof(uint32_t))
- {
- value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
- return true;
- }
- else if (sizeof (long double) == sizeof(uint64_t))
- {
- value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
- return true;
- }
- break;
+ case sizeof(double):
+ if (sizeof(double) == sizeof(uint32_t)) {
+ value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
+ return true;
+ } else if (sizeof(double) == sizeof(uint64_t)) {
+ value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
+ return true;
+ }
+ break;
+
+// TOOD: need a better way to detect when "long double" types are
+// the same bytes size as "double"
+#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \
+ !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \
+ !defined(__ANDROID__)
+ case sizeof(long double):
+ if (sizeof(long double) == sizeof(uint32_t)) {
+ value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
+ return true;
+ } else if (sizeof(long double) == sizeof(uint64_t)) {
+ value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
+ return true;
+ }
+ break;
#endif
- }
- break;
}
- return false;
+ break;
+ }
+ return false;
}
-bool
-RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- // Not supported yet. We could easily add support for this by remembering
- // the address of each entry (it would need to be part of the cursor)
- return false;
+bool RegisterContextMacOSXFrameBackchain::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ // Not supported yet. We could easily add support for this by remembering
+ // the address of each entry (it would need to be part of the cursor)
+ return false;
}
-bool
-RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- // libunwind frames can't handle this it doesn't always have all register
- // values. This call should only be called on frame zero anyway so there
- // shouldn't be any problem
- return false;
+bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ // libunwind frames can't handle this it doesn't always have all register
+ // values. This call should only be called on frame zero anyway so there
+ // shouldn't be any problem
+ return false;
}
-bool
-RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- // Since this class doesn't respond to "ReadAllRegisterValues()", it must
- // not have been the one that saved all the register values. So we just let
- // the thread's register context (the register context for frame zero) do
- // the writing.
- return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
+bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ // Since this class doesn't respond to "ReadAllRegisterValues()", it must
+ // not have been the one that saved all the register values. So we just let
+ // the thread's register context (the register context for frame zero) do
+ // the writing.
+ return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
}
-
uint32_t
-RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
+RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
+ kind, num);
}
-
diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
index 0ddadbed01e0..4f5816aa4909 100644
--- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
@@ -14,57 +14,48 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
#include "UnwindMacOSXFrameBackchain.h"
-class RegisterContextMacOSXFrameBackchain : public lldb_private::RegisterContext
-{
+class RegisterContextMacOSXFrameBackchain
+ : public lldb_private::RegisterContext {
public:
- RegisterContextMacOSXFrameBackchain (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- const UnwindMacOSXFrameBackchain::Cursor &cursor);
+ RegisterContextMacOSXFrameBackchain(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ const UnwindMacOSXFrameBackchain::Cursor &cursor);
+
+ ~RegisterContextMacOSXFrameBackchain() override;
+
+ void InvalidateAllRegisters() override;
- ~RegisterContextMacOSXFrameBackchain() override;
+ size_t GetRegisterCount() override;
- void
- InvalidateAllRegisters() override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- size_t
- GetRegisterSetCount() override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
private:
- UnwindMacOSXFrameBackchain::Cursor m_cursor;
- bool m_cursor_is_valid;
+ UnwindMacOSXFrameBackchain::Cursor m_cursor;
+ bool m_cursor_is_valid;
- DISALLOW_COPY_AND_ASSIGN (RegisterContextMacOSXFrameBackchain);
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextMacOSXFrameBackchain);
};
#endif // lldb_RegisterContextMacOSXFrameBackchain_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index 7ceb536272f4..a4cf07710194 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -22,66 +22,50 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_arm(thread, concrete_frame_idx) {}
-RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_arm (thread, concrete_frame_idx)
-{
-}
-
-RegisterContextMach_arm::~RegisterContextMach_arm()
-{
-}
+RegisterContextMach_arm::~RegisterContextMach_arm() {}
-int
-RegisterContextMach_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- mach_msg_type_number_t count = GPRWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
+int RegisterContextMach_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ mach_msg_type_number_t count = GPRWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
}
-int
-RegisterContextMach_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- mach_msg_type_number_t count = FPUWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
+int RegisterContextMach_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ mach_msg_type_number_t count = FPUWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
}
-int
-RegisterContextMach_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- mach_msg_type_number_t count = EXCWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
+int RegisterContextMach_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ mach_msg_type_number_t count = EXCWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
}
-int
-RegisterContextMach_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
-{
- mach_msg_type_number_t count = DBGWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&dbg, &count);
+int RegisterContextMach_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
+ mach_msg_type_number_t count = DBGWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&dbg, &count);
}
-int
-RegisterContextMach_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+int RegisterContextMach_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
}
-int
-RegisterContextMach_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+int RegisterContextMach_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
}
-int
-RegisterContextMach_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+int RegisterContextMach_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
}
-int
-RegisterContextMach_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount);
+int RegisterContextMach_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
+ const DBG &dbg) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/source/Plugins/Process/Utility/RegisterContextMach_arm.h
index e97a4bfff2b6..a2cf6bfcbe4a 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.h
@@ -17,40 +17,29 @@
// Project includes
#include "RegisterContextDarwin_arm.h"
-class RegisterContextMach_arm : public RegisterContextDarwin_arm
-{
+class RegisterContextMach_arm : public RegisterContextDarwin_arm {
public:
+ RegisterContextMach_arm(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
- RegisterContextMach_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextMach_arm();
+ virtual ~RegisterContextMach_arm();
protected:
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
};
-#endif // liblldb_RegisterContextMach_arm_h_
+#endif // liblldb_RegisterContextMach_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index 3d6c9a6baca6..959149edbc3e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -20,53 +20,40 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_i386(thread, concrete_frame_idx) {}
-RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_i386 (thread, concrete_frame_idx)
-{
-}
-
-RegisterContextMach_i386::~RegisterContextMach_i386()
-{
-}
+RegisterContextMach_i386::~RegisterContextMach_i386() {}
-int
-RegisterContextMach_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- mach_msg_type_number_t count = GPRWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
+int RegisterContextMach_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ mach_msg_type_number_t count = GPRWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
}
-int
-RegisterContextMach_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- mach_msg_type_number_t count = FPUWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
+int RegisterContextMach_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ mach_msg_type_number_t count = FPUWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
}
-int
-RegisterContextMach_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- mach_msg_type_number_t count = EXCWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
+int RegisterContextMach_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ mach_msg_type_number_t count = EXCWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
}
-int
-RegisterContextMach_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+int RegisterContextMach_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
}
-int
-RegisterContextMach_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+int RegisterContextMach_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
}
-int
-RegisterContextMach_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+int RegisterContextMach_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/source/Plugins/Process/Utility/RegisterContextMach_i386.h
index ad0f69d1c052..8ac693a55584 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.h
@@ -16,34 +16,25 @@
// Project includes
#include "RegisterContextDarwin_i386.h"
-class RegisterContextMach_i386 : public RegisterContextDarwin_i386
-{
+class RegisterContextMach_i386 : public RegisterContextDarwin_i386 {
public:
-
- RegisterContextMach_i386(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextMach_i386();
-
+ RegisterContextMach_i386(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextMach_i386();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
};
-#endif // liblldb_RegisterContextMach_i386_h_
+#endif // liblldb_RegisterContextMach_i386_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index f03685e1313f..522b73a2888e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -20,53 +20,43 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextMach_x86_64::RegisterContextMach_x86_64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_x86_64(thread, concrete_frame_idx) {}
-RegisterContextMach_x86_64::RegisterContextMach_x86_64(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_x86_64 (thread, concrete_frame_idx)
-{
-}
-
-RegisterContextMach_x86_64::~RegisterContextMach_x86_64()
-{
-}
+RegisterContextMach_x86_64::~RegisterContextMach_x86_64() {}
-int
-RegisterContextMach_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- mach_msg_type_number_t count = GPRWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
+int RegisterContextMach_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
+ GPR &gpr) {
+ mach_msg_type_number_t count = GPRWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
}
-int
-RegisterContextMach_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- mach_msg_type_number_t count = FPUWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
+int RegisterContextMach_x86_64::DoReadFPU(lldb::tid_t tid, int flavor,
+ FPU &fpu) {
+ mach_msg_type_number_t count = FPUWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
}
-int
-RegisterContextMach_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- mach_msg_type_number_t count = EXCWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
+int RegisterContextMach_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
+ EXC &exc) {
+ mach_msg_type_number_t count = EXCWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
}
-int
-RegisterContextMach_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+int RegisterContextMach_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
}
-int
-RegisterContextMach_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+int RegisterContextMach_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
}
-int
-RegisterContextMach_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+int RegisterContextMach_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
index 9e6dfa395500..cd425046b08e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextMach_x86_64.h ------------------------------*- C++ -*-===//
+//===-- RegisterContextMach_x86_64.h ------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,34 +17,25 @@
// Project includes
#include "RegisterContextDarwin_x86_64.h"
-class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64
-{
+class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 {
public:
-
- RegisterContextMach_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextMach_x86_64();
-
+ RegisterContextMach_x86_64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextMach_x86_64();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
};
-#endif // liblldb_RegisterContextMach_x86_64_h_
+#endif // liblldb_RegisterContextMach_x86_64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index 40d00b1eed80..57966e1729a6 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -26,149 +26,123 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// RegisterContextMemory constructor
//----------------------------------------------------------------------
-RegisterContextMemory::RegisterContextMemory
-(
- Thread &thread,
- uint32_t concrete_frame_idx,
- DynamicRegisterInfo &reg_infos,
- addr_t reg_data_addr
-) :
- RegisterContext (thread, concrete_frame_idx),
- m_reg_infos (reg_infos),
- m_reg_valid (),
- m_reg_data (),
- m_reg_data_addr (reg_data_addr)
-{
- // Resize our vector of bools to contain one bool for every register.
- // We will use these boolean values to know when a register value
- // is valid in m_reg_data.
- const size_t num_regs = reg_infos.GetNumRegisters();
- assert (num_regs > 0);
- m_reg_valid.resize (num_regs);
-
- // Make a heap based buffer that is big enough to store all registers
- DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0));
- m_reg_data.SetData (reg_data_sp);
+RegisterContextMemory::RegisterContextMemory(Thread &thread,
+ uint32_t concrete_frame_idx,
+ DynamicRegisterInfo &reg_infos,
+ addr_t reg_data_addr)
+ : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos),
+ m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) {
+ // Resize our vector of bools to contain one bool for every register.
+ // We will use these boolean values to know when a register value
+ // is valid in m_reg_data.
+ const size_t num_regs = reg_infos.GetNumRegisters();
+ assert(num_regs > 0);
+ m_reg_valid.resize(num_regs);
+
+ // Make a heap based buffer that is big enough to store all registers
+ DataBufferSP reg_data_sp(
+ new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0));
+ m_reg_data.SetData(reg_data_sp);
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-RegisterContextMemory::~RegisterContextMemory()
-{
-}
+RegisterContextMemory::~RegisterContextMemory() {}
-void
-RegisterContextMemory::InvalidateAllRegisters ()
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- SetAllRegisterValid (false);
+void RegisterContextMemory::InvalidateAllRegisters() {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
+ SetAllRegisterValid(false);
}
-void
-RegisterContextMemory::SetAllRegisterValid (bool b)
-{
- std::vector<bool>::iterator pos, end = m_reg_valid.end();
- for (pos = m_reg_valid.begin(); pos != end; ++pos)
- *pos = b;
+void RegisterContextMemory::SetAllRegisterValid(bool b) {
+ std::vector<bool>::iterator pos, end = m_reg_valid.end();
+ for (pos = m_reg_valid.begin(); pos != end; ++pos)
+ *pos = b;
}
-size_t
-RegisterContextMemory::GetRegisterCount ()
-{
- return m_reg_infos.GetNumRegisters ();
+size_t RegisterContextMemory::GetRegisterCount() {
+ return m_reg_infos.GetNumRegisters();
}
-const RegisterInfo *
-RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
-{
- return m_reg_infos.GetRegisterInfoAtIndex (reg);
+const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) {
+ return m_reg_infos.GetRegisterInfoAtIndex(reg);
}
-size_t
-RegisterContextMemory::GetRegisterSetCount ()
-{
- return m_reg_infos.GetNumRegisterSets ();
+size_t RegisterContextMemory::GetRegisterSetCount() {
+ return m_reg_infos.GetNumRegisterSets();
}
-const RegisterSet *
-RegisterContextMemory::GetRegisterSet (size_t reg_set)
-{
- return m_reg_infos.GetRegisterSet (reg_set);
+const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) {
+ return m_reg_infos.GetRegisterSet(reg_set);
}
-uint32_t
-RegisterContextMemory::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num);
+uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num);
}
-bool
-RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
- if (!m_reg_valid[reg_num])
- {
- if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ()))
- return false;
- }
- const bool partial_data_ok = false;
- return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success();
+bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
+ if (!m_reg_valid[reg_num]) {
+ if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer()))
+ return false;
+ }
+ const bool partial_data_ok = false;
+ return reg_value
+ .SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset,
+ partial_data_ok)
+ .Success();
}
-bool
-RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- {
- const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
- addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
- Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value));
- m_reg_valid[reg_num] = false;
- return error.Success();
- }
- return false;
+bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
+ const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
+ addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
+ Error error(WriteRegisterValueToMemory(reg_info, reg_addr,
+ reg_info->byte_size, reg_value));
+ m_reg_valid[reg_num] = false;
+ return error.Success();
+ }
+ return false;
}
-bool
-RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp)
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
- {
- SetAllRegisterValid (true);
- return true;
- }
- }
+bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),
+ data_sp->GetByteSize(),
+ error) == data_sp->GetByteSize()) {
+ SetAllRegisterValid(true);
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-bool
-RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- SetAllRegisterValid (false);
- if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
- return true;
- }
+bool RegisterContextMemory::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ SetAllRegisterValid(false);
+ if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),
+ data_sp->GetByteSize(),
+ error) == data_sp->GetByteSize())
+ return true;
}
- return false;
+ }
+ return false;
}
-void
-RegisterContextMemory::SetAllRegisterData (const lldb::DataBufferSP &data_sp)
-{
- m_reg_data.SetData(data_sp);
- SetAllRegisterValid (true);
+void RegisterContextMemory::SetAllRegisterData(
+ const lldb::DataBufferSP &data_sp) {
+ m_reg_data.SetData(data_sp);
+ SetAllRegisterValid(true);
}
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.h b/source/Plugins/Process/Utility/RegisterContextMemory.h
index d61aba9543d4..55de0412b094 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.h
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.h
@@ -16,76 +16,65 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
class DynamicRegisterInfo;
-class RegisterContextMemory : public lldb_private::RegisterContext
-{
+class RegisterContextMemory : public lldb_private::RegisterContext {
public:
- RegisterContextMemory (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- DynamicRegisterInfo &reg_info,
- lldb::addr_t reg_data_addr);
-
- ~RegisterContextMemory() override;
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- //------------------------------------------------------------------
- // If all of the thread register are in a contiguous buffer in
- // memory, then the default ReadRegister/WriteRegister and
- // ReadAllRegisterValues/WriteAllRegisterValues will work. If thread
- // registers are not contiguous, clients will want to subclass this
- // class and modify the read/write functions as needed.
- //------------------------------------------------------------------
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- void
- SetAllRegisterData (const lldb::DataBufferSP &data_sp);
+ RegisterContextMemory(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ DynamicRegisterInfo &reg_info,
+ lldb::addr_t reg_data_addr);
+
+ ~RegisterContextMemory() override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ //------------------------------------------------------------------
+ // If all of the thread register are in a contiguous buffer in
+ // memory, then the default ReadRegister/WriteRegister and
+ // ReadAllRegisterValues/WriteAllRegisterValues will work. If thread
+ // registers are not contiguous, clients will want to subclass this
+ // class and modify the read/write functions as needed.
+ //------------------------------------------------------------------
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ void SetAllRegisterData(const lldb::DataBufferSP &data_sp);
protected:
- void
- SetAllRegisterValid (bool b);
+ void SetAllRegisterValid(bool b);
- DynamicRegisterInfo &m_reg_infos;
- std::vector<bool> m_reg_valid;
- lldb_private::DataExtractor m_reg_data;
- lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register context that is stored in memmory
+ DynamicRegisterInfo &m_reg_infos;
+ std::vector<bool> m_reg_valid;
+ lldb_private::DataExtractor m_reg_data;
+ lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register
+ // context that is stored in memmory
private:
- DISALLOW_COPY_AND_ASSIGN (RegisterContextMemory);
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextMemory);
};
#endif // lldb_RegisterContextMemory_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
index 71ece160d4d4..4f64a8c4f321 100644
--- a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
@@ -1,52 +1,50 @@
-//===-- RegisterContextNetBSD_x86_64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextNetBSD_x86_64.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
-#include <cstddef>
-#include <vector>
-
-#include "llvm/Support/Compiler.h"
-
-#include "RegisterContextPOSIX_x86.h"
#include "RegisterContextNetBSD_x86_64.h"
+#include "RegisterContextPOSIX_x86.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <cstddef>
using namespace lldb_private;
using namespace lldb;
// src/sys/arch/amd64/include/frame_regs.h
-typedef struct _GPR
-{
- uint64_t rdi; /* 0 */
- uint64_t rsi; /* 1 */
- uint64_t rdx; /* 2 */
- uint64_t rcx; /* 3 */
- uint64_t r8; /* 4 */
- uint64_t r9; /* 5 */
- uint64_t r10; /* 6 */
- uint64_t r11; /* 7 */
- uint64_t r12; /* 8 */
- uint64_t r13; /* 9 */
- uint64_t r14; /* 10 */
- uint64_t r15; /* 11 */
- uint64_t rbp; /* 12 */
- uint64_t rbx; /* 13 */
- uint64_t rax; /* 14 */
- uint64_t gs; /* 15 */
- uint64_t fs; /* 16 */
- uint64_t es; /* 17 */
- uint64_t ds; /* 18 */
- uint64_t trapno; /* 19 */
- uint64_t err; /* 20 */
- uint64_t rip; /* 21 */
- uint64_t cs; /* 22 */
- uint64_t rflags; /* 23 */
- uint64_t rsp; /* 24 */
- uint64_t ss; /* 25 */
+typedef struct _GPR {
+ uint64_t rdi; /* 0 */
+ uint64_t rsi; /* 1 */
+ uint64_t rdx; /* 2 */
+ uint64_t rcx; /* 3 */
+ uint64_t r8; /* 4 */
+ uint64_t r9; /* 5 */
+ uint64_t r10; /* 6 */
+ uint64_t r11; /* 7 */
+ uint64_t r12; /* 8 */
+ uint64_t r13; /* 9 */
+ uint64_t r14; /* 10 */
+ uint64_t r15; /* 11 */
+ uint64_t rbp; /* 12 */
+ uint64_t rbx; /* 13 */
+ uint64_t rax; /* 14 */
+ uint64_t gs; /* 15 */
+ uint64_t fs; /* 16 */
+ uint64_t es; /* 17 */
+ uint64_t ds; /* 18 */
+ uint64_t trapno; /* 19 */
+ uint64_t err; /* 20 */
+ uint64_t rip; /* 21 */
+ uint64_t cs; /* 22 */
+ uint64_t rflags; /* 23 */
+ uint64_t rsp; /* 24 */
+ uint64_t ss; /* 25 */
} GPR;
/*
@@ -65,38 +63,35 @@ typedef struct _GPR
*/
struct UserArea {
- GPR gpr;
- uint64_t mc_tlsbase;
- FPR fpr;
+ GPR gpr;
+ uint64_t mc_tlsbase;
+ FPR fpr;
};
-
//---------------------------------------------------------------------------
// Cherry-pick parts of RegisterInfos_x86_64.h, without debug registers
//---------------------------------------------------------------------------
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(FXSAVE, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplX86_64.cpp from debugserver
-#define YMM_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + \
- (32 * reg_index))
+#define YMM_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
// Number of bytes needed to represent a FPR.
-#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg)
// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes)
// Number of bytes needed to represent an XMM register.
#define XMM_SIZE sizeof(XMMReg)
@@ -107,197 +102,234 @@ struct UserArea {
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, NULL, NULL }
-
-#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
- { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, NULL, NULL }
-
-#define DEFINE_FP_ST(reg, i) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
- NULL, NULL }
-
-#define DEFINE_FP_MM(reg, i) \
- { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingUint, eFormatHex, \
- { dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \
- NULL, NULL }
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64}, \
- NULL, NULL }
-
-#define DEFINE_YMM(reg, i) \
- { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64 }, \
- NULL, NULL }
-
-#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
- { #reg32, NULL, 4, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
- { #reg16, NULL, 2, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64)+1, eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-
-static RegisterInfo
-g_register_infos_x86_64[] =
-{
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-
- DEFINE_GPR_PSEUDO_32(eax, rax),
- DEFINE_GPR_PSEUDO_32(ebx, rbx),
- DEFINE_GPR_PSEUDO_32(ecx, rcx),
- DEFINE_GPR_PSEUDO_32(edx, rdx),
- DEFINE_GPR_PSEUDO_32(edi, rdi),
- DEFINE_GPR_PSEUDO_32(esi, rsi),
- DEFINE_GPR_PSEUDO_32(ebp, rbp),
- DEFINE_GPR_PSEUDO_32(esp, rsp),
- DEFINE_GPR_PSEUDO_32(r8d, r8),
- DEFINE_GPR_PSEUDO_32(r9d, r9),
- DEFINE_GPR_PSEUDO_32(r10d, r10),
- DEFINE_GPR_PSEUDO_32(r11d, r11),
- DEFINE_GPR_PSEUDO_32(r12d, r12),
- DEFINE_GPR_PSEUDO_32(r13d, r13),
- DEFINE_GPR_PSEUDO_32(r14d, r14),
- DEFINE_GPR_PSEUDO_32(r15d, r15),
- DEFINE_GPR_PSEUDO_16(ax, rax),
- DEFINE_GPR_PSEUDO_16(bx, rbx),
- DEFINE_GPR_PSEUDO_16(cx, rcx),
- DEFINE_GPR_PSEUDO_16(dx, rdx),
- DEFINE_GPR_PSEUDO_16(di, rdi),
- DEFINE_GPR_PSEUDO_16(si, rsi),
- DEFINE_GPR_PSEUDO_16(bp, rbp),
- DEFINE_GPR_PSEUDO_16(sp, rsp),
- DEFINE_GPR_PSEUDO_16(r8w, r8),
- DEFINE_GPR_PSEUDO_16(r9w, r9),
- DEFINE_GPR_PSEUDO_16(r10w, r10),
- DEFINE_GPR_PSEUDO_16(r11w, r11),
- DEFINE_GPR_PSEUDO_16(r12w, r12),
- DEFINE_GPR_PSEUDO_16(r13w, r13),
- DEFINE_GPR_PSEUDO_16(r14w, r14),
- DEFINE_GPR_PSEUDO_16(r15w, r15),
- DEFINE_GPR_PSEUDO_8H(ah, rax),
- DEFINE_GPR_PSEUDO_8H(bh, rbx),
- DEFINE_GPR_PSEUDO_8H(ch, rcx),
- DEFINE_GPR_PSEUDO_8H(dh, rdx),
- DEFINE_GPR_PSEUDO_8L(al, rax),
- DEFINE_GPR_PSEUDO_8L(bl, rbx),
- DEFINE_GPR_PSEUDO_8L(cl, rcx),
- DEFINE_GPR_PSEUDO_8L(dl, rdx),
- DEFINE_GPR_PSEUDO_8L(dil, rdi),
- DEFINE_GPR_PSEUDO_8L(sil, rsi),
- DEFINE_GPR_PSEUDO_8L(bpl, rbp),
- DEFINE_GPR_PSEUDO_8L(spl, rsp),
- DEFINE_GPR_PSEUDO_8L(r8l, r8),
- DEFINE_GPR_PSEUDO_8L(r9l, r9),
- DEFINE_GPR_PSEUDO_8L(r10l, r10),
- DEFINE_GPR_PSEUDO_8L(r11l, r11),
- DEFINE_GPR_PSEUDO_8L(r12l, r12),
- DEFINE_GPR_PSEUDO_8L(r13l, r13),
- DEFINE_GPR_PSEUDO_8L(r14l, r14),
- DEFINE_GPR_PSEUDO_8L(r15l, r15),
-
- // i387 Floating point registers. EH_frame, DWARF, Generic, Process Plugin
- DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR *)nullptr)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##reg##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##name##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_ST(reg, i) \
+ { \
+ #reg #i, nullptr, FP_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_MM(reg, i) \
+ { \
+ #reg #i, nullptr, sizeof(uint64_t), \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingUint, eFormatHex, \
+ {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_mm##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_XMM(reg, i) \
+ { \
+ #reg #i, nullptr, XMM_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_YMM(reg, i) \
+ { \
+ #reg #i, nullptr, YMM_SIZE, \
+ LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##h_x86_64, \
+ dwarf_##reg##i##h_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
+ { \
+ #reg32, nullptr, 4, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg32##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
+ { \
+ #reg16, nullptr, 2, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg16##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64,\
+ nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64,\
+ nullptr, 0 \
+ }
+
+static RegisterInfo g_register_infos_x86_64[] = {
+ // General purpose registers. EH_Frame, DWARF,
+ // Generic, Process Plugin
+ DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64,
+ LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64,
+ LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64,
+ LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64,
+ LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64,
+ LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64,
+ LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64,
+ LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64,
+ LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64,
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64,
+ LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx),
+ DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx),
+ DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi),
+ DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp),
+ DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9),
+ DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11),
+ DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13),
+ DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15),
+ DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx),
+ DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx),
+ DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi),
+ DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp),
+ DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9),
+ DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11),
+ DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13),
+ DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15),
+ DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx),
+ DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx),
+ DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx),
+ DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx),
+ DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi),
+ DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp),
+ DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9),
+ DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11),
+ DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13),
+ DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15),
+
+ // i387 Floating point registers. EH_frame,
+ // DWARF, Generic, Process Plugin
+ DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
// FP registers.
- DEFINE_FP_ST(st, 0),
- DEFINE_FP_ST(st, 1),
- DEFINE_FP_ST(st, 2),
- DEFINE_FP_ST(st, 3),
- DEFINE_FP_ST(st, 4),
- DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6),
- DEFINE_FP_ST(st, 7),
- DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1),
- DEFINE_FP_MM(mm, 2),
- DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4),
- DEFINE_FP_MM(mm, 5),
- DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
DEFINE_FP_MM(mm, 7),
// XMM registers
- DEFINE_XMM(xmm, 0),
- DEFINE_XMM(xmm, 1),
- DEFINE_XMM(xmm, 2),
- DEFINE_XMM(xmm, 3),
- DEFINE_XMM(xmm, 4),
- DEFINE_XMM(xmm, 5),
- DEFINE_XMM(xmm, 6),
- DEFINE_XMM(xmm, 7),
- DEFINE_XMM(xmm, 8),
- DEFINE_XMM(xmm, 9),
- DEFINE_XMM(xmm, 10),
- DEFINE_XMM(xmm, 11),
- DEFINE_XMM(xmm, 12),
- DEFINE_XMM(xmm, 13),
- DEFINE_XMM(xmm, 14),
+ DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
+ DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5),
+ DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8),
+ DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11),
+ DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14),
DEFINE_XMM(xmm, 15),
// Copy of YMM registers assembled from xmm and ymmh
- DEFINE_YMM(ymm, 0),
- DEFINE_YMM(ymm, 1),
- DEFINE_YMM(ymm, 2),
- DEFINE_YMM(ymm, 3),
- DEFINE_YMM(ymm, 4),
- DEFINE_YMM(ymm, 5),
- DEFINE_YMM(ymm, 6),
- DEFINE_YMM(ymm, 7),
- DEFINE_YMM(ymm, 8),
- DEFINE_YMM(ymm, 9),
- DEFINE_YMM(ymm, 10),
- DEFINE_YMM(ymm, 11),
- DEFINE_YMM(ymm, 12),
- DEFINE_YMM(ymm, 13),
- DEFINE_YMM(ymm, 14),
+ DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8),
+ DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11),
+ DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14),
DEFINE_YMM(ymm, 15),
};
@@ -306,52 +338,40 @@ g_register_infos_x86_64[] =
//---------------------------------------------------------------------------
static const RegisterInfo *
-PrivateGetRegisterInfoPtr (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
static uint32_t
-PrivateGetRegisterCount (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (PrivateGetRegisterInfoPtr (target_arch)),
- m_register_count (PrivateGetRegisterCount (target_arch))
-{
-}
+RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),
+ m_register_count(PrivateGetRegisterCount(target_arch)) {}
-size_t
-RegisterContextNetBSD_x86_64::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextNetBSD_x86_64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextNetBSD_x86_64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextNetBSD_x86_64::GetRegisterCount () const
-{
- return m_register_count;
+uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const {
+ return m_register_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
index c267278c418c..6b1998148d61 100644
--- a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
@@ -12,24 +12,20 @@
#include "RegisterInfoInterface.h"
-class RegisterContextNetBSD_x86_64:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextNetBSD_x86_64
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextNetBSD_x86_64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextNetBSD_x86_64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- const uint32_t m_register_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ const uint32_t m_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 029a0e7352ec..15d155e315fa 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -15,321 +15,204 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_arm.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_arm.h"
using namespace lldb;
using namespace lldb_private;
// arm general purpose registers.
-const uint32_t g_gpr_regnums_arm[] =
-{
- gpr_r0_arm,
- gpr_r1_arm,
- gpr_r2_arm,
- gpr_r3_arm,
- gpr_r4_arm,
- gpr_r5_arm,
- gpr_r6_arm,
- gpr_r7_arm,
- gpr_r8_arm,
- gpr_r9_arm,
- gpr_r10_arm,
- gpr_r11_arm,
- gpr_r12_arm,
- gpr_sp_arm,
- gpr_lr_arm,
- gpr_pc_arm,
- gpr_cpsr_arm,
+const uint32_t g_gpr_regnums_arm[] = {
+ gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm,
+ gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm,
+ gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm,
+ gpr_pc_arm, gpr_cpsr_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
+ k_num_gpr_registers_arm,
"g_gpr_regnums_arm has wrong number of register infos");
// arm floating point registers.
-static const uint32_t g_fpu_regnums_arm[] =
-{
- fpu_s0_arm,
- fpu_s1_arm,
- fpu_s2_arm,
- fpu_s3_arm,
- fpu_s4_arm,
- fpu_s5_arm,
- fpu_s6_arm,
- fpu_s7_arm,
- fpu_s8_arm,
- fpu_s9_arm,
- fpu_s10_arm,
- fpu_s11_arm,
- fpu_s12_arm,
- fpu_s13_arm,
- fpu_s14_arm,
- fpu_s15_arm,
- fpu_s16_arm,
- fpu_s17_arm,
- fpu_s18_arm,
- fpu_s19_arm,
- fpu_s20_arm,
- fpu_s21_arm,
- fpu_s22_arm,
- fpu_s23_arm,
- fpu_s24_arm,
- fpu_s25_arm,
- fpu_s26_arm,
- fpu_s27_arm,
- fpu_s28_arm,
- fpu_s29_arm,
- fpu_s30_arm,
- fpu_s31_arm,
- fpu_fpscr_arm,
- fpu_d0_arm,
- fpu_d1_arm,
- fpu_d2_arm,
- fpu_d3_arm,
- fpu_d4_arm,
- fpu_d5_arm,
- fpu_d6_arm,
- fpu_d7_arm,
- fpu_d8_arm,
- fpu_d9_arm,
- fpu_d10_arm,
- fpu_d11_arm,
- fpu_d12_arm,
- fpu_d13_arm,
- fpu_d14_arm,
- fpu_d15_arm,
- fpu_d16_arm,
- fpu_d17_arm,
- fpu_d18_arm,
- fpu_d19_arm,
- fpu_d20_arm,
- fpu_d21_arm,
- fpu_d22_arm,
- fpu_d23_arm,
- fpu_d24_arm,
- fpu_d25_arm,
- fpu_d26_arm,
- fpu_d27_arm,
- fpu_d28_arm,
- fpu_d29_arm,
- fpu_d30_arm,
- fpu_d31_arm,
- fpu_q0_arm,
- fpu_q1_arm,
- fpu_q2_arm,
- fpu_q3_arm,
- fpu_q4_arm,
- fpu_q5_arm,
- fpu_q6_arm,
- fpu_q7_arm,
- fpu_q8_arm,
- fpu_q9_arm,
- fpu_q10_arm,
- fpu_q11_arm,
- fpu_q12_arm,
- fpu_q13_arm,
- fpu_q14_arm,
+static const uint32_t g_fpu_regnums_arm[] = {
+ fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm,
+ fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm,
+ fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm,
+ fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm,
+ fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm,
+ fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm,
+ fpu_s30_arm, fpu_s31_arm, fpu_fpscr_arm, fpu_d0_arm, fpu_d1_arm,
+ fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, fpu_d5_arm, fpu_d6_arm,
+ fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, fpu_d10_arm, fpu_d11_arm,
+ fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, fpu_d15_arm, fpu_d16_arm,
+ fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, fpu_d20_arm, fpu_d21_arm,
+ fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, fpu_d25_arm, fpu_d26_arm,
+ fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, fpu_d30_arm, fpu_d31_arm,
+ fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm,
+ fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm,
+ fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm,
fpu_q15_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
+ k_num_fpr_registers_arm,
"g_fpu_regnums_arm has wrong number of register infos");
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 2
-};
+enum { k_num_register_sets = 2 };
// Register sets for arm.
-static const lldb_private::RegisterSet
-g_reg_sets_arm[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
-};
+static const lldb_private::RegisterSet g_reg_sets_arm[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
+ g_gpr_regnums_arm},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
+ g_fpu_regnums_arm}};
-bool RegisterContextPOSIX_arm::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool RegisterContextPOSIX_arm::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : lldb_private::RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- m_reg_info.num_registers = k_num_registers_arm;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
- m_reg_info.last_gpr = k_last_gpr_arm;
- m_reg_info.first_fpr = k_first_fpr_arm;
- m_reg_info.last_fpr = k_last_fpr_arm;
- m_reg_info.first_fpr_v = fpu_s0_arm;
- m_reg_info.last_fpr_v = fpu_s31_arm;
- m_reg_info.gpr_flags = gpr_cpsr_arm;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : lldb_private::RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
- ::memset(&m_fpr, 0, sizeof m_fpr);
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ m_reg_info.num_registers = k_num_registers_arm;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
+ m_reg_info.last_gpr = k_last_gpr_arm;
+ m_reg_info.first_fpr = k_first_fpr_arm;
+ m_reg_info.last_fpr = k_last_fpr_arm;
+ m_reg_info.first_fpr_v = fpu_s0_arm;
+ m_reg_info.last_fpr_v = fpu_s31_arm;
+ m_reg_info.gpr_flags = gpr_cpsr_arm;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
- // elf-core yet to support ReadFPR()
- lldb::ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+ ::memset(&m_fpr, 0, sizeof m_fpr);
-RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm()
-{
+ // elf-core yet to support ReadFPR()
+ lldb::ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_arm::Invalidate()
-{
-}
+RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {}
-void
-RegisterContextPOSIX_arm::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_arm::Invalidate() {}
+
+void RegisterContextPOSIX_arm::InvalidateAllRegisters() {}
-unsigned
-RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+unsigned RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_arm::GetRegisterCount()
-{
- size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- return num_registers;
+size_t RegisterContextPOSIX_arm::GetRegisterCount() {
+ size_t num_registers =
+ m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_arm::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize ();
+size_t RegisterContextPOSIX_arm::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+const lldb_private::RegisterInfo *RegisterContextPOSIX_arm::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_arm::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_arm::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
const lldb_private::RegisterSet *
-RegisterContextPOSIX_arm::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return &g_reg_sets_arm[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+RegisterContextPOSIX_arm::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return &g_reg_sets_arm[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-const char *
-RegisterContextPOSIX_arm::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_arm::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
- lldb_private::Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_arm::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+ lldb_private::Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index)
-{
- return set_index < k_num_register_sets;
+bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) {
+ return set_index < k_num_register_sets;
}
-
// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < lldb::kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+// object file sections that contain register numbers in them.
+uint32_t RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- return LLDB_INVALID_REGNUM;
-}
+ assert(kind < lldb::kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const lldb_private::RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
index fbbcb9402911..817649e7c498 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
@@ -14,112 +14,98 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
#include "lldb-arm-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_arm
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_arm : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_arm (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_arm(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_arm() override;
+ ~RegisterContextPOSIX_arm() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- struct QReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
-
- uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm]; // 32-bit general purpose registers.
- RegInfo m_reg_info;
- struct RegisterContextPOSIX_arm::FPU m_fpr; // floating-point registers including extended register sets.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- lldb::ByteOrder GetByteOrder();
-
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
+
+ uint32_t gpr_flags;
+ };
+
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+
+ uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm]; // 32-bit general
+ // purpose
+ // registers.
+ RegInfo m_reg_info;
+ struct RegisterContextPOSIX_arm::FPU
+ m_fpr; // floating-point registers including extended register sets.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 96508eafcce2..17c9dc301b50 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -15,288 +15,224 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_arm64.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_arm64.h"
using namespace lldb;
using namespace lldb_private;
// ARM64 general purpose registers.
-const uint32_t g_gpr_regnums_arm64[] =
-{
- gpr_x0_arm64,
- gpr_x1_arm64,
- gpr_x2_arm64,
- gpr_x3_arm64,
- gpr_x4_arm64,
- gpr_x5_arm64,
- gpr_x6_arm64,
- gpr_x7_arm64,
- gpr_x8_arm64,
- gpr_x9_arm64,
- gpr_x10_arm64,
- gpr_x11_arm64,
- gpr_x12_arm64,
- gpr_x13_arm64,
- gpr_x14_arm64,
- gpr_x15_arm64,
- gpr_x16_arm64,
- gpr_x17_arm64,
- gpr_x18_arm64,
- gpr_x19_arm64,
- gpr_x20_arm64,
- gpr_x21_arm64,
- gpr_x22_arm64,
- gpr_x23_arm64,
- gpr_x24_arm64,
- gpr_x25_arm64,
- gpr_x26_arm64,
- gpr_x27_arm64,
- gpr_x28_arm64,
- gpr_fp_arm64,
- gpr_lr_arm64,
- gpr_sp_arm64,
- gpr_pc_arm64,
- gpr_cpsr_arm64,
+const uint32_t g_gpr_regnums_arm64[] = {
+ gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,
+ gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,
+ gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,
+ gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,
+ gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,
+ gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,
+ gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,
+ gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,
+ gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,
+ gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,
+ gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,
+ gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,
+ gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,
+ gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,
+ gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,
+ gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - 1) == k_num_gpr_registers_arm64, \
+static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
+ 1) == k_num_gpr_registers_arm64,
"g_gpr_regnums_arm64 has wrong number of register infos");
// ARM64 floating point registers.
-static const uint32_t g_fpu_regnums_arm64[] =
-{
- fpu_v0_arm64,
- fpu_v1_arm64,
- fpu_v2_arm64,
- fpu_v3_arm64,
- fpu_v4_arm64,
- fpu_v5_arm64,
- fpu_v6_arm64,
- fpu_v7_arm64,
- fpu_v8_arm64,
- fpu_v9_arm64,
- fpu_v10_arm64,
- fpu_v11_arm64,
- fpu_v12_arm64,
- fpu_v13_arm64,
- fpu_v14_arm64,
- fpu_v15_arm64,
- fpu_v16_arm64,
- fpu_v17_arm64,
- fpu_v18_arm64,
- fpu_v19_arm64,
- fpu_v20_arm64,
- fpu_v21_arm64,
- fpu_v22_arm64,
- fpu_v23_arm64,
- fpu_v24_arm64,
- fpu_v25_arm64,
- fpu_v26_arm64,
- fpu_v27_arm64,
- fpu_v28_arm64,
- fpu_v29_arm64,
- fpu_v30_arm64,
- fpu_v31_arm64,
- fpu_fpsr_arm64,
- fpu_fpcr_arm64,
+static const uint32_t g_fpu_regnums_arm64[] = {
+ fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,
+ fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,
+ fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,
+ fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,
+ fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,
+ fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,
+ fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,
+ fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,
+ fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,
+ fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,
+ fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,
+ fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,
+ fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,
+ fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,
+ fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,
+ fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,
+
+ fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,
+ fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,
+ fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,
+ fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,
+ fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,
+ fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,
+ fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,
+ fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,
+ fpu_fpsr_arm64, fpu_fpcr_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - 1) == k_num_fpr_registers_arm64, \
+static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
+ 1) == k_num_fpr_registers_arm64,
"g_fpu_regnums_arm64 has wrong number of register infos");
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 2
-};
+enum { k_num_register_sets = 2 };
// Register sets for ARM64.
-static const lldb_private::RegisterSet
-g_reg_sets_arm64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm64, g_gpr_regnums_arm64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 }
-};
+static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
+ g_gpr_regnums_arm64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
+ g_fpu_regnums_arm64}};
-bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : lldb_private::RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- m_reg_info.num_registers = k_num_registers_arm64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
- m_reg_info.last_gpr = k_last_gpr_arm64;
- m_reg_info.first_fpr = k_first_fpr_arm64;
- m_reg_info.last_fpr = k_last_fpr_arm64;
- m_reg_info.first_fpr_v = fpu_v0_arm64;
- m_reg_info.last_fpr_v = fpu_v31_arm64;
- m_reg_info.gpr_flags = gpr_cpsr_arm64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : lldb_private::RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
- ::memset(&m_fpr, 0, sizeof m_fpr);
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_reg_info.num_registers = k_num_registers_arm64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
+ m_reg_info.last_gpr = k_last_gpr_arm64;
+ m_reg_info.first_fpr = k_first_fpr_arm64;
+ m_reg_info.last_fpr = k_last_fpr_arm64;
+ m_reg_info.first_fpr_v = fpu_v0_arm64;
+ m_reg_info.last_fpr_v = fpu_v31_arm64;
+ m_reg_info.gpr_flags = gpr_cpsr_arm64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
- // elf-core yet to support ReadFPR()
- lldb::ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+ ::memset(&m_fpr, 0, sizeof m_fpr);
-RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64()
-{
+ // elf-core yet to support ReadFPR()
+ lldb::ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_arm64::Invalidate()
-{
-}
+RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {}
-void
-RegisterContextPOSIX_arm64::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_arm64::Invalidate() {}
-unsigned
-RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+void RegisterContextPOSIX_arm64::InvalidateAllRegisters() {}
+
+unsigned RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_arm64::GetRegisterCount()
-{
- size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- return num_registers;
+size_t RegisterContextPOSIX_arm64::GetRegisterCount() {
+ size_t num_registers =
+ m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_arm64::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize ();
+size_t RegisterContextPOSIX_arm64::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm64::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+RegisterContextPOSIX_arm64::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_arm64::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
const lldb_private::RegisterSet *
-RegisterContextPOSIX_arm64::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return &g_reg_sets_arm64[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ return &g_reg_sets_arm64[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-const char *
-RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_arm64::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
- lldb_private::Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_arm64::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+ lldb_private::Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index)
-{
- return set_index < k_num_register_sets;
+bool RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index) {
+ return set_index < k_num_register_sets;
}
-
// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < lldb::kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+// object file sections that contain register numbers in them.
+uint32_t RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < lldb::kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const lldb_private::RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(reg_idx);
+
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
- return LLDB_INVALID_REGNUM;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index 225d4f25168e..923e786dd045 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -14,111 +14,98 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
#include "lldb-arm64-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_arm64
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_arm64 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_arm64() override;
+ ~RegisterContextPOSIX_arm64() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit general purpose registers.
- RegInfo m_reg_info;
- struct RegisterContextPOSIX_arm64::FPU m_fpr; // floating-point registers including extended register sets.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- lldb::ByteOrder GetByteOrder();
-
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
+
+ uint32_t gpr_flags;
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct VReg {
+ uint8_t bytes[16];
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
+
+ uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit
+ // general
+ // purpose
+ // registers.
+ RegInfo m_reg_info;
+ struct RegisterContextPOSIX_arm64::FPU
+ m_fpr; // floating-point registers including extended register sets.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_arm64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index cefedaec63c1..8c67fb89d08e 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -15,223 +15,150 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_mips64.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_mips64.h"
using namespace lldb_private;
using namespace lldb;
-static const
-uint32_t g_gpr_regnums[] =
-{
- gpr_zero_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_ic_mips64,
- gpr_dummy_mips64
-};
+static const uint32_t g_gpr_regnums[] = {
+ gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64,
+ gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64,
+ gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
+ gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64,
+ gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64,
+ gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
+ gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64,
+ gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64,
+ gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
+ gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64};
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 1
-};
+enum { k_num_register_sets = 1 };
-static const RegisterSet
-g_reg_sets_mips64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_mips64, g_gpr_regnums },
+static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
+ g_gpr_regnums},
};
-bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg)
-{
- return reg <= k_num_gpr_registers_mips64; // GPR's come first.
+bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg) {
+ return reg <= k_num_gpr_registers_mips64; // GPR's come first.
}
-bool
-RegisterContextPOSIX_mips64::IsFPR(unsigned reg)
-{
- // XXX
- return false;
+bool RegisterContextPOSIX_mips64::IsFPR(unsigned reg) {
+ // XXX
+ return false;
}
-RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(Thread &thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
-RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64()
-{
+ // elf-core yet to support ReadFPR()
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_mips64::Invalidate()
-{
-}
+RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {}
-void
-RegisterContextPOSIX_mips64::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_mips64::Invalidate() {}
-unsigned
-RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg)
-{
- assert(reg < k_num_registers_mips64 && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {}
+
+unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) {
+ assert(reg < k_num_registers_mips64 && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg)
-{
- assert(reg < k_num_registers_mips64 && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) {
+ assert(reg < k_num_registers_mips64 && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_mips64::GetRegisterCount()
-{
- size_t num_registers = k_num_registers_mips64;
- return num_registers;
+size_t RegisterContextPOSIX_mips64::GetRegisterCount() {
+ size_t num_registers = k_num_registers_mips64;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_mips64::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize();
+size_t RegisterContextPOSIX_mips64::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-const RegisterInfo *
-RegisterContextPOSIX_mips64::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_registers_mips64)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_registers_mips64)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_mips64::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
-
- return sets;
+size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_mips64::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- return &g_reg_sets_mips64[set];
- else
- return NULL;
+const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set))
+ return &g_reg_sets_mips64[set];
+ else
+ return NULL;
}
-const char *
-RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg)
-{
- assert(reg < k_num_registers_mips64 && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) {
+ assert(reg < k_num_registers_mips64 && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_mips64::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index)
-{
- size_t num_sets = k_num_register_sets;
+bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) {
+ size_t num_sets = k_num_register_sets;
- return (set_index < num_sets);
+ return (set_index < num_sets);
}
// Used when parsing DWARF and EH frame information and any other
// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
+uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
index 07552d8d681d..90ff9d659491 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
@@ -14,82 +14,69 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
#include "RegisterContext_mips.h"
+#include "RegisterInfoInterface.h"
#include "lldb-mips-freebsd-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
using namespace lldb_private;
class ProcessMonitor;
-class RegisterContextPOSIX_mips64
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_mips64 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_mips64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_mips64() override;
+ ~RegisterContextPOSIX_mips64() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- uint64_t m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+ uint64_t
+ m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
- bool
- IsGPR(unsigned reg);
+ bool IsGPR(unsigned reg);
- bool
- IsFPR(unsigned reg);
+ bool IsFPR(unsigned reg);
- lldb::ByteOrder GetByteOrder();
+ lldb::ByteOrder GetByteOrder();
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_mips64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index e353e8114765..6a9838a6fd0c 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,305 +16,184 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_powerpc.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_powerpc.h"
using namespace lldb_private;
using namespace lldb;
-static const
-uint32_t g_gpr_regnums[] =
-{
- gpr_r0_powerpc,
- gpr_r1_powerpc,
- gpr_r2_powerpc,
- gpr_r3_powerpc,
- gpr_r4_powerpc,
- gpr_r5_powerpc,
- gpr_r6_powerpc,
- gpr_r7_powerpc,
- gpr_r8_powerpc,
- gpr_r9_powerpc,
- gpr_r10_powerpc,
- gpr_r11_powerpc,
- gpr_r12_powerpc,
- gpr_r13_powerpc,
- gpr_r14_powerpc,
- gpr_r15_powerpc,
- gpr_r16_powerpc,
- gpr_r17_powerpc,
- gpr_r18_powerpc,
- gpr_r19_powerpc,
- gpr_r20_powerpc,
- gpr_r21_powerpc,
- gpr_r22_powerpc,
- gpr_r23_powerpc,
- gpr_r24_powerpc,
- gpr_r25_powerpc,
- gpr_r26_powerpc,
- gpr_r27_powerpc,
- gpr_r28_powerpc,
- gpr_r29_powerpc,
- gpr_r30_powerpc,
- gpr_r31_powerpc,
- gpr_lr_powerpc,
- gpr_cr_powerpc,
- gpr_xer_powerpc,
- gpr_ctr_powerpc,
+static const uint32_t g_gpr_regnums[] = {
+ gpr_r0_powerpc, gpr_r1_powerpc, gpr_r2_powerpc, gpr_r3_powerpc,
+ gpr_r4_powerpc, gpr_r5_powerpc, gpr_r6_powerpc, gpr_r7_powerpc,
+ gpr_r8_powerpc, gpr_r9_powerpc, gpr_r10_powerpc, gpr_r11_powerpc,
+ gpr_r12_powerpc, gpr_r13_powerpc, gpr_r14_powerpc, gpr_r15_powerpc,
+ gpr_r16_powerpc, gpr_r17_powerpc, gpr_r18_powerpc, gpr_r19_powerpc,
+ gpr_r20_powerpc, gpr_r21_powerpc, gpr_r22_powerpc, gpr_r23_powerpc,
+ gpr_r24_powerpc, gpr_r25_powerpc, gpr_r26_powerpc, gpr_r27_powerpc,
+ gpr_r28_powerpc, gpr_r29_powerpc, gpr_r30_powerpc, gpr_r31_powerpc,
+ gpr_lr_powerpc, gpr_cr_powerpc, gpr_xer_powerpc, gpr_ctr_powerpc,
gpr_pc_powerpc,
};
-static const
-uint32_t g_fpr_regnums[] =
-{
- fpr_f0_powerpc,
- fpr_f1_powerpc,
- fpr_f2_powerpc,
- fpr_f3_powerpc,
- fpr_f4_powerpc,
- fpr_f5_powerpc,
- fpr_f6_powerpc,
- fpr_f7_powerpc,
- fpr_f8_powerpc,
- fpr_f9_powerpc,
- fpr_f10_powerpc,
- fpr_f11_powerpc,
- fpr_f12_powerpc,
- fpr_f13_powerpc,
- fpr_f14_powerpc,
- fpr_f15_powerpc,
- fpr_f16_powerpc,
- fpr_f17_powerpc,
- fpr_f18_powerpc,
- fpr_f19_powerpc,
- fpr_f20_powerpc,
- fpr_f21_powerpc,
- fpr_f22_powerpc,
- fpr_f23_powerpc,
- fpr_f24_powerpc,
- fpr_f25_powerpc,
- fpr_f26_powerpc,
- fpr_f27_powerpc,
- fpr_f28_powerpc,
- fpr_f29_powerpc,
- fpr_f30_powerpc,
- fpr_f31_powerpc,
+static const uint32_t g_fpr_regnums[] = {
+ fpr_f0_powerpc, fpr_f1_powerpc, fpr_f2_powerpc, fpr_f3_powerpc,
+ fpr_f4_powerpc, fpr_f5_powerpc, fpr_f6_powerpc, fpr_f7_powerpc,
+ fpr_f8_powerpc, fpr_f9_powerpc, fpr_f10_powerpc, fpr_f11_powerpc,
+ fpr_f12_powerpc, fpr_f13_powerpc, fpr_f14_powerpc, fpr_f15_powerpc,
+ fpr_f16_powerpc, fpr_f17_powerpc, fpr_f18_powerpc, fpr_f19_powerpc,
+ fpr_f20_powerpc, fpr_f21_powerpc, fpr_f22_powerpc, fpr_f23_powerpc,
+ fpr_f24_powerpc, fpr_f25_powerpc, fpr_f26_powerpc, fpr_f27_powerpc,
+ fpr_f28_powerpc, fpr_f29_powerpc, fpr_f30_powerpc, fpr_f31_powerpc,
fpr_fpscr_powerpc,
};
-static const
-uint32_t g_vmx_regnums[] =
-{
- vmx_v0_powerpc,
- vmx_v1_powerpc,
- vmx_v2_powerpc,
- vmx_v3_powerpc,
- vmx_v4_powerpc,
- vmx_v5_powerpc,
- vmx_v6_powerpc,
- vmx_v7_powerpc,
- vmx_v8_powerpc,
- vmx_v9_powerpc,
- vmx_v10_powerpc,
- vmx_v11_powerpc,
- vmx_v12_powerpc,
- vmx_v13_powerpc,
- vmx_v14_powerpc,
- vmx_v15_powerpc,
- vmx_v16_powerpc,
- vmx_v17_powerpc,
- vmx_v18_powerpc,
- vmx_v19_powerpc,
- vmx_v20_powerpc,
- vmx_v21_powerpc,
- vmx_v22_powerpc,
- vmx_v23_powerpc,
- vmx_v24_powerpc,
- vmx_v25_powerpc,
- vmx_v26_powerpc,
- vmx_v27_powerpc,
- vmx_v28_powerpc,
- vmx_v29_powerpc,
- vmx_v30_powerpc,
- vmx_v31_powerpc,
- vmx_vrsave_powerpc,
- vmx_vscr_powerpc,
+static const uint32_t g_vmx_regnums[] = {
+ vmx_v0_powerpc, vmx_v1_powerpc, vmx_v2_powerpc, vmx_v3_powerpc,
+ vmx_v4_powerpc, vmx_v5_powerpc, vmx_v6_powerpc, vmx_v7_powerpc,
+ vmx_v8_powerpc, vmx_v9_powerpc, vmx_v10_powerpc, vmx_v11_powerpc,
+ vmx_v12_powerpc, vmx_v13_powerpc, vmx_v14_powerpc, vmx_v15_powerpc,
+ vmx_v16_powerpc, vmx_v17_powerpc, vmx_v18_powerpc, vmx_v19_powerpc,
+ vmx_v20_powerpc, vmx_v21_powerpc, vmx_v22_powerpc, vmx_v23_powerpc,
+ vmx_v24_powerpc, vmx_v25_powerpc, vmx_v26_powerpc, vmx_v27_powerpc,
+ vmx_v28_powerpc, vmx_v29_powerpc, vmx_v30_powerpc, vmx_v31_powerpc,
+ vmx_vrsave_powerpc, vmx_vscr_powerpc,
};
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 3
+enum { k_num_register_sets = 3 };
+
+static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_powerpc,
+ g_gpr_regnums},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_powerpc,
+ g_fpr_regnums},
+ {"Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc,
+ g_vmx_regnums},
};
-static const RegisterSet
-g_reg_sets_powerpc[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
- { "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
- { "Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
-};
-
-static_assert(k_first_gpr_powerpc == 0, "GPRs must index starting at 0, or fix IsGPR()");
-bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
-{
- return (reg <= k_last_gpr_powerpc); // GPR's come first.
+static_assert(k_first_gpr_powerpc == 0,
+ "GPRs must index starting at 0, or fix IsGPR()");
+bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg) {
+ return (reg <= k_last_gpr_powerpc); // GPR's come first.
}
-bool
-RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
-{
- return (reg >= k_first_fpr) && (reg <= k_last_fpr);
+bool RegisterContextPOSIX_powerpc::IsFPR(unsigned reg) {
+ return (reg >= k_first_fpr) && (reg <= k_last_fpr);
}
-bool
-RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
-{
- return (reg >= k_first_vmx) && (reg <= k_last_vmx);
+bool RegisterContextPOSIX_powerpc::IsVMX(unsigned reg) {
+ return (reg >= k_first_vmx) && (reg <= k_last_vmx);
}
-RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
-RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
-{
+ // elf-core yet to support ReadFPR()
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_powerpc::Invalidate()
-{
-}
+RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() {}
-void
-RegisterContextPOSIX_powerpc::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_powerpc::Invalidate() {}
-unsigned
-RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg)
-{
- assert(reg < k_num_registers_powerpc && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+void RegisterContextPOSIX_powerpc::InvalidateAllRegisters() {}
+
+unsigned RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg) {
+ assert(reg < k_num_registers_powerpc && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg)
-{
- assert(reg < k_num_registers_powerpc && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg) {
+ assert(reg < k_num_registers_powerpc && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_powerpc::GetRegisterCount()
-{
- size_t num_registers = k_num_registers_powerpc;
- return num_registers;
+size_t RegisterContextPOSIX_powerpc::GetRegisterCount() {
+ size_t num_registers = k_num_registers_powerpc;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_powerpc::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize();
+size_t RegisterContextPOSIX_powerpc::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-const RegisterInfo *
-RegisterContextPOSIX_powerpc::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+const RegisterInfo *RegisterContextPOSIX_powerpc::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_registers_powerpc)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_registers_powerpc)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_powerpc::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
-
- return sets;
+size_t RegisterContextPOSIX_powerpc::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- return &g_reg_sets_powerpc[set];
- else
- return NULL;
+const RegisterSet *RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set))
+ return &g_reg_sets_powerpc[set];
+ else
+ return NULL;
}
-const char *
-RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg)
-{
- assert(reg < k_num_registers_powerpc && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) {
+ assert(reg < k_num_registers_powerpc && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_powerpc::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_powerpc::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
-{
- size_t num_sets = k_num_register_sets;
+bool RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) {
+ size_t num_sets = k_num_register_sets;
- return (set_index < num_sets);
+ return (set_index < num_sets);
}
// Used when parsing DWARF and EH frame information and any other
// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
+uint32_t RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index 4168e46ebd9a..79bb01f6740c 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -14,210 +14,196 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "RegisterContext_powerpc.h"
+#include "RegisterInfoInterface.h"
#include "lldb/Core/Log.h"
#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
-#include "RegisterContext_powerpc.h"
class ProcessMonitor;
// ---------------------------------------------------------------------------
// Internal codes for all powerpc registers.
// ---------------------------------------------------------------------------
-enum
-{
- k_first_gpr_powerpc,
- gpr_r0_powerpc = k_first_gpr_powerpc,
- gpr_r1_powerpc,
- gpr_r2_powerpc,
- gpr_r3_powerpc,
- gpr_r4_powerpc,
- gpr_r5_powerpc,
- gpr_r6_powerpc,
- gpr_r7_powerpc,
- gpr_r8_powerpc,
- gpr_r9_powerpc,
- gpr_r10_powerpc,
- gpr_r11_powerpc,
- gpr_r12_powerpc,
- gpr_r13_powerpc,
- gpr_r14_powerpc,
- gpr_r15_powerpc,
- gpr_r16_powerpc,
- gpr_r17_powerpc,
- gpr_r18_powerpc,
- gpr_r19_powerpc,
- gpr_r20_powerpc,
- gpr_r21_powerpc,
- gpr_r22_powerpc,
- gpr_r23_powerpc,
- gpr_r24_powerpc,
- gpr_r25_powerpc,
- gpr_r26_powerpc,
- gpr_r27_powerpc,
- gpr_r28_powerpc,
- gpr_r29_powerpc,
- gpr_r30_powerpc,
- gpr_r31_powerpc,
- gpr_lr_powerpc,
- gpr_cr_powerpc,
- gpr_xer_powerpc,
- gpr_ctr_powerpc,
- gpr_pc_powerpc,
- k_last_gpr_powerpc = gpr_pc_powerpc,
-
- k_first_fpr,
- fpr_f0_powerpc = k_first_fpr,
- fpr_f1_powerpc,
- fpr_f2_powerpc,
- fpr_f3_powerpc,
- fpr_f4_powerpc,
- fpr_f5_powerpc,
- fpr_f6_powerpc,
- fpr_f7_powerpc,
- fpr_f8_powerpc,
- fpr_f9_powerpc,
- fpr_f10_powerpc,
- fpr_f11_powerpc,
- fpr_f12_powerpc,
- fpr_f13_powerpc,
- fpr_f14_powerpc,
- fpr_f15_powerpc,
- fpr_f16_powerpc,
- fpr_f17_powerpc,
- fpr_f18_powerpc,
- fpr_f19_powerpc,
- fpr_f20_powerpc,
- fpr_f21_powerpc,
- fpr_f22_powerpc,
- fpr_f23_powerpc,
- fpr_f24_powerpc,
- fpr_f25_powerpc,
- fpr_f26_powerpc,
- fpr_f27_powerpc,
- fpr_f28_powerpc,
- fpr_f29_powerpc,
- fpr_f30_powerpc,
- fpr_f31_powerpc,
- fpr_fpscr_powerpc,
- k_last_fpr = fpr_fpscr_powerpc,
-
- k_first_vmx,
- vmx_v0_powerpc = k_first_vmx,
- vmx_v1_powerpc,
- vmx_v2_powerpc,
- vmx_v3_powerpc,
- vmx_v4_powerpc,
- vmx_v5_powerpc,
- vmx_v6_powerpc,
- vmx_v7_powerpc,
- vmx_v8_powerpc,
- vmx_v9_powerpc,
- vmx_v10_powerpc,
- vmx_v11_powerpc,
- vmx_v12_powerpc,
- vmx_v13_powerpc,
- vmx_v14_powerpc,
- vmx_v15_powerpc,
- vmx_v16_powerpc,
- vmx_v17_powerpc,
- vmx_v18_powerpc,
- vmx_v19_powerpc,
- vmx_v20_powerpc,
- vmx_v21_powerpc,
- vmx_v22_powerpc,
- vmx_v23_powerpc,
- vmx_v24_powerpc,
- vmx_v25_powerpc,
- vmx_v26_powerpc,
- vmx_v27_powerpc,
- vmx_v28_powerpc,
- vmx_v29_powerpc,
- vmx_v30_powerpc,
- vmx_v31_powerpc,
- vmx_vrsave_powerpc,
- vmx_vscr_powerpc,
- k_last_vmx = vmx_vscr_powerpc,
-
- k_num_registers_powerpc,
- k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
- k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
- k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
+enum {
+ k_first_gpr_powerpc,
+ gpr_r0_powerpc = k_first_gpr_powerpc,
+ gpr_r1_powerpc,
+ gpr_r2_powerpc,
+ gpr_r3_powerpc,
+ gpr_r4_powerpc,
+ gpr_r5_powerpc,
+ gpr_r6_powerpc,
+ gpr_r7_powerpc,
+ gpr_r8_powerpc,
+ gpr_r9_powerpc,
+ gpr_r10_powerpc,
+ gpr_r11_powerpc,
+ gpr_r12_powerpc,
+ gpr_r13_powerpc,
+ gpr_r14_powerpc,
+ gpr_r15_powerpc,
+ gpr_r16_powerpc,
+ gpr_r17_powerpc,
+ gpr_r18_powerpc,
+ gpr_r19_powerpc,
+ gpr_r20_powerpc,
+ gpr_r21_powerpc,
+ gpr_r22_powerpc,
+ gpr_r23_powerpc,
+ gpr_r24_powerpc,
+ gpr_r25_powerpc,
+ gpr_r26_powerpc,
+ gpr_r27_powerpc,
+ gpr_r28_powerpc,
+ gpr_r29_powerpc,
+ gpr_r30_powerpc,
+ gpr_r31_powerpc,
+ gpr_lr_powerpc,
+ gpr_cr_powerpc,
+ gpr_xer_powerpc,
+ gpr_ctr_powerpc,
+ gpr_pc_powerpc,
+ k_last_gpr_powerpc = gpr_pc_powerpc,
+
+ k_first_fpr,
+ fpr_f0_powerpc = k_first_fpr,
+ fpr_f1_powerpc,
+ fpr_f2_powerpc,
+ fpr_f3_powerpc,
+ fpr_f4_powerpc,
+ fpr_f5_powerpc,
+ fpr_f6_powerpc,
+ fpr_f7_powerpc,
+ fpr_f8_powerpc,
+ fpr_f9_powerpc,
+ fpr_f10_powerpc,
+ fpr_f11_powerpc,
+ fpr_f12_powerpc,
+ fpr_f13_powerpc,
+ fpr_f14_powerpc,
+ fpr_f15_powerpc,
+ fpr_f16_powerpc,
+ fpr_f17_powerpc,
+ fpr_f18_powerpc,
+ fpr_f19_powerpc,
+ fpr_f20_powerpc,
+ fpr_f21_powerpc,
+ fpr_f22_powerpc,
+ fpr_f23_powerpc,
+ fpr_f24_powerpc,
+ fpr_f25_powerpc,
+ fpr_f26_powerpc,
+ fpr_f27_powerpc,
+ fpr_f28_powerpc,
+ fpr_f29_powerpc,
+ fpr_f30_powerpc,
+ fpr_f31_powerpc,
+ fpr_fpscr_powerpc,
+ k_last_fpr = fpr_fpscr_powerpc,
+
+ k_first_vmx,
+ vmx_v0_powerpc = k_first_vmx,
+ vmx_v1_powerpc,
+ vmx_v2_powerpc,
+ vmx_v3_powerpc,
+ vmx_v4_powerpc,
+ vmx_v5_powerpc,
+ vmx_v6_powerpc,
+ vmx_v7_powerpc,
+ vmx_v8_powerpc,
+ vmx_v9_powerpc,
+ vmx_v10_powerpc,
+ vmx_v11_powerpc,
+ vmx_v12_powerpc,
+ vmx_v13_powerpc,
+ vmx_v14_powerpc,
+ vmx_v15_powerpc,
+ vmx_v16_powerpc,
+ vmx_v17_powerpc,
+ vmx_v18_powerpc,
+ vmx_v19_powerpc,
+ vmx_v20_powerpc,
+ vmx_v21_powerpc,
+ vmx_v22_powerpc,
+ vmx_v23_powerpc,
+ vmx_v24_powerpc,
+ vmx_v25_powerpc,
+ vmx_v26_powerpc,
+ vmx_v27_powerpc,
+ vmx_v28_powerpc,
+ vmx_v29_powerpc,
+ vmx_v30_powerpc,
+ vmx_v31_powerpc,
+ vmx_vrsave_powerpc,
+ vmx_vscr_powerpc,
+ k_last_vmx = vmx_vscr_powerpc,
+
+ k_num_registers_powerpc,
+ k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
+ k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
+ k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
};
-class RegisterContextPOSIX_powerpc
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_powerpc : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_powerpc (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_powerpc(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_powerpc() override;
+ ~RegisterContextPOSIX_powerpc() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
- uint64_t m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
- uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+ uint64_t
+ m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
+ uint64_t
+ m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
+ uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
- bool
- IsGPR(unsigned reg);
+ bool IsGPR(unsigned reg);
- bool
- IsFPR(unsigned reg);
+ bool IsFPR(unsigned reg);
- bool
- IsVMX(unsigned reg);
+ bool IsVMX(unsigned reg);
- lldb::ByteOrder GetByteOrder();
+ lldb::ByteOrder GetByteOrder();
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool ReadVMX() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
- virtual bool WriteVMX() = 0;
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool ReadVMX() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
+ virtual bool WriteVMX() = 0;
};
#endif // liblldb_RegisterContextPOSIX_powerpc_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
index 960be50c7be3..e4dbe333a22d 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_s390x.cpp --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,245 +21,172 @@
#include "lldb/Target/Thread.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContext_s390x.h"
#include "RegisterContextPOSIX_s390x.h"
+#include "RegisterContext_s390x.h"
using namespace lldb_private;
using namespace lldb;
// s390x 64-bit general purpose registers.
-static const uint32_t g_gpr_regnums_s390x[] =
-{
- lldb_r0_s390x,
- lldb_r1_s390x,
- lldb_r2_s390x,
- lldb_r3_s390x,
- lldb_r4_s390x,
- lldb_r5_s390x,
- lldb_r6_s390x,
- lldb_r7_s390x,
- lldb_r8_s390x,
- lldb_r9_s390x,
- lldb_r10_s390x,
- lldb_r11_s390x,
- lldb_r12_s390x,
- lldb_r13_s390x,
- lldb_r14_s390x,
- lldb_r15_s390x,
- lldb_acr0_s390x,
- lldb_acr1_s390x,
- lldb_acr2_s390x,
- lldb_acr3_s390x,
- lldb_acr4_s390x,
- lldb_acr5_s390x,
- lldb_acr6_s390x,
- lldb_acr7_s390x,
- lldb_acr8_s390x,
- lldb_acr9_s390x,
- lldb_acr10_s390x,
- lldb_acr11_s390x,
- lldb_acr12_s390x,
- lldb_acr13_s390x,
- lldb_acr14_s390x,
- lldb_acr15_s390x,
- lldb_pswm_s390x,
- lldb_pswa_s390x,
+static const uint32_t g_gpr_regnums_s390x[] = {
+ lldb_r0_s390x, lldb_r1_s390x, lldb_r2_s390x, lldb_r3_s390x,
+ lldb_r4_s390x, lldb_r5_s390x, lldb_r6_s390x, lldb_r7_s390x,
+ lldb_r8_s390x, lldb_r9_s390x, lldb_r10_s390x, lldb_r11_s390x,
+ lldb_r12_s390x, lldb_r13_s390x, lldb_r14_s390x, lldb_r15_s390x,
+ lldb_acr0_s390x, lldb_acr1_s390x, lldb_acr2_s390x, lldb_acr3_s390x,
+ lldb_acr4_s390x, lldb_acr5_s390x, lldb_acr6_s390x, lldb_acr7_s390x,
+ lldb_acr8_s390x, lldb_acr9_s390x, lldb_acr10_s390x, lldb_acr11_s390x,
+ lldb_acr12_s390x, lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x,
+ lldb_pswm_s390x, lldb_pswa_s390x,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 1 == k_num_gpr_registers_s390x,
+static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
+ 1 ==
+ k_num_gpr_registers_s390x,
"g_gpr_regnums_s390x has wrong number of register infos");
// s390x 64-bit floating point registers.
-static const uint32_t g_fpu_regnums_s390x[] =
-{
- lldb_f0_s390x,
- lldb_f1_s390x,
- lldb_f2_s390x,
- lldb_f3_s390x,
- lldb_f4_s390x,
- lldb_f5_s390x,
- lldb_f6_s390x,
- lldb_f7_s390x,
- lldb_f8_s390x,
- lldb_f9_s390x,
- lldb_f10_s390x,
- lldb_f11_s390x,
- lldb_f12_s390x,
- lldb_f13_s390x,
- lldb_f14_s390x,
- lldb_f15_s390x,
+static const uint32_t g_fpu_regnums_s390x[] = {
+ lldb_f0_s390x, lldb_f1_s390x, lldb_f2_s390x, lldb_f3_s390x,
+ lldb_f4_s390x, lldb_f5_s390x, lldb_f6_s390x, lldb_f7_s390x,
+ lldb_f8_s390x, lldb_f9_s390x, lldb_f10_s390x, lldb_f11_s390x,
+ lldb_f12_s390x, lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x,
lldb_fpc_s390x,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 1 == k_num_fpr_registers_s390x,
+static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
+ 1 ==
+ k_num_fpr_registers_s390x,
"g_fpu_regnums_s390x has wrong number of register infos");
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 2
-};
+enum { k_num_register_sets = 2 };
// Register sets for s390x 64-bit.
-static const RegisterSet g_reg_sets_s390x[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_s390x, g_gpr_regnums_s390x },
- { "Floating Point Registers", "fpr", k_num_fpr_registers_s390x, g_fpu_regnums_s390x },
+static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
+ g_gpr_regnums_s390x},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
+ g_fpu_regnums_s390x},
};
-bool
-RegisterContextPOSIX_s390x::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPRs come first.
+bool RegisterContextPOSIX_s390x::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPRs come first.
}
-bool
-RegisterContextPOSIX_s390x::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_s390x::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(Thread &thread, uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
+RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- m_reg_info.num_registers = k_num_registers_s390x;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
- m_reg_info.last_gpr = k_last_gpr_s390x;
- m_reg_info.first_fpr = k_first_fpr_s390x;
- m_reg_info.last_fpr = k_last_fpr_s390x;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ m_reg_info.num_registers = k_num_registers_s390x;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
+ m_reg_info.last_gpr = k_last_gpr_s390x;
+ m_reg_info.first_fpr = k_first_fpr_s390x;
+ m_reg_info.last_fpr = k_last_fpr_s390x;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
}
-RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x()
-{
-}
+RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() {}
-void
-RegisterContextPOSIX_s390x::Invalidate()
-{
-}
+void RegisterContextPOSIX_s390x::Invalidate() {}
-void
-RegisterContextPOSIX_s390x::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_s390x::InvalidateAllRegisters() {}
-const RegisterInfo *
-RegisterContextPOSIX_s390x::GetRegisterInfo()
-{
- return m_register_info_ap->GetRegisterInfo();
+const RegisterInfo *RegisterContextPOSIX_s390x::GetRegisterInfo() {
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_s390x::GetRegisterCount()
-{
- return m_reg_info.num_registers;
+size_t RegisterContextPOSIX_s390x::GetRegisterCount() {
+ return m_reg_info.num_registers;
}
-unsigned
-RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+unsigned RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-const char *
-RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-bool
-RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index)
-{
- return set_index < k_num_register_sets;
+bool RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index) {
+ return set_index < k_num_register_sets;
}
-size_t
-RegisterContextPOSIX_s390x::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_s390x::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_s390x::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return &g_reg_sets_s390x[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return &g_reg_sets_s390x[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-lldb::ByteOrder
-RegisterContextPOSIX_s390x::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
// Used when parsing DWARF and EH frame information and any other
// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
+uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
- return LLDB_INVALID_REGNUM;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
index 4904b2857c43..1ffc45c2d4b1 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
@@ -14,90 +14,71 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
#include "RegisterContext_s390x.h"
+#include "RegisterInfoInterface.h"
#include "lldb-s390x-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_s390x(lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_s390x(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_s390x() override;
+ ~RegisterContextPOSIX_s390x() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- };
-
- RegInfo m_reg_info;
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap;
-
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- lldb::ByteOrder
- GetByteOrder();
-
- virtual bool
- ReadGPR() = 0;
- virtual bool
- ReadFPR() = 0;
- virtual bool
- WriteGPR() = 0;
- virtual bool
- WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ };
+
+ RegInfo m_reg_info;
+ std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap;
+
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_s390x_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 77b6385da8bd..99525b6c2df2 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -15,187 +15,94 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
+#include "lldb/Target/Process.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContext_x86.h"
#include "RegisterContextPOSIX_x86.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContext_x86.h"
using namespace lldb_private;
using namespace lldb;
-const uint32_t
-g_gpr_regnums_i386[] =
-{
- lldb_eax_i386,
- lldb_ebx_i386,
- lldb_ecx_i386,
- lldb_edx_i386,
- lldb_edi_i386,
- lldb_esi_i386,
- lldb_ebp_i386,
- lldb_esp_i386,
- lldb_eip_i386,
- lldb_eflags_i386,
- lldb_cs_i386,
- lldb_fs_i386,
- lldb_gs_i386,
- lldb_ss_i386,
- lldb_ds_i386,
- lldb_es_i386,
- lldb_ax_i386,
- lldb_bx_i386,
- lldb_cx_i386,
- lldb_dx_i386,
- lldb_di_i386,
- lldb_si_i386,
- lldb_bp_i386,
- lldb_sp_i386,
- lldb_ah_i386,
- lldb_bh_i386,
- lldb_ch_i386,
- lldb_dh_i386,
- lldb_al_i386,
- lldb_bl_i386,
- lldb_cl_i386,
- lldb_dl_i386,
- LLDB_INVALID_REGNUM, // Register sets must be terminated with LLDB_INVALID_REGNUM.
+const uint32_t g_gpr_regnums_i386[] = {
+ lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
+ lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
+ lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
+ lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
+ lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
+ lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
+ lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
+ lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM, // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 1 == k_num_gpr_registers_i386,
- "g_gpr_regnums_i386 has wrong number of register infos");
-
-const uint32_t
-g_lldb_regnums_i386[] =
-{
- lldb_fctrl_i386,
- lldb_fstat_i386,
- lldb_ftag_i386,
- lldb_fop_i386,
- lldb_fiseg_i386,
- lldb_fioff_i386,
- lldb_foseg_i386,
- lldb_fooff_i386,
- lldb_mxcsr_i386,
- lldb_mxcsrmask_i386,
- lldb_st0_i386,
- lldb_st1_i386,
- lldb_st2_i386,
- lldb_st3_i386,
- lldb_st4_i386,
- lldb_st5_i386,
- lldb_st6_i386,
- lldb_st7_i386,
- lldb_mm0_i386,
- lldb_mm1_i386,
- lldb_mm2_i386,
- lldb_mm3_i386,
- lldb_mm4_i386,
- lldb_mm5_i386,
- lldb_mm6_i386,
- lldb_mm7_i386,
- lldb_xmm0_i386,
- lldb_xmm1_i386,
- lldb_xmm2_i386,
- lldb_xmm3_i386,
- lldb_xmm4_i386,
- lldb_xmm5_i386,
- lldb_xmm6_i386,
- lldb_xmm7_i386,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
+ 1 ==
+ k_num_gpr_registers_i386,
+ "g_gpr_regnums_i386 has wrong number of register infos");
+
+const uint32_t g_lldb_regnums_i386[] = {
+ lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
+ lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
+ lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
+ lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
+ lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
+ lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
+ lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
+ lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
+ lldb_xmm6_i386, lldb_xmm7_i386,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) - 1 == k_num_fpr_registers_i386,
- "g_lldb_regnums_i386 has wrong number of register infos");
-
-const uint32_t
-g_avx_regnums_i386[] =
-{
- lldb_ymm0_i386,
- lldb_ymm1_i386,
- lldb_ymm2_i386,
- lldb_ymm3_i386,
- lldb_ymm4_i386,
- lldb_ymm5_i386,
- lldb_ymm6_i386,
- lldb_ymm7_i386,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) -
+ 1 ==
+ k_num_fpr_registers_i386,
+ "g_lldb_regnums_i386 has wrong number of register infos");
+
+const uint32_t g_avx_regnums_i386[] = {
+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 == k_num_avx_registers_i386,
- " g_avx_regnums_i386 has wrong number of register infos");
-
-static const
-uint32_t g_gpr_regnums_x86_64[] =
-{
- lldb_rax_x86_64,
- lldb_rbx_x86_64,
- lldb_rcx_x86_64,
- lldb_rdx_x86_64,
- lldb_rdi_x86_64,
- lldb_rsi_x86_64,
- lldb_rbp_x86_64,
- lldb_rsp_x86_64,
- lldb_r8_x86_64,
- lldb_r9_x86_64,
- lldb_r10_x86_64,
- lldb_r11_x86_64,
- lldb_r12_x86_64,
- lldb_r13_x86_64,
- lldb_r14_x86_64,
- lldb_r15_x86_64,
- lldb_rip_x86_64,
- lldb_rflags_x86_64,
- lldb_cs_x86_64,
- lldb_fs_x86_64,
- lldb_gs_x86_64,
- lldb_ss_x86_64,
- lldb_ds_x86_64,
- lldb_es_x86_64,
- lldb_eax_x86_64,
- lldb_ebx_x86_64,
- lldb_ecx_x86_64,
- lldb_edx_x86_64,
- lldb_edi_x86_64,
- lldb_esi_x86_64,
- lldb_ebp_x86_64,
- lldb_esp_x86_64,
- lldb_r8d_x86_64, // Low 32 bits or r8
- lldb_r9d_x86_64, // Low 32 bits or r9
- lldb_r10d_x86_64, // Low 32 bits or r10
- lldb_r11d_x86_64, // Low 32 bits or r11
- lldb_r12d_x86_64, // Low 32 bits or r12
- lldb_r13d_x86_64, // Low 32 bits or r13
- lldb_r14d_x86_64, // Low 32 bits or r14
- lldb_r15d_x86_64, // Low 32 bits or r15
- lldb_ax_x86_64,
- lldb_bx_x86_64,
- lldb_cx_x86_64,
- lldb_dx_x86_64,
- lldb_di_x86_64,
- lldb_si_x86_64,
- lldb_bp_x86_64,
- lldb_sp_x86_64,
- lldb_r8w_x86_64, // Low 16 bits or r8
- lldb_r9w_x86_64, // Low 16 bits or r9
- lldb_r10w_x86_64, // Low 16 bits or r10
- lldb_r11w_x86_64, // Low 16 bits or r11
- lldb_r12w_x86_64, // Low 16 bits or r12
- lldb_r13w_x86_64, // Low 16 bits or r13
- lldb_r14w_x86_64, // Low 16 bits or r14
- lldb_r15w_x86_64, // Low 16 bits or r15
- lldb_ah_x86_64,
- lldb_bh_x86_64,
- lldb_ch_x86_64,
- lldb_dh_x86_64,
- lldb_al_x86_64,
- lldb_bl_x86_64,
- lldb_cl_x86_64,
- lldb_dl_x86_64,
- lldb_dil_x86_64,
- lldb_sil_x86_64,
- lldb_bpl_x86_64,
- lldb_spl_x86_64,
+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
+ 1 ==
+ k_num_avx_registers_i386,
+ " g_avx_regnums_i386 has wrong number of register infos");
+
+static const uint32_t g_gpr_regnums_x86_64[] = {
+ lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
+ lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
+ lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
+ lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
+ lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
+ lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
+ lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
+ lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits or r8
+ lldb_r9d_x86_64, // Low 32 bits or r9
+ lldb_r10d_x86_64, // Low 32 bits or r10
+ lldb_r11d_x86_64, // Low 32 bits or r11
+ lldb_r12d_x86_64, // Low 32 bits or r12
+ lldb_r13d_x86_64, // Low 32 bits or r13
+ lldb_r14d_x86_64, // Low 32 bits or r14
+ lldb_r15d_x86_64, // Low 32 bits or r15
+ lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
+ lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits or r8
+ lldb_r9w_x86_64, // Low 16 bits or r9
+ lldb_r10w_x86_64, // Low 16 bits or r10
+ lldb_r11w_x86_64, // Low 16 bits or r11
+ lldb_r12w_x86_64, // Low 16 bits or r12
+ lldb_r13w_x86_64, // Low 16 bits or r13
+ lldb_r14w_x86_64, // Low 16 bits or r14
+ lldb_r15w_x86_64, // Low 16 bits or r15
+ lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
+ lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
+ lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
lldb_r8l_x86_64, // Low 8 bits or r8
lldb_r9l_x86_64, // Low 8 bits or r9
lldb_r10l_x86_64, // Low 8 bits or r10
@@ -204,464 +111,445 @@ uint32_t g_gpr_regnums_x86_64[] =
lldb_r13l_x86_64, // Low 8 bits or r13
lldb_r14l_x86_64, // Low 8 bits or r14
lldb_r15l_x86_64, // Low 8 bits or r15
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 1 == k_num_gpr_registers_x86_64,
- "g_gpr_regnums_x86_64 has wrong number of register infos");
-
-static const uint32_t
-g_lldb_regnums_x86_64[] =
-{
- lldb_fctrl_x86_64,
- lldb_fstat_x86_64,
- lldb_ftag_x86_64,
- lldb_fop_x86_64,
- lldb_fiseg_x86_64,
- lldb_fioff_x86_64,
- lldb_foseg_x86_64,
- lldb_fooff_x86_64,
- lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64,
- lldb_st0_x86_64,
- lldb_st1_x86_64,
- lldb_st2_x86_64,
- lldb_st3_x86_64,
- lldb_st4_x86_64,
- lldb_st5_x86_64,
- lldb_st6_x86_64,
- lldb_st7_x86_64,
- lldb_mm0_x86_64,
- lldb_mm1_x86_64,
- lldb_mm2_x86_64,
- lldb_mm3_x86_64,
- lldb_mm4_x86_64,
- lldb_mm5_x86_64,
- lldb_mm6_x86_64,
- lldb_mm7_x86_64,
- lldb_xmm0_x86_64,
- lldb_xmm1_x86_64,
- lldb_xmm2_x86_64,
- lldb_xmm3_x86_64,
- lldb_xmm4_x86_64,
- lldb_xmm5_x86_64,
- lldb_xmm6_x86_64,
- lldb_xmm7_x86_64,
- lldb_xmm8_x86_64,
- lldb_xmm9_x86_64,
- lldb_xmm10_x86_64,
- lldb_xmm11_x86_64,
- lldb_xmm12_x86_64,
- lldb_xmm13_x86_64,
- lldb_xmm14_x86_64,
- lldb_xmm15_x86_64,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
+ 1 ==
+ k_num_gpr_registers_x86_64,
+ "g_gpr_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t g_lldb_regnums_x86_64[] = {
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+ lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
+ lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
+ lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
+ lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
+ lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
+ lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
+ lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
+ lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
+ lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
+ lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
+ lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_lldb_regnums_x86_64) / sizeof(g_lldb_regnums_x86_64[0])) - 1 == k_num_fpr_registers_x86_64,
- "g_lldb_regnums_x86_64 has wrong number of register infos");
-
-static const uint32_t
-g_avx_regnums_x86_64[] =
-{
- lldb_ymm0_x86_64,
- lldb_ymm1_x86_64,
- lldb_ymm2_x86_64,
- lldb_ymm3_x86_64,
- lldb_ymm4_x86_64,
- lldb_ymm5_x86_64,
- lldb_ymm6_x86_64,
- lldb_ymm7_x86_64,
- lldb_ymm8_x86_64,
- lldb_ymm9_x86_64,
- lldb_ymm10_x86_64,
- lldb_ymm11_x86_64,
- lldb_ymm12_x86_64,
- lldb_ymm13_x86_64,
- lldb_ymm14_x86_64,
- lldb_ymm15_x86_64,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_lldb_regnums_x86_64) /
+ sizeof(g_lldb_regnums_x86_64[0])) -
+ 1 ==
+ k_num_fpr_registers_x86_64,
+ "g_lldb_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t g_avx_regnums_x86_64[] = {
+ lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
+ lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
+ lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
+ lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == k_num_avx_registers_x86_64,
- "g_avx_regnums_x86_64 has wrong number of register infos");
-
-uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = { lldb_eax_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = { lldb_ebx_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = { lldb_ecx_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = { lldb_edx_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = { lldb_edi_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = { lldb_esi_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = { lldb_ebp_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = { lldb_esp_i386, LLDB_INVALID_REGNUM };
-
-uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = { lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = { lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = { lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = { lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = { lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = { lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = { lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = { lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM };
-
-uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = { lldb_rax_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = { lldb_rbx_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = { lldb_rcx_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = { lldb_rdx_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = { lldb_rdi_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = { lldb_rsi_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = { lldb_rbp_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = { lldb_rsp_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = { lldb_r8_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = { lldb_r9_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = { lldb_r10_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = { lldb_r11_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = { lldb_r12_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = { lldb_r13_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = { lldb_r14_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = { lldb_r15_x86_64, LLDB_INVALID_REGNUM };
-
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = { lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64, lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = { lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64, lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = { lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64, lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = { lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64, lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = { lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = { lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = { lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = { lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = { lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = { lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = { lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = { lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = { lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = { lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = { lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = { lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64, LLDB_INVALID_REGNUM };
+static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = {lldb_eax_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = {lldb_ebx_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = {lldb_ecx_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = {lldb_edx_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = {lldb_edi_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = {lldb_esi_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = {lldb_ebp_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = {lldb_esp_i386,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = {
+ lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = {
+ lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = {
+ lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = {
+ lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = {
+ lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = {
+ lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = {
+ lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = {
+ lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = {lldb_rax_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = {lldb_rbx_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = {lldb_rcx_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = {lldb_rdx_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = {lldb_rdi_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = {lldb_rsi_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = {lldb_rbp_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = {lldb_rsp_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = {lldb_r8_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = {lldb_r9_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = {lldb_r10_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = {lldb_r11_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = {lldb_r12_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = {lldb_r13_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = {lldb_r14_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = {lldb_r15_x86_64,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = {
+ lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64,
+ lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = {
+ lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64,
+ lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = {
+ lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64,
+ lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = {
+ lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64,
+ lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = {
+ lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = {
+ lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = {
+ lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = {
+ lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = {
+ lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = {
+ lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = {
+ lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = {
+ lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = {
+ lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = {
+ lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = {
+ lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {
+ lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,
+ LLDB_INVALID_REGNUM};
// Number of register sets provided by this context.
-enum
-{
- k_num_extended_register_sets = 1,
- k_num_register_sets = 3
-};
-
-static const RegisterSet
-g_reg_sets_i386[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_lldb_regnums_i386 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
-};
-
-static const RegisterSet
-g_reg_sets_x86_64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_lldb_regnums_x86_64 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 }
-};
-
-bool RegisterContextPOSIX_x86::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
+
+static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
+ g_gpr_regnums_i386},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
+ g_lldb_regnums_i386},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
+ g_avx_regnums_i386}};
+
+static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
+ g_gpr_regnums_x86_64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
+ g_lldb_regnums_x86_64},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
+ g_avx_regnums_x86_64}};
+
+bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool RegisterContextPOSIX_x86::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-bool RegisterContextPOSIX_x86::IsAVX(unsigned reg)
-{
- return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
+bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) {
+ return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
}
-bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type)
-{
- bool generic_fpr = IsFPR(reg);
+bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) {
+ bool generic_fpr = IsFPR(reg);
- if (fpr_type == eXSAVE)
- return generic_fpr || IsAVX(reg);
- return generic_fpr;
+ if (fpr_type == eXSAVE)
+ return generic_fpr || IsAVX(reg);
+ return generic_fpr;
}
-RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(Thread &thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- m_reg_info.num_registers = k_num_registers_i386;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
- m_reg_info.num_avx_registers = k_num_avx_registers_i386;
- m_reg_info.last_gpr = k_last_gpr_i386;
- m_reg_info.first_fpr = k_first_fpr_i386;
- m_reg_info.last_fpr = k_last_fpr_i386;
- m_reg_info.first_st = lldb_st0_i386;
- m_reg_info.last_st = lldb_st7_i386;
- m_reg_info.first_mm = lldb_mm0_i386;
- m_reg_info.last_mm = lldb_mm7_i386;
- m_reg_info.first_xmm = lldb_xmm0_i386;
- m_reg_info.last_xmm = lldb_xmm7_i386;
- m_reg_info.first_ymm = lldb_ymm0_i386;
- m_reg_info.last_ymm = lldb_ymm7_i386;
- m_reg_info.first_dr = lldb_dr0_i386;
- m_reg_info.gpr_flags = lldb_eflags_i386;
- break;
- case llvm::Triple::x86_64:
- m_reg_info.num_registers = k_num_registers_x86_64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
- m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
- m_reg_info.last_gpr = k_last_gpr_x86_64;
- m_reg_info.first_fpr = k_first_fpr_x86_64;
- m_reg_info.last_fpr = k_last_fpr_x86_64;
- m_reg_info.first_st = lldb_st0_x86_64;
- m_reg_info.last_st = lldb_st7_x86_64;
- m_reg_info.first_mm = lldb_mm0_x86_64;
- m_reg_info.last_mm = lldb_mm7_x86_64;
- m_reg_info.first_xmm = lldb_xmm0_x86_64;
- m_reg_info.last_xmm = lldb_xmm15_x86_64;
- m_reg_info.first_ymm = lldb_ymm0_x86_64;
- m_reg_info.last_ymm = lldb_ymm15_x86_64;
- m_reg_info.first_dr = lldb_dr0_x86_64;
- m_reg_info.gpr_flags = lldb_rflags_x86_64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
+
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ m_reg_info.num_registers = k_num_registers_i386;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
+ m_reg_info.num_avx_registers = k_num_avx_registers_i386;
+ m_reg_info.last_gpr = k_last_gpr_i386;
+ m_reg_info.first_fpr = k_first_fpr_i386;
+ m_reg_info.last_fpr = k_last_fpr_i386;
+ m_reg_info.first_st = lldb_st0_i386;
+ m_reg_info.last_st = lldb_st7_i386;
+ m_reg_info.first_mm = lldb_mm0_i386;
+ m_reg_info.last_mm = lldb_mm7_i386;
+ m_reg_info.first_xmm = lldb_xmm0_i386;
+ m_reg_info.last_xmm = lldb_xmm7_i386;
+ m_reg_info.first_ymm = lldb_ymm0_i386;
+ m_reg_info.last_ymm = lldb_ymm7_i386;
+ m_reg_info.first_dr = lldb_dr0_i386;
+ m_reg_info.gpr_flags = lldb_eflags_i386;
+ break;
+ case llvm::Triple::x86_64:
+ m_reg_info.num_registers = k_num_registers_x86_64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
+ m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
+ m_reg_info.last_gpr = k_last_gpr_x86_64;
+ m_reg_info.first_fpr = k_first_fpr_x86_64;
+ m_reg_info.last_fpr = k_last_fpr_x86_64;
+ m_reg_info.first_st = lldb_st0_x86_64;
+ m_reg_info.last_st = lldb_st7_x86_64;
+ m_reg_info.first_mm = lldb_mm0_x86_64;
+ m_reg_info.last_mm = lldb_mm7_x86_64;
+ m_reg_info.first_xmm = lldb_xmm0_x86_64;
+ m_reg_info.last_xmm = lldb_xmm15_x86_64;
+ m_reg_info.first_ymm = lldb_ymm0_x86_64;
+ m_reg_info.last_ymm = lldb_ymm15_x86_64;
+ m_reg_info.first_dr = lldb_dr0_x86_64;
+ m_reg_info.gpr_flags = lldb_rflags_x86_64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_fpr.xstate.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+
+ ::memset(&m_fpr, 0, sizeof(FPR));
+
+ m_fpr_type = eNotValid;
+}
- ::memset(&m_fpr, 0, sizeof(FPR));
+RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() {}
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-
- m_fpr_type = eNotValid;
+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())
+ m_fpr_type = eFXSAVE; // assume generic floating-point registers
+ }
+ return m_fpr_type;
}
-RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86()
-{
-}
+void RegisterContextPOSIX_x86::Invalidate() {}
-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())
- m_fpr_type = eFXSAVE; // assume generic floating-point registers
- }
- return m_fpr_type;
-}
+void RegisterContextPOSIX_x86::InvalidateAllRegisters() {}
-void
-RegisterContextPOSIX_x86::Invalidate()
-{
+unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-void
-RegisterContextPOSIX_x86::InvalidateAllRegisters()
-{
+unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-unsigned
-RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+size_t RegisterContextPOSIX_x86::GetRegisterCount() {
+ size_t num_registers =
+ m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+ if (GetFPRType() == eXSAVE)
+ return num_registers + m_reg_info.num_avx_registers;
+ return num_registers;
}
-unsigned
-RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+size_t RegisterContextPOSIX_x86::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-size_t
-RegisterContextPOSIX_x86::GetRegisterCount()
-{
- size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- if (GetFPRType() == eXSAVE)
- return num_registers + m_reg_info.num_avx_registers;
- return num_registers;
+size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() {
+ return GetRegisterInfo()[m_reg_info.first_fpr].byte_offset;
}
-size_t
-RegisterContextPOSIX_x86::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize ();
+const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_x86::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
-}
-
-const RegisterInfo *
-RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_x86::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_x86::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_x86::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return &g_reg_sets_i386[set];
- case llvm::Triple::x86_64:
- return &g_reg_sets_x86_64[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterSet *RegisterContextPOSIX_x86::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return &g_reg_sets_i386[set];
+ case llvm::Triple::x86_64:
+ return &g_reg_sets_x86_64[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-const char *
-RegisterContextPOSIX_x86::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_x86::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_x86::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
// Parse ymm registers and into xmm.bytes and ymmh.bytes.
-bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == eByteOrderLittle)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(YMMHReg));
- return true;
- }
-
- if (byte_order == eByteOrderBig)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
+bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
+ lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == eByteOrderLittle) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == eByteOrderBig) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
// Concatenate xmm.bytes with ymmh.bytes
-bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == eByteOrderLittle)
- {
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
-
- if (byte_order == eByteOrderBig)
- {
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
+bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
+ lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == eByteOrderLittle) {
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == eByteOrderBig) {
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
-bool
-RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index)
-{
- // Note: Extended register sets are assumed to be at the end of g_reg_sets...
- size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) {
+ // Note: Extended register sets are assumed to be at the end of g_reg_sets...
+ size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
- if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
- ++num_sets;
- return (set_index < num_sets);
+ if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
+ ++num_sets;
+ return (set_index < num_sets);
}
-
// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+// object file sections that contain register numbers in them.
+uint32_t RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- return LLDB_INVALID_REGNUM;
-}
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index b4708255a566..c5afe089e476 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -14,181 +14,170 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
#include "RegisterContext_x86.h"
+#include "RegisterInfoInterface.h"
#include "lldb-x86-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_x86
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_x86 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
-
- ~RegisterContextPOSIX_x86() override;
-
- void
- Invalidate();
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- virtual size_t
- GetGPRSize();
-
- virtual unsigned
- GetRegisterSize(unsigned reg);
-
- virtual unsigned
- GetRegisterOffset(unsigned reg);
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
-
- const char *
- GetRegisterName(unsigned reg);
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- //---------------------------------------------------------------------------
- // Note: prefer kernel definitions over user-land
- //---------------------------------------------------------------------------
- enum FPRType
- {
- eNotValid = 0,
- eFSAVE, // TODO
- eFXSAVE,
- eSOFT, // TODO
- eXSAVE
- };
-
- static uint32_t g_contained_eax[];
- static uint32_t g_contained_ebx[];
- static uint32_t g_contained_ecx[];
- static uint32_t g_contained_edx[];
- static uint32_t g_contained_edi[];
- static uint32_t g_contained_esi[];
- static uint32_t g_contained_ebp[];
- static uint32_t g_contained_esp[];
-
- static uint32_t g_invalidate_eax[];
- static uint32_t g_invalidate_ebx[];
- static uint32_t g_invalidate_ecx[];
- static uint32_t g_invalidate_edx[];
- static uint32_t g_invalidate_edi[];
- static uint32_t g_invalidate_esi[];
- static uint32_t g_invalidate_ebp[];
- static uint32_t g_invalidate_esp[];
-
- static uint32_t g_contained_rax[];
- static uint32_t g_contained_rbx[];
- static uint32_t g_contained_rcx[];
- static uint32_t g_contained_rdx[];
- static uint32_t g_contained_rdi[];
- static uint32_t g_contained_rsi[];
- static uint32_t g_contained_rbp[];
- static uint32_t g_contained_rsp[];
- static uint32_t g_contained_r8[];
- static uint32_t g_contained_r9[];
- static uint32_t g_contained_r10[];
- static uint32_t g_contained_r11[];
- static uint32_t g_contained_r12[];
- static uint32_t g_contained_r13[];
- static uint32_t g_contained_r14[];
- static uint32_t g_contained_r15[];
-
- static uint32_t g_invalidate_rax[];
- static uint32_t g_invalidate_rbx[];
- static uint32_t g_invalidate_rcx[];
- static uint32_t g_invalidate_rdx[];
- static uint32_t g_invalidate_rdi[];
- static uint32_t g_invalidate_rsi[];
- static uint32_t g_invalidate_rbp[];
- static uint32_t g_invalidate_rsp[];
- static uint32_t g_invalidate_r8[];
- static uint32_t g_invalidate_r9[];
- static uint32_t g_invalidate_r10[];
- static uint32_t g_invalidate_r11[];
- static uint32_t g_invalidate_r12[];
- static uint32_t g_invalidate_r13[];
- static uint32_t g_invalidate_r14[];
- static uint32_t g_invalidate_r15[];
+ RegisterContextPOSIX_x86(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
+
+ ~RegisterContextPOSIX_x86() override;
+
+ void Invalidate();
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ virtual size_t GetGPRSize();
+
+ virtual size_t GetFXSAVEOffset();
+
+ virtual unsigned GetRegisterSize(unsigned reg);
+
+ virtual unsigned GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+ const char *GetRegisterName(unsigned reg);
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ //---------------------------------------------------------------------------
+ // Note: prefer kernel definitions over user-land
+ //---------------------------------------------------------------------------
+ enum FPRType {
+ eNotValid = 0,
+ eFSAVE, // TODO
+ eFXSAVE,
+ eSOFT, // TODO
+ eXSAVE
+ };
+
+ static uint32_t g_contained_eax[];
+ static uint32_t g_contained_ebx[];
+ static uint32_t g_contained_ecx[];
+ static uint32_t g_contained_edx[];
+ static uint32_t g_contained_edi[];
+ static uint32_t g_contained_esi[];
+ static uint32_t g_contained_ebp[];
+ static uint32_t g_contained_esp[];
+
+ static uint32_t g_invalidate_eax[];
+ static uint32_t g_invalidate_ebx[];
+ static uint32_t g_invalidate_ecx[];
+ static uint32_t g_invalidate_edx[];
+ static uint32_t g_invalidate_edi[];
+ static uint32_t g_invalidate_esi[];
+ static uint32_t g_invalidate_ebp[];
+ static uint32_t g_invalidate_esp[];
+
+ static uint32_t g_contained_rax[];
+ static uint32_t g_contained_rbx[];
+ static uint32_t g_contained_rcx[];
+ static uint32_t g_contained_rdx[];
+ static uint32_t g_contained_rdi[];
+ static uint32_t g_contained_rsi[];
+ static uint32_t g_contained_rbp[];
+ static uint32_t g_contained_rsp[];
+ static uint32_t g_contained_r8[];
+ static uint32_t g_contained_r9[];
+ static uint32_t g_contained_r10[];
+ static uint32_t g_contained_r11[];
+ static uint32_t g_contained_r12[];
+ static uint32_t g_contained_r13[];
+ static uint32_t g_contained_r14[];
+ static uint32_t g_contained_r15[];
+
+ static uint32_t g_invalidate_rax[];
+ static uint32_t g_invalidate_rbx[];
+ static uint32_t g_invalidate_rcx[];
+ static uint32_t g_invalidate_rdx[];
+ static uint32_t g_invalidate_rdi[];
+ static uint32_t g_invalidate_rsi[];
+ static uint32_t g_invalidate_rbp[];
+ static uint32_t g_invalidate_rsp[];
+ static uint32_t g_invalidate_r8[];
+ static uint32_t g_invalidate_r9[];
+ static uint32_t g_invalidate_r10[];
+ static uint32_t g_invalidate_r11[];
+ static uint32_t g_invalidate_r12[];
+ static uint32_t g_invalidate_r13[];
+ static uint32_t g_invalidate_r14[];
+ static uint32_t g_invalidate_r15[];
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
- uint32_t num_avx_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_st;
- uint32_t last_st;
- uint32_t first_mm;
- uint32_t last_mm;
- uint32_t first_xmm;
- uint32_t last_xmm;
- uint32_t first_ymm;
- uint32_t last_ymm;
-
- uint32_t first_dr;
- uint32_t gpr_flags;
- };
-
- uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit general purpose registers.
- RegInfo m_reg_info;
- FPRType m_fpr_type; // determines the type of data stored by union FPR, if any.
- FPR m_fpr; // floating-point registers including extended register sets.
- IOVEC m_iovec; // wrapper for xsave.
- YMM m_ymm_set; // copy of ymmh and xmm register halves.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- bool
- IsAVX(unsigned reg);
-
- lldb::ByteOrder GetByteOrder();
-
- bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
- bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
- bool IsFPR(unsigned reg, FPRType fpr_type);
- FPRType GetFPRType();
-
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+ uint32_t num_avx_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_st;
+ uint32_t last_st;
+ uint32_t first_mm;
+ uint32_t last_mm;
+ uint32_t first_xmm;
+ uint32_t last_xmm;
+ uint32_t first_ymm;
+ uint32_t last_ymm;
+
+ uint32_t first_dr;
+ uint32_t gpr_flags;
+ };
+
+ uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit
+ // general
+ // purpose
+ // registers.
+ RegInfo m_reg_info;
+ FPRType
+ m_fpr_type; // determines the type of data stored by union FPR, if any.
+ FPR m_fpr; // floating-point registers including extended register sets.
+ IOVEC m_iovec; // wrapper for xsave.
+ YMM m_ymm_set; // copy of ymmh and xmm register halves.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ bool IsAVX(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
+ bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
+ bool IsFPR(unsigned reg, FPRType fpr_type);
+ FPRType GetFPRType();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_x86_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
index 200ef4d3d651..2b5cb00fa96a 100644
--- a/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
@@ -7,255 +7,213 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private.h"
#include "lldb/Core/Error.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextThreadMemory.h"
using namespace lldb;
using namespace lldb_private;
-RegisterContextThreadMemory::RegisterContextThreadMemory (Thread &thread,
- lldb::addr_t register_data_addr) :
- RegisterContext (thread, 0),
- m_thread_wp (thread.shared_from_this()),
- m_reg_ctx_sp (),
- m_register_data_addr (register_data_addr),
- m_stop_id(0)
-{
-}
+RegisterContextThreadMemory::RegisterContextThreadMemory(
+ Thread &thread, lldb::addr_t register_data_addr)
+ : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()),
+ m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {}
-RegisterContextThreadMemory::~RegisterContextThreadMemory()
-{
-}
+RegisterContextThreadMemory::~RegisterContextThreadMemory() {}
-void
-RegisterContextThreadMemory::UpdateRegisterContext ()
-{
- ThreadSP thread_sp (m_thread_wp.lock());
- if (thread_sp)
- {
- ProcessSP process_sp (thread_sp->GetProcess());
+void RegisterContextThreadMemory::UpdateRegisterContext() {
+ ThreadSP thread_sp(m_thread_wp.lock());
+ if (thread_sp) {
+ ProcessSP process_sp(thread_sp->GetProcess());
- if (process_sp)
- {
- const uint32_t stop_id = process_sp->GetModID().GetStopID();
- if (m_stop_id != stop_id)
- {
- m_stop_id = stop_id;
- m_reg_ctx_sp.reset();
- }
- if (!m_reg_ctx_sp)
- {
- ThreadSP backing_thread_sp (thread_sp->GetBackingThread());
- if (backing_thread_sp)
- {
- m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
- }
- else
- {
- OperatingSystem *os = process_sp->GetOperatingSystem ();
- if (os->IsOperatingSystemPluginThread (thread_sp))
- m_reg_ctx_sp = os->CreateRegisterContextForThread (thread_sp.get(), m_register_data_addr);
- }
- }
- }
- else
- {
- m_reg_ctx_sp.reset();
- }
- }
- else
- {
+ if (process_sp) {
+ const uint32_t stop_id = process_sp->GetModID().GetStopID();
+ if (m_stop_id != stop_id) {
+ m_stop_id = stop_id;
m_reg_ctx_sp.reset();
+ }
+ if (!m_reg_ctx_sp) {
+ ThreadSP backing_thread_sp(thread_sp->GetBackingThread());
+ if (backing_thread_sp) {
+ m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
+ } else {
+ OperatingSystem *os = process_sp->GetOperatingSystem();
+ if (os->IsOperatingSystemPluginThread(thread_sp))
+ m_reg_ctx_sp = os->CreateRegisterContextForThread(
+ thread_sp.get(), m_register_data_addr);
+ }
+ }
+ } else {
+ m_reg_ctx_sp.reset();
}
+ } else {
+ m_reg_ctx_sp.reset();
+ }
}
//------------------------------------------------------------------
// Subclasses must override these functions
//------------------------------------------------------------------
-void
-RegisterContextThreadMemory::InvalidateAllRegisters ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- m_reg_ctx_sp->InvalidateAllRegisters();
+void RegisterContextThreadMemory::InvalidateAllRegisters() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ m_reg_ctx_sp->InvalidateAllRegisters();
}
-size_t
-RegisterContextThreadMemory::GetRegisterCount ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterCount();
- return 0;
+size_t RegisterContextThreadMemory::GetRegisterCount() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterCount();
+ return 0;
}
const RegisterInfo *
-RegisterContextThreadMemory::GetRegisterInfoAtIndex (size_t reg)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
- return NULL;
-}
-
-size_t
-RegisterContextThreadMemory::GetRegisterSetCount ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterSetCount();
- return 0;
-}
-
-const RegisterSet *
-RegisterContextThreadMemory::GetRegisterSet (size_t reg_set)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterSet(reg_set);
- return NULL;
-}
-
-bool
-RegisterContextThreadMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->WriteRegister (reg_info, reg_value);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->WriteAllRegisterValues (data_sp);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::CopyFromRegisterContext (lldb::RegisterContextSP reg_ctx_sp)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::NumSupportedHardwareBreakpoints ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
- return 0;
-}
-
-bool
-RegisterContextThreadMemory::ClearHardwareBreakpoint (uint32_t hw_idx)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ClearHardwareBreakpoint (hw_idx);
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::NumSupportedHardwareWatchpoints ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
- return 0;
+RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
+ return NULL;
}
-uint32_t
-RegisterContextThreadMemory::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
- return 0;
+size_t RegisterContextThreadMemory::GetRegisterSetCount() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterSetCount();
+ return 0;
}
-bool
-RegisterContextThreadMemory::ClearHardwareWatchpoint (uint32_t hw_index)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
- return false;
+const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterSet(reg_set);
+ return NULL;
}
-bool
-RegisterContextThreadMemory::HardwareSingleStep (bool enable)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->HardwareSingleStep(enable);
- return false;
+bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
+ return false;
}
-Error
-RegisterContextThreadMemory::ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ReadRegisterValueFromMemory (reg_info, src_addr, src_len, reg_value);
- Error error;
- error.SetErrorString("invalid register context");
- return error;
+bool RegisterContextThreadMemory::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->WriteRegister(reg_info, reg_value);
+ return false;
}
-Error
-RegisterContextThreadMemory::WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->WriteRegisterValueToMemory (reg_info, dst_addr, dst_len, reg_value);
- Error error;
- error.SetErrorString("invalid register context");
- return error;
+bool RegisterContextThreadMemory::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
+ return false;
+}
+
+bool RegisterContextThreadMemory::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->WriteAllRegisterValues(data_sp);
+ return false;
+}
+
+bool RegisterContextThreadMemory::CopyFromRegisterContext(
+ lldb::RegisterContextSP reg_ctx_sp) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
+ return 0;
+}
+
+bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx);
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
+ return 0;
+}
+
+uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size,
+ bool read,
+ bool write) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
+ return 0;
+}
+
+bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
+ return false;
+}
+
+bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->HardwareSingleStep(enable);
+ return false;
+}
+
+Error RegisterContextThreadMemory::ReadRegisterValueFromMemory(
+ const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr,
+ uint32_t src_len, RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr,
+ src_len, reg_value);
+ Error error;
+ error.SetErrorString("invalid register context");
+ return error;
+}
+
+Error RegisterContextThreadMemory::WriteRegisterValueToMemory(
+ const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr,
+ uint32_t dst_len, const RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len,
+ reg_value);
+ Error error;
+ error.SetErrorString("invalid register context");
+ return error;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
index b4680de79514..7e0a2a9f7f1e 100644
--- a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
+++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
@@ -16,103 +16,88 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class RegisterContextThreadMemory : public lldb_private::RegisterContext
-{
+
+class RegisterContextThreadMemory : public lldb_private::RegisterContext {
public:
- RegisterContextThreadMemory (Thread &thread,
- lldb::addr_t register_data_addr);
-
- ~RegisterContextThreadMemory() override;
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- const RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const RegisterSet *
- GetRegisterSet(size_t reg_set) override;
-
- bool
- ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-
- // These two functions are used to implement "push" and "pop" of register states. They are used primarily
- // for expression evaluation, where we need to push a new state (storing the old one in data_sp) and then
- // restoring the original state by passing the data_sp we got from ReadAllRegisters to WriteAllRegisterValues.
- // ReadAllRegisters will do what is necessary to return a coherent set of register values for this thread, which
- // may mean e.g. interrupting a thread that is sitting in a kernel trap. That is a somewhat disruptive operation,
- // so these API's should only be used when this behavior is needed.
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- bool
- CopyFromRegisterContext (lldb::RegisterContextSP context);
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- uint32_t
- NumSupportedHardwareBreakpoints() override;
-
- uint32_t
- SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- bool
- ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
- uint32_t
- NumSupportedHardwareWatchpoints() override;
-
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
-
- bool
- ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- bool
- HardwareSingleStep(bool enable) override;
-
- Error
- ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info,
- lldb::addr_t src_addr,
- uint32_t src_len,
- RegisterValue &reg_value) override;
-
- Error
- WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info,
- lldb::addr_t dst_addr, uint32_t dst_len,
- const RegisterValue &reg_value) override;
+ RegisterContextThreadMemory(Thread &thread, lldb::addr_t register_data_addr);
+
+ ~RegisterContextThreadMemory() override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
+
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ // These two functions are used to implement "push" and "pop" of register
+ // states. They are used primarily
+ // for expression evaluation, where we need to push a new state (storing the
+ // old one in data_sp) and then
+ // restoring the original state by passing the data_sp we got from
+ // ReadAllRegisters to WriteAllRegisterValues.
+ // ReadAllRegisters will do what is necessary to return a coherent set of
+ // register values for this thread, which
+ // may mean e.g. interrupting a thread that is sitting in a kernel trap. That
+ // is a somewhat disruptive operation,
+ // so these API's should only be used when this behavior is needed.
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ bool CopyFromRegisterContext(lldb::RegisterContextSP context);
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ uint32_t NumSupportedHardwareBreakpoints() override;
+
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ bool HardwareSingleStep(bool enable) override;
+
+ Error ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info,
+ lldb::addr_t src_addr, uint32_t src_len,
+ RegisterValue &reg_value) override;
+
+ Error WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info,
+ lldb::addr_t dst_addr, uint32_t dst_len,
+ const RegisterValue &reg_value) override;
protected:
- void
- UpdateRegisterContext ();
-
- lldb::ThreadWP m_thread_wp;
- lldb::RegisterContextSP m_reg_ctx_sp;
- lldb::addr_t m_register_data_addr;
- uint32_t m_stop_id;
+ void UpdateRegisterContext();
+
+ lldb::ThreadWP m_thread_wp;
+ lldb::RegisterContextSP m_reg_ctx_sp;
+ lldb::addr_t m_register_data_addr;
+ uint32_t m_stop_id;
private:
- DISALLOW_COPY_AND_ASSIGN (RegisterContextThreadMemory);
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextThreadMemory);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContext_mips.h b/source/Plugins/Process/Utility/RegisterContext_mips.h
index 3603227d5e73..565747cb4bd7 100644
--- a/source/Plugins/Process/Utility/RegisterContext_mips.h
+++ b/source/Plugins/Process/Utility/RegisterContext_mips.h
@@ -10,375 +10,371 @@
#ifndef liblldb_RegisterContext_mips64_H_
#define liblldb_RegisterContext_mips64_H_
-// eh_frame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
+#include <cstddef>
+#include <cstdint>
-enum
-{
- // GP Registers
- dwarf_zero_mips = 0,
- dwarf_r1_mips,
- dwarf_r2_mips,
- dwarf_r3_mips,
- dwarf_r4_mips,
- dwarf_r5_mips,
- dwarf_r6_mips,
- dwarf_r7_mips,
- dwarf_r8_mips,
- dwarf_r9_mips,
- dwarf_r10_mips,
- dwarf_r11_mips,
- dwarf_r12_mips,
- dwarf_r13_mips,
- dwarf_r14_mips,
- dwarf_r15_mips,
- dwarf_r16_mips,
- dwarf_r17_mips,
- dwarf_r18_mips,
- dwarf_r19_mips,
- dwarf_r20_mips,
- dwarf_r21_mips,
- dwarf_r22_mips,
- dwarf_r23_mips,
- dwarf_r24_mips,
- dwarf_r25_mips,
- dwarf_r26_mips,
- dwarf_r27_mips,
- dwarf_gp_mips,
- dwarf_sp_mips,
- dwarf_r30_mips,
- dwarf_ra_mips,
- dwarf_sr_mips,
- dwarf_lo_mips,
- dwarf_hi_mips,
- dwarf_bad_mips,
- dwarf_cause_mips,
- dwarf_pc_mips,
- dwarf_f0_mips,
- dwarf_f1_mips,
- dwarf_f2_mips,
- dwarf_f3_mips,
- dwarf_f4_mips,
- dwarf_f5_mips,
- dwarf_f6_mips,
- dwarf_f7_mips,
- dwarf_f8_mips,
- dwarf_f9_mips,
- dwarf_f10_mips,
- dwarf_f11_mips,
- dwarf_f12_mips,
- dwarf_f13_mips,
- dwarf_f14_mips,
- dwarf_f15_mips,
- dwarf_f16_mips,
- dwarf_f17_mips,
- dwarf_f18_mips,
- dwarf_f19_mips,
- dwarf_f20_mips,
- dwarf_f21_mips,
- dwarf_f22_mips,
- dwarf_f23_mips,
- dwarf_f24_mips,
- dwarf_f25_mips,
- dwarf_f26_mips,
- dwarf_f27_mips,
- dwarf_f28_mips,
- dwarf_f29_mips,
- dwarf_f30_mips,
- dwarf_f31_mips,
- dwarf_fcsr_mips,
- dwarf_fir_mips,
- dwarf_w0_mips,
- dwarf_w1_mips,
- dwarf_w2_mips,
- dwarf_w3_mips,
- dwarf_w4_mips,
- dwarf_w5_mips,
- dwarf_w6_mips,
- dwarf_w7_mips,
- dwarf_w8_mips,
- dwarf_w9_mips,
- dwarf_w10_mips,
- dwarf_w11_mips,
- dwarf_w12_mips,
- dwarf_w13_mips,
- dwarf_w14_mips,
- dwarf_w15_mips,
- dwarf_w16_mips,
- dwarf_w17_mips,
- dwarf_w18_mips,
- dwarf_w19_mips,
- dwarf_w20_mips,
- dwarf_w21_mips,
- dwarf_w22_mips,
- dwarf_w23_mips,
- dwarf_w24_mips,
- dwarf_w25_mips,
- dwarf_w26_mips,
- dwarf_w27_mips,
- dwarf_w28_mips,
- dwarf_w29_mips,
- dwarf_w30_mips,
- dwarf_w31_mips,
- dwarf_mcsr_mips,
- dwarf_mir_mips,
- dwarf_config5_mips,
- dwarf_ic_mips,
- dwarf_dummy_mips
+// eh_frame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
+
+enum {
+ // GP Registers
+ dwarf_zero_mips = 0,
+ dwarf_r1_mips,
+ dwarf_r2_mips,
+ dwarf_r3_mips,
+ dwarf_r4_mips,
+ dwarf_r5_mips,
+ dwarf_r6_mips,
+ dwarf_r7_mips,
+ dwarf_r8_mips,
+ dwarf_r9_mips,
+ dwarf_r10_mips,
+ dwarf_r11_mips,
+ dwarf_r12_mips,
+ dwarf_r13_mips,
+ dwarf_r14_mips,
+ dwarf_r15_mips,
+ dwarf_r16_mips,
+ dwarf_r17_mips,
+ dwarf_r18_mips,
+ dwarf_r19_mips,
+ dwarf_r20_mips,
+ dwarf_r21_mips,
+ dwarf_r22_mips,
+ dwarf_r23_mips,
+ dwarf_r24_mips,
+ dwarf_r25_mips,
+ dwarf_r26_mips,
+ dwarf_r27_mips,
+ dwarf_gp_mips,
+ dwarf_sp_mips,
+ dwarf_r30_mips,
+ dwarf_ra_mips,
+ dwarf_sr_mips,
+ dwarf_lo_mips,
+ dwarf_hi_mips,
+ dwarf_bad_mips,
+ dwarf_cause_mips,
+ dwarf_pc_mips,
+ dwarf_f0_mips,
+ dwarf_f1_mips,
+ dwarf_f2_mips,
+ dwarf_f3_mips,
+ dwarf_f4_mips,
+ dwarf_f5_mips,
+ dwarf_f6_mips,
+ dwarf_f7_mips,
+ dwarf_f8_mips,
+ dwarf_f9_mips,
+ dwarf_f10_mips,
+ dwarf_f11_mips,
+ dwarf_f12_mips,
+ dwarf_f13_mips,
+ dwarf_f14_mips,
+ dwarf_f15_mips,
+ dwarf_f16_mips,
+ dwarf_f17_mips,
+ dwarf_f18_mips,
+ dwarf_f19_mips,
+ dwarf_f20_mips,
+ dwarf_f21_mips,
+ dwarf_f22_mips,
+ dwarf_f23_mips,
+ dwarf_f24_mips,
+ dwarf_f25_mips,
+ dwarf_f26_mips,
+ dwarf_f27_mips,
+ dwarf_f28_mips,
+ dwarf_f29_mips,
+ dwarf_f30_mips,
+ dwarf_f31_mips,
+ dwarf_fcsr_mips,
+ dwarf_fir_mips,
+ dwarf_w0_mips,
+ dwarf_w1_mips,
+ dwarf_w2_mips,
+ dwarf_w3_mips,
+ dwarf_w4_mips,
+ dwarf_w5_mips,
+ dwarf_w6_mips,
+ dwarf_w7_mips,
+ dwarf_w8_mips,
+ dwarf_w9_mips,
+ dwarf_w10_mips,
+ dwarf_w11_mips,
+ dwarf_w12_mips,
+ dwarf_w13_mips,
+ dwarf_w14_mips,
+ dwarf_w15_mips,
+ dwarf_w16_mips,
+ dwarf_w17_mips,
+ dwarf_w18_mips,
+ dwarf_w19_mips,
+ dwarf_w20_mips,
+ dwarf_w21_mips,
+ dwarf_w22_mips,
+ dwarf_w23_mips,
+ dwarf_w24_mips,
+ dwarf_w25_mips,
+ dwarf_w26_mips,
+ dwarf_w27_mips,
+ dwarf_w28_mips,
+ dwarf_w29_mips,
+ dwarf_w30_mips,
+ dwarf_w31_mips,
+ dwarf_mcsr_mips,
+ dwarf_mir_mips,
+ dwarf_config5_mips,
+ dwarf_ic_mips,
+ dwarf_dummy_mips
};
-enum
-{
- dwarf_zero_mips64 = 0,
- dwarf_r1_mips64,
- dwarf_r2_mips64,
- dwarf_r3_mips64,
- dwarf_r4_mips64,
- dwarf_r5_mips64,
- dwarf_r6_mips64,
- dwarf_r7_mips64,
- dwarf_r8_mips64,
- dwarf_r9_mips64,
- dwarf_r10_mips64,
- dwarf_r11_mips64,
- dwarf_r12_mips64,
- dwarf_r13_mips64,
- dwarf_r14_mips64,
- dwarf_r15_mips64,
- dwarf_r16_mips64,
- dwarf_r17_mips64,
- dwarf_r18_mips64,
- dwarf_r19_mips64,
- dwarf_r20_mips64,
- dwarf_r21_mips64,
- dwarf_r22_mips64,
- dwarf_r23_mips64,
- dwarf_r24_mips64,
- dwarf_r25_mips64,
- dwarf_r26_mips64,
- dwarf_r27_mips64,
- dwarf_gp_mips64,
- dwarf_sp_mips64,
- dwarf_r30_mips64,
- dwarf_ra_mips64,
- dwarf_sr_mips64,
- dwarf_lo_mips64,
- dwarf_hi_mips64,
- dwarf_bad_mips64,
- dwarf_cause_mips64,
- dwarf_pc_mips64,
- dwarf_f0_mips64,
- dwarf_f1_mips64,
- dwarf_f2_mips64,
- dwarf_f3_mips64,
- dwarf_f4_mips64,
- dwarf_f5_mips64,
- dwarf_f6_mips64,
- dwarf_f7_mips64,
- dwarf_f8_mips64,
- dwarf_f9_mips64,
- dwarf_f10_mips64,
- dwarf_f11_mips64,
- dwarf_f12_mips64,
- dwarf_f13_mips64,
- dwarf_f14_mips64,
- dwarf_f15_mips64,
- dwarf_f16_mips64,
- dwarf_f17_mips64,
- dwarf_f18_mips64,
- dwarf_f19_mips64,
- dwarf_f20_mips64,
- dwarf_f21_mips64,
- dwarf_f22_mips64,
- dwarf_f23_mips64,
- dwarf_f24_mips64,
- dwarf_f25_mips64,
- dwarf_f26_mips64,
- dwarf_f27_mips64,
- dwarf_f28_mips64,
- dwarf_f29_mips64,
- dwarf_f30_mips64,
- dwarf_f31_mips64,
- dwarf_fcsr_mips64,
- dwarf_fir_mips64,
- dwarf_ic_mips64,
- dwarf_dummy_mips64,
- dwarf_w0_mips64,
- dwarf_w1_mips64,
- dwarf_w2_mips64,
- dwarf_w3_mips64,
- dwarf_w4_mips64,
- dwarf_w5_mips64,
- dwarf_w6_mips64,
- dwarf_w7_mips64,
- dwarf_w8_mips64,
- dwarf_w9_mips64,
- dwarf_w10_mips64,
- dwarf_w11_mips64,
- dwarf_w12_mips64,
- dwarf_w13_mips64,
- dwarf_w14_mips64,
- dwarf_w15_mips64,
- dwarf_w16_mips64,
- dwarf_w17_mips64,
- dwarf_w18_mips64,
- dwarf_w19_mips64,
- dwarf_w20_mips64,
- dwarf_w21_mips64,
- dwarf_w22_mips64,
- dwarf_w23_mips64,
- dwarf_w24_mips64,
- dwarf_w25_mips64,
- dwarf_w26_mips64,
- dwarf_w27_mips64,
- dwarf_w28_mips64,
- dwarf_w29_mips64,
- dwarf_w30_mips64,
- dwarf_w31_mips64,
- dwarf_mcsr_mips64,
- dwarf_mir_mips64,
- dwarf_config5_mips64,
+enum {
+ dwarf_zero_mips64 = 0,
+ dwarf_r1_mips64,
+ dwarf_r2_mips64,
+ dwarf_r3_mips64,
+ dwarf_r4_mips64,
+ dwarf_r5_mips64,
+ dwarf_r6_mips64,
+ dwarf_r7_mips64,
+ dwarf_r8_mips64,
+ dwarf_r9_mips64,
+ dwarf_r10_mips64,
+ dwarf_r11_mips64,
+ dwarf_r12_mips64,
+ dwarf_r13_mips64,
+ dwarf_r14_mips64,
+ dwarf_r15_mips64,
+ dwarf_r16_mips64,
+ dwarf_r17_mips64,
+ dwarf_r18_mips64,
+ dwarf_r19_mips64,
+ dwarf_r20_mips64,
+ dwarf_r21_mips64,
+ dwarf_r22_mips64,
+ dwarf_r23_mips64,
+ dwarf_r24_mips64,
+ dwarf_r25_mips64,
+ dwarf_r26_mips64,
+ dwarf_r27_mips64,
+ dwarf_gp_mips64,
+ dwarf_sp_mips64,
+ dwarf_r30_mips64,
+ dwarf_ra_mips64,
+ dwarf_sr_mips64,
+ dwarf_lo_mips64,
+ dwarf_hi_mips64,
+ dwarf_bad_mips64,
+ dwarf_cause_mips64,
+ dwarf_pc_mips64,
+ dwarf_f0_mips64,
+ dwarf_f1_mips64,
+ dwarf_f2_mips64,
+ dwarf_f3_mips64,
+ dwarf_f4_mips64,
+ dwarf_f5_mips64,
+ dwarf_f6_mips64,
+ dwarf_f7_mips64,
+ dwarf_f8_mips64,
+ dwarf_f9_mips64,
+ dwarf_f10_mips64,
+ dwarf_f11_mips64,
+ dwarf_f12_mips64,
+ dwarf_f13_mips64,
+ dwarf_f14_mips64,
+ dwarf_f15_mips64,
+ dwarf_f16_mips64,
+ dwarf_f17_mips64,
+ dwarf_f18_mips64,
+ dwarf_f19_mips64,
+ dwarf_f20_mips64,
+ dwarf_f21_mips64,
+ dwarf_f22_mips64,
+ dwarf_f23_mips64,
+ dwarf_f24_mips64,
+ dwarf_f25_mips64,
+ dwarf_f26_mips64,
+ dwarf_f27_mips64,
+ dwarf_f28_mips64,
+ dwarf_f29_mips64,
+ dwarf_f30_mips64,
+ dwarf_f31_mips64,
+ dwarf_fcsr_mips64,
+ dwarf_fir_mips64,
+ dwarf_ic_mips64,
+ dwarf_dummy_mips64,
+ dwarf_w0_mips64,
+ dwarf_w1_mips64,
+ dwarf_w2_mips64,
+ dwarf_w3_mips64,
+ dwarf_w4_mips64,
+ dwarf_w5_mips64,
+ dwarf_w6_mips64,
+ dwarf_w7_mips64,
+ dwarf_w8_mips64,
+ dwarf_w9_mips64,
+ dwarf_w10_mips64,
+ dwarf_w11_mips64,
+ dwarf_w12_mips64,
+ dwarf_w13_mips64,
+ dwarf_w14_mips64,
+ dwarf_w15_mips64,
+ dwarf_w16_mips64,
+ dwarf_w17_mips64,
+ dwarf_w18_mips64,
+ dwarf_w19_mips64,
+ dwarf_w20_mips64,
+ dwarf_w21_mips64,
+ dwarf_w22_mips64,
+ dwarf_w23_mips64,
+ dwarf_w24_mips64,
+ dwarf_w25_mips64,
+ dwarf_w26_mips64,
+ dwarf_w27_mips64,
+ dwarf_w28_mips64,
+ dwarf_w29_mips64,
+ dwarf_w30_mips64,
+ dwarf_w31_mips64,
+ dwarf_mcsr_mips64,
+ dwarf_mir_mips64,
+ dwarf_config5_mips64,
};
-struct IOVEC_mips
-{
- void *iov_base;
- size_t iov_len;
+struct IOVEC_mips {
+ void *iov_base;
+ size_t iov_len;
};
// GP registers
-struct GPR_linux_mips
-{
- uint64_t zero;
- uint64_t r1;
- uint64_t r2;
- uint64_t r3;
- uint64_t r4;
- uint64_t r5;
- uint64_t r6;
- uint64_t r7;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t r16;
- uint64_t r17;
- uint64_t r18;
- uint64_t r19;
- uint64_t r20;
- uint64_t r21;
- uint64_t r22;
- uint64_t r23;
- uint64_t r24;
- uint64_t r25;
- uint64_t r26;
- uint64_t r27;
- uint64_t gp;
- uint64_t sp;
- uint64_t r30;
- uint64_t ra;
- uint64_t mullo;
- uint64_t mulhi;
- uint64_t pc;
- uint64_t badvaddr;
- uint64_t sr;
- uint64_t cause;
- uint64_t config5;
+struct GPR_linux_mips {
+ uint64_t zero;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t gp;
+ uint64_t sp;
+ uint64_t r30;
+ uint64_t ra;
+ uint64_t mullo;
+ uint64_t mulhi;
+ uint64_t pc;
+ uint64_t badvaddr;
+ uint64_t sr;
+ uint64_t cause;
+ uint64_t config5;
};
-struct FPR_linux_mips
-{
- uint64_t f0;
- uint64_t f1;
- uint64_t f2;
- uint64_t f3;
- uint64_t f4;
- uint64_t f5;
- uint64_t f6;
- uint64_t f7;
- uint64_t f8;
- uint64_t f9;
- uint64_t f10;
- uint64_t f11;
- uint64_t f12;
- uint64_t f13;
- uint64_t f14;
- uint64_t f15;
- uint64_t f16;
- uint64_t f17;
- uint64_t f18;
- uint64_t f19;
- uint64_t f20;
- uint64_t f21;
- uint64_t f22;
- uint64_t f23;
- uint64_t f24;
- uint64_t f25;
- uint64_t f26;
- uint64_t f27;
- uint64_t f28;
- uint64_t f29;
- uint64_t f30;
- uint64_t f31;
- uint32_t fcsr;
- uint32_t fir;
- uint32_t config5;
+struct FPR_linux_mips {
+ uint64_t f0;
+ uint64_t f1;
+ uint64_t f2;
+ uint64_t f3;
+ uint64_t f4;
+ uint64_t f5;
+ uint64_t f6;
+ uint64_t f7;
+ uint64_t f8;
+ uint64_t f9;
+ uint64_t f10;
+ uint64_t f11;
+ uint64_t f12;
+ uint64_t f13;
+ uint64_t f14;
+ uint64_t f15;
+ uint64_t f16;
+ uint64_t f17;
+ uint64_t f18;
+ uint64_t f19;
+ uint64_t f20;
+ uint64_t f21;
+ uint64_t f22;
+ uint64_t f23;
+ uint64_t f24;
+ uint64_t f25;
+ uint64_t f26;
+ uint64_t f27;
+ uint64_t f28;
+ uint64_t f29;
+ uint64_t f30;
+ uint64_t f31;
+ uint32_t fcsr;
+ uint32_t fir;
+ uint32_t config5;
};
-struct MSAReg
-{
- uint8_t byte[16];
+struct MSAReg {
+ uint8_t byte[16];
};
-struct MSA_linux_mips
-{
- MSAReg w0;
- MSAReg w1;
- MSAReg w2;
- MSAReg w3;
- MSAReg w4;
- MSAReg w5;
- MSAReg w6;
- MSAReg w7;
- MSAReg w8;
- MSAReg w9;
- MSAReg w10;
- MSAReg w11;
- MSAReg w12;
- MSAReg w13;
- MSAReg w14;
- MSAReg w15;
- MSAReg w16;
- MSAReg w17;
- MSAReg w18;
- MSAReg w19;
- MSAReg w20;
- MSAReg w21;
- MSAReg w22;
- MSAReg w23;
- MSAReg w24;
- MSAReg w25;
- MSAReg w26;
- MSAReg w27;
- MSAReg w28;
- MSAReg w29;
- MSAReg w30;
- MSAReg w31;
- uint32_t fcsr; /* FPU control status register */
- uint32_t fir; /* FPU implementaion revision */
- uint32_t mcsr; /* MSA control status register */
- uint32_t mir; /* MSA implementation revision */
- uint32_t config5; /* Config5 register */
+struct MSA_linux_mips {
+ MSAReg w0;
+ MSAReg w1;
+ MSAReg w2;
+ MSAReg w3;
+ MSAReg w4;
+ MSAReg w5;
+ MSAReg w6;
+ MSAReg w7;
+ MSAReg w8;
+ MSAReg w9;
+ MSAReg w10;
+ MSAReg w11;
+ MSAReg w12;
+ MSAReg w13;
+ MSAReg w14;
+ MSAReg w15;
+ MSAReg w16;
+ MSAReg w17;
+ MSAReg w18;
+ MSAReg w19;
+ MSAReg w20;
+ MSAReg w21;
+ MSAReg w22;
+ MSAReg w23;
+ MSAReg w24;
+ MSAReg w25;
+ MSAReg w26;
+ MSAReg w27;
+ MSAReg w28;
+ MSAReg w29;
+ MSAReg w30;
+ MSAReg w31;
+ uint32_t fcsr; /* FPU control status register */
+ uint32_t fir; /* FPU implementaion revision */
+ uint32_t mcsr; /* MSA control status register */
+ uint32_t mir; /* MSA implementation revision */
+ uint32_t config5; /* Config5 register */
};
-struct UserArea
-{
- GPR_linux_mips gpr; // General purpose registers.
- FPR_linux_mips fpr; // Floating point registers.
- MSA_linux_mips msa; // MSA registers.
+struct UserArea {
+ GPR_linux_mips gpr; // General purpose registers.
+ FPR_linux_mips fpr; // Floating point registers.
+ MSA_linux_mips msa; // MSA registers.
};
#endif // liblldb_RegisterContext_mips64_H_
diff --git a/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
index 2e3053cf37bc..73242952c6d0 100644
--- a/source/Plugins/Process/Utility/RegisterContext_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
@@ -1,4 +1,5 @@
-//===-- RegisterContext_powerpc.h --------------------------------*- C++ -*-===//
+//===-- RegisterContext_powerpc.h --------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,114 +11,114 @@
#ifndef liblldb_RegisterContext_powerpc_H_
#define liblldb_RegisterContext_powerpc_H_
-// eh_frame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
-enum
-{
- dwarf_r0_powerpc = 0,
- dwarf_r1_powerpc,
- dwarf_r2_powerpc,
- dwarf_r3_powerpc,
- dwarf_r4_powerpc,
- dwarf_r5_powerpc,
- dwarf_r6_powerpc,
- dwarf_r7_powerpc,
- dwarf_r8_powerpc,
- dwarf_r9_powerpc,
- dwarf_r10_powerpc,
- dwarf_r11_powerpc,
- dwarf_r12_powerpc,
- dwarf_r13_powerpc,
- dwarf_r14_powerpc,
- dwarf_r15_powerpc,
- dwarf_r16_powerpc,
- dwarf_r17_powerpc,
- dwarf_r18_powerpc,
- dwarf_r19_powerpc,
- dwarf_r20_powerpc,
- dwarf_r21_powerpc,
- dwarf_r22_powerpc,
- dwarf_r23_powerpc,
- dwarf_r24_powerpc,
- dwarf_r25_powerpc,
- dwarf_r26_powerpc,
- dwarf_r27_powerpc,
- dwarf_r28_powerpc,
- dwarf_r29_powerpc,
- dwarf_r30_powerpc,
- dwarf_r31_powerpc,
- dwarf_f0_powerpc,
- dwarf_f1_powerpc,
- dwarf_f2_powerpc,
- dwarf_f3_powerpc,
- dwarf_f4_powerpc,
- dwarf_f5_powerpc,
- dwarf_f6_powerpc,
- dwarf_f7_powerpc,
- dwarf_f8_powerpc,
- dwarf_f9_powerpc,
- dwarf_f10_powerpc,
- dwarf_f11_powerpc,
- dwarf_f12_powerpc,
- dwarf_f13_powerpc,
- dwarf_f14_powerpc,
- dwarf_f15_powerpc,
- dwarf_f16_powerpc,
- dwarf_f17_powerpc,
- dwarf_f18_powerpc,
- dwarf_f19_powerpc,
- dwarf_f20_powerpc,
- dwarf_f21_powerpc,
- dwarf_f22_powerpc,
- dwarf_f23_powerpc,
- dwarf_f24_powerpc,
- dwarf_f25_powerpc,
- dwarf_f26_powerpc,
- dwarf_f27_powerpc,
- dwarf_f28_powerpc,
- dwarf_f29_powerpc,
- dwarf_f30_powerpc,
- dwarf_f31_powerpc,
- dwarf_cr_powerpc,
- dwarf_fpscr_powerpc,
- dwarf_msr_powerpc,
- dwarf_vscr_powerpc,
- dwarf_xer_powerpc = 101,
- dwarf_lr_powerpc = 108,
- dwarf_ctr_powerpc,
- dwarf_pc_powerpc,
- dwarf_vrsave_powerpc = 356,
- dwarf_v0_powerpc = 1124,
- dwarf_v1_powerpc,
- dwarf_v2_powerpc,
- dwarf_v3_powerpc,
- dwarf_v4_powerpc,
- dwarf_v5_powerpc,
- dwarf_v6_powerpc,
- dwarf_v7_powerpc,
- dwarf_v8_powerpc,
- dwarf_v9_powerpc,
- dwarf_v10_powerpc,
- dwarf_v11_powerpc,
- dwarf_v12_powerpc,
- dwarf_v13_powerpc,
- dwarf_v14_powerpc,
- dwarf_v15_powerpc,
- dwarf_v16_powerpc,
- dwarf_v17_powerpc,
- dwarf_v18_powerpc,
- dwarf_v19_powerpc,
- dwarf_v20_powerpc,
- dwarf_v21_powerpc,
- dwarf_v22_powerpc,
- dwarf_v23_powerpc,
- dwarf_v24_powerpc,
- dwarf_v25_powerpc,
- dwarf_v26_powerpc,
- dwarf_v27_powerpc,
- dwarf_v28_powerpc,
- dwarf_v29_powerpc,
- dwarf_v30_powerpc,
- dwarf_v31_powerpc,
+// eh_frame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
+enum {
+ dwarf_r0_powerpc = 0,
+ dwarf_r1_powerpc,
+ dwarf_r2_powerpc,
+ dwarf_r3_powerpc,
+ dwarf_r4_powerpc,
+ dwarf_r5_powerpc,
+ dwarf_r6_powerpc,
+ dwarf_r7_powerpc,
+ dwarf_r8_powerpc,
+ dwarf_r9_powerpc,
+ dwarf_r10_powerpc,
+ dwarf_r11_powerpc,
+ dwarf_r12_powerpc,
+ dwarf_r13_powerpc,
+ dwarf_r14_powerpc,
+ dwarf_r15_powerpc,
+ dwarf_r16_powerpc,
+ dwarf_r17_powerpc,
+ dwarf_r18_powerpc,
+ dwarf_r19_powerpc,
+ dwarf_r20_powerpc,
+ dwarf_r21_powerpc,
+ dwarf_r22_powerpc,
+ dwarf_r23_powerpc,
+ dwarf_r24_powerpc,
+ dwarf_r25_powerpc,
+ dwarf_r26_powerpc,
+ dwarf_r27_powerpc,
+ dwarf_r28_powerpc,
+ dwarf_r29_powerpc,
+ dwarf_r30_powerpc,
+ dwarf_r31_powerpc,
+ dwarf_f0_powerpc,
+ dwarf_f1_powerpc,
+ dwarf_f2_powerpc,
+ dwarf_f3_powerpc,
+ dwarf_f4_powerpc,
+ dwarf_f5_powerpc,
+ dwarf_f6_powerpc,
+ dwarf_f7_powerpc,
+ dwarf_f8_powerpc,
+ dwarf_f9_powerpc,
+ dwarf_f10_powerpc,
+ dwarf_f11_powerpc,
+ dwarf_f12_powerpc,
+ dwarf_f13_powerpc,
+ dwarf_f14_powerpc,
+ dwarf_f15_powerpc,
+ dwarf_f16_powerpc,
+ dwarf_f17_powerpc,
+ dwarf_f18_powerpc,
+ dwarf_f19_powerpc,
+ dwarf_f20_powerpc,
+ dwarf_f21_powerpc,
+ dwarf_f22_powerpc,
+ dwarf_f23_powerpc,
+ dwarf_f24_powerpc,
+ dwarf_f25_powerpc,
+ dwarf_f26_powerpc,
+ dwarf_f27_powerpc,
+ dwarf_f28_powerpc,
+ dwarf_f29_powerpc,
+ dwarf_f30_powerpc,
+ dwarf_f31_powerpc,
+ dwarf_cr_powerpc,
+ dwarf_fpscr_powerpc,
+ dwarf_msr_powerpc,
+ dwarf_vscr_powerpc,
+ dwarf_xer_powerpc = 101,
+ dwarf_lr_powerpc = 108,
+ dwarf_ctr_powerpc,
+ dwarf_pc_powerpc,
+ dwarf_vrsave_powerpc = 356,
+ dwarf_v0_powerpc = 1124,
+ dwarf_v1_powerpc,
+ dwarf_v2_powerpc,
+ dwarf_v3_powerpc,
+ dwarf_v4_powerpc,
+ dwarf_v5_powerpc,
+ dwarf_v6_powerpc,
+ dwarf_v7_powerpc,
+ dwarf_v8_powerpc,
+ dwarf_v9_powerpc,
+ dwarf_v10_powerpc,
+ dwarf_v11_powerpc,
+ dwarf_v12_powerpc,
+ dwarf_v13_powerpc,
+ dwarf_v14_powerpc,
+ dwarf_v15_powerpc,
+ dwarf_v16_powerpc,
+ dwarf_v17_powerpc,
+ dwarf_v18_powerpc,
+ dwarf_v19_powerpc,
+ dwarf_v20_powerpc,
+ dwarf_v21_powerpc,
+ dwarf_v22_powerpc,
+ dwarf_v23_powerpc,
+ dwarf_v24_powerpc,
+ dwarf_v25_powerpc,
+ dwarf_v26_powerpc,
+ dwarf_v27_powerpc,
+ dwarf_v28_powerpc,
+ dwarf_v29_powerpc,
+ dwarf_v30_powerpc,
+ dwarf_v31_powerpc,
};
#endif // liblldb_RegisterContext_powerpc_H_
diff --git a/source/Plugins/Process/Utility/RegisterContext_s390x.h b/source/Plugins/Process/Utility/RegisterContext_s390x.h
index 9777c7744409..90803dc16785 100644
--- a/source/Plugins/Process/Utility/RegisterContext_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterContext_s390x.h
@@ -14,80 +14,80 @@
// SystemZ ehframe, dwarf regnums
//---------------------------------------------------------------------------
-// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
-enum
-{
- // General Purpose Registers
- dwarf_r0_s390x = 0,
- dwarf_r1_s390x,
- dwarf_r2_s390x,
- dwarf_r3_s390x,
- dwarf_r4_s390x,
- dwarf_r5_s390x,
- dwarf_r6_s390x,
- dwarf_r7_s390x,
- dwarf_r8_s390x,
- dwarf_r9_s390x,
- dwarf_r10_s390x,
- dwarf_r11_s390x,
- dwarf_r12_s390x,
- dwarf_r13_s390x,
- dwarf_r14_s390x,
- dwarf_r15_s390x,
- // Floating Point Registers / Vector Registers 0-15
- dwarf_f0_s390x = 16,
- dwarf_f2_s390x,
- dwarf_f4_s390x,
- dwarf_f6_s390x,
- dwarf_f1_s390x,
- dwarf_f3_s390x,
- dwarf_f5_s390x,
- dwarf_f7_s390x,
- dwarf_f8_s390x,
- dwarf_f10_s390x,
- dwarf_f12_s390x,
- dwarf_f14_s390x,
- dwarf_f9_s390x,
- dwarf_f11_s390x,
- dwarf_f13_s390x,
- dwarf_f15_s390x,
- // Access Registers
- dwarf_acr0_s390x = 48,
- dwarf_acr1_s390x,
- dwarf_acr2_s390x,
- dwarf_acr3_s390x,
- dwarf_acr4_s390x,
- dwarf_acr5_s390x,
- dwarf_acr6_s390x,
- dwarf_acr7_s390x,
- dwarf_acr8_s390x,
- dwarf_acr9_s390x,
- dwarf_acr10_s390x,
- dwarf_acr11_s390x,
- dwarf_acr12_s390x,
- dwarf_acr13_s390x,
- dwarf_acr14_s390x,
- dwarf_acr15_s390x,
- // Program Status Word
- dwarf_pswm_s390x = 64,
- dwarf_pswa_s390x,
- // Vector Registers 16-31
- dwarf_v16_s390x = 68,
- dwarf_v18_s390x,
- dwarf_v20_s390x,
- dwarf_v22_s390x,
- dwarf_v17_s390x,
- dwarf_v19_s390x,
- dwarf_v21_s390x,
- dwarf_v23_s390x,
- dwarf_v24_s390x,
- dwarf_v26_s390x,
- dwarf_v28_s390x,
- dwarf_v30_s390x,
- dwarf_v25_s390x,
- dwarf_v27_s390x,
- dwarf_v29_s390x,
- dwarf_v31_s390x,
+// EHFrame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
+enum {
+ // General Purpose Registers
+ dwarf_r0_s390x = 0,
+ dwarf_r1_s390x,
+ dwarf_r2_s390x,
+ dwarf_r3_s390x,
+ dwarf_r4_s390x,
+ dwarf_r5_s390x,
+ dwarf_r6_s390x,
+ dwarf_r7_s390x,
+ dwarf_r8_s390x,
+ dwarf_r9_s390x,
+ dwarf_r10_s390x,
+ dwarf_r11_s390x,
+ dwarf_r12_s390x,
+ dwarf_r13_s390x,
+ dwarf_r14_s390x,
+ dwarf_r15_s390x,
+ // Floating Point Registers / Vector Registers 0-15
+ dwarf_f0_s390x = 16,
+ dwarf_f2_s390x,
+ dwarf_f4_s390x,
+ dwarf_f6_s390x,
+ dwarf_f1_s390x,
+ dwarf_f3_s390x,
+ dwarf_f5_s390x,
+ dwarf_f7_s390x,
+ dwarf_f8_s390x,
+ dwarf_f10_s390x,
+ dwarf_f12_s390x,
+ dwarf_f14_s390x,
+ dwarf_f9_s390x,
+ dwarf_f11_s390x,
+ dwarf_f13_s390x,
+ dwarf_f15_s390x,
+ // Access Registers
+ dwarf_acr0_s390x = 48,
+ dwarf_acr1_s390x,
+ dwarf_acr2_s390x,
+ dwarf_acr3_s390x,
+ dwarf_acr4_s390x,
+ dwarf_acr5_s390x,
+ dwarf_acr6_s390x,
+ dwarf_acr7_s390x,
+ dwarf_acr8_s390x,
+ dwarf_acr9_s390x,
+ dwarf_acr10_s390x,
+ dwarf_acr11_s390x,
+ dwarf_acr12_s390x,
+ dwarf_acr13_s390x,
+ dwarf_acr14_s390x,
+ dwarf_acr15_s390x,
+ // Program Status Word
+ dwarf_pswm_s390x = 64,
+ dwarf_pswa_s390x,
+ // Vector Registers 16-31
+ dwarf_v16_s390x = 68,
+ dwarf_v18_s390x,
+ dwarf_v20_s390x,
+ dwarf_v22_s390x,
+ dwarf_v17_s390x,
+ dwarf_v19_s390x,
+ dwarf_v21_s390x,
+ dwarf_v23_s390x,
+ dwarf_v24_s390x,
+ dwarf_v26_s390x,
+ dwarf_v28_s390x,
+ dwarf_v30_s390x,
+ dwarf_v25_s390x,
+ dwarf_v27_s390x,
+ dwarf_v29_s390x,
+ dwarf_v31_s390x,
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h
index 252f1253a086..ab2ca2bb6c2c 100644
--- a/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -10,319 +10,350 @@
#ifndef liblldb_RegisterContext_x86_H_
#define liblldb_RegisterContext_x86_H_
+#include <cstddef>
+#include <cstdint>
+
+#include "llvm/Support/Compiler.h"
+
//---------------------------------------------------------------------------
// i386 ehframe, dwarf regnums
//---------------------------------------------------------------------------
-// Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems (non-Darwin)
+// Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems
+// (non-Darwin)
//
-enum
-{
- ehframe_eax_i386 = 0,
- ehframe_ecx_i386,
- ehframe_edx_i386,
- ehframe_ebx_i386,
+enum {
+ ehframe_eax_i386 = 0,
+ ehframe_ecx_i386,
+ ehframe_edx_i386,
+ ehframe_ebx_i386,
- // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus dwarf's reg numbering).
- // To be specific:
- // i386+darwin eh_frame: 4 is ebp, 5 is esp
- // i386+everyone else eh_frame: 4 is esp, 5 is ebp
- // i386 dwarf: 4 is esp, 5 is ebp
- // lldb will get the darwin-specific eh_frame reg numberings from debugserver, or the ABI, so we
- // only encode the generally correct 4 == esp, 5 == ebp numbers in this generic header.
+ // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus
+ // dwarf's reg numbering).
+ // To be specific:
+ // i386+darwin eh_frame: 4 is ebp, 5 is esp
+ // i386+everyone else eh_frame: 4 is esp, 5 is ebp
+ // i386 dwarf: 4 is esp, 5 is ebp
+ // lldb will get the darwin-specific eh_frame reg numberings from debugserver,
+ // or the ABI, so we
+ // only encode the generally correct 4 == esp, 5 == ebp numbers in this
+ // generic header.
- ehframe_esp_i386,
- ehframe_ebp_i386,
- ehframe_esi_i386,
- ehframe_edi_i386,
- ehframe_eip_i386,
- ehframe_eflags_i386,
- ehframe_st0_i386 = 12,
- ehframe_st1_i386,
- ehframe_st2_i386,
- ehframe_st3_i386,
- ehframe_st4_i386,
- ehframe_st5_i386,
- ehframe_st6_i386,
- ehframe_st7_i386,
- ehframe_xmm0_i386 = 21,
- ehframe_xmm1_i386,
- ehframe_xmm2_i386,
- ehframe_xmm3_i386,
- ehframe_xmm4_i386,
- ehframe_xmm5_i386,
- ehframe_xmm6_i386,
- ehframe_xmm7_i386,
- ehframe_mm0_i386 = 29,
- ehframe_mm1_i386,
- ehframe_mm2_i386,
- ehframe_mm3_i386,
- ehframe_mm4_i386,
- ehframe_mm5_i386,
- ehframe_mm6_i386,
- ehframe_mm7_i386,
+ ehframe_esp_i386,
+ ehframe_ebp_i386,
+ ehframe_esi_i386,
+ ehframe_edi_i386,
+ ehframe_eip_i386,
+ ehframe_eflags_i386,
+ ehframe_st0_i386 = 12,
+ ehframe_st1_i386,
+ ehframe_st2_i386,
+ ehframe_st3_i386,
+ ehframe_st4_i386,
+ ehframe_st5_i386,
+ ehframe_st6_i386,
+ ehframe_st7_i386,
+ ehframe_xmm0_i386 = 21,
+ ehframe_xmm1_i386,
+ ehframe_xmm2_i386,
+ ehframe_xmm3_i386,
+ ehframe_xmm4_i386,
+ ehframe_xmm5_i386,
+ ehframe_xmm6_i386,
+ ehframe_xmm7_i386,
+ ehframe_mm0_i386 = 29,
+ ehframe_mm1_i386,
+ ehframe_mm2_i386,
+ ehframe_mm3_i386,
+ ehframe_mm4_i386,
+ ehframe_mm5_i386,
+ ehframe_mm6_i386,
+ ehframe_mm7_i386,
};
// DWARF register numbers (eRegisterKindDWARF)
// Intel's x86 or IA-32
-enum
-{
- // General Purpose Registers.
- dwarf_eax_i386 = 0,
- dwarf_ecx_i386,
- dwarf_edx_i386,
- dwarf_ebx_i386,
- dwarf_esp_i386,
- dwarf_ebp_i386,
- dwarf_esi_i386,
- dwarf_edi_i386,
- dwarf_eip_i386,
- dwarf_eflags_i386,
- // Floating Point Registers
- dwarf_st0_i386 = 11,
- dwarf_st1_i386,
- dwarf_st2_i386,
- dwarf_st3_i386,
- dwarf_st4_i386,
- dwarf_st5_i386,
- dwarf_st6_i386,
- dwarf_st7_i386,
- // SSE Registers
- dwarf_xmm0_i386 = 21,
- dwarf_xmm1_i386,
- dwarf_xmm2_i386,
- dwarf_xmm3_i386,
- dwarf_xmm4_i386,
- dwarf_xmm5_i386,
- dwarf_xmm6_i386,
- dwarf_xmm7_i386,
- // MMX Registers
- dwarf_mm0_i386 = 29,
- dwarf_mm1_i386,
- dwarf_mm2_i386,
- dwarf_mm3_i386,
- dwarf_mm4_i386,
- dwarf_mm5_i386,
- dwarf_mm6_i386,
- dwarf_mm7_i386,
- dwarf_fctrl_i386 = 37, // x87 control word
- dwarf_fstat_i386 = 38, // x87 status word
- dwarf_mxcsr_i386 = 39,
- dwarf_es_i386 = 40,
- dwarf_cs_i386 = 41,
- dwarf_ss_i386 = 42,
- dwarf_ds_i386 = 43,
- dwarf_fs_i386 = 44,
- dwarf_gs_i386 = 45
+enum {
+ // General Purpose Registers.
+ dwarf_eax_i386 = 0,
+ dwarf_ecx_i386,
+ dwarf_edx_i386,
+ dwarf_ebx_i386,
+ dwarf_esp_i386,
+ dwarf_ebp_i386,
+ dwarf_esi_i386,
+ dwarf_edi_i386,
+ dwarf_eip_i386,
+ dwarf_eflags_i386,
+ // Floating Point Registers
+ dwarf_st0_i386 = 11,
+ dwarf_st1_i386,
+ dwarf_st2_i386,
+ dwarf_st3_i386,
+ dwarf_st4_i386,
+ dwarf_st5_i386,
+ dwarf_st6_i386,
+ dwarf_st7_i386,
+ // SSE Registers
+ dwarf_xmm0_i386 = 21,
+ dwarf_xmm1_i386,
+ dwarf_xmm2_i386,
+ dwarf_xmm3_i386,
+ dwarf_xmm4_i386,
+ dwarf_xmm5_i386,
+ dwarf_xmm6_i386,
+ dwarf_xmm7_i386,
+ // MMX Registers
+ dwarf_mm0_i386 = 29,
+ dwarf_mm1_i386,
+ dwarf_mm2_i386,
+ dwarf_mm3_i386,
+ dwarf_mm4_i386,
+ dwarf_mm5_i386,
+ dwarf_mm6_i386,
+ dwarf_mm7_i386,
+ dwarf_fctrl_i386 = 37, // x87 control word
+ dwarf_fstat_i386 = 38, // x87 status word
+ dwarf_mxcsr_i386 = 39,
+ dwarf_es_i386 = 40,
+ dwarf_cs_i386 = 41,
+ dwarf_ss_i386 = 42,
+ dwarf_ds_i386 = 43,
+ dwarf_fs_i386 = 44,
+ dwarf_gs_i386 = 45,
- // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
- // then differentiate based on size of the register.
+ // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
+ // then differentiate based on size of the register.
+ dwarf_bnd0_i386 = 101,
+ dwarf_bnd1_i386,
+ dwarf_bnd2_i386,
+ dwarf_bnd3_i386,
};
//---------------------------------------------------------------------------
// AMD x86_64, AMD64, Intel EM64T, or Intel 64 ehframe, dwarf regnums
//---------------------------------------------------------------------------
-// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
+// EHFrame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
// This is the spec I used (as opposed to x86-64-abi-0.99.pdf):
// http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
-enum
-{
- // GP Registers
- dwarf_rax_x86_64 = 0,
- dwarf_rdx_x86_64,
- dwarf_rcx_x86_64,
- dwarf_rbx_x86_64,
- dwarf_rsi_x86_64,
- dwarf_rdi_x86_64,
- dwarf_rbp_x86_64,
- dwarf_rsp_x86_64,
- // Extended GP Registers
- dwarf_r8_x86_64 = 8,
- dwarf_r9_x86_64,
- dwarf_r10_x86_64,
- dwarf_r11_x86_64,
- dwarf_r12_x86_64,
- dwarf_r13_x86_64,
- dwarf_r14_x86_64,
- dwarf_r15_x86_64,
- // Return Address (RA) mapped to RIP
- dwarf_rip_x86_64 = 16,
- // SSE Vector Registers
- dwarf_xmm0_x86_64 = 17,
- dwarf_xmm1_x86_64,
- dwarf_xmm2_x86_64,
- dwarf_xmm3_x86_64,
- dwarf_xmm4_x86_64,
- dwarf_xmm5_x86_64,
- dwarf_xmm6_x86_64,
- dwarf_xmm7_x86_64,
- dwarf_xmm8_x86_64,
- dwarf_xmm9_x86_64,
- dwarf_xmm10_x86_64,
- dwarf_xmm11_x86_64,
- dwarf_xmm12_x86_64,
- dwarf_xmm13_x86_64,
- dwarf_xmm14_x86_64,
- dwarf_xmm15_x86_64,
- // Floating Point Registers
- dwarf_st0_x86_64 = 33,
- dwarf_st1_x86_64,
- dwarf_st2_x86_64,
- dwarf_st3_x86_64,
- dwarf_st4_x86_64,
- dwarf_st5_x86_64,
- dwarf_st6_x86_64,
- dwarf_st7_x86_64,
- // MMX Registers
- dwarf_mm0_x86_64 = 41,
- dwarf_mm1_x86_64,
- dwarf_mm2_x86_64,
- dwarf_mm3_x86_64,
- dwarf_mm4_x86_64,
- dwarf_mm5_x86_64,
- dwarf_mm6_x86_64,
- dwarf_mm7_x86_64,
- // Control and Status Flags Register
- dwarf_rflags_x86_64 = 49,
- // selector registers
- dwarf_es_x86_64 = 50,
- dwarf_cs_x86_64,
- dwarf_ss_x86_64,
- dwarf_ds_x86_64,
- dwarf_fs_x86_64,
- dwarf_gs_x86_64,
- // Floating point control registers
- dwarf_mxcsr_x86_64 = 64, // Media Control and Status
- dwarf_fctrl_x86_64, // x87 control word
- dwarf_fstat_x86_64, // x87 status word
- // Upper Vector Registers
- dwarf_ymm0h_x86_64 = 67,
- dwarf_ymm1h_x86_64,
- dwarf_ymm2h_x86_64,
- dwarf_ymm3h_x86_64,
- dwarf_ymm4h_x86_64,
- dwarf_ymm5h_x86_64,
- dwarf_ymm6h_x86_64,
- dwarf_ymm7h_x86_64,
- dwarf_ymm8h_x86_64,
- dwarf_ymm9h_x86_64,
- dwarf_ymm10h_x86_64,
- dwarf_ymm11h_x86_64,
- dwarf_ymm12h_x86_64,
- dwarf_ymm13h_x86_64,
- dwarf_ymm14h_x86_64,
- dwarf_ymm15h_x86_64,
- // AVX2 Vector Mask Registers
- // dwarf_k0_x86_64 = 118,
- // dwarf_k1_x86_64,
- // dwarf_k2_x86_64,
- // dwarf_k3_x86_64,
- // dwarf_k4_x86_64,
- // dwarf_k5_x86_64,
- // dwarf_k6_x86_64,
- // dwarf_k7_x86_64,
+enum {
+ // GP Registers
+ dwarf_rax_x86_64 = 0,
+ dwarf_rdx_x86_64,
+ dwarf_rcx_x86_64,
+ dwarf_rbx_x86_64,
+ dwarf_rsi_x86_64,
+ dwarf_rdi_x86_64,
+ dwarf_rbp_x86_64,
+ dwarf_rsp_x86_64,
+ // Extended GP Registers
+ dwarf_r8_x86_64 = 8,
+ dwarf_r9_x86_64,
+ dwarf_r10_x86_64,
+ dwarf_r11_x86_64,
+ dwarf_r12_x86_64,
+ dwarf_r13_x86_64,
+ dwarf_r14_x86_64,
+ dwarf_r15_x86_64,
+ // Return Address (RA) mapped to RIP
+ dwarf_rip_x86_64 = 16,
+ // SSE Vector Registers
+ dwarf_xmm0_x86_64 = 17,
+ dwarf_xmm1_x86_64,
+ dwarf_xmm2_x86_64,
+ dwarf_xmm3_x86_64,
+ dwarf_xmm4_x86_64,
+ dwarf_xmm5_x86_64,
+ dwarf_xmm6_x86_64,
+ dwarf_xmm7_x86_64,
+ dwarf_xmm8_x86_64,
+ dwarf_xmm9_x86_64,
+ dwarf_xmm10_x86_64,
+ dwarf_xmm11_x86_64,
+ dwarf_xmm12_x86_64,
+ dwarf_xmm13_x86_64,
+ dwarf_xmm14_x86_64,
+ dwarf_xmm15_x86_64,
+ // Floating Point Registers
+ dwarf_st0_x86_64 = 33,
+ dwarf_st1_x86_64,
+ dwarf_st2_x86_64,
+ dwarf_st3_x86_64,
+ dwarf_st4_x86_64,
+ dwarf_st5_x86_64,
+ dwarf_st6_x86_64,
+ dwarf_st7_x86_64,
+ // MMX Registers
+ dwarf_mm0_x86_64 = 41,
+ dwarf_mm1_x86_64,
+ dwarf_mm2_x86_64,
+ dwarf_mm3_x86_64,
+ dwarf_mm4_x86_64,
+ dwarf_mm5_x86_64,
+ dwarf_mm6_x86_64,
+ dwarf_mm7_x86_64,
+ // Control and Status Flags Register
+ dwarf_rflags_x86_64 = 49,
+ // selector registers
+ dwarf_es_x86_64 = 50,
+ dwarf_cs_x86_64,
+ dwarf_ss_x86_64,
+ dwarf_ds_x86_64,
+ dwarf_fs_x86_64,
+ dwarf_gs_x86_64,
+ // Floating point control registers
+ dwarf_mxcsr_x86_64 = 64, // Media Control and Status
+ dwarf_fctrl_x86_64, // x87 control word
+ dwarf_fstat_x86_64, // x87 status word
+ // Upper Vector Registers
+ dwarf_ymm0h_x86_64 = 67,
+ dwarf_ymm1h_x86_64,
+ dwarf_ymm2h_x86_64,
+ dwarf_ymm3h_x86_64,
+ dwarf_ymm4h_x86_64,
+ dwarf_ymm5h_x86_64,
+ dwarf_ymm6h_x86_64,
+ dwarf_ymm7h_x86_64,
+ dwarf_ymm8h_x86_64,
+ dwarf_ymm9h_x86_64,
+ dwarf_ymm10h_x86_64,
+ dwarf_ymm11h_x86_64,
+ dwarf_ymm12h_x86_64,
+ dwarf_ymm13h_x86_64,
+ dwarf_ymm14h_x86_64,
+ dwarf_ymm15h_x86_64,
+ // MPX registers
+ dwarf_bnd0_x86_64 = 126,
+ dwarf_bnd1_x86_64,
+ dwarf_bnd2_x86_64,
+ dwarf_bnd3_x86_64,
+ // AVX2 Vector Mask Registers
+ // dwarf_k0_x86_64 = 118,
+ // dwarf_k1_x86_64,
+ // dwarf_k2_x86_64,
+ // dwarf_k3_x86_64,
+ // dwarf_k4_x86_64,
+ // dwarf_k5_x86_64,
+ // dwarf_k6_x86_64,
+ // dwarf_k7_x86_64,
};
//---------------------------------------------------------------------------
// Generic floating-point registers
//---------------------------------------------------------------------------
-struct MMSReg
-{
- uint8_t bytes[10];
- uint8_t pad[6];
+struct MMSReg {
+ uint8_t bytes[10];
+ uint8_t pad[6];
};
-struct XMMReg
-{
- uint8_t bytes[16]; // 128-bits for each XMM register
+struct XMMReg {
+ uint8_t bytes[16]; // 128-bits for each XMM register
};
// i387_fxsave_struct
-struct FXSAVE
-{
- uint16_t fctrl; // FPU Control Word (fcw)
- uint16_t fstat; // FPU Status Word (fsw)
- uint8_t ftag; // FPU Tag Word (ftw)
- uint8_t reserved_1; // Reserved
- uint16_t fop; // Last Instruction Opcode (fop)
- union
- {
- struct
- {
- uint64_t fip; // Instruction Pointer
- uint64_t fdp; // Data Pointer
- } x86_64;
- struct
- {
- uint32_t fioff; // FPU IP Offset (fip)
- uint32_t fiseg; // FPU IP Selector (fcs)
- uint32_t fooff; // FPU Operand Pointer Offset (foo)
- uint32_t foseg; // FPU Operand Pointer Selector (fos)
- } i386_;// Added _ in the end to avoid error with gcc defining i386 in some cases
- } ptr;
- uint32_t mxcsr; // MXCSR Register State
- uint32_t mxcsrmask; // MXCSR Mask
- MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
- XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes
- uint32_t padding[24];
+struct FXSAVE {
+ uint16_t fctrl; // FPU Control Word (fcw)
+ uint16_t fstat; // FPU Status Word (fsw)
+ uint8_t ftag; // FPU Tag Word (ftw)
+ uint8_t reserved_1; // Reserved
+ uint16_t fop; // Last Instruction Opcode (fop)
+ union {
+ struct {
+ uint64_t fip; // Instruction Pointer
+ uint64_t fdp; // Data Pointer
+ } x86_64;
+ struct {
+ uint32_t fioff; // FPU IP Offset (fip)
+ uint32_t fiseg; // FPU IP Selector (fcs)
+ uint32_t fooff; // FPU Operand Pointer Offset (foo)
+ uint32_t foseg; // FPU Operand Pointer Selector (fos)
+ } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
+ // cases
+ } ptr;
+ uint32_t mxcsr; // MXCSR Register State
+ uint32_t mxcsrmask; // MXCSR Mask
+ MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
+ XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes
+ uint8_t padding1[48];
+ uint64_t xcr0;
+ uint8_t padding2[40];
};
//---------------------------------------------------------------------------
// Extended floating-point registers
//---------------------------------------------------------------------------
-struct YMMHReg
-{
- uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
+struct YMMHReg {
+ uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
+};
+
+struct YMMReg {
+ uint8_t bytes[32]; // 16 * 16 bits for each YMM register
+};
+
+struct YMM {
+ YMMReg ymm[16]; // assembled from ymmh and xmm registers
};
-struct YMMReg
-{
- uint8_t bytes[32]; // 16 * 16 bits for each YMM register
+struct MPXReg {
+ uint8_t bytes[16]; // MPX 128 bit bound registers
};
-struct YMM
-{
- YMMReg ymm[16]; // assembled from ymmh and xmm registers
+struct MPXCsr {
+ uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively
+ // BNDCSR state)
};
-struct XSAVE_HDR
-{
- uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states supported by the processor
- uint64_t reserved1[2];
- uint64_t reserved2[5];
-} __attribute__((packed));
+struct MPX {
+ MPXReg mpxr[4];
+ MPXCsr mpxc[2];
+};
-// x86 extensions to FXSAVE (i.e. for AVX processors)
-struct 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
- YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes are in FXSAVE.xmm for compatibility with SSE)
- // Slot any extensions to the register file here
-} __attribute__((packed, aligned (64)));
+LLVM_PACKED_START
+struct XSAVE_HDR {
+ uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states
+ // supported by the processor
+ uint64_t xcomp_bv; // Mask to indicate the format of the XSAVE area and of
+ // the XRSTOR instruction
+ uint64_t reserved1[1];
+ uint64_t reserved2[5];
+};
+LLVM_PACKED_END
+
+// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
+LLVM_PACKED_START
+struct LLVM_ALIGNAS(64) 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
+ YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes
+ // are in FXSAVE.xmm for compatibility with SSE)
+ uint64_t reserved3[16];
+ MPXReg mpxr[4]; // MPX BNDREG state, containing 128-bit bound registers
+ MPXCsr mpxc[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and
+ // BNDSTATUS registers
+};
+LLVM_PACKED_END
// Floating-point registers
-struct FPR
-{
- // Thread state for the floating-point unit of the processor read by ptrace.
- union XSTATE
- {
- FXSAVE fxsave; // Generic floating-point registers.
- XSAVE xsave; // x86 extended processor state.
- } xstate;
+struct FPR {
+ // Thread state for the floating-point unit of the processor read by ptrace.
+ union XSTATE {
+ FXSAVE fxsave; // Generic floating-point registers.
+ XSAVE xsave; // x86 extended processor state.
+ } xstate;
};
//---------------------------------------------------------------------------
// ptrace PTRACE_GETREGSET, PTRACE_SETREGSET structure
//---------------------------------------------------------------------------
-struct IOVEC
-{
- void *iov_base; // pointer to XSAVE
- size_t iov_len; // sizeof(XSAVE)
+struct IOVEC {
+ void *iov_base; // pointer to XSAVE
+ size_t iov_len; // sizeof(XSAVE)
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoInterface.h b/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 801885d5f4c5..12db366d7a57 100644
--- a/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -14,69 +14,60 @@
#include "lldb/Core/ArchSpec.h"
-namespace lldb_private
-{
+namespace lldb_private {
- ///------------------------------------------------------------------------------
- /// @class RegisterInfoInterface
- ///
- /// @brief RegisterInfo interface to patch RegisterInfo structure for archs.
- ///------------------------------------------------------------------------------
- class RegisterInfoInterface
- {
- public:
- RegisterInfoInterface(const lldb_private::ArchSpec& target_arch) : m_target_arch(target_arch) {}
- virtual ~RegisterInfoInterface () {}
+///------------------------------------------------------------------------------
+/// @class RegisterInfoInterface
+///
+/// @brief RegisterInfo interface to patch RegisterInfo structure for archs.
+///------------------------------------------------------------------------------
+class RegisterInfoInterface {
+public:
+ RegisterInfoInterface(const lldb_private::ArchSpec &target_arch)
+ : m_target_arch(target_arch) {}
+ virtual ~RegisterInfoInterface() {}
- virtual size_t
- GetGPRSize () const = 0;
+ virtual size_t GetGPRSize() const = 0;
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo () const = 0;
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo() const = 0;
- // Returns the number of registers including the user registers and the
- // lldb internal registers also
- virtual uint32_t
- GetRegisterCount () const = 0;
+ // Returns the number of registers including the user registers and the
+ // lldb internal registers also
+ virtual uint32_t GetRegisterCount() const = 0;
- // Returns the number of the user registers (excluding the registers
- // kept for lldb internal use only). Subclasses should override it if
- // they belongs to an architecture with lldb internal registers.
- virtual uint32_t
- GetUserRegisterCount () const
- {
- return GetRegisterCount();
- }
+ // Returns the number of the user registers (excluding the registers
+ // kept for lldb internal use only). Subclasses should override it if
+ // they belongs to an architecture with lldb internal registers.
+ virtual uint32_t GetUserRegisterCount() const { return GetRegisterCount(); }
- const lldb_private::ArchSpec&
- GetTargetArchitecture() const
- { return m_target_arch; }
+ const lldb_private::ArchSpec &GetTargetArchitecture() const {
+ return m_target_arch;
+ }
- virtual const lldb_private::RegisterInfo *
- GetDynamicRegisterInfo(const char *reg_name) const
- {
- const std::vector <lldb_private::RegisterInfo> * d_register_infos = GetDynamicRegisterInfoP();
- if(d_register_infos != nullptr)
- {
- std::vector <lldb_private::RegisterInfo> ::const_iterator pos = d_register_infos->begin();
- for(; pos < d_register_infos->end() ; pos++)
- {
- if(::strcmp(reg_name, pos->name) == 0)
- return(d_register_infos->data() + (pos - d_register_infos->begin()) );
- }
- }
- return nullptr;
- }
+ virtual const lldb_private::RegisterInfo *
+ GetDynamicRegisterInfo(const char *reg_name) const {
+ const std::vector<lldb_private::RegisterInfo> *d_register_infos =
+ GetDynamicRegisterInfoP();
+ if (d_register_infos != nullptr) {
+ std::vector<lldb_private::RegisterInfo>::const_iterator pos =
+ d_register_infos->begin();
+ for (; pos < d_register_infos->end(); pos++) {
+ if (::strcmp(reg_name, pos->name) == 0)
+ return (d_register_infos->data() + (pos - d_register_infos->begin()));
+ }
+ }
+ return nullptr;
+ }
- virtual const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const
- { return nullptr; }
-
- public:
- // FIXME make private.
- lldb_private::ArchSpec m_target_arch;
- };
+ virtual const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const {
+ return nullptr;
+ }
+public:
+ // FIXME make private.
+ lldb_private::ArchSpec m_target_arch;
+};
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
new file mode 100644
index 000000000000..1b145e0a173b
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -0,0 +1,99 @@
+//===-- RegisterInfoPOSIX_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 <cassert>
+#include <stddef.h>
+#include <vector>
+
+#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterInfoPOSIX_arm64.h"
+
+// Based on RegisterContextDarwin_arm64.cpp
+#define GPR_OFFSET(idx) ((idx)*8)
+#define GPR_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::GPR, reg))
+
+#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterInfoPOSIX_arm64::GPR))
+#define FPU_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::FPU, reg) + \
+ sizeof(RegisterInfoPOSIX_arm64::GPR))
+
+#define EXC_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::EXC, reg) + \
+ sizeof(RegisterInfoPOSIX_arm64::GPR) + \
+ sizeof(RegisterInfoPOSIX_arm64::FPU))
+#define DBG_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::DBG, reg) + \
+ sizeof(RegisterInfoPOSIX_arm64::GPR) + \
+ sizeof(RegisterInfoPOSIX_arm64::FPU) + \
+ sizeof(RegisterInfoPOSIX_arm64::EXC))
+
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, \
+ sizeof(((RegisterInfoPOSIX_arm64::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ dbg_##reg##i }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterInfoPOSIX_arm64::GPR) + \
+ sizeof(RegisterInfoPOSIX_arm64::FPU) + \
+ sizeof(RegisterInfoPOSIX_arm64::EXC))
+
+//-----------------------------------------------------------------------------
+// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
+//-----------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
+#include "RegisterInfos_arm64.h"
+#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+static const lldb_private::RegisterInfo *
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ return g_register_infos_arm64_le;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+}
+
+static uint32_t
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
+ sizeof(g_register_infos_arm64_le[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
+
+size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
+ return sizeof(struct RegisterInfoPOSIX_arm64::GPR);
+}
+
+const lldb_private::RegisterInfo *
+RegisterInfoPOSIX_arm64::GetRegisterInfo() const {
+ return m_register_info_p;
+}
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
+ return m_register_info_count;
+}
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
new file mode 100644
index 000000000000..af770760cbf4
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -0,0 +1,70 @@
+//===-- RegisterInfoPOSIX_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_RegisterContextLinux_arm64_H_
+#define liblldb_RegisterContextLinux_arm64_H_
+
+#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
+
+class RegisterInfoPOSIX_arm64 : public lldb_private::RegisterInfoInterface {
+public:
+ // based on RegisterContextDarwin_arm64.h
+ struct GPR {
+ uint64_t x[29]; // x0-x28
+ uint64_t fp; // x29
+ uint64_t lr; // x30
+ uint64_t sp; // x31
+ uint64_t pc; // pc
+ uint32_t cpsr; // cpsr
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct VReg {
+ uint8_t bytes[16];
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct EXC {
+ uint64_t far; // Virtual Fault Address
+ uint32_t esr; // Exception syndrome
+ uint32_t exception; // number of arm exception token
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct DBG {
+ uint64_t bvr[16];
+ uint64_t bcr[16];
+ uint64_t wvr[16];
+ uint64_t wcr[16];
+ uint64_t mdscr_el1;
+ };
+
+ RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm.h b/source/Plugins/Process/Utility/RegisterInfos_arm.h
index e3c7473bf712..74d3226c8a52 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm.h
@@ -15,12 +15,12 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
-#include "Utility/ARM_ehframe_Registers.h"
#include "Utility/ARM_DWARF_Registers.h"
+#include "Utility/ARM_ehframe_Registers.h"
using namespace lldb;
using namespace lldb_private;
@@ -45,461 +45,1580 @@ using namespace lldb_private;
#error DEFINE_DBG must be defined before including this header file
#endif
-enum
-{
- gpr_r0 = 0,
- gpr_r1,
- gpr_r2,
- gpr_r3,
- gpr_r4,
- gpr_r5,
- gpr_r6,
- gpr_r7,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13, gpr_sp = gpr_r13,
- gpr_r14, gpr_lr = gpr_r14,
- gpr_r15, gpr_pc = gpr_r15,
- gpr_cpsr,
-
- fpu_s0,
- fpu_s1,
- fpu_s2,
- fpu_s3,
- fpu_s4,
- fpu_s5,
- fpu_s6,
- fpu_s7,
- fpu_s8,
- fpu_s9,
- fpu_s10,
- fpu_s11,
- fpu_s12,
- fpu_s13,
- fpu_s14,
- fpu_s15,
- fpu_s16,
- fpu_s17,
- fpu_s18,
- fpu_s19,
- fpu_s20,
- fpu_s21,
- fpu_s22,
- fpu_s23,
- fpu_s24,
- fpu_s25,
- fpu_s26,
- fpu_s27,
- fpu_s28,
- fpu_s29,
- fpu_s30,
- fpu_s31,
- fpu_fpscr,
-
- fpu_d0,
- fpu_d1,
- fpu_d2,
- fpu_d3,
- fpu_d4,
- fpu_d5,
- fpu_d6,
- fpu_d7,
- fpu_d8,
- fpu_d9,
- fpu_d10,
- fpu_d11,
- fpu_d12,
- fpu_d13,
- fpu_d14,
- fpu_d15,
- fpu_d16,
- fpu_d17,
- fpu_d18,
- fpu_d19,
- fpu_d20,
- fpu_d21,
- fpu_d22,
- fpu_d23,
- fpu_d24,
- fpu_d25,
- fpu_d26,
- fpu_d27,
- fpu_d28,
- fpu_d29,
- fpu_d30,
- fpu_d31,
-
- fpu_q0,
- fpu_q1,
- fpu_q2,
- fpu_q3,
- fpu_q4,
- fpu_q5,
- fpu_q6,
- fpu_q7,
- fpu_q8,
- fpu_q9,
- fpu_q10,
- fpu_q11,
- fpu_q12,
- fpu_q13,
- fpu_q14,
- fpu_q15,
-
- exc_exception,
- exc_fsr,
- exc_far,
-
- dbg_bvr0,
- dbg_bvr1,
- dbg_bvr2,
- dbg_bvr3,
- dbg_bvr4,
- dbg_bvr5,
- dbg_bvr6,
- dbg_bvr7,
- dbg_bvr8,
- dbg_bvr9,
- dbg_bvr10,
- dbg_bvr11,
- dbg_bvr12,
- dbg_bvr13,
- dbg_bvr14,
- dbg_bvr15,
-
- dbg_bcr0,
- dbg_bcr1,
- dbg_bcr2,
- dbg_bcr3,
- dbg_bcr4,
- dbg_bcr5,
- dbg_bcr6,
- dbg_bcr7,
- dbg_bcr8,
- dbg_bcr9,
- dbg_bcr10,
- dbg_bcr11,
- dbg_bcr12,
- dbg_bcr13,
- dbg_bcr14,
- dbg_bcr15,
-
- dbg_wvr0,
- dbg_wvr1,
- dbg_wvr2,
- dbg_wvr3,
- dbg_wvr4,
- dbg_wvr5,
- dbg_wvr6,
- dbg_wvr7,
- dbg_wvr8,
- dbg_wvr9,
- dbg_wvr10,
- dbg_wvr11,
- dbg_wvr12,
- dbg_wvr13,
- dbg_wvr14,
- dbg_wvr15,
-
- dbg_wcr0,
- dbg_wcr1,
- dbg_wcr2,
- dbg_wcr3,
- dbg_wcr4,
- dbg_wcr5,
- dbg_wcr6,
- dbg_wcr7,
- dbg_wcr8,
- dbg_wcr9,
- dbg_wcr10,
- dbg_wcr11,
- dbg_wcr12,
- dbg_wcr13,
- dbg_wcr14,
- dbg_wcr15,
-
- k_num_registers
+enum {
+ gpr_r0 = 0,
+ gpr_r1,
+ gpr_r2,
+ gpr_r3,
+ gpr_r4,
+ gpr_r5,
+ gpr_r6,
+ gpr_r7,
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_r13,
+ gpr_sp = gpr_r13,
+ gpr_r14,
+ gpr_lr = gpr_r14,
+ gpr_r15,
+ gpr_pc = gpr_r15,
+ gpr_cpsr,
+
+ fpu_s0,
+ fpu_s1,
+ fpu_s2,
+ fpu_s3,
+ fpu_s4,
+ fpu_s5,
+ fpu_s6,
+ fpu_s7,
+ fpu_s8,
+ fpu_s9,
+ fpu_s10,
+ fpu_s11,
+ fpu_s12,
+ fpu_s13,
+ fpu_s14,
+ fpu_s15,
+ fpu_s16,
+ fpu_s17,
+ fpu_s18,
+ fpu_s19,
+ fpu_s20,
+ fpu_s21,
+ fpu_s22,
+ fpu_s23,
+ fpu_s24,
+ fpu_s25,
+ fpu_s26,
+ fpu_s27,
+ fpu_s28,
+ fpu_s29,
+ fpu_s30,
+ fpu_s31,
+ fpu_fpscr,
+
+ fpu_d0,
+ fpu_d1,
+ fpu_d2,
+ fpu_d3,
+ fpu_d4,
+ fpu_d5,
+ fpu_d6,
+ fpu_d7,
+ fpu_d8,
+ fpu_d9,
+ fpu_d10,
+ fpu_d11,
+ fpu_d12,
+ fpu_d13,
+ fpu_d14,
+ fpu_d15,
+ fpu_d16,
+ fpu_d17,
+ fpu_d18,
+ fpu_d19,
+ fpu_d20,
+ fpu_d21,
+ fpu_d22,
+ fpu_d23,
+ fpu_d24,
+ fpu_d25,
+ fpu_d26,
+ fpu_d27,
+ fpu_d28,
+ fpu_d29,
+ fpu_d30,
+ fpu_d31,
+
+ fpu_q0,
+ fpu_q1,
+ fpu_q2,
+ fpu_q3,
+ fpu_q4,
+ fpu_q5,
+ fpu_q6,
+ fpu_q7,
+ fpu_q8,
+ fpu_q9,
+ fpu_q10,
+ fpu_q11,
+ fpu_q12,
+ fpu_q13,
+ fpu_q14,
+ fpu_q15,
+
+ exc_exception,
+ exc_fsr,
+ exc_far,
+
+ dbg_bvr0,
+ dbg_bvr1,
+ dbg_bvr2,
+ dbg_bvr3,
+ dbg_bvr4,
+ dbg_bvr5,
+ dbg_bvr6,
+ dbg_bvr7,
+ dbg_bvr8,
+ dbg_bvr9,
+ dbg_bvr10,
+ dbg_bvr11,
+ dbg_bvr12,
+ dbg_bvr13,
+ dbg_bvr14,
+ dbg_bvr15,
+
+ dbg_bcr0,
+ dbg_bcr1,
+ dbg_bcr2,
+ dbg_bcr3,
+ dbg_bcr4,
+ dbg_bcr5,
+ dbg_bcr6,
+ dbg_bcr7,
+ dbg_bcr8,
+ dbg_bcr9,
+ dbg_bcr10,
+ dbg_bcr11,
+ dbg_bcr12,
+ dbg_bcr13,
+ dbg_bcr14,
+ dbg_bcr15,
+
+ dbg_wvr0,
+ dbg_wvr1,
+ dbg_wvr2,
+ dbg_wvr3,
+ dbg_wvr4,
+ dbg_wvr5,
+ dbg_wvr6,
+ dbg_wvr7,
+ dbg_wvr8,
+ dbg_wvr9,
+ dbg_wvr10,
+ dbg_wvr11,
+ dbg_wvr12,
+ dbg_wvr13,
+ dbg_wvr14,
+ dbg_wvr15,
+
+ dbg_wcr0,
+ dbg_wcr1,
+ dbg_wcr2,
+ dbg_wcr3,
+ dbg_wcr4,
+ dbg_wcr5,
+ dbg_wcr6,
+ dbg_wcr7,
+ dbg_wcr8,
+ dbg_wcr9,
+ dbg_wcr10,
+ dbg_wcr11,
+ dbg_wcr12,
+ dbg_wcr13,
+ dbg_wcr14,
+ dbg_wcr15,
+
+ k_num_registers
};
-static uint32_t g_s0_invalidates[] = { fpu_d0, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s1_invalidates[] = { fpu_d0, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s2_invalidates[] = { fpu_d1, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s3_invalidates[] = { fpu_d1, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s4_invalidates[] = { fpu_d2, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s5_invalidates[] = { fpu_d2, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s6_invalidates[] = { fpu_d3, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s7_invalidates[] = { fpu_d3, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s8_invalidates[] = { fpu_d4, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s9_invalidates[] = { fpu_d4, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s10_invalidates[] = { fpu_d5, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s11_invalidates[] = { fpu_d5, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s12_invalidates[] = { fpu_d6, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s13_invalidates[] = { fpu_d6, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s14_invalidates[] = { fpu_d7, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s15_invalidates[] = { fpu_d7, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s16_invalidates[] = { fpu_d8, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s17_invalidates[] = { fpu_d8, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s18_invalidates[] = { fpu_d9, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s19_invalidates[] = { fpu_d9, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s20_invalidates[] = { fpu_d10, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s21_invalidates[] = { fpu_d10, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s22_invalidates[] = { fpu_d11, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s23_invalidates[] = { fpu_d11, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s24_invalidates[] = { fpu_d12, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s25_invalidates[] = { fpu_d12, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s26_invalidates[] = { fpu_d13, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s27_invalidates[] = { fpu_d13, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s28_invalidates[] = { fpu_d14, fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_s29_invalidates[] = { fpu_d14, fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_s30_invalidates[] = { fpu_d15, fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_s31_invalidates[] = { fpu_d15, fpu_q7, LLDB_INVALID_REGNUM };
-
-static uint32_t g_d0_contains[] = { fpu_s0, fpu_s1, LLDB_INVALID_REGNUM };
-static uint32_t g_d1_contains[] = { fpu_s2, fpu_s3, LLDB_INVALID_REGNUM };
-static uint32_t g_d2_contains[] = { fpu_s4, fpu_s5, LLDB_INVALID_REGNUM };
-static uint32_t g_d3_contains[] = { fpu_s6, fpu_s7, LLDB_INVALID_REGNUM };
-static uint32_t g_d4_contains[] = { fpu_s8, fpu_s9, LLDB_INVALID_REGNUM };
-static uint32_t g_d5_contains[] = { fpu_s10, fpu_s11, LLDB_INVALID_REGNUM };
-static uint32_t g_d6_contains[] = { fpu_s12, fpu_s13, LLDB_INVALID_REGNUM };
-static uint32_t g_d7_contains[] = { fpu_s14, fpu_s15, LLDB_INVALID_REGNUM };
-static uint32_t g_d8_contains[] = { fpu_s16, fpu_s17, LLDB_INVALID_REGNUM };
-static uint32_t g_d9_contains[] = { fpu_s18, fpu_s19, LLDB_INVALID_REGNUM };
-static uint32_t g_d10_contains[] = { fpu_s20, fpu_s21, LLDB_INVALID_REGNUM };
-static uint32_t g_d11_contains[] = { fpu_s22, fpu_s23, LLDB_INVALID_REGNUM };
-static uint32_t g_d12_contains[] = { fpu_s24, fpu_s25, LLDB_INVALID_REGNUM };
-static uint32_t g_d13_contains[] = { fpu_s26, fpu_s27, LLDB_INVALID_REGNUM };
-static uint32_t g_d14_contains[] = { fpu_s28, fpu_s29, LLDB_INVALID_REGNUM };
-static uint32_t g_d15_contains[] = { fpu_s30, fpu_s31, LLDB_INVALID_REGNUM };
-
-static uint32_t g_d0_invalidates[] = { fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_d1_invalidates[] = { fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_d2_invalidates[] = { fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_d3_invalidates[] = { fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_d4_invalidates[] = { fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_d5_invalidates[] = { fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_d6_invalidates[] = { fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_d7_invalidates[] = { fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_d8_invalidates[] = { fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_d9_invalidates[] = { fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_d10_invalidates[] = { fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_d11_invalidates[] = { fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_d12_invalidates[] = { fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_d13_invalidates[] = { fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_d14_invalidates[] = { fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_d15_invalidates[] = { fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_d16_invalidates[] = { fpu_q8, LLDB_INVALID_REGNUM };
-static uint32_t g_d17_invalidates[] = { fpu_q8, LLDB_INVALID_REGNUM };
-static uint32_t g_d18_invalidates[] = { fpu_q9, LLDB_INVALID_REGNUM };
-static uint32_t g_d19_invalidates[] = { fpu_q9, LLDB_INVALID_REGNUM };
-static uint32_t g_d20_invalidates[] = { fpu_q10, LLDB_INVALID_REGNUM };
-static uint32_t g_d21_invalidates[] = { fpu_q10, LLDB_INVALID_REGNUM };
-static uint32_t g_d22_invalidates[] = { fpu_q11, LLDB_INVALID_REGNUM };
-static uint32_t g_d23_invalidates[] = { fpu_q11, LLDB_INVALID_REGNUM };
-static uint32_t g_d24_invalidates[] = { fpu_q12, LLDB_INVALID_REGNUM };
-static uint32_t g_d25_invalidates[] = { fpu_q12, LLDB_INVALID_REGNUM };
-static uint32_t g_d26_invalidates[] = { fpu_q13, LLDB_INVALID_REGNUM };
-static uint32_t g_d27_invalidates[] = { fpu_q13, LLDB_INVALID_REGNUM };
-static uint32_t g_d28_invalidates[] = { fpu_q14, LLDB_INVALID_REGNUM };
-static uint32_t g_d29_invalidates[] = { fpu_q14, LLDB_INVALID_REGNUM };
-static uint32_t g_d30_invalidates[] = { fpu_q15, LLDB_INVALID_REGNUM };
-static uint32_t g_d31_invalidates[] = { fpu_q15, LLDB_INVALID_REGNUM };
-
-static uint32_t g_q0_contains[] = { fpu_d0, fpu_d1, fpu_s0, fpu_s1, fpu_s2, fpu_s3, LLDB_INVALID_REGNUM };
-static uint32_t g_q1_contains[] = { fpu_d2, fpu_d3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, LLDB_INVALID_REGNUM };
-static uint32_t g_q2_contains[] = { fpu_d4, fpu_d5, fpu_s8, fpu_s9, fpu_s10, fpu_s11, LLDB_INVALID_REGNUM };
-static uint32_t g_q3_contains[] = { fpu_d6, fpu_d7, fpu_s12, fpu_s13, fpu_s14, fpu_s15, LLDB_INVALID_REGNUM };
-static uint32_t g_q4_contains[] = { fpu_d8, fpu_d9, fpu_s16, fpu_s17, fpu_s18, fpu_s19, LLDB_INVALID_REGNUM };
-static uint32_t g_q5_contains[] = { fpu_d10, fpu_d11, fpu_s20, fpu_s21, fpu_s22, fpu_s23, LLDB_INVALID_REGNUM };
-static uint32_t g_q6_contains[] = { fpu_d12, fpu_d13, fpu_s24, fpu_s25, fpu_s26, fpu_s27, LLDB_INVALID_REGNUM };
-static uint32_t g_q7_contains[] = { fpu_d14, fpu_d15, fpu_s28, fpu_s29, fpu_s30, fpu_s31, LLDB_INVALID_REGNUM };
-static uint32_t g_q8_contains[] = { fpu_d16, fpu_d17, LLDB_INVALID_REGNUM };
-static uint32_t g_q9_contains[] = { fpu_d18, fpu_d19, LLDB_INVALID_REGNUM };
-static uint32_t g_q10_contains[] = { fpu_d20, fpu_d21, LLDB_INVALID_REGNUM };
-static uint32_t g_q11_contains[] = { fpu_d22, fpu_d23, LLDB_INVALID_REGNUM };
-static uint32_t g_q12_contains[] = { fpu_d24, fpu_d25, LLDB_INVALID_REGNUM };
-static uint32_t g_q13_contains[] = { fpu_d26, fpu_d27, LLDB_INVALID_REGNUM };
-static uint32_t g_q14_contains[] = { fpu_d28, fpu_d29, LLDB_INVALID_REGNUM };
-static uint32_t g_q15_contains[] = { fpu_d30, fpu_d31, LLDB_INVALID_REGNUM };
+static uint32_t g_s0_invalidates[] = {fpu_d0, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s1_invalidates[] = {fpu_d0, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s2_invalidates[] = {fpu_d1, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s3_invalidates[] = {fpu_d1, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s4_invalidates[] = {fpu_d2, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s5_invalidates[] = {fpu_d2, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s6_invalidates[] = {fpu_d3, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s7_invalidates[] = {fpu_d3, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s8_invalidates[] = {fpu_d4, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s9_invalidates[] = {fpu_d4, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s10_invalidates[] = {fpu_d5, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s11_invalidates[] = {fpu_d5, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s12_invalidates[] = {fpu_d6, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s13_invalidates[] = {fpu_d6, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s14_invalidates[] = {fpu_d7, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s15_invalidates[] = {fpu_d7, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s16_invalidates[] = {fpu_d8, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s17_invalidates[] = {fpu_d8, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s18_invalidates[] = {fpu_d9, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s19_invalidates[] = {fpu_d9, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s20_invalidates[] = {fpu_d10, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s21_invalidates[] = {fpu_d10, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s22_invalidates[] = {fpu_d11, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s23_invalidates[] = {fpu_d11, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s24_invalidates[] = {fpu_d12, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s25_invalidates[] = {fpu_d12, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s26_invalidates[] = {fpu_d13, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s27_invalidates[] = {fpu_d13, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s28_invalidates[] = {fpu_d14, fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_s29_invalidates[] = {fpu_d14, fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_s30_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_s31_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM};
+
+static uint32_t g_d0_contains[] = {fpu_s0, fpu_s1, LLDB_INVALID_REGNUM};
+static uint32_t g_d1_contains[] = {fpu_s2, fpu_s3, LLDB_INVALID_REGNUM};
+static uint32_t g_d2_contains[] = {fpu_s4, fpu_s5, LLDB_INVALID_REGNUM};
+static uint32_t g_d3_contains[] = {fpu_s6, fpu_s7, LLDB_INVALID_REGNUM};
+static uint32_t g_d4_contains[] = {fpu_s8, fpu_s9, LLDB_INVALID_REGNUM};
+static uint32_t g_d5_contains[] = {fpu_s10, fpu_s11, LLDB_INVALID_REGNUM};
+static uint32_t g_d6_contains[] = {fpu_s12, fpu_s13, LLDB_INVALID_REGNUM};
+static uint32_t g_d7_contains[] = {fpu_s14, fpu_s15, LLDB_INVALID_REGNUM};
+static uint32_t g_d8_contains[] = {fpu_s16, fpu_s17, LLDB_INVALID_REGNUM};
+static uint32_t g_d9_contains[] = {fpu_s18, fpu_s19, LLDB_INVALID_REGNUM};
+static uint32_t g_d10_contains[] = {fpu_s20, fpu_s21, LLDB_INVALID_REGNUM};
+static uint32_t g_d11_contains[] = {fpu_s22, fpu_s23, LLDB_INVALID_REGNUM};
+static uint32_t g_d12_contains[] = {fpu_s24, fpu_s25, LLDB_INVALID_REGNUM};
+static uint32_t g_d13_contains[] = {fpu_s26, fpu_s27, LLDB_INVALID_REGNUM};
+static uint32_t g_d14_contains[] = {fpu_s28, fpu_s29, LLDB_INVALID_REGNUM};
+static uint32_t g_d15_contains[] = {fpu_s30, fpu_s31, LLDB_INVALID_REGNUM};
+
+static uint32_t g_d0_invalidates[] = {fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_d1_invalidates[] = {fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_d2_invalidates[] = {fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_d3_invalidates[] = {fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_d4_invalidates[] = {fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_d5_invalidates[] = {fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_d6_invalidates[] = {fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_d7_invalidates[] = {fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_d8_invalidates[] = {fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_d9_invalidates[] = {fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_d10_invalidates[] = {fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_d11_invalidates[] = {fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_d12_invalidates[] = {fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_d13_invalidates[] = {fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_d14_invalidates[] = {fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_d15_invalidates[] = {fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_d16_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM};
+static uint32_t g_d17_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM};
+static uint32_t g_d18_invalidates[] = {fpu_q9, LLDB_INVALID_REGNUM};
+static uint32_t g_d19_invalidates[] = {fpu_q9, LLDB_INVALID_REGNUM};
+static uint32_t g_d20_invalidates[] = {fpu_q10, LLDB_INVALID_REGNUM};
+static uint32_t g_d21_invalidates[] = {fpu_q10, LLDB_INVALID_REGNUM};
+static uint32_t g_d22_invalidates[] = {fpu_q11, LLDB_INVALID_REGNUM};
+static uint32_t g_d23_invalidates[] = {fpu_q11, LLDB_INVALID_REGNUM};
+static uint32_t g_d24_invalidates[] = {fpu_q12, LLDB_INVALID_REGNUM};
+static uint32_t g_d25_invalidates[] = {fpu_q12, LLDB_INVALID_REGNUM};
+static uint32_t g_d26_invalidates[] = {fpu_q13, LLDB_INVALID_REGNUM};
+static uint32_t g_d27_invalidates[] = {fpu_q13, LLDB_INVALID_REGNUM};
+static uint32_t g_d28_invalidates[] = {fpu_q14, LLDB_INVALID_REGNUM};
+static uint32_t g_d29_invalidates[] = {fpu_q14, LLDB_INVALID_REGNUM};
+static uint32_t g_d30_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM};
+static uint32_t g_d31_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM};
+
+static uint32_t g_q0_contains[] = {
+ fpu_d0, fpu_d1, fpu_s0, fpu_s1, fpu_s2, fpu_s3, LLDB_INVALID_REGNUM};
+static uint32_t g_q1_contains[] = {
+ fpu_d2, fpu_d3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, LLDB_INVALID_REGNUM};
+static uint32_t g_q2_contains[] = {
+ fpu_d4, fpu_d5, fpu_s8, fpu_s9, fpu_s10, fpu_s11, LLDB_INVALID_REGNUM};
+static uint32_t g_q3_contains[] = {
+ fpu_d6, fpu_d7, fpu_s12, fpu_s13, fpu_s14, fpu_s15, LLDB_INVALID_REGNUM};
+static uint32_t g_q4_contains[] = {
+ fpu_d8, fpu_d9, fpu_s16, fpu_s17, fpu_s18, fpu_s19, LLDB_INVALID_REGNUM};
+static uint32_t g_q5_contains[] = {
+ fpu_d10, fpu_d11, fpu_s20, fpu_s21, fpu_s22, fpu_s23, LLDB_INVALID_REGNUM};
+static uint32_t g_q6_contains[] = {
+ fpu_d12, fpu_d13, fpu_s24, fpu_s25, fpu_s26, fpu_s27, LLDB_INVALID_REGNUM};
+static uint32_t g_q7_contains[] = {
+ fpu_d14, fpu_d15, fpu_s28, fpu_s29, fpu_s30, fpu_s31, LLDB_INVALID_REGNUM};
+static uint32_t g_q8_contains[] = {fpu_d16, fpu_d17, LLDB_INVALID_REGNUM};
+static uint32_t g_q9_contains[] = {fpu_d18, fpu_d19, LLDB_INVALID_REGNUM};
+static uint32_t g_q10_contains[] = {fpu_d20, fpu_d21, LLDB_INVALID_REGNUM};
+static uint32_t g_q11_contains[] = {fpu_d22, fpu_d23, LLDB_INVALID_REGNUM};
+static uint32_t g_q12_contains[] = {fpu_d24, fpu_d25, LLDB_INVALID_REGNUM};
+static uint32_t g_q13_contains[] = {fpu_d26, fpu_d27, LLDB_INVALID_REGNUM};
+static uint32_t g_q14_contains[] = {fpu_d28, fpu_d29, LLDB_INVALID_REGNUM};
+static uint32_t g_q15_contains[] = {fpu_d30, fpu_d31, LLDB_INVALID_REGNUM};
static RegisterInfo g_register_infos_arm[] = {
-// NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
-// =========== ======= == ============== ================ ==================== =================== =================== ========================== =================== ============= ============== =================
-{ "r0", nullptr, 4, GPR_OFFSET(0), eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_r0 }, nullptr, nullptr, nullptr, 0},
-{ "r1", nullptr, 4, GPR_OFFSET(1), eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_r1 }, nullptr, nullptr, nullptr, 0},
-{ "r2", nullptr, 4, GPR_OFFSET(2), eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_r2 }, nullptr, nullptr, nullptr, 0},
-{ "r3", nullptr, 4, GPR_OFFSET(3), eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_r3 }, nullptr, nullptr, nullptr, 0},
-{ "r4", nullptr, 4, GPR_OFFSET(4), eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4 }, nullptr, nullptr, nullptr, 0},
-{ "r5", nullptr, 4, GPR_OFFSET(5), eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5 }, nullptr, nullptr, nullptr, 0},
-{ "r6", nullptr, 4, GPR_OFFSET(6), eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6 }, nullptr, nullptr, nullptr, 0},
-{ "r7", nullptr, 4, GPR_OFFSET(7), eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r7 }, nullptr, nullptr, nullptr, 0},
-{ "r8", nullptr, 4, GPR_OFFSET(8), eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8 }, nullptr, nullptr, nullptr, 0},
-{ "r9", nullptr, 4, GPR_OFFSET(9), eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9 }, nullptr, nullptr, nullptr, 0},
-{ "r10", nullptr, 4, GPR_OFFSET(10), eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r10 }, nullptr, nullptr, nullptr, 0},
-{ "r11", nullptr, 4, GPR_OFFSET(11), eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_r11 }, nullptr, nullptr, nullptr, 0},
-{ "r12", nullptr, 4, GPR_OFFSET(12), eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r12 }, nullptr, nullptr, nullptr, 0},
-{ "sp", "r13", 4, GPR_OFFSET(13), eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp }, nullptr, nullptr, nullptr, 0},
-{ "lr", "r14", 4, GPR_OFFSET(14), eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr }, nullptr, nullptr, nullptr, 0},
-{ "pc", "r15", 4, GPR_OFFSET(15), eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc }, nullptr, nullptr, nullptr, 0},
-{ "cpsr", "psr", 4, GPR_OFFSET(16), eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr }, nullptr, nullptr, nullptr, 0},
-
-{ "s0", nullptr, 4, FPU_OFFSET(0), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0 }, nullptr, g_s0_invalidates, nullptr, 0},
-{ "s1", nullptr, 4, FPU_OFFSET(1), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1 }, nullptr, g_s1_invalidates, nullptr, 0},
-{ "s2", nullptr, 4, FPU_OFFSET(2), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2 }, nullptr, g_s2_invalidates, nullptr, 0},
-{ "s3", nullptr, 4, FPU_OFFSET(3), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3 }, nullptr, g_s3_invalidates, nullptr, 0},
-{ "s4", nullptr, 4, FPU_OFFSET(4), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4 }, nullptr, g_s4_invalidates, nullptr, 0},
-{ "s5", nullptr, 4, FPU_OFFSET(5), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5 }, nullptr, g_s5_invalidates, nullptr, 0},
-{ "s6", nullptr, 4, FPU_OFFSET(6), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6 }, nullptr, g_s6_invalidates, nullptr, 0},
-{ "s7", nullptr, 4, FPU_OFFSET(7), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7 }, nullptr, g_s7_invalidates, nullptr, 0},
-{ "s8", nullptr, 4, FPU_OFFSET(8), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8 }, nullptr, g_s8_invalidates, nullptr, 0},
-{ "s9", nullptr, 4, FPU_OFFSET(9), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9 }, nullptr, g_s9_invalidates, nullptr, 0},
-{ "s10", nullptr, 4, FPU_OFFSET(10), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10 }, nullptr, g_s10_invalidates, nullptr, 0},
-{ "s11", nullptr, 4, FPU_OFFSET(11), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11 }, nullptr, g_s11_invalidates, nullptr, 0},
-{ "s12", nullptr, 4, FPU_OFFSET(12), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12 }, nullptr, g_s12_invalidates, nullptr, 0},
-{ "s13", nullptr, 4, FPU_OFFSET(13), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13 }, nullptr, g_s13_invalidates, nullptr, 0},
-{ "s14", nullptr, 4, FPU_OFFSET(14), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14 }, nullptr, g_s14_invalidates, nullptr, 0},
-{ "s15", nullptr, 4, FPU_OFFSET(15), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15 }, nullptr, g_s15_invalidates, nullptr, 0},
-{ "s16", nullptr, 4, FPU_OFFSET(16), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16 }, nullptr, g_s16_invalidates, nullptr, 0},
-{ "s17", nullptr, 4, FPU_OFFSET(17), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17 }, nullptr, g_s17_invalidates, nullptr, 0},
-{ "s18", nullptr, 4, FPU_OFFSET(18), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18 }, nullptr, g_s18_invalidates, nullptr, 0},
-{ "s19", nullptr, 4, FPU_OFFSET(19), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19 }, nullptr, g_s19_invalidates, nullptr, 0},
-{ "s20", nullptr, 4, FPU_OFFSET(20), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20 }, nullptr, g_s20_invalidates, nullptr, 0},
-{ "s21", nullptr, 4, FPU_OFFSET(21), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21 }, nullptr, g_s21_invalidates, nullptr, 0},
-{ "s22", nullptr, 4, FPU_OFFSET(22), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22 }, nullptr, g_s22_invalidates, nullptr, 0},
-{ "s23", nullptr, 4, FPU_OFFSET(23), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23 }, nullptr, g_s23_invalidates, nullptr, 0},
-{ "s24", nullptr, 4, FPU_OFFSET(24), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24 }, nullptr, g_s24_invalidates, nullptr, 0},
-{ "s25", nullptr, 4, FPU_OFFSET(25), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25 }, nullptr, g_s25_invalidates, nullptr, 0},
-{ "s26", nullptr, 4, FPU_OFFSET(26), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26 }, nullptr, g_s26_invalidates, nullptr, 0},
-{ "s27", nullptr, 4, FPU_OFFSET(27), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27 }, nullptr, g_s27_invalidates, nullptr, 0},
-{ "s28", nullptr, 4, FPU_OFFSET(28), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28 }, nullptr, g_s28_invalidates, nullptr, 0},
-{ "s29", nullptr, 4, FPU_OFFSET(29), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29 }, nullptr, g_s29_invalidates, nullptr, 0},
-{ "s30", nullptr, 4, FPU_OFFSET(30), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30 }, nullptr, g_s30_invalidates, nullptr, 0},
-{ "s31", nullptr, 4, FPU_OFFSET(31), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31 }, nullptr, g_s31_invalidates, nullptr, 0},
-{ "fpscr", nullptr, 4, FPSCR_OFFSET, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpscr }, nullptr, nullptr, nullptr, 0},
-
-{ "d0", nullptr, 8, FPU_OFFSET(0), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d0 }, g_d0_contains, g_d0_invalidates, nullptr, 0},
-{ "d1", nullptr, 8, FPU_OFFSET(2), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d1 }, g_d1_contains, g_d1_invalidates, nullptr, 0},
-{ "d2", nullptr, 8, FPU_OFFSET(4), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d2 }, g_d2_contains, g_d2_invalidates, nullptr, 0},
-{ "d3", nullptr, 8, FPU_OFFSET(6), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d3 }, g_d3_contains, g_d3_invalidates, nullptr, 0},
-{ "d4", nullptr, 8, FPU_OFFSET(8), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d4 }, g_d4_contains, g_d4_invalidates, nullptr, 0},
-{ "d5", nullptr, 8, FPU_OFFSET(10), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d5 }, g_d5_contains, g_d5_invalidates, nullptr, 0},
-{ "d6", nullptr, 8, FPU_OFFSET(12), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d6 }, g_d6_contains, g_d6_invalidates, nullptr, 0},
-{ "d7", nullptr, 8, FPU_OFFSET(14), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d7 }, g_d7_contains, g_d7_invalidates, nullptr, 0},
-{ "d8", nullptr, 8, FPU_OFFSET(16), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d8 }, g_d8_contains, g_d8_invalidates, nullptr, 0},
-{ "d9", nullptr, 8, FPU_OFFSET(18), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d9 }, g_d9_contains, g_d9_invalidates, nullptr, 0},
-{ "d10", nullptr, 8, FPU_OFFSET(20), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d10 }, g_d10_contains, g_d10_invalidates, nullptr, 0},
-{ "d11", nullptr, 8, FPU_OFFSET(22), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d11 }, g_d11_contains, g_d11_invalidates, nullptr, 0},
-{ "d12", nullptr, 8, FPU_OFFSET(24), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d12 }, g_d12_contains, g_d12_invalidates, nullptr, 0},
-{ "d13", nullptr, 8, FPU_OFFSET(26), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d13 }, g_d13_contains, g_d13_invalidates, nullptr, 0},
-{ "d14", nullptr, 8, FPU_OFFSET(28), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d14 }, g_d14_contains, g_d14_invalidates, nullptr, 0},
-{ "d15", nullptr, 8, FPU_OFFSET(30), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d15 }, g_d15_contains, g_d15_invalidates, nullptr, 0},
-{ "d16", nullptr, 8, FPU_OFFSET(32), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d16 }, nullptr, g_d16_invalidates, nullptr, 0 },
-{ "d17", nullptr, 8, FPU_OFFSET(34), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d17 }, nullptr, g_d17_invalidates, nullptr, 0},
-{ "d18", nullptr, 8, FPU_OFFSET(36), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d18 }, nullptr, g_d18_invalidates, nullptr, 0},
-{ "d19", nullptr, 8, FPU_OFFSET(38), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d19 }, nullptr, g_d19_invalidates, nullptr, 0},
-{ "d20", nullptr, 8, FPU_OFFSET(40), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d20 }, nullptr, g_d20_invalidates, nullptr, 0},
-{ "d21", nullptr, 8, FPU_OFFSET(42), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d21 }, nullptr, g_d21_invalidates, nullptr, 0},
-{ "d22", nullptr, 8, FPU_OFFSET(44), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d22 }, nullptr, g_d22_invalidates, nullptr, 0},
-{ "d23", nullptr, 8, FPU_OFFSET(46), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d23 }, nullptr, g_d23_invalidates, nullptr, 0},
-{ "d24", nullptr, 8, FPU_OFFSET(48), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d24 }, nullptr, g_d24_invalidates, nullptr, 0},
-{ "d25", nullptr, 8, FPU_OFFSET(50), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d25 }, nullptr, g_d25_invalidates, nullptr, 0},
-{ "d26", nullptr, 8, FPU_OFFSET(52), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d26 }, nullptr, g_d26_invalidates, nullptr, 0},
-{ "d27", nullptr, 8, FPU_OFFSET(54), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d27 }, nullptr, g_d27_invalidates, nullptr, 0},
-{ "d28", nullptr, 8, FPU_OFFSET(56), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d28 }, nullptr, g_d28_invalidates, nullptr, 0},
-{ "d29", nullptr, 8, FPU_OFFSET(58), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d29 }, nullptr, g_d29_invalidates, nullptr, 0},
-{ "d30", nullptr, 8, FPU_OFFSET(60), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d30 }, nullptr, g_d30_invalidates, nullptr, 0},
-{ "d31", nullptr, 8, FPU_OFFSET(62), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d31 }, nullptr, g_d31_invalidates, nullptr, 0},
-
-{ "q0", nullptr, 16, FPU_OFFSET(0), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q0 }, g_q0_contains, nullptr, nullptr, 0},
-{ "q1", nullptr, 16, FPU_OFFSET(4), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q1 }, g_q1_contains, nullptr, nullptr, 0},
-{ "q2", nullptr, 16, FPU_OFFSET(8), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q2 }, g_q2_contains, nullptr, nullptr, 0},
-{ "q3", nullptr, 16, FPU_OFFSET(12), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q3 }, g_q3_contains, nullptr, nullptr, 0},
-{ "q4", nullptr, 16, FPU_OFFSET(16), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q4 }, g_q4_contains, nullptr, nullptr, 0},
-{ "q5", nullptr, 16, FPU_OFFSET(20), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q5 }, g_q5_contains, nullptr, nullptr, 0},
-{ "q6", nullptr, 16, FPU_OFFSET(24), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q6 }, g_q6_contains, nullptr, nullptr, 0},
-{ "q7", nullptr, 16, FPU_OFFSET(28), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q7 }, g_q7_contains, nullptr, nullptr, 0},
-{ "q8", nullptr, 16, FPU_OFFSET(32), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q8 }, g_q8_contains, nullptr, nullptr, 0},
-{ "q9", nullptr, 16, FPU_OFFSET(36), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q9 }, g_q9_contains, nullptr, nullptr, 0},
-{ "q10", nullptr, 16, FPU_OFFSET(40), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q10 }, g_q10_contains, nullptr, nullptr, 0},
-{ "q11", nullptr, 16, FPU_OFFSET(44), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q11 }, g_q11_contains, nullptr, nullptr, 0},
-{ "q12", nullptr, 16, FPU_OFFSET(48), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q12 }, g_q12_contains, nullptr, nullptr, 0},
-{ "q13", nullptr, 16, FPU_OFFSET(52), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q13 }, g_q13_contains, nullptr, nullptr, 0},
-{ "q14", nullptr, 16, FPU_OFFSET(56), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q14 }, g_q14_contains, nullptr, nullptr, 0},
-{ "q15", nullptr, 16, FPU_OFFSET(60), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q15 }, g_q15_contains, nullptr, nullptr, 0},
-
-{ "exception", nullptr, 4, EXC_OFFSET(0), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, nullptr, nullptr, nullptr, 0},
-{ "fsr", nullptr, 4, EXC_OFFSET(1), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_fsr }, nullptr, nullptr, nullptr, 0},
-{ "far", nullptr, 4, EXC_OFFSET(2), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, nullptr, nullptr, nullptr, 0},
-
-{ DEFINE_DBG (bvr, 0) },
-{ DEFINE_DBG (bvr, 1) },
-{ DEFINE_DBG (bvr, 2) },
-{ DEFINE_DBG (bvr, 3) },
-{ DEFINE_DBG (bvr, 4) },
-{ DEFINE_DBG (bvr, 5) },
-{ DEFINE_DBG (bvr, 6) },
-{ DEFINE_DBG (bvr, 7) },
-{ DEFINE_DBG (bvr, 8) },
-{ DEFINE_DBG (bvr, 9) },
-{ DEFINE_DBG (bvr, 10) },
-{ DEFINE_DBG (bvr, 11) },
-{ DEFINE_DBG (bvr, 12) },
-{ DEFINE_DBG (bvr, 13) },
-{ DEFINE_DBG (bvr, 14) },
-{ DEFINE_DBG (bvr, 15) },
-
-{ DEFINE_DBG (bcr, 0) },
-{ DEFINE_DBG (bcr, 1) },
-{ DEFINE_DBG (bcr, 2) },
-{ DEFINE_DBG (bcr, 3) },
-{ DEFINE_DBG (bcr, 4) },
-{ DEFINE_DBG (bcr, 5) },
-{ DEFINE_DBG (bcr, 6) },
-{ DEFINE_DBG (bcr, 7) },
-{ DEFINE_DBG (bcr, 8) },
-{ DEFINE_DBG (bcr, 9) },
-{ DEFINE_DBG (bcr, 10) },
-{ DEFINE_DBG (bcr, 11) },
-{ DEFINE_DBG (bcr, 12) },
-{ DEFINE_DBG (bcr, 13) },
-{ DEFINE_DBG (bcr, 14) },
-{ DEFINE_DBG (bcr, 15) },
-
-{ DEFINE_DBG (wvr, 0) },
-{ DEFINE_DBG (wvr, 1) },
-{ DEFINE_DBG (wvr, 2) },
-{ DEFINE_DBG (wvr, 3) },
-{ DEFINE_DBG (wvr, 4) },
-{ DEFINE_DBG (wvr, 5) },
-{ DEFINE_DBG (wvr, 6) },
-{ DEFINE_DBG (wvr, 7) },
-{ DEFINE_DBG (wvr, 8) },
-{ DEFINE_DBG (wvr, 9) },
-{ DEFINE_DBG (wvr, 10) },
-{ DEFINE_DBG (wvr, 11) },
-{ DEFINE_DBG (wvr, 12) },
-{ DEFINE_DBG (wvr, 13) },
-{ DEFINE_DBG (wvr, 14) },
-{ DEFINE_DBG (wvr, 15) },
-
-{ DEFINE_DBG (wcr, 0) },
-{ DEFINE_DBG (wcr, 1) },
-{ DEFINE_DBG (wcr, 2) },
-{ DEFINE_DBG (wcr, 3) },
-{ DEFINE_DBG (wcr, 4) },
-{ DEFINE_DBG (wcr, 5) },
-{ DEFINE_DBG (wcr, 6) },
-{ DEFINE_DBG (wcr, 7) },
-{ DEFINE_DBG (wcr, 8) },
-{ DEFINE_DBG (wcr, 9) },
-{ DEFINE_DBG (wcr, 10) },
-{ DEFINE_DBG (wcr, 11) },
-{ DEFINE_DBG (wcr, 12) },
-{ DEFINE_DBG (wcr, 13) },
-{ DEFINE_DBG (wcr, 14) },
-{ DEFINE_DBG (wcr, 15) }
-};
+ // NAME ALT SZ OFFSET ENCODING FORMAT
+ // EH_FRAME DWARF GENERIC
+ // PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
+ // =========== ======= == ============== ================
+ // ==================== =================== ===================
+ // ========================== =================== =============
+ // ============== =================
+ {"r0",
+ nullptr,
+ 4,
+ GPR_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ gpr_r0},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ nullptr,
+ 4,
+ GPR_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ gpr_r1},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ nullptr,
+ 4,
+ GPR_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ gpr_r2},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ nullptr,
+ 4,
+ GPR_OFFSET(3),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ gpr_r3},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ nullptr,
+ 4,
+ GPR_OFFSET(4),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ nullptr,
+ 4,
+ GPR_OFFSET(5),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ nullptr,
+ 4,
+ GPR_OFFSET(6),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ nullptr,
+ 4,
+ GPR_OFFSET(7),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ nullptr,
+ 4,
+ GPR_OFFSET(8),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ nullptr,
+ 4,
+ GPR_OFFSET(9),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ nullptr,
+ 4,
+ GPR_OFFSET(10),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ nullptr,
+ 4,
+ GPR_OFFSET(11),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ gpr_r11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 4,
+ GPR_OFFSET(12),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "r13",
+ 4,
+ GPR_OFFSET(13),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ gpr_sp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r14",
+ 4,
+ GPR_OFFSET(14),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ gpr_lr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "r15",
+ 4,
+ GPR_OFFSET(15),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ gpr_pc},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ GPR_OFFSET(16),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ gpr_cpsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"s0",
+ nullptr,
+ 4,
+ FPU_OFFSET(0),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s0},
+ nullptr,
+ g_s0_invalidates,
+ nullptr,
+ 0},
+ {"s1",
+ nullptr,
+ 4,
+ FPU_OFFSET(1),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s1},
+ nullptr,
+ g_s1_invalidates,
+ nullptr,
+ 0},
+ {"s2",
+ nullptr,
+ 4,
+ FPU_OFFSET(2),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s2},
+ nullptr,
+ g_s2_invalidates,
+ nullptr,
+ 0},
+ {"s3",
+ nullptr,
+ 4,
+ FPU_OFFSET(3),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s3},
+ nullptr,
+ g_s3_invalidates,
+ nullptr,
+ 0},
+ {"s4",
+ nullptr,
+ 4,
+ FPU_OFFSET(4),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s4},
+ nullptr,
+ g_s4_invalidates,
+ nullptr,
+ 0},
+ {"s5",
+ nullptr,
+ 4,
+ FPU_OFFSET(5),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s5},
+ nullptr,
+ g_s5_invalidates,
+ nullptr,
+ 0},
+ {"s6",
+ nullptr,
+ 4,
+ FPU_OFFSET(6),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s6},
+ nullptr,
+ g_s6_invalidates,
+ nullptr,
+ 0},
+ {"s7",
+ nullptr,
+ 4,
+ FPU_OFFSET(7),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s7},
+ nullptr,
+ g_s7_invalidates,
+ nullptr,
+ 0},
+ {"s8",
+ nullptr,
+ 4,
+ FPU_OFFSET(8),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s8},
+ nullptr,
+ g_s8_invalidates,
+ nullptr,
+ 0},
+ {"s9",
+ nullptr,
+ 4,
+ FPU_OFFSET(9),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s9},
+ nullptr,
+ g_s9_invalidates,
+ nullptr,
+ 0},
+ {"s10",
+ nullptr,
+ 4,
+ FPU_OFFSET(10),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s10},
+ nullptr,
+ g_s10_invalidates,
+ nullptr,
+ 0},
+ {"s11",
+ nullptr,
+ 4,
+ FPU_OFFSET(11),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s11},
+ nullptr,
+ g_s11_invalidates,
+ nullptr,
+ 0},
+ {"s12",
+ nullptr,
+ 4,
+ FPU_OFFSET(12),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s12},
+ nullptr,
+ g_s12_invalidates,
+ nullptr,
+ 0},
+ {"s13",
+ nullptr,
+ 4,
+ FPU_OFFSET(13),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s13},
+ nullptr,
+ g_s13_invalidates,
+ nullptr,
+ 0},
+ {"s14",
+ nullptr,
+ 4,
+ FPU_OFFSET(14),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s14},
+ nullptr,
+ g_s14_invalidates,
+ nullptr,
+ 0},
+ {"s15",
+ nullptr,
+ 4,
+ FPU_OFFSET(15),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s15},
+ nullptr,
+ g_s15_invalidates,
+ nullptr,
+ 0},
+ {"s16",
+ nullptr,
+ 4,
+ FPU_OFFSET(16),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s16},
+ nullptr,
+ g_s16_invalidates,
+ nullptr,
+ 0},
+ {"s17",
+ nullptr,
+ 4,
+ FPU_OFFSET(17),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s17},
+ nullptr,
+ g_s17_invalidates,
+ nullptr,
+ 0},
+ {"s18",
+ nullptr,
+ 4,
+ FPU_OFFSET(18),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s18},
+ nullptr,
+ g_s18_invalidates,
+ nullptr,
+ 0},
+ {"s19",
+ nullptr,
+ 4,
+ FPU_OFFSET(19),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s19},
+ nullptr,
+ g_s19_invalidates,
+ nullptr,
+ 0},
+ {"s20",
+ nullptr,
+ 4,
+ FPU_OFFSET(20),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s20},
+ nullptr,
+ g_s20_invalidates,
+ nullptr,
+ 0},
+ {"s21",
+ nullptr,
+ 4,
+ FPU_OFFSET(21),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s21},
+ nullptr,
+ g_s21_invalidates,
+ nullptr,
+ 0},
+ {"s22",
+ nullptr,
+ 4,
+ FPU_OFFSET(22),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s22},
+ nullptr,
+ g_s22_invalidates,
+ nullptr,
+ 0},
+ {"s23",
+ nullptr,
+ 4,
+ FPU_OFFSET(23),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s23},
+ nullptr,
+ g_s23_invalidates,
+ nullptr,
+ 0},
+ {"s24",
+ nullptr,
+ 4,
+ FPU_OFFSET(24),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s24},
+ nullptr,
+ g_s24_invalidates,
+ nullptr,
+ 0},
+ {"s25",
+ nullptr,
+ 4,
+ FPU_OFFSET(25),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s25},
+ nullptr,
+ g_s25_invalidates,
+ nullptr,
+ 0},
+ {"s26",
+ nullptr,
+ 4,
+ FPU_OFFSET(26),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s26},
+ nullptr,
+ g_s26_invalidates,
+ nullptr,
+ 0},
+ {"s27",
+ nullptr,
+ 4,
+ FPU_OFFSET(27),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s27},
+ nullptr,
+ g_s27_invalidates,
+ nullptr,
+ 0},
+ {"s28",
+ nullptr,
+ 4,
+ FPU_OFFSET(28),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s28},
+ nullptr,
+ g_s28_invalidates,
+ nullptr,
+ 0},
+ {"s29",
+ nullptr,
+ 4,
+ FPU_OFFSET(29),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s29},
+ nullptr,
+ g_s29_invalidates,
+ nullptr,
+ 0},
+ {"s30",
+ nullptr,
+ 4,
+ FPU_OFFSET(30),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s30},
+ nullptr,
+ g_s30_invalidates,
+ nullptr,
+ 0},
+ {"s31",
+ nullptr,
+ 4,
+ FPU_OFFSET(31),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s31},
+ nullptr,
+ g_s31_invalidates,
+ nullptr,
+ 0},
+ {"fpscr",
+ nullptr,
+ 4,
+ FPSCR_OFFSET,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fpscr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"d0",
+ nullptr,
+ 8,
+ FPU_OFFSET(0),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d0},
+ g_d0_contains,
+ g_d0_invalidates,
+ nullptr,
+ 0},
+ {"d1",
+ nullptr,
+ 8,
+ FPU_OFFSET(2),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d1},
+ g_d1_contains,
+ g_d1_invalidates,
+ nullptr,
+ 0},
+ {"d2",
+ nullptr,
+ 8,
+ FPU_OFFSET(4),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d2},
+ g_d2_contains,
+ g_d2_invalidates,
+ nullptr,
+ 0},
+ {"d3",
+ nullptr,
+ 8,
+ FPU_OFFSET(6),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d3},
+ g_d3_contains,
+ g_d3_invalidates,
+ nullptr,
+ 0},
+ {"d4",
+ nullptr,
+ 8,
+ FPU_OFFSET(8),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d4},
+ g_d4_contains,
+ g_d4_invalidates,
+ nullptr,
+ 0},
+ {"d5",
+ nullptr,
+ 8,
+ FPU_OFFSET(10),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d5},
+ g_d5_contains,
+ g_d5_invalidates,
+ nullptr,
+ 0},
+ {"d6",
+ nullptr,
+ 8,
+ FPU_OFFSET(12),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d6},
+ g_d6_contains,
+ g_d6_invalidates,
+ nullptr,
+ 0},
+ {"d7",
+ nullptr,
+ 8,
+ FPU_OFFSET(14),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d7},
+ g_d7_contains,
+ g_d7_invalidates,
+ nullptr,
+ 0},
+ {"d8",
+ nullptr,
+ 8,
+ FPU_OFFSET(16),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d8},
+ g_d8_contains,
+ g_d8_invalidates,
+ nullptr,
+ 0},
+ {"d9",
+ nullptr,
+ 8,
+ FPU_OFFSET(18),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d9},
+ g_d9_contains,
+ g_d9_invalidates,
+ nullptr,
+ 0},
+ {"d10",
+ nullptr,
+ 8,
+ FPU_OFFSET(20),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d10},
+ g_d10_contains,
+ g_d10_invalidates,
+ nullptr,
+ 0},
+ {"d11",
+ nullptr,
+ 8,
+ FPU_OFFSET(22),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d11},
+ g_d11_contains,
+ g_d11_invalidates,
+ nullptr,
+ 0},
+ {"d12",
+ nullptr,
+ 8,
+ FPU_OFFSET(24),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d12},
+ g_d12_contains,
+ g_d12_invalidates,
+ nullptr,
+ 0},
+ {"d13",
+ nullptr,
+ 8,
+ FPU_OFFSET(26),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d13},
+ g_d13_contains,
+ g_d13_invalidates,
+ nullptr,
+ 0},
+ {"d14",
+ nullptr,
+ 8,
+ FPU_OFFSET(28),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d14},
+ g_d14_contains,
+ g_d14_invalidates,
+ nullptr,
+ 0},
+ {"d15",
+ nullptr,
+ 8,
+ FPU_OFFSET(30),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d15},
+ g_d15_contains,
+ g_d15_invalidates,
+ nullptr,
+ 0},
+ {"d16",
+ nullptr,
+ 8,
+ FPU_OFFSET(32),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d16},
+ nullptr,
+ g_d16_invalidates,
+ nullptr,
+ 0},
+ {"d17",
+ nullptr,
+ 8,
+ FPU_OFFSET(34),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d17},
+ nullptr,
+ g_d17_invalidates,
+ nullptr,
+ 0},
+ {"d18",
+ nullptr,
+ 8,
+ FPU_OFFSET(36),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d18},
+ nullptr,
+ g_d18_invalidates,
+ nullptr,
+ 0},
+ {"d19",
+ nullptr,
+ 8,
+ FPU_OFFSET(38),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d19},
+ nullptr,
+ g_d19_invalidates,
+ nullptr,
+ 0},
+ {"d20",
+ nullptr,
+ 8,
+ FPU_OFFSET(40),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d20},
+ nullptr,
+ g_d20_invalidates,
+ nullptr,
+ 0},
+ {"d21",
+ nullptr,
+ 8,
+ FPU_OFFSET(42),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d21},
+ nullptr,
+ g_d21_invalidates,
+ nullptr,
+ 0},
+ {"d22",
+ nullptr,
+ 8,
+ FPU_OFFSET(44),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d22},
+ nullptr,
+ g_d22_invalidates,
+ nullptr,
+ 0},
+ {"d23",
+ nullptr,
+ 8,
+ FPU_OFFSET(46),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d23},
+ nullptr,
+ g_d23_invalidates,
+ nullptr,
+ 0},
+ {"d24",
+ nullptr,
+ 8,
+ FPU_OFFSET(48),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d24},
+ nullptr,
+ g_d24_invalidates,
+ nullptr,
+ 0},
+ {"d25",
+ nullptr,
+ 8,
+ FPU_OFFSET(50),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d25},
+ nullptr,
+ g_d25_invalidates,
+ nullptr,
+ 0},
+ {"d26",
+ nullptr,
+ 8,
+ FPU_OFFSET(52),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d26},
+ nullptr,
+ g_d26_invalidates,
+ nullptr,
+ 0},
+ {"d27",
+ nullptr,
+ 8,
+ FPU_OFFSET(54),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d27},
+ nullptr,
+ g_d27_invalidates,
+ nullptr,
+ 0},
+ {"d28",
+ nullptr,
+ 8,
+ FPU_OFFSET(56),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d28},
+ nullptr,
+ g_d28_invalidates,
+ nullptr,
+ 0},
+ {"d29",
+ nullptr,
+ 8,
+ FPU_OFFSET(58),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d29},
+ nullptr,
+ g_d29_invalidates,
+ nullptr,
+ 0},
+ {"d30",
+ nullptr,
+ 8,
+ FPU_OFFSET(60),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d30},
+ nullptr,
+ g_d30_invalidates,
+ nullptr,
+ 0},
+ {"d31",
+ nullptr,
+ 8,
+ FPU_OFFSET(62),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d31},
+ nullptr,
+ g_d31_invalidates,
+ nullptr,
+ 0},
+
+ {"q0",
+ nullptr,
+ 16,
+ FPU_OFFSET(0),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q0},
+ g_q0_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q1",
+ nullptr,
+ 16,
+ FPU_OFFSET(4),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q1},
+ g_q1_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q2",
+ nullptr,
+ 16,
+ FPU_OFFSET(8),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q2},
+ g_q2_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q3",
+ nullptr,
+ 16,
+ FPU_OFFSET(12),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q3},
+ g_q3_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q4",
+ nullptr,
+ 16,
+ FPU_OFFSET(16),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q4},
+ g_q4_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q5",
+ nullptr,
+ 16,
+ FPU_OFFSET(20),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q5},
+ g_q5_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q6",
+ nullptr,
+ 16,
+ FPU_OFFSET(24),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q6},
+ g_q6_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q7",
+ nullptr,
+ 16,
+ FPU_OFFSET(28),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q7},
+ g_q7_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q8",
+ nullptr,
+ 16,
+ FPU_OFFSET(32),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q8},
+ g_q8_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q9",
+ nullptr,
+ 16,
+ FPU_OFFSET(36),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q9},
+ g_q9_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q10",
+ nullptr,
+ 16,
+ FPU_OFFSET(40),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q10},
+ g_q10_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q11",
+ nullptr,
+ 16,
+ FPU_OFFSET(44),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q11},
+ g_q11_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q12",
+ nullptr,
+ 16,
+ FPU_OFFSET(48),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q12},
+ g_q12_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q13",
+ nullptr,
+ 16,
+ FPU_OFFSET(52),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q13},
+ g_q13_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q14",
+ nullptr,
+ 16,
+ FPU_OFFSET(56),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q14},
+ g_q14_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q15",
+ nullptr,
+ 16,
+ FPU_OFFSET(60),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q15},
+ g_q15_contains,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"exception",
+ nullptr,
+ 4,
+ EXC_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_exception},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fsr",
+ nullptr,
+ 4,
+ EXC_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_fsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"far",
+ nullptr,
+ 4,
+ EXC_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_far},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_DBG(bvr, 0)},
+ {DEFINE_DBG(bvr, 1)},
+ {DEFINE_DBG(bvr, 2)},
+ {DEFINE_DBG(bvr, 3)},
+ {DEFINE_DBG(bvr, 4)},
+ {DEFINE_DBG(bvr, 5)},
+ {DEFINE_DBG(bvr, 6)},
+ {DEFINE_DBG(bvr, 7)},
+ {DEFINE_DBG(bvr, 8)},
+ {DEFINE_DBG(bvr, 9)},
+ {DEFINE_DBG(bvr, 10)},
+ {DEFINE_DBG(bvr, 11)},
+ {DEFINE_DBG(bvr, 12)},
+ {DEFINE_DBG(bvr, 13)},
+ {DEFINE_DBG(bvr, 14)},
+ {DEFINE_DBG(bvr, 15)},
+
+ {DEFINE_DBG(bcr, 0)},
+ {DEFINE_DBG(bcr, 1)},
+ {DEFINE_DBG(bcr, 2)},
+ {DEFINE_DBG(bcr, 3)},
+ {DEFINE_DBG(bcr, 4)},
+ {DEFINE_DBG(bcr, 5)},
+ {DEFINE_DBG(bcr, 6)},
+ {DEFINE_DBG(bcr, 7)},
+ {DEFINE_DBG(bcr, 8)},
+ {DEFINE_DBG(bcr, 9)},
+ {DEFINE_DBG(bcr, 10)},
+ {DEFINE_DBG(bcr, 11)},
+ {DEFINE_DBG(bcr, 12)},
+ {DEFINE_DBG(bcr, 13)},
+ {DEFINE_DBG(bcr, 14)},
+ {DEFINE_DBG(bcr, 15)},
+
+ {DEFINE_DBG(wvr, 0)},
+ {DEFINE_DBG(wvr, 1)},
+ {DEFINE_DBG(wvr, 2)},
+ {DEFINE_DBG(wvr, 3)},
+ {DEFINE_DBG(wvr, 4)},
+ {DEFINE_DBG(wvr, 5)},
+ {DEFINE_DBG(wvr, 6)},
+ {DEFINE_DBG(wvr, 7)},
+ {DEFINE_DBG(wvr, 8)},
+ {DEFINE_DBG(wvr, 9)},
+ {DEFINE_DBG(wvr, 10)},
+ {DEFINE_DBG(wvr, 11)},
+ {DEFINE_DBG(wvr, 12)},
+ {DEFINE_DBG(wvr, 13)},
+ {DEFINE_DBG(wvr, 14)},
+ {DEFINE_DBG(wvr, 15)},
+
+ {DEFINE_DBG(wcr, 0)},
+ {DEFINE_DBG(wcr, 1)},
+ {DEFINE_DBG(wcr, 2)},
+ {DEFINE_DBG(wcr, 3)},
+ {DEFINE_DBG(wcr, 4)},
+ {DEFINE_DBG(wcr, 5)},
+ {DEFINE_DBG(wcr, 6)},
+ {DEFINE_DBG(wcr, 7)},
+ {DEFINE_DBG(wcr, 8)},
+ {DEFINE_DBG(wcr, 9)},
+ {DEFINE_DBG(wcr, 10)},
+ {DEFINE_DBG(wcr, 11)},
+ {DEFINE_DBG(wcr, 12)},
+ {DEFINE_DBG(wcr, 13)},
+ {DEFINE_DBG(wcr, 14)},
+ {DEFINE_DBG(wcr, 15)}};
#endif // DECLARE_REGISTER_INFOS_ARM_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index f360f25501e7..b996533791ff 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -15,9 +15,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
#include "Utility/ARM64_DWARF_Registers.h"
#include "Utility/ARM64_ehframe_Registers.h"
@@ -50,302 +50,668 @@
#error DEFINE_DBG must be defined before including this header file
#endif
-enum
-{
- gpr_x0 = 0,
- gpr_x1,
- gpr_x2,
- gpr_x3,
- gpr_x4,
- gpr_x5,
- gpr_x6,
- gpr_x7,
- gpr_x8,
- gpr_x9,
- gpr_x10,
- gpr_x11,
- gpr_x12,
- gpr_x13,
- gpr_x14,
- gpr_x15,
- gpr_x16,
- gpr_x17,
- gpr_x18,
- gpr_x19,
- gpr_x20,
- gpr_x21,
- gpr_x22,
- gpr_x23,
- gpr_x24,
- gpr_x25,
- gpr_x26,
- gpr_x27,
- gpr_x28,
- gpr_x29 = 29, gpr_fp = gpr_x29,
- gpr_x30 = 30, gpr_lr = gpr_x30, gpr_ra = gpr_x30,
- gpr_x31 = 31, gpr_sp = gpr_x31,
- gpr_pc = 32,
- gpr_cpsr,
-
- fpu_v0,
- fpu_v1,
- fpu_v2,
- fpu_v3,
- fpu_v4,
- fpu_v5,
- fpu_v6,
- fpu_v7,
- fpu_v8,
- fpu_v9,
- fpu_v10,
- fpu_v11,
- fpu_v12,
- fpu_v13,
- fpu_v14,
- fpu_v15,
- fpu_v16,
- fpu_v17,
- fpu_v18,
- fpu_v19,
- fpu_v20,
- fpu_v21,
- fpu_v22,
- fpu_v23,
- fpu_v24,
- fpu_v25,
- fpu_v26,
- fpu_v27,
- fpu_v28,
- fpu_v29,
- fpu_v30,
- fpu_v31,
-
- fpu_fpsr,
- fpu_fpcr,
-
- exc_far,
- exc_esr,
- exc_exception,
-
- dbg_bvr0,
- dbg_bvr1,
- dbg_bvr2,
- dbg_bvr3,
- dbg_bvr4,
- dbg_bvr5,
- dbg_bvr6,
- dbg_bvr7,
- dbg_bvr8,
- dbg_bvr9,
- dbg_bvr10,
- dbg_bvr11,
- dbg_bvr12,
- dbg_bvr13,
- dbg_bvr14,
- dbg_bvr15,
-
- dbg_bcr0,
- dbg_bcr1,
- dbg_bcr2,
- dbg_bcr3,
- dbg_bcr4,
- dbg_bcr5,
- dbg_bcr6,
- dbg_bcr7,
- dbg_bcr8,
- dbg_bcr9,
- dbg_bcr10,
- dbg_bcr11,
- dbg_bcr12,
- dbg_bcr13,
- dbg_bcr14,
- dbg_bcr15,
-
- dbg_wvr0,
- dbg_wvr1,
- dbg_wvr2,
- dbg_wvr3,
- dbg_wvr4,
- dbg_wvr5,
- dbg_wvr6,
- dbg_wvr7,
- dbg_wvr8,
- dbg_wvr9,
- dbg_wvr10,
- dbg_wvr11,
- dbg_wvr12,
- dbg_wvr13,
- dbg_wvr14,
- dbg_wvr15,
-
- dbg_wcr0,
- dbg_wcr1,
- dbg_wcr2,
- dbg_wcr3,
- dbg_wcr4,
- dbg_wcr5,
- dbg_wcr6,
- dbg_wcr7,
- dbg_wcr8,
- dbg_wcr9,
- dbg_wcr10,
- dbg_wcr11,
- dbg_wcr12,
- dbg_wcr13,
- dbg_wcr14,
- dbg_wcr15,
-
- k_num_registers
+// Offsets for a little-endian layout of the register context
+#define GPR_W_PSEUDO_REG_ENDIAN_OFFSET 0
+#define FPU_S_PSEUDO_REG_ENDIAN_OFFSET 0
+#define FPU_D_PSEUDO_REG_ENDIAN_OFFSET 0
+
+enum {
+ gpr_x0 = 0,
+ gpr_x1,
+ gpr_x2,
+ gpr_x3,
+ gpr_x4,
+ gpr_x5,
+ gpr_x6,
+ gpr_x7,
+ gpr_x8,
+ gpr_x9,
+ gpr_x10,
+ gpr_x11,
+ gpr_x12,
+ gpr_x13,
+ gpr_x14,
+ gpr_x15,
+ gpr_x16,
+ gpr_x17,
+ gpr_x18,
+ gpr_x19,
+ gpr_x20,
+ gpr_x21,
+ gpr_x22,
+ gpr_x23,
+ gpr_x24,
+ gpr_x25,
+ gpr_x26,
+ gpr_x27,
+ gpr_x28,
+ gpr_x29 = 29,
+ gpr_fp = gpr_x29,
+ gpr_x30 = 30,
+ gpr_lr = gpr_x30,
+ gpr_ra = gpr_x30,
+ gpr_x31 = 31,
+ gpr_sp = gpr_x31,
+ gpr_pc = 32,
+ gpr_cpsr,
+
+ gpr_w0,
+ gpr_w1,
+ gpr_w2,
+ gpr_w3,
+ gpr_w4,
+ gpr_w5,
+ gpr_w6,
+ gpr_w7,
+ gpr_w8,
+ gpr_w9,
+ gpr_w10,
+ gpr_w11,
+ gpr_w12,
+ gpr_w13,
+ gpr_w14,
+ gpr_w15,
+ gpr_w16,
+ gpr_w17,
+ gpr_w18,
+ gpr_w19,
+ gpr_w20,
+ gpr_w21,
+ gpr_w22,
+ gpr_w23,
+ gpr_w24,
+ gpr_w25,
+ gpr_w26,
+ gpr_w27,
+ gpr_w28,
+
+ fpu_v0,
+ fpu_v1,
+ fpu_v2,
+ fpu_v3,
+ fpu_v4,
+ fpu_v5,
+ fpu_v6,
+ fpu_v7,
+ fpu_v8,
+ fpu_v9,
+ fpu_v10,
+ fpu_v11,
+ fpu_v12,
+ fpu_v13,
+ fpu_v14,
+ fpu_v15,
+ fpu_v16,
+ fpu_v17,
+ fpu_v18,
+ fpu_v19,
+ fpu_v20,
+ fpu_v21,
+ fpu_v22,
+ fpu_v23,
+ fpu_v24,
+ fpu_v25,
+ fpu_v26,
+ fpu_v27,
+ fpu_v28,
+ fpu_v29,
+ fpu_v30,
+ fpu_v31,
+
+ fpu_s0,
+ fpu_s1,
+ fpu_s2,
+ fpu_s3,
+ fpu_s4,
+ fpu_s5,
+ fpu_s6,
+ fpu_s7,
+ fpu_s8,
+ fpu_s9,
+ fpu_s10,
+ fpu_s11,
+ fpu_s12,
+ fpu_s13,
+ fpu_s14,
+ fpu_s15,
+ fpu_s16,
+ fpu_s17,
+ fpu_s18,
+ fpu_s19,
+ fpu_s20,
+ fpu_s21,
+ fpu_s22,
+ fpu_s23,
+ fpu_s24,
+ fpu_s25,
+ fpu_s26,
+ fpu_s27,
+ fpu_s28,
+ fpu_s29,
+ fpu_s30,
+ fpu_s31,
+
+ fpu_d0,
+ fpu_d1,
+ fpu_d2,
+ fpu_d3,
+ fpu_d4,
+ fpu_d5,
+ fpu_d6,
+ fpu_d7,
+ fpu_d8,
+ fpu_d9,
+ fpu_d10,
+ fpu_d11,
+ fpu_d12,
+ fpu_d13,
+ fpu_d14,
+ fpu_d15,
+ fpu_d16,
+ fpu_d17,
+ fpu_d18,
+ fpu_d19,
+ fpu_d20,
+ fpu_d21,
+ fpu_d22,
+ fpu_d23,
+ fpu_d24,
+ fpu_d25,
+ fpu_d26,
+ fpu_d27,
+ fpu_d28,
+ fpu_d29,
+ fpu_d30,
+ fpu_d31,
+
+ fpu_fpsr,
+ fpu_fpcr,
+
+ exc_far,
+ exc_esr,
+ exc_exception,
+
+ dbg_bvr0,
+ dbg_bvr1,
+ dbg_bvr2,
+ dbg_bvr3,
+ dbg_bvr4,
+ dbg_bvr5,
+ dbg_bvr6,
+ dbg_bvr7,
+ dbg_bvr8,
+ dbg_bvr9,
+ dbg_bvr10,
+ dbg_bvr11,
+ dbg_bvr12,
+ dbg_bvr13,
+ dbg_bvr14,
+ dbg_bvr15,
+
+ dbg_bcr0,
+ dbg_bcr1,
+ dbg_bcr2,
+ dbg_bcr3,
+ dbg_bcr4,
+ dbg_bcr5,
+ dbg_bcr6,
+ dbg_bcr7,
+ dbg_bcr8,
+ dbg_bcr9,
+ dbg_bcr10,
+ dbg_bcr11,
+ dbg_bcr12,
+ dbg_bcr13,
+ dbg_bcr14,
+ dbg_bcr15,
+
+ dbg_wvr0,
+ dbg_wvr1,
+ dbg_wvr2,
+ dbg_wvr3,
+ dbg_wvr4,
+ dbg_wvr5,
+ dbg_wvr6,
+ dbg_wvr7,
+ dbg_wvr8,
+ dbg_wvr9,
+ dbg_wvr10,
+ dbg_wvr11,
+ dbg_wvr12,
+ dbg_wvr13,
+ dbg_wvr14,
+ dbg_wvr15,
+
+ dbg_wcr0,
+ dbg_wcr1,
+ dbg_wcr2,
+ dbg_wcr3,
+ dbg_wcr4,
+ dbg_wcr5,
+ dbg_wcr6,
+ dbg_wcr7,
+ dbg_wcr8,
+ dbg_wcr9,
+ dbg_wcr10,
+ dbg_wcr11,
+ dbg_wcr12,
+ dbg_wcr13,
+ dbg_wcr14,
+ dbg_wcr15,
+
+ k_num_registers
};
-static lldb_private::RegisterInfo g_register_infos_arm64[] = {
-// General purpose registers
-// NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
-// ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== ===============
-{ "x0", nullptr, 8, GPR_OFFSET(0), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x0, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_x0 }, nullptr, nullptr, nullptr, 0},
-{ "x1", nullptr, 8, GPR_OFFSET(1), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x1, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_x1 }, nullptr, nullptr, nullptr, 0},
-{ "x2", nullptr, 8, GPR_OFFSET(2), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x2, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_x2 }, nullptr, nullptr, nullptr, 0},
-{ "x3", nullptr, 8, GPR_OFFSET(3), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x3, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_x3 }, nullptr, nullptr, nullptr, 0},
-{ "x4", nullptr, 8, GPR_OFFSET(4), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x4, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, gpr_x4 }, nullptr, nullptr, nullptr, 0},
-{ "x5", nullptr, 8, GPR_OFFSET(5), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x5, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, gpr_x5 }, nullptr, nullptr, nullptr, 0},
-{ "x6", nullptr, 8, GPR_OFFSET(6), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x6, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, gpr_x6 }, nullptr, nullptr, nullptr, 0},
-{ "x7", nullptr, 8, GPR_OFFSET(7), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x7, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, gpr_x7 }, nullptr, nullptr, nullptr, 0},
-{ "x8", nullptr, 8, GPR_OFFSET(8), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x8 }, nullptr, nullptr, nullptr, 0},
-{ "x9", nullptr, 8, GPR_OFFSET(9), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x9 }, nullptr, nullptr, nullptr, 0},
-{ "x10", nullptr, 8, GPR_OFFSET(10), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x10 }, nullptr, nullptr, nullptr, 0},
-{ "x11", nullptr, 8, GPR_OFFSET(11), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x11 }, nullptr, nullptr, nullptr, 0},
-{ "x12", nullptr, 8, GPR_OFFSET(12), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x12 }, nullptr, nullptr, nullptr, 0},
-{ "x13", nullptr, 8, GPR_OFFSET(13), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x13 }, nullptr, nullptr, nullptr, 0},
-{ "x14", nullptr, 8, GPR_OFFSET(14), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x14 }, nullptr, nullptr, nullptr, 0},
-{ "x15", nullptr, 8, GPR_OFFSET(15), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x15 }, nullptr, nullptr, nullptr, 0},
-{ "x16", nullptr, 8, GPR_OFFSET(16), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x16 }, nullptr, nullptr, nullptr, 0},
-{ "x17", nullptr, 8, GPR_OFFSET(17), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x17 }, nullptr, nullptr, nullptr, 0},
-{ "x18", nullptr, 8, GPR_OFFSET(18), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x18 }, nullptr, nullptr, nullptr, 0},
-{ "x19", nullptr, 8, GPR_OFFSET(19), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x19 }, nullptr, nullptr, nullptr, 0},
-{ "x20", nullptr, 8, GPR_OFFSET(20), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x20 }, nullptr, nullptr, nullptr, 0},
-{ "x21", nullptr, 8, GPR_OFFSET(21), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x21 }, nullptr, nullptr, nullptr, 0},
-{ "x22", nullptr, 8, GPR_OFFSET(22), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x22 }, nullptr, nullptr, nullptr, 0},
-{ "x23", nullptr, 8, GPR_OFFSET(23), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x23 }, nullptr, nullptr, nullptr, 0},
-{ "x24", nullptr, 8, GPR_OFFSET(24), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x24 }, nullptr, nullptr, nullptr, 0},
-{ "x25", nullptr, 8, GPR_OFFSET(25), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x25 }, nullptr, nullptr, nullptr, 0},
-{ "x26", nullptr, 8, GPR_OFFSET(26), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x26 }, nullptr, nullptr, nullptr, 0},
-{ "x27", nullptr, 8, GPR_OFFSET(27), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x27 }, nullptr, nullptr, nullptr, 0},
-{ "x28", nullptr, 8, GPR_OFFSET(28), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x28 }, nullptr, nullptr, nullptr, 0},
-
-{ "fp", "x29", 8, GPR_OFFSET(29), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_fp }, nullptr, nullptr, nullptr, 0},
-{ "lr", "x30", 8, GPR_OFFSET(30), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr }, nullptr, nullptr, nullptr, 0},
-{ "sp", "x31", 8, GPR_OFFSET(31), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp }, nullptr, nullptr, nullptr, 0},
-{ "pc", nullptr, 8, GPR_OFFSET(32), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc }, nullptr, nullptr, nullptr, 0},
-
-{ "cpsr", nullptr, 4, GPR_OFFSET_NAME(cpsr), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr }, nullptr, nullptr, nullptr, 0},
-
-{ "v0", nullptr, 16, FPU_OFFSET(0), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v0 }, nullptr, nullptr, nullptr, 0},
-{ "v1", nullptr, 16, FPU_OFFSET(1), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v1 }, nullptr, nullptr, nullptr, 0},
-{ "v2", nullptr, 16, FPU_OFFSET(2), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v2 }, nullptr, nullptr, nullptr, 0},
-{ "v3", nullptr, 16, FPU_OFFSET(3), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v3 }, nullptr, nullptr, nullptr, 0},
-{ "v4", nullptr, 16, FPU_OFFSET(4), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v4 }, nullptr, nullptr, nullptr, 0},
-{ "v5", nullptr, 16, FPU_OFFSET(5), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v5 }, nullptr, nullptr, nullptr, 0},
-{ "v6", nullptr, 16, FPU_OFFSET(6), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v6 }, nullptr, nullptr, nullptr, 0},
-{ "v7", nullptr, 16, FPU_OFFSET(7), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v7 }, nullptr, nullptr, nullptr, 0},
-{ "v8", nullptr, 16, FPU_OFFSET(8), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v8 }, nullptr, nullptr, nullptr, 0},
-{ "v9", nullptr, 16, FPU_OFFSET(9), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v9 }, nullptr, nullptr, nullptr, 0},
-{ "v10", nullptr, 16, FPU_OFFSET(10), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v10 }, nullptr, nullptr, nullptr, 0},
-{ "v11", nullptr, 16, FPU_OFFSET(11), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v11 }, nullptr, nullptr, nullptr, 0},
-{ "v12", nullptr, 16, FPU_OFFSET(12), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v12 }, nullptr, nullptr, nullptr, 0},
-{ "v13", nullptr, 16, FPU_OFFSET(13), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v13 }, nullptr, nullptr, nullptr, 0},
-{ "v14", nullptr, 16, FPU_OFFSET(14), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v14 }, nullptr, nullptr, nullptr, 0},
-{ "v15", nullptr, 16, FPU_OFFSET(15), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v15 }, nullptr, nullptr, nullptr, 0},
-{ "v16", nullptr, 16, FPU_OFFSET(16), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v16 }, nullptr, nullptr, nullptr, 0},
-{ "v17", nullptr, 16, FPU_OFFSET(17), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v17 }, nullptr, nullptr, nullptr, 0},
-{ "v18", nullptr, 16, FPU_OFFSET(18), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v18 }, nullptr, nullptr, nullptr, 0},
-{ "v19", nullptr, 16, FPU_OFFSET(19), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v19 }, nullptr, nullptr, nullptr, 0},
-{ "v20", nullptr, 16, FPU_OFFSET(20), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v20 }, nullptr, nullptr, nullptr, 0},
-{ "v21", nullptr, 16, FPU_OFFSET(21), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v21 }, nullptr, nullptr, nullptr, 0},
-{ "v22", nullptr, 16, FPU_OFFSET(22), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v22 }, nullptr, nullptr, nullptr, 0},
-{ "v23", nullptr, 16, FPU_OFFSET(23), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v23 }, nullptr, nullptr, nullptr, 0},
-{ "v24", nullptr, 16, FPU_OFFSET(24), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v24 }, nullptr, nullptr, nullptr, 0},
-{ "v25", nullptr, 16, FPU_OFFSET(25), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v25 }, nullptr, nullptr, nullptr, 0},
-{ "v26", nullptr, 16, FPU_OFFSET(26), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v26 }, nullptr, nullptr, nullptr, 0},
-{ "v27", nullptr, 16, FPU_OFFSET(27), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v27 }, nullptr, nullptr, nullptr, 0},
-{ "v28", nullptr, 16, FPU_OFFSET(28), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v28 }, nullptr, nullptr, nullptr, 0},
-{ "v29", nullptr, 16, FPU_OFFSET(29), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v29 }, nullptr, nullptr, nullptr, 0},
-{ "v30", nullptr, 16, FPU_OFFSET(30), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v30 }, nullptr, nullptr, nullptr, 0},
-{ "v31", nullptr, 16, FPU_OFFSET(31), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v31 }, nullptr, nullptr, nullptr, 0},
-
-{ "fpsr", nullptr, 4, FPU_OFFSET_NAME(fpsr), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr }, nullptr, nullptr, nullptr, 0},
-{ "fpcr", nullptr, 4, FPU_OFFSET_NAME(fpcr), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr }, nullptr, nullptr, nullptr, 0},
-
-{ "far", nullptr, 8, EXC_OFFSET_NAME(far), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, nullptr, nullptr, nullptr, 0},
-{ "esr", nullptr, 4, EXC_OFFSET_NAME(esr), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr }, nullptr, nullptr, nullptr, 0},
-{ "exception",nullptr, 4, EXC_OFFSET_NAME(exception), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, nullptr, nullptr, nullptr, 0},
-
-{ DEFINE_DBG (bvr, 0) },
-{ DEFINE_DBG (bvr, 1) },
-{ DEFINE_DBG (bvr, 2) },
-{ DEFINE_DBG (bvr, 3) },
-{ DEFINE_DBG (bvr, 4) },
-{ DEFINE_DBG (bvr, 5) },
-{ DEFINE_DBG (bvr, 6) },
-{ DEFINE_DBG (bvr, 7) },
-{ DEFINE_DBG (bvr, 8) },
-{ DEFINE_DBG (bvr, 9) },
-{ DEFINE_DBG (bvr, 10) },
-{ DEFINE_DBG (bvr, 11) },
-{ DEFINE_DBG (bvr, 12) },
-{ DEFINE_DBG (bvr, 13) },
-{ DEFINE_DBG (bvr, 14) },
-{ DEFINE_DBG (bvr, 15) },
-
-{ DEFINE_DBG (bcr, 0) },
-{ DEFINE_DBG (bcr, 1) },
-{ DEFINE_DBG (bcr, 2) },
-{ DEFINE_DBG (bcr, 3) },
-{ DEFINE_DBG (bcr, 4) },
-{ DEFINE_DBG (bcr, 5) },
-{ DEFINE_DBG (bcr, 6) },
-{ DEFINE_DBG (bcr, 7) },
-{ DEFINE_DBG (bcr, 8) },
-{ DEFINE_DBG (bcr, 9) },
-{ DEFINE_DBG (bcr, 10) },
-{ DEFINE_DBG (bcr, 11) },
-{ DEFINE_DBG (bcr, 12) },
-{ DEFINE_DBG (bcr, 13) },
-{ DEFINE_DBG (bcr, 14) },
-{ DEFINE_DBG (bcr, 15) },
-
-{ DEFINE_DBG (wvr, 0) },
-{ DEFINE_DBG (wvr, 1) },
-{ DEFINE_DBG (wvr, 2) },
-{ DEFINE_DBG (wvr, 3) },
-{ DEFINE_DBG (wvr, 4) },
-{ DEFINE_DBG (wvr, 5) },
-{ DEFINE_DBG (wvr, 6) },
-{ DEFINE_DBG (wvr, 7) },
-{ DEFINE_DBG (wvr, 8) },
-{ DEFINE_DBG (wvr, 9) },
-{ DEFINE_DBG (wvr, 10) },
-{ DEFINE_DBG (wvr, 11) },
-{ DEFINE_DBG (wvr, 12) },
-{ DEFINE_DBG (wvr, 13) },
-{ DEFINE_DBG (wvr, 14) },
-{ DEFINE_DBG (wvr, 15) },
-
-{ DEFINE_DBG (wcr, 0) },
-{ DEFINE_DBG (wcr, 1) },
-{ DEFINE_DBG (wcr, 2) },
-{ DEFINE_DBG (wcr, 3) },
-{ DEFINE_DBG (wcr, 4) },
-{ DEFINE_DBG (wcr, 5) },
-{ DEFINE_DBG (wcr, 6) },
-{ DEFINE_DBG (wcr, 7) },
-{ DEFINE_DBG (wcr, 8) },
-{ DEFINE_DBG (wcr, 9) },
-{ DEFINE_DBG (wcr, 10) },
-{ DEFINE_DBG (wcr, 11) },
-{ DEFINE_DBG (wcr, 12) },
-{ DEFINE_DBG (wcr, 13) },
-{ DEFINE_DBG (wcr, 14) },
-{ DEFINE_DBG (wcr, 15) }
+static uint32_t g_contained_x0[] = {gpr_x0, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x1[] = {gpr_x1, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x2[] = {gpr_x2, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x3[] = {gpr_x3, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x4[] = {gpr_x4, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x5[] = {gpr_x5, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x6[] = {gpr_x6, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x7[] = {gpr_x7, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x8[] = {gpr_x8, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x9[] = {gpr_x9, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x10[] = {gpr_x10, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x11[] = {gpr_x11, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x12[] = {gpr_x12, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x13[] = {gpr_x13, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x14[] = {gpr_x14, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x15[] = {gpr_x15, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x16[] = {gpr_x16, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x17[] = {gpr_x17, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x18[] = {gpr_x18, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x19[] = {gpr_x19, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x20[] = {gpr_x20, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x21[] = {gpr_x21, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x22[] = {gpr_x22, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x23[] = {gpr_x23, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x24[] = {gpr_x24, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x25[] = {gpr_x25, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x26[] = {gpr_x26, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x27[] = {gpr_x27, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x28[] = {gpr_x28, LLDB_INVALID_REGNUM};
+
+static uint32_t g_w0_invalidates[] = {gpr_x0, LLDB_INVALID_REGNUM};
+static uint32_t g_w1_invalidates[] = {gpr_x1, LLDB_INVALID_REGNUM};
+static uint32_t g_w2_invalidates[] = {gpr_x2, LLDB_INVALID_REGNUM};
+static uint32_t g_w3_invalidates[] = {gpr_x3, LLDB_INVALID_REGNUM};
+static uint32_t g_w4_invalidates[] = {gpr_x4, LLDB_INVALID_REGNUM};
+static uint32_t g_w5_invalidates[] = {gpr_x5, LLDB_INVALID_REGNUM};
+static uint32_t g_w6_invalidates[] = {gpr_x6, LLDB_INVALID_REGNUM};
+static uint32_t g_w7_invalidates[] = {gpr_x7, LLDB_INVALID_REGNUM};
+static uint32_t g_w8_invalidates[] = {gpr_x8, LLDB_INVALID_REGNUM};
+static uint32_t g_w9_invalidates[] = {gpr_x9, LLDB_INVALID_REGNUM};
+static uint32_t g_w10_invalidates[] = {gpr_x10, LLDB_INVALID_REGNUM};
+static uint32_t g_w11_invalidates[] = {gpr_x11, LLDB_INVALID_REGNUM};
+static uint32_t g_w12_invalidates[] = {gpr_x12, LLDB_INVALID_REGNUM};
+static uint32_t g_w13_invalidates[] = {gpr_x13, LLDB_INVALID_REGNUM};
+static uint32_t g_w14_invalidates[] = {gpr_x14, LLDB_INVALID_REGNUM};
+static uint32_t g_w15_invalidates[] = {gpr_x15, LLDB_INVALID_REGNUM};
+static uint32_t g_w16_invalidates[] = {gpr_x16, LLDB_INVALID_REGNUM};
+static uint32_t g_w17_invalidates[] = {gpr_x17, LLDB_INVALID_REGNUM};
+static uint32_t g_w18_invalidates[] = {gpr_x18, LLDB_INVALID_REGNUM};
+static uint32_t g_w19_invalidates[] = {gpr_x19, LLDB_INVALID_REGNUM};
+static uint32_t g_w20_invalidates[] = {gpr_x20, LLDB_INVALID_REGNUM};
+static uint32_t g_w21_invalidates[] = {gpr_x21, LLDB_INVALID_REGNUM};
+static uint32_t g_w22_invalidates[] = {gpr_x22, LLDB_INVALID_REGNUM};
+static uint32_t g_w23_invalidates[] = {gpr_x23, LLDB_INVALID_REGNUM};
+static uint32_t g_w24_invalidates[] = {gpr_x24, LLDB_INVALID_REGNUM};
+static uint32_t g_w25_invalidates[] = {gpr_x25, LLDB_INVALID_REGNUM};
+static uint32_t g_w26_invalidates[] = {gpr_x26, LLDB_INVALID_REGNUM};
+static uint32_t g_w27_invalidates[] = {gpr_x27, LLDB_INVALID_REGNUM};
+static uint32_t g_w28_invalidates[] = {gpr_x28, LLDB_INVALID_REGNUM};
+
+static uint32_t g_contained_v0[] = {fpu_v0, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v1[] = {fpu_v1, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v2[] = {fpu_v2, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v3[] = {fpu_v3, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v4[] = {fpu_v4, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v5[] = {fpu_v5, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v6[] = {fpu_v6, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v7[] = {fpu_v7, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v8[] = {fpu_v8, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v9[] = {fpu_v9, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v10[] = {fpu_v10, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v11[] = {fpu_v11, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v12[] = {fpu_v12, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v13[] = {fpu_v13, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v14[] = {fpu_v14, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v15[] = {fpu_v15, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v16[] = {fpu_v16, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v17[] = {fpu_v17, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v18[] = {fpu_v18, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v19[] = {fpu_v19, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v20[] = {fpu_v20, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v21[] = {fpu_v21, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v22[] = {fpu_v22, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v23[] = {fpu_v23, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v24[] = {fpu_v24, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v25[] = {fpu_v25, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v26[] = {fpu_v26, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v27[] = {fpu_v27, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v28[] = {fpu_v28, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v29[] = {fpu_v29, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v30[] = {fpu_v30, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v31[] = {fpu_v31, LLDB_INVALID_REGNUM};
+
+static uint32_t g_s0_invalidates[] = {fpu_v0, fpu_d0, LLDB_INVALID_REGNUM};
+static uint32_t g_s1_invalidates[] = {fpu_v1, fpu_d1, LLDB_INVALID_REGNUM};
+static uint32_t g_s2_invalidates[] = {fpu_v2, fpu_d2, LLDB_INVALID_REGNUM};
+static uint32_t g_s3_invalidates[] = {fpu_v3, fpu_d3, LLDB_INVALID_REGNUM};
+static uint32_t g_s4_invalidates[] = {fpu_v4, fpu_d4, LLDB_INVALID_REGNUM};
+static uint32_t g_s5_invalidates[] = {fpu_v5, fpu_d5, LLDB_INVALID_REGNUM};
+static uint32_t g_s6_invalidates[] = {fpu_v6, fpu_d6, LLDB_INVALID_REGNUM};
+static uint32_t g_s7_invalidates[] = {fpu_v7, fpu_d7, LLDB_INVALID_REGNUM};
+static uint32_t g_s8_invalidates[] = {fpu_v8, fpu_d8, LLDB_INVALID_REGNUM};
+static uint32_t g_s9_invalidates[] = {fpu_v9, fpu_d9, LLDB_INVALID_REGNUM};
+static uint32_t g_s10_invalidates[] = {fpu_v10, fpu_d10, LLDB_INVALID_REGNUM};
+static uint32_t g_s11_invalidates[] = {fpu_v11, fpu_d11, LLDB_INVALID_REGNUM};
+static uint32_t g_s12_invalidates[] = {fpu_v12, fpu_d12, LLDB_INVALID_REGNUM};
+static uint32_t g_s13_invalidates[] = {fpu_v13, fpu_d13, LLDB_INVALID_REGNUM};
+static uint32_t g_s14_invalidates[] = {fpu_v14, fpu_d14, LLDB_INVALID_REGNUM};
+static uint32_t g_s15_invalidates[] = {fpu_v15, fpu_d15, LLDB_INVALID_REGNUM};
+static uint32_t g_s16_invalidates[] = {fpu_v16, fpu_d16, LLDB_INVALID_REGNUM};
+static uint32_t g_s17_invalidates[] = {fpu_v17, fpu_d17, LLDB_INVALID_REGNUM};
+static uint32_t g_s18_invalidates[] = {fpu_v18, fpu_d18, LLDB_INVALID_REGNUM};
+static uint32_t g_s19_invalidates[] = {fpu_v19, fpu_d19, LLDB_INVALID_REGNUM};
+static uint32_t g_s20_invalidates[] = {fpu_v20, fpu_d20, LLDB_INVALID_REGNUM};
+static uint32_t g_s21_invalidates[] = {fpu_v21, fpu_d21, LLDB_INVALID_REGNUM};
+static uint32_t g_s22_invalidates[] = {fpu_v22, fpu_d22, LLDB_INVALID_REGNUM};
+static uint32_t g_s23_invalidates[] = {fpu_v23, fpu_d23, LLDB_INVALID_REGNUM};
+static uint32_t g_s24_invalidates[] = {fpu_v24, fpu_d24, LLDB_INVALID_REGNUM};
+static uint32_t g_s25_invalidates[] = {fpu_v25, fpu_d25, LLDB_INVALID_REGNUM};
+static uint32_t g_s26_invalidates[] = {fpu_v26, fpu_d26, LLDB_INVALID_REGNUM};
+static uint32_t g_s27_invalidates[] = {fpu_v27, fpu_d27, LLDB_INVALID_REGNUM};
+static uint32_t g_s28_invalidates[] = {fpu_v28, fpu_d28, LLDB_INVALID_REGNUM};
+static uint32_t g_s29_invalidates[] = {fpu_v29, fpu_d29, LLDB_INVALID_REGNUM};
+static uint32_t g_s30_invalidates[] = {fpu_v30, fpu_d30, LLDB_INVALID_REGNUM};
+static uint32_t g_s31_invalidates[] = {fpu_v31, fpu_d31, LLDB_INVALID_REGNUM};
+
+static uint32_t g_d0_invalidates[] = {fpu_v0, fpu_s0, LLDB_INVALID_REGNUM};
+static uint32_t g_d1_invalidates[] = {fpu_v1, fpu_s1, LLDB_INVALID_REGNUM};
+static uint32_t g_d2_invalidates[] = {fpu_v2, fpu_s2, LLDB_INVALID_REGNUM};
+static uint32_t g_d3_invalidates[] = {fpu_v3, fpu_s3, LLDB_INVALID_REGNUM};
+static uint32_t g_d4_invalidates[] = {fpu_v4, fpu_s4, LLDB_INVALID_REGNUM};
+static uint32_t g_d5_invalidates[] = {fpu_v5, fpu_s5, LLDB_INVALID_REGNUM};
+static uint32_t g_d6_invalidates[] = {fpu_v6, fpu_s6, LLDB_INVALID_REGNUM};
+static uint32_t g_d7_invalidates[] = {fpu_v7, fpu_s7, LLDB_INVALID_REGNUM};
+static uint32_t g_d8_invalidates[] = {fpu_v8, fpu_s8, LLDB_INVALID_REGNUM};
+static uint32_t g_d9_invalidates[] = {fpu_v9, fpu_s9, LLDB_INVALID_REGNUM};
+static uint32_t g_d10_invalidates[] = {fpu_v10, fpu_s10, LLDB_INVALID_REGNUM};
+static uint32_t g_d11_invalidates[] = {fpu_v11, fpu_s11, LLDB_INVALID_REGNUM};
+static uint32_t g_d12_invalidates[] = {fpu_v12, fpu_s12, LLDB_INVALID_REGNUM};
+static uint32_t g_d13_invalidates[] = {fpu_v13, fpu_s13, LLDB_INVALID_REGNUM};
+static uint32_t g_d14_invalidates[] = {fpu_v14, fpu_s14, LLDB_INVALID_REGNUM};
+static uint32_t g_d15_invalidates[] = {fpu_v15, fpu_s15, LLDB_INVALID_REGNUM};
+static uint32_t g_d16_invalidates[] = {fpu_v16, fpu_s16, LLDB_INVALID_REGNUM};
+static uint32_t g_d17_invalidates[] = {fpu_v17, fpu_s17, LLDB_INVALID_REGNUM};
+static uint32_t g_d18_invalidates[] = {fpu_v18, fpu_s18, LLDB_INVALID_REGNUM};
+static uint32_t g_d19_invalidates[] = {fpu_v19, fpu_s19, LLDB_INVALID_REGNUM};
+static uint32_t g_d20_invalidates[] = {fpu_v20, fpu_s20, LLDB_INVALID_REGNUM};
+static uint32_t g_d21_invalidates[] = {fpu_v21, fpu_s21, LLDB_INVALID_REGNUM};
+static uint32_t g_d22_invalidates[] = {fpu_v22, fpu_s22, LLDB_INVALID_REGNUM};
+static uint32_t g_d23_invalidates[] = {fpu_v23, fpu_s23, LLDB_INVALID_REGNUM};
+static uint32_t g_d24_invalidates[] = {fpu_v24, fpu_s24, LLDB_INVALID_REGNUM};
+static uint32_t g_d25_invalidates[] = {fpu_v25, fpu_s25, LLDB_INVALID_REGNUM};
+static uint32_t g_d26_invalidates[] = {fpu_v26, fpu_s26, LLDB_INVALID_REGNUM};
+static uint32_t g_d27_invalidates[] = {fpu_v27, fpu_s27, LLDB_INVALID_REGNUM};
+static uint32_t g_d28_invalidates[] = {fpu_v28, fpu_s28, LLDB_INVALID_REGNUM};
+static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM};
+static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM};
+static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
+
+static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
+ // clang-format off
+ // General purpose registers
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
+ // ===== ======= == ============= =================== ================ ================= =============== ======================== =================== ====== ============== ======= ======= ==
+ {"x0", nullptr, 8, GPR_OFFSET(0), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x0, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_x0}, nullptr, nullptr, nullptr, 0},
+ {"x1", nullptr, 8, GPR_OFFSET(1), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x1, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_x1}, nullptr, nullptr, nullptr, 0},
+ {"x2", nullptr, 8, GPR_OFFSET(2), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x2, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_x2}, nullptr, nullptr, nullptr, 0},
+ {"x3", nullptr, 8, GPR_OFFSET(3), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x3, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_x3}, nullptr, nullptr, nullptr, 0},
+ {"x4", nullptr, 8, GPR_OFFSET(4), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x4, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, gpr_x4}, nullptr, nullptr, nullptr, 0},
+ {"x5", nullptr, 8, GPR_OFFSET(5), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x5, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, gpr_x5}, nullptr, nullptr, nullptr, 0},
+ {"x6", nullptr, 8, GPR_OFFSET(6), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x6, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, gpr_x6}, nullptr, nullptr, nullptr, 0},
+ {"x7", nullptr, 8, GPR_OFFSET(7), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x7, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, gpr_x7}, nullptr, nullptr, nullptr, 0},
+ {"x8", nullptr, 8, GPR_OFFSET(8), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x8}, nullptr, nullptr, nullptr, 0},
+ {"x9", nullptr, 8, GPR_OFFSET(9), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x9}, nullptr, nullptr, nullptr, 0},
+ {"x10", nullptr, 8, GPR_OFFSET(10), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x10}, nullptr, nullptr, nullptr, 0},
+ {"x11", nullptr, 8, GPR_OFFSET(11), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x11}, nullptr, nullptr, nullptr, 0},
+ {"x12", nullptr, 8, GPR_OFFSET(12), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x12}, nullptr, nullptr, nullptr, 0},
+ {"x13", nullptr, 8, GPR_OFFSET(13), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x13}, nullptr, nullptr, nullptr, 0},
+ {"x14", nullptr, 8, GPR_OFFSET(14), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x14}, nullptr, nullptr, nullptr, 0},
+ {"x15", nullptr, 8, GPR_OFFSET(15), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x15}, nullptr, nullptr, nullptr, 0},
+ {"x16", nullptr, 8, GPR_OFFSET(16), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x16}, nullptr, nullptr, nullptr, 0},
+ {"x17", nullptr, 8, GPR_OFFSET(17), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x17}, nullptr, nullptr, nullptr, 0},
+ {"x18", nullptr, 8, GPR_OFFSET(18), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x18}, nullptr, nullptr, nullptr, 0},
+ {"x19", nullptr, 8, GPR_OFFSET(19), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x19}, nullptr, nullptr, nullptr, 0},
+ {"x20", nullptr, 8, GPR_OFFSET(20), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x20}, nullptr, nullptr, nullptr, 0},
+ {"x21", nullptr, 8, GPR_OFFSET(21), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x21}, nullptr, nullptr, nullptr, 0},
+ {"x22", nullptr, 8, GPR_OFFSET(22), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x22}, nullptr, nullptr, nullptr, 0},
+ {"x23", nullptr, 8, GPR_OFFSET(23), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x23}, nullptr, nullptr, nullptr, 0},
+ {"x24", nullptr, 8, GPR_OFFSET(24), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x24}, nullptr, nullptr, nullptr, 0},
+ {"x25", nullptr, 8, GPR_OFFSET(25), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x25}, nullptr, nullptr, nullptr, 0},
+ {"x26", nullptr, 8, GPR_OFFSET(26), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x26}, nullptr, nullptr, nullptr, 0},
+ {"x27", nullptr, 8, GPR_OFFSET(27), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x27}, nullptr, nullptr, nullptr, 0},
+ {"x28", nullptr, 8, GPR_OFFSET(28), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x28}, nullptr, nullptr, nullptr, 0},
+ {"fp", "x29", 8, GPR_OFFSET(29), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_fp}, nullptr, nullptr, nullptr, 0},
+ {"lr", "x30", 8, GPR_OFFSET(30), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr}, nullptr, nullptr, nullptr, 0},
+ {"sp", "x31", 8, GPR_OFFSET(31), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp}, nullptr, nullptr, nullptr, 0},
+ {"pc", nullptr, 8, GPR_OFFSET(32), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc}, nullptr, nullptr, nullptr, 0},
+
+ {"cpsr",nullptr, 4, GPR_OFFSET_NAME(cpsr), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr}, nullptr, nullptr, nullptr, 0},
+
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE INVALIDATES DYNEXPR SZ
+ // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
+ {"w0", nullptr, 4, GPR_OFFSET(0) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w0}, g_contained_x0, g_w0_invalidates, nullptr, 0},
+ {"w1", nullptr, 4, GPR_OFFSET(1) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w1}, g_contained_x1, g_w1_invalidates, nullptr, 0},
+ {"w2", nullptr, 4, GPR_OFFSET(2) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w2}, g_contained_x2, g_w2_invalidates, nullptr, 0},
+ {"w3", nullptr, 4, GPR_OFFSET(3) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w3}, g_contained_x3, g_w3_invalidates, nullptr, 0},
+ {"w4", nullptr, 4, GPR_OFFSET(4) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w4}, g_contained_x4, g_w4_invalidates, nullptr, 0},
+ {"w5", nullptr, 4, GPR_OFFSET(5) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w5}, g_contained_x5, g_w5_invalidates, nullptr, 0},
+ {"w6", nullptr, 4, GPR_OFFSET(6) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w6}, g_contained_x6, g_w6_invalidates, nullptr, 0},
+ {"w7", nullptr, 4, GPR_OFFSET(7) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w7}, g_contained_x7, g_w7_invalidates, nullptr, 0},
+ {"w8", nullptr, 4, GPR_OFFSET(8) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w8}, g_contained_x8, g_w8_invalidates, nullptr, 0},
+ {"w9", nullptr, 4, GPR_OFFSET(9) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w9}, g_contained_x9, g_w9_invalidates, nullptr, 0},
+ {"w10", nullptr, 4, GPR_OFFSET(10) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w10}, g_contained_x10, g_w10_invalidates, nullptr, 0},
+ {"w11", nullptr, 4, GPR_OFFSET(11) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w11}, g_contained_x11, g_w11_invalidates, nullptr, 0},
+ {"w12", nullptr, 4, GPR_OFFSET(12) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w12}, g_contained_x12, g_w12_invalidates, nullptr, 0},
+ {"w13", nullptr, 4, GPR_OFFSET(13) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w13}, g_contained_x13, g_w13_invalidates, nullptr, 0},
+ {"w14", nullptr, 4, GPR_OFFSET(14) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w14}, g_contained_x14, g_w14_invalidates, nullptr, 0},
+ {"w15", nullptr, 4, GPR_OFFSET(15) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w15}, g_contained_x15, g_w15_invalidates, nullptr, 0},
+ {"w16", nullptr, 4, GPR_OFFSET(16) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w16}, g_contained_x16, g_w16_invalidates, nullptr, 0},
+ {"w17", nullptr, 4, GPR_OFFSET(17) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w17}, g_contained_x17, g_w17_invalidates, nullptr, 0},
+ {"w18", nullptr, 4, GPR_OFFSET(18) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w18}, g_contained_x18, g_w18_invalidates, nullptr, 0},
+ {"w19", nullptr, 4, GPR_OFFSET(19) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w19}, g_contained_x19, g_w19_invalidates, nullptr, 0},
+ {"w20", nullptr, 4, GPR_OFFSET(20) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w20}, g_contained_x20, g_w20_invalidates, nullptr, 0},
+ {"w21", nullptr, 4, GPR_OFFSET(21) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w21}, g_contained_x21, g_w21_invalidates, nullptr, 0},
+ {"w22", nullptr, 4, GPR_OFFSET(22) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w22}, g_contained_x22, g_w22_invalidates, nullptr, 0},
+ {"w23", nullptr, 4, GPR_OFFSET(23) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w23}, g_contained_x23, g_w23_invalidates, nullptr, 0},
+ {"w24", nullptr, 4, GPR_OFFSET(24) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w24}, g_contained_x24, g_w24_invalidates, nullptr, 0},
+ {"w25", nullptr, 4, GPR_OFFSET(25) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w25}, g_contained_x25, g_w25_invalidates, nullptr, 0},
+ {"w26", nullptr, 4, GPR_OFFSET(26) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w26}, g_contained_x26, g_w26_invalidates, nullptr, 0},
+ {"w27", nullptr, 4, GPR_OFFSET(27) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w27}, g_contained_x27, g_w27_invalidates, nullptr, 0},
+ {"w28", nullptr, 4, GPR_OFFSET(28) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w28}, g_contained_x28, g_w28_invalidates, nullptr, 0},
+
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
+ // ===== ======= == ============= =================== ================ ================= =============== =================== =================== ====== ============== ======= ======= ==
+ {"v0", nullptr, 16, FPU_OFFSET(0), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v0}, nullptr, nullptr, nullptr, 0},
+ {"v1", nullptr, 16, FPU_OFFSET(1), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v1}, nullptr, nullptr, nullptr, 0},
+ {"v2", nullptr, 16, FPU_OFFSET(2), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v2}, nullptr, nullptr, nullptr, 0},
+ {"v3", nullptr, 16, FPU_OFFSET(3), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v3}, nullptr, nullptr, nullptr, 0},
+ {"v4", nullptr, 16, FPU_OFFSET(4), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v4}, nullptr, nullptr, nullptr, 0},
+ {"v5", nullptr, 16, FPU_OFFSET(5), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v5}, nullptr, nullptr, nullptr, 0},
+ {"v6", nullptr, 16, FPU_OFFSET(6), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v6}, nullptr, nullptr, nullptr, 0},
+ {"v7", nullptr, 16, FPU_OFFSET(7), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v7}, nullptr, nullptr, nullptr, 0},
+ {"v8", nullptr, 16, FPU_OFFSET(8), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v8}, nullptr, nullptr, nullptr, 0},
+ {"v9", nullptr, 16, FPU_OFFSET(9), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v9}, nullptr, nullptr, nullptr, 0},
+ {"v10", nullptr, 16, FPU_OFFSET(10), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v10}, nullptr, nullptr, nullptr, 0},
+ {"v11", nullptr, 16, FPU_OFFSET(11), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v11}, nullptr, nullptr, nullptr, 0},
+ {"v12", nullptr, 16, FPU_OFFSET(12), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v12}, nullptr, nullptr, nullptr, 0},
+ {"v13", nullptr, 16, FPU_OFFSET(13), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v13}, nullptr, nullptr, nullptr, 0},
+ {"v14", nullptr, 16, FPU_OFFSET(14), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v14}, nullptr, nullptr, nullptr, 0},
+ {"v15", nullptr, 16, FPU_OFFSET(15), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v15}, nullptr, nullptr, nullptr, 0},
+ {"v16", nullptr, 16, FPU_OFFSET(16), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v16}, nullptr, nullptr, nullptr, 0},
+ {"v17", nullptr, 16, FPU_OFFSET(17), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v17}, nullptr, nullptr, nullptr, 0},
+ {"v18", nullptr, 16, FPU_OFFSET(18), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v18}, nullptr, nullptr, nullptr, 0},
+ {"v19", nullptr, 16, FPU_OFFSET(19), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v19}, nullptr, nullptr, nullptr, 0},
+ {"v20", nullptr, 16, FPU_OFFSET(20), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v20}, nullptr, nullptr, nullptr, 0},
+ {"v21", nullptr, 16, FPU_OFFSET(21), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v21}, nullptr, nullptr, nullptr, 0},
+ {"v22", nullptr, 16, FPU_OFFSET(22), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v22}, nullptr, nullptr, nullptr, 0},
+ {"v23", nullptr, 16, FPU_OFFSET(23), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v23}, nullptr, nullptr, nullptr, 0},
+ {"v24", nullptr, 16, FPU_OFFSET(24), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v24}, nullptr, nullptr, nullptr, 0},
+ {"v25", nullptr, 16, FPU_OFFSET(25), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v25}, nullptr, nullptr, nullptr, 0},
+ {"v26", nullptr, 16, FPU_OFFSET(26), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v26}, nullptr, nullptr, nullptr, 0},
+ {"v27", nullptr, 16, FPU_OFFSET(27), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v27}, nullptr, nullptr, nullptr, 0},
+ {"v28", nullptr, 16, FPU_OFFSET(28), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v28}, nullptr, nullptr, nullptr, 0},
+ {"v29", nullptr, 16, FPU_OFFSET(29), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v29}, nullptr, nullptr, nullptr, 0},
+ {"v30", nullptr, 16, FPU_OFFSET(30), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v30}, nullptr, nullptr, nullptr, 0},
+ {"v31", nullptr, 16, FPU_OFFSET(31), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v31}, nullptr, nullptr, nullptr, 0},
+
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATES DYNEXPR SZ
+ // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
+ {"s0", nullptr, 4, FPU_OFFSET(0) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0}, g_contained_v0, g_s0_invalidates, nullptr, 0},
+ {"s1", nullptr, 4, FPU_OFFSET(1) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1}, g_contained_v1, g_s1_invalidates, nullptr, 0},
+ {"s2", nullptr, 4, FPU_OFFSET(2) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2}, g_contained_v2, g_s2_invalidates, nullptr, 0},
+ {"s3", nullptr, 4, FPU_OFFSET(3) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3}, g_contained_v3, g_s3_invalidates, nullptr, 0},
+ {"s4", nullptr, 4, FPU_OFFSET(4) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4}, g_contained_v4, g_s4_invalidates, nullptr, 0},
+ {"s5", nullptr, 4, FPU_OFFSET(5) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5}, g_contained_v5, g_s5_invalidates, nullptr, 0},
+ {"s6", nullptr, 4, FPU_OFFSET(6) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6}, g_contained_v6, g_s6_invalidates, nullptr, 0},
+ {"s7", nullptr, 4, FPU_OFFSET(7) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7}, g_contained_v7, g_s7_invalidates, nullptr, 0},
+ {"s8", nullptr, 4, FPU_OFFSET(8) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8}, g_contained_v8, g_s8_invalidates, nullptr, 0},
+ {"s9", nullptr, 4, FPU_OFFSET(9) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9}, g_contained_v9, g_s9_invalidates, nullptr, 0},
+ {"s10", nullptr, 4, FPU_OFFSET(10) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10}, g_contained_v10, g_s10_invalidates, nullptr, 0},
+ {"s11", nullptr, 4, FPU_OFFSET(11) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11}, g_contained_v11, g_s11_invalidates, nullptr, 0},
+ {"s12", nullptr, 4, FPU_OFFSET(12) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12}, g_contained_v12, g_s12_invalidates, nullptr, 0},
+ {"s13", nullptr, 4, FPU_OFFSET(13) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13}, g_contained_v13, g_s13_invalidates, nullptr, 0},
+ {"s14", nullptr, 4, FPU_OFFSET(14) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14}, g_contained_v14, g_s14_invalidates, nullptr, 0},
+ {"s15", nullptr, 4, FPU_OFFSET(15) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15}, g_contained_v15, g_s15_invalidates, nullptr, 0},
+ {"s16", nullptr, 4, FPU_OFFSET(16) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16}, g_contained_v16, g_s16_invalidates, nullptr, 0},
+ {"s17", nullptr, 4, FPU_OFFSET(17) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17}, g_contained_v17, g_s17_invalidates, nullptr, 0},
+ {"s18", nullptr, 4, FPU_OFFSET(18) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18}, g_contained_v18, g_s18_invalidates, nullptr, 0},
+ {"s19", nullptr, 4, FPU_OFFSET(19) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19}, g_contained_v19, g_s19_invalidates, nullptr, 0},
+ {"s20", nullptr, 4, FPU_OFFSET(20) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20}, g_contained_v20, g_s20_invalidates, nullptr, 0},
+ {"s21", nullptr, 4, FPU_OFFSET(21) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21}, g_contained_v21, g_s21_invalidates, nullptr, 0},
+ {"s22", nullptr, 4, FPU_OFFSET(22) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22}, g_contained_v22, g_s22_invalidates, nullptr, 0},
+ {"s23", nullptr, 4, FPU_OFFSET(23) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23}, g_contained_v23, g_s23_invalidates, nullptr, 0},
+ {"s24", nullptr, 4, FPU_OFFSET(24) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24}, g_contained_v24, g_s24_invalidates, nullptr, 0},
+ {"s25", nullptr, 4, FPU_OFFSET(25) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25}, g_contained_v25, g_s25_invalidates, nullptr, 0},
+ {"s26", nullptr, 4, FPU_OFFSET(26) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26}, g_contained_v26, g_s26_invalidates, nullptr, 0},
+ {"s27", nullptr, 4, FPU_OFFSET(27) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27}, g_contained_v27, g_s27_invalidates, nullptr, 0},
+ {"s28", nullptr, 4, FPU_OFFSET(28) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28}, g_contained_v28, g_s28_invalidates, nullptr, 0},
+ {"s29", nullptr, 4, FPU_OFFSET(29) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29}, g_contained_v29, g_s29_invalidates, nullptr, 0},
+ {"s30", nullptr, 4, FPU_OFFSET(30) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30}, g_contained_v30, g_s30_invalidates, nullptr, 0},
+ {"s31", nullptr, 4, FPU_OFFSET(31) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31}, g_contained_v31, g_s31_invalidates, nullptr, 0},
+
+ {"d0", nullptr, 8, FPU_OFFSET(0) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d0}, g_contained_v0, g_d0_invalidates, nullptr, 0},
+ {"d1", nullptr, 8, FPU_OFFSET(1) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d1}, g_contained_v1, g_d1_invalidates, nullptr, 0},
+ {"d2", nullptr, 8, FPU_OFFSET(2) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d2}, g_contained_v2, g_d2_invalidates, nullptr, 0},
+ {"d3", nullptr, 8, FPU_OFFSET(3) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d3}, g_contained_v3, g_d3_invalidates, nullptr, 0},
+ {"d4", nullptr, 8, FPU_OFFSET(4) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d4}, g_contained_v4, g_d4_invalidates, nullptr, 0},
+ {"d5", nullptr, 8, FPU_OFFSET(5) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d5}, g_contained_v5, g_d5_invalidates, nullptr, 0},
+ {"d6", nullptr, 8, FPU_OFFSET(6) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d6}, g_contained_v6, g_d6_invalidates, nullptr, 0},
+ {"d7", nullptr, 8, FPU_OFFSET(7) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d7}, g_contained_v7, g_d7_invalidates, nullptr, 0},
+ {"d8", nullptr, 8, FPU_OFFSET(8) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d8}, g_contained_v8, g_d8_invalidates, nullptr, 0},
+ {"d9", nullptr, 8, FPU_OFFSET(9) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d9}, g_contained_v9, g_d9_invalidates, nullptr, 0},
+ {"d10", nullptr, 8, FPU_OFFSET(10) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d10}, g_contained_v10, g_d10_invalidates, nullptr, 0},
+ {"d11", nullptr, 8, FPU_OFFSET(11) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d11}, g_contained_v11, g_d11_invalidates, nullptr, 0},
+ {"d12", nullptr, 8, FPU_OFFSET(12) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d12}, g_contained_v12, g_d12_invalidates, nullptr, 0},
+ {"d13", nullptr, 8, FPU_OFFSET(13) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d13}, g_contained_v13, g_d13_invalidates, nullptr, 0},
+ {"d14", nullptr, 8, FPU_OFFSET(14) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d14}, g_contained_v14, g_d14_invalidates, nullptr, 0},
+ {"d15", nullptr, 8, FPU_OFFSET(15) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d15}, g_contained_v15, g_d15_invalidates, nullptr, 0},
+ {"d16", nullptr, 8, FPU_OFFSET(16) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d16}, g_contained_v16, g_d16_invalidates, nullptr, 0},
+ {"d17", nullptr, 8, FPU_OFFSET(17) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d17}, g_contained_v17, g_d17_invalidates, nullptr, 0},
+ {"d18", nullptr, 8, FPU_OFFSET(18) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d18}, g_contained_v18, g_d18_invalidates, nullptr, 0},
+ {"d19", nullptr, 8, FPU_OFFSET(19) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d19}, g_contained_v19, g_d19_invalidates, nullptr, 0},
+ {"d20", nullptr, 8, FPU_OFFSET(20) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d20}, g_contained_v20, g_d20_invalidates, nullptr, 0},
+ {"d21", nullptr, 8, FPU_OFFSET(21) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d21}, g_contained_v21, g_d21_invalidates, nullptr, 0},
+ {"d22", nullptr, 8, FPU_OFFSET(22) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d22}, g_contained_v22, g_d22_invalidates, nullptr, 0},
+ {"d23", nullptr, 8, FPU_OFFSET(23) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d23}, g_contained_v23, g_d23_invalidates, nullptr, 0},
+ {"d24", nullptr, 8, FPU_OFFSET(24) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d24}, g_contained_v24, g_d24_invalidates, nullptr, 0},
+ {"d25", nullptr, 8, FPU_OFFSET(25) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d25}, g_contained_v25, g_d25_invalidates, nullptr, 0},
+ {"d26", nullptr, 8, FPU_OFFSET(26) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d26}, g_contained_v26, g_d26_invalidates, nullptr, 0},
+ {"d27", nullptr, 8, FPU_OFFSET(27) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d27}, g_contained_v27, g_d27_invalidates, nullptr, 0},
+ {"d28", nullptr, 8, FPU_OFFSET(28) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d28}, g_contained_v28, g_d28_invalidates, nullptr, 0},
+ {"d29", nullptr, 8, FPU_OFFSET(29) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d29}, g_contained_v29, g_d29_invalidates, nullptr, 0},
+ {"d30", nullptr, 8, FPU_OFFSET(30) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d30}, g_contained_v30, g_d30_invalidates, nullptr, 0},
+ {"d31", nullptr, 8, FPU_OFFSET(31) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d31}, g_contained_v31, g_d31_invalidates, nullptr, 0},
+
+ {"fpsr", nullptr, 4, FPU_OFFSET_NAME(fpsr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr}, nullptr, nullptr, nullptr, 0},
+ {"fpcr", nullptr, 4, FPU_OFFSET_NAME(fpcr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr}, nullptr, nullptr, nullptr, 0},
+
+ {"far", nullptr, 8, EXC_OFFSET_NAME(far), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, nullptr, 0},
+ {"esr", nullptr, 4, EXC_OFFSET_NAME(esr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr}, nullptr, nullptr, nullptr, 0},
+ {"exception", nullptr, 4, EXC_OFFSET_NAME(exception), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, nullptr, 0},
+
+ {DEFINE_DBG(bvr, 0)},
+ {DEFINE_DBG(bvr, 1)},
+ {DEFINE_DBG(bvr, 2)},
+ {DEFINE_DBG(bvr, 3)},
+ {DEFINE_DBG(bvr, 4)},
+ {DEFINE_DBG(bvr, 5)},
+ {DEFINE_DBG(bvr, 6)},
+ {DEFINE_DBG(bvr, 7)},
+ {DEFINE_DBG(bvr, 8)},
+ {DEFINE_DBG(bvr, 9)},
+ {DEFINE_DBG(bvr, 10)},
+ {DEFINE_DBG(bvr, 11)},
+ {DEFINE_DBG(bvr, 12)},
+ {DEFINE_DBG(bvr, 13)},
+ {DEFINE_DBG(bvr, 14)},
+ {DEFINE_DBG(bvr, 15)},
+
+ {DEFINE_DBG(bcr, 0)},
+ {DEFINE_DBG(bcr, 1)},
+ {DEFINE_DBG(bcr, 2)},
+ {DEFINE_DBG(bcr, 3)},
+ {DEFINE_DBG(bcr, 4)},
+ {DEFINE_DBG(bcr, 5)},
+ {DEFINE_DBG(bcr, 6)},
+ {DEFINE_DBG(bcr, 7)},
+ {DEFINE_DBG(bcr, 8)},
+ {DEFINE_DBG(bcr, 9)},
+ {DEFINE_DBG(bcr, 10)},
+ {DEFINE_DBG(bcr, 11)},
+ {DEFINE_DBG(bcr, 12)},
+ {DEFINE_DBG(bcr, 13)},
+ {DEFINE_DBG(bcr, 14)},
+ {DEFINE_DBG(bcr, 15)},
+
+ {DEFINE_DBG(wvr, 0)},
+ {DEFINE_DBG(wvr, 1)},
+ {DEFINE_DBG(wvr, 2)},
+ {DEFINE_DBG(wvr, 3)},
+ {DEFINE_DBG(wvr, 4)},
+ {DEFINE_DBG(wvr, 5)},
+ {DEFINE_DBG(wvr, 6)},
+ {DEFINE_DBG(wvr, 7)},
+ {DEFINE_DBG(wvr, 8)},
+ {DEFINE_DBG(wvr, 9)},
+ {DEFINE_DBG(wvr, 10)},
+ {DEFINE_DBG(wvr, 11)},
+ {DEFINE_DBG(wvr, 12)},
+ {DEFINE_DBG(wvr, 13)},
+ {DEFINE_DBG(wvr, 14)},
+ {DEFINE_DBG(wvr, 15)},
+
+ {DEFINE_DBG(wcr, 0)},
+ {DEFINE_DBG(wcr, 1)},
+ {DEFINE_DBG(wcr, 2)},
+ {DEFINE_DBG(wcr, 3)},
+ {DEFINE_DBG(wcr, 4)},
+ {DEFINE_DBG(wcr, 5)},
+ {DEFINE_DBG(wcr, 6)},
+ {DEFINE_DBG(wcr, 7)},
+ {DEFINE_DBG(wcr, 8)},
+ {DEFINE_DBG(wcr, 9)},
+ {DEFINE_DBG(wcr, 10)},
+ {DEFINE_DBG(wcr, 11)},
+ {DEFINE_DBG(wcr, 12)},
+ {DEFINE_DBG(wcr, 13)},
+ {DEFINE_DBG(wcr, 14)},
+ {DEFINE_DBG(wcr, 15)}
+ // clang-format on
};
#endif // DECLARE_REGISTER_INFOS_ARM64_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_i386.h b/source/Plugins/Process/Utility/RegisterInfos_i386.h
index a94b790b680f..8597d0c39dc4 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -7,41 +7,47 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-#include <stddef.h>
-
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/Support/Compiler.h"
+#include <cstddef>
+#include <cstdint>
// Project includes
#ifdef DECLARE_REGISTER_INFOS_I386_STRUCT
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR_i386, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR_i386, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplI386.cpp from debugserver
-#define YMM_OFFSET(reg_index) \
+#define YMM_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \
+ (32 * reg_index))
+
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+
+#define BNDC_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, i387) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + \
- sizeof(XMMReg) + (32 * reg_index))
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
// Number of bytes needed to represent a FPR.
#if !defined(FPR_SIZE)
-#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg)
#endif
// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes)
// Number of bytes needed to represent an XMM register.
#define XMM_SIZE sizeof(XMMReg)
@@ -49,158 +55,235 @@
// Number of bytes needed to represent a YMM register.
#define YMM_SIZE sizeof(YMMReg)
+// Number of bytes needed to represent MPX registers.
+#define BNDR_SIZE sizeof(MPXReg)
+#define BNDC_SIZE sizeof(MPXCsr)
+
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, NULL, NULL, NULL, 0}
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR *)nullptr)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##reg##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
-#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
- { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_i386 }, NULL, NULL, NULL, 0}
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##name##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
-#define DEFINE_FP_ST(reg, i) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_FP_MM(reg, i) \
- { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingUint, eFormatHex, \
- { ehframe_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mm##i##_i386 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386}, \
- NULL, NULL, NULL, 0}
-
-// I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then differentiate based on register size.
-#define DEFINE_YMM(reg, i) \
- { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_DR(reg, i) \
- { #reg#i, NULL, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0}
-
-#define DEFINE_GPR_PSEUDO_16(reg16, reg32) \
- { #reg16, NULL, 2, GPR_OFFSET(reg32), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \
- { #reg8, NULL, 1, GPR_OFFSET(reg32)+1, eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \
- { #reg8, NULL, 1, GPR_OFFSET(reg32), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32, NULL, 0}
-
-static RegisterInfo
-g_register_infos_i386[] =
-{
+#define DEFINE_FP_ST(reg, i) \
+ { \
+ #reg #i, nullptr, FP_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_MM(reg, i) \
+ { \
+ #reg #i, nullptr, sizeof(uint64_t), \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingUint, eFormatHex, \
+ {ehframe_mm##i##_i386, dwarf_mm##i##_i386, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_mm##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_XMM(reg, i) \
+ { \
+ #reg #i, nullptr, XMM_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+// I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then
+// differentiate based on register size.
+#define DEFINE_YMM(reg, i) \
+ { \
+ #reg #i, nullptr, YMM_SIZE, \
+ LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDR(reg, i) \
+ { \
+ #reg #i, nullptr, BNDR_SIZE, \
+ LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \
+ {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDC(name, i) \
+ { \
+ #name, nullptr, BNDC_SIZE, \
+ LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \
+ eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_DR(reg, i) \
+ { \
+ #reg #i, nullptr, DR_SIZE, \
+ DR_OFFSET(i), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_16(reg16, reg32) \
+ { \
+ #reg16, nullptr, 2, \
+ GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg16##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg32, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg32) + 1, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg32, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg32, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \
+ }
+
+static RegisterInfo g_register_infos_i386[] = {
// General purpose registers.
- DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-
- DEFINE_GPR_PSEUDO_16(ax, eax),
- DEFINE_GPR_PSEUDO_16(bx, ebx),
- DEFINE_GPR_PSEUDO_16(cx, ecx),
- DEFINE_GPR_PSEUDO_16(dx, edx),
- DEFINE_GPR_PSEUDO_16(di, edi),
- DEFINE_GPR_PSEUDO_16(si, esi),
- DEFINE_GPR_PSEUDO_16(bp, ebp),
- DEFINE_GPR_PSEUDO_16(sp, esp),
- DEFINE_GPR_PSEUDO_8H(ah, eax),
- DEFINE_GPR_PSEUDO_8H(bh, ebx),
- DEFINE_GPR_PSEUDO_8H(ch, ecx),
- DEFINE_GPR_PSEUDO_8H(dh, edx),
- DEFINE_GPR_PSEUDO_8L(al, eax),
- DEFINE_GPR_PSEUDO_8L(bl, ebx),
- DEFINE_GPR_PSEUDO_8L(cl, ecx),
- DEFINE_GPR_PSEUDO_8L(dl, edx),
+ DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386,
+ LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386,
+ LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386,
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386,
+ LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ DEFINE_GPR_PSEUDO_16(ax, eax), DEFINE_GPR_PSEUDO_16(bx, ebx),
+ DEFINE_GPR_PSEUDO_16(cx, ecx), DEFINE_GPR_PSEUDO_16(dx, edx),
+ DEFINE_GPR_PSEUDO_16(di, edi), DEFINE_GPR_PSEUDO_16(si, esi),
+ DEFINE_GPR_PSEUDO_16(bp, ebp), DEFINE_GPR_PSEUDO_16(sp, esp),
+ DEFINE_GPR_PSEUDO_8H(ah, eax), DEFINE_GPR_PSEUDO_8H(bh, ebx),
+ DEFINE_GPR_PSEUDO_8H(ch, ecx), DEFINE_GPR_PSEUDO_8H(dh, edx),
+ DEFINE_GPR_PSEUDO_8L(al, eax), DEFINE_GPR_PSEUDO_8L(bl, ebx),
+ DEFINE_GPR_PSEUDO_8L(cl, ecx), DEFINE_GPR_PSEUDO_8L(dl, edx),
// i387 Floating point registers.
- DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
// FP registers.
- DEFINE_FP_ST(st, 0),
- DEFINE_FP_ST(st, 1),
- DEFINE_FP_ST(st, 2),
- DEFINE_FP_ST(st, 3),
- DEFINE_FP_ST(st, 4),
- DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6),
- DEFINE_FP_ST(st, 7),
- DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1),
- DEFINE_FP_MM(mm, 2),
- DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4),
- DEFINE_FP_MM(mm, 5),
- DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
DEFINE_FP_MM(mm, 7),
// XMM registers
- DEFINE_XMM(xmm, 0),
- DEFINE_XMM(xmm, 1),
- DEFINE_XMM(xmm, 2),
- DEFINE_XMM(xmm, 3),
- DEFINE_XMM(xmm, 4),
- DEFINE_XMM(xmm, 5),
- DEFINE_XMM(xmm, 6),
- DEFINE_XMM(xmm, 7),
+ DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
+ DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5),
+ DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7),
// Copy of YMM registers assembled from xmm and ymmh
- DEFINE_YMM(ymm, 0),
- DEFINE_YMM(ymm, 1),
- DEFINE_YMM(ymm, 2),
- DEFINE_YMM(ymm, 3),
- DEFINE_YMM(ymm, 4),
- DEFINE_YMM(ymm, 5),
- DEFINE_YMM(ymm, 6),
- DEFINE_YMM(ymm, 7),
+ DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7),
+
+ // MPX registers
+ DEFINE_BNDR(bnd, 0),
+ DEFINE_BNDR(bnd, 1),
+ DEFINE_BNDR(bnd, 2),
+ DEFINE_BNDR(bnd, 3),
+
+ DEFINE_BNDC(bndcfgu, 0),
+ DEFINE_BNDC(bndstatus, 1),
// Debug registers for lldb internal use
- DEFINE_DR(dr, 0),
- DEFINE_DR(dr, 1),
- DEFINE_DR(dr, 2),
- DEFINE_DR(dr, 3),
- DEFINE_DR(dr, 4),
- DEFINE_DR(dr, 5),
- DEFINE_DR(dr, 6),
- DEFINE_DR(dr, 7)
-};
-
-static_assert((sizeof(g_register_infos_i386) / sizeof(g_register_infos_i386[0])) == k_num_registers_i386,
- "g_register_infos_x86_64 has wrong number of register infos");
+ DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3),
+ DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)};
+
+static_assert((sizeof(g_register_infos_i386) /
+ sizeof(g_register_infos_i386[0])) == k_num_registers_i386,
+ "g_register_infos_x86_64 has wrong number of register infos");
#undef GPR_OFFSET
#undef FPR_OFFSET
@@ -214,6 +297,8 @@ static_assert((sizeof(g_register_infos_i386) / sizeof(g_register_infos_i386[0]))
#undef DEFINE_FP
#undef DEFINE_XMM
#undef DEFINE_YMM
+#undef DEFINE_BNDR
+#undef DEFINE_BNDC
#undef DEFINE_DR
#undef DEFINE_GPR_PSEUDO_16
#undef DEFINE_GPR_PSEUDO_8H
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips.h b/source/Plugins/Process/Utility/RegisterInfos_mips.h
index 81294e7b0d97..b116b99b3f81 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -12,27 +12,27 @@
// C++ Includes
// Other libraries and framework includes
-#include "llvm/Support/Compiler.h"
#include "lldb/Core/dwarf.h"
+#include "llvm/Support/Compiler.h"
// Project includes
#ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, gpr) + \
- LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
+#define GPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, gpr) + \
+ LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
// Computes the offset of the given MSA in the extended data area.
-#define MSA_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, msa) + \
- LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
+#define MSA_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, msa) + \
+ LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
// Note that the size and offset will be updated by platform-specific classes.
#define DEFINE_GPR(reg, alt, kind1, kind2, kind3) \
@@ -44,11 +44,10 @@
NULL, NULL, NULL, 0 \
}
-const uint8_t dwarf_opcode_mips [] = {
- llvm::dwarf::DW_OP_regx, dwarf_sr_mips, llvm::dwarf::DW_OP_lit1,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr
- };
+const uint8_t dwarf_opcode_mips[] = {
+ llvm::dwarf::DW_OP_regx, dwarf_sr_mips, llvm::dwarf::DW_OP_lit1,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr};
#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \
{ \
@@ -69,13 +68,23 @@ const uint8_t dwarf_opcode_mips [] = {
NULL, NULL, NULL, 0 \
}
-#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector, \
- eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL, 0}
+#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips }, \
+ NULL, NULL, NULL, 0 \
+ }
-#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL, 0}
+#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips }, \
+ NULL, NULL, NULL, 0 \
+ }
// RegisterKind: EH_Frame, DWARF, Generic, Procss Plugin, LLDB
@@ -283,11 +292,11 @@ static RegisterInfo g_register_infos_mips[] = {
DEFINE_MSA_INFO(fir, nullptr, dwarf_fir_mips, dwarf_fir_mips,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA_INFO(config5, nullptr, dwarf_config5_mips, dwarf_config5_mips,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM)
-};
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM)};
-static_assert((sizeof(g_register_infos_mips) / sizeof(g_register_infos_mips[0])) == k_num_registers_mips,
- "g_register_infos_mips has wrong number of register infos");
+static_assert((sizeof(g_register_infos_mips) /
+ sizeof(g_register_infos_mips[0])) == k_num_registers_mips,
+ "g_register_infos_mips has wrong number of register infos");
#undef GPR_OFFSET
#undef FPR_OFFSET
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
index 5e9c503ca880..3c3912fa6978 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -12,8 +12,8 @@
// C++ Includes
// Other libraries and framework includes
-#include "llvm/Support/Compiler.h"
#include "lldb/Core/dwarf.h"
+#include "llvm/Support/Compiler.h"
// Project includes
@@ -21,23 +21,22 @@
// Computes the offset of the given GPR in the user data area.
#ifdef LINUX_MIPS64
- #define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, gpr) + \
- LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
+#define GPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, gpr) + \
+ LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
#else
- #define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname))
#endif
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
// Computes the offset of the given MSA in the extended data area.
-#define MSA_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, msa) + \
- LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
+#define MSA_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, msa) + \
+ LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
@@ -52,9 +51,14 @@
NULL, NULL, NULL, 0 \
}
#else
- #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR_freebsd_mips*)0)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL, 0}
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR_freebsd_mips *) 0)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ gpr_##reg##_mips64 }, \
+ NULL, NULL, NULL, 0 \
+ }
#endif
#define DEFINE_GPR_INFO(reg, alt, kind1, kind2, kind3) \
@@ -66,11 +70,10 @@
NULL, NULL, NULL, 0 \
}
-const uint8_t dwarf_opcode_mips64 [] = {
- llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr
- };
+const uint8_t dwarf_opcode_mips64[] = {
+ llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr};
#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \
{ \
@@ -91,60 +94,108 @@ const uint8_t dwarf_opcode_mips64 [] = {
NULL, NULL, NULL, 0 \
}
+#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips64 }, \
+ NULL, NULL, NULL, 0 \
+ }
-#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector, \
- eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL, 0}
-
-#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL, 0}
+#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips64 }, \
+ NULL, NULL, NULL, 0 \
+ }
-static RegisterInfo
-g_register_infos_mips64[] =
-{
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
+static RegisterInfo g_register_infos_mips64[] = {
+// General purpose registers. EH_Frame, DWARF,
+// Generic, Process Plugin
#ifndef LINUX_MIPS64
- DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
- DEFINE_GPR(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ic, nullptr, dwarf_ic_mips64, dwarf_ic_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64,
+ LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64,
+ LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64,
+ LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64,
+ LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64,
+ LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64,
+ LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64,
+ LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64,
+ LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64,
+ LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64,
+ LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64,
+ LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64,
+ LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64,
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ic, nullptr, dwarf_ic_mips64, dwarf_ic_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
#else
DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
LLDB_INVALID_REGNUM),
@@ -372,8 +423,9 @@ g_register_infos_mips64[] =
#endif
};
-static_assert((sizeof(g_register_infos_mips64) / sizeof(g_register_infos_mips64[0])) == k_num_registers_mips64,
- "g_register_infos_mips64 has wrong number of register infos");
+static_assert((sizeof(g_register_infos_mips64) /
+ sizeof(g_register_infos_mips64[0])) == k_num_registers_mips64,
+ "g_register_infos_mips64 has wrong number of register infos");
#undef DEFINE_GPR
#undef DEFINE_GPR_INFO
diff --git a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 927c73a5551d..c0d47f0d991f 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -10,170 +10,216 @@
#include <stddef.h>
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (offsetof(GPR, regname))
-#define FPR_OFFSET(regname) \
- (offsetof(FPR, regname))
-#define VMX_OFFSET(regname) \
- (offsetof(VMX, regname))
-#define GPR_SIZE(regname) \
- (sizeof(((GPR*)NULL)->regname))
+#define GPR_OFFSET(regname) (offsetof(GPR, regname))
+#define FPR_OFFSET(regname) (offsetof(FPR, regname))
+#define VMX_OFFSET(regname) (offsetof(VMX, regname))
+#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
#ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, lldb_kind) \
- { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, lldb_kind, LLDB_INVALID_REGNUM, gpr_##reg##_powerpc }, NULL, NULL, NULL, 0}
-#define DEFINE_FPR(reg, lldb_kind) \
- { #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
- eFormatFloat, { dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, lldb_kind, LLDB_INVALID_REGNUM, fpr_##reg##_powerpc }, NULL, NULL, NULL, 0}
-#define DEFINE_VMX(reg, lldb_kind) \
- { #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, \
- eFormatVectorOfUInt32, { dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, lldb_kind, LLDB_INVALID_REGNUM, vmx_##reg##_powerpc }, NULL, NULL, NULL, 0}
+#define DEFINE_GPR(reg, alt, lldb_kind) \
+ { \
+ #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {dwarf_##reg##_powerpc, \
+ dwarf_##reg##_powerpc, lldb_kind, \
+ LLDB_INVALID_REGNUM, \
+ gpr_##reg##_powerpc }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_FPR(reg, lldb_kind) \
+ { \
+ #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \
+ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \
+ lldb_kind, LLDB_INVALID_REGNUM, \
+ fpr_##reg##_powerpc }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_VMX(reg, lldb_kind) \
+ { \
+ #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt32, \
+ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \
+ lldb_kind, LLDB_INVALID_REGNUM, \
+ vmx_##reg##_powerpc }, \
+ NULL, NULL, NULL, 0 \
+ }
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
-#define POWERPC_REGS \
- DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
- DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r3, "arg1",LLDB_REGNUM_GENERIC_ARG1), \
- DEFINE_GPR(r4, "arg2",LLDB_REGNUM_GENERIC_ARG2), \
- DEFINE_GPR(r5, "arg3",LLDB_REGNUM_GENERIC_ARG3), \
- DEFINE_GPR(r6, "arg4",LLDB_REGNUM_GENERIC_ARG4), \
- DEFINE_GPR(r7, "arg5",LLDB_REGNUM_GENERIC_ARG5), \
- DEFINE_GPR(r8, "arg6",LLDB_REGNUM_GENERIC_ARG6), \
- DEFINE_GPR(r9, "arg7",LLDB_REGNUM_GENERIC_ARG7), \
- DEFINE_GPR(r10, "arg8",LLDB_REGNUM_GENERIC_ARG8), \
- DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
- DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
- DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \
- DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \
- DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
- DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f3, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f4, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f5, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f6, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f7, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f8, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f9, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f10, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f11, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f12, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f13, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f14, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f15, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f16, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f17, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f18, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f19, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f20, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f21, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f22, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f23, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f24, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f25, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f26, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f27, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f28, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
- { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { dwarf_fpscr_powerpc, dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpr_fpscr_powerpc }, NULL, NULL }, \
- DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \
- { "vrsave", NULL, 4, VMX_OFFSET(vrsave), eEncodingUint, eFormatHex, { dwarf_vrsave_powerpc, dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vrsave_powerpc }, NULL, NULL, NULL, 0}, \
- { "vscr", NULL, 4, VMX_OFFSET(vscr), eEncodingUint, eFormatHex, { dwarf_vscr_powerpc, dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_powerpc }, NULL, NULL, NULL, 0},
+// General purpose registers. EH_Frame, DWARF,
+// Generic, Process Plugin
+#define POWERPC_REGS \
+ DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \
+ , DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
+ DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \
+ DEFINE_GPR(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \
+ DEFINE_GPR(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \
+ DEFINE_GPR(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \
+ DEFINE_GPR(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \
+ DEFINE_GPR(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \
+ DEFINE_GPR(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \
+ DEFINE_GPR(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \
+ DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
+ DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
+ DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
+ DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f3, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f4, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f5, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f6, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f7, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f8, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f9, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f10, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f11, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f12, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f13, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f14, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f15, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f16, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f17, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f18, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f19, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f20, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f21, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f22, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f23, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f24, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f25, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f26, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f27, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f28, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
+ {"fpscr", \
+ NULL, \
+ 8, \
+ FPR_OFFSET(fpscr), \
+ eEncodingUint, \
+ eFormatHex, \
+ {dwarf_fpscr_powerpc, dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpr_fpscr_powerpc}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \
+ {"vrsave", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vrsave), \
+ eEncodingUint, \
+ eFormatHex, \
+ {dwarf_vrsave_powerpc, dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, vmx_vrsave_powerpc}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ {"vscr", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vscr), \
+ eEncodingUint, \
+ eFormatHex, \
+ {dwarf_vscr_powerpc, dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, vmx_vscr_powerpc}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0},
-static RegisterInfo
-g_register_infos_powerpc64[] =
-{
+static RegisterInfo g_register_infos_powerpc64[] = {
#define GPR GPR64
POWERPC_REGS
#undef GPR
};
-static RegisterInfo
-g_register_infos_powerpc32[] =
-{
+static RegisterInfo g_register_infos_powerpc32[] = {
#define GPR GPR32
POWERPC_REGS
#undef GPR
};
-static RegisterInfo
-g_register_infos_powerpc64_32[] =
-{
+static RegisterInfo g_register_infos_powerpc64_32[] = {
#define GPR GPR64
#undef GPR_SIZE
-#define GPR_SIZE(reg) (sizeof(uint32_t))
+#define GPR_SIZE(reg) (sizeof(uint32_t))
#undef GPR_OFFSET
-#define GPR_OFFSET(regname) \
- (offsetof(GPR, regname) + (sizeof(((GPR *)NULL)->regname) - GPR_SIZE(reg)))
+#define GPR_OFFSET(regname) \
+ (offsetof(GPR, regname) + (sizeof(((GPR *)NULL)->regname) - GPR_SIZE(reg)))
POWERPC_REGS
#undef GPR
};
-static_assert((sizeof(g_register_infos_powerpc32) / sizeof(g_register_infos_powerpc32[0])) == k_num_registers_powerpc,
- "g_register_infos_powerpc32 has wrong number of register infos");
-static_assert((sizeof(g_register_infos_powerpc64) / sizeof(g_register_infos_powerpc64[0])) == k_num_registers_powerpc,
- "g_register_infos_powerpc64 has wrong number of register infos");
-static_assert(sizeof(g_register_infos_powerpc64_32) == sizeof(g_register_infos_powerpc64),
- "g_register_infos_powerpc64_32 doesn't match size of g_register_infos_powerpc64");
+static_assert((sizeof(g_register_infos_powerpc32) /
+ sizeof(g_register_infos_powerpc32[0])) ==
+ k_num_registers_powerpc,
+ "g_register_infos_powerpc32 has wrong number of register infos");
+static_assert((sizeof(g_register_infos_powerpc64) /
+ sizeof(g_register_infos_powerpc64[0])) ==
+ k_num_registers_powerpc,
+ "g_register_infos_powerpc64 has wrong number of register infos");
+static_assert(sizeof(g_register_infos_powerpc64_32) ==
+ sizeof(g_register_infos_powerpc64),
+ "g_register_infos_powerpc64_32 doesn't match size of "
+ "g_register_infos_powerpc64");
#undef DEFINE_FPR
#undef DEFINE_GPR
@@ -181,4 +227,3 @@ static_assert(sizeof(g_register_infos_powerpc64_32) == sizeof(g_register_infos_p
#endif // DECLARE_REGISTER_INFOS_POWERPC_STRUCT
#undef GPR_OFFSET
-
diff --git a/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
index 0710174c0a85..0bbf422405ee 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
@@ -27,36 +27,39 @@
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
-#define DEFINE_GPR(name, size, offset, alt, generic) \
- { \
- #name, alt, size, offset, eEncodingUint, eFormatHex, \
- { dwarf_##name##_s390x, dwarf_##name##_s390x, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \
- { \
- #name, alt, size, offset, eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_FPR(name, size, offset) \
- { \
- #name, NULL, size, offset, eEncodingUint, eFormatHex, \
- { dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_FPR_NODWARF(name, size, offset) \
- { \
- #name, NULL, size, offset, eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-static RegisterInfo g_register_infos_s390x[] =
-{
+#define DEFINE_GPR(name, size, offset, alt, generic) \
+ { \
+ #name, alt, size, offset, eEncodingUint, eFormatHex, \
+ {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+#define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \
+ { \
+ #name, alt, size, offset, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+#define DEFINE_FPR(name, size, offset) \
+ { \
+ #name, NULL, size, offset, eEncodingUint, eFormatHex, \
+ {dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+#define DEFINE_FPR_NODWARF(name, size, offset) \
+ { \
+ #name, NULL, size, offset, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+static RegisterInfo g_register_infos_s390x[] = {
// General purpose registers.
DEFINE_GPR(r0, 8, GPR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM),
DEFINE_GPR(r1, 8, GPR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM),
@@ -94,31 +97,25 @@ static RegisterInfo g_register_infos_s390x[] =
DEFINE_GPR(pswa, 8, 8, "pc", LLDB_REGNUM_GENERIC_PC),
// Floating point registers.
- DEFINE_FPR(f0, 8, FPR_OFFSET(0)),
- DEFINE_FPR(f1, 8, FPR_OFFSET(1)),
- DEFINE_FPR(f2, 8, FPR_OFFSET(2)),
- DEFINE_FPR(f3, 8, FPR_OFFSET(3)),
- DEFINE_FPR(f4, 8, FPR_OFFSET(4)),
- DEFINE_FPR(f5, 8, FPR_OFFSET(5)),
- DEFINE_FPR(f6, 8, FPR_OFFSET(6)),
- DEFINE_FPR(f7, 8, FPR_OFFSET(7)),
- DEFINE_FPR(f8, 8, FPR_OFFSET(8)),
- DEFINE_FPR(f9, 8, FPR_OFFSET(9)),
- DEFINE_FPR(f10, 8, FPR_OFFSET(10)),
- DEFINE_FPR(f11, 8, FPR_OFFSET(11)),
- DEFINE_FPR(f12, 8, FPR_OFFSET(12)),
- DEFINE_FPR(f13, 8, FPR_OFFSET(13)),
- DEFINE_FPR(f14, 8, FPR_OFFSET(14)),
- DEFINE_FPR(f15, 8, FPR_OFFSET(15)),
+ DEFINE_FPR(f0, 8, FPR_OFFSET(0)), DEFINE_FPR(f1, 8, FPR_OFFSET(1)),
+ DEFINE_FPR(f2, 8, FPR_OFFSET(2)), DEFINE_FPR(f3, 8, FPR_OFFSET(3)),
+ DEFINE_FPR(f4, 8, FPR_OFFSET(4)), DEFINE_FPR(f5, 8, FPR_OFFSET(5)),
+ DEFINE_FPR(f6, 8, FPR_OFFSET(6)), DEFINE_FPR(f7, 8, FPR_OFFSET(7)),
+ DEFINE_FPR(f8, 8, FPR_OFFSET(8)), DEFINE_FPR(f9, 8, FPR_OFFSET(9)),
+ DEFINE_FPR(f10, 8, FPR_OFFSET(10)), DEFINE_FPR(f11, 8, FPR_OFFSET(11)),
+ DEFINE_FPR(f12, 8, FPR_OFFSET(12)), DEFINE_FPR(f13, 8, FPR_OFFSET(13)),
+ DEFINE_FPR(f14, 8, FPR_OFFSET(14)), DEFINE_FPR(f15, 8, FPR_OFFSET(15)),
DEFINE_FPR_NODWARF(fpc, 4, 0),
// Linux operating-specific info.
- DEFINE_GPR_NODWARF(orig_r2, 8, 16 + 16 * 8 + 16 * 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR_NODWARF(orig_r2, 8, 16 + 16 * 8 + 16 * 4, nullptr,
+ LLDB_INVALID_REGNUM),
DEFINE_GPR_NODWARF(last_break, 8, 0, nullptr, LLDB_INVALID_REGNUM),
DEFINE_GPR_NODWARF(system_call, 4, 0, nullptr, LLDB_INVALID_REGNUM),
};
-static_assert((sizeof(g_register_infos_s390x) / sizeof(g_register_infos_s390x[0])) == k_num_registers_s390x,
+static_assert((sizeof(g_register_infos_s390x) /
+ sizeof(g_register_infos_s390x[0])) == k_num_registers_s390x,
"g_register_infos_s390x has wrong number of register infos");
#undef GPR_OFFSET
diff --git a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index aeb6672ec943..2ba8059911a0 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -7,40 +7,45 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-#include <stddef.h>
-
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/Support/Compiler.h"
+#include <cstddef>
+#include <cstdint>
// Project includes
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(FXSAVE, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplX86_64.cpp from debugserver
-#define YMM_OFFSET(reg_index) \
+#define YMM_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
+
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+
+#define BNDC_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + \
- (32 * reg_index))
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT
// Number of bytes needed to represent a FPR.
-#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg)
// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes)
// Number of bytes needed to represent an XMM register.
#define XMM_SIZE sizeof(XMMReg)
@@ -48,222 +53,260 @@
// Number of bytes needed to represent a YMM register.
#define YMM_SIZE sizeof(YMMReg)
-#define DR_SIZE sizeof(((DBG*)NULL)->dr[0])
+// Number of bytes needed to represent MPX registers.
+#define BNDR_SIZE sizeof(MPXReg)
+#define BNDC_SIZE sizeof(MPXCsr)
+
+#define DR_SIZE sizeof(((DBG *)nullptr)->dr[0])
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, NULL, NULL, NULL, 0}
-
-#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
- { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, NULL, NULL, NULL, 0}
-
-#define DEFINE_FP_ST(reg, i) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_FP_MM(reg, i) \
- { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingUint, eFormatHex, \
- { dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64}, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_YMM(reg, i) \
- { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_DR(reg, i) \
- { #reg#i, NULL, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0}
-
-#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
- { #reg32, NULL, 4, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
- { #reg16, NULL, 2, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64)+1, eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-
-static RegisterInfo
-g_register_infos_x86_64[] =
-{
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-
- DEFINE_GPR_PSEUDO_32(eax, rax),
- DEFINE_GPR_PSEUDO_32(ebx, rbx),
- DEFINE_GPR_PSEUDO_32(ecx, rcx),
- DEFINE_GPR_PSEUDO_32(edx, rdx),
- DEFINE_GPR_PSEUDO_32(edi, rdi),
- DEFINE_GPR_PSEUDO_32(esi, rsi),
- DEFINE_GPR_PSEUDO_32(ebp, rbp),
- DEFINE_GPR_PSEUDO_32(esp, rsp),
- DEFINE_GPR_PSEUDO_32(r8d, r8),
- DEFINE_GPR_PSEUDO_32(r9d, r9),
- DEFINE_GPR_PSEUDO_32(r10d, r10),
- DEFINE_GPR_PSEUDO_32(r11d, r11),
- DEFINE_GPR_PSEUDO_32(r12d, r12),
- DEFINE_GPR_PSEUDO_32(r13d, r13),
- DEFINE_GPR_PSEUDO_32(r14d, r14),
- DEFINE_GPR_PSEUDO_32(r15d, r15),
- DEFINE_GPR_PSEUDO_16(ax, rax),
- DEFINE_GPR_PSEUDO_16(bx, rbx),
- DEFINE_GPR_PSEUDO_16(cx, rcx),
- DEFINE_GPR_PSEUDO_16(dx, rdx),
- DEFINE_GPR_PSEUDO_16(di, rdi),
- DEFINE_GPR_PSEUDO_16(si, rsi),
- DEFINE_GPR_PSEUDO_16(bp, rbp),
- DEFINE_GPR_PSEUDO_16(sp, rsp),
- DEFINE_GPR_PSEUDO_16(r8w, r8),
- DEFINE_GPR_PSEUDO_16(r9w, r9),
- DEFINE_GPR_PSEUDO_16(r10w, r10),
- DEFINE_GPR_PSEUDO_16(r11w, r11),
- DEFINE_GPR_PSEUDO_16(r12w, r12),
- DEFINE_GPR_PSEUDO_16(r13w, r13),
- DEFINE_GPR_PSEUDO_16(r14w, r14),
- DEFINE_GPR_PSEUDO_16(r15w, r15),
- DEFINE_GPR_PSEUDO_8H(ah, rax),
- DEFINE_GPR_PSEUDO_8H(bh, rbx),
- DEFINE_GPR_PSEUDO_8H(ch, rcx),
- DEFINE_GPR_PSEUDO_8H(dh, rdx),
- DEFINE_GPR_PSEUDO_8L(al, rax),
- DEFINE_GPR_PSEUDO_8L(bl, rbx),
- DEFINE_GPR_PSEUDO_8L(cl, rcx),
- DEFINE_GPR_PSEUDO_8L(dl, rdx),
- DEFINE_GPR_PSEUDO_8L(dil, rdi),
- DEFINE_GPR_PSEUDO_8L(sil, rsi),
- DEFINE_GPR_PSEUDO_8L(bpl, rbp),
- DEFINE_GPR_PSEUDO_8L(spl, rsp),
- DEFINE_GPR_PSEUDO_8L(r8l, r8),
- DEFINE_GPR_PSEUDO_8L(r9l, r9),
- DEFINE_GPR_PSEUDO_8L(r10l, r10),
- DEFINE_GPR_PSEUDO_8L(r11l, r11),
- DEFINE_GPR_PSEUDO_8L(r12l, r12),
- DEFINE_GPR_PSEUDO_8L(r13l, r13),
- DEFINE_GPR_PSEUDO_8L(r14l, r14),
- DEFINE_GPR_PSEUDO_8L(r15l, r15),
-
- // i387 Floating point registers. EH_frame, DWARF, Generic, Process Plugin
- DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR *)nullptr)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##reg##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##name##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_ST(reg, i) \
+ { \
+ #reg #i, nullptr, FP_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_MM(reg, i) \
+ { \
+ #reg #i, nullptr, sizeof(uint64_t), \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingUint, eFormatHex, \
+ {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_mm##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_XMM(reg, i) \
+ { \
+ #reg #i, nullptr, XMM_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_YMM(reg, i) \
+ { \
+ #reg #i, nullptr, YMM_SIZE, \
+ LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##h_x86_64, \
+ dwarf_##reg##i##h_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDR(reg, i) \
+ { \
+ #reg #i, nullptr, BNDR_SIZE, \
+ LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \
+ {dwarf_##reg##i##_x86_64, \
+ dwarf_##reg##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDC(name, i) \
+ { \
+ #name, nullptr, BNDC_SIZE, \
+ LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_DR(reg, i) \
+ { \
+ #reg #i, nullptr, DR_SIZE, \
+ DR_OFFSET(i), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
+ { \
+ #reg32, nullptr, 4, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg32##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
+ { \
+ #reg16, nullptr, 2, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg16##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+// clang-format off
+static RegisterInfo g_register_infos_x86_64[] = {
+// General purpose registers EH_Frame DWARF Generic Process Plugin
+// =========================== ================== ================ ========================= ====================
+ DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx),
+ DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx),
+ DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi),
+ DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp),
+ DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9),
+ DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11),
+ DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13),
+ DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15),
+ DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx),
+ DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx),
+ DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi),
+ DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp),
+ DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9),
+ DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11),
+ DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13),
+ DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15),
+ DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx),
+ DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx),
+ DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx),
+ DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx),
+ DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi),
+ DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp),
+ DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9),
+ DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11),
+ DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13),
+ DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15),
+
+// i387 Floating point registers. EH_frame DWARF Generic Process Plugin
+// ====================================== =============== ================== =================== ====================
+ DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
// FP registers.
- DEFINE_FP_ST(st, 0),
- DEFINE_FP_ST(st, 1),
- DEFINE_FP_ST(st, 2),
- DEFINE_FP_ST(st, 3),
- DEFINE_FP_ST(st, 4),
- DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6),
- DEFINE_FP_ST(st, 7),
- DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1),
- DEFINE_FP_MM(mm, 2),
- DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4),
- DEFINE_FP_MM(mm, 5),
- DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
DEFINE_FP_MM(mm, 7),
// XMM registers
- DEFINE_XMM(xmm, 0),
- DEFINE_XMM(xmm, 1),
- DEFINE_XMM(xmm, 2),
- DEFINE_XMM(xmm, 3),
- DEFINE_XMM(xmm, 4),
- DEFINE_XMM(xmm, 5),
- DEFINE_XMM(xmm, 6),
- DEFINE_XMM(xmm, 7),
- DEFINE_XMM(xmm, 8),
- DEFINE_XMM(xmm, 9),
- DEFINE_XMM(xmm, 10),
- DEFINE_XMM(xmm, 11),
- DEFINE_XMM(xmm, 12),
- DEFINE_XMM(xmm, 13),
- DEFINE_XMM(xmm, 14),
+ DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
+ DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5),
+ DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8),
+ DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11),
+ DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14),
DEFINE_XMM(xmm, 15),
// Copy of YMM registers assembled from xmm and ymmh
- DEFINE_YMM(ymm, 0),
- DEFINE_YMM(ymm, 1),
- DEFINE_YMM(ymm, 2),
- DEFINE_YMM(ymm, 3),
- DEFINE_YMM(ymm, 4),
- DEFINE_YMM(ymm, 5),
- DEFINE_YMM(ymm, 6),
- DEFINE_YMM(ymm, 7),
- DEFINE_YMM(ymm, 8),
- DEFINE_YMM(ymm, 9),
- DEFINE_YMM(ymm, 10),
- DEFINE_YMM(ymm, 11),
- DEFINE_YMM(ymm, 12),
- DEFINE_YMM(ymm, 13),
- DEFINE_YMM(ymm, 14),
+ DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8),
+ DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11),
+ DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14),
DEFINE_YMM(ymm, 15),
+ // MPX registers
+ DEFINE_BNDR(bnd, 0),
+ DEFINE_BNDR(bnd, 1),
+ DEFINE_BNDR(bnd, 2),
+ DEFINE_BNDR(bnd, 3),
+
+ DEFINE_BNDC(bndcfgu, 0),
+ DEFINE_BNDC(bndstatus, 1),
+
// Debug registers for lldb internal use
- DEFINE_DR(dr, 0),
- DEFINE_DR(dr, 1),
- DEFINE_DR(dr, 2),
- DEFINE_DR(dr, 3),
- DEFINE_DR(dr, 4),
- DEFINE_DR(dr, 5),
- DEFINE_DR(dr, 6),
- DEFINE_DR(dr, 7)
-};
-
-static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[0])) == k_num_registers_x86_64,
- "g_register_infos_x86_64 has wrong number of register infos");
+ DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3),
+ DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)};
+
+// clang-format on
+
+static_assert((sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0])) == k_num_registers_x86_64,
+ "g_register_infos_x86_64 has wrong number of register infos");
#undef FPR_SIZE
#undef FP_SIZE
@@ -274,6 +317,8 @@ static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[
#undef DEFINE_FP
#undef DEFINE_XMM
#undef DEFINE_YMM
+#undef DEFINE_BNDR
+#undef DEFINE_BNDC
#undef DEFINE_DR
#undef DEFINE_GPR_PSEUDO_32
#undef DEFINE_GPR_PSEUDO_16
@@ -284,130 +329,131 @@ static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[
#ifdef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
-#define UPDATE_GPR_INFO(reg, reg64) \
-do { \
- g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \
-} while(false);
-
-#define UPDATE_GPR_INFO_8H(reg, reg64) \
-do { \
- g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \
-} while(false);
-
-#define UPDATE_FPR_INFO(reg, reg64) \
-do { \
- g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \
-} while(false);
-
-#define UPDATE_FP_INFO(reg, i) \
-do { \
- g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \
-} while(false);
-
-#define UPDATE_XMM_INFO(reg, i) \
-do { \
- g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \
-} while(false);
-
-#define UPDATE_YMM_INFO(reg, i) \
-do { \
- g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \
-} while(false);
-
-#define UPDATE_DR_INFO(reg_index) \
-do { \
- g_register_infos[lldb_dr##reg_index##_i386].byte_offset = DR_OFFSET(reg_index); \
-} while(false);
-
- // Update the register offsets
- UPDATE_GPR_INFO(eax, rax);
- UPDATE_GPR_INFO(ebx, rbx);
- UPDATE_GPR_INFO(ecx, rcx);
- UPDATE_GPR_INFO(edx, rdx);
- UPDATE_GPR_INFO(edi, rdi);
- UPDATE_GPR_INFO(esi, rsi);
- UPDATE_GPR_INFO(ebp, rbp);
- UPDATE_GPR_INFO(esp, rsp);
- UPDATE_GPR_INFO(eip, rip);
- UPDATE_GPR_INFO(eflags, rflags);
- UPDATE_GPR_INFO(cs, cs);
- UPDATE_GPR_INFO(fs, fs);
- UPDATE_GPR_INFO(gs, gs);
- UPDATE_GPR_INFO(ss, ss);
- UPDATE_GPR_INFO(ds, ds);
- UPDATE_GPR_INFO(es, es);
-
- UPDATE_GPR_INFO(ax, rax);
- UPDATE_GPR_INFO(bx, rbx);
- UPDATE_GPR_INFO(cx, rcx);
- UPDATE_GPR_INFO(dx, rdx);
- UPDATE_GPR_INFO(di, rdi);
- UPDATE_GPR_INFO(si, rsi);
- UPDATE_GPR_INFO(bp, rbp);
- UPDATE_GPR_INFO(sp, rsp);
- UPDATE_GPR_INFO_8H(ah, rax);
- UPDATE_GPR_INFO_8H(bh, rbx);
- UPDATE_GPR_INFO_8H(ch, rcx);
- UPDATE_GPR_INFO_8H(dh, rdx);
- UPDATE_GPR_INFO(al, rax);
- UPDATE_GPR_INFO(bl, rbx);
- UPDATE_GPR_INFO(cl, rcx);
- UPDATE_GPR_INFO(dl, rdx);
-
- UPDATE_FPR_INFO(fctrl, fctrl);
- UPDATE_FPR_INFO(fstat, fstat);
- UPDATE_FPR_INFO(ftag, ftag);
- UPDATE_FPR_INFO(fop, fop);
- UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg);
- UPDATE_FPR_INFO(fioff, ptr.i386_.fioff);
- UPDATE_FPR_INFO(fooff, ptr.i386_.fooff);
- UPDATE_FPR_INFO(foseg, ptr.i386_.foseg);
- UPDATE_FPR_INFO(mxcsr, mxcsr);
- UPDATE_FPR_INFO(mxcsrmask, mxcsrmask);
-
- UPDATE_FP_INFO(st, 0);
- UPDATE_FP_INFO(st, 1);
- UPDATE_FP_INFO(st, 2);
- UPDATE_FP_INFO(st, 3);
- UPDATE_FP_INFO(st, 4);
- UPDATE_FP_INFO(st, 5);
- UPDATE_FP_INFO(st, 6);
- UPDATE_FP_INFO(st, 7);
- UPDATE_FP_INFO(mm, 0);
- UPDATE_FP_INFO(mm, 1);
- UPDATE_FP_INFO(mm, 2);
- UPDATE_FP_INFO(mm, 3);
- UPDATE_FP_INFO(mm, 4);
- UPDATE_FP_INFO(mm, 5);
- UPDATE_FP_INFO(mm, 6);
- UPDATE_FP_INFO(mm, 7);
-
- UPDATE_XMM_INFO(xmm, 0);
- UPDATE_XMM_INFO(xmm, 1);
- UPDATE_XMM_INFO(xmm, 2);
- UPDATE_XMM_INFO(xmm, 3);
- UPDATE_XMM_INFO(xmm, 4);
- UPDATE_XMM_INFO(xmm, 5);
- UPDATE_XMM_INFO(xmm, 6);
- UPDATE_XMM_INFO(xmm, 7);
-
- UPDATE_YMM_INFO(ymm, 0);
- UPDATE_YMM_INFO(ymm, 1);
- UPDATE_YMM_INFO(ymm, 2);
- UPDATE_YMM_INFO(ymm, 3);
- UPDATE_YMM_INFO(ymm, 4);
- UPDATE_YMM_INFO(ymm, 5);
- UPDATE_YMM_INFO(ymm, 6);
- UPDATE_YMM_INFO(ymm, 7);
-
- UPDATE_DR_INFO(0);
- UPDATE_DR_INFO(1);
- UPDATE_DR_INFO(2);
- UPDATE_DR_INFO(3);
- UPDATE_DR_INFO(4);
- UPDATE_DR_INFO(5);
- UPDATE_DR_INFO(6);
- UPDATE_DR_INFO(7);
+#define UPDATE_GPR_INFO(reg, reg64) \
+ do { \
+ g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \
+ } while (false);
+
+#define UPDATE_GPR_INFO_8H(reg, reg64) \
+ do { \
+ g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \
+ } while (false);
+
+#define UPDATE_FPR_INFO(reg, reg64) \
+ do { \
+ g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \
+ } while (false);
+
+#define UPDATE_FP_INFO(reg, i) \
+ do { \
+ g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \
+ } while (false);
+
+#define UPDATE_XMM_INFO(reg, i) \
+ do { \
+ g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \
+ } while (false);
+
+#define UPDATE_YMM_INFO(reg, i) \
+ do { \
+ g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \
+ } while (false);
+
+#define UPDATE_DR_INFO(reg_index) \
+ do { \
+ g_register_infos[lldb_dr##reg_index##_i386].byte_offset = \
+ DR_OFFSET(reg_index); \
+ } while (false);
+
+// Update the register offsets
+UPDATE_GPR_INFO(eax, rax);
+UPDATE_GPR_INFO(ebx, rbx);
+UPDATE_GPR_INFO(ecx, rcx);
+UPDATE_GPR_INFO(edx, rdx);
+UPDATE_GPR_INFO(edi, rdi);
+UPDATE_GPR_INFO(esi, rsi);
+UPDATE_GPR_INFO(ebp, rbp);
+UPDATE_GPR_INFO(esp, rsp);
+UPDATE_GPR_INFO(eip, rip);
+UPDATE_GPR_INFO(eflags, rflags);
+UPDATE_GPR_INFO(cs, cs);
+UPDATE_GPR_INFO(fs, fs);
+UPDATE_GPR_INFO(gs, gs);
+UPDATE_GPR_INFO(ss, ss);
+UPDATE_GPR_INFO(ds, ds);
+UPDATE_GPR_INFO(es, es);
+
+UPDATE_GPR_INFO(ax, rax);
+UPDATE_GPR_INFO(bx, rbx);
+UPDATE_GPR_INFO(cx, rcx);
+UPDATE_GPR_INFO(dx, rdx);
+UPDATE_GPR_INFO(di, rdi);
+UPDATE_GPR_INFO(si, rsi);
+UPDATE_GPR_INFO(bp, rbp);
+UPDATE_GPR_INFO(sp, rsp);
+UPDATE_GPR_INFO_8H(ah, rax);
+UPDATE_GPR_INFO_8H(bh, rbx);
+UPDATE_GPR_INFO_8H(ch, rcx);
+UPDATE_GPR_INFO_8H(dh, rdx);
+UPDATE_GPR_INFO(al, rax);
+UPDATE_GPR_INFO(bl, rbx);
+UPDATE_GPR_INFO(cl, rcx);
+UPDATE_GPR_INFO(dl, rdx);
+
+UPDATE_FPR_INFO(fctrl, fctrl);
+UPDATE_FPR_INFO(fstat, fstat);
+UPDATE_FPR_INFO(ftag, ftag);
+UPDATE_FPR_INFO(fop, fop);
+UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg);
+UPDATE_FPR_INFO(fioff, ptr.i386_.fioff);
+UPDATE_FPR_INFO(fooff, ptr.i386_.fooff);
+UPDATE_FPR_INFO(foseg, ptr.i386_.foseg);
+UPDATE_FPR_INFO(mxcsr, mxcsr);
+UPDATE_FPR_INFO(mxcsrmask, mxcsrmask);
+
+UPDATE_FP_INFO(st, 0);
+UPDATE_FP_INFO(st, 1);
+UPDATE_FP_INFO(st, 2);
+UPDATE_FP_INFO(st, 3);
+UPDATE_FP_INFO(st, 4);
+UPDATE_FP_INFO(st, 5);
+UPDATE_FP_INFO(st, 6);
+UPDATE_FP_INFO(st, 7);
+UPDATE_FP_INFO(mm, 0);
+UPDATE_FP_INFO(mm, 1);
+UPDATE_FP_INFO(mm, 2);
+UPDATE_FP_INFO(mm, 3);
+UPDATE_FP_INFO(mm, 4);
+UPDATE_FP_INFO(mm, 5);
+UPDATE_FP_INFO(mm, 6);
+UPDATE_FP_INFO(mm, 7);
+
+UPDATE_XMM_INFO(xmm, 0);
+UPDATE_XMM_INFO(xmm, 1);
+UPDATE_XMM_INFO(xmm, 2);
+UPDATE_XMM_INFO(xmm, 3);
+UPDATE_XMM_INFO(xmm, 4);
+UPDATE_XMM_INFO(xmm, 5);
+UPDATE_XMM_INFO(xmm, 6);
+UPDATE_XMM_INFO(xmm, 7);
+
+UPDATE_YMM_INFO(ymm, 0);
+UPDATE_YMM_INFO(ymm, 1);
+UPDATE_YMM_INFO(ymm, 2);
+UPDATE_YMM_INFO(ymm, 3);
+UPDATE_YMM_INFO(ymm, 4);
+UPDATE_YMM_INFO(ymm, 5);
+UPDATE_YMM_INFO(ymm, 6);
+UPDATE_YMM_INFO(ymm, 7);
+
+UPDATE_DR_INFO(0);
+UPDATE_DR_INFO(1);
+UPDATE_DR_INFO(2);
+UPDATE_DR_INFO(3);
+UPDATE_DR_INFO(4);
+UPDATE_DR_INFO(5);
+UPDATE_DR_INFO(6);
+UPDATE_DR_INFO(7);
#undef UPDATE_GPR_INFO
#undef UPDATE_GPR_INFO_8H
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 7c0487b1d43b..3b29a18dbe20 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -28,508 +28,557 @@
using namespace lldb;
using namespace lldb_private;
-
-const char *
-StopInfoMachException::GetDescription ()
-{
- if (m_description.empty() && m_value != 0)
- {
- ExecutionContext exe_ctx (m_thread_wp.lock());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch;
-
- const char *exc_desc = NULL;
- const char *code_label = "code";
- const char *code_desc = NULL;
- const char *subcode_label = "subcode";
- const char *subcode_desc = NULL;
- switch (m_value)
- {
- case 1: // EXC_BAD_ACCESS
- exc_desc = "EXC_BAD_ACCESS";
- subcode_label = "address";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code)
- {
- case 0xd: code_desc = "EXC_I386_GPFLT"; m_exc_data_count = 1; break;
- }
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code)
- {
- case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
- case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break;
- case 0x102: code_desc = "EXC_PPC_BADSPACE"; break;
- case 0x103: code_desc = "EXC_PPC_UNALIGNED"; break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 2: // EXC_BAD_INSTRUCTION
- exc_desc = "EXC_BAD_INSTRUCTION";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (m_exc_code == 1)
- code_desc = "EXC_I386_INVOP";
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break;
- case 2: code_desc = "EXC_PPC_UNIPL_INST"; break;
- case 3: code_desc = "EXC_PPC_PRIVINST"; break;
- case 4: code_desc = "EXC_PPC_PRIVREG"; break;
- case 5: code_desc = "EXC_PPC_TRACE"; break;
- case 6: code_desc = "EXC_PPC_PERFMON"; break;
- }
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (m_exc_code == 1)
- code_desc = "EXC_ARM_UNDEFINED";
- break;
-
- default:
- break;
- }
- break;
-
- case 3: // EXC_ARITHMETIC
- exc_desc = "EXC_ARITHMETIC";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_I386_DIV"; break;
- case 2: code_desc = "EXC_I386_INTO"; break;
- case 3: code_desc = "EXC_I386_NOEXT"; break;
- case 4: code_desc = "EXC_I386_EXTOVR"; break;
- case 5: code_desc = "EXC_I386_EXTERR"; break;
- case 6: code_desc = "EXC_I386_EMERR"; break;
- case 7: code_desc = "EXC_I386_BOUND"; break;
- case 8: code_desc = "EXC_I386_SSEEXTERR"; break;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_PPC_OVERFLOW"; break;
- case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break;
- case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break;
- case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break;
- case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break;
- case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break;
- case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 4: // EXC_EMULATION
- exc_desc = "EXC_EMULATION";
- break;
-
-
- case 5: // EXC_SOFTWARE
- exc_desc = "EXC_SOFTWARE";
- if (m_exc_code == 0x10003)
- {
- subcode_desc = "EXC_SOFT_SIGNAL";
- subcode_label = "signo";
- }
- break;
-
- case 6: // EXC_BREAKPOINT
- {
- exc_desc = "EXC_BREAKPOINT";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_I386_SGL"; break;
- case 2: code_desc = "EXC_I386_BPT"; break;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_PPC_BREAKPOINT"; break;
- }
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code)
- {
- case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
- case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
- case 1: code_desc = "EXC_ARM_BREAKPOINT"; break;
- // FIXME temporary workaround, exc_code 0 does not really mean EXC_ARM_BREAKPOINT
- case 0: code_desc = "EXC_ARM_BREAKPOINT"; break;
- }
- break;
-
- default:
- break;
- }
- }
- break;
+const char *StopInfoMachException::GetDescription() {
+ if (m_description.empty() && m_value != 0) {
+ ExecutionContext exe_ctx(m_thread_wp.lock());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ const char *exc_desc = NULL;
+ const char *code_label = "code";
+ const char *code_desc = NULL;
+ const char *subcode_label = "subcode";
+ const char *subcode_desc = NULL;
+ switch (m_value) {
+ case 1: // EXC_BAD_ACCESS
+ exc_desc = "EXC_BAD_ACCESS";
+ subcode_label = "address";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 0xd:
+ code_desc = "EXC_I386_GPFLT";
+ m_exc_data_count = 1;
+ break;
+ }
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
+ break;
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
+ break;
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_PPC_VM_PROT_READ";
+ break;
+ case 0x102:
+ code_desc = "EXC_PPC_BADSPACE";
+ break;
+ case 0x103:
+ code_desc = "EXC_PPC_UNALIGNED";
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 2: // EXC_BAD_INSTRUCTION
+ exc_desc = "EXC_BAD_INSTRUCTION";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (m_exc_code == 1)
+ code_desc = "EXC_I386_INVOP";
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_PPC_INVALID_SYSCALL";
+ break;
+ case 2:
+ code_desc = "EXC_PPC_UNIPL_INST";
+ break;
+ case 3:
+ code_desc = "EXC_PPC_PRIVINST";
+ break;
+ case 4:
+ code_desc = "EXC_PPC_PRIVREG";
+ break;
+ case 5:
+ code_desc = "EXC_PPC_TRACE";
+ break;
+ case 6:
+ code_desc = "EXC_PPC_PERFMON";
+ break;
+ }
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (m_exc_code == 1)
+ code_desc = "EXC_ARM_UNDEFINED";
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 3: // EXC_ARITHMETIC
+ exc_desc = "EXC_ARITHMETIC";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_DIV";
+ break;
+ case 2:
+ code_desc = "EXC_I386_INTO";
+ break;
+ case 3:
+ code_desc = "EXC_I386_NOEXT";
+ break;
+ case 4:
+ code_desc = "EXC_I386_EXTOVR";
+ break;
+ case 5:
+ code_desc = "EXC_I386_EXTERR";
+ break;
+ case 6:
+ code_desc = "EXC_I386_EMERR";
+ break;
case 7:
- exc_desc = "EXC_SYSCALL";
- break;
-
+ code_desc = "EXC_I386_BOUND";
+ break;
case 8:
- exc_desc = "EXC_MACH_SYSCALL";
- break;
-
- case 9:
- exc_desc = "EXC_RPC_ALERT";
- break;
-
- case 10:
- exc_desc = "EXC_CRASH";
- break;
- case 11:
- exc_desc = "EXC_RESOURCE";
- break;
- case 12:
- exc_desc = "EXC_GUARD";
- break;
+ code_desc = "EXC_I386_SSEEXTERR";
+ break;
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_PPC_OVERFLOW";
+ break;
+ case 2:
+ code_desc = "EXC_PPC_ZERO_DIVIDE";
+ break;
+ case 3:
+ code_desc = "EXC_PPC_FLT_INEXACT";
+ break;
+ case 4:
+ code_desc = "EXC_PPC_FLT_ZERO_DIVIDE";
+ break;
+ case 5:
+ code_desc = "EXC_PPC_FLT_UNDERFLOW";
+ break;
+ case 6:
+ code_desc = "EXC_PPC_FLT_OVERFLOW";
+ break;
+ case 7:
+ code_desc = "EXC_PPC_FLT_NOT_A_NUMBER";
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 4: // EXC_EMULATION
+ exc_desc = "EXC_EMULATION";
+ break;
+
+ case 5: // EXC_SOFTWARE
+ exc_desc = "EXC_SOFTWARE";
+ if (m_exc_code == 0x10003) {
+ subcode_desc = "EXC_SOFT_SIGNAL";
+ subcode_label = "signo";
+ }
+ break;
+
+ case 6: // EXC_BREAKPOINT
+ {
+ exc_desc = "EXC_BREAKPOINT";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_SGL";
+ break;
+ case 2:
+ code_desc = "EXC_I386_BPT";
+ break;
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_PPC_BREAKPOINT";
+ break;
}
-
- StreamString strm;
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
+ break;
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
+ break;
+ case 1:
+ code_desc = "EXC_ARM_BREAKPOINT";
+ break;
+ // FIXME temporary workaround, exc_code 0 does not really mean
+ // EXC_ARM_BREAKPOINT
+ case 0:
+ code_desc = "EXC_ARM_BREAKPOINT";
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } break;
+
+ case 7:
+ exc_desc = "EXC_SYSCALL";
+ break;
+
+ case 8:
+ exc_desc = "EXC_MACH_SYSCALL";
+ break;
+
+ case 9:
+ exc_desc = "EXC_RPC_ALERT";
+ break;
+
+ case 10:
+ exc_desc = "EXC_CRASH";
+ break;
+ case 11:
+ exc_desc = "EXC_RESOURCE";
+ break;
+ case 12:
+ exc_desc = "EXC_GUARD";
+ break;
+ }
- if (exc_desc)
- strm.PutCString(exc_desc);
- else
- strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
+ StreamString strm;
- if (m_exc_data_count >= 1)
- {
- if (code_desc)
- strm.Printf(" (%s=%s", code_label, code_desc);
- else
- strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
- }
+ if (exc_desc)
+ strm.PutCString(exc_desc);
+ else
+ strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
- if (m_exc_data_count >= 2)
- {
- if (subcode_desc)
- strm.Printf(", %s=%s", subcode_label, subcode_desc);
- else
- strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
- }
-
- if (m_exc_data_count > 0)
- strm.PutChar(')');
-
- m_description.swap (strm.GetString());
+ if (m_exc_data_count >= 1) {
+ if (code_desc)
+ strm.Printf(" (%s=%s", code_label, code_desc);
+ else
+ strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
}
- return m_description.c_str();
-}
+ if (m_exc_data_count >= 2) {
+ if (subcode_desc)
+ strm.Printf(", %s=%s", subcode_label, subcode_desc);
+ else
+ strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
+ }
+ if (m_exc_data_count > 0)
+ strm.PutChar(')');
+ m_description = strm.GetString();
+ }
+ return m_description.c_str();
+}
+StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
+ Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
+ uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
+ bool pc_already_adjusted, bool adjust_pc_if_needed) {
+ if (exc_type != 0) {
+ uint32_t pc_decrement = 0;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ switch (exc_type) {
+ case 1: // EXC_BAD_ACCESS
+ break;
+
+ case 2: // EXC_BAD_INSTRUCTION
+ switch (cpu) {
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (exc_code) {
+ case 1: // EXC_PPC_INVALID_SYSCALL
+ case 2: // EXC_PPC_UNIPL_INST
+ case 3: // EXC_PPC_PRIVINST
+ case 4: // EXC_PPC_PRIVREG
+ break;
+ case 5: // EXC_PPC_TRACE
+ return StopInfo::CreateStopReasonToTrace(thread);
+ case 6: // EXC_PPC_PERFMON
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 3: // EXC_ARITHMETIC
+ case 4: // EXC_EMULATION
+ break;
+
+ case 5: // EXC_SOFTWARE
+ if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
+ {
+ if (exc_sub_code == 5) {
+ // On MacOSX, a SIGTRAP can signify that a process has called
+ // exec, so we should check with our dynamic loader to verify.
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
+ if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
+ // The program was re-exec'ed
+ return StopInfo::CreateStopReasonWithExec(thread);
+ }
+ // if (!process_did_exec)
+ // {
+ // // We have a SIGTRAP, make sure we
+ // didn't exec by checking
+ // // for the PC being at
+ // "_dyld_start"...
+ // lldb::StackFrameSP frame_sp
+ // (thread.GetStackFrameAtIndex(0));
+ // if (frame_sp)
+ // {
+ // const Symbol *symbol =
+ // frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+ // if (symbol)
+ // {
+ // if (symbol->GetName() ==
+ // ConstString("_dyld_start"))
+ // process_did_exec = true;
+ // }
+ // }
+ // }
+ }
+ }
+ return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
+ }
+ break;
-StopInfoSP
-StopInfoMachException::CreateStopReasonWithMachException
-(
- Thread &thread,
- uint32_t exc_type,
- uint32_t exc_data_count,
- uint64_t exc_code,
- uint64_t exc_sub_code,
- uint64_t exc_sub_sub_code,
- bool pc_already_adjusted,
- bool adjust_pc_if_needed
-)
-{
- if (exc_type != 0)
+ case 6: // EXC_BREAKPOINT
{
- uint32_t pc_decrement = 0;
- ExecutionContext exe_ctx (thread.shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch;
-
- switch (exc_type)
+ bool is_actual_breakpoint = false;
+ bool is_trace_if_actual_breakpoint_missing = false;
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (exc_code == 1) // EXC_I386_SGL
{
- case 1: // EXC_BAD_ACCESS
- break;
-
- case 2: // EXC_BAD_INSTRUCTION
- switch (cpu)
- {
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (exc_code)
- {
- case 1: // EXC_PPC_INVALID_SYSCALL
- case 2: // EXC_PPC_UNIPL_INST
- case 3: // EXC_PPC_PRIVINST
- case 4: // EXC_PPC_PRIVREG
- break;
- case 5: // EXC_PPC_TRACE
- return StopInfo::CreateStopReasonToTrace (thread);
- case 6: // EXC_PPC_PERFMON
- break;
- }
- break;
-
- default:
- break;
+ if (!exc_sub_code) {
+ // This looks like a plain trap.
+ // Have to check if there is a breakpoint here as well. When you
+ // single-step onto a trap,
+ // the single step stops you not to trap. Since we also do that
+ // check below, let's just use
+ // that logic.
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else {
+
+ // It's a watchpoint, then.
+ // The exc_sub_code indicates the data break address.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data.
+ // Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
}
- break;
-
- case 3: // EXC_ARITHMETIC
- case 4: // EXC_EMULATION
- break;
-
- case 5: // EXC_SOFTWARE
- if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
- {
- if (exc_sub_code == 5)
- {
- // On MacOSX, a SIGTRAP can signify that a process has called
- // exec, so we should check with our dynamic loader to verify.
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
- if (dynamic_loader && dynamic_loader->ProcessDidExec())
- {
- // The program was re-exec'ed
- return StopInfo::CreateStopReasonWithExec (thread);
- }
-// if (!process_did_exec)
-// {
-// // We have a SIGTRAP, make sure we didn't exec by checking
-// // for the PC being at "_dyld_start"...
-// lldb::StackFrameSP frame_sp (thread.GetStackFrameAtIndex(0));
-// if (frame_sp)
-// {
-// const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
-// if (symbol)
-// {
-// if (symbol->GetName() == ConstString("_dyld_start"))
-// process_did_exec = true;
-// }
-// }
-// }
- }
- }
- return StopInfo::CreateStopReasonWithSignal (thread, exc_sub_code);
- }
- break;
-
- case 6: // EXC_BREAKPOINT
- {
- bool is_actual_breakpoint = false;
- bool is_trace_if_actual_breakpoint_missing = false;
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (exc_code == 1) // EXC_I386_SGL
- {
- if (!exc_sub_code)
- {
- // This looks like a plain trap.
- // Have to check if there is a breakpoint here as well. When you single-step onto a trap,
- // the single step stops you not to trap. Since we also do that check below, let's just use
- // that logic.
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- else
- {
-
- // It's a watchpoint, then.
- // The exc_sub_code indicates the data break address.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled())
- {
- // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
- // Set the hardware index if that's the case.
- if (exc_data_count >=3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
- }
- }
- }
- else if (exc_code == 2 || // EXC_I386_BPT
- exc_code == 3) // EXC_I386_BPTFLT
- {
- // KDP returns EXC_I386_BPTFLT for trace breakpoints
- if (exc_code == 3)
- is_trace_if_actual_breakpoint_missing = true;
-
- is_actual_breakpoint = true;
- if (!pc_already_adjusted)
- pc_decrement = 1;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
- // data break address from our watchpoint list.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled())
- {
- // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
- // Set the hardware index if that's the case.
- if (exc_data_count >=3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
- }
- else
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- }
- else if (exc_code == 1) // EXC_ARM_BREAKPOINT
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel is currently returning this so accept it as indicating a breakpoint until the kernel is fixed
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- break;
-
- case llvm::Triple::aarch64:
- {
- if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
- {
- // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 is set
- return StopInfo::CreateStopReasonToTrace(thread);
- }
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
- // data break address from our watchpoint list.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled())
- {
- // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
- // Set the hardware index if that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
- }
- // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS
- if (thread.GetTemporaryResumeState() == eStateStepping)
- return StopInfo::CreateStopReasonToTrace(thread);
- }
- // It looks like exc_sub_code has the 4 bytes of the instruction that triggered the
- // exception, i.e. our breakpoint opcode
- is_actual_breakpoint = exc_code == 1;
- break;
- }
-
- default:
- break;
- }
-
- if (is_actual_breakpoint)
- {
- RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
- addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
-
- ProcessSP process_sp (thread.CalculateProcess());
-
- lldb::BreakpointSiteSP bp_site_sp;
- if (process_sp)
- bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
- if (bp_site_sp && bp_site_sp->IsEnabled())
- {
- // Update the PC if we were asked to do so, but only do
- // so if we find a breakpoint that we know about cause
- // this could be a trap instruction in the code
- if (pc_decrement > 0 && adjust_pc_if_needed)
- reg_ctx_sp->SetPC (pc);
-
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- // If we have an operating system plug-in, we might have set a thread specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about the thread ID so we must always
- // report the breakpoint regardless of the thread.
- if (bp_site_sp->ValidForThisThread (&thread) || thread.GetProcess()->GetOperatingSystem () != NULL)
- return StopInfo::CreateStopReasonWithBreakpointSiteID (thread, bp_site_sp->GetID());
- else if (is_trace_if_actual_breakpoint_missing)
- return StopInfo::CreateStopReasonToTrace (thread);
- else
- return StopInfoSP();
- }
-
- // Don't call this a trace if we weren't single stepping this thread.
- if (is_trace_if_actual_breakpoint_missing && thread.GetTemporaryResumeState() == eStateStepping)
- {
- return StopInfo::CreateStopReasonToTrace (thread);
- }
- }
- }
- break;
+ }
+ } else if (exc_code == 2 || // EXC_I386_BPT
+ exc_code == 3) // EXC_I386_BPTFLT
+ {
+ // KDP returns EXC_I386_BPTFLT for trace breakpoints
+ if (exc_code == 3)
+ is_trace_if_actual_breakpoint_missing = true;
- case 7: // EXC_SYSCALL
- case 8: // EXC_MACH_SYSCALL
- case 9: // EXC_RPC_ALERT
- case 10: // EXC_CRASH
- break;
+ is_actual_breakpoint = true;
+ if (!pc_already_adjusted)
+ pc_decrement = 1;
}
-
- return StopInfoSP(new StopInfoMachException (thread, exc_type, exc_data_count, exc_code, exc_sub_code));
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled
+ // data break address from our watchpoint list.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data.
+ // Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
+ } else {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ }
+ } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
+ // is currently returning this so accept it as
+ // indicating a breakpoint until the kernel is
+ // fixed
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ }
+ break;
+
+ case llvm::Triple::aarch64: {
+ if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
+ {
+ // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
+ // is set
+ is_actual_breakpoint = false;
+ is_trace_if_actual_breakpoint_missing = true;
+ }
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled
+ // data break address from our watchpoint list.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data.
+ // Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
+ }
+ // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
+ // EXC_BAD_ACCESS
+ if (thread.GetTemporaryResumeState() == eStateStepping)
+ return StopInfo::CreateStopReasonToTrace(thread);
+ }
+ // It looks like exc_sub_code has the 4 bytes of the instruction that
+ // triggered the
+ // exception, i.e. our breakpoint opcode
+ is_actual_breakpoint = exc_code == 1;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (is_actual_breakpoint) {
+ RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+ addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
+
+ ProcessSP process_sp(thread.CalculateProcess());
+
+ lldb::BreakpointSiteSP bp_site_sp;
+ if (process_sp)
+ bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
+ if (bp_site_sp && bp_site_sp->IsEnabled()) {
+ // Update the PC if we were asked to do so, but only do
+ // so if we find a breakpoint that we know about cause
+ // this could be a trap instruction in the code
+ if (pc_decrement > 0 && adjust_pc_if_needed)
+ reg_ctx_sp->SetPC(pc);
+
+ // If the breakpoint is for this thread, then we'll report the hit,
+ // but if it is for another thread,
+ // we can just report no reason. We don't need to worry about
+ // stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices that
+ // there's a breakpoint under the pc.
+ // If we have an operating system plug-in, we might have set a thread
+ // specific breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about
+ // the thread ID so we must always
+ // report the breakpoint regardless of the thread.
+ if (bp_site_sp->ValidForThisThread(&thread) ||
+ thread.GetProcess()->GetOperatingSystem() != NULL)
+ return StopInfo::CreateStopReasonWithBreakpointSiteID(
+ thread, bp_site_sp->GetID());
+ else if (is_trace_if_actual_breakpoint_missing)
+ return StopInfo::CreateStopReasonToTrace(thread);
+ else
+ return StopInfoSP();
+ }
+
+ // Don't call this a trace if we weren't single stepping this thread.
+ if (is_trace_if_actual_breakpoint_missing &&
+ thread.GetTemporaryResumeState() == eStateStepping) {
+ return StopInfo::CreateStopReasonToTrace(thread);
+ }
+ }
+ } break;
+
+ case 7: // EXC_SYSCALL
+ case 8: // EXC_MACH_SYSCALL
+ case 9: // EXC_RPC_ALERT
+ case 10: // EXC_CRASH
+ break;
}
- return StopInfoSP();
+
+ return StopInfoSP(new StopInfoMachException(
+ thread, exc_type, exc_data_count, exc_code, exc_sub_code));
+ }
+ return StopInfoSP();
}
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.h b/source/Plugins/Process/Utility/StopInfoMachException.h
index 25e05ecc1ec7..94516454105e 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.h
+++ b/source/Plugins/Process/Utility/StopInfoMachException.h
@@ -20,52 +20,37 @@
namespace lldb_private {
-class StopInfoMachException : public StopInfo
-{
+class StopInfoMachException : public StopInfo {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- StopInfoMachException (Thread &thread,
- uint32_t exc_type,
- uint32_t exc_data_count,
- uint64_t exc_code,
- uint64_t exc_subcode) :
- StopInfo (thread, exc_type),
- m_exc_data_count (exc_data_count),
- m_exc_code (exc_code),
- m_exc_subcode (exc_subcode)
- {
- }
-
- ~StopInfoMachException() override = default;
-
- lldb::StopReason
- GetStopReason() const override
- {
- return lldb::eStopReasonException;
- }
-
- const char *
- GetDescription() override;
-
- // Since some mach exceptions will be reported as breakpoints, signals,
- // or trace, we use this static accessor which will translate the mach
- // exception into the correct StopInfo.
- static lldb::StopInfoSP
- CreateStopReasonWithMachException (Thread &thread,
- uint32_t exc_type,
- uint32_t exc_data_count,
- uint64_t exc_code,
- uint64_t exc_sub_code,
- uint64_t exc_sub_sub_code,
- bool pc_already_adjusted = true,
- bool adjust_pc_if_needed = false);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StopInfoMachException(Thread &thread, uint32_t exc_type,
+ uint32_t exc_data_count, uint64_t exc_code,
+ uint64_t exc_subcode)
+ : StopInfo(thread, exc_type), m_exc_data_count(exc_data_count),
+ m_exc_code(exc_code), m_exc_subcode(exc_subcode) {}
+
+ ~StopInfoMachException() override = default;
+
+ lldb::StopReason GetStopReason() const override {
+ return lldb::eStopReasonException;
+ }
+
+ const char *GetDescription() override;
+
+ // Since some mach exceptions will be reported as breakpoints, signals,
+ // or trace, we use this static accessor which will translate the mach
+ // exception into the correct StopInfo.
+ static lldb::StopInfoSP CreateStopReasonWithMachException(
+ Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
+ uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
+ bool pc_already_adjusted = true, bool adjust_pc_if_needed = false);
protected:
- uint32_t m_exc_data_count;
- uint64_t m_exc_code;
- uint64_t m_exc_subcode;
+ uint32_t m_exc_data_count;
+ uint64_t m_exc_code;
+ uint64_t m_exc_subcode;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/ThreadMemory.cpp b/source/Plugins/Process/Utility/ThreadMemory.cpp
index 6a7aa626bafc..b3cac1c854d1 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -1,4 +1,5 @@
-//===-- ThreadMemory.cpp ----------------------------------------------*- C++ -*-===//
+//===-- ThreadMemory.cpp ----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,133 +9,97 @@
//===----------------------------------------------------------------------===//
#include "Plugins/Process/Utility/ThreadMemory.h"
+#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
#include "lldb/Target/OperatingSystem.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Unwind.h"
-#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
using namespace lldb;
using namespace lldb_private;
-ThreadMemory::ThreadMemory (Process &process,
- tid_t tid,
- const ValueObjectSP &thread_info_valobj_sp) :
- Thread (process, tid),
- m_backing_thread_sp (),
- m_thread_info_valobj_sp (thread_info_valobj_sp),
- m_name(),
- m_queue()
-{
-}
-
+ThreadMemory::ThreadMemory(Process &process, tid_t tid,
+ const ValueObjectSP &thread_info_valobj_sp)
+ : Thread(process, tid), m_backing_thread_sp(),
+ m_thread_info_valobj_sp(thread_info_valobj_sp), m_name(), m_queue() {}
-ThreadMemory::ThreadMemory (Process &process,
- lldb::tid_t tid,
- const char *name,
- const char *queue,
- lldb::addr_t register_data_addr) :
- Thread (process, tid),
- m_backing_thread_sp (),
- m_thread_info_valobj_sp (),
- m_name(),
- m_queue(),
- m_register_data_addr (register_data_addr)
-{
- if (name)
- m_name = name;
- if (queue)
- m_queue = queue;
+ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid, const char *name,
+ const char *queue, lldb::addr_t register_data_addr)
+ : Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(),
+ m_name(), m_queue(), m_register_data_addr(register_data_addr) {
+ if (name)
+ m_name = name;
+ if (queue)
+ m_queue = queue;
}
+ThreadMemory::~ThreadMemory() { DestroyThread(); }
-ThreadMemory::~ThreadMemory()
-{
- DestroyThread();
+void ThreadMemory::WillResume(StateType resume_state) {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->WillResume(resume_state);
}
-void
-ThreadMemory::WillResume (StateType resume_state)
-{
- if (m_backing_thread_sp)
- m_backing_thread_sp->WillResume(resume_state);
+void ThreadMemory::ClearStackFrames() {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->ClearStackFrames();
+ Thread::ClearStackFrames();
}
-void
-ThreadMemory::ClearStackFrames ()
-{
- if (m_backing_thread_sp)
- m_backing_thread_sp->ClearStackFrames();
- Thread::ClearStackFrames();
+RegisterContextSP ThreadMemory::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp.reset(
+ new RegisterContextThreadMemory(*this, m_register_data_addr));
+ return m_reg_context_sp;
}
RegisterContextSP
-ThreadMemory::GetRegisterContext ()
-{
- if (!m_reg_context_sp)
- m_reg_context_sp.reset (new RegisterContextThreadMemory (*this, m_register_data_addr));
- return m_reg_context_sp;
-}
+ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
-RegisterContextSP
-ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
-{
- RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- reg_ctx_sp = GetRegisterContext ();
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
- }
- return reg_ctx_sp;
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ reg_ctx_sp = GetRegisterContext();
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadMemory::CalculateStopInfo ()
-{
- if (m_backing_thread_sp)
- {
- lldb::StopInfoSP backing_stop_info_sp (m_backing_thread_sp->GetPrivateStopInfo());
- if (backing_stop_info_sp && backing_stop_info_sp->IsValidForOperatingSystemThread(*this))
- {
- backing_stop_info_sp->SetThread (shared_from_this());
- SetStopInfo (backing_stop_info_sp);
- return true;
- }
+bool ThreadMemory::CalculateStopInfo() {
+ if (m_backing_thread_sp) {
+ lldb::StopInfoSP backing_stop_info_sp(
+ m_backing_thread_sp->GetPrivateStopInfo());
+ if (backing_stop_info_sp &&
+ backing_stop_info_sp->IsValidForOperatingSystemThread(*this)) {
+ backing_stop_info_sp->SetThread(shared_from_this());
+ SetStopInfo(backing_stop_info_sp);
+ return true;
}
- else
- {
- ProcessSP process_sp (GetProcess());
+ } else {
+ ProcessSP process_sp(GetProcess());
- if (process_sp)
- {
- OperatingSystem *os = process_sp->GetOperatingSystem ();
- if (os)
- {
- SetStopInfo (os->CreateThreadStopReason (this));
- return true;
- }
- }
+ if (process_sp) {
+ OperatingSystem *os = process_sp->GetOperatingSystem();
+ if (os) {
+ SetStopInfo(os->CreateThreadStopReason(this));
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-void
-ThreadMemory::RefreshStateAfterStop()
-{
- if (m_backing_thread_sp)
- return m_backing_thread_sp->RefreshStateAfterStop();
-
- if (m_reg_context_sp)
- m_reg_context_sp->InvalidateAllRegisters();
+void ThreadMemory::RefreshStateAfterStop() {
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->RefreshStateAfterStop();
+
+ if (m_reg_context_sp)
+ m_reg_context_sp->InvalidateAllRegisters();
}
diff --git a/source/Plugins/Process/Utility/ThreadMemory.h b/source/Plugins/Process/Utility/ThreadMemory.h
index 1e7cbfa44815..095544d244ba 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/source/Plugins/Process/Utility/ThreadMemory.h
@@ -18,129 +18,94 @@
// Project includes
#include "lldb/Target/Thread.h"
-class ThreadMemory :
- public lldb_private::Thread
-{
+class ThreadMemory : public lldb_private::Thread {
public:
- ThreadMemory (lldb_private::Process &process,
- lldb::tid_t tid,
- const lldb::ValueObjectSP &thread_info_valobj_sp);
-
- ThreadMemory (lldb_private::Process &process,
- lldb::tid_t tid,
- const char *name,
- const char *queue,
- lldb::addr_t register_data_addr);
-
- ~ThreadMemory() override;
-
- lldb::RegisterContextSP
- GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- bool
- CalculateStopInfo() override;
-
- const char *
- GetInfo() override
- {
- if (m_backing_thread_sp)
- m_backing_thread_sp->GetInfo();
- return nullptr;
- }
-
- const char *
- GetName() override
- {
- if (!m_name.empty())
- return m_name.c_str();
- if (m_backing_thread_sp)
- m_backing_thread_sp->GetName();
- return nullptr;
- }
-
- const char *
- GetQueueName() override
- {
- if (!m_queue.empty())
- return m_queue.c_str();
- if (m_backing_thread_sp)
- m_backing_thread_sp->GetQueueName();
- return nullptr;
- }
-
- void
- WillResume(lldb::StateType resume_state) override;
-
- void
- DidResume() override
- {
- if (m_backing_thread_sp)
- m_backing_thread_sp->DidResume();
- }
-
- lldb::user_id_t
- GetProtocolID() const override
- {
- if (m_backing_thread_sp)
- return m_backing_thread_sp->GetProtocolID();
- return Thread::GetProtocolID();
- }
-
- void
- RefreshStateAfterStop() override;
-
- lldb::ValueObjectSP &
- GetValueObject ()
- {
- return m_thread_info_valobj_sp;
- }
-
- void
- ClearStackFrames() override;
-
- void
- ClearBackingThread() override
- {
- m_backing_thread_sp.reset();
- }
-
- bool
- SetBackingThread(const lldb::ThreadSP &thread_sp) override
- {
- //printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(), thread_sp->GetID());
- m_backing_thread_sp = thread_sp;
- return (bool)thread_sp;
- }
-
- lldb::ThreadSP
- GetBackingThread() const override
- {
- return m_backing_thread_sp;
- }
+ ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
+ const lldb::ValueObjectSP &thread_info_valobj_sp);
+
+ ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
+ const char *name, const char *queue,
+ lldb::addr_t register_data_addr);
+
+ ~ThreadMemory() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+ bool CalculateStopInfo() override;
+
+ const char *GetInfo() override {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetInfo();
+ return nullptr;
+ }
+
+ const char *GetName() override {
+ if (!m_name.empty())
+ return m_name.c_str();
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetName();
+ return nullptr;
+ }
+
+ const char *GetQueueName() override {
+ if (!m_queue.empty())
+ return m_queue.c_str();
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetQueueName();
+ return nullptr;
+ }
+
+ void WillResume(lldb::StateType resume_state) override;
+
+ void DidResume() override {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->DidResume();
+ }
+
+ lldb::user_id_t GetProtocolID() const override {
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->GetProtocolID();
+ return Thread::GetProtocolID();
+ }
+
+ void RefreshStateAfterStop() override;
+
+ lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; }
+
+ void ClearStackFrames() override;
+
+ void ClearBackingThread() override { m_backing_thread_sp.reset(); }
+
+ bool SetBackingThread(const lldb::ThreadSP &thread_sp) override {
+ // printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(),
+ // thread_sp->GetID());
+ m_backing_thread_sp = thread_sp;
+ return (bool)thread_sp;
+ }
+
+ lldb::ThreadSP GetBackingThread() const override {
+ return m_backing_thread_sp;
+ }
protected:
- bool
- IsOperatingSystemPluginThread() const override
- {
- return true;
- }
-
- // If this memory thread is actually represented by a thread from the
- // lldb_private::Process subclass, then fill in the thread here and
- // all APIs will be routed through this thread object. If m_backing_thread_sp
- // is empty, then this thread is simply in memory with no representation
- // through the process plug-in.
- lldb::ThreadSP m_backing_thread_sp;
- lldb::ValueObjectSP m_thread_info_valobj_sp;
- std::string m_name;
- std::string m_queue;
- lldb::addr_t m_register_data_addr;
+ bool IsOperatingSystemPluginThread() const override { return true; }
+
+ // If this memory thread is actually represented by a thread from the
+ // lldb_private::Process subclass, then fill in the thread here and
+ // all APIs will be routed through this thread object. If m_backing_thread_sp
+ // is empty, then this thread is simply in memory with no representation
+ // through the process plug-in.
+ lldb::ThreadSP m_backing_thread_sp;
+ lldb::ValueObjectSP m_thread_info_valobj_sp;
+ std::string m_name;
+ std::string m_queue;
+ lldb::addr_t m_register_data_addr;
private:
- DISALLOW_COPY_AND_ASSIGN (ThreadMemory);
+ DISALLOW_COPY_AND_ASSIGN(ThreadMemory);
};
#endif // liblldb_ThreadMemory_h_
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 9be09c478a0e..6e2a9a9ee100 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -7,529 +7,532 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/Module.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/ABI.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
-#include "UnwindLLDB.h"
#include "RegisterContextLLDB.h"
+#include "UnwindLLDB.h"
using namespace lldb;
using namespace lldb_private;
-UnwindLLDB::UnwindLLDB (Thread &thread) :
- Unwind (thread),
- m_frames(),
- m_unwind_complete(false),
- m_user_supplied_trap_handler_functions()
-{
- ProcessSP process_sp(thread.GetProcess());
- if (process_sp)
- {
- Args args;
- process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames (args);
- size_t count = args.GetArgumentCount();
- for (size_t i = 0; i < count; i++)
- {
- const char *func_name = args.GetArgumentAtIndex(i);
- m_user_supplied_trap_handler_functions.push_back (ConstString (func_name));
- }
+UnwindLLDB::UnwindLLDB(Thread &thread)
+ : Unwind(thread), m_frames(), m_unwind_complete(false),
+ m_user_supplied_trap_handler_functions() {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ Args args;
+ process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);
+ size_t count = args.GetArgumentCount();
+ for (size_t i = 0; i < count; i++) {
+ const char *func_name = args.GetArgumentAtIndex(i);
+ m_user_supplied_trap_handler_functions.push_back(ConstString(func_name));
}
+ }
}
-uint32_t
-UnwindLLDB::DoGetFrameCount()
-{
- if (!m_unwind_complete)
- {
+uint32_t UnwindLLDB::DoGetFrameCount() {
+ if (!m_unwind_complete) {
//#define DEBUG_FRAME_SPEED 1
#if DEBUG_FRAME_SPEED
#define FRAME_COUNT 10000
- TimeValue time_value (TimeValue::Now());
+ using namespace std::chrono;
+ auto time_value = steady_clock::now();
#endif
- if (!AddFirstFrame ())
- return 0;
+ if (!AddFirstFrame())
+ return 0;
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
- while (AddOneMoreFrame (abi))
- {
+ while (AddOneMoreFrame(abi)) {
#if DEBUG_FRAME_SPEED
- if ((m_frames.size() % FRAME_COUNT) == 0)
- {
- TimeValue now(TimeValue::Now());
- uint64_t delta_t = now - time_value;
- printf ("%u frames in %" PRIu64 ".%09llu ms (%g frames/sec)\n",
- FRAME_COUNT,
- delta_t / TimeValue::NanoSecPerSec,
- delta_t % TimeValue::NanoSecPerSec,
- (float)FRAME_COUNT / ((float)delta_t / (float)TimeValue::NanoSecPerSec));
- time_value = now;
- }
+ if ((m_frames.size() % FRAME_COUNT) == 0) {
+ const auto now = steady_clock::now();
+ const auto delta_t = now - time_value;
+ printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT,
+ duration<double, std::milli>(delta_t).count(),
+ (float)FRAME_COUNT / duration<double>(delta_t).count());
+ time_value = now;
+ }
#endif
- }
}
- return m_frames.size ();
+ }
+ return m_frames.size();
}
-bool
-UnwindLLDB::AddFirstFrame ()
-{
- if (m_frames.size() > 0)
- return true;
-
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+bool UnwindLLDB::AddFirstFrame() {
+ if (m_frames.size() > 0)
+ return true;
- // First, set up the 0th (initial) frame
- CursorSP first_cursor_sp(new Cursor ());
- RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread,
- RegisterContextLLDBSP(),
- first_cursor_sp->sctx,
- 0, *this));
- if (reg_ctx_sp.get() == NULL)
- goto unwind_done;
-
- if (!reg_ctx_sp->IsValid())
- goto unwind_done;
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
- if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa))
- goto unwind_done;
+ // First, set up the 0th (initial) frame
+ CursorSP first_cursor_sp(new Cursor());
+ RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
+ m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this));
+ if (reg_ctx_sp.get() == NULL)
+ goto unwind_done;
- if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc))
- goto unwind_done;
+ if (!reg_ctx_sp->IsValid())
+ goto unwind_done;
- // Everything checks out, so release the auto pointer value and let the
- // cursor own it in its shared pointer
- first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
- m_frames.push_back (first_cursor_sp);
+ if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))
+ goto unwind_done;
- // Update the Full Unwind Plan for this frame if not valid
- UpdateUnwindPlanForFirstFrameIfInvalid(abi);
+ if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))
+ goto unwind_done;
- return true;
+ // Everything checks out, so release the auto pointer value and let the
+ // cursor own it in its shared pointer
+ first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
+ m_frames.push_back(first_cursor_sp);
+
+ // Update the Full Unwind Plan for this frame if not valid
+ UpdateUnwindPlanForFirstFrameIfInvalid(abi);
+
+ return true;
unwind_done:
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log)
- {
- log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID());
- }
- m_unwind_complete = true;
- return false;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log) {
+ log->Printf("th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
+ }
+ m_unwind_complete = true;
+ return false;
}
-UnwindLLDB::CursorSP
-UnwindLLDB::GetOneMoreFrame (ABI* abi)
-{
- assert (m_frames.size() != 0 && "Get one more frame called with empty frame list");
-
- // If we've already gotten to the end of the stack, don't bother to try again...
- if (m_unwind_complete)
- return nullptr;
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- CursorSP prev_frame = m_frames.back();
- uint32_t cur_idx = m_frames.size();
-
- CursorSP cursor_sp(new Cursor ());
- RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread,
- prev_frame->reg_ctx_lldb_sp,
- cursor_sp->sctx,
- cur_idx,
- *this));
-
- // We want to detect an unwind that cycles erroneously and stop backtracing.
- // Don't want this maximum unwind limit to be too low -- if you have a backtrace
- // with an "infinitely recursing" bug, it will crash when the stack blows out
- // and the first 35,000 frames are uninteresting - it's the top most 5 frames that
- // you actually care about. So you can't just cap the unwind at 10,000 or something.
- // Realistically anything over around 200,000 is going to blow out the stack space.
- // If we're still unwinding at that point, we're probably never going to finish.
- if (cur_idx > 300000)
- {
- if (log)
- log->Printf ("%*sFrame %d unwound too many frames, assuming unwind has gone astray, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
+ assert(m_frames.size() != 0 &&
+ "Get one more frame called with empty frame list");
+
+ // If we've already gotten to the end of the stack, don't bother to try
+ // again...
+ if (m_unwind_complete)
+ return nullptr;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ CursorSP prev_frame = m_frames.back();
+ uint32_t cur_idx = m_frames.size();
+
+ CursorSP cursor_sp(new Cursor());
+ RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
+ m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));
+
+ // We want to detect an unwind that cycles erroneously and stop backtracing.
+ // Don't want this maximum unwind limit to be too low -- if you have a
+ // backtrace
+ // with an "infinitely recursing" bug, it will crash when the stack blows out
+ // and the first 35,000 frames are uninteresting - it's the top most 5 frames
+ // that
+ // you actually care about. So you can't just cap the unwind at 10,000 or
+ // something.
+ // Realistically anything over around 200,000 is going to blow out the stack
+ // space.
+ // If we're still unwinding at that point, we're probably never going to
+ // finish.
+ if (cur_idx > 300000) {
+ if (log)
+ log->Printf("%*sFrame %d unwound too many frames, assuming unwind has "
+ "gone astray, stopping.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+
+ if (reg_ctx_sp.get() == NULL) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
- }
-
- if (reg_ctx_sp.get() == NULL)
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
- if (log)
- log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
+ return GetOneMoreFrame(abi);
}
- if (!reg_ctx_sp->IsValid())
- {
- // We failed to get a valid RegisterContext.
- // See if the regctx below this on the stack has a fallback unwind plan it can use.
- // Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
-
- if (log)
- log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ if (log)
+ log->Printf("%*sFrame %d did not get a RegisterContext, stopping.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+
+ if (!reg_ctx_sp->IsValid()) {
+ // We failed to get a valid RegisterContext.
+ // See if the regctx below this on the stack has a fallback unwind plan it
+ // can use.
+ // Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
- if (log)
- log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ if (log)
+ log->Printf("%*sFrame %d invalid RegisterContext for this frame, "
+ "stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))
- {
- // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not have
- // its (constructed) CFA aligned correctly -- don't do the abi alignment check for
- // these.
- if (reg_ctx_sp->IsTrapHandlerFrame() == false)
- {
- // See if we can find a fallback unwind plan for THIS frame. It may be
- // that the UnwindPlan we're using for THIS frame was bad and gave us a
- // bad CFA.
- // If that's not it, then see if we can change the UnwindPlan for the frame
- // below us ("NEXT") -- see if using that other UnwindPlan gets us a better
- // unwind state.
- if (reg_ctx_sp->TryFallbackUnwindPlan() == false
- || reg_ctx_sp->GetCFA (cursor_sp->cfa) == false
- || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false)
- {
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
-
- if (log)
- log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
- else
- {
- if (log)
- log->Printf("%*sFrame %d had a bad CFA value but we switched the UnwindPlan being used and got one that looks more realistic.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- }
- }
- }
- if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
+
+ if (log)
+ log->Printf(
+ "%*sFrame %d did not get CFA for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
+ // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
+ // have
+ // its (constructed) CFA aligned correctly -- don't do the abi alignment
+ // check for
+ // these.
+ if (reg_ctx_sp->IsTrapHandlerFrame() == false) {
+ // See if we can find a fallback unwind plan for THIS frame. It may be
+ // that the UnwindPlan we're using for THIS frame was bad and gave us a
+ // bad CFA.
+ // If that's not it, then see if we can change the UnwindPlan for the
+ // frame
+ // below us ("NEXT") -- see if using that other UnwindPlan gets us a
+ // better
+ // unwind state.
+ if (reg_ctx_sp->TryFallbackUnwindPlan() == false ||
+ reg_ctx_sp->GetCFA(cursor_sp->cfa) == false ||
+ abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) {
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be
+ // updated. Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
+ return nullptr;
+
+ return GetOneMoreFrame(abi);
}
if (log)
- log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ log->Printf("%*sFrame %d did not get a valid CFA for this frame, "
+ "stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
- }
- if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
-
+ } else {
if (log)
- log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ log->Printf("%*sFrame %d had a bad CFA value but we switched the "
+ "UnwindPlan being used and got one that looks more "
+ "realistic.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ }
+ }
+ }
+ if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- // Infinite loop where the current cursor is the same as the previous one...
- if (prev_frame->start_pc == cursor_sp->start_pc && prev_frame->cfa == cursor_sp->cfa)
- {
- if (log)
- log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID());
+
+ if (log)
+ log->Printf(
+ "%*sFrame %d did not get PC for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
- return cursor_sp;
+ if (log)
+ log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ // Infinite loop where the current cursor is the same as the previous one...
+ if (prev_frame->start_pc == cursor_sp->start_pc &&
+ prev_frame->cfa == cursor_sp->cfa) {
+ if (log)
+ log->Printf("th%d pc of this frame is the same as the previous frame and "
+ "CFAs for both frames are identical -- stopping unwind",
+ m_thread.GetIndexID());
+ return nullptr;
+ }
+
+ cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
+ return cursor_sp;
}
-void
-UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid (ABI *abi)
-{
- // This function is called for First Frame only.
- assert (m_frames.size() == 1 && "No. of cursor frames are not 1");
-
- bool old_m_unwind_complete = m_unwind_complete;
- CursorSP old_m_candidate_frame = m_candidate_frame;
-
- // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
- // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also
- // update the cfa of Frame 0 (if required).
- AddOneMoreFrame(abi);
-
- // Remove all the frames added by above function as the purpose of
- // using above function was just to check whether Unwinder of Frame 0
- // works or not.
- for(uint32_t i=1; i<m_frames.size(); i++)
- m_frames.pop_back();
-
- // Restore status after calling AddOneMoreFrame
- m_unwind_complete = old_m_unwind_complete;
- m_candidate_frame = old_m_candidate_frame;
- return;
-}
+void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
+ // This function is called for First Frame only.
+ assert(m_frames.size() == 1 && "No. of cursor frames are not 1");
+ bool old_m_unwind_complete = m_unwind_complete;
+ CursorSP old_m_candidate_frame = m_candidate_frame;
-bool
-UnwindLLDB::AddOneMoreFrame (ABI *abi)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
+ // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also
+ // update the cfa of Frame 0 (if required).
+ AddOneMoreFrame(abi);
- // Frame zero is a little different
- if (m_frames.empty())
- return false;
+ // Remove all the frames added by above function as the purpose of
+ // using above function was just to check whether Unwinder of Frame 0
+ // works or not.
+ for (uint32_t i = 1; i < m_frames.size(); i++)
+ m_frames.pop_back();
- // If we've already gotten to the end of the stack, don't bother to try again...
- if (m_unwind_complete)
- return false;
+ // Restore status after calling AddOneMoreFrame
+ m_unwind_complete = old_m_unwind_complete;
+ m_candidate_frame = old_m_candidate_frame;
+ return;
+}
- CursorSP new_frame = m_candidate_frame;
- if (new_frame == nullptr)
- new_frame = GetOneMoreFrame(abi);
+bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (new_frame == nullptr)
- {
- if (log)
- log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID());
- m_unwind_complete = true;
- return false;
- }
+ // Frame zero is a little different
+ if (m_frames.empty())
+ return false;
- m_frames.push_back(new_frame);
+ // If we've already gotten to the end of the stack, don't bother to try
+ // again...
+ if (m_unwind_complete)
+ return false;
- // If we can get one more frame further then accept that we get back a correct frame.
- m_candidate_frame = GetOneMoreFrame(abi);
- if (m_candidate_frame)
- return true;
-
- // We can't go further from the frame returned by GetOneMore frame. Lets try to get a
- // different frame with using the fallback unwind plan.
- if (!m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // We don't have a valid fallback unwind plan. Accept the frame as it is. This is a
- // valid situation when we are at the bottom of the stack.
- return true;
- }
+ CursorSP new_frame = m_candidate_frame;
+ if (new_frame == nullptr)
+ new_frame = GetOneMoreFrame(abi);
- // Remove the possibly incorrect frame from the frame list and try to add a different one with
- // the newly selected fallback unwind plan.
- m_frames.pop_back();
- CursorSP new_frame_v2 = GetOneMoreFrame(abi);
- if (new_frame_v2 == nullptr)
- {
- // We haven't got a new frame from the fallback unwind plan. Accept the frame from the
- // original unwind plan. This is a valid situation when we are at the bottom of the stack.
- m_frames.push_back(new_frame);
- return true;
- }
+ if (new_frame == nullptr) {
+ if (log)
+ log->Printf("th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
+ m_unwind_complete = true;
+ return false;
+ }
- // Push the new frame to the list and try to continue from this frame. If we can get a new frame
- // then accept it as the correct one.
- m_frames.push_back(new_frame_v2);
- m_candidate_frame = GetOneMoreFrame(abi);
- if (m_candidate_frame)
- {
- // If control reached here then TryFallbackUnwindPlan had succeeded for Cursor::m_frames[m_frames.size() - 2].
- // It also succeeded to Unwind next 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that.
- // For Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already updated during TryFallbackUnwindPlan
- // call above. However, cfa field still needs to be updated. Hence updating it here and then returning.
- if ( !(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(m_frames[m_frames.size() - 2]->cfa)))
- return false;
- return true;
- }
+ m_frames.push_back(new_frame);
- // The new frame hasn't helped in unwinding. Fall back to the original one as the default unwind
- // plan is usually more reliable then the fallback one.
- m_frames.pop_back();
+ // If we can get one more frame further then accept that we get back a correct
+ // frame.
+ m_candidate_frame = GetOneMoreFrame(abi);
+ if (m_candidate_frame)
+ return true;
+
+ // We can't go further from the frame returned by GetOneMore frame. Lets try
+ // to get a
+ // different frame with using the fallback unwind plan.
+ if (!m_frames[m_frames.size() - 2]
+ ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // We don't have a valid fallback unwind plan. Accept the frame as it is.
+ // This is a
+ // valid situation when we are at the bottom of the stack.
+ return true;
+ }
+
+ // Remove the possibly incorrect frame from the frame list and try to add a
+ // different one with
+ // the newly selected fallback unwind plan.
+ m_frames.pop_back();
+ CursorSP new_frame_v2 = GetOneMoreFrame(abi);
+ if (new_frame_v2 == nullptr) {
+ // We haven't got a new frame from the fallback unwind plan. Accept the
+ // frame from the
+ // original unwind plan. This is a valid situation when we are at the bottom
+ // of the stack.
m_frames.push_back(new_frame);
return true;
+ }
+
+ // Push the new frame to the list and try to continue from this frame. If we
+ // can get a new frame
+ // then accept it as the correct one.
+ m_frames.push_back(new_frame_v2);
+ m_candidate_frame = GetOneMoreFrame(abi);
+ if (m_candidate_frame) {
+ // If control reached here then TryFallbackUnwindPlan had succeeded for
+ // Cursor::m_frames[m_frames.size() - 2].
+ // It also succeeded to Unwind next 2 frames i.e. m_frames[m_frames.size() -
+ // 1] and a frame after that.
+ // For Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was
+ // already updated during TryFallbackUnwindPlan
+ // call above. However, cfa field still needs to be updated. Hence updating
+ // it here and then returning.
+ if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
+ m_frames[m_frames.size() - 2]->cfa)))
+ return false;
+ return true;
+ }
+
+ // The new frame hasn't helped in unwinding. Fall back to the original one as
+ // the default unwind
+ // plan is usually more reliable then the fallback one.
+ m_frames.pop_back();
+ m_frames.push_back(new_frame);
+ return true;
}
-bool
-UnwindLLDB::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
-{
- if (m_frames.size() == 0)
- {
- if (!AddFirstFrame())
- return false;
- }
+bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
+ if (m_frames.size() == 0) {
+ if (!AddFirstFrame())
+ return false;
+ }
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
- while (idx >= m_frames.size() && AddOneMoreFrame (abi))
- ;
+ while (idx >= m_frames.size() && AddOneMoreFrame(abi))
+ ;
- if (idx < m_frames.size ())
- {
- cfa = m_frames[idx]->cfa;
- pc = m_frames[idx]->start_pc;
- return true;
- }
- return false;
+ if (idx < m_frames.size()) {
+ cfa = m_frames[idx]->cfa;
+ pc = m_frames[idx]->start_pc;
+ return true;
+ }
+ return false;
}
lldb::RegisterContextSP
-UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t idx = frame->GetConcreteFrameIndex ();
-
- if (idx == 0)
- {
- return m_thread.GetRegisterContext();
- }
-
- if (m_frames.size() == 0)
- {
- if (!AddFirstFrame())
- return reg_ctx_sp;
- }
-
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
-
- while (idx >= m_frames.size())
- {
- if (!AddOneMoreFrame (abi))
- break;
- }
-
- const uint32_t num_frames = m_frames.size();
- if (idx < num_frames)
- {
- Cursor *frame_cursor = m_frames[idx].get();
- reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
- }
- return reg_ctx_sp;
+UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t idx = frame->GetConcreteFrameIndex();
+
+ if (idx == 0) {
+ return m_thread.GetRegisterContext();
+ }
+
+ if (m_frames.size() == 0) {
+ if (!AddFirstFrame())
+ return reg_ctx_sp;
+ }
+
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+
+ while (idx >= m_frames.size()) {
+ if (!AddOneMoreFrame(abi))
+ break;
+ }
+
+ const uint32_t num_frames = m_frames.size();
+ if (idx < num_frames) {
+ Cursor *frame_cursor = m_frames[idx].get();
+ reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
+ }
+ return reg_ctx_sp;
}
UnwindLLDB::RegisterContextLLDBSP
-UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num)
-{
- RegisterContextLLDBSP reg_ctx_sp;
- if (frame_num < m_frames.size())
- reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
- return reg_ctx_sp;
+UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) {
+ RegisterContextLLDBSP reg_ctx_sp;
+ if (frame_num < m_frames.size())
+ reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
+ return reg_ctx_sp;
}
-bool
-UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num, bool pc_reg)
-{
- int64_t frame_num = starting_frame_num;
- if (static_cast<size_t>(frame_num) >= m_frames.size())
- return false;
-
- // Never interrogate more than one level while looking for the saved pc value. If the value
- // isn't saved by frame_num, none of the frames lower on the stack will have a useful value.
- if (pc_reg)
- {
- 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;
- }
- while (frame_num >= 0)
- {
- UnwindLLDB::RegisterSearchResult result;
- result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
-
- // We descended down to the live register context aka stack frame 0 and are reading the value
- // out of a live register.
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
- && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext)
- {
- return true;
- }
+bool UnwindLLDB::SearchForSavedLocationForRegister(
+ uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
+ uint32_t starting_frame_num, bool pc_reg) {
+ int64_t frame_num = starting_frame_num;
+ if (static_cast<size_t>(frame_num) >= m_frames.size())
+ return false;
- // If we have unwind instructions saying that register N is saved in register M in the middle of
- // the stack (and N can equal M here, meaning the register was not used in this function), then
- // change the register number we're looking for to M and keep looking for a concrete location
- // down the stack, or an actual value from a live RegisterContext at frame 0.
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
- && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister
- && frame_num > 0)
- {
- result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- lldb_regnum = regloc.location.register_number;
- }
+ // Never interrogate more than one level while looking for the saved pc value.
+ // If the value
+ // isn't saved by frame_num, none of the frames lower on the stack will have a
+ // useful value.
+ if (pc_reg) {
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
+ lldb_regnum, regloc);
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
+ return true;
+ else
+ return false;
+ }
+ while (frame_num >= 0) {
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
+ lldb_regnum, regloc);
+
+ // We descended down to the live register context aka stack frame 0 and are
+ // reading the value
+ // out of a live register.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
+ regloc.type ==
+ UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) {
+ return true;
+ }
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- return true;
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
- return false;
- frame_num--;
+ // If we have unwind instructions saying that register N is saved in
+ // register M in the middle of
+ // the stack (and N can equal M here, meaning the register was not used in
+ // this function), then
+ // change the register number we're looking for to M and keep looking for a
+ // concrete location
+ // down the stack, or an actual value from a live RegisterContext at frame
+ // 0.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
+ regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister &&
+ frame_num > 0) {
+ result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ lldb_regnum = regloc.location.register_number;
}
- return false;
+
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
+ return true;
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
+ return false;
+ frame_num--;
+ }
+ return false;
}
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h
index d3c07078759b..b9323032180d 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -16,148 +16,150 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/lldb-public.h"
namespace lldb_private {
class RegisterContextLLDB;
-class UnwindLLDB : public lldb_private::Unwind
-{
-public:
- UnwindLLDB (lldb_private::Thread &thread);
+class UnwindLLDB : public lldb_private::Unwind {
+public:
+ UnwindLLDB(lldb_private::Thread &thread);
- ~UnwindLLDB() override = default;
+ ~UnwindLLDB() override = default;
- enum RegisterSearchResult
- {
- eRegisterFound = 0,
- eRegisterNotFound,
- eRegisterIsVolatile
- };
+ enum RegisterSearchResult {
+ eRegisterFound = 0,
+ eRegisterNotFound,
+ eRegisterIsVolatile
+ };
protected:
- friend class lldb_private::RegisterContextLLDB;
-
- struct RegisterLocation {
- enum RegisterLocationTypes
- {
- eRegisterNotSaved = 0, // register was not preserved by callee. If volatile reg, is unavailable
- eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
- eRegisterInRegister, // register is available in a (possible other) register (register_number)
- eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
- eRegisterValueInferred, // register val was computed (and is in inferred_value)
- eRegisterInLiveRegisterContext // register value is in a live (stack frame #0) register
- };
- int type;
- union
- {
- lldb::addr_t target_memory_location;
- uint32_t register_number; // in eRegisterKindLLDB register numbering system
- void* host_memory_location;
- uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset
- } location;
+ friend class lldb_private::RegisterContextLLDB;
+
+ struct RegisterLocation {
+ enum RegisterLocationTypes {
+ eRegisterNotSaved = 0, // register was not preserved by callee. If
+ // volatile reg, is unavailable
+ eRegisterSavedAtMemoryLocation, // register is saved at a specific word of
+ // target mem (target_memory_location)
+ eRegisterInRegister, // register is available in a (possible other)
+ // register (register_number)
+ eRegisterSavedAtHostMemoryLocation, // register is saved at a word in
+ // lldb's address space
+ eRegisterValueInferred, // register val was computed (and is in
+ // inferred_value)
+ eRegisterInLiveRegisterContext // register value is in a live (stack frame
+ // #0) register
};
+ int type;
+ union {
+ lldb::addr_t target_memory_location;
+ uint32_t
+ register_number; // in eRegisterKindLLDB register numbering system
+ void *host_memory_location;
+ uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer ==
+ // cfa + offset
+ } location;
+ };
+
+ void DoClear() override {
+ m_frames.clear();
+ m_candidate_frame.reset();
+ m_unwind_complete = false;
+ }
+
+ uint32_t DoGetFrameCount() override;
+
+ bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &start_pc) override;
+
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+ typedef std::shared_ptr<RegisterContextLLDB> RegisterContextLLDBSP;
+
+ // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame
+ // 1's RegisterContextLLDB)
+ // The RegisterContext for frame_num must already exist or this returns an
+ // empty shared pointer.
+ RegisterContextLLDBSP GetRegisterContextForFrameNum(uint32_t frame_num);
+
+ // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the
+ // first one that
+ // has a saved location for this reg.
+ bool SearchForSavedLocationForRegister(
+ uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
+ uint32_t starting_frame_num, bool pc_register);
+
+ //------------------------------------------------------------------
+ /// Provide the list of user-specified trap handler functions
+ ///
+ /// The Platform is one source of trap handler function names; that
+ /// may be augmented via a setting. The setting needs to be converted
+ /// into an array of ConstStrings before it can be used - we only want
+ /// to do that once per thread so it's here in the UnwindLLDB object.
+ ///
+ /// @return
+ /// Vector of ConstStrings of trap handler function names. May be
+ /// empty.
+ //------------------------------------------------------------------
+ const std::vector<ConstString> &GetUserSpecifiedTrapHandlerFunctionNames() {
+ return m_user_supplied_trap_handler_functions;
+ }
- void
- DoClear() override
- {
- m_frames.clear();
- m_candidate_frame.reset();
- m_unwind_complete = false;
- }
-
- uint32_t
- DoGetFrameCount() override;
-
- bool
- DoGetFrameInfoAtIndex(uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& start_pc) override;
-
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- typedef std::shared_ptr<RegisterContextLLDB> RegisterContextLLDBSP;
-
- // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame 1's RegisterContextLLDB)
- // The RegisterContext for frame_num must already exist or this returns an empty shared pointer.
+private:
+ struct Cursor {
+ lldb::addr_t start_pc; // The start address of the function/symbol for this
+ // frame - current pc if unknown
+ lldb::addr_t cfa; // The canonical frame address for this stack frame
+ lldb_private::SymbolContext sctx; // A symbol context we'll contribute to &
+ // provide to the StackFrame creation
RegisterContextLLDBSP
- GetRegisterContextForFrameNum (uint32_t frame_num);
-
- // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the first one that
- // has a saved location for this reg.
- bool
- SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num, bool pc_register);
-
-
- //------------------------------------------------------------------
- /// Provide the list of user-specified trap handler functions
- ///
- /// The Platform is one source of trap handler function names; that
- /// may be augmented via a setting. The setting needs to be converted
- /// into an array of ConstStrings before it can be used - we only want
- /// to do that once per thread so it's here in the UnwindLLDB object.
- ///
- /// @return
- /// Vector of ConstStrings of trap handler function names. May be
- /// empty.
- //------------------------------------------------------------------
- const std::vector<ConstString> &
- GetUserSpecifiedTrapHandlerFunctionNames ()
- {
- return m_user_supplied_trap_handler_functions;
- }
+ reg_ctx_lldb_sp; // These are all RegisterContextLLDB's
-private:
- struct Cursor
- {
- lldb::addr_t start_pc; // The start address of the function/symbol for this frame - current pc if unknown
- lldb::addr_t cfa; // The canonical frame address for this stack frame
- lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & provide to the StackFrame creation
- RegisterContextLLDBSP reg_ctx_lldb_sp; // These are all RegisterContextLLDB's
-
- Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx_lldb_sp() { }
- private:
- DISALLOW_COPY_AND_ASSIGN (Cursor);
- };
+ Cursor()
+ : start_pc(LLDB_INVALID_ADDRESS), cfa(LLDB_INVALID_ADDRESS), sctx(),
+ reg_ctx_lldb_sp() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Cursor);
+ };
+
+ typedef std::shared_ptr<Cursor> CursorSP;
+ std::vector<CursorSP> m_frames;
+ CursorSP m_candidate_frame;
+ bool m_unwind_complete; // If this is true, we've enumerated all the frames in
+ // the stack, and m_frames.size() is the
+ // number of frames, etc. Otherwise we've only gone as far as directly asked,
+ // and m_frames.size()
+ // is how far we've currently gone.
+
+ std::vector<ConstString> m_user_supplied_trap_handler_functions;
+
+ //-----------------------------------------------------------------
+ // Check if Full UnwindPlan of First frame is valid or not.
+ // If not then try Fallback UnwindPlan of the frame. If Fallback
+ // UnwindPlan succeeds then update the Full UnwindPlan with the
+ // Fallback UnwindPlan.
+ //-----------------------------------------------------------------
+ void UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi);
+
+ CursorSP GetOneMoreFrame(ABI *abi);
+
+ bool AddOneMoreFrame(ABI *abi);
+
+ bool AddFirstFrame();
- typedef std::shared_ptr<Cursor> CursorSP;
- std::vector<CursorSP> m_frames;
- CursorSP m_candidate_frame;
- bool m_unwind_complete; // If this is true, we've enumerated all the frames in the stack, and m_frames.size() is the
- // number of frames, etc. Otherwise we've only gone as far as directly asked, and m_frames.size()
- // is how far we've currently gone.
-
- std::vector<ConstString> m_user_supplied_trap_handler_functions;
-
- //-----------------------------------------------------------------
- // Check if Full UnwindPlan of First frame is valid or not.
- // If not then try Fallback UnwindPlan of the frame. If Fallback
- // UnwindPlan succeeds then update the Full UnwindPlan with the
- // Fallback UnwindPlan.
- //-----------------------------------------------------------------
- void
- UpdateUnwindPlanForFirstFrameIfInvalid (ABI* abi);
-
- CursorSP
- GetOneMoreFrame (ABI* abi);
-
- bool
- AddOneMoreFrame (ABI *abi);
-
- bool
- AddFirstFrame ();
-
- //------------------------------------------------------------------
- // For UnwindLLDB only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (UnwindLLDB);
+ //------------------------------------------------------------------
+ // For UnwindLLDB only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(UnwindLLDB);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index d011314b0963..e2691be603ec 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -13,8 +13,8 @@
// Project includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -25,251 +25,230 @@
using namespace lldb;
using namespace lldb_private;
-UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain (Thread &thread) :
- Unwind (thread),
- m_cursors()
-{
-}
-
-uint32_t
-UnwindMacOSXFrameBackchain::DoGetFrameCount()
-{
- if (m_cursors.empty())
- {
- ExecutionContext exe_ctx (m_thread.shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- const ArchSpec& target_arch = target->GetArchitecture ();
- // Frame zero should always be supplied by the thread...
- exe_ctx.SetFrameSP (m_thread.GetStackFrameAtIndex (0));
-
- if (target_arch.GetAddressByteSize() == 8)
- GetStackFrameData_x86_64 (exe_ctx);
- else
- GetStackFrameData_i386 (exe_ctx);
- }
+UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain(Thread &thread)
+ : Unwind(thread), m_cursors() {}
+
+uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() {
+ if (m_cursors.empty()) {
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ const ArchSpec &target_arch = target->GetArchitecture();
+ // Frame zero should always be supplied by the thread...
+ exe_ctx.SetFrameSP(m_thread.GetStackFrameAtIndex(0));
+
+ if (target_arch.GetAddressByteSize() == 8)
+ GetStackFrameData_x86_64(exe_ctx);
+ else
+ GetStackFrameData_i386(exe_ctx);
}
- return m_cursors.size();
+ }
+ return m_cursors.size();
}
-bool
-UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
-{
- const uint32_t frame_count = GetFrameCount();
- if (idx < frame_count)
- {
- if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
- return false;
- if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS)
- return false;
-
- pc = m_cursors[idx].pc;
- cfa = m_cursors[idx].fp;
-
- return true;
- }
- return false;
+bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
+ addr_t &cfa,
+ addr_t &pc) {
+ const uint32_t frame_count = GetFrameCount();
+ if (idx < frame_count) {
+ if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
+ return false;
+ if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS)
+ return false;
+
+ pc = m_cursors[idx].pc;
+ cfa = m_cursors[idx].fp;
+
+ return true;
+ }
+ return false;
}
-
+
lldb::RegisterContextSP
-UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_idx = frame->GetConcreteFrameIndex ();
- const uint32_t frame_count = GetFrameCount();
- if (concrete_idx < frame_count)
- reg_ctx_sp.reset (new RegisterContextMacOSXFrameBackchain (m_thread, concrete_idx, m_cursors[concrete_idx]));
- return reg_ctx_sp;
+UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_idx = frame->GetConcreteFrameIndex();
+ const uint32_t frame_count = GetFrameCount();
+ if (concrete_idx < frame_count)
+ reg_ctx_sp.reset(new RegisterContextMacOSXFrameBackchain(
+ m_thread, concrete_idx, m_cursors[concrete_idx]));
+ return reg_ctx_sp;
}
-size_t
-UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (const ExecutionContext &exe_ctx)
-{
- m_cursors.clear();
-
- StackFrame *first_frame = exe_ctx.GetFramePtr();
-
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- return 0;
-
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
- struct Frame_i386
- {
- uint32_t fp;
- uint32_t pc;
- };
-
- RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
- assert (reg_ctx);
-
- Cursor cursor;
- cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS);
- cursor.fp = reg_ctx->GetFP (0);
-
- Frame_i386 frame = { static_cast<uint32_t>(cursor.fp), static_cast<uint32_t>(cursor.pc) };
-
- m_cursors.push_back(cursor);
-
- const size_t k_frame_size = sizeof(frame);
- Error error;
- while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
- {
- // Read both the FP and PC (8 bytes)
- if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
- break;
- if (frame.pc >= 0x1000)
- {
- cursor.pc = frame.pc;
- cursor.fp = frame.fp;
- m_cursors.push_back (cursor);
- }
+size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
+ const ExecutionContext &exe_ctx) {
+ m_cursors.clear();
+
+ StackFrame *first_frame = exe_ctx.GetFramePtr();
+
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process == NULL)
+ return 0;
+
+ std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
+
+ struct Frame_i386 {
+ uint32_t fp;
+ uint32_t pc;
+ };
+
+ RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
+ assert(reg_ctx);
+
+ Cursor cursor;
+ cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
+ cursor.fp = reg_ctx->GetFP(0);
+
+ Frame_i386 frame = {static_cast<uint32_t>(cursor.fp),
+ static_cast<uint32_t>(cursor.pc)};
+
+ m_cursors.push_back(cursor);
+
+ const size_t k_frame_size = sizeof(frame);
+ Error error;
+ while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
+ // Read both the FP and PC (8 bytes)
+ if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
+ k_frame_size)
+ break;
+ if (frame.pc >= 0x1000) {
+ cursor.pc = frame.pc;
+ cursor.fp = frame.fp;
+ m_cursors.push_back(cursor);
}
- 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 = eSymbolContextModule |
- eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextSymbol;
-
- SymbolContext first_frame_sc (first_frame->GetSymbolContext(resolve_scope));
- const AddressRange *addr_range_ptr = NULL;
- AddressRange range;
- if (first_frame_sc.function)
- addr_range_ptr = &first_frame_sc.function->GetAddressRange();
- else if (first_frame_sc.symbol)
- {
- range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
- range.SetByteSize (first_frame_sc.symbol->GetByteSize());
- addr_range_ptr = &range;
- }
-
- if (addr_range_ptr)
- {
- if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress())
- {
- // We are at the first instruction, so we can recover the
- // previous PC by dereferencing the SP
- lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
- // Read the real second frame return address into frame.pc
- if (first_frame_sp && process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
- {
- cursor.fp = m_cursors.front().fp;
- cursor.pc = frame.pc; // Set the new second frame PC
-
- // Insert the second frame
- m_cursors.insert(m_cursors.begin()+1, cursor);
-
- m_cursors.front().fp = first_frame_sp;
- }
- }
- }
+ }
+ 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 =
+ eSymbolContextModule | eSymbolContextCompUnit |
+ eSymbolContextFunction | eSymbolContextSymbol;
+
+ SymbolContext first_frame_sc(
+ first_frame->GetSymbolContext(resolve_scope));
+ const AddressRange *addr_range_ptr = NULL;
+ AddressRange range;
+ if (first_frame_sc.function)
+ addr_range_ptr = &first_frame_sc.function->GetAddressRange();
+ else if (first_frame_sc.symbol) {
+ range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
+ range.SetByteSize(first_frame_sc.symbol->GetByteSize());
+ addr_range_ptr = &range;
+ }
+
+ if (addr_range_ptr) {
+ if (first_frame->GetFrameCodeAddress() ==
+ addr_range_ptr->GetBaseAddress()) {
+ // We are at the first instruction, so we can recover the
+ // previous PC by dereferencing the SP
+ lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
+ // Read the real second frame return address into frame.pc
+ if (first_frame_sp &&
+ process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
+ error) == sizeof(frame.pc)) {
+ cursor.fp = m_cursors.front().fp;
+ cursor.pc = frame.pc; // Set the new second frame PC
+
+ // Insert the second frame
+ m_cursors.insert(m_cursors.begin() + 1, cursor);
+
+ m_cursors.front().fp = first_frame_sp;
+ }
}
+ }
}
-// uint32_t i=0;
-// printf(" PC FP\n");
-// printf(" ------------------ ------------------ \n");
-// for (i=0; i<m_cursors.size(); ++i)
-// {
-// printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i, m_cursors[i].pc, m_cursors[i].fp);
-// }
- return m_cursors.size();
+ }
+ // uint32_t i=0;
+ // printf(" PC FP\n");
+ // printf(" ------------------ ------------------ \n");
+ // for (i=0; i<m_cursors.size(); ++i)
+ // {
+ // printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i,
+ // m_cursors[i].pc, m_cursors[i].fp);
+ // }
+ return m_cursors.size();
}
+size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
+ const ExecutionContext &exe_ctx) {
+ m_cursors.clear();
-size_t
-UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (const ExecutionContext &exe_ctx)
-{
- m_cursors.clear();
-
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- return 0;
-
- StackFrame *first_frame = exe_ctx.GetFramePtr();
-
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
- struct Frame_x86_64
- {
- uint64_t fp;
- uint64_t pc;
- };
-
- RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
- assert (reg_ctx);
-
- Cursor cursor;
- cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS);
- cursor.fp = reg_ctx->GetFP (0);
-
- Frame_x86_64 frame = { cursor.fp, cursor.pc };
-
- m_cursors.push_back(cursor);
- Error error;
- const size_t k_frame_size = sizeof(frame);
- while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
- {
- // Read both the FP and PC (16 bytes)
- if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
- break;
-
- if (frame.pc >= 0x1000)
- {
- cursor.pc = frame.pc;
- cursor.fp = frame.fp;
- m_cursors.push_back (cursor);
- }
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process == NULL)
+ return 0;
+
+ StackFrame *first_frame = exe_ctx.GetFramePtr();
+
+ std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
+
+ struct Frame_x86_64 {
+ uint64_t fp;
+ uint64_t pc;
+ };
+
+ RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
+ assert(reg_ctx);
+
+ Cursor cursor;
+ cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
+ cursor.fp = reg_ctx->GetFP(0);
+
+ Frame_x86_64 frame = {cursor.fp, cursor.pc};
+
+ m_cursors.push_back(cursor);
+ Error error;
+ const size_t k_frame_size = sizeof(frame);
+ while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
+ // Read both the FP and PC (16 bytes)
+ if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
+ k_frame_size)
+ break;
+
+ if (frame.pc >= 0x1000) {
+ cursor.pc = frame.pc;
+ cursor.fp = frame.fp;
+ m_cursors.push_back(cursor);
}
- 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 = eSymbolContextModule |
- eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextSymbol;
-
- SymbolContext first_frame_sc(first_frame->GetSymbolContext(resolve_scope));
- const AddressRange *addr_range_ptr = NULL;
- AddressRange range;
- if (first_frame_sc.function)
- addr_range_ptr = &first_frame_sc.function->GetAddressRange();
- else if (first_frame_sc.symbol)
- {
- range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
- range.SetByteSize (first_frame_sc.symbol->GetByteSize());
- addr_range_ptr = &range;
- }
-
- if (addr_range_ptr)
- {
- if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress())
- {
- // We are at the first instruction, so we can recover the
- // previous PC by dereferencing the SP
- lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
- // Read the real second frame return address into frame.pc
- if (process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
- {
- cursor.fp = m_cursors.front().fp;
- cursor.pc = frame.pc; // Set the new second frame PC
-
- // Insert the second frame
- m_cursors.insert(m_cursors.begin()+1, cursor);
-
- m_cursors.front().fp = first_frame_sp;
- }
- }
- }
+ }
+ 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 =
+ eSymbolContextModule | eSymbolContextCompUnit |
+ eSymbolContextFunction | eSymbolContextSymbol;
+
+ SymbolContext first_frame_sc(
+ first_frame->GetSymbolContext(resolve_scope));
+ const AddressRange *addr_range_ptr = NULL;
+ AddressRange range;
+ if (first_frame_sc.function)
+ addr_range_ptr = &first_frame_sc.function->GetAddressRange();
+ else if (first_frame_sc.symbol) {
+ range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
+ range.SetByteSize(first_frame_sc.symbol->GetByteSize());
+ addr_range_ptr = &range;
+ }
+
+ if (addr_range_ptr) {
+ if (first_frame->GetFrameCodeAddress() ==
+ addr_range_ptr->GetBaseAddress()) {
+ // We are at the first instruction, so we can recover the
+ // previous PC by dereferencing the SP
+ lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
+ // Read the real second frame return address into frame.pc
+ if (process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
+ error) == sizeof(frame.pc)) {
+ cursor.fp = m_cursors.front().fp;
+ cursor.pc = frame.pc; // Set the new second frame PC
+
+ // Insert the second frame
+ m_cursors.insert(m_cursors.begin() + 1, cursor);
+
+ m_cursors.front().fp = first_frame_sp;
+ }
}
+ }
}
- return m_cursors.size();
+ }
+ return m_cursors.size();
}
-
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
index f195514ed1ba..328117a306ef 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
@@ -16,55 +16,45 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/lldb-private.h"
-class UnwindMacOSXFrameBackchain : public lldb_private::Unwind
-{
-public:
- UnwindMacOSXFrameBackchain (lldb_private::Thread &thread);
+class UnwindMacOSXFrameBackchain : public lldb_private::Unwind {
+public:
+ UnwindMacOSXFrameBackchain(lldb_private::Thread &thread);
- ~UnwindMacOSXFrameBackchain() override = default;
+ ~UnwindMacOSXFrameBackchain() override = default;
protected:
- void
- DoClear() override
- {
- m_cursors.clear();
- }
-
- uint32_t
- DoGetFrameCount() override;
-
- bool
- DoGetFrameInfoAtIndex(uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& pc) override;
-
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- friend class RegisterContextMacOSXFrameBackchain;
-
- struct Cursor
- {
- lldb::addr_t pc; // Program counter
- lldb::addr_t fp; // Frame pointer for us with backchain
- };
+ void DoClear() override { m_cursors.clear(); }
+
+ uint32_t DoGetFrameCount() override;
+
+ bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) override;
+
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+ friend class RegisterContextMacOSXFrameBackchain;
+
+ struct Cursor {
+ lldb::addr_t pc; // Program counter
+ lldb::addr_t fp; // Frame pointer for us with backchain
+ };
private:
- std::vector<Cursor> m_cursors;
+ std::vector<Cursor> m_cursors;
- size_t
- GetStackFrameData_i386 (const lldb_private::ExecutionContext &exe_ctx);
+ size_t GetStackFrameData_i386(const lldb_private::ExecutionContext &exe_ctx);
- size_t
- GetStackFrameData_x86_64 (const lldb_private::ExecutionContext &exe_ctx);
+ size_t
+ GetStackFrameData_x86_64(const lldb_private::ExecutionContext &exe_ctx);
- //------------------------------------------------------------------
- // For UnwindMacOSXFrameBackchain only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (UnwindMacOSXFrameBackchain);
+ //------------------------------------------------------------------
+ // For UnwindMacOSXFrameBackchain only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(UnwindMacOSXFrameBackchain);
};
#endif // lldb_UnwindMacOSXFrameBackchain_h_
diff --git a/source/Plugins/Process/Utility/lldb-arm-register-enums.h b/source/Plugins/Process/Utility/lldb-arm-register-enums.h
index 4d82c10a78ea..49473bb885f2 100644
--- a/source/Plugins/Process/Utility/lldb-arm-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-arm-register-enums.h
@@ -10,192 +10,193 @@
#ifndef lldb_arm_register_enums_h
#define lldb_arm_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all ARM registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_arm = 0,
- gpr_r0_arm = k_first_gpr_arm,
- gpr_r1_arm,
- gpr_r2_arm,
- gpr_r3_arm,
- gpr_r4_arm,
- gpr_r5_arm,
- gpr_r6_arm,
- gpr_r7_arm,
- gpr_r8_arm,
- gpr_r9_arm,
- gpr_r10_arm,
- gpr_r11_arm,
- gpr_r12_arm,
- gpr_r13_arm, gpr_sp_arm = gpr_r13_arm,
- gpr_r14_arm, gpr_lr_arm = gpr_r14_arm,
- gpr_r15_arm, gpr_pc_arm = gpr_r15_arm,
- gpr_cpsr_arm,
+//---------------------------------------------------------------------------
+// Internal codes for all ARM registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_arm = 0,
+ gpr_r0_arm = k_first_gpr_arm,
+ gpr_r1_arm,
+ gpr_r2_arm,
+ gpr_r3_arm,
+ gpr_r4_arm,
+ gpr_r5_arm,
+ gpr_r6_arm,
+ gpr_r7_arm,
+ gpr_r8_arm,
+ gpr_r9_arm,
+ gpr_r10_arm,
+ gpr_r11_arm,
+ gpr_r12_arm,
+ gpr_r13_arm,
+ gpr_sp_arm = gpr_r13_arm,
+ gpr_r14_arm,
+ gpr_lr_arm = gpr_r14_arm,
+ gpr_r15_arm,
+ gpr_pc_arm = gpr_r15_arm,
+ gpr_cpsr_arm,
- k_last_gpr_arm = gpr_cpsr_arm,
+ k_last_gpr_arm = gpr_cpsr_arm,
- k_first_fpr_arm,
- fpu_s0_arm = k_first_fpr_arm,
- fpu_s1_arm,
- fpu_s2_arm,
- fpu_s3_arm,
- fpu_s4_arm,
- fpu_s5_arm,
- fpu_s6_arm,
- fpu_s7_arm,
- fpu_s8_arm,
- fpu_s9_arm,
- fpu_s10_arm,
- fpu_s11_arm,
- fpu_s12_arm,
- fpu_s13_arm,
- fpu_s14_arm,
- fpu_s15_arm,
- fpu_s16_arm,
- fpu_s17_arm,
- fpu_s18_arm,
- fpu_s19_arm,
- fpu_s20_arm,
- fpu_s21_arm,
- fpu_s22_arm,
- fpu_s23_arm,
- fpu_s24_arm,
- fpu_s25_arm,
- fpu_s26_arm,
- fpu_s27_arm,
- fpu_s28_arm,
- fpu_s29_arm,
- fpu_s30_arm,
- fpu_s31_arm,
- fpu_fpscr_arm,
- fpu_d0_arm,
- fpu_d1_arm,
- fpu_d2_arm,
- fpu_d3_arm,
- fpu_d4_arm,
- fpu_d5_arm,
- fpu_d6_arm,
- fpu_d7_arm,
- fpu_d8_arm,
- fpu_d9_arm,
- fpu_d10_arm,
- fpu_d11_arm,
- fpu_d12_arm,
- fpu_d13_arm,
- fpu_d14_arm,
- fpu_d15_arm,
- fpu_d16_arm,
- fpu_d17_arm,
- fpu_d18_arm,
- fpu_d19_arm,
- fpu_d20_arm,
- fpu_d21_arm,
- fpu_d22_arm,
- fpu_d23_arm,
- fpu_d24_arm,
- fpu_d25_arm,
- fpu_d26_arm,
- fpu_d27_arm,
- fpu_d28_arm,
- fpu_d29_arm,
- fpu_d30_arm,
- fpu_d31_arm,
- fpu_q0_arm,
- fpu_q1_arm,
- fpu_q2_arm,
- fpu_q3_arm,
- fpu_q4_arm,
- fpu_q5_arm,
- fpu_q6_arm,
- fpu_q7_arm,
- fpu_q8_arm,
- fpu_q9_arm,
- fpu_q10_arm,
- fpu_q11_arm,
- fpu_q12_arm,
- fpu_q13_arm,
- fpu_q14_arm,
- fpu_q15_arm,
- k_last_fpr_arm = fpu_q15_arm,
- exc_exception_arm,
- exc_fsr_arm,
- exc_far_arm,
+ k_first_fpr_arm,
+ fpu_s0_arm = k_first_fpr_arm,
+ fpu_s1_arm,
+ fpu_s2_arm,
+ fpu_s3_arm,
+ fpu_s4_arm,
+ fpu_s5_arm,
+ fpu_s6_arm,
+ fpu_s7_arm,
+ fpu_s8_arm,
+ fpu_s9_arm,
+ fpu_s10_arm,
+ fpu_s11_arm,
+ fpu_s12_arm,
+ fpu_s13_arm,
+ fpu_s14_arm,
+ fpu_s15_arm,
+ fpu_s16_arm,
+ fpu_s17_arm,
+ fpu_s18_arm,
+ fpu_s19_arm,
+ fpu_s20_arm,
+ fpu_s21_arm,
+ fpu_s22_arm,
+ fpu_s23_arm,
+ fpu_s24_arm,
+ fpu_s25_arm,
+ fpu_s26_arm,
+ fpu_s27_arm,
+ fpu_s28_arm,
+ fpu_s29_arm,
+ fpu_s30_arm,
+ fpu_s31_arm,
+ fpu_fpscr_arm,
+ fpu_d0_arm,
+ fpu_d1_arm,
+ fpu_d2_arm,
+ fpu_d3_arm,
+ fpu_d4_arm,
+ fpu_d5_arm,
+ fpu_d6_arm,
+ fpu_d7_arm,
+ fpu_d8_arm,
+ fpu_d9_arm,
+ fpu_d10_arm,
+ fpu_d11_arm,
+ fpu_d12_arm,
+ fpu_d13_arm,
+ fpu_d14_arm,
+ fpu_d15_arm,
+ fpu_d16_arm,
+ fpu_d17_arm,
+ fpu_d18_arm,
+ fpu_d19_arm,
+ fpu_d20_arm,
+ fpu_d21_arm,
+ fpu_d22_arm,
+ fpu_d23_arm,
+ fpu_d24_arm,
+ fpu_d25_arm,
+ fpu_d26_arm,
+ fpu_d27_arm,
+ fpu_d28_arm,
+ fpu_d29_arm,
+ fpu_d30_arm,
+ fpu_d31_arm,
+ fpu_q0_arm,
+ fpu_q1_arm,
+ fpu_q2_arm,
+ fpu_q3_arm,
+ fpu_q4_arm,
+ fpu_q5_arm,
+ fpu_q6_arm,
+ fpu_q7_arm,
+ fpu_q8_arm,
+ fpu_q9_arm,
+ fpu_q10_arm,
+ fpu_q11_arm,
+ fpu_q12_arm,
+ fpu_q13_arm,
+ fpu_q14_arm,
+ fpu_q15_arm,
+ k_last_fpr_arm = fpu_q15_arm,
+ exc_exception_arm,
+ exc_fsr_arm,
+ exc_far_arm,
- dbg_bvr0_arm,
- dbg_bvr1_arm,
- dbg_bvr2_arm,
- dbg_bvr3_arm,
- dbg_bvr4_arm,
- dbg_bvr5_arm,
- dbg_bvr6_arm,
- dbg_bvr7_arm,
- dbg_bvr8_arm,
- dbg_bvr9_arm,
- dbg_bvr10_arm,
- dbg_bvr11_arm,
- dbg_bvr12_arm,
- dbg_bvr13_arm,
- dbg_bvr14_arm,
- dbg_bvr15_arm,
- dbg_bcr0_arm,
- dbg_bcr1_arm,
- dbg_bcr2_arm,
- dbg_bcr3_arm,
- dbg_bcr4_arm,
- dbg_bcr5_arm,
- dbg_bcr6_arm,
- dbg_bcr7_arm,
- dbg_bcr8_arm,
- dbg_bcr9_arm,
- dbg_bcr10_arm,
- dbg_bcr11_arm,
- dbg_bcr12_arm,
- dbg_bcr13_arm,
- dbg_bcr14_arm,
- dbg_bcr15_arm,
- dbg_wvr0_arm,
- dbg_wvr1_arm,
- dbg_wvr2_arm,
- dbg_wvr3_arm,
- dbg_wvr4_arm,
- dbg_wvr5_arm,
- dbg_wvr6_arm,
- dbg_wvr7_arm,
- dbg_wvr8_arm,
- dbg_wvr9_arm,
- dbg_wvr10_arm,
- dbg_wvr11_arm,
- dbg_wvr12_arm,
- dbg_wvr13_arm,
- dbg_wvr14_arm,
- dbg_wvr15_arm,
- dbg_wcr0_arm,
- dbg_wcr1_arm,
- dbg_wcr2_arm,
- dbg_wcr3_arm,
- dbg_wcr4_arm,
- dbg_wcr5_arm,
- dbg_wcr6_arm,
- dbg_wcr7_arm,
- dbg_wcr8_arm,
- dbg_wcr9_arm,
- dbg_wcr10_arm,
- dbg_wcr11_arm,
- dbg_wcr12_arm,
- dbg_wcr13_arm,
- dbg_wcr14_arm,
- dbg_wcr15_arm,
+ dbg_bvr0_arm,
+ dbg_bvr1_arm,
+ dbg_bvr2_arm,
+ dbg_bvr3_arm,
+ dbg_bvr4_arm,
+ dbg_bvr5_arm,
+ dbg_bvr6_arm,
+ dbg_bvr7_arm,
+ dbg_bvr8_arm,
+ dbg_bvr9_arm,
+ dbg_bvr10_arm,
+ dbg_bvr11_arm,
+ dbg_bvr12_arm,
+ dbg_bvr13_arm,
+ dbg_bvr14_arm,
+ dbg_bvr15_arm,
+ dbg_bcr0_arm,
+ dbg_bcr1_arm,
+ dbg_bcr2_arm,
+ dbg_bcr3_arm,
+ dbg_bcr4_arm,
+ dbg_bcr5_arm,
+ dbg_bcr6_arm,
+ dbg_bcr7_arm,
+ dbg_bcr8_arm,
+ dbg_bcr9_arm,
+ dbg_bcr10_arm,
+ dbg_bcr11_arm,
+ dbg_bcr12_arm,
+ dbg_bcr13_arm,
+ dbg_bcr14_arm,
+ dbg_bcr15_arm,
+ dbg_wvr0_arm,
+ dbg_wvr1_arm,
+ dbg_wvr2_arm,
+ dbg_wvr3_arm,
+ dbg_wvr4_arm,
+ dbg_wvr5_arm,
+ dbg_wvr6_arm,
+ dbg_wvr7_arm,
+ dbg_wvr8_arm,
+ dbg_wvr9_arm,
+ dbg_wvr10_arm,
+ dbg_wvr11_arm,
+ dbg_wvr12_arm,
+ dbg_wvr13_arm,
+ dbg_wvr14_arm,
+ dbg_wvr15_arm,
+ dbg_wcr0_arm,
+ dbg_wcr1_arm,
+ dbg_wcr2_arm,
+ dbg_wcr3_arm,
+ dbg_wcr4_arm,
+ dbg_wcr5_arm,
+ dbg_wcr6_arm,
+ dbg_wcr7_arm,
+ dbg_wcr8_arm,
+ dbg_wcr9_arm,
+ dbg_wcr10_arm,
+ dbg_wcr11_arm,
+ dbg_wcr12_arm,
+ dbg_wcr13_arm,
+ dbg_wcr14_arm,
+ dbg_wcr15_arm,
- k_num_registers_arm,
- k_num_gpr_registers_arm = k_last_gpr_arm - k_first_gpr_arm + 1,
- k_num_fpr_registers_arm = k_last_fpr_arm - k_first_fpr_arm + 1
- };
+ k_num_registers_arm,
+ k_num_gpr_registers_arm = k_last_gpr_arm - k_first_gpr_arm + 1,
+ k_num_fpr_registers_arm = k_last_fpr_arm - k_first_fpr_arm + 1
+};
}
#endif // #ifndef lldb_arm64_register_enums_h
diff --git a/source/Plugins/Process/Utility/lldb-arm64-register-enums.h b/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
index a0c0db0f2786..7181ce448195 100644
--- a/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
@@ -10,163 +10,258 @@
#ifndef lldb_arm64_register_enums_h
#define lldb_arm64_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all ARM64 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_arm64,
- gpr_x0_arm64 = k_first_gpr_arm64,
- gpr_x1_arm64,
- gpr_x2_arm64,
- gpr_x3_arm64,
- gpr_x4_arm64,
- gpr_x5_arm64,
- gpr_x6_arm64,
- gpr_x7_arm64,
- gpr_x8_arm64,
- gpr_x9_arm64,
- gpr_x10_arm64,
- gpr_x11_arm64,
- gpr_x12_arm64,
- gpr_x13_arm64,
- gpr_x14_arm64,
- gpr_x15_arm64,
- gpr_x16_arm64,
- gpr_x17_arm64,
- gpr_x18_arm64,
- gpr_x19_arm64,
- gpr_x20_arm64,
- gpr_x21_arm64,
- gpr_x22_arm64,
- gpr_x23_arm64,
- gpr_x24_arm64,
- gpr_x25_arm64,
- gpr_x26_arm64,
- gpr_x27_arm64,
- gpr_x28_arm64,
- gpr_fp_arm64,
- gpr_lr_arm64,
- gpr_sp_arm64,
- gpr_pc_arm64,
- gpr_cpsr_arm64,
+//---------------------------------------------------------------------------
+// Internal codes for all ARM64 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_arm64,
+ gpr_x0_arm64 = k_first_gpr_arm64,
+ gpr_x1_arm64,
+ gpr_x2_arm64,
+ gpr_x3_arm64,
+ gpr_x4_arm64,
+ gpr_x5_arm64,
+ gpr_x6_arm64,
+ gpr_x7_arm64,
+ gpr_x8_arm64,
+ gpr_x9_arm64,
+ gpr_x10_arm64,
+ gpr_x11_arm64,
+ gpr_x12_arm64,
+ gpr_x13_arm64,
+ gpr_x14_arm64,
+ gpr_x15_arm64,
+ gpr_x16_arm64,
+ gpr_x17_arm64,
+ gpr_x18_arm64,
+ gpr_x19_arm64,
+ gpr_x20_arm64,
+ gpr_x21_arm64,
+ gpr_x22_arm64,
+ gpr_x23_arm64,
+ gpr_x24_arm64,
+ gpr_x25_arm64,
+ gpr_x26_arm64,
+ gpr_x27_arm64,
+ gpr_x28_arm64,
+ gpr_fp_arm64,
+ gpr_lr_arm64,
+ gpr_sp_arm64,
+ gpr_pc_arm64,
+ gpr_cpsr_arm64,
- k_last_gpr_arm64 = gpr_cpsr_arm64,
+ gpr_w0_arm64,
+ gpr_w1_arm64,
+ gpr_w2_arm64,
+ gpr_w3_arm64,
+ gpr_w4_arm64,
+ gpr_w5_arm64,
+ gpr_w6_arm64,
+ gpr_w7_arm64,
+ gpr_w8_arm64,
+ gpr_w9_arm64,
+ gpr_w10_arm64,
+ gpr_w11_arm64,
+ gpr_w12_arm64,
+ gpr_w13_arm64,
+ gpr_w14_arm64,
+ gpr_w15_arm64,
+ gpr_w16_arm64,
+ gpr_w17_arm64,
+ gpr_w18_arm64,
+ gpr_w19_arm64,
+ gpr_w20_arm64,
+ gpr_w21_arm64,
+ gpr_w22_arm64,
+ gpr_w23_arm64,
+ gpr_w24_arm64,
+ gpr_w25_arm64,
+ gpr_w26_arm64,
+ gpr_w27_arm64,
+ gpr_w28_arm64,
- k_first_fpr_arm64,
- fpu_v0_arm64 = k_first_fpr_arm64,
- fpu_v1_arm64,
- fpu_v2_arm64,
- fpu_v3_arm64,
- fpu_v4_arm64,
- fpu_v5_arm64,
- fpu_v6_arm64,
- fpu_v7_arm64,
- fpu_v8_arm64,
- fpu_v9_arm64,
- fpu_v10_arm64,
- fpu_v11_arm64,
- fpu_v12_arm64,
- fpu_v13_arm64,
- fpu_v14_arm64,
- fpu_v15_arm64,
- fpu_v16_arm64,
- fpu_v17_arm64,
- fpu_v18_arm64,
- fpu_v19_arm64,
- fpu_v20_arm64,
- fpu_v21_arm64,
- fpu_v22_arm64,
- fpu_v23_arm64,
- fpu_v24_arm64,
- fpu_v25_arm64,
- fpu_v26_arm64,
- fpu_v27_arm64,
- fpu_v28_arm64,
- fpu_v29_arm64,
- fpu_v30_arm64,
- fpu_v31_arm64,
- fpu_fpsr_arm64,
- fpu_fpcr_arm64,
- k_last_fpr_arm64 = fpu_fpcr_arm64,
+ k_last_gpr_arm64 = gpr_w28_arm64,
- exc_far_arm64,
- exc_esr_arm64,
- exc_exception_arm64,
+ k_first_fpr_arm64,
+ fpu_v0_arm64 = k_first_fpr_arm64,
+ fpu_v1_arm64,
+ fpu_v2_arm64,
+ fpu_v3_arm64,
+ fpu_v4_arm64,
+ fpu_v5_arm64,
+ fpu_v6_arm64,
+ fpu_v7_arm64,
+ fpu_v8_arm64,
+ fpu_v9_arm64,
+ fpu_v10_arm64,
+ fpu_v11_arm64,
+ fpu_v12_arm64,
+ fpu_v13_arm64,
+ fpu_v14_arm64,
+ fpu_v15_arm64,
+ fpu_v16_arm64,
+ fpu_v17_arm64,
+ fpu_v18_arm64,
+ fpu_v19_arm64,
+ fpu_v20_arm64,
+ fpu_v21_arm64,
+ fpu_v22_arm64,
+ fpu_v23_arm64,
+ fpu_v24_arm64,
+ fpu_v25_arm64,
+ fpu_v26_arm64,
+ fpu_v27_arm64,
+ fpu_v28_arm64,
+ fpu_v29_arm64,
+ fpu_v30_arm64,
+ fpu_v31_arm64,
- dbg_bvr0_arm64,
- dbg_bvr1_arm64,
- dbg_bvr2_arm64,
- dbg_bvr3_arm64,
- dbg_bvr4_arm64,
- dbg_bvr5_arm64,
- dbg_bvr6_arm64,
- dbg_bvr7_arm64,
- dbg_bvr8_arm64,
- dbg_bvr9_arm64,
- dbg_bvr10_arm64,
- dbg_bvr11_arm64,
- dbg_bvr12_arm64,
- dbg_bvr13_arm64,
- dbg_bvr14_arm64,
- dbg_bvr15_arm64,
- dbg_bcr0_arm64,
- dbg_bcr1_arm64,
- dbg_bcr2_arm64,
- dbg_bcr3_arm64,
- dbg_bcr4_arm64,
- dbg_bcr5_arm64,
- dbg_bcr6_arm64,
- dbg_bcr7_arm64,
- dbg_bcr8_arm64,
- dbg_bcr9_arm64,
- dbg_bcr10_arm64,
- dbg_bcr11_arm64,
- dbg_bcr12_arm64,
- dbg_bcr13_arm64,
- dbg_bcr14_arm64,
- dbg_bcr15_arm64,
- dbg_wvr0_arm64,
- dbg_wvr1_arm64,
- dbg_wvr2_arm64,
- dbg_wvr3_arm64,
- dbg_wvr4_arm64,
- dbg_wvr5_arm64,
- dbg_wvr6_arm64,
- dbg_wvr7_arm64,
- dbg_wvr8_arm64,
- dbg_wvr9_arm64,
- dbg_wvr10_arm64,
- dbg_wvr11_arm64,
- dbg_wvr12_arm64,
- dbg_wvr13_arm64,
- dbg_wvr14_arm64,
- dbg_wvr15_arm64,
- dbg_wcr0_arm64,
- dbg_wcr1_arm64,
- dbg_wcr2_arm64,
- dbg_wcr3_arm64,
- dbg_wcr4_arm64,
- dbg_wcr5_arm64,
- dbg_wcr6_arm64,
- dbg_wcr7_arm64,
- dbg_wcr8_arm64,
- dbg_wcr9_arm64,
- dbg_wcr10_arm64,
- dbg_wcr11_arm64,
- dbg_wcr12_arm64,
- dbg_wcr13_arm64,
- dbg_wcr14_arm64,
- dbg_wcr15_arm64,
+ fpu_s0_arm64,
+ fpu_s1_arm64,
+ fpu_s2_arm64,
+ fpu_s3_arm64,
+ fpu_s4_arm64,
+ fpu_s5_arm64,
+ fpu_s6_arm64,
+ fpu_s7_arm64,
+ fpu_s8_arm64,
+ fpu_s9_arm64,
+ fpu_s10_arm64,
+ fpu_s11_arm64,
+ fpu_s12_arm64,
+ fpu_s13_arm64,
+ fpu_s14_arm64,
+ fpu_s15_arm64,
+ fpu_s16_arm64,
+ fpu_s17_arm64,
+ fpu_s18_arm64,
+ fpu_s19_arm64,
+ fpu_s20_arm64,
+ fpu_s21_arm64,
+ fpu_s22_arm64,
+ fpu_s23_arm64,
+ fpu_s24_arm64,
+ fpu_s25_arm64,
+ fpu_s26_arm64,
+ fpu_s27_arm64,
+ fpu_s28_arm64,
+ fpu_s29_arm64,
+ fpu_s30_arm64,
+ fpu_s31_arm64,
- k_num_registers_arm64,
- k_num_gpr_registers_arm64 = k_last_gpr_arm64 - k_first_gpr_arm64 + 1,
- k_num_fpr_registers_arm64 = k_last_fpr_arm64 - k_first_fpr_arm64 + 1
- };
+ fpu_d0_arm64,
+ fpu_d1_arm64,
+ fpu_d2_arm64,
+ fpu_d3_arm64,
+ fpu_d4_arm64,
+ fpu_d5_arm64,
+ fpu_d6_arm64,
+ fpu_d7_arm64,
+ fpu_d8_arm64,
+ fpu_d9_arm64,
+ fpu_d10_arm64,
+ fpu_d11_arm64,
+ fpu_d12_arm64,
+ fpu_d13_arm64,
+ fpu_d14_arm64,
+ fpu_d15_arm64,
+ fpu_d16_arm64,
+ fpu_d17_arm64,
+ fpu_d18_arm64,
+ fpu_d19_arm64,
+ fpu_d20_arm64,
+ fpu_d21_arm64,
+ fpu_d22_arm64,
+ fpu_d23_arm64,
+ fpu_d24_arm64,
+ fpu_d25_arm64,
+ fpu_d26_arm64,
+ fpu_d27_arm64,
+ fpu_d28_arm64,
+ fpu_d29_arm64,
+ fpu_d30_arm64,
+ fpu_d31_arm64,
+
+ fpu_fpsr_arm64,
+ fpu_fpcr_arm64,
+ k_last_fpr_arm64 = fpu_fpcr_arm64,
+
+ exc_far_arm64,
+ exc_esr_arm64,
+ exc_exception_arm64,
+
+ dbg_bvr0_arm64,
+ dbg_bvr1_arm64,
+ dbg_bvr2_arm64,
+ dbg_bvr3_arm64,
+ dbg_bvr4_arm64,
+ dbg_bvr5_arm64,
+ dbg_bvr6_arm64,
+ dbg_bvr7_arm64,
+ dbg_bvr8_arm64,
+ dbg_bvr9_arm64,
+ dbg_bvr10_arm64,
+ dbg_bvr11_arm64,
+ dbg_bvr12_arm64,
+ dbg_bvr13_arm64,
+ dbg_bvr14_arm64,
+ dbg_bvr15_arm64,
+ dbg_bcr0_arm64,
+ dbg_bcr1_arm64,
+ dbg_bcr2_arm64,
+ dbg_bcr3_arm64,
+ dbg_bcr4_arm64,
+ dbg_bcr5_arm64,
+ dbg_bcr6_arm64,
+ dbg_bcr7_arm64,
+ dbg_bcr8_arm64,
+ dbg_bcr9_arm64,
+ dbg_bcr10_arm64,
+ dbg_bcr11_arm64,
+ dbg_bcr12_arm64,
+ dbg_bcr13_arm64,
+ dbg_bcr14_arm64,
+ dbg_bcr15_arm64,
+ dbg_wvr0_arm64,
+ dbg_wvr1_arm64,
+ dbg_wvr2_arm64,
+ dbg_wvr3_arm64,
+ dbg_wvr4_arm64,
+ dbg_wvr5_arm64,
+ dbg_wvr6_arm64,
+ dbg_wvr7_arm64,
+ dbg_wvr8_arm64,
+ dbg_wvr9_arm64,
+ dbg_wvr10_arm64,
+ dbg_wvr11_arm64,
+ dbg_wvr12_arm64,
+ dbg_wvr13_arm64,
+ dbg_wvr14_arm64,
+ dbg_wvr15_arm64,
+ dbg_wcr0_arm64,
+ dbg_wcr1_arm64,
+ dbg_wcr2_arm64,
+ dbg_wcr3_arm64,
+ dbg_wcr4_arm64,
+ dbg_wcr5_arm64,
+ dbg_wcr6_arm64,
+ dbg_wcr7_arm64,
+ dbg_wcr8_arm64,
+ dbg_wcr9_arm64,
+ dbg_wcr10_arm64,
+ dbg_wcr11_arm64,
+ dbg_wcr12_arm64,
+ dbg_wcr13_arm64,
+ dbg_wcr14_arm64,
+ dbg_wcr15_arm64,
+
+ k_num_registers_arm64,
+ k_num_gpr_registers_arm64 = k_last_gpr_arm64 - k_first_gpr_arm64 + 1,
+ k_num_fpr_registers_arm64 = k_last_fpr_arm64 - k_first_fpr_arm64 + 1
+};
}
#endif // #ifndef lldb_arm64_register_enums_h
diff --git a/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
index 69dc9efac32b..61929365b736 100644
--- a/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
@@ -1,4 +1,4 @@
-//===-- lldb-mips-frebsd-register-enums.h -------------------------------*- C++ -*-===//
+//===-- lldb-mips-freebsd-register-enums.h ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,61 +10,59 @@
#ifndef lldb_mips_freebsd_register_enums_h
#define lldb_mips_freebsd_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all mips registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_mips64,
- gpr_zero_mips64 = k_first_gpr_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_ic_mips64,
- gpr_dummy_mips64,
- k_last_gpr_mips64 = gpr_dummy_mips64,
+//---------------------------------------------------------------------------
+// Internal codes for all mips registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_mips64,
+ gpr_zero_mips64 = k_first_gpr_mips64,
+ gpr_r1_mips64,
+ gpr_r2_mips64,
+ gpr_r3_mips64,
+ gpr_r4_mips64,
+ gpr_r5_mips64,
+ gpr_r6_mips64,
+ gpr_r7_mips64,
+ gpr_r8_mips64,
+ gpr_r9_mips64,
+ gpr_r10_mips64,
+ gpr_r11_mips64,
+ gpr_r12_mips64,
+ gpr_r13_mips64,
+ gpr_r14_mips64,
+ gpr_r15_mips64,
+ gpr_r16_mips64,
+ gpr_r17_mips64,
+ gpr_r18_mips64,
+ gpr_r19_mips64,
+ gpr_r20_mips64,
+ gpr_r21_mips64,
+ gpr_r22_mips64,
+ gpr_r23_mips64,
+ gpr_r24_mips64,
+ gpr_r25_mips64,
+ gpr_r26_mips64,
+ gpr_r27_mips64,
+ gpr_gp_mips64,
+ gpr_sp_mips64,
+ gpr_r30_mips64,
+ gpr_ra_mips64,
+ gpr_sr_mips64,
+ gpr_mullo_mips64,
+ gpr_mulhi_mips64,
+ gpr_badvaddr_mips64,
+ gpr_cause_mips64,
+ gpr_pc_mips64,
+ gpr_ic_mips64,
+ gpr_dummy_mips64,
+ k_last_gpr_mips64 = gpr_dummy_mips64,
- k_num_registers_mips64,
+ k_num_registers_mips64,
- k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1
- };
+ k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1
+};
}
#endif // #ifndef lldb_mips_freebsd_register_enums_h
diff --git a/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
index 46ebf4ba06e3..0ecf3e366db0 100644
--- a/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
@@ -1,4 +1,5 @@
-//===-- lldb-mips-linux-register-enums.h -------------------------------*- C++ -*-===//
+//===-- lldb-mips-linux-register-enums.h -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,276 +11,277 @@
#ifndef lldb_mips_linux_register_enums_h
#define lldb_mips_linux_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all mips registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_mips,
- gpr_zero_mips = k_first_gpr_mips,
- gpr_r1_mips,
- gpr_r2_mips,
- gpr_r3_mips,
- gpr_r4_mips,
- gpr_r5_mips,
- gpr_r6_mips,
- gpr_r7_mips,
- gpr_r8_mips,
- gpr_r9_mips,
- gpr_r10_mips,
- gpr_r11_mips,
- gpr_r12_mips,
- gpr_r13_mips,
- gpr_r14_mips,
- gpr_r15_mips,
- gpr_r16_mips,
- gpr_r17_mips,
- gpr_r18_mips,
- gpr_r19_mips,
- gpr_r20_mips,
- gpr_r21_mips,
- gpr_r22_mips,
- gpr_r23_mips,
- gpr_r24_mips,
- gpr_r25_mips,
- gpr_r26_mips,
- gpr_r27_mips,
- gpr_gp_mips,
- gpr_sp_mips,
- gpr_r30_mips,
- gpr_ra_mips,
- gpr_sr_mips,
- gpr_mullo_mips,
- gpr_mulhi_mips,
- gpr_badvaddr_mips,
- gpr_cause_mips,
- gpr_pc_mips,
- gpr_config5_mips,
+//---------------------------------------------------------------------------
+// Internal codes for all mips registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_mips,
+ gpr_zero_mips = k_first_gpr_mips,
+ gpr_r1_mips,
+ gpr_r2_mips,
+ gpr_r3_mips,
+ gpr_r4_mips,
+ gpr_r5_mips,
+ gpr_r6_mips,
+ gpr_r7_mips,
+ gpr_r8_mips,
+ gpr_r9_mips,
+ gpr_r10_mips,
+ gpr_r11_mips,
+ gpr_r12_mips,
+ gpr_r13_mips,
+ gpr_r14_mips,
+ gpr_r15_mips,
+ gpr_r16_mips,
+ gpr_r17_mips,
+ gpr_r18_mips,
+ gpr_r19_mips,
+ gpr_r20_mips,
+ gpr_r21_mips,
+ gpr_r22_mips,
+ gpr_r23_mips,
+ gpr_r24_mips,
+ gpr_r25_mips,
+ gpr_r26_mips,
+ gpr_r27_mips,
+ gpr_gp_mips,
+ gpr_sp_mips,
+ gpr_r30_mips,
+ gpr_ra_mips,
+ gpr_sr_mips,
+ gpr_mullo_mips,
+ gpr_mulhi_mips,
+ gpr_badvaddr_mips,
+ gpr_cause_mips,
+ gpr_pc_mips,
+ gpr_config5_mips,
- k_last_gpr_mips = gpr_config5_mips,
+ k_last_gpr_mips = gpr_config5_mips,
- k_first_fpr_mips,
- fpr_f0_mips = k_first_fpr_mips,
- fpr_f1_mips,
- fpr_f2_mips,
- fpr_f3_mips,
- fpr_f4_mips,
- fpr_f5_mips,
- fpr_f6_mips,
- fpr_f7_mips,
- fpr_f8_mips,
- fpr_f9_mips,
- fpr_f10_mips,
- fpr_f11_mips,
- fpr_f12_mips,
- fpr_f13_mips,
- fpr_f14_mips,
- fpr_f15_mips,
- fpr_f16_mips,
- fpr_f17_mips,
- fpr_f18_mips,
- fpr_f19_mips,
- fpr_f20_mips,
- fpr_f21_mips,
- fpr_f22_mips,
- fpr_f23_mips,
- fpr_f24_mips,
- fpr_f25_mips,
- fpr_f26_mips,
- fpr_f27_mips,
- fpr_f28_mips,
- fpr_f29_mips,
- fpr_f30_mips,
- fpr_f31_mips,
- fpr_fcsr_mips,
- fpr_fir_mips,
- fpr_config5_mips,
- k_last_fpr_mips = fpr_config5_mips,
+ k_first_fpr_mips,
+ fpr_f0_mips = k_first_fpr_mips,
+ fpr_f1_mips,
+ fpr_f2_mips,
+ fpr_f3_mips,
+ fpr_f4_mips,
+ fpr_f5_mips,
+ fpr_f6_mips,
+ fpr_f7_mips,
+ fpr_f8_mips,
+ fpr_f9_mips,
+ fpr_f10_mips,
+ fpr_f11_mips,
+ fpr_f12_mips,
+ fpr_f13_mips,
+ fpr_f14_mips,
+ fpr_f15_mips,
+ fpr_f16_mips,
+ fpr_f17_mips,
+ fpr_f18_mips,
+ fpr_f19_mips,
+ fpr_f20_mips,
+ fpr_f21_mips,
+ fpr_f22_mips,
+ fpr_f23_mips,
+ fpr_f24_mips,
+ fpr_f25_mips,
+ fpr_f26_mips,
+ fpr_f27_mips,
+ fpr_f28_mips,
+ fpr_f29_mips,
+ fpr_f30_mips,
+ fpr_f31_mips,
+ fpr_fcsr_mips,
+ fpr_fir_mips,
+ fpr_config5_mips,
+ k_last_fpr_mips = fpr_config5_mips,
- k_first_msa_mips,
- msa_w0_mips = k_first_msa_mips,
- msa_w1_mips,
- msa_w2_mips,
- msa_w3_mips,
- msa_w4_mips,
- msa_w5_mips,
- msa_w6_mips,
- msa_w7_mips,
- msa_w8_mips,
- msa_w9_mips,
- msa_w10_mips,
- msa_w11_mips,
- msa_w12_mips,
- msa_w13_mips,
- msa_w14_mips,
- msa_w15_mips,
- msa_w16_mips,
- msa_w17_mips,
- msa_w18_mips,
- msa_w19_mips,
- msa_w20_mips,
- msa_w21_mips,
- msa_w22_mips,
- msa_w23_mips,
- msa_w24_mips,
- msa_w25_mips,
- msa_w26_mips,
- msa_w27_mips,
- msa_w28_mips,
- msa_w29_mips,
- msa_w30_mips,
- msa_w31_mips,
- msa_fcsr_mips,
- msa_fir_mips,
- msa_mcsr_mips,
- msa_mir_mips,
- msa_config5_mips,
- k_last_msa_mips = msa_config5_mips,
+ k_first_msa_mips,
+ msa_w0_mips = k_first_msa_mips,
+ msa_w1_mips,
+ msa_w2_mips,
+ msa_w3_mips,
+ msa_w4_mips,
+ msa_w5_mips,
+ msa_w6_mips,
+ msa_w7_mips,
+ msa_w8_mips,
+ msa_w9_mips,
+ msa_w10_mips,
+ msa_w11_mips,
+ msa_w12_mips,
+ msa_w13_mips,
+ msa_w14_mips,
+ msa_w15_mips,
+ msa_w16_mips,
+ msa_w17_mips,
+ msa_w18_mips,
+ msa_w19_mips,
+ msa_w20_mips,
+ msa_w21_mips,
+ msa_w22_mips,
+ msa_w23_mips,
+ msa_w24_mips,
+ msa_w25_mips,
+ msa_w26_mips,
+ msa_w27_mips,
+ msa_w28_mips,
+ msa_w29_mips,
+ msa_w30_mips,
+ msa_w31_mips,
+ msa_fcsr_mips,
+ msa_fir_mips,
+ msa_mcsr_mips,
+ msa_mir_mips,
+ msa_config5_mips,
+ k_last_msa_mips = msa_config5_mips,
- k_num_registers_mips,
+ k_num_registers_mips,
- k_num_gpr_registers_mips = k_last_gpr_mips - k_first_gpr_mips + 1,
- k_num_fpr_registers_mips = k_last_fpr_mips - k_first_fpr_mips + 1,
- k_num_msa_registers_mips = k_last_msa_mips - k_first_msa_mips + 1,
- k_num_user_registers_mips = k_num_gpr_registers_mips + k_num_fpr_registers_mips + k_num_msa_registers_mips
- };
+ k_num_gpr_registers_mips = k_last_gpr_mips - k_first_gpr_mips + 1,
+ k_num_fpr_registers_mips = k_last_fpr_mips - k_first_fpr_mips + 1,
+ k_num_msa_registers_mips = k_last_msa_mips - k_first_msa_mips + 1,
+ k_num_user_registers_mips = k_num_gpr_registers_mips +
+ k_num_fpr_registers_mips +
+ k_num_msa_registers_mips
+};
- //---------------------------------------------------------------------------
- // Internal codes for all mips64 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_mips64,
- gpr_zero_mips64 = k_first_gpr_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_config5_mips64,
- k_last_gpr_mips64 = gpr_config5_mips64,
+//---------------------------------------------------------------------------
+// Internal codes for all mips64 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_mips64,
+ gpr_zero_mips64 = k_first_gpr_mips64,
+ gpr_r1_mips64,
+ gpr_r2_mips64,
+ gpr_r3_mips64,
+ gpr_r4_mips64,
+ gpr_r5_mips64,
+ gpr_r6_mips64,
+ gpr_r7_mips64,
+ gpr_r8_mips64,
+ gpr_r9_mips64,
+ gpr_r10_mips64,
+ gpr_r11_mips64,
+ gpr_r12_mips64,
+ gpr_r13_mips64,
+ gpr_r14_mips64,
+ gpr_r15_mips64,
+ gpr_r16_mips64,
+ gpr_r17_mips64,
+ gpr_r18_mips64,
+ gpr_r19_mips64,
+ gpr_r20_mips64,
+ gpr_r21_mips64,
+ gpr_r22_mips64,
+ gpr_r23_mips64,
+ gpr_r24_mips64,
+ gpr_r25_mips64,
+ gpr_r26_mips64,
+ gpr_r27_mips64,
+ gpr_gp_mips64,
+ gpr_sp_mips64,
+ gpr_r30_mips64,
+ gpr_ra_mips64,
+ gpr_sr_mips64,
+ gpr_mullo_mips64,
+ gpr_mulhi_mips64,
+ gpr_badvaddr_mips64,
+ gpr_cause_mips64,
+ gpr_pc_mips64,
+ gpr_config5_mips64,
+ k_last_gpr_mips64 = gpr_config5_mips64,
- k_first_fpr_mips64,
- fpr_f0_mips64 = k_first_fpr_mips64,
- fpr_f1_mips64,
- fpr_f2_mips64,
- fpr_f3_mips64,
- fpr_f4_mips64,
- fpr_f5_mips64,
- fpr_f6_mips64,
- fpr_f7_mips64,
- fpr_f8_mips64,
- fpr_f9_mips64,
- fpr_f10_mips64,
- fpr_f11_mips64,
- fpr_f12_mips64,
- fpr_f13_mips64,
- fpr_f14_mips64,
- fpr_f15_mips64,
- fpr_f16_mips64,
- fpr_f17_mips64,
- fpr_f18_mips64,
- fpr_f19_mips64,
- fpr_f20_mips64,
- fpr_f21_mips64,
- fpr_f22_mips64,
- fpr_f23_mips64,
- fpr_f24_mips64,
- fpr_f25_mips64,
- fpr_f26_mips64,
- fpr_f27_mips64,
- fpr_f28_mips64,
- fpr_f29_mips64,
- fpr_f30_mips64,
- fpr_f31_mips64,
- fpr_fcsr_mips64,
- fpr_fir_mips64,
- fpr_config5_mips64,
- k_last_fpr_mips64 = fpr_config5_mips64,
+ k_first_fpr_mips64,
+ fpr_f0_mips64 = k_first_fpr_mips64,
+ fpr_f1_mips64,
+ fpr_f2_mips64,
+ fpr_f3_mips64,
+ fpr_f4_mips64,
+ fpr_f5_mips64,
+ fpr_f6_mips64,
+ fpr_f7_mips64,
+ fpr_f8_mips64,
+ fpr_f9_mips64,
+ fpr_f10_mips64,
+ fpr_f11_mips64,
+ fpr_f12_mips64,
+ fpr_f13_mips64,
+ fpr_f14_mips64,
+ fpr_f15_mips64,
+ fpr_f16_mips64,
+ fpr_f17_mips64,
+ fpr_f18_mips64,
+ fpr_f19_mips64,
+ fpr_f20_mips64,
+ fpr_f21_mips64,
+ fpr_f22_mips64,
+ fpr_f23_mips64,
+ fpr_f24_mips64,
+ fpr_f25_mips64,
+ fpr_f26_mips64,
+ fpr_f27_mips64,
+ fpr_f28_mips64,
+ fpr_f29_mips64,
+ fpr_f30_mips64,
+ fpr_f31_mips64,
+ fpr_fcsr_mips64,
+ fpr_fir_mips64,
+ fpr_config5_mips64,
+ k_last_fpr_mips64 = fpr_config5_mips64,
- k_first_msa_mips64,
- msa_w0_mips64 = k_first_msa_mips64,
- msa_w1_mips64,
- msa_w2_mips64,
- msa_w3_mips64,
- msa_w4_mips64,
- msa_w5_mips64,
- msa_w6_mips64,
- msa_w7_mips64,
- msa_w8_mips64,
- msa_w9_mips64,
- msa_w10_mips64,
- msa_w11_mips64,
- msa_w12_mips64,
- msa_w13_mips64,
- msa_w14_mips64,
- msa_w15_mips64,
- msa_w16_mips64,
- msa_w17_mips64,
- msa_w18_mips64,
- msa_w19_mips64,
- msa_w20_mips64,
- msa_w21_mips64,
- msa_w22_mips64,
- msa_w23_mips64,
- msa_w24_mips64,
- msa_w25_mips64,
- msa_w26_mips64,
- msa_w27_mips64,
- msa_w28_mips64,
- msa_w29_mips64,
- msa_w30_mips64,
- msa_w31_mips64,
- msa_fcsr_mips64,
- msa_fir_mips64,
- msa_mcsr_mips64,
- msa_mir_mips64,
- msa_config5_mips64,
- k_last_msa_mips64 = msa_config5_mips64,
+ k_first_msa_mips64,
+ msa_w0_mips64 = k_first_msa_mips64,
+ msa_w1_mips64,
+ msa_w2_mips64,
+ msa_w3_mips64,
+ msa_w4_mips64,
+ msa_w5_mips64,
+ msa_w6_mips64,
+ msa_w7_mips64,
+ msa_w8_mips64,
+ msa_w9_mips64,
+ msa_w10_mips64,
+ msa_w11_mips64,
+ msa_w12_mips64,
+ msa_w13_mips64,
+ msa_w14_mips64,
+ msa_w15_mips64,
+ msa_w16_mips64,
+ msa_w17_mips64,
+ msa_w18_mips64,
+ msa_w19_mips64,
+ msa_w20_mips64,
+ msa_w21_mips64,
+ msa_w22_mips64,
+ msa_w23_mips64,
+ msa_w24_mips64,
+ msa_w25_mips64,
+ msa_w26_mips64,
+ msa_w27_mips64,
+ msa_w28_mips64,
+ msa_w29_mips64,
+ msa_w30_mips64,
+ msa_w31_mips64,
+ msa_fcsr_mips64,
+ msa_fir_mips64,
+ msa_mcsr_mips64,
+ msa_mir_mips64,
+ msa_config5_mips64,
+ k_last_msa_mips64 = msa_config5_mips64,
- k_num_registers_mips64,
+ k_num_registers_mips64,
- k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1,
- k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1,
- k_num_msa_registers_mips64 = k_last_msa_mips64 - k_first_msa_mips64 + 1,
- k_num_user_registers_mips64 = k_num_gpr_registers_mips64 + k_num_fpr_registers_mips64 + k_num_msa_registers_mips64
- };
+ k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1,
+ k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1,
+ k_num_msa_registers_mips64 = k_last_msa_mips64 - k_first_msa_mips64 + 1,
+ k_num_user_registers_mips64 = k_num_gpr_registers_mips64 +
+ k_num_fpr_registers_mips64 +
+ k_num_msa_registers_mips64
+};
// Register no. for RegisterKind = eRegisterKindProcessPlugin
// The ptrace request PTRACE_PEEKUSER/PTRACE_POKEUSER used this number
diff --git a/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
index 174daa25e21b..65ff92f39bca 100644
--- a/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
@@ -10,84 +10,83 @@
#ifndef lldb_s390x_register_enums_h
#define lldb_s390x_register_enums_h
-namespace lldb_private
-{
+namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
//---------------------------------------------------------------------------
// Internal codes for all s390x registers.
//---------------------------------------------------------------------------
-enum
-{
- k_first_gpr_s390x,
- lldb_r0_s390x = k_first_gpr_s390x,
- lldb_r1_s390x,
- lldb_r2_s390x,
- lldb_r3_s390x,
- lldb_r4_s390x,
- lldb_r5_s390x,
- lldb_r6_s390x,
- lldb_r7_s390x,
- lldb_r8_s390x,
- lldb_r9_s390x,
- lldb_r10_s390x,
- lldb_r11_s390x,
- lldb_r12_s390x,
- lldb_r13_s390x,
- lldb_r14_s390x,
- lldb_r15_s390x,
- lldb_acr0_s390x,
- lldb_acr1_s390x,
- lldb_acr2_s390x,
- lldb_acr3_s390x,
- lldb_acr4_s390x,
- lldb_acr5_s390x,
- lldb_acr6_s390x,
- lldb_acr7_s390x,
- lldb_acr8_s390x,
- lldb_acr9_s390x,
- lldb_acr10_s390x,
- lldb_acr11_s390x,
- lldb_acr12_s390x,
- lldb_acr13_s390x,
- lldb_acr14_s390x,
- lldb_acr15_s390x,
- lldb_pswm_s390x,
- lldb_pswa_s390x,
- k_last_gpr_s390x = lldb_pswa_s390x,
+enum {
+ k_first_gpr_s390x,
+ lldb_r0_s390x = k_first_gpr_s390x,
+ lldb_r1_s390x,
+ lldb_r2_s390x,
+ lldb_r3_s390x,
+ lldb_r4_s390x,
+ lldb_r5_s390x,
+ lldb_r6_s390x,
+ lldb_r7_s390x,
+ lldb_r8_s390x,
+ lldb_r9_s390x,
+ lldb_r10_s390x,
+ lldb_r11_s390x,
+ lldb_r12_s390x,
+ lldb_r13_s390x,
+ lldb_r14_s390x,
+ lldb_r15_s390x,
+ lldb_acr0_s390x,
+ lldb_acr1_s390x,
+ lldb_acr2_s390x,
+ lldb_acr3_s390x,
+ lldb_acr4_s390x,
+ lldb_acr5_s390x,
+ lldb_acr6_s390x,
+ lldb_acr7_s390x,
+ lldb_acr8_s390x,
+ lldb_acr9_s390x,
+ lldb_acr10_s390x,
+ lldb_acr11_s390x,
+ lldb_acr12_s390x,
+ lldb_acr13_s390x,
+ lldb_acr14_s390x,
+ lldb_acr15_s390x,
+ lldb_pswm_s390x,
+ lldb_pswa_s390x,
+ k_last_gpr_s390x = lldb_pswa_s390x,
- k_first_fpr_s390x,
- lldb_f0_s390x = k_first_fpr_s390x,
- lldb_f1_s390x,
- lldb_f2_s390x,
- lldb_f3_s390x,
- lldb_f4_s390x,
- lldb_f5_s390x,
- lldb_f6_s390x,
- lldb_f7_s390x,
- lldb_f8_s390x,
- lldb_f9_s390x,
- lldb_f10_s390x,
- lldb_f11_s390x,
- lldb_f12_s390x,
- lldb_f13_s390x,
- lldb_f14_s390x,
- lldb_f15_s390x,
- lldb_fpc_s390x,
- k_last_fpr_s390x = lldb_fpc_s390x,
+ k_first_fpr_s390x,
+ lldb_f0_s390x = k_first_fpr_s390x,
+ lldb_f1_s390x,
+ lldb_f2_s390x,
+ lldb_f3_s390x,
+ lldb_f4_s390x,
+ lldb_f5_s390x,
+ lldb_f6_s390x,
+ lldb_f7_s390x,
+ lldb_f8_s390x,
+ lldb_f9_s390x,
+ lldb_f10_s390x,
+ lldb_f11_s390x,
+ lldb_f12_s390x,
+ lldb_f13_s390x,
+ lldb_f14_s390x,
+ lldb_f15_s390x,
+ lldb_fpc_s390x,
+ k_last_fpr_s390x = lldb_fpc_s390x,
- // These are only available on Linux.
- k_first_linux_s390x,
- lldb_orig_r2_s390x = k_first_linux_s390x,
- lldb_last_break_s390x,
- lldb_system_call_s390x,
- k_last_linux_s390x = lldb_system_call_s390x,
+ // These are only available on Linux.
+ k_first_linux_s390x,
+ lldb_orig_r2_s390x = k_first_linux_s390x,
+ lldb_last_break_s390x,
+ lldb_system_call_s390x,
+ k_last_linux_s390x = lldb_system_call_s390x,
- k_num_registers_s390x,
- k_num_gpr_registers_s390x = k_last_gpr_s390x - k_first_gpr_s390x + 1,
- k_num_fpr_registers_s390x = k_last_fpr_s390x - k_first_fpr_s390x + 1,
- k_num_linux_registers_s390x = k_last_linux_s390x - k_first_linux_s390x + 1,
- k_num_user_registers_s390x = k_num_gpr_registers_s390x + k_num_fpr_registers_s390x,
+ k_num_registers_s390x,
+ k_num_gpr_registers_s390x = k_last_gpr_s390x - k_first_gpr_s390x + 1,
+ k_num_fpr_registers_s390x = k_last_fpr_s390x - k_first_fpr_s390x + 1,
+ k_num_linux_registers_s390x = k_last_linux_s390x - k_first_linux_s390x + 1,
+ k_num_user_registers_s390x =
+ k_num_gpr_registers_s390x + k_num_fpr_registers_s390x,
};
}
diff --git a/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 63027b4451b8..770ec5a5f3ef 100644
--- a/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -10,286 +10,314 @@
#ifndef lldb_x86_register_enums_h
#define lldb_x86_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all i386 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_i386,
- lldb_eax_i386 = k_first_gpr_i386,
- lldb_ebx_i386,
- lldb_ecx_i386,
- lldb_edx_i386,
- lldb_edi_i386,
- lldb_esi_i386,
- lldb_ebp_i386,
- lldb_esp_i386,
- lldb_eip_i386,
- lldb_eflags_i386,
- lldb_cs_i386,
- lldb_fs_i386,
- lldb_gs_i386,
- lldb_ss_i386,
- lldb_ds_i386,
- lldb_es_i386,
+//---------------------------------------------------------------------------
+// Internal codes for all i386 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_i386,
+ lldb_eax_i386 = k_first_gpr_i386,
+ lldb_ebx_i386,
+ lldb_ecx_i386,
+ lldb_edx_i386,
+ lldb_edi_i386,
+ lldb_esi_i386,
+ lldb_ebp_i386,
+ lldb_esp_i386,
+ lldb_eip_i386,
+ lldb_eflags_i386,
+ lldb_cs_i386,
+ lldb_fs_i386,
+ lldb_gs_i386,
+ lldb_ss_i386,
+ lldb_ds_i386,
+ lldb_es_i386,
- k_first_alias_i386,
- lldb_ax_i386 = k_first_alias_i386,
- lldb_bx_i386,
- lldb_cx_i386,
- lldb_dx_i386,
- lldb_di_i386,
- lldb_si_i386,
- lldb_bp_i386,
- lldb_sp_i386,
- lldb_ah_i386,
- lldb_bh_i386,
- lldb_ch_i386,
- lldb_dh_i386,
- lldb_al_i386,
- lldb_bl_i386,
- lldb_cl_i386,
- lldb_dl_i386,
- k_last_alias_i386 = lldb_dl_i386,
+ k_first_alias_i386,
+ lldb_ax_i386 = k_first_alias_i386,
+ lldb_bx_i386,
+ lldb_cx_i386,
+ lldb_dx_i386,
+ lldb_di_i386,
+ lldb_si_i386,
+ lldb_bp_i386,
+ lldb_sp_i386,
+ lldb_ah_i386,
+ lldb_bh_i386,
+ lldb_ch_i386,
+ lldb_dh_i386,
+ lldb_al_i386,
+ lldb_bl_i386,
+ lldb_cl_i386,
+ lldb_dl_i386,
+ k_last_alias_i386 = lldb_dl_i386,
- k_last_gpr_i386 = k_last_alias_i386,
+ k_last_gpr_i386 = k_last_alias_i386,
- k_first_fpr_i386,
- lldb_fctrl_i386 = k_first_fpr_i386,
- lldb_fstat_i386,
- lldb_ftag_i386,
- lldb_fop_i386,
- lldb_fiseg_i386,
- lldb_fioff_i386,
- lldb_foseg_i386,
- lldb_fooff_i386,
- lldb_mxcsr_i386,
- lldb_mxcsrmask_i386,
- lldb_st0_i386,
- lldb_st1_i386,
- lldb_st2_i386,
- lldb_st3_i386,
- lldb_st4_i386,
- lldb_st5_i386,
- lldb_st6_i386,
- lldb_st7_i386,
- lldb_mm0_i386,
- lldb_mm1_i386,
- lldb_mm2_i386,
- lldb_mm3_i386,
- lldb_mm4_i386,
- lldb_mm5_i386,
- lldb_mm6_i386,
- lldb_mm7_i386,
- lldb_xmm0_i386,
- lldb_xmm1_i386,
- lldb_xmm2_i386,
- lldb_xmm3_i386,
- lldb_xmm4_i386,
- lldb_xmm5_i386,
- lldb_xmm6_i386,
- lldb_xmm7_i386,
- k_last_fpr_i386 = lldb_xmm7_i386,
+ k_first_fpr_i386,
+ lldb_fctrl_i386 = k_first_fpr_i386,
+ lldb_fstat_i386,
+ lldb_ftag_i386,
+ lldb_fop_i386,
+ lldb_fiseg_i386,
+ lldb_fioff_i386,
+ lldb_foseg_i386,
+ lldb_fooff_i386,
+ lldb_mxcsr_i386,
+ lldb_mxcsrmask_i386,
+ lldb_st0_i386,
+ lldb_st1_i386,
+ lldb_st2_i386,
+ lldb_st3_i386,
+ lldb_st4_i386,
+ lldb_st5_i386,
+ lldb_st6_i386,
+ lldb_st7_i386,
+ lldb_mm0_i386,
+ lldb_mm1_i386,
+ lldb_mm2_i386,
+ lldb_mm3_i386,
+ lldb_mm4_i386,
+ lldb_mm5_i386,
+ lldb_mm6_i386,
+ lldb_mm7_i386,
+ lldb_xmm0_i386,
+ lldb_xmm1_i386,
+ lldb_xmm2_i386,
+ lldb_xmm3_i386,
+ lldb_xmm4_i386,
+ lldb_xmm5_i386,
+ lldb_xmm6_i386,
+ lldb_xmm7_i386,
+ k_last_fpr_i386 = lldb_xmm7_i386,
- k_first_avx_i386,
- lldb_ymm0_i386 = k_first_avx_i386,
- lldb_ymm1_i386,
- lldb_ymm2_i386,
- lldb_ymm3_i386,
- lldb_ymm4_i386,
- lldb_ymm5_i386,
- lldb_ymm6_i386,
- lldb_ymm7_i386,
- k_last_avx_i386 = lldb_ymm7_i386,
+ k_first_avx_i386,
+ lldb_ymm0_i386 = k_first_avx_i386,
+ lldb_ymm1_i386,
+ lldb_ymm2_i386,
+ lldb_ymm3_i386,
+ lldb_ymm4_i386,
+ lldb_ymm5_i386,
+ lldb_ymm6_i386,
+ lldb_ymm7_i386,
+ k_last_avx_i386 = lldb_ymm7_i386,
- lldb_dr0_i386,
- lldb_dr1_i386,
- lldb_dr2_i386,
- lldb_dr3_i386,
- lldb_dr4_i386,
- lldb_dr5_i386,
- lldb_dr6_i386,
- lldb_dr7_i386,
+ k_first_mpxr_i386,
+ lldb_bnd0_i386 = k_first_mpxr_i386,
+ lldb_bnd1_i386,
+ lldb_bnd2_i386,
+ lldb_bnd3_i386,
+ k_last_mpxr = lldb_bnd3_i386,
- k_num_registers_i386,
- k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
- k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
- k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1,
- k_num_user_registers_i386 = k_num_gpr_registers_i386 + k_num_fpr_registers_i386 + k_num_avx_registers_i386,
- };
+ k_first_mpxc_i386,
+ lldb_bndcfgu_i386 = k_first_mpxc_i386,
+ lldb_bndstatus_i386,
+ k_last_mpxc_i386 = lldb_bndstatus_i386,
- //---------------------------------------------------------------------------
- // Internal codes for all x86_64 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_x86_64,
- lldb_rax_x86_64 = k_first_gpr_x86_64,
- lldb_rbx_x86_64,
- lldb_rcx_x86_64,
- lldb_rdx_x86_64,
- lldb_rdi_x86_64,
- lldb_rsi_x86_64,
- lldb_rbp_x86_64,
- lldb_rsp_x86_64,
- lldb_r8_x86_64,
- lldb_r9_x86_64,
- lldb_r10_x86_64,
- lldb_r11_x86_64,
- lldb_r12_x86_64,
- lldb_r13_x86_64,
- lldb_r14_x86_64,
- lldb_r15_x86_64,
- lldb_rip_x86_64,
- lldb_rflags_x86_64,
- lldb_cs_x86_64,
- lldb_fs_x86_64,
- lldb_gs_x86_64,
- lldb_ss_x86_64,
- lldb_ds_x86_64,
- lldb_es_x86_64,
+ lldb_dr0_i386,
+ lldb_dr1_i386,
+ lldb_dr2_i386,
+ lldb_dr3_i386,
+ lldb_dr4_i386,
+ lldb_dr5_i386,
+ lldb_dr6_i386,
+ lldb_dr7_i386,
- k_first_alias_x86_64,
- lldb_eax_x86_64 = k_first_alias_x86_64,
- lldb_ebx_x86_64,
- lldb_ecx_x86_64,
- lldb_edx_x86_64,
- lldb_edi_x86_64,
- lldb_esi_x86_64,
- lldb_ebp_x86_64,
- lldb_esp_x86_64,
- lldb_r8d_x86_64, // Low 32 bits of r8
- lldb_r9d_x86_64, // Low 32 bits of r9
- lldb_r10d_x86_64, // Low 32 bits of r10
- lldb_r11d_x86_64, // Low 32 bits of r11
- lldb_r12d_x86_64, // Low 32 bits of r12
- lldb_r13d_x86_64, // Low 32 bits of r13
- lldb_r14d_x86_64, // Low 32 bits of r14
- lldb_r15d_x86_64, // Low 32 bits of r15
- lldb_ax_x86_64,
- lldb_bx_x86_64,
- lldb_cx_x86_64,
- lldb_dx_x86_64,
- lldb_di_x86_64,
- lldb_si_x86_64,
- lldb_bp_x86_64,
- lldb_sp_x86_64,
- lldb_r8w_x86_64, // Low 16 bits of r8
- lldb_r9w_x86_64, // Low 16 bits of r9
- lldb_r10w_x86_64, // Low 16 bits of r10
- lldb_r11w_x86_64, // Low 16 bits of r11
- lldb_r12w_x86_64, // Low 16 bits of r12
- lldb_r13w_x86_64, // Low 16 bits of r13
- lldb_r14w_x86_64, // Low 16 bits of r14
- lldb_r15w_x86_64, // Low 16 bits of r15
- lldb_ah_x86_64,
- lldb_bh_x86_64,
- lldb_ch_x86_64,
- lldb_dh_x86_64,
- lldb_al_x86_64,
- lldb_bl_x86_64,
- lldb_cl_x86_64,
- lldb_dl_x86_64,
- lldb_dil_x86_64,
- lldb_sil_x86_64,
- lldb_bpl_x86_64,
- lldb_spl_x86_64,
- lldb_r8l_x86_64, // Low 8 bits of r8
- lldb_r9l_x86_64, // Low 8 bits of r9
- lldb_r10l_x86_64, // Low 8 bits of r10
- lldb_r11l_x86_64, // Low 8 bits of r11
- lldb_r12l_x86_64, // Low 8 bits of r12
- lldb_r13l_x86_64, // Low 8 bits of r13
- lldb_r14l_x86_64, // Low 8 bits of r14
- lldb_r15l_x86_64, // Low 8 bits of r15
- k_last_alias_x86_64 = lldb_r15l_x86_64,
+ k_num_registers_i386,
+ k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
+ k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
+ k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1,
+ k_num_mpx_registers_i386 = k_last_mpxc_i386 - k_first_mpxr_i386 + 1,
+ k_num_user_registers_i386 = k_num_gpr_registers_i386 +
+ k_num_fpr_registers_i386 +
+ k_num_avx_registers_i386 +
+ k_num_mpx_registers_i386,
+};
- k_last_gpr_x86_64 = k_last_alias_x86_64,
+//---------------------------------------------------------------------------
+// Internal codes for all x86_64 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_x86_64,
+ lldb_rax_x86_64 = k_first_gpr_x86_64,
+ lldb_rbx_x86_64,
+ lldb_rcx_x86_64,
+ lldb_rdx_x86_64,
+ lldb_rdi_x86_64,
+ lldb_rsi_x86_64,
+ lldb_rbp_x86_64,
+ lldb_rsp_x86_64,
+ lldb_r8_x86_64,
+ lldb_r9_x86_64,
+ lldb_r10_x86_64,
+ lldb_r11_x86_64,
+ lldb_r12_x86_64,
+ lldb_r13_x86_64,
+ lldb_r14_x86_64,
+ lldb_r15_x86_64,
+ lldb_rip_x86_64,
+ lldb_rflags_x86_64,
+ lldb_cs_x86_64,
+ lldb_fs_x86_64,
+ lldb_gs_x86_64,
+ lldb_ss_x86_64,
+ lldb_ds_x86_64,
+ lldb_es_x86_64,
- k_first_fpr_x86_64,
- lldb_fctrl_x86_64 = k_first_fpr_x86_64,
- lldb_fstat_x86_64,
- lldb_ftag_x86_64,
- lldb_fop_x86_64,
- lldb_fiseg_x86_64,
- lldb_fioff_x86_64,
- lldb_foseg_x86_64,
- lldb_fooff_x86_64,
- lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64,
- lldb_st0_x86_64,
- lldb_st1_x86_64,
- lldb_st2_x86_64,
- lldb_st3_x86_64,
- lldb_st4_x86_64,
- lldb_st5_x86_64,
- lldb_st6_x86_64,
- lldb_st7_x86_64,
- lldb_mm0_x86_64,
- lldb_mm1_x86_64,
- lldb_mm2_x86_64,
- lldb_mm3_x86_64,
- lldb_mm4_x86_64,
- lldb_mm5_x86_64,
- lldb_mm6_x86_64,
- lldb_mm7_x86_64,
- lldb_xmm0_x86_64,
- lldb_xmm1_x86_64,
- lldb_xmm2_x86_64,
- lldb_xmm3_x86_64,
- lldb_xmm4_x86_64,
- lldb_xmm5_x86_64,
- lldb_xmm6_x86_64,
- lldb_xmm7_x86_64,
- lldb_xmm8_x86_64,
- lldb_xmm9_x86_64,
- lldb_xmm10_x86_64,
- lldb_xmm11_x86_64,
- lldb_xmm12_x86_64,
- lldb_xmm13_x86_64,
- lldb_xmm14_x86_64,
- lldb_xmm15_x86_64,
- k_last_fpr_x86_64 = lldb_xmm15_x86_64,
+ k_first_alias_x86_64,
+ lldb_eax_x86_64 = k_first_alias_x86_64,
+ lldb_ebx_x86_64,
+ lldb_ecx_x86_64,
+ lldb_edx_x86_64,
+ lldb_edi_x86_64,
+ lldb_esi_x86_64,
+ lldb_ebp_x86_64,
+ lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits of r8
+ lldb_r9d_x86_64, // Low 32 bits of r9
+ lldb_r10d_x86_64, // Low 32 bits of r10
+ lldb_r11d_x86_64, // Low 32 bits of r11
+ lldb_r12d_x86_64, // Low 32 bits of r12
+ lldb_r13d_x86_64, // Low 32 bits of r13
+ lldb_r14d_x86_64, // Low 32 bits of r14
+ lldb_r15d_x86_64, // Low 32 bits of r15
+ lldb_ax_x86_64,
+ lldb_bx_x86_64,
+ lldb_cx_x86_64,
+ lldb_dx_x86_64,
+ lldb_di_x86_64,
+ lldb_si_x86_64,
+ lldb_bp_x86_64,
+ lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits of r8
+ lldb_r9w_x86_64, // Low 16 bits of r9
+ lldb_r10w_x86_64, // Low 16 bits of r10
+ lldb_r11w_x86_64, // Low 16 bits of r11
+ lldb_r12w_x86_64, // Low 16 bits of r12
+ lldb_r13w_x86_64, // Low 16 bits of r13
+ lldb_r14w_x86_64, // Low 16 bits of r14
+ lldb_r15w_x86_64, // Low 16 bits of r15
+ lldb_ah_x86_64,
+ lldb_bh_x86_64,
+ lldb_ch_x86_64,
+ lldb_dh_x86_64,
+ lldb_al_x86_64,
+ lldb_bl_x86_64,
+ lldb_cl_x86_64,
+ lldb_dl_x86_64,
+ lldb_dil_x86_64,
+ lldb_sil_x86_64,
+ lldb_bpl_x86_64,
+ lldb_spl_x86_64,
+ lldb_r8l_x86_64, // Low 8 bits of r8
+ lldb_r9l_x86_64, // Low 8 bits of r9
+ lldb_r10l_x86_64, // Low 8 bits of r10
+ lldb_r11l_x86_64, // Low 8 bits of r11
+ lldb_r12l_x86_64, // Low 8 bits of r12
+ lldb_r13l_x86_64, // Low 8 bits of r13
+ lldb_r14l_x86_64, // Low 8 bits of r14
+ lldb_r15l_x86_64, // Low 8 bits of r15
+ k_last_alias_x86_64 = lldb_r15l_x86_64,
- k_first_avx_x86_64,
- lldb_ymm0_x86_64 = k_first_avx_x86_64,
- lldb_ymm1_x86_64,
- lldb_ymm2_x86_64,
- lldb_ymm3_x86_64,
- lldb_ymm4_x86_64,
- lldb_ymm5_x86_64,
- lldb_ymm6_x86_64,
- lldb_ymm7_x86_64,
- lldb_ymm8_x86_64,
- lldb_ymm9_x86_64,
- lldb_ymm10_x86_64,
- lldb_ymm11_x86_64,
- lldb_ymm12_x86_64,
- lldb_ymm13_x86_64,
- lldb_ymm14_x86_64,
- lldb_ymm15_x86_64,
- k_last_avx_x86_64 = lldb_ymm15_x86_64,
+ k_last_gpr_x86_64 = k_last_alias_x86_64,
- lldb_dr0_x86_64,
- lldb_dr1_x86_64,
- lldb_dr2_x86_64,
- lldb_dr3_x86_64,
- lldb_dr4_x86_64,
- lldb_dr5_x86_64,
- lldb_dr6_x86_64,
- lldb_dr7_x86_64,
+ k_first_fpr_x86_64,
+ lldb_fctrl_x86_64 = k_first_fpr_x86_64,
+ lldb_fstat_x86_64,
+ lldb_ftag_x86_64,
+ lldb_fop_x86_64,
+ lldb_fiseg_x86_64,
+ lldb_fioff_x86_64,
+ lldb_foseg_x86_64,
+ lldb_fooff_x86_64,
+ lldb_mxcsr_x86_64,
+ lldb_mxcsrmask_x86_64,
+ lldb_st0_x86_64,
+ lldb_st1_x86_64,
+ lldb_st2_x86_64,
+ lldb_st3_x86_64,
+ lldb_st4_x86_64,
+ lldb_st5_x86_64,
+ lldb_st6_x86_64,
+ lldb_st7_x86_64,
+ lldb_mm0_x86_64,
+ lldb_mm1_x86_64,
+ lldb_mm2_x86_64,
+ lldb_mm3_x86_64,
+ lldb_mm4_x86_64,
+ lldb_mm5_x86_64,
+ lldb_mm6_x86_64,
+ lldb_mm7_x86_64,
+ lldb_xmm0_x86_64,
+ lldb_xmm1_x86_64,
+ lldb_xmm2_x86_64,
+ lldb_xmm3_x86_64,
+ lldb_xmm4_x86_64,
+ lldb_xmm5_x86_64,
+ lldb_xmm6_x86_64,
+ lldb_xmm7_x86_64,
+ lldb_xmm8_x86_64,
+ lldb_xmm9_x86_64,
+ lldb_xmm10_x86_64,
+ lldb_xmm11_x86_64,
+ lldb_xmm12_x86_64,
+ lldb_xmm13_x86_64,
+ lldb_xmm14_x86_64,
+ lldb_xmm15_x86_64,
+ k_last_fpr_x86_64 = lldb_xmm15_x86_64,
- k_num_registers_x86_64,
- k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
- k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
- k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1,
- k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 + k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64,
- };
+ k_first_avx_x86_64,
+ lldb_ymm0_x86_64 = k_first_avx_x86_64,
+ lldb_ymm1_x86_64,
+ lldb_ymm2_x86_64,
+ lldb_ymm3_x86_64,
+ lldb_ymm4_x86_64,
+ lldb_ymm5_x86_64,
+ lldb_ymm6_x86_64,
+ lldb_ymm7_x86_64,
+ lldb_ymm8_x86_64,
+ lldb_ymm9_x86_64,
+ lldb_ymm10_x86_64,
+ lldb_ymm11_x86_64,
+ lldb_ymm12_x86_64,
+ lldb_ymm13_x86_64,
+ lldb_ymm14_x86_64,
+ lldb_ymm15_x86_64,
+ k_last_avx_x86_64 = lldb_ymm15_x86_64,
+ k_first_mpxr_x86_64,
+ lldb_bnd0_x86_64 = k_first_mpxr_x86_64,
+ lldb_bnd1_x86_64,
+ lldb_bnd2_x86_64,
+ lldb_bnd3_x86_64,
+ k_last_mpxr_x86_64 = lldb_bnd3_x86_64,
+
+ k_first_mpxc_x86_64,
+ lldb_bndcfgu_x86_64 = k_first_mpxc_x86_64,
+ lldb_bndstatus_x86_64,
+ k_last_mpxc_x86_64 = lldb_bndstatus_x86_64,
+
+ lldb_dr0_x86_64,
+ lldb_dr1_x86_64,
+ lldb_dr2_x86_64,
+ lldb_dr3_x86_64,
+ lldb_dr4_x86_64,
+ lldb_dr5_x86_64,
+ lldb_dr6_x86_64,
+ lldb_dr7_x86_64,
+
+ k_num_registers_x86_64,
+ k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
+ k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
+ k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1,
+ k_num_mpx_registers_x86_64 = k_last_mpxc_x86_64 - k_first_mpxr_x86_64 + 1,
+ k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 +
+ k_num_fpr_registers_x86_64 +
+ k_num_avx_registers_x86_64 +
+ k_num_mpx_registers_x86_64,
+};
}
#endif // #ifndef lldb_x86_register_enums_h
diff --git a/source/Plugins/Process/Windows/Common/CMakeLists.txt b/source/Plugins/Process/Windows/Common/CMakeLists.txt
index 5a53c3c3300c..9386ed8a0e4c 100644
--- a/source/Plugins/Process/Windows/Common/CMakeLists.txt
+++ b/source/Plugins/Process/Windows/Common/CMakeLists.txt
@@ -2,9 +2,11 @@ include_directories(.)
include_directories(../../Utility)
set(PROC_WINDOWS_COMMON_SOURCES
- RegisterContextWindows.cpp
+ DebuggerThread.cpp
+ LocalDebugDelegate.cpp
ProcessWindows.cpp
ProcessWindowsLog.cpp
+ RegisterContextWindows.cpp
TargetThreadWindows.cpp
)
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
new file mode 100644
index 000000000000..be1462aa6602
--- /dev/null
+++ b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -0,0 +1,549 @@
+//===-- DebuggerThread.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebuggerThread.h"
+#include "ExceptionRecord.h"
+#include "IDebugDelegate.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/ThisThread.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/windows/HostProcessWindows.h"
+#include "lldb/Host/windows/HostThreadWindows.h"
+#include "lldb/Host/windows/ProcessLauncherWindows.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+struct DebugLaunchContext {
+ DebugLaunchContext(DebuggerThread *thread,
+ const ProcessLaunchInfo &launch_info)
+ : m_thread(thread), m_launch_info(launch_info) {}
+ DebuggerThread *m_thread;
+ ProcessLaunchInfo m_launch_info;
+};
+
+struct DebugAttachContext {
+ DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info)
+ : m_thread(thread), m_pid(pid), m_attach_info(attach_info) {}
+ DebuggerThread *m_thread;
+ lldb::pid_t m_pid;
+ ProcessAttachInfo m_attach_info;
+};
+}
+
+DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
+ : m_debug_delegate(debug_delegate), m_pid_to_detach(0),
+ m_is_shutting_down(false) {
+ m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
+}
+
+DebuggerThread::~DebuggerThread() { ::CloseHandle(m_debugging_ended_event); }
+
+Error DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread::DebugLaunch launching '%s'",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ Error error;
+ DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
+ HostThread slave_thread(ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine,
+ context, &error));
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "DebugLaunch couldn't launch debugger thread. %s",
+ error.AsCString());
+ }
+
+ return error;
+}
+
+Error DebuggerThread::DebugAttach(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread::DebugAttach attaching to '%llu'", pid);
+
+ Error error;
+ DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
+ HostThread slave_thread(ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.slave[?]", DebuggerThreadAttachRoutine,
+ context, &error));
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "DebugAttach couldn't attach to process '%llu'. %s", pid,
+ error.AsCString());
+ }
+
+ return error;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(void *data) {
+ DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
+ lldb::thread_result_t result =
+ context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
+ delete context;
+ return result;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
+ DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
+ lldb::thread_result_t result = context->m_thread->DebuggerThreadAttachRoutine(
+ context->m_pid, context->m_attach_info);
+ delete context;
+ return result;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
+ const ProcessLaunchInfo &launch_info) {
+ // Grab a shared_ptr reference to this so that we know it won't get deleted
+ // until after the
+ // thread routine has exited.
+ std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread preparing to launch '%s' on background thread.",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ Error error;
+ ProcessLauncherWindows launcher;
+ HostProcess process(launcher.LaunchProcess(launch_info, error));
+ // If we couldn't create the process, notify waiters immediately. Otherwise
+ // enter the debug
+ // loop and wait until we get the create process debug notification. Note
+ // that if the process
+ // was created successfully, we can throw away the process handle we got from
+ // CreateProcess
+ // because Windows will give us another (potentially more useful?) handle when
+ // it sends us the
+ // CREATE_PROCESS_DEBUG_EVENT.
+ if (error.Success())
+ DebugLoop();
+ else
+ m_debug_delegate->OnDebuggerError(error, 0);
+
+ return 0;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
+ // Grab a shared_ptr reference to this so that we know it won't get deleted
+ // until after the
+ // thread routine has exited.
+ std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to attach to "
+ "process '%llu' on background thread.",
+ pid);
+
+ if (!DebugActiveProcess((DWORD)pid)) {
+ Error error(::GetLastError(), eErrorTypeWin32);
+ m_debug_delegate->OnDebuggerError(error, 0);
+ return 0;
+ }
+
+ // The attach was successful, enter the debug loop. From here on out, this is
+ // no different than
+ // a create process operation, so all the same comments in DebugLaunch should
+ // apply from this
+ // point out.
+ DebugLoop();
+
+ return 0;
+}
+
+Error DebuggerThread::StopDebugging(bool terminate) {
+ Error error;
+
+ lldb::pid_t pid = m_process.GetProcessId();
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging('%s') called (inferior=%I64u).",
+ (terminate ? "true" : "false"), pid);
+
+ // Set m_is_shutting_down to true if it was false. Return if it was already
+ // true.
+ bool expected = false;
+ if (!m_is_shutting_down.compare_exchange_strong(expected, true))
+ return error;
+
+ // Make a copy of the process, since the termination sequence will reset
+ // DebuggerThread's internal copy and it needs to remain open for the Wait
+ // operation.
+ HostProcess process_copy = m_process;
+ lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
+
+ if (terminate) {
+ // Initiate the termination before continuing the exception, so that the
+ // next debug
+ // event we get is the exit process event, and not some other event.
+ BOOL terminate_suceeded = TerminateProcess(handle, 0);
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging called "
+ "TerminateProcess(0x%p, 0) "
+ "(inferior=%I64u), success='%s'",
+ handle, pid, (terminate_suceeded ? "true" : "false"));
+ }
+
+ // If we're stuck waiting for an exception to continue (e.g. the user is at a
+ // breakpoint
+ // messing around in the debugger), continue it now. But only AFTER calling
+ // TerminateProcess
+ // to make sure that the very next call to WaitForDebugEvent is an exit
+ // process event.
+ if (m_active_exception.get()) {
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_EXCEPTION,
+ "StopDebugging masking active exception");
+
+ ContinueAsyncException(ExceptionResult::MaskException);
+ }
+
+ if (!terminate) {
+ // Indicate that we want to detach.
+ m_pid_to_detach = GetProcess().GetProcessId();
+
+ // Force a fresh break so that the detach can happen from the debugger
+ // thread.
+ if (!::DebugBreakProcess(
+ GetProcess().GetNativeProcess().GetSystemHandle())) {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ }
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "StopDebugging waiting for detach from process %llu to complete.", pid);
+
+ DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
+ if (wait_result != WAIT_OBJECT_0) {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging WaitForSingleObject(0x%p, 5000) returned %lu",
+ m_debugging_ended_event, wait_result);
+ } else {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "StopDebugging detach from process %llu completed successfully.", pid);
+ }
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging encountered an error "
+ "while trying to stop process %llu. %s",
+ pid, error.AsCString());
+ }
+ return error;
+}
+
+void DebuggerThread::ContinueAsyncException(ExceptionResult result) {
+ if (!m_active_exception.get())
+ return;
+
+ WINLOG_IFANY(
+ WINDOWS_LOG_PROCESS | WINDOWS_LOG_EXCEPTION,
+ "ContinueAsyncException called for inferior process %I64u, broadcasting.",
+ m_process.GetProcessId());
+
+ m_active_exception.reset();
+ m_exception_pred.SetValue(result, eBroadcastAlways);
+}
+
+void DebuggerThread::FreeProcessHandles() {
+ m_process = HostProcess();
+ m_main_thread = HostThread();
+ if (m_image_file) {
+ ::CloseHandle(m_image_file);
+ m_image_file = nullptr;
+ }
+}
+
+void DebuggerThread::DebugLoop() {
+ DEBUG_EVENT dbe = {};
+ bool should_debug = true;
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
+ while (should_debug) {
+ WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
+ BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
+ if (wait_result) {
+ DWORD continue_status = DBG_CONTINUE;
+ switch (dbe.dwDebugEventCode) {
+ case EXCEPTION_DEBUG_EVENT: {
+ ExceptionResult status =
+ HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
+
+ if (status == ExceptionResult::MaskException)
+ continue_status = DBG_CONTINUE;
+ else if (status == ExceptionResult::SendToApplication)
+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
+
+ break;
+ }
+ case CREATE_THREAD_DEBUG_EVENT:
+ continue_status =
+ HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
+ break;
+ case CREATE_PROCESS_DEBUG_EVENT:
+ continue_status =
+ HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
+ break;
+ case EXIT_THREAD_DEBUG_EVENT:
+ continue_status =
+ HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
+ break;
+ case EXIT_PROCESS_DEBUG_EVENT:
+ continue_status =
+ HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
+ should_debug = false;
+ break;
+ case LOAD_DLL_DEBUG_EVENT:
+ continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
+ break;
+ case UNLOAD_DLL_DEBUG_EVENT:
+ continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
+ break;
+ case OUTPUT_DEBUG_STRING_EVENT:
+ continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
+ break;
+ case RIP_EVENT:
+ continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
+ if (dbe.u.RipInfo.dwType == SLE_ERROR)
+ should_debug = false;
+ break;
+ }
+
+ WINLOGD_IFALL(
+ WINDOWS_LOG_EVENT,
+ "DebugLoop calling ContinueDebugEvent(%lu, %lu, %lu) on thread %lu.",
+ dbe.dwProcessId, dbe.dwThreadId, continue_status,
+ ::GetCurrentThreadId());
+
+ ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
+
+ if (m_detached) {
+ should_debug = false;
+ }
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_EVENT,
+ "DebugLoop returned FALSE from WaitForDebugEvent. Error = %lu",
+ ::GetLastError());
+
+ should_debug = false;
+ }
+ }
+ FreeProcessHandles();
+
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
+ SetEvent(m_debugging_ended_event);
+}
+
+ExceptionResult
+DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
+ DWORD thread_id) {
+ if (m_is_shutting_down) {
+ // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
+ // exception that
+ // we use simply to wake up the DebuggerThread so that we can close out the
+ // debug loop.
+ if (m_pid_to_detach != 0 &&
+ info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION |
+ WINDOWS_LOG_PROCESS,
+ "Breakpoint exception is cue to detach from process 0x%lx",
+ m_pid_to_detach.load());
+ ::DebugActiveProcessStop(m_pid_to_detach);
+ m_detached = true;
+ }
+
+ // Don't perform any blocking operations while we're shutting down. That
+ // will
+ // cause TerminateProcess -> WaitForSingleObject to time out.
+ return ExceptionResult::SendToApplication;
+ }
+
+ bool first_chance = (info.dwFirstChance != 0);
+
+ m_active_exception.reset(
+ new ExceptionRecord(info.ExceptionRecord, thread_id));
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "HandleExceptionEvent encountered %s chance exception 0x%lx on "
+ "thread 0x%lx",
+ first_chance ? "first" : "second",
+ info.ExceptionRecord.ExceptionCode, thread_id);
+
+ ExceptionResult result =
+ m_debug_delegate->OnDebugException(first_chance, *m_active_exception);
+ m_exception_pred.SetValue(result, eBroadcastNever);
+
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred "
+ "!= BreakInDebugger");
+
+ m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger,
+ result);
+
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
+ m_exception_pred.GetValue());
+
+ return result;
+}
+
+DWORD
+DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleCreateThreadEvent Thread 0x%lx spawned in process %llu",
+ thread_id, m_process.GetProcessId());
+ HostThread thread(info.hThread);
+ thread.GetNativeThread().SetOwnsHandle(false);
+ m_debug_delegate->OnCreateThread(thread);
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id) {
+ uint32_t process_id = ::GetProcessId(info.hProcess);
+
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS,
+ "HandleCreateProcessEvent process %u spawned", process_id);
+
+ std::string thread_name;
+ llvm::raw_string_ostream name_stream(thread_name);
+ name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
+ name_stream.flush();
+ ThisThread::SetName(thread_name.c_str());
+
+ // info.hProcess and info.hThread are closed automatically by Windows when
+ // EXIT_PROCESS_DEBUG_EVENT is received.
+ m_process = HostProcess(info.hProcess);
+ ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
+ m_main_thread = HostThread(info.hThread);
+ m_main_thread.GetNativeThread().SetOwnsHandle(false);
+ m_image_file = info.hFile;
+
+ lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
+ m_debug_delegate->OnDebuggerConnected(load_addr);
+
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(
+ WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleExitThreadEvent Thread %lu exited with code %lu in process %llu",
+ thread_id, info.dwExitCode, m_process.GetProcessId());
+ m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleExitProcessEvent process %llu exited with code %lu",
+ m_process.GetProcessId(), info.dwExitCode);
+
+ m_debug_delegate->OnExitProcess(info.dwExitCode);
+
+ FreeProcessHandles();
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id) {
+ if (info.hFile == nullptr) {
+ // Not sure what this is, so just ignore it.
+ WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %llu - HandleLoadDllEvent has "
+ "a NULL file handle, returning...",
+ m_process.GetProcessId());
+ return DBG_CONTINUE;
+ }
+
+ std::vector<wchar_t> buffer(1);
+ DWORD required_size =
+ GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
+ if (required_size > 0) {
+ buffer.resize(required_size + 1);
+ required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0],
+ required_size, VOLUME_NAME_DOS);
+ std::string path_str_utf8;
+ llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
+ llvm::StringRef path_str = path_str_utf8;
+ const char *path = path_str.data();
+ if (path_str.startswith("\\\\?\\"))
+ path += 4;
+
+ FileSpec file_spec(path, false);
+ ModuleSpec module_spec(file_spec);
+ lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
+
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL "
+ "'%s' loaded at address 0x%p...",
+ m_process.GetProcessId(), path, info.lpBaseOfDll);
+
+ m_debug_delegate->OnLoadDll(module_spec, load_addr);
+ } else {
+ WINERR_IFALL(WINDOWS_LOG_EVENT, "Inferior %llu - HandleLoadDllEvent Error "
+ "%lu occurred calling "
+ "GetFinalPathNameByHandle",
+ m_process.GetProcessId(), ::GetLastError());
+ }
+ // Windows does not automatically close info.hFile, so we need to do it.
+ ::CloseHandle(info.hFile);
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFALL(WINDOWS_LOG_EVENT,
+ "HandleUnloadDllEvent process %llu unloading DLL at addr 0x%p.",
+ m_process.GetProcessId(), info.lpBaseOfDll);
+
+ m_debug_delegate->OnUnloadDll(
+ reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
+ DWORD thread_id) {
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
+ WINERR_IFALL(WINDOWS_LOG_EVENT, "HandleRipEvent encountered error %lu "
+ "(type=%lu) in process %llu thread %lu",
+ info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
+
+ Error error(info.dwError, eErrorTypeWin32);
+ m_debug_delegate->OnDebuggerError(error, info.dwType);
+
+ return DBG_CONTINUE;
+}
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.h b/source/Plugins/Process/Windows/Common/DebuggerThread.h
new file mode 100644
index 000000000000..ef4b47bab8c7
--- /dev/null
+++ b/source/Plugins/Process/Windows/Common/DebuggerThread.h
@@ -0,0 +1,106 @@
+//===-- DebuggerThread.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_Plugins_Process_Windows_DebuggerThread_H_
+#define liblldb_Plugins_Process_Windows_DebuggerThread_H_
+
+#include <atomic>
+#include <memory>
+
+#include "ForwardDecl.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/windows/windows.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// DebuggerThread
+//
+// Debugs a single process, notifying listeners as appropriate when interesting
+// things occur.
+//----------------------------------------------------------------------
+class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
+public:
+ DebuggerThread(DebugDelegateSP debug_delegate);
+ virtual ~DebuggerThread();
+
+ Error DebugLaunch(const ProcessLaunchInfo &launch_info);
+ Error DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
+
+ HostProcess GetProcess() const { return m_process; }
+ HostThread GetMainThread() const { return m_main_thread; }
+ std::weak_ptr<ExceptionRecord> GetActiveException() {
+ return m_active_exception;
+ }
+
+ Error StopDebugging(bool terminate);
+
+ void ContinueAsyncException(ExceptionResult result);
+
+private:
+ void FreeProcessHandles();
+ void DebugLoop();
+ ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
+ DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
+ DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
+
+ DebugDelegateSP m_debug_delegate;
+
+ HostProcess m_process; // The process being debugged.
+ HostThread m_main_thread; // The main thread of the inferior.
+
+ // The image file of the process being debugged.
+ HANDLE m_image_file = nullptr;
+
+ // The current exception waiting to be handled
+ ExceptionRecordSP m_active_exception;
+
+ // A predicate which gets signalled when an exception is finished processing
+ // and the debug loop can be continued.
+ Predicate<ExceptionResult> m_exception_pred;
+
+ // An event which gets signalled by the debugger thread when it exits the
+ // debugger loop and is detached from the inferior.
+ HANDLE m_debugging_ended_event = nullptr;
+
+ // Signals the loop to detach from the process (specified by pid).
+ std::atomic<DWORD> m_pid_to_detach;
+
+ // Signals the debug loop to stop processing certain types of events that
+ // block shutdown.
+ std::atomic<bool> m_is_shutting_down;
+
+ // Indicates we've detached from the inferior process and the debug loop can
+ // exit.
+ bool m_detached = false;
+
+ static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
+ lldb::thread_result_t
+ DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
+ static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
+ lldb::thread_result_t
+ DebuggerThreadAttachRoutine(lldb::pid_t pid,
+ const ProcessAttachInfo &launch_info);
+};
+}
+#endif
diff --git a/source/Plugins/Process/Windows/Common/ExceptionRecord.h b/source/Plugins/Process/Windows/Common/ExceptionRecord.h
index 79dae3fca4e8..1eec85d52c26 100644
--- a/source/Plugins/Process/Windows/Common/ExceptionRecord.h
+++ b/source/Plugins/Process/Windows/Common/ExceptionRecord.h
@@ -10,15 +10,14 @@
#ifndef liblldb_Plugins_Process_Windows_ExceptionRecord_H_
#define liblldb_Plugins_Process_Windows_ExceptionRecord_H_
-#include "lldb/lldb-forward.h"
#include "lldb/Host/windows/windows.h"
-#include <DbgHelp.h>
+#include "lldb/lldb-forward.h"
+#include <dbghelp.h>
#include <memory>
#include <vector>
-namespace lldb_private
-{
+namespace lldb_private {
//----------------------------------------------------------------------
// ExceptionRecord
@@ -26,73 +25,55 @@ namespace lldb_private
// ExceptionRecord defines an interface which allows implementors to receive
// notification of events that happen in a debugged process.
//----------------------------------------------------------------------
-class ExceptionRecord
-{
- public:
- ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id)
- {
- m_code = record.ExceptionCode;
- m_continuable = (record.ExceptionFlags == 0);
- if (record.ExceptionRecord)
- m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord, thread_id));
- m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);
- m_thread_id = thread_id;
- m_arguments.assign(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters);
- }
+class ExceptionRecord {
+public:
+ ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id) {
+ m_code = record.ExceptionCode;
+ m_continuable = (record.ExceptionFlags == 0);
+ if (record.ExceptionRecord)
+ m_next_exception.reset(
+ new ExceptionRecord(*record.ExceptionRecord, thread_id));
+ m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);
+ m_thread_id = thread_id;
+ m_arguments.assign(record.ExceptionInformation,
+ record.ExceptionInformation + record.NumberParameters);
+ }
- // MINIDUMP_EXCEPTIONs are almost identical to EXCEPTION_RECORDs.
- ExceptionRecord(const MINIDUMP_EXCEPTION &record, lldb::tid_t thread_id) :
- m_code(record.ExceptionCode),
- m_continuable(record.ExceptionFlags == 0),
+ // MINIDUMP_EXCEPTIONs are almost identical to EXCEPTION_RECORDs.
+ ExceptionRecord(const MINIDUMP_EXCEPTION &record, lldb::tid_t thread_id)
+ : m_code(record.ExceptionCode), m_continuable(record.ExceptionFlags == 0),
m_next_exception(nullptr),
m_exception_addr(static_cast<lldb::addr_t>(record.ExceptionAddress)),
m_thread_id(thread_id),
- m_arguments(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters)
- {
- // Set up link to nested exception.
- if (record.ExceptionRecord)
- {
- m_next_exception.reset(new ExceptionRecord(*reinterpret_cast<const MINIDUMP_EXCEPTION *>(record.ExceptionRecord),
- thread_id));
- }
+ m_arguments(record.ExceptionInformation,
+ record.ExceptionInformation + record.NumberParameters) {
+ // Set up link to nested exception.
+ if (record.ExceptionRecord) {
+ m_next_exception.reset(new ExceptionRecord(
+ *reinterpret_cast<const MINIDUMP_EXCEPTION *>(record.ExceptionRecord),
+ thread_id));
}
+ }
- virtual ~ExceptionRecord() {}
+ virtual ~ExceptionRecord() {}
- DWORD
- GetExceptionCode() const
- {
- return m_code;
- }
- bool
- IsContinuable() const
- {
- return m_continuable;
- }
- const ExceptionRecord *
- GetNextException() const
- {
- return m_next_exception.get();
- }
- lldb::addr_t
- GetExceptionAddress() const
- {
- return m_exception_addr;
- }
+ DWORD
+ GetExceptionCode() const { return m_code; }
+ bool IsContinuable() const { return m_continuable; }
+ const ExceptionRecord *GetNextException() const {
+ return m_next_exception.get();
+ }
+ lldb::addr_t GetExceptionAddress() const { return m_exception_addr; }
- lldb::tid_t
- GetThreadID() const
- {
- return m_thread_id;
- }
+ lldb::tid_t GetThreadID() const { return m_thread_id; }
- private:
- DWORD m_code;
- bool m_continuable;
- std::shared_ptr<ExceptionRecord> m_next_exception;
- lldb::addr_t m_exception_addr;
- lldb::tid_t m_thread_id;
- std::vector<ULONG_PTR> m_arguments;
+private:
+ DWORD m_code;
+ bool m_continuable;
+ std::shared_ptr<ExceptionRecord> m_next_exception;
+ lldb::addr_t m_exception_addr;
+ lldb::tid_t m_thread_id;
+ std::vector<ULONG_PTR> m_arguments;
};
}
diff --git a/source/Plugins/Process/Windows/Live/ForwardDecl.h b/source/Plugins/Process/Windows/Common/ForwardDecl.h
index a782597555e1..cfe1b79cee11 100644
--- a/source/Plugins/Process/Windows/Live/ForwardDecl.h
+++ b/source/Plugins/Process/Windows/Common/ForwardDecl.h
@@ -14,17 +14,18 @@
// ExceptionResult is returned by the debug delegate to specify how it processed
// the exception.
-enum class ExceptionResult
-{
- BreakInDebugger, // Break in the debugger and give the user a chance to interact with
- // the program before continuing.
- MaskException, // Eat the exception and don't let the application know it occurred.
- SendToApplication // Send the exception to the application to be handled as if there were
- // no debugger attached.
+enum class ExceptionResult {
+ BreakInDebugger, // Break in the debugger and give the user a chance to
+ // interact with
+ // the program before continuing.
+ MaskException, // Eat the exception and don't let the application know it
+ // occurred.
+ SendToApplication // Send the exception to the application to be handled as if
+ // there were
+ // no debugger attached.
};
-namespace lldb_private
-{
+namespace lldb_private {
class ProcessWindows;
diff --git a/source/Plugins/Process/Windows/Live/IDebugDelegate.h b/source/Plugins/Process/Windows/Common/IDebugDelegate.h
index 6d864de7ed42..e88e0ada053b 100644
--- a/source/Plugins/Process/Windows/Live/IDebugDelegate.h
+++ b/source/Plugins/Process/Windows/Common/IDebugDelegate.h
@@ -15,8 +15,7 @@
#include "lldb/lldb-types.h"
#include <string>
-namespace lldb_private
-{
+namespace lldb_private {
class Error;
class HostThread;
@@ -26,20 +25,21 @@ class HostThread;
// IDebugDelegate defines an interface which allows implementors to receive
// notification of events that happen in a debugged process.
//----------------------------------------------------------------------
-class IDebugDelegate
-{
- public:
- virtual ~IDebugDelegate() {}
+class IDebugDelegate {
+public:
+ virtual ~IDebugDelegate() {}
- virtual void OnExitProcess(uint32_t exit_code) = 0;
- virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
- virtual ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) = 0;
- virtual void OnCreateThread(const HostThread &thread) = 0;
- virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
- virtual void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) = 0;
- virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
- virtual void OnDebugString(const std::string &string) = 0;
- virtual void OnDebuggerError(const Error &error, uint32_t type) = 0;
+ virtual void OnExitProcess(uint32_t exit_code) = 0;
+ virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
+ virtual ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) = 0;
+ virtual void OnCreateThread(const HostThread &thread) = 0;
+ virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
+ virtual void OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) = 0;
+ virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
+ virtual void OnDebugString(const std::string &string) = 0;
+ virtual void OnDebuggerError(const Error &error, uint32_t type) = 0;
};
}
diff --git a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
new file mode 100644
index 000000000000..600aef372505
--- /dev/null
+++ b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
@@ -0,0 +1,73 @@
+//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LocalDebugDelegate.h"
+#include "ProcessWindows.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LocalDebugDelegate::LocalDebugDelegate(ProcessWP process)
+ : m_process(process) {}
+
+void LocalDebugDelegate::OnExitProcess(uint32_t exit_code) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnExitProcess(exit_code);
+}
+
+void LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnDebuggerConnected(image_base);
+}
+
+ExceptionResult
+LocalDebugDelegate::OnDebugException(bool first_chance,
+ const ExceptionRecord &record) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ return process->OnDebugException(first_chance, record);
+ else
+ return ExceptionResult::MaskException;
+}
+
+void LocalDebugDelegate::OnCreateThread(const HostThread &thread) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnCreateThread(thread);
+}
+
+void LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id,
+ uint32_t exit_code) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnExitThread(thread_id, exit_code);
+}
+
+void LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec,
+ lldb::addr_t module_addr) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnLoadDll(module_spec, module_addr);
+}
+
+void LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnUnloadDll(module_addr);
+}
+
+void LocalDebugDelegate::OnDebugString(const std::string &string) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnDebugString(string);
+}
+
+void LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnDebuggerError(error, type);
+}
+
+ProcessWindowsSP LocalDebugDelegate::GetProcessPointer() {
+ ProcessSP process = m_process.lock();
+ return std::static_pointer_cast<ProcessWindows>(process);
+}
diff --git a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
index ec2f9418142f..819854a1e631 100644
--- a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h
+++ b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
@@ -16,20 +16,19 @@
#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class ProcessWindowsLive;
-typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
+class ProcessWindows;
+typedef std::shared_ptr<ProcessWindows> ProcessWindowsSP;
//----------------------------------------------------------------------
// LocalDebugDelegate
//
-// LocalDebugDelegate creates a connection between a ProcessWindowsLive and the
-// debug driver. This serves to decouple ProcessWindowsLive from the debug driver.
-// It would be possible to get a similar decoupling by just having
-// ProcessWindowsLive implement this interface directly. There are two reasons why
-// we don't do this:
+// LocalDebugDelegate creates a connection between a ProcessWindows and the
+// debug driver. This serves to decouple ProcessWindows from the debug
+// driver. It would be possible to get a similar decoupling by just having
+// ProcessWindows implement this interface directly. There are two reasons
+// why we don't do this:
//
// 1) In the future when we add support for local debugging through LLGS, and we
// go through the Native*Protocol interface, it is likely we will need the
@@ -42,26 +41,26 @@ typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
// driver), so this adapter serves as a way to transparently hold the
// ProcessSP while still keeping it decoupled from the driver.
//----------------------------------------------------------------------
-class LocalDebugDelegate : public IDebugDelegate
-{
- public:
- explicit LocalDebugDelegate(lldb::ProcessWP process);
+class LocalDebugDelegate : public IDebugDelegate {
+public:
+ explicit LocalDebugDelegate(lldb::ProcessWP process);
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override;
- void OnCreateThread(const HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &message) override;
- void OnDebuggerError(const Error &error, uint32_t type) override;
+ void OnExitProcess(uint32_t exit_code) override;
+ void OnDebuggerConnected(lldb::addr_t image_base) override;
+ ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) override;
+ void OnCreateThread(const HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
+ void OnLoadDll(const lldb_private::ModuleSpec &module_spec,
+ lldb::addr_t module_addr) override;
+ void OnUnloadDll(lldb::addr_t module_addr) override;
+ void OnDebugString(const std::string &message) override;
+ void OnDebuggerError(const Error &error, uint32_t type) override;
- private:
- ProcessWindowsLiveSP
- GetProcessPointer();
+private:
+ ProcessWindowsSP GetProcessPointer();
- lldb::ProcessWP m_process;
+ lldb::ProcessWP m_process;
};
}
diff --git a/source/Plugins/Process/Windows/Common/NtStructures.h b/source/Plugins/Process/Windows/Common/NtStructures.h
index 6c688d9068d5..6826b98c769e 100644
--- a/source/Plugins/Process/Windows/Common/NtStructures.h
+++ b/source/Plugins/Process/Windows/Common/NtStructures.h
@@ -15,18 +15,17 @@
// This describes the layout of a TEB (Thread Environment Block) for a 64-bit
// process. It's adapted from the 32-bit TEB in winternl.h. Currently, we care
// only about the position of the TlsSlots.
-struct TEB64
-{
- ULONG64 Reserved1[12];
- ULONG64 ProcessEnvironmentBlock;
- ULONG64 Reserved2[399];
- BYTE Reserved3[1952];
- ULONG64 TlsSlots[64];
- BYTE Reserved4[8];
- ULONG64 Reserved5[26];
- ULONG64 ReservedForOle; // Windows 2000 only
- ULONG64 Reserved6[4];
- ULONG64 TlsExpansionSlots;
+struct TEB64 {
+ ULONG64 Reserved1[12];
+ ULONG64 ProcessEnvironmentBlock;
+ ULONG64 Reserved2[399];
+ BYTE Reserved3[1952];
+ ULONG64 TlsSlots[64];
+ BYTE Reserved4[8];
+ ULONG64 Reserved5[26];
+ ULONG64 ReservedForOle; // Windows 2000 only
+ ULONG64 Reserved6[4];
+ ULONG64 TlsExpansionSlots;
};
#endif
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 2c3f9fbecf92..50f787f78495 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -9,92 +9,1065 @@
#include "ProcessWindows.h"
+// Windows includes
+#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/HostNativeProcessBase.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "DebuggerThread.h"
+#include "ExceptionRecord.h"
+#include "ForwardDecl.h"
+#include "LocalDebugDelegate.h"
+#include "ProcessWindowsLog.h"
+#include "TargetThreadWindows.h"
+
using namespace lldb;
using namespace lldb_private;
-namespace lldb_private
-{
+namespace {
+std::string GetProcessExecutableName(HANDLE process_handle) {
+ std::vector<wchar_t> file_name;
+ DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
+ DWORD copied = 0;
+ do {
+ file_name_size *= 2;
+ file_name.resize(file_name_size);
+ copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
+ file_name_size);
+ } while (copied >= file_name_size);
+ file_name.resize(copied);
+ std::string result;
+ llvm::convertWideToUTF8(file_name.data(), result);
+ return result;
+}
+
+std::string GetProcessExecutableName(DWORD pid) {
+ std::string file_name;
+ HANDLE process_handle =
+ ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ if (process_handle != NULL) {
+ file_name = GetProcessExecutableName(process_handle);
+ ::CloseHandle(process_handle);
+ }
+ return file_name;
+}
+
+} // anonymous namespace
+
+namespace lldb_private {
+
+// We store a pointer to this class in the ProcessWindows, so that we don't
+// expose Windows-specific types and implementation details from a public header
+// file.
+class ProcessWindowsData {
+public:
+ ProcessWindowsData(bool stop_at_entry) : m_stop_at_entry(stop_at_entry) {
+ m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
+ }
+
+ ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
+
+ Error m_launch_error;
+ DebuggerThreadSP m_debugger;
+ StopInfoSP m_pending_stop_info;
+ HANDLE m_initial_stop_event = nullptr;
+ bool m_initial_stop_received = false;
+ bool m_stop_at_entry;
+ std::map<lldb::tid_t, HostThread> m_new_threads;
+ std::set<lldb::tid_t> m_exited_threads;
+};
+
+ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *) {
+ return ProcessSP(new ProcessWindows(target_sp, listener_sp));
+}
+
+void ProcessWindows::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
+}
+
+void ProcessWindows::Terminate() {}
+
+lldb_private::ConstString ProcessWindows::GetPluginNameStatic() {
+ static ConstString g_name("windows");
+ return g_name;
+}
+
+const char *ProcessWindows::GetPluginDescriptionStatic() {
+ return "Process plugin for Windows";
+}
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
- : lldb_private::Process(target_sp, listener_sp)
-{
+ProcessWindows::ProcessWindows(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp)
+ : lldb_private::Process(target_sp, listener_sp) {}
+
+ProcessWindows::~ProcessWindows() {}
+
+size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Error &error) {
+ error.SetErrorString("GetSTDOUT unsupported on Windows");
+ return 0;
}
-ProcessWindows::~ProcessWindows()
-{
+size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Error &error) {
+ error.SetErrorString("GetSTDERR unsupported on Windows");
+ return 0;
}
-size_t
-ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Error &error)
-{
- error.SetErrorString("GetSTDOUT unsupported on Windows");
- return 0;
+size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size,
+ Error &error) {
+ error.SetErrorString("PutSTDIN unsupported on Windows");
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+// ProcessInterface protocol.
+
+lldb_private::ConstString ProcessWindows::GetPluginName() {
+ return GetPluginNameStatic();
+}
+
+uint32_t ProcessWindows::GetPluginVersion() { return 1; }
+
+Error ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS,
+ "EnableBreakpointSite called with bp_site 0x%p "
+ "(id=%d, addr=0x%llx)",
+ bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
+
+ Error error = EnableSoftwareBreakpoint(bp_site);
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite failed. %s",
+ error.AsCString());
+ }
+ return error;
+}
+
+Error ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS,
+ "DisableBreakpointSite called with bp_site 0x%p "
+ "(id=%d, addr=0x%llx)",
+ bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
+
+ Error error = DisableSoftwareBreakpoint(bp_site);
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite failed. %s",
+ error.AsCString());
+ }
+ return error;
+}
+
+Error ProcessWindows::DoDetach(bool keep_stopped) {
+ DebuggerThreadSP debugger_thread;
+ StateType private_state;
+ {
+ // Acquire the lock only long enough to get the DebuggerThread.
+ // StopDebugging() will trigger a call back into ProcessWindows which
+ // will also acquire the lock. Thus we have to release the lock before
+ // calling StopDebugging().
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ private_state = GetPrivateState();
+
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDetach called while state = %u, but there is no active session.",
+ private_state);
+ return Error();
+ }
+
+ debugger_thread = m_session_data->m_debugger;
+ }
+
+ Error error;
+ if (private_state != eStateExited && private_state != eStateDetached) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDetach called for process %p while state = %d. Detaching...",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ error = debugger_thread->StopDebugging(false);
+ if (error.Success()) {
+ SetPrivateState(eStateDetached);
+ }
+
+ // By the time StopDebugging returns, there is no more debugger thread, so
+ // we can be assured that no other thread will race for the session data.
+ m_session_data.reset();
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDetach called for process %p while state = "
+ "%d, but cannot destroy in this state.",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ }
+
+ return error;
+}
+
+Error ProcessWindows::DoLaunch(Module *exe_module,
+ ProcessLaunchInfo &launch_info) {
+ // Even though m_session_data is accessed here, it is before a debugger thread
+ // has been
+ // kicked off. So there's no race conditions, and it shouldn't be necessary
+ // to acquire
+ // the mutex.
+
+ Error result;
+ if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
+ StreamString stream;
+ stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can "
+ "only be used for debug launches.",
+ launch_info.GetExecutableFile().GetPath().c_str());
+ std::string message = stream.GetString();
+ result.SetErrorString(message.c_str());
+
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "%s", message.c_str());
+ return result;
+ }
+
+ bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
+ m_session_data.reset(new ProcessWindowsData(stop_at_entry));
+
+ SetPrivateState(eStateLaunching);
+ DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
+ m_session_data->m_debugger.reset(new DebuggerThread(delegate));
+ DebuggerThreadSP debugger = m_session_data->m_debugger;
+
+ // Kick off the DebugLaunch asynchronously and wait for it to complete.
+ result = debugger->DebugLaunch(launch_info);
+ if (result.Fail()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
+ launch_info.GetExecutableFile().GetPath().c_str(),
+ result.AsCString());
+ return result;
+ }
+
+ HostProcess process;
+ Error error = WaitForDebuggerConnection(debugger, process);
+ if (error.Fail()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
+ launch_info.GetExecutableFile().GetPath().c_str(),
+ error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
+ // private state
+ // should already be set to eStateStopped as a result of hitting the initial
+ // breakpoint. If
+ // it was not set, the breakpoint should have already been resumed from and
+ // the private state
+ // should already be eStateRunning.
+ launch_info.SetProcessID(process.GetProcessId());
+ SetID(process.GetProcessId());
+
+ return result;
+}
+
+Error ProcessWindows::DoAttachToProcessWithID(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
+ m_session_data.reset(
+ new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
+
+ DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
+ DebuggerThreadSP debugger(new DebuggerThread(delegate));
+
+ m_session_data->m_debugger = debugger;
+
+ DWORD process_id = static_cast<DWORD>(pid);
+ Error error = debugger->DebugAttach(process_id, attach_info);
+ if (error.Fail()) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an "
+ "error occurred initiating the "
+ "asynchronous attach. %s",
+ error.AsCString());
+ return error;
+ }
+
+ HostProcess process;
+ error = WaitForDebuggerConnection(debugger, process);
+ if (error.Fail()) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an "
+ "error waiting for the debugger to "
+ "connect. %s",
+ error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoAttachToProcessWithID successfully attached to process with pid=%lu",
+ process_id);
+
+ // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
+ // private state
+ // should already be set to eStateStopped as a result of hitting the initial
+ // breakpoint. If
+ // it was not set, the breakpoint should have already been resumed from and
+ // the private state
+ // should already be eStateRunning.
+ SetID(process.GetProcessId());
+ return error;
+}
+
+Error ProcessWindows::DoResume() {
+ llvm::sys::ScopedLock lock(m_mutex);
+ Error error;
+
+ StateType private_state = GetPrivateState();
+ if (private_state == eStateStopped || private_state == eStateCrashed) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoResume called for process %I64u while state is %u. Resuming...",
+ m_session_data->m_debugger->GetProcess().GetProcessId(),
+ GetPrivateState());
+
+ ExceptionRecordSP active_exception =
+ m_session_data->m_debugger->GetActiveException().lock();
+ if (active_exception) {
+ // Resume the process and continue processing debug events. Mask
+ // the exception so that from the process's view, there is no
+ // indication that anything happened.
+ m_session_data->m_debugger->ContinueAsyncException(
+ ExceptionResult::MaskException);
+ }
+
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_THREAD,
+ "DoResume resuming %u threads.", m_thread_list.GetSize());
+
+ for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
+ auto thread = std::static_pointer_cast<TargetThreadWindows>(
+ m_thread_list.GetThreadAtIndex(i));
+ thread->DoResume();
+ }
+
+ SetPrivateState(eStateRunning);
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoResume called for process %I64u but state is %u. Returning...",
+ m_session_data->m_debugger->GetProcess().GetProcessId(),
+ GetPrivateState());
+ }
+ return error;
+}
+
+Error ProcessWindows::DoDestroy() {
+ DebuggerThreadSP debugger_thread;
+ StateType private_state;
+ {
+ // Acquire this lock inside an inner scope, only long enough to get the
+ // DebuggerThread.
+ // StopDebugging() will trigger a call back into ProcessWindows which will
+ // acquire the lock
+ // again, so we need to not deadlock.
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ private_state = GetPrivateState();
+
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDestroy called while state = %u, but there is no active session.",
+ private_state);
+ return Error();
+ }
+
+ debugger_thread = m_session_data->m_debugger;
+ }
+
+ Error error;
+ if (private_state != eStateExited && private_state != eStateDetached) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDestroy called for process %p while state = "
+ "%u. Shutting down...",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ error = debugger_thread->StopDebugging(true);
+
+ // By the time StopDebugging returns, there is no more debugger thread, so
+ // we can be assured that no other thread will race for the session data.
+ m_session_data.reset();
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDestroy called for process %p while state = "
+ "%d, but cannot destroy in this state.",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ }
+
+ return error;
+}
+
+Error ProcessWindows::DoHalt(bool &caused_stop) {
+ Error error;
+ StateType state = GetPrivateState();
+ if (state == eStateStopped)
+ caused_stop = false;
+ else {
+ llvm::sys::ScopedLock lock(m_mutex);
+ caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
+ .GetNativeProcess()
+ .GetSystemHandle());
+ if (!caused_stop) {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoHalt called DebugBreakProcess, but it failed with error %u",
+ error.GetError());
+ }
+ }
+ return error;
}
-size_t
-ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Error &error)
-{
- error.SetErrorString("GetSTDERR unsupported on Windows");
+void ProcessWindows::DidLaunch() {
+ ArchSpec arch_spec;
+ DidAttach(arch_spec);
+}
+
+void ProcessWindows::DidAttach(ArchSpec &arch_spec) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // The initial stop won't broadcast the state change event, so account for
+ // that here.
+ if (m_session_data && GetPrivateState() == eStateStopped &&
+ m_session_data->m_stop_at_entry)
+ RefreshStateAfterStop();
+}
+
+void ProcessWindows::RefreshStateAfterStop() {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "RefreshStateAfterStop called with no active session. Returning...");
+ return;
+ }
+
+ m_thread_list.RefreshStateAfterStop();
+
+ std::weak_ptr<ExceptionRecord> exception_record =
+ m_session_data->m_debugger->GetActiveException();
+ ExceptionRecordSP active_exception = exception_record.lock();
+ if (!active_exception) {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "RefreshStateAfterStop called for process %I64u but there is no "
+ "active exception. Why is the process stopped?",
+ m_session_data->m_debugger->GetProcess().GetProcessId());
+ return;
+ }
+
+ StopInfoSP stop_info;
+ m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
+ ThreadSP stop_thread = m_thread_list.GetSelectedThread();
+ if (!stop_thread)
+ return;
+
+ switch (active_exception->GetExceptionCode()) {
+ case EXCEPTION_SINGLE_STEP: {
+ RegisterContextSP register_context = stop_thread->GetRegisterContext();
+ const uint64_t pc = register_context->GetPC();
+ BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+ if (site && site->ValidForThisThread(stop_thread.get())) {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION |
+ WINDOWS_LOG_STEP,
+ "Single-stepped onto a breakpoint in process %I64u at "
+ "address 0x%I64x with breakpoint site %d",
+ m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
+ site->GetID());
+ stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
+ site->GetID());
+ stop_thread->SetStopInfo(stop_info);
+ } else {
+ WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
+ "RefreshStateAfterStop single stepping thread %llu",
+ stop_thread->GetID());
+ stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
+ stop_thread->SetStopInfo(stop_info);
+ }
+ return;
+ }
+
+ case EXCEPTION_BREAKPOINT: {
+ RegisterContextSP register_context = stop_thread->GetRegisterContext();
+
+ // The current EIP is AFTER the BP opcode, which is one byte.
+ uint64_t pc = register_context->GetPC() - 1;
+
+ BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+ if (site) {
+ WINLOG_IFANY(
+ WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "RefreshStateAfterStop detected breakpoint in process %I64u at "
+ "address 0x%I64x with breakpoint site %d",
+ m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
+ site->GetID());
+
+ if (site->ValidForThisThread(stop_thread.get())) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "Breakpoint site %d is valid for this thread (0x%I64x), "
+ "creating stop info.",
+ site->GetID(), stop_thread->GetID());
+
+ stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *stop_thread, site->GetID());
+ register_context->SetPC(pc);
+ } else {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "Breakpoint site %d is not valid for this thread, "
+ "creating empty stop info.",
+ site->GetID());
+ }
+ stop_thread->SetStopInfo(stop_info);
+ return;
+ } else {
+ // The thread hit a hard-coded breakpoint like an `int 3` or
+ // `__debugbreak()`.
+ WINLOG_IFALL(
+ WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "No breakpoint site matches for this thread. __debugbreak()? "
+ "Creating stop info with the exception.");
+ // FALLTHROUGH: We'll treat this as a generic exception record in the
+ // default case.
+ }
+ }
+
+ default: {
+ std::string desc;
+ llvm::raw_string_ostream desc_stream(desc);
+ desc_stream << "Exception "
+ << llvm::format_hex(active_exception->GetExceptionCode(), 8)
+ << " encountered at address "
+ << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
+ stop_info = StopInfo::CreateStopReasonWithException(
+ *stop_thread, desc_stream.str().c_str());
+ stop_thread->SetStopInfo(stop_info);
+ WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, "%s", desc_stream.str().c_str());
+ return;
+ }
+ }
+}
+
+bool ProcessWindows::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ return true;
+
+ // 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();
+ // However, if there is no executable module, we return true since we might be
+ // preparing to attach.
+ return true;
+}
+
+bool ProcessWindows::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // Add all the threads that were previously running and for which we did not
+ // detect a thread exited event.
+ int new_size = 0;
+ int continued_threads = 0;
+ int exited_threads = 0;
+ int new_threads = 0;
+
+ for (ThreadSP old_thread : old_thread_list.Threads()) {
+ lldb::tid_t old_thread_id = old_thread->GetID();
+ auto exited_thread_iter =
+ m_session_data->m_exited_threads.find(old_thread_id);
+ if (exited_thread_iter == m_session_data->m_exited_threads.end()) {
+ new_thread_list.AddThread(old_thread);
+ ++new_size;
+ ++continued_threads;
+ WINLOGV_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %llu was running and is still running.",
+ old_thread_id);
+ } else {
+ WINLOGV_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %llu was running and has exited.",
+ old_thread_id);
+ ++exited_threads;
+ }
+ }
+
+ // Also add all the threads that are new since the last time we broke into the
+ // debugger.
+ for (const auto &thread_info : m_session_data->m_new_threads) {
+ ThreadSP thread(new TargetThreadWindows(*this, thread_info.second));
+ thread->SetID(thread_info.first);
+ new_thread_list.AddThread(thread);
+ ++new_size;
+ ++new_threads;
+ WINLOGV_IFALL(WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %llu is new since last update.",
+ thread_info.first);
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - %d new threads, %d old threads, %d exited threads.",
+ new_threads, continued_threads, exited_threads);
+
+ m_session_data->m_new_threads.clear();
+ m_session_data->m_exited_threads.clear();
+
+ return new_size > 0;
+}
+
+bool ProcessWindows::IsAlive() {
+ StateType state = GetPrivateState();
+ switch (state) {
+ case eStateCrashed:
+ case eStateDetached:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateInvalid:
+ return false;
+ default:
+ return true;
+ }
+}
+
+size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf,
+ size_t size, Error &error) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (!m_session_data)
return 0;
+
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY,
+ "DoReadMemory attempting to read %u bytes from address 0x%I64x",
+ size, vm_addr);
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ SIZE_T bytes_read = 0;
+ if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
+ buf, size, &bytes_read)) {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u",
+ error.GetError());
+ }
+ return bytes_read;
}
-size_t
-ProcessWindows::PutSTDIN(const char *buf, size_t buf_size, Error &error)
-{
- error.SetErrorString("PutSTDIN unsupported on Windows");
+size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
+ size_t size, Error &error) {
+ llvm::sys::ScopedLock lock(m_mutex);
+ WINLOG_IFALL(
+ WINDOWS_LOG_MEMORY,
+ "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size,
+ vm_addr);
+
+ if (!m_session_data) {
+ WINERR_IFANY(
+ WINDOWS_LOG_MEMORY,
+ "DoWriteMemory cannot write, there is no active debugger connection.");
return 0;
+ }
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ SIZE_T bytes_written = 0;
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
+ FlushInstructionCache(handle, addr, bytes_written);
+ else {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u",
+ error.GetError());
+ }
+ return bytes_written;
}
-//------------------------------------------------------------------------------
-// ProcessInterface protocol.
+#define BOOL_STR(b) ((b) ? "true" : "false")
+
+Error ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
+ MemoryRegionInfo &info) {
+ Error error;
+ llvm::sys::ScopedLock lock(m_mutex);
+ info.Clear();
+
+ if (!m_session_data) {
+ error.SetErrorString(
+ "GetMemoryRegionInfo called with no debugging session.");
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "%s", error.AsCString());
+ return error;
+ }
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
+ error.SetErrorString(
+ "GetMemoryRegionInfo called with an invalid target process.");
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "%s", error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY,
+ "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr);
+
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ MEMORY_BASIC_INFORMATION mem_info = {};
+ SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
+ if (result == 0) {
+ if (::GetLastError() == ERROR_INVALID_PARAMETER) {
+ // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an
+ // address
+ // past the highest accessible address. We should return a range from the
+ // vm_addr
+ // to LLDB_INVALID_ADDRESS
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ info.SetMapped(MemoryRegionInfo::eNo);
+ return error;
+ } else {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "VirtualQueryEx returned error %u while "
+ "getting memory region info for address "
+ "0x%I64x",
+ error.GetError(), vm_addr);
+ return error;
+ }
+ }
+ // Protect bits are only valid for MEM_COMMIT regions.
+ if (mem_info.State == MEM_COMMIT) {
+ const bool readable = IsPageReadable(mem_info.Protect);
+ const bool executable = IsPageExecutable(mem_info.Protect);
+ const bool writable = IsPageWritable(mem_info.Protect);
+ info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ info.SetExecutable(executable ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ } else {
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ }
-lldb::addr_t
-ProcessWindows::GetImageInfoAddress()
-{
- Target &target = GetTarget();
- ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(&target);
- if (addr.IsValid())
- return addr.GetLoadAddress(&target);
+ // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
+ if (mem_info.State != MEM_FREE) {
+ info.GetRange().SetRangeBase(
+ reinterpret_cast<addr_t>(mem_info.AllocationBase));
+ info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
+ mem_info.RegionSize);
+ info.SetMapped(MemoryRegionInfo::eYes);
+ } else {
+ // In the unmapped case we need to return the distance to the next block of
+ // memory.
+ // VirtualQueryEx nearly does that except that it gives the distance from
+ // the start
+ // of the page containing vm_addr.
+ SYSTEM_INFO data;
+ GetSystemInfo(&data);
+ DWORD page_offset = vm_addr % data.dwPageSize;
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
+ info.SetMapped(MemoryRegionInfo::eNo);
+ }
+
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address %llu: "
+ "readable=%s, executable=%s, writable=%s",
+ vm_addr, BOOL_STR(info.GetReadable()),
+ BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable()));
+ return error;
+}
+
+lldb::addr_t ProcessWindows::GetImageInfoAddress() {
+ Target &target = GetTarget();
+ ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(&target);
+ if (addr.IsValid())
+ return addr.GetLoadAddress(&target);
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+void ProcessWindows::OnExitProcess(uint32_t exit_code) {
+ // No need to acquire the lock since m_session_data isn't accessed.
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %llu exited with code %u", GetID(),
+ exit_code);
+
+ TargetSP target = m_target_sp.lock();
+ if (target) {
+ ModuleSP executable_module = target->GetExecutableModule();
+ ModuleList unloaded_modules;
+ unloaded_modules.Append(executable_module);
+ target->ModulesDidUnload(unloaded_modules, true);
+ }
+
+ SetProcessExitStatus(GetID(), true, 0, exit_code);
+ SetPrivateState(eStateExited);
+}
+
+void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
+ DebuggerThreadSP debugger = m_session_data->m_debugger;
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "Debugger connected to process %I64u. Image base = 0x%I64x",
+ debugger->GetProcess().GetProcessId(), image_base);
+
+ ModuleSP module = GetTarget().GetExecutableModule();
+ if (!module) {
+ // During attach, we won't have the executable module, so find it now.
+ const DWORD pid = debugger->GetProcess().GetProcessId();
+ const std::string file_name = GetProcessExecutableName(pid);
+ if (file_name.empty()) {
+ return;
+ }
+
+ FileSpec executable_file(file_name, true);
+ ModuleSpec module_spec(executable_file);
+ Error error;
+ module = GetTarget().GetSharedModule(module_spec, &error);
+ if (!module) {
+ return;
+ }
+
+ GetTarget().SetExecutableModule(module, false);
+ }
+
+ bool load_addr_changed;
+ module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
+
+ ModuleList loaded_modules;
+ loaded_modules.Append(module);
+ GetTarget().ModulesDidLoad(loaded_modules);
+
+ // Add the main executable module to the list of pending module loads. We
+ // can't call
+ // GetTarget().ModulesDidLoad() here because we still haven't returned from
+ // DoLaunch() / DoAttach() yet
+ // so the target may not have set the process instance to `this` yet.
+ llvm::sys::ScopedLock lock(m_mutex);
+ const HostThreadWindows &wmain_thread =
+ debugger->GetMainThread().GetNativeThread();
+ m_session_data->m_new_threads[wmain_thread.GetThreadId()] =
+ debugger->GetMainThread();
+}
+
+ExceptionResult
+ProcessWindows::OnDebugException(bool first_chance,
+ const ExceptionRecord &record) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // FIXME: Without this check, occasionally when running the test suite there
+ // is
+ // an issue where m_session_data can be null. It's not clear how this could
+ // happen
+ // but it only surfaces while running the test suite. In order to properly
+ // diagnose
+ // this, we probably need to first figure allow the test suite to print out
+ // full
+ // lldb logs, and then add logging to the process plugin.
+ if (!m_session_data) {
+ WINERR_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception "
+ "0x%lx at address 0x%llu, but there is "
+ "no session.",
+ record.GetExceptionCode(), record.GetExceptionAddress());
+ return ExceptionResult::SendToApplication;
+ }
+
+ if (!first_chance) {
+ // Any second chance exception is an application crash by definition.
+ SetPrivateState(eStateCrashed);
+ }
+
+ ExceptionResult result = ExceptionResult::SendToApplication;
+ switch (record.GetExceptionCode()) {
+ case EXCEPTION_BREAKPOINT:
+ // Handle breakpoints at the first chance.
+ result = ExceptionResult::BreakInDebugger;
+
+ if (!m_session_data->m_initial_stop_received) {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS, "Hit loader breakpoint at address "
+ "0x%I64x, setting initial stop "
+ "event.",
+ record.GetExceptionAddress());
+ m_session_data->m_initial_stop_received = true;
+ ::SetEvent(m_session_data->m_initial_stop_event);
+ } else {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
+ "Hit non-loader breakpoint at address 0x%I64x.",
+ record.GetExceptionAddress());
+ }
+ SetPrivateState(eStateStopped);
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ result = ExceptionResult::BreakInDebugger;
+ SetPrivateState(eStateStopped);
+ break;
+ default:
+ WINLOG_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception "
+ "0x%lx at address 0x%llx "
+ "(first_chance=%s)",
+ record.GetExceptionCode(), record.GetExceptionAddress(),
+ BOOL_STR(first_chance));
+ // For non-breakpoints, give the application a chance to handle the
+ // exception first.
+ if (first_chance)
+ result = ExceptionResult::SendToApplication;
else
- return LLDB_INVALID_ADDRESS;
+ result = ExceptionResult::BreakInDebugger;
+ }
+
+ return result;
+}
+
+void ProcessWindows::OnCreateThread(const HostThread &new_thread) {
+ llvm::sys::ScopedLock lock(m_mutex);
+ const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
+ m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
+}
+
+void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // On a forced termination, we may get exit thread events after the session
+ // data has been cleaned up.
+ if (!m_session_data)
+ return;
+
+ // A thread may have started and exited before the debugger stopped allowing a
+ // refresh.
+ // Just remove it from the new threads list in that case.
+ auto iter = m_session_data->m_new_threads.find(thread_id);
+ if (iter != m_session_data->m_new_threads.end())
+ m_session_data->m_new_threads.erase(iter);
+ else
+ m_session_data->m_exited_threads.insert(thread_id);
+}
+
+void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) {
+ // Confusingly, there is no Target::AddSharedModule. Instead, calling
+ // GetSharedModule() with
+ // a new module will add it to the module list and return a corresponding
+ // ModuleSP.
+ Error error;
+ ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
+ bool load_addr_changed = false;
+ module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
+
+ ModuleList loaded_modules;
+ loaded_modules.Append(module);
+ GetTarget().ModulesDidLoad(loaded_modules);
+}
+
+void ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) {
+ Address resolved_addr;
+ if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) {
+ ModuleSP module = resolved_addr.GetModule();
+ if (module) {
+ ModuleList unloaded_modules;
+ unloaded_modules.Append(module);
+ GetTarget().ModulesDidUnload(unloaded_modules, false);
+ }
+ }
+}
+
+void ProcessWindows::OnDebugString(const std::string &string) {}
+
+void ProcessWindows::OnDebuggerError(const Error &error, uint32_t type) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (m_session_data->m_initial_stop_received) {
+ // This happened while debugging. Do we shutdown the debugging session, try
+ // to continue,
+ // or do something else?
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred during debugging. "
+ "Unexpected behavior may result. %s",
+ error.GetError(), error.AsCString());
+ } else {
+ // If we haven't actually launched the process yet, this was an error
+ // launching the
+ // process. Set the internal error and signal the initial stop event so
+ // that the DoLaunch
+ // method wakes up and returns a failure.
+ m_session_data->m_launch_error = error;
+ ::SetEvent(m_session_data->m_initial_stop_event);
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "Error %u occurred launching the process before the initial stop. %s",
+ error.GetError(), error.AsCString());
+ return;
+ }
}
-// The Windows page protection bits are NOT independent masks that can be bitwise-ORed
-// together. For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE | PAGE_READ).
-// To test for an access type, it's necessary to test for any of the bits that provide
-// that access type.
-bool
-ProcessWindows::IsPageReadable(uint32_t protect)
-{
- return (protect & PAGE_NOACCESS) == 0;
+Error ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger,
+ HostProcess &process) {
+ Error result;
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS,
+ "WaitForDebuggerConnection Waiting for loader breakpoint.");
+
+ // Block this function until we receive the initial stop from the process.
+ if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
+ WAIT_OBJECT_0) {
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS,
+ "WaitForDebuggerConnection hit loader breakpoint, returning.");
+
+ process = debugger->GetProcess();
+ return m_session_data->m_launch_error;
+ } else
+ return Error(::GetLastError(), eErrorTypeWin32);
}
-bool
-ProcessWindows::IsPageWritable(uint32_t protect)
-{
- return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
+// The Windows page protection bits are NOT independent masks that can be
+// bitwise-ORed together. For example, PAGE_EXECUTE_READ is not
+// (PAGE_EXECUTE | PAGE_READ). To test for an access type, it's necessary to
+// test for any of the bits that provide that access type.
+bool ProcessWindows::IsPageReadable(uint32_t protect) {
+ return (protect & PAGE_NOACCESS) == 0;
}
-bool
-ProcessWindows::IsPageExecutable(uint32_t protect)
-{
- return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;
+bool ProcessWindows::IsPageWritable(uint32_t protect) {
+ return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
+ PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
}
+bool ProcessWindows::IsPageExecutable(uint32_t protect) {
+ return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
+ PAGE_EXECUTE_WRITECOPY)) != 0;
}
+
+} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.h b/source/Plugins/Process/Windows/Common/ProcessWindows.h
index 0ee42e2ae1f1..fac06c46b2ba 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -11,42 +11,109 @@
#define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
// Other libraries and framework includes
-#include "lldb/lldb-forward.h"
#include "lldb/Core/Error.h"
#include "lldb/Target/Process.h"
+#include "lldb/lldb-forward.h"
+
+#include "llvm/Support/Mutex.h"
+
+#include "IDebugDelegate.h"
+
+namespace lldb_private {
-namespace lldb_private
-{
+class HostProcess;
+class ProcessWindowsData;
-class ProcessWindows : public lldb_private::Process
-{
+class ProcessWindows : public Process, public IDebugDelegate {
public:
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessWindows(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp);
+ //------------------------------------------------------------------
+ // Static functions.
+ //------------------------------------------------------------------
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *);
- ~ProcessWindows();
+ static void Initialize();
- size_t GetSTDOUT(char *buf, size_t buf_size, lldb_private::Error &error) override;
- size_t GetSTDERR(char *buf, size_t buf_size, lldb_private::Error &error) override;
- size_t PutSTDIN(const char *buf, size_t buf_size, lldb_private::Error &error) override;
+ static void Terminate();
- lldb::addr_t GetImageInfoAddress() override;
+ static lldb_private::ConstString GetPluginNameStatic();
-protected:
- // These decode the page protection bits.
- static bool
- IsPageReadable(uint32_t protect);
+ static const char *GetPluginDescriptionStatic();
- static bool
- IsPageWritable(uint32_t protect);
+ //------------------------------------------------------------------
+ // Constructors and destructors
+ //------------------------------------------------------------------
+ ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
- static bool
- IsPageExecutable(uint32_t protect);
-};
+ ~ProcessWindows();
+
+ size_t GetSTDOUT(char *buf, size_t buf_size, Error &error) override;
+ size_t GetSTDERR(char *buf, size_t buf_size, Error &error) override;
+ size_t PutSTDIN(const char *buf, size_t buf_size, Error &error) override;
+
+ // lldb_private::Process overrides
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ Error EnableBreakpointSite(BreakpointSite *bp_site) override;
+ Error DisableBreakpointSite(BreakpointSite *bp_site) override;
+
+ Error DoDetach(bool keep_stopped) override;
+ Error DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
+ Error DoAttachToProcessWithID(
+ lldb::pid_t pid,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
+ Error DoResume() override;
+ Error DoDestroy() override;
+ Error DoHalt(bool &caused_stop) override;
+ void DidLaunch() override;
+ void DidAttach(lldb_private::ArchSpec &arch_spec) override;
+
+ void RefreshStateAfterStop() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+ bool DestroyRequiresHalt() override { return false; }
+ bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
+ bool IsAlive() override;
+
+ size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Error &error) override;
+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ Error &error) override;
+ Error GetMemoryRegionInfo(lldb::addr_t vm_addr,
+ MemoryRegionInfo &info) override;
+
+ lldb::addr_t GetImageInfoAddress() override;
+
+ // IDebugDelegate overrides.
+ void OnExitProcess(uint32_t exit_code) override;
+ void OnDebuggerConnected(lldb::addr_t image_base) override;
+ ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) override;
+ void OnCreateThread(const HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
+ void OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) override;
+ void OnUnloadDll(lldb::addr_t module_addr) override;
+ void OnDebugString(const std::string &string) override;
+ void OnDebuggerError(const Error &error, uint32_t type) override;
+
+private:
+ Error WaitForDebuggerConnection(DebuggerThreadSP debugger,
+ HostProcess &process);
+
+ // These decode the page protection bits.
+ static bool IsPageReadable(uint32_t protect);
+ static bool IsPageWritable(uint32_t protect);
+ static bool IsPageExecutable(uint32_t protect);
+
+ llvm::sys::Mutex m_mutex;
+ std::unique_ptr<ProcessWindowsData> m_session_data;
+};
}
-#endif // liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
+#endif // liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
index 47722c5146b2..242c1996bdd4 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
@@ -18,177 +18,151 @@
using namespace lldb;
using namespace lldb_private;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
// that will construct the static g_log_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = nullptr;
+static Log *g_log = nullptr;
static llvm::ManagedStatic<std::once_flag> g_once_flag;
-void
-ProcessWindowsLog::Initialize()
-{
- static ConstString g_name("windows");
-
- std::call_once(*g_once_flag, [](){
- Log::Callbacks log_callbacks = {
- DisableLog,
- EnableLog,
- ListLogCategories
- };
-
- Log::RegisterLogChannel(g_name, log_callbacks);
- RegisterPluginName(g_name);
- });
-}
+void ProcessWindowsLog::Initialize() {
+ static ConstString g_name("windows");
-void
-ProcessWindowsLog::Terminate()
-{
-}
+ std::call_once(*g_once_flag, []() {
+ Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
-Log *
-ProcessWindowsLog::GetLog()
-{
- return (g_log_enabled) ? g_log : nullptr;
+ Log::RegisterLogChannel(g_name, log_callbacks);
+ RegisterPluginName(g_name);
+ });
}
-bool
-ProcessWindowsLog::TestLogFlags(uint32_t mask, LogMaskReq req)
-{
- Log *log = GetLog();
- if (!log)
- return false;
+void ProcessWindowsLog::Terminate() {}
- uint32_t log_mask = log->GetMask().Get();
- if (req == LogMaskReq::All)
- return ((log_mask & mask) == mask);
- else
- return (log_mask & mask);
+Log *ProcessWindowsLog::GetLog() { return (g_log_enabled) ? g_log : nullptr; }
+
+bool ProcessWindowsLog::TestLogFlags(uint32_t mask, LogMaskReq req) {
+ Log *log = GetLog();
+ if (!log)
+ return false;
+
+ uint32_t log_mask = log->GetMask().Get();
+ if (req == LogMaskReq::All)
+ return ((log_mask & mask) == mask);
+ else
+ return (log_mask & mask);
}
-static uint32_t
-GetFlagBits(const char *arg)
-{
- if (::strcasecmp(arg, "all") == 0 ) return WINDOWS_LOG_ALL;
- else if (::strcasecmp(arg, "break") == 0 ) return WINDOWS_LOG_BREAKPOINTS;
- else if (::strcasecmp(arg, "event") == 0 ) return WINDOWS_LOG_EVENT;
- else if (::strcasecmp(arg, "exception") == 0 ) return WINDOWS_LOG_EXCEPTION;
- else if (::strcasecmp(arg, "memory") == 0 ) return WINDOWS_LOG_MEMORY;
- else if (::strcasecmp(arg, "process") == 0 ) return WINDOWS_LOG_PROCESS;
- else if (::strcasecmp(arg, "registers") == 0 ) return WINDOWS_LOG_REGISTERS;
- else if (::strcasecmp(arg, "step") == 0 ) return WINDOWS_LOG_STEP;
- else if (::strcasecmp(arg, "thread") == 0 ) return WINDOWS_LOG_THREAD;
- else if (::strcasecmp(arg, "verbose") == 0 ) return WINDOWS_LOG_VERBOSE;
- return 0;
+static uint32_t GetFlagBits(const char *arg) {
+ if (::strcasecmp(arg, "all") == 0)
+ return WINDOWS_LOG_ALL;
+ else if (::strcasecmp(arg, "break") == 0)
+ return WINDOWS_LOG_BREAKPOINTS;
+ else if (::strcasecmp(arg, "event") == 0)
+ return WINDOWS_LOG_EVENT;
+ else if (::strcasecmp(arg, "exception") == 0)
+ return WINDOWS_LOG_EXCEPTION;
+ else if (::strcasecmp(arg, "memory") == 0)
+ return WINDOWS_LOG_MEMORY;
+ else if (::strcasecmp(arg, "process") == 0)
+ return WINDOWS_LOG_PROCESS;
+ else if (::strcasecmp(arg, "registers") == 0)
+ return WINDOWS_LOG_REGISTERS;
+ else if (::strcasecmp(arg, "step") == 0)
+ return WINDOWS_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ return WINDOWS_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ return WINDOWS_LOG_VERBOSE;
+ return 0;
}
-void
-ProcessWindowsLog::DisableLog(const char **args, Stream *feedback_strm)
-{
- Log *log (GetLog());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- if (args[0] != nullptr)
- {
- flag_bits = log->GetMask().Get();
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits &= ~bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories(feedback_strm);
- }
- }
- }
+void ProcessWindowsLog::DisableLog(const char **args, Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
+ uint32_t flag_bits = 0;
- log->GetMask().Reset(flag_bits);
- if (flag_bits == 0)
- {
- g_log_enabled = false;
- log->SetStream(lldb::StreamSP());
+ if (args[0] != nullptr) {
+ flag_bits = log->GetMask().Get();
+ for (; args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits &= ~bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
}
+ }
}
- return;
-}
-
-Log *
-ProcessWindowsLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
- uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
+ log->GetMask().Reset(flag_bits);
+ if (flag_bits == 0) {
+ g_log_enabled = false;
+ log->SetStream(lldb::StreamSP());
}
+ }
+ return;
+}
+
+Log *ProcessWindowsLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **args, Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits |= bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (; args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits |= bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = WINDOWS_LOG_ALL;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
- g_log_enabled = true;
+ }
}
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = WINDOWS_LOG_ALL;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ g_log_enabled = true;
+ }
+ return g_log;
}
-void
-ProcessWindowsLog::ListLogCategories(Stream *strm)
-{
- strm->Printf("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " break - log breakpoints\n"
- " event - log low level debugger events\n"
- " exception - log exception information\n"
- " memory - log memory reads and writes\n"
- " process - log process events and activities\n"
- " registers - log register read/writes\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n",
- ProcessWindowsLog::m_pluginname);
+void ProcessWindowsLog::ListLogCategories(Stream *strm) {
+ strm->Printf("Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " break - log breakpoints\n"
+ " event - log low level debugger events\n"
+ " exception - log exception information\n"
+ " memory - log memory reads and writes\n"
+ " process - log process events and activities\n"
+ " registers - log register read/writes\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n",
+ ProcessWindowsLog::m_pluginname);
}
const char *ProcessWindowsLog::m_pluginname = "";
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
index d798d131faeb..cbb99e8d907e 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
+++ b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
@@ -12,85 +12,80 @@
#include "lldb/Core/Log.h"
-#define WINDOWS_LOG_VERBOSE (1u << 0)
-#define WINDOWS_LOG_PROCESS (1u << 1) // Log process operations
-#define WINDOWS_LOG_EXCEPTION (1u << 1) // Log exceptions
-#define WINDOWS_LOG_THREAD (1u << 2) // Log thread operations
-#define WINDOWS_LOG_MEMORY (1u << 3) // Log memory reads/writes calls
-#define WINDOWS_LOG_BREAKPOINTS (1u << 4) // Log breakpoint operations
-#define WINDOWS_LOG_STEP (1u << 5) // Log step operations
-#define WINDOWS_LOG_REGISTERS (1u << 6) // Log register operations
-#define WINDOWS_LOG_EVENT (1u << 7) // Low level debug events
-#define WINDOWS_LOG_ALL (UINT32_MAX)
-
-enum class LogMaskReq
-{
- All,
- Any
-};
-
-class ProcessWindowsLog
-{
- static const char *m_pluginname;
+#define WINDOWS_LOG_VERBOSE (1u << 0)
+#define WINDOWS_LOG_PROCESS (1u << 1) // Log process operations
+#define WINDOWS_LOG_EXCEPTION (1u << 1) // Log exceptions
+#define WINDOWS_LOG_THREAD (1u << 2) // Log thread operations
+#define WINDOWS_LOG_MEMORY (1u << 3) // Log memory reads/writes calls
+#define WINDOWS_LOG_BREAKPOINTS (1u << 4) // Log breakpoint operations
+#define WINDOWS_LOG_STEP (1u << 5) // Log step operations
+#define WINDOWS_LOG_REGISTERS (1u << 6) // Log register operations
+#define WINDOWS_LOG_EVENT (1u << 7) // Low level debug events
+#define WINDOWS_LOG_ALL (UINT32_MAX)
+
+enum class LogMaskReq { All, Any };
+
+class ProcessWindowsLog {
+ static const char *m_pluginname;
public:
- // ---------------------------------------------------------------------
- // Public Static Methods
- // ---------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static void
- RegisterPluginName(const char *pluginName)
- {
- m_pluginname = pluginName;
- }
-
- static void
- RegisterPluginName(lldb_private::ConstString pluginName)
- {
- m_pluginname = pluginName.GetCString();
- }
-
- static bool
- TestLogFlags(uint32_t mask, LogMaskReq req);
-
- static lldb_private::Log *
- GetLog();
-
- static void
- DisableLog(const char **args, lldb_private::Stream *feedback_strm);
-
- static lldb_private::Log *
- EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options,
- const char **args, lldb_private::Stream *feedback_strm);
-
- static void
- ListLogCategories(lldb_private::Stream *strm);
+ // ---------------------------------------------------------------------
+ // Public Static Methods
+ // ---------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static void RegisterPluginName(const char *pluginName) {
+ m_pluginname = pluginName;
+ }
+
+ static void RegisterPluginName(lldb_private::ConstString pluginName) {
+ m_pluginname = pluginName.GetCString();
+ }
+
+ static bool TestLogFlags(uint32_t mask, LogMaskReq req);
+
+ static lldb_private::Log *GetLog();
+
+ static void DisableLog(const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp,
+ uint32_t log_options, const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static void ListLogCategories(lldb_private::Stream *strm);
};
-#define WINLOGF_IF(Flags, Req, Method, ...) \
- { \
- if (ProcessWindowsLog::TestLogFlags(Flags, Req)) \
- { \
- Log *log = ProcessWindowsLog::GetLog(); \
- if (log) \
- log->Method(__VA_ARGS__); \
- } \
- }
-
-#define WINLOG_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Printf, __VA_ARGS__)
-#define WINLOG_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Printf, __VA_ARGS__)
-#define WINLOGV_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Verbose, __VA_ARGS__)
-#define WINLOGV_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Verbose, __VA_ARGS__)
-#define WINLOGD_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Debug, __VA_ARGS__)
-#define WINLOGD_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Debug, __VA_ARGS__)
-#define WINERR_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Error, __VA_ARGS__)
-#define WINERR_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Error, __VA_ARGS__)
-#define WINWARN_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Warning, __VA_ARGS__)
-#define WINWARN_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Warning, __VA_ARGS__)
-
-#endif // liblldb_ProcessWindowsLog_h_
+#define WINLOGF_IF(Flags, Req, Method, ...) \
+ { \
+ if (ProcessWindowsLog::TestLogFlags(Flags, Req)) { \
+ Log *log = ProcessWindowsLog::GetLog(); \
+ if (log) \
+ log->Method(__VA_ARGS__); \
+ } \
+ }
+
+#define WINLOG_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Printf, __VA_ARGS__)
+#define WINLOG_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Printf, __VA_ARGS__)
+#define WINLOGV_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Verbose, __VA_ARGS__)
+#define WINLOGV_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Verbose, __VA_ARGS__)
+#define WINLOGD_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Debug, __VA_ARGS__)
+#define WINLOGD_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Debug, __VA_ARGS__)
+#define WINERR_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Error, __VA_ARGS__)
+#define WINERR_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Error, __VA_ARGS__)
+#define WINWARN_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Warning, __VA_ARGS__)
+#define WINWARN_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Warning, __VA_ARGS__)
+
+#endif // liblldb_ProcessWindowsLog_h_
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
index d61675f09b1b..0ef3c77e47c1 100644
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
#include "ProcessWindowsLog.h"
#include "RegisterContextWindows.h"
@@ -27,129 +27,109 @@ const DWORD kWinContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
-RegisterContextWindows::RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContext(thread, concrete_frame_idx)
- , m_context()
- , m_context_stale(true)
-{
-}
+RegisterContextWindows::RegisterContextWindows(Thread &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), m_context(),
+ m_context_stale(true) {}
-RegisterContextWindows::~RegisterContextWindows()
-{
-}
+RegisterContextWindows::~RegisterContextWindows() {}
-void
-RegisterContextWindows::InvalidateAllRegisters()
-{
- m_context_stale = true;
+void RegisterContextWindows::InvalidateAllRegisters() {
+ m_context_stale = true;
}
-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));
- }
- memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
- return true;
+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));
+ }
+ memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
+ return true;
}
-bool
-RegisterContextWindows::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- assert(data_sp->GetByteSize() >= sizeof(m_context));
- memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));
+bool RegisterContextWindows::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ assert(data_sp->GetByteSize() >= sizeof(m_context));
+ memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- if (!::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context))
- return false;
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ if (!::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
+ &m_context))
+ return false;
- return true;
+ return true;
}
-uint32_t
-RegisterContextWindows::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
+uint32_t RegisterContextWindows::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
- return LLDB_INVALID_REGNUM;
+ return LLDB_INVALID_REGNUM;
}
//------------------------------------------------------------------
// Subclasses can these functions if desired
//------------------------------------------------------------------
-uint32_t
-RegisterContextWindows::NumSupportedHardwareBreakpoints()
-{
- // Support for hardware breakpoints not yet implemented.
- return 0;
+uint32_t RegisterContextWindows::NumSupportedHardwareBreakpoints() {
+ // Support for hardware breakpoints not yet implemented.
+ return 0;
}
-uint32_t
-RegisterContextWindows::SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
-{
- return 0;
+uint32_t RegisterContextWindows::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ return 0;
}
-bool
-RegisterContextWindows::ClearHardwareBreakpoint(uint32_t hw_idx)
-{
- return false;
+bool RegisterContextWindows::ClearHardwareBreakpoint(uint32_t hw_idx) {
+ return false;
}
-uint32_t
-RegisterContextWindows::NumSupportedHardwareWatchpoints()
-{
- // Support for hardware watchpoints not yet implemented.
- return 0;
+uint32_t RegisterContextWindows::NumSupportedHardwareWatchpoints() {
+ // Support for hardware watchpoints not yet implemented.
+ return 0;
}
-uint32_t
-RegisterContextWindows::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write)
-{
- return 0;
+uint32_t RegisterContextWindows::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size, bool read,
+ bool write) {
+ return 0;
}
-bool
-RegisterContextWindows::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextWindows::ClearHardwareWatchpoint(uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextWindows::HardwareSingleStep(bool enable)
-{
- return false;
-}
+bool RegisterContextWindows::HardwareSingleStep(bool enable) { return false; }
-bool
-RegisterContextWindows::CacheAllRegisterValues()
-{
- if (!m_context_stale)
- return true;
-
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- memset(&m_context, 0, sizeof(m_context));
- m_context.ContextFlags = kWinContextFlags;
- if (!::GetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context))
- {
- WINERR_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext failed with error %u while caching register values.",
- ::GetLastError());
- return false;
- }
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext successfully updated the register values.", ::GetLastError());
- m_context_stale = false;
+bool RegisterContextWindows::CacheAllRegisterValues() {
+ if (!m_context_stale)
return true;
+
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ memset(&m_context, 0, sizeof(m_context));
+ m_context.ContextFlags = kWinContextFlags;
+ if (!::GetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
+ &m_context)) {
+ WINERR_IFALL(
+ WINDOWS_LOG_REGISTERS,
+ "GetThreadContext failed with error %lu while caching register values.",
+ ::GetLastError());
+ return false;
+ }
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS,
+ "GetThreadContext successfully updated the register values.");
+ m_context_stale = false;
+ return true;
}
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.h b/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
index 66b7a9004ead..bd09295c2f23 100644
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
+++ b/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
@@ -10,57 +10,57 @@
#ifndef liblldb_RegisterContextWindows_H_
#define liblldb_RegisterContextWindows_H_
-#include "lldb/lldb-forward.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindows : public lldb_private::RegisterContext
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindows : public lldb_private::RegisterContext {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindows();
+ virtual ~RegisterContextWindows();
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- void InvalidateAllRegisters() override;
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ void InvalidateAllRegisters() override;
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- //------------------------------------------------------------------
- // Subclasses can override these functions if desired
- //------------------------------------------------------------------
- uint32_t NumSupportedHardwareBreakpoints() override;
+ //------------------------------------------------------------------
+ // Subclasses can override these functions if desired
+ //------------------------------------------------------------------
+ uint32_t NumSupportedHardwareBreakpoints() override;
- uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- uint32_t NumSupportedHardwareWatchpoints() override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- bool HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
- protected:
- virtual bool CacheAllRegisterValues();
+protected:
+ virtual bool CacheAllRegisterValues();
- CONTEXT m_context;
- bool m_context_stale;
+ CONTEXT m_context;
+ bool m_context_stale;
};
}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
index dcb6f0c72435..8f2603c3365b 100644
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
@@ -16,83 +16,110 @@
#include "lldb/Host/windows/windows.h"
#include "lldb/Target/RegisterContext.h"
-#include "TargetThreadWindows.h"
#include "ProcessWindows.h"
#include "ProcessWindowsLog.h"
+#include "TargetThreadWindows.h"
#include "UnwindLLDB.h"
+#if defined(_WIN64)
+#include "x64/RegisterContextWindows_x64.h"
+#else
+#include "x86/RegisterContextWindows_x86.h"
+#endif
+
using namespace lldb;
using namespace lldb_private;
-TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread)
- : Thread(process, thread.GetNativeThread().GetThreadId())
- , m_host_thread(thread)
-{
-}
+TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
+ const HostThread &thread)
+ : Thread(process, thread.GetNativeThread().GetThreadId()),
+ m_host_thread(thread) {}
-TargetThreadWindows::~TargetThreadWindows()
-{
- DestroyThread();
-}
+TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
-void
-TargetThreadWindows::RefreshStateAfterStop()
-{
- ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
- SetState(eStateStopped);
- GetRegisterContext()->InvalidateIfNeeded(false);
+void TargetThreadWindows::RefreshStateAfterStop() {
+ ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
+ SetState(eStateStopped);
+ GetRegisterContext()->InvalidateIfNeeded(false);
}
-void
-TargetThreadWindows::WillResume(lldb::StateType resume_state)
-{
+void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
+
+void TargetThreadWindows::DidStop() {}
+
+RegisterContextSP TargetThreadWindows::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
+
+ return m_reg_context_sp;
}
-void
-TargetThreadWindows::DidStop()
-{
+RegisterContextSP
+TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) {
+ return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
}
-bool
-TargetThreadWindows::CalculateStopInfo()
-{
- SetStopInfo(m_stop_info_sp);
- return true;
+RegisterContextSP
+TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) {
+ if (!m_reg_context_sp) {
+ ArchSpec arch = HostInfo::GetArchitecture();
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86:
+#if defined(_WIN64)
+// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
+#else
+ m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx));
+#endif
+ break;
+ case llvm::Triple::x86_64:
+#if defined(_WIN64)
+ m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx));
+#else
+// LLDB is 32-bit, but the target process is 64-bit. We probably can't debug
+// this.
+#endif
+ default:
+ break;
+ }
+ }
+ return m_reg_context_sp;
}
-Unwind *
-TargetThreadWindows::GetUnwinder()
-{
- // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
- if (m_unwinder_ap.get() == NULL)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
- return m_unwinder_ap.get();
+bool TargetThreadWindows::CalculateStopInfo() {
+ SetStopInfo(m_stop_info_sp);
+ return true;
}
-bool
-TargetThreadWindows::DoResume()
-{
- StateType resume_state = GetTemporaryResumeState();
- StateType current_state = GetState();
- if (resume_state == current_state)
- return true;
-
- if (resume_state == eStateStepping)
- {
- uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
- flags_value |= 0x100; // Set the trap flag on the CPU
- GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
- }
+Unwind *TargetThreadWindows::GetUnwinder() {
+ // FIXME: Implement an unwinder based on the Windows unwinder exposed through
+ // DIA SDK.
+ if (m_unwinder_ap.get() == NULL)
+ m_unwinder_ap.reset(new UnwindLLDB(*this));
+ return m_unwinder_ap.get();
+}
- if (resume_state == eStateStepping || resume_state == eStateRunning)
- {
- DWORD previous_suspend_count = 0;
- HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
- do
- {
- previous_suspend_count = ::ResumeThread(thread_handle);
- } while (previous_suspend_count > 0);
- }
+bool TargetThreadWindows::DoResume() {
+ StateType resume_state = GetTemporaryResumeState();
+ StateType current_state = GetState();
+ if (resume_state == current_state)
return true;
+
+ if (resume_state == eStateStepping) {
+ uint32_t flags_index =
+ GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ uint64_t flags_value =
+ GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
+ flags_value |= 0x100; // Set the trap flag on the CPU
+ GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
+ }
+
+ if (resume_state == eStateStepping || resume_state == eStateRunning) {
+ DWORD previous_suspend_count = 0;
+ HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
+ do {
+ previous_suspend_count = ::ResumeThread(thread_handle);
+ } while (previous_suspend_count > 0);
+ }
+ return true;
}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
index 701b56b6d26a..8b4e3dfdda4a 100644
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
+++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
@@ -11,39 +11,40 @@
#define liblldb_Plugins_Process_Windows_TargetThreadWindows_H_
//#include "ForwardDecl.h"
-#include "lldb/lldb-forward.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+#include "RegisterContextWindows.h"
+
+namespace lldb_private {
class ProcessWindows;
class HostThread;
class StackFrame;
-class TargetThreadWindows : public lldb_private::Thread
-{
- public:
- TargetThreadWindows(ProcessWindows &process, const HostThread &thread);
- virtual ~TargetThreadWindows();
-
- // lldb_private::Thread overrides
- void RefreshStateAfterStop() override;
- void WillResume(lldb::StateType resume_state) override;
- void DidStop() override;
- bool CalculateStopInfo() override;
- Unwind *GetUnwinder() override;
-
- bool DoResume();
-
- HostThread
- GetHostThread() const
- {
- return m_host_thread;
- }
-
- private:
- HostThread m_host_thread;
+class TargetThreadWindows : public lldb_private::Thread {
+public:
+ TargetThreadWindows(ProcessWindows &process, const HostThread &thread);
+ virtual ~TargetThreadWindows();
+
+ // lldb_private::Thread overrides
+ void RefreshStateAfterStop() override;
+ void WillResume(lldb::StateType resume_state) override;
+ void DidStop() override;
+ lldb::RegisterContextSP GetRegisterContext() override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+ bool CalculateStopInfo() override;
+ Unwind *GetUnwinder() override;
+
+ bool DoResume();
+
+ HostThread GetHostThread() const { return m_host_thread; }
+
+private:
+ lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
+
+ HostThread m_host_thread;
};
}
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
index 3a9c31a0b776..942b4e97c40d 100644
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
+++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
@@ -7,16 +7,16 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
-#include "lldb-x86-register-enums.h"
-#include "RegisterContext_x86.h"
#include "RegisterContextWindows_x64.h"
+#include "RegisterContext_x86.h"
#include "TargetThreadWindows.h"
+#include "lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
@@ -26,302 +26,317 @@ using namespace lldb_private;
#define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase
#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
-namespace
-{
+namespace {
-// This enum defines the layout of the global RegisterInfo array. This is necessary because
-// lldb register sets are defined in terms of indices into the register array. As such, the
-// order of RegisterInfos defined in global registers array must match the order defined here.
-// When defining the register set layouts, these values can appear in an arbitrary order, and that
+// This enum defines the layout of the global RegisterInfo array. This is
+// necessary because
+// lldb register sets are defined in terms of indices into the register array.
+// As such, the
+// order of RegisterInfos defined in global registers array must match the order
+// defined here.
+// When defining the register set layouts, these values can appear in an
+// arbitrary order, and that
// determines the order that register values are displayed in a dump.
-enum RegisterIndex
-{
- eRegisterIndexRax,
- eRegisterIndexRbx,
- eRegisterIndexRcx,
- eRegisterIndexRdx,
- eRegisterIndexRdi,
- eRegisterIndexRsi,
- eRegisterIndexR8,
- eRegisterIndexR9,
- eRegisterIndexR10,
- eRegisterIndexR11,
- eRegisterIndexR12,
- eRegisterIndexR13,
- eRegisterIndexR14,
- eRegisterIndexR15,
- eRegisterIndexRbp,
- eRegisterIndexRsp,
- eRegisterIndexRip,
- eRegisterIndexRflags
+enum RegisterIndex {
+ eRegisterIndexRax,
+ eRegisterIndexRbx,
+ eRegisterIndexRcx,
+ eRegisterIndexRdx,
+ eRegisterIndexRdi,
+ eRegisterIndexRsi,
+ eRegisterIndexR8,
+ eRegisterIndexR9,
+ eRegisterIndexR10,
+ eRegisterIndexR11,
+ eRegisterIndexR12,
+ eRegisterIndexR13,
+ eRegisterIndexR14,
+ eRegisterIndexR15,
+ eRegisterIndexRbp,
+ eRegisterIndexRsp,
+ eRegisterIndexRip,
+ eRegisterIndexRflags
};
// Array of all register information supported by Windows x86
RegisterInfo g_register_infos[] = {
- // Macro auto defines most stuff eh_frame DWARF GENERIC
+ // Macro auto defines most stuff eh_frame DWARF
+ // GENERIC
// GDB LLDB VALUE REGS INVALIDATE REGS
- // ================================ ========================= ====================== =========================
+ // ================================ =========================
+ // ====================== =========================
// =================== ================= ========== ===============
{DEFINE_GPR(rax, nullptr),
- {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rax_x86_64},
+ {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rax_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rbx, nullptr),
- {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rbx_x86_64},
+ {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rbx_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rcx, nullptr),
- {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
+ {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rdx, nullptr),
- {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
+ {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rdi, nullptr),
- {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdi_x86_64},
+ {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rdi_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rsi, nullptr),
- {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
+ {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r8, nullptr),
- {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r8_x86_64},
+ {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r8_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r9, nullptr),
- {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r9_x86_64},
+ {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r9_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r10, nullptr),
- {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r10_x86_64},
+ {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r10_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r11, nullptr),
- {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r11_x86_64},
+ {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r11_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r12, nullptr),
- {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r12_x86_64},
+ {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r12_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r13, nullptr),
- {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r13_x86_64},
+ {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r13_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r14, nullptr),
- {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r14_x86_64},
+ {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r14_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r15, nullptr),
- {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r15_x86_64},
+ {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r15_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rbp, "fp"),
- {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
+ {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rsp, "sp"),
- {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
+ {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rip, "pc"),
- {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_rip_x86_64},
+ {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, lldb_rip_x86_64},
nullptr,
nullptr},
{DEFINE_GPR_BIN(eflags, "flags"),
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
nullptr,
nullptr},
};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-// Array of lldb register numbers used to define the set of all General Purpose Registers
-uint32_t g_gpr_reg_indices[] = {eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, eRegisterIndexRdx,
- eRegisterIndexRdi, eRegisterIndexRsi, eRegisterIndexR8, eRegisterIndexR9,
- eRegisterIndexR10, eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13,
- eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp, eRegisterIndexRsp,
- eRegisterIndexRip, eRegisterIndexRflags};
+// Array of lldb register numbers used to define the set of all General Purpose
+// Registers
+uint32_t g_gpr_reg_indices[] = {
+ eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
+ eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
+ eRegisterIndexR8, eRegisterIndexR9, eRegisterIndexR10,
+ eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13,
+ eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp,
+ eRegisterIndexRsp, eRegisterIndexRip, eRegisterIndexRflags};
RegisterSet g_register_sets[] = {
- {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
+ {"General Purpose Registers", "gpr",
+ llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
};
}
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
-RegisterContextWindows_x64::RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows(thread, concrete_frame_idx)
-{
-}
+RegisterContextWindows_x64::RegisterContextWindows_x64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextWindows(thread, concrete_frame_idx) {}
-RegisterContextWindows_x64::~RegisterContextWindows_x64()
-{
-}
+RegisterContextWindows_x64::~RegisterContextWindows_x64() {}
-size_t
-RegisterContextWindows_x64::GetRegisterCount()
-{
- return llvm::array_lengthof(g_register_infos);
+size_t RegisterContextWindows_x64::GetRegisterCount() {
+ return llvm::array_lengthof(g_register_infos);
}
const RegisterInfo *
-RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_register_infos)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_register_infos)
+ return &g_register_infos[reg];
+ return NULL;
}
-size_t
-RegisterContextWindows_x64::GetRegisterSetCount()
-{
- return llvm::array_lengthof(g_register_sets);
+size_t RegisterContextWindows_x64::GetRegisterSetCount() {
+ return llvm::array_lengthof(g_register_sets);
}
-const RegisterSet *
-RegisterContextWindows_x64::GetRegisterSet(size_t reg_set)
-{
- return &g_register_sets[reg_set];
+const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
+ return &g_register_sets[reg_set];
}
-bool
-RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!CacheAllRegisterValues())
- return false;
+bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ if (!CacheAllRegisterValues())
+ return false;
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- reg_value.SetUInt64(m_context.Rax);
- break;
- case lldb_rbx_x86_64:
- reg_value.SetUInt64(m_context.Rbx);
- break;
- case lldb_rcx_x86_64:
- reg_value.SetUInt64(m_context.Rcx);
- break;
- case lldb_rdx_x86_64:
- reg_value.SetUInt64(m_context.Rdx);
- break;
- case lldb_rdi_x86_64:
- reg_value.SetUInt64(m_context.Rdi);
- break;
- case lldb_rsi_x86_64:
- reg_value.SetUInt64(m_context.Rsi);
- break;
- case lldb_r8_x86_64:
- reg_value.SetUInt64(m_context.R8);
- break;
- case lldb_r9_x86_64:
- reg_value.SetUInt64(m_context.R9);
- break;
- case lldb_r10_x86_64:
- reg_value.SetUInt64(m_context.R10);
- break;
- case lldb_r11_x86_64:
- reg_value.SetUInt64(m_context.R11);
- break;
- case lldb_r12_x86_64:
- reg_value.SetUInt64(m_context.R12);
- break;
- case lldb_r13_x86_64:
- reg_value.SetUInt64(m_context.R13);
- break;
- case lldb_r14_x86_64:
- reg_value.SetUInt64(m_context.R14);
- break;
- case lldb_r15_x86_64:
- reg_value.SetUInt64(m_context.R15);
- break;
- case lldb_rbp_x86_64:
- reg_value.SetUInt64(m_context.Rbp);
- break;
- case lldb_rsp_x86_64:
- reg_value.SetUInt64(m_context.Rsp);
- break;
- case lldb_rip_x86_64:
- reg_value.SetUInt64(m_context.Rip);
- break;
- case lldb_rflags_x86_64:
- reg_value.SetUInt64(m_context.EFlags);
- break;
- }
- return true;
+ switch (reg_info->kinds[eRegisterKindLLDB]) {
+ case lldb_rax_x86_64:
+ reg_value.SetUInt64(m_context.Rax);
+ break;
+ case lldb_rbx_x86_64:
+ reg_value.SetUInt64(m_context.Rbx);
+ break;
+ case lldb_rcx_x86_64:
+ reg_value.SetUInt64(m_context.Rcx);
+ break;
+ case lldb_rdx_x86_64:
+ reg_value.SetUInt64(m_context.Rdx);
+ break;
+ case lldb_rdi_x86_64:
+ reg_value.SetUInt64(m_context.Rdi);
+ break;
+ case lldb_rsi_x86_64:
+ reg_value.SetUInt64(m_context.Rsi);
+ break;
+ case lldb_r8_x86_64:
+ reg_value.SetUInt64(m_context.R8);
+ break;
+ case lldb_r9_x86_64:
+ reg_value.SetUInt64(m_context.R9);
+ break;
+ case lldb_r10_x86_64:
+ reg_value.SetUInt64(m_context.R10);
+ break;
+ case lldb_r11_x86_64:
+ reg_value.SetUInt64(m_context.R11);
+ break;
+ case lldb_r12_x86_64:
+ reg_value.SetUInt64(m_context.R12);
+ break;
+ case lldb_r13_x86_64:
+ reg_value.SetUInt64(m_context.R13);
+ break;
+ case lldb_r14_x86_64:
+ reg_value.SetUInt64(m_context.R14);
+ break;
+ case lldb_r15_x86_64:
+ reg_value.SetUInt64(m_context.R15);
+ break;
+ case lldb_rbp_x86_64:
+ reg_value.SetUInt64(m_context.Rbp);
+ break;
+ case lldb_rsp_x86_64:
+ reg_value.SetUInt64(m_context.Rsp);
+ break;
+ case lldb_rip_x86_64:
+ reg_value.SetUInt64(m_context.Rip);
+ break;
+ case lldb_rflags_x86_64:
+ reg_value.SetUInt64(m_context.EFlags);
+ break;
+ }
+ return true;
}
-bool
-RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
+bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ // Since we cannot only write a single register value to the inferior, we need
+ // to make sure
+ // our cached copy of the register values are fresh. Otherwise when writing
+ // EAX, for example,
+ // we may also overwrite some other register with a stale value.
+ if (!CacheAllRegisterValues())
+ return false;
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- m_context.Rax = reg_value.GetAsUInt64();
- break;
- case lldb_rbx_x86_64:
- m_context.Rbx = reg_value.GetAsUInt64();
- break;
- case lldb_rcx_x86_64:
- m_context.Rcx = reg_value.GetAsUInt64();
- break;
- case lldb_rdx_x86_64:
- m_context.Rdx = reg_value.GetAsUInt64();
- break;
- case lldb_rdi_x86_64:
- m_context.Rdi = reg_value.GetAsUInt64();
- break;
- case lldb_rsi_x86_64:
- m_context.Rsi = reg_value.GetAsUInt64();
- break;
- case lldb_r8_x86_64:
- m_context.R8 = reg_value.GetAsUInt64();
- break;
- case lldb_r9_x86_64:
- m_context.R9 = reg_value.GetAsUInt64();
- break;
- case lldb_r10_x86_64:
- m_context.R10 = reg_value.GetAsUInt64();
- break;
- case lldb_r11_x86_64:
- m_context.R11 = reg_value.GetAsUInt64();
- break;
- case lldb_r12_x86_64:
- m_context.R12 = reg_value.GetAsUInt64();
- break;
- case lldb_r13_x86_64:
- m_context.R13 = reg_value.GetAsUInt64();
- break;
- case lldb_r14_x86_64:
- m_context.R14 = reg_value.GetAsUInt64();
- break;
- case lldb_r15_x86_64:
- m_context.R15 = reg_value.GetAsUInt64();
- break;
- case lldb_rbp_x86_64:
- m_context.Rbp = reg_value.GetAsUInt64();
- break;
- case lldb_rsp_x86_64:
- m_context.Rsp = reg_value.GetAsUInt64();
- break;
- case lldb_rip_x86_64:
- m_context.Rip = reg_value.GetAsUInt64();
- break;
- case lldb_rflags_x86_64:
- m_context.EFlags = reg_value.GetAsUInt64();
- break;
- }
+ switch (reg_info->kinds[eRegisterKindLLDB]) {
+ case lldb_rax_x86_64:
+ m_context.Rax = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbx_x86_64:
+ m_context.Rbx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rcx_x86_64:
+ m_context.Rcx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdx_x86_64:
+ m_context.Rdx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdi_x86_64:
+ m_context.Rdi = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsi_x86_64:
+ m_context.Rsi = reg_value.GetAsUInt64();
+ break;
+ case lldb_r8_x86_64:
+ m_context.R8 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r9_x86_64:
+ m_context.R9 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r10_x86_64:
+ m_context.R10 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r11_x86_64:
+ m_context.R11 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r12_x86_64:
+ m_context.R12 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r13_x86_64:
+ m_context.R13 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r14_x86_64:
+ m_context.R14 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r15_x86_64:
+ m_context.R15 = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbp_x86_64:
+ m_context.Rbp = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsp_x86_64:
+ m_context.Rsp = reg_value.GetAsUInt64();
+ break;
+ case lldb_rip_x86_64:
+ m_context.Rip = reg_value.GetAsUInt64();
+ break;
+ case lldb_rflags_x86_64:
+ m_context.EFlags = reg_value.GetAsUInt64();
+ break;
+ }
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
+ // Physically update the registers in the target process.
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ return ::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
index e69179d99c6c..62cedc8fbab0 100644
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
+++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
@@ -10,38 +10,38 @@
#ifndef liblldb_RegisterContextWindows_x64_H_
#define liblldb_RegisterContextWindows_x64_H_
-#include "lldb/lldb-forward.h"
#include "RegisterContextWindows.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindows_x64 : public RegisterContextWindows
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindows_x64 : public RegisterContextWindows {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindows_x64();
+ virtual ~RegisterContextWindows_x64();
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- size_t GetRegisterCount() override;
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ size_t GetRegisterCount() override;
- const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const RegisterSet *GetRegisterSet(size_t reg_set) override;
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
};
}
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
index 11733eee7cb4..2938f77f3c2a 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
@@ -7,16 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
-#include "lldb-x86-register-enums.h"
#include "ProcessWindowsLog.h"
-#include "RegisterContext_x86.h"
#include "RegisterContextWindows_x86.h"
+#include "RegisterContext_x86.h"
+#include "TargetThreadWindows.h"
+#include "lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
@@ -26,150 +27,272 @@ using namespace lldb_private;
#define DEFINE_GPR(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatHexUppercase
#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatBinary
-namespace
-{
+namespace {
-// This enum defines the layout of the global RegisterInfo array. This is necessary because
-// lldb register sets are defined in terms of indices into the register array. As such, the
-// order of RegisterInfos defined in global registers array must match the order defined here.
-// When defining the register set layouts, these values can appear in an arbitrary order, and that
+// This enum defines the layout of the global RegisterInfo array. This is
+// necessary because
+// lldb register sets are defined in terms of indices into the register array.
+// As such, the
+// order of RegisterInfos defined in global registers array must match the order
+// defined here.
+// When defining the register set layouts, these values can appear in an
+// arbitrary order, and that
// determines the order that register values are displayed in a dump.
-enum RegisterIndex
-{
- eRegisterIndexEax,
- eRegisterIndexEbx,
- eRegisterIndexEcx,
- eRegisterIndexEdx,
- eRegisterIndexEdi,
- eRegisterIndexEsi,
- eRegisterIndexEbp,
- eRegisterIndexEsp,
- eRegisterIndexEip,
- eRegisterIndexEflags
+enum RegisterIndex {
+ eRegisterIndexEax,
+ eRegisterIndexEbx,
+ eRegisterIndexEcx,
+ eRegisterIndexEdx,
+ eRegisterIndexEdi,
+ eRegisterIndexEsi,
+ eRegisterIndexEbp,
+ eRegisterIndexEsp,
+ eRegisterIndexEip,
+ eRegisterIndexEflags
};
// Array of all register information supported by Windows x86
-RegisterInfo g_register_infos[] =
-{
-// Macro auto defines most stuff eh_frame DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS
-// ============================== ======================= =================== ========================= =================== ================= ========== ===============
- { DEFINE_GPR(eax, nullptr), { ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_eax_i386 }, nullptr, nullptr},
- { DEFINE_GPR(ebx, nullptr), { ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ebx_i386 }, nullptr, nullptr},
- { DEFINE_GPR(ecx, nullptr), { ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ecx_i386 }, nullptr, nullptr},
- { DEFINE_GPR(edx, nullptr), { ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edx_i386 }, nullptr, nullptr},
- { DEFINE_GPR(edi, nullptr), { ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edi_i386 }, nullptr, nullptr},
- { DEFINE_GPR(esi, nullptr), { ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_esi_i386 }, nullptr, nullptr},
- { DEFINE_GPR(ebp, "fp"), { ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_ebp_i386 }, nullptr, nullptr},
- { DEFINE_GPR(esp, "sp"), { ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_esp_i386 }, nullptr, nullptr},
- { DEFINE_GPR(eip, "pc"), { ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_eip_i386 }, nullptr, nullptr},
- { DEFINE_GPR_BIN(eflags, "flags"), { ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, lldb_eflags_i386}, nullptr, nullptr},
+RegisterInfo g_register_infos[] = {
+ // Macro auto defines most stuff eh_frame DWARF
+ // GENERIC GDB LLDB
+ // VALUE REGS INVALIDATE REGS
+ // ============================== =======================
+ // =================== ========================= ===================
+ // ================= ========== ===============
+ {DEFINE_GPR(eax, nullptr),
+ {ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_eax_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(ebx, nullptr),
+ {ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_ebx_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(ecx, nullptr),
+ {ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_ecx_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(edx, nullptr),
+ {ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_edx_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(edi, nullptr),
+ {ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_edi_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(esi, nullptr),
+ {ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_esi_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(ebp, "fp"),
+ {ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, lldb_ebp_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(esp, "sp"),
+ {ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, lldb_esp_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(eip, "pc"),
+ {ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, lldb_eip_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR_BIN(eflags, "flags"),
+ {ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, lldb_eflags_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-// Array of lldb register numbers used to define the set of all General Purpose Registers
-uint32_t g_gpr_reg_indices[] =
-{
- eRegisterIndexEax,
- eRegisterIndexEbx,
- eRegisterIndexEcx,
- eRegisterIndexEdx,
- eRegisterIndexEdi,
- eRegisterIndexEsi,
- eRegisterIndexEbp,
- eRegisterIndexEsp,
- eRegisterIndexEip,
- eRegisterIndexEflags
-};
+// Array of lldb register numbers used to define the set of all General Purpose
+// Registers
+uint32_t g_gpr_reg_indices[] = {eRegisterIndexEax, eRegisterIndexEbx,
+ eRegisterIndexEcx, eRegisterIndexEdx,
+ eRegisterIndexEdi, eRegisterIndexEsi,
+ eRegisterIndexEbp, eRegisterIndexEsp,
+ eRegisterIndexEip, eRegisterIndexEflags};
RegisterSet g_register_sets[] = {
- {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
+ {"General Purpose Registers", "gpr",
+ llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
};
}
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
-RegisterContextWindows_x86::RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows(thread, concrete_frame_idx)
-{
-}
+RegisterContextWindows_x86::RegisterContextWindows_x86(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextWindows(thread, concrete_frame_idx) {}
-RegisterContextWindows_x86::~RegisterContextWindows_x86()
-{
-}
+RegisterContextWindows_x86::~RegisterContextWindows_x86() {}
-size_t
-RegisterContextWindows_x86::GetRegisterCount()
-{
- return llvm::array_lengthof(g_register_infos);
+size_t RegisterContextWindows_x86::GetRegisterCount() {
+ return llvm::array_lengthof(g_register_infos);
}
const RegisterInfo *
-RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_register_infos)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_register_infos)
+ return &g_register_infos[reg];
+ return NULL;
+}
+
+size_t RegisterContextWindows_x86::GetRegisterSetCount() {
+ return llvm::array_lengthof(g_register_sets);
}
-size_t
-RegisterContextWindows_x86::GetRegisterSetCount()
-{
- return llvm::array_lengthof(g_register_sets);
+const RegisterSet *RegisterContextWindows_x86::GetRegisterSet(size_t reg_set) {
+ return &g_register_sets[reg_set];
}
-const RegisterSet *
-RegisterContextWindows_x86::GetRegisterSet(size_t reg_set)
-{
- return &g_register_sets[reg_set];
+bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ if (!CacheAllRegisterValues())
+ return false;
+
+ uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ switch (reg) {
+ case lldb_eax_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EAX", m_context.Eax, reg_value);
+ case lldb_ebx_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EBX", m_context.Ebx, reg_value);
+ case lldb_ecx_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "ECX", m_context.Ecx, reg_value);
+ case lldb_edx_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EDX", m_context.Edx, reg_value);
+ case lldb_edi_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EDI", m_context.Edi, reg_value);
+ case lldb_esi_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "ESI", m_context.Esi, reg_value);
+ case lldb_ebp_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EBP", m_context.Ebp, reg_value);
+ case lldb_esp_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "ESP", m_context.Esp, reg_value);
+ case lldb_eip_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EIP", m_context.Eip, reg_value);
+ case lldb_eflags_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EFLAGS", m_context.EFlags,
+ reg_value);
+ default:
+ WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg);
+ break;
+ }
+ return false;
}
-bool
-RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!CacheAllRegisterValues())
- return false;
-
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg)
- {
- case lldb_eax_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EAX", m_context.Eax, reg_value);
- case lldb_ebx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EBX", m_context.Ebx, reg_value);
- case lldb_ecx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "ECX", m_context.Ecx, reg_value);
- case lldb_edx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EDX", m_context.Edx, reg_value);
- case lldb_edi_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EDI", m_context.Edi, reg_value);
- case lldb_esi_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "ESI", m_context.Esi, reg_value);
- case lldb_ebp_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EBP", m_context.Ebp, reg_value);
- case lldb_esp_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "ESP", m_context.Esp, reg_value);
- case lldb_eip_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EIP", m_context.Eip, reg_value);
- case lldb_eflags_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EFLAGS", m_context.EFlags, reg_value);
- default:
- WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg);
- break;
- }
+bool RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ // Since we cannot only write a single register value to the inferior, we need
+ // to make sure
+ // our cached copy of the register values are fresh. Otherwise when writing
+ // EAX, for example,
+ // we may also overwrite some other register with a stale value.
+ if (!CacheAllRegisterValues())
return false;
+
+ uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ switch (reg) {
+ case lldb_eax_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX",
+ reg_value.GetAsUInt32());
+ m_context.Eax = reg_value.GetAsUInt32();
+ break;
+ case lldb_ebx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX",
+ reg_value.GetAsUInt32());
+ m_context.Ebx = reg_value.GetAsUInt32();
+ break;
+ case lldb_ecx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX",
+ reg_value.GetAsUInt32());
+ m_context.Ecx = reg_value.GetAsUInt32();
+ break;
+ case lldb_edx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX",
+ reg_value.GetAsUInt32());
+ m_context.Edx = reg_value.GetAsUInt32();
+ break;
+ case lldb_edi_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI",
+ reg_value.GetAsUInt32());
+ m_context.Edi = reg_value.GetAsUInt32();
+ break;
+ case lldb_esi_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI",
+ reg_value.GetAsUInt32());
+ m_context.Esi = reg_value.GetAsUInt32();
+ break;
+ case lldb_ebp_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP",
+ reg_value.GetAsUInt32());
+ m_context.Ebp = reg_value.GetAsUInt32();
+ break;
+ case lldb_esp_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP",
+ reg_value.GetAsUInt32());
+ m_context.Esp = reg_value.GetAsUInt32();
+ break;
+ case lldb_eip_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP",
+ reg_value.GetAsUInt32());
+ m_context.Eip = reg_value.GetAsUInt32();
+ break;
+ case lldb_eflags_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS",
+ reg_value.GetAsUInt32());
+ m_context.EFlags = reg_value.GetAsUInt32();
+ break;
+ default:
+ WINWARN_IFALL(WINDOWS_LOG_REGISTERS,
+ "Write value 0x%x to unknown register %u",
+ reg_value.GetAsUInt32(), reg);
+ }
+
+ // Physically update the registers in the target process.
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ return ::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
-bool
-RegisterContextWindows_x86::ReadRegisterHelper(DWORD flags_required, const char *reg_name, DWORD value,
- RegisterValue &reg_value) const
-{
- if ((m_context.ContextFlags & flags_required) != flags_required)
- {
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Thread context doesn't have %s", reg_name);
- return false;
- }
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from %s", value, reg_name);
- reg_value.SetUInt32(value);
- return true;
+bool RegisterContextWindows_x86::ReadRegisterHelper(
+ DWORD flags_required, const char *reg_name, DWORD value,
+ RegisterValue &reg_value) const {
+ if ((m_context.ContextFlags & flags_required) != flags_required) {
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Thread context doesn't have %s",
+ reg_name);
+ return false;
+ }
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%lx from %s", value,
+ reg_name);
+ reg_value.SetUInt32(value);
+ return true;
}
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
index 6c29d54dcae2..aae645fdb5a3 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
@@ -10,42 +10,43 @@
#ifndef liblldb_RegisterContextWindows_x86_H_
#define liblldb_RegisterContextWindows_x86_H_
-#include "lldb/lldb-forward.h"
#include "RegisterContextWindows.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindows_x86 : public RegisterContextWindows
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindows_x86 : public RegisterContextWindows {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindows_x86();
+ virtual ~RegisterContextWindows_x86();
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- size_t GetRegisterCount() override;
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ size_t GetRegisterCount() override;
- const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const RegisterSet *GetRegisterSet(size_t reg_set) override;
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
private:
- bool
- ReadRegisterHelper(DWORD flags_required, const char *reg_name, DWORD value, RegisterValue &reg_value) const;
+ bool ReadRegisterHelper(DWORD flags_required, const char *reg_name,
+ DWORD value, RegisterValue &reg_value) const;
};
-
}
#endif // #ifndef liblldb_RegisterContextWindows_x86_H_
diff --git a/source/Plugins/Process/Windows/Live/CMakeLists.txt b/source/Plugins/Process/Windows/Live/CMakeLists.txt
deleted file mode 100644
index bdb680ad0bee..000000000000
--- a/source/Plugins/Process/Windows/Live/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-include_directories(.)
-include_directories(../../Utility)
-include_directories(../Common)
-
-set(PROC_WINDOWS_SOURCES
- DebuggerThread.cpp
- LocalDebugDelegate.cpp
- ProcessWindowsLive.cpp
- TargetThreadWindowsLive.cpp
- )
-
-if (CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES}
- x86/RegisterContextWindowsLive_x86.cpp
- )
-elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES}
- x64/RegisterContextWindowsLive_x64.cpp
- )
-endif()
-
-add_lldb_library(lldbPluginProcessWindows
- ${PROC_WINDOWS_SOURCES}
- )
diff --git a/source/Plugins/Process/Windows/Live/DebuggerThread.cpp b/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
deleted file mode 100644
index 2823474cbd5e..000000000000
--- a/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
+++ /dev/null
@@ -1,549 +0,0 @@
-//===-- DebuggerThread.DebuggerThread --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DebuggerThread.h"
-#include "ExceptionRecord.h"
-#include "IDebugDelegate.h"
-
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Predicate.h"
-#include "lldb/Host/ThisThread.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/windows/HostProcessWindows.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Target/Process.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace
-{
-struct DebugLaunchContext
-{
- DebugLaunchContext(DebuggerThread *thread, const ProcessLaunchInfo &launch_info)
- : m_thread(thread)
- , m_launch_info(launch_info)
- {
- }
- DebuggerThread *m_thread;
- ProcessLaunchInfo m_launch_info;
-};
-
-struct DebugAttachContext
-{
- DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid, const ProcessAttachInfo &attach_info)
- : m_thread(thread)
- , m_pid(pid)
- , m_attach_info(attach_info)
- {
- }
- DebuggerThread *m_thread;
- lldb::pid_t m_pid;
- ProcessAttachInfo m_attach_info;
-};
-}
-
-DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
- : m_debug_delegate(debug_delegate)
- , m_image_file(nullptr)
- , m_debugging_ended_event(nullptr)
- , m_is_shutting_down(false)
- , m_pid_to_detach(0)
- , m_detached(false)
-{
- m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
-}
-
-DebuggerThread::~DebuggerThread()
-{
- ::CloseHandle(m_debugging_ended_event);
-}
-
-Error
-DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
-{
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DebuggerThread::DebugLaunch launching '%s'", launch_info.GetExecutableFile().GetPath().c_str());
-
- Error error;
- DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
- DebuggerThreadLaunchRoutine, context, &error));
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DebugLaunch couldn't launch debugger thread. %s", error.AsCString());
- }
-
- return error;
-}
-
-Error
-DebuggerThread::DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread::DebugAttach attaching to '%u'", (DWORD)pid);
-
- Error error;
- DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
- DebuggerThreadAttachRoutine, context, &error));
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DebugAttach couldn't attach to process '%u'. %s", (DWORD)pid,
- error.AsCString());
- }
-
- return error;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadLaunchRoutine(void *data)
-{
- DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
- lldb::thread_result_t result = context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
- delete context;
- return result;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadAttachRoutine(void *data)
-{
- DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
- lldb::thread_result_t result =
- context->m_thread->DebuggerThreadAttachRoutine(context->m_pid, context->m_attach_info);
- delete context;
- return result;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info)
-{
- // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
- // thread routine has exited.
- std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to launch '%s' on background thread.",
- launch_info.GetExecutableFile().GetPath().c_str());
-
- Error error;
- ProcessLauncherWindows launcher;
- HostProcess process(launcher.LaunchProcess(launch_info, error));
- // If we couldn't create the process, notify waiters immediately. Otherwise enter the debug
- // loop and wait until we get the create process debug notification. Note that if the process
- // was created successfully, we can throw away the process handle we got from CreateProcess
- // because Windows will give us another (potentially more useful?) handle when it sends us the
- // CREATE_PROCESS_DEBUG_EVENT.
- if (error.Success())
- DebugLoop();
- else
- m_debug_delegate->OnDebuggerError(error, 0);
-
- return 0;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
- // thread routine has exited.
- std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to attach to process '%u' on background thread.",
- (DWORD)pid);
-
- if (!DebugActiveProcess((DWORD)pid))
- {
- Error error(::GetLastError(), eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, 0);
- return 0;
- }
-
- // The attach was successful, enter the debug loop. From here on out, this is no different than
- // a create process operation, so all the same comments in DebugLaunch should apply from this
- // point out.
- DebugLoop();
-
- return 0;
-}
-
-Error
-DebuggerThread::StopDebugging(bool terminate)
-{
- Error error;
-
- lldb::pid_t pid = m_process.GetProcessId();
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging('%s') called (inferior=%I64u).",
- (terminate ? "true" : "false"), pid);
-
- // Set m_is_shutting_down to true if it was false. Return if it was already true.
- bool expected = false;
- if (!m_is_shutting_down.compare_exchange_strong(expected, true))
- return error;
-
- // Make a copy of the process, since the termination sequence will reset
- // DebuggerThread's internal copy and it needs to remain open for the Wait operation.
- HostProcess process_copy = m_process;
- lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
-
- if (terminate)
- {
- // Initiate the termination before continuing the exception, so that the next debug
- // event we get is the exit process event, and not some other event.
- BOOL terminate_suceeded = TerminateProcess(handle, 0);
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging called TerminateProcess(0x%p, 0) (inferior=%I64u), success='%s'",
- handle, pid, (terminate_suceeded ? "true" : "false"));
- }
-
- // If we're stuck waiting for an exception to continue (e.g. the user is at a breakpoint
- // messing around in the debugger), continue it now. But only AFTER calling TerminateProcess
- // to make sure that the very next call to WaitForDebugEvent is an exit process event.
- if (m_active_exception.get())
- {
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
- "StopDebugging masking active exception");
-
- ContinueAsyncException(ExceptionResult::MaskException);
- }
-
- if (!terminate)
- {
- // Indicate that we want to detach.
- m_pid_to_detach = GetProcess().GetProcessId();
-
- // Force a fresh break so that the detach can happen from the debugger thread.
- if (!::DebugBreakProcess(GetProcess().GetNativeProcess().GetSystemHandle()))
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- }
- }
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging waiting for detach from process %u to complete.", pid);
-
- DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
- if (wait_result != WAIT_OBJECT_0)
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging WaitForSingleObject(0x%p, 5000) returned %u",
- m_debugging_ended_event, wait_result);
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging detach from process %u completed successfully.", pid);
- }
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging encountered an error while trying to stop process %u. %s",
- pid, error.AsCString());
- }
- return error;
-}
-
-void
-DebuggerThread::ContinueAsyncException(ExceptionResult result)
-{
- if (!m_active_exception.get())
- return;
-
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
- "ContinueAsyncException called for inferior process %I64u, broadcasting.",
- m_process.GetProcessId());
-
- m_active_exception.reset();
- m_exception_pred.SetValue(result, eBroadcastAlways);
-}
-
-void
-DebuggerThread::FreeProcessHandles()
-{
- m_process = HostProcess();
- m_main_thread = HostThread();
- if (m_image_file)
- {
- ::CloseHandle(m_image_file);
- m_image_file = nullptr;
- }
-}
-
-void
-DebuggerThread::DebugLoop()
-{
- DEBUG_EVENT dbe = {0};
- bool should_debug = true;
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
- while (should_debug)
- {
- WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
- BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
- if (wait_result)
- {
- DWORD continue_status = DBG_CONTINUE;
- switch (dbe.dwDebugEventCode)
- {
- case EXCEPTION_DEBUG_EVENT:
- {
- ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
-
- if (status == ExceptionResult::MaskException)
- continue_status = DBG_CONTINUE;
- else if (status == ExceptionResult::SendToApplication)
- continue_status = DBG_EXCEPTION_NOT_HANDLED;
-
- break;
- }
- case CREATE_THREAD_DEBUG_EVENT:
- continue_status = HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
- break;
- case CREATE_PROCESS_DEBUG_EVENT:
- continue_status = HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
- break;
- case EXIT_THREAD_DEBUG_EVENT:
- continue_status = HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
- break;
- case EXIT_PROCESS_DEBUG_EVENT:
- continue_status = HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
- should_debug = false;
- break;
- case LOAD_DLL_DEBUG_EVENT:
- continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
- break;
- case UNLOAD_DLL_DEBUG_EVENT:
- continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
- break;
- case OUTPUT_DEBUG_STRING_EVENT:
- continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
- break;
- case RIP_EVENT:
- continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
- if (dbe.u.RipInfo.dwType == SLE_ERROR)
- should_debug = false;
- break;
- }
-
- WINLOGD_IFALL(WINDOWS_LOG_EVENT, "DebugLoop calling ContinueDebugEvent(%u, %u, %u) on thread %u.",
- dbe.dwProcessId, dbe.dwThreadId, continue_status, ::GetCurrentThreadId());
-
- ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
-
- if (m_detached)
- {
- should_debug = false;
- }
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "DebugLoop returned FALSE from WaitForDebugEvent. Error = %u",
- ::GetCurrentThreadId(), ::GetLastError());
-
- should_debug = false;
- }
- }
- FreeProcessHandles();
-
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
- SetEvent(m_debugging_ended_event);
-}
-
-ExceptionResult
-DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
-{
- if (m_is_shutting_down)
- {
- // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic exception that
- // we use simply to wake up the DebuggerThread so that we can close out the debug loop.
- if (m_pid_to_detach != 0 && info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
- {
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS,
- "Breakpoint exception is cue to detach from process 0x%x",
- m_pid_to_detach.load());
- ::DebugActiveProcessStop(m_pid_to_detach);
- m_detached = true;
- }
-
- // Don't perform any blocking operations while we're shutting down. That will
- // cause TerminateProcess -> WaitForSingleObject to time out.
- return ExceptionResult::SendToApplication;
- }
-
- bool first_chance = (info.dwFirstChance != 0);
-
- m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
- "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
- first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
-
- ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
- *m_active_exception);
- m_exception_pred.SetValue(result, eBroadcastNever);
-
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
- "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred != BreakInDebugger");
-
- m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger, result);
-
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
- "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
- m_exception_pred.GetValue());
-
- return result;
-}
-
-DWORD
-DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
- thread_id, m_process.GetProcessId());
- HostThread thread(info.hThread);
- thread.GetNativeThread().SetOwnsHandle(false);
- m_debug_delegate->OnCreateThread(thread);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
-{
- uint32_t process_id = ::GetProcessId(info.hProcess);
-
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS, "HandleCreateProcessEvent process %u spawned", process_id);
-
- std::string thread_name;
- llvm::raw_string_ostream name_stream(thread_name);
- name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
- name_stream.flush();
- ThisThread::SetName(thread_name.c_str());
-
- // info.hProcess and info.hThread are closed automatically by Windows when
- // EXIT_PROCESS_DEBUG_EVENT is received.
- m_process = HostProcess(info.hProcess);
- ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
- m_main_thread = HostThread(info.hThread);
- m_main_thread.GetNativeThread().SetOwnsHandle(false);
- m_image_file = info.hFile;
-
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
- m_debug_delegate->OnDebuggerConnected(load_addr);
-
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
- thread_id, info.dwExitCode, m_process.GetProcessId());
- m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleExitProcessEvent process %I64u exited with code %u",
- m_process.GetProcessId(), info.dwExitCode);
-
- m_debug_delegate->OnExitProcess(info.dwExitCode);
-
- FreeProcessHandles();
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
-{
- if (info.hFile == nullptr)
- {
- // Not sure what this is, so just ignore it.
- WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has a NULL file handle, returning...",
- m_process.GetProcessId());
- return DBG_CONTINUE;
- }
-
- std::vector<wchar_t> buffer(1);
- DWORD required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
- if (required_size > 0)
- {
- buffer.resize(required_size + 1);
- required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size, VOLUME_NAME_DOS);
- std::string path_str_utf8;
- llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
- llvm::StringRef path_str = path_str_utf8;
- const char *path = path_str.data();
- if (path_str.startswith("\\\\?\\"))
- path += 4;
-
- FileSpec file_spec(path, false);
- ModuleSpec module_spec(file_spec);
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
-
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL '%s' loaded at address 0x%p...",
- m_process.GetProcessId(), path, info.lpBaseOfDll);
-
- m_debug_delegate->OnLoadDll(module_spec, load_addr);
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "Inferior %I64u - HandleLoadDllEvent Error %u occurred calling GetFinalPathNameByHandle",
- m_process.GetProcessId(), ::GetLastError());
- }
- // Windows does not automatically close info.hFile, so we need to do it.
- ::CloseHandle(info.hFile);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFALL(WINDOWS_LOG_EVENT,
- "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
- m_process.GetProcessId(), info.lpBaseOfDll);
-
- m_debug_delegate->OnUnloadDll(reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
-{
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
-{
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "HandleRipEvent encountered error %u (type=%u) in process %I64u thread %u",
- info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
-
- Error error(info.dwError, eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, info.dwType);
-
- return DBG_CONTINUE;
-}
diff --git a/source/Plugins/Process/Windows/Live/DebuggerThread.h b/source/Plugins/Process/Windows/Live/DebuggerThread.h
deleted file mode 100644
index 6a2619413950..000000000000
--- a/source/Plugins/Process/Windows/Live/DebuggerThread.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//===-- DebuggerThread.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_Plugins_Process_Windows_DebuggerThread_H_
-#define liblldb_Plugins_Process_Windows_DebuggerThread_H_
-
-#include <atomic>
-#include <memory>
-
-#include "ForwardDecl.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Predicate.h"
-#include "lldb/Host/windows/windows.h"
-
-namespace lldb_private
-{
-
-//----------------------------------------------------------------------
-// DebuggerThread
-//
-// Debugs a single process, notifying listeners as appropriate when interesting
-// things occur.
-//----------------------------------------------------------------------
-class DebuggerThread : public std::enable_shared_from_this<DebuggerThread>
-{
- public:
- DebuggerThread(DebugDelegateSP debug_delegate);
- virtual ~DebuggerThread();
-
- Error DebugLaunch(const ProcessLaunchInfo &launch_info);
- Error DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
-
- HostProcess
- GetProcess() const
- {
- return m_process;
- }
- HostThread
- GetMainThread() const
- {
- return m_main_thread;
- }
- std::weak_ptr<ExceptionRecord>
- GetActiveException()
- {
- return m_active_exception;
- }
-
- Error StopDebugging(bool terminate);
-
- void ContinueAsyncException(ExceptionResult result);
-
- private:
- void FreeProcessHandles();
- void DebugLoop();
- ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
- DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
-
- DebugDelegateSP m_debug_delegate;
-
- HostProcess m_process; // The process being debugged.
- HostThread m_main_thread; // The main thread of the inferior.
- HANDLE m_image_file; // The image file of the process being debugged.
-
- ExceptionRecordSP m_active_exception; // The current exception waiting to be handled
-
- Predicate<ExceptionResult> m_exception_pred; // A predicate which gets signalled when an exception
- // is finished processing and the debug loop can be
- // continued.
-
- HANDLE m_debugging_ended_event; // An event which gets signalled by the debugger thread when it
- // exits the debugger loop and is detached from the inferior.
-
- std::atomic<DWORD> m_pid_to_detach; // Signals the loop to detach from the process (specified by pid).
- std::atomic<bool> m_is_shutting_down; // Signals the debug loop to stop processing certain types of
- // events that block shutdown.
- bool m_detached; // Indicates we've detached from the inferior process and the debug loop can exit.
-
- static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
- lldb::thread_result_t DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
- static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
- lldb::thread_result_t DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &launch_info);
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp b/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp
deleted file mode 100644
index a0ac9725c756..000000000000
--- a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LocalDebugDelegate.h"
-#include "ProcessWindowsLive.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-LocalDebugDelegate::LocalDebugDelegate(ProcessWP process)
- : m_process(process)
-{
-}
-
-void
-LocalDebugDelegate::OnExitProcess(uint32_t exit_code)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnExitProcess(exit_code);
-}
-
-void
-LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebuggerConnected(image_base);
-}
-
-ExceptionResult
-LocalDebugDelegate::OnDebugException(bool first_chance, const ExceptionRecord &record)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- return process->OnDebugException(first_chance, record);
- else
- return ExceptionResult::MaskException;
-}
-
-void
-LocalDebugDelegate::OnCreateThread(const HostThread &thread)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnCreateThread(thread);
-}
-
-void
-LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnExitThread(thread_id, exit_code);
-}
-
-void
-LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnLoadDll(module_spec, module_addr);
-}
-
-void
-LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnUnloadDll(module_addr);
-}
-
-void
-LocalDebugDelegate::OnDebugString(const std::string &string)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebugString(string);
-}
-
-void
-LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebuggerError(error, type);
-}
-
-ProcessWindowsLiveSP
-LocalDebugDelegate::GetProcessPointer()
-{
- ProcessSP process = m_process.lock();
- return std::static_pointer_cast<ProcessWindowsLive>(process);
-}
diff --git a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
deleted file mode 100644
index 300e0caa4378..000000000000
--- a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
+++ /dev/null
@@ -1,1069 +0,0 @@
-//===-- ProcessWindowsLive.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// Windows includes
-#include "lldb/Host/windows/windows.h"
-#include <psapi.h>
-
-// C++ Includes
-#include <list>
-#include <mutex>
-#include <set>
-#include <vector>
-
-// 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/Host.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/HostNativeProcessBase.h"
-#include "lldb/Host/HostNativeThreadBase.h"
-#include "lldb/Host/MonitoringProcessLauncher.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/FileAction.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "DebuggerThread.h"
-#include "ExceptionRecord.h"
-#include "LocalDebugDelegate.h"
-#include "ProcessWindowsLive.h"
-#include "TargetThreadWindowsLive.h"
-
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#define BOOL_STR(b) ((b) ? "true" : "false")
-
-namespace
-{
-
-std::string
-GetProcessExecutableName(HANDLE process_handle)
-{
- std::vector<wchar_t> file_name;
- DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
- DWORD copied = 0;
- do
- {
- file_name_size *= 2;
- file_name.resize(file_name_size);
- copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), file_name_size);
- } while (copied >= file_name_size);
- file_name.resize(copied);
- std::string result;
- llvm::convertWideToUTF8(file_name.data(), result);
- return result;
-}
-
-std::string
-GetProcessExecutableName(DWORD pid)
-{
- std::string file_name;
- HANDLE process_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
- if (process_handle != NULL)
- {
- file_name = GetProcessExecutableName(process_handle);
- ::CloseHandle(process_handle);
- }
- return file_name;
-}
-
-} // anonymous namespace
-
-namespace lldb_private
-{
-
-// We store a pointer to this class in the ProcessWindows, so that we don't expose Windows
-// OS specific types and implementation details from a public header file.
-class ProcessWindowsData
-{
- public:
- ProcessWindowsData(bool stop_at_entry)
- : m_stop_at_entry(stop_at_entry)
- , m_initial_stop_event(nullptr)
- , m_initial_stop_received(false)
- {
- m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
- }
-
- ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
-
- lldb_private::Error m_launch_error;
- lldb_private::DebuggerThreadSP m_debugger;
- StopInfoSP m_pending_stop_info;
- HANDLE m_initial_stop_event;
- bool m_stop_at_entry;
- bool m_initial_stop_received;
- std::map<lldb::tid_t, HostThread> m_new_threads;
- std::set<lldb::tid_t> m_exited_threads;
-};
-}
-//------------------------------------------------------------------------------
-// Static functions.
-
-ProcessSP
-ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *)
-{
- return ProcessSP(new ProcessWindowsLive(target_sp, listener_sp));
-}
-
-void
-ProcessWindowsLive::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- });
-}
-
-//------------------------------------------------------------------------------
-// Constructors and destructors.
-
-ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
- : lldb_private::ProcessWindows(target_sp, listener_sp)
-{
-}
-
-ProcessWindowsLive::~ProcessWindowsLive()
-{
-}
-
-void
-ProcessWindowsLive::Terminate()
-{
-}
-
-lldb_private::ConstString
-ProcessWindowsLive::GetPluginNameStatic()
-{
- static ConstString g_name("windows");
- return g_name;
-}
-
-const char *
-ProcessWindowsLive::GetPluginDescriptionStatic()
-{
- return "Process plugin for Windows";
-}
-
-Error
-ProcessWindowsLive::EnableBreakpointSite(BreakpointSite *bp_site)
-{
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite called with bp_site 0x%p "
- "(id=%d, addr=0x%x)",
- bp_site->GetID(), bp_site->GetLoadAddress());
-
- Error error = EnableSoftwareBreakpoint(bp_site);
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite failed. %s", error.AsCString());
- }
- return error;
-}
-
-Error
-ProcessWindowsLive::DisableBreakpointSite(BreakpointSite *bp_site)
-{
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite called with bp_site 0x%p "
- "(id=%d, addr=0x%x)",
- bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
-
- Error error = DisableSoftwareBreakpoint(bp_site);
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite failed. %s", error.AsCString());
- }
- return error;
-}
-
-bool
-ProcessWindowsLive::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- // Add all the threads that were previously running and for which we did not detect a thread
- // exited event.
- int new_size = 0;
- int continued_threads = 0;
- int exited_threads = 0;
- int new_threads = 0;
-
- for (ThreadSP old_thread : old_thread_list.Threads())
- {
- lldb::tid_t old_thread_id = old_thread->GetID();
- auto exited_thread_iter = m_session_data->m_exited_threads.find(old_thread_id);
- if (exited_thread_iter == m_session_data->m_exited_threads.end())
- {
- new_thread_list.AddThread(old_thread);
- ++new_size;
- ++continued_threads;
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u was running and is still running.",
- old_thread_id);
- }
- else
- {
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u was running and has exited.",
- old_thread_id);
- ++exited_threads;
- }
- }
-
- // Also add all the threads that are new since the last time we broke into the debugger.
- for (const auto &thread_info : m_session_data->m_new_threads)
- {
- ThreadSP thread(new TargetThreadWindowsLive(*this, thread_info.second));
- thread->SetID(thread_info.first);
- new_thread_list.AddThread(thread);
- ++new_size;
- ++new_threads;
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u is new since last update.", thread_info.first);
- }
-
- WINLOG_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - %d new threads, %d old threads, %d exited threads.",
- new_threads, continued_threads, exited_threads);
-
- m_session_data->m_new_threads.clear();
- m_session_data->m_exited_threads.clear();
-
- return new_size > 0;
-}
-
-Error
-ProcessWindowsLive::DoLaunch(Module *exe_module,
- ProcessLaunchInfo &launch_info)
-{
- // Even though m_session_data is accessed here, it is before a debugger thread has been
- // kicked off. So there's no race conditions, and it shouldn't be necessary to acquire
- // the mutex.
-
- Error result;
- if (!launch_info.GetFlags().Test(eLaunchFlagDebug))
- {
- StreamString stream;
- stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can only be used for debug launches.",
- launch_info.GetExecutableFile().GetPath().c_str());
- std::string message = stream.GetString();
- result.SetErrorString(message.c_str());
-
- WINERR_IFALL(WINDOWS_LOG_PROCESS, message.c_str());
- return result;
- }
-
- bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
- m_session_data.reset(new ProcessWindowsData(stop_at_entry));
-
- SetPrivateState(eStateLaunching);
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- m_session_data->m_debugger.reset(new DebuggerThread(delegate));
- DebuggerThreadSP debugger = m_session_data->m_debugger;
-
- // Kick off the DebugLaunch asynchronously and wait for it to complete.
- result = debugger->DebugLaunch(launch_info);
- if (result.Fail())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
- launch_info.GetExecutableFile().GetPath().c_str(), result.AsCString());
- return result;
- }
-
- HostProcess process;
- Error error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
- launch_info.GetExecutableFile().GetPath().c_str(), error.AsCString());
- return error;
- }
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'",
- launch_info.GetExecutableFile().GetPath().c_str());
-
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the private state
- // should already be set to eStateStopped as a result of hitting the initial breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and the private state
- // should already be eStateRunning.
- launch_info.SetProcessID(process.GetProcessId());
- SetID(process.GetProcessId());
-
- return result;
-}
-
-Error
-ProcessWindowsLive::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- m_session_data.reset(new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
-
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- DebuggerThreadSP debugger(new DebuggerThread(delegate));
-
- m_session_data->m_debugger = debugger;
-
- DWORD process_id = static_cast<DWORD>(pid);
- Error error = debugger->DebugAttach(process_id, attach_info);
- if (error.Fail())
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DoAttachToProcessWithID encountered an error occurred initiating the asynchronous attach. %s",
- error.AsCString());
- return error;
- }
-
- HostProcess process;
- error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail())
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DoAttachToProcessWithID encountered an error waiting for the debugger to connect. %s",
- error.AsCString());
- return error;
- }
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID successfully attached to process with pid=%u",
- process_id);
-
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the private state
- // should already be set to eStateStopped as a result of hitting the initial breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and the private state
- // should already be eStateRunning.
- SetID(process.GetProcessId());
- return error;
-}
-
-Error
-ProcessWindowsLive::WaitForDebuggerConnection(DebuggerThreadSP debugger, HostProcess &process)
-{
- Error result;
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_BREAKPOINTS, "WaitForDebuggerConnection Waiting for loader breakpoint.");
-
- // Block this function until we receive the initial stop from the process.
- if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) == WAIT_OBJECT_0)
- {
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_BREAKPOINTS, "WaitForDebuggerConnection hit loader breakpoint, returning.");
-
- process = debugger->GetProcess();
- return m_session_data->m_launch_error;
- }
- else
- return Error(::GetLastError(), eErrorTypeWin32);
-}
-
-Error
-ProcessWindowsLive::DoResume()
-{
- llvm::sys::ScopedLock lock(m_mutex);
- Error error;
-
- StateType private_state = GetPrivateState();
- if (private_state == eStateStopped || private_state == eStateCrashed)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoResume called for process %I64u while state is %u. Resuming...",
- m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState());
-
- ExceptionRecordSP active_exception =
- m_session_data->m_debugger->GetActiveException().lock();
- if (active_exception)
- {
- // Resume the process and continue processing debug events. Mask
- // the exception so that from the process's view, there is no
- // indication that anything happened.
- m_session_data->m_debugger->ContinueAsyncException(
- ExceptionResult::MaskException);
- }
-
- WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_THREAD, "DoResume resuming %u threads.",
- m_thread_list.GetSize());
-
- for (int i = 0; i < m_thread_list.GetSize(); ++i)
- {
- auto thread = std::static_pointer_cast<TargetThreadWindowsLive>(
- m_thread_list.GetThreadAtIndex(i));
- thread->DoResume();
- }
-
- SetPrivateState(eStateRunning);
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoResume called for process %I64u but state is %u. Returning...",
- m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState());
- }
- return error;
-}
-
-
-//------------------------------------------------------------------------------
-// ProcessInterface protocol.
-
-lldb_private::ConstString
-ProcessWindowsLive::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessWindowsLive::GetPluginVersion()
-{
- return 1;
-}
-
-Error
-ProcessWindowsLive::DoDetach(bool keep_stopped)
-{
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire the lock only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which
- // will also acquire the lock. Thus we have to release the lock before
- // calling StopDebugging().
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "DoDetach called while state = %u, but there is no active session.",
- private_state);
- return Error();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Error error;
- if (private_state != eStateExited && private_state != eStateDetached)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoDetach called for process %I64u while state = %u. Detaching...",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- error = debugger_thread->StopDebugging(false);
- if (error.Success())
- {
- SetPrivateState(eStateDetached);
- }
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DoDetach called for process %I64u while state = %u, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- }
-
- return error;
-}
-
-Error
-ProcessWindowsLive::DoDestroy()
-{
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire this lock inside an inner scope, only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which will acquire the lock
- // again, so we need to not deadlock.
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "DoDestroy called while state = %u, but there is no active session.",
- private_state);
- return Error();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Error error;
- if (private_state != eStateExited && private_state != eStateDetached)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoDestroy called for process %I64u while state = %u. Shutting down...",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- error = debugger_thread->StopDebugging(true);
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DoDestroy called for process %I64u while state = %u, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- }
-
- return error;
-}
-
-void
-ProcessWindowsLive::RefreshStateAfterStop()
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "RefreshStateAfterStop called with no active session. Returning...");
- return;
- }
-
- m_thread_list.RefreshStateAfterStop();
-
- std::weak_ptr<ExceptionRecord> exception_record = m_session_data->m_debugger->GetActiveException();
- ExceptionRecordSP active_exception = exception_record.lock();
- if (!active_exception)
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "RefreshStateAfterStop called for process %I64u but there is no "
- "active exception. Why is the process stopped?",
- m_session_data->m_debugger->GetProcess().GetProcessId());
- return;
- }
-
- StopInfoSP stop_info;
- m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
- ThreadSP stop_thread = m_thread_list.GetSelectedThread();
- if (!stop_thread)
- return;
-
- switch (active_exception->GetExceptionCode())
- {
- case EXCEPTION_SINGLE_STEP:
- {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
- const uint64_t pc = register_context->GetPC();
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site && site->ValidForThisThread(stop_thread.get()))
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
- "Single-stepped onto a breakpoint in process %I64u at "
- "address 0x%I64x with breakpoint site %d",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID());
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread, site->GetID());
- stop_thread->SetStopInfo(stop_info);
- }
- else
- {
- WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
- "RefreshStateAfterStop single stepping thread %u", stop_thread->GetID());
- stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
- stop_thread->SetStopInfo(stop_info);
- }
- return;
- }
-
- case EXCEPTION_BREAKPOINT:
- {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
-
- // The current EIP is AFTER the BP opcode, which is one byte.
- uint64_t pc = register_context->GetPC() - 1;
-
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site)
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "RefreshStateAfterStop detected breakpoint in process %I64u at "
- "address 0x%I64x with breakpoint site %d",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID());
-
- if (site->ValidForThisThread(stop_thread.get()))
- {
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "Breakpoint site %d is valid for this thread (0x%I64x), creating stop info.",
- site->GetID(), stop_thread->GetID());
-
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
- *stop_thread, site->GetID());
- register_context->SetPC(pc);
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "Breakpoint site %d is not valid for this thread, creating empty stop info.",
- site->GetID());
- }
- stop_thread->SetStopInfo(stop_info);
- return;
- }
- else
- {
- // The thread hit a hard-coded breakpoint like an `int 3` or `__debugbreak()`.
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "No breakpoint site matches for this thread. __debugbreak()? "
- "Creating stop info with the exception.");
- // FALLTHROUGH: We'll treat this as a generic exception record in the default case.
- }
- }
-
- default:
- {
- std::string desc;
- llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address "
- << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
- stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
- stop_thread->SetStopInfo(stop_info);
- WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, desc_stream.str().c_str());
- return;
- }
- }
-}
-
-bool
-ProcessWindowsLive::IsAlive()
-{
- StateType state = GetPrivateState();
- switch (state)
- {
- case eStateCrashed:
- case eStateDetached:
- case eStateUnloaded:
- case eStateExited:
- case eStateInvalid:
- return false;
- default:
- return true;
- }
-}
-
-Error
-ProcessWindowsLive::DoHalt(bool &caused_stop)
-{
- Error error;
- StateType state = GetPrivateState();
- if (state == eStateStopped)
- caused_stop = false;
- else
- {
- llvm::sys::ScopedLock lock(m_mutex);
- caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess().GetNativeProcess().GetSystemHandle());
- if (!caused_stop)
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoHalt called DebugBreakProcess, but it failed with error %u",
- error.GetError());
- }
- }
- return error;
-}
-
-void
-ProcessWindowsLive::DidLaunch()
-{
- ArchSpec arch_spec;
- DidAttach(arch_spec);
-}
-
-void
-ProcessWindowsLive::DidAttach(ArchSpec &arch_spec)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // The initial stop won't broadcast the state change event, so account for that here.
- if (m_session_data && GetPrivateState() == eStateStopped && m_session_data->m_stop_at_entry)
- RefreshStateAfterStop();
-}
-
-size_t
-ProcessWindowsLive::DoReadMemory(lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- Error &error)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data)
- return 0;
-
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory attempting to read %u bytes from address 0x%I64x", size, vm_addr);
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_read = 0;
- if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr, buf, size, &bytes_read))
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u", error.GetError());
- }
- return bytes_read;
-}
-
-size_t
-ProcessWindowsLive::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Error &error)
-{
- llvm::sys::ScopedLock lock(m_mutex);
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size, vm_addr);
-
- if (!m_session_data)
- {
- WINERR_IFANY(WINDOWS_LOG_MEMORY, "DoWriteMemory cannot write, there is no active debugger connection.");
- return 0;
- }
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_written = 0;
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
- FlushInstructionCache(handle, addr, bytes_written);
- else
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u", error.GetError());
- }
- return bytes_written;
-}
-
-Error
-ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info)
-{
- Error error;
- llvm::sys::ScopedLock lock(m_mutex);
- info.Clear();
-
- if (!m_session_data)
- {
- error.SetErrorString("GetMemoryRegionInfo called with no debugging session.");
- WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
- return error;
- }
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
- {
- error.SetErrorString("GetMemoryRegionInfo called with an invalid target process.");
- WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
- return error;
- }
-
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr);
-
- void *addr = reinterpret_cast<void *>(vm_addr);
- MEMORY_BASIC_INFORMATION mem_info = {0};
- SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
- if (result == 0)
- {
- if (::GetLastError() == ERROR_INVALID_PARAMETER)
- {
- // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an address
- // past the highest accessible address. We should return a range from the vm_addr
- // to LLDB_INVALID_ADDRESS
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- info.SetMapped(MemoryRegionInfo::eNo);
- return error;
- }
- else
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_MEMORY,
- "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
- error.GetError(), vm_addr);
- return error;
- }
- }
-
- // Protect bits are only valid for MEM_COMMIT regions.
- if (mem_info.State == MEM_COMMIT) {
- const bool readable = IsPageReadable(mem_info.Protect);
- const bool executable = IsPageExecutable(mem_info.Protect);
- const bool writable = IsPageWritable(mem_info.Protect);
- info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- }
- else
- {
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- }
-
- // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
- if (mem_info.State != MEM_FREE) {
- info.GetRange().SetRangeBase(reinterpret_cast<addr_t>(mem_info.AllocationBase));
- info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) + mem_info.RegionSize);
- info.SetMapped(MemoryRegionInfo::eYes);
- }
- else
- {
- // In the unmapped case we need to return the distance to the next block of memory.
- // VirtualQueryEx nearly does that except that it gives the distance from the start
- // of the page containing vm_addr.
- SYSTEM_INFO data;
- GetSystemInfo(&data);
- DWORD page_offset = vm_addr % data.dwPageSize;
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
- info.SetMapped(MemoryRegionInfo::eNo);
- }
-
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: readable=%s, executable=%s, writable=%s",
- BOOL_STR(info.GetReadable()), BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable()));
- return error;
-}
-
-bool
-ProcessWindowsLive::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
-
- // 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();
- // However, if there is no executable module, we return true since we might be preparing to attach.
- return true;
-}
-
-void
-ProcessWindowsLive::OnExitProcess(uint32_t exit_code)
-{
- // No need to acquire the lock since m_session_data isn't accessed.
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %u exited with code %u", GetID(), exit_code);
-
- TargetSP target = m_target_sp.lock();
- if (target)
- {
- ModuleSP executable_module = target->GetExecutableModule();
- ModuleList unloaded_modules;
- unloaded_modules.Append(executable_module);
- target->ModulesDidUnload(unloaded_modules, true);
- }
-
- SetProcessExitStatus(GetID(), true, 0, exit_code);
- SetPrivateState(eStateExited);
-}
-
-void
-ProcessWindowsLive::OnDebuggerConnected(lldb::addr_t image_base)
-{
- DebuggerThreadSP debugger = m_session_data->m_debugger;
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Debugger connected to process %I64u. Image base = 0x%I64x",
- debugger->GetProcess().GetProcessId(), image_base);
-
- ModuleSP module = GetTarget().GetExecutableModule();
- if (!module)
- {
- // During attach, we won't have the executable module, so find it now.
- const DWORD pid = debugger->GetProcess().GetProcessId();
- const std::string file_name = GetProcessExecutableName(pid);
- if (file_name.empty())
- {
- return;
- }
-
- FileSpec executable_file(file_name, true);
- ModuleSpec module_spec(executable_file);
- Error error;
- module = GetTarget().GetSharedModule(module_spec, &error);
- if (!module)
- {
- return;
- }
-
- GetTarget().SetExecutableModule(module, false);
- }
-
- bool load_addr_changed;
- module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
-
- // Add the main executable module to the list of pending module loads. We can't call
- // GetTarget().ModulesDidLoad() here because we still haven't returned from DoLaunch() / DoAttach() yet
- // so the target may not have set the process instance to `this` yet.
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wmain_thread = debugger->GetMainThread().GetNativeThread();
- m_session_data->m_new_threads[wmain_thread.GetThreadId()] = debugger->GetMainThread();
-}
-
-ExceptionResult
-ProcessWindowsLive::OnDebugException(bool first_chance, const ExceptionRecord &record)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // FIXME: Without this check, occasionally when running the test suite there is
- // an issue where m_session_data can be null. It's not clear how this could happen
- // but it only surfaces while running the test suite. In order to properly diagnose
- // this, we probably need to first figure allow the test suite to print out full
- // lldb logs, and then add logging to the process plugin.
- if (!m_session_data)
- {
- WINERR_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%x at address 0x%I64x, but there is no session.",
- record.GetExceptionCode(), record.GetExceptionAddress());
- return ExceptionResult::SendToApplication;
- }
-
- if (!first_chance)
- {
- // Any second chance exception is an application crash by definition.
- SetPrivateState(eStateCrashed);
- }
-
- ExceptionResult result = ExceptionResult::SendToApplication;
- switch (record.GetExceptionCode())
- {
- case EXCEPTION_BREAKPOINT:
- // Handle breakpoints at the first chance.
- result = ExceptionResult::BreakInDebugger;
-
- if (!m_session_data->m_initial_stop_received)
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
- "Hit loader breakpoint at address 0x%I64x, setting initial stop event.",
- record.GetExceptionAddress());
- m_session_data->m_initial_stop_received = true;
- ::SetEvent(m_session_data->m_initial_stop_event);
- }
- else
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
- "Hit non-loader breakpoint at address 0x%I64x.",
- record.GetExceptionAddress());
- }
- SetPrivateState(eStateStopped);
- break;
- case EXCEPTION_SINGLE_STEP:
- result = ExceptionResult::BreakInDebugger;
- SetPrivateState(eStateStopped);
- break;
- default:
- WINLOG_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%x at address 0x%I64x (first_chance=%s)",
- record.GetExceptionCode(), record.GetExceptionAddress(), BOOL_STR(first_chance));
- // For non-breakpoints, give the application a chance to handle the exception first.
- if (first_chance)
- result = ExceptionResult::SendToApplication;
- else
- result = ExceptionResult::BreakInDebugger;
- }
-
- return result;
-}
-
-void
-ProcessWindowsLive::OnCreateThread(const HostThread &new_thread)
-{
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
- m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
-}
-
-void
-ProcessWindowsLive::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // On a forced termination, we may get exit thread events after the session
- // data has been cleaned up.
- if (!m_session_data)
- return;
-
- // A thread may have started and exited before the debugger stopped allowing a refresh.
- // Just remove it from the new threads list in that case.
- auto iter = m_session_data->m_new_threads.find(thread_id);
- if (iter != m_session_data->m_new_threads.end())
- m_session_data->m_new_threads.erase(iter);
- else
- m_session_data->m_exited_threads.insert(thread_id);
-}
-
-void
-ProcessWindowsLive::OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr)
-{
- // Confusingly, there is no Target::AddSharedModule. Instead, calling GetSharedModule() with
- // a new module will add it to the module list and return a corresponding ModuleSP.
- Error error;
- ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
- bool load_addr_changed = false;
- module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
-}
-
-void
-ProcessWindowsLive::OnUnloadDll(lldb::addr_t module_addr)
-{
- Address resolved_addr;
- if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr))
- {
- ModuleSP module = resolved_addr.GetModule();
- if (module)
- {
- ModuleList unloaded_modules;
- unloaded_modules.Append(module);
- GetTarget().ModulesDidUnload(unloaded_modules, false);
- }
- }
-}
-
-void
-ProcessWindowsLive::OnDebugString(const std::string &string)
-{
-}
-
-void
-ProcessWindowsLive::OnDebuggerError(const Error &error, uint32_t type)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (m_session_data->m_initial_stop_received)
- {
- // This happened while debugging. Do we shutdown the debugging session, try to continue,
- // or do something else?
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred during debugging. Unexpected behavior may result. %s",
- error.GetError(), error.AsCString());
- }
- else
- {
- // If we haven't actually launched the process yet, this was an error launching the
- // process. Set the internal error and signal the initial stop event so that the DoLaunch
- // method wakes up and returns a failure.
- m_session_data->m_launch_error = error;
- ::SetEvent(m_session_data->m_initial_stop_event);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred launching the process before the initial stop. %s",
- error.GetError(), error.AsCString());
- return;
- }
-}
diff --git a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
deleted file mode 100644
index 657877f529b2..000000000000
--- a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===-- ProcessWindowsLive.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_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
-#define liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
-
-// C Includes
-
-// C++ Includes
-#include <memory>
-#include <queue>
-
-// Other libraries and framework includes
-#include "ForwardDecl.h"
-#include "IDebugDelegate.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Process.h"
-
-#include "llvm/Support/Mutex.h"
-
-#include "plugins/Process/Windows/Common/ProcessWindows.h"
-
-class ProcessMonitor;
-
-namespace lldb_private
-{
-class HostProcess;
-class ProcessWindowsData;
-
-class ProcessWindowsLive : public lldb_private::ProcessWindows, public lldb_private::IDebugDelegate
-{
-public:
- //------------------------------------------------------------------
- // Static functions.
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessWindowsLive(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp);
-
- ~ProcessWindowsLive();
-
- // lldb_private::Process overrides
- lldb_private::ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
-
- lldb_private::Error EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- lldb_private::Error DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- lldb_private::Error DoDetach(bool keep_stopped) override;
- lldb_private::Error DoLaunch(lldb_private::Module *exe_module, lldb_private::ProcessLaunchInfo &launch_info) override;
- lldb_private::Error DoAttachToProcessWithID(lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
- lldb_private::Error DoResume() override;
- lldb_private::Error DoDestroy() override;
- lldb_private::Error DoHalt(bool &caused_stop) override;
-
- void DidLaunch() override;
- void DidAttach(lldb_private::ArchSpec &arch_spec) override;
-
- void RefreshStateAfterStop() override;
-
- bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
- bool
- DestroyRequiresHalt() override
- {
- return false;
- }
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override;
- bool IsAlive() override;
-
- size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, lldb_private::Error &error) override;
- size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, lldb_private::Error &error) override;
- lldb_private::Error GetMemoryRegionInfo(lldb::addr_t vm_addr, lldb_private::MemoryRegionInfo &info) override;
-
- // IDebugDelegate overrides.
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance, const lldb_private::ExceptionRecord &record) override;
- void OnCreateThread(const lldb_private::HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &string) override;
- void OnDebuggerError(const lldb_private::Error &error, uint32_t type) override;
-
- private:
- lldb_private::Error WaitForDebuggerConnection(lldb_private::DebuggerThreadSP debugger,
- lldb_private::HostProcess &process);
-
- llvm::sys::Mutex m_mutex;
-
- // Data for the active debugging session.
- std::unique_ptr<lldb_private::ProcessWindowsData> m_session_data;
-};
-
-}
-
-#endif // liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
diff --git a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
deleted file mode 100644
index 52b32716e674..000000000000
--- a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- TargetThreadWindowsLive.cpp------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/Log.h"
-#include "lldb/Core/Logging.h"
-#include "lldb/Core/State.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/HostNativeThreadBase.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Target/RegisterContext.h"
-
-#include "TargetThreadWindowsLive.h"
-#include "ProcessWindows.h"
-#include "ProcessWindowsLog.h"
-#include "UnwindLLDB.h"
-
-#if defined(_WIN64)
-#include "x64/RegisterContextWindowsLive_x64.h"
-#else
-#include "x86/RegisterContextWindowsLive_x86.h"
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread)
- : TargetThreadWindows(process, thread)
- , m_host_thread(thread)
-{
-}
-
-TargetThreadWindowsLive::~TargetThreadWindowsLive()
-{
- DestroyThread();
-}
-
-void
-TargetThreadWindowsLive::RefreshStateAfterStop()
-{
- ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
- SetState(eStateStopped);
- GetRegisterContext()->InvalidateIfNeeded(false);
-}
-
-void
-TargetThreadWindowsLive::WillResume(lldb::StateType resume_state)
-{
-}
-
-void
-TargetThreadWindowsLive::DidStop()
-{
-}
-
-RegisterContextSP
-TargetThreadWindowsLive::GetRegisterContext()
-{
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
-
- return m_reg_context_sp;
-}
-
-RegisterContextSP
-TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame)
-{
- return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
-}
-
-RegisterContextSP
-TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx)
-{
- if (!m_reg_context_sp)
- {
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine())
- {
- case llvm::Triple::x86:
-#if defined(_WIN64)
- // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
-#else
- m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx));
-#endif
- break;
- case llvm::Triple::x86_64:
-#if defined(_WIN64)
- m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx));
-#else
- // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
-#endif
- default:
- break;
- }
- }
- return m_reg_context_sp;
-}
-
-bool
-TargetThreadWindowsLive::CalculateStopInfo()
-{
- SetStopInfo(m_stop_info_sp);
- return true;
-}
-
-Unwind *
-TargetThreadWindowsLive::GetUnwinder()
-{
- // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
- if (m_unwinder_ap.get() == NULL)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
- return m_unwinder_ap.get();
-}
-
-bool
-TargetThreadWindowsLive::DoResume()
-{
- StateType resume_state = GetTemporaryResumeState();
- StateType current_state = GetState();
- if (resume_state == current_state)
- return true;
-
- if (resume_state == eStateStepping)
- {
- uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
- flags_value |= 0x100; // Set the trap flag on the CPU
- GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
- }
-
- if (resume_state == eStateStepping || resume_state == eStateRunning)
- {
- DWORD previous_suspend_count = 0;
- HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
- do
- {
- previous_suspend_count = ::ResumeThread(thread_handle);
- } while (previous_suspend_count > 0);
- }
- return true;
-}
diff --git a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h
deleted file mode 100644
index 15262b9e9423..000000000000
--- a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- TargetThreadWindowsLive.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_Plugins_Process_Windows_TargetThreadWindowsLive_H_
-#define liblldb_Plugins_Process_Windows_TargetThreadWindowsLive_H_
-
-#include "lldb/lldb-forward.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Thread.h"
-
-#include "Plugins/Process/Windows/Common/TargetThreadWindows.h"
-
-namespace lldb_private
-{
-class ProcessWindows;
-class HostThread;
-class StackFrame;
-
-class TargetThreadWindowsLive : public lldb_private::TargetThreadWindows
-{
- public:
- TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread);
- virtual ~TargetThreadWindowsLive();
-
- // lldb_private::Thread overrides
- void RefreshStateAfterStop() override;
- void WillResume(lldb::StateType resume_state) override;
- void DidStop() override;
- lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override;
- bool CalculateStopInfo() override;
- Unwind *GetUnwinder() override;
-
- bool DoResume();
-
- HostThread
- GetHostThread() const
- {
- return m_host_thread;
- }
-
- private:
- lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
-
- HostThread m_host_thread;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp b/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp
deleted file mode 100644
index e74647ab68fb..000000000000
--- a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-//===-- RegisterContextWindowsLive_x64.cpp ----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private-types.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "lldb-x86-register-enums.h"
-#include "RegisterContextWindowsLive_x64.h"
-#include "TargetThreadWindows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextWindowsLive_x64::RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows_x64(thread, concrete_frame_idx)
-{
-}
-
-RegisterContextWindowsLive_x64::~RegisterContextWindowsLive_x64()
-{
-}
-
-
-bool
-RegisterContextWindowsLive_x64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!CacheAllRegisterValues())
- return false;
-
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- reg_value.SetUInt64(m_context.Rax);
- break;
- case lldb_rbx_x86_64:
- reg_value.SetUInt64(m_context.Rbx);
- break;
- case lldb_rcx_x86_64:
- reg_value.SetUInt64(m_context.Rcx);
- break;
- case lldb_rdx_x86_64:
- reg_value.SetUInt64(m_context.Rdx);
- break;
- case lldb_rdi_x86_64:
- reg_value.SetUInt64(m_context.Rdi);
- break;
- case lldb_rsi_x86_64:
- reg_value.SetUInt64(m_context.Rsi);
- break;
- case lldb_r8_x86_64:
- reg_value.SetUInt64(m_context.R8);
- break;
- case lldb_r9_x86_64:
- reg_value.SetUInt64(m_context.R9);
- break;
- case lldb_r10_x86_64:
- reg_value.SetUInt64(m_context.R10);
- break;
- case lldb_r11_x86_64:
- reg_value.SetUInt64(m_context.R11);
- break;
- case lldb_r12_x86_64:
- reg_value.SetUInt64(m_context.R12);
- break;
- case lldb_r13_x86_64:
- reg_value.SetUInt64(m_context.R13);
- break;
- case lldb_r14_x86_64:
- reg_value.SetUInt64(m_context.R14);
- break;
- case lldb_r15_x86_64:
- reg_value.SetUInt64(m_context.R15);
- break;
- case lldb_rbp_x86_64:
- reg_value.SetUInt64(m_context.Rbp);
- break;
- case lldb_rsp_x86_64:
- reg_value.SetUInt64(m_context.Rsp);
- break;
- case lldb_rip_x86_64:
- reg_value.SetUInt64(m_context.Rip);
- break;
- case lldb_rflags_x86_64:
- reg_value.SetUInt64(m_context.EFlags);
- break;
- }
- return true;
-}
-
-bool
-RegisterContextWindowsLive_x64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
-
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- m_context.Rax = reg_value.GetAsUInt64();
- break;
- case lldb_rbx_x86_64:
- m_context.Rbx = reg_value.GetAsUInt64();
- break;
- case lldb_rcx_x86_64:
- m_context.Rcx = reg_value.GetAsUInt64();
- break;
- case lldb_rdx_x86_64:
- m_context.Rdx = reg_value.GetAsUInt64();
- break;
- case lldb_rdi_x86_64:
- m_context.Rdi = reg_value.GetAsUInt64();
- break;
- case lldb_rsi_x86_64:
- m_context.Rsi = reg_value.GetAsUInt64();
- break;
- case lldb_r8_x86_64:
- m_context.R8 = reg_value.GetAsUInt64();
- break;
- case lldb_r9_x86_64:
- m_context.R9 = reg_value.GetAsUInt64();
- break;
- case lldb_r10_x86_64:
- m_context.R10 = reg_value.GetAsUInt64();
- break;
- case lldb_r11_x86_64:
- m_context.R11 = reg_value.GetAsUInt64();
- break;
- case lldb_r12_x86_64:
- m_context.R12 = reg_value.GetAsUInt64();
- break;
- case lldb_r13_x86_64:
- m_context.R13 = reg_value.GetAsUInt64();
- break;
- case lldb_r14_x86_64:
- m_context.R14 = reg_value.GetAsUInt64();
- break;
- case lldb_r15_x86_64:
- m_context.R15 = reg_value.GetAsUInt64();
- break;
- case lldb_rbp_x86_64:
- m_context.Rbp = reg_value.GetAsUInt64();
- break;
- case lldb_rsp_x86_64:
- m_context.Rsp = reg_value.GetAsUInt64();
- break;
- case lldb_rip_x86_64:
- m_context.Rip = reg_value.GetAsUInt64();
- break;
- case lldb_rflags_x86_64:
- m_context.EFlags = reg_value.GetAsUInt64();
- break;
- }
-
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
-}
diff --git a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h b/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h
deleted file mode 100644
index bd250a994d3a..000000000000
--- a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- RegisterContextWindowsLive_x64.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_RegisterContextWindowsLive_x64_H_
-#define liblldb_RegisterContextWindowsLive_x64_H_
-
-#include "lldb/lldb-forward.h"
-#include "../../Common/x64/RegisterContextWindows_x64.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsLive_x64 : public RegisterContextWindows_x64
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindowsLive_x64();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-};
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsLive_x64_H_
diff --git a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp b/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp
deleted file mode 100644
index f2decc72d16d..000000000000
--- a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//===-- RegisterContextWindowsLive_x86.cpp ------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private-types.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "lldb-x86-register-enums.h"
-#include "ProcessWindowsLog.h"
-#include "RegisterContextWindowsLive_x86.h"
-#include "TargetThreadWindows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-
-namespace lldb_private
-{
-
-RegisterContextWindowsLive_x86::RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows_x86(thread, concrete_frame_idx)
-{
-}
-
-RegisterContextWindowsLive_x86::~RegisterContextWindowsLive_x86()
-{
-}
-
-
-bool
-RegisterContextWindowsLive_x86::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
-
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg)
- {
- case lldb_eax_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX", reg_value.GetAsUInt32());
- m_context.Eax = reg_value.GetAsUInt32();
- break;
- case lldb_ebx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX", reg_value.GetAsUInt32());
- m_context.Ebx = reg_value.GetAsUInt32();
- break;
- case lldb_ecx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX", reg_value.GetAsUInt32());
- m_context.Ecx = reg_value.GetAsUInt32();
- break;
- case lldb_edx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX", reg_value.GetAsUInt32());
- m_context.Edx = reg_value.GetAsUInt32();
- break;
- case lldb_edi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI", reg_value.GetAsUInt32());
- m_context.Edi = reg_value.GetAsUInt32();
- break;
- case lldb_esi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI", reg_value.GetAsUInt32());
- m_context.Esi = reg_value.GetAsUInt32();
- break;
- case lldb_ebp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP", reg_value.GetAsUInt32());
- m_context.Ebp = reg_value.GetAsUInt32();
- break;
- case lldb_esp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP", reg_value.GetAsUInt32());
- m_context.Esp = reg_value.GetAsUInt32();
- break;
- case lldb_eip_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP", reg_value.GetAsUInt32());
- m_context.Eip = reg_value.GetAsUInt32();
- break;
- case lldb_eflags_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS", reg_value.GetAsUInt32());
- m_context.EFlags = reg_value.GetAsUInt32();
- break;
- default:
- WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to unknown register %u", reg_value.GetAsUInt32(),
- reg);
- }
-
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
-}
-
-} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h b/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h
deleted file mode 100644
index 9554f017408a..000000000000
--- a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextWindowsLive_x86.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_RegisterContextWindowsLive_x86_H_
-#define liblldb_RegisterContextWindowsLive_x86_H_
-
-#include "lldb/lldb-forward.h"
-#include "../../Common/x86/RegisterContextWindows_x86.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsLive_x86 : public RegisterContextWindows_x86
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindowsLive_x86();
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-};
-
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsLive_x86_H_
diff --git a/source/Plugins/Process/Windows/MiniDump/CMakeLists.txt b/source/Plugins/Process/Windows/MiniDump/CMakeLists.txt
deleted file mode 100644
index b43246b00351..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-include_directories(../../Utility)
-include_directories(../Common)
-
-set(PROC_WINDOWS_MINIDUMP_SOURCES
- ProcessWinMiniDump.cpp
- ThreadWinMiniDump.cpp
- )
-
-if (CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(PROC_WINDOWS_MINIDUMP_SOURCES ${PROC_WINDOWS_MINIDUMP_SOURCES}
- x86/RegisterContextWindowsMiniDump_x86.cpp
- )
-elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(PROC_WINDOWS_MINIDUMP_SOURCES ${PROC_WINDOWS_MINIDUMP_SOURCES}
- x64/RegisterContextWindowsMiniDump_x64.cpp
- )
-endif()
-
-add_lldb_library(lldbPluginProcessWinMiniDump
- ${PROC_WINDOWS_MINIDUMP_SOURCES}
- )
diff --git a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
deleted file mode 100644
index 05839667688f..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
+++ /dev/null
@@ -1,710 +0,0 @@
-//===-- ProcessWinMiniDump.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessWinMiniDump.h"
-
-#include "lldb/Host/windows/windows.h"
-#include <DbgHelp.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#include <memory>
-#include <mutex>
-
-#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/Log.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/Target/MemoryRegionInfo.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include "Plugins/Process/Windows/Common/NtStructures.h"
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "ExceptionRecord.h"
-#include "ThreadWinMiniDump.h"
-
-using namespace lldb_private;
-
-// Implementation class for ProcessWinMiniDump encapsulates the Windows-specific
-// code, keeping non-portable types out of the header files.
-// TODO(amccarth): Determine if we need a mutex for access. Given that this is
-// postmortem debugging, I don't think so.
-class ProcessWinMiniDump::Impl
-{
-public:
- Impl(const FileSpec &core_file, ProcessWinMiniDump *self);
- ~Impl();
-
- Error
- DoLoadCore();
-
- bool
- UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list);
-
- void
- RefreshStateAfterStop();
-
- size_t
- DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error);
-
- Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info);
-
-private:
- // Describes a range of memory captured in the mini dump.
- struct Range
- {
- lldb::addr_t start; // virtual address of the beginning of the range
- size_t size; // size of the range in bytes
- const uint8_t *ptr; // absolute pointer to the first byte of the range
- };
-
- // If the mini dump has a memory range that contains the desired address, it
- // returns true with the details of the range in *range_out. Otherwise, it
- // returns false.
- bool
- FindMemoryRange(lldb::addr_t addr, Range *range_out) const;
-
- lldb_private::Error
- MapMiniDumpIntoMemory();
-
- lldb_private::ArchSpec
- DetermineArchitecture();
-
- void
- ReadExceptionRecord();
-
- void
- ReadMiscInfo();
-
- void
- ReadModuleList();
-
- // A thin wrapper around WinAPI's MiniDumpReadDumpStream to avoid redundant
- // checks. If there's a failure (e.g., if the requested stream doesn't exist),
- // the function returns nullptr and sets *size_out to 0.
- void *
- FindDumpStream(unsigned stream_number, size_t *size_out) const;
-
- // Getting a string out of a mini dump is a chore. You're usually given a
- // relative virtual address (RVA), which points to a counted string that's in
- // Windows Unicode (UTF-16). This wrapper handles all the redirection and
- // returns a UTF-8 copy of the string.
- std::string
- GetMiniDumpString(RVA rva) const;
-
- ProcessWinMiniDump *m_self; // non-owning back pointer
- FileSpec m_core_file;
- HANDLE m_dump_file; // handle to the open minidump file
- HANDLE m_mapping; // handle to the file mapping for the minidump file
- void * m_base_addr; // base memory address of the minidump
- std::shared_ptr<ExceptionRecord> m_exception_sp;
- bool m_is_wow64; // minidump is of a 32-bit process captured with a 64-bit debugger
-};
-
-ProcessWinMiniDump::Impl::Impl(const FileSpec &core_file, ProcessWinMiniDump *self)
- : m_self(self),
- m_core_file(core_file),
- m_dump_file(INVALID_HANDLE_VALUE),
- m_mapping(NULL),
- m_base_addr(nullptr),
- m_exception_sp(),
- m_is_wow64(false)
-{
-}
-
-ProcessWinMiniDump::Impl::~Impl()
-{
- if (m_base_addr)
- {
- ::UnmapViewOfFile(m_base_addr);
- m_base_addr = nullptr;
- }
- if (m_mapping)
- {
- ::CloseHandle(m_mapping);
- m_mapping = NULL;
- }
- if (m_dump_file != INVALID_HANDLE_VALUE)
- {
- ::CloseHandle(m_dump_file);
- m_dump_file = INVALID_HANDLE_VALUE;
- }
-}
-
-Error
-ProcessWinMiniDump::Impl::DoLoadCore()
-{
- Error error = MapMiniDumpIntoMemory();
- if (error.Fail())
- {
- return error;
- }
-
- m_self->GetTarget().SetArchitecture(DetermineArchitecture());
- ReadMiscInfo(); // notably for process ID
- ReadModuleList();
- ReadExceptionRecord();
-
- return error;
-
-}
-
-bool
-ProcessWinMiniDump::Impl::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- size_t size = 0;
- auto thread_list_ptr = static_cast<const MINIDUMP_THREAD_LIST *>(FindDumpStream(ThreadListStream, &size));
- if (thread_list_ptr)
- {
- const ULONG32 thread_count = thread_list_ptr->NumberOfThreads;
- for (ULONG32 i = 0; i < thread_count; ++i) {
- const auto &mini_dump_thread = thread_list_ptr->Threads[i];
- auto thread_sp = std::make_shared<ThreadWinMiniDump>(*m_self, mini_dump_thread.ThreadId);
- if (mini_dump_thread.ThreadContext.DataSize >= sizeof(CONTEXT))
- {
- const CONTEXT *context = reinterpret_cast<const CONTEXT *>(static_cast<const char *>(m_base_addr) +
- mini_dump_thread.ThreadContext.Rva);
-
- if (m_is_wow64)
- {
- // On Windows, a 32-bit process can run on a 64-bit machine under WOW64.
- // If the minidump was captured with a 64-bit debugger, then the CONTEXT
- // we just grabbed from the mini_dump_thread is the one for the 64-bit
- // "native" process rather than the 32-bit "guest" process we care about.
- // In this case, we can get the 32-bit CONTEXT from the TEB (Thread
- // Environment Block) of the 64-bit process.
- Error error;
- TEB64 wow64teb = {0};
- m_self->ReadMemory(mini_dump_thread.Teb, &wow64teb, sizeof(wow64teb), error);
- if (error.Success())
- {
- // Slot 1 of the thread-local storage in the 64-bit TEB points to a structure
- // that includes the 32-bit CONTEXT (after a ULONG).
- // See: https://msdn.microsoft.com/en-us/library/ms681670.aspx
- const size_t addr = wow64teb.TlsSlots[1];
- Range range = {0};
- if (FindMemoryRange(addr, &range))
- {
- lldbassert(range.start <= addr);
- const size_t offset = addr - range.start + sizeof(ULONG);
- if (offset < range.size)
- {
- const size_t overlap = range.size - offset;
- if (overlap >= sizeof(CONTEXT))
- {
- context = reinterpret_cast<const CONTEXT *>(range.ptr + offset);
- }
- }
- }
- }
-
- // NOTE: We don't currently use the TEB for anything else. If we need it in
- // the future, the 32-bit TEB is located according to the address stored in the
- // first slot of the 64-bit TEB (wow64teb.Reserved1[0]).
- }
-
- thread_sp->SetContext(context);
- }
- new_thread_list.AddThread(thread_sp);
- }
- }
-
- return new_thread_list.GetSize(false) > 0;
-}
-
-void
-ProcessWinMiniDump::Impl::RefreshStateAfterStop()
-{
- if (!m_exception_sp)
- return;
-
- auto active_exception = m_exception_sp;
- std::string desc;
- llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address " << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
- m_self->m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
- auto stop_thread = m_self->m_thread_list.GetSelectedThread();
- auto stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
- stop_thread->SetStopInfo(stop_info);
-}
-
-size_t
-ProcessWinMiniDump::Impl::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- // I don't have a sense of how frequently this is called or how many memory
- // ranges a mini dump typically has, so I'm not sure if searching for the
- // appropriate range linearly each time is stupid. Perhaps we should build
- // an index for faster lookups.
- Range range = {0};
- if (!FindMemoryRange(addr, &range))
- {
- return 0;
- }
-
- // There's at least some overlap between the beginning of the desired range
- // (addr) and the current range. Figure out where the overlap begins and
- // how much overlap there is, then copy it to the destination buffer.
- lldbassert(range.start <= addr);
- const size_t offset = addr - range.start;
- lldbassert(offset < range.size);
- const size_t overlap = std::min(size, range.size - offset);
- std::memcpy(buf, range.ptr + offset, overlap);
- return overlap;
-}
-
-Error
-ProcessWinMiniDump::Impl::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
-{
- Error error;
- size_t size;
- info.Clear();
- const auto list = reinterpret_cast<const MINIDUMP_MEMORY_INFO_LIST *>(FindDumpStream(MemoryInfoListStream, &size));
- if (list == nullptr || size < sizeof(MINIDUMP_MEMORY_INFO_LIST))
- {
- error.SetErrorString("the mini dump contains no memory range information");
- return error;
- }
-
- if (list->SizeOfEntry < sizeof(MINIDUMP_MEMORY_INFO))
- {
- error.SetErrorString("the entries in the mini dump memory info list are smaller than expected");
- return error;
- }
-
- if (size < list->SizeOfHeader + list->SizeOfEntry * list->NumberOfEntries)
- {
- error.SetErrorString("the mini dump memory info list is incomplete");
- return error;
- }
-
- const MINIDUMP_MEMORY_INFO *next_entry = nullptr;
-
- for (int i = 0; i < list->NumberOfEntries; ++i)
- {
- const auto entry = reinterpret_cast<const MINIDUMP_MEMORY_INFO *>(reinterpret_cast<const char *>(list) +
- list->SizeOfHeader + i * list->SizeOfEntry);
- const auto head = entry->BaseAddress;
- const auto tail = head + entry->RegionSize;
- if (head <= load_addr && load_addr < tail)
- {
- info.GetRange().SetRangeBase((entry->State != MEM_FREE) ? head : load_addr);
- info.GetRange().SetRangeEnd(tail);
- info.SetReadable(IsPageReadable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetWritable(IsPageWritable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetExecutable(IsPageExecutable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetMapped((entry->State != MEM_FREE) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- return error;
- }
- else if (head > load_addr && (next_entry == nullptr || head < next_entry->BaseAddress) )
- {
- // 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;
- }
- }
-
- // 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->BaseAddress:LLDB_INVALID_ADDRESS);
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetMapped(MemoryRegionInfo::eNo);
-
- // 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 error;
-}
-
-bool
-ProcessWinMiniDump::Impl::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
-{
- size_t stream_size = 0;
- auto mem_list_stream = static_cast<const MINIDUMP_MEMORY_LIST *>(FindDumpStream(MemoryListStream, &stream_size));
- if (mem_list_stream)
- {
- for (ULONG32 i = 0; i < mem_list_stream->NumberOfMemoryRanges; ++i)
- {
- const MINIDUMP_MEMORY_DESCRIPTOR &mem_desc = mem_list_stream->MemoryRanges[i];
- const MINIDUMP_LOCATION_DESCRIPTOR &loc_desc = mem_desc.Memory;
- const lldb::addr_t range_start = mem_desc.StartOfMemoryRange;
- const size_t range_size = loc_desc.DataSize;
- if (range_start <= addr && addr < range_start + range_size)
- {
- range_out->start = range_start;
- range_out->size = range_size;
- range_out->ptr = reinterpret_cast<const uint8_t *>(m_base_addr) + loc_desc.Rva;
- return true;
- }
- }
- }
-
- // Some mini dumps have a Memory64ListStream that captures all the heap
- // memory. We can't exactly use the same loop as above, because the mini
- // dump uses slightly different data structures to describe those.
- auto mem_list64_stream = static_cast<const MINIDUMP_MEMORY64_LIST *>(FindDumpStream(Memory64ListStream, &stream_size));
- if (mem_list64_stream)
- {
- size_t base_rva = mem_list64_stream->BaseRva;
- for (ULONG32 i = 0; i < mem_list64_stream->NumberOfMemoryRanges; ++i) {
- const MINIDUMP_MEMORY_DESCRIPTOR64 &mem_desc = mem_list64_stream->MemoryRanges[i];
- const lldb::addr_t range_start = mem_desc.StartOfMemoryRange;
- const size_t range_size = mem_desc.DataSize;
- if (range_start <= addr && addr < range_start + range_size)
- {
- range_out->start = range_start;
- range_out->size = range_size;
- range_out->ptr = reinterpret_cast<const uint8_t *>(m_base_addr) + base_rva;
- return true;
- }
- base_rva += range_size;
- }
- }
-
- return false;
-}
-
-Error
-ProcessWinMiniDump::Impl::MapMiniDumpIntoMemory()
-{
- Error error;
- const char *file = m_core_file.GetCString();
- std::wstring wfile;
- if (!llvm::ConvertUTF8toWide(file, wfile))
- {
- error.SetErrorString("Error converting path to UTF-16");
- return error;
- }
- m_dump_file =
- ::CreateFileW(wfile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (m_dump_file == INVALID_HANDLE_VALUE)
- {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
-
- m_mapping = ::CreateFileMappingW(m_dump_file, NULL, PAGE_READONLY, 0, 0, NULL);
- if (m_mapping == NULL)
- {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
-
- m_base_addr = ::MapViewOfFile(m_mapping, FILE_MAP_READ, 0, 0, 0);
- if (m_base_addr == nullptr)
- {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
-
- return error;
-}
-
-ArchSpec
-ProcessWinMiniDump::Impl::DetermineArchitecture()
-{
- size_t size = 0;
- auto system_info_ptr = static_cast<const MINIDUMP_SYSTEM_INFO *>(FindDumpStream(SystemInfoStream, &size));
- if (system_info_ptr)
- {
- switch (system_info_ptr->ProcessorArchitecture)
- {
- case PROCESSOR_ARCHITECTURE_INTEL:
- if (system_info_ptr->ProcessorLevel == 6)
- {
- return ArchSpec("i686-pc-windows");
- }
- else
- {
- return ArchSpec("i386-pc-windows");
- }
- break;
- case PROCESSOR_ARCHITECTURE_AMD64:
- return ArchSpec("x86_64-pc-windows");
- default:
- break;
- }
- }
-
- return ArchSpec(); // invalid or unknown
-}
-
-void
-ProcessWinMiniDump::Impl::ReadExceptionRecord()
-{
- size_t size = 0;
- auto exception_stream_ptr = static_cast<MINIDUMP_EXCEPTION_STREAM*>(FindDumpStream(ExceptionStream, &size));
- if (exception_stream_ptr)
- {
- m_exception_sp.reset(
- new ExceptionRecord(exception_stream_ptr->ExceptionRecord, exception_stream_ptr->ThreadId));
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Minidump has no exception record.");
- // TODO: See if we can recover the exception from the TEB.
- }
-}
-
-void
-ProcessWinMiniDump::Impl::ReadMiscInfo()
-{
- size_t size = 0;
- const auto misc_info_ptr = static_cast<MINIDUMP_MISC_INFO*>(FindDumpStream(MiscInfoStream, &size));
- if (!misc_info_ptr || size < sizeof(MINIDUMP_MISC_INFO)) {
- return;
- }
-
- if ((misc_info_ptr->Flags1 & MINIDUMP_MISC1_PROCESS_ID) != 0) {
- // This misc info record has the process ID.
- m_self->SetID(misc_info_ptr->ProcessId);
- }
-}
-
-void
-ProcessWinMiniDump::Impl::ReadModuleList()
-{
- size_t size = 0;
- auto module_list_ptr = static_cast<MINIDUMP_MODULE_LIST*>(FindDumpStream(ModuleListStream, &size));
- if (!module_list_ptr || module_list_ptr->NumberOfModules == 0)
- {
- return;
- }
-
- for (ULONG32 i = 0; i < module_list_ptr->NumberOfModules; ++i)
- {
- const auto &module = module_list_ptr->Modules[i];
- const auto file_name = GetMiniDumpString(module.ModuleNameRva);
- const auto file_spec = FileSpec(file_name, true);
- if (FileSpec::Compare(file_spec, FileSpec("wow64.dll", false), false) == 0)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Minidump is for a WOW64 process.");
- m_is_wow64 = true;
- }
- ModuleSpec module_spec = file_spec;
-
- lldb::ModuleSP module_sp = m_self->GetTarget().GetSharedModule(module_spec);
- if (!module_sp)
- {
- continue;
- }
- bool load_addr_changed = false;
- module_sp->SetLoadAddress(m_self->GetTarget(), module.BaseOfImage, false, load_addr_changed);
- }
-}
-
-void *
-ProcessWinMiniDump::Impl::FindDumpStream(unsigned stream_number, size_t *size_out) const
-{
- void *stream = nullptr;
- *size_out = 0;
-
- MINIDUMP_DIRECTORY *dir = nullptr;
- if (::MiniDumpReadDumpStream(m_base_addr, stream_number, &dir, nullptr, nullptr) && dir != nullptr &&
- dir->Location.DataSize > 0)
- {
- assert(dir->StreamType == stream_number);
- *size_out = dir->Location.DataSize;
- stream = static_cast<void *>(static_cast<char *>(m_base_addr) + dir->Location.Rva);
- }
-
- return stream;
-}
-
-std::string
-ProcessWinMiniDump::Impl::GetMiniDumpString(RVA rva) const
-{
- std::string result;
- if (!m_base_addr)
- {
- return result;
- }
- auto md_string = reinterpret_cast<const MINIDUMP_STRING *>(static_cast<const char *>(m_base_addr) + rva);
- auto source_start = reinterpret_cast<const UTF16 *>(md_string->Buffer);
- const auto source_length = ::wcslen(md_string->Buffer);
- const auto source_end = source_start + source_length;
- result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * source_length); // worst case length
- auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
- const auto result_end = result_start + result.size();
- ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);
- const auto result_size = std::distance(reinterpret_cast<UTF8 *>(&result[0]), result_start);
- result.resize(result_size); // shrink to actual length
- return result;
-}
-
-ConstString
-ProcessWinMiniDump::GetPluginNameStatic()
-{
- static ConstString g_name("win-minidump");
- return g_name;
-}
-
-const char *
-ProcessWinMiniDump::GetPluginDescriptionStatic()
-{
- return "Windows minidump plug-in.";
-}
-
-void
-ProcessWinMiniDump::Terminate()
-{
- PluginManager::UnregisterPlugin(ProcessWinMiniDump::CreateInstance);
-}
-
-lldb::ProcessSP
-ProcessWinMiniDump::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
-{
- lldb::ProcessSP process_sp;
- if (crash_file)
- {
- process_sp.reset(new ProcessWinMiniDump(target_sp, listener_sp, *crash_file));
- }
- return process_sp;
-}
-
-bool
-ProcessWinMiniDump::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- // TODO(amccarth): Eventually, this needs some actual logic.
- return true;
-}
-
-ProcessWinMiniDump::ProcessWinMiniDump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file)
- : ProcessWindows(target_sp, listener_sp), m_impl_up(new Impl(core_file, this))
-{
-}
-
-ProcessWinMiniDump::~ProcessWinMiniDump()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
-}
-
-ConstString
-ProcessWinMiniDump::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessWinMiniDump::GetPluginVersion()
-{
- return 1;
-}
-
-Error
-ProcessWinMiniDump::DoLoadCore()
-{
- return m_impl_up->DoLoadCore();
-}
-
-DynamicLoader *
-ProcessWinMiniDump::GetDynamicLoader()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset(DynamicLoader::FindPlugin(this, DynamicLoaderWindowsDYLD::GetPluginNameStatic().GetCString()));
- return m_dyld_ap.get();
-}
-
-bool
-ProcessWinMiniDump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- return m_impl_up->UpdateThreadList(old_thread_list, new_thread_list);
-}
-
-void
-ProcessWinMiniDump::RefreshStateAfterStop()
-{
- if (!m_impl_up)
- return;
- return m_impl_up->RefreshStateAfterStop();
-}
-
-Error
-ProcessWinMiniDump::DoDestroy()
-{
- return Error();
-}
-
-bool
-ProcessWinMiniDump::IsAlive()
-{
- return true;
-}
-
-bool
-ProcessWinMiniDump::WarnBeforeDetach() const
-{
- // Since this is post-mortem debugging, there's no need to warn the user
- // that quitting the debugger will terminate the process.
- return false;
-}
-
-size_t
-ProcessWinMiniDump::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since we have it all cached our our dump file anyway.
- return DoReadMemory(addr, buf, size, error);
-}
-
-size_t
-ProcessWinMiniDump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- return m_impl_up->DoReadMemory(addr, buf, size, error);
-}
-
-Error
-ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
-{
- return m_impl_up->GetMemoryRegionInfo(load_addr, info);
-}
-
-void
-ProcessWinMiniDump::Clear()
-{
- m_thread_list.Clear();
-}
-
-void
-ProcessWinMiniDump::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
- });
-}
-
-ArchSpec
-ProcessWinMiniDump::GetArchitecture()
-{
- // TODO
- return ArchSpec();
-}
diff --git a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
deleted file mode 100644
index 3e1ac4bffbe3..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===-- ProcessWinMiniDump.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_ProcessWinMiniDump_h_
-#define liblldb_ProcessWinMiniDump_h_
-
-#include <list>
-#include <vector>
-
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Target/Process.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindows.h"
-
-struct ThreadData;
-
-class ProcessWinMiniDump : public lldb_private::ProcessWindows
-{
- public:
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- ProcessWinMiniDump(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec &core_file);
-
- virtual
- ~ProcessWinMiniDump();
-
- bool
- CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
-
- lldb_private::Error
- DoLoadCore() override;
-
- lldb_private::DynamicLoader *
- GetDynamicLoader() override;
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- lldb_private::Error
- DoDestroy() override;
-
- void
- RefreshStateAfterStop() override;
-
- bool
- IsAlive() override;
-
- bool
- WarnBeforeDetach () const override;
-
- size_t
- ReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- size_t
- DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- lldb_private::ArchSpec
- GetArchitecture();
-
- lldb_private::Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &range_info) override;
-
- protected:
- void
- Clear();
-
- bool
- UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- private:
- // Keep Windows-specific types out of this header.
- class Impl;
- std::unique_ptr<Impl> m_impl_up;
-};
-
-#endif // liblldb_ProcessWinMiniDump_h_
diff --git a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp b/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp
deleted file mode 100644
index ddcd15b1ae12..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-//===-- ThreadWinMiniDump.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ThreadWinMiniDump.h"
-
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/windows/windows.h"
-#include <DbgHelp.h>
-
-#include "ProcessWinMiniDump.h"
-#if defined(_WIN64)
-#include "x64/RegisterContextWindowsMiniDump_x64.h"
-#else
-#include "x86/RegisterContextWindowsMiniDump_x86.h"
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-// This is a minimal implementation in order to get something running. It will
-// be fleshed out as more mini-dump functionality is added.
-
-class ThreadWinMiniDump::Data {
- public:
- Data() : m_context(nullptr) {}
- const CONTEXT *m_context;
-};
-
-ThreadWinMiniDump::ThreadWinMiniDump(lldb_private::Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_data(new Data)
-{
-}
-
-ThreadWinMiniDump::~ThreadWinMiniDump()
-{
-}
-
-void
-ThreadWinMiniDump::RefreshStateAfterStop()
-{
-}
-
-lldb::RegisterContextSP
-ThreadWinMiniDump::GetRegisterContext()
-{
- if (m_reg_context_sp.get() == NULL) {
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- }
- return m_reg_context_sp;
-}
-
-lldb::RegisterContextSP
-ThreadWinMiniDump::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
-{
- const uint32_t concrete_frame_idx = (frame) ? frame->GetConcreteFrameIndex() : 0;
- RegisterContextSP reg_ctx_sp;
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine())
- {
- case llvm::Triple::x86:
-#if defined(_WIN64)
- // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
-#else
- reg_ctx_sp.reset(new RegisterContextWindowsMiniDump_x86(*this, concrete_frame_idx, m_data->m_context));
-#endif
- break;
- case llvm::Triple::x86_64:
-#if defined(_WIN64)
- reg_ctx_sp.reset(new RegisterContextWindowsMiniDump_x64(*this, concrete_frame_idx, m_data->m_context));
-#else
- // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
-#endif
- default:
- break;
- }
- return reg_ctx_sp;
-}
-
-void
-ThreadWinMiniDump::ClearStackFrames()
-{
-}
-
-void
-ThreadWinMiniDump::SetContext(const void *context)
-{
- if (m_data)
- {
- m_data->m_context = static_cast<const CONTEXT *>(context);
- }
-}
-
-bool
-ThreadWinMiniDump::CalculateStopInfo()
-{
- return false;
-}
diff --git a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h b/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h
deleted file mode 100644
index c78925422102..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- ThreadWinMiniDump.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_ThreadWinMiniDump_h_
-#define liblldb_ThreadWinMiniDump_h_
-
-#include <string>
-
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Target/Thread.h"
-
-class ThreadWinMiniDump : public lldb_private::Thread
-{
-public:
- ThreadWinMiniDump(lldb_private::Process &process, lldb::tid_t tid);
-
- virtual
- ~ThreadWinMiniDump();
-
- void
- RefreshStateAfterStop() override;
-
- lldb::RegisterContextSP
- GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- void
- ClearStackFrames() override;
-
- void
- SetContext(const void *context);
-
-protected:
- lldb::RegisterContextSP m_reg_context_sp;
- class Data;
- std::unique_ptr<Data> m_data; // for WinAPI-specific data
-
- bool CalculateStopInfo() override;
-};
-
-#endif
diff --git a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp b/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp
deleted file mode 100644
index 41d9195f1eed..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_x64.cpp ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private-types.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "RegisterContextWindowsMiniDump_x64.h"
-
-using namespace lldb;
-
-namespace lldb_private
-{
-
-RegisterContextWindowsMiniDump_x64::RegisterContextWindowsMiniDump_x64(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context)
- : RegisterContextWindows_x64(thread, concrete_frame_idx)
-{
- if (context)
- {
- m_context = *context;
- m_context_stale = false;
- }
-}
-
-RegisterContextWindowsMiniDump_x64::~RegisterContextWindowsMiniDump_x64()
-{
-}
-
-bool
-RegisterContextWindowsMiniDump_x64::WriteRegister(const RegisterInfo * /* reg_info */, const RegisterValue & /* reg_value */)
-{
- return false;
-}
-
-bool
-RegisterContextWindowsMiniDump_x64::CacheAllRegisterValues()
-{
- // Since this is post-mortem debugging, we either have the context or we don't.
- return !m_context_stale;
-}
-
-} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h b/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h
deleted file mode 100644
index 86d58046113f..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_x64.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_RegisterContextWindowsMiniDump_x64_H_
-#define liblldb_RegisterContextWindowsMiniDump_x64_H_
-
-#include "lldb/lldb-forward.h"
-#include "Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsMiniDump_x64 : public RegisterContextWindows_x64
-{
- public:
- RegisterContextWindowsMiniDump_x64(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context);
-
- virtual ~RegisterContextWindowsMiniDump_x64();
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-
- protected:
- bool CacheAllRegisterValues() override;
-};
-
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsMiniDump_x64_H_
diff --git a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp b/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp
deleted file mode 100644
index 2c8a069c5376..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_x86.cpp ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private-types.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "RegisterContextWindowsMiniDump_x86.h"
-
-using namespace lldb;
-
-namespace lldb_private
-{
-
-RegisterContextWindowsMiniDump_x86::RegisterContextWindowsMiniDump_x86(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context)
- : RegisterContextWindows_x86(thread, concrete_frame_idx)
-{
- if (context)
- {
- m_context = *context;
- m_context_stale = false;
- }
-}
-
-RegisterContextWindowsMiniDump_x86::~RegisterContextWindowsMiniDump_x86()
-{
-}
-
-bool
-RegisterContextWindowsMiniDump_x86::WriteRegister(const RegisterInfo * /* reg_info */, const RegisterValue & /* reg_value */)
-{
- return false;
-}
-
-bool
-RegisterContextWindowsMiniDump_x86::CacheAllRegisterValues()
-{
- // Since this is post-mortem debugging, we either have the context or we don't.
- return !m_context_stale;
-}
-
-} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h b/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h
deleted file mode 100644
index d36e0cfd9e7b..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_x86.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_RegisterContextWindowsMiniDump_x86_H_
-#define liblldb_RegisterContextWindowsMiniDump_x86_H_
-
-#include "lldb/lldb-forward.h"
-#include "Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsMiniDump_x86 : public RegisterContextWindows_x86
-{
- public:
- RegisterContextWindowsMiniDump_x86(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context);
-
- virtual ~RegisterContextWindowsMiniDump_x86();
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-
- protected:
- bool CacheAllRegisterValues() override;
-};
-
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsMiniDump_x86_H_
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index a729d2beee77..6ac308fe559c 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -28,8 +28,8 @@
#include "llvm/Support/ELF.h"
-#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
// Project includes
#include "ProcessElfCore.h"
@@ -37,482 +37,443 @@
using namespace lldb_private;
-ConstString
-ProcessElfCore::GetPluginNameStatic()
-{
- static ConstString g_name("elf-core");
- return g_name;
+ConstString ProcessElfCore::GetPluginNameStatic() {
+ static ConstString g_name("elf-core");
+ return g_name;
}
-const char *
-ProcessElfCore::GetPluginDescriptionStatic()
-{
- return "ELF core dump plug-in.";
+const char *ProcessElfCore::GetPluginDescriptionStatic() {
+ return "ELF core dump plug-in.";
}
-void
-ProcessElfCore::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessElfCore::CreateInstance);
+void ProcessElfCore::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance);
}
-
-lldb::ProcessSP
-ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
-{
- lldb::ProcessSP process_sp;
- if (crash_file)
- {
- // Read enough data for a ELF32 header or ELF64 header
- const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
-
- lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size));
- if (data_sp && data_sp->GetByteSize() == header_size &&
- elf::ELFHeader::MagicBytesMatch (data_sp->GetBytes()))
- {
- elf::ELFHeader elf_header;
- DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
- lldb::offset_t data_offset = 0;
- if (elf_header.Parse(data, &data_offset))
- {
- if (elf_header.e_type == llvm::ELF::ET_CORE)
- process_sp.reset(new ProcessElfCore (target_sp, listener_sp, *crash_file));
- }
- }
+lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file) {
+ lldb::ProcessSP process_sp;
+ if (crash_file) {
+ // Read enough data for a ELF32 header or ELF64 header
+ const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
+
+ lldb::DataBufferSP data_sp(crash_file->ReadFileContents(0, header_size));
+ if (data_sp && data_sp->GetByteSize() == header_size &&
+ elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
+ elf::ELFHeader elf_header;
+ DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
+ lldb::offset_t data_offset = 0;
+ if (elf_header.Parse(data, &data_offset)) {
+ if (elf_header.e_type == llvm::ELF::ET_CORE)
+ process_sp.reset(
+ new ProcessElfCore(target_sp, listener_sp, *crash_file));
+ }
}
- return process_sp;
+ }
+ return process_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())
- {
- ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
- Error error (ModuleList::GetSharedModule (core_module_spec, m_core_module_sp,
- NULL, NULL, NULL));
- if (m_core_module_sp)
- {
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
- return true;
- }
+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()) {
+ ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
+ Error error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
+ NULL, NULL, NULL));
+ if (m_core_module_sp) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
+ return true;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// ProcessElfCore constructor
//----------------------------------------------------------------------
-ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
- const FileSpec &core_file) :
- Process (target_sp, listener_sp),
- m_core_module_sp (),
- m_core_file (core_file),
- m_dyld_plugin_name (),
- m_os(llvm::Triple::UnknownOS),
- m_thread_data_valid(false),
- m_thread_data(),
- m_core_aranges ()
-{
-}
+ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec &core_file)
+ : Process(target_sp, listener_sp), m_core_module_sp(),
+ m_core_file(core_file), m_dyld_plugin_name(),
+ m_os(llvm::Triple::UnknownOS), m_thread_data_valid(false),
+ m_thread_data(), m_core_aranges() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessElfCore::~ProcessElfCore()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
+ProcessElfCore::~ProcessElfCore() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-ConstString
-ProcessElfCore::GetPluginName()
-{
- return GetPluginNameStatic();
+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);
+
+ VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
+ if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
+ last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
+ last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
+ last_entry->SetRangeEnd(range_entry.GetRangeEnd());
+ last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
+ } else {
+ m_core_aranges.Append(range_entry);
+ }
+
+ // 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);
+
+ m_core_range_infos.Append(
+ VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
+
+ return addr;
}
-uint32_t
-ProcessElfCore::GetPluginVersion()
-{
- return 1;
-}
+//----------------------------------------------------------------------
+// Process Control
+//----------------------------------------------------------------------
+Error ProcessElfCore::DoLoadCore() {
+ Error error;
+ if (!m_core_module_sp) {
+ error.SetErrorString("invalid core module");
+ return error;
+ }
-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);
-
- VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
- if (last_entry &&
- last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
- last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
- last_entry->GetByteSize() == last_entry->data.GetByteSize())
- {
- last_entry->SetRangeEnd (range_entry.GetRangeEnd());
- last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
- }
- else
- {
- m_core_aranges.Append(range_entry);
- }
+ ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
+ if (core == NULL) {
+ error.SetErrorString("invalid core object file");
+ return error;
+ }
- // 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 : 0) |
- ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0) |
- ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0);
+ const uint32_t num_segments = core->GetProgramHeaderCount();
+ if (num_segments == 0) {
+ error.SetErrorString("core file has no segments");
+ return error;
+ }
- m_core_range_infos.Append(VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
+ SetCanJIT(false);
- return addr;
-}
+ m_thread_data_valid = true;
-//----------------------------------------------------------------------
-// Process Control
-//----------------------------------------------------------------------
-Error
-ProcessElfCore::DoLoadCore ()
-{
- Error error;
- if (!m_core_module_sp)
- {
- error.SetErrorString ("invalid core module");
- return error;
- }
+ bool ranges_are_sorted = true;
+ lldb::addr_t vm_addr = 0;
+ /// 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);
- ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
- if (core == NULL)
- {
- error.SetErrorString ("invalid core object file");
- return error;
- }
+ DataExtractor data = core->GetSegmentDataByIndex(i);
- const uint32_t num_segments = core->GetProgramHeaderCount();
- if (num_segments == 0)
- {
- error.SetErrorString ("core file has no segments");
+ // Parse thread contexts and auxv structure
+ if (header->p_type == llvm::ELF::PT_NOTE) {
+ error = ParseThreadContextsFromNoteSegment(header, data);
+ if (error.Fail())
return error;
}
-
- SetCanJIT(false);
-
- m_thread_data_valid = true;
-
- bool ranges_are_sorted = true;
- lldb::addr_t vm_addr = 0;
- /// 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);
-
- // Parse thread contexts and auxv structure
- if (header->p_type == llvm::ELF::PT_NOTE)
- ParseThreadContextsFromNoteSegment(header, data);
-
- // PT_LOAD segments contains address map
- if (header->p_type == llvm::ELF::PT_LOAD)
- {
- lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
- if (vm_addr > last_addr)
- ranges_are_sorted = false;
- vm_addr = last_addr;
- }
+ // PT_LOAD segments contains address map
+ if (header->p_type == llvm::ELF::PT_LOAD) {
+ lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
+ if (vm_addr > last_addr)
+ ranges_are_sorted = false;
+ vm_addr = last_addr;
}
-
- if (!ranges_are_sorted)
- {
- m_core_aranges.Sort();
- m_core_range_infos.Sort();
+ }
+
+ if (!ranges_are_sorted) {
+ m_core_aranges.Sort();
+ m_core_range_infos.Sort();
+ }
+
+ // Even if the architecture is set in the target, we need to override
+ // it to match the core file which is always single arch.
+ ArchSpec arch(m_core_module_sp->GetArchitecture());
+ if (arch.IsValid())
+ GetTarget().SetArchitecture(arch);
+
+ SetUnixSignals(UnixSignals::Create(GetArchitecture()));
+
+ // Ensure we found at least one thread that was stopped on a signal.
+ bool siginfo_signal_found = false;
+ bool prstatus_signal_found = false;
+ // Check we found a signal in a SIGINFO note.
+ for (const auto &thread_data: m_thread_data) {
+ if (thread_data.signo != 0)
+ siginfo_signal_found = true;
+ if (thread_data.prstatus_sig != 0)
+ prstatus_signal_found = true;
+ }
+ if (!siginfo_signal_found) {
+ // If we don't have signal from SIGINFO use the signal from each threads
+ // PRSTATUS note.
+ if (prstatus_signal_found) {
+ for (auto &thread_data: m_thread_data)
+ thread_data.signo = thread_data.prstatus_sig;
+ } else if (m_thread_data.size() > 0) {
+ // If all else fails force the first thread to be SIGSTOP
+ m_thread_data.begin()->signo =
+ GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
}
-
- // Even if the architecture is set in the target, we need to override
- // it to match the core file which is always single arch.
- ArchSpec arch (m_core_module_sp->GetArchitecture());
- if (arch.IsValid())
- GetTarget().SetArchitecture(arch);
-
- SetUnixSignals(UnixSignals::Create(GetArchitecture()));
-
- // Core files are useless without the main executable. See if we can locate the main
- // executable using data we found in the core file notes.
- lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
- if (!exe_module_sp)
- {
- // The first entry in the NT_FILE might be our executable
- if (!m_nt_file_entries.empty())
- {
- ModuleSpec exe_module_spec;
- exe_module_spec.GetArchitecture() = arch;
- exe_module_spec.GetFileSpec().SetFile(m_nt_file_entries[0].path.GetCString(), false);
- if (exe_module_spec.GetFileSpec())
- {
- exe_module_sp = GetTarget().GetSharedModule(exe_module_spec);
- if (exe_module_sp)
- GetTarget().SetExecutableModule(exe_module_sp, false);
- }
- }
+ }
+
+ // Core files are useless without the main executable. See if we can locate
+ // the main
+ // executable using data we found in the core file notes.
+ lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
+ if (!exe_module_sp) {
+ // The first entry in the NT_FILE might be our executable
+ if (!m_nt_file_entries.empty()) {
+ ModuleSpec exe_module_spec;
+ exe_module_spec.GetArchitecture() = arch;
+ exe_module_spec.GetFileSpec().SetFile(
+ m_nt_file_entries[0].path.GetCString(), false);
+ if (exe_module_spec.GetFileSpec()) {
+ exe_module_sp = GetTarget().GetSharedModule(exe_module_spec);
+ if (exe_module_sp)
+ GetTarget().SetExecutableModule(exe_module_sp, false);
+ }
}
- return error;
+ }
+ return error;
}
-lldb_private::DynamicLoader *
-ProcessElfCore::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
- return m_dyld_ap.get();
+lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(
+ this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
+ return m_dyld_ap.get();
}
-bool
-ProcessElfCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- const uint32_t num_threads = GetNumThreadContexts ();
- if (!m_thread_data_valid)
- return false;
-
- for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
- {
- const ThreadData &td = m_thread_data[tid];
- lldb::ThreadSP thread_sp(new ThreadElfCore (*this, td));
- new_thread_list.AddThread (thread_sp);
- }
- return new_thread_list.GetSize(false) > 0;
-}
+bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ const uint32_t num_threads = GetNumThreadContexts();
+ if (!m_thread_data_valid)
+ return false;
-void
-ProcessElfCore::RefreshStateAfterStop ()
-{
+ for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
+ const ThreadData &td = m_thread_data[tid];
+ lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td));
+ new_thread_list.AddThread(thread_sp);
+ }
+ return new_thread_list.GetSize(false) > 0;
}
-Error
-ProcessElfCore::DoDestroy ()
-{
- return Error();
-}
+void ProcessElfCore::RefreshStateAfterStop() {}
+
+Error ProcessElfCore::DoDestroy() { return Error(); }
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessElfCore::IsAlive ()
-{
- return true;
-}
+bool ProcessElfCore::IsAlive() { return true; }
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessElfCore::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since in core files we have it all cached our our core file anyway.
- return DoReadMemory (addr, buf, size, error);
+size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since in core files we have it all cached our our core file anyway.
+ return DoReadMemory(addr, buf, size, error);
}
-Error
-ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &region_info)
-{
- region_info.Clear();
- const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
- if (permission_entry)
- {
- if (permission_entry->Contains(load_addr))
- {
- region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
- const Flags permissions(permission_entry->data);
- region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eYes);
- }
- else if (load_addr < permission_entry->GetRangeBase())
- {
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- return Error();
+Error ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) {
+ region_info.Clear();
+ const VMRangeToPermissions::Entry *permission_entry =
+ m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+ if (permission_entry) {
+ if (permission_entry->Contains(load_addr)) {
+ region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+ const Flags permissions(permission_entry->data);
+ region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eYes);
+ } else if (load_addr < permission_entry->GetRangeBase()) {
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
}
-
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
return Error();
+ }
+
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ return Error();
}
-size_t
-ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
-
- if (core_objfile == NULL)
- return 0;
-
- // Get the address range
- const VMRangeToFileOffset::Entry *address_range = m_core_aranges.FindEntryThatContains (addr);
- if (address_range == NULL || address_range->GetRangeEnd() < addr)
- {
- error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
- return 0;
- }
-
- // Convert the address into core file offset
- const lldb::addr_t offset = addr - address_range->GetRangeBase();
- const lldb::addr_t file_start = address_range->data.GetRangeBase();
- const lldb::addr_t file_end = address_range->data.GetRangeEnd();
- size_t bytes_to_read = size; // Number of bytes to read from the core file
- size_t bytes_copied = 0; // Number of bytes actually read from the core file
- size_t zero_fill_size = 0; // Padding
- lldb::addr_t bytes_left = 0; // Number of bytes available in the core file from the given address
-
- // Figure out how many on-disk bytes remain in this segment
- // starting at the given offset
- if (file_end > file_start + offset)
- bytes_left = file_end - (file_start + offset);
-
- // Figure out how many bytes we need to zero-fill if we are
- // reading more bytes than available in the on-disk segment
- if (bytes_to_read > bytes_left)
- {
- zero_fill_size = bytes_to_read - bytes_left;
- bytes_to_read = bytes_left;
- }
-
- // If there is data available on the core file read it
- if (bytes_to_read)
- bytes_copied = core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
-
- assert(zero_fill_size <= size);
- // Pad remaining bytes
- if (zero_fill_size)
- memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
-
- return bytes_copied + zero_fill_size;
+size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+
+ if (core_objfile == NULL)
+ return 0;
+
+ // Get the address range
+ const VMRangeToFileOffset::Entry *address_range =
+ m_core_aranges.FindEntryThatContains(addr);
+ if (address_range == NULL || address_range->GetRangeEnd() < addr) {
+ error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64,
+ addr);
+ return 0;
+ }
+
+ // Convert the address into core file offset
+ const lldb::addr_t offset = addr - address_range->GetRangeBase();
+ const lldb::addr_t file_start = address_range->data.GetRangeBase();
+ const lldb::addr_t file_end = address_range->data.GetRangeEnd();
+ size_t bytes_to_read = size; // Number of bytes to read from the core file
+ size_t bytes_copied = 0; // Number of bytes actually read from the core file
+ size_t zero_fill_size = 0; // Padding
+ lldb::addr_t bytes_left =
+ 0; // Number of bytes available in the core file from the given address
+
+ // Figure out how many on-disk bytes remain in this segment
+ // starting at the given offset
+ if (file_end > file_start + offset)
+ bytes_left = file_end - (file_start + offset);
+
+ // Figure out how many bytes we need to zero-fill if we are
+ // reading more bytes than available in the on-disk segment
+ if (bytes_to_read > bytes_left) {
+ zero_fill_size = bytes_to_read - bytes_left;
+ bytes_to_read = bytes_left;
+ }
+
+ // If there is data available on the core file read it
+ if (bytes_to_read)
+ bytes_copied =
+ core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
+
+ assert(zero_fill_size <= size);
+ // Pad remaining bytes
+ if (zero_fill_size)
+ memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
+
+ return bytes_copied + zero_fill_size;
}
-void
-ProcessElfCore::Clear()
-{
- m_thread_list.Clear();
- m_os = llvm::Triple::UnknownOS;
+void ProcessElfCore::Clear() {
+ m_thread_list.Clear();
+ m_os = llvm::Triple::UnknownOS;
- SetUnixSignals(std::make_shared<UnixSignals>());
+ SetUnixSignals(std::make_shared<UnixSignals>());
}
-void
-ProcessElfCore::Initialize()
-{
- static std::once_flag g_once_flag;
+void ProcessElfCore::Initialize() {
+ static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
- });
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
}
-lldb::addr_t
-ProcessElfCore::GetImageInfoAddress()
-{
- ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(&GetTarget());
+lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
+ ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(&GetTarget());
- if (addr.IsValid())
- return addr.GetLoadAddress(&GetTarget());
- return LLDB_INVALID_ADDRESS;
+ if (addr.IsValid())
+ return addr.GetLoadAddress(&GetTarget());
+ return LLDB_INVALID_ADDRESS;
}
/// Core files PT_NOTE segment descriptor types
enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_TASKSTRUCT,
- NT_PLATFORM,
- NT_AUXV,
- NT_FILE = 0x46494c45
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_TASKSTRUCT,
+ NT_PLATFORM,
+ NT_AUXV,
+ NT_FILE = 0x46494c45,
+ NT_PRXFPREG = 0x46e62b7f,
+ NT_SIGINFO = 0x53494749,
};
namespace FREEBSD {
enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16,
- NT_PPC_VMX = 0x100
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_THRMISC = 7,
+ NT_PROCSTAT_AUXV = 16,
+ NT_PPC_VMX = 0x100
};
-
}
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
-static void
-ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
- ArchSpec &arch)
-{
- lldb::offset_t offset = 0;
- bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
- arch.GetMachine() == llvm::Triple::mips64 ||
- arch.GetMachine() == llvm::Triple::ppc64 ||
- arch.GetMachine() == llvm::Triple::x86_64);
- int pr_version = data.GetU32(&offset);
-
- Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- {
- if (pr_version > 1)
- log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
- }
-
- // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
- if (lp64)
- offset += 32;
- else
- offset += 16;
-
- thread_data.signo = data.GetU32(&offset); // pr_cursig
- thread_data.tid = data.GetU32(&offset); // pr_pid
- if (lp64)
- offset += 4;
-
- size_t len = data.GetByteSize() - offset;
- thread_data.gpregset = DataExtractor(data, offset, len);
+static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
+ ArchSpec &arch) {
+ lldb::offset_t offset = 0;
+ bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
+ arch.GetMachine() == llvm::Triple::mips64 ||
+ arch.GetMachine() == llvm::Triple::ppc64 ||
+ arch.GetMachine() == llvm::Triple::x86_64);
+ int pr_version = data.GetU32(&offset);
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ if (pr_version > 1)
+ log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
+ }
+
+ // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
+ if (lp64)
+ offset += 32;
+ else
+ offset += 16;
+
+ thread_data.signo = data.GetU32(&offset); // pr_cursig
+ thread_data.tid = data.GetU32(&offset); // pr_pid
+ if (lp64)
+ offset += 4;
+
+ size_t len = data.GetByteSize() - offset;
+ thread_data.gpregset = DataExtractor(data, offset, len);
}
-static void
-ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data)
-{
- lldb::offset_t offset = 0;
- thread_data.name = data.GetCStr(&offset, 20);
+static void ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) {
+ lldb::offset_t offset = 0;
+ thread_data.name = data.GetCStr(&offset, 20);
}
/// Parse Thread context from PT_NOTE segment and store it in the thread list
@@ -525,183 +486,189 @@ ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data)
/// b) NT_PRPSINFO - Process info(pid..)
/// c) NT_FPREGSET - Floating point registers
/// 4) The NOTE entries can be in any order
-/// 5) If a core file contains multiple thread contexts then there is two data forms
-/// a) Each thread context(2 or more NOTE entries) contained in its own segment (PT_NOTE)
+/// 5) If a core file contains multiple thread contexts then there is two data
+/// forms
+/// a) Each thread context(2 or more NOTE entries) contained in its own
+/// segment (PT_NOTE)
/// b) All thread context is stored in a single segment(PT_NOTE).
-/// This case is little tricker since while parsing we have to find where the
+/// This case is little tricker since while parsing we have to find where
+/// the
/// new thread starts. The current implementation marks beginning of
/// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
/// For case (b) there may be either one NT_PRPSINFO per thread, or a single
/// one that applies to all threads (depending on the platform type).
-void
-ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *segment_header,
- DataExtractor segment_data)
-{
- assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
-
- lldb::offset_t offset = 0;
- std::unique_ptr<ThreadData> thread_data(new ThreadData);
- bool have_prstatus = false;
- bool have_prpsinfo = false;
-
- ArchSpec arch = GetArchitecture();
- ELFLinuxPrPsInfo prpsinfo;
- ELFLinuxPrStatus prstatus;
- size_t header_size;
- size_t len;
-
- // Loop through the NOTE entires in the segment
- while (offset < segment_header->p_filesz)
- {
- ELFNote note = ELFNote();
- note.Parse(segment_data, &offset);
-
- // Beginning of new thread
- if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
- (note.n_type == NT_PRPSINFO && have_prpsinfo))
- {
- assert(thread_data->gpregset.GetByteSize() > 0);
- // Add the new thread to thread list
- m_thread_data.push_back(*thread_data);
- *thread_data = ThreadData();
- have_prstatus = false;
- have_prpsinfo = false;
- }
+Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
+ const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
+ assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
+
+ lldb::offset_t offset = 0;
+ std::unique_ptr<ThreadData> thread_data(new ThreadData);
+ bool have_prstatus = false;
+ bool have_prpsinfo = false;
+
+ ArchSpec arch = GetArchitecture();
+ ELFLinuxPrPsInfo prpsinfo;
+ ELFLinuxPrStatus prstatus;
+ ELFLinuxSigInfo siginfo;
+ size_t header_size;
+ size_t len;
+ Error error;
+
+ // Loop through the NOTE entires in the segment
+ while (offset < segment_header->p_filesz) {
+ ELFNote note = ELFNote();
+ note.Parse(segment_data, &offset);
+
+ // Beginning of new thread
+ if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
+ (note.n_type == NT_PRPSINFO && have_prpsinfo)) {
+ assert(thread_data->gpregset.GetByteSize() > 0);
+ // Add the new thread to thread list
+ m_thread_data.push_back(*thread_data);
+ *thread_data = ThreadData();
+ have_prstatus = false;
+ have_prpsinfo = false;
+ }
- size_t note_start, note_size;
- note_start = offset;
- note_size = llvm::alignTo(note.n_descsz, 4);
-
- // Store the NOTE information in the current thread
- DataExtractor note_data (segment_data, note_start, note_size);
- note_data.SetAddressByteSize(m_core_module_sp->GetArchitecture().GetAddressByteSize());
- if (note.n_name == "FreeBSD")
- {
- m_os = llvm::Triple::FreeBSD;
- switch (note.n_type)
- {
- case FREEBSD::NT_PRSTATUS:
- have_prstatus = true;
- ParseFreeBSDPrStatus(*thread_data, note_data, arch);
- break;
- case FREEBSD::NT_FPREGSET:
- thread_data->fpregset = note_data;
- break;
- case FREEBSD::NT_PRPSINFO:
- have_prpsinfo = true;
- break;
- case FREEBSD::NT_THRMISC:
- ParseFreeBSDThrMisc(*thread_data, note_data);
- break;
- case FREEBSD::NT_PROCSTAT_AUXV:
- // FIXME: FreeBSD sticks an int at the beginning of the note
- m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
- break;
- case FREEBSD::NT_PPC_VMX:
- thread_data->vregset = note_data;
- break;
- default:
- break;
- }
+ size_t note_start, note_size;
+ note_start = offset;
+ note_size = llvm::alignTo(note.n_descsz, 4);
+
+ // Store the NOTE information in the current thread
+ DataExtractor note_data(segment_data, note_start, note_size);
+ note_data.SetAddressByteSize(
+ m_core_module_sp->GetArchitecture().GetAddressByteSize());
+ if (note.n_name == "FreeBSD") {
+ m_os = llvm::Triple::FreeBSD;
+ switch (note.n_type) {
+ case FREEBSD::NT_PRSTATUS:
+ have_prstatus = true;
+ ParseFreeBSDPrStatus(*thread_data, note_data, arch);
+ break;
+ case FREEBSD::NT_FPREGSET:
+ thread_data->fpregset = note_data;
+ break;
+ case FREEBSD::NT_PRPSINFO:
+ have_prpsinfo = true;
+ break;
+ case FREEBSD::NT_THRMISC:
+ ParseFreeBSDThrMisc(*thread_data, note_data);
+ break;
+ case FREEBSD::NT_PROCSTAT_AUXV:
+ // FIXME: FreeBSD sticks an int at the beginning of the note
+ m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
+ break;
+ case FREEBSD::NT_PPC_VMX:
+ thread_data->vregset = note_data;
+ break;
+ default:
+ break;
+ }
+ } else if (note.n_name == "CORE") {
+ switch (note.n_type) {
+ case NT_PRSTATUS:
+ have_prstatus = true;
+ error = prstatus.Parse(note_data, arch);
+ if (error.Fail())
+ return error;
+ thread_data->prstatus_sig = prstatus.pr_cursig;
+ thread_data->tid = prstatus.pr_pid;
+ header_size = ELFLinuxPrStatus::GetSize(arch);
+ len = note_data.GetByteSize() - header_size;
+ thread_data->gpregset = DataExtractor(note_data, header_size, len);
+ break;
+ case NT_FPREGSET:
+ // In a i386 core file NT_FPREGSET is present, but it's not the result
+ // of the FXSAVE instruction like in 64 bit files.
+ // The result from FXSAVE is in NT_PRXFPREG for i386 core files
+ if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64)
+ thread_data->fpregset = note_data;
+ break;
+ case NT_PRPSINFO:
+ have_prpsinfo = true;
+ error = prpsinfo.Parse(note_data, arch);
+ if (error.Fail())
+ return error;
+ thread_data->name = prpsinfo.pr_fname;
+ SetID(prpsinfo.pr_pid);
+ break;
+ case NT_AUXV:
+ m_auxv = DataExtractor(note_data);
+ break;
+ case NT_FILE: {
+ m_nt_file_entries.clear();
+ lldb::offset_t offset = 0;
+ const uint64_t count = note_data.GetAddress(&offset);
+ note_data.GetAddress(&offset); // Skip page size
+ for (uint64_t i = 0; i < count; ++i) {
+ NT_FILE_Entry entry;
+ entry.start = note_data.GetAddress(&offset);
+ entry.end = note_data.GetAddress(&offset);
+ entry.file_ofs = note_data.GetAddress(&offset);
+ m_nt_file_entries.push_back(entry);
}
- else if (note.n_name == "CORE")
- {
- switch (note.n_type)
- {
- case NT_PRSTATUS:
- have_prstatus = true;
- prstatus.Parse(note_data, arch);
- thread_data->signo = prstatus.pr_cursig;
- thread_data->tid = prstatus.pr_pid;
- header_size = ELFLinuxPrStatus::GetSize(arch);
- len = note_data.GetByteSize() - header_size;
- thread_data->gpregset = DataExtractor(note_data, header_size, len);
- break;
- case NT_FPREGSET:
- thread_data->fpregset = note_data;
- break;
- case NT_PRPSINFO:
- have_prpsinfo = true;
- prpsinfo.Parse(note_data, arch);
- thread_data->name = prpsinfo.pr_fname;
- SetID(prpsinfo.pr_pid);
- break;
- case NT_AUXV:
- m_auxv = DataExtractor(note_data);
- break;
- case NT_FILE:
- {
- m_nt_file_entries.clear();
- lldb::offset_t offset = 0;
- const uint64_t count = note_data.GetAddress(&offset);
- note_data.GetAddress(&offset); // Skip page size
- for (uint64_t i = 0; i<count; ++i)
- {
- NT_FILE_Entry entry;
- entry.start = note_data.GetAddress(&offset);
- entry.end = note_data.GetAddress(&offset);
- entry.file_ofs = note_data.GetAddress(&offset);
- m_nt_file_entries.push_back(entry);
- }
- for (uint64_t i = 0; i<count; ++i)
- {
- const char *path = note_data.GetCStr(&offset);
- if (path && path[0])
- m_nt_file_entries[i].path.SetCString(path);
- }
- }
- break;
- default:
- break;
- }
+ for (uint64_t i = 0; i < count; ++i) {
+ const char *path = note_data.GetCStr(&offset);
+ if (path && path[0])
+ m_nt_file_entries[i].path.SetCString(path);
}
-
- offset += note_size;
- }
- // Add last entry in the note section
- if (thread_data && thread_data->gpregset.GetByteSize() > 0)
- {
- m_thread_data.push_back(*thread_data);
+ } break;
+ case NT_SIGINFO: {
+ error = siginfo.Parse(note_data, arch);
+ if (error.Fail())
+ return error;
+ thread_data->signo = siginfo.si_signo;
+ } break;
+ default:
+ break;
+ }
+ } else if (note.n_name == "LINUX") {
+ switch (note.n_type) {
+ case NT_PRXFPREG:
+ thread_data->fpregset = note_data;
+ }
}
+
+ offset += note_size;
+ }
+ // Add last entry in the note section
+ if (thread_data && thread_data->gpregset.GetByteSize() > 0) {
+ m_thread_data.push_back(*thread_data);
+ }
+
+ return error;
}
-uint32_t
-ProcessElfCore::GetNumThreadContexts ()
-{
- if (!m_thread_data_valid)
- DoLoadCore();
- return m_thread_data.size();
+uint32_t ProcessElfCore::GetNumThreadContexts() {
+ if (!m_thread_data_valid)
+ DoLoadCore();
+ return m_thread_data.size();
}
-ArchSpec
-ProcessElfCore::GetArchitecture()
-{
- ObjectFileELF *core_file = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
- ArchSpec arch;
- core_file->GetArchitecture(arch);
- return arch;
+ArchSpec ProcessElfCore::GetArchitecture() {
+ ObjectFileELF *core_file =
+ (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
+ ArchSpec arch;
+ core_file->GetArchitecture(arch);
+ return arch;
}
-const lldb::DataBufferSP
-ProcessElfCore::GetAuxvData()
-{
- const uint8_t *start = m_auxv.GetDataStart();
- size_t len = m_auxv.GetByteSize();
- lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
- return buffer;
+const lldb::DataBufferSP ProcessElfCore::GetAuxvData() {
+ const uint8_t *start = m_auxv.GetDataStart();
+ size_t len = m_auxv.GetByteSize();
+ lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
+ return buffer;
}
-bool
-ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info)
-{
- info.Clear();
- info.SetProcessID(GetID());
- info.SetArchitecture(GetArchitecture());
- lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
- if (module_sp)
- {
- const bool add_exe_file_as_first_arg = false;
- info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), add_exe_file_as_first_arg);
- }
- return true;
+bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
+ info.Clear();
+ info.SetProcessID(GetID());
+ info.SetArchitecture(GetArchitecture());
+ lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+ if (module_sp) {
+ const bool add_exe_file_as_first_arg = false;
+ info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
+ add_exe_file_as_first_arg);
+ }
+ return true;
}
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h
index 4bcbb363d3f8..a8dde47b3079 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -32,151 +32,144 @@
struct ThreadData;
-class ProcessElfCore : public lldb_private::Process
-{
+class ProcessElfCore : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec *crash_file_path);
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ProcessElfCore(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec &core_file);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec &core_file);
- ~ProcessElfCore() override;
+ ~ProcessElfCore() override;
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- lldb_private::Error DoLoadCore() override;
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ lldb_private::Error DoLoadCore() override;
- lldb_private::DynamicLoader *GetDynamicLoader() override;
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- lldb_private::Error DoDestroy() override;
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ lldb_private::Error DoDestroy() override;
- void RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool IsAlive() override;
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
- size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
- lldb_private::Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
+ lldb_private::Error
+ GetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
- lldb::addr_t GetImageInfoAddress() override;
+ lldb::addr_t GetImageInfoAddress() override;
- lldb_private::ArchSpec
- GetArchitecture();
+ lldb_private::ArchSpec GetArchitecture();
- // Returns AUXV structure found in the core file
- const lldb::DataBufferSP
- GetAuxvData() override;
+ // Returns AUXV structure found in the core file
+ const lldb::DataBufferSP GetAuxvData() override;
- bool
- GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
+ bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
protected:
- void
- Clear ( );
+ void Clear();
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
private:
- struct NT_FILE_Entry
- {
- lldb::addr_t start;
- lldb::addr_t end;
- lldb::addr_t file_ofs;
- lldb_private::ConstString path;
- };
-
- //------------------------------------------------------------------
- // 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> VMRangeToFileOffset;
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions;
-
- lldb::ModuleSP m_core_module_sp;
- lldb_private::FileSpec m_core_file;
- std::string m_dyld_plugin_name;
- DISALLOW_COPY_AND_ASSIGN (ProcessElfCore);
-
- llvm::Triple::OSType m_os;
-
- // True if m_thread_contexts contains valid entries
- bool m_thread_data_valid;
-
- // Contain thread data read from NOTE segments
- std::vector<ThreadData> m_thread_data;
-
- // AUXV structure found from the NOTE segment
- lldb_private::DataExtractor m_auxv;
-
- // Address ranges found in the core
- VMRangeToFileOffset m_core_aranges;
-
- // Permissions for all ranges
- VMRangeToPermissions m_core_range_infos;
-
- // NT_FILE entries found from the NOTE segment
- std::vector<NT_FILE_Entry> m_nt_file_entries;
-
- // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
- void
- ParseThreadContextsFromNoteSegment (const elf::ELFProgramHeader *segment_header,
- lldb_private::DataExtractor segment_data);
-
- // Returns number of thread contexts stored in the core file
- uint32_t
- GetNumThreadContexts();
-
- // Parse a contiguous address range of the process from LOAD segment
- lldb::addr_t
- AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
+ struct NT_FILE_Entry {
+ lldb::addr_t start;
+ lldb::addr_t end;
+ lldb::addr_t file_ofs;
+ lldb_private::ConstString path;
+ };
+
+ //------------------------------------------------------------------
+ // 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>
+ VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
+ VMRangeToPermissions;
+
+ lldb::ModuleSP m_core_module_sp;
+ lldb_private::FileSpec m_core_file;
+ std::string m_dyld_plugin_name;
+ DISALLOW_COPY_AND_ASSIGN(ProcessElfCore);
+
+ llvm::Triple::OSType m_os;
+
+ // True if m_thread_contexts contains valid entries
+ bool m_thread_data_valid;
+
+ // Contain thread data read from NOTE segments
+ std::vector<ThreadData> m_thread_data;
+
+ // AUXV structure found from the NOTE segment
+ lldb_private::DataExtractor m_auxv;
+
+ // Address ranges found in the core
+ VMRangeToFileOffset m_core_aranges;
+
+ // Permissions for all ranges
+ VMRangeToPermissions m_core_range_infos;
+
+ // NT_FILE entries found from the NOTE segment
+ std::vector<NT_FILE_Entry> m_nt_file_entries;
+
+ // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
+ lldb_private::Error ParseThreadContextsFromNoteSegment(
+ const elf::ELFProgramHeader *segment_header,
+ lldb_private::DataExtractor segment_data);
+
+ // Returns number of thread contexts stored in the core file
+ uint32_t GetNumThreadContexts();
+
+ // Parse a contiguous address range of the process from LOAD segment
+ lldb::addr_t
+ AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
};
#endif // liblldb_ProcessElfCore_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 6778aeaaac00..81d88e69b97f 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,87 +7,65 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_arm.h"
+
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_arm.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_arm(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
+RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_arm(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm()
-{
-}
+RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() {}
-bool
-RegisterContextCorePOSIX_arm::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_arm::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_arm::ReadFPR()
-{
- return false;
-}
+bool RegisterContextCorePOSIX_arm::ReadFPR() { return false; }
-bool
-RegisterContextCorePOSIX_arm::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- return false;
+bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
index 0e74897b5b5c..c0850e5e414e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm.h --------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm.h --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,53 +14,44 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_arm :
- public RegisterContextPOSIX_arm
-{
+class RegisterContextCorePOSIX_arm : public RegisterContextPOSIX_arm {
public:
- RegisterContextCorePOSIX_arm (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_arm(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_arm() override;
+ ~RegisterContextCorePOSIX_arm() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
};
#endif // liblldb_RegisterContextCorePOSIX_arm_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 7cfdd415ad5b..41c02bf94c37 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm64.cpp ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,87 +7,65 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_arm64.h"
+
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_arm64.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_arm64(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
+RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_arm64(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64()
-{
-}
+RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {}
-bool
-RegisterContextCorePOSIX_arm64::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_arm64::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_arm64::ReadFPR()
-{
- return false;
-}
+bool RegisterContextCorePOSIX_arm64::ReadFPR() { return false; }
-bool
-RegisterContextCorePOSIX_arm64::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- return false;
+bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 9b05edb1935f..da3e5bff605c 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm64.h ------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm64.h ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,53 +14,44 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_arm64 :
- public RegisterContextPOSIX_arm64
-{
+class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
public:
- RegisterContextCorePOSIX_arm64 (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_arm64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_arm64() override;
+ ~RegisterContextCorePOSIX_arm64() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
};
#endif // liblldb_RegisterContextCorePOSIX_arm64_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index 9d908e371a32..6a168d314fd7 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_mips64.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_mips64.cpp ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,87 +7,65 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_mips64.h"
+
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_mips64.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_mips64(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
+RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_mips64(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64()
-{
-}
+RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {}
-bool
-RegisterContextCorePOSIX_mips64::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_mips64::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_mips64::ReadFPR()
-{
- return false;
-}
+bool RegisterContextCorePOSIX_mips64::ReadFPR() { return false; }
-bool
-RegisterContextCorePOSIX_mips64::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- return false;
+bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
index 6cbfd504b7db..b1deca3d3178 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_mips64.h -----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_mips64.h -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,53 +14,44 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_mips64 :
- public RegisterContextPOSIX_mips64
-{
+class RegisterContextCorePOSIX_mips64 : public RegisterContextPOSIX_mips64 {
public:
- RegisterContextCorePOSIX_mips64 (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_mips64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_mips64() override;
+ ~RegisterContextCorePOSIX_mips64() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
};
#endif // liblldb_RegisterContextCorePOSIX_mips64_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 9d8c97849ff8..edfa1902c327 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_powerpc.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_powerpc.cpp --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,127 +7,100 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_powerpc.h"
+
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_powerpc.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset,
- const DataExtractor &vregset)
- : RegisterContextPOSIX_powerpc(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
- m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
- m_fpr.SetData(m_fpr_buffer);
- m_fpr.SetByteOrder(fpregset.GetByteOrder());
- m_vec_buffer.reset(new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
- m_vec.SetData(m_vec_buffer);
- m_vec.SetByteOrder(fpregset.GetByteOrder());
+RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset,
+ const DataExtractor &vregset)
+ : RegisterContextPOSIX_powerpc(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+ m_fpr_buffer.reset(
+ new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+ m_fpr.SetData(m_fpr_buffer);
+ m_fpr.SetByteOrder(fpregset.GetByteOrder());
+ m_vec_buffer.reset(
+ new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
+ m_vec.SetData(m_vec_buffer);
+ m_vec.SetByteOrder(vregset.GetByteOrder());
}
-RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc()
-{
-}
+RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() {}
-bool
-RegisterContextCorePOSIX_powerpc::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_powerpc::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_powerpc::ReadFPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_powerpc::ReadFPR() { return true; }
-bool
-RegisterContextCorePOSIX_powerpc::ReadVMX()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_powerpc::ReadVMX() { return true; }
-bool
-RegisterContextCorePOSIX_powerpc::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteVMX()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteVMX() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
- uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
- uint32_t v[4];
- offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
- if (offset == reg_info->byte_size)
- {
- value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
- return true;
- }
- } else {
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- if (reg_info->byte_size < sizeof(v))
- value = (uint32_t)v;
- else
- value = v;
- return true;
- }
+bool RegisterContextCorePOSIX_powerpc::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
+ return true;
+ }
+ } else {
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ if (reg_info->byte_size < sizeof(v))
+ value = (uint32_t)v;
+ else
+ value = v;
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
index 0f587fd1459c..8e6315f06636 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_powerpc.h ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_powerpc.h ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,64 +14,52 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_powerpc :
- public RegisterContextPOSIX_powerpc
-{
+class RegisterContextCorePOSIX_powerpc : public RegisterContextPOSIX_powerpc {
public:
- RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset,
- const lldb_private::DataExtractor &vregset);
+ RegisterContextCorePOSIX_powerpc(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset,
+ const lldb_private::DataExtractor &vregset);
- ~RegisterContextCorePOSIX_powerpc() override;
+ ~RegisterContextCorePOSIX_powerpc() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- ReadVMX() override;
+ bool ReadVMX() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
- bool
- WriteVMX() override;
+ bool WriteVMX() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb::DataBufferSP m_fpr_buffer;
- lldb::DataBufferSP m_vec_buffer;
- lldb_private::DataExtractor m_gpr;
- lldb_private::DataExtractor m_fpr;
- lldb_private::DataExtractor m_vec;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb::DataBufferSP m_fpr_buffer;
+ lldb::DataBufferSP m_vec_buffer;
+ lldb_private::DataExtractor m_gpr;
+ lldb_private::DataExtractor m_fpr;
+ lldb_private::DataExtractor m_vec;
};
#endif // liblldb_RegisterContextCorePOSIX_powerpc_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index d2f0a8dd3671..6db817789612 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_s390x.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_s390x.cpp ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,109 +7,87 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_s390x.h"
+
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_s390x.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_s390x(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
-
- m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
- m_fpr.SetData(m_fpr_buffer);
- m_fpr.SetByteOrder(fpregset.GetByteOrder());
+RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_s390x(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ m_fpr_buffer.reset(
+ new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+ m_fpr.SetData(m_fpr_buffer);
+ m_fpr.SetByteOrder(fpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x()
-{
-}
+RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() {}
-bool
-RegisterContextCorePOSIX_s390x::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_s390x::ReadGPR() { return true; }
+
+bool RegisterContextCorePOSIX_s390x::ReadFPR() { return true; }
-bool
-RegisterContextCorePOSIX_s390x::ReadFPR()
-{
- return true;
+bool RegisterContextCorePOSIX_s390x::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_s390x::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteFPR()
-{
- assert(0);
+bool RegisterContextCorePOSIX_s390x::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
return false;
-}
-bool
-RegisterContextCorePOSIX_s390x::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return false;
-
- if (IsGPR(reg))
- {
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value.SetUInt(v, reg_info->byte_size);
- return true;
- }
+ if (IsGPR(reg)) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value.SetUInt(v, reg_info->byte_size);
+ return true;
}
-
- if (IsFPR(reg))
- {
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value.SetUInt(v, reg_info->byte_size);
- return true;
- }
+ }
+
+ if (IsFPR(reg)) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value.SetUInt(v, reg_info->byte_size);
+ return true;
}
+ }
- return false;
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
index 8bb6fe1771ef..516e5c57e2b9 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_s390x.h ------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_s390x.h ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,52 +14,46 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x
-{
+class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x {
public:
- RegisterContextCorePOSIX_s390x(lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_s390x(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_s390x() override;
+ ~RegisterContextCorePOSIX_s390x() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
- lldb::DataBufferSP m_fpr_buffer;
- lldb_private::DataExtractor m_fpr;
+ lldb::DataBufferSP m_fpr_buffer;
+ lldb_private::DataExtractor m_fpr;
};
#endif // liblldb_RegisterContextCorePOSIX_s390x_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
index 926c7aff3603..7f8223f7752e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_x86_64.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_x86_64.cpp ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,93 +7,92 @@
//
//===----------------------------------------------------------------------===//
+#include "RegisterContextPOSIXCore_x86_64.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_x86_64.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_x86 (thread, 0, register_info)
-{
- size_t size, len;
-
- size = GetGPRSize();
- m_gpregset = new uint8_t[size];
- len = gpregset.ExtractBytes (0, size, lldb::eByteOrderLittle, m_gpregset);
- assert(len == size);
-}
+RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_x86(thread, 0, register_info) {
+ size_t size, len;
+
+ size = GetGPRSize();
+ m_gpregset.reset(new uint8_t[size]);
+ len =
+ gpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_gpregset.get());
+ if (len != size)
+ m_gpregset.reset();
-RegisterContextCorePOSIX_x86_64::~RegisterContextCorePOSIX_x86_64()
-{
- delete [] m_gpregset;
+ size = sizeof(FXSAVE);
+ m_fpregset.reset(new uint8_t[size]);
+ len =
+ fpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_fpregset.get());
+ if (len != size)
+ m_fpregset.reset();
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadGPR()
-{
- return m_gpregset != NULL;
+bool RegisterContextCorePOSIX_x86_64::ReadGPR() {
+ return m_gpregset != nullptr;
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadFPR()
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::ReadFPR() {
+ return m_fpregset != nullptr;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- switch (reg_info->byte_size)
- {
- case 4:
- value = *(uint32_t *)(m_gpregset + reg_info->byte_offset);
- return true;
- case 8:
- value = *(uint64_t *)(m_gpregset + reg_info->byte_offset);
- return true;
- }
+bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint8_t *src;
+ size_t offset;
+ const size_t fxsave_offset = reg_info->byte_offset - GetFXSAVEOffset();
+ // make the offset relative to the beginning of the FXSAVE structure
+ // because this is the data that we have (not the entire UserArea)
+
+ if (m_gpregset && reg_info->byte_offset < GetGPRSize()) {
+ src = m_gpregset.get();
+ offset = reg_info->byte_offset;
+ } else if (m_fpregset && fxsave_offset < sizeof(FXSAVE)) {
+ src = m_fpregset.get();
+ offset = fxsave_offset;
+ } else {
return false;
+ }
+
+ Error error;
+ value.SetFromMemoryData(reg_info, src + offset, reg_info->byte_size,
+ lldb::eByteOrderLittle, error);
+
+ return error.Success();
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
index 60f2ad33b4a5..8340368f8c3c 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_x86_64.h -----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_x86_64.h -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,49 +16,38 @@
// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
-class RegisterContextCorePOSIX_x86_64 :
- public RegisterContextPOSIX_x86
-{
+class RegisterContextCorePOSIX_x86_64 : public RegisterContextPOSIX_x86 {
public:
- RegisterContextCorePOSIX_x86_64 (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_x86_64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_x86_64() override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- uint8_t *m_gpregset;
+ std::unique_ptr<uint8_t[]> m_gpregset;
+ std::unique_ptr<uint8_t[]> m_fpregset;
};
#endif // liblldb_RegisterContextCorePOSIX_x86_64_h_
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index e4cfa68044f1..86b15c0d2fbe 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -14,24 +14,24 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
-#include "ThreadElfCore.h"
-#include "ProcessElfCore.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "ProcessElfCore.h"
#include "RegisterContextPOSIXCore_arm.h"
#include "RegisterContextPOSIXCore_arm64.h"
#include "RegisterContextPOSIXCore_mips64.h"
#include "RegisterContextPOSIXCore_powerpc.h"
#include "RegisterContextPOSIXCore_s390x.h"
#include "RegisterContextPOSIXCore_x86_64.h"
+#include "ThreadElfCore.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,223 +39,325 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Construct a Thread object with given data
//----------------------------------------------------------------------
-ThreadElfCore::ThreadElfCore (Process &process, const ThreadData &td) :
- Thread(process, td.tid),
- m_thread_name(td.name),
- m_thread_reg_ctx_sp (),
- m_signo(td.signo),
- m_gpregset_data(td.gpregset),
- m_fpregset_data(td.fpregset),
- m_vregset_data(td.vregset)
-{
-}
+ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
+ : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
+ m_signo(td.signo), m_gpregset_data(td.gpregset),
+ m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
-ThreadElfCore::~ThreadElfCore ()
-{
- DestroyThread();
+ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
+
+void ThreadElfCore::RefreshStateAfterStop() {
+ GetRegisterContext()->InvalidateIfNeeded(false);
}
-void
-ThreadElfCore::RefreshStateAfterStop()
-{
- GetRegisterContext()->InvalidateIfNeeded (false);
+void ThreadElfCore::ClearStackFrames() {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ unwinder->Clear();
+ Thread::ClearStackFrames();
}
-void
-ThreadElfCore::ClearStackFrames ()
-{
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- unwinder->Clear();
- Thread::ClearStackFrames();
+RegisterContextSP ThreadElfCore::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL) {
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ }
+ return m_reg_context_sp;
}
RegisterContextSP
-ThreadElfCore::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL) {
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
+ThreadElfCore::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();
+
+ if (concrete_frame_idx == 0) {
+ if (m_thread_reg_ctx_sp)
+ return m_thread_reg_ctx_sp;
+
+ ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
+ ArchSpec arch = process->GetArchitecture();
+ RegisterInfoInterface *reg_interface = NULL;
+
+ switch (arch.GetTriple().getOS()) {
+ case llvm::Triple::FreeBSD: {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(arch);
+ break;
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextFreeBSD_arm(arch);
+ break;
+ case llvm::Triple::ppc:
+ reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
+ break;
+ case llvm::Triple::ppc64:
+ reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
+ break;
+ case llvm::Triple::mips64:
+ reg_interface = new RegisterContextFreeBSD_mips64(arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextFreeBSD_i386(arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextFreeBSD_x86_64(arch);
+ break;
+ default:
+ break;
+ }
+ break;
}
- return m_reg_context_sp;
-}
-RegisterContextSP
-ThreadElfCore::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 ();
-
- if (concrete_frame_idx == 0)
- {
- if (m_thread_reg_ctx_sp)
- return m_thread_reg_ctx_sp;
-
- ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
- ArchSpec arch = process->GetArchitecture();
- RegisterInfoInterface *reg_interface = NULL;
-
- switch (arch.GetTriple().getOS())
- {
- case llvm::Triple::FreeBSD:
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextFreeBSD_arm64(arch);
- break;
- case llvm::Triple::arm:
- reg_interface = new RegisterContextFreeBSD_arm(arch);
- break;
- case llvm::Triple::ppc:
- reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
- break;
- case llvm::Triple::ppc64:
- reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
- break;
- case llvm::Triple::mips64:
- reg_interface = new RegisterContextFreeBSD_mips64(arch);
- break;
- case llvm::Triple::x86:
- reg_interface = new RegisterContextFreeBSD_i386(arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextFreeBSD_x86_64(arch);
- break;
- default:
- break;
- }
- break;
- }
-
- case llvm::Triple::Linux:
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::arm:
- reg_interface = new RegisterContextLinux_arm(arch);
- break;
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextLinux_arm64(arch);
- break;
- case llvm::Triple::systemz:
- reg_interface = new RegisterContextLinux_s390x(arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextLinux_x86_64(arch);
- break;
- default:
- break;
- }
- break;
- }
-
- default:
- break;
- }
-
- if (!reg_interface) {
- if (log)
- log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
- __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
- assert (false && "Architecture or OS not supported");
- }
-
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::arm:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::mips64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
- break;
- case llvm::Triple::systemz:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- default:
- break;
- }
-
- reg_ctx_sp = m_thread_reg_ctx_sp;
+ case llvm::Triple::Linux: {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextLinux_arm(arch);
+ break;
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(arch);
+ break;
+ case llvm::Triple::systemz:
+ reg_interface = new RegisterContextLinux_s390x(arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextLinux_i386(arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextLinux_x86_64(arch);
+ break;
+ default:
+ break;
+ }
+ break;
}
- else if (m_unwinder_ap.get())
- {
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+
+ default:
+ break;
}
- return reg_ctx_sp;
-}
-bool
-ThreadElfCore::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
- return true;
+ if (!reg_interface) {
+ if (log)
+ log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
+ __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
+ assert(false && "Architecture or OS not supported");
}
- return false;
+
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::arm:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::mips64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data,
+ m_vregset_data));
+ break;
+ case llvm::Triple::systemz:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ default:
+ break;
+ }
+
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else if (m_unwinder_ap.get()) {
+ reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
+}
+
+bool ThreadElfCore::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
+ return true;
+ }
+ return false;
}
//----------------------------------------------------------------
// Parse PRSTATUS from NOTE entry
//----------------------------------------------------------------
-ELFLinuxPrStatus::ELFLinuxPrStatus()
-{
- memset(this, 0, sizeof(ELFLinuxPrStatus));
+ELFLinuxPrStatus::ELFLinuxPrStatus() {
+ memset(this, 0, sizeof(ELFLinuxPrStatus));
}
-bool
-ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
-{
- ByteOrder byteorder = data.GetByteOrder();
- size_t len;
- switch(arch.GetCore())
- {
- case ArchSpec::eCore_s390x_generic:
- case ArchSpec::eCore_x86_64_x86_64:
- len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
- return len == ELFLINUXPRSTATUS64_SIZE;
- default:
- return false;
- }
+Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
+ break;
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ offset_t offset = 0;
+ si_signo = data.GetU32(&offset);
+ si_code = data.GetU32(&offset);
+ si_errno = data.GetU32(&offset);
+
+ pr_cursig = data.GetU16(&offset);
+ offset += 2; // pad
+
+ pr_sigpend = data.GetU32(&offset);
+ pr_sighold = data.GetU32(&offset);
+
+ pr_pid = data.GetU32(&offset);
+ pr_ppid = data.GetU32(&offset);
+ pr_pgrp = data.GetU32(&offset);
+ pr_sid = data.GetU32(&offset);
+
+ pr_utime.tv_sec = data.GetU32(&offset);
+ pr_utime.tv_usec = data.GetU32(&offset);
+
+ pr_stime.tv_sec = data.GetU32(&offset);
+ pr_stime.tv_usec = data.GetU32(&offset);
+
+ pr_cutime.tv_sec = data.GetU32(&offset);
+ pr_cutime.tv_usec = data.GetU32(&offset);
+
+ pr_cstime.tv_sec = data.GetU32(&offset);
+ pr_cstime.tv_usec = data.GetU32(&offset);
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxPrStatus::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
}
//----------------------------------------------------------------
// Parse PRPSINFO from NOTE entry
//----------------------------------------------------------------
-ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
-{
- memset(this, 0, sizeof(ELFLinuxPrPsInfo));
+ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
+ memset(this, 0, sizeof(ELFLinuxPrPsInfo));
}
-bool
-ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
-{
- ByteOrder byteorder = data.GetByteOrder();
- size_t len;
- switch(arch.GetCore())
- {
- case ArchSpec::eCore_s390x_generic:
- case ArchSpec::eCore_x86_64_x86_64:
- len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
- return len == ELFLINUXPRPSINFO64_SIZE;
- default:
- return false;
- }
+Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrPsInfo), byteorder, this);
+ break;
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ size_t size = 0;
+ offset_t offset = 0;
+
+ pr_state = data.GetU8(&offset);
+ pr_sname = data.GetU8(&offset);
+ pr_zomb = data.GetU8(&offset);
+ pr_nice = data.GetU8(&offset);
+
+ pr_flag = data.GetU32(&offset);
+ pr_uid = data.GetU16(&offset);
+ pr_gid = data.GetU16(&offset);
+
+ pr_pid = data.GetU32(&offset);
+ pr_ppid = data.GetU32(&offset);
+ pr_pgrp = data.GetU32(&offset);
+ pr_sid = data.GetU32(&offset);
+
+ size = 16;
+ data.ExtractBytes(offset, size, byteorder, pr_fname);
+ offset += size;
+
+ size = 80;
+ data.ExtractBytes(offset, size, byteorder, pr_psargs);
+ offset += size;
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxPrPsInfo::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
}
+//----------------------------------------------------------------
+// Parse SIGINFO from NOTE entry
+//----------------------------------------------------------------
+ELFLinuxSigInfo::ELFLinuxSigInfo() {
+ memset(this, 0, sizeof(ELFLinuxSigInfo));
+}
+
+Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
+ break;
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ offset_t offset = 0;
+ si_signo = data.GetU32(&offset);
+ si_code = data.GetU32(&offset);
+ si_errno = data.GetU32(&offset);
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxSigInfo::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
+}
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index b4e990140675..1957ac243ceb 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -16,168 +16,204 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/Thread.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Target/Thread.h"
-struct compat_timeval
-{
- int64_t tv_sec;
- int32_t tv_usec;
+struct compat_timeval {
+ alignas(8) uint64_t tv_sec;
+ alignas(8) uint64_t tv_usec;
};
// PRSTATUS structure's size differs based on architecture.
-// Currently parsing done only for x86-64 architecture by
-// simply reading data from the buffer.
-// The following macros are used to specify the size.
-// Calculating size using sizeof() wont work because of padding.
-#define ELFLINUXPRSTATUS64_SIZE (112)
-#define ELFLINUXPRPSINFO64_SIZE (132)
+// This is the layout in the x86-64 arch.
+// In the i386 case we parse it manually and fill it again
+// in the same structure
+// The gp registers are also a part of this struct, but they are handled
+// separately
#undef si_signo
#undef si_code
#undef si_errno
-struct ELFLinuxPrStatus
-{
- int32_t si_signo;
- int32_t si_code;
- int32_t si_errno;
-
- int16_t pr_cursig;
-
- uint64_t pr_sigpend;
- uint64_t pr_sighold;
-
- uint32_t pr_pid;
- uint32_t pr_ppid;
- uint32_t pr_pgrp;
- uint32_t pr_sid;
-
- compat_timeval pr_utime;
- compat_timeval pr_stime;
- compat_timeval pr_cutime;
- compat_timeval pr_cstime;
-
- ELFLinuxPrStatus();
-
- bool
- Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
-
- static size_t
- GetSize(lldb_private::ArchSpec &arch)
- {
- switch(arch.GetCore())
- {
- case lldb_private::ArchSpec::eCore_s390x_generic:
- case lldb_private::ArchSpec::eCore_x86_64_x86_64:
- return ELFLINUXPRSTATUS64_SIZE;
- default:
- return 0;
- }
+struct ELFLinuxPrStatus {
+ int32_t si_signo;
+ int32_t si_code;
+ int32_t si_errno;
+
+ int16_t pr_cursig;
+
+ alignas(8) uint64_t pr_sigpend;
+ alignas(8) uint64_t pr_sighold;
+
+ uint32_t pr_pid;
+ uint32_t pr_ppid;
+ uint32_t pr_pgrp;
+ uint32_t pr_sid;
+
+ compat_timeval pr_utime;
+ compat_timeval pr_stime;
+ compat_timeval pr_cutime;
+ compat_timeval pr_cstime;
+
+ ELFLinuxPrStatus();
+
+ lldb_private::Error Parse(lldb_private::DataExtractor &data,
+ lldb_private::ArchSpec &arch);
+
+ // Return the bytesize of the structure
+ // 64 bit - just sizeof
+ // 32 bit - hardcoded because we are reusing the struct, but some of the
+ // members are smaller -
+ // so the layout is not the same
+ static size_t GetSize(lldb_private::ArchSpec &arch) {
+ switch (arch.GetCore()) {
+ case lldb_private::ArchSpec::eCore_s390x_generic:
+ case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ return sizeof(ELFLinuxPrStatus);
+ case lldb_private::ArchSpec::eCore_x86_32_i386:
+ case lldb_private::ArchSpec::eCore_x86_32_i486:
+ return 72;
+ default:
+ return 0;
+ }
+ }
+};
+
+static_assert(sizeof(ELFLinuxPrStatus) == 112,
+ "sizeof ELFLinuxPrStatus is not correct!");
+
+struct ELFLinuxSigInfo {
+ int32_t si_signo;
+ int32_t si_code;
+ int32_t si_errno;
+
+ ELFLinuxSigInfo();
+
+ lldb_private::Error Parse(lldb_private::DataExtractor &data,
+ const lldb_private::ArchSpec &arch);
+
+ // Return the bytesize of the structure
+ // 64 bit - just sizeof
+ // 32 bit - hardcoded because we are reusing the struct, but some of the
+ // members are smaller -
+ // so the layout is not the same
+ static size_t GetSize(const lldb_private::ArchSpec &arch) {
+ switch (arch.GetCore()) {
+ case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ return sizeof(ELFLinuxSigInfo);
+ case lldb_private::ArchSpec::eCore_s390x_generic:
+ case lldb_private::ArchSpec::eCore_x86_32_i386:
+ case lldb_private::ArchSpec::eCore_x86_32_i486:
+ return 12;
+ default:
+ return 0;
}
+ }
};
-struct ELFLinuxPrPsInfo
-{
- char pr_state;
- char pr_sname;
- char pr_zomb;
- char pr_nice;
- uint64_t pr_flag;
- uint32_t pr_uid;
- uint32_t pr_gid;
- int32_t pr_pid;
- int32_t pr_ppid;
- int32_t pr_pgrp;
- int32_t pr_sid;
- char pr_fname[16];
- char pr_psargs[80];
-
- ELFLinuxPrPsInfo();
-
- bool
- Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
-
- static size_t
- GetSize(lldb_private::ArchSpec &arch)
- {
- switch(arch.GetCore())
- {
- case lldb_private::ArchSpec::eCore_s390x_generic:
- case lldb_private::ArchSpec::eCore_x86_64_x86_64:
- return ELFLINUXPRPSINFO64_SIZE;
- default:
- return 0;
- }
+static_assert(sizeof(ELFLinuxSigInfo) == 12,
+ "sizeof ELFLinuxSigInfo is not correct!");
+
+// PRPSINFO structure's size differs based on architecture.
+// This is the layout in the x86-64 arch case.
+// In the i386 case we parse it manually and fill it again
+// in the same structure
+struct ELFLinuxPrPsInfo {
+ char pr_state;
+ char pr_sname;
+ char pr_zomb;
+ char pr_nice;
+ alignas(8) uint64_t pr_flag;
+ uint32_t pr_uid;
+ uint32_t pr_gid;
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ char pr_fname[16];
+ char pr_psargs[80];
+
+ ELFLinuxPrPsInfo();
+
+ lldb_private::Error Parse(lldb_private::DataExtractor &data,
+ lldb_private::ArchSpec &arch);
+
+ // Return the bytesize of the structure
+ // 64 bit - just sizeof
+ // 32 bit - hardcoded because we are reusing the struct, but some of the
+ // members are smaller -
+ // so the layout is not the same
+ static size_t GetSize(lldb_private::ArchSpec &arch) {
+ switch (arch.GetCore()) {
+ case lldb_private::ArchSpec::eCore_s390x_generic:
+ case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ return sizeof(ELFLinuxPrPsInfo);
+ case lldb_private::ArchSpec::eCore_x86_32_i386:
+ case lldb_private::ArchSpec::eCore_x86_32_i486:
+ return 124;
+ default:
+ return 0;
}
+ }
};
-struct ThreadData
-{
- lldb_private::DataExtractor gpregset;
- lldb_private::DataExtractor fpregset;
- lldb_private::DataExtractor vregset;
- lldb::tid_t tid;
- int signo;
- std::string name;
+static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
+ "sizeof ELFLinuxPrPsInfo is not correct!");
+
+struct ThreadData {
+ lldb_private::DataExtractor gpregset;
+ lldb_private::DataExtractor fpregset;
+ lldb_private::DataExtractor vregset;
+ lldb::tid_t tid;
+ int signo = 0;
+ int prstatus_sig = 0;
+ std::string name;
};
-class ThreadElfCore : public lldb_private::Thread
-{
+class ThreadElfCore : public lldb_private::Thread {
public:
- ThreadElfCore (lldb_private::Process &process, const ThreadData &td);
+ ThreadElfCore(lldb_private::Process &process, const ThreadData &td);
- ~ThreadElfCore() override;
+ ~ThreadElfCore() override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- lldb::RegisterContextSP
- GetRegisterContext() override;
+ lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
- void
- ClearStackFrames() override;
+ void ClearStackFrames() override;
- static bool
- ThreadIDIsValid (lldb::tid_t thread)
- {
- return thread != 0;
- }
+ static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
- const char *
- GetName() override
- {
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
- }
+ const char *GetName() override {
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
+ }
- void
- SetName(const char *name) override
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) override {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
protected:
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- lldb::RegisterContextSP m_thread_reg_ctx_sp;
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ std::string m_thread_name;
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
- int m_signo;
+ int m_signo;
- lldb_private::DataExtractor m_gpregset_data;
- lldb_private::DataExtractor m_fpregset_data;
- lldb_private::DataExtractor m_vregset_data;
+ lldb_private::DataExtractor m_gpregset_data;
+ lldb_private::DataExtractor m_fpregset_data;
+ lldb_private::DataExtractor m_vregset_data;
- bool CalculateStopInfo() override;
+ bool CalculateStopInfo() override;
};
#endif // liblldb_ThreadElfCore_h_
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
index 8dbfa453f2c2..b28522725868 100644
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -3,6 +3,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
endif()
add_lldb_library(lldbPluginProcessGDBRemote
+ GDBRemoteClientBase.cpp
GDBRemoteCommunication.cpp
GDBRemoteCommunicationClient.cpp
GDBRemoteCommunicationServer.cpp
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
new file mode 100644
index 000000000000..1e20a090161d
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -0,0 +1,376 @@
+//===-- GDBRemoteClientBase.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GDBRemoteClientBase.h"
+
+#include "llvm/ADT/StringExtras.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "ProcessGDBRemoteLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+using namespace std::chrono;
+
+static const seconds kInterruptTimeout(5);
+
+/////////////////////////
+// GDBRemoteClientBase //
+/////////////////////////
+
+GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;
+
+GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
+ const char *listener_name)
+ : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0),
+ m_is_running(false), m_should_stop(false) {}
+
+StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
+ ContinueDelegate &delegate, const UnixSignals &signals,
+ llvm::StringRef payload, StringExtractorGDBRemote &response) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ response.Clear();
+
+ {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_continue_packet = payload;
+ m_should_stop = false;
+ }
+ ContinueLock cont_lock(*this);
+ if (!cont_lock)
+ return eStateInvalid;
+ OnRunPacketSent(true);
+
+ for (;;) {
+ PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
+ switch (read_result) {
+ case PacketResult::ErrorReplyTimeout: {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ if (m_async_count == 0)
+ continue;
+ if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
+ return eStateInvalid;
+ }
+ case PacketResult::Success:
+ break;
+ default:
+ if (log)
+ log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false",
+ __FUNCTION__);
+ return eStateInvalid;
+ }
+ if (response.Empty())
+ return eStateInvalid;
+
+ const char stop_type = response.GetChar();
+ if (log)
+ log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
+ response.GetStringRef().c_str());
+
+ switch (stop_type) {
+ case 'W':
+ case 'X':
+ return eStateExited;
+ case 'E':
+ // ERROR
+ return eStateInvalid;
+ default:
+ if (log)
+ log->Printf("GDBRemoteClientBase::%s () unrecognized async packet",
+ __FUNCTION__);
+ return eStateInvalid;
+ case 'O': {
+ std::string inferior_stdout;
+ response.GetHexByteString(inferior_stdout);
+ delegate.HandleAsyncStdout(inferior_stdout);
+ break;
+ }
+ case 'A':
+ delegate.HandleAsyncMisc(
+ llvm::StringRef(response.GetStringRef()).substr(1));
+ break;
+ case 'J':
+ delegate.HandleAsyncStructuredDataPacket(response.GetStringRef());
+ break;
+ case 'T':
+ case 'S':
+ // Do this with the continue lock held.
+ const bool should_stop = ShouldStop(signals, response);
+ response.SetFilePos(0);
+
+ // The packet we should resume with. In the future
+ // we should check our thread list and "do the right thing"
+ // for new threads that show up while we stop and run async
+ // packets. Setting the packet to 'c' to continue all threads
+ // is the right thing to do 99.99% of the time because if a
+ // thread was single stepping, and we sent an interrupt, we
+ // will notice above that we didn't stop due to an interrupt
+ // but stopped due to stepping and we would _not_ continue.
+ // This packet may get modified by the async actions (e.g. to send a
+ // signal).
+ m_continue_packet = 'c';
+ cont_lock.unlock();
+
+ delegate.HandleStopReply();
+ if (should_stop)
+ return eStateStopped;
+
+ switch (cont_lock.lock()) {
+ case ContinueLock::LockResult::Success:
+ break;
+ case ContinueLock::LockResult::Failed:
+ return eStateInvalid;
+ case ContinueLock::LockResult::Cancelled:
+ return eStateStopped;
+ }
+ OnRunPacketSent(false);
+ break;
+ }
+ }
+}
+
+bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
+ Lock lock(*this, true);
+ if (!lock || !lock.DidInterrupt())
+ return false;
+
+ m_continue_packet = 'C';
+ m_continue_packet += llvm::hexdigit((signo / 16) % 16);
+ m_continue_packet += llvm::hexdigit(signo % 16);
+ return true;
+}
+
+bool GDBRemoteClientBase::Interrupt() {
+ Lock lock(*this, true);
+ if (!lock.DidInterrupt())
+ return false;
+ m_should_stop = true;
+ return true;
+}
+GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::SendPacketAndWaitForResponse(
+ llvm::StringRef payload, StringExtractorGDBRemote &response,
+ bool send_async) {
+ Lock lock(*this, send_async);
+ if (!lock) {
+ if (Log *log =
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
+ log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
+ "packet '%.*s' (send_async=%d)",
+ __FUNCTION__, int(payload.size()), payload.data(),
+ send_async);
+ return PacketResult::ErrorSendFailed;
+ }
+
+ return SendPacketAndWaitForResponseNoLock(payload, response);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
+ llvm::StringRef payload, StringExtractorGDBRemote &response) {
+ PacketResult packet_result = SendPacketNoLock(payload);
+ if (packet_result != PacketResult::Success)
+ return packet_result;
+
+ const size_t max_response_retries = 3;
+ for (size_t i = 0; i < max_response_retries; ++i) {
+ packet_result = ReadPacket(response, GetPacketTimeout(), true);
+ // Make sure we received a response
+ if (packet_result != PacketResult::Success)
+ return packet_result;
+ // Make sure our response is valid for the payload that was sent
+ if (response.ValidateResponse())
+ return packet_result;
+ // Response says it wasn't valid
+ Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
+ if (log)
+ log->Printf(
+ "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
+ int(payload.size()), payload.data(), response.GetStringRef().c_str(),
+ (i == (max_response_retries - 1))
+ ? "using invalid response and giving up"
+ : "ignoring response and waiting for another");
+ }
+ return packet_result;
+}
+
+bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
+ StringExtractorGDBRemote &response) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
+
+ // we want to lock down packet sending while we continue
+ Lock lock(*this, true);
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
+ __FUNCTION__, int(payload.size()), payload.data());
+
+ if (SendPacketNoLock(payload) != PacketResult::Success)
+ return false;
+
+ OnRunPacketSent(true);
+
+ // wait for the response to the vCont
+ if (ReadPacket(response, llvm::None, false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ return true;
+ }
+
+ return false;
+}
+bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
+ StringExtractorGDBRemote &response) {
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ if (m_async_count == 0)
+ return true; // We were not interrupted. The process stopped on its own.
+
+ // Older debugserver stubs (before April 2016) can return two
+ // stop-reply packets in response to a ^C packet.
+ // Additionally, all debugservers still return two stop replies if
+ // the inferior stops due to some other reason before the remote
+ // stub manages to interrupt it. We need to wait for this
+ // additional packet to make sure the packet sequence does not get
+ // skewed.
+ StringExtractorGDBRemote extra_stop_reply_packet;
+ ReadPacket(extra_stop_reply_packet, milliseconds(100), false);
+
+ // Interrupting is typically done using SIGSTOP or SIGINT, so if
+ // the process stops with some other signal, we definitely want to
+ // stop.
+ const uint8_t signo = response.GetHexU8(UINT8_MAX);
+ if (signo != signals.GetSignalNumberFromName("SIGSTOP") &&
+ signo != signals.GetSignalNumberFromName("SIGINT"))
+ return true;
+
+ // We probably only stopped to perform some async processing, so continue
+ // after that is done.
+ // TODO: This is not 100% correct, as the process may have been stopped with
+ // SIGINT or SIGSTOP that was not caused by us (e.g. raise(SIGINT)). This will
+ // normally cause a stop, but if it's done concurrently with a async
+ // interrupt, that stop will get eaten (llvm.org/pr20231).
+ return false;
+}
+
+void GDBRemoteClientBase::OnRunPacketSent(bool first) {
+ if (first)
+ BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
+}
+
+///////////////////////////////////////
+// GDBRemoteClientBase::ContinueLock //
+///////////////////////////////////////
+
+GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm)
+ : m_comm(comm), m_acquired(false) {
+ lock();
+}
+
+GDBRemoteClientBase::ContinueLock::~ContinueLock() {
+ if (m_acquired)
+ unlock();
+}
+
+void GDBRemoteClientBase::ContinueLock::unlock() {
+ lldbassert(m_acquired);
+ {
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ m_comm.m_is_running = false;
+ }
+ m_comm.m_cv.notify_all();
+ m_acquired = false;
+}
+
+GDBRemoteClientBase::ContinueLock::LockResult
+GDBRemoteClientBase::ContinueLock::lock() {
+ Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
+ if (log)
+ log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
+ __FUNCTION__, m_comm.m_continue_packet.c_str());
+
+ lldbassert(!m_acquired);
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
+ if (m_comm.m_should_stop) {
+ m_comm.m_should_stop = false;
+ if (log)
+ log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled",
+ __FUNCTION__);
+ return LockResult::Cancelled;
+ }
+ if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
+ PacketResult::Success)
+ return LockResult::Failed;
+
+ lldbassert(!m_comm.m_is_running);
+ m_comm.m_is_running = true;
+ m_acquired = true;
+ return LockResult::Success;
+}
+
+///////////////////////////////
+// GDBRemoteClientBase::Lock //
+///////////////////////////////
+
+GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
+ : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
+ m_acquired(false), m_did_interrupt(false) {
+ SyncWithContinueThread(interrupt);
+ if (m_acquired)
+ m_async_lock.lock();
+}
+
+void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ if (m_comm.m_is_running && !interrupt)
+ return; // We were asked to avoid interrupting the sender. Lock is not
+ // acquired.
+
+ ++m_comm.m_async_count;
+ if (m_comm.m_is_running) {
+ if (m_comm.m_async_count == 1) {
+ // The sender has sent the continue packet and we are the first async
+ // packet. Let's interrupt it.
+ const char ctrl_c = '\x03';
+ ConnectionStatus status = eConnectionStatusSuccess;
+ size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
+ if (bytes_written == 0) {
+ --m_comm.m_async_count;
+ if (log)
+ log->Printf("GDBRemoteClientBase::Lock::Lock failed to send "
+ "interrupt packet");
+ return;
+ }
+ if (log)
+ 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_did_interrupt = true;
+ }
+ m_acquired = true;
+}
+
+GDBRemoteClientBase::Lock::~Lock() {
+ if (!m_acquired)
+ return;
+ {
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ --m_comm.m_async_count;
+ }
+ m_comm.m_cv.notify_one();
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
new file mode 100644
index 000000000000..2646405c9b91
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -0,0 +1,144 @@
+//===-- GDBRemoteClientBase.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_GDBRemoteClientBase_h_
+#define liblldb_GDBRemoteClientBase_h_
+
+#include "GDBRemoteCommunication.h"
+
+#include <condition_variable>
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+class GDBRemoteClientBase : public GDBRemoteCommunication {
+public:
+ struct ContinueDelegate {
+ virtual ~ContinueDelegate();
+ virtual void HandleAsyncStdout(llvm::StringRef out) = 0;
+ virtual void HandleAsyncMisc(llvm::StringRef data) = 0;
+ virtual void HandleStopReply() = 0;
+
+ // =========================================================================
+ /// Process asynchronously-received structured data.
+ ///
+ /// @param[in] data
+ /// The complete data packet, expected to start with JSON-async.
+ // =========================================================================
+ virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0;
+ };
+
+ GDBRemoteClientBase(const char *comm_name, const char *listener_name);
+
+ bool SendAsyncSignal(int signo);
+
+ bool Interrupt();
+
+ lldb::StateType SendContinuePacketAndWaitForResponse(
+ ContinueDelegate &delegate, const UnixSignals &signals,
+ llvm::StringRef payload, StringExtractorGDBRemote &response);
+
+ PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
+ StringExtractorGDBRemote &response,
+ bool send_async);
+
+ bool SendvContPacket(llvm::StringRef payload,
+ StringExtractorGDBRemote &response);
+
+ class Lock {
+ public:
+ Lock(GDBRemoteClientBase &comm, bool interrupt);
+ ~Lock();
+
+ explicit operator bool() { return m_acquired; }
+
+ // Whether we had to interrupt the continue thread to acquire the
+ // connection.
+ bool DidInterrupt() const { return m_did_interrupt; }
+
+ private:
+ std::unique_lock<std::recursive_mutex> m_async_lock;
+ GDBRemoteClientBase &m_comm;
+ bool m_acquired;
+ bool m_did_interrupt;
+
+ void SyncWithContinueThread(bool interrupt);
+ };
+
+protected:
+ PacketResult
+ SendPacketAndWaitForResponseNoLock(llvm::StringRef payload,
+ StringExtractorGDBRemote &response);
+
+ virtual void OnRunPacketSent(bool first);
+
+private:
+ // Variables handling synchronization between the Continue thread and any
+ // other threads
+ // wishing to send packets over the connection. Either the continue thread has
+ // control over
+ // the connection (m_is_running == true) or the connection is free for an
+ // arbitrary number of
+ // other senders to take which indicate their interest by incrementing
+ // m_async_count.
+ // Semantics of individual states:
+ // - m_continue_packet == false, m_async_count == 0: connection is free
+ // - m_continue_packet == true, m_async_count == 0: only continue thread is
+ // present
+ // - m_continue_packet == true, m_async_count > 0: continue thread has
+ // control, async threads
+ // should interrupt it and wait for it to set m_continue_packet to false
+ // - m_continue_packet == false, m_async_count > 0: async threads have
+ // control, continue
+ // thread needs to wait for them to finish (m_async_count goes down to 0).
+ std::mutex m_mutex;
+ std::condition_variable m_cv;
+ // Packet with which to resume after an async interrupt. Can be changed by an
+ // async thread
+ // e.g. to inject a signal.
+ std::string m_continue_packet;
+ // When was the interrupt packet sent. Used to make sure we time out if the
+ // stub does not
+ // respond to interrupt requests.
+ std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
+ uint32_t m_async_count;
+ bool m_is_running;
+ bool m_should_stop; // Whether we should resume after a stop.
+ // end of continue thread synchronization block
+
+ // This handles the synchronization between individual async threads. For now
+ // they just use a
+ // simple mutex.
+ std::recursive_mutex m_async_mutex;
+
+ bool ShouldStop(const UnixSignals &signals,
+ StringExtractorGDBRemote &response);
+
+ class ContinueLock {
+ public:
+ enum class LockResult { Success, Cancelled, Failed };
+
+ explicit ContinueLock(GDBRemoteClientBase &comm);
+ ~ContinueLock();
+ explicit operator bool() { return m_acquired; }
+
+ LockResult lock();
+
+ void unlock();
+
+ private:
+ GDBRemoteClientBase &m_comm;
+ bool m_acquired;
+ };
+};
+
+} // namespace process_gdb_remote
+} // namespace lldb_private
+
+#endif // liblldb_GDBRemoteCommunicationClient_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f164b1411be8..bd87521fe6e7 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "GDBRemoteCommunication.h"
// C Includes
@@ -29,25 +28,25 @@
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ScopedPrinter.h"
// Project includes
#include "ProcessGDBRemoteLog.h"
#if defined(__APPLE__)
-# define DEBUGSERVER_BASENAME "debugserver"
+#define DEBUGSERVER_BASENAME "debugserver"
#else
-# define DEBUGSERVER_BASENAME "lldb-server"
+#define DEBUGSERVER_BASENAME "lldb-server"
#endif
-#if defined (HAVE_LIBCOMPRESSION)
+#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif
-#if defined (HAVE_LIBZ)
+#if defined(HAVE_LIBZ)
#include <zlib.h>
#endif
@@ -55,1449 +54,1309 @@ 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(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 ()
-{
+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 = Host::GetCurrentThreadID();
+ }
}
-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 = Host::GetCurrentThreadID();
- }
+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 = Host::GetCurrentThreadID();
+ }
}
-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 = Host::GetCurrentThreadID();
- }
+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 (Stream &strm) const
-{
- const uint32_t size = GetNumPacketsInHistory ();
- const uint32_t first_idx = GetFirstSavedPacketIndex ();
+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;
- 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());
- }
+ 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
//----------------------------------------------------------------------
-GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
- const char *listener_name) :
- Communication(comm_name),
+GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
+ const char *listener_name)
+ : Communication(comm_name),
#ifdef LLDB_CONFIGURATION_DEBUG
- m_packet_timeout (1000),
+ m_packet_timeout(1000),
#else
- m_packet_timeout (1),
+ m_packet_timeout(1),
#endif
- m_echo_number(0),
- m_supports_qEcho (eLazyBoolCalculate),
- m_sequence_mutex (Mutex::eMutexTypeRecursive),
- m_public_is_running (false),
- m_private_is_running (false),
- m_history (512),
- m_send_acks (true),
- m_compression_type (CompressionType::None),
- m_listen_url ()
-{
+ m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512),
+ m_send_acks(true), m_compression_type(CompressionType::None),
+ m_listen_url() {
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunication::~GDBRemoteCommunication()
-{
- if (IsConnected())
- {
- Disconnect();
- }
-
- // Stop the communications read thread which is used to parse all
- // incoming packets. This function will block until the read
- // thread returns.
- if (m_read_thread_enabled)
- StopReadThread();
+GDBRemoteCommunication::~GDBRemoteCommunication() {
+ if (IsConnected()) {
+ Disconnect();
+ }
+
+ // Stop the communications read thread which is used to parse all
+ // incoming packets. This function will block until the read
+ // thread returns.
+ if (m_read_thread_enabled)
+ StopReadThread();
}
-char
-GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
-{
- int checksum = 0;
+char GDBRemoteCommunication::CalculcateChecksum(llvm::StringRef payload) {
+ int checksum = 0;
- for (size_t i = 0; i < payload_length; ++i)
- checksum += payload[i];
+ for (char c : payload)
+ checksum += c;
- return checksum & 255;
+ return checksum & 255;
}
-size_t
-GDBRemoteCommunication::SendAck ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
- ConnectionStatus status = eConnectionStatusSuccess;
- char ch = '+';
- 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);
- return bytes_written;
+size_t GDBRemoteCommunication::SendAck() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ ConnectionStatus status = eConnectionStatusSuccess;
+ char ch = '+';
+ 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);
+ return bytes_written;
}
-size_t
-GDBRemoteCommunication::SendNack ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
- ConnectionStatus status = eConnectionStatusSuccess;
- char ch = '-';
- 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);
- return bytes_written;
+size_t GDBRemoteCommunication::SendNack() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ ConnectionStatus status = eConnectionStatusSuccess;
+ char ch = '-';
+ 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);
+ return bytes_written;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
-{
- Mutex::Locker locker(m_sequence_mutex);
- return SendPacketNoLock (payload, payload_length);
-}
+GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
+ if (IsConnected()) {
+ StreamString packet(0, 4, eByteOrderBig);
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
-{
- if (IsConnected())
- {
- StreamString packet(0, 4, eByteOrderBig);
-
- packet.PutChar('$');
- packet.Write (payload, payload_length);
- packet.PutChar('#');
- packet.PutHex8(CalculcateChecksum (payload, payload_length));
-
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
- ConnectionStatus status = eConnectionStatusSuccess;
- const char *packet_data = packet.GetData();
- const size_t packet_length = packet.GetSize();
- size_t bytes_written = Write (packet_data, packet_length, status, NULL);
- if (log)
- {
- size_t binary_start_offset = 0;
- if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) == 0)
- {
- const char *first_comma = strchr(packet_data, ',');
- if (first_comma)
- {
- const char *second_comma = strchr(first_comma + 1, ',');
- if (second_comma)
- binary_start_offset = second_comma - packet_data + 1;
- }
- }
-
- // If logging was just enabled and we have history, then dump out what
- // we have to the log so we get the historical context. The Dump() call that
- // logs all of the packet will set a boolean so that we don't dump this more
- // than once
- if (!m_history.DidDumpToLog ())
- m_history.Dump (log);
-
- if (binary_start_offset)
- {
- StreamString strm;
- // Print non binary data header
- strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)binary_start_offset, packet_data);
- const uint8_t *p;
- // Print binary data exactly as sent
- for (p = (const uint8_t*)packet_data + binary_start_offset; *p != '#'; ++p)
- strm.Printf("\\x%2.2x", *p);
- // Print the checksum
- strm.Printf("%*s", (int)3, p);
- log->PutCString(strm.GetString().c_str());
- }
- else
- log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet_length, packet_data);
- }
+ packet.PutChar('$');
+ packet.Write(payload.data(), payload.size());
+ packet.PutChar('#');
+ packet.PutHex8(CalculcateChecksum(payload));
- m_history.AddPacket (packet.GetString(), packet_length, History::ePacketTypeSend, bytes_written);
-
-
- if (bytes_written == packet_length)
- {
- if (GetSendAcks ())
- return GetAck ();
- else
- return PacketResult::Success;
- }
- else
- {
- if (log)
- log->Printf ("error: failed to send packet: %.*s", (int)packet_length, packet_data);
+ 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();
+ size_t bytes_written = Write(packet_data, packet_length, status, NULL);
+ if (log) {
+ size_t binary_start_offset = 0;
+ if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) ==
+ 0) {
+ const char *first_comma = strchr(packet_data, ',');
+ if (first_comma) {
+ const char *second_comma = strchr(first_comma + 1, ',');
+ if (second_comma)
+ binary_start_offset = second_comma - packet_data + 1;
}
+ }
+
+ // If logging was just enabled and we have history, then dump out what
+ // we have to the log so we get the historical context. The Dump() call
+ // that
+ // logs all of the packet will set a boolean so that we don't dump this
+ // more
+ // than once
+ if (!m_history.DidDumpToLog())
+ m_history.Dump(log);
+
+ if (binary_start_offset) {
+ StreamString strm;
+ // Print non binary data header
+ strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
+ (int)binary_start_offset, packet_data);
+ const uint8_t *p;
+ // Print binary data exactly as sent
+ for (p = (const uint8_t *)packet_data + binary_start_offset; *p != '#';
+ ++p)
+ strm.Printf("\\x%2.2x", *p);
+ // Print the checksum
+ strm.Printf("%*s", (int)3, p);
+ log->PutString(strm.GetString());
+ } else
+ log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
+ (int)packet_length, packet_data);
}
- return PacketResult::ErrorSendFailed;
-}
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::GetAck ()
-{
- StringExtractorGDBRemote packet;
- PacketResult result = ReadPacket (packet, GetPacketTimeoutInMicroSeconds (), false);
- if (result == PacketResult::Success)
- {
- if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck)
- return PacketResult::Success;
- else
- return PacketResult::ErrorSendAck;
- }
- return result;
-}
+ m_history.AddPacket(packet.GetString(), packet_length,
+ History::ePacketTypeSend, bytes_written);
-bool
-GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
-{
- if (IsRunning())
- return locker.TryLock (m_sequence_mutex, failure_message);
-
- locker.Lock (m_sequence_mutex);
- return true;
+ if (bytes_written == packet_length) {
+ if (GetSendAcks())
+ return GetAck();
+ else
+ return PacketResult::Success;
+ } else {
+ if (log)
+ log->Printf("error: failed to send packet: %.*s", (int)packet_length,
+ packet_data);
+ }
+ }
+ return PacketResult::ErrorSendFailed;
}
-
-bool
-GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
-{
- return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
+GDBRemoteCommunication::PacketResult GDBRemoteCommunication::GetAck() {
+ StringExtractorGDBRemote packet;
+ PacketResult result = ReadPacket(packet, GetPacketTimeout(), false);
+ if (result == PacketResult::Success) {
+ if (packet.GetResponseType() ==
+ StringExtractorGDBRemote::ResponseType::eAck)
+ return PacketResult::Success;
+ else
+ return PacketResult::ErrorSendAck;
+ }
+ return result;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout)
-{
- if (m_read_thread_enabled)
- return PopPacketFromQueue (response, timeout_usec);
- else
- return WaitForPacketWithTimeoutMicroSecondsNoLock (response, timeout_usec, sync_on_timeout);
+GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout,
+ bool sync_on_timeout) {
+ if (m_read_thread_enabled)
+ return PopPacketFromQueue(response, timeout);
+ else
+ return WaitForPacketNoLock(response, timeout, sync_on_timeout);
}
-
// This function is called when a packet is requested.
// A whole packet is popped from the packet queue and returned to the caller.
// Packets are placed into this queue from the communication read thread.
// See GDBRemoteCommunication::AppendBytesToCache.
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec)
-{
- // Calculate absolute timeout value
- TimeValue timeout = TimeValue::Now();
- timeout.OffsetWithMicroSeconds(timeout_usec);
-
- do
- {
- // scope for the mutex
- {
- // lock down the packet queue
- Mutex::Locker locker(m_packet_queue_mutex);
-
- // Wait on condition variable.
- if (m_packet_queue.size() == 0)
- m_condition_queue_not_empty.Wait(m_packet_queue_mutex, &timeout);
-
- if (m_packet_queue.size() > 0)
- {
- // get the front element of the queue
- response = m_packet_queue.front();
-
- // remove the front element
- m_packet_queue.pop();
-
- // we got a packet
- return PacketResult::Success;
- }
- }
-
- // Disconnected
- if (!IsConnected())
- return PacketResult::ErrorDisconnected;
-
- // Loop while not timed out
- } while (TimeValue::Now() < timeout);
-
- return PacketResult::ErrorReplyTimeout;
+GDBRemoteCommunication::PopPacketFromQueue(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout) {
+ auto pred = [&] { return !m_packet_queue.empty() && IsConnected(); };
+ // lock down the packet queue
+ std::unique_lock<std::mutex> lock(m_packet_queue_mutex);
+
+ if (!timeout)
+ m_condition_queue_not_empty.wait(lock, pred);
+ else {
+ if (!m_condition_queue_not_empty.wait_for(lock, *timeout, pred))
+ return PacketResult::ErrorReplyTimeout;
+ if (!IsConnected())
+ return PacketResult::ErrorDisconnected;
+ }
+
+ // get the front element of the queue
+ response = m_packet_queue.front();
+
+ // remove the front element
+ m_packet_queue.pop();
+
+ // we got a packet
+ return PacketResult::Success;
}
-
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec, bool sync_on_timeout)
-{
- uint8_t buffer[8192];
- Error error;
+GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
+ Timeout<std::micro> timeout,
+ bool sync_on_timeout) {
+ uint8_t buffer[8192];
+ Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS |
+ GDBR_LOG_VERBOSE));
- // Check for a packet from our cache first without trying any reading...
- if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
- return PacketResult::Success;
+ // Check for a packet from our cache first without trying any reading...
+ if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
+ return PacketResult::Success;
- bool timed_out = false;
- bool disconnected = false;
- while (IsConnected() && !timed_out)
- {
- lldb::ConnectionStatus status = eConnectionStatusNoConnection;
- size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
-
- if (log)
- log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
- __PRETTY_FUNCTION__,
- timeout_usec,
- Communication::ConnectionStatusAsCString (status),
- error.AsCString(),
- (uint64_t)bytes_read);
-
- if (bytes_read > 0)
- {
- if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid)
- return PacketResult::Success;
- }
- else
- {
- switch (status)
- {
- case eConnectionStatusTimedOut:
- case eConnectionStatusInterrupted:
- if (sync_on_timeout)
- {
- //------------------------------------------------------------------
- /// Sync the remote GDB server and make sure we get a response that
- /// corresponds to what we send.
- ///
- /// Sends a "qEcho" packet and makes sure it gets the exact packet
- /// echoed back. If the qEcho packet isn't supported, we send a qC
- /// packet and make sure we get a valid thread ID back. We use the
- /// "qC" packet since its response if very unique: is responds with
- /// "QC%x" where %x is the thread ID of the current thread. This
- /// makes the response unique enough from other packet responses to
- /// ensure we are back on track.
- ///
- /// This packet is needed after we time out sending a packet so we
- /// can ensure that we are getting the response for the packet we
- /// are sending. There are no sequence IDs in the GDB remote
- /// protocol (there used to be, but they are not supported anymore)
- /// so if you timeout sending packet "abc", you might then send
- /// packet "cde" and get the response for the previous "abc" packet.
- /// Many responses are "OK" or "" (unsupported) or "EXX" (error) so
- /// many responses for packets can look like responses for other
- /// packets. So if we timeout, we need to ensure that we can get
- /// back on track. If we can't get back on track, we must
- /// disconnect.
- //------------------------------------------------------------------
- bool sync_success = false;
- bool got_actual_response = false;
- // We timed out, we need to sync back up with the
- char echo_packet[32];
- int echo_packet_len = 0;
- RegularExpression response_regex;
-
- if (m_supports_qEcho == eLazyBoolYes)
- {
- echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qEcho:%u", ++m_echo_number);
- std::string regex_str = "^";
- regex_str += echo_packet;
- regex_str += "$";
- response_regex.Compile(regex_str.c_str());
- }
- else
- {
- echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qC");
- response_regex.Compile("^QC[0-9A-Fa-f]+$");
- }
-
- PacketResult echo_packet_result = SendPacketNoLock (echo_packet, echo_packet_len);
- if (echo_packet_result == PacketResult::Success)
- {
- const uint32_t max_retries = 3;
- uint32_t successful_responses = 0;
- for (uint32_t i=0; i<max_retries; ++i)
- {
- StringExtractorGDBRemote echo_response;
- echo_packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (echo_response, timeout_usec, false);
- if (echo_packet_result == PacketResult::Success)
- {
- ++successful_responses;
- if (response_regex.Execute(echo_response.GetStringRef().c_str()))
- {
- sync_success = true;
- break;
- }
- else if (successful_responses == 1)
- {
- // We got something else back as the first successful response, it probably is
- // the response to the packet we actually wanted, so copy it over if this
- // is the first success and continue to try to get the qEcho response
- packet = echo_response;
- got_actual_response = true;
- }
- }
- else if (echo_packet_result == PacketResult::ErrorReplyTimeout)
- continue; // Packet timed out, continue waiting for a response
- else
- break; // Something else went wrong getting the packet back, we failed and are done trying
- }
- }
-
- // We weren't able to sync back up with the server, we must abort otherwise
- // all responses might not be from the right packets...
- if (sync_success)
- {
- // We timed out, but were able to recover
- if (got_actual_response)
- {
- // We initially timed out, but we did get a response that came in before the successful
- // reply to our qEcho packet, so lets say everything is fine...
- return PacketResult::Success;
- }
- }
- else
- {
- disconnected = true;
- Disconnect();
- }
+ bool timed_out = false;
+ bool disconnected = false;
+ while (IsConnected() && !timed_out) {
+ lldb::ConnectionStatus status = eConnectionStatusNoConnection;
+ size_t bytes_read = Read(buffer, sizeof(buffer), timeout, status, &error);
+
+ if (log)
+ log->Printf("%s: Read (buffer, (sizeof(buffer), timeout = %ld us, "
+ "status = %s, error = %s) => bytes_read = %" PRIu64,
+ LLVM_PRETTY_FUNCTION, long(timeout ? timeout->count() : -1),
+ Communication::ConnectionStatusAsCString(status),
+ error.AsCString(), (uint64_t)bytes_read);
+
+ if (bytes_read > 0) {
+ if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid)
+ return PacketResult::Success;
+ } else {
+ switch (status) {
+ case eConnectionStatusTimedOut:
+ case eConnectionStatusInterrupted:
+ if (sync_on_timeout) {
+ //------------------------------------------------------------------
+ /// Sync the remote GDB server and make sure we get a response that
+ /// corresponds to what we send.
+ ///
+ /// Sends a "qEcho" packet and makes sure it gets the exact packet
+ /// echoed back. If the qEcho packet isn't supported, we send a qC
+ /// packet and make sure we get a valid thread ID back. We use the
+ /// "qC" packet since its response if very unique: is responds with
+ /// "QC%x" where %x is the thread ID of the current thread. This
+ /// makes the response unique enough from other packet responses to
+ /// ensure we are back on track.
+ ///
+ /// This packet is needed after we time out sending a packet so we
+ /// can ensure that we are getting the response for the packet we
+ /// are sending. There are no sequence IDs in the GDB remote
+ /// protocol (there used to be, but they are not supported anymore)
+ /// so if you timeout sending packet "abc", you might then send
+ /// packet "cde" and get the response for the previous "abc" packet.
+ /// Many responses are "OK" or "" (unsupported) or "EXX" (error) so
+ /// many responses for packets can look like responses for other
+ /// packets. So if we timeout, we need to ensure that we can get
+ /// back on track. If we can't get back on track, we must
+ /// disconnect.
+ //------------------------------------------------------------------
+ bool sync_success = false;
+ bool got_actual_response = false;
+ // We timed out, we need to sync back up with the
+ char echo_packet[32];
+ int echo_packet_len = 0;
+ RegularExpression response_regex;
+
+ if (m_supports_qEcho == eLazyBoolYes) {
+ echo_packet_len = ::snprintf(echo_packet, sizeof(echo_packet),
+ "qEcho:%u", ++m_echo_number);
+ std::string regex_str = "^";
+ regex_str += echo_packet;
+ regex_str += "$";
+ response_regex.Compile(regex_str);
+ } else {
+ echo_packet_len =
+ ::snprintf(echo_packet, sizeof(echo_packet), "qC");
+ response_regex.Compile(llvm::StringRef("^QC[0-9A-Fa-f]+$"));
+ }
+
+ PacketResult echo_packet_result =
+ SendPacketNoLock(llvm::StringRef(echo_packet, echo_packet_len));
+ if (echo_packet_result == PacketResult::Success) {
+ const uint32_t max_retries = 3;
+ uint32_t successful_responses = 0;
+ for (uint32_t i = 0; i < max_retries; ++i) {
+ StringExtractorGDBRemote echo_response;
+ echo_packet_result =
+ WaitForPacketNoLock(echo_response, timeout, false);
+ if (echo_packet_result == PacketResult::Success) {
+ ++successful_responses;
+ if (response_regex.Execute(echo_response.GetStringRef())) {
+ sync_success = true;
+ break;
+ } else if (successful_responses == 1) {
+ // We got something else back as the first successful
+ // response, it probably is
+ // the response to the packet we actually wanted, so copy it
+ // over if this
+ // is the first success and continue to try to get the qEcho
+ // response
+ packet = echo_response;
+ got_actual_response = true;
}
- timed_out = true;
- break;
- case eConnectionStatusSuccess:
- //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
- break;
-
- case eConnectionStatusEndOfFile:
- case eConnectionStatusNoConnection:
- case eConnectionStatusLostConnection:
- case eConnectionStatusError:
- disconnected = true;
- Disconnect();
- break;
+ } else if (echo_packet_result == PacketResult::ErrorReplyTimeout)
+ continue; // Packet timed out, continue waiting for a response
+ else
+ break; // Something else went wrong getting the packet back, we
+ // failed and are done trying
}
+ }
+
+ // We weren't able to sync back up with the server, we must abort
+ // otherwise
+ // all responses might not be from the right packets...
+ if (sync_success) {
+ // We timed out, but were able to recover
+ if (got_actual_response) {
+ // We initially timed out, but we did get a response that came in
+ // before the successful
+ // reply to our qEcho packet, so lets say everything is fine...
+ return PacketResult::Success;
+ }
+ } else {
+ disconnected = true;
+ Disconnect();
+ }
}
+ timed_out = true;
+ break;
+ case eConnectionStatusSuccess:
+ // printf ("status = success but error = %s\n",
+ // error.AsCString("<invalid>"));
+ break;
+
+ case eConnectionStatusEndOfFile:
+ case eConnectionStatusNoConnection:
+ case eConnectionStatusLostConnection:
+ case eConnectionStatusError:
+ disconnected = true;
+ Disconnect();
+ break;
+ }
}
- packet.Clear ();
- if (disconnected)
- return PacketResult::ErrorDisconnected;
- if (timed_out)
- return PacketResult::ErrorReplyTimeout;
- else
- return PacketResult::ErrorReplyFailed;
+ }
+ packet.Clear();
+ if (disconnected)
+ return PacketResult::ErrorDisconnected;
+ if (timed_out)
+ return PacketResult::ErrorReplyTimeout;
+ else
+ return PacketResult::ErrorReplyFailed;
}
-bool
-GDBRemoteCommunication::DecompressPacket ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-
- if (!CompressionIsEnabled())
- return true;
-
- size_t pkt_size = m_bytes.size();
-
- // Smallest possible compressed packet is $N#00 - an uncompressed empty reply, most commonly indicating
- // an unsupported packet. Anything less than 5 characters, it's definitely not a compressed packet.
- if (pkt_size < 5)
- return true;
-
- if (m_bytes[0] != '$' && m_bytes[0] != '%')
- return true;
- if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
- return true;
-
- size_t hash_mark_idx = m_bytes.find ('#');
- if (hash_mark_idx == std::string::npos)
- return true;
- if (hash_mark_idx + 2 >= m_bytes.size())
- return true;
-
- if (!::isxdigit (m_bytes[hash_mark_idx + 1]) || !::isxdigit (m_bytes[hash_mark_idx + 2]))
- return true;
-
- size_t content_length = pkt_size - 5; // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
- size_t content_start = 2; // The first character of the compressed/not-compressed text of the packet
- size_t checksum_idx = hash_mark_idx + 1; // The first character of the two hex checksum characters
-
- // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain multiple packets.
- // size_of_first_packet is the size of the initial packet which we'll replace with the decompressed
- // version of, leaving the rest of m_bytes unmodified.
- size_t size_of_first_packet = hash_mark_idx + 3;
-
- // Compressed packets ("$C") start with a base10 number which is the size of the uncompressed payload,
- // then a : and then the compressed data. e.g. $C1024:<binary>#00
- // Update content_start and content_length to only include the <binary> part of the packet.
-
- uint64_t decompressed_bufsize = ULONG_MAX;
- if (m_bytes[1] == 'C')
- {
- size_t i = content_start;
- while (i < hash_mark_idx && isdigit(m_bytes[i]))
- i++;
- if (i < hash_mark_idx && m_bytes[i] == ':')
- {
- i++;
- content_start = i;
- content_length = hash_mark_idx - content_start;
- std::string bufsize_str (m_bytes.data() + 2, i - 2 - 1);
- errno = 0;
- decompressed_bufsize = ::strtoul (bufsize_str.c_str(), NULL, 10);
- if (errno != 0 || decompressed_bufsize == ULONG_MAX)
- {
- m_bytes.erase (0, size_of_first_packet);
- return false;
- }
- }
- }
+bool GDBRemoteCommunication::DecompressPacket() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
- if (GetSendAcks ())
- {
- char packet_checksum_cstr[3];
- packet_checksum_cstr[0] = m_bytes[checksum_idx];
- packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
- packet_checksum_cstr[2] = '\0';
- long packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
-
- long actual_checksum = CalculcateChecksum (m_bytes.data() + 1, hash_mark_idx - 1);
- bool success = packet_checksum == actual_checksum;
- if (!success)
- {
- if (log)
- log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
- (int)(pkt_size),
- m_bytes.c_str(),
- (uint8_t)packet_checksum,
- (uint8_t)actual_checksum);
- }
- // Send the ack or nack if needed
- if (!success)
- {
- SendNack();
- m_bytes.erase (0, size_of_first_packet);
- return false;
- }
- else
- {
- SendAck();
- }
- }
+ if (!CompressionIsEnabled())
+ return true;
- if (m_bytes[1] == 'N')
- {
- // This packet was not compressed -- delete the 'N' character at the
- // start and the packet may be processed as-is.
- m_bytes.erase(1, 1);
- return true;
- }
+ size_t pkt_size = m_bytes.size();
- // Reverse the gdb-remote binary escaping that was done to the compressed text to
- // guard characters like '$', '#', '}', etc.
- std::vector<uint8_t> unescaped_content;
- unescaped_content.reserve (content_length);
- size_t i = content_start;
- while (i < hash_mark_idx)
- {
- if (m_bytes[i] == '}')
- {
- i++;
- unescaped_content.push_back (m_bytes[i] ^ 0x20);
- }
- else
- {
- unescaped_content.push_back (m_bytes[i]);
- }
- i++;
- }
+ // Smallest possible compressed packet is $N#00 - an uncompressed empty reply,
+ // most commonly indicating
+ // an unsupported packet. Anything less than 5 characters, it's definitely
+ // not a compressed packet.
+ if (pkt_size < 5)
+ return true;
- uint8_t *decompressed_buffer = nullptr;
- size_t decompressed_bytes = 0;
+ if (m_bytes[0] != '$' && m_bytes[0] != '%')
+ return true;
+ if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
+ return true;
- if (decompressed_bufsize != ULONG_MAX)
- {
- decompressed_buffer = (uint8_t *) malloc (decompressed_bufsize + 1);
- if (decompressed_buffer == nullptr)
- {
- m_bytes.erase (0, size_of_first_packet);
- return false;
- }
+ size_t hash_mark_idx = m_bytes.find('#');
+ if (hash_mark_idx == std::string::npos)
+ return true;
+ if (hash_mark_idx + 2 >= m_bytes.size())
+ return true;
- }
+ if (!::isxdigit(m_bytes[hash_mark_idx + 1]) ||
+ !::isxdigit(m_bytes[hash_mark_idx + 2]))
+ return true;
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so check that compression_decode_buffer() is available
- if (compression_decode_buffer != NULL &&
- (m_compression_type == CompressionType::ZlibDeflate
- || m_compression_type == CompressionType::LZFSE
- || m_compression_type == CompressionType::LZ4))
- {
- compression_algorithm compression_type;
- if (m_compression_type == CompressionType::ZlibDeflate)
- compression_type = COMPRESSION_ZLIB;
- else if (m_compression_type == CompressionType::LZFSE)
- compression_type = COMPRESSION_LZFSE;
- else if (m_compression_type == CompressionType::LZ4)
- compression_type = COMPRESSION_LZ4_RAW;
- 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 (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);
- }
+ size_t content_length =
+ pkt_size -
+ 5; // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
+ size_t content_start = 2; // The first character of the
+ // compressed/not-compressed text of the packet
+ size_t checksum_idx =
+ hash_mark_idx +
+ 1; // The first character of the two hex checksum characters
+
+ // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain
+ // multiple packets.
+ // size_of_first_packet is the size of the initial packet which we'll replace
+ // with the decompressed
+ // version of, leaving the rest of m_bytes unmodified.
+ size_t size_of_first_packet = hash_mark_idx + 3;
+
+ // Compressed packets ("$C") start with a base10 number which is the size of
+ // the uncompressed payload,
+ // then a : and then the compressed data. e.g. $C1024:<binary>#00
+ // Update content_start and content_length to only include the <binary> part
+ // of the packet.
+
+ uint64_t decompressed_bufsize = ULONG_MAX;
+ if (m_bytes[1] == 'C') {
+ size_t i = content_start;
+ while (i < hash_mark_idx && isdigit(m_bytes[i]))
+ i++;
+ if (i < hash_mark_idx && m_bytes[i] == ':') {
+ i++;
+ content_start = i;
+ content_length = hash_mark_idx - content_start;
+ std::string bufsize_str(m_bytes.data() + 2, i - 2 - 1);
+ errno = 0;
+ decompressed_bufsize = ::strtoul(bufsize_str.c_str(), NULL, 10);
+ if (errno != 0 || decompressed_bufsize == ULONG_MAX) {
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
+ }
}
-#endif
-
-#if defined (HAVE_LIBZ)
- if (decompressed_bytes == 0
- && decompressed_bufsize != ULONG_MAX
- && decompressed_buffer != nullptr
- && m_compression_type == CompressionType::ZlibDeflate)
- {
- z_stream stream;
- memset (&stream, 0, sizeof (z_stream));
- stream.next_in = (Bytef *) unescaped_content.data();
- stream.avail_in = (uInt) unescaped_content.size();
- stream.total_in = 0;
- stream.next_out = (Bytef *) decompressed_buffer;
- stream.avail_out = decompressed_bufsize;
- stream.total_out = 0;
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- if (inflateInit2 (&stream, -15) == Z_OK)
- {
- int status = inflate (&stream, Z_NO_FLUSH);
- inflateEnd (&stream);
- if (status == Z_STREAM_END)
- {
- decompressed_bytes = stream.total_out;
- }
- }
+ }
+
+ if (GetSendAcks()) {
+ char packet_checksum_cstr[3];
+ packet_checksum_cstr[0] = m_bytes[checksum_idx];
+ packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
+ packet_checksum_cstr[2] = '\0';
+ long packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+
+ long actual_checksum = CalculcateChecksum(
+ llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1));
+ bool success = packet_checksum == actual_checksum;
+ if (!success) {
+ if (log)
+ log->Printf(
+ "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
+ (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum,
+ (uint8_t)actual_checksum);
}
-#endif
+ // Send the ack or nack if needed
+ if (!success) {
+ SendNack();
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
+ } else {
+ SendAck();
+ }
+ }
- if (decompressed_bytes == 0 || decompressed_buffer == nullptr)
- {
- if (decompressed_buffer)
- free (decompressed_buffer);
- m_bytes.erase (0, size_of_first_packet);
- return false;
+ if (m_bytes[1] == 'N') {
+ // This packet was not compressed -- delete the 'N' character at the
+ // start and the packet may be processed as-is.
+ m_bytes.erase(1, 1);
+ return true;
+ }
+
+ // Reverse the gdb-remote binary escaping that was done to the compressed text
+ // to
+ // guard characters like '$', '#', '}', etc.
+ std::vector<uint8_t> unescaped_content;
+ unescaped_content.reserve(content_length);
+ size_t i = content_start;
+ while (i < hash_mark_idx) {
+ if (m_bytes[i] == '}') {
+ i++;
+ unescaped_content.push_back(m_bytes[i] ^ 0x20);
+ } else {
+ unescaped_content.push_back(m_bytes[i]);
}
+ i++;
+ }
+
+ uint8_t *decompressed_buffer = nullptr;
+ size_t decompressed_bytes = 0;
- std::string new_packet;
- new_packet.reserve (decompressed_bytes + 6);
- new_packet.push_back (m_bytes[0]);
- new_packet.append ((const char *) decompressed_buffer, decompressed_bytes);
- new_packet.push_back ('#');
- if (GetSendAcks ())
- {
- uint8_t decompressed_checksum = CalculcateChecksum ((const char *) decompressed_buffer, decompressed_bytes);
- char decompressed_checksum_str[3];
- snprintf (decompressed_checksum_str, 3, "%02x", decompressed_checksum);
- new_packet.append (decompressed_checksum_str);
+ if (decompressed_bufsize != ULONG_MAX) {
+ decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize + 1);
+ if (decompressed_buffer == nullptr) {
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
}
- else
- {
- new_packet.push_back ('0');
- new_packet.push_back ('0');
+ }
+
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so check that compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ (m_compression_type == CompressionType::ZlibDeflate ||
+ m_compression_type == CompressionType::LZFSE ||
+ m_compression_type == CompressionType::LZ4)) {
+ compression_algorithm compression_type;
+ if (m_compression_type == CompressionType::ZlibDeflate)
+ compression_type = COMPRESSION_ZLIB;
+ else if (m_compression_type == CompressionType::LZFSE)
+ compression_type = COMPRESSION_LZFSE;
+ else if (m_compression_type == CompressionType::LZ4)
+ compression_type = COMPRESSION_LZ4_RAW;
+ 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 (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);
}
+ }
+#endif
- m_bytes.replace (0, size_of_first_packet, new_packet.data(), new_packet.size());
+#if defined(HAVE_LIBZ)
+ if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX &&
+ decompressed_buffer != nullptr &&
+ m_compression_type == CompressionType::ZlibDeflate) {
+ z_stream stream;
+ memset(&stream, 0, sizeof(z_stream));
+ stream.next_in = (Bytef *)unescaped_content.data();
+ stream.avail_in = (uInt)unescaped_content.size();
+ stream.total_in = 0;
+ stream.next_out = (Bytef *)decompressed_buffer;
+ stream.avail_out = decompressed_bufsize;
+ stream.total_out = 0;
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ if (inflateInit2(&stream, -15) == Z_OK) {
+ int status = inflate(&stream, Z_NO_FLUSH);
+ inflateEnd(&stream);
+ if (status == Z_STREAM_END) {
+ decompressed_bytes = stream.total_out;
+ }
+ }
+ }
+#endif
- free (decompressed_buffer);
- return true;
+ if (decompressed_bytes == 0 || decompressed_buffer == nullptr) {
+ if (decompressed_buffer)
+ free(decompressed_buffer);
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
+ }
+
+ std::string new_packet;
+ new_packet.reserve(decompressed_bytes + 6);
+ new_packet.push_back(m_bytes[0]);
+ new_packet.append((const char *)decompressed_buffer, decompressed_bytes);
+ new_packet.push_back('#');
+ if (GetSendAcks()) {
+ uint8_t decompressed_checksum = CalculcateChecksum(
+ llvm::StringRef((const char *)decompressed_buffer, decompressed_bytes));
+ char decompressed_checksum_str[3];
+ snprintf(decompressed_checksum_str, 3, "%02x", decompressed_checksum);
+ new_packet.append(decompressed_checksum_str);
+ } else {
+ new_packet.push_back('0');
+ new_packet.push_back('0');
+ }
+
+ m_bytes.replace(0, size_of_first_packet, new_packet.data(),
+ new_packet.size());
+
+ free(decompressed_buffer);
+ return true;
}
GDBRemoteCommunication::PacketType
-GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
-{
- // Put the packet data into the buffer in a thread safe fashion
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
-
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-
- if (src && src_len > 0)
- {
- if (log && log->GetVerbose())
- {
- StreamString s;
- log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s",
- __FUNCTION__,
- (uint32_t)src_len,
- (uint32_t)src_len,
- src);
- }
- m_bytes.append ((const char *)src, src_len);
+GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
+ StringExtractorGDBRemote &packet) {
+ // Put the packet data into the buffer in a thread safe fashion
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+
+ if (src && src_len > 0) {
+ if (log && log->GetVerbose()) {
+ StreamString s;
+ log->Printf("GDBRemoteCommunication::%s adding %u bytes: %.*s",
+ __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
+ }
+ m_bytes.append((const char *)src, src_len);
+ }
+
+ bool isNotifyPacket = false;
+
+ // Parse up the packets into gdb remote packets
+ if (!m_bytes.empty()) {
+ // end_idx must be one past the last valid packet byte. Start
+ // it off with an invalid value that is the same as the current
+ // index.
+ size_t content_start = 0;
+ size_t content_length = 0;
+ size_t total_length = 0;
+ size_t checksum_idx = std::string::npos;
+
+ // Size of packet before it is decompressed, for logging purposes
+ size_t original_packet_size = m_bytes.size();
+ if (CompressionIsEnabled()) {
+ if (DecompressPacket() == false) {
+ packet.Clear();
+ return GDBRemoteCommunication::PacketType::Standard;
+ }
}
- bool isNotifyPacket = false;
-
- // Parse up the packets into gdb remote packets
- if (!m_bytes.empty())
- {
- // end_idx must be one past the last valid packet byte. Start
- // it off with an invalid value that is the same as the current
- // index.
- size_t content_start = 0;
- size_t content_length = 0;
- size_t total_length = 0;
- size_t checksum_idx = std::string::npos;
-
- // Size of packet before it is decompressed, for logging purposes
- size_t original_packet_size = m_bytes.size();
- if (CompressionIsEnabled())
- {
- if (DecompressPacket() == false)
- {
- packet.Clear();
- return GDBRemoteCommunication::PacketType::Standard;
- }
+ switch (m_bytes[0]) {
+ case '+': // Look for ack
+ case '-': // Look for cancel
+ case '\x03': // ^C to halt target
+ content_length = total_length = 1; // The command is one byte long...
+ break;
+
+ case '%': // Async notify packet
+ isNotifyPacket = true;
+ LLVM_FALLTHROUGH;
+
+ case '$':
+ // Look for a standard gdb packet?
+ {
+ size_t hash_pos = m_bytes.find('#');
+ if (hash_pos != std::string::npos) {
+ if (hash_pos + 2 < m_bytes.size()) {
+ checksum_idx = hash_pos + 1;
+ // Skip the dollar sign
+ content_start = 1;
+ // Don't include the # in the content or the $ in the content length
+ content_length = hash_pos - 1;
+
+ total_length =
+ hash_pos + 3; // Skip the # and the two hex checksum bytes
+ } else {
+ // Checksum bytes aren't all here yet
+ content_length = std::string::npos;
+ }
}
-
- switch (m_bytes[0])
- {
- case '+': // Look for ack
- case '-': // Look for cancel
- case '\x03': // ^C to halt target
- content_length = total_length = 1; // The command is one byte long...
- break;
-
- case '%': // Async notify packet
- isNotifyPacket = true;
- LLVM_FALLTHROUGH;
-
- case '$':
- // Look for a standard gdb packet?
- {
- size_t hash_pos = m_bytes.find('#');
- if (hash_pos != std::string::npos)
- {
- if (hash_pos + 2 < m_bytes.size())
- {
- checksum_idx = hash_pos + 1;
- // Skip the dollar sign
- content_start = 1;
- // Don't include the # in the content or the $ in the content length
- content_length = hash_pos - 1;
-
- total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
- }
- else
- {
- // Checksum bytes aren't all here yet
- content_length = std::string::npos;
- }
- }
- }
- break;
-
- default:
- {
- // We have an unexpected byte and we need to flush all bad
- // data that is in m_bytes, so we need to find the first
- // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
- // or '$' character (start of packet header) or of course,
- // the end of the data in m_bytes...
- const size_t bytes_len = m_bytes.size();
- bool done = false;
- uint32_t idx;
- for (idx = 1; !done && idx < bytes_len; ++idx)
- {
- switch (m_bytes[idx])
- {
- case '+':
- case '-':
- case '\x03':
- case '%':
- case '$':
- done = true;
- break;
-
- default:
- break;
- }
- }
- if (log)
- log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
- __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
- m_bytes.erase(0, idx - 1);
- }
- break;
+ }
+ break;
+
+ default: {
+ // We have an unexpected byte and we need to flush all bad
+ // data that is in m_bytes, so we need to find the first
+ // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
+ // or '$' character (start of packet header) or of course,
+ // the end of the data in m_bytes...
+ const size_t bytes_len = m_bytes.size();
+ bool done = false;
+ uint32_t idx;
+ for (idx = 1; !done && idx < bytes_len; ++idx) {
+ switch (m_bytes[idx]) {
+ case '+':
+ case '-':
+ case '\x03':
+ case '%':
+ case '$':
+ done = true;
+ break;
+
+ default:
+ break;
}
+ }
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
+ __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
+ m_bytes.erase(0, idx - 1);
+ } break;
+ }
- if (content_length == std::string::npos)
- {
- packet.Clear();
- return GDBRemoteCommunication::PacketType::Invalid;
- }
- else if (total_length > 0)
- {
-
- // We have a valid packet...
- assert (content_length <= m_bytes.size());
- assert (total_length <= m_bytes.size());
- assert (content_length <= total_length);
- size_t content_end = content_start + content_length;
-
- bool success = true;
- std::string &packet_str = packet.GetStringRef();
- if (log)
- {
- // If logging was just enabled and we have history, then dump out what
- // we have to the log so we get the historical context. The Dump() call that
- // logs all of the packet will set a boolean so that we don't dump this more
- // than once
- if (!m_history.DidDumpToLog ())
- m_history.Dump (log);
-
- bool binary = false;
- // Only detect binary for packets that start with a '$' and have a '#CC' checksum
- if (m_bytes[0] == '$' && total_length > 4)
- {
- for (size_t i=0; !binary && i<total_length; ++i)
- {
- if (isprint (m_bytes[i]) == 0 && isspace (m_bytes[i]) == 0)
- {
- binary = true;
- }
- }
- }
- if (binary)
- {
- StreamString strm;
- // Packet header...
- if (CompressionIsEnabled())
- strm.Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %c", (uint64_t) original_packet_size, (uint64_t)total_length, m_bytes[0]);
- else
- strm.Printf("<%4" PRIu64 "> read packet: %c", (uint64_t)total_length, m_bytes[0]);
- for (size_t i=content_start; i<content_end; ++i)
- {
- // Remove binary escaped bytes when displaying the packet...
- const char ch = m_bytes[i];
- if (ch == 0x7d)
- {
- // 0x7d is the escape character. The next character is to
- // be XOR'd with 0x20.
- const char escapee = m_bytes[++i] ^ 0x20;
- strm.Printf("%2.2x", escapee);
- }
- else
- {
- strm.Printf("%2.2x", (uint8_t)ch);
- }
- }
- // Packet footer...
- strm.Printf("%c%c%c", m_bytes[total_length-3], m_bytes[total_length-2], m_bytes[total_length-1]);
- log->PutCString(strm.GetString().c_str());
- }
- else
- {
- if (CompressionIsEnabled())
- log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s", (uint64_t) original_packet_size, (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
- else
- log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
- }
+ if (content_length == std::string::npos) {
+ packet.Clear();
+ return GDBRemoteCommunication::PacketType::Invalid;
+ } else if (total_length > 0) {
+
+ // We have a valid packet...
+ assert(content_length <= m_bytes.size());
+ assert(total_length <= m_bytes.size());
+ assert(content_length <= total_length);
+ size_t content_end = content_start + content_length;
+
+ bool success = true;
+ std::string &packet_str = packet.GetStringRef();
+ if (log) {
+ // If logging was just enabled and we have history, then dump out what
+ // we have to the log so we get the historical context. The Dump() call
+ // that
+ // logs all of the packet will set a boolean so that we don't dump this
+ // more
+ // than once
+ if (!m_history.DidDumpToLog())
+ m_history.Dump(log);
+
+ bool binary = false;
+ // Only detect binary for packets that start with a '$' and have a '#CC'
+ // checksum
+ if (m_bytes[0] == '$' && total_length > 4) {
+ for (size_t i = 0; !binary && i < total_length; ++i) {
+ if (isprint(m_bytes[i]) == 0 && isspace(m_bytes[i]) == 0) {
+ binary = true;
}
-
- m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
-
- // Clear packet_str in case there is some existing data in it.
- packet_str.clear();
- // Copy the packet from m_bytes to packet_str expanding the
- // run-length encoding in the process.
- // Reserve enough byte for the most common case (no RLE used)
- packet_str.reserve(m_bytes.length());
- for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c)
- {
- if (*c == '*')
- {
- // '*' indicates RLE. Next character will give us the
- // repeat count and previous character is what is to be
- // repeated.
- char char_to_repeat = packet_str.back();
- // Number of time the previous character is repeated
- int repeat_count = *++c + 3 - ' ';
- // We have the char_to_repeat and repeat_count. Now push
- // it in the packet.
- for (int i = 0; i < repeat_count; ++i)
- packet_str.push_back(char_to_repeat);
- }
- else if (*c == 0x7d)
- {
- // 0x7d is the escape character. The next character is to
- // be XOR'd with 0x20.
- char escapee = *++c ^ 0x20;
- packet_str.push_back(escapee);
- }
- else
- {
- packet_str.push_back(*c);
- }
+ }
+ }
+ if (binary) {
+ StreamString strm;
+ // Packet header...
+ if (CompressionIsEnabled())
+ strm.Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %c",
+ (uint64_t)original_packet_size, (uint64_t)total_length,
+ m_bytes[0]);
+ else
+ strm.Printf("<%4" PRIu64 "> read packet: %c",
+ (uint64_t)total_length, m_bytes[0]);
+ for (size_t i = content_start; i < content_end; ++i) {
+ // Remove binary escaped bytes when displaying the packet...
+ const char ch = m_bytes[i];
+ if (ch == 0x7d) {
+ // 0x7d is the escape character. The next character is to
+ // be XOR'd with 0x20.
+ const char escapee = m_bytes[++i] ^ 0x20;
+ strm.Printf("%2.2x", escapee);
+ } else {
+ strm.Printf("%2.2x", (uint8_t)ch);
}
-
- if (m_bytes[0] == '$' || m_bytes[0] == '%')
- {
- assert (checksum_idx < m_bytes.size());
- if (::isxdigit (m_bytes[checksum_idx+0]) ||
- ::isxdigit (m_bytes[checksum_idx+1]))
- {
- if (GetSendAcks ())
- {
- const char *packet_checksum_cstr = &m_bytes[checksum_idx];
- char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
- char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
- success = packet_checksum == actual_checksum;
- if (!success)
- {
- if (log)
- log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
- (int)(total_length),
- m_bytes.c_str(),
- (uint8_t)packet_checksum,
- (uint8_t)actual_checksum);
- }
- // Send the ack or nack if needed
- if (!success)
- SendNack();
- else
- SendAck();
- }
- }
- else
- {
- success = false;
- if (log)
- log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
- }
+ }
+ // Packet footer...
+ strm.Printf("%c%c%c", m_bytes[total_length - 3],
+ m_bytes[total_length - 2], m_bytes[total_length - 1]);
+ log->PutString(strm.GetString());
+ } else {
+ if (CompressionIsEnabled())
+ log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s",
+ (uint64_t)original_packet_size, (uint64_t)total_length,
+ (int)(total_length), m_bytes.c_str());
+ else
+ log->Printf("<%4" PRIu64 "> read packet: %.*s",
+ (uint64_t)total_length, (int)(total_length),
+ m_bytes.c_str());
+ }
+ }
+
+ m_history.AddPacket(m_bytes, total_length, History::ePacketTypeRecv,
+ total_length);
+
+ // Clear packet_str in case there is some existing data in it.
+ packet_str.clear();
+ // Copy the packet from m_bytes to packet_str expanding the
+ // run-length encoding in the process.
+ // Reserve enough byte for the most common case (no RLE used)
+ packet_str.reserve(m_bytes.length());
+ for (std::string::const_iterator c = m_bytes.begin() + content_start;
+ c != m_bytes.begin() + content_end; ++c) {
+ if (*c == '*') {
+ // '*' indicates RLE. Next character will give us the
+ // repeat count and previous character is what is to be
+ // repeated.
+ char char_to_repeat = packet_str.back();
+ // Number of time the previous character is repeated
+ int repeat_count = *++c + 3 - ' ';
+ // We have the char_to_repeat and repeat_count. Now push
+ // it in the packet.
+ for (int i = 0; i < repeat_count; ++i)
+ packet_str.push_back(char_to_repeat);
+ } else if (*c == 0x7d) {
+ // 0x7d is the escape character. The next character is to
+ // be XOR'd with 0x20.
+ char escapee = *++c ^ 0x20;
+ packet_str.push_back(escapee);
+ } else {
+ packet_str.push_back(*c);
+ }
+ }
+
+ if (m_bytes[0] == '$' || m_bytes[0] == '%') {
+ assert(checksum_idx < m_bytes.size());
+ if (::isxdigit(m_bytes[checksum_idx + 0]) ||
+ ::isxdigit(m_bytes[checksum_idx + 1])) {
+ if (GetSendAcks()) {
+ const char *packet_checksum_cstr = &m_bytes[checksum_idx];
+ char packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+ char actual_checksum = CalculcateChecksum(packet_str);
+ success = packet_checksum == actual_checksum;
+ if (!success) {
+ if (log)
+ log->Printf("error: checksum mismatch: %.*s expected 0x%2.2x, "
+ "got 0x%2.2x",
+ (int)(total_length), m_bytes.c_str(),
+ (uint8_t)packet_checksum, (uint8_t)actual_checksum);
}
-
- m_bytes.erase(0, total_length);
- packet.SetFilePos(0);
-
- if (isNotifyPacket)
- return GDBRemoteCommunication::PacketType::Notify;
+ // Send the ack or nack if needed
+ if (!success)
+ SendNack();
else
- return GDBRemoteCommunication::PacketType::Standard;
+ SendAck();
+ }
+ } else {
+ success = false;
+ if (log)
+ log->Printf("error: invalid checksum in packet: '%s'\n",
+ m_bytes.c_str());
}
+ }
+
+ m_bytes.erase(0, total_length);
+ packet.SetFilePos(0);
+
+ if (isNotifyPacket)
+ return GDBRemoteCommunication::PacketType::Notify;
+ else
+ return GDBRemoteCommunication::PacketType::Standard;
}
- packet.Clear();
- return GDBRemoteCommunication::PacketType::Invalid;
+ }
+ packet.Clear();
+ return GDBRemoteCommunication::PacketType::Invalid;
}
-Error
-GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
-{
- Error error;
- if (m_listen_thread.IsJoinable())
- {
- error.SetErrorString("listen thread already running");
- }
+Error GDBRemoteCommunication::StartListenThread(const char *hostname,
+ uint16_t port) {
+ Error error;
+ if (m_listen_thread.IsJoinable()) {
+ error.SetErrorString("listen thread already running");
+ } else {
+ char listen_url[512];
+ if (hostname && hostname[0])
+ snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname,
+ port);
else
- {
- char listen_url[512];
- if (hostname && hostname[0])
- snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
- else
- snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
- m_listen_url = listen_url;
- SetConnection(new ConnectionFileDescriptor());
- m_listen_thread = ThreadLauncher::LaunchThread(listen_url, GDBRemoteCommunication::ListenThread, this, &error);
- }
- return error;
+ snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
+ m_listen_url = listen_url;
+ SetConnection(new ConnectionFileDescriptor());
+ m_listen_thread = ThreadLauncher::LaunchThread(
+ listen_url, GDBRemoteCommunication::ListenThread, this, &error);
+ }
+ return error;
}
-bool
-GDBRemoteCommunication::JoinListenThread ()
-{
- if (m_listen_thread.IsJoinable())
- m_listen_thread.Join(nullptr);
- return true;
+bool GDBRemoteCommunication::JoinListenThread() {
+ if (m_listen_thread.IsJoinable())
+ m_listen_thread.Join(nullptr);
+ return true;
}
lldb::thread_result_t
-GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
-{
- GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
- Error error;
- ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
-
- if (connection)
- {
- // Do the listen on another thread so we can continue on...
- if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
- comm->SetConnection(NULL);
- }
- return NULL;
+GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) {
+ GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
+ Error error;
+ ConnectionFileDescriptor *connection =
+ (ConnectionFileDescriptor *)comm->GetConnection();
+
+ if (connection) {
+ // Do the listen on another thread so we can continue on...
+ if (connection->Connect(comm->m_listen_url.c_str(), &error) !=
+ eConnectionStatusSuccess)
+ comm->SetConnection(NULL);
+ }
+ return NULL;
}
-Error
-GDBRemoteCommunication::StartDebugserverProcess (const char *url,
- Platform *platform,
- ProcessLaunchInfo &launch_info,
- uint16_t *port,
- const Args& inferior_args)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+Error GDBRemoteCommunication::StartDebugserverProcess(
+ const char *url, Platform *platform, ProcessLaunchInfo &launch_info,
+ uint16_t *port, const Args *inferior_args, int pass_comm_fd) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")",
+ __FUNCTION__, url ? url : "<empty>",
+ port ? *port : uint16_t(0));
+
+ Error error;
+ // If we locate debugserver, keep that located version around
+ static FileSpec g_debugserver_file_spec;
+
+ char debugserver_path[PATH_MAX];
+ FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
+
+ // Always check to see if we have an environment override for the path
+ // to the debugserver to use and use it if we do.
+ const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
+ if (env_debugserver_path) {
+ debugserver_file_spec.SetFile(env_debugserver_path, false);
if (log)
- log->Printf ("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")", __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));
-
- Error error;
- // If we locate debugserver, keep that located version around
- static FileSpec g_debugserver_file_spec;
-
- char debugserver_path[PATH_MAX];
- FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
-
- // Always check to see if we have an environment override for the path
- // to the debugserver to use and use it if we do.
- const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
- if (env_debugserver_path)
- {
- debugserver_file_spec.SetFile (env_debugserver_path, false);
+ log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
+ "from environment variable: %s",
+ __FUNCTION__, env_debugserver_path);
+ } else
+ debugserver_file_spec = g_debugserver_file_spec;
+ bool debugserver_exists = debugserver_file_spec.Exists();
+ if (!debugserver_exists) {
+ // The debugserver binary is in the LLDB.framework/Resources
+ // directory.
+ if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir,
+ debugserver_file_spec)) {
+ debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
+ debugserver_exists = debugserver_file_spec.Exists();
+ if (debugserver_exists) {
if (log)
- log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path);
- }
- else
- debugserver_file_spec = g_debugserver_file_spec;
- bool debugserver_exists = debugserver_file_spec.Exists();
- if (!debugserver_exists)
- {
- // The debugserver binary is in the LLDB.framework/Resources
- // directory.
- if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, debugserver_file_spec))
- {
- debugserver_file_spec.AppendPathComponent (DEBUGSERVER_BASENAME);
- debugserver_exists = debugserver_file_spec.Exists();
- if (debugserver_exists)
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
-
- g_debugserver_file_spec = debugserver_file_spec;
- }
- else
- {
- debugserver_file_spec = platform->LocateExecutable(DEBUGSERVER_BASENAME);
- if (debugserver_file_spec)
- {
- // Platform::LocateExecutable() wouldn't return a path if it doesn't exist
- debugserver_exists = true;
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
- }
- // Don't cache the platform specific GDB server binary as it could change
- // from platform to platform
- g_debugserver_file_spec.Clear();
- }
+ log->Printf(
+ "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
+
+ g_debugserver_file_spec = debugserver_file_spec;
+ } else {
+ debugserver_file_spec =
+ platform->LocateExecutable(DEBUGSERVER_BASENAME);
+ if (debugserver_file_spec) {
+ // Platform::LocateExecutable() wouldn't return a path if it doesn't
+ // exist
+ debugserver_exists = true;
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() could not find "
+ "gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
}
+ // Don't cache the platform specific GDB server binary as it could
+ // change
+ // from platform to platform
+ g_debugserver_file_spec.Clear();
+ }
}
-
- if (debugserver_exists)
- {
- debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
+ }
+
+ if (debugserver_exists) {
+ debugserver_file_spec.GetPath(debugserver_path, sizeof(debugserver_path));
- Args &debugserver_args = launch_info.GetArguments();
- debugserver_args.Clear();
- char arg_cstr[PATH_MAX];
+ Args &debugserver_args = launch_info.GetArguments();
+ debugserver_args.Clear();
+ char arg_cstr[PATH_MAX];
- // Start args with "debugserver /file/path -r --"
- debugserver_args.AppendArgument(debugserver_path);
+ // Start args with "debugserver /file/path -r --"
+ debugserver_args.AppendArgument(llvm::StringRef(debugserver_path));
#if !defined(__APPLE__)
- // First argument to lldb-server must be mode in which to run.
- debugserver_args.AppendArgument("gdbserver");
+ // First argument to lldb-server must be mode in which to run.
+ debugserver_args.AppendArgument(llvm::StringRef("gdbserver"));
#endif
- // If a url is supplied then use it
- if (url)
- debugserver_args.AppendArgument(url);
+ // If a url is supplied then use it
+ if (url)
+ debugserver_args.AppendArgument(llvm::StringRef(url));
+
+ if (pass_comm_fd >= 0) {
+ StreamString fd_arg;
+ fd_arg.Printf("--fd=%i", pass_comm_fd);
+ debugserver_args.AppendArgument(fd_arg.GetString());
+ // Send "pass_comm_fd" down to the inferior so it can use it to
+ // communicate back with this process
+ launch_info.AppendDuplicateFileAction(pass_comm_fd, pass_comm_fd);
+ }
- // use native registers, not the GDB registers
- debugserver_args.AppendArgument("--native-regs");
+ // use native registers, not the GDB registers
+ debugserver_args.AppendArgument(llvm::StringRef("--native-regs"));
- if (launch_info.GetLaunchInSeparateProcessGroup())
- {
- debugserver_args.AppendArgument("--setsid");
- }
+ if (launch_info.GetLaunchInSeparateProcessGroup()) {
+ debugserver_args.AppendArgument(llvm::StringRef("--setsid"));
+ }
- llvm::SmallString<PATH_MAX> 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 -
- // once data is written to the pipe, debug server is up and running.
- Pipe socket_pipe;
-
- // port is null when debug server should listen on domain socket -
- // we're not interested in port value but rather waiting for debug server
- // to become available.
- if ((port != nullptr && *port == 0) || port == nullptr)
- {
- if (url)
- {
- // Create a temporary file to get the stdout/stderr and redirect the
- // output of the command into this file. We will later read this file
- // if all goes well and fill the data into "command_output_ptr"
-
-#if defined(__APPLE__)
- // Binding to port zero, we need to figure out what port it ends up
- // using using a named pipe...
- error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
- if (error.Fail())
- {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "named pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- debugserver_args.AppendArgument("--named-pipe");
- debugserver_args.AppendArgument(named_pipe_path.c_str());
-#else
- // Binding to port zero, we need to figure out what port it ends up
- // using using an unnamed pipe...
- error = socket_pipe.CreateNew(true);
- if (error.Fail())
- {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "unnamed pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- int write_fd = socket_pipe.GetWriteFileDescriptor();
- debugserver_args.AppendArgument("--pipe");
- debugserver_args.AppendArgument(std::to_string(write_fd).c_str());
- launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
-#endif
- }
- else
- {
- // No host and port given, so lets listen on our end and make the debugserver
- // connect to us..
- error = StartListenThread ("127.0.0.1", 0);
- if (error.Fail())
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() unable to start listen thread: %s", __FUNCTION__, error.AsCString());
- return error;
- }
-
- ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
- // Wait for 10 seconds to resolve the bound port
- *port = connection->GetListeningPort(10);
- if (*port > 0)
- {
- char port_cstr[32];
- snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", *port);
- // Send the host and port down that debugserver and specify an option
- // so that it connects back to the port we are listening to in this process
- debugserver_args.AppendArgument("--reverse-connect");
- debugserver_args.AppendArgument(port_cstr);
- }
- else
- {
- error.SetErrorString ("failed to bind to port 0 on 127.0.0.1");
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
- return error;
- }
- }
- }
-
- const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
- if (env_debugserver_log_file)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
- debugserver_args.AppendArgument(arg_cstr);
- }
-
+ llvm::SmallString<PATH_MAX> 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 -
+ // once data is written to the pipe, debug server is up and running.
+ Pipe socket_pipe;
+
+ // port is null when debug server should listen on domain socket -
+ // we're not interested in port value but rather waiting for debug server
+ // to become available.
+ if (pass_comm_fd == -1 &&
+ ((port != nullptr && *port == 0) || port == nullptr)) {
+ if (url) {
+// Create a temporary file to get the stdout/stderr and redirect the
+// output of the command into this file. We will later read this file
+// if all goes well and fill the data into "command_output_ptr"
#if defined(__APPLE__)
- const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
- if (env_debugserver_log_flags)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
- debugserver_args.AppendArgument(arg_cstr);
+ // Binding to port zero, we need to figure out what port it ends up
+ // using using a named pipe...
+ error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe",
+ false, named_pipe_path);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "named pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
}
+ debugserver_args.AppendArgument(llvm::StringRef("--named-pipe"));
+ debugserver_args.AppendArgument(named_pipe_path);
#else
- const char *env_debugserver_log_channels = getenv("LLDB_SERVER_LOG_CHANNELS");
- if (env_debugserver_log_channels)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-channels=%s", env_debugserver_log_channels);
- debugserver_args.AppendArgument(arg_cstr);
+ // Binding to port zero, we need to figure out what port it ends up
+ // using using an unnamed pipe...
+ error = socket_pipe.CreateNew(true);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "unnamed pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
}
+ int write_fd = socket_pipe.GetWriteFileDescriptor();
+ debugserver_args.AppendArgument(llvm::StringRef("--pipe"));
+ debugserver_args.AppendArgument(llvm::to_string(write_fd));
+ launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
#endif
-
- // Add additional args, starting with LLDB_DEBUGSERVER_EXTRA_ARG_1 until an env var doesn't come back.
- uint32_t env_var_index = 1;
- bool has_env_var;
- do
- {
- char env_var_name[64];
- snprintf (env_var_name, sizeof (env_var_name), "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
- const char *extra_arg = getenv(env_var_name);
- has_env_var = extra_arg != nullptr;
-
- if (has_env_var)
- {
- debugserver_args.AppendArgument (extra_arg);
- if (log)
- log->Printf ("GDBRemoteCommunication::%s adding env var %s contents to stub command line (%s)", __FUNCTION__, env_var_name, extra_arg);
- }
- } while (has_env_var);
-
- if (inferior_args.GetArgumentCount() > 0)
- {
- debugserver_args.AppendArgument ("--");
- debugserver_args.AppendArguments (inferior_args);
+ } else {
+ // No host and port given, so lets listen on our end and make the
+ // debugserver
+ // connect to us..
+ error = StartListenThread("127.0.0.1", 0);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() unable to start listen "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
}
- // Copy the current environment to the gdbserver/debugserver instance
- StringList env;
- if (Host::GetEnvironment(env))
- {
- for (size_t i = 0; i < env.GetSize(); ++i)
- launch_info.GetEnvironmentEntries().AppendArgument(env[i].c_str());
+ ConnectionFileDescriptor *connection =
+ (ConnectionFileDescriptor *)GetConnection();
+ // Wait for 10 seconds to resolve the bound port
+ uint16_t port_ = connection->GetListeningPort(10);
+ if (port_ > 0) {
+ char port_cstr[32];
+ snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", port_);
+ // Send the host and port down that debugserver and specify an option
+ // so that it connects back to the port we are listening to in this
+ // process
+ debugserver_args.AppendArgument(llvm::StringRef("--reverse-connect"));
+ debugserver_args.AppendArgument(llvm::StringRef(port_cstr));
+ if (port)
+ *port = port_;
+ } else {
+ error.SetErrorString("failed to bind to port 0 on 127.0.0.1");
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
+ return error;
}
+ }
+ }
- // Close STDIN, STDOUT and STDERR.
- launch_info.AppendCloseFileAction (STDIN_FILENO);
- launch_info.AppendCloseFileAction (STDOUT_FILENO);
- launch_info.AppendCloseFileAction (STDERR_FILENO);
+ const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
+ if (env_debugserver_log_file) {
+ ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-file=%s",
+ env_debugserver_log_file);
+ debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ }
- // Redirect STDIN, STDOUT and STDERR to "/dev/null".
- launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
- launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
- launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
+#if defined(__APPLE__)
+ const char *env_debugserver_log_flags =
+ getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
+ if (env_debugserver_log_flags) {
+ ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-flags=%s",
+ env_debugserver_log_flags);
+ debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ }
+#else
+ const char *env_debugserver_log_channels =
+ getenv("LLDB_SERVER_LOG_CHANNELS");
+ if (env_debugserver_log_channels) {
+ ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-channels=%s",
+ env_debugserver_log_channels);
+ debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ }
+#endif
+ // Add additional args, starting with LLDB_DEBUGSERVER_EXTRA_ARG_1 until an
+ // env var doesn't come back.
+ uint32_t env_var_index = 1;
+ bool has_env_var;
+ do {
+ char env_var_name[64];
+ snprintf(env_var_name, sizeof(env_var_name),
+ "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
+ const char *extra_arg = getenv(env_var_name);
+ has_env_var = extra_arg != nullptr;
+
+ if (has_env_var) {
+ debugserver_args.AppendArgument(llvm::StringRef(extra_arg));
if (log)
- {
- StreamString string_stream;
- Platform *const platform = nullptr;
- launch_info.Dump(string_stream, platform);
- log->Printf("launch info for gdb-remote stub:\n%s", string_stream.GetString().c_str());
- }
- error = Host::LaunchProcess(launch_info);
-
- if (error.Success() &&
- launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- {
- if (named_pipe_path.size() > 0)
- {
- error = socket_pipe.OpenAsReader(named_pipe_path, false);
- if (error.Fail())
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to open named pipe %s for reading: %s",
- __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
- }
-
- if (socket_pipe.CanWrite())
- socket_pipe.CloseWriteFileDescriptor();
- if (socket_pipe.CanRead())
- {
- char port_cstr[PATH_MAX] = {0};
- port_cstr[0] = '\0';
- size_t num_bytes = sizeof(port_cstr);
- // Read port from pipe with 10 second timeout.
- error = socket_pipe.ReadWithTimeout(port_cstr, num_bytes,
- std::chrono::seconds{10}, num_bytes);
- if (error.Success() && (port != nullptr))
- {
- assert(num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
- *port = StringConvert::ToUInt32(port_cstr, 0);
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "debugserver listens %u port",
- __FUNCTION__, *port);
- }
- else
- {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to read a port value from pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
-
- }
- socket_pipe.Close();
- }
-
- if (named_pipe_path.size() > 0)
- {
- const auto err = socket_pipe.Delete(named_pipe_path);
- if (err.Fail())
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
- }
- }
+ log->Printf("GDBRemoteCommunication::%s adding env var %s contents "
+ "to stub command line (%s)",
+ __FUNCTION__, env_var_name, extra_arg);
+ }
+ } while (has_env_var);
+
+ if (inferior_args && inferior_args->GetArgumentCount() > 0) {
+ debugserver_args.AppendArgument(llvm::StringRef("--"));
+ debugserver_args.AppendArguments(*inferior_args);
+ }
- // Make sure we actually connect with the debugserver...
- JoinListenThread();
- }
+ // Copy the current environment to the gdbserver/debugserver instance
+ StringList env;
+ if (Host::GetEnvironment(env)) {
+ for (size_t i = 0; i < env.GetSize(); ++i)
+ launch_info.GetEnvironmentEntries().AppendArgument(env[i]);
}
- else
- {
- error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
+
+ // Close STDIN, STDOUT and STDERR.
+ launch_info.AppendCloseFileAction(STDIN_FILENO);
+ launch_info.AppendCloseFileAction(STDOUT_FILENO);
+ launch_info.AppendCloseFileAction(STDERR_FILENO);
+
+ // Redirect STDIN, STDOUT and STDERR to "/dev/null".
+ launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
+ launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true);
+ launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true);
+
+ if (log) {
+ StreamString string_stream;
+ Platform *const platform = nullptr;
+ launch_info.Dump(string_stream, platform);
+ log->Printf("launch info for gdb-remote stub:\n%s",
+ string_stream.GetData());
}
+ error = Host::LaunchProcess(launch_info);
+
+ if (error.Success() &&
+ (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) &&
+ pass_comm_fd == -1) {
+ if (named_pipe_path.size() > 0) {
+ error = socket_pipe.OpenAsReader(named_pipe_path, false);
+ if (error.Fail())
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "failed to open named pipe %s for reading: %s",
+ __FUNCTION__, named_pipe_path.c_str(),
+ error.AsCString());
+ }
+
+ if (socket_pipe.CanWrite())
+ socket_pipe.CloseWriteFileDescriptor();
+ if (socket_pipe.CanRead()) {
+ char port_cstr[PATH_MAX] = {0};
+ port_cstr[0] = '\0';
+ size_t num_bytes = sizeof(port_cstr);
+ // Read port from pipe with 10 second timeout.
+ error = socket_pipe.ReadWithTimeout(
+ port_cstr, num_bytes, std::chrono::seconds{10}, num_bytes);
+ if (error.Success() && (port != nullptr)) {
+ assert(num_bytes > 0 && port_cstr[num_bytes - 1] == '\0');
+ *port = StringConvert::ToUInt32(port_cstr, 0);
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "debugserver listens %u port",
+ __FUNCTION__, *port);
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "failed to read a port value from pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(),
+ error.AsCString());
+ }
+ socket_pipe.Close();
+ }
+
+ if (named_pipe_path.size() > 0) {
+ const auto err = socket_pipe.Delete(named_pipe_path);
+ if (err.Fail()) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
+ }
+ }
- if (error.Fail())
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
+ // Make sure we actually connect with the debugserver...
+ JoinListenThread();
}
+ } else {
+ error.SetErrorStringWithFormat("unable to locate " DEBUGSERVER_BASENAME);
+ }
- return error;
-}
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
+ }
-void
-GDBRemoteCommunication::DumpHistory(Stream &strm)
-{
- m_history.Dump (strm);
+ return error;
}
-GDBRemoteCommunication::ScopedTimeout::ScopedTimeout (GDBRemoteCommunication& gdb_comm,
- uint32_t timeout) :
- m_gdb_comm (gdb_comm)
-{
- m_saved_timeout = m_gdb_comm.SetPacketTimeout (timeout);
+void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
+
+GDBRemoteCommunication::ScopedTimeout::ScopedTimeout(
+ GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout)
+ : m_gdb_comm(gdb_comm) {
+ m_saved_timeout = m_gdb_comm.SetPacketTimeout(timeout);
}
-GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout ()
-{
- m_gdb_comm.SetPacketTimeout (m_saved_timeout);
+GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
+ m_gdb_comm.SetPacketTimeout(m_saved_timeout);
}
-// This function is called via the Communications class read thread when bytes become available
-// for this connection. This function will consume all incoming bytes and try to parse whole
-// packets as they become available. Full packets are placed in a queue, so that all packet
-// requests can simply pop from this queue. Async notification packets will be dispatched
+// This function is called via the Communications class read thread when bytes
+// become available
+// for this connection. This function will consume all incoming bytes and try to
+// parse whole
+// packets as they become available. Full packets are placed in a queue, so that
+// all packet
+// requests can simply pop from this queue. Async notification packets will be
+// dispatched
// immediately to the ProcessGDBRemote Async thread via an event.
-void GDBRemoteCommunication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, lldb::ConnectionStatus status)
-{
- StringExtractorGDBRemote packet;
-
- while (true)
- {
- PacketType type = CheckForPacket(bytes, len, packet);
-
- // scrub the data so we do not pass it back to CheckForPacket
- // on future passes of the loop
- bytes = nullptr;
- len = 0;
-
- // we may have received no packet so lets bail out
- if (type == PacketType::Invalid)
- break;
-
- if (type == PacketType::Standard)
- {
- // scope for the mutex
- {
- // lock down the packet queue
- Mutex::Locker locker(m_packet_queue_mutex);
- // push a new packet into the queue
- m_packet_queue.push(packet);
- // Signal condition variable that we have a packet
- m_condition_queue_not_empty.Signal();
-
- }
- }
+void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
+ size_t len, bool broadcast,
+ lldb::ConnectionStatus status) {
+ StringExtractorGDBRemote packet;
+
+ while (true) {
+ PacketType type = CheckForPacket(bytes, len, packet);
+
+ // scrub the data so we do not pass it back to CheckForPacket
+ // on future passes of the loop
+ bytes = nullptr;
+ len = 0;
+
+ // we may have received no packet so lets bail out
+ if (type == PacketType::Invalid)
+ break;
+
+ if (type == PacketType::Standard) {
+ // scope for the mutex
+ {
+ // lock down the packet queue
+ std::lock_guard<std::mutex> guard(m_packet_queue_mutex);
+ // push a new packet into the queue
+ m_packet_queue.push(packet);
+ // Signal condition variable that we have a packet
+ m_condition_queue_not_empty.notify_one();
+ }
+ }
- if (type == PacketType::Notify)
- {
- // put this packet into an event
- const char *pdata = packet.GetStringRef().c_str();
+ if (type == PacketType::Notify) {
+ // put this packet into an event
+ const char *pdata = packet.GetStringRef().c_str();
- // as the communication class, we are a broadcaster and the
- // async thread is tuned to listen to us
- BroadcastEvent(
- eBroadcastBitGdbReadThreadGotNotify,
- new EventDataBytes(pdata));
- }
+ // as the communication class, we are a broadcaster and the
+ // async thread is tuned to listen to us
+ BroadcastEvent(eBroadcastBitGdbReadThreadGotNotify,
+ new EventDataBytes(pdata));
}
+ }
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 2a01bcec260c..1f3fa17cfc26 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -12,365 +12,275 @@
// C Includes
// C++ Includes
-#include <string>
+#include <condition_variable>
+#include <mutex>
#include <queue>
+#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Listener.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Interpreter/Args.h"
+#include "lldb/lldb-public.h"
#include "Utility/StringExtractorGDBRemote.h"
namespace lldb_private {
namespace process_gdb_remote {
-typedef enum
-{
- eStoppointInvalid = -1,
- eBreakpointSoftware = 0,
- eBreakpointHardware,
- eWatchpointWrite,
- eWatchpointRead,
- eWatchpointReadWrite
+typedef enum {
+ eStoppointInvalid = -1,
+ eBreakpointSoftware = 0,
+ eBreakpointHardware,
+ eWatchpointWrite,
+ eWatchpointRead,
+ eWatchpointReadWrite
} GDBStoppointType;
-enum class CompressionType
-{
- None = 0, // no compression
- ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's libcompression
- LZFSE, // an Apple compression scheme, requires Apple's libcompression
- LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with https://code.google.com/p/lz4/
- LZMA, // Lempel–Ziv–Markov chain algorithm
+enum class CompressionType {
+ None = 0, // no compression
+ ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's
+ // libcompression
+ LZFSE, // an Apple compression scheme, requires Apple's libcompression
+ LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with
+ // https://code.google.com/p/lz4/
+ LZMA, // Lempel–Ziv–Markov chain algorithm
};
class ProcessGDBRemote;
-class GDBRemoteCommunication : public Communication
-{
+class GDBRemoteCommunication : public Communication {
public:
- enum
- {
- eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
- eBroadcastBitGdbReadThreadGotNotify = kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
- };
+ enum {
+ eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
+ eBroadcastBitGdbReadThreadGotNotify =
+ kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
+ };
+
+ enum class PacketType { Invalid = 0, Standard, Notify };
+
+ enum class PacketResult {
+ Success = 0, // Success
+ ErrorSendFailed, // Error sending the packet
+ ErrorSendAck, // Didn't get an ack back after sending a packet
+ ErrorReplyFailed, // Error getting the reply
+ ErrorReplyTimeout, // Timed out waiting for reply
+ ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that
+ // was sent
+ ErrorReplyAck, // Sending reply ack failed
+ ErrorDisconnected, // We were disconnected
+ ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet
+ // request
+ };
+
+ // Class to change the timeout for a given scope and restore it to the
+ // original value when the
+ // created ScopedTimeout object got out of scope
+ class ScopedTimeout {
+ public:
+ ScopedTimeout(GDBRemoteCommunication &gdb_comm,
+ std::chrono::seconds timeout);
+ ~ScopedTimeout();
+
+ private:
+ GDBRemoteCommunication &m_gdb_comm;
+ std::chrono::seconds m_saved_timeout;
+ };
+
+ GDBRemoteCommunication(const char *comm_name, const char *listener_name);
+
+ ~GDBRemoteCommunication() override;
+
+ PacketResult GetAck();
+
+ size_t SendAck();
+
+ size_t SendNack();
+
+ char CalculcateChecksum(llvm::StringRef payload);
+
+ PacketType CheckForPacket(const uint8_t *src, size_t src_len,
+ StringExtractorGDBRemote &packet);
+
+ bool GetSendAcks() { return m_send_acks; }
+
+ //------------------------------------------------------------------
+ // Set the global packet timeout.
+ //
+ // For clients, this is the timeout that gets used when sending
+ // packets and waiting for responses. For servers, this is used when waiting
+ // for ACKs.
+ //------------------------------------------------------------------
+ std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
+ const auto old_packet_timeout = m_packet_timeout;
+ m_packet_timeout = packet_timeout;
+ return old_packet_timeout;
+ }
+
+ std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
+
+ //------------------------------------------------------------------
+ // Start a debugserver instance on the current host using the
+ // supplied connection URL.
+ //------------------------------------------------------------------
+ Error StartDebugserverProcess(
+ const char *url,
+ Platform *platform, // If non nullptr, then check with the platform for
+ // the GDB server binary if it can't be located
+ ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args,
+ int pass_comm_fd); // Communication file descriptor to pass during
+ // fork/exec to avoid having to connect/accept
+
+ void DumpHistory(Stream &strm);
- enum class PacketType
- {
- Invalid = 0,
- Standard,
- Notify
- };
-
- enum class PacketResult
- {
- Success = 0, // Success
- ErrorSendFailed, // Error sending the packet
- ErrorSendAck, // Didn't get an ack back after sending a packet
- ErrorReplyFailed, // Error getting the reply
- ErrorReplyTimeout, // Timed out waiting for reply
- ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that was sent
- ErrorReplyAck, // Sending reply ack failed
- ErrorDisconnected, // We were disconnected
- ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
+protected:
+ class History {
+ public:
+ enum PacketType {
+ ePacketTypeInvalid = 0,
+ ePacketTypeSend,
+ ePacketTypeRecv
};
- // Class to change the timeout for a given scope and restore it to the original value when the
- // created ScopedTimeout object got out of scope
- class ScopedTimeout
- {
- public:
- ScopedTimeout (GDBRemoteCommunication& gdb_comm, uint32_t timeout);
- ~ScopedTimeout ();
-
- private:
- GDBRemoteCommunication& m_gdb_comm;
- uint32_t m_saved_timeout;
+ 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;
};
- GDBRemoteCommunication(const char *comm_name,
- const char *listener_name);
-
- ~GDBRemoteCommunication() override;
-
- PacketResult
- GetAck ();
-
- size_t
- SendAck ();
+ History(uint32_t size);
- size_t
- SendNack ();
+ ~History();
- char
- CalculcateChecksum (const char *payload,
- size_t payload_length);
+ // For single char packets for ack, nack and /x03
+ void AddPacket(char packet_char, PacketType type,
+ uint32_t bytes_transmitted);
- bool
- GetSequenceMutex(Mutex::Locker& locker, const char *failure_message = nullptr);
+ void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
+ uint32_t bytes_transmitted);
- PacketType
- CheckForPacket (const uint8_t *src,
- size_t src_len,
- StringExtractorGDBRemote &packet);
+ void Dump(Stream &strm) const;
- bool
- IsRunning() const
- {
- return m_public_is_running.GetValue();
- }
+ void Dump(Log *log) const;
- bool
- GetSendAcks ()
- {
- return m_send_acks;
- }
+ bool DidDumpToLog() const { return m_dumped_to_log; }
- //------------------------------------------------------------------
- // Client and server must implement these pure virtual functions
- //------------------------------------------------------------------
- virtual bool
- GetThreadSuffixSupported () = 0;
-
- //------------------------------------------------------------------
- // Set the global packet timeout.
- //
- // For clients, this is the timeout that gets used when sending
- // packets and waiting for responses. For servers, this might not
- // get used, and if it doesn't this should be moved to the
- // GDBRemoteCommunicationClient.
- //------------------------------------------------------------------
- uint32_t
- SetPacketTimeout (uint32_t packet_timeout)
- {
- const uint32_t old_packet_timeout = m_packet_timeout;
- m_packet_timeout = packet_timeout;
- return old_packet_timeout;
+ protected:
+ uint32_t GetFirstSavedPacketIndex() const {
+ if (m_total_packet_count < m_packets.size())
+ return 0;
+ else
+ return m_curr_idx + 1;
}
- uint32_t
- GetPacketTimeoutInMicroSeconds () const
- {
- return m_packet_timeout * TimeValue::MicroSecPerSec;
+ uint32_t GetNumPacketsInHistory() const {
+ if (m_total_packet_count < m_packets.size())
+ return m_total_packet_count;
+ else
+ return (uint32_t)m_packets.size();
}
- //------------------------------------------------------------------
- // Start a debugserver instance on the current host using the
- // supplied connection URL.
- //------------------------------------------------------------------
- Error
- StartDebugserverProcess(const char *url,
- Platform *platform, // If non nullptr, then check with the platform for the GDB server binary if it can't be located
- ProcessLaunchInfo &launch_info,
- uint16_t *port,
- const Args& inferior_args = Args());
-
- void
- DumpHistory(Stream &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;
- };
-
- uint32_t m_packet_timeout;
- uint32_t m_echo_number;
- LazyBool m_supports_qEcho;
-#ifdef ENABLE_MUTEX_ERROR_CHECKING
- TrackingMutex m_sequence_mutex;
-#else
- Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
-#endif
- Predicate<bool> m_public_is_running;
- Predicate<bool> m_private_is_running;
- History 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
- // a single process
-
- CompressionType m_compression_type;
-
- PacketResult
- SendPacket (const char *payload,
- size_t payload_length);
-
- PacketResult
- SendPacketNoLock (const char *payload,
- size_t payload_length);
-
- PacketResult
- ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout);
-
- // Pop a packet from the queue in a thread safe manner
- PacketResult
- PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec);
-
- PacketResult
- WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
- uint32_t timeout_usec,
- bool sync_on_timeout);
-
- bool
- WaitForNotRunningPrivate (const TimeValue *timeout_ptr);
-
- bool
- CompressionIsEnabled ()
- {
- return m_compression_type != CompressionType::None;
+ uint32_t GetNextIndex() {
+ ++m_total_packet_count;
+ const uint32_t idx = m_curr_idx;
+ m_curr_idx = NormalizeIndex(idx + 1);
+ return idx;
}
- // If compression is enabled, decompress the packet in m_bytes and update
- // m_bytes with the uncompressed version.
- // Returns 'true' packet was decompressed and m_bytes is the now-decompressed text.
- // Returns 'false' if unable to decompress or if the checksum was invalid.
- //
- // NB: Once the packet has been decompressed, checksum cannot be computed based
- // on m_bytes. The checksum was for the compressed packet.
- bool
- DecompressPacket ();
-
- Error
- StartListenThread (const char *hostname = "127.0.0.1", uint16_t port = 0);
-
- bool
- JoinListenThread ();
-
- static lldb::thread_result_t
- ListenThread (lldb::thread_arg_t arg);
-
- // GDB-Remote read thread
- // . this thread constantly tries to read from the communication
- // class and stores all packets received in a queue. The usual
- // threads read requests simply pop packets off the queue in the
- // usual order.
- // This setup allows us to intercept and handle async packets, such
- // as the notify packet.
-
- // This method is defined as part of communication.h
- // when the read thread gets any bytes it will pass them on to this function
- void AppendBytesToCache(const uint8_t * bytes,
- size_t len,
- bool broadcast,
- lldb::ConnectionStatus status) override;
+ 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;
+ };
+
+ std::chrono::seconds m_packet_timeout;
+ uint32_t m_echo_number;
+ LazyBool m_supports_qEcho;
+ History 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
+ // a single process
+
+ CompressionType m_compression_type;
+
+ PacketResult SendPacketNoLock(llvm::StringRef payload);
+
+ PacketResult ReadPacket(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout, bool sync_on_timeout);
+
+ // Pop a packet from the queue in a thread safe manner
+ PacketResult PopPacketFromQueue(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout);
+
+ PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout,
+ bool sync_on_timeout);
+
+ bool CompressionIsEnabled() {
+ return m_compression_type != CompressionType::None;
+ }
+
+ // If compression is enabled, decompress the packet in m_bytes and update
+ // m_bytes with the uncompressed version.
+ // Returns 'true' packet was decompressed and m_bytes is the now-decompressed
+ // text.
+ // Returns 'false' if unable to decompress or if the checksum was invalid.
+ //
+ // NB: Once the packet has been decompressed, checksum cannot be computed
+ // based
+ // on m_bytes. The checksum was for the compressed packet.
+ bool DecompressPacket();
+
+ Error StartListenThread(const char *hostname = "127.0.0.1",
+ uint16_t port = 0);
+
+ bool JoinListenThread();
+
+ static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
+
+ // GDB-Remote read thread
+ // . this thread constantly tries to read from the communication
+ // class and stores all packets received in a queue. The usual
+ // threads read requests simply pop packets off the queue in the
+ // usual order.
+ // This setup allows us to intercept and handle async packets, such
+ // as the notify packet.
+
+ // This method is defined as part of communication.h
+ // when the read thread gets any bytes it will pass them on to this function
+ void AppendBytesToCache(const uint8_t *bytes, size_t len, bool broadcast,
+ lldb::ConnectionStatus status) override;
private:
- std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
- lldb_private::Mutex m_packet_queue_mutex; // Mutex for accessing queue
- Condition m_condition_queue_not_empty; // Condition variable to wait for packets
+ std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
+ std::mutex m_packet_queue_mutex; // Mutex for accessing queue
+ std::condition_variable
+ m_condition_queue_not_empty; // Condition variable to wait for packets
- HostThread m_listen_thread;
- std::string m_listen_url;
+ HostThread m_listen_thread;
+ std::string m_listen_url;
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index a792bbbd1385..f9bbaef60215 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "GDBRemoteCommunicationClient.h"
// C Includes
@@ -15,48 +14,48 @@
#include <sys/stat.h>
// C++ Includes
-#include <sstream>
#include <numeric>
+#include <sstream>
// Other libraries and framework includes
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamGDBRemote.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Host/TimeValue.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/JSON.h"
+#include "lldb/Utility/LLDBAssert.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
+#include "Utility/StringExtractorGDBRemote.h"
#include "lldb/Host/Config.h"
-#if defined (HAVE_LIBCOMPRESSION)
+#include "llvm/ADT/StringSwitch.h"
+
+#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace std::chrono;
//----------------------------------------------------------------------
// GDBRemoteCommunicationClient constructor
//----------------------------------------------------------------------
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
- : GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
+ : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
m_supports_not_sending_acks(eLazyBoolCalculate),
m_supports_thread_suffix(eLazyBoolCalculate),
m_supports_threads_in_stop_reply(eLazyBoolCalculate),
@@ -77,8 +76,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
m_attach_or_wait_reply(eLazyBoolCalculate),
m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
- m_supports_p(eLazyBoolCalculate),
- m_supports_x(eLazyBoolCalculate),
+ m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
m_avoid_g_packets(eLazyBoolCalculate),
m_supports_QSaveRegisterState(eLazyBoolCalculate),
m_supports_qXfer_auxv_read(eLazyBoolCalculate),
@@ -88,503 +86,449 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
- m_supports_qProcessInfoPID(true),
- m_supports_qfProcessInfo(true),
- m_supports_qUserName(true),
- m_supports_qGroupName(true),
- m_supports_qThreadStopInfo(true),
- m_supports_z0(true),
- m_supports_z1(true),
- m_supports_z2(true),
- m_supports_z3(true),
- m_supports_z4(true),
- m_supports_QEnvironment(true),
- m_supports_QEnvironmentHexEncoded(true),
- m_supports_qSymbol(true),
- m_qSymbol_requests_done(false),
- m_supports_qModuleInfo(true),
- m_supports_jThreadsInfo(true),
- m_curr_pid(LLDB_INVALID_PROCESS_ID),
- m_curr_tid(LLDB_INVALID_THREAD_ID),
+ m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
+ m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
+ m_supports_qUserName(true), m_supports_qGroupName(true),
+ m_supports_qThreadStopInfo(true), m_supports_z0(true),
+ m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
+ m_supports_z4(true), m_supports_QEnvironment(true),
+ m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
+ m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
+ m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
+ m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
m_curr_tid_run(LLDB_INVALID_THREAD_ID),
- m_num_supported_hardware_watchpoints(0),
- m_async_mutex(),
- m_async_packet_predicate(false),
- m_async_packet(),
- m_async_result(PacketResult::Success),
- m_async_response(),
- m_async_signal(-1),
- m_interrupt_sent(false),
- m_thread_id_to_used_usec_map(),
- m_host_arch(),
- m_process_arch(),
- m_os_version_major(UINT32_MAX),
- m_os_version_minor(UINT32_MAX),
- m_os_version_update(UINT32_MAX),
- m_os_build(),
- m_os_kernel(),
- m_hostname(),
- m_gdb_server_name(),
- m_gdb_server_version(UINT32_MAX),
- m_default_packet_timeout(0),
- m_max_packet_size(0)
-{
-}
+ m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
+ m_os_version_major(UINT32_MAX), m_os_version_minor(UINT32_MAX),
+ m_os_version_update(UINT32_MAX), m_os_build(), m_os_kernel(),
+ m_hostname(), m_gdb_server_name(), m_gdb_server_version(UINT32_MAX),
+ m_default_packet_timeout(0), m_max_packet_size(0),
+ m_qSupported_response(), m_supported_async_json_packets_is_valid(false),
+ m_supported_async_json_packets_sp() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
-{
- if (IsConnected())
- Disconnect();
-}
-
-bool
-GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
-{
- ResetDiscoverableSettings(false);
-
- // Start the read thread after we send the handshake ack since if we
- // fail to send the handshake ack, there is no reason to continue...
- if (SendAck())
- {
- // Wait for any responses that might have been queued up in the remote
- // GDB server and flush them all
- StringExtractorGDBRemote response;
- PacketResult packet_result = PacketResult::Success;
- const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response
- while (packet_result == PacketResult::Success)
- packet_result = ReadPacket (response, timeout_usec, false);
-
- // The return value from QueryNoAckModeSupported() is true if the packet
- // was sent and _any_ response (including UNIMPLEMENTED) was received),
- // or false if no response was received. This quickly tells us if we have
- // a live connection to a remote GDB server...
- if (QueryNoAckModeSupported())
- {
- return true;
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorString("failed to get reply to handshake packet");
- }
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorString("failed to send the handshake ack");
- }
- return false;
+GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
+ if (IsConnected())
+ Disconnect();
}
-bool
-GDBRemoteCommunicationClient::GetEchoSupported ()
-{
- if (m_supports_qEcho == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qEcho == eLazyBoolYes;
-}
+bool GDBRemoteCommunicationClient::HandshakeWithServer(Error *error_ptr) {
+ ResetDiscoverableSettings(false);
+ // Start the read thread after we send the handshake ack since if we
+ // fail to send the handshake ack, there is no reason to continue...
+ if (SendAck()) {
+ // Wait for any responses that might have been queued up in the remote
+ // GDB server and flush them all
+ StringExtractorGDBRemote response;
+ PacketResult packet_result = PacketResult::Success;
+ while (packet_result == PacketResult::Success)
+ packet_result = ReadPacket(response, milliseconds(10), false);
-bool
-GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
-{
- if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
+ // The return value from QueryNoAckModeSupported() is true if the packet
+ // was sent and _any_ response (including UNIMPLEMENTED) was received),
+ // or false if no response was received. This quickly tells us if we have
+ // a live connection to a remote GDB server...
+ if (QueryNoAckModeSupported()) {
+ return true;
+ } else {
+ if (error_ptr)
+ error_ptr->SetErrorString("failed to get reply to handshake packet");
}
- return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
+ } else {
+ if (error_ptr)
+ error_ptr->SetErrorString("failed to send the handshake ack");
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
-{
- if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetEchoSupported() {
+ if (m_supports_qEcho == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qEcho == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
-{
- if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_libraries_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
+ if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
-{
- if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_auxv_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
+ if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported ()
-{
- if (m_supports_qXfer_features_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_features_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
+ if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_libraries_read == eLazyBoolYes;
}
-uint64_t
-GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
-{
- if (m_max_packet_size == 0)
- {
- GetRemoteQSupported();
- }
- return m_max_packet_size;
+bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
+ if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_auxv_read == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
-{
- if (m_supports_not_sending_acks == eLazyBoolCalculate)
- {
- m_send_acks = true;
- m_supports_not_sending_acks = eLazyBoolNo;
-
- // This is the first real packet that we'll send in a debug session and it may take a little
- // longer than normal to receive a reply. Wait at least 6 seconds for a reply to this packet.
-
- const uint32_t minimum_timeout = 6;
- uint32_t old_timeout = GetPacketTimeoutInMicroSeconds() / lldb_private::TimeValue::MicroSecPerSec;
- GDBRemoteCommunication::ScopedTimeout timeout (*this, std::max (old_timeout, minimum_timeout));
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_send_acks = false;
- m_supports_not_sending_acks = eLazyBoolYes;
- }
- return true;
- }
- }
- return false;
+bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
+ if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_features_read == eLazyBoolYes;
}
-void
-GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
-{
- if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
- {
- m_supports_threads_in_stop_reply = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_supports_threads_in_stop_reply = eLazyBoolYes;
- }
- }
+uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
+ if (m_max_packet_size == 0) {
+ GetRemoteQSupported();
+ }
+ return m_max_packet_size;
}
-bool
-GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
-{
- if (m_attach_or_wait_reply == eLazyBoolCalculate)
- {
- m_attach_or_wait_reply = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_attach_or_wait_reply = eLazyBoolYes;
- }
- }
- if (m_attach_or_wait_reply == eLazyBoolYes)
- return true;
- else
- return false;
-}
+bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
+ if (m_supports_not_sending_acks == eLazyBoolCalculate) {
+ m_send_acks = true;
+ m_supports_not_sending_acks = eLazyBoolNo;
-bool
-GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
-{
- if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
- {
- m_prepare_for_reg_writing_reply = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_prepare_for_reg_writing_reply = eLazyBoolYes;
- }
+ // This is the first real packet that we'll send in a debug session and it
+ // may take a little
+ // longer than normal to receive a reply. Wait at least 6 seconds for a
+ // reply to this packet.
+
+ ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_send_acks = false;
+ m_supports_not_sending_acks = eLazyBoolYes;
+ }
+ return true;
}
- if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
- return true;
- else
- return false;
+ }
+ return false;
}
+void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
+ if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
+ m_supports_threads_in_stop_reply = eLazyBoolNo;
-void
-GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
-{
- if (did_exec == false)
- {
- // Hard reset everything, this is when we first connect to a GDB server
- m_supports_not_sending_acks = eLazyBoolCalculate;
- m_supports_thread_suffix = eLazyBoolCalculate;
- m_supports_threads_in_stop_reply = eLazyBoolCalculate;
- m_supports_vCont_c = eLazyBoolCalculate;
- m_supports_vCont_C = eLazyBoolCalculate;
- m_supports_vCont_s = eLazyBoolCalculate;
- m_supports_vCont_S = eLazyBoolCalculate;
- m_supports_p = eLazyBoolCalculate;
- m_supports_x = eLazyBoolCalculate;
- m_supports_QSaveRegisterState = eLazyBoolCalculate;
- m_qHostInfo_is_valid = eLazyBoolCalculate;
- m_curr_pid_is_valid = eLazyBoolCalculate;
- m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
- m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
- m_supports_memory_region_info = eLazyBoolCalculate;
- m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
- m_attach_or_wait_reply = eLazyBoolCalculate;
- m_avoid_g_packets = eLazyBoolCalculate;
- m_supports_qXfer_auxv_read = eLazyBoolCalculate;
- m_supports_qXfer_libraries_read = eLazyBoolCalculate;
- m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
- m_supports_qXfer_features_read = eLazyBoolCalculate;
- m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
- m_supports_qProcessInfoPID = true;
- m_supports_qfProcessInfo = true;
- m_supports_qUserName = true;
- m_supports_qGroupName = true;
- m_supports_qThreadStopInfo = true;
- m_supports_z0 = true;
- m_supports_z1 = true;
- m_supports_z2 = true;
- m_supports_z3 = true;
- m_supports_z4 = true;
- m_supports_QEnvironment = true;
- m_supports_QEnvironmentHexEncoded = true;
- m_supports_qSymbol = true;
- m_qSymbol_requests_done = false;
- m_supports_qModuleInfo = true;
- m_host_arch.Clear();
- m_os_version_major = UINT32_MAX;
- m_os_version_minor = UINT32_MAX;
- m_os_version_update = UINT32_MAX;
- m_os_build.clear();
- m_os_kernel.clear();
- m_hostname.clear();
- m_gdb_server_name.clear();
- m_gdb_server_version = UINT32_MAX;
- m_default_packet_timeout = 0;
- m_max_packet_size = 0;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_supports_threads_in_stop_reply = eLazyBoolYes;
}
-
- // These flags should be reset when we first connect to a GDB server
- // and when our inferior process execs
- m_qProcessInfo_is_valid = eLazyBoolCalculate;
- m_process_arch.Clear();
+ }
}
-void
-GDBRemoteCommunicationClient::GetRemoteQSupported ()
-{
- // Clear out any capabilities we expect to see in the qSupported response
- m_supports_qXfer_auxv_read = eLazyBoolNo;
- m_supports_qXfer_libraries_read = eLazyBoolNo;
- m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
- m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
- m_supports_qXfer_features_read = eLazyBoolNo;
- m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if not, we assume no limit
-
- // build the qSupported packet
- std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
- StreamString packet;
- packet.PutCString( "qSupported" );
- for ( uint32_t i = 0; i < features.size( ); ++i )
- {
- packet.PutCString( i==0 ? ":" : ";");
- packet.PutCString( features[i].c_str( ) );
- }
+bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
+ if (m_attach_or_wait_reply == eLazyBoolCalculate) {
+ m_attach_or_wait_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetData(),
- response,
- /*send_async=*/false) == PacketResult::Success)
- {
- const char *response_cstr = response.GetStringRef().c_str();
- if (::strstr (response_cstr, "qXfer:auxv:read+"))
- m_supports_qXfer_auxv_read = eLazyBoolYes;
- if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
- m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
- if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
- {
- m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
- m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
- }
- if (::strstr (response_cstr, "qXfer:libraries:read+"))
- m_supports_qXfer_libraries_read = eLazyBoolYes;
- if (::strstr (response_cstr, "qXfer:features:read+"))
- m_supports_qXfer_features_read = eLazyBoolYes;
-
-
- // Look for a list of compressions in the features list e.g.
- // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
- const char *features_list = ::strstr (response_cstr, "qXfer:features:");
- if (features_list)
- {
- const char *compressions = ::strstr (features_list, "SupportedCompressions=");
- if (compressions)
- {
- std::vector<std::string> supported_compressions;
- compressions += sizeof ("SupportedCompressions=") - 1;
- const char *end_of_compressions = strchr (compressions, ';');
- if (end_of_compressions == NULL)
- {
- end_of_compressions = strchr (compressions, '\0');
- }
- const char *current_compression = compressions;
- while (current_compression < end_of_compressions)
- {
- const char *next_compression_name = strchr (current_compression, ',');
- const char *end_of_this_word = next_compression_name;
- if (next_compression_name == NULL || end_of_compressions < next_compression_name)
- {
- end_of_this_word = end_of_compressions;
- }
-
- if (end_of_this_word)
- {
- if (end_of_this_word == current_compression)
- {
- current_compression++;
- }
- else
- {
- std::string this_compression (current_compression, end_of_this_word - current_compression);
- supported_compressions.push_back (this_compression);
- current_compression = end_of_this_word + 1;
- }
- }
- else
- {
- supported_compressions.push_back (current_compression);
- current_compression = end_of_compressions;
- }
- }
+ if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_attach_or_wait_reply = eLazyBoolYes;
+ }
+ }
+ if (m_attach_or_wait_reply == eLazyBoolYes)
+ return true;
+ else
+ return false;
+}
- if (supported_compressions.size() > 0)
- {
- MaybeEnableCompression (supported_compressions);
- }
- }
- }
+bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
+ if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
+ m_prepare_for_reg_writing_reply = eLazyBoolNo;
- if (::strstr (response_cstr, "qEcho"))
- m_supports_qEcho = eLazyBoolYes;
- else
- m_supports_qEcho = eLazyBoolNo;
-
- const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
- if (packet_size_str)
- {
- StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
- m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
- if (m_max_packet_size == 0)
- {
- m_max_packet_size = UINT64_MAX; // Must have been a garbled response
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("Garbled PacketSize spec in qSupported response");
- }
- }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_prepare_for_reg_writing_reply = eLazyBoolYes;
}
+ }
+ if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
+ return true;
+ else
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
-{
- if (m_supports_thread_suffix == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_thread_suffix = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_supports_thread_suffix = eLazyBoolYes;
- }
+void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
+ if (did_exec == false) {
+ // Hard reset everything, this is when we first connect to a GDB server
+ m_supports_not_sending_acks = eLazyBoolCalculate;
+ m_supports_thread_suffix = eLazyBoolCalculate;
+ m_supports_threads_in_stop_reply = eLazyBoolCalculate;
+ m_supports_vCont_c = eLazyBoolCalculate;
+ m_supports_vCont_C = eLazyBoolCalculate;
+ m_supports_vCont_s = eLazyBoolCalculate;
+ m_supports_vCont_S = eLazyBoolCalculate;
+ m_supports_p = eLazyBoolCalculate;
+ m_supports_x = eLazyBoolCalculate;
+ m_supports_QSaveRegisterState = eLazyBoolCalculate;
+ m_qHostInfo_is_valid = eLazyBoolCalculate;
+ m_curr_pid_is_valid = eLazyBoolCalculate;
+ m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
+ m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
+ m_supports_memory_region_info = eLazyBoolCalculate;
+ m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
+ m_attach_or_wait_reply = eLazyBoolCalculate;
+ m_avoid_g_packets = eLazyBoolCalculate;
+ m_supports_qXfer_auxv_read = eLazyBoolCalculate;
+ m_supports_qXfer_libraries_read = eLazyBoolCalculate;
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
+ m_supports_qXfer_features_read = eLazyBoolCalculate;
+ m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
+ m_supports_qProcessInfoPID = true;
+ m_supports_qfProcessInfo = true;
+ m_supports_qUserName = true;
+ m_supports_qGroupName = true;
+ m_supports_qThreadStopInfo = true;
+ m_supports_z0 = true;
+ m_supports_z1 = true;
+ m_supports_z2 = true;
+ m_supports_z3 = true;
+ m_supports_z4 = true;
+ m_supports_QEnvironment = true;
+ m_supports_QEnvironmentHexEncoded = true;
+ m_supports_qSymbol = true;
+ m_qSymbol_requests_done = false;
+ m_supports_qModuleInfo = true;
+ m_host_arch.Clear();
+ m_os_version_major = UINT32_MAX;
+ m_os_version_minor = UINT32_MAX;
+ m_os_version_update = UINT32_MAX;
+ m_os_build.clear();
+ m_os_kernel.clear();
+ m_hostname.clear();
+ m_gdb_server_name.clear();
+ m_gdb_server_version = UINT32_MAX;
+ m_default_packet_timeout = seconds(0);
+ m_max_packet_size = 0;
+ m_qSupported_response.clear();
+ m_supported_async_json_packets_is_valid = false;
+ m_supported_async_json_packets_sp.reset();
+ m_supports_jModulesInfo = true;
+ }
+
+ // These flags should be reset when we first connect to a GDB server
+ // and when our inferior process execs
+ m_qProcessInfo_is_valid = eLazyBoolCalculate;
+ m_process_arch.Clear();
+}
+
+void GDBRemoteCommunicationClient::GetRemoteQSupported() {
+ // Clear out any capabilities we expect to see in the qSupported response
+ m_supports_qXfer_auxv_read = eLazyBoolNo;
+ m_supports_qXfer_libraries_read = eLazyBoolNo;
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
+ m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
+ m_supports_qXfer_features_read = eLazyBoolNo;
+ m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
+ // not, we assume no limit
+
+ // build the qSupported packet
+ std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
+ StreamString packet;
+ packet.PutCString("qSupported");
+ for (uint32_t i = 0; i < features.size(); ++i) {
+ packet.PutCString(i == 0 ? ":" : ";");
+ packet.PutCString(features[i]);
+ }
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response,
+ /*send_async=*/false) ==
+ PacketResult::Success) {
+ const char *response_cstr = response.GetStringRef().c_str();
+
+ // Hang on to the qSupported packet, so that platforms can do custom
+ // configuration of the transport before attaching/launching the
+ // process.
+ m_qSupported_response = response_cstr;
+
+ if (::strstr(response_cstr, "qXfer:auxv:read+"))
+ m_supports_qXfer_auxv_read = eLazyBoolYes;
+ if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
+ if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
+ m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
+ }
+ if (::strstr(response_cstr, "qXfer:libraries:read+"))
+ m_supports_qXfer_libraries_read = eLazyBoolYes;
+ if (::strstr(response_cstr, "qXfer:features:read+"))
+ m_supports_qXfer_features_read = eLazyBoolYes;
+
+ // Look for a list of compressions in the features list e.g.
+ // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
+ const char *features_list = ::strstr(response_cstr, "qXfer:features:");
+ if (features_list) {
+ const char *compressions =
+ ::strstr(features_list, "SupportedCompressions=");
+ if (compressions) {
+ std::vector<std::string> supported_compressions;
+ compressions += sizeof("SupportedCompressions=") - 1;
+ const char *end_of_compressions = strchr(compressions, ';');
+ if (end_of_compressions == NULL) {
+ end_of_compressions = strchr(compressions, '\0');
+ }
+ const char *current_compression = compressions;
+ while (current_compression < end_of_compressions) {
+ const char *next_compression_name = strchr(current_compression, ',');
+ const char *end_of_this_word = next_compression_name;
+ if (next_compression_name == NULL ||
+ end_of_compressions < next_compression_name) {
+ end_of_this_word = end_of_compressions;
+ }
+
+ if (end_of_this_word) {
+ if (end_of_this_word == current_compression) {
+ current_compression++;
+ } else {
+ std::string this_compression(
+ current_compression, end_of_this_word - current_compression);
+ supported_compressions.push_back(this_compression);
+ current_compression = end_of_this_word + 1;
+ }
+ } else {
+ supported_compressions.push_back(current_compression);
+ current_compression = end_of_compressions;
+ }
+ }
+
+ if (supported_compressions.size() > 0) {
+ MaybeEnableCompression(supported_compressions);
+ }
+ }
+ }
+
+ if (::strstr(response_cstr, "qEcho"))
+ m_supports_qEcho = eLazyBoolYes;
+ else
+ m_supports_qEcho = eLazyBoolNo;
+
+ const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
+ if (packet_size_str) {
+ StringExtractorGDBRemote packet_response(packet_size_str +
+ strlen("PacketSize="));
+ m_max_packet_size =
+ packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
+ if (m_max_packet_size == 0) {
+ m_max_packet_size = UINT64_MAX; // Must have been a garbled response
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("Garbled PacketSize spec in qSupported response");
+ }
}
- return m_supports_thread_suffix;
+ }
}
-bool
-GDBRemoteCommunicationClient::GetVContSupported (char flavor)
-{
- if (m_supports_vCont_c == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_vCont_any = eLazyBoolNo;
- m_supports_vCont_all = eLazyBoolNo;
- m_supports_vCont_c = eLazyBoolNo;
- m_supports_vCont_C = eLazyBoolNo;
- m_supports_vCont_s = eLazyBoolNo;
- m_supports_vCont_S = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
- {
- const char *response_cstr = response.GetStringRef().c_str();
- if (::strstr (response_cstr, ";c"))
- m_supports_vCont_c = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";C"))
- m_supports_vCont_C = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";s"))
- m_supports_vCont_s = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";S"))
- m_supports_vCont_S = eLazyBoolYes;
-
- if (m_supports_vCont_c == eLazyBoolYes &&
- m_supports_vCont_C == eLazyBoolYes &&
- m_supports_vCont_s == eLazyBoolYes &&
- m_supports_vCont_S == eLazyBoolYes)
- {
- m_supports_vCont_all = eLazyBoolYes;
- }
-
- if (m_supports_vCont_c == eLazyBoolYes ||
- m_supports_vCont_C == eLazyBoolYes ||
- m_supports_vCont_s == eLazyBoolYes ||
- m_supports_vCont_S == eLazyBoolYes)
- {
- m_supports_vCont_any = eLazyBoolYes;
- }
- }
- }
-
- switch (flavor)
- {
- case 'a': return m_supports_vCont_any;
- case 'A': return m_supports_vCont_all;
- case 'c': return m_supports_vCont_c;
- case 'C': return m_supports_vCont_C;
- case 's': return m_supports_vCont_s;
- case 'S': return m_supports_vCont_S;
- default: break;
+
+bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
+ if (m_supports_thread_suffix == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_thread_suffix = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_supports_thread_suffix = eLazyBoolYes;
}
- return false;
+ }
+ return m_supports_thread_suffix;
+}
+bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
+ if (m_supports_vCont_c == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_vCont_any = eLazyBoolNo;
+ m_supports_vCont_all = eLazyBoolNo;
+ m_supports_vCont_c = eLazyBoolNo;
+ m_supports_vCont_C = eLazyBoolNo;
+ m_supports_vCont_s = eLazyBoolNo;
+ m_supports_vCont_S = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("vCont?", response, false) ==
+ PacketResult::Success) {
+ const char *response_cstr = response.GetStringRef().c_str();
+ if (::strstr(response_cstr, ";c"))
+ m_supports_vCont_c = eLazyBoolYes;
+
+ if (::strstr(response_cstr, ";C"))
+ m_supports_vCont_C = eLazyBoolYes;
+
+ if (::strstr(response_cstr, ";s"))
+ m_supports_vCont_s = eLazyBoolYes;
+
+ if (::strstr(response_cstr, ";S"))
+ m_supports_vCont_S = eLazyBoolYes;
+
+ if (m_supports_vCont_c == eLazyBoolYes &&
+ m_supports_vCont_C == eLazyBoolYes &&
+ m_supports_vCont_s == eLazyBoolYes &&
+ m_supports_vCont_S == eLazyBoolYes) {
+ m_supports_vCont_all = eLazyBoolYes;
+ }
+
+ if (m_supports_vCont_c == eLazyBoolYes ||
+ m_supports_vCont_C == eLazyBoolYes ||
+ m_supports_vCont_s == eLazyBoolYes ||
+ m_supports_vCont_S == eLazyBoolYes) {
+ m_supports_vCont_any = eLazyBoolYes;
+ }
+ }
+ }
+
+ switch (flavor) {
+ case 'a':
+ return m_supports_vCont_any;
+ case 'A':
+ return m_supports_vCont_all;
+ case 'c':
+ return m_supports_vCont_c;
+ case 'C':
+ return m_supports_vCont_C;
+ case 's':
+ return m_supports_vCont_s;
+ case 'S':
+ return m_supports_vCont_S;
+ default:
+ break;
+ }
+ return false;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
+ lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
+ bool send_async) {
+ Lock lock(*this, send_async);
+ if (!lock) {
+ if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
+ GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
+ log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
+ "for %s packet.",
+ __FUNCTION__, payload.GetData());
+ return PacketResult::ErrorNoSequenceLock;
+ }
+
+ if (GetThreadSuffixSupported())
+ payload.Printf(";thread:%4.4" PRIx64 ";", tid);
+ else {
+ if (!SetCurrentThread(tid))
+ return PacketResult::ErrorSendFailed;
+ }
+
+ return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
}
// Check if the target supports 'p' packet. It sends out a 'p'
@@ -592,4043 +536,3098 @@ GDBRemoteCommunicationClient::GetVContSupported (char flavor)
// that support is available.
//
// Takes a valid thread ID because p needs to apply to a thread.
-bool
-GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
-{
- if (m_supports_p == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_p = eLazyBoolNo;
- char packet[256];
- if (GetThreadSuffixSupported())
- snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
- else
- snprintf(packet, sizeof(packet), "p0");
-
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- m_supports_p = eLazyBoolYes;
- }
- }
- return m_supports_p;
-}
-
-StructuredData::ObjectSP
-GDBRemoteCommunicationClient::GetThreadsInfo()
-{
- // Get information on all threads at one using the "jThreadsInfo" packet
- StructuredData::ObjectSP object_sp;
-
- if (m_supports_jThreadsInfo)
- {
- StringExtractorGDBRemote response;
- response.SetResponseValidatorToJSON();
- if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- {
- m_supports_jThreadsInfo = false;
- }
- else if (!response.Empty())
- {
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
- }
- }
+bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
+ if (m_supports_p == eLazyBoolCalculate) {
+ m_supports_p = eLazyBoolNo;
+ StreamString payload;
+ payload.PutCString("p0");
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+ response, false) ==
+ PacketResult::Success &&
+ response.IsNormalResponse()) {
+ m_supports_p = eLazyBoolYes;
}
- return object_sp;
+ }
+ return m_supports_p;
}
+StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
+ // Get information on all threads at one using the "jThreadsInfo" packet
+ StructuredData::ObjectSP object_sp;
-bool
-GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported ()
-{
- if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_jThreadExtendedInfo = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_supports_jThreadExtendedInfo = eLazyBoolYes;
- }
- }
+ if (m_supports_jThreadsInfo) {
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse()) {
+ m_supports_jThreadsInfo = false;
+ } else if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ }
}
- return m_supports_jThreadExtendedInfo;
+ }
+ return object_sp;
}
-bool
-GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported ()
-{
- if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
- }
- }
+bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
+ if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_jThreadExtendedInfo = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_supports_jThreadExtendedInfo = eLazyBoolYes;
+ }
}
- return m_supports_jLoadedDynamicLibrariesInfos;
+ }
+ return m_supports_jThreadExtendedInfo;
}
-bool
-GDBRemoteCommunicationClient::GetxPacketSupported ()
-{
- if (m_supports_x == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_x = eLazyBoolNo;
- char packet[256];
- snprintf (packet, sizeof (packet), "x0,0");
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_supports_x = eLazyBoolYes;
- }
+bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
+ if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
+ response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
+ }
}
- return m_supports_x;
+ }
+ return m_supports_jLoadedDynamicLibrariesInfos;
}
-GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses
-(
- const char *payload_prefix,
- std::string &response_string
-)
-{
- Mutex::Locker locker;
- if (!GetSequenceMutex(locker,
- "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex"))
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'",
- payload_prefix);
- return PacketResult::ErrorNoSequenceLock;
- }
-
- response_string = "";
- std::string payload_prefix_str(payload_prefix);
- unsigned int response_size = 0x1000;
- if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
- response_size = GetRemoteMaxPacketSize();
- }
-
- for (unsigned int offset = 0; true; offset += response_size)
- {
- StringExtractorGDBRemote this_response;
- // Construct payload
- char sizeDescriptor[128];
- snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size);
- PacketResult result = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(),
- this_response,
- /*send_async=*/false);
- if (result != PacketResult::Success)
- return result;
-
- const std::string &this_string = this_response.GetStringRef();
-
- // Check for m or l as first character; l seems to mean this is the last chunk
- char first_char = *this_string.c_str();
- if (first_char != 'm' && first_char != 'l')
- {
- return PacketResult::ErrorReplyInvalid;
- }
- // Concatenate the result so far (skipping 'm' or 'l')
- response_string.append(this_string, 1, std::string::npos);
- if (first_char == 'l')
- // We're done
- return PacketResult::Success;
+bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
+ if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_jGetSharedCacheInfo = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_supports_jGetSharedCacheInfo = eLazyBoolYes;
+ }
}
+ }
+ return m_supports_jGetSharedCacheInfo;
}
-GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
-(
- const char *payload,
- StringExtractorGDBRemote &response,
- bool send_async
-)
-{
- return SendPacketAndWaitForResponse (payload,
- ::strlen (payload),
- response,
- send_async);
-}
-
-GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload,
- size_t payload_length,
- StringExtractorGDBRemote &response)
-{
- PacketResult packet_result = SendPacketNoLock(payload, payload_length);
- if (packet_result == PacketResult::Success)
- {
- const size_t max_response_retries = 3;
- for (size_t i=0; i<max_response_retries; ++i)
- {
- packet_result = ReadPacket(response, GetPacketTimeoutInMicroSeconds (), true);
- // Make sure we received a response
- if (packet_result != PacketResult::Success)
- return packet_result;
- // Make sure our response is valid for the payload that was sent
- if (response.ValidateResponse())
- return packet_result;
- // Response says it wasn't valid
- Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
- if (log)
- log->Printf("error: packet with payload \"%*s\" got invalid response \"%s\": %s",
- (int)payload_length,
- payload,
- response.GetStringRef().c_str(),
- (i == (max_response_retries - 1)) ? "using invalid response and giving up" : "ignoring response and waiting for another");
- }
+bool GDBRemoteCommunicationClient::GetxPacketSupported() {
+ if (m_supports_x == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_x = eLazyBoolNo;
+ char packet[256];
+ snprintf(packet, sizeof(packet), "x0,0");
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_supports_x = eLazyBoolYes;
}
- return packet_result;
+ }
+ return m_supports_x;
}
GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
-(
- const char *payload,
- size_t payload_length,
- StringExtractorGDBRemote &response,
- bool send_async
-)
-{
- PacketResult packet_result = PacketResult::ErrorSendFailed;
- Mutex::Locker locker;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
- // In order to stop async notifications from being processed in the middle of the
- // send/receive sequence Hijack the broadcast. Then rebroadcast any events when we are done.
- static ListenerSP hijack_listener_sp(Listener::MakeListener("lldb.NotifyHijacker"));
- HijackBroadcaster(hijack_listener_sp, eBroadcastBitGdbReadThreadGotNotify);
-
- if (GetSequenceMutex (locker))
- {
- packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
- }
- else
- {
- if (send_async)
- {
- if (IsRunning())
- {
- std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
- m_async_packet.assign(payload, payload_length);
- m_async_response.CopyResponseValidator(response);
- m_async_packet_predicate.SetValue (true, eBroadcastNever);
-
- if (log)
- log->Printf ("async: async packet = %s", m_async_packet.c_str());
-
- bool timed_out = false;
- if (SendInterrupt(locker, 2, timed_out))
- {
- if (m_interrupt_sent)
- {
- m_interrupt_sent = false;
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds (m_packet_timeout);
-
- if (log)
- log->Printf ("async: sent interrupt");
-
- if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
- {
- if (log)
- log->Printf ("async: got response");
-
- // Swap the response buffer to avoid malloc and string copy
- response.GetStringRef().swap (m_async_response.GetStringRef());
- packet_result = m_async_result;
- }
- else
- {
- if (log)
- log->Printf ("async: timed out waiting for response");
- }
-
- // Make sure we wait until the continue packet has been sent again...
- if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
- {
- if (log)
- {
- if (timed_out)
- log->Printf ("async: timed out waiting for process to resume, but process was resumed");
- else
- log->Printf ("async: async packet sent");
- }
- }
- else
- {
- if (log)
- log->Printf ("async: timed out waiting for process to resume");
- }
- }
- else
- {
- // We had a racy condition where we went to send the interrupt
- // yet we were able to get the lock, so the process must have
- // just stopped?
- if (log)
- log->Printf ("async: got lock without sending interrupt");
- // Send the packet normally since we got the lock
- packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
- }
- }
- else
- {
- if (log)
- log->Printf ("async: failed to interrupt");
- }
-
- m_async_response.SetResponseValidator(nullptr, nullptr);
-
- }
- else
- {
- if (log)
- log->Printf ("async: not running, async is ignored");
- }
- }
- else
- {
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
- }
- }
-
- // Remove our Hijacking listener from the broadcast.
- RestoreBroadcaster();
-
- // If a notification event occurred, rebroadcast since it can now be processed safely.
- EventSP event_sp;
- if (hijack_listener_sp->GetNextEvent(event_sp))
- BroadcastEvent(event_sp);
-
- return packet_result;
-}
-
-static const char *end_delimiter = "--end--;";
-static const int end_delimiter_len = 8;
-
-std::string
-GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
-( ProcessGDBRemote *process,
- StringExtractorGDBRemote& profileDataExtractor
-)
-{
- std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
- std::stringstream final_output;
- std::string name, value;
-
- // Going to assuming thread_used_usec comes first, else bail out.
- while (profileDataExtractor.GetNameColonValue(name, value))
- {
- if (name.compare("thread_used_id") == 0)
- {
- StringExtractor threadIDHexExtractor(value.c_str());
- uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
-
- bool has_used_usec = false;
- uint32_t curr_used_usec = 0;
- std::string usec_name, usec_value;
- uint32_t input_file_pos = profileDataExtractor.GetFilePos();
- if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
- {
- if (usec_name.compare("thread_used_usec") == 0)
- {
- has_used_usec = true;
- curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
- }
- else
- {
- // We didn't find what we want, it is probably
- // an older version. Bail out.
- profileDataExtractor.SetFilePos(input_file_pos);
- }
- }
-
- if (has_used_usec)
- {
- uint32_t prev_used_usec = 0;
- std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
- if (iterator != m_thread_id_to_used_usec_map.end())
- {
- prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
- }
-
- uint32_t real_used_usec = curr_used_usec - prev_used_usec;
- // A good first time record is one that runs for at least 0.25 sec
- bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
- bool good_subsequent_time = (prev_used_usec > 0) &&
- ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
-
- if (good_first_time || good_subsequent_time)
- {
- // We try to avoid doing too many index id reservation,
- // resulting in fast increase of index ids.
-
- final_output << name << ":";
- int32_t index_id = process->AssignIndexIDToThread(thread_id);
- final_output << index_id << ";";
-
- final_output << usec_name << ":" << usec_value << ";";
- }
- else
- {
- // Skip past 'thread_used_name'.
- std::string local_name, local_value;
- profileDataExtractor.GetNameColonValue(local_name, local_value);
- }
-
- // Store current time as previous time so that they can be compared later.
- new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
- }
- else
- {
- // Bail out and use old string.
- final_output << name << ":" << value << ";";
- }
- }
- else
- {
- final_output << name << ":" << value << ";";
- }
- }
- final_output << end_delimiter;
- m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
-
- return final_output.str();
-}
-
-bool
-GDBRemoteCommunicationClient::SendvContPacket
-(
- ProcessGDBRemote *process,
- const char *payload,
- size_t packet_length,
- StringExtractorGDBRemote &response
-)
-{
-
- m_curr_tid = LLDB_INVALID_THREAD_ID;
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
-
- // we want to lock down packet sending while we continue
- Mutex::Locker locker(m_sequence_mutex);
-
- // here we broadcast this before we even send the packet!!
- // this signals doContinue() to exit
- BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
-
- // set the public state to running
- m_public_is_running.SetValue(true, eBroadcastNever);
-
- // Set the starting continue packet into "continue_packet". This packet
- // may change if we are interrupted and we continue after an async packet...
- std::string continue_packet(payload, packet_length);
-
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s () sending vCont packet: %s", __FUNCTION__, continue_packet.c_str());
-
- if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
- return false;
-
- // set the private state to running and broadcast this
- m_private_is_running.SetValue(true, eBroadcastAlways);
-
+GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
+ const char *payload_prefix, std::string &response_string) {
+ Lock lock(*this, false);
+ if (!lock) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
+ GDBR_LOG_PACKETS));
if (log)
- log->Printf("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());
-
- // wait for the response to the vCont
- if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- }
-
- return false;
-}
-
-StateType
-GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
-(
- ProcessGDBRemote *process,
- const char *payload,
- size_t packet_length,
- StringExtractorGDBRemote &response
-)
-{
- m_curr_tid = LLDB_INVALID_THREAD_ID;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
-
- Mutex::Locker locker(m_sequence_mutex);
- StateType state = eStateRunning;
-
- m_public_is_running.SetValue (true, eBroadcastNever);
- // Set the starting continue packet into "continue_packet". This packet
- // may change if we are interrupted and we continue after an async packet...
- std::string continue_packet(payload, packet_length);
-
- const auto sigstop_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
- const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT");
-
- bool got_async_packet = false;
- bool broadcast_sent = false;
-
- while (state == eStateRunning)
- {
- if (!got_async_packet)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
- if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
- state = eStateInvalid;
- else
- m_interrupt_sent = false;
-
- if (! broadcast_sent)
- {
- BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
- broadcast_sent = true;
- }
-
- m_private_is_running.SetValue (true, eBroadcastAlways);
- }
-
- got_async_packet = false;
-
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());
-
- if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
- {
- if (response.Empty())
- state = eStateInvalid;
- else
- {
- const char stop_type = response.GetChar();
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
- switch (stop_type)
- {
- case 'T':
- case 'S':
- {
- if (process->GetStopID() == 0)
- {
- if (process->GetID() == LLDB_INVALID_PROCESS_ID)
- {
- lldb::pid_t pid = GetCurrentProcessID ();
- if (pid != LLDB_INVALID_PROCESS_ID)
- process->SetID (pid);
- }
- process->BuildDynamicRegisterInfo (true);
- }
-
- // Privately notify any internal threads that we have stopped
- // in case we wanted to interrupt our process, yet we might
- // send a packet and continue without returning control to the
- // user.
- m_private_is_running.SetValue (false, eBroadcastAlways);
-
- const uint8_t signo = response.GetHexU8 (UINT8_MAX);
-
- bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
- if (continue_after_async || m_interrupt_sent)
- {
- // We sent an interrupt packet to stop the inferior process
- // for an async signal or to send an async packet while running
- // but we might have been single stepping and received the
- // stop packet for the step instead of for the interrupt packet.
- // Typically when an interrupt is sent a SIGINT or SIGSTOP
- // is used, so if we get anything else, we need to try and
- // get another stop reply packet that may have been sent
- // due to sending the interrupt when the target is stopped
- // which will just re-send a copy of the last stop reply
- // packet. If we don't do this, then the reply for our
- // async packet will be the repeat stop reply packet and cause
- // a lot of trouble for us! We also have some debugserver
- // binaries that would send two stop replies anytime the process
- // was interrupted, so we need to also check for an extra
- // stop reply packet if we interrupted the process
- const bool received_nonstop_signal = signo != sigint_signo && signo != sigstop_signo;
- if (m_interrupt_sent || received_nonstop_signal)
- {
- if (received_nonstop_signal)
- continue_after_async = false;
-
- // Try for a very brief time (0.1s) to get another stop reply
- // packet to make sure it doesn't get in the way
- StringExtractorGDBRemote extra_stop_reply_packet;
- uint32_t timeout_usec = 100000;
- if (ReadPacket (extra_stop_reply_packet, timeout_usec, false) == PacketResult::Success)
- {
- switch (extra_stop_reply_packet.GetChar())
- {
- case 'T':
- case 'S':
- // We did get an extra stop reply, which means
- // our interrupt didn't stop the target so we
- // shouldn't continue after the async signal
- // or packet is sent...
- continue_after_async = false;
- break;
- }
- }
- }
- }
-
- if (m_async_signal != -1)
- {
- if (log)
- log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
-
- // Save off the async signal we are supposed to send
- const int async_signal = m_async_signal;
- // Clear the async signal member so we don't end up
- // sending the signal multiple times...
- m_async_signal = -1;
- // Check which signal we stopped with
- if (signo == async_signal)
- {
- if (log)
- log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
-
- // We already stopped with a signal that we wanted
- // to stop with, so we are done
- }
- else
- {
- // We stopped with a different signal that the one
- // we wanted to stop with, so now we must resume
- // with the signal we want
- char signal_packet[32];
- int signal_packet_len = 0;
- signal_packet_len = ::snprintf (signal_packet,
- sizeof (signal_packet),
- "C%2.2x",
- async_signal);
-
- if (log)
- log->Printf ("async: stopped with signal %s, resume with %s",
- Host::GetSignalAsCString (signo),
- Host::GetSignalAsCString (async_signal));
-
- // Set the continue packet to resume even if the
- // interrupt didn't cause our stop (ignore continue_after_async)
- continue_packet.assign(signal_packet, signal_packet_len);
- continue;
- }
- }
- else if (m_async_packet_predicate.GetValue())
- {
- Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-
- // We are supposed to send an asynchronous packet while
- // we are running.
- m_async_response.Clear();
- if (m_async_packet.empty())
- {
- m_async_result = PacketResult::ErrorSendFailed;
- if (packet_log)
- packet_log->Printf ("async: error: empty async packet");
-
- }
- else
- {
- if (packet_log)
- packet_log->Printf ("async: sending packet");
-
- m_async_result = SendPacketAndWaitForResponse (&m_async_packet[0],
- m_async_packet.size(),
- m_async_response,
- false);
- }
- // Let the other thread that was trying to send the async
- // packet know that the packet has been sent and response is
- // ready...
- m_async_packet_predicate.SetValue(false, eBroadcastAlways);
-
- if (packet_log)
- packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);
-
- // Set the continue packet to resume if our interrupt
- // for the async packet did cause the stop
- if (continue_after_async)
- {
- // Reverting this for now as it is causing deadlocks
- // in programs (<rdar://problem/11529853>). In the future
- // we should check our thread list and "do the right thing"
- // for new threads that show up while we stop and run async
- // packets. Setting the packet to 'c' to continue all threads
- // is the right thing to do 99.99% of the time because if a
- // thread was single stepping, and we sent an interrupt, we
- // will notice above that we didn't stop due to an interrupt
- // but stopped due to stepping and we would _not_ continue.
- continue_packet.assign (1, 'c');
- continue;
- }
- }
- // Stop with signal and thread info
- state = eStateStopped;
- }
- break;
-
- case 'W':
- case 'X':
- // process exited
- state = eStateExited;
- break;
-
- case 'O':
- // STDOUT
- {
- got_async_packet = true;
- std::string inferior_stdout;
- inferior_stdout.reserve(response.GetBytesLeft () / 2);
-
- uint8_t ch;
- while (response.GetHexU8Ex(ch))
- {
- if (ch != 0)
- inferior_stdout.append(1, (char)ch);
- }
- process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
- }
- break;
-
- case 'A':
- // Async miscellaneous reply. Right now, only profile data is coming through this channel.
- {
- got_async_packet = true;
- std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
- if (m_partial_profile_data.length() > 0)
- {
- m_partial_profile_data.append(input);
- input = m_partial_profile_data;
- m_partial_profile_data.clear();
- }
-
- size_t found, pos = 0, len = input.length();
- while ((found = input.find(end_delimiter, pos)) != std::string::npos)
- {
- StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
- std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
- process->BroadcastAsyncProfileData (profile_data);
-
- pos = found + end_delimiter_len;
- }
-
- if (pos < len)
- {
- // Last incomplete chunk.
- m_partial_profile_data = input.substr(pos);
- }
- }
- break;
-
- case 'E':
- // ERROR
- state = eStateInvalid;
- break;
-
- default:
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
- state = eStateInvalid;
- break;
- }
- }
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(...) => false", __FUNCTION__);
- state = eStateInvalid;
- }
- }
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
- response.SetFilePos(0);
- m_private_is_running.SetValue (false, eBroadcastAlways);
- m_public_is_running.SetValue (false, eBroadcastAlways);
- return state;
-}
-
-bool
-GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
-{
- std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
- m_async_signal = signo;
- bool timed_out = false;
- Mutex::Locker locker;
- if (SendInterrupt (locker, 1, timed_out))
- return true;
- m_async_signal = -1;
- return false;
-}
-
-// This function takes a mutex locker as a parameter in case the GetSequenceMutex
-// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
-// (the expected result), then it will send the halt packet. If it does succeed
-// then the caller that requested the interrupt will want to keep the sequence
-// locked down so that no one else can send packets while the caller has control.
-// This function usually gets called when we are running and need to stop the
-// target. It can also be used when we are running and we need to do something
-// else (like read/write memory), so we need to interrupt the running process
-// (gdb remote protocol requires this), and do what we need to do, then resume.
-
-bool
-GDBRemoteCommunicationClient::SendInterrupt
-(
- Mutex::Locker& locker,
- uint32_t seconds_to_wait_for_stop,
- bool &timed_out
-)
-{
- timed_out = false;
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
-
- if (IsRunning())
- {
- // Only send an interrupt if our debugserver is running...
- if (GetSequenceMutex (locker))
- {
- if (log)
- log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
- }
- else
- {
- // Someone has the mutex locked waiting for a response or for the
- // inferior to stop, so send the interrupt on the down low...
- char ctrl_c = '\x03';
- ConnectionStatus status = eConnectionStatusSuccess;
- size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
- if (log)
- log->PutCString("send packet: \\x03");
- if (bytes_written > 0)
- {
- m_interrupt_sent = true;
- if (seconds_to_wait_for_stop)
- {
- TimeValue timeout;
- if (seconds_to_wait_for_stop)
- {
- timeout = TimeValue::Now();
- timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
- }
- if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
- {
- if (log)
- log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
- return true;
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
- }
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
- return true;
- }
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - failed to write interrupt");
- }
- return false;
- }
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - not running");
- }
- return true;
-}
-
-lldb::pid_t
-GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy)
-{
- if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
- return m_curr_pid;
-
- // First try to retrieve the pid via the qProcessInfo request.
- GetCurrentProcessInfo (allow_lazy);
- if (m_curr_pid_is_valid == eLazyBoolYes)
- {
- // We really got it.
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "packets with prefix '%s'",
+ payload_prefix);
+ return PacketResult::ErrorNoSequenceLock;
+ }
+
+ response_string = "";
+ std::string payload_prefix_str(payload_prefix);
+ unsigned int response_size = 0x1000;
+ if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
+ response_size = GetRemoteMaxPacketSize();
+ }
+
+ for (unsigned int offset = 0; true; offset += response_size) {
+ StringExtractorGDBRemote this_response;
+ // Construct payload
+ char sizeDescriptor[128];
+ snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
+ response_size);
+ PacketResult result = SendPacketAndWaitForResponseNoLock(
+ payload_prefix_str + sizeDescriptor, this_response);
+ if (result != PacketResult::Success)
+ return result;
+
+ const std::string &this_string = this_response.GetStringRef();
+
+ // Check for m or l as first character; l seems to mean this is the last
+ // chunk
+ char first_char = *this_string.c_str();
+ if (first_char != 'm' && first_char != 'l') {
+ return PacketResult::ErrorReplyInvalid;
+ }
+ // Concatenate the result so far (skipping 'm' or 'l')
+ response_string.append(this_string, 1, std::string::npos);
+ if (first_char == 'l')
+ // We're done
+ return PacketResult::Success;
+ }
+}
+
+lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
+ if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
+ return m_curr_pid;
+
+ // First try to retrieve the pid via the qProcessInfo request.
+ GetCurrentProcessInfo(allow_lazy);
+ if (m_curr_pid_is_valid == eLazyBoolYes) {
+ // We really got it.
+ return m_curr_pid;
+ } else {
+ // If we don't get a response for qProcessInfo, check if $qC gives us a
+ // result.
+ // $qC only returns a real process id on older debugserver and lldb-platform
+ // stubs.
+ // The gdb remote protocol documents $qC as returning the thread id, which
+ // newer
+ // debugserver and lldb-gdbserver stubs return correctly.
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qC", response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() == 'Q') {
+ if (response.GetChar() == 'C') {
+ m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
+ if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
+ m_curr_pid_is_valid = eLazyBoolYes;
+ return m_curr_pid;
+ }
+ }
+ }
+ }
+
+ // If we don't get a response for $qC, check if $qfThreadID gives us a
+ // result.
+ if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
+ std::vector<lldb::tid_t> thread_ids;
+ bool sequence_mutex_unavailable;
+ size_t size;
+ size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
+ if (size && sequence_mutex_unavailable == false) {
+ m_curr_pid = thread_ids.front();
+ m_curr_pid_is_valid = eLazyBoolYes;
return m_curr_pid;
+ }
+ }
+ }
+
+ return LLDB_INVALID_PROCESS_ID;
+}
+
+bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
+ error_str.clear();
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return true;
+ if (response.GetChar() == 'E') {
+ // A string the describes what failed when launching...
+ error_str = response.GetStringRef().substr(1);
+ } else {
+ error_str.assign("unknown error occurred launching process");
+ }
+ } else {
+ error_str.assign("timed out waiting for app to launch");
+ }
+ return false;
+}
+
+int GDBRemoteCommunicationClient::SendArgumentsPacket(
+ const ProcessLaunchInfo &launch_info) {
+ // Since we don't get the send argv0 separate from the executable path, we
+ // need to
+ // make sure to use the actual executable path found in the launch_info...
+ std::vector<const char *> argv;
+ FileSpec exe_file = launch_info.GetExecutableFile();
+ std::string exe_path;
+ const char *arg = NULL;
+ const Args &launch_args = launch_info.GetArguments();
+ if (exe_file)
+ exe_path = exe_file.GetPath(false);
+ else {
+ arg = launch_args.GetArgumentAtIndex(0);
+ if (arg)
+ exe_path = arg;
+ }
+ if (!exe_path.empty()) {
+ argv.push_back(exe_path.c_str());
+ for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL;
+ ++i) {
+ if (arg)
+ argv.push_back(arg);
+ }
+ }
+ if (!argv.empty()) {
+ StreamString packet;
+ packet.PutChar('A');
+ for (size_t i = 0, n = argv.size(); i < n; ++i) {
+ arg = argv[i];
+ const int arg_len = strlen(arg);
+ if (i > 0)
+ packet.PutChar(',');
+ packet.Printf("%i,%i,", arg_len * 2, (int)i);
+ packet.PutBytesAsRawHex8(arg, arg_len);
}
- else
- {
- // If we don't get a response for qProcessInfo, check if $qC gives us a result.
- // $qC only returns a real process id on older debugserver and lldb-platform stubs.
- // The gdb remote protocol documents $qC as returning the thread id, which newer
- // debugserver and lldb-gdbserver stubs return correctly.
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success)
- {
- if (response.GetChar() == 'Q')
- {
- if (response.GetChar() == 'C')
- {
- m_curr_pid = response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
- if (m_curr_pid != LLDB_INVALID_PROCESS_ID)
- {
- m_curr_pid_is_valid = eLazyBoolYes;
- return m_curr_pid;
- }
- }
- }
- }
-
- // If we don't get a response for $qC, check if $qfThreadID gives us a result.
- if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
- {
- std::vector<lldb::tid_t> thread_ids;
- bool sequence_mutex_unavailable;
- size_t size;
- size = GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
- if (size && sequence_mutex_unavailable == false)
- {
- m_curr_pid = thread_ids.front();
- m_curr_pid_is_valid = eLazyBoolYes;
- return m_curr_pid;
- }
- }
- }
-
- return LLDB_INVALID_PROCESS_ID;
-}
-bool
-GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
-{
- error_str.clear();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- if (response.GetChar() == 'E')
- {
- // A string the describes what failed when launching...
- error_str = response.GetStringRef().substr(1);
- }
- else
- {
- error_str.assign ("unknown error occurred launching process");
- }
- }
- else
- {
- error_str.assign ("timed out waiting for app to launch");
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return false;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
-{
- // Since we don't get the send argv0 separate from the executable path, we need to
- // make sure to use the actual executable path found in the launch_info...
- std::vector<const char *> argv;
- FileSpec exe_file = launch_info.GetExecutableFile();
- std::string exe_path;
- const char *arg = NULL;
- const Args &launch_args = launch_info.GetArguments();
- if (exe_file)
- exe_path = exe_file.GetPath(false);
- else
- {
- arg = launch_args.GetArgumentAtIndex(0);
- if (arg)
- exe_path = arg;
- }
- if (!exe_path.empty())
- {
- argv.push_back(exe_path.c_str());
- for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
- {
- if (arg)
- argv.push_back(arg);
+int GDBRemoteCommunicationClient::SendEnvironmentPacket(
+ char const *name_equal_value) {
+ 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) {
+ if (isprint(*p)) {
+ switch (*p) {
+ case '$':
+ case '#':
+ case '*':
+ case '}':
+ send_hex_encoding = true;
+ break;
+ default:
+ break;
}
+ } else {
+ // We have non printable characters, lets hex encode this...
+ send_hex_encoding = true;
+ }
}
- if (!argv.empty())
- {
- StreamString packet;
- packet.PutChar('A');
- for (size_t i = 0, n = argv.size(); i < n; ++i)
- {
- arg = argv[i];
- const int arg_len = strlen(arg);
- if (i > 0)
- packet.PutChar(',');
- packet.Printf("%i,%i,", arg_len * 2, (int)i);
- packet.PutBytesAsRawHex8 (arg, arg_len);
- }
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
+ StringExtractorGDBRemote response;
+ if (send_hex_encoding) {
+ if (m_supports_QEnvironmentHexEncoded) {
+ packet.PutCString("QEnvironmentHexEncoded:");
+ packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ if (response.IsUnsupportedResponse())
+ m_supports_QEnvironmentHexEncoded = false;
}
- }
- return -1;
-}
+ }
-int
-GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
-{
- 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)
- {
- if (isprint(*p))
- {
- switch (*p)
- {
- case '$':
- case '#':
- case '*':
- case '}':
- send_hex_encoding = true;
- break;
- default:
- break;
- }
- }
- else
- {
- // We have non printable characters, lets hex encode this...
- send_hex_encoding = true;
- }
- }
-
- StringExtractorGDBRemote response;
- if (send_hex_encoding)
- {
- if (m_supports_QEnvironmentHexEncoded)
- {
- packet.PutCString("QEnvironmentHexEncoded:");
- packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- if (response.IsUnsupportedResponse())
- m_supports_QEnvironmentHexEncoded = false;
- }
- }
-
- }
- else if (m_supports_QEnvironment)
- {
- packet.Printf("QEnvironment:%s", name_equal_value);
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- if (response.IsUnsupportedResponse())
- m_supports_QEnvironment = false;
- }
- }
+ } else if (m_supports_QEnvironment) {
+ packet.Printf("QEnvironment:%s", name_equal_value);
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ if (response.IsUnsupportedResponse())
+ m_supports_QEnvironment = false;
+ }
}
- return -1;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
-{
- if (arch && arch[0])
- {
- StreamString packet;
- packet.Printf("QLaunchArch:%s", arch);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
+int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
+ if (arch && arch[0]) {
+ StreamString packet;
+ packet.Printf("QLaunchArch:%s", arch);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SendLaunchEventDataPacket (char const *data, bool *was_supported)
-{
- if (data && *data != '\0')
- {
- StreamString packet;
- packet.Printf("QSetProcessEvent:%s", data);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- if (was_supported)
- *was_supported = true;
- return 0;
- }
- else if (response.IsUnsupportedResponse())
- {
- if (was_supported)
- *was_supported = false;
- return -1;
- }
- else
- {
- uint8_t error = response.GetError();
- if (was_supported)
- *was_supported = true;
- if (error)
- return error;
- }
- }
+int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
+ char const *data, bool *was_supported) {
+ if (data && *data != '\0') {
+ StreamString packet;
+ packet.Printf("QSetProcessEvent:%s", data);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ if (was_supported)
+ *was_supported = true;
+ return 0;
+ } else if (response.IsUnsupportedResponse()) {
+ if (was_supported)
+ *was_supported = false;
+ return -1;
+ } else {
+ uint8_t error = response.GetError();
+ if (was_supported)
+ *was_supported = true;
+ if (error)
+ return error;
+ }
}
- return -1;
+ }
+ return -1;
}
-bool
-GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
- uint32_t &minor,
- uint32_t &update)
-{
- if (GetHostInfo ())
- {
- if (m_os_version_major != UINT32_MAX)
- {
- major = m_os_version_major;
- minor = m_os_version_minor;
- update = m_os_version_update;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetOSVersion(uint32_t &major,
+ uint32_t &minor,
+ uint32_t &update) {
+ if (GetHostInfo()) {
+ if (m_os_version_major != UINT32_MAX) {
+ major = m_os_version_major;
+ minor = m_os_version_minor;
+ update = m_os_version_update;
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
-{
- if (GetHostInfo ())
- {
- if (!m_os_build.empty())
- {
- s = m_os_build;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
+ if (GetHostInfo()) {
+ if (!m_os_build.empty()) {
+ s = m_os_build;
+ return true;
}
- s.clear();
- return false;
+ }
+ s.clear();
+ return false;
}
-
-bool
-GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
-{
- if (GetHostInfo ())
- {
- if (!m_os_kernel.empty())
- {
- s = m_os_kernel;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
+ if (GetHostInfo()) {
+ if (!m_os_kernel.empty()) {
+ s = m_os_kernel;
+ return true;
}
- s.clear();
- return false;
+ }
+ s.clear();
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetHostname (std::string &s)
-{
- if (GetHostInfo ())
- {
- if (!m_hostname.empty())
- {
- s = m_hostname;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
+ if (GetHostInfo()) {
+ if (!m_hostname.empty()) {
+ s = m_hostname;
+ return true;
}
- s.clear();
- return false;
+ }
+ s.clear();
+ return false;
}
-ArchSpec
-GDBRemoteCommunicationClient::GetSystemArchitecture ()
-{
- if (GetHostInfo ())
- return m_host_arch;
- return ArchSpec();
+ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
+ if (GetHostInfo())
+ return m_host_arch;
+ return ArchSpec();
}
const lldb_private::ArchSpec &
-GDBRemoteCommunicationClient::GetProcessArchitecture ()
-{
- if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
- GetCurrentProcessInfo ();
- return m_process_arch;
+GDBRemoteCommunicationClient::GetProcessArchitecture() {
+ if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+ GetCurrentProcessInfo();
+ return m_process_arch;
}
-bool
-GDBRemoteCommunicationClient::GetGDBServerVersion()
-{
- if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate)
- {
- m_gdb_server_name.clear();
- m_gdb_server_version = 0;
- m_qGDBServerVersion_is_valid = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qGDBServerVersion", response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- std::string name;
- std::string value;
- bool success = false;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("name") == 0)
- {
- success = true;
- m_gdb_server_name.swap(value);
- }
- else if (name.compare("version") == 0)
- {
- size_t dot_pos = value.find('.');
- if (dot_pos != std::string::npos)
- value[dot_pos] = '\0';
- const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
- if (version != UINT32_MAX)
- {
- success = true;
- m_gdb_server_version = version;
- }
- }
- }
- if (success)
- m_qGDBServerVersion_is_valid = eLazyBoolYes;
- }
- }
- }
- return m_qGDBServerVersion_is_valid == eLazyBoolYes;
-}
+bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
+ if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
+ m_gdb_server_name.clear();
+ m_gdb_server_version = 0;
+ m_qGDBServerVersion_is_valid = eLazyBoolNo;
-void
-GDBRemoteCommunicationClient::MaybeEnableCompression (std::vector<std::string> supported_compressions)
-{
- CompressionType avail_type = CompressionType::None;
- std::string avail_name;
-
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "lzfse")
- {
- avail_type = CompressionType::LZFSE;
- avail_name = compression;
- break;
- }
- }
- }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name, value;
+ bool success = false;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("name")) {
+ success = true;
+ m_gdb_server_name = value;
+ } else if (name.equals("version")) {
+ llvm::StringRef major, minor;
+ std::tie(major, minor) = value.split('.');
+ if (!major.getAsInteger(0, m_gdb_server_version))
+ success = true;
+ }
+ }
+ if (success)
+ m_qGDBServerVersion_is_valid = eLazyBoolYes;
+ }
+ }
+ }
+ return m_qGDBServerVersion_is_valid == eLazyBoolYes;
+}
+
+void GDBRemoteCommunicationClient::MaybeEnableCompression(
+ std::vector<std::string> supported_compressions) {
+ CompressionType avail_type = CompressionType::None;
+ std::string avail_name;
+
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "lzfse") {
+ avail_type = CompressionType::LZFSE;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "zlib-deflate")
- {
- avail_type = CompressionType::ZlibDeflate;
- avail_name = compression;
- break;
- }
- }
- }
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "zlib-deflate") {
+ avail_type = CompressionType::ZlibDeflate;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
-#if defined (HAVE_LIBZ)
- if (avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "zlib-deflate")
- {
- avail_type = CompressionType::ZlibDeflate;
- avail_name = compression;
- break;
- }
- }
+#if defined(HAVE_LIBZ)
+ if (avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "zlib-deflate") {
+ avail_type = CompressionType::ZlibDeflate;
+ avail_name = compression;
+ break;
+ }
}
+ }
#endif
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "lz4")
- {
- avail_type = CompressionType::LZ4;
- avail_name = compression;
- break;
- }
- }
- }
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "lz4") {
+ avail_type = CompressionType::LZ4;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "lzma")
- {
- avail_type = CompressionType::LZMA;
- avail_name = compression;
- break;
- }
- }
- }
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "lzma") {
+ avail_type = CompressionType::LZMA;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
- if (avail_type != CompressionType::None)
- {
- StringExtractorGDBRemote response;
- std::string packet = "QEnableCompression:type:" + avail_name + ";";
- if (SendPacketAndWaitForResponse (packet.c_str(), response, false) != PacketResult::Success)
- return;
-
- if (response.IsOKResponse())
- {
- m_compression_type = avail_type;
- }
- }
-}
+ if (avail_type != CompressionType::None) {
+ StringExtractorGDBRemote response;
+ std::string packet = "QEnableCompression:type:" + avail_name + ";";
+ if (SendPacketAndWaitForResponse(packet, response, false) !=
+ PacketResult::Success)
+ return;
-const char *
-GDBRemoteCommunicationClient::GetGDBServerProgramName()
-{
- if (GetGDBServerVersion())
- {
- if (!m_gdb_server_name.empty())
- return m_gdb_server_name.c_str();
+ if (response.IsOKResponse()) {
+ m_compression_type = avail_type;
}
- return NULL;
+ }
}
-uint32_t
-GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
-{
- if (GetGDBServerVersion())
- return m_gdb_server_version;
- return 0;
+const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
+ if (GetGDBServerVersion()) {
+ if (!m_gdb_server_name.empty())
+ return m_gdb_server_name.c_str();
+ }
+ return NULL;
}
-bool
-GDBRemoteCommunicationClient::GetDefaultThreadId (lldb::tid_t &tid)
-{
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC",response,false) != PacketResult::Success)
- return false;
-
- if (!response.IsNormalResponse())
- return false;
-
- if (response.GetChar() == 'Q' && response.GetChar() == 'C')
- tid = response.GetHexMaxU32(true, -1);
-
- return true;
+uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
+ if (GetGDBServerVersion())
+ return m_gdb_server_version;
+ return 0;
}
-bool
-GDBRemoteCommunicationClient::GetHostInfo (bool force)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));
-
- if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
- {
- m_qHostInfo_is_valid = eLazyBoolNo;
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- std::string name;
- std::string value;
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
- std::string arch_name;
- std::string os_name;
- std::string vendor_name;
- std::string triple;
- std::string distribution_id;
- uint32_t pointer_byte_size = 0;
- StringExtractor extractor;
- ByteOrder byte_order = eByteOrderInvalid;
- uint32_t num_keys_decoded = 0;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("cputype") == 0)
- {
- // exception type in big endian hex
- cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
- if (cpu != LLDB_INVALID_CPUTYPE)
- ++num_keys_decoded;
- }
- else if (name.compare("cpusubtype") == 0)
- {
- // exception count in big endian hex
- sub = StringConvert::ToUInt32 (value.c_str(), 0, 0);
- if (sub != 0)
- ++num_keys_decoded;
- }
- else if (name.compare("arch") == 0)
- {
- arch_name.swap (value);
- ++num_keys_decoded;
- }
- else if (name.compare("triple") == 0)
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (triple);
- ++num_keys_decoded;
- }
- else if (name.compare ("distribution_id") == 0)
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (distribution_id);
- ++num_keys_decoded;
- }
- else if (name.compare("os_build") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (m_os_build);
- ++num_keys_decoded;
- }
- else if (name.compare("hostname") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (m_hostname);
- ++num_keys_decoded;
- }
- else if (name.compare("os_kernel") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (m_os_kernel);
- ++num_keys_decoded;
- }
- else if (name.compare("ostype") == 0)
- {
- os_name.swap (value);
- ++num_keys_decoded;
- }
- else if (name.compare("vendor") == 0)
- {
- vendor_name.swap(value);
- ++num_keys_decoded;
- }
- else if (name.compare("endian") == 0)
- {
- ++num_keys_decoded;
- if (value.compare("little") == 0)
- byte_order = eByteOrderLittle;
- else if (value.compare("big") == 0)
- byte_order = eByteOrderBig;
- else if (value.compare("pdp") == 0)
- byte_order = eByteOrderPDP;
- else
- --num_keys_decoded;
- }
- else if (name.compare("ptrsize") == 0)
- {
- pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0);
- if (pointer_byte_size != 0)
- ++num_keys_decoded;
- }
- else if ((name.compare("os_version") == 0) ||
- (name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"...
- {
- Args::StringToVersion (value.c_str(),
- m_os_version_major,
- m_os_version_minor,
- m_os_version_update);
- if (m_os_version_major != UINT32_MAX)
- ++num_keys_decoded;
- }
- else if (name.compare("watchpoint_exceptions_received") == 0)
- {
- ++num_keys_decoded;
- if (strcmp(value.c_str(),"before") == 0)
- m_watchpoints_trigger_after_instruction = eLazyBoolNo;
- else if (strcmp(value.c_str(),"after") == 0)
- m_watchpoints_trigger_after_instruction = eLazyBoolYes;
- else
- --num_keys_decoded;
- }
- else if (name.compare("default_packet_timeout") == 0)
- {
- m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0);
- if (m_default_packet_timeout > 0)
- {
- SetPacketTimeout(m_default_packet_timeout);
- ++num_keys_decoded;
- }
- }
+bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qC", response, false) !=
+ PacketResult::Success)
+ return false;
- }
-
- if (num_keys_decoded > 0)
- m_qHostInfo_is_valid = eLazyBoolYes;
-
- if (triple.empty())
- {
- if (arch_name.empty())
- {
- if (cpu != LLDB_INVALID_CPUTYPE)
- {
- m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_host_arch.GetByteOrder());
- }
-
- if (!vendor_name.empty())
- m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
- if (!os_name.empty())
- m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
-
- }
- }
- else
- {
- std::string triple;
- triple += arch_name;
- if (!vendor_name.empty() || !os_name.empty())
- {
- triple += '-';
- if (vendor_name.empty())
- triple += "unknown";
- else
- triple += vendor_name;
- triple += '-';
- if (os_name.empty())
- triple += "unknown";
- else
- triple += os_name;
- }
- m_host_arch.SetTriple (triple.c_str());
-
- llvm::Triple &host_triple = m_host_arch.GetTriple();
- if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
- {
- switch (m_host_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- host_triple.setOS(llvm::Triple::IOS);
- break;
- default:
- host_triple.setOS(llvm::Triple::MacOSX);
- break;
- }
- }
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_host_arch.GetByteOrder());
- }
-
- }
- }
- else
- {
- m_host_arch.SetTriple (triple.c_str());
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_host_arch.GetByteOrder());
- }
+ if (!response.IsNormalResponse())
+ return false;
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s parsed host architecture as %s, triple as %s from triple text %s", __FUNCTION__, m_host_arch.GetArchitectureName () ? m_host_arch.GetArchitectureName () : "<null-arch-name>", m_host_arch.GetTriple ().getTriple ().c_str(), triple.c_str ());
- }
- if (!distribution_id.empty ())
- m_host_arch.SetDistributionId (distribution_id.c_str ());
- }
- }
- }
- return m_qHostInfo_is_valid == eLazyBoolYes;
-}
+ if (response.GetChar() == 'Q' && response.GetChar() == 'C')
+ tid = response.GetHexMaxU32(true, -1);
-int
-GDBRemoteCommunicationClient::SendAttach
-(
- lldb::pid_t pid,
- StringExtractorGDBRemote& response
-)
-{
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
- assert (packet_len < (int)sizeof(packet));
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsErrorResponse())
- return response.GetError();
- return 0;
- }
- }
- return -1;
+ return true;
}
-int
-GDBRemoteCommunicationClient::SendStdinNotification (const char* data, size_t data_len)
-{
- StreamString packet;
- packet.PutCString("I");
- packet.PutBytesAsRawHex8(data, data_len);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- return 0;
- }
- return response.GetError();
+bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
+ if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
+ m_qHostInfo_is_valid = eLazyBoolNo;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string arch_name;
+ std::string os_name;
+ std::string vendor_name;
+ std::string triple;
+ std::string distribution_id;
+ uint32_t pointer_byte_size = 0;
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t num_keys_decoded = 0;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("cputype")) {
+ // exception type in big endian hex
+ if (!value.getAsInteger(0, cpu))
+ ++num_keys_decoded;
+ } else if (name.equals("cpusubtype")) {
+ // exception count in big endian hex
+ if (!value.getAsInteger(0, sub))
+ ++num_keys_decoded;
+ } else if (name.equals("arch")) {
+ arch_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("triple")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(triple);
+ ++num_keys_decoded;
+ } else if (name.equals("distribution_id")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(distribution_id);
+ ++num_keys_decoded;
+ } else if (name.equals("os_build")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(m_os_build);
+ ++num_keys_decoded;
+ } else if (name.equals("hostname")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(m_hostname);
+ ++num_keys_decoded;
+ } else if (name.equals("os_kernel")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(m_os_kernel);
+ ++num_keys_decoded;
+ } else if (name.equals("ostype")) {
+ os_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("vendor")) {
+ vendor_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("endian")) {
+ byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
+ .Case("little", eByteOrderLittle)
+ .Case("big", eByteOrderBig)
+ .Case("pdp", eByteOrderPDP)
+ .Default(eByteOrderInvalid);
+ if (byte_order != eByteOrderInvalid)
+ ++num_keys_decoded;
+ } else if (name.equals("ptrsize")) {
+ if (!value.getAsInteger(0, pointer_byte_size))
+ ++num_keys_decoded;
+ } else if (name.equals("os_version") ||
+ name.equals(
+ "version")) // Older debugserver binaries used the
+ // "version" key instead of
+ // "os_version"...
+ {
+ Args::StringToVersion(value, m_os_version_major, m_os_version_minor,
+ m_os_version_update);
+ if (m_os_version_major != UINT32_MAX)
+ ++num_keys_decoded;
+ } else if (name.equals("watchpoint_exceptions_received")) {
+ m_watchpoints_trigger_after_instruction =
+ llvm::StringSwitch<LazyBool>(value)
+ .Case("before", eLazyBoolNo)
+ .Case("after", eLazyBoolYes)
+ .Default(eLazyBoolCalculate);
+ if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
+ ++num_keys_decoded;
+ } else if (name.equals("default_packet_timeout")) {
+ uint32_t timeout_seconds;
+ if (!value.getAsInteger(0, timeout_seconds)) {
+ m_default_packet_timeout = seconds(timeout_seconds);
+ SetPacketTimeout(m_default_packet_timeout);
+ ++num_keys_decoded;
+ }
+ }
+ }
+
+ if (num_keys_decoded > 0)
+ m_qHostInfo_is_valid = eLazyBoolYes;
+
+ if (triple.empty()) {
+ if (arch_name.empty()) {
+ if (cpu != LLDB_INVALID_CPUTYPE) {
+ m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_host_arch.GetByteOrder());
+ }
+
+ if (!vendor_name.empty())
+ m_host_arch.GetTriple().setVendorName(
+ llvm::StringRef(vendor_name));
+ if (!os_name.empty())
+ m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ }
+ } else {
+ std::string triple;
+ triple += arch_name;
+ if (!vendor_name.empty() || !os_name.empty()) {
+ triple += '-';
+ if (vendor_name.empty())
+ triple += "unknown";
+ else
+ triple += vendor_name;
+ triple += '-';
+ if (os_name.empty())
+ triple += "unknown";
+ else
+ triple += os_name;
+ }
+ m_host_arch.SetTriple(triple.c_str());
+
+ llvm::Triple &host_triple = m_host_arch.GetTriple();
+ if (host_triple.getVendor() == llvm::Triple::Apple &&
+ host_triple.getOS() == llvm::Triple::Darwin) {
+ switch (m_host_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ host_triple.setOS(llvm::Triple::IOS);
+ break;
+ default:
+ host_triple.setOS(llvm::Triple::MacOSX);
+ break;
+ }
+ }
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_host_arch.GetByteOrder());
+ }
+ }
+ } else {
+ m_host_arch.SetTriple(triple.c_str());
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_host_arch.GetByteOrder());
+ }
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s parsed host "
+ "architecture as %s, triple as %s from triple text %s",
+ __FUNCTION__, m_host_arch.GetArchitectureName()
+ ? m_host_arch.GetArchitectureName()
+ : "<null-arch-name>",
+ m_host_arch.GetTriple().getTriple().c_str(),
+ triple.c_str());
+ }
+ if (!distribution_id.empty())
+ m_host_arch.SetDistributionId(distribution_id.c_str());
+ }
+ }
+ }
+ return m_qHostInfo_is_valid == eLazyBoolYes;
+}
+
+int GDBRemoteCommunicationClient::SendAttach(
+ lldb::pid_t pid, StringExtractorGDBRemote &response) {
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ assert(packet_len < (int)sizeof(packet));
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsErrorResponse())
+ return response.GetError();
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
+ size_t data_len) {
+ StreamString packet;
+ packet.PutCString("I");
+ packet.PutBytesAsRawHex8(data, data_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ return 0;
+ }
+ return response.GetError();
}
const lldb_private::ArchSpec &
-GDBRemoteCommunicationClient::GetHostArchitecture ()
-{
- if (m_qHostInfo_is_valid == eLazyBoolCalculate)
- GetHostInfo ();
- return m_host_arch;
+GDBRemoteCommunicationClient::GetHostArchitecture() {
+ if (m_qHostInfo_is_valid == eLazyBoolCalculate)
+ GetHostInfo();
+ return m_host_arch;
}
-uint32_t
-GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
-{
- if (m_qHostInfo_is_valid == eLazyBoolCalculate)
- GetHostInfo ();
- return m_default_packet_timeout;
+seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
+ if (m_qHostInfo_is_valid == eLazyBoolCalculate)
+ GetHostInfo();
+ return m_default_packet_timeout;
}
-addr_t
-GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
-{
- if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
- {
- m_supports_alloc_dealloc_memory = eLazyBoolYes;
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
- (uint64_t)size,
- permissions & lldb::ePermissionsReadable ? "r" : "",
- permissions & lldb::ePermissionsWritable ? "w" : "",
- permissions & lldb::ePermissionsExecutable ? "x" : "");
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- else if (!response.IsErrorResponse())
- return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
- }
- else
- {
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- }
- }
- return LLDB_INVALID_ADDRESS;
+addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
+ uint32_t permissions) {
+ if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
+ m_supports_alloc_dealloc_memory = eLazyBoolYes;
+ char packet[64];
+ const int packet_len = ::snprintf(
+ packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
+ permissions & lldb::ePermissionsReadable ? "r" : "",
+ permissions & lldb::ePermissionsWritable ? "w" : "",
+ permissions & lldb::ePermissionsExecutable ? "x" : "");
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ else if (!response.IsErrorResponse())
+ return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+ } else {
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
+ if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
+ m_supports_alloc_dealloc_memory = eLazyBoolYes;
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ else if (response.IsOKResponse())
+ return true;
+ } else {
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ }
+ }
+ return false;
+}
+
+Error GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
+ Error error;
+
+ if (keep_stopped) {
+ if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success &&
+ response.IsOKResponse()) {
+ m_supports_detach_stay_stopped = eLazyBoolYes;
+ } else {
+ m_supports_detach_stay_stopped = eLazyBoolNo;
+ }
+ }
+
+ if (m_supports_detach_stay_stopped == eLazyBoolNo) {
+ error.SetErrorString("Stays stopped not supported by this target.");
+ return error;
+ } else {
+ StringExtractorGDBRemote response;
+ PacketResult packet_result =
+ SendPacketAndWaitForResponse("D1", response, false);
+ if (packet_result != PacketResult::Success)
+ error.SetErrorString("Sending extended disconnect packet failed.");
+ }
+ } else {
+ StringExtractorGDBRemote response;
+ PacketResult packet_result =
+ SendPacketAndWaitForResponse("D", response, false);
+ if (packet_result != PacketResult::Success)
+ error.SetErrorString("Sending disconnect packet failed.");
+ }
+ return error;
}
-bool
-GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
-{
- if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
- {
- m_supports_alloc_dealloc_memory = eLazyBoolYes;
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- else if (response.IsOKResponse())
- return true;
- }
- else
- {
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- }
- }
- return false;
-}
+Error GDBRemoteCommunicationClient::GetMemoryRegionInfo(
+ lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
+ Error error;
+ region_info.Clear();
-Error
-GDBRemoteCommunicationClient::Detach (bool keep_stopped)
-{
- Error error;
-
- if (keep_stopped)
- {
- if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
- {
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success
- && response.IsOKResponse())
- {
- m_supports_detach_stay_stopped = eLazyBoolYes;
- }
+ if (m_supports_memory_region_info != eLazyBoolNo) {
+ m_supports_memory_region_info = eLazyBoolYes;
+ char packet[64];
+ const int packet_len = ::snprintf(
+ packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ addr_t addr_value = LLDB_INVALID_ADDRESS;
+ bool success = true;
+ bool saw_permissions = false;
+ while (success && response.GetNameColonValue(name, value)) {
+ if (name.equals("start")) {
+ if (!value.getAsInteger(16, addr_value))
+ region_info.GetRange().SetRangeBase(addr_value);
+ } else if (name.equals("size")) {
+ if (!value.getAsInteger(16, addr_value))
+ region_info.GetRange().SetByteSize(addr_value);
+ } else if (name.equals("permissions") &&
+ region_info.GetRange().IsValid()) {
+ saw_permissions = true;
+ if (region_info.GetRange().Contains(addr)) {
+ if (value.find('r') != llvm::StringRef::npos)
+ region_info.SetReadable(MemoryRegionInfo::eYes);
else
- {
- m_supports_detach_stay_stopped = eLazyBoolNo;
- }
- }
+ region_info.SetReadable(MemoryRegionInfo::eNo);
- if (m_supports_detach_stay_stopped == eLazyBoolNo)
- {
- error.SetErrorString("Stays stopped not supported by this target.");
- return error;
- }
- else
- {
- StringExtractorGDBRemote response;
- PacketResult packet_result = SendPacketAndWaitForResponse ("D1", 2, response, false);
- if (packet_result != PacketResult::Success)
- error.SetErrorString ("Sending extended disconnect packet failed.");
- }
- }
- else
- {
- StringExtractorGDBRemote response;
- PacketResult packet_result = SendPacketAndWaitForResponse ("D", 1, response, false);
- if (packet_result != PacketResult::Success)
- error.SetErrorString ("Sending disconnect packet failed.");
- }
- return error;
-}
+ if (value.find('w') != llvm::StringRef::npos)
+ region_info.SetWritable(MemoryRegionInfo::eYes);
+ else
+ region_info.SetWritable(MemoryRegionInfo::eNo);
-Error
-GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
- lldb_private::MemoryRegionInfo &region_info)
-{
- Error error;
+ if (value.find('x') != llvm::StringRef::npos)
+ region_info.SetExecutable(MemoryRegionInfo::eYes);
+ else
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+
+ region_info.SetMapped(MemoryRegionInfo::eYes);
+ } else {
+ // The reported region does not contain this address -- we're
+ // looking at an unmapped page
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ }
+ } else if (name.equals("name")) {
+ StringExtractorGDBRemote name_extractor(value);
+ std::string name;
+ name_extractor.GetHexByteString(name);
+ region_info.SetName(name.c_str());
+ } else if (name.equals("error")) {
+ StringExtractorGDBRemote error_extractor(value);
+ std::string error_string;
+ // Now convert the HEX bytes into a string value
+ error_extractor.GetHexByteString(error_string);
+ error.SetErrorString(error_string.c_str());
+ }
+ }
+
+ // We got a valid address range back but no permissions -- which means
+ // this is an unmapped page
+ if (region_info.GetRange().IsValid() && saw_permissions == false) {
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ }
+ } else {
+ m_supports_memory_region_info = eLazyBoolNo;
+ }
+ }
+
+ if (m_supports_memory_region_info == eLazyBoolNo) {
+ error.SetErrorString("qMemoryRegionInfo is not supported");
+ }
+ if (error.Fail())
region_info.Clear();
-
- if (m_supports_memory_region_info != eLazyBoolNo)
- {
- m_supports_memory_region_info = eLazyBoolYes;
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- std::string name;
- std::string value;
- addr_t addr_value;
- bool success = true;
- bool saw_permissions = false;
- while (success && response.GetNameColonValue(name, value))
- {
- if (name.compare ("start") == 0)
- {
- addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
- if (success)
- region_info.GetRange().SetRangeBase(addr_value);
- }
- else if (name.compare ("size") == 0)
- {
- addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success);
- if (success)
- region_info.GetRange().SetByteSize (addr_value);
- }
- else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
- {
- saw_permissions = true;
- if (region_info.GetRange().Contains (addr))
- {
- if (value.find('r') != std::string::npos)
- region_info.SetReadable (MemoryRegionInfo::eYes);
- else
- region_info.SetReadable (MemoryRegionInfo::eNo);
-
- if (value.find('w') != std::string::npos)
- region_info.SetWritable (MemoryRegionInfo::eYes);
- else
- region_info.SetWritable (MemoryRegionInfo::eNo);
-
- if (value.find('x') != std::string::npos)
- region_info.SetExecutable (MemoryRegionInfo::eYes);
- else
- region_info.SetExecutable (MemoryRegionInfo::eNo);
-
- region_info.SetMapped(MemoryRegionInfo::eYes);
- }
- else
- {
- // The reported region does not contain this address -- we're looking at an unmapped page
- region_info.SetReadable (MemoryRegionInfo::eNo);
- region_info.SetWritable (MemoryRegionInfo::eNo);
- region_info.SetExecutable (MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- }
- else if (name.compare ("error") == 0)
- {
- StringExtractorGDBRemote name_extractor;
- // Swap "value" over into "name_extractor"
- name_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- name_extractor.GetHexByteString (value);
- error.SetErrorString(value.c_str());
- }
- }
-
- // We got a valid address range back but no permissions -- which means this is an unmapped page
- if (region_info.GetRange().IsValid() && saw_permissions == false)
- {
- region_info.SetReadable (MemoryRegionInfo::eNo);
- region_info.SetWritable (MemoryRegionInfo::eNo);
- region_info.SetExecutable (MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- }
- else
- {
- m_supports_memory_region_info = eLazyBoolNo;
- }
- }
-
- if (m_supports_memory_region_info == eLazyBoolNo)
- {
- error.SetErrorString("qMemoryRegionInfo is not supported");
- }
- if (error.Fail())
- region_info.Clear();
- return error;
-
+ return error;
}
-Error
-GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
-{
- Error error;
+Error GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
+ Error error;
- if (m_supports_watchpoint_support_info == eLazyBoolYes)
- {
- num = m_num_supported_hardware_watchpoints;
- return error;
- }
+ if (m_supports_watchpoint_support_info == eLazyBoolYes) {
+ num = m_num_supported_hardware_watchpoints;
+ return error;
+ }
- // Set num to 0 first.
- num = 0;
- if (m_supports_watchpoint_support_info != eLazyBoolNo)
- {
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- m_supports_watchpoint_support_info = eLazyBoolYes;
- std::string name;
- std::string value;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare ("num") == 0)
- {
- num = StringConvert::ToUInt32(value.c_str(), 0, 0);
- m_num_supported_hardware_watchpoints = num;
- }
- }
- }
- else
- {
- m_supports_watchpoint_support_info = eLazyBoolNo;
+ // Set num to 0 first.
+ num = 0;
+ if (m_supports_watchpoint_support_info != eLazyBoolNo) {
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ m_supports_watchpoint_support_info = eLazyBoolYes;
+ llvm::StringRef name;
+ llvm::StringRef value;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("num")) {
+ value.getAsInteger(0, m_num_supported_hardware_watchpoints);
+ num = m_num_supported_hardware_watchpoints;
}
+ }
+ } else {
+ m_supports_watchpoint_support_info = eLazyBoolNo;
}
+ }
- if (m_supports_watchpoint_support_info == eLazyBoolNo)
- {
- error.SetErrorString("qWatchpointSupportInfo is not supported");
- }
- return error;
-
+ if (m_supports_watchpoint_support_info == eLazyBoolNo) {
+ error.SetErrorString("qWatchpointSupportInfo is not supported");
+ }
+ return error;
}
-lldb_private::Error
-GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch)
-{
- Error error(GetWatchpointSupportInfo(num));
- if (error.Success())
- error = GetWatchpointsTriggerAfterInstruction(after, arch);
- return error;
+lldb_private::Error GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
+ uint32_t &num, bool &after, const ArchSpec &arch) {
+ Error error(GetWatchpointSupportInfo(num));
+ if (error.Success())
+ error = GetWatchpointsTriggerAfterInstruction(after, arch);
+ return error;
}
lldb_private::Error
-GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch)
-{
- Error error;
- llvm::Triple::ArchType atype = arch.GetMachine();
-
- // we assume watchpoints will happen after running the relevant opcode
- // and we only want to override this behavior if we have explicitly
- // received a qHostInfo telling us otherwise
- if (m_qHostInfo_is_valid != eLazyBoolYes)
- {
- // On targets like MIPS, watchpoint exceptions are always generated
- // before the instruction is executed. The connected target may not
- // support qHostInfo or qWatchpointSupportInfo packets.
- if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
- || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
- after = false;
- else
- after = true;
- }
+GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
+ bool &after, const ArchSpec &arch) {
+ Error error;
+ llvm::Triple::ArchType atype = arch.GetMachine();
+
+ // we assume watchpoints will happen after running the relevant opcode
+ // and we only want to override this behavior if we have explicitly
+ // received a qHostInfo telling us otherwise
+ if (m_qHostInfo_is_valid != eLazyBoolYes) {
+ // On targets like MIPS, watchpoint exceptions are always generated
+ // before the instruction is executed. The connected target may not
+ // support qHostInfo or qWatchpointSupportInfo packets.
+ if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
+ after = false;
else
- {
- // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
- // if it is not calculated before.
- if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
- (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
- || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
- m_watchpoints_trigger_after_instruction = eLazyBoolNo;
-
- after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
- }
- return error;
-}
-
-int
-GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec)
-{
- if (file_spec)
- {
- std::string path{file_spec.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetSTDIN:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
+ after = true;
+ } else {
+ // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
+ // if it is not calculated before.
+ if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
+ (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
+ m_watchpoints_trigger_after_instruction = eLazyBoolNo;
+
+ after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
+ }
+ return error;
+}
+
+int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
+ if (file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetSTDIN:");
+ packet.PutCStringAsRawHex8(path.c_str());
-int
-GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec)
-{
- if (file_spec)
- {
- std::string path{file_spec.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetSTDOUT:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec)
-{
- if (file_spec)
- {
- std::string path{file_spec.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetSTDERR:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
+int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
+ if (file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetSTDOUT:");
+ packet.PutCStringAsRawHex8(path.c_str());
-bool
-GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir)
-{
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- return false;
- if (response.IsErrorResponse())
- return false;
- std::string cwd;
- response.GetHexByteString(cwd);
- working_dir.SetFile(cwd, false, GetHostArchitecture());
- return !cwd.empty();
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return false;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir)
-{
- if (working_dir)
- {
- std::string path{working_dir.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetWorkingDir:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
+int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
+ if (file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetSTDERR:");
+ packet.PutCStringAsRawHex8(path.c_str());
-int
-GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
-{
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
- assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
-}
+ }
+ return -1;
+}
+
+bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ return false;
+ if (response.IsErrorResponse())
+ return false;
+ std::string cwd;
+ response.GetHexByteString(cwd);
+ working_dir.SetFile(cwd, false, GetHostArchitecture());
+ return !cwd.empty();
+ }
+ return false;
+}
+
+int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
+ if (working_dir) {
+ std::string path{working_dir.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetWorkingDir:");
+ packet.PutCStringAsRawHex8(path.c_str());
-int
-GDBRemoteCommunicationClient::SetDetachOnError (bool enable)
-{
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDetachOnError:%i", enable ? 1 : 0);
- assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
-}
-
+ }
+ return -1;
+}
+
+int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ return -1;
+}
+
+int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
+ char packet[32];
+ const int packet_len = ::snprintf(packet, sizeof(packet),
+ "QSetDetachOnError:%i", enable ? 1 : 0);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ return -1;
+}
+
+bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
+ StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ StringExtractor extractor;
-bool
-GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
-{
- if (response.IsNormalResponse())
- {
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string vendor;
+ std::string os_type;
+
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("pid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ value.getAsInteger(0, pid);
+ process_info.SetProcessID(pid);
+ } else if (name.equals("ppid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ value.getAsInteger(0, pid);
+ process_info.SetParentProcessID(pid);
+ } else if (name.equals("uid")) {
+ uint32_t uid = UINT32_MAX;
+ value.getAsInteger(0, uid);
+ process_info.SetUserID(uid);
+ } else if (name.equals("euid")) {
+ uint32_t uid = UINT32_MAX;
+ value.getAsInteger(0, uid);
+ process_info.SetEffectiveGroupID(uid);
+ } else if (name.equals("gid")) {
+ uint32_t gid = UINT32_MAX;
+ value.getAsInteger(0, gid);
+ process_info.SetGroupID(gid);
+ } else if (name.equals("egid")) {
+ uint32_t gid = UINT32_MAX;
+ value.getAsInteger(0, gid);
+ process_info.SetEffectiveGroupID(gid);
+ } else if (name.equals("triple")) {
+ StringExtractor extractor(value);
+ std::string triple;
+ extractor.GetHexByteString(triple);
+ process_info.GetArchitecture().SetTriple(triple.c_str());
+ } else if (name.equals("name")) {
+ StringExtractor extractor(value);
+ // The process name from ASCII hex bytes since we can't
+ // control the characters in a process name
std::string name;
- std::string value;
- StringExtractor extractor;
-
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
- std::string vendor;
- std::string os_type;
-
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("pid") == 0)
- {
- process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
- }
- else if (name.compare("ppid") == 0)
- {
- process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
- }
- else if (name.compare("uid") == 0)
- {
- process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("euid") == 0)
- {
- process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("gid") == 0)
- {
- process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("egid") == 0)
- {
- process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("triple") == 0)
- {
- StringExtractor extractor;
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (value);
- process_info.GetArchitecture ().SetTriple (value.c_str());
- }
- else if (name.compare("name") == 0)
- {
- StringExtractor extractor;
- // The process name from ASCII hex bytes since we can't
- // control the characters in a process name
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (value);
- process_info.GetExecutableFile().SetFile (value.c_str(), false);
- }
- else if (name.compare("cputype") == 0)
- {
- cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
- }
- else if (name.compare("cpusubtype") == 0)
- {
- sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- }
- else if (name.compare("vendor") == 0)
- {
- vendor = value;
- }
- else if (name.compare("ostype") == 0)
- {
- os_type = value;
- }
- }
-
- if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty())
- {
- if (vendor == "apple")
- {
- process_info.GetArchitecture().SetArchitecture (eArchTypeMachO, cpu, sub);
- process_info.GetArchitecture().GetTriple().setVendorName (llvm::StringRef (vendor));
- process_info.GetArchitecture().GetTriple().setOSName (llvm::StringRef (os_type));
- }
- }
-
- if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- return true;
- }
- return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- process_info.Clear();
-
- if (m_supports_qProcessInfoPID)
- {
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- return DecodeProcessInfoResponse (response, process_info);
- }
- else
- {
- m_supports_qProcessInfoPID = false;
- return false;
- }
- }
- return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
-
- if (allow_lazy)
- {
- if (m_qProcessInfo_is_valid == eLazyBoolYes)
- return true;
- if (m_qProcessInfo_is_valid == eLazyBoolNo)
- return false;
- }
-
- GetHostInfo ();
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- std::string name;
- std::string value;
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
- std::string arch_name;
- std::string os_name;
- std::string vendor_name;
- std::string triple;
- std::string elf_abi;
- uint32_t pointer_byte_size = 0;
- StringExtractor extractor;
- ByteOrder byte_order = eByteOrderInvalid;
- uint32_t num_keys_decoded = 0;
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("cputype") == 0)
- {
- cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
- if (cpu != LLDB_INVALID_CPUTYPE)
- ++num_keys_decoded;
- }
- else if (name.compare("cpusubtype") == 0)
- {
- sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- if (sub != 0)
- ++num_keys_decoded;
- }
- else if (name.compare("triple") == 0)
- {
- StringExtractor extractor;
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (triple);
- ++num_keys_decoded;
- }
- else if (name.compare("ostype") == 0)
- {
- os_name.swap (value);
- ++num_keys_decoded;
- }
- else if (name.compare("vendor") == 0)
- {
- vendor_name.swap(value);
- ++num_keys_decoded;
- }
- else if (name.compare("endian") == 0)
- {
- ++num_keys_decoded;
- if (value.compare("little") == 0)
- byte_order = eByteOrderLittle;
- else if (value.compare("big") == 0)
- byte_order = eByteOrderBig;
- else if (value.compare("pdp") == 0)
- byte_order = eByteOrderPDP;
- else
- --num_keys_decoded;
- }
- else if (name.compare("ptrsize") == 0)
- {
- pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- if (pointer_byte_size != 0)
- ++num_keys_decoded;
- }
- else if (name.compare("pid") == 0)
- {
- pid = StringConvert::ToUInt64(value.c_str(), 0, 16);
- if (pid != LLDB_INVALID_PROCESS_ID)
- ++num_keys_decoded;
- }
- else if (name.compare("elf_abi") == 0)
- {
- elf_abi = value;
- ++num_keys_decoded;
- }
- }
- if (num_keys_decoded > 0)
- m_qProcessInfo_is_valid = eLazyBoolYes;
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- m_curr_pid_is_valid = eLazyBoolYes;
- m_curr_pid = pid;
- }
-
- // Set the ArchSpec from the triple if we have it.
- if (!triple.empty ())
- {
- m_process_arch.SetTriple (triple.c_str ());
- m_process_arch.SetFlags(elf_abi);
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
- }
- }
- else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
- {
- llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
-
- assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
- switch (triple.getObjectFormat()) {
- case llvm::Triple::MachO:
- m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
- break;
- case llvm::Triple::ELF:
- m_process_arch.SetArchitecture (eArchTypeELF, cpu, sub);
- break;
- case llvm::Triple::COFF:
- m_process_arch.SetArchitecture (eArchTypeCOFF, cpu, sub);
- break;
- case llvm::Triple::UnknownObjectFormat:
- if (log)
- log->Printf("error: failed to determine target architecture");
- return false;
- }
-
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_process_arch.GetByteOrder());
- }
- m_process_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
- m_process_arch.GetTriple().setOSName(llvm::StringRef (os_name));
- m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
- m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
- }
- return true;
- }
- }
- else
- {
- m_qProcessInfo_is_valid = eLazyBoolNo;
- }
-
- return false;
-}
-
-
-uint32_t
-GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- process_infos.Clear();
-
- if (m_supports_qfProcessInfo)
- {
- StreamString packet;
- packet.PutCString ("qfProcessInfo");
- if (!match_info.MatchAllProcesses())
- {
- packet.PutChar (':');
- const char *name = match_info.GetProcessInfo().GetName();
- bool has_name_match = false;
- if (name && name[0])
- {
- has_name_match = true;
- NameMatchType name_match_type = match_info.GetNameMatchType();
- switch (name_match_type)
- {
- case eNameMatchIgnore:
- has_name_match = false;
- break;
-
- case eNameMatchEquals:
- packet.PutCString ("name_match:equals;");
- break;
-
- case eNameMatchContains:
- packet.PutCString ("name_match:contains;");
- break;
-
- case eNameMatchStartsWith:
- packet.PutCString ("name_match:starts_with;");
- break;
-
- case eNameMatchEndsWith:
- packet.PutCString ("name_match:ends_with;");
- break;
-
- case eNameMatchRegularExpression:
- packet.PutCString ("name_match:regex;");
- break;
- }
- if (has_name_match)
- {
- packet.PutCString ("name:");
- packet.PutBytesAsRawHex8(name, ::strlen(name));
- packet.PutChar (';');
- }
- }
-
- if (match_info.GetProcessInfo().ProcessIDIsValid())
- packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
- if (match_info.GetProcessInfo().ParentProcessIDIsValid())
- packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
- if (match_info.GetProcessInfo().UserIDIsValid())
- packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
- if (match_info.GetProcessInfo().GroupIDIsValid())
- packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
- if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
- packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
- if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
- packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
- if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
- packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
- if (match_info.GetProcessInfo().GetArchitecture().IsValid())
- {
- const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
- const llvm::Triple &triple = match_arch.GetTriple();
- packet.PutCString("triple:");
- packet.PutCString(triple.getTriple().c_str());
- packet.PutChar (';');
- }
- }
- StringExtractorGDBRemote response;
- // Increase timeout as the first qfProcessInfo packet takes a long time
- // on Android. The value of 1min was arrived at empirically.
- GDBRemoteCommunication::ScopedTimeout timeout (*this, 60);
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- do
- {
- ProcessInstanceInfo process_info;
- if (!DecodeProcessInfoResponse (response, process_info))
- break;
- process_infos.Append(process_info);
- response.GetStringRef().clear();
- response.SetFilePos(0);
- } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
- }
- else
- {
- m_supports_qfProcessInfo = false;
- return 0;
- }
- }
- return process_infos.GetSize();
-
-}
-
-bool
-GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
-{
- if (m_supports_qUserName)
- {
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- // Make sure we parsed the right number of characters. The response is
- // the hex encoded user name and should make up the entire packet.
- // If there are any non-hex ASCII bytes, the length won't match below..
- if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
- return true;
- }
- }
- else
- {
- m_supports_qUserName = false;
- return false;
- }
- }
- return false;
-
-}
-
-bool
-GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
-{
- if (m_supports_qGroupName)
- {
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- // Make sure we parsed the right number of characters. The response is
- // the hex encoded group name and should make up the entire packet.
- // If there are any non-hex ASCII bytes, the length won't match below..
- if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
- return true;
- }
- }
- else
- {
- m_supports_qGroupName = false;
- return false;
- }
- }
- return false;
-}
-
-bool
-GDBRemoteCommunicationClient::SetNonStopMode (const bool enable)
-{
- // Form non-stop packet request
+ extractor.GetHexByteString(name);
+ process_info.GetExecutableFile().SetFile(name, false);
+ } else if (name.equals("cputype")) {
+ value.getAsInteger(0, cpu);
+ } else if (name.equals("cpusubtype")) {
+ value.getAsInteger(0, sub);
+ } else if (name.equals("vendor")) {
+ vendor = value;
+ } else if (name.equals("ostype")) {
+ os_type = value;
+ }
+ }
+
+ if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
+ if (vendor == "apple") {
+ process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
+ sub);
+ process_info.GetArchitecture().GetTriple().setVendorName(
+ llvm::StringRef(vendor));
+ process_info.GetArchitecture().GetTriple().setOSName(
+ llvm::StringRef(os_type));
+ }
+ }
+
+ if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetProcessInfo(
+ lldb::pid_t pid, ProcessInstanceInfo &process_info) {
+ process_info.Clear();
+
+ if (m_supports_qProcessInfoPID) {
char packet[32];
- const int packet_len = ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
assert(packet_len < (int)sizeof(packet));
-
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- // Send to target
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- if (response.IsOKResponse())
- return true;
-
- // Failed or not supported
- return false;
-
-}
-
-static void
-MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
-{
- packet.Clear();
- packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
- uint32_t bytes_left = send_size;
- while (bytes_left > 0)
- {
- if (bytes_left >= 26)
- {
- packet.PutCString("abcdefghijklmnopqrstuvwxyz");
- bytes_left -= 26;
- }
- else
- {
- packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
- bytes_left = 0;
- }
- }
-}
-
-template<typename T>
-T calculate_standard_deviation(const std::vector<T> &v)
-{
- T sum = std::accumulate(std::begin(v), std::end(v), T(0));
- T mean = sum / (T)v.size();
- T accum = T(0);
- std::for_each (std::begin(v), std::end(v), [&](const T d) {
- T delta = d - mean;
- accum += delta * delta;
- });
-
- T stdev = sqrt(accum / (v.size()-1));
- return stdev;
-}
-
-void
-GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm)
-{
- uint32_t i;
- TimeValue start_time, end_time;
- uint64_t total_time_nsec;
- if (SendSpeedTestPacket (0, 0))
- {
- StreamString packet;
- if (json)
- strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n \"results\" : [", num_packets);
- else
- strm.Printf("Testing sending %u packets of various sizes:\n", num_packets);
- strm.Flush();
-
- uint32_t result_idx = 0;
- uint32_t send_size;
- std::vector<float> packet_times;
-
- for (send_size = 0; send_size <= max_send; send_size ? send_size *= 2 : send_size = 4)
- {
- for (uint32_t recv_size = 0; recv_size <= max_recv; recv_size ? recv_size *= 2 : recv_size = 4)
- {
- MakeSpeedTestPacket (packet, send_size, recv_size);
-
- packet_times.clear();
- // Test how long it takes to send 'num_packets' packets
- start_time = TimeValue::Now();
- for (i=0; i<num_packets; ++i)
- {
- TimeValue packet_start_time = TimeValue::Now();
- StringExtractorGDBRemote response;
- SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
- TimeValue packet_end_time = TimeValue::Now();
- uint64_t packet_time_nsec = packet_end_time.GetAsNanoSecondsSinceJan1_1970() - packet_start_time.GetAsNanoSecondsSinceJan1_1970();
- packet_times.push_back((float)packet_time_nsec);
- }
- end_time = TimeValue::Now();
- total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
-
- float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
- float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
- float average_ms_per_packet = total_ms / num_packets;
- const float standard_deviation = calculate_standard_deviation<float>(packet_times);
- if (json)
- {
- strm.Printf ("%s\n {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 ", \"standard_deviation_nsec\" : %9" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec, (uint64_t)standard_deviation);
- ++result_idx;
- }
- else
- {
- strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %9.2f packets/sec (%10.6f ms per packet) with standard deviation of %10.6f ms\n",
- send_size,
- recv_size,
- total_time_nsec / TimeValue::NanoSecPerSec,
- total_time_nsec % TimeValue::NanoSecPerSec,
- packets_per_second,
- average_ms_per_packet,
- standard_deviation/(float)TimeValue::NanoSecPerMilliSec);
- }
- strm.Flush();
- }
- }
-
- const uint64_t k_recv_amount = 4*1024*1024; // Receive amount in bytes
-
- const float k_recv_amount_mb = (float)k_recv_amount/(1024.0f*1024.0f);
- if (json)
- strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" : %" PRIu64 ",\n \"results\" : [", k_recv_amount);
- else
- strm.Printf("Testing receiving %2.1fMB of data using varying receive packet sizes:\n", k_recv_amount_mb);
- strm.Flush();
- send_size = 0;
- result_idx = 0;
- for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2)
- {
- MakeSpeedTestPacket (packet, send_size, recv_size);
-
- // If we have a receive size, test how long it takes to receive 4MB of data
- if (recv_size > 0)
- {
- start_time = TimeValue::Now();
- uint32_t bytes_read = 0;
- uint32_t packet_count = 0;
- while (bytes_read < k_recv_amount)
- {
- StringExtractorGDBRemote response;
- SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
- bytes_read += recv_size;
- ++packet_count;
- }
- end_time = TimeValue::Now();
- total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
- float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
- float packets_per_second = (((float)packet_count)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
- float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
- float average_ms_per_packet = total_ms / packet_count;
-
- if (json)
- {
- strm.Printf ("%s\n {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec);
- ++result_idx;
- }
- else
- {
- strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to receive %2.1fMB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per packet)\n",
- send_size,
- recv_size,
- packet_count,
- k_recv_amount_mb,
- total_time_nsec / TimeValue::NanoSecPerSec,
- total_time_nsec % TimeValue::NanoSecPerSec,
- mb_second,
- packets_per_second,
- average_ms_per_packet);
- }
- strm.Flush();
- }
- }
- if (json)
- strm.Printf("\n ]\n }\n}\n");
- else
- strm.EOL();
- }
-}
-
-bool
-GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
-{
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ return DecodeProcessInfoResponse(response, process_info);
+ } else {
+ m_supports_qProcessInfoPID = false;
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
+ GDBR_LOG_PACKETS));
+
+ if (allow_lazy) {
+ if (m_qProcessInfo_is_valid == eLazyBoolYes)
+ return true;
+ if (m_qProcessInfo_is_valid == eLazyBoolNo)
+ return false;
+ }
+
+ GetHostInfo();
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string arch_name;
+ std::string os_name;
+ std::string vendor_name;
+ std::string triple;
+ std::string elf_abi;
+ uint32_t pointer_byte_size = 0;
+ StringExtractor extractor;
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t num_keys_decoded = 0;
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("cputype")) {
+ if (!value.getAsInteger(16, cpu))
+ ++num_keys_decoded;
+ } else if (name.equals("cpusubtype")) {
+ if (!value.getAsInteger(16, sub))
+ ++num_keys_decoded;
+ } else if (name.equals("triple")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(triple);
+ ++num_keys_decoded;
+ } else if (name.equals("ostype")) {
+ os_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("vendor")) {
+ vendor_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("endian")) {
+ byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
+ .Case("little", eByteOrderLittle)
+ .Case("big", eByteOrderBig)
+ .Case("pdp", eByteOrderPDP)
+ .Default(eByteOrderInvalid);
+ if (byte_order != eByteOrderInvalid)
+ ++num_keys_decoded;
+ } else if (name.equals("ptrsize")) {
+ if (!value.getAsInteger(16, pointer_byte_size))
+ ++num_keys_decoded;
+ } else if (name.equals("pid")) {
+ if (!value.getAsInteger(16, pid))
+ ++num_keys_decoded;
+ } else if (name.equals("elf_abi")) {
+ elf_abi = value;
+ ++num_keys_decoded;
+ }
+ }
+ if (num_keys_decoded > 0)
+ m_qProcessInfo_is_valid = eLazyBoolYes;
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ m_curr_pid_is_valid = eLazyBoolYes;
+ m_curr_pid = pid;
+ }
+
+ // Set the ArchSpec from the triple if we have it.
+ if (!triple.empty()) {
+ m_process_arch.SetTriple(triple.c_str());
+ m_process_arch.SetFlags(elf_abi);
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
+ }
+ } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
+ !vendor_name.empty()) {
+ llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
+
+ assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
+ switch (triple.getObjectFormat()) {
+ case llvm::Triple::MachO:
+ m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ break;
+ case llvm::Triple::ELF:
+ m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
+ break;
+ case llvm::Triple::COFF:
+ m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
+ break;
+ case llvm::Triple::UnknownObjectFormat:
+ if (log)
+ log->Printf("error: failed to determine target architecture");
+ return false;
+ }
+
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_process_arch.GetByteOrder());
+ }
+ m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
+ m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
+ m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ }
+ return true;
+ }
+ } else {
+ m_qProcessInfo_is_valid = eLazyBoolNo;
+ }
+
+ return false;
+}
+
+uint32_t GDBRemoteCommunicationClient::FindProcesses(
+ const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ process_infos.Clear();
+
+ if (m_supports_qfProcessInfo) {
StreamString packet;
- packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
- uint32_t bytes_left = send_size;
- while (bytes_left > 0)
- {
- if (bytes_left >= 26)
- {
- packet.PutCString("abcdefghijklmnopqrstuvwxyz");
- bytes_left -= 26;
- }
- else
- {
- packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
- bytes_left = 0;
- }
+ packet.PutCString("qfProcessInfo");
+ if (!match_info.MatchAllProcesses()) {
+ packet.PutChar(':');
+ const char *name = match_info.GetProcessInfo().GetName();
+ bool has_name_match = false;
+ if (name && name[0]) {
+ has_name_match = true;
+ NameMatchType name_match_type = match_info.GetNameMatchType();
+ switch (name_match_type) {
+ case eNameMatchIgnore:
+ has_name_match = false;
+ break;
+
+ case eNameMatchEquals:
+ packet.PutCString("name_match:equals;");
+ break;
+
+ case eNameMatchContains:
+ packet.PutCString("name_match:contains;");
+ break;
+
+ case eNameMatchStartsWith:
+ packet.PutCString("name_match:starts_with;");
+ break;
+
+ case eNameMatchEndsWith:
+ packet.PutCString("name_match:ends_with;");
+ break;
+
+ case eNameMatchRegularExpression:
+ packet.PutCString("name_match:regex;");
+ break;
+ }
+ if (has_name_match) {
+ packet.PutCString("name:");
+ packet.PutBytesAsRawHex8(name, ::strlen(name));
+ packet.PutChar(';');
+ }
+ }
+
+ if (match_info.GetProcessInfo().ProcessIDIsValid())
+ packet.Printf("pid:%" PRIu64 ";",
+ match_info.GetProcessInfo().GetProcessID());
+ if (match_info.GetProcessInfo().ParentProcessIDIsValid())
+ packet.Printf("parent_pid:%" PRIu64 ";",
+ match_info.GetProcessInfo().GetParentProcessID());
+ if (match_info.GetProcessInfo().UserIDIsValid())
+ packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
+ if (match_info.GetProcessInfo().GroupIDIsValid())
+ packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
+ if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
+ packet.Printf("euid:%u;",
+ match_info.GetProcessInfo().GetEffectiveUserID());
+ if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
+ packet.Printf("egid:%u;",
+ match_info.GetProcessInfo().GetEffectiveGroupID());
+ if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
+ packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
+ if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
+ const ArchSpec &match_arch =
+ match_info.GetProcessInfo().GetArchitecture();
+ const llvm::Triple &triple = match_arch.GetTriple();
+ packet.PutCString("triple:");
+ packet.PutCString(triple.getTriple());
+ packet.PutChar(';');
+ }
}
-
StringExtractorGDBRemote response;
- return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
-}
-
-bool
-GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostname,
- lldb::pid_t &pid,
- uint16_t &port,
- std::string &socket_name)
-{
- pid = LLDB_INVALID_PROCESS_ID;
- port = 0;
- socket_name.clear();
-
+ // Increase timeout as the first qfProcessInfo packet takes a long time
+ // on Android. The value of 1min was arrived at empirically.
+ ScopedTimeout timeout(*this, minutes(1));
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ do {
+ ProcessInstanceInfo process_info;
+ if (!DecodeProcessInfoResponse(response, process_info))
+ break;
+ process_infos.Append(process_info);
+ response.GetStringRef().clear();
+ response.SetFilePos(0);
+ } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
+ PacketResult::Success);
+ } else {
+ m_supports_qfProcessInfo = false;
+ return 0;
+ }
+ }
+ return process_infos.GetSize();
+}
+
+bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
+ std::string &name) {
+ if (m_supports_qUserName) {
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- StreamString stream;
- stream.PutCString("qLaunchGDBServer;");
- std::string hostname;
- if (remote_accept_hostname && remote_accept_hostname[0])
- hostname = remote_accept_hostname;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ // Make sure we parsed the right number of characters. The response is
+ // the hex encoded user name and should make up the entire packet.
+ // If there are any non-hex ASCII bytes, the length won't match below..
+ if (response.GetHexByteString(name) * 2 ==
+ response.GetStringRef().size())
+ return true;
+ }
+ } else {
+ m_supports_qUserName = false;
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
+ std::string &name) {
+ if (m_supports_qGroupName) {
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ // Make sure we parsed the right number of characters. The response is
+ // the hex encoded group name and should make up the entire packet.
+ // If there are any non-hex ASCII bytes, the length won't match below..
+ if (response.GetHexByteString(name) * 2 ==
+ response.GetStringRef().size())
+ return true;
+ }
+ } else {
+ m_supports_qGroupName = false;
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
+ // Form non-stop packet request
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+
+ StringExtractorGDBRemote response;
+ // Send to target
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success)
+ if (response.IsOKResponse())
+ return true;
+
+ // Failed or not supported
+ return false;
+}
+
+static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
+ uint32_t recv_size) {
+ packet.Clear();
+ packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
+ uint32_t bytes_left = send_size;
+ while (bytes_left > 0) {
+ if (bytes_left >= 26) {
+ packet.PutCString("abcdefghijklmnopqrstuvwxyz");
+ bytes_left -= 26;
+ } else {
+ packet.Printf("%*.*s;", bytes_left, bytes_left,
+ "abcdefghijklmnopqrstuvwxyz");
+ bytes_left = 0;
+ }
+ }
+}
+
+duration<float>
+calculate_standard_deviation(const std::vector<duration<float>> &v) {
+ using Dur = duration<float>;
+ Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
+ Dur mean = sum / v.size();
+ float accum = 0;
+ for (auto d : v) {
+ float delta = (d - mean).count();
+ accum += delta * delta;
+ };
+
+ return Dur(sqrtf(accum / (v.size() - 1)));
+}
+
+void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
+ uint32_t max_send,
+ uint32_t max_recv,
+ uint64_t recv_amount,
+ bool json, Stream &strm) {
+ uint32_t i;
+ if (SendSpeedTestPacket(0, 0)) {
+ StreamString packet;
+ if (json)
+ strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
+ "\"results\" : [",
+ num_packets);
else
- {
- if (HostInfo::GetHostname(hostname))
- {
- // Make the GDB server we launch only accept connections from this host
- stream.Printf("host:%s;", hostname.c_str());
- }
- else
- {
- // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
- stream.Printf("host:*;");
+ strm.Printf("Testing sending %u packets of various sizes:\n",
+ num_packets);
+ strm.Flush();
+
+ uint32_t result_idx = 0;
+ uint32_t send_size;
+ std::vector<duration<float>> packet_times;
+
+ for (send_size = 0; send_size <= max_send;
+ send_size ? send_size *= 2 : send_size = 4) {
+ for (uint32_t recv_size = 0; recv_size <= max_recv;
+ recv_size ? recv_size *= 2 : recv_size = 4) {
+ MakeSpeedTestPacket(packet, send_size, recv_size);
+
+ packet_times.clear();
+ // Test how long it takes to send 'num_packets' packets
+ const auto start_time = steady_clock::now();
+ for (i = 0; i < num_packets; ++i) {
+ const auto packet_start_time = steady_clock::now();
+ StringExtractorGDBRemote response;
+ SendPacketAndWaitForResponse(packet.GetString(), response, false);
+ const auto packet_end_time = steady_clock::now();
+ packet_times.push_back(packet_end_time - packet_start_time);
+ }
+ const auto end_time = steady_clock::now();
+ const auto total_time = end_time - start_time;
+
+ float packets_per_second =
+ ((float)num_packets) / duration<float>(total_time).count();
+ auto average_per_packet = total_time / num_packets;
+ const duration<float> standard_deviation =
+ calculate_standard_deviation(packet_times);
+ if (json) {
+ strm.Printf("%s\n {\"send_size\" : %6" PRIu32
+ ", \"recv_size\" : %6" PRIu32
+ ", \"total_time_nsec\" : %12" PRIu64
+ ", \"standard_deviation_nsec\" : %9" PRIu64 " }",
+ result_idx > 0 ? "," : "", send_size, recv_size,
+ duration_cast<nanoseconds>(total_time).count(),
+ duration_cast<nanoseconds>(standard_deviation).count());
+ ++result_idx;
+ } else {
+ strm.Printf(
+ "qSpeedTest(send=%-7u, recv=%-7u) in %.9f"
+ " sec for %9.2f packets/sec (%10.6f ms per packet) with standard "
+ "deviation of %10.6f ms\n",
+ send_size, recv_size, duration<float>(total_time).count(),
+ packets_per_second,
+ duration<float, std::milli>(average_per_packet).count(),
+ duration<float, std::milli>(standard_deviation).count());
}
+ strm.Flush();
+ }
}
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
-
- // give the process a few seconds to startup
- GDBRemoteCommunication::ScopedTimeout timeout (*this, 10);
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- std::string name;
- std::string value;
- StringExtractor extractor;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("port") == 0)
- port = StringConvert::ToUInt32(value.c_str(), 0, 0);
- else if (name.compare("pid") == 0)
- pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
- else if (name.compare("socket_name") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString(value);
-
- socket_name = value;
- }
+ const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
+ if (json)
+ strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
+ ": %" PRIu64 ",\n \"results\" : [",
+ recv_amount);
+ else
+ strm.Printf("Testing receiving %2.1fMB of data using varying receive "
+ "packet sizes:\n",
+ k_recv_amount_mb);
+ strm.Flush();
+ send_size = 0;
+ result_idx = 0;
+ for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
+ MakeSpeedTestPacket(packet, send_size, recv_size);
+
+ // If we have a receive size, test how long it takes to receive 4MB of
+ // data
+ if (recv_size > 0) {
+ const auto start_time = steady_clock::now();
+ uint32_t bytes_read = 0;
+ uint32_t packet_count = 0;
+ while (bytes_read < recv_amount) {
+ StringExtractorGDBRemote response;
+ SendPacketAndWaitForResponse(packet.GetString(), response, false);
+ bytes_read += recv_size;
+ ++packet_count;
+ }
+ const auto end_time = steady_clock::now();
+ const auto total_time = end_time - start_time;
+ float mb_second = ((float)recv_amount) /
+ duration<float>(total_time).count() /
+ (1024.0 * 1024.0);
+ float packets_per_second =
+ ((float)packet_count) / duration<float>(total_time).count();
+ const auto average_per_packet = total_time / packet_count;
+
+ if (json) {
+ strm.Printf("%s\n {\"send_size\" : %6" PRIu32
+ ", \"recv_size\" : %6" PRIu32
+ ", \"total_time_nsec\" : %12" PRIu64 " }",
+ result_idx > 0 ? "," : "", send_size, recv_size,
+ duration_cast<nanoseconds>(total_time).count());
+ ++result_idx;
+ } else {
+ strm.Printf("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to "
+ "receive %2.1fMB in %.9f"
+ " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per "
+ "packet)\n",
+ send_size, recv_size, packet_count, k_recv_amount_mb,
+ duration<float>(total_time).count(), mb_second,
+ packets_per_second,
+ duration<float, std::milli>(average_per_packet).count());
}
- return true;
+ strm.Flush();
+ }
}
- return false;
+ if (json)
+ strm.Printf("\n ]\n }\n}\n");
+ else
+ strm.EOL();
+ }
+}
+
+bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
+ uint32_t recv_size) {
+ StreamString packet;
+ packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
+ uint32_t bytes_left = send_size;
+ while (bytes_left > 0) {
+ if (bytes_left >= 26) {
+ packet.PutCString("abcdefghijklmnopqrstuvwxyz");
+ bytes_left -= 26;
+ } else {
+ packet.Printf("%*.*s;", bytes_left, bytes_left,
+ "abcdefghijklmnopqrstuvwxyz");
+ bytes_left = 0;
+ }
+ }
+
+ StringExtractorGDBRemote response;
+ return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success;
+}
+
+bool GDBRemoteCommunicationClient::LaunchGDBServer(
+ const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
+ std::string &socket_name) {
+ pid = LLDB_INVALID_PROCESS_ID;
+ port = 0;
+ socket_name.clear();
+
+ StringExtractorGDBRemote response;
+ StreamString stream;
+ stream.PutCString("qLaunchGDBServer;");
+ std::string hostname;
+ if (remote_accept_hostname && remote_accept_hostname[0])
+ hostname = remote_accept_hostname;
+ else {
+ if (HostInfo::GetHostname(hostname)) {
+ // Make the GDB server we launch only accept connections from this host
+ stream.Printf("host:%s;", hostname.c_str());
+ } else {
+ // Make the GDB server we launch accept connections from any host since we
+ // can't figure out the hostname
+ stream.Printf("host:*;");
+ }
+ }
+ // give the process a few seconds to startup
+ ScopedTimeout timeout(*this, seconds(10));
+
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("port"))
+ value.getAsInteger(0, port);
+ else if (name.equals("pid"))
+ value.getAsInteger(0, pid);
+ else if (name.compare("socket_name") == 0) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(socket_name);
+ }
+ }
+ return true;
+ }
+ return false;
}
-size_t
-GDBRemoteCommunicationClient::QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls)
-{
- connection_urls.clear();
+size_t GDBRemoteCommunicationClient::QueryGDBServer(
+ std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
+ connection_urls.clear();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != PacketResult::Success)
- return 0;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
+ PacketResult::Success)
+ return 0;
- StructuredData::ObjectSP data = StructuredData::ParseJSON(response.GetStringRef());
- if (!data)
- return 0;
+ StructuredData::ObjectSP data =
+ StructuredData::ParseJSON(response.GetStringRef());
+ if (!data)
+ return 0;
- StructuredData::Array* array = data->GetAsArray();
- if (!array)
- return 0;
+ StructuredData::Array *array = data->GetAsArray();
+ if (!array)
+ return 0;
- for (size_t i = 0, count = array->GetSize(); i < count; ++i)
- {
- StructuredData::Dictionary* element = nullptr;
- if (!array->GetItemAtIndexAsDictionary(i, element))
- continue;
+ for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
+ StructuredData::Dictionary *element = nullptr;
+ if (!array->GetItemAtIndexAsDictionary(i, element))
+ continue;
- uint16_t port = 0;
- if (StructuredData::ObjectSP port_osp = element->GetValueForKey(llvm::StringRef("port")))
- port = port_osp->GetIntegerValue(0);
+ uint16_t port = 0;
+ if (StructuredData::ObjectSP port_osp =
+ element->GetValueForKey(llvm::StringRef("port")))
+ port = port_osp->GetIntegerValue(0);
- std::string socket_name;
- if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name")))
- socket_name = socket_name_osp->GetStringValue();
+ std::string socket_name;
+ if (StructuredData::ObjectSP socket_name_osp =
+ element->GetValueForKey(llvm::StringRef("socket_name")))
+ socket_name = socket_name_osp->GetStringValue();
- if (port != 0 || !socket_name.empty())
- connection_urls.emplace_back(port, socket_name);
- }
- return connection_urls.size();
+ if (port != 0 || !socket_name.empty())
+ connection_urls.emplace_back(port, socket_name);
+ }
+ return connection_urls.size();
}
-bool
-GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
-{
- StreamString stream;
- stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
+bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
+ StreamString stream;
+ stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- }
- return false;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return true;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
-{
- if (m_curr_tid == tid)
- return true;
-
- char packet[32];
- int packet_len;
- if (tid == UINT64_MAX)
- packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
- else
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
- assert (packet_len + 1 < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_curr_tid = tid;
- return true;
- }
+bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
+ if (m_curr_tid == tid)
+ return true;
- /*
- * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hg packet.
- * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
- * give us pid and/or tid. Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && IsConnected())
- {
- m_curr_tid = 1;
- return true;
- }
- }
- return false;
-}
+ char packet[32];
+ int packet_len;
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
+ else
+ packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_curr_tid = tid;
+ return true;
+ }
+
+ /*
+ * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+ * Hg packet.
+ * The reply from '?' packet could be as simple as 'S05'. There is no packet
+ * which can
+ * give us pid and/or tid. Assume pid=tid=1 in such cases.
+ */
+ if (response.IsUnsupportedResponse() && IsConnected()) {
+ m_curr_tid = 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
+ if (m_curr_tid_run == tid)
+ return true;
-bool
-GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
-{
- if (m_curr_tid_run == tid)
+ char packet[32];
+ int packet_len;
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
+ else
+ packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
+
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_curr_tid_run = tid;
+ return true;
+ }
+
+ /*
+ * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+ * Hc packet.
+ * The reply from '?' packet could be as simple as 'S05'. There is no packet
+ * which can
+ * give us pid and/or tid. Assume pid=tid=1 in such cases.
+ */
+ if (response.IsUnsupportedResponse() && IsConnected()) {
+ m_curr_tid_run = 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetStopReply(
+ StringExtractorGDBRemote &response) {
+ if (SendPacketAndWaitForResponse("?", response, false) ==
+ PacketResult::Success)
+ return response.IsNormalResponse();
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetThreadStopInfo(
+ lldb::tid_t tid, StringExtractorGDBRemote &response) {
+ if (m_supports_qThreadStopInfo) {
+ char packet[256];
+ int packet_len =
+ ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ m_supports_qThreadStopInfo = false;
+ else if (response.IsNormalResponse())
return true;
-
- char packet[32];
- int packet_len;
- if (tid == UINT64_MAX)
- packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
- else
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
-
- assert (packet_len + 1 < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_curr_tid_run = tid;
- return true;
- }
-
- /*
- * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hc packet.
- * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
- * give us pid and/or tid. Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && IsConnected())
- {
- m_curr_tid_run = 1;
- return true;
- }
+ else
+ return false;
+ } else {
+ m_supports_qThreadStopInfo = false;
}
- return false;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
-{
- if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
- return response.IsNormalResponse();
- return false;
-}
+uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
+ GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
+ __FUNCTION__, insert ? "add" : "remove", addr);
-bool
-GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
-{
- if (m_supports_qThreadStopInfo)
- {
- char packet[256];
- int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
- assert (packet_len < (int)sizeof(packet));
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- m_supports_qThreadStopInfo = false;
- else if (response.IsNormalResponse())
- return true;
- else
- return false;
- }
- else
- {
- m_supports_qThreadStopInfo = false;
- }
+ // Check if the stub is known not to support this breakpoint type
+ if (!SupportsGDBStoppointPacket(type))
+ return UINT8_MAX;
+ // Construct the breakpoint packet
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
+ insert ? 'Z' : 'z', type, addr, length);
+ // Check we haven't overwritten the end of the packet buffer
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ // Make sure the response is either "OK", "EXX" where XX are two hex digits,
+ // or "" (unsupported)
+ response.SetResponseValidatorToOKErrorNotSupported();
+ // Try to send the breakpoint packet, and check that it was correctly sent
+ if (SendPacketAndWaitForResponse(packet, response, true) ==
+ PacketResult::Success) {
+ // Receive and OK packet when the breakpoint successfully placed
+ if (response.IsOKResponse())
+ return 0;
+
+ // Error while setting breakpoint, send back specific error
+ if (response.IsErrorResponse())
+ return response.GetError();
+
+ // Empty packet informs us that breakpoint is not supported
+ if (response.IsUnsupportedResponse()) {
+ // Disable this breakpoint type since it is unsupported
+ switch (type) {
+ case eBreakpointSoftware:
+ m_supports_z0 = false;
+ break;
+ case eBreakpointHardware:
+ m_supports_z1 = false;
+ break;
+ case eWatchpointWrite:
+ m_supports_z2 = false;
+ break;
+ case eWatchpointRead:
+ m_supports_z3 = false;
+ break;
+ case eWatchpointReadWrite:
+ m_supports_z4 = false;
+ break;
+ case eStoppointInvalid:
+ return UINT8_MAX;
+ }
}
- return false;
+ }
+ // Signal generic failure
+ return UINT8_MAX;
}
+size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
+ std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
+ thread_ids.clear();
-uint8_t
-GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
- __FUNCTION__, insert ? "add" : "remove", addr);
-
- // Check if the stub is known not to support this breakpoint type
- if (!SupportsGDBStoppointPacket(type))
- return UINT8_MAX;
- // Construct the breakpoint packet
- char packet[64];
- const int packet_len = ::snprintf (packet,
- sizeof(packet),
- "%c%i,%" PRIx64 ",%x",
- insert ? 'Z' : 'z',
- type,
- addr,
- length);
- // Check we haven't overwritten the end of the packet buffer
- assert (packet_len + 1 < (int)sizeof(packet));
+ Lock lock(*this, false);
+ if (lock) {
+ sequence_mutex_unavailable = false;
StringExtractorGDBRemote response;
- // Make sure the response is either "OK", "EXX" where XX are two hex digits, or "" (unsupported)
- response.SetResponseValidatorToOKErrorNotSupported();
- // Try to send the breakpoint packet, and check that it was correctly sent
- if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
- {
- // Receive and OK packet when the breakpoint successfully placed
- if (response.IsOKResponse())
- return 0;
-
- // Error while setting breakpoint, send back specific error
- if (response.IsErrorResponse())
- return response.GetError();
-
- // Empty packet informs us that breakpoint is not supported
- if (response.IsUnsupportedResponse())
- {
- // Disable this breakpoint type since it is unsupported
- switch (type)
- {
- case eBreakpointSoftware: m_supports_z0 = false; break;
- case eBreakpointHardware: m_supports_z1 = false; break;
- case eWatchpointWrite: m_supports_z2 = false; break;
- case eWatchpointRead: m_supports_z3 = false; break;
- case eWatchpointReadWrite: m_supports_z4 = false; break;
- case eStoppointInvalid: return UINT8_MAX;
- }
- }
- }
- // Signal generic failure
- return UINT8_MAX;
-}
-
-size_t
-GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
- bool &sequence_mutex_unavailable)
-{
- Mutex::Locker locker;
- thread_ids.clear();
-
- if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
- {
- sequence_mutex_unavailable = false;
- StringExtractorGDBRemote response;
-
- PacketResult packet_result;
- for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response);
- packet_result == PacketResult::Success && response.IsNormalResponse();
- packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response))
- {
- char ch = response.GetChar();
- if (ch == 'l')
- break;
- if (ch == 'm')
- {
- do
- {
- tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
-
- if (tid != LLDB_INVALID_THREAD_ID)
- {
- thread_ids.push_back (tid);
- }
- ch = response.GetChar(); // Skip the command separator
- } while (ch == ','); // Make sure we got a comma separator
- }
- }
- /*
- * Connected bare-iron target (like YAMON gdb-stub) may not have support for
- * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet could
- * be as simple as 'S05'. There is no packet which can give us pid and/or tid.
- * Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && thread_ids.size() == 0 && IsConnected())
- {
- thread_ids.push_back (1);
- }
- }
- else
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
+ PacketResult packet_result;
+ for (packet_result =
+ SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
+ packet_result == PacketResult::Success && response.IsNormalResponse();
+ packet_result =
+ SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
+ char ch = response.GetChar();
+ if (ch == 'l')
+ break;
+ if (ch == 'm') {
+ do {
+ tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
+
+ if (tid != LLDB_INVALID_THREAD_ID) {
+ thread_ids.push_back(tid);
+ }
+ ch = response.GetChar(); // Skip the command separator
+ } while (ch == ','); // Make sure we got a comma separator
+ }
+ }
+
+ /*
+ * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+ * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
+ * could
+ * be as simple as 'S05'. There is no packet which can give us pid and/or
+ * tid.
+ * Assume pid=tid=1 in such cases.
+ */
+ if (response.IsUnsupportedResponse() && thread_ids.size() == 0 &&
+ IsConnected()) {
+ thread_ids.push_back(1);
+ }
+ } else {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+// assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the
+// sequence mutex");
#else
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
+ GDBR_LOG_PACKETS));
+ if (log)
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "packet 'qfThreadInfo'");
#endif
- sequence_mutex_unavailable = true;
- }
- return thread_ids.size();
+ sequence_mutex_unavailable = true;
+ }
+ return thread_ids.size();
}
-lldb::addr_t
-GDBRemoteCommunicationClient::GetShlibInfoAddr()
-{
- if (!IsRunning())
- {
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
- }
- }
+lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
+ PacketResult::Success ||
+ !response.IsNormalResponse())
return LLDB_INVALID_ADDRESS;
-}
-
-lldb_private::Error
-GDBRemoteCommunicationClient::RunShellCommand(const char *command, // Shouldn't be NULL
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass NULL if you don't want the process exit status
- int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass NULL if you don't want the command output
- uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
-{
- lldb_private::StreamString stream;
- stream.PutCString("qPlatform_shell:");
- stream.PutBytesAsRawHex8(command, strlen(command));
- stream.PutChar(',');
- stream.PutHex32(timeout_sec);
- if (working_dir)
- {
- std::string path{working_dir.GetPath(false)};
- stream.PutChar(',');
- stream.PutCStringAsRawHex8(path.c_str());
- }
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return Error("malformed reply");
- if (response.GetChar() != ',')
- return Error("malformed reply");
- uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
- if (exitcode == UINT32_MAX)
- return Error("unable to run remote process");
- else if (status_ptr)
- *status_ptr = exitcode;
- if (response.GetChar() != ',')
- return Error("malformed reply");
- uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
- if (signo_ptr)
- *signo_ptr = signo;
- if (response.GetChar() != ',')
- return Error("malformed reply");
- std::string output;
- response.GetEscapedBinaryData(output);
- if (command_output)
- command_output->assign(output);
- return Error();
- }
- return Error("unable to send packet");
-}
-
-Error
-GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
- uint32_t file_permissions)
-{
- std::string path{file_spec.GetPath(false)};
- lldb_private::StreamString stream;
- stream.PutCString("qPlatform_mkdir:");
- stream.PutHex32(file_permissions);
+ return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+}
+
+lldb_private::Error GDBRemoteCommunicationClient::RunShellCommand(
+ const char *command, // Shouldn't be NULL
+ const FileSpec &
+ working_dir, // Pass empty FileSpec to use the current working directory
+ int *status_ptr, // Pass NULL if you don't want the process exit status
+ int *signo_ptr, // Pass NULL if you don't want the signal that caused the
+ // process to exit
+ std::string
+ *command_output, // Pass NULL if you don't want the command output
+ uint32_t
+ timeout_sec) // Timeout in seconds to wait for shell program to finish
+{
+ lldb_private::StreamString stream;
+ stream.PutCString("qPlatform_shell:");
+ stream.PutBytesAsRawHex8(command, strlen(command));
+ stream.PutChar(',');
+ stream.PutHex32(timeout_sec);
+ if (working_dir) {
+ std::string path{working_dir.GetPath(false)};
stream.PutChar(',');
stream.PutCStringAsRawHex8(path.c_str());
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
- return Error("failed to send '%s' packet", packet);
-
+ }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
if (response.GetChar() != 'F')
- return Error("invalid response to '%s' packet", packet);
-
- return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
-}
-
-Error
-GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
- uint32_t file_permissions)
-{
- std::string path{file_spec.GetPath(false)};
- lldb_private::StreamString stream;
- stream.PutCString("qPlatform_chmod:");
- stream.PutHex32(file_permissions);
- stream.PutChar(',');
- stream.PutCStringAsRawHex8(path.c_str());
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
- return Error("failed to send '%s' packet", packet);
-
- if (response.GetChar() != 'F')
- return Error("invalid response to '%s' packet", packet);
-
- return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
-}
-
-static uint64_t
-ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
- uint64_t fail_result,
- Error &error)
-{
- response.SetFilePos(0);
- if (response.GetChar() != 'F')
- return fail_result;
- int32_t result = response.GetS32 (-2);
- if (result == -2)
- return fail_result;
- if (response.GetChar() == ',')
- {
- int result_errno = response.GetS32 (-2);
- if (result_errno != -2)
- error.SetError(result_errno, eErrorTypePOSIX);
- else
- error.SetError(-1, eErrorTypeGeneric);
- }
+ return Error("malformed reply");
+ if (response.GetChar() != ',')
+ return Error("malformed reply");
+ uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
+ if (exitcode == UINT32_MAX)
+ return Error("unable to run remote process");
+ else if (status_ptr)
+ *status_ptr = exitcode;
+ if (response.GetChar() != ',')
+ return Error("malformed reply");
+ uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
+ if (signo_ptr)
+ *signo_ptr = signo;
+ if (response.GetChar() != ',')
+ return Error("malformed reply");
+ std::string output;
+ response.GetEscapedBinaryData(output);
+ if (command_output)
+ command_output->assign(output);
+ return Error();
+ }
+ return Error("unable to send packet");
+}
+
+Error GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
+ uint32_t file_permissions) {
+ std::string path{file_spec.GetPath(false)};
+ lldb_private::StreamString stream;
+ stream.PutCString("qPlatform_mkdir:");
+ stream.PutHex32(file_permissions);
+ stream.PutChar(',');
+ stream.PutCStringAsRawHex8(path.c_str());
+ llvm::StringRef packet = stream.GetString();
+ StringExtractorGDBRemote response;
+
+ if (SendPacketAndWaitForResponse(packet, response, false) !=
+ PacketResult::Success)
+ return Error("failed to send '%s' packet", packet.str().c_str());
+
+ if (response.GetChar() != 'F')
+ return Error("invalid response to '%s' packet", packet.str().c_str());
+
+ return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
+}
+
+Error GDBRemoteCommunicationClient::SetFilePermissions(
+ const FileSpec &file_spec, uint32_t file_permissions) {
+ std::string path{file_spec.GetPath(false)};
+ lldb_private::StreamString stream;
+ stream.PutCString("qPlatform_chmod:");
+ stream.PutHex32(file_permissions);
+ stream.PutChar(',');
+ stream.PutCStringAsRawHex8(path.c_str());
+ llvm::StringRef packet = stream.GetString();
+ StringExtractorGDBRemote response;
+
+ if (SendPacketAndWaitForResponse(packet, response, false) !=
+ PacketResult::Success)
+ return Error("failed to send '%s' packet", stream.GetData());
+
+ if (response.GetChar() != 'F')
+ return Error("invalid response to '%s' packet", stream.GetData());
+
+ return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
+}
+
+static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
+ uint64_t fail_result, Error &error) {
+ response.SetFilePos(0);
+ if (response.GetChar() != 'F')
+ return fail_result;
+ int32_t result = response.GetS32(-2);
+ if (result == -2)
+ return fail_result;
+ if (response.GetChar() == ',') {
+ int result_errno = response.GetS32(-2);
+ if (result_errno != -2)
+ error.SetError(result_errno, eErrorTypePOSIX);
else
- error.Clear();
- return result;
+ error.SetError(-1, eErrorTypeGeneric);
+ } else
+ error.Clear();
+ return result;
}
lldb::user_id_t
-GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
- uint32_t flags,
- mode_t mode,
- Error &error)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:open:");
- if (path.empty())
- return UINT64_MAX;
- stream.PutCStringAsRawHex8(path.c_str());
- stream.PutChar(',');
- stream.PutHex32(flags);
- stream.PutChar(',');
- stream.PutHex32(mode);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- return ParseHostIOPacketResponse (response, UINT64_MAX, error);
- }
+GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
+ uint32_t flags, mode_t mode,
+ Error &error) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:open:");
+ if (path.empty())
return UINT64_MAX;
-}
-
-bool
-GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
- Error &error)
-{
- lldb_private::StreamString stream;
- stream.Printf("vFile:close:%i", (int)fd);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- return ParseHostIOPacketResponse (response, -1, error) == 0;
- }
- return false;
+ stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutChar(',');
+ stream.PutHex32(flags);
+ stream.PutChar(',');
+ stream.PutHex32(mode);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ return ParseHostIOPacketResponse(response, UINT64_MAX, error);
+ }
+ return UINT64_MAX;
+}
+
+bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd, Error &error) {
+ lldb_private::StreamString stream;
+ stream.Printf("vFile:close:%i", (int)fd);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ return ParseHostIOPacketResponse(response, -1, error) == 0;
+ }
+ return false;
}
// Extension of host I/O packets to get the file size.
-lldb::user_id_t
-GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:size:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return UINT64_MAX;
- uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
- return retcode;
- }
- return UINT64_MAX;
+lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
+ const lldb_private::FileSpec &file_spec) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:size:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return UINT64_MAX;
+ uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
+ return retcode;
+ }
+ return UINT64_MAX;
+}
+
+Error GDBRemoteCommunicationClient::GetFilePermissions(
+ const FileSpec &file_spec, uint32_t &file_permissions) {
+ std::string path{file_spec.GetPath(false)};
+ Error error;
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:mode:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F') {
+ error.SetErrorStringWithFormat("invalid response to '%s' packet",
+ stream.GetData());
+ } else {
+ const uint32_t mode = response.GetS32(-1);
+ if (static_cast<int32_t>(mode) == -1) {
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ else
+ error.SetErrorToGenericError();
+ } else
+ error.SetErrorToGenericError();
+ } else {
+ file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat("failed to send '%s' packet",
+ stream.GetData());
+ }
+ return error;
+}
+
+uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
+ uint64_t offset, void *dst,
+ uint64_t dst_len,
+ Error &error) {
+ lldb_private::StreamString stream;
+ stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
+ offset);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return 0;
+ uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
+ if (retcode == UINT32_MAX)
+ return retcode;
+ const char next = (response.Peek() ? *response.Peek() : 0);
+ if (next == ',')
+ return 0;
+ if (next == ';') {
+ response.GetChar(); // skip the semicolon
+ std::string buffer;
+ if (response.GetEscapedBinaryData(buffer)) {
+ const uint64_t data_to_write =
+ std::min<uint64_t>(dst_len, buffer.size());
+ if (data_to_write > 0)
+ memcpy(dst, &buffer[0], data_to_write);
+ return data_to_write;
+ }
+ }
+ }
+ return 0;
+}
+
+uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
+ uint64_t offset,
+ const void *src,
+ uint64_t src_len,
+ Error &error) {
+ lldb_private::StreamGDBRemote stream;
+ stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
+ stream.PutEscapedBytes(src, src_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F') {
+ error.SetErrorStringWithFormat("write file failed");
+ return 0;
+ }
+ uint64_t bytes_written = response.GetU64(UINT64_MAX);
+ if (bytes_written == UINT64_MAX) {
+ error.SetErrorToGenericError();
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ }
+ return 0;
+ }
+ return bytes_written;
+ } else {
+ error.SetErrorString("failed to send vFile:pwrite packet");
+ }
+ return 0;
+}
+
+Error GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
+ const FileSpec &dst) {
+ std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
+ Error error;
+ lldb_private::StreamGDBRemote stream;
+ stream.PutCString("vFile:symlink:");
+ // the unix symlink() command reverses its parameters where the dst if first,
+ // so we follow suit here
+ stream.PutCStringAsRawHex8(dst_path.c_str());
+ stream.PutChar(',');
+ stream.PutCStringAsRawHex8(src_path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() == 'F') {
+ uint32_t result = response.GetU32(UINT32_MAX);
+ if (result != 0) {
+ error.SetErrorToGenericError();
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ }
+ }
+ } else {
+ // Should have returned with 'F<result>[,<errno>]'
+ error.SetErrorStringWithFormat("symlink failed");
+ }
+ } else {
+ error.SetErrorString("failed to send vFile:symlink packet");
+ }
+ return error;
+}
+
+Error GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ Error error;
+ lldb_private::StreamGDBRemote stream;
+ stream.PutCString("vFile:unlink:");
+ // the unix symlink() command reverses its parameters where the dst if first,
+ // so we follow suit here
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() == 'F') {
+ uint32_t result = response.GetU32(UINT32_MAX);
+ if (result != 0) {
+ error.SetErrorToGenericError();
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ }
+ }
+ } else {
+ // Should have returned with 'F<result>[,<errno>]'
+ error.SetErrorStringWithFormat("unlink failed");
+ }
+ } else {
+ error.SetErrorString("failed to send vFile:unlink packet");
+ }
+ return error;
}
-Error
-GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
- uint32_t &file_permissions)
-{
- std::string path{file_spec.GetPath(false)};
- Error error;
- lldb_private::StreamString stream;
- stream.PutCString("vFile:mode:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- {
- error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
- }
- else
- {
- const uint32_t mode = response.GetS32(-1);
- if (static_cast<int32_t>(mode) == -1)
- {
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- else
- error.SetErrorToGenericError();
- }
- else
- error.SetErrorToGenericError();
- }
- else
- {
- file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
- }
- }
- }
- else
- {
- error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
- }
- return error;
-}
+// Extension of host I/O packets to get whether a file exists.
+bool GDBRemoteCommunicationClient::GetFileExists(
+ const lldb_private::FileSpec &file_spec) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:exists:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return false;
+ if (response.GetChar() != ',')
+ return false;
+ bool retcode = (response.GetChar() != '0');
+ return retcode;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::CalculateMD5(
+ const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:MD5:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return false;
+ if (response.GetChar() != ',')
+ return false;
+ if (response.Peek() && *response.Peek() == 'x')
+ return false;
+ low = response.GetHexMaxU64(false, UINT64_MAX);
+ high = response.GetHexMaxU64(false, UINT64_MAX);
+ return true;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
+ // Some targets have issues with g/G packets and we need to avoid using them
+ if (m_avoid_g_packets == eLazyBoolCalculate) {
+ if (process) {
+ m_avoid_g_packets = eLazyBoolNo;
+ const ArchSpec &arch = process->GetTarget().GetArchitecture();
+ if (arch.IsValid() &&
+ arch.GetTriple().getVendor() == llvm::Triple::Apple &&
+ arch.GetTriple().getOS() == llvm::Triple::IOS &&
+ arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ m_avoid_g_packets = eLazyBoolYes;
+ uint32_t gdb_server_version = GetGDBServerProgramVersion();
+ if (gdb_server_version != 0) {
+ const char *gdb_server_name = GetGDBServerProgramName();
+ if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
+ if (gdb_server_version >= 310)
+ m_avoid_g_packets = eLazyBoolNo;
+ }
+ }
+ }
+ }
+ }
+ return m_avoid_g_packets == eLazyBoolYes;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
+ uint32_t reg) {
+ StreamString payload;
+ payload.Printf("p%x", reg);
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success ||
+ !response.IsNormalResponse())
+ return nullptr;
+
+ DataBufferSP buffer_sp(
+ new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+ response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ return buffer_sp;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
+ StreamString payload;
+ payload.PutChar('g');
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success ||
+ !response.IsNormalResponse())
+ return nullptr;
+
+ DataBufferSP buffer_sp(
+ new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+ response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ return buffer_sp;
+}
+
+bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
+ uint32_t reg_num,
+ llvm::ArrayRef<uint8_t> data) {
+ StreamString payload;
+ payload.Printf("P%x=", reg_num);
+ payload.PutBytesAsRawHex8(data.data(), data.size(),
+ endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+ StringExtractorGDBRemote response;
+ return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+ response, false) ==
+ PacketResult::Success &&
+ response.IsOKResponse();
+}
+
+bool GDBRemoteCommunicationClient::WriteAllRegisters(
+ lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
+ StreamString payload;
+ payload.PutChar('G');
+ payload.PutBytesAsRawHex8(data.data(), data.size(),
+ endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+ StringExtractorGDBRemote response;
+ return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+ response, false) ==
+ PacketResult::Success &&
+ response.IsOKResponse();
+}
+
+bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
+ uint32_t &save_id) {
+ save_id = 0; // Set to invalid save ID
+ if (m_supports_QSaveRegisterState == eLazyBoolNo)
+ return false;
-uint64_t
-GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- Error &error)
-{
- lldb_private::StreamString stream;
- stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return 0;
- uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
- if (retcode == UINT32_MAX)
- return retcode;
- const char next = (response.Peek() ? *response.Peek() : 0);
- if (next == ',')
- return 0;
- if (next == ';')
- {
- response.GetChar(); // skip the semicolon
- std::string buffer;
- if (response.GetEscapedBinaryData(buffer))
- {
- const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
- if (data_to_write > 0)
- memcpy(dst, &buffer[0], data_to_write);
- return data_to_write;
- }
- }
- }
- return 0;
-}
+ m_supports_QSaveRegisterState = eLazyBoolYes;
+ StreamString payload;
+ payload.PutCString("QSaveRegisterState");
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success)
+ return false;
-uint64_t
-GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- Error &error)
-{
- lldb_private::StreamGDBRemote stream;
- stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
- stream.PutEscapedBytes(src, src_len);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- {
- error.SetErrorStringWithFormat("write file failed");
- return 0;
- }
- uint64_t bytes_written = response.GetU64(UINT64_MAX);
- if (bytes_written == UINT64_MAX)
- {
- error.SetErrorToGenericError();
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- }
- return 0;
- }
- return bytes_written;
- }
- else
- {
- error.SetErrorString ("failed to send vFile:pwrite packet");
- }
- return 0;
-}
+ if (response.IsUnsupportedResponse())
+ m_supports_QSaveRegisterState = eLazyBoolNo;
-Error
-GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, const FileSpec &dst)
-{
- std::string src_path{src.GetPath(false)},
- dst_path{dst.GetPath(false)};
- Error error;
- lldb_private::StreamGDBRemote stream;
- stream.PutCString("vFile:symlink:");
- // the unix symlink() command reverses its parameters where the dst if first,
- // so we follow suit here
- stream.PutCStringAsRawHex8(dst_path.c_str());
- stream.PutChar(',');
- stream.PutCStringAsRawHex8(src_path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() == 'F')
- {
- uint32_t result = response.GetU32(UINT32_MAX);
- if (result != 0)
- {
- error.SetErrorToGenericError();
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- }
- }
- }
- else
- {
- // Should have returned with 'F<result>[,<errno>]'
- error.SetErrorStringWithFormat("symlink failed");
- }
- }
- else
- {
- error.SetErrorString ("failed to send vFile:symlink packet");
- }
- return error;
-}
+ const uint32_t response_save_id = response.GetU32(0);
+ if (response_save_id == 0)
+ return false;
-Error
-GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec)
-{
- std::string path{file_spec.GetPath(false)};
- Error error;
- lldb_private::StreamGDBRemote stream;
- stream.PutCString("vFile:unlink:");
- // the unix symlink() command reverses its parameters where the dst if first,
- // so we follow suit here
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() == 'F')
- {
- uint32_t result = response.GetU32(UINT32_MAX);
- if (result != 0)
- {
- error.SetErrorToGenericError();
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- }
- }
- }
- else
- {
- // Should have returned with 'F<result>[,<errno>]'
- error.SetErrorStringWithFormat("unlink failed");
- }
- }
- else
- {
- error.SetErrorString ("failed to send vFile:unlink packet");
- }
- return error;
+ save_id = response_save_id;
+ return true;
}
-// Extension of host I/O packets to get whether a file exists.
-bool
-GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:exists:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return false;
- if (response.GetChar() != ',')
- return false;
- bool retcode = (response.GetChar() != '0');
- return retcode;
- }
+bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
+ uint32_t save_id) {
+ // We use the "m_supports_QSaveRegisterState" variable here because the
+ // QSaveRegisterState and QRestoreRegisterState packets must both be supported
+ // in
+ // order to be useful
+ if (m_supports_QSaveRegisterState == eLazyBoolNo)
return false;
-}
-bool
-GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
- uint64_t &high,
- uint64_t &low)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:MD5:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return false;
- if (response.GetChar() != ',')
- return false;
- if (response.Peek() && *response.Peek() == 'x')
- return false;
- low = response.GetHexMaxU64(false, UINT64_MAX);
- high = response.GetHexMaxU64(false, UINT64_MAX);
- return true;
- }
+ StreamString payload;
+ payload.Printf("QRestoreRegisterState:%u", save_id);
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success)
return false;
-}
-bool
-GDBRemoteCommunicationClient::AvoidGPackets (ProcessGDBRemote *process)
-{
- // Some targets have issues with g/G packets and we need to avoid using them
- if (m_avoid_g_packets == eLazyBoolCalculate)
- {
- if (process)
- {
- m_avoid_g_packets = eLazyBoolNo;
- const ArchSpec &arch = process->GetTarget().GetArchitecture();
- if (arch.IsValid()
- && arch.GetTriple().getVendor() == llvm::Triple::Apple
- && arch.GetTriple().getOS() == llvm::Triple::IOS
- && arch.GetTriple().getArch() == llvm::Triple::aarch64)
- {
- m_avoid_g_packets = eLazyBoolYes;
- uint32_t gdb_server_version = GetGDBServerProgramVersion();
- if (gdb_server_version != 0)
- {
- const char *gdb_server_name = GetGDBServerProgramName();
- if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0)
- {
- if (gdb_server_version >= 310)
- m_avoid_g_packets = eLazyBoolNo;
- }
- }
- }
- }
- }
- return m_avoid_g_packets == eLazyBoolYes;
+ if (response.IsOKResponse())
+ return true;
+
+ if (response.IsUnsupportedResponse())
+ m_supports_QSaveRegisterState = eLazyBoolNo;
+ return false;
}
-bool
-GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
-{
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
-
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[64];
- int packet_len = 0;
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid);
- else
- packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
- assert (packet_len < ((int)sizeof(packet) - 1));
- return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
- }
- }
+bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
+ if (!GetSyncThreadStateSupported())
return false;
+ StreamString packet;
+ StringExtractorGDBRemote response;
+ packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
+ return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ GDBRemoteCommunication::PacketResult::Success &&
+ response.IsOKResponse();
}
+bool GDBRemoteCommunicationClient::GetModuleInfo(
+ const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
+ ModuleSpec &module_spec) {
+ if (!m_supports_qModuleInfo)
+ return false;
-bool
-GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response)
-{
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
-
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[64];
- int packet_len = 0;
- // Get all registers in one packet
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid);
- else
- packet_len = ::snprintf (packet, sizeof(packet), "g");
- assert (packet_len < ((int)sizeof(packet) - 1));
- return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
- }
- }
+ std::string module_path = module_file_spec.GetPath(false);
+ if (module_path.empty())
return false;
-}
-bool
-GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
-{
- save_id = 0; // Set to invalid save ID
- if (m_supports_QSaveRegisterState == eLazyBoolNo)
- return false;
-
- m_supports_QSaveRegisterState = eLazyBoolYes;
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[256];
- if (thread_suffix_supported)
- ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid);
- else
- ::snprintf(packet, sizeof(packet), "QSaveRegisterState");
-
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- {
- // This packet isn't supported, don't try calling it again
- m_supports_QSaveRegisterState = eLazyBoolNo;
- }
-
- const uint32_t response_save_id = response.GetU32(0);
- if (response_save_id != 0)
- {
- save_id = response_save_id;
- return true;
- }
- }
- }
- }
+
+ StreamString packet;
+ packet.PutCString("qModuleInfo:");
+ packet.PutCStringAsRawHex8(module_path.c_str());
+ packet.PutCString(";");
+ const auto &triple = arch_spec.GetTriple().getTriple();
+ packet.PutCStringAsRawHex8(triple.c_str());
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
+ PacketResult::Success)
return false;
-}
-bool
-GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
-{
- // We use the "m_supports_QSaveRegisterState" variable here because the
- // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
- // order to be useful
- if (m_supports_QSaveRegisterState == eLazyBoolNo)
- return false;
-
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[256];
- if (thread_suffix_supported)
- ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid);
- else
- ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id);
-
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- return true;
- }
- else if (response.IsUnsupportedResponse())
- {
- // This packet isn't supported, don't try calling this packet or
- // QSaveRegisterState again...
- m_supports_QSaveRegisterState = eLazyBoolNo;
- }
- }
- }
- }
+ if (response.IsErrorResponse())
return false;
-}
-bool
-GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec,
- const lldb_private::ArchSpec& arch_spec,
- ModuleSpec &module_spec)
-{
- if (!m_supports_qModuleInfo)
- return false;
+ if (response.IsUnsupportedResponse()) {
+ m_supports_qModuleInfo = false;
+ return false;
+ }
+
+ llvm::StringRef name;
+ llvm::StringRef value;
+
+ module_spec.Clear();
+ module_spec.GetFileSpec() = module_file_spec;
+
+ while (response.GetNameColonValue(name, value)) {
+ if (name == "uuid" || name == "md5") {
+ StringExtractor extractor(value);
+ std::string uuid;
+ extractor.GetHexByteString(uuid);
+ module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2);
+ } else if (name == "triple") {
+ StringExtractor extractor(value);
+ std::string triple;
+ extractor.GetHexByteString(triple);
+ module_spec.GetArchitecture().SetTriple(triple.c_str());
+ } else if (name == "file_offset") {
+ uint64_t ival = 0;
+ if (!value.getAsInteger(16, ival))
+ module_spec.SetObjectOffset(ival);
+ } else if (name == "file_size") {
+ uint64_t ival = 0;
+ if (!value.getAsInteger(16, ival))
+ module_spec.SetObjectSize(ival);
+ } else if (name == "file_path") {
+ StringExtractor extractor(value);
+ std::string path;
+ extractor.GetHexByteString(path);
+ module_spec.GetFileSpec() = FileSpec(path, false, arch_spec);
+ }
+ }
+
+ return true;
+}
+
+static llvm::Optional<ModuleSpec>
+ParseModuleSpec(StructuredData::Dictionary *dict) {
+ ModuleSpec result;
+ if (!dict)
+ return llvm::None;
+
+ std::string string;
+ uint64_t integer;
+
+ if (!dict->GetValueForKeyAsString("uuid", string))
+ return llvm::None;
+ result.GetUUID().SetFromCString(string.c_str(), string.size());
+
+ if (!dict->GetValueForKeyAsInteger("file_offset", integer))
+ return llvm::None;
+ result.SetObjectOffset(integer);
+
+ if (!dict->GetValueForKeyAsInteger("file_size", integer))
+ return llvm::None;
+ result.SetObjectSize(integer);
+
+ if (!dict->GetValueForKeyAsString("triple", string))
+ return llvm::None;
+ result.GetArchitecture().SetTriple(string.c_str());
+
+ if (!dict->GetValueForKeyAsString("file_path", string))
+ return llvm::None;
+ result.GetFileSpec() = FileSpec(string, false, result.GetArchitecture());
+
+ return result;
+}
+
+llvm::Optional<std::vector<ModuleSpec>>
+GDBRemoteCommunicationClient::GetModulesInfo(
+ llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
+ if (!m_supports_jModulesInfo)
+ return llvm::None;
+
+ JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
+ for (const FileSpec &module_file_spec : module_file_specs) {
+ JSONObject::SP module_sp = std::make_shared<JSONObject>();
+ module_array_sp->AppendObject(module_sp);
+ module_sp->SetObject(
+ "file", std::make_shared<JSONString>(module_file_spec.GetPath()));
+ module_sp->SetObject("triple",
+ std::make_shared<JSONString>(triple.getTriple()));
+ }
+ StreamString unescaped_payload;
+ unescaped_payload.PutCString("jModulesInfo:");
+ module_array_sp->Write(unescaped_payload);
+ StreamGDBRemote payload;
+ payload.PutEscapedBytes(unescaped_payload.GetString().data(),
+ unescaped_payload.GetSize());
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
+ PacketResult::Success ||
+ response.IsErrorResponse())
+ return llvm::None;
+
+ if (response.IsUnsupportedResponse()) {
+ m_supports_jModulesInfo = false;
+ return llvm::None;
+ }
+
+ StructuredData::ObjectSP response_object_sp =
+ StructuredData::ParseJSON(response.GetStringRef());
+ if (!response_object_sp)
+ return llvm::None;
+
+ StructuredData::Array *response_array = response_object_sp->GetAsArray();
+ if (!response_array)
+ return llvm::None;
+
+ std::vector<ModuleSpec> result;
+ for (size_t i = 0; i < response_array->GetSize(); ++i) {
+ if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
+ response_array->GetItemAtIndex(i)->GetAsDictionary()))
+ result.push_back(*module_spec);
+ }
+
+ return result;
+}
- std::string module_path = module_file_spec.GetPath (false);
- if (module_path.empty ())
- return false;
+// query the target remote for extended information using the qXfer packet
+//
+// example: object='features', annex='target.xml', out=<xml output>
+// return: 'true' on success
+// 'false' on failure (err set)
+bool GDBRemoteCommunicationClient::ReadExtFeature(
+ const lldb_private::ConstString object,
+ const lldb_private::ConstString annex, std::string &out,
+ lldb_private::Error &err) {
- StreamString packet;
- packet.PutCString("qModuleInfo:");
- packet.PutCStringAsRawHex8(module_path.c_str());
- packet.PutCString(";");
- const auto& triple = arch_spec.GetTriple().getTriple();
- packet.PutCStringAsRawHex8(triple.c_str());
+ std::stringstream output;
+ StringExtractorGDBRemote chunk;
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success)
- return false;
+ uint64_t size = GetRemoteMaxPacketSize();
+ if (size == 0)
+ size = 0x1000;
+ size = size - 1; // Leave space for the 'm' or 'l' character in the response
+ int offset = 0;
+ bool active = true;
- if (response.IsErrorResponse ())
- return false;
+ // loop until all data has been read
+ while (active) {
- if (response.IsUnsupportedResponse ())
- {
- m_supports_qModuleInfo = false;
- return false;
- }
+ // send query extended feature packet
+ std::stringstream packet;
+ packet << "qXfer:" << object.AsCString("")
+ << ":read:" << annex.AsCString("") << ":" << std::hex << offset
+ << "," << std::hex << size;
- std::string name;
- std::string value;
- bool success;
- StringExtractor extractor;
+ GDBRemoteCommunication::PacketResult res =
+ SendPacketAndWaitForResponse(packet.str(), chunk, false);
- module_spec.Clear ();
- module_spec.GetFileSpec () = module_file_spec;
-
- while (response.GetNameColonValue (name, value))
- {
- if (name == "uuid" || name == "md5")
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (value);
- module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2);
- }
- else if (name == "triple")
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (value);
- module_spec.GetArchitecture().SetTriple (value.c_str ());
- }
- else if (name == "file_offset")
- {
- const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
- if (success)
- module_spec.SetObjectOffset (ival);
- }
- else if (name == "file_size")
- {
- const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
- if (success)
- module_spec.SetObjectSize (ival);
- }
- else if (name == "file_path")
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (value);
- module_spec.GetFileSpec() = FileSpec(value.c_str(), false, arch_spec);
- }
+ if (res != GDBRemoteCommunication::PacketResult::Success) {
+ err.SetErrorString("Error sending $qXfer packet");
+ return false;
}
- return true;
-}
+ const std::string &str = chunk.GetStringRef();
+ if (str.length() == 0) {
+ // should have some data in chunk
+ err.SetErrorString("Empty response from $qXfer packet");
+ return false;
+ }
-// query the target remote for extended information using the qXfer packet
-//
-// example: object='features', annex='target.xml', out=<xml output>
-// return: 'true' on success
-// 'false' on failure (err set)
-bool
-GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString object,
- const lldb_private::ConstString annex,
- std::string & out,
- lldb_private::Error & err) {
-
- std::stringstream output;
- StringExtractorGDBRemote chunk;
-
- uint64_t size = GetRemoteMaxPacketSize();
- if (size == 0)
- size = 0x1000;
- size = size - 1; // Leave space for the 'm' or 'l' character in the response
- int offset = 0;
- bool active = true;
-
- // loop until all data has been read
- while ( active ) {
-
- // send query extended feature packet
- std::stringstream packet;
- packet << "qXfer:"
- << object.AsCString("") << ":read:"
- << annex.AsCString("") << ":"
- << std::hex << offset << ","
- << std::hex << size;
-
- GDBRemoteCommunication::PacketResult res =
- SendPacketAndWaitForResponse( packet.str().c_str(),
- chunk,
- false );
-
- if ( res != GDBRemoteCommunication::PacketResult::Success ) {
- err.SetErrorString( "Error sending $qXfer packet" );
- return false;
- }
+ // check packet code
+ switch (str[0]) {
+ // last chunk
+ case ('l'):
+ active = false;
+ LLVM_FALLTHROUGH;
- const std::string & str = chunk.GetStringRef( );
- if ( str.length() == 0 ) {
- // should have some data in chunk
- err.SetErrorString( "Empty response from $qXfer packet" );
- return false;
- }
+ // more chunks
+ case ('m'):
+ if (str.length() > 1)
+ output << &str[1];
+ offset += size;
+ break;
- // check packet code
- switch ( str[0] ) {
- // last chunk
- case ( 'l' ):
- active = false;
- LLVM_FALLTHROUGH;
-
- // more chunks
- case ( 'm' ) :
- if ( str.length() > 1 )
- output << &str[1];
- offset += size;
- break;
-
- // unknown chunk
- default:
- err.SetErrorString( "Invalid continuation code from $qXfer packet" );
- return false;
- }
+ // unknown chunk
+ default:
+ err.SetErrorString("Invalid continuation code from $qXfer packet");
+ return false;
}
+ }
- out = output.str( );
- err.Success( );
- return true;
+ out = output.str();
+ err.Success();
+ return true;
}
// Notify the target that gdb is prepared to serve symbol lookup requests.
// packet: "qSymbol::"
// reply:
// OK The target does not need to look up any (more) symbols.
-// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex encoded).
-// LLDB may provide the value by sending another qSymbol packet
+// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
+// encoded).
+// LLDB may provide the value by sending another qSymbol
+// packet
// in the form of"qSymbol:<sym_value>:<sym_name>".
//
// Three examples:
//
// lldb sends: qSymbol::
// lldb receives: OK
-// Remote gdb stub does not need to know the addresses of any symbols, lldb does not
+// Remote gdb stub does not need to know the addresses of any symbols, lldb
+// does not
// need to ask again in this session.
//
// lldb sends: qSymbol::
// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
// lldb receives: OK
-// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does not know
-// the address at this time. lldb needs to send qSymbol:: again when it has more
+// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
+// not know
+// the address at this time. lldb needs to send qSymbol:: again when it has
+// more
// solibs loaded.
//
// lldb sends: qSymbol::
// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
// lldb receives: OK
-// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says that it
-// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it does not
+// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
+// that it
+// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
+// does not
// need any more symbols. lldb does not need to ask again in this session.
-void
-GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
-{
- // Set to true once we've resolved a symbol to an address for the remote stub.
- // If we get an 'OK' response after this, the remote stub doesn't need any more
- // symbols and we can stop asking.
- bool symbol_response_provided = false;
-
- // Is this the inital qSymbol:: packet?
- bool first_qsymbol_query = true;
-
- if (m_supports_qSymbol && m_qSymbol_requests_done == false)
- {
- Mutex::Locker locker;
- if (GetSequenceMutex(locker, "GDBRemoteCommunicationClient::ServeSymbolLookups() failed due to not getting the sequence mutex"))
- {
- StreamString packet;
- packet.PutCString ("qSymbol::");
- StringExtractorGDBRemote response;
- while (SendPacketAndWaitForResponseNoLock(packet.GetData(), packet.GetSize(), response) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- if (symbol_response_provided || first_qsymbol_query)
- {
- m_qSymbol_requests_done = true;
- }
-
- // We are done serving symbols requests
- return;
- }
- first_qsymbol_query = false;
+void GDBRemoteCommunicationClient::ServeSymbolLookups(
+ lldb_private::Process *process) {
+ // Set to true once we've resolved a symbol to an address for the remote stub.
+ // If we get an 'OK' response after this, the remote stub doesn't need any
+ // more
+ // symbols and we can stop asking.
+ bool symbol_response_provided = false;
+
+ // Is this the initial qSymbol:: packet?
+ bool first_qsymbol_query = true;
+
+ if (m_supports_qSymbol && m_qSymbol_requests_done == false) {
+ Lock lock(*this, false);
+ if (lock) {
+ StreamString packet;
+ packet.PutCString("qSymbol::");
+ StringExtractorGDBRemote response;
+ while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ if (symbol_response_provided || first_qsymbol_query) {
+ m_qSymbol_requests_done = true;
+ }
+
+ // We are done serving symbols requests
+ return;
+ }
+ first_qsymbol_query = false;
+
+ if (response.IsUnsupportedResponse()) {
+ // qSymbol is not supported by the current GDB server we are connected
+ // to
+ m_supports_qSymbol = false;
+ return;
+ } else {
+ llvm::StringRef response_str(response.GetStringRef());
+ if (response_str.startswith("qSymbol:")) {
+ response.SetFilePos(strlen("qSymbol:"));
+ std::string symbol_name;
+ if (response.GetHexByteString(symbol_name)) {
+ if (symbol_name.empty())
+ return;
+
+ addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
+ lldb_private::SymbolContextList sc_list;
+ if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ ConstString(symbol_name), eSymbolTypeAny, sc_list)) {
+ const size_t num_scs = sc_list.GetSize();
+ for (size_t sc_idx = 0;
+ sc_idx < num_scs &&
+ symbol_load_addr == LLDB_INVALID_ADDRESS;
+ ++sc_idx) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(sc_idx, sc)) {
+ if (sc.symbol) {
+ switch (sc.symbol->GetType()) {
+ case eSymbolTypeInvalid:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeVariable:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeTrampoline:
+ break;
- if (response.IsUnsupportedResponse())
- {
- // qSymbol is not supported by the current GDB server we are connected to
- m_supports_qSymbol = false;
- return;
- }
- else
- {
- llvm::StringRef response_str(response.GetStringRef());
- if (response_str.startswith("qSymbol:"))
- {
- response.SetFilePos(strlen("qSymbol:"));
- std::string symbol_name;
- if (response.GetHexByteString(symbol_name))
- {
- if (symbol_name.empty())
- return;
-
- addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
- lldb_private::SymbolContextList sc_list;
- if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list))
- {
- const size_t num_scs = sc_list.GetSize();
- for (size_t sc_idx=0; sc_idx<num_scs && symbol_load_addr == LLDB_INVALID_ADDRESS; ++sc_idx)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(sc_idx, sc))
- {
- if (sc.symbol)
- {
- switch (sc.symbol->GetType())
- {
- case eSymbolTypeInvalid:
- case eSymbolTypeAbsolute:
- case eSymbolTypeUndefined:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeVariable:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeTrampoline:
- break;
-
- case eSymbolTypeCode:
- case eSymbolTypeResolver:
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeException:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- case eSymbolTypeReExported:
- symbol_load_addr = sc.symbol->GetLoadAddress(&process->GetTarget());
- break;
- }
- }
- }
- }
- }
- // This is the normal path where our symbol lookup was successful and we want
- // to send a packet with the new symbol value and see if another lookup needs to be
- // done.
-
- // Change "packet" to contain the requested symbol value and name
- packet.Clear();
- packet.PutCString("qSymbol:");
- if (symbol_load_addr != LLDB_INVALID_ADDRESS)
- {
- packet.Printf("%" PRIx64, symbol_load_addr);
- symbol_response_provided = true;
- }
- else
- {
- symbol_response_provided = false;
- }
- packet.PutCString(":");
- packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
- continue; // go back to the while loop and send "packet" and wait for another response
- }
+ case eSymbolTypeCode:
+ case eSymbolTypeResolver:
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeException:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ case eSymbolTypeReExported:
+ symbol_load_addr =
+ sc.symbol->GetLoadAddress(&process->GetTarget());
+ break;
+ }
}
+ }
}
- }
- // If we make it here, the symbol request packet response wasn't valid or
- // our symbol lookup failed so we must abort
- return;
+ }
+ // This is the normal path where our symbol lookup was successful
+ // and we want
+ // to send a packet with the new symbol value and see if another
+ // lookup needs to be
+ // done.
+
+ // Change "packet" to contain the requested symbol value and name
+ packet.Clear();
+ packet.PutCString("qSymbol:");
+ if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
+ packet.Printf("%" PRIx64, symbol_load_addr);
+ symbol_response_provided = true;
+ } else {
+ symbol_response_provided = false;
+ }
+ packet.PutCString(":");
+ packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
+ continue; // go back to the while loop and send "packet" and wait
+ // for another response
+ }
+ }
+ }
+ }
+ // If we make it here, the symbol request packet response wasn't valid or
+ // our symbol lookup failed so we must abort
+ return;
+
+ } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
+ GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
+ log->Printf(
+ "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
+ __FUNCTION__);
+ }
+ }
+}
+
+StructuredData::Array *
+GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
+ if (!m_supported_async_json_packets_is_valid) {
+ // Query the server for the array of supported asynchronous JSON
+ // packets.
+ m_supported_async_json_packets_is_valid = true;
- }
- }
-}
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ // Poll it now.
+ StringExtractorGDBRemote response;
+ const bool send_async = false;
+ if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
+ send_async) == PacketResult::Success) {
+ m_supported_async_json_packets_sp =
+ StructuredData::ParseJSON(response.GetStringRef());
+ if (m_supported_async_json_packets_sp &&
+ !m_supported_async_json_packets_sp->GetAsArray()) {
+ // We were returned something other than a JSON array. This
+ // is invalid. Clear it out.
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets returned invalid "
+ "result: %s",
+ __FUNCTION__, response.GetStringRef().c_str());
+ m_supported_async_json_packets_sp.reset();
+ }
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets unsupported",
+ __FUNCTION__);
+ }
+
+ if (log && m_supported_async_json_packets_sp) {
+ StreamString stream;
+ m_supported_async_json_packets_sp->Dump(stream);
+ log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
+ "JSON packets: %s",
+ __FUNCTION__, stream.GetData());
+ }
+ }
+
+ return m_supported_async_json_packets_sp
+ ? m_supported_async_json_packets_sp->GetAsArray()
+ : nullptr;
+}
+
+Error GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
+ const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+ Error error;
+
+ if (type_name.GetLength() == 0) {
+ error.SetErrorString("invalid type_name argument");
+ return error;
+ }
+
+ // Build command: Configure{type_name}: serialized config
+ // data.
+ StreamGDBRemote stream;
+ stream.PutCString("QConfigure");
+ stream.PutCString(type_name.AsCString());
+ stream.PutChar(':');
+ if (config_sp) {
+ // Gather the plain-text version of the configuration data.
+ StreamString unescaped_stream;
+ config_sp->Dump(unescaped_stream);
+ unescaped_stream.Flush();
+
+ // Add it to the stream in escaped fashion.
+ stream.PutEscapedBytes(unescaped_stream.GetString().data(),
+ unescaped_stream.GetSize());
+ }
+ stream.Flush();
+
+ // Send the packet.
+ const bool send_async = false;
+ StringExtractorGDBRemote response;
+ auto result =
+ SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
+ if (result == PacketResult::Success) {
+ // We failed if the config result comes back other than OK.
+ if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
+ // Okay!
+ error.Clear();
+ } else {
+ error.SetErrorStringWithFormat("configuring StructuredData feature "
+ "%s failed with error %s",
+ type_name.AsCString(),
+ response.GetStringRef().c_str());
+ }
+ } else {
+ // Can we get more data here on the failure?
+ error.SetErrorStringWithFormat("configuring StructuredData feature %s "
+ "failed when sending packet: "
+ "PacketResult=%d",
+ type_name.AsCString(), (int)result);
+ }
+ return error;
+}
+
+void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
+ GDBRemoteClientBase::OnRunPacketSent(first);
+ m_curr_tid = LLDB_INVALID_THREAD_ID;
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 096c4cf81015..83162a662e06 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -10,8 +10,11 @@
#ifndef liblldb_GDBRemoteCommunicationClient_h_
#define liblldb_GDBRemoteCommunicationClient_h_
+#include "GDBRemoteClientBase.h"
+
// C Includes
// C++ Includes
+#include <chrono>
#include <map>
#include <mutex>
#include <string>
@@ -23,660 +26,563 @@
#include "lldb/Core/StructuredData.h"
#include "lldb/Target/Process.h"
-#include "GDBRemoteCommunication.h"
+#include "llvm/ADT/Optional.h"
namespace lldb_private {
namespace process_gdb_remote {
-class GDBRemoteCommunicationClient : public GDBRemoteCommunication
-{
+class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
public:
- GDBRemoteCommunicationClient();
-
- ~GDBRemoteCommunicationClient() override;
-
- //------------------------------------------------------------------
- // After connecting, send the handshake to the server to make sure
- // we are communicating with it.
- //------------------------------------------------------------------
- bool
- HandshakeWithServer (Error *error_ptr);
-
- PacketResult
- SendPacketAndWaitForResponse (const char *send_payload,
- StringExtractorGDBRemote &response,
- bool send_async);
-
- PacketResult
- SendPacketAndWaitForResponse (const char *send_payload,
- size_t send_length,
- StringExtractorGDBRemote &response,
- bool send_async);
-
- // For packets which specify a range of output to be returned,
- // return all of the output via a series of request packets of the form
- // <prefix>0,<size>
- // <prefix><size>,<size>
- // <prefix><size>*2,<size>
- // <prefix><size>*3,<size>
- // ...
- // until a "$l..." packet is received, indicating the end.
- // (size is in hex; this format is used by a standard gdbserver to
- // return the given portion of the output specified by <prefix>;
- // for example, "qXfer:libraries-svr4:read::fff,1000" means
- // "return a chunk of the xml description file for shared
- // library load addresses, where the chunk starts at offset 0xfff
- // and continues for 0x1000 bytes").
- // Concatenate the resulting server response packets together and
- // return in response_string. If any packet fails, the return value
- // indicates that failure and the returned string value is undefined.
- PacketResult
- SendPacketsAndConcatenateResponses (const char *send_payload_prefix,
- std::string &response_string);
-
- lldb::StateType
- SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
- const char *packet_payload,
- size_t packet_length,
- StringExtractorGDBRemote &response);
-
- bool
- SendvContPacket (ProcessGDBRemote *process,
- const char *payload,
- size_t packet_length,
- StringExtractorGDBRemote &response);
-
- bool
- GetThreadSuffixSupported () override;
-
- // This packet is usually sent first and the boolean return value
- // indicates if the packet was send and any response was received
- // even in the response is UNIMPLEMENTED. If the packet failed to
- // get a response, then false is returned. This quickly tells us
- // if we were able to connect and communicate with the remote GDB
- // server
- bool
- QueryNoAckModeSupported ();
-
- void
- GetListThreadsInStopReplySupported ();
-
- bool
- SendAsyncSignal (int signo);
-
- bool
- SendInterrupt (Mutex::Locker &locker,
- uint32_t seconds_to_wait_for_stop,
- bool &timed_out);
-
- lldb::pid_t
- GetCurrentProcessID (bool allow_lazy = true);
-
- bool
- GetLaunchSuccess (std::string &error_str);
-
- bool
- LaunchGDBServer (const char *remote_accept_hostname,
- lldb::pid_t &pid,
- uint16_t &port,
- std::string &socket_name);
-
- size_t
- QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls);
-
- bool
- KillSpawnedProcess (lldb::pid_t pid);
-
- //------------------------------------------------------------------
- /// Sends a GDB remote protocol 'A' packet that delivers program
- /// arguments to the remote server.
- ///
- /// @param[in] argv
- /// A NULL terminated array of const C strings to use as the
- /// arguments.
- ///
- /// @return
- /// Zero if the response was "OK", a positive value if the
- /// the response was "Exx" where xx are two hex digits, or
- /// -1 if the call is unsupported or any other unexpected
- /// response was received.
- //------------------------------------------------------------------
- int
- SendArgumentsPacket (const ProcessLaunchInfo &launch_info);
-
- //------------------------------------------------------------------
- /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
- /// environment that will get used when launching an application
- /// in conjunction with the 'A' packet. This function can be called
- /// multiple times in a row in order to pass on the desired
- /// environment that the inferior should be launched with.
- ///
- /// @param[in] name_equal_value
- /// A NULL terminated C string that contains a single environment
- /// in the format "NAME=VALUE".
- ///
- /// @return
- /// Zero if the response was "OK", a positive value if the
- /// the response was "Exx" where xx are two hex digits, or
- /// -1 if the call is unsupported or any other unexpected
- /// response was received.
- //------------------------------------------------------------------
- int
- SendEnvironmentPacket (char const *name_equal_value);
-
- int
- SendLaunchArchPacket (const char *arch);
-
- int
- SendLaunchEventDataPacket(const char *data, bool *was_supported = nullptr);
-
- //------------------------------------------------------------------
- /// Sends a "vAttach:PID" where PID is in hex.
- ///
- /// @param[in] pid
- /// A process ID for the remote gdb server to attach to.
- ///
- /// @param[out] response
- /// The response received from the gdb server. If the return
- /// value is zero, \a response will contain a stop reply
- /// packet.
- ///
- /// @return
- /// Zero if the attach was successful, or an error indicating
- /// an error code.
- //------------------------------------------------------------------
- int
- SendAttach (lldb::pid_t pid,
- StringExtractorGDBRemote& response);
-
- //------------------------------------------------------------------
- /// Sends a GDB remote protocol 'I' packet that delivers stdin
- /// data to the remote process.
- ///
- /// @param[in] data
- /// A pointer to stdin data.
- ///
- /// @param[in] data_len
- /// The number of bytes available at \a data.
- ///
- /// @return
- /// Zero if the attach was successful, or an error indicating
- /// an error code.
- //------------------------------------------------------------------
- int
- SendStdinNotification(const char* data, size_t data_len);
-
- //------------------------------------------------------------------
- /// Sets the path to use for stdin/out/err for a process
- /// that will be launched with the 'A' packet.
- ///
- /// @param[in] path
- /// The path to use for stdin/out/err
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetSTDIN(const FileSpec &file_spec);
- int
- SetSTDOUT(const FileSpec &file_spec);
- int
- SetSTDERR(const FileSpec &file_spec);
-
- //------------------------------------------------------------------
- /// Sets the disable ASLR flag to \a enable for a process that will
- /// be launched with the 'A' packet.
- ///
- /// @param[in] enable
- /// A boolean value indicating whether to disable ASLR or not.
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetDisableASLR (bool enable);
-
- //------------------------------------------------------------------
- /// Sets the DetachOnError flag to \a enable for the process controlled by the stub.
- ///
- /// @param[in] enable
- /// A boolean value indicating whether to detach on error or not.
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetDetachOnError (bool enable);
-
- //------------------------------------------------------------------
- /// Sets the working directory to \a path for a process that will
- /// be launched with the 'A' packet for non platform based
- /// connections. If this packet is sent to a GDB server that
- /// implements the platform, it will change the current working
- /// directory for the platform process.
- ///
- /// @param[in] working_dir
- /// The path to a directory to use when launching our process
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetWorkingDir(const FileSpec &working_dir);
-
- //------------------------------------------------------------------
- /// Gets the current working directory of a remote platform GDB
- /// server.
- ///
- /// @param[out] working_dir
- /// The current working directory on the remote platform.
- ///
- /// @return
- /// Boolean for success
- //------------------------------------------------------------------
- bool
- GetWorkingDir(FileSpec &working_dir);
-
- lldb::addr_t
- AllocateMemory (size_t size, uint32_t permissions);
-
- bool
- DeallocateMemory (lldb::addr_t addr);
-
- Error
- Detach (bool keep_stopped);
-
- Error
- GetMemoryRegionInfo (lldb::addr_t addr, MemoryRegionInfo &range_info);
-
- Error
- GetWatchpointSupportInfo (uint32_t &num);
-
- Error
- GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch);
-
- Error
- GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch);
-
- const ArchSpec &
- GetHostArchitecture ();
-
- uint32_t
- GetHostDefaultPacketTimeout();
-
- const ArchSpec &
- GetProcessArchitecture ();
-
- void
- GetRemoteQSupported();
-
- bool
- GetVContSupported (char flavor);
-
- bool
- GetpPacketSupported (lldb::tid_t tid);
-
- bool
- GetxPacketSupported ();
-
- bool
- GetVAttachOrWaitSupported ();
-
- bool
- GetSyncThreadStateSupported();
-
- void
- ResetDiscoverableSettings (bool did_exec);
-
- bool
- GetHostInfo (bool force = false);
-
- bool
- GetDefaultThreadId (lldb::tid_t &tid);
-
- bool
- GetOSVersion (uint32_t &major,
- uint32_t &minor,
- uint32_t &update);
-
- bool
- GetOSBuildString (std::string &s);
-
- bool
- GetOSKernelDescription (std::string &s);
-
- ArchSpec
- GetSystemArchitecture ();
-
- bool
- GetHostname (std::string &s);
-
- lldb::addr_t
- GetShlibInfoAddr();
-
- bool
- GetSupportsThreadSuffix ();
-
- bool
- GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info);
-
- uint32_t
- FindProcesses (const ProcessInstanceInfoMatch &process_match_info,
- ProcessInstanceInfoList &process_infos);
-
- bool
- GetUserName (uint32_t uid, std::string &name);
-
- bool
- GetGroupName (uint32_t gid, std::string &name);
-
- bool
- HasFullVContSupport ()
- {
- return GetVContSupported ('A');
- }
+ GDBRemoteCommunicationClient();
+
+ ~GDBRemoteCommunicationClient() override;
+
+ //------------------------------------------------------------------
+ // After connecting, send the handshake to the server to make sure
+ // we are communicating with it.
+ //------------------------------------------------------------------
+ bool HandshakeWithServer(Error *error_ptr);
+
+ // For packets which specify a range of output to be returned,
+ // return all of the output via a series of request packets of the form
+ // <prefix>0,<size>
+ // <prefix><size>,<size>
+ // <prefix><size>*2,<size>
+ // <prefix><size>*3,<size>
+ // ...
+ // until a "$l..." packet is received, indicating the end.
+ // (size is in hex; this format is used by a standard gdbserver to
+ // return the given portion of the output specified by <prefix>;
+ // for example, "qXfer:libraries-svr4:read::fff,1000" means
+ // "return a chunk of the xml description file for shared
+ // library load addresses, where the chunk starts at offset 0xfff
+ // and continues for 0x1000 bytes").
+ // Concatenate the resulting server response packets together and
+ // return in response_string. If any packet fails, the return value
+ // indicates that failure and the returned string value is undefined.
+ PacketResult
+ SendPacketsAndConcatenateResponses(const char *send_payload_prefix,
+ std::string &response_string);
+
+ bool GetThreadSuffixSupported();
+
+ // This packet is usually sent first and the boolean return value
+ // indicates if the packet was send and any response was received
+ // even in the response is UNIMPLEMENTED. If the packet failed to
+ // get a response, then false is returned. This quickly tells us
+ // if we were able to connect and communicate with the remote GDB
+ // server
+ bool QueryNoAckModeSupported();
+
+ void GetListThreadsInStopReplySupported();
+
+ lldb::pid_t GetCurrentProcessID(bool allow_lazy = true);
+
+ bool GetLaunchSuccess(std::string &error_str);
+
+ bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid,
+ uint16_t &port, std::string &socket_name);
+
+ size_t QueryGDBServer(
+ std::vector<std::pair<uint16_t, std::string>> &connection_urls);
+
+ bool KillSpawnedProcess(lldb::pid_t pid);
+
+ //------------------------------------------------------------------
+ /// Sends a GDB remote protocol 'A' packet that delivers program
+ /// arguments to the remote server.
+ ///
+ /// @param[in] argv
+ /// A NULL terminated array of const C strings to use as the
+ /// arguments.
+ ///
+ /// @return
+ /// Zero if the response was "OK", a positive value if the
+ /// the response was "Exx" where xx are two hex digits, or
+ /// -1 if the call is unsupported or any other unexpected
+ /// response was received.
+ //------------------------------------------------------------------
+ int SendArgumentsPacket(const ProcessLaunchInfo &launch_info);
+
+ //------------------------------------------------------------------
+ /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
+ /// environment that will get used when launching an application
+ /// in conjunction with the 'A' packet. This function can be called
+ /// multiple times in a row in order to pass on the desired
+ /// environment that the inferior should be launched with.
+ ///
+ /// @param[in] name_equal_value
+ /// A NULL terminated C string that contains a single environment
+ /// in the format "NAME=VALUE".
+ ///
+ /// @return
+ /// Zero if the response was "OK", a positive value if the
+ /// the response was "Exx" where xx are two hex digits, or
+ /// -1 if the call is unsupported or any other unexpected
+ /// response was received.
+ //------------------------------------------------------------------
+ int SendEnvironmentPacket(char const *name_equal_value);
+
+ int SendLaunchArchPacket(const char *arch);
+
+ int SendLaunchEventDataPacket(const char *data,
+ bool *was_supported = nullptr);
+
+ //------------------------------------------------------------------
+ /// Sends a "vAttach:PID" where PID is in hex.
+ ///
+ /// @param[in] pid
+ /// A process ID for the remote gdb server to attach to.
+ ///
+ /// @param[out] response
+ /// The response received from the gdb server. If the return
+ /// value is zero, \a response will contain a stop reply
+ /// packet.
+ ///
+ /// @return
+ /// Zero if the attach was successful, or an error indicating
+ /// an error code.
+ //------------------------------------------------------------------
+ int SendAttach(lldb::pid_t pid, StringExtractorGDBRemote &response);
+
+ //------------------------------------------------------------------
+ /// Sends a GDB remote protocol 'I' packet that delivers stdin
+ /// data to the remote process.
+ ///
+ /// @param[in] data
+ /// A pointer to stdin data.
+ ///
+ /// @param[in] data_len
+ /// The number of bytes available at \a data.
+ ///
+ /// @return
+ /// Zero if the attach was successful, or an error indicating
+ /// an error code.
+ //------------------------------------------------------------------
+ int SendStdinNotification(const char *data, size_t data_len);
+
+ //------------------------------------------------------------------
+ /// Sets the path to use for stdin/out/err for a process
+ /// that will be launched with the 'A' packet.
+ ///
+ /// @param[in] path
+ /// The path to use for stdin/out/err
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetSTDIN(const FileSpec &file_spec);
+ int SetSTDOUT(const FileSpec &file_spec);
+ int SetSTDERR(const FileSpec &file_spec);
+
+ //------------------------------------------------------------------
+ /// Sets the disable ASLR flag to \a enable for a process that will
+ /// be launched with the 'A' packet.
+ ///
+ /// @param[in] enable
+ /// A boolean value indicating whether to disable ASLR or not.
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetDisableASLR(bool enable);
+
+ //------------------------------------------------------------------
+ /// Sets the DetachOnError flag to \a enable for the process controlled by the
+ /// stub.
+ ///
+ /// @param[in] enable
+ /// A boolean value indicating whether to detach on error or not.
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetDetachOnError(bool enable);
+
+ //------------------------------------------------------------------
+ /// Sets the working directory to \a path for a process that will
+ /// be launched with the 'A' packet for non platform based
+ /// connections. If this packet is sent to a GDB server that
+ /// implements the platform, it will change the current working
+ /// directory for the platform process.
+ ///
+ /// @param[in] working_dir
+ /// The path to a directory to use when launching our process
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetWorkingDir(const FileSpec &working_dir);
+
+ //------------------------------------------------------------------
+ /// Gets the current working directory of a remote platform GDB
+ /// server.
+ ///
+ /// @param[out] working_dir
+ /// The current working directory on the remote platform.
+ ///
+ /// @return
+ /// Boolean for success
+ //------------------------------------------------------------------
+ bool GetWorkingDir(FileSpec &working_dir);
+
+ lldb::addr_t AllocateMemory(size_t size, uint32_t permissions);
+
+ bool DeallocateMemory(lldb::addr_t addr);
+
+ Error Detach(bool keep_stopped);
+
+ Error GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info);
+
+ Error GetWatchpointSupportInfo(uint32_t &num);
+
+ Error GetWatchpointSupportInfo(uint32_t &num, bool &after,
+ const ArchSpec &arch);
+
+ Error GetWatchpointsTriggerAfterInstruction(bool &after,
+ const ArchSpec &arch);
+
+ const ArchSpec &GetHostArchitecture();
+
+ std::chrono::seconds GetHostDefaultPacketTimeout();
+
+ const ArchSpec &GetProcessArchitecture();
+
+ void GetRemoteQSupported();
- bool
- HasAnyVContSupport ()
- {
- return GetVContSupported ('a');
- }
-
- bool
- GetStopReply (StringExtractorGDBRemote &response);
-
- bool
- GetThreadStopInfo (lldb::tid_t tid,
- StringExtractorGDBRemote &response);
-
- bool
- SupportsGDBStoppointPacket (GDBStoppointType type)
- {
- switch (type)
- {
- case eBreakpointSoftware: return m_supports_z0;
- case eBreakpointHardware: return m_supports_z1;
- case eWatchpointWrite: return m_supports_z2;
- case eWatchpointRead: return m_supports_z3;
- case eWatchpointReadWrite: return m_supports_z4;
- default: return false;
- }
- }
+ bool GetVContSupported(char flavor);
- uint8_t
- SendGDBStoppointTypePacket (GDBStoppointType type, // Type of breakpoint or watchpoint
- bool insert, // Insert or remove?
- lldb::addr_t addr, // Address of breakpoint or watchpoint
- uint32_t length); // Byte Size of breakpoint or watchpoint
-
- bool
- SetNonStopMode (const bool enable);
-
- void
- TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm);
-
- // This packet is for testing the speed of the interface only. Both
- // the client and server need to support it, but this allows us to
- // measure the packet speed without any other work being done on the
- // other end and avoids any of that work affecting the packet send
- // and response times.
- bool
- SendSpeedTestPacket (uint32_t send_size,
- uint32_t recv_size);
-
- bool
- SetCurrentThread (uint64_t tid);
-
- bool
- SetCurrentThreadForRun (uint64_t tid);
-
- bool
- GetQXferAuxvReadSupported ();
-
- bool
- GetQXferLibrariesReadSupported ();
-
- bool
- GetQXferLibrariesSVR4ReadSupported ();
-
- uint64_t
- GetRemoteMaxPacketSize();
-
- bool
- GetEchoSupported ();
-
- bool
- GetAugmentedLibrariesSVR4ReadSupported ();
-
- bool
- GetQXferFeaturesReadSupported ();
-
- LazyBool
- SupportsAllocDeallocMemory () // const
- {
- // Uncomment this to have lldb pretend the debug server doesn't respond to alloc/dealloc memory packets.
- // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
- return m_supports_alloc_dealloc_memory;
- }
+ bool GetpPacketSupported(lldb::tid_t tid);
+
+ bool GetxPacketSupported();
+
+ bool GetVAttachOrWaitSupported();
+
+ bool GetSyncThreadStateSupported();
+
+ void ResetDiscoverableSettings(bool did_exec);
+
+ bool GetHostInfo(bool force = false);
+
+ bool GetDefaultThreadId(lldb::tid_t &tid);
+
+ bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update);
+
+ bool GetOSBuildString(std::string &s);
+
+ bool GetOSKernelDescription(std::string &s);
+
+ ArchSpec GetSystemArchitecture();
+
+ bool GetHostname(std::string &s);
+
+ lldb::addr_t GetShlibInfoAddr();
+
+ bool GetSupportsThreadSuffix();
+
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info);
- size_t
- GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
- bool &sequence_mutex_unavailable);
-
- bool
- GetInterruptWasSent () const
- {
- return m_interrupt_sent;
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info,
+ ProcessInstanceInfoList &process_infos);
+
+ bool GetUserName(uint32_t uid, std::string &name);
+
+ bool GetGroupName(uint32_t gid, std::string &name);
+
+ bool HasFullVContSupport() { return GetVContSupported('A'); }
+
+ bool HasAnyVContSupport() { return GetVContSupported('a'); }
+
+ bool GetStopReply(StringExtractorGDBRemote &response);
+
+ bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response);
+
+ bool SupportsGDBStoppointPacket(GDBStoppointType type) {
+ switch (type) {
+ case eBreakpointSoftware:
+ return m_supports_z0;
+ case eBreakpointHardware:
+ return m_supports_z1;
+ case eWatchpointWrite:
+ return m_supports_z2;
+ case eWatchpointRead:
+ return m_supports_z3;
+ case eWatchpointReadWrite:
+ return m_supports_z4;
+ default:
+ return false;
}
-
- lldb::user_id_t
- OpenFile (const FileSpec& file_spec, uint32_t flags, mode_t mode, Error &error);
-
- bool
- CloseFile (lldb::user_id_t fd, Error &error);
-
- lldb::user_id_t
- GetFileSize (const FileSpec& file_spec);
-
- Error
- GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions);
-
- Error
- SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions);
-
- uint64_t
- ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- Error &error);
-
- uint64_t
- WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- Error &error);
-
- Error
- CreateSymlink(const FileSpec &src,
- const FileSpec &dst);
-
- Error
- Unlink(const FileSpec &file_spec);
-
- Error
- MakeDirectory(const FileSpec &file_spec, uint32_t mode);
-
- bool
- GetFileExists (const FileSpec& file_spec);
-
- Error
- RunShellCommand(const char *command, // Shouldn't be nullptr
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass nullptr if you don't want the process exit status
- int *signo_ptr, // Pass nullptr if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass nullptr if you don't want the command output
- uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
-
- bool
- CalculateMD5 (const FileSpec& file_spec, uint64_t &high, uint64_t &low);
-
- std::string
- HarmonizeThreadIdsForProfileData (ProcessGDBRemote *process,
- StringExtractorGDBRemote &inputStringExtractor);
-
- bool
- ReadRegister(lldb::tid_t tid,
- uint32_t reg_num, // Must be the eRegisterKindProcessPlugin register number, to be sent to the remote
- StringExtractorGDBRemote &response);
-
- bool
- ReadAllRegisters (lldb::tid_t tid,
- StringExtractorGDBRemote &response);
-
- bool
- SaveRegisterState (lldb::tid_t tid, uint32_t &save_id);
-
- bool
- RestoreRegisterState (lldb::tid_t tid, uint32_t save_id);
-
- const char *
- GetGDBServerProgramName();
-
- uint32_t
- GetGDBServerProgramVersion();
-
- bool
- AvoidGPackets(ProcessGDBRemote *process);
-
- StructuredData::ObjectSP
- GetThreadsInfo();
-
- bool
- GetThreadExtendedInfoSupported();
-
- bool
- GetLoadedDynamicLibrariesInfosSupported();
-
- bool
- GetModuleInfo (const FileSpec& module_file_spec,
- const ArchSpec& arch_spec,
- ModuleSpec &module_spec);
-
- bool
- ReadExtFeature (const lldb_private::ConstString object,
- const lldb_private::ConstString annex,
- std::string & out,
- lldb_private::Error & err);
-
- void
- ServeSymbolLookups(lldb_private::Process *process);
+ }
+
+ uint8_t SendGDBStoppointTypePacket(
+ GDBStoppointType type, // Type of breakpoint or watchpoint
+ bool insert, // Insert or remove?
+ lldb::addr_t addr, // Address of breakpoint or watchpoint
+ uint32_t length); // Byte Size of breakpoint or watchpoint
+
+ bool SetNonStopMode(const bool enable);
+
+ void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send,
+ uint32_t max_recv, uint64_t recv_amount, bool json,
+ Stream &strm);
+
+ // This packet is for testing the speed of the interface only. Both
+ // the client and server need to support it, but this allows us to
+ // measure the packet speed without any other work being done on the
+ // other end and avoids any of that work affecting the packet send
+ // and response times.
+ bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);
+
+ bool SetCurrentThread(uint64_t tid);
+
+ bool SetCurrentThreadForRun(uint64_t tid);
+
+ bool GetQXferAuxvReadSupported();
+
+ bool GetQXferLibrariesReadSupported();
+
+ bool GetQXferLibrariesSVR4ReadSupported();
+
+ uint64_t GetRemoteMaxPacketSize();
+
+ bool GetEchoSupported();
+
+ bool GetAugmentedLibrariesSVR4ReadSupported();
+
+ bool GetQXferFeaturesReadSupported();
+
+ LazyBool SupportsAllocDeallocMemory() // const
+ {
+ // Uncomment this to have lldb pretend the debug server doesn't respond to
+ // alloc/dealloc memory packets.
+ // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
+ return m_supports_alloc_dealloc_memory;
+ }
+
+ size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
+ bool &sequence_mutex_unavailable);
+
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ mode_t mode, Error &error);
+
+ bool CloseFile(lldb::user_id_t fd, Error &error);
+
+ lldb::user_id_t GetFileSize(const FileSpec &file_spec);
+
+ Error GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions);
+
+ Error SetFilePermissions(const FileSpec &file_spec,
+ uint32_t file_permissions);
+
+ uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+ uint64_t dst_len, Error &error);
+
+ uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
+ uint64_t src_len, Error &error);
+
+ Error CreateSymlink(const FileSpec &src, const FileSpec &dst);
+
+ Error Unlink(const FileSpec &file_spec);
+
+ Error MakeDirectory(const FileSpec &file_spec, uint32_t mode);
+
+ bool GetFileExists(const FileSpec &file_spec);
+
+ Error RunShellCommand(
+ const char *command, // Shouldn't be nullptr
+ const FileSpec &working_dir, // Pass empty FileSpec to use the current
+ // working directory
+ int *status_ptr, // Pass nullptr if you don't want the process exit status
+ int *signo_ptr, // Pass nullptr if you don't want the signal that caused
+ // the process to exit
+ std::string
+ *command_output, // Pass nullptr if you don't want the command output
+ uint32_t timeout_sec); // Timeout in seconds to wait for shell program to
+ // finish
+
+ bool CalculateMD5(const FileSpec &file_spec, uint64_t &high, uint64_t &low);
+
+ lldb::DataBufferSP ReadRegister(
+ lldb::tid_t tid,
+ uint32_t
+ reg_num); // Must be the eRegisterKindProcessPlugin register number
+
+ lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid);
+
+ bool
+ WriteRegister(lldb::tid_t tid,
+ uint32_t reg_num, // eRegisterKindProcessPlugin register number
+ llvm::ArrayRef<uint8_t> data);
+
+ bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);
+
+ bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);
+
+ bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id);
+
+ bool SyncThreadState(lldb::tid_t tid);
+
+ const char *GetGDBServerProgramName();
+
+ uint32_t GetGDBServerProgramVersion();
+
+ bool AvoidGPackets(ProcessGDBRemote *process);
+
+ StructuredData::ObjectSP GetThreadsInfo();
+
+ bool GetThreadExtendedInfoSupported();
+
+ bool GetLoadedDynamicLibrariesInfosSupported();
+
+ bool GetSharedCacheInfoSupported();
+
+ bool GetModuleInfo(const FileSpec &module_file_spec,
+ const ArchSpec &arch_spec, ModuleSpec &module_spec);
+
+ llvm::Optional<std::vector<ModuleSpec>>
+ GetModulesInfo(llvm::ArrayRef<FileSpec> module_file_specs,
+ const llvm::Triple &triple);
+
+ bool ReadExtFeature(const lldb_private::ConstString object,
+ const lldb_private::ConstString annex, std::string &out,
+ lldb_private::Error &err);
+
+ void ServeSymbolLookups(lldb_private::Process *process);
+
+ //------------------------------------------------------------------
+ /// Return the feature set supported by the gdb-remote server.
+ ///
+ /// This method returns the remote side's response to the qSupported
+ /// packet. The response is the complete string payload returned
+ /// to the client.
+ ///
+ /// @return
+ /// The string returned by the server to the qSupported query.
+ //------------------------------------------------------------------
+ const std::string &GetServerSupportedFeatures() const {
+ return m_qSupported_response;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the array of async JSON packet types supported by the remote.
+ ///
+ /// This method returns the remote side's array of supported JSON
+ /// packet types as a list of type names. Each of the results are
+ /// expected to have an Enable{type_name} command to enable and configure
+ /// the related feature. Each type_name for an enabled feature will
+ /// possibly send async-style packets that contain a payload of a
+ /// binhex-encoded JSON dictionary. The dictionary will have a
+ /// string field named 'type', that contains the type_name of the
+ /// supported packet type.
+ ///
+ /// There is a Plugin category called structured-data plugins.
+ /// A plugin indicates whether it knows how to handle a type_name.
+ /// If so, it can be used to process the async JSON packet.
+ ///
+ /// @return
+ /// The string returned by the server to the qSupported query.
+ //------------------------------------------------------------------
+ lldb_private::StructuredData::Array *GetSupportedStructuredDataPlugins();
+
+ //------------------------------------------------------------------
+ /// Configure a StructuredData feature on the remote end.
+ ///
+ /// @see \b Process::ConfigureStructuredData(...) for details.
+ //------------------------------------------------------------------
+ Error
+ ConfigureRemoteStructuredData(const ConstString &type_name,
+ const StructuredData::ObjectSP &config_sp);
protected:
- LazyBool m_supports_not_sending_acks;
- LazyBool m_supports_thread_suffix;
- LazyBool m_supports_threads_in_stop_reply;
- LazyBool m_supports_vCont_all;
- LazyBool m_supports_vCont_any;
- LazyBool m_supports_vCont_c;
- LazyBool m_supports_vCont_C;
- LazyBool m_supports_vCont_s;
- LazyBool m_supports_vCont_S;
- LazyBool m_qHostInfo_is_valid;
- LazyBool m_curr_pid_is_valid;
- LazyBool m_qProcessInfo_is_valid;
- LazyBool m_qGDBServerVersion_is_valid;
- LazyBool m_supports_alloc_dealloc_memory;
- LazyBool m_supports_memory_region_info;
- LazyBool m_supports_watchpoint_support_info;
- LazyBool m_supports_detach_stay_stopped;
- LazyBool m_watchpoints_trigger_after_instruction;
- LazyBool m_attach_or_wait_reply;
- LazyBool m_prepare_for_reg_writing_reply;
- LazyBool m_supports_p;
- LazyBool m_supports_x;
- LazyBool m_avoid_g_packets;
- LazyBool m_supports_QSaveRegisterState;
- LazyBool m_supports_qXfer_auxv_read;
- LazyBool m_supports_qXfer_libraries_read;
- LazyBool m_supports_qXfer_libraries_svr4_read;
- LazyBool m_supports_qXfer_features_read;
- LazyBool m_supports_augmented_libraries_svr4_read;
- LazyBool m_supports_jThreadExtendedInfo;
- LazyBool m_supports_jLoadedDynamicLibrariesInfos;
-
- bool
- m_supports_qProcessInfoPID:1,
- m_supports_qfProcessInfo:1,
- m_supports_qUserName:1,
- m_supports_qGroupName:1,
- m_supports_qThreadStopInfo:1,
- m_supports_z0:1,
- m_supports_z1:1,
- m_supports_z2:1,
- m_supports_z3:1,
- m_supports_z4:1,
- m_supports_QEnvironment:1,
- m_supports_QEnvironmentHexEncoded:1,
- m_supports_qSymbol:1,
- m_qSymbol_requests_done:1,
- m_supports_qModuleInfo:1,
- m_supports_jThreadsInfo:1;
-
- lldb::pid_t m_curr_pid;
- lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations
- lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for continue, step, etc
-
- uint32_t m_num_supported_hardware_watchpoints;
-
- // If we need to send a packet while the target is running, the m_async_XXX
- // member variables take care of making this happen.
- std::recursive_mutex m_async_mutex;
- Predicate<bool> m_async_packet_predicate;
- std::string m_async_packet;
- PacketResult m_async_result;
- StringExtractorGDBRemote m_async_response;
- int m_async_signal; // We were asked to deliver a signal to the inferior process.
- bool m_interrupt_sent;
- std::string m_partial_profile_data;
- std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
-
- ArchSpec m_host_arch;
- ArchSpec m_process_arch;
- uint32_t m_os_version_major;
- uint32_t m_os_version_minor;
- uint32_t m_os_version_update;
- std::string m_os_build;
- std::string m_os_kernel;
- std::string m_hostname;
- std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if qGDBServerVersion is not supported
- uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if qGDBServerVersion is not supported
- uint32_t m_default_packet_timeout;
- uint64_t m_max_packet_size; // as returned by qSupported
-
- PacketResult
- SendPacketAndWaitForResponseNoLock (const char *payload,
- size_t payload_length,
- StringExtractorGDBRemote &response);
-
- bool
- GetCurrentProcessInfo (bool allow_lazy_pid = true);
-
- bool
- GetGDBServerVersion();
-
- // Given the list of compression types that the remote debug stub can support,
- // possibly enable compression if we find an encoding we can handle.
- void
- MaybeEnableCompression (std::vector<std::string> supported_compressions);
-
- bool
- DecodeProcessInfoResponse (StringExtractorGDBRemote &response,
- ProcessInstanceInfo &process_info);
+ LazyBool m_supports_not_sending_acks;
+ LazyBool m_supports_thread_suffix;
+ LazyBool m_supports_threads_in_stop_reply;
+ LazyBool m_supports_vCont_all;
+ LazyBool m_supports_vCont_any;
+ LazyBool m_supports_vCont_c;
+ LazyBool m_supports_vCont_C;
+ LazyBool m_supports_vCont_s;
+ LazyBool m_supports_vCont_S;
+ LazyBool m_qHostInfo_is_valid;
+ LazyBool m_curr_pid_is_valid;
+ LazyBool m_qProcessInfo_is_valid;
+ LazyBool m_qGDBServerVersion_is_valid;
+ LazyBool m_supports_alloc_dealloc_memory;
+ LazyBool m_supports_memory_region_info;
+ LazyBool m_supports_watchpoint_support_info;
+ LazyBool m_supports_detach_stay_stopped;
+ LazyBool m_watchpoints_trigger_after_instruction;
+ LazyBool m_attach_or_wait_reply;
+ LazyBool m_prepare_for_reg_writing_reply;
+ LazyBool m_supports_p;
+ LazyBool m_supports_x;
+ LazyBool m_avoid_g_packets;
+ LazyBool m_supports_QSaveRegisterState;
+ LazyBool m_supports_qXfer_auxv_read;
+ LazyBool m_supports_qXfer_libraries_read;
+ LazyBool m_supports_qXfer_libraries_svr4_read;
+ LazyBool m_supports_qXfer_features_read;
+ LazyBool m_supports_augmented_libraries_svr4_read;
+ LazyBool m_supports_jThreadExtendedInfo;
+ LazyBool m_supports_jLoadedDynamicLibrariesInfos;
+ LazyBool m_supports_jGetSharedCacheInfo;
+
+ bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
+ m_supports_qUserName : 1, m_supports_qGroupName : 1,
+ m_supports_qThreadStopInfo : 1, m_supports_z0 : 1, m_supports_z1 : 1,
+ m_supports_z2 : 1, m_supports_z3 : 1, m_supports_z4 : 1,
+ m_supports_QEnvironment : 1, m_supports_QEnvironmentHexEncoded : 1,
+ m_supports_qSymbol : 1, m_qSymbol_requests_done : 1,
+ m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1,
+ m_supports_jModulesInfo : 1;
+
+ lldb::pid_t m_curr_pid;
+ lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all
+ // other operations
+ lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for
+ // continue, step, etc
+
+ uint32_t m_num_supported_hardware_watchpoints;
+
+ ArchSpec m_host_arch;
+ ArchSpec m_process_arch;
+ uint32_t m_os_version_major;
+ uint32_t m_os_version_minor;
+ uint32_t m_os_version_update;
+ std::string m_os_build;
+ std::string m_os_kernel;
+ std::string m_hostname;
+ std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if
+ // qGDBServerVersion is not supported
+ uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if
+ // qGDBServerVersion is not supported
+ std::chrono::seconds m_default_packet_timeout;
+ uint64_t m_max_packet_size; // as returned by qSupported
+ std::string m_qSupported_response; // the complete response to qSupported
+
+ bool m_supported_async_json_packets_is_valid;
+ lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
+
+ bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
+
+ bool GetGDBServerVersion();
+
+ // Given the list of compression types that the remote debug stub can support,
+ // possibly enable compression if we find an encoding we can handle.
+ void MaybeEnableCompression(std::vector<std::string> supported_compressions);
+
+ bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
+ ProcessInstanceInfo &process_info);
+
+ void OnRunPacketSent(bool first) override;
+
+ PacketResult SendThreadSpecificPacketAndWaitForResponse(
+ lldb::tid_t tid, StreamString &&payload,
+ StringExtractorGDBRemote &response, bool send_async);
private:
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationClient);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 4ee66b84d474..934824e214dc 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -25,114 +25,96 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(const char *comm_name,
- const char *listener_name) :
- GDBRemoteCommunication (comm_name, listener_name),
- m_exit_now (false)
-{
-}
+GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
+ const char *comm_name, const char *listener_name)
+ : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {}
-GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
-{
-}
+GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
void GDBRemoteCommunicationServer::RegisterPacketHandler(
- StringExtractorGDBRemote::ServerPacketType packet_type,
- PacketHandler handler)
-{
- m_packet_handlers[packet_type] = std::move(handler);
+ StringExtractorGDBRemote::ServerPacketType packet_type,
+ PacketHandler handler) {
+ m_packet_handlers[packet_type] = std::move(handler);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
- Error &error,
- bool &interrupt,
- bool &quit)
-{
- StringExtractorGDBRemote packet;
-
- PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec, false);
- if (packet_result == PacketResult::Success)
- {
- const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
- switch (packet_type)
- {
- case StringExtractorGDBRemote::eServerPacketType_nack:
- case StringExtractorGDBRemote::eServerPacketType_ack:
- break;
-
- case StringExtractorGDBRemote::eServerPacketType_invalid:
- error.SetErrorString("invalid packet");
- quit = true;
- break;
-
- case StringExtractorGDBRemote::eServerPacketType_unimplemented:
- packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
- break;
-
- default:
- auto handler_it = m_packet_handlers.find(packet_type);
- if (handler_it == m_packet_handlers.end())
- packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
- else
- packet_result = handler_it->second (packet, error, interrupt, quit);
- break;
- }
+GDBRemoteCommunicationServer::GetPacketAndSendResponse(
+ Timeout<std::micro> timeout, Error &error, bool &interrupt, bool &quit) {
+ StringExtractorGDBRemote packet;
+
+ PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
+ if (packet_result == PacketResult::Success) {
+ const StringExtractorGDBRemote::ServerPacketType packet_type =
+ packet.GetServerPacketType();
+ switch (packet_type) {
+ case StringExtractorGDBRemote::eServerPacketType_nack:
+ case StringExtractorGDBRemote::eServerPacketType_ack:
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_invalid:
+ error.SetErrorString("invalid packet");
+ quit = true;
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_unimplemented:
+ packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str());
+ break;
+
+ default:
+ auto handler_it = m_packet_handlers.find(packet_type);
+ if (handler_it == m_packet_handlers.end())
+ packet_result =
+ SendUnimplementedResponse(packet.GetStringRef().c_str());
+ else
+ packet_result = handler_it->second(packet, error, interrupt, quit);
+ break;
}
- else
- {
- if (!IsConnected())
- {
- error.SetErrorString("lost connection");
- quit = true;
- }
- else
- {
- error.SetErrorString("timeout");
- }
+ } else {
+ if (!IsConnected()) {
+ error.SetErrorString("lost connection");
+ quit = true;
+ } else {
+ error.SetErrorString("timeout");
}
+ }
- // Check if anything occurred that would force us to want to exit.
- if (m_exit_now)
- quit = true;
+ // Check if anything occurred that would force us to want to exit.
+ if (m_exit_now)
+ quit = true;
- return packet_result;
+ return packet_result;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
-{
- // TODO: Log the packet we aren't handling...
- return SendPacketNoLock ("", 0);
+GDBRemoteCommunicationServer::SendUnimplementedResponse(const char *) {
+ // TODO: Log the packet we aren't handling...
+ return SendPacketNoLock("");
}
-
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
-{
- char packet[16];
- int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
- assert (packet_len < (int)sizeof(packet));
- return SendPacketNoLock (packet, packet_len);
+GDBRemoteCommunicationServer::SendErrorResponse(uint8_t err) {
+ char packet[16];
+ int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
+ assert(packet_len < (int)sizeof(packet));
+ return SendPacketNoLock(llvm::StringRef(packet, packet_len));
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendIllFormedResponse (const StringExtractorGDBRemote &failed_packet, const char *message)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", __FUNCTION__, failed_packet.GetStringRef ().c_str (), message ? message : "");
- return SendErrorResponse (0x03);
+GDBRemoteCommunicationServer::SendIllFormedResponse(
+ const StringExtractorGDBRemote &failed_packet, const char *message) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
+ __FUNCTION__, failed_packet.GetStringRef().c_str(),
+ message ? message : "");
+ return SendErrorResponse(0x03);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendOKResponse ()
-{
- return SendPacketNoLock ("OK", 2);
+GDBRemoteCommunicationServer::SendOKResponse() {
+ return SendPacketNoLock("OK");
}
-bool
-GDBRemoteCommunicationServer::HandshakeWithClient()
-{
- return GetAck() == PacketResult::Success;
+bool GDBRemoteCommunicationServer::HandshakeWithClient() {
+ return GetAck() == PacketResult::Success;
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 1d512bf1de59..0c583e62d76b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -17,8 +17,8 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunication.h"
+#include "lldb/lldb-private-forward.h"
class StringExtractorGDBRemote;
@@ -27,52 +27,47 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class GDBRemoteCommunicationServer : public GDBRemoteCommunication
-{
+class GDBRemoteCommunicationServer : public GDBRemoteCommunication {
public:
- using PortMap = std::map<uint16_t, lldb::pid_t>;
- using PacketHandler = std::function<PacketResult(StringExtractorGDBRemote &packet,
- Error &error,
- bool &interrupt,
- bool &quit)>;
+ using PortMap = std::map<uint16_t, lldb::pid_t>;
+ using PacketHandler =
+ std::function<PacketResult(StringExtractorGDBRemote &packet, Error &error,
+ bool &interrupt, bool &quit)>;
- GDBRemoteCommunicationServer(const char *comm_name,
- const char *listener_name);
+ GDBRemoteCommunicationServer(const char *comm_name,
+ const char *listener_name);
- ~GDBRemoteCommunicationServer() override;
+ ~GDBRemoteCommunicationServer() override;
- void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
- PacketHandler handler);
+ void
+ RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
+ PacketHandler handler);
- PacketResult
- GetPacketAndSendResponse (uint32_t timeout_usec,
- Error &error,
- bool &interrupt,
- bool &quit);
+ PacketResult GetPacketAndSendResponse(Timeout<std::micro> timeout,
+ Error &error, bool &interrupt,
+ bool &quit);
- // After connecting, do a little handshake with the client to make sure
- // we are at least communicating
- bool
- HandshakeWithClient ();
+ // After connecting, do a little handshake with the client to make sure
+ // we are at least communicating
+ bool HandshakeWithClient();
protected:
- std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler> m_packet_handlers;
- bool m_exit_now; // use in asynchronous handling to indicate process should exit.
+ std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler>
+ m_packet_handlers;
+ bool m_exit_now; // use in asynchronous handling to indicate process should
+ // exit.
- PacketResult
- SendUnimplementedResponse (const char *packet);
+ PacketResult SendUnimplementedResponse(const char *packet);
- PacketResult
- SendErrorResponse (uint8_t error);
+ PacketResult SendErrorResponse(uint8_t error);
- PacketResult
- SendIllFormedResponse (const StringExtractorGDBRemote &packet, const char *error_message);
+ PacketResult SendIllFormedResponse(const StringExtractorGDBRemote &packet,
+ const char *error_message);
- PacketResult
- SendOKResponse ();
+ PacketResult SendOKResponse();
private:
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServer);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 26a2e697e854..e4e6810f665c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -12,12 +12,16 @@
#include <errno.h>
// C Includes
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
// C++ Includes
-#include <cstring>
#include <chrono>
+#include <cstring>
// Other libraries and framework includes
-#include "llvm/ADT/Triple.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StreamGDBRemote.h"
@@ -34,6 +38,8 @@
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/JSON.h"
+#include "llvm/ADT/Triple.h"
// Project includes
#include "ProcessGDBRemoteLog.h"
@@ -43,1214 +49,1252 @@
#include "lldb/Host/android/HostInfoAndroid.h"
#endif
+#include "llvm/ADT/StringSwitch.h"
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
#ifdef __ANDROID__
- const static uint32_t g_default_packet_timeout_sec = 20; // seconds
+const static uint32_t g_default_packet_timeout_sec = 20; // seconds
#else
- const static uint32_t g_default_packet_timeout_sec = 0; // not specified
+const static uint32_t g_default_packet_timeout_sec = 0; // not specified
#endif
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerCommon constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name) :
- GDBRemoteCommunicationServer (comm_name, listener_name),
- m_process_launch_info (),
- m_process_launch_error (),
- m_proc_infos (),
- m_proc_infos_index (0),
- m_thread_suffix_supported (false),
- m_list_threads_in_stop_reply (false)
-{
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
- &GDBRemoteCommunicationServerCommon::Handle_A);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironment,
- &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
- &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGroupName,
- &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qHostInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
- &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
- &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
- &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qEcho,
- &GDBRemoteCommunicationServerCommon::Handle_qEcho);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
- &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
- &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
- &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
- &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
- &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
- &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
- &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
- &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
- &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
- &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSupported,
- &GDBRemoteCommunicationServerCommon::Handle_qSupported);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
- &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qUserName,
- &GDBRemoteCommunicationServerCommon::Handle_qUserName);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_close,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_exists,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_md5,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_mode,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_open,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pread,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_size,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_stat,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
+GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
+ const char *comm_name, const char *listener_name)
+ : GDBRemoteCommunicationServer(comm_name, listener_name),
+ m_process_launch_info(), m_process_launch_error(), m_proc_infos(),
+ m_proc_infos_index(0), m_thread_suffix_supported(false),
+ m_list_threads_in_stop_reply(false) {
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
+ &GDBRemoteCommunicationServerCommon::Handle_A);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QEnvironment,
+ &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
+ &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qGroupName,
+ &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qHostInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
+ &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
+ &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
+ &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qEcho,
+ &GDBRemoteCommunicationServerCommon::Handle_qEcho);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jModulesInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
+ &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
+ &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
+ &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
+ &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
+ &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
+ &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qSupported,
+ &GDBRemoteCommunicationServerCommon::Handle_qSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
+ &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qUserName,
+ &GDBRemoteCommunicationServerCommon::Handle_qUserName);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_close,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_exists,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_md5,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_mode,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_open,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_pread,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_size,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_stat,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon()
-{
-}
+GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qHostInfo (StringExtractorGDBRemote &packet)
-{
- StreamString response;
+GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
+ StringExtractorGDBRemote &packet) {
+ StreamString response;
- // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
+ // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
- ArchSpec host_arch(HostInfo::GetArchitecture());
- const llvm::Triple &host_triple = host_arch.GetTriple();
- response.PutCString("triple:");
- response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
- response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
-
- const char* distribution_id = host_arch.GetDistributionId ().AsCString ();
- if (distribution_id)
- {
- response.PutCString("distribution_id:");
- response.PutCStringAsRawHex8(distribution_id);
- response.PutCString(";");
- }
+ ArchSpec host_arch(HostInfo::GetArchitecture());
+ const llvm::Triple &host_triple = host_arch.GetTriple();
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
+ response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
+
+ const char *distribution_id = host_arch.GetDistributionId().AsCString();
+ if (distribution_id) {
+ response.PutCString("distribution_id:");
+ response.PutCStringAsRawHex8(distribution_id);
+ response.PutCString(";");
+ }
- // Only send out MachO info when lldb-platform/llgs is running on a MachO host.
#if defined(__APPLE__)
- uint32_t cpu = host_arch.GetMachOCPUType();
- uint32_t sub = host_arch.GetMachOCPUSubType();
- if (cpu != LLDB_INVALID_CPUTYPE)
- response.Printf ("cputype:%u;", cpu);
- if (sub != LLDB_INVALID_CPUTYPE)
- response.Printf ("cpusubtype:%u;", sub);
-
- if (cpu == ArchSpec::kCore_arm_any)
- response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
- else
- response.Printf("watchpoint_exceptions_received:after;");
+ // For parity with debugserver, we'll include the vendor key.
+ response.PutCString("vendor:apple;");
+
+ // Send out MachO info.
+ uint32_t cpu = host_arch.GetMachOCPUType();
+ uint32_t sub = host_arch.GetMachOCPUSubType();
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ response.Printf("cputype:%u;", cpu);
+ if (sub != LLDB_INVALID_CPUTYPE)
+ response.Printf("cpusubtype:%u;", sub);
+
+ if (cpu == ArchSpec::kCore_arm_any) {
+// Indicate the OS type.
+#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
+ response.PutCString("ostype:tvos;");
+#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
+ response.PutCString("ostype:watchos;");
#else
- if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
- host_arch.GetMachine() == llvm::Triple::aarch64_be ||
- host_arch.GetMachine() == llvm::Triple::arm ||
- host_arch.GetMachine() == llvm::Triple::armeb ||
- host_arch.GetMachine() == llvm::Triple::mips64 ||
- host_arch.GetMachine() == llvm::Triple::mips64el ||
- host_arch.GetMachine() == llvm::Triple::mips ||
- host_arch.GetMachine() == llvm::Triple::mipsel)
- response.Printf("watchpoint_exceptions_received:before;");
- else
- response.Printf("watchpoint_exceptions_received:after;");
+ response.PutCString("ostype:ios;");
#endif
- switch (endian::InlHostByteOrder())
- {
- case eByteOrderBig: response.PutCString ("endian:big;"); break;
- case eByteOrderLittle: response.PutCString ("endian:little;"); break;
- case eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
- default: response.PutCString ("endian:unknown;"); break;
- }
+ // On arm, we use "synchronous" watchpoints which means the exception is
+ // delivered before the instruction executes.
+ response.PutCString("watchpoint_exceptions_received:before;");
+ } else {
+ response.PutCString("ostype:macosx;");
+ response.Printf("watchpoint_exceptions_received:after;");
+ }
- uint32_t major = UINT32_MAX;
- uint32_t minor = UINT32_MAX;
- uint32_t update = UINT32_MAX;
- if (HostInfo::GetOSVersion(major, minor, update))
- {
- if (major != UINT32_MAX)
- {
- response.Printf("os_version:%u", major);
- if (minor != UINT32_MAX)
- {
- response.Printf(".%u", minor);
- if (update != UINT32_MAX)
- response.Printf(".%u", update);
- }
- response.PutChar(';');
- }
- }
+#else
+ if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
+ host_arch.GetMachine() == llvm::Triple::aarch64_be ||
+ host_arch.GetMachine() == llvm::Triple::arm ||
+ host_arch.GetMachine() == llvm::Triple::armeb ||
+ host_arch.GetMachine() == llvm::Triple::mips64 ||
+ host_arch.GetMachine() == llvm::Triple::mips64el ||
+ host_arch.GetMachine() == llvm::Triple::mips ||
+ host_arch.GetMachine() == llvm::Triple::mipsel)
+ response.Printf("watchpoint_exceptions_received:before;");
+ else
+ response.Printf("watchpoint_exceptions_received:after;");
+#endif
- std::string s;
- if (HostInfo::GetOSBuildString(s))
- {
- response.PutCString ("os_build:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
- }
- if (HostInfo::GetOSKernelDescription(s))
- {
- response.PutCString ("os_kernel:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
+ switch (endian::InlHostByteOrder()) {
+ case eByteOrderBig:
+ response.PutCString("endian:big;");
+ break;
+ case eByteOrderLittle:
+ response.PutCString("endian:little;");
+ break;
+ case eByteOrderPDP:
+ response.PutCString("endian:pdp;");
+ break;
+ default:
+ response.PutCString("endian:unknown;");
+ break;
+ }
+
+ uint32_t major = UINT32_MAX;
+ uint32_t minor = UINT32_MAX;
+ uint32_t update = UINT32_MAX;
+ if (HostInfo::GetOSVersion(major, minor, update)) {
+ if (major != UINT32_MAX) {
+ response.Printf("os_version:%u", major);
+ if (minor != UINT32_MAX) {
+ response.Printf(".%u", minor);
+ if (update != UINT32_MAX)
+ response.Printf(".%u", update);
+ }
+ response.PutChar(';');
}
+ }
+
+ std::string s;
+ if (HostInfo::GetOSBuildString(s)) {
+ response.PutCString("os_build:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
+ if (HostInfo::GetOSKernelDescription(s)) {
+ response.PutCString("os_kernel:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
#if defined(__APPLE__)
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- // For iOS devices, we are connected through a USB Mux so we never pretend
- // to actually have a hostname as far as the remote lldb that is connecting
- // to this lldb-platform is concerned
- response.PutCString ("hostname:");
- response.PutCStringAsRawHex8("127.0.0.1");
+ // For iOS devices, we are connected through a USB Mux so we never pretend
+ // to actually have a hostname as far as the remote lldb that is connecting
+ // to this lldb-platform is concerned
+ response.PutCString("hostname:");
+ response.PutCStringAsRawHex8("127.0.0.1");
+ response.PutChar(';');
+#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ if (HostInfo::GetHostname(s)) {
+ response.PutCString("hostname:");
+ response.PutCStringAsRawHex8(s.c_str());
response.PutChar(';');
-#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- if (HostInfo::GetHostname(s))
- {
- response.PutCString ("hostname:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
- }
-#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ }
+#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-#else // #if defined(__APPLE__)
- if (HostInfo::GetHostname(s))
- {
- response.PutCString ("hostname:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
- }
-#endif // #if defined(__APPLE__)
+#else // #if defined(__APPLE__)
+ if (HostInfo::GetHostname(s)) {
+ response.PutCString("hostname:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
+#endif // #if defined(__APPLE__)
- if (g_default_packet_timeout_sec > 0)
- response.Printf ("default_packet_timeout:%u;", g_default_packet_timeout_sec);
+ if (g_default_packet_timeout_sec > 0)
+ response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);
- return SendPacketNoLock (response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
-{
- // Packet format: "qProcessInfoPID:%i" where %i is the pid
- packet.SetFilePos (::strlen ("qProcessInfoPID:"));
- lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- ProcessInstanceInfo proc_info;
- if (Host::GetProcessInfo (pid, proc_info))
- {
- StreamString response;
- CreateProcessInfoResponse (proc_info, response);
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
+GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID(
+ StringExtractorGDBRemote &packet) {
+ // Packet format: "qProcessInfoPID:%i" where %i is the pid
+ packet.SetFilePos(::strlen("qProcessInfoPID:"));
+ lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID);
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ ProcessInstanceInfo proc_info;
+ if (Host::GetProcessInfo(pid, proc_info)) {
+ StreamString response;
+ CreateProcessInfoResponse(proc_info, response);
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse (1);
+ }
+ return SendErrorResponse(1);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
-{
- m_proc_infos_index = 0;
- m_proc_infos.Clear();
-
- ProcessInstanceInfoMatch match_info;
- packet.SetFilePos(::strlen ("qfProcessInfo"));
- if (packet.GetChar() == ':')
- {
-
- std::string key;
- std::string value;
- while (packet.GetNameColonValue(key, value))
- {
- bool success = true;
- if (key.compare("name") == 0)
- {
- StringExtractor extractor;
- extractor.GetStringRef().swap(value);
- extractor.GetHexByteString (value);
- match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false);
- }
- else if (key.compare("name_match") == 0)
- {
- if (value.compare("equals") == 0)
- {
- match_info.SetNameMatchType (eNameMatchEquals);
- }
- else if (value.compare("starts_with") == 0)
- {
- match_info.SetNameMatchType (eNameMatchStartsWith);
- }
- else if (value.compare("ends_with") == 0)
- {
- match_info.SetNameMatchType (eNameMatchEndsWith);
- }
- else if (value.compare("contains") == 0)
- {
- match_info.SetNameMatchType (eNameMatchContains);
- }
- else if (value.compare("regex") == 0)
- {
- match_info.SetNameMatchType (eNameMatchRegularExpression);
- }
- else
- {
- success = false;
- }
- }
- else if (key.compare("pid") == 0)
- {
- match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
- }
- else if (key.compare("parent_pid") == 0)
- {
- match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
- }
- else if (key.compare("uid") == 0)
- {
- match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("gid") == 0)
- {
- match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("euid") == 0)
- {
- match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("egid") == 0)
- {
- match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("all_users") == 0)
- {
- match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
- }
- else if (key.compare("triple") == 0)
- {
- match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL);
- }
- else
- {
- success = false;
- }
-
- if (!success)
- return SendErrorResponse (2);
- }
- }
-
- if (Host::FindProcesses (match_info, m_proc_infos))
- {
- // We found something, return the first item by calling the get
- // subsequent process info packet handler...
- return Handle_qsProcessInfo (packet);
+GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ m_proc_infos_index = 0;
+ m_proc_infos.Clear();
+
+ ProcessInstanceInfoMatch match_info;
+ packet.SetFilePos(::strlen("qfProcessInfo"));
+ if (packet.GetChar() == ':') {
+ llvm::StringRef key;
+ llvm::StringRef value;
+ while (packet.GetNameColonValue(key, value)) {
+ bool success = true;
+ if (key.equals("name")) {
+ StringExtractor extractor(value);
+ std::string file;
+ extractor.GetHexByteString(file);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(file, false);
+ } else if (key.equals("name_match")) {
+ NameMatchType name_match =
+ llvm::StringSwitch<NameMatchType>(value)
+ .Case("equals", eNameMatchEquals)
+ .Case("starts_with", eNameMatchStartsWith)
+ .Case("ends_with", eNameMatchEndsWith)
+ .Case("contains", eNameMatchContains)
+ .Case("regex", eNameMatchRegularExpression)
+ .Default(eNameMatchIgnore);
+ match_info.SetNameMatchType(name_match);
+ if (name_match == eNameMatchIgnore)
+ return SendErrorResponse(2);
+ } else if (key.equals("pid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ if (value.getAsInteger(0, pid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetProcessID(pid);
+ } else if (key.equals("parent_pid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ if (value.getAsInteger(0, pid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetParentProcessID(pid);
+ } else if (key.equals("uid")) {
+ uint32_t uid = UINT32_MAX;
+ if (value.getAsInteger(0, uid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetUserID(uid);
+ } else if (key.equals("gid")) {
+ uint32_t gid = UINT32_MAX;
+ if (value.getAsInteger(0, gid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetGroupID(gid);
+ } else if (key.equals("euid")) {
+ uint32_t uid = UINT32_MAX;
+ if (value.getAsInteger(0, uid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetEffectiveUserID(uid);
+ } else if (key.equals("egid")) {
+ uint32_t gid = UINT32_MAX;
+ if (value.getAsInteger(0, gid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetEffectiveGroupID(gid);
+ } else if (key.equals("all_users")) {
+ match_info.SetMatchAllUsers(
+ Args::StringToBoolean(value, false, &success));
+ } else if (key.equals("triple")) {
+ match_info.GetProcessInfo().GetArchitecture().SetTriple(
+ value.str().c_str(), NULL);
+ } else {
+ success = false;
+ }
+
+ if (!success)
+ return SendErrorResponse(2);
}
- return SendErrorResponse (3);
+ }
+
+ if (Host::FindProcesses(match_info, m_proc_infos)) {
+ // We found something, return the first item by calling the get
+ // subsequent process info packet handler...
+ return Handle_qsProcessInfo(packet);
+ }
+ return SendErrorResponse(3);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
-{
- if (m_proc_infos_index < m_proc_infos.GetSize())
- {
- StreamString response;
- CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
- ++m_proc_infos_index;
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
- return SendErrorResponse (4);
+GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ if (m_proc_infos_index < m_proc_infos.GetSize()) {
+ StreamString response;
+ CreateProcessInfoResponse(
+ m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
+ ++m_proc_infos_index;
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(4);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qUserName (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_qUserName(
+ StringExtractorGDBRemote &packet) {
#if !defined(LLDB_DISABLE_POSIX)
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
-
- // Packet format: "qUserName:%i" where %i is the uid
- packet.SetFilePos(::strlen ("qUserName:"));
- uint32_t uid = packet.GetU32 (UINT32_MAX);
- if (uid != UINT32_MAX)
- {
- std::string name;
- if (HostInfo::LookupUserName(uid, name))
- {
- StreamString response;
- response.PutCStringAsRawHex8 (name.c_str());
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
+
+ // Packet format: "qUserName:%i" where %i is the uid
+ packet.SetFilePos(::strlen("qUserName:"));
+ uint32_t uid = packet.GetU32(UINT32_MAX);
+ if (uid != UINT32_MAX) {
+ std::string name;
+ if (HostInfo::LookupUserName(uid, name)) {
+ StreamString response;
+ response.PutCStringAsRawHex8(name.c_str());
+ return SendPacketNoLock(response.GetString());
}
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
+ }
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
#endif
- return SendErrorResponse (5);
-
+ return SendErrorResponse(5);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qGroupName (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_qGroupName(
+ StringExtractorGDBRemote &packet) {
#if !defined(LLDB_DISABLE_POSIX)
- // Packet format: "qGroupName:%i" where %i is the gid
- packet.SetFilePos(::strlen ("qGroupName:"));
- uint32_t gid = packet.GetU32 (UINT32_MAX);
- if (gid != UINT32_MAX)
- {
- std::string name;
- if (HostInfo::LookupGroupName(gid, name))
- {
- StreamString response;
- response.PutCStringAsRawHex8 (name.c_str());
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
+ // Packet format: "qGroupName:%i" where %i is the gid
+ packet.SetFilePos(::strlen("qGroupName:"));
+ uint32_t gid = packet.GetU32(UINT32_MAX);
+ if (gid != UINT32_MAX) {
+ std::string name;
+ if (HostInfo::LookupGroupName(gid, name)) {
+ StreamString response;
+ response.PutCStringAsRawHex8(name.c_str());
+ return SendPacketNoLock(response.GetString());
}
+ }
#endif
- return SendErrorResponse (6);
+ return SendErrorResponse(6);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("qSpeedTest:"));
-
- std::string key;
- std::string value;
- bool success = packet.GetNameColonValue(key, value);
- if (success && key.compare("response_size") == 0)
- {
- uint32_t response_size = StringConvert::ToUInt32(value.c_str(), 0, 0, &success);
- if (success)
- {
- if (response_size == 0)
- return SendOKResponse();
- StreamString response;
- uint32_t bytes_left = response_size;
- response.PutCString("data:");
- while (bytes_left > 0)
- {
- if (bytes_left >= 26)
- {
- response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- bytes_left -= 26;
- }
- else
- {
- response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- bytes_left = 0;
- }
- }
- return SendPacketNoLock (response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_qSpeedTest(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qSpeedTest:"));
+
+ llvm::StringRef key;
+ llvm::StringRef value;
+ bool success = packet.GetNameColonValue(key, value);
+ if (success && key.equals("response_size")) {
+ uint32_t response_size = 0;
+ if (!value.getAsInteger(0, response_size)) {
+ if (response_size == 0)
+ return SendOKResponse();
+ StreamString response;
+ uint32_t bytes_left = response_size;
+ response.PutCString("data:");
+ while (bytes_left > 0) {
+ if (bytes_left >= 26) {
+ response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ bytes_left -= 26;
+ } else {
+ response.Printf("%*.*s;", bytes_left, bytes_left,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ bytes_left = 0;
}
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse (7);
+ }
+ return SendErrorResponse(7);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:open:"));
- std::string path;
- packet.GetHexByteStringTerminatedBy(path,',');
- if (!path.empty())
- {
- if (packet.GetChar() == ',')
- {
- uint32_t flags = File::ConvertOpenOptionsForPOSIXOpen(
- packet.GetHexMaxU32(false, 0));
- if (packet.GetChar() == ',')
- {
- mode_t mode = packet.GetHexMaxU32(false, 0600);
- Error error;
- const FileSpec path_spec{path, true};
- int fd = ::open(path_spec.GetCString(), flags, mode);
- const int save_errno = fd == -1 ? errno : 0;
- StreamString response;
- response.PutChar('F');
- response.Printf("%i", fd);
- if (save_errno)
- response.Printf(",%i", save_errno);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- }
+GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:open:"));
+ std::string path;
+ packet.GetHexByteStringTerminatedBy(path, ',');
+ if (!path.empty()) {
+ if (packet.GetChar() == ',') {
+ uint32_t flags =
+ File::ConvertOpenOptionsForPOSIXOpen(packet.GetHexMaxU32(false, 0));
+ if (packet.GetChar() == ',') {
+ mode_t mode = packet.GetHexMaxU32(false, 0600);
+ Error error;
+ const FileSpec path_spec{path, true};
+ int fd = ::open(path_spec.GetCString(), flags, mode);
+ const int save_errno = fd == -1 ? errno : 0;
+ StreamString response;
+ response.PutChar('F');
+ response.Printf("%i", fd);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ return SendPacketNoLock(response.GetString());
+ }
}
- return SendErrorResponse(18);
+ }
+ return SendErrorResponse(18);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Close (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:close:"));
- int fd = packet.GetS32(-1);
- Error error;
- int err = -1;
- int save_errno = 0;
- if (fd >= 0)
- {
- err = close(fd);
- save_errno = err == -1 ? errno : 0;
- }
- else
- {
- save_errno = EINVAL;
- }
- StreamString response;
- response.PutChar('F');
- response.Printf("%i", err);
- if (save_errno)
- response.Printf(",%i", save_errno);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:close:"));
+ int fd = packet.GetS32(-1);
+ Error error;
+ int err = -1;
+ int save_errno = 0;
+ if (fd >= 0) {
+ err = close(fd);
+ save_errno = err == -1 ? errno : 0;
+ } else {
+ save_errno = EINVAL;
+ }
+ StreamString response;
+ response.PutChar('F');
+ response.Printf("%i", err);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
+ StringExtractorGDBRemote &packet) {
#ifdef _WIN32
- // Not implemented on Windows
- return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
+ // Not implemented on Windows
+ return SendUnimplementedResponse(
+ "GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
#else
- StreamGDBRemote response;
- packet.SetFilePos(::strlen("vFile:pread:"));
- int fd = packet.GetS32(-1);
- if (packet.GetChar() == ',')
- {
- uint64_t count = packet.GetU64(UINT64_MAX);
- if (packet.GetChar() == ',')
- {
- uint64_t offset = packet.GetU64(UINT32_MAX);
- if (count == UINT64_MAX)
- {
- response.Printf("F-1:%i", EINVAL);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
-
- std::string buffer(count, 0);
- const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
- const int save_errno = bytes_read == -1 ? errno : 0;
- response.PutChar('F');
- response.Printf("%zi", bytes_read);
- if (save_errno)
- response.Printf(",%i", save_errno);
- else
- {
- response.PutChar(';');
- response.PutEscapedBytes(&buffer[0], bytes_read);
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+ StreamGDBRemote response;
+ packet.SetFilePos(::strlen("vFile:pread:"));
+ int fd = packet.GetS32(-1);
+ if (packet.GetChar() == ',') {
+ uint64_t count = packet.GetU64(UINT64_MAX);
+ if (packet.GetChar() == ',') {
+ uint64_t offset = packet.GetU64(UINT32_MAX);
+ if (count == UINT64_MAX) {
+ response.Printf("F-1:%i", EINVAL);
+ return SendPacketNoLock(response.GetString());
+ }
+
+ std::string buffer(count, 0);
+ const ssize_t bytes_read = ::pread(fd, &buffer[0], buffer.size(), offset);
+ const int save_errno = bytes_read == -1 ? errno : 0;
+ response.PutChar('F');
+ response.Printf("%zi", bytes_read);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ else {
+ response.PutChar(';');
+ response.PutEscapedBytes(&buffer[0], bytes_read);
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse(21);
+ }
+ return SendErrorResponse(21);
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
+ StringExtractorGDBRemote &packet) {
#ifdef _WIN32
- return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite() unimplemented");
+ return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_"
+ "vFile_pWrite() unimplemented");
#else
- packet.SetFilePos(::strlen("vFile:pwrite:"));
-
- StreamGDBRemote response;
- response.PutChar('F');
-
- int fd = packet.GetU32(UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- off_t offset = packet.GetU64(UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- std::string buffer;
- if (packet.GetEscapedBinaryData(buffer))
- {
- const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset);
- const int save_errno = bytes_written == -1 ? errno : 0;
- response.Printf("%zi", bytes_written);
- if (save_errno)
- response.Printf(",%i", save_errno);
- }
- else
- {
- response.Printf ("-1,%i", EINVAL);
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+ packet.SetFilePos(::strlen("vFile:pwrite:"));
+
+ StreamGDBRemote response;
+ response.PutChar('F');
+
+ int fd = packet.GetU32(UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ off_t offset = packet.GetU64(UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ std::string buffer;
+ if (packet.GetEscapedBinaryData(buffer)) {
+ const ssize_t bytes_written =
+ ::pwrite(fd, buffer.data(), buffer.size(), offset);
+ const int save_errno = bytes_written == -1 ? errno : 0;
+ response.Printf("%zi", bytes_written);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ } else {
+ response.Printf("-1,%i", EINVAL);
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse(27);
+ }
+ return SendErrorResponse(27);
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Size (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:size:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path.c_str(), false));
- StreamString response;
- response.PutChar('F');
- response.PutHex64(retcode);
- if (retcode == UINT64_MAX)
- {
- response.PutChar(',');
- response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode()
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:size:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path, false));
+ StreamString response;
+ response.PutChar('F');
+ response.PutHex64(retcode);
+ if (retcode == UINT64_MAX) {
+ response.PutChar(',');
+ response.PutHex64(
+ retcode); // TODO: replace with Host::GetSyswideErrorCode()
}
- return SendErrorResponse(22);
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(22);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:mode:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- Error error;
- const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
- StreamString response;
- response.Printf("F%u", mode);
- if (mode == 0 || error.Fail())
- response.Printf(",%i", (int)error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(23);
+GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:mode:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ Error error;
+ const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
+ StreamString response;
+ response.Printf("F%u", mode);
+ if (mode == 0 || error.Fail())
+ response.Printf(",%i", (int)error.GetError());
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(23);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:exists:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- bool retcode = FileSystem::GetFileExists(FileSpec(path.c_str(), false));
- StreamString response;
- response.PutChar('F');
- response.PutChar(',');
- if (retcode)
- response.PutChar('1');
- else
- response.PutChar('0');
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(24);
+GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:exists:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ bool retcode = FileSystem::GetFileExists(FileSpec(path, false));
+ StreamString response;
+ response.PutChar('F');
+ response.PutChar(',');
+ if (retcode)
+ response.PutChar('1');
+ else
+ response.PutChar('0');
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(24);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:symlink:"));
- std::string dst, src;
- packet.GetHexByteStringTerminatedBy(dst, ',');
- packet.GetChar(); // Skip ',' char
- packet.GetHexByteString(src);
- Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
- StreamString response;
- response.Printf("F%u,%u", error.GetError(), error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:symlink:"));
+ std::string dst, src;
+ packet.GetHexByteStringTerminatedBy(dst, ',');
+ packet.GetChar(); // Skip ',' char
+ packet.GetHexByteString(src);
+ Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
+ StreamString response;
+ response.Printf("F%u,%u", error.GetError(), error.GetError());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:unlink:"));
- std::string path;
- packet.GetHexByteString(path);
- Error error = FileSystem::Unlink(FileSpec{path, true});
- StreamString response;
- response.Printf("F%u,%u", error.GetError(), error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:unlink:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ Error error = FileSystem::Unlink(FileSpec{path, true});
+ StreamString response;
+ response.Printf("F%u,%u", error.GetError(), error.GetError());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("qPlatform_shell:"));
- std::string path;
- std::string working_dir;
- packet.GetHexByteStringTerminatedBy(path,',');
- if (!path.empty())
- {
- if (packet.GetChar() == ',')
- {
- // FIXME: add timeout to qPlatform_shell packet
- // uint32_t timeout = packet.GetHexMaxU32(false, 32);
- uint32_t timeout = 10;
- if (packet.GetChar() == ',')
- packet.GetHexByteString(working_dir);
- int status, signo;
- std::string output;
- Error err = Host::RunShellCommand(path.c_str(),
- FileSpec{working_dir, true},
- &status, &signo, &output, timeout);
- StreamGDBRemote response;
- if (err.Fail())
- {
- response.PutCString("F,");
- response.PutHex32(UINT32_MAX);
- }
- else
- {
- response.PutCString("F,");
- response.PutHex32(status);
- response.PutChar(',');
- response.PutHex32(signo);
- response.PutChar(',');
- response.PutEscapedBytes(output.c_str(), output.size());
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qPlatform_shell:"));
+ std::string path;
+ std::string working_dir;
+ packet.GetHexByteStringTerminatedBy(path, ',');
+ if (!path.empty()) {
+ if (packet.GetChar() == ',') {
+ // FIXME: add timeout to qPlatform_shell packet
+ // uint32_t timeout = packet.GetHexMaxU32(false, 32);
+ uint32_t timeout = 10;
+ if (packet.GetChar() == ',')
+ packet.GetHexByteString(working_dir);
+ int status, signo;
+ std::string output;
+ Error err =
+ Host::RunShellCommand(path.c_str(), FileSpec{working_dir, true},
+ &status, &signo, &output, timeout);
+ StreamGDBRemote response;
+ if (err.Fail()) {
+ response.PutCString("F,");
+ response.PutHex32(UINT32_MAX);
+ } else {
+ response.PutCString("F,");
+ response.PutHex32(status);
+ response.PutChar(',');
+ response.PutHex32(signo);
+ response.PutChar(',');
+ response.PutEscapedBytes(output.c_str(), output.size());
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse(24);
+ }
+ return SendErrorResponse(24);
}
-
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
-{
- return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
+GDBRemoteCommunicationServerCommon::Handle_vFile_Stat(
+ StringExtractorGDBRemote &packet) {
+ return SendUnimplementedResponse(
+ "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:MD5:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- uint64_t a,b;
- StreamGDBRemote response;
- if (!FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b))
- {
- response.PutCString("F,");
- response.PutCString("x");
- }
- else
- {
- response.PutCString("F,");
- response.PutHex64(a);
- response.PutHex64(b);
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_MD5(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:MD5:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ uint64_t a, b;
+ StreamGDBRemote response;
+ if (!FileSystem::CalculateMD5(FileSpec(path, false), a, b)) {
+ response.PutCString("F,");
+ response.PutCString("x");
+ } else {
+ response.PutCString("F,");
+ response.PutHex64(a);
+ response.PutHex64(b);
}
- return SendErrorResponse(25);
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(25);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("qPlatform_mkdir:"));
- mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- std::string path;
- packet.GetHexByteString(path);
- Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
-
- StreamGDBRemote response;
- response.Printf("F%u", error.GetError());
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(20);
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qPlatform_mkdir:"));
+ mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ std::string path;
+ packet.GetHexByteString(path);
+ Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
+
+ StreamGDBRemote response;
+ response.Printf("F%u", error.GetError());
+
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(20);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("qPlatform_chmod:"));
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qPlatform_chmod:"));
- mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- std::string path;
- packet.GetHexByteString(path);
- Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
+ mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ std::string path;
+ packet.GetHexByteString(path);
+ Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
- StreamGDBRemote response;
- response.Printf("F%u", error.GetError());
+ StreamGDBRemote response;
+ response.Printf("F%u", error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(19);
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(19);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qSupported (StringExtractorGDBRemote &packet)
-{
- StreamGDBRemote response;
-
- // Features common to lldb-platform and llgs.
- uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less
- response.Printf ("PacketSize=%x", max_packet_size);
-
- response.PutCString (";QStartNoAckMode+");
- response.PutCString (";QThreadSuffixSupported+");
- response.PutCString (";QListThreadsInStopReply+");
- response.PutCString (";qEcho+");
+GDBRemoteCommunicationServerCommon::Handle_qSupported(
+ StringExtractorGDBRemote &packet) {
+ StreamGDBRemote response;
+
+ // Features common to lldb-platform and llgs.
+ uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet
+ // size--debugger can always use less
+ response.Printf("PacketSize=%x", max_packet_size);
+
+ response.PutCString(";QStartNoAckMode+");
+ response.PutCString(";QThreadSuffixSupported+");
+ response.PutCString(";QListThreadsInStopReply+");
+ response.PutCString(";qEcho+");
#if defined(__linux__)
- response.PutCString (";qXfer:auxv:read+");
+ response.PutCString(";qXfer:auxv:read+");
#endif
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet)
-{
- m_thread_suffix_supported = true;
- return SendOKResponse();
+GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported(
+ StringExtractorGDBRemote &packet) {
+ m_thread_suffix_supported = true;
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet)
-{
- m_list_threads_in_stop_reply = true;
- return SendOKResponse();
+GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply(
+ StringExtractorGDBRemote &packet) {
+ m_list_threads_in_stop_reply = true;
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetDetachOnError:"));
- if (packet.GetU32(0))
- m_process_launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
- else
- m_process_launch_info.GetFlags().Clear (eLaunchFlagDetachOnError);
- return SendOKResponse ();
+GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetDetachOnError:"));
+ if (packet.GetU32(0))
+ m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
+ else
+ m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
-{
- // Send response first before changing m_send_acks to we ack this packet
- PacketResult packet_result = SendOKResponse ();
- m_send_acks = false;
- return packet_result;
+GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode(
+ StringExtractorGDBRemote &packet) {
+ // Send response first before changing m_send_acks to we ack this packet
+ PacketResult packet_result = SendOKResponse();
+ m_send_acks = false;
+ return packet_result;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetSTDIN:"));
- FileAction file_action;
- std::string path;
- packet.GetHexByteString(path);
- const bool read = false;
- const bool write = true;
- if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write))
- {
- m_process_launch_info.AppendFileAction(file_action);
- return SendOKResponse ();
- }
- return SendErrorResponse (15);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetSTDIN:"));
+ FileAction file_action;
+ std::string path;
+ packet.GetHexByteString(path);
+ const bool read = true;
+ const bool write = false;
+ if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) {
+ m_process_launch_info.AppendFileAction(file_action);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(15);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetSTDOUT:"));
- FileAction file_action;
- std::string path;
- packet.GetHexByteString(path);
- const bool read = true;
- const bool write = false;
- if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write))
- {
- m_process_launch_info.AppendFileAction(file_action);
- return SendOKResponse ();
- }
- return SendErrorResponse (16);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetSTDOUT:"));
+ FileAction file_action;
+ std::string path;
+ packet.GetHexByteString(path);
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) {
+ m_process_launch_info.AppendFileAction(file_action);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(16);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetSTDERR:"));
- FileAction file_action;
- std::string path;
- packet.GetHexByteString(path);
- const bool read = true;
- const bool write = false;
- if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write))
- {
- m_process_launch_info.AppendFileAction(file_action);
- return SendOKResponse ();
- }
- return SendErrorResponse (17);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetSTDERR:"));
+ FileAction file_action;
+ std::string path;
+ packet.GetHexByteString(path);
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) {
+ m_process_launch_info.AppendFileAction(file_action);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(17);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
-{
- if (m_process_launch_error.Success())
- return SendOKResponse();
- StreamString response;
- response.PutChar('E');
- response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
- return SendPacketNoLock (response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess(
+ StringExtractorGDBRemote &packet) {
+ if (m_process_launch_error.Success())
+ return SendOKResponse();
+ StreamString response;
+ response.PutChar('E');
+ response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QEnvironment (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QEnvironment:"));
- const uint32_t bytes_left = packet.GetBytesLeft();
- if (bytes_left > 0)
- {
- m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
- return SendOKResponse ();
- }
- return SendErrorResponse (12);
+GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QEnvironment:"));
+ const uint32_t bytes_left = packet.GetBytesLeft();
+ if (bytes_left > 0) {
+ m_process_launch_info.GetEnvironmentEntries().AppendArgument(
+ llvm::StringRef::withNullAsEmpty(packet.Peek()));
+ return SendOKResponse();
+ }
+ return SendErrorResponse(12);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
- const uint32_t bytes_left = packet.GetBytesLeft();
- if (bytes_left > 0)
- {
- std::string str;
- packet.GetHexByteString(str);
- m_process_launch_info.GetEnvironmentEntries().AppendArgument(str.c_str());
- return SendOKResponse();
- }
- return SendErrorResponse(12);
+GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
+ const uint32_t bytes_left = packet.GetBytesLeft();
+ if (bytes_left > 0) {
+ std::string str;
+ packet.GetHexByteString(str);
+ m_process_launch_info.GetEnvironmentEntries().AppendArgument(str);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(12);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QLaunchArch:"));
- const uint32_t bytes_left = packet.GetBytesLeft();
- if (bytes_left > 0)
- {
- const char* arch_triple = packet.Peek();
- ArchSpec arch_spec(arch_triple,NULL);
- m_process_launch_info.SetArchitecture(arch_spec);
- return SendOKResponse();
- }
- return SendErrorResponse(13);
+GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QLaunchArch:"));
+ const uint32_t bytes_left = packet.GetBytesLeft();
+ if (bytes_left > 0) {
+ const char *arch_triple = packet.Peek();
+ ArchSpec arch_spec(arch_triple, NULL);
+ m_process_launch_info.SetArchitecture(arch_spec);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(13);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_A (StringExtractorGDBRemote &packet)
-{
- // The 'A' packet is the most over designed packet ever here with
- // redundant argument indexes, redundant argument lengths and needed hex
- // encoded argument string values. Really all that is needed is a comma
- // separated hex encoded argument value list, but we will stay true to the
- // documented version of the 'A' packet here...
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- int actual_arg_index = 0;
-
- packet.SetFilePos(1); // Skip the 'A'
- bool success = true;
- while (success && packet.GetBytesLeft() > 0)
- {
- // Decode the decimal argument string length. This length is the
- // number of hex nibbles in the argument string value.
- const uint32_t arg_len = packet.GetU32(UINT32_MAX);
- if (arg_len == UINT32_MAX)
+GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
+ // The 'A' packet is the most over designed packet ever here with
+ // redundant argument indexes, redundant argument lengths and needed hex
+ // encoded argument string values. Really all that is needed is a comma
+ // separated hex encoded argument value list, but we will stay true to the
+ // documented version of the 'A' packet here...
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ int actual_arg_index = 0;
+
+ packet.SetFilePos(1); // Skip the 'A'
+ bool success = true;
+ while (success && packet.GetBytesLeft() > 0) {
+ // Decode the decimal argument string length. This length is the
+ // number of hex nibbles in the argument string value.
+ const uint32_t arg_len = packet.GetU32(UINT32_MAX);
+ if (arg_len == UINT32_MAX)
+ success = false;
+ else {
+ // Make sure the argument hex string length is followed by a comma
+ if (packet.GetChar() != ',')
+ success = false;
+ else {
+ // Decode the argument index. We ignore this really because
+ // who would really send down the arguments in a random order???
+ const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
+ if (arg_idx == UINT32_MAX)
+ success = false;
+ else {
+ // Make sure the argument index is followed by a comma
+ if (packet.GetChar() != ',')
success = false;
- else
- {
- // Make sure the argument hex string length is followed by a comma
- if (packet.GetChar() != ',')
- success = false;
- else
- {
- // Decode the argument index. We ignore this really because
- // who would really send down the arguments in a random order???
- const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
- if (arg_idx == UINT32_MAX)
- success = false;
- else
- {
- // Make sure the argument index is followed by a comma
- if (packet.GetChar() != ',')
- success = false;
- else
- {
- // Decode the argument string value from hex bytes
- // back into a UTF8 string and make sure the length
- // matches the one supplied in the packet
- std::string arg;
- if (packet.GetHexByteStringFixedLength(arg, arg_len) != (arg_len / 2))
- success = false;
- else
- {
- // If there are any bytes left
- if (packet.GetBytesLeft())
- {
- if (packet.GetChar() != ',')
- success = false;
- }
-
- if (success)
- {
- if (arg_idx == 0)
- m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
- m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
- if (log)
- log->Printf ("LLGSPacketHandler::%s added arg %d: \"%s\"", __FUNCTION__, actual_arg_index, arg.c_str ());
- ++actual_arg_index;
- }
- }
- }
- }
+ else {
+ // Decode the argument string value from hex bytes
+ // back into a UTF8 string and make sure the length
+ // matches the one supplied in the packet
+ std::string arg;
+ if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
+ (arg_len / 2))
+ success = false;
+ else {
+ // If there are any bytes left
+ if (packet.GetBytesLeft()) {
+ if (packet.GetChar() != ',')
+ success = false;
+ }
+
+ if (success) {
+ if (arg_idx == 0)
+ m_process_launch_info.GetExecutableFile().SetFile(arg, false);
+ m_process_launch_info.GetArguments().AppendArgument(arg);
+ if (log)
+ log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
+ __FUNCTION__, actual_arg_index, arg.c_str());
+ ++actual_arg_index;
+ }
}
+ }
}
+ }
}
-
- if (success)
- {
- m_process_launch_error = LaunchProcess ();
- if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- {
- return SendOKResponse ();
- }
- else
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
- __FUNCTION__,
- m_process_launch_error.AsCString());
-
- }
+ }
+
+ if (success) {
+ m_process_launch_error = LaunchProcess();
+ if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
+ return SendOKResponse();
+ } else {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
+ __FUNCTION__, m_process_launch_error.AsCString());
}
- return SendErrorResponse (8);
+ }
+ return SendErrorResponse(8);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qEcho (StringExtractorGDBRemote &packet)
-{
- // Just echo back the exact same packet for qEcho...
- return SendPacketNoLock(packet.GetStringRef().c_str(), packet.GetStringRef().size());
+GDBRemoteCommunicationServerCommon::Handle_qEcho(
+ StringExtractorGDBRemote &packet) {
+ // Just echo back the exact same packet for qEcho...
+ return SendPacketNoLock(packet.GetStringRef());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("qModuleInfo:"));
-
- std::string module_path;
- packet.GetHexByteStringTerminatedBy(module_path, ';');
- if (module_path.empty())
- return SendErrorResponse (1);
-
- if (packet.GetChar() != ';')
- return SendErrorResponse (2);
-
- std::string triple;
- packet.GetHexByteString(triple);
- ArchSpec arch(triple.c_str());
-
- const FileSpec req_module_path_spec(module_path.c_str(), true);
- const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch);
- const ModuleSpec module_spec(module_path_spec, arch);
-
- ModuleSpecList module_specs;
- if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs))
- return SendErrorResponse (3);
+GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qModuleInfo:"));
+
+ std::string module_path;
+ packet.GetHexByteStringTerminatedBy(module_path, ';');
+ if (module_path.empty())
+ return SendErrorResponse(1);
+
+ if (packet.GetChar() != ';')
+ return SendErrorResponse(2);
+
+ std::string triple;
+ packet.GetHexByteString(triple);
+
+ ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);
+ if (!matched_module_spec.GetFileSpec())
+ return SendErrorResponse(3);
+
+ const auto file_offset = matched_module_spec.GetObjectOffset();
+ const auto file_size = matched_module_spec.GetObjectSize();
+ const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
+
+ StreamGDBRemote response;
+
+ if (uuid_str.empty()) {
+ std::string md5_hash;
+ if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(),
+ file_offset, file_size, md5_hash))
+ return SendErrorResponse(5);
+ response.PutCString("md5:");
+ response.PutCStringAsRawHex8(md5_hash.c_str());
+ } else {
+ response.PutCString("uuid:");
+ response.PutCStringAsRawHex8(uuid_str.c_str());
+ }
+ response.PutChar(';');
+
+ const auto &module_arch = matched_module_spec.GetArchitecture();
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(module_arch.GetTriple().getTriple().c_str());
+ response.PutChar(';');
+
+ response.PutCString("file_path:");
+ response.PutCStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString());
+ response.PutChar(';');
+ response.PutCString("file_offset:");
+ response.PutHex64(file_offset);
+ response.PutChar(';');
+ response.PutCString("file_size:");
+ response.PutHex64(file_size);
+ response.PutChar(';');
+
+ return SendPacketNoLock(response.GetString());
+}
- ModuleSpec matched_module_spec;
- if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
- return SendErrorResponse (4);
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("jModulesInfo:"));
+
+ StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());
+ if (!object_sp)
+ return SendErrorResponse(1);
+
+ StructuredData::Array *packet_array = object_sp->GetAsArray();
+ if (!packet_array)
+ return SendErrorResponse(2);
+
+ JSONArray::SP response_array_sp = std::make_shared<JSONArray>();
+ for (size_t i = 0; i < packet_array->GetSize(); ++i) {
+ StructuredData::Dictionary *query =
+ packet_array->GetItemAtIndex(i)->GetAsDictionary();
+ if (!query)
+ continue;
+ std::string file, triple;
+ if (!query->GetValueForKeyAsString("file", file) ||
+ !query->GetValueForKeyAsString("triple", triple))
+ continue;
+
+ ModuleSpec matched_module_spec = GetModuleInfo(file, triple);
+ if (!matched_module_spec.GetFileSpec())
+ continue;
const auto file_offset = matched_module_spec.GetObjectOffset();
const auto file_size = matched_module_spec.GetObjectSize();
const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
- StreamGDBRemote response;
-
if (uuid_str.empty())
- {
- std::string md5_hash;
- if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), file_offset, file_size, md5_hash))
- return SendErrorResponse (5);
- response.PutCString ("md5:");
- response.PutCStringAsRawHex8(md5_hash.c_str());
- }
- else{
- response.PutCString ("uuid:");
- response.PutCStringAsRawHex8(uuid_str.c_str());
- }
- response.PutChar(';');
+ continue;
+
+ JSONObject::SP response = std::make_shared<JSONObject>();
+ response_array_sp->AppendObject(response);
+ response->SetObject("uuid", std::make_shared<JSONString>(uuid_str));
+ response->SetObject(
+ "triple",
+ std::make_shared<JSONString>(
+ matched_module_spec.GetArchitecture().GetTriple().getTriple()));
+ response->SetObject("file_path",
+ std::make_shared<JSONString>(
+ matched_module_spec.GetFileSpec().GetPath()));
+ response->SetObject("file_offset",
+ std::make_shared<JSONNumber>(file_offset));
+ response->SetObject("file_size", std::make_shared<JSONNumber>(file_size));
+ }
+
+ StreamString response;
+ response_array_sp->Write(response);
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetString().data(),
+ response.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
+}
- const auto &module_arch = matched_module_spec.GetArchitecture();
+void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
+ const ProcessInstanceInfo &proc_info, StreamString &response) {
+ response.Printf(
+ "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
+ proc_info.GetProcessID(), proc_info.GetParentProcessID(),
+ proc_info.GetUserID(), proc_info.GetGroupID(),
+ proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
+ response.PutCString("name:");
+ response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+ response.PutChar(';');
+ const ArchSpec &proc_arch = proc_info.GetArchitecture();
+ if (proc_arch.IsValid()) {
+ const llvm::Triple &proc_triple = proc_arch.GetTriple();
response.PutCString("triple:");
- response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str());
- response.PutChar(';');
-
- response.PutCString("file_path:");
- response.PutCStringAsRawHex8(module_path_spec.GetCString());
- response.PutChar(';');
- response.PutCString("file_offset:");
- response.PutHex64(file_offset);
+ response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
response.PutChar(';');
- response.PutCString("file_size:");
- response.PutHex64(file_size);
- response.PutChar(';');
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ }
}
-void
-GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
- StreamString &response)
-{
- response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
- proc_info.GetProcessID(),
- proc_info.GetParentProcessID(),
- proc_info.GetUserID(),
- proc_info.GetGroupID(),
- proc_info.GetEffectiveUserID(),
- proc_info.GetEffectiveGroupID());
- response.PutCString ("name:");
- response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+void GDBRemoteCommunicationServerCommon::
+ CreateProcessInfoResponse_DebugServerStyle(
+ const ProcessInstanceInfo &proc_info, StreamString &response) {
+ response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
+ ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
+ proc_info.GetProcessID(), proc_info.GetParentProcessID(),
+ proc_info.GetUserID(), proc_info.GetGroupID(),
+ proc_info.GetEffectiveUserID(),
+ proc_info.GetEffectiveGroupID());
+
+ const ArchSpec &proc_arch = proc_info.GetArchitecture();
+ if (proc_arch.IsValid()) {
+ const llvm::Triple &proc_triple = proc_arch.GetTriple();
+#if defined(__APPLE__)
+ // We'll send cputype/cpusubtype.
+ const uint32_t cpu_type = proc_arch.GetMachOCPUType();
+ if (cpu_type != 0)
+ response.Printf("cputype:%" PRIx32 ";", cpu_type);
+
+ const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
+ if (cpu_subtype != 0)
+ response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
+
+ const std::string vendor = proc_triple.getVendorName();
+ if (!vendor.empty())
+ response.Printf("vendor:%s;", vendor.c_str());
+#else
+ // We'll send the triple.
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
response.PutChar(';');
- const ArchSpec &proc_arch = proc_info.GetArchitecture();
- if (proc_arch.IsValid())
- {
- const llvm::Triple &proc_triple = proc_arch.GetTriple();
- response.PutCString("triple:");
- response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
- response.PutChar(';');
+#endif
+ std::string ostype = proc_triple.getOSName();
+ // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
+ if (proc_triple.getVendor() == llvm::Triple::Apple) {
+ switch (proc_triple.getArch()) {
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ case llvm::Triple::aarch64:
+ ostype = "ios";
+ break;
+ default:
+ // No change.
+ break;
+ }
+ }
+ response.Printf("ostype:%s;", ostype.c_str());
+
+ switch (proc_arch.GetByteOrder()) {
+ case lldb::eByteOrderLittle:
+ response.PutCString("endian:little;");
+ break;
+ case lldb::eByteOrderBig:
+ response.PutCString("endian:big;");
+ break;
+ case lldb::eByteOrderPDP:
+ response.PutCString("endian:pdp;");
+ break;
+ default:
+ // Nothing.
+ break;
}
+ // In case of MIPS64, pointer size is depend on ELF ABI
+ // For N32 the pointer size is 4 and for N64 it is 8
+ std::string abi = proc_arch.GetTargetABI();
+ if (!abi.empty())
+ response.Printf("elf_abi:%s;", abi.c_str());
+ response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
+ }
}
-void
-GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse_DebugServerStyle (
- const ProcessInstanceInfo &proc_info, StreamString &response)
-{
- response.Printf ("pid:%" PRIx64 ";parent-pid:%" PRIx64 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
- proc_info.GetProcessID(),
- proc_info.GetParentProcessID(),
- proc_info.GetUserID(),
- proc_info.GetGroupID(),
- proc_info.GetEffectiveUserID(),
- proc_info.GetEffectiveGroupID());
-
- const ArchSpec &proc_arch = proc_info.GetArchitecture();
- if (proc_arch.IsValid())
- {
- const llvm::Triple &proc_triple = proc_arch.GetTriple();
-#if defined(__APPLE__)
- // We'll send cputype/cpusubtype.
- const uint32_t cpu_type = proc_arch.GetMachOCPUType();
- if (cpu_type != 0)
- response.Printf ("cputype:%" PRIx32 ";", cpu_type);
-
- const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
- if (cpu_subtype != 0)
- response.Printf ("cpusubtype:%" PRIx32 ";", cpu_subtype);
-
- const std::string vendor = proc_triple.getVendorName ();
- if (!vendor.empty ())
- response.Printf ("vendor:%s;", vendor.c_str ());
+FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
+ const std::string &module_path, const ArchSpec &arch) {
+#ifdef __ANDROID__
+ return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
#else
- // We'll send the triple.
- response.PutCString("triple:");
- response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
- response.PutChar(';');
+ return FileSpec(module_path, true);
#endif
- std::string ostype = proc_triple.getOSName ();
- // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
- if (proc_triple.getVendor () == llvm::Triple::Apple)
- {
- switch (proc_triple.getArch ())
- {
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- case llvm::Triple::aarch64:
- ostype = "ios";
- break;
- default:
- // No change.
- break;
- }
- }
- response.Printf ("ostype:%s;", ostype.c_str ());
+}
+ModuleSpec GDBRemoteCommunicationServerCommon::GetModuleInfo(
+ const std::string &module_path, const std::string &triple) {
+ ArchSpec arch(triple.c_str());
- switch (proc_arch.GetByteOrder ())
- {
- case lldb::eByteOrderLittle: response.PutCString ("endian:little;"); break;
- case lldb::eByteOrderBig: response.PutCString ("endian:big;"); break;
- case lldb::eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
- default:
- // Nothing.
- break;
- }
+ const FileSpec req_module_path_spec(module_path, true);
+ const FileSpec module_path_spec =
+ FindModuleFile(req_module_path_spec.GetPath(), arch);
+ const ModuleSpec module_spec(module_path_spec, arch);
- // In case of MIPS64, pointer size is depend on ELF ABI
- // For N32 the pointer size is 4 and for N64 it is 8
- std::string abi = proc_arch.GetTargetABI();
- if (!abi.empty())
- response.Printf("elf_abi:%s;", abi.c_str());
- response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
- }
-}
+ ModuleSpecList module_specs;
+ if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0,
+ module_specs))
+ return ModuleSpec();
-FileSpec
-GDBRemoteCommunicationServerCommon::FindModuleFile(const std::string& module_path,
- const ArchSpec& arch)
-{
-#ifdef __ANDROID__
- return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
-#else
- return FileSpec(module_path.c_str(), true);
-#endif
+ ModuleSpec matched_module_spec;
+ if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+ return ModuleSpec();
+
+ return matched_module_spec;
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index d2fd70042ccc..321a92266bdd 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -16,8 +16,8 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-forward.h"
#include "lldb/Target/Process.h"
+#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationServer.h"
#include "GDBRemoteCommunicationServerCommon.h"
@@ -29,175 +29,132 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class GDBRemoteCommunicationServerCommon :
- public GDBRemoteCommunicationServer
-{
+class GDBRemoteCommunicationServerCommon : public GDBRemoteCommunicationServer {
public:
- GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name);
+ GDBRemoteCommunicationServerCommon(const char *comm_name,
+ const char *listener_name);
- ~GDBRemoteCommunicationServerCommon() override;
+ ~GDBRemoteCommunicationServerCommon() override;
protected:
- ProcessLaunchInfo m_process_launch_info;
- Error m_process_launch_error;
- ProcessInstanceInfoList m_proc_infos;
- uint32_t m_proc_infos_index;
- bool m_thread_suffix_supported;
- bool m_list_threads_in_stop_reply;
+ ProcessLaunchInfo m_process_launch_info;
+ Error m_process_launch_error;
+ ProcessInstanceInfoList m_proc_infos;
+ uint32_t m_proc_infos_index;
+ bool m_thread_suffix_supported;
+ bool m_list_threads_in_stop_reply;
+
+ PacketResult Handle_A(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_A (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qHostInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qHostInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qProcessInfoPID(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qfProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qsProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qUserName(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qUserName (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qGroupName(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qGroupName (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qSpeedTest(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qSpeedTest (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Open(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Open (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Close(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Close (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_pRead(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_pRead (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_pWrite(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Size(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Size (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Mode(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Mode (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Exists(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Exists (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_symlink(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_symlink (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_unlink(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_unlink (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Stat(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Stat (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_MD5(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qEcho(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qEcho (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qModuleInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qModuleInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_jModulesInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qPlatform_shell(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qPlatform_mkdir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qPlatform_chmod(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qSupported (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qSupported(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetDetachOnError (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetDetachOnError(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QStartNoAckMode(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetSTDIN(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetSTDOUT(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetSTDERR(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qLaunchSuccess(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QEnvironment (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QEnvironment(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QEnvironmentHexEncoded(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QLaunchArch (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QLaunchArch(StringExtractorGDBRemote &packet);
- static void
- CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
- StreamString &response);
+ static void CreateProcessInfoResponse(const ProcessInstanceInfo &proc_info,
+ StreamString &response);
- static void
- CreateProcessInfoResponse_DebugServerStyle (const ProcessInstanceInfo &proc_info,
- StreamString &response);
+ static void CreateProcessInfoResponse_DebugServerStyle(
+ const ProcessInstanceInfo &proc_info, StreamString &response);
- template <typename T>
- void
- RegisterMemberFunctionHandler (StringExtractorGDBRemote::ServerPacketType packet_type,
- PacketResult (T::*handler) (StringExtractorGDBRemote& packet))
- {
- RegisterPacketHandler(packet_type,
- [this, handler] (StringExtractorGDBRemote packet,
- Error &error,
- bool &interrupt,
- bool &quit)
- {
- return (static_cast<T*>(this)->*handler) (packet);
- });
- }
+ template <typename T>
+ void RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::ServerPacketType packet_type,
+ PacketResult (T::*handler)(StringExtractorGDBRemote &packet)) {
+ RegisterPacketHandler(packet_type,
+ [this, handler](StringExtractorGDBRemote packet,
+ Error &error, bool &interrupt,
+ bool &quit) {
+ return (static_cast<T *>(this)->*handler)(packet);
+ });
+ }
- bool
- GetThreadSuffixSupported () override
- {
- return true;
- }
+ //------------------------------------------------------------------
+ /// Launch a process with the current launch settings.
+ ///
+ /// This method supports running an lldb-gdbserver or similar
+ /// server in a situation where the startup code has been provided
+ /// with all the information for a child process to be launched.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of the
+ /// launch.
+ //------------------------------------------------------------------
+ virtual Error LaunchProcess() = 0;
- //------------------------------------------------------------------
- /// Launch a process with the current launch settings.
- ///
- /// This method supports running an lldb-gdbserver or similar
- /// server in a situation where the startup code has been provided
- /// with all the information for a child process to be launched.
- ///
- /// @return
- /// An Error object indicating the success or failure of the
- /// launch.
- //------------------------------------------------------------------
- virtual Error
- LaunchProcess () = 0;
+ virtual FileSpec FindModuleFile(const std::string &module_path,
+ const ArchSpec &arch);
- virtual FileSpec
- FindModuleFile (const std::string& module_path, const ArchSpec& arch);
+private:
+ ModuleSpec GetModuleInfo(const std::string &module_path,
+ const std::string &triple);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index c468ba33e858..bf72673f1769 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -16,13 +16,11 @@
// C Includes
// C++ Includes
-#include <cstring>
#include <chrono>
+#include <cstring>
#include <thread>
// Other libraries and framework includes
-#include "llvm/ADT/Triple.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
@@ -36,20 +34,22 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Host/TimeValue.h"
-#include "lldb/Target/FileAction.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Target/FileAction.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ScopedPrinter.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
-#include "Utility/UriParser.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
+#include "Utility/StringExtractorGDBRemote.h"
+#include "Utility/UriParser.h"
using namespace lldb;
using namespace lldb_private;
@@ -60,2934 +60,3110 @@ using namespace llvm;
// GDBRemote Errors
//----------------------------------------------------------------------
-namespace
-{
- enum GDBRemoteServerError
- {
- // Set to the first unused error number in literal form below
- eErrorFirst = 29,
- eErrorNoProcess = eErrorFirst,
- eErrorResume,
- eErrorExitStatus
- };
+namespace {
+enum GDBRemoteServerError {
+ // Set to the first unused error number in literal form below
+ eErrorFirst = 29,
+ eErrorNoProcess = eErrorFirst,
+ eErrorResume,
+ eErrorExitStatus
+};
}
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerLLGS constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(MainLoop &mainloop)
- : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
- m_mainloop(mainloop),
- m_current_tid(LLDB_INVALID_THREAD_ID),
- m_continue_tid(LLDB_INVALID_THREAD_ID),
- m_debugged_process_mutex(),
- m_debugged_process_sp(),
- m_stdio_communication("process.stdio"),
+GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
+ MainLoop &mainloop)
+ : GDBRemoteCommunicationServerCommon("gdb-remote.server",
+ "gdb-remote.server.rx_packet"),
+ m_mainloop(mainloop), m_current_tid(LLDB_INVALID_THREAD_ID),
+ m_continue_tid(LLDB_INVALID_THREAD_ID), m_debugged_process_mutex(),
+ m_debugged_process_sp(), m_stdio_communication("process.stdio"),
m_inferior_prev_state(StateType::eStateInvalid),
- m_active_auxv_buffer_sp(),
- m_saved_registers_mutex(),
- m_saved_registers_map(),
- m_next_saved_registers_id(1),
- m_handshake_completed(false)
-{
- RegisterPacketHandlers();
-}
-
-void
-GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers()
-{
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C,
- &GDBRemoteCommunicationServerLLGS::Handle_C);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c,
- &GDBRemoteCommunicationServerLLGS::Handle_c);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D,
- &GDBRemoteCommunicationServerLLGS::Handle_D);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H,
- &GDBRemoteCommunicationServerLLGS::Handle_H);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I,
- &GDBRemoteCommunicationServerLLGS::Handle_I);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
- &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_m,
- &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
- &GDBRemoteCommunicationServerLLGS::Handle_M);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
- &GDBRemoteCommunicationServerLLGS::Handle_p);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
- &GDBRemoteCommunicationServerLLGS::Handle_P);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
- &GDBRemoteCommunicationServerLLGS::Handle_qC);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
- &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
- &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported,
- &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qRegisterInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState,
- &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState,
- &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR,
- &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
- &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jThreadsInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read,
- &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
- &GDBRemoteCommunicationServerLLGS::Handle_s);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_stop_reason,
- &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ?
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vAttach,
- &GDBRemoteCommunicationServerLLGS::Handle_vAttach);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont,
- &GDBRemoteCommunicationServerLLGS::Handle_vCont);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont_actions,
- &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_x,
- &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
- &GDBRemoteCommunicationServerLLGS::Handle_Z);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
- &GDBRemoteCommunicationServerLLGS::Handle_z);
-
- RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
- [this](StringExtractorGDBRemote packet,
- Error &error,
- bool &interrupt,
- bool &quit)
- {
- quit = true;
- return this->Handle_k (packet);
- });
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetLaunchArguments (const char *const args[], int argc)
-{
- if ((argc < 1) || !args || !args[0] || !args[0][0])
- return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
- m_process_launch_info.SetArguments (const_cast<const char**> (args), true);
- return Error ();
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetLaunchFlags (unsigned int launch_flags)
-{
- m_process_launch_info.GetFlags ().Set (launch_flags);
- return Error ();
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::LaunchProcess ()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
- return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
- Error error;
- {
- std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
- assert (!m_debugged_process_sp && "lldb-gdbserver creating debugged process but one already exists");
- error = NativeProcessProtocol::Launch(
- m_process_launch_info,
- *this,
- m_mainloop,
- m_debugged_process_sp);
- }
-
- if (!error.Success ())
- {
- fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
- return error;
- }
-
- // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
- // as needed.
- // llgs local-process debugging may specify PTY paths, which will make these
- // file actions non-null
- // process launch -i/e/o will also make these file actions non-null
- // nullptr means that the traffic is expected to flow over gdb-remote protocol
- if (
- m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
- m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
- m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr
- )
- {
- // nullptr means it's not redirected to file or pty (in case of LLGS local)
- // at least one of stdio will be transferred pty<->gdb-remote
- // we need to give the pty master handle to this object to read and/or write
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " setting up stdout/stderr redirection via $O gdb-remote commands", __FUNCTION__, m_debugged_process_sp->GetID ());
-
- // Setup stdout/stderr mapping from inferior to $O
- auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
- if (terminal_fd >= 0)
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
- error = SetSTDIOFileDescriptor (terminal_fd);
- if (error.Fail ())
- return error;
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
- }
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " skipping stdout/stderr redirection via $O: inferior will communicate over client-provided file descriptors", __FUNCTION__, m_debugged_process_sp->GetID ());
- }
-
- printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID ());
-
+ m_active_auxv_buffer_sp(), m_saved_registers_mutex(),
+ m_saved_registers_map(), m_next_saved_registers_id(1),
+ m_handshake_completed(false) {
+ RegisterPacketHandlers();
+}
+
+void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C,
+ &GDBRemoteCommunicationServerLLGS::Handle_C);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c,
+ &GDBRemoteCommunicationServerLLGS::Handle_c);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D,
+ &GDBRemoteCommunicationServerLLGS::Handle_D);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H,
+ &GDBRemoteCommunicationServerLLGS::Handle_H);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I,
+ &GDBRemoteCommunicationServerLLGS::Handle_I);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_interrupt,
+ &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_m,
+ &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
+ &GDBRemoteCommunicationServerLLGS::Handle_M);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
+ &GDBRemoteCommunicationServerLLGS::Handle_p);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
+ &GDBRemoteCommunicationServerLLGS::Handle_P);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
+ &GDBRemoteCommunicationServerLLGS::Handle_qC);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
+ &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
+ &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported,
+ &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qRegisterInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState,
+ &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState,
+ &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR,
+ &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
+ &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jThreadsInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read,
+ &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
+ &GDBRemoteCommunicationServerLLGS::Handle_s);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_stop_reason,
+ &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ?
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vAttach,
+ &GDBRemoteCommunicationServerLLGS::Handle_vAttach);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vCont,
+ &GDBRemoteCommunicationServerLLGS::Handle_vCont);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vCont_actions,
+ &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_x,
+ &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
+ &GDBRemoteCommunicationServerLLGS::Handle_Z);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
+ &GDBRemoteCommunicationServerLLGS::Handle_z);
+
+ RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
+ [this](StringExtractorGDBRemote packet, Error &error,
+ bool &interrupt, bool &quit) {
+ quit = true;
+ return this->Handle_k(packet);
+ });
+}
+
+Error GDBRemoteCommunicationServerLLGS::SetLaunchArguments(
+ const char *const args[], int argc) {
+ if ((argc < 1) || !args || !args[0] || !args[0][0])
+ return Error("%s: no process command line specified to launch",
+ __FUNCTION__);
+
+ m_process_launch_info.SetArguments(const_cast<const char **>(args), true);
+ return Error();
+}
+
+Error GDBRemoteCommunicationServerLLGS::SetLaunchFlags(
+ unsigned int launch_flags) {
+ m_process_launch_info.GetFlags().Set(launch_flags);
+ return Error();
+}
+
+Error GDBRemoteCommunicationServerLLGS::LaunchProcess() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!m_process_launch_info.GetArguments().GetArgumentCount())
+ return Error("%s: no process command line specified to launch",
+ __FUNCTION__);
+
+ const bool should_forward_stdio =
+ m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
+ m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
+ m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr;
+ 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);
+
+ Error error;
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
+ assert(!m_debugged_process_sp && "lldb-server creating debugged "
+ "process but one already exists");
+ error = NativeProcessProtocol::Launch(m_process_launch_info, *this,
+ m_mainloop, m_debugged_process_sp);
+ }
+
+ if (!error.Success()) {
+ fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
return error;
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid)
-{
- Error error;
-
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+ }
+
+ // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
+ // as needed.
+ // llgs local-process debugging may specify PTY paths, which will make these
+ // file actions non-null
+ // process launch -i/e/o will also make these file actions non-null
+ // nullptr means that the traffic is expected to flow over gdb-remote protocol
+ if (should_forward_stdio) {
+ // nullptr means it's not redirected to file or pty (in case of LLGS local)
+ // at least one of stdio will be transferred pty<->gdb-remote
+ // we need to give the pty master handle to this object to read and/or write
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, __FUNCTION__, pid);
-
- // Before we try to attach, make sure we aren't already monitoring something else.
- if (m_debugged_process_sp && m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID)
- return Error("cannot attach to a process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", pid, m_debugged_process_sp->GetID());
-
- // Try to attach.
- error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, m_debugged_process_sp);
- if (!error.Success ())
- {
- fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ());
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " setting up stdout/stderr redirection via $O gdb-remote commands",
+ __FUNCTION__, m_debugged_process_sp->GetID());
+
+ // Setup stdout/stderr mapping from inferior to $O
+ auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
+ if (terminal_fd >= 0) {
+ if (log)
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
+ error = SetSTDIOFileDescriptor(terminal_fd);
+ if (error.Fail())
return error;
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
}
-
- // Setup stdout/stderr mapping from inferior.
- auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
- if (terminal_fd >= 0)
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
- error = SetSTDIOFileDescriptor (terminal_fd);
- if (error.Fail ())
- return error;
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
- }
-
- printf ("Attached to process %" PRIu64 "...\n", pid);
-
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " skipping stdout/stderr redirection via $O: inferior will "
+ "communicate over client-provided file descriptors",
+ __FUNCTION__, m_debugged_process_sp->GetID());
+ }
+
+ printf("Launched '%s' as process %" PRIu64 "...\n",
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
+ m_process_launch_info.GetProcessID());
+
+ return error;
+}
+
+Error GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
+ Error error;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
+ __FUNCTION__, pid);
+
+ // Before we try to attach, make sure we aren't already monitoring something
+ // else.
+ if (m_debugged_process_sp &&
+ m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID)
+ return Error("cannot attach to a process %" PRIu64
+ " when another process with pid %" PRIu64
+ " is being debugged.",
+ pid, m_debugged_process_sp->GetID());
+
+ // Try to attach.
+ error = NativeProcessProtocol::Attach(pid, *this, m_mainloop,
+ m_debugged_process_sp);
+ if (!error.Success()) {
+ fprintf(stderr, "%s: failed to attach to process %" PRIu64 ": %s",
+ __FUNCTION__, pid, error.AsCString());
return error;
-}
+ }
-void
-GDBRemoteCommunicationServerLLGS::InitializeDelegate (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ // Setup stdout/stderr mapping from inferior.
+ auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
+ if (terminal_fd >= 0) {
if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", current state: %s",
- __FUNCTION__,
- process->GetID (),
- StateAsCString (process->GetState ()));
- }
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendWResponse (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // send W notification
- ExitType exit_type = ExitType::eExitTypeInvalid;
- int return_code = 0;
- std::string exit_description;
-
- const bool got_exit_info = process->GetExitStatus (&exit_type, &return_code, exit_description);
- if (!got_exit_info)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", failed to retrieve process exit status", __FUNCTION__, process->GetID ());
-
- StreamGDBRemote response;
- response.PutChar ('E');
- response.PutHex8 (GDBRemoteServerError::eErrorExitStatus);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", returning exit type %d, return code %d [%s]", __FUNCTION__, process->GetID (), exit_type, return_code, exit_description.c_str ());
-
- StreamGDBRemote response;
-
- char return_type_code;
- switch (exit_type)
- {
- case ExitType::eExitTypeExit:
- return_type_code = 'W';
- break;
- case ExitType::eExitTypeSignal:
- return_type_code = 'X';
- break;
- case ExitType::eExitTypeStop:
- return_type_code = 'S';
- break;
- case ExitType::eExitTypeInvalid:
- return_type_code = 'E';
- break;
- }
- response.PutChar (return_type_code);
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
+ error = SetSTDIOFileDescriptor(terminal_fd);
+ if (error.Fail())
+ return error;
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
+ }
- // POSIX exit status limited to unsigned 8 bits.
- response.PutHex8 (return_code);
+ printf("Attached to process %" PRIu64 "...\n", pid);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+ return error;
}
-static void
-AppendHexValue (StreamString &response, const uint8_t* buf, uint32_t buf_size, bool swap)
-{
- int64_t i;
- if (swap)
- {
- for (i = buf_size-1; i >= 0; i--)
- response.PutHex8 (buf[i]);
- }
- else
- {
- for (i = 0; i < buf_size; i++)
- response.PutHex8 (buf[i]);
- }
+void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
+ __FUNCTION__, process->GetID(),
+ StateAsCString(process->GetState()));
+ }
}
-static void
-WriteRegisterValueInHexFixedWidth (StreamString &response,
- NativeRegisterContextSP &reg_ctx_sp,
- const RegisterInfo &reg_info,
- const RegisterValue *reg_value_p)
-{
- RegisterValue reg_value;
- if (!reg_value_p)
- {
- Error error = reg_ctx_sp->ReadRegister (&reg_info, reg_value);
- if (error.Success ())
- reg_value_p = &reg_value;
- // else log.
- }
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendWResponse(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // send W notification
+ ExitType exit_type = ExitType::eExitTypeInvalid;
+ int return_code = 0;
+ std::string exit_description;
+
+ const bool got_exit_info =
+ process->GetExitStatus(&exit_type, &return_code, exit_description);
+ if (!got_exit_info) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ ", failed to retrieve process exit status",
+ __FUNCTION__, process->GetID());
- if (reg_value_p)
- {
- AppendHexValue (response, (const uint8_t*) reg_value_p->GetBytes (), reg_value_p->GetByteSize (), false);
- }
- else
- {
- // Zero-out any unreadable values.
- if (reg_info.byte_size > 0)
- {
- std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
- AppendHexValue (response, zeros.data(), zeros.size(), false);
- }
- }
-}
+ StreamGDBRemote response;
+ response.PutChar('E');
+ response.PutHex8(GDBRemoteServerError::eErrorExitStatus);
+ return SendPacketNoLock(response.GetString());
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ ", returning exit type %d, return code %d [%s]",
+ __FUNCTION__, process->GetID(), exit_type, return_code,
+ exit_description.c_str());
-static JSONObject::SP
-GetRegistersAsJSON(NativeThreadProtocol &thread, bool abridged)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
+ StreamGDBRemote response;
- NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext ();
- if (! reg_ctx_sp)
- return nullptr;
+ char return_type_code;
+ switch (exit_type) {
+ case ExitType::eExitTypeExit:
+ return_type_code = 'W';
+ break;
+ case ExitType::eExitTypeSignal:
+ return_type_code = 'X';
+ break;
+ case ExitType::eExitTypeStop:
+ return_type_code = 'S';
+ break;
+ case ExitType::eExitTypeInvalid:
+ return_type_code = 'E';
+ break;
+ }
+ response.PutChar(return_type_code);
+
+ // POSIX exit status limited to unsigned 8 bits.
+ response.PutHex8(return_code);
+
+ return SendPacketNoLock(response.GetString());
+ }
+}
+
+static void AppendHexValue(StreamString &response, const uint8_t *buf,
+ uint32_t buf_size, bool swap) {
+ int64_t i;
+ if (swap) {
+ for (i = buf_size - 1; i >= 0; i--)
+ response.PutHex8(buf[i]);
+ } else {
+ for (i = 0; i < buf_size; i++)
+ response.PutHex8(buf[i]);
+ }
+}
+
+static void WriteRegisterValueInHexFixedWidth(
+ StreamString &response, NativeRegisterContextSP &reg_ctx_sp,
+ const RegisterInfo &reg_info, const RegisterValue *reg_value_p) {
+ RegisterValue reg_value;
+ if (!reg_value_p) {
+ Error error = reg_ctx_sp->ReadRegister(&reg_info, reg_value);
+ if (error.Success())
+ reg_value_p = &reg_value;
+ // else log.
+ }
+
+ if (reg_value_p) {
+ AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(),
+ reg_value_p->GetByteSize(), false);
+ } else {
+ // Zero-out any unreadable values.
+ if (reg_info.byte_size > 0) {
+ std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
+ AppendHexValue(response, zeros.data(), zeros.size(), false);
+ }
+ }
+}
+
+static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread,
+ bool abridged) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
+ return nullptr;
- JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
+ JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
- // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers.
- const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
- if (! reg_set_p)
- return nullptr;
- for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p)
- {
- uint32_t reg_num = *reg_num_p;
+ // Expedite all registers in the first register set (i.e. should be GPRs) that
+ // are not contained in other registers.
+ const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
+ if (!reg_set_p)
+ return nullptr;
+ for (const uint32_t *reg_num_p = reg_set_p->registers;
+ *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+ uint32_t reg_num = *reg_num_p;
#else
- // Expedite only a couple of registers until we figure out why sending registers is
- // expensive.
- static const uint32_t k_expedited_registers[] = {
- LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM
- };
- static const uint32_t k_abridged_expedited_registers[] = {
- LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM
- };
-
- for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers : k_expedited_registers;
- *generic_reg_p != LLDB_INVALID_REGNUM;
- ++generic_reg_p)
- {
- uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, *generic_reg_p);
- if (reg_num == LLDB_INVALID_REGNUM)
- continue; // Target does not support the given register.
+ // Expedite only a couple of registers until we figure out why sending
+ // registers is
+ // expensive.
+ static const uint32_t k_expedited_registers[] = {
+ LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP,
+ LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM};
+ static const uint32_t k_abridged_expedited_registers[] = {
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM};
+
+ for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers
+ : k_expedited_registers;
+ *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) {
+ uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, *generic_reg_p);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ continue; // Target does not support the given register.
#endif
- const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
- if (reg_info_p == nullptr)
- {
- if (log)
- log->Printf("%s failed to get register info for register index %" PRIu32,
- __FUNCTION__, reg_num);
- continue;
- }
-
- if (reg_info_p->value_regs != nullptr)
- continue; // Only expedite registers that are not contained in other registers.
-
- RegisterValue reg_value;
- Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
- if (error.Fail())
- {
- if (log)
- log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__,
- reg_info_p->name ? reg_info_p->name : "<unnamed-register>", reg_num,
- error.AsCString ());
- continue;
- }
-
- StreamString stream;
- WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p, &reg_value);
-
- register_object_sp->SetObject(std::to_string(reg_num),
- std::make_shared<JSONString>(stream.GetString()));
- }
-
- return register_object_sp;
-}
-
-static const char *
-GetStopReasonString(StopReason stop_reason)
-{
- switch (stop_reason)
- {
- case eStopReasonTrace:
- return "trace";
- case eStopReasonBreakpoint:
- return "breakpoint";
- case eStopReasonWatchpoint:
- return "watchpoint";
- case eStopReasonSignal:
- return "signal";
- case eStopReasonException:
- return "exception";
- case eStopReasonExec:
- return "exec";
- case eStopReasonInstrumentation:
- case eStopReasonInvalid:
- case eStopReasonPlanComplete:
- case eStopReasonThreadExiting:
- case eStopReasonNone:
- break; // ignored
+ const RegisterInfo *const reg_info_p =
+ reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+ if (reg_info_p == nullptr) {
+ if (log)
+ log->Printf(
+ "%s failed to get register info for register index %" PRIu32,
+ __FUNCTION__, reg_num);
+ continue;
}
- return nullptr;
-}
-static JSONArray::SP
-GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (reg_info_p->value_regs != nullptr)
+ continue; // Only expedite registers that are not contained in other
+ // registers.
- JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
-
- // Ensure we can get info on the given thread.
- uint32_t thread_idx = 0;
- for ( NativeThreadProtocolSP thread_sp;
- (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
- ++thread_idx)
- {
-
- lldb::tid_t tid = thread_sp->GetID();
-
- // Grab the reason this thread stopped.
- struct ThreadStopInfo tid_stop_info;
- std::string description;
- if (!thread_sp->GetStopReason (tid_stop_info, description))
- return nullptr;
-
- const int signum = tid_stop_info.details.signal.signo;
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ RegisterValue reg_value;
+ Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
__FUNCTION__,
- process.GetID (),
- tid,
- signum,
- tid_stop_info.reason,
- tid_stop_info.details.exception.type);
- }
-
- JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
- threads_array_sp->AppendObject(thread_obj_sp);
-
- if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged))
- thread_obj_sp->SetObject("registers", registers_sp);
-
- thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
- if (signum != 0)
- thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ reg_num, error.AsCString());
+ continue;
+ }
+
+ StreamString stream;
+ WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p,
+ &reg_value);
+
+ register_object_sp->SetObject(
+ llvm::to_string(reg_num),
+ std::make_shared<JSONString>(stream.GetString()));
+ }
+
+ return register_object_sp;
+}
+
+static const char *GetStopReasonString(StopReason stop_reason) {
+ switch (stop_reason) {
+ case eStopReasonTrace:
+ return "trace";
+ case eStopReasonBreakpoint:
+ return "breakpoint";
+ case eStopReasonWatchpoint:
+ return "watchpoint";
+ case eStopReasonSignal:
+ return "signal";
+ case eStopReasonException:
+ return "exception";
+ case eStopReasonExec:
+ return "exec";
+ case eStopReasonInstrumentation:
+ case eStopReasonInvalid:
+ case eStopReasonPlanComplete:
+ case eStopReasonThreadExiting:
+ case eStopReasonNone:
+ break; // ignored
+ }
+ return nullptr;
+}
+
+static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
+ bool abridged) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+ JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
+
+ // Ensure we can get info on the given thread.
+ uint32_t thread_idx = 0;
+ for (NativeThreadProtocolSP thread_sp;
+ (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
+ ++thread_idx) {
+
+ lldb::tid_t tid = thread_sp->GetID();
- const std::string thread_name = thread_sp->GetName ();
- if (! thread_name.empty())
- thread_obj_sp->SetObject("name", std::make_shared<JSONString>(thread_name));
-
- if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
- thread_obj_sp->SetObject("reason", std::make_shared<JSONString>(stop_reason_str));
-
- if (! description.empty())
- thread_obj_sp->SetObject("description", std::make_shared<JSONString>(description));
-
- if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
- {
- thread_obj_sp->SetObject("metype",
- std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
-
- JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
- for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
- {
- medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
- tid_stop_info.details.exception.data[i]));
- }
- thread_obj_sp->SetObject("medata", medata_array_sp);
- }
+ // Grab the reason this thread stopped.
+ struct ThreadStopInfo tid_stop_info;
+ std::string description;
+ if (!thread_sp->GetStopReason(tid_stop_info, description))
+ return nullptr;
- // TODO: Expedite interesting regions of inferior memory
+ const int signum = tid_stop_info.details.signal.signo;
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64
+ " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ __FUNCTION__, process.GetID(), tid, signum,
+ tid_stop_info.reason, tid_stop_info.details.exception.type);
}
- return threads_array_sp;
-}
+ JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
+ threads_array_sp->AppendObject(thread_obj_sp);
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread (lldb::tid_t tid)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged))
+ thread_obj_sp->SetObject("registers", registers_sp);
- // Ensure we have a debugged process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (50);
+ thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
+ if (signum != 0)
+ thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, m_debugged_process_sp->GetID (), tid);
+ const std::string thread_name = thread_sp->GetName();
+ if (!thread_name.empty())
+ thread_obj_sp->SetObject("name",
+ std::make_shared<JSONString>(thread_name));
- // Ensure we can get info on the given thread.
- NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid));
- if (!thread_sp)
- return SendErrorResponse (51);
+ if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
+ thread_obj_sp->SetObject("reason",
+ std::make_shared<JSONString>(stop_reason_str));
- // Grab the reason this thread stopped.
- struct ThreadStopInfo tid_stop_info;
- std::string description;
- if (!thread_sp->GetStopReason (tid_stop_info, description))
- return SendErrorResponse (52);
+ if (!description.empty())
+ thread_obj_sp->SetObject("description",
+ std::make_shared<JSONString>(description));
- // FIXME implement register handling for exec'd inferiors.
- // if (tid_stop_info.reason == eStopReasonExec)
- // {
- // const bool force = true;
- // InitializeRegisters(force);
- // }
+ if ((tid_stop_info.reason == eStopReasonException) &&
+ tid_stop_info.details.exception.type) {
+ thread_obj_sp->SetObject(
+ "metype",
+ std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
- StreamString response;
- // Output the T packet with the thread
- response.PutChar ('T');
- int signum = tid_stop_info.details.signal.signo;
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- tid,
- signum,
- tid_stop_info.reason,
- tid_stop_info.details.exception.type);
+ JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
+ for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count;
+ ++i) {
+ medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
+ tid_stop_info.details.exception.data[i]));
+ }
+ thread_obj_sp->SetObject("medata", medata_array_sp);
}
- // Print the signal number.
- response.PutHex8 (signum & 0xff);
-
- // Include the tid.
- response.Printf ("thread:%" PRIx64 ";", tid);
-
- // Include the thread name if there is one.
- const std::string thread_name = thread_sp->GetName ();
- if (!thread_name.empty ())
- {
- size_t thread_name_len = thread_name.length ();
+ // TODO: Expedite interesting regions of inferior memory
+ }
- if (::strcspn (thread_name.c_str (), "$#+-;:") == thread_name_len)
- {
- response.PutCString ("name:");
- response.PutCString (thread_name.c_str ());
- }
- else
- {
- // The thread name contains special chars, send as hex bytes.
- response.PutCString ("hexname:");
- response.PutCStringAsRawHex8 (thread_name.c_str ());
- }
- response.PutChar (';');
- }
-
- // If a 'QListThreadsInStopReply' was sent to enable this feature, we
- // will send all thread IDs back in the "threads" key whose value is
- // a list of hex thread IDs separated by commas:
- // "threads:10a,10b,10c;"
- // This will save the debugger from having to send a pair of qfThreadInfo
- // and qsThreadInfo packets, but it also might take a lot of room in the
- // stop reply packet, so it must be enabled only on systems where there
- // are no limits on packet lengths.
- if (m_list_threads_in_stop_reply)
- {
- response.PutCString ("threads:");
-
- uint32_t thread_index = 0;
- NativeThreadProtocolSP listed_thread_sp;
- for (listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index); listed_thread_sp; ++thread_index, listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index))
- {
- if (thread_index > 0)
- response.PutChar (',');
- response.Printf ("%" PRIx64, listed_thread_sp->GetID ());
- }
- response.PutChar (';');
-
- // Include JSON info that describes the stop reason for any threads
- // that actually have stop reasons. We use the new "jstopinfo" key
- // whose values is hex ascii JSON that contains the thread IDs
- // thread stop info only for threads that have stop reasons. Only send
- // this if we have more than one thread otherwise this packet has all
- // the info it needs.
- if (thread_index > 0)
- {
- const bool threads_with_valid_stop_info_only = true;
- JSONArray::SP threads_info_sp = GetJSONThreadsInfo(*m_debugged_process_sp,
- threads_with_valid_stop_info_only);
- if (threads_info_sp)
- {
- response.PutCString("jstopinfo:");
- StreamString unescaped_response;
- threads_info_sp->Write(unescaped_response);
- response.PutCStringAsRawHex8(unescaped_response.GetData());
- response.PutChar(';');
- }
- else if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a jstopinfo field for pid %" PRIu64,
- __FUNCTION__, m_debugged_process_sp->GetID());
+ return threads_array_sp;
+}
- }
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
+ lldb::tid_t tid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+ // Ensure we have a debugged process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(50);
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64
+ " tid %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID(), tid);
+
+ // Ensure we can get info on the given thread.
+ NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid));
+ if (!thread_sp)
+ return SendErrorResponse(51);
+
+ // Grab the reason this thread stopped.
+ struct ThreadStopInfo tid_stop_info;
+ std::string description;
+ if (!thread_sp->GetStopReason(tid_stop_info, description))
+ return SendErrorResponse(52);
+
+ // FIXME implement register handling for exec'd inferiors.
+ // if (tid_stop_info.reason == eStopReasonExec)
+ // {
+ // const bool force = true;
+ // InitializeRegisters(force);
+ // }
+
+ StreamString response;
+ // Output the T packet with the thread
+ response.PutChar('T');
+ int signum = tid_stop_info.details.signal.signo;
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64
+ " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID(), tid, signum,
+ tid_stop_info.reason, tid_stop_info.details.exception.type);
+ }
+
+ // Print the signal number.
+ response.PutHex8(signum & 0xff);
+
+ // Include the tid.
+ response.Printf("thread:%" PRIx64 ";", tid);
+
+ // Include the thread name if there is one.
+ const std::string thread_name = thread_sp->GetName();
+ if (!thread_name.empty()) {
+ size_t thread_name_len = thread_name.length();
+
+ if (::strcspn(thread_name.c_str(), "$#+-;:") == thread_name_len) {
+ response.PutCString("name:");
+ response.PutCString(thread_name);
+ } else {
+ // The thread name contains special chars, send as hex bytes.
+ response.PutCString("hexname:");
+ response.PutCStringAsRawHex8(thread_name.c_str());
+ }
+ response.PutChar(';');
+ }
+
+ // If a 'QListThreadsInStopReply' was sent to enable this feature, we
+ // will send all thread IDs back in the "threads" key whose value is
+ // a list of hex thread IDs separated by commas:
+ // "threads:10a,10b,10c;"
+ // This will save the debugger from having to send a pair of qfThreadInfo
+ // and qsThreadInfo packets, but it also might take a lot of room in the
+ // stop reply packet, so it must be enabled only on systems where there
+ // are no limits on packet lengths.
+ if (m_list_threads_in_stop_reply) {
+ response.PutCString("threads:");
+
+ uint32_t thread_index = 0;
+ NativeThreadProtocolSP listed_thread_sp;
+ for (listed_thread_sp =
+ m_debugged_process_sp->GetThreadAtIndex(thread_index);
+ listed_thread_sp; ++thread_index,
+ listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex(
+ thread_index)) {
+ if (thread_index > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx64, listed_thread_sp->GetID());
+ }
+ response.PutChar(';');
+
+ // Include JSON info that describes the stop reason for any threads
+ // that actually have stop reasons. We use the new "jstopinfo" key
+ // whose values is hex ascii JSON that contains the thread IDs
+ // thread stop info only for threads that have stop reasons. Only send
+ // this if we have more than one thread otherwise this packet has all
+ // the info it needs.
+ if (thread_index > 0) {
+ const bool threads_with_valid_stop_info_only = true;
+ JSONArray::SP threads_info_sp = GetJSONThreadsInfo(
+ *m_debugged_process_sp, threads_with_valid_stop_info_only);
+ if (threads_info_sp) {
+ response.PutCString("jstopinfo:");
+ StreamString unescaped_response;
+ threads_info_sp->Write(unescaped_response);
+ response.PutCStringAsRawHex8(unescaped_response.GetData());
+ response.PutChar(';');
+ } else if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a "
+ "jstopinfo field for pid %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
}
-
- //
- // Expedite registers.
- //
-
- // Grab the register context.
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext ();
- if (reg_ctx_sp)
- {
- // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers.
- const RegisterSet *reg_set_p;
- if (reg_ctx_sp->GetRegisterSetCount () > 0 && ((reg_set_p = reg_ctx_sp->GetRegisterSet (0)) != nullptr))
- {
+ }
+
+ //
+ // Expedite registers.
+ //
+
+ // Grab the register context.
+ NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+ if (reg_ctx_sp) {
+ // Expedite all registers in the first register set (i.e. should be GPRs)
+ // that are not contained in other registers.
+ const RegisterSet *reg_set_p;
+ if (reg_ctx_sp->GetRegisterSetCount() > 0 &&
+ ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
+ "from set '%s' (registers set count: %zu)",
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ reg_set_p->num_registers);
+
+ for (const uint32_t *reg_num_p = reg_set_p->registers;
+ *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+ const RegisterInfo *const reg_info_p =
+ reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p);
+ if (reg_info_p == nullptr) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
+ "register info for register set '%s', register index "
+ "%" PRIu32,
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ *reg_num_p);
+ } else if (reg_info_p->value_regs == nullptr) {
+ // Only expediate registers that are not contained in other registers.
+ RegisterValue reg_value;
+ Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ if (error.Success()) {
+ response.Printf("%.02x:", *reg_num_p);
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
+ &reg_value);
+ response.PutChar(';');
+ } else {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s expediting registers from set '%s' (registers set count: %zu)", __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", reg_set_p->num_registers);
-
- for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p)
- {
- const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex (*reg_num_p);
- if (reg_info_p == nullptr)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get register info for register set '%s', register index %" PRIu32, __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", *reg_num_p);
- }
- else if (reg_info_p->value_regs == nullptr)
- {
- // Only expediate registers that are not contained in other registers.
- RegisterValue reg_value;
- Error error = reg_ctx_sp->ReadRegister (reg_info_p, reg_value);
- if (error.Success ())
- {
- response.Printf ("%.02x:", *reg_num_p);
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, &reg_value);
- response.PutChar (';');
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__, reg_info_p->name ? reg_info_p->name : "<unnamed-register>", *reg_num_p, error.AsCString ());
-
- }
- }
- }
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__, reg_info_p->name ? reg_info_p->name
+ : "<unnamed-register>",
+ *reg_num_p, error.AsCString());
+ }
}
+ }
}
+ }
- const char* reason_str = GetStopReasonString(tid_stop_info.reason);
- if (reason_str != nullptr)
- {
- response.Printf ("reason:%s;", reason_str);
- }
+ const char *reason_str = GetStopReasonString(tid_stop_info.reason);
+ if (reason_str != nullptr) {
+ response.Printf("reason:%s;", reason_str);
+ }
- if (!description.empty())
- {
- // Description may contains special chars, send as hex bytes.
- response.PutCString ("description:");
- response.PutCStringAsRawHex8 (description.c_str ());
- response.PutChar (';');
- }
- else if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
- {
- response.PutCString ("metype:");
- response.PutHex64 (tid_stop_info.details.exception.type);
- response.PutCString (";mecount:");
- response.PutHex32 (tid_stop_info.details.exception.data_count);
- response.PutChar (';');
-
- for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
- {
- response.PutCString ("medata:");
- response.PutHex64 (tid_stop_info.details.exception.data[i]);
- response.PutChar (';');
- }
+ if (!description.empty()) {
+ // Description may contains special chars, send as hex bytes.
+ response.PutCString("description:");
+ response.PutCStringAsRawHex8(description.c_str());
+ response.PutChar(';');
+ } else if ((tid_stop_info.reason == eStopReasonException) &&
+ tid_stop_info.details.exception.type) {
+ response.PutCString("metype:");
+ response.PutHex64(tid_stop_info.details.exception.type);
+ response.PutCString(";mecount:");
+ response.PutHex32(tid_stop_info.details.exception.data_count);
+ response.PutChar(';');
+
+ for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) {
+ response.PutCString("medata:");
+ response.PutHex64(tid_stop_info.details.exception.data[i]);
+ response.PutChar(';');
}
+ }
- return SendPacketNoLock (response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
-void
-GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- PacketResult result = SendStopReasonForState(StateType::eStateExited);
- if (result != PacketResult::Success)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
- }
+void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
- // Close the pipe to the inferior terminal i/o if we launched it
- // and set one up.
- MaybeCloseInferiorTerminalConnection ();
-
- // We are ready to exit the debug monitor.
- m_exit_now = true;
-}
-
-void
-GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- // Send the stop reason unless this is the stop after the
- // launch or attach.
- switch (m_inferior_prev_state)
- {
- case eStateLaunching:
- case eStateAttaching:
- // Don't send anything per debugserver behavior.
- break;
- default:
- // In all other cases, send the stop reason.
- PacketResult result = SendStopReasonForState(StateType::eStateStopped);
- if (result != PacketResult::Success)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
- }
- break;
- }
-}
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-void
-GDBRemoteCommunicationServerLLGS::ProcessStateChanged (NativeProcessProtocol *process, lldb::StateType state)
-{
- assert (process && "process cannot be NULL");
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ PacketResult result = SendStopReasonForState(StateType::eStateExited);
+ if (result != PacketResult::Success) {
if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", state: %s",
- __FUNCTION__,
- process->GetID (),
- StateAsCString (state));
- }
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
+ }
+
+ // Close the pipe to the inferior terminal i/o if we launched it
+ // and set one up.
+ MaybeCloseInferiorTerminalConnection();
+
+ // We are ready to exit the debug monitor.
+ m_exit_now = true;
+}
+
+void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+
+ // Send the stop reason unless this is the stop after the
+ // launch or attach.
+ switch (m_inferior_prev_state) {
+ case eStateLaunching:
+ case eStateAttaching:
+ // Don't send anything per debugserver behavior.
+ break;
+ default:
+ // In all other cases, send the stop reason.
+ PacketResult result = SendStopReasonForState(StateType::eStateStopped);
+ if (result != PacketResult::Success) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
+ }
+ break;
+ }
+}
+
+void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
+ NativeProcessProtocol *process, lldb::StateType state) {
+ assert(process && "process cannot be NULL");
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
+ }
+
+ switch (state) {
+ case StateType::eStateRunning:
+ StartSTDIOForwarding();
+ break;
+
+ case StateType::eStateStopped:
+ // Make sure we get all of the pending stdout/stderr from the inferior
+ // and send it to the lldb host before we send the state change
+ // notification
+ SendProcessOutput();
+ // Then stop the forwarding, so that any late output (see llvm.org/pr25652)
+ // does not
+ // interfere with our protocol.
+ StopSTDIOForwarding();
+ HandleInferiorState_Stopped(process);
+ break;
- switch (state)
- {
- case StateType::eStateRunning:
- StartSTDIOForwarding();
- break;
-
- case StateType::eStateStopped:
- // Make sure we get all of the pending stdout/stderr from the inferior
- // and send it to the lldb host before we send the state change
- // notification
- SendProcessOutput();
- // Then stop the forwarding, so that any late output (see llvm.org/pr25652) does not
- // interfere with our protocol.
- StopSTDIOForwarding();
- HandleInferiorState_Stopped (process);
- break;
-
- case StateType::eStateExited:
- // Same as above
- SendProcessOutput();
- StopSTDIOForwarding();
- HandleInferiorState_Exited (process);
- break;
+ case StateType::eStateExited:
+ // Same as above
+ SendProcessOutput();
+ StopSTDIOForwarding();
+ HandleInferiorState_Exited(process);
+ break;
- default:
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s didn't handle state change for pid %" PRIu64 ", new state: %s",
- __FUNCTION__,
- process->GetID (),
- StateAsCString (state));
- }
- break;
+ default:
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state "
+ "change for pid %" PRIu64 ", new state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
}
+ break;
+ }
- // Remember the previous state reported to us.
- m_inferior_prev_state = state;
+ // Remember the previous state reported to us.
+ m_inferior_prev_state = state;
}
-void
-GDBRemoteCommunicationServerLLGS::DidExec (NativeProcessProtocol *process)
-{
- ClearProcessSpecificData ();
+void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) {
+ ClearProcessSpecificData();
}
-void
-GDBRemoteCommunicationServerLLGS::DataAvailableCallback ()
-{
- Log *log (GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
+void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
+ Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
- if (! m_handshake_completed)
- {
- if (! HandshakeWithClient())
- {
- if(log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with client failed, exiting",
- __FUNCTION__);
- m_mainloop.RequestTermination();
- return;
- }
- m_handshake_completed = true;
+ if (!m_handshake_completed) {
+ if (!HandshakeWithClient()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with "
+ "client failed, exiting",
+ __FUNCTION__);
+ m_mainloop.RequestTermination();
+ return;
}
+ m_handshake_completed = true;
+ }
- bool interrupt = false;
- bool done = false;
- Error error;
- while (true)
- {
- const PacketResult result = GetPacketAndSendResponse (0, error, interrupt, done);
- if (result == PacketResult::ErrorReplyTimeout)
- break; // No more packets in the queue
-
- if ((result != PacketResult::Success))
- {
- if(log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s",
- __FUNCTION__, error.AsCString());
- m_mainloop.RequestTermination();
- break;
- }
+ bool interrupt = false;
+ bool done = false;
+ Error error;
+ while (true) {
+ const PacketResult result = GetPacketAndSendResponse(
+ std::chrono::microseconds(0), error, interrupt, done);
+ if (result == PacketResult::ErrorReplyTimeout)
+ break; // No more packets in the queue
+
+ if ((result != PacketResult::Success)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
+ m_mainloop.RequestTermination();
+ break;
}
+ }
}
-Error
-GDBRemoteCommunicationServerLLGS::InitializeConnection (std::unique_ptr<Connection> &&connection)
-{
- IOObjectSP read_object_sp = connection->GetReadObject();
- GDBRemoteCommunicationServer::SetConnection(connection.release());
+Error GDBRemoteCommunicationServerLLGS::InitializeConnection(
+ std::unique_ptr<Connection> &&connection) {
+ IOObjectSP read_object_sp = connection->GetReadObject();
+ GDBRemoteCommunicationServer::SetConnection(connection.release());
- Error error;
- m_network_handle_up = m_mainloop.RegisterReadObject(read_object_sp,
- [this] (MainLoopBase &) { DataAvailableCallback(); }, error);
- return error;
+ Error error;
+ m_network_handle_up = m_mainloop.RegisterReadObject(
+ read_object_sp, [this](MainLoopBase &) { DataAvailableCallback(); },
+ error);
+ return error;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendONotification (const char *buffer, uint32_t len)
-{
- if ((buffer == nullptr) || (len == 0))
- {
- // Nothing to send.
- return PacketResult::Success;
- }
-
- StreamString response;
- response.PutChar ('O');
- response.PutBytesAsRawHex8 (buffer, len);
-
- return SendPacketNoLock (response.GetData (), response.GetSize ());
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor (int fd)
-{
- Error error;
-
- // Set up the reading/handling of process I/O
- std::unique_ptr<ConnectionFileDescriptor> conn_up (new ConnectionFileDescriptor (fd, true));
- if (!conn_up)
- {
- error.SetErrorString ("failed to create ConnectionFileDescriptor");
- return error;
- }
+GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer,
+ uint32_t len) {
+ if ((buffer == nullptr) || (len == 0)) {
+ // Nothing to send.
+ return PacketResult::Success;
+ }
- m_stdio_communication.SetCloseOnEOF (false);
- m_stdio_communication.SetConnection (conn_up.release());
- if (!m_stdio_communication.IsConnected ())
- {
- error.SetErrorString ("failed to set connection for inferior I/O communication");
- return error;
- }
+ StreamString response;
+ response.PutChar('O');
+ response.PutBytesAsRawHex8(buffer, len);
- return Error();
+ return SendPacketNoLock(response.GetString());
}
-void
-GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding()
-{
- // Don't forward if not connected (e.g. when attaching).
- if (! m_stdio_communication.IsConnected())
- return;
-
- // llgs local-process debugging may specify PTY paths, which will make these
- // file actions non-null
- // process launch -e/o will also make these file actions non-null
- // nullptr means that the traffic is expected to flow over gdb-remote protocol
- if ( m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) &&
- m_process_launch_info.GetFileActionForFD(STDERR_FILENO))
- return;
-
- Error error;
- lldbassert(! m_stdio_handle_up);
- m_stdio_handle_up = m_mainloop.RegisterReadObject(
- m_stdio_communication.GetConnection()->GetReadObject(),
- [this] (MainLoopBase &) { SendProcessOutput(); }, error);
-
- if (! m_stdio_handle_up)
- {
- // Not much we can do about the failure. Log it and continue without forwarding.
- if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio forwarding: %s",
- __FUNCTION__, error.AsCString());
- }
-}
+Error GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) {
+ Error error;
-void
-GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding()
-{
- m_stdio_handle_up.reset();
-}
+ // Set up the reading/handling of process I/O
+ std::unique_ptr<ConnectionFileDescriptor> conn_up(
+ new ConnectionFileDescriptor(fd, true));
+ if (!conn_up) {
+ error.SetErrorString("failed to create ConnectionFileDescriptor");
+ return error;
+ }
-void
-GDBRemoteCommunicationServerLLGS::SendProcessOutput()
-{
- char buffer[1024];
- ConnectionStatus status;
- Error error;
- while (true)
- {
- size_t bytes_read = m_stdio_communication.Read(buffer, sizeof buffer, 0, status, &error);
- switch (status)
- {
- case eConnectionStatusSuccess:
- SendONotification(buffer, bytes_read);
- break;
- case eConnectionStatusLostConnection:
- case eConnectionStatusEndOfFile:
- case eConnectionStatusError:
- case eConnectionStatusNoConnection:
- if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio forwarding as communication returned status %d (error: %s)", __FUNCTION__, status, error.AsCString());
- m_stdio_handle_up.reset();
- return;
-
- case eConnectionStatusInterrupted:
- case eConnectionStatusTimedOut:
- return;
- }
- }
+ m_stdio_communication.SetCloseOnEOF(false);
+ m_stdio_communication.SetConnection(conn_up.release());
+ if (!m_stdio_communication.IsConnected()) {
+ error.SetErrorString(
+ "failed to set connection for inferior I/O communication");
+ return error;
+ }
+
+ return Error();
+}
+
+void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
+ // Don't forward if not connected (e.g. when attaching).
+ if (!m_stdio_communication.IsConnected())
+ return;
+
+ Error error;
+ lldbassert(!m_stdio_handle_up);
+ m_stdio_handle_up = m_mainloop.RegisterReadObject(
+ m_stdio_communication.GetConnection()->GetReadObject(),
+ [this](MainLoopBase &) { SendProcessOutput(); }, error);
+
+ if (!m_stdio_handle_up) {
+ // Not much we can do about the failure. Log it and continue without
+ // forwarding.
+ if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
+ "forwarding: %s",
+ __FUNCTION__, error.AsCString());
+ }
+}
+
+void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() {
+ m_stdio_handle_up.reset();
+}
+
+void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
+ char buffer[1024];
+ ConnectionStatus status;
+ Error error;
+ while (true) {
+ size_t bytes_read = m_stdio_communication.Read(
+ buffer, sizeof buffer, std::chrono::microseconds(0), status, &error);
+ switch (status) {
+ case eConnectionStatusSuccess:
+ SendONotification(buffer, bytes_read);
+ break;
+ case eConnectionStatusLostConnection:
+ case eConnectionStatusEndOfFile:
+ case eConnectionStatusError:
+ case eConnectionStatusNoConnection:
+ if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
+ "forwarding as communication returned status %d (error: "
+ "%s)",
+ __FUNCTION__, status, error.AsCString());
+ m_stdio_handle_up.reset();
+ return;
+
+ case eConnectionStatusInterrupted:
+ case eConnectionStatusTimedOut:
+ return;
+ }
+ }
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
+GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
- lldb::pid_t pid = m_debugged_process_sp->GetID ();
+ lldb::pid_t pid = m_debugged_process_sp->GetID();
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse (1);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(1);
- ProcessInstanceInfo proc_info;
- if (!Host::GetProcessInfo (pid, proc_info))
- return SendErrorResponse (1);
+ ProcessInstanceInfo proc_info;
+ if (!Host::GetProcessInfo(pid, proc_info))
+ return SendErrorResponse(1);
- StreamString response;
- CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ StreamString response;
+ CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qC (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
+GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID ();
- SetCurrentThreadID (tid);
+ // Make sure we set the current thread so g and p packets return
+ // the data the gdb will expect.
+ lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID();
+ SetCurrentThreadID(tid);
- NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread ();
- if (!thread_sp)
- return SendErrorResponse (69);
+ NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread();
+ if (!thread_sp)
+ return SendErrorResponse(69);
- StreamString response;
- response.Printf ("QC%" PRIx64, thread_sp->GetID ());
+ StreamString response;
+ response.Printf("QC%" PRIx64, thread_sp->GetID());
- return SendPacketNoLock (response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_k (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- StopSTDIOForwarding();
+ StopSTDIOForwarding();
- if (! m_debugged_process_sp)
- {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s No debugged process found.", __FUNCTION__);
- return PacketResult::Success;
- }
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s No debugged process found.",
+ __FUNCTION__);
+ return PacketResult::Success;
+ }
- Error error = m_debugged_process_sp->Kill();
- if (error.Fail() && log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged process %" PRIu64 ": %s",
- __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
+ Error error = m_debugged_process_sp->Kill();
+ if (error.Fail() && log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged "
+ "process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
- // No OK response for kill packet.
- // return SendOKResponse ();
- return PacketResult::Success;
+ // No OK response for kill packet.
+ // return SendOKResponse ();
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetDisableASLR:"));
- if (packet.GetU32(0))
- m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
- else
- m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
- return SendOKResponse ();
+GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetDisableASLR:"));
+ if (packet.GetU32(0))
+ m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
+ else
+ m_process_launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos (::strlen ("QSetWorkingDir:"));
- std::string path;
- packet.GetHexByteString (path);
- m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
- return SendOKResponse ();
+GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetWorkingDir:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
-{
- FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
- if (working_dir)
- {
- StreamString response;
- response.PutCStringAsRawHex8(working_dir.GetCString());
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
+ if (working_dir) {
+ StreamString response;
+ response.PutCStringAsRawHex8(working_dir.GetCString());
+ return SendPacketNoLock(response.GetString());
+ }
- return SendErrorResponse(14);
+ return SendErrorResponse(14);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_C (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- // Ensure we have a native process.
- if (!m_debugged_process_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
- return SendErrorResponse (0x36);
- }
-
- // Pull out the signal number.
- packet.SetFilePos (::strlen ("C"));
- if (packet.GetBytesLeft () < 1)
- {
- // Shouldn't be using a C without a signal.
- return SendIllFormedResponse (packet, "C packet specified without signal.");
- }
- const uint32_t signo = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (signo == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse (packet, "failed to parse signal number");
-
- // Handle optional continue address.
- if (packet.GetBytesLeft () > 0)
- {
- // FIXME add continue at address support for $C{signo}[;{continue-address}].
- if (*packet.Peek () == ';')
- return SendUnimplementedResponse (packet.GetStringRef().c_str());
- else
- return SendIllFormedResponse (packet, "unexpected content after $C{signal-number}");
- }
+GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
- ResumeActionList resume_actions (StateType::eStateRunning, 0);
- Error error;
-
- // We have two branches: what to do if a continue thread is specified (in which case we target
- // sending the signal to that thread), or when we don't have a continue thread set (in which
- // case we send a signal to the process).
-
- // TODO discuss with Greg Clayton, make sure this makes sense.
-
- lldb::tid_t signal_tid = GetContinueThreadID ();
- if (signal_tid != LLDB_INVALID_THREAD_ID)
- {
- // The resume action for the continue thread (or all threads if a continue thread is not set).
- ResumeAction action = { GetContinueThreadID (), StateType::eStateRunning, static_cast<int> (signo) };
-
- // Add the action for the continue thread (or all threads when the continue thread isn't present).
- resume_actions.Append (action);
- }
+ // Ensure we have a native process.
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
+ return SendErrorResponse(0x36);
+ }
+
+ // Pull out the signal number.
+ packet.SetFilePos(::strlen("C"));
+ if (packet.GetBytesLeft() < 1) {
+ // Shouldn't be using a C without a signal.
+ return SendIllFormedResponse(packet, "C packet specified without signal.");
+ }
+ const uint32_t signo =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (signo == std::numeric_limits<uint32_t>::max())
+ return SendIllFormedResponse(packet, "failed to parse signal number");
+
+ // Handle optional continue address.
+ if (packet.GetBytesLeft() > 0) {
+ // FIXME add continue at address support for $C{signo}[;{continue-address}].
+ if (*packet.Peek() == ';')
+ return SendUnimplementedResponse(packet.GetStringRef().c_str());
else
- {
- // Send the signal to the process since we weren't targeting a specific continue thread with the signal.
- error = m_debugged_process_sp->Signal (signo);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send signal for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
-
- return SendErrorResponse (0x52);
- }
- }
-
- // Resume the threads.
- error = m_debugged_process_sp->Resume (resume_actions);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to resume threads for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
+ return SendIllFormedResponse(
+ packet, "unexpected content after $C{signal-number}");
+ }
+
+ ResumeActionList resume_actions(StateType::eStateRunning, 0);
+ Error error;
+
+ // We have two branches: what to do if a continue thread is specified (in
+ // which case we target
+ // sending the signal to that thread), or when we don't have a continue thread
+ // set (in which
+ // case we send a signal to the process).
+
+ // TODO discuss with Greg Clayton, make sure this makes sense.
+
+ lldb::tid_t signal_tid = GetContinueThreadID();
+ if (signal_tid != LLDB_INVALID_THREAD_ID) {
+ // The resume action for the continue thread (or all threads if a continue
+ // thread is not set).
+ ResumeAction action = {GetContinueThreadID(), StateType::eStateRunning,
+ static_cast<int>(signo)};
+
+ // Add the action for the continue thread (or all threads when the continue
+ // thread isn't present).
+ resume_actions.Append(action);
+ } else {
+ // Send the signal to the process since we weren't targeting a specific
+ // continue thread with the signal.
+ error = m_debugged_process_sp->Signal(signo);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send "
+ "signal for process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+
+ return SendErrorResponse(0x52);
+ }
+ }
+
+ // Resume the threads.
+ error = m_debugged_process_sp->Resume(resume_actions);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to resume "
+ "threads for process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
- return SendErrorResponse (0x38);
- }
+ return SendErrorResponse(0x38);
+ }
- // Don't send an "OK" packet; response is the stopped/exited message.
- return PacketResult::Success;
+ // Don't send an "OK" packet; response is the stopped/exited message.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_c (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- packet.SetFilePos (packet.GetFilePos() + ::strlen ("c"));
+GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
- // For now just support all continue.
- const bool has_continue_address = (packet.GetBytesLeft () > 0);
- if (has_continue_address)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s not implemented for c{address} variant [%s remains]", __FUNCTION__, packet.Peek ());
- return SendUnimplementedResponse (packet.GetStringRef().c_str());
- }
+ packet.SetFilePos(packet.GetFilePos() + ::strlen("c"));
- // Ensure we have a native process.
- if (!m_debugged_process_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
- return SendErrorResponse (0x36);
- }
+ // For now just support all continue.
+ const bool has_continue_address = (packet.GetBytesLeft() > 0);
+ if (has_continue_address) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s not implemented for "
+ "c{address} variant [%s remains]",
+ __FUNCTION__, packet.Peek());
+ return SendUnimplementedResponse(packet.GetStringRef().c_str());
+ }
+
+ // Ensure we have a native process.
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
+ return SendErrorResponse(0x36);
+ }
- // Build the ResumeActionList
- ResumeActionList actions (StateType::eStateRunning, 0);
+ // Build the ResumeActionList
+ ResumeActionList actions(StateType::eStateRunning, 0);
- Error error = m_debugged_process_sp->Resume (actions);
- if (error.Fail ())
- {
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- }
- return SendErrorResponse (GDBRemoteServerError::eErrorResume);
+ Error error = m_debugged_process_sp->Resume(actions);
+ if (error.Fail()) {
+ if (log) {
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64
+ ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
}
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
- // No response required from continue.
- return PacketResult::Success;
+ // No response required from continue.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vCont_actions (StringExtractorGDBRemote &packet)
-{
- StreamString response;
- response.Printf("vCont;c;C;s;S");
+GDBRemoteCommunicationServerLLGS::Handle_vCont_actions(
+ StringExtractorGDBRemote &packet) {
+ StreamString response;
+ response.Printf("vCont;c;C;s;S");
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s handling vCont packet", __FUNCTION__);
-
- packet.SetFilePos (::strlen ("vCont"));
+GDBRemoteCommunicationServerLLGS::Handle_vCont(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
+ __FUNCTION__);
- if (packet.GetBytesLeft() == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s missing action from vCont package", __FUNCTION__);
- return SendIllFormedResponse (packet, "Missing action from vCont package");
- }
+ packet.SetFilePos(::strlen("vCont"));
- // Check if this is all continue (no options or ";c").
- if (::strcmp (packet.Peek (), ";c") == 0)
- {
- // Move past the ';', then do a simple 'c'.
- packet.SetFilePos (packet.GetFilePos () + 1);
- return Handle_c (packet);
- }
- else if (::strcmp (packet.Peek (), ";s") == 0)
- {
- // Move past the ';', then do a simple 's'.
- packet.SetFilePos (packet.GetFilePos () + 1);
- return Handle_s (packet);
- }
+ if (packet.GetBytesLeft() == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s missing action from "
+ "vCont package",
+ __FUNCTION__);
+ return SendIllFormedResponse(packet, "Missing action from vCont package");
+ }
+
+ // Check if this is all continue (no options or ";c").
+ if (::strcmp(packet.Peek(), ";c") == 0) {
+ // Move past the ';', then do a simple 'c'.
+ packet.SetFilePos(packet.GetFilePos() + 1);
+ return Handle_c(packet);
+ } else if (::strcmp(packet.Peek(), ";s") == 0) {
+ // Move past the ';', then do a simple 's'.
+ packet.SetFilePos(packet.GetFilePos() + 1);
+ return Handle_s(packet);
+ }
+
+ // Ensure we have a native process.
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
+ return SendErrorResponse(0x36);
+ }
+
+ ResumeActionList thread_actions;
+
+ while (packet.GetBytesLeft() && *packet.Peek() == ';') {
+ // Skip the semi-colon.
+ packet.GetChar();
+
+ // Build up the thread action.
+ ResumeAction thread_action;
+ thread_action.tid = LLDB_INVALID_THREAD_ID;
+ thread_action.state = eStateInvalid;
+ thread_action.signal = 0;
+
+ const char action = packet.GetChar();
+ switch (action) {
+ case 'C':
+ thread_action.signal = packet.GetHexMaxU32(false, 0);
+ if (thread_action.signal == 0)
+ return SendIllFormedResponse(
+ packet, "Could not parse signal in vCont packet C action");
+ LLVM_FALLTHROUGH;
+
+ case 'c':
+ // Continue
+ thread_action.state = eStateRunning;
+ break;
+
+ case 'S':
+ thread_action.signal = packet.GetHexMaxU32(false, 0);
+ if (thread_action.signal == 0)
+ return SendIllFormedResponse(
+ packet, "Could not parse signal in vCont packet S action");
+ LLVM_FALLTHROUGH;
+
+ case 's':
+ // Step
+ thread_action.state = eStateStepping;
+ break;
- // Ensure we have a native process.
- if (!m_debugged_process_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
- return SendErrorResponse (0x36);
+ default:
+ return SendIllFormedResponse(packet, "Unsupported vCont action");
+ break;
}
- ResumeActionList thread_actions;
-
- while (packet.GetBytesLeft () && *packet.Peek () == ';')
- {
- // Skip the semi-colon.
- packet.GetChar ();
-
- // Build up the thread action.
- ResumeAction thread_action;
- thread_action.tid = LLDB_INVALID_THREAD_ID;
- thread_action.state = eStateInvalid;
- thread_action.signal = 0;
-
- const char action = packet.GetChar ();
- switch (action)
- {
- case 'C':
- thread_action.signal = packet.GetHexMaxU32 (false, 0);
- if (thread_action.signal == 0)
- return SendIllFormedResponse (packet, "Could not parse signal in vCont packet C action");
- LLVM_FALLTHROUGH;
-
- case 'c':
- // Continue
- thread_action.state = eStateRunning;
- break;
-
- case 'S':
- thread_action.signal = packet.GetHexMaxU32 (false, 0);
- if (thread_action.signal == 0)
- return SendIllFormedResponse (packet, "Could not parse signal in vCont packet S action");
- LLVM_FALLTHROUGH;
-
- case 's':
- // Step
- thread_action.state = eStateStepping;
- break;
-
- default:
- return SendIllFormedResponse (packet, "Unsupported vCont action");
- break;
- }
-
- // Parse out optional :{thread-id} value.
- if (packet.GetBytesLeft () && (*packet.Peek () == ':'))
- {
- // Consume the separator.
- packet.GetChar ();
-
- thread_action.tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID);
- if (thread_action.tid == LLDB_INVALID_THREAD_ID)
- return SendIllFormedResponse (packet, "Could not parse thread number in vCont packet");
- }
+ // Parse out optional :{thread-id} value.
+ if (packet.GetBytesLeft() && (*packet.Peek() == ':')) {
+ // Consume the separator.
+ packet.GetChar();
- thread_actions.Append (thread_action);
+ thread_action.tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+ if (thread_action.tid == LLDB_INVALID_THREAD_ID)
+ return SendIllFormedResponse(
+ packet, "Could not parse thread number in vCont packet");
}
- Error error = m_debugged_process_sp->Resume (thread_actions);
- if (error.Fail ())
- {
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s vCont failed for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- }
- return SendErrorResponse (GDBRemoteServerError::eErrorResume);
+ thread_actions.Append(thread_action);
+ }
+
+ Error error = m_debugged_process_sp->Resume(thread_actions);
+ if (error.Fail()) {
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s vCont failed for "
+ "process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
}
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
- // No response required from vCont.
- return PacketResult::Success;
+ // No response required from vCont.
+ return PacketResult::Success;
}
-void
-GDBRemoteCommunicationServerLLGS::SetCurrentThreadID (lldb::tid_t tid)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting current thread id to %" PRIu64, __FUNCTION__, tid);
+void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s setting current thread "
+ "id to %" PRIu64,
+ __FUNCTION__, tid);
- m_current_tid = tid;
- if (m_debugged_process_sp)
- m_debugged_process_sp->SetCurrentThreadID (m_current_tid);
+ m_current_tid = tid;
+ if (m_debugged_process_sp)
+ m_debugged_process_sp->SetCurrentThreadID(m_current_tid);
}
-void
-GDBRemoteCommunicationServerLLGS::SetContinueThreadID (lldb::tid_t tid)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting continue thread id to %" PRIu64, __FUNCTION__, tid);
+void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s setting continue thread "
+ "id to %" PRIu64,
+ __FUNCTION__, tid);
- m_continue_tid = tid;
+ m_continue_tid = tid;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_stop_reason (StringExtractorGDBRemote &packet)
-{
- // Handle the $? gdbremote command.
+GDBRemoteCommunicationServerLLGS::Handle_stop_reason(
+ StringExtractorGDBRemote &packet) {
+ // Handle the $? gdbremote command.
- // If no process, indicate error
- if (!m_debugged_process_sp)
- return SendErrorResponse (02);
+ // If no process, indicate error
+ if (!m_debugged_process_sp)
+ return SendErrorResponse(02);
- return SendStopReasonForState (m_debugged_process_sp->GetState());
+ return SendStopReasonForState(m_debugged_process_sp->GetState());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReasonForState (lldb::StateType process_state)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- switch (process_state)
- {
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateDetached:
- // NOTE: gdb protocol doc looks like it should return $OK
- // when everything is running (i.e. no stopped result).
- return PacketResult::Success; // Ignore
-
- case eStateSuspended:
- case eStateStopped:
- case eStateCrashed:
- {
- lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID ();
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- SetCurrentThreadID (tid);
- return SendStopReplyPacketForThread (tid);
- }
+GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
+ lldb::StateType process_state) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ switch (process_state) {
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ // NOTE: gdb protocol doc looks like it should return $OK
+ // when everything is running (i.e. no stopped result).
+ return PacketResult::Success; // Ignore
+
+ case eStateSuspended:
+ case eStateStopped:
+ case eStateCrashed: {
+ lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID();
+ // Make sure we set the current thread so g and p packets return
+ // the data the gdb will expect.
+ SetCurrentThreadID(tid);
+ return SendStopReplyPacketForThread(tid);
+ }
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- return SendWResponse(m_debugged_process_sp.get());
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateExited:
+ return SendWResponse(m_debugged_process_sp.get());
- default:
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", current state reporting not handled: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- StateAsCString (process_state));
- }
- break;
+ default:
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ ", current state reporting not handled: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ StateAsCString(process_state));
}
-
- return SendErrorResponse (0);
+ break;
+ }
+
+ return SendErrorResponse(0);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
-
- // Ensure we have a thread.
- NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadAtIndex (0));
- if (!thread_sp)
- return SendErrorResponse (69);
-
- // Get the register context for the first thread.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- return SendErrorResponse (69);
-
- // Parse out the register number from the request.
- packet.SetFilePos (strlen("qRegisterInfo"));
- const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (reg_index == std::numeric_limits<uint32_t>::max ())
- return SendErrorResponse (69);
-
- // Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount ())
- return SendErrorResponse (69);
-
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return SendErrorResponse (69);
-
- // Build the reginfos response.
- StreamGDBRemote response;
-
- response.PutCString ("name:");
- response.PutCString (reg_info->name);
- response.PutChar (';');
-
- if (reg_info->alt_name && reg_info->alt_name[0])
- {
- response.PutCString ("alt-name:");
- response.PutCString (reg_info->alt_name);
- response.PutChar (';');
- }
-
- response.Printf ("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", reg_info->byte_size * 8, reg_info->byte_offset);
-
- switch (reg_info->encoding)
- {
- case eEncodingUint: response.PutCString ("encoding:uint;"); break;
- case eEncodingSint: response.PutCString ("encoding:sint;"); break;
- case eEncodingIEEE754: response.PutCString ("encoding:ieee754;"); break;
- case eEncodingVector: response.PutCString ("encoding:vector;"); break;
- default: break;
- }
-
- switch (reg_info->format)
- {
- case eFormatBinary: response.PutCString ("format:binary;"); break;
- case eFormatDecimal: response.PutCString ("format:decimal;"); break;
- case eFormatHex: response.PutCString ("format:hex;"); break;
- case eFormatFloat: response.PutCString ("format:float;"); break;
- case eFormatVectorOfSInt8: response.PutCString ("format:vector-sint8;"); break;
- case eFormatVectorOfUInt8: response.PutCString ("format:vector-uint8;"); break;
- case eFormatVectorOfSInt16: response.PutCString ("format:vector-sint16;"); break;
- case eFormatVectorOfUInt16: response.PutCString ("format:vector-uint16;"); break;
- case eFormatVectorOfSInt32: response.PutCString ("format:vector-sint32;"); break;
- case eFormatVectorOfUInt32: response.PutCString ("format:vector-uint32;"); break;
- case eFormatVectorOfFloat32: response.PutCString ("format:vector-float32;"); break;
- case eFormatVectorOfUInt128: response.PutCString ("format:vector-uint128;"); break;
- default: break;
- };
-
- const char *const register_set_name = reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
- if (register_set_name)
- {
- response.PutCString ("set:");
- response.PutCString (register_set_name);
- response.PutChar (';');
- }
-
- if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
- response.Printf ("ehframe:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
-
- if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
- response.Printf ("dwarf:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
-
- switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric])
- {
- case LLDB_REGNUM_GENERIC_PC: response.PutCString("generic:pc;"); break;
- case LLDB_REGNUM_GENERIC_SP: response.PutCString("generic:sp;"); break;
- case LLDB_REGNUM_GENERIC_FP: response.PutCString("generic:fp;"); break;
- case LLDB_REGNUM_GENERIC_RA: response.PutCString("generic:ra;"); break;
- case LLDB_REGNUM_GENERIC_FLAGS: response.PutCString("generic:flags;"); break;
- case LLDB_REGNUM_GENERIC_ARG1: response.PutCString("generic:arg1;"); break;
- case LLDB_REGNUM_GENERIC_ARG2: response.PutCString("generic:arg2;"); break;
- case LLDB_REGNUM_GENERIC_ARG3: response.PutCString("generic:arg3;"); break;
- case LLDB_REGNUM_GENERIC_ARG4: response.PutCString("generic:arg4;"); break;
- case LLDB_REGNUM_GENERIC_ARG5: response.PutCString("generic:arg5;"); break;
- case LLDB_REGNUM_GENERIC_ARG6: response.PutCString("generic:arg6;"); break;
- case LLDB_REGNUM_GENERIC_ARG7: response.PutCString("generic:arg7;"); break;
- case LLDB_REGNUM_GENERIC_ARG8: response.PutCString("generic:arg8;"); break;
- default: break;
- }
-
- if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
- {
- response.PutCString ("container-regs:");
- int i = 0;
- for (const uint32_t *reg_num = reg_info->value_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i)
- {
- if (i > 0)
- response.PutChar (',');
- response.Printf ("%" PRIx32, *reg_num);
- }
- response.PutChar (';');
- }
-
- if (reg_info->invalidate_regs && reg_info->invalidate_regs[0])
- {
- response.PutCString ("invalidate-regs:");
- int i = 0;
- for (const uint32_t *reg_num = reg_info->invalidate_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i)
- {
- if (i > 0)
- response.PutChar (',');
- response.Printf ("%" PRIx32, *reg_num);
- }
- response.PutChar (';');
- }
-
- if (reg_info->dynamic_size_dwarf_expr_bytes)
- {
- const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
- response.PutCString("dynamic_size_dwarf_expr_bytes:");
- for(uint32_t i = 0; i < dwarf_opcode_len; ++i)
- response.PutHex8 (reg_info->dynamic_size_dwarf_expr_bytes[i]);
- response.PutChar(';');
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
+
+ // Ensure we have a thread.
+ NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadAtIndex(0));
+ if (!thread_sp)
+ return SendErrorResponse(69);
+
+ // Get the register context for the first thread.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp)
+ return SendErrorResponse(69);
+
+ // Parse out the register number from the request.
+ packet.SetFilePos(strlen("qRegisterInfo"));
+ const uint32_t reg_index =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (reg_index == std::numeric_limits<uint32_t>::max())
+ return SendErrorResponse(69);
+
+ // Return the end of registers response if we've iterated one past the end of
+ // the register set.
+ if (reg_index >= reg_context_sp->GetUserRegisterCount())
+ return SendErrorResponse(69);
+
+ const RegisterInfo *reg_info =
+ reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info)
+ return SendErrorResponse(69);
+
+ // Build the reginfos response.
+ StreamGDBRemote response;
+
+ response.PutCString("name:");
+ response.PutCString(reg_info->name);
+ response.PutChar(';');
+
+ if (reg_info->alt_name && reg_info->alt_name[0]) {
+ response.PutCString("alt-name:");
+ response.PutCString(reg_info->alt_name);
+ response.PutChar(';');
+ }
+
+ response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";",
+ reg_info->byte_size * 8, reg_info->byte_offset);
+
+ switch (reg_info->encoding) {
+ case eEncodingUint:
+ response.PutCString("encoding:uint;");
+ break;
+ case eEncodingSint:
+ response.PutCString("encoding:sint;");
+ break;
+ case eEncodingIEEE754:
+ response.PutCString("encoding:ieee754;");
+ break;
+ case eEncodingVector:
+ response.PutCString("encoding:vector;");
+ break;
+ default:
+ break;
+ }
+
+ switch (reg_info->format) {
+ case eFormatBinary:
+ response.PutCString("format:binary;");
+ break;
+ case eFormatDecimal:
+ response.PutCString("format:decimal;");
+ break;
+ case eFormatHex:
+ response.PutCString("format:hex;");
+ break;
+ case eFormatFloat:
+ response.PutCString("format:float;");
+ break;
+ case eFormatVectorOfSInt8:
+ response.PutCString("format:vector-sint8;");
+ break;
+ case eFormatVectorOfUInt8:
+ response.PutCString("format:vector-uint8;");
+ break;
+ case eFormatVectorOfSInt16:
+ response.PutCString("format:vector-sint16;");
+ break;
+ case eFormatVectorOfUInt16:
+ response.PutCString("format:vector-uint16;");
+ break;
+ case eFormatVectorOfSInt32:
+ response.PutCString("format:vector-sint32;");
+ break;
+ case eFormatVectorOfUInt32:
+ response.PutCString("format:vector-uint32;");
+ break;
+ case eFormatVectorOfFloat32:
+ response.PutCString("format:vector-float32;");
+ break;
+ case eFormatVectorOfUInt64:
+ response.PutCString("format:vector-uint64;");
+ break;
+ case eFormatVectorOfUInt128:
+ response.PutCString("format:vector-uint128;");
+ break;
+ default:
+ break;
+ };
+
+ const char *const register_set_name =
+ reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
+ if (register_set_name) {
+ response.PutCString("set:");
+ response.PutCString(register_set_name);
+ response.PutChar(';');
+ }
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
+ LLDB_INVALID_REGNUM)
+ response.Printf("ehframe:%" PRIu32 ";",
+ reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
+ response.Printf("dwarf:%" PRIu32 ";",
+ reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
+
+ switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) {
+ case LLDB_REGNUM_GENERIC_PC:
+ response.PutCString("generic:pc;");
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ response.PutCString("generic:sp;");
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ response.PutCString("generic:fp;");
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ response.PutCString("generic:ra;");
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ response.PutCString("generic:flags;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG1:
+ response.PutCString("generic:arg1;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG2:
+ response.PutCString("generic:arg2;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG3:
+ response.PutCString("generic:arg3;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG4:
+ response.PutCString("generic:arg4;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG5:
+ response.PutCString("generic:arg5;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG6:
+ response.PutCString("generic:arg6;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG7:
+ response.PutCString("generic:arg7;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG8:
+ response.PutCString("generic:arg8;");
+ break;
+ default:
+ break;
+ }
+
+ if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
+ response.PutCString("container-regs:");
+ int i = 0;
+ for (const uint32_t *reg_num = reg_info->value_regs;
+ *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+ if (i > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx32, *reg_num);
+ }
+ response.PutChar(';');
+ }
+
+ if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
+ response.PutCString("invalidate-regs:");
+ int i = 0;
+ for (const uint32_t *reg_num = reg_info->invalidate_regs;
+ *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+ if (i > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx32, *reg_num);
+ }
+ response.PutChar(';');
+ }
+
+ if (reg_info->dynamic_size_dwarf_expr_bytes) {
+ const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
+ response.PutCString("dynamic_size_dwarf_expr_bytes:");
+ for (uint32_t i = 0; i < dwarf_opcode_len; ++i)
+ response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]);
+ response.PutChar(';');
+ }
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() no process (%s), returning OK", __FUNCTION__, m_debugged_process_sp ? "invalid process id" : "null m_debugged_process_sp");
- return SendOKResponse ();
- }
-
- StreamGDBRemote response;
- response.PutChar ('m');
+GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() starting thread iteration", __FUNCTION__);
-
- NativeThreadProtocolSP thread_sp;
- uint32_t thread_index;
- for (thread_index = 0, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index);
- thread_sp;
- ++thread_index, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32 "(%s, tid=0x%" PRIx64 ")", __FUNCTION__, thread_index, thread_sp ? "is not null" : "null", thread_sp ? thread_sp->GetID () : LLDB_INVALID_THREAD_ID);
- if (thread_index > 0)
- response.PutChar(',');
- response.Printf ("%" PRIx64, thread_sp->GetID ());
- }
-
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s() no process (%s), "
+ "returning OK",
+ __FUNCTION__,
+ m_debugged_process_sp ? "invalid process id"
+ : "null m_debugged_process_sp");
+ return SendOKResponse();
+ }
+
+ StreamGDBRemote response;
+ response.PutChar('m');
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s() starting thread iteration",
+ __FUNCTION__);
+
+ NativeThreadProtocolSP thread_sp;
+ uint32_t thread_index;
+ for (thread_index = 0,
+ thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index);
+ thread_sp; ++thread_index,
+ thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index)) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() finished thread iteration", __FUNCTION__);
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32
+ "(%s, tid=0x%" PRIx64 ")",
+ __FUNCTION__, thread_index, thread_sp ? "is not null" : "null",
+ thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID);
+ if (thread_index > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx64, thread_sp->GetID());
+ }
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s() finished thread iteration",
+ __FUNCTION__);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo (StringExtractorGDBRemote &packet)
-{
- // FIXME for now we return the full thread list in the initial packet and always do nothing here.
- return SendPacketNoLock ("l", 1);
+GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo(
+ StringExtractorGDBRemote &packet) {
+ // FIXME for now we return the full thread list in the initial packet and
+ // always do nothing here.
+ return SendPacketNoLock("l");
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_p (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Parse out the register number from the request.
- packet.SetFilePos (strlen("p"));
- const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (reg_index == std::numeric_limits<uint32_t>::max ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
- return SendErrorResponse (0x15);
- }
-
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Get the thread's register context.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
- }
-
- // Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
- return SendErrorResponse (0x15);
- }
-
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index);
- return SendErrorResponse (0x15);
- }
-
- // Build the reginfos response.
- StreamGDBRemote response;
-
- // Retrieve the value
- RegisterValue reg_value;
- Error error = reg_context_sp->ReadRegister (reg_info, reg_value);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, read of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ());
- return SendErrorResponse (0x15);
- }
-
- const uint8_t *const data = reinterpret_cast<const uint8_t*> (reg_value.GetBytes ());
- if (!data)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get data bytes from requested register %" PRIu32, __FUNCTION__, reg_index);
- return SendErrorResponse (0x15);
- }
+GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Parse out the register number from the request.
+ packet.SetFilePos(strlen("p"));
+ const uint32_t reg_index =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (reg_index == std::numeric_limits<uint32_t>::max()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return SendErrorResponse(0x15);
+ }
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no thread available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Get the thread's register context.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ // Return the end of registers response if we've iterated one past the end of
+ // the register set.
+ if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index,
+ reg_context_sp->GetUserRegisterCount());
+ return SendErrorResponse(0x15);
+ }
+
+ const RegisterInfo *reg_info =
+ reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
+ return SendErrorResponse(0x15);
+ }
+
+ // Build the reginfos response.
+ StreamGDBRemote response;
+
+ // Retrieve the value
+ RegisterValue reg_value;
+ Error error = reg_context_sp->ReadRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ return SendErrorResponse(0x15);
+ }
+
+ const uint8_t *const data =
+ reinterpret_cast<const uint8_t *>(reg_value.GetBytes());
+ if (!data) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get data "
+ "bytes from requested register %" PRIu32,
+ __FUNCTION__, reg_index);
+ return SendErrorResponse(0x15);
+ }
- // FIXME flip as needed to get data in big/little endian format for this host.
- for (uint32_t i = 0; i < reg_value.GetByteSize (); ++i)
- response.PutHex8 (data[i]);
+ // FIXME flip as needed to get data in big/little endian format for this host.
+ for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i)
+ response.PutHex8(data[i]);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_P (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Ensure there is more content.
- if (packet.GetBytesLeft () < 1)
- return SendIllFormedResponse (packet, "Empty P packet");
-
- // Parse out the register number from the request.
- packet.SetFilePos (strlen("P"));
- const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (reg_index == std::numeric_limits<uint32_t>::max ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
- return SendErrorResponse (0x29);
- }
-
- // Note debugserver would send an E30 here.
- if ((packet.GetBytesLeft () < 1) || (packet.GetChar () != '='))
- return SendIllFormedResponse (packet, "P packet missing '=' char after register number");
-
- // Get process architecture.
- ArchSpec process_arch;
- if (!m_debugged_process_sp || !m_debugged_process_sp->GetArchitecture (process_arch))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to retrieve inferior architecture", __FUNCTION__);
- return SendErrorResponse (0x49);
- }
-
- // Parse out the value.
- uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
- size_t reg_size = packet.GetHexBytesAvail (reg_bytes, sizeof(reg_bytes));
-
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available (thread index 0)", __FUNCTION__);
- return SendErrorResponse (0x28);
- }
-
- // Get the thread's register context.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
- }
-
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex (reg_index);
- if (!reg_info)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index);
- return SendErrorResponse (0x48);
- }
-
- // Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
- return SendErrorResponse (0x47);
- }
-
- // The dwarf expression are evaluate on host site
- // which may cause register size to change
- // Hence the reg_size may not be same as reg_info->bytes_size
- if ((reg_size != reg_info->byte_size) && !(reg_info->dynamic_size_dwarf_expr_bytes))
- {
- return SendIllFormedResponse (packet, "P packet register size is incorrect");
- }
-
- // Build the reginfos response.
- StreamGDBRemote response;
-
- RegisterValue reg_value (reg_bytes, reg_size, process_arch.GetByteOrder ());
- Error error = reg_context_sp->WriteRegister (reg_info, reg_value);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, write of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ());
- return SendErrorResponse (0x32);
- }
+GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Ensure there is more content.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Empty P packet");
+
+ // Parse out the register number from the request.
+ packet.SetFilePos(strlen("P"));
+ const uint32_t reg_index =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (reg_index == std::numeric_limits<uint32_t>::max()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return SendErrorResponse(0x29);
+ }
+
+ // Note debugserver would send an E30 here.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '='))
+ return SendIllFormedResponse(
+ packet, "P packet missing '=' char after register number");
+
+ // Get process architecture.
+ ArchSpec process_arch;
+ if (!m_debugged_process_sp ||
+ !m_debugged_process_sp->GetArchitecture(process_arch)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve "
+ "inferior architecture",
+ __FUNCTION__);
+ return SendErrorResponse(0x49);
+ }
+
+ // Parse out the value.
+ uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
+ size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
+ "available (thread index 0)",
+ __FUNCTION__);
+ return SendErrorResponse(0x28);
+ }
+
+ // Get the thread's register context.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ const RegisterInfo *reg_info =
+ reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
+ return SendErrorResponse(0x48);
+ }
+
+ // Return the end of registers response if we've iterated one past the end of
+ // the register set.
+ if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index,
+ reg_context_sp->GetUserRegisterCount());
+ return SendErrorResponse(0x47);
+ }
+
+ // The dwarf expression are evaluate on host site
+ // which may cause register size to change
+ // Hence the reg_size may not be same as reg_info->bytes_size
+ if ((reg_size != reg_info->byte_size) &&
+ !(reg_info->dynamic_size_dwarf_expr_bytes)) {
+ return SendIllFormedResponse(packet, "P packet register size is incorrect");
+ }
+
+ // Build the reginfos response.
+ StreamGDBRemote response;
+
+ RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder());
+ Error error = reg_context_sp->WriteRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ return SendErrorResponse(0x32);
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_H (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out which variant of $H is requested.
- packet.SetFilePos (strlen("H"));
- if (packet.GetBytesLeft () < 1)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, H command missing {g,c} variant", __FUNCTION__);
- return SendIllFormedResponse (packet, "H command missing {g,c} variant");
- }
-
- const char h_variant = packet.GetChar ();
- switch (h_variant)
- {
- case 'g':
- break;
-
- case 'c':
- break;
-
- default:
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", __FUNCTION__, h_variant);
- return SendIllFormedResponse (packet, "H variant unsupported, should be c or g");
- }
-
- // Parse out the thread number.
- // FIXME return a parse success/fail value. All values are valid here.
- const lldb::tid_t tid = packet.GetHexMaxU64 (false, std::numeric_limits<lldb::tid_t>::max ());
+GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- // Ensure we have the given thread when not specifying -1 (all threads) or 0 (any thread).
- if (tid != LLDB_INVALID_THREAD_ID && tid != 0)
- {
- NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid));
- if (!thread_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 " not found", __FUNCTION__, tid);
- return SendErrorResponse (0x15);
- }
- }
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out which variant of $H is requested.
+ packet.SetFilePos(strlen("H"));
+ if (packet.GetBytesLeft() < 1) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, H command "
+ "missing {g,c} variant",
+ __FUNCTION__);
+ return SendIllFormedResponse(packet, "H command missing {g,c} variant");
+ }
- // Now switch the given thread type.
- switch (h_variant)
- {
- case 'g':
- SetCurrentThreadID (tid);
- break;
+ const char h_variant = packet.GetChar();
+ switch (h_variant) {
+ case 'g':
+ break;
- case 'c':
- SetContinueThreadID (tid);
- break;
+ case 'c':
+ break;
- default:
- assert (false && "unsupported $H variant - shouldn't get here");
- return SendIllFormedResponse (packet, "H variant unsupported, should be c or g");
- }
-
- return SendOKResponse();
+ default:
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
+ __FUNCTION__, h_variant);
+ return SendIllFormedResponse(packet,
+ "H variant unsupported, should be c or g");
+ }
+
+ // Parse out the thread number.
+ // FIXME return a parse success/fail value. All values are valid here.
+ const lldb::tid_t tid =
+ packet.GetHexMaxU64(false, std::numeric_limits<lldb::tid_t>::max());
+
+ // Ensure we have the given thread when not specifying -1 (all threads) or 0
+ // (any thread).
+ if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
+ NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid));
+ if (!thread_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
+ " not found",
+ __FUNCTION__, tid);
+ return SendErrorResponse(0x15);
+ }
+ }
+
+ // Now switch the given thread type.
+ switch (h_variant) {
+ case 'g':
+ SetCurrentThreadID(tid);
+ break;
+
+ case 'c':
+ SetContinueThreadID(tid);
+ break;
+
+ default:
+ assert(false && "unsupported $H variant - shouldn't get here");
+ return SendIllFormedResponse(packet,
+ "H variant unsupported, should be c or g");
+ }
+
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_I (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- packet.SetFilePos (::strlen("I"));
- char tmp[4096];
- for (;;)
- {
- size_t read = packet.GetHexBytesAvail(tmp, sizeof(tmp));
- if (read == 0)
- {
- break;
- }
- // write directly to stdin *this might block if stdin buffer is full*
- // TODO: enqueue this block in circular buffer and send window size to remote host
- ConnectionStatus status;
- Error error;
- m_stdio_communication.Write(tmp, read, status, &error);
- if (error.Fail())
- {
- return SendErrorResponse (0x15);
- }
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ packet.SetFilePos(::strlen("I"));
+ uint8_t tmp[4096];
+ for (;;) {
+ size_t read = packet.GetHexBytesAvail(tmp);
+ if (read == 0) {
+ break;
+ }
+ // write directly to stdin *this might block if stdin buffer is full*
+ // TODO: enqueue this block in circular buffer and send window size to
+ // remote host
+ ConnectionStatus status;
+ Error error;
+ m_stdio_communication.Write(tmp, read, status, &error);
+ if (error.Fail()) {
+ return SendErrorResponse(0x15);
}
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_interrupt (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Interrupt the process.
- Error error = m_debugged_process_sp->Interrupt ();
- if (error.Fail ())
- {
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- }
- return SendErrorResponse (GDBRemoteServerError::eErrorResume);
- }
+GDBRemoteCommunicationServerLLGS::Handle_interrupt(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Interrupt the process.
+ Error error = m_debugged_process_sp->Interrupt();
+ if (error.Fail()) {
+ if (log) {
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64
+ ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
+ }
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
- // No response required from stop all.
- return PacketResult::Success;
+ // No response required from stop all.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_memory_read(StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out the memory address.
- packet.SetFilePos (strlen("m"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short m packet");
-
- // Read the address. Punting on validation.
- // FIXME replace with Hex U64 read with no default value that fails on failed read.
- const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
-
- // Validate comma.
- if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
- return SendIllFormedResponse(packet, "Comma sep missing in m packet");
-
- // Get # bytes to read.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Length missing in m packet");
-
- const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
- if (byte_count == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to read: zero-length packet", __FUNCTION__);
- return SendOKResponse();
- }
-
- // Allocate the response buffer.
- std::string buf(byte_count, '\0');
- if (buf.empty())
- return SendErrorResponse (0x78);
-
-
- // Retrieve the process memory.
- size_t bytes_read = 0;
- Error error = m_debugged_process_sp->ReadMemoryWithoutTrap(read_addr, &buf[0], byte_count, bytes_read);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to read. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, error.AsCString ());
- return SendErrorResponse (0x08);
- }
+GDBRemoteCommunicationServerLLGS::Handle_memory_read(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (bytes_read == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, byte_count);
- return SendErrorResponse (0x08);
- }
-
- StreamGDBRemote response;
- packet.SetFilePos(0);
- char kind = packet.GetChar('?');
- if (kind == 'x')
- response.PutEscapedBytes(buf.data(), byte_count);
- else
- {
- assert(kind == 'm');
- for (size_t i = 0; i < bytes_read; ++i)
- response.PutHex8(buf[i]);
- }
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("m"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short m packet");
+
+ // Read the address. Punting on validation.
+ // FIXME replace with Hex U64 read with no default value that fails on failed
+ // read.
+ const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+
+ // Validate comma.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
+ return SendIllFormedResponse(packet, "Comma sep missing in m packet");
+
+ // Get # bytes to read.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Length missing in m packet");
+
+ const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
+ if (byte_count == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: "
+ "zero-length packet",
+ __FUNCTION__);
+ return SendOKResponse();
+ }
+
+ // Allocate the response buffer.
+ std::string buf(byte_count, '\0');
+ if (buf.empty())
+ return SendErrorResponse(0x78);
+
+ // Retrieve the process memory.
+ size_t bytes_read = 0;
+ Error error = m_debugged_process_sp->ReadMemoryWithoutTrap(
+ read_addr, &buf[0], byte_count, bytes_read);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": failed to read. Error: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), read_addr,
+ error.AsCString());
+ return SendErrorResponse(0x08);
+ }
+
+ if (bytes_read == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
+ __FUNCTION__, m_debugged_process_sp->GetID(), read_addr,
+ byte_count);
+ return SendErrorResponse(0x08);
+ }
+
+ StreamGDBRemote response;
+ packet.SetFilePos(0);
+ char kind = packet.GetChar('?');
+ if (kind == 'x')
+ response.PutEscapedBytes(buf.data(), byte_count);
+ else {
+ assert(kind == 'm');
+ for (size_t i = 0; i < bytes_read; ++i)
+ response.PutHex8(buf[i]);
+ }
+
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_M (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out the memory address.
- packet.SetFilePos (strlen("M"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short M packet");
-
- // Read the address. Punting on validation.
- // FIXME replace with Hex U64 read with no default value that fails on failed read.
- const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0);
-
- // Validate comma.
- if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
- return SendIllFormedResponse(packet, "Comma sep missing in M packet");
-
- // Get # bytes to read.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Length missing in M packet");
+GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
- if (byte_count == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to write: zero-length packet", __FUNCTION__);
- return PacketResult::Success;
- }
-
- // Validate colon.
- if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':'))
- return SendIllFormedResponse(packet, "Comma sep missing in M packet after byte length");
-
- // Allocate the conversion buffer.
- std::vector<uint8_t> buf(byte_count, 0);
- if (buf.empty())
- return SendErrorResponse (0x78);
-
- // Convert the hex memory write contents to bytes.
- StreamGDBRemote response;
- const uint64_t convert_count = packet.GetHexBytes(&buf[0], byte_count, 0);
- if (convert_count != byte_count)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": asked to write %" PRIu64 " bytes, but only found %" PRIu64 " to convert.", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count, convert_count);
- return SendIllFormedResponse (packet, "M content byte length specified did not match hex-encoded content length");
- }
-
- // Write the process memory.
- size_t bytes_written = 0;
- Error error = m_debugged_process_sp->WriteMemory (write_addr, &buf[0], byte_count, bytes_written);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to write. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, error.AsCString ());
- return SendErrorResponse (0x09);
- }
-
- if (bytes_written == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count);
- return SendErrorResponse (0x09);
- }
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("M"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short M packet");
+
+ // Read the address. Punting on validation.
+ // FIXME replace with Hex U64 read with no default value that fails on failed
+ // read.
+ const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0);
+
+ // Validate comma.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
+ return SendIllFormedResponse(packet, "Comma sep missing in M packet");
+
+ // Get # bytes to read.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Length missing in M packet");
+
+ const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
+ if (byte_count == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to write: "
+ "zero-length packet",
+ __FUNCTION__);
+ return PacketResult::Success;
+ }
+
+ // Validate colon.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':'))
+ return SendIllFormedResponse(
+ packet, "Comma sep missing in M packet after byte length");
+
+ // Allocate the conversion buffer.
+ std::vector<uint8_t> buf(byte_count, 0);
+ if (buf.empty())
+ return SendErrorResponse(0x78);
+
+ // Convert the hex memory write contents to bytes.
+ StreamGDBRemote response;
+ const uint64_t convert_count = packet.GetHexBytes(buf, 0);
+ if (convert_count != byte_count) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": asked to write %" PRIu64
+ " bytes, but only found %" PRIu64 " to convert.",
+ __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+ byte_count, convert_count);
+ return SendIllFormedResponse(packet, "M content byte length specified did "
+ "not match hex-encoded content "
+ "length");
+ }
+
+ // Write the process memory.
+ size_t bytes_written = 0;
+ Error error = m_debugged_process_sp->WriteMemory(write_addr, &buf[0],
+ byte_count, bytes_written);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": failed to write. Error: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ }
+
+ if (bytes_written == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes",
+ __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+ byte_count);
+ return SendErrorResponse(0x09);
+ }
- return SendOKResponse ();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Currently only the NativeProcessProtocol knows if it can handle a qMemoryRegionInfoSupported
- // request, but we're not guaranteed to be attached to a process. For now we'll assume the
- // client only asks this when a process is being debugged.
-
- // Ensure we have a process running; otherwise, we can't figure this out
- // since we won't have a NativeProcessProtocol.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Currently only the NativeProcessProtocol knows if it can handle a
+ // qMemoryRegionInfoSupported
+ // request, but we're not guaranteed to be attached to a process. For now
+ // we'll assume the
+ // client only asks this when a process is being debugged.
+
+ // Ensure we have a process running; otherwise, we can't figure this out
+ // since we won't have a NativeProcessProtocol.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
- // Test if we can get any region back when asking for the region around NULL.
- MemoryRegionInfo region_info;
- const Error error = m_debugged_process_sp->GetMemoryRegionInfo (0, region_info);
- if (error.Fail ())
- {
- // We don't support memory region info collection for this NativeProcessProtocol.
- return SendUnimplementedResponse ("");
- }
+ // Test if we can get any region back when asking for the region around NULL.
+ MemoryRegionInfo region_info;
+ const Error error =
+ m_debugged_process_sp->GetMemoryRegionInfo(0, region_info);
+ if (error.Fail()) {
+ // We don't support memory region info collection for this
+ // NativeProcessProtocol.
+ return SendUnimplementedResponse("");
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out the memory address.
- packet.SetFilePos (strlen("qMemoryRegionInfo:"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
-
- // Read the address. Punting on validation.
- const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- StreamGDBRemote response;
-
- // Get the memory region info for the target address.
- MemoryRegionInfo region_info;
- const Error error = m_debugged_process_sp->GetMemoryRegionInfo (read_addr, region_info);
- if (error.Fail ())
- {
- // Return the error message.
-
- response.PutCString ("error:");
- response.PutCStringAsRawHex8 (error.AsCString ());
- response.PutChar (';');
- }
- else
- {
- // Range start and size.
- response.Printf ("start:%" PRIx64 ";size:%" PRIx64 ";", region_info.GetRange ().GetRangeBase (), region_info.GetRange ().GetByteSize ());
-
- // Permissions.
- if (region_info.GetReadable () ||
- region_info.GetWritable () ||
- region_info.GetExecutable ())
- {
- // Write permissions info.
- response.PutCString ("permissions:");
-
- if (region_info.GetReadable ())
- response.PutChar ('r');
- if (region_info.GetWritable ())
- response.PutChar('w');
- if (region_info.GetExecutable())
- response.PutChar ('x');
-
- response.PutChar (';');
- }
- }
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("qMemoryRegionInfo:"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
+
+ // Read the address. Punting on validation.
+ const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+
+ StreamGDBRemote response;
+
+ // Get the memory region info for the target address.
+ MemoryRegionInfo region_info;
+ const Error error =
+ m_debugged_process_sp->GetMemoryRegionInfo(read_addr, region_info);
+ if (error.Fail()) {
+ // Return the error message.
+
+ response.PutCString("error:");
+ response.PutCStringAsRawHex8(error.AsCString());
+ response.PutChar(';');
+ } else {
+ // Range start and size.
+ response.Printf("start:%" PRIx64 ";size:%" PRIx64 ";",
+ region_info.GetRange().GetRangeBase(),
+ region_info.GetRange().GetByteSize());
+
+ // Permissions.
+ if (region_info.GetReadable() || region_info.GetWritable() ||
+ region_info.GetExecutable()) {
+ // Write permissions info.
+ response.PutCString("permissions:");
+
+ if (region_info.GetReadable())
+ response.PutChar('r');
+ if (region_info.GetWritable())
+ response.PutChar('w');
+ if (region_info.GetExecutable())
+ response.PutChar('x');
+
+ response.PutChar(';');
+ }
+
+ // Name
+ ConstString name = region_info.GetName();
+ if (name) {
+ response.PutCString("name:");
+ response.PutCStringAsRawHex8(name.AsCString());
+ response.PutChar(';');
+ }
+ }
+
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_Z (StringExtractorGDBRemote &packet)
-{
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out software or hardware breakpoint or watchpoint requested.
- packet.SetFilePos (strlen("Z"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short Z packet, missing software/hardware specifier");
-
- bool want_breakpoint = true;
- bool want_hardware = false;
- uint32_t watch_flags = 0;
-
- const GDBStoppointType stoppoint_type =
- GDBStoppointType(packet.GetS32 (eStoppointInvalid));
- switch (stoppoint_type)
- {
- case eBreakpointSoftware:
- want_hardware = false; want_breakpoint = true; break;
- case eBreakpointHardware:
- want_hardware = true; want_breakpoint = true; break;
- case eWatchpointWrite:
- watch_flags = 1;
- want_hardware = true; want_breakpoint = false; break;
- case eWatchpointRead:
- watch_flags = 2;
- want_hardware = true; want_breakpoint = false; break;
- case eWatchpointReadWrite:
- watch_flags = 3;
- want_hardware = true; want_breakpoint = false; break;
- case eStoppointInvalid:
- return SendIllFormedResponse(packet, "Z packet had invalid software/hardware specifier");
-
- }
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after stoppoint type");
-
- // Parse out the stoppoint address.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short Z packet, missing address");
- const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after address");
-
- // Parse out the stoppoint size (i.e. size hint for opcode size).
- const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (size == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse size argument");
-
- if (want_breakpoint)
- {
- // Try to set the breakpoint.
- const Error error = m_debugged_process_sp->SetBreakpoint (addr, size, want_hardware);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to set breakpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
- else
- {
- // Try to set the watchpoint.
- const Error error = m_debugged_process_sp->SetWatchpoint (
- addr, size, watch_flags, want_hardware);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to set watchpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
+GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out software or hardware breakpoint or watchpoint requested.
+ packet.SetFilePos(strlen("Z"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "Too short Z packet, missing software/hardware specifier");
+
+ bool want_breakpoint = true;
+ bool want_hardware = false;
+ uint32_t watch_flags = 0;
+
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32(eStoppointInvalid));
+ switch (stoppoint_type) {
+ case eBreakpointSoftware:
+ want_hardware = false;
+ want_breakpoint = true;
+ break;
+ case eBreakpointHardware:
+ want_hardware = true;
+ want_breakpoint = true;
+ break;
+ case eWatchpointWrite:
+ watch_flags = 1;
+ want_hardware = true;
+ want_breakpoint = false;
+ break;
+ case eWatchpointRead:
+ watch_flags = 2;
+ want_hardware = true;
+ want_breakpoint = false;
+ break;
+ case eWatchpointReadWrite:
+ watch_flags = 3;
+ want_hardware = true;
+ want_breakpoint = false;
+ break;
+ case eStoppointInvalid:
+ return SendIllFormedResponse(
+ packet, "Z packet had invalid software/hardware specifier");
+ }
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed Z packet, expecting comma after stoppoint type");
+
+ // Parse out the stoppoint address.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short Z packet, missing address");
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed Z packet, expecting comma after address");
+
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (size == std::numeric_limits<uint32_t>::max())
+ return SendIllFormedResponse(
+ packet, "Malformed Z packet, failed to parse size argument");
+
+ if (want_breakpoint) {
+ // Try to set the breakpoint.
+ const Error error =
+ m_debugged_process_sp->SetBreakpoint(addr, size, want_hardware);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to set breakpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ } else {
+ // Try to set the watchpoint.
+ const Error error = m_debugged_process_sp->SetWatchpoint(
+ addr, size, watch_flags, want_hardware);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to set watchpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ }
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_z (StringExtractorGDBRemote &packet)
-{
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out software or hardware breakpoint or watchpoint requested.
- packet.SetFilePos (strlen("z"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier");
-
- bool want_breakpoint = true;
-
- const GDBStoppointType stoppoint_type =
- GDBStoppointType(packet.GetS32 (eStoppointInvalid));
- switch (stoppoint_type)
- {
- case eBreakpointHardware: want_breakpoint = true; break;
- case eBreakpointSoftware: want_breakpoint = true; break;
- case eWatchpointWrite: want_breakpoint = false; break;
- case eWatchpointRead: want_breakpoint = false; break;
- case eWatchpointReadWrite: want_breakpoint = false; break;
- default:
- return SendIllFormedResponse(packet, "z packet had invalid software/hardware specifier");
-
- }
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after stoppoint type");
-
- // Parse out the stoppoint address.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short z packet, missing address");
- const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after address");
-
- /*
- // Parse out the stoppoint size (i.e. size hint for opcode size).
- const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (size == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed z packet, failed to parse size argument");
- */
-
- if (want_breakpoint)
- {
- // Try to clear the breakpoint.
- const Error error = m_debugged_process_sp->RemoveBreakpoint (addr);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to remove breakpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
- else
- {
- // Try to clear the watchpoint.
- const Error error = m_debugged_process_sp->RemoveWatchpoint (addr);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to remove watchpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
+GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out software or hardware breakpoint or watchpoint requested.
+ packet.SetFilePos(strlen("z"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "Too short z packet, missing software/hardware specifier");
+
+ bool want_breakpoint = true;
+
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32(eStoppointInvalid));
+ switch (stoppoint_type) {
+ case eBreakpointHardware:
+ want_breakpoint = true;
+ break;
+ case eBreakpointSoftware:
+ want_breakpoint = true;
+ break;
+ case eWatchpointWrite:
+ want_breakpoint = false;
+ break;
+ case eWatchpointRead:
+ want_breakpoint = false;
+ break;
+ case eWatchpointReadWrite:
+ want_breakpoint = false;
+ break;
+ default:
+ return SendIllFormedResponse(
+ packet, "z packet had invalid software/hardware specifier");
+ }
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed z packet, expecting comma after stoppoint type");
+
+ // Parse out the stoppoint address.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short z packet, missing address");
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed z packet, expecting comma after address");
+
+ /*
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size = packet.GetHexMaxU32 (false,
+ std::numeric_limits<uint32_t>::max ());
+ if (size == std::numeric_limits<uint32_t>::max ())
+ return SendIllFormedResponse(packet, "Malformed z packet, failed to parse
+ size argument");
+ */
+
+ if (want_breakpoint) {
+ // Try to clear the breakpoint.
+ const Error error = m_debugged_process_sp->RemoveBreakpoint(addr);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to remove breakpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ } else {
+ // Try to clear the watchpoint.
+ const Error error = m_debugged_process_sp->RemoveWatchpoint(addr);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to remove watchpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ }
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_s (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
-
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x32);
- }
+GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- // We first try to use a continue thread id. If any one or any all set, use the current thread.
- // Bail out if we don't have a thread id.
- lldb::tid_t tid = GetContinueThreadID ();
- if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
- tid = GetCurrentThreadID ();
- if (tid == LLDB_INVALID_THREAD_ID)
- return SendErrorResponse (0x33);
-
- // Double check that we have such a thread.
- // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
- NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID (tid);
- if (!thread_sp || thread_sp->GetID () != tid)
- return SendErrorResponse (0x33);
-
- // Create the step action for the given thread.
- ResumeAction action = { tid, eStateStepping, 0 };
-
- // Setup the actions list.
- ResumeActionList actions;
- actions.Append (action);
-
- // All other threads stop while we're single stepping a thread.
- actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
- Error error = m_debugged_process_sp->Resume (actions);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " Resume() failed with error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), tid, error.AsCString ());
- return SendErrorResponse(0x49);
- }
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x32);
+ }
+
+ // We first try to use a continue thread id. If any one or any all set, use
+ // the current thread.
+ // Bail out if we don't have a thread id.
+ lldb::tid_t tid = GetContinueThreadID();
+ if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
+ tid = GetCurrentThreadID();
+ if (tid == LLDB_INVALID_THREAD_ID)
+ return SendErrorResponse(0x33);
+
+ // Double check that we have such a thread.
+ // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
+ NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID(tid);
+ if (!thread_sp || thread_sp->GetID() != tid)
+ return SendErrorResponse(0x33);
+
+ // Create the step action for the given thread.
+ ResumeAction action = {tid, eStateStepping, 0};
+
+ // Setup the actions list.
+ ResumeActionList actions;
+ actions.Append(action);
+
+ // All other threads stop while we're single stepping a thread.
+ actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
+ Error error = m_debugged_process_sp->Resume(actions);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64 " Resume() failed with error: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), tid,
+ error.AsCString());
+ return SendErrorResponse(0x49);
+ }
- // No response here - the stop or exit will come from the resulting action.
- return PacketResult::Success;
+ // No response here - the stop or exit will come from the resulting action.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet)
-{
- // *BSD impls should be able to do this too.
+GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read(
+ StringExtractorGDBRemote &packet) {
+// *BSD impls should be able to do this too.
#if defined(__linux__)
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Parse out the offset.
- packet.SetFilePos (strlen("qXfer:auxv:read::"));
- if (packet.GetBytesLeft () < 1)
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset");
-
- const uint64_t auxv_offset = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ());
- if (auxv_offset == std::numeric_limits<uint64_t>::max ())
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset");
-
- // Parse out comma.
- if (packet.GetBytesLeft () < 1 || packet.GetChar () != ',')
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing comma after offset");
-
- // Parse out the length.
- const uint64_t auxv_length = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ());
- if (auxv_length == std::numeric_limits<uint64_t>::max ())
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing length");
-
- // Grab the auxv data if we need it.
- if (!m_active_auxv_buffer_sp)
- {
- // Make sure we have a valid process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x10);
- }
-
- // Grab the auxv data.
- m_active_auxv_buffer_sp = Host::GetAuxvData (m_debugged_process_sp->GetID ());
- if (!m_active_auxv_buffer_sp || m_active_auxv_buffer_sp->GetByteSize () == 0)
- {
- // Hmm, no auxv data, call that an error.
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data retrieved", __FUNCTION__);
- m_active_auxv_buffer_sp.reset ();
- return SendErrorResponse (0x11);
- }
- }
-
- // FIXME find out if/how I lock the stream here.
-
- StreamGDBRemote response;
- bool done_with_buffer = false;
-
- if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize ())
- {
- // We have nothing left to send. Mark the buffer as complete.
- response.PutChar ('l');
- done_with_buffer = true;
- }
- else
- {
- // Figure out how many bytes are available starting at the given offset.
- const uint64_t bytes_remaining = m_active_auxv_buffer_sp->GetByteSize () - auxv_offset;
-
- // Figure out how many bytes we're going to read.
- const uint64_t bytes_to_read = (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length;
-
- // Mark the response type according to whether we're reading the remainder of the auxv data.
- if (bytes_to_read >= bytes_remaining)
- {
- // There will be nothing left to read after this
- response.PutChar ('l');
- done_with_buffer = true;
- }
- else
- {
- // There will still be bytes to read after this request.
- response.PutChar ('m');
- }
-
- // Now write the data in encoded binary form.
- response.PutEscapedBytes (m_active_auxv_buffer_sp->GetBytes () + auxv_offset, bytes_to_read);
- }
-
- if (done_with_buffer)
- m_active_auxv_buffer_sp.reset ();
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Parse out the offset.
+ packet.SetFilePos(strlen("qXfer:auxv:read::"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet,
+ "qXfer:auxv:read:: packet missing offset");
+
+ const uint64_t auxv_offset =
+ packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+ if (auxv_offset == std::numeric_limits<uint64_t>::max())
+ return SendIllFormedResponse(packet,
+ "qXfer:auxv:read:: packet missing offset");
+
+ // Parse out comma.
+ if (packet.GetBytesLeft() < 1 || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "qXfer:auxv:read:: packet missing comma after offset");
+
+ // Parse out the length.
+ const uint64_t auxv_length =
+ packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+ if (auxv_length == std::numeric_limits<uint64_t>::max())
+ return SendIllFormedResponse(packet,
+ "qXfer:auxv:read:: packet missing length");
+
+ // Grab the auxv data if we need it.
+ if (!m_active_auxv_buffer_sp) {
+ // Make sure we have a valid process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x10);
+ }
+
+ // Grab the auxv data.
+ m_active_auxv_buffer_sp = Host::GetAuxvData(m_debugged_process_sp->GetID());
+ if (!m_active_auxv_buffer_sp ||
+ m_active_auxv_buffer_sp->GetByteSize() == 0) {
+ // Hmm, no auxv data, call that an error.
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data "
+ "retrieved",
+ __FUNCTION__);
+ m_active_auxv_buffer_sp.reset();
+ return SendErrorResponse(0x11);
+ }
+ }
+
+ // FIXME find out if/how I lock the stream here.
+
+ StreamGDBRemote response;
+ bool done_with_buffer = false;
+
+ if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize()) {
+ // We have nothing left to send. Mark the buffer as complete.
+ response.PutChar('l');
+ done_with_buffer = true;
+ } else {
+ // Figure out how many bytes are available starting at the given offset.
+ const uint64_t bytes_remaining =
+ m_active_auxv_buffer_sp->GetByteSize() - auxv_offset;
+
+ // Figure out how many bytes we're going to read.
+ const uint64_t bytes_to_read =
+ (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length;
+
+ // Mark the response type according to whether we're reading the remainder
+ // of the auxv data.
+ if (bytes_to_read >= bytes_remaining) {
+ // There will be nothing left to read after this
+ response.PutChar('l');
+ done_with_buffer = true;
+ } else {
+ // There will still be bytes to read after this request.
+ response.PutChar('m');
+ }
+
+ // Now write the data in encoded binary form.
+ response.PutEscapedBytes(m_active_auxv_buffer_sp->GetBytes() + auxv_offset,
+ bytes_to_read);
+ }
+
+ if (done_with_buffer)
+ m_active_auxv_buffer_sp.reset();
+
+ return SendPacketNoLock(response.GetString());
#else
- return SendUnimplementedResponse ("not implemented on this platform");
+ return SendUnimplementedResponse("not implemented on this platform");
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Move past packet name.
- packet.SetFilePos (strlen ("QSaveRegisterState"));
-
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (m_thread_suffix_supported)
- return SendIllFormedResponse (packet, "No thread specified in QSaveRegisterState packet");
- else
- return SendIllFormedResponse (packet, "No thread was is set with the Hg packet");
- }
-
- // Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
- }
-
- // Save registers to a buffer.
- DataBufferSP register_data_sp;
- Error error = reg_context_sp->ReadAllRegisterValues (register_data_sp);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to save all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x75);
- }
-
- // Allocate a new save id.
- const uint32_t save_id = GetNextSavedRegistersID ();
- assert ((m_saved_registers_map.find (save_id) == m_saved_registers_map.end ()) && "GetNextRegisterSaveID() returned an existing register save id");
+GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Move past packet name.
+ packet.SetFilePos(strlen("QSaveRegisterState"));
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (m_thread_suffix_supported)
+ return SendIllFormedResponse(
+ packet, "No thread specified in QSaveRegisterState packet");
+ else
+ return SendIllFormedResponse(packet,
+ "No thread was is set with the Hg packet");
+ }
- // Save the register data buffer under the save id.
- {
- std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
- m_saved_registers_map[save_id] = register_data_sp;
- }
+ // Grab the register context for the thread.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ // Save registers to a buffer.
+ DataBufferSP register_data_sp;
+ Error error = reg_context_sp->ReadAllRegisterValues(register_data_sp);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to save all register values: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x75);
+ }
+
+ // Allocate a new save id.
+ const uint32_t save_id = GetNextSavedRegistersID();
+ assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) &&
+ "GetNextRegisterSaveID() returned an existing register save id");
+
+ // Save the register data buffer under the save id.
+ {
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
+ m_saved_registers_map[save_id] = register_data_sp;
+ }
- // Write the response.
- StreamGDBRemote response;
- response.Printf ("%" PRIu32, save_id);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ // Write the response.
+ StreamGDBRemote response;
+ response.Printf("%" PRIu32, save_id);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Parse out save id.
- packet.SetFilePos (strlen ("QRestoreRegisterState:"));
- if (packet.GetBytesLeft () < 1)
- return SendIllFormedResponse (packet, "QRestoreRegisterState packet missing register save id");
-
- const uint32_t save_id = packet.GetU32 (0);
- if (save_id == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState packet has malformed save id, expecting decimal uint32_t", __FUNCTION__);
- return SendErrorResponse (0x76);
- }
+GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Parse out save id.
+ packet.SetFilePos(strlen("QRestoreRegisterState:"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "QRestoreRegisterState packet missing register save id");
+
+ const uint32_t save_id = packet.GetU32(0);
+ if (save_id == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState "
+ "packet has malformed save id, expecting decimal uint32_t",
+ __FUNCTION__);
+ return SendErrorResponse(0x76);
+ }
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (m_thread_suffix_supported)
+ return SendIllFormedResponse(
+ packet, "No thread specified in QRestoreRegisterState packet");
+ else
+ return SendIllFormedResponse(packet,
+ "No thread was is set with the Hg packet");
+ }
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (m_thread_suffix_supported)
- return SendIllFormedResponse (packet, "No thread specified in QRestoreRegisterState packet");
- else
- return SendIllFormedResponse (packet, "No thread was is set with the Hg packet");
- }
+ // Grab the register context for the thread.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ // Retrieve register state buffer, then remove from the list.
+ DataBufferSP register_data_sp;
+ {
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
- // Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
+ // Find the register set buffer for the given save id.
+ auto it = m_saved_registers_map.find(save_id);
+ if (it == m_saved_registers_map.end()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " does not have a register set save buffer for id %" PRIu32,
+ __FUNCTION__, m_debugged_process_sp->GetID(), save_id);
+ return SendErrorResponse(0x77);
}
+ register_data_sp = it->second;
- // Retrieve register state buffer, then remove from the list.
- DataBufferSP register_data_sp;
- {
- std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
-
- // Find the register set buffer for the given save id.
- auto it = m_saved_registers_map.find (save_id);
- if (it == m_saved_registers_map.end ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " does not have a register set save buffer for id %" PRIu32, __FUNCTION__, m_debugged_process_sp->GetID (), save_id);
- return SendErrorResponse (0x77);
- }
- register_data_sp = it->second;
-
- // Remove it from the map.
- m_saved_registers_map.erase (it);
- }
+ // Remove it from the map.
+ m_saved_registers_map.erase(it);
+ }
- Error error = reg_context_sp->WriteAllRegisterValues (register_data_sp);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to restore all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x77);
- }
+ Error error = reg_context_sp->WriteAllRegisterValues(register_data_sp);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to restore all register values: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x77);
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vAttach (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Consume the ';' after vAttach.
- packet.SetFilePos (strlen ("vAttach"));
- if (!packet.GetBytesLeft () || packet.GetChar () != ';')
- return SendIllFormedResponse (packet, "vAttach missing expected ';'");
-
- // Grab the PID to which we will attach (assume hex encoding).
- lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16);
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendIllFormedResponse (packet, "vAttach failed to parse the process id");
-
- // Attempt to attach.
+GDBRemoteCommunicationServerLLGS::Handle_vAttach(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Consume the ';' after vAttach.
+ packet.SetFilePos(strlen("vAttach"));
+ if (!packet.GetBytesLeft() || packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "vAttach missing expected ';'");
+
+ // Grab the PID to which we will attach (assume hex encoding).
+ lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendIllFormedResponse(packet,
+ "vAttach failed to parse the process id");
+
+ // Attempt to attach.
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
+ "pid %" PRIu64,
+ __FUNCTION__, pid);
+
+ Error error = AttachToProcess(pid);
+
+ if (error.Fail()) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s attempting to attach to pid %" PRIu64, __FUNCTION__, pid);
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, pid, error.AsCString());
+ return SendErrorResponse(0x01);
+ }
- Error error = AttachToProcess (pid);
-
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to attach to pid %" PRIu64 ": %s\n", __FUNCTION__, pid, error.AsCString());
- return SendErrorResponse (0x01);
- }
-
- // Notify we attached by sending a stop packet.
- return SendStopReasonForState (m_debugged_process_sp->GetState ());
+ // Notify we attached by sending a stop packet.
+ return SendStopReasonForState(m_debugged_process_sp->GetState());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- StopSTDIOForwarding();
+ StopSTDIOForwarding();
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-
- // Consume the ';' after D.
- packet.SetFilePos (1);
- if (packet.GetBytesLeft ())
- {
- if (packet.GetChar () != ';')
- return SendIllFormedResponse (packet, "D missing expected ';'");
-
- // Grab the PID from which we will detach (assume hex encoding).
- pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16);
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendIllFormedResponse (packet, "D failed to parse the process id");
- }
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+ // Consume the ';' after D.
+ packet.SetFilePos(1);
+ if (packet.GetBytesLeft()) {
+ if (packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "D missing expected ';'");
+
+ // Grab the PID from which we will detach (assume hex encoding).
+ pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendIllFormedResponse(packet, "D failed to parse the process id");
+ }
- if (pid != LLDB_INVALID_PROCESS_ID &&
- m_debugged_process_sp->GetID () != pid)
- {
- return SendIllFormedResponse (packet, "Invalid pid");
- }
+ if (pid != LLDB_INVALID_PROCESS_ID && m_debugged_process_sp->GetID() != pid) {
+ return SendIllFormedResponse(packet, "Invalid pid");
+ }
- const Error error = m_debugged_process_sp->Detach ();
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to detach from pid %" PRIu64 ": %s\n",
- __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x01);
- }
+ const Error error = m_debugged_process_sp->Detach();
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x01);
+ }
- return SendOKResponse ();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- packet.SetFilePos (strlen("qThreadStopInfo"));
- const lldb::tid_t tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID);
- if (tid == LLDB_INVALID_THREAD_ID)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse thread id from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
- return SendErrorResponse (0x15);
- }
- return SendStopReplyPacketForThread (tid);
+GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ packet.SetFilePos(strlen("qThreadStopInfo"));
+ const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+ if (tid == LLDB_INVALID_THREAD_ID) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse thread id from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return SendErrorResponse(0x15);
+ }
+ return SendStopReplyPacketForThread(tid);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo (StringExtractorGDBRemote &)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
-
- // Ensure we have a debugged process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (50);
-
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64,
+GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
+ StringExtractorGDBRemote &) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+ // Ensure we have a debugged process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(50);
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid "
+ "%" PRIu64,
__FUNCTION__, m_debugged_process_sp->GetID());
+ StreamString response;
+ const bool threads_with_valid_stop_info_only = false;
+ JSONArray::SP threads_array_sp = GetJSONThreadsInfo(
+ *m_debugged_process_sp, threads_with_valid_stop_info_only);
+ if (!threads_array_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a "
+ "packet for pid %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
+ return SendErrorResponse(52);
+ }
- StreamString response;
- const bool threads_with_valid_stop_info_only = false;
- JSONArray::SP threads_array_sp = GetJSONThreadsInfo(*m_debugged_process_sp,
- threads_with_valid_stop_info_only);
- if (! threads_array_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a packet for pid %" PRIu64,
- __FUNCTION__, m_debugged_process_sp->GetID());
- return SendErrorResponse(52);
- }
-
- threads_array_sp->Write(response);
- StreamGDBRemote escaped_response;
- escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
- return SendPacketNoLock (escaped_response.GetData(), escaped_response.GetSize());
+ threads_array_sp->Write(response);
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp ||
- m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse (68);
-
- packet.SetFilePos(strlen("qWatchpointSupportInfo"));
- if (packet.GetBytesLeft() == 0)
- return SendOKResponse();
- if (packet.GetChar() != ':')
- return SendErrorResponse(67);
+GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(68);
+
+ packet.SetFilePos(strlen("qWatchpointSupportInfo"));
+ if (packet.GetBytesLeft() == 0)
+ return SendOKResponse();
+ if (packet.GetChar() != ':')
+ return SendErrorResponse(67);
- uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
- StreamGDBRemote response;
- response.Printf ("num:%d;", num);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
+ StreamGDBRemote response;
+ response.Printf("num:%d;", num);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp ||
- m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse(67);
+GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(67);
- packet.SetFilePos(strlen("qFileLoadAddress:"));
- if (packet.GetBytesLeft() == 0)
- return SendErrorResponse(68);
+ packet.SetFilePos(strlen("qFileLoadAddress:"));
+ if (packet.GetBytesLeft() == 0)
+ return SendErrorResponse(68);
- std::string file_name;
- packet.GetHexByteString(file_name);
+ std::string file_name;
+ packet.GetHexByteString(file_name);
- lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
- Error error = m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address);
- if (error.Fail())
- return SendErrorResponse(69);
+ lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
+ Error error =
+ m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address);
+ if (error.Fail())
+ return SendErrorResponse(69);
- if (file_load_address == LLDB_INVALID_ADDRESS)
- return SendErrorResponse(1); // File not loaded
+ if (file_load_address == LLDB_INVALID_ADDRESS)
+ return SendErrorResponse(1); // File not loaded
- StreamGDBRemote response;
- response.PutHex64(file_load_address);
- return SendPacketNoLock(response.GetData(), response.GetSize());
-}
-
-void
-GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection ()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Tell the stdio connection to shut down.
- if (m_stdio_communication.IsConnected())
- {
- auto connection = m_stdio_communication.GetConnection();
- if (connection)
- {
- Error error;
- connection->Disconnect (&error);
-
- if (error.Success ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - SUCCESS", __FUNCTION__);
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - FAIL: %s", __FUNCTION__, error.AsCString ());
- }
- }
- }
+ StreamGDBRemote response;
+ response.PutHex64(file_load_address);
+ return SendPacketNoLock(response.GetString());
}
+void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-NativeThreadProtocolSP
-GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix (StringExtractorGDBRemote &packet)
-{
- NativeThreadProtocolSP thread_sp;
+ // Tell the stdio connection to shut down.
+ if (m_stdio_communication.IsConnected()) {
+ auto connection = m_stdio_communication.GetConnection();
+ if (connection) {
+ Error error;
+ connection->Disconnect(&error);
- // We have no thread if we don't have a process.
- if (!m_debugged_process_sp || m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
- return thread_sp;
-
- // If the client hasn't asked for thread suffix support, there will not be a thread suffix.
- // Use the current thread in that case.
- if (!m_thread_suffix_supported)
- {
- const lldb::tid_t current_tid = GetCurrentThreadID ();
- if (current_tid == LLDB_INVALID_THREAD_ID)
- return thread_sp;
- else if (current_tid == 0)
- {
- // Pick a thread.
- return m_debugged_process_sp->GetThreadAtIndex (0);
- }
- else
- return m_debugged_process_sp->GetThreadByID (current_tid);
+ if (error.Success()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - SUCCESS",
+ __FUNCTION__);
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - FAIL: %s",
+ __FUNCTION__, error.AsCString());
+ }
}
+ }
+}
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
+ StringExtractorGDBRemote &packet) {
+ NativeThreadProtocolSP thread_sp;
- // Parse out the ';'.
- if (packet.GetBytesLeft () < 1 || packet.GetChar () != ';')
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected ';' prior to start of thread suffix: packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
- return thread_sp;
- }
+ // We have no thread if we don't have a process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+ return thread_sp;
- if (!packet.GetBytesLeft ())
- return thread_sp;
+ // If the client hasn't asked for thread suffix support, there will not be a
+ // thread suffix.
+ // Use the current thread in that case.
+ if (!m_thread_suffix_supported) {
+ const lldb::tid_t current_tid = GetCurrentThreadID();
+ if (current_tid == LLDB_INVALID_THREAD_ID)
+ return thread_sp;
+ else if (current_tid == 0) {
+ // Pick a thread.
+ return m_debugged_process_sp->GetThreadAtIndex(0);
+ } else
+ return m_debugged_process_sp->GetThreadByID(current_tid);
+ }
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Parse out the ';'.
+ if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected ';' prior to start of thread suffix: packet "
+ "contents = '%s'",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return thread_sp;
+ }
- // Parse out thread: portion.
- if (strncmp (packet.Peek (), "thread:", strlen("thread:")) != 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected 'thread:' but not found, packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
- return thread_sp;
- }
- packet.SetFilePos (packet.GetFilePos () + strlen("thread:"));
- const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
- if (tid != 0)
- return m_debugged_process_sp->GetThreadByID (tid);
+ if (!packet.GetBytesLeft())
+ return thread_sp;
+ // Parse out thread: portion.
+ if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected 'thread:' but not found, packet contents = "
+ "'%s'",
+ __FUNCTION__, packet.GetStringRef().c_str());
return thread_sp;
+ }
+ packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
+ const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
+ if (tid != 0)
+ return m_debugged_process_sp->GetThreadByID(tid);
+
+ return thread_sp;
}
-lldb::tid_t
-GDBRemoteCommunicationServerLLGS::GetCurrentThreadID () const
-{
- if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID)
- {
- // Use whatever the debug process says is the current thread id
- // since the protocol either didn't specify or specified we want
- // any/all threads marked as the current thread.
- if (!m_debugged_process_sp)
- return LLDB_INVALID_THREAD_ID;
- return m_debugged_process_sp->GetCurrentThreadID ();
- }
- // Use the specific current thread id set by the gdb remote protocol.
- return m_current_tid;
+lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
+ if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) {
+ // Use whatever the debug process says is the current thread id
+ // since the protocol either didn't specify or specified we want
+ // any/all threads marked as the current thread.
+ if (!m_debugged_process_sp)
+ return LLDB_INVALID_THREAD_ID;
+ return m_debugged_process_sp->GetCurrentThreadID();
+ }
+ // Use the specific current thread id set by the gdb remote protocol.
+ return m_current_tid;
}
-uint32_t
-GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID ()
-{
- std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
- return m_next_saved_registers_id++;
+uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() {
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
+ return m_next_saved_registers_id++;
}
-void
-GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData ()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__);
+void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__);
- // Clear any auxv cached data.
- // *BSD impls should be able to do this too.
+// Clear any auxv cached data.
+// *BSD impls should be able to do this too.
#if defined(__linux__)
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer (previously %s)",
- __FUNCTION__,
- m_active_auxv_buffer_sp ? "was set" : "was not set");
- m_active_auxv_buffer_sp.reset ();
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer "
+ "(previously %s)",
+ __FUNCTION__,
+ m_active_auxv_buffer_sp ? "was set" : "was not set");
+ m_active_auxv_buffer_sp.reset();
#endif
}
FileSpec
-GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string& module_path,
- const ArchSpec& arch)
-{
- if (m_debugged_process_sp)
- {
- FileSpec file_spec;
- if (m_debugged_process_sp->GetLoadedModuleFileSpec(module_path.c_str(), file_spec).Success())
- {
- if (file_spec.Exists())
- return file_spec;
- }
- }
-
- return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
+GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
+ const ArchSpec &arch) {
+ if (m_debugged_process_sp) {
+ FileSpec file_spec;
+ if (m_debugged_process_sp
+ ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
+ .Success()) {
+ if (file_spec.Exists())
+ return file_spec;
+ }
+ }
+
+ return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index caf6eb319e63..fa52cdaab493 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -16,10 +16,10 @@
#include <unordered_map>
// Other libraries and framework includes
-#include "lldb/lldb-private-forward.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/MainLoop.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/lldb-private-forward.h"
// Project includes
#include "GDBRemoteCommunicationServerCommon.h"
@@ -32,282 +32,220 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class GDBRemoteCommunicationServerLLGS :
- public GDBRemoteCommunicationServerCommon,
- public NativeProcessProtocol::NativeDelegate
-{
+class GDBRemoteCommunicationServerLLGS
+ : public GDBRemoteCommunicationServerCommon,
+ public NativeProcessProtocol::NativeDelegate {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
-
- //------------------------------------------------------------------
- /// Specify the program to launch and its arguments.
- ///
- /// @param[in] args
- /// The command line to launch.
- ///
- /// @param[in] argc
- /// The number of elements in the args array of cstring pointers.
- ///
- /// @return
- /// An Error object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Error
- SetLaunchArguments (const char *const args[], int argc);
-
- //------------------------------------------------------------------
- /// Specify the launch flags for the process.
- ///
- /// @param[in] launch_flags
- /// The launch flags to use when launching this process.
- ///
- /// @return
- /// An Error object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Error
- SetLaunchFlags (unsigned int launch_flags);
-
- //------------------------------------------------------------------
- /// Launch a process with the current launch settings.
- ///
- /// This method supports running an lldb-gdbserver or similar
- /// server in a situation where the startup code has been provided
- /// with all the information for a child process to be launched.
- ///
- /// @return
- /// An Error object indicating the success or failure of the
- /// launch.
- //------------------------------------------------------------------
- Error
- LaunchProcess () override;
-
- //------------------------------------------------------------------
- /// Attach to a process.
- ///
- /// This method supports attaching llgs to a process accessible via the
- /// configured Platform.
- ///
- /// @return
- /// An Error object indicating the success or failure of the
- /// attach operation.
- //------------------------------------------------------------------
- Error
- AttachToProcess (lldb::pid_t pid);
-
- //------------------------------------------------------------------
- // NativeProcessProtocol::NativeDelegate overrides
- //------------------------------------------------------------------
- void
- InitializeDelegate (NativeProcessProtocol *process) override;
-
- void
- ProcessStateChanged (NativeProcessProtocol *process, lldb::StateType state) override;
-
- void
- DidExec (NativeProcessProtocol *process) override;
-
- Error
- InitializeConnection (std::unique_ptr<Connection> &&connection);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
+
+ //------------------------------------------------------------------
+ /// Specify the program to launch and its arguments.
+ ///
+ /// @param[in] args
+ /// The command line to launch.
+ ///
+ /// @param[in] argc
+ /// The number of elements in the args array of cstring pointers.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of making
+ /// the setting.
+ //------------------------------------------------------------------
+ Error SetLaunchArguments(const char *const args[], int argc);
+
+ //------------------------------------------------------------------
+ /// Specify the launch flags for the process.
+ ///
+ /// @param[in] launch_flags
+ /// The launch flags to use when launching this process.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of making
+ /// the setting.
+ //------------------------------------------------------------------
+ Error SetLaunchFlags(unsigned int launch_flags);
+
+ //------------------------------------------------------------------
+ /// Launch a process with the current launch settings.
+ ///
+ /// This method supports running an lldb-gdbserver or similar
+ /// server in a situation where the startup code has been provided
+ /// with all the information for a child process to be launched.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of the
+ /// launch.
+ //------------------------------------------------------------------
+ Error LaunchProcess() override;
+
+ //------------------------------------------------------------------
+ /// Attach to a process.
+ ///
+ /// This method supports attaching llgs to a process accessible via the
+ /// configured Platform.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of the
+ /// attach operation.
+ //------------------------------------------------------------------
+ Error AttachToProcess(lldb::pid_t pid);
+
+ //------------------------------------------------------------------
+ // NativeProcessProtocol::NativeDelegate overrides
+ //------------------------------------------------------------------
+ void InitializeDelegate(NativeProcessProtocol *process) override;
+
+ void ProcessStateChanged(NativeProcessProtocol *process,
+ lldb::StateType state) override;
+
+ void DidExec(NativeProcessProtocol *process) override;
+
+ Error InitializeConnection(std::unique_ptr<Connection> &&connection);
protected:
- MainLoop &m_mainloop;
- MainLoop::ReadHandleUP m_network_handle_up;
- lldb::tid_t m_current_tid;
- lldb::tid_t m_continue_tid;
- std::recursive_mutex m_debugged_process_mutex;
- NativeProcessProtocolSP m_debugged_process_sp;
+ MainLoop &m_mainloop;
+ MainLoop::ReadHandleUP m_network_handle_up;
+ lldb::tid_t m_current_tid;
+ lldb::tid_t m_continue_tid;
+ std::recursive_mutex m_debugged_process_mutex;
+ NativeProcessProtocolSP m_debugged_process_sp;
- Communication m_stdio_communication;
- MainLoop::ReadHandleUP m_stdio_handle_up;
+ Communication m_stdio_communication;
+ MainLoop::ReadHandleUP m_stdio_handle_up;
- lldb::StateType m_inferior_prev_state;
- lldb::DataBufferSP m_active_auxv_buffer_sp;
- std::mutex m_saved_registers_mutex;
- std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
- uint32_t m_next_saved_registers_id;
- bool m_handshake_completed : 1;
+ lldb::StateType m_inferior_prev_state;
+ lldb::DataBufferSP m_active_auxv_buffer_sp;
+ std::mutex m_saved_registers_mutex;
+ std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
+ uint32_t m_next_saved_registers_id;
+ bool m_handshake_completed : 1;
- PacketResult
- SendONotification (const char *buffer, uint32_t len);
+ PacketResult SendONotification(const char *buffer, uint32_t len);
- PacketResult
- SendWResponse (NativeProcessProtocol *process);
+ PacketResult SendWResponse(NativeProcessProtocol *process);
- PacketResult
- SendStopReplyPacketForThread (lldb::tid_t tid);
+ PacketResult SendStopReplyPacketForThread(lldb::tid_t tid);
- PacketResult
- SendStopReasonForState (lldb::StateType process_state);
+ PacketResult SendStopReasonForState(lldb::StateType process_state);
- PacketResult
- Handle_k (StringExtractorGDBRemote &packet);
+ PacketResult Handle_k(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qC (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qC(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetDisableASLR(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_C (StringExtractorGDBRemote &packet);
+ PacketResult Handle_C(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_c (StringExtractorGDBRemote &packet);
+ PacketResult Handle_c(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vCont (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vCont(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vCont_actions (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vCont_actions(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_stop_reason (StringExtractorGDBRemote &packet);
+ PacketResult Handle_stop_reason(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qRegisterInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qRegisterInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qfThreadInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qfThreadInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qsThreadInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_p (StringExtractorGDBRemote &packet);
+ PacketResult Handle_p(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_P (StringExtractorGDBRemote &packet);
+ PacketResult Handle_P(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_H (StringExtractorGDBRemote &packet);
+ PacketResult Handle_H(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_I (StringExtractorGDBRemote &packet);
+ PacketResult Handle_I(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_interrupt (StringExtractorGDBRemote &packet);
+ PacketResult Handle_interrupt(StringExtractorGDBRemote &packet);
- // Handles $m and $x packets.
- PacketResult
- Handle_memory_read (StringExtractorGDBRemote &packet);
+ // Handles $m and $x packets.
+ PacketResult Handle_memory_read(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_M (StringExtractorGDBRemote &packet);
+ PacketResult Handle_M(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet);
+ PacketResult
+ Handle_qMemoryRegionInfoSupported(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qMemoryRegionInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_Z (StringExtractorGDBRemote &packet);
+ PacketResult Handle_Z(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_z (StringExtractorGDBRemote &packet);
+ PacketResult Handle_z(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_s (StringExtractorGDBRemote &packet);
+ PacketResult Handle_s(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qXfer_auxv_read(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSaveRegisterState (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vAttach (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_D (StringExtractorGDBRemote &packet);
+ PacketResult Handle_D(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qThreadStopInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_jThreadsInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_jThreadsInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qWatchpointSupportInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qFileLoadAddress (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qFileLoadAddress(StringExtractorGDBRemote &packet);
- void
- SetCurrentThreadID (lldb::tid_t tid);
+ void SetCurrentThreadID(lldb::tid_t tid);
- lldb::tid_t
- GetCurrentThreadID () const;
+ lldb::tid_t GetCurrentThreadID() const;
- void
- SetContinueThreadID (lldb::tid_t tid);
+ void SetContinueThreadID(lldb::tid_t tid);
- lldb::tid_t
- GetContinueThreadID () const { return m_continue_tid; }
+ lldb::tid_t GetContinueThreadID() const { return m_continue_tid; }
- Error
- SetSTDIOFileDescriptor (int fd);
+ Error SetSTDIOFileDescriptor(int fd);
- FileSpec
- FindModuleFile (const std::string& module_path, const ArchSpec& arch) override;
+ FileSpec FindModuleFile(const std::string &module_path,
+ const ArchSpec &arch) override;
private:
- void
- HandleInferiorState_Exited (NativeProcessProtocol *process);
+ void HandleInferiorState_Exited(NativeProcessProtocol *process);
- void
- HandleInferiorState_Stopped (NativeProcessProtocol *process);
+ void HandleInferiorState_Stopped(NativeProcessProtocol *process);
- NativeThreadProtocolSP
- GetThreadFromSuffix (StringExtractorGDBRemote &packet);
+ NativeThreadProtocolSP GetThreadFromSuffix(StringExtractorGDBRemote &packet);
- uint32_t
- GetNextSavedRegistersID ();
+ uint32_t GetNextSavedRegistersID();
- void
- MaybeCloseInferiorTerminalConnection ();
+ void MaybeCloseInferiorTerminalConnection();
- void
- ClearProcessSpecificData ();
+ void ClearProcessSpecificData();
- void
- RegisterPacketHandlers ();
+ void RegisterPacketHandlers();
- void
- DataAvailableCallback ();
+ void DataAvailableCallback();
- void
- SendProcessOutput ();
+ void SendProcessOutput();
- void
- StartSTDIOForwarding();
+ void StartSTDIOForwarding();
- void
- StopSTDIOForwarding();
+ void StopSTDIOForwarding();
- //------------------------------------------------------------------
- // For GDBRemoteCommunicationServerLLGS only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerLLGS);
+ //------------------------------------------------------------------
+ // For GDBRemoteCommunicationServerLLGS only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerLLGS);
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_
+#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index d6900c27293c..11069749186a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -13,8 +13,8 @@
// C Includes
// C++ Includes
-#include <cstring>
#include <chrono>
+#include <cstring>
#include <mutex>
#include <sstream>
@@ -47,549 +47,525 @@ using namespace lldb_private::process_gdb_remote;
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerPlatform constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,
- const char *socket_scheme)
- : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
- m_socket_protocol(socket_protocol),
- m_socket_scheme(socket_scheme),
- m_spawned_pids_mutex(),
- m_port_map(),
- m_port_offset(0)
-{
- m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
- m_pending_gdb_server.port = 0;
-
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
- &GDBRemoteCommunicationServerPlatform::Handle_qC);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
- &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
- &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
- &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
- &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
- &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
- &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
- &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
-
- RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
- [this](StringExtractorGDBRemote packet, Error &error, bool &interrupt, bool &quit) {
- error.SetErrorString("interrupt received");
- interrupt = true;
- return PacketResult::Success;
- });
+GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
+ const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
+ : GDBRemoteCommunicationServerCommon("gdb-remote.server",
+ "gdb-remote.server.rx_packet"),
+ m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
+ m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
+ m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
+ m_pending_gdb_server.port = 0;
+
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qC,
+ &GDBRemoteCommunicationServerPlatform::Handle_qC);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
+ &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
+ &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
+ &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
+ &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
+ &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
+ &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
+ &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
+
+ RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
+ [this](StringExtractorGDBRemote packet, Error &error,
+ bool &interrupt, bool &quit) {
+ error.SetErrorString("interrupt received");
+ interrupt = true;
+ return PacketResult::Success;
+ });
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform()
-{
-}
-
-Error
-GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args& args,
- std::string hostname,
- lldb::pid_t& pid,
- uint16_t& port,
- std::string& socket_name)
-{
- if (port == UINT16_MAX)
- port = GetNextAvailablePort();
-
- // Spawn a new thread to accept the port that gets bound after
- // binding to port 0 (zero).
-
- // ignore the hostname send from the remote end, just use the ip address
- // that we're currently communicating with as the hostname
-
- // Spawn a debugserver and try to get the port it listens to.
- ProcessLaunchInfo debugserver_launch_info;
- if (hostname.empty())
- hostname = "127.0.0.1";
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
-
- // Do not run in a new session so that it can not linger after the
- // platform closes.
- debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
- debugserver_launch_info.SetMonitorProcessCallback(
- std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1), false);
-
- std::string platform_scheme;
- std::string platform_ip;
- int platform_port;
- std::string platform_path;
- bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
- UNUSED_IF_ASSERT_DISABLED(ok);
- assert(ok);
-
- std::ostringstream url;
- // debugserver does not accept the URL scheme prefix.
+GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
+
+Error GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
+ const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
+ uint16_t &port, std::string &socket_name) {
+ if (port == UINT16_MAX)
+ port = GetNextAvailablePort();
+
+ // Spawn a new thread to accept the port that gets bound after
+ // binding to port 0 (zero).
+
+ // ignore the hostname send from the remote end, just use the ip address
+ // that we're currently communicating with as the hostname
+
+ // Spawn a debugserver and try to get the port it listens to.
+ ProcessLaunchInfo debugserver_launch_info;
+ if (hostname.empty())
+ hostname = "127.0.0.1";
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
+
+ // Do not run in a new session so that it can not linger after the
+ // platform closes.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
+ debugserver_launch_info.SetMonitorProcessCallback(
+ std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
+ this, std::placeholders::_1),
+ false);
+
+ llvm::StringRef platform_scheme;
+ llvm::StringRef platform_ip;
+ int platform_port;
+ llvm::StringRef platform_path;
+ bool ok = UriParser::Parse(GetConnection()->GetURI(), platform_scheme,
+ platform_ip, platform_port, platform_path);
+ UNUSED_IF_ASSERT_DISABLED(ok);
+ assert(ok);
+
+ std::ostringstream url;
+// debugserver does not accept the URL scheme prefix.
#if !defined(__APPLE__)
- url << m_socket_scheme << "://";
+ url << m_socket_scheme << "://";
#endif
- uint16_t* port_ptr = &port;
- if (m_socket_protocol == Socket::ProtocolTcp)
- url << platform_ip << ":" << port;
- else
- {
- socket_name = GetDomainSocketPath("gdbserver").GetPath();
- url << socket_name;
- port_ptr = nullptr;
- }
-
- Error error = StartDebugserverProcess (url.str().c_str(),
- nullptr,
- debugserver_launch_info,
- port_ptr,
- args);
-
- pid = debugserver_launch_info.GetProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- m_spawned_pids.insert(pid);
- if (port > 0)
- AssociatePortWithProcess(port, pid);
- }
- else
- {
- if (port > 0)
- FreePort(port);
- }
- return error;
+ uint16_t *port_ptr = &port;
+ if (m_socket_protocol == Socket::ProtocolTcp)
+ url << platform_ip.str() << ":" << port;
+ else {
+ socket_name = GetDomainSocketPath("gdbserver").GetPath();
+ url << socket_name;
+ port_ptr = nullptr;
+ }
+
+ Error error = StartDebugserverProcess(
+ url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
+
+ pid = debugserver_launch_info.GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ m_spawned_pids.insert(pid);
+ if (port > 0)
+ AssociatePortWithProcess(port, pid);
+ } else {
+ if (port > 0)
+ FreePort(port);
+ }
+ return error;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
+ StringExtractorGDBRemote &packet) {
#ifdef _WIN32
- return SendErrorResponse(9);
+ return SendErrorResponse(9);
#else
- // Spawn a local debugserver as a platform so we can then attach or launch
- // a process...
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ // Spawn a local debugserver as a platform so we can then attach or launch
+ // a process...
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
+ __FUNCTION__);
+
+ ConnectionFileDescriptor file_conn;
+ std::string hostname;
+ packet.SetFilePos(::strlen("qLaunchGDBServer;"));
+ llvm::StringRef name;
+ llvm::StringRef value;
+ uint16_t port = UINT16_MAX;
+ while (packet.GetNameColonValue(name, value)) {
+ if (name.equals("host"))
+ hostname = value;
+ else if (name.equals("port"))
+ value.getAsInteger(0, port);
+ }
+
+ lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ std::string socket_name;
+ Error error =
+ LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
+ if (error.Fail()) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__);
-
- ConnectionFileDescriptor file_conn;
- std::string hostname;
- packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
- std::string name;
- std::string value;
- uint16_t port = UINT16_MAX;
- while (packet.GetNameColonValue(name, value))
- {
- if (name.compare ("host") == 0)
- hostname.swap(value);
- else if (name.compare ("port") == 0)
- port = StringConvert::ToUInt32(value.c_str(), 0, 0);
- }
-
- lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
- std::string socket_name;
- Error error = LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
- if (error.Fail())
- {
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ());
- return SendErrorResponse(9);
- }
-
- if (log)
- log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);
-
- StreamGDBRemote response;
- response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
- if (!socket_name.empty())
- {
- response.PutCString("socket_name:");
- response.PutCStringAsRawHex8(socket_name.c_str());
- response.PutChar(';');
- }
-
- PacketResult packet_result = SendPacketNoLock(response.GetData(), response.GetSize());
- if (packet_result != PacketResult::Success)
- {
- if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
- ::kill (debugserver_pid, SIGINT);
- }
- return packet_result;
+ log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launch failed: %s",
+ __FUNCTION__, error.AsCString());
+ return SendErrorResponse(9);
+ }
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launched successfully as pid %" PRIu64,
+ __FUNCTION__, debugserver_pid);
+
+ StreamGDBRemote response;
+ response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
+ port + m_port_offset);
+ if (!socket_name.empty()) {
+ response.PutCString("socket_name:");
+ response.PutCStringAsRawHex8(socket_name.c_str());
+ response.PutChar(';');
+ }
+
+ PacketResult packet_result = SendPacketNoLock(response.GetString());
+ if (packet_result != PacketResult::Success) {
+ if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ ::kill(debugserver_pid, SIGINT);
+ }
+ return packet_result;
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer (StringExtractorGDBRemote &packet)
-{
- if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse(4);
-
- JSONObject::SP server_sp = std::make_shared<JSONObject>();
- server_sp->SetObject("port", std::make_shared<JSONNumber>(m_pending_gdb_server.port));
- if (!m_pending_gdb_server.socket_name.empty())
- server_sp->SetObject("socket_name",
- std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
-
- JSONArray server_list;
- server_list.AppendObject(server_sp);
-
- StreamGDBRemote response;
- server_list.Write(response);
-
- StreamGDBRemote escaped_response;
- escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
- return SendPacketNoLock(escaped_response.GetData(), escaped_response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
+ StringExtractorGDBRemote &packet) {
+ if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(4);
+
+ JSONObject::SP server_sp = std::make_shared<JSONObject>();
+ server_sp->SetObject("port",
+ std::make_shared<JSONNumber>(m_pending_gdb_server.port));
+ if (!m_pending_gdb_server.socket_name.empty())
+ server_sp->SetObject(
+ "socket_name",
+ std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
+
+ JSONArray server_list;
+ server_list.AppendObject(server_sp);
+
+ StreamGDBRemote response;
+ server_list.Write(response);
+
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetString().data(),
+ response.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
+GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
- lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
+ lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
- // verify that we know anything about this pid.
- // Scope for locker
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- {
- // not a pid we know about
- return SendErrorResponse (10);
- }
+ // verify that we know anything about this pid.
+ // Scope for locker
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+ // not a pid we know about
+ return SendErrorResponse(10);
}
+ }
- // go ahead and attempt to kill the spawned process
- if (KillSpawnedProcess (pid))
- return SendOKResponse ();
- else
- return SendErrorResponse (11);
+ // go ahead and attempt to kill the spawned process
+ if (KillSpawnedProcess(pid))
+ return SendOKResponse();
+ else
+ return SendErrorResponse(11);
}
-bool
-GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
-{
- // make sure we know about this process
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return false;
- }
+bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
+ // make sure we know about this process
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return false;
+ }
- // first try a SIGTERM (standard kill)
- Host::Kill (pid, SIGTERM);
+ // first try a SIGTERM (standard kill)
+ Host::Kill(pid, SIGTERM);
- // check if that worked
- for (size_t i=0; i<10; ++i)
+ // check if that worked
+ for (size_t i = 0; i < 10; ++i) {
{
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- {
- // it is now killed
- return true;
- }
- }
- usleep (10000);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+ // it is now killed
+ return true;
+ }
}
+ usleep(10000);
+ }
- // check one more time after the final usleep
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return true;
- }
+ // check one more time after the final usleep
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return true;
+ }
- // the launched process still lives. Now try killing it again,
- // this time with an unblockable signal.
- Host::Kill (pid, SIGKILL);
+ // the launched process still lives. Now try killing it again,
+ // this time with an unblockable signal.
+ Host::Kill(pid, SIGKILL);
- for (size_t i=0; i<10; ++i)
+ for (size_t i = 0; i < 10; ++i) {
{
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- {
- // it is now killed
- return true;
- }
- }
- usleep (10000);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+ // it is now killed
+ return true;
+ }
}
+ usleep(10000);
+ }
- // check one more time after the final usleep
- // Scope for locker
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return true;
- }
+ // check one more time after the final usleep
+ // Scope for locker
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return true;
+ }
- // no luck - the process still lives
- return false;
+ // no luck - the process still lives
+ return false;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
-{
- lldb::pid_t pid = m_process_launch_info.GetProcessID ();
- m_process_launch_info.Clear ();
+GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ lldb::pid_t pid = m_process_launch_info.GetProcessID();
+ m_process_launch_info.Clear();
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse (1);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(1);
- ProcessInstanceInfo proc_info;
- if (!Host::GetProcessInfo (pid, proc_info))
- return SendErrorResponse (1);
+ ProcessInstanceInfo proc_info;
+ if (!Host::GetProcessInfo(pid, proc_info))
+ return SendErrorResponse(1);
- StreamString response;
- CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ StreamString response;
+ CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
-{
- // If this packet is sent to a platform, then change the current working directory
-
- char cwd[PATH_MAX];
- if (getcwd(cwd, sizeof(cwd)) == NULL)
- return SendErrorResponse(errno);
-
- StreamString response;
- response.PutBytesAsRawHex8(cwd, strlen(cwd));
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ // If this packet is sent to a platform, then change the current working
+ // directory
+
+ char cwd[PATH_MAX];
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ return SendErrorResponse(errno);
+
+ StreamString response;
+ response.PutBytesAsRawHex8(cwd, strlen(cwd));
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos (::strlen ("QSetWorkingDir:"));
- std::string path;
- packet.GetHexByteString (path);
-
- // If this packet is sent to a platform, then change the current working directory
- if (::chdir(path.c_str()) != 0)
- return SendErrorResponse (errno);
- return SendOKResponse ();
+GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetWorkingDir:"));
+ std::string path;
+ packet.GetHexByteString(path);
+
+ // If this packet is sent to a platform, then change the current working
+ // directory
+ if (::chdir(path.c_str()) != 0)
+ return SendErrorResponse(errno);
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packet)
-{
- // NOTE: lldb should now be using qProcessInfo for process IDs. This path here
- // should not be used. It is reporting process id instead of thread id. The
- // correct answer doesn't seem to make much sense for lldb-platform.
- // CONSIDER: flip to "unsupported".
- lldb::pid_t pid = m_process_launch_info.GetProcessID();
-
- StreamString response;
- response.Printf("QC%" PRIx64, pid);
-
- // If we launch a process and this GDB server is acting as a platform,
- // then we need to clear the process launch state so we can start
- // launching another process. In order to launch a process a bunch or
- // packets need to be sent: environment packets, working directory,
- // disable ASLR, and many more settings. When we launch a process we
- // then need to know when to clear this information. Currently we are
- // selecting the 'qC' packet as that packet which seems to make the most
- // sense.
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- m_process_launch_info.Clear();
- }
-
- return SendPacketNoLock (response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_qC(
+ StringExtractorGDBRemote &packet) {
+ // NOTE: lldb should now be using qProcessInfo for process IDs. This path
+ // here
+ // should not be used. It is reporting process id instead of thread id. The
+ // correct answer doesn't seem to make much sense for lldb-platform.
+ // CONSIDER: flip to "unsupported".
+ lldb::pid_t pid = m_process_launch_info.GetProcessID();
+
+ StreamString response;
+ response.Printf("QC%" PRIx64, pid);
+
+ // If we launch a process and this GDB server is acting as a platform,
+ // then we need to clear the process launch state so we can start
+ // launching another process. In order to launch a process a bunch or
+ // packets need to be sent: environment packets, working directory,
+ // disable ASLR, and many more settings. When we launch a process we
+ // then need to know when to clear this information. Currently we are
+ // selecting the 'qC' packet as that packet which seems to make the most
+ // sense.
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ m_process_launch_info.Clear();
+ }
+
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet)
-{
- StructuredData::Array signal_array;
-
- const auto &signals = Host::GetUnixSignals();
- for (auto signo = signals->GetFirstSignalNumber();
- signo != LLDB_INVALID_SIGNAL_NUMBER;
- signo = signals->GetNextSignalNumber(signo))
- {
- auto dictionary = std::make_shared<StructuredData::Dictionary>();
-
- dictionary->AddIntegerItem("signo", signo);
- dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
-
- bool suppress, stop, notify;
- signals->GetSignalInfo(signo, suppress, stop, notify);
- dictionary->AddBooleanItem("suppress", suppress);
- dictionary->AddBooleanItem("stop", stop);
- dictionary->AddBooleanItem("notify", notify);
-
- signal_array.Push(dictionary);
- }
-
- StreamString response;
- signal_array.Dump(response);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
+ StringExtractorGDBRemote &packet) {
+ StructuredData::Array signal_array;
+
+ const auto &signals = Host::GetUnixSignals();
+ for (auto signo = signals->GetFirstSignalNumber();
+ signo != LLDB_INVALID_SIGNAL_NUMBER;
+ signo = signals->GetNextSignalNumber(signo)) {
+ auto dictionary = std::make_shared<StructuredData::Dictionary>();
+
+ dictionary->AddIntegerItem("signo", signo);
+ dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
+
+ bool suppress, stop, notify;
+ signals->GetSignalInfo(signo, suppress, stop, notify);
+ dictionary->AddBooleanItem("suppress", suppress);
+ dictionary->AddBooleanItem("stop", stop);
+ dictionary->AddBooleanItem("notify", notify);
+
+ signal_array.Push(dictionary);
+ }
+
+ StreamString response;
+ signal_array.Dump(response);
+ return SendPacketNoLock(response.GetString());
}
-bool
-GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid)
-{
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- FreePortForProcess(pid);
- m_spawned_pids.erase(pid);
- return true;
+bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
+ lldb::pid_t pid) {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ FreePortForProcess(pid);
+ m_spawned_pids.erase(pid);
+ return true;
}
-Error
-GDBRemoteCommunicationServerPlatform::LaunchProcess ()
-{
- if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
- return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
- // specify the process monitor if not already set. This should
- // generally be what happens since we need to reap started
- // processes.
- if (!m_process_launch_info.GetMonitorProcessCallback ())
- m_process_launch_info.SetMonitorProcessCallback(
- std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1),
- false);
-
- Error error = Host::LaunchProcess(m_process_launch_info);
- if (!error.Success ())
- {
- fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
- return error;
- }
+Error GDBRemoteCommunicationServerPlatform::LaunchProcess() {
+ if (!m_process_launch_info.GetArguments().GetArgumentCount())
+ return Error("%s: no process command line specified to launch",
+ __FUNCTION__);
+
+ // specify the process monitor if not already set. This should
+ // generally be what happens since we need to reap started
+ // processes.
+ if (!m_process_launch_info.GetMonitorProcessCallback())
+ m_process_launch_info.SetMonitorProcessCallback(
+ std::bind(
+ &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
+ this, std::placeholders::_1),
+ false);
+
+ Error error = Host::LaunchProcess(m_process_launch_info);
+ if (!error.Success()) {
+ fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
+ return error;
+ }
- printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
+ printf("Launched '%s' as process %" PRIu64 "...\n",
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
+ m_process_launch_info.GetProcessID());
- // add to list of spawned processes. On an lldb-gdbserver, we
- // would expect there to be only one.
- const auto pid = m_process_launch_info.GetProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- // add to spawned pids
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- m_spawned_pids.insert(pid);
- }
+ // add to list of spawned processes. On an lldb-gdbserver, we
+ // would expect there to be only one.
+ const auto pid = m_process_launch_info.GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ // add to spawned pids
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ m_spawned_pids.insert(pid);
+ }
- return error;
+ return error;
}
-void
-GDBRemoteCommunicationServerPlatform::SetPortMap (PortMap &&port_map)
-{
- m_port_map = port_map;
+void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
+ m_port_map = port_map;
}
-uint16_t
-GDBRemoteCommunicationServerPlatform::GetNextAvailablePort ()
-{
- if (m_port_map.empty())
- return 0; // Bind to port zero and get a port, we didn't have any limitations
+uint16_t GDBRemoteCommunicationServerPlatform::GetNextAvailablePort() {
+ if (m_port_map.empty())
+ return 0; // Bind to port zero and get a port, we didn't have any
+ // limitations
- for (auto &pair : m_port_map)
- {
- if (pair.second == LLDB_INVALID_PROCESS_ID)
- {
- pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
- return pair.first;
- }
+ for (auto &pair : m_port_map) {
+ if (pair.second == LLDB_INVALID_PROCESS_ID) {
+ pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
+ return pair.first;
}
- return UINT16_MAX;
+ }
+ return UINT16_MAX;
}
-bool
-GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess (uint16_t port, lldb::pid_t pid)
-{
- PortMap::iterator pos = m_port_map.find(port);
- if (pos != m_port_map.end())
- {
- pos->second = pid;
- return true;
- }
- return false;
+bool GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess(
+ uint16_t port, lldb::pid_t pid) {
+ PortMap::iterator pos = m_port_map.find(port);
+ if (pos != m_port_map.end()) {
+ pos->second = pid;
+ return true;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationServerPlatform::FreePort (uint16_t port)
-{
- PortMap::iterator pos = m_port_map.find(port);
- if (pos != m_port_map.end())
- {
- pos->second = LLDB_INVALID_PROCESS_ID;
- return true;
- }
- return false;
+bool GDBRemoteCommunicationServerPlatform::FreePort(uint16_t port) {
+ PortMap::iterator pos = m_port_map.find(port);
+ if (pos != m_port_map.end()) {
+ pos->second = LLDB_INVALID_PROCESS_ID;
+ return true;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationServerPlatform::FreePortForProcess (lldb::pid_t pid)
-{
- if (!m_port_map.empty())
- {
- for (auto &pair : m_port_map)
- {
- if (pair.second == pid)
- {
- pair.second = LLDB_INVALID_PROCESS_ID;
- return true;
- }
- }
+bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) {
+ if (!m_port_map.empty()) {
+ for (auto &pair : m_port_map) {
+ if (pair.second == pid) {
+ pair.second = LLDB_INVALID_PROCESS_ID;
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-const FileSpec&
-GDBRemoteCommunicationServerPlatform::GetDomainSocketDir()
-{
- static FileSpec g_domainsocket_dir;
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []() {
- const char* domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
- if (domainsocket_dir_env != nullptr)
- g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
- else
- HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
- });
-
- return g_domainsocket_dir;
+const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
+ static FileSpec g_domainsocket_dir;
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ const char *domainsocket_dir_env =
+ ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
+ if (domainsocket_dir_env != nullptr)
+ g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
+ else
+ HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
+ });
+
+ return g_domainsocket_dir;
}
FileSpec
-GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char* prefix)
-{
- llvm::SmallString<PATH_MAX> socket_path;
- llvm::SmallString<PATH_MAX> socket_name((llvm::StringRef(prefix) + ".%%%%%%").str());
+GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
+ llvm::SmallString<PATH_MAX> socket_path;
+ llvm::SmallString<PATH_MAX> socket_name(
+ (llvm::StringRef(prefix) + ".%%%%%%").str());
- FileSpec socket_path_spec(GetDomainSocketDir());
- socket_path_spec.AppendPathComponent(socket_name.c_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);
+ llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
+ return FileSpec(socket_path.c_str(), false);
}
-void
-GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset)
-{
- m_port_offset = port_offset;
+void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
+ m_port_offset = port_offset;
}
-void
-GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(lldb::pid_t pid,
- uint16_t port,
- const std::string& socket_name)
-{
- m_pending_gdb_server.pid = pid;
- m_pending_gdb_server.port = port;
- m_pending_gdb_server.socket_name = socket_name;
+void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
+ lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
+ m_pending_gdb_server.pid = pid;
+ m_pending_gdb_server.port = port;
+ m_pending_gdb_server.socket_name = socket_name;
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index 1f4d08c64e00..472d86e3a15c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -24,110 +24,90 @@
namespace lldb_private {
namespace process_gdb_remote {
-class GDBRemoteCommunicationServerPlatform :
- public GDBRemoteCommunicationServerCommon
-{
+class GDBRemoteCommunicationServerPlatform
+ : public GDBRemoteCommunicationServerCommon {
public:
- typedef std::map<uint16_t, lldb::pid_t> PortMap;
+ typedef std::map<uint16_t, lldb::pid_t> PortMap;
- GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,
- const char* socket_scheme);
+ GDBRemoteCommunicationServerPlatform(
+ const Socket::SocketProtocol socket_protocol, const char *socket_scheme);
- ~GDBRemoteCommunicationServerPlatform() override;
+ ~GDBRemoteCommunicationServerPlatform() override;
- Error
- LaunchProcess () override;
+ Error LaunchProcess() override;
- // Set both ports to zero to let the platform automatically bind to
- // a port chosen by the OS.
- void
- SetPortMap (PortMap &&port_map);
+ // Set both ports to zero to let the platform automatically bind to
+ // a port chosen by the OS.
+ void SetPortMap(PortMap &&port_map);
- //----------------------------------------------------------------------
- // If we are using a port map where we can only use certain ports,
- // get the next available port.
- //
- // If we are using a port map and we are out of ports, return UINT16_MAX
- //
- // If we aren't using a port map, return 0 to indicate we should bind to
- // port 0 and then figure out which port we used.
- //----------------------------------------------------------------------
- uint16_t
- GetNextAvailablePort ();
+ //----------------------------------------------------------------------
+ // If we are using a port map where we can only use certain ports,
+ // get the next available port.
+ //
+ // If we are using a port map and we are out of ports, return UINT16_MAX
+ //
+ // If we aren't using a port map, return 0 to indicate we should bind to
+ // port 0 and then figure out which port we used.
+ //----------------------------------------------------------------------
+ uint16_t GetNextAvailablePort();
- bool
- AssociatePortWithProcess (uint16_t port, lldb::pid_t pid);
+ bool AssociatePortWithProcess(uint16_t port, lldb::pid_t pid);
- bool
- FreePort (uint16_t port);
+ bool FreePort(uint16_t port);
- bool
- FreePortForProcess (lldb::pid_t pid);
+ bool FreePortForProcess(lldb::pid_t pid);
- void
- SetPortOffset (uint16_t port_offset);
+ void SetPortOffset(uint16_t port_offset);
- void
- SetInferiorArguments (const lldb_private::Args& args);
+ void SetInferiorArguments(const lldb_private::Args &args);
- Error
- LaunchGDBServer(const lldb_private::Args& args,
- std::string hostname,
- lldb::pid_t& pid,
- uint16_t& port,
- std::string& socket_name);
+ Error LaunchGDBServer(const lldb_private::Args &args, std::string hostname,
+ lldb::pid_t &pid, uint16_t &port,
+ std::string &socket_name);
- void
- SetPendingGdbServer(lldb::pid_t pid, uint16_t port, const std::string& socket_name);
+ void SetPendingGdbServer(lldb::pid_t pid, uint16_t port,
+ const std::string &socket_name);
protected:
- const Socket::SocketProtocol m_socket_protocol;
- const std::string m_socket_scheme;
- std::recursive_mutex m_spawned_pids_mutex;
- std::set<lldb::pid_t> m_spawned_pids;
+ const Socket::SocketProtocol m_socket_protocol;
+ const std::string m_socket_scheme;
+ std::recursive_mutex m_spawned_pids_mutex;
+ std::set<lldb::pid_t> m_spawned_pids;
- PortMap m_port_map;
- uint16_t m_port_offset;
- struct { lldb::pid_t pid; uint16_t port; std::string socket_name; } m_pending_gdb_server;
+ PortMap m_port_map;
+ uint16_t m_port_offset;
+ struct {
+ lldb::pid_t pid;
+ uint16_t port;
+ std::string socket_name;
+ } m_pending_gdb_server;
- PacketResult
- Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qLaunchGDBServer(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qQueryGDBServer (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qQueryGDBServer(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qKillSpawnedProcess(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qC (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qC(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
private:
- bool
- KillSpawnedProcess (lldb::pid_t pid);
+ bool KillSpawnedProcess(lldb::pid_t pid);
- bool
- DebugserverProcessReaped (lldb::pid_t pid);
+ bool DebugserverProcessReaped(lldb::pid_t pid);
- static const FileSpec&
- GetDomainSocketDir();
+ static const FileSpec &GetDomainSocketDir();
- static FileSpec
- GetDomainSocketPath(const char* prefix);
+ static FileSpec GetDomainSocketPath(const char *prefix);
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerPlatform);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerPlatform);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 57983c4979a6..27ce67ded783 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -21,12 +21,12 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/Utils.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
+#include "Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -35,1189 +35,953 @@ using namespace lldb_private::process_gdb_remote;
//----------------------------------------------------------------------
// GDBRemoteRegisterContext constructor
//----------------------------------------------------------------------
-GDBRemoteRegisterContext::GDBRemoteRegisterContext
-(
- ThreadGDBRemote &thread,
- uint32_t concrete_frame_idx,
- GDBRemoteDynamicRegisterInfo &reg_info,
- bool read_all_at_once
-) :
- RegisterContext (thread, concrete_frame_idx),
- m_reg_info (reg_info),
- m_reg_valid (),
- m_reg_data (),
- m_read_all_at_once (read_all_at_once)
-{
- // Resize our vector of bools to contain one bool for every register.
- // We will use these boolean values to know when a register value
- // is valid in m_reg_data.
- m_reg_valid.resize (reg_info.GetNumRegisters());
-
- // Make a heap based buffer that is big enough to store all registers
- DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0));
- m_reg_data.SetData (reg_data_sp);
- m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
+GDBRemoteRegisterContext::GDBRemoteRegisterContext(
+ ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
+ GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once)
+ : RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
+ m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once) {
+ // Resize our vector of bools to contain one bool for every register.
+ // We will use these boolean values to know when a register value
+ // is valid in m_reg_data.
+ m_reg_valid.resize(reg_info.GetNumRegisters());
+
+ // Make a heap based buffer that is big enough to store all registers
+ DataBufferSP reg_data_sp(
+ new DataBufferHeap(reg_info.GetRegisterDataByteSize(), 0));
+ m_reg_data.SetData(reg_data_sp);
+ m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteRegisterContext::~GDBRemoteRegisterContext()
-{
-}
+GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {}
-void
-GDBRemoteRegisterContext::InvalidateAllRegisters ()
-{
- SetAllRegisterValid (false);
+void GDBRemoteRegisterContext::InvalidateAllRegisters() {
+ SetAllRegisterValid(false);
}
-void
-GDBRemoteRegisterContext::SetAllRegisterValid (bool b)
-{
- std::vector<bool>::iterator pos, end = m_reg_valid.end();
- for (pos = m_reg_valid.begin(); pos != end; ++pos)
- *pos = b;
+void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
+ std::vector<bool>::iterator pos, end = m_reg_valid.end();
+ for (pos = m_reg_valid.begin(); pos != end; ++pos)
+ *pos = b;
}
-size_t
-GDBRemoteRegisterContext::GetRegisterCount ()
-{
- return m_reg_info.GetNumRegisters ();
+size_t GDBRemoteRegisterContext::GetRegisterCount() {
+ return m_reg_info.GetNumRegisters();
}
const RegisterInfo *
-GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg)
-{
- RegisterInfo* reg_info = m_reg_info.GetRegisterInfoAtIndex (reg);
-
- if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes)
- {
- const ArchSpec &arch = m_thread.GetProcess ()->GetTarget ().GetArchitecture ();
- uint8_t reg_size = UpdateDynamicRegisterSize (arch, reg_info);
- reg_info->byte_size = reg_size;
- }
- return reg_info;
+GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
+ RegisterInfo *reg_info = m_reg_info.GetRegisterInfoAtIndex(reg);
+
+ if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) {
+ const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
+ uint8_t reg_size = UpdateDynamicRegisterSize(arch, reg_info);
+ reg_info->byte_size = reg_size;
+ }
+ return reg_info;
}
-size_t
-GDBRemoteRegisterContext::GetRegisterSetCount ()
-{
- return m_reg_info.GetNumRegisterSets ();
+size_t GDBRemoteRegisterContext::GetRegisterSetCount() {
+ return m_reg_info.GetNumRegisterSets();
}
-
-
-const RegisterSet *
-GDBRemoteRegisterContext::GetRegisterSet (size_t reg_set)
-{
- return m_reg_info.GetRegisterSet (reg_set);
+const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
+ return m_reg_info.GetRegisterSet(reg_set);
}
+bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ // Read the register
+ if (ReadRegisterBytes(reg_info, m_reg_data)) {
+ const bool partial_data_ok = false;
+ Error error(value.SetValueFromData(reg_info, m_reg_data,
+ reg_info->byte_offset, partial_data_ok));
+ return error.Success();
+ }
+ return false;
+}
-
-bool
-GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- // Read the register
- if (ReadRegisterBytes (reg_info, m_reg_data))
- {
- const bool partial_data_ok = false;
- Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
- return error.Success();
- }
+bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
+ uint32_t reg, llvm::ArrayRef<uint8_t> data) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info == NULL)
return false;
-}
-bool
-GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
-{
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
- if (reg_info == NULL)
- return false;
-
- // Invalidate if needed
- InvalidateIfNeeded(false);
-
- const uint32_t reg_byte_size = reg_info->byte_size;
- const size_t bytes_copied = response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), reg_byte_size, '\xcc');
- bool success = bytes_copied == reg_byte_size;
- if (success)
- {
- SetRegisterIsValid(reg, true);
- }
- else if (bytes_copied > 0)
- {
- // Only set register is valid to false if we copied some bytes, else
- // leave it as it was.
- SetRegisterIsValid(reg, false);
- }
- return success;
+ // Invalidate if needed
+ InvalidateIfNeeded(false);
+
+ const size_t reg_byte_size = reg_info->byte_size;
+ memcpy(const_cast<uint8_t *>(
+ m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),
+ data.data(), std::min(data.size(), reg_byte_size));
+ bool success = data.size() >= reg_byte_size;
+ if (success) {
+ SetRegisterIsValid(reg, true);
+ } else if (data.size() > 0) {
+ // Only set register is valid to false if we copied some bytes, else
+ // leave it as it was.
+ SetRegisterIsValid(reg, false);
+ }
+ return success;
}
-bool
-GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, uint64_t new_reg_val)
-{
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
- if (reg_info == NULL)
- return false;
-
- // Early in process startup, we can get a thread that has an invalid byte order
- // because the process hasn't been completely set up yet (see the ctor where the
- // byte order is setfrom the process). If that's the case, we can't set the
- // value here.
- if (m_reg_data.GetByteOrder() == eByteOrderInvalid)
- {
- return false;
- }
-
- // Invalidate if needed
- InvalidateIfNeeded (false);
+bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
+ uint64_t new_reg_val) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info == NULL)
+ return false;
- DataBufferSP buffer_sp (new DataBufferHeap (&new_reg_val, sizeof (new_reg_val)));
- DataExtractor data (buffer_sp, endian::InlHostByteOrder(), sizeof (void*));
+ // Early in process startup, we can get a thread that has an invalid byte
+ // order
+ // because the process hasn't been completely set up yet (see the ctor where
+ // the
+ // byte order is setfrom the process). If that's the case, we can't set the
+ // value here.
+ if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {
+ return false;
+ }
- // If our register context and our register info disagree, which should never happen, don't
- // overwrite past the end of the buffer.
- if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
- return false;
+ // Invalidate if needed
+ InvalidateIfNeeded(false);
- // Grab a pointer to where we are going to put this register
- uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
+ DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
+ DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
- if (dst == NULL)
- return false;
+ // If our register context and our register info disagree, which should never
+ // happen, don't
+ // overwrite past the end of the buffer.
+ if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+ return false;
+ // Grab a pointer to where we are going to put this register
+ uint8_t *dst = const_cast<uint8_t *>(
+ m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
- if (data.CopyByteOrderedData (0, // src offset
- reg_info->byte_size, // src length
- dst, // dst
- reg_info->byte_size, // dst length
- m_reg_data.GetByteOrder())) // dst byte order
- {
- SetRegisterIsValid (reg, true);
- return true;
- }
+ if (dst == NULL)
return false;
+
+ if (data.CopyByteOrderedData(0, // src offset
+ reg_info->byte_size, // src length
+ dst, // dst
+ reg_info->byte_size, // dst length
+ m_reg_data.GetByteOrder())) // dst byte order
+ {
+ SetRegisterIsValid(reg, true);
+ return true;
+ }
+ return false;
}
// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().
-bool
-GDBRemoteRegisterContext::GetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm)
-{
- const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
- const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
- StringExtractorGDBRemote response;
- if (gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg, response))
- return PrivateSetRegisterValue (lldb_reg, response);
- return false;
+bool GDBRemoteRegisterContext::GetPrimordialRegister(
+ const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
+ const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
+ StringExtractorGDBRemote response;
+ if (DataBufferSP buffer_sp =
+ gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
+ return PrivateSetRegisterValue(
+ lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),
+ buffer_sp->GetByteSize()));
+ return false;
}
-bool
-GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data)
-{
- ExecutionContext exe_ctx (CalculateThread());
+bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
+ DataExtractor &data) {
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
- InvalidateIfNeeded(false);
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ InvalidateIfNeeded(false);
- if (!GetRegisterIsValid(reg))
- {
- if (m_read_all_at_once)
- {
- StringExtractorGDBRemote response;
- if (!gdb_comm.ReadAllRegisters(m_thread.GetProtocolID(), response))
- return false;
- if (response.IsNormalResponse())
- if (response.GetHexBytes(const_cast<void *>(reinterpret_cast<const void *>(m_reg_data.GetDataStart())),
- m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize())
- SetAllRegisterValid (true);
- }
- else if (reg_info->value_regs)
- {
- // Process this composite register request by delegating to the constituent
- // primordial registers.
-
- // Index of the primordial register.
- bool success = true;
- for (uint32_t idx = 0; success; ++idx)
- {
- const uint32_t prim_reg = reg_info->value_regs[idx];
- if (prim_reg == LLDB_INVALID_REGNUM)
- break;
- // We have a valid primordial register as our constituent.
- // Grab the corresponding register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
- if (prim_reg_info == NULL)
- success = false;
- else
- {
- // Read the containing register if it hasn't already been read
- if (!GetRegisterIsValid(prim_reg))
- success = GetPrimordialRegister(prim_reg_info, gdb_comm);
- }
- }
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (success)
- {
- // If we reach this point, all primordial register requests have succeeded.
- // Validate this composite register.
- SetRegisterIsValid (reg_info, true);
- }
+ if (!GetRegisterIsValid(reg)) {
+ if (m_read_all_at_once) {
+ if (DataBufferSP buffer_sp =
+ gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
+ memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
+ buffer_sp->GetBytes(),
+ std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));
+ if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
+ SetAllRegisterValid(true);
+ return true;
}
- else
- {
- // Get each register individually
- GetPrimordialRegister(reg_info, gdb_comm);
+ }
+ return false;
+ }
+ if (reg_info->value_regs) {
+ // Process this composite register request by delegating to the
+ // constituent
+ // primordial registers.
+
+ // Index of the primordial register.
+ bool success = true;
+ for (uint32_t idx = 0; success; ++idx) {
+ const uint32_t prim_reg = reg_info->value_regs[idx];
+ if (prim_reg == LLDB_INVALID_REGNUM)
+ break;
+ // We have a valid primordial register as our constituent.
+ // Grab the corresponding register info.
+ const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
+ if (prim_reg_info == NULL)
+ success = false;
+ else {
+ // Read the containing register if it hasn't already been read
+ if (!GetRegisterIsValid(prim_reg))
+ success = GetPrimordialRegister(prim_reg_info, gdb_comm);
}
-
- // Make sure we got a valid register value after reading it
- if (!GetRegisterIsValid(reg))
- return false;
+ }
+
+ if (success) {
+ // If we reach this point, all primordial register requests have
+ // succeeded.
+ // Validate this composite register.
+ SetRegisterIsValid(reg_info, true);
+ }
+ } else {
+ // Get each register individually
+ GetPrimordialRegister(reg_info, gdb_comm);
}
- if (&data != &m_reg_data)
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size);
-#endif
- // If our register context and our register info disagree, which should never happen, don't
- // read past the end of the buffer.
- if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
- return false;
-
- // If we aren't extracting into our own buffer (which
- // only happens when this function is called from
- // ReadRegisterValue(uint32_t, Scalar&)) then
- // we transfer bytes from our buffer into the data
- // buffer that was passed in
-
- data.SetByteOrder (m_reg_data.GetByteOrder());
- data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size);
- }
- return true;
-}
+ // Make sure we got a valid register value after reading it
+ if (!GetRegisterIsValid(reg))
+ return false;
+ }
-bool
-GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- DataExtractor data;
- if (value.GetData (data))
- return WriteRegisterBytes (reg_info, data, 0);
- return false;
+ if (&data != &m_reg_data) {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(m_reg_data.GetByteSize() >=
+ reg_info->byte_offset + reg_info->byte_size);
+#endif
+ // If our register context and our register info disagree, which should
+ // never happen, don't
+ // read past the end of the buffer.
+ if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+ return false;
+
+ // If we aren't extracting into our own buffer (which
+ // only happens when this function is called from
+ // ReadRegisterValue(uint32_t, Scalar&)) then
+ // we transfer bytes from our buffer into the data
+ // buffer that was passed in
+
+ data.SetByteOrder(m_reg_data.GetByteOrder());
+ data.SetData(m_reg_data, reg_info->byte_offset, reg_info->byte_size);
+ }
+ return true;
}
-// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
-bool
-GDBRemoteRegisterContext::SetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm)
-{
- StreamString packet;
- StringExtractorGDBRemote response;
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
- reg_info->byte_size,
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (gdb_comm.GetThreadSuffixSupported())
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- // Invalidate just this register
- SetRegisterIsValid(reg, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- }
- return false;
+bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ DataExtractor data;
+ if (value.GetData(data))
+ return WriteRegisterBytes(reg_info, data, 0);
+ return false;
}
-void
-GDBRemoteRegisterContext::SyncThreadState(Process *process)
-{
- // NB. We assume our caller has locked the sequence mutex.
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *) process)->GetGDBRemote());
- if (!gdb_comm.GetSyncThreadStateSupported())
- return;
-
- StreamString packet;
- StringExtractorGDBRemote response;
- packet.Printf ("QSyncThreadState:%4.4" PRIx64 ";", m_thread.GetProtocolID());
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- InvalidateAllRegisters();
- }
+// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
+bool GDBRemoteRegisterContext::SetPrimordialRegister(
+ const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
+ StreamString packet;
+ StringExtractorGDBRemote response;
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ // Invalidate just this register
+ SetRegisterIsValid(reg, false);
+
+ return gdb_comm.WriteRegister(
+ m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
+ {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
+ reg_info->byte_size});
}
-bool
-GDBRemoteRegisterContext::WriteRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset)
-{
- ExecutionContext exe_ctx (CalculateThread());
+bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
+ DataExtractor &data,
+ uint32_t data_offset) {
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-// FIXME: This check isn't right because IsRunning checks the Public state, but this
-// is work you need to do - for instance in ShouldStop & friends - before the public
-// state has been changed.
-// if (gdb_comm.IsRunning())
-// return false;
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size);
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(m_reg_data.GetByteSize() >=
+ reg_info->byte_offset + reg_info->byte_size);
#endif
- // If our register context and our register info disagree, which should never happen, don't
- // overwrite past the end of the buffer.
- if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
- return false;
+ // If our register context and our register info disagree, which should never
+ // happen, don't
+ // overwrite past the end of the buffer.
+ if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+ return false;
- // Grab a pointer to where we are going to put this register
- uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
+ // Grab a pointer to where we are going to put this register
+ uint8_t *dst = const_cast<uint8_t *>(
+ m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
- if (dst == NULL)
- return false;
+ if (dst == NULL)
+ return false;
+ if (data.CopyByteOrderedData(data_offset, // src offset
+ reg_info->byte_size, // src length
+ dst, // dst
+ reg_info->byte_size, // dst length
+ m_reg_data.GetByteOrder())) // dst byte order
+ {
+ GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ if (lock) {
+ if (m_read_all_at_once) {
+ // Invalidate all register values
+ InvalidateIfNeeded(true);
+
+ // Set all registers in one packet
+ if (gdb_comm.WriteAllRegisters(
+ m_thread.GetProtocolID(),
+ {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
- if (data.CopyByteOrderedData (data_offset, // src offset
- reg_info->byte_size, // src length
- dst, // dst
- reg_info->byte_size, // dst length
- m_reg_data.GetByteOrder())) // dst byte order
- {
- Mutex::Locker locker;
- if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write register."))
{
- const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
- ProcessSP process_sp (m_thread.GetProcess());
- if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
- {
- StreamString packet;
- StringExtractorGDBRemote response;
-
- if (m_read_all_at_once)
- {
- // Set all registers in one packet
- packet.PutChar ('G');
- packet.PutBytesAsRawHex8 (m_reg_data.GetDataStart(),
- m_reg_data.GetByteSize(),
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- // Invalidate all register values
- InvalidateIfNeeded (true);
-
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- SetAllRegisterValid (false);
- if (response.IsOKResponse())
- {
- return true;
- }
- }
- }
- else
- {
- bool success = true;
-
- if (reg_info->value_regs)
- {
- // This register is part of another register. In this case we read the actual
- // register data for any "value_regs", and once all that data is read, we will
- // have enough data in our register context bytes for the value of this register
-
- // Invalidate this composite register first.
-
- for (uint32_t idx = 0; success; ++idx)
- {
- const uint32_t reg = reg_info->value_regs[idx];
- if (reg == LLDB_INVALID_REGNUM)
- break;
- // We have a valid primordial register as our constituent.
- // Grab the corresponding register info.
- const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
- if (value_reg_info == NULL)
- success = false;
- else
- success = SetPrimordialRegister(value_reg_info, gdb_comm);
- }
- }
- else
- {
- // This is an actual register, write it
- success = SetPrimordialRegister(reg_info, gdb_comm);
- }
-
- // Check if writing this register will invalidate any other register values?
- // If so, invalidate them
- if (reg_info->invalidate_regs)
- {
- for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
- reg != LLDB_INVALID_REGNUM;
- reg = reg_info->invalidate_regs[++idx])
- {
- SetRegisterIsValid(reg, false);
- }
- }
-
- return success;
- }
- }
+ SetAllRegisterValid(false);
+ return true;
}
- else
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
- if (log)
- {
- if (log->GetVerbose())
- {
- StreamString strm;
- gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData());
- }
- else
- log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name);
- }
+ } else {
+ bool success = true;
+
+ if (reg_info->value_regs) {
+ // This register is part of another register. In this case we read the
+ // actual
+ // register data for any "value_regs", and once all that data is read,
+ // we will
+ // have enough data in our register context bytes for the value of
+ // this register
+
+ // Invalidate this composite register first.
+
+ for (uint32_t idx = 0; success; ++idx) {
+ const uint32_t reg = reg_info->value_regs[idx];
+ if (reg == LLDB_INVALID_REGNUM)
+ break;
+ // We have a valid primordial register as our constituent.
+ // Grab the corresponding register info.
+ const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
+ if (value_reg_info == NULL)
+ success = false;
+ else
+ success = SetPrimordialRegister(value_reg_info, gdb_comm);
+ }
+ } else {
+ // This is an actual register, write it
+ success = SetPrimordialRegister(reg_info, gdb_comm);
+ }
+
+ // Check if writing this register will invalidate any other register
+ // values?
+ // If so, invalidate them
+ if (reg_info->invalidate_regs) {
+ for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
+ reg != LLDB_INVALID_REGNUM;
+ reg = reg_info->invalidate_regs[++idx]) {
+ SetRegisterIsValid(reg, false);
+ }
}
+
+ return success;
+ }
+ } else {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+ GDBR_LOG_PACKETS));
+ if (log) {
+ if (log->GetVerbose()) {
+ StreamString strm;
+ gdb_comm.DumpHistory(strm);
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\":\n%s",
+ reg_info->name, strm.GetData());
+ } else
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\"",
+ reg_info->name);
+ }
}
+ }
+ return false;
+}
+
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+ RegisterCheckpoint &reg_checkpoint) {
+ ExecutionContext exe_ctx(CalculateThread());
+
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
return false;
+
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
+
+ uint32_t save_id = 0;
+ if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {
+ reg_checkpoint.SetID(save_id);
+ reg_checkpoint.GetData().reset();
+ return true;
+ } else {
+ reg_checkpoint.SetID(0); // Invalid save ID is zero
+ return ReadAllRegisterValues(reg_checkpoint.GetData());
+ }
}
-bool
-GDBRemoteRegisterContext::ReadAllRegisterValues (RegisterCheckpoint &reg_checkpoint)
-{
- ExecutionContext exe_ctx (CalculateThread());
-
+bool GDBRemoteRegisterContext::WriteAllRegisterValues(
+ const RegisterCheckpoint &reg_checkpoint) {
+ uint32_t save_id = reg_checkpoint.GetID();
+ if (save_id != 0) {
+ ExecutionContext exe_ctx(CalculateThread());
+
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-
- uint32_t save_id = 0;
- if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id))
- {
- reg_checkpoint.SetID(save_id);
- reg_checkpoint.GetData().reset();
- return true;
- }
- else
- {
- reg_checkpoint.SetID(0); // Invalid save ID is zero
- return ReadAllRegisterValues(reg_checkpoint.GetData());
- }
-}
+ return false;
-bool
-GDBRemoteRegisterContext::WriteAllRegisterValues (const RegisterCheckpoint &reg_checkpoint)
-{
- uint32_t save_id = reg_checkpoint.GetID();
- if (save_id != 0)
- {
- ExecutionContext exe_ctx (CalculateThread());
-
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-
- return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
- }
- else
- {
- return WriteAllRegisterValues(reg_checkpoint.GetData());
- }
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
+
+ return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
+ } else {
+ return WriteAllRegisterValues(reg_checkpoint.GetData());
+ }
}
-bool
-GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- ExecutionContext exe_ctx (CalculateThread());
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
- StringExtractorGDBRemote response;
+ const bool use_g_packet =
+ gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
- const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+ GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ if (lock) {
+ if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
+ InvalidateAllRegisters();
- Mutex::Locker locker;
- if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read all registers."))
- {
- SyncThreadState(process);
-
- char packet[32];
- const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
- ProcessSP process_sp (m_thread.GetProcess());
- if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
- {
- int packet_len = 0;
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID());
- else
- packet_len = ::snprintf (packet, sizeof(packet), "g");
- assert (packet_len < ((int)sizeof(packet) - 1));
-
- if (use_g_packet && gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- int packet_len = 0;
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID());
- else
- packet_len = ::snprintf (packet, sizeof(packet), "g");
- assert (packet_len < ((int)sizeof(packet) - 1));
-
- if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsErrorResponse())
- return false;
-
- std::string &response_str = response.GetStringRef();
- if (isxdigit(response_str[0]))
- {
- response_str.insert(0, 1, 'G');
- if (thread_suffix_supported)
- {
- char thread_id_cstr[64];
- ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
- response_str.append (thread_id_cstr);
- }
- data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size()));
- return true;
- }
- }
- }
- else
- {
- // For the use_g_packet == false case, we're going to read each register
- // individually and store them as binary data in a buffer instead of as ascii
- // characters.
- const RegisterInfo *reg_info;
-
- // data_sp will take ownership of this DataBufferHeap pointer soon.
- DataBufferSP reg_ctx(new DataBufferHeap(m_reg_info.GetRegisterDataByteSize(), 0));
-
- for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++)
- {
- if (reg_info->value_regs) // skip registers that are slices of real registers
- continue;
- ReadRegisterBytes (reg_info, m_reg_data);
- // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer
- }
- memcpy (reg_ctx->GetBytes(), m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize());
-
- data_sp = reg_ctx;
- return true;
- }
- }
- }
- else
- {
+ if (use_g_packet &&
+ (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
+ return true;
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
- if (log)
- {
- if (log->GetVerbose())
- {
- StreamString strm;
- gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData());
- }
- else
- log->Printf("error: failed to get packet sequence mutex, not sending read all registers");
- }
+ // We're going to read each register
+ // individually and store them as binary data in a buffer.
+ const RegisterInfo *reg_info;
+
+ for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) {
+ if (reg_info
+ ->value_regs) // skip registers that are slices of real registers
+ continue;
+ ReadRegisterBytes(reg_info, m_reg_data);
+ // ReadRegisterBytes saves the contents of the register in to the
+ // m_reg_data buffer
}
+ data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(),
+ m_reg_info.GetRegisterDataByteSize()));
+ return true;
+ } else {
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+ GDBR_LOG_PACKETS));
+ if (log) {
+ if (log->GetVerbose()) {
+ StreamString strm;
+ gdb_comm.DumpHistory(strm);
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "read all registers:\n%s",
+ strm.GetData());
+ } else
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "read all registers");
+ }
+ }
- data_sp.reset();
- return false;
+ data_sp.reset();
+ return false;
}
-bool
-GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
- return false;
+bool GDBRemoteRegisterContext::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
+ return false;
- ExecutionContext exe_ctx (CalculateThread());
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
- const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+ const bool use_g_packet =
+ gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
- StringExtractorGDBRemote response;
- Mutex::Locker locker;
- if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write all registers."))
- {
- const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
- ProcessSP process_sp (m_thread.GetProcess());
- if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
- {
- // The data_sp contains the entire G response packet including the
- // G, and if the thread suffix is supported, it has the thread suffix
- // as well.
- const char *G_packet = (const char *)data_sp->GetBytes();
- size_t G_packet_len = data_sp->GetByteSize();
- if (use_g_packet
- && gdb_comm.SendPacketAndWaitForResponse (G_packet,
- G_packet_len,
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- // The data_sp contains the entire G response packet including the
- // G, and if the thread suffix is supported, it has the thread suffix
- // as well.
- const char *G_packet = (const char *)data_sp->GetBytes();
- size_t G_packet_len = data_sp->GetByteSize();
- if (gdb_comm.SendPacketAndWaitForResponse (G_packet,
- G_packet_len,
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- else if (response.IsErrorResponse())
- {
- uint32_t num_restored = 0;
- // We need to manually go through all of the registers and
- // restore them manually
-
- response.GetStringRef().assign (G_packet, G_packet_len);
- response.SetFilePos(1); // Skip the leading 'G'
-
- // G_packet_len is hex-ascii characters plus prefix 'G' plus suffix thread specifier.
- // This means buffer will be a little more than 2x larger than necessary but we resize
- // it down once we've extracted all hex ascii chars from the packet.
- DataBufferHeap buffer (G_packet_len, 0);
-
- const uint32_t bytes_extracted = response.GetHexBytes (buffer.GetBytes(),
- buffer.GetByteSize(),
- '\xcc');
-
- DataExtractor restore_data (buffer.GetBytes(),
- buffer.GetByteSize(),
- m_reg_data.GetByteOrder(),
- m_reg_data.GetAddressByteSize());
-
- if (bytes_extracted < restore_data.GetByteSize())
- restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder());
-
- const RegisterInfo *reg_info;
-
- // The g packet contents may either include the slice registers (registers defined in
- // terms of other registers, e.g. eax is a subset of rax) or not. The slice registers
- // should NOT be in the g packet, but some implementations may incorrectly include them.
- //
- // If the slice registers are included in the packet, we must step over the slice registers
- // when parsing the packet -- relying on the RegisterInfo byte_offset field would be incorrect.
- // If the slice registers are not included, then using the byte_offset values into the
- // data buffer is the best way to find individual register values.
-
- uint64_t size_including_slice_registers = 0;
- uint64_t size_not_including_slice_registers = 0;
- uint64_t size_by_highest_offset = 0;
-
- for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx)
- {
- size_including_slice_registers += reg_info->byte_size;
- if (reg_info->value_regs == NULL)
- size_not_including_slice_registers += reg_info->byte_size;
- if (reg_info->byte_offset >= size_by_highest_offset)
- size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
- }
-
- bool use_byte_offset_into_buffer;
- if (size_by_highest_offset == restore_data.GetByteSize())
- {
- // The size of the packet agrees with the highest offset: + size in the register file
- use_byte_offset_into_buffer = true;
- }
- else if (size_not_including_slice_registers == restore_data.GetByteSize())
- {
- // The size of the packet is the same as concatenating all of the registers sequentially,
- // skipping the slice registers
- use_byte_offset_into_buffer = true;
- }
- else if (size_including_slice_registers == restore_data.GetByteSize())
- {
- // The slice registers are present in the packet (when they shouldn't be).
- // Don't try to use the RegisterInfo byte_offset into the restore_data, it will
- // point to the wrong place.
- use_byte_offset_into_buffer = false;
- }
- else {
- // None of our expected sizes match the actual g packet data we're looking at.
- // The most conservative approach here is to use the running total byte offset.
- use_byte_offset_into_buffer = false;
- }
-
- // In case our register definitions don't include the correct offsets,
- // keep track of the size of each reg & compute offset based on that.
- uint32_t running_byte_offset = 0;
- for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, running_byte_offset += reg_info->byte_size)
- {
- // Skip composite aka slice registers (e.g. eax is a slice of rax).
- if (reg_info->value_regs)
- continue;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- uint32_t register_offset;
- if (use_byte_offset_into_buffer)
- {
- register_offset = reg_info->byte_offset;
- }
- else
- {
- register_offset = running_byte_offset;
- }
-
- // Only write down the registers that need to be written
- // if we are going to be doing registers individually.
- bool write_reg = true;
- const uint32_t reg_byte_size = reg_info->byte_size;
-
- const char *restore_src = (const char *)restore_data.PeekData(register_offset, reg_byte_size);
- if (restore_src)
- {
- StreamString packet;
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (restore_src,
- reg_byte_size,
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- SetRegisterIsValid(reg, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- const char *current_src = (const char *)m_reg_data.PeekData(register_offset, reg_byte_size);
- if (current_src)
- write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0;
- }
-
- if (write_reg)
- {
- StreamString packet;
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (restore_src,
- reg_byte_size,
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- SetRegisterIsValid(reg, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- ++num_restored;
- }
- }
- }
- }
- return num_restored > 0;
- }
- }
- }
- else
- {
- // For the use_g_packet == false case, we're going to write each register
- // individually. The data buffer is binary data in this case, instead of
- // ascii characters.
-
- bool arm64_debugserver = false;
- if (m_thread.GetProcess().get())
- {
- const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
- if (arch.IsValid()
- && arch.GetMachine() == llvm::Triple::aarch64
- && arch.GetTriple().getVendor() == llvm::Triple::Apple
- && arch.GetTriple().getOS() == llvm::Triple::IOS)
- {
- arm64_debugserver = true;
- }
- }
- uint32_t num_restored = 0;
- const RegisterInfo *reg_info;
- for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++)
- {
- if (reg_info->value_regs) // skip registers that are slices of real registers
- continue;
- // Skip the fpsr and fpcr floating point status/control register writing to
- // work around a bug in an older version of debugserver that would lead to
- // register context corruption when writing fpsr/fpcr.
- if (arm64_debugserver &&
- (strcmp (reg_info->name, "fpsr") == 0 || strcmp (reg_info->name, "fpcr") == 0))
- {
- continue;
- }
- StreamString packet;
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size, endian::InlHostByteOrder(), endian::InlHostByteOrder());
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- SetRegisterIsValid(reg_info, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- ++num_restored;
- }
- }
- return num_restored > 0;
- }
+ GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ if (lock) {
+ // The data_sp contains the G response packet.
+ if (use_g_packet) {
+ if (gdb_comm.WriteAllRegisters(
+ m_thread.GetProtocolID(),
+ {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
+ return true;
+
+ uint32_t num_restored = 0;
+ // We need to manually go through all of the registers and
+ // restore them manually
+ DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
+ m_reg_data.GetAddressByteSize());
+
+ const RegisterInfo *reg_info;
+
+ // The g packet contents may either include the slice registers (registers
+ // defined in
+ // terms of other registers, e.g. eax is a subset of rax) or not. The
+ // slice registers
+ // should NOT be in the g packet, but some implementations may incorrectly
+ // include them.
+ //
+ // If the slice registers are included in the packet, we must step over
+ // the slice registers
+ // when parsing the packet -- relying on the RegisterInfo byte_offset
+ // field would be incorrect.
+ // If the slice registers are not included, then using the byte_offset
+ // values into the
+ // data buffer is the best way to find individual register values.
+
+ uint64_t size_including_slice_registers = 0;
+ uint64_t size_not_including_slice_registers = 0;
+ uint64_t size_by_highest_offset = 0;
+
+ for (uint32_t reg_idx = 0;
+ (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) {
+ size_including_slice_registers += reg_info->byte_size;
+ if (reg_info->value_regs == NULL)
+ size_not_including_slice_registers += reg_info->byte_size;
+ if (reg_info->byte_offset >= size_by_highest_offset)
+ size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
+ }
+
+ bool use_byte_offset_into_buffer;
+ if (size_by_highest_offset == restore_data.GetByteSize()) {
+ // The size of the packet agrees with the highest offset: + size in the
+ // register file
+ use_byte_offset_into_buffer = true;
+ } else if (size_not_including_slice_registers ==
+ restore_data.GetByteSize()) {
+ // The size of the packet is the same as concatenating all of the
+ // registers sequentially,
+ // skipping the slice registers
+ use_byte_offset_into_buffer = true;
+ } else if (size_including_slice_registers == restore_data.GetByteSize()) {
+ // The slice registers are present in the packet (when they shouldn't
+ // be).
+ // Don't try to use the RegisterInfo byte_offset into the restore_data,
+ // it will
+ // point to the wrong place.
+ use_byte_offset_into_buffer = false;
+ } else {
+ // None of our expected sizes match the actual g packet data we're
+ // looking at.
+ // The most conservative approach here is to use the running total byte
+ // offset.
+ use_byte_offset_into_buffer = false;
+ }
+
+ // In case our register definitions don't include the correct offsets,
+ // keep track of the size of each reg & compute offset based on that.
+ uint32_t running_byte_offset = 0;
+ for (uint32_t reg_idx = 0;
+ (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL;
+ ++reg_idx, running_byte_offset += reg_info->byte_size) {
+ // Skip composite aka slice registers (e.g. eax is a slice of rax).
+ if (reg_info->value_regs)
+ continue;
+
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ uint32_t register_offset;
+ if (use_byte_offset_into_buffer) {
+ register_offset = reg_info->byte_offset;
+ } else {
+ register_offset = running_byte_offset;
}
- }
- else
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
- if (log)
- {
- if (log->GetVerbose())
- {
- StreamString strm;
- gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData());
- }
- else
- log->Printf("error: failed to get packet sequence mutex, not sending write all registers");
+
+ const uint32_t reg_byte_size = reg_info->byte_size;
+
+ const uint8_t *restore_src =
+ restore_data.PeekData(register_offset, reg_byte_size);
+ if (restore_src) {
+ SetRegisterIsValid(reg, false);
+ if (gdb_comm.WriteRegister(
+ m_thread.GetProtocolID(),
+ reg_info->kinds[eRegisterKindProcessPlugin],
+ {restore_src, reg_byte_size}))
+ ++num_restored;
+ }
+ }
+ return num_restored > 0;
+ } else {
+ // For the use_g_packet == false case, we're going to write each register
+ // individually. The data buffer is binary data in this case, instead of
+ // ascii characters.
+
+ bool arm64_debugserver = false;
+ if (m_thread.GetProcess().get()) {
+ const ArchSpec &arch =
+ m_thread.GetProcess()->GetTarget().GetArchitecture();
+ if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 &&
+ arch.GetTriple().getVendor() == llvm::Triple::Apple &&
+ arch.GetTriple().getOS() == llvm::Triple::IOS) {
+ arm64_debugserver = true;
}
+ }
+ uint32_t num_restored = 0;
+ const RegisterInfo *reg_info;
+ for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL;
+ i++) {
+ if (reg_info->value_regs) // skip registers that are slices of real
+ // registers
+ continue;
+ // Skip the fpsr and fpcr floating point status/control register writing
+ // to
+ // work around a bug in an older version of debugserver that would lead
+ // to
+ // register context corruption when writing fpsr/fpcr.
+ if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
+ strcmp(reg_info->name, "fpcr") == 0)) {
+ continue;
+ }
+
+ SetRegisterIsValid(reg_info, false);
+ if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),
+ reg_info->kinds[eRegisterKindProcessPlugin],
+ {data_sp->GetBytes() + reg_info->byte_offset,
+ reg_info->byte_size}))
+ ++num_restored;
+ }
+ return num_restored > 0;
}
- return false;
+ } else {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+ GDBR_LOG_PACKETS));
+ if (log) {
+ if (log->GetVerbose()) {
+ StreamString strm;
+ gdb_comm.DumpHistory(strm);
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write all registers:\n%s",
+ strm.GetData());
+ } else
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write all registers");
+ }
+ }
+ return false;
}
-
-uint32_t
-GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num);
+uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_reg_info.ConvertRegisterKindToRegisterNumber(kind, num);
}
-
-void
-GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch)
-{
- // For Advanced SIMD and VFP register mapping.
- static uint32_t g_d0_regs[] = { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1)
- static uint32_t g_d1_regs[] = { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3)
- static uint32_t g_d2_regs[] = { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5)
- static uint32_t g_d3_regs[] = { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7)
- static uint32_t g_d4_regs[] = { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9)
- static uint32_t g_d5_regs[] = { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11)
- static uint32_t g_d6_regs[] = { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13)
- static uint32_t g_d7_regs[] = { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15)
- static uint32_t g_d8_regs[] = { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17)
- static uint32_t g_d9_regs[] = { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19)
- static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21)
- static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23)
- static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25)
- static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27)
- static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29)
- static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31)
- static uint32_t g_q0_regs[] = { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3)
- static uint32_t g_q1_regs[] = { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7)
- static uint32_t g_q2_regs[] = { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11)
- static uint32_t g_q3_regs[] = { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15)
- static uint32_t g_q4_regs[] = { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19)
- static uint32_t g_q5_regs[] = { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23)
- static uint32_t g_q6_regs[] = { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27)
- static uint32_t g_q7_regs[] = { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31)
- static uint32_t g_q8_regs[] = { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17)
- static uint32_t g_q9_regs[] = { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19)
- static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21)
- static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23)
- static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25)
- static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27)
- static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29)
- static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31)
-
- // This is our array of composite registers, with each element coming from the above register mappings.
- static uint32_t *g_composites[] = {
- g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, g_d6_regs, g_d7_regs,
- g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs,
- g_q0_regs, g_q1_regs, g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs,
- g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs
- };
-
+void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
+ // For Advanced SIMD and VFP register mapping.
+ static uint32_t g_d0_regs[] = {26, 27, LLDB_INVALID_REGNUM}; // (s0, s1)
+ static uint32_t g_d1_regs[] = {28, 29, LLDB_INVALID_REGNUM}; // (s2, s3)
+ static uint32_t g_d2_regs[] = {30, 31, LLDB_INVALID_REGNUM}; // (s4, s5)
+ static uint32_t g_d3_regs[] = {32, 33, LLDB_INVALID_REGNUM}; // (s6, s7)
+ static uint32_t g_d4_regs[] = {34, 35, LLDB_INVALID_REGNUM}; // (s8, s9)
+ static uint32_t g_d5_regs[] = {36, 37, LLDB_INVALID_REGNUM}; // (s10, s11)
+ static uint32_t g_d6_regs[] = {38, 39, LLDB_INVALID_REGNUM}; // (s12, s13)
+ static uint32_t g_d7_regs[] = {40, 41, LLDB_INVALID_REGNUM}; // (s14, s15)
+ static uint32_t g_d8_regs[] = {42, 43, LLDB_INVALID_REGNUM}; // (s16, s17)
+ static uint32_t g_d9_regs[] = {44, 45, LLDB_INVALID_REGNUM}; // (s18, s19)
+ static uint32_t g_d10_regs[] = {46, 47, LLDB_INVALID_REGNUM}; // (s20, s21)
+ static uint32_t g_d11_regs[] = {48, 49, LLDB_INVALID_REGNUM}; // (s22, s23)
+ static uint32_t g_d12_regs[] = {50, 51, LLDB_INVALID_REGNUM}; // (s24, s25)
+ static uint32_t g_d13_regs[] = {52, 53, LLDB_INVALID_REGNUM}; // (s26, s27)
+ static uint32_t g_d14_regs[] = {54, 55, LLDB_INVALID_REGNUM}; // (s28, s29)
+ static uint32_t g_d15_regs[] = {56, 57, LLDB_INVALID_REGNUM}; // (s30, s31)
+ static uint32_t g_q0_regs[] = {
+ 26, 27, 28, 29, LLDB_INVALID_REGNUM}; // (d0, d1) -> (s0, s1, s2, s3)
+ static uint32_t g_q1_regs[] = {
+ 30, 31, 32, 33, LLDB_INVALID_REGNUM}; // (d2, d3) -> (s4, s5, s6, s7)
+ static uint32_t g_q2_regs[] = {
+ 34, 35, 36, 37, LLDB_INVALID_REGNUM}; // (d4, d5) -> (s8, s9, s10, s11)
+ static uint32_t g_q3_regs[] = {
+ 38, 39, 40, 41, LLDB_INVALID_REGNUM}; // (d6, d7) -> (s12, s13, s14, s15)
+ static uint32_t g_q4_regs[] = {
+ 42, 43, 44, 45, LLDB_INVALID_REGNUM}; // (d8, d9) -> (s16, s17, s18, s19)
+ static uint32_t g_q5_regs[] = {
+ 46, 47, 48, 49,
+ LLDB_INVALID_REGNUM}; // (d10, d11) -> (s20, s21, s22, s23)
+ static uint32_t g_q6_regs[] = {
+ 50, 51, 52, 53,
+ LLDB_INVALID_REGNUM}; // (d12, d13) -> (s24, s25, s26, s27)
+ static uint32_t g_q7_regs[] = {
+ 54, 55, 56, 57,
+ LLDB_INVALID_REGNUM}; // (d14, d15) -> (s28, s29, s30, s31)
+ static uint32_t g_q8_regs[] = {59, 60, LLDB_INVALID_REGNUM}; // (d16, d17)
+ static uint32_t g_q9_regs[] = {61, 62, LLDB_INVALID_REGNUM}; // (d18, d19)
+ static uint32_t g_q10_regs[] = {63, 64, LLDB_INVALID_REGNUM}; // (d20, d21)
+ static uint32_t g_q11_regs[] = {65, 66, LLDB_INVALID_REGNUM}; // (d22, d23)
+ static uint32_t g_q12_regs[] = {67, 68, LLDB_INVALID_REGNUM}; // (d24, d25)
+ static uint32_t g_q13_regs[] = {69, 70, LLDB_INVALID_REGNUM}; // (d26, d27)
+ static uint32_t g_q14_regs[] = {71, 72, LLDB_INVALID_REGNUM}; // (d28, d29)
+ static uint32_t g_q15_regs[] = {73, 74, LLDB_INVALID_REGNUM}; // (d30, d31)
+
+ // This is our array of composite registers, with each element coming from the
+ // above register mappings.
+ static uint32_t *g_composites[] = {
+ g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs,
+ g_d6_regs, g_d7_regs, g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs,
+ g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, g_q0_regs, g_q1_regs,
+ g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs,
+ g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs,
+ g_q14_regs, g_q15_regs};
+
+ // clang-format off
static RegisterInfo g_register_infos[] = {
-// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS
-// ====== ====== === === ============= ============ =================== =================== ====================== ============= ==== ========== ===============
- { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, NULL, NULL},
- { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, NULL, NULL},
- { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, NULL, NULL},
- { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, NULL, NULL},
- { "r4", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, NULL, NULL},
- { "r5", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, NULL, NULL},
- { "r6", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, NULL, NULL},
- { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, NULL, NULL},
- { "r8", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, NULL, NULL},
- { "r9", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, NULL, NULL},
- { "r10", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, NULL, NULL},
- { "r11", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, NULL, NULL},
- { "r12", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, NULL, NULL},
- { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, NULL, NULL},
- { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, NULL, NULL},
- { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, NULL, NULL},
- { "f0", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, NULL, NULL},
- { "f1", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, NULL, NULL},
- { "f2", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, NULL, NULL},
- { "f3", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, NULL, NULL},
- { "f4", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, NULL, NULL},
- { "f5", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, NULL, NULL},
- { "f6", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, NULL, NULL},
- { "f7", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, NULL, NULL},
- { "fps", NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, NULL, NULL},
- { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, NULL, NULL},
- { "s0", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, NULL, NULL},
- { "s1", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, NULL, NULL},
- { "s2", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, NULL, NULL},
- { "s3", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, NULL, NULL},
- { "s4", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, NULL, NULL},
- { "s5", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, NULL, NULL},
- { "s6", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, NULL, NULL},
- { "s7", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, NULL, NULL},
- { "s8", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, NULL, NULL},
- { "s9", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, NULL, NULL},
- { "s10", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, NULL, NULL},
- { "s11", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, NULL, NULL},
- { "s12", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, NULL, NULL},
- { "s13", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, NULL, NULL},
- { "s14", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, NULL, NULL},
- { "s15", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, NULL, NULL},
- { "s16", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, NULL, NULL},
- { "s17", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, NULL, NULL},
- { "s18", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, NULL, NULL},
- { "s19", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, NULL, NULL},
- { "s20", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, NULL, NULL},
- { "s21", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, NULL, NULL},
- { "s22", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, NULL, NULL},
- { "s23", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, NULL, NULL},
- { "s24", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, NULL, NULL},
- { "s25", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, NULL, NULL},
- { "s26", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, NULL, NULL},
- { "s27", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, NULL, NULL},
- { "s28", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, NULL, NULL},
- { "s29", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, NULL, NULL},
- { "s30", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, NULL, NULL},
- { "s31", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, NULL, NULL},
- { "fpscr",NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, NULL, NULL},
- { "d16", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, NULL, NULL},
- { "d17", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, NULL, NULL},
- { "d18", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, NULL, NULL},
- { "d19", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, NULL, NULL},
- { "d20", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, NULL, NULL},
- { "d21", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, NULL, NULL},
- { "d22", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, NULL, NULL},
- { "d23", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, NULL, NULL},
- { "d24", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, NULL, NULL},
- { "d25", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, NULL, NULL},
- { "d26", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, NULL, NULL},
- { "d27", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, NULL, NULL},
- { "d28", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, NULL, NULL},
- { "d29", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, NULL, NULL},
- { "d30", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, NULL, NULL},
- { "d31", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, NULL, NULL},
- { "d0", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, NULL},
- { "d1", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, NULL},
- { "d2", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, NULL},
- { "d3", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, NULL},
- { "d4", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, NULL},
- { "d5", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, NULL},
- { "d6", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, NULL},
- { "d7", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, NULL},
- { "d8", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, NULL},
- { "d9", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, NULL},
- { "d10", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, NULL},
- { "d11", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, NULL},
- { "d12", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, NULL},
- { "d13", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, NULL},
- { "d14", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, NULL},
- { "d15", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, NULL},
- { "q0", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, NULL},
- { "q1", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, NULL},
- { "q2", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, NULL},
- { "q3", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, NULL},
- { "q4", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, NULL},
- { "q5", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, NULL},
- { "q6", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, NULL},
- { "q7", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, NULL},
- { "q8", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, NULL},
- { "q9", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, NULL},
- { "q10", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, NULL},
- { "q11", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, NULL},
- { "q12", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, NULL},
- { "q13", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, NULL},
- { "q14", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, NULL},
- { "q15", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, NULL}
+// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS SIZE EXPR SIZE LEN
+// ====== ====== === === ============= ========== =================== =================== ====================== ============= ==== ========== =============== ========= ========
+ { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, nullptr, nullptr, nullptr, 0 },
+ { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, nullptr, nullptr, nullptr, 0 },
+ { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, nullptr, nullptr, nullptr, 0 },
+ { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, nullptr, nullptr, nullptr, 0 },
+ { "r4", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, nullptr, nullptr, nullptr, 0 },
+ { "r5", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, nullptr, nullptr, nullptr, 0 },
+ { "r6", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, nullptr, nullptr, nullptr, 0 },
+ { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, nullptr, nullptr, nullptr, 0 },
+ { "r8", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, nullptr, nullptr, nullptr, 0 },
+ { "r9", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, nullptr, nullptr, nullptr, 0 },
+ { "r10", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, nullptr, nullptr, nullptr, 0 },
+ { "r11", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, nullptr, nullptr, nullptr, 0 },
+ { "r12", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, nullptr, nullptr, nullptr, 0 },
+ { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, nullptr, nullptr, nullptr, 0 },
+ { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, nullptr, nullptr, nullptr, 0 },
+ { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, nullptr, nullptr, nullptr, 0 },
+ { "f0", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, nullptr, nullptr, nullptr, 0 },
+ { "f1", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, nullptr, nullptr, nullptr, 0 },
+ { "f2", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, nullptr, nullptr, nullptr, 0 },
+ { "f3", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, nullptr, nullptr, nullptr, 0 },
+ { "f4", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, nullptr, nullptr, nullptr, 0 },
+ { "f5", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, nullptr, nullptr, nullptr, 0 },
+ { "f6", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, nullptr, nullptr, nullptr, 0 },
+ { "f7", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, nullptr, nullptr, nullptr, 0 },
+ { "fps", nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, nullptr, nullptr, nullptr, 0 },
+ { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, nullptr, nullptr, nullptr, 0 },
+ { "s0", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, nullptr, nullptr, nullptr, 0 },
+ { "s1", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, nullptr, nullptr, nullptr, 0 },
+ { "s2", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, nullptr, nullptr, nullptr, 0 },
+ { "s3", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, nullptr, nullptr, nullptr, 0 },
+ { "s4", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, nullptr, nullptr, nullptr, 0 },
+ { "s5", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, nullptr, nullptr, nullptr, 0 },
+ { "s6", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, nullptr, nullptr, nullptr, 0 },
+ { "s7", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, nullptr, nullptr, nullptr, 0 },
+ { "s8", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, nullptr, nullptr, nullptr, 0 },
+ { "s9", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, nullptr, nullptr, nullptr, 0 },
+ { "s10", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, nullptr, nullptr, nullptr, 0 },
+ { "s11", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, nullptr, nullptr, nullptr, 0 },
+ { "s12", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, nullptr, nullptr, nullptr, 0 },
+ { "s13", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, nullptr, nullptr, nullptr, 0 },
+ { "s14", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, nullptr, nullptr, nullptr, 0 },
+ { "s15", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, nullptr, nullptr, nullptr, 0 },
+ { "s16", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, nullptr, nullptr, nullptr, 0 },
+ { "s17", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, nullptr, nullptr, nullptr, 0 },
+ { "s18", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, nullptr, nullptr, nullptr, 0 },
+ { "s19", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, nullptr, nullptr, nullptr, 0 },
+ { "s20", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, nullptr, nullptr, nullptr, 0 },
+ { "s21", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, nullptr, nullptr, nullptr, 0 },
+ { "s22", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, nullptr, nullptr, nullptr, 0 },
+ { "s23", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, nullptr, nullptr, nullptr, 0 },
+ { "s24", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, nullptr, nullptr, nullptr, 0 },
+ { "s25", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, nullptr, nullptr, nullptr, 0 },
+ { "s26", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, nullptr, nullptr, nullptr, 0 },
+ { "s27", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, nullptr, nullptr, nullptr, 0 },
+ { "s28", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, nullptr, nullptr, nullptr, 0 },
+ { "s29", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, nullptr, nullptr, nullptr, 0 },
+ { "s30", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, nullptr, nullptr, nullptr, 0 },
+ { "s31", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, nullptr, nullptr, nullptr, 0 },
+ { "fpscr",nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, nullptr, nullptr, nullptr, 0 },
+ { "d16", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, nullptr, nullptr, nullptr, 0 },
+ { "d17", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, nullptr, nullptr, nullptr, 0 },
+ { "d18", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, nullptr, nullptr, nullptr, 0 },
+ { "d19", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, nullptr, nullptr, nullptr, 0 },
+ { "d20", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, nullptr, nullptr, nullptr, 0 },
+ { "d21", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, nullptr, nullptr, nullptr, 0 },
+ { "d22", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, nullptr, nullptr, nullptr, 0 },
+ { "d23", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, nullptr, nullptr, nullptr, 0 },
+ { "d24", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, nullptr, nullptr, nullptr, 0 },
+ { "d25", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, nullptr, nullptr, nullptr, 0 },
+ { "d26", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, nullptr, nullptr, nullptr, 0 },
+ { "d27", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, nullptr, nullptr, nullptr, 0 },
+ { "d28", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, nullptr, nullptr, nullptr, 0 },
+ { "d29", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, nullptr, nullptr, nullptr, 0 },
+ { "d30", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, nullptr, nullptr, nullptr, 0 },
+ { "d31", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, nullptr, nullptr, nullptr, 0 },
+ { "d0", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, nullptr, nullptr, 0 },
+ { "d1", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, nullptr, nullptr, 0 },
+ { "d2", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, nullptr, nullptr, 0 },
+ { "d3", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, nullptr, nullptr, 0 },
+ { "d4", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, nullptr, nullptr, 0 },
+ { "d5", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, nullptr, nullptr, 0 },
+ { "d6", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, nullptr, nullptr, 0 },
+ { "d7", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, nullptr, nullptr, 0 },
+ { "d8", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, nullptr, nullptr, 0 },
+ { "d9", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, nullptr, nullptr, 0 },
+ { "d10", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, nullptr, nullptr, 0 },
+ { "d11", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, nullptr, nullptr, 0 },
+ { "d12", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, nullptr, nullptr, 0 },
+ { "d13", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, nullptr, nullptr, 0 },
+ { "d14", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, nullptr, nullptr, 0 },
+ { "d15", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, nullptr, nullptr, 0 },
+ { "q0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, nullptr, nullptr, 0 },
+ { "q1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, nullptr, nullptr, 0 },
+ { "q2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, nullptr, nullptr, 0 },
+ { "q3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, nullptr, nullptr, 0 },
+ { "q4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, nullptr, nullptr, 0 },
+ { "q5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, nullptr, nullptr, 0 },
+ { "q6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, nullptr, nullptr, 0 },
+ { "q7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, nullptr, nullptr, 0 },
+ { "q8", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, nullptr, nullptr, 0 },
+ { "q9", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, nullptr, nullptr, 0 },
+ { "q10", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, nullptr, nullptr, 0 },
+ { "q11", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, nullptr, nullptr, 0 },
+ { "q12", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, nullptr, nullptr, 0 },
+ { "q13", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, nullptr, nullptr, 0 },
+ { "q14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, nullptr, nullptr, 0 },
+ { "q15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, nullptr, nullptr, 0 }
};
-
- static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
- static ConstString gpr_reg_set ("General Purpose Registers");
- static ConstString sfp_reg_set ("Software Floating Point Registers");
- static ConstString vfp_reg_set ("Floating Point Registers");
- size_t i;
- if (from_scratch)
- {
- // Calculate the offsets of the registers
- // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the
- // "primordial" registers is important. This enables us to calculate the offset of the composite
- // register by using the offset of its first primordial register. For example, to calculate the
- // offset of q0, use s0's offset.
- if (g_register_infos[2].byte_offset == 0)
- {
- uint32_t byte_offset = 0;
- for (i=0; i<num_registers; ++i)
- {
- // For primordial registers, increment the byte_offset by the byte_size to arrive at the
- // byte_offset for the next register. Otherwise, we have a composite register whose
- // offset can be calculated by consulting the offset of its first primordial register.
- if (!g_register_infos[i].value_regs)
- {
- g_register_infos[i].byte_offset = byte_offset;
- byte_offset += g_register_infos[i].byte_size;
- }
- else
- {
- const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0];
- g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset;
- }
- }
- }
- for (i=0; i<num_registers; ++i)
- {
- ConstString name;
- ConstString alt_name;
- if (g_register_infos[i].name && g_register_infos[i].name[0])
- name.SetCString(g_register_infos[i].name);
- if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
- alt_name.SetCString(g_register_infos[i].alt_name);
-
- if (i <= 15 || i == 25)
- AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set);
- else if (i <= 24)
- AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set);
- else
- AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set);
+ // clang-format on
+
+ static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
+ static ConstString gpr_reg_set("General Purpose Registers");
+ static ConstString sfp_reg_set("Software Floating Point Registers");
+ static ConstString vfp_reg_set("Floating Point Registers");
+ size_t i;
+ if (from_scratch) {
+ // Calculate the offsets of the registers
+ // Note that the layout of the "composite" registers (d0-d15 and q0-q15)
+ // which comes after the
+ // "primordial" registers is important. This enables us to calculate the
+ // offset of the composite
+ // register by using the offset of its first primordial register. For
+ // example, to calculate the
+ // offset of q0, use s0's offset.
+ if (g_register_infos[2].byte_offset == 0) {
+ uint32_t byte_offset = 0;
+ for (i = 0; i < num_registers; ++i) {
+ // For primordial registers, increment the byte_offset by the byte_size
+ // to arrive at the
+ // byte_offset for the next register. Otherwise, we have a composite
+ // register whose
+ // offset can be calculated by consulting the offset of its first
+ // primordial register.
+ if (!g_register_infos[i].value_regs) {
+ g_register_infos[i].byte_offset = byte_offset;
+ byte_offset += g_register_infos[i].byte_size;
+ } else {
+ const uint32_t first_primordial_reg =
+ g_register_infos[i].value_regs[0];
+ g_register_infos[i].byte_offset =
+ g_register_infos[first_primordial_reg].byte_offset;
}
+ }
}
- else
- {
- // Add composite registers to our primordial registers, then.
- const size_t num_composites = llvm::array_lengthof(g_composites);
- const size_t num_dynamic_regs = GetNumRegisters();
- const size_t num_common_regs = num_registers - num_composites;
- RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
-
- // First we need to validate that all registers that we already have match the non composite regs.
- // If so, then we can add the registers, else we need to bail
- bool match = true;
- if (num_dynamic_regs == num_common_regs)
- {
- for (i=0; match && i<num_dynamic_regs; ++i)
- {
- // Make sure all register names match
- if (m_regs[i].name && g_register_infos[i].name)
- {
- if (strcmp(m_regs[i].name, g_register_infos[i].name))
- {
- match = false;
- break;
- }
- }
-
- // Make sure all register byte sizes match
- if (m_regs[i].byte_size != g_register_infos[i].byte_size)
- {
- match = false;
- break;
- }
- }
- }
- else
- {
- // Wrong number of registers.
+ for (i = 0; i < num_registers; ++i) {
+ ConstString name;
+ ConstString alt_name;
+ if (g_register_infos[i].name && g_register_infos[i].name[0])
+ name.SetCString(g_register_infos[i].name);
+ if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
+ alt_name.SetCString(g_register_infos[i].alt_name);
+
+ if (i <= 15 || i == 25)
+ AddRegister(g_register_infos[i], name, alt_name, gpr_reg_set);
+ else if (i <= 24)
+ AddRegister(g_register_infos[i], name, alt_name, sfp_reg_set);
+ else
+ AddRegister(g_register_infos[i], name, alt_name, vfp_reg_set);
+ }
+ } else {
+ // Add composite registers to our primordial registers, then.
+ const size_t num_composites = llvm::array_lengthof(g_composites);
+ const size_t num_dynamic_regs = GetNumRegisters();
+ const size_t num_common_regs = num_registers - num_composites;
+ RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
+
+ // First we need to validate that all registers that we already have match
+ // the non composite regs.
+ // If so, then we can add the registers, else we need to bail
+ bool match = true;
+ if (num_dynamic_regs == num_common_regs) {
+ for (i = 0; match && i < num_dynamic_regs; ++i) {
+ // Make sure all register names match
+ if (m_regs[i].name && g_register_infos[i].name) {
+ if (strcmp(m_regs[i].name, g_register_infos[i].name)) {
match = false;
+ break;
+ }
}
- // If "match" is true, then we can add extra registers.
- if (match)
- {
- for (i=0; i<num_composites; ++i)
- {
- ConstString name;
- ConstString alt_name;
- const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0];
- const char *reg_name = g_register_infos[first_primordial_reg].name;
- if (reg_name && reg_name[0])
- {
- for (uint32_t j = 0; j < num_dynamic_regs; ++j)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
- // Find a matching primordial register info entry.
- if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0)
- {
- // The name matches the existing primordial entry.
- // Find and assign the offset, and then add this composite register entry.
- g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
- name.SetCString(g_comp_register_infos[i].name);
- AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set);
- }
- }
- }
+
+ // Make sure all register byte sizes match
+ if (m_regs[i].byte_size != g_register_infos[i].byte_size) {
+ match = false;
+ break;
+ }
+ }
+ } else {
+ // Wrong number of registers.
+ match = false;
+ }
+ // If "match" is true, then we can add extra registers.
+ if (match) {
+ for (i = 0; i < num_composites; ++i) {
+ ConstString name;
+ ConstString alt_name;
+ const uint32_t first_primordial_reg =
+ g_comp_register_infos[i].value_regs[0];
+ const char *reg_name = g_register_infos[first_primordial_reg].name;
+ if (reg_name && reg_name[0]) {
+ for (uint32_t j = 0; j < num_dynamic_regs; ++j) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
+ // Find a matching primordial register info entry.
+ if (reg_info && reg_info->name &&
+ ::strcasecmp(reg_info->name, reg_name) == 0) {
+ // The name matches the existing primordial entry.
+ // Find and assign the offset, and then add this composite
+ // register entry.
+ g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
+ name.SetCString(g_comp_register_infos[i].name);
+ AddRegister(g_comp_register_infos[i], name, alt_name,
+ vfp_reg_set);
}
+ }
}
+ }
}
+ }
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 0e26c69eb2a9..5b3e04eb588e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -16,12 +16,12 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/lldb-enumerations.h"
+#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Target/RegisterContext.h"
-#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
#include "GDBRemoteCommunicationClient.h"
@@ -33,133 +33,102 @@ namespace process_gdb_remote {
class ThreadGDBRemote;
class ProcessGDBRemote;
-class GDBRemoteDynamicRegisterInfo :
- public DynamicRegisterInfo
-{
+class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
public:
- GDBRemoteDynamicRegisterInfo () :
- DynamicRegisterInfo()
- {
- }
+ GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}
- ~GDBRemoteDynamicRegisterInfo() override = default;
+ ~GDBRemoteDynamicRegisterInfo() override = default;
- void
- HardcodeARMRegisters(bool from_scratch);
+ void HardcodeARMRegisters(bool from_scratch);
};
-class GDBRemoteRegisterContext : public RegisterContext
-{
+class GDBRemoteRegisterContext : public RegisterContext {
public:
- GDBRemoteRegisterContext (ThreadGDBRemote &thread,
- uint32_t concrete_frame_idx,
- GDBRemoteDynamicRegisterInfo &reg_info,
- bool read_all_at_once);
+ GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
+ GDBRemoteDynamicRegisterInfo &reg_info,
+ bool read_all_at_once);
+
+ ~GDBRemoteRegisterContext() override;
- ~GDBRemoteRegisterContext() override;
+ void InvalidateAllRegisters() override;
- void
- InvalidateAllRegisters () override;
+ size_t GetRegisterCount() override;
- size_t
- GetRegisterCount () override;
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- const RegisterInfo *
- GetRegisterInfoAtIndex (size_t reg) override;
+ size_t GetRegisterSetCount() override;
- size_t
- GetRegisterSetCount () override;
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
- const RegisterSet *
- GetRegisterSet (size_t reg_set) override;
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) override;
- bool
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) override;
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) override;
- bool
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- ReadAllRegisterValues (RegisterCheckpoint &reg_checkpoint) override;
+ bool ReadAllRegisterValues(RegisterCheckpoint &reg_checkpoint) override;
- bool
- WriteAllRegisterValues (const RegisterCheckpoint &reg_checkpoint) override;
+ bool
+ WriteAllRegisterValues(const RegisterCheckpoint &reg_checkpoint) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- friend class ThreadGDBRemote;
-
- bool
- ReadRegisterBytes (const RegisterInfo *reg_info,
- DataExtractor &data);
-
- bool
- WriteRegisterBytes (const RegisterInfo *reg_info,
- DataExtractor &data,
- uint32_t data_offset);
-
- bool
- PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
-
- bool
- PrivateSetRegisterValue (uint32_t reg, uint64_t val);
-
- void
- SetAllRegisterValid (bool b);
-
- bool
- GetRegisterIsValid (uint32_t reg) const
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (reg < m_reg_valid.size());
+ friend class ThreadGDBRemote;
+
+ bool ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data);
+
+ bool WriteRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data,
+ uint32_t data_offset);
+
+ bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
+
+ bool PrivateSetRegisterValue(uint32_t reg, uint64_t val);
+
+ void SetAllRegisterValid(bool b);
+
+ bool GetRegisterIsValid(uint32_t reg) const {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(reg < m_reg_valid.size());
#endif
- if (reg < m_reg_valid.size())
- return m_reg_valid[reg];
- return false;
- }
-
- void
- SetRegisterIsValid (const RegisterInfo *reg_info, bool valid)
- {
- if (reg_info)
- return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
- }
-
- void
- SetRegisterIsValid (uint32_t reg, bool valid)
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (reg < m_reg_valid.size());
+ if (reg < m_reg_valid.size())
+ return m_reg_valid[reg];
+ return false;
+ }
+
+ void SetRegisterIsValid(const RegisterInfo *reg_info, bool valid) {
+ if (reg_info)
+ return SetRegisterIsValid(reg_info->kinds[lldb::eRegisterKindLLDB],
+ valid);
+ }
+
+ void SetRegisterIsValid(uint32_t reg, bool valid) {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(reg < m_reg_valid.size());
#endif
- if (reg < m_reg_valid.size())
- m_reg_valid[reg] = valid;
- }
-
- void
- SyncThreadState(Process *process); // Assumes the sequence mutex has already been acquired.
-
- GDBRemoteDynamicRegisterInfo &m_reg_info;
- std::vector<bool> m_reg_valid;
- DataExtractor m_reg_data;
- bool m_read_all_at_once;
+ if (reg < m_reg_valid.size())
+ m_reg_valid[reg] = valid;
+ }
+
+ GDBRemoteDynamicRegisterInfo &m_reg_info;
+ std::vector<bool> m_reg_valid;
+ DataExtractor m_reg_data;
+ bool m_read_all_at_once;
private:
- // Helper function for ReadRegisterBytes().
- bool GetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm);
- // Helper function for WriteRegisterBytes().
- bool SetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm);
-
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
+ // Helper function for ReadRegisterBytes().
+ bool GetPrimordialRegister(const RegisterInfo *reg_info,
+ GDBRemoteCommunicationClient &gdb_comm);
+ // Helper function for WriteRegisterBytes().
+ bool SetPrimordialRegister(const RegisterInfo *reg_info,
+ GDBRemoteCommunicationClient &gdb_comm);
+
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f501e43b00d7..fac52901e763 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -14,7 +14,8 @@
#include <stdlib.h>
#ifndef LLDB_DISABLE_POSIX
#include <netinet/in.h>
-#include <sys/mman.h> // for mmap
+#include <sys/mman.h> // for mmap
+#include <sys/socket.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
@@ -24,13 +25,11 @@
#include <algorithm>
#include <map>
#include <mutex>
+#include <sstream>
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -40,136 +39,119 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"
#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Host/XML.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Interpreter/Options.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/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
-#include "lldb/Target/SystemRuntime.h"
+#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/PseudoTerminal.h"
// Project includes
-#include "lldb/Host/Host.h"
+#include "GDBRemoteRegisterContext.h"
+#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
-#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
-#include "Utility/StringExtractorGDBRemote.h"
-#include "GDBRemoteRegisterContext.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
+#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Host/Host.h"
-#define DEBUGSERVER_BASENAME "debugserver"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define DEBUGSERVER_BASENAME "debugserver"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-namespace lldb
-{
- // Provide a function that can easily dump the packet history if we know a
- // ProcessGDBRemote * value (which we can get from logs or from debugging).
- // We need the function in the lldb namespace so it makes it into the final
- // executable since the LLDB shared library only exports stuff in the lldb
- // namespace. This allows you to attach with a debugger and call this
- // function and get the packet history dumped to a file.
- void
- DumpProcessGDBRemotePacketHistory (void *p, const char *path)
- {
- StreamFile strm;
- Error error (strm.GetFile().Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate));
- if (error.Success())
- ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory (strm);
- }
+namespace lldb {
+// Provide a function that can easily dump the packet history if we know a
+// ProcessGDBRemote * value (which we can get from logs or from debugging).
+// We need the function in the lldb namespace so it makes it into the final
+// executable since the LLDB shared library only exports stuff in the lldb
+// namespace. This allows you to attach with a debugger and call this
+// function and get the packet history dumped to a file.
+void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
+ StreamFile strm;
+ Error error(strm.GetFile().Open(path, File::eOpenOptionWrite |
+ File::eOpenOptionCanCreate));
+ if (error.Success())
+ ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm);
+}
}
namespace {
- static PropertyDefinition
- g_properties[] =
- {
- { "packet-timeout" , OptionValue::eTypeUInt64 , true , 1, NULL, 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 }
- };
-
- enum
- {
- ePropertyPacketTimeout,
- ePropertyTargetDefinitionFile
- };
+static PropertyDefinition g_properties[] = {
+ {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, 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}};
- class PluginProperties : public Properties
- {
- public:
-
- static ConstString
- GetSettingName ()
- {
- return ProcessGDBRemote::GetPluginNameStatic();
- }
-
- PluginProperties() :
- Properties ()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual
- ~PluginProperties()
- {
- }
-
- uint64_t
- GetPacketTimeout()
- {
- const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
- }
-
- bool
- SetPacketTimeout(uint64_t timeout)
- {
- const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, timeout);
- }
+enum { ePropertyPacketTimeout, ePropertyTargetDefinitionFile };
- FileSpec
- GetTargetDefinitionFile () const
- {
- const uint32_t idx = ePropertyTargetDefinitionFile;
- return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx);
- }
- };
+class PluginProperties : public Properties {
+public:
+ static ConstString GetSettingName() {
+ return ProcessGDBRemote::GetPluginNameStatic();
+ }
+
+ PluginProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~PluginProperties() {}
+
+ uint64_t GetPacketTimeout() {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ NULL, idx, g_properties[idx].default_uint_value);
+ }
+
+ bool SetPacketTimeout(uint64_t timeout) {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, timeout);
+ }
+
+ FileSpec GetTargetDefinitionFile() const {
+ const uint32_t idx = ePropertyTargetDefinitionFile;
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+ }
+};
- typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
- static const ProcessKDPPropertiesSP &
- GetGlobalPluginProperties()
- {
- static ProcessKDPPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new PluginProperties ());
- return g_settings_sp;
- }
+static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
+ static ProcessKDPPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new PluginProperties());
+ return g_settings_sp;
+}
} // anonymous namespace end
@@ -177,3885 +159,3562 @@ namespace {
// ephemeral port from the kernel and make sure we reserve it before passing
// it to debugserver.
-#if defined (__APPLE__)
-#define LOW_PORT (IPPORT_RESERVED)
-#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
+#if defined(__APPLE__)
+#define LOW_PORT (IPPORT_RESERVED)
+#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
#else
-#define LOW_PORT (1024u)
-#define HIGH_PORT (49151u)
+#define LOW_PORT (1024u)
+#define HIGH_PORT (49151u)
#endif
-#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
+#if defined(__APPLE__) && \
+ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
static bool rand_initialized = false;
-static inline uint16_t
-get_random_port ()
-{
- if (!rand_initialized)
- {
- time_t seed = time(NULL);
+static inline uint16_t get_random_port() {
+ if (!rand_initialized) {
+ time_t seed = time(NULL);
- rand_initialized = true;
- srand(seed);
- }
- return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
+ rand_initialized = true;
+ srand(seed);
+ }
+ return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
}
#endif
-ConstString
-ProcessGDBRemote::GetPluginNameStatic()
-{
- static ConstString g_name("gdb-remote");
- return g_name;
+ConstString ProcessGDBRemote::GetPluginNameStatic() {
+ static ConstString g_name("gdb-remote");
+ return g_name;
}
-const char *
-ProcessGDBRemote::GetPluginDescriptionStatic()
-{
- return "GDB Remote protocol based debugging plug-in.";
+const char *ProcessGDBRemote::GetPluginDescriptionStatic() {
+ return "GDB Remote protocol based debugging plug-in.";
}
-void
-ProcessGDBRemote::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessGDBRemote::CreateInstance);
+void ProcessGDBRemote::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessGDBRemote::CreateInstance);
}
-
lldb::ProcessSP
-ProcessGDBRemote::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file_path)
-{
- lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset (new ProcessGDBRemote (target_sp, listener_sp));
- return process_sp;
+ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file_path) {
+ lldb::ProcessSP process_sp;
+ if (crash_file_path == NULL)
+ process_sp.reset(new ProcessGDBRemote(target_sp, listener_sp));
+ return process_sp;
}
-bool
-ProcessGDBRemote::CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- Module *exe_module = target_sp->GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- // We can't debug core files...
- switch (exe_objfile->GetType())
- {
- case ObjectFile::eTypeInvalid:
- case ObjectFile::eTypeCoreFile:
- case ObjectFile::eTypeDebugInfo:
- case ObjectFile::eTypeObjectFile:
- case ObjectFile::eTypeSharedLibrary:
- case ObjectFile::eTypeStubLibrary:
- case ObjectFile::eTypeJIT:
- return false;
- case ObjectFile::eTypeExecutable:
- case ObjectFile::eTypeDynamicLinker:
- case ObjectFile::eTypeUnknown:
- break;
- }
- return exe_module->GetFileSpec().Exists();
- }
- // However, if there is no executable module, we return true since we might be preparing to attach.
+bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
return true;
+
+ // For now we are just making sure the file exists for a given module
+ Module *exe_module = target_sp->GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ // We can't debug core files...
+ switch (exe_objfile->GetType()) {
+ case ObjectFile::eTypeInvalid:
+ case ObjectFile::eTypeCoreFile:
+ case ObjectFile::eTypeDebugInfo:
+ case ObjectFile::eTypeObjectFile:
+ case ObjectFile::eTypeSharedLibrary:
+ case ObjectFile::eTypeStubLibrary:
+ case ObjectFile::eTypeJIT:
+ return false;
+ case ObjectFile::eTypeExecutable:
+ case ObjectFile::eTypeDynamicLinker:
+ case ObjectFile::eTypeUnknown:
+ break;
+ }
+ return exe_module->GetFileSpec().Exists();
+ }
+ // However, if there is no executable module, we return true since we might be
+ // preparing to attach.
+ return true;
}
//----------------------------------------------------------------------
// ProcessGDBRemote constructor
//----------------------------------------------------------------------
-ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, ListenerSP listener_sp)
- : Process(target_sp, listener_sp),
- m_flags(0),
- m_gdb_comm(),
- m_debugserver_pid(LLDB_INVALID_PROCESS_ID),
- m_last_stop_packet_mutex(),
+ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
+ ListenerSP listener_sp)
+ : Process(target_sp, listener_sp), m_flags(0), m_gdb_comm(),
+ m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
m_register_info(),
m_async_broadcaster(NULL, "lldb.process.gdb-remote.async-broadcaster"),
- m_async_listener_sp(Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
- m_async_thread_state_mutex(),
- m_thread_ids(),
- m_thread_pcs(),
- m_jstopinfo_sp(),
- m_jthreadsinfo_sp(),
- m_continue_c_tids(),
- m_continue_C_tids(),
- m_continue_s_tids(),
- m_continue_S_tids(),
- m_max_memory_size(0),
- m_remote_stub_max_memory_size(0),
- 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_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, "async thread continue");
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit, "async thread did exit");
-
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
-
- const uint32_t async_event_mask = eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
-
- if (m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, async_event_mask) != async_event_mask)
- {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for m_async_broadcaster events", __FUNCTION__);
- }
-
- const uint32_t gdb_event_mask =
- Communication::eBroadcastBitReadThreadDidExit | GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
- if (m_async_listener_sp->StartListeningForEvents(&m_gdb_comm, gdb_event_mask) != gdb_event_mask)
- {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events", __FUNCTION__);
- }
-
- const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
- if (timeout_seconds > 0)
- m_gdb_comm.SetPacketTimeout(timeout_seconds);
+ m_async_listener_sp(
+ Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
+ m_async_thread_state_mutex(), m_thread_ids(), m_thread_pcs(),
+ m_jstopinfo_sp(), m_jthreadsinfo_sp(), m_continue_c_tids(),
+ m_continue_C_tids(), m_continue_s_tids(), m_continue_S_tids(),
+ m_max_memory_size(0), m_remote_stub_max_memory_size(0),
+ 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_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
+ "async thread should exit");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
+ "async thread continue");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit,
+ "async thread did exit");
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
+
+ const uint32_t async_event_mask =
+ eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
+
+ if (m_async_listener_sp->StartListeningForEvents(
+ &m_async_broadcaster, async_event_mask) != async_event_mask) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s failed to listen for "
+ "m_async_broadcaster events",
+ __FUNCTION__);
+ }
+
+ const uint32_t gdb_event_mask =
+ Communication::eBroadcastBitReadThreadDidExit |
+ GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
+ if (m_async_listener_sp->StartListeningForEvents(
+ &m_gdb_comm, gdb_event_mask) != gdb_event_mask) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events",
+ __FUNCTION__);
+ }
+
+ const uint64_t timeout_seconds =
+ GetGlobalPluginProperties()->GetPacketTimeout();
+ if (timeout_seconds > 0)
+ m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessGDBRemote::~ProcessGDBRemote()
-{
- // m_mach_process.UnregisterNotificationCallbacks (this);
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
-
- // The general Finalize is going to try to destroy the process and that SHOULD
- // shut down the async thread. However, if we don't kill it it will get stranded and
- // its connection will go away so when it wakes up it will crash. So kill it for sure here.
- StopAsyncThread();
- KillDebugserverProcess();
+ProcessGDBRemote::~ProcessGDBRemote() {
+ // m_mach_process.UnregisterNotificationCallbacks (this);
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
+
+ // The general Finalize is going to try to destroy the process and that SHOULD
+ // shut down the async thread. However, if we don't kill it it will get
+ // stranded and
+ // its connection will go away so when it wakes up it will crash. So kill it
+ // for sure here.
+ StopAsyncThread();
+ KillDebugserverProcess();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-ConstString
-ProcessGDBRemote::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessGDBRemote::GetPluginVersion()
-{
- return 1;
-}
-
-bool
-ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
-{
- ScriptInterpreter *interpreter = GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- Error error;
- StructuredData::ObjectSP module_object_sp(interpreter->LoadPluginModule(target_definition_fspec, error));
- if (module_object_sp)
- {
- StructuredData::DictionarySP target_definition_sp(
- interpreter->GetDynamicSettings(module_object_sp, &GetTarget(), "gdb-server-target-definition", error));
-
- if (target_definition_sp)
- {
- StructuredData::ObjectSP target_object(target_definition_sp->GetValueForKey("host-info"));
- if (target_object)
- {
- if (auto host_info_dict = target_object->GetAsDictionary())
- {
- StructuredData::ObjectSP triple_value = host_info_dict->GetValueForKey("triple");
- if (auto triple_string_value = triple_value->GetAsString())
- {
- std::string triple_string = triple_string_value->GetValue();
- ArchSpec host_arch(triple_string.c_str());
- if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture()))
- {
- GetTarget().SetArchitecture(host_arch);
- }
- }
- }
- }
- m_breakpoint_pc_offset = 0;
- StructuredData::ObjectSP breakpoint_pc_offset_value = target_definition_sp->GetValueForKey("breakpoint-pc-offset");
- if (breakpoint_pc_offset_value)
- {
- if (auto breakpoint_pc_int_value = breakpoint_pc_offset_value->GetAsInteger())
- m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
- }
-
- if (m_register_info.SetRegisterInfo(*target_definition_sp, GetTarget().GetArchitecture()) > 0)
- {
- return true;
+ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ProcessGDBRemote::GetPluginVersion() { return 1; }
+
+bool ProcessGDBRemote::ParsePythonTargetDefinition(
+ const FileSpec &target_definition_fspec) {
+ ScriptInterpreter *interpreter =
+ GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ Error error;
+ StructuredData::ObjectSP module_object_sp(
+ interpreter->LoadPluginModule(target_definition_fspec, error));
+ if (module_object_sp) {
+ StructuredData::DictionarySP target_definition_sp(
+ interpreter->GetDynamicSettings(module_object_sp, &GetTarget(),
+ "gdb-server-target-definition", error));
+
+ if (target_definition_sp) {
+ StructuredData::ObjectSP target_object(
+ target_definition_sp->GetValueForKey("host-info"));
+ if (target_object) {
+ if (auto host_info_dict = target_object->GetAsDictionary()) {
+ StructuredData::ObjectSP triple_value =
+ host_info_dict->GetValueForKey("triple");
+ if (auto triple_string_value = triple_value->GetAsString()) {
+ std::string triple_string = triple_string_value->GetValue();
+ ArchSpec host_arch(triple_string.c_str());
+ if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) {
+ GetTarget().SetArchitecture(host_arch);
}
+ }
}
+ }
+ m_breakpoint_pc_offset = 0;
+ StructuredData::ObjectSP breakpoint_pc_offset_value =
+ target_definition_sp->GetValueForKey("breakpoint-pc-offset");
+ if (breakpoint_pc_offset_value) {
+ if (auto breakpoint_pc_int_value =
+ breakpoint_pc_offset_value->GetAsInteger())
+ m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
+ }
+
+ if (m_register_info.SetRegisterInfo(*target_definition_sp,
+ GetTarget().GetArchitecture()) > 0) {
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-// If the remote stub didn't give us eh_frame or DWARF register numbers for a register,
+// If the remote stub didn't give us eh_frame or DWARF register numbers for a
+// register,
// see if the ABI can provide them.
// DWARF and eh_frame register numbers are defined as a part of the ABI.
-static void
-AugmentRegisterInfoViaABI (RegisterInfo &reg_info, ConstString reg_name, ABISP abi_sp)
-{
- if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM
- || reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM)
- {
- if (abi_sp)
- {
- RegisterInfo abi_reg_info;
- if (abi_sp->GetRegisterInfoByName (reg_name, abi_reg_info))
- {
- if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindEHFrame] = abi_reg_info.kinds[eRegisterKindEHFrame];
- }
- if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindDWARF] = abi_reg_info.kinds[eRegisterKindDWARF];
- }
- if (reg_info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindGeneric] = abi_reg_info.kinds[eRegisterKindGeneric];
- }
- }
+static void AugmentRegisterInfoViaABI(RegisterInfo &reg_info,
+ ConstString reg_name, ABISP abi_sp) {
+ if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM ||
+ reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) {
+ if (abi_sp) {
+ RegisterInfo abi_reg_info;
+ if (abi_sp->GetRegisterInfoByName(reg_name, abi_reg_info)) {
+ if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM &&
+ abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindEHFrame] =
+ abi_reg_info.kinds[eRegisterKindEHFrame];
}
- }
-}
-
-static size_t
-SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_regiter_numbers, std::vector<uint32_t> &regnums, int base)
-{
- regnums.clear();
- std::pair<llvm::StringRef, llvm::StringRef> value_pair;
- value_pair.second = comma_separated_regiter_numbers;
- do
- {
- value_pair = value_pair.second.split(',');
- if (!value_pair.first.empty())
- {
- uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, base);
- if (reg != LLDB_INVALID_REGNUM)
- regnums.push_back (reg);
- }
- } while (!value_pair.second.empty());
- return regnums.size();
-}
-
-
-void
-ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
-{
- if (!force && m_register_info.GetNumRegisters() > 0)
- return;
-
- m_register_info.Clear();
-
- // Check if qHostInfo specified a specific packet timeout for this connection.
- // If so then lets update our setting so the user knows what the timeout is
- // and can see it.
- const uint32_t host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
- if (host_packet_timeout)
- {
- GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout);
- }
-
- // Register info search order:
- // 1 - Use the target definition python file if one is specified.
- // 2 - If the target definition doesn't have any of the info from the target.xml (registers) then proceed to read the target.xml.
- // 3 - Fall back on the qRegisterInfo packets.
-
- FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile ();
- if (!target_definition_fspec.Exists())
- {
- // If the filename doesn't exist, it may be a ~ not having been expanded - try to resolve it.
- target_definition_fspec.ResolvePath();
- }
- if (target_definition_fspec)
- {
- // See if we can get register definitions from a python file
- if (ParsePythonTargetDefinition (target_definition_fspec))
- {
- return;
+ if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM &&
+ abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindDWARF] =
+ abi_reg_info.kinds[eRegisterKindDWARF];
}
- else
- {
- StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
- stream_sp->Printf ("ERROR: target description file %s failed to parse.\n", target_definition_fspec.GetPath().c_str());
+ if (reg_info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM &&
+ abi_reg_info.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindGeneric] =
+ abi_reg_info.kinds[eRegisterKindGeneric];
}
+ }
}
+ }
+}
- const ArchSpec &target_arch = GetTarget().GetArchitecture();
- const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
- const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+static size_t SplitCommaSeparatedRegisterNumberString(
+ const llvm::StringRef &comma_separated_regiter_numbers,
+ std::vector<uint32_t> &regnums, int base) {
+ regnums.clear();
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = comma_separated_regiter_numbers;
+ do {
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty()) {
+ uint32_t reg = StringConvert::ToUInt32(value_pair.first.str().c_str(),
+ LLDB_INVALID_REGNUM, base);
+ if (reg != LLDB_INVALID_REGNUM)
+ regnums.push_back(reg);
+ }
+ } while (!value_pair.second.empty());
+ return regnums.size();
+}
- // Use the process' architecture instead of the host arch, if available
- ArchSpec arch_to_use;
- if (remote_process_arch.IsValid ())
- arch_to_use = remote_process_arch;
- else
- arch_to_use = remote_host_arch;
-
- if (!arch_to_use.IsValid())
- arch_to_use = target_arch;
-
- if (GetGDBServerRegisterInfo (arch_to_use))
- return;
-
- char packet[128];
- uint32_t reg_offset = 0;
- uint32_t reg_num = 0;
- for (StringExtractorGDBRemote::ResponseType response_type = StringExtractorGDBRemote::eResponse;
- response_type == StringExtractorGDBRemote::eResponse;
- ++reg_num)
- {
- const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- response_type = response.GetResponseType();
- if (response_type == StringExtractorGDBRemote::eResponse)
+void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
+ if (!force && m_register_info.GetNumRegisters() > 0)
+ return;
+
+ m_register_info.Clear();
+
+ // Check if qHostInfo specified a specific packet timeout for this connection.
+ // If so then lets update our setting so the user knows what the timeout is
+ // and can see it.
+ const auto host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
+ if (host_packet_timeout > std::chrono::seconds(0)) {
+ GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout.count());
+ }
+
+ // Register info search order:
+ // 1 - Use the target definition python file if one is specified.
+ // 2 - If the target definition doesn't have any of the info from the
+ // target.xml (registers) then proceed to read the target.xml.
+ // 3 - Fall back on the qRegisterInfo packets.
+
+ FileSpec target_definition_fspec =
+ GetGlobalPluginProperties()->GetTargetDefinitionFile();
+ if (!target_definition_fspec.Exists()) {
+ // If the filename doesn't exist, it may be a ~ not having been expanded -
+ // try to resolve it.
+ target_definition_fspec.ResolvePath();
+ }
+ if (target_definition_fspec) {
+ // See if we can get register definitions from a python file
+ if (ParsePythonTargetDefinition(target_definition_fspec)) {
+ return;
+ } else {
+ StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
+ stream_sp->Printf("ERROR: target description file %s failed to parse.\n",
+ target_definition_fspec.GetPath().c_str());
+ }
+ }
+
+ const ArchSpec &target_arch = GetTarget().GetArchitecture();
+ const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ // Use the process' architecture instead of the host arch, if available
+ ArchSpec arch_to_use;
+ if (remote_process_arch.IsValid())
+ arch_to_use = remote_process_arch;
+ else
+ arch_to_use = remote_host_arch;
+
+ if (!arch_to_use.IsValid())
+ arch_to_use = target_arch;
+
+ if (GetGDBServerRegisterInfo(arch_to_use))
+ return;
+
+ char packet[128];
+ uint32_t reg_offset = 0;
+ uint32_t reg_num = 0;
+ for (StringExtractorGDBRemote::ResponseType response_type =
+ StringExtractorGDBRemote::eResponse;
+ response_type == StringExtractorGDBRemote::eResponse; ++reg_num) {
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qRegisterInfo%x", reg_num);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ response_type = response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ ConstString reg_name;
+ ConstString alt_name;
+ ConstString set_name;
+ std::vector<uint32_t> value_regs;
+ std::vector<uint32_t> invalidate_regs;
+ std::vector<uint8_t> dwarf_opcode_bytes;
+ RegisterInfo reg_info = {
+ NULL, // Name
+ NULL, // Alt name
+ 0, // byte size
+ reg_offset, // offset
+ eEncodingUint, // encoding
+ eFormatHex, // format
{
- std::string name;
- std::string value;
- ConstString reg_name;
- ConstString alt_name;
- ConstString set_name;
- std::vector<uint32_t> value_regs;
- std::vector<uint32_t> invalidate_regs;
- std::vector<uint8_t> dwarf_opcode_bytes;
- RegisterInfo reg_info = { NULL, // Name
- NULL, // Alt name
- 0, // byte size
- reg_offset, // offset
- eEncodingUint, // encoding
- eFormatHex, // format
- {
- LLDB_INVALID_REGNUM, // eh_frame reg num
- LLDB_INVALID_REGNUM, // DWARF reg num
- LLDB_INVALID_REGNUM, // generic reg num
- reg_num, // process plugin reg num
- reg_num // native register number
- },
- NULL,
- NULL,
- NULL, // Dwarf expression opcode bytes pointer
- 0 // Dwarf expression opcode bytes length
- };
-
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("name") == 0)
- {
- reg_name.SetCString(value.c_str());
- }
- else if (name.compare("alt-name") == 0)
- {
- alt_name.SetCString(value.c_str());
- }
- else if (name.compare("bitsize") == 0)
- {
- reg_info.byte_size = StringConvert::ToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
- }
- else if (name.compare("offset") == 0)
- {
- uint32_t offset = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
- if (reg_offset != offset)
- {
- reg_offset = offset;
- }
- }
- else if (name.compare("encoding") == 0)
- {
- const Encoding encoding = Args::StringToEncoding (value.c_str());
- if (encoding != eEncodingInvalid)
- reg_info.encoding = encoding;
- }
- else if (name.compare("format") == 0)
- {
- Format format = eFormatInvalid;
- if (Args::StringToFormat (value.c_str(), format, NULL).Success())
- reg_info.format = format;
- else if (value.compare("binary") == 0)
- reg_info.format = eFormatBinary;
- else if (value.compare("decimal") == 0)
- reg_info.format = eFormatDecimal;
- else if (value.compare("hex") == 0)
- reg_info.format = eFormatHex;
- else if (value.compare("float") == 0)
- reg_info.format = eFormatFloat;
- else if (value.compare("vector-sint8") == 0)
- reg_info.format = eFormatVectorOfSInt8;
- else if (value.compare("vector-uint8") == 0)
- reg_info.format = eFormatVectorOfUInt8;
- else if (value.compare("vector-sint16") == 0)
- reg_info.format = eFormatVectorOfSInt16;
- else if (value.compare("vector-uint16") == 0)
- reg_info.format = eFormatVectorOfUInt16;
- else if (value.compare("vector-sint32") == 0)
- reg_info.format = eFormatVectorOfSInt32;
- else if (value.compare("vector-uint32") == 0)
- reg_info.format = eFormatVectorOfUInt32;
- else if (value.compare("vector-float32") == 0)
- reg_info.format = eFormatVectorOfFloat32;
- else if (value.compare("vector-uint128") == 0)
- reg_info.format = eFormatVectorOfUInt128;
- }
- else if (name.compare("set") == 0)
- {
- set_name.SetCString(value.c_str());
- }
- else if (name.compare("gcc") == 0 || name.compare("ehframe") == 0)
- {
- reg_info.kinds[eRegisterKindEHFrame] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name.compare("dwarf") == 0)
- {
- reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name.compare("generic") == 0)
- {
- reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str());
- }
- else if (name.compare("container-regs") == 0)
- {
- SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
- }
- else if (name.compare("invalidate-regs") == 0)
- {
- SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
- }
- else if (name.compare("dynamic_size_dwarf_expr_bytes") == 0)
- {
- size_t dwarf_opcode_len = value.length () / 2;
- assert (dwarf_opcode_len > 0);
-
- dwarf_opcode_bytes.resize (dwarf_opcode_len);
- StringExtractor opcode_extractor;
- reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
-
- // Swap "value" over into "opcode_extractor"
- opcode_extractor.GetStringRef ().swap (value);
- uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (),
- dwarf_opcode_len);
- assert (dwarf_opcode_len == ret_val);
-
- reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data ();
- }
- }
-
- reg_info.byte_offset = reg_offset;
- assert (reg_info.byte_size != 0);
- reg_offset += reg_info.byte_size;
- if (!value_regs.empty())
- {
- value_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.value_regs = value_regs.data();
- }
- if (!invalidate_regs.empty())
- {
- invalidate_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.invalidate_regs = invalidate_regs.data();
- }
-
- // We have to make a temporary ABI here, and not use the GetABI because this code
- // gets called in DidAttach, when the target architecture (and consequently the ABI we'll get from
- // the process) may be wrong.
- ABISP abi_to_use = ABI::FindPlugin(arch_to_use);
-
- AugmentRegisterInfoViaABI (reg_info, reg_name, abi_to_use);
+ LLDB_INVALID_REGNUM, // eh_frame reg num
+ LLDB_INVALID_REGNUM, // DWARF reg num
+ LLDB_INVALID_REGNUM, // generic reg num
+ reg_num, // process plugin reg num
+ reg_num // native register number
+ },
+ NULL,
+ NULL,
+ NULL, // Dwarf expression opcode bytes pointer
+ 0 // Dwarf expression opcode bytes length
+ };
- m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("name")) {
+ reg_name.SetString(value);
+ } else if (name.equals("alt-name")) {
+ alt_name.SetString(value);
+ } else if (name.equals("bitsize")) {
+ value.getAsInteger(0, reg_info.byte_size);
+ reg_info.byte_size /= CHAR_BIT;
+ } else if (name.equals("offset")) {
+ if (value.getAsInteger(0, reg_offset))
+ reg_offset = UINT32_MAX;
+ } else if (name.equals("encoding")) {
+ const Encoding encoding = Args::StringToEncoding(value);
+ if (encoding != eEncodingInvalid)
+ reg_info.encoding = encoding;
+ } else if (name.equals("format")) {
+ Format format = eFormatInvalid;
+ if (Args::StringToFormat(value.str().c_str(), format, NULL)
+ .Success())
+ reg_info.format = format;
+ else {
+ reg_info.format =
+ llvm::StringSwitch<Format>(value)
+ .Case("binary", eFormatBinary)
+ .Case("decimal", eFormatDecimal)
+ .Case("hex", eFormatHex)
+ .Case("float", eFormatFloat)
+ .Case("vector-sint8", eFormatVectorOfSInt8)
+ .Case("vector-uint8", eFormatVectorOfUInt8)
+ .Case("vector-sint16", eFormatVectorOfSInt16)
+ .Case("vector-uint16", eFormatVectorOfUInt16)
+ .Case("vector-sint32", eFormatVectorOfSInt32)
+ .Case("vector-uint32", eFormatVectorOfUInt32)
+ .Case("vector-float32", eFormatVectorOfFloat32)
+ .Case("vector-uint64", eFormatVectorOfUInt64)
+ .Case("vector-uint128", eFormatVectorOfUInt128)
+ .Default(eFormatInvalid);
}
- else
- {
- break; // ensure exit before reg_num is incremented
- }
- }
- else
- {
- break;
+ } else if (name.equals("set")) {
+ set_name.SetString(value);
+ } else if (name.equals("gcc") || name.equals("ehframe")) {
+ if (value.getAsInteger(0, reg_info.kinds[eRegisterKindEHFrame]))
+ reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
+ } else if (name.equals("dwarf")) {
+ if (value.getAsInteger(0, reg_info.kinds[eRegisterKindDWARF]))
+ reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+ } else if (name.equals("generic")) {
+ reg_info.kinds[eRegisterKindGeneric] =
+ Args::StringToGenericRegister(value);
+ } else if (name.equals("container-regs")) {
+ SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
+ } else if (name.equals("invalidate-regs")) {
+ SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
+ } else if (name.equals("dynamic_size_dwarf_expr_bytes")) {
+ size_t dwarf_opcode_len = value.size() / 2;
+ assert(dwarf_opcode_len > 0);
+
+ dwarf_opcode_bytes.resize(dwarf_opcode_len);
+ reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
+
+ StringExtractor opcode_extractor(value);
+ uint32_t ret_val =
+ opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+ assert(dwarf_opcode_len == ret_val);
+
+ reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data();
+ }
}
- }
- if (m_register_info.GetNumRegisters() > 0)
- {
- m_register_info.Finalize(GetTarget().GetArchitecture());
- return;
- }
+ reg_info.byte_offset = reg_offset;
+ assert(reg_info.byte_size != 0);
+ reg_offset += reg_info.byte_size;
+ if (!value_regs.empty()) {
+ value_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = value_regs.data();
+ }
+ if (!invalidate_regs.empty()) {
+ invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = invalidate_regs.data();
+ }
- // We didn't get anything if the accumulated reg_num is zero. See if we are
- // debugging ARM and fill with a hard coded register set until we can get an
- // updated debugserver down on the devices.
- // On the other hand, if the accumulated reg_num is positive, see if we can
- // add composite registers to the existing primordial ones.
- bool from_scratch = (m_register_info.GetNumRegisters() == 0);
+ // We have to make a temporary ABI here, and not use the GetABI because
+ // this code
+ // gets called in DidAttach, when the target architecture (and
+ // consequently the ABI we'll get from
+ // the process) may be wrong.
+ ABISP abi_to_use = ABI::FindPlugin(arch_to_use);
- if (!target_arch.IsValid())
- {
- if (arch_to_use.IsValid()
- && (arch_to_use.GetMachine() == llvm::Triple::arm || arch_to_use.GetMachine() == llvm::Triple::thumb)
- && arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
- m_register_info.HardcodeARMRegisters(from_scratch);
- }
- else if (target_arch.GetMachine() == llvm::Triple::arm
- || target_arch.GetMachine() == llvm::Triple::thumb)
- {
- m_register_info.HardcodeARMRegisters(from_scratch);
- }
+ AugmentRegisterInfoViaABI(reg_info, reg_name, abi_to_use);
- // At this point, we can finalize our register info.
- m_register_info.Finalize (GetTarget().GetArchitecture());
+ m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+ } else {
+ break; // ensure exit before reg_num is incremented
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (m_register_info.GetNumRegisters() > 0) {
+ m_register_info.Finalize(GetTarget().GetArchitecture());
+ return;
+ }
+
+ // We didn't get anything if the accumulated reg_num is zero. See if we are
+ // debugging ARM and fill with a hard coded register set until we can get an
+ // updated debugserver down on the devices.
+ // On the other hand, if the accumulated reg_num is positive, see if we can
+ // add composite registers to the existing primordial ones.
+ bool from_scratch = (m_register_info.GetNumRegisters() == 0);
+
+ if (!target_arch.IsValid()) {
+ if (arch_to_use.IsValid() &&
+ (arch_to_use.GetMachine() == llvm::Triple::arm ||
+ arch_to_use.GetMachine() == llvm::Triple::thumb) &&
+ arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
+ m_register_info.HardcodeARMRegisters(from_scratch);
+ } else if (target_arch.GetMachine() == llvm::Triple::arm ||
+ target_arch.GetMachine() == llvm::Triple::thumb) {
+ m_register_info.HardcodeARMRegisters(from_scratch);
+ }
+
+ // At this point, we can finalize our register info.
+ m_register_info.Finalize(GetTarget().GetArchitecture());
}
-Error
-ProcessGDBRemote::WillLaunch (Module* module)
-{
- return WillLaunchOrAttach ();
+Error ProcessGDBRemote::WillLaunch(Module *module) {
+ return WillLaunchOrAttach();
}
-Error
-ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid)
-{
- return WillLaunchOrAttach ();
+Error ProcessGDBRemote::WillAttachToProcessWithID(lldb::pid_t pid) {
+ return WillLaunchOrAttach();
}
-Error
-ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
-{
- return WillLaunchOrAttach ();
+Error ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) {
+ return WillLaunchOrAttach();
}
-Error
-ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- Error error (WillLaunchOrAttach ());
-
- if (error.Fail())
- return error;
-
- error = ConnectToDebugserver (remote_url);
+Error ProcessGDBRemote::DoConnectRemote(Stream *strm,
+ llvm::StringRef remote_url) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Error error(WillLaunchOrAttach());
- if (error.Fail())
- return error;
- StartAsyncThread ();
-
- lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
- if (pid == LLDB_INVALID_PROCESS_ID)
- {
- // We don't have a valid process ID, so note that we are connected
- // and could now request to launch or attach, or get remote process
- // listings...
- SetPrivateState (eStateConnected);
- }
- else
- {
- // We have a valid process
- SetID (pid);
- GetThreadList();
- StringExtractorGDBRemote response;
- if (m_gdb_comm.GetStopReply(response))
- {
- SetLastStopPacket(response);
+ if (error.Fail())
+ return error;
- // '?' Packets must be handled differently in non-stop mode
- if (GetTarget().GetNonStopModeEnabled())
- HandleStopReplySequence();
+ error = ConnectToDebugserver(remote_url);
- Target &target = GetTarget();
- if (!target.GetArchitecture().IsValid())
- {
- if (m_gdb_comm.GetProcessArchitecture().IsValid())
- {
- target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
- }
- else
- {
- target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
- }
- }
-
- const StateType state = SetThreadStopInfo (response);
- if (state != eStateInvalid)
- {
- SetPrivateState (state);
- }
- else
- error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
+ if (error.Fail())
+ return error;
+ StartAsyncThread();
+
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ if (pid == LLDB_INVALID_PROCESS_ID) {
+ // We don't have a valid process ID, so note that we are connected
+ // and could now request to launch or attach, or get remote process
+ // listings...
+ SetPrivateState(eStateConnected);
+ } else {
+ // We have a valid process
+ SetID(pid);
+ GetThreadList();
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.GetStopReply(response)) {
+ SetLastStopPacket(response);
+
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
+ Target &target = GetTarget();
+ if (!target.GetArchitecture().IsValid()) {
+ if (m_gdb_comm.GetProcessArchitecture().IsValid()) {
+ target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ } else {
+ target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
}
- else
- error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
- }
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalizing target architecture initial triple: %s (GetTarget().GetArchitecture().IsValid() %s, m_gdb_comm.GetHostArchitecture().IsValid(): %s)", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str (), GetTarget ().GetArchitecture ().IsValid () ? "true" : "false", m_gdb_comm.GetHostArchitecture ().IsValid () ? "true" : "false");
-
-
- if (error.Success()
- && !GetTarget().GetArchitecture().IsValid()
- && m_gdb_comm.GetHostArchitecture().IsValid())
- {
- // Prefer the *process'* architecture over that of the *host*, if available.
- if (m_gdb_comm.GetProcessArchitecture().IsValid())
- GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
- else
- GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
- }
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ());
-
- if (error.Success())
- {
- PlatformSP platform_sp = GetTarget().GetPlatform();
- if (platform_sp && platform_sp->IsConnected())
- SetUnixSignals(platform_sp->GetUnixSignals());
- else
- SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture()));
- }
+ }
+
+ const StateType state = SetThreadStopInfo(response);
+ if (state != eStateInvalid) {
+ SetPrivateState(state);
+ } else
+ error.SetErrorStringWithFormat(
+ "Process %" PRIu64 " was reported after connecting to "
+ "'%s', but state was not stopped: %s",
+ pid, remote_url.str().c_str(), StateAsCString(state));
+ } else
+ error.SetErrorStringWithFormat("Process %" PRIu64
+ " was reported after connecting to '%s', "
+ "but no stop reply packet was received",
+ pid, remote_url.str().c_str());
+ }
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s pid %" PRIu64
+ ": normalizing target architecture initial triple: %s "
+ "(GetTarget().GetArchitecture().IsValid() %s, "
+ "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
+ GetTarget().GetArchitecture().IsValid() ? "true" : "false",
+ m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");
+
+ if (error.Success() && !GetTarget().GetArchitecture().IsValid() &&
+ m_gdb_comm.GetHostArchitecture().IsValid()) {
+ // Prefer the *process'* architecture over that of the *host*, if available.
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ else
+ GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ }
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s pid %" PRIu64
+ ": normalized target architecture triple: %s",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+
+ if (error.Success()) {
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+ if (platform_sp && platform_sp->IsConnected())
+ SetUnixSignals(platform_sp->GetUnixSignals());
+ else
+ SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture()));
+ }
- return error;
+ return error;
}
-Error
-ProcessGDBRemote::WillLaunchOrAttach ()
-{
- Error error;
- m_stdio_communication.Clear ();
- return error;
+Error ProcessGDBRemote::WillLaunchOrAttach() {
+ Error error;
+ m_stdio_communication.Clear();
+ return error;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
-Error
-ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- Error error;
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s() entered", __FUNCTION__);
-
- uint32_t launch_flags = launch_info.GetFlags().Get();
- FileSpec stdin_file_spec{};
- FileSpec stdout_file_spec{};
- FileSpec stderr_file_spec{};
- FileSpec working_dir = launch_info.GetWorkingDirectory();
-
- const FileAction *file_action;
- file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
- if (file_action)
- {
- if (file_action->GetAction() == FileAction::eFileActionOpen)
- stdin_file_spec = file_action->GetFileSpec();
- }
- file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
- if (file_action)
- {
- if (file_action->GetAction() == FileAction::eFileActionOpen)
- stdout_file_spec = file_action->GetFileSpec();
- }
- file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
- if (file_action)
- {
- if (file_action->GetAction() == FileAction::eFileActionOpen)
- stderr_file_spec = file_action->GetFileSpec();
- }
-
- if (log)
- {
- if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
- log->Printf ("ProcessGDBRemote::%s provided with STDIO paths via launch_info: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
- else
- log->Printf ("ProcessGDBRemote::%s no STDIO paths given via launch_info", __FUNCTION__);
- }
-
- const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
- if (stdin_file_spec || disable_stdio)
- {
- // the inferior will be reading stdin from the specified file
- // or stdio is completely disabled
- m_stdin_forward = false;
- }
+Error ProcessGDBRemote::DoLaunch(Module *exe_module,
+ ProcessLaunchInfo &launch_info) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Error error;
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s() entered", __FUNCTION__);
+
+ uint32_t launch_flags = launch_info.GetFlags().Get();
+ FileSpec stdin_file_spec{};
+ FileSpec stdout_file_spec{};
+ FileSpec stderr_file_spec{};
+ FileSpec working_dir = launch_info.GetWorkingDirectory();
+
+ const FileAction *file_action;
+ file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
+ if (file_action) {
+ if (file_action->GetAction() == FileAction::eFileActionOpen)
+ stdin_file_spec = file_action->GetFileSpec();
+ }
+ file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
+ if (file_action) {
+ if (file_action->GetAction() == FileAction::eFileActionOpen)
+ stdout_file_spec = file_action->GetFileSpec();
+ }
+ file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
+ if (file_action) {
+ if (file_action->GetAction() == FileAction::eFileActionOpen)
+ stderr_file_spec = file_action->GetFileSpec();
+ }
+
+ if (log) {
+ if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
+ log->Printf("ProcessGDBRemote::%s provided with STDIO paths via "
+ "launch_info: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
else
- {
- m_stdin_forward = true;
- }
-
- // ::LogSetBitMask (GDBR_LOG_DEFAULT);
- // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
- // ::LogSetLogFile ("/dev/stdout");
-
- ObjectFile * object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- error = EstablishConnectionIfNeeded (launch_info);
- if (error.Success())
- {
- lldb_utility::PseudoTerminal pty;
- const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
-
- PlatformSP platform_sp (GetTarget().GetPlatform());
- 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);
- if (!stdout_file_spec)
- stdout_file_spec.SetFile(FileSystem::DEV_NULL, false);
- if (!stderr_file_spec)
- stderr_file_spec.SetFile(FileSystem::DEV_NULL, false);
- }
- else if (platform_sp && platform_sp->IsHost())
- {
- // If the debugserver is local and we aren't disabling STDIO, lets use
- // a pseudo terminal to instead of relying on the 'O' packets for stdio
- // since 'O' packets can really slow down debugging if the inferior
- // 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};
-
- if (!stdin_file_spec)
- stdin_file_spec = slave_name;
-
- if (!stdout_file_spec)
- stdout_file_spec = slave_name;
-
- if (!stderr_file_spec)
- stderr_file_spec = slave_name;
- }
- if (log)
- log->Printf ("ProcessGDBRemote::%s adjusted STDIO paths for local platform (IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
- }
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
-
- if (stdin_file_spec)
- m_gdb_comm.SetSTDIN(stdin_file_spec);
- if (stdout_file_spec)
- m_gdb_comm.SetSTDOUT(stdout_file_spec);
- if (stderr_file_spec)
- m_gdb_comm.SetSTDERR(stderr_file_spec);
-
- m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR);
- m_gdb_comm.SetDetachOnError (launch_flags & eLaunchFlagDetachOnError);
-
- m_gdb_comm.SendLaunchArchPacket (GetTarget().GetArchitecture().GetArchitectureName());
-
- const char * launch_event_data = launch_info.GetLaunchEventData();
- if (launch_event_data != NULL && *launch_event_data != '\0')
- m_gdb_comm.SendLaunchEventDataPacket (launch_event_data);
-
- if (working_dir)
- {
- m_gdb_comm.SetWorkingDir (working_dir);
- }
-
- // Send the environment and the program + arguments after we connect
- const Args &environment = launch_info.GetEnvironmentEntries();
- if (environment.GetArgumentCount())
- {
- size_t num_environment_entries = environment.GetArgumentCount();
- for (size_t i=0; i<num_environment_entries; ++i)
- {
- const char *env_entry = environment.GetArgumentAtIndex(i);
- if (env_entry == NULL || m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
- break;
- }
- }
-
- {
- // Scope for the scoped timeout object
- GDBRemoteCommunication::ScopedTimeout timeout (m_gdb_comm, 10);
-
- int arg_packet_err = m_gdb_comm.SendArgumentsPacket (launch_info);
- if (arg_packet_err == 0)
- {
- std::string error_str;
- if (m_gdb_comm.GetLaunchSuccess (error_str))
- {
- SetID (m_gdb_comm.GetCurrentProcessID ());
- }
- else
- {
- error.SetErrorString (error_str.c_str());
- }
- }
- else
- {
- error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err);
- }
- }
-
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- {
- if (log)
- log->Printf("failed to connect to debugserver: %s", error.AsCString());
- KillDebugserverProcess ();
- return error;
- }
-
- StringExtractorGDBRemote response;
- if (m_gdb_comm.GetStopReply(response))
- {
- SetLastStopPacket(response);
- // '?' Packets must be handled differently in non-stop mode
- if (GetTarget().GetNonStopModeEnabled())
- HandleStopReplySequence();
-
- const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
-
- if (process_arch.IsValid())
- {
- GetTarget().MergeArchitecture(process_arch);
- }
- else
- {
- const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture();
- if (host_arch.IsValid())
- GetTarget().MergeArchitecture(host_arch);
- }
-
- SetPrivateState (SetThreadStopInfo (response));
-
- if (!disable_stdio)
- {
- if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
- SetSTDIOFileDescriptor (pty.ReleaseMasterFileDescriptor());
- }
- }
+ log->Printf("ProcessGDBRemote::%s no STDIO paths given via launch_info",
+ __FUNCTION__);
+ }
+
+ const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
+ if (stdin_file_spec || disable_stdio) {
+ // the inferior will be reading stdin from the specified file
+ // or stdio is completely disabled
+ m_stdin_forward = false;
+ } else {
+ m_stdin_forward = true;
+ }
+
+ // ::LogSetBitMask (GDBR_LOG_DEFAULT);
+ // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE |
+ // LLDB_LOG_OPTION_PREPEND_TIMESTAMP |
+ // LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
+ // ::LogSetLogFile ("/dev/stdout");
+
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ error = EstablishConnectionIfNeeded(launch_info);
+ if (error.Success()) {
+ lldb_utility::PseudoTerminal pty;
+ const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
+
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ 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);
+ if (!stdout_file_spec)
+ stdout_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ if (!stderr_file_spec)
+ stderr_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ } else if (platform_sp && platform_sp->IsHost()) {
+ // If the debugserver is local and we aren't disabling STDIO, lets use
+ // a pseudo terminal to instead of relying on the 'O' packets for stdio
+ // since 'O' packets can really slow down debugging if the inferior
+ // 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};
+
+ if (!stdin_file_spec)
+ stdin_file_spec = slave_name;
+
+ if (!stdout_file_spec)
+ stdout_file_spec = slave_name;
+
+ if (!stderr_file_spec)
+ stderr_file_spec = slave_name;
}
- else
- {
- if (log)
- log->Printf("failed to connect to debugserver: %s", error.AsCString());
+ if (log)
+ log->Printf(
+ "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
+ "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+ }
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s final STDIO paths after all "
+ "adjustments: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString()
+ : "<null>");
+
+ if (stdin_file_spec)
+ m_gdb_comm.SetSTDIN(stdin_file_spec);
+ if (stdout_file_spec)
+ m_gdb_comm.SetSTDOUT(stdout_file_spec);
+ if (stderr_file_spec)
+ m_gdb_comm.SetSTDERR(stderr_file_spec);
+
+ m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
+ m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
+
+ m_gdb_comm.SendLaunchArchPacket(
+ GetTarget().GetArchitecture().GetArchitectureName());
+
+ const char *launch_event_data = launch_info.GetLaunchEventData();
+ if (launch_event_data != NULL && *launch_event_data != '\0')
+ m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
+
+ if (working_dir) {
+ m_gdb_comm.SetWorkingDir(working_dir);
+ }
+
+ // Send the environment and the program + arguments after we connect
+ const Args &environment = launch_info.GetEnvironmentEntries();
+ if (environment.GetArgumentCount()) {
+ size_t num_environment_entries = environment.GetArgumentCount();
+ for (size_t i = 0; i < num_environment_entries; ++i) {
+ const char *env_entry = environment.GetArgumentAtIndex(i);
+ if (env_entry == NULL ||
+ m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
+ break;
}
- }
- else
- {
- // Set our user ID to an invalid process ID.
- SetID(LLDB_INVALID_PROCESS_ID);
- error.SetErrorStringWithFormat ("failed to get object file from '%s' for arch %s",
- exe_module->GetFileSpec().GetFilename().AsCString(),
- exe_module->GetArchitecture().GetArchitectureName());
- }
- return error;
-
-}
-
+ }
-Error
-ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
-{
- Error error;
- // Only connect if we have a valid connect URL
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ {
+ // Scope for the scoped timeout object
+ GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm,
+ std::chrono::seconds(10));
+
+ int arg_packet_err = m_gdb_comm.SendArgumentsPacket(launch_info);
+ if (arg_packet_err == 0) {
+ std::string error_str;
+ if (m_gdb_comm.GetLaunchSuccess(error_str)) {
+ SetID(m_gdb_comm.GetCurrentProcessID());
+ } else {
+ error.SetErrorString(error_str.c_str());
+ }
+ } else {
+ error.SetErrorStringWithFormat("'A' packet returned an error: %i",
+ arg_packet_err);
+ }
+ }
- if (connect_url && connect_url[0])
- {
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
if (log)
- log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, connect_url);
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- if (conn_ap.get())
- {
- const uint32_t max_retry_count = 50;
- uint32_t retry_count = 0;
- while (!m_gdb_comm.IsConnected())
- {
- if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
- {
- m_gdb_comm.SetConnection (conn_ap.release());
- break;
- }
- else if (error.WasInterrupted())
- {
- // If we were interrupted, don't keep retrying.
- break;
- }
+ log->Printf("failed to connect to debugserver: %s",
+ error.AsCString());
+ KillDebugserverProcess();
+ return error;
+ }
- retry_count++;
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.GetStopReply(response)) {
+ SetLastStopPacket(response);
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
+ const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ if (process_arch.IsValid()) {
+ GetTarget().MergeArchitecture(process_arch);
+ } else {
+ const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture();
+ if (host_arch.IsValid())
+ GetTarget().MergeArchitecture(host_arch);
+ }
- if (retry_count >= max_retry_count)
- break;
+ SetPrivateState(SetThreadStopInfo(response));
- usleep (100000);
- }
+ if (!disable_stdio) {
+ if (pty.GetMasterFileDescriptor() !=
+ lldb_utility::PseudoTerminal::invalid_fd)
+ SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor());
}
- }
+ }
+ } else {
+ if (log)
+ log->Printf("failed to connect to debugserver: %s", error.AsCString());
+ }
+ } else {
+ // Set our user ID to an invalid process ID.
+ SetID(LLDB_INVALID_PROCESS_ID);
+ error.SetErrorStringWithFormat(
+ "failed to get object file from '%s' for arch %s",
+ exe_module->GetFileSpec().GetFilename().AsCString(),
+ exe_module->GetArchitecture().GetArchitectureName());
+ }
+ return error;
+}
- if (!m_gdb_comm.IsConnected())
- {
- if (error.Success())
- error.SetErrorString("not connected to remote gdb server");
- return error;
- }
+Error ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
+ Error error;
+ // Only connect if we have a valid connect URL
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (!connect_url.empty()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
+ connect_url.str().c_str());
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ new ConnectionFileDescriptor());
+ if (conn_ap.get()) {
+ const uint32_t max_retry_count = 50;
+ uint32_t retry_count = 0;
+ while (!m_gdb_comm.IsConnected()) {
+ if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess) {
+ m_gdb_comm.SetConnection(conn_ap.release());
+ break;
+ } else if (error.WasInterrupted()) {
+ // If we were interrupted, don't keep retrying.
+ break;
+ }
- // Start the communications read thread so all incoming data can be
- // parsed into packets and queued as they arrive.
- if (GetTarget().GetNonStopModeEnabled())
- m_gdb_comm.StartReadThread();
+ retry_count++;
- // We always seem to be able to open a connection to a local port
- // so we need to make sure we can then send data to it. If we can't
- // then we aren't actually connected to anything, so try and do the
- // handshake with the remote GDB server and make sure that goes
- // alright.
- if (!m_gdb_comm.HandshakeWithServer (&error))
- {
- m_gdb_comm.Disconnect();
- if (error.Success())
- error.SetErrorString("not connected to remote gdb server");
- return error;
+ if (retry_count >= max_retry_count)
+ break;
+
+ usleep(100000);
+ }
}
+ }
- // Send $QNonStop:1 packet on startup if required
- if (GetTarget().GetNonStopModeEnabled())
- GetTarget().SetNonStopModeEnabled (m_gdb_comm.SetNonStopMode(true));
+ if (!m_gdb_comm.IsConnected()) {
+ if (error.Success())
+ error.SetErrorString("not connected to remote gdb server");
+ return error;
+ }
+
+ // Start the communications read thread so all incoming data can be
+ // parsed into packets and queued as they arrive.
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.StartReadThread();
+
+ // We always seem to be able to open a connection to a local port
+ // so we need to make sure we can then send data to it. If we can't
+ // then we aren't actually connected to anything, so try and do the
+ // handshake with the remote GDB server and make sure that goes
+ // alright.
+ if (!m_gdb_comm.HandshakeWithServer(&error)) {
+ m_gdb_comm.Disconnect();
+ if (error.Success())
+ error.SetErrorString("not connected to remote gdb server");
+ return error;
+ }
- m_gdb_comm.GetEchoSupported ();
- m_gdb_comm.GetThreadSuffixSupported ();
- m_gdb_comm.GetListThreadsInStopReplySupported ();
- m_gdb_comm.GetHostInfo ();
- m_gdb_comm.GetVContSupported ('c');
- m_gdb_comm.GetVAttachOrWaitSupported();
+ // Send $QNonStop:1 packet on startup if required
+ if (GetTarget().GetNonStopModeEnabled())
+ GetTarget().SetNonStopModeEnabled(m_gdb_comm.SetNonStopMode(true));
- // Ask the remote server for the default thread id
- if (GetTarget().GetNonStopModeEnabled())
- m_gdb_comm.GetDefaultThreadId(m_initial_tid);
+ m_gdb_comm.GetEchoSupported();
+ m_gdb_comm.GetThreadSuffixSupported();
+ m_gdb_comm.GetListThreadsInStopReplySupported();
+ m_gdb_comm.GetHostInfo();
+ m_gdb_comm.GetVContSupported('c');
+ m_gdb_comm.GetVAttachOrWaitSupported();
+ // Ask the remote server for the default thread id
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.GetDefaultThreadId(m_initial_tid);
- size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
- for (size_t idx = 0; idx < num_cmds; idx++)
- {
- StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse (GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
- }
- return error;
+ size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
+ for (size_t idx = 0; idx < num_cmds; idx++) {
+ StringExtractorGDBRemote response;
+ m_gdb_comm.SendPacketAndWaitForResponse(
+ GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
+ }
+ return error;
}
-void
-ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DidLaunch()");
- if (GetID() != LLDB_INVALID_PROCESS_ID)
- {
- BuildDynamicRegisterInfo (false);
+void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+ if (GetID() != LLDB_INVALID_PROCESS_ID) {
+ BuildDynamicRegisterInfo(false);
- // See if the GDB server supports the qHostInfo information
+ // See if the GDB server supports the qHostInfo information
+ // See if the GDB server supports the qProcessInfo packet, if so
+ // prefer that over the Host information as it will be more specific
+ // to our process.
- // See if the GDB server supports the qProcessInfo packet, if so
- // prefer that over the Host information as it will be more specific
- // to our process.
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+ if (remote_process_arch.IsValid()) {
+ process_arch = remote_process_arch;
+ if (log)
+ log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, "
+ "using %s %s",
+ __FUNCTION__, process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ } else {
+ process_arch = m_gdb_comm.GetHostArchitecture();
+ 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>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ }
+
+ if (process_arch.IsValid()) {
+ const ArchSpec &target_arch = GetTarget().GetArchitecture();
+ if (target_arch.IsValid()) {
+ if (log)
+ log->Printf(
+ "ProcessGDBRemote::%s analyzing target arch, currently %s %s",
+ __FUNCTION__, target_arch.GetArchitectureName()
+ ? target_arch.GetArchitectureName()
+ : "<null>",
+ target_arch.GetTriple().getTriple().c_str()
+ ? target_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+
+ // If the remote host is ARM and we have apple as the vendor, then
+ // ARM executables and shared libraries can have mixed ARM
+ // architectures.
+ // You can have an armv6 executable, and if the host is armv7, then the
+ // system will load the best possible architecture for all shared
+ // libraries
+ // it has, so we really need to take the remote host architecture as our
+ // defacto architecture in this case.
+
+ if ((process_arch.GetMachine() == llvm::Triple::arm ||
+ process_arch.GetMachine() == llvm::Triple::thumb) &&
+ process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {
+ GetTarget().SetArchitecture(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>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ } else {
+ // Fill in what is missing in the triple
+ const llvm::Triple &remote_triple = process_arch.GetTriple();
+ llvm::Triple new_target_triple = target_arch.GetTriple();
+ if (new_target_triple.getVendorName().size() == 0) {
+ new_target_triple.setVendor(remote_triple.getVendor());
+
+ if (new_target_triple.getOSName().size() == 0) {
+ new_target_triple.setOS(remote_triple.getOS());
+
+ if (new_target_triple.getEnvironmentName().size() == 0)
+ new_target_triple.setEnvironment(
+ remote_triple.getEnvironment());
+ }
- const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
- if (remote_process_arch.IsValid())
- {
- process_arch = remote_process_arch;
- if (log)
- log->Printf ("ProcessGDBRemote::%s gdb-remote had process architecture, using %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
- process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
+ ArchSpec new_target_arch = target_arch;
+ new_target_arch.SetTriple(new_target_triple);
+ GetTarget().SetArchitecture(new_target_arch);
+ }
}
- else
- {
- process_arch = m_gdb_comm.GetHostArchitecture();
- 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>",
- process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
- }
-
- if (process_arch.IsValid())
- {
- const ArchSpec &target_arch = GetTarget().GetArchitecture();
- if (target_arch.IsValid())
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s analyzing target arch, currently %s %s",
- __FUNCTION__,
- target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>",
- target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
-
- // If the remote host is ARM and we have apple as the vendor, then
- // ARM executables and shared libraries can have mixed ARM architectures.
- // You can have an armv6 executable, and if the host is armv7, then the
- // system will load the best possible architecture for all shared libraries
- // it has, so we really need to take the remote host architecture as our
- // defacto architecture in this case.
-
- if ((process_arch.GetMachine() == llvm::Triple::arm || process_arch.GetMachine() == llvm::Triple::thumb)
- && process_arch.GetTriple().getVendor() == llvm::Triple::Apple)
- {
- GetTarget().SetArchitecture (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>",
- process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
- }
- else
- {
- // Fill in what is missing in the triple
- const llvm::Triple &remote_triple = process_arch.GetTriple();
- llvm::Triple new_target_triple = target_arch.GetTriple();
- if (new_target_triple.getVendorName().size() == 0)
- {
- new_target_triple.setVendor (remote_triple.getVendor());
-
- if (new_target_triple.getOSName().size() == 0)
- {
- new_target_triple.setOS (remote_triple.getOS());
-
- if (new_target_triple.getEnvironmentName().size() == 0)
- new_target_triple.setEnvironment (remote_triple.getEnvironment());
- }
-
- ArchSpec new_target_arch = target_arch;
- new_target_arch.SetTriple(new_target_triple);
- GetTarget().SetArchitecture(new_target_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>",
- target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
- }
- else
- {
- // The target doesn't have a valid architecture yet, set it from
- // the architecture we got from the remote GDB server
- GetTarget().SetArchitecture (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>",
+ target_arch.GetTriple().getTriple().c_str()
+ ? target_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ } else {
+ // The target doesn't have a valid architecture yet, set it from
+ // the architecture we got from the remote GDB server
+ GetTarget().SetArchitecture(process_arch);
+ }
+ }
+
+ // Find out which StructuredDataPlugins are supported by the
+ // debug monitor. These plugins transmit data over async $J packets.
+ auto supported_packets_array =
+ m_gdb_comm.GetSupportedStructuredDataPlugins();
+ if (supported_packets_array)
+ MapSupportedStructuredDataPlugins(*supported_packets_array);
+ }
}
-void
-ProcessGDBRemote::DidLaunch ()
-{
- ArchSpec process_arch;
- DidLaunchOrAttach (process_arch);
+void ProcessGDBRemote::DidLaunch() {
+ ArchSpec process_arch;
+ DidLaunchOrAttach(process_arch);
}
-Error
-ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- Error error;
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s()", __FUNCTION__);
-
- // Clear out and clean up from any current state
- Clear();
- if (attach_pid != LLDB_INVALID_PROCESS_ID)
- {
- error = EstablishConnectionIfNeeded (attach_info);
- if (error.Success())
- {
- m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
-
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
- SetID (attach_pid);
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
- }
- else
- SetExitStatus (-1, error.AsCString());
- }
-
- return error;
+Error ProcessGDBRemote::DoAttachToProcessWithID(
+ lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Error error;
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+
+ // Clear out and clean up from any current state
+ Clear();
+ if (attach_pid != LLDB_INVALID_PROCESS_ID) {
+ error = EstablishConnectionIfNeeded(attach_info);
+ if (error.Success()) {
+ m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
+
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
+ SetID(attach_pid);
+ m_async_broadcaster.BroadcastEvent(
+ eBroadcastBitAsyncContinue, new EventDataBytes(packet, packet_len));
+ } else
+ SetExitStatus(-1, error.AsCString());
+ }
+
+ return error;
}
-Error
-ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
-{
- Error error;
- // Clear out and clean up from any current state
- Clear();
-
- if (process_name && process_name[0])
- {
- error = EstablishConnectionIfNeeded (attach_info);
- if (error.Success())
- {
- StreamString packet;
-
- m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
-
- if (attach_info.GetWaitForLaunch())
- {
- if (!m_gdb_comm.GetVAttachOrWaitSupported())
- {
- packet.PutCString ("vAttachWait");
- }
- else
- {
- if (attach_info.GetIgnoreExisting())
- packet.PutCString("vAttachWait");
- else
- packet.PutCString ("vAttachOrWait");
- }
- }
- else
- packet.PutCString("vAttachName");
- packet.PutChar(';');
- packet.PutBytesAsRawHex8(process_name, strlen(process_name), endian::InlHostByteOrder(), endian::InlHostByteOrder());
-
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet.GetData(), packet.GetSize()));
-
+Error ProcessGDBRemote::DoAttachToProcessWithName(
+ const char *process_name, const ProcessAttachInfo &attach_info) {
+ Error error;
+ // Clear out and clean up from any current state
+ Clear();
+
+ if (process_name && process_name[0]) {
+ error = EstablishConnectionIfNeeded(attach_info);
+ if (error.Success()) {
+ StreamString packet;
+
+ m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
+
+ if (attach_info.GetWaitForLaunch()) {
+ if (!m_gdb_comm.GetVAttachOrWaitSupported()) {
+ packet.PutCString("vAttachWait");
+ } else {
+ if (attach_info.GetIgnoreExisting())
+ packet.PutCString("vAttachWait");
+ else
+ packet.PutCString("vAttachOrWait");
}
- else
- SetExitStatus (-1, error.AsCString());
- }
- return error;
+ } else
+ packet.PutCString("vAttachName");
+ packet.PutChar(';');
+ packet.PutBytesAsRawHex8(process_name, strlen(process_name),
+ endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+
+ m_async_broadcaster.BroadcastEvent(
+ eBroadcastBitAsyncContinue,
+ new EventDataBytes(packet.GetString().data(), packet.GetSize()));
+
+ } else
+ SetExitStatus(-1, error.AsCString());
+ }
+ return error;
}
-void
-ProcessGDBRemote::DidExit ()
-{
- // When we exit, disconnect from the GDB server communications
- m_gdb_comm.Disconnect();
+void ProcessGDBRemote::DidExit() {
+ // When we exit, disconnect from the GDB server communications
+ m_gdb_comm.Disconnect();
}
-void
-ProcessGDBRemote::DidAttach (ArchSpec &process_arch)
-{
- // If you can figure out what the architecture is, fill it in here.
- process_arch.Clear();
- DidLaunchOrAttach (process_arch);
+void ProcessGDBRemote::DidAttach(ArchSpec &process_arch) {
+ // If you can figure out what the architecture is, fill it in here.
+ process_arch.Clear();
+ DidLaunchOrAttach(process_arch);
}
-
-Error
-ProcessGDBRemote::WillResume ()
-{
- m_continue_c_tids.clear();
- m_continue_C_tids.clear();
- m_continue_s_tids.clear();
- m_continue_S_tids.clear();
- m_jstopinfo_sp.reset();
- m_jthreadsinfo_sp.reset();
- return Error();
+Error ProcessGDBRemote::WillResume() {
+ m_continue_c_tids.clear();
+ m_continue_C_tids.clear();
+ m_continue_s_tids.clear();
+ m_continue_S_tids.clear();
+ m_jstopinfo_sp.reset();
+ m_jthreadsinfo_sp.reset();
+ return Error();
}
-Error
-ProcessGDBRemote::DoResume ()
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::Resume()");
-
- ListenerSP listener_sp (Listener::MakeListener("gdb-remote.resume-packet-sent"));
- if (listener_sp->StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
- {
- listener_sp->StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
-
- const size_t num_threads = GetThreadList().GetSize();
-
- StreamString continue_packet;
- bool continue_packet_error = false;
- if (m_gdb_comm.HasAnyVContSupport ())
- {
- if (!GetTarget().GetNonStopModeEnabled() &&
- (m_continue_c_tids.size() == num_threads ||
- (m_continue_c_tids.empty() &&
- m_continue_C_tids.empty() &&
- m_continue_s_tids.empty() &&
- m_continue_S_tids.empty())))
- {
- // All threads are continuing, just send a "c" packet
- continue_packet.PutCString ("c");
- }
- else
- {
- continue_packet.PutCString ("vCont");
-
- if (!m_continue_c_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('c'))
- {
- for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
- }
- else
- continue_packet_error = true;
- }
-
- if (!continue_packet_error && !m_continue_C_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('C'))
- {
- for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
- }
- else
- continue_packet_error = true;
- }
-
- if (!continue_packet_error && !m_continue_s_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('s'))
- {
- for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
- }
- else
- continue_packet_error = true;
- }
+Error ProcessGDBRemote::DoResume() {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::Resume()");
+
+ ListenerSP listener_sp(
+ Listener::MakeListener("gdb-remote.resume-packet-sent"));
+ if (listener_sp->StartListeningForEvents(
+ &m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent)) {
+ listener_sp->StartListeningForEvents(
+ &m_async_broadcaster,
+ ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
+
+ const size_t num_threads = GetThreadList().GetSize();
+
+ StreamString continue_packet;
+ bool continue_packet_error = false;
+ if (m_gdb_comm.HasAnyVContSupport()) {
+ if (!GetTarget().GetNonStopModeEnabled() &&
+ (m_continue_c_tids.size() == num_threads ||
+ (m_continue_c_tids.empty() && m_continue_C_tids.empty() &&
+ m_continue_s_tids.empty() && m_continue_S_tids.empty()))) {
+ // All threads are continuing, just send a "c" packet
+ continue_packet.PutCString("c");
+ } else {
+ continue_packet.PutCString("vCont");
+
+ if (!m_continue_c_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('c')) {
+ for (tid_collection::const_iterator
+ t_pos = m_continue_c_tids.begin(),
+ t_end = m_continue_c_tids.end();
+ t_pos != t_end; ++t_pos)
+ continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
+ } else
+ continue_packet_error = true;
+ }
- if (!continue_packet_error && !m_continue_S_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('S'))
- {
- for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
- }
- else
- continue_packet_error = true;
- }
+ if (!continue_packet_error && !m_continue_C_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('C')) {
+ for (tid_sig_collection::const_iterator
+ s_pos = m_continue_C_tids.begin(),
+ s_end = m_continue_C_tids.end();
+ s_pos != s_end; ++s_pos)
+ continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second,
+ s_pos->first);
+ } else
+ continue_packet_error = true;
+ }
- if (continue_packet_error)
- continue_packet.GetString().clear();
- }
+ if (!continue_packet_error && !m_continue_s_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('s')) {
+ for (tid_collection::const_iterator
+ t_pos = m_continue_s_tids.begin(),
+ t_end = m_continue_s_tids.end();
+ t_pos != t_end; ++t_pos)
+ continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
+ } else
+ continue_packet_error = true;
}
- else
+
+ if (!continue_packet_error && !m_continue_S_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('S')) {
+ for (tid_sig_collection::const_iterator
+ s_pos = m_continue_S_tids.begin(),
+ s_end = m_continue_S_tids.end();
+ s_pos != s_end; ++s_pos)
+ continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second,
+ s_pos->first);
+ } else
continue_packet_error = true;
+ }
if (continue_packet_error)
- {
- // Either no vCont support, or we tried to use part of the vCont
- // packet that wasn't supported by the remote GDB server.
- // We need to try and make a simple packet that can do our continue
- const size_t num_continue_c_tids = m_continue_c_tids.size();
- const size_t num_continue_C_tids = m_continue_C_tids.size();
- const size_t num_continue_s_tids = m_continue_s_tids.size();
- const size_t num_continue_S_tids = m_continue_S_tids.size();
- if (num_continue_c_tids > 0)
- {
- if (num_continue_c_tids == num_threads)
- {
- // All threads are resuming...
- m_gdb_comm.SetCurrentThreadForRun (-1);
- continue_packet.PutChar ('c');
- continue_packet_error = false;
- }
- else if (num_continue_c_tids == 1 &&
- num_continue_C_tids == 0 &&
- num_continue_s_tids == 0 &&
- num_continue_S_tids == 0 )
- {
- // Only one thread is continuing
- m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front());
- continue_packet.PutChar ('c');
- continue_packet_error = false;
- }
+ continue_packet.Clear();
+ }
+ } else
+ continue_packet_error = true;
+
+ if (continue_packet_error) {
+ // Either no vCont support, or we tried to use part of the vCont
+ // packet that wasn't supported by the remote GDB server.
+ // We need to try and make a simple packet that can do our continue
+ const size_t num_continue_c_tids = m_continue_c_tids.size();
+ const size_t num_continue_C_tids = m_continue_C_tids.size();
+ const size_t num_continue_s_tids = m_continue_s_tids.size();
+ const size_t num_continue_S_tids = m_continue_S_tids.size();
+ if (num_continue_c_tids > 0) {
+ if (num_continue_c_tids == num_threads) {
+ // All threads are resuming...
+ m_gdb_comm.SetCurrentThreadForRun(-1);
+ continue_packet.PutChar('c');
+ continue_packet_error = false;
+ } else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
+ num_continue_s_tids == 0 && num_continue_S_tids == 0) {
+ // Only one thread is continuing
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_c_tids.front());
+ continue_packet.PutChar('c');
+ continue_packet_error = false;
+ }
+ }
+
+ if (continue_packet_error && num_continue_C_tids > 0) {
+ if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
+ num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
+ num_continue_S_tids == 0) {
+ const int continue_signo = m_continue_C_tids.front().second;
+ // Only one thread is continuing
+ if (num_continue_C_tids > 1) {
+ // More that one thread with a signal, yet we don't have
+ // vCont support and we are being asked to resume each
+ // thread with a signal, we need to make sure they are
+ // all the same signal, or we can't issue the continue
+ // accurately with the current support...
+ if (num_continue_C_tids > 1) {
+ continue_packet_error = false;
+ for (size_t i = 1; i < m_continue_C_tids.size(); ++i) {
+ if (m_continue_C_tids[i].second != continue_signo)
+ continue_packet_error = true;
+ }
}
+ if (!continue_packet_error)
+ m_gdb_comm.SetCurrentThreadForRun(-1);
+ } else {
+ // Set the continue thread ID
+ continue_packet_error = false;
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_C_tids.front().first);
+ }
+ if (!continue_packet_error) {
+ // Add threads continuing with the same signo...
+ continue_packet.Printf("C%2.2x", continue_signo);
+ }
+ }
+ }
- if (continue_packet_error && num_continue_C_tids > 0)
- {
- if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
- num_continue_C_tids > 0 &&
- num_continue_s_tids == 0 &&
- num_continue_S_tids == 0 )
- {
- const int continue_signo = m_continue_C_tids.front().second;
- // Only one thread is continuing
- if (num_continue_C_tids > 1)
- {
- // More that one thread with a signal, yet we don't have
- // vCont support and we are being asked to resume each
- // thread with a signal, we need to make sure they are
- // all the same signal, or we can't issue the continue
- // accurately with the current support...
- if (num_continue_C_tids > 1)
- {
- continue_packet_error = false;
- for (size_t i=1; i<m_continue_C_tids.size(); ++i)
- {
- if (m_continue_C_tids[i].second != continue_signo)
- continue_packet_error = true;
- }
- }
- if (!continue_packet_error)
- m_gdb_comm.SetCurrentThreadForRun (-1);
- }
- else
- {
- // Set the continue thread ID
- continue_packet_error = false;
- m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first);
- }
- if (!continue_packet_error)
- {
- // Add threads continuing with the same signo...
- continue_packet.Printf("C%2.2x", continue_signo);
- }
- }
- }
+ if (continue_packet_error && num_continue_s_tids > 0) {
+ if (num_continue_s_tids == num_threads) {
+ // All threads are resuming...
+ m_gdb_comm.SetCurrentThreadForRun(-1);
- if (continue_packet_error && num_continue_s_tids > 0)
- {
- if (num_continue_s_tids == num_threads)
- {
- // All threads are resuming...
- m_gdb_comm.SetCurrentThreadForRun (-1);
-
- // If in Non-Stop-Mode use vCont when stepping
- if (GetTarget().GetNonStopModeEnabled())
- {
- if (m_gdb_comm.GetVContSupported('s'))
- continue_packet.PutCString("vCont;s");
- else
- continue_packet.PutChar('s');
- }
- else
- continue_packet.PutChar('s');
-
- continue_packet_error = false;
- }
- else if (num_continue_c_tids == 0 &&
- num_continue_C_tids == 0 &&
- num_continue_s_tids == 1 &&
- num_continue_S_tids == 0 )
- {
- // Only one thread is stepping
- m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front());
- continue_packet.PutChar ('s');
- continue_packet_error = false;
- }
- }
-
- if (!continue_packet_error && num_continue_S_tids > 0)
- {
- if (num_continue_S_tids == num_threads)
- {
- const int step_signo = m_continue_S_tids.front().second;
- // Are all threads trying to step with the same signal?
- continue_packet_error = false;
- if (num_continue_S_tids > 1)
- {
- for (size_t i=1; i<num_threads; ++i)
- {
- if (m_continue_S_tids[i].second != step_signo)
- continue_packet_error = true;
- }
- }
- if (!continue_packet_error)
- {
- // Add threads stepping with the same signo...
- m_gdb_comm.SetCurrentThreadForRun (-1);
- continue_packet.Printf("S%2.2x", step_signo);
- }
- }
- else if (num_continue_c_tids == 0 &&
- num_continue_C_tids == 0 &&
- num_continue_s_tids == 0 &&
- num_continue_S_tids == 1 )
- {
- // Only one thread is stepping with signal
- m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first);
- continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
- continue_packet_error = false;
- }
+ // If in Non-Stop-Mode use vCont when stepping
+ if (GetTarget().GetNonStopModeEnabled()) {
+ if (m_gdb_comm.GetVContSupported('s'))
+ continue_packet.PutCString("vCont;s");
+ else
+ continue_packet.PutChar('s');
+ } else
+ continue_packet.PutChar('s');
+
+ continue_packet_error = false;
+ } else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
+ num_continue_s_tids == 1 && num_continue_S_tids == 0) {
+ // Only one thread is stepping
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());
+ continue_packet.PutChar('s');
+ continue_packet_error = false;
+ }
+ }
+
+ if (!continue_packet_error && num_continue_S_tids > 0) {
+ if (num_continue_S_tids == num_threads) {
+ const int step_signo = m_continue_S_tids.front().second;
+ // Are all threads trying to step with the same signal?
+ continue_packet_error = false;
+ if (num_continue_S_tids > 1) {
+ for (size_t i = 1; i < num_threads; ++i) {
+ if (m_continue_S_tids[i].second != step_signo)
+ continue_packet_error = true;
}
+ }
+ if (!continue_packet_error) {
+ // Add threads stepping with the same signo...
+ m_gdb_comm.SetCurrentThreadForRun(-1);
+ continue_packet.Printf("S%2.2x", step_signo);
+ }
+ } else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
+ num_continue_s_tids == 0 && num_continue_S_tids == 1) {
+ // Only one thread is stepping with signal
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_S_tids.front().first);
+ continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
+ continue_packet_error = false;
}
+ }
+ }
- if (continue_packet_error)
- {
- error.SetErrorString ("can't make continue packet for this resume");
- }
- else
- {
- EventSP event_sp;
- TimeValue timeout;
- timeout = TimeValue::Now();
- timeout.OffsetWithSeconds (5);
- if (!m_async_thread.IsJoinable())
- {
- error.SetErrorString ("Trying to resume but the async thread is dead.");
- if (log)
- log->Printf ("ProcessGDBRemote::DoResume: Trying to resume but the async thread is dead.");
- return error;
- }
+ if (continue_packet_error) {
+ error.SetErrorString("can't make continue packet for this resume");
+ } else {
+ EventSP event_sp;
+ if (!m_async_thread.IsJoinable()) {
+ error.SetErrorString("Trying to resume but the async thread is dead.");
+ if (log)
+ log->Printf("ProcessGDBRemote::DoResume: Trying to resume but the "
+ "async thread is dead.");
+ return error;
+ }
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
+ m_async_broadcaster.BroadcastEvent(
+ eBroadcastBitAsyncContinue,
+ new EventDataBytes(continue_packet.GetString().data(),
+ continue_packet.GetSize()));
- if (listener_sp->WaitForEvent (&timeout, event_sp) == false)
- {
- error.SetErrorString("Resume timed out.");
- if (log)
- log->Printf ("ProcessGDBRemote::DoResume: Resume timed out.");
- }
- else if (event_sp->BroadcasterIs (&m_async_broadcaster))
- {
- error.SetErrorString ("Broadcast continue, but the async thread was killed before we got an ack back.");
- if (log)
- log->Printf ("ProcessGDBRemote::DoResume: Broadcast continue, but the async thread was killed before we got an ack back.");
- return error;
- }
- }
+ if (listener_sp->GetEvent(event_sp, std::chrono::seconds(5)) == false) {
+ error.SetErrorString("Resume timed out.");
+ if (log)
+ log->Printf("ProcessGDBRemote::DoResume: Resume timed out.");
+ } else if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
+ error.SetErrorString("Broadcast continue, but the async thread was "
+ "killed before we got an ack back.");
+ if (log)
+ log->Printf("ProcessGDBRemote::DoResume: Broadcast continue, but the "
+ "async thread was killed before we got an ack back.");
+ return error;
+ }
}
+ }
- return error;
+ return error;
}
-void
-ProcessGDBRemote::HandleStopReplySequence ()
-{
- while(true)
- {
- // Send vStopped
- StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+void ProcessGDBRemote::HandleStopReplySequence() {
+ while (true) {
+ // Send vStopped
+ StringExtractorGDBRemote response;
+ m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
- // OK represents end of signal list
- if (response.IsOKResponse())
- break;
+ // OK represents end of signal list
+ if (response.IsOKResponse())
+ break;
- // If not OK or a normal packet we have a problem
- if (!response.IsNormalResponse())
- break;
+ // If not OK or a normal packet we have a problem
+ if (!response.IsNormalResponse())
+ break;
- SetLastStopPacket(response);
- }
+ SetLastStopPacket(response);
+ }
}
-void
-ProcessGDBRemote::ClearThreadIDList ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
- m_thread_ids.clear();
- m_thread_pcs.clear();
+void ProcessGDBRemote::ClearThreadIDList() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
}
size_t
-ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue (std::string &value)
-{
- m_thread_ids.clear();
- m_thread_pcs.clear();
- size_t comma_pos;
- lldb::tid_t tid;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- // thread in big endian hex
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- value.erase(0, comma_pos + 1);
- }
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) {
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
+ size_t comma_pos;
+ lldb::tid_t tid;
+ while ((comma_pos = value.find(',')) != std::string::npos) {
+ value[comma_pos] = '\0';
+ // thread in big endian hex
+ tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- return m_thread_ids.size();
+ m_thread_ids.push_back(tid);
+ value.erase(0, comma_pos + 1);
+ }
+ tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ if (tid != LLDB_INVALID_THREAD_ID)
+ m_thread_ids.push_back(tid);
+ return m_thread_ids.size();
}
size_t
-ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue (std::string &value)
-{
- m_thread_pcs.clear();
- size_t comma_pos;
- lldb::addr_t pc;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_ADDRESS)
- m_thread_pcs.push_back (pc);
- value.erase(0, comma_pos + 1);
- }
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_THREAD_ID)
- m_thread_pcs.push_back (pc);
- return m_thread_pcs.size();
+ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(std::string &value) {
+ m_thread_pcs.clear();
+ size_t comma_pos;
+ lldb::addr_t pc;
+ while ((comma_pos = value.find(',')) != std::string::npos) {
+ value[comma_pos] = '\0';
+ pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
+ if (pc != LLDB_INVALID_ADDRESS)
+ m_thread_pcs.push_back(pc);
+ value.erase(0, comma_pos + 1);
+ }
+ pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
+ if (pc != LLDB_INVALID_THREAD_ID)
+ m_thread_pcs.push_back(pc);
+ return m_thread_pcs.size();
}
-bool
-ProcessGDBRemote::UpdateThreadIDList ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-
- if (m_jthreadsinfo_sp)
- {
- // If we have the JSON threads info, we can get the thread list from that
- StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
- if (thread_infos && thread_infos->GetSize() > 0)
- {
- m_thread_ids.clear();
- m_thread_pcs.clear();
- thread_infos->ForEach([this](StructuredData::Object* object) -> bool {
- StructuredData::Dictionary *thread_dict = object->GetAsDictionary();
- if (thread_dict)
- {
- // Set the thread stop info from the JSON dictionary
- SetThreadStopInfo (thread_dict);
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))
- m_thread_ids.push_back(tid);
- }
- return true; // Keep iterating through all thread_info objects
- });
+bool ProcessGDBRemote::UpdateThreadIDList() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+
+ if (m_jthreadsinfo_sp) {
+ // If we have the JSON threads info, we can get the thread list from that
+ StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
+ if (thread_infos && thread_infos->GetSize() > 0) {
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
+ thread_infos->ForEach([this](StructuredData::Object *object) -> bool {
+ StructuredData::Dictionary *thread_dict = object->GetAsDictionary();
+ if (thread_dict) {
+ // Set the thread stop info from the JSON dictionary
+ SetThreadStopInfo(thread_dict);
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))
+ m_thread_ids.push_back(tid);
+ }
+ return true; // Keep iterating through all thread_info objects
+ });
+ }
+ if (!m_thread_ids.empty())
+ return true;
+ } else {
+ // See if we can get the thread IDs from the current stop reply packets
+ // that might contain a "threads" key/value pair
+
+ // Lock the thread stack while we access it
+ // Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+ std::unique_lock<std::recursive_mutex> stop_stack_lock(
+ m_last_stop_packet_mutex, std::defer_lock);
+ if (stop_stack_lock.try_lock()) {
+ // Get the number of stop packets on the stack
+ int nItems = m_stop_packet_stack.size();
+ // Iterate over them
+ for (int i = 0; i < nItems; i++) {
+ // Get the thread stop info
+ StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
+ const std::string &stop_info_str = stop_info.GetStringRef();
+
+ m_thread_pcs.clear();
+ const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
+ if (thread_pcs_pos != std::string::npos) {
+ const size_t start = thread_pcs_pos + strlen(";thread-pcs:");
+ const size_t end = stop_info_str.find(';', start);
+ if (end != std::string::npos) {
+ std::string value = stop_info_str.substr(start, end - start);
+ UpdateThreadPCsFromStopReplyThreadsValue(value);
+ }
}
- if (!m_thread_ids.empty())
- return true;
- }
- else
- {
- // See if we can get the thread IDs from the current stop reply packets
- // that might contain a "threads" key/value pair
-
- // Lock the thread stack while we access it
- //Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
- std::unique_lock<std::recursive_mutex> stop_stack_lock(m_last_stop_packet_mutex, std::defer_lock);
- if (stop_stack_lock.try_lock())
- {
- // Get the number of stop packets on the stack
- int nItems = m_stop_packet_stack.size();
- // Iterate over them
- for (int i = 0; i < nItems; i++)
- {
- // Get the thread stop info
- StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
- const std::string &stop_info_str = stop_info.GetStringRef();
-
- m_thread_pcs.clear();
- const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
- if (thread_pcs_pos != std::string::npos)
- {
- const size_t start = thread_pcs_pos + strlen(";thread-pcs:");
- const size_t end = stop_info_str.find(';', start);
- if (end != std::string::npos)
- {
- std::string value = stop_info_str.substr(start, end - start);
- UpdateThreadPCsFromStopReplyThreadsValue(value);
- }
- }
- const size_t threads_pos = stop_info_str.find(";threads:");
- if (threads_pos != std::string::npos)
- {
- const size_t start = threads_pos + strlen(";threads:");
- const size_t end = stop_info_str.find(';', start);
- if (end != std::string::npos)
- {
- std::string value = stop_info_str.substr(start, end - start);
- if (UpdateThreadIDsFromStopReplyThreadsValue(value))
- return true;
- }
- }
- }
+ const size_t threads_pos = stop_info_str.find(";threads:");
+ if (threads_pos != std::string::npos) {
+ const size_t start = threads_pos + strlen(";threads:");
+ const size_t end = stop_info_str.find(';', start);
+ if (end != std::string::npos) {
+ std::string value = stop_info_str.substr(start, end - start);
+ if (UpdateThreadIDsFromStopReplyThreadsValue(value))
+ return true;
+ }
}
+ }
}
+ }
- bool sequence_mutex_unavailable = false;
- m_gdb_comm.GetCurrentThreadIDs (m_thread_ids, sequence_mutex_unavailable);
- if (sequence_mutex_unavailable)
- {
- return false; // We just didn't get the list
- }
- return true;
+ bool sequence_mutex_unavailable = false;
+ m_gdb_comm.GetCurrentThreadIDs(m_thread_ids, sequence_mutex_unavailable);
+ if (sequence_mutex_unavailable) {
+ return false; // We just didn't get the list
+ }
+ return true;
}
-bool
-ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- // locker will keep a mutex locked until it goes out of scope
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
- if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf ("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- size_t num_thread_ids = m_thread_ids.size();
- // The "m_thread_ids" thread ID list should always be updated after each stop
- // reply packet, but in case it isn't, update it here.
- if (num_thread_ids == 0)
- {
- if (!UpdateThreadIDList ())
- return false;
- num_thread_ids = m_thread_ids.size();
- }
-
- ThreadList old_thread_list_copy(old_thread_list);
- if (num_thread_ids > 0)
- {
- for (size_t i=0; i<num_thread_ids; ++i)
- {
- tid_t tid = m_thread_ids[i];
- ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
- if (!thread_sp)
- {
- thread_sp.reset (new ThreadGDBRemote (*this, tid));
- if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf(
- "ProcessGDBRemote::%s Making new thread: %p for thread ID: 0x%" PRIx64 ".\n",
- __FUNCTION__, static_cast<void*>(thread_sp.get()),
- thread_sp->GetID());
- }
- else
- {
- if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf(
- "ProcessGDBRemote::%s Found old thread: %p for thread ID: 0x%" PRIx64 ".\n",
- __FUNCTION__, static_cast<void*>(thread_sp.get()),
- thread_sp->GetID());
- }
- // The m_thread_pcs vector has pc values in big-endian order, not target-endian, unlike most
- // of the register read/write packets in gdb-remote protocol.
- // Early in the process startup, we may not yet have set the process ByteOrder so we ignore these;
- // they are a performance improvement over fetching thread register values individually, the
- // method we will fall back to if needed.
- if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() && GetByteOrder() != eByteOrderInvalid)
- {
- ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
- RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
- if (reg_ctx_sp)
- {
- uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber
- (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- if (pc_regnum != LLDB_INVALID_REGNUM)
- {
- gdb_thread->PrivateSetRegisterValue (pc_regnum, m_thread_pcs[i]);
- }
- }
- }
- new_thread_list.AddThreadSortedByIndexID (thread_sp);
+bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // locker will keep a mutex locked until it goes out of scope
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_THREAD));
+ if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+ log->Printf("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__,
+ GetID());
+
+ size_t num_thread_ids = m_thread_ids.size();
+ // The "m_thread_ids" thread ID list should always be updated after each stop
+ // reply packet, but in case it isn't, update it here.
+ if (num_thread_ids == 0) {
+ if (!UpdateThreadIDList())
+ return false;
+ num_thread_ids = m_thread_ids.size();
+ }
+
+ ThreadList old_thread_list_copy(old_thread_list);
+ if (num_thread_ids > 0) {
+ for (size_t i = 0; i < num_thread_ids; ++i) {
+ tid_t tid = m_thread_ids[i];
+ ThreadSP thread_sp(
+ old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
+ if (!thread_sp) {
+ thread_sp.reset(new ThreadGDBRemote(*this, tid));
+ if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+ log->Printf("ProcessGDBRemote::%s Making new thread: %p for thread "
+ "ID: 0x%" PRIx64 ".\n",
+ __FUNCTION__, static_cast<void *>(thread_sp.get()),
+ thread_sp->GetID());
+ } else {
+ if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+ log->Printf("ProcessGDBRemote::%s Found old thread: %p for thread "
+ "ID: 0x%" PRIx64 ".\n",
+ __FUNCTION__, static_cast<void *>(thread_sp.get()),
+ thread_sp->GetID());
+ }
+ // The m_thread_pcs vector has pc values in big-endian order, not
+ // target-endian, unlike most
+ // of the register read/write packets in gdb-remote protocol.
+ // Early in the process startup, we may not yet have set the process
+ // ByteOrder so we ignore these;
+ // they are a performance improvement over fetching thread register values
+ // individually, the
+ // method we will fall back to if needed.
+ if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() &&
+ GetByteOrder() != eByteOrderInvalid) {
+ ThreadGDBRemote *gdb_thread =
+ static_cast<ThreadGDBRemote *>(thread_sp.get());
+ RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
+ if (reg_ctx_sp) {
+ uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ if (pc_regnum != LLDB_INVALID_REGNUM) {
+ gdb_thread->PrivateSetRegisterValue(pc_regnum, m_thread_pcs[i]);
+ }
}
+ }
+ new_thread_list.AddThreadSortedByIndexID(thread_sp);
}
+ }
- // Whatever that is left in old_thread_list_copy are not
- // present in new_thread_list. Remove non-existent threads from internal id table.
- size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
- for (size_t i=0; i<old_num_thread_ids; i++)
- {
- ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex (i, false));
- if (old_thread_sp)
- {
- lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
- m_thread_id_to_index_id_map.erase(old_thread_id);
- }
+ // Whatever that is left in old_thread_list_copy are not
+ // present in new_thread_list. Remove non-existent threads from internal id
+ // table.
+ size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
+ for (size_t i = 0; i < old_num_thread_ids; i++) {
+ ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
+ if (old_thread_sp) {
+ lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
+ m_thread_id_to_index_id_map.erase(old_thread_id);
}
+ }
- return true;
+ return true;
}
-
-bool
-ProcessGDBRemote::GetThreadStopInfoFromJSON (ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp)
-{
- // See if we got thread stop infos for all threads via the "jThreadsInfo" packet
- if (thread_infos_sp)
- {
- StructuredData::Array *thread_infos = thread_infos_sp->GetAsArray();
- if (thread_infos)
- {
- lldb::tid_t tid;
- const size_t n = thread_infos->GetSize();
- for (size_t i=0; i<n; ++i)
- {
- StructuredData::Dictionary *thread_dict = thread_infos->GetItemAtIndex(i)->GetAsDictionary();
- if (thread_dict)
- {
- if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid, LLDB_INVALID_THREAD_ID))
- {
- if (tid == thread->GetID())
- return (bool)SetThreadStopInfo(thread_dict);
- }
- }
- }
+bool ProcessGDBRemote::GetThreadStopInfoFromJSON(
+ ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp) {
+ // See if we got thread stop infos for all threads via the "jThreadsInfo"
+ // packet
+ if (thread_infos_sp) {
+ StructuredData::Array *thread_infos = thread_infos_sp->GetAsArray();
+ if (thread_infos) {
+ lldb::tid_t tid;
+ const size_t n = thread_infos->GetSize();
+ for (size_t i = 0; i < n; ++i) {
+ StructuredData::Dictionary *thread_dict =
+ thread_infos->GetItemAtIndex(i)->GetAsDictionary();
+ if (thread_dict) {
+ if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>(
+ "tid", tid, LLDB_INVALID_THREAD_ID)) {
+ if (tid == thread->GetID())
+ return (bool)SetThreadStopInfo(thread_dict);
+ }
}
+ }
}
- return false;
+ }
+ return false;
}
-bool
-ProcessGDBRemote::CalculateThreadStopInfo (ThreadGDBRemote *thread)
-{
- // See if we got thread stop infos for all threads via the "jThreadsInfo" packet
- if (GetThreadStopInfoFromJSON (thread, m_jthreadsinfo_sp))
- return true;
+bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) {
+ // See if we got thread stop infos for all threads via the "jThreadsInfo"
+ // packet
+ if (GetThreadStopInfoFromJSON(thread, m_jthreadsinfo_sp))
+ return true;
- // See if we got thread stop info for any threads valid stop info reasons threads
- // via the "jstopinfo" packet stop reply packet key/value pair?
- if (m_jstopinfo_sp)
- {
- // If we have "jstopinfo" then we have stop descriptions for all threads
- // that have stop reasons, and if there is no entry for a thread, then
- // it has no stop reason.
- thread->GetRegisterContext()->InvalidateIfNeeded(true);
- if (!GetThreadStopInfoFromJSON (thread, m_jstopinfo_sp))
- {
- thread->SetStopInfo (StopInfoSP());
- }
- return true;
+ // See if we got thread stop info for any threads valid stop info reasons
+ // threads
+ // via the "jstopinfo" packet stop reply packet key/value pair?
+ if (m_jstopinfo_sp) {
+ // If we have "jstopinfo" then we have stop descriptions for all threads
+ // that have stop reasons, and if there is no entry for a thread, then
+ // it has no stop reason.
+ thread->GetRegisterContext()->InvalidateIfNeeded(true);
+ if (!GetThreadStopInfoFromJSON(thread, m_jstopinfo_sp)) {
+ thread->SetStopInfo(StopInfoSP());
}
+ return true;
+ }
- // Fall back to using the qThreadStopInfo packet
- StringExtractorGDBRemote stop_packet;
- if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
- return SetThreadStopInfo (stop_packet) == eStateStopped;
- return false;
+ // Fall back to using the qThreadStopInfo packet
+ StringExtractorGDBRemote stop_packet;
+ if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
+ return SetThreadStopInfo(stop_packet) == eStateStopped;
+ return false;
}
-
-ThreadSP
-ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
- ExpeditedRegisterMap &expedited_register_map,
- uint8_t signo,
- const std::string &thread_name,
- const std::string &reason,
- const std::string &description,
- uint32_t exc_type,
- const std::vector<addr_t> &exc_data,
- addr_t thread_dispatch_qaddr,
- bool queue_vars_valid, // Set to true if queue_name, queue_kind and queue_serial are valid
- LazyBool associated_with_dispatch_queue,
- addr_t dispatch_queue_t,
- std::string &queue_name,
- QueueKind queue_kind,
- uint64_t queue_serial)
-{
- ThreadSP thread_sp;
- if (tid != LLDB_INVALID_THREAD_ID)
- {
- // Scope for "locker" below
- {
- // m_thread_list_real does have its own mutex, but we need to
- // hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
- // and the m_thread_list_real.AddThread(...) so it doesn't change on us
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
- thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
-
- if (!thread_sp)
- {
- // Create the thread if we need to
- thread_sp.reset (new ThreadGDBRemote (*this, tid));
- m_thread_list_real.AddThread(thread_sp);
+ThreadSP ProcessGDBRemote::SetThreadStopInfo(
+ lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map,
+ uint8_t signo, const std::string &thread_name, const std::string &reason,
+ const std::string &description, uint32_t exc_type,
+ const std::vector<addr_t> &exc_data, addr_t thread_dispatch_qaddr,
+ bool queue_vars_valid, // Set to true if queue_name, queue_kind and
+ // queue_serial are valid
+ LazyBool associated_with_dispatch_queue, addr_t dispatch_queue_t,
+ std::string &queue_name, QueueKind queue_kind, uint64_t queue_serial) {
+ ThreadSP thread_sp;
+ if (tid != LLDB_INVALID_THREAD_ID) {
+ // Scope for "locker" below
+ {
+ // m_thread_list_real does have its own mutex, but we need to
+ // hold onto the mutex between the call to
+ // m_thread_list_real.FindThreadByID(...)
+ // and the m_thread_list_real.AddThread(...) so it doesn't change on us
+ std::lock_guard<std::recursive_mutex> guard(
+ m_thread_list_real.GetMutex());
+ thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
+
+ if (!thread_sp) {
+ // Create the thread if we need to
+ thread_sp.reset(new ThreadGDBRemote(*this, tid));
+ m_thread_list_real.AddThread(thread_sp);
+ }
+ }
+
+ if (thread_sp) {
+ ThreadGDBRemote *gdb_thread =
+ static_cast<ThreadGDBRemote *>(thread_sp.get());
+ gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+
+ for (const auto &pair : expedited_register_map) {
+ StringExtractor reg_value_extractor;
+ reg_value_extractor.GetStringRef() = pair.second;
+ DataBufferSP buffer_sp(new DataBufferHeap(
+ reg_value_extractor.GetStringRef().size() / 2, 0));
+ reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
+ }
+
+ thread_sp->SetName(thread_name.empty() ? NULL : thread_name.c_str());
+
+ gdb_thread->SetThreadDispatchQAddr(thread_dispatch_qaddr);
+ // Check if the GDB server was able to provide the queue name, kind and
+ // serial number
+ if (queue_vars_valid)
+ gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind,
+ queue_serial, dispatch_queue_t,
+ associated_with_dispatch_queue);
+ else
+ gdb_thread->ClearQueueInfo();
+
+ gdb_thread->SetAssociatedWithLibdispatchQueue(
+ associated_with_dispatch_queue);
+
+ if (dispatch_queue_t != LLDB_INVALID_ADDRESS)
+ gdb_thread->SetQueueLibdispatchQueueAddress(dispatch_queue_t);
+
+ // Make sure we update our thread stop reason just once
+ if (!thread_sp->StopInfoIsUpToDate()) {
+ thread_sp->SetStopInfo(StopInfoSP());
+ // If there's a memory thread backed by this thread, we need to use it
+ // to calcualte StopInfo.
+ ThreadSP memory_thread_sp =
+ m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID());
+ if (memory_thread_sp)
+ thread_sp = memory_thread_sp;
+
+ if (exc_type != 0) {
+ const size_t exc_data_size = exc_data.size();
+
+ thread_sp->SetStopInfo(
+ StopInfoMachException::CreateStopReasonWithMachException(
+ *thread_sp, exc_type, exc_data_size,
+ exc_data_size >= 1 ? exc_data[0] : 0,
+ exc_data_size >= 2 ? exc_data[1] : 0,
+ exc_data_size >= 3 ? exc_data[2] : 0));
+ } else {
+ bool handled = false;
+ bool did_exec = false;
+ if (!reason.empty()) {
+ if (reason.compare("trace") == 0) {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+ ->GetBreakpointSiteList()
+ .FindByAddress(pc);
+
+ // If the current pc is a breakpoint site then the StopInfo should
+ // be set to Breakpoint
+ // Otherwise, it will be set to Trace.
+ if (bp_site_sp &&
+ bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ } else
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonToTrace(*thread_sp));
+ handled = true;
+ } else if (reason.compare("breakpoint") == 0) {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+ ->GetBreakpointSiteList()
+ .FindByAddress(pc);
+ if (bp_site_sp) {
+ // If the breakpoint is for this thread, then we'll report the
+ // hit, but if it is for another thread,
+ // we can just report no reason. We don't need to worry about
+ // stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices
+ // that there's a breakpoint under the pc.
+ handled = true;
+ if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ } else {
+ StopInfoSP invalid_stop_info_sp;
+ thread_sp->SetStopInfo(invalid_stop_info_sp);
+ }
+ }
+ } else if (reason.compare("trap") == 0) {
+ // Let the trap just use the standard signal stop reason below...
+ } else if (reason.compare("watchpoint") == 0) {
+ 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);
+ addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+ watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
+ if (wp_addr != LLDB_INVALID_ADDRESS) {
+ WatchpointSP wp_sp;
+ ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
+ if ((core >= ArchSpec::kCore_mips_first &&
+ core <= ArchSpec::kCore_mips_last) ||
+ (core >= ArchSpec::eCore_arm_generic &&
+ core <= ArchSpec::eCore_arm_aarch64))
+ wp_sp = GetTarget().GetWatchpointList().FindByAddress(
+ wp_hit_addr);
+ if (!wp_sp)
+ wp_sp =
+ GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ if (wp_sp) {
+ wp_sp->SetHardwareIndex(wp_index);
+ watch_id = wp_sp->GetID();
+ }
+ }
+ if (watch_id == LLDB_INVALID_WATCH_ID) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
+ GDBR_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("failed to find watchpoint");
+ }
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
+ *thread_sp, watch_id, wp_hit_addr));
+ handled = true;
+ } else if (reason.compare("exception") == 0) {
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
+ *thread_sp, description.c_str()));
+ handled = true;
+ } else if (reason.compare("exec") == 0) {
+ did_exec = true;
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithExec(*thread_sp));
+ handled = true;
}
- }
-
- if (thread_sp)
- {
- ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
- gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
-
- for (const auto &pair : expedited_register_map)
- {
- StringExtractor reg_value_extractor;
- reg_value_extractor.GetStringRef() = pair.second;
- gdb_thread->PrivateSetRegisterValue (pair.first, reg_value_extractor);
+ } else if (!signo) {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp =
+ thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
+ pc);
+
+ // If the current pc is a breakpoint site then the StopInfo should
+ // be set to Breakpoint
+ // even though the remote stub did not set it as such. This can
+ // happen when
+ // the thread is involuntarily interrupted (e.g. due to stops on
+ // other
+ // threads) just as it is about to execute the breakpoint
+ // instruction.
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ handled = true;
}
-
- thread_sp->SetName (thread_name.empty() ? NULL : thread_name.c_str());
-
- gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
- // Check if the GDB server was able to provide the queue name, kind and serial number
- if (queue_vars_valid)
- gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial, dispatch_queue_t, associated_with_dispatch_queue);
- else
- gdb_thread->ClearQueueInfo();
-
- gdb_thread->SetAssociatedWithLibdispatchQueue (associated_with_dispatch_queue);
-
- if (dispatch_queue_t != LLDB_INVALID_ADDRESS)
- gdb_thread->SetQueueLibdispatchQueueAddress (dispatch_queue_t);
-
- // Make sure we update our thread stop reason just once
- if (!thread_sp->StopInfoIsUpToDate())
- {
- thread_sp->SetStopInfo (StopInfoSP());
- // If there's a memory thread backed by this thread, we need to use it to calcualte StopInfo.
- ThreadSP memory_thread_sp = m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID());
- if (memory_thread_sp)
- thread_sp = memory_thread_sp;
-
- if (exc_type != 0)
- {
- const size_t exc_data_size = exc_data.size();
-
- thread_sp->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
- exc_type,
- exc_data_size,
- exc_data_size >= 1 ? exc_data[0] : 0,
- exc_data_size >= 2 ? exc_data[1] : 0,
- exc_data_size >= 3 ? exc_data[2] : 0));
+ }
+
+ if (!handled && signo && did_exec == false) {
+ if (signo == SIGTRAP) {
+ // Currently we are going to assume SIGTRAP means we are either
+ // hitting a breakpoint or hardware single stepping.
+ handled = true;
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC() +
+ m_breakpoint_pc_offset;
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+ ->GetBreakpointSiteList()
+ .FindByAddress(pc);
+
+ if (bp_site_sp) {
+ // If the breakpoint is for this thread, then we'll report the
+ // hit, but if it is for another thread,
+ // we can just report no reason. We don't need to worry about
+ // stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices
+ // that there's a breakpoint under the pc.
+ if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ if (m_breakpoint_pc_offset != 0)
+ thread_sp->GetRegisterContext()->SetPC(pc);
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ } else {
+ StopInfoSP invalid_stop_info_sp;
+ thread_sp->SetStopInfo(invalid_stop_info_sp);
}
+ } else {
+ // If we were stepping then assume the stop was the result of
+ // the trace. If we were
+ // not stepping then report the SIGTRAP.
+ // FIXME: We are still missing the case where we single step
+ // over a trap instruction.
+ if (thread_sp->GetTemporaryResumeState() == eStateStepping)
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonToTrace(*thread_sp));
else
- {
- bool handled = false;
- bool did_exec = false;
- if (!reason.empty())
- {
- if (reason.compare("trace") == 0)
- {
- addr_t pc = thread_sp->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
- // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
- // Otherwise, it will be set to Trace.
- if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
- {
- thread_sp->SetStopInfo(
- StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
- }
- else
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
- handled = true;
- }
- else if (reason.compare("breakpoint") == 0)
- {
- addr_t pc = thread_sp->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
- if (bp_site_sp)
- {
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- handled = true;
- if (bp_site_sp->ValidForThisThread (thread_sp.get()))
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
- }
- else
- {
- StopInfoSP invalid_stop_info_sp;
- thread_sp->SetStopInfo (invalid_stop_info_sp);
- }
- }
- }
- else if (reason.compare("trap") == 0)
- {
- // Let the trap just use the standard signal stop reason below...
- }
- else if (reason.compare("watchpoint") == 0)
- {
- 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);
- addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
- watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
- if (wp_addr != LLDB_INVALID_ADDRESS)
- {
- WatchpointSP wp_sp;
- ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
- if ((core >= ArchSpec::kCore_mips_first && core <= ArchSpec::kCore_mips_last) ||
- (core >= ArchSpec::eCore_arm_generic && core <= ArchSpec::eCore_arm_aarch64))
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr);
- if (!wp_sp)
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- if (wp_sp)
- {
- wp_sp->SetHardwareIndex(wp_index);
- watch_id = wp_sp->GetID();
- }
- }
- if (watch_id == LLDB_INVALID_WATCH_ID)
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS));
- if (log) log->Printf ("failed to find watchpoint");
- }
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id, wp_hit_addr));
- handled = true;
- }
- else if (reason.compare("exception") == 0)
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
- handled = true;
- }
- else if (reason.compare("exec") == 0)
- {
- did_exec = true;
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithExec(*thread_sp));
- handled = true;
- }
- }
- else if (!signo)
- {
- addr_t pc = thread_sp->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp =
- thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
- // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
- // even though the remote stub did not set it as such. This can happen when
- // the thread is involuntarily interrupted (e.g. due to stops on other
- // threads) just as it is about to execute the breakpoint instruction.
- if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
- {
- thread_sp->SetStopInfo(
- StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
- handled = true;
- }
- }
-
- if (!handled && signo && did_exec == false)
- {
- if (signo == SIGTRAP)
- {
- // Currently we are going to assume SIGTRAP means we are either
- // hitting a breakpoint or hardware single stepping.
- handled = true;
- addr_t pc = thread_sp->GetRegisterContext()->GetPC() + m_breakpoint_pc_offset;
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
- if (bp_site_sp)
- {
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- if (bp_site_sp->ValidForThisThread (thread_sp.get()))
- {
- if(m_breakpoint_pc_offset != 0)
- thread_sp->GetRegisterContext()->SetPC(pc);
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
- }
- else
- {
- StopInfoSP invalid_stop_info_sp;
- thread_sp->SetStopInfo (invalid_stop_info_sp);
- }
- }
- else
- {
- // If we were stepping then assume the stop was the result of the trace. If we were
- // not stepping then report the SIGTRAP.
- // FIXME: We are still missing the case where we single step over a trap instruction.
- if (thread_sp->GetTemporaryResumeState() == eStateStepping)
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
- else
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo, description.c_str()));
- }
- }
- if (!handled)
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo, description.c_str()));
- }
-
- if (!description.empty())
- {
- lldb::StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
- if (stop_info_sp)
- {
- const char *stop_info_desc = stop_info_sp->GetDescription();
- if (!stop_info_desc || !stop_info_desc[0])
- stop_info_sp->SetDescription (description.c_str());
- }
- else
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
- }
- }
- }
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+ *thread_sp, signo, description.c_str()));
+ }
}
+ if (!handled)
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+ *thread_sp, signo, description.c_str()));
+ }
+
+ if (!description.empty()) {
+ lldb::StopInfoSP stop_info_sp(thread_sp->GetStopInfo());
+ if (stop_info_sp) {
+ const char *stop_info_desc = stop_info_sp->GetDescription();
+ if (!stop_info_desc || !stop_info_desc[0])
+ stop_info_sp->SetDescription(description.c_str());
+ } else {
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
+ *thread_sp, description.c_str()));
+ }
+ }
}
+ }
}
- return thread_sp;
+ }
+ return thread_sp;
}
lldb::ThreadSP
-ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict)
-{
- static ConstString g_key_tid("tid");
- static ConstString g_key_name("name");
- static ConstString g_key_reason("reason");
- static ConstString g_key_metype("metype");
- static ConstString g_key_medata("medata");
- static ConstString g_key_qaddr("qaddr");
- static ConstString g_key_dispatch_queue_t("dispatch_queue_t");
- static ConstString g_key_associated_with_dispatch_queue("associated_with_dispatch_queue");
- static ConstString g_key_queue_name("qname");
- static ConstString g_key_queue_kind("qkind");
- static ConstString g_key_queue_serial_number("qserialnum");
- static ConstString g_key_registers("registers");
- static ConstString g_key_memory("memory");
- static ConstString g_key_address("address");
- static ConstString g_key_bytes("bytes");
- static ConstString g_key_description("description");
- static ConstString g_key_signal("signal");
+ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
+ static ConstString g_key_tid("tid");
+ static ConstString g_key_name("name");
+ static ConstString g_key_reason("reason");
+ static ConstString g_key_metype("metype");
+ static ConstString g_key_medata("medata");
+ static ConstString g_key_qaddr("qaddr");
+ static ConstString g_key_dispatch_queue_t("dispatch_queue_t");
+ static ConstString g_key_associated_with_dispatch_queue(
+ "associated_with_dispatch_queue");
+ static ConstString g_key_queue_name("qname");
+ static ConstString g_key_queue_kind("qkind");
+ static ConstString g_key_queue_serial_number("qserialnum");
+ static ConstString g_key_registers("registers");
+ static ConstString g_key_memory("memory");
+ static ConstString g_key_address("address");
+ static ConstString g_key_bytes("bytes");
+ static ConstString g_key_description("description");
+ static ConstString g_key_signal("signal");
+
+ // Stop with signal and thread info
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ uint8_t signo = 0;
+ std::string value;
+ std::string thread_name;
+ std::string reason;
+ std::string description;
+ uint32_t exc_type = 0;
+ std::vector<addr_t> exc_data;
+ addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
+ ExpeditedRegisterMap expedited_register_map;
+ bool queue_vars_valid = false;
+ addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
+ LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
+ std::string queue_name;
+ QueueKind queue_kind = eQueueKindUnknown;
+ uint64_t queue_serial_number = 0;
+ // Iterate through all of the thread dictionary key/value pairs from the
+ // structured data dictionary
+
+ thread_dict->ForEach([this, &tid, &expedited_register_map, &thread_name,
+ &signo, &reason, &description, &exc_type, &exc_data,
+ &thread_dispatch_qaddr, &queue_vars_valid,
+ &associated_with_dispatch_queue, &dispatch_queue_t,
+ &queue_name, &queue_kind, &queue_serial_number](
+ ConstString key,
+ StructuredData::Object *object) -> bool {
+ if (key == g_key_tid) {
+ // thread in big endian hex
+ tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+ } else if (key == g_key_metype) {
+ // exception type in big endian hex
+ exc_type = object->GetIntegerValue(0);
+ } else if (key == g_key_medata) {
+ // exception data in big endian hex
+ StructuredData::Array *array = object->GetAsArray();
+ if (array) {
+ array->ForEach([&exc_data](StructuredData::Object *object) -> bool {
+ exc_data.push_back(object->GetIntegerValue());
+ return true; // Keep iterating through all array items
+ });
+ }
+ } else if (key == g_key_name) {
+ thread_name = object->GetStringValue();
+ } else if (key == g_key_qaddr) {
+ thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
+ } else if (key == g_key_queue_name) {
+ queue_vars_valid = true;
+ queue_name = object->GetStringValue();
+ } else if (key == g_key_queue_kind) {
+ std::string queue_kind_str = object->GetStringValue();
+ if (queue_kind_str == "serial") {
+ queue_vars_valid = true;
+ queue_kind = eQueueKindSerial;
+ } else if (queue_kind_str == "concurrent") {
+ queue_vars_valid = true;
+ queue_kind = eQueueKindConcurrent;
+ }
+ } else if (key == g_key_queue_serial_number) {
+ queue_serial_number = object->GetIntegerValue(0);
+ if (queue_serial_number != 0)
+ queue_vars_valid = true;
+ } else if (key == g_key_dispatch_queue_t) {
+ dispatch_queue_t = object->GetIntegerValue(0);
+ if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
+ queue_vars_valid = true;
+ } else if (key == g_key_associated_with_dispatch_queue) {
+ queue_vars_valid = true;
+ bool associated = object->GetBooleanValue();
+ if (associated)
+ associated_with_dispatch_queue = eLazyBoolYes;
+ else
+ associated_with_dispatch_queue = eLazyBoolNo;
+ } else if (key == g_key_reason) {
+ reason = object->GetStringValue();
+ } else if (key == g_key_description) {
+ description = object->GetStringValue();
+ } else if (key == g_key_registers) {
+ StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
+
+ if (registers_dict) {
+ registers_dict->ForEach(
+ [&expedited_register_map](ConstString key,
+ StructuredData::Object *object) -> bool {
+ const uint32_t reg =
+ StringConvert::ToUInt32(key.GetCString(), UINT32_MAX, 10);
+ if (reg != UINT32_MAX)
+ expedited_register_map[reg] = object->GetStringValue();
+ return true; // Keep iterating through all array items
+ });
+ }
+ } else if (key == g_key_memory) {
+ StructuredData::Array *array = object->GetAsArray();
+ if (array) {
+ array->ForEach([this](StructuredData::Object *object) -> bool {
+ StructuredData::Dictionary *mem_cache_dict =
+ object->GetAsDictionary();
+ if (mem_cache_dict) {
+ lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
+ if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>(
+ "address", mem_cache_addr)) {
+ if (mem_cache_addr != LLDB_INVALID_ADDRESS) {
+ StringExtractor bytes;
+ if (mem_cache_dict->GetValueForKeyAsString(
+ "bytes", bytes.GetStringRef())) {
+ bytes.SetFilePos(0);
+
+ const size_t byte_size = bytes.GetStringRef().size() / 2;
+ DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ const size_t bytes_copied =
+ bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
+ if (bytes_copied == byte_size)
+ m_memory_cache.AddL1CacheData(mem_cache_addr,
+ data_buffer_sp);
+ }
+ }
+ }
+ }
+ return true; // Keep iterating through all array items
+ });
+ }
+
+ } else if (key == g_key_signal)
+ signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
+ return true; // Keep iterating through all dictionary key/value pairs
+ });
+
+ return SetThreadStopInfo(tid, expedited_register_map, signo, thread_name,
+ reason, description, exc_type, exc_data,
+ thread_dispatch_qaddr, queue_vars_valid,
+ associated_with_dispatch_queue, dispatch_queue_t,
+ queue_name, queue_kind, queue_serial_number);
+}
+StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
+ stop_packet.SetFilePos(0);
+ const char stop_type = stop_packet.GetChar();
+ switch (stop_type) {
+ case 'T':
+ case 'S': {
+ // This is a bit of a hack, but is is required. If we did exec, we
+ // need to clear our thread lists and also know to rebuild our dynamic
+ // register info before we lookup and threads and populate the expedited
+ // register values so we need to know this right away so we can cleanup
+ // and update our registers.
+ const uint32_t stop_id = GetStopID();
+ if (stop_id == 0) {
+ // Our first stop, make sure we have a process ID, and also make
+ // sure we know about our registers
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ SetID(pid);
+ }
+ BuildDynamicRegisterInfo(true);
+ }
// Stop with signal and thread info
lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- uint8_t signo = 0;
- std::string value;
+ const uint8_t signo = stop_packet.GetHexU8();
+ llvm::StringRef key;
+ llvm::StringRef value;
std::string thread_name;
std::string reason;
std::string description;
uint32_t exc_type = 0;
std::vector<addr_t> exc_data;
addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
- ExpeditedRegisterMap expedited_register_map;
- bool queue_vars_valid = false;
+ bool queue_vars_valid =
+ false; // says if locals below that start with "queue_" are valid
addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
std::string queue_name;
QueueKind queue_kind = eQueueKindUnknown;
uint64_t queue_serial_number = 0;
- // Iterate through all of the thread dictionary key/value pairs from the structured data dictionary
-
- thread_dict->ForEach([this,
- &tid,
- &expedited_register_map,
- &thread_name,
- &signo,
- &reason,
- &description,
- &exc_type,
- &exc_data,
- &thread_dispatch_qaddr,
- &queue_vars_valid,
- &associated_with_dispatch_queue,
- &dispatch_queue_t,
- &queue_name,
- &queue_kind,
- &queue_serial_number]
- (ConstString key, StructuredData::Object* object) -> bool
- {
- if (key == g_key_tid)
- {
- // thread in big endian hex
- tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
- }
- else if (key == g_key_metype)
- {
- // exception type in big endian hex
- exc_type = object->GetIntegerValue(0);
- }
- else if (key == g_key_medata)
- {
- // exception data in big endian hex
- StructuredData::Array *array = object->GetAsArray();
- if (array)
- {
- array->ForEach([&exc_data](StructuredData::Object* object) -> bool {
- exc_data.push_back(object->GetIntegerValue());
- return true; // Keep iterating through all array items
- });
- }
- }
- else if (key == g_key_name)
- {
- thread_name = object->GetStringValue();
- }
- else if (key == g_key_qaddr)
- {
- thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
- }
- else if (key == g_key_queue_name)
- {
- queue_vars_valid = true;
- queue_name = object->GetStringValue();
- }
- else if (key == g_key_queue_kind)
- {
- std::string queue_kind_str = object->GetStringValue();
- if (queue_kind_str == "serial")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindSerial;
- }
- else if (queue_kind_str == "concurrent")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindConcurrent;
- }
- }
- else if (key == g_key_queue_serial_number)
- {
- queue_serial_number = object->GetIntegerValue(0);
- if (queue_serial_number != 0)
- queue_vars_valid = true;
- }
- else if (key == g_key_dispatch_queue_t)
- {
- dispatch_queue_t = object->GetIntegerValue(0);
- if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
- queue_vars_valid = true;
- }
- else if (key == g_key_associated_with_dispatch_queue)
- {
- queue_vars_valid = true;
- bool associated = object->GetBooleanValue ();
- if (associated)
- associated_with_dispatch_queue = eLazyBoolYes;
- else
- associated_with_dispatch_queue = eLazyBoolNo;
- }
- else if (key == g_key_reason)
- {
- reason = object->GetStringValue();
- }
- else if (key == g_key_description)
- {
- description = object->GetStringValue();
+ ExpeditedRegisterMap expedited_register_map;
+ while (stop_packet.GetNameColonValue(key, value)) {
+ if (key.compare("metype") == 0) {
+ // exception type in big endian hex
+ value.getAsInteger(16, exc_type);
+ } else if (key.compare("medata") == 0) {
+ // exception data in big endian hex
+ uint64_t x;
+ value.getAsInteger(16, x);
+ exc_data.push_back(x);
+ } else if (key.compare("thread") == 0) {
+ // thread in big endian hex
+ if (value.getAsInteger(16, tid))
+ tid = LLDB_INVALID_THREAD_ID;
+ } else if (key.compare("threads") == 0) {
+ std::lock_guard<std::recursive_mutex> guard(
+ m_thread_list_real.GetMutex());
+
+ m_thread_ids.clear();
+ // A comma separated list of all threads in the current
+ // process that includes the thread for this stop reply
+ // packet
+ lldb::tid_t tid;
+ while (!value.empty()) {
+ llvm::StringRef tid_str;
+ std::tie(tid_str, value) = value.split(',');
+ if (tid_str.getAsInteger(16, tid))
+ tid = LLDB_INVALID_THREAD_ID;
+ m_thread_ids.push_back(tid);
}
- else if (key == g_key_registers)
- {
- StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
-
- if (registers_dict)
- {
- registers_dict->ForEach([&expedited_register_map](ConstString key, StructuredData::Object* object) -> bool {
- const uint32_t reg = StringConvert::ToUInt32 (key.GetCString(), UINT32_MAX, 10);
- if (reg != UINT32_MAX)
- expedited_register_map[reg] = object->GetStringValue();
- return true; // Keep iterating through all array items
- });
- }
+ } else if (key.compare("thread-pcs") == 0) {
+ m_thread_pcs.clear();
+ // A comma separated list of all threads in the current
+ // process that includes the thread for this stop reply
+ // packet
+ lldb::addr_t pc;
+ while (!value.empty()) {
+ llvm::StringRef pc_str;
+ std::tie(pc_str, value) = value.split(',');
+ if (pc_str.getAsInteger(16, pc))
+ pc = LLDB_INVALID_ADDRESS;
+ m_thread_pcs.push_back(pc);
}
- else if (key == g_key_memory)
- {
- StructuredData::Array *array = object->GetAsArray();
- if (array)
- {
- array->ForEach([this](StructuredData::Object* object) -> bool {
- StructuredData::Dictionary *mem_cache_dict = object->GetAsDictionary();
- if (mem_cache_dict)
- {
- lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
- if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>("address", mem_cache_addr))
- {
- if (mem_cache_addr != LLDB_INVALID_ADDRESS)
- {
- StringExtractor bytes;
- if (mem_cache_dict->GetValueForKeyAsString("bytes", bytes.GetStringRef()))
- {
- bytes.SetFilePos(0);
-
- const size_t byte_size = bytes.GetStringRef().size()/2;
- DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
- const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0);
- if (bytes_copied == byte_size)
- m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
- }
- }
- }
- }
- return true; // Keep iterating through all array items
- });
- }
-
+ } else if (key.compare("jstopinfo") == 0) {
+ StringExtractor json_extractor(value);
+ std::string json;
+ // Now convert the HEX bytes into a string value
+ json_extractor.GetHexByteString(json);
+
+ // This JSON contains thread IDs and thread stop info for all threads.
+ // It doesn't contain expedited registers, memory or queue info.
+ m_jstopinfo_sp = StructuredData::ParseJSON(json);
+ } else if (key.compare("hexname") == 0) {
+ StringExtractor name_extractor(value);
+ std::string name;
+ // Now convert the HEX bytes into a string value
+ name_extractor.GetHexByteString(thread_name);
+ } else if (key.compare("name") == 0) {
+ thread_name = value;
+ } else if (key.compare("qaddr") == 0) {
+ value.getAsInteger(16, thread_dispatch_qaddr);
+ } else if (key.compare("dispatch_queue_t") == 0) {
+ queue_vars_valid = true;
+ value.getAsInteger(16, dispatch_queue_t);
+ } else if (key.compare("qname") == 0) {
+ queue_vars_valid = true;
+ StringExtractor name_extractor(value);
+ // Now convert the HEX bytes into a string value
+ name_extractor.GetHexByteString(queue_name);
+ } else if (key.compare("qkind") == 0) {
+ queue_kind = llvm::StringSwitch<QueueKind>(value)
+ .Case("serial", eQueueKindSerial)
+ .Case("concurrent", eQueueKindConcurrent)
+ .Default(eQueueKindUnknown);
+ queue_vars_valid = queue_kind != eQueueKindUnknown;
+ } else if (key.compare("qserialnum") == 0) {
+ if (!value.getAsInteger(0, queue_serial_number))
+ queue_vars_valid = true;
+ } else if (key.compare("reason") == 0) {
+ reason = value;
+ } else if (key.compare("description") == 0) {
+ StringExtractor desc_extractor(value);
+ // Now convert the HEX bytes into a string value
+ desc_extractor.GetHexByteString(description);
+ } else if (key.compare("memory") == 0) {
+ // Expedited memory. GDB servers can choose to send back expedited
+ // memory
+ // that can populate the L1 memory cache in the process so that things
+ // like
+ // the frame pointer backchain can be expedited. This will help stack
+ // backtracing be more efficient by not having to send as many memory
+ // read
+ // requests down the remote GDB server.
+
+ // Key/value pair format: memory:<addr>=<bytes>;
+ // <addr> is a number whose base will be interpreted by the prefix:
+ // "0x[0-9a-fA-F]+" for hex
+ // "0[0-7]+" for octal
+ // "[1-9]+" for decimal
+ // <bytes> is native endian ASCII hex bytes just like the register
+ // values
+ llvm::StringRef addr_str, bytes_str;
+ std::tie(addr_str, bytes_str) = value.split('=');
+ if (!addr_str.empty() && !bytes_str.empty()) {
+ lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
+ if (!addr_str.getAsInteger(0, mem_cache_addr)) {
+ StringExtractor bytes(bytes_str);
+ const size_t byte_size = bytes.GetBytesLeft() / 2;
+ DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ const size_t bytes_copied =
+ bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
+ if (bytes_copied == byte_size)
+ m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
+ }
}
- else if (key == g_key_signal)
- signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
- return true; // Keep iterating through all dictionary key/value pairs
- });
-
- return SetThreadStopInfo (tid,
- expedited_register_map,
- signo,
- thread_name,
- reason,
- description,
- exc_type,
- exc_data,
- thread_dispatch_qaddr,
- queue_vars_valid,
- associated_with_dispatch_queue,
- dispatch_queue_t,
- queue_name,
- queue_kind,
- queue_serial_number);
+ } else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 ||
+ key.compare("awatch") == 0) {
+ // Support standard GDB remote stop reply packet 'TAAwatch:addr'
+ lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS;
+ value.getAsInteger(16, wp_addr);
+
+ WatchpointSP wp_sp =
+ GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ uint32_t wp_index = LLDB_INVALID_INDEX32;
+
+ if (wp_sp)
+ wp_index = wp_sp->GetHardwareIndex();
+
+ reason = "watchpoint";
+ StreamString ostr;
+ ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
+ description = ostr.GetString();
+ } else if (key.compare("library") == 0) {
+ LoadModules();
+ } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
+ uint32_t reg = UINT32_MAX;
+ if (!key.getAsInteger(16, reg))
+ expedited_register_map[reg] = std::move(value);
+ }
+ }
+
+ if (tid == LLDB_INVALID_THREAD_ID) {
+ // A thread id may be invalid if the response is old style 'S' packet
+ // which does not provide the
+ // thread information. So update the thread list and choose the first one.
+ UpdateThreadIDList();
+
+ if (!m_thread_ids.empty()) {
+ tid = m_thread_ids.front();
+ }
+ }
+
+ ThreadSP thread_sp = SetThreadStopInfo(
+ tid, expedited_register_map, signo, thread_name, reason, description,
+ exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
+ associated_with_dispatch_queue, dispatch_queue_t, queue_name,
+ queue_kind, queue_serial_number);
+
+ return eStateStopped;
+ } break;
+
+ case 'W':
+ case 'X':
+ // process exited
+ return eStateExited;
+
+ default:
+ break;
+ }
+ return eStateInvalid;
}
-StateType
-ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
-{
- stop_packet.SetFilePos (0);
- const char stop_type = stop_packet.GetChar();
- switch (stop_type)
- {
- case 'T':
- case 'S':
- {
- // This is a bit of a hack, but is is required. If we did exec, we
- // need to clear our thread lists and also know to rebuild our dynamic
- // register info before we lookup and threads and populate the expedited
- // register values so we need to know this right away so we can cleanup
- // and update our registers.
- const uint32_t stop_id = GetStopID();
- if (stop_id == 0)
- {
- // Our first stop, make sure we have a process ID, and also make
- // sure we know about our registers
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- {
- lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
- if (pid != LLDB_INVALID_PROCESS_ID)
- SetID (pid);
- }
- BuildDynamicRegisterInfo (true);
- }
- // Stop with signal and thread info
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- const uint8_t signo = stop_packet.GetHexU8();
- std::string key;
- std::string value;
- std::string thread_name;
- std::string reason;
- std::string description;
- uint32_t exc_type = 0;
- std::vector<addr_t> exc_data;
- addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
- bool queue_vars_valid = false; // says if locals below that start with "queue_" are valid
- addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
- LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
- std::string queue_name;
- QueueKind queue_kind = eQueueKindUnknown;
- uint64_t queue_serial_number = 0;
- ExpeditedRegisterMap expedited_register_map;
- while (stop_packet.GetNameColonValue(key, value))
- {
- if (key.compare("metype") == 0)
- {
- // exception type in big endian hex
- exc_type = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- }
- else if (key.compare("medata") == 0)
- {
- // exception data in big endian hex
- exc_data.push_back(StringConvert::ToUInt64 (value.c_str(), 0, 16));
- }
- else if (key.compare("thread") == 0)
- {
- // thread in big endian hex
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- }
- else if (key.compare("threads") == 0)
- {
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-
- m_thread_ids.clear();
- // A comma separated list of all threads in the current
- // process that includes the thread for this stop reply
- // packet
- size_t comma_pos;
- lldb::tid_t tid;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- // thread in big endian hex
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- value.erase(0, comma_pos + 1);
- }
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- }
- else if (key.compare("thread-pcs") == 0)
- {
- m_thread_pcs.clear();
- // A comma separated list of all threads in the current
- // process that includes the thread for this stop reply
- // packet
- size_t comma_pos;
- lldb::addr_t pc;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- // thread in big endian hex
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_ADDRESS)
- m_thread_pcs.push_back (pc);
- value.erase(0, comma_pos + 1);
- }
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_ADDRESS)
- m_thread_pcs.push_back (pc);
- }
- else if (key.compare("jstopinfo") == 0)
- {
- StringExtractor json_extractor;
- // Swap "value" over into "name_extractor"
- json_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- json_extractor.GetHexByteString (value);
-
- // This JSON contains thread IDs and thread stop info for all threads.
- // It doesn't contain expedited registers, memory or queue info.
- m_jstopinfo_sp = StructuredData::ParseJSON (value);
- }
- else if (key.compare("hexname") == 0)
- {
- StringExtractor name_extractor;
- // Swap "value" over into "name_extractor"
- name_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- name_extractor.GetHexByteString (value);
- thread_name.swap (value);
- }
- else if (key.compare("name") == 0)
- {
- thread_name.swap (value);
- }
- else if (key.compare("qaddr") == 0)
- {
- thread_dispatch_qaddr = StringConvert::ToUInt64 (value.c_str(), 0, 16);
- }
- else if (key.compare("dispatch_queue_t") == 0)
- {
- queue_vars_valid = true;
- dispatch_queue_t = StringConvert::ToUInt64 (value.c_str(), 0, 16);
- }
- else if (key.compare("qname") == 0)
- {
- queue_vars_valid = true;
- StringExtractor name_extractor;
- // Swap "value" over into "name_extractor"
- name_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- name_extractor.GetHexByteString (value);
- queue_name.swap (value);
- }
- else if (key.compare("qkind") == 0)
- {
- if (value == "serial")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindSerial;
- }
- else if (value == "concurrent")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindConcurrent;
- }
- }
- else if (key.compare("qserialnum") == 0)
- {
- queue_serial_number = StringConvert::ToUInt64 (value.c_str(), 0, 0);
- if (queue_serial_number != 0)
- queue_vars_valid = true;
- }
- else if (key.compare("reason") == 0)
- {
- reason.swap(value);
- }
- else if (key.compare("description") == 0)
- {
- StringExtractor desc_extractor;
- // Swap "value" over into "name_extractor"
- desc_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- desc_extractor.GetHexByteString (value);
- description.swap(value);
- }
- else if (key.compare("memory") == 0)
- {
- // Expedited memory. GDB servers can choose to send back expedited memory
- // that can populate the L1 memory cache in the process so that things like
- // the frame pointer backchain can be expedited. This will help stack
- // backtracing be more efficient by not having to send as many memory read
- // requests down the remote GDB server.
-
- // Key/value pair format: memory:<addr>=<bytes>;
- // <addr> is a number whose base will be interpreted by the prefix:
- // "0x[0-9a-fA-F]+" for hex
- // "0[0-7]+" for octal
- // "[1-9]+" for decimal
- // <bytes> is native endian ASCII hex bytes just like the register values
- llvm::StringRef value_ref(value);
- std::pair<llvm::StringRef, llvm::StringRef> pair;
- pair = value_ref.split('=');
- if (!pair.first.empty() && !pair.second.empty())
- {
- std::string addr_str(pair.first.str());
- const lldb::addr_t mem_cache_addr = StringConvert::ToUInt64(addr_str.c_str(), LLDB_INVALID_ADDRESS, 0);
- if (mem_cache_addr != LLDB_INVALID_ADDRESS)
- {
- StringExtractor bytes;
- bytes.GetStringRef() = pair.second.str();
- const size_t byte_size = bytes.GetStringRef().size()/2;
- DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
- const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0);
- if (bytes_copied == byte_size)
- m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
- }
- }
- }
- else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 || key.compare("awatch") == 0)
- {
- // Support standard GDB remote stop reply packet 'TAAwatch:addr'
- lldb::addr_t wp_addr = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- uint32_t wp_index = LLDB_INVALID_INDEX32;
-
- if (wp_sp)
- wp_index = wp_sp->GetHardwareIndex();
-
- reason = "watchpoint";
- StreamString ostr;
- ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
- description = ostr.GetString().c_str();
- }
- else if (key.compare("library") == 0)
- {
- LoadModules();
- }
- else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1]))
- {
- uint32_t reg = StringConvert::ToUInt32 (key.c_str(), UINT32_MAX, 16);
- if (reg != UINT32_MAX)
- expedited_register_map[reg] = std::move(value);
- }
- }
-
- if (tid == LLDB_INVALID_THREAD_ID)
- {
- // A thread id may be invalid if the response is old style 'S' packet which does not provide the
- // thread information. So update the thread list and choose the first one.
- UpdateThreadIDList ();
-
- if (!m_thread_ids.empty ())
- {
- tid = m_thread_ids.front ();
- }
- }
-
- ThreadSP thread_sp = SetThreadStopInfo (tid,
- expedited_register_map,
- signo,
- thread_name,
- reason,
- description,
- exc_type,
- exc_data,
- thread_dispatch_qaddr,
- queue_vars_valid,
- associated_with_dispatch_queue,
- dispatch_queue_t,
- queue_name,
- queue_kind,
- queue_serial_number);
-
- return eStateStopped;
- }
- break;
-
- case 'W':
- case 'X':
- // process exited
- return eStateExited;
-
- default:
- break;
- }
- return eStateInvalid;
+void ProcessGDBRemote::RefreshStateAfterStop() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
+ // Set the thread stop info. It might have a "threads" key whose value is
+ // a list of all thread IDs in the current process, so m_thread_ids might
+ // get set.
+
+ // Scope for the lock
+ {
+ // Lock the thread stack while we access it
+ std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
+ // Get the number of stop packets on the stack
+ int nItems = m_stop_packet_stack.size();
+ // Iterate over them
+ for (int i = 0; i < nItems; i++) {
+ // Get the thread stop info
+ StringExtractorGDBRemote stop_info = m_stop_packet_stack[i];
+ // Process thread stop info
+ SetThreadStopInfo(stop_info);
+ }
+ // Clear the thread stop stack
+ m_stop_packet_stack.clear();
+ }
+
+ // Check to see if SetThreadStopInfo() filled in m_thread_ids?
+ if (m_thread_ids.empty()) {
+ // No, we need to fetch the thread list manually
+ UpdateThreadIDList();
+ }
+
+ // If we have queried for a default thread id
+ if (m_initial_tid != LLDB_INVALID_THREAD_ID) {
+ m_thread_list.SetSelectedThreadByID(m_initial_tid);
+ m_initial_tid = LLDB_INVALID_THREAD_ID;
+ }
+
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list_real.RefreshStateAfterStop();
}
-void
-ProcessGDBRemote::RefreshStateAfterStop ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-
- m_thread_ids.clear();
- m_thread_pcs.clear();
- // Set the thread stop info. It might have a "threads" key whose value is
- // a list of all thread IDs in the current process, so m_thread_ids might
- // get set.
-
- // Scope for the lock
- {
- // Lock the thread stack while we access it
- std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
- // Get the number of stop packets on the stack
- int nItems = m_stop_packet_stack.size();
- // Iterate over them
- for (int i = 0; i < nItems; i++)
- {
- // Get the thread stop info
- StringExtractorGDBRemote stop_info = m_stop_packet_stack[i];
- // Process thread stop info
- SetThreadStopInfo(stop_info);
- }
- // Clear the thread stop stack
- m_stop_packet_stack.clear();
- }
-
- // Check to see if SetThreadStopInfo() filled in m_thread_ids?
- if (m_thread_ids.empty())
- {
- // No, we need to fetch the thread list manually
- UpdateThreadIDList();
- }
-
- // If we have queried for a default thread id
- if (m_initial_tid != LLDB_INVALID_THREAD_ID)
- {
- m_thread_list.SetSelectedThreadByID(m_initial_tid);
- m_initial_tid = LLDB_INVALID_THREAD_ID;
- }
-
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
- m_thread_list_real.RefreshStateAfterStop();
+Error ProcessGDBRemote::DoHalt(bool &caused_stop) {
+ Error error;
+ if (m_public_state.GetValue() == eStateAttaching) {
+ // We are being asked to halt during an attach. We need to just close
+ // our file handle and debugserver will go away, and we can be done...
+ m_gdb_comm.Disconnect();
+ } else
+ caused_stop = m_gdb_comm.Interrupt();
+ return error;
}
-Error
-ProcessGDBRemote::DoHalt (bool &caused_stop)
-{
- Error error;
-
- bool timed_out = false;
- Mutex::Locker locker;
+Error ProcessGDBRemote::DoDetach(bool keep_stopped) {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
- if (m_public_state.GetValue() == eStateAttaching)
- {
- // We are being asked to halt during an attach. We need to just close
- // our file handle and debugserver will go away, and we can be done...
- m_gdb_comm.Disconnect();
- }
+ error = m_gdb_comm.Detach(keep_stopped);
+ if (log) {
+ if (error.Success())
+ log->PutCString(
+ "ProcessGDBRemote::DoDetach() detach packet sent successfully");
else
- {
- if (!m_gdb_comm.SendInterrupt (locker, 2, timed_out))
- {
- if (timed_out)
- error.SetErrorString("timed out sending interrupt packet");
- else
- error.SetErrorString("unknown error sending interrupt packet");
- }
+ log->Printf("ProcessGDBRemote::DoDetach() detach packet send failed: %s",
+ error.AsCString() ? error.AsCString() : "<unknown error>");
+ }
- caused_stop = m_gdb_comm.GetInterruptWasSent ();
- }
+ if (!error.Success())
return error;
-}
-Error
-ProcessGDBRemote::DoDetach(bool keep_stopped)
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+ // Sleep for one second to let the process get all detached...
+ StopAsyncThread();
- error = m_gdb_comm.Detach (keep_stopped);
- if (log)
- {
- if (error.Success())
- log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
- else
- log->Printf ("ProcessGDBRemote::DoDetach() detach packet send failed: %s", error.AsCString() ? error.AsCString() : "<unknown error>");
- }
-
- if (!error.Success())
- return error;
+ SetPrivateState(eStateDetached);
+ ResumePrivateStateThread();
- // Sleep for one second to let the process get all detached...
- StopAsyncThread ();
-
- SetPrivateState (eStateDetached);
- ResumePrivateStateThread();
-
- //KillDebugserverProcess ();
- return error;
+ // KillDebugserverProcess ();
+ return error;
}
+Error ProcessGDBRemote::DoDestroy() {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy()");
+
+ // There is a bug in older iOS debugservers where they don't shut down the
+ // process
+ // they are debugging properly. If the process is sitting at a breakpoint or
+ // an exception,
+ // this can cause problems with restarting. So we check to see if any of our
+ // threads are stopped
+ // at a breakpoint, and if so we remove all the breakpoints, resume the
+ // process, and THEN
+ // destroy it again.
+ //
+ // Note, we don't have a good way to test the version of debugserver, but I
+ // happen to know that
+ // the set of all the iOS debugservers which don't support
+ // GetThreadSuffixSupported() and that of
+ // the debugservers with this bug are equal. There really should be a better
+ // way to test this!
+ //
+ // We also use m_destroy_tried_resuming to make sure we only do this once, if
+ // we resume and then halt and
+ // get called here to destroy again and we're still at a breakpoint or
+ // exception, then we should
+ // just do the straight-forward kill.
+ //
+ // And of course, if we weren't able to stop the process by the time we get
+ // here, it isn't
+ // necessary (or helpful) to do any of this.
+
+ if (!m_gdb_comm.GetThreadSuffixSupported() &&
+ m_public_state.GetValue() != eStateRunning) {
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+
+ // FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
+ if (platform_sp && platform_sp->GetName() &&
+ platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic()) {
+ if (m_destroy_tried_resuming) {
+ if (log)
+ log->PutCString("ProcessGDBRemote::DoDestroy() - Tried resuming to "
+ "destroy once already, not doing it again.");
+ } else {
+ // At present, the plans are discarded and the breakpoints disabled
+ // Process::Destroy,
+ // but we really need it to happen here and it doesn't matter if we do
+ // it twice.
+ m_thread_list.DiscardThreadPlans();
+ DisableAllBreakpointSites();
+
+ bool stop_looks_like_crash = false;
+ ThreadList &threads = GetThreadList();
-Error
-ProcessGDBRemote::DoDestroy ()
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy()");
-
- // There is a bug in older iOS debugservers where they don't shut down the process
- // they are debugging properly. If the process is sitting at a breakpoint or an exception,
- // this can cause problems with restarting. So we check to see if any of our threads are stopped
- // at a breakpoint, and if so we remove all the breakpoints, resume the process, and THEN
- // destroy it again.
- //
- // Note, we don't have a good way to test the version of debugserver, but I happen to know that
- // the set of all the iOS debugservers which don't support GetThreadSuffixSupported() and that of
- // the debugservers with this bug are equal. There really should be a better way to test this!
- //
- // We also use m_destroy_tried_resuming to make sure we only do this once, if we resume and then halt and
- // get called here to destroy again and we're still at a breakpoint or exception, then we should
- // just do the straight-forward kill.
- //
- // And of course, if we weren't able to stop the process by the time we get here, it isn't
- // necessary (or helpful) to do any of this.
-
- if (!m_gdb_comm.GetThreadSuffixSupported() && m_public_state.GetValue() != eStateRunning)
- {
- PlatformSP platform_sp = GetTarget().GetPlatform();
-
- // FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
- if (platform_sp
- && platform_sp->GetName()
- && platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic())
{
- if (m_destroy_tried_resuming)
- {
- if (log)
- log->PutCString ("ProcessGDBRemote::DoDestroy() - Tried resuming to destroy once already, not doing it again.");
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+
+ size_t num_threads = threads.GetSize();
+ for (size_t i = 0; i < num_threads; i++) {
+ ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
+ StopReason reason = eStopReasonInvalid;
+ if (stop_info_sp)
+ reason = stop_info_sp->GetStopReason();
+ if (reason == eStopReasonBreakpoint ||
+ reason == eStopReasonException) {
+ if (log)
+ log->Printf(
+ "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
+ " stopped with reason: %s.",
+ thread_sp->GetProtocolID(), stop_info_sp->GetDescription());
+ stop_looks_like_crash = true;
+ break;
}
- else
- {
- // At present, the plans are discarded and the breakpoints disabled Process::Destroy,
- // but we really need it to happen here and it doesn't matter if we do it twice.
- m_thread_list.DiscardThreadPlans();
- DisableAllBreakpointSites();
-
- bool stop_looks_like_crash = false;
- ThreadList &threads = GetThreadList();
-
- {
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
- size_t num_threads = threads.GetSize();
- for (size_t i = 0; i < num_threads; i++)
- {
- ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
- StopReason reason = eStopReasonInvalid;
- if (stop_info_sp)
- reason = stop_info_sp->GetStopReason();
- if (reason == eStopReasonBreakpoint
- || reason == eStopReasonException)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 " stopped with reason: %s.",
- thread_sp->GetProtocolID(),
- stop_info_sp->GetDescription());
- stop_looks_like_crash = true;
- break;
- }
- }
- }
+ }
+ }
- if (stop_looks_like_crash)
- {
- if (log)
- log->PutCString ("ProcessGDBRemote::DoDestroy() - Stopped at a breakpoint, continue and then kill.");
- m_destroy_tried_resuming = true;
-
- // If we are going to run again before killing, it would be good to suspend all the threads
- // before resuming so they won't get into more trouble. Sadly, for the threads stopped with
- // the breakpoint or exception, the exception doesn't get cleared if it is suspended, so we do
- // have to run the risk of letting those threads proceed a bit.
-
- {
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
- size_t num_threads = threads.GetSize();
- for (size_t i = 0; i < num_threads; i++)
- {
- ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
- StopReason reason = eStopReasonInvalid;
- if (stop_info_sp)
- reason = stop_info_sp->GetStopReason();
- if (reason != eStopReasonBreakpoint
- && reason != eStopReasonException)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: 0x%4.4" PRIx64 " before running.",
- thread_sp->GetProtocolID());
- thread_sp->SetResumeState(eStateSuspended);
- }
- }
- }
- Resume ();
- return Destroy(false);
- }
+ if (stop_looks_like_crash) {
+ if (log)
+ log->PutCString("ProcessGDBRemote::DoDestroy() - Stopped at a "
+ "breakpoint, continue and then kill.");
+ m_destroy_tried_resuming = true;
+
+ // If we are going to run again before killing, it would be good to
+ // suspend all the threads
+ // before resuming so they won't get into more trouble. Sadly, for
+ // the threads stopped with
+ // the breakpoint or exception, the exception doesn't get cleared if
+ // it is suspended, so we do
+ // have to run the risk of letting those threads proceed a bit.
+
+ {
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+
+ size_t num_threads = threads.GetSize();
+ for (size_t i = 0; i < num_threads; i++) {
+ ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
+ StopReason reason = eStopReasonInvalid;
+ if (stop_info_sp)
+ reason = stop_info_sp->GetStopReason();
+ if (reason != eStopReasonBreakpoint &&
+ reason != eStopReasonException) {
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy() - Suspending "
+ "thread: 0x%4.4" PRIx64 " before running.",
+ thread_sp->GetProtocolID());
+ thread_sp->SetResumeState(eStateSuspended);
+ }
}
+ }
+ Resume();
+ return Destroy(false);
}
+ }
}
+ }
- // Interrupt if our inferior is running...
- int exit_status = SIGABRT;
- std::string exit_string;
+ // Interrupt if our inferior is running...
+ int exit_status = SIGABRT;
+ std::string exit_string;
- if (m_gdb_comm.IsConnected())
- {
- if (m_public_state.GetValue() != eStateAttaching)
- {
- StringExtractorGDBRemote response;
- bool send_async = true;
- GDBRemoteCommunication::ScopedTimeout (m_gdb_comm, 3);
+ if (m_gdb_comm.IsConnected()) {
+ if (m_public_state.GetValue() != eStateAttaching) {
+ StringExtractorGDBRemote response;
+ bool send_async = true;
+ GDBRemoteCommunication::ScopedTimeout(m_gdb_comm,
+ std::chrono::seconds(3));
- if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async) == GDBRemoteCommunication::PacketResult::Success)
- {
- char packet_cmd = response.GetChar(0);
+ if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, send_async) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ char packet_cmd = response.GetChar(0);
- if (packet_cmd == 'W' || packet_cmd == 'X')
- {
+ if (packet_cmd == 'W' || packet_cmd == 'X') {
#if defined(__APPLE__)
- // For Native processes on Mac OS X, we launch through the Host Platform, then hand the process off
- // to debugserver, which becomes the parent process through "PT_ATTACH". Then when we go to kill
- // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then we call waitpid which returns
- // with no error and the correct status. But amusingly enough that doesn't seem to actually reap
- // the process, but instead it is left around as a Zombie. Probably the kernel is in the process of
- // switching ownership back to lldb which was the original parent, and gets confused in the handoff.
- // Anyway, so call waitpid here to finally reap it.
- PlatformSP platform_sp(GetTarget().GetPlatform());
- if (platform_sp && platform_sp->IsHost())
- {
- int status;
- ::pid_t reap_pid;
- reap_pid = waitpid (GetID(), &status, WNOHANG);
- if (log)
- log->Printf ("Reaped pid: %d, status: %d.\n", reap_pid, status);
- }
-#endif
- SetLastStopPacket (response);
- ClearThreadIDList ();
- exit_status = response.GetHexU8();
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy - got unexpected response to k packet: %s", response.GetStringRef().c_str());
- exit_string.assign("got unexpected response to k packet: ");
- exit_string.append(response.GetStringRef());
- }
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy - failed to send k packet");
- exit_string.assign("failed to send the k packet");
- }
- }
- else
- {
+ // For Native processes on Mac OS X, we launch through the Host
+ // Platform, then hand the process off
+ // to debugserver, which becomes the parent process through
+ // "PT_ATTACH". Then when we go to kill
+ // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then we
+ // call waitpid which returns
+ // with no error and the correct status. But amusingly enough that
+ // doesn't seem to actually reap
+ // the process, but instead it is left around as a Zombie. Probably
+ // the kernel is in the process of
+ // switching ownership back to lldb which was the original parent, and
+ // gets confused in the handoff.
+ // Anyway, so call waitpid here to finally reap it.
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ if (platform_sp && platform_sp->IsHost()) {
+ int status;
+ ::pid_t reap_pid;
+ reap_pid = waitpid(GetID(), &status, WNOHANG);
if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy - killed or interrupted while attaching");
- exit_string.assign ("killed or interrupted while attaching.");
+ log->Printf("Reaped pid: %d, status: %d.\n", reap_pid, status);
+ }
+#endif
+ SetLastStopPacket(response);
+ ClearThreadIDList();
+ exit_status = response.GetHexU8();
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy - got unexpected response "
+ "to k packet: %s",
+ response.GetStringRef().c_str());
+ exit_string.assign("got unexpected response to k packet: ");
+ exit_string.append(response.GetStringRef());
}
- }
- else
- {
- // If we missed setting the exit status on the way out, do it here.
- // NB set exit status can be called multiple times, the first one sets the status.
- exit_string.assign("destroying when not connected to debugserver");
- }
-
- SetExitStatus(exit_status, exit_string.c_str());
-
- StopAsyncThread ();
- KillDebugserverProcess ();
- return error;
-}
-
-void
-ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
-{
- const bool did_exec = response.GetStringRef().find(";reason:exec;") != std::string::npos;
- if (did_exec)
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ } else {
if (log)
- log->Printf ("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+ log->Printf("ProcessGDBRemote::DoDestroy - failed to send k packet");
+ exit_string.assign("failed to send the k packet");
+ }
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy - killed or interrupted while "
+ "attaching");
+ exit_string.assign("killed or interrupted while attaching.");
+ }
+ } else {
+ // If we missed setting the exit status on the way out, do it here.
+ // NB set exit status can be called multiple times, the first one sets the
+ // status.
+ exit_string.assign("destroying when not connected to debugserver");
+ }
+
+ SetExitStatus(exit_status, exit_string.c_str());
+
+ StopAsyncThread();
+ KillDebugserverProcess();
+ return error;
+}
- m_thread_list_real.Clear();
- m_thread_list.Clear();
- BuildDynamicRegisterInfo (true);
- m_gdb_comm.ResetDiscoverableSettings (did_exec);
- }
+void ProcessGDBRemote::SetLastStopPacket(
+ const StringExtractorGDBRemote &response) {
+ const bool did_exec =
+ response.GetStringRef().find(";reason:exec;") != std::string::npos;
+ if (did_exec) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::SetLastStopPacket () - detected exec");
- // Scope the lock
- {
- // Lock the thread stack while we access it
- std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
-
- // 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)
- m_stop_packet_stack.clear();
-
- // Add this stop packet to the stop packet stack
- // This stack will get popped and examined when we switch to the
- // Stopped state
- m_stop_packet_stack.push_back(response);
- }
+ m_thread_list_real.Clear();
+ m_thread_list.Clear();
+ BuildDynamicRegisterInfo(true);
+ m_gdb_comm.ResetDiscoverableSettings(did_exec);
+ }
+
+ // Scope the lock
+ {
+ // Lock the thread stack while we access it
+ std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
+
+ // 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)
+ m_stop_packet_stack.clear();
+
+ // Add this stop packet to the stop packet stack
+ // This stack will get popped and examined when we switch to the
+ // Stopped state
+ m_stop_packet_stack.push_back(response);
+ }
}
-void
-ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp)
-{
- Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));
+void ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp) {
+ Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));
}
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessGDBRemote::IsAlive ()
-{
- return m_gdb_comm.IsConnected() && Process::IsAlive();
+bool ProcessGDBRemote::IsAlive() {
+ return m_gdb_comm.IsConnected() && Process::IsAlive();
}
-addr_t
-ProcessGDBRemote::GetImageInfoAddress()
-{
- // request the link map address via the $qShlibInfoAddr packet
- lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();
+addr_t ProcessGDBRemote::GetImageInfoAddress() {
+ // request the link map address via the $qShlibInfoAddr packet
+ lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();
- // the loaded module list can also provides a link map address
- if (addr == LLDB_INVALID_ADDRESS)
- {
- LoadedModuleInfoList list;
- if (GetLoadedModuleList (list).Success())
- addr = list.m_link_map;
- }
+ // the loaded module list can also provides a link map address
+ if (addr == LLDB_INVALID_ADDRESS) {
+ LoadedModuleInfoList list;
+ if (GetLoadedModuleList(list).Success())
+ addr = list.m_link_map;
+ }
- return addr;
+ return addr;
}
-void
-ProcessGDBRemote::WillPublicStop ()
-{
- // See if the GDB remote client supports the JSON threads info.
- // If so, we gather stop info for all threads, expedited registers,
- // expedited memory, runtime queue information (iOS and MacOSX only),
- // and more. Expediting memory will help stack backtracing be much
- // faster. Expediting registers will make sure we don't have to read
- // the thread registers for GPRs.
- m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();
-
- if (m_jthreadsinfo_sp)
- {
- // Now set the stop info for each thread and also expedite any registers
- // and memory that was in the jThreadsInfo response.
- StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
- if (thread_infos)
- {
- const size_t n = thread_infos->GetSize();
- for (size_t i=0; i<n; ++i)
- {
- StructuredData::Dictionary *thread_dict = thread_infos->GetItemAtIndex(i)->GetAsDictionary();
- if (thread_dict)
- SetThreadStopInfo(thread_dict);
- }
- }
- }
+void ProcessGDBRemote::WillPublicStop() {
+ // See if the GDB remote client supports the JSON threads info.
+ // If so, we gather stop info for all threads, expedited registers,
+ // expedited memory, runtime queue information (iOS and MacOSX only),
+ // and more. Expediting memory will help stack backtracing be much
+ // faster. Expediting registers will make sure we don't have to read
+ // the thread registers for GPRs.
+ m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();
+
+ if (m_jthreadsinfo_sp) {
+ // Now set the stop info for each thread and also expedite any registers
+ // and memory that was in the jThreadsInfo response.
+ StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
+ if (thread_infos) {
+ const size_t n = thread_infos->GetSize();
+ for (size_t i = 0; i < n; ++i) {
+ StructuredData::Dictionary *thread_dict =
+ thread_infos->GetItemAtIndex(i)->GetAsDictionary();
+ if (thread_dict)
+ SetThreadStopInfo(thread_dict);
+ }
+ }
+ }
}
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- GetMaxMemorySize ();
- if (size > m_max_memory_size)
- {
- // Keep memory read sizes down to a sane limit. This function will be
- // called multiple times in order to complete the task by
- // lldb_private::Process so it is ok to do this.
- size = m_max_memory_size;
- }
-
- char packet[64];
- int packet_len;
- bool binary_memory_read = m_gdb_comm.GetxPacketSupported();
- packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,
- binary_memory_read ? 'x' : 'm', (uint64_t)addr, (uint64_t)size);
- assert (packet_len + 1 < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- error.Clear();
- if (binary_memory_read)
- {
- // The lower level GDBRemoteCommunication packet receive layer has already de-quoted any
- // 0x7d character escaping that was present in the packet
-
- size_t data_received_size = response.GetBytesLeft();
- if (data_received_size > size)
- {
- // Don't write past the end of BUF if the remote debug server gave us too
- // much data for some reason.
- data_received_size = size;
- }
- memcpy (buf, response.GetStringRef().data(), data_received_size);
- return data_received_size;
- }
- else
- {
- return response.GetHexBytes(buf, size, '\xdd');
- }
+size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ GetMaxMemorySize();
+ if (size > m_max_memory_size) {
+ // Keep memory read sizes down to a sane limit. This function will be
+ // called multiple times in order to complete the task by
+ // lldb_private::Process so it is ok to do this.
+ size = m_max_memory_size;
+ }
+
+ char packet[64];
+ int packet_len;
+ bool binary_memory_read = m_gdb_comm.GetxPacketSupported();
+ packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,
+ binary_memory_read ? 'x' : 'm', (uint64_t)addr,
+ (uint64_t)size);
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ error.Clear();
+ if (binary_memory_read) {
+ // The lower level GDBRemoteCommunication packet receive layer has
+ // already de-quoted any
+ // 0x7d character escaping that was present in the packet
+
+ size_t data_received_size = response.GetBytesLeft();
+ if (data_received_size > size) {
+ // Don't write past the end of BUF if the remote debug server gave us
+ // too
+ // much data for some reason.
+ data_received_size = size;
}
- else if (response.IsErrorResponse())
- error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
- else if (response.IsUnsupportedResponse())
- error.SetErrorStringWithFormat("GDB server does not support reading memory");
- else
- error.SetErrorStringWithFormat("unexpected response to GDB server memory read packet '%s': '%s'", packet, response.GetStringRef().c_str());
- }
+ memcpy(buf, response.GetStringRef().data(), data_received_size);
+ return data_received_size;
+ } else {
+ return response.GetHexBytes(
+ llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size), '\xdd');
+ }
+ } else if (response.IsErrorResponse())
+ error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
+ else if (response.IsUnsupportedResponse())
+ error.SetErrorStringWithFormat(
+ "GDB server does not support reading memory");
else
- {
- error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
- }
- return 0;
+ error.SetErrorStringWithFormat(
+ "unexpected response to GDB server memory read packet '%s': '%s'",
+ packet, response.GetStringRef().c_str());
+ } else {
+ error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
+ }
+ return 0;
}
-size_t
-ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
-{
- GetMaxMemorySize ();
- if (size > m_max_memory_size)
- {
- // Keep memory read sizes down to a sane limit. This function will be
- // called multiple times in order to complete the task by
- // lldb_private::Process so it is ok to do this.
- size = m_max_memory_size;
- }
-
- StreamString packet;
- packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
- packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(), endian::InlHostByteOrder());
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- error.Clear();
- return size;
- }
- else if (response.IsErrorResponse())
- error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64, addr);
- else if (response.IsUnsupportedResponse())
- error.SetErrorStringWithFormat("GDB server does not support writing memory");
- else
- error.SetErrorStringWithFormat("unexpected response to GDB server memory write packet '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
- }
+size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
+ size_t size, Error &error) {
+ GetMaxMemorySize();
+ if (size > m_max_memory_size) {
+ // Keep memory read sizes down to a sane limit. This function will be
+ // called multiple times in order to complete the task by
+ // lldb_private::Process so it is ok to do this.
+ size = m_max_memory_size;
+ }
+
+ StreamString packet;
+ packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
+ packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ error.Clear();
+ return size;
+ } else if (response.IsErrorResponse())
+ error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64,
+ addr);
+ else if (response.IsUnsupportedResponse())
+ error.SetErrorStringWithFormat(
+ "GDB server does not support writing memory");
else
- {
- error.SetErrorStringWithFormat("failed to send packet: '%s'", packet.GetString().c_str());
- }
- return 0;
+ error.SetErrorStringWithFormat(
+ "unexpected response to GDB server memory write packet '%s': '%s'",
+ packet.GetData(), response.GetStringRef().c_str());
+ } else {
+ error.SetErrorStringWithFormat("failed to send packet: '%s'",
+ packet.GetData());
+ }
+ return 0;
}
-lldb::addr_t
-ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_EXPRESSIONS));
- addr_t allocated_addr = LLDB_INVALID_ADDRESS;
-
- if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo)
- {
- allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
- if (allocated_addr != LLDB_INVALID_ADDRESS || m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)
- return allocated_addr;
- }
-
- if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo)
- {
- // Call mmap() to create memory in the inferior..
- unsigned prot = 0;
- if (permissions & lldb::ePermissionsReadable)
- prot |= eMmapProtRead;
- if (permissions & lldb::ePermissionsWritable)
- prot |= eMmapProtWrite;
- if (permissions & lldb::ePermissionsExecutable)
- prot |= eMmapProtExec;
-
- if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
- eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))
- m_addr_to_mmap_size[allocated_addr] = size;
- else
- {
- allocated_addr = LLDB_INVALID_ADDRESS;
- if (log)
- log->Printf ("ProcessGDBRemote::%s no direct stub support for memory allocation, and InferiorCallMmap also failed - is stub missing register context save/restore capability?", __FUNCTION__);
- }
- }
-
- if (allocated_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat("unable to allocate %" PRIu64 " bytes of memory with permissions %s", (uint64_t)size, GetPermissionsAsCString (permissions));
- else
- error.Clear();
- return allocated_addr;
+lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
+ uint32_t permissions,
+ Error &error) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_EXPRESSIONS));
+ addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+
+ if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo) {
+ allocated_addr = m_gdb_comm.AllocateMemory(size, permissions);
+ if (allocated_addr != LLDB_INVALID_ADDRESS ||
+ m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)
+ return allocated_addr;
+ }
+
+ if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo) {
+ // Call mmap() to create memory in the inferior..
+ unsigned prot = 0;
+ if (permissions & lldb::ePermissionsReadable)
+ prot |= eMmapProtRead;
+ if (permissions & lldb::ePermissionsWritable)
+ prot |= eMmapProtWrite;
+ if (permissions & lldb::ePermissionsExecutable)
+ prot |= eMmapProtExec;
+
+ if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
+ eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))
+ m_addr_to_mmap_size[allocated_addr] = size;
+ else {
+ allocated_addr = LLDB_INVALID_ADDRESS;
+ if (log)
+ log->Printf("ProcessGDBRemote::%s no direct stub support for memory "
+ "allocation, and InferiorCallMmap also failed - is stub "
+ "missing register context save/restore capability?",
+ __FUNCTION__);
+ }
+ }
+
+ if (allocated_addr == LLDB_INVALID_ADDRESS)
+ error.SetErrorStringWithFormat(
+ "unable to allocate %" PRIu64 " bytes of memory with permissions %s",
+ (uint64_t)size, GetPermissionsAsCString(permissions));
+ else
+ error.Clear();
+ return allocated_addr;
}
-Error
-ProcessGDBRemote::GetMemoryRegionInfo (addr_t load_addr,
- MemoryRegionInfo &region_info)
-{
+Error ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
- Error error (m_gdb_comm.GetMemoryRegionInfo (load_addr, region_info));
- return error;
+ Error error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));
+ return error;
}
-Error
-ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num)
-{
+Error ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num) {
- Error error (m_gdb_comm.GetWatchpointSupportInfo (num));
- return error;
+ Error error(m_gdb_comm.GetWatchpointSupportInfo(num));
+ return error;
}
-Error
-ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num, bool& after)
-{
- Error error (m_gdb_comm.GetWatchpointSupportInfo (num, after, GetTarget().GetArchitecture()));
- return error;
+Error ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+ Error error(m_gdb_comm.GetWatchpointSupportInfo(
+ num, after, GetTarget().GetArchitecture()));
+ return error;
}
-Error
-ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
-{
- Error error;
- LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
-
- switch (supported)
- {
- case eLazyBoolCalculate:
- // We should never be deallocating memory without allocating memory
- // first so we should never get eLazyBoolCalculate
- error.SetErrorString ("tried to deallocate memory without ever allocating memory");
- break;
-
- case eLazyBoolYes:
- if (!m_gdb_comm.DeallocateMemory (addr))
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
- break;
-
- case eLazyBoolNo:
- // Call munmap() to deallocate memory in the inferior..
- {
- MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
- if (pos != m_addr_to_mmap_size.end() &&
- InferiorCallMunmap(this, addr, pos->second))
- m_addr_to_mmap_size.erase (pos);
- else
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
- }
- break;
- }
-
- return error;
+Error ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
+
+ switch (supported) {
+ case eLazyBoolCalculate:
+ // We should never be deallocating memory without allocating memory
+ // first so we should never get eLazyBoolCalculate
+ error.SetErrorString(
+ "tried to deallocate memory without ever allocating memory");
+ break;
+
+ case eLazyBoolYes:
+ if (!m_gdb_comm.DeallocateMemory(addr))
+ error.SetErrorStringWithFormat(
+ "unable to deallocate memory at 0x%" PRIx64, addr);
+ break;
+
+ case eLazyBoolNo:
+ // Call munmap() to deallocate memory in the inferior..
+ {
+ MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
+ if (pos != m_addr_to_mmap_size.end() &&
+ InferiorCallMunmap(this, addr, pos->second))
+ m_addr_to_mmap_size.erase(pos);
+ else
+ error.SetErrorStringWithFormat(
+ "unable to deallocate memory at 0x%" PRIx64, addr);
+ }
+ break;
+ }
+
+ return error;
}
-
//------------------------------------------------------------------
// Process STDIO
//------------------------------------------------------------------
-size_t
-ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
-{
- if (m_stdio_communication.IsConnected())
- {
- ConnectionStatus status;
- m_stdio_communication.Write(src, src_len, status, NULL);
- }
- else if (m_stdin_forward)
- {
- m_gdb_comm.SendStdinNotification(src, src_len);
- }
- return 0;
+size_t ProcessGDBRemote::PutSTDIN(const char *src, size_t src_len,
+ Error &error) {
+ if (m_stdio_communication.IsConnected()) {
+ ConnectionStatus status;
+ m_stdio_communication.Write(src, src_len, status, NULL);
+ } else if (m_stdin_forward) {
+ m_gdb_comm.SendStdinNotification(src, src_len);
+ }
+ return 0;
}
-Error
-ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
-{
- Error error;
- assert(bp_site != NULL);
-
- // Get logging info
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
- user_id_t site_id = bp_site->GetID();
-
- // Get the breakpoint address
- const addr_t addr = bp_site->GetLoadAddress();
-
- // Log that a breakpoint was requested
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64, site_id, (uint64_t)addr);
-
- // Breakpoint already exists and is enabled
- if (bp_site->IsEnabled())
- {
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
- return error;
- }
+Error ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
+ Error error;
+ assert(bp_site != NULL);
- // Get the software breakpoint trap opcode size
- const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
+ // Get logging info
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ user_id_t site_id = bp_site->GetID();
- // SupportsGDBStoppointPacket() simply checks a boolean, indicating if this breakpoint type
- // is supported by the remote stub. These are set to true by default, and later set to false
- // only after we receive an unimplemented response when sending a breakpoint packet. This means
- // initially that unless we were specifically instructed to use a hardware breakpoint, LLDB will
- // attempt to set a software breakpoint. HardwareRequired() also queries a boolean variable which
- // indicates if the user specifically asked for hardware breakpoints. If true then we will
- // skip over software breakpoints.
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) && (!bp_site->HardwareRequired()))
- {
- // Try to send off a software breakpoint packet ($Z0)
- uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size);
- if (error_no == 0)
- {
- // The breakpoint was placed successfully
- bp_site->SetEnabled(true);
- bp_site->SetType(BreakpointSite::eExternal);
- return error;
- }
+ // Get the breakpoint address
+ const addr_t addr = bp_site->GetLoadAddress();
- // SendGDBStoppointTypePacket() will return an error if it was unable to set this
- // breakpoint. We need to differentiate between a error specific to placing this breakpoint
- // or if we have learned that this breakpoint type is unsupported. To do this, we
- // must test the support boolean for this breakpoint type to see if it now indicates that
- // this breakpoint type is unsupported. If they are still supported then we should return
- // with the error code. If they are now unsupported, then we would like to fall through
- // and try another form of breakpoint.
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
- {
- if (error_no != UINT8_MAX)
- error.SetErrorStringWithFormat("error: %d sending the breakpoint request", errno);
- else
- error.SetErrorString("error sending the breakpoint request");
- return error;
- }
-
- // We reach here when software breakpoints have been found to be unsupported. For future
- // calls to set a breakpoint, we will not attempt to set a breakpoint with a type that is
- // known not to be supported.
- if (log)
- log->Printf("Software breakpoints are unsupported");
-
- // So we will fall through and try a hardware breakpoint
- }
-
- // The process of setting a hardware breakpoint is much the same as above. We check the
- // supported boolean for this breakpoint type, and if it is thought to be supported then we
- // will try to set this breakpoint with a hardware breakpoint.
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
- {
- // Try to send off a hardware breakpoint packet ($Z1)
- uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size);
- if (error_no == 0)
- {
- // The breakpoint was placed successfully
- bp_site->SetEnabled(true);
- bp_site->SetType(BreakpointSite::eHardware);
- return error;
- }
-
- // Check if the error was something other then an unsupported breakpoint type
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
- {
- // Unable to set this hardware breakpoint
- if (error_no != UINT8_MAX)
- error.SetErrorStringWithFormat("error: %d sending the hardware breakpoint request "
- "(hardware breakpoint resources might be exhausted or unavailable)",
- error_no);
- else
- error.SetErrorString("error sending the hardware breakpoint request (hardware breakpoint resources "
- "might be exhausted or unavailable)");
- return error;
- }
+ // Log that a breakpoint was requested
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64,
+ site_id, (uint64_t)addr);
- // We will reach here when the stub gives an unsupported response to a hardware breakpoint
- if (log)
- log->Printf("Hardware breakpoints are unsupported");
+ // Breakpoint already exists and is enabled
+ if (bp_site->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",
+ site_id, (uint64_t)addr);
+ return error;
+ }
+
+ // Get the software breakpoint trap opcode size
+ const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
+
+ // SupportsGDBStoppointPacket() simply checks a boolean, indicating if this
+ // breakpoint type
+ // is supported by the remote stub. These are set to true by default, and
+ // later set to false
+ // only after we receive an unimplemented response when sending a breakpoint
+ // packet. This means
+ // initially that unless we were specifically instructed to use a hardware
+ // breakpoint, LLDB will
+ // attempt to set a software breakpoint. HardwareRequired() also queries a
+ // boolean variable which
+ // indicates if the user specifically asked for hardware breakpoints. If true
+ // then we will
+ // skip over software breakpoints.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) &&
+ (!bp_site->HardwareRequired())) {
+ // Try to send off a software breakpoint packet ($Z0)
+ uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
+ eBreakpointSoftware, true, addr, bp_op_size);
+ if (error_no == 0) {
+ // The breakpoint was placed successfully
+ bp_site->SetEnabled(true);
+ bp_site->SetType(BreakpointSite::eExternal);
+ return error;
+ }
+
+ // SendGDBStoppointTypePacket() will return an error if it was unable to set
+ // this
+ // breakpoint. We need to differentiate between a error specific to placing
+ // this breakpoint
+ // or if we have learned that this breakpoint type is unsupported. To do
+ // this, we
+ // must test the support boolean for this breakpoint type to see if it now
+ // indicates that
+ // this breakpoint type is unsupported. If they are still supported then we
+ // should return
+ // with the error code. If they are now unsupported, then we would like to
+ // fall through
+ // and try another form of breakpoint.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) {
+ if (error_no != UINT8_MAX)
+ error.SetErrorStringWithFormat(
+ "error: %d sending the breakpoint request", errno);
+ else
+ error.SetErrorString("error sending the breakpoint request");
+ return error;
+ }
+
+ // We reach here when software breakpoints have been found to be
+ // unsupported. For future
+ // calls to set a breakpoint, we will not attempt to set a breakpoint with a
+ // type that is
+ // known not to be supported.
+ if (log)
+ log->Printf("Software breakpoints are unsupported");
+
+ // So we will fall through and try a hardware breakpoint
+ }
+
+ // The process of setting a hardware breakpoint is much the same as above. We
+ // check the
+ // supported boolean for this breakpoint type, and if it is thought to be
+ // supported then we
+ // will try to set this breakpoint with a hardware breakpoint.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
+ // Try to send off a hardware breakpoint packet ($Z1)
+ uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
+ eBreakpointHardware, true, addr, bp_op_size);
+ if (error_no == 0) {
+ // The breakpoint was placed successfully
+ bp_site->SetEnabled(true);
+ bp_site->SetType(BreakpointSite::eHardware);
+ return error;
+ }
+
+ // Check if the error was something other then an unsupported breakpoint
+ // type
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
+ // Unable to set this hardware breakpoint
+ if (error_no != UINT8_MAX)
+ error.SetErrorStringWithFormat(
+ "error: %d sending the hardware breakpoint request "
+ "(hardware breakpoint resources might be exhausted or unavailable)",
+ error_no);
+ else
+ error.SetErrorString("error sending the hardware breakpoint request "
+ "(hardware breakpoint resources "
+ "might be exhausted or unavailable)");
+ return error;
+ }
+
+ // We will reach here when the stub gives an unsupported response to a
+ // hardware breakpoint
+ if (log)
+ log->Printf("Hardware breakpoints are unsupported");
- // Finally we will falling through to a #trap style breakpoint
- }
+ // Finally we will falling through to a #trap style breakpoint
+ }
- // Don't fall through when hardware breakpoints were specifically requested
- if (bp_site->HardwareRequired())
- {
- error.SetErrorString("hardware breakpoints are not supported");
- return error;
- }
+ // Don't fall through when hardware breakpoints were specifically requested
+ if (bp_site->HardwareRequired()) {
+ error.SetErrorString("hardware breakpoints are not supported");
+ return error;
+ }
- // As a last resort we want to place a manual breakpoint. An instruction
- // is placed into the process memory using memory write packets.
- return EnableSoftwareBreakpoint(bp_site);
+ // As a last resort we want to place a manual breakpoint. An instruction
+ // is placed into the process memory using memory write packets.
+ return EnableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessGDBRemote::DisableBreakpointSite (BreakpointSite *bp_site)
-{
- Error error;
- assert (bp_site != NULL);
- addr_t addr = bp_site->GetLoadAddress();
- user_id_t site_id = bp_site->GetID();
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64, site_id, (uint64_t)addr);
-
- if (bp_site->IsEnabled())
- {
- const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
+Error ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
+ Error error;
+ assert(bp_site != NULL);
+ addr_t addr = bp_site->GetLoadAddress();
+ user_id_t site_id = bp_site->GetID();
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ site_id, (uint64_t)addr);
+
+ if (bp_site->IsEnabled()) {
+ const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
- BreakpointSite::Type bp_type = bp_site->GetType();
- switch (bp_type)
- {
- case BreakpointSite::eSoftware:
- error = DisableSoftwareBreakpoint (bp_site);
- break;
+ BreakpointSite::Type bp_type = bp_site->GetType();
+ switch (bp_type) {
+ case BreakpointSite::eSoftware:
+ error = DisableSoftwareBreakpoint(bp_site);
+ break;
- case BreakpointSite::eHardware:
- if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false, addr, bp_op_size))
- error.SetErrorToGenericError();
- break;
+ case BreakpointSite::eHardware:
+ if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false,
+ addr, bp_op_size))
+ error.SetErrorToGenericError();
+ break;
- case BreakpointSite::eExternal:
- {
- GDBStoppointType stoppoint_type;
- if (bp_site->IsHardware())
- stoppoint_type = eBreakpointHardware;
- else
- stoppoint_type = eBreakpointSoftware;
+ case BreakpointSite::eExternal: {
+ GDBStoppointType stoppoint_type;
+ if (bp_site->IsHardware())
+ stoppoint_type = eBreakpointHardware;
+ else
+ stoppoint_type = eBreakpointSoftware;
- if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr, bp_op_size))
- error.SetErrorToGenericError();
- }
- break;
- }
- if (error.Success())
- bp_site->SetEnabled(false);
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
- return error;
+ if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr,
+ bp_op_size))
+ error.SetErrorToGenericError();
+ } break;
}
-
if (error.Success())
- error.SetErrorToGenericError();
+ bp_site->SetEnabled(false);
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+ site_id, (uint64_t)addr);
return error;
+ }
+
+ if (error.Success())
+ error.SetErrorToGenericError();
+ return error;
}
// Pre-requisite: wp != NULL.
-static GDBStoppointType
-GetGDBStoppointType (Watchpoint *wp)
-{
- assert(wp);
- bool watch_read = wp->WatchpointRead();
- bool watch_write = wp->WatchpointWrite();
-
- // watch_read and watch_write cannot both be false.
- assert(watch_read || watch_write);
- if (watch_read && watch_write)
- return eWatchpointReadWrite;
- else if (watch_read)
- return eWatchpointRead;
- else // Must be watch_write, then.
- return eWatchpointWrite;
+static GDBStoppointType GetGDBStoppointType(Watchpoint *wp) {
+ assert(wp);
+ bool watch_read = wp->WatchpointRead();
+ bool watch_write = wp->WatchpointWrite();
+
+ // watch_read and watch_write cannot both be false.
+ assert(watch_read || watch_write);
+ if (watch_read && watch_write)
+ return eWatchpointReadWrite;
+ else if (watch_read)
+ return eWatchpointRead;
+ else // Must be watch_write, then.
+ return eWatchpointWrite;
}
-Error
-ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", watchID);
- if (wp->IsEnabled())
- {
- if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", watchID, (uint64_t)addr);
- return error;
- }
-
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SupportsGDBStoppointPacket (type))
- {
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, wp->GetByteSize()) == 0)
- {
- wp->SetEnabled(true, notify);
- return error;
- }
- else
- error.SetErrorString("sending gdb watchpoint packet failed");
- }
- else
- error.SetErrorString("watchpoints not supported");
- }
- else
- {
- error.SetErrorString("Watchpoint argument was NULL.");
- }
- if (error.Success())
- error.SetErrorToGenericError();
- return error;
+Error ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
+ addr_t addr = wp->GetLoadAddress();
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
+ return error;
+ }
+
+ GDBStoppointType type = GetGDBStoppointType(wp);
+ // Pass down an appropriate z/Z packet...
+ if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
+ if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
+ wp->GetByteSize()) == 0) {
+ wp->SetEnabled(true, notify);
+ return error;
+ } else
+ error.SetErrorString("sending gdb watchpoint packet failed");
+ } else
+ error.SetErrorString("watchpoints not supported");
+ } else {
+ error.SetErrorString("Watchpoint argument was NULL.");
+ }
+ if (error.Success())
+ error.SetErrorToGenericError();
+ return error;
}
-Error
-ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
-
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+Error ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64, watchID, (uint64_t)addr);
-
- if (!wp->IsEnabled())
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
- // See also 'class WatchpointSentry' within StopInfo.cpp.
- // This disabling attempt might come from the user-supplied actions, we'll route it in order for
- // the watchpoint object to intelligently process this action.
- wp->SetEnabled(false, notify);
- return error;
- }
+ addr_t addr = wp->GetLoadAddress();
- if (wp->IsHardware())
- {
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, wp->GetByteSize()) == 0)
- {
- wp->SetEnabled(false, notify);
- return error;
- }
- else
- error.SetErrorString("sending gdb watchpoint packet failed");
- }
- // TODO: clear software watchpoints if we implement them
- }
- else
- {
- error.SetErrorString("Watchpoint argument was NULL.");
- }
- if (error.Success())
- error.SetErrorToGenericError();
- return error;
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ watchID, (uint64_t)addr);
+
+ if (!wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+ watchID, (uint64_t)addr);
+ // See also 'class WatchpointSentry' within StopInfo.cpp.
+ // This disabling attempt might come from the user-supplied actions, we'll
+ // route it in order for
+ // the watchpoint object to intelligently process this action.
+ wp->SetEnabled(false, notify);
+ return error;
+ }
+
+ if (wp->IsHardware()) {
+ GDBStoppointType type = GetGDBStoppointType(wp);
+ // Pass down an appropriate z/Z packet...
+ if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
+ wp->GetByteSize()) == 0) {
+ wp->SetEnabled(false, notify);
+ return error;
+ } else
+ error.SetErrorString("sending gdb watchpoint packet failed");
+ }
+ // TODO: clear software watchpoints if we implement them
+ } else {
+ error.SetErrorString("Watchpoint argument was NULL.");
+ }
+ if (error.Success())
+ error.SetErrorToGenericError();
+ return error;
}
-void
-ProcessGDBRemote::Clear()
-{
- m_flags = 0;
- m_thread_list_real.Clear();
- m_thread_list.Clear();
+void ProcessGDBRemote::Clear() {
+ m_flags = 0;
+ m_thread_list_real.Clear();
+ m_thread_list.Clear();
}
-Error
-ProcessGDBRemote::DoSignal (int signo)
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
+Error ProcessGDBRemote::DoSignal(int signo) {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DoSignal (signal = %d)", signo);
- if (!m_gdb_comm.SendAsyncSignal (signo))
- error.SetErrorStringWithFormat("failed to send signal %i", signo);
- return error;
+ if (!m_gdb_comm.SendAsyncSignal(signo))
+ error.SetErrorStringWithFormat("failed to send signal %i", signo);
+ return error;
}
-Error
-ProcessGDBRemote::EstablishConnectionIfNeeded (const ProcessInfo &process_info)
-{
- // Make sure we aren't already connected?
- if (m_gdb_comm.IsConnected())
- return Error();
-
- PlatformSP platform_sp (GetTarget ().GetPlatform ());
- if (platform_sp && !platform_sp->IsHost ())
- return Error("Lost debug server connection");
+Error ProcessGDBRemote::EstablishConnectionIfNeeded(
+ const ProcessInfo &process_info) {
+ // Make sure we aren't already connected?
+ if (m_gdb_comm.IsConnected())
+ return Error();
- auto error = LaunchAndConnectToDebugserver (process_info);
- if (error.Fail())
- {
- const char *error_string = error.AsCString();
- if (error_string == nullptr)
- error_string = "unable to launch " DEBUGSERVER_BASENAME;
- }
- return error;
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ if (platform_sp && !platform_sp->IsHost())
+ return Error("Lost debug server connection");
+
+ auto error = LaunchAndConnectToDebugserver(process_info);
+ if (error.Fail()) {
+ const char *error_string = error.AsCString();
+ if (error_string == nullptr)
+ error_string = "unable to launch " DEBUGSERVER_BASENAME;
+ }
+ return error;
}
+#if defined(__APPLE__)
+#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1
+#endif
-Error
-ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
-{
- using namespace std::placeholders; // For _1, _2, etc.
-
- Error error;
- if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
- {
- // If we locate debugserver, keep that located version around
- static FileSpec g_debugserver_file_spec;
-
- ProcessLaunchInfo debugserver_launch_info;
- // Make debugserver run in its own session so signals generated by
- // special terminal key sequences (^C) don't affect debugserver.
- debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
-
- const std::weak_ptr<ProcessGDBRemote> this_wp = std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
- debugserver_launch_info.SetMonitorProcessCallback(std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4),
- false);
- debugserver_launch_info.SetUserID(process_info.GetUserID());
-
-#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
- // On iOS, still do a local connection using a random port
- const char *hostname = "127.0.0.1";
- uint16_t port = get_random_port ();
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+static bool SetCloexecFlag(int fd) {
+#if defined(FD_CLOEXEC)
+ int flags = ::fcntl(fd, F_GETFD);
+ if (flags == -1)
+ return false;
+ return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);
#else
- // Set hostname being NULL to do the reverse connect where debugserver
- // will bind to port zero and it will communicate back to us the port
- // that we will connect to
- const char *hostname = nullptr;
- uint16_t port = 0;
+ return false;
+#endif
+}
#endif
- StreamString url_str;
- const char* url = nullptr;
- if (hostname != nullptr)
- {
- url_str.Printf("%s:%u", hostname, port);
- url = url_str.GetData();
- }
+Error ProcessGDBRemote::LaunchAndConnectToDebugserver(
+ const ProcessInfo &process_info) {
+ using namespace std::placeholders; // For _1, _2, etc.
+
+ Error error;
+ if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) {
+ // If we locate debugserver, keep that located version around
+ static FileSpec g_debugserver_file_spec;
+
+ ProcessLaunchInfo debugserver_launch_info;
+ // Make debugserver run in its own session so signals generated by
+ // special terminal key sequences (^C) don't affect debugserver.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
+
+ const std::weak_ptr<ProcessGDBRemote> this_wp =
+ std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
+ debugserver_launch_info.SetMonitorProcessCallback(
+ std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false);
+ debugserver_launch_info.SetUserID(process_info.GetUserID());
+
+ int communication_fd = -1;
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+ // Auto close the sockets we might open up unless everything goes OK. This
+ // helps us not leak file descriptors when things go wrong.
+ lldb_utility::CleanUp<int, int> our_socket(-1, -1, close);
+ lldb_utility::CleanUp<int, int> gdb_socket(-1, -1, close);
+
+ // Use a socketpair on Apple for now until other platforms can verify it
+ // works and is fast enough
+ {
+ int sockets[2]; /* the pair of socket descriptors */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
- error = m_gdb_comm.StartDebugserverProcess (url,
- GetTarget().GetPlatform().get(),
- debugserver_launch_info,
- &port);
+ our_socket.set(sockets[0]);
+ gdb_socket.set(sockets[1]);
+ }
- if (error.Success ())
- m_debugserver_pid = debugserver_launch_info.GetProcessID();
- else
- m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ // Don't let any child processes inherit our communication socket
+ SetCloexecFlag(our_socket.get());
+ communication_fd = gdb_socket.get();
+#endif
- if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
- StartAsyncThread ();
+ error = m_gdb_comm.StartDebugserverProcess(
+ nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info,
+ nullptr, nullptr, communication_fd);
- if (error.Fail())
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ if (error.Success())
+ m_debugserver_pid = debugserver_launch_info.GetProcessID();
+ else
+ m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+
+ if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+ // Our process spawned correctly, we can now set our connection to use our
+ // end of the socket pair
+ m_gdb_comm.SetConnection(
+ new ConnectionFileDescriptor(our_socket.release(), true));
+#endif
+ StartAsyncThread();
+ }
- if (log)
- log->Printf("failed to start debugserver process: %s", error.AsCString());
- return error;
- }
+ if (error.Fail()) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (m_gdb_comm.IsConnected())
- {
- // Finish the connection process by doing the handshake without connecting (send NULL URL)
- ConnectToDebugserver (NULL);
- }
- else
- {
- StreamString connect_url;
- connect_url.Printf("connect://%s:%u", hostname, port);
- error = ConnectToDebugserver (connect_url.GetString().c_str());
- }
+ if (log)
+ log->Printf("failed to start debugserver process: %s",
+ error.AsCString());
+ return error;
+ }
+ if (m_gdb_comm.IsConnected()) {
+ // Finish the connection process by doing the handshake without connecting
+ // (send NULL URL)
+ ConnectToDebugserver("");
+ } else {
+ error.SetErrorString("connection failed");
}
- return error;
+ }
+ return error;
}
-bool
-ProcessGDBRemote::MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
- 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));
- const bool handled = true;
-
- if (log)
- log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64 ", signo=%i (0x%x), exit_status=%i)", __FUNCTION__,
- debugserver_pid, signo, signo, exit_status);
-
- std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
- if (log)
- log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__, static_cast<void *>(process_sp.get()));
- if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
- return handled;
-
- // Sleep for a half a second to make sure our inferior process has
- // time to set its exit status before we set it incorrectly when
- // both the debugserver and the inferior process shut down.
- usleep(500000);
- // If our process hasn't yet exited, debugserver might have died.
- // If the process did exit, then we are reaping it.
- const StateType state = process_sp->GetState();
-
- if (state != eStateInvalid && state != eStateUnloaded && state != eStateExited && state != eStateDetached)
- {
- char error_str[1024];
- if (signo)
- {
- const char *signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo);
- if (signal_cstr)
- ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
- else
- ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
- }
- else
- {
- ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
- exit_status);
- }
+bool ProcessGDBRemote::MonitorDebugserverProcess(
+ std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
+ 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));
+ const bool handled = true;
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
+ ", signo=%i (0x%x), exit_status=%i)",
+ __FUNCTION__, debugserver_pid, signo, signo, exit_status);
+
+ std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
+ if (log)
+ log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
+ static_cast<void *>(process_sp.get()));
+ if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
+ return handled;
- process_sp->SetExitStatus(-1, error_str);
+ // Sleep for a half a second to make sure our inferior process has
+ // time to set its exit status before we set it incorrectly when
+ // both the debugserver and the inferior process shut down.
+ usleep(500000);
+ // If our process hasn't yet exited, debugserver might have died.
+ // If the process did exit, then we are reaping it.
+ const StateType state = process_sp->GetState();
+
+ if (state != eStateInvalid && state != eStateUnloaded &&
+ state != eStateExited && state != eStateDetached) {
+ char error_str[1024];
+ if (signo) {
+ const char *signal_cstr =
+ process_sp->GetUnixSignals()->GetSignalAsCString(signo);
+ if (signal_cstr)
+ ::snprintf(error_str, sizeof(error_str),
+ DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
+ else
+ ::snprintf(error_str, sizeof(error_str),
+ DEBUGSERVER_BASENAME " died with signal %i", signo);
+ } else {
+ ::snprintf(error_str, sizeof(error_str),
+ DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
+ exit_status);
}
- // Debugserver has exited we need to let our ProcessGDBRemote
- // know that it no longer has a debugserver instance
- process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- return handled;
+
+ process_sp->SetExitStatus(-1, error_str);
+ }
+ // Debugserver has exited we need to let our ProcessGDBRemote
+ // know that it no longer has a debugserver instance
+ process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ return handled;
}
-void
-ProcessGDBRemote::KillDebugserverProcess ()
-{
- m_gdb_comm.Disconnect();
- if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
- {
- Host::Kill (m_debugserver_pid, SIGINT);
- m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- }
+void ProcessGDBRemote::KillDebugserverProcess() {
+ m_gdb_comm.Disconnect();
+ if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+ Host::Kill(m_debugserver_pid, SIGINT);
+ m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ }
}
-void
-ProcessGDBRemote::Initialize()
-{
- static std::once_flag g_once_flag;
+void ProcessGDBRemote::Initialize() {
+ static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
- });
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+ });
}
-void
-ProcessGDBRemote::DebuggerInitialize (Debugger &debugger)
-{
- if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForProcessPlugin (debugger,
- GetGlobalPluginProperties()->GetValueProperties(),
- ConstString ("Properties for the gdb-remote process plug-in."),
- is_global_setting);
- }
+void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForProcessPlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForProcessPlugin(
+ debugger, GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString("Properties for the gdb-remote process plug-in."),
+ is_global_setting);
+ }
}
-bool
-ProcessGDBRemote::StartAsyncThread ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+bool ProcessGDBRemote::StartAsyncThread() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
+ if (log)
+ log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
- 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).
+ 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.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
- }
- else if (log)
- log->Printf("ProcessGDBRemote::%s () - Called when Async thread was already running.", __FUNCTION__);
+ m_async_thread =
+ ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>",
+ ProcessGDBRemote::AsyncThread, this, NULL);
+ } else if (log)
+ log->Printf("ProcessGDBRemote::%s () - Called when Async thread was "
+ "already running.",
+ __FUNCTION__);
- return m_async_thread.IsJoinable();
+ return m_async_thread.IsJoinable();
}
-void
-ProcessGDBRemote::StopAsyncThread ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+void ProcessGDBRemote::StopAsyncThread() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
+ if (log)
+ log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
- std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
- if (m_async_thread.IsJoinable())
- {
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+ if (m_async_thread.IsJoinable()) {
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
- // This will shut down the async thread.
- m_gdb_comm.Disconnect(); // Disconnect from the debug server.
+ // This will shut down the async thread.
+ m_gdb_comm.Disconnect(); // Disconnect from the debug server.
- // Stop the stdio thread
- m_async_thread.Join(nullptr);
- m_async_thread.Reset();
- }
- else if (log)
- log->Printf("ProcessGDBRemote::%s () - Called when Async thread was not running.", __FUNCTION__);
+ // Stop the stdio thread
+ m_async_thread.Join(nullptr);
+ m_async_thread.Reset();
+ } else if (log)
+ log->Printf(
+ "ProcessGDBRemote::%s () - Called when Async thread was not running.",
+ __FUNCTION__);
}
-bool
-ProcessGDBRemote::HandleNotifyPacket (StringExtractorGDBRemote &packet)
-{
- // get the packet at a string
- const std::string &pkt = packet.GetStringRef();
- // skip %stop:
- StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
-
- // pass as a thread stop info packet
- SetLastStopPacket(stop_info);
-
- // check for more stop reasons
- HandleStopReplySequence();
-
- // if the process is stopped then we need to fake a resume
- // so that we can stop properly with the new break. This
- // is possible due to SetPrivateState() broadcasting the
- // state change as a side effect.
- if (GetPrivateState() == lldb::StateType::eStateStopped)
- {
- SetPrivateState(lldb::StateType::eStateRunning);
- }
+bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) {
+ // get the packet at a string
+ const std::string &pkt = packet.GetStringRef();
+ // skip %stop:
+ StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
- // since we have some stopped packets we can halt the process
- SetPrivateState(lldb::StateType::eStateStopped);
+ // pass as a thread stop info packet
+ SetLastStopPacket(stop_info);
- return true;
+ // check for more stop reasons
+ HandleStopReplySequence();
+
+ // if the process is stopped then we need to fake a resume
+ // so that we can stop properly with the new break. This
+ // is possible due to SetPrivateState() broadcasting the
+ // state change as a side effect.
+ if (GetPrivateState() == lldb::StateType::eStateStopped) {
+ SetPrivateState(lldb::StateType::eStateRunning);
+ }
+
+ // since we have some stopped packets we can halt the process
+ SetPrivateState(lldb::StateType::eStateStopped);
+
+ return true;
}
-thread_result_t
-ProcessGDBRemote::AsyncThread (void *arg)
-{
- ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
+thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
+ ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, arg, process->GetID());
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread starting...",
+ __FUNCTION__, arg, process->GetID());
- EventSP event_sp;
- bool done = false;
- while (!done)
- {
+ EventSP event_sp;
+ bool done = false;
+ while (!done) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp)...",
+ __FUNCTION__, arg, process->GetID());
+ if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
+ const uint32_t event_type = event_sp->GetType();
+ if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
- if (process->m_async_listener_sp->WaitForEvent (NULL, event_sp))
- {
- const uint32_t event_type = event_sp->GetType();
- if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
-
- switch (event_type)
- {
- case eBroadcastBitAsyncContinue:
- {
- const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
-
- if (continue_packet)
- {
- const char *continue_cstr = (const char *)continue_packet->GetBytes ();
- const size_t continue_cstr_len = continue_packet->GetByteSize ();
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
-
- if (::strstr (continue_cstr, "vAttach") == NULL)
- process->SetPrivateState(eStateRunning);
- StringExtractorGDBRemote response;
-
- // If in Non-Stop-Mode
- if (process->GetTarget().GetNonStopModeEnabled())
- {
- // send the vCont packet
- if (!process->GetGDBRemote().SendvContPacket(process, continue_cstr, continue_cstr_len, response))
- {
- // Something went wrong
- done = true;
- break;
- }
- }
- // If in All-Stop-Mode
- else
- {
- StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
-
- // We need to immediately clear the thread ID list so we are sure to get a valid list of threads.
- // The thread ID list might be contained within the "response", or the stop reply packet that
- // caused the stop. So clear it now before we give the stop reply packet to the process
- // using the process->SetLastStopPacket()...
- process->ClearThreadIDList ();
-
- switch (stop_state)
- {
- case eStateStopped:
- case eStateCrashed:
- case eStateSuspended:
- process->SetLastStopPacket (response);
- process->SetPrivateState (stop_state);
- break;
-
- case eStateExited:
- {
- process->SetLastStopPacket (response);
- process->ClearThreadIDList();
- response.SetFilePos(1);
-
- int exit_status = response.GetHexU8();
- const char *desc_cstr = NULL;
- StringExtractor extractor;
- std::string desc_string;
- if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';')
- {
- std::string desc_token;
- while (response.GetNameColonValue (desc_token, desc_string))
- {
- if (desc_token == "description")
- {
- extractor.GetStringRef().swap(desc_string);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (desc_string);
- desc_cstr = desc_string.c_str();
- }
- }
- }
- process->SetExitStatus(exit_status, desc_cstr);
- done = true;
- break;
- }
- case eStateInvalid:
- {
- // Check to see if we were trying to attach and if we got back
- // the "E87" error code from debugserver -- this indicates that
- // the process is not debuggable. Return a slightly more helpful
- // error message about why the attach failed.
- if (::strstr (continue_cstr, "vAttach") != NULL
- && response.GetError() == 0x87)
- {
- process->SetExitStatus(-1, "cannot attach to process due to System Integrity Protection");
- }
- // E01 code from vAttach means that the attach failed
- if (::strstr (continue_cstr, "vAttach") != NULL
- && response.GetError() == 0x1)
- {
- process->SetExitStatus(-1, "unable to attach");
- }
- else
- {
- process->SetExitStatus(-1, "lost connection");
- }
- break;
- }
-
- default:
- process->SetPrivateState (stop_state);
- break;
- } // switch(stop_state)
- } // else // if in All-stop-mode
- } // if (continue_packet)
- } // case eBroadcastBitAysncContinue
- break;
-
- case eBroadcastBitAsyncThreadShouldExit:
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
- done = true;
- break;
-
- default:
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
- done = true;
- break;
- }
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") Got an event of type: %d...",
+ __FUNCTION__, arg, process->GetID(), event_type);
+
+ switch (event_type) {
+ case eBroadcastBitAsyncContinue: {
+ const EventDataBytes *continue_packet =
+ EventDataBytes::GetEventDataFromEvent(event_sp.get());
+
+ if (continue_packet) {
+ const char *continue_cstr =
+ (const char *)continue_packet->GetBytes();
+ const size_t continue_cstr_len = continue_packet->GetByteSize();
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncContinue: %s",
+ __FUNCTION__, arg, process->GetID(), continue_cstr);
+
+ if (::strstr(continue_cstr, "vAttach") == NULL)
+ process->SetPrivateState(eStateRunning);
+ StringExtractorGDBRemote response;
+
+ // If in Non-Stop-Mode
+ if (process->GetTarget().GetNonStopModeEnabled()) {
+ // send the vCont packet
+ if (!process->GetGDBRemote().SendvContPacket(
+ llvm::StringRef(continue_cstr, continue_cstr_len),
+ response)) {
+ // Something went wrong
+ done = true;
+ break;
+ }
}
- else if (event_sp->BroadcasterIs (&process->m_gdb_comm))
- {
- switch (event_type)
- {
- case Communication::eBroadcastBitReadThreadDidExit:
- process->SetExitStatus (-1, "lost connection");
- done = true;
- break;
-
- case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify:
- {
- lldb_private::Event *event = event_sp.get();
- const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event);
- StringExtractorGDBRemote notify((const char*)continue_packet->GetBytes());
- // Hand this over to the process to handle
- process->HandleNotifyPacket(notify);
- break;
- }
-
- default:
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
- done = true;
- break;
+ // If in All-Stop-Mode
+ else {
+ StateType stop_state =
+ process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
+ *process, *process->GetUnixSignals(),
+ llvm::StringRef(continue_cstr, continue_cstr_len),
+ response);
+
+ // We need to immediately clear the thread ID list so we are sure
+ // to get a valid list of threads.
+ // The thread ID list might be contained within the "response", or
+ // the stop reply packet that
+ // caused the stop. So clear it now before we give the stop reply
+ // packet to the process
+ // using the process->SetLastStopPacket()...
+ process->ClearThreadIDList();
+
+ switch (stop_state) {
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ process->SetLastStopPacket(response);
+ process->SetPrivateState(stop_state);
+ break;
+
+ case eStateExited: {
+ process->SetLastStopPacket(response);
+ process->ClearThreadIDList();
+ response.SetFilePos(1);
+
+ int exit_status = response.GetHexU8();
+ std::string desc_string;
+ if (response.GetBytesLeft() > 0 &&
+ response.GetChar('-') == ';') {
+ llvm::StringRef desc_str;
+ llvm::StringRef desc_token;
+ while (response.GetNameColonValue(desc_token, desc_str)) {
+ if (desc_token != "description")
+ continue;
+ StringExtractor extractor(desc_str);
+ extractor.GetHexByteString(desc_string);
+ }
}
- }
+ process->SetExitStatus(exit_status, desc_string.c_str());
+ done = true;
+ break;
+ }
+ case eStateInvalid: {
+ // Check to see if we were trying to attach and if we got back
+ // the "E87" error code from debugserver -- this indicates that
+ // the process is not debuggable. Return a slightly more
+ // helpful
+ // error message about why the attach failed.
+ if (::strstr(continue_cstr, "vAttach") != NULL &&
+ response.GetError() == 0x87) {
+ process->SetExitStatus(-1, "cannot attach to process due to "
+ "System Integrity Protection");
+ }
+ // E01 code from vAttach means that the attach failed
+ if (::strstr(continue_cstr, "vAttach") != NULL &&
+ response.GetError() == 0x1) {
+ process->SetExitStatus(-1, "unable to attach");
+ } else {
+ process->SetExitStatus(-1, "lost connection");
+ }
+ break;
+ }
+
+ default:
+ process->SetPrivateState(stop_state);
+ break;
+ } // switch(stop_state)
+ } // else // if in All-stop-mode
+ } // if (continue_packet)
+ } // case eBroadcastBitAysncContinue
+ break;
+
+ case eBroadcastBitAsyncThreadShouldExit:
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncThreadShouldExit...",
+ __FUNCTION__, arg, process->GetID());
+ done = true;
+ break;
+
+ default:
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
+ done = true;
+ break;
}
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
- done = true;
+ } else if (event_sp->BroadcasterIs(&process->m_gdb_comm)) {
+ switch (event_type) {
+ case Communication::eBroadcastBitReadThreadDidExit:
+ process->SetExitStatus(-1, "lost connection");
+ done = true;
+ break;
+
+ case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify: {
+ lldb_private::Event *event = event_sp.get();
+ const EventDataBytes *continue_packet =
+ EventDataBytes::GetEventDataFromEvent(event);
+ StringExtractorGDBRemote notify(
+ (const char *)continue_packet->GetBytes());
+ // Hand this over to the process to handle
+ process->HandleNotifyPacket(notify);
+ break;
+ }
+
+ default:
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
+ done = true;
+ break;
}
+ }
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp) => false",
+ __FUNCTION__, arg, process->GetID());
+ done = true;
}
+ }
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, arg, process->GetID());
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread exiting...",
+ __FUNCTION__, arg, process->GetID());
- return NULL;
+ return NULL;
}
-//uint32_t
-//ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
+// uint32_t
+// ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList
+// &matches, std::vector<lldb::pid_t> &pids)
//{
-// // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
-// // process and ask it for the list of processes. But if we are local, we can let the Host do it.
+// // If we are planning to launch the debugserver remotely, then we need to
+// fire up a debugserver
+// // process and ask it for the list of processes. But if we are local, we
+// can let the Host do it.
// if (m_local_debugserver)
// {
// return Host::ListProcessesMatchingName (name, matches, pids);
@@ -4068,189 +3727,240 @@ ProcessGDBRemote::AsyncThread (void *arg)
//
//}
//
-bool
-ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
-{
- // I don't think I have to do anything here, just make sure I notice the new thread when it starts to
- // run so I can stop it if that's what I want to do.
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Hit New Thread Notification breakpoint.");
- return false;
+bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
+ void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ // I don't think I have to do anything here, just make sure I notice the new
+ // thread when it starts to
+ // run so I can stop it if that's what I want to do.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf("Hit New Thread Notification breakpoint.");
+ return false;
}
-
-bool
-ProcessGDBRemote::StartNoticingNewThreads()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (m_thread_create_bp_sp)
- {
+bool ProcessGDBRemote::StartNoticingNewThreads() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (m_thread_create_bp_sp) {
+ if (log && log->GetVerbose())
+ log->Printf("Enabled noticing new thread breakpoint.");
+ m_thread_create_bp_sp->SetEnabled(true);
+ } else {
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ if (platform_sp) {
+ m_thread_create_bp_sp =
+ platform_sp->SetThreadCreationBreakpoint(GetTarget());
+ if (m_thread_create_bp_sp) {
if (log && log->GetVerbose())
- log->Printf("Enabled noticing new thread breakpoint.");
- m_thread_create_bp_sp->SetEnabled(true);
- }
- else
- {
- PlatformSP platform_sp (GetTarget().GetPlatform());
- if (platform_sp)
- {
- m_thread_create_bp_sp = platform_sp->SetThreadCreationBreakpoint(GetTarget());
- if (m_thread_create_bp_sp)
- {
- if (log && log->GetVerbose())
- log->Printf("Successfully created new thread notification breakpoint %i", m_thread_create_bp_sp->GetID());
- m_thread_create_bp_sp->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
- }
- else
- {
- if (log)
- log->Printf("Failed to create new thread notification breakpoint.");
- }
- }
+ log->Printf(
+ "Successfully created new thread notification breakpoint %i",
+ m_thread_create_bp_sp->GetID());
+ m_thread_create_bp_sp->SetCallback(
+ ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
+ } else {
+ if (log)
+ log->Printf("Failed to create new thread notification breakpoint.");
+ }
}
- return m_thread_create_bp_sp.get() != NULL;
+ }
+ return m_thread_create_bp_sp.get() != NULL;
}
-bool
-ProcessGDBRemote::StopNoticingNewThreads()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log && log->GetVerbose())
- log->Printf ("Disabling new thread notification breakpoint.");
+bool ProcessGDBRemote::StopNoticingNewThreads() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log && log->GetVerbose())
+ log->Printf("Disabling new thread notification breakpoint.");
- if (m_thread_create_bp_sp)
- m_thread_create_bp_sp->SetEnabled(false);
+ if (m_thread_create_bp_sp)
+ m_thread_create_bp_sp->SetEnabled(false);
- return true;
+ return true;
}
-DynamicLoader *
-ProcessGDBRemote::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
- return m_dyld_ap.get();
+DynamicLoader *ProcessGDBRemote::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(this, NULL));
+ return m_dyld_ap.get();
}
-Error
-ProcessGDBRemote::SendEventData(const char *data)
-{
- int return_value;
- bool was_supported;
+Error ProcessGDBRemote::SendEventData(const char *data) {
+ int return_value;
+ bool was_supported;
- Error error;
+ Error error;
- return_value = m_gdb_comm.SendLaunchEventDataPacket (data, &was_supported);
- if (return_value != 0)
- {
- if (!was_supported)
- error.SetErrorString("Sending events is not supported for this process.");
- else
- error.SetErrorStringWithFormat("Error sending event data: %d.", return_value);
- }
- return error;
+ return_value = m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
+ if (return_value != 0) {
+ if (!was_supported)
+ error.SetErrorString("Sending events is not supported for this process.");
+ else
+ error.SetErrorStringWithFormat("Error sending event data: %d.",
+ return_value);
+ }
+ return error;
}
-const DataBufferSP
-ProcessGDBRemote::GetAuxvData()
-{
- DataBufferSP buf;
- if (m_gdb_comm.GetQXferAuxvReadSupported())
- {
- std::string response_string;
- if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::", response_string) == GDBRemoteCommunication::PacketResult::Success)
- buf.reset(new DataBufferHeap(response_string.c_str(), response_string.length()));
- }
- return buf;
+const DataBufferSP ProcessGDBRemote::GetAuxvData() {
+ DataBufferSP buf;
+ if (m_gdb_comm.GetQXferAuxvReadSupported()) {
+ std::string response_string;
+ if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::",
+ response_string) ==
+ GDBRemoteCommunication::PacketResult::Success)
+ buf.reset(new DataBufferHeap(response_string.c_str(),
+ response_string.length()));
+ }
+ return buf;
}
StructuredData::ObjectSP
-ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid)
-{
- StructuredData::ObjectSP object_sp;
+ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {
+ StructuredData::ObjectSP object_sp;
- if (m_gdb_comm.GetThreadExtendedInfoSupported())
- {
- StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
- SystemRuntime *runtime = GetSystemRuntime();
- if (runtime)
- {
- runtime->AddThreadExtendedInfoPacketHints (args_dict);
- }
- args_dict->GetAsDictionary()->AddIntegerItem ("thread", tid);
+ if (m_gdb_comm.GetThreadExtendedInfoSupported()) {
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+ SystemRuntime *runtime = GetSystemRuntime();
+ if (runtime) {
+ runtime->AddThreadExtendedInfoPacketHints(args_dict);
+ }
+ args_dict->GetAsDictionary()->AddIntegerItem("thread", tid);
- StreamString packet;
- packet << "jThreadExtendedInfo:";
- args_dict->Dump (packet);
+ StreamString packet;
+ packet << "jThreadExtendedInfo:";
+ args_dict->Dump(packet, false);
- // FIXME the final character of a JSON dictionary, '}', is the escape
- // character in gdb-remote binary mode. lldb currently doesn't escape
- // these characters in its packet output -- so we add the quoted version
- // of the } character here manually in case we talk to a debugserver which
- // un-escapes the characters at packet read time.
- packet << (char) (0x7d ^ 0x20);
+ // FIXME the final character of a JSON dictionary, '}', is the escape
+ // character in gdb-remote binary mode. lldb currently doesn't escape
+ // these characters in its packet output -- so we add the quoted version
+ // of the } character here manually in case we talk to a debugserver which
+ // un-escapes the characters at packet read time.
+ packet << (char)(0x7d ^ 0x20);
- StringExtractorGDBRemote response;
- response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
- if (response_type == StringExtractorGDBRemote::eResponse)
- {
- if (!response.Empty())
- {
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
- }
- }
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ StringExtractorGDBRemote::ResponseType response_type =
+ response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
}
+ }
}
- return object_sp;
+ }
+ return object_sp;
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
+ lldb::addr_t image_list_address, lldb::addr_t image_count) {
+
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+ args_dict->GetAsDictionary()->AddIntegerItem("image_list_address",
+ image_list_address);
+ args_dict->GetAsDictionary()->AddIntegerItem("image_count", image_count);
+
+ return GetLoadedDynamicLibrariesInfos_sender(args_dict);
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos() {
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+
+ args_dict->GetAsDictionary()->AddBooleanItem("fetch_all_solibs", true);
+
+ return GetLoadedDynamicLibrariesInfos_sender(args_dict);
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
+ const std::vector<lldb::addr_t> &load_addresses) {
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+ StructuredData::ArraySP addresses(new StructuredData::Array);
+
+ for (auto addr : load_addresses) {
+ StructuredData::ObjectSP addr_sp(new StructuredData::Integer(addr));
+ addresses->AddItem(addr_sp);
+ }
+
+ args_dict->GetAsDictionary()->AddItem("solib_addresses", addresses);
+
+ return GetLoadedDynamicLibrariesInfos_sender(args_dict);
}
StructuredData::ObjectSP
-ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count)
-{
- StructuredData::ObjectSP object_sp;
+ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
+ StructuredData::ObjectSP args_dict) {
+ StructuredData::ObjectSP object_sp;
- if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported())
- {
- // Scope for the scoped timeout object
- GDBRemoteCommunication::ScopedTimeout timeout (m_gdb_comm, 10);
+ if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
+ // Scope for the scoped timeout object
+ GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm,
+ std::chrono::seconds(10));
- StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
- args_dict->GetAsDictionary()->AddIntegerItem ("image_list_address", image_list_address);
- args_dict->GetAsDictionary()->AddIntegerItem ("image_count", image_count);
+ StreamString packet;
+ packet << "jGetLoadedDynamicLibrariesInfos:";
+ args_dict->Dump(packet, false);
- StreamString packet;
- packet << "jGetLoadedDynamicLibrariesInfos:";
- args_dict->Dump (packet);
+ // FIXME the final character of a JSON dictionary, '}', is the escape
+ // character in gdb-remote binary mode. lldb currently doesn't escape
+ // these characters in its packet output -- so we add the quoted version
+ // of the } character here manually in case we talk to a debugserver which
+ // un-escapes the characters at packet read time.
+ packet << (char)(0x7d ^ 0x20);
- // FIXME the final character of a JSON dictionary, '}', is the escape
- // character in gdb-remote binary mode. lldb currently doesn't escape
- // these characters in its packet output -- so we add the quoted version
- // of the } character here manually in case we talk to a debugserver which
- // un-escapes the characters at packet read time.
- packet << (char) (0x7d ^ 0x20);
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ StringExtractorGDBRemote::ResponseType response_type =
+ response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ }
+ }
+ }
+ }
+ return object_sp;
+}
- StringExtractorGDBRemote response;
- response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
- if (response_type == StringExtractorGDBRemote::eResponse)
- {
- if (!response.Empty())
- {
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
- }
- }
+StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
+ StructuredData::ObjectSP object_sp;
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+
+ if (m_gdb_comm.GetSharedCacheInfoSupported()) {
+ StreamString packet;
+ packet << "jGetSharedCacheInfo:";
+ args_dict->Dump(packet, false);
+
+ // FIXME the final character of a JSON dictionary, '}', is the escape
+ // character in gdb-remote binary mode. lldb currently doesn't escape
+ // these characters in its packet output -- so we add the quoted version
+ // of the } character here manually in case we talk to a debugserver which
+ // un-escapes the characters at packet read time.
+ packet << (char)(0x7d ^ 0x20);
+
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ StringExtractorGDBRemote::ResponseType response_type =
+ response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
}
+ }
}
- return object_sp;
+ }
+ return object_sp;
+}
+
+Error ProcessGDBRemote::ConfigureStructuredData(
+ const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+ return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
}
// Establish the largest memory read/write payloads we should use.
@@ -4262,100 +3972,103 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_addres
// If the remote stub doesn't advertise a max packet size, use a
// conservative default.
-void
-ProcessGDBRemote::GetMaxMemorySize()
-{
- const uint64_t reasonable_largeish_default = 128 * 1024;
- const uint64_t conservative_default = 512;
+void ProcessGDBRemote::GetMaxMemorySize() {
+ const uint64_t reasonable_largeish_default = 128 * 1024;
+ const uint64_t conservative_default = 512;
- if (m_max_memory_size == 0)
- {
- uint64_t stub_max_size = m_gdb_comm.GetRemoteMaxPacketSize();
- if (stub_max_size != UINT64_MAX && stub_max_size != 0)
- {
- // Save the stub's claimed maximum packet size
- m_remote_stub_max_memory_size = stub_max_size;
+ if (m_max_memory_size == 0) {
+ uint64_t stub_max_size = m_gdb_comm.GetRemoteMaxPacketSize();
+ if (stub_max_size != UINT64_MAX && stub_max_size != 0) {
+ // Save the stub's claimed maximum packet size
+ m_remote_stub_max_memory_size = stub_max_size;
- // Even if the stub says it can support ginormous packets,
- // don't exceed our reasonable largeish default packet size.
- if (stub_max_size > reasonable_largeish_default)
- {
- stub_max_size = reasonable_largeish_default;
- }
+ // Even if the stub says it can support ginormous packets,
+ // don't exceed our reasonable largeish default packet size.
+ if (stub_max_size > reasonable_largeish_default) {
+ stub_max_size = reasonable_largeish_default;
+ }
- m_max_memory_size = stub_max_size;
- }
- else
- {
- m_max_memory_size = conservative_default;
- }
+ m_max_memory_size = stub_max_size;
+ } else {
+ m_max_memory_size = conservative_default;
}
+ }
}
-void
-ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max)
-{
- if (user_specified_max != 0)
- {
- GetMaxMemorySize ();
-
- if (m_remote_stub_max_memory_size != 0)
- {
- if (m_remote_stub_max_memory_size < user_specified_max)
- {
- m_max_memory_size = m_remote_stub_max_memory_size; // user specified a packet size too big, go as big
- // as the remote stub says we can go.
- }
- else
- {
- m_max_memory_size = user_specified_max; // user's packet size is good
- }
- }
- else
- {
- m_max_memory_size = user_specified_max; // user's packet size is probably fine
- }
+void ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize(
+ uint64_t user_specified_max) {
+ if (user_specified_max != 0) {
+ GetMaxMemorySize();
+
+ if (m_remote_stub_max_memory_size != 0) {
+ if (m_remote_stub_max_memory_size < user_specified_max) {
+ m_max_memory_size = m_remote_stub_max_memory_size; // user specified a
+ // packet size too
+ // big, go as big
+ // as the remote stub says we can go.
+ } else {
+ m_max_memory_size = user_specified_max; // user's packet size is good
+ }
+ } else {
+ m_max_memory_size =
+ user_specified_max; // user's packet size is probably fine
}
+ }
}
-bool
-ProcessGDBRemote::GetModuleSpec(const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec)
-{
- Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch,
+ ModuleSpec &module_spec) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (!m_gdb_comm.GetModuleInfo (module_file_spec, arch, module_spec))
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s - failed to get module info for %s:%s",
- __FUNCTION__, module_file_spec.GetPath ().c_str (),
- arch.GetTriple ().getTriple ().c_str ());
- return false;
- }
+ const ModuleCacheKey key(module_file_spec.GetPath(),
+ arch.GetTriple().getTriple());
+ auto cached = m_cached_module_specs.find(key);
+ if (cached != m_cached_module_specs.end()) {
+ module_spec = cached->second;
+ return bool(module_spec);
+ }
+ if (!m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
if (log)
- {
- StreamString stream;
- module_spec.Dump (stream);
- log->Printf ("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
- __FUNCTION__, module_file_spec.GetPath ().c_str (),
- arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ());
- }
+ log->Printf("ProcessGDBRemote::%s - failed to get module info for %s:%s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str());
+ return false;
+ }
+
+ if (log) {
+ StreamString stream;
+ module_spec.Dump(stream);
+ log->Printf("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str(), stream.GetData());
+ }
+
+ m_cached_module_specs[key] = module_spec;
+ return true;
+}
- return true;
+void ProcessGDBRemote::PrefetchModuleSpecs(
+ llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
+ auto module_specs = m_gdb_comm.GetModulesInfo(module_file_specs, triple);
+ if (module_specs) {
+ for (const FileSpec &spec : module_file_specs)
+ m_cached_module_specs[ModuleCacheKey(spec.GetPath(),
+ triple.getTriple())] = ModuleSpec();
+ for (const ModuleSpec &spec : *module_specs)
+ m_cached_module_specs[ModuleCacheKey(spec.GetFileSpec().GetPath(),
+ triple.getTriple())] = spec;
+ }
}
-bool
-ProcessGDBRemote::GetHostOSVersion(uint32_t &major,
- uint32_t &minor,
- uint32_t &update)
-{
- if (m_gdb_comm.GetOSVersion(major, minor, update))
- return true;
- // We failed to get the host OS version, defer to the base
- // implementation to correctly invalidate the arguments.
- return Process::GetHostOSVersion(major, minor, update);
+bool ProcessGDBRemote::GetHostOSVersion(uint32_t &major, uint32_t &minor,
+ uint32_t &update) {
+ if (m_gdb_comm.GetOSVersion(major, minor, update))
+ return true;
+ // We failed to get the host OS version, defer to the base
+ // implementation to correctly invalidate the arguments.
+ return Process::GetHostOSVersion(major, minor, update);
}
namespace {
@@ -4363,29 +4076,29 @@ namespace {
typedef std::vector<std::string> stringVec;
typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
-struct RegisterSetInfo
-{
- ConstString name;
+struct RegisterSetInfo {
+ ConstString name;
};
typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
-struct GdbServerTargetInfo
-{
- std::string arch;
- std::string osabi;
- stringVec includes;
- RegisterSetMap reg_set_map;
- XMLNode feature_node;
+struct GdbServerTargetInfo {
+ std::string arch;
+ std::string osabi;
+ stringVec includes;
+ RegisterSetMap reg_set_map;
+ XMLNode feature_node;
};
-bool
-ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp, uint32_t &cur_reg_num, uint32_t &reg_offset)
-{
- if (!feature_node)
- return false;
+bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
+ GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp,
+ uint32_t &cur_reg_num, uint32_t &reg_offset) {
+ if (!feature_node)
+ return false;
- feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset, &abi_sp](const XMLNode &reg_node) -> bool {
+ feature_node.ForEachChildElementWithName(
+ "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;
@@ -4396,931 +4109,1038 @@ ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemot
std::vector<uint8_t> dwarf_opcode_bytes;
bool encoding_set = false;
bool format_set = false;
- RegisterInfo reg_info = { NULL, // Name
- NULL, // Alt name
- 0, // byte size
- reg_offset, // offset
- eEncodingUint, // encoding
- eFormatHex, // format
+ RegisterInfo reg_info = {
+ NULL, // Name
+ NULL, // Alt name
+ 0, // byte size
+ reg_offset, // offset
+ eEncodingUint, // encoding
+ eFormatHex, // format
{
LLDB_INVALID_REGNUM, // eh_frame reg num
LLDB_INVALID_REGNUM, // DWARF reg num
LLDB_INVALID_REGNUM, // generic reg num
- cur_reg_num, // process plugin reg num
- cur_reg_num // native register number
+ cur_reg_num, // process plugin reg num
+ cur_reg_num // native register number
},
NULL,
NULL,
- NULL, // Dwarf Expression opcode bytes pointer
- 0 // Dwarf Expression opcode bytes length
+ NULL, // Dwarf Expression opcode bytes pointer
+ 0 // Dwarf Expression opcode bytes length
};
- reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, &reg_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, &reg_info, &cur_reg_num, &reg_offset, &dwarf_opcode_bytes](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
- if (name == "name")
- {
- reg_name.SetString(value);
- }
- else if (name == "bitsize")
- {
- reg_info.byte_size = StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT;
- }
- else if (name == "type")
- {
- gdb_type = value.str();
- }
- else if (name == "group")
- {
- gdb_group = value.str();
- }
- else if (name == "regnum")
- {
- const uint32_t regnum = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
- if (regnum != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindProcessPlugin] = regnum;
- }
- }
- else if (name == "offset")
- {
- reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
- }
- else if (name == "altname")
- {
- alt_name.SetString(value);
- }
- else if (name == "encoding")
- {
- encoding_set = true;
- reg_info.encoding = Args::StringToEncoding (value.data(), eEncodingUint);
- }
- else if (name == "format")
- {
- format_set = true;
- Format format = eFormatInvalid;
- if (Args::StringToFormat (value.data(), format, NULL).Success())
- reg_info.format = format;
- else if (value == "vector-sint8")
- reg_info.format = eFormatVectorOfSInt8;
- else if (value == "vector-uint8")
- reg_info.format = eFormatVectorOfUInt8;
- else if (value == "vector-sint16")
- reg_info.format = eFormatVectorOfSInt16;
- else if (value == "vector-uint16")
- reg_info.format = eFormatVectorOfUInt16;
- else if (value == "vector-sint32")
- reg_info.format = eFormatVectorOfSInt32;
- else if (value == "vector-uint32")
- reg_info.format = eFormatVectorOfUInt32;
- else if (value == "vector-float32")
- reg_info.format = eFormatVectorOfFloat32;
- else if (value == "vector-uint128")
- reg_info.format = eFormatVectorOfUInt128;
- }
- else if (name == "group_id")
- {
- const uint32_t set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
- RegisterSetMap::const_iterator pos = target_info.reg_set_map.find(set_id);
- if (pos != target_info.reg_set_map.end())
- set_name = pos->second.name;
- }
- else if (name == "gcc_regnum" || name == "ehframe_regnum")
- {
- reg_info.kinds[eRegisterKindEHFrame] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name == "dwarf_regnum")
- {
- reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name == "generic")
- {
- reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value.data());
- }
- else if (name == "value_regnums")
- {
- SplitCommaSeparatedRegisterNumberString(value, value_regs, 0);
- }
- else if (name == "invalidate_regnums")
- {
- SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
- }
- else if (name == "dynamic_size_dwarf_expr_bytes")
- {
- StringExtractor opcode_extractor;
- std::string opcode_string = value.str ();
- size_t dwarf_opcode_len = opcode_string.length () / 2;
- assert (dwarf_opcode_len > 0);
-
- dwarf_opcode_bytes.resize (dwarf_opcode_len);
- reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
- opcode_extractor.GetStringRef ().swap (opcode_string);
- uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (),
- dwarf_opcode_len);
- assert (dwarf_opcode_len == ret_val);
-
- reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data ();
- }
- else
- {
- printf("unhandled attribute %s = %s\n", name.data(), value.data());
+ reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type,
+ &reg_name, &alt_name, &set_name, &value_regs,
+ &invalidate_regs, &encoding_set, &format_set,
+ &reg_info, &cur_reg_num, &reg_offset,
+ &dwarf_opcode_bytes](
+ const llvm::StringRef &name,
+ const llvm::StringRef &value) -> bool {
+ if (name == "name") {
+ reg_name.SetString(value);
+ } else if (name == "bitsize") {
+ reg_info.byte_size =
+ StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT;
+ } else if (name == "type") {
+ gdb_type = value.str();
+ } else if (name == "group") {
+ gdb_group = value.str();
+ } else if (name == "regnum") {
+ const uint32_t regnum =
+ StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+ if (regnum != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindProcessPlugin] = regnum;
}
- return true; // Keep iterating through all attributes
+ } else if (name == "offset") {
+ reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+ } else if (name == "altname") {
+ alt_name.SetString(value);
+ } else if (name == "encoding") {
+ encoding_set = true;
+ reg_info.encoding = Args::StringToEncoding(value, eEncodingUint);
+ } else if (name == "format") {
+ format_set = true;
+ Format format = eFormatInvalid;
+ if (Args::StringToFormat(value.data(), format, NULL).Success())
+ reg_info.format = format;
+ else if (value == "vector-sint8")
+ reg_info.format = eFormatVectorOfSInt8;
+ else if (value == "vector-uint8")
+ reg_info.format = eFormatVectorOfUInt8;
+ else if (value == "vector-sint16")
+ reg_info.format = eFormatVectorOfSInt16;
+ else if (value == "vector-uint16")
+ reg_info.format = eFormatVectorOfUInt16;
+ else if (value == "vector-sint32")
+ reg_info.format = eFormatVectorOfSInt32;
+ else if (value == "vector-uint32")
+ reg_info.format = eFormatVectorOfUInt32;
+ else if (value == "vector-float32")
+ reg_info.format = eFormatVectorOfFloat32;
+ else if (value == "vector-uint64")
+ reg_info.format = eFormatVectorOfUInt64;
+ else if (value == "vector-uint128")
+ reg_info.format = eFormatVectorOfUInt128;
+ } else if (name == "group_id") {
+ const uint32_t set_id =
+ StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+ RegisterSetMap::const_iterator pos =
+ target_info.reg_set_map.find(set_id);
+ if (pos != target_info.reg_set_map.end())
+ set_name = pos->second.name;
+ } else if (name == "gcc_regnum" || name == "ehframe_regnum") {
+ reg_info.kinds[eRegisterKindEHFrame] =
+ StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+ } else if (name == "dwarf_regnum") {
+ reg_info.kinds[eRegisterKindDWARF] =
+ StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+ } else if (name == "generic") {
+ reg_info.kinds[eRegisterKindGeneric] =
+ Args::StringToGenericRegister(value);
+ } else if (name == "value_regnums") {
+ SplitCommaSeparatedRegisterNumberString(value, value_regs, 0);
+ } else if (name == "invalidate_regnums") {
+ SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
+ } else if (name == "dynamic_size_dwarf_expr_bytes") {
+ StringExtractor opcode_extractor;
+ std::string opcode_string = value.str();
+ size_t dwarf_opcode_len = opcode_string.length() / 2;
+ assert(dwarf_opcode_len > 0);
+
+ dwarf_opcode_bytes.resize(dwarf_opcode_len);
+ reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
+ opcode_extractor.GetStringRef().swap(opcode_string);
+ uint32_t ret_val =
+ opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+ assert(dwarf_opcode_len == ret_val);
+
+ reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data();
+ } else {
+ printf("unhandled attribute %s = %s\n", name.data(), value.data());
+ }
+ return true; // Keep iterating through all attributes
});
- if (!gdb_type.empty() && !(encoding_set || format_set))
- {
- if (gdb_type.find("int") == 0)
- {
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if (gdb_type == "data_ptr" || gdb_type == "code_ptr")
- {
- reg_info.format = eFormatAddressInfo;
- reg_info.encoding = eEncodingUint;
- }
- else if (gdb_type == "i387_ext" || gdb_type == "float")
- {
- reg_info.format = eFormatFloat;
- reg_info.encoding = eEncodingIEEE754;
- }
+ if (!gdb_type.empty() && !(encoding_set || format_set)) {
+ if (gdb_type.find("int") == 0) {
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") {
+ reg_info.format = eFormatAddressInfo;
+ reg_info.encoding = eEncodingUint;
+ } else if (gdb_type == "i387_ext" || gdb_type == "float") {
+ reg_info.format = eFormatFloat;
+ reg_info.encoding = eEncodingIEEE754;
+ }
}
- // Only update the register set name if we didn't get a "reg_set" attribute.
+ // Only update the register set name if we didn't get a "reg_set"
+ // attribute.
// "set_name" will be empty if we didn't have a "reg_set" attribute.
if (!set_name && !gdb_group.empty())
- set_name.SetCString(gdb_group.c_str());
+ set_name.SetCString(gdb_group.c_str());
reg_info.byte_offset = reg_offset;
- assert (reg_info.byte_size != 0);
+ assert(reg_info.byte_size != 0);
reg_offset += reg_info.byte_size;
- if (!value_regs.empty())
- {
- value_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.value_regs = value_regs.data();
+ if (!value_regs.empty()) {
+ value_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = value_regs.data();
}
- if (!invalidate_regs.empty())
- {
- invalidate_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.invalidate_regs = invalidate_regs.data();
+ if (!invalidate_regs.empty()) {
+ invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = invalidate_regs.data();
}
++cur_reg_num;
- AugmentRegisterInfoViaABI (reg_info, reg_name, abi_sp);
+ AugmentRegisterInfoViaABI(reg_info, reg_name, abi_sp);
dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name);
return true; // Keep iterating through all "reg" elements
- });
- return true;
+ });
+ return true;
}
} // namespace {}
-
// query the target of gdb-remote for extended target information
// return: 'true' on success
// 'false' on failure
-bool
-ProcessGDBRemote::GetGDBServerRegisterInfo (ArchSpec &arch_to_use)
-{
- // Make sure LLDB has an XML parser it can use first
- if (!XMLDocument::XMLEnabled())
- return false;
-
- // redirect libxml2's error handler since the default prints to stdout
-
- GDBRemoteCommunicationClient & comm = m_gdb_comm;
-
- // check that we have extended feature read support
- if ( !comm.GetQXferFeaturesReadSupported( ) )
- return false;
-
- // request the target xml file
- std::string raw;
- lldb_private::Error lldberr;
- if (!comm.ReadExtFeature(ConstString("features"),
- ConstString("target.xml"),
- raw,
- lldberr))
- {
- return false;
- }
+bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
+ // Make sure LLDB has an XML parser it can use first
+ if (!XMLDocument::XMLEnabled())
+ return false;
+ // redirect libxml2's error handler since the default prints to stdout
- XMLDocument xml_document;
+ GDBRemoteCommunicationClient &comm = m_gdb_comm;
- if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml"))
- {
- GdbServerTargetInfo target_info;
+ // check that we have extended feature read support
+ if (!comm.GetQXferFeaturesReadSupported())
+ return false;
- XMLNode target_node = xml_document.GetRootElement("target");
- if (target_node)
- {
- XMLNode feature_node;
- target_node.ForEachChildElement([&target_info, this, &feature_node](const XMLNode &node) -> bool
- {
- llvm::StringRef name = node.GetName();
- if (name == "architecture")
- {
- node.GetElementText(target_info.arch);
- }
- else if (name == "osabi")
- {
- node.GetElementText(target_info.osabi);
- }
- else if (name == "xi:include" || name == "include")
- {
- llvm::StringRef href = node.GetAttributeValue("href");
- if (!href.empty())
- target_info.includes.push_back(href.str());
- }
- else if (name == "feature")
- {
- feature_node = node;
- }
- else if (name == "groups")
- {
- node.ForEachChildElementWithName("group", [&target_info](const XMLNode &node) -> bool {
- uint32_t set_id = UINT32_MAX;
- RegisterSetInfo set_info;
-
- node.ForEachAttribute([&set_id, &set_info](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
- if (name == "id")
- set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
- if (name == "name")
- set_info.name = ConstString(value);
- return true; // Keep iterating through all attributes
- });
-
- if (set_id != UINT32_MAX)
- target_info.reg_set_map[set_id] = set_info;
- return true; // Keep iterating through all "group" elements
+ // request the target xml file
+ std::string raw;
+ lldb_private::Error lldberr;
+ if (!comm.ReadExtFeature(ConstString("features"), ConstString("target.xml"),
+ raw, lldberr)) {
+ return false;
+ }
+
+ XMLDocument xml_document;
+
+ if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml")) {
+ GdbServerTargetInfo target_info;
+
+ XMLNode target_node = xml_document.GetRootElement("target");
+ if (target_node) {
+ XMLNode feature_node;
+ target_node.ForEachChildElement([&target_info, this, &feature_node](
+ const XMLNode &node) -> bool {
+ llvm::StringRef name = node.GetName();
+ if (name == "architecture") {
+ node.GetElementText(target_info.arch);
+ } else if (name == "osabi") {
+ node.GetElementText(target_info.osabi);
+ } else if (name == "xi:include" || name == "include") {
+ llvm::StringRef href = node.GetAttributeValue("href");
+ if (!href.empty())
+ target_info.includes.push_back(href.str());
+ } else if (name == "feature") {
+ feature_node = node;
+ } else if (name == "groups") {
+ node.ForEachChildElementWithName(
+ "group", [&target_info](const XMLNode &node) -> bool {
+ uint32_t set_id = UINT32_MAX;
+ RegisterSetInfo set_info;
+
+ node.ForEachAttribute(
+ [&set_id, &set_info](const llvm::StringRef &name,
+ const llvm::StringRef &value) -> bool {
+ if (name == "id")
+ set_id = StringConvert::ToUInt32(value.data(),
+ UINT32_MAX, 0);
+ if (name == "name")
+ set_info.name = ConstString(value);
+ return true; // Keep iterating through all attributes
});
- }
- return true; // Keep iterating through all children of the target_node
- });
-
- // Initialize these outside of ParseRegisters, since they should not be reset inside each include feature
- uint32_t cur_reg_num = 0;
- uint32_t reg_offset = 0;
-
- // Don't use Process::GetABI, this code gets called from DidAttach, and in that context we haven't
- // set the Target's architecture yet, so the ABI is also potentially incorrect.
- ABISP abi_to_use_sp = ABI::FindPlugin(arch_to_use);
- if (feature_node)
- {
- ParseRegisters(feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
- }
- for (const auto &include : target_info.includes)
- {
- // request register file
- std::string xml_data;
- if (!comm.ReadExtFeature(ConstString("features"),
- ConstString(include),
- xml_data,
- lldberr))
- continue;
-
- XMLDocument include_xml_document;
- include_xml_document.ParseMemory(xml_data.data(), xml_data.size(), include.c_str());
- XMLNode include_feature_node = include_xml_document.GetRootElement("feature");
- if (include_feature_node)
- {
- ParseRegisters(include_feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
- }
- }
- this->m_register_info.Finalize(arch_to_use);
+ if (set_id != UINT32_MAX)
+ target_info.reg_set_map[set_id] = set_info;
+ return true; // Keep iterating through all "group" elements
+ });
+ }
+ return true; // Keep iterating through all children of the target_node
+ });
+
+ // Initialize these outside of ParseRegisters, since they should not be
+ // reset inside each include feature
+ uint32_t cur_reg_num = 0;
+ uint32_t reg_offset = 0;
+
+ // Don't use Process::GetABI, this code gets called from DidAttach, and in
+ // that context we haven't
+ // set the Target's architecture yet, so the ABI is also potentially
+ // incorrect.
+ ABISP abi_to_use_sp = ABI::FindPlugin(arch_to_use);
+ if (feature_node) {
+ ParseRegisters(feature_node, target_info, this->m_register_info,
+ abi_to_use_sp, cur_reg_num, reg_offset);
+ }
+
+ for (const auto &include : target_info.includes) {
+ // request register file
+ std::string xml_data;
+ if (!comm.ReadExtFeature(ConstString("features"), ConstString(include),
+ xml_data, lldberr))
+ continue;
+
+ XMLDocument include_xml_document;
+ include_xml_document.ParseMemory(xml_data.data(), xml_data.size(),
+ include.c_str());
+ XMLNode include_feature_node =
+ include_xml_document.GetRootElement("feature");
+ if (include_feature_node) {
+ ParseRegisters(include_feature_node, target_info,
+ this->m_register_info, abi_to_use_sp, cur_reg_num,
+ reg_offset);
}
+ }
+ this->m_register_info.Finalize(arch_to_use);
}
+ }
- return m_register_info.GetNumRegisters() > 0;
+ return m_register_info.GetNumRegisters() > 0;
}
-Error
-ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list)
-{
- // Make sure LLDB has an XML parser it can use first
- if (!XMLDocument::XMLEnabled())
- return Error (0, ErrorType::eErrorTypeGeneric);
+Error ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
+ // Make sure LLDB has an XML parser it can use first
+ if (!XMLDocument::XMLEnabled())
+ return Error(0, ErrorType::eErrorTypeGeneric);
- Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS);
- if (log)
- log->Printf ("ProcessGDBRemote::%s", __FUNCTION__);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS);
+ if (log)
+ log->Printf("ProcessGDBRemote::%s", __FUNCTION__);
- GDBRemoteCommunicationClient & comm = m_gdb_comm;
+ GDBRemoteCommunicationClient &comm = m_gdb_comm;
- // check that we have extended feature read support
- if (comm.GetQXferLibrariesSVR4ReadSupported ()) {
- list.clear ();
+ // check that we have extended feature read support
+ if (comm.GetQXferLibrariesSVR4ReadSupported()) {
+ list.clear();
- // request the loaded library list
- std::string raw;
- lldb_private::Error lldberr;
+ // request the loaded library list
+ std::string raw;
+ lldb_private::Error lldberr;
- if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr))
- return Error (0, ErrorType::eErrorTypeGeneric);
+ if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""),
+ raw, lldberr))
+ return Error(0, ErrorType::eErrorTypeGeneric);
- // parse the xml file in memory
- if (log)
- log->Printf ("parsing: %s", raw.c_str());
- XMLDocument doc;
+ // parse the xml file in memory
+ if (log)
+ log->Printf("parsing: %s", raw.c_str());
+ XMLDocument doc;
- if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Error (0, ErrorType::eErrorTypeGeneric);
+ if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
+ return Error(0, ErrorType::eErrorTypeGeneric);
- XMLNode root_element = doc.GetRootElement("library-list-svr4");
- if (!root_element)
- return Error();
+ XMLNode root_element = doc.GetRootElement("library-list-svr4");
+ if (!root_element)
+ return Error();
- // main link map structure
- llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
- if (!main_lm.empty())
- {
- list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0);
- }
+ // main link map structure
+ llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
+ if (!main_lm.empty()) {
+ list.m_link_map =
+ StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0);
+ }
- root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
+ root_element.ForEachChildElementWithName(
+ "library", [log, &list](const XMLNode &library) -> bool {
- LoadedModuleInfoList::LoadedModuleInfo module;
+ LoadedModuleInfoList::LoadedModuleInfo module;
- library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
+ library.ForEachAttribute(
+ [log, &module](const llvm::StringRef &name,
+ const llvm::StringRef &value) -> bool {
if (name == "name")
- module.set_name (value.str());
- else if (name == "lm")
- {
- // the address of the link_map struct.
- module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
- }
- else if (name == "l_addr")
- {
- // the displacement as read from the field 'l_addr' of the link_map struct.
- module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
- // base address is always a displacement, not an absolute value.
- module.set_base_is_offset(true);
- }
- else if (name == "l_ld")
- {
- // the memory address of the libraries PT_DYAMIC section.
- module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
+ module.set_name(value.str());
+ else if (name == "lm") {
+ // the address of the link_map struct.
+ module.set_link_map(StringConvert::ToUInt64(
+ value.data(), LLDB_INVALID_ADDRESS, 0));
+ } else if (name == "l_addr") {
+ // the displacement as read from the field 'l_addr' of the
+ // link_map struct.
+ module.set_base(StringConvert::ToUInt64(
+ value.data(), LLDB_INVALID_ADDRESS, 0));
+ // base address is always a displacement, not an absolute
+ // value.
+ module.set_base_is_offset(true);
+ } else if (name == "l_ld") {
+ // the memory address of the libraries PT_DYAMIC section.
+ module.set_dynamic(StringConvert::ToUInt64(
+ value.data(), LLDB_INVALID_ADDRESS, 0));
}
return true; // Keep iterating over all properties of "library"
- });
-
- if (log)
- {
- std::string name;
- lldb::addr_t lm=0, base=0, ld=0;
- bool base_is_offset;
-
- module.get_name (name);
- module.get_link_map (lm);
- module.get_base (base);
- module.get_base_is_offset (base_is_offset);
- module.get_dynamic (ld);
-
- log->Printf ("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64 "[%s], ld:0x%08" PRIx64 ", name:'%s')", lm, base, (base_is_offset ? "offset" : "absolute"), ld, name.c_str());
- }
-
- list.add (module);
- return true; // Keep iterating over all "library" elements in the root node
+ });
+
+ if (log) {
+ std::string name;
+ lldb::addr_t lm = 0, base = 0, ld = 0;
+ bool base_is_offset;
+
+ module.get_name(name);
+ module.get_link_map(lm);
+ module.get_base(base);
+ module.get_base_is_offset(base_is_offset);
+ module.get_dynamic(ld);
+
+ log->Printf("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64
+ "[%s], ld:0x%08" PRIx64 ", name:'%s')",
+ lm, base, (base_is_offset ? "offset" : "absolute"), ld,
+ name.c_str());
+ }
+
+ list.add(module);
+ return true; // Keep iterating over all "library" elements in the root
+ // node
});
- if (log)
- log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());
- } else if (comm.GetQXferLibrariesReadSupported ()) {
- list.clear ();
-
- // request the loaded library list
- std::string raw;
- lldb_private::Error lldberr;
-
- if (!comm.ReadExtFeature (ConstString ("libraries"), ConstString (""), raw, lldberr))
- return Error (0, ErrorType::eErrorTypeGeneric);
-
- if (log)
- log->Printf ("parsing: %s", raw.c_str());
- XMLDocument doc;
-
- if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Error (0, ErrorType::eErrorTypeGeneric);
-
- XMLNode root_element = doc.GetRootElement("library-list");
- if (!root_element)
- return Error();
-
- root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
- LoadedModuleInfoList::LoadedModuleInfo module;
-
- llvm::StringRef name = library.GetAttributeValue("name");
- module.set_name(name.str());
+ if (log)
+ log->Printf("found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ } else if (comm.GetQXferLibrariesReadSupported()) {
+ list.clear();
- // The base address of a given library will be the address of its
- // first section. Most remotes send only one section for Windows
- // targets for example.
- const XMLNode &section = library.FindFirstChildElementWithName("section");
- llvm::StringRef address = section.GetAttributeValue("address");
- module.set_base(StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0));
- // These addresses are absolute values.
- module.set_base_is_offset(false);
+ // request the loaded library list
+ std::string raw;
+ lldb_private::Error lldberr;
- if (log)
- {
- std::string name;
- lldb::addr_t base = 0;
- bool base_is_offset;
- module.get_name (name);
- module.get_base (base);
- module.get_base_is_offset (base_is_offset);
-
- log->Printf ("found (base:0x%08" PRIx64 "[%s], name:'%s')", base, (base_is_offset ? "offset" : "absolute"), name.c_str());
- }
+ if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw,
+ lldberr))
+ return Error(0, ErrorType::eErrorTypeGeneric);
- list.add (module);
- return true; // Keep iterating over all "library" elements in the root node
+ if (log)
+ log->Printf("parsing: %s", raw.c_str());
+ XMLDocument doc;
+
+ if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
+ return Error(0, ErrorType::eErrorTypeGeneric);
+
+ XMLNode root_element = doc.GetRootElement("library-list");
+ if (!root_element)
+ return Error();
+
+ root_element.ForEachChildElementWithName(
+ "library", [log, &list](const XMLNode &library) -> bool {
+ LoadedModuleInfoList::LoadedModuleInfo module;
+
+ llvm::StringRef name = library.GetAttributeValue("name");
+ module.set_name(name.str());
+
+ // The base address of a given library will be the address of its
+ // first section. Most remotes send only one section for Windows
+ // targets for example.
+ const XMLNode &section =
+ library.FindFirstChildElementWithName("section");
+ llvm::StringRef address = section.GetAttributeValue("address");
+ module.set_base(
+ StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0));
+ // These addresses are absolute values.
+ module.set_base_is_offset(false);
+
+ if (log) {
+ std::string name;
+ lldb::addr_t base = 0;
+ bool base_is_offset;
+ module.get_name(name);
+ module.get_base(base);
+ module.get_base_is_offset(base_is_offset);
+
+ log->Printf("found (base:0x%08" PRIx64 "[%s], name:'%s')", base,
+ (base_is_offset ? "offset" : "absolute"), name.c_str());
+ }
+
+ list.add(module);
+ return true; // Keep iterating over all "library" elements in the root
+ // node
});
- if (log)
- log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());
- } else {
- return Error (0, ErrorType::eErrorTypeGeneric);
- }
+ if (log)
+ log->Printf("found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ } else {
+ return Error(0, ErrorType::eErrorTypeGeneric);
+ }
- return Error();
+ return Error();
}
-lldb::ModuleSP
-ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map,
- lldb::addr_t base_addr, bool value_is_offset)
-{
- DynamicLoader *loader = GetDynamicLoader();
- if (!loader)
- return nullptr;
+lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
+ lldb::addr_t link_map,
+ lldb::addr_t base_addr,
+ bool value_is_offset) {
+ DynamicLoader *loader = GetDynamicLoader();
+ if (!loader)
+ return nullptr;
- return loader->LoadModuleAtAddress(file, link_map, base_addr, value_is_offset);
+ return loader->LoadModuleAtAddress(file, link_map, base_addr,
+ value_is_offset);
}
-size_t
-ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
-{
- using lldb_private::process_gdb_remote::ProcessGDBRemote;
-
- // request a list of loaded libraries from GDBServer
- if (GetLoadedModuleList (module_list).Fail())
- return 0;
+size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
+ using lldb_private::process_gdb_remote::ProcessGDBRemote;
- // get a list of all the modules
- ModuleList new_modules;
+ // request a list of loaded libraries from GDBServer
+ if (GetLoadedModuleList(module_list).Fail())
+ return 0;
- for (LoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list)
- {
- std::string mod_name;
- lldb::addr_t mod_base;
- lldb::addr_t link_map;
- bool mod_base_is_offset;
-
- bool valid = true;
- valid &= modInfo.get_name (mod_name);
- valid &= modInfo.get_base (mod_base);
- valid &= modInfo.get_base_is_offset (mod_base_is_offset);
- if (!valid)
- continue;
-
- if (!modInfo.get_link_map (link_map))
- link_map = LLDB_INVALID_ADDRESS;
-
- FileSpec file (mod_name.c_str(), true);
- lldb::ModuleSP module_sp = LoadModuleAtAddress (file, link_map, mod_base,
- mod_base_is_offset);
-
- if (module_sp.get())
- new_modules.Append (module_sp);
- }
+ // get a list of all the modules
+ ModuleList new_modules;
+
+ for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list.m_list) {
+ std::string mod_name;
+ lldb::addr_t mod_base;
+ lldb::addr_t link_map;
+ bool mod_base_is_offset;
+
+ bool valid = true;
+ valid &= modInfo.get_name(mod_name);
+ valid &= modInfo.get_base(mod_base);
+ valid &= modInfo.get_base_is_offset(mod_base_is_offset);
+ if (!valid)
+ continue;
+
+ if (!modInfo.get_link_map(link_map))
+ link_map = LLDB_INVALID_ADDRESS;
+
+ FileSpec file(mod_name, true);
+ lldb::ModuleSP module_sp =
+ LoadModuleAtAddress(file, link_map, mod_base, mod_base_is_offset);
+
+ if (module_sp.get())
+ new_modules.Append(module_sp);
+ }
+
+ if (new_modules.GetSize() > 0) {
+ ModuleList removed_modules;
+ Target &target = GetTarget();
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+ for (size_t i = 0; i < loaded_modules.GetSize(); ++i) {
+ const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);
+
+ bool found = false;
+ for (size_t j = 0; j < new_modules.GetSize(); ++j) {
+ if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())
+ found = true;
+ }
+
+ // The main executable will never be included in libraries-svr4, don't
+ // remove it
+ if (!found &&
+ loaded_module.get() != target.GetExecutableModulePointer()) {
+ removed_modules.Append(loaded_module);
+ }
+ }
+
+ loaded_modules.Remove(removed_modules);
+ m_process->GetTarget().ModulesDidUnload(removed_modules, false);
+
+ new_modules.ForEach([&target](const lldb::ModuleSP module_sp) -> bool {
+ lldb_private::ObjectFile *obj = module_sp->GetObjectFile();
+ if (!obj)
+ return true;
- if (new_modules.GetSize() > 0)
- {
- ModuleList removed_modules;
- Target &target = GetTarget();
- ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+ if (obj->GetType() != ObjectFile::Type::eTypeExecutable)
+ return true;
- for (size_t i = 0; i < loaded_modules.GetSize(); ++i)
- {
- const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);
+ lldb::ModuleSP module_copy_sp = module_sp;
+ target.SetExecutableModule(module_copy_sp, false);
+ return false;
+ });
- bool found = false;
- for (size_t j = 0; j < new_modules.GetSize(); ++j)
- {
- if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())
- found = true;
- }
+ loaded_modules.AppendIfNeeded(new_modules);
+ m_process->GetTarget().ModulesDidLoad(new_modules);
+ }
- // The main executable will never be included in libraries-svr4, don't remove it
- if (!found && loaded_module.get() != target.GetExecutableModulePointer())
- {
- removed_modules.Append (loaded_module);
- }
- }
-
- loaded_modules.Remove (removed_modules);
- m_process->GetTarget().ModulesDidUnload (removed_modules, false);
+ return new_modules.GetSize();
+}
- new_modules.ForEach ([&target](const lldb::ModuleSP module_sp) -> bool
- {
- lldb_private::ObjectFile * obj = module_sp->GetObjectFile ();
- if (!obj)
- return true;
+size_t ProcessGDBRemote::LoadModules() {
+ LoadedModuleInfoList module_list;
+ return LoadModules(module_list);
+}
- if (obj->GetType () != ObjectFile::Type::eTypeExecutable)
- return true;
+Error ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
+ bool &is_loaded,
+ lldb::addr_t &load_addr) {
+ is_loaded = false;
+ load_addr = LLDB_INVALID_ADDRESS;
+
+ std::string file_path = file.GetPath(false);
+ if (file_path.empty())
+ return Error("Empty file name specified");
+
+ StreamString packet;
+ packet.PutCString("qFileLoadAddress:");
+ packet.PutCStringAsRawHex8(file_path.c_str());
+
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) !=
+ GDBRemoteCommunication::PacketResult::Success)
+ return Error("Sending qFileLoadAddress packet failed");
+
+ if (response.IsErrorResponse()) {
+ if (response.GetError() == 1) {
+ // The file is not loaded into the inferior
+ is_loaded = false;
+ load_addr = LLDB_INVALID_ADDRESS;
+ return Error();
+ }
+
+ return Error(
+ "Fetching file load address from remote server returned an error");
+ }
+
+ if (response.IsNormalResponse()) {
+ is_loaded = true;
+ load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+ return Error();
+ }
- lldb::ModuleSP module_copy_sp = module_sp;
- target.SetExecutableModule (module_copy_sp, false);
- return false;
- });
+ return Error("Unknown error happened during sending the load address packet");
+}
- loaded_modules.AppendIfNeeded (new_modules);
- m_process->GetTarget().ModulesDidLoad (new_modules);
- }
+void ProcessGDBRemote::ModulesDidLoad(ModuleList &module_list) {
+ // We must call the lldb_private::Process::ModulesDidLoad () first before we
+ // do anything
+ Process::ModulesDidLoad(module_list);
- return new_modules.GetSize();
+ // After loading shared libraries, we can ask our remote GDB server if
+ // it needs any symbols.
+ m_gdb_comm.ServeSymbolLookups(this);
}
-size_t
-ProcessGDBRemote::LoadModules ()
-{
- LoadedModuleInfoList module_list;
- return LoadModules (module_list);
+void ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out) {
+ AppendSTDOUT(out.data(), out.size());
}
-Error
-ProcessGDBRemote::GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr)
-{
- is_loaded = false;
- load_addr = LLDB_INVALID_ADDRESS;
-
- std::string file_path = file.GetPath(false);
- if (file_path.empty ())
- return Error("Empty file name specified");
-
- StreamString packet;
- packet.PutCString("qFileLoadAddress:");
- packet.PutCStringAsRawHex8(file_path.c_str());
-
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), response, false) != GDBRemoteCommunication::PacketResult::Success)
- return Error("Sending qFileLoadAddress packet failed");
+static const char *end_delimiter = "--end--;";
+static const int end_delimiter_len = 8;
+
+void ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data) {
+ std::string input = data.str(); // '1' to move beyond 'A'
+ if (m_partial_profile_data.length() > 0) {
+ m_partial_profile_data.append(input);
+ input = m_partial_profile_data;
+ m_partial_profile_data.clear();
+ }
+
+ size_t found, pos = 0, len = input.length();
+ while ((found = input.find(end_delimiter, pos)) != std::string::npos) {
+ StringExtractorGDBRemote profileDataExtractor(
+ input.substr(pos, found).c_str());
+ std::string profile_data =
+ HarmonizeThreadIdsForProfileData(profileDataExtractor);
+ BroadcastAsyncProfileData(profile_data);
+
+ pos = found + end_delimiter_len;
+ }
+
+ if (pos < len) {
+ // Last incomplete chunk.
+ m_partial_profile_data = input.substr(pos);
+ }
+}
- if (response.IsErrorResponse())
- {
- if (response.GetError() == 1)
- {
- // The file is not loaded into the inferior
- is_loaded = false;
- load_addr = LLDB_INVALID_ADDRESS;
- return Error();
+std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(
+ StringExtractorGDBRemote &profileDataExtractor) {
+ std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
+ std::string output;
+ llvm::raw_string_ostream output_stream(output);
+ llvm::StringRef name, value;
+
+ // Going to assuming thread_used_usec comes first, else bail out.
+ while (profileDataExtractor.GetNameColonValue(name, value)) {
+ if (name.compare("thread_used_id") == 0) {
+ StringExtractor threadIDHexExtractor(value);
+ uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
+
+ bool has_used_usec = false;
+ uint32_t curr_used_usec = 0;
+ llvm::StringRef usec_name, usec_value;
+ uint32_t input_file_pos = profileDataExtractor.GetFilePos();
+ if (profileDataExtractor.GetNameColonValue(usec_name, usec_value)) {
+ if (usec_name.equals("thread_used_usec")) {
+ has_used_usec = true;
+ usec_value.getAsInteger(0, curr_used_usec);
+ } else {
+ // We didn't find what we want, it is probably
+ // an older version. Bail out.
+ profileDataExtractor.SetFilePos(input_file_pos);
+ }
+ }
+
+ if (has_used_usec) {
+ uint32_t prev_used_usec = 0;
+ std::map<uint64_t, uint32_t>::iterator iterator =
+ m_thread_id_to_used_usec_map.find(thread_id);
+ if (iterator != m_thread_id_to_used_usec_map.end()) {
+ prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
}
- return Error("Fetching file load address from remote server returned an error");
- }
+ uint32_t real_used_usec = curr_used_usec - prev_used_usec;
+ // A good first time record is one that runs for at least 0.25 sec
+ bool good_first_time =
+ (prev_used_usec == 0) && (real_used_usec > 250000);
+ bool good_subsequent_time =
+ (prev_used_usec > 0) &&
+ ((real_used_usec > 0) || (HasAssignedIndexIDToThread(thread_id)));
+
+ if (good_first_time || good_subsequent_time) {
+ // We try to avoid doing too many index id reservation,
+ // resulting in fast increase of index ids.
+
+ output_stream << name << ":";
+ int32_t index_id = AssignIndexIDToThread(thread_id);
+ output_stream << index_id << ";";
+
+ output_stream << usec_name << ":" << usec_value << ";";
+ } else {
+ // Skip past 'thread_used_name'.
+ llvm::StringRef local_name, local_value;
+ profileDataExtractor.GetNameColonValue(local_name, local_value);
+ }
- if (response.IsNormalResponse())
- {
- is_loaded = true;
- load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
- return Error();
+ // Store current time as previous time so that they can be compared
+ // later.
+ new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
+ } else {
+ // Bail out and use old string.
+ output_stream << name << ":" << value << ";";
+ }
+ } else {
+ output_stream << name << ":" << value << ";";
}
+ }
+ output_stream << end_delimiter;
+ m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
- return Error("Unknown error happened during sending the load address packet");
+ return output_stream.str();
}
+void ProcessGDBRemote::HandleStopReply() {
+ if (GetStopID() != 0)
+ return;
-void
-ProcessGDBRemote::ModulesDidLoad (ModuleList &module_list)
-{
- // We must call the lldb_private::Process::ModulesDidLoad () first before we do anything
- Process::ModulesDidLoad (module_list);
-
- // After loading shared libraries, we can ask our remote GDB server if
- // it needs any symbols.
- m_gdb_comm.ServeSymbolLookups(this);
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ SetID(pid);
+ }
+ BuildDynamicRegisterInfo(true);
}
-
-class CommandObjectProcessGDBRemoteSpeedTest: public CommandObjectParsed
-{
-public:
- CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet speed-test",
- "Tests packet speeds of various sizes to determine the performance characteristics of the GDB remote connection. ",
- NULL),
- m_option_group (interpreter),
- m_num_packets (LLDB_OPT_SET_1, false, "count", 'c', 0, eArgTypeCount, "The number of packets to send of each varying size (default is 1000).", 1000),
- m_max_send (LLDB_OPT_SET_1, false, "max-send", 's', 0, eArgTypeCount, "The maximum number of bytes to send in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
- m_max_recv (LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount, "The maximum number of bytes to receive in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
- m_json (LLDB_OPT_SET_1, false, "json", 'j', "Print the output as JSON data for easy parsing.", false, true)
- {
- m_option_group.Append (&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectProcessGDBRemoteSpeedTest ()
- {
+static const char *const s_async_json_packet_prefix = "JSON-async:";
+
+static StructuredData::ObjectSP
+ParseStructuredDataPacket(llvm::StringRef packet) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+ if (!packet.consume_front(s_async_json_packet_prefix)) {
+ if (log) {
+ log->Printf(
+ "GDBRemoteCommmunicationClientBase::%s() received $J packet "
+ "but was not a StructuredData packet: packet starts with "
+ "%s",
+ __FUNCTION__,
+ packet.slice(0, strlen(s_async_json_packet_prefix)).str().c_str());
+ }
+ return StructuredData::ObjectSP();
+ }
+
+ // This is an asynchronous JSON packet, destined for a
+ // StructuredDataPlugin.
+ StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet);
+ if (log) {
+ if (json_sp) {
+ StreamString json_str;
+ json_sp->Dump(json_str);
+ json_str.Flush();
+ log->Printf("ProcessGDBRemote::%s() "
+ "received Async StructuredData packet: %s",
+ __FUNCTION__, json_str.GetData());
+ } else {
+ log->Printf("ProcessGDBRemote::%s"
+ "() received StructuredData packet:"
+ " parse failure",
+ __FUNCTION__);
}
+ }
+ return json_sp;
+}
+void ProcessGDBRemote::HandleAsyncStructuredDataPacket(llvm::StringRef data) {
+ auto structured_data_sp = ParseStructuredDataPacket(data);
+ if (structured_data_sp)
+ RouteAsyncStructuredData(structured_data_sp);
+}
- Options *
- GetOptions () override
- {
- return &m_option_group;
+class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed {
+public:
+ CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet speed-test",
+ "Tests packet speeds of various sizes to determine "
+ "the performance characteristics of the GDB remote "
+ "connection. ",
+ NULL),
+ m_option_group(),
+ m_num_packets(LLDB_OPT_SET_1, false, "count", 'c', 0, eArgTypeCount,
+ "The number of packets to send of each varying size "
+ "(default is 1000).",
+ 1000),
+ m_max_send(LLDB_OPT_SET_1, false, "max-send", 's', 0, eArgTypeCount,
+ "The maximum number of bytes to send in a packet. Sizes "
+ "increase in powers of 2 while the size is less than or "
+ "equal to this option value. (default 1024).",
+ 1024),
+ m_max_recv(LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount,
+ "The maximum number of bytes to receive in a packet. Sizes "
+ "increase in powers of 2 while the size is less than or "
+ "equal to this option value. (default 1024).",
+ 1024),
+ m_json(LLDB_OPT_SET_1, false, "json", 'j',
+ "Print the output as JSON data for easy parsing.", false, true) {
+ m_option_group.Append(&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectProcessGDBRemoteSpeedTest() {}
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext()
+ .GetProcessPtr();
+ if (process) {
+ StreamSP output_stream_sp(
+ m_interpreter.GetDebugger().GetAsyncOutputStream());
+ result.SetImmediateOutputStream(output_stream_sp);
+
+ const uint32_t num_packets =
+ (uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();
+ const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();
+ const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();
+ const bool json = m_json.GetOptionValue().GetCurrentValue();
+ const uint64_t k_recv_amount =
+ 4 * 1024 * 1024; // Receive amount in bytes
+ process->GetGDBRemote().TestPacketSpeed(
+ num_packets, max_send, max_recv, k_recv_amount, json,
+ output_stream_sp ? *output_stream_sp : result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
}
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- StreamSP output_stream_sp (m_interpreter.GetDebugger().GetAsyncOutputStream());
- result.SetImmediateOutputStream (output_stream_sp);
-
- const uint32_t num_packets = (uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();
- const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();
- const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();
- const bool json = m_json.GetOptionValue().GetCurrentValue();
- if (output_stream_sp)
- process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, *output_stream_sp);
- else
- {
- process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, result.GetOutputStream());
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
protected:
- OptionGroupOptions m_option_group;
- OptionGroupUInt64 m_num_packets;
- OptionGroupUInt64 m_max_send;
- OptionGroupUInt64 m_max_recv;
- OptionGroupBoolean m_json;
-
+ OptionGroupOptions m_option_group;
+ OptionGroupUInt64 m_num_packets;
+ OptionGroupUInt64 m_max_send;
+ OptionGroupUInt64 m_max_recv;
+ OptionGroupBoolean m_json;
};
-class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed {
private:
-
public:
- CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet history",
- "Dumps the packet history buffer. ",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketHistory ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- process->GetGDBRemote().DumpHistory(result.GetOutputStream());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
+ CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet history",
+ "Dumps the packet history buffer. ", NULL) {}
+
+ ~CommandObjectProcessGDBRemotePacketHistory() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext()
+ .GetProcessPtr();
+ if (process) {
+ process->GetGDBRemote().DumpHistory(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
}
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
};
-class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed {
private:
-
public:
- CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet xfer-size",
- "Maximum size that lldb will try to read/write one one chunk.",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketXferSize ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- result.AppendErrorWithFormat ("'%s' takes an argument to specify the max amount to be transferred when reading/writing", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- const char *packet_size = command.GetArgumentAtIndex(0);
- errno = 0;
- uint64_t user_specified_max = strtoul (packet_size, NULL, 10);
- if (errno == 0 && user_specified_max != 0)
- {
- process->SetUserSpecifiedMaxMemoryTransferSize (user_specified_max);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
+ CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "process plugin packet xfer-size",
+ "Maximum size that lldb will try to read/write one one chunk.",
+ NULL) {}
+
+ ~CommandObjectProcessGDBRemotePacketXferSize() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendErrorWithFormat("'%s' takes an argument to specify the max "
+ "amount to be transferred when "
+ "reading/writing",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ const char *packet_size = command.GetArgumentAtIndex(0);
+ errno = 0;
+ uint64_t user_specified_max = strtoul(packet_size, NULL, 10);
+ if (errno == 0 && user_specified_max != 0) {
+ process->SetUserSpecifiedMaxMemoryTransferSize(user_specified_max);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
}
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
};
-
-class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed {
private:
-
public:
- CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet send",
- "Send a custom packet through the GDB remote protocol and print the answer. "
- "The packet header and footer will automatically be added to the packet prior to sending and stripped from the result.",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketSend ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- result.AppendErrorWithFormat ("'%s' takes a one or more packet content arguments", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
+ CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet send",
+ "Send a custom packet through the GDB remote "
+ "protocol and print the answer. "
+ "The packet header and footer will automatically "
+ "be added to the packet prior to sending and "
+ "stripped from the result.",
+ NULL) {}
+
+ ~CommandObjectProcessGDBRemotePacketSend() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendErrorWithFormat(
+ "'%s' takes a one or more packet content arguments",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ for (size_t i = 0; i < argc; ++i) {
+ const char *packet_cstr = command.GetArgumentAtIndex(0);
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(
+ packet_cstr, response, send_async);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf(" packet: %s\n", packet_cstr);
+ std::string &response_str = response.GetStringRef();
+
+ if (strstr(packet_cstr, "qGetProfileData") != NULL) {
+ response_str = process->HarmonizeThreadIdsForProfileData(response);
}
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- for (size_t i=0; i<argc; ++ i)
- {
- const char *packet_cstr = command.GetArgumentAtIndex(0);
- bool send_async = true;
- StringExtractorGDBRemote response;
- process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- Stream &output_strm = result.GetOutputStream();
- output_strm.Printf (" packet: %s\n", packet_cstr);
- std::string &response_str = response.GetStringRef();
-
- if (strstr(packet_cstr, "qGetProfileData") != NULL)
- {
- response_str = process->GetGDBRemote().HarmonizeThreadIdsForProfileData(process, response);
- }
-
- if (response_str.empty())
- output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
- else
- output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
- }
- }
- return true;
+ if (response_str.empty())
+ output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
+ }
}
+ return true;
+ }
};
-class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw
-{
+class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw {
private:
-
public:
- CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "process plugin packet monitor",
- "Send a qRcmd packet through the GDB remote protocol and print the response."
- "The argument passed to this command will be hex encoded into a valid 'qRcmd' packet, sent and the response will be printed.",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketMonitor ()
- {
- }
-
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- if (command == NULL || command[0] == '\0')
- {
- result.AppendErrorWithFormat ("'%s' takes a command string argument", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- StreamString packet;
- packet.PutCString("qRcmd,");
- packet.PutBytesAsRawHex8(command, strlen(command));
- const char *packet_cstr = packet.GetString().c_str();
-
- bool send_async = true;
- StringExtractorGDBRemote response;
- process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- Stream &output_strm = result.GetOutputStream();
- output_strm.Printf (" packet: %s\n", packet_cstr);
- const std::string &response_str = response.GetStringRef();
-
- if (response_str.empty())
- output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
- else
- output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
- }
- return true;
+ CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "process plugin packet monitor",
+ "Send a qRcmd packet through the GDB remote protocol "
+ "and print the response."
+ "The argument passed to this command will be hex "
+ "encoded into a valid 'qRcmd' packet, sent and the "
+ "response will be printed.") {}
+
+ ~CommandObjectProcessGDBRemotePacketMonitor() {}
+
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ if (command == NULL || command[0] == '\0') {
+ result.AppendErrorWithFormat("'%s' takes a command string argument",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ StreamString packet;
+ packet.PutCString("qRcmd,");
+ packet.PutBytesAsRawHex8(command, strlen(command));
+
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(
+ packet.GetString(), response, send_async);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf(" packet: %s\n", packet.GetData());
+ const std::string &response_str = response.GetStringRef();
+
+ if (response_str.empty())
+ output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
}
+ return true;
+ }
};
-class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword
-{
+class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword {
private:
-
public:
- CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "process plugin packet",
- "Commands that deal with GDB remote packets.",
- NULL)
- {
- LoadSubCommand ("history", CommandObjectSP (new CommandObjectProcessGDBRemotePacketHistory (interpreter)));
- LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessGDBRemotePacketSend (interpreter)));
- LoadSubCommand ("monitor", CommandObjectSP (new CommandObjectProcessGDBRemotePacketMonitor (interpreter)));
- LoadSubCommand ("xfer-size", CommandObjectSP (new CommandObjectProcessGDBRemotePacketXferSize (interpreter)));
- LoadSubCommand ("speed-test", CommandObjectSP (new CommandObjectProcessGDBRemoteSpeedTest (interpreter)));
- }
-
- ~CommandObjectProcessGDBRemotePacket ()
- {
- }
+ CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process plugin packet",
+ "Commands that deal with GDB remote packets.",
+ NULL) {
+ LoadSubCommand(
+ "history",
+ CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketHistory(interpreter)));
+ LoadSubCommand(
+ "send", CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketSend(interpreter)));
+ LoadSubCommand(
+ "monitor",
+ CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketMonitor(interpreter)));
+ LoadSubCommand(
+ "xfer-size",
+ CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketXferSize(interpreter)));
+ LoadSubCommand("speed-test",
+ CommandObjectSP(new CommandObjectProcessGDBRemoteSpeedTest(
+ interpreter)));
+ }
+
+ ~CommandObjectProcessGDBRemotePacket() {}
};
-class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword
-{
+class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {
public:
- CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessGDBRemote process.",
- "process plugin <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket (interpreter)));
- }
-
- ~CommandObjectMultiwordProcessGDBRemote ()
- {
- }
+ CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "process plugin",
+ "Commands for operating on a ProcessGDBRemote process.",
+ "process plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "packet",
+ CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));
+ }
+
+ ~CommandObjectMultiwordProcessGDBRemote() {}
};
-CommandObject *
-ProcessGDBRemote::GetPluginCommandObject()
-{
- if (!m_command_sp)
- m_command_sp.reset (new CommandObjectMultiwordProcessGDBRemote (GetTarget().GetDebugger().GetCommandInterpreter()));
- return m_command_sp.get();
+CommandObject *ProcessGDBRemote::GetPluginCommandObject() {
+ if (!m_command_sp)
+ m_command_sp.reset(new CommandObjectMultiwordProcessGDBRemote(
+ GetTarget().GetDebugger().GetCommandInterpreter()));
+ return m_command_sp.get();
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 6d373965fc42..6423abc55836 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -24,462 +24,425 @@
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/LoadedModuleInfoList.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/ThreadSafeValue.h"
-#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/lldb-private-forward.h"
-#include "lldb/Utility/StringExtractor.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/StringExtractor.h"
+#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationClient.h"
#include "GDBRemoteRegisterContext.h"
+#include "llvm/ADT/DenseMap.h"
+
namespace lldb_private {
namespace process_gdb_remote {
class ThreadGDBRemote;
-class ProcessGDBRemote : public Process
-{
+class ProcessGDBRemote : public Process,
+ private GDBRemoteClientBase::ContinueDelegate {
public:
- ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+ ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
- ~ProcessGDBRemote() override;
+ ~ProcessGDBRemote() override;
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path);
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path);
- static void
- Initialize();
+ static void Initialize();
- static void
- DebuggerInitialize (Debugger &debugger);
+ static void DebuggerInitialize(Debugger &debugger);
- static void
- Terminate();
+ static void Terminate();
- static ConstString
- GetPluginNameStatic();
+ static ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool
- CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
- CommandObject *
- GetPluginCommandObject() override;
+ CommandObject *GetPluginCommandObject() override;
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- Error
- WillLaunch (Module* module) override;
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ Error WillLaunch(Module *module) override;
- Error
- DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) override;
+ Error DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
- void
- DidLaunch () override;
-
- Error
- WillAttachToProcessWithID (lldb::pid_t pid) override;
-
- Error
- WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) override;
+ void DidLaunch() override;
- Error
- DoConnectRemote (Stream *strm, const char *remote_url) override;
-
- Error
- WillLaunchOrAttach ();
-
- Error
- DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) override;
-
- Error
- DoAttachToProcessWithName (const char *process_name,
- const ProcessAttachInfo &attach_info) override;
-
- void
- DidAttach (ArchSpec &process_arch) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- Error
- WillResume () override;
-
- Error
- DoResume () override;
-
- Error
- DoHalt (bool &caused_stop) override;
-
- Error
- DoDetach (bool keep_stopped) override;
-
- bool
- DetachRequiresHalt() override { return true; }
-
- Error
- DoSignal (int signal) override;
-
- Error
- DoDestroy () override;
-
- void
- RefreshStateAfterStop() override;
-
- void
- SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool
- IsAlive () override;
-
- lldb::addr_t
- GetImageInfoAddress() override;
-
- void
- WillPublicStop () override;
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t
- DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error) override;
-
- size_t
- DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, Error &error) override;
-
- lldb::addr_t
- DoAllocateMemory (size_t size, uint32_t permissions, Error &error) override;
-
- Error
- GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &region_info) override;
-
- Error
- DoDeallocateMemory (lldb::addr_t ptr) override;
-
- //------------------------------------------------------------------
- // Process STDIO
- //------------------------------------------------------------------
- size_t
- PutSTDIN (const char *buf, size_t buf_size, Error &error) override;
-
- //----------------------------------------------------------------------
- // Process Breakpoints
- //----------------------------------------------------------------------
- Error
- EnableBreakpointSite (BreakpointSite *bp_site) override;
-
- Error
- DisableBreakpointSite (BreakpointSite *bp_site) override;
-
- //----------------------------------------------------------------------
- // Process Watchpoints
- //----------------------------------------------------------------------
- Error
- EnableWatchpoint (Watchpoint *wp, bool notify = true) override;
-
- Error
- DisableWatchpoint (Watchpoint *wp, bool notify = true) override;
-
- Error
- GetWatchpointSupportInfo (uint32_t &num) override;
-
- Error
- GetWatchpointSupportInfo (uint32_t &num, bool& after) override;
-
- bool
- StartNoticingNewThreads() override;
-
- bool
- StopNoticingNewThreads() override;
-
- GDBRemoteCommunicationClient &
- GetGDBRemote()
- {
- return m_gdb_comm;
- }
-
- Error
- SendEventData(const char *data) override;
+ Error WillAttachToProcessWithID(lldb::pid_t pid) override;
+
+ Error WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) override;
+
+ Error DoConnectRemote(Stream *strm, llvm::StringRef remote_url) override;
+
+ Error WillLaunchOrAttach();
+
+ Error DoAttachToProcessWithID(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) override;
+
+ Error
+ DoAttachToProcessWithName(const char *process_name,
+ const ProcessAttachInfo &attach_info) override;
+
+ void DidAttach(ArchSpec &process_arch) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ Error WillResume() override;
+
+ Error DoResume() override;
+
+ Error DoHalt(bool &caused_stop) override;
+
+ Error DoDetach(bool keep_stopped) override;
+
+ bool DetachRequiresHalt() override { return true; }
+
+ Error DoSignal(int signal) override;
+
+ Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
+
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
+
+ lldb::addr_t GetImageInfoAddress() override;
+
+ void WillPublicStop() override;
+
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) override;
+
+ size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ Error &error) override;
+
+ lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+ Error &error) override;
+
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) override;
- //----------------------------------------------------------------------
- // Override DidExit so we can disconnect from the remote GDB server
- //----------------------------------------------------------------------
- void
- DidExit () override;
+ Error DoDeallocateMemory(lldb::addr_t ptr) override;
- void
- SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max);
+ //------------------------------------------------------------------
+ // Process STDIO
+ //------------------------------------------------------------------
+ size_t PutSTDIN(const char *buf, size_t buf_size, Error &error) override;
- bool
- GetModuleSpec(const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec) override;
+ //----------------------------------------------------------------------
+ // Process Breakpoints
+ //----------------------------------------------------------------------
+ Error EnableBreakpointSite(BreakpointSite *bp_site) override;
- bool
- GetHostOSVersion(uint32_t &major,
- uint32_t &minor,
- uint32_t &update) override;
+ Error DisableBreakpointSite(BreakpointSite *bp_site) override;
- size_t
- LoadModules(LoadedModuleInfoList &module_list) override;
+ //----------------------------------------------------------------------
+ // Process Watchpoints
+ //----------------------------------------------------------------------
+ Error EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
- size_t
- LoadModules() override;
+ Error DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
- Error
- GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr) override;
+ Error GetWatchpointSupportInfo(uint32_t &num) override;
- void
- ModulesDidLoad (ModuleList &module_list) override;
+ Error GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
- StructuredData::ObjectSP
- GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override;
+ bool StartNoticingNewThreads() override;
+
+ bool StopNoticingNewThreads() override;
+
+ GDBRemoteCommunicationClient &GetGDBRemote() { return m_gdb_comm; }
+
+ Error SendEventData(const char *data) override;
+
+ //----------------------------------------------------------------------
+ // Override DidExit so we can disconnect from the remote GDB server
+ //----------------------------------------------------------------------
+ void DidExit() override;
+
+ void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max);
+
+ bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
+ ModuleSpec &module_spec) override;
+
+ void PrefetchModuleSpecs(llvm::ArrayRef<FileSpec> module_file_specs,
+ const llvm::Triple &triple) override;
+
+ bool GetHostOSVersion(uint32_t &major, uint32_t &minor,
+ uint32_t &update) override;
+
+ size_t LoadModules(LoadedModuleInfoList &module_list) override;
+
+ size_t LoadModules() override;
+
+ Error GetFileLoadAddress(const FileSpec &file, bool &is_loaded,
+ lldb::addr_t &load_addr) override;
+
+ void ModulesDidLoad(ModuleList &module_list) override;
+
+ StructuredData::ObjectSP
+ GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address,
+ lldb::addr_t image_count) override;
+
+ Error
+ ConfigureStructuredData(const ConstString &type_name,
+ const StructuredData::ObjectSP &config_sp) override;
+
+ StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override;
+
+ StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(
+ const std::vector<lldb::addr_t> &load_addresses) override;
+
+ StructuredData::ObjectSP
+ GetLoadedDynamicLibrariesInfos_sender(StructuredData::ObjectSP args);
+
+ StructuredData::ObjectSP GetSharedCacheInfo() override;
+
+ std::string HarmonizeThreadIdsForProfileData(
+ StringExtractorGDBRemote &inputStringExtractor);
protected:
- friend class ThreadGDBRemote;
- friend class GDBRemoteCommunicationClient;
- friend class GDBRemoteRegisterContext;
-
- //------------------------------------------------------------------
- /// Broadcaster event bits definitions.
- //------------------------------------------------------------------
- enum
- {
- eBroadcastBitAsyncContinue = (1 << 0),
- eBroadcastBitAsyncThreadShouldExit = (1 << 1),
- eBroadcastBitAsyncThreadDidExit = (1 << 2)
- };
-
- Flags m_flags; // Process specific flags (see eFlags enums)
- GDBRemoteCommunicationClient m_gdb_comm;
- std::atomic<lldb::pid_t> m_debugserver_pid;
- std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet stack replaces the last stop packet variable
- std::recursive_mutex m_last_stop_packet_mutex;
- GDBRemoteDynamicRegisterInfo m_register_info;
- Broadcaster m_async_broadcaster;
- lldb::ListenerSP m_async_listener_sp;
- HostThread m_async_thread;
- std::recursive_mutex m_async_thread_state_mutex;
- typedef std::vector<lldb::tid_t> tid_collection;
- typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
- typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
- typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
- tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping
- std::vector<lldb::addr_t> m_thread_pcs; // PC values for all the threads.
- StructuredData::ObjectSP m_jstopinfo_sp; // Stop info only for any threads that have valid stop infos
- StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited registers and memory for all threads if "jThreadsInfo" packet is supported
- tid_collection m_continue_c_tids; // 'c' for continue
- tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
- tid_collection m_continue_s_tids; // 's' for step
- tid_sig_collection m_continue_S_tids; // 'S' for step with signal
- uint64_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory
- uint64_t m_remote_stub_max_memory_size; // The maximum memory size the remote gdb stub can handle
- MMapMap m_addr_to_mmap_size;
- lldb::BreakpointSP m_thread_create_bp_sp;
- bool m_waiting_for_attach;
- bool m_destroy_tried_resuming;
- lldb::CommandObjectSP m_command_sp;
- int64_t m_breakpoint_pc_offset;
- lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
-
- //----------------------------------------------------------------------
- // Accessors
- //----------------------------------------------------------------------
- bool
- IsRunning ( lldb::StateType state )
- {
- return state == lldb::eStateRunning || IsStepping(state);
- }
+ friend class ThreadGDBRemote;
+ friend class GDBRemoteCommunicationClient;
+ friend class GDBRemoteRegisterContext;
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum {
+ eBroadcastBitAsyncContinue = (1 << 0),
+ eBroadcastBitAsyncThreadShouldExit = (1 << 1),
+ eBroadcastBitAsyncThreadDidExit = (1 << 2)
+ };
- bool
- IsStepping ( lldb::StateType state)
- {
- return state == lldb::eStateStepping;
- }
+ Flags m_flags; // Process specific flags (see eFlags enums)
+ GDBRemoteCommunicationClient m_gdb_comm;
+ std::atomic<lldb::pid_t> m_debugserver_pid;
+ std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet
+ // stack replaces
+ // the last stop
+ // packet variable
+ std::recursive_mutex m_last_stop_packet_mutex;
+ GDBRemoteDynamicRegisterInfo m_register_info;
+ Broadcaster m_async_broadcaster;
+ lldb::ListenerSP m_async_listener_sp;
+ HostThread m_async_thread;
+ std::recursive_mutex m_async_thread_state_mutex;
+ typedef std::vector<lldb::tid_t> tid_collection;
+ typedef std::vector<std::pair<lldb::tid_t, int>> tid_sig_collection;
+ typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+ typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
+ tid_collection m_thread_ids; // Thread IDs for all threads. This list gets
+ // updated after stopping
+ std::vector<lldb::addr_t> m_thread_pcs; // PC values for all the threads.
+ StructuredData::ObjectSP m_jstopinfo_sp; // Stop info only for any threads
+ // that have valid stop infos
+ StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited
+ // registers and memory for all
+ // threads if "jThreadsInfo"
+ // packet is supported
+ tid_collection m_continue_c_tids; // 'c' for continue
+ tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
+ tid_collection m_continue_s_tids; // 's' for step
+ tid_sig_collection m_continue_S_tids; // 'S' for step with signal
+ uint64_t m_max_memory_size; // The maximum number of bytes to read/write when
+ // reading and writing memory
+ uint64_t m_remote_stub_max_memory_size; // The maximum memory size the remote
+ // gdb stub can handle
+ MMapMap m_addr_to_mmap_size;
+ lldb::BreakpointSP m_thread_create_bp_sp;
+ bool m_waiting_for_attach;
+ bool m_destroy_tried_resuming;
+ lldb::CommandObjectSP m_command_sp;
+ int64_t m_breakpoint_pc_offset;
+ lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
- bool
- CanResume ( lldb::StateType state)
- {
- return state == lldb::eStateStopped;
- }
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+ bool IsRunning(lldb::StateType state) {
+ return state == lldb::eStateRunning || IsStepping(state);
+ }
- bool
- HasExited (lldb::StateType state)
- {
- return state == lldb::eStateExited;
- }
+ bool IsStepping(lldb::StateType state) {
+ return state == lldb::eStateStepping;
+ }
- bool
- ProcessIDIsValid ( ) const;
+ bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }
- void
- Clear ( );
+ bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }
- Flags &
- GetFlags ()
- {
- return m_flags;
- }
+ bool ProcessIDIsValid() const;
- const Flags &
- GetFlags () const
- {
- return m_flags;
- }
+ void Clear();
+
+ Flags &GetFlags() { return m_flags; }
- bool
- UpdateThreadList (ThreadList &old_thread_list,
- ThreadList &new_thread_list) override;
+ const Flags &GetFlags() const { return m_flags; }
- Error
- EstablishConnectionIfNeeded (const ProcessInfo &process_info);
+ bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
- Error
- LaunchAndConnectToDebugserver (const ProcessInfo &process_info);
+ Error EstablishConnectionIfNeeded(const ProcessInfo &process_info);
- void
- KillDebugserverProcess ();
+ Error LaunchAndConnectToDebugserver(const ProcessInfo &process_info);
- void
- BuildDynamicRegisterInfo (bool force);
+ void KillDebugserverProcess();
- void
- SetLastStopPacket (const StringExtractorGDBRemote &response);
+ void BuildDynamicRegisterInfo(bool force);
- bool
- ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);
+ void SetLastStopPacket(const StringExtractorGDBRemote &response);
- const lldb::DataBufferSP
- GetAuxvData() override;
+ bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);
- StructuredData::ObjectSP
- GetExtendedInfoForThread (lldb::tid_t tid);
+ const lldb::DataBufferSP GetAuxvData() override;
- void
- GetMaxMemorySize();
+ StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid);
- bool
- CalculateThreadStopInfo (ThreadGDBRemote *thread);
+ void GetMaxMemorySize();
- size_t
- UpdateThreadPCsFromStopReplyThreadsValue (std::string &value);
+ bool CalculateThreadStopInfo(ThreadGDBRemote *thread);
- size_t
- UpdateThreadIDsFromStopReplyThreadsValue (std::string &value);
+ size_t UpdateThreadPCsFromStopReplyThreadsValue(std::string &value);
- bool
- HandleNotifyPacket(StringExtractorGDBRemote &packet);
+ size_t UpdateThreadIDsFromStopReplyThreadsValue(std::string &value);
- bool
- StartAsyncThread ();
+ bool HandleNotifyPacket(StringExtractorGDBRemote &packet);
- void
- StopAsyncThread ();
+ bool StartAsyncThread();
- static lldb::thread_result_t
- AsyncThread (void *arg);
+ void StopAsyncThread();
- static bool
- MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t pid, bool exited, int signo,
- int exit_status);
+ static lldb::thread_result_t AsyncThread(void *arg);
- lldb::StateType
- SetThreadStopInfo (StringExtractor& stop_packet);
+ static bool
+ MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp,
+ lldb::pid_t pid, bool exited, int signo,
+ int exit_status);
- bool
- GetThreadStopInfoFromJSON (ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp);
+ lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet);
- lldb::ThreadSP
- SetThreadStopInfo (StructuredData::Dictionary *thread_dict);
+ bool
+ GetThreadStopInfoFromJSON(ThreadGDBRemote *thread,
+ const StructuredData::ObjectSP &thread_infos_sp);
- lldb::ThreadSP
- SetThreadStopInfo (lldb::tid_t tid,
- ExpeditedRegisterMap &expedited_register_map,
- uint8_t signo,
- const std::string &thread_name,
- const std::string &reason,
- const std::string &description,
- uint32_t exc_type,
- const std::vector<lldb::addr_t> &exc_data,
- lldb::addr_t thread_dispatch_qaddr,
- bool queue_vars_valid,
- lldb_private::LazyBool associated_with_libdispatch_queue,
- lldb::addr_t dispatch_queue_t,
- std::string &queue_name,
- lldb::QueueKind queue_kind,
- uint64_t queue_serial);
+ lldb::ThreadSP SetThreadStopInfo(StructuredData::Dictionary *thread_dict);
- void
- HandleStopReplySequence ();
+ lldb::ThreadSP
+ SetThreadStopInfo(lldb::tid_t tid,
+ ExpeditedRegisterMap &expedited_register_map, uint8_t signo,
+ const std::string &thread_name, const std::string &reason,
+ const std::string &description, uint32_t exc_type,
+ const std::vector<lldb::addr_t> &exc_data,
+ lldb::addr_t thread_dispatch_qaddr, bool queue_vars_valid,
+ lldb_private::LazyBool associated_with_libdispatch_queue,
+ lldb::addr_t dispatch_queue_t, std::string &queue_name,
+ lldb::QueueKind queue_kind, uint64_t queue_serial);
- void
- ClearThreadIDList ();
+ void HandleStopReplySequence();
- bool
- UpdateThreadIDList ();
+ void ClearThreadIDList();
- void
- DidLaunchOrAttach (ArchSpec& process_arch);
+ bool UpdateThreadIDList();
- Error
- ConnectToDebugserver (const char *host_port);
+ void DidLaunchOrAttach(ArchSpec &process_arch);
- const char *
- GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr,
- std::string &dispatch_queue_name);
+ Error ConnectToDebugserver(llvm::StringRef host_port);
- DynamicLoader *
- GetDynamicLoader () override;
+ const char *GetDispatchQueueNameForThread(lldb::addr_t thread_dispatch_qaddr,
+ std::string &dispatch_queue_name);
- // Query remote GDBServer for register information
- bool
- GetGDBServerRegisterInfo (ArchSpec &arch);
+ DynamicLoader *GetDynamicLoader() override;
- // Query remote GDBServer for a detailed loaded library list
- Error
- GetLoadedModuleList (LoadedModuleInfoList &);
+ // Query remote GDBServer for register information
+ bool GetGDBServerRegisterInfo(ArchSpec &arch);
- lldb::ModuleSP
- LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr,
- bool value_is_offset);
+ // Query remote GDBServer for a detailed loaded library list
+ Error GetLoadedModuleList(LoadedModuleInfoList &);
+
+ lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file,
+ lldb::addr_t link_map,
+ lldb::addr_t base_addr,
+ bool value_is_offset);
private:
- //------------------------------------------------------------------
- // For ProcessGDBRemote only
- //------------------------------------------------------------------
- static bool
- NewThreadNotifyBreakpointHit (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);
+ //------------------------------------------------------------------
+ // For ProcessGDBRemote only
+ //------------------------------------------------------------------
+ std::string m_partial_profile_data;
+ std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
+
+ static bool NewThreadNotifyBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ //------------------------------------------------------------------
+ // ContinueDelegate interface
+ //------------------------------------------------------------------
+ void HandleAsyncStdout(llvm::StringRef out) override;
+ void HandleAsyncMisc(llvm::StringRef data) override;
+ void HandleStopReply() override;
+ void HandleAsyncStructuredDataPacket(llvm::StringRef data) override;
+
+ using ModuleCacheKey = std::pair<std::string, std::string>;
+ // KeyInfo for the cached module spec DenseMap.
+ // The invariant is that all real keys will have the file and architecture
+ // set.
+ // The empty key has an empty file and an empty arch.
+ // The tombstone key has an invalid arch and an empty file.
+ // The comparison and hash functions take the file name and architecture
+ // triple into account.
+ struct ModuleCacheInfo {
+ static ModuleCacheKey getEmptyKey() { return ModuleCacheKey(); }
+
+ static ModuleCacheKey getTombstoneKey() { return ModuleCacheKey("", "T"); }
+
+ static unsigned getHashValue(const ModuleCacheKey &key) {
+ return llvm::hash_combine(key.first, key.second);
+ }
+
+ static bool isEqual(const ModuleCacheKey &LHS, const ModuleCacheKey &RHS) {
+ return LHS == RHS;
+ }
+ };
+
+ llvm::DenseMap<ModuleCacheKey, ModuleSpec, ModuleCacheInfo>
+ m_cached_module_specs;
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessGDBRemote);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
index d4726adc890e..899037ae98aa 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -11,8 +11,8 @@
#include <mutex>
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
#include "ProcessGDBRemote.h"
@@ -20,196 +20,198 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_lob_sp the first time this function is
+// that will construct the static g_lob_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = NULL;
-static Log *
-GetLog ()
-{
- if (!g_log_enabled)
- return NULL;
- return g_log;
+static Log *g_log = NULL;
+static Log *GetLog() {
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-void
-ProcessGDBRemoteLog::Initialize()
-{
- static ConstString g_name("gdb-remote");
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, [](){
- Log::Callbacks log_callbacks = {
- DisableLog,
- EnableLog,
- ListLogCategories
- };
-
- Log::RegisterLogChannel (g_name, log_callbacks);
- });
-}
+void ProcessGDBRemoteLog::Initialize() {
+ static ConstString g_name("gdb-remote");
+ static std::once_flag g_once_flag;
-Log *
-ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && mask)
- {
- uint32_t log_mask = log->GetMask().Get();
- if ((log_mask & mask) != mask)
- return NULL;
- }
- return log;
+ std::call_once(g_once_flag, []() {
+ Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
+
+ Log::RegisterLogChannel(g_name, log_callbacks);
+ });
}
-Log *
-ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && log->GetMask().Get() & mask)
- return log;
- return NULL;
+Log *ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && mask) {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return NULL;
+ }
+ return log;
}
-void
-ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm)
-{
- Log *log (GetLog ());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- if (categories[0] != NULL)
- {
- flag_bits = log->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~GDBR_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~GDBR_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~GDBR_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~GDBR_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~GDBR_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~GDBR_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~GDBR_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~GDBR_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~GDBR_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~GDBR_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~GDBR_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- }
-
- }
- }
-
- if (flag_bits == 0)
- g_log_enabled = false;
- else
- log->GetMask().Reset (flag_bits);
- }
-
- return;
+Log *ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && log->GetMask().Get() & mask)
+ return log;
+ return NULL;
}
-Log *
-ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
+void ProcessGDBRemoteLog::DisableLog(const char **categories,
+ Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
+
+ if (categories && categories[0]) {
+ flag_bits = log->GetMask().Get();
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits &= ~GDBR_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits &= ~GDBR_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits &= ~GDBR_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits &= ~GDBR_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits &= ~GDBR_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits &= ~GDBR_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits &= ~GDBR_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits &= ~GDBR_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits &= ~GDBR_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits &= ~GDBR_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits &= ~GDBR_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits &= ~GDBR_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
+ }
+ }
}
+ if (flag_bits == 0)
+ g_log_enabled = false;
+ else
+ log->GetMask().Reset(flag_bits);
+ }
+
+ return;
+}
+
+Log *ProcessGDBRemoteLog::EnableLog(StreamSP &log_stream_sp,
+ uint32_t log_options,
+ const char **categories,
+ Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (size_t i=0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits |= GDBR_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= GDBR_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= GDBR_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= GDBR_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= GDBR_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= GDBR_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= GDBR_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= GDBR_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= GDBR_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= GDBR_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= GDBR_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= GDBR_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits |= GDBR_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits |= GDBR_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits |= GDBR_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits |= GDBR_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits |= GDBR_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits |= GDBR_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits |= GDBR_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits |= GDBR_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits |= GDBR_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits |= GDBR_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits |= GDBR_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits |= GDBR_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits |= GDBR_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = GDBR_LOG_DEFAULT;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
+ }
}
- g_log_enabled = true;
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = GDBR_LOG_DEFAULT;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ }
+ g_log_enabled = true;
+ return g_log;
}
-void
-ProcessGDBRemoteLog::ListLogCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " async - log asynchronous activity\n"
- " break - log breakpoints\n"
- " communication - log communication activity\n"
- " default - enable the default set of logging categories for liblldb\n"
- " packets - log gdb remote packets\n"
- " memory - log memory reads and writes\n"
- " data-short - log memory bytes for memory reads and writes for short transactions only\n"
- " data-long - log memory bytes for memory reads and writes for all transactions\n"
- " process - log process events and activities\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic().GetCString());
+void ProcessGDBRemoteLog::ListLogCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " async - log asynchronous activity\n"
+ " break - log breakpoints\n"
+ " communication - log communication activity\n"
+ " default - enable the default set of logging categories for liblldb\n"
+ " packets - log gdb remote packets\n"
+ " memory - log memory reads and writes\n"
+ " data-short - log memory bytes for memory reads and writes for short "
+ "transactions only\n"
+ " data-long - log memory bytes for memory reads and writes for all "
+ "transactions\n"
+ " process - log process events and activities\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n"
+ " watch - log watchpoint related activities\n",
+ ProcessGDBRemote::GetPluginNameStatic().GetCString());
}
-
-void
-ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
- if (log)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void ProcessGDBRemoteLog::LogIf(uint32_t mask, const char *format, ...) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(mask));
+ if (log) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index 3cd974d7d821..f5e92b450614 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -17,50 +17,44 @@
// Project includes
#include "lldb/Core/Log.h"
-#define GDBR_LOG_VERBOSE (1u << 0)
-#define GDBR_LOG_PROCESS (1u << 1)
-#define GDBR_LOG_THREAD (1u << 2)
-#define GDBR_LOG_PACKETS (1u << 3)
-#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define GDBR_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
-#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define GDBR_LOG_BREAKPOINTS (1u << 7)
-#define GDBR_LOG_WATCHPOINTS (1u << 8)
-#define GDBR_LOG_STEP (1u << 9)
-#define GDBR_LOG_COMM (1u << 10)
-#define GDBR_LOG_ASYNC (1u << 11)
-#define GDBR_LOG_ALL (UINT32_MAX)
-#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS
+#define GDBR_LOG_VERBOSE (1u << 0)
+#define GDBR_LOG_PROCESS (1u << 1)
+#define GDBR_LOG_THREAD (1u << 2)
+#define GDBR_LOG_PACKETS (1u << 3)
+#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define GDBR_LOG_MEMORY_DATA_SHORT \
+ (1u << 5) // Log short memory reads/writes bytes
+#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
+#define GDBR_LOG_BREAKPOINTS (1u << 7)
+#define GDBR_LOG_WATCHPOINTS (1u << 8)
+#define GDBR_LOG_STEP (1u << 9)
+#define GDBR_LOG_COMM (1u << 10)
+#define GDBR_LOG_ASYNC (1u << 11)
+#define GDBR_LOG_ALL (UINT32_MAX)
+#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS
namespace lldb_private {
namespace process_gdb_remote {
-class ProcessGDBRemoteLog
-{
+class ProcessGDBRemoteLog {
public:
- static void
- Initialize();
+ static void Initialize();
- static Log *
- GetLogIfAllCategoriesSet(uint32_t mask = 0);
-
- static Log *
- GetLogIfAnyCategoryIsSet (uint32_t mask);
+ static Log *GetLogIfAllCategoriesSet(uint32_t mask = 0);
- static void
- DisableLog (const char **categories, Stream *feedback_strm);
+ static Log *GetLogIfAnyCategoryIsSet(uint32_t mask);
- static Log *
- EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm);
+ static void DisableLog(const char **categories, Stream *feedback_strm);
- static void
- ListLogCategories (Stream *strm);
+ static Log *EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options,
+ const char **categories, Stream *feedback_strm);
- static void
- LogIf (uint32_t mask, const char *format, ...);
+ static void ListLogCategories(Stream *strm);
+
+ static void LogIf(uint32_t mask, const char *format, ...);
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_ProcessGDBRemoteLog_h_
+#endif // liblldb_ProcessGDBRemoteLog_h_
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index a4af12c492c1..ab552145a18b 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "ThreadGDBRemote.h"
#include "lldb/Breakpoint/Watchpoint.h"
@@ -36,372 +35,318 @@ using namespace lldb_private::process_gdb_remote;
// Thread Registers
//----------------------------------------------------------------------
-ThreadGDBRemote::ThreadGDBRemote (Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_thread_name (),
- m_dispatch_queue_name (),
- m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
- m_dispatch_queue_t (LLDB_INVALID_ADDRESS),
- m_queue_kind (eQueueKindUnknown),
- m_queue_serial_number (LLDB_INVALID_QUEUE_ID),
- m_associated_with_libdispatch_queue (eLazyBoolCalculate)
-{
- ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
- this,
- process.GetID(),
- GetID());
+ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
+ : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
+ m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS),
+ m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),
+ m_queue_serial_number(LLDB_INVALID_QUEUE_ID),
+ m_associated_with_libdispatch_queue(eLazyBoolCalculate) {
+ ProcessGDBRemoteLog::LogIf(
+ GDBR_LOG_THREAD,
+ "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this,
+ process.GetID(), GetID());
}
-ThreadGDBRemote::~ThreadGDBRemote ()
-{
- ProcessSP process_sp(GetProcess());
- ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
- this,
- process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID,
- GetID());
- DestroyThread();
+ThreadGDBRemote::~ThreadGDBRemote() {
+ ProcessSP process_sp(GetProcess());
+ ProcessGDBRemoteLog::LogIf(
+ GDBR_LOG_THREAD,
+ "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this,
+ process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());
+ DestroyThread();
}
-const char *
-ThreadGDBRemote::GetName ()
-{
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+const char *ThreadGDBRemote::GetName() {
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
}
-void
-ThreadGDBRemote::ClearQueueInfo ()
-{
- m_dispatch_queue_name.clear();
- m_queue_kind = eQueueKindUnknown;
- m_queue_serial_number = 0;
- m_dispatch_queue_t = LLDB_INVALID_ADDRESS;
- m_associated_with_libdispatch_queue = eLazyBoolCalculate;
+void ThreadGDBRemote::ClearQueueInfo() {
+ m_dispatch_queue_name.clear();
+ m_queue_kind = eQueueKindUnknown;
+ m_queue_serial_number = 0;
+ m_dispatch_queue_t = LLDB_INVALID_ADDRESS;
+ m_associated_with_libdispatch_queue = eLazyBoolCalculate;
}
-void
-ThreadGDBRemote::SetQueueInfo (std::string &&queue_name, QueueKind queue_kind, uint64_t queue_serial, addr_t dispatch_queue_t, LazyBool associated_with_libdispatch_queue)
-{
- m_dispatch_queue_name = queue_name;
- m_queue_kind = queue_kind;
- m_queue_serial_number = queue_serial;
- m_dispatch_queue_t = dispatch_queue_t;
- m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
+void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name,
+ QueueKind queue_kind, uint64_t queue_serial,
+ addr_t dispatch_queue_t,
+ LazyBool associated_with_libdispatch_queue) {
+ m_dispatch_queue_name = queue_name;
+ m_queue_kind = queue_kind;
+ m_queue_serial_number = queue_serial;
+ m_dispatch_queue_t = dispatch_queue_t;
+ m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
}
+const char *ThreadGDBRemote::GetQueueName() {
+ // If our cached queue info is valid, then someone called
+ // ThreadGDBRemote::SetQueueInfo(...)
+ // with valid information that was gleaned from the stop reply packet. In this
+ // case we trust
+ // that the info is valid in m_dispatch_queue_name without refetching it
+ if (CachedQueueInfoIsValid()) {
+ if (m_dispatch_queue_name.empty())
+ return nullptr;
+ else
+ return m_dispatch_queue_name.c_str();
+ }
+ // Always re-fetch the dispatch queue name since it can change
-const char *
-ThreadGDBRemote::GetQueueName ()
-{
- // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
- if (CachedQueueInfoIsValid())
- {
- if (m_dispatch_queue_name.empty())
- return nullptr;
- else
- return m_dispatch_queue_name.c_str();
- }
- // Always re-fetch the dispatch queue name since it can change
-
- if (m_associated_with_libdispatch_queue == eLazyBoolNo)
- return nullptr;
-
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- m_dispatch_queue_name = runtime->GetQueueNameFromThreadQAddress (m_thread_dispatch_qaddr);
- else
- m_dispatch_queue_name.clear();
-
- if (!m_dispatch_queue_name.empty())
- return m_dispatch_queue_name.c_str();
- }
+ if (m_associated_with_libdispatch_queue == eLazyBoolNo)
+ return nullptr;
+
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime)
+ m_dispatch_queue_name =
+ runtime->GetQueueNameFromThreadQAddress(m_thread_dispatch_qaddr);
+ else
+ m_dispatch_queue_name.clear();
+
+ if (!m_dispatch_queue_name.empty())
+ return m_dispatch_queue_name.c_str();
}
- return NULL;
+ }
+ return NULL;
}
-QueueKind
-ThreadGDBRemote::GetQueueKind ()
-{
- // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
- if (CachedQueueInfoIsValid())
- {
- return m_queue_kind;
- }
+QueueKind ThreadGDBRemote::GetQueueKind() {
+ // If our cached queue info is valid, then someone called
+ // ThreadGDBRemote::SetQueueInfo(...)
+ // with valid information that was gleaned from the stop reply packet. In this
+ // case we trust
+ // that the info is valid in m_dispatch_queue_name without refetching it
+ if (CachedQueueInfoIsValid()) {
+ return m_queue_kind;
+ }
+
+ if (m_associated_with_libdispatch_queue == eLazyBoolNo)
+ return eQueueKindUnknown;
- if (m_associated_with_libdispatch_queue == eLazyBoolNo)
- return eQueueKindUnknown;
-
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- m_queue_kind = runtime->GetQueueKind (m_thread_dispatch_qaddr);
- return m_queue_kind;
- }
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime)
+ m_queue_kind = runtime->GetQueueKind(m_thread_dispatch_qaddr);
+ return m_queue_kind;
}
- return eQueueKindUnknown;
+ }
+ return eQueueKindUnknown;
}
+queue_id_t ThreadGDBRemote::GetQueueID() {
+ // If our cached queue info is valid, then someone called
+ // ThreadGDBRemote::SetQueueInfo(...)
+ // with valid information that was gleaned from the stop reply packet. In this
+ // case we trust
+ // that the info is valid in m_dispatch_queue_name without refetching it
+ if (CachedQueueInfoIsValid())
+ return m_queue_serial_number;
-queue_id_t
-ThreadGDBRemote::GetQueueID ()
-{
- // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
- if (CachedQueueInfoIsValid())
- return m_queue_serial_number;
-
- if (m_associated_with_libdispatch_queue == eLazyBoolNo)
- return LLDB_INVALID_QUEUE_ID;
-
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- {
- return runtime->GetQueueIDFromThreadQAddress (m_thread_dispatch_qaddr);
- }
- }
- }
+ if (m_associated_with_libdispatch_queue == eLazyBoolNo)
return LLDB_INVALID_QUEUE_ID;
+
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime) {
+ return runtime->GetQueueIDFromThreadQAddress(m_thread_dispatch_qaddr);
+ }
+ }
+ }
+ return LLDB_INVALID_QUEUE_ID;
}
-QueueSP
-ThreadGDBRemote::GetQueue ()
-{
- queue_id_t queue_id = GetQueueID();
- QueueSP queue;
- if (queue_id != LLDB_INVALID_QUEUE_ID)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- queue = process_sp->GetQueueList().FindQueueByID (queue_id);
- }
+QueueSP ThreadGDBRemote::GetQueue() {
+ queue_id_t queue_id = GetQueueID();
+ QueueSP queue;
+ if (queue_id != LLDB_INVALID_QUEUE_ID) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ queue = process_sp->GetQueueList().FindQueueByID(queue_id);
}
- return queue;
+ }
+ return queue;
}
-addr_t
-ThreadGDBRemote::GetQueueLibdispatchQueueAddress ()
-{
- if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS)
- {
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- {
- m_dispatch_queue_t = runtime->GetLibdispatchQueueAddressFromThreadQAddress (m_thread_dispatch_qaddr);
- }
- }
+addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress() {
+ if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) {
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime) {
+ m_dispatch_queue_t =
+ runtime->GetLibdispatchQueueAddressFromThreadQAddress(
+ m_thread_dispatch_qaddr);
}
+ }
}
- return m_dispatch_queue_t;
+ }
+ return m_dispatch_queue_t;
}
-void
-ThreadGDBRemote::SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t)
-{
- m_dispatch_queue_t = dispatch_queue_t;
+void ThreadGDBRemote::SetQueueLibdispatchQueueAddress(
+ lldb::addr_t dispatch_queue_t) {
+ m_dispatch_queue_t = dispatch_queue_t;
}
-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;
+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;
}
-LazyBool
-ThreadGDBRemote::GetAssociatedWithLibdispatchQueue ()
-{
- return m_associated_with_libdispatch_queue;
+LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() {
+ return m_associated_with_libdispatch_queue;
}
-void
-ThreadGDBRemote::SetAssociatedWithLibdispatchQueue (LazyBool associated_with_libdispatch_queue)
-{
- m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
+void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue(
+ LazyBool associated_with_libdispatch_queue) {
+ m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
}
-StructuredData::ObjectSP
-ThreadGDBRemote::FetchThreadExtendedInfo ()
-{
- StructuredData::ObjectSP object_sp;
- const lldb::user_id_t tid = GetProtocolID();
- Log *log(GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
- if (log)
- log->Printf ("Fetching extended information for thread %4.4" PRIx64, tid);
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- object_sp = gdb_process->GetExtendedInfoForThread (tid);
- }
- return object_sp;
+StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
+ StructuredData::ObjectSP object_sp;
+ const lldb::user_id_t tid = GetProtocolID();
+ Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ if (log)
+ log->Printf("Fetching extended information for thread %4.4" PRIx64, tid);
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ ProcessGDBRemote *gdb_process =
+ static_cast<ProcessGDBRemote *>(process_sp.get());
+ object_sp = gdb_process->GetExtendedInfoForThread(tid);
+ }
+ return object_sp;
}
-void
-ThreadGDBRemote::WillResume (StateType resume_state)
-{
- int signo = GetResumeSignal();
- const lldb::user_id_t tid = GetProtocolID();
- Log *log(GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
- if (log)
- log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, StateAsCString(resume_state));
-
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- switch (resume_state)
- {
- case eStateSuspended:
- case eStateStopped:
- // Don't append anything for threads that should stay stopped.
- break;
-
- case eStateRunning:
- if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
- gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
- else
- gdb_process->m_continue_c_tids.push_back(tid);
- break;
-
- case eStateStepping:
- if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
- gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
- else
- gdb_process->m_continue_s_tids.push_back(tid);
- break;
-
- default:
- break;
- }
+void ThreadGDBRemote::WillResume(StateType resume_state) {
+ int signo = GetResumeSignal();
+ const lldb::user_id_t tid = GetProtocolID();
+ Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ if (log)
+ log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
+ StateAsCString(resume_state));
+
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ ProcessGDBRemote *gdb_process =
+ static_cast<ProcessGDBRemote *>(process_sp.get());
+ switch (resume_state) {
+ case eStateSuspended:
+ case eStateStopped:
+ // Don't append anything for threads that should stay stopped.
+ break;
+
+ case eStateRunning:
+ if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
+ gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
+ else
+ gdb_process->m_continue_c_tids.push_back(tid);
+ break;
+
+ case eStateStepping:
+ if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
+ gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
+ else
+ gdb_process->m_continue_s_tids.push_back(tid);
+ break;
+
+ default:
+ break;
}
+ }
}
-void
-ThreadGDBRemote::RefreshStateAfterStop()
-{
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The GDBRemoteRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded (force);
-}
-
-bool
-ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread)
-{
- return thread != 0;
+void ThreadGDBRemote::RefreshStateAfterStop() {
+ // Invalidate all registers in our register context. We don't set "force" to
+ // true because the stop reply packet might have had some register values
+ // that were expedited and these will already be copied into the register
+ // context by the time this function gets called. The GDBRemoteRegisterContext
+ // class has been made smart enough to detect when it needs to invalidate
+ // which registers are valid by putting hooks in the register read and
+ // register supply functions where they check the process stop ID and do
+ // the right thing.
+ const bool force = false;
+ GetRegisterContext()->InvalidateIfNeeded(force);
}
-void
-ThreadGDBRemote::Dump(Log *log, uint32_t index)
-{
+bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) {
+ return thread != 0;
}
+void ThreadGDBRemote::Dump(Log *log, uint32_t index) {}
-bool
-ThreadGDBRemote::ShouldStop (bool &step_more)
-{
- return true;
-}
-lldb::RegisterContextSP
-ThreadGDBRemote::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- return m_reg_context_sp;
+bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; }
+lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL)
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
-
- if (concrete_frame_idx == 0)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- // read_all_registers_at_once will be true if 'p' packet is not supported.
- bool read_all_registers_at_once = !gdb_process->GetGDBRemote().GetpPacketSupported (GetID());
- reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
- }
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ ProcessGDBRemote *gdb_process =
+ static_cast<ProcessGDBRemote *>(process_sp.get());
+ // read_all_registers_at_once will be true if 'p' packet is not supported.
+ bool read_all_registers_at_once =
+ !gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
+ reg_ctx_sp.reset(new GDBRemoteRegisterContext(
+ *this, concrete_frame_idx, gdb_process->m_register_info,
+ read_all_registers_at_once));
}
- return reg_ctx_sp;
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
-{
- GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
- assert (gdb_reg_ctx);
- return gdb_reg_ctx->PrivateSetRegisterValue (reg, response);
+bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg,
+ llvm::ArrayRef<uint8_t> data) {
+ GDBRemoteRegisterContext *gdb_reg_ctx =
+ static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
+ assert(gdb_reg_ctx);
+ return gdb_reg_ctx->PrivateSetRegisterValue(reg, data);
}
-bool
-ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, uint64_t regval)
-{
- GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
- assert (gdb_reg_ctx);
- return gdb_reg_ctx->PrivateSetRegisterValue (reg, regval);
+bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) {
+ GDBRemoteRegisterContext *gdb_reg_ctx =
+ static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
+ assert(gdb_reg_ctx);
+ return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval);
}
-bool
-ThreadGDBRemote::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- return static_cast<ProcessGDBRemote *>(process_sp.get())->CalculateThreadStopInfo(this);
- return false;
+bool ThreadGDBRemote::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp)
+ return static_cast<ProcessGDBRemote *>(process_sp.get())
+ ->CalculateThreadStopInfo(this);
+ return false;
}
-
-
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index d7619f491e66..27caf42fc4a5 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -27,126 +27,94 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class ThreadGDBRemote : public Thread
-{
+class ThreadGDBRemote : public Thread {
public:
- ThreadGDBRemote (Process &process, lldb::tid_t tid);
+ ThreadGDBRemote(Process &process, lldb::tid_t tid);
- ~ThreadGDBRemote() override;
+ ~ThreadGDBRemote() override;
- void
- WillResume (lldb::StateType resume_state) override;
+ void WillResume(lldb::StateType resume_state) override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- const char *
- GetName () override;
+ const char *GetName() override;
- const char *
- GetQueueName () override;
+ const char *GetQueueName() override;
- lldb::QueueKind
- GetQueueKind () override;
+ lldb::QueueKind GetQueueKind() override;
- lldb::queue_id_t
- GetQueueID () override;
+ lldb::queue_id_t GetQueueID() override;
- lldb::QueueSP
- GetQueue () override;
+ lldb::QueueSP GetQueue() override;
- lldb::addr_t
- GetQueueLibdispatchQueueAddress () override;
+ lldb::addr_t GetQueueLibdispatchQueueAddress() override;
- void
- SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t) override;
+ void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override;
- bool
- ThreadHasQueueInformation () const override;
+ bool ThreadHasQueueInformation() const override;
- lldb::RegisterContextSP
- GetRegisterContext () override;
+ lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame (StackFrame *frame) override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
- void
- Dump (Log *log, uint32_t index);
+ void Dump(Log *log, uint32_t index);
- static bool
- ThreadIDIsValid (lldb::tid_t thread);
+ static bool ThreadIDIsValid(lldb::tid_t thread);
- bool
- ShouldStop (bool &step_more);
+ bool ShouldStop(bool &step_more);
- const char *
- GetBasicInfoAsString ();
+ const char *GetBasicInfoAsString();
- void
- SetName (const char *name) override
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) override {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
- lldb::addr_t
- GetThreadDispatchQAddr ()
- {
- return m_thread_dispatch_qaddr;
- }
+ lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
- void
- SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
- {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
+ void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
+ m_thread_dispatch_qaddr = thread_dispatch_qaddr;
+ }
- void
- ClearQueueInfo ();
-
- void
- SetQueueInfo (std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue);
+ void ClearQueueInfo();
- lldb_private::LazyBool
- GetAssociatedWithLibdispatchQueue () override;
+ void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind,
+ uint64_t queue_serial, lldb::addr_t dispatch_queue_t,
+ lldb_private::LazyBool associated_with_libdispatch_queue);
- void
- SetAssociatedWithLibdispatchQueue (lldb_private::LazyBool associated_with_libdispatch_queue) override;
+ lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() override;
- StructuredData::ObjectSP
- FetchThreadExtendedInfo () override;
+ void SetAssociatedWithLibdispatchQueue(
+ lldb_private::LazyBool associated_with_libdispatch_queue) override;
+
+ StructuredData::ObjectSP FetchThreadExtendedInfo() override;
protected:
- friend class ProcessGDBRemote;
-
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::addr_t m_dispatch_queue_t;
- lldb::QueueKind m_queue_kind; // Queue info from stop reply/stop info for thread
- uint64_t m_queue_serial_number; // Queue info from stop reply/stop info for thread
- lldb_private::LazyBool m_associated_with_libdispatch_queue;
-
- bool
- PrivateSetRegisterValue (uint32_t reg,
- StringExtractor &response);
-
- bool
- PrivateSetRegisterValue (uint32_t reg,
- uint64_t regval);
-
- bool
- CachedQueueInfoIsValid() const
- {
- return m_queue_kind != lldb::eQueueKindUnknown;
- }
- void
- SetStopInfoFromPacket (StringExtractor &stop_packet, uint32_t stop_id);
-
- bool
- CalculateStopInfo () override;
+ friend class ProcessGDBRemote;
+
+ std::string m_thread_name;
+ std::string m_dispatch_queue_name;
+ lldb::addr_t m_thread_dispatch_qaddr;
+ lldb::addr_t m_dispatch_queue_t;
+ lldb::QueueKind
+ m_queue_kind; // Queue info from stop reply/stop info for thread
+ uint64_t
+ m_queue_serial_number; // Queue info from stop reply/stop info for thread
+ lldb_private::LazyBool m_associated_with_libdispatch_queue;
+
+ bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
+
+ bool PrivateSetRegisterValue(uint32_t reg, uint64_t regval);
+
+ bool CachedQueueInfoIsValid() const {
+ return m_queue_kind != lldb::eQueueKindUnknown;
+ }
+ void SetStopInfoFromPacket(StringExtractor &stop_packet, uint32_t stop_id);
+
+ bool CalculateStopInfo() override;
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 6bf198ca2f37..f83499cdb233 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -1,4 +1,5 @@
-//===-- ProcessMachCore.cpp ------------------------------------------*- C++ -*-===//
+//===-- ProcessMachCore.cpp ------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,622 +33,576 @@
// Project includes
#include "ProcessMachCore.h"
-#include "ThreadMachCore.h"
#include "StopInfoMachException.h"
+#include "ThreadMachCore.h"
// Needed for the plug-in names for the dynamic loaders.
#include "lldb/Utility/SafeMachO.h"
-#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
+#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
using namespace lldb;
using namespace lldb_private;
-ConstString
-ProcessMachCore::GetPluginNameStatic()
-{
- static ConstString g_name("mach-o-core");
- return g_name;
+ConstString ProcessMachCore::GetPluginNameStatic() {
+ static ConstString g_name("mach-o-core");
+ return g_name;
}
-const char *
-ProcessMachCore::GetPluginDescriptionStatic()
-{
- return "Mach-O core file debugging plug-in.";
+const char *ProcessMachCore::GetPluginDescriptionStatic() {
+ return "Mach-O core file debugging plug-in.";
}
-void
-ProcessMachCore::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessMachCore::CreateInstance);
+void ProcessMachCore::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessMachCore::CreateInstance);
}
-
-lldb::ProcessSP
-ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file)
-{
- lldb::ProcessSP process_sp;
- if (crash_file)
- {
- const size_t header_size = sizeof(llvm::MachO::mach_header);
- lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size));
- if (data_sp && data_sp->GetByteSize() == header_size)
- {
- DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
-
- lldb::offset_t data_offset = 0;
- llvm::MachO::mach_header mach_header;
- if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header))
- {
- if (mach_header.filetype == llvm::MachO::MH_CORE)
- process_sp.reset(new ProcessMachCore (target_sp, listener_sp, *crash_file));
- }
- }
-
+lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file) {
+ lldb::ProcessSP process_sp;
+ if (crash_file) {
+ const size_t header_size = sizeof(llvm::MachO::mach_header);
+ lldb::DataBufferSP data_sp(crash_file->ReadFileContents(0, header_size));
+ if (data_sp && data_sp->GetByteSize() == header_size) {
+ DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
+
+ lldb::offset_t data_offset = 0;
+ llvm::MachO::mach_header mach_header;
+ if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) {
+ if (mach_header.filetype == llvm::MachO::MH_CORE)
+ process_sp.reset(
+ new ProcessMachCore(target_sp, listener_sp, *crash_file));
+ }
}
- return process_sp;
+ }
+ return process_sp;
}
-bool
-ProcessMachCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
+bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ 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())
- {
- // Don't add the Target's architecture to the ModuleSpec - we may be working
- // with a core file that doesn't have the correct cpusubtype in the header
- // but we should still try to use it - ModuleSpecList::FindMatchingModuleSpec
- // enforces a strict arch mach.
- ModuleSpec core_module_spec(m_core_file);
- Error error (ModuleList::GetSharedModule (core_module_spec,
- m_core_module_sp,
- NULL,
- NULL,
- NULL));
-
- if (m_core_module_sp)
- {
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
- 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()) {
+ // Don't add the Target's architecture to the ModuleSpec - we may be working
+ // with a core file that doesn't have the correct cpusubtype in the header
+ // but we should still try to use it -
+ // ModuleSpecList::FindMatchingModuleSpec
+ // enforces a strict arch mach.
+ ModuleSpec core_module_spec(m_core_file);
+ Error error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
+ NULL, NULL, NULL));
+
+ if (m_core_module_sp) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
+ return true;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// ProcessMachCore constructor
//----------------------------------------------------------------------
-ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec &core_file)
- : Process(target_sp, listener_sp),
- m_core_aranges(),
- m_core_range_infos(),
- m_core_module_sp(),
- m_core_file(core_file),
+ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec &core_file)
+ : Process(target_sp, listener_sp), m_core_aranges(), m_core_range_infos(),
+ m_core_module_sp(), m_core_file(core_file),
m_dyld_addr(LLDB_INVALID_ADDRESS),
- m_mach_kernel_addr(LLDB_INVALID_ADDRESS),
- m_dyld_plugin_name()
-{
-}
+ m_mach_kernel_addr(LLDB_INVALID_ADDRESS), m_dyld_plugin_name() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessMachCore::~ProcessMachCore()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
+ProcessMachCore::~ProcessMachCore() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-ConstString
-ProcessMachCore::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+ConstString ProcessMachCore::GetPluginName() { return GetPluginNameStatic(); }
-uint32_t
-ProcessMachCore::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ProcessMachCore::GetPluginVersion() { return 1; }
-bool
-ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_PROCESS));
- llvm::MachO::mach_header header;
- Error error;
- if (DoReadMemory (addr, &header, sizeof(header), error) != sizeof(header))
- return false;
- if (header.magic == llvm::MachO::MH_CIGAM ||
- header.magic == llvm::MachO::MH_CIGAM_64)
- {
- header.magic = llvm::ByteSwap_32(header.magic);
- header.cputype = llvm::ByteSwap_32(header.cputype);
- header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
- header.filetype = llvm::ByteSwap_32(header.filetype);
- header.ncmds = llvm::ByteSwap_32(header.ncmds);
- header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
- header.flags = llvm::ByteSwap_32(header.flags);
- }
-
- // TODO: swap header if needed...
- //printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
- if (header.magic == llvm::MachO::MH_MAGIC ||
- header.magic == llvm::MachO::MH_MAGIC_64)
- {
- // Check MH_EXECUTABLE to see if we can find the mach image
- // that contains the shared library list. The dynamic loader
- // (dyld) is what contains the list for user applications,
- // and the mach kernel contains a global that has the list
- // of kexts to load
- switch (header.filetype)
- {
- case llvm::MachO::MH_DYLINKER:
- //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
- // Address of dyld "struct mach_header" in the core file
- if (log)
- log->Printf ("ProcessMachCore::GetDynamicLoaderAddress found a user process dyld binary image at 0x%" PRIx64, addr);
- m_dyld_addr = addr;
- return true;
-
- case llvm::MachO::MH_EXECUTE:
- //printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
- // Check MH_EXECUTABLE file types to see if the dynamic link object flag
- // is NOT set. If it isn't, then we have a mach_kernel.
- if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0)
- {
- if (log)
- log->Printf ("ProcessMachCore::GetDynamicLoaderAddress found a mach kernel binary image at 0x%" PRIx64, addr);
- // Address of the mach kernel "struct mach_header" in the core file.
- m_mach_kernel_addr = addr;
- return true;
- }
- break;
- }
- }
+bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
+ LIBLLDB_LOG_PROCESS));
+ llvm::MachO::mach_header header;
+ Error error;
+ if (DoReadMemory(addr, &header, sizeof(header), error) != sizeof(header))
return false;
+ if (header.magic == llvm::MachO::MH_CIGAM ||
+ header.magic == llvm::MachO::MH_CIGAM_64) {
+ header.magic = llvm::ByteSwap_32(header.magic);
+ header.cputype = llvm::ByteSwap_32(header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32(header.filetype);
+ header.ncmds = llvm::ByteSwap_32(header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32(header.flags);
+ }
+
+ // TODO: swap header if needed...
+ // printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr,
+ // header.magic, header.filetype);
+ if (header.magic == llvm::MachO::MH_MAGIC ||
+ header.magic == llvm::MachO::MH_MAGIC_64) {
+ // Check MH_EXECUTABLE to see if we can find the mach image
+ // that contains the shared library list. The dynamic loader
+ // (dyld) is what contains the list for user applications,
+ // and the mach kernel contains a global that has the list
+ // of kexts to load
+ switch (header.filetype) {
+ case llvm::MachO::MH_DYLINKER:
+ // printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
+ // Address of dyld "struct mach_header" in the core file
+ if (log)
+ log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a user "
+ "process dyld binary image at 0x%" PRIx64,
+ addr);
+ m_dyld_addr = addr;
+ return true;
+
+ case llvm::MachO::MH_EXECUTE:
+ // printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
+ // Check MH_EXECUTABLE file types to see if the dynamic link object flag
+ // is NOT set. If it isn't, then we have a mach_kernel.
+ if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
+ if (log)
+ log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a mach "
+ "kernel binary image at 0x%" PRIx64,
+ addr);
+ // Address of the mach kernel "struct mach_header" in the core file.
+ m_mach_kernel_addr = addr;
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
-Error
-ProcessMachCore::DoLoadCore ()
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_PROCESS));
- Error error;
- if (!m_core_module_sp)
- {
- error.SetErrorString ("invalid core module");
- return error;
- }
+Error ProcessMachCore::DoLoadCore() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
+ LIBLLDB_LOG_PROCESS));
+ Error error;
+ if (!m_core_module_sp) {
+ error.SetErrorString("invalid core module");
+ return error;
+ }
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile == NULL)
- {
- error.SetErrorString ("invalid core object file");
- return error;
- }
-
- if (core_objfile->GetNumThreadContexts() == 0)
- {
- error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
- return error;
- }
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ if (core_objfile == NULL) {
+ error.SetErrorString("invalid core object file");
+ return error;
+ }
- SectionList *section_list = core_objfile->GetSectionList();
- if (section_list == NULL)
- {
- error.SetErrorString ("core file has no sections");
- return error;
- }
-
- const uint32_t num_sections = section_list->GetNumSections(0);
- if (num_sections == 0)
- {
- error.SetErrorString ("core file has no sections");
- return error;
- }
-
- SetCanJIT(false);
-
- llvm::MachO::mach_header header;
- DataExtractor data (&header,
- sizeof(header),
- m_core_module_sp->GetArchitecture().GetByteOrder(),
- m_core_module_sp->GetArchitecture().GetAddressByteSize());
-
- bool ranges_are_sorted = true;
- addr_t vm_addr = 0;
- for (uint32_t i=0; i<num_sections; ++i)
- {
- Section *section = section_list->GetSectionAtIndex (i).get();
- if (section)
- {
- lldb::addr_t section_vm_addr = section->GetFileAddress();
- FileRange file_range (section->GetFileOffset(), section->GetFileSize());
- VMRangeToFileOffset::Entry range_entry (section_vm_addr,
- section->GetByteSize(),
- file_range);
-
- if (vm_addr > section_vm_addr)
- ranges_are_sorted = false;
- vm_addr = section->GetFileAddress();
- VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
-// printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
-// i,
-// range_entry.GetRangeBase(),
-// range_entry.GetRangeEnd(),
-// range_entry.data.GetRangeBase(),
-// range_entry.data.GetRangeEnd());
-
- if (last_entry &&
- last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
- last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
- {
- last_entry->SetRangeEnd (range_entry.GetRangeEnd());
- last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
- //puts("combine");
- }
- else
- {
- m_core_aranges.Append(range_entry);
- }
- // Some core files don't fill in the permissions correctly. If that is the case
- // assume read + execute so clients don't think the memory is not readable,
- // or executable. The memory isn't writable since this plug-in doesn't implement
- // DoWriteMemory.
- uint32_t permissions = section->GetPermissions();
- if (permissions == 0)
- permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
- m_core_range_infos.Append(
- VMRangeToPermissions::Entry(section_vm_addr, section->GetByteSize(), permissions));
- }
+ if (core_objfile->GetNumThreadContexts() == 0) {
+ error.SetErrorString("core file doesn't contain any LC_THREAD load "
+ "commands, or the LC_THREAD architecture is not "
+ "supported in this lldb");
+ return error;
+ }
+
+ SectionList *section_list = core_objfile->GetSectionList();
+ if (section_list == NULL) {
+ error.SetErrorString("core file has no sections");
+ return error;
+ }
+
+ const uint32_t num_sections = section_list->GetNumSections(0);
+ if (num_sections == 0) {
+ error.SetErrorString("core file has no sections");
+ return error;
+ }
+
+ SetCanJIT(false);
+
+ llvm::MachO::mach_header header;
+ DataExtractor data(&header, sizeof(header),
+ m_core_module_sp->GetArchitecture().GetByteOrder(),
+ m_core_module_sp->GetArchitecture().GetAddressByteSize());
+
+ bool ranges_are_sorted = true;
+ addr_t vm_addr = 0;
+ for (uint32_t i = 0; i < num_sections; ++i) {
+ Section *section = section_list->GetSectionAtIndex(i).get();
+ if (section) {
+ lldb::addr_t section_vm_addr = section->GetFileAddress();
+ FileRange file_range(section->GetFileOffset(), section->GetFileSize());
+ VMRangeToFileOffset::Entry range_entry(
+ section_vm_addr, section->GetByteSize(), file_range);
+
+ if (vm_addr > section_vm_addr)
+ ranges_are_sorted = false;
+ vm_addr = section->GetFileAddress();
+ VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
+ // printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " -
+ // 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
+ // i,
+ // range_entry.GetRangeBase(),
+ // range_entry.GetRangeEnd(),
+ // range_entry.data.GetRangeBase(),
+ // range_entry.data.GetRangeEnd());
+
+ if (last_entry &&
+ last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
+ last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) {
+ last_entry->SetRangeEnd(range_entry.GetRangeEnd());
+ last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
+ // puts("combine");
+ } else {
+ m_core_aranges.Append(range_entry);
+ }
+ // Some core files don't fill in the permissions correctly. If that is the
+ // case
+ // assume read + execute so clients don't think the memory is not
+ // readable,
+ // or executable. The memory isn't writable since this plug-in doesn't
+ // implement
+ // DoWriteMemory.
+ uint32_t permissions = section->GetPermissions();
+ if (permissions == 0)
+ permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
+ m_core_range_infos.Append(VMRangeToPermissions::Entry(
+ section_vm_addr, section->GetByteSize(), permissions));
}
- if (!ranges_are_sorted)
- {
- m_core_aranges.Sort();
- m_core_range_infos.Sort();
+ }
+ if (!ranges_are_sorted) {
+ m_core_aranges.Sort();
+ m_core_range_infos.Sort();
+ }
+
+ if (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
+ // binary so
+ // we don't miss one or the other. Step through all memory segments
+ // searching for
+ // a kernel binary and for a user process dyld -- we'll decide which to
+ // prefer
+ // later if both are present.
+
+ const size_t num_core_aranges = m_core_aranges.GetSize();
+ for (size_t i = 0; i < num_core_aranges; ++i) {
+ const VMRangeToFileOffset::Entry *entry =
+ m_core_aranges.GetEntryAtIndex(i);
+ lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
+ lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
+ for (lldb::addr_t section_vm_addr = section_vm_addr_start;
+ section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) {
+ GetDynamicLoaderAddress(section_vm_addr);
+ }
}
-
- if (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 binary so
- // we don't miss one or the other. Step through all memory segments searching for
- // a kernel binary and for a user process dyld -- we'll decide which to prefer
- // later if both are present.
-
- const size_t num_core_aranges = m_core_aranges.GetSize();
- for (size_t i = 0; i < num_core_aranges; ++i)
- {
- const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
- lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
- lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
- for (lldb::addr_t section_vm_addr = section_vm_addr_start;
- section_vm_addr < section_vm_addr_end;
- section_vm_addr += 0x1000)
- {
- GetDynamicLoaderAddress (section_vm_addr);
- }
- }
+ }
+
+ if (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()) {
+ GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture());
}
-
- if (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())
- {
- GetTarget().SetArchitecture (m_core_module_sp->GetArchitecture());
- }
-
- // SearchForDarwinKernel will end up calling back into this this class in the GetImageInfoAddress
- // method which will give it the m_mach_kernel_addr/m_dyld_addr it already has. Save that aside
- // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
- // DynamicLoaderDarwinKernel does a real search for the kernel using its own heuristics.
-
- addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
- addr_t saved_user_dyld_addr = m_dyld_addr;
- m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
- m_dyld_addr = LLDB_INVALID_ADDRESS;
-
- addr_t better_kernel_address = DynamicLoaderDarwinKernel::SearchForDarwinKernel (this);
-
- m_mach_kernel_addr = saved_mach_kernel_addr;
- m_dyld_addr = saved_user_dyld_addr;
-
- if (better_kernel_address != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using the kernel address from DynamicLoaderDarwinKernel");
- m_mach_kernel_addr = better_kernel_address;
- }
+ // SearchForDarwinKernel will end up calling back into this this class in
+ // the GetImageInfoAddress
+ // method which will give it the m_mach_kernel_addr/m_dyld_addr it already
+ // has. Save that aside
+ // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily
+ // so
+ // DynamicLoaderDarwinKernel does a real search for the kernel using its own
+ // heuristics.
+
+ addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
+ addr_t saved_user_dyld_addr = m_dyld_addr;
+ m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
+ m_dyld_addr = LLDB_INVALID_ADDRESS;
+
+ addr_t better_kernel_address =
+ DynamicLoaderDarwinKernel::SearchForDarwinKernel(this);
+
+ m_mach_kernel_addr = saved_mach_kernel_addr;
+ m_dyld_addr = saved_user_dyld_addr;
+
+ if (better_kernel_address != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address "
+ "from DynamicLoaderDarwinKernel");
+ m_mach_kernel_addr = better_kernel_address;
}
-
-
- // If we found both a user-process dyld and a kernel binary, we need to decide
- // which to prefer.
- if (GetCorefilePreference() == eKernelCorefile)
- {
- if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- }
- else if (m_dyld_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
- m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
- }
+ }
+
+ // If we found both a user-process dyld and a kernel binary, we need to decide
+ // which to prefer.
+ if (GetCorefilePreference() == eKernelCorefile) {
+ if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image "
+ "at 0x%" PRIx64,
+ m_mach_kernel_addr);
+ m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
+ } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld "
+ "image at 0x%" PRIx64,
+ m_dyld_addr);
+ m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
}
- else
- {
- if (m_dyld_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
- m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
- }
- else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- }
+ } else {
+ if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld "
+ "image at 0x%" PRIx64,
+ m_dyld_addr);
+ m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+ } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image "
+ "at 0x%" PRIx64,
+ m_mach_kernel_addr);
+ m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
}
-
- // Even if the architecture is set in the target, we need to override
- // it to match the core file which is always single arch.
- ArchSpec arch (m_core_module_sp->GetArchitecture());
- if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
- {
- arch.SetTriple ("i386", GetTarget().GetPlatform().get());
+ }
+
+ if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic()) {
+ // For non-user process core files, the permissions on the core file
+ // segments are usually
+ // meaningless, they may be just "read", because we're dealing with kernel
+ // coredumps or
+ // early startup coredumps and the dumper is grabbing pages of memory
+ // without knowing
+ // what they are. If they aren't marked as "exeuctable", that can break the
+ // unwinder
+ // which will check a pc value to see if it is in an executable segment and
+ // stop the
+ // backtrace early if it is not ("executable" and "unknown" would both be
+ // fine, but
+ // "not executable" will break the unwinder).
+ size_t core_range_infos_size = m_core_range_infos.GetSize();
+ for (size_t i = 0; i < core_range_infos_size; i++) {
+ VMRangeToPermissions::Entry *ent =
+ m_core_range_infos.GetMutableEntryAtIndex(i);
+ ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
}
- if (arch.IsValid())
- GetTarget().SetArchitecture(arch);
-
- return error;
+ }
+
+ // Even if the architecture is set in the target, we need to override
+ // it to match the core file which is always single arch.
+ ArchSpec arch(m_core_module_sp->GetArchitecture());
+ if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) {
+ arch.SetTriple("i386", GetTarget().GetPlatform().get());
+ }
+ if (arch.IsValid())
+ GetTarget().SetArchitecture(arch);
+
+ return error;
}
-lldb_private::DynamicLoader *
-ProcessMachCore::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
- return m_dyld_ap.get();
+lldb_private::DynamicLoader *ProcessMachCore::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(
+ this,
+ m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
+ return m_dyld_ap.get();
}
-bool
-ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- if (old_thread_list.GetSize(false) == 0)
- {
- // Make up the thread the first time this is called so we can setup our one and only
- // core thread state.
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
-
- if (core_objfile)
- {
- const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
- for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
- {
- ThreadSP thread_sp(new ThreadMachCore (*this, tid));
- new_thread_list.AddThread (thread_sp);
- }
- }
- }
- else
- {
- const uint32_t num_threads = old_thread_list.GetSize(false);
- for (uint32_t i=0; i<num_threads; ++i)
- new_thread_list.AddThread (old_thread_list.GetThreadAtIndex (i, false));
+bool ProcessMachCore::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ if (old_thread_list.GetSize(false) == 0) {
+ // Make up the thread the first time this is called so we can setup our one
+ // and only
+ // core thread state.
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+
+ if (core_objfile) {
+ const uint32_t num_threads = core_objfile->GetNumThreadContexts();
+ for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
+ ThreadSP thread_sp(new ThreadMachCore(*this, tid));
+ new_thread_list.AddThread(thread_sp);
+ }
}
- return new_thread_list.GetSize(false) > 0;
+ } else {
+ const uint32_t num_threads = old_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < num_threads; ++i)
+ new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
+ }
+ return new_thread_list.GetSize(false) > 0;
}
-void
-ProcessMachCore::RefreshStateAfterStop ()
-{
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
- //SetThreadStopInfo (m_last_stop_packet);
+void ProcessMachCore::RefreshStateAfterStop() {
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list.RefreshStateAfterStop();
+ // SetThreadStopInfo (m_last_stop_packet);
}
-Error
-ProcessMachCore::DoDestroy ()
-{
- return Error();
-}
+Error ProcessMachCore::DoDestroy() { return Error(); }
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessMachCore::IsAlive ()
-{
- return true;
-}
+bool ProcessMachCore::IsAlive() { return true; }
-bool
-ProcessMachCore::WarnBeforeDetach () const
-{
- return false;
-}
+bool ProcessMachCore::WarnBeforeDetach() const { return false; }
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessMachCore::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since in core files we have it all cached our our core file anyway.
- return DoReadMemory (addr, buf, size, error);
+size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since in core files we have it all cached our our core file anyway.
+ return DoReadMemory(addr, buf, size, error);
}
-size_t
-ProcessMachCore::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- size_t bytes_read = 0;
-
- if (core_objfile)
- {
- //----------------------------------------------------------------------
- // Segments are not always contiguous in mach-o core files. We have core
- // files that have segments like:
- // Address Size File off File size
- // ---------- ---------- ---------- ----------
- // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0 0x00000000 __TEXT
- // LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000 --- --- 0 0x00000000 __TEXT
- // LC_SEGMENT 0x000f7000 0x00001000 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
- //
- // Any if the user executes the following command:
- //
- // (lldb) mem read 0xf6ff0
- //
- // We would attempt to read 32 bytes from 0xf6ff0 but would only
- // get 16 unless we loop through consecutive memory ranges that are
- // contiguous in the address space, but not in the file data.
- //----------------------------------------------------------------------
- while (bytes_read < size)
- {
- const addr_t curr_addr = addr + bytes_read;
- const VMRangeToFileOffset::Entry *core_memory_entry = m_core_aranges.FindEntryThatContains(curr_addr);
-
- if (core_memory_entry)
- {
- const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
- const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
- const size_t bytes_to_read = std::min(size - bytes_read, (size_t)bytes_left);
- const size_t curr_bytes_read = core_objfile->CopyData(core_memory_entry->data.GetRangeBase() + offset,
- bytes_to_read, (char *)buf + bytes_read);
- if (curr_bytes_read == 0)
- break;
- bytes_read += curr_bytes_read;
- }
- else
- {
- // Only set the error if we didn't read any bytes
- if (bytes_read == 0)
- error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64, curr_addr);
- break;
- }
- }
+size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ size_t bytes_read = 0;
+
+ if (core_objfile) {
+ //----------------------------------------------------------------------
+ // Segments are not always contiguous in mach-o core files. We have core
+ // files that have segments like:
+ // Address Size File off File size
+ // ---------- ---------- ---------- ----------
+ // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0
+ // 0x00000000 __TEXT
+ // LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000 --- --- 0
+ // 0x00000000 __TEXT
+ // LC_SEGMENT 0x000f7000 0x00001000 0x1d60aee8 0x00001000 --- --- 0
+ // 0x00000000 __TEXT
+ //
+ // Any if the user executes the following command:
+ //
+ // (lldb) mem read 0xf6ff0
+ //
+ // We would attempt to read 32 bytes from 0xf6ff0 but would only
+ // get 16 unless we loop through consecutive memory ranges that are
+ // contiguous in the address space, but not in the file data.
+ //----------------------------------------------------------------------
+ while (bytes_read < size) {
+ const addr_t curr_addr = addr + bytes_read;
+ const VMRangeToFileOffset::Entry *core_memory_entry =
+ m_core_aranges.FindEntryThatContains(curr_addr);
+
+ if (core_memory_entry) {
+ const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
+ const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
+ const size_t bytes_to_read =
+ std::min(size - bytes_read, (size_t)bytes_left);
+ const size_t curr_bytes_read = core_objfile->CopyData(
+ core_memory_entry->data.GetRangeBase() + offset, bytes_to_read,
+ (char *)buf + bytes_read);
+ if (curr_bytes_read == 0)
+ break;
+ bytes_read += curr_bytes_read;
+ } else {
+ // Only set the error if we didn't read any bytes
+ if (bytes_read == 0)
+ error.SetErrorStringWithFormat(
+ "core file does not contain 0x%" PRIx64, curr_addr);
+ break;
+ }
}
+ }
- return bytes_read;
+ return bytes_read;
}
-Error
-ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr, MemoryRegionInfo &region_info)
-{
- region_info.Clear();
- const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
- if (permission_entry)
- {
- if (permission_entry->Contains(load_addr))
- {
- region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
- const Flags permissions(permission_entry->data);
- region_info.SetReadable(permissions.Test(ePermissionsReadable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetWritable(permissions.Test(ePermissionsWritable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetExecutable(permissions.Test(ePermissionsExecutable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eYes);
- }
- else if (load_addr < permission_entry->GetRangeBase())
- {
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- return Error();
+Error ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
+ region_info.Clear();
+ const VMRangeToPermissions::Entry *permission_entry =
+ m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+ if (permission_entry) {
+ if (permission_entry->Contains(load_addr)) {
+ region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+ const Flags permissions(permission_entry->data);
+ region_info.SetReadable(permissions.Test(ePermissionsReadable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetWritable(permissions.Test(ePermissionsWritable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetExecutable(permissions.Test(ePermissionsExecutable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eYes);
+ } else if (load_addr < permission_entry->GetRangeBase()) {
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
}
-
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
return Error();
+ }
+
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ return Error();
}
-void
-ProcessMachCore::Clear()
-{
- m_thread_list.Clear();
-}
+void ProcessMachCore::Clear() { m_thread_list.Clear(); }
-void
-ProcessMachCore::Initialize()
-{
- static std::once_flag g_once_flag;
+void ProcessMachCore::Initialize() {
+ static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- });
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
}
-addr_t
-ProcessMachCore::GetImageInfoAddress()
-{
- // If we found both a user-process dyld and a kernel binary, we need to decide
- // which to prefer.
- if (GetCorefilePreference() == eKernelCorefile)
- {
- if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
- {
- return m_mach_kernel_addr;
- }
- return m_dyld_addr;
+addr_t ProcessMachCore::GetImageInfoAddress() {
+ // If we found both a user-process dyld and a kernel binary, we need to decide
+ // which to prefer.
+ if (GetCorefilePreference() == eKernelCorefile) {
+ if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ return m_mach_kernel_addr;
}
- else
- {
- if (m_dyld_addr != LLDB_INVALID_ADDRESS)
- {
- return m_dyld_addr;
- }
- return m_mach_kernel_addr;
+ return m_dyld_addr;
+ } else {
+ if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
+ return m_dyld_addr;
}
+ return m_mach_kernel_addr;
+ }
}
-
-lldb_private::ObjectFile *
-ProcessMachCore::GetCoreObjectFile ()
-{
- return m_core_module_sp->GetObjectFile();
+lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() {
+ return m_core_module_sp->GetObjectFile();
}
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.h b/source/Plugins/Process/mach-core/ProcessMachCore.h
index 21a0083b2d12..7094eb33110b 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -23,147 +23,131 @@
class ThreadKDP;
-class ProcessMachCore : public lldb_private::Process
-{
+class ProcessMachCore : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ProcessMachCore(lldb::TargetSP target_sp,
- lldb::ListenerSP listener,
- const lldb_private::FileSpec &core_file);
-
- ~ProcessMachCore() override;
-
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener,
- const lldb_private::FileSpec *crash_file_path);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool
- CanDebug (lldb::TargetSP target_sp,
- bool plugin_specified_by_name) override;
-
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- lldb_private::Error
- DoLoadCore () override;
-
- lldb_private::DynamicLoader *
- GetDynamicLoader () override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- lldb_private::Error
- DoDestroy () override;
-
- void
- RefreshStateAfterStop() override;
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool
- IsAlive () override;
-
- bool
- WarnBeforeDetach () const override;
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t
- ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- size_t
- DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- lldb_private::Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
-
- lldb::addr_t
- GetImageInfoAddress () override;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ProcessMachCore(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ const lldb_private::FileSpec &core_file);
+
+ ~ProcessMachCore() override;
+
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ const lldb_private::FileSpec *crash_file_path);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ lldb_private::Error DoLoadCore() override;
+
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ lldb_private::Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
+
+ bool WarnBeforeDetach() const override;
+
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
+
+ lldb_private::Error
+ GetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
+
+ lldb::addr_t GetImageInfoAddress() override;
protected:
- friend class ThreadMachCore;
-
- void
- Clear ( );
-
- bool
- UpdateThreadList (lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- lldb_private::ObjectFile *
- GetCoreObjectFile ();
+ friend class ThreadMachCore;
+
+ void Clear();
+
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
+
+ lldb_private::ObjectFile *GetCoreObjectFile();
+
private:
- bool
- GetDynamicLoaderAddress (lldb::addr_t addr);
-
- typedef enum CorefilePreference { eUserProcessCorefile, eKernelCorefile } CorefilePreferences;
-
- //------------------------------------------------------------------
- /// If a core file can be interpreted multiple ways, this establishes
- /// which style wins.
- ///
- /// If a core file contains both a kernel binary and a user-process
- /// dynamic loader, lldb needs to pick one over the other. This could
- /// be a kernel corefile that happens to have a copy of dyld in its
- /// memory. Or it could be a user process coredump of lldb while doing
- /// kernel debugging - so a copy of the kernel is in its heap. This
- /// should become a setting so it can be over-ridden when necessary.
- //------------------------------------------------------------------
- CorefilePreference
- GetCorefilePreference ()
- {
- // For now, if both user process and kernel binaries a present,
- // assume this is a kernel coredump which has a copy of a user
- // process dyld in one of its pages.
- return eKernelCorefile;
- }
-
- //------------------------------------------------------------------
- // For ProcessMachCore only
- //------------------------------------------------------------------
- typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
- 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;
-
- VMRangeToFileOffset m_core_aranges;
- VMRangeToPermissions m_core_range_infos;
- lldb::ModuleSP m_core_module_sp;
- lldb_private::FileSpec m_core_file;
- lldb::addr_t m_dyld_addr;
- lldb::addr_t m_mach_kernel_addr;
- lldb_private::ConstString m_dyld_plugin_name;
-
- DISALLOW_COPY_AND_ASSIGN (ProcessMachCore);
+ bool GetDynamicLoaderAddress(lldb::addr_t addr);
+
+ typedef enum CorefilePreference {
+ eUserProcessCorefile,
+ eKernelCorefile
+ } CorefilePreferences;
+
+ //------------------------------------------------------------------
+ /// If a core file can be interpreted multiple ways, this establishes
+ /// which style wins.
+ ///
+ /// If a core file contains both a kernel binary and a user-process
+ /// dynamic loader, lldb needs to pick one over the other. This could
+ /// be a kernel corefile that happens to have a copy of dyld in its
+ /// memory. Or it could be a user process coredump of lldb while doing
+ /// kernel debugging - so a copy of the kernel is in its heap. This
+ /// should become a setting so it can be over-ridden when necessary.
+ //------------------------------------------------------------------
+ CorefilePreference GetCorefilePreference() {
+ // For now, if both user process and kernel binaries a present,
+ // assume this is a kernel coredump which has a copy of a user
+ // process dyld in one of its pages.
+ return eKernelCorefile;
+ }
+
+ //------------------------------------------------------------------
+ // For ProcessMachCore only
+ //------------------------------------------------------------------
+ typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
+ 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;
+
+ VMRangeToFileOffset m_core_aranges;
+ VMRangeToPermissions m_core_range_infos;
+ lldb::ModuleSP m_core_module_sp;
+ lldb_private::FileSpec m_core_file;
+ lldb::addr_t m_dyld_addr;
+ lldb::addr_t m_mach_kernel_addr;
+ lldb_private::ConstString m_dyld_plugin_name;
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessMachCore);
};
#endif // liblldb_ProcessMachCore_h_
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 2720c910e4d1..828b705edf57 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -7,22 +7,21 @@
//
//===----------------------------------------------------------------------===//
-
#include "ThreadMachCore.h"
#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
-#include "lldb/Breakpoint/Watchpoint.h"
#include "ProcessMachCore.h"
//#include "RegisterContextKDP_arm.h"
@@ -36,97 +35,71 @@ using namespace lldb_private;
// Thread Registers
//----------------------------------------------------------------------
-ThreadMachCore::ThreadMachCore (Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_thread_name (),
- m_dispatch_queue_name (),
- m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
- m_thread_reg_ctx_sp ()
-{
-}
+ThreadMachCore::ThreadMachCore(Process &process, lldb::tid_t tid)
+ : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
+ m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS), m_thread_reg_ctx_sp() {}
-ThreadMachCore::~ThreadMachCore ()
-{
- DestroyThread();
-}
+ThreadMachCore::~ThreadMachCore() { DestroyThread(); }
-const char *
-ThreadMachCore::GetName ()
-{
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+const char *ThreadMachCore::GetName() {
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
}
-void
-ThreadMachCore::RefreshStateAfterStop()
-{
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The KDPRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded (force);
+void ThreadMachCore::RefreshStateAfterStop() {
+ // Invalidate all registers in our register context. We don't set "force" to
+ // true because the stop reply packet might have had some register values
+ // that were expedited and these will already be copied into the register
+ // context by the time this function gets called. The KDPRegisterContext
+ // class has been made smart enough to detect when it needs to invalidate
+ // which registers are valid by putting hooks in the register read and
+ // register supply functions where they check the process stop ID and do
+ // the right thing.
+ const bool force = false;
+ GetRegisterContext()->InvalidateIfNeeded(force);
}
-bool
-ThreadMachCore::ThreadIDIsValid (lldb::tid_t thread)
-{
- return thread != 0;
-}
+bool ThreadMachCore::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
-lldb::RegisterContextSP
-ThreadMachCore::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- return m_reg_context_sp;
+lldb::RegisterContextSP ThreadMachCore::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL)
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-ThreadMachCore::CreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- if (!m_thread_reg_ctx_sp)
- {
- ProcessSP process_sp (GetProcess());
-
- ObjectFile *core_objfile = static_cast<ProcessMachCore *>(process_sp.get())->GetCoreObjectFile ();
- if (core_objfile)
- m_thread_reg_ctx_sp = core_objfile->GetThreadContextAtIndex (GetID(), *this);
- }
- reg_ctx_sp = m_thread_reg_ctx_sp;
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ThreadMachCore::CreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (!m_thread_reg_ctx_sp) {
+ ProcessSP process_sp(GetProcess());
+
+ ObjectFile *core_objfile =
+ static_cast<ProcessMachCore *>(process_sp.get())->GetCoreObjectFile();
+ if (core_objfile)
+ m_thread_reg_ctx_sp =
+ core_objfile->GetThreadContextAtIndex(GetID(), *this);
}
- return reg_ctx_sp;
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadMachCore::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
- return true;
- }
- return false;
+bool ThreadMachCore::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
+ return true;
+ }
+ return false;
}
-
-
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h
index 25973540db16..a4db484e850f 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.h
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.h
@@ -20,72 +20,55 @@
class ProcessMachCore;
-class ThreadMachCore : public lldb_private::Thread
-{
+class ThreadMachCore : public lldb_private::Thread {
public:
- ThreadMachCore (lldb_private::Process &process,
- lldb::tid_t tid);
+ ThreadMachCore(lldb_private::Process &process, lldb::tid_t tid);
- ~ThreadMachCore() override;
+ ~ThreadMachCore() override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- const char *
- GetName() override;
+ const char *GetName() override;
- lldb::RegisterContextSP
- GetRegisterContext() override;
+ lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
- static bool
- ThreadIDIsValid (lldb::tid_t thread);
+ static bool ThreadIDIsValid(lldb::tid_t thread);
- bool
- ShouldStop (bool &step_more);
+ bool ShouldStop(bool &step_more);
- const char *
- GetBasicInfoAsString ();
+ const char *GetBasicInfoAsString();
- void
- SetName(const char *name) override
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) override {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
- lldb::addr_t
- GetThreadDispatchQAddr ()
- {
- return m_thread_dispatch_qaddr;
- }
+ lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
- void
- SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
- {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
+ void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
+ m_thread_dispatch_qaddr = thread_dispatch_qaddr;
+ }
protected:
- friend class ProcessMachCore;
-
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::RegisterContextSP m_thread_reg_ctx_sp;
-
- //------------------------------------------------------------------
- // Protected member functions.
- //------------------------------------------------------------------
- bool
- CalculateStopInfo() override;
+ friend class ProcessMachCore;
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ std::string m_thread_name;
+ std::string m_dispatch_queue_name;
+ lldb::addr_t m_thread_dispatch_qaddr;
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+
+ //------------------------------------------------------------------
+ // Protected member functions.
+ //------------------------------------------------------------------
+ bool CalculateStopInfo() override;
};
#endif // liblldb_ThreadMachCore_h_
diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt
new file mode 100644
index 000000000000..ddc89cbd92c1
--- /dev/null
+++ b/source/Plugins/Process/minidump/CMakeLists.txt
@@ -0,0 +1,10 @@
+include_directories(../Utility)
+
+add_lldb_library(lldbPluginProcessMinidump
+ MinidumpTypes.cpp
+ MinidumpParser.cpp
+ RegisterContextMinidump_x86_32.cpp
+ RegisterContextMinidump_x86_64.cpp
+ ProcessMinidump.cpp
+ ThreadMinidump.cpp
+ )
diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp
new file mode 100644
index 000000000000..37b3709c09c1
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -0,0 +1,458 @@
+//===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "MinidumpParser.h"
+#include "NtStructures.h"
+#include "RegisterContextMinidump_x86_32.h"
+
+// Other libraries and framework includes
+#include "lldb/Target/MemoryRegionInfo.h"
+
+// C includes
+// C++ includes
+#include <map>
+
+using namespace lldb_private;
+using namespace minidump;
+
+llvm::Optional<MinidumpParser>
+MinidumpParser::Create(const lldb::DataBufferSP &data_buf_sp) {
+ if (data_buf_sp->GetByteSize() < sizeof(MinidumpHeader)) {
+ return llvm::None;
+ }
+
+ llvm::ArrayRef<uint8_t> header_data(data_buf_sp->GetBytes(),
+ sizeof(MinidumpHeader));
+ const MinidumpHeader *header = MinidumpHeader::Parse(header_data);
+
+ if (header == nullptr) {
+ return llvm::None;
+ }
+
+ lldb::offset_t directory_list_offset = header->stream_directory_rva;
+ // check if there is enough data for the parsing of the directory list
+ if ((directory_list_offset +
+ sizeof(MinidumpDirectory) * header->streams_count) >
+ data_buf_sp->GetByteSize()) {
+ return llvm::None;
+ }
+
+ const MinidumpDirectory *directory = nullptr;
+ Error error;
+ llvm::ArrayRef<uint8_t> directory_data(
+ data_buf_sp->GetBytes() + directory_list_offset,
+ sizeof(MinidumpDirectory) * header->streams_count);
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> directory_map;
+
+ for (uint32_t i = 0; i < header->streams_count; ++i) {
+ error = consumeObject(directory_data, directory);
+ if (error.Fail()) {
+ return llvm::None;
+ }
+ directory_map[static_cast<const uint32_t>(directory->stream_type)] =
+ directory->location;
+ }
+
+ return MinidumpParser(data_buf_sp, header, std::move(directory_map));
+}
+
+MinidumpParser::MinidumpParser(
+ const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header,
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &&directory_map)
+ : m_data_sp(data_buf_sp), m_header(header), m_directory_map(directory_map) {
+}
+
+llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
+ return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(),
+ m_data_sp->GetByteSize());
+}
+
+llvm::ArrayRef<uint8_t>
+MinidumpParser::GetStream(MinidumpStreamType stream_type) {
+ auto iter = m_directory_map.find(static_cast<uint32_t>(stream_type));
+ if (iter == m_directory_map.end())
+ return {};
+
+ // check if there is enough data
+ if (iter->second.rva + iter->second.data_size > m_data_sp->GetByteSize())
+ return {};
+
+ return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes() + iter->second.rva,
+ iter->second.data_size);
+}
+
+llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) {
+ auto arr_ref = m_data_sp->GetData();
+ if (rva > arr_ref.size())
+ return llvm::None;
+ arr_ref = arr_ref.drop_front(rva);
+ return parseMinidumpString(arr_ref);
+}
+
+llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::ThreadList);
+
+ if (data.size() == 0)
+ return llvm::None;
+
+ return MinidumpThread::ParseThreadList(data);
+}
+
+llvm::ArrayRef<uint8_t>
+MinidumpParser::GetThreadContext(const MinidumpThread &td) {
+ if (td.thread_context.rva + td.thread_context.data_size > GetData().size())
+ return {};
+
+ return GetData().slice(td.thread_context.rva, td.thread_context.data_size);
+}
+
+llvm::ArrayRef<uint8_t>
+MinidumpParser::GetThreadContextWow64(const MinidumpThread &td) {
+ // On Windows, a 32-bit process can run on a 64-bit machine under
+ // WOW64. If the minidump was captured with a 64-bit debugger, then
+ // the CONTEXT we just grabbed from the mini_dump_thread is the one
+ // for the 64-bit "native" process rather than the 32-bit "guest"
+ // process we care about. In this case, we can get the 32-bit CONTEXT
+ // from the TEB (Thread Environment Block) of the 64-bit process.
+ auto teb_mem = GetMemory(td.teb, sizeof(TEB64));
+ if (teb_mem.empty())
+ return {};
+
+ const TEB64 *wow64teb;
+ Error error = consumeObject(teb_mem, wow64teb);
+ if (error.Fail())
+ return {};
+
+ // Slot 1 of the thread-local storage in the 64-bit TEB points to a
+ // structure that includes the 32-bit CONTEXT (after a ULONG).
+ // See: https://msdn.microsoft.com/en-us/library/ms681670.aspx
+ auto context =
+ GetMemory(wow64teb->tls_slots[1] + 4, sizeof(MinidumpContext_x86_32));
+ if (context.size() < sizeof(MinidumpContext_x86_32))
+ return {};
+
+ return context;
+ // NOTE: We don't currently use the TEB for anything else. If we
+ // need it in the future, the 32-bit TEB is located according to the address
+ // stored in the first slot of the 64-bit TEB (wow64teb.Reserved1[0]).
+}
+
+const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::SystemInfo);
+
+ if (data.size() == 0)
+ return nullptr;
+
+ return MinidumpSystemInfo::Parse(data);
+}
+
+ArchSpec MinidumpParser::GetArchitecture() {
+ ArchSpec arch_spec;
+ const MinidumpSystemInfo *system_info = GetSystemInfo();
+
+ if (!system_info)
+ return arch_spec;
+
+ // TODO what to do about big endiand flavors of arm ?
+ // TODO set the arm subarch stuff if the minidump has info about it
+
+ llvm::Triple triple;
+ triple.setVendor(llvm::Triple::VendorType::UnknownVendor);
+
+ const MinidumpCPUArchitecture arch =
+ static_cast<const MinidumpCPUArchitecture>(
+ static_cast<const uint32_t>(system_info->processor_arch));
+
+ switch (arch) {
+ case MinidumpCPUArchitecture::X86:
+ triple.setArch(llvm::Triple::ArchType::x86);
+ break;
+ case MinidumpCPUArchitecture::AMD64:
+ triple.setArch(llvm::Triple::ArchType::x86_64);
+ break;
+ case MinidumpCPUArchitecture::ARM:
+ triple.setArch(llvm::Triple::ArchType::arm);
+ break;
+ case MinidumpCPUArchitecture::ARM64:
+ triple.setArch(llvm::Triple::ArchType::aarch64);
+ break;
+ default:
+ triple.setArch(llvm::Triple::ArchType::UnknownArch);
+ break;
+ }
+
+ const MinidumpOSPlatform os = static_cast<const MinidumpOSPlatform>(
+ static_cast<const uint32_t>(system_info->platform_id));
+
+ // TODO add all of the OSes that Minidump/breakpad distinguishes?
+ switch (os) {
+ case MinidumpOSPlatform::Win32S:
+ case MinidumpOSPlatform::Win32Windows:
+ case MinidumpOSPlatform::Win32NT:
+ case MinidumpOSPlatform::Win32CE:
+ triple.setOS(llvm::Triple::OSType::Win32);
+ break;
+ case MinidumpOSPlatform::Linux:
+ triple.setOS(llvm::Triple::OSType::Linux);
+ break;
+ case MinidumpOSPlatform::MacOSX:
+ triple.setOS(llvm::Triple::OSType::MacOSX);
+ break;
+ case MinidumpOSPlatform::Android:
+ triple.setOS(llvm::Triple::OSType::Linux);
+ triple.setEnvironment(llvm::Triple::EnvironmentType::Android);
+ break;
+ default:
+ triple.setOS(llvm::Triple::OSType::UnknownOS);
+ break;
+ }
+
+ arch_spec.SetTriple(triple);
+
+ return arch_spec;
+}
+
+const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MiscInfo);
+
+ if (data.size() == 0)
+ return nullptr;
+
+ return MinidumpMiscInfo::Parse(data);
+}
+
+llvm::Optional<LinuxProcStatus> MinidumpParser::GetLinuxProcStatus() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::LinuxProcStatus);
+
+ if (data.size() == 0)
+ return llvm::None;
+
+ return LinuxProcStatus::Parse(data);
+}
+
+llvm::Optional<lldb::pid_t> MinidumpParser::GetPid() {
+ const MinidumpMiscInfo *misc_info = GetMiscInfo();
+ if (misc_info != nullptr) {
+ return misc_info->GetPid();
+ }
+
+ llvm::Optional<LinuxProcStatus> proc_status = GetLinuxProcStatus();
+ if (proc_status.hasValue()) {
+ return proc_status->GetPid();
+ }
+
+ return llvm::None;
+}
+
+llvm::ArrayRef<MinidumpModule> MinidumpParser::GetModuleList() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::ModuleList);
+
+ if (data.size() == 0)
+ return {};
+
+ return MinidumpModule::ParseModuleList(data);
+}
+
+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;
+
+ 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);
+ }
+
+ return filtered_modules;
+}
+
+const MinidumpExceptionStream *MinidumpParser::GetExceptionStream() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::Exception);
+
+ if (data.size() == 0)
+ return nullptr;
+
+ return MinidumpExceptionStream::Parse(data);
+}
+
+llvm::Optional<minidump::Range>
+MinidumpParser::FindMemoryRange(lldb::addr_t addr) {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MemoryList);
+ llvm::ArrayRef<uint8_t> data64 = GetStream(MinidumpStreamType::Memory64List);
+
+ if (data.empty() && data64.empty())
+ return llvm::None;
+
+ if (!data.empty()) {
+ llvm::ArrayRef<MinidumpMemoryDescriptor> memory_list =
+ MinidumpMemoryDescriptor::ParseMemoryList(data);
+
+ if (memory_list.empty())
+ return llvm::None;
+
+ for (const auto &memory_desc : memory_list) {
+ const MinidumpLocationDescriptor &loc_desc = memory_desc.memory;
+ const lldb::addr_t range_start = memory_desc.start_of_memory_range;
+ const size_t range_size = loc_desc.data_size;
+
+ if (loc_desc.rva + loc_desc.data_size > GetData().size())
+ return llvm::None;
+
+ if (range_start <= addr && addr < range_start + range_size) {
+ return minidump::Range(range_start,
+ GetData().slice(loc_desc.rva, range_size));
+ }
+ }
+ }
+
+ // Some Minidumps have a Memory64ListStream that captures all the heap
+ // memory (full-memory Minidumps). We can't exactly use the same loop as
+ // above, because the Minidump uses slightly different data structures to
+ // describe those
+
+ if (!data64.empty()) {
+ llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
+ uint64_t base_rva;
+ std::tie(memory64_list, base_rva) =
+ MinidumpMemoryDescriptor64::ParseMemory64List(data64);
+
+ if (memory64_list.empty())
+ return llvm::None;
+
+ for (const auto &memory_desc64 : memory64_list) {
+ const lldb::addr_t range_start = memory_desc64.start_of_memory_range;
+ const size_t range_size = memory_desc64.data_size;
+
+ if (base_rva + range_size > GetData().size())
+ return llvm::None;
+
+ if (range_start <= addr && addr < range_start + range_size) {
+ return minidump::Range(range_start,
+ GetData().slice(base_rva, range_size));
+ }
+ base_rva += range_size;
+ }
+ }
+
+ return llvm::None;
+}
+
+llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
+ size_t size) {
+ // I don't have a sense of how frequently this is called or how many memory
+ // ranges a Minidump typically has, so I'm not sure if searching for the
+ // appropriate range linearly each time is stupid. Perhaps we should build
+ // an index for faster lookups.
+ llvm::Optional<minidump::Range> range = FindMemoryRange(addr);
+ if (!range)
+ return {};
+
+ // There's at least some overlap between the beginning of the desired range
+ // (addr) and the current range. Figure out where the overlap begins and
+ // how much overlap there is.
+
+ const size_t offset = addr - range->start;
+
+ if (addr < range->start || offset >= range->range_ref.size())
+ return {};
+
+ const size_t overlap = std::min(size, range->range_ref.size() - offset);
+ 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);
+ if (data.empty())
+ return llvm::None;
+
+ std::vector<const MinidumpMemoryInfo *> mem_info_list =
+ MinidumpMemoryInfo::ParseMemoryInfoList(data);
+ if (mem_info_list.empty())
+ return llvm::None;
+
+ const auto yes = MemoryRegionInfo::eYes;
+ const auto no = MemoryRegionInfo::eNo;
+
+ 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;
+ }
+ }
+
+ // 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;
+}
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
new file mode 100644
index 000000000000..67523a72ad11
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -0,0 +1,102 @@
+//===-- MinidumpParser.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_MinidumpParser_h_
+#define liblldb_MinidumpParser_h_
+
+// Project includes
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Error.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+
+// C includes
+
+// C++ includes
+#include <cstring>
+#include <unordered_map>
+
+namespace lldb_private {
+
+namespace minidump {
+
+// Describes a range of memory captured in the Minidump
+struct Range {
+ lldb::addr_t start; // virtual address of the beginning of the range
+ // range_ref - absolute pointer to the first byte of the range and size
+ llvm::ArrayRef<uint8_t> range_ref;
+
+ Range(lldb::addr_t start, llvm::ArrayRef<uint8_t> range_ref)
+ : start(start), range_ref(range_ref) {}
+};
+
+class MinidumpParser {
+public:
+ static llvm::Optional<MinidumpParser>
+ Create(const lldb::DataBufferSP &data_buf_sp);
+
+ llvm::ArrayRef<uint8_t> GetData();
+
+ llvm::ArrayRef<uint8_t> GetStream(MinidumpStreamType stream_type);
+
+ llvm::Optional<std::string> GetMinidumpString(uint32_t rva);
+
+ llvm::ArrayRef<MinidumpThread> GetThreads();
+
+ llvm::ArrayRef<uint8_t> GetThreadContext(const MinidumpThread &td);
+
+ llvm::ArrayRef<uint8_t> GetThreadContextWow64(const MinidumpThread &td);
+
+ const MinidumpSystemInfo *GetSystemInfo();
+
+ ArchSpec GetArchitecture();
+
+ const MinidumpMiscInfo *GetMiscInfo();
+
+ llvm::Optional<LinuxProcStatus> GetLinuxProcStatus();
+
+ llvm::Optional<lldb::pid_t> GetPid();
+
+ llvm::ArrayRef<MinidumpModule> GetModuleList();
+
+ // There are cases in which there is more than one record in the ModuleList
+ // for the same module name.(e.g. when the binary has non contiguous segments)
+ // So this function returns a filtered module list - if it finds records that
+ // have the same name, it keeps the copy with the lowest load address.
+ std::vector<const MinidumpModule *> GetFilteredModuleList();
+
+ const MinidumpExceptionStream *GetExceptionStream();
+
+ llvm::Optional<Range> FindMemoryRange(lldb::addr_t addr);
+
+ llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size);
+
+ llvm::Optional<MemoryRegionInfo> GetMemoryRegionInfo(lldb::addr_t);
+
+private:
+ lldb::DataBufferSP m_data_sp;
+ const MinidumpHeader *m_header;
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> m_directory_map;
+
+ MinidumpParser(
+ const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header,
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &&directory_map);
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_MinidumpParser_h_
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp
new file mode 100644
index 000000000000..863d124a7ccc
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -0,0 +1,235 @@
+//===-- MinidumpTypes.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+const MinidumpHeader *MinidumpHeader::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpHeader *header = nullptr;
+ Error error = consumeObject(data, header);
+
+ const MinidumpHeaderConstants signature =
+ static_cast<const MinidumpHeaderConstants>(
+ static_cast<const uint32_t>(header->signature));
+ const MinidumpHeaderConstants version =
+ static_cast<const MinidumpHeaderConstants>(
+ static_cast<const uint32_t>(header->version) & 0x0000ffff);
+ // the high 16 bits of the version field are implementation specific
+
+ if (error.Fail() || signature != MinidumpHeaderConstants::Signature ||
+ version != MinidumpHeaderConstants::Version)
+ return nullptr;
+
+ // TODO check for max number of streams ?
+ // TODO more sanity checks ?
+
+ return header;
+}
+
+// Minidump string
+llvm::Optional<std::string>
+lldb_private::minidump::parseMinidumpString(llvm::ArrayRef<uint8_t> &data) {
+ std::string result;
+
+ const uint32_t *source_length;
+ Error error = consumeObject(data, source_length);
+ if (error.Fail() || *source_length > data.size() || *source_length % 2 != 0)
+ return llvm::None;
+
+ auto source_start = reinterpret_cast<const llvm::UTF16 *>(data.data());
+ // source_length is the length of the string in bytes
+ // we need the length of the string in UTF-16 characters/code points (16 bits
+ // per char)
+ // that's why it's divided by 2
+ const auto source_end = source_start + (*source_length) / 2;
+ // resize to worst case length
+ result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * (*source_length) / 2);
+ auto result_start = reinterpret_cast<llvm::UTF8 *>(&result[0]);
+ const auto result_end = result_start + result.size();
+ llvm::ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end,
+ llvm::strictConversion);
+ const auto result_size =
+ std::distance(reinterpret_cast<llvm::UTF8 *>(&result[0]), result_start);
+ result.resize(result_size); // shrink to actual length
+
+ return result;
+}
+
+// MinidumpThread
+const MinidumpThread *MinidumpThread::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpThread *thread = nullptr;
+ Error error = consumeObject(data, thread);
+ if (error.Fail())
+ return nullptr;
+
+ return thread;
+}
+
+llvm::ArrayRef<MinidumpThread>
+MinidumpThread::ParseThreadList(llvm::ArrayRef<uint8_t> &data) {
+ const llvm::support::ulittle32_t *thread_count;
+ Error error = consumeObject(data, thread_count);
+ if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size())
+ return {};
+
+ return llvm::ArrayRef<MinidumpThread>(
+ reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count);
+}
+
+// MinidumpSystemInfo
+const MinidumpSystemInfo *
+MinidumpSystemInfo::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpSystemInfo *system_info;
+ Error error = consumeObject(data, system_info);
+ if (error.Fail())
+ return nullptr;
+
+ return system_info;
+}
+
+// MinidumpMiscInfo
+const MinidumpMiscInfo *MinidumpMiscInfo::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpMiscInfo *misc_info;
+ Error error = consumeObject(data, misc_info);
+ if (error.Fail())
+ return nullptr;
+
+ return misc_info;
+}
+
+llvm::Optional<lldb::pid_t> MinidumpMiscInfo::GetPid() const {
+ uint32_t pid_flag =
+ static_cast<const uint32_t>(MinidumpMiscInfoFlags::ProcessID);
+ if (flags1 & pid_flag)
+ return llvm::Optional<lldb::pid_t>(process_id);
+
+ return llvm::None;
+}
+
+// Linux Proc Status
+// it's stored as an ascii string in the file
+llvm::Optional<LinuxProcStatus>
+LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) {
+ LinuxProcStatus result;
+ result.proc_status =
+ llvm::StringRef(reinterpret_cast<const char *>(data.data()), data.size());
+ data = data.drop_front(data.size());
+
+ llvm::SmallVector<llvm::StringRef, 0> lines;
+ result.proc_status.split(lines, '\n', 42);
+ // /proc/$pid/status has 41 lines, but why not use 42?
+ for (auto line : lines) {
+ if (line.consume_front("Pid:")) {
+ line = line.trim();
+ if (!line.getAsInteger(10, result.pid))
+ return result;
+ }
+ }
+
+ return llvm::None;
+}
+
+lldb::pid_t LinuxProcStatus::GetPid() const { return pid; }
+
+// Module stuff
+const MinidumpModule *MinidumpModule::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpModule *module = nullptr;
+ Error error = consumeObject(data, module);
+ if (error.Fail())
+ return nullptr;
+
+ return module;
+}
+
+llvm::ArrayRef<MinidumpModule>
+MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) {
+
+ const llvm::support::ulittle32_t *modules_count;
+ Error error = consumeObject(data, modules_count);
+ if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size())
+ return {};
+
+ return llvm::ArrayRef<MinidumpModule>(
+ reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count);
+}
+
+// Exception stuff
+const MinidumpExceptionStream *
+MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpExceptionStream *exception_stream = nullptr;
+ Error error = consumeObject(data, exception_stream);
+ if (error.Fail())
+ return nullptr;
+
+ return exception_stream;
+}
+
+llvm::ArrayRef<MinidumpMemoryDescriptor>
+MinidumpMemoryDescriptor::ParseMemoryList(llvm::ArrayRef<uint8_t> &data) {
+ const llvm::support::ulittle32_t *mem_ranges_count;
+ Error error = consumeObject(data, mem_ranges_count);
+ if (error.Fail() ||
+ *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) > data.size())
+ return {};
+
+ return llvm::makeArrayRef(
+ reinterpret_cast<const MinidumpMemoryDescriptor *>(data.data()),
+ *mem_ranges_count);
+}
+
+std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
+MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) {
+ const llvm::support::ulittle64_t *mem_ranges_count;
+ Error error = consumeObject(data, mem_ranges_count);
+ if (error.Fail() ||
+ *mem_ranges_count * sizeof(MinidumpMemoryDescriptor64) > data.size())
+ return {};
+
+ const llvm::support::ulittle64_t *base_rva;
+ error = consumeObject(data, base_rva);
+ if (error.Fail())
+ return {};
+
+ return std::make_pair(
+ llvm::makeArrayRef(
+ reinterpret_cast<const MinidumpMemoryDescriptor64 *>(data.data()),
+ *mem_ranges_count),
+ *base_rva);
+}
+
+std::vector<const MinidumpMemoryInfo *>
+MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpMemoryInfoListHeader *header;
+ Error error = consumeObject(data, header);
+ if (error.Fail() ||
+ header->size_of_header < sizeof(MinidumpMemoryInfoListHeader) ||
+ header->size_of_entry < sizeof(MinidumpMemoryInfo))
+ return {};
+
+ data = data.drop_front(header->size_of_header -
+ sizeof(MinidumpMemoryInfoListHeader));
+
+ if (header->size_of_entry * header->num_of_entries > data.size())
+ return {};
+
+ std::vector<const MinidumpMemoryInfo *> result;
+ 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));
+ }
+
+ return result;
+}
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h
new file mode 100644
index 000000000000..46871a1b84d8
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -0,0 +1,470 @@
+//===-- MinidumpTypes.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_MinidumpTypes_h_
+#define liblldb_MinidumpTypes_h_
+
+// Project includes
+
+// Other libraries and framework includes
+#include "lldb/Core/Error.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+
+// C includes
+// C++ includes
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms679293(v=vs.85).aspx
+// https://chromium.googlesource.com/breakpad/breakpad/
+
+namespace lldb_private {
+
+namespace minidump {
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+enum class MinidumpHeaderConstants : uint32_t {
+ Signature = 0x504d444d, // 'PMDM'
+ Version = 0x0000a793, // 42899
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Signature)
+
+};
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680394.aspx
+enum class MinidumpStreamType : uint32_t {
+ Unused = 0,
+ Reserved0 = 1,
+ Reserved1 = 2,
+ ThreadList = 3,
+ ModuleList = 4,
+ MemoryList = 5,
+ Exception = 6,
+ SystemInfo = 7,
+ ThreadExList = 8,
+ Memory64List = 9,
+ CommentA = 10,
+ CommentW = 11,
+ HandleData = 12,
+ FunctionTable = 13,
+ UnloadedModuleList = 14,
+ MiscInfo = 15,
+ MemoryInfoList = 16,
+ ThreadInfoList = 17,
+ HandleOperationList = 18,
+ Token = 19,
+ JavascriptData = 20,
+ SystemMemoryInfo = 21,
+ ProcessVMCounters = 22,
+ LastReserved = 0x0000ffff,
+
+ /* Breakpad extension types. 0x4767 = "Gg" */
+ BreakpadInfo = 0x47670001,
+ AssertionInfo = 0x47670002,
+ /* These are additional minidump stream values which are specific to
+ * the linux breakpad implementation. */
+ LinuxCPUInfo = 0x47670003, /* /proc/cpuinfo */
+ LinuxProcStatus = 0x47670004, /* /proc/$x/status */
+ LinuxLSBRelease = 0x47670005, /* /etc/lsb-release */
+ LinuxCMDLine = 0x47670006, /* /proc/$x/cmdline */
+ LinuxEnviron = 0x47670007, /* /proc/$x/environ */
+ LinuxAuxv = 0x47670008, /* /proc/$x/auxv */
+ LinuxMaps = 0x47670009, /* /proc/$x/maps */
+ LinuxDSODebug = 0x4767000A
+};
+
+// for MinidumpSystemInfo.processor_arch
+enum class MinidumpCPUArchitecture : uint16_t {
+ X86 = 0, /* PROCESSOR_ARCHITECTURE_INTEL */
+ MIPS = 1, /* PROCESSOR_ARCHITECTURE_MIPS */
+ Alpha = 2, /* PROCESSOR_ARCHITECTURE_ALPHA */
+ PPC = 3, /* PROCESSOR_ARCHITECTURE_PPC */
+ SHX = 4, /* PROCESSOR_ARCHITECTURE_SHX (Super-H) */
+ ARM = 5, /* PROCESSOR_ARCHITECTURE_ARM */
+ IA64 = 6, /* PROCESSOR_ARCHITECTURE_IA64 */
+ Alpha64 = 7, /* PROCESSOR_ARCHITECTURE_ALPHA64 */
+ MSIL = 8, /* PROCESSOR_ARCHITECTURE_MSIL
+ * (Microsoft Intermediate Language) */
+ AMD64 = 9, /* PROCESSOR_ARCHITECTURE_AMD64 */
+ X86Win64 = 10, /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
+ SPARC = 0x8001, /* Breakpad-defined value for SPARC */
+ PPC64 = 0x8002, /* Breakpad-defined value for PPC64 */
+ ARM64 = 0x8003, /* Breakpad-defined value for ARM64 */
+ MIPS64 = 0x8004, /* Breakpad-defined value for MIPS64 */
+ Unknown = 0xffff /* PROCESSOR_ARCHITECTURE_UNKNOWN */
+};
+
+// for MinidumpSystemInfo.platform_id
+enum class MinidumpOSPlatform : uint32_t {
+ Win32S = 0, /* VER_PLATFORM_WIN32s (Windows 3.1) */
+ Win32Windows = 1, /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
+ Win32NT = 2, /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
+ Win32CE = 3, /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
+ * (Windows CE, Windows Mobile, "Handheld") */
+
+ /* The following values are Breakpad-defined. */
+ Unix = 0x8000, /* Generic Unix-ish */
+ MacOSX = 0x8101, /* Mac OS X/Darwin */
+ IOS = 0x8102, /* iOS */
+ Linux = 0x8201, /* Linux */
+ Solaris = 0x8202, /* Solaris */
+ Android = 0x8203, /* Android */
+ PS3 = 0x8204, /* PS3 */
+ NaCl = 0x8205 /* Native Client (NaCl) */
+};
+
+// For MinidumpCPUInfo.arm_cpu_info.elf_hwcaps.
+// This matches the Linux kernel definitions from <asm/hwcaps.h>
+enum class MinidumpPCPUInformationARMElfHwCaps : uint32_t {
+ SWP = (1 << 0),
+ Half = (1 << 1),
+ Thumb = (1 << 2),
+ _26BIT = (1 << 3),
+ FastMult = (1 << 4),
+ FPA = (1 << 5),
+ VFP = (1 << 6),
+ EDSP = (1 << 7),
+ Java = (1 << 8),
+ IWMMXT = (1 << 9),
+ Crunch = (1 << 10),
+ ThumbEE = (1 << 11),
+ Neon = (1 << 12),
+ VFPv3 = (1 << 13),
+ VFPv3D16 = (1 << 14),
+ TLS = (1 << 15),
+ VFPv4 = (1 << 16),
+ IDIVA = (1 << 17),
+ IDIVT = (1 << 18),
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IDIVT)
+};
+
+enum class MinidumpMiscInfoFlags : uint32_t {
+ ProcessID = (1 << 0),
+ ProcessTimes = (1 << 1),
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ ProcessTimes)
+};
+
+template <typename T>
+Error consumeObject(llvm::ArrayRef<uint8_t> &Buffer, const T *&Object) {
+ Error error;
+ if (Buffer.size() < sizeof(T)) {
+ error.SetErrorString("Insufficient buffer!");
+ return error;
+ }
+
+ Object = reinterpret_cast<const T *>(Buffer.data());
+ Buffer = Buffer.drop_front(sizeof(T));
+ return error;
+}
+
+// parse a MinidumpString which is with UTF-16
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680395(v=vs.85).aspx
+llvm::Optional<std::string> parseMinidumpString(llvm::ArrayRef<uint8_t> &data);
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680378(v=vs.85).aspx
+struct MinidumpHeader {
+ llvm::support::ulittle32_t signature;
+ llvm::support::ulittle32_t
+ version; // The high 16 bits of version field are implementation specific
+ llvm::support::ulittle32_t streams_count;
+ llvm::support::ulittle32_t
+ stream_directory_rva; // offset of the stream directory
+ llvm::support::ulittle32_t checksum;
+ llvm::support::ulittle32_t time_date_stamp; // time_t format
+ llvm::support::ulittle64_t flags;
+
+ static const MinidumpHeader *Parse(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpHeader) == 32,
+ "sizeof MinidumpHeader is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680383.aspx
+struct MinidumpLocationDescriptor {
+ llvm::support::ulittle32_t data_size;
+ llvm::support::ulittle32_t rva;
+};
+static_assert(sizeof(MinidumpLocationDescriptor) == 8,
+ "sizeof MinidumpLocationDescriptor is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680384(v=vs.85).aspx
+struct MinidumpMemoryDescriptor {
+ llvm::support::ulittle64_t start_of_memory_range;
+ MinidumpLocationDescriptor memory;
+
+ static llvm::ArrayRef<MinidumpMemoryDescriptor>
+ ParseMemoryList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpMemoryDescriptor) == 16,
+ "sizeof MinidumpMemoryDescriptor is not correct!");
+
+struct MinidumpMemoryDescriptor64 {
+ llvm::support::ulittle64_t start_of_memory_range;
+ llvm::support::ulittle64_t data_size;
+
+ static std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
+ ParseMemory64List(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpMemoryDescriptor64) == 16,
+ "sizeof MinidumpMemoryDescriptor64 is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680365.aspx
+struct MinidumpDirectory {
+ llvm::support::ulittle32_t stream_type;
+ MinidumpLocationDescriptor location;
+};
+static_assert(sizeof(MinidumpDirectory) == 12,
+ "sizeof MinidumpDirectory is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680385(v=vs.85).aspx
+struct MinidumpMemoryInfoListHeader {
+ llvm::support::ulittle32_t size_of_header;
+ llvm::support::ulittle32_t size_of_entry;
+ llvm::support::ulittle64_t num_of_entries;
+};
+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,
+ MemReserve = 0x2000,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree)
+};
+
+enum class MinidumpMemoryInfoType : uint32_t {
+ MemImage = 0x1000000,
+ MemMapped = 0x40000,
+ MemPrivate = 0x20000,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage)
+};
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
+enum class MinidumpMemoryProtectionContants : uint32_t {
+ PageExecute = 0x10,
+ PageExecuteRead = 0x20,
+ PageExecuteReadWrite = 0x40,
+ PageExecuteWriteCopy = 0x80,
+ PageNoAccess = 0x01,
+ PageReadOnly = 0x02,
+ PageReadWrite = 0x04,
+ PageWriteCopy = 0x08,
+ PageTargetsInvalid = 0x40000000,
+ PageTargetsNoUpdate = 0x40000000,
+
+ PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite |
+ PageWriteCopy,
+ PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite |
+ PageExecuteWriteCopy,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid)
+};
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx
+struct MinidumpThread {
+ llvm::support::ulittle32_t thread_id;
+ llvm::support::ulittle32_t suspend_count;
+ llvm::support::ulittle32_t priority_class;
+ llvm::support::ulittle32_t priority;
+ llvm::support::ulittle64_t teb;
+ MinidumpMemoryDescriptor stack;
+ MinidumpLocationDescriptor thread_context;
+
+ static const MinidumpThread *Parse(llvm::ArrayRef<uint8_t> &data);
+
+ static llvm::ArrayRef<MinidumpThread>
+ ParseThreadList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpThread) == 48,
+ "sizeof MinidumpThread is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
+union MinidumpCPUInfo {
+ struct {
+ llvm::support::ulittle32_t vendor_id[3]; /* cpuid 0: ebx, edx, ecx */
+ llvm::support::ulittle32_t version_information; /* cpuid 1: eax */
+ llvm::support::ulittle32_t feature_information; /* cpuid 1: edx */
+ llvm::support::ulittle32_t
+ amd_extended_cpu_features; /* cpuid 0x80000001, ebx */
+ } x86_cpu_info;
+ struct {
+ llvm::support::ulittle32_t cpuid;
+ llvm::support::ulittle32_t elf_hwcaps; /* linux specific, 0 otherwise */
+ } arm_cpu_info;
+ struct {
+ llvm::support::ulittle64_t processor_features[2];
+ } other_cpu_info;
+};
+static_assert(sizeof(MinidumpCPUInfo) == 24,
+ "sizeof MinidumpCPUInfo is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
+struct MinidumpSystemInfo {
+ llvm::support::ulittle16_t processor_arch;
+ llvm::support::ulittle16_t processor_level;
+ llvm::support::ulittle16_t processor_revision;
+
+ uint8_t number_of_processors;
+ uint8_t product_type;
+
+ llvm::support::ulittle32_t major_version;
+ llvm::support::ulittle32_t minor_version;
+ llvm::support::ulittle32_t build_number;
+ llvm::support::ulittle32_t platform_id;
+ llvm::support::ulittle32_t csd_version_rva;
+
+ llvm::support::ulittle16_t suit_mask;
+ llvm::support::ulittle16_t reserved2;
+
+ MinidumpCPUInfo cpu;
+
+ static const MinidumpSystemInfo *Parse(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpSystemInfo) == 56,
+ "sizeof MinidumpSystemInfo is not correct!");
+
+// TODO misc2, misc3 ?
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx
+struct MinidumpMiscInfo {
+ llvm::support::ulittle32_t size;
+ // flags1 represents what info in the struct is valid
+ llvm::support::ulittle32_t flags1;
+ llvm::support::ulittle32_t process_id;
+ llvm::support::ulittle32_t process_create_time;
+ llvm::support::ulittle32_t process_user_time;
+ llvm::support::ulittle32_t process_kernel_time;
+
+ static const MinidumpMiscInfo *Parse(llvm::ArrayRef<uint8_t> &data);
+
+ llvm::Optional<lldb::pid_t> GetPid() const;
+};
+static_assert(sizeof(MinidumpMiscInfo) == 24,
+ "sizeof MinidumpMiscInfo is not correct!");
+
+// The /proc/pid/status is saved as an ascii string in the file
+class LinuxProcStatus {
+public:
+ llvm::StringRef proc_status;
+ lldb::pid_t pid;
+
+ static llvm::Optional<LinuxProcStatus> Parse(llvm::ArrayRef<uint8_t> &data);
+
+ lldb::pid_t GetPid() const;
+
+private:
+ LinuxProcStatus() = default;
+};
+
+// MinidumpModule stuff
+struct MinidumpVSFixedFileInfo {
+ llvm::support::ulittle32_t signature;
+ llvm::support::ulittle32_t struct_version;
+ llvm::support::ulittle32_t file_version_hi;
+ llvm::support::ulittle32_t file_version_lo;
+ llvm::support::ulittle32_t product_version_hi;
+ llvm::support::ulittle32_t product_version_lo;
+ // file_flags_mask - identifies valid bits in fileFlags
+ llvm::support::ulittle32_t file_flags_mask;
+ llvm::support::ulittle32_t file_flags;
+ llvm::support::ulittle32_t file_os;
+ llvm::support::ulittle32_t file_type;
+ llvm::support::ulittle32_t file_subtype;
+ llvm::support::ulittle32_t file_date_hi;
+ llvm::support::ulittle32_t file_date_lo;
+};
+static_assert(sizeof(MinidumpVSFixedFileInfo) == 52,
+ "sizeof MinidumpVSFixedFileInfo is not correct!");
+
+struct MinidumpModule {
+ llvm::support::ulittle64_t base_of_image;
+ llvm::support::ulittle32_t size_of_image;
+ llvm::support::ulittle32_t checksum;
+ llvm::support::ulittle32_t time_date_stamp;
+ llvm::support::ulittle32_t module_name_rva;
+ MinidumpVSFixedFileInfo version_info;
+ MinidumpLocationDescriptor CV_record;
+ MinidumpLocationDescriptor misc_record;
+ llvm::support::ulittle32_t reserved0[2];
+ llvm::support::ulittle32_t reserved1[2];
+
+ static const MinidumpModule *Parse(llvm::ArrayRef<uint8_t> &data);
+
+ static llvm::ArrayRef<MinidumpModule>
+ ParseModuleList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpModule) == 108,
+ "sizeof MinidumpVSFixedFileInfo is not correct!");
+
+// Exception stuff
+struct MinidumpException {
+ enum : unsigned {
+ ExceptonInfoMaxParams = 15,
+ DumpRequested = 0xFFFFFFFF,
+ };
+
+ llvm::support::ulittle32_t exception_code;
+ llvm::support::ulittle32_t exception_flags;
+ llvm::support::ulittle64_t exception_record;
+ llvm::support::ulittle64_t exception_address;
+ llvm::support::ulittle32_t number_parameters;
+ llvm::support::ulittle32_t unused_alignment;
+ llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams];
+};
+static_assert(sizeof(MinidumpException) == 152,
+ "sizeof MinidumpException is not correct!");
+
+struct MinidumpExceptionStream {
+ llvm::support::ulittle32_t thread_id;
+ llvm::support::ulittle32_t alignment;
+ MinidumpException exception_record;
+ MinidumpLocationDescriptor thread_context;
+
+ static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpExceptionStream) == 168,
+ "sizeof MinidumpExceptionStream is not correct!");
+
+} // namespace minidump
+} // namespace lldb_private
+#endif // liblldb_MinidumpTypes_h_
diff --git a/source/Plugins/Process/minidump/NtStructures.h b/source/Plugins/Process/minidump/NtStructures.h
new file mode 100644
index 000000000000..c0afd77358cd
--- /dev/null
+++ b/source/Plugins/Process/minidump/NtStructures.h
@@ -0,0 +1,37 @@
+//===-- NtStructures.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_Plugins_Process_Minidump_NtStructures_h_
+#define liblldb_Plugins_Process_Minidump_NtStructures_h_
+
+#include "llvm/Support/Endian.h"
+
+namespace lldb_private {
+
+namespace minidump {
+
+// This describes the layout of a TEB (Thread Environment Block) for a 64-bit
+// process. It's adapted from the 32-bit TEB in winternl.h. Currently, we care
+// only about the position of the tls_slots.
+struct TEB64 {
+ llvm::support::ulittle64_t reserved1[12];
+ llvm::support::ulittle64_t process_environment_block;
+ llvm::support::ulittle64_t reserved2[399];
+ uint8_t reserved3[1952];
+ llvm::support::ulittle64_t tls_slots[64];
+ uint8_t reserved4[8];
+ llvm::support::ulittle64_t reserved5[26];
+ llvm::support::ulittle64_t reserved_for_ole; // Windows 2000 only
+ llvm::support::ulittle64_t reserved6[4];
+ llvm::support::ulittle64_t tls_expansion_slots;
+};
+
+#endif // liblldb_Plugins_Process_Minidump_NtStructures_h_
+} // namespace minidump
+} // namespace lldb_private
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp
new file mode 100644
index 000000000000..46d8df8b16f1
--- /dev/null
+++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -0,0 +1,301 @@
+//===-- ProcessMinidump.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "ProcessMinidump.h"
+#include "ThreadMinidump.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Log.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/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+ConstString ProcessMinidump::GetPluginNameStatic() {
+ static ConstString g_name("minidump");
+ return g_name;
+}
+
+const char *ProcessMinidump::GetPluginDescriptionStatic() {
+ return "Minidump plug-in.";
+}
+
+lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file) {
+ if (!crash_file)
+ return nullptr;
+
+ lldb::ProcessSP process_sp;
+ // Read enough data for the Minidump header
+ const size_t header_size = sizeof(MinidumpHeader);
+ lldb::DataBufferSP data_sp(crash_file->MemoryMapFileContents(0, header_size));
+ if (!data_sp)
+ return nullptr;
+
+ // first, only try to parse the header, beacuse we need to be fast
+ llvm::ArrayRef<uint8_t> header_data(data_sp->GetBytes(), header_size);
+ const MinidumpHeader *header = MinidumpHeader::Parse(header_data);
+
+ if (data_sp->GetByteSize() != header_size || header == nullptr)
+ return nullptr;
+
+ lldb::DataBufferSP all_data_sp(crash_file->MemoryMapFileContents());
+ auto minidump_parser = MinidumpParser::Create(all_data_sp);
+ // check if the parser object is valid
+ if (!minidump_parser)
+ return nullptr;
+
+ return std::make_shared<ProcessMinidump>(target_sp, listener_sp, *crash_file,
+ minidump_parser.getValue());
+}
+
+bool ProcessMinidump::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ return true;
+}
+
+ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec &core_file,
+ MinidumpParser minidump_parser)
+ : Process(target_sp, listener_sp), m_minidump_parser(minidump_parser),
+ m_core_file(core_file), m_is_wow64(false) {}
+
+ProcessMinidump::~ProcessMinidump() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
+}
+
+void ProcessMinidump::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ ProcessMinidump::CreateInstance);
+ });
+}
+
+void ProcessMinidump::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessMinidump::CreateInstance);
+}
+
+Error ProcessMinidump::DoLoadCore() {
+ Error error;
+
+ m_thread_list = m_minidump_parser.GetThreads();
+ m_active_exception = m_minidump_parser.GetExceptionStream();
+ ReadModuleList();
+ GetTarget().SetArchitecture(GetArchitecture());
+
+ llvm::Optional<lldb::pid_t> pid = m_minidump_parser.GetPid();
+ if (!pid) {
+ error.SetErrorString("failed to parse PID");
+ return error;
+ }
+ SetID(pid.getValue());
+
+ 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; }
+
+Error ProcessMinidump::DoDestroy() { return Error(); }
+
+void ProcessMinidump::RefreshStateAfterStop() {
+ if (!m_active_exception)
+ return;
+
+ if (m_active_exception->exception_record.exception_code ==
+ MinidumpException::DumpRequested) {
+ return;
+ }
+
+ lldb::StopInfoSP stop_info;
+ lldb::ThreadSP stop_thread;
+
+ Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id);
+ stop_thread = Process::m_thread_list.GetSelectedThread();
+ ArchSpec arch = GetArchitecture();
+
+ if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
+ stop_info = StopInfo::CreateStopReasonWithSignal(
+ *stop_thread, m_active_exception->exception_record.exception_code);
+ } else {
+ std::string desc;
+ llvm::raw_string_ostream desc_stream(desc);
+ desc_stream << "Exception "
+ << llvm::format_hex(
+ m_active_exception->exception_record.exception_code, 8)
+ << " encountered at address "
+ << llvm::format_hex(
+ m_active_exception->exception_record.exception_address,
+ 8);
+ stop_info = StopInfo::CreateStopReasonWithException(
+ *stop_thread, desc_stream.str().c_str());
+ }
+
+ stop_thread->SetStopInfo(stop_info);
+}
+
+bool ProcessMinidump::IsAlive() { return true; }
+
+bool ProcessMinidump::WarnBeforeDetach() const { return false; }
+
+size_t ProcessMinidump::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since we have it all cached in our dump file anyway.
+ return DoReadMemory(addr, buf, size, error);
+}
+
+size_t ProcessMinidump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+
+ llvm::ArrayRef<uint8_t> mem = m_minidump_parser.GetMemory(addr, size);
+ if (mem.empty()) {
+ error.SetErrorString("could not parse memory info");
+ return 0;
+ }
+
+ std::memcpy(buf, mem.data(), mem.size());
+ return mem.size();
+}
+
+ArchSpec ProcessMinidump::GetArchitecture() {
+ if (!m_is_wow64) {
+ return m_minidump_parser.GetArchitecture();
+ }
+
+ llvm::Triple triple;
+ triple.setVendor(llvm::Triple::VendorType::UnknownVendor);
+ triple.setArch(llvm::Triple::ArchType::x86);
+ triple.setOS(llvm::Triple::OSType::Win32);
+ return ArchSpec(triple);
+}
+
+Error ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ Error 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;
+}
+
+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 (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]);
+ else
+ context = m_minidump_parser.GetThreadContextWow64(m_thread_list[tid]);
+
+ lldb::ThreadSP thread_sp(
+ new ThreadMinidump(*this, m_thread_list[tid], context));
+ new_thread_list.AddThread(thread_sp);
+ }
+ return new_thread_list.GetSize(false) > 0;
+}
+
+void ProcessMinidump::ReadModuleList() {
+ std::vector<const MinidumpModule *> filtered_modules =
+ m_minidump_parser.GetFilteredModuleList();
+
+ for (auto module : filtered_modules) {
+ llvm::Optional<std::string> name =
+ m_minidump_parser.GetMinidumpString(module->module_name_rva);
+
+ if (!name)
+ continue;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ if (log) {
+ log->Printf("ProcessMinidump::%s found module: name: %s %#010" PRIx64
+ "-%#010" PRIx64 " size: %" PRIu32,
+ __FUNCTION__, name.getValue().c_str(),
+ uint64_t(module->base_of_image),
+ module->base_of_image + module->size_of_image,
+ uint32_t(module->size_of_image));
+ }
+
+ // check if the process is wow64 - a 32 bit windows process running on a
+ // 64 bit windows
+ if (llvm::StringRef(name.getValue()).endswith_lower("wow64.dll")) {
+ m_is_wow64 = true;
+ }
+
+ const auto file_spec = FileSpec(name.getValue(), true);
+ ModuleSpec module_spec = file_spec;
+ Error error;
+ lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error);
+ if (!module_sp || error.Fail()) {
+ continue;
+ }
+
+ if (log) {
+ log->Printf("ProcessMinidump::%s load module: name: %s", __FUNCTION__,
+ name.getValue().c_str());
+ }
+
+ bool load_addr_changed = false;
+ module_sp->SetLoadAddress(GetTarget(), module->base_of_image, false,
+ load_addr_changed);
+ }
+}
+
+bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) {
+ info.Clear();
+ info.SetProcessID(GetID());
+ info.SetArchitecture(GetArchitecture());
+ lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+ if (module_sp) {
+ const bool add_exe_file_as_first_arg = false;
+ info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
+ add_exe_file_as_first_arg);
+ }
+ return true;
+}
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
new file mode 100644
index 000000000000..78eadc809a4d
--- /dev/null
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -0,0 +1,105 @@
+//===-- ProcessMinidump.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_ProcessMinidump_h_
+#define liblldb_ProcessMinidump_h_
+
+// Project includes
+#include "MinidumpParser.h"
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+// C Includes
+// C++ Includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+class ProcessMinidump : public Process {
+public:
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ ProcessMinidump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const FileSpec &core_file, MinidumpParser minidump_parser);
+
+ ~ProcessMinidump() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ Error DoLoadCore() override;
+
+ DynamicLoader *GetDynamicLoader() override;
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ bool IsAlive() override;
+
+ bool WarnBeforeDetach() const override;
+
+ size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) override;
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) override;
+
+ ArchSpec GetArchitecture();
+
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
+ bool GetProcessInfo(ProcessInstanceInfo &info) override;
+
+ MinidumpParser m_minidump_parser;
+
+protected:
+ void Clear();
+
+ bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
+
+ void ReadModuleList();
+
+private:
+ FileSpec m_core_file;
+ llvm::ArrayRef<MinidumpThread> m_thread_list;
+ const MinidumpExceptionStream *m_active_exception;
+ bool m_is_wow64;
+};
+
+} // namespace minidump
+} // namespace lldb_private
+
+#endif // liblldb_ProcessMinidump_h_
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
new file mode 100644
index 000000000000..7f3768216f3a
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
@@ -0,0 +1,99 @@
+//===-- RegisterContextMinidump_x86_32.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "RegisterContextMinidump_x86_32.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+static void writeRegister(const void *reg_src,
+ llvm::MutableArrayRef<uint8_t> reg_dest) {
+ memcpy(reg_dest.data(), reg_src, reg_dest.size());
+}
+
+lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_32(
+ llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface) {
+
+ const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo();
+
+ lldb::DataBufferSP result_context_buf(
+ new DataBufferHeap(target_reg_interface->GetGPRSize(), 0));
+ uint8_t *result_base = result_context_buf->GetBytes();
+
+ if (source_data.size() < sizeof(MinidumpContext_x86_32))
+ return nullptr;
+
+ const MinidumpContext_x86_32 *context;
+ consumeObject(source_data, context);
+
+ const MinidumpContext_x86_32_Flags context_flags =
+ static_cast<MinidumpContext_x86_32_Flags>(
+ static_cast<uint32_t>(context->context_flags));
+ auto x86_32_Flag = MinidumpContext_x86_32_Flags::x86_32_Flag;
+ auto ControlFlag = MinidumpContext_x86_32_Flags::Control;
+ auto IntegerFlag = MinidumpContext_x86_32_Flags::Integer;
+ auto SegmentsFlag = MinidumpContext_x86_32_Flags::Segments;
+
+ if ((context_flags & x86_32_Flag) != x86_32_Flag) {
+ return nullptr;
+ }
+
+ if ((context_flags & ControlFlag) == ControlFlag) {
+ writeRegister(&context->ebp,
+ reg_info[lldb_ebp_i386].mutable_data(result_base));
+ writeRegister(&context->eip,
+ reg_info[lldb_eip_i386].mutable_data(result_base));
+ writeRegister(&context->cs,
+ reg_info[lldb_cs_i386].mutable_data(result_base));
+ writeRegister(&context->eflags,
+ reg_info[lldb_eflags_i386].mutable_data(result_base));
+ writeRegister(&context->esp,
+ reg_info[lldb_esp_i386].mutable_data(result_base));
+ writeRegister(&context->ss,
+ reg_info[lldb_ss_i386].mutable_data(result_base));
+ }
+
+ if ((context_flags & SegmentsFlag) == SegmentsFlag) {
+ writeRegister(&context->ds,
+ reg_info[lldb_ds_i386].mutable_data(result_base));
+ writeRegister(&context->es,
+ reg_info[lldb_es_i386].mutable_data(result_base));
+ writeRegister(&context->fs,
+ reg_info[lldb_fs_i386].mutable_data(result_base));
+ writeRegister(&context->gs,
+ reg_info[lldb_gs_i386].mutable_data(result_base));
+ }
+
+ if ((context_flags & IntegerFlag) == IntegerFlag) {
+ writeRegister(&context->eax,
+ reg_info[lldb_eax_i386].mutable_data(result_base));
+ writeRegister(&context->ecx,
+ reg_info[lldb_ecx_i386].mutable_data(result_base));
+ writeRegister(&context->edx,
+ reg_info[lldb_edx_i386].mutable_data(result_base));
+ writeRegister(&context->ebx,
+ reg_info[lldb_ebx_i386].mutable_data(result_base));
+ writeRegister(&context->esi,
+ reg_info[lldb_esi_i386].mutable_data(result_base));
+ writeRegister(&context->edi,
+ reg_info[lldb_edi_i386].mutable_data(result_base));
+ }
+
+ // TODO parse the floating point registers
+
+ return result_context_buf;
+}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
new file mode 100644
index 000000000000..e18bb3b4f5d9
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
@@ -0,0 +1,138 @@
+//===-- RegisterContextMinidump_x86_32.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_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"
+
+#include "lldb/Target/RegisterContext.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/Support/Endian.h"
+
+// C includes
+// C++ includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+// This function receives an ArrayRef pointing to the bytes of the Minidump
+// register context and returns a DataBuffer that's ordered by the offsets
+// specified in the RegisterInfoInterface argument
+// This way we can reuse the already existing register contexts
+lldb::DataBufferSP
+ConvertMinidumpContext_x86_32(llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface);
+
+// Reference: see breakpad/crashpad source or WinNT.h
+struct MinidumpFloatingSaveAreaX86 {
+ llvm::support::ulittle32_t control_word;
+ llvm::support::ulittle32_t status_word;
+ llvm::support::ulittle32_t tag_word;
+ llvm::support::ulittle32_t error_offset;
+ llvm::support::ulittle32_t error_selector;
+ llvm::support::ulittle32_t data_offset;
+ llvm::support::ulittle32_t data_selector;
+
+ enum {
+ RegisterAreaSize = 80,
+ };
+ // register_area contains eight 80-bit (x87 "long double") quantities for
+ // floating-point registers %st0 (%mm0) through %st7 (%mm7).
+ uint8_t register_area[RegisterAreaSize];
+ llvm::support::ulittle32_t cr0_npx_state;
+};
+
+struct MinidumpContext_x86_32 {
+ // The context_flags field determines which parts
+ // of the structure are populated (have valid values)
+ llvm::support::ulittle32_t context_flags;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_32_Flags::DebugRegisters
+ llvm::support::ulittle32_t dr0;
+ llvm::support::ulittle32_t dr1;
+ llvm::support::ulittle32_t dr2;
+ llvm::support::ulittle32_t dr3;
+ llvm::support::ulittle32_t dr6;
+ llvm::support::ulittle32_t dr7;
+
+ // The next field is included with
+ // MinidumpContext_x86_32_Flags::FloatingPoint
+ MinidumpFloatingSaveAreaX86 float_save;
+
+ // The next 4 registers are included with
+ // MinidumpContext_x86_32_Flags::Segments
+ llvm::support::ulittle32_t gs;
+ llvm::support::ulittle32_t fs;
+ llvm::support::ulittle32_t es;
+ llvm::support::ulittle32_t ds;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_32_Flags::Integer
+ llvm::support::ulittle32_t edi;
+ llvm::support::ulittle32_t esi;
+ llvm::support::ulittle32_t ebx;
+ llvm::support::ulittle32_t edx;
+ llvm::support::ulittle32_t ecx;
+ llvm::support::ulittle32_t eax;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_32_Flags::Control
+ llvm::support::ulittle32_t ebp;
+ llvm::support::ulittle32_t eip;
+ llvm::support::ulittle32_t cs; // WinNT.h says "must be sanitized"
+ llvm::support::ulittle32_t eflags; // WinNT.h says "must be sanitized"
+ llvm::support::ulittle32_t esp;
+ llvm::support::ulittle32_t ss;
+
+ // The next field is included with
+ // MinidumpContext_x86_32_Flags::ExtendedRegisters
+ // It contains vector (MMX/SSE) registers. It it laid out in the
+ // format used by the fxsave and fsrstor instructions, so it includes
+ // a copy of the x87 floating-point registers as well. See FXSAVE in
+ // "Intel Architecture Software Developer's Manual, Volume 2."
+ enum {
+ ExtendedRegistersSize = 512,
+ };
+ uint8_t extended_registers[ExtendedRegistersSize];
+};
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+// For context_flags. These values indicate the type of
+// context stored in the structure. The high 24 bits identify the CPU, the
+// low 8 bits identify the type of context saved.
+enum class MinidumpContext_x86_32_Flags : uint32_t {
+ x86_32_Flag = 0x00010000, // CONTEXT_i386, CONTEXT_i486
+ Control = x86_32_Flag | 0x00000001,
+ Integer = x86_32_Flag | 0x00000002,
+ Segments = x86_32_Flag | 0x00000004,
+ FloatingPoint = x86_32_Flag | 0x00000008,
+ DebugRegisters = x86_32_Flag | 0x00000010,
+ ExtendedRegisters = x86_32_Flag | 0x00000020,
+ XState = x86_32_Flag | 0x00000040,
+
+ Full = Control | Integer | Segments,
+ All = Full | FloatingPoint | DebugRegisters | ExtendedRegisters,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All)
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_RegisterContextMinidump_x86_32_h_
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
new file mode 100644
index 000000000000..881c26a5774a
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
@@ -0,0 +1,113 @@
+//===-- RegisterContextMinidump_x86_64.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "RegisterContextMinidump_x86_64.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+static llvm::MutableArrayRef<uint8_t> getDestRegister(uint8_t *context,
+ const RegisterInfo &reg) {
+ auto bytes = reg.mutable_data(context);
+
+ switch (reg.kinds[lldb::eRegisterKindLLDB]) {
+ case lldb_cs_x86_64:
+ case lldb_ds_x86_64:
+ case lldb_es_x86_64:
+ case lldb_fs_x86_64:
+ case lldb_gs_x86_64:
+ case lldb_ss_x86_64:
+ return bytes.take_front(2);
+ break;
+ case lldb_rflags_x86_64:
+ return bytes.take_front(4);
+ break;
+ default:
+ return bytes.take_front(8);
+ break;
+ }
+}
+
+static void writeRegister(const void *reg_src, uint8_t *context,
+ const RegisterInfo &reg) {
+ llvm::MutableArrayRef<uint8_t> reg_dest = getDestRegister(context, reg);
+ memcpy(reg_dest.data(), reg_src, reg_dest.size());
+}
+
+lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64(
+ llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface) {
+
+ const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo();
+
+ lldb::DataBufferSP result_context_buf(
+ new DataBufferHeap(target_reg_interface->GetGPRSize(), 0));
+ uint8_t *result_base = result_context_buf->GetBytes();
+
+ if (source_data.size() < sizeof(MinidumpContext_x86_64))
+ return nullptr;
+
+ const MinidumpContext_x86_64 *context;
+ consumeObject(source_data, context);
+
+ const MinidumpContext_x86_64_Flags context_flags =
+ static_cast<MinidumpContext_x86_64_Flags>(
+ static_cast<uint32_t>(context->context_flags));
+ auto x86_64_Flag = MinidumpContext_x86_64_Flags::x86_64_Flag;
+ auto ControlFlag = MinidumpContext_x86_64_Flags::Control;
+ auto IntegerFlag = MinidumpContext_x86_64_Flags::Integer;
+ auto SegmentsFlag = MinidumpContext_x86_64_Flags::Segments;
+
+ if ((context_flags & x86_64_Flag) != x86_64_Flag)
+ return nullptr;
+
+ if ((context_flags & ControlFlag) == ControlFlag) {
+ writeRegister(&context->cs, result_base, reg_info[lldb_cs_x86_64]);
+ writeRegister(&context->ss, result_base, reg_info[lldb_ss_x86_64]);
+ writeRegister(&context->eflags, result_base, reg_info[lldb_rflags_x86_64]);
+ writeRegister(&context->rsp, result_base, reg_info[lldb_rsp_x86_64]);
+ writeRegister(&context->rip, result_base, reg_info[lldb_rip_x86_64]);
+ }
+
+ if ((context_flags & SegmentsFlag) == SegmentsFlag) {
+ writeRegister(&context->ds, result_base, reg_info[lldb_ds_x86_64]);
+ writeRegister(&context->es, result_base, reg_info[lldb_es_x86_64]);
+ writeRegister(&context->fs, result_base, reg_info[lldb_fs_x86_64]);
+ writeRegister(&context->gs, result_base, reg_info[lldb_gs_x86_64]);
+ }
+
+ if ((context_flags & IntegerFlag) == IntegerFlag) {
+ writeRegister(&context->rax, result_base, reg_info[lldb_rax_x86_64]);
+ writeRegister(&context->rcx, result_base, reg_info[lldb_rcx_x86_64]);
+ writeRegister(&context->rdx, result_base, reg_info[lldb_rdx_x86_64]);
+ writeRegister(&context->rbx, result_base, reg_info[lldb_rbx_x86_64]);
+ writeRegister(&context->rbp, result_base, reg_info[lldb_rbp_x86_64]);
+ writeRegister(&context->rsi, result_base, reg_info[lldb_rsi_x86_64]);
+ writeRegister(&context->rdi, result_base, reg_info[lldb_rdi_x86_64]);
+ writeRegister(&context->r8, result_base, reg_info[lldb_r8_x86_64]);
+ writeRegister(&context->r9, result_base, reg_info[lldb_r9_x86_64]);
+ writeRegister(&context->r10, result_base, reg_info[lldb_r10_x86_64]);
+ writeRegister(&context->r11, result_base, reg_info[lldb_r11_x86_64]);
+ writeRegister(&context->r12, result_base, reg_info[lldb_r12_x86_64]);
+ writeRegister(&context->r13, result_base, reg_info[lldb_r13_x86_64]);
+ writeRegister(&context->r14, result_base, reg_info[lldb_r14_x86_64]);
+ writeRegister(&context->r15, result_base, reg_info[lldb_r15_x86_64]);
+ }
+
+ // TODO parse the floating point registers
+
+ return result_context_buf;
+}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
new file mode 100644
index 000000000000..9ba2ee9f29ad
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
@@ -0,0 +1,183 @@
+//===-- RegisterContextMinidump_x86_64.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_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"
+
+#include "lldb/Target/RegisterContext.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/Support/Endian.h"
+
+// C includes
+// C++ includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+// This function receives an ArrayRef pointing to the bytes of the Minidump
+// register context and returns a DataBuffer that's ordered by the offsets
+// specified in the RegisterInfoInterface argument
+// This way we can reuse the already existing register contexts
+lldb::DataBufferSP
+ConvertMinidumpContext_x86_64(llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface);
+
+struct Uint128 {
+ llvm::support::ulittle64_t high;
+ llvm::support::ulittle64_t low;
+};
+
+// Reference: see breakpad/crashpad source or WinNT.h
+struct MinidumpXMMSaveArea32AMD64 {
+ llvm::support::ulittle16_t control_word;
+ llvm::support::ulittle16_t status_word;
+ uint8_t tag_word;
+ uint8_t reserved1;
+ llvm::support::ulittle16_t error_opcode;
+ llvm::support::ulittle32_t error_offset;
+ llvm::support::ulittle16_t error_selector;
+ llvm::support::ulittle16_t reserved2;
+ llvm::support::ulittle32_t data_offset;
+ llvm::support::ulittle16_t data_selector;
+ llvm::support::ulittle16_t reserved3;
+ llvm::support::ulittle32_t mx_csr;
+ llvm::support::ulittle32_t mx_csr_mask;
+ Uint128 float_registers[8];
+ Uint128 xmm_registers[16];
+ uint8_t reserved4[96];
+};
+
+struct MinidumpContext_x86_64 {
+ // Register parameter home addresses.
+ llvm::support::ulittle64_t p1_home;
+ llvm::support::ulittle64_t p2_home;
+ llvm::support::ulittle64_t p3_home;
+ llvm::support::ulittle64_t p4_home;
+ llvm::support::ulittle64_t p5_home;
+ llvm::support::ulittle64_t p6_home;
+
+ // The context_flags field determines which parts
+ // of the structure are populated (have valid values)
+ llvm::support::ulittle32_t context_flags;
+ llvm::support::ulittle32_t mx_csr;
+
+ // The next register is included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle16_t cs;
+
+ // The next 4 registers are included with
+ // MinidumpContext_x86_64_Flags::Segments
+ llvm::support::ulittle16_t ds;
+ llvm::support::ulittle16_t es;
+ llvm::support::ulittle16_t fs;
+ llvm::support::ulittle16_t gs;
+
+ // The next 2 registers are included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle16_t ss;
+ llvm::support::ulittle32_t eflags;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_64_Flags::DebugRegisters
+ llvm::support::ulittle64_t dr0;
+ llvm::support::ulittle64_t dr1;
+ llvm::support::ulittle64_t dr2;
+ llvm::support::ulittle64_t dr3;
+ llvm::support::ulittle64_t dr6;
+ llvm::support::ulittle64_t dr7;
+
+ // The next 4 registers are included with
+ // MinidumpContext_x86_64_Flags::Integer
+ llvm::support::ulittle64_t rax;
+ llvm::support::ulittle64_t rcx;
+ llvm::support::ulittle64_t rdx;
+ llvm::support::ulittle64_t rbx;
+
+ // The next register is included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle64_t rsp;
+
+ // The next 11 registers are included with
+ // MinidumpContext_x86_64_Flags::Integer
+ llvm::support::ulittle64_t rbp;
+ llvm::support::ulittle64_t rsi;
+ llvm::support::ulittle64_t rdi;
+ llvm::support::ulittle64_t r8;
+ llvm::support::ulittle64_t r9;
+ llvm::support::ulittle64_t r10;
+ llvm::support::ulittle64_t r11;
+ llvm::support::ulittle64_t r12;
+ llvm::support::ulittle64_t r13;
+ llvm::support::ulittle64_t r14;
+ llvm::support::ulittle64_t r15;
+
+ // The next register is included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle64_t rip;
+
+ // The next set of registers are included with
+ // MinidumpContext_x86_64_Flags:FloatingPoint
+ union FPR {
+ MinidumpXMMSaveArea32AMD64 flt_save;
+ struct {
+ Uint128 header[2];
+ Uint128 legacy[8];
+ Uint128 xmm[16];
+ } sse_registers;
+ };
+
+ enum {
+ VRCount = 26,
+ };
+
+ Uint128 vector_register[VRCount];
+ llvm::support::ulittle64_t vector_control;
+
+ // The next 5 registers are included with
+ // MinidumpContext_x86_64_Flags::DebugRegisters
+ llvm::support::ulittle64_t debug_control;
+ llvm::support::ulittle64_t last_branch_to_rip;
+ llvm::support::ulittle64_t last_branch_from_rip;
+ llvm::support::ulittle64_t last_exception_to_rip;
+ llvm::support::ulittle64_t last_exception_from_rip;
+};
+
+// For context_flags. These values indicate the type of
+// context stored in the structure. The high 24 bits identify the CPU, the
+// low 8 bits identify the type of context saved.
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+enum class MinidumpContext_x86_64_Flags : uint32_t {
+ x86_64_Flag = 0x00100000,
+ Control = x86_64_Flag | 0x00000001,
+ Integer = x86_64_Flag | 0x00000002,
+ Segments = x86_64_Flag | 0x00000004,
+ FloatingPoint = x86_64_Flag | 0x00000008,
+ DebugRegisters = x86_64_Flag | 0x00000010,
+ XState = x86_64_Flag | 0x00000040,
+
+ Full = Control | Integer | FloatingPoint,
+ All = Full | Segments | DebugRegisters,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All)
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_RegisterContextMinidump_h_
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp
new file mode 100644
index 000000000000..e42108b9261a
--- /dev/null
+++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -0,0 +1,114 @@
+//===-- ThreadMinidump.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "ThreadMinidump.h"
+#include "ProcessMinidump.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"
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Unwind.h"
+
+// C Includes
+// C++ Includes
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace minidump;
+
+ThreadMinidump::ThreadMinidump(Process &process, const MinidumpThread &td,
+ llvm::ArrayRef<uint8_t> gpregset_data)
+ : Thread(process, td.thread_id), m_thread_reg_ctx_sp(),
+ m_gpregset_data(gpregset_data) {}
+
+ThreadMinidump::~ThreadMinidump() {}
+
+void ThreadMinidump::RefreshStateAfterStop() {}
+
+void ThreadMinidump::ClearStackFrames() {}
+
+RegisterContextSP ThreadMinidump::GetRegisterContext() {
+ if (!m_reg_context_sp) {
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+ }
+ return m_reg_context_sp;
+}
+
+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();
+
+ if (concrete_frame_idx == 0) {
+ if (m_thread_reg_ctx_sp)
+ return m_thread_reg_ctx_sp;
+
+ ProcessMinidump *process =
+ static_cast<ProcessMinidump *>(GetProcess().get());
+ ArchSpec arch = process->GetArchitecture();
+ RegisterInfoInterface *reg_interface = nullptr;
+
+ // TODO write other register contexts and add them here
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86: {
+ reg_interface = new RegisterContextLinux_i386(arch);
+ lldb::DataBufferSP buf =
+ ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
+ DataExtractor gpregs(buf, lldb::eByteOrderLittle, 4);
+ DataExtractor fpregs;
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
+ *this, reg_interface, gpregs, fpregs));
+ break;
+ }
+ case llvm::Triple::x86_64: {
+ reg_interface = new RegisterContextLinux_x86_64(arch);
+ lldb::DataBufferSP buf =
+ ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
+ DataExtractor gpregs(buf, lldb::eByteOrderLittle, 8);
+ DataExtractor fpregs;
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
+ *this, reg_interface, gpregs, fpregs));
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!reg_interface) {
+ if (log)
+ log->Printf("elf-core::%s:: Architecture(%d) not supported",
+ __FUNCTION__, arch.GetMachine());
+ assert(false && "Architecture not supported");
+ }
+
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else if (m_unwinder_ap) {
+ reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
+ }
+
+ return reg_ctx_sp;
+}
+
+bool ThreadMinidump::CalculateStopInfo() { return false; }
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.h b/source/Plugins/Process/minidump/ThreadMinidump.h
new file mode 100644
index 000000000000..97db452edfff
--- /dev/null
+++ b/source/Plugins/Process/minidump/ThreadMinidump.h
@@ -0,0 +1,52 @@
+//===-- ThreadMinidump.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_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 {
+
+namespace minidump {
+
+class ThreadMinidump : public Thread {
+public:
+ ThreadMinidump(Process &process, const MinidumpThread &td,
+ llvm::ArrayRef<uint8_t> gpregset_data);
+
+ ~ThreadMinidump() override;
+
+ void RefreshStateAfterStop() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+
+ void ClearStackFrames() override;
+
+protected:
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+ llvm::ArrayRef<uint8_t> m_gpregset_data;
+
+ bool CalculateStopInfo() override;
+};
+
+} // namespace minidump
+} // namespace lldb_private
+
+#endif // liblldb_ThreadMinidump_h_
diff --git a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index 1a352fa1987f..2f04ec97a9ff 100644
--- a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -21,73 +21,51 @@ using namespace lldb;
using namespace lldb_private;
ScriptInterpreterNone::ScriptInterpreterNone(CommandInterpreter &interpreter)
- : ScriptInterpreter(interpreter, eScriptLanguageNone)
-{
-}
+ : ScriptInterpreter(interpreter, eScriptLanguageNone) {}
-ScriptInterpreterNone::~ScriptInterpreterNone()
-{
-}
+ScriptInterpreterNone::~ScriptInterpreterNone() {}
-bool
-ScriptInterpreterNone::ExecuteOneLine(const char *command, CommandReturnObject *, const ExecuteScriptOptions &)
-{
- m_interpreter.GetDebugger().GetErrorFile()->PutCString(
- "error: there is no embedded script interpreter in this mode.\n");
- return false;
+bool ScriptInterpreterNone::ExecuteOneLine(const char *command,
+ CommandReturnObject *,
+ const ExecuteScriptOptions &) {
+ m_interpreter.GetDebugger().GetErrorFile()->PutCString(
+ "error: there is no embedded script interpreter in this mode.\n");
+ return false;
}
-void
-ScriptInterpreterNone::ExecuteInterpreterLoop()
-{
- m_interpreter.GetDebugger().GetErrorFile()->PutCString(
- "error: there is no embedded script interpreter in this mode.\n");
+void ScriptInterpreterNone::ExecuteInterpreterLoop() {
+ m_interpreter.GetDebugger().GetErrorFile()->PutCString(
+ "error: there is no embedded script interpreter in this mode.\n");
}
-void
-ScriptInterpreterNone::Initialize()
-{
- static std::once_flag g_once_flag;
+void ScriptInterpreterNone::Initialize() {
+ static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(),
- lldb::eScriptLanguageNone, CreateInstance);
- });
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ lldb::eScriptLanguageNone, CreateInstance);
+ });
}
-void
-ScriptInterpreterNone::Terminate()
-{
-}
+void ScriptInterpreterNone::Terminate() {}
lldb::ScriptInterpreterSP
-ScriptInterpreterNone::CreateInstance(CommandInterpreter &interpreter)
-{
- return std::make_shared<ScriptInterpreterNone>(interpreter);
+ScriptInterpreterNone::CreateInstance(CommandInterpreter &interpreter) {
+ return std::make_shared<ScriptInterpreterNone>(interpreter);
}
-lldb_private::ConstString
-ScriptInterpreterNone::GetPluginNameStatic()
-{
- static ConstString g_name("script-none");
- return g_name;
+lldb_private::ConstString ScriptInterpreterNone::GetPluginNameStatic() {
+ static ConstString g_name("script-none");
+ return g_name;
}
-const char *
-ScriptInterpreterNone::GetPluginDescriptionStatic()
-{
- return "Null script interpreter";
+const char *ScriptInterpreterNone::GetPluginDescriptionStatic() {
+ return "Null script interpreter";
}
-lldb_private::ConstString
-ScriptInterpreterNone::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ScriptInterpreterNone::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ScriptInterpreterNone::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ScriptInterpreterNone::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
index 49fd4fabfbc5..d66b2f07310c 100644
--- a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
+++ b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
@@ -16,49 +16,40 @@
// Project includes
#include "lldb/Interpreter/ScriptInterpreter.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class ScriptInterpreterNone : public ScriptInterpreter
-{
- public:
- ScriptInterpreterNone(CommandInterpreter &interpreter);
+class ScriptInterpreterNone : public ScriptInterpreter {
+public:
+ ScriptInterpreterNone(CommandInterpreter &interpreter);
- ~ScriptInterpreterNone() override;
+ ~ScriptInterpreterNone() override;
- bool
- ExecuteOneLine(const char *command, CommandReturnObject *result,
- const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
+ bool ExecuteOneLine(
+ const char *command, CommandReturnObject *result,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
- void
- ExecuteInterpreterLoop() override;
+ void ExecuteInterpreterLoop() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb::ScriptInterpreterSP
- CreateInstance(CommandInterpreter &interpreter);
+ static lldb::ScriptInterpreterSP
+ CreateInstance(CommandInterpreter &interpreter);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 1fdf4c70a5dc..f3453f2d011d 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -1,4 +1,5 @@
-//===-- PythonDataObjects.cpp ------------------------------------*- C++ -*-===//
+//===-- PythonDataObjects.cpp ------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,7 +14,6 @@
#else
-#include "lldb-python.h"
#include "PythonDataObjects.h"
#include "ScriptInterpreterPython.h"
@@ -31,1273 +31,1020 @@
using namespace lldb_private;
using namespace lldb;
-void
-StructuredPythonObject::Dump(Stream &s) const
-{
- s << "Python Obj: 0x" << GetValue();
+void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const {
+ s << "Python Obj: 0x" << GetValue();
}
//----------------------------------------------------------------------
// PythonObject
//----------------------------------------------------------------------
-void
-PythonObject::Dump(Stream &strm) const
-{
- if (m_py_obj)
- {
- FILE *file = ::tmpfile();
- if (file)
- {
- ::PyObject_Print (m_py_obj, file, 0);
- const long length = ftell (file);
- if (length)
- {
- ::rewind(file);
- std::vector<char> file_contents (length,'\0');
- const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file);
- if (length_read > 0)
- strm.Write (file_contents.data(), length_read);
- }
- ::fclose (file);
- }
+void PythonObject::Dump(Stream &strm) const {
+ if (m_py_obj) {
+ FILE *file = ::tmpfile();
+ if (file) {
+ ::PyObject_Print(m_py_obj, file, 0);
+ const long length = ftell(file);
+ if (length) {
+ ::rewind(file);
+ std::vector<char> file_contents(length, '\0');
+ const size_t length_read =
+ ::fread(file_contents.data(), 1, file_contents.size(), file);
+ if (length_read > 0)
+ strm.Write(file_contents.data(), length_read);
+ }
+ ::fclose(file);
}
- else
- strm.PutCString ("NULL");
-}
-
-PyObjectType
-PythonObject::GetObjectType() const
-{
- if (!IsAllocated())
- return PyObjectType::None;
-
- if (PythonModule::Check(m_py_obj))
- return PyObjectType::Module;
- if (PythonList::Check(m_py_obj))
- return PyObjectType::List;
- if (PythonTuple::Check(m_py_obj))
- return PyObjectType::Tuple;
- if (PythonDictionary::Check(m_py_obj))
- return PyObjectType::Dictionary;
- if (PythonString::Check(m_py_obj))
- return PyObjectType::String;
+ } else
+ strm.PutCString("NULL");
+}
+
+PyObjectType PythonObject::GetObjectType() const {
+ if (!IsAllocated())
+ return PyObjectType::None;
+
+ if (PythonModule::Check(m_py_obj))
+ return PyObjectType::Module;
+ if (PythonList::Check(m_py_obj))
+ return PyObjectType::List;
+ if (PythonTuple::Check(m_py_obj))
+ return PyObjectType::Tuple;
+ if (PythonDictionary::Check(m_py_obj))
+ return PyObjectType::Dictionary;
+ if (PythonString::Check(m_py_obj))
+ return PyObjectType::String;
#if PY_MAJOR_VERSION >= 3
- if (PythonBytes::Check(m_py_obj))
- return PyObjectType::Bytes;
+ if (PythonBytes::Check(m_py_obj))
+ return PyObjectType::Bytes;
#endif
- if (PythonByteArray::Check(m_py_obj))
- return PyObjectType::ByteArray;
- if (PythonInteger::Check(m_py_obj))
- return PyObjectType::Integer;
- if (PythonFile::Check(m_py_obj))
- return PyObjectType::File;
- if (PythonCallable::Check(m_py_obj))
- return PyObjectType::Callable;
- return PyObjectType::Unknown;
-}
-
-PythonString
-PythonObject::Repr() const
-{
- if (!m_py_obj)
- return PythonString();
- PyObject *repr = PyObject_Repr(m_py_obj);
- if (!repr)
- return PythonString();
- return PythonString(PyRefType::Owned, repr);
-}
-
-PythonString
-PythonObject::Str() const
-{
- if (!m_py_obj)
- return PythonString();
- PyObject *str = PyObject_Str(m_py_obj);
- if (!str)
- return PythonString();
- return PythonString(PyRefType::Owned, str);
+ if (PythonByteArray::Check(m_py_obj))
+ return PyObjectType::ByteArray;
+ if (PythonInteger::Check(m_py_obj))
+ return PyObjectType::Integer;
+ if (PythonFile::Check(m_py_obj))
+ return PyObjectType::File;
+ if (PythonCallable::Check(m_py_obj))
+ return PyObjectType::Callable;
+ return PyObjectType::Unknown;
+}
+
+PythonString PythonObject::Repr() const {
+ if (!m_py_obj)
+ return PythonString();
+ PyObject *repr = PyObject_Repr(m_py_obj);
+ if (!repr)
+ return PythonString();
+ return PythonString(PyRefType::Owned, repr);
+}
+
+PythonString PythonObject::Str() const {
+ if (!m_py_obj)
+ return PythonString();
+ PyObject *str = PyObject_Str(m_py_obj);
+ if (!str)
+ return PythonString();
+ return PythonString(PyRefType::Owned, str);
}
PythonObject
-PythonObject::ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict)
-{
- size_t dot_pos = name.find_first_of('.');
- llvm::StringRef piece = name.substr(0, dot_pos);
- PythonObject result = dict.GetItemForKey(PythonString(piece));
- if (dot_pos == llvm::StringRef::npos)
- {
- // There was no dot, we're done.
- return result;
- }
+PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
+ const PythonDictionary &dict) {
+ size_t dot_pos = name.find_first_of('.');
+ llvm::StringRef piece = name.substr(0, dot_pos);
+ PythonObject result = dict.GetItemForKey(PythonString(piece));
+ if (dot_pos == llvm::StringRef::npos) {
+ // There was no dot, we're done.
+ return result;
+ }
+
+ // There was a dot. The remaining portion of the name should be looked up in
+ // the context of the object that was found in the dictionary.
+ return result.ResolveName(name.substr(dot_pos + 1));
+}
+
+PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
+ // Resolve the name in the context of the specified object. If,
+ // for example, `this` refers to a PyModule, then this will look for
+ // `name` in this module. If `this` refers to a PyType, then it will
+ // resolve `name` as an attribute of that type. If `this` refers to
+ // an instance of an object, then it will resolve `name` as the value
+ // of the specified field.
+ //
+ // This function handles dotted names so that, for example, if `m_py_obj`
+ // refers to the `sys` module, and `name` == "path.append", then it
+ // will find the function `sys.path.append`.
+
+ size_t dot_pos = name.find_first_of('.');
+ if (dot_pos == llvm::StringRef::npos) {
+ // No dots in the name, we should be able to find the value immediately
+ // as an attribute of `m_py_obj`.
+ return GetAttributeValue(name);
+ }
+
+ // Look up the first piece of the name, and resolve the rest as a child of
+ // that.
+ PythonObject parent = ResolveName(name.substr(0, dot_pos));
+ if (!parent.IsAllocated())
+ return PythonObject();
- // There was a dot. The remaining portion of the name should be looked up in
- // the context of the object that was found in the dictionary.
- return result.ResolveName(name.substr(dot_pos + 1));
+ // Tail recursion.. should be optimized by the compiler
+ return parent.ResolveName(name.substr(dot_pos + 1));
}
-PythonObject
-PythonObject::ResolveName(llvm::StringRef name) const
-{
- // Resolve the name in the context of the specified object. If,
- // for example, `this` refers to a PyModule, then this will look for
- // `name` in this module. If `this` refers to a PyType, then it will
- // resolve `name` as an attribute of that type. If `this` refers to
- // an instance of an object, then it will resolve `name` as the value
- // of the specified field.
- //
- // This function handles dotted names so that, for example, if `m_py_obj`
- // refers to the `sys` module, and `name` == "path.append", then it
- // will find the function `sys.path.append`.
-
- size_t dot_pos = name.find_first_of('.');
- if (dot_pos == llvm::StringRef::npos)
- {
- // No dots in the name, we should be able to find the value immediately
- // as an attribute of `m_py_obj`.
- return GetAttributeValue(name);
- }
+bool PythonObject::HasAttribute(llvm::StringRef attr) const {
+ if (!IsValid())
+ return false;
+ PythonString py_attr(attr);
+ return !!PyObject_HasAttr(m_py_obj, py_attr.get());
+}
- // Look up the first piece of the name, and resolve the rest as a child of that.
- PythonObject parent = ResolveName(name.substr(0, dot_pos));
- if (!parent.IsAllocated())
- return PythonObject();
+PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
+ if (!IsValid())
+ return PythonObject();
- // Tail recursion.. should be optimized by the compiler
- return parent.ResolveName(name.substr(dot_pos + 1));
-}
+ PythonString py_attr(attr);
+ if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
+ return PythonObject();
-bool
-PythonObject::HasAttribute(llvm::StringRef attr) const
-{
- if (!IsValid())
- return false;
- PythonString py_attr(attr);
- return !!PyObject_HasAttr(m_py_obj, py_attr.get());
+ return PythonObject(PyRefType::Owned,
+ PyObject_GetAttr(m_py_obj, py_attr.get()));
}
-PythonObject
-PythonObject::GetAttributeValue(llvm::StringRef attr) const
-{
- if (!IsValid())
- return PythonObject();
-
- PythonString py_attr(attr);
- if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
- return PythonObject();
-
- return PythonObject(PyRefType::Owned,
- PyObject_GetAttr(m_py_obj, py_attr.get()));
-}
-
-bool
-PythonObject::IsNone() const
-{
- return m_py_obj == Py_None;
-}
-
-bool
-PythonObject::IsValid() const
-{
- return m_py_obj != nullptr;
-}
-
-bool
-PythonObject::IsAllocated() const
-{
- return IsValid() && !IsNone();
-}
-
-StructuredData::ObjectSP
-PythonObject::CreateStructuredObject() const
-{
- switch (GetObjectType())
- {
- case PyObjectType::Dictionary:
- return PythonDictionary(PyRefType::Borrowed, m_py_obj).CreateStructuredDictionary();
- case PyObjectType::Integer:
- return PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
- case PyObjectType::List:
- return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
- case PyObjectType::String:
- return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
- case PyObjectType::Bytes:
- return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
- case PyObjectType::ByteArray:
- return PythonByteArray(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
- case PyObjectType::None:
- return StructuredData::ObjectSP();
- default:
- return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
- }
+bool PythonObject::IsNone() const { return m_py_obj == Py_None; }
+
+bool PythonObject::IsValid() const { return m_py_obj != nullptr; }
+
+bool PythonObject::IsAllocated() const { return IsValid() && !IsNone(); }
+
+StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
+ switch (GetObjectType()) {
+ case PyObjectType::Dictionary:
+ return PythonDictionary(PyRefType::Borrowed, m_py_obj)
+ .CreateStructuredDictionary();
+ case PyObjectType::Integer:
+ return PythonInteger(PyRefType::Borrowed, m_py_obj)
+ .CreateStructuredInteger();
+ case PyObjectType::List:
+ return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
+ case PyObjectType::String:
+ return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
+ case PyObjectType::Bytes:
+ return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
+ case PyObjectType::ByteArray:
+ return PythonByteArray(PyRefType::Borrowed, m_py_obj)
+ .CreateStructuredString();
+ case PyObjectType::None:
+ return StructuredData::ObjectSP();
+ default:
+ return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
+ }
}
//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------
-PythonBytes::PythonBytes() : PythonObject()
-{
-}
+PythonBytes::PythonBytes() : PythonObject() {}
-PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject()
-{
- SetBytes(bytes);
+PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() {
+ SetBytes(bytes);
}
-PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject()
-{
- SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
+PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() {
+ SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
}
-PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject()
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
+PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
}
-PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object)
-{
-}
+PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object) {}
-PythonBytes::~PythonBytes()
-{
-}
+PythonBytes::~PythonBytes() {}
-bool
-PythonBytes::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
- if (PyBytes_Check(py_obj))
- return true;
+bool PythonBytes::Check(PyObject *py_obj) {
+ if (!py_obj)
return false;
+ if (PyBytes_Check(py_obj))
+ return true;
+ return false;
}
-void
-PythonBytes::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonBytes::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonBytes::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-llvm::ArrayRef<uint8_t>
-PythonBytes::GetBytes() const
-{
- if (!IsValid())
- return llvm::ArrayRef<uint8_t>();
+llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
+ if (!IsValid())
+ return llvm::ArrayRef<uint8_t>();
- Py_ssize_t size;
- char *c;
+ Py_ssize_t size;
+ char *c;
- PyBytes_AsStringAndSize(m_py_obj, &c, &size);
- return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
+ PyBytes_AsStringAndSize(m_py_obj, &c, &size);
+ return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
}
-size_t
-PythonBytes::GetSize() const
-{
- if (!IsValid())
- return 0;
- return PyBytes_Size(m_py_obj);
+size_t PythonBytes::GetSize() const {
+ if (!IsValid())
+ return 0;
+ return PyBytes_Size(m_py_obj);
}
-void
-PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes)
-{
- const char *data = reinterpret_cast<const char *>(bytes.data());
- PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
- PythonObject::Reset(PyRefType::Owned, py_bytes);
+void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
+ const char *data = reinterpret_cast<const char *>(bytes.data());
+ PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
+ PythonObject::Reset(PyRefType::Owned, py_bytes);
}
-StructuredData::StringSP
-PythonBytes::CreateStructuredString() const
-{
- StructuredData::StringSP result(new StructuredData::String);
- Py_ssize_t size;
- char *c;
- PyBytes_AsStringAndSize(m_py_obj, &c, &size);
- result->SetValue(std::string(c, size));
- return result;
+StructuredData::StringSP PythonBytes::CreateStructuredString() const {
+ StructuredData::StringSP result(new StructuredData::String);
+ Py_ssize_t size;
+ char *c;
+ PyBytes_AsStringAndSize(m_py_obj, &c, &size);
+ result->SetValue(std::string(c, size));
+ return result;
}
-PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) : PythonByteArray(bytes.data(), bytes.size())
-{
-}
+PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
+ : PythonByteArray(bytes.data(), bytes.size()) {}
-PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length)
-{
- const char *str = reinterpret_cast<const char *>(bytes);
- Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
+PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
+ const char *str = reinterpret_cast<const char *>(bytes);
+ Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
}
-PythonByteArray::PythonByteArray(PyRefType type, PyObject *o)
-{
- Reset(type, o);
+PythonByteArray::PythonByteArray(PyRefType type, PyObject *o) {
+ Reset(type, o);
}
-PythonByteArray::PythonByteArray(const PythonBytes &object) : PythonObject(object)
-{
-}
+PythonByteArray::PythonByteArray(const PythonBytes &object)
+ : PythonObject(object) {}
-PythonByteArray::~PythonByteArray()
-{
-}
+PythonByteArray::~PythonByteArray() {}
-bool
-PythonByteArray::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
- if (PyByteArray_Check(py_obj))
- return true;
+bool PythonByteArray::Check(PyObject *py_obj) {
+ if (!py_obj)
return false;
+ if (PyByteArray_Check(py_obj))
+ return true;
+ return false;
}
-void
-PythonByteArray::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonByteArray::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonByteArray::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-llvm::ArrayRef<uint8_t>
-PythonByteArray::GetBytes() const
-{
- if (!IsValid())
- return llvm::ArrayRef<uint8_t>();
+llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
+ if (!IsValid())
+ return llvm::ArrayRef<uint8_t>();
- char *c = PyByteArray_AsString(m_py_obj);
- size_t size = GetSize();
- return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
+ char *c = PyByteArray_AsString(m_py_obj);
+ size_t size = GetSize();
+ return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
}
-size_t
-PythonByteArray::GetSize() const
-{
- if (!IsValid())
- return 0;
+size_t PythonByteArray::GetSize() const {
+ if (!IsValid())
+ return 0;
- return PyByteArray_Size(m_py_obj);
+ return PyByteArray_Size(m_py_obj);
}
-StructuredData::StringSP
-PythonByteArray::CreateStructuredString() const
-{
- StructuredData::StringSP result(new StructuredData::String);
- llvm::ArrayRef<uint8_t> bytes = GetBytes();
- const char *str = reinterpret_cast<const char *>(bytes.data());
- result->SetValue(std::string(str, bytes.size()));
- return result;
+StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
+ StructuredData::StringSP result(new StructuredData::String);
+ llvm::ArrayRef<uint8_t> bytes = GetBytes();
+ const char *str = reinterpret_cast<const char *>(bytes.data());
+ result->SetValue(std::string(str, bytes.size()));
+ return result;
}
//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------
-PythonString::PythonString(PyRefType type, PyObject *py_obj)
- : PythonObject()
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
+PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
}
-PythonString::PythonString(const PythonString &object)
- : PythonObject(object)
-{
-}
+PythonString::PythonString(const PythonString &object) : PythonObject(object) {}
-PythonString::PythonString(llvm::StringRef string)
- : PythonObject()
-{
- SetString(string);
+PythonString::PythonString(llvm::StringRef string) : PythonObject() {
+ SetString(string);
}
-PythonString::PythonString(const char *string)
- : PythonObject()
-{
- SetString(llvm::StringRef(string));
+PythonString::PythonString(const char *string) : PythonObject() {
+ SetString(llvm::StringRef(string));
}
-PythonString::PythonString()
- : PythonObject()
-{
-}
+PythonString::PythonString() : PythonObject() {}
-PythonString::~PythonString ()
-{
-}
+PythonString::~PythonString() {}
-bool
-PythonString::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
+bool PythonString::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
- if (PyUnicode_Check(py_obj))
- return true;
+ if (PyUnicode_Check(py_obj))
+ return true;
#if PY_MAJOR_VERSION < 3
- if (PyString_Check(py_obj))
- return true;
+ if (PyString_Check(py_obj))
+ return true;
#endif
- return false;
+ return false;
}
-void
-PythonString::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonString::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonString::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonString::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
#if PY_MAJOR_VERSION < 3
- // In Python 2, Don't store PyUnicode objects directly, because we need
- // access to their underlying character buffers which Python 2 doesn't
- // provide.
- if (PyUnicode_Check(py_obj))
- result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
+ // In Python 2, Don't store PyUnicode objects directly, because we need
+ // access to their underlying character buffers which Python 2 doesn't
+ // provide.
+ if (PyUnicode_Check(py_obj))
+ result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
#endif
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-llvm::StringRef
-PythonString::GetString() const
-{
- if (!IsValid())
- return llvm::StringRef();
+llvm::StringRef PythonString::GetString() const {
+ if (!IsValid())
+ return llvm::StringRef();
- Py_ssize_t size;
- char *c;
+ Py_ssize_t size;
+ char *c;
#if PY_MAJOR_VERSION >= 3
- c = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
+ c = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
#else
- PyString_AsStringAndSize(m_py_obj, &c, &size);
+ PyString_AsStringAndSize(m_py_obj, &c, &size);
#endif
- return llvm::StringRef(c, size);
+ return llvm::StringRef(c, size);
}
-size_t
-PythonString::GetSize() const
-{
- if (IsValid())
- {
+size_t PythonString::GetSize() const {
+ if (IsValid()) {
#if PY_MAJOR_VERSION >= 3
- return PyUnicode_GetSize(m_py_obj);
+ return PyUnicode_GetSize(m_py_obj);
#else
- return PyString_Size(m_py_obj);
+ return PyString_Size(m_py_obj);
#endif
- }
- return 0;
+ }
+ return 0;
}
-void
-PythonString::SetString (llvm::StringRef string)
-{
+void PythonString::SetString(llvm::StringRef string) {
#if PY_MAJOR_VERSION >= 3
- PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
- PythonObject::Reset(PyRefType::Owned, unicode);
+ PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
+ PythonObject::Reset(PyRefType::Owned, unicode);
#else
- PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
- PythonObject::Reset(PyRefType::Owned, str);
+ PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
+ PythonObject::Reset(PyRefType::Owned, str);
#endif
}
-StructuredData::StringSP
-PythonString::CreateStructuredString() const
-{
- StructuredData::StringSP result(new StructuredData::String);
- result->SetValue(GetString());
- return result;
+StructuredData::StringSP PythonString::CreateStructuredString() const {
+ StructuredData::StringSP result(new StructuredData::String);
+ result->SetValue(GetString());
+ return result;
}
//----------------------------------------------------------------------
// PythonInteger
//----------------------------------------------------------------------
-PythonInteger::PythonInteger()
- : PythonObject()
-{
-
-}
+PythonInteger::PythonInteger() : PythonObject() {}
PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
- : PythonObject()
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
+ : PythonObject() {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
}
PythonInteger::PythonInteger(const PythonInteger &object)
- : PythonObject(object)
-{
-}
+ : PythonObject(object) {}
-PythonInteger::PythonInteger(int64_t value)
- : PythonObject()
-{
- SetInteger(value);
+PythonInteger::PythonInteger(int64_t value) : PythonObject() {
+ SetInteger(value);
}
+PythonInteger::~PythonInteger() {}
-PythonInteger::~PythonInteger ()
-{
-}
-
-bool
-PythonInteger::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
+bool PythonInteger::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
#if PY_MAJOR_VERSION >= 3
- // Python 3 does not have PyInt_Check. There is only one type of
- // integral value, long.
- return PyLong_Check(py_obj);
+ // Python 3 does not have PyInt_Check. There is only one type of
+ // integral value, long.
+ return PyLong_Check(py_obj);
#else
- return PyLong_Check(py_obj) || PyInt_Check(py_obj);
+ return PyLong_Check(py_obj) || PyInt_Check(py_obj);
#endif
}
-void
-PythonInteger::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonInteger::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonInteger::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
#if PY_MAJOR_VERSION < 3
- // Always store this as a PyLong, which makes interoperability between
- // Python 2.x and Python 3.x easier. This is only necessary in 2.x,
- // since 3.x doesn't even have a PyInt.
- if (PyInt_Check(py_obj))
- {
- // Since we converted the original object to a different type, the new
- // object is an owned object regardless of the ownership semantics requested
- // by the user.
- result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
- }
+ // Always store this as a PyLong, which makes interoperability between
+ // Python 2.x and Python 3.x easier. This is only necessary in 2.x,
+ // since 3.x doesn't even have a PyInt.
+ if (PyInt_Check(py_obj)) {
+ // Since we converted the original object to a different type, the new
+ // object is an owned object regardless of the ownership semantics requested
+ // by the user.
+ result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
+ }
#endif
- assert(PyLong_Check(result.get()) && "Couldn't get a PyLong from this PyObject");
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
-int64_t
-PythonInteger::GetInteger() const
-{
- if (m_py_obj)
- {
- assert(PyLong_Check(m_py_obj) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong");
-
- return PyLong_AsLongLong(m_py_obj);
+ assert(PyLong_Check(result.get()) &&
+ "Couldn't get a PyLong from this PyObject");
+
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
+}
+
+int64_t PythonInteger::GetInteger() const {
+ if (m_py_obj) {
+ assert(PyLong_Check(m_py_obj) &&
+ "PythonInteger::GetInteger has a PyObject that isn't a PyLong");
+
+ int overflow = 0;
+ int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
+ if (overflow != 0) {
+ // We got an integer that overflows, like 18446744072853913392L
+ // we can't use PyLong_AsLongLong() as it will return
+ // 0xffffffffffffffff. If we use the unsigned long long
+ // it will work as expected.
+ const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
+ result = static_cast<int64_t>(uval);
}
- return UINT64_MAX;
+ return result;
+ }
+ return UINT64_MAX;
}
-void
-PythonInteger::SetInteger(int64_t value)
-{
- PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
+void PythonInteger::SetInteger(int64_t value) {
+ PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
}
-StructuredData::IntegerSP
-PythonInteger::CreateStructuredInteger() const
-{
- StructuredData::IntegerSP result(new StructuredData::Integer);
- result->SetValue(GetInteger());
- return result;
+StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
+ StructuredData::IntegerSP result(new StructuredData::Integer);
+ result->SetValue(GetInteger());
+ return result;
}
//----------------------------------------------------------------------
// PythonList
//----------------------------------------------------------------------
-PythonList::PythonList(PyInitialValue value)
- : PythonObject()
-{
- if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyList_New(0));
+PythonList::PythonList(PyInitialValue value) : PythonObject() {
+ if (value == PyInitialValue::Empty)
+ Reset(PyRefType::Owned, PyList_New(0));
}
-PythonList::PythonList(int list_size)
- : PythonObject()
-{
- Reset(PyRefType::Owned, PyList_New(list_size));
+PythonList::PythonList(int list_size) : PythonObject() {
+ Reset(PyRefType::Owned, PyList_New(list_size));
}
-PythonList::PythonList(PyRefType type, PyObject *py_obj)
- : PythonObject()
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
+PythonList::PythonList(PyRefType type, PyObject *py_obj) : PythonObject() {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
}
-PythonList::PythonList(const PythonList &list)
- : PythonObject(list)
-{
-}
+PythonList::PythonList(const PythonList &list) : PythonObject(list) {}
-PythonList::~PythonList ()
-{
-}
+PythonList::~PythonList() {}
-bool
-PythonList::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
- return PyList_Check(py_obj);
+bool PythonList::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
+ return PyList_Check(py_obj);
}
-void
-PythonList::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonList::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonList::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonList::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-uint32_t
-PythonList::GetSize() const
-{
- if (IsValid())
- return PyList_GET_SIZE(m_py_obj);
- return 0;
+uint32_t PythonList::GetSize() const {
+ if (IsValid())
+ return PyList_GET_SIZE(m_py_obj);
+ return 0;
}
-PythonObject
-PythonList::GetItemAtIndex(uint32_t index) const
-{
- if (IsValid())
- return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
- return PythonObject();
+PythonObject PythonList::GetItemAtIndex(uint32_t index) const {
+ if (IsValid())
+ return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
+ return PythonObject();
}
-void
-PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object)
-{
- if (IsAllocated() && object.IsValid())
- {
- // PyList_SetItem is documented to "steal" a reference, so we need to
- // convert it to an owned reference by incrementing it.
- Py_INCREF(object.get());
- PyList_SetItem(m_py_obj, index, object.get());
- }
+void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
+ if (IsAllocated() && object.IsValid()) {
+ // PyList_SetItem is documented to "steal" a reference, so we need to
+ // convert it to an owned reference by incrementing it.
+ Py_INCREF(object.get());
+ PyList_SetItem(m_py_obj, index, object.get());
+ }
}
-void
-PythonList::AppendItem(const PythonObject &object)
-{
- if (IsAllocated() && object.IsValid())
- {
- // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
- // here like we do with `PyList_SetItem`.
- PyList_Append(m_py_obj, object.get());
- }
+void PythonList::AppendItem(const PythonObject &object) {
+ if (IsAllocated() && object.IsValid()) {
+ // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
+ // here like we do with `PyList_SetItem`.
+ PyList_Append(m_py_obj, object.get());
+ }
}
-StructuredData::ArraySP
-PythonList::CreateStructuredArray() const
-{
- StructuredData::ArraySP result(new StructuredData::Array);
- uint32_t count = GetSize();
- for (uint32_t i = 0; i < count; ++i)
- {
- PythonObject obj = GetItemAtIndex(i);
- result->AddItem(obj.CreateStructuredObject());
- }
- return result;
+StructuredData::ArraySP PythonList::CreateStructuredArray() const {
+ StructuredData::ArraySP result(new StructuredData::Array);
+ uint32_t count = GetSize();
+ for (uint32_t i = 0; i < count; ++i) {
+ PythonObject obj = GetItemAtIndex(i);
+ result->AddItem(obj.CreateStructuredObject());
+ }
+ return result;
}
//----------------------------------------------------------------------
// PythonTuple
//----------------------------------------------------------------------
-PythonTuple::PythonTuple(PyInitialValue value)
- : PythonObject()
-{
- if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyTuple_New(0));
+PythonTuple::PythonTuple(PyInitialValue value) : PythonObject() {
+ if (value == PyInitialValue::Empty)
+ Reset(PyRefType::Owned, PyTuple_New(0));
}
-PythonTuple::PythonTuple(int tuple_size)
- : PythonObject()
-{
- Reset(PyRefType::Owned, PyTuple_New(tuple_size));
+PythonTuple::PythonTuple(int tuple_size) : PythonObject() {
+ Reset(PyRefType::Owned, PyTuple_New(tuple_size));
}
-PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj)
- : PythonObject()
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
+PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj) : PythonObject() {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
}
-PythonTuple::PythonTuple(const PythonTuple &tuple)
- : PythonObject(tuple)
-{
-}
+PythonTuple::PythonTuple(const PythonTuple &tuple) : PythonObject(tuple) {}
-PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects)
-{
- m_py_obj = PyTuple_New(objects.size());
+PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
+ m_py_obj = PyTuple_New(objects.size());
- uint32_t idx = 0;
- for (auto object : objects)
- {
- if (object.IsValid())
- SetItemAtIndex(idx, object);
- idx++;
- }
+ uint32_t idx = 0;
+ for (auto object : objects) {
+ if (object.IsValid())
+ SetItemAtIndex(idx, object);
+ idx++;
+ }
}
-PythonTuple::PythonTuple(std::initializer_list<PyObject*> objects)
-{
- m_py_obj = PyTuple_New(objects.size());
+PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
+ m_py_obj = PyTuple_New(objects.size());
- uint32_t idx = 0;
- for (auto py_object : objects)
- {
- PythonObject object(PyRefType::Borrowed, py_object);
- if (object.IsValid())
- SetItemAtIndex(idx, object);
- idx++;
- }
+ uint32_t idx = 0;
+ for (auto py_object : objects) {
+ PythonObject object(PyRefType::Borrowed, py_object);
+ if (object.IsValid())
+ SetItemAtIndex(idx, object);
+ idx++;
+ }
}
-PythonTuple::~PythonTuple()
-{
-}
+PythonTuple::~PythonTuple() {}
-bool
-PythonTuple::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
- return PyTuple_Check(py_obj);
+bool PythonTuple::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
+ return PyTuple_Check(py_obj);
}
-void
-PythonTuple::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonTuple::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonTuple::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-uint32_t
-PythonTuple::GetSize() const
-{
- if (IsValid())
- return PyTuple_GET_SIZE(m_py_obj);
- return 0;
+uint32_t PythonTuple::GetSize() const {
+ if (IsValid())
+ return PyTuple_GET_SIZE(m_py_obj);
+ return 0;
}
-PythonObject
-PythonTuple::GetItemAtIndex(uint32_t index) const
-{
- if (IsValid())
- return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
- return PythonObject();
+PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const {
+ if (IsValid())
+ return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
+ return PythonObject();
}
-void
-PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object)
-{
- if (IsAllocated() && object.IsValid())
- {
- // PyTuple_SetItem is documented to "steal" a reference, so we need to
- // convert it to an owned reference by incrementing it.
- Py_INCREF(object.get());
- PyTuple_SetItem(m_py_obj, index, object.get());
- }
+void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
+ if (IsAllocated() && object.IsValid()) {
+ // PyTuple_SetItem is documented to "steal" a reference, so we need to
+ // convert it to an owned reference by incrementing it.
+ Py_INCREF(object.get());
+ PyTuple_SetItem(m_py_obj, index, object.get());
+ }
}
-StructuredData::ArraySP
-PythonTuple::CreateStructuredArray() const
-{
- StructuredData::ArraySP result(new StructuredData::Array);
- uint32_t count = GetSize();
- for (uint32_t i = 0; i < count; ++i)
- {
- PythonObject obj = GetItemAtIndex(i);
- result->AddItem(obj.CreateStructuredObject());
- }
- return result;
+StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
+ StructuredData::ArraySP result(new StructuredData::Array);
+ uint32_t count = GetSize();
+ for (uint32_t i = 0; i < count; ++i) {
+ PythonObject obj = GetItemAtIndex(i);
+ result->AddItem(obj.CreateStructuredObject());
+ }
+ return result;
}
//----------------------------------------------------------------------
// PythonDictionary
//----------------------------------------------------------------------
-PythonDictionary::PythonDictionary(PyInitialValue value)
- : PythonObject()
-{
- if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyDict_New());
+PythonDictionary::PythonDictionary(PyInitialValue value) : PythonObject() {
+ if (value == PyInitialValue::Empty)
+ Reset(PyRefType::Owned, PyDict_New());
}
PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj)
- : PythonObject()
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
+ : PythonObject() {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
}
PythonDictionary::PythonDictionary(const PythonDictionary &object)
- : PythonObject(object)
-{
-}
+ : PythonObject(object) {}
-PythonDictionary::~PythonDictionary ()
-{
-}
+PythonDictionary::~PythonDictionary() {}
-bool
-PythonDictionary::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
+bool PythonDictionary::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
- return PyDict_Check(py_obj);
+ return PyDict_Check(py_obj);
}
-void
-PythonDictionary::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonDictionary::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonDictionary::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-uint32_t
-PythonDictionary::GetSize() const
-{
- if (IsValid())
- return PyDict_Size(m_py_obj);
- return 0;
+uint32_t PythonDictionary::GetSize() const {
+ if (IsValid())
+ return PyDict_Size(m_py_obj);
+ return 0;
}
-PythonList
-PythonDictionary::GetKeys() const
-{
- if (IsValid())
- return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
- return PythonList(PyInitialValue::Invalid);
+PythonList PythonDictionary::GetKeys() const {
+ if (IsValid())
+ return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
+ return PythonList(PyInitialValue::Invalid);
}
-PythonObject
-PythonDictionary::GetItemForKey(const PythonObject &key) const
-{
- if (IsAllocated() && key.IsValid())
- return PythonObject(PyRefType::Borrowed, PyDict_GetItem(m_py_obj, key.get()));
- return PythonObject();
+PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
+ if (IsAllocated() && key.IsValid())
+ return PythonObject(PyRefType::Borrowed,
+ PyDict_GetItem(m_py_obj, key.get()));
+ return PythonObject();
}
-void
-PythonDictionary::SetItemForKey(const PythonObject &key, const PythonObject &value)
-{
- if (IsAllocated() && key.IsValid() && value.IsValid())
- PyDict_SetItem(m_py_obj, key.get(), value.get());
+void PythonDictionary::SetItemForKey(const PythonObject &key,
+ const PythonObject &value) {
+ if (IsAllocated() && key.IsValid() && value.IsValid())
+ PyDict_SetItem(m_py_obj, key.get(), value.get());
}
StructuredData::DictionarySP
-PythonDictionary::CreateStructuredDictionary() const
-{
- StructuredData::DictionarySP result(new StructuredData::Dictionary);
- PythonList keys(GetKeys());
- uint32_t num_keys = keys.GetSize();
- for (uint32_t i = 0; i < num_keys; ++i)
- {
- PythonObject key = keys.GetItemAtIndex(i);
- PythonObject value = GetItemForKey(key);
- StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
- result->AddItem(key.Str().GetString(), structured_value);
- }
- return result;
+PythonDictionary::CreateStructuredDictionary() const {
+ StructuredData::DictionarySP result(new StructuredData::Dictionary);
+ PythonList keys(GetKeys());
+ uint32_t num_keys = keys.GetSize();
+ for (uint32_t i = 0; i < num_keys; ++i) {
+ PythonObject key = keys.GetItemAtIndex(i);
+ PythonObject value = GetItemForKey(key);
+ StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
+ result->AddItem(key.Str().GetString(), structured_value);
+ }
+ return result;
}
-PythonModule::PythonModule() : PythonObject()
-{
-}
+PythonModule::PythonModule() : PythonObject() {}
-PythonModule::PythonModule(PyRefType type, PyObject *py_obj)
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
+PythonModule::PythonModule(PyRefType type, PyObject *py_obj) {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
}
-PythonModule::PythonModule(const PythonModule &dict) : PythonObject(dict)
-{
-}
+PythonModule::PythonModule(const PythonModule &dict) : PythonObject(dict) {}
-PythonModule::~PythonModule()
-{
-}
+PythonModule::~PythonModule() {}
-PythonModule
-PythonModule::BuiltinsModule()
-{
+PythonModule PythonModule::BuiltinsModule() {
#if PY_MAJOR_VERSION >= 3
- return AddModule("builtins");
+ return AddModule("builtins");
#else
- return AddModule("__builtin__");
+ return AddModule("__builtin__");
#endif
}
-PythonModule
-PythonModule::MainModule()
-{
- return AddModule("__main__");
-}
+PythonModule PythonModule::MainModule() { return AddModule("__main__"); }
-PythonModule
-PythonModule::AddModule(llvm::StringRef module)
-{
- std::string str = module.str();
- return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
+PythonModule PythonModule::AddModule(llvm::StringRef module) {
+ std::string str = module.str();
+ return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
}
-
-PythonModule
-PythonModule::ImportModule(llvm::StringRef module)
-{
- std::string str = module.str();
- return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
+PythonModule PythonModule::ImportModule(llvm::StringRef module) {
+ std::string str = module.str();
+ return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
}
-bool
-PythonModule::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
+bool PythonModule::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
- return PyModule_Check(py_obj);
+ return PyModule_Check(py_obj);
}
-void
-PythonModule::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonModule::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonModule::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-PythonDictionary
-PythonModule::GetDictionary() const
-{
- return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
+PythonDictionary PythonModule::GetDictionary() const {
+ return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
}
-PythonCallable::PythonCallable() : PythonObject()
-{
-}
+PythonCallable::PythonCallable() : PythonObject() {}
-PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj)
-{
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
+PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj) {
+ Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
}
PythonCallable::PythonCallable(const PythonCallable &callable)
- : PythonObject(callable)
-{
-}
+ : PythonObject(callable) {}
-PythonCallable::~PythonCallable()
-{
-}
+PythonCallable::~PythonCallable() {}
-bool
-PythonCallable::Check(PyObject *py_obj)
-{
- if (!py_obj)
- return false;
+bool PythonCallable::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
- return PyCallable_Check(py_obj);
+ return PyCallable_Check(py_obj);
}
-void
-PythonCallable::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonCallable::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonCallable::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack overflow since it calls
- // back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls
+ // back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
+PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
+ ArgInfo result = {0, false, false, false};
+ if (!IsValid())
+ return result;
-PythonCallable::ArgInfo
-PythonCallable::GetNumArguments() const
-{
- ArgInfo result = { 0, false, false, false };
- if (!IsValid())
- return result;
-
- PyObject *py_func_obj = m_py_obj;
- if (PyMethod_Check(py_func_obj))
- {
- py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
- PythonObject im_self = GetAttributeValue("im_self");
- if (im_self.IsValid() && !im_self.IsNone())
+ PyObject *py_func_obj = m_py_obj;
+ if (PyMethod_Check(py_func_obj)) {
+ py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
+ PythonObject im_self = GetAttributeValue("im_self");
+ if (im_self.IsValid() && !im_self.IsNone())
+ result.is_bound_method = true;
+ } else {
+ // see if this is a callable object with an __call__ method
+ if (!PyFunction_Check(py_func_obj)) {
+ PythonObject __call__ = GetAttributeValue("__call__");
+ if (__call__.IsValid()) {
+ auto __callable__ = __call__.AsType<PythonCallable>();
+ if (__callable__.IsValid()) {
+ py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
+ PythonObject im_self = GetAttributeValue("im_self");
+ if (im_self.IsValid() && !im_self.IsNone())
result.is_bound_method = true;
- }
- else
- {
- // see if this is a callable object with an __call__ method
- if (!PyFunction_Check(py_func_obj))
- {
- PythonObject __call__ = GetAttributeValue("__call__");
- if (__call__.IsValid())
- {
- auto __callable__ = __call__.AsType<PythonCallable>();
- if (__callable__.IsValid())
- {
- py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
- PythonObject im_self = GetAttributeValue("im_self");
- if (im_self.IsValid() && !im_self.IsNone())
- result.is_bound_method = true;
- }
- }
}
+ }
}
+ }
- if (!py_func_obj)
- return result;
-
- PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(py_func_obj);
- if (!code)
- return result;
+ if (!py_func_obj)
+ return result;
- result.count = code->co_argcount;
- result.has_varargs = !!(code->co_flags & CO_VARARGS);
- result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
+ PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
+ if (!code)
return result;
-}
-PythonObject
-PythonCallable::operator ()()
-{
- return PythonObject(PyRefType::Owned,
- PyObject_CallObject(m_py_obj, nullptr));
+ result.count = code->co_argcount;
+ result.has_varargs = !!(code->co_flags & CO_VARARGS);
+ result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
+ return result;
}
-PythonObject
-PythonCallable::operator ()(std::initializer_list<PyObject*> args)
-{
- PythonTuple arg_tuple(args);
- return PythonObject(PyRefType::Owned,
- PyObject_CallObject(m_py_obj, arg_tuple.get()));
+PythonObject PythonCallable::operator()() {
+ return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
}
-PythonObject
-PythonCallable::operator ()(std::initializer_list<PythonObject> args)
-{
- PythonTuple arg_tuple(args);
- return PythonObject(PyRefType::Owned,
- PyObject_CallObject(m_py_obj, arg_tuple.get()));
+PythonObject PythonCallable::
+operator()(std::initializer_list<PyObject *> args) {
+ PythonTuple arg_tuple(args);
+ return PythonObject(PyRefType::Owned,
+ PyObject_CallObject(m_py_obj, arg_tuple.get()));
}
-PythonFile::PythonFile()
- : PythonObject()
-{
+PythonObject PythonCallable::
+operator()(std::initializer_list<PythonObject> args) {
+ PythonTuple arg_tuple(args);
+ return PythonObject(PyRefType::Owned,
+ PyObject_CallObject(m_py_obj, arg_tuple.get()));
}
-PythonFile::PythonFile(File &file, const char *mode)
-{
- Reset(file, mode);
-}
+PythonFile::PythonFile() : PythonObject() {}
-PythonFile::PythonFile(const char *path, const char *mode)
-{
- lldb_private::File file(path, GetOptionsFromMode(mode));
- Reset(file, mode);
-}
+PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }
-PythonFile::PythonFile(PyRefType type, PyObject *o)
-{
- Reset(type, o);
+PythonFile::PythonFile(const char *path, const char *mode) {
+ lldb_private::File file(path, GetOptionsFromMode(mode));
+ Reset(file, mode);
}
-PythonFile::~PythonFile()
-{
-}
+PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); }
-bool
-PythonFile::Check(PyObject *py_obj)
-{
+PythonFile::~PythonFile() {}
+
+bool PythonFile::Check(PyObject *py_obj) {
#if PY_MAJOR_VERSION < 3
- return PyFile_Check(py_obj);
+ return PyFile_Check(py_obj);
#else
- // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
- // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper
- // over `io.open()`, which returns some object derived from `io.IOBase`.
- // As a result, the only way to detect a file in Python 3 is to check whether
- // it inherits from `io.IOBase`. Since it is possible for non-files to also
- // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
- // attribute, which should guarantee that it is backed by the file system.
- PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
- PythonDictionary io_dict(PyRefType::Borrowed, PyModule_GetDict(io_module.get()));
- PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
-
- PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
-
- if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
- return false;
- if (!object_type.HasAttribute("fileno"))
- return false;
+ // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
+ // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper
+ // over `io.open()`, which returns some object derived from `io.IOBase`.
+ // As a result, the only way to detect a file in Python 3 is to check whether
+ // it inherits from `io.IOBase`. Since it is possible for non-files to also
+ // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
+ // attribute, which should guarantee that it is backed by the file system.
+ PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
+ PythonDictionary io_dict(PyRefType::Borrowed,
+ PyModule_GetDict(io_module.get()));
+ PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
+
+ PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
+
+ if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
+ return false;
+ if (!object_type.HasAttribute("fileno"))
+ return false;
- return true;
+ return true;
#endif
}
-void
-PythonFile::Reset(PyRefType type, PyObject *py_obj)
-{
- // Grab the desired reference type so that if we end up rejecting
- // `py_obj` it still gets decremented if necessary.
- PythonObject result(type, py_obj);
+void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
+ // Grab the desired reference type so that if we end up rejecting
+ // `py_obj` it still gets decremented if necessary.
+ PythonObject result(type, py_obj);
- if (!PythonFile::Check(py_obj))
- {
- PythonObject::Reset();
- return;
- }
+ if (!PythonFile::Check(py_obj)) {
+ PythonObject::Reset();
+ return;
+ }
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ // Calling PythonObject::Reset(const PythonObject&) will lead to stack
+ // overflow since it calls back into the virtual implementation.
+ PythonObject::Reset(PyRefType::Borrowed, result.get());
}
-void
-PythonFile::Reset(File &file, const char *mode)
-{
- if (!file.IsValid())
- {
- Reset();
- return;
- }
+void PythonFile::Reset(File &file, const char *mode) {
+ if (!file.IsValid()) {
+ Reset();
+ return;
+ }
- char *cmode = const_cast<char *>(mode);
+ char *cmode = const_cast<char *>(mode);
#if PY_MAJOR_VERSION >= 3
- Reset(PyRefType::Owned,
- PyFile_FromFd(file.GetDescriptor(), nullptr, cmode, -1, nullptr, "ignore", nullptr, 0));
+ Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode,
+ -1, nullptr, "ignore", nullptr, 0));
#else
- // Read through the Python source, doesn't seem to modify these strings
- Reset(PyRefType::Owned,
- PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, nullptr));
+ // Read through the Python source, doesn't seem to modify these strings
+ Reset(PyRefType::Owned,
+ PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode,
+ nullptr));
#endif
}
-uint32_t
-PythonFile::GetOptionsFromMode(llvm::StringRef mode)
-{
- if (mode.empty())
- return 0;
-
- return llvm::StringSwitch<uint32_t>(mode.str().c_str())
- .Case("r", File::eOpenOptionRead)
- .Case("w", File::eOpenOptionWrite)
- .Case("a", File::eOpenOptionWrite|File::eOpenOptionAppend|File::eOpenOptionCanCreate)
- .Case("r+", File::eOpenOptionRead|File::eOpenOptionWrite)
- .Case("w+", File::eOpenOptionRead|File::eOpenOptionWrite|File::eOpenOptionCanCreate|File::eOpenOptionTruncate)
- .Case("a+", File::eOpenOptionRead|File::eOpenOptionWrite|File::eOpenOptionAppend|File::eOpenOptionCanCreate)
- .Default(0);
-}
+uint32_t PythonFile::GetOptionsFromMode(llvm::StringRef mode) {
+ if (mode.empty())
+ return 0;
-bool
-PythonFile::GetUnderlyingFile(File &file) const
-{
- if (!IsValid())
- return false;
+ return llvm::StringSwitch<uint32_t>(mode.str())
+ .Case("r", File::eOpenOptionRead)
+ .Case("w", File::eOpenOptionWrite)
+ .Case("a", File::eOpenOptionWrite | File::eOpenOptionAppend |
+ File::eOpenOptionCanCreate)
+ .Case("r+", File::eOpenOptionRead | File::eOpenOptionWrite)
+ .Case("w+", File::eOpenOptionRead | File::eOpenOptionWrite |
+ File::eOpenOptionCanCreate | File::eOpenOptionTruncate)
+ .Case("a+", File::eOpenOptionRead | File::eOpenOptionWrite |
+ File::eOpenOptionAppend | File::eOpenOptionCanCreate)
+ .Default(0);
+}
+
+bool PythonFile::GetUnderlyingFile(File &file) const {
+ if (!IsValid())
+ return false;
- file.Close();
- // We don't own the file descriptor returned by this function, make sure the
- // File object knows about that.
- file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
- PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
- file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
- return file.IsValid();
+ file.Close();
+ // We don't own the file descriptor returned by this function, make sure the
+ // File object knows about that.
+ file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
+ PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
+ file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
+ return file.IsValid();
}
-
#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 78245a98d0b8..b84996c928da 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -12,16 +12,19 @@
#ifndef LLDB_DISABLE_PYTHON
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-defines.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/StructuredData.h"
#include "lldb/Core/Flags.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Host/File.h"
#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/lldb-defines.h"
#include "llvm/ADT/ArrayRef.h"
@@ -33,536 +36,434 @@ class PythonList;
class PythonDictionary;
class PythonInteger;
-class StructuredPythonObject : public StructuredData::Generic
-{
+class StructuredPythonObject : public StructuredData::Generic {
public:
- StructuredPythonObject()
- : StructuredData::Generic()
- {
- }
-
- StructuredPythonObject(void *obj)
- : StructuredData::Generic(obj)
- {
- Py_XINCREF(GetValue());
- }
-
- ~StructuredPythonObject() override
- {
- if (Py_IsInitialized())
- Py_XDECREF(GetValue());
- SetValue(nullptr);
- }
-
- bool
- IsValid() const override
- {
- return GetValue() && GetValue() != Py_None;
- }
-
- void Dump(Stream &s) const override;
+ StructuredPythonObject() : StructuredData::Generic() {}
+
+ StructuredPythonObject(void *obj) : StructuredData::Generic(obj) {
+ Py_XINCREF(GetValue());
+ }
+
+ ~StructuredPythonObject() override {
+ if (Py_IsInitialized())
+ Py_XDECREF(GetValue());
+ SetValue(nullptr);
+ }
+
+ bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
private:
- DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
+ DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
};
-enum class PyObjectType
-{
- Unknown,
- None,
- Integer,
- Dictionary,
- List,
- String,
- Bytes,
- ByteArray,
- Module,
- Callable,
- Tuple,
- File
+enum class PyObjectType {
+ Unknown,
+ None,
+ Integer,
+ Dictionary,
+ List,
+ String,
+ Bytes,
+ ByteArray,
+ Module,
+ Callable,
+ Tuple,
+ File
};
-enum class PyRefType
-{
- Borrowed, // We are not given ownership of the incoming PyObject.
- // We cannot safely hold it without calling Py_INCREF.
- Owned // We have ownership of the incoming PyObject. We should
- // not call Py_INCREF.
+enum class PyRefType {
+ Borrowed, // We are not given ownership of the incoming PyObject.
+ // We cannot safely hold it without calling Py_INCREF.
+ Owned // We have ownership of the incoming PyObject. We should
+ // not call Py_INCREF.
};
-enum class PyInitialValue
-{
- Invalid,
- Empty
-};
+enum class PyInitialValue { Invalid, Empty };
-class PythonObject
-{
+class PythonObject {
public:
- PythonObject()
- : m_py_obj(nullptr)
- {
- }
-
- PythonObject(PyRefType type, PyObject *py_obj)
- : m_py_obj(nullptr)
- {
- Reset(type, py_obj);
- }
-
- PythonObject(const PythonObject &rhs)
- : m_py_obj(nullptr)
- {
- Reset(rhs);
- }
-
- virtual ~PythonObject()
- {
- Reset();
- }
-
- void
- Reset()
- {
- // Avoid calling the virtual method since it's not necessary
- // to actually validate the type of the PyObject if we're
- // just setting to null.
- if (Py_IsInitialized())
- Py_XDECREF(m_py_obj);
- m_py_obj = nullptr;
- }
-
- void
- Reset(const PythonObject &rhs)
- {
- // Avoid calling the virtual method if it's not necessary
- // to actually validate the type of the PyObject.
- if (!rhs.IsValid())
- Reset();
- else
- Reset(PyRefType::Borrowed, rhs.m_py_obj);
- }
-
- // PythonObject is implicitly convertible to PyObject *, which will call the
- // wrong overload. We want to explicitly disallow this, since a PyObject
- // *always* owns its reference. Therefore the overload which takes a
- // PyRefType doesn't make sense, and the copy constructor should be used.
- void
- Reset(PyRefType type, const PythonObject &ref) = delete;
-
- virtual void
- Reset(PyRefType type, PyObject *py_obj)
- {
- if (py_obj == m_py_obj)
- return;
-
- if (Py_IsInitialized())
- Py_XDECREF(m_py_obj);
-
- m_py_obj = py_obj;
-
- // If this is a borrowed reference, we need to convert it to
- // an owned reference by incrementing it. If it is an owned
- // reference (for example the caller allocated it with PyDict_New()
- // then we must *not* increment it.
- if (Py_IsInitialized() && type == PyRefType::Borrowed)
- Py_XINCREF(m_py_obj);
- }
-
- void
- Dump () const
- {
- if (m_py_obj)
- _PyObject_Dump (m_py_obj);
- else
- puts ("NULL");
- }
-
- void
- Dump (Stream &strm) const;
-
- PyObject*
- get() const
- {
- return m_py_obj;
- }
-
- PyObject*
- release()
- {
- PyObject *result = m_py_obj;
- m_py_obj = nullptr;
- return result;
- }
-
- PythonObject &
- operator=(const PythonObject &other)
- {
- Reset(PyRefType::Borrowed, other.get());
- return *this;
- }
-
- PyObjectType
- GetObjectType() const;
-
- PythonString
- Repr() const;
-
- PythonString
- Str() const;
-
- static PythonObject
- ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict);
-
- template<typename T>
- static T
- ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict)
- {
- return ResolveNameWithDictionary(name, dict).AsType<T>();
- }
-
- PythonObject
- ResolveName(llvm::StringRef name) const;
-
- template<typename T>
- T
- ResolveName(llvm::StringRef name) const
- {
- return ResolveName(name).AsType<T>();
- }
-
- bool
- HasAttribute(llvm::StringRef attribute) const;
-
- PythonObject
- GetAttributeValue(llvm::StringRef attribute) const;
-
- bool
- IsValid() const;
-
- bool
- IsAllocated() const;
-
- bool
- IsNone() const;
-
- template<typename T>
- T AsType() const
- {
- if (!T::Check(m_py_obj))
- return T();
- return T(PyRefType::Borrowed, m_py_obj);
- }
-
- StructuredData::ObjectSP
- CreateStructuredObject() const;
+ PythonObject() : m_py_obj(nullptr) {}
+
+ PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) {
+ Reset(type, py_obj);
+ }
+
+ PythonObject(const PythonObject &rhs) : m_py_obj(nullptr) { Reset(rhs); }
+
+ virtual ~PythonObject() { Reset(); }
+
+ void Reset() {
+ // Avoid calling the virtual method since it's not necessary
+ // to actually validate the type of the PyObject if we're
+ // just setting to null.
+ if (Py_IsInitialized())
+ Py_XDECREF(m_py_obj);
+ m_py_obj = nullptr;
+ }
+
+ void Reset(const PythonObject &rhs) {
+ // Avoid calling the virtual method if it's not necessary
+ // to actually validate the type of the PyObject.
+ if (!rhs.IsValid())
+ Reset();
+ else
+ Reset(PyRefType::Borrowed, rhs.m_py_obj);
+ }
+
+ // PythonObject is implicitly convertible to PyObject *, which will call the
+ // wrong overload. We want to explicitly disallow this, since a PyObject
+ // *always* owns its reference. Therefore the overload which takes a
+ // PyRefType doesn't make sense, and the copy constructor should be used.
+ void Reset(PyRefType type, const PythonObject &ref) = delete;
+
+ virtual void Reset(PyRefType type, PyObject *py_obj) {
+ if (py_obj == m_py_obj)
+ return;
+
+ if (Py_IsInitialized())
+ Py_XDECREF(m_py_obj);
+
+ m_py_obj = py_obj;
+
+ // If this is a borrowed reference, we need to convert it to
+ // an owned reference by incrementing it. If it is an owned
+ // reference (for example the caller allocated it with PyDict_New()
+ // then we must *not* increment it.
+ if (Py_IsInitialized() && type == PyRefType::Borrowed)
+ Py_XINCREF(m_py_obj);
+ }
+
+ void Dump() const {
+ if (m_py_obj)
+ _PyObject_Dump(m_py_obj);
+ else
+ puts("NULL");
+ }
+
+ void Dump(Stream &strm) const;
+
+ PyObject *get() const { return m_py_obj; }
+
+ PyObject *release() {
+ PyObject *result = m_py_obj;
+ m_py_obj = nullptr;
+ return result;
+ }
+
+ PythonObject &operator=(const PythonObject &other) {
+ Reset(PyRefType::Borrowed, other.get());
+ return *this;
+ }
+
+ PyObjectType GetObjectType() const;
+
+ PythonString Repr() const;
+
+ PythonString Str() const;
+
+ static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
+ const PythonDictionary &dict);
+
+ template <typename T>
+ static T ResolveNameWithDictionary(llvm::StringRef name,
+ const PythonDictionary &dict) {
+ return ResolveNameWithDictionary(name, dict).AsType<T>();
+ }
+
+ PythonObject ResolveName(llvm::StringRef name) const;
+
+ template <typename T> T ResolveName(llvm::StringRef name) const {
+ return ResolveName(name).AsType<T>();
+ }
+
+ bool HasAttribute(llvm::StringRef attribute) const;
+
+ PythonObject GetAttributeValue(llvm::StringRef attribute) const;
+
+ bool IsValid() const;
+
+ bool IsAllocated() const;
+
+ bool IsNone() const;
+
+ template <typename T> T AsType() const {
+ if (!T::Check(m_py_obj))
+ return T();
+ return T(PyRefType::Borrowed, m_py_obj);
+ }
+
+ StructuredData::ObjectSP CreateStructuredObject() const;
protected:
- PyObject* m_py_obj;
+ PyObject *m_py_obj;
};
-class PythonBytes : public PythonObject
-{
+class PythonBytes : public PythonObject {
public:
- PythonBytes();
- explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
- PythonBytes(const uint8_t *bytes, size_t length);
- PythonBytes(PyRefType type, PyObject *o);
- PythonBytes(const PythonBytes &object);
+ PythonBytes();
+ explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
+ PythonBytes(const uint8_t *bytes, size_t length);
+ PythonBytes(PyRefType type, PyObject *o);
+ PythonBytes(const PythonBytes &object);
- ~PythonBytes() override;
+ ~PythonBytes() override;
- static bool
- Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void
- Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- llvm::ArrayRef<uint8_t>
- GetBytes() const;
+ llvm::ArrayRef<uint8_t> GetBytes() const;
- size_t
- GetSize() const;
+ size_t GetSize() const;
- void
- SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
+ void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
- StructuredData::StringSP
- CreateStructuredString() const;
+ StructuredData::StringSP CreateStructuredString() const;
};
-class PythonByteArray : public PythonObject
-{
+class PythonByteArray : public PythonObject {
public:
- PythonByteArray();
- explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
- PythonByteArray(const uint8_t *bytes, size_t length);
- PythonByteArray(PyRefType type, PyObject *o);
- PythonByteArray(const PythonBytes &object);
+ PythonByteArray();
+ explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
+ PythonByteArray(const uint8_t *bytes, size_t length);
+ PythonByteArray(PyRefType type, PyObject *o);
+ PythonByteArray(const PythonBytes &object);
- ~PythonByteArray() override;
+ ~PythonByteArray() override;
- static bool
- Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void
- Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- llvm::ArrayRef<uint8_t>
- GetBytes() const;
+ llvm::ArrayRef<uint8_t> GetBytes() const;
- size_t
- GetSize() const;
+ size_t GetSize() const;
- void
- SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
+ void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
- StructuredData::StringSP
- CreateStructuredString() const;
+ StructuredData::StringSP CreateStructuredString() const;
};
-class PythonString : public PythonObject
-{
+class PythonString : public PythonObject {
public:
- PythonString();
- explicit PythonString(llvm::StringRef string);
- explicit PythonString(const char *string);
- PythonString(PyRefType type, PyObject *o);
- PythonString(const PythonString &object);
+ PythonString();
+ explicit PythonString(llvm::StringRef string);
+ explicit PythonString(const char *string);
+ PythonString(PyRefType type, PyObject *o);
+ PythonString(const PythonString &object);
- ~PythonString() override;
+ ~PythonString() override;
- static bool Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- llvm::StringRef
- GetString() const;
+ llvm::StringRef GetString() const;
- size_t
- GetSize() const;
+ size_t GetSize() const;
- void SetString(llvm::StringRef string);
+ void SetString(llvm::StringRef string);
- StructuredData::StringSP CreateStructuredString() const;
+ StructuredData::StringSP CreateStructuredString() const;
};
-class PythonInteger : public PythonObject
-{
+class PythonInteger : public PythonObject {
public:
- PythonInteger();
- explicit PythonInteger(int64_t value);
- PythonInteger(PyRefType type, PyObject *o);
- PythonInteger(const PythonInteger &object);
+ PythonInteger();
+ explicit PythonInteger(int64_t value);
+ PythonInteger(PyRefType type, PyObject *o);
+ PythonInteger(const PythonInteger &object);
- ~PythonInteger() override;
+ ~PythonInteger() override;
- static bool Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- int64_t GetInteger() const;
+ int64_t GetInteger() const;
- void
- SetInteger (int64_t value);
+ void SetInteger(int64_t value);
- StructuredData::IntegerSP CreateStructuredInteger() const;
+ StructuredData::IntegerSP CreateStructuredInteger() const;
};
-class PythonList : public PythonObject
-{
+class PythonList : public PythonObject {
public:
- PythonList() {}
- explicit PythonList(PyInitialValue value);
- explicit PythonList(int list_size);
- PythonList(PyRefType type, PyObject *o);
- PythonList(const PythonList &list);
+ PythonList() {}
+ explicit PythonList(PyInitialValue value);
+ explicit PythonList(int list_size);
+ PythonList(PyRefType type, PyObject *o);
+ PythonList(const PythonList &list);
- ~PythonList() override;
+ ~PythonList() override;
- static bool Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- uint32_t GetSize() const;
+ uint32_t GetSize() const;
- PythonObject GetItemAtIndex(uint32_t index) const;
+ PythonObject GetItemAtIndex(uint32_t index) const;
- void SetItemAtIndex(uint32_t index, const PythonObject &object);
+ void SetItemAtIndex(uint32_t index, const PythonObject &object);
- void AppendItem(const PythonObject &object);
+ void AppendItem(const PythonObject &object);
- StructuredData::ArraySP CreateStructuredArray() const;
+ StructuredData::ArraySP CreateStructuredArray() const;
};
-class PythonTuple : public PythonObject
-{
+class PythonTuple : public PythonObject {
public:
- PythonTuple() {}
- explicit PythonTuple(PyInitialValue value);
- explicit PythonTuple(int tuple_size);
- PythonTuple(PyRefType type, PyObject *o);
- PythonTuple(const PythonTuple &tuple);
- PythonTuple(std::initializer_list<PythonObject> objects);
- PythonTuple(std::initializer_list<PyObject*> objects);
+ PythonTuple() {}
+ explicit PythonTuple(PyInitialValue value);
+ explicit PythonTuple(int tuple_size);
+ PythonTuple(PyRefType type, PyObject *o);
+ PythonTuple(const PythonTuple &tuple);
+ PythonTuple(std::initializer_list<PythonObject> objects);
+ PythonTuple(std::initializer_list<PyObject *> objects);
- ~PythonTuple() override;
+ ~PythonTuple() override;
- static bool Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- uint32_t GetSize() const;
+ uint32_t GetSize() const;
- PythonObject GetItemAtIndex(uint32_t index) const;
+ PythonObject GetItemAtIndex(uint32_t index) const;
- void SetItemAtIndex(uint32_t index, const PythonObject &object);
+ void SetItemAtIndex(uint32_t index, const PythonObject &object);
- StructuredData::ArraySP CreateStructuredArray() const;
+ StructuredData::ArraySP CreateStructuredArray() const;
};
-class PythonDictionary : public PythonObject
-{
+class PythonDictionary : public PythonObject {
public:
- PythonDictionary() {}
- explicit PythonDictionary(PyInitialValue value);
- PythonDictionary(PyRefType type, PyObject *o);
- PythonDictionary(const PythonDictionary &dict);
+ PythonDictionary() {}
+ explicit PythonDictionary(PyInitialValue value);
+ PythonDictionary(PyRefType type, PyObject *o);
+ PythonDictionary(const PythonDictionary &dict);
- ~PythonDictionary() override;
+ ~PythonDictionary() override;
- static bool Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- uint32_t GetSize() const;
+ uint32_t GetSize() const;
- PythonList GetKeys() const;
+ PythonList GetKeys() const;
- PythonObject GetItemForKey(const PythonObject &key) const;
- void SetItemForKey(const PythonObject &key, const PythonObject &value);
+ PythonObject GetItemForKey(const PythonObject &key) const;
+ void SetItemForKey(const PythonObject &key, const PythonObject &value);
- StructuredData::DictionarySP CreateStructuredDictionary() const;
+ StructuredData::DictionarySP CreateStructuredDictionary() const;
};
-class PythonModule : public PythonObject
-{
- public:
- PythonModule();
- PythonModule(PyRefType type, PyObject *o);
- PythonModule(const PythonModule &dict);
+class PythonModule : public PythonObject {
+public:
+ PythonModule();
+ PythonModule(PyRefType type, PyObject *o);
+ PythonModule(const PythonModule &dict);
- ~PythonModule() override;
+ ~PythonModule() override;
- static bool Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- static PythonModule
- BuiltinsModule();
+ static PythonModule BuiltinsModule();
- static PythonModule
- MainModule();
+ static PythonModule MainModule();
- static PythonModule
- AddModule(llvm::StringRef module);
+ static PythonModule AddModule(llvm::StringRef module);
- static PythonModule
- ImportModule(llvm::StringRef module);
+ static PythonModule ImportModule(llvm::StringRef module);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- PythonDictionary GetDictionary() const;
+ PythonDictionary GetDictionary() const;
};
-class PythonCallable : public PythonObject
-{
+class PythonCallable : public PythonObject {
public:
- struct ArgInfo {
- size_t count;
- bool is_bound_method : 1;
- bool has_varargs : 1;
- bool has_kwargs : 1;
- };
+ struct ArgInfo {
+ size_t count;
+ bool is_bound_method : 1;
+ bool has_varargs : 1;
+ bool has_kwargs : 1;
+ };
- PythonCallable();
- PythonCallable(PyRefType type, PyObject *o);
- PythonCallable(const PythonCallable &dict);
+ PythonCallable();
+ PythonCallable(PyRefType type, PyObject *o);
+ PythonCallable(const PythonCallable &dict);
- ~PythonCallable() override;
+ ~PythonCallable() override;
- static bool
- Check(PyObject *py_obj);
+ static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ // Bring in the no-argument base class version
+ using PythonObject::Reset;
- void
- Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(PyRefType type, PyObject *py_obj) override;
- ArgInfo
- GetNumArguments() const;
+ ArgInfo GetNumArguments() const;
- PythonObject
- operator ()();
+ PythonObject operator()();
- PythonObject
- operator ()(std::initializer_list<PyObject*> args);
+ PythonObject operator()(std::initializer_list<PyObject *> args);
- PythonObject
- operator ()(std::initializer_list<PythonObject> args);
+ PythonObject operator()(std::initializer_list<PythonObject> args);
- template<typename Arg, typename... Args>
- PythonObject
- operator ()(const Arg &arg, Args... args)
- {
- return operator()({ arg, args... });
- }
+ template <typename Arg, typename... Args>
+ PythonObject operator()(const Arg &arg, Args... args) {
+ return operator()({arg, args...});
+ }
};
+class PythonFile : public PythonObject {
+public:
+ PythonFile();
+ PythonFile(File &file, const char *mode);
+ PythonFile(const char *path, const char *mode);
+ PythonFile(PyRefType type, PyObject *o);
-class PythonFile : public PythonObject
-{
- public:
- PythonFile();
- PythonFile(File &file, const char *mode);
- PythonFile(const char *path, const char *mode);
- PythonFile(PyRefType type, PyObject *o);
+ ~PythonFile() override;
- ~PythonFile() override;
+ static bool Check(PyObject *py_obj);
- static bool Check(PyObject *py_obj);
+ using PythonObject::Reset;
- using PythonObject::Reset;
+ void Reset(PyRefType type, PyObject *py_obj) override;
+ void Reset(File &file, const char *mode);
- void Reset(PyRefType type, PyObject *py_obj) override;
- void Reset(File &file, const char *mode);
+ static uint32_t GetOptionsFromMode(llvm::StringRef mode);
- static uint32_t GetOptionsFromMode(llvm::StringRef mode);
-
- bool GetUnderlyingFile(File &file) const;
+ bool GetUnderlyingFile(File &file) const;
};
} // namespace lldb_private
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
index 2cbd85bfa11e..4d956d5dbe14 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
@@ -9,7 +9,9 @@
#ifndef LLDB_DISABLE_PYTHON
+// LLDB Python header must be included first
#include "lldb-python.h"
+
#include "PythonExceptionState.h"
#include "llvm/ADT/StringRef.h"
@@ -18,184 +20,152 @@
using namespace lldb_private;
PythonExceptionState::PythonExceptionState(bool restore_on_exit)
- : m_restore_on_exit(restore_on_exit)
-{
- Acquire(restore_on_exit);
+ : m_restore_on_exit(restore_on_exit) {
+ Acquire(restore_on_exit);
}
-PythonExceptionState::~PythonExceptionState()
-{
- if (m_restore_on_exit)
- Restore();
+PythonExceptionState::~PythonExceptionState() {
+ if (m_restore_on_exit)
+ Restore();
}
-void
-PythonExceptionState::Acquire(bool restore_on_exit)
-{
- // If a state is already acquired, the user needs to decide whether they
- // want to discard or restore it. Don't allow the potential silent
- // loss of a valid state.
- assert(!IsError());
-
- if (!HasErrorOccurred())
- return;
-
- PyObject *py_type = nullptr;
- PyObject *py_value = nullptr;
- PyObject *py_traceback = nullptr;
- PyErr_Fetch(&py_type, &py_value, &py_traceback);
- // PyErr_Fetch clears the error flag.
- assert(!HasErrorOccurred());
-
- // Ownership of the objects returned by `PyErr_Fetch` is transferred
- // to us.
- m_type.Reset(PyRefType::Owned, py_type);
- m_value.Reset(PyRefType::Owned, py_value);
- m_traceback.Reset(PyRefType::Owned, py_traceback);
- m_restore_on_exit = restore_on_exit;
+void PythonExceptionState::Acquire(bool restore_on_exit) {
+ // If a state is already acquired, the user needs to decide whether they
+ // want to discard or restore it. Don't allow the potential silent
+ // loss of a valid state.
+ assert(!IsError());
+
+ if (!HasErrorOccurred())
+ return;
+
+ PyObject *py_type = nullptr;
+ PyObject *py_value = nullptr;
+ PyObject *py_traceback = nullptr;
+ PyErr_Fetch(&py_type, &py_value, &py_traceback);
+ // PyErr_Fetch clears the error flag.
+ assert(!HasErrorOccurred());
+
+ // Ownership of the objects returned by `PyErr_Fetch` is transferred
+ // to us.
+ m_type.Reset(PyRefType::Owned, py_type);
+ m_value.Reset(PyRefType::Owned, py_value);
+ m_traceback.Reset(PyRefType::Owned, py_traceback);
+ m_restore_on_exit = restore_on_exit;
}
-void
-PythonExceptionState::Restore()
-{
- if (m_type.IsValid())
- {
- // The documentation for PyErr_Restore says "Do not pass a null type and
- // non-null value or traceback. So only restore if type was non-null
- // to begin with. In this case we're passing ownership back to Python
- // so release them all.
- PyErr_Restore(m_type.release(), m_value.release(), m_traceback.release());
- }
-
- // After we restore, we should not hold onto the exception state. Demand that
- // it be re-acquired.
- Discard();
+void PythonExceptionState::Restore() {
+ if (m_type.IsValid()) {
+ // The documentation for PyErr_Restore says "Do not pass a null type and
+ // non-null value or traceback. So only restore if type was non-null
+ // to begin with. In this case we're passing ownership back to Python
+ // so release them all.
+ PyErr_Restore(m_type.release(), m_value.release(), m_traceback.release());
+ }
+
+ // After we restore, we should not hold onto the exception state. Demand that
+ // it be re-acquired.
+ Discard();
}
-void
-PythonExceptionState::Discard()
-{
- m_type.Reset();
- m_value.Reset();
- m_traceback.Reset();
+void PythonExceptionState::Discard() {
+ m_type.Reset();
+ m_value.Reset();
+ m_traceback.Reset();
}
-void
-PythonExceptionState::Reset()
-{
- if (m_restore_on_exit)
- Restore();
- else
- Discard();
-}
-
-bool
-PythonExceptionState::HasErrorOccurred()
-{
- return PyErr_Occurred();
-}
-
-bool
-PythonExceptionState::IsError() const
-{
- return m_type.IsValid() || m_value.IsValid() || m_traceback.IsValid();
-}
-
-PythonObject
-PythonExceptionState::GetType() const
-{
- return m_type;
+void PythonExceptionState::Reset() {
+ if (m_restore_on_exit)
+ Restore();
+ else
+ Discard();
}
-PythonObject
-PythonExceptionState::GetValue() const
-{
- return m_value;
-}
+bool PythonExceptionState::HasErrorOccurred() { return PyErr_Occurred(); }
-PythonObject
-PythonExceptionState::GetTraceback() const
-{
- return m_traceback;
+bool PythonExceptionState::IsError() const {
+ return m_type.IsValid() || m_value.IsValid() || m_traceback.IsValid();
}
-std::string
-PythonExceptionState::Format() const
-{
- // Don't allow this function to modify the error state.
- PythonExceptionState state(true);
-
- std::string backtrace = ReadBacktrace();
- if (!IsError())
- return std::string();
-
- // It's possible that ReadPythonBacktrace generated another exception.
- // If this happens we have to clear the exception, because otherwise
- // PyObject_Str() will assert below. That's why we needed to do the
- // save / restore at the beginning of this function.
- PythonExceptionState bt_error_state(false);
-
- std::string error_string;
- llvm::raw_string_ostream error_stream(error_string);
- error_stream << m_value.Str().GetString() << "\n";
-
- if (!bt_error_state.IsError())
- {
- // If we were able to read the backtrace, just append it.
- error_stream << backtrace << "\n";
- }
- else
- {
- // Otherwise, append some information about why we were unable to
- // obtain the backtrace.
- PythonString bt_error = bt_error_state.GetValue().Str();
- error_stream << "An error occurred while retrieving the backtrace: " << bt_error.GetString() << "\n";
- }
- return error_stream.str();
+PythonObject PythonExceptionState::GetType() const { return m_type; }
+
+PythonObject PythonExceptionState::GetValue() const { return m_value; }
+
+PythonObject PythonExceptionState::GetTraceback() const { return m_traceback; }
+
+std::string PythonExceptionState::Format() const {
+ // Don't allow this function to modify the error state.
+ PythonExceptionState state(true);
+
+ std::string backtrace = ReadBacktrace();
+ if (!IsError())
+ return std::string();
+
+ // It's possible that ReadPythonBacktrace generated another exception.
+ // If this happens we have to clear the exception, because otherwise
+ // PyObject_Str() will assert below. That's why we needed to do the
+ // save / restore at the beginning of this function.
+ PythonExceptionState bt_error_state(false);
+
+ std::string error_string;
+ llvm::raw_string_ostream error_stream(error_string);
+ error_stream << m_value.Str().GetString() << "\n";
+
+ if (!bt_error_state.IsError()) {
+ // If we were able to read the backtrace, just append it.
+ error_stream << backtrace << "\n";
+ } else {
+ // Otherwise, append some information about why we were unable to
+ // obtain the backtrace.
+ PythonString bt_error = bt_error_state.GetValue().Str();
+ error_stream << "An error occurred while retrieving the backtrace: "
+ << bt_error.GetString() << "\n";
+ }
+ return error_stream.str();
}
-std::string
-PythonExceptionState::ReadBacktrace() const
-{
- std::string retval("backtrace unavailable");
+std::string PythonExceptionState::ReadBacktrace() const {
+ std::string retval("backtrace unavailable");
- auto traceback_module = PythonModule::ImportModule("traceback");
+ auto traceback_module = PythonModule::ImportModule("traceback");
#if PY_MAJOR_VERSION >= 3
- auto stringIO_module = PythonModule::ImportModule("io");
+ auto stringIO_module = PythonModule::ImportModule("io");
#else
- auto stringIO_module = PythonModule::ImportModule("StringIO");
+ auto stringIO_module = PythonModule::ImportModule("StringIO");
#endif
- if (!m_traceback.IsAllocated())
- return retval;
+ if (!m_traceback.IsAllocated())
+ return retval;
- if (!traceback_module.IsAllocated() || !stringIO_module.IsAllocated())
- return retval;
+ if (!traceback_module.IsAllocated() || !stringIO_module.IsAllocated())
+ return retval;
- auto stringIO_builder = stringIO_module.ResolveName<PythonCallable>("StringIO");
- if (!stringIO_builder.IsAllocated())
- return retval;
+ auto stringIO_builder =
+ stringIO_module.ResolveName<PythonCallable>("StringIO");
+ if (!stringIO_builder.IsAllocated())
+ return retval;
- auto stringIO_buffer = stringIO_builder();
- if (!stringIO_buffer.IsAllocated())
- return retval;
+ auto stringIO_buffer = stringIO_builder();
+ if (!stringIO_buffer.IsAllocated())
+ return retval;
- auto printTB = traceback_module.ResolveName<PythonCallable>("print_tb");
- if (!printTB.IsAllocated())
- return retval;
+ auto printTB = traceback_module.ResolveName<PythonCallable>("print_tb");
+ if (!printTB.IsAllocated())
+ return retval;
- auto printTB_result = printTB(m_traceback.get(), Py_None, stringIO_buffer.get());
- auto stringIO_getvalue = stringIO_buffer.ResolveName<PythonCallable>("getvalue");
- if (!stringIO_getvalue.IsAllocated())
- return retval;
+ auto printTB_result =
+ printTB(m_traceback.get(), Py_None, stringIO_buffer.get());
+ auto stringIO_getvalue =
+ stringIO_buffer.ResolveName<PythonCallable>("getvalue");
+ if (!stringIO_getvalue.IsAllocated())
+ return retval;
- auto printTB_string = stringIO_getvalue().AsType<PythonString>();
- if (!printTB_string.IsAllocated())
- return retval;
+ auto printTB_string = stringIO_getvalue().AsType<PythonString>();
+ if (!printTB_string.IsAllocated())
+ return retval;
- llvm::StringRef string_data(printTB_string.GetString());
- retval.assign(string_data.data(), string_data.size());
+ llvm::StringRef string_data(printTB_string.GetString());
+ retval.assign(string_data.data(), string_data.size());
- return retval;
+ return retval;
}
#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
index c74e52b9ef56..20f4b4c6329d 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
+++ b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
@@ -14,54 +14,41 @@
#include "PythonDataObjects.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class PythonExceptionState
-{
- public:
- explicit PythonExceptionState(bool restore_on_exit);
- ~PythonExceptionState();
+class PythonExceptionState {
+public:
+ explicit PythonExceptionState(bool restore_on_exit);
+ ~PythonExceptionState();
- void
- Acquire(bool restore_on_exit);
+ void Acquire(bool restore_on_exit);
- void
- Restore();
+ void Restore();
- void
- Discard();
+ void Discard();
- void
- Reset();
+ void Reset();
- static bool
- HasErrorOccurred();
+ static bool HasErrorOccurred();
- bool
- IsError() const;
+ bool IsError() const;
- PythonObject
- GetType() const;
+ PythonObject GetType() const;
- PythonObject
- GetValue() const;
+ PythonObject GetValue() const;
- PythonObject
- GetTraceback() const;
+ PythonObject GetTraceback() const;
- std::string
- Format() const;
+ std::string Format() const;
- private:
- std::string
- ReadBacktrace() const;
+private:
+ std::string ReadBacktrace() const;
- bool m_restore_on_exit;
+ bool m_restore_on_exit;
- PythonObject m_type;
- PythonObject m_value;
- PythonObject m_traceback;
+ PythonObject m_type;
+ PythonObject m_value;
+ PythonObject m_traceback;
};
}
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 788167370593..3747b2b86d52 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -13,13 +13,15 @@
#else
+// LLDB Python header must be included first
#include "lldb-python.h"
-#include "ScriptInterpreterPython.h"
+
#include "PythonDataObjects.h"
#include "PythonExceptionState.h"
+#include "ScriptInterpreterPython.h"
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <mutex>
#include <string>
@@ -47,1574 +49,1548 @@
#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
#endif
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
static ScriptInterpreterPython::SWIGInitCallback g_swig_init_callback = nullptr;
-static ScriptInterpreterPython::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = nullptr;
-static ScriptInterpreterPython::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
-static ScriptInterpreterPython::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
-static ScriptInterpreterPython::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
-static ScriptInterpreterPython::SWIGPythonCreateCommandObject g_swig_create_cmd = nullptr;
-static ScriptInterpreterPython::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
-static ScriptInterpreterPython::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
-static ScriptInterpreterPython::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
-static ScriptInterpreterPython::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = nullptr;
-static ScriptInterpreterPython::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
-static ScriptInterpreterPython::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
-static ScriptInterpreterPython::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
-static ScriptInterpreterPython::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr;
-static ScriptInterpreterPython::SWIGPythonCallCommand g_swig_call_command = nullptr;
-static ScriptInterpreterPython::SWIGPythonCallCommandObject g_swig_call_command_object = nullptr;
-static ScriptInterpreterPython::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
-static ScriptInterpreterPython::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
-static ScriptInterpreterPython::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
-static ScriptInterpreterPython::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
-static ScriptInterpreterPython::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
-static ScriptInterpreterPython::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
-static ScriptInterpreterPython::SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr;
-static ScriptInterpreterPython::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
-static ScriptInterpreterPython::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr;
-static ScriptInterpreterPython::SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr;
+static ScriptInterpreterPython::SWIGBreakpointCallbackFunction
+ g_swig_breakpoint_callback = nullptr;
+static ScriptInterpreterPython::SWIGWatchpointCallbackFunction
+ g_swig_watchpoint_callback = nullptr;
+static ScriptInterpreterPython::SWIGPythonTypeScriptCallbackFunction
+ g_swig_typescript_callback = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateSyntheticProvider
+ g_swig_synthetic_script = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateCommandObject
+ g_swig_create_cmd = nullptr;
+static ScriptInterpreterPython::SWIGPythonCalculateNumChildren
+ g_swig_calc_children = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetChildAtIndex
+ g_swig_get_child_index = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetIndexOfChildWithName
+ g_swig_get_index_child = nullptr;
+static ScriptInterpreterPython::SWIGPythonCastPyObjectToSBValue
+ g_swig_cast_to_sbvalue = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetValueObjectSPFromSBValue
+ g_swig_get_valobj_sp_from_sbvalue = nullptr;
+static ScriptInterpreterPython::SWIGPythonUpdateSynthProviderInstance
+ g_swig_update_provider = nullptr;
+static ScriptInterpreterPython::SWIGPythonMightHaveChildrenSynthProviderInstance
+ g_swig_mighthavechildren_provider = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetValueSynthProviderInstance
+ g_swig_getvalue_provider = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallCommand g_swig_call_command =
+ nullptr;
+static ScriptInterpreterPython::SWIGPythonCallCommandObject
+ g_swig_call_command_object = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallModuleInit
+ g_swig_call_module_init = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateOSPlugin
+ g_swig_create_os_plugin = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Process
+ g_swig_run_script_keyword_process = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Thread
+ g_swig_run_script_keyword_thread = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Target
+ g_swig_run_script_keyword_target = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Frame
+ g_swig_run_script_keyword_frame = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Value
+ g_swig_run_script_keyword_value = nullptr;
+static ScriptInterpreterPython::SWIGPython_GetDynamicSetting g_swig_plugin_get =
+ nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateScriptedThreadPlan
+ g_swig_thread_plan_script = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallThreadPlan
+ g_swig_call_thread_plan = nullptr;
static bool g_initialized = false;
-namespace
-{
+namespace {
// Initializing Python is not a straightforward process. We cannot control what
// external code may have done before getting to this point in LLDB, including
// potentially having already initialized Python, so we need to do a lot of work
// to ensure that the existing state of the system is maintained across our
-// initialization. We do this by using an RAII pattern where we save off initial
-// state at the beginning, and restore it at the end
-struct InitializePythonRAII
-{
+// initialization. We do this by using an RAII pattern where we save off
+// initial
+// state at the beginning, and restore it at the end
+struct InitializePythonRAII {
public:
- InitializePythonRAII() :
- m_gil_state(PyGILState_UNLOCKED),
- m_was_already_initialized(false)
- {
- // Python will muck with STDIN terminal state, so save off any current TTY
- // settings so we can restore them.
- m_stdin_tty_state.Save(STDIN_FILENO, false);
+ InitializePythonRAII()
+ : m_gil_state(PyGILState_UNLOCKED), m_was_already_initialized(false) {
+ // Python will muck with STDIN terminal state, so save off any current TTY
+ // settings so we can restore them.
+ m_stdin_tty_state.Save(STDIN_FILENO, false);
- InitializePythonHome();
+ InitializePythonHome();
- // 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.
+// 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.
#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3)
- Py_InitializeEx(0);
- InitializeThreadsPrivate();
+ Py_InitializeEx(0);
+ InitializeThreadsPrivate();
#else
- InitializeThreadsPrivate();
- Py_InitializeEx(0);
+ InitializeThreadsPrivate();
+ Py_InitializeEx(0);
#endif
- }
+ }
- ~InitializePythonRAII()
- {
- if (m_was_already_initialized)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+ ~InitializePythonRAII() {
+ if (m_was_already_initialized) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT |
+ LIBLLDB_LOG_VERBOSE));
- if (log)
- {
- log->Printf("Releasing PyGILState. Returning to state = %slocked\n",
- m_was_already_initialized == PyGILState_UNLOCKED ? "un" : "");
- }
- PyGILState_Release(m_gil_state);
- }
- else
- {
- // We initialized the threads in this function, just unlock the GIL.
- PyEval_SaveThread();
- }
-
- m_stdin_tty_state.Restore();
+ if (log) {
+ log->Printf("Releasing PyGILState. Returning to state = %slocked\n",
+ m_was_already_initialized == PyGILState_UNLOCKED ? "un"
+ : "");
+ }
+ PyGILState_Release(m_gil_state);
+ } else {
+ // We initialized the threads in this function, just unlock the GIL.
+ PyEval_SaveThread();
}
+ m_stdin_tty_state.Restore();
+ }
+
private:
- void InitializePythonHome()
- {
+ void InitializePythonHome() {
#if defined(LLDB_PYTHON_HOME)
#if PY_MAJOR_VERSION >= 3
- size_t size = 0;
- static wchar_t *g_python_home = Py_DecodeLocale(LLDB_PYTHON_HOME, &size);
+ size_t size = 0;
+ static wchar_t *g_python_home = Py_DecodeLocale(LLDB_PYTHON_HOME, &size);
#else
- static char g_python_home[] = LLDB_PYTHON_HOME;
+ static char g_python_home[] = LLDB_PYTHON_HOME;
#endif
- Py_SetPythonHome(g_python_home);
+ Py_SetPythonHome(g_python_home);
#endif
- }
+ }
- void InitializeThreadsPrivate()
- {
- if (PyEval_ThreadsInitialized())
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+ void InitializeThreadsPrivate() {
+ if (PyEval_ThreadsInitialized()) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT |
+ LIBLLDB_LOG_VERBOSE));
- m_was_already_initialized = true;
- m_gil_state = PyGILState_Ensure();
- if (log)
- {
- log->Printf("Ensured PyGILState. Previous state = %slocked\n",
+ m_was_already_initialized = true;
+ m_gil_state = PyGILState_Ensure();
+ if (log) {
+ log->Printf("Ensured PyGILState. Previous state = %slocked\n",
m_gil_state == PyGILState_UNLOCKED ? "un" : "");
- }
- return;
- }
-
- // InitThreads acquires the GIL if it hasn't been called before.
- PyEval_InitThreads();
+ }
+ return;
}
- TerminalState m_stdin_tty_state;
- PyGILState_STATE m_gil_state;
- bool m_was_already_initialized;
-};
+ // InitThreads acquires the GIL if it hasn't been called before.
+ PyEval_InitThreads();
+ }
+ TerminalState m_stdin_tty_state;
+ PyGILState_STATE m_gil_state;
+ bool m_was_already_initialized;
+};
}
-ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *py_interpreter,
- uint16_t on_entry,
- uint16_t on_leave,
- FILE *in,
- FILE *out,
- FILE *err) :
- ScriptInterpreterLocker (),
- m_teardown_session( (on_leave & TearDownSession) == TearDownSession ),
- m_python_interpreter(py_interpreter)
-{
- DoAcquireLock();
- if ((on_entry & InitSession) == InitSession)
- {
- if (DoInitSession(on_entry, in, out, err) == false)
- {
- // Don't teardown the session if we didn't init it.
- m_teardown_session = false;
- }
- }
+ScriptInterpreterPython::Locker::Locker(ScriptInterpreterPython *py_interpreter,
+ uint16_t on_entry, uint16_t on_leave,
+ FILE *in, FILE *out, FILE *err)
+ : ScriptInterpreterLocker(),
+ m_teardown_session((on_leave & TearDownSession) == TearDownSession),
+ m_python_interpreter(py_interpreter) {
+ DoAcquireLock();
+ if ((on_entry & InitSession) == InitSession) {
+ if (DoInitSession(on_entry, in, out, err) == false) {
+ // Don't teardown the session if we didn't init it.
+ m_teardown_session = false;
+ }
+ }
+}
+
+bool ScriptInterpreterPython::Locker::DoAcquireLock() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT |
+ LIBLLDB_LOG_VERBOSE));
+ m_GILState = PyGILState_Ensure();
+ if (log)
+ log->Printf("Ensured PyGILState. Previous state = %slocked\n",
+ m_GILState == PyGILState_UNLOCKED ? "un" : "");
+
+ // we need to save the thread state when we first start the command
+ // because we might decide to interrupt it while some action is taking
+ // place outside of Python (e.g. printing to screen, waiting for the network,
+ // ...)
+ // in that case, _PyThreadState_Current will be NULL - and we would be unable
+ // to set the asynchronous exception - not a desirable situation
+ m_python_interpreter->SetThreadState(PyThreadState_Get());
+ m_python_interpreter->IncrementLockCount();
+ return true;
+}
+
+bool ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags,
+ FILE *in, FILE *out,
+ FILE *err) {
+ if (!m_python_interpreter)
+ return false;
+ return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
}
-bool
-ScriptInterpreterPython::Locker::DoAcquireLock()
-{
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
- m_GILState = PyGILState_Ensure();
- if (log)
- log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
-
- // we need to save the thread state when we first start the command
- // because we might decide to interrupt it while some action is taking
- // place outside of Python (e.g. printing to screen, waiting for the network, ...)
- // in that case, _PyThreadState_Current will be NULL - and we would be unable
- // to set the asynchronous exception - not a desirable situation
- m_python_interpreter->SetThreadState(PyThreadState_Get());
- m_python_interpreter->IncrementLockCount();
- return true;
+bool ScriptInterpreterPython::Locker::DoFreeLock() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT |
+ LIBLLDB_LOG_VERBOSE));
+ if (log)
+ log->Printf("Releasing PyGILState. Returning to state = %slocked\n",
+ m_GILState == PyGILState_UNLOCKED ? "un" : "");
+ PyGILState_Release(m_GILState);
+ m_python_interpreter->DecrementLockCount();
+ return true;
}
-bool
-ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err)
-{
- if (!m_python_interpreter)
- return false;
- return m_python_interpreter->EnterSession (on_entry_flags, in, out, err);
-}
+bool ScriptInterpreterPython::Locker::DoTearDownSession() {
+ if (!m_python_interpreter)
+ return false;
+ m_python_interpreter->LeaveSession();
+ return true;
+}
+
+ScriptInterpreterPython::Locker::~Locker() {
+ if (m_teardown_session)
+ DoTearDownSession();
+ DoFreeLock();
+}
+
+ScriptInterpreterPython::ScriptInterpreterPython(
+ CommandInterpreter &interpreter)
+ : ScriptInterpreter(interpreter, eScriptLanguagePython),
+ IOHandlerDelegateMultiline("DONE"), m_saved_stdin(), m_saved_stdout(),
+ m_saved_stderr(), m_main_module(), m_lldb_module(),
+ m_session_dict(PyInitialValue::Invalid),
+ m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(),
+ m_run_one_line_str_global(),
+ m_dictionary_name(
+ interpreter.GetDebugger().GetInstanceName().AsCString()),
+ m_terminal_state(), m_active_io_handler(eIOHandlerNone),
+ m_session_is_active(false), m_pty_slave_is_open(false),
+ m_valid_session(true), m_lock_count(0), m_command_thread_state(nullptr) {
+ InitializePrivate();
+
+ m_dictionary_name.append("_dict");
+ StreamString run_string;
+ run_string.Printf("%s = dict()", m_dictionary_name.c_str());
+
+ Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ PyRun_SimpleString(run_string.GetData());
+
+ run_string.Clear();
+ run_string.Printf(
+ "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')",
+ m_dictionary_name.c_str());
+ PyRun_SimpleString(run_string.GetData());
+
+ // Reloading modules requires a different syntax in Python 2 and Python 3.
+ // This provides
+ // a consistent syntax no matter what version of Python.
+ run_string.Clear();
+ run_string.Printf("run_one_line (%s, 'from six.moves import reload_module')",
+ m_dictionary_name.c_str());
+ PyRun_SimpleString(run_string.GetData());
+
+ // WARNING: temporary code that loads Cocoa formatters - this should be done
+ // on a per-platform basis rather than loading the whole set
+ // and letting the individual formatter classes exploit APIs to check whether
+ // they can/cannot do their task
+ run_string.Clear();
+ run_string.Printf(
+ "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')",
+ m_dictionary_name.c_str());
+ PyRun_SimpleString(run_string.GetData());
+ run_string.Clear();
+
+ run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from "
+ "lldb.embedded_interpreter import run_python_interpreter; "
+ "from lldb.embedded_interpreter import run_one_line')",
+ m_dictionary_name.c_str());
+ PyRun_SimpleString(run_string.GetData());
+ run_string.Clear();
+
+ run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
+ "; pydoc.pager = pydoc.plainpager')",
+ m_dictionary_name.c_str(),
+ interpreter.GetDebugger().GetID());
+ PyRun_SimpleString(run_string.GetData());
+}
+
+ScriptInterpreterPython::~ScriptInterpreterPython() {
+ // the session dictionary may hold objects with complex state
+ // which means that they may need to be torn down with some level of smarts
+ // and that, in turn, requires a valid thread state
+ // force Python to procure itself such a thread state, nuke the session
+ // dictionary
+ // and then release it for others to use and proceed with the rest of the
+ // shutdown
+ auto gil_state = PyGILState_Ensure();
+ m_session_dict.Reset();
+ PyGILState_Release(gil_state);
+}
+
+void ScriptInterpreterPython::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ lldb::eScriptLanguagePython, CreateInstance);
+ });
+}
+
+void ScriptInterpreterPython::Terminate() {}
-bool
-ScriptInterpreterPython::Locker::DoFreeLock()
-{
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
- PyGILState_Release(m_GILState);
- m_python_interpreter->DecrementLockCount();
- return true;
+lldb::ScriptInterpreterSP
+ScriptInterpreterPython::CreateInstance(CommandInterpreter &interpreter) {
+ return std::make_shared<ScriptInterpreterPython>(interpreter);
}
-bool
-ScriptInterpreterPython::Locker::DoTearDownSession()
-{
- if (!m_python_interpreter)
- return false;
- m_python_interpreter->LeaveSession ();
- return true;
+lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() {
+ static ConstString g_name("script-python");
+ return g_name;
}
-ScriptInterpreterPython::Locker::~Locker()
-{
- if (m_teardown_session)
- DoTearDownSession();
- DoFreeLock();
-}
-
-ScriptInterpreterPython::ScriptInterpreterPython(CommandInterpreter &interpreter) :
- ScriptInterpreter(interpreter, eScriptLanguagePython),
- IOHandlerDelegateMultiline("DONE"),
- m_saved_stdin(),
- m_saved_stdout(),
- m_saved_stderr(),
- m_main_module(),
- m_lldb_module(),
- m_session_dict(PyInitialValue::Invalid),
- m_sys_module_dict(PyInitialValue::Invalid),
- m_run_one_line_function(),
- m_run_one_line_str_global(),
- m_dictionary_name(interpreter.GetDebugger().GetInstanceName().AsCString()),
- m_terminal_state(),
- m_active_io_handler(eIOHandlerNone),
- m_session_is_active(false),
- m_pty_slave_is_open(false),
- m_valid_session(true),
- m_lock_count(0),
- m_command_thread_state(nullptr)
-{
- InitializePrivate();
-
- m_dictionary_name.append("_dict");
- StreamString run_string;
- run_string.Printf ("%s = dict()", m_dictionary_name.c_str());
-
- Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
- PyRun_SimpleString (run_string.GetData());
-
- run_string.Clear();
- run_string.Printf ("run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')", m_dictionary_name.c_str());
- PyRun_SimpleString (run_string.GetData());
-
- // Reloading modules requires a different syntax in Python 2 and Python 3. This provides
- // a consistent syntax no matter what version of Python.
- run_string.Clear();
- run_string.Printf("run_one_line (%s, 'from six.moves import reload_module')", m_dictionary_name.c_str());
- PyRun_SimpleString(run_string.GetData());
-
- // WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
- // and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
- run_string.Clear();
- run_string.Printf ("run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
- PyRun_SimpleString (run_string.GetData());
- run_string.Clear();
-
- run_string.Printf ("run_one_line (%s, 'import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line')", m_dictionary_name.c_str());
- PyRun_SimpleString (run_string.GetData());
- run_string.Clear();
-
- run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 "; pydoc.pager = pydoc.plainpager')", m_dictionary_name.c_str(),
- interpreter.GetDebugger().GetID());
- PyRun_SimpleString (run_string.GetData());
-}
-
-ScriptInterpreterPython::~ScriptInterpreterPython ()
-{
- // the session dictionary may hold objects with complex state
- // which means that they may need to be torn down with some level of smarts
- // and that, in turn, requires a valid thread state
- // force Python to procure itself such a thread state, nuke the session dictionary
- // and then release it for others to use and proceed with the rest of the shutdown
- auto gil_state = PyGILState_Ensure();
- m_session_dict.Reset();
- PyGILState_Release(gil_state);
-}
-
-void
-ScriptInterpreterPython::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- lldb::eScriptLanguagePython,
- CreateInstance);
- });
+const char *ScriptInterpreterPython::GetPluginDescriptionStatic() {
+ return "Embedded Python interpreter";
}
-
-void
-ScriptInterpreterPython::Terminate()
-{
+lldb_private::ConstString ScriptInterpreterPython::GetPluginName() {
+ return GetPluginNameStatic();
}
-
-lldb::ScriptInterpreterSP
-ScriptInterpreterPython::CreateInstance(CommandInterpreter &interpreter)
-{
- return std::make_shared<ScriptInterpreterPython>(interpreter);
-}
-
-lldb_private::ConstString
-ScriptInterpreterPython::GetPluginNameStatic()
-{
- static ConstString g_name("script-python");
- return g_name;
-}
-
-const char *
-ScriptInterpreterPython::GetPluginDescriptionStatic()
-{
- return "Embedded Python interpreter";
-}
-
-lldb_private::ConstString
-ScriptInterpreterPython::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ScriptInterpreterPython::GetPluginVersion()
-{
- return 1;
-}
-
-void
-ScriptInterpreterPython::IOHandlerActivated (IOHandler &io_handler)
-{
- const char *instructions = nullptr;
-
- switch (m_active_io_handler)
- {
- case eIOHandlerNone:
- break;
- case eIOHandlerBreakpoint:
- instructions = R"(Enter your Python command(s). Type 'DONE' to end.
+
+uint32_t ScriptInterpreterPython::GetPluginVersion() { return 1; }
+
+void ScriptInterpreterPython::IOHandlerActivated(IOHandler &io_handler) {
+ const char *instructions = nullptr;
+
+ switch (m_active_io_handler) {
+ case eIOHandlerNone:
+ break;
+ case eIOHandlerBreakpoint:
+ instructions = R"(Enter your Python command(s). Type 'DONE' to end.
def function (frame, bp_loc, internal_dict):
"""frame: the lldb.SBFrame for the location at which you stopped
bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
internal_dict: an LLDB support object not to be used"""
)";
- break;
- case eIOHandlerWatchpoint:
- instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
- break;
- }
-
- if (instructions)
- {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString(instructions);
- output_sp->Flush();
- }
- }
-}
-
-void
-ScriptInterpreterPython::IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
-{
- io_handler.SetIsDone(true);
- bool batch_mode = m_interpreter.GetBatchCommandMode();
-
- switch (m_active_io_handler)
- {
- case eIOHandlerNone:
- break;
- case eIOHandlerBreakpoint:
- {
- std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
- for (auto bp_options : *bp_options_vec)
- {
- if (!bp_options)
- continue;
-
- std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
- if (data_ap.get())
- {
- data_ap->user_source.SplitIntoLines(data);
-
- if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source).Success())
- {
- BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
- bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
- }
- else if (!batch_mode)
- {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
- if (error_sp)
- {
- error_sp->Printf ("Warning: No command attached to breakpoint.\n");
- error_sp->Flush();
- }
- }
- }
- }
- m_active_io_handler = eIOHandlerNone;
- }
+ break;
+ case eIOHandlerWatchpoint:
+ instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
+ break;
+ }
+
+ if (instructions) {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(instructions);
+ output_sp->Flush();
+ }
+ }
+}
+
+void ScriptInterpreterPython::IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) {
+ io_handler.SetIsDone(true);
+ bool batch_mode = m_interpreter.GetBatchCommandMode();
+
+ switch (m_active_io_handler) {
+ case eIOHandlerNone:
+ break;
+ case eIOHandlerBreakpoint: {
+ std::vector<BreakpointOptions *> *bp_options_vec =
+ (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
+ for (auto bp_options : *bp_options_vec) {
+ if (!bp_options)
+ continue;
+
+ auto data_ap = llvm::make_unique<CommandDataPython>();
+ if (!data_ap)
break;
- case eIOHandlerWatchpoint:
- {
- WatchpointOptions *wp_options = (WatchpointOptions *)io_handler.GetUserData();
- std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
- if (data_ap.get())
- {
- data_ap->user_source.SplitIntoLines(data);
-
- if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
- {
- BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
- wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
- }
- else if (!batch_mode)
- {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
- if (error_sp)
- {
- error_sp->Printf ("Warning: No command attached to breakpoint.\n");
- error_sp->Flush();
- }
- }
- }
- m_active_io_handler = eIOHandlerNone;
+ data_ap->user_source.SplitIntoLines(data);
+
+ if (GenerateBreakpointCommandCallbackData(data_ap->user_source,
+ data_ap->script_source)
+ .Success()) {
+ auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
+ std::move(data_ap));
+ bp_options->SetCallback(
+ ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
+ } else if (!batch_mode) {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ if (error_sp) {
+ error_sp->Printf("Warning: No command attached to breakpoint.\n");
+ error_sp->Flush();
}
- break;
- }
-}
-
-
-void
-ScriptInterpreterPython::ResetOutputFileHandle (FILE *fh)
-{
-}
-
-void
-ScriptInterpreterPython::SaveTerminalState (int fd)
-{
- // Python mucks with the terminal state of STDIN. If we can possibly avoid
- // this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state
- // on the input file handle.
- m_terminal_state.Save (fd, false);
-}
-
-void
-ScriptInterpreterPython::RestoreTerminalState ()
-{
- // Python mucks with the terminal state of STDIN. If we can possibly avoid
- // this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state
- // on the input file handle.
- m_terminal_state.Restore();
-}
-
-void
-ScriptInterpreterPython::LeaveSession ()
-{
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+ }
+ }
+ m_active_io_handler = eIOHandlerNone;
+ } break;
+ case eIOHandlerWatchpoint: {
+ WatchpointOptions *wp_options =
+ (WatchpointOptions *)io_handler.GetUserData();
+ auto data_ap = llvm::make_unique<WatchpointOptions::CommandData>();
+ data_ap->user_source.SplitIntoLines(data);
+
+ if (GenerateWatchpointCommandCallbackData(data_ap->user_source,
+ data_ap->script_source)) {
+ auto baton_sp =
+ std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_ap));
+ wp_options->SetCallback(
+ ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
+ } else if (!batch_mode) {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ if (error_sp) {
+ error_sp->Printf("Warning: No command attached to breakpoint.\n");
+ error_sp->Flush();
+ }
+ }
+ m_active_io_handler = eIOHandlerNone;
+ } break;
+ }
+}
+
+void ScriptInterpreterPython::ResetOutputFileHandle(FILE *fh) {}
+
+void ScriptInterpreterPython::SaveTerminalState(int fd) {
+ // Python mucks with the terminal state of STDIN. If we can possibly avoid
+ // this by setting the file handles up correctly prior to entering the
+ // interpreter we should. For now we save and restore the terminal state
+ // on the input file handle.
+ m_terminal_state.Save(fd, false);
+}
+
+void ScriptInterpreterPython::RestoreTerminalState() {
+ // Python mucks with the terminal state of STDIN. If we can possibly avoid
+ // this by setting the file handles up correctly prior to entering the
+ // interpreter we should. For now we save and restore the terminal state
+ // on the input file handle.
+ m_terminal_state.Restore();
+}
+
+void ScriptInterpreterPython::LeaveSession() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
+ if (log)
+ log->PutCString("ScriptInterpreterPython::LeaveSession()");
+
+ // checking that we have a valid thread state - since we use our own threading
+ // and locking
+ // in some (rare) cases during cleanup Python may end up believing we have no
+ // thread state
+ // and PyImport_AddModule will crash if that is the case - since that seems to
+ // only happen
+ // when destroying the SBDebugger, we can make do without clearing up stdout
+ // and stderr
+
+ // rdar://problem/11292882
+ // When the current thread state is NULL, PyThreadState_Get() issues a fatal
+ // error.
+ if (PyThreadState_GetDict()) {
+ PythonDictionary &sys_module_dict = GetSysModuleDictionary();
+ if (sys_module_dict.IsValid()) {
+ if (m_saved_stdin.IsValid()) {
+ sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin);
+ m_saved_stdin.Reset();
+ }
+ if (m_saved_stdout.IsValid()) {
+ sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout);
+ m_saved_stdout.Reset();
+ }
+ if (m_saved_stderr.IsValid()) {
+ sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr);
+ m_saved_stderr.Reset();
+ }
+ }
+ }
+
+ m_session_is_active = false;
+}
+
+bool ScriptInterpreterPython::SetStdHandle(File &file, const char *py_name,
+ PythonFile &save_file,
+ const char *mode) {
+ if (file.IsValid()) {
+ // Flush the file before giving it to python to avoid interleaved output.
+ file.Flush();
+
+ PythonDictionary &sys_module_dict = GetSysModuleDictionary();
+
+ save_file = sys_module_dict.GetItemForKey(PythonString(py_name))
+ .AsType<PythonFile>();
+
+ PythonFile new_file(file, mode);
+ sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
+ return true;
+ } else
+ save_file.Reset();
+ return false;
+}
+
+bool ScriptInterpreterPython::EnterSession(uint16_t on_entry_flags, FILE *in,
+ FILE *out, FILE *err) {
+ // If we have already entered the session, without having officially 'left'
+ // it, then there is no need to
+ // 'enter' it again.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
+ if (m_session_is_active) {
if (log)
- log->PutCString("ScriptInterpreterPython::LeaveSession()");
+ log->Printf(
+ "ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16
+ ") session is already active, returning without doing anything",
+ on_entry_flags);
+ return false;
+ }
+
+ if (log)
+ log->Printf(
+ "ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")",
+ on_entry_flags);
+
+ m_session_is_active = true;
+
+ StreamString run_string;
+
+ if (on_entry_flags & Locker::InitGlobals) {
+ run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
+ m_dictionary_name.c_str(),
+ GetCommandInterpreter().GetDebugger().GetID());
+ run_string.Printf(
+ "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
+ GetCommandInterpreter().GetDebugger().GetID());
+ run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()");
+ run_string.PutCString("; lldb.process = lldb.target.GetProcess()");
+ run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()");
+ run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
+ run_string.PutCString("')");
+ } else {
+ // If we aren't initing the globals, we should still always set the debugger
+ // (since that is always unique.)
+ run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
+ m_dictionary_name.c_str(),
+ GetCommandInterpreter().GetDebugger().GetID());
+ run_string.Printf(
+ "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
+ GetCommandInterpreter().GetDebugger().GetID());
+ run_string.PutCString("')");
+ }
+
+ PyRun_SimpleString(run_string.GetData());
+ run_string.Clear();
+
+ PythonDictionary &sys_module_dict = GetSysModuleDictionary();
+ if (sys_module_dict.IsValid()) {
+ File in_file(in, false);
+ File out_file(out, false);
+ File err_file(err, false);
+
+ lldb::StreamFileSP in_sp;
+ lldb::StreamFileSP out_sp;
+ lldb::StreamFileSP err_sp;
+ if (!in_file.IsValid() || !out_file.IsValid() || !err_file.IsValid())
+ m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid(in_sp, out_sp,
+ err_sp);
+
+ if (on_entry_flags & Locker::NoSTDIN) {
+ m_saved_stdin.Reset();
+ } else {
+ if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r")) {
+ if (in_sp)
+ SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r");
+ }
+ }
+
+ if (!SetStdHandle(out_file, "stdout", m_saved_stdout, "w")) {
+ if (out_sp)
+ SetStdHandle(out_sp->GetFile(), "stdout", m_saved_stdout, "w");
+ }
+
+ if (!SetStdHandle(err_file, "stderr", m_saved_stderr, "w")) {
+ if (err_sp)
+ SetStdHandle(err_sp->GetFile(), "stderr", m_saved_stderr, "w");
+ }
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ return true;
+}
+
+PythonObject &ScriptInterpreterPython::GetMainModule() {
+ if (!m_main_module.IsValid())
+ m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__"));
+ return m_main_module;
+}
+
+PythonDictionary &ScriptInterpreterPython::GetSessionDictionary() {
+ if (m_session_dict.IsValid())
+ return m_session_dict;
- // checking that we have a valid thread state - since we use our own threading and locking
- // in some (rare) cases during cleanup Python may end up believing we have no thread state
- // and PyImport_AddModule will crash if that is the case - since that seems to only happen
- // when destroying the SBDebugger, we can make do without clearing up stdout and stderr
+ PythonObject &main_module = GetMainModule();
+ if (!main_module.IsValid())
+ return m_session_dict;
- // rdar://problem/11292882
- // When the current thread state is NULL, PyThreadState_Get() issues a fatal error.
- if (PyThreadState_GetDict())
- {
- PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
- if (sys_module_dict.IsValid())
- {
- if (m_saved_stdin.IsValid())
- {
- sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin);
- m_saved_stdin.Reset ();
- }
- if (m_saved_stdout.IsValid())
- {
- sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout);
- m_saved_stdout.Reset ();
- }
- if (m_saved_stderr.IsValid())
- {
- sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr);
- m_saved_stderr.Reset ();
- }
- }
- }
+ PythonDictionary main_dict(PyRefType::Borrowed,
+ PyModule_GetDict(main_module.get()));
+ if (!main_dict.IsValid())
+ return m_session_dict;
- m_session_is_active = false;
+ PythonObject item = main_dict.GetItemForKey(PythonString(m_dictionary_name));
+ m_session_dict.Reset(PyRefType::Borrowed, item.get());
+ return m_session_dict;
}
-bool
-ScriptInterpreterPython::SetStdHandle(File &file, const char *py_name, PythonFile &save_file, const char *mode)
-{
- if (file.IsValid())
- {
- // Flush the file before giving it to python to avoid interleaved output.
- file.Flush();
-
- PythonDictionary &sys_module_dict = GetSysModuleDictionary();
-
- save_file = sys_module_dict.GetItemForKey(PythonString(py_name)).AsType<PythonFile>();
+PythonDictionary &ScriptInterpreterPython::GetSysModuleDictionary() {
+ if (m_sys_module_dict.IsValid())
+ return m_sys_module_dict;
- PythonFile new_file(file, mode);
- sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
- return true;
- }
- else
- save_file.Reset();
- return false;
+ PythonObject sys_module(PyRefType::Borrowed, PyImport_AddModule("sys"));
+ if (sys_module.IsValid())
+ m_sys_module_dict.Reset(PyRefType::Borrowed,
+ PyModule_GetDict(sys_module.get()));
+ return m_sys_module_dict;
}
-bool
-ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
- FILE *in,
- FILE *out,
- FILE *err)
-{
- // If we have already entered the session, without having officially 'left' it, then there is no need to
- // 'enter' it again.
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
- if (m_session_is_active)
- {
- if (log)
- log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ") session is already active, returning without doing anything", on_entry_flags);
- return false;
- }
-
- if (log)
- log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")", on_entry_flags);
-
-
- m_session_is_active = true;
-
- StreamString run_string;
-
- if (on_entry_flags & Locker::InitGlobals)
- {
- run_string.Printf ( "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
- run_string.Printf ( "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
- run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
- run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
- run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
- run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
- run_string.PutCString ("')");
- }
- else
- {
- // If we aren't initing the globals, we should still always set the debugger (since that is always unique.)
- run_string.Printf ( "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
- run_string.Printf ( "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
- run_string.PutCString ("')");
- }
-
- PyRun_SimpleString (run_string.GetData());
- run_string.Clear();
-
- PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
- if (sys_module_dict.IsValid())
- {
- File in_file(in, false);
- File out_file(out, false);
- File err_file(err, false);
-
- lldb::StreamFileSP in_sp;
- lldb::StreamFileSP out_sp;
- lldb::StreamFileSP err_sp;
- if (!in_file.IsValid() || !out_file.IsValid() || !err_file.IsValid())
- m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid (in_sp, out_sp, err_sp);
-
-
- if (on_entry_flags & Locker::NoSTDIN)
- {
- m_saved_stdin.Reset();
- }
- else
- {
- if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r"))
- {
- if (in_sp)
- SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r");
- }
- }
+static std::string GenerateUniqueName(const char *base_name_wanted,
+ uint32_t &functions_counter,
+ const void *name_token = nullptr) {
+ StreamString sstr;
- if (!SetStdHandle(out_file, "stdout", m_saved_stdout, "w"))
- {
- if (out_sp)
- SetStdHandle(out_sp->GetFile(), "stdout", m_saved_stdout, "w");
- }
+ if (!base_name_wanted)
+ return std::string();
- if (!SetStdHandle(err_file, "stderr", m_saved_stderr, "w"))
- {
- if (err_sp)
- SetStdHandle(err_sp->GetFile(), "stderr", m_saved_stderr, "w");
- }
- }
+ if (!name_token)
+ sstr.Printf("%s_%d", base_name_wanted, functions_counter++);
+ else
+ sstr.Printf("%s_%p", base_name_wanted, name_token);
- if (PyErr_Occurred())
- PyErr_Clear ();
-
- return true;
-}
-
-PythonObject &
-ScriptInterpreterPython::GetMainModule()
-{
- if (!m_main_module.IsValid())
- m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__"));
- return m_main_module;
+ return sstr.GetString();
}
-PythonDictionary &
-ScriptInterpreterPython::GetSessionDictionary ()
-{
- if (m_session_dict.IsValid())
- return m_session_dict;
+bool ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects() {
+ if (m_run_one_line_function.IsValid())
+ return true;
- PythonObject &main_module = GetMainModule();
- if (!main_module.IsValid())
- return m_session_dict;
+ PythonObject module(PyRefType::Borrowed,
+ PyImport_AddModule("lldb.embedded_interpreter"));
+ if (!module.IsValid())
+ return false;
- PythonDictionary main_dict(PyRefType::Borrowed, PyModule_GetDict(main_module.get()));
- if (!main_dict.IsValid())
- return m_session_dict;
+ PythonDictionary module_dict(PyRefType::Borrowed,
+ PyModule_GetDict(module.get()));
+ if (!module_dict.IsValid())
+ return false;
- PythonObject item = main_dict.GetItemForKey(PythonString(m_dictionary_name));
- m_session_dict.Reset(PyRefType::Borrowed, item.get());
- return m_session_dict;
+ m_run_one_line_function =
+ module_dict.GetItemForKey(PythonString("run_one_line"));
+ m_run_one_line_str_global =
+ module_dict.GetItemForKey(PythonString("g_run_one_line_str"));
+ return m_run_one_line_function.IsValid();
}
-PythonDictionary &
-ScriptInterpreterPython::GetSysModuleDictionary ()
-{
- if (m_sys_module_dict.IsValid())
- return m_sys_module_dict;
-
- PythonObject sys_module(PyRefType::Borrowed, PyImport_AddModule("sys"));
- if (sys_module.IsValid())
- m_sys_module_dict.Reset(PyRefType::Borrowed, PyModule_GetDict(sys_module.get()));
- return m_sys_module_dict;
+static void ReadThreadBytesReceived(void *baton, const void *src,
+ size_t src_len) {
+ if (src && src_len) {
+ Stream *strm = (Stream *)baton;
+ strm->Write(src, src_len);
+ strm->Flush();
+ }
}
-static std::string
-GenerateUniqueName (const char* base_name_wanted,
- uint32_t& functions_counter,
- const void* name_token = nullptr)
-{
- StreamString sstr;
-
- if (!base_name_wanted)
- return std::string();
-
- if (!name_token)
- sstr.Printf ("%s_%d", base_name_wanted, functions_counter++);
- else
- sstr.Printf ("%s_%p", base_name_wanted, name_token);
-
- return sstr.GetString();
-}
-
-bool
-ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects ()
-{
- if (m_run_one_line_function.IsValid())
- return true;
-
- PythonObject module(PyRefType::Borrowed, PyImport_AddModule ("lldb.embedded_interpreter"));
- if (!module.IsValid())
- return false;
-
- PythonDictionary module_dict(PyRefType::Borrowed, PyModule_GetDict(module.get()));
- if (!module_dict.IsValid())
- return false;
-
- m_run_one_line_function = module_dict.GetItemForKey(PythonString("run_one_line"));
- m_run_one_line_str_global = module_dict.GetItemForKey(PythonString("g_run_one_line_str"));
- return m_run_one_line_function.IsValid();
-}
-
-static void
-ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
-{
- if (src && src_len)
- {
- Stream *strm = (Stream *)baton;
- strm->Write(src, src_len);
- strm->Flush();
- }
-}
+bool ScriptInterpreterPython::ExecuteOneLine(
+ const char *command, CommandReturnObject *result,
+ const ExecuteScriptOptions &options) {
+ if (!m_valid_session)
+ return false;
-bool
-ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, const ExecuteScriptOptions &options)
-{
- if (!m_valid_session)
- return false;
-
- if (command && command[0])
- {
- // We want to call run_one_line, passing in the dictionary and the command string. We cannot do this through
- // PyRun_SimpleString here because the command string may contain escaped characters, and putting it inside
- // another string to pass to PyRun_SimpleString messes up the escaping. So we use the following more complicated
- // method to pass the command string directly down to Python.
- Debugger &debugger = m_interpreter.GetDebugger();
-
- StreamFileSP input_file_sp;
- StreamFileSP output_file_sp;
- StreamFileSP error_file_sp;
- Communication output_comm ("lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
- bool join_read_thread = false;
- if (options.GetEnableIO())
- {
- if (result)
- {
- input_file_sp = debugger.GetInputFile();
- // Set output to a temporary file so we can forward the results on to the result object
-
- Pipe pipe;
- Error pipe_result = pipe.CreateNew(false);
- if (pipe_result.Success())
- {
+ if (command && command[0]) {
+ // We want to call run_one_line, passing in the dictionary and the command
+ // string. We cannot do this through
+ // PyRun_SimpleString here because the command string may contain escaped
+ // characters, and putting it inside
+ // another string to pass to PyRun_SimpleString messes up the escaping. So
+ // we use the following more complicated
+ // method to pass the command string directly down to Python.
+ Debugger &debugger = m_interpreter.GetDebugger();
+
+ StreamFileSP input_file_sp;
+ StreamFileSP output_file_sp;
+ StreamFileSP error_file_sp;
+ Communication output_comm(
+ "lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
+ bool join_read_thread = false;
+ if (options.GetEnableIO()) {
+ if (result) {
+ input_file_sp = debugger.GetInputFile();
+ // Set output to a temporary file so we can forward the results on to
+ // the result object
+
+ Pipe pipe;
+ Error pipe_result = pipe.CreateNew(false);
+ if (pipe_result.Success()) {
#if defined(_WIN32)
- lldb::file_t read_file = pipe.GetReadNativeHandle();
- pipe.ReleaseReadFileDescriptor();
- std::unique_ptr<ConnectionGenericFile> conn_ap(new ConnectionGenericFile(read_file, true));
+ lldb::file_t read_file = pipe.GetReadNativeHandle();
+ pipe.ReleaseReadFileDescriptor();
+ std::unique_ptr<ConnectionGenericFile> conn_ap(
+ new ConnectionGenericFile(read_file, true));
#else
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true));
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(),
+ true));
#endif
- if (conn_ap->IsConnected())
- {
- output_comm.SetConnection(conn_ap.release());
- output_comm.SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived, &result->GetOutputStream());
- output_comm.StartReadThread();
- join_read_thread = true;
- FILE *outfile_handle = fdopen (pipe.ReleaseWriteFileDescriptor(), "w");
- output_file_sp.reset(new StreamFile(outfile_handle, true));
- error_file_sp = output_file_sp;
- if (outfile_handle)
- ::setbuf (outfile_handle, nullptr);
-
- result->SetImmediateOutputFile(debugger.GetOutputFile()->GetFile().GetStream());
- result->SetImmediateErrorFile(debugger.GetErrorFile()->GetFile().GetStream());
- }
- }
- }
- if (!input_file_sp || !output_file_sp || !error_file_sp)
- debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp, error_file_sp);
- }
- else
- {
- input_file_sp.reset (new StreamFile ());
- input_file_sp->GetFile().Open(FileSystem::DEV_NULL, File::eOpenOptionRead);
- output_file_sp.reset (new StreamFile ());
- output_file_sp->GetFile().Open(FileSystem::DEV_NULL, File::eOpenOptionWrite);
+ if (conn_ap->IsConnected()) {
+ output_comm.SetConnection(conn_ap.release());
+ output_comm.SetReadThreadBytesReceivedCallback(
+ ReadThreadBytesReceived, &result->GetOutputStream());
+ output_comm.StartReadThread();
+ join_read_thread = true;
+ FILE *outfile_handle =
+ fdopen(pipe.ReleaseWriteFileDescriptor(), "w");
+ output_file_sp.reset(new StreamFile(outfile_handle, true));
error_file_sp = output_file_sp;
+ if (outfile_handle)
+ ::setbuf(outfile_handle, nullptr);
+
+ result->SetImmediateOutputFile(
+ debugger.GetOutputFile()->GetFile().GetStream());
+ result->SetImmediateErrorFile(
+ debugger.GetErrorFile()->GetFile().GetStream());
+ }
}
-
- FILE *in_file = input_file_sp->GetFile().GetStream();
- FILE *out_file = output_file_sp->GetFile().GetStream();
- FILE *err_file = error_file_sp->GetFile().GetStream();
- bool success = false;
- {
- // WARNING! It's imperative that this RAII scope be as tight as possible. In particular, the
- // scope must end *before* we try to join the read thread. The reason for this is that a
- // pre-requisite for joining the read thread is that we close the write handle (to break the
- // pipe and cause it to wake up and exit). But acquiring the GIL as below will redirect Python's
- // stdio to use this same handle. If we close the handle while Python is still using it, bad
- // things will happen.
- Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock |
- ScriptInterpreterPython::Locker::InitSession |
- (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) |
- ((result && result->GetInteractive()) ? 0: Locker::NoSTDIN),
- ScriptInterpreterPython::Locker::FreeAcquiredLock |
- ScriptInterpreterPython::Locker::TearDownSession,
- in_file,
- out_file,
- err_file);
-
- // Find the correct script interpreter dictionary in the main module.
- PythonDictionary &session_dict = GetSessionDictionary ();
- if (session_dict.IsValid())
- {
- if (GetEmbeddedInterpreterModuleObjects ())
- {
- if (PyCallable_Check(m_run_one_line_function.get()))
- {
- PythonObject pargs(PyRefType::Owned, Py_BuildValue("(Os)", session_dict.get(), command));
- if (pargs.IsValid())
- {
- PythonObject return_value(PyRefType::Owned,
- PyObject_CallObject(m_run_one_line_function.get(), pargs.get()));
- if (return_value.IsValid())
- success = true;
- else if (options.GetMaskoutErrors() && PyErr_Occurred ())
- {
- PyErr_Print();
- PyErr_Clear();
- }
- }
- }
- }
+ }
+ if (!input_file_sp || !output_file_sp || !error_file_sp)
+ debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp,
+ error_file_sp);
+ } else {
+ input_file_sp.reset(new StreamFile());
+ input_file_sp->GetFile().Open(FileSystem::DEV_NULL,
+ File::eOpenOptionRead);
+ output_file_sp.reset(new StreamFile());
+ output_file_sp->GetFile().Open(FileSystem::DEV_NULL,
+ File::eOpenOptionWrite);
+ error_file_sp = output_file_sp;
+ }
+
+ FILE *in_file = input_file_sp->GetFile().GetStream();
+ FILE *out_file = output_file_sp->GetFile().GetStream();
+ FILE *err_file = error_file_sp->GetFile().GetStream();
+ bool success = false;
+ {
+ // WARNING! It's imperative that this RAII scope be as tight as possible.
+ // In particular, the
+ // scope must end *before* we try to join the read thread. The reason for
+ // this is that a
+ // pre-requisite for joining the read thread is that we close the write
+ // handle (to break the
+ // pipe and cause it to wake up and exit). But acquiring the GIL as below
+ // will redirect Python's
+ // stdio to use this same handle. If we close the handle while Python is
+ // still using it, bad
+ // things will happen.
+ Locker locker(
+ this,
+ ScriptInterpreterPython::Locker::AcquireLock |
+ ScriptInterpreterPython::Locker::InitSession |
+ (options.GetSetLLDBGlobals()
+ ? ScriptInterpreterPython::Locker::InitGlobals
+ : 0) |
+ ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
+ ScriptInterpreterPython::Locker::FreeAcquiredLock |
+ ScriptInterpreterPython::Locker::TearDownSession,
+ in_file, out_file, err_file);
+
+ // Find the correct script interpreter dictionary in the main module.
+ PythonDictionary &session_dict = GetSessionDictionary();
+ if (session_dict.IsValid()) {
+ if (GetEmbeddedInterpreterModuleObjects()) {
+ if (PyCallable_Check(m_run_one_line_function.get())) {
+ PythonObject pargs(
+ PyRefType::Owned,
+ Py_BuildValue("(Os)", session_dict.get(), command));
+ if (pargs.IsValid()) {
+ PythonObject return_value(
+ PyRefType::Owned,
+ PyObject_CallObject(m_run_one_line_function.get(),
+ pargs.get()));
+ if (return_value.IsValid())
+ success = true;
+ else if (options.GetMaskoutErrors() && PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
}
-
- // Flush our output and error file handles
- ::fflush (out_file);
- if (out_file != err_file)
- ::fflush (err_file);
+ }
}
-
- if (join_read_thread)
- {
- // Close the write end of the pipe since we are done with our
- // one line script. This should cause the read thread that
- // output_comm is using to exit
- output_file_sp->GetFile().Close();
- // The close above should cause this thread to exit when it gets
- // to the end of file, so let it get all its data
- output_comm.JoinReadThread();
- // Now we can close the read end of the pipe
- output_comm.Disconnect();
- }
-
-
- if (success)
- return true;
-
- // The one-liner failed. Append the error message.
- if (result)
- result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
- return false;
+ }
+
+ // Flush our output and error file handles
+ ::fflush(out_file);
+ if (out_file != err_file)
+ ::fflush(err_file);
}
+ if (join_read_thread) {
+ // Close the write end of the pipe since we are done with our
+ // one line script. This should cause the read thread that
+ // output_comm is using to exit
+ output_file_sp->GetFile().Close();
+ // The close above should cause this thread to exit when it gets
+ // to the end of file, so let it get all its data
+ output_comm.JoinReadThread();
+ // Now we can close the read end of the pipe
+ output_comm.Disconnect();
+ }
+
+ if (success)
+ return true;
+
+ // The one-liner failed. Append the error message.
if (result)
- result->AppendError ("empty command passed to python\n");
+ result->AppendErrorWithFormat(
+ "python failed attempting to evaluate '%s'\n", command);
return false;
-}
+ }
+ if (result)
+ result->AppendError("empty command passed to python\n");
+ return false;
+}
-class IOHandlerPythonInterpreter :
- public IOHandler
-{
+class IOHandlerPythonInterpreter : public IOHandler {
public:
-
- IOHandlerPythonInterpreter (Debugger &debugger,
- ScriptInterpreterPython *python) :
- IOHandler (debugger, IOHandler::Type::PythonInterpreter),
- m_python(python)
- {
-
- }
-
- ~IOHandlerPythonInterpreter() override
- {
-
- }
-
- ConstString
- GetControlSequence (char ch) override
- {
- if (ch == 'd')
- return ConstString("quit()\n");
- return ConstString();
- }
-
- void
- Run () override
- {
- if (m_python)
- {
- int stdin_fd = GetInputFD();
- if (stdin_fd >= 0)
- {
- Terminal terminal(stdin_fd);
- TerminalState terminal_state;
- const bool is_a_tty = terminal.IsATerminal();
-
- if (is_a_tty)
- {
- terminal_state.Save (stdin_fd, false);
- terminal.SetCanonical(false);
- terminal.SetEcho(true);
- }
-
- ScriptInterpreterPython::Locker locker (m_python,
- ScriptInterpreterPython::Locker::AcquireLock |
- ScriptInterpreterPython::Locker::InitSession |
- ScriptInterpreterPython::Locker::InitGlobals,
- ScriptInterpreterPython::Locker::FreeAcquiredLock |
- ScriptInterpreterPython::Locker::TearDownSession);
-
- // The following call drops into the embedded interpreter loop and stays there until the
- // user chooses to exit from the Python interpreter.
- // This embedded interpreter will, as any Python code that performs I/O, unlock the GIL before
- // a system call that can hang, and lock it when the syscall has returned.
-
- // We need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and
- // PyGILState_Release (using the Locker above). This is because Python has a global lock which must be held whenever we want
- // to touch any Python objects. Otherwise, if the user calls Python code, the interpreter state will be off,
- // and things could hang (it's happened before).
-
- StreamString run_string;
- run_string.Printf ("run_python_interpreter (%s)", m_python->GetDictionaryName ());
- PyRun_SimpleString (run_string.GetData());
-
- if (is_a_tty)
- terminal_state.Restore();
- }
+ IOHandlerPythonInterpreter(Debugger &debugger,
+ ScriptInterpreterPython *python)
+ : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
+ m_python(python) {}
+
+ ~IOHandlerPythonInterpreter() override {}
+
+ ConstString GetControlSequence(char ch) override {
+ if (ch == 'd')
+ return ConstString("quit()\n");
+ return ConstString();
+ }
+
+ void Run() override {
+ if (m_python) {
+ int stdin_fd = GetInputFD();
+ if (stdin_fd >= 0) {
+ Terminal terminal(stdin_fd);
+ TerminalState terminal_state;
+ const bool is_a_tty = terminal.IsATerminal();
+
+ if (is_a_tty) {
+ terminal_state.Save(stdin_fd, false);
+ terminal.SetCanonical(false);
+ terminal.SetEcho(true);
}
- SetIsDone(true);
- }
- void
- Cancel () override
- {
-
- }
+ ScriptInterpreterPython::Locker locker(
+ m_python, ScriptInterpreterPython::Locker::AcquireLock |
+ ScriptInterpreterPython::Locker::InitSession |
+ ScriptInterpreterPython::Locker::InitGlobals,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock |
+ ScriptInterpreterPython::Locker::TearDownSession);
- bool
- Interrupt () override
- {
- return m_python->Interrupt();
- }
-
- void
- GotEOF() override
- {
-
- }
-protected:
- ScriptInterpreterPython *m_python;
-};
+ // The following call drops into the embedded interpreter loop and stays
+ // there until the
+ // user chooses to exit from the Python interpreter.
+ // This embedded interpreter will, as any Python code that performs I/O,
+ // unlock the GIL before
+ // a system call that can hang, and lock it when the syscall has
+ // returned.
+ // We need to surround the call to the embedded interpreter with calls
+ // to PyGILState_Ensure and
+ // PyGILState_Release (using the Locker above). This is because Python
+ // has a global lock which must be held whenever we want
+ // to touch any Python objects. Otherwise, if the user calls Python
+ // code, the interpreter state will be off,
+ // and things could hang (it's happened before).
-void
-ScriptInterpreterPython::ExecuteInterpreterLoop ()
-{
- Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+ StreamString run_string;
+ run_string.Printf("run_python_interpreter (%s)",
+ m_python->GetDictionaryName());
+ PyRun_SimpleString(run_string.GetData());
- Debugger &debugger = GetCommandInterpreter().GetDebugger();
+ if (is_a_tty)
+ terminal_state.Restore();
+ }
+ }
+ SetIsDone(true);
+ }
- // At the moment, the only time the debugger does not have an input file handle is when this is called
- // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
- // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
- // do it.
+ void Cancel() override {}
- if (!debugger.GetInputFile()->GetFile().IsValid())
- return;
+ bool Interrupt() override { return m_python->Interrupt(); }
- IOHandlerSP io_handler_sp (new IOHandlerPythonInterpreter (debugger, this));
- if (io_handler_sp)
- {
- debugger.PushIOHandler(io_handler_sp);
- }
-}
+ void GotEOF() override {}
-bool
-ScriptInterpreterPython::Interrupt()
-{
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+protected:
+ ScriptInterpreterPython *m_python;
+};
- if (IsExecutingPython())
- {
- PyThreadState *state = PyThreadState_GET();
- if (!state)
- state = GetThreadState();
- if (state)
- {
- long tid = state->thread_id;
- PyThreadState_Swap(state);
- int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
- if (log)
- log->Printf("ScriptInterpreterPython::Interrupt() sending PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid, num_threads);
- return true;
- }
- }
- if (log)
- log->Printf("ScriptInterpreterPython::Interrupt() python code not running, can't interrupt");
- return false;
+void ScriptInterpreterPython::ExecuteInterpreterLoop() {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION);
-}
-bool
-ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
- ScriptInterpreter::ScriptReturnType return_type,
- void *ret_value,
- const ExecuteScriptOptions &options)
-{
-
- Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) | Locker::NoSTDIN,
- ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
-
- PythonObject py_return;
- PythonObject &main_module = GetMainModule();
- PythonDictionary globals(PyRefType::Borrowed, PyModule_GetDict(main_module.get()));
- PythonObject py_error;
- bool ret_success = false;
- int success;
-
- PythonDictionary locals = GetSessionDictionary ();
-
- if (!locals.IsValid())
- {
- locals.Reset(PyRefType::Owned, PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
- }
-
- if (!locals.IsValid())
- locals = globals;
-
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
-
- if (in_string != nullptr)
- {
- { // scope for PythonInputReaderManager
- //PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
- py_return.Reset(PyRefType::Owned, PyRun_String(in_string, Py_eval_input, globals.get(), locals.get()));
- if (!py_return.IsValid())
- {
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
-
- py_return.Reset(PyRefType::Owned, PyRun_String(in_string, Py_single_input, globals.get(), locals.get()));
- }
- }
+ Debugger &debugger = GetCommandInterpreter().GetDebugger();
- if (py_return.IsValid())
- {
- switch (return_type)
- {
- case eScriptReturnTypeCharPtr: // "char *"
- {
- const char format[3] = "s#";
- success = PyArg_Parse (py_return.get(), format, (char **) ret_value);
- break;
- }
- case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return == Py_None
- {
- const char format[3] = "z";
- success = PyArg_Parse (py_return.get(), format, (char **) ret_value);
- break;
- }
- case eScriptReturnTypeBool:
- {
- const char format[2] = "b";
- success = PyArg_Parse (py_return.get(), format, (bool *) ret_value);
- break;
- }
- case eScriptReturnTypeShortInt:
- {
- const char format[2] = "h";
- success = PyArg_Parse (py_return.get(), format, (short *) ret_value);
- break;
- }
- case eScriptReturnTypeShortIntUnsigned:
- {
- const char format[2] = "H";
- success = PyArg_Parse (py_return.get(), format, (unsigned short *) ret_value);
- break;
- }
- case eScriptReturnTypeInt:
- {
- const char format[2] = "i";
- success = PyArg_Parse (py_return.get(), format, (int *) ret_value);
- break;
- }
- case eScriptReturnTypeIntUnsigned:
- {
- const char format[2] = "I";
- success = PyArg_Parse (py_return.get(), format, (unsigned int *) ret_value);
- break;
- }
- case eScriptReturnTypeLongInt:
- {
- const char format[2] = "l";
- success = PyArg_Parse (py_return.get(), format, (long *) ret_value);
- break;
- }
- case eScriptReturnTypeLongIntUnsigned:
- {
- const char format[2] = "k";
- success = PyArg_Parse (py_return.get(), format, (unsigned long *) ret_value);
- break;
- }
- case eScriptReturnTypeLongLong:
- {
- const char format[2] = "L";
- success = PyArg_Parse (py_return.get(), format, (long long *) ret_value);
- break;
- }
- case eScriptReturnTypeLongLongUnsigned:
- {
- const char format[2] = "K";
- success = PyArg_Parse (py_return.get(), format, (unsigned long long *) ret_value);
- break;
- }
- case eScriptReturnTypeFloat:
- {
- const char format[2] = "f";
- success = PyArg_Parse (py_return.get(), format, (float *) ret_value);
- break;
- }
- case eScriptReturnTypeDouble:
- {
- const char format[2] = "d";
- success = PyArg_Parse (py_return.get(), format, (double *) ret_value);
- break;
- }
- case eScriptReturnTypeChar:
- {
- const char format[2] = "c";
- success = PyArg_Parse (py_return.get(), format, (char *) ret_value);
- break;
- }
- case eScriptReturnTypeOpaqueObject:
- {
- success = true;
- PyObject *saved_value = py_return.get();
- Py_XINCREF(saved_value);
- *((PyObject **)ret_value) = saved_value;
- break;
- }
- }
+ // At the moment, the only time the debugger does not have an input file
+ // handle is when this is called
+ // directly from Python, in which case it is both dangerous and unnecessary
+ // (not to mention confusing) to
+ // try to embed a running interpreter loop inside the already running Python
+ // interpreter loop, so we won't
+ // do it.
- if (success)
- ret_success = true;
- else
- ret_success = false;
- }
- }
+ if (!debugger.GetInputFile()->GetFile().IsValid())
+ return;
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- {
- ret_success = false;
- if (options.GetMaskoutErrors())
+ IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
+ if (io_handler_sp) {
+ debugger.PushIOHandler(io_handler_sp);
+ }
+}
+
+bool ScriptInterpreterPython::Interrupt() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
+
+ if (IsExecutingPython()) {
+ PyThreadState *state = PyThreadState_GET();
+ if (!state)
+ state = GetThreadState();
+ if (state) {
+ long tid = state->thread_id;
+ PyThreadState_Swap(state);
+ int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
+ if (log)
+ log->Printf("ScriptInterpreterPython::Interrupt() sending "
+ "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
+ tid, num_threads);
+ return true;
+ }
+ }
+ if (log)
+ log->Printf("ScriptInterpreterPython::Interrupt() python code not running, "
+ "can't interrupt");
+ return false;
+}
+bool ScriptInterpreterPython::ExecuteOneLineWithReturn(
+ const char *in_string, ScriptInterpreter::ScriptReturnType return_type,
+ void *ret_value, const ExecuteScriptOptions &options) {
+
+ Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock |
+ ScriptInterpreterPython::Locker::InitSession |
+ (options.GetSetLLDBGlobals()
+ ? ScriptInterpreterPython::Locker::InitGlobals
+ : 0) |
+ Locker::NoSTDIN,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock |
+ ScriptInterpreterPython::Locker::TearDownSession);
+
+ PythonObject py_return;
+ PythonObject &main_module = GetMainModule();
+ PythonDictionary globals(PyRefType::Borrowed,
+ PyModule_GetDict(main_module.get()));
+ PythonObject py_error;
+ bool ret_success = false;
+ int success;
+
+ PythonDictionary locals = GetSessionDictionary();
+
+ if (!locals.IsValid()) {
+ locals.Reset(
+ PyRefType::Owned,
+ PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
+ }
+
+ if (!locals.IsValid())
+ locals = globals;
+
+ py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
+ if (py_error.IsValid())
+ PyErr_Clear();
+
+ if (in_string != nullptr) {
+ { // scope for PythonInputReaderManager
+ // PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
+ py_return.Reset(
+ PyRefType::Owned,
+ PyRun_String(in_string, Py_eval_input, globals.get(), locals.get()));
+ if (!py_return.IsValid()) {
+ py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
+ if (py_error.IsValid())
+ PyErr_Clear();
+
+ py_return.Reset(PyRefType::Owned,
+ PyRun_String(in_string, Py_single_input, globals.get(),
+ locals.get()));
+ }
+ }
+
+ if (py_return.IsValid()) {
+ switch (return_type) {
+ case eScriptReturnTypeCharPtr: // "char *"
+ {
+ const char format[3] = "s#";
+ success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ break;
+ }
+ case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
+ // Py_None
{
- if (PyErr_GivenExceptionMatches (py_error.get(), PyExc_SyntaxError))
- PyErr_Print ();
- PyErr_Clear();
+ const char format[3] = "z";
+ success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ break;
}
- }
-
- return ret_success;
-}
-
-Error
-ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options)
-{
- Error error;
-
- Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) | Locker::NoSTDIN,
- ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
-
- PythonObject return_value;
- PythonObject &main_module = GetMainModule();
- PythonDictionary globals(PyRefType::Borrowed, PyModule_GetDict(main_module.get()));
- PythonObject py_error;
+ case eScriptReturnTypeBool: {
+ const char format[2] = "b";
+ success = PyArg_Parse(py_return.get(), format, (bool *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeShortInt: {
+ const char format[2] = "h";
+ success = PyArg_Parse(py_return.get(), format, (short *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeShortIntUnsigned: {
+ const char format[2] = "H";
+ success =
+ PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeInt: {
+ const char format[2] = "i";
+ success = PyArg_Parse(py_return.get(), format, (int *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeIntUnsigned: {
+ const char format[2] = "I";
+ success =
+ PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongInt: {
+ const char format[2] = "l";
+ success = PyArg_Parse(py_return.get(), format, (long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongIntUnsigned: {
+ const char format[2] = "k";
+ success =
+ PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongLong: {
+ const char format[2] = "L";
+ success = PyArg_Parse(py_return.get(), format, (long long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeLongLongUnsigned: {
+ const char format[2] = "K";
+ success = PyArg_Parse(py_return.get(), format,
+ (unsigned long long *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeFloat: {
+ const char format[2] = "f";
+ success = PyArg_Parse(py_return.get(), format, (float *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeDouble: {
+ const char format[2] = "d";
+ success = PyArg_Parse(py_return.get(), format, (double *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeChar: {
+ const char format[2] = "c";
+ success = PyArg_Parse(py_return.get(), format, (char *)ret_value);
+ break;
+ }
+ case eScriptReturnTypeOpaqueObject: {
+ success = true;
+ PyObject *saved_value = py_return.get();
+ Py_XINCREF(saved_value);
+ *((PyObject **)ret_value) = saved_value;
+ break;
+ }
+ }
- PythonDictionary locals = GetSessionDictionary();
+ if (success)
+ ret_success = true;
+ else
+ ret_success = false;
+ }
+ }
- if (!locals.IsValid())
- locals.Reset(PyRefType::Owned, PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
+ py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
+ if (py_error.IsValid()) {
+ ret_success = false;
+ if (options.GetMaskoutErrors()) {
+ if (PyErr_GivenExceptionMatches(py_error.get(), PyExc_SyntaxError))
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
- if (!locals.IsValid())
- locals = globals;
+ return ret_success;
+}
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
-
- if (in_string != nullptr)
- {
- PythonObject code_object;
- code_object.Reset(PyRefType::Owned, Py_CompileString(in_string, "temp.py", Py_file_input));
+Error ScriptInterpreterPython::ExecuteMultipleLines(
+ const char *in_string, const ExecuteScriptOptions &options) {
+ Error error;
- if (code_object.IsValid())
- {
- // In Python 2.x, PyEval_EvalCode takes a PyCodeObject, but in Python 3.x, it takes
- // a PyObject. They are convertible (hence the function PyCode_Check(PyObject*), so
- // we have to do the cast for Python 2.x
+ Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock |
+ ScriptInterpreterPython::Locker::InitSession |
+ (options.GetSetLLDBGlobals()
+ ? ScriptInterpreterPython::Locker::InitGlobals
+ : 0) |
+ Locker::NoSTDIN,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock |
+ ScriptInterpreterPython::Locker::TearDownSession);
+
+ PythonObject return_value;
+ PythonObject &main_module = GetMainModule();
+ PythonDictionary globals(PyRefType::Borrowed,
+ PyModule_GetDict(main_module.get()));
+ PythonObject py_error;
+
+ PythonDictionary locals = GetSessionDictionary();
+
+ if (!locals.IsValid())
+ locals.Reset(
+ PyRefType::Owned,
+ PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
+
+ if (!locals.IsValid())
+ locals = globals;
+
+ py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
+ if (py_error.IsValid())
+ PyErr_Clear();
+
+ if (in_string != nullptr) {
+ PythonObject code_object;
+ code_object.Reset(PyRefType::Owned,
+ Py_CompileString(in_string, "temp.py", Py_file_input));
+
+ if (code_object.IsValid()) {
+// In Python 2.x, PyEval_EvalCode takes a PyCodeObject, but in Python 3.x, it
+// takes
+// a PyObject. They are convertible (hence the function
+// PyCode_Check(PyObject*), so
+// we have to do the cast for Python 2.x
#if PY_MAJOR_VERSION >= 3
- PyObject *py_code_obj = code_object.get();
+ PyObject *py_code_obj = code_object.get();
#else
- PyCodeObject *py_code_obj = reinterpret_cast<PyCodeObject *>(code_object.get());
+ PyCodeObject *py_code_obj =
+ reinterpret_cast<PyCodeObject *>(code_object.get());
#endif
- return_value.Reset(PyRefType::Owned, PyEval_EvalCode(py_code_obj, globals.get(), locals.get()));
- }
+ return_value.Reset(
+ PyRefType::Owned,
+ PyEval_EvalCode(py_code_obj, globals.get(), locals.get()));
}
+ }
- PythonExceptionState exception_state(!options.GetMaskoutErrors());
- if (exception_state.IsError())
- error.SetErrorString(exception_state.Format().c_str());
+ PythonExceptionState exception_state(!options.GetMaskoutErrors());
+ if (exception_state.IsError())
+ error.SetErrorString(exception_state.Format().c_str());
- return error;
+ return error;
}
+void ScriptInterpreterPython::CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) {
+ m_active_io_handler = eIOHandlerBreakpoint;
+ m_interpreter.GetPythonCommandsFromIOHandler(" ", *this, true,
+ &bp_options_vec);
+}
-void
-ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
- CommandReturnObject &result)
-{
- m_active_io_handler = eIOHandlerBreakpoint;
- m_interpreter.GetPythonCommandsFromIOHandler (" ", *this, true, &bp_options_vec);
+void ScriptInterpreterPython::CollectDataForWatchpointCommandCallback(
+ WatchpointOptions *wp_options, CommandReturnObject &result) {
+ m_active_io_handler = eIOHandlerWatchpoint;
+ m_interpreter.GetPythonCommandsFromIOHandler(" ", *this, true, wp_options);
}
-void
-ScriptInterpreterPython::CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
- CommandReturnObject &result)
-{
- m_active_io_handler = eIOHandlerWatchpoint;
- m_interpreter.GetPythonCommandsFromIOHandler (" ", *this, true, wp_options);
+void ScriptInterpreterPython::SetBreakpointCommandCallbackFunction(
+ BreakpointOptions *bp_options, const char *function_name) {
+ // For now just cons up a oneliner that calls the provided function.
+ std::string oneliner("return ");
+ oneliner += function_name;
+ oneliner += "(frame, bp_loc, internal_dict)";
+ m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback(
+ bp_options, oneliner.c_str());
}
-void
-ScriptInterpreterPython::SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
- const char *function_name)
-{
- // For now just cons up a oneliner that calls the provided function.
- std::string oneliner("return ");
- oneliner += function_name;
- oneliner += "(frame, bp_loc, internal_dict)";
- m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
- oneliner.c_str());
+Error ScriptInterpreterPython::SetBreakpointCommandCallback(
+ BreakpointOptions *bp_options,
+ std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
+ Error error;
+ error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
+ cmd_data_up->script_source);
+ if (error.Fail()) {
+ return error;
+ }
+ auto baton_sp =
+ std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
+ bp_options->SetCallback(ScriptInterpreterPython::BreakpointCallbackFunction,
+ baton_sp);
+ return error;
}
// Set a Python one-liner as the callback for the breakpoint.
-Error
-ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
- const char *command_body_text)
-{
- std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
-
- // Split the command_body_text into lines, and pass that to GenerateBreakpointCommandCallbackData. That will
- // wrap the body in an auto-generated function, and return the function name in script_source. That is what
- // the callback will actually invoke.
-
- data_ap->user_source.SplitIntoLines(command_body_text);
- Error error = GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source);
- if (error.Success())
- {
- BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
- bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
- return error;
- }
- else
- return error;
+Error ScriptInterpreterPython::SetBreakpointCommandCallback(
+ BreakpointOptions *bp_options, const char *command_body_text) {
+ auto data_ap = llvm::make_unique<CommandDataPython>();
+
+ // Split the command_body_text into lines, and pass that to
+ // GenerateBreakpointCommandCallbackData. That will
+ // wrap the body in an auto-generated function, and return the function name
+ // in script_source. That is what
+ // the callback will actually invoke.
+
+ data_ap->user_source.SplitIntoLines(command_body_text);
+ Error error = GenerateBreakpointCommandCallbackData(data_ap->user_source,
+ data_ap->script_source);
+ if (error.Success()) {
+ auto baton_sp =
+ std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_ap));
+ bp_options->SetCallback(ScriptInterpreterPython::BreakpointCallbackFunction,
+ baton_sp);
+ return error;
+ } else
+ return error;
}
// Set a Python one-liner as the callback for the watchpoint.
-void
-ScriptInterpreterPython::SetWatchpointCommandCallback (WatchpointOptions *wp_options,
- const char *oneliner)
-{
- std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
+void ScriptInterpreterPython::SetWatchpointCommandCallback(
+ WatchpointOptions *wp_options, const char *oneliner) {
+ auto data_ap = llvm::make_unique<WatchpointOptions::CommandData>();
+
+ // It's necessary to set both user_source and script_source to the oneliner.
+ // The former is used to generate callback description (as in watchpoint
+ // command list)
+ // while the latter is used for Python to interpret during the actual
+ // callback.
+
+ data_ap->user_source.AppendString(oneliner);
+ data_ap->script_source.assign(oneliner);
+
+ if (GenerateWatchpointCommandCallbackData(data_ap->user_source,
+ data_ap->script_source)) {
+ auto baton_sp =
+ std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_ap));
+ wp_options->SetCallback(ScriptInterpreterPython::WatchpointCallbackFunction,
+ baton_sp);
+ }
+
+ return;
+}
+
+Error ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter(
+ StringList &function_def) {
+ // Convert StringList to one long, newline delimited, const char *.
+ std::string function_def_string(function_def.CopyList());
+
+ Error error = ExecuteMultipleLines(
+ function_def_string.c_str(),
+ ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
+ return error;
+}
+
+Error ScriptInterpreterPython::GenerateFunction(const char *signature,
+ const StringList &input) {
+ Error error;
+ int num_lines = input.GetSize();
+ if (num_lines == 0) {
+ error.SetErrorString("No input data.");
+ return error;
+ }
- // It's necessary to set both user_source and script_source to the oneliner.
- // The former is used to generate callback description (as in watchpoint command list)
- // while the latter is used for Python to interpret during the actual callback.
+ if (!signature || *signature == 0) {
+ error.SetErrorString("No output function name.");
+ return error;
+ }
+
+ StreamString sstr;
+ StringList auto_generated_function;
+ auto_generated_function.AppendString(signature);
+ auto_generated_function.AppendString(
+ " global_dict = globals()"); // Grab the global dictionary
+ auto_generated_function.AppendString(
+ " new_keys = internal_dict.keys()"); // Make a list of keys in the
+ // session dict
+ auto_generated_function.AppendString(
+ " old_keys = global_dict.keys()"); // Save list of keys in global dict
+ auto_generated_function.AppendString(
+ " global_dict.update (internal_dict)"); // Add the session dictionary
+ // to the
+ // global dictionary.
+
+ // Wrap everything up inside the function, increasing the indentation.
+
+ auto_generated_function.AppendString(" if True:");
+ for (int i = 0; i < num_lines; ++i) {
+ sstr.Clear();
+ sstr.Printf(" %s", input.GetStringAtIndex(i));
+ auto_generated_function.AppendString(sstr.GetData());
+ }
+ auto_generated_function.AppendString(
+ " for key in new_keys:"); // Iterate over all the keys from session
+ // dict
+ auto_generated_function.AppendString(
+ " internal_dict[key] = global_dict[key]"); // Update session dict
+ // values
+ auto_generated_function.AppendString(
+ " if key not in old_keys:"); // If key was not originally in
+ // global dict
+ auto_generated_function.AppendString(
+ " del global_dict[key]"); // ...then remove key/value from
+ // global dict
+
+ // Verify that the results are valid Python.
+
+ error = ExportFunctionDefinitionToInterpreter(auto_generated_function);
+
+ return error;
+}
+
+bool ScriptInterpreterPython::GenerateTypeScriptFunction(
+ StringList &user_input, std::string &output, const void *name_token) {
+ static uint32_t num_created_functions = 0;
+ user_input.RemoveBlankLines();
+ StreamString sstr;
+
+ // Check to see if we have any data; if not, just return.
+ if (user_input.GetSize() == 0)
+ return false;
- data_ap->user_source.AppendString (oneliner);
- data_ap->script_source.assign (oneliner);
+ // Take what the user wrote, wrap it all up inside one big auto-generated
+ // Python function, passing in the
+ // ValueObject as parameter to the function.
- if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
- {
- BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
- wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
- }
-
- return;
-}
+ std::string auto_generated_function_name(
+ GenerateUniqueName("lldb_autogen_python_type_print_func",
+ num_created_functions, name_token));
+ sstr.Printf("def %s (valobj, internal_dict):",
+ auto_generated_function_name.c_str());
-Error
-ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
-{
- // Convert StringList to one long, newline delimited, const char *.
- std::string function_def_string(function_def.CopyList());
+ if (!GenerateFunction(sstr.GetData(), user_input).Success())
+ return false;
- Error error = ExecuteMultipleLines (function_def_string.c_str(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
- return error;
+ // Store the name of the auto-generated function to be called.
+ output.assign(auto_generated_function_name);
+ return true;
}
-Error
-ScriptInterpreterPython::GenerateFunction(const char *signature, const StringList &input)
-{
- Error error;
- int num_lines = input.GetSize ();
- if (num_lines == 0)
- {
- error.SetErrorString ("No input data.");
- return error;
- }
-
- if (!signature || *signature == 0)
- {
- error.SetErrorString("No output function name.");
- return error;
- }
+bool ScriptInterpreterPython::GenerateScriptAliasFunction(
+ StringList &user_input, std::string &output) {
+ static uint32_t num_created_functions = 0;
+ user_input.RemoveBlankLines();
+ StreamString sstr;
- StreamString sstr;
- StringList auto_generated_function;
- auto_generated_function.AppendString (signature);
- auto_generated_function.AppendString (" global_dict = globals()"); // Grab the global dictionary
- auto_generated_function.AppendString (" new_keys = internal_dict.keys()"); // Make a list of keys in the session dict
- auto_generated_function.AppendString (" old_keys = global_dict.keys()"); // Save list of keys in global dict
- auto_generated_function.AppendString (" global_dict.update (internal_dict)"); // Add the session dictionary to the
- // global dictionary.
-
- // Wrap everything up inside the function, increasing the indentation.
-
- auto_generated_function.AppendString(" if True:");
- for (int i = 0; i < num_lines; ++i)
- {
- sstr.Clear ();
- sstr.Printf (" %s", input.GetStringAtIndex (i));
- auto_generated_function.AppendString (sstr.GetData());
- }
- auto_generated_function.AppendString (" for key in new_keys:"); // Iterate over all the keys from session dict
- auto_generated_function.AppendString (" internal_dict[key] = global_dict[key]"); // Update session dict values
- auto_generated_function.AppendString (" if key not in old_keys:"); // If key was not originally in global dict
- auto_generated_function.AppendString (" del global_dict[key]"); // ...then remove key/value from global dict
-
- // Verify that the results are valid Python.
-
- error = ExportFunctionDefinitionToInterpreter (auto_generated_function);
-
- return error;
-}
+ // Check to see if we have any data; if not, just return.
+ if (user_input.GetSize() == 0)
+ return false;
-bool
-ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, const void* name_token)
-{
- static uint32_t num_created_functions = 0;
- user_input.RemoveBlankLines ();
- StreamString sstr;
-
- // Check to see if we have any data; if not, just return.
- if (user_input.GetSize() == 0)
- return false;
-
- // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
- // ValueObject as parameter to the function.
-
- std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_type_print_func", num_created_functions, name_token));
- sstr.Printf ("def %s (valobj, internal_dict):", auto_generated_function_name.c_str());
-
- if (!GenerateFunction(sstr.GetData(), user_input).Success())
- return false;
+ std::string auto_generated_function_name(GenerateUniqueName(
+ "lldb_autogen_python_cmd_alias_func", num_created_functions));
- // Store the name of the auto-generated function to be called.
- output.assign(auto_generated_function_name);
- return true;
-}
+ sstr.Printf("def %s (debugger, args, result, internal_dict):",
+ auto_generated_function_name.c_str());
-bool
-ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, std::string &output)
-{
- static uint32_t num_created_functions = 0;
- user_input.RemoveBlankLines ();
- StreamString sstr;
-
- // Check to see if we have any data; if not, just return.
- if (user_input.GetSize() == 0)
- return false;
-
- std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_cmd_alias_func", num_created_functions));
+ if (!GenerateFunction(sstr.GetData(), user_input).Success())
+ return false;
- sstr.Printf ("def %s (debugger, args, result, internal_dict):", auto_generated_function_name.c_str());
-
- if (!GenerateFunction(sstr.GetData(),user_input).Success())
- return false;
-
- // Store the name of the auto-generated function to be called.
- output.assign(auto_generated_function_name);
- return true;
+ // Store the name of the auto-generated function to be called.
+ output.assign(auto_generated_function_name);
+ return true;
}
+bool ScriptInterpreterPython::GenerateTypeSynthClass(StringList &user_input,
+ std::string &output,
+ const void *name_token) {
+ static uint32_t num_created_classes = 0;
+ user_input.RemoveBlankLines();
+ int num_lines = user_input.GetSize();
+ StreamString sstr;
-bool
-ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, const void* name_token)
-{
- static uint32_t num_created_classes = 0;
- user_input.RemoveBlankLines ();
- int num_lines = user_input.GetSize ();
- StreamString sstr;
-
- // Check to see if we have any data; if not, just return.
- if (user_input.GetSize() == 0)
- return false;
-
- // Wrap all user input into a Python class
-
- std::string auto_generated_class_name(GenerateUniqueName("lldb_autogen_python_type_synth_class",num_created_classes,name_token));
-
- StringList auto_generated_class;
-
- // Create the function name & definition string.
-
- sstr.Printf ("class %s:", auto_generated_class_name.c_str());
- auto_generated_class.AppendString (sstr.GetData());
-
- // Wrap everything up inside the class, increasing the indentation.
- // we don't need to play any fancy indentation tricks here because there is no
- // surrounding code whose indentation we need to honor
- for (int i = 0; i < num_lines; ++i)
- {
- sstr.Clear ();
- sstr.Printf (" %s", user_input.GetStringAtIndex (i));
- auto_generated_class.AppendString (sstr.GetData());
- }
-
-
- // Verify that the results are valid Python.
- // (even though the method is ExportFunctionDefinitionToInterpreter, a class will actually be exported)
- // (TODO: rename that method to ExportDefinitionToInterpreter)
- if (!ExportFunctionDefinitionToInterpreter (auto_generated_class).Success())
- return false;
-
- // Store the name of the auto-generated class
-
- output.assign(auto_generated_class_name);
- return true;
-}
+ // Check to see if we have any data; if not, just return.
+ if (user_input.GetSize() == 0)
+ return false;
-StructuredData::GenericSP
-ScriptInterpreterPython::OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp)
-{
- if (class_name == nullptr || class_name[0] == '\0')
- return StructuredData::GenericSP();
+ // Wrap all user input into a Python class
- if (!process_sp)
- return StructuredData::GenericSP();
+ std::string auto_generated_class_name(GenerateUniqueName(
+ "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
- void* ret_val;
-
- {
- Locker py_lock (this,
- Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
- ret_val = g_swig_create_os_plugin (class_name,
- m_dictionary_name.c_str(),
- process_sp);
- }
+ StringList auto_generated_class;
+
+ // Create the function name & definition string.
- return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ sstr.Printf("class %s:", auto_generated_class_name.c_str());
+ auto_generated_class.AppendString(sstr.GetString());
+
+ // Wrap everything up inside the class, increasing the indentation.
+ // we don't need to play any fancy indentation tricks here because there is no
+ // surrounding code whose indentation we need to honor
+ for (int i = 0; i < num_lines; ++i) {
+ sstr.Clear();
+ sstr.Printf(" %s", user_input.GetStringAtIndex(i));
+ auto_generated_class.AppendString(sstr.GetString());
+ }
+
+ // Verify that the results are valid Python.
+ // (even though the method is ExportFunctionDefinitionToInterpreter, a class
+ // will actually be exported)
+ // (TODO: rename that method to ExportDefinitionToInterpreter)
+ if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success())
+ return false;
+
+ // Store the name of the auto-generated class
+
+ output.assign(auto_generated_class_name);
+ return true;
}
-StructuredData::DictionarySP
-ScriptInterpreterPython::OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp)
-{
- Locker py_lock(this,
- Locker::AcquireLock | Locker::NoSTDIN,
+StructuredData::GenericSP ScriptInterpreterPython::OSPlugin_CreatePluginObject(
+ const char *class_name, lldb::ProcessSP process_sp) {
+ if (class_name == nullptr || class_name[0] == '\0')
+ return StructuredData::GenericSP();
+
+ if (!process_sp)
+ return StructuredData::GenericSP();
+
+ void *ret_val;
+
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
Locker::FreeLock);
-
- static char callee_name[] = "get_register_info";
-
- if (!os_plugin_object_sp)
- return StructuredData::DictionarySP();
+ ret_val = g_swig_create_os_plugin(class_name, m_dictionary_name.c_str(),
+ process_sp);
+ }
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return nullptr;
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+}
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)generic->GetValue());
+StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_RegisterInfo(
+ StructuredData::ObjectSP os_plugin_object_sp) {
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- if (!implementor.IsAllocated())
- return StructuredData::DictionarySP();
+ static char callee_name[] = "get_register_info";
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+ if (!os_plugin_object_sp)
+ return StructuredData::DictionarySP();
- if (PyErr_Occurred())
- PyErr_Clear();
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
- if (!pmeth.IsAllocated())
- return StructuredData::DictionarySP();
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
-
- return StructuredData::DictionarySP();
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)generic->GetValue());
- // if it fails, print the error but otherwise go on
+ if (!implementor.IsAllocated())
+ return StructuredData::DictionarySP();
+
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return StructuredData::DictionarySP();
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
- if (py_return.get())
- {
- PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
- return result_dict.CreateStructuredDictionary();
- }
+ PyErr_Clear();
+
return StructuredData::DictionarySP();
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ if (py_return.get()) {
+ PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
+ return result_dict.CreateStructuredDictionary();
+ }
+ return StructuredData::DictionarySP();
}
-StructuredData::ArraySP
-ScriptInterpreterPython::OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp)
-{
- Locker py_lock (this,
- Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
+StructuredData::ArraySP ScriptInterpreterPython::OSPlugin_ThreadsInfo(
+ StructuredData::ObjectSP os_plugin_object_sp) {
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- static char callee_name[] = "get_thread_info";
+ static char callee_name[] = "get_thread_info";
- if (!os_plugin_object_sp)
- return StructuredData::ArraySP();
+ if (!os_plugin_object_sp)
+ return StructuredData::ArraySP();
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return nullptr;
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)generic->GetValue());
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)generic->GetValue());
- if (!implementor.IsAllocated())
- return StructuredData::ArraySP();
+ if (!implementor.IsAllocated())
+ return StructuredData::ArraySP();
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
- if (PyErr_Occurred())
- PyErr_Clear();
+ if (PyErr_Occurred())
+ PyErr_Clear();
- if (!pmeth.IsAllocated())
- return StructuredData::ArraySP();
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
-
- return StructuredData::ArraySP();
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+ if (!pmeth.IsAllocated())
+ return StructuredData::ArraySP();
- // if it fails, print the error but otherwise go on
+ if (PyCallable_Check(pmeth.get()) == 0) {
if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
+ PyErr_Clear();
- if (py_return.get())
- {
- PythonList result_list(PyRefType::Borrowed, py_return.get());
- return result_list.CreateStructuredArray();
- }
return StructuredData::ArraySP();
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+
+ // 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());
+ return result_list.CreateStructuredArray();
+ }
+ return StructuredData::ArraySP();
}
// GetPythonValueFormatString provides a system independent type safe way to
@@ -1623,1620 +1599,1598 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin
// as the underlying typedef for uint* types, size_t, off_t and other values
// change.
-template <typename T>
-const char *GetPythonValueFormatString(T t)
-{
- assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
- return nullptr;
+template <typename T> const char *GetPythonValueFormatString(T t) {
+ assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a "
+ "specialization of GetPythonValueFormatString() to support this "
+ "type.");
+ return nullptr;
}
-template <> const char *GetPythonValueFormatString (char *) { return "s"; }
-template <> const char *GetPythonValueFormatString (char) { return "b"; }
-template <> const char *GetPythonValueFormatString (unsigned char) { return "B"; }
-template <> const char *GetPythonValueFormatString (short) { return "h"; }
-template <> const char *GetPythonValueFormatString (unsigned short) { return "H"; }
-template <> const char *GetPythonValueFormatString (int) { return "i"; }
-template <> const char *GetPythonValueFormatString (unsigned int) { return "I"; }
-template <> const char *GetPythonValueFormatString (long) { return "l"; }
-template <> const char *GetPythonValueFormatString (unsigned long) { return "k"; }
-template <> const char *GetPythonValueFormatString (long long) { return "L"; }
-template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; }
-template <> const char *GetPythonValueFormatString (float t) { return "f"; }
-template <> const char *GetPythonValueFormatString (double t) { return "d"; }
-
-StructuredData::StringSP
-ScriptInterpreterPython::OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid)
-{
- Locker py_lock (this,
- Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- static char callee_name[] = "get_register_data";
- static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
-
- if (!os_plugin_object_sp)
- return StructuredData::StringSP();
-
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return nullptr;
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)generic->GetValue());
-
- if (!implementor.IsAllocated())
- return StructuredData::StringSP();
-
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+template <> const char *GetPythonValueFormatString(char *) { return "s"; }
+template <> const char *GetPythonValueFormatString(char) { return "b"; }
+template <> const char *GetPythonValueFormatString(unsigned char) {
+ return "B";
+}
+template <> const char *GetPythonValueFormatString(short) { return "h"; }
+template <> const char *GetPythonValueFormatString(unsigned short) {
+ return "H";
+}
+template <> const char *GetPythonValueFormatString(int) { return "i"; }
+template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
+template <> const char *GetPythonValueFormatString(long) { return "l"; }
+template <> const char *GetPythonValueFormatString(unsigned long) {
+ return "k";
+}
+template <> const char *GetPythonValueFormatString(long long) { return "L"; }
+template <> const char *GetPythonValueFormatString(unsigned long long) {
+ return "K";
+}
+template <> const char *GetPythonValueFormatString(float t) { return "f"; }
+template <> const char *GetPythonValueFormatString(double t) { return "d"; }
- if (PyErr_Occurred())
- PyErr_Clear();
+StructuredData::StringSP ScriptInterpreterPython::OSPlugin_RegisterContextData(
+ StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- if (!pmeth.IsAllocated())
- return StructuredData::StringSP();
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
- return StructuredData::StringSP();
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, param_format, tid));
+ static char callee_name[] = "get_register_data";
+ static char *param_format =
+ const_cast<char *>(GetPythonValueFormatString(tid));
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
+ if (!os_plugin_object_sp)
+ return StructuredData::StringSP();
- if (py_return.get())
- {
- PythonBytes result(PyRefType::Borrowed, py_return.get());
- return result.CreateStructuredString();
- }
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)generic->GetValue());
+
+ if (!implementor.IsAllocated())
return StructuredData::StringSP();
+
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return StructuredData::StringSP();
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return StructuredData::StringSP();
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name, param_format, tid));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return.get()) {
+ PythonBytes result(PyRefType::Borrowed, py_return.get());
+ return result.CreateStructuredString();
+ }
+ return StructuredData::StringSP();
}
-StructuredData::DictionarySP
-ScriptInterpreterPython::OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, lldb::addr_t context)
-{
- Locker py_lock(this,
- Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- static char callee_name[] = "create_thread";
- std::string param_format;
- param_format += GetPythonValueFormatString(tid);
- param_format += GetPythonValueFormatString(context);
-
- if (!os_plugin_object_sp)
- return StructuredData::DictionarySP();
+StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_CreateThread(
+ StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
+ lldb::addr_t context) {
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic)
- return nullptr;
+ static char callee_name[] = "create_thread";
+ std::string param_format;
+ param_format += GetPythonValueFormatString(tid);
+ param_format += GetPythonValueFormatString(context);
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)generic->GetValue());
+ if (!os_plugin_object_sp)
+ return StructuredData::DictionarySP();
- if (!implementor.IsAllocated())
- return StructuredData::DictionarySP();
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)generic->GetValue());
- if (PyErr_Occurred())
- PyErr_Clear();
+ if (!implementor.IsAllocated())
+ return StructuredData::DictionarySP();
- if (!pmeth.IsAllocated())
- return StructuredData::DictionarySP();
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
- return StructuredData::DictionarySP();
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, &param_format[0], tid, context));
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
+ if (PyErr_Occurred())
+ PyErr_Clear();
- if (py_return.get())
- {
- PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
- return result_dict.CreateStructuredDictionary();
- }
+ if (!pmeth.IsAllocated())
+ return StructuredData::DictionarySP();
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
return StructuredData::DictionarySP();
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name,
+ &param_format[0], tid, context));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return.get()) {
+ PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
+ return result_dict.CreateStructuredDictionary();
+ }
+ return StructuredData::DictionarySP();
}
-StructuredData::ObjectSP
-ScriptInterpreterPython::CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan_sp)
-{
- if (class_name == nullptr || class_name[0] == '\0')
- return StructuredData::ObjectSP();
+StructuredData::ObjectSP ScriptInterpreterPython::CreateScriptedThreadPlan(
+ const char *class_name, lldb::ThreadPlanSP thread_plan_sp) {
+ if (class_name == nullptr || class_name[0] == '\0')
+ return StructuredData::ObjectSP();
- if (!thread_plan_sp.get())
- return StructuredData::ObjectSP();
+ if (!thread_plan_sp.get())
+ return StructuredData::ObjectSP();
- Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter = static_cast<ScriptInterpreterPython *>(script_interpreter);
-
- if (!script_interpreter)
- return StructuredData::ObjectSP();
+ Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
+ ScriptInterpreter *script_interpreter =
+ debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter =
+ static_cast<ScriptInterpreterPython *>(script_interpreter);
- void* ret_val;
+ if (!script_interpreter)
+ return StructuredData::ObjectSP();
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-
- ret_val = g_swig_thread_plan_script (class_name,
- python_interpreter->m_dictionary_name.c_str(),
- thread_plan_sp);
- }
+ void *ret_val;
- return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
-}
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-bool
-ScriptInterpreterPython::ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
-{
- bool explains_stop = true;
- StructuredData::Generic *generic = nullptr;
- if (implementor_sp)
- generic = implementor_sp->GetAsGeneric();
- if (generic)
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- explains_stop = g_swig_call_thread_plan(generic->GetValue(), "explains_stop", event, script_error);
- if (script_error)
- return true;
- }
- return explains_stop;
-}
+ ret_val = g_swig_thread_plan_script(
+ class_name, python_interpreter->m_dictionary_name.c_str(),
+ thread_plan_sp);
+ }
-bool
-ScriptInterpreterPython::ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
-{
- bool should_stop = true;
- StructuredData::Generic *generic = nullptr;
- if (implementor_sp)
- generic = implementor_sp->GetAsGeneric();
- if (generic)
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- should_stop = g_swig_call_thread_plan(generic->GetValue(), "should_stop", event, script_error);
- if (script_error)
- return true;
- }
- return should_stop;
+ return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
}
-lldb::StateType
-ScriptInterpreterPython::ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error)
-{
- bool should_step = false;
- StructuredData::Generic *generic = nullptr;
- if (implementor_sp)
- generic = implementor_sp->GetAsGeneric();
- if (generic)
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- should_step = g_swig_call_thread_plan(generic->GetValue(), "should_step", NULL, script_error);
- if (script_error)
- should_step = true;
- }
- if (should_step)
- return lldb::eStateStepping;
- else
- return lldb::eStateRunning;
+bool ScriptInterpreterPython::ScriptedThreadPlanExplainsStop(
+ StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
+ bool explains_stop = true;
+ StructuredData::Generic *generic = nullptr;
+ if (implementor_sp)
+ generic = implementor_sp->GetAsGeneric();
+ if (generic) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ explains_stop = g_swig_call_thread_plan(
+ generic->GetValue(), "explains_stop", event, script_error);
+ if (script_error)
+ return true;
+ }
+ return explains_stop;
+}
+
+bool ScriptInterpreterPython::ScriptedThreadPlanShouldStop(
+ StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
+ bool should_stop = true;
+ StructuredData::Generic *generic = nullptr;
+ if (implementor_sp)
+ generic = implementor_sp->GetAsGeneric();
+ if (generic) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ should_stop = g_swig_call_thread_plan(generic->GetValue(), "should_stop",
+ event, script_error);
+ if (script_error)
+ return true;
+ }
+ return should_stop;
+}
+
+bool ScriptInterpreterPython::ScriptedThreadPlanIsStale(
+ StructuredData::ObjectSP implementor_sp, bool &script_error) {
+ bool is_stale = true;
+ StructuredData::Generic *generic = nullptr;
+ if (implementor_sp)
+ generic = implementor_sp->GetAsGeneric();
+ if (generic) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ is_stale = g_swig_call_thread_plan(generic->GetValue(), "is_stale", nullptr,
+ script_error);
+ if (script_error)
+ return true;
+ }
+ return is_stale;
+}
+
+lldb::StateType ScriptInterpreterPython::ScriptedThreadPlanGetRunState(
+ StructuredData::ObjectSP implementor_sp, bool &script_error) {
+ bool should_step = false;
+ StructuredData::Generic *generic = nullptr;
+ if (implementor_sp)
+ generic = implementor_sp->GetAsGeneric();
+ if (generic) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ should_step = g_swig_call_thread_plan(generic->GetValue(), "should_step",
+ NULL, script_error);
+ if (script_error)
+ should_step = true;
+ }
+ if (should_step)
+ return lldb::eStateStepping;
+ else
+ return lldb::eStateRunning;
}
StructuredData::ObjectSP
-ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error)
-{
- if (!file_spec.Exists())
- {
- error.SetErrorString("no such file");
- return StructuredData::ObjectSP();
- }
+ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec,
+ lldb_private::Error &error) {
+ if (!file_spec.Exists()) {
+ error.SetErrorString("no such file");
+ return StructuredData::ObjectSP();
+ }
- StructuredData::ObjectSP module_sp;
+ StructuredData::ObjectSP module_sp;
- if (LoadScriptingModule(file_spec.GetPath().c_str(),true,true,error,&module_sp))
- return module_sp;
+ if (LoadScriptingModule(file_spec.GetPath().c_str(), true, true, error,
+ &module_sp))
+ return module_sp;
- return StructuredData::ObjectSP();
+ return StructuredData::ObjectSP();
}
-StructuredData::DictionarySP
-ScriptInterpreterPython::GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name,
- lldb_private::Error &error)
-{
- if (!plugin_module_sp || !target || !setting_name || !setting_name[0] || !g_swig_plugin_get)
- return StructuredData::DictionarySP();
- StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
- if (!generic)
- return StructuredData::DictionarySP();
+StructuredData::DictionarySP ScriptInterpreterPython::GetDynamicSettings(
+ StructuredData::ObjectSP plugin_module_sp, Target *target,
+ const char *setting_name, lldb_private::Error &error) {
+ if (!plugin_module_sp || !target || !setting_name || !setting_name[0] ||
+ !g_swig_plugin_get)
+ return StructuredData::DictionarySP();
+ StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
+ if (!generic)
+ return StructuredData::DictionarySP();
- PythonObject reply_pyobj;
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- TargetSP target_sp(target->shared_from_this());
- reply_pyobj.Reset(PyRefType::Owned,
- (PyObject *)g_swig_plugin_get(generic->GetValue(), setting_name, target_sp));
- }
+ PythonObject reply_pyobj;
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ TargetSP target_sp(target->shared_from_this());
+ reply_pyobj.Reset(PyRefType::Owned,
+ (PyObject *)g_swig_plugin_get(generic->GetValue(),
+ setting_name, target_sp));
+ }
- PythonDictionary py_dict(PyRefType::Borrowed, reply_pyobj.get());
- return py_dict.CreateStructuredDictionary();
+ PythonDictionary py_dict(PyRefType::Borrowed, reply_pyobj.get());
+ return py_dict.CreateStructuredDictionary();
}
StructuredData::ObjectSP
-ScriptInterpreterPython::CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj)
-{
- if (class_name == nullptr || class_name[0] == '\0')
- return StructuredData::ObjectSP();
+ScriptInterpreterPython::CreateSyntheticScriptedProvider(
+ const char *class_name, lldb::ValueObjectSP valobj) {
+ if (class_name == nullptr || class_name[0] == '\0')
+ return StructuredData::ObjectSP();
- if (!valobj.get())
- return StructuredData::ObjectSP();
+ if (!valobj.get())
+ return StructuredData::ObjectSP();
- ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target)
- return StructuredData::ObjectSP();
+ ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
+ Target *target = exe_ctx.GetTargetPtr();
- Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
-
- if (!script_interpreter)
- return StructuredData::ObjectSP();
+ if (!target)
+ return StructuredData::ObjectSP();
- void *ret_val = nullptr;
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreter *script_interpreter =
+ debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter =
+ (ScriptInterpreterPython *)script_interpreter;
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_synthetic_script (class_name,
- python_interpreter->m_dictionary_name.c_str(),
- valobj);
- }
+ if (!script_interpreter)
+ return StructuredData::ObjectSP();
+
+ void *ret_val = nullptr;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_synthetic_script(
+ class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
+ }
- return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
+ return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
}
StructuredData::GenericSP
-ScriptInterpreterPython::CreateScriptCommandObject (const char *class_name)
-{
- DebuggerSP debugger_sp(GetCommandInterpreter().GetDebugger().shared_from_this());
-
- if (class_name == nullptr || class_name[0] == '\0')
- return StructuredData::GenericSP();
-
- if (!debugger_sp.get())
- return StructuredData::GenericSP();
-
- void* ret_val;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_create_cmd (class_name,
- m_dictionary_name.c_str(),
- debugger_sp);
- }
-
- return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ScriptInterpreterPython::CreateScriptCommandObject(const char *class_name) {
+ DebuggerSP debugger_sp(
+ GetCommandInterpreter().GetDebugger().shared_from_this());
+
+ if (class_name == nullptr || class_name[0] == '\0')
+ return StructuredData::GenericSP();
+
+ if (!debugger_sp.get())
+ return StructuredData::GenericSP();
+
+ void *ret_val;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val =
+ g_swig_create_cmd(class_name, m_dictionary_name.c_str(), debugger_sp);
+ }
+
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}
-bool
-ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token)
-{
- StringList input;
- input.SplitIntoLines(oneliner, strlen(oneliner));
- return GenerateTypeScriptFunction(input, output, name_token);
+bool ScriptInterpreterPython::GenerateTypeScriptFunction(
+ const char *oneliner, std::string &output, const void *name_token) {
+ StringList input;
+ input.SplitIntoLines(oneliner, strlen(oneliner));
+ return GenerateTypeScriptFunction(input, output, name_token);
}
-bool
-ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, const void* name_token)
-{
- StringList input;
- input.SplitIntoLines(oneliner, strlen(oneliner));
- return GenerateTypeSynthClass(input, output, name_token);
+bool ScriptInterpreterPython::GenerateTypeSynthClass(const char *oneliner,
+ std::string &output,
+ const void *name_token) {
+ StringList input;
+ input.SplitIntoLines(oneliner, strlen(oneliner));
+ return GenerateTypeSynthClass(input, output, name_token);
}
+Error ScriptInterpreterPython::GenerateBreakpointCommandCallbackData(
+ StringList &user_input, std::string &output) {
+ static uint32_t num_created_functions = 0;
+ user_input.RemoveBlankLines();
+ StreamString sstr;
+ Error error;
+ if (user_input.GetSize() == 0) {
+ error.SetErrorString("No input data.");
+ return error;
+ }
-Error
-ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, std::string& output)
-{
- static uint32_t num_created_functions = 0;
- user_input.RemoveBlankLines ();
- StreamString sstr;
- Error error;
- if (user_input.GetSize() == 0)
- {
- error.SetErrorString("No input data.");
- return error;
- }
+ std::string auto_generated_function_name(GenerateUniqueName(
+ "lldb_autogen_python_bp_callback_func_", num_created_functions));
+ sstr.Printf("def %s (frame, bp_loc, internal_dict):",
+ auto_generated_function_name.c_str());
- std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_bp_callback_func_",num_created_functions));
- sstr.Printf ("def %s (frame, bp_loc, internal_dict):", auto_generated_function_name.c_str());
-
- error = GenerateFunction(sstr.GetData(), user_input);
- if (!error.Success())
- return error;
-
- // Store the name of the auto-generated function to be called.
- output.assign(auto_generated_function_name);
+ error = GenerateFunction(sstr.GetData(), user_input);
+ if (!error.Success())
return error;
+
+ // Store the name of the auto-generated function to be called.
+ output.assign(auto_generated_function_name);
+ return error;
}
-bool
-ScriptInterpreterPython::GenerateWatchpointCommandCallbackData (StringList &user_input, std::string& output)
-{
- static uint32_t num_created_functions = 0;
- user_input.RemoveBlankLines ();
- StreamString sstr;
+bool ScriptInterpreterPython::GenerateWatchpointCommandCallbackData(
+ StringList &user_input, std::string &output) {
+ static uint32_t num_created_functions = 0;
+ user_input.RemoveBlankLines();
+ StreamString sstr;
- if (user_input.GetSize() == 0)
- return false;
+ if (user_input.GetSize() == 0)
+ return false;
- std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_wp_callback_func_",num_created_functions));
- sstr.Printf ("def %s (frame, wp, internal_dict):", auto_generated_function_name.c_str());
-
- if (!GenerateFunction(sstr.GetData(), user_input).Success())
- return false;
-
- // Store the name of the auto-generated function to be called.
- output.assign(auto_generated_function_name);
- return true;
+ std::string auto_generated_function_name(GenerateUniqueName(
+ "lldb_autogen_python_wp_callback_func_", num_created_functions));
+ sstr.Printf("def %s (frame, wp, internal_dict):",
+ auto_generated_function_name.c_str());
+
+ if (!GenerateFunction(sstr.GetData(), user_input).Success())
+ return false;
+
+ // Store the name of the auto-generated function to be called.
+ output.assign(auto_generated_function_name);
+ return true;
}
-bool
-ScriptInterpreterPython::GetScriptedSummary(const char *python_function_name, lldb::ValueObjectSP valobj,
- StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options,
- std::string &retval)
-{
-
- Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
-
- if (!valobj.get())
- {
- retval.assign("<no object>");
- return false;
- }
+bool ScriptInterpreterPython::GetScriptedSummary(
+ const char *python_function_name, lldb::ValueObjectSP valobj,
+ StructuredData::ObjectSP &callee_wrapper_sp,
+ const TypeSummaryOptions &options, std::string &retval) {
- void *old_callee = nullptr;
- StructuredData::Generic *generic = nullptr;
- if (callee_wrapper_sp)
- {
- generic = callee_wrapper_sp->GetAsGeneric();
- if (generic)
- old_callee = generic->GetValue();
- }
- void* new_callee = old_callee;
-
- bool ret_val;
- if (python_function_name && *python_function_name)
- {
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- {
- TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
-
- Timer scoped_timer ("g_swig_typescript_callback","g_swig_typescript_callback");
- ret_val = g_swig_typescript_callback (python_function_name,
- GetSessionDictionary().get(),
- valobj,
- &new_callee,
- options_sp,
- retval);
- }
- }
- }
- else
- {
- retval.assign("<no function name>");
- return false;
- }
-
- if (new_callee && old_callee != new_callee)
- callee_wrapper_sp.reset(new StructuredPythonObject(new_callee));
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION);
- return ret_val;
+ if (!valobj.get()) {
+ retval.assign("<no object>");
+ return false;
+ }
+
+ void *old_callee = nullptr;
+ StructuredData::Generic *generic = nullptr;
+ if (callee_wrapper_sp) {
+ generic = callee_wrapper_sp->GetAsGeneric();
+ if (generic)
+ old_callee = generic->GetValue();
+ }
+ void *new_callee = old_callee;
+
+ bool ret_val;
+ if (python_function_name && *python_function_name) {
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession |
+ Locker::NoSTDIN);
+ {
+ TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
+
+ Timer scoped_timer("g_swig_typescript_callback",
+ "g_swig_typescript_callback");
+ ret_val = g_swig_typescript_callback(
+ python_function_name, GetSessionDictionary().get(), valobj,
+ &new_callee, options_sp, retval);
+ }
+ }
+ } else {
+ retval.assign("<no function name>");
+ return false;
+ }
+
+ if (new_callee && old_callee != new_callee)
+ callee_wrapper_sp.reset(new StructuredPythonObject(new_callee));
+
+ return ret_val;
}
-void
-ScriptInterpreterPython::Clear ()
-{
- // Release any global variables that might have strong references to
- // LLDB objects when clearing the python script interpreter.
- Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
-
- // This may be called as part of Py_Finalize. In that case the modules are destroyed in random
- // order and we can't guarantee that we can access these.
- if (Py_IsInitialized())
- PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process = None; lldb.thread = None; lldb.frame = None");
-}
-
-bool
-ScriptInterpreterPython::BreakpointCallbackFunction
-(
- void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id
-)
-{
- BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
- const char *python_function_name = bp_option_data->script_source.c_str();
-
- if (!context)
- return true;
-
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target)
- return true;
-
- Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
-
- if (!script_interpreter)
- return true;
-
- if (python_function_name && python_function_name[0])
- {
- const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
- BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
- if (breakpoint_sp)
+void ScriptInterpreterPython::Clear() {
+ // Release any global variables that might have strong references to
+ // LLDB objects when clearing the python script interpreter.
+ Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
+
+ // This may be called as part of Py_Finalize. In that case the modules are
+ // destroyed in random
+ // order and we can't guarantee that we can access these.
+ if (Py_IsInitialized())
+ PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
+ "= None; lldb.thread = None; lldb.frame = None");
+}
+
+bool ScriptInterpreterPython::BreakpointCallbackFunction(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ CommandDataPython *bp_option_data = (CommandDataPython *)baton;
+ const char *python_function_name = bp_option_data->script_source.c_str();
+
+ if (!context)
+ return true;
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Target *target = exe_ctx.GetTargetPtr();
+
+ if (!target)
+ return true;
+
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreter *script_interpreter =
+ debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter =
+ (ScriptInterpreterPython *)script_interpreter;
+
+ if (!script_interpreter)
+ return true;
+
+ if (python_function_name && python_function_name[0]) {
+ const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
+ BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
+ if (breakpoint_sp) {
+ const BreakpointLocationSP bp_loc_sp(
+ breakpoint_sp->FindLocationByID(break_loc_id));
+
+ if (stop_frame_sp && bp_loc_sp) {
+ bool ret_val = true;
{
- const BreakpointLocationSP bp_loc_sp (breakpoint_sp->FindLocationByID (break_loc_id));
-
- if (stop_frame_sp && bp_loc_sp)
- {
- bool ret_val = true;
- {
- Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_breakpoint_callback (python_function_name,
- python_interpreter->m_dictionary_name.c_str(),
- stop_frame_sp,
- bp_loc_sp);
- }
- return ret_val;
- }
+ Locker py_lock(python_interpreter, Locker::AcquireLock |
+ Locker::InitSession |
+ Locker::NoSTDIN);
+ ret_val = g_swig_breakpoint_callback(
+ python_function_name,
+ python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
+ bp_loc_sp);
}
+ return ret_val;
+ }
}
- // We currently always true so we stop in case anything goes wrong when
- // trying to call the script function
- return true;
+ }
+ // We currently always true so we stop in case anything goes wrong when
+ // trying to call the script function
+ return true;
}
-bool
-ScriptInterpreterPython::WatchpointCallbackFunction
-(
- void *baton,
- StoppointCallbackContext *context,
- user_id_t watch_id
-)
-{
- WatchpointOptions::CommandData *wp_option_data = (WatchpointOptions::CommandData *) baton;
- const char *python_function_name = wp_option_data->script_source.c_str();
-
- if (!context)
- return true;
-
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target)
- return true;
-
- Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
-
- if (!script_interpreter)
- return true;
-
- if (python_function_name && python_function_name[0])
- {
- const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
- WatchpointSP wp_sp = target->GetWatchpointList().FindByID (watch_id);
- if (wp_sp)
+bool ScriptInterpreterPython::WatchpointCallbackFunction(
+ void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
+ WatchpointOptions::CommandData *wp_option_data =
+ (WatchpointOptions::CommandData *)baton;
+ const char *python_function_name = wp_option_data->script_source.c_str();
+
+ if (!context)
+ return true;
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Target *target = exe_ctx.GetTargetPtr();
+
+ if (!target)
+ return true;
+
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreter *script_interpreter =
+ debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter =
+ (ScriptInterpreterPython *)script_interpreter;
+
+ if (!script_interpreter)
+ return true;
+
+ if (python_function_name && python_function_name[0]) {
+ const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
+ WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
+ if (wp_sp) {
+ if (stop_frame_sp && wp_sp) {
+ bool ret_val = true;
{
- if (stop_frame_sp && wp_sp)
- {
- bool ret_val = true;
- {
- Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_watchpoint_callback (python_function_name,
- python_interpreter->m_dictionary_name.c_str(),
- stop_frame_sp,
- wp_sp);
- }
- return ret_val;
- }
+ Locker py_lock(python_interpreter, Locker::AcquireLock |
+ Locker::InitSession |
+ Locker::NoSTDIN);
+ ret_val = g_swig_watchpoint_callback(
+ python_function_name,
+ python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
+ wp_sp);
}
+ return ret_val;
+ }
}
- // We currently always true so we stop in case anything goes wrong when
- // trying to call the script function
- return true;
+ }
+ // We currently always true so we stop in case anything goes wrong when
+ // trying to call the script function
+ return true;
}
-size_t
-ScriptInterpreterPython::CalculateNumChildren(const StructuredData::ObjectSP &implementor_sp, uint32_t max)
-{
- if (!implementor_sp)
- return 0;
- StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
- if (!generic)
- return 0;
- void *implementor = generic->GetValue();
- if (!implementor)
- return 0;
-
- if (!g_swig_calc_children)
- return 0;
-
- size_t ret_val = 0;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_calc_children (implementor, max);
- }
-
- return ret_val;
+size_t ScriptInterpreterPython::CalculateNumChildren(
+ const StructuredData::ObjectSP &implementor_sp, uint32_t max) {
+ if (!implementor_sp)
+ return 0;
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return 0;
+ void *implementor = generic->GetValue();
+ if (!implementor)
+ return 0;
+
+ if (!g_swig_calc_children)
+ return 0;
+
+ size_t ret_val = 0;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_calc_children(implementor, max);
+ }
+
+ return ret_val;
}
-lldb::ValueObjectSP
-ScriptInterpreterPython::GetChildAtIndex(const StructuredData::ObjectSP &implementor_sp, uint32_t idx)
-{
- if (!implementor_sp)
- return lldb::ValueObjectSP();
-
- StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
- if (!generic)
- return lldb::ValueObjectSP();
- void *implementor = generic->GetValue();
- if (!implementor)
- return lldb::ValueObjectSP();
-
- if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
- return lldb::ValueObjectSP();
-
- lldb::ValueObjectSP ret_val;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- void* child_ptr = g_swig_get_child_index (implementor,idx);
- if (child_ptr != nullptr && child_ptr != Py_None)
- {
- lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
- if (sb_value_ptr == nullptr)
- Py_XDECREF(child_ptr);
- else
- ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
- }
- else
- {
- Py_XDECREF(child_ptr);
- }
+lldb::ValueObjectSP ScriptInterpreterPython::GetChildAtIndex(
+ const StructuredData::ObjectSP &implementor_sp, uint32_t idx) {
+ if (!implementor_sp)
+ return lldb::ValueObjectSP();
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return lldb::ValueObjectSP();
+ void *implementor = generic->GetValue();
+ if (!implementor)
+ return lldb::ValueObjectSP();
+
+ if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
+ return lldb::ValueObjectSP();
+
+ lldb::ValueObjectSP ret_val;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ void *child_ptr = g_swig_get_child_index(implementor, idx);
+ if (child_ptr != nullptr && child_ptr != Py_None) {
+ lldb::SBValue *sb_value_ptr =
+ (lldb::SBValue *)g_swig_cast_to_sbvalue(child_ptr);
+ if (sb_value_ptr == nullptr)
+ Py_XDECREF(child_ptr);
+ else
+ ret_val = g_swig_get_valobj_sp_from_sbvalue(sb_value_ptr);
+ } else {
+ Py_XDECREF(child_ptr);
}
-
- return ret_val;
+ }
+
+ return ret_val;
}
-int
-ScriptInterpreterPython::GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor_sp, const char *child_name)
-{
- if (!implementor_sp)
- return UINT32_MAX;
-
- StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
- if (!generic)
- return UINT32_MAX;
- void *implementor = generic->GetValue();
- if (!implementor)
- return UINT32_MAX;
-
- if (!g_swig_get_index_child)
- return UINT32_MAX;
-
- int ret_val = UINT32_MAX;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_get_index_child (implementor, child_name);
- }
-
- return ret_val;
+int ScriptInterpreterPython::GetIndexOfChildWithName(
+ const StructuredData::ObjectSP &implementor_sp, const char *child_name) {
+ if (!implementor_sp)
+ return UINT32_MAX;
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return UINT32_MAX;
+ void *implementor = generic->GetValue();
+ if (!implementor)
+ return UINT32_MAX;
+
+ if (!g_swig_get_index_child)
+ return UINT32_MAX;
+
+ int ret_val = UINT32_MAX;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_get_index_child(implementor, child_name);
+ }
+
+ return ret_val;
}
-bool
-ScriptInterpreterPython::UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp)
-{
- bool ret_val = false;
-
- if (!implementor_sp)
- return ret_val;
+bool ScriptInterpreterPython::UpdateSynthProviderInstance(
+ const StructuredData::ObjectSP &implementor_sp) {
+ bool ret_val = false;
- StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
- if (!generic)
- return ret_val;
- void *implementor = generic->GetValue();
- if (!implementor)
- return ret_val;
-
- if (!g_swig_update_provider)
- return ret_val;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_update_provider (implementor);
- }
-
+ if (!implementor_sp)
return ret_val;
-}
-bool
-ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp)
-{
- bool ret_val = false;
-
- if (!implementor_sp)
- return ret_val;
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ void *implementor = generic->GetValue();
+ if (!implementor)
+ return ret_val;
- StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
- if (!generic)
- return ret_val;
- void *implementor = generic->GetValue();
- if (!implementor)
- return ret_val;
-
- if (!g_swig_mighthavechildren_provider)
- return ret_val;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_mighthavechildren_provider (implementor);
- }
-
+ if (!g_swig_update_provider)
return ret_val;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_update_provider(implementor);
+ }
+
+ return ret_val;
}
-lldb::ValueObjectSP
-ScriptInterpreterPython::GetSyntheticValue(const StructuredData::ObjectSP &implementor_sp)
-{
- lldb::ValueObjectSP ret_val(nullptr);
-
- if (!implementor_sp)
- return ret_val;
+bool ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance(
+ const StructuredData::ObjectSP &implementor_sp) {
+ bool ret_val = false;
- StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
- if (!generic)
- return ret_val;
- void *implementor = generic->GetValue();
- if (!implementor)
- return ret_val;
-
- if (!g_swig_getvalue_provider || !g_swig_cast_to_sbvalue || !g_swig_get_valobj_sp_from_sbvalue)
- return ret_val;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- void* child_ptr = g_swig_getvalue_provider (implementor);
- if (child_ptr != nullptr && child_ptr != Py_None)
- {
- lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
- if (sb_value_ptr == nullptr)
- Py_XDECREF(child_ptr);
- else
- ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
- }
- else
- {
- Py_XDECREF(child_ptr);
- }
- }
-
+ if (!implementor_sp)
+ return ret_val;
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ void *implementor = generic->GetValue();
+ if (!implementor)
return ret_val;
+
+ if (!g_swig_mighthavechildren_provider)
+ return ret_val;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_mighthavechildren_provider(implementor);
+ }
+
+ return ret_val;
}
-ConstString
-ScriptInterpreterPython::GetSyntheticTypeName (const StructuredData::ObjectSP &implementor_sp)
-{
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+lldb::ValueObjectSP ScriptInterpreterPython::GetSyntheticValue(
+ const StructuredData::ObjectSP &implementor_sp) {
+ lldb::ValueObjectSP ret_val(nullptr);
- static char callee_name[] = "get_type_name";
+ if (!implementor_sp)
+ return ret_val;
- ConstString ret_val;
- bool got_string = false;
- std::string buffer;
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ void *implementor = generic->GetValue();
+ if (!implementor)
+ return ret_val;
- if (!implementor_sp)
- return ret_val;
-
- StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
- if (!generic)
- return ret_val;
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)generic->GetValue());
- if (!implementor.IsAllocated())
- return ret_val;
-
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- if (!pmeth.IsAllocated())
- return ret_val;
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
- return ret_val;
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr));
-
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
-
- if (py_return.IsAllocated() && PythonString::Check(py_return.get()))
- {
- PythonString py_string(PyRefType::Borrowed, py_return.get());
- llvm::StringRef return_data(py_string.GetString());
- if (!return_data.empty())
- {
- buffer.assign(return_data.data(), return_data.size());
- got_string = true;
- }
- }
-
- if (got_string)
- ret_val.SetCStringWithLength(buffer.c_str(), buffer.size());
-
+ if (!g_swig_getvalue_provider || !g_swig_cast_to_sbvalue ||
+ !g_swig_get_valobj_sp_from_sbvalue)
return ret_val;
-}
-bool
-ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
- Process* process,
- std::string& output,
- Error& error)
-{
- bool ret_val;
- if (!process)
- {
- error.SetErrorString("no process");
- return false;
- }
- if (!impl_function || !impl_function[0])
- {
- error.SetErrorString("no function to execute");
- return false;
- }
- if (!g_swig_run_script_keyword_process)
- {
- error.SetErrorString("internal helper function missing");
- return false;
- }
- {
- ProcessSP process_sp(process->shared_from_this());
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_run_script_keyword_process (impl_function, m_dictionary_name.c_str(), process_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ void *child_ptr = g_swig_getvalue_provider(implementor);
+ if (child_ptr != nullptr && child_ptr != Py_None) {
+ lldb::SBValue *sb_value_ptr =
+ (lldb::SBValue *)g_swig_cast_to_sbvalue(child_ptr);
+ if (sb_value_ptr == nullptr)
+ Py_XDECREF(child_ptr);
+ else
+ ret_val = g_swig_get_valobj_sp_from_sbvalue(sb_value_ptr);
+ } else {
+ Py_XDECREF(child_ptr);
}
- return ret_val;
+ }
+
+ return ret_val;
}
-bool
-ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
- Thread* thread,
- std::string& output,
- Error& error)
-{
- bool ret_val;
- if (!thread)
- {
- error.SetErrorString("no thread");
- return false;
- }
- if (!impl_function || !impl_function[0])
- {
- error.SetErrorString("no function to execute");
- return false;
- }
- if (!g_swig_run_script_keyword_thread)
- {
- error.SetErrorString("internal helper function missing");
- return false;
- }
- {
- ThreadSP thread_sp(thread->shared_from_this());
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_run_script_keyword_thread (impl_function, m_dictionary_name.c_str(), thread_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
- }
+ConstString ScriptInterpreterPython::GetSyntheticTypeName(
+ const StructuredData::ObjectSP &implementor_sp) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ static char callee_name[] = "get_type_name";
+
+ ConstString ret_val;
+ bool got_string = false;
+ std::string buffer;
+
+ if (!implementor_sp)
return ret_val;
-}
-bool
-ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
- Target* target,
- std::string& output,
- Error& error)
-{
- bool ret_val;
- if (!target)
- {
- error.SetErrorString("no thread");
- return false;
- }
- if (!impl_function || !impl_function[0])
- {
- error.SetErrorString("no function to execute");
- return false;
- }
- if (!g_swig_run_script_keyword_target)
- {
- error.SetErrorString("internal helper function missing");
- return false;
- }
- {
- TargetSP target_sp(target->shared_from_this());
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_run_script_keyword_target (impl_function, m_dictionary_name.c_str(), target_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
- }
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)generic->GetValue());
+ if (!implementor.IsAllocated())
return ret_val;
-}
-bool
-ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
- StackFrame* frame,
- std::string& output,
- Error& error)
-{
- bool ret_val;
- if (!frame)
- {
- error.SetErrorString("no frame");
- return false;
- }
- if (!impl_function || !impl_function[0])
- {
- error.SetErrorString("no function to execute");
- return false;
- }
- if (!g_swig_run_script_keyword_frame)
- {
- error.SetErrorString("internal helper function missing");
- return false;
- }
- {
- StackFrameSP frame_sp(frame->shared_from_this());
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_run_script_keyword_frame (impl_function, m_dictionary_name.c_str(), frame_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
- }
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
return ret_val;
-}
-
-bool
-ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
- ValueObject *value,
- std::string& output,
- Error& error)
-{
- bool ret_val;
- if (!value)
- {
- error.SetErrorString("no value");
- return false;
- }
- if (!impl_function || !impl_function[0])
- {
- error.SetErrorString("no function to execute");
- return false;
- }
- if (!g_swig_run_script_keyword_value)
- {
- error.SetErrorString("internal helper function missing");
- return false;
- }
- {
- ValueObjectSP value_sp(value->GetSP());
- Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = g_swig_run_script_keyword_value (impl_function, m_dictionary_name.c_str(), value_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
- }
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
return ret_val;
-}
+ }
-uint64_t replace_all(std::string& str, const std::string& oldStr, const std::string& newStr)
-{
- size_t pos = 0;
- uint64_t matches = 0;
- while((pos = str.find(oldStr, pos)) != std::string::npos)
- {
- matches++;
- str.replace(pos, oldStr.length(), newStr);
- pos += newStr.length();
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
+ PythonString py_string(PyRefType::Borrowed, py_return.get());
+ llvm::StringRef return_data(py_string.GetString());
+ if (!return_data.empty()) {
+ buffer.assign(return_data.data(), return_data.size());
+ got_string = true;
}
- return matches;
+ }
+
+ if (got_string)
+ ret_val.SetCStringWithLength(buffer.c_str(), buffer.size());
+
+ return ret_val;
}
-bool
-ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_reload, bool init_session, lldb_private::Error &error,
- StructuredData::ObjectSP *module_sp)
-{
- if (!pathname || !pathname[0])
- {
+bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
+ Process *process,
+ std::string &output,
+ Error &error) {
+ bool ret_val;
+ if (!process) {
+ error.SetErrorString("no process");
+ return false;
+ }
+ if (!impl_function || !impl_function[0]) {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
+ if (!g_swig_run_script_keyword_process) {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+ {
+ ProcessSP process_sp(process->shared_from_this());
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_run_script_keyword_process(
+ impl_function, m_dictionary_name.c_str(), process_sp, output);
+ if (!ret_val)
+ error.SetErrorString("python script evaluation failed");
+ }
+ return ret_val;
+}
+
+bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
+ Thread *thread,
+ std::string &output,
+ Error &error) {
+ bool ret_val;
+ if (!thread) {
+ error.SetErrorString("no thread");
+ return false;
+ }
+ if (!impl_function || !impl_function[0]) {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
+ if (!g_swig_run_script_keyword_thread) {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+ {
+ ThreadSP thread_sp(thread->shared_from_this());
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_run_script_keyword_thread(
+ impl_function, m_dictionary_name.c_str(), thread_sp, output);
+ if (!ret_val)
+ error.SetErrorString("python script evaluation failed");
+ }
+ return ret_val;
+}
+
+bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
+ Target *target,
+ std::string &output,
+ Error &error) {
+ bool ret_val;
+ if (!target) {
+ error.SetErrorString("no thread");
+ return false;
+ }
+ if (!impl_function || !impl_function[0]) {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
+ if (!g_swig_run_script_keyword_target) {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+ {
+ TargetSP target_sp(target->shared_from_this());
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_run_script_keyword_target(
+ impl_function, m_dictionary_name.c_str(), target_sp, output);
+ if (!ret_val)
+ error.SetErrorString("python script evaluation failed");
+ }
+ return ret_val;
+}
+
+bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
+ StackFrame *frame,
+ std::string &output,
+ Error &error) {
+ bool ret_val;
+ if (!frame) {
+ error.SetErrorString("no frame");
+ return false;
+ }
+ if (!impl_function || !impl_function[0]) {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
+ if (!g_swig_run_script_keyword_frame) {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+ {
+ StackFrameSP frame_sp(frame->shared_from_this());
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_run_script_keyword_frame(
+ impl_function, m_dictionary_name.c_str(), frame_sp, output);
+ if (!ret_val)
+ error.SetErrorString("python script evaluation failed");
+ }
+ return ret_val;
+}
+
+bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
+ ValueObject *value,
+ std::string &output,
+ Error &error) {
+ bool ret_val;
+ if (!value) {
+ error.SetErrorString("no value");
+ return false;
+ }
+ if (!impl_function || !impl_function[0]) {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
+ if (!g_swig_run_script_keyword_value) {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+ {
+ ValueObjectSP value_sp(value->GetSP());
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_run_script_keyword_value(
+ impl_function, m_dictionary_name.c_str(), value_sp, output);
+ if (!ret_val)
+ error.SetErrorString("python script evaluation failed");
+ }
+ return ret_val;
+}
+
+uint64_t replace_all(std::string &str, const std::string &oldStr,
+ const std::string &newStr) {
+ size_t pos = 0;
+ uint64_t matches = 0;
+ while ((pos = str.find(oldStr, pos)) != std::string::npos) {
+ matches++;
+ str.replace(pos, oldStr.length(), newStr);
+ pos += newStr.length();
+ }
+ return matches;
+}
+
+bool ScriptInterpreterPython::LoadScriptingModule(
+ const char *pathname, bool can_reload, bool init_session,
+ lldb_private::Error &error, StructuredData::ObjectSP *module_sp) {
+ if (!pathname || !pathname[0]) {
+ error.SetErrorString("invalid pathname");
+ return false;
+ }
+
+ if (!g_swig_call_module_init) {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+
+ lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
+
+ {
+ FileSpec target_file(pathname, true);
+ std::string basename(target_file.GetFilename().GetCString());
+
+ StreamString command_stream;
+
+ // Before executing Python code, lock the GIL.
+ Locker py_lock(this, Locker::AcquireLock |
+ (init_session ? Locker::InitSession : 0) |
+ Locker::NoSTDIN,
+ Locker::FreeAcquiredLock |
+ (init_session ? Locker::TearDownSession : 0));
+
+ if (target_file.GetFileType() == FileSpec::eFileTypeInvalid ||
+ target_file.GetFileType() == FileSpec::eFileTypeUnknown) {
+ // if not a valid file of any sort, check if it might be a filename still
+ // dot can't be used but / and \ can, and if either is found, reject
+ if (strchr(pathname, '\\') || strchr(pathname, '/')) {
error.SetErrorString("invalid pathname");
return false;
- }
-
- if (!g_swig_call_module_init)
- {
- error.SetErrorString("internal helper function missing");
+ }
+ basename = pathname; // not a filename, probably a package of some sort,
+ // let it go through
+ } else if (target_file.GetFileType() == FileSpec::eFileTypeDirectory ||
+ target_file.GetFileType() == FileSpec::eFileTypeRegular ||
+ target_file.GetFileType() == FileSpec::eFileTypeSymbolicLink) {
+ std::string directory = target_file.GetDirectory().GetCString();
+ replace_all(directory, "\\", "\\\\");
+ replace_all(directory, "'", "\\'");
+
+ // now make sure that Python has "directory" in the search path
+ StreamString command_stream;
+ command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
+ "sys.path.insert(1,'%s');\n\n",
+ directory.c_str(), directory.c_str());
+ bool syspath_retval =
+ ExecuteMultipleLines(command_stream.GetData(),
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false))
+ .Success();
+ if (!syspath_retval) {
+ error.SetErrorString("Python sys.path handling failed");
return false;
+ }
+
+ // strip .py or .pyc extension
+ ConstString extension = target_file.GetFileNameExtension();
+ if (extension) {
+ if (::strcmp(extension.GetCString(), "py") == 0)
+ basename.resize(basename.length() - 3);
+ else if (::strcmp(extension.GetCString(), "pyc") == 0)
+ basename.resize(basename.length() - 4);
+ }
+ } else {
+ error.SetErrorString("no known way to import this module specification");
+ return false;
+ }
+
+ // check if the module is already import-ed
+ command_stream.Clear();
+ command_stream.Printf("sys.modules.__contains__('%s')", basename.c_str());
+ bool does_contain = false;
+ // this call will succeed if the module was ever imported in any Debugger in
+ // the lifetime of the process
+ // in which this LLDB framework is living
+ bool was_imported_globally =
+ (ExecuteOneLineWithReturn(
+ command_stream.GetData(),
+ ScriptInterpreterPython::eScriptReturnTypeBool, &does_contain,
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false)) &&
+ does_contain);
+ // this call will fail if the module was not imported in this Debugger
+ // before
+ command_stream.Clear();
+ command_stream.Printf("sys.getrefcount(%s)", basename.c_str());
+ bool was_imported_locally = GetSessionDictionary()
+ .GetItemForKey(PythonString(basename))
+ .IsAllocated();
+
+ bool was_imported = (was_imported_globally || was_imported_locally);
+
+ if (was_imported == true && can_reload == false) {
+ error.SetErrorString("module already imported");
+ return false;
+ }
+
+ // now actually do the import
+ command_stream.Clear();
+
+ if (was_imported) {
+ if (!was_imported_locally)
+ command_stream.Printf("import %s ; reload_module(%s)", basename.c_str(),
+ basename.c_str());
+ else
+ command_stream.Printf("reload_module(%s)", basename.c_str());
+ } else
+ command_stream.Printf("import %s", basename.c_str());
+
+ error = ExecuteMultipleLines(command_stream.GetData(),
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false));
+ if (error.Fail())
+ return false;
+
+ // if we are here, everything worked
+ // call __lldb_init_module(debugger,dict)
+ if (!g_swig_call_module_init(basename.c_str(), m_dictionary_name.c_str(),
+ debugger_sp)) {
+ error.SetErrorString("calling __lldb_init_module failed");
+ return false;
+ }
+
+ if (module_sp) {
+ // everything went just great, now set the module object
+ command_stream.Clear();
+ command_stream.Printf("%s", basename.c_str());
+ void *module_pyobj = nullptr;
+ if (ExecuteOneLineWithReturn(
+ command_stream.GetData(),
+ ScriptInterpreter::eScriptReturnTypeOpaqueObject,
+ &module_pyobj) &&
+ module_pyobj)
+ module_sp->reset(new StructuredPythonObject(module_pyobj));
}
-
- lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
- {
- FileSpec target_file(pathname, true);
- std::string basename(target_file.GetFilename().GetCString());
-
- StreamString command_stream;
-
- // Before executing Python code, lock the GIL.
- Locker py_lock (this,
- Locker::AcquireLock | (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN,
- Locker::FreeAcquiredLock | (init_session ? Locker::TearDownSession : 0));
-
- if (target_file.GetFileType() == FileSpec::eFileTypeInvalid ||
- target_file.GetFileType() == FileSpec::eFileTypeUnknown)
- {
- // if not a valid file of any sort, check if it might be a filename still
- // dot can't be used but / and \ can, and if either is found, reject
- if (strchr(pathname,'\\') || strchr(pathname,'/'))
- {
- error.SetErrorString("invalid pathname");
- return false;
- }
- basename = pathname; // not a filename, probably a package of some sort, let it go through
- }
- else if (target_file.GetFileType() == FileSpec::eFileTypeDirectory ||
- target_file.GetFileType() == FileSpec::eFileTypeRegular ||
- target_file.GetFileType() == FileSpec::eFileTypeSymbolicLink)
- {
- std::string directory = target_file.GetDirectory().GetCString();
- replace_all(directory, "\\", "\\\\");
- replace_all(directory, "'", "\\'");
-
- // now make sure that Python has "directory" in the search path
- StreamString command_stream;
- command_stream.Printf("if not (sys.path.__contains__('%s')):\n sys.path.insert(1,'%s');\n\n",
- directory.c_str(),
- directory.c_str());
- bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)).Success();
- if (!syspath_retval)
- {
- error.SetErrorString("Python sys.path handling failed");
- return false;
- }
+ return true;
+ }
+}
- // strip .py or .pyc extension
- ConstString extension = target_file.GetFileNameExtension();
- if (extension)
- {
- if (::strcmp(extension.GetCString(), "py") == 0)
- basename.resize(basename.length()-3);
- else if(::strcmp(extension.GetCString(), "pyc") == 0)
- basename.resize(basename.length()-4);
- }
- }
- else
- {
- error.SetErrorString("no known way to import this module specification");
- return false;
- }
-
- // check if the module is already import-ed
- command_stream.Clear();
- command_stream.Printf("sys.modules.__contains__('%s')",basename.c_str());
- bool does_contain = false;
- // this call will succeed if the module was ever imported in any Debugger in the lifetime of the process
- // in which this LLDB framework is living
- bool was_imported_globally = (ExecuteOneLineWithReturn(command_stream.GetData(),
- ScriptInterpreterPython::eScriptReturnTypeBool,
- &does_contain,
- ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)) && does_contain);
- // this call will fail if the module was not imported in this Debugger before
- command_stream.Clear();
- command_stream.Printf("sys.getrefcount(%s)",basename.c_str());
- bool was_imported_locally = GetSessionDictionary().GetItemForKey(PythonString(basename)).IsAllocated();
-
- bool was_imported = (was_imported_globally || was_imported_locally);
-
- if (was_imported == true && can_reload == false)
- {
- error.SetErrorString("module already imported");
- return false;
- }
+bool ScriptInterpreterPython::IsReservedWord(const char *word) {
+ if (!word || !word[0])
+ return false;
- // now actually do the import
- command_stream.Clear();
-
- if (was_imported)
- {
- if (!was_imported_locally)
- command_stream.Printf("import %s ; reload_module(%s)",basename.c_str(),basename.c_str());
- else
- command_stream.Printf("reload_module(%s)",basename.c_str());
- }
- else
- command_stream.Printf("import %s", basename.c_str());
-
- error = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false));
- if (error.Fail())
- return false;
-
- // if we are here, everything worked
- // call __lldb_init_module(debugger,dict)
- if (!g_swig_call_module_init (basename.c_str(),
- m_dictionary_name.c_str(),
- debugger_sp))
- {
- error.SetErrorString("calling __lldb_init_module failed");
- return false;
- }
-
- if (module_sp)
- {
- // everything went just great, now set the module object
- command_stream.Clear();
- command_stream.Printf("%s",basename.c_str());
- void* module_pyobj = nullptr;
- if (ExecuteOneLineWithReturn(command_stream.GetData(),ScriptInterpreter::eScriptReturnTypeOpaqueObject,&module_pyobj) && module_pyobj)
- module_sp->reset(new StructuredPythonObject(module_pyobj));
- }
-
- return true;
- }
+ llvm::StringRef word_sr(word);
+
+ // filter out a few characters that would just confuse us
+ // and that are clearly not keyword material anyway
+ if (word_sr.find_first_of("'\"") != llvm::StringRef::npos)
+ return false;
+
+ StreamString command_stream;
+ command_stream.Printf("keyword.iskeyword('%s')", word);
+ bool result;
+ ExecuteScriptOptions options;
+ options.SetEnableIO(false);
+ options.SetMaskoutErrors(true);
+ options.SetSetLLDBGlobals(false);
+ if (ExecuteOneLineWithReturn(command_stream.GetData(),
+ ScriptInterpreter::eScriptReturnTypeBool,
+ &result, options))
+ return result;
+ return false;
}
-bool
-ScriptInterpreterPython::IsReservedWord (const char* word)
-{
- if (!word || !word[0])
- return false;
-
- llvm::StringRef word_sr(word);
+ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler(
+ lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro)
+ : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
+ m_old_asynch(debugger_sp->GetAsyncExecution()) {
+ if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
+ m_debugger_sp->SetAsyncExecution(false);
+ else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
+ m_debugger_sp->SetAsyncExecution(true);
+}
- // filter out a few characters that would just confuse us
- // and that are clearly not keyword material anyway
- if (word_sr.find_first_of("'\"") != llvm::StringRef::npos)
- return false;
-
- StreamString command_stream;
- command_stream.Printf("keyword.iskeyword('%s')", word);
- bool result;
- ExecuteScriptOptions options;
- options.SetEnableIO(false);
- options.SetMaskoutErrors(true);
- options.SetSetLLDBGlobals(false);
- if (ExecuteOneLineWithReturn(command_stream.GetData(), ScriptInterpreter::eScriptReturnTypeBool, &result, options))
- return result;
- return false;
+ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler() {
+ if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
+ m_debugger_sp->SetAsyncExecution(m_old_asynch);
}
-ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
- ScriptedCommandSynchronicity synchro) :
- m_debugger_sp(debugger_sp),
- m_synch_wanted(synchro),
- m_old_asynch(debugger_sp->GetAsyncExecution())
-{
- if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
- m_debugger_sp->SetAsyncExecution(false);
- else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
- m_debugger_sp->SetAsyncExecution(true);
-}
-
-ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler()
-{
- if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
- m_debugger_sp->SetAsyncExecution(m_old_asynch);
-}
-
-bool
-ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
- const char* args,
- ScriptedCommandSynchronicity synchronicity,
- lldb_private::CommandReturnObject& cmd_retobj,
- Error& error,
- const lldb_private::ExecutionContext& exe_ctx)
-{
- if (!impl_function)
- {
- error.SetErrorString("no function to execute");
- return false;
- }
-
- if (!g_swig_call_command)
- {
- error.SetErrorString("no helper function to run scripted commands");
- return false;
- }
-
- lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
- lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
-
- if (!debugger_sp.get())
- {
- error.SetErrorString("invalid Debugger pointer");
- return false;
- }
-
- bool ret_val = false;
-
- std::string err_msg;
+bool ScriptInterpreterPython::RunScriptBasedCommand(
+ const char *impl_function, const char *args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject &cmd_retobj, Error &error,
+ const lldb_private::ExecutionContext &exe_ctx) {
+ if (!impl_function) {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
- Locker::FreeLock | Locker::TearDownSession);
-
- SynchronicityHandler synch_handler(debugger_sp,
- synchronicity);
-
- ret_val = g_swig_call_command (impl_function,
- m_dictionary_name.c_str(),
- debugger_sp,
- args,
- cmd_retobj,
- exe_ctx_ref_sp);
- }
-
- if (!ret_val)
- error.SetErrorString("unable to execute script function");
- else
- error.Clear();
-
- return ret_val;
+ if (!g_swig_call_command) {
+ error.SetErrorString("no helper function to run scripted commands");
+ return false;
+ }
+
+ lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
+
+ if (!debugger_sp.get()) {
+ error.SetErrorString("invalid Debugger pointer");
+ return false;
+ }
+
+ bool ret_val = false;
+
+ std::string err_msg;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession |
+ (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
+ Locker::FreeLock | Locker::TearDownSession);
+
+ SynchronicityHandler synch_handler(debugger_sp, synchronicity);
+
+ ret_val =
+ g_swig_call_command(impl_function, m_dictionary_name.c_str(),
+ debugger_sp, args, cmd_retobj, exe_ctx_ref_sp);
+ }
+
+ if (!ret_val)
+ error.SetErrorString("unable to execute script function");
+ else
+ error.Clear();
+
+ return ret_val;
}
-bool
-ScriptInterpreterPython::RunScriptBasedCommand (StructuredData::GenericSP impl_obj_sp,
- const char* args,
- ScriptedCommandSynchronicity synchronicity,
- lldb_private::CommandReturnObject& cmd_retobj,
- Error& error,
- const lldb_private::ExecutionContext& exe_ctx)
-{
- if (!impl_obj_sp || !impl_obj_sp->IsValid())
- {
- error.SetErrorString("no function to execute");
- return false;
- }
-
- if (!g_swig_call_command_object)
- {
- error.SetErrorString("no helper function to run scripted commands");
- return false;
- }
-
- lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
- lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
-
- if (!debugger_sp.get())
- {
- error.SetErrorString("invalid Debugger pointer");
- return false;
- }
-
- bool ret_val = false;
-
- std::string err_msg;
-
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
- Locker::FreeLock | Locker::TearDownSession);
-
- SynchronicityHandler synch_handler(debugger_sp,
- synchronicity);
-
- ret_val = g_swig_call_command_object (impl_obj_sp->GetValue(),
- debugger_sp,
- args,
- cmd_retobj,
- exe_ctx_ref_sp);
- }
-
- if (!ret_val)
- error.SetErrorString("unable to execute script function");
- else
- error.Clear();
+bool ScriptInterpreterPython::RunScriptBasedCommand(
+ StructuredData::GenericSP impl_obj_sp, const char *args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject &cmd_retobj, Error &error,
+ const lldb_private::ExecutionContext &exe_ctx) {
+ if (!impl_obj_sp || !impl_obj_sp->IsValid()) {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
- return ret_val;
+ if (!g_swig_call_command_object) {
+ error.SetErrorString("no helper function to run scripted commands");
+ return false;
+ }
+
+ lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
+
+ if (!debugger_sp.get()) {
+ error.SetErrorString("invalid Debugger pointer");
+ return false;
+ }
+
+ bool ret_val = false;
+
+ std::string err_msg;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession |
+ (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
+ Locker::FreeLock | Locker::TearDownSession);
+
+ SynchronicityHandler synch_handler(debugger_sp, synchronicity);
+
+ ret_val = g_swig_call_command_object(impl_obj_sp->GetValue(), debugger_sp,
+ args, cmd_retobj, exe_ctx_ref_sp);
+ }
+
+ if (!ret_val)
+ error.SetErrorString("unable to execute script function");
+ else
+ error.Clear();
+
+ return ret_val;
}
// in Python, a special attribute __doc__ contains the docstring
// for an object (function, method, class, ...) if any is defined
// Otherwise, the attribute's value is None
-bool
-ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string& dest)
-{
- dest.clear();
- if (!item || !*item)
- return false;
- std::string command(item);
- command += ".__doc__";
-
- char* result_ptr = nullptr; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
-
- if (ExecuteOneLineWithReturn (command.c_str(),
- ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
- &result_ptr,
- ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)))
- {
- if (result_ptr)
- dest.assign(result_ptr);
- return true;
- }
- else
- {
- StreamString str_stream;
- str_stream.Printf("Function %s was not found. Containing module might be missing.",item);
- dest.assign(str_stream.GetData());
- return false;
- }
+bool ScriptInterpreterPython::GetDocumentationForItem(const char *item,
+ std::string &dest) {
+ dest.clear();
+ if (!item || !*item)
+ return false;
+ std::string command(item);
+ command += ".__doc__";
+
+ char *result_ptr = nullptr; // Python is going to point this to valid data if
+ // ExecuteOneLineWithReturn returns successfully
+
+ if (ExecuteOneLineWithReturn(
+ command.c_str(), ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
+ &result_ptr,
+ ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) {
+ if (result_ptr)
+ dest.assign(result_ptr);
+ return true;
+ } else {
+ StreamString str_stream;
+ str_stream.Printf(
+ "Function %s was not found. Containing module might be missing.", item);
+ dest = str_stream.GetString();
+ return false;
+ }
}
-bool
-ScriptInterpreterPython::GetShortHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
- std::string& dest)
-{
- bool got_string = false;
- dest.clear();
-
- Locker py_lock (this,
- Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- static char callee_name[] = "get_short_help";
-
- if (!cmd_obj_sp)
- return false;
+bool ScriptInterpreterPython::GetShortHelpForCommandObject(
+ StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
+ bool got_string = false;
+ dest.clear();
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)cmd_obj_sp->GetValue());
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- if (!implementor.IsAllocated())
- return false;
+ static char callee_name[] = "get_short_help";
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+ if (!cmd_obj_sp)
+ return false;
- if (PyErr_Occurred())
- PyErr_Clear();
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)cmd_obj_sp->GetValue());
- if (!pmeth.IsAllocated())
- return false;
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
- return false;
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+ if (!implementor.IsAllocated())
+ return false;
+
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
- // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return false;
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
+ PyErr_Clear();
+ return false;
+ }
- if (py_return.IsAllocated() && PythonString::Check(py_return.get()))
- {
- PythonString py_string(PyRefType::Borrowed, py_return.get());
- llvm::StringRef return_data(py_string.GetString());
- dest.assign(return_data.data(), return_data.size());
- got_string = true;
- }
- return got_string;
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
+ PythonString py_string(PyRefType::Borrowed, py_return.get());
+ llvm::StringRef return_data(py_string.GetString());
+ dest.assign(return_data.data(), return_data.size());
+ got_string = true;
+ }
+ return got_string;
}
-uint32_t
-ScriptInterpreterPython::GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp)
-{
- uint32_t result = 0;
-
- Locker py_lock (this,
- Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- static char callee_name[] = "get_flags";
-
- if (!cmd_obj_sp)
- return result;
+uint32_t ScriptInterpreterPython::GetFlagsForCommandObject(
+ StructuredData::GenericSP cmd_obj_sp) {
+ uint32_t result = 0;
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)cmd_obj_sp->GetValue());
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- if (!implementor.IsAllocated())
- return result;
+ static char callee_name[] = "get_flags";
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+ if (!cmd_obj_sp)
+ return result;
- if (PyErr_Occurred())
- PyErr_Clear();
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)cmd_obj_sp->GetValue());
- if (!pmeth.IsAllocated())
- return result;
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
- return result;
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+ if (!implementor.IsAllocated())
+ return result;
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
- if (py_return.IsAllocated() && PythonInteger::Check(py_return.get()))
- {
- PythonInteger int_value(PyRefType::Borrowed, py_return.get());
- result = int_value.GetInteger();
- }
-
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return result;
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
return result;
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return.IsAllocated() && PythonInteger::Check(py_return.get())) {
+ PythonInteger int_value(PyRefType::Borrowed, py_return.get());
+ result = int_value.GetInteger();
+ }
+
+ return result;
}
-bool
-ScriptInterpreterPython::GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
- std::string& dest)
-{
- bool got_string = false;
- dest.clear();
-
- Locker py_lock (this,
- Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- static char callee_name[] = "get_long_help";
-
- if (!cmd_obj_sp)
- return false;
+bool ScriptInterpreterPython::GetLongHelpForCommandObject(
+ StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
+ bool got_string = false;
+ dest.clear();
- PythonObject implementor(PyRefType::Borrowed, (PyObject *)cmd_obj_sp->GetValue());
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- if (!implementor.IsAllocated())
- return false;
+ static char callee_name[] = "get_long_help";
- PythonObject pmeth(PyRefType::Owned, PyObject_GetAttrString(implementor.get(), callee_name));
+ if (!cmd_obj_sp)
+ return false;
- if (PyErr_Occurred())
- PyErr_Clear();
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)cmd_obj_sp->GetValue());
- if (!pmeth.IsAllocated())
- return false;
-
- if (PyCallable_Check(pmeth.get()) == 0)
- {
- if (PyErr_Occurred())
- PyErr_Clear();
-
- return false;
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+ if (!implementor.IsAllocated())
+ return false;
- // if it fails, print the error but otherwise go on
+ PythonObject pmeth(PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), callee_name));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return false;
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
+ PyErr_Clear();
- if (py_return.IsAllocated() && PythonString::Check(py_return.get()))
- {
- PythonString str(PyRefType::Borrowed, py_return.get());
- llvm::StringRef str_data(str.GetString());
- dest.assign(str_data.data(), str_data.size());
- got_string = true;
- }
-
- return got_string;
-}
+ return false;
+ }
-std::unique_ptr<ScriptInterpreterLocker>
-ScriptInterpreterPython::AcquireInterpreterLock ()
-{
- std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
- Locker::FreeLock | Locker::TearDownSession));
- return py_lock;
-}
-
-void
-ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callback,
- SWIGBreakpointCallbackFunction swig_breakpoint_callback,
- SWIGWatchpointCallbackFunction swig_watchpoint_callback,
- SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
- SWIGPythonCreateSyntheticProvider swig_synthetic_script,
- SWIGPythonCreateCommandObject swig_create_cmd,
- SWIGPythonCalculateNumChildren swig_calc_children,
- SWIGPythonGetChildAtIndex swig_get_child_index,
- SWIGPythonGetIndexOfChildWithName swig_get_index_child,
- SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
- SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
- SWIGPythonUpdateSynthProviderInstance swig_update_provider,
- SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
- SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
- SWIGPythonCallCommand swig_call_command,
- SWIGPythonCallCommandObject swig_call_command_object,
- SWIGPythonCallModuleInit swig_call_module_init,
- SWIGPythonCreateOSPlugin swig_create_os_plugin,
- SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
- SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
- SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
- SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
- SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
- SWIGPython_GetDynamicSetting swig_plugin_get,
- SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
- SWIGPythonCallThreadPlan swig_call_thread_plan)
-{
- g_swig_init_callback = swig_init_callback;
- g_swig_breakpoint_callback = swig_breakpoint_callback;
- g_swig_watchpoint_callback = swig_watchpoint_callback;
- g_swig_typescript_callback = swig_typescript_callback;
- g_swig_synthetic_script = swig_synthetic_script;
- g_swig_create_cmd = swig_create_cmd;
- g_swig_calc_children = swig_calc_children;
- g_swig_get_child_index = swig_get_child_index;
- g_swig_get_index_child = swig_get_index_child;
- g_swig_cast_to_sbvalue = swig_cast_to_sbvalue;
- g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
- g_swig_update_provider = swig_update_provider;
- g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
- g_swig_getvalue_provider = swig_getvalue_provider;
- g_swig_call_command = swig_call_command;
- 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_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;
- g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
- g_swig_run_script_keyword_value = swig_run_script_keyword_value;
- 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;
-}
-
-void
-ScriptInterpreterPython::InitializePrivate ()
-{
- if (g_initialized)
- return;
-
- g_initialized = true;
-
- Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
-
- // RAII-based initialization which correctly handles multiple-initialization, version-
- // specific differences among Python 2 and Python 3, and saving and restoring various
- // other pieces of state that can get mucked with during initialization.
- InitializePythonRAII initialize_guard;
-
- if (g_swig_init_callback)
- g_swig_init_callback ();
-
- // Update the path python uses to search for modules to include the current directory.
-
- PyRun_SimpleString ("import sys");
- AddToSysPath(AddLocation::End, ".");
-
- FileSpec file_spec;
- // Don't denormalize paths when calling file_spec.GetPath(). On platforms that use
- // a backslash as the path separator, this will result in executing python code containing
- // paths with unescaped backslashes. But Python also accepts forward slashes, so to make
- // life easier we just use that.
- if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
- AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
- if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
- AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
-
- PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line");
-}
-
-void
-ScriptInterpreterPython::AddToSysPath(AddLocation location, std::string path)
-{
- std::string path_copy;
-
- std::string statement;
- if (location == AddLocation::Beginning)
- {
- statement.assign("sys.path.insert(0,\"");
- statement.append (path);
- statement.append ("\")");
- }
- else
- {
- statement.assign("sys.path.append(\"");
- statement.append(path);
- statement.append("\")");
- }
- PyRun_SimpleString (statement.c_str());
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // right now we know this function exists and is callable..
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
+ PythonString str(PyRefType::Borrowed, py_return.get());
+ llvm::StringRef str_data(str.GetString());
+ dest.assign(str_data.data(), str_data.size());
+ got_string = true;
+ }
+
+ return got_string;
}
+std::unique_ptr<ScriptInterpreterLocker>
+ScriptInterpreterPython::AcquireInterpreterLock() {
+ std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
+ this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
+ Locker::FreeLock | Locker::TearDownSession));
+ return py_lock;
+}
+
+void ScriptInterpreterPython::InitializeInterpreter(
+ SWIGInitCallback swig_init_callback,
+ SWIGBreakpointCallbackFunction swig_breakpoint_callback,
+ SWIGWatchpointCallbackFunction swig_watchpoint_callback,
+ SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
+ SWIGPythonCreateSyntheticProvider swig_synthetic_script,
+ SWIGPythonCreateCommandObject swig_create_cmd,
+ SWIGPythonCalculateNumChildren swig_calc_children,
+ SWIGPythonGetChildAtIndex swig_get_child_index,
+ SWIGPythonGetIndexOfChildWithName swig_get_index_child,
+ SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue,
+ SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
+ SWIGPythonUpdateSynthProviderInstance swig_update_provider,
+ SWIGPythonMightHaveChildrenSynthProviderInstance
+ swig_mighthavechildren_provider,
+ SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
+ SWIGPythonCallCommand swig_call_command,
+ SWIGPythonCallCommandObject swig_call_command_object,
+ SWIGPythonCallModuleInit swig_call_module_init,
+ SWIGPythonCreateOSPlugin swig_create_os_plugin,
+ SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
+ SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
+ SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
+ SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
+ SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
+ SWIGPython_GetDynamicSetting swig_plugin_get,
+ SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
+ SWIGPythonCallThreadPlan swig_call_thread_plan) {
+ g_swig_init_callback = swig_init_callback;
+ g_swig_breakpoint_callback = swig_breakpoint_callback;
+ g_swig_watchpoint_callback = swig_watchpoint_callback;
+ g_swig_typescript_callback = swig_typescript_callback;
+ g_swig_synthetic_script = swig_synthetic_script;
+ g_swig_create_cmd = swig_create_cmd;
+ g_swig_calc_children = swig_calc_children;
+ g_swig_get_child_index = swig_get_child_index;
+ g_swig_get_index_child = swig_get_index_child;
+ g_swig_cast_to_sbvalue = swig_cast_to_sbvalue;
+ g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
+ g_swig_update_provider = swig_update_provider;
+ g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
+ g_swig_getvalue_provider = swig_getvalue_provider;
+ g_swig_call_command = swig_call_command;
+ 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_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;
+ g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
+ g_swig_run_script_keyword_value = swig_run_script_keyword_value;
+ 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;
+}
+
+void ScriptInterpreterPython::InitializePrivate() {
+ if (g_initialized)
+ return;
-//void
-//ScriptInterpreterPython::Terminate ()
+ g_initialized = true;
+
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION);
+
+ // RAII-based initialization which correctly handles multiple-initialization,
+ // version-
+ // specific differences among Python 2 and Python 3, and saving and restoring
+ // various
+ // other pieces of state that can get mucked with during initialization.
+ InitializePythonRAII initialize_guard;
+
+ if (g_swig_init_callback)
+ g_swig_init_callback();
+
+ // Update the path python uses to search for modules to include the current
+ // directory.
+
+ PyRun_SimpleString("import sys");
+ AddToSysPath(AddLocation::End, ".");
+
+ FileSpec file_spec;
+ // Don't denormalize paths when calling file_spec.GetPath(). On platforms
+ // that use
+ // a backslash as the path separator, this will result in executing python
+ // code containing
+ // paths with unescaped backslashes. But Python also accepts forward slashes,
+ // so to make
+ // life easier we just use that.
+ if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
+ AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
+ AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
+
+ PyRun_SimpleString("sys.dont_write_bytecode = 1; import "
+ "lldb.embedded_interpreter; from "
+ "lldb.embedded_interpreter import run_python_interpreter; "
+ "from lldb.embedded_interpreter import run_one_line");
+}
+
+void ScriptInterpreterPython::AddToSysPath(AddLocation location,
+ std::string path) {
+ std::string path_copy;
+
+ std::string statement;
+ if (location == AddLocation::Beginning) {
+ statement.assign("sys.path.insert(0,\"");
+ statement.append(path);
+ statement.append("\")");
+ } else {
+ statement.assign("sys.path.append(\"");
+ statement.append(path);
+ statement.append("\")");
+ }
+ PyRun_SimpleString(statement.c_str());
+}
+
+// void
+// ScriptInterpreterPython::Terminate ()
//{
-// // We are intentionally NOT calling Py_Finalize here (this would be the logical place to call it). Calling
-// // Py_Finalize here causes test suite runs to seg fault: The test suite runs in Python. It registers
-// // SBDebugger::Terminate to be called 'at_exit'. When the test suite Python harness finishes up, it calls
-// // Py_Finalize, which calls all the 'at_exit' registered functions. SBDebugger::Terminate calls Debugger::Terminate,
-// // which calls lldb::Terminate, which calls ScriptInterpreter::Terminate, which calls
-// // ScriptInterpreterPython::Terminate. So if we call Py_Finalize here, we end up with Py_Finalize being called from
+// // We are intentionally NOT calling Py_Finalize here (this would be the
+// logical place to call it). Calling
+// // Py_Finalize here causes test suite runs to seg fault: The test suite
+// runs in Python. It registers
+// // SBDebugger::Terminate to be called 'at_exit'. When the test suite
+// Python harness finishes up, it calls
+// // Py_Finalize, which calls all the 'at_exit' registered functions.
+// SBDebugger::Terminate calls Debugger::Terminate,
+// // which calls lldb::Terminate, which calls ScriptInterpreter::Terminate,
+// which calls
+// // ScriptInterpreterPython::Terminate. So if we call Py_Finalize here, we
+// end up with Py_Finalize being called from
// // within Py_Finalize, which results in a seg fault.
// //
-// // Since this function only gets called when lldb is shutting down and going away anyway, the fact that we don't
-// // actually call Py_Finalize should not cause any problems (everything should shut down/go away anyway when the
+// // Since this function only gets called when lldb is shutting down and
+// going away anyway, the fact that we don't
+// // actually call Py_Finalize should not cause any problems (everything
+// should shut down/go away anyway when the
// // process exits).
// //
//// Py_Finalize ();
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index 263bb527d833..7b0e1b000d6f 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -24,585 +24,543 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "PythonDataObjects.h"
+#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/IOHandler.h"
-#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Host/Terminal.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/lldb-private.h"
class IOHandlerPythonInterpreter;
namespace lldb_private {
-
-class ScriptInterpreterPython :
- public ScriptInterpreter,
- public IOHandlerDelegateMultiline
-{
+
+class ScriptInterpreterPython : public ScriptInterpreter,
+ public IOHandlerDelegateMultiline {
public:
+ class CommandDataPython : public BreakpointOptions::CommandData {
+ public:
+ CommandDataPython() : BreakpointOptions::CommandData() {
+ interpreter = lldb::eScriptLanguagePython;
+ }
+ };
+
#if PY_MAJOR_VERSION >= 3
- typedef PyObject*(*SWIGInitCallback) (void);
+ typedef PyObject *(*SWIGInitCallback)(void);
#else
- typedef void(*SWIGInitCallback) (void);
+ typedef void (*SWIGInitCallback)(void);
#endif
- typedef bool (*SWIGBreakpointCallbackFunction) (const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& frame_sp,
- const lldb::BreakpointLocationSP &bp_loc_sp);
-
- typedef bool (*SWIGWatchpointCallbackFunction) (const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& frame_sp,
- const lldb::WatchpointSP &wp_sp);
-
- typedef bool (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
- void *session_dictionary,
- const lldb::ValueObjectSP& valobj_sp,
- void** pyfunct_wrapper,
- const lldb::TypeSummaryOptionsSP& options,
- std::string& retval);
-
- typedef void* (*SWIGPythonCreateSyntheticProvider) (const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ValueObjectSP& valobj_sp);
-
- typedef void* (*SWIGPythonCreateCommandObject) (const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::DebuggerSP debugger_sp);
-
- typedef void* (*SWIGPythonCreateScriptedThreadPlan) (const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ThreadPlanSP& thread_plan_sp);
-
- typedef bool (*SWIGPythonCallThreadPlan) (void *implementor, const char *method_name, Event *event_sp, bool &got_error);
-
- typedef void* (*SWIGPythonCreateOSPlugin) (const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP& process_sp);
-
- typedef size_t (*SWIGPythonCalculateNumChildren) (void *implementor, uint32_t max);
-
- typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx);
-
- typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name);
-
- typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data);
-
- typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue) (void* data);
-
- typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data);
-
- typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data);
-
- typedef void* (*SWIGPythonGetValueSynthProviderInstance) (void *implementor);
-
- typedef bool (*SWIGPythonCallCommand) (const char *python_function_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger,
- const char* args,
- lldb_private::CommandReturnObject& cmd_retobj,
- lldb::ExecutionContextRefSP exe_ctx_ref_sp);
-
- typedef bool (*SWIGPythonCallCommandObject) (void *implementor,
- lldb::DebuggerSP& debugger,
- const char* args,
- lldb_private::CommandReturnObject& cmd_retobj,
- lldb::ExecutionContextRefSP exe_ctx_ref_sp);
-
- typedef bool (*SWIGPythonCallModuleInit) (const char *python_module_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger);
-
- typedef bool (*SWIGPythonScriptKeyword_Process) (const char* python_function_name,
- const char* session_dictionary_name,
- lldb::ProcessSP& process,
- std::string& output);
-
- typedef bool (*SWIGPythonScriptKeyword_Thread) (const char* python_function_name,
- const char* session_dictionary_name,
- lldb::ThreadSP& thread,
- std::string& output);
-
- typedef bool (*SWIGPythonScriptKeyword_Target) (const char* python_function_name,
- const char* session_dictionary_name,
- lldb::TargetSP& target,
- std::string& output);
+ typedef bool (*SWIGBreakpointCallbackFunction)(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &frame_sp,
+ const lldb::BreakpointLocationSP &bp_loc_sp);
- typedef bool (*SWIGPythonScriptKeyword_Frame) (const char* python_function_name,
- const char* session_dictionary_name,
- lldb::StackFrameSP& frame,
- std::string& output);
-
- typedef bool (*SWIGPythonScriptKeyword_Value) (const char* python_function_name,
- const char* session_dictionary_name,
- lldb::ValueObjectSP& value,
- std::string& output);
-
- typedef void* (*SWIGPython_GetDynamicSetting) (void* module,
- const char* setting,
- const lldb::TargetSP& target_sp);
-
- friend class ::IOHandlerPythonInterpreter;
-
- ScriptInterpreterPython (CommandInterpreter &interpreter);
-
- ~ScriptInterpreterPython() override;
-
- bool
- Interrupt() override;
-
- bool
- ExecuteOneLine (const char *command,
- CommandReturnObject *result,
- const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
-
- void
- ExecuteInterpreterLoop () override;
-
- bool
- ExecuteOneLineWithReturn (const char *in_string,
- ScriptInterpreter::ScriptReturnType return_type,
- void *ret_value,
- const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
-
- lldb_private::Error
- ExecuteMultipleLines (const char *in_string,
- const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
-
- Error
- ExportFunctionDefinitionToInterpreter (StringList &function_def) override;
-
- bool
- GenerateTypeScriptFunction(StringList &input, std::string& output, const void* name_token = nullptr) override;
-
- bool
- GenerateTypeSynthClass(StringList &input, std::string& output, const void* name_token = nullptr) override;
-
- bool
- GenerateTypeSynthClass(const char* oneliner, std::string& output, const void* name_token = nullptr) override;
-
- // use this if the function code is just a one-liner script
- bool
- GenerateTypeScriptFunction(const char* oneliner, std::string& output, const void* name_token = nullptr) override;
-
- bool
- GenerateScriptAliasFunction (StringList &input, std::string& output) override;
-
- StructuredData::ObjectSP CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) override;
-
- StructuredData::GenericSP CreateScriptCommandObject (const char *class_name) override;
-
- StructuredData::ObjectSP CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan) override;
-
- bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override;
-
- bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override;
-
- lldb::StateType ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) override;
-
- StructuredData::GenericSP OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) override;
-
- StructuredData::DictionarySP OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
-
- StructuredData::ArraySP OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
-
- StructuredData::StringSP OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t thread_id) override;
-
- StructuredData::DictionarySP OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
- lldb::addr_t context) override;
-
- StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error) override;
-
- StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name,
- lldb_private::Error &error) override;
-
- size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, uint32_t max) override;
-
- lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override;
-
- int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) override;
-
- bool UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) override;
-
- bool MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) override;
-
- lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
-
- ConstString GetSyntheticTypeName (const StructuredData::ObjectSP &implementor) override;
-
- bool
- RunScriptBasedCommand(const char* impl_function,
- const char* args,
- ScriptedCommandSynchronicity synchronicity,
- lldb_private::CommandReturnObject& cmd_retobj,
- Error& error,
- const lldb_private::ExecutionContext& exe_ctx) override;
-
- bool
- RunScriptBasedCommand (StructuredData::GenericSP impl_obj_sp,
- const char* args,
- ScriptedCommandSynchronicity synchronicity,
- lldb_private::CommandReturnObject& cmd_retobj,
- Error& error,
- const lldb_private::ExecutionContext& exe_ctx) override;
-
- Error
- GenerateFunction(const char *signature, const StringList &input) override;
-
- Error
- GenerateBreakpointCommandCallbackData (StringList &input, std::string& output) override;
-
- bool
- GenerateWatchpointCommandCallbackData (StringList &input, std::string& output) override;
-
-// static size_t
-// GenerateBreakpointOptionsCommandCallback (void *baton,
-// InputReader &reader,
-// lldb::InputReaderAction notification,
-// const char *bytes,
-// size_t bytes_len);
-//
-// static size_t
-// GenerateWatchpointOptionsCommandCallback (void *baton,
-// InputReader &reader,
-// lldb::InputReaderAction notification,
-// const char *bytes,
-// size_t bytes_len);
-
- static bool
- BreakpointCallbackFunction (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- static bool
- WatchpointCallbackFunction (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t watch_id);
-
- bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp,
- const TypeSummaryOptions &options, std::string &retval) override;
-
- void
- Clear () override;
-
- bool
- GetDocumentationForItem (const char* item, std::string& dest) override;
-
- bool
- GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override;
-
- uint32_t
- GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp) override;
-
- bool
- GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override;
-
- bool
- CheckObjectExists (const char* name) override
- {
- if (!name || !name[0])
- return false;
- std::string temp;
- return GetDocumentationForItem (name,temp);
- }
-
- bool
- RunScriptFormatKeyword (const char* impl_function,
- Process* process,
- std::string& output,
- Error& error) override;
-
- bool
- RunScriptFormatKeyword (const char* impl_function,
- Thread* thread,
- std::string& output,
- Error& error) override;
-
- bool
- RunScriptFormatKeyword (const char* impl_function,
- Target* target,
- std::string& output,
- Error& error) override;
-
- bool
- RunScriptFormatKeyword (const char* impl_function,
- StackFrame* frame,
- std::string& output,
- Error& error) override;
-
- bool
- RunScriptFormatKeyword (const char* impl_function,
- ValueObject* value,
- std::string& output,
- Error& error) override;
-
- bool LoadScriptingModule(const char *filename, bool can_reload, bool init_session, lldb_private::Error &error,
- StructuredData::ObjectSP *module_sp = nullptr) override;
-
- bool
- IsReservedWord (const char* word) override;
-
- std::unique_ptr<ScriptInterpreterLocker>
- AcquireInterpreterLock () override;
-
- void
- CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
- CommandReturnObject &result) override;
-
- void
- CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
- CommandReturnObject &result) override;
-
- /// Set the callback body text into the callback for the breakpoint.
- Error
- SetBreakpointCommandCallback (BreakpointOptions *bp_options,
- const char *callback_body) override;
-
- void
- SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
- const char *function_name) override;
-
- /// Set a one-liner as the callback for the watchpoint.
- void
- SetWatchpointCommandCallback (WatchpointOptions *wp_options,
- const char *oneliner) override;
-
- StringList
- ReadCommandInputFromUser (FILE *in_file);
-
- void ResetOutputFileHandle(FILE *new_fh) override;
-
- static void
- InitializePrivate ();
-
- static void
- InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
- SWIGBreakpointCallbackFunction swig_breakpoint_callback,
- SWIGWatchpointCallbackFunction swig_watchpoint_callback,
- SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
- SWIGPythonCreateSyntheticProvider swig_synthetic_script,
- SWIGPythonCreateCommandObject swig_create_cmd,
- SWIGPythonCalculateNumChildren swig_calc_children,
- SWIGPythonGetChildAtIndex swig_get_child_index,
- SWIGPythonGetIndexOfChildWithName swig_get_index_child,
- SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
- SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
- SWIGPythonUpdateSynthProviderInstance swig_update_provider,
- SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
- SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
- SWIGPythonCallCommand swig_call_command,
- SWIGPythonCallCommandObject swig_call_command_object,
- SWIGPythonCallModuleInit swig_call_module_init,
- SWIGPythonCreateOSPlugin swig_create_os_plugin,
- SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
- SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
- SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
- SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
- SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
- SWIGPython_GetDynamicSetting swig_plugin_get,
- SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
- SWIGPythonCallThreadPlan swig_call_thread_plan);
-
- const char *
- GetDictionaryName ()
- {
- return m_dictionary_name.c_str();
- }
+ typedef bool (*SWIGWatchpointCallbackFunction)(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp);
- PyThreadState *
- GetThreadState()
- {
- return m_command_thread_state;
- }
+ typedef bool (*SWIGPythonTypeScriptCallbackFunction)(
+ const char *python_function_name, void *session_dictionary,
+ const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
+ const lldb::TypeSummaryOptionsSP &options, std::string &retval);
- void
- SetThreadState (PyThreadState *s)
- {
- if (s)
- m_command_thread_state = s;
- }
+ typedef void *(*SWIGPythonCreateSyntheticProvider)(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::ValueObjectSP &valobj_sp);
- //----------------------------------------------------------------------
- // IOHandlerDelegate
- //----------------------------------------------------------------------
- void
- IOHandlerActivated (IOHandler &io_handler) override;
-
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb::ScriptInterpreterSP
- CreateInstance(CommandInterpreter &interpreter);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- class Locker : public ScriptInterpreterLocker
- {
- public:
- enum OnEntry
- {
- AcquireLock = 0x0001,
- InitSession = 0x0002,
- InitGlobals = 0x0004,
- NoSTDIN = 0x0008
- };
-
- enum OnLeave
- {
- FreeLock = 0x0001,
- FreeAcquiredLock = 0x0002, // do not free the lock if we already held it when calling constructor
- TearDownSession = 0x0004
- };
-
- Locker(ScriptInterpreterPython *py_interpreter = nullptr,
- uint16_t on_entry = AcquireLock | InitSession,
- uint16_t on_leave = FreeLock | TearDownSession,
- FILE *in = nullptr,
- FILE *out = nullptr,
- FILE *err = nullptr);
-
- ~Locker () override;
-
- private:
- bool
- DoAcquireLock ();
-
- bool
- DoInitSession (uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
-
- bool
- DoFreeLock ();
-
- bool
- DoTearDownSession ();
-
- static void
- ReleasePythonLock ();
-
- bool m_teardown_session;
- ScriptInterpreterPython *m_python_interpreter;
-// FILE* m_tmp_fh;
- PyGILState_STATE m_GILState;
- };
+ typedef void *(*SWIGPythonCreateCommandObject)(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::DebuggerSP debugger_sp);
-protected:
- class SynchronicityHandler
- {
- private:
- lldb::DebuggerSP m_debugger_sp;
- ScriptedCommandSynchronicity m_synch_wanted;
- bool m_old_asynch;
-
- public:
- SynchronicityHandler(lldb::DebuggerSP,
- ScriptedCommandSynchronicity);
-
- ~SynchronicityHandler();
+ typedef void *(*SWIGPythonCreateScriptedThreadPlan)(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::ThreadPlanSP &thread_plan_sp);
+
+ typedef bool (*SWIGPythonCallThreadPlan)(void *implementor,
+ const char *method_name,
+ Event *event_sp, bool &got_error);
+
+ typedef void *(*SWIGPythonCreateOSPlugin)(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp);
+
+ typedef size_t (*SWIGPythonCalculateNumChildren)(void *implementor,
+ uint32_t max);
+
+ typedef void *(*SWIGPythonGetChildAtIndex)(void *implementor, uint32_t idx);
+
+ typedef int (*SWIGPythonGetIndexOfChildWithName)(void *implementor,
+ const char *child_name);
+
+ typedef void *(*SWIGPythonCastPyObjectToSBValue)(void *data);
+
+ typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue)(
+ void *data);
+
+ typedef bool (*SWIGPythonUpdateSynthProviderInstance)(void *data);
+
+ typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance)(void *data);
+
+ typedef void *(*SWIGPythonGetValueSynthProviderInstance)(void *implementor);
+
+ typedef bool (*SWIGPythonCallCommand)(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::DebuggerSP &debugger, const char *args,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+ typedef bool (*SWIGPythonCallCommandObject)(
+ void *implementor, lldb::DebuggerSP &debugger, const char *args,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+ typedef bool (*SWIGPythonCallModuleInit)(const char *python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP &debugger);
+
+ typedef bool (*SWIGPythonScriptKeyword_Process)(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::ProcessSP &process, std::string &output);
+
+ typedef bool (*SWIGPythonScriptKeyword_Thread)(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::ThreadSP &thread, std::string &output);
+
+ typedef bool (*SWIGPythonScriptKeyword_Target)(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::TargetSP &target, std::string &output);
+
+ typedef bool (*SWIGPythonScriptKeyword_Frame)(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::StackFrameSP &frame, std::string &output);
+
+ typedef bool (*SWIGPythonScriptKeyword_Value)(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::ValueObjectSP &value, std::string &output);
+
+ typedef void *(*SWIGPython_GetDynamicSetting)(
+ void *module, const char *setting, const lldb::TargetSP &target_sp);
+
+ friend class ::IOHandlerPythonInterpreter;
+
+ ScriptInterpreterPython(CommandInterpreter &interpreter);
+
+ ~ScriptInterpreterPython() override;
+
+ bool Interrupt() override;
+
+ bool ExecuteOneLine(
+ const char *command, CommandReturnObject *result,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
+
+ void ExecuteInterpreterLoop() override;
+
+ bool ExecuteOneLineWithReturn(
+ const char *in_string, ScriptInterpreter::ScriptReturnType return_type,
+ void *ret_value,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
+
+ lldb_private::Error ExecuteMultipleLines(
+ const char *in_string,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
+
+ Error
+ ExportFunctionDefinitionToInterpreter(StringList &function_def) override;
+
+ bool GenerateTypeScriptFunction(StringList &input, std::string &output,
+ const void *name_token = nullptr) override;
+
+ bool GenerateTypeSynthClass(StringList &input, std::string &output,
+ const void *name_token = nullptr) override;
+
+ bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
+ const void *name_token = nullptr) override;
+
+ // use this if the function code is just a one-liner script
+ bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
+ const void *name_token = nullptr) override;
+
+ bool GenerateScriptAliasFunction(StringList &input,
+ std::string &output) override;
+
+ StructuredData::ObjectSP
+ CreateSyntheticScriptedProvider(const char *class_name,
+ lldb::ValueObjectSP valobj) override;
+
+ StructuredData::GenericSP
+ CreateScriptCommandObject(const char *class_name) override;
+
+ StructuredData::ObjectSP
+ CreateScriptedThreadPlan(const char *class_name,
+ lldb::ThreadPlanSP thread_plan) override;
+
+ bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
+ Event *event,
+ bool &script_error) override;
+
+ bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
+ Event *event, bool &script_error) override;
+
+ bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
+ bool &script_error) override;
+
+ lldb::StateType
+ ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
+ bool &script_error) override;
+
+ StructuredData::GenericSP
+ OSPlugin_CreatePluginObject(const char *class_name,
+ lldb::ProcessSP process_sp) override;
+
+ StructuredData::DictionarySP
+ OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
+
+ StructuredData::ArraySP
+ OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
+
+ StructuredData::StringSP
+ OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
+ lldb::tid_t thread_id) override;
+
+ StructuredData::DictionarySP
+ OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
+ lldb::tid_t tid, lldb::addr_t context) override;
+
+ StructuredData::ObjectSP
+ LoadPluginModule(const FileSpec &file_spec,
+ lldb_private::Error &error) override;
+
+ StructuredData::DictionarySP
+ GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
+ const char *setting_name,
+ lldb_private::Error &error) override;
+
+ size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
+ uint32_t max) override;
+
+ lldb::ValueObjectSP
+ GetChildAtIndex(const StructuredData::ObjectSP &implementor,
+ uint32_t idx) override;
+
+ int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
+ const char *child_name) override;
+
+ bool UpdateSynthProviderInstance(
+ const StructuredData::ObjectSP &implementor) override;
+
+ bool MightHaveChildrenSynthProviderInstance(
+ const StructuredData::ObjectSP &implementor) override;
+
+ lldb::ValueObjectSP
+ GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
+
+ ConstString
+ GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
+
+ bool
+ RunScriptBasedCommand(const char *impl_function, const char *args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ Error &error,
+ const lldb_private::ExecutionContext &exe_ctx) override;
+
+ bool
+ RunScriptBasedCommand(StructuredData::GenericSP impl_obj_sp, const char *args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ Error &error,
+ const lldb_private::ExecutionContext &exe_ctx) override;
+
+ Error GenerateFunction(const char *signature,
+ const StringList &input) override;
+
+ Error GenerateBreakpointCommandCallbackData(StringList &input,
+ std::string &output) override;
+
+ bool GenerateWatchpointCommandCallbackData(StringList &input,
+ std::string &output) override;
+
+ // static size_t
+ // GenerateBreakpointOptionsCommandCallback (void *baton,
+ // InputReader &reader,
+ // lldb::InputReaderAction
+ // notification,
+ // const char *bytes,
+ // size_t bytes_len);
+ //
+ // static size_t
+ // GenerateWatchpointOptionsCommandCallback (void *baton,
+ // InputReader &reader,
+ // lldb::InputReaderAction
+ // notification,
+ // const char *bytes,
+ // size_t bytes_len);
+
+ static bool BreakpointCallbackFunction(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ static bool WatchpointCallbackFunction(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t watch_id);
+
+ bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
+ StructuredData::ObjectSP &callee_wrapper_sp,
+ const TypeSummaryOptions &options,
+ std::string &retval) override;
+
+ void Clear() override;
+
+ bool GetDocumentationForItem(const char *item, std::string &dest) override;
+
+ bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
+ std::string &dest) override;
+
+ uint32_t
+ GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
+
+ bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
+ std::string &dest) override;
+
+ bool CheckObjectExists(const char *name) override {
+ if (!name || !name[0])
+ return false;
+ std::string temp;
+ return GetDocumentationForItem(name, temp);
+ }
+
+ bool RunScriptFormatKeyword(const char *impl_function, Process *process,
+ std::string &output, Error &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
+ std::string &output, Error &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, Target *target,
+ std::string &output, Error &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
+ std::string &output, Error &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
+ std::string &output, Error &error) override;
+
+ bool
+ LoadScriptingModule(const char *filename, bool can_reload, bool init_session,
+ lldb_private::Error &error,
+ StructuredData::ObjectSP *module_sp = nullptr) override;
+
+ bool IsReservedWord(const char *word) override;
+
+ std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
+
+ void CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) override;
+
+ void
+ CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
+ CommandReturnObject &result) override;
+
+ /// Set the callback body text into the callback for the breakpoint.
+ Error SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+ const char *callback_body) override;
+
+ void SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options,
+ const char *function_name) override;
+
+ /// This one is for deserialization:
+ Error SetBreakpointCommandCallback(
+ BreakpointOptions *bp_options,
+ std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
+
+ /// Set a one-liner as the callback for the watchpoint.
+ void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
+ const char *oneliner) override;
+
+ StringList ReadCommandInputFromUser(FILE *in_file);
+
+ void ResetOutputFileHandle(FILE *new_fh) override;
+
+ static void InitializePrivate();
+
+ static void InitializeInterpreter(
+ SWIGInitCallback python_swig_init_callback,
+ SWIGBreakpointCallbackFunction swig_breakpoint_callback,
+ SWIGWatchpointCallbackFunction swig_watchpoint_callback,
+ SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
+ SWIGPythonCreateSyntheticProvider swig_synthetic_script,
+ SWIGPythonCreateCommandObject swig_create_cmd,
+ SWIGPythonCalculateNumChildren swig_calc_children,
+ SWIGPythonGetChildAtIndex swig_get_child_index,
+ SWIGPythonGetIndexOfChildWithName swig_get_index_child,
+ SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue,
+ SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
+ SWIGPythonUpdateSynthProviderInstance swig_update_provider,
+ SWIGPythonMightHaveChildrenSynthProviderInstance
+ swig_mighthavechildren_provider,
+ SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
+ SWIGPythonCallCommand swig_call_command,
+ SWIGPythonCallCommandObject swig_call_command_object,
+ SWIGPythonCallModuleInit swig_call_module_init,
+ SWIGPythonCreateOSPlugin swig_create_os_plugin,
+ SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
+ SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
+ SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
+ SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
+ SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
+ SWIGPython_GetDynamicSetting swig_plugin_get,
+ SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
+ SWIGPythonCallThreadPlan swig_call_thread_plan);
+
+ const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
+
+ PyThreadState *GetThreadState() { return m_command_thread_state; }
+
+ void SetThreadState(PyThreadState *s) {
+ if (s)
+ m_command_thread_state = s;
+ }
+
+ //----------------------------------------------------------------------
+ // IOHandlerDelegate
+ //----------------------------------------------------------------------
+ void IOHandlerActivated(IOHandler &io_handler) override;
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ScriptInterpreterSP
+ CreateInstance(CommandInterpreter &interpreter);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ class Locker : public ScriptInterpreterLocker {
+ public:
+ enum OnEntry {
+ AcquireLock = 0x0001,
+ InitSession = 0x0002,
+ InitGlobals = 0x0004,
+ NoSTDIN = 0x0008
};
-
- enum class AddLocation
- {
- Beginning,
- End
+
+ enum OnLeave {
+ FreeLock = 0x0001,
+ FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
+ // when calling constructor
+ TearDownSession = 0x0004
};
- static void AddToSysPath(AddLocation location, std::string path);
+ Locker(ScriptInterpreterPython *py_interpreter = nullptr,
+ uint16_t on_entry = AcquireLock | InitSession,
+ uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
+ FILE *out = nullptr, FILE *err = nullptr);
- bool
- EnterSession(uint16_t on_entry_flags,
- FILE *in,
- FILE *out,
- FILE *err);
+ ~Locker() override;
- void
- LeaveSession();
+ private:
+ bool DoAcquireLock();
- void
- SaveTerminalState(int fd);
+ bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
- void
- RestoreTerminalState();
+ bool DoFreeLock();
- uint32_t
- IsExecutingPython () const
- {
- return m_lock_count > 0;
- }
+ bool DoTearDownSession();
- uint32_t
- IncrementLockCount()
- {
- return ++m_lock_count;
- }
+ static void ReleasePythonLock();
- uint32_t
- DecrementLockCount()
- {
- if (m_lock_count > 0)
- --m_lock_count;
- return m_lock_count;
- }
+ bool m_teardown_session;
+ ScriptInterpreterPython *m_python_interpreter;
+ // FILE* m_tmp_fh;
+ PyGILState_STATE m_GILState;
+ };
- enum ActiveIOHandler {
- eIOHandlerNone,
- eIOHandlerBreakpoint,
- eIOHandlerWatchpoint
- };
+protected:
+ class SynchronicityHandler {
+ private:
+ lldb::DebuggerSP m_debugger_sp;
+ ScriptedCommandSynchronicity m_synch_wanted;
+ bool m_old_asynch;
+
+ public:
+ SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity);
+
+ ~SynchronicityHandler();
+ };
+
+ enum class AddLocation { Beginning, End };
+
+ static void AddToSysPath(AddLocation location, std::string path);
+
+ bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
+
+ void LeaveSession();
+
+ void SaveTerminalState(int fd);
+
+ void RestoreTerminalState();
+
+ uint32_t IsExecutingPython() const { return m_lock_count > 0; }
+
+ uint32_t IncrementLockCount() { return ++m_lock_count; }
+
+ uint32_t DecrementLockCount() {
+ if (m_lock_count > 0)
+ --m_lock_count;
+ return m_lock_count;
+ }
+
+ enum ActiveIOHandler {
+ eIOHandlerNone,
+ eIOHandlerBreakpoint,
+ eIOHandlerWatchpoint
+ };
+
+ PythonObject &GetMainModule();
+
+ PythonDictionary &GetSessionDictionary();
+
+ PythonDictionary &GetSysModuleDictionary();
+
+ bool GetEmbeddedInterpreterModuleObjects();
+
+ bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
+ const char *mode);
- PythonObject &GetMainModule();
-
- PythonDictionary &
- GetSessionDictionary ();
-
- PythonDictionary &
- GetSysModuleDictionary ();
-
- bool
- GetEmbeddedInterpreterModuleObjects ();
-
- bool
- SetStdHandle(File &file, const char *py_name, PythonFile &save_file, const char *mode);
-
- PythonFile m_saved_stdin;
- PythonFile m_saved_stdout;
- PythonFile m_saved_stderr;
- PythonObject m_main_module;
- PythonObject m_lldb_module;
- PythonDictionary m_session_dict;
- PythonDictionary m_sys_module_dict;
- PythonObject m_run_one_line_function;
- PythonObject m_run_one_line_str_global;
- std::string m_dictionary_name;
- TerminalState m_terminal_state;
- ActiveIOHandler m_active_io_handler;
- bool m_session_is_active;
- bool m_pty_slave_is_open;
- bool m_valid_session;
- uint32_t m_lock_count;
- PyThreadState *m_command_thread_state;
+ PythonFile m_saved_stdin;
+ PythonFile m_saved_stdout;
+ PythonFile m_saved_stderr;
+ PythonObject m_main_module;
+ PythonObject m_lldb_module;
+ PythonDictionary m_session_dict;
+ PythonDictionary m_sys_module_dict;
+ PythonObject m_run_one_line_function;
+ PythonObject m_run_one_line_str_global;
+ std::string m_dictionary_name;
+ TerminalState m_terminal_state;
+ ActiveIOHandler m_active_io_handler;
+ bool m_session_is_active;
+ bool m_pty_slave_is_open;
+ bool m_valid_session;
+ uint32_t m_lock_count;
+ PyThreadState *m_command_thread_state;
};
} // namespace lldb_private
diff --git a/source/Plugins/ScriptInterpreter/Python/lldb-python.h b/source/Plugins/ScriptInterpreter/Python/lldb-python.h
index 013492c39bf8..ee13b7a5cd1f 100644
--- a/source/Plugins/ScriptInterpreter/Python/lldb-python.h
+++ b/source/Plugins/ScriptInterpreter/Python/lldb-python.h
@@ -1,4 +1,5 @@
-//===-- lldb-python.h --------------------------------------------*- C++ -*-===//
+//===-- lldb-python.h --------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,11 +11,20 @@
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H
-// Python.h needs to be included before any system headers in order to avoid redefinition of macros
+// Python.h needs to be included before any system headers in order to avoid
+// redefinition of macros
#ifdef LLDB_DISABLE_PYTHON
// Python is disabled in this build
#else
+#include "llvm/Support/Compiler.h"
+#if defined(LLVM_ON_WIN32)
+// If anyone #includes Host/PosixApi.h later, it will try to typedef pid_t. We
+// need to ensure this doesn't happen. At the same time, Python.h will also try
+// to redefine a bunch of stuff that PosixApi.h defines. So define it all now
+// so that PosixApi.h doesn't redefine it.
+#define NO_PID_T
+#endif
#if defined(__linux__)
// features.h will define _POSIX_C_SOURCE if _GNU_SOURCE is defined. This value
// may be different from the value that Python defines it to be which results
diff --git a/source/Plugins/StructuredData/CMakeLists.txt b/source/Plugins/StructuredData/CMakeLists.txt
new file mode 100644
index 000000000000..40d64558482d
--- /dev/null
+++ b/source/Plugins/StructuredData/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(DarwinLog)
+
diff --git a/source/Plugins/StructuredData/DarwinLog/CMakeLists.txt b/source/Plugins/StructuredData/DarwinLog/CMakeLists.txt
new file mode 100644
index 000000000000..ce0e21b4ed33
--- /dev/null
+++ b/source/Plugins/StructuredData/DarwinLog/CMakeLists.txt
@@ -0,0 +1,5 @@
+list(APPEND SOURCES
+ StructuredDataDarwinLog.cpp
+ )
+
+add_lldb_library(lldbPluginStructuredDataDarwinLog ${SOURCES})
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
new file mode 100644
index 000000000000..e459268f5448
--- /dev/null
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -0,0 +1,2018 @@
+//===-- StructuredDataDarwinLog.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "StructuredDataDarwinLog.h"
+
+// C includes
+#include <string.h>
+
+// C++ includes
+#include <sstream>
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/Property.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlanCallOnFunctionExit.h"
+
+#define DARWIN_LOG_TYPE_VALUE "DarwinLog"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#pragma mark -
+#pragma mark Anonymous Namespace
+
+// -----------------------------------------------------------------------------
+// Anonymous namespace
+// -----------------------------------------------------------------------------
+
+namespace sddarwinlog_private {
+const uint64_t NANOS_PER_MICRO = 1000;
+const uint64_t NANOS_PER_MILLI = NANOS_PER_MICRO * 1000;
+const uint64_t NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
+const uint64_t NANOS_PER_MINUTE = NANOS_PER_SECOND * 60;
+const uint64_t NANOS_PER_HOUR = NANOS_PER_MINUTE * 60;
+
+static bool DEFAULT_FILTER_FALLTHROUGH_ACCEPTS = true;
+
+//------------------------------------------------------------------
+/// Global, sticky enable switch. If true, the user has explicitly
+/// run the enable command. When a process launches or is attached to,
+/// we will enable DarwinLog if either the settings for auto-enable is
+/// on, or if the user had explicitly run enable at some point prior
+/// to the launch/attach.
+//------------------------------------------------------------------
+static bool s_is_explicitly_enabled;
+
+class EnableOptions;
+using EnableOptionsSP = std::shared_ptr<EnableOptions>;
+
+using OptionsMap =
+ std::map<DebuggerWP, EnableOptionsSP, std::owner_less<DebuggerWP>>;
+
+static OptionsMap &GetGlobalOptionsMap() {
+ static OptionsMap s_options_map;
+ return s_options_map;
+}
+
+static std::mutex &GetGlobalOptionsMapLock() {
+ static std::mutex s_options_map_lock;
+ return s_options_map_lock;
+}
+
+EnableOptionsSP GetGlobalEnableOptions(const DebuggerSP &debugger_sp) {
+ if (!debugger_sp)
+ return EnableOptionsSP();
+
+ std::lock_guard<std::mutex> locker(GetGlobalOptionsMapLock());
+ OptionsMap &options_map = GetGlobalOptionsMap();
+ DebuggerWP debugger_wp(debugger_sp);
+ auto find_it = options_map.find(debugger_wp);
+ if (find_it != options_map.end())
+ return find_it->second;
+ else
+ return EnableOptionsSP();
+}
+
+void SetGlobalEnableOptions(const DebuggerSP &debugger_sp,
+ const EnableOptionsSP &options_sp) {
+ std::lock_guard<std::mutex> locker(GetGlobalOptionsMapLock());
+ OptionsMap &options_map = GetGlobalOptionsMap();
+ DebuggerWP debugger_wp(debugger_sp);
+ auto find_it = options_map.find(debugger_wp);
+ if (find_it != options_map.end())
+ find_it->second = options_sp;
+ else
+ options_map.insert(std::make_pair(debugger_wp, options_sp));
+}
+
+#pragma mark -
+#pragma mark Settings Handling
+
+//------------------------------------------------------------------
+/// Code to handle the StructuredDataDarwinLog settings
+//------------------------------------------------------------------
+
+static PropertyDefinition g_properties[] = {
+ {
+ "enable-on-startup", // name
+ OptionValue::eTypeBoolean, // type
+ true, // global
+ false, // default uint value
+ nullptr, // default cstring value
+ nullptr, // enum values
+ "Enable Darwin os_log collection when debugged process is launched "
+ "or attached." // description
+ },
+ {
+ "auto-enable-options", // name
+ OptionValue::eTypeString, // type
+ true, // global
+ 0, // default uint value
+ "", // default cstring value
+ nullptr, // 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 };
+
+class StructuredDataDarwinLogProperties : public Properties {
+public:
+ static ConstString &GetSettingName() {
+ static ConstString g_setting_name("darwin-log");
+ return g_setting_name;
+ }
+
+ StructuredDataDarwinLogProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~StructuredDataDarwinLogProperties() {}
+
+ bool GetEnableOnStartup() const {
+ const uint32_t idx = ePropertyEnableOnStartup;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
+ }
+
+ llvm::StringRef GetAutoEnableOptions() const {
+ const uint32_t idx = ePropertyAutoEnableOptions;
+ return m_collection_sp->GetPropertyAtIndexAsString(
+ nullptr, idx, g_properties[idx].default_cstr_value);
+ }
+
+ const char *GetLoggingModuleName() const { return "libsystem_trace.dylib"; }
+};
+
+using StructuredDataDarwinLogPropertiesSP =
+ std::shared_ptr<StructuredDataDarwinLogProperties>;
+
+static const StructuredDataDarwinLogPropertiesSP &GetGlobalProperties() {
+ static StructuredDataDarwinLogPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new StructuredDataDarwinLogProperties());
+ return g_settings_sp;
+}
+
+const char *const s_filter_attributes[] = {
+ "activity", // current activity
+ "activity-chain", // entire activity chain, each level separated by ':'
+ "category", // category of the log message
+ "message", // message contents, fully expanded
+ "subsystem" // subsystem of the log message
+
+ // Consider impelmenting this action as it would be cheaper to filter.
+ // "message" requires always formatting the message, which is a waste
+ // of cycles if it ends up being rejected.
+ // "format", // format string used to format message text
+};
+
+static const ConstString &GetDarwinLogTypeName() {
+ static const ConstString s_key_name("DarwinLog");
+ return s_key_name;
+}
+
+static const ConstString &GetLogEventType() {
+ static const ConstString s_event_type("log");
+ return s_event_type;
+}
+
+class FilterRule;
+using FilterRuleSP = std::shared_ptr<FilterRule>;
+
+class FilterRule {
+public:
+ virtual ~FilterRule() {}
+
+ using OperationCreationFunc =
+ std::function<FilterRuleSP(bool accept, size_t attribute_index,
+ const std::string &op_arg, Error &error)>;
+
+ static void RegisterOperation(const ConstString &operation,
+ const OperationCreationFunc &creation_func) {
+ GetCreationFuncMap().insert(std::make_pair(operation, creation_func));
+ }
+
+ static FilterRuleSP CreateRule(bool match_accepts, size_t attribute,
+ const ConstString &operation,
+ const std::string &op_arg, Error &error) {
+ // Find the creation func for this type of filter rule.
+ auto map = GetCreationFuncMap();
+ auto find_it = map.find(operation);
+ if (find_it == map.end()) {
+ error.SetErrorStringWithFormat("unknown filter operation \""
+ "%s\"",
+ operation.GetCString());
+ return FilterRuleSP();
+ }
+
+ return find_it->second(match_accepts, attribute, op_arg, error);
+ }
+
+ StructuredData::ObjectSP Serialize() const {
+ StructuredData::Dictionary *dict_p = new StructuredData::Dictionary();
+
+ // Indicate whether this is an accept or reject rule.
+ dict_p->AddBooleanItem("accept", m_accept);
+
+ // Indicate which attribute of the message this filter references.
+ // This can drop into the rule-specific DoSerialization if we get
+ // to the point where not all FilterRule derived classes work on
+ // an attribute. (e.g. logical and/or and other compound
+ // operations).
+ dict_p->AddStringItem("attribute", s_filter_attributes[m_attribute_index]);
+
+ // Indicate the type of the rule.
+ dict_p->AddStringItem("type", GetOperationType().GetCString());
+
+ // Let the rule add its own specific details here.
+ DoSerialization(*dict_p);
+
+ return StructuredData::ObjectSP(dict_p);
+ }
+
+ virtual void Dump(Stream &stream) const = 0;
+
+ const ConstString &GetOperationType() const { return m_operation; }
+
+protected:
+ FilterRule(bool accept, size_t attribute_index, const ConstString &operation)
+ : m_accept(accept), m_attribute_index(attribute_index),
+ m_operation(operation) {}
+
+ virtual void DoSerialization(StructuredData::Dictionary &dict) const = 0;
+
+ bool GetMatchAccepts() const { return m_accept; }
+
+ const char *GetFilterAttribute() const {
+ return s_filter_attributes[m_attribute_index];
+ }
+
+private:
+ using CreationFuncMap = std::map<ConstString, OperationCreationFunc>;
+
+ static CreationFuncMap &GetCreationFuncMap() {
+ static CreationFuncMap s_map;
+ return s_map;
+ }
+
+ const bool m_accept;
+ const size_t m_attribute_index;
+ const ConstString m_operation;
+};
+
+using FilterRules = std::vector<FilterRuleSP>;
+
+class RegexFilterRule : public FilterRule {
+public:
+ static void RegisterOperation() {
+ FilterRule::RegisterOperation(StaticGetOperation(), CreateOperation);
+ }
+
+ void Dump(Stream &stream) const override {
+ stream.Printf("%s %s regex %s", GetMatchAccepts() ? "accept" : "reject",
+ GetFilterAttribute(), m_regex_text.c_str());
+ }
+
+protected:
+ void DoSerialization(StructuredData::Dictionary &dict) const override {
+ dict.AddStringItem("regex", m_regex_text);
+ }
+
+private:
+ static FilterRuleSP CreateOperation(bool accept, size_t attribute_index,
+ const std::string &op_arg, Error &error) {
+ // We treat the op_arg as a regex. Validate it.
+ if (op_arg.empty()) {
+ error.SetErrorString("regex filter type requires a regex "
+ "argument");
+ return FilterRuleSP();
+ }
+
+ // Instantiate the regex so we can report any errors.
+ auto regex = RegularExpression(op_arg);
+ if (!regex.IsValid()) {
+ char error_text[256];
+ error_text[0] = '\0';
+ regex.GetErrorAsCString(error_text, sizeof(error_text));
+ error.SetErrorString(error_text);
+ return FilterRuleSP();
+ }
+
+ // We passed all our checks, this appears fine.
+ error.Clear();
+ return FilterRuleSP(new RegexFilterRule(accept, attribute_index, op_arg));
+ }
+
+ static const ConstString &StaticGetOperation() {
+ static ConstString s_operation("regex");
+ return s_operation;
+ }
+
+ RegexFilterRule(bool accept, size_t attribute_index,
+ const std::string &regex_text)
+ : FilterRule(accept, attribute_index, StaticGetOperation()),
+ m_regex_text(regex_text) {}
+
+ const std::string m_regex_text;
+};
+
+class ExactMatchFilterRule : public FilterRule {
+public:
+ static void RegisterOperation() {
+ FilterRule::RegisterOperation(StaticGetOperation(), CreateOperation);
+ }
+
+ void Dump(Stream &stream) const override {
+ stream.Printf("%s %s match %s", GetMatchAccepts() ? "accept" : "reject",
+ GetFilterAttribute(), m_match_text.c_str());
+ }
+
+protected:
+ void DoSerialization(StructuredData::Dictionary &dict) const override {
+ dict.AddStringItem("exact_text", m_match_text);
+ }
+
+private:
+ static FilterRuleSP CreateOperation(bool accept, size_t attribute_index,
+ const std::string &op_arg, Error &error) {
+ if (op_arg.empty()) {
+ error.SetErrorString("exact match filter type requires an "
+ "argument containing the text that must "
+ "match the specified message attribute.");
+ return FilterRuleSP();
+ }
+
+ error.Clear();
+ return FilterRuleSP(
+ new ExactMatchFilterRule(accept, attribute_index, op_arg));
+ }
+
+ static const ConstString &StaticGetOperation() {
+ static ConstString s_operation("match");
+ return s_operation;
+ }
+
+ ExactMatchFilterRule(bool accept, size_t attribute_index,
+ const std::string &match_text)
+ : FilterRule(accept, attribute_index, StaticGetOperation()),
+ m_match_text(match_text) {}
+
+ const std::string m_match_text;
+};
+
+static void RegisterFilterOperations() {
+ ExactMatchFilterRule::RegisterOperation();
+ RegexFilterRule::RegisterOperation();
+}
+
+// =========================================================================
+// Commands
+// =========================================================================
+
+// -------------------------------------------------------------------------
+/// Provides the main on-off switch for enabling darwin logging.
+///
+/// It is valid to run the enable command when logging is already enabled.
+/// This resets the logging with whatever settings are currently set.
+// -------------------------------------------------------------------------
+
+static OptionDefinition g_enable_option_table[] = {
+ // Source stream include/exclude options (the first-level filter).
+ // This one should be made as small as possible as everything that
+ // goes through here must be processed by the process monitor.
+ {LLDB_OPT_SET_ALL, false, "any-process", 'a', OptionParser::eNoArgument,
+ nullptr, 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,
+ "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,
+ "Specifies info-level log messages should be included."},
+ {LLDB_OPT_SET_ALL, false, "filter", 'f', OptionParser::eRequiredArgument,
+ nullptr, nullptr, 0, eArgRawInput,
+ // There doesn't appear to be a great way for me to have these
+ // multi-line, formatted tables in help. This looks mostly right
+ // but there are extra linefeeds added at seemingly random spots,
+ // and indentation isn't handled properly on those lines.
+ "Appends a filter rule to the log message filter chain. Multiple "
+ "rules may be added by specifying this option multiple times, "
+ "once per filter rule. Filter rules are processed in the order "
+ "they are specified, with the --no-match-accepts setting used "
+ "for any message that doesn't match one of the rules.\n"
+ "\n"
+ " Filter spec format:\n"
+ "\n"
+ " --filter \"{action} {attribute} {op}\"\n"
+ "\n"
+ " {action} :=\n"
+ " accept |\n"
+ " reject\n"
+ "\n"
+ " {attribute} :=\n"
+ " activity | // message's most-derived activity\n"
+ " activity-chain | // message's {parent}:{child} activity\n"
+ " category | // message's category\n"
+ " message | // message's expanded contents\n"
+ " subsystem | // message's subsystem\n"
+ "\n"
+ " {op} :=\n"
+ " match {exact-match-text} |\n"
+ " regex {search-regex}\n"
+ "\n"
+ "The regex flavor used is the C++ std::regex ECMAScript format. "
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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 "
+ "a log message."},
+ {LLDB_OPT_SET_ALL, false, "category", 'c', OptionParser::eNoArgument,
+ nullptr, nullptr, 0, eArgTypeNone,
+ "Include the category in the the message header when displaying "
+ "a log message."},
+ {LLDB_OPT_SET_ALL, false, "activity-chain", 'C', OptionParser::eNoArgument,
+ nullptr, nullptr, 0, eArgTypeNone,
+ "Include the activity parent-child chain in the the message header "
+ "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,
+ "Shortcut to specify that all header fields should be displayed."}};
+
+class EnableOptions : public Options {
+public:
+ EnableOptions()
+ : Options(), m_include_debug_level(false), m_include_info_level(false),
+ m_include_any_process(false),
+ m_filter_fall_through_accepts(DEFAULT_FILTER_FALLTHROUGH_ACCEPTS),
+ m_echo_to_stderr(false), m_display_timestamp_relative(false),
+ m_display_subsystem(false), m_display_category(false),
+ m_display_activity_chain(false), m_broadcast_events(true),
+ m_live_stream(true), m_filter_rules() {}
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_include_debug_level = false;
+ m_include_info_level = false;
+ m_include_any_process = false;
+ m_filter_fall_through_accepts = DEFAULT_FILTER_FALLTHROUGH_ACCEPTS;
+ m_echo_to_stderr = false;
+ m_display_timestamp_relative = false;
+ m_display_subsystem = false;
+ m_display_category = false;
+ m_display_activity_chain = false;
+ m_broadcast_events = true;
+ m_live_stream = true;
+ m_filter_rules.clear();
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'a':
+ m_include_any_process = true;
+ break;
+
+ case 'A':
+ m_display_timestamp_relative = true;
+ m_display_category = true;
+ m_display_subsystem = true;
+ m_display_activity_chain = true;
+ break;
+
+ case 'b':
+ m_broadcast_events = Args::StringToBoolean(option_arg, true, nullptr);
+ break;
+
+ case 'c':
+ m_display_category = true;
+ break;
+
+ case 'C':
+ m_display_activity_chain = true;
+ break;
+
+ case 'd':
+ m_include_debug_level = true;
+ break;
+
+ case 'e':
+ m_echo_to_stderr = Args::StringToBoolean(option_arg, false, nullptr);
+ break;
+
+ case 'f':
+ return ParseFilterRule(option_arg);
+
+ case 'i':
+ m_include_info_level = true;
+ break;
+
+ case 'l':
+ m_live_stream = Args::StringToBoolean(option_arg, false, nullptr);
+ break;
+
+ case 'n':
+ m_filter_fall_through_accepts =
+ Args::StringToBoolean(option_arg, true, nullptr);
+ break;
+
+ case 'r':
+ m_display_timestamp_relative = true;
+ break;
+
+ case 's':
+ m_display_subsystem = true;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unsupported option '%c'", short_option);
+ }
+ return error;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_enable_option_table);
+ }
+
+ StructuredData::DictionarySP BuildConfigurationData(bool enabled) {
+ StructuredData::DictionarySP config_sp(new StructuredData::Dictionary());
+
+ // Set the basic enabled state.
+ config_sp->AddBooleanItem("enabled", enabled);
+
+ // If we're disabled, there's nothing more to add.
+ if (!enabled)
+ return config_sp;
+
+ // Handle source stream flags.
+ auto source_flags_sp =
+ StructuredData::DictionarySP(new StructuredData::Dictionary());
+ config_sp->AddItem("source-flags", source_flags_sp);
+
+ source_flags_sp->AddBooleanItem("any-process", m_include_any_process);
+ source_flags_sp->AddBooleanItem("debug-level", m_include_debug_level);
+ // The debug-level flag, if set, implies info-level.
+ source_flags_sp->AddBooleanItem("info-level", m_include_info_level ||
+ m_include_debug_level);
+ source_flags_sp->AddBooleanItem("live-stream", m_live_stream);
+
+ // Specify default filter rule (the fall-through)
+ config_sp->AddBooleanItem("filter-fall-through-accepts",
+ m_filter_fall_through_accepts);
+
+ // Handle filter rules
+ if (!m_filter_rules.empty()) {
+ auto json_filter_rules_sp =
+ StructuredData::ArraySP(new StructuredData::Array);
+ config_sp->AddItem("filter-rules", json_filter_rules_sp);
+ for (auto &rule_sp : m_filter_rules) {
+ if (!rule_sp)
+ continue;
+ json_filter_rules_sp->AddItem(rule_sp->Serialize());
+ }
+ }
+ return config_sp;
+ }
+
+ bool GetIncludeDebugLevel() const { return m_include_debug_level; }
+
+ bool GetIncludeInfoLevel() const {
+ // Specifying debug level implies info level.
+ return m_include_info_level || m_include_debug_level;
+ }
+
+ const FilterRules &GetFilterRules() const { return m_filter_rules; }
+
+ bool GetFallthroughAccepts() const { return m_filter_fall_through_accepts; }
+
+ bool GetEchoToStdErr() const { return m_echo_to_stderr; }
+
+ bool GetDisplayTimestampRelative() const {
+ return m_display_timestamp_relative;
+ }
+
+ bool GetDisplaySubsystem() const { return m_display_subsystem; }
+ bool GetDisplayCategory() const { return m_display_category; }
+ bool GetDisplayActivityChain() const { return m_display_activity_chain; }
+
+ bool GetDisplayAnyHeaderFields() const {
+ return m_display_timestamp_relative || m_display_activity_chain ||
+ m_display_subsystem || m_display_category;
+ }
+
+ bool GetBroadcastEvents() const { return m_broadcast_events; }
+
+private:
+ Error ParseFilterRule(llvm::StringRef rule_text) {
+ Error error;
+
+ if (rule_text.empty()) {
+ error.SetErrorString("invalid rule_text");
+ return error;
+ }
+
+ // filter spec format:
+ //
+ // {action} {attribute} {op}
+ //
+ // {action} :=
+ // accept |
+ // reject
+ //
+ // {attribute} :=
+ // category |
+ // subsystem |
+ // activity |
+ // activity-chain |
+ // message |
+ // format
+ //
+ // {op} :=
+ // match {exact-match-text} |
+ // regex {search-regex}
+
+ // Parse action.
+ auto action_end_pos = rule_text.find(" ");
+ if (action_end_pos == std::string::npos) {
+ error.SetErrorStringWithFormat("could not parse filter rule "
+ "action from \"%s\"",
+ rule_text.str().c_str());
+ return error;
+ }
+ auto action = rule_text.substr(0, action_end_pos);
+ bool accept;
+ if (action == "accept")
+ accept = true;
+ else if (action == "reject")
+ accept = false;
+ else {
+ error.SetErrorString("filter action must be \"accept\" or \"deny\"");
+ return error;
+ }
+
+ // parse attribute
+ auto attribute_end_pos = rule_text.find(" ", action_end_pos + 1);
+ if (attribute_end_pos == std::string::npos) {
+ error.SetErrorStringWithFormat("could not parse filter rule "
+ "attribute from \"%s\"",
+ rule_text.str().c_str());
+ return error;
+ }
+ auto attribute = rule_text.substr(action_end_pos + 1,
+ attribute_end_pos - (action_end_pos + 1));
+ auto attribute_index = MatchAttributeIndex(attribute);
+ if (attribute_index < 0) {
+ error.SetErrorStringWithFormat("filter rule attribute unknown: "
+ "%s",
+ attribute.str().c_str());
+ return error;
+ }
+
+ // parse operation
+ auto operation_end_pos = rule_text.find(" ", attribute_end_pos + 1);
+ auto operation = rule_text.substr(
+ attribute_end_pos + 1, operation_end_pos - (attribute_end_pos + 1));
+
+ // add filter spec
+ auto rule_sp =
+ FilterRule::CreateRule(accept, attribute_index, ConstString(operation),
+ rule_text.substr(operation_end_pos + 1), error);
+
+ if (rule_sp && error.Success())
+ m_filter_rules.push_back(rule_sp);
+
+ return error;
+ }
+
+ int MatchAttributeIndex(llvm::StringRef attribute_name) const {
+ for (const auto &Item : llvm::enumerate(s_filter_attributes)) {
+ if (attribute_name == Item.Value)
+ return Item.Index;
+ }
+
+ // We didn't match anything.
+ return -1;
+ }
+
+ bool m_include_debug_level;
+ bool m_include_info_level;
+ bool m_include_any_process;
+ bool m_filter_fall_through_accepts;
+ bool m_echo_to_stderr;
+ bool m_display_timestamp_relative;
+ bool m_display_subsystem;
+ bool m_display_category;
+ bool m_display_activity_chain;
+ bool m_broadcast_events;
+ bool m_live_stream;
+ FilterRules m_filter_rules;
+};
+
+class EnableCommand : public CommandObjectParsed {
+public:
+ EnableCommand(CommandInterpreter &interpreter, bool enable, const char *name,
+ const char *help, const char *syntax)
+ : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable),
+ m_options_sp(enable ? new EnableOptions() : nullptr) {}
+
+protected:
+ void AppendStrictSourcesWarning(CommandReturnObject &result,
+ const char *source_name) {
+ if (!source_name)
+ return;
+
+ // Check if we're *not* using strict sources. If not,
+ // then the user is going to get debug-level info
+ // anyways, probably not what they're expecting.
+ // Unfortunately we can only fix this by adding an
+ // env var, which would have had to have happened
+ // already. Thus, a warning is the best we can do here.
+ StreamString stream;
+ stream.Printf("darwin-log source settings specify to exclude "
+ "%s messages, but setting "
+ "'plugin.structured-data.darwin-log."
+ "strict-sources' is disabled. This process will "
+ "automatically have %s messages included. Enable"
+ " the property and relaunch the target binary to have"
+ " these messages excluded.",
+ source_name, source_name);
+ result.AppendWarning(stream.GetString());
+ }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ // First off, set the global sticky state of enable/disable
+ // based on this command execution.
+ s_is_explicitly_enabled = m_enable;
+
+ // Next, if this is an enable, save off the option data.
+ // We will need it later if a process hasn't been launched or
+ // attached yet.
+ if (m_enable) {
+ // Save off enabled configuration so we can apply these parsed
+ // options the next time an attach or launch occurs.
+ DebuggerSP debugger_sp =
+ GetCommandInterpreter().GetDebugger().shared_from_this();
+ SetGlobalEnableOptions(debugger_sp, m_options_sp);
+ }
+
+ // Now check if we have a running process. If so, we should
+ // instruct the process monitor to enable/disable DarwinLog support
+ // now.
+ Target *target = GetSelectedOrDummyTarget();
+ if (!target) {
+ // No target, so there is nothing more to do right now.
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
+
+ // Grab the active process.
+ auto process_sp = target->GetProcessSP();
+ if (!process_sp) {
+ // No active process, so there is nothing more to do right
+ // now.
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
+
+ // If the process is no longer alive, we can't do this now.
+ // We'll catch it the next time the process is started up.
+ if (!process_sp->IsAlive()) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
+
+ // Get the plugin for the process.
+ auto plugin_sp =
+ process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
+ if (!plugin_sp || (plugin_sp->GetPluginName() !=
+ StructuredDataDarwinLog::GetStaticPluginName())) {
+ result.AppendError("failed to get StructuredDataPlugin for "
+ "the process");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ StructuredDataDarwinLog &plugin =
+ *static_cast<StructuredDataDarwinLog *>(plugin_sp.get());
+
+ if (m_enable) {
+// To do this next part right, we need to track whether we
+// added the proper environment variable at launch time.
+// It is incorrect to assume that we're enabling after launch,
+// and that therefore if we needed the env var set to properly
+// handle the options, that it is set incorrectly. The env var
+// could have been added if this is a re-enable using different
+// arguments. This is a bit tricky as the point where we
+// have to set the env var, we don't yet have a process or the
+// associated darwin-log plugin instance, and thus don't have a
+// great place to stick this knowledge.
+#if 0
+ // Check if we're attempting to disable debug-level or
+ // info-level content but we haven't launched with the magic
+ // env var that suppresses the "always add" of those. In
+ // that scenario, the user is asking *not* to see debug or
+ // info level messages, but will see them anyway. Warn and
+ // show how to correct it.
+ if (!m_options_sp->GetIncludeDebugLevel() &&
+ !GetGlobalProperties()->GetUseStrictSources())
+ {
+ AppendStrictSourcesWarning(result, "debug-level");
+ }
+
+ if (!m_options_sp->GetIncludeInfoLevel() &&
+ !GetGlobalProperties()->GetUseStrictSources())
+ {
+ AppendStrictSourcesWarning(result, "info-level");
+ }
+#endif
+
+ // Hook up the breakpoint for the process that detects when
+ // libtrace has been sufficiently initialized to really start
+ // the os_log stream. This is insurance to assure us that
+ // logging is really enabled. Requesting that logging be
+ // enabled for a process before libtrace is initialized
+ // results in a scenario where no errors occur, but no logging
+ // is captured, either. This step is to eliminate that
+ // possibility.
+ plugin.AddInitCompletionHook(*process_sp.get());
+ }
+
+ // Send configuration to the feature by way of the process.
+ // Construct the options we will use.
+ auto config_sp = m_options_sp->BuildConfigurationData(m_enable);
+ const Error error =
+ process_sp->ConfigureStructuredData(GetDarwinLogTypeName(), config_sp);
+
+ // Report results.
+ if (!error.Success()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ // Our configuration failed, so we're definitely disabled.
+ plugin.SetEnabled(false);
+ } else {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ // Our configuration succeeeded, so we're enabled/disabled
+ // per whichever one this command is setup to do.
+ plugin.SetEnabled(m_enable);
+ }
+ return result.Succeeded();
+ }
+
+ Options *GetOptions() override {
+ // We don't have options when this represents disable.
+ return m_enable ? m_options_sp.get() : nullptr;
+ }
+
+private:
+ const bool m_enable;
+ EnableOptionsSP m_options_sp;
+};
+
+// -------------------------------------------------------------------------
+/// Provides the status command.
+// -------------------------------------------------------------------------
+class StatusCommand : public CommandObjectParsed {
+public:
+ StatusCommand(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "status",
+ "Show whether Darwin log supported is available"
+ " and enabled.",
+ "plugin structured-data darwin-log status") {}
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ auto &stream = result.GetOutputStream();
+
+ // Figure out if we've got a process. If so, we can tell if
+ // DarwinLog is available for that process.
+ Target *target = GetSelectedOrDummyTarget();
+ auto process_sp = target ? target->GetProcessSP() : ProcessSP();
+ if (!target || !process_sp) {
+ stream.PutCString("Availability: unknown (requires process)\n");
+ stream.PutCString("Enabled: not applicable "
+ "(requires process)\n");
+ } else {
+ auto plugin_sp =
+ process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
+ stream.Printf("Availability: %s\n",
+ plugin_sp ? "available" : "unavailable");
+ auto &plugin_name = StructuredDataDarwinLog::GetStaticPluginName();
+ const bool enabled =
+ plugin_sp ? plugin_sp->GetEnabled(plugin_name) : false;
+ stream.Printf("Enabled: %s\n", enabled ? "true" : "false");
+ }
+
+ // Display filter settings.
+ DebuggerSP debugger_sp =
+ GetCommandInterpreter().GetDebugger().shared_from_this();
+ auto options_sp = GetGlobalEnableOptions(debugger_sp);
+ if (!options_sp) {
+ // Nothing more to do.
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+
+ // Print filter rules
+ stream.PutCString("DarwinLog filter rules:\n");
+
+ stream.IndentMore();
+
+ if (options_sp->GetFilterRules().empty()) {
+ stream.Indent();
+ stream.PutCString("none\n");
+ } else {
+ // Print each of the filter rules.
+ int rule_number = 0;
+ for (auto rule_sp : options_sp->GetFilterRules()) {
+ ++rule_number;
+ if (!rule_sp)
+ continue;
+
+ stream.Indent();
+ stream.Printf("%02d: ", rule_number);
+ rule_sp->Dump(stream);
+ stream.PutChar('\n');
+ }
+ }
+ stream.IndentLess();
+
+ // Print no-match handling.
+ stream.Indent();
+ stream.Printf("no-match behavior: %s\n",
+ options_sp->GetFallthroughAccepts() ? "accept" : "reject");
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+};
+
+// -------------------------------------------------------------------------
+/// Provides the darwin-log base command
+// -------------------------------------------------------------------------
+class BaseCommand : public CommandObjectMultiword {
+public:
+ BaseCommand(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "plugin structured-data darwin-log",
+ "Commands for configuring Darwin os_log "
+ "support.",
+ "") {
+ // enable
+ auto enable_help = "Enable Darwin log collection, or re-enable "
+ "with modified configuration.";
+ auto enable_syntax = "plugin structured-data darwin-log enable";
+ auto enable_cmd_sp = CommandObjectSP(
+ new EnableCommand(interpreter,
+ true, // enable
+ "enable", enable_help, enable_syntax));
+ LoadSubCommand("enable", enable_cmd_sp);
+
+ // disable
+ auto disable_help = "Disable Darwin log collection.";
+ auto disable_syntax = "plugin structured-data darwin-log disable";
+ auto disable_cmd_sp = CommandObjectSP(
+ new EnableCommand(interpreter,
+ false, // disable
+ "disable", disable_help, disable_syntax));
+ LoadSubCommand("disable", disable_cmd_sp);
+
+ // status
+ auto status_cmd_sp = CommandObjectSP(new StatusCommand(interpreter));
+ LoadSubCommand("status", status_cmd_sp);
+ }
+};
+
+EnableOptionsSP ParseAutoEnableOptions(Error &error, Debugger &debugger) {
+ // We are abusing the options data model here so that we can parse
+ // options without requiring the Debugger instance.
+
+ // We have an empty execution context at this point. We only want
+ // to parse options, and we don't need any context to do this here.
+ // In fact, we want to be able to parse the enable options before having
+ // any context.
+ ExecutionContext exe_ctx;
+
+ EnableOptionsSP options_sp(new EnableOptions());
+ options_sp->NotifyOptionParsingStarting(&exe_ctx);
+
+ CommandReturnObject result;
+
+ // Parse the arguments.
+ auto options_property_sp =
+ debugger.GetPropertyValue(nullptr, "plugin.structured-data.darwin-log."
+ "auto-enable-options",
+ false, error);
+ if (!error.Success())
+ return EnableOptionsSP();
+ if (!options_property_sp) {
+ error.SetErrorString("failed to find option setting for "
+ "plugin.structured-data.darwin-log.");
+ return EnableOptionsSP();
+ }
+
+ const char *enable_options =
+ options_property_sp->GetAsString()->GetCurrentValue();
+ Args args(enable_options);
+ if (args.GetArgumentCount() > 0) {
+ // Eliminate the initial '--' that would be required to set the
+ // settings that themselves include '-' and/or '--'.
+ const char *first_arg = args.GetArgumentAtIndex(0);
+ if (first_arg && (strcmp(first_arg, "--") == 0))
+ args.Shift();
+ }
+
+ // ParseOptions calls getopt_long_only, which always skips the zero'th item in
+ // the array and starts at position 1,
+ // so we need to push a dummy value into position zero.
+ args.Unshift(llvm::StringRef("dummy_string"));
+ bool require_validation = false;
+ error = args.ParseOptions(*options_sp.get(), &exe_ctx, PlatformSP(),
+ require_validation);
+ if (!error.Success())
+ return EnableOptionsSP();
+
+ if (!options_sp->VerifyOptions(result))
+ return EnableOptionsSP();
+
+ // We successfully parsed and validated the options.
+ return options_sp;
+}
+
+bool RunEnableCommand(CommandInterpreter &interpreter) {
+ StreamString command_stream;
+
+ command_stream << "plugin structured-data darwin-log enable";
+ auto enable_options = GetGlobalProperties()->GetAutoEnableOptions();
+ if (!enable_options.empty()) {
+ command_stream << ' ';
+ command_stream << enable_options;
+ }
+
+ // Run the command.
+ CommandReturnObject return_object;
+ interpreter.HandleCommand(command_stream.GetData(), eLazyBoolNo,
+ return_object);
+ return return_object.Succeeded();
+}
+}
+using namespace sddarwinlog_private;
+
+#pragma mark -
+#pragma mark Public static API
+
+// -----------------------------------------------------------------------------
+// Public static API
+// -----------------------------------------------------------------------------
+
+void StructuredDataDarwinLog::Initialize() {
+ RegisterFilterOperations();
+ PluginManager::RegisterPlugin(
+ GetStaticPluginName(), "Darwin os_log() and os_activity() support",
+ &CreateInstance, &DebuggerInitialize, &FilterLaunchInfo);
+}
+
+void StructuredDataDarwinLog::Terminate() {
+ PluginManager::UnregisterPlugin(&CreateInstance);
+}
+
+const ConstString &StructuredDataDarwinLog::GetStaticPluginName() {
+ static ConstString s_plugin_name("darwin-log");
+ return s_plugin_name;
+}
+
+#pragma mark -
+#pragma mark PluginInterface API
+
+// -----------------------------------------------------------------------------
+// PluginInterface API
+// -----------------------------------------------------------------------------
+
+ConstString StructuredDataDarwinLog::GetPluginName() {
+ return GetStaticPluginName();
+}
+
+uint32_t StructuredDataDarwinLog::GetPluginVersion() { return 1; }
+
+#pragma mark -
+#pragma mark StructuredDataPlugin API
+
+// -----------------------------------------------------------------------------
+// StructuredDataPlugin API
+// -----------------------------------------------------------------------------
+
+bool StructuredDataDarwinLog::SupportsStructuredDataType(
+ const ConstString &type_name) {
+ return type_name == GetDarwinLogTypeName();
+}
+
+void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
+ Process &process, const ConstString &type_name,
+ const StructuredData::ObjectSP &object_sp) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ StreamString json_stream;
+ if (object_sp)
+ object_sp->Dump(json_stream);
+ else
+ json_stream.PutCString("<null>");
+ log->Printf("StructuredDataDarwinLog::%s() called with json: %s",
+ __FUNCTION__, json_stream.GetData());
+ }
+
+ // Ignore empty structured data.
+ if (!object_sp) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() StructuredData object "
+ "is null",
+ __FUNCTION__);
+ return;
+ }
+
+ // Ignore any data that isn't for us.
+ if (type_name != GetDarwinLogTypeName()) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() StructuredData type "
+ "expected to be %s but was %s, ignoring",
+ __FUNCTION__, GetDarwinLogTypeName().AsCString(),
+ type_name.AsCString());
+ return;
+ }
+
+ // Broadcast the structured data event if we have that enabled.
+ // This is the way that the outside world (all clients) get access
+ // to this data. This plugin sets policy as to whether we do that.
+ DebuggerSP debugger_sp = process.GetTarget().GetDebugger().shared_from_this();
+ auto options_sp = GetGlobalEnableOptions(debugger_sp);
+ if (options_sp && options_sp->GetBroadcastEvents()) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() broadcasting event",
+ __FUNCTION__);
+ process.BroadcastStructuredData(object_sp, shared_from_this());
+ }
+
+ // Later, hang on to a configurable amount of these and allow commands
+ // to inspect, including showing backtraces.
+}
+
+static void SetErrorWithJSON(Error &error, const char *message,
+ StructuredData::Object &object) {
+ if (!message) {
+ error.SetErrorString("Internal error: message not set.");
+ return;
+ }
+
+ StreamString object_stream;
+ object.Dump(object_stream);
+ object_stream.Flush();
+
+ error.SetErrorStringWithFormat("%s: %s", message, object_stream.GetData());
+}
+
+Error StructuredDataDarwinLog::GetDescription(
+ const StructuredData::ObjectSP &object_sp, lldb_private::Stream &stream) {
+ Error error;
+
+ if (!object_sp) {
+ error.SetErrorString("No structured data.");
+ return error;
+ }
+
+ // Log message payload objects will be dictionaries.
+ const StructuredData::Dictionary *dictionary = object_sp->GetAsDictionary();
+ if (!dictionary) {
+ SetErrorWithJSON(error, "Structured data should have been a dictionary "
+ "but wasn't",
+ *object_sp);
+ return error;
+ }
+
+ // Validate this is really a message for our plugin.
+ ConstString type_name;
+ if (!dictionary->GetValueForKeyAsString("type", type_name)) {
+ SetErrorWithJSON(error, "Structured data doesn't contain mandatory "
+ "type field",
+ *object_sp);
+ return error;
+ }
+
+ if (type_name != GetDarwinLogTypeName()) {
+ // This is okay - it simply means the data we received is not a log
+ // message. We'll just format it as is.
+ object_sp->Dump(stream);
+ return error;
+ }
+
+ // DarwinLog dictionaries store their data
+ // in an array with key name "events".
+ StructuredData::Array *events = nullptr;
+ if (!dictionary->GetValueForKeyAsArray("events", events) || !events) {
+ SetErrorWithJSON(error, "Log structured data is missing mandatory "
+ "'events' field, expected to be an array",
+ *object_sp);
+ return error;
+ }
+
+ events->ForEach(
+ [&stream, &error, &object_sp, this](StructuredData::Object *object) {
+ if (!object) {
+ // Invalid. Stop iterating.
+ SetErrorWithJSON(error, "Log event entry is null", *object_sp);
+ return false;
+ }
+
+ auto event = object->GetAsDictionary();
+ if (!event) {
+ // Invalid, stop iterating.
+ SetErrorWithJSON(error, "Log event is not a dictionary", *object_sp);
+ return false;
+ }
+
+ // If we haven't already grabbed the first timestamp
+ // value, do that now.
+ if (!m_recorded_first_timestamp) {
+ uint64_t timestamp = 0;
+ if (event->GetValueForKeyAsInteger("timestamp", timestamp)) {
+ m_first_timestamp_seen = timestamp;
+ m_recorded_first_timestamp = true;
+ }
+ }
+
+ HandleDisplayOfEvent(*event, stream);
+ return true;
+ });
+
+ stream.Flush();
+ return error;
+}
+
+bool StructuredDataDarwinLog::GetEnabled(const ConstString &type_name) const {
+ if (type_name == GetStaticPluginName())
+ return m_is_enabled;
+ else
+ return false;
+}
+
+void StructuredDataDarwinLog::SetEnabled(bool enabled) {
+ m_is_enabled = enabled;
+}
+
+void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
+ ModuleList &module_list) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s called (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
+
+ // Check if we should enable the darwin log support on startup/attach.
+ if (!GetGlobalProperties()->GetEnableOnStartup() &&
+ !s_is_explicitly_enabled) {
+ // We're neither auto-enabled or explicitly enabled, so we shouldn't
+ // try to enable here.
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s not applicable, we're not "
+ "enabled (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
+ return;
+ }
+
+ // If we already added the breakpoint, we've got nothing left to do.
+ {
+ std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
+ if (m_added_breakpoint) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s process uid %u's "
+ "post-libtrace-init breakpoint is already set",
+ __FUNCTION__, process.GetUniqueID());
+ return;
+ }
+ }
+
+ // The logging support module name, specifies the name of
+ // the image name that must be loaded into the debugged process before
+ // we can try to enable logging.
+ const char *logging_module_cstr =
+ GetGlobalProperties()->GetLoggingModuleName();
+ if (!logging_module_cstr || (logging_module_cstr[0] == 0)) {
+ // We need this. Bail.
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s no logging module name "
+ "specified, we don't know where to set a breakpoint "
+ "(process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
+ return;
+ }
+
+ const ConstString logging_module_name = ConstString(logging_module_cstr);
+
+ // We need to see libtrace in the list of modules before we can enable
+ // tracing for the target process.
+ bool found_logging_support_module = false;
+ for (size_t i = 0; i < module_list.GetSize(); ++i) {
+ auto module_sp = module_list.GetModuleAtIndex(i);
+ if (!module_sp)
+ continue;
+
+ auto &file_spec = module_sp->GetFileSpec();
+ found_logging_support_module =
+ (file_spec.GetLastPathComponent() == logging_module_name);
+ if (found_logging_support_module)
+ break;
+ }
+
+ if (!found_logging_support_module) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s logging module %s "
+ "has not yet been loaded, can't set a breakpoint "
+ "yet (process uid %u)",
+ __FUNCTION__, logging_module_name.AsCString(),
+ process.GetUniqueID());
+ return;
+ }
+
+ // Time to enqueue the breakpoint so we can wait for logging support
+ // to be initialized before we try to tap the libtrace stream.
+ AddInitCompletionHook(process);
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s post-init hook breakpoint "
+ "set for logging module %s (process uid %u)",
+ __FUNCTION__, logging_module_name.AsCString(),
+ process.GetUniqueID());
+
+ // We need to try the enable here as well, which will succeed
+ // in the event that we're attaching to (rather than launching) the
+ // process and the process is already past initialization time. In that
+ // case, the completion breakpoint will never get hit and therefore won't
+ // start that way. It doesn't hurt much beyond a bit of bandwidth
+ // if we end up doing this twice. It hurts much more if we don't get
+ // the logging enabled when the user expects it.
+ EnableNow();
+}
+
+// -----------------------------------------------------------------------------
+// public destructor
+// -----------------------------------------------------------------------------
+
+StructuredDataDarwinLog::~StructuredDataDarwinLog() {
+ if (m_breakpoint_id != LLDB_INVALID_BREAK_ID) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
+ m_breakpoint_id = LLDB_INVALID_BREAK_ID;
+ }
+ }
+}
+
+#pragma mark -
+#pragma mark Private instance methods
+
+// -----------------------------------------------------------------------------
+// Private constructors
+// -----------------------------------------------------------------------------
+
+StructuredDataDarwinLog::StructuredDataDarwinLog(const ProcessWP &process_wp)
+ : StructuredDataPlugin(process_wp), m_recorded_first_timestamp(false),
+ m_first_timestamp_seen(0), m_is_enabled(false),
+ m_added_breakpoint_mutex(), m_added_breakpoint(),
+ m_breakpoint_id(LLDB_INVALID_BREAK_ID) {}
+
+// -----------------------------------------------------------------------------
+// Private static methods
+// -----------------------------------------------------------------------------
+
+StructuredDataPluginSP
+StructuredDataDarwinLog::CreateInstance(Process &process) {
+ // Currently only Apple targets support the os_log/os_activity
+ // protocol.
+ if (process.GetTarget().GetArchitecture().GetTriple().getVendor() ==
+ llvm::Triple::VendorType::Apple) {
+ auto process_wp = ProcessWP(process.shared_from_this());
+ return StructuredDataPluginSP(new StructuredDataDarwinLog(process_wp));
+ } else {
+ return StructuredDataPluginSP();
+ }
+}
+
+void StructuredDataDarwinLog::DebuggerInitialize(Debugger &debugger) {
+ // Setup parent class first.
+ StructuredDataPlugin::InitializeBasePluginForDebugger(debugger);
+
+ // Get parent command.
+ auto &interpreter = debugger.GetCommandInterpreter();
+ llvm::StringRef parent_command_text = "plugin structured-data";
+ auto parent_command =
+ interpreter.GetCommandObjectForCommand(parent_command_text);
+ if (!parent_command) {
+ // Ut oh, parent failed to create parent command.
+ // TODO log
+ return;
+ }
+
+ auto command_name = "darwin-log";
+ auto command_sp = CommandObjectSP(new BaseCommand(interpreter));
+ bool result = parent_command->LoadSubCommand(command_name, command_sp);
+ if (!result) {
+ // TODO log it once we setup structured data logging
+ }
+
+ if (!PluginManager::GetSettingForPlatformPlugin(
+ debugger, StructuredDataDarwinLogProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForStructuredDataPlugin(
+ debugger, GetGlobalProperties()->GetValueProperties(),
+ ConstString("Properties for the darwin-log"
+ " plug-in."),
+ is_global_setting);
+ }
+}
+
+Error StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info,
+ Target *target) {
+ Error error;
+
+ // If we're not debugging this launched process, there's nothing for us
+ // to do here.
+ if (!launch_info.GetFlags().AnySet(eLaunchFlagDebug))
+ return error;
+
+ // Darwin os_log() support automatically adds debug-level and info-level
+ // messages when a debugger is attached to a process. However, with
+ // integrated suppport for debugging built into the command-line LLDB,
+ // the user may specifically set to *not* include debug-level and info-level
+ // content. When the user is using the integrated log support, we want
+ // to put the kabosh on that automatic adding of info and debug level.
+ // This is done by adding an environment variable to the process on launch.
+ // (This also means it is not possible to suppress this behavior if
+ // attaching to an already-running app).
+ // Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
+ // If the target architecture is not one that supports DarwinLog, we have
+ // nothing to do here.
+ auto &triple = target ? target->GetArchitecture().GetTriple()
+ : launch_info.GetArchitecture().GetTriple();
+ if (triple.getVendor() != llvm::Triple::Apple) {
+ return error;
+ }
+
+ // If DarwinLog is not enabled (either by explicit user command or via
+ // the auto-enable option), then we have nothing to do.
+ if (!GetGlobalProperties()->GetEnableOnStartup() &&
+ !s_is_explicitly_enabled) {
+ // Nothing to do, DarwinLog is not enabled.
+ return error;
+ }
+
+ // If we don't have parsed configuration info, that implies we have
+ // enable-on-startup set up, but we haven't yet attempted to run the
+ // enable command.
+ if (!target) {
+ // We really can't do this without a target. We need to be able
+ // to get to the debugger to get the proper options to do this right.
+ // TODO log.
+ error.SetErrorString("requires a target to auto-enable DarwinLog.");
+ return error;
+ }
+
+ DebuggerSP debugger_sp = target->GetDebugger().shared_from_this();
+ auto options_sp = GetGlobalEnableOptions(debugger_sp);
+ if (!options_sp && debugger_sp) {
+ options_sp = ParseAutoEnableOptions(error, *debugger_sp.get());
+ if (!options_sp || !error.Success())
+ return error;
+
+ // We already parsed the options, save them now so we don't generate
+ // them again until the user runs the command manually.
+ SetGlobalEnableOptions(debugger_sp, options_sp);
+ }
+
+ auto &env_vars = launch_info.GetEnvironmentEntries();
+ if (!options_sp->GetEchoToStdErr()) {
+ // The user doesn't want to see os_log/NSLog messages echo to stderr.
+ // That mechanism is entirely separate from the DarwinLog support.
+ // By default we don't want to get it via stderr, because that would
+ // be in duplicate of the explicit log support here.
+
+ // Here we need to strip out any OS_ACTIVITY_DT_MODE setting to prevent
+ // echoing of os_log()/NSLog() to stderr in the target program.
+ size_t argument_index;
+ if (env_vars.ContainsEnvironmentVariable(
+ llvm::StringRef("OS_ACTIVITY_DT_MODE"), &argument_index))
+ env_vars.DeleteArgumentAtIndex(argument_index);
+
+ // We will also set the env var that tells any downstream launcher
+ // from adding OS_ACTIVITY_DT_MODE.
+ env_vars.AddOrReplaceEnvironmentVariable(
+ llvm::StringRef("IDE_DISABLED_OS_ACTIVITY_DT_MODE"),
+ llvm::StringRef("1"));
+ }
+
+ // Set the OS_ACTIVITY_MODE env var appropriately to enable/disable
+ // debug and info level messages.
+ const char *env_var_value;
+ if (options_sp->GetIncludeDebugLevel())
+ env_var_value = "debug";
+ else if (options_sp->GetIncludeInfoLevel())
+ env_var_value = "info";
+ else
+ env_var_value = "default";
+
+ if (env_var_value) {
+ launch_info.GetEnvironmentEntries().AddOrReplaceEnvironmentVariable(
+ llvm::StringRef("OS_ACTIVITY_MODE"), llvm::StringRef(env_var_value));
+ }
+
+ return error;
+}
+
+bool StructuredDataDarwinLog::InitCompletionHookCallback(
+ void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ // We hit the init function. We now want to enqueue our new thread plan,
+ // which will in turn enqueue a StepOut thread plan. When the StepOut
+ // finishes and control returns to our new thread plan, that is the time
+ // when we can execute our logic to enable the logging support.
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() called", __FUNCTION__);
+
+ // Get the current thread.
+ if (!context) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() warning: no context, "
+ "ignoring",
+ __FUNCTION__);
+ return false;
+ }
+
+ // Get the plugin from the process.
+ auto process_sp = context->exe_ctx_ref.GetProcessSP();
+ if (!process_sp) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() warning: invalid "
+ "process in context, ignoring",
+ __FUNCTION__);
+ return false;
+ }
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() call is for process uid %d",
+ __FUNCTION__, process_sp->GetUniqueID());
+
+ auto plugin_sp = process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
+ if (!plugin_sp) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() warning: no plugin for "
+ "feature %s in process uid %u",
+ __FUNCTION__, GetDarwinLogTypeName().AsCString(),
+ process_sp->GetUniqueID());
+ return false;
+ }
+
+ // Create the callback for when the thread plan completes.
+ bool called_enable_method = false;
+ const auto process_uid = process_sp->GetUniqueID();
+
+ std::weak_ptr<StructuredDataPlugin> plugin_wp(plugin_sp);
+ ThreadPlanCallOnFunctionExit::Callback callback =
+ [plugin_wp, &called_enable_method, log, process_uid]() {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::post-init callback: "
+ "called (process uid %u)",
+ process_uid);
+
+ auto strong_plugin_sp = plugin_wp.lock();
+ if (!strong_plugin_sp) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::post-init callback: "
+ "plugin no longer exists, ignoring (process "
+ "uid %u)",
+ process_uid);
+ return;
+ }
+ // Make sure we only call it once, just in case the
+ // thread plan hits the breakpoint twice.
+ if (!called_enable_method) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::post-init callback: "
+ "calling EnableNow() (process uid %u)",
+ process_uid);
+ static_cast<StructuredDataDarwinLog *>(strong_plugin_sp.get())
+ ->EnableNow();
+ called_enable_method = true;
+ } else {
+ // Our breakpoint was hit more than once. Unexpected but
+ // no harm done. Log it.
+ if (log)
+ log->Printf("StructuredDataDarwinLog::post-init callback: "
+ "skipping EnableNow(), already called by "
+ "callback [we hit this more than once] "
+ "(process uid %u)",
+ process_uid);
+ }
+ };
+
+ // Grab the current thread.
+ auto thread_sp = context->exe_ctx_ref.GetThreadSP();
+ if (!thread_sp) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() warning: failed to "
+ "retrieve the current thread from the execution "
+ "context, nowhere to run the thread plan (process uid "
+ "%u)",
+ __FUNCTION__, process_sp->GetUniqueID());
+ return false;
+ }
+
+ // Queue the thread plan.
+ auto thread_plan_sp = ThreadPlanSP(
+ new ThreadPlanCallOnFunctionExit(*thread_sp.get(), callback));
+ const bool abort_other_plans = false;
+ thread_sp->QueueThreadPlan(thread_plan_sp, abort_other_plans);
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() queuing thread plan on "
+ "trace library init method entry (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
+
+ // We return false here to indicate that it isn't a public stop.
+ return false;
+}
+
+void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() called (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
+
+ // Make sure we haven't already done this.
+ {
+ std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
+ if (m_added_breakpoint) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() ignoring request, "
+ "breakpoint already set (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
+ return;
+ }
+
+ // We're about to do this, don't let anybody else try to do it.
+ m_added_breakpoint = true;
+ }
+
+ // Set a breakpoint for the process that will kick in when libtrace
+ // has finished its initialization.
+ Target &target = process.GetTarget();
+
+ // Build up the module list.
+ FileSpecList module_spec_list;
+ auto module_file_spec =
+ FileSpec(GetGlobalProperties()->GetLoggingModuleName(), false);
+ module_spec_list.Append(module_file_spec);
+
+ // We aren't specifying a source file set.
+ FileSpecList *source_spec_list = nullptr;
+
+ const char *func_name = "_libtrace_init";
+ const lldb::addr_t offset = 0;
+ const LazyBool skip_prologue = eLazyBoolCalculate;
+ // This is an internal breakpoint - the user shouldn't see it.
+ const bool internal = true;
+ const bool hardware = false;
+
+ auto breakpoint_sp = target.CreateBreakpoint(
+ &module_spec_list, source_spec_list, func_name, eFunctionNameTypeFull,
+ eLanguageTypeC, offset, skip_prologue, internal, hardware);
+ if (!breakpoint_sp) {
+ // Huh? Bail here.
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() failed to set "
+ "breakpoint in module %s, function %s (process uid %u)",
+ __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
+ func_name, process.GetUniqueID());
+ return;
+ }
+
+ // Set our callback.
+ breakpoint_sp->SetCallback(InitCompletionHookCallback, nullptr);
+ m_breakpoint_id = breakpoint_sp->GetID();
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() breakpoint set in module %s,"
+ "function %s (process uid %u)",
+ __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
+ func_name, process.GetUniqueID());
+}
+
+void StructuredDataDarwinLog::DumpTimestamp(Stream &stream,
+ uint64_t timestamp) {
+ const uint64_t delta_nanos = timestamp - m_first_timestamp_seen;
+
+ const uint64_t hours = delta_nanos / NANOS_PER_HOUR;
+ uint64_t nanos_remaining = delta_nanos % NANOS_PER_HOUR;
+
+ const uint64_t minutes = nanos_remaining / NANOS_PER_MINUTE;
+ nanos_remaining = nanos_remaining % NANOS_PER_MINUTE;
+
+ const uint64_t seconds = nanos_remaining / NANOS_PER_SECOND;
+ nanos_remaining = nanos_remaining % NANOS_PER_SECOND;
+
+ stream.Printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%09" PRIu64, hours,
+ minutes, seconds, nanos_remaining);
+}
+
+size_t
+StructuredDataDarwinLog::DumpHeader(Stream &output_stream,
+ const StructuredData::Dictionary &event) {
+ StreamString stream;
+
+ ProcessSP process_sp = GetProcess();
+ if (!process_sp) {
+ // TODO log
+ return 0;
+ }
+
+ DebuggerSP debugger_sp =
+ process_sp->GetTarget().GetDebugger().shared_from_this();
+ if (!debugger_sp) {
+ // TODO log
+ return 0;
+ }
+
+ auto options_sp = GetGlobalEnableOptions(debugger_sp);
+ if (!options_sp) {
+ // TODO log
+ return 0;
+ }
+
+ // Check if we should even display a header.
+ if (!options_sp->GetDisplayAnyHeaderFields())
+ return 0;
+
+ stream.PutChar('[');
+
+ int header_count = 0;
+ if (options_sp->GetDisplayTimestampRelative()) {
+ uint64_t timestamp = 0;
+ if (event.GetValueForKeyAsInteger("timestamp", timestamp)) {
+ DumpTimestamp(stream, timestamp);
+ ++header_count;
+ }
+ }
+
+ if (options_sp->GetDisplayActivityChain()) {
+ std::string activity_chain;
+ if (event.GetValueForKeyAsString("activity-chain", activity_chain) &&
+ !activity_chain.empty()) {
+ if (header_count > 0)
+ stream.PutChar(',');
+
+// Switch over to the #if 0 branch once we figure out
+// how we want to present settings for the tri-state of
+// no-activity, activity (most derived only), or activity-chain.
+#if 1
+ // Display the activity chain, from parent-most to child-most
+ // activity, separated by a colon (:).
+ stream.PutCString("activity-chain=");
+ stream.PutCString(activity_chain);
+#else
+ if (GetGlobalProperties()->GetDisplayActivityChain()) {
+ // Display the activity chain, from parent-most to child-most
+ // activity, separated by a colon (:).
+ stream.PutCString("activity-chain=");
+ stream.PutCString(activity_chain.c_str());
+ } else {
+ // We're only displaying the child-most activity.
+ stream.PutCString("activity=");
+ auto pos = activity_chain.find_last_of(':');
+ if (pos == std::string::npos) {
+ // The activity chain only has one level, use the whole
+ // thing.
+ stream.PutCString(activity_chain.c_str());
+ } else {
+ // Display everything after the final ':'.
+ stream.PutCString(activity_chain.substr(pos + 1).c_str());
+ }
+ }
+#endif
+ ++header_count;
+ }
+ }
+
+ if (options_sp->GetDisplaySubsystem()) {
+ std::string subsystem;
+ if (event.GetValueForKeyAsString("subsystem", subsystem) &&
+ !subsystem.empty()) {
+ if (header_count > 0)
+ stream.PutChar(',');
+ stream.PutCString("subsystem=");
+ stream.PutCString(subsystem);
+ ++header_count;
+ }
+ }
+
+ if (options_sp->GetDisplayCategory()) {
+ std::string category;
+ if (event.GetValueForKeyAsString("category", category) &&
+ !category.empty()) {
+ if (header_count > 0)
+ stream.PutChar(',');
+ stream.PutCString("category=");
+ stream.PutCString(category);
+ ++header_count;
+ }
+ }
+ stream.PutCString("] ");
+
+ output_stream.PutCString(stream.GetString());
+
+ return stream.GetSize();
+}
+
+size_t StructuredDataDarwinLog::HandleDisplayOfEvent(
+ const StructuredData::Dictionary &event, Stream &stream) {
+ // Check the type of the event.
+ ConstString event_type;
+ if (!event.GetValueForKeyAsString("type", event_type)) {
+ // Hmm, we expected to get events that describe
+ // what they are. Continue anyway.
+ return 0;
+ }
+
+ if (event_type != GetLogEventType())
+ return 0;
+
+ size_t total_bytes = 0;
+
+ // Grab the message content.
+ std::string message;
+ if (!event.GetValueForKeyAsString("message", message))
+ return true;
+
+ // Display the log entry.
+ const auto len = message.length();
+
+ total_bytes += DumpHeader(stream, event);
+
+ stream.Write(message.c_str(), len);
+ total_bytes += len;
+
+ // Add an end of line.
+ stream.PutChar('\n');
+ total_bytes += sizeof(char);
+
+ return total_bytes;
+}
+
+void StructuredDataDarwinLog::EnableNow() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() called", __FUNCTION__);
+
+ // Run the enable command.
+ auto process_sp = GetProcess();
+ if (!process_sp) {
+ // Nothing to do.
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() warning: failed to get "
+ "valid process, skipping",
+ __FUNCTION__);
+ return;
+ }
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() call is for process uid %u",
+ __FUNCTION__, process_sp->GetUniqueID());
+
+ // If we have configuration data, we can directly enable it now.
+ // Otherwise, we need to run through the command interpreter to parse
+ // the auto-run options (which is the only way we get here without having
+ // already-parsed configuration data).
+ DebuggerSP debugger_sp =
+ process_sp->GetTarget().GetDebugger().shared_from_this();
+ if (!debugger_sp) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() warning: failed to get "
+ "debugger shared pointer, skipping (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
+ return;
+ }
+
+ auto options_sp = GetGlobalEnableOptions(debugger_sp);
+ if (!options_sp) {
+ // We haven't run the enable command yet. Just do that now, it'll
+ // take care of the rest.
+ auto &interpreter = debugger_sp->GetCommandInterpreter();
+ const bool success = RunEnableCommand(interpreter);
+ if (log) {
+ if (success)
+ log->Printf("StructuredDataDarwinLog::%s() ran enable command "
+ "successfully for (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
+ else
+ log->Printf("StructuredDataDarwinLog::%s() error: running "
+ "enable command failed (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
+ }
+ // Report failures to the debugger error stream.
+ auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
+ if (error_stream_sp) {
+ error_stream_sp->Printf("failed to configure DarwinLog "
+ "support\n");
+ error_stream_sp->Flush();
+ }
+ return;
+ }
+
+ // We've previously been enabled. We will re-enable now with the
+ // previously specified options.
+ auto config_sp = options_sp->BuildConfigurationData(true);
+ if (!config_sp) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() warning: failed to "
+ "build configuration data for enable options, skipping "
+ "(process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
+ return;
+ }
+
+ // We can run it directly.
+ // Send configuration to the feature by way of the process.
+ const Error error =
+ process_sp->ConfigureStructuredData(GetDarwinLogTypeName(), config_sp);
+
+ // Report results.
+ if (!error.Success()) {
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() "
+ "ConfigureStructuredData() call failed "
+ "(process uid %u): %s",
+ __FUNCTION__, process_sp->GetUniqueID(), error.AsCString());
+ auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
+ if (error_stream_sp) {
+ error_stream_sp->Printf("failed to configure DarwinLog "
+ "support: %s\n",
+ error.AsCString());
+ error_stream_sp->Flush();
+ }
+ m_is_enabled = false;
+ } else {
+ m_is_enabled = true;
+ if (log)
+ log->Printf("StructuredDataDarwinLog::%s() success via direct "
+ "configuration (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
+ }
+}
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h
new file mode 100644
index 000000000000..7eaab127c3f3
--- /dev/null
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h
@@ -0,0 +1,138 @@
+//===-- StructuredDataDarwinLog.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef StructuredDataDarwinLog_h
+#define StructuredDataDarwinLog_h
+
+#include "lldb/Target/StructuredDataPlugin.h"
+
+#include <mutex>
+
+// Forward declarations
+namespace sddarwinlog_private {
+class EnableCommand;
+}
+
+namespace lldb_private {
+
+class StructuredDataDarwinLog : public StructuredDataPlugin {
+ friend sddarwinlog_private::EnableCommand;
+
+public:
+ // -------------------------------------------------------------------------
+ // Public static API
+ // -------------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static const ConstString &GetStaticPluginName();
+
+ // -------------------------------------------------------------------------
+ /// Return whether the DarwinLog functionality is enabled.
+ ///
+ /// The DarwinLog functionality is enabled if the user expicitly enabled
+ /// it with the enable command, or if the user has the setting set
+ /// that controls if we always enable it for newly created/attached
+ /// processes.
+ ///
+ /// @return
+ /// True if DarwinLog support is/will be enabled for existing or
+ /// newly launched/attached processes.
+ // -------------------------------------------------------------------------
+ static bool IsEnabled();
+
+ // -------------------------------------------------------------------------
+ // PluginInterface API
+ // -------------------------------------------------------------------------
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ // -------------------------------------------------------------------------
+ // StructuredDataPlugin API
+ // -------------------------------------------------------------------------
+
+ bool SupportsStructuredDataType(const ConstString &type_name) override;
+
+ void HandleArrivalOfStructuredData(
+ Process &process, const ConstString &type_name,
+ const StructuredData::ObjectSP &object_sp) override;
+
+ Error GetDescription(const StructuredData::ObjectSP &object_sp,
+ lldb_private::Stream &stream) override;
+
+ bool GetEnabled(const ConstString &type_name) const override;
+
+ void ModulesDidLoad(Process &process, ModuleList &module_list) override;
+
+ ~StructuredDataDarwinLog();
+
+private:
+ // -------------------------------------------------------------------------
+ // Private constructors
+ // -------------------------------------------------------------------------
+
+ StructuredDataDarwinLog(const lldb::ProcessWP &process_wp);
+
+ // -------------------------------------------------------------------------
+ // Private static methods
+ // -------------------------------------------------------------------------
+
+ static lldb::StructuredDataPluginSP CreateInstance(Process &process);
+
+ static void DebuggerInitialize(Debugger &debugger);
+
+ static bool InitCompletionHookCallback(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ static Error FilterLaunchInfo(ProcessLaunchInfo &launch_info, Target *target);
+
+ // -------------------------------------------------------------------------
+ // Internal helper methods used by friend classes
+ // -------------------------------------------------------------------------
+ void SetEnabled(bool enabled);
+
+ void AddInitCompletionHook(Process &process);
+
+ // -------------------------------------------------------------------------
+ // Private methods
+ // -------------------------------------------------------------------------
+
+ void DumpTimestamp(Stream &stream, uint64_t timestamp);
+
+ size_t DumpHeader(Stream &stream, const StructuredData::Dictionary &event);
+
+ size_t HandleDisplayOfEvent(const StructuredData::Dictionary &event,
+ Stream &stream);
+
+ // -------------------------------------------------------------------------
+ /// Call the enable command again, using whatever settings were initially
+ /// made.
+ // -------------------------------------------------------------------------
+
+ void EnableNow();
+
+ // -------------------------------------------------------------------------
+ // Private data
+ // -------------------------------------------------------------------------
+ bool m_recorded_first_timestamp;
+ uint64_t m_first_timestamp_seen;
+ bool m_is_enabled;
+ std::mutex m_added_breakpoint_mutex;
+ bool m_added_breakpoint;
+ lldb::user_id_t m_breakpoint_id;
+};
+}
+
+#endif /* StructuredDataPluginDarwinLog_hpp */
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index ac69243b65c0..5ce20cc0989c 100644
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -4,6 +4,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF
DWARFASTParserClang.cpp
DWARFASTParserGo.cpp
DWARFASTParserJava.cpp
+ DWARFASTParserOCaml.cpp
DWARFAttribute.cpp
DWARFCompileUnit.cpp
DWARFDataExtractor.cpp
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index 5fe0cc4d416e..5ed9c6ab7282 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -9,83 +9,64 @@
#include "DIERef.h"
#include "DWARFCompileUnit.h"
-#include "DWARFFormValue.h"
#include "DWARFDebugInfo.h"
+#include "DWARFFormValue.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
-DIERef::DIERef() :
- cu_offset(DW_INVALID_OFFSET),
- die_offset(DW_INVALID_OFFSET)
-{}
+DIERef::DIERef()
+ : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {}
-DIERef::DIERef(dw_offset_t c, dw_offset_t d) :
- cu_offset(c),
- die_offset(d)
-{}
+DIERef::DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {}
-DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf) :
- cu_offset(DW_INVALID_OFFSET),
- die_offset(uid&0xffffffff)
-{
- SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
- if (debug_map)
- {
- const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid);
- SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx);
- if (actual_dwarf)
- {
- DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
- if (debug_info)
- {
- DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIEOffset(die_offset);
- if (dwarf_cu)
- {
- cu_offset = dwarf_cu->GetOffset();
- return;
- }
- }
+DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf)
+ : cu_offset(DW_INVALID_OFFSET), die_offset(uid & 0xffffffff) {
+ SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
+ if (debug_map) {
+ const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid);
+ SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx);
+ if (actual_dwarf) {
+ DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
+ if (debug_info) {
+ DWARFCompileUnit *dwarf_cu =
+ debug_info->GetCompileUnitContainingDIEOffset(die_offset);
+ if (dwarf_cu) {
+ cu_offset = dwarf_cu->GetOffset();
+ return;
}
- die_offset = DW_INVALID_OFFSET;
- }
- else
- {
- cu_offset = uid>>32;
+ }
}
+ die_offset = DW_INVALID_OFFSET;
+ } else {
+ cu_offset = uid >> 32;
+ }
}
-DIERef::DIERef(const DWARFFormValue& form_value) :
- cu_offset(DW_INVALID_OFFSET),
- die_offset(DW_INVALID_OFFSET)
-{
- if (form_value.IsValid())
- {
- const DWARFCompileUnit* dwarf_cu = form_value.GetCompileUnit();
- if (dwarf_cu)
- {
- if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
- cu_offset = dwarf_cu->GetBaseObjOffset();
- else
- cu_offset = dwarf_cu->GetOffset();
- }
- die_offset = form_value.Reference();
+DIERef::DIERef(const DWARFFormValue &form_value)
+ : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {
+ if (form_value.IsValid()) {
+ const DWARFCompileUnit *dwarf_cu = form_value.GetCompileUnit();
+ if (dwarf_cu) {
+ if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
+ cu_offset = dwarf_cu->GetBaseObjOffset();
+ else
+ cu_offset = dwarf_cu->GetOffset();
}
+ die_offset = form_value.Reference();
+ }
}
-lldb::user_id_t
-DIERef::GetUID(SymbolFileDWARF *dwarf) const
-{
- //----------------------------------------------------------------------
- // Each SymbolFileDWARF will set its ID to what is expected.
- //
- // SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the
- // ID set to the compile unit index.
- //
- // SymbolFileDWARFDwo sets the ID to the compile unit offset.
- //----------------------------------------------------------------------
- if (dwarf)
- return dwarf->GetID() | die_offset;
- else
- return LLDB_INVALID_UID;
+lldb::user_id_t DIERef::GetUID(SymbolFileDWARF *dwarf) const {
+ //----------------------------------------------------------------------
+ // Each SymbolFileDWARF will set its ID to what is expected.
+ //
+ // SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the
+ // ID set to the compile unit index.
+ //
+ // SymbolFileDWARFDwo sets the ID to the compile unit offset.
+ //----------------------------------------------------------------------
+ if (dwarf)
+ return dwarf->GetID() | die_offset;
+ else
+ return LLDB_INVALID_UID;
}
-
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.h b/source/Plugins/SymbolFile/DWARF/DIERef.h
index ad4ad45623a3..d0048d0f6d6b 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -16,49 +16,39 @@
class DWARFFormValue;
class SymbolFileDWARF;
-struct DIERef
-{
- DIERef();
+struct DIERef {
+ DIERef();
- DIERef(dw_offset_t c, dw_offset_t d);
+ DIERef(dw_offset_t c, dw_offset_t d);
- //----------------------------------------------------------------------
- // In order to properly decode a lldb::user_id_t back into a DIERef we
- // need the DWARF file since it knows if DWARF in .o files is being used
- // (MacOSX) or if DWO files are being used. The encoding of the user ID
- // differs between the two types of DWARF.
- //----------------------------------------------------------------------
- explicit
- DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf);
+ //----------------------------------------------------------------------
+ // In order to properly decode a lldb::user_id_t back into a DIERef we
+ // need the DWARF file since it knows if DWARF in .o files is being used
+ // (MacOSX) or if DWO files are being used. The encoding of the user ID
+ // differs between the two types of DWARF.
+ //----------------------------------------------------------------------
+ explicit DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf);
- explicit
- DIERef(const DWARFFormValue& form_value);
+ explicit DIERef(const DWARFFormValue &form_value);
- //----------------------------------------------------------------------
- // In order to properly encode a DIERef unto a lldb::user_id_t we need
- // the DWARF file since it knows if DWARF in .o files is being used
- // (MacOSX) or if DWO files are being used. The encoding of the user ID
- // differs between the two types of DWARF.
- //----------------------------------------------------------------------
- lldb::user_id_t
- GetUID(SymbolFileDWARF *dwarf) const;
+ //----------------------------------------------------------------------
+ // In order to properly encode a DIERef unto a lldb::user_id_t we need
+ // the DWARF file since it knows if DWARF in .o files is being used
+ // (MacOSX) or if DWO files are being used. The encoding of the user ID
+ // differs between the two types of DWARF.
+ //----------------------------------------------------------------------
+ lldb::user_id_t GetUID(SymbolFileDWARF *dwarf) const;
- bool
- operator< (const DIERef &ref) const
- {
- return die_offset < ref.die_offset;
- }
+ bool operator<(const DIERef &ref) const {
+ return die_offset < ref.die_offset;
+ }
- bool
- operator< (const DIERef &ref)
- {
- return die_offset < ref.die_offset;
- }
+ bool operator<(const DIERef &ref) { return die_offset < ref.die_offset; }
- dw_offset_t cu_offset;
- dw_offset_t die_offset;
+ dw_offset_t cu_offset;
+ dw_offset_t die_offset;
};
typedef std::vector<DIERef> DIEArray;
-#endif // SymbolFileDWARF_DIERef_h_
+#endif // SymbolFileDWARF_DIERef_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 2fb360440f63..ae7c770d6ef7 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -17,37 +17,34 @@
class DWARFDIE;
-class DWARFASTParser
-{
+class DWARFASTParser {
public:
- virtual ~DWARFASTParser() {}
+ virtual ~DWARFASTParser() {}
- virtual lldb::TypeSP
- ParseTypeFromDWARF (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- lldb_private::Log *log,
- bool *type_is_new_ptr) = 0;
+ virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die,
+ lldb_private::Log *log,
+ bool *type_is_new_ptr) = 0;
- virtual lldb_private::Function *
- ParseFunctionFromDWARF (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die) = 0;
+ virtual lldb_private::Function *
+ ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die) = 0;
- virtual bool
- CompleteTypeFromDWARF (const DWARFDIE &die,
- lldb_private::Type *type,
- lldb_private::CompilerType &compiler_type) = 0;
+ virtual bool
+ CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ lldb_private::CompilerType &compiler_type) = 0;
- virtual lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF (const DWARFDIE &die) = 0;
+ virtual lldb_private::CompilerDecl
+ GetDeclForUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual lldb_private::CompilerDeclContext
- GetDeclContextForUIDFromDWARF (const DWARFDIE &die) = 0;
+ virtual lldb_private::CompilerDeclContext
+ GetDeclContextForUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) = 0;
+ virtual lldb_private::CompilerDeclContext
+ GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual std::vector<DWARFDIE>
- GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) = 0;
+ virtual std::vector<DWARFDIE>
+ GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0;
};
-#endif // SymbolFileDWARF_DWARFASTParser_h_
+#endif // SymbolFileDWARF_DWARFASTParser_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 23381df3297a..554b71a36c4f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -11,11 +11,11 @@
#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIE.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
-#include "DWARFDIE.h"
-#include "DWARFDIECollection.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include "UniqueDWARFASTType.h"
@@ -54,4206 +54,4035 @@
#define DEBUG_PRINTF(fmt, ...)
#endif
-
using namespace lldb;
using namespace lldb_private;
-DWARFASTParserClang::DWARFASTParserClang (ClangASTContext &ast) :
- m_ast (ast),
- m_die_to_decl_ctx (),
- m_decl_ctx_to_die ()
-{
+DWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast)
+ : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
+
+DWARFASTParserClang::~DWARFASTParserClang() {}
+
+static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) {
+ switch (dwarf_accessibility) {
+ case DW_ACCESS_public:
+ return eAccessPublic;
+ case DW_ACCESS_private:
+ return eAccessPrivate;
+ case DW_ACCESS_protected:
+ return eAccessProtected;
+ default:
+ break;
+ }
+ return eAccessNone;
}
-DWARFASTParserClang::~DWARFASTParserClang ()
-{
+static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) {
+ switch (decl_kind) {
+ case clang::Decl::CXXRecord:
+ case clang::Decl::ClassTemplateSpecialization:
+ return true;
+ default:
+ break;
+ }
+ return false;
}
-
-static AccessType
-DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
-{
- switch (dwarf_accessibility)
- {
- case DW_ACCESS_public: return eAccessPublic;
- case DW_ACCESS_private: return eAccessPrivate;
- case DW_ACCESS_protected: return eAccessProtected;
- default: break;
+struct BitfieldInfo {
+ uint64_t bit_size;
+ uint64_t bit_offset;
+
+ BitfieldInfo()
+ : bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {}
+
+ void Clear() {
+ bit_size = LLDB_INVALID_ADDRESS;
+ bit_offset = LLDB_INVALID_ADDRESS;
+ }
+
+ bool IsValid() const {
+ return (bit_size != LLDB_INVALID_ADDRESS) &&
+ (bit_offset != LLDB_INVALID_ADDRESS);
+ }
+
+ bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const {
+ if (IsValid()) {
+ // This bitfield info is valid, so any subsequent bitfields
+ // must not overlap and must be at a higher bit offset than
+ // any previous bitfield + size.
+ return (bit_size + bit_offset) <= next_bit_offset;
+ } else {
+ // If the this BitfieldInfo is not valid, then any offset isOK
+ return true;
}
- return eAccessNone;
+ }
+};
+
+ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {
+ if (!m_clang_ast_importer_ap) {
+ m_clang_ast_importer_ap.reset(new ClangASTImporter);
+ }
+ return *m_clang_ast_importer_ap;
}
-static bool
-DeclKindIsCXXClass (clang::Decl::Kind decl_kind)
-{
- switch (decl_kind)
- {
- case clang::Decl::CXXRecord:
- case clang::Decl::ClassTemplateSpecialization:
- return true;
- default:
- break;
+TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
+ ModuleSP dwo_module_sp = die.GetContainingDWOModule();
+ if (dwo_module_sp) {
+ // This type comes from an external DWO module
+ std::vector<CompilerContext> dwo_context;
+ die.GetDWOContext(dwo_context);
+ TypeMap dwo_types;
+ if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true,
+ dwo_types)) {
+ const size_t num_dwo_types = dwo_types.GetSize();
+ if (num_dwo_types == 1) {
+ // We found a real definition for this type elsewhere
+ // so lets use it and cache the fact that we found
+ // a complete type for this die
+ TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
+ if (dwo_type_sp) {
+ lldb_private::CompilerType dwo_type =
+ dwo_type_sp->GetForwardCompilerType();
+
+ lldb_private::CompilerType type =
+ GetClangASTImporter().CopyType(m_ast, dwo_type);
+
+ // printf ("copied_qual_type: ast = %p, clang_type = %p, name =
+ // '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(),
+ // external_type->GetName().GetCString());
+ if (type) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ TypeSP type_sp(new Type(die.GetID(), dwarf, dwo_type_sp->GetName(),
+ dwo_type_sp->GetByteSize(), NULL,
+ LLDB_INVALID_UID, Type::eEncodingInvalid,
+ &dwo_type_sp->GetDeclaration(), type,
+ Type::eResolveStateForward));
+
+ dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
+ if (tag_decl)
+ LinkDeclContextToDIE(tag_decl, die);
+ else {
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(die);
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ }
+ return type_sp;
+ }
+ }
+ }
}
- return false;
+ }
+ return TypeSP();
}
-struct BitfieldInfo
-{
- uint64_t bit_size;
- uint64_t bit_offset;
-
- BitfieldInfo() :
- bit_size(LLDB_INVALID_ADDRESS),
- bit_offset(LLDB_INVALID_ADDRESS)
- {
- }
+TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
+ const DWARFDIE &die, Log *log,
+ bool *type_is_new_ptr) {
+ TypeSP type_sp;
- void
- Clear()
- {
- bit_size = LLDB_INVALID_ADDRESS;
- bit_offset = LLDB_INVALID_ADDRESS;
- }
+ if (type_is_new_ptr)
+ *type_is_new_ptr = false;
- bool
- IsValid() const
- {
- return (bit_size != LLDB_INVALID_ADDRESS) &&
- (bit_offset != LLDB_INVALID_ADDRESS);
+ AccessType accessibility = eAccessNone;
+ if (die) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ if (log) {
+ DWARFDIE context_die;
+ clang::DeclContext *context =
+ GetClangDeclContextContainingDIE(die, &context_die);
+
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die "
+ "0x%8.8x)) %s name = '%s')",
+ die.GetOffset(), static_cast<void *>(context),
+ context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
}
+ //
+ // Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ // if (log && dwarf_cu)
+ // {
+ // StreamString s;
+ // die->DumpLocation (this, dwarf_cu, s);
+ // dwarf->GetObjectFile()->GetModule()->LogMessage (log,
+ // "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
+ //
+ // }
+
+ Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
+ TypeList *type_list = dwarf->GetTypeList();
+ if (type_ptr == NULL) {
+ 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;
+ Declaration decl;
+
+ Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
+ CompilerType clang_type;
+ DWARFFormValue form_value;
+
+ dw_attr_t attr;
+
+ switch (tag) {
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_const_type:
+ case DW_TAG_restrict_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_unspecified_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
- bool
- NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const
- {
- if (IsValid())
- {
- // This bitfield info is valid, so any subsequent bitfields
- // must not overlap and must be at a higher bit offset than
- // any previous bitfield + size.
- return (bit_size + bit_offset) <= next_bit_offset;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ uint32_t encoding = 0;
+ DWARFFormValue encoding_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_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ 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;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_encoding:
+ encoding = form_value.Unsigned();
+ break;
+ case DW_AT_type:
+ encoding_uid = form_value;
+ break;
+ default:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
}
- else
- {
- // If the this BitfieldInfo is not valid, then any offset isOK
- return true;
+
+ if (tag == DW_TAG_typedef && encoding_uid.IsValid()) {
+ // Try to parse a typedef from the DWO file first as modules
+ // can contain typedef'ed structures that have no names like:
+ //
+ // typedef struct { int a; } Foo;
+ //
+ // In this case we will have a structure with no name and a
+ // typedef named "Foo" that points to this unnamed structure.
+ // The name in the typedef is the only identifier for the struct,
+ // so always try to get typedefs from DWO files if possible.
+ //
+ // The type_sp returned will be empty if the typedef doesn't exist
+ // in a DWO file, so it is cheap to call this function just to check.
+ //
+ // If we don't do this we end up creating a TypeSP that says this
+ // is a typedef to type 0x123 (the DW_AT_type value would be 0x123
+ // in the DW_TAG_typedef), and this is the unnamed structure type.
+ // We will have a hard time tracking down an unnammed structure
+ // type in the module DWO file, so we make sure we don't get into
+ // this situation by always resolving typedefs from the DWO file.
+ const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
+
+ // First make sure that the die that this is typedef'ed to _is_
+ // just a declaration (DW_AT_declaration == 1), not a full definition
+ // since template types can't be represented in modules since only
+ // concrete instances of templates are ever emitted and modules
+ // won't contain those
+ if (encoding_die &&
+ encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) ==
+ 1) {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+ }
}
- }
-};
+ 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.Reference());
-ClangASTImporter &
-DWARFASTParserClang::GetClangASTImporter()
-{
- if (!m_clang_ast_importer_ap)
- {
- m_clang_ast_importer_ap.reset (new ClangASTImporter);
- }
- return *m_clang_ast_importer_ap;
-}
+ switch (tag) {
+ default:
+ break;
+ case DW_TAG_unspecified_type:
+ if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
+ strcmp(type_name_cstr, "decltype(nullptr)") == 0) {
+ resolve_state = Type::eResolveStateFull;
+ clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
+ break;
+ }
+ // Fall through to base type below in case we can handle the type
+ // there...
+ LLVM_FALLTHROUGH;
+
+ case DW_TAG_base_type:
+ resolve_state = Type::eResolveStateFull;
+ clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
+ type_name_cstr, encoding, byte_size * 8);
+ break;
+
+ case DW_TAG_pointer_type:
+ encoding_data_type = Type::eEncodingIsPointerUID;
+ break;
+ case DW_TAG_reference_type:
+ encoding_data_type = Type::eEncodingIsLValueReferenceUID;
+ break;
+ case DW_TAG_rvalue_reference_type:
+ encoding_data_type = Type::eEncodingIsRValueReferenceUID;
+ break;
+ case DW_TAG_typedef:
+ encoding_data_type = Type::eEncodingIsTypedefUID;
+ break;
+ case DW_TAG_const_type:
+ encoding_data_type = Type::eEncodingIsConstUID;
+ break;
+ case DW_TAG_restrict_type:
+ encoding_data_type = Type::eEncodingIsRestrictUID;
+ break;
+ case DW_TAG_volatile_type:
+ encoding_data_type = Type::eEncodingIsVolatileUID;
+ break;
+ }
-TypeSP
-DWARFASTParserClang::ParseTypeFromDWO (const DWARFDIE &die, Log *log)
-{
- ModuleSP dwo_module_sp = die.GetContainingDWOModule();
- if (dwo_module_sp)
- {
- // This type comes from an external DWO module
- std::vector<CompilerContext> dwo_context;
- die.GetDWOContext(dwo_context);
- TypeMap dwo_types;
- if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, dwo_types))
- {
- const size_t num_dwo_types = dwo_types.GetSize();
- if (num_dwo_types == 1)
- {
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
- TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
- if (dwo_type_sp)
- {
- lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType();
-
- lldb_private::CompilerType type = GetClangASTImporter().CopyType (m_ast, dwo_type);
-
- //printf ("copied_qual_type: ast = %p, clang_type = %p, name = '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), external_type->GetName().GetCString());
- if (type)
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- TypeSP type_sp (new Type (die.GetID(),
- dwarf,
- dwo_type_sp->GetName(),
- dwo_type_sp->GetByteSize(),
- NULL,
- LLDB_INVALID_UID,
- Type::eEncodingInvalid,
- &dwo_type_sp->GetDeclaration(),
- type,
- Type::eResolveStateForward));
-
- dwarf->GetTypeList()->Insert(type_sp);
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
- if (tag_decl)
- LinkDeclContextToDIE(tag_decl, die);
- else
- {
- clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- }
- return type_sp;
+ if (!clang_type &&
+ (encoding_data_type == Type::eEncodingIsPointerUID ||
+ encoding_data_type == Type::eEncodingIsTypedefUID) &&
+ sc.comp_unit != NULL) {
+ if (tag == DW_TAG_pointer_type) {
+ DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
+
+ if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {
+ // Blocks have a __FuncPtr inside them which is a pointer to a
+ // function of the proper type.
+
+ for (DWARFDIE child_die = target_die.GetFirstChild();
+ child_die.IsValid(); child_die = child_die.GetSibling()) {
+ if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
+ "__FuncPtr")) {
+ DWARFDIE function_pointer_type =
+ child_die.GetReferencedDIE(DW_AT_type);
+
+ if (function_pointer_type) {
+ DWARFDIE function_type =
+ function_pointer_type.GetReferencedDIE(DW_AT_type);
+
+ bool function_type_is_new_pointer;
+ TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
+ sc, function_type, log, &function_type_is_new_pointer);
+
+ if (lldb_function_type_sp) {
+ clang_type = m_ast.CreateBlockPointerType(
+ lldb_function_type_sp->GetForwardCompilerType());
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
}
+ }
+
+ break;
}
+ }
}
- }
- }
- return TypeSP();
-}
-
-TypeSP
-DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
- const DWARFDIE &die,
- Log *log,
- bool *type_is_new_ptr)
-{
- TypeSP type_sp;
-
- if (type_is_new_ptr)
- *type_is_new_ptr = false;
+ }
- AccessType accessibility = eAccessNone;
- if (die)
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (log)
- {
- DWARFDIE context_die;
- clang::DeclContext *context = GetClangDeclContextContainingDIE (die, &context_die);
+ bool translation_unit_is_objc =
+ (sc.comp_unit->GetLanguage() == eLanguageTypeObjC ||
+ sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
- dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
- die.GetOffset(),
- static_cast<void*>(context),
- context_die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
+ if (translation_unit_is_objc) {
+ if (type_name_cstr != NULL) {
+ static ConstString g_objc_type_name_id("id");
+ static ConstString g_objc_type_name_Class("Class");
+ static ConstString g_objc_type_name_selector("SEL");
+ if (type_name_const_str == g_objc_type_name_id) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective C 'id' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+
+ } else if (type_name_const_str == g_objc_type_name_Class) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective C 'Class' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+ } else if (type_name_const_str == g_objc_type_name_selector) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective C 'selector' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+ }
+ } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
+ encoding_uid.IsValid()) {
+ // Clang sometimes erroneously emits id as objc_object*. In that
+ // case we fix up the type to "id".
+
+ const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
+
+ if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
+ if (const char *struct_name = encoding_die.GetName()) {
+ if (!strcmp(struct_name, "objc_object")) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s "
+ "'%s' is 'objc_object*', which we overrode to "
+ "'id'.",
+ die.GetOffset(), die.GetTagAsCString(),
+ die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+ }
+ }
+ }
+ }
+ }
}
- //
- // Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- // if (log && dwarf_cu)
- // {
- // StreamString s;
- // die->DumpLocation (this, dwarf_cu, s);
- // dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
- //
- // }
-
- Type *type_ptr = dwarf->GetDIEToType().lookup (die.GetDIE());
- TypeList* type_list = dwarf->GetTypeList();
- if (type_ptr == NULL)
- {
- 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;
- Declaration decl;
+ type_sp.reset(
+ new Type(die.GetID(), dwarf, type_name_const_str, byte_size, NULL,
+ DIERef(encoding_uid).GetUID(dwarf), encoding_data_type,
+ &decl, clang_type, resolve_state));
+
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+
+ // Type* encoding_type =
+ // GetUniquedTypeForDIEOffset(encoding_uid, type_sp,
+ // NULL, 0, 0, false);
+ // if (encoding_type != NULL)
+ // {
+ // if (encoding_type != DIE_IS_BEING_PARSED)
+ // type_sp->SetEncodingType(encoding_type);
+ // else
+ // m_indirect_fixups.push_back(type_sp.get());
+ // }
+ } break;
+
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+ bool byte_size_valid = false;
+
+ LanguageType class_language = eLanguageTypeUnknown;
+ bool is_complete_objc_class = false;
+ // bool struct_is_class = 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_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()));
+ break;
- Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
- CompilerType clang_type;
- DWARFFormValue form_value;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
- dw_attr_t attr;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
- switch (tag)
- {
- case DW_TAG_typedef:
- case DW_TAG_base_type:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_const_type:
- case DW_TAG_restrict_type:
- case DW_TAG_volatile_type:
- case DW_TAG_unspecified_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- const size_t num_attributes = die.GetAttributes (attributes);
- uint32_t encoding = 0;
- DWARFFormValue encoding_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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: 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;
- case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
- case DW_AT_encoding: encoding = form_value.Unsigned(); break;
- case DW_AT_type: encoding_uid = form_value; break;
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
+ case DW_AT_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
- if (tag == DW_TAG_typedef && encoding_uid.IsValid())
- {
- // Try to parse a typedef from the DWO file first as modules
- // can contain typedef'ed structures that have no names like:
- //
- // typedef struct { int a; } Foo;
- //
- // In this case we will have a structure with no name and a
- // typedef named "Foo" that points to this unnamed structure.
- // The name in the typedef is the only identifier for the struct,
- // so always try to get typedefs from DWO files if possible.
- //
- // The type_sp returned will be empty if the typedef doesn't exist
- // in a DWO file, so it is cheap to call this function just to check.
- //
- // If we don't do this we end up creating a TypeSP that says this
- // is a typedef to type 0x123 (the DW_AT_type value would be 0x123
- // in the DW_TAG_typedef), and this is the unnamed structure type.
- // We will have a hard time tracking down an unnammed structure
- // type in the module DWO file, so we make sure we don't get into
- // this situation by always resolving typedefs from the DWO file.
- const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
-
- // First make sure that the die that this is typedef'ed to _is_
- // just a declaration (DW_AT_declaration == 1), not a full definition
- // since template types can't be represented in modules since only
- // concrete instances of templates are ever emitted and modules
- // won't contain those
- if (encoding_die && encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1)
- {
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
- }
- }
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ byte_size_valid = true;
+ 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.Reference());
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
- switch (tag)
- {
- default:
- break;
+ case DW_AT_declaration:
+ is_forward_declaration = form_value.Boolean();
+ break;
- case DW_TAG_unspecified_type:
- if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
- strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
- {
- resolve_state = Type::eResolveStateFull;
- clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
- break;
- }
- // Fall through to base type below in case we can handle the type there...
- LLVM_FALLTHROUGH;
-
- case DW_TAG_base_type:
- resolve_state = Type::eResolveStateFull;
- clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
- encoding,
- byte_size * 8);
- break;
-
- case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
- case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
- case DW_TAG_rvalue_reference_type: encoding_data_type = Type::eEncodingIsRValueReferenceUID; break;
- case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
- case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
- case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
- case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
- }
+ case DW_AT_APPLE_runtime_class:
+ class_language = (LanguageType)form_value.Signed();
+ break;
- if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
- {
- if (tag == DW_TAG_pointer_type)
- {
- DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
-
- if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0))
- {
- // Blocks have a __FuncPtr inside them which is a pointer to a function of the proper type.
-
- for (DWARFDIE child_die = target_die.GetFirstChild();
- child_die.IsValid();
- child_die = child_die.GetSibling())
- {
- if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""), "__FuncPtr"))
- {
- DWARFDIE function_pointer_type = child_die.GetReferencedDIE(DW_AT_type);
-
- if (function_pointer_type)
- {
- DWARFDIE function_type = function_pointer_type.GetReferencedDIE(DW_AT_type);
-
- bool function_type_is_new_pointer;
- TypeSP lldb_function_type_sp = ParseTypeFromDWARF(sc, function_type, log, &function_type_is_new_pointer);
-
- if (lldb_function_type_sp)
- {
- clang_type = m_ast.CreateBlockPointerType(lldb_function_type_sp->GetForwardCompilerType());
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- }
-
- break;
- }
- }
- }
- }
-
- bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
-
- if (translation_unit_is_objc)
- {
- if (type_name_cstr != NULL)
- {
- static ConstString g_objc_type_name_id("id");
- static ConstString g_objc_type_name_Class("Class");
- static ConstString g_objc_type_name_selector("SEL");
-
- if (type_name_const_str == g_objc_type_name_id)
- {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
+ case DW_AT_APPLE_objc_complete_type:
+ is_complete_objc_class = form_value.Signed();
+ break;
- }
- else if (type_name_const_str == g_objc_type_name_Class)
- {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- else if (type_name_const_str == g_objc_type_name_selector)
- {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- }
- else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid.IsValid())
- {
- // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
-
- const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
-
- if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type)
- {
- if (const char *struct_name = encoding_die.GetName())
- {
- if (!strcmp(struct_name, "objc_object"))
- {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- }
- }
- }
- }
- }
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_data_location:
+ case DW_AT_description:
+ case DW_AT_start_scope:
+ case DW_AT_visibility:
+ default:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
+ }
- type_sp.reset( new Type (die.GetID(),
- dwarf,
- type_name_const_str,
- byte_size,
- NULL,
- DIERef(encoding_uid).GetUID(dwarf),
- encoding_data_type,
- &decl,
- clang_type,
- resolve_state));
-
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
-
- // Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
- // if (encoding_type != NULL)
- // {
- // if (encoding_type != DIE_IS_BEING_PARSED)
- // type_sp->SetEncodingType(encoding_type);
- // else
- // m_indirect_fixups.push_back(type_sp.get());
- // }
- }
- break;
-
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
- bool byte_size_valid = false;
-
- LanguageType class_language = eLanguageTypeUnknown;
- bool is_complete_objc_class = false;
- //bool struct_is_class = 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_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()));
- break;
-
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
-
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
-
- 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_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
-
- case DW_AT_declaration:
- is_forward_declaration = form_value.Boolean();
- break;
-
- case DW_AT_APPLE_runtime_class:
- class_language = (LanguageType)form_value.Signed();
- break;
-
- case DW_AT_APPLE_objc_complete_type:
- is_complete_objc_class = form_value.Signed();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
+ // 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());
+
+ ConstString unique_typename(type_name_const_str);
+ Declaration unique_decl(decl);
+
+ if (type_name_const_str) {
+ LanguageType die_language = die.GetLanguage();
+ if (Language::LanguageIsCPlusPlus(die_language)) {
+ // For C++, we rely solely upon the one definition rule that says
+ // only
+ // one thing can exist at a given decl context. We ignore the file
+ // and
+ // line that things are declared on.
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
+ }
+
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl,
+ byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
+ type_sp = unique_ast_entry_ap->m_type_sp;
+ if (type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
+ }
- // 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());
-
- ConstString unique_typename(type_name_const_str);
- Declaration unique_decl(decl);
-
- if (type_name_const_str)
- {
- LanguageType die_language = die.GetLanguage();
- if (Language::LanguageIsCPlusPlus(die_language))
- {
- // For C++, we rely solely upon the one definition rule that says only
- // one thing can exist at a given decl context. We ignore the file and
- // line that things are declared on.
- std::string qualified_name;
- if (die.GetQualifiedName(qualified_name))
- unique_typename = ConstString(qualified_name);
- unique_decl.Clear();
- }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ int tag_decl_kind = -1;
+ AccessType default_accessibility = eAccessNone;
+ if (tag == DW_TAG_structure_type) {
+ tag_decl_kind = clang::TTK_Struct;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_union_type) {
+ tag_decl_kind = clang::TTK_Union;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_class_type) {
+ tag_decl_kind = clang::TTK_Class;
+ default_accessibility = eAccessPrivate;
+ }
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(unique_typename, die, unique_decl,
- byte_size_valid ? byte_size : -1,
- *unique_ast_entry_ap))
- {
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
- {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
+ if (byte_size_valid && byte_size == 0 && type_name_cstr &&
+ die.HasChildren() == false &&
+ sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {
+ // Work around an issue with clang at the moment where
+ // forward declarations for objective C classes are emitted
+ // as:
+ // DW_TAG_structure_type [2]
+ // DW_AT_name( "ForwardObjcClass" )
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_decl_file( "..." )
+ // DW_AT_decl_line( 1 )
+ //
+ // Note that there is no DW_AT_declaration and there are
+ // no children, and the byte size is zero.
+ is_forward_declaration = true;
+ }
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
+ if (class_language == eLanguageTypeObjC ||
+ class_language == eLanguageTypeObjC_plus_plus) {
+ if (!is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // We have a valid eSymbolTypeObjCClass class symbol whose
+ // name matches the current objective C class that we
+ // are trying to find and this DIE isn't the complete
+ // definition (we checked is_complete_objc_class above and
+ // know it is false), so the real definition is in here somewhere
+ type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name_const_str, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in
+ // this DWARF, see if we have a declaration anywhere
+ // else...
+ type_sp =
+ debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name_const_str, true);
+ }
+ }
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type)
- {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_union_type)
- {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_class_type)
- {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
+ "incomplete objc type, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr,
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere
+ // so lets use it and cache the fact that we found
+ // a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
+ }
- if (byte_size_valid && byte_size == 0 && type_name_cstr &&
- die.HasChildren() == false &&
- sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
- {
- // Work around an issue with clang at the moment where
- // forward declarations for objective C classes are emitted
- // as:
- // DW_TAG_structure_type [2]
- // DW_AT_name( "ForwardObjcClass" )
- // DW_AT_byte_size( 0x00 )
- // DW_AT_decl_file( "..." )
- // DW_AT_decl_line( 1 )
- //
- // Note that there is no DW_AT_declaration and there are
- // no children, and the byte size is zero.
- is_forward_declaration = true;
- }
+ if (is_forward_declaration) {
+ // We have a forward declaration to a type and we need
+ // to try and find a full declaration. We look in the
+ // current type index just in case we have a forward
+ // declaration followed by an actual declarations in the
+ // DWARF. If this fails, we need to look elsewhere...
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, trying to find complete type",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+ }
+
+ // See if the type comes from a DWO module and if so, track down that
+ // type.
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
+ // type_name_const_str);
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in
+ // this DWARF, see if we have a declaration anywhere
+ // else...
+ type_sp =
+ debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
+ }
- if (class_language == eLanguageTypeObjC ||
- class_language == eLanguageTypeObjC_plus_plus)
- {
- if (!is_complete_objc_class && die.Supports_DW_AT_APPLE_objc_complete_type())
- {
- // We have a valid eSymbolTypeObjCClass class symbol whose
- // name matches the current objective C class that we
- // are trying to find and this DIE isn't the complete
- // definition (we checked is_complete_objc_class above and
- // know it is false), so the real definition is in here somewhere
- type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
-
- if (!type_sp)
- {
- SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
- type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
- }
- }
+ // We found a real definition for this type elsewhere
+ // so lets use it and cache the fact that we found
+ // a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
+ dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ assert(tag_decl_kind != -1);
+ bool clang_type_was_created = false;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
+ if (accessibility == eAccessNone && decl_ctx) {
+ // Check the decl context that contains this class/struct/union.
+ // If it is a class we must give it an accessibility.
+ const clang::Decl::Kind containing_decl_kind =
+ decl_ctx->getDeclKind();
+ if (DeclKindIsCXXClass(containing_decl_kind))
+ accessibility = default_accessibility;
+ }
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
+
+ if (type_name_cstr && strchr(type_name_cstr, '<')) {
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ if (ParseTemplateParameterInfos(die, template_param_infos)) {
+ clang::ClassTemplateDecl *class_template_decl =
+ m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
+ type_name_cstr, tag_decl_kind,
+ template_param_infos);
+
+ clang::ClassTemplateSpecializationDecl
+ *class_specialization_decl =
+ m_ast.CreateClassTemplateSpecializationDecl(
+ decl_ctx, class_template_decl, tag_decl_kind,
+ template_param_infos);
+ clang_type = m_ast.CreateClassTemplateSpecializationType(
+ class_specialization_decl);
+ clang_type_was_created = true;
+
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+ }
+ }
+
+ if (!clang_type_was_created) {
+ clang_type_was_created = true;
+ clang_type = m_ast.CreateRecordType(decl_ctx, accessibility,
+ type_name_cstr, tag_decl_kind,
+ class_language, &metadata);
+ }
+ }
- if (type_sp)
- {
- if (log)
- {
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64,
- static_cast<void*>(this),
- die.GetOffset(),
- DW_TAG_value_to_name(tag),
- type_name_cstr,
- type_sp->GetID());
- }
+ // Store a forward declaration to this class type in case any
+ // parameters in any class methods need it for the clang
+ // types for function prototypes.
+ LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
+ byte_size, NULL, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &decl, clang_type,
+ Type::eResolveStateForward));
+
+ type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
+
+ // Add our type to the unique type map so we don't
+ // end up creating many copies of the same type over
+ // and over in the ASTContext for our module
+ unique_ast_entry_ap->m_type_sp = type_sp;
+ unique_ast_entry_ap->m_die = die;
+ unique_ast_entry_ap->m_declaration = unique_decl;
+ unique_ast_entry_ap->m_byte_size = byte_size;
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
+ *unique_ast_entry_ap);
+
+ if (is_forward_declaration && die.HasChildren()) {
+ // Check to see if the DIE actually has a definition, some version of
+ // GCC will
+ // emit DIEs with DW_AT_declaration set to true, but yet still have
+ // subprogram,
+ // members, or inheritance, so we can't trust it
+ DWARFDIE child_die = die.GetFirstChild();
+ while (child_die) {
+ switch (child_die.Tag()) {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ case DW_TAG_member:
+ case DW_TAG_APPLE_property:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ child_die.Clear();
+ is_forward_declaration = false;
+ break;
+ default:
+ child_die = child_die.GetSibling();
+ break;
+ }
+ }
+ }
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
+ 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
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), type_name_cstr);
+ }
+ if (tag == DW_TAG_structure_type) // this only applies in C
+ {
+ clang::RecordDecl *record_decl =
+ ClangASTContext::GetAsRecordDecl(clang_type);
- if (is_forward_declaration)
- {
- // We have a forward declaration to a type and we need
- // to try and find a full declaration. We look in the
- // current type index just in case we have a forward
- // declaration followed by an actual declarations in the
- // DWARF. If this fails, we need to look elsewhere...
- if (log)
- {
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type",
- static_cast<void*>(this),
- die.GetOffset(),
- DW_TAG_value_to_name(tag),
- type_name_cstr);
- }
+ if (record_decl) {
+ GetClangASTImporter().InsertRecordDecl(
+ record_decl, ClangASTImporter::LayoutInfo());
+ }
+ }
+ } else if (clang_type_was_created) {
+ // Start the definition if the class is not objective C since
+ // the underlying decls respond to isCompleteDefinition(). Objective
+ // C decls don't respond to isCompleteDefinition() so we can't
+ // start the declaration definition right away. For C++
+ // class/union/structs
+ // we want to start the definition in case the class is needed as
+ // the
+ // declaration context for a contained class or type without the
+ // need
+ // to complete that type..
+
+ if (class_language != eLanguageTypeObjC &&
+ class_language != eLanguageTypeObjC_plus_plus)
+ ClangASTContext::StartTagDeclarationDefinition(clang_type);
+
+ // Leave this as a forward declaration until we need
+ // to know the details of the type. lldb_private::Type
+ // will automatically call the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)"
+ // When the definition needs to be defined.
+ assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()) &&
+ "Type already in the forward declaration map!");
+ // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF,
+ // it can be a
+ // SymbolFileDWARFDebugMap for Apple binaries.
+ dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
+ clang_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()
+ [ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()] = die.GetDIERef();
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+ }
+ }
+ } break;
- // See if the type comes from a DWO module and if so, track down that type.
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
-
- if (!type_sp)
- {
- SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
- type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
- }
- }
+ case DW_TAG_enumeration_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
- if (type_sp)
- {
- if (log)
- {
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
- static_cast<void*>(this),
- die.GetOffset(),
- DW_TAG_value_to_name(tag),
- type_name_cstr,
- type_sp->GetID());
- }
+ DWARFFormValue encoding_form;
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
- dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
- }
- assert (tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type.SetCompilerType(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE()));
- if (!clang_type)
- {
- clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (die, nullptr);
- if (accessibility == eAccessNone && decl_ctx)
- {
- // Check the decl context that contains this class/struct/union.
- // If it is a class we must give it an accessibility.
- const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
- if (DeclKindIsCXXClass (containing_decl_kind))
- accessibility = default_accessibility;
- }
+ 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_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
+ case DW_AT_type:
+ encoding_form = form_value;
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_accessibility:
+ break; // accessibility =
+ // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+ case DW_AT_declaration:
+ is_forward_declaration = form_value.Boolean();
+ break;
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_bit_stride:
+ case DW_AT_byte_stride:
+ case DW_AT_data_location:
+ case DW_AT_description:
+ case DW_AT_start_scope:
+ case DW_AT_visibility:
+ case DW_AT_specification:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
+
+ if (is_forward_declaration) {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ type_sp =
+ dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in
+ // this DWARF, see if we have a declaration anywhere
+ // else...
+ type_sp =
+ debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
- metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual (die));
-
- if (type_name_cstr && strchr (type_name_cstr, '<'))
- {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- if (ParseTemplateParameterInfos (die, template_param_infos))
- {
- clang::ClassTemplateDecl *class_template_decl = m_ast.ParseClassTemplateDecl (decl_ctx,
- accessibility,
- type_name_cstr,
- tag_decl_kind,
- template_param_infos);
-
- clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl (decl_ctx,
- class_template_decl,
- tag_decl_kind,
- template_param_infos);
- clang_type = m_ast.CreateClassTemplateSpecializationType (class_specialization_decl);
- clang_type_was_created = true;
-
- m_ast.SetMetadata (class_template_decl, metadata);
- m_ast.SetMetadata (class_specialization_decl, metadata);
- }
- }
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr,
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere
+ // so lets use it and cache the fact that we found
+ // a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(
+ DIERef(type_sp->GetID(), dwarf)));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ CompilerType enumerator_clang_type;
+ clang_type.SetCompilerType(
+ &m_ast,
+ dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ if (encoding_form.IsValid()) {
+ Type *enumerator_type =
+ dwarf->ResolveTypeUID(DIERef(encoding_form));
+ if (enumerator_type)
+ enumerator_clang_type = enumerator_type->GetFullCompilerType();
+ }
- if (!clang_type_was_created)
- {
- clang_type_was_created = true;
- clang_type = m_ast.CreateRecordType (decl_ctx,
- accessibility,
- type_name_cstr,
- tag_decl_kind,
- class_language,
- &metadata);
- }
- }
+ if (!enumerator_clang_type) {
+ if (byte_size > 0) {
+ enumerator_clang_type =
+ m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
+ NULL, DW_ATE_signed, byte_size * 8);
+ } else {
+ enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
+ }
+ }
- // Store a forward declaration to this class type in case any
- // parameters in any class methods need it for the clang
- // types for function prototypes.
- LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
- type_sp.reset (new Type (die.GetID(),
- dwarf,
- type_name_const_str,
- byte_size,
- NULL,
- LLDB_INVALID_UID,
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateForward));
-
- type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
-
-
- // Add our type to the unique type map so we don't
- // end up creating many copies of the same type over
- // and over in the ASTContext for our module
- unique_ast_entry_ap->m_type_sp = type_sp;
- unique_ast_entry_ap->m_die = die;
- unique_ast_entry_ap->m_declaration = unique_decl;
- unique_ast_entry_ap->m_byte_size = byte_size;
- dwarf->GetUniqueDWARFASTTypeMap().Insert (unique_typename,
- *unique_ast_entry_ap);
-
- if (is_forward_declaration && die.HasChildren())
- {
- // Check to see if the DIE actually has a definition, some version of GCC will
- // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram,
- // members, or inheritance, so we can't trust it
- DWARFDIE child_die = die.GetFirstChild();
- while (child_die)
- {
- switch (child_die.Tag())
- {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- child_die.Clear();
- is_forward_declaration = false;
- break;
- default:
- child_die = child_die.GetSibling();
- break;
- }
- }
- }
+ clang_type = m_ast.CreateEnumerationType(
+ type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
+ decl, enumerator_clang_type);
+ } else {
+ enumerator_clang_type =
+ m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+ }
+
+ LinkDeclContextToDIE(
+ ClangASTContext::GetDeclContextForType(clang_type), die);
+
+ type_sp.reset(new Type(
+ die.GetID(), dwarf, type_name_const_str, byte_size, NULL,
+ DIERef(encoding_form).GetUID(dwarf), Type::eEncodingIsUID, &decl,
+ clang_type, Type::eResolveStateForward));
+
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ if (die.HasChildren()) {
+ SymbolContext cu_sc(die.GetLLDBCompileUnit());
+ bool is_signed = false;
+ enumerator_clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(cu_sc, clang_type, is_signed,
+ type_sp->GetByteSize(), die);
+ }
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), type_name_cstr);
+ }
+ }
+ } break;
+
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ DWARFFormValue type_die_form;
+ bool is_variadic = false;
+ bool is_inline = false;
+ bool is_static = false;
+ bool is_virtual = false;
+ bool is_explicit = false;
+ bool is_artificial = false;
+ bool has_template_params = false;
+ DWARFFormValue specification_die_form;
+ DWARFFormValue abstract_origin_die_form;
+ dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
+
+ unsigned type_quals = 0;
+ clang::StorageClass storage =
+ clang::SC_None; //, Extern, Static, PrivateExtern
- 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
- if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
- {
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
- }
- else
- {
- dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
- die.GetOffset(),
- type_name_cstr);
- }
+ 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_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
- clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type);
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ break; // mangled =
+ // form_value.AsCString(&dwarf->get_debug_str_data());
+ // break;
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
+ case DW_AT_declaration:
+ break; // is_forward_declaration = form_value.Boolean(); break;
+ case DW_AT_inline:
+ is_inline = form_value.Boolean();
+ break;
+ case DW_AT_virtuality:
+ is_virtual = form_value.Boolean();
+ break;
+ case DW_AT_explicit:
+ is_explicit = form_value.Boolean();
+ break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
- if (record_decl)
- {
- GetClangASTImporter().InsertRecordDecl(record_decl, ClangASTImporter::LayoutInfo());
- }
- }
- }
- else if (clang_type_was_created)
- {
- // Start the definition if the class is not objective C since
- // the underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++ class/union/structs
- // we want to start the definition in case the class is needed as the
- // declaration context for a contained class or type without the need
- // to complete that type..
-
- if (class_language != eLanguageTypeObjC &&
- class_language != eLanguageTypeObjC_plus_plus)
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
-
- // Leave this as a forward declaration until we need
- // to know the details of the type. lldb_private::Type
- // will automatically call the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)"
- // When the definition needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(
- ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
- "Type already in the forward declaration map!");
- // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF, it can be a
- // SymbolFileDWARFDebugMap for Apple binaries.
- dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()[ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()] = die.GetDIERef();
- m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true);
- }
- }
+ 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_TAG_enumeration_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- DWARFFormValue encoding_form;
-
- 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_type: encoding_form = form_value; break;
- case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
- case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_bit_stride:
- case DW_AT_byte_stride:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
-
- if (is_forward_declaration)
- {
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
-
- if (!type_sp)
- {
- SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
- type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
- }
- }
-
- if (type_sp)
- {
- if (log)
- {
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
- static_cast<void*>(this),
- die.GetOffset(),
- DW_TAG_value_to_name(tag),
- type_name_cstr,
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
+ break;
- }
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
-
- CompilerType enumerator_clang_type;
- clang_type.SetCompilerType (&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE()));
- if (!clang_type)
- {
- if (encoding_form.IsValid())
- {
- Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form));
- if (enumerator_type)
- enumerator_clang_type = enumerator_type->GetFullCompilerType ();
- }
+ case DW_AT_specification:
+ specification_die_form = form_value;
+ break;
- if (!enumerator_clang_type)
- {
- if (byte_size > 0)
- {
- enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(NULL,
- DW_ATE_signed,
- byte_size * 8);
- }
- else
- {
- enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
- }
- }
+ case DW_AT_abstract_origin:
+ abstract_origin_die_form = form_value;
+ break;
- clang_type = m_ast.CreateEnumerationType (type_name_cstr,
- GetClangDeclContextContainingDIE (die, nullptr),
- decl,
- enumerator_clang_type);
- }
- else
- {
- enumerator_clang_type = m_ast.GetEnumerationIntegerType (clang_type.GetOpaqueQualType());
- }
+ case DW_AT_object_pointer:
+ object_pointer_die_offset = form_value.Reference();
+ break;
- LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
-
- type_sp.reset( new Type (die.GetID(),
- dwarf,
- type_name_const_str,
- byte_size,
- NULL,
- DIERef(encoding_form).GetUID(dwarf),
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateForward));
-
- if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
- {
- if (die.HasChildren())
- {
- SymbolContext cu_sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- enumerator_clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die);
- }
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
- }
- else
- {
- dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
- die.GetOffset(),
- type_name_cstr);
- }
- }
- }
- break;
-
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- DWARFFormValue type_die_form;
- bool is_variadic = false;
- bool is_inline = false;
- bool is_static = false;
- bool is_virtual = false;
- bool is_explicit = false;
- bool is_artificial = false;
- bool has_template_params = false;
- DWARFFormValue specification_die_form;
- DWARFFormValue abstract_origin_die_form;
- dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
-
- unsigned type_quals = 0;
- 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&dwarf->get_debug_str_data()); break;
- case DW_AT_type: type_die_form = form_value; break;
- case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_inline: is_inline = form_value.Boolean(); break;
- case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
- case DW_AT_explicit: is_explicit = form_value.Boolean(); break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); 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_specification:
- specification_die_form = form_value;
- break;
-
- case DW_AT_abstract_origin:
- abstract_origin_die_form = form_value;
- break;
-
- case DW_AT_object_pointer:
- object_pointer_die_offset = form_value.Reference();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_address_class:
- case DW_AT_calling_convention:
- case DW_AT_data_location:
- case DW_AT_elemental:
- case DW_AT_entry_pc:
- case DW_AT_frame_base:
- case DW_AT_high_pc:
- case DW_AT_low_pc:
- case DW_AT_prototyped:
- case DW_AT_pure:
- case DW_AT_ranges:
- case DW_AT_recursive:
- case DW_AT_return_addr:
- case DW_AT_segment:
- case DW_AT_start_scope:
- case DW_AT_static_link:
- case DW_AT_trampoline:
- case DW_AT_visibility:
- case DW_AT_vtable_elem_location:
- case DW_AT_description:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_address_class:
+ case DW_AT_calling_convention:
+ case DW_AT_data_location:
+ case DW_AT_elemental:
+ case DW_AT_entry_pc:
+ case DW_AT_frame_base:
+ case DW_AT_high_pc:
+ case DW_AT_low_pc:
+ case DW_AT_prototyped:
+ case DW_AT_pure:
+ case DW_AT_ranges:
+ case DW_AT_recursive:
+ case DW_AT_return_addr:
+ case DW_AT_segment:
+ case DW_AT_start_scope:
+ case DW_AT_static_link:
+ case DW_AT_trampoline:
+ case DW_AT_visibility:
+ case DW_AT_vtable_elem_location:
+ case DW_AT_description:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
+ }
- std::string object_pointer_name;
- if (object_pointer_die_offset != DW_INVALID_OFFSET)
- {
- DWARFDIE object_pointer_die = die.GetDIE (object_pointer_die_offset);
- if (object_pointer_die)
- {
- const char *object_pointer_name_cstr = object_pointer_die.GetName();
- if (object_pointer_name_cstr)
- object_pointer_name = object_pointer_name_cstr;
- }
- }
+ std::string object_pointer_name;
+ if (object_pointer_die_offset != DW_INVALID_OFFSET) {
+ DWARFDIE object_pointer_die = die.GetDIE(object_pointer_die_offset);
+ if (object_pointer_die) {
+ const char *object_pointer_name_cstr = object_pointer_die.GetName();
+ if (object_pointer_name_cstr)
+ object_pointer_name = object_pointer_name_cstr;
+ }
+ }
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- CompilerType return_clang_type;
- Type *func_type = NULL;
+ CompilerType return_clang_type;
+ Type *func_type = NULL;
- if (type_die_form.IsValid())
- func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+ if (type_die_form.IsValid())
+ func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
- if (func_type)
- return_clang_type = func_type->GetForwardCompilerType ();
- else
- return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
+ if (func_type)
+ return_clang_type = func_type->GetForwardCompilerType();
+ else
+ return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
+ std::vector<CompilerType> function_param_types;
+ std::vector<clang::ParmVarDecl *> function_param_decls;
- std::vector<CompilerType> function_param_types;
- std::vector<clang::ParmVarDecl*> function_param_decls;
+ // Parse the function children for the parameters
- // Parse the function children for the parameters
+ DWARFDIE decl_ctx_die;
+ clang::DeclContext *containing_decl_ctx =
+ GetClangDeclContextContainingDIE(die, &decl_ctx_die);
+ const clang::Decl::Kind containing_decl_kind =
+ containing_decl_ctx->getDeclKind();
- DWARFDIE decl_ctx_die;
- clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, &decl_ctx_die);
- const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
+ bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
+ // Start off static. This will be set to false in
+ // ParseChildParameters(...)
+ // if we find a "this" parameters as the first parameter
+ if (is_cxx_method) {
+ is_static = true;
+ }
- bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
- // Start off static. This will be set to false in ParseChildParameters(...)
- // if we find a "this" parameters as the first parameter
- if (is_cxx_method)
- {
- is_static = true;
- }
+ 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);
+ }
- 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);
- }
+ bool ignore_containing_context = false;
+ // Check for templatized class member functions. If we had any
+ // DW_TAG_template_type_parameter
+ // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we
+ // can't let this become
+ // a method in a class. Why? Because templatized functions are only
+ // emitted if one of the
+ // templatized methods is used in the current compile unit and we will
+ // end up with classes
+ // that may or may not include these member functions and this means one
+ // class won't match another
+ // class definition and it affects our ability to use a class in the
+ // clang expression parser. So
+ // for the greater good, we currently must not allow any template member
+ // functions in a class definition.
+ if (is_cxx_method && has_template_params) {
+ ignore_containing_context = true;
+ is_cxx_method = false;
+ }
- bool ignore_containing_context = false;
- // Check for templatized class member functions. If we had any DW_TAG_template_type_parameter
- // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we can't let this become
- // a method in a class. Why? Because templatized functions are only emitted if one of the
- // templatized methods is used in the current compile unit and we will end up with classes
- // that may or may not include these member functions and this means one class won't match another
- // class definition and it affects our ability to use a class in the clang expression parser. So
- // for the greater good, we currently must not allow any template member functions in a class definition.
- if (is_cxx_method && has_template_params)
- {
- ignore_containing_context = true;
- is_cxx_method = false;
+ // clang_type will get the function prototype clang type after this call
+ clang_type = m_ast.CreateFunctionType(
+ return_clang_type, function_param_types.data(),
+ function_param_types.size(), is_variadic, type_quals);
+
+ if (type_name_cstr) {
+ bool type_handled = false;
+ if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
+ ObjCLanguage::MethodName objc_method(type_name_cstr, true);
+ if (objc_method.IsValid(true)) {
+ CompilerType class_opaque_type;
+ ConstString class_name(objc_method.GetClassName());
+ if (class_name) {
+ TypeSP complete_objc_class_type_sp(
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(
+ DWARFDIE(), class_name, false));
+
+ if (complete_objc_class_type_sp) {
+ CompilerType type_clang_forward_type =
+ complete_objc_class_type_sp->GetForwardCompilerType();
+ if (ClangASTContext::IsObjCObjectOrInterfaceType(
+ type_clang_forward_type))
+ class_opaque_type = type_clang_forward_type;
+ }
+ }
+
+ if (class_opaque_type) {
+ // If accessibility isn't set to anything valid, assume public
+ // for
+ // now...
+ if (accessibility == eAccessNone)
+ accessibility = eAccessPublic;
+
+ clang::ObjCMethodDecl *objc_method_decl =
+ m_ast.AddMethodToObjCObjectType(
+ class_opaque_type, type_name_cstr, clang_type,
+ accessibility, is_artificial, is_variadic);
+ type_handled = objc_method_decl != NULL;
+ if (type_handled) {
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(objc_method_decl), die);
+ m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: invalid Objective-C method 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));
+ }
+ }
+ } else if (is_cxx_method) {
+ // Look at the parent of this DIE and see if is is
+ // a class or struct and see if this is actually a
+ // C++ method
+ Type *class_type = dwarf->ResolveType(decl_ctx_die);
+ if (class_type) {
+ bool alternate_defn = false;
+ if (class_type->GetID() != decl_ctx_die.GetID() ||
+ decl_ctx_die.GetContainingDWOModuleDIE()) {
+ alternate_defn = true;
+
+ // We uniqued the parent class of this function to another
+ // class
+ // so we now need to associate all dies under "decl_ctx_die"
+ // to
+ // DIEs in the DIE for "class_type"...
+ SymbolFileDWARF *class_symfile = NULL;
+ DWARFDIE class_type_die;
+
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(
+ SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(
+ class_type->GetID()));
+ class_type_die = class_symfile->DebugInfo()->GetDIE(
+ DIERef(class_type->GetID(), dwarf));
+ } else {
+ class_symfile = dwarf;
+ class_type_die = dwarf->DebugInfo()->GetDIE(
+ DIERef(class_type->GetID(), dwarf));
+ }
+ if (class_type_die) {
+ DWARFDIECollection failures;
+
+ CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
+ class_type, failures);
+
+ // FIXME do something with these failures that's smarter
+ // than
+ // just dropping them on the ground. Unfortunately classes
+ // don't
+ // like having stuff added to them after their definitions
+ // are
+ // complete...
+
+ type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
+ break;
}
+ }
+ }
- // clang_type will get the function prototype clang type after this call
- clang_type = m_ast.CreateFunctionType (return_clang_type,
- function_param_types.data(),
- function_param_types.size(),
- is_variadic,
- type_quals);
-
-
- if (type_name_cstr)
- {
- bool type_handled = false;
- if (tag == DW_TAG_subprogram ||
- tag == DW_TAG_inlined_subroutine)
- {
- ObjCLanguage::MethodName objc_method (type_name_cstr, true);
- if (objc_method.IsValid(true))
- {
- CompilerType class_opaque_type;
- ConstString class_name(objc_method.GetClassName());
- if (class_name)
- {
- TypeSP complete_objc_class_type_sp (dwarf->FindCompleteObjCDefinitionTypeForDIE (DWARFDIE(), class_name, false));
-
- if (complete_objc_class_type_sp)
- {
- CompilerType type_clang_forward_type = complete_objc_class_type_sp->GetForwardCompilerType ();
- if (ClangASTContext::IsObjCObjectOrInterfaceType(type_clang_forward_type))
- class_opaque_type = type_clang_forward_type;
- }
- }
-
- if (class_opaque_type)
- {
- // If accessibility isn't set to anything valid, assume public for
- // now...
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
-
- clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType (class_opaque_type,
- type_name_cstr,
- clang_type,
- accessibility,
- is_artificial,
- is_variadic);
- type_handled = objc_method_decl != NULL;
- if (type_handled)
- {
- LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
- m_ast.SetMetadataAsUserID (objc_method_decl, die.GetID());
- }
- else
- {
- dwarf->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid Objective-C method 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));
- }
- }
- }
- else if (is_cxx_method)
- {
- // Look at the parent of this DIE and see if is is
- // a class or struct and see if this is actually a
- // C++ method
- Type *class_type = dwarf->ResolveType (decl_ctx_die);
- if (class_type)
- {
- bool alternate_defn = false;
- if (class_type->GetID() != decl_ctx_die.GetID() || decl_ctx_die.GetContainingDWOModuleDIE())
- {
- alternate_defn = true;
-
- // We uniqued the parent class of this function to another class
- // so we now need to associate all dies under "decl_ctx_die" to
- // DIEs in the DIE for "class_type"...
- SymbolFileDWARF *class_symfile = NULL;
- DWARFDIE class_type_die;
-
- SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
- class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf));
- }
- else
- {
- class_symfile = dwarf;
- class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID(), dwarf));
- }
- if (class_type_die)
- {
- DWARFDIECollection failures;
-
- CopyUniqueClassMethodTypes (decl_ctx_die,
- class_type_die,
- class_type,
- failures);
-
- // FIXME do something with these failures that's smarter than
- // just dropping them on the ground. Unfortunately classes don't
- // like having stuff added to them after their definitions are
- // complete...
-
- type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- break;
- }
- }
- }
-
- if (specification_die_form.IsValid())
- {
- // We have a specification which we are going to base our function
- // prototype off of, so we need this type to be completed so that the
- // m_die_to_decl_ctx for the method in the specification has a valid
- // clang decl context.
- class_type->GetForwardCompilerType ();
- // If we have a specification, then the function type should have been
- // made with the specification and not with this die.
- DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(DIERef(specification_die_form));
- clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (spec_die);
- if (spec_clang_decl_ctx)
- {
- LinkDeclContextToDIE(spec_clang_decl_ctx, die);
- }
- else
- {
- dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64 ") has no decl\n",
- die.GetID(),
- specification_die_form.Reference());
- }
- type_handled = true;
- }
- else if (abstract_origin_die_form.IsValid())
- {
- // We have a specification which we are going to base our function
- // prototype off of, so we need this type to be completed so that the
- // m_die_to_decl_ctx for the method in the abstract origin has a valid
- // clang decl context.
- class_type->GetForwardCompilerType ();
-
- DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form));
- clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (abs_die);
- if (abs_clang_decl_ctx)
- {
- LinkDeclContextToDIE (abs_clang_decl_ctx, die);
- }
- else
- {
- dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64 ") has no decl\n",
- die.GetID(),
- abstract_origin_die_form.Reference());
- }
- type_handled = true;
- }
- else
- {
- CompilerType class_opaque_type = class_type->GetForwardCompilerType ();
- if (ClangASTContext::IsCXXClassType(class_opaque_type))
- {
- if (class_opaque_type.IsBeingDefined () || alternate_defn)
- {
- if (!is_static && !die.HasChildren())
- {
- // We have a C++ member function with no children (this pointer!)
- // and clang will get mad if we try and make a function that isn't
- // well formed in the DWARF, so we will just skip it...
- type_handled = true;
- }
- else
- {
- bool add_method = true;
- if (alternate_defn)
- {
- // If an alternate definition for the class exists, then add the method only if an
- // equivalent is not already present.
- clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(class_opaque_type.GetOpaqueQualType());
- if (record_decl)
- {
- for (auto method_iter = record_decl->method_begin();
- method_iter != record_decl->method_end();
- method_iter++)
- {
- clang::CXXMethodDecl *method_decl = *method_iter;
- if (method_decl->getNameInfo().getAsString() == std::string(type_name_cstr))
- {
- if (method_decl->getType() ==
- ClangUtil::GetQualType(clang_type))
- {
- add_method = false;
- LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(method_decl), die);
- type_handled = true;
-
- break;
- }
- }
- }
- }
- }
-
- if (add_method)
- {
- // REMOVE THE CRASH DESCRIPTION BELOW
- Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s",
- type_name_cstr,
- class_type->GetName().GetCString(),
- die.GetID(),
- dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str());
-
- const bool is_attr_used = false;
- // Neither GCC 4.2 nor clang++ currently set a valid accessibility
- // in the DWARF for C++ methods... Default to public for now...
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
-
- clang::CXXMethodDecl *cxx_method_decl;
- cxx_method_decl = m_ast.AddMethodToCXXRecordType (class_opaque_type.GetOpaqueQualType(),
- type_name_cstr,
- clang_type,
- accessibility,
- is_virtual,
- is_static,
- is_inline,
- is_explicit,
- is_attr_used,
- is_artificial);
-
- type_handled = cxx_method_decl != NULL;
-
- if (type_handled)
- {
- LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
-
- Host::SetCrashDescription (NULL);
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
-
- if (!object_pointer_name.empty())
- {
- metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf ("Setting object pointer name: %s on method object %p.\n",
- object_pointer_name.c_str(),
- static_cast<void*>(cxx_method_decl));
- }
- m_ast.SetMetadata (cxx_method_decl, metadata);
- }
- else
- {
- ignore_containing_context = true;
- }
- }
- }
- }
- else
- {
- // We were asked to parse the type for a method in a class, yet the
- // class hasn't been asked to complete itself through the
- // clang::ExternalASTSource protocol, so we need to just have the
- // class complete itself and do things the right way, then our
- // DIE should then have an entry in the dwarf->GetDIEToType() map. First
- // we need to modify the dwarf->GetDIEToType() so it doesn't think we are
- // trying to parse this DIE anymore...
- dwarf->GetDIEToType()[die.GetDIE()] = NULL;
-
- // Now we get the full type to force our class type to complete itself
- // using the clang::ExternalASTSource protocol which will parse all
- // base classes and all methods (including the method for this DIE).
- class_type->GetFullCompilerType ();
-
- // The type for this DIE should have been filled in the function call above
- type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- break;
- }
-
- // FIXME This is fixing some even uglier behavior but we really need to
- // uniq the methods of each class as well as the class itself.
- // <rdar://problem/11240464>
- type_handled = true;
- }
- }
- }
+ if (specification_die_form.IsValid()) {
+ // We have a specification which we are going to base our
+ // function
+ // prototype off of, so we need this type to be completed so
+ // that the
+ // m_die_to_decl_ctx for the method in the specification has a
+ // valid
+ // clang decl context.
+ class_type->GetForwardCompilerType();
+ // If we have a specification, then the function type should
+ // have been
+ // made with the specification and not with this die.
+ DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(
+ DIERef(specification_die_form));
+ clang::DeclContext *spec_clang_decl_ctx =
+ GetClangDeclContextForDIE(spec_die);
+ if (spec_clang_decl_ctx) {
+ LinkDeclContextToDIE(spec_clang_decl_ctx, die);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64
+ ") has no decl\n",
+ die.GetID(), specification_die_form.Reference());
+ }
+ type_handled = true;
+ } else if (abstract_origin_die_form.IsValid()) {
+ // We have a specification which we are going to base our
+ // function
+ // prototype off of, so we need this type to be completed so
+ // that the
+ // m_die_to_decl_ctx for the method in the abstract origin has
+ // a valid
+ // clang decl context.
+ class_type->GetForwardCompilerType();
+
+ DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE(
+ DIERef(abstract_origin_die_form));
+ clang::DeclContext *abs_clang_decl_ctx =
+ GetClangDeclContextForDIE(abs_die);
+ if (abs_clang_decl_ctx) {
+ LinkDeclContextToDIE(abs_clang_decl_ctx, die);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64
+ ") has no decl\n",
+ die.GetID(), abstract_origin_die_form.Reference());
+ }
+ type_handled = true;
+ } else {
+ CompilerType class_opaque_type =
+ class_type->GetForwardCompilerType();
+ if (ClangASTContext::IsCXXClassType(class_opaque_type)) {
+ if (class_opaque_type.IsBeingDefined() || alternate_defn) {
+ if (!is_static && !die.HasChildren()) {
+ // We have a C++ member function with no children (this
+ // pointer!)
+ // and clang will get mad if we try and make a function
+ // that isn't
+ // well formed in the DWARF, so we will just skip it...
+ type_handled = true;
+ } else {
+ bool add_method = true;
+ if (alternate_defn) {
+ // If an alternate definition for the class exists,
+ // then add the method only if an
+ // equivalent is not already present.
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(
+ class_opaque_type.GetOpaqueQualType());
+ if (record_decl) {
+ for (auto method_iter = record_decl->method_begin();
+ method_iter != record_decl->method_end();
+ method_iter++) {
+ clang::CXXMethodDecl *method_decl = *method_iter;
+ if (method_decl->getNameInfo().getAsString() ==
+ std::string(type_name_cstr)) {
+ if (method_decl->getType() ==
+ ClangUtil::GetQualType(clang_type)) {
+ add_method = false;
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(
+ method_decl),
+ die);
+ type_handled = true;
+
+ break;
}
+ }
}
+ }
}
- if (!type_handled)
- {
- clang::FunctionDecl *function_decl = nullptr;
-
- if (abstract_origin_die_form.IsValid())
- {
- DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form));
-
- SymbolContext sc;
-
- if (dwarf->ResolveType (abs_die))
- {
- function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(GetCachedClangDeclContextForDIE(abs_die));
-
- if (function_decl)
- {
- LinkDeclContextToDIE(function_decl, die);
- }
- }
- }
+ if (add_method) {
+ llvm::PrettyStackTraceFormat stack_trace(
+ "SymbolFileDWARF::ParseType() is adding a method "
+ "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
+ type_name_cstr,
+ class_type->GetName().GetCString(), die.GetID(),
+ dwarf->GetObjectFile()
+ ->GetFileSpec()
+ .GetPath()
+ .c_str());
+
+ const bool is_attr_used = false;
+ // Neither GCC 4.2 nor clang++ currently set a valid
+ // accessibility
+ // in the DWARF for C++ methods... Default to public
+ // for now...
+ if (accessibility == eAccessNone)
+ accessibility = eAccessPublic;
+
+ clang::CXXMethodDecl *cxx_method_decl =
+ m_ast.AddMethodToCXXRecordType(
+ class_opaque_type.GetOpaqueQualType(),
+ type_name_cstr, clang_type, accessibility,
+ is_virtual, is_static, is_inline, is_explicit,
+ is_attr_used, is_artificial);
+
+ type_handled = cxx_method_decl != NULL;
+
+ if (type_handled) {
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(
+ cxx_method_decl),
+ die);
- if (!function_decl)
- {
- // We just have a function that isn't part of a class
- function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx,
- type_name_cstr,
- clang_type,
- storage,
- is_inline);
-
- // if (template_param_infos.GetSize() > 0)
- // {
- // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx,
- // function_decl,
- // type_name_cstr,
- // template_param_infos);
- //
- // CreateFunctionTemplateSpecializationInfo (function_decl,
- // func_template_decl,
- // template_param_infos);
- // }
- // Add the decl to our DIE to decl context map
-
- lldbassert (function_decl);
-
- if (function_decl)
- {
- LinkDeclContextToDIE(function_decl, die);
-
- if (!function_param_decls.empty())
- m_ast.SetFunctionParameters (function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
-
- if (!object_pointer_name.empty())
- {
- metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf ("Setting object pointer name: %s on function object %p.",
- object_pointer_name.c_str(),
- static_cast<void*>(function_decl));
- }
- m_ast.SetMetadata (function_decl, metadata);
- }
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+
+ if (!object_pointer_name.empty()) {
+ metadata.SetObjectPtrName(
+ object_pointer_name.c_str());
+ if (log)
+ log->Printf(
+ "Setting object pointer name: %s on method "
+ "object %p.\n",
+ object_pointer_name.c_str(),
+ static_cast<void *>(cxx_method_decl));
}
+ m_ast.SetMetadata(cxx_method_decl, metadata);
+ } else {
+ ignore_containing_context = true;
+ }
}
+ }
+ } else {
+ // We were asked to parse the type for a method in a
+ // class, yet the
+ // class hasn't been asked to complete itself through the
+ // clang::ExternalASTSource protocol, so we need to just
+ // have the
+ // class complete itself and do things the right way, then
+ // our
+ // DIE should then have an entry in the
+ // dwarf->GetDIEToType() map. First
+ // we need to modify the dwarf->GetDIEToType() so it
+ // doesn't think we are
+ // trying to parse this DIE anymore...
+ dwarf->GetDIEToType()[die.GetDIE()] = NULL;
+
+ // Now we get the full type to force our class type to
+ // complete itself
+ // using the clang::ExternalASTSource protocol which will
+ // parse all
+ // base classes and all methods (including the method for
+ // this DIE).
+ class_type->GetFullCompilerType();
+
+ // The type for this DIE should have been filled in the
+ // function call above
+ type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
+ break;
+ }
+
+ // FIXME This is fixing some even uglier behavior but we
+ // really need to
+ // uniq the methods of each class as well as the class
+ // itself.
+ // <rdar://problem/11240464>
+ type_handled = true;
}
- type_sp.reset( new Type (die.GetID(),
- dwarf,
- type_name_const_str,
- 0,
- NULL,
- LLDB_INVALID_UID,
- Type::eEncodingIsUID,
- &decl,
- clang_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->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- DWARFFormValue type_die_form;
- int64_t first_index = 0;
- uint32_t byte_stride = 0;
- uint32_t bit_stride = 0;
- bool is_vector = 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- 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_form = form_value; break;
- case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break;
- case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
- case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
- case DW_AT_GNU_vector: is_vector = form_value.Boolean(); break;
- case DW_AT_accessibility: break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_ordering:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
+ }
+ }
+ }
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
-
- DIERef type_die_ref(type_die_form);
- 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);
- 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)
- {
- ModuleSP module_sp = die.GetModule();
- if (module_sp)
- {
- if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
- module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info or disable -gmodule",
- die.GetOffset(),
- type_die_ref.die_offset);
- else
- module_sp->ReportError ("DWARF DW_TAG_array_type DIE at 0x%8.8x has a class/union/struct element type DIE 0x%8.8x that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
- die.GetOffset(),
- type_die_ref.die_offset,
- die.GetLLDBCompileUnit() ? die.GetLLDBCompileUnit()->GetPath().c_str() : "the source file");
- }
+ if (!type_handled) {
+ clang::FunctionDecl *function_decl = nullptr;
- // We have no choice other than to pretend that the element class type
- // is complete. If we don't do this, clang will crash when trying
- // to layout the class. Since we provide layout assistance, all
- // ivars in this class and other classes will be fine, this is
- // the best we can do short of crashing.
- if (ClangASTContext::StartTagDeclarationDefinition(array_element_type))
- {
- ClangASTContext::CompleteTagDeclarationDefinition(array_element_type);
- }
- else
- {
- module_sp->ReportError ("DWARF DIE at 0x%8.8x was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
- type_die_ref.die_offset);
- }
- }
+ if (abstract_origin_die_form.IsValid()) {
+ DWARFDIE abs_die =
+ dwarf->DebugInfo()->GetDIE(DIERef(abstract_origin_die_form));
- uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
- if (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)
- {
- num_elements = *pos;
- clang_type = m_ast.CreateArrayType (array_element_type,
- num_elements,
- is_vector);
- array_element_type = clang_type;
- array_element_bit_stride = num_elements ?
- array_element_bit_stride * num_elements :
- array_element_bit_stride;
- }
- }
- else
- {
- clang_type = m_ast.CreateArrayType (array_element_type, 0, is_vector);
- }
- ConstString empty_name;
- type_sp.reset( new Type (die.GetID(),
- dwarf,
- empty_name,
- array_element_bit_stride / 8,
- NULL,
- DIERef(type_die_form).GetUID(dwarf),
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateFull));
- type_sp->SetEncodingType (element_type);
- }
- }
+ SymbolContext sc;
+
+ if (dwarf->ResolveType(abs_die)) {
+ function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ GetCachedClangDeclContextForDIE(abs_die));
+
+ if (function_decl) {
+ LinkDeclContextToDIE(function_decl, die);
}
- break;
-
- case DW_TAG_ptr_to_member_type:
- {
- DWARFFormValue type_die_form;
- DWARFFormValue containing_type_die_form;
-
- 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_type:
- type_die_form = form_value; break;
- case DW_AT_containing_type:
- containing_type_die_form = form_value; break;
- }
- }
- }
+ }
+ }
- Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
- Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
+ if (!function_decl) {
+ // We just have a function that isn't part of a class
+ function_decl = m_ast.CreateFunctionDeclaration(
+ ignore_containing_context ? m_ast.GetTranslationUnitDecl()
+ : containing_decl_ctx,
+ type_name_cstr, clang_type, storage, is_inline);
+
+ // if (template_param_infos.GetSize() >
+ // 0)
+ // {
+ // clang::FunctionTemplateDecl
+ // *func_template_decl =
+ // CreateFunctionTemplateDecl
+ // (containing_decl_ctx,
+ // function_decl,
+ // type_name_cstr,
+ // template_param_infos);
+ //
+ // CreateFunctionTemplateSpecializationInfo
+ // (function_decl,
+ // func_template_decl,
+ // template_param_infos);
+ // }
+ // Add the decl to our DIE to decl context map
+
+ lldbassert(function_decl);
+
+ if (function_decl) {
+ LinkDeclContextToDIE(function_decl, die);
+
+ if (!function_param_decls.empty())
+ m_ast.SetFunctionParameters(function_decl,
+ &function_param_decls.front(),
+ function_param_decls.size());
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+
+ if (!object_pointer_name.empty()) {
+ metadata.SetObjectPtrName(object_pointer_name.c_str());
+ if (log)
+ log->Printf("Setting object pointer name: %s on function "
+ "object %p.",
+ object_pointer_name.c_str(),
+ static_cast<void *>(function_decl));
+ }
+ m_ast.SetMetadata(function_decl, metadata);
+ }
+ }
+ }
+ }
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, &decl,
+ clang_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->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ DWARFFormValue type_die_form;
+ int64_t first_index = 0;
+ uint32_t byte_stride = 0;
+ uint32_t bit_stride = 0;
+ bool is_vector = false;
+ const size_t num_attributes = die.GetAttributes(attributes);
- CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType ();
- CompilerType class_clang_type = class_type->GetLayoutCompilerType ();
-
- clang_type = ClangASTContext::CreateMemberPointerType(class_clang_type, pointee_clang_type);
+ 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_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
- byte_size = clang_type.GetByteSize(nullptr);
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_byte_size:
+ break; // byte_size = form_value.Unsigned(); break;
+ case DW_AT_byte_stride:
+ byte_stride = form_value.Unsigned();
+ break;
+ case DW_AT_bit_stride:
+ bit_stride = form_value.Unsigned();
+ break;
+ case DW_AT_GNU_vector:
+ is_vector = form_value.Boolean();
+ break;
+ case DW_AT_accessibility:
+ break; // accessibility =
+ // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+ case DW_AT_declaration:
+ break; // is_forward_declaration = form_value.Boolean(); break;
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_data_location:
+ case DW_AT_description:
+ case DW_AT_ordering:
+ case DW_AT_start_scope:
+ case DW_AT_visibility:
+ case DW_AT_specification:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
+
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ DIERef type_die_ref(type_die_form);
+ 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);
+ 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) {
+ ModuleSP module_sp = die.GetModule();
+ if (module_sp) {
+ if (die.GetCU()->GetProducer() ==
+ DWARFCompileUnit::eProducerClang)
+ module_sp->ReportError(
+ "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+ "class/union/struct element type DIE 0x%8.8x that is a "
+ "forward declaration, not a complete definition.\nTry "
+ "compiling the source file with -fno-limit-debug-info or "
+ "disable -gmodule",
+ die.GetOffset(), type_die_ref.die_offset);
+ else
+ module_sp->ReportError(
+ "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+ "class/union/struct element type DIE 0x%8.8x that is a "
+ "forward declaration, not a complete definition.\nPlease "
+ "file a bug against the compiler and include the "
+ "preprocessed output for %s",
+ die.GetOffset(), type_die_ref.die_offset,
+ die.GetLLDBCompileUnit()
+ ? die.GetLLDBCompileUnit()->GetPath().c_str()
+ : "the source file");
+ }
+
+ // We have no choice other than to pretend that the element class
+ // type
+ // is complete. If we don't do this, clang will crash when trying
+ // to layout the class. Since we provide layout assistance, all
+ // ivars in this class and other classes will be fine, this is
+ // the best we can do short of crashing.
+ if (ClangASTContext::StartTagDeclarationDefinition(
+ array_element_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(
+ array_element_type);
+ } else {
+ module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
+ "start its definition.\nPlease file a "
+ "bug and attach the file at the start "
+ "of this error message",
+ type_die_ref.die_offset);
+ }
+ }
- 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));
- }
+ uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
+ if (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) {
+ num_elements = *pos;
+ clang_type = m_ast.CreateArrayType(array_element_type,
+ num_elements, is_vector);
+ array_element_type = clang_type;
+ array_element_bit_stride =
+ num_elements ? array_element_bit_stride * num_elements
+ : array_element_bit_stride;
+ }
+ } else {
+ clang_type =
+ m_ast.CreateArrayType(array_element_type, 0, is_vector);
+ }
+ ConstString empty_name;
+ type_sp.reset(new Type(
+ die.GetID(), dwarf, empty_name, array_element_bit_stride / 8,
+ NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID,
+ &decl, clang_type, Type::eResolveStateFull));
+ type_sp->SetEncodingType(element_type);
+ }
+ }
+ } break;
- 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;
+ case DW_TAG_ptr_to_member_type: {
+ DWARFFormValue type_die_form;
+ DWARFFormValue containing_type_die_form;
+
+ 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_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_containing_type:
+ containing_type_die_form = form_value;
+ break;
+ }
}
+ }
- if (type_sp.get())
- {
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+ Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+ Type *class_type =
+ dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
- SymbolContextScope * symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_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;
- }
+ CompilerType pointee_clang_type =
+ pointee_type->GetForwardCompilerType();
+ CompilerType class_clang_type = class_type->GetLayoutCompilerType();
- if (symbol_context_scope != NULL)
- {
- type_sp->SetSymbolContextScope(symbol_context_scope);
- }
+ clang_type = ClangASTContext::CreateMemberPointerType(
+ class_clang_type, pointee_clang_type);
- // We are ready to put this type into the uniqued list up at the module level
- type_list->Insert (type_sp);
+ byte_size = clang_type.GetByteSize(nullptr);
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- }
+ 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));
}
- else if (type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
+
+ 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) {
+ 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->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ }
+ } else if (type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
}
- return type_sp;
+ }
+ return type_sp;
}
// DWARF parsing functions
-class DWARFASTParserClang::DelayedAddObjCClassProperty
-{
+class DWARFASTParserClang::DelayedAddObjCClassProperty {
public:
- DelayedAddObjCClassProperty(const CompilerType &class_opaque_type,
- const char *property_name,
- const CompilerType &property_opaque_type, // The property type is only required if you don't have an ivar decl
- clang::ObjCIvarDecl *ivar_decl,
- const char *property_setter_name,
- const char *property_getter_name,
- uint32_t property_attributes,
- const ClangASTMetadata *metadata) :
- m_class_opaque_type (class_opaque_type),
- m_property_name (property_name),
- m_property_opaque_type (property_opaque_type),
- m_ivar_decl (ivar_decl),
- m_property_setter_name (property_setter_name),
- m_property_getter_name (property_getter_name),
- m_property_attributes (property_attributes)
- {
- if (metadata != NULL)
- {
- m_metadata_ap.reset(new ClangASTMetadata());
- *m_metadata_ap = *metadata;
- }
+ DelayedAddObjCClassProperty(
+ const CompilerType &class_opaque_type, const char *property_name,
+ const CompilerType &property_opaque_type, // The property type is only
+ // required if you don't have an
+ // ivar decl
+ clang::ObjCIvarDecl *ivar_decl, const char *property_setter_name,
+ const char *property_getter_name, uint32_t property_attributes,
+ const ClangASTMetadata *metadata)
+ : m_class_opaque_type(class_opaque_type), m_property_name(property_name),
+ m_property_opaque_type(property_opaque_type), m_ivar_decl(ivar_decl),
+ m_property_setter_name(property_setter_name),
+ m_property_getter_name(property_getter_name),
+ m_property_attributes(property_attributes) {
+ if (metadata != NULL) {
+ m_metadata_ap.reset(new ClangASTMetadata());
+ *m_metadata_ap = *metadata;
}
-
- DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
- {
- *this = rhs;
+ }
+
+ DelayedAddObjCClassProperty(const DelayedAddObjCClassProperty &rhs) {
+ *this = rhs;
+ }
+
+ DelayedAddObjCClassProperty &
+ operator=(const DelayedAddObjCClassProperty &rhs) {
+ m_class_opaque_type = rhs.m_class_opaque_type;
+ m_property_name = rhs.m_property_name;
+ m_property_opaque_type = rhs.m_property_opaque_type;
+ m_ivar_decl = rhs.m_ivar_decl;
+ m_property_setter_name = rhs.m_property_setter_name;
+ m_property_getter_name = rhs.m_property_getter_name;
+ m_property_attributes = rhs.m_property_attributes;
+
+ if (rhs.m_metadata_ap.get()) {
+ m_metadata_ap.reset(new ClangASTMetadata());
+ *m_metadata_ap = *rhs.m_metadata_ap;
}
+ return *this;
+ }
- DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
- {
- m_class_opaque_type = rhs.m_class_opaque_type;
- m_property_name = rhs.m_property_name;
- m_property_opaque_type = rhs.m_property_opaque_type;
- m_ivar_decl = rhs.m_ivar_decl;
- m_property_setter_name = rhs.m_property_setter_name;
- m_property_getter_name = rhs.m_property_getter_name;
- m_property_attributes = rhs.m_property_attributes;
-
- if (rhs.m_metadata_ap.get())
- {
- m_metadata_ap.reset (new ClangASTMetadata());
- *m_metadata_ap = *rhs.m_metadata_ap;
- }
- return *this;
- }
-
- bool
- Finalize()
- {
- return ClangASTContext::AddObjCClassProperty (m_class_opaque_type,
- m_property_name,
- m_property_opaque_type,
- m_ivar_decl,
- m_property_setter_name,
- m_property_getter_name,
- m_property_attributes,
- m_metadata_ap.get());
- }
+ bool Finalize() {
+ return ClangASTContext::AddObjCClassProperty(
+ m_class_opaque_type, m_property_name, m_property_opaque_type,
+ m_ivar_decl, m_property_setter_name, m_property_getter_name,
+ m_property_attributes, m_metadata_ap.get());
+ }
private:
- CompilerType m_class_opaque_type;
- const char *m_property_name;
- CompilerType m_property_opaque_type;
- clang::ObjCIvarDecl *m_ivar_decl;
- const char *m_property_setter_name;
- const char *m_property_getter_name;
- uint32_t m_property_attributes;
- std::unique_ptr<ClangASTMetadata> m_metadata_ap;
+ CompilerType m_class_opaque_type;
+ const char *m_property_name;
+ CompilerType m_property_opaque_type;
+ clang::ObjCIvarDecl *m_ivar_decl;
+ const char *m_property_setter_name;
+ const char *m_property_getter_name;
+ uint32_t m_property_attributes;
+ std::unique_ptr<ClangASTMetadata> m_metadata_ap;
};
-bool
-DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
- ClangASTContext::TemplateParameterInfos &template_param_infos)
-{
- const dw_tag_t tag = die.Tag();
-
- switch (tag)
- {
- case DW_TAG_template_type_parameter:
- case DW_TAG_template_value_parameter:
- {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes (attributes);
- const char *name = nullptr;
- CompilerType clang_type;
- uint64_t uval64 = 0;
- bool uval64_valid = false;
- if (num_attributes > 0)
- {
- DWARFFormValue form_value;
- for (size_t i=0; i<num_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
-
- switch (attr)
- {
- case DW_AT_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- name = form_value.AsCString();
- break;
-
- case DW_AT_type:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
- if (lldb_type)
- clang_type = lldb_type->GetForwardCompilerType ();
- }
- break;
+bool DWARFASTParserClang::ParseTemplateDIE(
+ const DWARFDIE &die,
+ ClangASTContext::TemplateParameterInfos &template_param_infos) {
+ const dw_tag_t tag = die.Tag();
- case DW_AT_const_value:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- uval64_valid = true;
- uval64 = form_value.Unsigned();
- }
- break;
- default:
- break;
- }
- }
+ switch (tag) {
+ case DW_TAG_template_type_parameter:
+ case DW_TAG_template_value_parameter: {
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ const char *name = nullptr;
+ CompilerType clang_type;
+ uint64_t uval64 = 0;
+ bool uval64_valid = false;
+ if (num_attributes > 0) {
+ DWARFFormValue form_value;
+ for (size_t i = 0; i < num_attributes; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+
+ switch (attr) {
+ case DW_AT_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_type:
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
+ if (lldb_type)
+ clang_type = lldb_type->GetForwardCompilerType();
+ }
+ break;
+
+ case DW_AT_const_value:
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ uval64_valid = true;
+ uval64 = form_value.Unsigned();
+ }
+ break;
+ default:
+ break;
+ }
+ }
- clang::ASTContext *ast = m_ast.getASTContext();
- if (!clang_type)
- clang_type = m_ast.GetBasicType(eBasicTypeVoid);
-
- if (clang_type)
- {
- bool is_signed = false;
- if (name && name[0])
- template_param_infos.names.push_back(name);
- else
- template_param_infos.names.push_back(NULL);
-
- // Get the signed value for any integer or enumeration if available
- clang_type.IsIntegerOrEnumerationType (is_signed);
-
- if (tag == DW_TAG_template_value_parameter && uval64_valid)
- {
- llvm::APInt apint (clang_type.GetBitSize(nullptr), uval64, is_signed);
- template_param_infos.args.push_back(
- clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed), ClangUtil::GetQualType(clang_type)));
- }
- else
- {
- template_param_infos.args.push_back(
- clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
- }
- }
- else
- {
- return false;
- }
+ clang::ASTContext *ast = m_ast.getASTContext();
+ if (!clang_type)
+ clang_type = m_ast.GetBasicType(eBasicTypeVoid);
- }
+ if (clang_type) {
+ bool is_signed = false;
+ if (name && name[0])
+ template_param_infos.names.push_back(name);
+ else
+ template_param_infos.names.push_back(NULL);
+
+ // Get the signed value for any integer or enumeration if available
+ clang_type.IsIntegerOrEnumerationType(is_signed);
+
+ if (tag == DW_TAG_template_value_parameter && uval64_valid) {
+ llvm::APInt apint(clang_type.GetBitSize(nullptr), uval64, is_signed);
+ template_param_infos.args.push_back(
+ clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed),
+ ClangUtil::GetQualType(clang_type)));
+ } else {
+ template_param_infos.args.push_back(
+ clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
}
- return true;
-
- default:
- break;
+ } else {
+ return false;
+ }
}
- return false;
+ }
+ return true;
+
+ default:
+ break;
+ }
+ return false;
}
-bool
-DWARFASTParserClang::ParseTemplateParameterInfos (const DWARFDIE &parent_die,
- ClangASTContext::TemplateParameterInfos &template_param_infos)
-{
+bool DWARFASTParserClang::ParseTemplateParameterInfos(
+ const DWARFDIE &parent_die,
+ ClangASTContext::TemplateParameterInfos &template_param_infos) {
- if (!parent_die)
- return false;
+ if (!parent_die)
+ return false;
- Args template_parameter_names;
- for (DWARFDIE die = parent_die.GetFirstChild();
- die.IsValid();
- die = die.GetSibling())
- {
- const dw_tag_t tag = die.Tag();
+ Args template_parameter_names;
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
+ die = die.GetSibling()) {
+ const dw_tag_t tag = die.Tag();
- switch (tag)
- {
- case DW_TAG_template_type_parameter:
- case DW_TAG_template_value_parameter:
- ParseTemplateDIE (die, template_param_infos);
- break;
+ switch (tag) {
+ case DW_TAG_template_type_parameter:
+ case DW_TAG_template_value_parameter:
+ ParseTemplateDIE(die, template_param_infos);
+ break;
- default:
- break;
- }
+ default:
+ break;
}
- if (template_param_infos.args.empty())
- return false;
- return template_param_infos.args.size() == template_param_infos.names.size();
+ }
+ if (template_param_infos.args.empty())
+ return false;
+ return template_param_infos.args.size() == template_param_infos.names.size();
}
-bool
-DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type)
-{
- SymbolFileDWARF *dwarf = die.GetDWARF();
+bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
+ lldb_private::Type *type,
+ CompilerType &clang_type) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
- std::lock_guard<std::recursive_mutex> guard(dwarf->GetObjectFile()->GetModule()->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(
+ dwarf->GetObjectFile()->GetModule()->GetMutex());
- // Disable external storage for this type so we don't get anymore
- // clang::ExternalASTSource queries for this type.
- m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), false);
+ // Disable external storage for this type so we don't get anymore
+ // clang::ExternalASTSource queries for this type.
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), false);
- if (!die)
- return false;
+ if (!die)
+ return false;
#if defined LLDB_CONFIGURATION_DEBUG
- //----------------------------------------------------------------------
- // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES
- // environment variable can be set with one or more typenames separated
- // by ';' characters. This will cause this function to not complete any
- // types whose names match.
- //
- // Examples of setting this environment variable:
- //
- // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo
- // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz
- //----------------------------------------------------------------------
- const char *dont_complete_typenames_cstr = getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES");
- if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0])
- {
- const char *die_name = die.GetName();
- if (die_name && die_name[0])
- {
- const char *match = strstr(dont_complete_typenames_cstr, die_name);
- if (match)
- {
- size_t die_name_length = strlen(die_name);
- while (match)
- {
- const char separator_char = ';';
- const char next_char = match[die_name_length];
- if (next_char == '\0' || next_char == separator_char)
- {
- if (match == dont_complete_typenames_cstr || match[-1] == separator_char)
- return false;
- }
- match = strstr(match+1, die_name);
- }
- }
+ //----------------------------------------------------------------------
+ // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES
+ // environment variable can be set with one or more typenames separated
+ // by ';' characters. This will cause this function to not complete any
+ // types whose names match.
+ //
+ // Examples of setting this environment variable:
+ //
+ // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo
+ // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz
+ //----------------------------------------------------------------------
+ const char *dont_complete_typenames_cstr =
+ getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES");
+ if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0]) {
+ const char *die_name = die.GetName();
+ if (die_name && die_name[0]) {
+ const char *match = strstr(dont_complete_typenames_cstr, die_name);
+ if (match) {
+ size_t die_name_length = strlen(die_name);
+ while (match) {
+ const char separator_char = ';';
+ const char next_char = match[die_name_length];
+ if (next_char == '\0' || next_char == separator_char) {
+ if (match == dont_complete_typenames_cstr ||
+ match[-1] == separator_char)
+ return false;
+ }
+ match = strstr(match + 1, die_name);
}
+ }
}
+ }
#endif
- const dw_tag_t tag = die.Tag();
+ const dw_tag_t tag = die.Tag();
+
+ 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(), die.GetTagAsCString(), type->GetName().AsCString());
+ assert(clang_type);
+ DWARFAttributes attributes;
+ switch (tag) {
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type: {
+ ClangASTImporter::LayoutInfo layout_info;
- 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(),
- die.GetTagAsCString(),
- type->GetName().AsCString());
- assert (clang_type);
- DWARFAttributes attributes;
- switch (tag)
{
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- {
- ClangASTImporter::LayoutInfo layout_info;
-
- {
- if (die.HasChildren())
- {
- LanguageType class_language = eLanguageTypeUnknown;
- if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type))
- {
- class_language = eLanguageTypeObjC;
- // For objective C we don't start the definition when
- // the class is created.
- ClangASTContext::StartTagDeclarationDefinition (clang_type);
- }
-
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type)
- {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_union_type)
- {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_class_type)
- {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
+ if (die.HasChildren()) {
+ LanguageType class_language = eLanguageTypeUnknown;
+ if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) {
+ class_language = eLanguageTypeObjC;
+ // For objective C we don't start the definition when
+ // the class is created.
+ ClangASTContext::StartTagDeclarationDefinition(clang_type);
+ }
- SymbolContext sc(die.GetLLDBCompileUnit());
- std::vector<clang::CXXBaseSpecifier *> base_classes;
- 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,
- member_accessibilities,
- member_function_dies,
- delayed_properties,
- default_accessibility,
- is_a_class,
- layout_info);
-
- // Now parse any methods if there were any...
- size_t num_functions = member_function_dies.Size();
- if (num_functions > 0)
- {
- for (size_t i=0; i<num_functions; ++i)
- {
- dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i));
- }
- }
+ int tag_decl_kind = -1;
+ AccessType default_accessibility = eAccessNone;
+ if (tag == DW_TAG_structure_type) {
+ tag_decl_kind = clang::TTK_Struct;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_union_type) {
+ tag_decl_kind = clang::TTK_Union;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_class_type) {
+ tag_decl_kind = clang::TTK_Class;
+ default_accessibility = eAccessPrivate;
+ }
- if (class_language == eLanguageTypeObjC)
- {
- ConstString class_name (clang_type.GetTypeName());
- if (class_name)
- {
- DIEArray method_die_offsets;
- dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets);
-
- if (!method_die_offsets.empty())
- {
- DWARFDebugInfo* debug_info = dwarf->DebugInfo();
-
- const size_t num_matches = method_die_offsets.size();
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = method_die_offsets[i];
- DWARFDIE method_die = debug_info->GetDIE (die_ref);
-
- if (method_die)
- method_die.ResolveType ();
- }
- }
+ SymbolContext sc(die.GetLLDBCompileUnit());
+ std::vector<clang::CXXBaseSpecifier *> base_classes;
+ 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,
+ member_accessibilities, member_function_dies,
+ delayed_properties, default_accessibility, is_a_class,
+ layout_info);
+
+ // Now parse any methods if there were any...
+ size_t num_functions = member_function_dies.Size();
+ if (num_functions > 0) {
+ for (size_t i = 0; i < num_functions; ++i) {
+ dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i));
+ }
+ }
- for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
- pi != pe;
- ++pi)
- pi->Finalize();
- }
- }
+ if (class_language == eLanguageTypeObjC) {
+ ConstString class_name(clang_type.GetTypeName());
+ if (class_name) {
+ DIEArray method_die_offsets;
+ dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets);
- // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
- // need to tell the clang type it is actually a class.
- if (class_language != eLanguageTypeObjC)
- {
- if (is_a_class && tag_decl_kind != clang::TTK_Class)
- m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), clang::TTK_Class);
- }
+ if (!method_die_offsets.empty()) {
+ DWARFDebugInfo *debug_info = dwarf->DebugInfo();
- // Since DW_TAG_structure_type gets used for both classes
- // and structures, we may need to set any DW_TAG_member
- // fields to have a "private" access if none was specified.
- // When we parsed the child members we tracked that actual
- // accessibility value for each DW_TAG_member in the
- // "member_accessibilities" array. If the value for the
- // member is zero, then it was set to the "default_accessibility"
- // which for structs was "public". Below we correct this
- // by setting any fields to "private" that weren't correctly
- // set.
- if (is_a_class && !member_accessibilities.empty())
- {
- // This is a class and all members that didn't have
- // their access specified are private.
- m_ast.SetDefaultAccessForRecordFields (m_ast.GetAsRecordDecl(clang_type),
- eAccessPrivate,
- &member_accessibilities.front(),
- member_accessibilities.size());
- }
+ const size_t num_matches = method_die_offsets.size();
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = method_die_offsets[i];
+ DWARFDIE method_die = debug_info->GetDIE(die_ref);
- if (!base_classes.empty())
- {
- // Make sure all base classes refer to complete types and not
- // forward declarations. If we don't do this, clang will crash
- // with an assertion in the call to clang_type.SetBaseClassesForClassType()
- for (auto &base_class : base_classes)
- {
- 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)
- {
- auto module = dwarf->GetObjectFile()->GetModule();
- module->ReportError (
- ":: Class '%s' has a base class '%s' which does not have a complete definition.",
- die.GetName(),
- base_class_type.GetTypeName().GetCString());
- if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
- module->ReportError (":: Try compiling the source file with -fno-limit-debug-info.");
-
- // We have no choice other than to pretend that the base class
- // is complete. If we don't do this, clang will crash when we
- // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
- // below. Since we provide layout assistance, all ivars in this
- // class and other classes will be fine, this is the best we can do
- // short of crashing.
- if (ClangASTContext::StartTagDeclarationDefinition (base_class_type))
- {
- ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
- }
- }
- }
- }
- 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());
- }
- }
+ if (method_die)
+ method_die.ResolveType();
+ }
}
- ClangASTContext::BuildIndirectFields (clang_type);
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
+ for (DelayedPropertyList::iterator pi = delayed_properties.begin(),
+ pe = delayed_properties.end();
+ pi != pe; ++pi)
+ pi->Finalize();
+ }
+ }
- if (!layout_info.field_offsets.empty() ||
- !layout_info.base_offsets.empty() ||
- !layout_info.vbase_offsets.empty() )
- {
- if (type)
- layout_info.bit_size = type->GetByteSize() * 8;
- if (layout_info.bit_size == 0)
- layout_info.bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
-
- clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl)
- {
- if (log)
- {
- ModuleSP module_sp = dwarf->GetObjectFile()->GetModule();
-
- if (module_sp)
- {
- module_sp->LogMessage (log,
- "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
- static_cast<void*>(clang_type.GetOpaqueQualType()),
- static_cast<void*>(record_decl),
- layout_info.bit_size,
- layout_info.alignment,
- static_cast<uint32_t>(layout_info.field_offsets.size()),
- static_cast<uint32_t>(layout_info.base_offsets.size()),
- static_cast<uint32_t>(layout_info.vbase_offsets.size()));
-
- uint32_t idx;
- {
- llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos,
- end = layout_info.field_offsets.end();
- for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
- {
- module_sp->LogMessage(log,
- "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }",
- static_cast<void *>(clang_type.GetOpaqueQualType()),
- idx,
- static_cast<uint32_t>(pos->second),
- pos->first->getNameAsString().c_str());
- }
- }
+ // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
+ // need to tell the clang type it is actually a class.
+ if (class_language != eLanguageTypeObjC) {
+ if (is_a_class && tag_decl_kind != clang::TTK_Class)
+ m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type),
+ clang::TTK_Class);
+ }
- {
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos,
- base_end = layout_info.base_offsets.end();
- for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx)
- {
- module_sp->LogMessage(log,
- "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }",
- clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(),
- base_pos->first->getNameAsString().c_str());
- }
- }
- {
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos,
- vbase_end = layout_info.vbase_offsets.end();
- for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx)
- {
- module_sp->LogMessage(log,
- "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }",
- static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
- static_cast<uint32_t>(vbase_pos->second.getQuantity()),
- vbase_pos->first->getNameAsString().c_str());
- }
- }
+ // Since DW_TAG_structure_type gets used for both classes
+ // and structures, we may need to set any DW_TAG_member
+ // fields to have a "private" access if none was specified.
+ // When we parsed the child members we tracked that actual
+ // accessibility value for each DW_TAG_member in the
+ // "member_accessibilities" array. If the value for the
+ // member is zero, then it was set to the "default_accessibility"
+ // which for structs was "public". Below we correct this
+ // by setting any fields to "private" that weren't correctly
+ // set.
+ if (is_a_class && !member_accessibilities.empty()) {
+ // This is a class and all members that didn't have
+ // their access specified are private.
+ m_ast.SetDefaultAccessForRecordFields(
+ m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
+ &member_accessibilities.front(), member_accessibilities.size());
+ }
- }
- }
- GetClangASTImporter().InsertRecordDecl(record_decl, layout_info);
+ if (!base_classes.empty()) {
+ // Make sure all base classes refer to complete types and not
+ // forward declarations. If we don't do this, clang will crash
+ // with an assertion in the call to
+ // clang_type.SetBaseClassesForClassType()
+ for (auto &base_class : base_classes) {
+ 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) {
+ auto module = dwarf->GetObjectFile()->GetModule();
+ module->ReportError(":: Class '%s' has a base class '%s' which "
+ "does not have a complete definition.",
+ die.GetName(),
+ base_class_type.GetTypeName().GetCString());
+ if (die.GetCU()->GetProducer() ==
+ DWARFCompileUnit::eProducerClang)
+ module->ReportError(":: Try compiling the source file with "
+ "-fno-limit-debug-info.");
+
+ // We have no choice other than to pretend that the base class
+ // is complete. If we don't do this, clang will crash when we
+ // call setBases() inside of
+ // "clang_type.SetBaseClassesForClassType()"
+ // below. Since we provide layout assistance, all ivars in this
+ // class and other classes will be fine, this is the best we can
+ // do
+ // short of crashing.
+ if (ClangASTContext::StartTagDeclarationDefinition(
+ base_class_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(
+ base_class_type);
}
+ }
}
+ }
+ 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());
}
+ }
+ }
- return (bool)clang_type;
-
- case DW_TAG_enumeration_type:
- if (ClangASTContext::StartTagDeclarationDefinition (clang_type))
+ ClangASTContext::BuildIndirectFields(clang_type);
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+
+ if (!layout_info.field_offsets.empty() ||
+ !layout_info.base_offsets.empty() ||
+ !layout_info.vbase_offsets.empty()) {
+ if (type)
+ layout_info.bit_size = type->GetByteSize() * 8;
+ if (layout_info.bit_size == 0)
+ layout_info.bit_size =
+ die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl) {
+ if (log) {
+ ModuleSP module_sp = dwarf->GetObjectFile()->GetModule();
+
+ if (module_sp) {
+ module_sp->LogMessage(
+ log,
+ "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) "
+ "caching layout info for record_decl = %p, bit_size = %" PRIu64
+ ", alignment = %" PRIu64
+ ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
+ static_cast<void *>(clang_type.GetOpaqueQualType()),
+ static_cast<void *>(record_decl), layout_info.bit_size,
+ layout_info.alignment,
+ static_cast<uint32_t>(layout_info.field_offsets.size()),
+ static_cast<uint32_t>(layout_info.base_offsets.size()),
+ static_cast<uint32_t>(layout_info.vbase_offsets.size()));
+
+ uint32_t idx;
{
- if (die.HasChildren())
- {
- SymbolContext sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die);
- }
- ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator
+ pos,
+ end = layout_info.field_offsets.end();
+ for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end;
+ ++pos, ++idx) {
+ module_sp->LogMessage(
+ log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = "
+ "%p) field[%u] = { bit_offset=%u, name='%s' }",
+ static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
+ static_cast<uint32_t>(pos->second),
+ pos->first->getNameAsString().c_str());
+ }
}
- return (bool)clang_type;
- default:
- assert(false && "not a forward clang type decl!");
- break;
+ {
+ llvm::DenseMap<const clang::CXXRecordDecl *,
+ clang::CharUnits>::const_iterator base_pos,
+ base_end = layout_info.base_offsets.end();
+ for (idx = 0, base_pos = layout_info.base_offsets.begin();
+ base_pos != base_end; ++base_pos, ++idx) {
+ module_sp->LogMessage(
+ log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = "
+ "%p) base[%u] = { byte_offset=%u, name='%s' }",
+ clang_type.GetOpaqueQualType(), idx,
+ (uint32_t)base_pos->second.getQuantity(),
+ base_pos->first->getNameAsString().c_str());
+ }
+ }
+ {
+ llvm::DenseMap<const clang::CXXRecordDecl *,
+ clang::CharUnits>::const_iterator vbase_pos,
+ vbase_end = layout_info.vbase_offsets.end();
+ for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin();
+ vbase_pos != vbase_end; ++vbase_pos, ++idx) {
+ module_sp->LogMessage(
+ log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = "
+ "%p) vbase[%u] = { byte_offset=%u, name='%s' }",
+ static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
+ static_cast<uint32_t>(vbase_pos->second.getQuantity()),
+ vbase_pos->first->getNameAsString().c_str());
+ }
+ }
+ }
+ }
+ GetClangASTImporter().InsertRecordDecl(record_decl, layout_info);
+ }
+ }
+ }
+
+ return (bool)clang_type;
+
+ case DW_TAG_enumeration_type:
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ if (die.HasChildren()) {
+ SymbolContext sc(die.GetLLDBCompileUnit());
+ bool is_signed = false;
+ clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(),
+ die);
+ }
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
}
+ return (bool)clang_type;
- return false;
+ default:
+ assert(false && "not a forward clang type decl!");
+ break;
+ }
+
+ return false;
}
-std::vector<DWARFDIE>
-DWARFASTParserClang::GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context)
-{
- std::vector<DWARFDIE> result;
- for (auto it = m_decl_ctx_to_die.find((clang::DeclContext *)decl_context.GetOpaqueDeclContext()); it != m_decl_ctx_to_die.end(); it++)
- result.push_back(it->second);
- return result;
+std::vector<DWARFDIE> DWARFASTParserClang::GetDIEForDeclContext(
+ lldb_private::CompilerDeclContext decl_context) {
+ std::vector<DWARFDIE> result;
+ for (auto it = m_decl_ctx_to_die.find(
+ (clang::DeclContext *)decl_context.GetOpaqueDeclContext());
+ it != m_decl_ctx_to_die.end(); it++)
+ result.push_back(it->second);
+ return result;
}
-CompilerDecl
-DWARFASTParserClang::GetDeclForUIDFromDWARF (const DWARFDIE &die)
-{
- clang::Decl *clang_decl = GetClangDeclForDIE(die);
- if (clang_decl != nullptr)
- return CompilerDecl(&m_ast, clang_decl);
- return CompilerDecl();
+CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
+ clang::Decl *clang_decl = GetClangDeclForDIE(die);
+ if (clang_decl != nullptr)
+ return CompilerDecl(&m_ast, clang_decl);
+ return CompilerDecl();
}
CompilerDeclContext
-DWARFASTParserClang::GetDeclContextForUIDFromDWARF (const DWARFDIE &die)
-{
- clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (die);
- if (clang_decl_ctx)
- return CompilerDeclContext(&m_ast, clang_decl_ctx);
- return CompilerDeclContext();
+DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
+ clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die);
+ if (clang_decl_ctx)
+ return CompilerDeclContext(&m_ast, clang_decl_ctx);
+ return CompilerDeclContext();
}
CompilerDeclContext
-DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die)
-{
- clang::DeclContext *clang_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr);
- if (clang_decl_ctx)
- return CompilerDeclContext(&m_ast, clang_decl_ctx);
- return CompilerDeclContext();
+DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
+ clang::DeclContext *clang_decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
+ if (clang_decl_ctx)
+ return CompilerDeclContext(&m_ast, clang_decl_ctx);
+ return CompilerDeclContext();
}
-size_t
-DWARFASTParserClang::ParseChildEnumerators (const SymbolContext& sc,
- lldb_private::CompilerType &clang_type,
- bool is_signed,
- uint32_t enumerator_byte_size,
- const DWARFDIE &parent_die)
-{
- if (!parent_die)
- return 0;
-
- size_t enumerators_added = 0;
+size_t DWARFASTParserClang::ParseChildEnumerators(
+ const SymbolContext &sc, lldb_private::CompilerType &clang_type,
+ bool is_signed, uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {
+ if (!parent_die)
+ return 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
- {
- const dw_tag_t tag = die.Tag();
- if (tag == DW_TAG_enumerator)
- {
- DWARFAttributes attributes;
- const size_t num_child_attributes = die.GetAttributes(attributes);
- if (num_child_attributes > 0)
- {
- const char *name = NULL;
- bool got_value = false;
- int64_t enum_value = 0;
- Declaration decl;
-
- 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_const_value:
- got_value = true;
- if (is_signed)
- enum_value = form_value.Signed();
- else
- enum_value = form_value.Unsigned();
- break;
-
- case DW_AT_name:
- name = form_value.AsCString();
- break;
-
- case DW_AT_description:
- default:
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_sibling:
- break;
- }
- }
- }
+ size_t enumerators_added = 0;
- 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);
- ++enumerators_added;
- }
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
+ die = die.GetSibling()) {
+ const dw_tag_t tag = die.Tag();
+ if (tag == DW_TAG_enumerator) {
+ DWARFAttributes attributes;
+ const size_t num_child_attributes = die.GetAttributes(attributes);
+ if (num_child_attributes > 0) {
+ const char *name = NULL;
+ bool got_value = false;
+ int64_t enum_value = 0;
+ Declaration decl;
+
+ 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_const_value:
+ got_value = true;
+ if (is_signed)
+ enum_value = form_value.Signed();
+ else
+ enum_value = form_value.Unsigned();
+ break;
+
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_description:
+ default:
+ case DW_AT_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_sibling:
+ break;
}
+ }
+ }
+
+ 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);
+ ++enumerators_added;
}
+ }
}
- return enumerators_added;
+ }
+ return enumerators_added;
}
#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
-class DIEStack
-{
+class DIEStack {
public:
-
- void Push (const DWARFDIE &die)
- {
- m_dies.push_back (die);
+ void Push(const DWARFDIE &die) { m_dies.push_back(die); }
+
+ void LogDIEs(Log *log) {
+ StreamString log_strm;
+ const size_t n = m_dies.size();
+ log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
+ for (size_t i = 0; i < n; i++) {
+ std::string qualified_name;
+ const DWARFDIE &die = m_dies[i];
+ die.GetQualifiedName(qualified_name);
+ log_strm.Printf("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n", (uint64_t)i,
+ die.GetOffset(), die.GetTagAsCString(),
+ qualified_name.c_str());
}
-
-
- void LogDIEs (Log *log)
- {
- StreamString log_strm;
- const size_t n = m_dies.size();
- log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
- for (size_t i=0; i<n; i++)
- {
- std::string qualified_name;
- const DWARFDIE &die = m_dies[i];
- die.GetQualifiedName(qualified_name);
- log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
- (uint64_t)i,
- die.GetOffset(),
- die.GetTagAsCString(),
- qualified_name.c_str());
- }
- log->PutCString(log_strm.GetData());
- }
- void Pop ()
- {
- m_dies.pop_back();
+ log->PutCString(log_strm.GetData());
+ }
+ void Pop() { m_dies.pop_back(); }
+
+ class ScopedPopper {
+ public:
+ ScopedPopper(DIEStack &die_stack)
+ : m_die_stack(die_stack), m_valid(false) {}
+
+ void Push(const DWARFDIE &die) {
+ m_valid = true;
+ m_die_stack.Push(die);
}
- class ScopedPopper
- {
- public:
- ScopedPopper (DIEStack &die_stack) :
- m_die_stack (die_stack),
- m_valid (false)
- {
- }
-
- void
- Push (const DWARFDIE &die)
- {
- m_valid = true;
- m_die_stack.Push (die);
- }
-
- ~ScopedPopper ()
- {
- if (m_valid)
- m_die_stack.Pop();
- }
-
-
+ ~ScopedPopper() {
+ if (m_valid)
+ m_die_stack.Pop();
+ }
- protected:
- DIEStack &m_die_stack;
- bool m_valid;
- };
+ protected:
+ DIEStack &m_die_stack;
+ bool m_valid;
+ };
protected:
- typedef std::vector<DWARFDIE> Stack;
- Stack m_dies;
+ typedef std::vector<DWARFDIE> Stack;
+ Stack m_dies;
};
#endif
-Function *
-DWARFASTParserClang::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());
-
- const dw_tag_t tag = die.Tag();
+Function *DWARFASTParserClang::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());
+
+ const dw_tag_t tag = die.Tag();
+
+ if (tag != DW_TAG_subprogram)
+ return NULL;
- if (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))
- {
+ 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);
+ }
- // 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;
+ if (mangled)
+ func_name.SetValue(ConstString(mangled), true);
+ else if (die.GetParent().Tag() == DW_TAG_compile_unit &&
+ Language::LanguageIsCPlusPlus(die.GetLanguage()) && name &&
+ strcmp(name, "main") != 0) {
+ // If the mangled name is not present in the DWARF, generate the
+ // demangled name
+ // using the decl context. We skip if the function is "main" as its name
+ // is
+ // never mangled.
+ bool is_static = false;
+ bool is_variadic = false;
+ bool has_template_params = false;
+ unsigned type_quals = 0;
+ std::vector<CompilerType> param_types;
+ std::vector<clang::ParmVarDecl *> param_decls;
+ DWARFDeclContext decl_ctx;
+ StreamString sstr;
+
+ die.GetDWARFDeclContext(decl_ctx);
+ sstr << decl_ctx.GetQualifiedName();
+
+ 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);
+ sstr << "(";
+ for (size_t i = 0; i < param_types.size(); i++) {
+ if (i > 0)
+ sstr << ", ";
+ sstr << param_types[i].GetTypeName();
+ }
+ if (is_variadic)
+ sstr << ", ...";
+ sstr << ")";
+ if (type_quals & clang::Qualifiers::Const)
+ sstr << " const";
+
+ func_name.SetValue(ConstString(sstr.GetString()), false);
+ } else
+ 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->GetDIEToType().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;
+}
- if (func_range.GetBaseAddress().IsValid())
- {
- Mangled func_name;
- if (mangled)
- func_name.SetValue(ConstString(mangled), true);
- else if (die.GetParent().Tag() == DW_TAG_compile_unit &&
- Language::LanguageIsCPlusPlus(die.GetLanguage()) &&
- name && strcmp(name, "main") != 0)
- {
- // If the mangled name is not present in the DWARF, generate the demangled name
- // using the decl context. We skip if the function is "main" as its name is
- // never mangled.
- bool is_static = false;
- bool is_variadic = false;
- bool has_template_params = false;
- unsigned type_quals = 0;
- std::vector<CompilerType> param_types;
- std::vector<clang::ParmVarDecl*> param_decls;
- DWARFDeclContext decl_ctx;
- StreamString sstr;
-
- die.GetDWARFDeclContext(decl_ctx);
- sstr << decl_ctx.GetQualifiedName();
-
- 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);
- sstr << "(";
- for (size_t i = 0; i < param_types.size(); i++)
- {
- if (i > 0)
- sstr << ", ";
- sstr << param_types[i].GetTypeName();
+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<int> &member_accessibilities,
+ DWARFDIECollection &member_function_dies,
+ DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
+ bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
+ if (!parent_die)
+ return 0;
+
+ // Get the parent byte size so we can verify any members will fit
+ const uint64_t parent_byte_size =
+ parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX) * 8;
+ const uint64_t parent_bit_size =
+ parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
+
+ uint32_t member_idx = 0;
+ BitfieldInfo last_field_info;
+
+ ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
+ ClangASTContext *ast =
+ llvm::dyn_cast_or_null<ClangASTContext>(class_clang_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:
+ case DW_TAG_APPLE_property: {
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ Declaration decl;
+ // DWARFExpression location;
+ const char *name = NULL;
+ const char *prop_name = NULL;
+ const char *prop_getter_name = NULL;
+ const char *prop_setter_name = NULL;
+ uint32_t prop_attributes = 0;
+
+ bool is_artificial = false;
+ DWARFFormValue encoding_form;
+ AccessType accessibility = eAccessNone;
+ uint32_t member_byte_offset =
+ (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
+ size_t byte_size = 0;
+ int64_t bit_offset = 0;
+ uint64_t data_bit_offset = UINT64_MAX;
+ size_t bit_size = 0;
+ bool is_external =
+ false; // On DW_TAG_members, this means the member is static
+ uint32_t i;
+ for (i = 0; i < num_attributes && !is_artificial; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ encoding_form = form_value;
+ break;
+ case DW_AT_bit_offset:
+ bit_offset = form_value.Signed();
+ break;
+ case DW_AT_bit_size:
+ bit_size = form_value.Unsigned();
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_data_bit_offset:
+ data_bit_offset = form_value.Unsigned();
+ break;
+ case DW_AT_data_member_location:
+ if (form_value.BlockData()) {
+ Value initialValue(0);
+ Value memberOffset(0);
+ const DWARFDataExtractor &debug_info_data =
+ die.GetDWARF()->get_debug_info_data();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ if (DWARFExpression::Evaluate(
+ nullptr, // ExecutionContext *
+ nullptr, // ClangExpressionVariableList *
+ nullptr, // ClangExpressionDeclMap *
+ nullptr, // RegisterContext *
+ module_sp, debug_info_data, die.GetCU(), block_offset,
+ block_length, eRegisterKindDWARF, &initialValue,
+ nullptr, memberOffset, nullptr)) {
+ member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
- if (is_variadic)
- sstr << ", ...";
- sstr << ")";
- if (type_quals & clang::Qualifiers::Const)
- sstr << " const";
+ } 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;
+
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
+ case DW_AT_APPLE_property_name:
+ prop_name = form_value.AsCString();
+ break;
+ case DW_AT_APPLE_property_getter:
+ prop_getter_name = form_value.AsCString();
+ break;
+ case DW_AT_APPLE_property_setter:
+ prop_setter_name = form_value.AsCString();
+ break;
+ case DW_AT_APPLE_property_attribute:
+ prop_attributes = form_value.Unsigned();
+ break;
+ case DW_AT_external:
+ is_external = form_value.Boolean();
+ break;
- func_name.SetValue(ConstString(sstr.GetData()), false);
+ default:
+ case DW_AT_declaration:
+ case DW_AT_description:
+ case DW_AT_mutable:
+ case DW_AT_visibility:
+ case DW_AT_sibling:
+ break;
}
- else
- 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->GetDIEToType().lookup (die.GetDIE());
+ }
+ }
- assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
+ if (prop_name) {
+ ConstString fixed_getter;
+ ConstString fixed_setter;
- 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;
-}
+ // Check if the property getter/setter were provided as full
+ // names. We want basenames, so we extract them.
-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<int> &member_accessibilities,
- DWARFDIECollection &member_function_dies,
- DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
- bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info)
-{
- if (!parent_die)
- return 0;
-
- // Get the parent byte size so we can verify any members will fit
- const uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX) * 8;
- const uint64_t parent_bit_size = parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
-
- uint32_t member_idx = 0;
- BitfieldInfo last_field_info;
-
- ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem());
- if (ast == nullptr)
- return 0;
-
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
- {
- dw_tag_t tag = die.Tag();
+ if (prop_getter_name && prop_getter_name[0] == '-') {
+ ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
+ prop_getter_name = prop_getter_method.GetSelector().GetCString();
+ }
- switch (tag)
- {
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes (attributes);
- if (num_attributes > 0)
- {
- Declaration decl;
- //DWARFExpression location;
- const char *name = NULL;
- const char *prop_name = NULL;
- const char *prop_getter_name = NULL;
- const char *prop_setter_name = NULL;
- uint32_t prop_attributes = 0;
-
-
- bool is_artificial = false;
- DWARFFormValue encoding_form;
- AccessType accessibility = eAccessNone;
- uint32_t member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
- size_t byte_size = 0;
- int64_t bit_offset = 0;
- uint64_t data_bit_offset = UINT64_MAX;
- size_t bit_size = 0;
- bool is_external = false; // On DW_TAG_members, this means the member is static
- uint32_t i;
- for (i=0; i<num_attributes && !is_artificial; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name: name = form_value.AsCString(); break;
- case DW_AT_type: encoding_form = form_value; break;
- case DW_AT_bit_offset: bit_offset = form_value.Signed(); break;
- case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
- case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
- case DW_AT_data_bit_offset: data_bit_offset = form_value.Unsigned(); break;
- case DW_AT_data_member_location:
- if (form_value.BlockData())
- {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(nullptr, // ExecutionContext *
- nullptr, // ClangExpressionVariableList *
- nullptr, // ClangExpressionDeclMap *
- nullptr, // RegisterContext *
- module_sp,
- debug_info_data,
- die.GetCU(),
- block_offset,
- block_length,
- eRegisterKindDWARF,
- &initialValue,
- nullptr,
- memberOffset,
- nullptr))
- {
- 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;
-
- case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
- case DW_AT_APPLE_property_name: prop_name = form_value.AsCString();
- break;
- case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString();
- break;
- case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString();
- break;
- case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
- case DW_AT_external: is_external = form_value.Boolean(); break;
-
- default:
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_mutable:
- case DW_AT_visibility:
- case DW_AT_sibling:
- break;
- }
- }
- }
+ if (prop_setter_name && prop_setter_name[0] == '-') {
+ ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
+ prop_setter_name = prop_setter_method.GetSelector().GetCString();
+ }
- if (prop_name)
- {
- ConstString fixed_getter;
- ConstString fixed_setter;
+ // If the names haven't been provided, they need to be
+ // filled in.
- // Check if the property getter/setter were provided as full
- // names. We want basenames, so we extract them.
+ if (!prop_getter_name) {
+ prop_getter_name = prop_name;
+ }
+ if (!prop_setter_name && prop_name[0] &&
+ !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {
+ StreamString ss;
- if (prop_getter_name && prop_getter_name[0] == '-')
- {
- ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
- prop_getter_name = prop_getter_method.GetSelector().GetCString();
- }
+ ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);
- if (prop_setter_name && prop_setter_name[0] == '-')
- {
- ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
- prop_setter_name = prop_setter_method.GetSelector().GetCString();
- }
+ fixed_setter.SetString(ss.GetString());
+ prop_setter_name = fixed_setter.GetCString();
+ }
+ }
- // If the names haven't been provided, they need to be
- // filled in.
+ // Clang has a DWARF generation bug where sometimes it
+ // represents fields that are references with bad byte size
+ // and bit size/offset information such as:
+ //
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_bit_size( 0x40 )
+ // DW_AT_bit_offset( 0xffffffffffffffc0 )
+ //
+ // So check the bit offset to make sure it is sane, and if
+ // the values are not sane, remove them. If we don't do this
+ // then we will end up with a crash if we try to use this
+ // type in an expression when clang becomes unhappy with its
+ // recycled debug info.
+
+ if (byte_size == 0 && bit_offset < 0) {
+ bit_size = 0;
+ bit_offset = 0;
+ }
- if (!prop_getter_name)
- {
- prop_getter_name = prop_name;
- }
- if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly))
- {
- StreamString ss;
+ // FIXME: Make Clang ignore Objective-C accessibility for expressions
+ if (class_language == eLanguageTypeObjC ||
+ 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;
+ }
- ss.Printf("set%c%s:",
- toupper(prop_name[0]),
- &prop_name[1]);
+ // Handle static members
+ if (is_external && member_byte_offset == UINT32_MAX) {
+ Type *var_type = die.ResolveTypeUID(DIERef(encoding_form));
+
+ if (var_type) {
+ if (accessibility == eAccessNone)
+ accessibility = eAccessPublic;
+ ClangASTContext::AddVariableToRecordType(
+ class_clang_type, name, var_type->GetLayoutCompilerType(),
+ accessibility);
+ }
+ break;
+ }
- fixed_setter.SetCString(ss.GetData());
- prop_setter_name = fixed_setter.GetCString();
- }
- }
+ if (is_artificial == false) {
+ Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));
+
+ clang::FieldDecl *field_decl = NULL;
+ if (tag == DW_TAG_member) {
+ if (member_type) {
+ if (accessibility == eAccessNone)
+ accessibility = default_accessibility;
+ member_accessibilities.push_back(accessibility);
+
+ uint64_t field_bit_offset =
+ (member_byte_offset == UINT32_MAX ? 0
+ : (member_byte_offset * 8));
+ if (bit_size > 0) {
+
+ BitfieldInfo this_field_info;
+ this_field_info.bit_offset = field_bit_offset;
+ this_field_info.bit_size = bit_size;
+
+ /////////////////////////////////////////////////////////////
+ // How to locate a field given the DWARF debug information
+ //
+ // AT_byte_size indicates the size of the word in which the
+ // bit offset must be interpreted.
+ //
+ // AT_data_member_location indicates the byte offset of the
+ // word from the base address of the structure.
+ //
+ // AT_bit_offset indicates how many bits into the word
+ // (according to the host endianness) the low-order bit of
+ // the field starts. AT_bit_offset can be negative.
+ //
+ // AT_bit_size indicates the size of the field in bits.
+ /////////////////////////////////////////////////////////////
+
+ if (data_bit_offset != UINT64_MAX) {
+ this_field_info.bit_offset = data_bit_offset;
+ } else {
+ if (byte_size == 0)
+ byte_size = member_type->GetByteSize();
+
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ if (objfile->GetByteOrder() == eByteOrderLittle) {
+ this_field_info.bit_offset += byte_size * 8;
+ this_field_info.bit_offset -= (bit_offset + bit_size);
+ } else {
+ this_field_info.bit_offset += bit_offset;
+ }
+ }
- // Clang has a DWARF generation bug where sometimes it
- // represents fields that are references with bad byte size
- // and bit size/offset information such as:
- //
- // DW_AT_byte_size( 0x00 )
- // DW_AT_bit_size( 0x40 )
- // DW_AT_bit_offset( 0xffffffffffffffc0 )
- //
- // So check the bit offset to make sure it is sane, and if
- // the values are not sane, remove them. If we don't do this
- // then we will end up with a crash if we try to use this
- // type in an expression when clang becomes unhappy with its
- // recycled debug info.
-
- if (byte_size == 0 && bit_offset < 0)
- {
- bit_size = 0;
- bit_offset = 0;
- }
+ if ((this_field_info.bit_offset >= parent_bit_size) ||
+ !last_field_info.NextBitfieldOffsetIsValid(
+ this_field_info.bit_offset)) {
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ objfile->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
+ "bit offset (0x%8.8" PRIx64
+ ") member will be ignored. Please file a bug against the "
+ "compiler and include the preprocessed output for %s\n",
+ die.GetID(), DW_TAG_value_to_name(tag), name,
+ this_field_info.bit_offset,
+ sc.comp_unit ? sc.comp_unit->GetPath().c_str()
+ : "the source file");
+ this_field_info.Clear();
+ continue;
+ }
- // FIXME: Make Clang ignore Objective-C accessibility for expressions
- if (class_language == eLanguageTypeObjC ||
- 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;
+ // Update the field bit offset we will report for layout
+ field_bit_offset = this_field_info.bit_offset;
+
+ // If the member to be emitted did not start on a character
+ // boundary and there is
+ // empty space between the last field and this one, then we need
+ // to emit an
+ // anonymous member filling up the space up to its start. There
+ // are three cases
+ // here:
+ //
+ // 1 If the previous member ended on a character boundary, then
+ // we can emit an
+ // anonymous member starting at the most recent character
+ // boundary.
+ //
+ // 2 If the previous member did not end on a character boundary
+ // and the distance
+ // from the end of the previous member to the current member
+ // is less than a
+ // word width, then we can emit an anonymous member starting
+ // right after the
+ // previous member and right before this member.
+ //
+ // 3 If the previous member did not end on a character boundary
+ // and the distance
+ // from the end of the previous member to the current member
+ // is greater than
+ // or equal a word width, then we act as in Case 1.
+
+ const uint64_t character_width = 8;
+ const uint64_t word_width = 32;
+
+ // Objective-C has invalid DW_AT_bit_offset values in older
+ // versions
+ // of clang, so we have to be careful and only insert unnamed
+ // bitfields
+ // if we have a new enough clang.
+ bool detect_unnamed_bitfields = true;
+
+ if (class_language == eLanguageTypeObjC ||
+ class_language == eLanguageTypeObjC_plus_plus)
+ detect_unnamed_bitfields =
+ die.GetCU()->Supports_unnamed_objc_bitfields();
+
+ if (detect_unnamed_bitfields) {
+ BitfieldInfo anon_field_info;
+
+ if ((this_field_info.bit_offset % character_width) !=
+ 0) // not char aligned
+ {
+ uint64_t last_field_end = 0;
+
+ if (last_field_info.IsValid())
+ last_field_end =
+ last_field_info.bit_offset + last_field_info.bit_size;
+
+ if (this_field_info.bit_offset != last_field_end) {
+ if (((last_field_end % character_width) == 0) || // case 1
+ (this_field_info.bit_offset - last_field_end >=
+ word_width)) // case 3
+ {
+ anon_field_info.bit_size =
+ this_field_info.bit_offset % character_width;
+ anon_field_info.bit_offset =
+ this_field_info.bit_offset -
+ anon_field_info.bit_size;
+ } else // case 2
+ {
+ anon_field_info.bit_size =
+ this_field_info.bit_offset - last_field_end;
+ anon_field_info.bit_offset = last_field_end;
+ }
}
-
- // Handle static members
- if (is_external && member_byte_offset == UINT32_MAX)
- {
- Type *var_type = die.ResolveTypeUID(DIERef(encoding_form));
-
- if (var_type)
- {
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
- ClangASTContext::AddVariableToRecordType (class_clang_type,
- name,
- var_type->GetLayoutCompilerType (),
- accessibility);
- }
- break;
+ }
+
+ if (anon_field_info.IsValid()) {
+ clang::FieldDecl *unnamed_bitfield_decl =
+ ClangASTContext::AddFieldToRecordType(
+ class_clang_type, NULL,
+ m_ast.GetBuiltinTypeForEncodingAndBitSize(
+ eEncodingSint, word_width),
+ accessibility, anon_field_info.bit_size);
+
+ layout_info.field_offsets.insert(std::make_pair(
+ unnamed_bitfield_decl, anon_field_info.bit_offset));
+ }
+ }
+ last_field_info = this_field_info;
+ } else {
+ last_field_info.Clear();
+ }
+
+ CompilerType member_clang_type =
+ member_type->GetLayoutCompilerType();
+ if (!member_clang_type.IsCompleteType())
+ member_clang_type.GetCompleteType();
+
+ {
+ // Older versions of clang emit array[0] and array[1] in the
+ // same way (<rdar://problem/12566646>).
+ // If the current field is at the end of the structure, then
+ // there is definitely no room for extra
+ // elements and we override the type to array[0].
+
+ CompilerType member_array_element_type;
+ uint64_t member_array_size;
+ bool member_array_is_incomplete;
+
+ if (member_clang_type.IsArrayType(
+ &member_array_element_type, &member_array_size,
+ &member_array_is_incomplete) &&
+ !member_array_is_incomplete) {
+ uint64_t parent_byte_size =
+ parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size,
+ UINT64_MAX);
+
+ if (member_byte_offset >= parent_byte_size) {
+ if (member_array_size != 1 &&
+ (member_array_size != 0 ||
+ member_byte_offset > parent_byte_size)) {
+ module_sp->ReportError(
+ "0x%8.8" PRIx64
+ ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
+ " which extends beyond the bounds of 0x%8.8" PRIx64,
+ die.GetID(), name, encoding_form.Reference(),
+ parent_die.GetID());
}
- if (is_artificial == false)
- {
- Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));
-
- clang::FieldDecl *field_decl = NULL;
- if (tag == DW_TAG_member)
- {
- if (member_type)
- {
- if (accessibility == eAccessNone)
- accessibility = default_accessibility;
- member_accessibilities.push_back(accessibility);
-
- uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
- if (bit_size > 0)
- {
-
- BitfieldInfo this_field_info;
- this_field_info.bit_offset = field_bit_offset;
- this_field_info.bit_size = bit_size;
-
- /////////////////////////////////////////////////////////////
- // How to locate a field given the DWARF debug information
- //
- // AT_byte_size indicates the size of the word in which the
- // bit offset must be interpreted.
- //
- // AT_data_member_location indicates the byte offset of the
- // word from the base address of the structure.
- //
- // AT_bit_offset indicates how many bits into the word
- // (according to the host endianness) the low-order bit of
- // the field starts. AT_bit_offset can be negative.
- //
- // AT_bit_size indicates the size of the field in bits.
- /////////////////////////////////////////////////////////////
-
- if (data_bit_offset != UINT64_MAX)
- {
- this_field_info.bit_offset = data_bit_offset;
- }
- else
- {
- if (byte_size == 0)
- byte_size = member_type->GetByteSize();
-
- ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
- if (objfile->GetByteOrder() == eByteOrderLittle)
- {
- this_field_info.bit_offset += byte_size * 8;
- this_field_info.bit_offset -= (bit_offset + bit_size);
- }
- else
- {
- this_field_info.bit_offset += bit_offset;
- }
- }
-
- if ((this_field_info.bit_offset >= parent_bit_size) || !last_field_info.NextBitfieldOffsetIsValid(this_field_info.bit_offset))
- {
- ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
- objfile->GetModule()->ReportWarning("0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the compiler and include the preprocessed output for %s\n",
- die.GetID(),
- DW_TAG_value_to_name(tag),
- name,
- this_field_info.bit_offset,
- sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
- this_field_info.Clear();
- continue;
- }
-
- // Update the field bit offset we will report for layout
- field_bit_offset = this_field_info.bit_offset;
-
- // If the member to be emitted did not start on a character boundary and there is
- // empty space between the last field and this one, then we need to emit an
- // anonymous member filling up the space up to its start. There are three cases
- // here:
- //
- // 1 If the previous member ended on a character boundary, then we can emit an
- // anonymous member starting at the most recent character boundary.
- //
- // 2 If the previous member did not end on a character boundary and the distance
- // from the end of the previous member to the current member is less than a
- // word width, then we can emit an anonymous member starting right after the
- // previous member and right before this member.
- //
- // 3 If the previous member did not end on a character boundary and the distance
- // from the end of the previous member to the current member is greater than
- // or equal a word width, then we act as in Case 1.
-
- const uint64_t character_width = 8;
- const uint64_t word_width = 32;
-
- // Objective-C has invalid DW_AT_bit_offset values in older versions
- // of clang, so we have to be careful and only insert unnamed bitfields
- // if we have a new enough clang.
- bool detect_unnamed_bitfields = true;
-
- if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
- detect_unnamed_bitfields = die.GetCU()->Supports_unnamed_objc_bitfields ();
-
- if (detect_unnamed_bitfields)
- {
- BitfieldInfo anon_field_info;
-
- if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
- {
- uint64_t last_field_end = 0;
-
- if (last_field_info.IsValid())
- last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
-
- if (this_field_info.bit_offset != last_field_end)
- {
- if (((last_field_end % character_width) == 0) || // case 1
- (this_field_info.bit_offset - last_field_end >= word_width)) // case 3
- {
- anon_field_info.bit_size = this_field_info.bit_offset % character_width;
- anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
- }
- else // case 2
- {
- anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
- anon_field_info.bit_offset = last_field_end;
- }
- }
- }
-
- if (anon_field_info.IsValid())
- {
- clang::FieldDecl *unnamed_bitfield_decl =
- ClangASTContext::AddFieldToRecordType (class_clang_type,
- NULL,
- m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
- accessibility,
- anon_field_info.bit_size);
-
- layout_info.field_offsets.insert(
- std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
- }
- }
- last_field_info = this_field_info;
- }
- else
- {
- last_field_info.Clear();
- }
-
- CompilerType member_clang_type = member_type->GetLayoutCompilerType ();
- if (!member_clang_type.IsCompleteType())
- member_clang_type.GetCompleteType();
-
- {
- // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
- // If the current field is at the end of the structure, then there is definitely no room for extra
- // elements and we override the type to array[0].
-
- CompilerType member_array_element_type;
- uint64_t member_array_size;
- bool member_array_is_incomplete;
-
- if (member_clang_type.IsArrayType(&member_array_element_type,
- &member_array_size,
- &member_array_is_incomplete) &&
- !member_array_is_incomplete)
- {
- uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
-
- if (member_byte_offset >= parent_byte_size)
- {
- if (member_array_size != 1 && (member_array_size != 0 || member_byte_offset > parent_byte_size))
- {
- module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64,
- die.GetID(),
- name,
- encoding_form.Reference(),
- parent_die.GetID());
- }
-
- member_clang_type = m_ast.CreateArrayType(member_array_element_type, 0, false);
- }
- }
- }
-
- if (ClangASTContext::IsCXXClassType(member_clang_type) && member_clang_type.GetCompleteType() == false)
- {
- if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
- module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info",
- parent_die.GetOffset(),
- parent_die.GetName(),
- die.GetOffset(),
- name);
- else
- module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
- parent_die.GetOffset(),
- parent_die.GetName(),
- die.GetOffset(),
- name,
- sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
- // We have no choice other than to pretend that the member class
- // is complete. If we don't do this, clang will crash when trying
- // to layout the class. Since we provide layout assistance, all
- // ivars in this class and other classes will be fine, this is
- // the best we can do short of crashing.
- if (ClangASTContext::StartTagDeclarationDefinition(member_clang_type))
- {
- ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);
- }
- else
- {
- module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type claims to be a C++ class but we were not able to start its definition.\nPlease file a bug and attach the file at the start of this error message",
- parent_die.GetOffset(),
- parent_die.GetName(),
- die.GetOffset(),
- name);
- }
- }
-
- field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,
- name,
- member_clang_type,
- accessibility,
- bit_size);
-
- m_ast.SetMetadataAsUserID (field_decl, die.GetID());
-
- layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset));
- }
- else
- {
- if (name)
- module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
- die.GetID(),
- name,
- encoding_form.Reference());
- else
- module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
- die.GetID(),
- encoding_form.Reference());
- }
- }
-
- if (prop_name != NULL && member_type)
- {
- clang::ObjCIvarDecl *ivar_decl = NULL;
+ member_clang_type = m_ast.CreateArrayType(
+ member_array_element_type, 0, false);
+ }
+ }
+ }
+
+ if (ClangASTContext::IsCXXClassType(member_clang_type) &&
+ member_clang_type.GetCompleteType() == false) {
+ if (die.GetCU()->GetProducer() ==
+ DWARFCompileUnit::eProducerClang)
+ module_sp->ReportError(
+ "DWARF DIE at 0x%8.8x (class %s) has a member variable "
+ "0x%8.8x (%s) whose type is a forward declaration, not a "
+ "complete definition.\nTry compiling the source file "
+ "with -fno-limit-debug-info",
+ parent_die.GetOffset(), parent_die.GetName(),
+ die.GetOffset(), name);
+ else
+ module_sp->ReportError(
+ "DWARF DIE at 0x%8.8x (class %s) has a member variable "
+ "0x%8.8x (%s) whose type is a forward declaration, not a "
+ "complete definition.\nPlease file a bug against the "
+ "compiler and include the preprocessed output for %s",
+ parent_die.GetOffset(), parent_die.GetName(),
+ die.GetOffset(), name,
+ sc.comp_unit ? sc.comp_unit->GetPath().c_str()
+ : "the source file");
+ // We have no choice other than to pretend that the member class
+ // is complete. If we don't do this, clang will crash when
+ // trying
+ // to layout the class. Since we provide layout assistance, all
+ // ivars in this class and other classes will be fine, this is
+ // the best we can do short of crashing.
+ if (ClangASTContext::StartTagDeclarationDefinition(
+ member_clang_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(
+ member_clang_type);
+ } else {
+ module_sp->ReportError(
+ "DWARF DIE at 0x%8.8x (class %s) has a member variable "
+ "0x%8.8x (%s) whose type claims to be a C++ class but we "
+ "were not able to start its definition.\nPlease file a "
+ "bug and attach the file at the start of this error "
+ "message",
+ parent_die.GetOffset(), parent_die.GetName(),
+ die.GetOffset(), name);
+ }
+ }
+
+ field_decl = ClangASTContext::AddFieldToRecordType(
+ class_clang_type, name, member_clang_type, accessibility,
+ bit_size);
+
+ m_ast.SetMetadataAsUserID(field_decl, die.GetID());
+
+ layout_info.field_offsets.insert(
+ std::make_pair(field_decl, field_bit_offset));
+ } else {
+ if (name)
+ module_sp->ReportError(
+ "0x%8.8" PRIx64
+ ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
+ " which was unable to be parsed",
+ die.GetID(), name, encoding_form.Reference());
+ else
+ module_sp->ReportError(
+ "0x%8.8" PRIx64
+ ": DW_TAG_member refers to type 0x%8.8" PRIx64
+ " which was unable to be parsed",
+ die.GetID(), encoding_form.Reference());
+ }
+ }
- if (field_decl)
- {
- ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
- assert (ivar_decl != NULL);
- }
+ if (prop_name != NULL && member_type) {
+ clang::ObjCIvarDecl *ivar_decl = NULL;
- ClangASTMetadata metadata;
- metadata.SetUserID (die.GetID());
- delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
- prop_name,
- member_type->GetLayoutCompilerType (),
- ivar_decl,
- prop_setter_name,
- prop_getter_name,
- prop_attributes,
- &metadata));
-
- if (ivar_decl)
- m_ast.SetMetadataAsUserID (ivar_decl, die.GetID());
- }
- }
- }
- ++member_idx;
+ if (field_decl) {
+ ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
+ assert(ivar_decl != NULL);
}
- break;
- case DW_TAG_subprogram:
- // Let the type parsing code handle this one for us.
- member_function_dies.Append (die);
- break;
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ delayed_properties.push_back(DelayedAddObjCClassProperty(
+ class_clang_type, prop_name,
+ member_type->GetLayoutCompilerType(), ivar_decl,
+ prop_setter_name, prop_getter_name, prop_attributes,
+ &metadata));
+
+ if (ivar_decl)
+ m_ast.SetMetadataAsUserID(ivar_decl, die.GetID());
+ }
+ }
+ }
+ ++member_idx;
+ } break;
+
+ case DW_TAG_subprogram:
+ // Let the type parsing code handle this one for us.
+ member_function_dies.Append(die);
+ break;
+
+ case DW_TAG_inheritance: {
+ is_a_class = true;
+ if (default_accessibility == eAccessNone)
+ default_accessibility = eAccessPrivate;
+ // TODO: implement DW_TAG_inheritance type parsing
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ Declaration decl;
+ DWARFExpression location(die.GetCU());
+ DWARFFormValue encoding_form;
+ AccessType accessibility = default_accessibility;
+ bool is_virtual = false;
+ bool is_base_of_class = true;
+ off_t member_byte_offset = 0;
+ 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_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_type:
+ encoding_form = 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.GetDWARF()->get_debug_info_data();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ if (DWARFExpression::Evaluate(
+ nullptr, nullptr, nullptr, nullptr, module_sp,
+ debug_info_data, die.GetCU(), block_offset,
+ block_length, eRegisterKindDWARF, &initialValue,
+ nullptr, memberOffset, nullptr)) {
+ 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;
- case DW_TAG_inheritance:
- {
- is_a_class = true;
- if (default_accessibility == eAccessNone)
- default_accessibility = eAccessPrivate;
- // TODO: implement DW_TAG_inheritance type parsing
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes (attributes);
- if (num_attributes > 0)
- {
- Declaration decl;
- DWARFExpression location(die.GetCU());
- DWARFFormValue encoding_form;
- AccessType accessibility = default_accessibility;
- bool is_virtual = false;
- bool is_base_of_class = true;
- off_t member_byte_offset = 0;
- 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_type: encoding_form = 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.GetDWARF()->get_debug_info_data();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate (nullptr,
- nullptr,
- nullptr,
- nullptr,
- module_sp,
- debug_info_data,
- die.GetCU(),
- block_offset,
- block_length,
- eRegisterKindDWARF,
- &initialValue,
- nullptr,
- memberOffset,
- nullptr))
- {
- 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;
-
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
-
- case DW_AT_virtuality:
- is_virtual = form_value.Boolean();
- break;
-
- case DW_AT_sibling:
- break;
-
- default:
- break;
- }
- }
- }
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
- Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form));
- if (base_class_type == NULL)
- {
- module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message",
- die.GetOffset(),
- encoding_form.Reference(),
- parent_die.GetOffset());
- break;
- }
+ case DW_AT_virtuality:
+ is_virtual = form_value.Boolean();
+ break;
- CompilerType base_class_clang_type = base_class_type->GetFullCompilerType ();
- assert (base_class_clang_type);
- 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));
-
- if (is_virtual)
- {
- // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't
- // give us a constant offset, but gives us a DWARF expressions that requires an actual object
- // in memory. the DW_AT_data_member_location for a virtual base class looks like:
- // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus )
- // Given this, there is really no valid response we can give to clang for virtual base
- // class offsets, and this should eventually be removed from LayoutRecordType() in the external
- // AST source in clang.
- }
- else
- {
- layout_info.base_offsets.insert(
- std::make_pair(ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()),
- clang::CharUnits::fromQuantity(member_byte_offset)));
- }
- }
- }
- }
- break;
+ case DW_AT_sibling:
+ break;
default:
- break;
+ break;
+ }
+ }
}
- }
-
- return true;
-}
+ Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form));
+ if (base_class_type == NULL) {
+ module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to "
+ "resolve the base class at 0x%8.8" PRIx64
+ " from enclosing type 0x%8.8x. \nPlease file "
+ "a bug and attach the file at the start of "
+ "this error message",
+ die.GetOffset(), encoding_form.Reference(),
+ parent_die.GetOffset());
+ break;
+ }
-size_t
-DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
- 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,
- std::vector<clang::ParmVarDecl*>& function_param_decls,
- unsigned &type_quals)
-{
- if (!parent_die)
- return 0;
-
- size_t arg_idx = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
- {
- const 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)
- {
- const char *name = NULL;
- Declaration decl;
- DWARFFormValue param_type_die_form;
- bool is_artificial = false;
- // one of None, Auto, Register, Extern, Static, PrivateExtern
-
- clang::StorageClass storage = clang::SC_None;
- 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_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name: name = form_value.AsCString();
- break;
- case DW_AT_type: param_type_die_form = form_value; break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
- case DW_AT_location:
- // if (form_value.BlockData())
- // {
- // const DWARFDataExtractor& debug_info_data = debug_info();
- // uint32_t block_length = form_value.Unsigned();
- // DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
- // }
- // else
- // {
- // }
- // break;
- case DW_AT_const_value:
- case DW_AT_default_value:
- case DW_AT_description:
- case DW_AT_endianity:
- case DW_AT_is_optional:
- case DW_AT_segment:
- case DW_AT_variable_parameter:
- default:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
+ CompilerType base_class_clang_type =
+ base_class_type->GetFullCompilerType();
+ assert(base_class_clang_type);
+ 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));
+
+ if (is_virtual) {
+ // Do not specify any offset for virtual inheritance. The DWARF
+ // produced by clang doesn't
+ // give us a constant offset, but gives us a DWARF expressions that
+ // requires an actual object
+ // in memory. the DW_AT_data_member_location for a virtual base
+ // class looks like:
+ // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref,
+ // DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref,
+ // DW_OP_plus )
+ // Given this, there is really no valid response we can give to
+ // clang for virtual base
+ // class offsets, and this should eventually be removed from
+ // LayoutRecordType() in the external
+ // AST source in clang.
+ } else {
+ layout_info.base_offsets.insert(std::make_pair(
+ ast->GetAsCXXRecordDecl(
+ base_class_clang_type.GetOpaqueQualType()),
+ clang::CharUnits::fromQuantity(member_byte_offset)));
+ }
+ }
+ }
+ } break;
- bool skip = false;
- if (skip_artificial)
- {
- if (is_artificial)
- {
- // In order to determine if a C++ member function is
- // "const" we have to look at the const-ness of "this"...
- // Ugly, but that
- if (arg_idx == 0)
- {
- if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
- {
- // Often times compilers omit the "this" name for the
- // specification DIEs, so we can't rely upon the name
- // being in the formal parameter DIE...
- if (name == NULL || ::strcmp(name, "this")==0)
- {
- Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form));
- if (this_type)
- {
- uint32_t encoding_mask = this_type->GetEncodingMask();
- if (encoding_mask & Type::eEncodingIsPointerUID)
- {
- is_static = false;
-
- if (encoding_mask & (1u << Type::eEncodingIsConstUID))
- type_quals |= clang::Qualifiers::Const;
- if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
- type_quals |= clang::Qualifiers::Volatile;
- }
- }
- }
- }
- }
- skip = true;
- }
- else
- {
-
- // HACK: Objective C formal parameters "self" and "_cmd"
- // are not marked as artificial in the DWARF...
- CompileUnit *comp_unit = die.GetLLDBCompileUnit();
- if (comp_unit)
- {
- switch (comp_unit->GetLanguage())
- {
- case eLanguageTypeObjC:
- case eLanguageTypeObjC_plus_plus:
- if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
- skip = true;
- break;
- default:
- break;
- }
- }
- }
- }
+ default:
+ break;
+ }
+ }
- if (!skip)
- {
- Type *type = die.ResolveTypeUID(DIERef(param_type_die_form));
- if (type)
- {
- function_param_types.push_back (type->GetForwardCompilerType ());
+ return true;
+}
- clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration (name,
- type->GetForwardCompilerType (),
- storage);
- assert(param_var_decl);
- function_param_decls.push_back(param_var_decl);
+size_t DWARFASTParserClang::ParseChildParameters(
+ const SymbolContext &sc, 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,
+ std::vector<clang::ParmVarDecl *> &function_param_decls,
+ unsigned &type_quals) {
+ if (!parent_die)
+ return 0;
+
+ size_t arg_idx = 0;
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
+ die = die.GetSibling()) {
+ const 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) {
+ const char *name = NULL;
+ Declaration decl;
+ DWARFFormValue param_type_die_form;
+ bool is_artificial = false;
+ // one of None, Auto, Register, Extern, Static, PrivateExtern
+
+ clang::StorageClass storage = clang::SC_None;
+ 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_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ param_type_die_form = form_value;
+ break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
+ case DW_AT_location:
+ // if (form_value.BlockData())
+ // {
+ // const DWARFDataExtractor&
+ // debug_info_data = debug_info();
+ // uint32_t block_length =
+ // form_value.Unsigned();
+ // DWARFDataExtractor
+ // location(debug_info_data,
+ // form_value.BlockData() -
+ // debug_info_data.GetDataStart(),
+ // block_length);
+ // }
+ // else
+ // {
+ // }
+ // break;
+ case DW_AT_const_value:
+ case DW_AT_default_value:
+ case DW_AT_description:
+ case DW_AT_endianity:
+ case DW_AT_is_optional:
+ case DW_AT_segment:
+ case DW_AT_variable_parameter:
+ default:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
- m_ast.SetMetadataAsUserID (param_var_decl, die.GetID());
- }
+ bool skip = false;
+ if (skip_artificial) {
+ if (is_artificial) {
+ // In order to determine if a C++ member function is
+ // "const" we have to look at the const-ness of "this"...
+ // Ugly, but that
+ if (arg_idx == 0) {
+ if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind())) {
+ // Often times compilers omit the "this" name for the
+ // specification DIEs, so we can't rely upon the name
+ // being in the formal parameter DIE...
+ if (name == NULL || ::strcmp(name, "this") == 0) {
+ Type *this_type =
+ die.ResolveTypeUID(DIERef(param_type_die_form));
+ if (this_type) {
+ uint32_t encoding_mask = this_type->GetEncodingMask();
+ if (encoding_mask & Type::eEncodingIsPointerUID) {
+ is_static = false;
+
+ if (encoding_mask & (1u << Type::eEncodingIsConstUID))
+ type_quals |= clang::Qualifiers::Const;
+ if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
+ type_quals |= clang::Qualifiers::Volatile;
}
+ }
}
- arg_idx++;
+ }
}
+ skip = true;
+ } else {
+
+ // HACK: Objective C formal parameters "self" and "_cmd"
+ // are not marked as artificial in the DWARF...
+ CompileUnit *comp_unit = die.GetLLDBCompileUnit();
+ if (comp_unit) {
+ switch (comp_unit->GetLanguage()) {
+ case eLanguageTypeObjC:
+ case eLanguageTypeObjC_plus_plus:
+ if (name && name[0] &&
+ (strcmp(name, "self") == 0 || strcmp(name, "_cmd") == 0))
+ skip = true;
break;
-
- case DW_TAG_unspecified_parameters:
- is_variadic = true;
+ default:
break;
+ }
+ }
+ }
+ }
- case DW_TAG_template_type_parameter:
- case DW_TAG_template_value_parameter:
- // The one caller of this was never using the template_param_infos,
- // and the local variable was taking up a large amount of stack space
- // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
- // the template params back, we can add them back.
- // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
- has_template_params = true;
- break;
+ if (!skip) {
+ Type *type = die.ResolveTypeUID(DIERef(param_type_die_form));
+ if (type) {
+ function_param_types.push_back(type->GetForwardCompilerType());
- default:
- break;
+ clang::ParmVarDecl *param_var_decl =
+ m_ast.CreateParameterDeclaration(
+ name, type->GetForwardCompilerType(), storage);
+ assert(param_var_decl);
+ function_param_decls.push_back(param_var_decl);
+
+ m_ast.SetMetadataAsUserID(param_var_decl, die.GetID());
+ }
}
+ }
+ arg_idx++;
+ } break;
+
+ case DW_TAG_unspecified_parameters:
+ is_variadic = true;
+ break;
+
+ case DW_TAG_template_type_parameter:
+ case DW_TAG_template_value_parameter:
+ // The one caller of this was never using the template_param_infos,
+ // and the local variable was taking up a large amount of stack space
+ // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
+ // the template params back, we can add them back.
+ // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
+ has_template_params = true;
+ break;
+
+ default:
+ break;
}
- return arg_idx;
+ }
+ 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)
-{
- 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;
- uint64_t lower_bound = 0;
- uint64_t upper_bound = 0;
- bool upper_bound_valid = false;
- 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_name:
- break;
-
- case DW_AT_count:
- num_elements = form_value.Unsigned();
- break;
-
- case DW_AT_bit_stride:
- bit_stride = form_value.Unsigned();
- break;
-
- case DW_AT_byte_stride:
- byte_stride = form_value.Unsigned();
- break;
-
- case DW_AT_lower_bound:
- lower_bound = form_value.Unsigned();
- break;
-
- case DW_AT_upper_bound:
- upper_bound_valid = true;
- upper_bound = form_value.Unsigned();
- break;
-
- default:
- case DW_AT_abstract_origin:
- case DW_AT_accessibility:
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_sibling:
- case DW_AT_threads_scaled:
- case DW_AT_type:
- case DW_AT_visibility:
- break;
- }
- }
- }
+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) {
+ if (!parent_die)
+ return;
- if (num_elements == 0)
- {
- if (upper_bound_valid && upper_bound >= lower_bound)
- num_elements = upper_bound - lower_bound + 1;
- }
+ 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;
+ uint64_t lower_bound = 0;
+ uint64_t upper_bound = 0;
+ bool upper_bound_valid = false;
+ 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_name:
+ break;
+
+ case DW_AT_count:
+ num_elements = form_value.Unsigned();
+ break;
+
+ case DW_AT_bit_stride:
+ bit_stride = form_value.Unsigned();
+ break;
+
+ case DW_AT_byte_stride:
+ byte_stride = form_value.Unsigned();
+ break;
+
+ case DW_AT_lower_bound:
+ lower_bound = form_value.Unsigned();
+ break;
+
+ case DW_AT_upper_bound:
+ upper_bound_valid = true;
+ upper_bound = form_value.Unsigned();
+ break;
- element_orders.push_back (num_elements);
- }
+ default:
+ case DW_AT_abstract_origin:
+ case DW_AT_accessibility:
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_data_location:
+ case DW_AT_declaration:
+ case DW_AT_description:
+ case DW_AT_sibling:
+ case DW_AT_threads_scaled:
+ case DW_AT_type:
+ case DW_AT_visibility:
+ break;
}
- break;
+ }
}
- }
-}
-
-Type *
-DWARFASTParserClang::GetTypeForDIE (const DWARFDIE &die)
-{
- if (die)
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0)
- {
- DWARFFormValue type_die_form;
- for (size_t i = 0; i < num_attributes; ++i)
- {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
- return dwarf->ResolveTypeUID(dwarf->GetDIE (DIERef(form_value)), true);
- }
+ if (num_elements == 0) {
+ if (upper_bound_valid && upper_bound >= lower_bound)
+ num_elements = upper_bound - lower_bound + 1;
}
- }
- return nullptr;
+ element_orders.push_back(num_elements);
+ }
+ } break;
+ }
+ }
}
-clang::Decl *
-DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
-{
- if (!die)
- return nullptr;
-
- switch (die.Tag())
- {
- case DW_TAG_variable:
- case DW_TAG_constant:
- case DW_TAG_formal_parameter:
- case DW_TAG_imported_declaration:
- case DW_TAG_imported_module:
- break;
- default:
- return nullptr;
+Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {
+ if (die) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ DWARFFormValue type_die_form;
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+
+ if (attr == DW_AT_type &&
+ attributes.ExtractFormValueAtIndex(i, form_value))
+ return dwarf->ResolveTypeUID(dwarf->GetDIE(DIERef(form_value)), true);
+ }
}
+ }
- DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE());
- if (cache_pos != m_die_to_decl.end())
- return cache_pos->second;
+ return nullptr;
+}
- if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification))
- {
- clang::Decl *decl = GetClangDeclForDIE(spec_die);
- m_die_to_decl[die.GetDIE()] = decl;
- m_decl_to_die[decl].insert(die.GetDIE());
- return decl;
- }
-
- if (DWARFDIE abstract_origin_die = die.GetReferencedDIE(DW_AT_abstract_origin))
- {
- clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);
- m_die_to_decl[die.GetDIE()] = decl;
- m_decl_to_die[decl].insert(die.GetDIE());
- return decl;
- }
+clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
+ if (!die)
+ return nullptr;
- clang::Decl *decl = nullptr;
- switch (die.Tag())
- {
- case DW_TAG_variable:
- case DW_TAG_constant:
- case DW_TAG_formal_parameter:
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- Type *type = GetTypeForDIE(die);
- if (dwarf && type)
- {
- const char *name = die.GetName();
- clang::DeclContext *decl_context =
- ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- decl = m_ast.CreateVariableDeclaration(decl_context, name,
- ClangUtil::GetQualType(type->GetForwardCompilerType()));
- }
- break;
- }
- case DW_TAG_imported_declaration:
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
- if (imported_uid)
- {
- CompilerDecl imported_decl = imported_uid.GetDecl();
- if (imported_decl)
- {
- clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)imported_decl.GetOpaqueDecl()))
- decl = m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl);
- }
- }
- break;
- }
- case DW_TAG_imported_module:
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
+ switch (die.Tag()) {
+ case DW_TAG_variable:
+ case DW_TAG_constant:
+ case DW_TAG_formal_parameter:
+ case DW_TAG_imported_declaration:
+ case DW_TAG_imported_module:
+ break;
+ default:
+ return nullptr;
+ }
- if (imported_uid)
- {
- CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext();
- if (imported_decl_ctx)
- {
- clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl_ctx))
- decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
- }
- }
- break;
- }
- default:
- break;
- }
+ DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE());
+ if (cache_pos != m_die_to_decl.end())
+ return cache_pos->second;
+ if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) {
+ clang::Decl *decl = GetClangDeclForDIE(spec_die);
m_die_to_decl[die.GetDIE()] = decl;
m_decl_to_die[decl].insert(die.GetDIE());
+ return decl;
+ }
+ if (DWARFDIE abstract_origin_die =
+ die.GetReferencedDIE(DW_AT_abstract_origin)) {
+ clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);
+ m_die_to_decl[die.GetDIE()] = decl;
+ m_decl_to_die[decl].insert(die.GetDIE());
return decl;
-}
+ }
-clang::DeclContext *
-DWARFASTParserClang::GetClangDeclContextForDIE (const DWARFDIE &die)
-{
- if (die)
- {
- clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE (die);
- if (decl_ctx)
- return decl_ctx;
-
- bool try_parsing_type = true;
- switch (die.Tag())
- {
- case DW_TAG_compile_unit:
- decl_ctx = m_ast.GetTranslationUnitDecl();
- try_parsing_type = false;
- break;
+ clang::Decl *decl = nullptr;
+ switch (die.Tag()) {
+ case DW_TAG_variable:
+ case DW_TAG_constant:
+ case DW_TAG_formal_parameter: {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ Type *type = GetTypeForDIE(die);
+ if (dwarf && type) {
+ const char *name = die.GetName();
+ clang::DeclContext *decl_context =
+ ClangASTContext::DeclContextGetAsDeclContext(
+ dwarf->GetDeclContextContainingUID(die.GetID()));
+ decl = m_ast.CreateVariableDeclaration(
+ decl_context, name,
+ ClangUtil::GetQualType(type->GetForwardCompilerType()));
+ }
+ break;
+ }
+ case DW_TAG_imported_declaration: {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
+ if (imported_uid) {
+ CompilerDecl imported_decl = imported_uid.GetDecl();
+ if (imported_decl) {
+ clang::DeclContext *decl_context =
+ ClangASTContext::DeclContextGetAsDeclContext(
+ dwarf->GetDeclContextContainingUID(die.GetID()));
+ if (clang::NamedDecl *clang_imported_decl =
+ llvm::dyn_cast<clang::NamedDecl>(
+ (clang::Decl *)imported_decl.GetOpaqueDecl()))
+ decl =
+ m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl);
+ }
+ }
+ break;
+ }
+ case DW_TAG_imported_module: {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
+
+ if (imported_uid) {
+ CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext();
+ if (imported_decl_ctx) {
+ clang::DeclContext *decl_context =
+ ClangASTContext::DeclContextGetAsDeclContext(
+ dwarf->GetDeclContextContainingUID(die.GetID()));
+ if (clang::NamespaceDecl *ns_decl =
+ ClangASTContext::DeclContextGetAsNamespaceDecl(
+ imported_decl_ctx))
+ decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
- case DW_TAG_namespace:
- decl_ctx = ResolveNamespaceDIE (die);
- try_parsing_type = false;
- break;
+ m_die_to_decl[die.GetDIE()] = decl;
+ m_decl_to_die[decl].insert(die.GetDIE());
- case DW_TAG_lexical_block:
- decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die);
- try_parsing_type = false;
- break;
+ return decl;
+}
- default:
- break;
- }
+clang::DeclContext *
+DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
+ if (die) {
+ clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die);
+ if (decl_ctx)
+ return decl_ctx;
+
+ bool try_parsing_type = true;
+ switch (die.Tag()) {
+ case DW_TAG_compile_unit:
+ decl_ctx = m_ast.GetTranslationUnitDecl();
+ try_parsing_type = false;
+ break;
+
+ case DW_TAG_namespace:
+ decl_ctx = ResolveNamespaceDIE(die);
+ try_parsing_type = false;
+ break;
+
+ case DW_TAG_lexical_block:
+ decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die);
+ try_parsing_type = false;
+ break;
+
+ default:
+ break;
+ }
- if (decl_ctx == nullptr && try_parsing_type)
- {
- Type* type = die.GetDWARF()->ResolveType (die);
- if (type)
- decl_ctx = GetCachedClangDeclContextForDIE (die);
- }
+ if (decl_ctx == nullptr && try_parsing_type) {
+ Type *type = die.GetDWARF()->ResolveType(die);
+ if (type)
+ decl_ctx = GetCachedClangDeclContextForDIE(die);
+ }
- if (decl_ctx)
- {
- LinkDeclContextToDIE (decl_ctx, die);
- return decl_ctx;
- }
+ if (decl_ctx) {
+ LinkDeclContextToDIE(decl_ctx, die);
+ return decl_ctx;
}
- return nullptr;
+ }
+ return nullptr;
}
-clang::BlockDecl *
-DWARFASTParserClang::ResolveBlockDIE (const DWARFDIE &die)
-{
- if (die && die.Tag() == DW_TAG_lexical_block)
- {
- clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
-
- if (!decl)
- {
- DWARFDIE decl_context_die;
- clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die);
- decl = m_ast.CreateBlockDeclaration(decl_context);
+clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
+ if (die && die.Tag() == DW_TAG_lexical_block) {
+ clang::BlockDecl *decl =
+ llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
- if (decl)
- LinkDeclContextToDIE((clang::DeclContext *)decl, die);
- }
+ if (!decl) {
+ DWARFDIE decl_context_die;
+ clang::DeclContext *decl_context =
+ GetClangDeclContextContainingDIE(die, &decl_context_die);
+ decl = m_ast.CreateBlockDeclaration(decl_context);
- return decl;
+ if (decl)
+ LinkDeclContextToDIE((clang::DeclContext *)decl, die);
}
- return nullptr;
+
+ return decl;
+ }
+ return nullptr;
}
clang::NamespaceDecl *
-DWARFASTParserClang::ResolveNamespaceDIE (const DWARFDIE &die)
-{
- if (die && die.Tag() == DW_TAG_namespace)
- {
- // See if we already parsed this namespace DIE and associated it with a
- // uniqued namespace declaration
- clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
- if (namespace_decl)
- return namespace_decl;
- else
- {
- const char *namespace_name = die.GetName();
- clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr);
- namespace_decl = m_ast.GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
- Log *log = nullptr;// (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log)
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (namespace_name)
- {
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
- static_cast<void*>(m_ast.getASTContext()),
- die.GetID(),
- namespace_name,
- static_cast<void*>(namespace_decl),
- static_cast<void*>(namespace_decl->getOriginalNamespace()));
- }
- else
- {
- dwarf->GetObjectFile()->GetModule()->LogMessage (log,
- "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
- static_cast<void*>(m_ast.getASTContext()),
- die.GetID(),
- static_cast<void*>(namespace_decl),
- static_cast<void*>(namespace_decl->getOriginalNamespace()));
- }
- }
-
- if (namespace_decl)
- LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
- return namespace_decl;
+DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
+ if (die && die.Tag() == DW_TAG_namespace) {
+ // See if we already parsed this namespace DIE and associated it with a
+ // uniqued namespace declaration
+ clang::NamespaceDecl *namespace_decl =
+ static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
+ if (namespace_decl)
+ return namespace_decl;
+ else {
+ const char *namespace_name = die.GetName();
+ clang::DeclContext *containing_decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
+ namespace_decl = m_ast.GetUniqueNamespaceDeclaration(namespace_name,
+ containing_decl_ctx);
+ Log *log =
+ nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ if (log) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ if (namespace_name) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "ASTContext => %p: 0x%8.8" PRIx64
+ ": DW_TAG_namespace with DW_AT_name(\"%s\") => "
+ "clang::NamespaceDecl *%p (original = %p)",
+ static_cast<void *>(m_ast.getASTContext()), die.GetID(),
+ namespace_name, static_cast<void *>(namespace_decl),
+ static_cast<void *>(namespace_decl->getOriginalNamespace()));
+ } else {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "ASTContext => %p: 0x%8.8" PRIx64
+ ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p "
+ "(original = %p)",
+ static_cast<void *>(m_ast.getASTContext()), die.GetID(),
+ static_cast<void *>(namespace_decl),
+ static_cast<void *>(namespace_decl->getOriginalNamespace()));
}
+ }
+
+ if (namespace_decl)
+ LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die);
+ return namespace_decl;
}
- return nullptr;
+ }
+ return nullptr;
}
-clang::DeclContext *
-DWARFASTParserClang::GetClangDeclContextContainingDIE (const DWARFDIE &die,
- DWARFDIE *decl_ctx_die_copy)
-{
- SymbolFileDWARF *dwarf = die.GetDWARF();
+clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE(
+ const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
- DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE (die);
+ DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die);
- if (decl_ctx_die_copy)
- *decl_ctx_die_copy = decl_ctx_die;
+ if (decl_ctx_die_copy)
+ *decl_ctx_die_copy = decl_ctx_die;
- if (decl_ctx_die)
- {
- clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (decl_ctx_die);
- if (clang_decl_ctx)
- return clang_decl_ctx;
- }
- return m_ast.GetTranslationUnitDecl();
+ if (decl_ctx_die) {
+ clang::DeclContext *clang_decl_ctx =
+ GetClangDeclContextForDIE(decl_ctx_die);
+ if (clang_decl_ctx)
+ return clang_decl_ctx;
+ }
+ return m_ast.GetTranslationUnitDecl();
}
clang::DeclContext *
-DWARFASTParserClang::GetCachedClangDeclContextForDIE (const DWARFDIE &die)
-{
- if (die)
- {
- DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());
- if (pos != m_die_to_decl_ctx.end())
- return pos->second;
- }
- return nullptr;
+DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) {
+ if (die) {
+ DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());
+ if (pos != m_die_to_decl_ctx.end())
+ return pos->second;
+ }
+ return nullptr;
}
-void
-DWARFASTParserClang::LinkDeclContextToDIE (clang::DeclContext *decl_ctx, const DWARFDIE &die)
-{
- m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
- // There can be many DIEs for a single decl context
- //m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
- m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
+void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
+ const DWARFDIE &die) {
+ m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
+ // There can be many DIEs for a single decl context
+ // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
+ m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
}
-bool
-DWARFASTParserClang::CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die,
- const DWARFDIE &dst_class_die,
- lldb_private::Type *class_type,
- DWARFDIECollection &failures)
-{
- if (!class_type || !src_class_die || !dst_class_die)
- return false;
- if (src_class_die.Tag() != dst_class_die.Tag())
- return false;
+bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
+ const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die,
+ lldb_private::Type *class_type, DWARFDIECollection &failures) {
+ if (!class_type || !src_class_die || !dst_class_die)
+ return false;
+ if (src_class_die.Tag() != dst_class_die.Tag())
+ return false;
- // We need to complete the class type so we can get all of the method types
- // parsed so we can then unique those types to their equivalent counterparts
- // in "dst_cu" and "dst_class_die"
- class_type->GetFullCompilerType ();
-
- DWARFDIE src_die;
- DWARFDIE dst_die;
- UniqueCStringMap<DWARFDIE> src_name_to_die;
- UniqueCStringMap<DWARFDIE> dst_name_to_die;
- UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
- UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
- for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); src_die = src_die.GetSibling())
- {
- if (src_die.Tag() == DW_TAG_subprogram)
- {
- // Make sure this is a declaration and not a concrete instance by looking
- // for DW_AT_declaration set to 1. Sometimes concrete function instances
- // are placed inside the class definitions and shouldn't be included in
- // the list of things are are tracking here.
- if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1)
- {
- const char *src_name = src_die.GetMangledName ();
- if (src_name)
- {
- ConstString src_const_name(src_name);
- if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
- src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
- else
- src_name_to_die.Append(src_const_name.GetCString(), src_die);
- }
- }
+ // We need to complete the class type so we can get all of the method types
+ // parsed so we can then unique those types to their equivalent counterparts
+ // in "dst_cu" and "dst_class_die"
+ class_type->GetFullCompilerType();
+
+ DWARFDIE src_die;
+ DWARFDIE dst_die;
+ UniqueCStringMap<DWARFDIE> src_name_to_die;
+ UniqueCStringMap<DWARFDIE> dst_name_to_die;
+ UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
+ UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
+ for (src_die = src_class_die.GetFirstChild(); src_die.IsValid();
+ src_die = src_die.GetSibling()) {
+ if (src_die.Tag() == DW_TAG_subprogram) {
+ // Make sure this is a declaration and not a concrete instance by looking
+ // for DW_AT_declaration set to 1. Sometimes concrete function instances
+ // are placed inside the class definitions and shouldn't be included in
+ // the list of things are are tracking here.
+ if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
+ const char *src_name = src_die.GetMangledName();
+ if (src_name) {
+ ConstString src_const_name(src_name);
+ if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
+ src_name_to_die_artificial.Append(src_const_name.GetStringRef(),
+ src_die);
+ else
+ src_name_to_die.Append(src_const_name.GetStringRef(), src_die);
}
+ }
}
- for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); dst_die = dst_die.GetSibling())
- {
- if (dst_die.Tag() == DW_TAG_subprogram)
- {
- // Make sure this is a declaration and not a concrete instance by looking
- // for DW_AT_declaration set to 1. Sometimes concrete function instances
- // are placed inside the class definitions and shouldn't be included in
- // the list of things are are tracking here.
- if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1)
- {
- const char *dst_name = dst_die.GetMangledName ();
- if (dst_name)
- {
- ConstString dst_const_name(dst_name);
- if ( dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
- dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
- else
- dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
- }
- }
+ }
+ for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
+ dst_die = dst_die.GetSibling()) {
+ if (dst_die.Tag() == DW_TAG_subprogram) {
+ // Make sure this is a declaration and not a concrete instance by looking
+ // for DW_AT_declaration set to 1. Sometimes concrete function instances
+ // are placed inside the class definitions and shouldn't be included in
+ // the list of things are are tracking here.
+ if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
+ const char *dst_name = dst_die.GetMangledName();
+ if (dst_name) {
+ ConstString dst_const_name(dst_name);
+ if (dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
+ dst_name_to_die_artificial.Append(dst_const_name.GetStringRef(),
+ dst_die);
+ else
+ dst_name_to_die.Append(dst_const_name.GetStringRef(), dst_die);
}
+ }
}
- const uint32_t src_size = src_name_to_die.GetSize ();
- const uint32_t dst_size = dst_name_to_die.GetSize ();
- Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
-
- // Is everything kosher so we can go through the members at top speed?
- bool fast_path = true;
-
- if (src_size != dst_size)
- {
- if (src_size != 0 && dst_size != 0)
- {
- if (log)
- log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
- src_class_die.GetOffset(),
- dst_class_die.GetOffset(),
- src_size,
- dst_size);
- }
-
- fast_path = false;
+ }
+ const uint32_t src_size = src_name_to_die.GetSize();
+ const uint32_t dst_size = dst_name_to_die.GetSize();
+ Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO |
+ // DWARF_LOG_TYPE_COMPLETION));
+
+ // Is everything kosher so we can go through the members at top speed?
+ bool fast_path = true;
+
+ if (src_size != dst_size) {
+ if (src_size != 0 && dst_size != 0) {
+ if (log)
+ log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but they didn't have the same size (src=%d, dst=%d)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(),
+ src_size, dst_size);
}
- uint32_t idx;
+ fast_path = false;
+ }
- if (fast_path)
- {
- for (idx = 0; idx < src_size; ++idx)
- {
- src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
- dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
+ uint32_t idx;
- if (src_die.Tag() != dst_die.Tag())
- {
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
- src_class_die.GetOffset(),
- dst_class_die.GetOffset(),
- src_die.GetOffset(),
- src_die.GetTagAsCString(),
- dst_die.GetOffset(),
- dst_die.GetTagAsCString());
- fast_path = false;
- }
+ if (fast_path) {
+ for (idx = 0; idx < src_size; ++idx) {
+ src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);
+ dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
- const char *src_name = src_die.GetMangledName ();
- const char *dst_name = dst_die.GetMangledName ();
+ if (src_die.Tag() != dst_die.Tag()) {
+ if (log)
+ log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(),
+ src_die.GetOffset(), src_die.GetTagAsCString(),
+ dst_die.GetOffset(), dst_die.GetTagAsCString());
+ fast_path = false;
+ }
- // Make sure the names match
- if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
- continue;
+ const char *src_name = src_die.GetMangledName();
+ const char *dst_name = dst_die.GetMangledName();
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
- src_class_die.GetOffset(),
- dst_class_die.GetOffset(),
- src_die.GetOffset(),
- src_name,
- dst_die.GetOffset(),
- dst_name);
-
- fast_path = false;
- }
- }
+ // Make sure the names match
+ if (src_name == dst_name || (strcmp(src_name, dst_name) == 0))
+ continue;
- DWARFASTParserClang *src_dwarf_ast_parser = (DWARFASTParserClang *)src_die.GetDWARFParser();
- DWARFASTParserClang *dst_dwarf_ast_parser = (DWARFASTParserClang *)dst_die.GetDWARFParser();
+ if (log)
+ log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(),
+ src_die.GetOffset(), src_name, dst_die.GetOffset(),
+ dst_name);
- // Now do the work of linking the DeclContexts and Types.
- if (fast_path)
- {
- // We can do this quickly. Just run across the tables index-for-index since
- // we know each node has matching names and tags.
- for (idx = 0; idx < src_size; ++idx)
- {
- src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
- dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
-
- clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
- if (src_decl_ctx)
- {
- if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_decl_ctx),
- src_die.GetOffset(), dst_die.GetOffset());
- dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die);
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
- }
-
- Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
- if (src_child_type)
- {
- if (log)
- log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_child_type),
- src_child_type->GetID(),
- src_die.GetOffset(), dst_die.GetOffset());
- dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
- }
- }
+ fast_path = false;
}
- else
- {
- // We must do this slowly. For each member of the destination, look
- // up a member in the source with the same name, check its tag, and
- // unique them if everything matches up. Report failures.
-
- if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
- {
- src_name_to_die.Sort();
-
- for (idx = 0; idx < dst_size; ++idx)
- {
- const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
- dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
- src_die = src_name_to_die.Find(dst_name, DWARFDIE());
-
- if (src_die && (src_die.Tag() == dst_die.Tag()))
- {
- clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
- if (src_decl_ctx)
- {
- if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_decl_ctx),
- src_die.GetOffset(),
- dst_die.GetOffset());
- dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die);
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
- }
-
- Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
- if (src_child_type)
- {
- if (log)
- log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_child_type),
- src_child_type->GetID(),
- src_die.GetOffset(),
- dst_die.GetOffset());
- dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
- }
- }
- else
- {
- if (log)
- log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die.GetOffset());
-
- failures.Append(dst_die);
- }
- }
- }
+ }
+
+ DWARFASTParserClang *src_dwarf_ast_parser =
+ (DWARFASTParserClang *)src_die.GetDWARFParser();
+ DWARFASTParserClang *dst_dwarf_ast_parser =
+ (DWARFASTParserClang *)dst_die.GetDWARFParser();
+
+ // Now do the work of linking the DeclContexts and Types.
+ if (fast_path) {
+ // We can do this quickly. Just run across the tables index-for-index since
+ // we know each node has matching names and tags.
+ for (idx = 0; idx < src_size; ++idx) {
+ src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);
+ dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
+
+ clang::DeclContext *src_decl_ctx =
+ src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
+ if (src_decl_ctx) {
+ if (log)
+ log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
+ dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
+ } else {
+ if (log)
+ log->Printf("warning: tried to unique decl context from 0x%8.8x for "
+ "0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
+ }
+
+ Type *src_child_type =
+ dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
+ if (src_child_type) {
+ if (log)
+ log->Printf(
+ "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
+ dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
+ } else {
+ if (log)
+ log->Printf("warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
+ }
}
-
- const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
- const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
-
- if (src_size_artificial && dst_size_artificial)
- {
- dst_name_to_die_artificial.Sort();
-
- for (idx = 0; idx < src_size_artificial; ++idx)
- {
- const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
- src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
- dst_die = dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE());
-
- if (dst_die)
- {
- // Both classes have the artificial types, link them
- clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
- if (src_decl_ctx)
- {
- if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_decl_ctx),
- src_die.GetOffset(), dst_die.GetOffset());
- dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die);
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
- }
-
- Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
- if (src_child_type)
- {
- if (log)
- log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_child_type),
- src_child_type->GetID(),
- src_die.GetOffset(), dst_die.GetOffset());
- dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
- }
- }
+ } else {
+ // We must do this slowly. For each member of the destination, look
+ // up a member in the source with the same name, check its tag, and
+ // unique them if everything matches up. Report failures.
+
+ if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) {
+ src_name_to_die.Sort();
+
+ for (idx = 0; idx < dst_size; ++idx) {
+ llvm::StringRef dst_name = dst_name_to_die.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
+ src_die = src_name_to_die.Find(dst_name, DWARFDIE());
+
+ if (src_die && (src_die.Tag() == dst_die.Tag())) {
+ clang::DeclContext *src_decl_ctx =
+ src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
+ if (src_decl_ctx) {
+ if (log)
+ log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx),
+ src_die.GetOffset(), dst_die.GetOffset());
+ dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
+ } else {
+ if (log)
+ log->Printf("warning: tried to unique decl context from 0x%8.8x "
+ "for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
+ }
+
+ Type *src_child_type =
+ dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
+ if (src_child_type) {
+ if (log)
+ log->Printf("uniquing type %p (uid=0x%" PRIx64
+ ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type),
+ src_child_type->GetID(), src_die.GetOffset(),
+ dst_die.GetOffset());
+ dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] =
+ src_child_type;
+ } else {
+ if (log)
+ log->Printf("warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
+ }
+ } else {
+ if (log)
+ log->Printf("warning: couldn't find a match for 0x%8.8x",
+ dst_die.GetOffset());
+
+ failures.Append(dst_die);
}
+ }
}
+ }
+
+ const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize();
+ const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize();
+
+ if (src_size_artificial && dst_size_artificial) {
+ dst_name_to_die_artificial.Sort();
+
+ for (idx = 0; idx < src_size_artificial; ++idx) {
+ llvm::StringRef src_name_artificial =
+ src_name_to_die_artificial.GetCStringAtIndex(idx);
+ src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
+ dst_die =
+ dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE());
+
+ if (dst_die) {
+ // Both classes have the artificial types, link them
+ clang::DeclContext *src_decl_ctx =
+ src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
+ if (src_decl_ctx) {
+ if (log)
+ log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
+ dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
+ } else {
+ if (log)
+ log->Printf("warning: tried to unique decl context from 0x%8.8x "
+ "for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
+ }
- if (dst_size_artificial)
- {
- for (idx = 0; idx < dst_size_artificial; ++idx)
- {
- const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
- dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
- if (log)
- log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die.GetOffset(), dst_name_artificial);
-
- failures.Append(dst_die);
+ Type *src_child_type =
+ dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
+ if (src_child_type) {
+ if (log)
+ log->Printf(
+ "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
+ dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
+ } else {
+ if (log)
+ log->Printf("warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
+ }
}
+ }
+
+ if (dst_size_artificial) {
+ for (idx = 0; idx < dst_size_artificial; ++idx) {
+ llvm::StringRef dst_name_artificial =
+ dst_name_to_die_artificial.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
+ if (log)
+ log->Printf("warning: need to create artificial method for 0x%8.8x for "
+ "method '%s'",
+ dst_die.GetOffset(), dst_name_artificial.str().c_str());
+
+ failures.Append(dst_die);
+ }
+ }
- return (failures.Size() != 0);
+ return (failures.Size() != 0);
}
-
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 0826423b0359..3d6d08eef9ed 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -13,10 +13,10 @@
// 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"
-#include "clang/AST/CharUnits.h"
// Project includes
#include "DWARFASTParser.h"
@@ -29,149 +29,131 @@
class DWARFDebugInfoEntry;
class DWARFDIECollection;
-class DWARFASTParserClang : public DWARFASTParser
-{
+class DWARFASTParserClang : public DWARFASTParser {
public:
- DWARFASTParserClang (lldb_private::ClangASTContext &ast);
-
- ~DWARFASTParserClang() override;
+ DWARFASTParserClang(lldb_private::ClangASTContext &ast);
- // DWARFASTParser interface.
- lldb::TypeSP
- ParseTypeFromDWARF (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- lldb_private::Log *log,
- bool *type_is_new_ptr) override;
+ ~DWARFASTParserClang() override;
+ // DWARFASTParser interface.
+ 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;
+ 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;
+ bool
+ CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ lldb_private::CompilerType &compiler_type) override;
- lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF (const DWARFDIE &die) override;
+ lldb_private::CompilerDecl
+ GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
- std::vector<DWARFDIE>
- GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override;
+ std::vector<DWARFDIE>
+ GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUIDFromDWARF (const DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
- lldb_private::ClangASTImporter &
- GetClangASTImporter();
+ lldb_private::ClangASTImporter &GetClangASTImporter();
protected:
- class DelayedAddObjCClassProperty;
- typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList;
-
- clang::BlockDecl *
- ResolveBlockDIE (const DWARFDIE &die);
-
- clang::NamespaceDecl *
- ResolveNamespaceDIE (const DWARFDIE &die);
-
- bool
- ParseTemplateDIE (const DWARFDIE &die,
- lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
- bool
- ParseTemplateParameterInfos (const DWARFDIE &parent_die,
- 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);
-
- size_t
- ParseChildParameters (const lldb_private::SymbolContext& sc,
- clang::DeclContext *containing_decl_ctx,
- const DWARFDIE &parent_die,
- bool skip_artificial,
- bool &is_static,
- bool &is_variadic,
- bool &has_template_params,
- std::vector<lldb_private::CompilerType>& function_args,
- 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,
- const DWARFDIE &parent_die);
-
- lldb_private::Type *
- GetTypeForDIE (const DWARFDIE &die);
-
- clang::Decl *
- GetClangDeclForDIE (const DWARFDIE &die);
-
- clang::DeclContext *
- GetClangDeclContextForDIE (const DWARFDIE &die);
-
- clang::DeclContext *
- GetClangDeclContextContainingDIE (const DWARFDIE &die,
- DWARFDIE *decl_ctx_die);
-
- bool
- CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die,
- const DWARFDIE &dst_class_die,
- lldb_private::Type *class_type,
- DWARFDIECollection &failures);
-
- clang::DeclContext *
- GetCachedClangDeclContextForDIE (const DWARFDIE &die);
-
- void
- LinkDeclContextToDIE (clang::DeclContext *decl_ctx,
- const DWARFDIE &die);
-
- void
- LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);
-
- lldb::TypeSP
- ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log);
-
- //----------------------------------------------------------------------
- // Return true if this type is a declaration to a type in an external
- // module.
- //----------------------------------------------------------------------
- lldb::ModuleSP
- GetModuleForType (const DWARFDIE &die);
-
- typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
- //typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;
- typedef std::multimap<const clang::DeclContext *, const DWARFDIE> DeclContextToDIEMap;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> DIEToDeclMap;
- typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
-
- lldb_private::ClangASTContext &m_ast;
- DIEToDeclMap m_die_to_decl;
- DeclToDIEMap m_decl_to_die;
- DIEToDeclContextMap m_die_to_decl_ctx;
- DeclContextToDIEMap m_decl_ctx_to_die;
- std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
+ class DelayedAddObjCClassProperty;
+ typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
+
+ clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
+
+ clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
+
+ bool ParseTemplateDIE(const DWARFDIE &die,
+ lldb_private::ClangASTContext::TemplateParameterInfos
+ &template_param_infos);
+ bool ParseTemplateParameterInfos(
+ const DWARFDIE &parent_die,
+ 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);
+
+ size_t
+ ParseChildParameters(const lldb_private::SymbolContext &sc,
+ clang::DeclContext *containing_decl_ctx,
+ const DWARFDIE &parent_die, bool skip_artificial,
+ bool &is_static, bool &is_variadic,
+ bool &has_template_params,
+ std::vector<lldb_private::CompilerType> &function_args,
+ 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,
+ const DWARFDIE &parent_die);
+
+ lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
+
+ clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
+
+ clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die);
+
+ clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
+ DWARFDIE *decl_ctx_die);
+
+ bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
+ const DWARFDIE &dst_class_die,
+ lldb_private::Type *class_type,
+ DWARFDIECollection &failures);
+
+ clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
+
+ void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die);
+
+ void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
+
+ lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log);
+
+ //----------------------------------------------------------------------
+ // Return true if this type is a declaration to a type in an external
+ // module.
+ //----------------------------------------------------------------------
+ lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
+
+ typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+ DIEToDeclContextMap;
+ // typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet>
+ // DeclContextToDIEMap;
+ typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
+ DeclContextToDIEMap;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
+ DIEToDeclMap;
+ typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
+
+ lldb_private::ClangASTContext &m_ast;
+ DIEToDeclMap m_die_to_decl;
+ DeclToDIEMap m_decl_to_die;
+ DIEToDeclContextMap m_die_to_decl_ctx;
+ DeclContextToDIEMap m_decl_ctx_to_die;
+ std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
index 346e2d63b908..2507465750c7 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -11,11 +11,11 @@
#include "DWARFASTParserGo.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIE.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
-#include "DWARFDIE.h"
-#include "DWARFDIECollection.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include "UniqueDWARFASTType.h"
@@ -44,787 +44,732 @@
using namespace lldb;
using namespace lldb_private;
-DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast)
- : m_ast(ast)
-{
-}
+DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {}
-DWARFASTParserGo::~DWARFASTParserGo()
-{
-}
+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;
+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 (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());
- }
+ 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();
- }
+ 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;
+ }
+ }
+ }
+ }
- 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);
- }
- }
- }
+ 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_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());
- }
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ byte_size_valid = true;
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);
- }
- }
- }
+ case DW_AT_go_kind:
+ go_kind = form_value.Unsigned();
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;
+ // TODO: Should we use SLICETYPE's DW_AT_go_elem?
+ default:
+ break;
+ }
}
+ }
+ }
- if (type_sp.get())
- {
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+ // 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;
+ }
+ }
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_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;
- }
+ 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);
+ }
- if (symbol_context_scope != NULL)
- {
- type_sp->SetSymbolContextScope(symbol_context_scope);
- }
+ 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;
- // We are ready to put this type into the uniqued list up at the module level
- type_list->Insert(type_sp);
+ case DW_AT_external:
+ if (form_value.Unsigned()) {
+ if (storage == clang::SC_None)
+ storage = clang::SC_Extern;
+ else
+ storage = clang::SC_PrivateExtern;
+ }
+ break;
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+ case DW_AT_high_pc:
+ case DW_AT_low_pc:
+ break;
+ }
}
+ }
}
- 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,
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- const DWARFDIE &parent_die, bool &is_variadic,
- std::vector<CompilerType> &function_param_types)
-{
- if (!parent_die)
- return 0;
+ std::vector<CompilerType> function_param_types;
- size_t arg_idx = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
- {
+ // Parse the function children for the parameters
- 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;
+ if (die.HasChildren()) {
+ ParseChildParameters(sc, die, is_variadic, function_param_types);
+ }
- case DW_TAG_unspecified_parameters:
- is_variadic = true;
+ // 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;
- default:
+ 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) {
+ 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 arg_idx;
+ }
+ return type_sp;
}
-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);
- }
+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;
}
- 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;
}
-bool
-DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &compiler_type)
-{
- if (!die)
- return false;
+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;
- 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);
- }
+ default:
+ case DW_AT_type:
+ break;
}
- m_ast.CompleteStructType(compiler_type);
- return (bool)compiler_type;
+ }
}
- default:
- assert(false && "not a forward go type decl!");
- 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;
-}
-size_t
-DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_compiler_type)
-{
- size_t count = 0;
- uint32_t member_idx = 0;
+ const dw_tag_t tag = die.Tag();
- 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;
+ 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;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
+ switch (tag) {
+ case DW_TAG_structure_type: {
{
- 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.GetDWARF()->get_debug_info_data();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
- NULL, // ClangExpressionVariableList *
- NULL, // ClangExpressionDeclMap *
- NULL, // RegisterContext *
- module_sp, debug_info_data, die.GetCU(),
- block_offset, block_length, eRegisterKindDWARF,
- &initialValue, NULL, 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);
- }
+ 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.GetDWARF()->get_debug_info_data();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ if (DWARFExpression::Evaluate(
+ NULL, // ExecutionContext *
+ NULL, // ClangExpressionVariableList *
+ NULL, // ClangExpressionDeclMap *
+ NULL, // RegisterContext *
+ module_sp, debug_info_data, die.GetCU(), block_offset,
+ block_length, eRegisterKindDWARF, &initialValue, NULL,
+ memberOffset, NULL)) {
+ member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
- ++member_idx;
- }
- break;
+ } 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;
+ 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;
+ 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);
- }
+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 (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();
- }
- }
+ 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;
+ }
+ return NULL;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
index 5039fc7f7672..2a7c3871a309 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
@@ -18,67 +18,67 @@
#include "llvm/ADT/SmallVector.h"
// Project includes
-#include "lldb/Core/PluginInterface.h"
-#include "lldb/Symbol/GoASTContext.h"
-#include "DWARFDefines.h"
#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
-{
+class DWARFASTParserGo : public DWARFASTParser {
public:
- DWARFASTParserGo(lldb_private::GoASTContext &ast);
+ DWARFASTParserGo(lldb_private::GoASTContext &ast);
- ~DWARFASTParserGo() override;
+ ~DWARFASTParserGo() override;
- lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log,
- bool *type_is_new_ptr) 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;
+ 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;
+ 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
+ GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override {
+ return lldb_private::CompilerDeclContext();
+ }
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF(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();
- }
+ 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>();
- }
+ 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;
+ 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
index b21bf2ded489..8b5202ba265f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
@@ -23,533 +23,487 @@
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");
- }
- }
+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);
+ 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)
- {
+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_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");
- }
+ 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");
}
+ }
- 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;
- 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;
+ 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");
- }
- }
+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;
-}
+ DIERef type_die_ref(type_attr_value);
+ Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
+ if (!pointee_type)
+ return nullptr;
-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");
- }
- }
- }
+ 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;
+}
- 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;
- }
- }
- }
+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");
+ }
}
-
- 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;
+ }
+
+ 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;
}
+ }
}
-
- 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();
+ }
+
+ 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;
}
- 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;
- }
- }
+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 (!type_sp)
- return nullptr;
+ if (!die)
+ return nullptr;
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+ SymbolFileDWARF *dwarf = die.GetDWARF();
- SymbolContextScope *symbol_context_scope = nullptr;
- if (sc_parent_tag == DW_TAG_compile_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;
- }
+ 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) {
+ 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);
+ 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();
+ dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
- return type_sp;
+ 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);
- }
+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();
- }
- }
+ 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;
+ }
+ 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();
- }
- }
+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) {
+ DWARFCompileUnit *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 && "Not a forward java type declaration!");
+ 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;
}
- return false;
-}
+ case DW_TAG_inheritance: {
+ DWARFFormValue encoding_uid;
+ uint32_t member_byte_offset = UINT32_MAX;
-void
-DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, CompilerType &compiler_type)
-{
- DWARFCompileUnit *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;
+ 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
index 6a7eee75e6f7..01d81833d517 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
@@ -27,64 +27,55 @@
class DWARFDebugInfoEntry;
class DWARFDIECollection;
-class DWARFASTParserJava : public DWARFASTParser
-{
+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);
+ 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_private::JavaASTContext &m_ast;
- lldb::TypeSP
- ParseBaseTypeFromDIE(const DWARFDIE &die);
+ lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die);
- lldb::TypeSP
- ParseArrayTypeFromDIE(const DWARFDIE &die);
+ lldb::TypeSP ParseArrayTypeFromDIE(const DWARFDIE &die);
- lldb::TypeSP
- ParseReferenceTypeFromDIE(const DWARFDIE &die);
+ lldb::TypeSP ParseReferenceTypeFromDIE(const DWARFDIE &die);
- lldb::TypeSP
- ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type);
+ 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
new file mode 100644
index 000000000000..0cf7ff2b938f
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
@@ -0,0 +1,209 @@
+//===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===//
+
+#include "DWARFASTParserOCaml.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.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"
+
+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) {
+ 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
new file mode 100644
index 000000000000..e3b2279ca8fc
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
@@ -0,0 +1,60 @@
+//===-- DWARFASTParserOCaml.h -----------------------------------*- C++ -*-===//
+
+#ifndef SymbolFileDWARF_DWARFASTParserOCaml_h_
+#define SymbolFileDWARF_DWARFASTParserOCaml_h_
+
+#include "DWARFASTParser.h"
+#include "DWARFCompileUnit.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 14fc2cea2329..bc49fc5de2cd 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -15,103 +15,80 @@
using namespace lldb_private;
-DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() :
- m_code (InvalidCode),
- m_tag (0),
- m_has_children (0),
- m_attributes()
-{
-}
+DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
+ : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {}
-DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) :
- m_code (InvalidCode),
- m_tag (tag),
- m_has_children (has_children),
- m_attributes()
-{
-}
+DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
+ uint8_t has_children)
+ : m_code(InvalidCode), m_tag(tag), m_has_children(has_children),
+ m_attributes() {}
-bool
-DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr)
-{
- return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
+bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
}
-bool
-DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
-{
- m_code = code;
- m_attributes.clear();
- if (m_code)
- {
- m_tag = data.GetULEB128(offset_ptr);
- m_has_children = data.GetU8(offset_ptr);
-
- while (data.ValidOffset(*offset_ptr))
- {
- dw_attr_t attr = data.GetULEB128(offset_ptr);
- dw_form_t form = data.GetULEB128(offset_ptr);
-
- if (attr && form)
- m_attributes.push_back(DWARFAttribute(attr, form));
- else
- break;
- }
-
- return m_tag != 0;
- }
- else
- {
- m_tag = 0;
- m_has_children = 0;
+bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ dw_uleb128_t code) {
+ m_code = code;
+ m_attributes.clear();
+ if (m_code) {
+ m_tag = data.GetULEB128(offset_ptr);
+ m_has_children = data.GetU8(offset_ptr);
+
+ while (data.ValidOffset(*offset_ptr)) {
+ dw_attr_t attr = data.GetULEB128(offset_ptr);
+ dw_form_t form = data.GetULEB128(offset_ptr);
+
+ if (attr && form)
+ m_attributes.push_back(DWARFAttribute(attr, form));
+ else
+ break;
}
- return false;
-}
+ return m_tag != 0;
+ } else {
+ m_tag = 0;
+ m_has_children = 0;
+ }
+ return false;
+}
-void
-DWARFAbbreviationDeclaration::Dump(Stream *s) const
-{
- s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, has_children = %s\n", m_code, DW_TAG_value_to_name(m_tag), DW_CHILDREN_value_to_name(m_has_children));
+void DWARFAbbreviationDeclaration::Dump(Stream *s) const {
+ s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, "
+ "has_children = %s\n",
+ m_code, DW_TAG_value_to_name(m_tag),
+ DW_CHILDREN_value_to_name(m_has_children));
- DWARFAttribute::const_iterator pos;
+ DWARFAttribute::const_iterator pos;
- for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
- s->Printf(" attr = %s, form = %s\n", DW_AT_value_to_name(pos->get_attr()), DW_FORM_value_to_name(pos->get_form()));
+ for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
+ s->Printf(" attr = %s, form = %s\n",
+ DW_AT_value_to_name(pos->get_attr()),
+ DW_FORM_value_to_name(pos->get_form()));
- s->Printf("\n");
+ s->Printf("\n");
}
-
-
-bool
-DWARFAbbreviationDeclaration::IsValid()
-{
- return m_code != 0 && m_tag != 0;
+bool DWARFAbbreviationDeclaration::IsValid() {
+ return m_code != 0 && m_tag != 0;
}
-
-
uint32_t
-DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const
-{
- uint32_t i;
- const uint32_t kNumAttributes = m_attributes.size();
- for (i = 0; i < kNumAttributes; ++i)
- {
- if (m_attributes[i].get_attr() == attr)
- return i;
- }
- return DW_INVALID_INDEX;
+DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
+ uint32_t i;
+ const uint32_t kNumAttributes = m_attributes.size();
+ for (i = 0; i < kNumAttributes; ++i) {
+ if (m_attributes[i].get_attr() == attr)
+ return i;
+ }
+ return DW_INVALID_INDEX;
}
-
-bool
-DWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const
-{
- return Tag() == rhs.Tag()
- && HasChildren() == rhs.HasChildren()
- && Attributes() == rhs.Attributes();
+bool DWARFAbbreviationDeclaration::
+operator==(const DWARFAbbreviationDeclaration &rhs) const {
+ return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
+ Attributes() == rhs.Attributes();
}
-
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
index 0ef153a704cd..28e713f9beb1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -10,63 +10,66 @@
#ifndef liblldb_DWARFAbbreviationDeclaration_h_
#define liblldb_DWARFAbbreviationDeclaration_h_
-#include "SymbolFileDWARF.h"
#include "DWARFAttribute.h"
+#include "SymbolFileDWARF.h"
class DWARFCompileUnit;
-class DWARFAbbreviationDeclaration
-{
+class DWARFAbbreviationDeclaration {
public:
- enum { InvalidCode = 0 };
- DWARFAbbreviationDeclaration();
+ enum { InvalidCode = 0 };
+ DWARFAbbreviationDeclaration();
+
+ // For hand crafting an abbreviation declaration
+ DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children);
+ void AddAttribute(const DWARFAttribute &attr) {
+ m_attributes.push_back(attr);
+ }
- // For hand crafting an abbreviation declaration
- DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children);
- void AddAttribute(const DWARFAttribute& attr)
- {
- m_attributes.push_back(attr);
- }
+ dw_uleb128_t Code() const { return m_code; }
+ void SetCode(dw_uleb128_t code) { m_code = code; }
+ dw_tag_t Tag() const { return m_tag; }
+ bool HasChildren() const { return m_has_children; }
+ size_t NumAttributes() const { return m_attributes.size(); }
+ dw_attr_t GetAttrByIndex(uint32_t idx) const {
+ return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0;
+ }
+ 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;
+ }
- dw_uleb128_t Code() const { return m_code; }
- void SetCode(dw_uleb128_t code) { m_code = code; }
- dw_tag_t Tag() const { return m_tag; }
- bool HasChildren() const { return m_has_children; }
- size_t NumAttributes() const { return m_attributes.size(); }
- dw_attr_t GetAttrByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0; }
- 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);
+ }
+ dw_form_t GetFormByIndexUnchecked(uint32_t idx) const {
+ return m_attributes[idx].get_form();
+ }
+ uint32_t FindAttributeIndex(dw_attr_t attr) const;
+ bool Extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+ bool Extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr, dw_uleb128_t code);
+ bool IsValid();
+ void Dump(lldb_private::Stream *s) const;
+ bool operator==(const DWARFAbbreviationDeclaration &rhs) const;
+ const DWARFAttribute::collection &Attributes() const { return m_attributes; }
- // 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);
- }
- dw_form_t GetFormByIndexUnchecked (uint32_t idx) const
- {
- return m_attributes[idx].get_form();
- }
- uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool Extract(const lldb_private::DWARFDataExtractor& data, lldb::offset_t *offset_ptr);
- bool Extract(const lldb_private::DWARFDataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code);
- bool IsValid();
- void Dump(lldb_private::Stream *s) const;
- bool operator == (const DWARFAbbreviationDeclaration& rhs) const;
- const DWARFAttribute::collection& Attributes() const { return m_attributes; }
protected:
- dw_uleb128_t m_code;
- dw_tag_t m_tag;
- uint8_t m_has_children;
- DWARFAttribute::collection m_attributes;
+ dw_uleb128_t m_code;
+ dw_tag_t m_tag;
+ uint8_t m_has_children;
+ DWARFAttribute::collection m_attributes;
};
-#endif // liblldb_DWARFAbbreviationDeclaration_h_
+#endif // liblldb_DWARFAbbreviationDeclaration_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index a522bcb35288..d2573f3742ba 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -8,83 +8,67 @@
//===----------------------------------------------------------------------===//
#include "DWARFAttribute.h"
-#include "DWARFDebugInfo.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
-DWARFAttributes::DWARFAttributes() :
- m_infos()
-{
-}
+DWARFAttributes::DWARFAttributes() : m_infos() {}
-DWARFAttributes::~DWARFAttributes()
-{
-}
+DWARFAttributes::~DWARFAttributes() {}
-
-uint32_t
-DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const
-{
- collection::const_iterator end = m_infos.end();
- collection::const_iterator beg = m_infos.begin();
- collection::const_iterator pos;
- for (pos = beg; pos != end; ++pos)
- {
- if (pos->attr.get_attr() == attr)
- return std::distance(beg, pos);
- }
- return UINT32_MAX;
+uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
+ collection::const_iterator end = m_infos.end();
+ collection::const_iterator beg = m_infos.begin();
+ collection::const_iterator pos;
+ for (pos = beg; pos != end; ++pos) {
+ if (pos->attr.get_attr() == attr)
+ return std::distance(beg, pos);
+ }
+ return UINT32_MAX;
}
-void
-DWARFAttributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form)
-{
- AttributeValue attr_value = { cu, attr_die_offset, { attr, form } };
- m_infos.push_back(attr_value);
+void DWARFAttributes::Append(const DWARFCompileUnit *cu,
+ dw_offset_t attr_die_offset, dw_attr_t attr,
+ dw_form_t form) {
+ AttributeValue attr_value = {cu, attr_die_offset, {attr, form}};
+ m_infos.push_back(attr_value);
}
-bool
-DWARFAttributes::ContainsAttribute(dw_attr_t attr) const
-{
- return FindAttributeIndex(attr) != UINT32_MAX;
+bool DWARFAttributes::ContainsAttribute(dw_attr_t attr) const {
+ return FindAttributeIndex(attr) != UINT32_MAX;
}
-bool
-DWARFAttributes::RemoveAttribute(dw_attr_t attr)
-{
- uint32_t attr_index = FindAttributeIndex(attr);
- if (attr_index != UINT32_MAX)
- {
- m_infos.erase(m_infos.begin() + attr_index);
- return true;
- }
- return false;
+bool DWARFAttributes::RemoveAttribute(dw_attr_t attr) {
+ uint32_t attr_index = FindAttributeIndex(attr);
+ if (attr_index != UINT32_MAX) {
+ m_infos.erase(m_infos.begin() + attr_index);
+ return true;
+ }
+ return false;
}
-bool
-DWARFAttributes::ExtractFormValueAtIndex (uint32_t i, DWARFFormValue &form_value) const
-{
- const DWARFCompileUnit *cu = CompileUnitAtIndex(i);
- form_value.SetCompileUnit(cu);
- form_value.SetForm(FormAtIndex(i));
- lldb::offset_t offset = DIEOffsetAtIndex(i);
- return form_value.ExtractValue(cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset);
+bool DWARFAttributes::ExtractFormValueAtIndex(
+ uint32_t i, DWARFFormValue &form_value) const {
+ const DWARFCompileUnit *cu = CompileUnitAtIndex(i);
+ form_value.SetCompileUnit(cu);
+ form_value.SetForm(FormAtIndex(i));
+ lldb::offset_t offset = DIEOffsetAtIndex(i);
+ return form_value.ExtractValue(
+ cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset);
}
-uint64_t
-DWARFAttributes::FormValueAsUnsigned (dw_attr_t attr, uint64_t fail_value) const
-{
- const uint32_t attr_idx = FindAttributeIndex (attr);
- if (attr_idx != UINT32_MAX)
- return FormValueAsUnsignedAtIndex (attr_idx, fail_value);
- return fail_value;
+uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
+ uint64_t fail_value) const {
+ const uint32_t attr_idx = FindAttributeIndex(attr);
+ if (attr_idx != UINT32_MAX)
+ return FormValueAsUnsignedAtIndex(attr_idx, fail_value);
+ return fail_value;
}
uint64_t
-DWARFAttributes::FormValueAsUnsignedAtIndex(uint32_t i, uint64_t fail_value) const
-{
- DWARFFormValue form_value;
- if (ExtractFormValueAtIndex(i, form_value))
- return form_value.Reference();
- return fail_value;
+DWARFAttributes::FormValueAsUnsignedAtIndex(uint32_t i,
+ uint64_t fail_value) const {
+ DWARFFormValue form_value;
+ if (ExtractFormValueAtIndex(i, form_value))
+ return form_value.Reference();
+ return fail_value;
}
-
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index f5ca9cce525e..317e710e6d94 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -10,72 +10,76 @@
#ifndef SymbolFileDWARF_DWARFAttribute_h_
#define SymbolFileDWARF_DWARFAttribute_h_
-#include "llvm/ADT/SmallVector.h"
#include "DWARFDefines.h"
+#include "llvm/ADT/SmallVector.h"
#include <vector>
class DWARFCompileUnit;
class DWARFFormValue;
-class DWARFAttribute
-{
+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) : m_attr(attr), m_form(form) {}
- void set (dw_attr_t attr, dw_form_t form) { m_attr = attr; m_form = form; }
- void set_attr (dw_attr_t attr) { m_attr = attr; }
- 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
- {
- attr = m_attr;
- form = m_form;
- }
- bool operator == (const DWARFAttribute& rhs) const { return m_attr == rhs.m_attr && m_form == rhs.m_form; }
- typedef std::vector<DWARFAttribute> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
+ void set(dw_attr_t attr, dw_form_t form) {
+ m_attr = attr;
+ m_form = form;
+ }
+ void set_attr(dw_attr_t attr) { m_attr = attr; }
+ 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 {
+ attr = m_attr;
+ form = m_form;
+ }
+ bool operator==(const DWARFAttribute &rhs) const {
+ return m_attr == rhs.m_attr && m_form == rhs.m_form;
+ }
+ typedef std::vector<DWARFAttribute> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
protected:
- dw_attr_t m_attr;
- dw_form_t m_form;
+ dw_attr_t m_attr;
+ dw_form_t m_form;
};
-
-class DWARFAttributes
-{
+class DWARFAttributes {
public:
- DWARFAttributes();
- ~DWARFAttributes();
+ DWARFAttributes();
+ ~DWARFAttributes();
- void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form);
- const DWARFCompileUnit * CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; }
- dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; }
- dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr.get_attr(); }
- dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); }
- bool ExtractFormValueAtIndex (uint32_t i, DWARFFormValue &form_value) const;
- uint64_t FormValueAsUnsignedAtIndex (uint32_t i, uint64_t fail_value) const;
- uint64_t FormValueAsUnsigned (dw_attr_t attr, uint64_t fail_value) const;
- uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool ContainsAttribute(dw_attr_t attr) const;
- bool RemoveAttribute(dw_attr_t attr);
- void Clear() { m_infos.clear(); }
- size_t Size() const { return m_infos.size(); }
+ void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset,
+ dw_attr_t attr, dw_form_t form);
+ const DWARFCompileUnit *CompileUnitAtIndex(uint32_t i) const {
+ return m_infos[i].cu;
+ }
+ dw_offset_t DIEOffsetAtIndex(uint32_t i) const {
+ return m_infos[i].die_offset;
+ }
+ dw_attr_t AttributeAtIndex(uint32_t i) const {
+ return m_infos[i].attr.get_attr();
+ }
+ dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); }
+ bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const;
+ uint64_t FormValueAsUnsignedAtIndex(uint32_t i, uint64_t fail_value) const;
+ uint64_t FormValueAsUnsigned(dw_attr_t attr, uint64_t fail_value) const;
+ uint32_t FindAttributeIndex(dw_attr_t attr) const;
+ bool ContainsAttribute(dw_attr_t attr) const;
+ bool RemoveAttribute(dw_attr_t attr);
+ void Clear() { m_infos.clear(); }
+ size_t Size() const { return m_infos.size(); }
protected:
- struct AttributeValue
- {
- const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in case we have DW_FORM_ref_addr values
- dw_offset_t die_offset;
- DWARFAttribute attr;
- };
- typedef llvm::SmallVector<AttributeValue, 8> collection;
- collection m_infos;
+ struct AttributeValue {
+ const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in
+ // case we have DW_FORM_ref_addr values
+ dw_offset_t die_offset;
+ DWARFAttribute attr;
+ };
+ typedef llvm::SmallVector<AttributeValue, 8> collection;
+ collection m_infos;
};
-#endif // SymbolFileDWARF_DWARFAttribute_h_
+#endif // SymbolFileDWARF_DWARFAttribute_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index c5d7568b5272..6d3ff8e35910 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -9,6 +9,7 @@
#include "DWARFCompileUnit.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
@@ -18,130 +19,108 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
-#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
#include "LogChannelDWARF.h"
#include "NameToDIE.h"
#include "SymbolFileDWARF.h"
-#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDebugMap.h"
+#include "SymbolFileDWARFDwo.h"
using namespace lldb;
using namespace lldb_private;
using namespace std;
-
extern int g_verbose;
-DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) :
- m_dwarf2Data (dwarf2Data),
- m_abbrevs (NULL),
- m_user_data (NULL),
- m_die_array (),
- m_func_aranges_ap (),
- m_base_addr (0),
- m_offset (DW_INVALID_OFFSET),
- m_length (0),
- m_version (0),
- m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()),
- m_producer (eProducerInvalid),
- m_producer_version_major (0),
- m_producer_version_minor (0),
- m_producer_version_update (0),
- m_language_type (eLanguageTypeUnknown),
- m_is_dwarf64 (false),
- m_is_optimized (eLazyBoolCalculate),
- m_addr_base (0),
- m_base_obj_offset (DW_INVALID_OFFSET)
-{
+DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
+ : m_dwarf2Data(dwarf2Data), m_abbrevs(NULL), m_user_data(NULL),
+ m_die_array(), m_func_aranges_ap(), m_base_addr(0),
+ m_offset(DW_INVALID_OFFSET), m_length(0), m_version(0),
+ m_addr_size(DWARFCompileUnit::GetDefaultAddressSize()),
+ m_producer(eProducerInvalid), m_producer_version_major(0),
+ m_producer_version_minor(0), m_producer_version_update(0),
+ m_language_type(eLanguageTypeUnknown), m_is_dwarf64(false),
+ m_is_optimized(eLazyBoolCalculate), m_addr_base(0),
+ m_ranges_base(0), m_base_obj_offset(DW_INVALID_OFFSET) {}
+
+DWARFCompileUnit::~DWARFCompileUnit() {}
+
+void DWARFCompileUnit::Clear() {
+ m_offset = DW_INVALID_OFFSET;
+ m_length = 0;
+ m_version = 0;
+ m_abbrevs = NULL;
+ m_addr_size = DWARFCompileUnit::GetDefaultAddressSize();
+ m_base_addr = 0;
+ m_die_array.clear();
+ m_func_aranges_ap.reset();
+ m_user_data = NULL;
+ m_producer = eProducerInvalid;
+ m_language_type = eLanguageTypeUnknown;
+ m_is_dwarf64 = false;
+ m_is_optimized = eLazyBoolCalculate;
+ m_addr_base = 0;
+ m_base_obj_offset = DW_INVALID_OFFSET;
}
-DWARFCompileUnit::~DWARFCompileUnit()
-{}
-
-void
-DWARFCompileUnit::Clear()
-{
- m_offset = DW_INVALID_OFFSET;
- m_length = 0;
- m_version = 0;
- m_abbrevs = NULL;
- m_addr_size = DWARFCompileUnit::GetDefaultAddressSize();
- m_base_addr = 0;
- m_die_array.clear();
- m_func_aranges_ap.reset();
- m_user_data = NULL;
- m_producer = eProducerInvalid;
- m_language_type = eLanguageTypeUnknown;
- m_is_dwarf64 = false;
- m_is_optimized = eLazyBoolCalculate;
- m_addr_base = 0;
- m_base_obj_offset = DW_INVALID_OFFSET;
-}
+bool DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info,
+ lldb::offset_t *offset_ptr) {
+ Clear();
-bool
-DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr)
-{
- Clear();
-
- m_offset = *offset_ptr;
-
- if (debug_info.ValidOffset(*offset_ptr))
- {
- dw_offset_t abbr_offset;
- const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev();
- m_length = debug_info.GetDWARFInitialLength(offset_ptr);
- m_is_dwarf64 = debug_info.IsDWARF64();
- m_version = debug_info.GetU16(offset_ptr);
- abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
- m_addr_size = debug_info.GetU8 (offset_ptr);
-
- bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1);
- bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
- bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
- bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
-
- if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL)
- {
- m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
- return true;
- }
+ m_offset = *offset_ptr;
- // reset the offset to where we tried to parse from if anything went wrong
- *offset_ptr = m_offset;
- }
-
- return false;
-}
+ if (debug_info.ValidOffset(*offset_ptr)) {
+ dw_offset_t abbr_offset;
+ const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev();
+ m_length = debug_info.GetDWARFInitialLength(offset_ptr);
+ m_is_dwarf64 = debug_info.IsDWARF64();
+ m_version = debug_info.GetU16(offset_ptr);
+ abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
+ m_addr_size = debug_info.GetU8(offset_ptr);
+ bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1);
+ bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+ bool abbr_offset_OK =
+ m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
+ bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
-void
-DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die)
-{
- if (m_die_array.size() > 1)
- {
- // std::vectors never get any smaller when resized to a smaller size,
- // or when clear() or erase() are called, the size will report that it
- // is smaller, but the memory allocated remains intact (call capacity()
- // to see this). So we need to create a temporary vector and swap the
- // contents which will cause just the internal pointers to be swapped
- // so that when "tmp_array" goes out of scope, it will destroy the
- // contents.
-
- // Save at least the compile unit DIE
- DWARFDebugInfoEntry::collection tmp_array;
- m_die_array.swap(tmp_array);
- if (keep_compile_unit_die)
- m_die_array.push_back(tmp_array.front());
+ if (length_OK && version_OK && addr_size_OK && abbr_offset_OK &&
+ abbr != NULL) {
+ m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
+ return true;
}
- if (m_dwo_symbol_file)
- m_dwo_symbol_file->GetCompileUnit()->ClearDIEs(keep_compile_unit_die);
+ // reset the offset to where we tried to parse from if anything went wrong
+ *offset_ptr = m_offset;
+ }
+
+ return false;
+}
+
+void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) {
+ if (m_die_array.size() > 1) {
+ // std::vectors never get any smaller when resized to a smaller size,
+ // or when clear() or erase() are called, the size will report that it
+ // is smaller, but the memory allocated remains intact (call capacity()
+ // to see this). So we need to create a temporary vector and swap the
+ // contents which will cause just the internal pointers to be swapped
+ // so that when "tmp_array" goes out of scope, it will destroy the
+ // contents.
+
+ // Save at least the compile unit DIE
+ DWARFDebugInfoEntry::collection tmp_array;
+ m_die_array.swap(tmp_array);
+ if (keep_compile_unit_die)
+ m_die_array.push_back(tmp_array.front());
+ }
+
+ if (m_dwo_symbol_file)
+ m_dwo_symbol_file->GetCompileUnit()->ClearDIEs(keep_compile_unit_die);
}
//----------------------------------------------------------------------
@@ -150,454 +129,422 @@ DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die)
// Parses a compile unit and indexes its DIEs if it hasn't already been
// done.
//----------------------------------------------------------------------
-size_t
-DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only)
-{
- const size_t initial_die_array_size = m_die_array.size();
- if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1)
- return 0; // Already parsed
-
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )",
- m_offset,
- cu_die_only);
-
- // Set the offset to that of the first DIE and calculate the start of the
- // next compilation unit header.
- lldb::offset_t offset = GetFirstDIEOffset();
- lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
-
- DWARFDebugInfoEntry die;
- // Keep a flat array of the DIE for binary lookup by DIE offset
- if (!cu_die_only)
- {
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
- if (log)
- {
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
- "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at .debug_info[0x%8.8x]",
- GetOffset());
- }
+size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
+ const size_t initial_die_array_size = m_die_array.size();
+ if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1)
+ return 0; // Already parsed
+
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )",
+ m_offset, cu_die_only);
+
+ // Set the offset to that of the first DIE and calculate the start of the
+ // next compilation unit header.
+ lldb::offset_t offset = GetFirstDIEOffset();
+ lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
+
+ DWARFDebugInfoEntry die;
+ // Keep a flat array of the DIE for binary lookup by DIE offset
+ if (!cu_die_only) {
+ Log *log(
+ LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS));
+ if (log) {
+ m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
+ log, "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at "
+ ".debug_info[0x%8.8x]",
+ GetOffset());
}
-
- uint32_t depth = 0;
- // We are in our compile unit, parse starting at the offset
- // we were told to parse
- const DWARFDataExtractor& debug_info_data = m_dwarf2Data->get_debug_info_data();
- std::vector<uint32_t> die_index_stack;
- die_index_stack.reserve(32);
- die_index_stack.push_back(0);
- bool prev_die_had_children = false;
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
- while (offset < next_cu_offset &&
- die.FastExtract (debug_info_data, this, fixed_form_sizes, &offset))
- {
-// if (log)
-// log->Printf("0x%8.8x: %*.*s%s%s",
-// die.GetOffset(),
-// depth * 2, depth * 2, "",
-// DW_TAG_value_to_name (die.Tag()),
-// die.HasChildren() ? " *" : "");
-
- const bool null_die = die.IsNULL();
- if (depth == 0)
- {
- if (initial_die_array_size == 0)
- AddCompileUnitDIE(die);
- uint64_t base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (base_addr == LLDB_INVALID_ADDRESS)
- base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_entry_pc, 0);
- SetBaseAddress (base_addr);
- if (cu_die_only)
- return 1;
- }
- else
- {
- if (null_die)
- {
- if (prev_die_had_children)
- {
- // This will only happen if a DIE says is has children
- // but all it contains is a NULL tag. Since we are removing
- // the NULL DIEs from the list (saves up to 25% in C++ code),
- // we need a way to let the DIE know that it actually doesn't
- // have children.
- if (!m_die_array.empty())
- m_die_array.back().SetEmptyChildren(true);
- }
- }
- else
- {
- die.SetParentIndex(m_die_array.size() - die_index_stack[depth-1]);
-
- if (die_index_stack.back())
- m_die_array[die_index_stack.back()].SetSiblingIndex(m_die_array.size()-die_index_stack.back());
-
- // Only push the DIE if it isn't a NULL DIE
- m_die_array.push_back(die);
- }
+ }
+
+ uint32_t depth = 0;
+ // We are in our compile unit, parse starting at the offset
+ // we were told to parse
+ const DWARFDataExtractor &debug_info_data =
+ m_dwarf2Data->get_debug_info_data();
+ std::vector<uint32_t> die_index_stack;
+ die_index_stack.reserve(32);
+ die_index_stack.push_back(0);
+ bool prev_die_had_children = false;
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+ m_is_dwarf64);
+ while (offset < next_cu_offset &&
+ die.FastExtract(debug_info_data, this, fixed_form_sizes, &offset)) {
+ // if (log)
+ // log->Printf("0x%8.8x: %*.*s%s%s",
+ // die.GetOffset(),
+ // depth * 2, depth * 2, "",
+ // DW_TAG_value_to_name (die.Tag()),
+ // die.HasChildren() ? " *" : "");
+
+ const bool null_die = die.IsNULL();
+ if (depth == 0) {
+ if (initial_die_array_size == 0)
+ AddCompileUnitDIE(die);
+ uint64_t base_addr = die.GetAttributeValueAsAddress(
+ m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (base_addr == LLDB_INVALID_ADDRESS)
+ base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this,
+ DW_AT_entry_pc, 0);
+ SetBaseAddress(base_addr);
+ if (cu_die_only)
+ return 1;
+ } else {
+ if (null_die) {
+ if (prev_die_had_children) {
+ // This will only happen if a DIE says is has children
+ // but all it contains is a NULL tag. Since we are removing
+ // the NULL DIEs from the list (saves up to 25% in C++ code),
+ // we need a way to let the DIE know that it actually doesn't
+ // have children.
+ if (!m_die_array.empty())
+ m_die_array.back().SetEmptyChildren(true);
}
+ } else {
+ die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]);
- if (null_die)
- {
- // NULL DIE.
- if (!die_index_stack.empty())
- die_index_stack.pop_back();
-
- if (depth > 0)
- --depth;
- if (depth == 0)
- break; // We are done with this compile unit!
-
- prev_die_had_children = false;
- }
- else
- {
- die_index_stack.back() = m_die_array.size() - 1;
- // Normal DIE
- const bool die_has_children = die.HasChildren();
- if (die_has_children)
- {
- die_index_stack.push_back(0);
- ++depth;
- }
- prev_die_had_children = die_has_children;
- }
- }
+ if (die_index_stack.back())
+ m_die_array[die_index_stack.back()].SetSiblingIndex(
+ m_die_array.size() - die_index_stack.back());
- // Give a little bit of info if we encounter corrupt DWARF (our offset
- // should always terminate at or before the start of the next compilation
- // unit header).
- if (offset > next_cu_offset)
- {
- m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8" PRIx64 "\n",
- GetOffset(),
- offset);
+ // Only push the DIE if it isn't a NULL DIE
+ m_die_array.push_back(die);
+ }
}
- // Since std::vector objects will double their size, we really need to
- // make a new array with the perfect size so we don't end up wasting
- // space. So here we copy and swap to make sure we don't have any extra
- // memory taken up.
-
- if (m_die_array.size () < m_die_array.capacity())
- {
- DWARFDebugInfoEntry::collection exact_size_die_array (m_die_array.begin(), m_die_array.end());
- exact_size_die_array.swap (m_die_array);
- }
- Log *verbose_log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE));
- if (verbose_log)
- {
- StreamString strm;
- Dump(&strm);
- if (m_die_array.empty())
- strm.Printf("error: no DIE for compile unit");
- else
- m_die_array[0].Dump(m_dwarf2Data, this, strm, UINT32_MAX);
- verbose_log->PutCString (strm.GetString().c_str());
+ if (null_die) {
+ // NULL DIE.
+ if (!die_index_stack.empty())
+ die_index_stack.pop_back();
+
+ if (depth > 0)
+ --depth;
+ if (depth == 0)
+ break; // We are done with this compile unit!
+
+ prev_die_had_children = false;
+ } else {
+ die_index_stack.back() = m_die_array.size() - 1;
+ // Normal DIE
+ const bool die_has_children = die.HasChildren();
+ if (die_has_children) {
+ die_index_stack.push_back(0);
+ ++depth;
+ }
+ prev_die_had_children = die_has_children;
}
+ }
+
+ // Give a little bit of info if we encounter corrupt DWARF (our offset
+ // should always terminate at or before the start of the next compilation
+ // unit header).
+ if (offset > next_cu_offset) {
+ m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning(
+ "DWARF compile unit extends beyond its bounds cu 0x%8.8x at "
+ "0x%8.8" PRIx64 "\n",
+ GetOffset(), offset);
+ }
+
+ // Since std::vector objects will double their size, we really need to
+ // make a new array with the perfect size so we don't end up wasting
+ // space. So here we copy and swap to make sure we don't have any extra
+ // memory taken up.
+
+ if (m_die_array.size() < m_die_array.capacity()) {
+ DWARFDebugInfoEntry::collection exact_size_die_array(m_die_array.begin(),
+ m_die_array.end());
+ exact_size_die_array.swap(m_die_array);
+ }
+ Log *verbose_log(
+ LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE));
+ if (verbose_log) {
+ StreamString strm;
+ Dump(&strm);
+ if (m_die_array.empty())
+ strm.Printf("error: no DIE for compile unit");
+ else
+ m_die_array[0].Dump(m_dwarf2Data, this, strm, UINT32_MAX);
+ verbose_log->PutString(strm.GetString());
+ }
- if (!m_dwo_symbol_file)
- return m_die_array.size();
+ if (!m_dwo_symbol_file)
+ return m_die_array.size();
- DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit();
- size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only);
- return m_die_array.size() + dwo_die_count - 1; // We have 2 CU die, but we waht to count it only as one
+ DWARFCompileUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
+ size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only);
+ return m_die_array.size() + dwo_die_count -
+ 1; // We have 2 CU die, but we want to count it only as one
}
-void
-DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry& die)
-{
- assert (m_die_array.empty() && "Compile unit DIE already added");
- AddDIE(die);
-
- const DWARFDebugInfoEntry &cu_die = m_die_array.front();
- std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file = m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die);
- if (!dwo_symbol_file)
- return;
-
- DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit();
- if (!dwo_cu)
- return; // Can't fetch the compile unit from the dwo file.
-
- DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
- if (!dwo_cu_die.IsValid())
- return; // Can't fetch the compile unit DIE from the dwo file.
-
- uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data,
- this,
- DW_AT_GNU_dwo_id,
- 0);
- uint64_t sub_dwo_id = dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
- if (main_dwo_id != sub_dwo_id)
- return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to a differectn compilation.
-
- m_dwo_symbol_file = std::move(dwo_symbol_file);
-
- dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data,
- this,
- DW_AT_GNU_addr_base,
- 0);
- dwo_cu->SetAddrBase(addr_base, m_offset);
+void DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry &die) {
+ assert(m_die_array.empty() && "Compile unit DIE already added");
+ AddDIE(die);
+
+ const DWARFDebugInfoEntry &cu_die = m_die_array.front();
+ std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
+ m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die);
+ if (!dwo_symbol_file)
+ return;
+
+ DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
+ if (!dwo_cu)
+ return; // Can't fetch the compile unit from the dwo file.
+
+ DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
+ if (!dwo_cu_die.IsValid())
+ return; // Can't fetch the compile unit DIE from the dwo file.
+
+ uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned(
+ m_dwarf2Data, this, DW_AT_GNU_dwo_id, 0);
+ uint64_t sub_dwo_id =
+ dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
+ if (main_dwo_id != sub_dwo_id)
+ return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to
+ // a differectn compilation.
+
+ m_dwo_symbol_file = std::move(dwo_symbol_file);
+
+ dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(
+ m_dwarf2Data, this, DW_AT_GNU_addr_base, 0);
+ dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
+ m_dwarf2Data, this, DW_AT_GNU_ranges_base, 0);
+ dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset);
}
-dw_offset_t
-DWARFCompileUnit::GetAbbrevOffset() const
-{
- return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
+dw_offset_t DWARFCompileUnit::GetAbbrevOffset() const {
+ return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
}
-
-
-bool
-DWARFCompileUnit::Verify(Stream *s) const
-{
- const DWARFDataExtractor& debug_info = m_dwarf2Data->get_debug_info_data();
- bool valid_offset = debug_info.ValidOffset(m_offset);
- bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1);
- bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
- bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset());
- bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
- bool verbose = s->GetVerbose();
- if (valid_offset && length_OK && version_OK && addr_size_OK && abbr_offset_OK)
- {
- if (verbose)
- s->Printf(" 0x%8.8x: OK\n", m_offset);
- return true;
- }
- else
- {
- s->Printf(" 0x%8.8x: ", m_offset);
-
- m_dwarf2Data->get_debug_info_data().Dump (s, m_offset, lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0, 0);
- s->EOL();
- if (valid_offset)
- {
- if (!length_OK)
- s->Printf(" The length (0x%8.8x) for this compile unit is too large for the .debug_info provided.\n", m_length);
- if (!version_OK)
- s->Printf(" The 16 bit compile unit header version is not supported.\n");
- if (!abbr_offset_OK)
- s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) is not valid.\n", GetAbbrevOffset());
- if (!addr_size_OK)
- s->Printf(" The address size is unsupported: 0x%2.2x\n", m_addr_size);
- }
- else
- s->Printf(" The start offset of the compile unit header in the .debug_info is invalid.\n");
- }
- return false;
+bool DWARFCompileUnit::Verify(Stream *s) const {
+ const DWARFDataExtractor &debug_info = m_dwarf2Data->get_debug_info_data();
+ bool valid_offset = debug_info.ValidOffset(m_offset);
+ bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1);
+ bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+ bool abbr_offset_OK =
+ m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset());
+ bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
+ bool verbose = s->GetVerbose();
+ if (valid_offset && length_OK && version_OK && addr_size_OK &&
+ abbr_offset_OK) {
+ if (verbose)
+ s->Printf(" 0x%8.8x: OK\n", m_offset);
+ return true;
+ } else {
+ s->Printf(" 0x%8.8x: ", m_offset);
+
+ m_dwarf2Data->get_debug_info_data().Dump(s, m_offset, lldb::eFormatHex, 1,
+ Size(), 32, LLDB_INVALID_ADDRESS,
+ 0, 0);
+ s->EOL();
+ if (valid_offset) {
+ if (!length_OK)
+ s->Printf(" The length (0x%8.8x) for this compile unit is too "
+ "large for the .debug_info provided.\n",
+ m_length);
+ if (!version_OK)
+ s->Printf(" The 16 bit compile unit header version is not "
+ "supported.\n");
+ if (!abbr_offset_OK)
+ s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) "
+ "is not valid.\n",
+ GetAbbrevOffset());
+ if (!addr_size_OK)
+ s->Printf(" The address size is unsupported: 0x%2.2x\n",
+ m_addr_size);
+ } else
+ s->Printf(" The start offset of the compile unit header in the "
+ ".debug_info is invalid.\n");
+ }
+ return false;
}
-
-void
-DWARFCompileUnit::Dump(Stream *s) const
-{
- s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at {0x%8.8x})\n",
- m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset());
+void DWARFCompileUnit::Dump(Stream *s) const {
+ s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, "
+ "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
+ "{0x%8.8x})\n",
+ m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size,
+ GetNextCompileUnitOffset());
}
-
static uint8_t g_default_addr_size = 4;
-uint8_t
-DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu)
-{
- if (cu)
- return cu->GetAddressByteSize();
- return DWARFCompileUnit::GetDefaultAddressSize();
+uint8_t DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit *cu) {
+ if (cu)
+ return cu->GetAddressByteSize();
+ return DWARFCompileUnit::GetDefaultAddressSize();
}
-bool
-DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit* cu)
-{
- if (cu)
- return cu->IsDWARF64();
- return false;
+bool DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit *cu) {
+ if (cu)
+ return cu->IsDWARF64();
+ return false;
}
-uint8_t
-DWARFCompileUnit::GetDefaultAddressSize()
-{
- return g_default_addr_size;
+uint8_t DWARFCompileUnit::GetDefaultAddressSize() {
+ return g_default_addr_size;
}
-void
-DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size)
-{
- g_default_addr_size = addr_size;
+void DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) {
+ g_default_addr_size = addr_size;
}
-lldb::user_id_t
-DWARFCompileUnit::GetID () const
-{
- dw_offset_t local_id = m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
- if (m_dwarf2Data)
- return DIERef(local_id, local_id).GetUID(m_dwarf2Data);
- else
- return local_id;
+lldb::user_id_t DWARFCompileUnit::GetID() const {
+ dw_offset_t local_id =
+ m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
+ if (m_dwarf2Data)
+ return DIERef(local_id, local_id).GetUID(m_dwarf2Data);
+ else
+ return local_id;
}
-void
-DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
- DWARFDebugAranges* debug_aranges)
-{
- // This function is usually called if there in no .debug_aranges section
- // in order to produce a compile unit level set of address ranges that
- // is accurate.
-
- size_t num_debug_aranges = debug_aranges->GetNumRanges();
-
- // First get the compile unit DIE only and check if it has a DW_AT_ranges
- const DWARFDebugInfoEntry* die = GetCompileUnitDIEPtrOnly();
-
- const dw_offset_t cu_offset = GetOffset();
- if (die)
- {
- DWARFRangeList ranges;
- const size_t num_ranges = die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false);
- if (num_ranges > 0)
- {
- // This compile unit has DW_AT_ranges, assume this is correct if it
- // is present since clang no longer makes .debug_aranges by default
- // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does
- // this with recent GCC builds.
- for (size_t i=0; i<num_ranges; ++i)
- {
- const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
- debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd());
- }
-
- return; // We got all of our ranges from the DW_AT_ranges attribute
- }
+void DWARFCompileUnit::BuildAddressRangeTable(
+ SymbolFileDWARF *dwarf2Data, DWARFDebugAranges *debug_aranges) {
+ // This function is usually called if there in no .debug_aranges section
+ // in order to produce a compile unit level set of address ranges that
+ // is accurate.
+
+ size_t num_debug_aranges = debug_aranges->GetNumRanges();
+
+ // First get the compile unit DIE only and check if it has a DW_AT_ranges
+ const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
+
+ const dw_offset_t cu_offset = GetOffset();
+ if (die) {
+ DWARFRangeList ranges;
+ const size_t num_ranges =
+ die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false);
+ if (num_ranges > 0) {
+ // This compile unit has DW_AT_ranges, assume this is correct if it
+ // is present since clang no longer makes .debug_aranges by default
+ // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does
+ // this with recent GCC builds.
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
+ debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
+
+ return; // We got all of our ranges from the DW_AT_ranges attribute
}
- // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
-
- // If the DIEs weren't parsed, then we don't want all dies for all compile units
- // to stay loaded when they weren't needed. So we can end up parsing the DWARF
- // and then throwing them all away to keep memory usage down.
- const bool clear_dies = ExtractDIEsIfNeeded (false) > 1;
-
- die = DIEPtr();
- if (die)
- die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
-
- if (debug_aranges->GetNumRanges() == num_debug_aranges)
- {
- // We got nothing from the functions, maybe we have a line tables only
- // situation. Check the line tables and build the arange table from this.
- SymbolContext sc;
- sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
- if (sc.comp_unit)
- {
- SymbolFileDWARFDebugMap *debug_map_sym_file = m_dwarf2Data->GetDebugMapSymfile();
- if (debug_map_sym_file == NULL)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table)
- {
- LineTable::FileAddressRanges file_ranges;
- const bool append = true;
- const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append);
- for (uint32_t idx=0; idx<num_ranges; ++idx)
- {
- const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx);
- debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd());
- }
- }
- }
- else
- debug_map_sym_file->AddOSOARanges(dwarf2Data,debug_aranges);
+ }
+ // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
+
+ // If the DIEs weren't parsed, then we don't want all dies for all compile
+ // units
+ // to stay loaded when they weren't needed. So we can end up parsing the DWARF
+ // and then throwing them all away to keep memory usage down.
+ const bool clear_dies = ExtractDIEsIfNeeded(false) > 1;
+
+ die = DIEPtr();
+ if (die)
+ die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
+
+ if (debug_aranges->GetNumRanges() == num_debug_aranges) {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
+ if (sc.comp_unit) {
+ SymbolFileDWARFDebugMap *debug_map_sym_file =
+ m_dwarf2Data->GetDebugMapSymfile();
+ if (debug_map_sym_file == NULL) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table) {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges =
+ line_table->GetContiguousFileAddressRanges(file_ranges, append);
+ for (uint32_t idx = 0; idx < num_ranges; ++idx) {
+ const LineTable::FileAddressRanges::Entry &range =
+ file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
+ range.GetRangeEnd());
+ }
}
+ } else
+ debug_map_sym_file->AddOSOARanges(dwarf2Data, debug_aranges);
}
-
- if (debug_aranges->GetNumRanges() == num_debug_aranges)
- {
- // We got nothing from the functions, maybe we have a line tables only
- // situation. Check the line tables and build the arange table from this.
- SymbolContext sc;
- sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
- if (sc.comp_unit)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table)
- {
- LineTable::FileAddressRanges file_ranges;
- const bool append = true;
- const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append);
- for (uint32_t idx=0; idx<num_ranges; ++idx)
- {
- const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx);
- debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
- }
- }
+ }
+
+ if (debug_aranges->GetNumRanges() == num_debug_aranges) {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
+ if (sc.comp_unit) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table) {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges =
+ line_table->GetContiguousFileAddressRanges(file_ranges, append);
+ for (uint32_t idx = 0; idx < num_ranges; ++idx) {
+ const LineTable::FileAddressRanges::Entry &range =
+ file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
+ range.GetRangeEnd());
}
+ }
}
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- ClearDIEs (true);
+ }
+ // Keep memory down by clearing DIEs if this generate function
+ // caused them to be parsed
+ if (clear_dies)
+ ClearDIEs(true);
}
+const DWARFDebugAranges &DWARFCompileUnit::GetFunctionAranges() {
+ if (m_func_aranges_ap.get() == NULL) {
+ m_func_aranges_ap.reset(new DWARFDebugAranges());
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-const DWARFDebugAranges &
-DWARFCompileUnit::GetFunctionAranges ()
-{
- if (m_func_aranges_ap.get() == NULL)
- {
- m_func_aranges_ap.reset (new DWARFDebugAranges());
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-
- if (log)
- {
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log,
- "DWARFCompileUnit::GetFunctionAranges() for compile unit at .debug_info[0x%8.8x]",
- GetOffset());
- }
- const DWARFDebugInfoEntry* die = DIEPtr();
- if (die)
- die->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get());
-
- if (m_dwo_symbol_file)
- {
- DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit();
- const DWARFDebugInfoEntry* dwo_die = dwo_cu->DIEPtr();
- if (dwo_die)
- dwo_die->BuildFunctionAddressRangeTable (m_dwo_symbol_file.get(),
- dwo_cu,
- m_func_aranges_ap.get());
- }
-
- const bool minimize = false;
- m_func_aranges_ap->Sort(minimize);
+ if (log) {
+ m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage(
+ log, "DWARFCompileUnit::GetFunctionAranges() for compile unit at "
+ ".debug_info[0x%8.8x]",
+ GetOffset());
+ }
+ const DWARFDebugInfoEntry *die = DIEPtr();
+ if (die)
+ die->BuildFunctionAddressRangeTable(m_dwarf2Data, this,
+ m_func_aranges_ap.get());
+
+ if (m_dwo_symbol_file) {
+ DWARFCompileUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
+ const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr();
+ if (dwo_die)
+ dwo_die->BuildFunctionAddressRangeTable(m_dwo_symbol_file.get(), dwo_cu,
+ m_func_aranges_ap.get());
}
- return *m_func_aranges_ap.get();
+
+ const bool minimize = false;
+ m_func_aranges_ap->Sort(minimize);
+ }
+ return *m_func_aranges_ap.get();
}
DWARFDIE
-DWARFCompileUnit::LookupAddress (const dw_addr_t address)
-{
- if (DIE())
- {
- const DWARFDebugAranges &func_aranges = GetFunctionAranges ();
-
- // Re-check the aranges auto pointer contents in case it was created above
- if (!func_aranges.IsEmpty())
- return GetDIE(func_aranges.FindAddress(address));
- }
- return DWARFDIE();
+DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
+ if (DIE()) {
+ const DWARFDebugAranges &func_aranges = GetFunctionAranges();
+
+ // Re-check the aranges auto pointer contents in case it was created above
+ if (!func_aranges.IsEmpty())
+ return GetDIE(func_aranges.FindAddress(address));
+ }
+ return DWARFDIE();
}
//----------------------------------------------------------------------
// Compare function DWARFDebugAranges::Range structures
//----------------------------------------------------------------------
-static bool CompareDIEOffset (const DWARFDebugInfoEntry& die, const dw_offset_t die_offset)
-{
- return die.GetOffset() < die_offset;
+static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
+ const dw_offset_t die_offset) {
+ return die.GetOffset() < die_offset;
}
//----------------------------------------------------------------------
@@ -609,627 +556,575 @@ static bool CompareDIEOffset (const DWARFDebugInfoEntry& die, const dw_offset_t
// from the DWARF file.
//----------------------------------------------------------------------
DWARFDIE
-DWARFCompileUnit::GetDIE (dw_offset_t die_offset)
-{
- if (die_offset != DW_INVALID_OFFSET)
- {
- if (m_dwo_symbol_file)
- return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset);
-
- if (ContainsDIEOffset(die_offset))
- {
- ExtractDIEsIfNeeded (false);
- DWARFDebugInfoEntry::iterator end = m_die_array.end();
- DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset);
- if (pos != end)
- {
- if (die_offset == (*pos).GetOffset())
- return DWARFDIE(this, &(*pos));
- }
- }
- else
- {
- // Don't specify the compile unit offset as we don't know it because the DIE belongs to
- // a different compile unit in the same symbol file.
- return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset);
- }
+DWARFCompileUnit::GetDIE(dw_offset_t die_offset) {
+ if (die_offset != DW_INVALID_OFFSET) {
+ if (m_dwo_symbol_file)
+ return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset);
+
+ if (ContainsDIEOffset(die_offset)) {
+ ExtractDIEsIfNeeded(false);
+ DWARFDebugInfoEntry::iterator end = m_die_array.end();
+ DWARFDebugInfoEntry::iterator pos =
+ lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset);
+ if (pos != end) {
+ if (die_offset == (*pos).GetOffset())
+ return DWARFDIE(this, &(*pos));
+ }
+ } else {
+ // Don't specify the compile unit offset as we don't know it because the
+ // DIE belongs to
+ // a different compile unit in the same symbol file.
+ return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset);
}
- return DWARFDIE(); // Not found
+ }
+ return DWARFDIE(); // Not found
}
-size_t
-DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const
-{
- size_t old_size = dies.Size();
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
- for (pos = m_die_array.begin(); pos != end; ++pos)
- {
- if (pos->Tag() == tag)
- dies.Append (DWARFDIE(this, &(*pos)));
- }
-
- // Return the number of DIEs added to the collection
- return dies.Size() - old_size;
+size_t DWARFCompileUnit::AppendDIEsWithTag(const dw_tag_t tag,
+ DWARFDIECollection &dies,
+ uint32_t depth) const {
+ size_t old_size = dies.Size();
+ DWARFDebugInfoEntry::const_iterator pos;
+ DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
+ for (pos = m_die_array.begin(); pos != end; ++pos) {
+ if (pos->Tag() == tag)
+ dies.Append(DWARFDIE(this, &(*pos)));
+ }
+
+ // Return the number of DIEs added to the collection
+ return dies.Size() - old_size;
}
-//void
-//DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx)
+// void
+// DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx)
//{
// m_global_die_indexes.push_back (die_idx);
//}
//
//
-//void
-//DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die)
+// void
+// DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die)
//{
// // Indexes to all file level global and static variables
// m_global_die_indexes;
-//
+//
// if (m_die_array.empty())
// return;
-//
+//
// const DWARFDebugInfoEntry* first_die = &m_die_array[0];
// const DWARFDebugInfoEntry* end = first_die + m_die_array.size();
// if (first_die <= die && die < end)
// m_global_die_indexes.push_back (die - first_die);
//}
+void DWARFCompileUnit::Index(NameToDIE &func_basenames,
+ NameToDIE &func_fullnames, NameToDIE &func_methods,
+ NameToDIE &func_selectors,
+ NameToDIE &objc_class_selectors,
+ NameToDIE &globals, NameToDIE &types,
+ NameToDIE &namespaces) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]",
+ GetOffset());
+ }
+
+ const LanguageType cu_language = GetLanguageType();
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+ m_is_dwarf64);
+
+ IndexPrivate(this, cu_language, fixed_form_sizes, GetOffset(), func_basenames,
+ func_fullnames, func_methods, func_selectors,
+ objc_class_selectors, globals, types, namespaces);
+
+ SymbolFileDWARFDwo *dwo_symbol_file = GetDwoSymbolFile();
+ if (dwo_symbol_file) {
+ IndexPrivate(dwo_symbol_file->GetCompileUnit(), cu_language,
+ fixed_form_sizes, GetOffset(), func_basenames, func_fullnames,
+ func_methods, func_selectors, objc_class_selectors, globals,
+ types, namespaces);
+ }
+}
-void
-DWARFCompileUnit::Index (NameToDIE& func_basenames,
- NameToDIE& func_fullnames,
- NameToDIE& func_methods,
- NameToDIE& func_selectors,
- NameToDIE& objc_class_selectors,
- NameToDIE& globals,
- NameToDIE& types,
- NameToDIE& namespaces)
-{
- Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log,
- "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]",
- GetOffset());
- }
+void DWARFCompileUnit::IndexPrivate(
+ DWARFCompileUnit *dwarf_cu, const LanguageType cu_language,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ const dw_offset_t cu_offset, NameToDIE &func_basenames,
+ NameToDIE &func_fullnames, NameToDIE &func_methods,
+ NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
+ NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) {
+ DWARFDebugInfoEntry::const_iterator pos;
+ DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin();
+ DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end();
+ for (pos = begin; pos != end; ++pos) {
+ const DWARFDebugInfoEntry &die = *pos;
+
+ const dw_tag_t tag = die.Tag();
+
+ switch (tag) {
+ case DW_TAG_array_type:
+ case DW_TAG_base_type:
+ case DW_TAG_class_type:
+ case DW_TAG_constant:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_namespace:
+ case DW_TAG_string_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ case DW_TAG_unspecified_type:
+ case DW_TAG_variable:
+ break;
- const LanguageType cu_language = GetLanguageType();
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
-
- IndexPrivate(this,
- cu_language,
- fixed_form_sizes,
- GetOffset(),
- func_basenames,
- func_fullnames,
- func_methods,
- func_selectors,
- objc_class_selectors,
- globals,
- types,
- namespaces);
-
- SymbolFileDWARFDwo* dwo_symbol_file = GetDwoSymbolFile();
- if (dwo_symbol_file)
- {
- IndexPrivate(dwo_symbol_file->GetCompileUnit(),
- cu_language,
- fixed_form_sizes,
- GetOffset(),
- func_basenames,
- func_fullnames,
- func_methods,
- func_selectors,
- objc_class_selectors,
- globals,
- types,
- namespaces);
+ default:
+ continue;
}
-}
-void
-DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
- const LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
- const dw_offset_t cu_offset,
- NameToDIE& func_basenames,
- NameToDIE& func_fullnames,
- NameToDIE& func_methods,
- NameToDIE& func_selectors,
- NameToDIE& objc_class_selectors,
- NameToDIE& globals,
- NameToDIE& types,
- NameToDIE& namespaces)
-{
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin();
- DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end();
- for (pos = begin; pos != end; ++pos)
- {
- const DWARFDebugInfoEntry &die = *pos;
-
- const dw_tag_t tag = die.Tag();
-
- switch (tag)
- {
- case DW_TAG_array_type:
- case DW_TAG_base_type:
- case DW_TAG_class_type:
- case DW_TAG_constant:
- case DW_TAG_enumeration_type:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_namespace:
- case DW_TAG_string_type:
- case DW_TAG_structure_type:
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- case DW_TAG_unspecified_type:
- case DW_TAG_variable:
- break;
-
- default:
- continue;
- }
-
- DWARFAttributes attributes;
- const char *name = NULL;
- const char *mangled_cstr = NULL;
- bool is_declaration = false;
- //bool is_artificial = false;
- bool has_address = false;
- bool has_location_or_const_value = false;
- bool is_global_or_static_variable = false;
-
- DWARFFormValue specification_die_form;
- const size_t num_attributes = die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes);
- if (num_attributes > 0)
- {
- for (uint32_t i=0; i<num_attributes; ++i)
- {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- switch (attr)
- {
- case DW_AT_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- name = form_value.AsCString();
- break;
-
- case DW_AT_declaration:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- is_declaration = form_value.Unsigned() != 0;
- break;
-
-// case DW_AT_artificial:
-// if (attributes.ExtractFormValueAtIndex(i, form_value))
-// is_artificial = form_value.Unsigned() != 0;
-// break;
-
- case DW_AT_MIPS_linkage_name:
- case DW_AT_linkage_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- mangled_cstr = form_value.AsCString();
- break;
-
- case DW_AT_low_pc:
- case DW_AT_high_pc:
- case DW_AT_ranges:
- has_address = true;
- break;
-
- case DW_AT_entry_pc:
- has_address = true;
- break;
-
- case DW_AT_location:
- case DW_AT_const_value:
- has_location_or_const_value = true;
- if (tag == DW_TAG_variable)
- {
- const DWARFDebugInfoEntry* parent_die = die.GetParent();
- while ( parent_die != NULL )
- {
- switch (parent_die->Tag())
- {
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- case DW_TAG_inlined_subroutine:
- // Even if this is a function level static, we don't add it. We could theoretically
- // add these if we wanted to by introspecting into the DW_AT_location and seeing
- // if the location describes a hard coded address, but we dont want the performance
- // penalty of that right now.
- is_global_or_static_variable = false;
-// if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
-// {
-// // If we have valid block data, then we have location expression bytes
-// // that are fixed (not a location list).
-// const uint8_t *block_data = form_value.BlockData();
-// if (block_data)
-// {
-// uint32_t block_length = form_value.Unsigned();
-// if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
-// {
-// if (block_data[0] == DW_OP_addr)
-// add_die = true;
-// }
-// }
-// }
- parent_die = NULL; // Terminate the while loop.
- break;
-
- case DW_TAG_compile_unit:
- is_global_or_static_variable = true;
- parent_die = NULL; // Terminate the while loop.
- break;
-
- default:
- parent_die = parent_die->GetParent(); // Keep going in the while loop.
- break;
- }
- }
- }
- break;
-
- case DW_AT_specification:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- specification_die_form = form_value;
- break;
- }
+ DWARFAttributes attributes;
+ const char *name = NULL;
+ const char *mangled_cstr = NULL;
+ bool is_declaration = false;
+ // bool is_artificial = false;
+ bool has_address = false;
+ bool has_location_or_const_value = false;
+ bool is_global_or_static_variable = false;
+
+ DWARFFormValue specification_die_form;
+ const size_t num_attributes =
+ die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes);
+ if (num_attributes > 0) {
+ for (uint32_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ switch (attr) {
+ case DW_AT_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_declaration:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ is_declaration = form_value.Unsigned() != 0;
+ break;
+
+ // case DW_AT_artificial:
+ // if (attributes.ExtractFormValueAtIndex(i,
+ // form_value))
+ // is_artificial = form_value.Unsigned() != 0;
+ // break;
+
+ case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ mangled_cstr = form_value.AsCString();
+ break;
+
+ case DW_AT_low_pc:
+ case DW_AT_high_pc:
+ case DW_AT_ranges:
+ has_address = true;
+ break;
+
+ case DW_AT_entry_pc:
+ has_address = true;
+ break;
+
+ case DW_AT_location:
+ case DW_AT_const_value:
+ has_location_or_const_value = true;
+ if (tag == DW_TAG_variable) {
+ const DWARFDebugInfoEntry *parent_die = die.GetParent();
+ while (parent_die != NULL) {
+ switch (parent_die->Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block:
+ case DW_TAG_inlined_subroutine:
+ // Even if this is a function level static, we don't add it. We
+ // could theoretically
+ // add these if we wanted to by introspecting into the
+ // DW_AT_location and seeing
+ // if the location describes a hard coded address, but we dont
+ // want the performance
+ // penalty of that right now.
+ is_global_or_static_variable = false;
+ // if
+ // (attributes.ExtractFormValueAtIndex(dwarf2Data,
+ // i, form_value))
+ // {
+ // // If we have valid block
+ // data, then we have location
+ // expression bytes
+ // // that are fixed (not a
+ // location list).
+ // const uint8_t *block_data =
+ // form_value.BlockData();
+ // if (block_data)
+ // {
+ // uint32_t block_length =
+ // form_value.Unsigned();
+ // if (block_length == 1 +
+ // attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
+ // {
+ // if (block_data[0] ==
+ // DW_OP_addr)
+ // add_die = true;
+ // }
+ // }
+ // }
+ parent_die = NULL; // Terminate the while loop.
+ break;
+
+ case DW_TAG_compile_unit:
+ is_global_or_static_variable = true;
+ parent_die = NULL; // Terminate the while loop.
+ break;
+
+ default:
+ parent_die =
+ parent_die->GetParent(); // Keep going in the while loop.
+ break;
+ }
}
+ }
+ break;
+
+ case DW_AT_specification:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ specification_die_form = form_value;
+ break;
}
+ }
+ }
- switch (tag)
- {
- case DW_TAG_subprogram:
- if (has_address)
- {
- if (name)
- {
- ObjCLanguage::MethodName objc_method(name, true);
- if (objc_method.IsValid(true))
- {
- ConstString objc_class_name_with_category (objc_method.GetClassNameWithCategory());
- ConstString objc_selector_name (objc_method.GetSelector());
- ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true));
- ConstString objc_class_name_no_category (objc_method.GetClassName());
- func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- if (objc_class_name_with_category)
- objc_class_selectors.Insert(objc_class_name_with_category, DIERef(cu_offset, die.GetOffset()));
- if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category)
- objc_class_selectors.Insert(objc_class_name_no_category, DIERef(cu_offset, die.GetOffset()));
- if (objc_selector_name)
- func_selectors.Insert (objc_selector_name, DIERef(cu_offset, die.GetOffset()));
- if (objc_fullname_no_category_name)
- func_fullnames.Insert (objc_fullname_no_category_name, DIERef(cu_offset, die.GetOffset()));
- }
- // If we have a mangled name, then the DW_AT_name attribute
- // is usually the method name without the class or any parameters
- const DWARFDebugInfoEntry *parent = die.GetParent();
- bool is_method = false;
- if (parent)
- {
- dw_tag_t parent_tag = parent->Tag();
- if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type)
- {
- is_method = true;
- }
- else
- {
- if (specification_die_form.IsValid())
- {
- DWARFDIE specification_die = dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE (DIERef(specification_die_form));
- if (specification_die.GetParent().IsStructOrClass())
- is_method = true;
- }
- }
- }
-
-
- if (is_method)
- func_methods.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- else
- func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
-
- if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
- func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- }
- if (mangled_cstr)
- {
- // Make sure our mangled name isn't the same string table entry
- // as our name. If it starts with '_', then it is ok, else compare
- // the string to make sure it isn't the same and we don't end up
- // with duplicate entries
- if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
- {
- Mangled mangled (ConstString(mangled_cstr), true);
- func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
- ConstString demangled = mangled.GetDemangledName(cu_language);
- if (demangled)
- func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset()));
- }
- }
+ switch (tag) {
+ case DW_TAG_subprogram:
+ if (has_address) {
+ if (name) {
+ ObjCLanguage::MethodName objc_method(name, true);
+ if (objc_method.IsValid(true)) {
+ ConstString objc_class_name_with_category(
+ objc_method.GetClassNameWithCategory());
+ ConstString objc_selector_name(objc_method.GetSelector());
+ ConstString objc_fullname_no_category_name(
+ objc_method.GetFullNameWithoutCategory(true));
+ ConstString objc_class_name_no_category(objc_method.GetClassName());
+ func_fullnames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_class_name_with_category)
+ objc_class_selectors.Insert(objc_class_name_with_category,
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_class_name_no_category &&
+ objc_class_name_no_category != objc_class_name_with_category)
+ objc_class_selectors.Insert(objc_class_name_no_category,
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_selector_name)
+ func_selectors.Insert(objc_selector_name,
+ DIERef(cu_offset, die.GetOffset()));
+ if (objc_fullname_no_category_name)
+ func_fullnames.Insert(objc_fullname_no_category_name,
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ // If we have a mangled name, then the DW_AT_name attribute
+ // is usually the method name without the class or any parameters
+ const DWARFDebugInfoEntry *parent = die.GetParent();
+ bool is_method = false;
+ if (parent) {
+ dw_tag_t parent_tag = parent->Tag();
+ if (parent_tag == DW_TAG_class_type ||
+ parent_tag == DW_TAG_structure_type) {
+ is_method = true;
+ } else {
+ if (specification_die_form.IsValid()) {
+ DWARFDIE specification_die =
+ dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE(
+ DIERef(specification_die_form));
+ if (specification_die.GetParent().IsStructOrClass())
+ is_method = true;
+ }
}
- break;
-
- case DW_TAG_inlined_subroutine:
- if (has_address)
- {
- if (name)
- func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- if (mangled_cstr)
- {
- // Make sure our mangled name isn't the same string table entry
- // as our name. If it starts with '_', then it is ok, else compare
- // the string to make sure it isn't the same and we don't end up
- // with duplicate entries
- if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
- {
- Mangled mangled (ConstString(mangled_cstr), true);
- func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
- ConstString demangled = mangled.GetDemangledName(cu_language);
- if (demangled)
- func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset()));
- }
- }
- else
- func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- }
- break;
-
- case DW_TAG_array_type:
- case DW_TAG_base_type:
- case DW_TAG_class_type:
- case DW_TAG_constant:
- case DW_TAG_enumeration_type:
- case DW_TAG_string_type:
- case DW_TAG_structure_type:
- case DW_TAG_subroutine_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- case DW_TAG_unspecified_type:
- if (name && !is_declaration)
- types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- if (mangled_cstr && !is_declaration)
- types.Insert (ConstString(mangled_cstr), DIERef(cu_offset, die.GetOffset()));
- break;
-
- case DW_TAG_namespace:
- if (name)
- namespaces.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- break;
-
- case DW_TAG_variable:
- if (name && has_location_or_const_value && is_global_or_static_variable)
- {
- globals.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
- // Be sure to include variables by their mangled and demangled
- // names if they have any since a variable can have a basename
- // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled
- // mangled name "(anonymous namespace)::i"...
-
- // Make sure our mangled name isn't the same string table entry
- // as our name. If it starts with '_', then it is ok, else compare
- // the string to make sure it isn't the same and we don't end up
- // with duplicate entries
- if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
- {
- Mangled mangled (ConstString(mangled_cstr), true);
- globals.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
- ConstString demangled = mangled.GetDemangledName(cu_language);
- if (demangled)
- globals.Insert (demangled, DIERef(cu_offset, die.GetOffset()));
- }
- }
- break;
-
- default:
- continue;
+ }
+
+ if (is_method)
+ func_methods.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ else
+ func_basenames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+
+ if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
+ func_fullnames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
}
- }
-}
+ if (mangled_cstr) {
+ // Make sure our mangled name isn't the same string table entry
+ // as our name. If it starts with '_', then it is ok, else compare
+ // the string to make sure it isn't the same and we don't end up
+ // with duplicate entries
+ if (name && name != mangled_cstr &&
+ ((mangled_cstr[0] == '_') ||
+ (::strcmp(name, mangled_cstr) != 0))) {
+ Mangled mangled(ConstString(mangled_cstr), true);
+ func_fullnames.Insert(mangled.GetMangledName(),
+ DIERef(cu_offset, die.GetOffset()));
+ ConstString demangled = mangled.GetDemangledName(cu_language);
+ if (demangled)
+ func_fullnames.Insert(demangled,
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ }
+ }
+ break;
+
+ case DW_TAG_inlined_subroutine:
+ if (has_address) {
+ if (name)
+ func_basenames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ if (mangled_cstr) {
+ // Make sure our mangled name isn't the same string table entry
+ // as our name. If it starts with '_', then it is ok, else compare
+ // the string to make sure it isn't the same and we don't end up
+ // with duplicate entries
+ if (name && name != mangled_cstr &&
+ ((mangled_cstr[0] == '_') ||
+ (::strcmp(name, mangled_cstr) != 0))) {
+ Mangled mangled(ConstString(mangled_cstr), true);
+ func_fullnames.Insert(mangled.GetMangledName(),
+ DIERef(cu_offset, die.GetOffset()));
+ ConstString demangled = mangled.GetDemangledName(cu_language);
+ if (demangled)
+ func_fullnames.Insert(demangled,
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ } else
+ func_fullnames.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ }
+ break;
+
+ case DW_TAG_array_type:
+ case DW_TAG_base_type:
+ case DW_TAG_class_type:
+ case DW_TAG_constant:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_string_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ case DW_TAG_unspecified_type:
+ if (name && !is_declaration)
+ types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
+ if (mangled_cstr && !is_declaration)
+ types.Insert(ConstString(mangled_cstr),
+ DIERef(cu_offset, die.GetOffset()));
+ break;
+
+ case DW_TAG_namespace:
+ if (name)
+ namespaces.Insert(ConstString(name),
+ DIERef(cu_offset, die.GetOffset()));
+ break;
+
+ case DW_TAG_variable:
+ if (name && has_location_or_const_value && is_global_or_static_variable) {
+ globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset()));
+ // Be sure to include variables by their mangled and demangled
+ // names if they have any since a variable can have a basename
+ // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled
+ // mangled name "(anonymous namespace)::i"...
+
+ // Make sure our mangled name isn't the same string table entry
+ // as our name. If it starts with '_', then it is ok, else compare
+ // the string to make sure it isn't the same and we don't end up
+ // with duplicate entries
+ if (mangled_cstr && name != mangled_cstr &&
+ ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
+ Mangled mangled(ConstString(mangled_cstr), true);
+ globals.Insert(mangled.GetMangledName(),
+ DIERef(cu_offset, die.GetOffset()));
+ ConstString demangled = mangled.GetDemangledName(cu_language);
+ if (demangled)
+ globals.Insert(demangled, DIERef(cu_offset, die.GetOffset()));
+ }
+ }
+ break;
-bool
-DWARFCompileUnit::Supports_unnamed_objc_bitfields ()
-{
- if (GetProducer() == eProducerClang)
- {
- const uint32_t major_version = GetProducerVersionMajor();
- if (major_version > 425 || (major_version == 425 && GetProducerVersionUpdate() >= 13))
- return true;
- else
- return false;
+ default:
+ continue;
}
- return true; // Assume all other compilers didn't have incorrect ObjC bitfield info
+ }
}
-bool
-DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type ()
-{
- if (GetProducer() == eProducerLLVMGCC)
- return false;
- return true;
+bool DWARFCompileUnit::Supports_unnamed_objc_bitfields() {
+ if (GetProducer() == eProducerClang) {
+ const uint32_t major_version = GetProducerVersionMajor();
+ if (major_version > 425 ||
+ (major_version == 425 && GetProducerVersionUpdate() >= 13))
+ return true;
+ else
+ return false;
+ }
+ return true; // Assume all other compilers didn't have incorrect ObjC bitfield
+ // info
}
-bool
-DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid()
-{
- // llvm-gcc makes completely invalid decl file attributes and won't ever
- // be fixed, so we need to know to ignore these.
- return GetProducer() == eProducerLLVMGCC;
+bool DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type() {
+ if (GetProducer() == eProducerLLVMGCC)
+ return false;
+ return true;
}
-void
-DWARFCompileUnit::ParseProducerInfo ()
-{
- m_producer_version_major = UINT32_MAX;
- m_producer_version_minor = UINT32_MAX;
- m_producer_version_update = UINT32_MAX;
+bool DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() {
+ // llvm-gcc makes completely invalid decl file attributes and won't ever
+ // be fixed, so we need to know to ignore these.
+ return GetProducer() == eProducerLLVMGCC;
+}
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
- if (die)
- {
-
- const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL);
- if (producer_cstr)
- {
- RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$");
- if (llvm_gcc_regex.Execute (producer_cstr))
- {
- m_producer = eProducerLLVMGCC;
- }
- else if (strstr(producer_cstr, "clang"))
- {
- static RegularExpression g_clang_version_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)");
- RegularExpression::Match regex_match(3);
- if (g_clang_version_regex.Execute (producer_cstr, &regex_match))
- {
- std::string str;
- if (regex_match.GetMatchAtIndex (producer_cstr, 1, str))
- m_producer_version_major = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex (producer_cstr, 2, str))
- m_producer_version_minor = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex (producer_cstr, 3, str))
- m_producer_version_update = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- }
- m_producer = eProducerClang;
- }
- else if (strstr(producer_cstr, "GNU"))
- m_producer = eProducerGCC;
+void DWARFCompileUnit::ParseProducerInfo() {
+ m_producer_version_major = UINT32_MAX;
+ m_producer_version_minor = UINT32_MAX;
+ m_producer_version_update = UINT32_MAX;
+
+ const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
+ if (die) {
+
+ const char *producer_cstr = die->GetAttributeValueAsString(
+ m_dwarf2Data, this, DW_AT_producer, NULL);
+ if (producer_cstr) {
+ RegularExpression llvm_gcc_regex(
+ llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple "
+ "Inc\\. build [0-9]+\\) \\(LLVM build "
+ "[\\.0-9]+\\)$"));
+ if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) {
+ m_producer = eProducerLLVMGCC;
+ } else if (strstr(producer_cstr, "clang")) {
+ static RegularExpression g_clang_version_regex(
+ llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"));
+ RegularExpression::Match regex_match(3);
+ if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr),
+ &regex_match)) {
+ std::string str;
+ if (regex_match.GetMatchAtIndex(producer_cstr, 1, str))
+ m_producer_version_major =
+ StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (regex_match.GetMatchAtIndex(producer_cstr, 2, str))
+ m_producer_version_minor =
+ StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (regex_match.GetMatchAtIndex(producer_cstr, 3, str))
+ m_producer_version_update =
+ StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
}
+ m_producer = eProducerClang;
+ } else if (strstr(producer_cstr, "GNU"))
+ m_producer = eProducerGCC;
}
- if (m_producer == eProducerInvalid)
- m_producer = eProcucerOther;
+ }
+ if (m_producer == eProducerInvalid)
+ m_producer = eProcucerOther;
}
-DWARFCompileUnit::Producer
-DWARFCompileUnit::GetProducer ()
-{
- if (m_producer == eProducerInvalid)
- ParseProducerInfo ();
- return m_producer;
+DWARFCompileUnit::Producer DWARFCompileUnit::GetProducer() {
+ if (m_producer == eProducerInvalid)
+ ParseProducerInfo();
+ return m_producer;
}
-
-uint32_t
-DWARFCompileUnit::GetProducerVersionMajor()
-{
- if (m_producer_version_major == 0)
- ParseProducerInfo ();
- return m_producer_version_major;
+uint32_t DWARFCompileUnit::GetProducerVersionMajor() {
+ if (m_producer_version_major == 0)
+ ParseProducerInfo();
+ return m_producer_version_major;
}
-uint32_t
-DWARFCompileUnit::GetProducerVersionMinor()
-{
- if (m_producer_version_minor == 0)
- ParseProducerInfo ();
- return m_producer_version_minor;
+uint32_t DWARFCompileUnit::GetProducerVersionMinor() {
+ if (m_producer_version_minor == 0)
+ ParseProducerInfo();
+ return m_producer_version_minor;
}
-uint32_t
-DWARFCompileUnit::GetProducerVersionUpdate()
-{
- if (m_producer_version_update == 0)
- ParseProducerInfo ();
- return m_producer_version_update;
+uint32_t DWARFCompileUnit::GetProducerVersionUpdate() {
+ if (m_producer_version_update == 0)
+ ParseProducerInfo();
+ return m_producer_version_update;
}
-LanguageType
-DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val)
-{
- // Note: user languages between lo_user and hi_user
- // must be handled explicitly here.
- switch (val)
- {
- case DW_LANG_Mips_Assembler:
- return eLanguageTypeMipsAssembler;
- case DW_LANG_GOOGLE_RenderScript:
- return eLanguageTypeExtRenderScript;
- default:
- return static_cast<LanguageType>(val);
- }
+LanguageType DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) {
+ // Note: user languages between lo_user and hi_user
+ // must be handled explicitly here.
+ switch (val) {
+ case DW_LANG_Mips_Assembler:
+ return eLanguageTypeMipsAssembler;
+ case DW_LANG_GOOGLE_RenderScript:
+ return eLanguageTypeExtRenderScript;
+ default:
+ return static_cast<LanguageType>(val);
+ }
}
-LanguageType
-DWARFCompileUnit::GetLanguageType()
-{
- if (m_language_type != eLanguageTypeUnknown)
- return m_language_type;
-
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
- if (die)
- m_language_type = LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0));
+LanguageType DWARFCompileUnit::GetLanguageType() {
+ if (m_language_type != eLanguageTypeUnknown)
return m_language_type;
-}
-bool
-DWARFCompileUnit::IsDWARF64() const
-{
- return m_is_dwarf64;
+ const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
+ if (die)
+ m_language_type = LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(
+ m_dwarf2Data, this, DW_AT_language, 0));
+ return m_language_type;
}
-bool
-DWARFCompileUnit::GetIsOptimized ()
-{
- if (m_is_optimized == eLazyBoolCalculate)
- {
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
- if (die)
- {
- m_is_optimized = eLazyBoolNo;
- if (die->GetAttributeValueAsUnsigned (m_dwarf2Data, this, DW_AT_APPLE_optimized, 0) == 1)
- {
- m_is_optimized = eLazyBoolYes;
- }
- }
- }
- if (m_is_optimized == eLazyBoolYes)
- {
- return true;
- }
- else
- {
- return false;
+bool DWARFCompileUnit::IsDWARF64() const { return m_is_dwarf64; }
+
+bool DWARFCompileUnit::GetIsOptimized() {
+ if (m_is_optimized == eLazyBoolCalculate) {
+ const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly();
+ if (die) {
+ m_is_optimized = eLazyBoolNo;
+ if (die->GetAttributeValueAsUnsigned(m_dwarf2Data, this,
+ DW_AT_APPLE_optimized, 0) == 1) {
+ m_is_optimized = eLazyBoolYes;
+ }
}
+ }
+ if (m_is_optimized == eLazyBoolYes) {
+ return true;
+ } else {
+ return false;
+ }
}
-DWARFFormValue::FixedFormSizes
-DWARFCompileUnit::GetFixedFormSizes ()
-{
- return DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), IsDWARF64());
+DWARFFormValue::FixedFormSizes DWARFCompileUnit::GetFixedFormSizes() {
+ return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
+ IsDWARF64());
}
-TypeSystem *
-DWARFCompileUnit::GetTypeSystem ()
-{
- if (m_dwarf2Data)
- return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType());
- else
- return nullptr;
+TypeSystem *DWARFCompileUnit::GetTypeSystem() {
+ if (m_dwarf2Data)
+ return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType());
+ else
+ return nullptr;
}
-void
-DWARFCompileUnit::SetUserData(void *d)
-{
- m_user_data = d;
- if (m_dwo_symbol_file)
- m_dwo_symbol_file->GetCompileUnit()->SetUserData(d);
+void DWARFCompileUnit::SetUserData(void *d) {
+ m_user_data = d;
+ if (m_dwo_symbol_file)
+ m_dwo_symbol_file->GetCompileUnit()->SetUserData(d);
}
-void
-DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset)
-{
- m_addr_base = addr_base;
- m_base_obj_offset = base_obj_offset;
+void DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base,
+ dw_addr_t ranges_base,
+ dw_offset_t base_obj_offset) {
+ m_addr_base = addr_base;
+ m_ranges_base = ranges_base;
+ m_base_obj_offset = base_obj_offset;
}
-lldb::ByteOrder
-DWARFCompileUnit::GetByteOrder() const
-{
- return m_dwarf2Data->GetObjectFile()->GetByteOrder();
+lldb::ByteOrder DWARFCompileUnit::GetByteOrder() const {
+ return m_dwarf2Data->GetObjectFile()->GetByteOrder();
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 8d96e3698ab2..430251337575 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -10,258 +10,214 @@
#ifndef SymbolFileDWARF_DWARFCompileUnit_h_
#define SymbolFileDWARF_DWARFCompileUnit_h_
-#include "lldb/lldb-enumerations.h"
-#include "DWARFDebugInfoEntry.h"
#include "DWARFDIE.h"
+#include "DWARFDebugInfoEntry.h"
+#include "lldb/lldb-enumerations.h"
class NameToDIE;
class SymbolFileDWARF;
class SymbolFileDWARFDwo;
-class DWARFCompileUnit
-{
+class DWARFCompileUnit {
public:
- enum Producer
- {
- eProducerInvalid = 0,
- eProducerClang,
- eProducerGCC,
- eProducerLLVMGCC,
- eProcucerOther
- };
-
- DWARFCompileUnit(SymbolFileDWARF* dwarf2Data);
- ~DWARFCompileUnit();
-
- bool Extract(const lldb_private::DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr);
- size_t ExtractDIEsIfNeeded (bool cu_die_only);
- DWARFDIE LookupAddress(const dw_addr_t address);
- size_t AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& matching_dies, uint32_t depth = UINT32_MAX) const;
- void Clear();
- bool Verify(lldb_private::Stream *s) const;
- void Dump(lldb_private::Stream *s) const;
- dw_offset_t GetOffset() const { return m_offset; }
- lldb::user_id_t GetID () const;
- uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; /* Size in bytes of the compile unit header */ }
- bool ContainsDIEOffset(dw_offset_t die_offset) const { return die_offset >= GetFirstDIEOffset() && die_offset < GetNextCompileUnitOffset(); }
- dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
- dw_offset_t GetNextCompileUnitOffset() const { return m_offset + m_length + (m_is_dwarf64 ? 12 : 4); }
- size_t GetDebugInfoSize() const { return m_length + (m_is_dwarf64 ? 12 : 4) - Size(); /* Size in bytes of the .debug_info data associated with this compile unit. */ }
- uint32_t GetLength() const { return m_length; }
- uint16_t GetVersion() const { return m_version; }
- const DWARFAbbreviationDeclarationSet* GetAbbreviations() const { return m_abbrevs; }
- dw_offset_t GetAbbrevOffset() const;
- uint8_t GetAddressByteSize() const { return m_addr_size; }
- dw_addr_t GetBaseAddress() const { return m_base_addr; }
- dw_addr_t GetAddrBase() const { return m_addr_base; }
- void SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset);
- void ClearDIEs(bool keep_compile_unit_die);
- void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
- DWARFDebugAranges* debug_aranges);
-
- lldb::ByteOrder
- GetByteOrder() const;
-
- lldb_private::TypeSystem *
- GetTypeSystem();
-
- DWARFFormValue::FixedFormSizes
- GetFixedFormSizes ();
-
- void
- SetBaseAddress(dw_addr_t base_addr)
- {
- m_base_addr = base_addr;
- }
-
- DWARFDIE
- GetCompileUnitDIEOnly()
- {
- return DWARFDIE(this, GetCompileUnitDIEPtrOnly());
- }
-
- DWARFDIE
- DIE ()
- {
- return DWARFDIE(this, DIEPtr());
- }
-
- void
- AddDIE (DWARFDebugInfoEntry& die)
- {
- // The average bytes per DIE entry has been seen to be
- // around 14-20 so lets pre-reserve half of that since
- // we are now stripping the NULL tags.
-
- // Only reserve the memory if we are adding children of
- // the main compile unit DIE. The compile unit DIE is always
- // the first entry, so if our size is 1, then we are adding
- // the first compile unit child DIE and should reserve
- // the memory.
- if (m_die_array.empty())
- m_die_array.reserve(GetDebugInfoSize() / 24);
- m_die_array.push_back(die);
- }
-
- void
- AddCompileUnitDIE (DWARFDebugInfoEntry& die);
-
- bool
- HasDIEsParsed () const
- {
- return m_die_array.size() > 1;
- }
-
- DWARFDIE
- GetDIE (dw_offset_t die_offset);
-
- static uint8_t
- GetAddressByteSize(const DWARFCompileUnit* cu);
-
- static bool
- IsDWARF64(const DWARFCompileUnit* cu);
-
- static uint8_t
- GetDefaultAddressSize();
-
- static void
- SetDefaultAddressSize(uint8_t addr_size);
-
- void *
- GetUserData() const
- {
- return m_user_data;
- }
-
- void
- SetUserData(void *d);
-
- bool
- Supports_DW_AT_APPLE_objc_complete_type ();
-
- bool
- DW_AT_decl_file_attributes_are_invalid();
-
- bool
- Supports_unnamed_objc_bitfields ();
-
- void
- Index (NameToDIE& func_basenames,
- NameToDIE& func_fullnames,
- NameToDIE& func_methods,
- NameToDIE& func_selectors,
- NameToDIE& objc_class_selectors,
- NameToDIE& globals,
- NameToDIE& types,
- NameToDIE& namespaces);
-
- const DWARFDebugAranges &
- GetFunctionAranges ();
-
- SymbolFileDWARF*
- GetSymbolFileDWARF () const
- {
- return m_dwarf2Data;
- }
-
- Producer
- GetProducer ();
-
- uint32_t
- GetProducerVersionMajor();
-
- uint32_t
- GetProducerVersionMinor();
-
- uint32_t
- GetProducerVersionUpdate();
-
- static lldb::LanguageType
- LanguageTypeFromDWARF(uint64_t val);
-
- lldb::LanguageType
- GetLanguageType();
-
- bool
- IsDWARF64() const;
-
- bool
- GetIsOptimized ();
-
- SymbolFileDWARFDwo*
- GetDwoSymbolFile() const
- {
- return m_dwo_symbol_file.get();
- }
-
- dw_offset_t
- GetBaseObjOffset() const
- {
- return m_base_obj_offset;
- }
+ enum Producer {
+ eProducerInvalid = 0,
+ eProducerClang,
+ eProducerGCC,
+ eProducerLLVMGCC,
+ eProcucerOther
+ };
+
+ DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
+ ~DWARFCompileUnit();
+
+ bool Extract(const lldb_private::DWARFDataExtractor &debug_info,
+ lldb::offset_t *offset_ptr);
+ size_t ExtractDIEsIfNeeded(bool cu_die_only);
+ DWARFDIE LookupAddress(const dw_addr_t address);
+ size_t AppendDIEsWithTag(const dw_tag_t tag,
+ DWARFDIECollection &matching_dies,
+ uint32_t depth = UINT32_MAX) const;
+ void Clear();
+ bool Verify(lldb_private::Stream *s) const;
+ void Dump(lldb_private::Stream *s) const;
+ dw_offset_t GetOffset() const { return m_offset; }
+ lldb::user_id_t GetID() const;
+ uint32_t Size() const {
+ return m_is_dwarf64 ? 23
+ : 11; /* Size in bytes of the compile unit header */
+ }
+ bool ContainsDIEOffset(dw_offset_t die_offset) const {
+ return die_offset >= GetFirstDIEOffset() &&
+ die_offset < GetNextCompileUnitOffset();
+ }
+ dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
+ dw_offset_t GetNextCompileUnitOffset() const {
+ return m_offset + m_length + (m_is_dwarf64 ? 12 : 4);
+ }
+ size_t GetDebugInfoSize() const {
+ return m_length + (m_is_dwarf64 ? 12 : 4) - Size(); /* Size in bytes of the
+ .debug_info data
+ associated with this
+ compile unit. */
+ }
+ uint32_t GetLength() const { return m_length; }
+ uint16_t GetVersion() const { return m_version; }
+ const DWARFAbbreviationDeclarationSet *GetAbbreviations() const {
+ return m_abbrevs;
+ }
+ dw_offset_t GetAbbrevOffset() const;
+ uint8_t GetAddressByteSize() const { return m_addr_size; }
+ dw_addr_t GetBaseAddress() const { return m_base_addr; }
+ dw_addr_t GetAddrBase() const { return m_addr_base; }
+ dw_addr_t GetRangesBase() const { return m_ranges_base; }
+ void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, dw_offset_t base_obj_offset);
+ void ClearDIEs(bool keep_compile_unit_die);
+ void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
+ DWARFDebugAranges *debug_aranges);
+
+ lldb::ByteOrder GetByteOrder() const;
+
+ lldb_private::TypeSystem *GetTypeSystem();
+
+ DWARFFormValue::FixedFormSizes GetFixedFormSizes();
+
+ void SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
+
+ DWARFDIE
+ GetCompileUnitDIEOnly() { return DWARFDIE(this, GetCompileUnitDIEPtrOnly()); }
+
+ DWARFDIE
+ DIE() { return DWARFDIE(this, DIEPtr()); }
+
+ void AddDIE(DWARFDebugInfoEntry &die) {
+ // The average bytes per DIE entry has been seen to be
+ // around 14-20 so lets pre-reserve half of that since
+ // we are now stripping the NULL tags.
+
+ // Only reserve the memory if we are adding children of
+ // the main compile unit DIE. The compile unit DIE is always
+ // the first entry, so if our size is 1, then we are adding
+ // the first compile unit child DIE and should reserve
+ // the memory.
+ if (m_die_array.empty())
+ m_die_array.reserve(GetDebugInfoSize() / 24);
+ m_die_array.push_back(die);
+ }
+
+ void AddCompileUnitDIE(DWARFDebugInfoEntry &die);
+
+ bool HasDIEsParsed() const { return m_die_array.size() > 1; }
+
+ DWARFDIE
+ GetDIE(dw_offset_t die_offset);
+
+ static uint8_t GetAddressByteSize(const DWARFCompileUnit *cu);
+
+ static bool IsDWARF64(const DWARFCompileUnit *cu);
+
+ static uint8_t GetDefaultAddressSize();
+
+ static void SetDefaultAddressSize(uint8_t addr_size);
+
+ void *GetUserData() const { return m_user_data; }
+
+ void SetUserData(void *d);
+
+ bool Supports_DW_AT_APPLE_objc_complete_type();
+
+ bool DW_AT_decl_file_attributes_are_invalid();
+
+ bool Supports_unnamed_objc_bitfields();
+
+ void Index(NameToDIE &func_basenames, NameToDIE &func_fullnames,
+ NameToDIE &func_methods, NameToDIE &func_selectors,
+ NameToDIE &objc_class_selectors, NameToDIE &globals,
+ NameToDIE &types, NameToDIE &namespaces);
+
+ const DWARFDebugAranges &GetFunctionAranges();
+
+ SymbolFileDWARF *GetSymbolFileDWARF() const { return m_dwarf2Data; }
+
+ Producer GetProducer();
+
+ uint32_t GetProducerVersionMajor();
+
+ uint32_t GetProducerVersionMinor();
+
+ uint32_t GetProducerVersionUpdate();
+
+ static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
+
+ lldb::LanguageType GetLanguageType();
+
+ bool IsDWARF64() const;
+
+ bool GetIsOptimized();
+
+ SymbolFileDWARFDwo *GetDwoSymbolFile() const {
+ return m_dwo_symbol_file.get();
+ }
+
+ dw_offset_t GetBaseObjOffset() const { return m_base_obj_offset; }
protected:
- SymbolFileDWARF* m_dwarf2Data;
- std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
- const DWARFAbbreviationDeclarationSet *m_abbrevs;
- void * m_user_data;
- DWARFDebugInfoEntry::collection m_die_array; // The compile unit debug information entry item
- std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs
- dw_addr_t m_base_addr;
- dw_offset_t m_offset;
- dw_offset_t m_length;
- uint16_t m_version;
- uint8_t m_addr_size;
- Producer m_producer;
- uint32_t m_producer_version_major;
- uint32_t m_producer_version_minor;
- uint32_t m_producer_version_update;
- lldb::LanguageType m_language_type;
- bool m_is_dwarf64;
- lldb_private::LazyBool m_is_optimized;
- dw_addr_t m_addr_base; // Value of DW_AT_addr_base
- dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the offset of
- // the base compile unit in the main object file
-
- void
- ParseProducerInfo ();
-
- static void
- IndexPrivate (DWARFCompileUnit* dwarf_cu,
- const lldb::LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
- const dw_offset_t cu_offset,
- NameToDIE& func_basenames,
- NameToDIE& func_fullnames,
- NameToDIE& func_methods,
- NameToDIE& func_selectors,
- NameToDIE& objc_class_selectors,
- NameToDIE& globals,
- NameToDIE& types,
- NameToDIE& namespaces);
+ SymbolFileDWARF *m_dwarf2Data;
+ std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
+ const DWARFAbbreviationDeclarationSet *m_abbrevs;
+ void *m_user_data;
+ DWARFDebugInfoEntry::collection
+ m_die_array; // The compile unit debug information entry item
+ std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to
+ // the .debug_aranges
+ // table, but this one
+ // points to the exact
+ // DW_TAG_subprogram
+ // DIEs
+ dw_addr_t m_base_addr;
+ dw_offset_t m_offset;
+ dw_offset_t m_length;
+ uint16_t m_version;
+ uint8_t m_addr_size;
+ Producer m_producer;
+ uint32_t m_producer_version_major;
+ uint32_t m_producer_version_minor;
+ uint32_t m_producer_version_update;
+ lldb::LanguageType m_language_type;
+ bool m_is_dwarf64;
+ lldb_private::LazyBool m_is_optimized;
+ dw_addr_t m_addr_base; // Value of DW_AT_addr_base
+ dw_addr_t m_ranges_base; // Value of DW_AT_ranges_base
+ dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the
+ // offset of the base compile unit in the main
+ // object file
+
+ void ParseProducerInfo();
+
+ static void
+ IndexPrivate(DWARFCompileUnit *dwarf_cu, const lldb::LanguageType cu_language,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ const dw_offset_t cu_offset, NameToDIE &func_basenames,
+ NameToDIE &func_fullnames, NameToDIE &func_methods,
+ NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
+ NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
private:
-
- const DWARFDebugInfoEntry*
- GetCompileUnitDIEPtrOnly()
- {
- ExtractDIEsIfNeeded (true);
- if (m_die_array.empty())
- return NULL;
- return &m_die_array[0];
- }
-
- const DWARFDebugInfoEntry*
- DIEPtr()
- {
- ExtractDIEsIfNeeded (false);
- if (m_die_array.empty())
- return NULL;
- return &m_die_array[0];
- }
-
-
- DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit);
+ const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly() {
+ ExtractDIEsIfNeeded(true);
+ if (m_die_array.empty())
+ return NULL;
+ return &m_die_array[0];
+ }
+
+ const DWARFDebugInfoEntry *DIEPtr() {
+ ExtractDIEsIfNeeded(false);
+ if (m_die_array.empty())
+ return NULL;
+ return &m_die_array[0];
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
};
-#endif // SymbolFileDWARF_DWARFCompileUnit_h_
+#endif // SymbolFileDWARF_DWARFCompileUnit_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 0f02c74fd2eb..5222419d3233 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -11,13 +11,13 @@
#include "DWARFASTParser.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
-#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
#include "SymbolFileDWARF.h"
@@ -28,543 +28,441 @@
using namespace lldb_private;
-DIERef
-DWARFDIE::GetDIERef() const
-{
- if (!IsValid())
- return DIERef();
+DIERef DWARFDIE::GetDIERef() const {
+ if (!IsValid())
+ return DIERef();
- dw_offset_t cu_offset = m_cu->GetOffset();
- if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
- cu_offset = m_cu->GetBaseObjOffset();
- return DIERef(cu_offset, m_die->GetOffset());
+ dw_offset_t cu_offset = m_cu->GetOffset();
+ if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
+ cu_offset = m_cu->GetBaseObjOffset();
+ return DIERef(cu_offset, m_die->GetOffset());
}
-dw_tag_t
-DWARFDIE::Tag() const
-{
- if (m_die)
- return m_die->Tag();
- else
- return 0;
+dw_tag_t DWARFDIE::Tag() const {
+ if (m_die)
+ return m_die->Tag();
+ else
+ return 0;
}
-const char *
-DWARFDIE::GetTagAsCString () const
-{
- return lldb_private::DW_TAG_value_to_name (Tag());
+const char *DWARFDIE::GetTagAsCString() const {
+ return lldb_private::DW_TAG_value_to_name(Tag());
}
DWARFDIE
-DWARFDIE::GetParent () const
-{
- if (IsValid())
- return DWARFDIE(m_cu, m_die->GetParent());
- else
- return DWARFDIE();
+DWARFDIE::GetParent() const {
+ if (IsValid())
+ return DWARFDIE(m_cu, m_die->GetParent());
+ else
+ return DWARFDIE();
}
DWARFDIE
-DWARFDIE::GetFirstChild () const
-{
- if (IsValid())
- return DWARFDIE(m_cu, m_die->GetFirstChild());
- else
- return DWARFDIE();
+DWARFDIE::GetFirstChild() const {
+ if (IsValid())
+ return DWARFDIE(m_cu, m_die->GetFirstChild());
+ else
+ return DWARFDIE();
}
DWARFDIE
-DWARFDIE::GetSibling () const
-{
- if (IsValid())
- return DWARFDIE(m_cu, m_die->GetSibling());
- else
- return DWARFDIE();
+DWARFDIE::GetSibling() const {
+ if (IsValid())
+ return DWARFDIE(m_cu, m_die->GetSibling());
+ else
+ return DWARFDIE();
}
DWARFDIE
-DWARFDIE::GetReferencedDIE (const dw_attr_t attr) const
-{
- const dw_offset_t die_offset = GetAttributeValueAsReference (attr, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- return GetDIE(die_offset);
- else
- return DWARFDIE();
+DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
+ const dw_offset_t die_offset =
+ GetAttributeValueAsReference(attr, DW_INVALID_OFFSET);
+ if (die_offset != DW_INVALID_OFFSET)
+ return GetDIE(die_offset);
+ else
+ return DWARFDIE();
}
DWARFDIE
-DWARFDIE::GetDIE (dw_offset_t die_offset) const
-{
- if (IsValid())
- return m_cu->GetDIE(die_offset);
- else
- return DWARFDIE();
+DWARFDIE::GetDIE(dw_offset_t die_offset) const {
+ if (IsValid())
+ return m_cu->GetDIE(die_offset);
+ else
+ return DWARFDIE();
}
-const char *
-DWARFDIE::GetAttributeValueAsString (const dw_attr_t attr, const char *fail_value) const
-{
- if (IsValid())
- return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr, fail_value);
- else
- return fail_value;
+const char *DWARFDIE::GetAttributeValueAsString(const dw_attr_t attr,
+ const char *fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
}
-uint64_t
-DWARFDIE::GetAttributeValueAsUnsigned (const dw_attr_t attr, uint64_t fail_value) const
-{
- if (IsValid())
- return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr, fail_value);
- else
- return fail_value;
+uint64_t DWARFDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
+ uint64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
}
-int64_t
-DWARFDIE::GetAttributeValueAsSigned (const dw_attr_t attr, int64_t fail_value) const
-{
- if (IsValid())
- return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr, fail_value);
- else
- return fail_value;
+int64_t DWARFDIE::GetAttributeValueAsSigned(const dw_attr_t attr,
+ int64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
}
DWARFDIE
-DWARFDIE::GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const
-{
- if (IsValid())
- {
- DWARFCompileUnit *cu = GetCU();
- SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF();
- const bool check_specification_or_abstract_origin = true;
- DWARFFormValue form_value;
- if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return dwarf->GetDIE(DIERef(form_value));
- }
- return DWARFDIE();
+DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
+ if (IsValid()) {
+ DWARFCompileUnit *cu = GetCU();
+ SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF();
+ const bool check_specification_or_abstract_origin = true;
+ DWARFFormValue form_value;
+ if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return dwarf->GetDIE(DIERef(form_value));
+ }
+ return DWARFDIE();
+}
+
+uint64_t DWARFDIE::GetAttributeValueAsReference(const dw_attr_t attr,
+ uint64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
+}
+
+uint64_t DWARFDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
+ uint64_t fail_value) const {
+ if (IsValid())
+ return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr,
+ fail_value);
+ else
+ return fail_value;
}
-uint64_t
-DWARFDIE::GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const
-{
- if (IsValid())
- return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr, fail_value);
- else
- return fail_value;
-}
-
-uint64_t
-DWARFDIE::GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const
-{
- if (IsValid())
- return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr, fail_value);
- else
- return fail_value;
-}
-
-
DWARFDIE
-DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const
-{
- if (IsValid())
- {
- SymbolFileDWARF *dwarf= GetDWARF();
- DWARFCompileUnit *cu = GetCU();
- DWARFDebugInfoEntry* function_die = nullptr;
- DWARFDebugInfoEntry* block_die = nullptr;
- if (m_die->LookupAddress (file_addr,
- dwarf,
- cu,
- &function_die,
- &block_die))
- {
- if (block_die && block_die != function_die)
- {
- if (cu->ContainsDIEOffset(block_die->GetOffset()))
- return DWARFDIE(cu, block_die);
- else
- return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die);
- }
- }
+DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const {
+ if (IsValid()) {
+ SymbolFileDWARF *dwarf = GetDWARF();
+ DWARFCompileUnit *cu = GetCU();
+ DWARFDebugInfoEntry *function_die = nullptr;
+ DWARFDebugInfoEntry *block_die = nullptr;
+ if (m_die->LookupAddress(file_addr, dwarf, cu, &function_die, &block_die)) {
+ if (block_die && block_die != function_die) {
+ if (cu->ContainsDIEOffset(block_die->GetOffset()))
+ return DWARFDIE(cu, block_die);
+ else
+ return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit(
+ DIERef(cu->GetOffset(), block_die->GetOffset())),
+ block_die);
+ }
}
- return DWARFDIE();
-}
-
-lldb::user_id_t
-DWARFDIE::GetID () const
-{
- return GetDIERef().GetUID(GetDWARF());
+ }
+ return DWARFDIE();
}
-const char *
-DWARFDIE::GetName () const
-{
- if (IsValid())
- return m_die->GetName (GetDWARF(), m_cu);
- else
- return nullptr;
+lldb::user_id_t DWARFDIE::GetID() const {
+ return GetDIERef().GetUID(GetDWARF());
}
-const char *
-DWARFDIE::GetMangledName () const
-{
- if (IsValid())
- return m_die->GetMangledName (GetDWARF(), m_cu);
- else
- return nullptr;
+const char *DWARFDIE::GetName() const {
+ if (IsValid())
+ return m_die->GetName(GetDWARF(), m_cu);
+ else
+ return nullptr;
}
-const char *
-DWARFDIE::GetPubname () const
-{
- if (IsValid())
- return m_die->GetPubname (GetDWARF(), m_cu);
- else
- return nullptr;
+const char *DWARFDIE::GetMangledName() const {
+ if (IsValid())
+ return m_die->GetMangledName(GetDWARF(), m_cu);
+ else
+ return nullptr;
}
-const char *
-DWARFDIE::GetQualifiedName (std::string &storage) const
-{
- if (IsValid())
- return m_die->GetQualifiedName (GetDWARF(), m_cu, storage);
- else
- return nullptr;
+const char *DWARFDIE::GetPubname() const {
+ if (IsValid())
+ return m_die->GetPubname(GetDWARF(), m_cu);
+ else
+ return nullptr;
}
-lldb::LanguageType
-DWARFDIE::GetLanguage () const
-{
- if (IsValid())
- return m_cu->GetLanguageType();
- else
- return lldb::eLanguageTypeUnknown;
+const char *DWARFDIE::GetQualifiedName(std::string &storage) const {
+ if (IsValid())
+ return m_die->GetQualifiedName(GetDWARF(), m_cu, storage);
+ else
+ return nullptr;
}
-
-lldb::ModuleSP
-DWARFDIE::GetModule () const
-{
- SymbolFileDWARF *dwarf = GetDWARF();
- if (dwarf)
- return dwarf->GetObjectFile()->GetModule();
- else
- return lldb::ModuleSP();
+lldb::LanguageType DWARFDIE::GetLanguage() const {
+ if (IsValid())
+ return m_cu->GetLanguageType();
+ else
+ return lldb::eLanguageTypeUnknown;
}
-lldb_private::CompileUnit *
-DWARFDIE::GetLLDBCompileUnit () const
-{
- if (IsValid())
- return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU());
- else
- return nullptr;
+lldb::ModuleSP DWARFDIE::GetModule() const {
+ SymbolFileDWARF *dwarf = GetDWARF();
+ if (dwarf)
+ return dwarf->GetObjectFile()->GetModule();
+ else
+ return lldb::ModuleSP();
}
-lldb_private::Type *
-DWARFDIE::ResolveType () const
-{
- if (IsValid())
- return GetDWARF()->ResolveType(*this, true);
- else
- return nullptr;
+lldb_private::CompileUnit *DWARFDIE::GetLLDBCompileUnit() const {
+ if (IsValid())
+ return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU());
+ else
+ return nullptr;
}
-lldb_private::Type *
-DWARFDIE::ResolveTypeUID (const DIERef &die_ref) const
-{
- SymbolFileDWARF *dwarf = GetDWARF();
- if (dwarf)
- return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true);
- else
- return nullptr;
-}
-
-void
-DWARFDIE::GetDeclContextDIEs (DWARFDIECollection &decl_context_dies) const
-{
- if (IsValid())
- {
- DWARFDIE parent_decl_ctx_die = m_die->GetParentDeclContextDIE (GetDWARF(), GetCU());
- if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE())
- {
- decl_context_dies.Append(parent_decl_ctx_die);
- parent_decl_ctx_die.GetDeclContextDIEs (decl_context_dies);
- }
- }
+lldb_private::Type *DWARFDIE::ResolveType() const {
+ if (IsValid())
+ return GetDWARF()->ResolveType(*this, true);
+ else
+ return nullptr;
}
-void
-DWARFDIE::GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const
-{
- if (IsValid())
- {
- dwarf_decl_ctx.SetLanguage(GetLanguage());
- m_die->GetDWARFDeclContext (GetDWARF(), GetCU(), dwarf_decl_ctx);
- }
- else
- {
- dwarf_decl_ctx.Clear();
- }
+lldb_private::Type *DWARFDIE::ResolveTypeUID(const DIERef &die_ref) const {
+ SymbolFileDWARF *dwarf = GetDWARF();
+ if (dwarf)
+ return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true);
+ else
+ return nullptr;
}
-void
-DWARFDIE::GetDWOContext (std::vector<CompilerContext> &context) const
-{
- const dw_tag_t tag = Tag();
- if (tag == DW_TAG_compile_unit)
- return;
- DWARFDIE parent = GetParent();
- if (parent)
- parent.GetDWOContext(context);
- switch (tag)
- {
- case DW_TAG_module:
- context.push_back(CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
- break;
- case DW_TAG_namespace:
- context.push_back(CompilerContext(CompilerContextKind::Namespace, ConstString(GetName())));
- break;
- case DW_TAG_structure_type:
- context.push_back(CompilerContext(CompilerContextKind::Structure, ConstString(GetName())));
- break;
- case DW_TAG_union_type:
- context.push_back(CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
- break;
- case DW_TAG_class_type:
- context.push_back(CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
- break;
- case DW_TAG_enumeration_type:
- context.push_back(CompilerContext(CompilerContextKind::Enumeration, ConstString(GetName())));
- break;
- case DW_TAG_subprogram:
- context.push_back(CompilerContext(CompilerContextKind::Function, ConstString(GetPubname())));
- break;
- case DW_TAG_variable:
- context.push_back(CompilerContext(CompilerContextKind::Variable, ConstString(GetPubname())));
- break;
- case DW_TAG_typedef:
- context.push_back(CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
- break;
- default:
- break;
+void DWARFDIE::GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const {
+ if (IsValid()) {
+ DWARFDIE parent_decl_ctx_die =
+ m_die->GetParentDeclContextDIE(GetDWARF(), GetCU());
+ if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE()) {
+ decl_context_dies.Append(parent_decl_ctx_die);
+ parent_decl_ctx_die.GetDeclContextDIEs(decl_context_dies);
}
+ }
+}
+
+void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
+ if (IsValid()) {
+ dwarf_decl_ctx.SetLanguage(GetLanguage());
+ m_die->GetDWARFDeclContext(GetDWARF(), GetCU(), dwarf_decl_ctx);
+ } else {
+ dwarf_decl_ctx.Clear();
+ }
+}
+
+void DWARFDIE::GetDWOContext(std::vector<CompilerContext> &context) const {
+ const dw_tag_t tag = Tag();
+ if (tag == DW_TAG_compile_unit)
+ return;
+ DWARFDIE parent = GetParent();
+ if (parent)
+ parent.GetDWOContext(context);
+ switch (tag) {
+ case DW_TAG_module:
+ context.push_back(
+ CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
+ break;
+ case DW_TAG_namespace:
+ context.push_back(CompilerContext(CompilerContextKind::Namespace,
+ ConstString(GetName())));
+ break;
+ case DW_TAG_structure_type:
+ context.push_back(CompilerContext(CompilerContextKind::Structure,
+ ConstString(GetName())));
+ break;
+ case DW_TAG_union_type:
+ context.push_back(
+ CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
+ break;
+ case DW_TAG_class_type:
+ context.push_back(
+ CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
+ break;
+ case DW_TAG_enumeration_type:
+ context.push_back(CompilerContext(CompilerContextKind::Enumeration,
+ ConstString(GetName())));
+ break;
+ case DW_TAG_subprogram:
+ context.push_back(CompilerContext(CompilerContextKind::Function,
+ ConstString(GetPubname())));
+ break;
+ case DW_TAG_variable:
+ context.push_back(CompilerContext(CompilerContextKind::Variable,
+ ConstString(GetPubname())));
+ break;
+ case DW_TAG_typedef:
+ context.push_back(
+ CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
+ break;
+ default:
+ break;
+ }
}
-
-
DWARFDIE
-DWARFDIE::GetParentDeclContextDIE () const
-{
- if (IsValid())
- return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu);
- else
- return DWARFDIE();
+DWARFDIE::GetParentDeclContextDIE() const {
+ if (IsValid())
+ return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu);
+ else
+ return DWARFDIE();
}
-
-dw_offset_t
-DWARFDIE::GetOffset () const
-{
- if (IsValid())
- return m_die->GetOffset();
- else
- return DW_INVALID_OFFSET;
+dw_offset_t DWARFDIE::GetOffset() const {
+ if (IsValid())
+ return m_die->GetOffset();
+ else
+ return DW_INVALID_OFFSET;
}
-dw_offset_t
-DWARFDIE::GetCompileUnitRelativeOffset () const
-{
- if (IsValid())
- return m_die->GetOffset() - m_cu->GetOffset();
- else
- return DW_INVALID_OFFSET;
+dw_offset_t DWARFDIE::GetCompileUnitRelativeOffset() const {
+ if (IsValid())
+ return m_die->GetOffset() - m_cu->GetOffset();
+ else
+ return DW_INVALID_OFFSET;
}
-SymbolFileDWARF *
-DWARFDIE::GetDWARF () const
-{
- if (m_cu)
- return m_cu->GetSymbolFileDWARF();
- else
- return nullptr;
+SymbolFileDWARF *DWARFDIE::GetDWARF() const {
+ if (m_cu)
+ return m_cu->GetSymbolFileDWARF();
+ else
+ return nullptr;
}
-lldb_private::TypeSystem *
-DWARFDIE::GetTypeSystem () const
-{
- if (m_cu)
- return m_cu->GetTypeSystem();
- else
- return nullptr;
+lldb_private::TypeSystem *DWARFDIE::GetTypeSystem() const {
+ if (m_cu)
+ return m_cu->GetTypeSystem();
+ else
+ return nullptr;
}
-DWARFASTParser *
-DWARFDIE::GetDWARFParser () const
-{
- lldb_private::TypeSystem *type_system = GetTypeSystem ();
- if (type_system)
- return type_system->GetDWARFParser();
- else
- return nullptr;
+DWARFASTParser *DWARFDIE::GetDWARFParser() const {
+ lldb_private::TypeSystem *type_system = GetTypeSystem();
+ if (type_system)
+ return type_system->GetDWARFParser();
+ else
+ return nullptr;
}
-bool
-DWARFDIE::IsStructOrClass () const
-{
- const dw_tag_t tag = Tag();
- return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;
+bool DWARFDIE::IsStructOrClass() const {
+ const dw_tag_t tag = Tag();
+ return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;
}
-
DWARFDIE
-DWARFDIE::GetContainingDWOModuleDIE () const
-{
- if (IsValid())
- {
- DWARFDIE top_module_die;
- // Now make sure this DIE is scoped in a DW_TAG_module tag and return true if so
- for (DWARFDIE parent = GetParent(); parent.IsValid(); parent = parent.GetParent())
- {
- const dw_tag_t tag = parent.Tag();
- if (tag == DW_TAG_module)
- top_module_die = parent;
- else if (tag == DW_TAG_compile_unit)
- break;
- }
-
- return top_module_die;
+DWARFDIE::GetContainingDWOModuleDIE() const {
+ if (IsValid()) {
+ DWARFDIE top_module_die;
+ // Now make sure this DIE is scoped in a DW_TAG_module tag and return true
+ // if so
+ for (DWARFDIE parent = GetParent(); parent.IsValid();
+ parent = parent.GetParent()) {
+ const dw_tag_t tag = parent.Tag();
+ if (tag == DW_TAG_module)
+ top_module_die = parent;
+ else if (tag == DW_TAG_compile_unit)
+ break;
}
- return DWARFDIE();
+
+ return top_module_die;
+ }
+ return DWARFDIE();
}
-lldb::ModuleSP
-DWARFDIE::GetContainingDWOModule () const
-{
- if (IsValid())
- {
- DWARFDIE dwo_module_die = GetContainingDWOModuleDIE();
+lldb::ModuleSP DWARFDIE::GetContainingDWOModule() const {
+ if (IsValid()) {
+ DWARFDIE dwo_module_die = GetContainingDWOModuleDIE();
- if (dwo_module_die)
- {
- const char *module_name = dwo_module_die.GetName();
- if (module_name)
- return GetDWARF()->GetDWOModule (lldb_private::ConstString(module_name));
- }
+ if (dwo_module_die) {
+ const char *module_name = dwo_module_die.GetName();
+ if (module_name)
+ return GetDWARF()->GetDWOModule(lldb_private::ConstString(module_name));
}
- return lldb::ModuleSP();
+ }
+ return lldb::ModuleSP();
}
-bool
-DWARFDIE::HasChildren () const
-{
- if (m_die)
- return m_die->HasChildren();
- else
- return false;
-}
-
-bool
-DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type () const
-{
- if (IsValid())
- return GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
- else
- return false;
-}
-
-size_t
-DWARFDIE::GetAttributes (DWARFAttributes &attributes, uint32_t depth) const
-{
- if (IsValid())
- {
- return m_die->GetAttributes (m_cu,
- m_cu->GetFixedFormSizes(),
- attributes,
- depth);
- }
- if (depth == 0)
- attributes.Clear();
- return 0;
+bool DWARFDIE::HasChildren() const {
+ if (m_die)
+ return m_die->HasChildren();
+ else
+ return false;
}
-
-bool
-DWARFDIE::GetDIENamesAndRanges (const char * &name,
- const char * &mangled,
- DWARFRangeList& ranges,
- int& decl_file,
- int& decl_line,
- int& decl_column,
- int& call_file,
- int& call_line,
- int& call_column,
- lldb_private::DWARFExpression *frame_base) const
-{
- if (IsValid())
- {
- return m_die->GetDIENamesAndRanges (GetDWARF(),
- GetCU(),
- name,
- mangled,
- ranges,
- decl_file,
- decl_line,
- decl_column,
- call_file,
- call_line,
- call_column,
- frame_base);
- }
- else
- return false;
+bool DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
+ if (IsValid())
+ return GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
+ else
+ return false;
}
-void
-DWARFDIE::Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const
-{
- if (s && IsValid())
- m_die->Dump (GetDWARF(), GetCU(), *s, recurse_depth);
+size_t DWARFDIE::GetAttributes(DWARFAttributes &attributes,
+ uint32_t depth) const {
+ if (IsValid()) {
+ return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes,
+ depth);
+ }
+ if (depth == 0)
+ attributes.Clear();
+ return 0;
}
-
-CompilerDecl
-DWARFDIE::GetDecl () const
-{
- DWARFASTParser *dwarf_ast = GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclForUIDFromDWARF(*this);
- else
- return CompilerDecl();
+bool DWARFDIE::GetDIENamesAndRanges(
+ const char *&name, const char *&mangled, DWARFRangeList &ranges,
+ int &decl_file, int &decl_line, int &decl_column, int &call_file,
+ int &call_line, int &call_column,
+ lldb_private::DWARFExpression *frame_base) const {
+ if (IsValid()) {
+ return m_die->GetDIENamesAndRanges(
+ GetDWARF(), GetCU(), name, mangled, ranges, decl_file, decl_line,
+ decl_column, call_file, call_line, call_column, frame_base);
+ } else
+ return false;
}
-CompilerDeclContext
-DWARFDIE::GetDeclContext () const
-{
- DWARFASTParser *dwarf_ast = GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextForUIDFromDWARF(*this);
- else
- return CompilerDeclContext();
+void DWARFDIE::Dump(lldb_private::Stream *s,
+ const uint32_t recurse_depth) const {
+ if (s && IsValid())
+ m_die->Dump(GetDWARF(), GetCU(), *s, recurse_depth);
}
-CompilerDeclContext
-DWARFDIE::GetContainingDeclContext () const
-{
- DWARFASTParser *dwarf_ast = GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this);
- else
- return CompilerDeclContext();
+CompilerDecl DWARFDIE::GetDecl() const {
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclForUIDFromDWARF(*this);
+ else
+ return CompilerDecl();
}
-bool operator == (const DWARFDIE &lhs, const DWARFDIE &rhs)
-{
- return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
+CompilerDeclContext DWARFDIE::GetDeclContext() const {
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextForUIDFromDWARF(*this);
+ else
+ return CompilerDeclContext();
}
-bool operator != (const DWARFDIE &lhs, const DWARFDIE &rhs)
-{
- return lhs.GetDIE() != rhs.GetDIE() || lhs.GetCU() != rhs.GetCU();
+CompilerDeclContext DWARFDIE::GetContainingDeclContext() const {
+ DWARFASTParser *dwarf_ast = GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this);
+ else
+ return CompilerDeclContext();
}
+bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs) {
+ return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
+}
+bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
+ return lhs.GetDIE() != rhs.GetDIE() || lhs.GetCU() != rhs.GetCU();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 2dcd1d7dc43e..8af3015b9d76 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -10,8 +10,8 @@
#ifndef SymbolFileDWARF_DWARFDIE_h_
#define SymbolFileDWARF_DWARFDIE_h_
-#include "lldb/lldb-types.h"
#include "lldb/Core/dwarf.h"
+#include "lldb/lldb-types.h"
struct DIERef;
class DWARFASTParser;
@@ -22,274 +22,200 @@ class DWARFDeclContext;
class DWARFDIECollection;
class SymbolFileDWARF;
-class DWARFDIE
-{
+class DWARFDIE {
public:
- DWARFDIE () :
- m_cu (nullptr),
- m_die (nullptr)
- {
- }
+ DWARFDIE() : m_cu(nullptr), m_die(nullptr) {}
- DWARFDIE (DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) :
- m_cu (cu),
- m_die (die)
- {
- }
+ DWARFDIE(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die)
+ : m_cu(cu), m_die(die) {}
- DWARFDIE (const DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) :
- m_cu (const_cast<DWARFCompileUnit *>(cu)),
- m_die (die)
- {
- }
+ DWARFDIE(const DWARFCompileUnit *cu, DWARFDebugInfoEntry *die)
+ : m_cu(const_cast<DWARFCompileUnit *>(cu)), m_die(die) {}
- DWARFDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) :
- m_cu (cu),
- m_die (const_cast<DWARFDebugInfoEntry *>(die))
- {
- }
+ DWARFDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+ : m_cu(cu), m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
- DWARFDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) :
- m_cu (const_cast<DWARFCompileUnit *>(cu)),
- m_die (const_cast<DWARFDebugInfoEntry *>(die))
- {
- }
+ DWARFDIE(const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+ : m_cu(const_cast<DWARFCompileUnit *>(cu)),
+ m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
- //----------------------------------------------------------------------
- // Tests
- //----------------------------------------------------------------------
- explicit operator bool () const
- {
- return IsValid();
- }
+ //----------------------------------------------------------------------
+ // Tests
+ //----------------------------------------------------------------------
+ explicit operator bool() const { return IsValid(); }
- bool
- IsValid() const
- {
- return m_cu && m_die;
- }
+ bool IsValid() const { return m_cu && m_die; }
- bool
- IsStructOrClass () const;
+ bool IsStructOrClass() const;
- bool
- HasChildren () const;
+ bool HasChildren() const;
- bool
- Supports_DW_AT_APPLE_objc_complete_type () const;
+ bool Supports_DW_AT_APPLE_objc_complete_type() const;
- //----------------------------------------------------------------------
- // Accessors
- //----------------------------------------------------------------------
- SymbolFileDWARF *
- GetDWARF () const;
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+ SymbolFileDWARF *GetDWARF() const;
- DWARFCompileUnit *
- GetCU() const
- {
- return m_cu;
- }
+ DWARFCompileUnit *GetCU() const { return m_cu; }
- DWARFDebugInfoEntry *
- GetDIE() const
- {
- return m_die;
- }
+ DWARFDebugInfoEntry *GetDIE() const { return m_die; }
- DIERef
- GetDIERef() const;
-
- lldb_private::TypeSystem *
- GetTypeSystem () const;
-
- DWARFASTParser *
- GetDWARFParser () const;
-
- void
- Set (DWARFCompileUnit *cu, DWARFDebugInfoEntry *die)
- {
- if (cu && die)
- {
- m_cu = cu;
- m_die = die;
- }
- else
- {
- Clear();
- }
- }
+ DIERef GetDIERef() const;
- void
- Clear ()
- {
- m_cu = nullptr;
- m_die = nullptr;
+ lldb_private::TypeSystem *GetTypeSystem() const;
+
+ DWARFASTParser *GetDWARFParser() const;
+
+ void Set(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) {
+ if (cu && die) {
+ m_cu = cu;
+ m_die = die;
+ } else {
+ Clear();
}
+ }
+
+ void Clear() {
+ m_cu = nullptr;
+ m_die = nullptr;
+ }
+
+ lldb::ModuleSP GetContainingDWOModule() const;
- lldb::ModuleSP
- GetContainingDWOModule () const;
+ DWARFDIE
+ GetContainingDWOModuleDIE() const;
- DWARFDIE
- GetContainingDWOModuleDIE () const;
+ //----------------------------------------------------------------------
+ // Accessing information about a DIE
+ //----------------------------------------------------------------------
+ dw_tag_t Tag() const;
- //----------------------------------------------------------------------
- // Accessing information about a DIE
- //----------------------------------------------------------------------
- dw_tag_t
- Tag() const;
+ const char *GetTagAsCString() const;
- const char *
- GetTagAsCString () const;
+ dw_offset_t GetOffset() const;
- dw_offset_t
- GetOffset () const;
+ dw_offset_t GetCompileUnitRelativeOffset() const;
- dw_offset_t
- GetCompileUnitRelativeOffset () const;
+ //----------------------------------------------------------------------
+ // Get the LLDB user ID for this DIE. This is often just the DIE offset,
+ // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if
+ // we are doing Darwin DWARF in .o file, or DWARF stand alone debug
+ // info.
+ //----------------------------------------------------------------------
+ lldb::user_id_t GetID() const;
- //----------------------------------------------------------------------
- // Get the LLDB user ID for this DIE. This is often just the DIE offset,
- // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if
- // we are doing Darwin DWARF in .o file, or DWARF stand alone debug
- // info.
- //----------------------------------------------------------------------
- lldb::user_id_t
- GetID() const;
+ const char *GetName() const;
- const char *
- GetName () const;
+ const char *GetMangledName() const;
- const char *
- GetMangledName () const;
+ const char *GetPubname() const;
- const char *
- GetPubname () const;
+ const char *GetQualifiedName(std::string &storage) const;
- const char *
- GetQualifiedName (std::string &storage) const;
+ lldb::LanguageType GetLanguage() const;
- lldb::LanguageType
- GetLanguage () const;
+ lldb::ModuleSP GetModule() const;
- lldb::ModuleSP
- GetModule () const;
+ lldb_private::CompileUnit *GetLLDBCompileUnit() const;
- lldb_private::CompileUnit *
- GetLLDBCompileUnit () const;
+ lldb_private::Type *ResolveType() const;
- lldb_private::Type *
- ResolveType () const;
+ //----------------------------------------------------------------------
+ // Resolve a type by UID using this DIE's DWARF file
+ //----------------------------------------------------------------------
+ lldb_private::Type *ResolveTypeUID(const DIERef &die_ref) const;
- //----------------------------------------------------------------------
- // Resolve a type by UID using this DIE's DWARF file
- //----------------------------------------------------------------------
- lldb_private::Type *
- ResolveTypeUID (const DIERef &die_ref) const;
+ //----------------------------------------------------------------------
+ // Functions for obtaining DIE relations and references
+ //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- // Functions for obtaining DIE relations and references
- //----------------------------------------------------------------------
+ DWARFDIE
+ GetParent() const;
- DWARFDIE
- GetParent () const;
+ DWARFDIE
+ GetFirstChild() const;
- DWARFDIE
- GetFirstChild () const;
+ DWARFDIE
+ GetSibling() const;
- DWARFDIE
- GetSibling () const;
+ DWARFDIE
+ GetReferencedDIE(const dw_attr_t attr) const;
- DWARFDIE
- GetReferencedDIE (const dw_attr_t attr) const;
+ //----------------------------------------------------------------------
+ // Get a another DIE from the same DWARF file as this DIE. This will
+ // check the current DIE's compile unit first to see if "die_offset" is
+ // in the same compile unit, and fall back to checking the DWARF file.
+ //----------------------------------------------------------------------
+ DWARFDIE
+ GetDIE(dw_offset_t die_offset) const;
- //----------------------------------------------------------------------
- // Get a another DIE from the same DWARF file as this DIE. This will
- // check the current DIE's compile unit first to see if "die_offset" is
- // in the same compile unit, and fall back to checking the DWARF file.
- //----------------------------------------------------------------------
- DWARFDIE
- GetDIE (dw_offset_t die_offset) const;
+ DWARFDIE
+ LookupDeepestBlock(lldb::addr_t file_addr) const;
- DWARFDIE
- LookupDeepestBlock (lldb::addr_t file_addr) const;
+ DWARFDIE
+ GetParentDeclContextDIE() const;
- DWARFDIE
- GetParentDeclContextDIE () const;
+ //----------------------------------------------------------------------
+ // DeclContext related functions
+ //----------------------------------------------------------------------
+ void GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const;
- //----------------------------------------------------------------------
- // DeclContext related functions
- //----------------------------------------------------------------------
- void
- GetDeclContextDIEs (DWARFDIECollection &decl_context_dies) const;
+ void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const;
- void
- GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const;
+ void GetDWOContext(std::vector<lldb_private::CompilerContext> &context) const;
- void
- GetDWOContext (std::vector<lldb_private::CompilerContext> &context) const;
+ //----------------------------------------------------------------------
+ // Getting attribute values from the DIE.
+ //
+ // GetAttributeValueAsXXX() functions should only be used if you are
+ // looking for one or two attributes on a DIE. If you are trying to
+ // parse all attributes, use GetAttributes (...) instead
+ //----------------------------------------------------------------------
+ const char *GetAttributeValueAsString(const dw_attr_t attr,
+ const char *fail_value) const;
- //----------------------------------------------------------------------
- // Getting attribute values from the DIE.
- //
- // GetAttributeValueAsXXX() functions should only be used if you are
- // looking for one or two attributes on a DIE. If you are trying to
- // parse all attributes, use GetAttributes (...) instead
- //----------------------------------------------------------------------
- const char *
- GetAttributeValueAsString (const dw_attr_t attr, const char *fail_value) const;
+ uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr,
+ uint64_t fail_value) const;
- uint64_t
- GetAttributeValueAsUnsigned (const dw_attr_t attr, uint64_t fail_value) const;
+ int64_t GetAttributeValueAsSigned(const dw_attr_t attr,
+ int64_t fail_value) const;
- int64_t
- GetAttributeValueAsSigned (const dw_attr_t attr, int64_t fail_value) const;
+ uint64_t GetAttributeValueAsReference(const dw_attr_t attr,
+ uint64_t fail_value) const;
- uint64_t
- GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const;
+ DWARFDIE
+ GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
- DWARFDIE
- GetAttributeValueAsReferenceDIE (const dw_attr_t attr) const;
+ uint64_t GetAttributeValueAsAddress(const dw_attr_t attr,
+ uint64_t fail_value) const;
- uint64_t
- GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const;
+ size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const;
- size_t
- GetAttributes (DWARFAttributes &attributes, uint32_t depth = 0) const;
+ bool GetDIENamesAndRanges(const char *&name, const char *&mangled,
+ DWARFRangeList &ranges, int &decl_file,
+ int &decl_line, int &decl_column, int &call_file,
+ int &call_line, int &call_column,
+ lldb_private::DWARFExpression *frame_base) const;
- bool
- GetDIENamesAndRanges (const char * &name,
- const char * &mangled,
- DWARFRangeList& ranges,
- int& decl_file,
- int& decl_line,
- int& decl_column,
- int& call_file,
- int& call_line,
- int& call_column,
- lldb_private::DWARFExpression *frame_base) const;
+ //----------------------------------------------------------------------
+ // Pretty printing
+ //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- // Pretty printing
- //----------------------------------------------------------------------
+ void Dump(lldb_private::Stream *s, const uint32_t recurse_depth) const;
- void
- Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const;
+ lldb_private::CompilerDecl GetDecl() const;
- lldb_private::CompilerDecl
- GetDecl () const;
+ lldb_private::CompilerDeclContext GetDeclContext() const;
- lldb_private::CompilerDeclContext
- GetDeclContext() const;
-
- lldb_private::CompilerDeclContext
- GetContainingDeclContext() const;
+ lldb_private::CompilerDeclContext GetContainingDeclContext() const;
protected:
- DWARFCompileUnit *m_cu;
- DWARFDebugInfoEntry *m_die;
+ DWARFCompileUnit *m_cu;
+ DWARFDebugInfoEntry *m_die;
};
-bool operator == (const DWARFDIE &lhs, const DWARFDIE &rhs);
-bool operator != (const DWARFDIE &lhs, const DWARFDIE &rhs);
+bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs);
+bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs);
-#endif // SymbolFileDWARF_DWARFDIE_h_
+#endif // SymbolFileDWARF_DWARFDIE_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
index e9f09fd8776c..5fb63589591e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
@@ -16,32 +16,20 @@
using namespace lldb_private;
using namespace std;
-void
-DWARFDIECollection::Append (const DWARFDIE &die)
-{
- m_dies.push_back (die);
-}
+void DWARFDIECollection::Append(const DWARFDIE &die) { m_dies.push_back(die); }
DWARFDIE
-DWARFDIECollection::GetDIEAtIndex(uint32_t idx) const
-{
- if (idx < m_dies.size())
- return m_dies[idx];
- return DWARFDIE();
+DWARFDIECollection::GetDIEAtIndex(uint32_t idx) const {
+ if (idx < m_dies.size())
+ return m_dies[idx];
+ return DWARFDIE();
}
+size_t DWARFDIECollection::Size() const { return m_dies.size(); }
-size_t
-DWARFDIECollection::Size() const
-{
- return m_dies.size();
-}
-
-void
-DWARFDIECollection::Dump(Stream *s, const char* title) const
-{
- if (title && title[0] != '\0')
- s->Printf( "%s\n", title);
- for (const auto &die : m_dies)
- s->Printf( "0x%8.8x\n", die.GetOffset());
+void DWARFDIECollection::Dump(Stream *s, const char *title) const {
+ if (title && title[0] != '\0')
+ s->Printf("%s\n", title);
+ for (const auto &die : m_dies)
+ s->Printf("0x%8.8x\n", die.GetOffset());
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
index 83d58ec49300..e1e73e71ae7f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
@@ -13,36 +13,26 @@
#include "DWARFDIE.h"
#include <vector>
-class DWARFDIECollection
-{
+class DWARFDIECollection {
public:
- DWARFDIECollection() :
- m_dies()
- {
- }
- ~DWARFDIECollection()
- {
- }
+ DWARFDIECollection() : m_dies() {}
+ ~DWARFDIECollection() {}
- void
- Append (const DWARFDIE &die);
+ void Append(const DWARFDIE &die);
- void
- Dump(lldb_private::Stream *s, const char* title) const;
+ void Dump(lldb_private::Stream *s, const char *title) const;
- DWARFDIE
- GetDIEAtIndex (uint32_t idx) const;
+ DWARFDIE
+ GetDIEAtIndex(uint32_t idx) const;
- size_t
- Size() const;
+ size_t Size() const;
protected:
- typedef std::vector<DWARFDIE> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
+ typedef std::vector<DWARFDIE> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
- collection m_dies; // Ordered list of die offsets
+ collection m_dies; // Ordered list of die offsets
};
-
-#endif // SymbolFileDWARF_DWARFDIECollection_h_
+#endif // SymbolFileDWARF_DWARFDIECollection_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
index 9bf47cd7a9ac..0c807d7d604b 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
@@ -12,19 +12,16 @@
namespace lldb_private {
uint64_t
-DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const
-{
- uint64_t length = GetU32(offset_ptr);
- m_is_dwarf64 = (length == UINT32_MAX);
- if (m_is_dwarf64)
- length = GetU64(offset_ptr);
- return length;
+DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const {
+ uint64_t length = GetU32(offset_ptr);
+ m_is_dwarf64 = (length == UINT32_MAX);
+ if (m_is_dwarf64)
+ length = GetU64(offset_ptr);
+ return length;
}
dw_offset_t
-DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const
-{
- return GetMaxU64(offset_ptr, m_is_dwarf64 ? 8 : 4);
+DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
+ return GetMaxU64(offset_ptr, m_is_dwarf64 ? 8 : 4);
}
-
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
index 0281b5ad5c89..62ddbe8ecd5a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DWARFDataExtractor_h_
-#define liblldb_DWARFDataExtractor_h_
+#ifndef liblldb_DWARFDataExtractor_h_
+#define liblldb_DWARFDataExtractor_h_
// Other libraries and framework includes.
#include "lldb/Core/DataExtractor.h"
@@ -16,30 +16,25 @@
namespace lldb_private {
-class DWARFDataExtractor : public lldb_private::DataExtractor
-{
+class DWARFDataExtractor : public lldb_private::DataExtractor {
public:
- DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) { }
+ DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) {}
- DWARFDataExtractor (const DWARFDataExtractor& data, lldb::offset_t offset, lldb::offset_t length) :
- DataExtractor(data, offset, length), m_is_dwarf64(false) { }
+ DWARFDataExtractor(const DWARFDataExtractor &data, lldb::offset_t offset,
+ lldb::offset_t length)
+ : DataExtractor(data, offset, length), m_is_dwarf64(false) {}
- uint64_t
- GetDWARFInitialLength(lldb::offset_t *offset_ptr) const;
+ uint64_t GetDWARFInitialLength(lldb::offset_t *offset_ptr) const;
- dw_offset_t
- GetDWARFOffset(lldb::offset_t *offset_ptr) const;
+ dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
- size_t
- GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
+ size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
- bool
- IsDWARF64() const { return m_is_dwarf64; }
+ bool IsDWARF64() const { return m_is_dwarf64; }
protected:
- mutable bool m_is_dwarf64;
+ mutable bool m_is_dwarf64;
};
-
}
-#endif // liblldb_DWARFDataExtractor_h_
+#endif // liblldb_DWARFDataExtractor_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
index 6773d0762a21..fe6df913b762 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -18,74 +18,63 @@ using namespace std;
//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Clear()
//----------------------------------------------------------------------
-void
-DWARFAbbreviationDeclarationSet::Clear()
-{
- m_idx_offset = 0;
- m_decls.clear();
+void DWARFAbbreviationDeclarationSet::Clear() {
+ m_idx_offset = 0;
+ m_decls.clear();
}
-
//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Extract()
//----------------------------------------------------------------------
-bool
-DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr)
-{
- const lldb::offset_t begin_offset = *offset_ptr;
- m_offset = begin_offset;
- Clear();
- DWARFAbbreviationDeclaration abbrevDeclaration;
- dw_uleb128_t prev_abbr_code = 0;
- while (abbrevDeclaration.Extract(data, offset_ptr))
- {
- m_decls.push_back(abbrevDeclaration);
- if (m_idx_offset == 0)
- m_idx_offset = abbrevDeclaration.Code();
- else
- {
- if (prev_abbr_code + 1 != abbrevDeclaration.Code())
- m_idx_offset = UINT32_MAX; // Out of order indexes, we can't do O(1) lookups...
- }
- prev_abbr_code = abbrevDeclaration.Code();
+bool DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ const lldb::offset_t begin_offset = *offset_ptr;
+ m_offset = begin_offset;
+ Clear();
+ DWARFAbbreviationDeclaration abbrevDeclaration;
+ dw_uleb128_t prev_abbr_code = 0;
+ while (abbrevDeclaration.Extract(data, offset_ptr)) {
+ m_decls.push_back(abbrevDeclaration);
+ if (m_idx_offset == 0)
+ m_idx_offset = abbrevDeclaration.Code();
+ else {
+ if (prev_abbr_code + 1 != abbrevDeclaration.Code())
+ m_idx_offset =
+ UINT32_MAX; // Out of order indexes, we can't do O(1) lookups...
}
- return begin_offset != *offset_ptr;
+ prev_abbr_code = abbrevDeclaration.Code();
+ }
+ return begin_offset != *offset_ptr;
}
-
//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Dump()
//----------------------------------------------------------------------
-void
-DWARFAbbreviationDeclarationSet::Dump(Stream *s) const
-{
- std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
+void DWARFAbbreviationDeclarationSet::Dump(Stream *s) const {
+ std::for_each(
+ m_decls.begin(), m_decls.end(),
+ bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump), s));
}
-
//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
//----------------------------------------------------------------------
-const DWARFAbbreviationDeclaration*
-DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
-{
- if (m_idx_offset == UINT32_MAX)
- {
- DWARFAbbreviationDeclarationCollConstIter pos;
- DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
- for (pos = m_decls.begin(); pos != end; ++pos)
- {
- if (pos->Code() == abbrCode)
- return &(*pos);
- }
- }
- else
- {
- uint32_t idx = abbrCode - m_idx_offset;
- if (idx < m_decls.size())
- return &m_decls[idx];
+const DWARFAbbreviationDeclaration *
+DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(
+ dw_uleb128_t abbrCode) const {
+ if (m_idx_offset == UINT32_MAX) {
+ DWARFAbbreviationDeclarationCollConstIter pos;
+ DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
+ for (pos = m_decls.begin(); pos != end; ++pos) {
+ if (pos->Code() == abbrCode)
+ return &(*pos);
}
- return NULL;
+ } else {
+ uint32_t idx = abbrCode - m_idx_offset;
+ if (idx < m_decls.size())
+ return &m_decls[idx];
+ }
+ return NULL;
}
//----------------------------------------------------------------------
@@ -94,22 +83,20 @@ DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCod
// Append an abbreviation declaration with a sequential code for O(n)
// lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
//----------------------------------------------------------------------
-dw_uleb128_t
-DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
-{
- // Get the next abbreviation code based on our current array size
- dw_uleb128_t code = m_decls.size()+1;
+dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(
+ const DWARFAbbreviationDeclaration &abbrevDecl) {
+ // Get the next abbreviation code based on our current array size
+ dw_uleb128_t code = m_decls.size() + 1;
- // Push the new declaration on the back
- m_decls.push_back(abbrevDecl);
+ // Push the new declaration on the back
+ m_decls.push_back(abbrevDecl);
- // Update the code for this new declaration
- m_decls.back().SetCode(code);
+ // Update the code for this new declaration
+ m_decls.back().SetCode(code);
- return code; // return the new abbreviation code!
+ return code; // return the new abbreviation code!
}
-
//----------------------------------------------------------------------
// Encode
//
@@ -117,8 +104,9 @@ DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviat
// into a byte representation as would be found in a ".debug_abbrev"
// debug information section.
//----------------------------------------------------------------------
-//void
-//DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const
+// void
+// DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf)
+// const
//{
// DWARFAbbreviationDeclarationCollConstIter pos;
// DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
@@ -127,76 +115,63 @@ DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviat
// debug_abbrev_buf.Append8(0);
//}
-
//----------------------------------------------------------------------
// DWARFDebugAbbrev constructor
//----------------------------------------------------------------------
-DWARFDebugAbbrev::DWARFDebugAbbrev() :
- m_abbrevCollMap(),
- m_prev_abbr_offset_pos(m_abbrevCollMap.end())
-{
-}
-
+DWARFDebugAbbrev::DWARFDebugAbbrev()
+ : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
//----------------------------------------------------------------------
// DWARFDebugAbbrev::Parse()
//----------------------------------------------------------------------
-void
-DWARFDebugAbbrev::Parse(const DWARFDataExtractor& data)
-{
- lldb::offset_t offset = 0;
+void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) {
+ lldb::offset_t offset = 0;
- while (data.ValidOffset(offset))
- {
- uint32_t initial_cu_offset = offset;
- DWARFAbbreviationDeclarationSet abbrevDeclSet;
+ while (data.ValidOffset(offset)) {
+ uint32_t initial_cu_offset = offset;
+ DWARFAbbreviationDeclarationSet abbrevDeclSet;
- if (abbrevDeclSet.Extract(data, &offset))
- m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
- else
- break;
- }
- m_prev_abbr_offset_pos = m_abbrevCollMap.end();
+ if (abbrevDeclSet.Extract(data, &offset))
+ m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
+ else
+ break;
+ }
+ m_prev_abbr_offset_pos = m_abbrevCollMap.end();
}
//----------------------------------------------------------------------
// DWARFDebugAbbrev::Dump()
//----------------------------------------------------------------------
-void
-DWARFDebugAbbrev::Dump(Stream *s) const
-{
- if (m_abbrevCollMap.empty())
- {
- s->PutCString("< EMPTY >\n");
- return;
- }
-
- DWARFAbbreviationDeclarationCollMapConstIter pos;
- for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
- {
- s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
- pos->second.Dump(s);
- }
+void DWARFDebugAbbrev::Dump(Stream *s) const {
+ if (m_abbrevCollMap.empty()) {
+ s->PutCString("< EMPTY >\n");
+ return;
+ }
+
+ DWARFAbbreviationDeclarationCollMapConstIter pos;
+ for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) {
+ s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
+ pos->second.Dump(s);
+ }
}
-
//----------------------------------------------------------------------
// DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
//----------------------------------------------------------------------
-const DWARFAbbreviationDeclarationSet*
-DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
-{
- DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
- DWARFAbbreviationDeclarationCollMapConstIter pos;
- if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset)
- return &(m_prev_abbr_offset_pos->second);
- else
- {
- pos = m_abbrevCollMap.find(cu_abbr_offset);
- m_prev_abbr_offset_pos = pos;
- }
-
- if (pos != m_abbrevCollMap.end())
- return &(pos->second);
- return NULL;
+const DWARFAbbreviationDeclarationSet *
+DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
+ dw_offset_t cu_abbr_offset) const {
+ DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
+ DWARFAbbreviationDeclarationCollMapConstIter pos;
+ if (m_prev_abbr_offset_pos != end &&
+ m_prev_abbr_offset_pos->first == cu_abbr_offset)
+ return &(m_prev_abbr_offset_pos->second);
+ else {
+ pos = m_abbrevCollMap.find(cu_abbr_offset);
+ m_prev_abbr_offset_pos = pos;
+ }
+
+ if (pos != m_abbrevCollMap.end())
+ return &(pos->second);
+ return NULL;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 8ec2c4ba8e21..137c81780513 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -15,60 +15,60 @@
#include "lldb/lldb-private.h"
-#include "DWARFDefines.h"
#include "DWARFAbbreviationDeclaration.h"
+#include "DWARFDefines.h"
-typedef std::vector<DWARFAbbreviationDeclaration> DWARFAbbreviationDeclarationColl;
-typedef DWARFAbbreviationDeclarationColl::iterator DWARFAbbreviationDeclarationCollIter;
-typedef DWARFAbbreviationDeclarationColl::const_iterator DWARFAbbreviationDeclarationCollConstIter;
-
+typedef std::vector<DWARFAbbreviationDeclaration>
+ DWARFAbbreviationDeclarationColl;
+typedef DWARFAbbreviationDeclarationColl::iterator
+ DWARFAbbreviationDeclarationCollIter;
+typedef DWARFAbbreviationDeclarationColl::const_iterator
+ DWARFAbbreviationDeclarationCollConstIter;
-class DWARFAbbreviationDeclarationSet
-{
+class DWARFAbbreviationDeclarationSet {
public:
- DWARFAbbreviationDeclarationSet() :
- m_offset(DW_INVALID_OFFSET),
- m_idx_offset(0),
- m_decls()
- {
- }
+ DWARFAbbreviationDeclarationSet()
+ : m_offset(DW_INVALID_OFFSET), m_idx_offset(0), m_decls() {}
- DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset) :
- m_offset(offset),
- m_idx_offset(idx_offset),
- m_decls()
- {
- }
+ DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset)
+ : m_offset(offset), m_idx_offset(idx_offset), m_decls() {}
- void Clear();
- dw_offset_t GetOffset() const { return m_offset; }
- void Dump(lldb_private::Stream *s) const;
- bool Extract(const lldb_private::DWARFDataExtractor& data, lldb::offset_t *offset_ptr);
- //void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
- dw_uleb128_t AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl);
+ void Clear();
+ dw_offset_t GetOffset() const { return m_offset; }
+ void Dump(lldb_private::Stream *s) const;
+ bool Extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+ // void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
+ dw_uleb128_t
+ AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration &abbrevDecl);
+
+ const DWARFAbbreviationDeclaration *
+ GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const;
- const DWARFAbbreviationDeclaration* GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const;
private:
- dw_offset_t m_offset;
- uint32_t m_idx_offset;
- std::vector<DWARFAbbreviationDeclaration> m_decls;
+ dw_offset_t m_offset;
+ uint32_t m_idx_offset;
+ std::vector<DWARFAbbreviationDeclaration> m_decls;
};
-typedef std::map<dw_offset_t, DWARFAbbreviationDeclarationSet> DWARFAbbreviationDeclarationCollMap;
-typedef DWARFAbbreviationDeclarationCollMap::iterator DWARFAbbreviationDeclarationCollMapIter;
-typedef DWARFAbbreviationDeclarationCollMap::const_iterator DWARFAbbreviationDeclarationCollMapConstIter;
-
+typedef std::map<dw_offset_t, DWARFAbbreviationDeclarationSet>
+ DWARFAbbreviationDeclarationCollMap;
+typedef DWARFAbbreviationDeclarationCollMap::iterator
+ DWARFAbbreviationDeclarationCollMapIter;
+typedef DWARFAbbreviationDeclarationCollMap::const_iterator
+ DWARFAbbreviationDeclarationCollMapConstIter;
-class DWARFDebugAbbrev
-{
+class DWARFDebugAbbrev {
public:
- DWARFDebugAbbrev();
- const DWARFAbbreviationDeclarationSet* GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
- void Dump(lldb_private::Stream *s) const;
- void Parse(const lldb_private::DWARFDataExtractor& data);
+ DWARFDebugAbbrev();
+ const DWARFAbbreviationDeclarationSet *
+ GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
+ void Dump(lldb_private::Stream *s) const;
+ void Parse(const lldb_private::DWARFDataExtractor &data);
+
protected:
- DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;
- mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos;
+ DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;
+ mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos;
};
-#endif // SymbolFileDWARF_DWARFDebugAbbrev_h_
+#endif // SymbolFileDWARF_DWARFDebugAbbrev_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
index b0b71368b800..06b46f0569eb 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -9,302 +9,262 @@
#include "DWARFDebugArangeSet.h"
-#include <assert.h>
-#include "lldb/Core/Stream.h"
#include "SymbolFileDWARF.h"
+#include "lldb/Core/Stream.h"
+#include <assert.h>
using namespace lldb_private;
-DWARFDebugArangeSet::DWARFDebugArangeSet() :
- m_offset(DW_INVALID_OFFSET),
- m_header(),
- m_arange_descriptors()
-{
- m_header.length = 0;
- m_header.version = 0;
- m_header.cu_offset = 0;
- m_header.addr_size = 0;
- m_header.seg_size = 0;
+DWARFDebugArangeSet::DWARFDebugArangeSet()
+ : m_offset(DW_INVALID_OFFSET), m_header(), m_arange_descriptors() {
+ m_header.length = 0;
+ m_header.version = 0;
+ m_header.cu_offset = 0;
+ m_header.addr_size = 0;
+ m_header.seg_size = 0;
}
-void
-DWARFDebugArangeSet::Clear()
-{
- m_offset = DW_INVALID_OFFSET;
- m_header.length = 0;
- m_header.version = 0;
- m_header.cu_offset = 0;
- m_header.addr_size = 0;
- m_header.seg_size = 0;
- m_arange_descriptors.clear();
+void DWARFDebugArangeSet::Clear() {
+ m_offset = DW_INVALID_OFFSET;
+ m_header.length = 0;
+ m_header.version = 0;
+ m_header.cu_offset = 0;
+ m_header.addr_size = 0;
+ m_header.seg_size = 0;
+ m_arange_descriptors.clear();
}
-void
-DWARFDebugArangeSet::SetHeader
-(
- uint16_t version,
- uint32_t cu_offset,
- uint8_t addr_size,
- uint8_t seg_size
-)
-{
- m_header.version = version;
- m_header.cu_offset = cu_offset;
- m_header.addr_size = addr_size;
- m_header.seg_size = seg_size;
+void DWARFDebugArangeSet::SetHeader(uint16_t version, uint32_t cu_offset,
+ uint8_t addr_size, uint8_t seg_size) {
+ m_header.version = version;
+ m_header.cu_offset = cu_offset;
+ m_header.addr_size = addr_size;
+ m_header.seg_size = seg_size;
}
-void
-DWARFDebugArangeSet::Compact()
-{
- if (m_arange_descriptors.empty())
- return;
+void DWARFDebugArangeSet::Compact() {
+ if (m_arange_descriptors.empty())
+ return;
- // Iterate through all arange descriptors and combine any ranges that
- // overlap or have matching boundaries. The m_arange_descriptors are assumed
- // to be in ascending order after being built by adding descriptors
- // using the AddDescriptor method.
- uint32_t i = 0;
- while (i + 1 < m_arange_descriptors.size())
- {
- if (m_arange_descriptors[i].end_address() >= m_arange_descriptors[i+1].address)
- {
- // The current range ends at or exceeds the start of the next address range.
- // Compute the max end address between the two and use that to make the new
- // length.
- const dw_addr_t max_end_addr = std::max(m_arange_descriptors[i].end_address(), m_arange_descriptors[i+1].end_address());
- m_arange_descriptors[i].length = max_end_addr - m_arange_descriptors[i].address;
- // Now remove the next entry as it was just combined with the previous one.
- m_arange_descriptors.erase(m_arange_descriptors.begin()+i+1);
- }
- else
- {
- // Discontiguous address range, just proceed to the next one.
- ++i;
- }
+ // Iterate through all arange descriptors and combine any ranges that
+ // overlap or have matching boundaries. The m_arange_descriptors are assumed
+ // to be in ascending order after being built by adding descriptors
+ // using the AddDescriptor method.
+ uint32_t i = 0;
+ while (i + 1 < m_arange_descriptors.size()) {
+ if (m_arange_descriptors[i].end_address() >=
+ m_arange_descriptors[i + 1].address) {
+ // The current range ends at or exceeds the start of the next address
+ // range.
+ // Compute the max end address between the two and use that to make the
+ // new
+ // length.
+ const dw_addr_t max_end_addr =
+ std::max(m_arange_descriptors[i].end_address(),
+ m_arange_descriptors[i + 1].end_address());
+ m_arange_descriptors[i].length =
+ max_end_addr - m_arange_descriptors[i].address;
+ // Now remove the next entry as it was just combined with the previous
+ // one.
+ m_arange_descriptors.erase(m_arange_descriptors.begin() + i + 1);
+ } else {
+ // Discontiguous address range, just proceed to the next one.
+ ++i;
}
+ }
}
//----------------------------------------------------------------------
// Compare function DWARFDebugArangeSet::Descriptor structures
//----------------------------------------------------------------------
-static bool DescriptorLessThan (const DWARFDebugArangeSet::Descriptor& range1, const DWARFDebugArangeSet::Descriptor& range2)
-{
- return range1.address < range2.address;
+static bool DescriptorLessThan(const DWARFDebugArangeSet::Descriptor &range1,
+ const DWARFDebugArangeSet::Descriptor &range2) {
+ return range1.address < range2.address;
}
//----------------------------------------------------------------------
// Add a range descriptor and keep things sorted so we can easily
// compact the ranges before being saved or used.
//----------------------------------------------------------------------
-void
-DWARFDebugArangeSet::AddDescriptor(const DWARFDebugArangeSet::Descriptor& range)
-{
- if (m_arange_descriptors.empty())
- {
- m_arange_descriptors.push_back(range);
- return;
- }
+void DWARFDebugArangeSet::AddDescriptor(
+ const DWARFDebugArangeSet::Descriptor &range) {
+ if (m_arange_descriptors.empty()) {
+ m_arange_descriptors.push_back(range);
+ return;
+ }
- DescriptorIter end = m_arange_descriptors.end();
- DescriptorIter pos = lower_bound(m_arange_descriptors.begin(), end, range, DescriptorLessThan);
- const dw_addr_t range_end_addr = range.end_address();
- if (pos != end)
- {
- const dw_addr_t found_end_addr = pos->end_address();
- if (range.address < pos->address)
- {
- if (range_end_addr < pos->address)
- {
- // Non-contiguous entries, add this one before the found entry
- m_arange_descriptors.insert(pos, range);
- }
- else if (range_end_addr == pos->address)
- {
- // The top end of 'range' is the lower end of the entry
- // pointed to by 'pos'. We can combine range with the
- // entry we found by setting the starting address and
- // increasing the length since they don't overlap.
- pos->address = range.address;
- pos->length += range.length;
- }
- else
- {
- // We can combine these two and make sure the largest end
- // address is used to make end address.
- pos->address = range.address;
- pos->length = std::max(found_end_addr, range_end_addr) - pos->address;
- }
- }
- else if (range.address == pos->address)
- {
- pos->length = std::max(pos->length, range.length);
- }
+ DescriptorIter end = m_arange_descriptors.end();
+ DescriptorIter pos =
+ lower_bound(m_arange_descriptors.begin(), end, range, DescriptorLessThan);
+ const dw_addr_t range_end_addr = range.end_address();
+ if (pos != end) {
+ const dw_addr_t found_end_addr = pos->end_address();
+ if (range.address < pos->address) {
+ if (range_end_addr < pos->address) {
+ // Non-contiguous entries, add this one before the found entry
+ m_arange_descriptors.insert(pos, range);
+ } else if (range_end_addr == pos->address) {
+ // The top end of 'range' is the lower end of the entry
+ // pointed to by 'pos'. We can combine range with the
+ // entry we found by setting the starting address and
+ // increasing the length since they don't overlap.
+ pos->address = range.address;
+ pos->length += range.length;
+ } else {
+ // We can combine these two and make sure the largest end
+ // address is used to make end address.
+ pos->address = range.address;
+ pos->length = std::max(found_end_addr, range_end_addr) - pos->address;
+ }
+ } else if (range.address == pos->address) {
+ pos->length = std::max(pos->length, range.length);
}
- else
- {
- // NOTE: 'pos' points to entry past the end which is ok for insert,
- // don't use otherwise!!!
- const dw_addr_t max_addr = m_arange_descriptors.back().end_address();
- if (max_addr < range.address)
- {
- // Non-contiguous entries, add this one before the found entry
- m_arange_descriptors.insert(pos, range);
- }
- else if (max_addr == range.address)
- {
- m_arange_descriptors.back().length += range.length;
- }
- else
- {
- m_arange_descriptors.back().length = std::max(max_addr, range_end_addr) - m_arange_descriptors.back().address;
- }
+ } else {
+ // NOTE: 'pos' points to entry past the end which is ok for insert,
+ // don't use otherwise!!!
+ const dw_addr_t max_addr = m_arange_descriptors.back().end_address();
+ if (max_addr < range.address) {
+ // Non-contiguous entries, add this one before the found entry
+ m_arange_descriptors.insert(pos, range);
+ } else if (max_addr == range.address) {
+ m_arange_descriptors.back().length += range.length;
+ } else {
+ m_arange_descriptors.back().length = std::max(max_addr, range_end_addr) -
+ m_arange_descriptors.back().address;
}
+ }
}
-bool
-DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data, lldb::offset_t *offset_ptr)
-{
- if (data.ValidOffset(*offset_ptr))
- {
- m_arange_descriptors.clear();
- m_offset = *offset_ptr;
+bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ if (data.ValidOffset(*offset_ptr)) {
+ m_arange_descriptors.clear();
+ m_offset = *offset_ptr;
- // 7.20 Address Range Table
- //
- // Each set of entries in the table of address ranges contained in
- // the .debug_aranges section begins with a header consisting of: a
- // 4-byte length containing the length of the set of entries for this
- // compilation unit, not including the length field itself; a 2-byte
- // version identifier containing the value 2 for DWARF Version 2; a
- // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
- // containing the size in bytes of an address (or the offset portion of
- // an address for segmented addressing) on the target system; and a
- // 1-byte unsigned integer containing the size in bytes of a segment
- // descriptor on the target system. This header is followed by a series
- // of tuples. Each tuple consists of an address and a length, each in
- // the size appropriate for an address on the target architecture.
- m_header.length = data.GetDWARFInitialLength(offset_ptr);
- m_header.version = data.GetU16(offset_ptr);
- m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
- m_header.addr_size = data.GetU8(offset_ptr);
- m_header.seg_size = data.GetU8(offset_ptr);
-
- // Try to avoid reading invalid arange sets by making sure:
- // 1 - the version looks good
- // 2 - the address byte size looks plausible
- // 3 - the length seems to make sense
- // size looks plausible
- if ((m_header.version >= 2 && m_header.version <= 5) &&
- (m_header.addr_size == 4 || m_header.addr_size == 8) &&
- (m_header.length > 0))
- {
- if (data.ValidOffset(m_offset + sizeof(m_header.length) + m_header.length - 1))
- {
- // The first tuple following the header in each set begins at an offset
- // that is a multiple of the size of a single tuple (that is, twice the
- // size of an address). The header is padded, if necessary, to the
- // appropriate boundary.
- const uint32_t header_size = *offset_ptr - m_offset;
- const uint32_t tuple_size = m_header.addr_size << 1;
- uint32_t first_tuple_offset = 0;
- while (first_tuple_offset < header_size)
- first_tuple_offset += tuple_size;
-
- *offset_ptr = m_offset + first_tuple_offset;
-
- Descriptor arangeDescriptor;
-
- static_assert(sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length),
- "DWARFDebugArangeSet::Descriptor.address and DWARFDebugArangeSet::Descriptor.length must have same size");
-
- while (data.ValidOffset(*offset_ptr))
- {
- arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size);
- arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size);
-
- // Each set of tuples is terminated by a 0 for the address and 0
- // for the length.
- if (arangeDescriptor.address || arangeDescriptor.length)
- m_arange_descriptors.push_back(arangeDescriptor);
- else
- break; // We are done if we get a zero address and length
- }
- }
-#if defined (LLDB_CONFIGURATION_DEBUG)
- else
- {
- printf ("warning: .debug_arange set length is too large arange data at 0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, addr_size=%u, seg_size=%u\n",
- m_offset,
- m_header.length,
- m_header.version,
- m_header.cu_offset,
- m_header.addr_size,
- m_header.seg_size);
- }
-#endif
- }
-#if defined (LLDB_CONFIGURATION_DEBUG)
- else
- {
- printf ("warning: .debug_arange set has bad header at 0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, addr_size=%u, seg_size=%u\n",
- m_offset,
- m_header.length,
- m_header.version,
- m_header.cu_offset,
- m_header.addr_size,
- m_header.seg_size);
+ // 7.20 Address Range Table
+ //
+ // Each set of entries in the table of address ranges contained in
+ // the .debug_aranges section begins with a header consisting of: a
+ // 4-byte length containing the length of the set of entries for this
+ // compilation unit, not including the length field itself; a 2-byte
+ // version identifier containing the value 2 for DWARF Version 2; a
+ // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
+ // containing the size in bytes of an address (or the offset portion of
+ // an address for segmented addressing) on the target system; and a
+ // 1-byte unsigned integer containing the size in bytes of a segment
+ // descriptor on the target system. This header is followed by a series
+ // of tuples. Each tuple consists of an address and a length, each in
+ // the size appropriate for an address on the target architecture.
+ m_header.length = data.GetDWARFInitialLength(offset_ptr);
+ m_header.version = data.GetU16(offset_ptr);
+ m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
+ m_header.addr_size = data.GetU8(offset_ptr);
+ m_header.seg_size = data.GetU8(offset_ptr);
+
+ // Try to avoid reading invalid arange sets by making sure:
+ // 1 - the version looks good
+ // 2 - the address byte size looks plausible
+ // 3 - the length seems to make sense
+ // size looks plausible
+ if ((m_header.version >= 2 && m_header.version <= 5) &&
+ (m_header.addr_size == 4 || m_header.addr_size == 8) &&
+ (m_header.length > 0)) {
+ if (data.ValidOffset(m_offset + sizeof(m_header.length) +
+ m_header.length - 1)) {
+ // The first tuple following the header in each set begins at an offset
+ // that is a multiple of the size of a single tuple (that is, twice the
+ // size of an address). The header is padded, if necessary, to the
+ // appropriate boundary.
+ const uint32_t header_size = *offset_ptr - m_offset;
+ const uint32_t tuple_size = m_header.addr_size << 1;
+ uint32_t first_tuple_offset = 0;
+ while (first_tuple_offset < header_size)
+ first_tuple_offset += tuple_size;
+
+ *offset_ptr = m_offset + first_tuple_offset;
+
+ Descriptor arangeDescriptor;
+
+ static_assert(
+ sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length),
+ "DWARFDebugArangeSet::Descriptor.address and "
+ "DWARFDebugArangeSet::Descriptor.length must have same size");
+
+ while (data.ValidOffset(*offset_ptr)) {
+ arangeDescriptor.address =
+ data.GetMaxU64(offset_ptr, m_header.addr_size);
+ arangeDescriptor.length =
+ data.GetMaxU64(offset_ptr, m_header.addr_size);
+
+ // Each set of tuples is terminated by a 0 for the address and 0
+ // for the length.
+ if (arangeDescriptor.address || arangeDescriptor.length)
+ m_arange_descriptors.push_back(arangeDescriptor);
+ else
+ break; // We are done if we get a zero address and length
}
+ }
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ else {
+ printf("warning: .debug_arange set length is too large arange data at "
+ "0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, "
+ "addr_size=%u, seg_size=%u\n",
+ m_offset, m_header.length, m_header.version, m_header.cu_offset,
+ m_header.addr_size, m_header.seg_size);
+ }
#endif
-
- return !m_arange_descriptors.empty();
}
- return false;
-}
-
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ else {
+ printf("warning: .debug_arange set has bad header at 0x%8.8x: "
+ "length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, "
+ "addr_size=%u, seg_size=%u\n",
+ m_offset, m_header.length, m_header.version, m_header.cu_offset,
+ m_header.addr_size, m_header.seg_size);
+ }
+#endif
-dw_offset_t
-DWARFDebugArangeSet::GetOffsetOfNextEntry() const
-{
- return m_offset + m_header.length + 4;
+ return !m_arange_descriptors.empty();
+ }
+ return false;
}
+dw_offset_t DWARFDebugArangeSet::GetOffsetOfNextEntry() const {
+ return m_offset + m_header.length + 4;
+}
-void
-DWARFDebugArangeSet::Dump(Stream *s) const
-{
- s->Printf("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
- m_header.length ,m_header.version, m_header.cu_offset, m_header.addr_size, m_header.seg_size);
+void DWARFDebugArangeSet::Dump(Stream *s) const {
+ s->Printf("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, "
+ "cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
+ m_header.length, m_header.version, m_header.cu_offset,
+ m_header.addr_size, m_header.seg_size);
- const uint32_t hex_width = m_header.addr_size * 2;
- DescriptorConstIter pos;
- DescriptorConstIter end = m_arange_descriptors.end();
- for (pos = m_arange_descriptors.begin(); pos != end; ++pos)
- s->Printf("[0x%*.*" PRIx64 " - 0x%*.*" PRIx64 ")\n",
- hex_width, hex_width, pos->address,
- hex_width, hex_width, pos->end_address());
+ const uint32_t hex_width = m_header.addr_size * 2;
+ DescriptorConstIter pos;
+ DescriptorConstIter end = m_arange_descriptors.end();
+ for (pos = m_arange_descriptors.begin(); pos != end; ++pos)
+ s->Printf("[0x%*.*" PRIx64 " - 0x%*.*" PRIx64 ")\n", hex_width, hex_width,
+ pos->address, hex_width, hex_width, pos->end_address());
}
-
-class DescriptorContainsAddress
-{
+class DescriptorContainsAddress {
public:
- DescriptorContainsAddress (dw_addr_t address) : m_address(address) {}
- bool operator() (const DWARFDebugArangeSet::Descriptor& desc) const
- {
- return (m_address >= desc.address) && (m_address < (desc.address + desc.length));
- }
- private:
- const dw_addr_t m_address;
+ DescriptorContainsAddress(dw_addr_t address) : m_address(address) {}
+ bool operator()(const DWARFDebugArangeSet::Descriptor &desc) const {
+ return (m_address >= desc.address) &&
+ (m_address < (desc.address + desc.length));
+ }
+
+private:
+ const dw_addr_t m_address;
};
-dw_offset_t
-DWARFDebugArangeSet::FindAddress(dw_addr_t address) const
-{
- DescriptorConstIter end = m_arange_descriptors.end();
- DescriptorConstIter pos = std::find_if( m_arange_descriptors.begin(), end, // Range
- DescriptorContainsAddress(address));// Predicate
- if (pos != end)
- return m_header.cu_offset;
+dw_offset_t DWARFDebugArangeSet::FindAddress(dw_addr_t address) const {
+ DescriptorConstIter end = m_arange_descriptors.end();
+ DescriptorConstIter pos =
+ std::find_if(m_arange_descriptors.begin(), end, // Range
+ DescriptorContainsAddress(address)); // Predicate
+ if (pos != end)
+ return m_header.cu_offset;
- return DW_INVALID_OFFSET;
+ return DW_INVALID_OFFSET;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
index fde36b7e0adc..ae6319a13d0e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -15,62 +15,62 @@
class SymbolFileDWARF;
-class DWARFDebugArangeSet
-{
+class DWARFDebugArangeSet {
public:
- struct Header
- {
- uint32_t length; // The total length of the entries for that set, not including the length field itself.
- uint16_t version; // The DWARF version number
- uint32_t cu_offset; // The offset from the beginning of the .debug_info section of the compilation unit entry referenced by the table.
- uint8_t addr_size; // The size in bytes of an address on the target architecture. For segmented addressing, this is the size of the offset portion of the address
- uint8_t seg_size; // The size in bytes of a segment descriptor on the target architecture. If the target system uses a flat address space, this value is 0.
- };
+ struct Header {
+ uint32_t length; // The total length of the entries for that set, not
+ // including the length field itself.
+ uint16_t version; // The DWARF version number
+ uint32_t cu_offset; // The offset from the beginning of the .debug_info
+ // section of the compilation unit entry referenced by
+ // the table.
+ uint8_t addr_size; // The size in bytes of an address on the target
+ // architecture. For segmented addressing, this is the
+ // size of the offset portion of the address
+ uint8_t seg_size; // The size in bytes of a segment descriptor on the target
+ // architecture. If the target system uses a flat address
+ // space, this value is 0.
+ };
- struct Descriptor
- {
- dw_addr_t address;
- dw_addr_t length;
- dw_addr_t end_address() const { return address + length; }
- };
+ struct Descriptor {
+ dw_addr_t address;
+ dw_addr_t length;
+ dw_addr_t end_address() const { return address + length; }
+ };
+ DWARFDebugArangeSet();
+ void Clear();
+ void SetOffset(uint32_t offset) { m_offset = offset; }
+ void SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size,
+ uint8_t seg_size);
+ void AddDescriptor(const DWARFDebugArangeSet::Descriptor &range);
+ void Compact();
+ bool Extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+ void Dump(lldb_private::Stream *s) const;
+ dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; }
+ dw_offset_t GetOffsetOfNextEntry() const;
+ dw_offset_t FindAddress(dw_addr_t address) const;
+ size_t NumDescriptors() const { return m_arange_descriptors.size(); }
+ const Header &GetHeader() const { return m_header; }
+ const Descriptor *GetDescriptor(uint32_t i) const {
+ if (i < m_arange_descriptors.size())
+ return &m_arange_descriptors[i];
+ return NULL;
+ }
- DWARFDebugArangeSet();
- void Clear();
- void SetOffset(uint32_t offset) { m_offset = offset; }
- void SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size, uint8_t seg_size);
- void AddDescriptor(const DWARFDebugArangeSet::Descriptor& range);
- void Compact();
- bool Extract(const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr);
- void Dump(lldb_private::Stream *s) const;
- dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; }
- dw_offset_t GetOffsetOfNextEntry() const;
- dw_offset_t FindAddress(dw_addr_t address) const;
- size_t NumDescriptors() const { return m_arange_descriptors.size(); }
- const Header& GetHeader() const { return m_header; }
- const Descriptor* GetDescriptor(uint32_t i) const
- {
- if (i < m_arange_descriptors.size())
- return &m_arange_descriptors[i];
- return NULL;
- }
-
- const Descriptor &
- GetDescriptorRef (uint32_t i) const
- {
- return m_arange_descriptors[i];
- }
-
+ const Descriptor &GetDescriptorRef(uint32_t i) const {
+ return m_arange_descriptors[i];
+ }
protected:
- typedef std::vector<Descriptor> DescriptorColl;
- typedef DescriptorColl::iterator DescriptorIter;
- typedef DescriptorColl::const_iterator DescriptorConstIter;
-
+ typedef std::vector<Descriptor> DescriptorColl;
+ typedef DescriptorColl::iterator DescriptorIter;
+ typedef DescriptorColl::const_iterator DescriptorConstIter;
- uint32_t m_offset;
- Header m_header;
- DescriptorColl m_arange_descriptors;
+ uint32_t m_offset;
+ Header m_header;
+ DescriptorColl m_arange_descriptors;
};
-#endif // SymbolFileDWARF_DWARFDebugArangeSet_h_
+#endif // SymbolFileDWARF_DWARFDebugArangeSet_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index 60e5c6ed62fe..5e71e9dfcbb3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -18,10 +18,10 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
-#include "DWARFDebugInfo.h"
-#include "DWARFCompileUnit.h"
using namespace lldb;
using namespace lldb_private;
@@ -29,148 +29,122 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DWARFDebugAranges::DWARFDebugAranges() :
- m_aranges()
-{
-}
+DWARFDebugAranges::DWARFDebugAranges() : m_aranges() {}
//----------------------------------------------------------------------
// CountArangeDescriptors
//----------------------------------------------------------------------
-class CountArangeDescriptors
-{
+class CountArangeDescriptors {
public:
- CountArangeDescriptors (uint32_t& count_ref) : count(count_ref)
- {
-// printf("constructor CountArangeDescriptors()\n");
- }
- void operator() (const DWARFDebugArangeSet& set)
- {
- count += set.NumDescriptors();
- }
- uint32_t& count;
+ CountArangeDescriptors(uint32_t &count_ref) : count(count_ref) {
+ // printf("constructor CountArangeDescriptors()\n");
+ }
+ void operator()(const DWARFDebugArangeSet &set) {
+ count += set.NumDescriptors();
+ }
+ uint32_t &count;
};
-
//----------------------------------------------------------------------
// Extract
//----------------------------------------------------------------------
-bool
-DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data)
-{
- if (debug_aranges_data.ValidOffset(0))
- {
- lldb::offset_t offset = 0;
-
- DWARFDebugArangeSet set;
- Range range;
- while (set.Extract(debug_aranges_data, &offset))
- {
- const uint32_t num_descriptors = set.NumDescriptors();
- if (num_descriptors > 0)
- {
- const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset();
-
- for (uint32_t i=0; i<num_descriptors; ++i)
- {
- const DWARFDebugArangeSet::Descriptor &descriptor = set.GetDescriptorRef(i);
- m_aranges.Append(RangeToDIE::Entry (descriptor.address, descriptor.length, cu_offset));
- }
- }
- set.Clear();
+bool DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data) {
+ if (debug_aranges_data.ValidOffset(0)) {
+ lldb::offset_t offset = 0;
+
+ DWARFDebugArangeSet set;
+ Range range;
+ while (set.Extract(debug_aranges_data, &offset)) {
+ const uint32_t num_descriptors = set.NumDescriptors();
+ if (num_descriptors > 0) {
+ const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset();
+
+ for (uint32_t i = 0; i < num_descriptors; ++i) {
+ const DWARFDebugArangeSet::Descriptor &descriptor =
+ set.GetDescriptorRef(i);
+ m_aranges.Append(RangeToDIE::Entry(descriptor.address,
+ descriptor.length, cu_offset));
}
+ }
+ set.Clear();
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// Generate
//----------------------------------------------------------------------
-bool
-DWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data)
-{
- Clear();
- DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
- if (debug_info)
- {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (cu)
- cu->BuildAddressRangeTable(dwarf2Data, this);
- }
+bool DWARFDebugAranges::Generate(SymbolFileDWARF *dwarf2Data) {
+ Clear();
+ DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
+ if (debug_info) {
+ uint32_t cu_idx = 0;
+ const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+ for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (cu)
+ cu->BuildAddressRangeTable(dwarf2Data, this);
}
- return !IsEmpty();
+ }
+ return !IsEmpty();
}
+void DWARFDebugAranges::Dump(Log *log) const {
+ if (log == NULL)
+ return;
-void
-DWARFDebugAranges::Dump (Log *log) const
-{
- if (log == NULL)
- return;
-
- const size_t num_entries = m_aranges.GetSize();
- for (size_t i=0; i<num_entries; ++i)
- {
- const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
- if (entry)
- log->Printf ("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")",
- entry->data,
- entry->GetRangeBase(),
- entry->GetRangeEnd());
- }
+ const size_t num_entries = m_aranges.GetSize();
+ for (size_t i = 0; i < num_entries; ++i) {
+ const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
+ if (entry)
+ log->Printf("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data,
+ entry->GetRangeBase(), entry->GetRangeEnd());
+ }
}
-void
-DWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
-{
- if (high_pc > low_pc)
- m_aranges.Append(RangeToDIE::Entry (low_pc, high_pc - low_pc, offset));
+void DWARFDebugAranges::AppendRange(dw_offset_t offset, dw_addr_t low_pc,
+ dw_addr_t high_pc) {
+ if (high_pc > low_pc)
+ m_aranges.Append(RangeToDIE::Entry(low_pc, high_pc - low_pc, offset));
}
-void
-DWARFDebugAranges::Sort (bool minimize)
-{
- Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
- __PRETTY_FUNCTION__, static_cast<void*>(this));
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
- size_t orig_arange_size = 0;
- if (log)
- {
- orig_arange_size = m_aranges.GetSize();
- log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64 " entries", minimize, (uint64_t)orig_arange_size);
- }
-
- m_aranges.Sort();
- m_aranges.CombineConsecutiveEntriesWithEqualData();
-
- if (log)
- {
- if (minimize)
- {
- const size_t new_arange_size = m_aranges.GetSize();
- const size_t delta = orig_arange_size - new_arange_size;
- log->Printf ("DWARFDebugAranges::Sort() %" PRIu64 " entries after minimizing (%" PRIu64 " entries combined for %" PRIu64 " bytes saved)",
- (uint64_t)new_arange_size,
- (uint64_t)delta,
- (uint64_t)delta * sizeof(Range));
- }
- Dump (log);
+void DWARFDebugAranges::Sort(bool minimize) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p", LLVM_PRETTY_FUNCTION,
+ static_cast<void *>(this));
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
+ size_t orig_arange_size = 0;
+ if (log) {
+ orig_arange_size = m_aranges.GetSize();
+ log->Printf("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64
+ " entries",
+ minimize, (uint64_t)orig_arange_size);
+ }
+
+ m_aranges.Sort();
+ m_aranges.CombineConsecutiveEntriesWithEqualData();
+
+ if (log) {
+ if (minimize) {
+ const size_t new_arange_size = m_aranges.GetSize();
+ const size_t delta = orig_arange_size - new_arange_size;
+ log->Printf("DWARFDebugAranges::Sort() %" PRIu64
+ " entries after minimizing (%" PRIu64
+ " entries combined for %" PRIu64 " bytes saved)",
+ (uint64_t)new_arange_size, (uint64_t)delta,
+ (uint64_t)delta * sizeof(Range));
}
+ Dump(log);
+ }
}
//----------------------------------------------------------------------
// FindAddress
//----------------------------------------------------------------------
-dw_offset_t
-DWARFDebugAranges::FindAddress(dw_addr_t address) const
-{
- const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address);
- if (entry)
- return entry->data;
- return DW_INVALID_OFFSET;
+dw_offset_t DWARFDebugAranges::FindAddress(dw_addr_t address) const {
+ const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address);
+ if (entry)
+ return entry->data;
+ return DW_INVALID_OFFSET;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
index 206aa3a60f49..6524cb3ce483 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -17,78 +17,50 @@
class SymbolFileDWARF;
-class DWARFDebugAranges
-{
+class DWARFDebugAranges {
protected:
- typedef lldb_private::RangeDataArray<dw_addr_t, uint32_t, dw_offset_t, 1> RangeToDIE;
+ typedef lldb_private::RangeDataArray<dw_addr_t, uint32_t, dw_offset_t, 1>
+ RangeToDIE;
public:
- typedef RangeToDIE::Entry Range;
- typedef std::vector<RangeToDIE::Entry> RangeColl;
-
- DWARFDebugAranges();
-
- void
- Clear()
- {
- m_aranges.Clear();
- }
-
- bool
- Extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
-
- bool
- Generate(SymbolFileDWARF* dwarf2Data);
-
- // Use append range multiple times and then call sort
- void
- AppendRange (dw_offset_t cu_offset,
- dw_addr_t low_pc,
- dw_addr_t high_pc);
-
- void
- Sort (bool minimize);
-
- const Range*
- RangeAtIndex(uint32_t idx) const
- {
- return m_aranges.GetEntryAtIndex (idx);
- }
-
- void
- Dump (lldb_private::Log *log) const;
-
- dw_offset_t
- FindAddress(dw_addr_t address) const;
-
- bool
- IsEmpty() const
- {
- return m_aranges.IsEmpty();
- }
- size_t
- GetNumRanges() const
- {
- return m_aranges.GetSize();
- }
-
- dw_offset_t
- OffsetAtIndex(uint32_t idx) const
- {
- const Range *range = m_aranges.GetEntryAtIndex (idx);
- if (range)
- return range->data;
- return DW_INVALID_OFFSET;
- }
-
- static void
- Dump(SymbolFileDWARF* dwarf2Data, lldb_private::Stream *s);
-
-protected:
+ typedef RangeToDIE::Entry Range;
+ typedef std::vector<RangeToDIE::Entry> RangeColl;
+ DWARFDebugAranges();
- RangeToDIE m_aranges;
-};
+ void Clear() { m_aranges.Clear(); }
+
+ bool Extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
+
+ bool Generate(SymbolFileDWARF *dwarf2Data);
+
+ // Use append range multiple times and then call sort
+ void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc);
+
+ void Sort(bool minimize);
+
+ const Range *RangeAtIndex(uint32_t idx) const {
+ return m_aranges.GetEntryAtIndex(idx);
+ }
+ void Dump(lldb_private::Log *log) const;
+
+ dw_offset_t FindAddress(dw_addr_t address) const;
+
+ bool IsEmpty() const { return m_aranges.IsEmpty(); }
+ size_t GetNumRanges() const { return m_aranges.GetSize(); }
+
+ dw_offset_t OffsetAtIndex(uint32_t idx) const {
+ const Range *range = m_aranges.GetEntryAtIndex(idx);
+ if (range)
+ return range->data;
+ return DW_INVALID_OFFSET;
+ }
+
+ static void Dump(SymbolFileDWARF *dwarf2Data, lldb_private::Stream *s);
+
+protected:
+ RangeToDIE m_aranges;
+};
-#endif // SymbolFileDWARF_DWARFDebugAranges_h_
+#endif // SymbolFileDWARF_DWARFDebugAranges_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 417f2cd79bda..9dc656d79326 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -14,12 +14,13 @@
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Host/PosixApi.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "DWARFDebugAranges.h"
-#include "DWARFDebugInfo.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugAranges.h"
+#include "DWARFDebugAranges.h"
+#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFFormValue.h"
#include "LogChannelDWARF.h"
@@ -31,229 +32,192 @@ using namespace std;
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DWARFDebugInfo::DWARFDebugInfo() :
- m_dwarf2Data(NULL),
- m_compile_units(),
- m_cu_aranges_ap ()
-{
-}
+DWARFDebugInfo::DWARFDebugInfo()
+ : m_dwarf2Data(NULL), m_compile_units(), m_cu_aranges_ap() {}
//----------------------------------------------------------------------
// SetDwarfData
//----------------------------------------------------------------------
-void
-DWARFDebugInfo::SetDwarfData(SymbolFileDWARF* dwarf2Data)
-{
- m_dwarf2Data = dwarf2Data;
- m_compile_units.clear();
+void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) {
+ m_dwarf2Data = dwarf2Data;
+ m_compile_units.clear();
}
+DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() {
+ if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
+
+ m_cu_aranges_ap.reset(new DWARFDebugAranges());
+ const DWARFDataExtractor &debug_aranges_data =
+ m_dwarf2Data->get_debug_aranges_data();
+ if (debug_aranges_data.GetByteSize() > 0) {
+ if (log)
+ log->Printf(
+ "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from "
+ ".debug_aranges",
+ m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
+ m_cu_aranges_ap->Extract(debug_aranges_data);
+ }
-DWARFDebugAranges &
-DWARFDebugInfo::GetCompileUnitAranges ()
-{
- if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data)
- {
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-
- m_cu_aranges_ap.reset (new DWARFDebugAranges());
- const DWARFDataExtractor &debug_aranges_data = m_dwarf2Data->get_debug_aranges_data();
- if (debug_aranges_data.GetByteSize() > 0)
- {
- if (log)
- log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from .debug_aranges",
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
- m_cu_aranges_ap->Extract (debug_aranges_data);
-
- }
-
- // Make a list of all CUs represented by the arange data in the file.
- std::set<dw_offset_t> cus_with_data;
- for (size_t n=0;n<m_cu_aranges_ap.get()->GetNumRanges();n++)
- {
- dw_offset_t offset = m_cu_aranges_ap.get()->OffsetAtIndex(n);
- if (offset != DW_INVALID_OFFSET)
- cus_with_data.insert (offset);
- }
+ // Make a list of all CUs represented by the arange data in the file.
+ std::set<dw_offset_t> cus_with_data;
+ for (size_t n = 0; n < m_cu_aranges_ap.get()->GetNumRanges(); n++) {
+ dw_offset_t offset = m_cu_aranges_ap.get()->OffsetAtIndex(n);
+ if (offset != DW_INVALID_OFFSET)
+ cus_with_data.insert(offset);
+ }
- // Manually build arange data for everything that wasn't in the .debug_aranges table.
- bool printed = false;
- const size_t num_compile_units = GetNumCompileUnits();
- for (size_t idx = 0; idx < num_compile_units; ++idx)
- {
- DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx);
-
- dw_offset_t offset = cu->GetOffset();
- if (cus_with_data.find(offset) == cus_with_data.end())
- {
- if (log)
- {
- if (!printed)
- log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing",
- m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
- printed = true;
- }
- cu->BuildAddressRangeTable (m_dwarf2Data, m_cu_aranges_ap.get());
- }
+ // Manually build arange data for everything that wasn't in the
+ // .debug_aranges table.
+ bool printed = false;
+ const size_t num_compile_units = GetNumCompileUnits();
+ for (size_t idx = 0; idx < num_compile_units; ++idx) {
+ DWARFCompileUnit *cu = GetCompileUnitAtIndex(idx);
+
+ dw_offset_t offset = cu->GetOffset();
+ if (cus_with_data.find(offset) == cus_with_data.end()) {
+ if (log) {
+ if (!printed)
+ log->Printf(
+ "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing",
+ m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
+ printed = true;
}
-
- const bool minimize = true;
- m_cu_aranges_ap->Sort (minimize);
+ cu->BuildAddressRangeTable(m_dwarf2Data, m_cu_aranges_ap.get());
+ }
}
- return *m_cu_aranges_ap.get();
+
+ const bool minimize = true;
+ m_cu_aranges_ap->Sort(minimize);
+ }
+ return *m_cu_aranges_ap.get();
}
-void
-DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded()
-{
- if (m_compile_units.empty())
- {
- if (m_dwarf2Data != NULL)
- {
- lldb::offset_t offset = 0;
- const DWARFDataExtractor &debug_info_data = m_dwarf2Data->get_debug_info_data();
- while (debug_info_data.ValidOffset(offset))
- {
- DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(m_dwarf2Data));
- // Out of memory?
- if (cu_sp.get() == NULL)
- break;
-
- if (cu_sp->Extract(debug_info_data, &offset) == false)
- break;
-
- m_compile_units.push_back(cu_sp);
-
- offset = cu_sp->GetNextCompileUnitOffset();
- }
- }
+void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
+ if (m_compile_units.empty()) {
+ if (m_dwarf2Data != NULL) {
+ lldb::offset_t offset = 0;
+ const DWARFDataExtractor &debug_info_data =
+ m_dwarf2Data->get_debug_info_data();
+ while (debug_info_data.ValidOffset(offset)) {
+ DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(m_dwarf2Data));
+ // Out of memory?
+ if (cu_sp.get() == NULL)
+ break;
+
+ if (cu_sp->Extract(debug_info_data, &offset) == false)
+ break;
+
+ m_compile_units.push_back(cu_sp);
+
+ offset = cu_sp->GetNextCompileUnitOffset();
+ }
}
+ }
}
-size_t
-DWARFDebugInfo::GetNumCompileUnits()
-{
- ParseCompileUnitHeadersIfNeeded();
- return m_compile_units.size();
+size_t DWARFDebugInfo::GetNumCompileUnits() {
+ ParseCompileUnitHeadersIfNeeded();
+ return m_compile_units.size();
}
-DWARFCompileUnit*
-DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx)
-{
- DWARFCompileUnit* cu = NULL;
- if (idx < GetNumCompileUnits())
- cu = m_compile_units[idx].get();
- return cu;
+DWARFCompileUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) {
+ DWARFCompileUnit *cu = NULL;
+ if (idx < GetNumCompileUnits())
+ cu = m_compile_units[idx].get();
+ return cu;
}
-bool
-DWARFDebugInfo::ContainsCompileUnit (const DWARFCompileUnit *cu) const
-{
- // Not a verify efficient function, but it is handy for use in assertions
- // to make sure that a compile unit comes from a debug information file.
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator pos;
-
- for (pos = m_compile_units.begin(); pos != end_pos; ++pos)
- {
- if (pos->get() == cu)
- return true;
- }
- return false;
+bool DWARFDebugInfo::ContainsCompileUnit(const DWARFCompileUnit *cu) const {
+ // Not a verify efficient function, but it is handy for use in assertions
+ // to make sure that a compile unit comes from a debug information file.
+ CompileUnitColl::const_iterator end_pos = m_compile_units.end();
+ CompileUnitColl::const_iterator pos;
+
+ for (pos = m_compile_units.begin(); pos != end_pos; ++pos) {
+ if (pos->get() == cu)
+ return true;
+ }
+ return false;
}
-bool
-DWARFDebugInfo::OffsetLessThanCompileUnitOffset (dw_offset_t offset, const DWARFCompileUnitSP& cu_sp)
-{
- return offset < cu_sp->GetOffset();
+bool DWARFDebugInfo::OffsetLessThanCompileUnitOffset(
+ dw_offset_t offset, const DWARFCompileUnitSP &cu_sp) {
+ return offset < cu_sp->GetOffset();
}
-DWARFCompileUnit *
-DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr)
-{
- DWARFCompileUnitSP cu_sp;
- uint32_t cu_idx = DW_INVALID_INDEX;
- if (cu_offset != DW_INVALID_OFFSET)
- {
- ParseCompileUnitHeadersIfNeeded();
-
- // Watch out for single compile unit executable as they are pretty common
- const size_t num_cus = m_compile_units.size();
- if (num_cus == 1)
- {
- if (m_compile_units[0]->GetOffset() == cu_offset)
- {
- cu_sp = m_compile_units[0];
- cu_idx = 0;
- }
- }
- else if (num_cus)
- {
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
- CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, cu_offset, OffsetLessThanCompileUnitOffset);
- if (pos != begin_pos)
- {
- --pos;
- if ((*pos)->GetOffset() == cu_offset)
- {
- cu_sp = *pos;
- cu_idx = std::distance(begin_pos, pos);
- }
- }
+DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset,
+ uint32_t *idx_ptr) {
+ DWARFCompileUnitSP cu_sp;
+ uint32_t cu_idx = DW_INVALID_INDEX;
+ if (cu_offset != DW_INVALID_OFFSET) {
+ ParseCompileUnitHeadersIfNeeded();
+
+ // Watch out for single compile unit executable as they are pretty common
+ const size_t num_cus = m_compile_units.size();
+ if (num_cus == 1) {
+ if (m_compile_units[0]->GetOffset() == cu_offset) {
+ cu_sp = m_compile_units[0];
+ cu_idx = 0;
+ }
+ } else if (num_cus) {
+ CompileUnitColl::const_iterator end_pos = m_compile_units.end();
+ CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
+ CompileUnitColl::const_iterator pos = std::upper_bound(
+ begin_pos, end_pos, cu_offset, OffsetLessThanCompileUnitOffset);
+ if (pos != begin_pos) {
+ --pos;
+ if ((*pos)->GetOffset() == cu_offset) {
+ cu_sp = *pos;
+ cu_idx = std::distance(begin_pos, pos);
}
+ }
}
- if (idx_ptr)
- *idx_ptr = cu_idx;
- return cu_sp.get();
+ }
+ if (idx_ptr)
+ *idx_ptr = cu_idx;
+ return cu_sp.get();
}
-DWARFCompileUnit *
-DWARFDebugInfo::GetCompileUnit (const DIERef& die_ref)
-{
- if (die_ref.cu_offset == DW_INVALID_OFFSET)
- return GetCompileUnitContainingDIEOffset(die_ref.die_offset);
- else
- return GetCompileUnit(die_ref.cu_offset);
+DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(const DIERef &die_ref) {
+ if (die_ref.cu_offset == DW_INVALID_OFFSET)
+ return GetCompileUnitContainingDIEOffset(die_ref.die_offset);
+ else
+ return GetCompileUnit(die_ref.cu_offset);
}
-DWARFCompileUnit*
-DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset)
-{
- ParseCompileUnitHeadersIfNeeded();
+DWARFCompileUnit *
+DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) {
+ ParseCompileUnitHeadersIfNeeded();
- DWARFCompileUnitSP cu_sp;
+ DWARFCompileUnitSP cu_sp;
- // Watch out for single compile unit executable as they are pretty common
- const size_t num_cus = m_compile_units.size();
- if (num_cus == 1)
- {
- if (m_compile_units[0]->ContainsDIEOffset(die_offset))
- return m_compile_units[0].get();
- }
- else if (num_cus)
- {
- CompileUnitColl::const_iterator end_pos = m_compile_units.end();
- CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
- CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset);
- if (pos != begin_pos)
- {
- --pos;
- if ((*pos)->ContainsDIEOffset(die_offset))
- return (*pos).get();
- }
+ // Watch out for single compile unit executable as they are pretty common
+ const size_t num_cus = m_compile_units.size();
+ if (num_cus == 1) {
+ if (m_compile_units[0]->ContainsDIEOffset(die_offset))
+ return m_compile_units[0].get();
+ } else if (num_cus) {
+ CompileUnitColl::const_iterator end_pos = m_compile_units.end();
+ CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
+ CompileUnitColl::const_iterator pos = std::upper_bound(
+ begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset);
+ if (pos != begin_pos) {
+ --pos;
+ if ((*pos)->ContainsDIEOffset(die_offset))
+ return (*pos).get();
}
+ }
- return nullptr;
+ return nullptr;
}
DWARFDIE
-DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset)
-{
- DWARFCompileUnit* cu = GetCompileUnitContainingDIEOffset(die_offset);
- if (cu)
- return cu->GetDIE(die_offset);
- return DWARFDIE();
+DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) {
+ DWARFCompileUnit *cu = GetCompileUnitContainingDIEOffset(die_offset);
+ if (cu)
+ return cu->GetDIE(die_offset);
+ return DWARFDIE();
}
//----------------------------------------------------------------------
@@ -262,12 +226,11 @@ DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset)
// Get the DIE (Debug Information Entry) with the specified offset.
//----------------------------------------------------------------------
DWARFDIE
-DWARFDebugInfo::GetDIE(const DIERef& die_ref)
-{
- DWARFCompileUnit *cu = GetCompileUnit(die_ref);
- if (cu)
- return cu->GetDIE (die_ref.die_offset);
- return DWARFDIE(); // Not found
+DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
+ DWARFCompileUnit *cu = GetCompileUnit(die_ref);
+ if (cu)
+ return cu->GetDIE(die_ref.die_offset);
+ return DWARFDIE(); // Not found
}
//----------------------------------------------------------------------
@@ -280,88 +243,75 @@ DWARFDebugInfo::GetDIE(const DIERef& die_ref)
// for different tasks such as parsing the file contents into a
// structured data, dumping, verifying and much more.
//----------------------------------------------------------------------
-void
-DWARFDebugInfo::Parse(SymbolFileDWARF* dwarf2Data, Callback callback, void* userData)
-{
- if (dwarf2Data)
- {
- lldb::offset_t offset = 0;
- uint32_t depth = 0;
- DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
- if (cu.get() == NULL)
- return;
- DWARFDebugInfoEntry die;
-
- while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset))
- {
- const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
-
- depth = 0;
- // Call the callback function with no DIE pointer for the compile unit
- // and get the offset that we are to continue to parse from
- offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData);
-
- // Make sure we are within our compile unit
- if (offset < next_cu_offset)
- {
- // We are in our compile unit, parse starting at the offset
- // we were told to parse
- bool done = false;
- while (!done && die.Extract(dwarf2Data, cu.get(), &offset))
- {
- // Call the callback function with DIE pointer that falls within the compile unit
- offset = callback(dwarf2Data, cu.get(), &die, offset, depth, userData);
-
- if (die.IsNULL())
- {
- if (depth)
- --depth;
- else
- done = true; // We are done with this compile unit!
- }
- else if (die.HasChildren())
- ++depth;
- }
- }
-
- // Make sure the offset returned is valid, and if not stop parsing.
- // Returning DW_INVALID_OFFSET from this callback is a good way to end
- // all parsing
- if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
- break;
-
- // See if during the callback anyone retained a copy of the compile
- // unit other than ourselves and if so, let whomever did own the object
- // and create a new one for our own use!
- if (!cu.unique())
- cu.reset(new DWARFCompileUnit(dwarf2Data));
-
-
- // Make sure we start on a proper
- offset = next_cu_offset;
+void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
+ void *userData) {
+ if (dwarf2Data) {
+ lldb::offset_t offset = 0;
+ uint32_t depth = 0;
+ DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
+ if (cu.get() == NULL)
+ return;
+ DWARFDebugInfoEntry die;
+
+ while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset)) {
+ const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
+
+ depth = 0;
+ // Call the callback function with no DIE pointer for the compile unit
+ // and get the offset that we are to continue to parse from
+ offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData);
+
+ // Make sure we are within our compile unit
+ if (offset < next_cu_offset) {
+ // We are in our compile unit, parse starting at the offset
+ // we were told to parse
+ bool done = false;
+ while (!done && die.Extract(dwarf2Data, cu.get(), &offset)) {
+ // Call the callback function with DIE pointer that falls within the
+ // compile unit
+ offset =
+ callback(dwarf2Data, cu.get(), &die, offset, depth, userData);
+
+ if (die.IsNULL()) {
+ if (depth)
+ --depth;
+ else
+ done = true; // We are done with this compile unit!
+ } else if (die.HasChildren())
+ ++depth;
}
+ }
+
+ // Make sure the offset returned is valid, and if not stop parsing.
+ // Returning DW_INVALID_OFFSET from this callback is a good way to end
+ // all parsing
+ if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
+ break;
+
+ // See if during the callback anyone retained a copy of the compile
+ // unit other than ourselves and if so, let whomever did own the object
+ // and create a new one for our own use!
+ if (!cu.unique())
+ cu.reset(new DWARFCompileUnit(dwarf2Data));
+
+ // Make sure we start on a proper
+ offset = next_cu_offset;
}
+ }
}
-typedef struct DumpInfo
-{
- DumpInfo(Stream* init_strm, uint32_t off, uint32_t depth) :
- strm(init_strm),
- die_offset(off),
- recurse_depth(depth),
- found_depth(UINT32_MAX),
- found_die(false),
- ancestors()
- {
- }
- Stream* strm;
- const uint32_t die_offset;
- const uint32_t recurse_depth;
- uint32_t found_depth;
- bool found_die;
- std::vector<DWARFDebugInfoEntry> ancestors;
-
- DISALLOW_COPY_AND_ASSIGN(DumpInfo);
+typedef struct DumpInfo {
+ DumpInfo(Stream *init_strm, uint32_t off, uint32_t depth)
+ : strm(init_strm), die_offset(off), recurse_depth(depth),
+ found_depth(UINT32_MAX), found_die(false), ancestors() {}
+ Stream *strm;
+ const uint32_t die_offset;
+ const uint32_t recurse_depth;
+ uint32_t found_depth;
+ bool found_die;
+ std::vector<DWARFDebugInfoEntry> ancestors;
+
+ DISALLOW_COPY_AND_ASSIGN(DumpInfo);
} DumpInfo;
//----------------------------------------------------------------------
@@ -374,168 +324,134 @@ typedef struct DumpInfo
// This function dump DWARF information and obey recurse depth and
// whether a single DIE is to be dumped (or all of the data).
//----------------------------------------------------------------------
-static dw_offset_t DumpCallback
-(
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- DWARFDebugInfoEntry* die,
- const dw_offset_t next_offset,
- const uint32_t curr_depth,
- void* userData
-)
-{
- DumpInfo* dumpInfo = (DumpInfo*)userData;
- Stream *s = dumpInfo->strm;
- bool show_parents = s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors);
-
- if (die)
- {
- // Are we dumping everything?
- if (dumpInfo->die_offset == DW_INVALID_OFFSET)
- {
- // Yes we are dumping everything. Obey our recurse level though
- if (curr_depth < dumpInfo->recurse_depth)
- die->Dump(dwarf2Data, cu, *s, 0);
- }
- else
- {
- // We are dumping a specific DIE entry by offset
- if (dumpInfo->die_offset == die->GetOffset())
- {
- // We found the DIE we were looking for, dump it!
- if (show_parents)
- {
- s->SetIndentLevel(0);
- const uint32_t num_ancestors = dumpInfo->ancestors.size();
- if (num_ancestors > 0)
- {
- for (uint32_t i=0; i<num_ancestors-1; ++i)
- {
- dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0);
- s->IndentMore();
- }
- }
- }
-
- dumpInfo->found_depth = curr_depth;
-
- die->Dump(dwarf2Data, cu, *s, 0);
-
- // Note that we found the DIE we were looking for
- dumpInfo->found_die = true;
-
- // Since we are dumping a single DIE, if there are no children we are done!
- if (!die->HasChildren() || dumpInfo->recurse_depth == 0)
- return DW_INVALID_OFFSET; // Return an invalid address to end parsing
- }
- else if (dumpInfo->found_die)
- {
- // Are we done with all the children?
- if (curr_depth <= dumpInfo->found_depth)
- return DW_INVALID_OFFSET;
-
- // We have already found our DIE and are printing it's children. Obey
- // our recurse depth and return an invalid offset if we get done
- // dumping all of the children
- if (dumpInfo->recurse_depth == UINT32_MAX || curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth)
- die->Dump(dwarf2Data, cu, *s, 0);
- }
- else if (dumpInfo->die_offset > die->GetOffset())
- {
- if (show_parents)
- dumpInfo->ancestors.back() = *die;
+static dw_offset_t DumpCallback(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu, DWARFDebugInfoEntry *die,
+ const dw_offset_t next_offset,
+ const uint32_t curr_depth, void *userData) {
+ DumpInfo *dumpInfo = (DumpInfo *)userData;
+ Stream *s = dumpInfo->strm;
+ bool show_parents =
+ s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors);
+
+ if (die) {
+ // Are we dumping everything?
+ if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
+ // Yes we are dumping everything. Obey our recurse level though
+ if (curr_depth < dumpInfo->recurse_depth)
+ die->Dump(dwarf2Data, cu, *s, 0);
+ } else {
+ // We are dumping a specific DIE entry by offset
+ if (dumpInfo->die_offset == die->GetOffset()) {
+ // We found the DIE we were looking for, dump it!
+ if (show_parents) {
+ s->SetIndentLevel(0);
+ const uint32_t num_ancestors = dumpInfo->ancestors.size();
+ if (num_ancestors > 0) {
+ for (uint32_t i = 0; i < num_ancestors - 1; ++i) {
+ dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0);
+ s->IndentMore();
}
+ }
}
- // Keep up with our indent level
- if (die->IsNULL())
- {
- if (show_parents)
- dumpInfo->ancestors.pop_back();
-
- if (curr_depth <= 1)
- return cu->GetNextCompileUnitOffset();
- else
- s->IndentLess();
- }
- else if (die->HasChildren())
- {
- if (show_parents)
- {
- DWARFDebugInfoEntry null_die;
- dumpInfo->ancestors.push_back(null_die);
- }
- s->IndentMore();
- }
+ dumpInfo->found_depth = curr_depth;
+
+ die->Dump(dwarf2Data, cu, *s, 0);
+
+ // Note that we found the DIE we were looking for
+ dumpInfo->found_die = true;
+
+ // Since we are dumping a single DIE, if there are no children we are
+ // done!
+ if (!die->HasChildren() || dumpInfo->recurse_depth == 0)
+ return DW_INVALID_OFFSET; // Return an invalid address to end parsing
+ } else if (dumpInfo->found_die) {
+ // Are we done with all the children?
+ if (curr_depth <= dumpInfo->found_depth)
+ return DW_INVALID_OFFSET;
+
+ // We have already found our DIE and are printing it's children. Obey
+ // our recurse depth and return an invalid offset if we get done
+ // dumping all of the children
+ if (dumpInfo->recurse_depth == UINT32_MAX ||
+ curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth)
+ die->Dump(dwarf2Data, cu, *s, 0);
+ } else if (dumpInfo->die_offset > die->GetOffset()) {
+ if (show_parents)
+ dumpInfo->ancestors.back() = *die;
+ }
}
- else
- {
- if (cu == NULL)
- s->PutCString("NULL - cu");
- // We have a compile unit, reset our indent level to zero just in case
- s->SetIndentLevel(0);
-
- // See if we are dumping everything?
- if (dumpInfo->die_offset == DW_INVALID_OFFSET)
- {
- // We are dumping everything
- if (cu)
- {
- cu->Dump(s);
- return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this Compile Unit
- }
- else
- {
- return DW_INVALID_OFFSET;
- }
- }
- else
- {
- if (show_parents)
- {
- dumpInfo->ancestors.clear();
- dumpInfo->ancestors.resize(1);
- }
- // We are dumping only a single DIE possibly with it's children and
- // we must find it's compile unit before we can dump it properly
- if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset())
- {
- // Not found, maybe the DIE offset provided wasn't correct?
- // *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << " was not found." << endl;
- return DW_INVALID_OFFSET;
- }
- else
- {
- // See if the DIE is in this compile unit?
- if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset())
- {
- // This DIE is in this compile unit!
- if (s->GetVerbose())
- cu->Dump(s); // Dump the compile unit for the DIE in verbose mode
-
- return next_offset;
- // // We found our compile unit that contains our DIE, just skip to dumping the requested DIE...
- // return dumpInfo->die_offset;
- }
- else
- {
- // Skip to the next compile unit as the DIE isn't in the current one!
- if (cu)
- {
- return cu->GetNextCompileUnitOffset();
- }
- else
- {
- return DW_INVALID_OFFSET;
- }
- }
- }
+ // Keep up with our indent level
+ if (die->IsNULL()) {
+ if (show_parents)
+ dumpInfo->ancestors.pop_back();
+
+ if (curr_depth <= 1)
+ return cu->GetNextCompileUnitOffset();
+ else
+ s->IndentLess();
+ } else if (die->HasChildren()) {
+ if (show_parents) {
+ DWARFDebugInfoEntry null_die;
+ dumpInfo->ancestors.push_back(null_die);
+ }
+ s->IndentMore();
+ }
+ } else {
+ if (cu == NULL)
+ s->PutCString("NULL - cu");
+ // We have a compile unit, reset our indent level to zero just in case
+ s->SetIndentLevel(0);
+
+ // See if we are dumping everything?
+ if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
+ // We are dumping everything
+ if (cu) {
+ cu->Dump(s);
+ return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this
+ // Compile Unit
+ } else {
+ return DW_INVALID_OFFSET;
+ }
+ } else {
+ if (show_parents) {
+ dumpInfo->ancestors.clear();
+ dumpInfo->ancestors.resize(1);
+ }
+
+ // We are dumping only a single DIE possibly with it's children and
+ // we must find it's compile unit before we can dump it properly
+ if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) {
+ // Not found, maybe the DIE offset provided wasn't correct?
+ // *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << "
+ // was not found." << endl;
+ return DW_INVALID_OFFSET;
+ } else {
+ // See if the DIE is in this compile unit?
+ if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) {
+ // This DIE is in this compile unit!
+ if (s->GetVerbose())
+ cu->Dump(s); // Dump the compile unit for the DIE in verbose mode
+
+ return next_offset;
+ // // We found our compile unit that contains our DIE, just skip to
+ // dumping the requested DIE...
+ // return dumpInfo->die_offset;
+ } else {
+ // Skip to the next compile unit as the DIE isn't in the current one!
+ if (cu) {
+ return cu->GetNextCompileUnitOffset();
+ } else {
+ return DW_INVALID_OFFSET;
+ }
}
+ }
}
+ }
- // Just return the current offset to parse the next CU or DIE entry
- return next_offset;
+ // Just return the current offset to parse the next CU or DIE entry
+ return next_offset;
}
//----------------------------------------------------------------------
@@ -550,65 +466,51 @@ static dw_offset_t DumpCallback
// headers and the DW_TAG_compile unit tags. A depth of 2 will also
// dump all types and functions.
//----------------------------------------------------------------------
-void
-DWARFDebugInfo::Dump
-(
- Stream *s,
- SymbolFileDWARF* dwarf2Data,
- const uint32_t die_offset,
- const uint32_t recurse_depth
-)
-{
- DumpInfo dumpInfo(s, die_offset, recurse_depth);
- s->PutCString(".debug_info contents");
- if (dwarf2Data->get_debug_info_data().GetByteSize() > 0)
- {
- if (die_offset == DW_INVALID_OFFSET)
- s->PutCString(":\n");
- else
- {
- s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset);
- if (recurse_depth != UINT32_MAX)
- s->Printf(" recursing %u levels deep.", recurse_depth);
- s->EOL();
- }
- }
- else
- {
- s->PutCString(": < EMPTY >\n");
- return;
+void DWARFDebugInfo::Dump(Stream *s, SymbolFileDWARF *dwarf2Data,
+ const uint32_t die_offset,
+ const uint32_t recurse_depth) {
+ DumpInfo dumpInfo(s, die_offset, recurse_depth);
+ s->PutCString(".debug_info contents");
+ if (dwarf2Data->get_debug_info_data().GetByteSize() > 0) {
+ if (die_offset == DW_INVALID_OFFSET)
+ s->PutCString(":\n");
+ else {
+ s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset);
+ if (recurse_depth != UINT32_MAX)
+ s->Printf(" recursing %u levels deep.", recurse_depth);
+ s->EOL();
}
- DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo);
+ } else {
+ s->PutCString(": < EMPTY >\n");
+ return;
+ }
+ DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo);
}
-
//----------------------------------------------------------------------
// Dump
//
// Dump the contents of this DWARFDebugInfo object as has been parsed
// and/or modified after it has been parsed.
//----------------------------------------------------------------------
-void
-DWARFDebugInfo::Dump (Stream *s, const uint32_t die_offset, const uint32_t recurse_depth)
-{
- DumpInfo dumpInfo(s, die_offset, recurse_depth);
+void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset,
+ const uint32_t recurse_depth) {
+ DumpInfo dumpInfo(s, die_offset, recurse_depth);
- s->PutCString("Dumping .debug_info section from internal representation\n");
+ s->PutCString("Dumping .debug_info section from internal representation\n");
- CompileUnitColl::const_iterator pos;
- uint32_t curr_depth = 0;
- ParseCompileUnitHeadersIfNeeded();
- for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos)
- {
- DWARFCompileUnit *cu = pos->get();
- DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo);
-
- const DWARFDIE die = cu->DIE();
- if (die)
- die.Dump(s, recurse_depth);
- }
-}
+ CompileUnitColl::const_iterator pos;
+ uint32_t curr_depth = 0;
+ ParseCompileUnitHeadersIfNeeded();
+ for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) {
+ DWARFCompileUnit *cu = pos->get();
+ DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo);
+ const DWARFDIE die = cu->DIE();
+ if (die)
+ die.Dump(s, recurse_depth);
+ }
+}
//----------------------------------------------------------------------
// FindCallbackString
@@ -620,46 +522,37 @@ DWARFDebugInfo::Dump (Stream *s, const uint32_t die_offset, const uint32_t recur
// This function will find the die_offset of any items whose DW_AT_name
// matches the given string
//----------------------------------------------------------------------
-typedef struct FindCallbackStringInfoTag
-{
- const char* name;
- bool ignore_case;
- RegularExpression* regex;
- vector<dw_offset_t>& die_offsets;
+typedef struct FindCallbackStringInfoTag {
+ const char *name;
+ bool ignore_case;
+ RegularExpression *regex;
+ vector<dw_offset_t> &die_offsets;
} FindCallbackStringInfo;
-static dw_offset_t FindCallbackString
-(
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- DWARFDebugInfoEntry* die,
- const dw_offset_t next_offset,
- const uint32_t curr_depth,
- void* userData
-)
-{
- FindCallbackStringInfo* info = (FindCallbackStringInfo*)userData;
+static dw_offset_t
+FindCallbackString(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ DWARFDebugInfoEntry *die, const dw_offset_t next_offset,
+ const uint32_t curr_depth, void *userData) {
+ FindCallbackStringInfo *info = (FindCallbackStringInfo *)userData;
- if (die)
- {
- const char* die_name = die->GetName(dwarf2Data, cu);
- if (die_name)
- {
- if (info->regex)
- {
- if (info->regex->Execute(die_name))
- info->die_offsets.push_back(die->GetOffset());
- }
- else
- {
- if ((info->ignore_case ? strcasecmp(die_name, info->name) : strcmp(die_name, info->name)) == 0)
- info->die_offsets.push_back(die->GetOffset());
- }
- }
- }
+ if (!die)
+ return next_offset;
- // Just return the current offset to parse the next CU or DIE entry
+ const char *die_name = die->GetName(dwarf2Data, cu);
+ if (!die_name)
return next_offset;
+
+ if (info->regex) {
+ if (info->regex->Execute(llvm::StringRef(die_name)))
+ info->die_offsets.push_back(die->GetOffset());
+ } else {
+ if ((info->ignore_case ? strcasecmp(die_name, info->name)
+ : strcmp(die_name, info->name)) == 0)
+ info->die_offsets.push_back(die->GetOffset());
+ }
+
+ // Just return the current offset to parse the next CU or DIE entry
+ return next_offset;
}
//----------------------------------------------------------------------
@@ -670,16 +563,14 @@ static dw_offset_t FindCallbackString
// .debug_pubnames section). The string must match the entire name
// and case sensitive searches are an option.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfo::Find(const char* name, bool ignore_case, vector<dw_offset_t>& die_offsets) const
-{
- die_offsets.clear();
- if (name && name[0])
- {
- FindCallbackStringInfo info = { name, ignore_case, NULL, die_offsets };
- DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
- }
- return !die_offsets.empty();
+bool DWARFDebugInfo::Find(const char *name, bool ignore_case,
+ vector<dw_offset_t> &die_offsets) const {
+ die_offsets.clear();
+ if (name && name[0]) {
+ FindCallbackStringInfo info = {name, ignore_case, NULL, die_offsets};
+ DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
+ }
+ return !die_offsets.empty();
}
//----------------------------------------------------------------------
@@ -690,11 +581,10 @@ DWARFDebugInfo::Find(const char* name, bool ignore_case, vector<dw_offset_t>& di
// .debug_pubnames section). The string must match the supplied regular
// expression.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfo::Find(RegularExpression& re, vector<dw_offset_t>& die_offsets) const
-{
- die_offsets.clear();
- FindCallbackStringInfo info = { NULL, false, &re, die_offsets };
- DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
- return !die_offsets.empty();
+bool DWARFDebugInfo::Find(RegularExpression &re,
+ vector<dw_offset_t> &die_offsets) const {
+ die_offsets.clear();
+ FindCallbackStringInfo info = {NULL, false, &re, die_offsets};
+ DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
+ return !die_offsets.empty();
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index 7783135bdb95..a05a8886bb48 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -10,78 +10,82 @@
#ifndef SymbolFileDWARF_DWARFDebugInfo_h_
#define SymbolFileDWARF_DWARFDebugInfo_h_
-#include <vector>
#include <map>
+#include <vector>
+#include "DWARFDIE.h"
+#include "SymbolFileDWARF.h"
#include "lldb/lldb-private.h"
#include "lldb/lldb-private.h"
-#include "SymbolFileDWARF.h"
-#include "DWARFDIE.h"
-typedef std::multimap<const char*, dw_offset_t, CStringCompareFunctionObject> CStringToDIEMap;
+typedef std::multimap<const char *, dw_offset_t, CStringCompareFunctionObject>
+ CStringToDIEMap;
typedef CStringToDIEMap::iterator CStringToDIEMapIter;
typedef CStringToDIEMap::const_iterator CStringToDIEMapConstIter;
-class DWARFDebugInfo
-{
+class DWARFDebugInfo {
public:
- typedef dw_offset_t (*Callback)(
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- DWARFDebugInfoEntry* die,
- const dw_offset_t next_offset,
- const uint32_t depth,
- void* userData);
-
- DWARFDebugInfo();
- void SetDwarfData(SymbolFileDWARF* dwarf2Data);
-
- size_t GetNumCompileUnits();
- bool ContainsCompileUnit (const DWARFCompileUnit *cu) const;
- DWARFCompileUnit* GetCompileUnitAtIndex (uint32_t idx);
- DWARFCompileUnit* GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
- DWARFCompileUnit* GetCompileUnitContainingDIEOffset (dw_offset_t die_offset);
- DWARFCompileUnit* GetCompileUnit(const DIERef& die_ref);
- DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
- DWARFDIE GetDIE (const DIERef& die_ref);
-
- void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth);
- static void Parse(SymbolFileDWARF* parser, Callback callback, void* userData);
- static void Verify(lldb_private::Stream *s, SymbolFileDWARF* dwarf2Data);
- static void Dump(lldb_private::Stream *s, SymbolFileDWARF* dwarf2Data, const uint32_t die_offset, const uint32_t recurse_depth);
- bool Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const;
- bool Find(lldb_private::RegularExpression& re, std::vector<dw_offset_t>& die_offsets) const;
-
- enum
- {
- eDumpFlag_Verbose = (1<<0), // Verbose dumping
- eDumpFlag_ShowForm = (1<<1), // Show the DW_form type
- eDumpFlag_ShowAncestors = (1<<2) // Show all parent DIEs when dumping single DIEs
- };
-
- DWARFDebugAranges &
- GetCompileUnitAranges ();
+ typedef dw_offset_t (*Callback)(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ DWARFDebugInfoEntry *die,
+ const dw_offset_t next_offset,
+ const uint32_t depth, void *userData);
+
+ DWARFDebugInfo();
+ void SetDwarfData(SymbolFileDWARF *dwarf2Data);
+
+ size_t GetNumCompileUnits();
+ bool ContainsCompileUnit(const DWARFCompileUnit *cu) const;
+ DWARFCompileUnit *GetCompileUnitAtIndex(uint32_t idx);
+ DWARFCompileUnit *GetCompileUnit(dw_offset_t cu_offset,
+ uint32_t *idx_ptr = NULL);
+ DWARFCompileUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset);
+ DWARFCompileUnit *GetCompileUnit(const DIERef &die_ref);
+ DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
+ DWARFDIE GetDIE(const DIERef &die_ref);
+
+ void Dump(lldb_private::Stream *s, const uint32_t die_offset,
+ const uint32_t recurse_depth);
+ static void Parse(SymbolFileDWARF *parser, Callback callback, void *userData);
+ static void Verify(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data);
+ static void Dump(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data,
+ const uint32_t die_offset, const uint32_t recurse_depth);
+ bool Find(const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offsets) const;
+ bool Find(lldb_private::RegularExpression &re,
+ std::vector<dw_offset_t> &die_offsets) const;
+
+ enum {
+ eDumpFlag_Verbose = (1 << 0), // Verbose dumping
+ eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type
+ eDumpFlag_ShowAncestors =
+ (1 << 2) // Show all parent DIEs when dumping single DIEs
+ };
+
+ DWARFDebugAranges &GetCompileUnitAranges();
protected:
- typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
+ typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
- static bool
- OffsetLessThanCompileUnitOffset (dw_offset_t offset, const DWARFCompileUnitSP& cu_sp);
+ static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset,
+ const DWARFCompileUnitSP &cu_sp);
- typedef std::vector<DWARFCompileUnitSP> CompileUnitColl;
+ typedef std::vector<DWARFCompileUnitSP> CompileUnitColl;
- //----------------------------------------------------------------------
- // Member variables
- //----------------------------------------------------------------------
- SymbolFileDWARF* m_dwarf2Data;
- CompileUnitColl m_compile_units;
- std::unique_ptr<DWARFDebugAranges> m_cu_aranges_ap; // A quick address to compile unit table
+ //----------------------------------------------------------------------
+ // Member variables
+ //----------------------------------------------------------------------
+ SymbolFileDWARF *m_dwarf2Data;
+ CompileUnitColl m_compile_units;
+ std::unique_ptr<DWARFDebugAranges>
+ m_cu_aranges_ap; // A quick address to compile unit table
private:
- // All parsing needs to be done partially any managed by this class as accessors are called.
- void ParseCompileUnitHeadersIfNeeded();
+ // All parsing needs to be done partially any managed by this class as
+ // accessors are called.
+ void ParseCompileUnitHeadersIfNeeded();
- DISALLOW_COPY_AND_ASSIGN (DWARFDebugInfo);
+ DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo);
};
-#endif // SymbolFileDWARF_DWARFDebugInfo_h_
+#endif // SymbolFileDWARF_DWARFDebugInfo_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index f48d8fc9eeb2..a824c4ac6afe 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -19,13 +19,13 @@
#include "lldb/Symbol/ObjectFile.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
+#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
-#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
-#include "DWARFDebugRanges.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDwo.h"
@@ -33,159 +33,157 @@ using namespace lldb_private;
using namespace std;
extern int g_verbose;
-bool
-DWARFDebugInfoEntry::FastExtract
-(
- const DWARFDataExtractor& debug_info_data,
- const DWARFCompileUnit* cu,
- const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
- lldb::offset_t *offset_ptr
-)
-{
- 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));
- m_abbr_idx = abbr_idx;
-
- //assert (fixed_form_sizes); // For best performance this should be specified!
-
- if (m_abbr_idx)
- {
- lldb::offset_t offset = *offset_ptr;
-
- const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
-
- if (abbrevDecl == NULL)
- {
- cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid abbreviation code %u, please file a bug and attach the file at the start of this error message",
- m_offset,
- (unsigned)abbr_idx);
- // WE can't parse anymore if the DWARF is borked...
- *offset_ptr = UINT32_MAX;
- return false;
- }
- m_tag = abbrevDecl->Tag();
- m_has_children = abbrevDecl->HasChildren();
- // Skip all data in the .debug_info for the attributes
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_form_t form;
- for (i=0; i<numAttributes; ++i)
- {
- form = abbrevDecl->GetFormByIndexUnchecked(i);
+bool DWARFDebugInfoEntry::FastExtract(
+ const DWARFDataExtractor &debug_info_data, const DWARFCompileUnit *cu,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ lldb::offset_t *offset_ptr) {
+ 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));
+ m_abbr_idx = abbr_idx;
+
+ // assert (fixed_form_sizes); // For best performance this should be
+ // specified!
+
+ if (m_abbr_idx) {
+ lldb::offset_t offset = *offset_ptr;
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
- if (fixed_skip_size)
- offset += fixed_skip_size;
- else
- {
- bool form_is_indirect = false;
- do
- {
- form_is_indirect = false;
- uint32_t form_size = 0;
- switch (form)
- {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
- case DW_FORM_exprloc :
- case DW_FORM_block : form_size = debug_info_data.GetULEB128 (&offset); break;
- case DW_FORM_block1 : form_size = debug_info_data.GetU8_unchecked (&offset); break;
- case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break;
- case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&offset);break;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string :
- debug_info_data.GetCStr (&offset);
- break;
-
- // Compile unit address sized values
- case DW_FORM_addr :
- form_size = cu->GetAddressByteSize();
- break;
- case DW_FORM_ref_addr :
- if (cu->GetVersion() <= 2)
- form_size = cu->GetAddressByteSize();
- else
- form_size = cu->IsDWARF64() ? 8 : 4;
- break;
-
- // 0 sized form
- case DW_FORM_flag_present:
- form_size = 0;
- break;
-
- // 1 byte values
- case DW_FORM_data1 :
- case DW_FORM_flag :
- case DW_FORM_ref1 :
- form_size = 1;
- break;
-
- // 2 byte values
- case DW_FORM_data2 :
- case DW_FORM_ref2 :
- form_size = 2;
- break;
-
- // 4 byte values
- case DW_FORM_data4 :
- case DW_FORM_ref4 :
- form_size = 4;
- break;
-
- // 8 byte values
- case DW_FORM_data8 :
- case DW_FORM_ref8 :
- case DW_FORM_ref_sig8 :
- form_size = 8;
- break;
-
- // 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);
- break;
-
- case DW_FORM_indirect :
- form_is_indirect = true;
- form = debug_info_data.GetULEB128 (&offset);
- break;
-
- case DW_FORM_strp :
- case DW_FORM_sec_offset :
- if (cu->IsDWARF64 ())
- debug_info_data.GetU64 (offset_ptr);
- else
- debug_info_data.GetU32 (offset_ptr);
- break;
-
- default:
- *offset_ptr = m_offset;
- return false;
- }
- offset += form_size;
-
- } while (form_is_indirect);
- }
- }
- *offset_ptr = offset;
- return true;
- }
- else
- {
- m_tag = 0;
- m_has_children = false;
- return true; // NULL debug tag entry
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
+
+ if (abbrevDecl == NULL) {
+ cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
+ "attach the file at the start of this error message",
+ m_offset, (unsigned)abbr_idx);
+ // WE can't parse anymore if the DWARF is borked...
+ *offset_ptr = UINT32_MAX;
+ return false;
}
+ m_tag = abbrevDecl->Tag();
+ m_has_children = abbrevDecl->HasChildren();
+ // Skip all data in the .debug_info for the attributes
+ const uint32_t numAttributes = abbrevDecl->NumAttributes();
+ uint32_t i;
+ dw_form_t form;
+ for (i = 0; i < numAttributes; ++i) {
+ form = abbrevDecl->GetFormByIndexUnchecked(i);
+
+ const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ if (fixed_skip_size)
+ offset += fixed_skip_size;
+ else {
+ bool form_is_indirect = false;
+ do {
+ form_is_indirect = false;
+ uint32_t form_size = 0;
+ switch (form) {
+ // Blocks if inlined data that have a length field and the data bytes
+ // inlined in the .debug_info
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ form_size = debug_info_data.GetULEB128(&offset);
+ break;
+ case DW_FORM_block1:
+ form_size = debug_info_data.GetU8_unchecked(&offset);
+ break;
+ case DW_FORM_block2:
+ form_size = debug_info_data.GetU16_unchecked(&offset);
+ break;
+ case DW_FORM_block4:
+ form_size = debug_info_data.GetU32_unchecked(&offset);
+ break;
+
+ // Inlined NULL terminated C-strings
+ case DW_FORM_string:
+ debug_info_data.GetCStr(&offset);
+ break;
+
+ // Compile unit address sized values
+ case DW_FORM_addr:
+ form_size = cu->GetAddressByteSize();
+ break;
+ case DW_FORM_ref_addr:
+ if (cu->GetVersion() <= 2)
+ form_size = cu->GetAddressByteSize();
+ else
+ form_size = cu->IsDWARF64() ? 8 : 4;
+ break;
+
+ // 0 sized form
+ case DW_FORM_flag_present:
+ form_size = 0;
+ break;
+
+ // 1 byte values
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ form_size = 1;
+ break;
+
+ // 2 byte values
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ form_size = 2;
+ break;
+
+ // 4 byte values
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ form_size = 4;
+ break;
+
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ form_size = 8;
+ break;
+
+ // 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);
+ break;
+
+ case DW_FORM_indirect:
+ form_is_indirect = true;
+ form = debug_info_data.GetULEB128(&offset);
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_sec_offset:
+ if (cu->IsDWARF64())
+ debug_info_data.GetU64(offset_ptr);
+ else
+ debug_info_data.GetU32(offset_ptr);
+ break;
- return false;
+ default:
+ *offset_ptr = m_offset;
+ return false;
+ }
+ offset += form_size;
+
+ } while (form_is_indirect);
+ }
+ }
+ *offset_ptr = offset;
+ return true;
+ } else {
+ m_tag = 0;
+ m_has_children = false;
+ return true; // NULL debug tag entry
+ }
+
+ return false;
}
//----------------------------------------------------------------------
@@ -195,165 +193,164 @@ DWARFDebugInfoEntry::FastExtract
// .debug_info and .debug_abbrev data within the SymbolFileDWARF class
// starting at the given offset
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::Extract
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- lldb::offset_t *offset_ptr
-)
-{
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-// const DWARFDataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
- const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
- lldb::offset_t offset = *offset_ptr;
-// if (offset >= cu_end_offset)
-// Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset);
- if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
- {
- m_offset = offset;
-
- const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
- assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
- m_abbr_idx = abbr_idx;
- if (abbr_idx)
- {
- const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
-
- if (abbrevDecl)
- {
- m_tag = abbrevDecl->Tag();
- m_has_children = abbrevDecl->HasChildren();
-
- bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
- if (cu && isCompileUnitTag)
- const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0);
-
- // 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);
-
- 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<DWARFCompileUnit*>(cu)->SetBaseAddress(form_value.Address());
- }
- }
- else
- {
- bool form_is_indirect = false;
- do
- {
- form_is_indirect = false;
- uint32_t form_size = 0;
- switch (form)
- {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
- case DW_FORM_exprloc :
- case DW_FORM_block : form_size = debug_info_data.GetULEB128(&offset); break;
- case DW_FORM_block1 : form_size = debug_info_data.GetU8(&offset); break;
- case DW_FORM_block2 : form_size = debug_info_data.GetU16(&offset); break;
- case DW_FORM_block4 : form_size = debug_info_data.GetU32(&offset); break;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string : debug_info_data.GetCStr(&offset); break;
-
- // Compile unit address sized values
- case DW_FORM_addr :
- form_size = cu->GetAddressByteSize();
- break;
- case DW_FORM_ref_addr :
- if (cu->GetVersion() <= 2)
- form_size = cu->GetAddressByteSize();
- else
- form_size = cu->IsDWARF64() ? 8 : 4;
- break;
-
- // 0 sized form
- case DW_FORM_flag_present:
- form_size = 0;
- break;
-
- // 1 byte values
- case DW_FORM_data1 :
- case DW_FORM_flag :
- case DW_FORM_ref1 :
- form_size = 1;
- break;
-
- // 2 byte values
- case DW_FORM_data2 :
- case DW_FORM_ref2 :
- form_size = 2;
- break;
-
- // 4 byte values
- case DW_FORM_data4 :
- case DW_FORM_ref4 :
- form_size = 4;
- break;
-
- // 8 byte values
- case DW_FORM_data8 :
- case DW_FORM_ref8 :
- case DW_FORM_ref_sig8 :
- form_size = 8;
- break;
-
- // 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);
- break;
-
- case DW_FORM_indirect :
- form = debug_info_data.GetULEB128(&offset);
- form_is_indirect = true;
- break;
-
- case DW_FORM_strp :
- case DW_FORM_sec_offset :
- if (cu->IsDWARF64 ())
- debug_info_data.GetU64 (offset_ptr);
- else
- debug_info_data.GetU32 (offset_ptr);
- break;
-
- default:
- *offset_ptr = offset;
- return false;
- }
-
- offset += form_size;
- } while (form_is_indirect);
- }
- }
- *offset_ptr = offset;
- return true;
+bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ lldb::offset_t *offset_ptr) {
+ const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+ // const DWARFDataExtractor& debug_str_data =
+ // dwarf2Data->get_debug_str_data();
+ const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
+ lldb::offset_t offset = *offset_ptr;
+ // if (offset >= cu_end_offset)
+ // Log::Error("DIE at offset 0x%8.8x is beyond the end of the current
+ // compile unit (0x%8.8x)", m_offset, cu_end_offset);
+ if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) {
+ m_offset = offset;
+
+ const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
+ assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
+ m_abbr_idx = abbr_idx;
+ if (abbr_idx) {
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
+
+ if (abbrevDecl) {
+ m_tag = abbrevDecl->Tag();
+ m_has_children = abbrevDecl->HasChildren();
+
+ bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
+ if (cu && isCompileUnitTag)
+ const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0);
+
+ // 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);
+
+ 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<DWARFCompileUnit *>(cu)->SetBaseAddress(
+ form_value.Address());
}
+ } else {
+ bool form_is_indirect = false;
+ do {
+ form_is_indirect = false;
+ uint32_t form_size = 0;
+ switch (form) {
+ // Blocks if inlined data that have a length field and the data
+ // bytes
+ // inlined in the .debug_info
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ form_size = debug_info_data.GetULEB128(&offset);
+ break;
+ case DW_FORM_block1:
+ form_size = debug_info_data.GetU8(&offset);
+ break;
+ case DW_FORM_block2:
+ form_size = debug_info_data.GetU16(&offset);
+ break;
+ case DW_FORM_block4:
+ form_size = debug_info_data.GetU32(&offset);
+ break;
+
+ // Inlined NULL terminated C-strings
+ case DW_FORM_string:
+ debug_info_data.GetCStr(&offset);
+ break;
+
+ // Compile unit address sized values
+ case DW_FORM_addr:
+ form_size = cu->GetAddressByteSize();
+ break;
+ case DW_FORM_ref_addr:
+ if (cu->GetVersion() <= 2)
+ form_size = cu->GetAddressByteSize();
+ else
+ form_size = cu->IsDWARF64() ? 8 : 4;
+ break;
+
+ // 0 sized form
+ case DW_FORM_flag_present:
+ form_size = 0;
+ break;
+
+ // 1 byte values
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ form_size = 1;
+ break;
+
+ // 2 byte values
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ form_size = 2;
+ break;
+
+ // 4 byte values
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ form_size = 4;
+ break;
+
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ form_size = 8;
+ break;
+
+ // 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);
+ break;
+
+ case DW_FORM_indirect:
+ form = debug_info_data.GetULEB128(&offset);
+ form_is_indirect = true;
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_sec_offset:
+ if (cu->IsDWARF64())
+ debug_info_data.GetU64(offset_ptr);
+ else
+ debug_info_data.GetU32(offset_ptr);
+ break;
+
+ default:
+ *offset_ptr = offset;
+ return false;
+ }
+
+ offset += form_size;
+ } while (form_is_indirect);
+ }
}
- else
- {
- m_tag = 0;
- m_has_children = false;
- *offset_ptr = offset;
- return true; // NULL debug tag entry
- }
+ *offset_ptr = offset;
+ return true;
+ }
+ } else {
+ m_tag = 0;
+ m_has_children = false;
+ *offset_ptr = offset;
+ return true; // NULL debug tag entry
}
+ }
- return false;
+ return false;
}
//----------------------------------------------------------------------
@@ -362,20 +359,15 @@ DWARFDebugInfoEntry::Extract
// Dumps all of a debug information entries parents up until oldest and
// all of it's attributes to the specified stream.
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::DumpAncestry
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const DWARFDebugInfoEntry* oldest,
- Stream &s,
- uint32_t recurse_depth
-) const
-{
- const DWARFDebugInfoEntry* parent = GetParent();
- if (parent && parent != oldest)
- parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
- Dump(dwarf2Data, cu, s, recurse_depth);
+void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const DWARFDebugInfoEntry *oldest,
+ Stream &s,
+ uint32_t recurse_depth) const {
+ const DWARFDebugInfoEntry *parent = GetParent();
+ if (parent && parent != oldest)
+ parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
+ Dump(dwarf2Data, cu, s, recurse_depth);
}
//----------------------------------------------------------------------
@@ -385,238 +377,206 @@ DWARFDebugInfoEntry::DumpAncestry
// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
// attributes.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::GetDIENamesAndRanges
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const char * &name,
- const char * &mangled,
- DWARFRangeList& ranges,
- int& decl_file,
- int& decl_line,
- int& decl_column,
- int& call_file,
- int& call_line,
- int& call_column,
- DWARFExpression *frame_base
-) const
-{
- if (dwarf2Data == nullptr)
- return false;
-
- SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file)
- return GetDIENamesAndRanges(dwo_symbol_file,
- dwo_symbol_file->GetCompileUnit(),
- name,
- mangled,
- ranges,
- decl_file,
- decl_line,
- decl_column,
- call_file,
- call_line,
- call_column,
- frame_base);
-
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- std::vector<DIERef> die_refs;
- bool set_frame_base_loclist_addr = false;
-
- lldb::offset_t offset;
- const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
-
- if (abbrevDecl)
- {
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-
- if (!debug_info_data.ValidOffset(offset))
- return false;
-
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- bool do_offset = false;
+bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, const char *&name,
+ const char *&mangled, DWARFRangeList &ranges, int &decl_file,
+ int &decl_line, int &decl_column, int &call_file, int &call_line,
+ int &call_column, DWARFExpression *frame_base) const {
+ if (dwarf2Data == nullptr)
+ return false;
- for (i=0; i<numAttributes; ++i)
- {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
- DWARFFormValue form_value(cu, form);
- if (form_value.ExtractValue(debug_info_data, &offset))
- {
- switch (attr)
- {
- case DW_AT_low_pc:
- lo_pc = form_value.Address();
-
- if (do_offset)
- hi_pc += lo_pc;
- do_offset = false;
- break;
-
- case DW_AT_entry_pc:
- lo_pc = form_value.Address();
- break;
-
- case DW_AT_high_pc:
- if (form_value.Form() == DW_FORM_addr ||
- form_value.Form() == DW_FORM_GNU_addr_index)
- {
- hi_pc = form_value.Address();
- }
- else
- {
- hi_pc = form_value.Unsigned();
- if (lo_pc == LLDB_INVALID_ADDRESS)
- do_offset = hi_pc != LLDB_INVALID_ADDRESS;
- else
- hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save on relocations
- }
- break;
-
- case DW_AT_ranges:
- {
- const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
- if (debug_ranges)
- {
- debug_ranges->FindRanges(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
- {
- 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:
- if (name == NULL)
- name = form_value.AsCString();
- break;
-
- case DW_AT_MIPS_linkage_name:
- case DW_AT_linkage_name:
- if (mangled == NULL)
- mangled = form_value.AsCString();
- break;
-
- case DW_AT_abstract_origin:
- die_refs.emplace_back(form_value);
- break;
-
- case DW_AT_specification:
- die_refs.emplace_back(form_value);
- break;
-
- case DW_AT_decl_file:
- if (decl_file == 0)
- decl_file = form_value.Unsigned();
- break;
-
- case DW_AT_decl_line:
- if (decl_line == 0)
- decl_line = form_value.Unsigned();
- break;
-
- case DW_AT_decl_column:
- if (decl_column == 0)
- decl_column = form_value.Unsigned();
- break;
-
- case DW_AT_call_file:
- if (call_file == 0)
- call_file = form_value.Unsigned();
- break;
-
- case DW_AT_call_line:
- if (call_line == 0)
- call_line = form_value.Unsigned();
- break;
-
- case DW_AT_call_column:
- if (call_column == 0)
- call_column = form_value.Unsigned();
- break;
-
- case DW_AT_frame_base:
- if (frame_base)
- {
- if (form_value.BlockData())
- {
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length);
- }
- else
- {
- const DWARFDataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(cu, debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0)
- {
- frame_base->SetOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
- if (lo_pc != LLDB_INVALID_ADDRESS)
- {
- assert (lo_pc >= cu->GetBaseAddress());
- frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress());
- }
- else
- {
- set_frame_base_loclist_addr = true;
- }
- }
- }
- }
- break;
-
- default:
- break;
+ SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
+ if (dwo_symbol_file)
+ return GetDIENamesAndRanges(
+ dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled,
+ ranges, decl_file, decl_line, decl_column, call_file, call_line,
+ call_column, frame_base);
+
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ std::vector<DIERef> die_refs;
+ bool set_frame_base_loclist_addr = false;
+
+ lldb::offset_t offset;
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+
+ lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
+
+ if (abbrevDecl) {
+ const DWARFDataExtractor &debug_info_data =
+ dwarf2Data->get_debug_info_data();
+
+ if (!debug_info_data.ValidOffset(offset))
+ 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);
+ if (form_value.ExtractValue(debug_info_data, &offset)) {
+ switch (attr) {
+ case DW_AT_low_pc:
+ lo_pc = form_value.Address();
+
+ if (do_offset)
+ hi_pc += lo_pc;
+ do_offset = false;
+ break;
+
+ case DW_AT_entry_pc:
+ lo_pc = form_value.Address();
+ break;
+
+ case DW_AT_high_pc:
+ if (form_value.Form() == DW_FORM_addr ||
+ form_value.Form() == DW_FORM_GNU_addr_index) {
+ hi_pc = form_value.Address();
+ } else {
+ hi_pc = form_value.Unsigned();
+ if (lo_pc == LLDB_INVALID_ADDRESS)
+ do_offset = hi_pc != LLDB_INVALID_ADDRESS;
+ else
+ hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
+ // on relocations
+ }
+ 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 {
+ 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:
+ if (name == NULL)
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
+ if (mangled == NULL)
+ mangled = form_value.AsCString();
+ break;
+
+ case DW_AT_abstract_origin:
+ die_refs.emplace_back(form_value);
+ break;
+
+ case DW_AT_specification:
+ die_refs.emplace_back(form_value);
+ break;
+
+ case DW_AT_decl_file:
+ if (decl_file == 0)
+ decl_file = form_value.Unsigned();
+ break;
+
+ case DW_AT_decl_line:
+ if (decl_line == 0)
+ decl_line = form_value.Unsigned();
+ break;
+
+ case DW_AT_decl_column:
+ if (decl_column == 0)
+ decl_column = form_value.Unsigned();
+ break;
+
+ case DW_AT_call_file:
+ if (call_file == 0)
+ call_file = form_value.Unsigned();
+ break;
+
+ case DW_AT_call_line:
+ if (call_line == 0)
+ call_line = form_value.Unsigned();
+ break;
+
+ case DW_AT_call_column:
+ if (call_column == 0)
+ call_column = form_value.Unsigned();
+ break;
+
+ case DW_AT_frame_base:
+ if (frame_base) {
+ if (form_value.BlockData()) {
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ frame_base->SetOpcodeData(module, debug_info_data, block_offset,
+ block_length);
+ } else {
+ const DWARFDataExtractor &debug_loc_data =
+ dwarf2Data->get_debug_loc_data();
+ const dw_offset_t debug_loc_offset = form_value.Unsigned();
+
+ size_t loc_list_length = DWARFExpression::LocationListSize(
+ cu, debug_loc_data, debug_loc_offset);
+ if (loc_list_length > 0) {
+ frame_base->SetOpcodeData(module, debug_loc_data,
+ debug_loc_offset, loc_list_length);
+ if (lo_pc != LLDB_INVALID_ADDRESS) {
+ assert(lo_pc >= cu->GetBaseAddress());
+ frame_base->SetLocationListSlide(lo_pc -
+ cu->GetBaseAddress());
+ } else {
+ set_frame_base_loclist_addr = true;
}
+ }
}
- }
- }
+ }
+ break;
- if (ranges.IsEmpty())
- {
- if (lo_pc != LLDB_INVALID_ADDRESS)
- {
- if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
- ranges.Append(DWARFRangeList::Entry (lo_pc, hi_pc - lo_pc));
- else
- ranges.Append(DWARFRangeList::Entry (lo_pc, 0));
+ default:
+ break;
}
+ }
}
-
- if (set_frame_base_loclist_addr)
- {
- dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
- assert (lowest_range_pc >= cu->GetBaseAddress());
- frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress());
+ }
+
+ if (ranges.IsEmpty()) {
+ if (lo_pc != LLDB_INVALID_ADDRESS) {
+ if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
+ ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
+ else
+ ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
}
-
- if (ranges.IsEmpty() || name == NULL || mangled == NULL)
- {
- for (const DIERef& die_ref : die_refs)
- {
- if (die_ref.die_offset != DW_INVALID_OFFSET)
- {
- DWARFDIE die = dwarf2Data->GetDIE(die_ref);
- if (die)
- die.GetDIE()->GetDIENamesAndRanges(die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
- }
- }
+ }
+
+ if (set_frame_base_loclist_addr) {
+ dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
+ assert(lowest_range_pc >= cu->GetBaseAddress());
+ frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
+ }
+
+ if (ranges.IsEmpty() || name == NULL || mangled == NULL) {
+ for (const DIERef &die_ref : die_refs) {
+ if (die_ref.die_offset != DW_INVALID_OFFSET) {
+ DWARFDIE die = dwarf2Data->GetDIE(die_ref);
+ if (die)
+ die.GetDIE()->GetDIENamesAndRanges(
+ die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file,
+ decl_line, decl_column, call_file, call_line, call_column);
+ }
}
- return !ranges.IsEmpty();
+ }
+ return !ranges.IsEmpty();
}
//----------------------------------------------------------------------
@@ -625,95 +585,74 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
// Dumps a debug information entry and all of it's attributes to the
// specified stream.
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::Dump
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- Stream &s,
- uint32_t recurse_depth
-) const
-{
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
- lldb::offset_t offset = m_offset;
-
- if (debug_info_data.ValidOffset(offset))
- {
- dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
-
- s.Printf("\n0x%8.8x: ", m_offset);
- s.Indent();
- if (abbrCode != m_abbr_idx)
- {
- s.Printf( "error: DWARF has been modified\n");
- }
- else if (abbrCode)
- {
- const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode);
-
- if (abbrevDecl)
- {
- s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
- s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' ');
-
- // 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);
-
- DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form);
- }
+void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu, Stream &s,
+ uint32_t recurse_depth) const {
+ const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+ lldb::offset_t offset = m_offset;
+
+ if (debug_info_data.ValidOffset(offset)) {
+ dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
+
+ s.Printf("\n0x%8.8x: ", m_offset);
+ s.Indent();
+ if (abbrCode != m_abbr_idx) {
+ s.Printf("error: DWARF has been modified\n");
+ } else if (abbrCode) {
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode);
+
+ if (abbrevDecl) {
+ s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
+ s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
+
+ // 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);
- const DWARFDebugInfoEntry* child = GetFirstChild();
- if (recurse_depth > 0 && child)
- {
- s.IndentMore();
-
- while (child)
- {
- child->Dump(dwarf2Data, cu, s, recurse_depth-1);
- child = child->GetSibling();
- }
- s.IndentLess();
- }
- }
- else
- s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode);
+ DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
+ form);
}
- else
- {
- s.Printf( "NULL\n");
+
+ const DWARFDebugInfoEntry *child = GetFirstChild();
+ if (recurse_depth > 0 && child) {
+ s.IndentMore();
+
+ while (child) {
+ child->Dump(dwarf2Data, cu, s, recurse_depth - 1);
+ child = child->GetSibling();
+ }
+ s.IndentLess();
}
+ } else
+ s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
+ "code: %u\n",
+ abbrCode);
+ } else {
+ s.Printf("NULL\n");
}
+ }
}
-void
-DWARFDebugInfoEntry::DumpLocation
-(
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- Stream &s
-) const
-{
- const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly();
- const char *cu_name = NULL;
- if (cu_die)
- cu_name = cu_die.GetName ();
- const char *obj_file_name = NULL;
- ObjectFile *obj_file = dwarf2Data->GetObjectFile();
- if (obj_file)
- obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
- const char *die_name = GetName (dwarf2Data, cu);
- s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)",
- cu->GetOffset(),
- GetOffset(),
- die_name ? die_name : "",
- cu_name ? cu_name : "<NULL>",
- obj_file_name ? obj_file_name : "<NULL>");
+void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu, Stream &s) const {
+ const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly();
+ const char *cu_name = NULL;
+ if (cu_die)
+ cu_name = cu_die.GetName();
+ const char *obj_file_name = NULL;
+ ObjectFile *obj_file = dwarf2Data->GetObjectFile();
+ if (obj_file)
+ obj_file_name =
+ obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
+ const char *die_name = GetName(dwarf2Data, cu);
+ s.Printf("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(),
+ GetOffset(), die_name ? die_name : "", cu_name ? cu_name : "<NULL>",
+ obj_file_name ? obj_file_name : "<NULL>");
}
//----------------------------------------------------------------------
@@ -723,162 +662,142 @@ DWARFDebugInfoEntry::DumpLocation
// special display of attributes is done (disassemble location lists,
// show enumeration values for attributes, etc).
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::DumpAttribute
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const DWARFDataExtractor& debug_info_data,
- lldb::offset_t *offset_ptr,
- Stream &s,
- dw_attr_t attr,
- dw_form_t form
-)
-{
- bool verbose = s.GetVerbose();
- bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
-
- if (verbose)
- s.Offset (*offset_ptr);
- else
- s.Printf (" ");
- s.Indent(DW_AT_value_to_name(attr));
-
- if (show_form)
- {
- s.Printf( "[%s", DW_FORM_value_to_name(form));
+void DWARFDebugInfoEntry::DumpAttribute(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
+ Stream &s, dw_attr_t attr, dw_form_t form) {
+ bool verbose = s.GetVerbose();
+ bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
+
+ if (verbose)
+ s.Offset(*offset_ptr);
+ else
+ s.Printf(" ");
+ s.Indent(DW_AT_value_to_name(attr));
+
+ if (show_form) {
+ s.Printf("[%s", DW_FORM_value_to_name(form));
+ }
+
+ DWARFFormValue form_value(cu, form);
+
+ if (!form_value.ExtractValue(debug_info_data, offset_ptr))
+ return;
+
+ if (show_form) {
+ if (form == DW_FORM_indirect) {
+ s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
}
- DWARFFormValue form_value(cu, form);
+ s.PutCString("] ");
+ }
- if (!form_value.ExtractValue(debug_info_data, offset_ptr))
- return;
+ s.PutCString("( ");
- if (show_form)
- {
- if (form == DW_FORM_indirect)
- {
- s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form()));
- }
+ // Always dump form value if verbose is enabled
+ if (verbose) {
+ form_value.Dump(s);
+ }
- s.PutCString("] ");
- }
+ // Check to see if we have any special attribute formatters
+ switch (attr) {
+ case DW_AT_stmt_list:
+ if (verbose)
+ s.PutCString(" ( ");
+ s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
+ if (verbose)
+ s.PutCString(" )");
+ break;
- s.PutCString("( ");
+ case DW_AT_language:
+ if (verbose)
+ s.PutCString(" ( ");
+ s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
+ if (verbose)
+ s.PutCString(" )");
+ break;
- // Always dump form value if verbose is enabled
+ case DW_AT_encoding:
+ if (verbose)
+ s.PutCString(" ( ");
+ s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
if (verbose)
- {
+ s.PutCString(" )");
+ break;
+
+ case DW_AT_frame_base:
+ case DW_AT_location:
+ case DW_AT_data_member_location: {
+ const uint8_t *blockData = form_value.BlockData();
+ if (blockData) {
+ if (!verbose)
form_value.Dump(s);
- }
-
-
- // Check to see if we have any special attribute formatters
- switch (attr)
- {
- case DW_AT_stmt_list:
- if ( verbose ) s.PutCString(" ( ");
- s.Printf( "0x%8.8" PRIx64, form_value.Unsigned());
- if ( verbose ) s.PutCString(" )");
- break;
-
- case DW_AT_language:
- if ( verbose ) s.PutCString(" ( ");
- s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
- if ( verbose ) s.PutCString(" )");
- break;
-
- case DW_AT_encoding:
- if ( verbose ) s.PutCString(" ( ");
- s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
- if ( verbose ) s.PutCString(" )");
- break;
-
- case DW_AT_frame_base:
- case DW_AT_location:
- case DW_AT_data_member_location:
- {
- const uint8_t* blockData = form_value.BlockData();
- if (blockData)
- {
- if (!verbose)
- form_value.Dump(s);
-
- // Location description is inlined in data in the form value
- DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned());
- if ( verbose ) s.PutCString(" ( ");
- DWARFExpression::PrintDWARFExpression(s,
- locationData,
- DWARFCompileUnit::GetAddressByteSize(cu),
- 4,
- false);
- if ( verbose ) s.PutCString(" )");
- }
- else
- {
- // We have a location list offset as the value that is
- // the offset into the .debug_loc section that describes
- // the value over it's lifetime
- uint64_t debug_loc_offset = form_value.Unsigned();
- if (dwarf2Data)
- {
- if ( !verbose )
- form_value.Dump(s);
- DWARFExpression::PrintDWARFLocationList(s,
- cu,
- dwarf2Data->get_debug_loc_data(),
- debug_loc_offset);
- }
- else
- {
- if ( !verbose )
- form_value.Dump(s);
- }
- }
- }
- break;
-
- case DW_AT_abstract_origin:
- case DW_AT_specification:
- {
- uint64_t abstract_die_offset = form_value.Reference();
- form_value.Dump(s);
- // *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
- if ( verbose ) s.PutCString(" ( ");
- GetName(dwarf2Data, cu, abstract_die_offset, s);
- if ( verbose ) s.PutCString(" )");
- }
- break;
- case DW_AT_type:
- {
- uint64_t type_die_offset = form_value.Reference();
- if (!verbose)
- form_value.Dump(s);
- s.PutCString(" ( ");
- AppendTypeName(dwarf2Data, cu, type_die_offset, s);
- s.PutCString(" )");
- }
- break;
+ // Location description is inlined in data in the form value
+ DWARFDataExtractor locationData(debug_info_data,
+ (*offset_ptr) - form_value.Unsigned(),
+ form_value.Unsigned());
+ if (verbose)
+ s.PutCString(" ( ");
+ DWARFExpression::PrintDWARFExpression(
+ s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
+ if (verbose)
+ s.PutCString(" )");
+ } else {
+ // We have a location list offset as the value that is
+ // the offset into the .debug_loc section that describes
+ // the value over it's lifetime
+ uint64_t debug_loc_offset = form_value.Unsigned();
+ if (dwarf2Data) {
+ if (!verbose)
+ form_value.Dump(s);
+ DWARFExpression::PrintDWARFLocationList(
+ s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
+ } else {
+ if (!verbose)
+ form_value.Dump(s);
+ }
+ }
+ } break;
- case DW_AT_ranges:
- {
- if ( !verbose )
- form_value.Dump(s);
- lldb::offset_t ranges_offset = form_value.Unsigned();
- dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
- if (dwarf2Data)
- DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
- }
- break;
+ case DW_AT_abstract_origin:
+ case DW_AT_specification: {
+ uint64_t abstract_die_offset = form_value.Reference();
+ form_value.Dump(s);
+ // *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
+ if (verbose)
+ s.PutCString(" ( ");
+ GetName(dwarf2Data, cu, abstract_die_offset, s);
+ if (verbose)
+ s.PutCString(" )");
+ } break;
+
+ case DW_AT_type: {
+ uint64_t type_die_offset = form_value.Reference();
+ if (!verbose)
+ form_value.Dump(s);
+ s.PutCString(" ( ");
+ AppendTypeName(dwarf2Data, cu, type_die_offset, s);
+ s.PutCString(" )");
+ } break;
+
+ case DW_AT_ranges: {
+ if (!verbose)
+ form_value.Dump(s);
+ lldb::offset_t ranges_offset = form_value.Unsigned();
+ dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
+ if (dwarf2Data)
+ DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
+ &ranges_offset, base_addr);
+ } break;
- default:
- if ( !verbose )
- form_value.Dump(s);
- break;
- }
+ default:
+ if (!verbose)
+ form_value.Dump(s);
+ break;
+ }
- s.PutCString(" )\n");
+ s.PutCString(" )\n");
}
//----------------------------------------------------------------------
@@ -887,94 +806,78 @@ DWARFDebugInfoEntry::DumpAttribute
// the results. Any duplicate attributes will have the first instance
// take precedence (this can happen for declaration attributes).
//----------------------------------------------------------------------
-size_t
-DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu,
- DWARFFormValue::FixedFormSizes fixed_form_sizes,
- DWARFAttributes& attributes,
- uint32_t curr_depth) const
-{
- SymbolFileDWARF* dwarf2Data = nullptr;
- const DWARFAbbreviationDeclaration* abbrevDecl = nullptr;
- lldb::offset_t offset = 0;
- if (cu)
- {
- if (m_tag != DW_TAG_compile_unit)
- {
- SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file)
- return GetAttributes(dwo_symbol_file->GetCompileUnit(),
- fixed_form_sizes,
- attributes,
- curr_depth);
- }
-
- dwarf2Data = cu->GetSymbolFileDWARF();
- abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+size_t DWARFDebugInfoEntry::GetAttributes(
+ const DWARFCompileUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
+ DWARFAttributes &attributes, uint32_t curr_depth) const {
+ SymbolFileDWARF *dwarf2Data = nullptr;
+ const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
+ lldb::offset_t offset = 0;
+ if (cu) {
+ if (m_tag != DW_TAG_compile_unit) {
+ SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
+ if (dwo_symbol_file)
+ return GetAttributes(dwo_symbol_file->GetCompileUnit(),
+ fixed_form_sizes, attributes, curr_depth);
}
- if (abbrevDecl)
- {
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-
- if (fixed_form_sizes.Empty())
- fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
- 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);
-
- // 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
- // attributes that don't make sense.
- switch (attr)
- {
- case DW_AT_sibling:
- case DW_AT_declaration:
- if (curr_depth > 0)
- {
- // This attribute doesn't make sense when combined with
- // the DIE that references this DIE. We know a DIE is
- // referencing this DIE because curr_depth is not zero
- break;
- }
- LLVM_FALLTHROUGH;
- default:
- attributes.Append(cu, offset, attr, form);
- break;
- }
-
- 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 = const_cast<DWARFCompileUnit*>(cu)->GetDIE(die_offset);
- if (spec_die)
- spec_die.GetAttributes(attributes, curr_depth + 1);
- }
- }
- else
- {
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
- if (fixed_skip_size)
- offset += fixed_skip_size;
- else
- DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
- }
+ dwarf2Data = cu->GetSymbolFileDWARF();
+ abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+ }
+
+ if (abbrevDecl) {
+ const DWARFDataExtractor &debug_info_data =
+ dwarf2Data->get_debug_info_data();
+
+ if (fixed_form_sizes.Empty())
+ fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
+ 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);
+
+ // 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
+ // attributes that don't make sense.
+ switch (attr) {
+ case DW_AT_sibling:
+ case DW_AT_declaration:
+ if (curr_depth > 0) {
+ // This attribute doesn't make sense when combined with
+ // the DIE that references this DIE. We know a DIE is
+ // referencing this DIE because curr_depth is not zero
+ break;
}
+ LLVM_FALLTHROUGH;
+ default:
+ attributes.Append(cu, offset, attr, form);
+ break;
+ }
+
+ 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 =
+ const_cast<DWARFCompileUnit *>(cu)->GetDIE(die_offset);
+ if (spec_die)
+ spec_die.GetAttributes(attributes, curr_depth + 1);
+ }
+ } else {
+ const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ if (fixed_skip_size)
+ offset += fixed_skip_size;
+ else
+ DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
+ }
}
- else
- {
- attributes.Clear();
- }
- return attributes.Size();
-
+ } else {
+ attributes.Clear();
+ }
+ return attributes.Size();
}
//----------------------------------------------------------------------
@@ -985,105 +888,84 @@ DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu,
// if we fail since an offset of zero is invalid for an attribute (it
// would be a compile unit header).
//----------------------------------------------------------------------
-dw_offset_t
-DWARFDebugInfoEntry::GetAttributeValue
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- DWARFFormValue& form_value,
- dw_offset_t* end_attr_offset_ptr,
- bool check_specification_or_abstract_origin
-) const
-{
- SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file && m_tag != DW_TAG_compile_unit)
- return GetAttributeValue(dwo_symbol_file,
- dwo_symbol_file->GetCompileUnit(),
- attr,
- form_value,
- end_attr_offset_ptr,
- check_specification_or_abstract_origin);
-
- lldb::offset_t offset;
- const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- if (abbrevDecl)
- {
- uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
-
- if (attr_idx != DW_INVALID_INDEX)
- {
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-
- uint32_t idx=0;
- while (idx<attr_idx)
- DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
-
- const dw_offset_t attr_offset = offset;
- form_value.SetCompileUnit(cu);
- form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
- if (form_value.ExtractValue(debug_info_data, &offset))
- {
- if (end_attr_offset_ptr)
- *end_attr_offset_ptr = offset;
- return attr_offset;
- }
- }
+dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, DWARFFormValue &form_value,
+ dw_offset_t *end_attr_offset_ptr,
+ bool check_specification_or_abstract_origin) const {
+ SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
+ if (dwo_symbol_file && m_tag != DW_TAG_compile_unit)
+ return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(),
+ attr, form_value, end_attr_offset_ptr,
+ check_specification_or_abstract_origin);
+
+ lldb::offset_t offset;
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+
+ if (abbrevDecl) {
+ uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
+
+ if (attr_idx != DW_INVALID_INDEX) {
+ const DWARFDataExtractor &debug_info_data =
+ dwarf2Data->get_debug_info_data();
+
+ uint32_t idx = 0;
+ while (idx < attr_idx)
+ DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
+ debug_info_data, &offset, cu);
+
+ const dw_offset_t attr_offset = offset;
+ form_value.SetCompileUnit(cu);
+ form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
+ if (form_value.ExtractValue(debug_info_data, &offset)) {
+ if (end_attr_offset_ptr)
+ *end_attr_offset_ptr = offset;
+ return attr_offset;
+ }
+ }
+ }
+
+ if (check_specification_or_abstract_origin) {
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
+ DWARFDIE die =
+ const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
+ if (die) {
+ dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
+ die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
+ false);
+ if (die_offset)
+ return die_offset;
+ }
}
- if (check_specification_or_abstract_origin)
- {
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
- {
- DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference());
- if (die)
- {
- dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(die.GetDWARF(),
- die.GetCU(),
- attr,
- form_value,
- end_attr_offset_ptr,
- false);
- if (die_offset)
- return die_offset;
- }
- }
-
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value))
- {
- DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference());
- if (die)
- {
- dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(die.GetDWARF(),
- die.GetCU(),
- attr,
- form_value,
- end_attr_offset_ptr,
- false);
- if (die_offset)
- return die_offset;
- }
- }
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
+ DWARFDIE die =
+ const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
+ if (die) {
+ dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
+ die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
+ false);
+ if (die_offset)
+ return die_offset;
+ }
}
+ }
- if (!dwo_symbol_file)
- return 0;
+ if (!dwo_symbol_file)
+ return 0;
- DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit();
- if (!dwo_cu)
- return 0;
+ DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
+ if (!dwo_cu)
+ return 0;
- DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
- if (!dwo_cu_die.IsValid())
- return 0;
+ DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
+ if (!dwo_cu_die.IsValid())
+ return 0;
- return dwo_cu_die.GetDIE()->GetAttributeValue(dwo_symbol_file,
- dwo_cu,
- attr,
- form_value,
- end_attr_offset_ptr,
- check_specification_or_abstract_origin);
+ return dwo_cu_die.GetDIE()->GetAttributeValue(
+ dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr,
+ check_specification_or_abstract_origin);
}
//----------------------------------------------------------------------
@@ -1094,19 +976,15 @@ DWARFDebugInfoEntry::GetAttributeValue
// and will only be available as long as the SymbolFileDWARF is still around
// and it's content doesn't change.
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetAttributeValueAsString
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- const char* fail_value,
- bool check_specification_or_abstract_origin) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.AsCString();
- return fail_value;
+const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, const char *fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.AsCString();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1114,20 +992,15 @@ DWARFDebugInfoEntry::GetAttributeValueAsString
//
// Get the value of an attribute as unsigned and return it.
//----------------------------------------------------------------------
-uint64_t
-DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Unsigned();
- return fail_value;
+uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Unsigned();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1135,20 +1008,15 @@ DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
//
// Get the value of an attribute a signed value and return it.
//----------------------------------------------------------------------
-int64_t
-DWARFDebugInfoEntry::GetAttributeValueAsSigned
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- int64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Signed();
- return fail_value;
+int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, int64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Signed();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1157,36 +1025,26 @@ DWARFDebugInfoEntry::GetAttributeValueAsSigned
// Get the value of an attribute as reference and fix up and compile
// unit relative offsets as needed.
//----------------------------------------------------------------------
-uint64_t
-DWARFDebugInfoEntry::GetAttributeValueAsReference
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Reference();
- return fail_value;
+uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Reference();
+ return fail_value;
}
-uint64_t
-DWARFDebugInfoEntry::GetAttributeValueAsAddress
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Address();
- return fail_value;
+uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Address();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1197,27 +1055,20 @@ DWARFDebugInfoEntry::GetAttributeValueAsAddress
//
// Returns the hi_pc or fail_value.
//----------------------------------------------------------------------
-dw_addr_t
-DWARFDebugInfoEntry::GetAttributeHighPC
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t lo_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr, check_specification_or_abstract_origin))
- {
- dw_form_t form = form_value.Form();
- if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
- return form_value.Address();
-
- // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
- return lo_pc + form_value.Unsigned();
- }
- return fail_value;
+dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t lo_pc,
+ uint64_t fail_value, bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
+ check_specification_or_abstract_origin)) {
+ dw_form_t form = form_value.Form();
+ if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
+ return form_value.Address();
+
+ // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
+ return lo_pc + form_value.Unsigned();
+ }
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1228,61 +1079,48 @@ DWARFDebugInfoEntry::GetAttributeHighPC
//
// Returns true or sets lo_pc and hi_pc to fail_value.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::GetAttributeAddressRange
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t& lo_pc,
- dw_addr_t& hi_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value, check_specification_or_abstract_origin);
- if (lo_pc != fail_value)
- {
- hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value, check_specification_or_abstract_origin);
- if (hi_pc != fail_value)
- return true;
- }
- lo_pc = fail_value;
- hi_pc = fail_value;
- return false;
+bool DWARFDebugInfoEntry::GetAttributeAddressRange(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc,
+ dw_addr_t &hi_pc, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value,
+ check_specification_or_abstract_origin);
+ if (lo_pc != fail_value) {
+ hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value,
+ check_specification_or_abstract_origin);
+ if (hi_pc != fail_value)
+ return true;
+ }
+ lo_pc = fail_value;
+ hi_pc = fail_value;
+ return false;
}
-size_t
-DWARFDebugInfoEntry::GetAttributeAddressRanges (SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFRangeList &ranges,
- bool check_hi_lo_pc,
- 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(debug_ranges_offset, ranges);
- ranges.Slide (cu->GetBaseAddress());
- }
- else if (check_hi_lo_pc)
- {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS, check_specification_or_abstract_origin))
- {
- if (lo_pc < hi_pc)
- ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
- }
+size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFRangeList &ranges, bool check_hi_lo_pc,
+ 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());
+ } else if (check_hi_lo_pc) {
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
+ LLDB_INVALID_ADDRESS,
+ check_specification_or_abstract_origin)) {
+ if (lo_pc < hi_pc)
+ ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
}
- return ranges.GetSize();
+ }
+ return ranges.GetSize();
}
//----------------------------------------------------------------------
@@ -1291,14 +1129,9 @@ DWARFDebugInfoEntry::GetAttributeAddressRanges (SymbolFileDWARF* dwarf2Data,
// Get value of the DW_AT_name attribute and return it if one exists,
// else return NULL.
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu
-) const
-{
- return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const {
+ return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
}
//----------------------------------------------------------------------
@@ -1307,31 +1140,28 @@ DWARFDebugInfoEntry::GetName
// Get value of the DW_AT_MIPS_linkage_name attribute and return it if
// one exists, else return the value of the DW_AT_name attribute
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetMangledName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- bool substitute_name_allowed
-) const
-{
- const char* name = nullptr;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true);
- if (name)
- return name;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, true);
- if (name)
- return name;
-
- if (!substitute_name_allowed)
- return nullptr;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+const char *
+DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ bool substitute_name_allowed) const {
+ const char *name = nullptr;
+
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
+ nullptr, true);
+ if (name)
return name;
-}
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
+ true);
+ if (name)
+ return name;
+
+ if (!substitute_name_allowed)
+ return nullptr;
+
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ return name;
+}
//----------------------------------------------------------------------
// GetPubname
@@ -1339,29 +1169,25 @@ DWARFDebugInfoEntry::GetMangledName
// Get value the name for a DIE as it should appear for a
// .debug_pubnames or .debug_pubtypes section.
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetPubname
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu
-) const
-{
- const char* name = nullptr;
- if (!dwarf2Data)
- return name;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true);
- if (name)
- return name;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, true);
- if (name)
- return name;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const {
+ const char *name = nullptr;
+ if (!dwarf2Data)
return name;
-}
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
+ nullptr, true);
+ if (name)
+ return name;
+
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
+ true);
+ if (name)
+ return name;
+
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ return name;
+}
//----------------------------------------------------------------------
// GetName
@@ -1372,41 +1198,30 @@ DWARFDebugInfoEntry::GetPubname
// into the stream, and if no DW_AT_name attribute exists for the DIE
// then nothing is printed.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::GetName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- Stream &s
-)
-{
- if (dwarf2Data == NULL)
- {
- s.PutCString("NULL");
- return false;
- }
-
- DWARFDebugInfoEntry die;
- lldb::offset_t offset = die_offset;
- if (die.Extract(dwarf2Data, cu, &offset))
- {
- if (die.IsNULL())
- {
- s.PutCString("NULL");
- return true;
- }
- else
- {
- const char* name = die.GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
- if (name)
- {
- s.PutCString(name);
- return true;
- }
- }
- }
+bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset, Stream &s) {
+ if (dwarf2Data == NULL) {
+ s.PutCString("NULL");
return false;
+ }
+
+ DWARFDebugInfoEntry die;
+ lldb::offset_t offset = die_offset;
+ if (die.Extract(dwarf2Data, cu, &offset)) {
+ if (die.IsNULL()) {
+ s.PutCString("NULL");
+ return true;
+ } else {
+ const char *name = die.GetAttributeValueAsString(
+ dwarf2Data, cu, DW_AT_name, nullptr, true);
+ if (name) {
+ s.PutCString(name);
+ return true;
+ }
+ }
+ }
+ return false;
}
//----------------------------------------------------------------------
@@ -1417,144 +1232,168 @@ DWARFDebugInfoEntry::GetName
// the supplied stream. This is used to show the name of types given
// a type identifier.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::AppendTypeName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- Stream &s
-)
-{
- if (dwarf2Data == NULL)
- {
- s.PutCString("NULL");
- return false;
- }
-
- DWARFDebugInfoEntry die;
- lldb::offset_t offset = die_offset;
- if (die.Extract(dwarf2Data, cu, &offset))
- {
- if (die.IsNULL())
- {
- s.PutCString("NULL");
- return true;
+bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset,
+ Stream &s) {
+ if (dwarf2Data == NULL) {
+ s.PutCString("NULL");
+ return false;
+ }
+
+ DWARFDebugInfoEntry die;
+ lldb::offset_t offset = die_offset;
+ if (die.Extract(dwarf2Data, cu, &offset)) {
+ if (die.IsNULL()) {
+ s.PutCString("NULL");
+ return true;
+ } else {
+ const char *name = die.GetPubname(dwarf2Data, cu);
+ if (name)
+ s.PutCString(name);
+ else {
+ bool result = true;
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+
+ if (abbrevDecl == NULL)
+ return false;
+
+ switch (abbrevDecl->Tag()) {
+ case DW_TAG_array_type:
+ break; // print out a "[]" after printing the full type of the element
+ // below
+ case DW_TAG_base_type:
+ s.PutCString("base ");
+ break;
+ case DW_TAG_class_type:
+ s.PutCString("class ");
+ break;
+ case DW_TAG_const_type:
+ s.PutCString("const ");
+ break;
+ case DW_TAG_enumeration_type:
+ s.PutCString("enum ");
+ break;
+ case DW_TAG_file_type:
+ s.PutCString("file ");
+ break;
+ case DW_TAG_interface_type:
+ s.PutCString("interface ");
+ break;
+ case DW_TAG_packed_type:
+ s.PutCString("packed ");
+ break;
+ case DW_TAG_pointer_type:
+ break; // print out a '*' after printing the full type below
+ case DW_TAG_ptr_to_member_type:
+ break; // print out a '*' after printing the full type below
+ case DW_TAG_reference_type:
+ break; // print out a '&' after printing the full type below
+ case DW_TAG_restrict_type:
+ s.PutCString("restrict ");
+ break;
+ case DW_TAG_set_type:
+ s.PutCString("set ");
+ break;
+ case DW_TAG_shared_type:
+ s.PutCString("shared ");
+ break;
+ case DW_TAG_string_type:
+ s.PutCString("string ");
+ break;
+ case DW_TAG_structure_type:
+ s.PutCString("struct ");
+ break;
+ case DW_TAG_subrange_type:
+ s.PutCString("subrange ");
+ break;
+ case DW_TAG_subroutine_type:
+ s.PutCString("function ");
+ break;
+ case DW_TAG_thrown_type:
+ s.PutCString("thrown ");
+ break;
+ case DW_TAG_union_type:
+ s.PutCString("union ");
+ break;
+ case DW_TAG_unspecified_type:
+ s.PutCString("unspecified ");
+ break;
+ case DW_TAG_volatile_type:
+ s.PutCString("volatile ");
+ break;
+ default:
+ return false;
}
- else
- {
- const char* name = die.GetPubname(dwarf2Data, cu);
- if (name)
- s.PutCString(name);
- else
- {
- bool result = true;
- const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- if (abbrevDecl == NULL)
- return false;
-
- switch (abbrevDecl->Tag())
- {
- case DW_TAG_array_type: break; // print out a "[]" after printing the full type of the element below
- case DW_TAG_base_type: s.PutCString("base "); break;
- case DW_TAG_class_type: s.PutCString("class "); break;
- case DW_TAG_const_type: s.PutCString("const "); break;
- case DW_TAG_enumeration_type: s.PutCString("enum "); break;
- case DW_TAG_file_type: s.PutCString("file "); break;
- case DW_TAG_interface_type: s.PutCString("interface "); break;
- case DW_TAG_packed_type: s.PutCString("packed "); break;
- case DW_TAG_pointer_type: break; // print out a '*' after printing the full type below
- case DW_TAG_ptr_to_member_type: break; // print out a '*' after printing the full type below
- case DW_TAG_reference_type: break; // print out a '&' after printing the full type below
- case DW_TAG_restrict_type: s.PutCString("restrict "); break;
- case DW_TAG_set_type: s.PutCString("set "); break;
- case DW_TAG_shared_type: s.PutCString("shared "); break;
- case DW_TAG_string_type: s.PutCString("string "); break;
- case DW_TAG_structure_type: s.PutCString("struct "); break;
- case DW_TAG_subrange_type: s.PutCString("subrange "); break;
- case DW_TAG_subroutine_type: s.PutCString("function "); break;
- case DW_TAG_thrown_type: s.PutCString("thrown "); break;
- case DW_TAG_union_type: s.PutCString("union "); break;
- case DW_TAG_unspecified_type: s.PutCString("unspecified "); break;
- case DW_TAG_volatile_type: s.PutCString("volatile "); break;
- default:
- return false;
- }
- // Follow the DW_AT_type if possible
- DWARFFormValue form_value;
- if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value))
- {
- uint64_t next_die_offset = form_value.Reference();
- result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
- }
+ // Follow the DW_AT_type if possible
+ DWARFFormValue form_value;
+ if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
+ uint64_t next_die_offset = form_value.Reference();
+ result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
+ }
- switch (abbrevDecl->Tag())
- {
- case DW_TAG_array_type: s.PutCString("[]"); break;
- case DW_TAG_pointer_type: s.PutChar('*'); break;
- case DW_TAG_ptr_to_member_type: s.PutChar('*'); break;
- case DW_TAG_reference_type: s.PutChar('&'); break;
- default:
- break;
- }
- return result;
- }
+ switch (abbrevDecl->Tag()) {
+ case DW_TAG_array_type:
+ s.PutCString("[]");
+ break;
+ case DW_TAG_pointer_type:
+ s.PutChar('*');
+ break;
+ case DW_TAG_ptr_to_member_type:
+ s.PutChar('*');
+ break;
+ case DW_TAG_reference_type:
+ s.PutChar('&');
+ break;
+ default:
+ break;
}
+ return result;
+ }
}
- return false;
+ }
+ return false;
}
-bool
-DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const
-{
- if (die)
- {
- const dw_offset_t die_offset = die->GetOffset();
- if (die_offset > GetOffset())
- {
- const DWARFDebugInfoEntry *sibling = GetSibling();
- assert (sibling); // TODO: take this out
- if (sibling)
- return die_offset < sibling->GetOffset();
- }
+bool DWARFDebugInfoEntry::Contains(const DWARFDebugInfoEntry *die) const {
+ if (die) {
+ const dw_offset_t die_offset = die->GetOffset();
+ if (die_offset > GetOffset()) {
+ const DWARFDebugInfoEntry *sibling = GetSibling();
+ assert(sibling); // TODO: take this out
+ if (sibling)
+ return die_offset < sibling->GetOffset();
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// BuildAddressRangeTable
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::BuildAddressRangeTable
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges
-) const
-{
- if (m_tag)
- {
- if (m_tag == DW_TAG_subprogram)
- {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
- {
- /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
- debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
- }
- }
-
+void DWARFDebugInfoEntry::BuildAddressRangeTable(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const {
+ if (m_tag) {
+ if (m_tag == DW_TAG_subprogram) {
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
+ LLDB_INVALID_ADDRESS)) {
+ /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
+ /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
+ debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
+ }
+ }
- const DWARFDebugInfoEntry* child = GetFirstChild();
- while (child)
- {
- child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
- child = child->GetSibling();
- }
+ const DWARFDebugInfoEntry *child = GetFirstChild();
+ while (child) {
+ child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
+ child = child->GetSibling();
}
+ }
}
//----------------------------------------------------------------------
@@ -1565,477 +1404,478 @@ DWARFDebugInfoEntry::BuildAddressRangeTable
// table instead of the compile unit offset (which is the way the
// standard .debug_aranges section does it).
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges
-) const
-{
- if (m_tag)
- {
- if (m_tag == DW_TAG_subprogram)
- {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
- {
- // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
- debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
- }
- }
+void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const {
+ if (m_tag) {
+ if (m_tag == DW_TAG_subprogram) {
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
+ LLDB_INVALID_ADDRESS)) {
+ // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
+ // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
+ debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
+ }
+ }
- const DWARFDebugInfoEntry* child = GetFirstChild();
- while (child)
- {
- child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
- child = child->GetSibling();
- }
+ const DWARFDebugInfoEntry *child = GetFirstChild();
+ while (child) {
+ child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
+ child = child->GetSibling();
}
+ }
}
-void
-DWARFDebugInfoEntry::GetDeclContextDIEs (DWARFCompileUnit* cu,
- DWARFDIECollection &decl_context_dies) const
-{
+void DWARFDebugInfoEntry::GetDeclContextDIEs(
+ DWARFCompileUnit *cu, DWARFDIECollection &decl_context_dies) const {
- DWARFDIE die (cu, const_cast<DWARFDebugInfoEntry *>(this));
- die.GetDeclContextDIEs(decl_context_dies);
+ DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
+ die.GetDeclContextDIEs(decl_context_dies);
}
-void
-DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- DWARFDeclContext &dwarf_decl_ctx) const
-{
- const dw_tag_t tag = Tag();
- if (tag != DW_TAG_compile_unit)
- {
- dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
- DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
- if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this)
- {
- if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit)
- parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext (parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(), dwarf_decl_ctx);
- }
+void DWARFDebugInfoEntry::GetDWARFDeclContext(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ DWARFDeclContext &dwarf_decl_ctx) const {
+ const dw_tag_t tag = Tag();
+ if (tag != DW_TAG_compile_unit) {
+ dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
+ DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
+ if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
+ if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit)
+ parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
+ parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(),
+ dwarf_decl_ctx);
}
+ }
}
+bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ const DWARFDeclContext &dwarf_decl_ctx) const {
-bool
-DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFDeclContext &dwarf_decl_ctx) const
-{
-
- DWARFDeclContext this_dwarf_decl_ctx;
- GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx);
- return this_dwarf_decl_ctx == dwarf_decl_ctx;
+ DWARFDeclContext this_dwarf_decl_ctx;
+ GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx);
+ return this_dwarf_decl_ctx == dwarf_decl_ctx;
}
DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu) const
-{
- DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
- return GetParentDeclContextDIE (dwarf2Data, cu, attributes);
+DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu) const {
+ DWARFAttributes attributes;
+ GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+ return GetParentDeclContextDIE(dwarf2Data, cu, attributes);
}
DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes) const
-{
- DWARFDIE die (cu, const_cast<DWARFDebugInfoEntry *>(this));
-
- while (die)
- {
- // If this is the original DIE that we are searching for a declaration
- // for, then don't look in the cache as we don't want our own decl
- // context to be our decl context...
- if (die.GetDIE() != this)
- {
- switch (die.Tag())
- {
- case DW_TAG_compile_unit:
- case DW_TAG_namespace:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- return die;
-
- default:
- break;
- }
- }
-
- dw_offset_t die_offset;
-
- die_offset = attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- {
- DWARFDIE spec_die = cu->GetDIE (die_offset);
- if (spec_die)
- {
- DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
- }
-
- die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- {
- DWARFDIE abs_die = cu->GetDIE (die_offset);
- if (abs_die)
- {
- DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
- }
-
- die = die.GetParent();
- }
- return DWARFDIE();
-}
+DWARFDebugInfoEntry::GetParentDeclContextDIE(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes) const {
+ DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
+
+ while (die) {
+ // If this is the original DIE that we are searching for a declaration
+ // for, then don't look in the cache as we don't want our own decl
+ // context to be our decl context...
+ if (die.GetDIE() != this) {
+ switch (die.Tag()) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_namespace:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ return die;
+
+ default:
+ break;
+ }
+ }
+
+ dw_offset_t die_offset;
+
+ die_offset =
+ attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
+ if (die_offset != DW_INVALID_OFFSET) {
+ DWARFDIE spec_die = cu->GetDIE(die_offset);
+ if (spec_die) {
+ DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+ }
+ die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin,
+ DW_INVALID_OFFSET);
+ if (die_offset != DW_INVALID_OFFSET) {
+ DWARFDIE abs_die = cu->GetDIE(die_offset);
+ if (abs_die) {
+ DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+ }
-const char *
-DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- std::string &storage) const
-{
- DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
- return GetQualifiedName (dwarf2Data, cu, attributes, storage);
+ die = die.GetParent();
+ }
+ return DWARFDIE();
}
-const char*
-DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes,
- std::string &storage) const
-{
-
- const char *name = GetName (dwarf2Data, cu);
-
- if (name)
- {
- DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
- storage.clear();
- // TODO: change this to get the correct decl context parent....
- while (parent_decl_ctx_die)
- {
- const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
- switch (parent_tag)
- {
- case DW_TAG_namespace:
- {
- const char *namespace_name = parent_decl_ctx_die.GetName ();
- if (namespace_name)
- {
- storage.insert (0, "::");
- storage.insert (0, namespace_name);
- }
- else
- {
- storage.insert (0, "(anonymous namespace)::");
- }
- parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
- }
- break;
-
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- {
- const char *class_union_struct_name = parent_decl_ctx_die.GetName ();
-
- if (class_union_struct_name)
- {
- storage.insert (0, "::");
- storage.insert (0, class_union_struct_name);
- }
- parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
- }
- break;
-
- default:
- parent_decl_ctx_die.Clear();
- break;
- }
- }
-
- if (storage.empty())
- storage.append ("::");
-
- storage.append (name);
- }
- if (storage.empty())
- return NULL;
- return storage.c_str();
+const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ std::string &storage) const {
+ DWARFAttributes attributes;
+ GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+ return GetQualifiedName(dwarf2Data, cu, attributes, storage);
}
+const char *DWARFDebugInfoEntry::GetQualifiedName(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes, std::string &storage) const {
+
+ const char *name = GetName(dwarf2Data, cu);
+
+ if (name) {
+ DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
+ storage.clear();
+ // TODO: change this to get the correct decl context parent....
+ while (parent_decl_ctx_die) {
+ const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
+ switch (parent_tag) {
+ case DW_TAG_namespace: {
+ const char *namespace_name = parent_decl_ctx_die.GetName();
+ if (namespace_name) {
+ storage.insert(0, "::");
+ storage.insert(0, namespace_name);
+ } else {
+ storage.insert(0, "(anonymous namespace)::");
+ }
+ parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
+ } break;
+
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type: {
+ const char *class_union_struct_name = parent_decl_ctx_die.GetName();
+
+ if (class_union_struct_name) {
+ storage.insert(0, "::");
+ storage.insert(0, class_union_struct_name);
+ }
+ parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
+ } break;
+
+ default:
+ parent_decl_ctx_die.Clear();
+ break;
+ }
+ }
+
+ if (storage.empty())
+ storage.append("::");
+
+ storage.append(name);
+ }
+ if (storage.empty())
+ return NULL;
+ return storage.c_str();
+}
//----------------------------------------------------------------------
// LookupAddress
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::LookupAddress
-(
- const dw_addr_t address,
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugInfoEntry** function_die,
- DWARFDebugInfoEntry** block_die
-)
-{
- bool found_address = false;
- if (m_tag)
- {
- bool check_children = false;
- bool match_addr_range = false;
- // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address);
- switch (m_tag)
- {
- case DW_TAG_array_type : break;
- case DW_TAG_class_type : check_children = true; break;
- case DW_TAG_entry_point : break;
- case DW_TAG_enumeration_type : break;
- case DW_TAG_formal_parameter : break;
- case DW_TAG_imported_declaration : break;
- case DW_TAG_label : break;
- case DW_TAG_lexical_block : check_children = true; match_addr_range = true; break;
- case DW_TAG_member : break;
- case DW_TAG_pointer_type : break;
- case DW_TAG_reference_type : break;
- case DW_TAG_compile_unit : match_addr_range = true; break;
- case DW_TAG_string_type : break;
- case DW_TAG_structure_type : check_children = true; break;
- case DW_TAG_subroutine_type : break;
- case DW_TAG_typedef : break;
- case DW_TAG_union_type : break;
- case DW_TAG_unspecified_parameters : break;
- case DW_TAG_variant : break;
- case DW_TAG_common_block : check_children = true; break;
- case DW_TAG_common_inclusion : break;
- case DW_TAG_inheritance : break;
- case DW_TAG_inlined_subroutine : check_children = true; match_addr_range = true; break;
- case DW_TAG_module : match_addr_range = true; break;
- case DW_TAG_ptr_to_member_type : break;
- case DW_TAG_set_type : break;
- case DW_TAG_subrange_type : break;
- case DW_TAG_with_stmt : break;
- case DW_TAG_access_declaration : break;
- case DW_TAG_base_type : break;
- case DW_TAG_catch_block : match_addr_range = true; break;
- case DW_TAG_const_type : break;
- case DW_TAG_constant : break;
- case DW_TAG_enumerator : break;
- case DW_TAG_file_type : break;
- case DW_TAG_friend : break;
- case DW_TAG_namelist : break;
- case DW_TAG_namelist_item : break;
- case DW_TAG_packed_type : break;
- case DW_TAG_subprogram : match_addr_range = true; break;
- case DW_TAG_template_type_parameter : break;
- case DW_TAG_template_value_parameter : break;
- case DW_TAG_thrown_type : break;
- case DW_TAG_try_block : match_addr_range = true; break;
- case DW_TAG_variant_part : break;
- case DW_TAG_variable : break;
- case DW_TAG_volatile_type : break;
- case DW_TAG_dwarf_procedure : break;
- case DW_TAG_restrict_type : break;
- case DW_TAG_interface_type : break;
- case DW_TAG_namespace : check_children = true; break;
- case DW_TAG_imported_module : break;
- case DW_TAG_unspecified_type : break;
- case DW_TAG_partial_unit : break;
- case DW_TAG_imported_unit : break;
- case DW_TAG_shared_type : break;
- default: break;
- }
-
- if (match_addr_range)
- {
- dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (lo_pc != LLDB_INVALID_ADDRESS)
- {
- dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
- if (hi_pc != LLDB_INVALID_ADDRESS)
- {
- // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
- if ((lo_pc <= address) && (address < hi_pc))
- {
- found_address = true;
- // puts("***MATCH***");
- switch (m_tag)
- {
- case DW_TAG_compile_unit: // File
- check_children = ((function_die != NULL) || (block_die != NULL));
- break;
-
- case DW_TAG_subprogram: // Function
- if (function_die)
- *function_die = this;
- check_children = (block_die != NULL);
- break;
-
- case DW_TAG_inlined_subroutine: // Inlined Function
- case DW_TAG_lexical_block: // Block { } in code
- if (block_die)
- {
- *block_die = this;
- check_children = true;
- }
- break;
-
- default:
- check_children = true;
- break;
- }
- }
- }
- else
- { // compile units may not have a valid high/low pc when there
- // are address gaps in subroutines so we must always search
- // if there is no valid high and low PC
- check_children = (m_tag == DW_TAG_compile_unit) && ((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)
- {
- DWARFRangeList ranges;
- DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
- debug_ranges->FindRanges(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());
- if (ranges.FindEntryThatContains(address))
- {
- found_address = true;
- // puts("***MATCH***");
- switch (m_tag)
- {
- case DW_TAG_compile_unit: // File
- check_children = ((function_die != NULL) || (block_die != NULL));
- break;
-
- case DW_TAG_subprogram: // Function
- if (function_die)
- *function_die = this;
- check_children = (block_die != NULL);
- break;
-
- case DW_TAG_inlined_subroutine: // Inlined Function
- case DW_TAG_lexical_block: // Block { } in code
- if (block_die)
- {
- *block_die = this;
- check_children = true;
- }
- break;
-
- default:
- check_children = true;
- break;
- }
- }
- else
- {
- check_children = false;
- }
- }
- }
- }
+bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
+ SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugInfoEntry **function_die,
+ DWARFDebugInfoEntry **block_die) {
+ bool found_address = false;
+ if (m_tag) {
+ bool check_children = false;
+ bool match_addr_range = false;
+ // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
+ // DW_TAG_value_to_name(tag), address);
+ switch (m_tag) {
+ case DW_TAG_array_type:
+ break;
+ case DW_TAG_class_type:
+ check_children = true;
+ break;
+ case DW_TAG_entry_point:
+ break;
+ case DW_TAG_enumeration_type:
+ break;
+ case DW_TAG_formal_parameter:
+ break;
+ case DW_TAG_imported_declaration:
+ break;
+ case DW_TAG_label:
+ break;
+ case DW_TAG_lexical_block:
+ check_children = true;
+ match_addr_range = true;
+ break;
+ case DW_TAG_member:
+ break;
+ case DW_TAG_pointer_type:
+ break;
+ case DW_TAG_reference_type:
+ break;
+ case DW_TAG_compile_unit:
+ match_addr_range = true;
+ break;
+ case DW_TAG_string_type:
+ break;
+ case DW_TAG_structure_type:
+ check_children = true;
+ break;
+ case DW_TAG_subroutine_type:
+ break;
+ case DW_TAG_typedef:
+ break;
+ case DW_TAG_union_type:
+ break;
+ case DW_TAG_unspecified_parameters:
+ break;
+ case DW_TAG_variant:
+ break;
+ case DW_TAG_common_block:
+ check_children = true;
+ break;
+ case DW_TAG_common_inclusion:
+ break;
+ case DW_TAG_inheritance:
+ break;
+ case DW_TAG_inlined_subroutine:
+ check_children = true;
+ match_addr_range = true;
+ break;
+ case DW_TAG_module:
+ match_addr_range = true;
+ break;
+ case DW_TAG_ptr_to_member_type:
+ break;
+ case DW_TAG_set_type:
+ break;
+ case DW_TAG_subrange_type:
+ break;
+ case DW_TAG_with_stmt:
+ break;
+ case DW_TAG_access_declaration:
+ break;
+ case DW_TAG_base_type:
+ break;
+ case DW_TAG_catch_block:
+ match_addr_range = true;
+ break;
+ case DW_TAG_const_type:
+ break;
+ case DW_TAG_constant:
+ break;
+ case DW_TAG_enumerator:
+ break;
+ case DW_TAG_file_type:
+ break;
+ case DW_TAG_friend:
+ break;
+ case DW_TAG_namelist:
+ break;
+ case DW_TAG_namelist_item:
+ break;
+ case DW_TAG_packed_type:
+ break;
+ case DW_TAG_subprogram:
+ match_addr_range = true;
+ break;
+ case DW_TAG_template_type_parameter:
+ break;
+ case DW_TAG_template_value_parameter:
+ break;
+ case DW_TAG_thrown_type:
+ break;
+ case DW_TAG_try_block:
+ match_addr_range = true;
+ break;
+ case DW_TAG_variant_part:
+ break;
+ case DW_TAG_variable:
+ break;
+ case DW_TAG_volatile_type:
+ break;
+ case DW_TAG_dwarf_procedure:
+ break;
+ case DW_TAG_restrict_type:
+ break;
+ case DW_TAG_interface_type:
+ break;
+ case DW_TAG_namespace:
+ check_children = true;
+ break;
+ case DW_TAG_imported_module:
+ break;
+ case DW_TAG_unspecified_type:
+ break;
+ case DW_TAG_partial_unit:
+ break;
+ case DW_TAG_imported_unit:
+ break;
+ case DW_TAG_shared_type:
+ break;
+ default:
+ break;
+ }
+ if (match_addr_range) {
+ dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc,
+ LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS) {
+ dw_addr_t hi_pc =
+ GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS) {
+ // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ",
+ // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
+ if ((lo_pc <= address) && (address < hi_pc)) {
+ found_address = true;
+ // puts("***MATCH***");
+ switch (m_tag) {
+ case DW_TAG_compile_unit: // File
+ check_children = ((function_die != NULL) || (block_die != NULL));
+ break;
+
+ case DW_TAG_subprogram: // Function
+ if (function_die)
+ *function_die = this;
+ check_children = (block_die != NULL);
+ break;
+
+ case DW_TAG_inlined_subroutine: // Inlined Function
+ case DW_TAG_lexical_block: // Block { } in code
+ if (block_die) {
+ *block_die = this;
+ check_children = true;
+ }
+ break;
- if (check_children)
- {
- // printf("checking children\n");
- DWARFDebugInfoEntry* child = GetFirstChild();
- while (child)
- {
- if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die))
- return true;
- child = child->GetSibling();
+ default:
+ check_children = true;
+ break;
}
+ }
+ } else { // compile units may not have a valid high/low pc when there
+ // are address gaps in subroutines so we must always search
+ // if there is no valid high and low PC
+ check_children = (m_tag == DW_TAG_compile_unit) &&
+ ((function_die != NULL) || (block_die != NULL));
}
- }
- return found_address;
-}
+ } else {
+ dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
+ dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
+ if (debug_ranges_offset != DW_INVALID_OFFSET) {
+ 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());
+ if (ranges.FindEntryThatContains(address)) {
+ found_address = true;
+ // puts("***MATCH***");
+ switch (m_tag) {
+ case DW_TAG_compile_unit: // File
+ check_children = ((function_die != NULL) || (block_die != NULL));
+ break;
+
+ case DW_TAG_subprogram: // Function
+ if (function_die)
+ *function_die = this;
+ check_children = (block_die != NULL);
+ break;
+
+ case DW_TAG_inlined_subroutine: // Inlined Function
+ case DW_TAG_lexical_block: // Block { } in code
+ if (block_die) {
+ *block_die = this;
+ check_children = true;
+ }
+ break;
-const DWARFAbbreviationDeclaration*
-DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit *cu,
- lldb::offset_t &offset) const
-{
- if (dwarf2Data)
- {
- offset = GetOffset();
-
- const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
- if (abbrev_set)
- {
- const DWARFAbbreviationDeclaration* abbrev_decl = abbrev_set->GetAbbreviationDeclaration (m_abbr_idx);
- if (abbrev_decl)
- {
- // Make sure the abbreviation code still matches. If it doesn't and
- // the DWARF data was mmap'ed, the backing file might have been modified
- // which is bad news.
- const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
-
- if (abbrev_decl->Code() == abbrev_code)
- return abbrev_decl;
-
- dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
- GetOffset(),
- (uint32_t)abbrev_decl->Code(),
- (uint32_t)abbrev_code);
+ default:
+ check_children = true;
+ break;
}
+ } else {
+ check_children = false;
+ }
}
+ }
}
- offset = DW_INVALID_OFFSET;
- return NULL;
-}
-
-bool
-DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b)
-{
- return a.GetOffset() < b.GetOffset();
+ if (check_children) {
+ // printf("checking children\n");
+ DWARFDebugInfoEntry *child = GetFirstChild();
+ while (child) {
+ if (child->LookupAddress(address, dwarf2Data, cu, function_die,
+ block_die))
+ return true;
+ child = child->GetSibling();
+ }
+ }
+ }
+ return found_address;
}
-void
-DWARFDebugInfoEntry::DumpDIECollection (Stream &strm, DWARFDebugInfoEntry::collection &die_collection)
-{
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator end = die_collection.end();
- strm.PutCString("\noffset parent sibling child\n");
- strm.PutCString("-------- -------- -------- --------\n");
- for (pos = die_collection.begin(); pos != end; ++pos)
- {
- const DWARFDebugInfoEntry& die_ref = *pos;
- const DWARFDebugInfoEntry* p = die_ref.GetParent();
- const DWARFDebugInfoEntry* s = die_ref.GetSibling();
- const DWARFDebugInfoEntry* c = die_ref.GetFirstChild();
- strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n",
- die_ref.GetOffset(),
- p ? p->GetOffset() : 0,
- s ? s->GetOffset() : 0,
- c ? c->GetOffset() : 0,
- die_ref.Tag(),
- DW_TAG_value_to_name(die_ref.Tag()),
- die_ref.HasChildren() ? " *" : "");
+const DWARFAbbreviationDeclaration *
+DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ lldb::offset_t &offset) const {
+ if (dwarf2Data) {
+ offset = GetOffset();
+
+ const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
+ if (abbrev_set) {
+ const DWARFAbbreviationDeclaration *abbrev_decl =
+ abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
+ if (abbrev_decl) {
+ // Make sure the abbreviation code still matches. If it doesn't and
+ // the DWARF data was mmap'ed, the backing file might have been modified
+ // which is bad news.
+ const uint64_t abbrev_code =
+ dwarf2Data->get_debug_info_data().GetULEB128(&offset);
+
+ if (abbrev_decl->Code() == abbrev_code)
+ return abbrev_decl;
+
+ dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "0x%8.8x: the DWARF debug information has been modified (abbrev "
+ "code was %u, and is now %u)",
+ GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code);
+ }
}
+ }
+ offset = DW_INVALID_OFFSET;
+ return NULL;
}
+bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a,
+ const DWARFDebugInfoEntry &b) {
+ return a.GetOffset() < b.GetOffset();
+}
+void DWARFDebugInfoEntry::DumpDIECollection(
+ Stream &strm, DWARFDebugInfoEntry::collection &die_collection) {
+ DWARFDebugInfoEntry::const_iterator pos;
+ DWARFDebugInfoEntry::const_iterator end = die_collection.end();
+ strm.PutCString("\noffset parent sibling child\n");
+ strm.PutCString("-------- -------- -------- --------\n");
+ for (pos = die_collection.begin(); pos != end; ++pos) {
+ const DWARFDebugInfoEntry &die_ref = *pos;
+ const DWARFDebugInfoEntry *p = die_ref.GetParent();
+ const DWARFDebugInfoEntry *s = die_ref.GetSibling();
+ const DWARFDebugInfoEntry *c = die_ref.GetFirstChild();
+ strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", die_ref.GetOffset(),
+ p ? p->GetOffset() : 0, s ? s->GetOffset() : 0,
+ c ? c->GetOffset() : 0, die_ref.Tag(),
+ DW_TAG_value_to_name(die_ref.Tag()),
+ die_ref.HasChildren() ? " *" : "");
+ }
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 27b4fe93bc33..15abac77a475 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -13,390 +13,295 @@
#include "SymbolFileDWARF.h"
#include "llvm/ADT/SmallVector.h"
-#include "DWARFDebugAbbrev.h"
#include "DWARFAbbreviationDeclaration.h"
+#include "DWARFDebugAbbrev.h"
#include "DWARFDebugRanges.h"
-#include <vector>
#include <map>
#include <set>
+#include <vector>
-typedef std::map<const DWARFDebugInfoEntry*, dw_addr_t> DIEToAddressMap;
-typedef DIEToAddressMap::iterator DIEToAddressMapIter;
-typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter;
-
-typedef std::map<dw_addr_t, const DWARFDebugInfoEntry*> AddressToDIEMap;
-typedef AddressToDIEMap::iterator AddressToDIEMapIter;
-typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter;
+typedef std::map<const DWARFDebugInfoEntry *, dw_addr_t> DIEToAddressMap;
+typedef DIEToAddressMap::iterator DIEToAddressMapIter;
+typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter;
+typedef std::map<dw_addr_t, const DWARFDebugInfoEntry *> AddressToDIEMap;
+typedef AddressToDIEMap::iterator AddressToDIEMapIter;
+typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter;
-typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap;
-typedef DIEToDIEMap::iterator DIEToDIEMapIter;
-typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter;
+typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap;
+typedef DIEToDIEMap::iterator DIEToDIEMapIter;
+typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter;
-typedef std::map<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMap;
-typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter;
-typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter;
+typedef std::map<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMap;
+typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter;
+typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter;
-typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap;
-typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter;
-typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter;
+typedef std::multimap<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMMap;
+typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter;
+typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter;
class DWARFDeclContext;
#define DIE_SIBLING_IDX_BITSIZE 31
#define DIE_ABBR_IDX_BITSIZE 15
-class DWARFDebugInfoEntry
-{
+class DWARFDebugInfoEntry {
public:
- typedef std::vector<DWARFDebugInfoEntry> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- typedef std::vector<dw_offset_t> offset_collection;
- typedef offset_collection::iterator offset_collection_iterator;
- typedef offset_collection::const_iterator offset_collection_const_iterator;
-
- 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)
- {
- }
-
- void Clear ()
- {
- m_offset = DW_INVALID_OFFSET;
- m_parent_idx = 0;
- m_sibling_idx = 0;
- m_empty_children = false;
- m_abbr_idx = 0;
- m_has_children = false;
- m_tag = 0;
- }
-
- bool Contains (const DWARFDebugInfoEntry *die) const;
-
- void BuildAddressRangeTable(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges) const;
-
- void BuildFunctionAddressRangeTable(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges) const;
-
- bool FastExtract(
- const lldb_private::DWARFDataExtractor& debug_info_data,
- const DWARFCompileUnit* cu,
- const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
- lldb::offset_t* offset_ptr);
-
- bool Extract(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- lldb::offset_t* offset_ptr);
-
- bool LookupAddress(
- const dw_addr_t address,
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugInfoEntry** function_die,
- DWARFDebugInfoEntry** block_die);
-
- size_t GetAttributes(
- const DWARFCompileUnit* cu,
- DWARFFormValue::FixedFormSizes fixed_form_sizes,
- DWARFAttributes& attrs,
- uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!!
-
- dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- DWARFFormValue& formValue,
- dw_offset_t* end_attr_offset_ptr = nullptr,
- bool check_specification_or_abstract_origin = false) const;
-
- const char* GetAttributeValueAsString(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- const char* fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- uint64_t GetAttributeValueAsUnsigned(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- uint64_t GetAttributeValueAsReference(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- int64_t GetAttributeValueAsSigned(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- int64_t fail_value,
+ typedef std::vector<DWARFDebugInfoEntry> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ typedef std::vector<dw_offset_t> offset_collection;
+ typedef offset_collection::iterator offset_collection_iterator;
+ typedef offset_collection::const_iterator offset_collection_const_iterator;
+
+ 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) {}
+
+ void Clear() {
+ m_offset = DW_INVALID_OFFSET;
+ m_parent_idx = 0;
+ m_sibling_idx = 0;
+ m_empty_children = false;
+ m_abbr_idx = 0;
+ m_has_children = false;
+ m_tag = 0;
+ }
+
+ bool Contains(const DWARFDebugInfoEntry *die) const;
+
+ void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const;
+
+ void BuildFunctionAddressRangeTable(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const;
+
+ bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data,
+ const DWARFCompileUnit *cu,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ lldb::offset_t *offset_ptr);
+
+ bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ lldb::offset_t *offset_ptr);
+
+ bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugInfoEntry **function_die,
+ DWARFDebugInfoEntry **block_die);
+
+ size_t GetAttributes(const DWARFCompileUnit *cu,
+ DWARFFormValue::FixedFormSizes fixed_form_sizes,
+ DWARFAttributes &attrs,
+ uint32_t curr_depth = 0)
+ const; // "curr_depth" for internal use only, don't set this yourself!!!
+
+ dw_offset_t
+ GetAttributeValue(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, DWARFFormValue &formValue,
+ dw_offset_t *end_attr_offset_ptr = nullptr,
bool check_specification_or_abstract_origin = false) const;
- uint64_t GetAttributeValueAsAddress(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- dw_addr_t GetAttributeHighPC(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t lo_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- bool GetAttributeAddressRange(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t& lo_pc,
- dw_addr_t& hi_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- size_t GetAttributeAddressRanges (
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFRangeList &ranges,
- bool check_hi_lo_pc,
- bool check_specification_or_abstract_origin = false) const;
-
- const char* GetName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu) const;
-
- const char* GetMangledName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- bool substitute_name_allowed = true) const;
-
- const char* GetPubname(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu) const;
-
- static bool GetName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- lldb_private::Stream &s);
-
- static bool AppendTypeName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- lldb_private::Stream &s);
-
- const char * GetQualifiedName (
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- std::string &storage) const;
-
- const char * GetQualifiedName (
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes,
- std::string &storage) const;
-
- static bool OffsetLessThan (
- const DWARFDebugInfoEntry& a,
- const DWARFDebugInfoEntry& b);
-
- void Dump(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- lldb_private::Stream &s,
- uint32_t recurse_depth) const;
-
- void DumpAncestry(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const DWARFDebugInfoEntry* oldest,
- lldb_private::Stream &s,
+ const char *GetAttributeValueAsString(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, const char *fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ uint64_t GetAttributeValueAsUnsigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ uint64_t GetAttributeValueAsReference(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ int64_t GetAttributeValueAsSigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, int64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ uint64_t GetAttributeValueAsAddress(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ dw_addr_t
+ GetAttributeHighPC(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ dw_addr_t lo_pc, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ bool GetAttributeAddressRange(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc,
+ dw_addr_t &hi_pc, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ size_t GetAttributeAddressRanges(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFRangeList &ranges, bool check_hi_lo_pc,
+ bool check_specification_or_abstract_origin = false) const;
+
+ const char *GetName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const;
+
+ const char *GetMangledName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ bool substitute_name_allowed = true) const;
+
+ const char *GetPubname(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const;
+
+ static bool GetName(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset, lldb_private::Stream &s);
+
+ static bool AppendTypeName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset,
+ lldb_private::Stream &s);
+
+ const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ std::string &storage) const;
+
+ const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes,
+ std::string &storage) const;
+
+ static bool OffsetLessThan(const DWARFDebugInfoEntry &a,
+ const DWARFDebugInfoEntry &b);
+
+ void Dump(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ lldb_private::Stream &s, uint32_t recurse_depth) const;
+
+ void DumpAncestry(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const DWARFDebugInfoEntry *oldest, lldb_private::Stream &s,
uint32_t recurse_depth) const;
- static void DumpAttribute(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const lldb_private::DWARFDataExtractor& debug_info_data,
- lldb::offset_t *offset_ptr,
- lldb_private::Stream &s,
- dw_attr_t attr,
- dw_form_t form);
- // This one dumps the comp unit name, objfile name and die offset for this die so the stream S.
- void DumpLocation(
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
+ static void
+ DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const lldb_private::DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr, lldb_private::Stream &s,
+ dw_attr_t attr, dw_form_t form);
+ // This one dumps the comp unit name, objfile name and die offset for this die
+ // so the stream S.
+ void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
lldb_private::Stream &s) const;
-
- bool GetDIENamesAndRanges(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const char * &name,
- const char * &mangled,
- DWARFRangeList& rangeList,
- int& decl_file,
- int& decl_line,
- int& decl_column,
- int& call_file,
- int& call_line,
- int& call_column,
- lldb_private::DWARFExpression *frame_base = NULL) const;
-
- const DWARFAbbreviationDeclaration*
- GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit *cu,
- lldb::offset_t &offset) const;
-
- dw_tag_t
- Tag () const
- {
- return m_tag;
- }
-
- bool
- IsNULL() const
- {
- return m_abbr_idx == 0;
- }
-
- dw_offset_t
- GetOffset () const
- {
- return m_offset;
- }
-
- void
- SetOffset (dw_offset_t offset)
- {
- m_offset = offset;
- }
-
- bool
- HasChildren () const
- {
- return m_has_children;
- }
-
- void
- SetHasChildren (bool b)
- {
- m_has_children = b;
- }
-
- // We know we are kept in a vector of contiguous entries, so we know
- // our parent will be some index behind "this".
- DWARFDebugInfoEntry* GetParent() { return m_parent_idx > 0 ? this - m_parent_idx : NULL; }
- const DWARFDebugInfoEntry* GetParent() const { return m_parent_idx > 0 ? this - m_parent_idx : NULL; }
- // We know we are kept in a vector of contiguous entries, so we know
- // our sibling will be some index after "this".
- DWARFDebugInfoEntry* GetSibling() { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; }
- const DWARFDebugInfoEntry* GetSibling() const { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; }
- // We know we are kept in a vector of contiguous entries, so we know
- // 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; }
- const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; }
-
-
- void GetDeclContextDIEs (DWARFCompileUnit* cu,
- DWARFDIECollection &decl_context_dies) const;
-
- void GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- DWARFDeclContext &dwarf_decl_ctx) const;
-
-
- bool MatchesDWARFDeclContext(SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFDeclContext &dwarf_decl_ctx) const;
-
- DWARFDIE GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu) const;
- DWARFDIE GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes) const;
-
- void
- SetParent (DWARFDebugInfoEntry* parent)
- {
- if (parent)
- {
- // We know we are kept in a vector of contiguous entries, so we know
- // our parent will be some index behind "this".
- m_parent_idx = this - parent;
- }
- else
- m_parent_idx = 0;
- }
- void
- SetSibling (DWARFDebugInfoEntry* sibling)
- {
- if (sibling)
- {
- // We know we are kept in a vector of contiguous entries, so we know
- // our sibling will be some index after "this".
- m_sibling_idx = sibling - this;
- sibling->SetParent(GetParent());
- }
- else
- m_sibling_idx = 0;
- }
-
- void
- SetSiblingIndex (uint32_t idx)
- {
- m_sibling_idx = idx;
- }
-
- 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);
-protected:
+ bool
+ GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const char *&name, const char *&mangled,
+ DWARFRangeList &rangeList, int &decl_file,
+ int &decl_line, int &decl_column, int &call_file,
+ int &call_line, int &call_column,
+ lldb_private::DWARFExpression *frame_base = NULL) const;
+
+ const DWARFAbbreviationDeclaration *
+ GetAbbreviationDeclarationPtr(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ lldb::offset_t &offset) const;
+
+ dw_tag_t Tag() const { return m_tag; }
+
+ bool IsNULL() const { return m_abbr_idx == 0; }
+
+ dw_offset_t GetOffset() const { return m_offset; }
+
+ void SetOffset(dw_offset_t offset) { m_offset = offset; }
+
+ bool HasChildren() const { return m_has_children; }
+
+ void SetHasChildren(bool b) { m_has_children = b; }
+
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our parent will be some index behind "this".
+ DWARFDebugInfoEntry *GetParent() {
+ return m_parent_idx > 0 ? this - m_parent_idx : NULL;
+ }
+ const DWARFDebugInfoEntry *GetParent() const {
+ return m_parent_idx > 0 ? this - m_parent_idx : NULL;
+ }
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our sibling will be some index after "this".
+ DWARFDebugInfoEntry *GetSibling() {
+ return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;
+ }
+ const DWARFDebugInfoEntry *GetSibling() const {
+ return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;
+ }
+ // We know we are kept in a vector of contiguous entries, so we know
+ // 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;
+ }
+ const DWARFDebugInfoEntry *GetFirstChild() const {
+ return (HasChildren() && !m_empty_children) ? this + 1 : NULL;
+ }
+
+ void GetDeclContextDIEs(DWARFCompileUnit *cu,
+ DWARFDIECollection &decl_context_dies) const;
+
+ void GetDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ DWARFDeclContext &dwarf_decl_ctx) const;
+
+ bool MatchesDWARFDeclContext(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ const DWARFDeclContext &dwarf_decl_ctx) const;
+
+ DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu) const;
+ DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes) const;
+
+ void SetParent(DWARFDebugInfoEntry *parent) {
+ if (parent) {
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our parent will be some index behind "this".
+ m_parent_idx = this - parent;
+ } else
+ m_parent_idx = 0;
+ }
+ void SetSibling(DWARFDebugInfoEntry *sibling) {
+ if (sibling) {
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our sibling will be some index after "this".
+ m_sibling_idx = sibling - this;
+ sibling->SetParent(GetParent());
+ } else
+ m_sibling_idx = 0;
+ }
+
+ void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
+
+ 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);
- dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry
- 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
+protected:
+ dw_offset_t
+ m_offset; // Offset within the .debug_info of the start of this entry
+ 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
};
-#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
+#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
index 84c2142e8419..bce21c44b73e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
@@ -18,8 +18,8 @@
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
-#include "SymbolFileDWARF.h"
#include "LogChannelDWARF.h"
+#include "SymbolFileDWARF.h"
using namespace lldb;
using namespace lldb_private;
@@ -31,359 +31,329 @@ using namespace std;
// Parse all information in the debug_line_data into an internal
// representation.
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Parse(const DWARFDataExtractor& debug_line_data)
-{
- m_lineTableMap.clear();
- lldb::offset_t offset = 0;
- LineTable::shared_ptr line_table_sp(new LineTable);
- while (debug_line_data.ValidOffset(offset))
- {
- const lldb::offset_t debug_line_offset = offset;
-
- if (line_table_sp.get() == NULL)
- break;
-
- if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get()))
- {
- // Make sure we don't don't loop infinitely
- if (offset <= debug_line_offset)
- break;
- //DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n", debug_line_offset);
- m_lineTableMap[debug_line_offset] = line_table_sp;
- line_table_sp.reset(new LineTable);
- }
- else
- ++offset; // Try next byte in line table
- }
+void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
+ m_lineTableMap.clear();
+ lldb::offset_t offset = 0;
+ LineTable::shared_ptr line_table_sp(new LineTable);
+ while (debug_line_data.ValidOffset(offset)) {
+ const lldb::offset_t debug_line_offset = offset;
+
+ if (line_table_sp.get() == NULL)
+ break;
+
+ if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) {
+ // Make sure we don't don't loop infinitely
+ if (offset <= debug_line_offset)
+ break;
+ // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n",
+ // debug_line_offset);
+ m_lineTableMap[debug_line_offset] = line_table_sp;
+ line_table_sp.reset(new LineTable);
+ } else
+ ++offset; // Try next byte in line table
+ }
}
-void
-DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor& debug_line_data)
-{
- if (m_lineTableMap.empty())
- Parse(debug_line_data);
+void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
+ if (m_lineTableMap.empty())
+ Parse(debug_line_data);
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::GetLineTable
//----------------------------------------------------------------------
DWARFDebugLine::LineTable::shared_ptr
-DWARFDebugLine::GetLineTable(const dw_offset_t offset) const
-{
- DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
- LineTableConstIter pos = m_lineTableMap.find(offset);
- if (pos != m_lineTableMap.end())
- line_table_shared_ptr = pos->second;
- return line_table_shared_ptr;
+DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
+ DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
+ LineTableConstIter pos = m_lineTableMap.find(offset);
+ if (pos != m_lineTableMap.end())
+ line_table_shared_ptr = pos->second;
+ return line_table_shared_ptr;
}
-
//----------------------------------------------------------------------
// DumpStateToFile
//----------------------------------------------------------------------
-static void
-DumpStateToFile (dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
-{
- Log *log = (Log *)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable)
- {
- // If the row is zero we are being called with the prologue only
- state.prologue->Dump (log);
- log->PutCString ("Address Line Column File");
- log->PutCString ("------------------ ------ ------ ------");
- }
- else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
- {
- // Done parsing line table
- }
- else
- {
- log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : "");
- }
+static void DumpStateToFile(dw_offset_t offset,
+ const DWARFDebugLine::State &state,
+ void *userData) {
+ Log *log = (Log *)userData;
+ if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
+ // If the row is zero we are being called with the prologue only
+ state.prologue->Dump(log);
+ log->PutCString("Address Line Column File");
+ log->PutCString("------------------ ------ ------ ------");
+ } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
+ // Done parsing line table
+ } else {
+ log->Printf("0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line,
+ state.column, state.file, state.end_sequence ? " END" : "");
+ }
}
//----------------------------------------------------------------------
// DWARFDebugLine::DumpLineTableRows
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset)
-{
- const DWARFDataExtractor& debug_line_data = dwarf2Data->get_debug_line_data();
-
- if (debug_line_offset == DW_INVALID_OFFSET)
- {
- // Dump line table to a single file only
- debug_line_offset = 0;
- while (debug_line_data.ValidOffset(debug_line_offset))
- debug_line_offset = DumpStatementTable (log, debug_line_data, debug_line_offset);
- }
- else
- {
- // Dump line table to a single file only
- DumpStatementTable (log, debug_line_data, debug_line_offset);
- }
- return false;
+bool DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t debug_line_offset) {
+ const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
+
+ if (debug_line_offset == DW_INVALID_OFFSET) {
+ // Dump line table to a single file only
+ debug_line_offset = 0;
+ while (debug_line_data.ValidOffset(debug_line_offset))
+ debug_line_offset =
+ DumpStatementTable(log, debug_line_data, debug_line_offset);
+ } else {
+ // Dump line table to a single file only
+ DumpStatementTable(log, debug_line_data, debug_line_offset);
+ }
+ return false;
}
//----------------------------------------------------------------------
// DWARFDebugLine::DumpStatementTable
//----------------------------------------------------------------------
dw_offset_t
-DWARFDebugLine::DumpStatementTable(Log *log, const DWARFDataExtractor& debug_line_data, const dw_offset_t debug_line_offset)
-{
- if (debug_line_data.ValidOffset(debug_line_offset))
- {
- lldb::offset_t offset = debug_line_offset;
- log->Printf( "----------------------------------------------------------------------\n"
- "debug_line[0x%8.8x]\n"
- "----------------------------------------------------------------------\n", debug_line_offset);
-
- if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
- return offset;
- else
- return debug_line_offset + 1; // Skip to next byte in .debug_line section
- }
+DWARFDebugLine::DumpStatementTable(Log *log,
+ const DWARFDataExtractor &debug_line_data,
+ const dw_offset_t debug_line_offset) {
+ if (debug_line_data.ValidOffset(debug_line_offset)) {
+ lldb::offset_t offset = debug_line_offset;
+ log->Printf("--------------------------------------------------------------"
+ "--------\n"
+ "debug_line[0x%8.8x]\n"
+ "--------------------------------------------------------------"
+ "--------\n",
+ debug_line_offset);
+
+ if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
+ return offset;
+ else
+ return debug_line_offset + 1; // Skip to next byte in .debug_line section
+ }
- return DW_INVALID_OFFSET;
+ return DW_INVALID_OFFSET;
}
-
//----------------------------------------------------------------------
// DumpOpcodes
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset, uint32_t dump_flags)
-{
- const DWARFDataExtractor& debug_line_data = dwarf2Data->get_debug_line_data();
-
- if (debug_line_data.GetByteSize() == 0)
- {
- log->Printf( "< EMPTY >\n");
- return false;
- }
+bool DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t debug_line_offset,
+ uint32_t dump_flags) {
+ const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
- if (debug_line_offset == DW_INVALID_OFFSET)
- {
- // Dump line table to a single file only
- debug_line_offset = 0;
- while (debug_line_data.ValidOffset(debug_line_offset))
- debug_line_offset = DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags);
- }
- else
- {
- // Dump line table to a single file only
- DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags);
- }
+ if (debug_line_data.GetByteSize() == 0) {
+ log->Printf("< EMPTY >\n");
return false;
+ }
+
+ if (debug_line_offset == DW_INVALID_OFFSET) {
+ // Dump line table to a single file only
+ debug_line_offset = 0;
+ while (debug_line_data.ValidOffset(debug_line_offset))
+ debug_line_offset = DumpStatementOpcodes(log, debug_line_data,
+ debug_line_offset, dump_flags);
+ } else {
+ // Dump line table to a single file only
+ DumpStatementOpcodes(log, debug_line_data, debug_line_offset, dump_flags);
+ }
+ return false;
}
//----------------------------------------------------------------------
// DumpStatementOpcodes
//----------------------------------------------------------------------
-dw_offset_t
-DWARFDebugLine::DumpStatementOpcodes(Log *log, const DWARFDataExtractor& debug_line_data, const dw_offset_t debug_line_offset, uint32_t flags)
-{
- lldb::offset_t offset = debug_line_offset;
- if (debug_line_data.ValidOffset(offset))
- {
- Prologue prologue;
-
- if (ParsePrologue(debug_line_data, &offset, &prologue))
- {
- log->PutCString ("----------------------------------------------------------------------");
- log->Printf ("debug_line[0x%8.8x]", debug_line_offset);
- log->PutCString ("----------------------------------------------------------------------\n");
- prologue.Dump (log);
- }
- else
- {
- offset = debug_line_offset;
- log->Printf( "0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset));
- return offset;
- }
-
- Row row(prologue.default_is_stmt);
- const dw_offset_t end_offset = debug_line_offset + prologue.total_length + sizeof(prologue.total_length);
+dw_offset_t DWARFDebugLine::DumpStatementOpcodes(
+ Log *log, const DWARFDataExtractor &debug_line_data,
+ const dw_offset_t debug_line_offset, uint32_t flags) {
+ lldb::offset_t offset = debug_line_offset;
+ if (debug_line_data.ValidOffset(offset)) {
+ Prologue prologue;
- assert(debug_line_data.ValidOffset(end_offset-1));
+ if (ParsePrologue(debug_line_data, &offset, &prologue)) {
+ log->PutCString("--------------------------------------------------------"
+ "--------------");
+ log->Printf("debug_line[0x%8.8x]", debug_line_offset);
+ log->PutCString("--------------------------------------------------------"
+ "--------------\n");
+ prologue.Dump(log);
+ } else {
+ offset = debug_line_offset;
+ log->Printf("0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset,
+ debug_line_data.GetU8(&offset));
+ return offset;
+ }
- while (offset < end_offset)
- {
- const uint32_t op_offset = offset;
- uint8_t opcode = debug_line_data.GetU8(&offset);
- switch (opcode)
- {
- case 0: // Extended Opcodes always start with a zero opcode followed by
- { // a uleb128 length so you can skip ones you don't know about
-
- dw_offset_t ext_offset = offset;
- dw_uleb128_t len = debug_line_data.GetULEB128(&offset);
- dw_offset_t arg_size = len - (offset - ext_offset);
- uint8_t sub_opcode = debug_line_data.GetU8(&offset);
-// if (verbose)
-// log->Printf( "Extended: <%u> %2.2x ", len, sub_opcode);
-
- switch (sub_opcode)
- {
- case DW_LNE_end_sequence :
- log->Printf( "0x%8.8x: DW_LNE_end_sequence", op_offset);
- row.Dump(log);
- row.Reset(prologue.default_is_stmt);
- break;
-
- case DW_LNE_set_address :
- {
- row.address = debug_line_data.GetMaxU64(&offset, arg_size);
- log->Printf( "0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset, row.address);
- }
- break;
-
- case DW_LNE_define_file:
- {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(&offset);
- fileEntry.dir_idx = debug_line_data.GetULEB128(&offset);
- fileEntry.mod_time = debug_line_data.GetULEB128(&offset);
- fileEntry.length = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNE_define_file('%s', dir=%i, mod_time=0x%8.8x, length=%i )",
- op_offset,
- fileEntry.name,
- fileEntry.dir_idx,
- fileEntry.mod_time,
- fileEntry.length);
- prologue.file_names.push_back(fileEntry);
- }
- break;
-
- case DW_LNE_set_discriminator:
- {
- uint64_t discriminator = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")", op_offset, discriminator);
- }
- break;
- default:
- log->Printf( "0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode", op_offset, opcode);
- // Length doesn't include the zero opcode byte or the length itself, but
- // it does include the sub_opcode, so we have to adjust for that below
- offset += arg_size;
- break;
- }
- }
- break;
-
- // Standard Opcodes
- case DW_LNS_copy:
- log->Printf( "0x%8.8x: DW_LNS_copy", op_offset);
- row.Dump (log);
- break;
-
- case DW_LNS_advance_pc:
- {
- dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset);
- dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length;
- log->Printf( "0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset, addr_offset);
- row.address += addr_offset;
- }
- break;
-
- case DW_LNS_advance_line:
- {
- dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_advance_line (%i)", op_offset, line_offset);
- row.line += line_offset;
- }
- break;
-
- case DW_LNS_set_file:
- row.file = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file);
- break;
-
- case DW_LNS_set_column:
- row.column = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column);
- break;
-
- case DW_LNS_negate_stmt:
- row.is_stmt = !row.is_stmt;
- log->Printf( "0x%8.8x: DW_LNS_negate_stmt", op_offset);
- break;
-
- case DW_LNS_set_basic_block:
- row.basic_block = true;
- log->Printf( "0x%8.8x: DW_LNS_set_basic_block", op_offset);
- break;
-
- case DW_LNS_const_add_pc:
- {
- uint8_t adjust_opcode = 255 - prologue.opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")", op_offset, addr_offset);
- row.address += addr_offset;
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- {
- uint16_t pc_offset = debug_line_data.GetU16(&offset);
- log->Printf( "0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset, pc_offset);
- row.address += pc_offset;
- }
- break;
-
- case DW_LNS_set_prologue_end:
- row.prologue_end = true;
- log->Printf( "0x%8.8x: DW_LNS_set_prologue_end", op_offset);
- break;
-
- case DW_LNS_set_epilogue_begin:
- row.epilogue_begin = true;
- log->Printf( "0x%8.8x: DW_LNS_set_epilogue_begin", op_offset);
- break;
-
- case DW_LNS_set_isa:
- row.isa = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa);
- break;
-
- // Special Opcodes
- default:
- if (opcode < prologue.opcode_base)
- {
- // We have an opcode that this parser doesn't know about, skip
- // the number of ULEB128 numbers that is says to skip in the
- // prologue's standard_opcode_lengths array
- uint8_t n = prologue.standard_opcode_lengths[opcode-1];
- log->Printf( "0x%8.8x: Special : Unknown skipping %u ULEB128 values.", op_offset, n);
- while (n > 0)
- {
- debug_line_data.GetULEB128(&offset);
- --n;
- }
- }
- else
- {
- uint8_t adjust_opcode = opcode - prologue.opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- int32_t line_offset = prologue.line_base + (adjust_opcode % prologue.line_range);
- log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n", op_offset, (uint64_t)addr_offset, line_offset);
- row.address += addr_offset;
- row.line += line_offset;
- row.Dump (log);
- }
- break;
- }
+ Row row(prologue.default_is_stmt);
+ const dw_offset_t end_offset = debug_line_offset + prologue.total_length +
+ sizeof(prologue.total_length);
+
+ assert(debug_line_data.ValidOffset(end_offset - 1));
+
+ while (offset < end_offset) {
+ const uint32_t op_offset = offset;
+ uint8_t opcode = debug_line_data.GetU8(&offset);
+ switch (opcode) {
+ case 0: // Extended Opcodes always start with a zero opcode followed by
+ { // a uleb128 length so you can skip ones you don't know about
+
+ dw_offset_t ext_offset = offset;
+ dw_uleb128_t len = debug_line_data.GetULEB128(&offset);
+ dw_offset_t arg_size = len - (offset - ext_offset);
+ uint8_t sub_opcode = debug_line_data.GetU8(&offset);
+ // if (verbose)
+ // log->Printf( "Extended: <%u> %2.2x ", len,
+ // sub_opcode);
+
+ switch (sub_opcode) {
+ case DW_LNE_end_sequence:
+ log->Printf("0x%8.8x: DW_LNE_end_sequence", op_offset);
+ row.Dump(log);
+ row.Reset(prologue.default_is_stmt);
+ break;
+
+ case DW_LNE_set_address: {
+ row.address = debug_line_data.GetMaxU64(&offset, arg_size);
+ log->Printf("0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset,
+ row.address);
+ } break;
+
+ case DW_LNE_define_file: {
+ FileNameEntry fileEntry;
+ fileEntry.name = debug_line_data.GetCStr(&offset);
+ fileEntry.dir_idx = debug_line_data.GetULEB128(&offset);
+ fileEntry.mod_time = debug_line_data.GetULEB128(&offset);
+ fileEntry.length = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNE_define_file('%s', dir=%i, "
+ "mod_time=0x%8.8x, length=%i )",
+ op_offset, fileEntry.name, fileEntry.dir_idx,
+ fileEntry.mod_time, fileEntry.length);
+ prologue.file_names.push_back(fileEntry);
+ } break;
+
+ case DW_LNE_set_discriminator: {
+ uint64_t discriminator = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")",
+ op_offset, discriminator);
+ } break;
+ default:
+ log->Printf("0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode",
+ op_offset, opcode);
+ // Length doesn't include the zero opcode byte or the length itself,
+ // but
+ // it does include the sub_opcode, so we have to adjust for that below
+ offset += arg_size;
+ break;
+ }
+ } break;
+
+ // Standard Opcodes
+ case DW_LNS_copy:
+ log->Printf("0x%8.8x: DW_LNS_copy", op_offset);
+ row.Dump(log);
+ break;
+
+ case DW_LNS_advance_pc: {
+ dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset);
+ dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length;
+ log->Printf("0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset,
+ addr_offset);
+ row.address += addr_offset;
+ } break;
+
+ case DW_LNS_advance_line: {
+ dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_advance_line (%i)", op_offset,
+ line_offset);
+ row.line += line_offset;
+ } break;
+
+ case DW_LNS_set_file:
+ row.file = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file);
+ break;
+
+ case DW_LNS_set_column:
+ row.column = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column);
+ break;
+
+ case DW_LNS_negate_stmt:
+ row.is_stmt = !row.is_stmt;
+ log->Printf("0x%8.8x: DW_LNS_negate_stmt", op_offset);
+ break;
+
+ case DW_LNS_set_basic_block:
+ row.basic_block = true;
+ log->Printf("0x%8.8x: DW_LNS_set_basic_block", op_offset);
+ break;
+
+ case DW_LNS_const_add_pc: {
+ uint8_t adjust_opcode = 255 - prologue.opcode_base;
+ dw_addr_t addr_offset =
+ (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
+ log->Printf("0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")",
+ op_offset, addr_offset);
+ row.address += addr_offset;
+ } break;
+
+ case DW_LNS_fixed_advance_pc: {
+ uint16_t pc_offset = debug_line_data.GetU16(&offset);
+ log->Printf("0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset,
+ pc_offset);
+ row.address += pc_offset;
+ } break;
+
+ case DW_LNS_set_prologue_end:
+ row.prologue_end = true;
+ log->Printf("0x%8.8x: DW_LNS_set_prologue_end", op_offset);
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ row.epilogue_begin = true;
+ log->Printf("0x%8.8x: DW_LNS_set_epilogue_begin", op_offset);
+ break;
+
+ case DW_LNS_set_isa:
+ row.isa = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa);
+ break;
+
+ // Special Opcodes
+ default:
+ if (opcode < prologue.opcode_base) {
+ // We have an opcode that this parser doesn't know about, skip
+ // the number of ULEB128 numbers that is says to skip in the
+ // prologue's standard_opcode_lengths array
+ uint8_t n = prologue.standard_opcode_lengths[opcode - 1];
+ log->Printf("0x%8.8x: Special : Unknown skipping %u ULEB128 values.",
+ op_offset, n);
+ while (n > 0) {
+ debug_line_data.GetULEB128(&offset);
+ --n;
+ }
+ } else {
+ uint8_t adjust_opcode = opcode - prologue.opcode_base;
+ dw_addr_t addr_offset =
+ (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
+ int32_t line_offset =
+ prologue.line_base + (adjust_opcode % prologue.line_range);
+ log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n",
+ op_offset, (uint64_t)addr_offset, line_offset);
+ row.address += addr_offset;
+ row.line += line_offset;
+ row.Dump(log);
}
- return end_offset;
+ break;
+ }
}
- return DW_INVALID_OFFSET;
+ return end_offset;
+ }
+ return DW_INVALID_OFFSET;
}
-
-
-
//----------------------------------------------------------------------
// Parse
//
@@ -391,120 +361,112 @@ DWARFDebugLine::DumpStatementOpcodes(Log *log, const DWARFDataExtractor& debug_l
// new prologue is parsed and every time a new row is to be added to
// the line table.
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Parse(const DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData)
-{
- lldb::offset_t offset = 0;
- if (debug_line_data.ValidOffset(offset))
- {
- if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
- ++offset; // Skip to next byte in .debug_line section
- }
+void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
+ DWARFDebugLine::State::Callback callback,
+ void *userData) {
+ lldb::offset_t offset = 0;
+ if (debug_line_data.ValidOffset(offset)) {
+ if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
+ ++offset; // Skip to next byte in .debug_line section
+ }
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::ParsePrologue(const DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue)
-{
- const lldb::offset_t prologue_offset = *offset_ptr;
-
- //DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
-
- prologue->Clear();
- uint32_t i;
- 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)
- return false;
-
- prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
- const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
- prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
- if (prologue->version >= 4)
- prologue->maximum_operations_per_instruction = debug_line_data.GetU8(offset_ptr);
- else
- prologue->maximum_operations_per_instruction = 1;
- prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
- prologue->line_base = debug_line_data.GetU8(offset_ptr);
- prologue->line_range = debug_line_data.GetU8(offset_ptr);
- prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
-
- prologue->standard_opcode_lengths.reserve(prologue->opcode_base-1);
-
- for (i=1; i<prologue->opcode_base; ++i)
- {
- uint8_t op_len = debug_line_data.GetU8(offset_ptr);
- 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;
- }
-
- 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;
- }
+bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr,
+ Prologue *prologue) {
+ const lldb::offset_t prologue_offset = *offset_ptr;
+
+ // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
+
+ prologue->Clear();
+ uint32_t i;
+ 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)
+ return false;
- // XXX GNU as is broken for 64-Bit DWARF
- if (*offset_ptr != end_prologue_offset)
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: parsing line table prologue at 0x%8.8" PRIx64 " should have ended at 0x%8.8" PRIx64 " but it ended at 0x%8.8" PRIx64 "\n",
- prologue_offset,
- end_prologue_offset,
- *offset_ptr);
- }
- return end_prologue_offset;
+ prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
+ const lldb::offset_t end_prologue_offset =
+ prologue->prologue_length + *offset_ptr;
+ prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
+ if (prologue->version >= 4)
+ prologue->maximum_operations_per_instruction =
+ debug_line_data.GetU8(offset_ptr);
+ else
+ prologue->maximum_operations_per_instruction = 1;
+ prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
+ prologue->line_base = debug_line_data.GetU8(offset_ptr);
+ prologue->line_range = debug_line_data.GetU8(offset_ptr);
+ prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
+
+ prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1);
+
+ for (i = 1; i < prologue->opcode_base; ++i) {
+ uint8_t op_len = debug_line_data.GetU8(offset_ptr);
+ 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;
+ }
+
+ 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
+ if (*offset_ptr != end_prologue_offset) {
+ Host::SystemLog(Host::eSystemLogWarning,
+ "warning: parsing line table prologue at 0x%8.8" PRIx64
+ " should have ended at 0x%8.8" PRIx64
+ " but it ended at 0x%8.8" PRIx64 "\n",
+ prologue_offset, end_prologue_offset, *offset_ptr);
+ }
+ return end_prologue_offset;
}
-bool
-DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp,
- const DWARFDataExtractor& debug_line_data,
- const char *cu_comp_dir,
- dw_offset_t stmt_list,
- FileSpecList &support_files)
-{
- lldb::offset_t offset = stmt_list;
-
- Prologue prologue;
- if (!ParsePrologue(debug_line_data, &offset, &prologue))
- {
- Host::SystemLog (Host::eSystemLogError, "error: parsing line table prologue at 0x%8.8x (parsing ended around 0x%8.8" PRIx64 "\n", stmt_list, offset);
- return false;
- }
-
- FileSpec file_spec;
- std::string remapped_file;
-
- for (uint32_t file_idx = 1; prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx)
- {
- if (module_sp->RemapSourceFile(file_spec.GetCString(), remapped_file))
- file_spec.SetFile(remapped_file, false);
- support_files.Append(file_spec);
-
- }
- return true;
+bool DWARFDebugLine::ParseSupportFiles(
+ const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
+ const char *cu_comp_dir, dw_offset_t stmt_list,
+ FileSpecList &support_files) {
+ lldb::offset_t offset = stmt_list;
+
+ Prologue prologue;
+ if (!ParsePrologue(debug_line_data, &offset, &prologue)) {
+ Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
+ "at 0x%8.8x (parsing ended around "
+ "0x%8.8" PRIx64 "\n",
+ stmt_list, offset);
+ return false;
+ }
+
+ FileSpec file_spec;
+ std::string remapped_file;
+
+ 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);
+ support_files.Append(file_spec);
+ }
+ return true;
}
//----------------------------------------------------------------------
@@ -514,304 +476,294 @@ DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp,
// callback function once for the prologue (row in state will be zero)
// and each time a row is to be added to the line table.
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::ParseStatementTable
-(
- const DWARFDataExtractor& debug_line_data,
- lldb::offset_t* offset_ptr,
- DWARFDebugLine::State::Callback callback,
- void* userData
-)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
- Prologue::shared_ptr prologue(new Prologue());
-
-
- const dw_offset_t debug_line_offset = *offset_ptr;
-
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
- debug_line_offset);
-
- if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get()))
- {
- if (log)
- log->Error ("failed to parse DWARF line table prologue");
- // Restore our offset and return false to indicate failure!
- *offset_ptr = debug_line_offset;
- return false;
- }
+bool DWARFDebugLine::ParseStatementTable(
+ const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
+ DWARFDebugLine::State::Callback callback, void *userData) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
+ Prologue::shared_ptr prologue(new Prologue());
- if (log)
- prologue->Dump (log);
+ const dw_offset_t debug_line_offset = *offset_ptr;
- const dw_offset_t end_offset = debug_line_offset + prologue->total_length + (debug_line_data.GetDWARFSizeofInitialLength());
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
+ debug_line_offset);
- State state(prologue, log, callback, userData);
-
- while (*offset_ptr < end_offset)
- {
- //DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
- uint8_t opcode = debug_line_data.GetU8(offset_ptr);
-
- if (opcode == 0)
+ if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) {
+ if (log)
+ log->Error("failed to parse DWARF line table prologue");
+ // Restore our offset and return false to indicate failure!
+ *offset_ptr = debug_line_offset;
+ return false;
+ }
+
+ if (log)
+ prologue->Dump(log);
+
+ const dw_offset_t end_offset =
+ debug_line_offset + prologue->total_length +
+ (debug_line_data.GetDWARFSizeofInitialLength());
+
+ State state(prologue, log, callback, userData);
+
+ while (*offset_ptr < end_offset) {
+ // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
+ uint8_t opcode = debug_line_data.GetU8(offset_ptr);
+
+ if (opcode == 0) {
+ // Extended Opcodes always start with a zero opcode followed by
+ // a uleb128 length so you can skip ones you don't know about
+ lldb::offset_t ext_offset = *offset_ptr;
+ dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
+ dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
+
+ // DEBUG_PRINTF("Extended: <%2u> ", len);
+ uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
+ switch (sub_opcode) {
+ case DW_LNE_end_sequence:
+ // Set the end_sequence register of the state machine to true and
+ // append a row to the matrix using the current values of the
+ // state-machine registers. Then reset the registers to the initial
+ // values specified above. Every statement program sequence must end
+ // with a DW_LNE_end_sequence instruction which creates a row whose
+ // address is that of the byte after the last target machine instruction
+ // of the sequence.
+ state.end_sequence = true;
+ state.AppendRowToMatrix(*offset_ptr);
+ state.Reset();
+ break;
+
+ case DW_LNE_set_address:
+ // Takes a single relocatable address as an operand. The size of the
+ // operand is the size appropriate to hold an address on the target
+ // machine. Set the address register to the value given by the
+ // relocatable address. All of the other statement program opcodes
+ // that affect the address register add a delta to it. This instruction
+ // stores a relocatable value into it instead.
+ if (arg_size == 4)
+ state.address = debug_line_data.GetU32(offset_ptr);
+ else // arg_size == 8
+ state.address = debug_line_data.GetU64(offset_ptr);
+ break;
+
+ case DW_LNE_define_file:
+ // Takes 4 arguments. The first is a null terminated string containing
+ // a source file name. The second is an unsigned LEB128 number
+ // representing
+ // the directory index of the directory in which the file was found. The
+ // third is an unsigned LEB128 number representing the time of last
+ // modification of the file. The fourth is an unsigned LEB128 number
+ // representing the length in bytes of the file. The time and length
+ // fields may contain LEB128(0) if the information is not available.
+ //
+ // The directory index represents an entry in the include_directories
+ // section of the statement program prologue. The index is LEB128(0)
+ // if the file was found in the current directory of the compilation,
+ // LEB128(1) if it was found in the first directory in the
+ // include_directories section, and so on. The directory index is
+ // ignored for file names that represent full path names.
+ //
+ // The files are numbered, starting at 1, in the order in which they
+ // appear; the names in the prologue come before names defined by
+ // the DW_LNE_define_file instruction. These numbers are used in the
+ // file register of the state machine.
{
- // Extended Opcodes always start with a zero opcode followed by
- // a uleb128 length so you can skip ones you don't know about
- lldb::offset_t ext_offset = *offset_ptr;
- dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
- dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
-
- //DEBUG_PRINTF("Extended: <%2u> ", len);
- uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
- switch (sub_opcode)
- {
- case DW_LNE_end_sequence:
- // Set the end_sequence register of the state machine to true and
- // append a row to the matrix using the current values of the
- // state-machine registers. Then reset the registers to the initial
- // values specified above. Every statement program sequence must end
- // with a DW_LNE_end_sequence instruction which creates a row whose
- // address is that of the byte after the last target machine instruction
- // of the sequence.
- state.end_sequence = true;
- state.AppendRowToMatrix(*offset_ptr);
- state.Reset();
- break;
-
- case DW_LNE_set_address:
- // Takes a single relocatable address as an operand. The size of the
- // operand is the size appropriate to hold an address on the target
- // machine. Set the address register to the value given by the
- // relocatable address. All of the other statement program opcodes
- // that affect the address register add a delta to it. This instruction
- // stores a relocatable value into it instead.
- if (arg_size == 4)
- state.address = debug_line_data.GetU32(offset_ptr);
- else // arg_size == 8
- state.address = debug_line_data.GetU64(offset_ptr);
- break;
-
- case DW_LNE_define_file:
- // Takes 4 arguments. The first is a null terminated string containing
- // a source file name. The second is an unsigned LEB128 number representing
- // the directory index of the directory in which the file was found. The
- // third is an unsigned LEB128 number representing the time of last
- // modification of the file. The fourth is an unsigned LEB128 number
- // representing the length in bytes of the file. The time and length
- // fields may contain LEB128(0) if the information is not available.
- //
- // The directory index represents an entry in the include_directories
- // section of the statement program prologue. The index is LEB128(0)
- // if the file was found in the current directory of the compilation,
- // LEB128(1) if it was found in the first directory in the
- // include_directories section, and so on. The directory index is
- // ignored for file names that represent full path names.
- //
- // The files are numbered, starting at 1, in the order in which they
- // appear; the names in the prologue come before names defined by
- // the DW_LNE_define_file instruction. These numbers are used in the
- // file register of the state machine.
- {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(offset_ptr);
- 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);
- state.prologue->file_names.push_back(fileEntry);
- }
- break;
-
- default:
- // Length doesn't include the zero opcode byte or the length itself, but
- // it does include the sub_opcode, so we have to adjust for that below
- (*offset_ptr) += arg_size;
- break;
- }
+ FileNameEntry fileEntry;
+ fileEntry.name = debug_line_data.GetCStr(offset_ptr);
+ 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);
+ state.prologue->file_names.push_back(fileEntry);
}
- else if (opcode < prologue->opcode_base)
+ break;
+
+ default:
+ // Length doesn't include the zero opcode byte or the length itself, but
+ // it does include the sub_opcode, so we have to adjust for that below
+ (*offset_ptr) += arg_size;
+ break;
+ }
+ } else if (opcode < prologue->opcode_base) {
+ switch (opcode) {
+ // Standard Opcodes
+ case DW_LNS_copy:
+ // Takes no arguments. Append a row to the matrix using the
+ // current values of the state-machine registers. Then set
+ // the basic_block register to false.
+ state.AppendRowToMatrix(*offset_ptr);
+ break;
+
+ case DW_LNS_advance_pc:
+ // Takes a single unsigned LEB128 operand, multiplies it by the
+ // min_inst_length field of the prologue, and adds the
+ // result to the address register of the state machine.
+ state.address +=
+ debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
+ break;
+
+ case DW_LNS_advance_line:
+ // Takes a single signed LEB128 operand and adds that value to
+ // the line register of the state machine.
+ state.line += debug_line_data.GetSLEB128(offset_ptr);
+ break;
+
+ case DW_LNS_set_file:
+ // Takes a single unsigned LEB128 operand and stores it in the file
+ // register of the state machine.
+ state.file = debug_line_data.GetULEB128(offset_ptr);
+ break;
+
+ case DW_LNS_set_column:
+ // Takes a single unsigned LEB128 operand and stores it in the
+ // column register of the state machine.
+ state.column = debug_line_data.GetULEB128(offset_ptr);
+ break;
+
+ case DW_LNS_negate_stmt:
+ // Takes no arguments. Set the is_stmt register of the state
+ // machine to the logical negation of its current value.
+ state.is_stmt = !state.is_stmt;
+ break;
+
+ case DW_LNS_set_basic_block:
+ // Takes no arguments. Set the basic_block register of the
+ // state machine to true
+ state.basic_block = true;
+ break;
+
+ case DW_LNS_const_add_pc:
+ // Takes no arguments. Add to the address register of the state
+ // machine the address increment value corresponding to special
+ // opcode 255. The motivation for DW_LNS_const_add_pc is this:
+ // when the statement program needs to advance the address by a
+ // small amount, it can use a single special opcode, which occupies
+ // a single byte. When it needs to advance the address by up to
+ // twice the range of the last special opcode, it can use
+ // DW_LNS_const_add_pc followed by a special opcode, for a total
+ // of two bytes. Only if it needs to advance the address by more
+ // than twice that range will it need to use both DW_LNS_advance_pc
+ // and a special opcode, requiring three or more bytes.
{
- switch (opcode)
- {
- // Standard Opcodes
- case DW_LNS_copy:
- // Takes no arguments. Append a row to the matrix using the
- // current values of the state-machine registers. Then set
- // the basic_block register to false.
- state.AppendRowToMatrix(*offset_ptr);
- break;
-
- case DW_LNS_advance_pc:
- // Takes a single unsigned LEB128 operand, multiplies it by the
- // min_inst_length field of the prologue, and adds the
- // result to the address register of the state machine.
- state.address += debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
- break;
-
- case DW_LNS_advance_line:
- // Takes a single signed LEB128 operand and adds that value to
- // the line register of the state machine.
- state.line += debug_line_data.GetSLEB128(offset_ptr);
- break;
-
- case DW_LNS_set_file:
- // Takes a single unsigned LEB128 operand and stores it in the file
- // register of the state machine.
- state.file = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_set_column:
- // Takes a single unsigned LEB128 operand and stores it in the
- // column register of the state machine.
- state.column = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_negate_stmt:
- // Takes no arguments. Set the is_stmt register of the state
- // machine to the logical negation of its current value.
- state.is_stmt = !state.is_stmt;
- break;
-
- case DW_LNS_set_basic_block:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
- state.basic_block = true;
- break;
-
- case DW_LNS_const_add_pc:
- // Takes no arguments. Add to the address register of the state
- // machine the address increment value corresponding to special
- // opcode 255. The motivation for DW_LNS_const_add_pc is this:
- // when the statement program needs to advance the address by a
- // small amount, it can use a single special opcode, which occupies
- // a single byte. When it needs to advance the address by up to
- // twice the range of the last special opcode, it can use
- // DW_LNS_const_add_pc followed by a special opcode, for a total
- // of two bytes. Only if it needs to advance the address by more
- // than twice that range will it need to use both DW_LNS_advance_pc
- // and a special opcode, requiring three or more bytes.
- {
- uint8_t adjust_opcode = 255 - prologue->opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
- state.address += addr_offset;
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- // Takes a single uhalf operand. Add to the address register of
- // the state machine the value of the (unencoded) operand. This
- // is the only extended opcode that takes an argument that is not
- // a variable length number. The motivation for DW_LNS_fixed_advance_pc
- // is this: existing assemblers cannot emit DW_LNS_advance_pc or
- // special opcodes because they cannot encode LEB128 numbers or
- // judge when the computation of a special opcode overflows and
- // requires the use of DW_LNS_advance_pc. Such assemblers, however,
- // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
- state.address += debug_line_data.GetU16(offset_ptr);
- break;
-
- case DW_LNS_set_prologue_end:
- // Takes no arguments. Set the prologue_end register of the
- // state machine to true
- state.prologue_end = true;
- break;
-
- case DW_LNS_set_epilogue_begin:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
- state.epilogue_begin = true;
- break;
-
- case DW_LNS_set_isa:
- // Takes a single unsigned LEB128 operand and stores it in the
- // column register of the state machine.
- state.isa = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- default:
- // Handle any unknown standard opcodes here. We know the lengths
- // of such opcodes because they are specified in the prologue
- // as a multiple of LEB128 operands for each opcode.
- {
- uint8_t i;
- assert (static_cast<size_t>(opcode - 1) < prologue->standard_opcode_lengths.size());
- const uint8_t opcode_length = prologue->standard_opcode_lengths[opcode - 1];
- for (i=0; i<opcode_length; ++i)
- debug_line_data.Skip_LEB128(offset_ptr);
- }
- break;
- }
+ uint8_t adjust_opcode = 255 - prologue->opcode_base;
+ dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
+ prologue->min_inst_length;
+ state.address += addr_offset;
}
- else
+ break;
+
+ case DW_LNS_fixed_advance_pc:
+ // Takes a single uhalf operand. Add to the address register of
+ // the state machine the value of the (unencoded) operand. This
+ // is the only extended opcode that takes an argument that is not
+ // a variable length number. The motivation for DW_LNS_fixed_advance_pc
+ // is this: existing assemblers cannot emit DW_LNS_advance_pc or
+ // special opcodes because they cannot encode LEB128 numbers or
+ // judge when the computation of a special opcode overflows and
+ // requires the use of DW_LNS_advance_pc. Such assemblers, however,
+ // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
+ state.address += debug_line_data.GetU16(offset_ptr);
+ break;
+
+ case DW_LNS_set_prologue_end:
+ // Takes no arguments. Set the prologue_end register of the
+ // state machine to true
+ state.prologue_end = true;
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ // Takes no arguments. Set the basic_block register of the
+ // state machine to true
+ state.epilogue_begin = true;
+ break;
+
+ case DW_LNS_set_isa:
+ // Takes a single unsigned LEB128 operand and stores it in the
+ // column register of the state machine.
+ state.isa = debug_line_data.GetULEB128(offset_ptr);
+ break;
+
+ default:
+ // Handle any unknown standard opcodes here. We know the lengths
+ // of such opcodes because they are specified in the prologue
+ // as a multiple of LEB128 operands for each opcode.
{
- // Special Opcodes
-
- // A special opcode value is chosen based on the amount that needs
- // to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base
- // field in the header, plus the value of the line_range field,
- // minus 1 (line base + line range - 1). If the desired line
- // increment is greater than the maximum line increment, a standard
- // opcode must be used instead of a special opcode. The "address
- // advance" is calculated by dividing the desired address increment
- // by the minimum_instruction_length field from the header. The
- // special opcode is then calculated using the following formula:
- //
- // opcode = (desired line increment - line_base) + (line_range * address advance) + opcode_base
- //
- // If the resulting opcode is greater than 255, a standard opcode
- // must be used instead.
- //
- // To decode a special opcode, subtract the opcode_base from the
- // opcode itself to give the adjusted opcode. The amount to
- // increment the address register is the result of the adjusted
- // opcode divided by the line_range multiplied by the
- // minimum_instruction_length field from the header. That is:
- //
- // address increment = (adjusted opcode / line_range) * minimum_instruction_length
- //
- // The amount to increment the line register is the line_base plus
- // the result of the adjusted opcode modulo the line_range. That is:
- //
- // line increment = line_base + (adjusted opcode % line_range)
-
- uint8_t adjust_opcode = opcode - prologue->opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
- int32_t line_offset = prologue->line_base + (adjust_opcode % prologue->line_range);
- state.line += line_offset;
- state.address += addr_offset;
- state.AppendRowToMatrix(*offset_ptr);
+ uint8_t i;
+ assert(static_cast<size_t>(opcode - 1) <
+ prologue->standard_opcode_lengths.size());
+ const uint8_t opcode_length =
+ prologue->standard_opcode_lengths[opcode - 1];
+ for (i = 0; i < opcode_length; ++i)
+ debug_line_data.Skip_LEB128(offset_ptr);
}
+ break;
+ }
+ } else {
+ // Special Opcodes
+
+ // A special opcode value is chosen based on the amount that needs
+ // to be added to the line and address registers. The maximum line
+ // increment for a special opcode is the value of the line_base
+ // field in the header, plus the value of the line_range field,
+ // minus 1 (line base + line range - 1). If the desired line
+ // increment is greater than the maximum line increment, a standard
+ // opcode must be used instead of a special opcode. The "address
+ // advance" is calculated by dividing the desired address increment
+ // by the minimum_instruction_length field from the header. The
+ // special opcode is then calculated using the following formula:
+ //
+ // opcode = (desired line increment - line_base) + (line_range * address
+ // advance) + opcode_base
+ //
+ // If the resulting opcode is greater than 255, a standard opcode
+ // must be used instead.
+ //
+ // To decode a special opcode, subtract the opcode_base from the
+ // opcode itself to give the adjusted opcode. The amount to
+ // increment the address register is the result of the adjusted
+ // opcode divided by the line_range multiplied by the
+ // minimum_instruction_length field from the header. That is:
+ //
+ // address increment = (adjusted opcode / line_range) *
+ // minimum_instruction_length
+ //
+ // The amount to increment the line register is the line_base plus
+ // the result of the adjusted opcode modulo the line_range. That is:
+ //
+ // line increment = line_base + (adjusted opcode % line_range)
+
+ uint8_t adjust_opcode = opcode - prologue->opcode_base;
+ dw_addr_t addr_offset =
+ (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
+ int32_t line_offset =
+ prologue->line_base + (adjust_opcode % prologue->line_range);
+ state.line += line_offset;
+ state.address += addr_offset;
+ state.AppendRowToMatrix(*offset_ptr);
}
+ }
- state.Finalize( *offset_ptr );
+ state.Finalize(*offset_ptr);
- return end_offset;
+ return end_offset;
}
-
//----------------------------------------------------------------------
// ParseStatementTableCallback
//----------------------------------------------------------------------
-static void
-ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
-{
- DWARFDebugLine::LineTable* line_table = (DWARFDebugLine::LineTable*)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable)
- {
- // Just started parsing the line table, so lets keep a reference to
- // the prologue using the supplied shared pointer
- line_table->prologue = state.prologue;
- }
- else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
- {
- // Done parsing line table, nothing to do for the cleanup
- }
- else
- {
- // We have a new row, lets append it
- line_table->AppendRow(state);
- }
+static void ParseStatementTableCallback(dw_offset_t offset,
+ const DWARFDebugLine::State &state,
+ void *userData) {
+ DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
+ if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
+ // Just started parsing the line table, so lets keep a reference to
+ // the prologue using the supplied shared pointer
+ line_table->prologue = state.prologue;
+ } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
+ // Done parsing line table, nothing to do for the cleanup
+ } else {
+ // We have a new row, lets append it
+ line_table->AppendRow(state);
+ }
}
//----------------------------------------------------------------------
@@ -820,75 +772,65 @@ ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& sta
// Parse a line table at offset and populate the LineTable class with
// the prologue and all rows.
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::ParseStatementTable(const DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table)
-{
- return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table);
+bool DWARFDebugLine::ParseStatementTable(
+ const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
+ LineTable *line_table) {
+ return ParseStatementTable(debug_line_data, offset_ptr,
+ ParseStatementTableCallback, line_table);
}
-
-inline bool
-DWARFDebugLine::Prologue::IsValid() const
-{
- return SymbolFileDWARF::SupportedVersion(version);
+inline bool DWARFDebugLine::Prologue::IsValid() const {
+ return SymbolFileDWARF::SupportedVersion(version);
}
//----------------------------------------------------------------------
// DWARFDebugLine::Prologue::Dump
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Prologue::Dump(Log *log)
-{
- uint32_t i;
-
- log->Printf( "Line table prologue:");
- log->Printf( " total_length: 0x%8.8x", total_length);
- log->Printf( " version: %u", version);
- log->Printf( "prologue_length: 0x%8.8x", prologue_length);
- log->Printf( "min_inst_length: %u", min_inst_length);
- log->Printf( "default_is_stmt: %u", default_is_stmt);
- log->Printf( " line_base: %i", line_base);
- log->Printf( " line_range: %u", line_range);
- log->Printf( " opcode_base: %u", opcode_base);
-
- for (i=0; i<standard_opcode_lengths.size(); ++i)
- {
- log->Printf( "standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i+1), standard_opcode_lengths[i]);
+void DWARFDebugLine::Prologue::Dump(Log *log) {
+ uint32_t i;
+
+ log->Printf("Line table prologue:");
+ log->Printf(" total_length: 0x%8.8x", total_length);
+ log->Printf(" version: %u", version);
+ log->Printf("prologue_length: 0x%8.8x", prologue_length);
+ log->Printf("min_inst_length: %u", min_inst_length);
+ log->Printf("default_is_stmt: %u", default_is_stmt);
+ log->Printf(" line_base: %i", line_base);
+ log->Printf(" line_range: %u", line_range);
+ log->Printf(" opcode_base: %u", opcode_base);
+
+ for (i = 0; i < standard_opcode_lengths.size(); ++i) {
+ log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1),
+ standard_opcode_lengths[i]);
+ }
+
+ if (!include_directories.empty()) {
+ for (i = 0; i < include_directories.size(); ++i) {
+ log->Printf("include_directories[%3u] = '%s'", i + 1,
+ include_directories[i]);
}
-
- if (!include_directories.empty())
- {
- for (i=0; i<include_directories.size(); ++i)
- {
- log->Printf( "include_directories[%3u] = '%s'", i+1, include_directories[i]);
- }
- }
-
- if (!file_names.empty())
- {
- log->PutCString (" Dir Mod Time File Len File Name");
- log->PutCString (" ---- ---------- ---------- ---------------------------");
- for (i=0; i<file_names.size(); ++i)
- {
- const FileNameEntry& fileEntry = file_names[i];
- log->Printf ("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s",
- i+1,
- fileEntry.dir_idx,
- fileEntry.mod_time,
- fileEntry.length,
- fileEntry.name);
- }
+ }
+
+ if (!file_names.empty()) {
+ log->PutCString(" Dir Mod Time File Len File Name");
+ log->PutCString(" ---- ---------- ---------- "
+ "---------------------------");
+ for (i = 0; i < file_names.size(); ++i) {
+ const FileNameEntry &fileEntry = file_names[i];
+ log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1,
+ fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length,
+ fileEntry.name);
}
+ }
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue::Append
//
// Append the contents of the prologue to the binary stream buffer
//----------------------------------------------------------------------
-//void
-//DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
+// void
+// DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
//{
// uint32_t i;
//
@@ -906,7 +848,8 @@ DWARFDebugLine::Prologue::Dump(Log *log)
//
// for (i=0; i<include_directories.size(); ++i)
// buff.AppendCStr(include_directories[i].c_str());
-// buff.Append8(0); // Terminate the include directory section with empty string
+// buff.Append8(0); // Terminate the include directory section with empty
+// string
//
// for (i=0; i<file_names.size(); ++i)
// {
@@ -918,307 +861,242 @@ DWARFDebugLine::Prologue::Dump(Log *log)
// buff.Append8(0); // Terminate the file names section with empty string
//}
-
-bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *comp_dir, FileSpec &file) const
-{
- uint32_t idx = file_idx - 1; // File indexes are 1 based...
- if (idx < file_names.size())
- {
- file.SetFile(file_names[idx].name, false);
- if (file.IsRelative())
- {
- if (file_names[idx].dir_idx > 0)
- {
- const uint32_t dir_idx = file_names[idx].dir_idx - 1;
- if (dir_idx < include_directories.size())
- {
- file.PrependPathComponent(include_directories[dir_idx]);
- if (!file.IsRelative())
- return true;
- }
- }
-
- if (comp_dir && comp_dir[0])
- file.PrependPathComponent(comp_dir);
+bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *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);
+ if (file.IsRelative()) {
+ if (file_names[idx].dir_idx > 0) {
+ const uint32_t dir_idx = file_names[idx].dir_idx - 1;
+ if (dir_idx < include_directories.size()) {
+ file.PrependPathComponent(include_directories[dir_idx]);
+ if (!file.IsRelative())
+ return true;
}
- return true;
+ }
+
+ if (comp_dir && comp_dir[0])
+ file.PrependPathComponent(comp_dir);
}
- return false;
+ return true;
+ }
+ return false;
}
//----------------------------------------------------------------------
// DWARFDebugLine::LineTable::Dump
//----------------------------------------------------------------------
-void
-DWARFDebugLine::LineTable::Dump(Log *log) const
-{
- if (prologue.get())
- prologue->Dump (log);
-
- if (!rows.empty())
- {
- log->PutCString ("Address Line Column File ISA Flags");
- log->PutCString ("------------------ ------ ------ ------ --- -------------");
- Row::const_iterator pos = rows.begin();
- Row::const_iterator end = rows.end();
- while (pos != end)
- {
- (*pos).Dump (log);
- ++pos;
- }
+void DWARFDebugLine::LineTable::Dump(Log *log) const {
+ if (prologue.get())
+ prologue->Dump(log);
+
+ if (!rows.empty()) {
+ log->PutCString("Address Line Column File ISA Flags");
+ log->PutCString(
+ "------------------ ------ ------ ------ --- -------------");
+ Row::const_iterator pos = rows.begin();
+ Row::const_iterator end = rows.end();
+ while (pos != end) {
+ (*pos).Dump(log);
+ ++pos;
}
+ }
}
-
-void
-DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row& state)
-{
- rows.push_back(state);
+void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
+ rows.push_back(state);
}
-
-
//----------------------------------------------------------------------
-// Compare function for the binary search in DWARFDebugLine::LineTable::LookupAddress()
+// Compare function for the binary search in
+// DWARFDebugLine::LineTable::LookupAddress()
//----------------------------------------------------------------------
-static bool FindMatchingAddress (const DWARFDebugLine::Row& row1, const DWARFDebugLine::Row& row2)
-{
- return row1.address < row2.address;
+static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
+ const DWARFDebugLine::Row &row2) {
+ return row1.address < row2.address;
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::LineTable::LookupAddress
//----------------------------------------------------------------------
-uint32_t
-DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const
-{
- uint32_t index = UINT32_MAX;
- if (!rows.empty())
- {
- // Use the lower_bound algorithm to perform a binary search since we know
- // that our line table data is ordered by address.
- DWARFDebugLine::Row row;
- row.address = address;
- Row::const_iterator begin_pos = rows.begin();
- Row::const_iterator end_pos = rows.end();
- Row::const_iterator pos = lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
- if (pos == end_pos)
- {
- if (address < cu_high_pc)
- return rows.size()-1;
- }
+uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
+ dw_addr_t cu_high_pc) const {
+ uint32_t index = UINT32_MAX;
+ if (!rows.empty()) {
+ // Use the lower_bound algorithm to perform a binary search since we know
+ // that our line table data is ordered by address.
+ DWARFDebugLine::Row row;
+ row.address = address;
+ Row::const_iterator begin_pos = rows.begin();
+ Row::const_iterator end_pos = rows.end();
+ Row::const_iterator pos =
+ lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
+ if (pos == end_pos) {
+ if (address < cu_high_pc)
+ return rows.size() - 1;
+ } else {
+ // Rely on fact that we are using a std::vector and we can do
+ // pointer arithmetic to find the row index (which will be one less
+ // that what we found since it will find the first position after
+ // the current address) since std::vector iterators are just
+ // pointers to the container type.
+ index = pos - begin_pos;
+ if (pos->address > address) {
+ if (index > 0)
+ --index;
else
- {
- // Rely on fact that we are using a std::vector and we can do
- // pointer arithmetic to find the row index (which will be one less
- // that what we found since it will find the first position after
- // the current address) since std::vector iterators are just
- // pointers to the container type.
- index = pos - begin_pos;
- if (pos->address > address)
- {
- if (index > 0)
- --index;
- else
- index = UINT32_MAX;
- }
- }
+ index = UINT32_MAX;
+ }
}
- return index; // Failed to find address
+ }
+ return index; // Failed to find address
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::Row::Row
//----------------------------------------------------------------------
-DWARFDebugLine::Row::Row(bool default_is_stmt) :
- address(0),
- line(1),
- column(0),
- file(1),
- is_stmt(default_is_stmt),
- basic_block(false),
- end_sequence(false),
- prologue_end(false),
- epilogue_begin(false),
- isa(0)
-{
-}
+DWARFDebugLine::Row::Row(bool default_is_stmt)
+ : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
+ basic_block(false), end_sequence(false), prologue_end(false),
+ epilogue_begin(false), isa(0) {}
//----------------------------------------------------------------------
// Called after a row is appended to the matrix
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Row::PostAppend()
-{
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
+void DWARFDebugLine::Row::PostAppend() {
+ basic_block = false;
+ prologue_end = false;
+ epilogue_begin = false;
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::Row::Reset
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Row::Reset(bool default_is_stmt)
-{
- address = 0;
- line = 1;
- column = 0;
- file = 1;
- is_stmt = default_is_stmt;
- basic_block = false;
- end_sequence = false;
- prologue_end = false;
- epilogue_begin = false;
- isa = 0;
+void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
+ address = 0;
+ line = 1;
+ column = 0;
+ file = 1;
+ is_stmt = default_is_stmt;
+ basic_block = false;
+ end_sequence = false;
+ prologue_end = false;
+ epilogue_begin = false;
+ isa = 0;
}
//----------------------------------------------------------------------
// DWARFDebugLine::Row::Dump
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Row::Dump(Log *log) const
-{
- log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s",
- address,
- line,
- column,
- file,
- isa,
- is_stmt ? " is_stmt" : "",
- basic_block ? " basic_block" : "",
- prologue_end ? " prologue_end" : "",
- epilogue_begin ? " epilogue_begin" : "",
- end_sequence ? " end_sequence" : "");
+void DWARFDebugLine::Row::Dump(Log *log) const {
+ log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
+ column, file, isa, is_stmt ? " is_stmt" : "",
+ basic_block ? " basic_block" : "",
+ prologue_end ? " prologue_end" : "",
+ epilogue_begin ? " epilogue_begin" : "",
+ end_sequence ? " end_sequence" : "");
}
//----------------------------------------------------------------------
// Compare function LineTable structures
//----------------------------------------------------------------------
-static bool AddressLessThan (const DWARFDebugLine::Row& a, const DWARFDebugLine::Row& b)
-{
- return a.address < b.address;
+static bool AddressLessThan(const DWARFDebugLine::Row &a,
+ const DWARFDebugLine::Row &b) {
+ return a.address < b.address;
}
-
-
// Insert a row at the correct address if the addresses can be out of
// order which can only happen when we are linking a line table that
// may have had it's contents rearranged.
-void
-DWARFDebugLine::Row::Insert(Row::collection& state_coll, const Row& state)
-{
- // If we don't have anything yet, or if the address of the last state in our
- // line table is less than the current one, just append the current state
- if (state_coll.empty() || AddressLessThan(state_coll.back(), state))
- {
- state_coll.push_back(state);
- }
- else
- {
- // Do a binary search for the correct entry
- pair<Row::iterator, Row::iterator> range(equal_range(state_coll.begin(), state_coll.end(), state, AddressLessThan));
-
- // If the addresses are equal, we can safely replace the previous entry
- // with the current one if the one it is replacing is an end_sequence entry.
- // We currently always place an extra end sequence when ever we exit a valid
- // address range for a function in case the functions get rearranged by
- // optimizations or by order specifications. These extra end sequences will
- // disappear by getting replaced with valid consecutive entries within a
- // compile unit if there are no gaps.
- if (range.first == range.second)
- {
- state_coll.insert(range.first, state);
- }
- else
- {
- if ((distance(range.first, range.second) == 1) && range.first->end_sequence == true)
- {
- *range.first = state;
- }
- else
- {
- state_coll.insert(range.second, state);
- }
- }
+void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
+ const Row &state) {
+ // If we don't have anything yet, or if the address of the last state in our
+ // line table is less than the current one, just append the current state
+ if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) {
+ state_coll.push_back(state);
+ } else {
+ // Do a binary search for the correct entry
+ pair<Row::iterator, Row::iterator> range(equal_range(
+ state_coll.begin(), state_coll.end(), state, AddressLessThan));
+
+ // If the addresses are equal, we can safely replace the previous entry
+ // with the current one if the one it is replacing is an end_sequence entry.
+ // We currently always place an extra end sequence when ever we exit a valid
+ // address range for a function in case the functions get rearranged by
+ // optimizations or by order specifications. These extra end sequences will
+ // disappear by getting replaced with valid consecutive entries within a
+ // compile unit if there are no gaps.
+ if (range.first == range.second) {
+ state_coll.insert(range.first, state);
+ } else {
+ if ((distance(range.first, range.second) == 1) &&
+ range.first->end_sequence == true) {
+ *range.first = state;
+ } else {
+ state_coll.insert(range.second, state);
+ }
}
+ }
}
-void
-DWARFDebugLine::Row::Dump(Log *log, const Row::collection& state_coll)
-{
- std::for_each (state_coll.begin(), state_coll.end(), bind2nd(std::mem_fun_ref(&Row::Dump),log));
+void DWARFDebugLine::Row::Dump(Log *log, const Row::collection &state_coll) {
+ std::for_each(state_coll.begin(), state_coll.end(),
+ bind2nd(std::mem_fun_ref(&Row::Dump), log));
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::State::State
//----------------------------------------------------------------------
-DWARFDebugLine::State::State(Prologue::shared_ptr& p, Log *l, DWARFDebugLine::State::Callback cb, void* userData) :
- Row (p->default_is_stmt),
- prologue (p),
- log (l),
- callback (cb),
- callbackUserData (userData),
- row (StartParsingLineTable)
-{
- // Call the callback with the initial row state of zero for the prologue
- if (callback)
- callback(0, *this, callbackUserData);
+DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
+ DWARFDebugLine::State::Callback cb, void *userData)
+ : Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
+ callbackUserData(userData), row(StartParsingLineTable) {
+ // Call the callback with the initial row state of zero for the prologue
+ if (callback)
+ callback(0, *this, callbackUserData);
}
//----------------------------------------------------------------------
// DWARFDebugLine::State::Reset
//----------------------------------------------------------------------
-void
-DWARFDebugLine::State::Reset()
-{
- Row::Reset(prologue->default_is_stmt);
-}
+void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
//----------------------------------------------------------------------
// DWARFDebugLine::State::AppendRowToMatrix
//----------------------------------------------------------------------
-void
-DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset)
-{
- // Each time we are to add an entry into the line table matrix
- // call the callback function so that someone can do something with
- // the current state of the state machine (like build a line table
- // or dump the line table!)
- if (log)
- {
- if (row == 0)
- {
- log->PutCString ("Address Line Column File ISA Flags");
- log->PutCString ("------------------ ------ ------ ------ --- -------------");
- }
- Dump (log);
+void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
+ // Each time we are to add an entry into the line table matrix
+ // call the callback function so that someone can do something with
+ // the current state of the state machine (like build a line table
+ // or dump the line table!)
+ if (log) {
+ if (row == 0) {
+ log->PutCString("Address Line Column File ISA Flags");
+ log->PutCString(
+ "------------------ ------ ------ ------ --- -------------");
}
+ Dump(log);
+ }
- ++row; // Increase the row number before we call our callback for a real row
- if (callback)
- callback(offset, *this, callbackUserData);
- PostAppend();
+ ++row; // Increase the row number before we call our callback for a real row
+ if (callback)
+ callback(offset, *this, callbackUserData);
+ PostAppend();
}
//----------------------------------------------------------------------
// DWARFDebugLine::State::Finalize
//----------------------------------------------------------------------
-void
-DWARFDebugLine::State::Finalize(dw_offset_t offset)
-{
- // Call the callback with a special row state when we are done parsing a
- // line table
- row = DoneParsingLineTable;
- if (callback)
- callback(offset, *this, callbackUserData);
+void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
+ // Call the callback with a special row state when we are done parsing a
+ // line table
+ row = DoneParsingLineTable;
+ if (callback)
+ callback(offset, *this, callbackUserData);
}
-//void
-//DWARFDebugLine::AppendLineTableData
+// void
+// DWARFDebugLine::AppendLineTableData
//(
// const DWARFDebugLine::Prologue* prologue,
// const DWARFDebugLine::Row::collection& state_coll,
@@ -1240,7 +1118,8 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset)
// bool default_is_stmt = prologue->default_is_stmt;
// const DWARFDebugLine::Row reset_state(default_is_stmt);
// const DWARFDebugLine::Row* prev_state = &reset_state;
-// const int32_t max_line_increment_for_special_opcode = prologue->MaxLineIncrementForSpecialOpcode();
+// const int32_t max_line_increment_for_special_opcode =
+// prologue->MaxLineIncrementForSpecialOpcode();
// for (pos = state_coll.begin(); pos != end; ++pos)
// {
// const DWARFDebugLine::Row& curr_state = *pos;
@@ -1257,7 +1136,8 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset)
// if (prev_state == &reset_state)
// {
// debug_line_data.Append8(0); // Extended opcode
-// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of opcode bytes
+// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of
+// opcode bytes
// debug_line_data.Append8(DW_LNE_set_address);
// debug_line_data.AppendMax64(curr_state.address, addr_size);
// addr_advance = 0;
@@ -1276,7 +1156,8 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset)
// }
//
// // Don't do anything fancy if we are at the end of a sequence
-// // as we don't want to push any extra rows since the DW_LNE_end_sequence
+// // as we don't want to push any extra rows since the
+// DW_LNE_end_sequence
// // will push a row itself!
// if (curr_state.end_sequence)
// {
@@ -1310,26 +1191,38 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset)
// line_increment = 0;
// }
//
-// uint32_t special_opcode = (line_increment >= prologue->line_base) ? ((line_increment - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
+// uint32_t special_opcode = (line_increment >=
+// prologue->line_base) ? ((line_increment -
+// prologue->line_base) + (prologue->line_range * addr_advance)
+// + prologue->opcode_base) : 256;
// if (special_opcode > 255)
// {
-// // Both the address and line won't fit in one special opcode
+// // Both the address and line won't fit in one special
+// opcode
// // check to see if just the line advance will?
-// uint32_t special_opcode_line = ((line_increment >= prologue->line_base) && (line_increment != 0)) ?
-// ((line_increment - prologue->line_base) + prologue->opcode_base) : 256;
+// uint32_t special_opcode_line = ((line_increment >=
+// prologue->line_base) && (line_increment != 0)) ?
+// ((line_increment - prologue->line_base) +
+// prologue->opcode_base) : 256;
//
//
// if (special_opcode_line > 255)
// {
-// // Nope, the line advance won't fit by itself, check the address increment by itself
+// // Nope, the line advance won't fit by itself, check
+// the address increment by itself
// uint32_t special_opcode_addr = addr_advance ?
-// ((0 - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
+// ((0 - prologue->line_base) +
+// (prologue->line_range * addr_advance) +
+// prologue->opcode_base) : 256;
//
// if (special_opcode_addr > 255)
// {
-// // Neither the address nor the line will fit in a
-// // special opcode, we must manually enter both then
-// // do a DW_LNS_copy to push a row (special opcode
+// // Neither the address nor the line will fit in
+// a
+// // special opcode, we must manually enter both
+// then
+// // do a DW_LNS_copy to push a row (special
+// opcode
// // automatically imply a new row is pushed)
// if (line_increment != 0)
// {
@@ -1349,9 +1242,12 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset)
// }
// else
// {
-// // The address increment alone will fit into a special opcode
-// // so modify our line change, then issue a special opcode
-// // for the address increment and it will push a row into the
+// // The address increment alone will fit into a
+// special opcode
+// // so modify our line change, then issue a
+// special opcode
+// // for the address increment and it will push a
+// row into the
// // line table
// if (line_increment != 0)
// {
@@ -1359,16 +1255,21 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset)
// debug_line_data.Append32_as_SLEB128(line_increment);
// }
//
-// // Advance of line and address will fit into a single byte special opcode
-// // and this will also push a row onto the line table
+// // Advance of line and address will fit into a
+// single byte special opcode
+// // and this will also push a row onto the line
+// table
// debug_line_data.Append8(special_opcode_addr);
// }
// }
// else
// {
-// // The line change alone will fit into a special opcode
-// // so modify our address increment first, then issue a
-// // special opcode for the line change and it will push
+// // The line change alone will fit into a special
+// opcode
+// // so modify our address increment first, then issue
+// a
+// // special opcode for the line change and it will
+// push
// // a row into the line table
// if (addr_advance > 0)
// {
@@ -1376,14 +1277,16 @@ DWARFDebugLine::State::Finalize(dw_offset_t offset)
// debug_line_data.Append32_as_ULEB128(addr_advance);
// }
//
-// // Advance of line and address will fit into a single byte special opcode
+// // Advance of line and address will fit into a
+// single byte special opcode
// // and this will also push a row onto the line table
// debug_line_data.Append8(special_opcode_line);
// }
// }
// else
// {
-// // Advance of line and address will fit into a single byte special opcode
+// // Advance of line and address will fit into a single
+// byte special opcode
// // and this will also push a row onto the line table
// debug_line_data.Append8(special_opcode);
// }
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
index 9f2219b01812..ea02cfed6e01 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
@@ -11,8 +11,8 @@
#define SymbolFileDWARF_DWARFDebugLine_h_
#include <map>
-#include <vector>
#include <string>
+#include <vector>
#include "lldb/lldb-private.h"
@@ -24,199 +24,219 @@ class SymbolFileDWARF;
//----------------------------------------------------------------------
// DWARFDebugLine
//----------------------------------------------------------------------
-class DWARFDebugLine
-{
+class DWARFDebugLine {
public:
- //------------------------------------------------------------------
- // FileNameEntry
- //------------------------------------------------------------------
- struct FileNameEntry
- {
- FileNameEntry() :
- name(nullptr),
- dir_idx(0),
- mod_time(0),
- length(0)
- {
- }
-
- const char* name;
- dw_sleb128_t dir_idx;
- dw_sleb128_t mod_time;
- dw_sleb128_t length;
-
- };
-
- //------------------------------------------------------------------
- // Prologue
- //------------------------------------------------------------------
- struct Prologue
- {
-
- Prologue() :
- total_length(0),
- version(0),
- prologue_length(0),
- min_inst_length(0),
- default_is_stmt(0),
- line_base(0),
- line_range(0),
- opcode_base(0),
- standard_opcode_lengths(),
- include_directories(),
- file_names()
- {
- }
-
- typedef std::shared_ptr<Prologue> shared_ptr;
-
- uint32_t total_length; // The size in bytes of the statement information for this compilation unit (not including the total_length field itself).
- uint16_t version; // Version identifier for the statement information format.
- 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.
- uint8_t min_inst_length;// The size in bytes of the smallest target machine instruction. Statement program opcodes that alter the address register first multiply their operands by this value.
- uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum number of individual operations that may be encoded in an instruction.
- uint8_t default_is_stmt;// The initial value of theis_stmtregister.
- int8_t line_base; // This parameter affects the meaning of the special opcodes. See below.
- uint8_t line_range; // This parameter affects the meaning of the special opcodes. See below.
- uint8_t opcode_base; // The number assigned to the first special opcode.
- std::vector<uint8_t> standard_opcode_lengths;
- std::vector<const char *> include_directories;
- std::vector<FileNameEntry> file_names;
-
- int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; }
- bool IsValid() const;
-// void Append(BinaryStreamBuf& buff) const;
- void Dump (lldb_private::Log *log);
- void Clear()
- {
- total_length = version = prologue_length = min_inst_length = line_base = line_range = opcode_base = 0;
- line_base = 0;
- standard_opcode_lengths.clear();
- include_directories.clear();
- file_names.clear();
- }
- bool GetFile(uint32_t file_idx, const char *comp_dir, lldb_private::FileSpec &file) const;
-
- };
-
- // Standard .debug_line state machine structure
- struct Row
- {
- typedef std::vector<Row> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- Row(bool default_is_stmt = false);
- virtual ~Row() {}
- void PostAppend ();
- void Reset(bool default_is_stmt);
- void Dump(lldb_private::Log *log) const;
- static void Insert(Row::collection& state_coll, const Row& state);
- static void Dump(lldb_private::Log *log, const Row::collection& state_coll);
-
- dw_addr_t address; // The program-counter value corresponding to a machine instruction generated by the compiler.
- uint32_t line; // An unsigned integer indicating a source line number. Lines are numbered beginning at 1. The compiler may emit the value 0 in cases where an instruction cannot be attributed to any source line.
- uint16_t column; // An unsigned integer indicating a column number within a source line. Columns are numbered beginning at 1. The value 0 is reserved to indicate that a statement begins at the 'left edge' of the line.
- uint16_t file; // An unsigned integer indicating the identity of the source file corresponding to a machine instruction.
- uint8_t is_stmt:1, // A boolean indicating that the current instruction is the beginning of a statement.
- basic_block:1, // A boolean indicating that the current instruction is the beginning of a basic block.
- end_sequence:1, // A boolean indicating that the current address is that of the first byte after the end of a sequence of target machine instructions.
- prologue_end:1, // A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an entry breakpoint of a function.
- epilogue_begin:1;// A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an exit breakpoint of a function.
- uint32_t isa; // An unsigned integer whose value encodes the applicable instruction set architecture for the current instruction.
- };
-
-
- //------------------------------------------------------------------
- // LineTable
- //------------------------------------------------------------------
- struct LineTable
- {
- typedef std::shared_ptr<LineTable> shared_ptr;
-
- LineTable() :
- prologue(),
- rows()
- {
- }
-
- void AppendRow(const DWARFDebugLine::Row& state);
- void Clear()
- {
- prologue.reset();
- rows.clear();
- }
-
- uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
- void Dump(lldb_private::Log *log) const;
-
- Prologue::shared_ptr prologue;
- Row::collection rows;
- };
-
- //------------------------------------------------------------------
- // State
- //------------------------------------------------------------------
- struct State : public Row
- {
- typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData);
-
- // Special row codes used when calling the callback
- enum
- {
- StartParsingLineTable = 0,
- DoneParsingLineTable = -1
- };
-
- State (Prologue::shared_ptr& prologue_sp,
- lldb_private::Log *log,
- Callback callback,
- void* userData);
-
- void
- AppendRowToMatrix (dw_offset_t offset);
-
- void
- Finalize (dw_offset_t offset);
-
- void
- Reset ();
-
- Prologue::shared_ptr prologue;
- lldb_private::Log *log;
- Callback callback; // Callback function that gets called each time an entry is to be added to the matrix
- void* callbackUserData;
- int row; // The row number that starts at zero for the prologue, and increases for each row added to the matrix
- private:
- DISALLOW_COPY_AND_ASSIGN (State);
- };
-
- static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0); // If line_offset is invalid, dump everything
- static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET); // If line_offset is invalid, dump everything
- static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DWARFDataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files);
- static bool ParsePrologue(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue);
- static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData);
- static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, const dw_offset_t line_offset);
- static dw_offset_t DumpStatementOpcodes(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, 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);
- static void Parse(const lldb_private::DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
-// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data);
-
- DWARFDebugLine() :
- m_lineTableMap()
- {
+ //------------------------------------------------------------------
+ // FileNameEntry
+ //------------------------------------------------------------------
+ struct FileNameEntry {
+ FileNameEntry() : name(nullptr), dir_idx(0), mod_time(0), length(0) {}
+
+ const char *name;
+ dw_sleb128_t dir_idx;
+ dw_sleb128_t mod_time;
+ dw_sleb128_t length;
+ };
+
+ //------------------------------------------------------------------
+ // Prologue
+ //------------------------------------------------------------------
+ struct Prologue {
+
+ Prologue()
+ : total_length(0), version(0), prologue_length(0), min_inst_length(0),
+ default_is_stmt(0), line_base(0), line_range(0), opcode_base(0),
+ standard_opcode_lengths(), include_directories(), file_names() {}
+
+ typedef std::shared_ptr<Prologue> shared_ptr;
+
+ uint32_t total_length; // The size in bytes of the statement information for
+ // this compilation unit (not including the
+ // total_length field itself).
+ uint16_t
+ version; // Version identifier for the statement information format.
+ 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.
+ uint8_t min_inst_length; // The size in bytes of the smallest target machine
+ // instruction. Statement program opcodes that
+ // alter the address register first multiply their
+ // operands by this value.
+ uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum
+ // number of individual
+ // operations that may be
+ // encoded in an instruction.
+ uint8_t default_is_stmt; // The initial value of theis_stmtregister.
+ int8_t line_base; // This parameter affects the meaning of the special
+ // opcodes. See below.
+ uint8_t line_range; // This parameter affects the meaning of the special
+ // opcodes. See below.
+ uint8_t opcode_base; // The number assigned to the first special opcode.
+ std::vector<uint8_t> standard_opcode_lengths;
+ std::vector<const char *> include_directories;
+ std::vector<FileNameEntry> file_names;
+
+ int32_t MaxLineIncrementForSpecialOpcode() const {
+ return line_base + (int8_t)line_range - 1;
+ }
+ bool IsValid() const;
+ // void Append(BinaryStreamBuf& buff) const;
+ void Dump(lldb_private::Log *log);
+ void Clear() {
+ total_length = version = prologue_length = min_inst_length = line_base =
+ line_range = opcode_base = 0;
+ line_base = 0;
+ standard_opcode_lengths.clear();
+ include_directories.clear();
+ file_names.clear();
+ }
+ bool GetFile(uint32_t file_idx, const char *comp_dir,
+ lldb_private::FileSpec &file) const;
+ };
+
+ // Standard .debug_line state machine structure
+ struct Row {
+ typedef std::vector<Row> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ Row(bool default_is_stmt = false);
+ virtual ~Row() {}
+ void PostAppend();
+ void Reset(bool default_is_stmt);
+ void Dump(lldb_private::Log *log) const;
+ static void Insert(Row::collection &state_coll, const Row &state);
+ static void Dump(lldb_private::Log *log, const Row::collection &state_coll);
+
+ dw_addr_t address; // The program-counter value corresponding to a machine
+ // instruction generated by the compiler.
+ uint32_t line; // An unsigned integer indicating a source line number. Lines
+ // are numbered beginning at 1. The compiler may emit the
+ // value 0 in cases where an instruction cannot be attributed
+ // to any source line.
+ uint16_t column; // An unsigned integer indicating a column number within a
+ // source line. Columns are numbered beginning at 1. The
+ // value 0 is reserved to indicate that a statement begins
+ // at the 'left edge' of the line.
+ uint16_t file; // An unsigned integer indicating the identity of the source
+ // file corresponding to a machine instruction.
+ uint8_t is_stmt : 1, // A boolean indicating that the current instruction is
+ // the beginning of a statement.
+ basic_block : 1, // A boolean indicating that the current instruction is
+ // the beginning of a basic block.
+ end_sequence : 1, // A boolean indicating that the current address is
+ // that of the first byte after the end of a sequence
+ // of target machine instructions.
+ prologue_end : 1, // A boolean indicating that the current address is
+ // one (of possibly many) where execution should be
+ // suspended for an entry breakpoint of a function.
+ epilogue_begin : 1; // A boolean indicating that the current address is
+ // one (of possibly many) where execution should be
+ // suspended for an exit breakpoint of a function.
+ uint32_t isa; // An unsigned integer whose value encodes the applicable
+ // instruction set architecture for the current instruction.
+ };
+
+ //------------------------------------------------------------------
+ // LineTable
+ //------------------------------------------------------------------
+ struct LineTable {
+ typedef std::shared_ptr<LineTable> shared_ptr;
+
+ LineTable() : prologue(), rows() {}
+
+ void AppendRow(const DWARFDebugLine::Row &state);
+ void Clear() {
+ prologue.reset();
+ rows.clear();
}
- void Parse(const lldb_private::DWARFDataExtractor& debug_line_data);
- void ParseIfNeeded(const lldb_private::DWARFDataExtractor& debug_line_data);
- LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
+ uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
+ void Dump(lldb_private::Log *log) const;
+
+ Prologue::shared_ptr prologue;
+ Row::collection rows;
+ };
+
+ //------------------------------------------------------------------
+ // State
+ //------------------------------------------------------------------
+ struct State : public Row {
+ typedef void (*Callback)(dw_offset_t offset, const State &state,
+ void *userData);
+
+ // Special row codes used when calling the callback
+ enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 };
+
+ State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log,
+ Callback callback, void *userData);
+
+ void AppendRowToMatrix(dw_offset_t offset);
+
+ void Finalize(dw_offset_t offset);
+
+ void Reset();
+
+ Prologue::shared_ptr prologue;
+ lldb_private::Log *log;
+ Callback callback; // Callback function that gets called each time an entry
+ // is to be added to the matrix
+ void *callbackUserData;
+ int row; // The row number that starts at zero for the prologue, and
+ // increases for each row added to the matrix
+ private:
+ DISALLOW_COPY_AND_ASSIGN(State);
+ };
+
+ static bool DumpOpcodes(
+ lldb_private::Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t line_offset = DW_INVALID_OFFSET,
+ uint32_t dump_flags = 0); // If line_offset is invalid, dump everything
+ static bool DumpLineTableRows(
+ lldb_private::Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t line_offset =
+ DW_INVALID_OFFSET); // If line_offset is invalid, dump everything
+ static bool
+ ParseSupportFiles(const lldb::ModuleSP &module_sp,
+ const lldb_private::DWARFDataExtractor &debug_line_data,
+ const char *cu_comp_dir, dw_offset_t stmt_list,
+ lldb_private::FileSpecList &support_files);
+ static bool
+ ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr, Prologue *prologue);
+ static bool
+ ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr, State::Callback callback,
+ void *userData);
+ static dw_offset_t
+ DumpStatementTable(lldb_private::Log *log,
+ const lldb_private::DWARFDataExtractor &debug_line_data,
+ const dw_offset_t line_offset);
+ static dw_offset_t
+ DumpStatementOpcodes(lldb_private::Log *log,
+ const lldb_private::DWARFDataExtractor &debug_line_data,
+ 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);
+ static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
+ DWARFDebugLine::State::Callback callback, void *userData);
+ // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
+ // const DWARFDebugLine::Row::collection& state_coll, const uint32_t
+ // addr_size, BinaryStreamBuf &debug_line_data);
+
+ DWARFDebugLine() : m_lineTableMap() {}
+
+ void Parse(const lldb_private::DWARFDataExtractor &debug_line_data);
+ void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data);
+ LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
protected:
- typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
- typedef LineTableMap::iterator LineTableIter;
- typedef LineTableMap::const_iterator LineTableConstIter;
+ typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
+ typedef LineTableMap::iterator LineTableIter;
+ typedef LineTableMap::const_iterator LineTableConstIter;
- LineTableMap m_lineTableMap;
+ LineTableMap m_lineTableMap;
};
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
+#endif // SymbolFileDWARF_DWARFDebugLine_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
index 0e2aaa47e8c9..d56463039a19 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
@@ -17,32 +17,23 @@
using namespace lldb_private;
using namespace std;
-DWARFDebugMacinfo::DWARFDebugMacinfo()
-{
-}
+DWARFDebugMacinfo::DWARFDebugMacinfo() {}
-DWARFDebugMacinfo::~DWARFDebugMacinfo()
-{
-}
+DWARFDebugMacinfo::~DWARFDebugMacinfo() {}
-void
-DWARFDebugMacinfo::Dump(Stream *s, const DWARFDataExtractor& macinfo_data, lldb::offset_t offset)
-{
- DWARFDebugMacinfoEntry maninfo_entry;
- if (macinfo_data.GetByteSize() == 0)
- {
- s->PutCString("< EMPTY >\n");
- return;
- }
- if (offset == LLDB_INVALID_OFFSET)
- {
- offset = 0;
- while (maninfo_entry.Extract(macinfo_data, &offset))
- maninfo_entry.Dump(s);
- }
- else
- {
- if (maninfo_entry.Extract(macinfo_data, &offset))
- maninfo_entry.Dump(s);
- }
+void DWARFDebugMacinfo::Dump(Stream *s, const DWARFDataExtractor &macinfo_data,
+ lldb::offset_t offset) {
+ DWARFDebugMacinfoEntry maninfo_entry;
+ if (macinfo_data.GetByteSize() == 0) {
+ s->PutCString("< EMPTY >\n");
+ return;
+ }
+ if (offset == LLDB_INVALID_OFFSET) {
+ offset = 0;
+ while (maninfo_entry.Extract(macinfo_data, &offset))
+ maninfo_entry.Dump(s);
+ } else {
+ if (maninfo_entry.Extract(macinfo_data, &offset))
+ maninfo_entry.Dump(s);
+ }
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
index 077718cf7db2..ec9dc85669c4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
@@ -12,18 +12,15 @@
#include "SymbolFileDWARF.h"
-class DWARFDebugMacinfo
-{
+class DWARFDebugMacinfo {
public:
- DWARFDebugMacinfo();
+ DWARFDebugMacinfo();
- ~DWARFDebugMacinfo();
+ ~DWARFDebugMacinfo();
- static void
- Dump (lldb_private::Stream *s,
- const lldb_private::DWARFDataExtractor& macinfo_data,
- lldb::offset_t offset = LLDB_INVALID_OFFSET);
+ static void Dump(lldb_private::Stream *s,
+ const lldb_private::DWARFDataExtractor &macinfo_data,
+ lldb::offset_t offset = LLDB_INVALID_OFFSET);
};
-
-#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
+#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
index 4a176bb8aad4..45498590236f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
@@ -14,119 +14,98 @@
using namespace lldb_private;
using namespace std;
-DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry() :
- m_type_code(0),
- m_line(0),
- m_op2()
-{
- m_op2.cstr = NULL;
+DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry()
+ : m_type_code(0), m_line(0), m_op2() {
+ m_op2.cstr = NULL;
}
-DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry()
-{
+DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry() {}
+
+const char *DWARFDebugMacinfoEntry::GetCString() const {
+ switch (m_type_code) {
+ case 0:
+ case DW_MACINFO_start_file:
+ case DW_MACINFO_end_file:
+ return NULL;
+ default:
+ break;
+ }
+ return m_op2.cstr;
}
-const char*
-DWARFDebugMacinfoEntry::GetCString() const
-{
- switch (m_type_code)
- {
- case 0:
- case DW_MACINFO_start_file:
- case DW_MACINFO_end_file:
- return NULL;
- default:
- break;
- }
- return m_op2.cstr;
-}
+void DWARFDebugMacinfoEntry::Dump(Stream *s) const {
+ if (m_type_code) {
+ s->PutCString(DW_MACINFO_value_to_name(m_type_code));
+ switch (m_type_code) {
+ case DW_MACINFO_define:
+ s->Printf(" line:%u #define %s\n", (uint32_t)m_line, m_op2.cstr);
+ break;
+ case DW_MACINFO_undef:
+ s->Printf(" line:%u #undef %s\n", (uint32_t)m_line, m_op2.cstr);
+ break;
-void
-DWARFDebugMacinfoEntry::Dump(Stream *s) const
-{
- if (m_type_code)
- {
- s->PutCString(DW_MACINFO_value_to_name(m_type_code));
-
- switch (m_type_code)
- {
- case DW_MACINFO_define:
- s->Printf(" line:%u #define %s\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- case DW_MACINFO_undef:
- s->Printf(" line:%u #undef %s\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- default:
- s->Printf(" line:%u str: '%s'\n", (uint32_t)m_line, m_op2.cstr);
- break;
+ default:
+ s->Printf(" line:%u str: '%s'\n", (uint32_t)m_line, m_op2.cstr);
+ break;
- case DW_MACINFO_start_file:
- s->Printf(" line:%u file index: '%u'\n", (uint32_t)m_line, (uint32_t)m_op2.file_idx);
- break;
+ case DW_MACINFO_start_file:
+ s->Printf(" line:%u file index: '%u'\n", (uint32_t)m_line,
+ (uint32_t)m_op2.file_idx);
+ break;
- case DW_MACINFO_end_file:
- break;
- }
- }
- else
- {
- s->PutCString(" END\n");
+ case DW_MACINFO_end_file:
+ break;
}
+ } else {
+ s->PutCString(" END\n");
+ }
}
+bool DWARFDebugMacinfoEntry::Extract(const DWARFDataExtractor &mac_info_data,
+ lldb::offset_t *offset_ptr) {
+ if (mac_info_data.ValidOffset(*offset_ptr)) {
+ m_type_code = mac_info_data.GetU8(offset_ptr);
+
+ switch (m_type_code) {
+
+ case DW_MACINFO_define:
+ case DW_MACINFO_undef:
+ // 2 operands:
+ // Arg 1: operand encodes the line number of the source line on which
+ // the relevant defining or undefining pre-processor directives
+ // appeared.
+ m_line = mac_info_data.GetULEB128(offset_ptr);
+ // Arg 2: define string
+ m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
+ break;
-bool
-DWARFDebugMacinfoEntry::Extract(const DWARFDataExtractor& mac_info_data, lldb::offset_t* offset_ptr)
-{
- if (mac_info_data.ValidOffset(*offset_ptr))
- {
- m_type_code = mac_info_data.GetU8(offset_ptr);
-
- switch (m_type_code)
- {
-
- case DW_MACINFO_define:
- case DW_MACINFO_undef:
- // 2 operands:
- // Arg 1: operand encodes the line number of the source line on which
- // the relevant defining or undefining pre-processor directives
- // appeared.
- m_line = mac_info_data.GetULEB128(offset_ptr);
- // Arg 2: define string
- m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
- break;
-
- case DW_MACINFO_start_file:
- // 2 operands:
- // Op 1: line number of the source line on which the inclusion
- // pre-processor directive occurred.
- m_line = mac_info_data.GetULEB128(offset_ptr);
- // Op 2: a source file name index to a file number in the statement
- // information table for the relevant compilation unit.
- m_op2.file_idx = mac_info_data.GetULEB128(offset_ptr);
- break;
-
- case 0: // End of list
- case DW_MACINFO_end_file:
- // No operands
- m_line = DW_INVALID_OFFSET;
- m_op2.cstr = NULL;
- break;
- default:
- // Vendor specific entries always have a ULEB128 and a string
- m_line = mac_info_data.GetULEB128(offset_ptr);
- m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
- break;
- }
- return true;
+ case DW_MACINFO_start_file:
+ // 2 operands:
+ // Op 1: line number of the source line on which the inclusion
+ // pre-processor directive occurred.
+ m_line = mac_info_data.GetULEB128(offset_ptr);
+ // Op 2: a source file name index to a file number in the statement
+ // information table for the relevant compilation unit.
+ m_op2.file_idx = mac_info_data.GetULEB128(offset_ptr);
+ break;
+
+ case 0: // End of list
+ case DW_MACINFO_end_file:
+ // No operands
+ m_line = DW_INVALID_OFFSET;
+ m_op2.cstr = NULL;
+ break;
+ default:
+ // Vendor specific entries always have a ULEB128 and a string
+ m_line = mac_info_data.GetULEB128(offset_ptr);
+ m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
+ break;
}
- else
- m_type_code = 0;
+ return true;
+ } else
+ m_type_code = 0;
- return false;
+ return false;
}
-
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
index 72318d86e1ca..96829c2fc09b 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
@@ -12,46 +12,31 @@
#include "SymbolFileDWARF.h"
-class DWARFDebugMacinfoEntry
-{
+class DWARFDebugMacinfoEntry {
public:
- DWARFDebugMacinfoEntry();
+ DWARFDebugMacinfoEntry();
- ~DWARFDebugMacinfoEntry();
+ ~DWARFDebugMacinfoEntry();
- uint8_t
- TypeCode() const
- {
- return m_type_code;
- }
+ uint8_t TypeCode() const { return m_type_code; }
- uint8_t
- GetLineNumber() const
- {
- return m_line;
- }
+ uint8_t GetLineNumber() const { return m_line; }
- void
- Dump(lldb_private::Stream *s) const;
+ void Dump(lldb_private::Stream *s) const;
- const char*
- GetCString() const;
+ const char *GetCString() const;
- bool
- Extract(const lldb_private::DWARFDataExtractor& mac_info_data,
- lldb::offset_t* offset_ptr);
+ bool Extract(const lldb_private::DWARFDataExtractor &mac_info_data,
+ lldb::offset_t *offset_ptr);
protected:
-
private:
- uint8_t m_type_code;
- dw_uleb128_t m_line;
- union
- {
- dw_uleb128_t file_idx;
- const char* cstr;
- } m_op2;
+ uint8_t m_type_code;
+ dw_uleb128_t m_line;
+ union {
+ dw_uleb128_t file_idx;
+ const char *cstr;
+ } m_op2;
};
-
-#endif // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
+#endif // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
index 75c812e6e79d..1c31d1c42598 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
@@ -17,112 +17,111 @@
using namespace lldb_private;
DWARFDebugMacroHeader
-DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset)
-{
- DWARFDebugMacroHeader header;
+DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
+ lldb::offset_t *offset) {
+ DWARFDebugMacroHeader header;
- // Skip over the version field in header.
- header.m_version = debug_macro_data.GetU16(offset);
+ // Skip over the version field in header.
+ 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;
+ uint8_t flags = debug_macro_data.GetU8(offset);
+ header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false;
- if (flags & DEBUG_LINE_OFFSET_MASK)
- {
- if (header.m_offset_is_64_bit)
- header.m_debug_line_offset = debug_macro_data.GetU64(offset);
- else
- header.m_debug_line_offset = debug_macro_data.GetU32(offset);
- }
+ if (flags & DEBUG_LINE_OFFSET_MASK) {
+ if (header.m_offset_is_64_bit)
+ header.m_debug_line_offset = debug_macro_data.GetU64(offset);
+ else
+ header.m_debug_line_offset = debug_macro_data.GetU32(offset);
+ }
- // Skip over the operands table if it is present.
- if (flags & OPCODE_OPERANDS_TABLE_MASK)
- SkipOperandTable(debug_macro_data, offset);
+ // Skip over the operands table if it is present.
+ if (flags & OPCODE_OPERANDS_TABLE_MASK)
+ SkipOperandTable(debug_macro_data, offset);
- return header;
+ return header;
}
-void
-DWARFDebugMacroHeader::SkipOperandTable(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset)
-{
- uint8_t entry_count = debug_macro_data.GetU8(offset);
- for (uint8_t i = 0; i < entry_count; i++)
- {
- // Skip over the opcode number.
- debug_macro_data.GetU8(offset);
+void DWARFDebugMacroHeader::SkipOperandTable(
+ const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
+ uint8_t entry_count = debug_macro_data.GetU8(offset);
+ for (uint8_t i = 0; i < entry_count; i++) {
+ // Skip over the opcode number.
+ debug_macro_data.GetU8(offset);
- uint64_t operand_count = debug_macro_data.GetULEB128(offset);
+ uint64_t operand_count = debug_macro_data.GetULEB128(offset);
- for (uint64_t j = 0; j < operand_count; j++)
- {
- // Skip over the operand form
- debug_macro_data.GetU8(offset);
- }
+ for (uint64_t j = 0; j < operand_count; j++) {
+ // Skip over the operand form
+ debug_macro_data.GetU8(offset);
}
+ }
}
-void
-DWARFDebugMacroEntry::ReadMacroEntries(const DWARFDataExtractor &debug_macro_data,
- const DWARFDataExtractor &debug_str_data,
- const bool offset_is_64_bit,
- lldb::offset_t *offset,
- SymbolFileDWARF *sym_file_dwarf,
- DebugMacrosSP &debug_macros_sp)
-{
- llvm::dwarf::MacroEntryType type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
- while (type != 0)
- {
- lldb::offset_t new_offset = 0, str_offset = 0;
- uint32_t line = 0;
- const char *macro_str = nullptr;
- uint32_t debug_line_file_idx = 0;
+void DWARFDebugMacroEntry::ReadMacroEntries(
+ const DWARFDataExtractor &debug_macro_data,
+ const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit,
+ lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf,
+ DebugMacrosSP &debug_macros_sp) {
+ llvm::dwarf::MacroEntryType type =
+ static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
+ while (type != 0) {
+ lldb::offset_t new_offset = 0, str_offset = 0;
+ uint32_t line = 0;
+ const char *macro_str = nullptr;
+ uint32_t debug_line_file_idx = 0;
- switch (type)
- {
- case DW_MACRO_define:
- case DW_MACRO_undef:
- line = debug_macro_data.GetULEB128(offset);
- macro_str = debug_macro_data.GetCStr(offset);
- if (type == DW_MACRO_define)
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str));
- else
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str));
- break;
- case DW_MACRO_define_indirect:
- case DW_MACRO_undef_indirect:
- line = debug_macro_data.GetULEB128(offset);
- if (offset_is_64_bit)
- str_offset = debug_macro_data.GetU64(offset);
- else
- str_offset = debug_macro_data.GetU32(offset);
- macro_str = debug_str_data.GetCStr(&str_offset);
- if (type == DW_MACRO_define_indirect)
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str));
- else
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str));
- break;
- case DW_MACRO_start_file:
- line = debug_macro_data.GetULEB128(offset);
- debug_line_file_idx = debug_macro_data.GetULEB128(offset);
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
- break;
- case DW_MACRO_end_file:
- // This operation has no operands.
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
- break;
- case DW_MACRO_transparent_include:
- if (offset_is_64_bit)
- new_offset = debug_macro_data.GetU64(offset);
- else
- new_offset = debug_macro_data.GetU32(offset);
- debug_macros_sp->AddMacroEntry(
- DebugMacroEntry::CreateIndirectEntry(sym_file_dwarf->ParseDebugMacros(&new_offset)));
- break;
- default:
- // TODO: Add support for other standard operations.
- // TODO: Provide mechanism to hook handling of non-standard/extension operands.
- return;
- }
- type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
+ switch (type) {
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
+ line = debug_macro_data.GetULEB128(offset);
+ macro_str = debug_macro_data.GetCStr(offset);
+ if (type == DW_MACRO_define)
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateDefineEntry(line, macro_str));
+ else
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateUndefEntry(line, macro_str));
+ break;
+ case DW_MACRO_define_strp:
+ case DW_MACRO_undef_strp:
+ line = debug_macro_data.GetULEB128(offset);
+ if (offset_is_64_bit)
+ str_offset = debug_macro_data.GetU64(offset);
+ else
+ str_offset = debug_macro_data.GetU32(offset);
+ macro_str = debug_str_data.GetCStr(&str_offset);
+ if (type == DW_MACRO_define_strp)
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateDefineEntry(line, macro_str));
+ else
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateUndefEntry(line, macro_str));
+ break;
+ case DW_MACRO_start_file:
+ line = debug_macro_data.GetULEB128(offset);
+ debug_line_file_idx = debug_macro_data.GetULEB128(offset);
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
+ break;
+ case DW_MACRO_end_file:
+ // This operation has no operands.
+ debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
+ break;
+ case DW_MACRO_import:
+ if (offset_is_64_bit)
+ new_offset = debug_macro_data.GetU64(offset);
+ else
+ new_offset = debug_macro_data.GetU32(offset);
+ debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
+ sym_file_dwarf->ParseDebugMacros(&new_offset)));
+ break;
+ default:
+ // TODO: Add support for other standard operations.
+ // TODO: Provide mechanism to hook handling of non-standard/extension
+ // operands.
+ return;
}
+ type = static_cast<llvm::dwarf::MacroEntryType>(
+ debug_macro_data.GetU8(offset));
+ }
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
index c60b9749b005..021b434cd457 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
@@ -1,4 +1,5 @@
-//===-- DWARFDebugMacro.h ----------------------------------------*- C++ -*-===//
+//===-- DWARFDebugMacro.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,12 +13,11 @@
#include <map>
-#include "lldb/lldb-types.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Symbol/DebugMacros.h"
+#include "lldb/lldb-types.h"
-namespace lldb_private
-{
+namespace lldb_private {
class DWARFDataExtractor;
@@ -25,44 +25,38 @@ class DWARFDataExtractor;
class SymbolFileDWARF;
-class DWARFDebugMacroHeader
-{
+class DWARFDebugMacroHeader {
public:
- enum HeaderFlagMask
- {
- OFFSET_SIZE_MASK = 0x1,
- DEBUG_LINE_OFFSET_MASK = 0x2,
- OPCODE_OPERANDS_TABLE_MASK = 0x4
- };
+ enum HeaderFlagMask {
+ OFFSET_SIZE_MASK = 0x1,
+ DEBUG_LINE_OFFSET_MASK = 0x2,
+ OPCODE_OPERANDS_TABLE_MASK = 0x4
+ };
- static DWARFDebugMacroHeader
- ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset);
+ static DWARFDebugMacroHeader
+ ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data,
+ lldb::offset_t *offset);
- bool
- OffsetIs64Bit() const
- {
- return m_offset_is_64_bit;
- }
+ bool OffsetIs64Bit() const { return m_offset_is_64_bit; }
private:
- static void
- SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset);
+ static void
+ SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data,
+ lldb::offset_t *offset);
- uint16_t m_version;
- bool m_offset_is_64_bit;
- uint64_t m_debug_line_offset;
+ uint16_t m_version;
+ bool m_offset_is_64_bit;
+ uint64_t m_debug_line_offset;
};
-class DWARFDebugMacroEntry
-{
+class DWARFDebugMacroEntry {
public:
- static void
- ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data,
- const lldb_private::DWARFDataExtractor &debug_str_data,
- const bool offset_is_64_bit,
- lldb::offset_t *sect_offset,
- SymbolFileDWARF *sym_file_dwarf,
- lldb_private::DebugMacrosSP &debug_macros_sp);
+ static void
+ ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data,
+ const lldb_private::DWARFDataExtractor &debug_str_data,
+ const bool offset_is_64_bit, lldb::offset_t *sect_offset,
+ SymbolFileDWARF *sym_file_dwarf,
+ lldb_private::DebugMacrosSP &debug_macros_sp);
};
#endif // SymbolFileDWARF_DWARFDebugMacro_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
index 547bd0cd1a5a..d4281bac79a1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
@@ -12,268 +12,242 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
-#include "DWARFDebugInfo.h"
+#include "DWARFCompileUnit.h"
#include "DWARFDIECollection.h"
+#include "DWARFDebugInfo.h"
#include "DWARFFormValue.h"
-#include "DWARFCompileUnit.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
-
using namespace lldb;
using namespace lldb_private;
-DWARFDebugPubnames::DWARFDebugPubnames() :
- m_sets()
-{
-}
-
-bool
-DWARFDebugPubnames::Extract(const DWARFDataExtractor& data)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
- (uint64_t)data.GetByteSize());
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
- if (log)
- log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", (uint64_t)data.GetByteSize());
-
- if (data.ValidOffset(0))
- {
- lldb::offset_t offset = 0;
-
- DWARFDebugPubnamesSet set;
- while (data.ValidOffset(offset))
- {
- if (set.Extract(data, &offset))
- {
- m_sets.push_back(set);
- offset = set.GetOffsetOfNextEntry();
- }
- else
- break;
- }
- if (log)
- Dump (log);
- return true;
+DWARFDebugPubnames::DWARFDebugPubnames() : m_sets() {}
+
+bool DWARFDebugPubnames::Extract(const DWARFDataExtractor &data) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
+ (uint64_t)data.GetByteSize());
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
+ if (log)
+ log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
+ (uint64_t)data.GetByteSize());
+
+ if (data.ValidOffset(0)) {
+ lldb::offset_t offset = 0;
+
+ DWARFDebugPubnamesSet set;
+ while (data.ValidOffset(offset)) {
+ if (set.Extract(data, &offset)) {
+ m_sets.push_back(set);
+ offset = set.GetOffsetOfNextEntry();
+ } else
+ break;
}
- return false;
-}
-
-
-bool
-DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF* dwarf2Data)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "DWARFDebugPubnames::GeneratePubnames (data = %p)",
- static_cast<void*>(dwarf2Data));
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
if (log)
- log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)",
- static_cast<void*>(dwarf2Data));
-
- m_sets.clear();
- DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
- if (debug_info)
- {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
-
- DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
-
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(),
- cu->IsDWARF64());
-
- bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
-
- DWARFDIECollection dies;
- const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_subprogram, dies) +
- cu->AppendDIEsWithTag (DW_TAG_variable, dies);
-
- dw_offset_t cu_offset = cu->GetOffset();
- DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset);
-
- size_t die_idx;
- for (die_idx = 0; die_idx < die_count; ++die_idx)
- {
- DWARFDIE die = dies.GetDIEAtIndex(die_idx);
- DWARFAttributes attributes;
- const char *name = NULL;
- const char *mangled = NULL;
- bool add_die = false;
- const size_t num_attributes = die.GetDIE()->GetAttributes(die.GetCU(), fixed_form_sizes, attributes);
- if (num_attributes > 0)
- {
- uint32_t i;
-
- dw_tag_t tag = die.Tag();
-
- for (i=0; i<num_attributes; ++i)
- {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- switch (attr)
- {
- case DW_AT_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- name = form_value.AsCString();
- break;
-
- case DW_AT_MIPS_linkage_name:
- case DW_AT_linkage_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- mangled = form_value.AsCString();
- break;
-
- case DW_AT_low_pc:
- case DW_AT_ranges:
- case DW_AT_entry_pc:
- if (tag == DW_TAG_subprogram)
- add_die = true;
- break;
-
- case DW_AT_location:
- if (tag == DW_TAG_variable)
- {
- DWARFDIE parent_die = die.GetParent();
- while ( parent_die )
- {
- switch (parent_die.Tag())
- {
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- case DW_TAG_inlined_subroutine:
- // Even if this is a function level static, we don't add it. We could theoretically
- // add these if we wanted to by introspecting into the DW_AT_location and seeing
- // if the location describes a hard coded address, but we don't want the performance
- // penalty of that right now.
- add_die = false;
- parent_die.Clear(); // Terminate the while loop.
- break;
-
- case DW_TAG_compile_unit:
- add_die = true;
- parent_die.Clear(); // Terminate the while loop.
- break;
-
- default:
- parent_die = parent_die.GetParent(); // Keep going in the while loop.
- break;
- }
- }
- }
- break;
- }
- }
- }
+ Dump(log);
+ return true;
+ }
+ return false;
+}
- if (add_die && (name || mangled))
- {
- pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), mangled ? mangled : name);
+bool DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF *dwarf2Data) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "DWARFDebugPubnames::GeneratePubnames (data = %p)",
+ static_cast<void *>(dwarf2Data));
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
+ if (log)
+ log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)",
+ static_cast<void *>(dwarf2Data));
+
+ m_sets.clear();
+ DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
+ if (debug_info) {
+ uint32_t cu_idx = 0;
+ const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+ for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+
+ DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(
+ cu->GetAddressByteSize(), cu->IsDWARF64());
+
+ bool clear_dies = cu->ExtractDIEsIfNeeded(false) > 1;
+
+ DWARFDIECollection dies;
+ const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_subprogram, dies) +
+ cu->AppendDIEsWithTag(DW_TAG_variable, dies);
+
+ dw_offset_t cu_offset = cu->GetOffset();
+ DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset,
+ cu->GetNextCompileUnitOffset() -
+ cu_offset);
+
+ size_t die_idx;
+ for (die_idx = 0; die_idx < die_count; ++die_idx) {
+ DWARFDIE die = dies.GetDIEAtIndex(die_idx);
+ DWARFAttributes attributes;
+ const char *name = NULL;
+ const char *mangled = NULL;
+ bool add_die = false;
+ const size_t num_attributes = die.GetDIE()->GetAttributes(
+ die.GetCU(), fixed_form_sizes, attributes);
+ if (num_attributes > 0) {
+ uint32_t i;
+
+ dw_tag_t tag = die.Tag();
+
+ for (i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ switch (attr) {
+ case DW_AT_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ mangled = form_value.AsCString();
+ break;
+
+ case DW_AT_low_pc:
+ case DW_AT_ranges:
+ case DW_AT_entry_pc:
+ if (tag == DW_TAG_subprogram)
+ add_die = true;
+ break;
+
+ case DW_AT_location:
+ if (tag == DW_TAG_variable) {
+ DWARFDIE parent_die = die.GetParent();
+ while (parent_die) {
+ switch (parent_die.Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block:
+ case DW_TAG_inlined_subroutine:
+ // Even if this is a function level static, we don't add it.
+ // We could theoretically
+ // add these if we wanted to by introspecting into the
+ // DW_AT_location and seeing
+ // if the location describes a hard coded address, but we
+ // don't want the performance
+ // penalty of that right now.
+ add_die = false;
+ parent_die.Clear(); // Terminate the while loop.
+ break;
+
+ case DW_TAG_compile_unit:
+ add_die = true;
+ parent_die.Clear(); // Terminate the while loop.
+ break;
+
+ default:
+ parent_die =
+ parent_die.GetParent(); // Keep going in the while loop.
+ break;
+ }
}
+ }
+ break;
}
+ }
+ }
- if (pubnames_set.NumDescriptors() > 0)
- {
- m_sets.push_back(pubnames_set);
- }
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- cu->ClearDIEs (true);
+ if (add_die && (name || mangled)) {
+ pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(),
+ mangled ? mangled : name);
}
- }
- if (m_sets.empty())
- return false;
- if (log)
- Dump (log);
- return true;
-}
+ }
-bool
-DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data)
-{
- m_sets.clear();
- DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
- if (debug_info)
- {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- DWARFDIECollection dies;
- const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_base_type, dies);
- dw_offset_t cu_offset = cu->GetOffset();
- DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset);
-
- size_t die_idx;
- for (die_idx = 0; die_idx < die_count; ++die_idx)
- {
- DWARFDIE die = dies.GetDIEAtIndex (die_idx);
- const char *name = die.GetName();
-
- if (name)
- pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name);
- }
+ if (pubnames_set.NumDescriptors() > 0) {
+ m_sets.push_back(pubnames_set);
+ }
- if (pubnames_set.NumDescriptors() > 0)
- {
- m_sets.push_back(pubnames_set);
- }
- }
+ // Keep memory down by clearing DIEs if this generate function
+ // caused them to be parsed
+ if (clear_dies)
+ cu->ClearDIEs(true);
}
- return !m_sets.empty();
+ }
+ if (m_sets.empty())
+ return false;
+ if (log)
+ Dump(log);
+ return true;
}
-void
-DWARFDebugPubnames::Dump(Log *s) const
-{
- if (m_sets.empty())
- s->PutCString("< EMPTY >\n");
- else
- {
- const_iterator pos;
- const_iterator end = m_sets.end();
-
- for (pos = m_sets.begin(); pos != end; ++pos)
- (*pos).Dump(s);
+bool DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data) {
+ m_sets.clear();
+ DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
+ if (debug_info) {
+ uint32_t cu_idx = 0;
+ const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+ for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ DWARFDIECollection dies;
+ const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_base_type, dies);
+ dw_offset_t cu_offset = cu->GetOffset();
+ DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset,
+ cu->GetNextCompileUnitOffset() -
+ cu_offset);
+
+ size_t die_idx;
+ for (die_idx = 0; die_idx < die_count; ++die_idx) {
+ DWARFDIE die = dies.GetDIEAtIndex(die_idx);
+ const char *name = die.GetName();
+
+ if (name)
+ pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name);
+ }
+
+ if (pubnames_set.NumDescriptors() > 0) {
+ m_sets.push_back(pubnames_set);
+ }
}
+ }
+ return !m_sets.empty();
}
-bool
-DWARFDebugPubnames::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const
-{
+void DWARFDebugPubnames::Dump(Log *s) const {
+ if (m_sets.empty())
+ s->PutCString("< EMPTY >\n");
+ else {
const_iterator pos;
const_iterator end = m_sets.end();
- die_offsets.clear();
-
for (pos = m_sets.begin(); pos != end; ++pos)
- {
- (*pos).Find(name, ignore_case, die_offsets);
- }
+ (*pos).Dump(s);
+ }
+}
+
+bool DWARFDebugPubnames::Find(const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offsets) const {
+ const_iterator pos;
+ const_iterator end = m_sets.end();
+
+ die_offsets.clear();
+
+ for (pos = m_sets.begin(); pos != end; ++pos) {
+ (*pos).Find(name, ignore_case, die_offsets);
+ }
- return !die_offsets.empty();
+ return !die_offsets.empty();
}
-bool
-DWARFDebugPubnames::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const
-{
- const_iterator pos;
- const_iterator end = m_sets.end();
+bool DWARFDebugPubnames::Find(const RegularExpression &regex,
+ std::vector<dw_offset_t> &die_offsets) const {
+ const_iterator pos;
+ const_iterator end = m_sets.end();
- die_offsets.clear();
+ die_offsets.clear();
- for (pos = m_sets.begin(); pos != end; ++pos)
- {
- (*pos).Find(regex, die_offsets);
- }
+ for (pos = m_sets.begin(); pos != end; ++pos) {
+ (*pos).Find(regex, die_offsets);
+ }
- return !die_offsets.empty();
+ return !die_offsets.empty();
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
index cacb1ea109bf..57dabade012c 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
@@ -16,23 +16,25 @@
#include "DWARFDebugPubnamesSet.h"
-class DWARFDebugPubnames
-{
+class DWARFDebugPubnames {
public:
- DWARFDebugPubnames();
- bool Extract(const lldb_private::DWARFDataExtractor& data);
- bool GeneratePubnames(SymbolFileDWARF* dwarf2Data);
- bool GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data);
-
- void Dump(lldb_private::Log *s) const;
- bool Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
- bool Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const;
+ DWARFDebugPubnames();
+ bool Extract(const lldb_private::DWARFDataExtractor &data);
+ bool GeneratePubnames(SymbolFileDWARF *dwarf2Data);
+ bool GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data);
+
+ void Dump(lldb_private::Log *s) const;
+ bool Find(const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offset_coll) const;
+ bool Find(const lldb_private::RegularExpression &regex,
+ std::vector<dw_offset_t> &die_offsets) const;
+
protected:
- typedef std::list<DWARFDebugPubnamesSet> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
+ typedef std::list<DWARFDebugPubnamesSet> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
- collection m_sets;
+ collection m_sets;
};
-#endif // SymbolFileDWARF_DWARFDebugPubnames_h_
+#endif // SymbolFileDWARF_DWARFDebugPubnames_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
index b7e1b27d1501..4518d65811b5 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
@@ -9,158 +9,138 @@
#include "DWARFDebugPubnamesSet.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/RegularExpression.h"
#include "SymbolFileDWARF.h"
using namespace lldb_private;
-DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() :
- m_offset(DW_INVALID_OFFSET),
- m_header(),
- m_descriptors(),
- m_name_to_descriptor_index()
-{
+DWARFDebugPubnamesSet::DWARFDebugPubnamesSet()
+ : m_offset(DW_INVALID_OFFSET), m_header(), m_descriptors(),
+ m_name_to_descriptor_index() {}
+
+DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset,
+ dw_offset_t cu_die_offset,
+ dw_offset_t cu_die_length)
+ : m_offset(debug_aranges_offset), m_header(), m_descriptors(),
+ m_name_to_descriptor_index() {
+ m_header.length =
+ 10; // set the length to only include the header right for now
+ m_header.version = 2; // The DWARF version number
+ m_header.die_offset = cu_die_offset; // compile unit .debug_info offset
+ m_header.die_length = cu_die_length; // compile unit .debug_info length
}
-DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) :
- m_offset(debug_aranges_offset),
- m_header(),
- m_descriptors(),
- m_name_to_descriptor_index()
-{
- m_header.length = 10; // set the length to only include the header right for now
- m_header.version = 2; // The DWARF version number
- m_header.die_offset = cu_die_offset;// compile unit .debug_info offset
- m_header.die_length = cu_die_length;// compile unit .debug_info length
-}
-
-void
-DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name)
-{
- if (name && name[0])
- {
- // Adjust our header length
- m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
- Descriptor pubnameDesc(cu_rel_offset, name);
- m_descriptors.push_back(pubnameDesc);
- }
+void DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset,
+ const char *name) {
+ if (name && name[0]) {
+ // Adjust our header length
+ m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
+ Descriptor pubnameDesc(cu_rel_offset, name);
+ m_descriptors.push_back(pubnameDesc);
+ }
}
-void
-DWARFDebugPubnamesSet::Clear()
-{
- m_offset = DW_INVALID_OFFSET;
- m_header.length = 10;
- m_header.version = 2;
- m_header.die_offset = DW_INVALID_OFFSET;
- m_header.die_length = 0;
- m_descriptors.clear();
+void DWARFDebugPubnamesSet::Clear() {
+ m_offset = DW_INVALID_OFFSET;
+ m_header.length = 10;
+ m_header.version = 2;
+ m_header.die_offset = DW_INVALID_OFFSET;
+ m_header.die_length = 0;
+ m_descriptors.clear();
}
-
//----------------------------------------------------------------------
// InitNameIndexes
//----------------------------------------------------------------------
-void
-DWARFDebugPubnamesSet::InitNameIndexes() const
-{
- // Create the name index vector to be able to quickly search by name
- const size_t count = m_descriptors.size();
- for (uint32_t idx = 0; idx < count; ++idx)
- {
- const char* name = m_descriptors[idx].name.c_str();
- if (name && name[0])
- m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx));
- }
+void DWARFDebugPubnamesSet::InitNameIndexes() const {
+ // Create the name index vector to be able to quickly search by name
+ const size_t count = m_descriptors.size();
+ for (uint32_t idx = 0; idx < count; ++idx) {
+ const char *name = m_descriptors[idx].name.c_str();
+ if (name && name[0])
+ m_name_to_descriptor_index.insert(
+ cstr_to_index_mmap::value_type(name, idx));
+ }
}
-
-bool
-DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr)
-{
- if (data.ValidOffset(*offset_ptr))
- {
- m_descriptors.clear();
- m_offset = *offset_ptr;
- m_header.length = data.GetDWARFInitialLength(offset_ptr);
- m_header.version = data.GetU16(offset_ptr);
- m_header.die_offset = data.GetDWARFOffset(offset_ptr);
- m_header.die_length = data.GetDWARFOffset(offset_ptr);
-
- Descriptor pubnameDesc;
- while (data.ValidOffset(*offset_ptr))
- {
- pubnameDesc.offset = data.GetDWARFOffset(offset_ptr);
-
- if (pubnameDesc.offset)
- {
- const char* name = data.GetCStr(offset_ptr);
- if (name && name[0])
- {
- pubnameDesc.name = name;
- m_descriptors.push_back(pubnameDesc);
- }
- }
- else
- break; // We are done if we get a zero 4 byte offset
+bool DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ if (data.ValidOffset(*offset_ptr)) {
+ m_descriptors.clear();
+ m_offset = *offset_ptr;
+ m_header.length = data.GetDWARFInitialLength(offset_ptr);
+ m_header.version = data.GetU16(offset_ptr);
+ m_header.die_offset = data.GetDWARFOffset(offset_ptr);
+ m_header.die_length = data.GetDWARFOffset(offset_ptr);
+
+ Descriptor pubnameDesc;
+ while (data.ValidOffset(*offset_ptr)) {
+ pubnameDesc.offset = data.GetDWARFOffset(offset_ptr);
+
+ if (pubnameDesc.offset) {
+ const char *name = data.GetCStr(offset_ptr);
+ if (name && name[0]) {
+ pubnameDesc.name = name;
+ m_descriptors.push_back(pubnameDesc);
}
-
- return !m_descriptors.empty();
+ } else
+ break; // We are done if we get a zero 4 byte offset
}
- return false;
-}
-dw_offset_t
-DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const
-{
- return m_offset + m_header.length + 4;
+ return !m_descriptors.empty();
+ }
+ return false;
}
-void
-DWARFDebugPubnamesSet::Dump(Log *log) const
-{
- log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x",
- m_header.length,
- m_header.version,
- m_header.die_offset,
- m_header.die_length);
-
- bool verbose = log->GetVerbose();
-
- DescriptorConstIter pos;
- DescriptorConstIter end = m_descriptors.end();
- for (pos = m_descriptors.begin(); pos != end; ++pos)
- {
- if (verbose)
- log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, m_header.die_offset, pos->offset + m_header.die_offset, pos->name.c_str());
- else
- log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str());
- }
+dw_offset_t DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const {
+ return m_offset + m_header.length + 4;
}
-
-void
-DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const
-{
- if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
- InitNameIndexes();
-
- std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name));
- for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos)
- die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset);
+void DWARFDebugPubnamesSet::Dump(Log *log) const {
+ log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, "
+ "die_offset = 0x%8.8x, die_length = 0x%8.8x",
+ m_header.length, m_header.version, m_header.die_offset,
+ m_header.die_length);
+
+ bool verbose = log->GetVerbose();
+
+ DescriptorConstIter pos;
+ DescriptorConstIter end = m_descriptors.end();
+ for (pos = m_descriptors.begin(); pos != end; ++pos) {
+ if (verbose)
+ log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset,
+ m_header.die_offset, pos->offset + m_header.die_offset,
+ pos->name.c_str());
+ else
+ log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset,
+ pos->name.c_str());
+ }
}
-void
-DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const
-{
- DescriptorConstIter pos;
- DescriptorConstIter end = m_descriptors.end();
- for (pos = m_descriptors.begin(); pos != end; ++pos)
- {
- if ( regex.Execute(pos->name.c_str()) )
- die_offset_coll.push_back(m_header.die_offset + pos->offset);
- }
+void DWARFDebugPubnamesSet::Find(
+ const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offset_coll) const {
+ if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
+ InitNameIndexes();
+
+ std::pair<cstr_to_index_mmap::const_iterator,
+ cstr_to_index_mmap::const_iterator>
+ range(m_name_to_descriptor_index.equal_range(name));
+ for (cstr_to_index_mmap::const_iterator pos = range.first;
+ pos != range.second; ++pos)
+ die_offset_coll.push_back(m_header.die_offset +
+ m_descriptors[(*pos).second].offset);
}
+void DWARFDebugPubnamesSet::Find(
+ const RegularExpression &regex,
+ std::vector<dw_offset_t> &die_offset_coll) const {
+ DescriptorConstIter pos;
+ DescriptorConstIter end = m_descriptors.end();
+ for (pos = m_descriptors.begin(); pos != end; ++pos) {
+ if (regex.Execute(pos->name))
+ die_offset_coll.push_back(m_header.die_offset + pos->offset);
+ }
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
index 075807b2dcc3..9654ee3d6da7 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
@@ -19,81 +19,74 @@
#include <ext/hash_map>
#endif
-class DWARFDebugPubnamesSet
-{
+class DWARFDebugPubnamesSet {
public:
- struct Header
- {
- uint32_t length; // length of the set of entries for this compilation unit, not including the length field itself
- uint16_t version; // The DWARF version number
- uint32_t die_offset; // compile unit .debug_info offset
- uint32_t die_length; // compile unit .debug_info length
- Header() :
- length(10),
- version(2),
- die_offset(DW_INVALID_OFFSET),
- die_length(0)
- {
- }
- };
+ struct Header {
+ uint32_t length; // length of the set of entries for this compilation unit,
+ // not including the length field itself
+ uint16_t version; // The DWARF version number
+ uint32_t die_offset; // compile unit .debug_info offset
+ uint32_t die_length; // compile unit .debug_info length
+ Header()
+ : length(10), version(2), die_offset(DW_INVALID_OFFSET), die_length(0) {
+ }
+ };
- struct Descriptor
- {
- Descriptor() :
- offset(),
- name()
- {
- }
+ struct Descriptor {
+ Descriptor() : offset(), name() {}
- Descriptor(dw_offset_t the_offset, const char *the_name) :
- offset(the_offset),
- name(the_name ? the_name : "")
- {
- }
-
- dw_offset_t offset;
- std::string name;
- };
-
- DWARFDebugPubnamesSet();
- DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t die_length);
- dw_offset_t GetOffset() const { return m_offset; }
- void SetOffset(dw_offset_t offset) { m_offset = offset; }
- DWARFDebugPubnamesSet::Header& GetHeader() { return m_header; }
- const DWARFDebugPubnamesSet::Header& GetHeader() const { return m_header; }
- const DWARFDebugPubnamesSet::Descriptor* GetDescriptor(uint32_t i) const
- {
- if (i < m_descriptors.size())
- return &m_descriptors[i];
- return NULL;
- }
- uint32_t NumDescriptors() const { return m_descriptors.size(); }
- void AddDescriptor(dw_offset_t cu_rel_offset, const char* name);
- void Clear();
- bool Extract(const lldb_private::DWARFDataExtractor& debug_pubnames_data, lldb::offset_t *offset_ptr);
- void Dump(lldb_private::Log *s) const;
- void InitNameIndexes() const;
- void Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
- void Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const;
- dw_offset_t GetOffsetOfNextEntry() const;
+ Descriptor(dw_offset_t the_offset, const char *the_name)
+ : offset(the_offset), name(the_name ? the_name : "") {}
+ dw_offset_t offset;
+ std::string name;
+ };
+ DWARFDebugPubnamesSet();
+ DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset,
+ dw_offset_t cu_die_offset, dw_offset_t die_length);
+ dw_offset_t GetOffset() const { return m_offset; }
+ void SetOffset(dw_offset_t offset) { m_offset = offset; }
+ DWARFDebugPubnamesSet::Header &GetHeader() { return m_header; }
+ const DWARFDebugPubnamesSet::Header &GetHeader() const { return m_header; }
+ const DWARFDebugPubnamesSet::Descriptor *GetDescriptor(uint32_t i) const {
+ if (i < m_descriptors.size())
+ return &m_descriptors[i];
+ return NULL;
+ }
+ uint32_t NumDescriptors() const { return m_descriptors.size(); }
+ void AddDescriptor(dw_offset_t cu_rel_offset, const char *name);
+ void Clear();
+ bool Extract(const lldb_private::DWARFDataExtractor &debug_pubnames_data,
+ lldb::offset_t *offset_ptr);
+ void Dump(lldb_private::Log *s) const;
+ void InitNameIndexes() const;
+ void Find(const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offset_coll) const;
+ void Find(const lldb_private::RegularExpression &regex,
+ std::vector<dw_offset_t> &die_offsets) const;
+ dw_offset_t GetOffsetOfNextEntry() const;
protected:
- typedef std::vector<Descriptor> DescriptorColl;
- typedef DescriptorColl::iterator DescriptorIter;
- typedef DescriptorColl::const_iterator DescriptorConstIter;
-
+ typedef std::vector<Descriptor> DescriptorColl;
+ typedef DescriptorColl::iterator DescriptorIter;
+ typedef DescriptorColl::const_iterator DescriptorConstIter;
- dw_offset_t m_offset;
- Header m_header;
+ dw_offset_t m_offset;
+ Header m_header;
#if __cplusplus >= 201103L || defined(_MSC_VER)
- typedef std::unordered_multimap<const char*, uint32_t, std::hash<const char*>, CStringEqualBinaryPredicate> cstr_to_index_mmap;
+ typedef std::unordered_multimap<const char *, uint32_t,
+ std::hash<const char *>,
+ CStringEqualBinaryPredicate>
+ cstr_to_index_mmap;
#else
- typedef __gnu_cxx::hash_multimap<const char*, uint32_t, __gnu_cxx::hash<const char*>, CStringEqualBinaryPredicate> cstr_to_index_mmap;
+ typedef __gnu_cxx::hash_multimap<const char *, uint32_t,
+ __gnu_cxx::hash<const char *>,
+ CStringEqualBinaryPredicate>
+ cstr_to_index_mmap;
#endif
- DescriptorColl m_descriptors;
- mutable cstr_to_index_mmap m_name_to_descriptor_index;
+ DescriptorColl m_descriptors;
+ mutable cstr_to_index_mmap m_name_to_descriptor_index;
};
-#endif // SymbolFileDWARF_DWARFDebugPubnamesSet_h_
+#endif // SymbolFileDWARF_DWARFDebugPubnamesSet_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index fc2831f22438..78fe571c50cf 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -15,135 +15,117 @@
using namespace lldb_private;
using namespace std;
-DWARFDebugRanges::DWARFDebugRanges() :
- m_range_map()
-{
+DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
+
+DWARFDebugRanges::~DWARFDebugRanges() {}
+
+void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) {
+ DWARFRangeList range_list;
+ lldb::offset_t offset = 0;
+ dw_offset_t debug_ranges_offset = offset;
+ while (Extract(dwarf2Data, &offset, range_list)) {
+ range_list.Sort();
+ m_range_map[debug_ranges_offset] = range_list;
+ debug_ranges_offset = offset;
+ }
}
-DWARFDebugRanges::~DWARFDebugRanges()
-{
-}
-
-void
-DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data)
-{
- DWARFRangeList range_list;
- lldb::offset_t offset = 0;
- dw_offset_t debug_ranges_offset = offset;
- while (Extract(dwarf2Data, &offset, range_list))
- {
- range_list.Sort();
- m_range_map[debug_ranges_offset] = range_list;
- debug_ranges_offset = offset;
+bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data,
+ lldb::offset_t *offset_ptr,
+ DWARFRangeList &range_list) {
+ range_list.Clear();
+
+ lldb::offset_t range_offset = *offset_ptr;
+ const DWARFDataExtractor &debug_ranges_data =
+ dwarf2Data->get_debug_ranges_data();
+ uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
+
+ while (
+ debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
+ dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ if (!begin && !end) {
+ // End of range list
+ break;
}
-}
-
-bool
-DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, lldb::offset_t *offset_ptr, DWARFRangeList &range_list)
-{
- range_list.Clear();
-
- lldb::offset_t range_offset = *offset_ptr;
- const DWARFDataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data();
- uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
-
- while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
- {
- dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- if (!begin && !end)
- {
- // End of range list
- break;
- }
- // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
- // of ones
- switch (addr_size)
- {
- case 2:
- if (begin == 0xFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
-
- case 4:
- if (begin == 0xFFFFFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
-
- case 8:
- break;
-
- default:
- assert(!"DWARFRangeList::Extract() unsupported address size.");
- break;
- }
-
- // Filter out empty ranges
- if (begin < end)
- range_list.Append(DWARFRangeList::Entry(begin, end - begin));
+ // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
+ // of ones
+ switch (addr_size) {
+ case 2:
+ if (begin == 0xFFFFull)
+ begin = LLDB_INVALID_ADDRESS;
+ break;
+
+ case 4:
+ if (begin == 0xFFFFFFFFull)
+ begin = LLDB_INVALID_ADDRESS;
+ break;
+
+ case 8:
+ break;
+
+ default:
+ assert(!"DWARFRangeList::Extract() unsupported address size.");
+ break;
}
- // Make sure we consumed at least something
- return range_offset != *offset_ptr;
-}
+ // Filter out empty ranges
+ if (begin < end)
+ range_list.Append(DWARFRangeList::Entry(begin, end - begin));
+ }
+ // Make sure we consumed at least something
+ return range_offset != *offset_ptr;
+}
-void
-DWARFDebugRanges::Dump(Stream &s, const DWARFDataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr)
-{
- uint32_t addr_size = s.GetAddressByteSize();
- bool verbose = s.GetVerbose();
-
- dw_addr_t base_addr = cu_base_addr;
- while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
- {
- dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
- // of ones
- if (begin == 0xFFFFFFFFull && addr_size == 4)
- begin = LLDB_INVALID_ADDRESS;
-
- s.Indent();
- if (verbose)
- {
- s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = ");
- }
-
-
- if (begin == 0 && end == 0)
- {
- s.PutCString(" End");
- break;
- }
- else if (begin == LLDB_INVALID_ADDRESS)
- {
- // A base address selection entry
- base_addr = end;
- s.Address(base_addr, sizeof (dw_addr_t), " Base address = ");
- }
- else
- {
- // Convert from offset to an address
- dw_addr_t begin_addr = begin + base_addr;
- dw_addr_t end_addr = end + base_addr;
-
- s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL);
- }
+void DWARFDebugRanges::Dump(Stream &s,
+ const DWARFDataExtractor &debug_ranges_data,
+ lldb::offset_t *offset_ptr,
+ dw_addr_t cu_base_addr) {
+ uint32_t addr_size = s.GetAddressByteSize();
+ bool verbose = s.GetVerbose();
+
+ dw_addr_t base_addr = cu_base_addr;
+ while (
+ debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
+ dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
+ // of ones
+ if (begin == 0xFFFFFFFFull && addr_size == 4)
+ begin = LLDB_INVALID_ADDRESS;
+
+ s.Indent();
+ if (verbose) {
+ s.AddressRange(begin, end, sizeof(dw_addr_t), " offsets = ");
}
-}
-bool
-DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, DWARFRangeList& range_list) const
-{
- range_map_const_iterator pos = m_range_map.find(debug_ranges_offset);
- if (pos != m_range_map.end())
- {
- range_list = pos->second;
- return true;
+ if (begin == 0 && end == 0) {
+ s.PutCString(" End");
+ break;
+ } else if (begin == LLDB_INVALID_ADDRESS) {
+ // A base address selection entry
+ base_addr = end;
+ s.Address(base_addr, sizeof(dw_addr_t), " Base address = ");
+ } else {
+ // Convert from offset to an address
+ dw_addr_t begin_addr = begin + base_addr;
+ dw_addr_t end_addr = end + base_addr;
+
+ s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t),
+ verbose ? " ==> addrs = " : NULL);
}
- return false;
+ }
}
-
-
+bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base,
+ dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const {
+ dw_addr_t debug_ranges_address = debug_ranges_base + 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;
+ return true;
+ }
+ return false;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index 3ff4ea3502c9..f514359e00a4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -10,33 +10,31 @@
#ifndef SymbolFileDWARF_DWARFDebugRanges_h_
#define SymbolFileDWARF_DWARFDebugRanges_h_
-#include "SymbolFileDWARF.h"
#include "DWARFDIE.h"
+#include "SymbolFileDWARF.h"
#include <map>
-class DWARFDebugRanges
-{
+class DWARFDebugRanges {
public:
-
- DWARFDebugRanges();
- ~DWARFDebugRanges();
- void Extract(SymbolFileDWARF* dwarf2Data);
- 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_offset_t debug_ranges_offset, DWARFRangeList& range_list) const;
+ DWARFDebugRanges();
+ ~DWARFDebugRanges();
+ void Extract(SymbolFileDWARF *dwarf2Data);
+ 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,
+ DWARFRangeList &range_list);
- bool
- Extract (SymbolFileDWARF* dwarf2Data,
- lldb::offset_t *offset_ptr,
- DWARFRangeList &range_list);
-
- typedef std::map<dw_offset_t, DWARFRangeList> range_map;
- typedef range_map::iterator range_map_iterator;
- typedef range_map::const_iterator range_map_const_iterator;
- range_map m_range_map;
+ typedef std::map<dw_offset_t, DWARFRangeList> range_map;
+ typedef range_map::iterator range_map_iterator;
+ typedef range_map::const_iterator range_map_const_iterator;
+ range_map m_range_map;
};
-
-#endif // SymbolFileDWARF_DWARFDebugRanges_h_
+#endif // SymbolFileDWARF_DWARFDebugRanges_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
index 5512072529fc..79f2f221696b 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
@@ -9,96 +9,80 @@
#include "DWARFDeclContext.h"
-const char *
-DWARFDeclContext::GetQualifiedName () const
-{
- if (m_qualified_name.empty())
- {
- // The declaration context array for a class named "foo" in namespace
- // "a::b::c" will be something like:
- // [0] DW_TAG_class_type "foo"
- // [1] DW_TAG_namespace "c"
- // [2] DW_TAG_namespace "b"
- // [3] DW_TAG_namespace "a"
- if (!m_entries.empty())
- {
- if (m_entries.size() == 1)
- {
- if (m_entries[0].name)
- {
- m_qualified_name.append("::");
- m_qualified_name.append(m_entries[0].name);
- }
- }
+const char *DWARFDeclContext::GetQualifiedName() const {
+ if (m_qualified_name.empty()) {
+ // The declaration context array for a class named "foo" in namespace
+ // "a::b::c" will be something like:
+ // [0] DW_TAG_class_type "foo"
+ // [1] DW_TAG_namespace "c"
+ // [2] DW_TAG_namespace "b"
+ // [3] DW_TAG_namespace "a"
+ if (!m_entries.empty()) {
+ if (m_entries.size() == 1) {
+ if (m_entries[0].name) {
+ m_qualified_name.append("::");
+ m_qualified_name.append(m_entries[0].name);
+ }
+ } else {
+ collection::const_reverse_iterator pos;
+ collection::const_reverse_iterator begin = m_entries.rbegin();
+ collection::const_reverse_iterator end = m_entries.rend();
+ for (pos = begin; pos != end; ++pos) {
+ if (pos != begin)
+ m_qualified_name.append("::");
+ if (pos->name == NULL) {
+ if (pos->tag == DW_TAG_namespace)
+ m_qualified_name.append("(anonymous namespace)");
+ else if (pos->tag == DW_TAG_class_type)
+ m_qualified_name.append("(anonymous class)");
+ else if (pos->tag == DW_TAG_structure_type)
+ m_qualified_name.append("(anonymous struct)");
+ else if (pos->tag == DW_TAG_union_type)
+ m_qualified_name.append("(anonymous union)");
else
- {
- collection::const_reverse_iterator pos;
- collection::const_reverse_iterator begin = m_entries.rbegin();
- collection::const_reverse_iterator end = m_entries.rend();
- for (pos = begin; pos != end; ++pos)
- {
- if (pos != begin)
- m_qualified_name.append("::");
- if (pos->name == NULL)
- {
- if (pos->tag == DW_TAG_namespace)
- m_qualified_name.append ("(anonymous namespace)");
- else if (pos->tag == DW_TAG_class_type)
- m_qualified_name.append ("(anonymous class)");
- else if (pos->tag == DW_TAG_structure_type)
- m_qualified_name.append ("(anonymous struct)");
- else if (pos->tag == DW_TAG_union_type)
- m_qualified_name.append ("(anonymous union)");
- else
- m_qualified_name.append ("(anonymous)");
- }
- else
- m_qualified_name.append(pos->name);
- }
- }
+ m_qualified_name.append("(anonymous)");
+ } else
+ m_qualified_name.append(pos->name);
}
+ }
}
- if (m_qualified_name.empty())
- return NULL;
- return m_qualified_name.c_str();
+ }
+ if (m_qualified_name.empty())
+ return NULL;
+ return m_qualified_name.c_str();
}
+bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const {
+ if (m_entries.size() != rhs.m_entries.size())
+ return false;
-bool
-DWARFDeclContext::operator==(const DWARFDeclContext& rhs) const
-{
- if (m_entries.size() != rhs.m_entries.size())
- return false;
-
- collection::const_iterator pos;
- collection::const_iterator begin = m_entries.begin();
- collection::const_iterator end = m_entries.end();
+ collection::const_iterator pos;
+ collection::const_iterator begin = m_entries.begin();
+ collection::const_iterator end = m_entries.end();
- collection::const_iterator rhs_pos;
- collection::const_iterator rhs_begin = rhs.m_entries.begin();
- // The two entry arrays have the same size
-
- // First compare the tags before we do expensive name compares
- for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
- {
- if (pos->tag != rhs_pos->tag)
- {
- // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
- // used interchangeably in GCC
- if (pos->tag == DW_TAG_structure_type && rhs_pos->tag == DW_TAG_class_type)
- continue;
- if (pos->tag == DW_TAG_class_type && rhs_pos->tag == DW_TAG_structure_type)
- continue;
- return false;
- }
- }
- // The tags all match, now compare the names
- for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
- {
- if (!pos->NameMatches (*rhs_pos))
- return false;
+ collection::const_iterator rhs_pos;
+ collection::const_iterator rhs_begin = rhs.m_entries.begin();
+ // The two entry arrays have the same size
+
+ // First compare the tags before we do expensive name compares
+ for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
+ if (pos->tag != rhs_pos->tag) {
+ // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
+ // used interchangeably in GCC
+ if (pos->tag == DW_TAG_structure_type &&
+ rhs_pos->tag == DW_TAG_class_type)
+ continue;
+ if (pos->tag == DW_TAG_class_type &&
+ rhs_pos->tag == DW_TAG_structure_type)
+ continue;
+ return false;
}
- // All tags and names match
- return true;
+ }
+ // The tags all match, now compare the names
+ for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
+ if (!pos->NameMatches(*rhs_pos))
+ return false;
+ }
+ // All tags and names match
+ return true;
}
-
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 2452274a293b..0d0a5a317262 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -27,112 +27,69 @@
// in another DWARF file.
//----------------------------------------------------------------------
-class DWARFDeclContext
-{
+class DWARFDeclContext {
public:
- struct Entry
- {
- Entry () :
- tag(0),
- name(NULL)
- {
- }
- Entry (dw_tag_t t, const char *n) :
- tag(t),
- name(n)
- {
- }
-
- bool
- NameMatches (const Entry& rhs) const
- {
- if (name == rhs.name)
- return true;
- else if (name && rhs.name)
- return strcmp(name, rhs.name) == 0;
- return false;
- }
-
- // Test operator
- explicit operator bool() const
- {
- return tag != 0;
- }
-
- dw_tag_t tag;
- const char *name;
- };
-
- DWARFDeclContext () :
- m_entries(),
- m_language(lldb::eLanguageTypeUnknown)
- {
+ struct Entry {
+ Entry() : tag(0), name(NULL) {}
+ Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
+
+ bool NameMatches(const Entry &rhs) const {
+ if (name == rhs.name)
+ return true;
+ else if (name && rhs.name)
+ return strcmp(name, rhs.name) == 0;
+ return false;
}
- void
- AppendDeclContext (dw_tag_t tag, const char *name)
- {
- m_entries.push_back(Entry(tag, name));
- }
+ // Test operator
+ explicit operator bool() const { return tag != 0; }
- bool
- operator ==(const DWARFDeclContext& rhs) const;
+ dw_tag_t tag;
+ const char *name;
+ };
- uint32_t
- GetSize() const
- {
- return m_entries.size();
- }
+ DWARFDeclContext() : m_entries(), m_language(lldb::eLanguageTypeUnknown) {}
- Entry &
- operator[] (uint32_t idx)
- {
- // "idx" must be valid
- return m_entries[idx];
- }
+ void AppendDeclContext(dw_tag_t tag, const char *name) {
+ m_entries.push_back(Entry(tag, name));
+ }
- const Entry &
- operator[] (uint32_t idx) const
- {
- // "idx" must be valid
- return m_entries[idx];
- }
+ bool operator==(const DWARFDeclContext &rhs) const;
- const char *
- GetQualifiedName () const;
+ uint32_t GetSize() const { return m_entries.size(); }
- // Same as GetQaulifiedName, but the life time of the returned string will
- // be that of the LLDB session.
- lldb_private::ConstString
- GetQualifiedNameAsConstString () const
- {
- return lldb_private::ConstString (GetQualifiedName ());
- }
+ Entry &operator[](uint32_t idx) {
+ // "idx" must be valid
+ return m_entries[idx];
+ }
- void
- Clear()
- {
- m_entries.clear();
- m_qualified_name.clear();
- }
+ const Entry &operator[](uint32_t idx) const {
+ // "idx" must be valid
+ return m_entries[idx];
+ }
- lldb::LanguageType
- GetLanguage() const
- {
- return m_language;
- }
+ const char *GetQualifiedName() const;
- void
- SetLanguage(lldb::LanguageType language)
- {
- m_language = language;
- }
+ // Same as GetQaulifiedName, but the life time of the returned string will
+ // be that of the LLDB session.
+ lldb_private::ConstString GetQualifiedNameAsConstString() const {
+ return lldb_private::ConstString(GetQualifiedName());
+ }
+
+ void Clear() {
+ m_entries.clear();
+ m_qualified_name.clear();
+ }
+
+ lldb::LanguageType GetLanguage() const { return m_language; }
+
+ void SetLanguage(lldb::LanguageType language) { m_language = language; }
protected:
- typedef std::vector<Entry> collection;
- collection m_entries;
- mutable std::string m_qualified_name;
- lldb::LanguageType m_language;
+ typedef std::vector<Entry> collection;
+ collection m_entries;
+ mutable std::string m_qualified_name;
+ lldb::LanguageType m_language;
};
-#endif // SymbolFileDWARF_DWARFDeclContext_h_
+#endif // SymbolFileDWARF_DWARFDeclContext_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index fe4093bc130e..c5260bb1cb1a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDefines.c ------------------------------------------*- C++ -*-===//
+//===-- DWARFDefines.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,490 +8,640 @@
//===----------------------------------------------------------------------===//
#include "DWARFDefines.h"
+#include "lldb/Core/ConstString.h"
#include <cstdio>
#include <cstring>
#include <string>
-#include "lldb/Core/ConstString.h"
namespace lldb_private {
-const char *
-DW_TAG_value_to_name (uint32_t val)
-{
+const char *DW_TAG_value_to_name(uint32_t val) {
static char invalid[100];
if (val == 0)
- return "NULL";
+ return "NULL";
- const char *llvmstr = llvm::dwarf::TagString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_TAG constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::TagString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_TAG constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
-}
+ return llvmstr.data();
+}
-const char *
-DW_CHILDREN_value_to_name (uint8_t val)
-{
+const char *DW_CHILDREN_value_to_name(uint8_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::ChildrenString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_CHILDREN constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::ChildrenString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_CHILDREN constant: 0x%x",
+ val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_AT_value_to_name (uint32_t val)
-{
+const char *DW_AT_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::AttributeString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_AT constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::AttributeString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_AT constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_FORM_value_to_name (uint32_t val)
-{
+const char *DW_FORM_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::FormEncodingString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_FORM constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::FormEncodingString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_FORM constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_OP_value_to_name (uint32_t val)
-{
+const char *DW_OP_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::OperationEncodingString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_OP constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::OperationEncodingString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-DRC_class
-DW_OP_value_to_class (uint32_t val)
-{
+DRC_class DW_OP_value_to_class(uint32_t val) {
switch (val) {
- case 0x03: return DRC_ONEOPERAND;
- case 0x06: return DRC_ZEROOPERANDS;
- case 0x08: return DRC_ONEOPERAND;
- case 0x09: return DRC_ONEOPERAND;
- case 0x0a: return DRC_ONEOPERAND;
- case 0x0b: return DRC_ONEOPERAND;
- case 0x0c: return DRC_ONEOPERAND;
- case 0x0d: return DRC_ONEOPERAND;
- case 0x0e: return DRC_ONEOPERAND;
- case 0x0f: return DRC_ONEOPERAND;
- case 0x10: return DRC_ONEOPERAND;
- case 0x11: return DRC_ONEOPERAND;
- case 0x12: return DRC_ZEROOPERANDS;
- case 0x13: return DRC_ZEROOPERANDS;
- case 0x14: return DRC_ZEROOPERANDS;
- case 0x15: return DRC_ONEOPERAND;
- case 0x16: return DRC_ZEROOPERANDS;
- case 0x17: return DRC_ZEROOPERANDS;
- case 0x18: return DRC_ZEROOPERANDS;
- case 0x19: return DRC_ZEROOPERANDS;
- case 0x1a: return DRC_ZEROOPERANDS;
- case 0x1b: return DRC_ZEROOPERANDS;
- case 0x1c: return DRC_ZEROOPERANDS;
- case 0x1d: return DRC_ZEROOPERANDS;
- case 0x1e: return DRC_ZEROOPERANDS;
- case 0x1f: return DRC_ZEROOPERANDS;
- case 0x20: return DRC_ZEROOPERANDS;
- case 0x21: return DRC_ZEROOPERANDS;
- case 0x22: return DRC_ZEROOPERANDS;
- case 0x23: return DRC_ONEOPERAND;
- case 0x24: return DRC_ZEROOPERANDS;
- case 0x25: return DRC_ZEROOPERANDS;
- case 0x26: return DRC_ZEROOPERANDS;
- case 0x27: return DRC_ZEROOPERANDS;
- case 0x2f: return DRC_ONEOPERAND;
- case 0x28: return DRC_ONEOPERAND;
- case 0x29: return DRC_ZEROOPERANDS;
- case 0x2a: return DRC_ZEROOPERANDS;
- case 0x2b: return DRC_ZEROOPERANDS;
- case 0x2c: return DRC_ZEROOPERANDS;
- case 0x2d: return DRC_ZEROOPERANDS;
- case 0x2e: return DRC_ZEROOPERANDS;
- case 0x30: return DRC_ZEROOPERANDS;
- case 0x31: return DRC_ZEROOPERANDS;
- case 0x32: return DRC_ZEROOPERANDS;
- case 0x33: return DRC_ZEROOPERANDS;
- case 0x34: return DRC_ZEROOPERANDS;
- case 0x35: return DRC_ZEROOPERANDS;
- case 0x36: return DRC_ZEROOPERANDS;
- case 0x37: return DRC_ZEROOPERANDS;
- case 0x38: return DRC_ZEROOPERANDS;
- case 0x39: return DRC_ZEROOPERANDS;
- case 0x3a: return DRC_ZEROOPERANDS;
- case 0x3b: return DRC_ZEROOPERANDS;
- case 0x3c: return DRC_ZEROOPERANDS;
- case 0x3d: return DRC_ZEROOPERANDS;
- case 0x3e: return DRC_ZEROOPERANDS;
- case 0x3f: return DRC_ZEROOPERANDS;
- case 0x40: return DRC_ZEROOPERANDS;
- case 0x41: return DRC_ZEROOPERANDS;
- case 0x42: return DRC_ZEROOPERANDS;
- case 0x43: return DRC_ZEROOPERANDS;
- case 0x44: return DRC_ZEROOPERANDS;
- case 0x45: return DRC_ZEROOPERANDS;
- case 0x46: return DRC_ZEROOPERANDS;
- case 0x47: return DRC_ZEROOPERANDS;
- case 0x48: return DRC_ZEROOPERANDS;
- case 0x49: return DRC_ZEROOPERANDS;
- case 0x4a: return DRC_ZEROOPERANDS;
- case 0x4b: return DRC_ZEROOPERANDS;
- case 0x4c: return DRC_ZEROOPERANDS;
- case 0x4d: return DRC_ZEROOPERANDS;
- case 0x4e: return DRC_ZEROOPERANDS;
- case 0x4f: return DRC_ZEROOPERANDS;
- case 0x50: return DRC_ZEROOPERANDS;
- case 0x51: return DRC_ZEROOPERANDS;
- case 0x52: return DRC_ZEROOPERANDS;
- case 0x53: return DRC_ZEROOPERANDS;
- case 0x54: return DRC_ZEROOPERANDS;
- case 0x55: return DRC_ZEROOPERANDS;
- case 0x56: return DRC_ZEROOPERANDS;
- case 0x57: return DRC_ZEROOPERANDS;
- case 0x58: return DRC_ZEROOPERANDS;
- case 0x59: return DRC_ZEROOPERANDS;
- case 0x5a: return DRC_ZEROOPERANDS;
- case 0x5b: return DRC_ZEROOPERANDS;
- case 0x5c: return DRC_ZEROOPERANDS;
- case 0x5d: return DRC_ZEROOPERANDS;
- case 0x5e: return DRC_ZEROOPERANDS;
- case 0x5f: return DRC_ZEROOPERANDS;
- case 0x60: return DRC_ZEROOPERANDS;
- case 0x61: return DRC_ZEROOPERANDS;
- case 0x62: return DRC_ZEROOPERANDS;
- case 0x63: return DRC_ZEROOPERANDS;
- case 0x64: return DRC_ZEROOPERANDS;
- case 0x65: return DRC_ZEROOPERANDS;
- case 0x66: return DRC_ZEROOPERANDS;
- case 0x67: return DRC_ZEROOPERANDS;
- case 0x68: return DRC_ZEROOPERANDS;
- case 0x69: return DRC_ZEROOPERANDS;
- case 0x6a: return DRC_ZEROOPERANDS;
- case 0x6b: return DRC_ZEROOPERANDS;
- case 0x6c: return DRC_ZEROOPERANDS;
- case 0x6d: return DRC_ZEROOPERANDS;
- case 0x6e: return DRC_ZEROOPERANDS;
- case 0x6f: return DRC_ZEROOPERANDS;
- case 0x70: return DRC_ONEOPERAND;
- case 0x71: return DRC_ONEOPERAND;
- case 0x72: return DRC_ONEOPERAND;
- case 0x73: return DRC_ONEOPERAND;
- case 0x74: return DRC_ONEOPERAND;
- case 0x75: return DRC_ONEOPERAND;
- case 0x76: return DRC_ONEOPERAND;
- case 0x77: return DRC_ONEOPERAND;
- case 0x78: return DRC_ONEOPERAND;
- case 0x79: return DRC_ONEOPERAND;
- case 0x7a: return DRC_ONEOPERAND;
- case 0x7b: return DRC_ONEOPERAND;
- case 0x7c: return DRC_ONEOPERAND;
- case 0x7d: return DRC_ONEOPERAND;
- case 0x7e: return DRC_ONEOPERAND;
- case 0x7f: return DRC_ONEOPERAND;
- case 0x80: return DRC_ONEOPERAND;
- case 0x81: return DRC_ONEOPERAND;
- case 0x82: return DRC_ONEOPERAND;
- case 0x83: return DRC_ONEOPERAND;
- case 0x84: return DRC_ONEOPERAND;
- case 0x85: return DRC_ONEOPERAND;
- case 0x86: return DRC_ONEOPERAND;
- case 0x87: return DRC_ONEOPERAND;
- case 0x88: return DRC_ONEOPERAND;
- case 0x89: return DRC_ONEOPERAND;
- case 0x8a: return DRC_ONEOPERAND;
- case 0x8b: return DRC_ONEOPERAND;
- case 0x8c: return DRC_ONEOPERAND;
- case 0x8d: return DRC_ONEOPERAND;
- case 0x8e: return DRC_ONEOPERAND;
- case 0x8f: return DRC_ONEOPERAND;
- case 0x90: return DRC_ONEOPERAND;
- case 0x91: return DRC_ONEOPERAND;
- case 0x92: return DRC_TWOOPERANDS;
- case 0x93: return DRC_ONEOPERAND;
- case 0x94: return DRC_ONEOPERAND;
- case 0x95: return DRC_ONEOPERAND;
- case 0x96: return DRC_ZEROOPERANDS;
- case 0x97: return DRC_DWARFv3 | DRC_ZEROOPERANDS;
- case 0x98: return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0x99: return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0x9a: return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0xf0: return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
- case 0xe0: return 0;
- case 0xff: return 0;
- default: return 0;
+ case 0x03:
+ return DRC_ONEOPERAND;
+ case 0x06:
+ return DRC_ZEROOPERANDS;
+ case 0x08:
+ return DRC_ONEOPERAND;
+ case 0x09:
+ return DRC_ONEOPERAND;
+ case 0x0a:
+ return DRC_ONEOPERAND;
+ case 0x0b:
+ return DRC_ONEOPERAND;
+ case 0x0c:
+ return DRC_ONEOPERAND;
+ case 0x0d:
+ return DRC_ONEOPERAND;
+ case 0x0e:
+ return DRC_ONEOPERAND;
+ case 0x0f:
+ return DRC_ONEOPERAND;
+ case 0x10:
+ return DRC_ONEOPERAND;
+ case 0x11:
+ return DRC_ONEOPERAND;
+ case 0x12:
+ return DRC_ZEROOPERANDS;
+ case 0x13:
+ return DRC_ZEROOPERANDS;
+ case 0x14:
+ return DRC_ZEROOPERANDS;
+ case 0x15:
+ return DRC_ONEOPERAND;
+ case 0x16:
+ return DRC_ZEROOPERANDS;
+ case 0x17:
+ return DRC_ZEROOPERANDS;
+ case 0x18:
+ return DRC_ZEROOPERANDS;
+ case 0x19:
+ return DRC_ZEROOPERANDS;
+ case 0x1a:
+ return DRC_ZEROOPERANDS;
+ case 0x1b:
+ return DRC_ZEROOPERANDS;
+ case 0x1c:
+ return DRC_ZEROOPERANDS;
+ case 0x1d:
+ return DRC_ZEROOPERANDS;
+ case 0x1e:
+ return DRC_ZEROOPERANDS;
+ case 0x1f:
+ return DRC_ZEROOPERANDS;
+ case 0x20:
+ return DRC_ZEROOPERANDS;
+ case 0x21:
+ return DRC_ZEROOPERANDS;
+ case 0x22:
+ return DRC_ZEROOPERANDS;
+ case 0x23:
+ return DRC_ONEOPERAND;
+ case 0x24:
+ return DRC_ZEROOPERANDS;
+ case 0x25:
+ return DRC_ZEROOPERANDS;
+ case 0x26:
+ return DRC_ZEROOPERANDS;
+ case 0x27:
+ return DRC_ZEROOPERANDS;
+ case 0x2f:
+ return DRC_ONEOPERAND;
+ case 0x28:
+ return DRC_ONEOPERAND;
+ case 0x29:
+ return DRC_ZEROOPERANDS;
+ case 0x2a:
+ return DRC_ZEROOPERANDS;
+ case 0x2b:
+ return DRC_ZEROOPERANDS;
+ case 0x2c:
+ return DRC_ZEROOPERANDS;
+ case 0x2d:
+ return DRC_ZEROOPERANDS;
+ case 0x2e:
+ return DRC_ZEROOPERANDS;
+ case 0x30:
+ return DRC_ZEROOPERANDS;
+ case 0x31:
+ return DRC_ZEROOPERANDS;
+ case 0x32:
+ return DRC_ZEROOPERANDS;
+ case 0x33:
+ return DRC_ZEROOPERANDS;
+ case 0x34:
+ return DRC_ZEROOPERANDS;
+ case 0x35:
+ return DRC_ZEROOPERANDS;
+ case 0x36:
+ return DRC_ZEROOPERANDS;
+ case 0x37:
+ return DRC_ZEROOPERANDS;
+ case 0x38:
+ return DRC_ZEROOPERANDS;
+ case 0x39:
+ return DRC_ZEROOPERANDS;
+ case 0x3a:
+ return DRC_ZEROOPERANDS;
+ case 0x3b:
+ return DRC_ZEROOPERANDS;
+ case 0x3c:
+ return DRC_ZEROOPERANDS;
+ case 0x3d:
+ return DRC_ZEROOPERANDS;
+ case 0x3e:
+ return DRC_ZEROOPERANDS;
+ case 0x3f:
+ return DRC_ZEROOPERANDS;
+ case 0x40:
+ return DRC_ZEROOPERANDS;
+ case 0x41:
+ return DRC_ZEROOPERANDS;
+ case 0x42:
+ return DRC_ZEROOPERANDS;
+ case 0x43:
+ return DRC_ZEROOPERANDS;
+ case 0x44:
+ return DRC_ZEROOPERANDS;
+ case 0x45:
+ return DRC_ZEROOPERANDS;
+ case 0x46:
+ return DRC_ZEROOPERANDS;
+ case 0x47:
+ return DRC_ZEROOPERANDS;
+ case 0x48:
+ return DRC_ZEROOPERANDS;
+ case 0x49:
+ return DRC_ZEROOPERANDS;
+ case 0x4a:
+ return DRC_ZEROOPERANDS;
+ case 0x4b:
+ return DRC_ZEROOPERANDS;
+ case 0x4c:
+ return DRC_ZEROOPERANDS;
+ case 0x4d:
+ return DRC_ZEROOPERANDS;
+ case 0x4e:
+ return DRC_ZEROOPERANDS;
+ case 0x4f:
+ return DRC_ZEROOPERANDS;
+ case 0x50:
+ return DRC_ZEROOPERANDS;
+ case 0x51:
+ return DRC_ZEROOPERANDS;
+ case 0x52:
+ return DRC_ZEROOPERANDS;
+ case 0x53:
+ return DRC_ZEROOPERANDS;
+ case 0x54:
+ return DRC_ZEROOPERANDS;
+ case 0x55:
+ return DRC_ZEROOPERANDS;
+ case 0x56:
+ return DRC_ZEROOPERANDS;
+ case 0x57:
+ return DRC_ZEROOPERANDS;
+ case 0x58:
+ return DRC_ZEROOPERANDS;
+ case 0x59:
+ return DRC_ZEROOPERANDS;
+ case 0x5a:
+ return DRC_ZEROOPERANDS;
+ case 0x5b:
+ return DRC_ZEROOPERANDS;
+ case 0x5c:
+ return DRC_ZEROOPERANDS;
+ case 0x5d:
+ return DRC_ZEROOPERANDS;
+ case 0x5e:
+ return DRC_ZEROOPERANDS;
+ case 0x5f:
+ return DRC_ZEROOPERANDS;
+ case 0x60:
+ return DRC_ZEROOPERANDS;
+ case 0x61:
+ return DRC_ZEROOPERANDS;
+ case 0x62:
+ return DRC_ZEROOPERANDS;
+ case 0x63:
+ return DRC_ZEROOPERANDS;
+ case 0x64:
+ return DRC_ZEROOPERANDS;
+ case 0x65:
+ return DRC_ZEROOPERANDS;
+ case 0x66:
+ return DRC_ZEROOPERANDS;
+ case 0x67:
+ return DRC_ZEROOPERANDS;
+ case 0x68:
+ return DRC_ZEROOPERANDS;
+ case 0x69:
+ return DRC_ZEROOPERANDS;
+ case 0x6a:
+ return DRC_ZEROOPERANDS;
+ case 0x6b:
+ return DRC_ZEROOPERANDS;
+ case 0x6c:
+ return DRC_ZEROOPERANDS;
+ case 0x6d:
+ return DRC_ZEROOPERANDS;
+ case 0x6e:
+ return DRC_ZEROOPERANDS;
+ case 0x6f:
+ return DRC_ZEROOPERANDS;
+ case 0x70:
+ return DRC_ONEOPERAND;
+ case 0x71:
+ return DRC_ONEOPERAND;
+ case 0x72:
+ return DRC_ONEOPERAND;
+ case 0x73:
+ return DRC_ONEOPERAND;
+ case 0x74:
+ return DRC_ONEOPERAND;
+ case 0x75:
+ return DRC_ONEOPERAND;
+ case 0x76:
+ return DRC_ONEOPERAND;
+ case 0x77:
+ return DRC_ONEOPERAND;
+ case 0x78:
+ return DRC_ONEOPERAND;
+ case 0x79:
+ return DRC_ONEOPERAND;
+ case 0x7a:
+ return DRC_ONEOPERAND;
+ case 0x7b:
+ return DRC_ONEOPERAND;
+ case 0x7c:
+ return DRC_ONEOPERAND;
+ case 0x7d:
+ return DRC_ONEOPERAND;
+ case 0x7e:
+ return DRC_ONEOPERAND;
+ case 0x7f:
+ return DRC_ONEOPERAND;
+ case 0x80:
+ return DRC_ONEOPERAND;
+ case 0x81:
+ return DRC_ONEOPERAND;
+ case 0x82:
+ return DRC_ONEOPERAND;
+ case 0x83:
+ return DRC_ONEOPERAND;
+ case 0x84:
+ return DRC_ONEOPERAND;
+ case 0x85:
+ return DRC_ONEOPERAND;
+ case 0x86:
+ return DRC_ONEOPERAND;
+ case 0x87:
+ return DRC_ONEOPERAND;
+ case 0x88:
+ return DRC_ONEOPERAND;
+ case 0x89:
+ return DRC_ONEOPERAND;
+ case 0x8a:
+ return DRC_ONEOPERAND;
+ case 0x8b:
+ return DRC_ONEOPERAND;
+ case 0x8c:
+ return DRC_ONEOPERAND;
+ case 0x8d:
+ return DRC_ONEOPERAND;
+ case 0x8e:
+ return DRC_ONEOPERAND;
+ case 0x8f:
+ return DRC_ONEOPERAND;
+ case 0x90:
+ return DRC_ONEOPERAND;
+ case 0x91:
+ return DRC_ONEOPERAND;
+ case 0x92:
+ return DRC_TWOOPERANDS;
+ case 0x93:
+ return DRC_ONEOPERAND;
+ case 0x94:
+ return DRC_ONEOPERAND;
+ case 0x95:
+ return DRC_ONEOPERAND;
+ case 0x96:
+ return DRC_ZEROOPERANDS;
+ case 0x97:
+ return DRC_DWARFv3 | DRC_ZEROOPERANDS;
+ case 0x98:
+ return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0x99:
+ return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0x9a:
+ return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0xf0:
+ return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
+ case 0xe0:
+ return 0;
+ case 0xff:
+ return 0;
+ default:
+ return 0;
}
}
-const char *
-DW_ATE_value_to_name (uint32_t val)
-{
+const char *DW_ATE_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::AttributeEncodingString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ATE constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::AttributeEncodingString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ATE constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_ACCESS_value_to_name (uint32_t val)
-{
+const char *DW_ACCESS_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::AccessibilityString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ACCESS constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::AccessibilityString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ACCESS constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_VIS_value_to_name (uint32_t val)
-{
+const char *DW_VIS_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::VisibilityString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_VIS constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::VisibilityString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_VIS constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_VIRTUALITY_value_to_name (uint32_t val)
-{
+const char *DW_VIRTUALITY_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::VirtualityString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_VIRTUALITY constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::VirtualityString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_VIRTUALITY constant: 0x%x",
+ val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_LANG_value_to_name (uint32_t val)
-{
+const char *DW_LANG_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::LanguageString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_LANG constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::LanguageString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_LANG constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_ID_value_to_name (uint32_t val)
-{
+const char *DW_ID_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::CaseString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ID constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::CaseString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ID constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_CC_value_to_name (uint32_t val)
-{
+const char *DW_CC_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::ConventionString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_CC constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::ConventionString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_CC constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_INL_value_to_name (uint32_t val)
-{
+const char *DW_INL_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::InlineCodeString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_INL constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::InlineCodeString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_INL constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_ORD_value_to_name (uint32_t val)
-{
+const char *DW_ORD_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::ArrayOrderString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ORD constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::ArrayOrderString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ORD constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_DSC_value_to_name (uint32_t val)
-{
+const char *DW_DSC_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::DiscriminantString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_DSC constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::DiscriminantString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_DSC constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_LNS_value_to_name (uint32_t val)
-{
+const char *DW_LNS_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::LNStandardString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_LNS constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::LNStandardString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_LNS constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_LNE_value_to_name (uint32_t val)
-{
+const char *DW_LNE_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::LNExtendedString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_LNE constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::LNExtendedString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_LNE constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_MACINFO_value_to_name (uint32_t val)
-{
+const char *DW_MACINFO_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::MacinfoString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_MACINFO constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::MacinfoString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_MACINFO constant: 0x%x",
+ val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-const char *
-DW_CFA_value_to_name (uint32_t val)
-{
+const char *DW_CFA_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::CallFrameString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_CFA constant: 0x%x", val);
- return invalid;
+ llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val);
+ return invalid;
}
- return llvmstr;
+ return llvmstr.data();
}
-DW_TAG_CategoryEnum
-get_tag_category (uint16_t tag)
-{
- switch (tag)
- {
- case DW_TAG_array_type : return TagCategoryType;
- case DW_TAG_class_type : return TagCategoryType;
- case DW_TAG_entry_point : return TagCategoryProgram;
- case DW_TAG_enumeration_type : return TagCategoryType;
- case DW_TAG_formal_parameter : return TagCategoryVariable;
- case DW_TAG_imported_declaration : return TagCategoryProgram;
- case DW_TAG_label : return TagCategoryProgram;
- case DW_TAG_lexical_block : return TagCategoryProgram;
- case DW_TAG_member : return TagCategoryType;
- case DW_TAG_pointer_type : return TagCategoryType;
- case DW_TAG_reference_type : return TagCategoryType;
- case DW_TAG_compile_unit : return TagCategoryProgram;
- case DW_TAG_string_type : return TagCategoryType;
- case DW_TAG_structure_type : return TagCategoryType;
- case DW_TAG_subroutine_type : return TagCategoryType;
- case DW_TAG_typedef : return TagCategoryType;
- case DW_TAG_union_type : return TagCategoryType;
- case DW_TAG_unspecified_parameters : return TagCategoryVariable;
- case DW_TAG_variant : return TagCategoryType;
- case DW_TAG_common_block : return TagCategoryProgram;
- case DW_TAG_common_inclusion : return TagCategoryProgram;
- case DW_TAG_inheritance : return TagCategoryType;
- case DW_TAG_inlined_subroutine : return TagCategoryProgram;
- case DW_TAG_module : return TagCategoryProgram;
- case DW_TAG_ptr_to_member_type : return TagCategoryType;
- case DW_TAG_set_type : return TagCategoryType;
- case DW_TAG_subrange_type : return TagCategoryType;
- case DW_TAG_with_stmt : return TagCategoryProgram;
- case DW_TAG_access_declaration : return TagCategoryProgram;
- case DW_TAG_base_type : return TagCategoryType;
- case DW_TAG_catch_block : return TagCategoryProgram;
- case DW_TAG_const_type : return TagCategoryType;
- case DW_TAG_constant : return TagCategoryVariable;
- case DW_TAG_enumerator : return TagCategoryType;
- case DW_TAG_file_type : return TagCategoryType;
- case DW_TAG_friend : return TagCategoryType;
- case DW_TAG_namelist : return TagCategoryVariable;
- case DW_TAG_namelist_item : return TagCategoryVariable;
- case DW_TAG_packed_type : return TagCategoryType;
- case DW_TAG_subprogram : return TagCategoryProgram;
- case DW_TAG_template_type_parameter : return TagCategoryType;
- case DW_TAG_template_value_parameter : return TagCategoryType;
- case DW_TAG_thrown_type : return TagCategoryType;
- case DW_TAG_try_block : return TagCategoryProgram;
- case DW_TAG_variant_part : return TagCategoryType;
- case DW_TAG_variable : return TagCategoryVariable;
- case DW_TAG_volatile_type : return TagCategoryType;
- case DW_TAG_dwarf_procedure : return TagCategoryProgram;
- case DW_TAG_restrict_type : return TagCategoryType;
- case DW_TAG_interface_type : return TagCategoryType;
- case DW_TAG_namespace : return TagCategoryProgram;
- case DW_TAG_imported_module : return TagCategoryProgram;
- case DW_TAG_unspecified_type : return TagCategoryType;
- case DW_TAG_partial_unit : return TagCategoryProgram;
- case DW_TAG_imported_unit : return TagCategoryProgram;
- case DW_TAG_shared_type : return TagCategoryType;
- default: break;
- }
+DW_TAG_CategoryEnum get_tag_category(uint16_t tag) {
+ switch (tag) {
+ case DW_TAG_array_type:
+ return TagCategoryType;
+ case DW_TAG_class_type:
+ return TagCategoryType;
+ case DW_TAG_entry_point:
+ return TagCategoryProgram;
+ case DW_TAG_enumeration_type:
+ return TagCategoryType;
+ case DW_TAG_formal_parameter:
+ return TagCategoryVariable;
+ case DW_TAG_imported_declaration:
+ return TagCategoryProgram;
+ case DW_TAG_label:
+ return TagCategoryProgram;
+ case DW_TAG_lexical_block:
+ return TagCategoryProgram;
+ case DW_TAG_member:
+ return TagCategoryType;
+ case DW_TAG_pointer_type:
+ return TagCategoryType;
+ case DW_TAG_reference_type:
+ return TagCategoryType;
+ case DW_TAG_compile_unit:
+ return TagCategoryProgram;
+ case DW_TAG_string_type:
+ return TagCategoryType;
+ case DW_TAG_structure_type:
+ return TagCategoryType;
+ case DW_TAG_subroutine_type:
+ return TagCategoryType;
+ case DW_TAG_typedef:
+ return TagCategoryType;
+ case DW_TAG_union_type:
+ return TagCategoryType;
+ case DW_TAG_unspecified_parameters:
+ return TagCategoryVariable;
+ case DW_TAG_variant:
+ return TagCategoryType;
+ case DW_TAG_common_block:
+ return TagCategoryProgram;
+ case DW_TAG_common_inclusion:
+ return TagCategoryProgram;
+ case DW_TAG_inheritance:
+ return TagCategoryType;
+ case DW_TAG_inlined_subroutine:
+ return TagCategoryProgram;
+ case DW_TAG_module:
+ return TagCategoryProgram;
+ case DW_TAG_ptr_to_member_type:
+ return TagCategoryType;
+ case DW_TAG_set_type:
+ return TagCategoryType;
+ case DW_TAG_subrange_type:
+ return TagCategoryType;
+ case DW_TAG_with_stmt:
return TagCategoryProgram;
+ case DW_TAG_access_declaration:
+ return TagCategoryProgram;
+ case DW_TAG_base_type:
+ return TagCategoryType;
+ case DW_TAG_catch_block:
+ return TagCategoryProgram;
+ case DW_TAG_const_type:
+ return TagCategoryType;
+ case DW_TAG_constant:
+ return TagCategoryVariable;
+ case DW_TAG_enumerator:
+ return TagCategoryType;
+ case DW_TAG_file_type:
+ return TagCategoryType;
+ case DW_TAG_friend:
+ return TagCategoryType;
+ case DW_TAG_namelist:
+ return TagCategoryVariable;
+ case DW_TAG_namelist_item:
+ return TagCategoryVariable;
+ case DW_TAG_packed_type:
+ return TagCategoryType;
+ case DW_TAG_subprogram:
+ return TagCategoryProgram;
+ case DW_TAG_template_type_parameter:
+ return TagCategoryType;
+ case DW_TAG_template_value_parameter:
+ return TagCategoryType;
+ case DW_TAG_thrown_type:
+ return TagCategoryType;
+ case DW_TAG_try_block:
+ return TagCategoryProgram;
+ case DW_TAG_variant_part:
+ return TagCategoryType;
+ case DW_TAG_variable:
+ return TagCategoryVariable;
+ case DW_TAG_volatile_type:
+ return TagCategoryType;
+ case DW_TAG_dwarf_procedure:
+ return TagCategoryProgram;
+ case DW_TAG_restrict_type:
+ return TagCategoryType;
+ case DW_TAG_interface_type:
+ return TagCategoryType;
+ case DW_TAG_namespace:
+ return TagCategoryProgram;
+ case DW_TAG_imported_module:
+ return TagCategoryProgram;
+ case DW_TAG_unspecified_type:
+ return TagCategoryType;
+ case DW_TAG_partial_unit:
+ return TagCategoryProgram;
+ case DW_TAG_imported_unit:
+ return TagCategoryProgram;
+ case DW_TAG_shared_type:
+ return TagCategoryType;
+ default:
+ break;
+ }
+ return TagCategoryProgram;
}
} // namespace lldb_private
-
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index d47e6a350c93..038f5706c060 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -10,106 +10,104 @@
#ifndef SymbolFileDWARF_DWARFDefines_h_
#define SymbolFileDWARF_DWARFDefines_h_
-#include <stdint.h>
#include "lldb/Core/dwarf.h"
+#include <stdint.h>
namespace lldb_private {
-typedef uint32_t DRC_class; // Holds DRC_* class bitfields
+typedef uint32_t DRC_class; // Holds DRC_* class bitfields
-enum DW_TAG_Category
-{
- TagCategoryVariable,
- TagCategoryType,
- TagCategoryProgram,
- kNumTagCategories
+enum DW_TAG_Category {
+ TagCategoryVariable,
+ TagCategoryType,
+ TagCategoryProgram,
+ kNumTagCategories
};
typedef enum DW_TAG_Category DW_TAG_CategoryEnum;
-const char *DW_TAG_value_to_name (uint32_t val);
+const char *DW_TAG_value_to_name(uint32_t val);
-DW_TAG_CategoryEnum get_tag_category (uint16_t tag);
+DW_TAG_CategoryEnum get_tag_category(uint16_t tag);
-const char *DW_CHILDREN_value_to_name (uint8_t val);
+const char *DW_CHILDREN_value_to_name(uint8_t val);
-const char *DW_AT_value_to_name (uint32_t val);
+const char *DW_AT_value_to_name(uint32_t val);
-const char *DW_FORM_value_to_name (uint32_t val);
+const char *DW_FORM_value_to_name(uint32_t val);
-const char *DW_OP_value_to_name (uint32_t val);
+const char *DW_OP_value_to_name(uint32_t val);
-DRC_class DW_OP_value_to_class (uint32_t val);
+DRC_class DW_OP_value_to_class(uint32_t val);
-const char *DW_ATE_value_to_name (uint32_t val);
+const char *DW_ATE_value_to_name(uint32_t val);
-const char *DW_ACCESS_value_to_name (uint32_t val);
+const char *DW_ACCESS_value_to_name(uint32_t val);
-const char *DW_VIS_value_to_name (uint32_t val);
+const char *DW_VIS_value_to_name(uint32_t val);
-const char *DW_VIRTUALITY_value_to_name (uint32_t val);
+const char *DW_VIRTUALITY_value_to_name(uint32_t val);
-const char *DW_LANG_value_to_name (uint32_t val);
+const char *DW_LANG_value_to_name(uint32_t val);
-const char *DW_ID_value_to_name (uint32_t val);
+const char *DW_ID_value_to_name(uint32_t val);
-const char *DW_CC_value_to_name (uint32_t val);
+const char *DW_CC_value_to_name(uint32_t val);
-const char *DW_INL_value_to_name (uint32_t val);
+const char *DW_INL_value_to_name(uint32_t val);
-const char *DW_ORD_value_to_name (uint32_t val);
+const char *DW_ORD_value_to_name(uint32_t val);
-const char *DW_DSC_value_to_name (uint32_t val);
+const char *DW_DSC_value_to_name(uint32_t val);
-const char *DW_LNS_value_to_name (uint32_t val);
+const char *DW_LNS_value_to_name(uint32_t val);
-const char *DW_LNE_value_to_name (uint32_t val);
+const char *DW_LNE_value_to_name(uint32_t val);
-const char *DW_MACINFO_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);
-const char *DW_GNU_EH_PE_value_to_name (uint32_t val);
+const char *DW_GNU_EH_PE_value_to_name(uint32_t val);
/* These DRC are entirely our own construction,
although they are derived from various comments in the DWARF standard.
Most of these are not useful to the parser, but the DW_AT and DW_FORM
classes should prove to be usable in some fashion. */
-#define DRC_0x65 0x1
-#define DRC_ADDRESS 0x2
-#define DRC_BLOCK 0x4
-#define DRC_CONSTANT 0x8
-#define DRC_DWARFv3 0x10
-#define DRC_FLAG 0x20
-#define DRC_INDIRECT_SPECIAL 0x40
-#define DRC_LINEPTR 0x80
-#define DRC_LOCEXPR 0x100
-#define DRC_LOCLISTPTR 0x200
-#define DRC_MACPTR 0x400
-#define DRC_ONEOPERAND 0x800
-#define DRC_OPERANDONE_1BYTE_DELTA 0x1000
-#define DRC_OPERANDONE_2BYTE_DELTA 0x2000
-#define DRC_OPERANDONE_4BYTE_DELTA 0x4000
-#define DRC_OPERANDONE_ADDRESS 0x8000
-#define DRC_OPERANDONE_BLOCK 0x10000
-#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000
-#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000
-#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000
-#define DRC_OPERANDTWO_BLOCK 0x100000
-#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000
-#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000
-#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000
-#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000
-#define DRC_RANGELISTPTR 0x2000000
-#define DRC_REFERENCE 0x4000000
-#define DRC_STRING 0x8000000
-#define DRC_TWOOPERANDS 0x10000000
-#define DRC_VENDOR_GNU 0x20000000
-#define DRC_VENDOR_MIPS 0x40000000
-#define DRC_ZEROOPERANDS 0x80000000
+#define DRC_0x65 0x1
+#define DRC_ADDRESS 0x2
+#define DRC_BLOCK 0x4
+#define DRC_CONSTANT 0x8
+#define DRC_DWARFv3 0x10
+#define DRC_FLAG 0x20
+#define DRC_INDIRECT_SPECIAL 0x40
+#define DRC_LINEPTR 0x80
+#define DRC_LOCEXPR 0x100
+#define DRC_LOCLISTPTR 0x200
+#define DRC_MACPTR 0x400
+#define DRC_ONEOPERAND 0x800
+#define DRC_OPERANDONE_1BYTE_DELTA 0x1000
+#define DRC_OPERANDONE_2BYTE_DELTA 0x2000
+#define DRC_OPERANDONE_4BYTE_DELTA 0x4000
+#define DRC_OPERANDONE_ADDRESS 0x8000
+#define DRC_OPERANDONE_BLOCK 0x10000
+#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000
+#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000
+#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000
+#define DRC_OPERANDTWO_BLOCK 0x100000
+#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000
+#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000
+#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000
+#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000
+#define DRC_RANGELISTPTR 0x2000000
+#define DRC_REFERENCE 0x4000000
+#define DRC_STRING 0x8000000
+#define DRC_TWOOPERANDS 0x10000000
+#define DRC_VENDOR_GNU 0x20000000
+#define DRC_VENDOR_MIPS 0x40000000
+#define DRC_ZEROOPERANDS 0x80000000
} // namespace lldb_private
-
-#endif // SymbolFileDWARF_DWARFDefines_h_
+#endif // SymbolFileDWARF_DWARFDefines_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index addc14858461..ad18c56b3300 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -9,19 +9,17 @@
#include <assert.h>
-#include "lldb/Core/dwarf.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Core/dwarf.h"
-#include "DWARFFormValue.h"
#include "DWARFCompileUnit.h"
+#include "DWARFFormValue.h"
class DWARFCompileUnit;
using namespace lldb_private;
-
-static uint8_t g_form_sizes_addr4[] =
-{
+static uint8_t g_form_sizes_addr4[] = {
0, // 0x00 unused
4, // 0x01 DW_FORM_addr
0, // 0x02 unused
@@ -38,7 +36,8 @@ static uint8_t g_form_sizes_addr4[] =
0, // 0x0d DW_FORM_sdata
4, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+ // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -58,9 +57,7 @@ static uint8_t g_form_sizes_addr4[] =
};
-static uint8_t
-g_form_sizes_addr8[] =
-{
+static uint8_t g_form_sizes_addr8[] = {
0, // 0x00 unused
8, // 0x01 DW_FORM_addr
0, // 0x02 unused
@@ -77,7 +74,8 @@ g_form_sizes_addr8[] =
0, // 0x0d DW_FORM_sdata
4, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+ // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -98,9 +96,7 @@ g_form_sizes_addr8[] =
// Difference with g_form_sizes_addr8:
// DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4
-static uint8_t
-g_form_sizes_addr8_dwarf64[] =
-{
+static uint8_t g_form_sizes_addr8_dwarf64[] = {
0, // 0x00 unused
8, // 0x01 DW_FORM_addr
0, // 0x02 unused
@@ -117,7 +113,8 @@ g_form_sizes_addr8_dwarf64[] =
0, // 0x0d DW_FORM_sdata
8, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+ // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -137,552 +134,612 @@ g_form_sizes_addr8_dwarf64[] =
};
DWARFFormValue::FixedFormSizes
-DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64)
-{
- if (!is_dwarf64) {
- switch (addr_size)
- {
- case 4: return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
- case 8: return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
- }
- } else {
- if (addr_size == 8)
- return FixedFormSizes(g_form_sizes_addr8_dwarf64, sizeof(g_form_sizes_addr8_dwarf64));
- // is_dwarf64 && addr_size == 4 : no provider does this.
+DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
+ bool is_dwarf64) {
+ if (!is_dwarf64) {
+ switch (addr_size) {
+ case 4:
+ return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
+ case 8:
+ return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
}
- return FixedFormSizes();
-}
-
-DWARFFormValue::DWARFFormValue() :
- m_cu (NULL),
- m_form(0),
- m_value()
-{
-}
-
-DWARFFormValue::DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form) :
- m_cu (cu),
- m_form(form),
- m_value()
-{
-}
-
-void
-DWARFFormValue::Clear()
-{
- m_cu = nullptr;
- m_form = 0;
- memset(&m_value, 0, sizeof(m_value));
+ } else {
+ if (addr_size == 8)
+ return FixedFormSizes(g_form_sizes_addr8_dwarf64,
+ sizeof(g_form_sizes_addr8_dwarf64));
+ // is_dwarf64 && addr_size == 4 : no provider does this.
+ }
+ return FixedFormSizes();
}
-bool
-DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr)
-{
- bool indirect = false;
- bool is_block = false;
- m_value.data = NULL;
- uint8_t ref_addr_size;
- // Read the value for the form into value and follow and DW_FORM_indirect instances we run into
- do
- {
- indirect = false;
- switch (m_form)
- {
- case DW_FORM_addr: assert(m_cu);
- m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu)); break;
- case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break;
- case DW_FORM_block4: 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); 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); break;
- case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break;
- case DW_FORM_strp: assert(m_cu);
- m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::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_ref1: m_value.value.uval = data.GetU8(offset_ptr); break;
- case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break;
- case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break;
- case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break;
- case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); 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, DWARFCompileUnit::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);
-
- if (is_block)
- {
- m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
- if (m_value.data != NULL)
- {
- *offset_ptr += m_value.value.uval;
- }
- }
+DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
- return true;
-}
+DWARFFormValue::DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form)
+ : m_cu(cu), m_form(form), m_value() {}
-bool
-DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const
-{
- return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
+void DWARFFormValue::Clear() {
+ m_cu = nullptr;
+ m_form = 0;
+ memset(&m_value, 0, sizeof(m_value));
}
-bool
-DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu)
-{
- uint8_t ref_addr_size;
- switch (form)
- {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
- case DW_FORM_exprloc:
- case DW_FORM_block: { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true;
- case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); *offset_ptr += size; } return true;
- case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); *offset_ptr += size; } return true;
- case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); *offset_ptr += size; } return true;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string:
- debug_info_data.GetCStr(offset_ptr);
- return true;
-
- // Compile unit address sized values
+bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ bool indirect = false;
+ bool is_block = false;
+ m_value.data = NULL;
+ uint8_t ref_addr_size;
+ // Read the value for the form into value and follow and DW_FORM_indirect
+ // instances we run into
+ do {
+ indirect = false;
+ switch (m_form) {
case DW_FORM_addr:
- *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
- return true;
-
- case DW_FORM_ref_addr:
- ref_addr_size = 4;
- assert (cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong
- if (cu->GetVersion() <= 2)
- ref_addr_size = cu->GetAddressByteSize();
- else
- ref_addr_size = cu->IsDWARF64() ? 8 : 4;
- *offset_ptr += ref_addr_size;
- return true;
-
- // 0 bytes values (implied from DW_FORM)
- case DW_FORM_flag_present:
- return true;
-
- // 1 byte values
+ assert(m_cu);
+ m_value.value.uval = data.GetMaxU64(
+ offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu));
+ break;
+ case DW_FORM_block2:
+ m_value.value.uval = data.GetU16(offset_ptr);
+ is_block = true;
+ break;
+ case DW_FORM_block4:
+ 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);
+ 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);
+ break;
+ case DW_FORM_sdata:
+ m_value.value.sval = data.GetSLEB128(offset_ptr);
+ break;
+ case DW_FORM_strp:
+ assert(m_cu);
+ m_value.value.uval =
+ data.GetMaxU64(offset_ptr, DWARFCompileUnit::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_ref1:
- *offset_ptr += 1;
- return true;
-
- // 2 byte values
- case DW_FORM_data2:
+ m_value.value.uval = data.GetU8(offset_ptr);
+ break;
case DW_FORM_ref2:
- *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;
-
- // 4 byte values
- case DW_FORM_data4:
+ m_value.value.uval = data.GetU16(offset_ptr);
+ break;
case DW_FORM_ref4:
- *offset_ptr += 4;
- return true;
-
- // 8 byte values
- case DW_FORM_data8:
+ m_value.value.uval = data.GetU32(offset_ptr);
+ break;
case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- *offset_ptr += 8;
- return true;
-
- // signed or unsigned LEB 128 values
- case DW_FORM_sdata:
- case DW_FORM_udata:
+ m_value.value.uval = data.GetU64(offset_ptr);
+ break;
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;
-
+ m_value.value.uval = data.GetULEB128(offset_ptr);
+ break;
case DW_FORM_indirect:
- {
- dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
- return DWARFFormValue::SkipValue (indirect_form,
- debug_info_data,
- offset_ptr,
- cu);
- }
+ 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, DWARFCompileUnit::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:
- break;
+ return false;
+ break;
}
- return false;
-}
+ } while (indirect);
+ if (is_block) {
+ m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
+ if (m_value.data != NULL) {
+ *offset_ptr += m_value.value.uval;
+ }
+ }
-void
-DWARFFormValue::Dump(Stream &s) const
-{
- uint64_t uvalue = Unsigned();
- bool cu_relative_offset = false;
+ return true;
+}
- bool verbose = s.GetVerbose();
+bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr) const {
+ return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
+}
- switch (m_form)
- {
- case DW_FORM_addr: s.Address(uvalue, sizeof (uint64_t)); break;
- case DW_FORM_flag:
- case DW_FORM_data1: s.PutHex8(uvalue); break;
- case DW_FORM_data2: s.PutHex16(uvalue); break;
- case DW_FORM_sec_offset:
- case DW_FORM_data4: s.PutHex32(uvalue); break;
- case DW_FORM_ref_sig8:
- case DW_FORM_data8: s.PutHex64(uvalue); break;
- case DW_FORM_string: s.QuotedCString(AsCString()); break;
- case DW_FORM_exprloc:
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- if (uvalue > 0)
- {
- switch (m_form)
- {
- case DW_FORM_exprloc:
- case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break;
- case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break;
- case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break;
- case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break;
- default: break;
- }
-
- const uint8_t* data_ptr = m_value.data;
- if (data_ptr)
- {
- const uint8_t* end_data_ptr = data_ptr + uvalue; // uvalue contains size of block
- while (data_ptr < end_data_ptr)
- {
- s.Printf("%2.2x ", *data_ptr);
- ++data_ptr;
- }
- }
- else
- s.PutCString("NULL");
- }
- break;
+bool DWARFFormValue::SkipValue(dw_form_t form,
+ const DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr,
+ const DWARFCompileUnit *cu) {
+ uint8_t ref_addr_size;
+ switch (form) {
+ // Blocks if inlined data that have a length field and the data bytes
+ // inlined in the .debug_info
+ case DW_FORM_exprloc:
+ case DW_FORM_block: {
+ dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
+ case DW_FORM_block1: {
+ dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
+ case DW_FORM_block2: {
+ dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
+ case DW_FORM_block4: {
+ dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
- case DW_FORM_sdata: s.PutSLEB128(uvalue); break;
- case DW_FORM_udata: s.PutULEB128(uvalue); break;
- case DW_FORM_strp:
- {
- const char* dbg_str = AsCString();
- if (dbg_str)
- {
- if (verbose)
- s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
- s.QuotedCString(dbg_str);
- }
- else
- {
- s.PutHex32(uvalue);
- }
- }
- break;
+ // Inlined NULL terminated C-strings
+ case DW_FORM_string:
+ debug_info_data.GetCStr(offset_ptr);
+ return true;
- case DW_FORM_ref_addr:
- {
- assert (m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong
- if (m_cu->GetVersion() <= 2)
- s.Address(uvalue, sizeof (uint64_t) * 2);
- else
- s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
- break;
- }
- case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
- case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
- case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
- case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break;
- case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break;
-
- // All DW_FORM_indirect attributes should be resolved prior to calling this function
- case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break;
- case DW_FORM_flag_present: break;
- default:
- s.Printf("DW_FORM(0x%4.4x)", m_form);
- break;
- }
+ // Compile unit address sized values
+ case DW_FORM_addr:
+ *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
+ return true;
- if (cu_relative_offset)
- {
- assert (m_cu); // CU must be valid for DW_FORM_ref forms that are compile unit relative or we will get this wrong
- if (verbose)
- s.PutCString(" => ");
+ case DW_FORM_ref_addr:
+ ref_addr_size = 4;
+ assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get
+ // this wrong
+ if (cu->GetVersion() <= 2)
+ ref_addr_size = cu->GetAddressByteSize();
+ else
+ ref_addr_size = cu->IsDWARF64() ? 8 : 4;
+ *offset_ptr += ref_addr_size;
+ return true;
- s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
- }
-}
+ // 0 bytes values (implied from DW_FORM)
+ case DW_FORM_flag_present:
+ return true;
-const char*
-DWARFFormValue::AsCString() const
-{
- SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF();
+ // 1 byte values
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ *offset_ptr += 1;
+ return true;
- if (m_form == DW_FORM_string)
- {
- return m_value.value.cstr;
- }
- else if (m_form == DW_FORM_strp)
- {
- if (!symbol_file)
- return nullptr;
+ // 2 byte values
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ *offset_ptr += 2;
+ return true;
- return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
- }
- else if (m_form == DW_FORM_GNU_str_index)
- {
- if (!symbol_file)
- return nullptr;
-
- uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
- lldb::offset_t offset = m_value.value.uval * index_size;
- dw_offset_t str_offset = symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, index_size);
- return symbol_file->get_debug_str_data().PeekCStr(str_offset);
- }
- return nullptr;
-}
+ // 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;
-dw_addr_t
-DWARFFormValue::Address() const
-{
- SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF();
+ // 4 byte values
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ *offset_ptr += 4;
+ return true;
- if (m_form == DW_FORM_addr)
- return Unsigned();
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ *offset_ptr += 8;
+ return true;
- assert(m_cu);
- assert(m_form == DW_FORM_GNU_addr_index);
+ // 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;
- if (!symbol_file)
- return 0;
+ case DW_FORM_indirect: {
+ dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
+ return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr,
+ cu);
+ }
- uint32_t index_size = m_cu->GetAddressByteSize();
- dw_offset_t addr_base = m_cu->GetAddrBase();
- lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
- return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
+ default:
+ break;
+ }
+ return false;
}
-uint64_t
-DWARFFormValue::Reference() const
-{
- uint64_t die_offset = 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:
- 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();
+void DWARFFormValue::Dump(Stream &s) const {
+ uint64_t uvalue = Unsigned();
+ bool cu_relative_offset = false;
+
+ bool verbose = s.GetVerbose();
+
+ switch (m_form) {
+ case DW_FORM_addr:
+ s.Address(uvalue, sizeof(uint64_t));
+ break;
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ s.PutHex8(uvalue);
+ break;
+ case DW_FORM_data2:
+ s.PutHex16(uvalue);
+ break;
+ case DW_FORM_sec_offset:
+ case DW_FORM_data4:
+ s.PutHex32(uvalue);
+ break;
+ case DW_FORM_ref_sig8:
+ case DW_FORM_data8:
+ s.PutHex64(uvalue);
+ break;
+ case DW_FORM_string:
+ s.QuotedCString(AsCString());
+ break;
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ if (uvalue > 0) {
+ switch (m_form) {
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ s.Printf("<0x%" PRIx64 "> ", uvalue);
break;
-
- default:
+ case DW_FORM_block1:
+ s.Printf("<0x%2.2x> ", (uint8_t)uvalue);
+ break;
+ case DW_FORM_block2:
+ s.Printf("<0x%4.4x> ", (uint16_t)uvalue);
break;
+ case DW_FORM_block4:
+ s.Printf("<0x%8.8x> ", (uint32_t)uvalue);
+ break;
+ default:
+ break;
+ }
+
+ const uint8_t *data_ptr = m_value.data;
+ if (data_ptr) {
+ const uint8_t *end_data_ptr =
+ data_ptr + uvalue; // uvalue contains size of block
+ while (data_ptr < end_data_ptr) {
+ s.Printf("%2.2x ", *data_ptr);
+ ++data_ptr;
+ }
+ } else
+ s.PutCString("NULL");
}
-
- return die_offset;
-}
-
-uint64_t
-DWARFFormValue::Reference (dw_offset_t base_offset) const
-{
- uint64_t die_offset = 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;
-
- default:
- break;
+ break;
+
+ case DW_FORM_sdata:
+ s.PutSLEB128(uvalue);
+ break;
+ case DW_FORM_udata:
+ s.PutULEB128(uvalue);
+ break;
+ case DW_FORM_strp: {
+ const char *dbg_str = AsCString();
+ if (dbg_str) {
+ if (verbose)
+ s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
+ s.QuotedCString(dbg_str);
+ } else {
+ s.PutHex32(uvalue);
}
-
- return die_offset;
+ } break;
+
+ case DW_FORM_ref_addr: {
+ assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will
+ // get this wrong
+ if (m_cu->GetVersion() <= 2)
+ s.Address(uvalue, sizeof(uint64_t) * 2);
+ else
+ s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
+ // support DWARF64 yet
+ break;
+ }
+ case DW_FORM_ref1:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%2.2x", (uint8_t)uvalue);
+ break;
+ case DW_FORM_ref2:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%4.4x", (uint16_t)uvalue);
+ break;
+ case DW_FORM_ref4:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%4.4x", (uint32_t)uvalue);
+ break;
+ case DW_FORM_ref8:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%8.8" PRIx64, uvalue);
+ break;
+ case DW_FORM_ref_udata:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%" PRIx64, uvalue);
+ break;
+
+ // All DW_FORM_indirect attributes should be resolved prior to calling this
+ // function
+ case DW_FORM_indirect:
+ s.PutCString("DW_FORM_indirect");
+ break;
+ case DW_FORM_flag_present:
+ break;
+ default:
+ s.Printf("DW_FORM(0x%4.4x)", m_form);
+ break;
+ }
+
+ if (cu_relative_offset) {
+ assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
+ // unit relative or we will get this wrong
+ if (verbose)
+ s.PutCString(" => ");
+
+ s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
+ }
}
+const char *DWARFFormValue::AsCString() const {
+ SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
+
+ if (m_form == DW_FORM_string) {
+ return m_value.value.cstr;
+ } else if (m_form == DW_FORM_strp) {
+ if (!symbol_file)
+ return nullptr;
-const uint8_t*
-DWARFFormValue::BlockData() const
-{
- return m_value.data;
+ return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
+ } else if (m_form == DW_FORM_GNU_str_index) {
+ if (!symbol_file)
+ return nullptr;
+
+ uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
+ lldb::offset_t offset = m_value.value.uval * index_size;
+ dw_offset_t str_offset =
+ symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
+ index_size);
+ return symbol_file->get_debug_str_data().PeekCStr(str_offset);
+ }
+ return nullptr;
}
+dw_addr_t DWARFFormValue::Address() const {
+ SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
-bool
-DWARFFormValue::IsBlockForm(const dw_form_t form)
-{
- switch (form)
- {
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- return true;
- }
- return false;
-}
+ if (m_form == DW_FORM_addr)
+ return Unsigned();
-bool
-DWARFFormValue::IsDataForm(const dw_form_t form)
-{
- switch (form)
- {
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_data1:
- case DW_FORM_data2:
- case DW_FORM_data4:
- case DW_FORM_data8:
- return true;
- }
- return false;
-}
+ assert(m_cu);
+ assert(m_form == DW_FORM_GNU_addr_index);
-int
-DWARFFormValue::Compare (const DWARFFormValue& a_value,
- const DWARFFormValue& b_value)
-{
- dw_form_t a_form = a_value.Form();
- dw_form_t b_form = b_value.Form();
- if (a_form < b_form)
- return -1;
- if (a_form > b_form)
- return 1;
- switch (a_form)
- {
- case DW_FORM_addr:
- case DW_FORM_flag:
- case DW_FORM_data1:
- case DW_FORM_data2:
- case DW_FORM_data4:
- case DW_FORM_data8:
- case DW_FORM_udata:
- case DW_FORM_ref_addr:
- case DW_FORM_sec_offset:
- case DW_FORM_flag_present:
- case DW_FORM_ref_sig8:
- case DW_FORM_GNU_addr_index:
- {
- uint64_t a = a_value.Unsigned();
- uint64_t b = b_value.Unsigned();
- if (a < b)
- return -1;
- if (a > b)
- return 1;
- return 0;
- }
+ if (!symbol_file)
+ return 0;
- case DW_FORM_sdata:
- {
- int64_t a = a_value.Signed();
- int64_t b = b_value.Signed();
- if (a < b)
- return -1;
- if (a > b)
- return 1;
- return 0;
- }
+ uint32_t index_size = m_cu->GetAddressByteSize();
+ dw_offset_t addr_base = m_cu->GetAddrBase();
+ lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
+ return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
+}
- case DW_FORM_string:
- case DW_FORM_strp:
- case DW_FORM_GNU_str_index:
- {
- const char *a_string = a_value.AsCString();
- const char *b_string = b_value.AsCString();
- if (a_string == b_string)
- return 0;
- else if (a_string && b_string)
- return strcmp(a_string, b_string);
- else if (a_string == NULL)
- return -1; // A string is NULL, and B is valid
- else
- return 1; // A string valid, and B is NULL
- }
+uint64_t DWARFFormValue::Reference() const {
+ uint64_t die_offset = 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:
+ 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;
+
+ default:
+ break;
+ }
+
+ return die_offset;
+}
+uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
+ uint64_t die_offset = 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;
+
+ default:
+ break;
+ }
+
+ return die_offset;
+}
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- case DW_FORM_exprloc:
- {
- uint64_t a_len = a_value.Unsigned();
- uint64_t b_len = b_value.Unsigned();
- if (a_len < b_len)
- return -1;
- if (a_len > b_len)
- return 1;
- // The block lengths are the same
- return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
- }
- break;
+const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- {
- uint64_t a = a_value.Reference();
- uint64_t b = b_value.Reference();
- if (a < b)
- return -1;
- if (a > b)
- return 1;
- return 0;
- }
+bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
+ switch (form) {
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ return true;
+ }
+ return false;
+}
- case DW_FORM_indirect:
- assert(!"This shouldn't happen after the form has been extracted...");
- break;
+bool DWARFFormValue::IsDataForm(const dw_form_t form) {
+ switch (form) {
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ return true;
+ }
+ return false;
+}
- default:
- assert(!"Unhandled DW_FORM");
- break;
- }
+int DWARFFormValue::Compare(const DWARFFormValue &a_value,
+ const DWARFFormValue &b_value) {
+ dw_form_t a_form = a_value.Form();
+ dw_form_t b_form = b_value.Form();
+ if (a_form < b_form)
return -1;
+ if (a_form > b_form)
+ return 1;
+ switch (a_form) {
+ case DW_FORM_addr:
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_udata:
+ case DW_FORM_ref_addr:
+ case DW_FORM_sec_offset:
+ case DW_FORM_flag_present:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_GNU_addr_index: {
+ uint64_t a = a_value.Unsigned();
+ uint64_t b = b_value.Unsigned();
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ case DW_FORM_sdata: {
+ int64_t a = a_value.Signed();
+ int64_t b = b_value.Signed();
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_str_index: {
+ const char *a_string = a_value.AsCString();
+ const char *b_string = b_value.AsCString();
+ if (a_string == b_string)
+ return 0;
+ else if (a_string && b_string)
+ return strcmp(a_string, b_string);
+ else if (a_string == NULL)
+ return -1; // A string is NULL, and B is valid
+ else
+ return 1; // A string valid, and B is NULL
+ }
+
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_exprloc: {
+ uint64_t a_len = a_value.Unsigned();
+ uint64_t b_len = b_value.Unsigned();
+ if (a_len < b_len)
+ return -1;
+ if (a_len > b_len)
+ return 1;
+ // The block lengths are the same
+ return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
+ } break;
+
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata: {
+ uint64_t a = a_value.Reference();
+ uint64_t b = b_value.Reference();
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ case DW_FORM_indirect:
+ assert(!"This shouldn't happen after the form has been extracted...");
+ break;
+
+ default:
+ assert(!"Unhandled DW_FORM");
+ break;
+ }
+ return -1;
}
-
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 07bd038d9486..8d6af3d65b33 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -10,103 +10,87 @@
#ifndef SymbolFileDWARF_DWARFFormValue_h_
#define SymbolFileDWARF_DWARFFormValue_h_
-#include <stddef.h> // for NULL
#include "DWARFDataExtractor.h"
+#include <stddef.h> // for NULL
class DWARFCompileUnit;
-class DWARFFormValue
-{
+class DWARFFormValue {
public:
- typedef struct ValueTypeTag
- {
- ValueTypeTag() :
- value(),
- data(NULL)
- {
- value.uval = 0;
- }
+ typedef struct ValueTypeTag {
+ ValueTypeTag() : value(), data(NULL) { value.uval = 0; }
+
+ union {
+ uint64_t uval;
+ int64_t sval;
+ const char *cstr;
+ } value;
+ const uint8_t *data;
+ } ValueType;
- union
- {
- uint64_t uval;
- int64_t sval;
- const char* cstr;
- } value;
- const uint8_t* data;
- } ValueType;
-
- class FixedFormSizes
- {
- public:
- FixedFormSizes() :
- m_fix_sizes(nullptr), m_size(0)
- {}
+ class FixedFormSizes {
+ public:
+ FixedFormSizes() : m_fix_sizes(nullptr), m_size(0) {}
- FixedFormSizes(const uint8_t* fix_sizes, size_t size) :
- m_fix_sizes(fix_sizes), m_size(size)
- {}
+ FixedFormSizes(const uint8_t *fix_sizes, size_t size)
+ : m_fix_sizes(fix_sizes), m_size(size) {}
- uint8_t
- GetSize(uint32_t index) const
- {
- return index < m_size ? m_fix_sizes[index] : 0;
- }
+ uint8_t GetSize(uint32_t index) const {
+ return index < m_size ? m_fix_sizes[index] : 0;
+ }
- bool
- Empty() const
- {
- return m_size == 0;
- }
+ bool Empty() const { return m_size == 0; }
- private:
- const uint8_t* m_fix_sizes;
- size_t m_size;
- };
+ private:
+ const uint8_t *m_fix_sizes;
+ size_t m_size;
+ };
- enum
- {
- eValueTypeInvalid = 0,
- eValueTypeUnsigned,
- eValueTypeSigned,
- eValueTypeCStr,
- eValueTypeBlock
- };
+ enum {
+ eValueTypeInvalid = 0,
+ eValueTypeUnsigned,
+ eValueTypeSigned,
+ eValueTypeCStr,
+ eValueTypeBlock
+ };
+
+ DWARFFormValue();
+ DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form);
+ const DWARFCompileUnit *GetCompileUnit() const { return m_cu; }
+ void SetCompileUnit(const DWARFCompileUnit *cu) { m_cu = cu; }
+ dw_form_t Form() const { return m_form; }
+ void SetForm(dw_form_t form) { m_form = form; }
+ const ValueType &Value() const { return m_value; }
+ void Dump(lldb_private::Stream &s) const;
+ bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+ const uint8_t *BlockData() const;
+ uint64_t Reference() const;
+ uint64_t Reference(dw_offset_t offset) const;
+ bool Boolean() const { return m_value.value.uval != 0; }
+ uint64_t Unsigned() const { return m_value.value.uval; }
+ void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
+ int64_t Signed() const { return m_value.value.sval; }
+ void SetSigned(int64_t sval) { m_value.value.sval = sval; }
+ const char *AsCString() const;
+ dw_addr_t Address() const;
+ bool IsValid() const { return m_form != 0; }
+ bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr) const;
+ static bool SkipValue(const dw_form_t form,
+ const lldb_private::DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr, const DWARFCompileUnit *cu);
+ static bool IsBlockForm(const dw_form_t form);
+ static bool IsDataForm(const dw_form_t form);
+ static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size,
+ bool is_dwarf64);
+ static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
+ void Clear();
- DWARFFormValue();
- DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form);
- const DWARFCompileUnit* GetCompileUnit () const { return m_cu; }
- void SetCompileUnit (const DWARFCompileUnit* cu) { m_cu = cu; }
- dw_form_t Form() const { return m_form; }
- void SetForm(dw_form_t form) { m_form = form; }
- const ValueType& Value() const { return m_value; }
- void Dump(lldb_private::Stream &s) const;
- bool ExtractValue(const lldb_private::DWARFDataExtractor& data,
- lldb::offset_t* offset_ptr);
- const uint8_t* BlockData() const;
- uint64_t Reference() const;
- uint64_t Reference (dw_offset_t offset) const;
- bool Boolean() const { return m_value.value.uval != 0; }
- uint64_t Unsigned() const { return m_value.value.uval; }
- void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
- int64_t Signed() const { return m_value.value.sval; }
- void SetSigned(int64_t sval) { m_value.value.sval = sval; }
- const char* AsCString() const;
- dw_addr_t Address() const;
- bool IsValid() const { return m_form != 0; }
- bool SkipValue(const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const;
- static bool SkipValue(const dw_form_t form, const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu);
- static bool IsBlockForm(const dw_form_t form);
- static bool IsDataForm(const dw_form_t form);
- static FixedFormSizes GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64);
- static int Compare (const DWARFFormValue& a,
- const DWARFFormValue& b);
- void Clear();
protected:
- const DWARFCompileUnit* m_cu; // Compile unit for this form
- dw_form_t m_form; // Form for this value
- ValueType m_value; // Contains all data for the form
+ const DWARFCompileUnit *m_cu; // Compile unit for this form
+ dw_form_t m_form; // Form for this value
+ ValueType m_value; // Contains all data for the form
};
-
-#endif // SymbolFileDWARF_DWARFFormValue_h_
+#endif // SymbolFileDWARF_DWARFFormValue_h_
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 12e1e89c36bd..afdb1d6afed3 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -8,747 +8,637 @@
//===----------------------------------------------------------------------===//
#include "HashedNameToDIE.h"
-
-void
-DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets)
-{
+#include "llvm/ADT/StringRef.h"
+
+void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
+ DIEArray &die_offsets) {
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+}
+
+void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ DIEArray &die_offsets) {
+ if (tag == 0) {
+ ExtractDIEArray(die_info_array, die_offsets);
+ } else {
const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
-}
-
-void
-DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- DIEArray &die_offsets)
-{
- if (tag == 0)
- {
- ExtractDIEArray (die_info_array, die_offsets);
- }
- else
- {
- const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches)
- {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- }
+ for (size_t i = 0; i < count; ++i) {
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches) {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches =
+ tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
}
+ }
}
-void
-DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets)
-{
- if (tag == 0)
- {
- ExtractDIEArray (die_info_array, die_offsets);
- }
- else
- {
- const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- if (qualified_name_hash != die_info_array[i].qualified_name_hash)
- continue;
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches)
- {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- }
- }
-}
-
-void
-DWARFMappedHash::ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
- bool return_implementation_only_if_available,
- DIEArray &die_offsets)
-{
+void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets) {
+ if (tag == 0) {
+ ExtractDIEArray(die_info_array, die_offsets);
+ } else {
const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- const dw_tag_t die_tag = die_info_array[i].tag;
- if (die_tag == 0 || die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- {
- if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation)
- {
- if (return_implementation_only_if_available)
- {
- // We found the one true definition for this class, so
- // only return that
- die_offsets.clear();
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- return;
- }
- else
- {
- // Put the one true definition as the first entry so it
- // matches first
- die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset, die_info_array[i].offset);
- }
- }
- else
- {
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- }
- }
+ for (size_t i = 0; i < count; ++i) {
+ if (qualified_name_hash != die_info_array[i].qualified_name_hash)
+ continue;
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches) {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches =
+ tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
}
-}
-
-void
-DWARFMappedHash::ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array,
- uint32_t type_flag_mask,
- uint32_t type_flag_value,
- DIEArray &die_offsets)
-{
- const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
+ }
+}
+
+void DWARFMappedHash::ExtractClassOrStructDIEArray(
+ const DIEInfoArray &die_info_array,
+ bool return_implementation_only_if_available, DIEArray &die_offsets) {
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i) {
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ if (die_tag == 0 || die_tag == DW_TAG_class_type ||
+ die_tag == DW_TAG_structure_type) {
+ if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) {
+ if (return_implementation_only_if_available) {
+ // We found the one true definition for this class, so
+ // only return that
+ die_offsets.clear();
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ return;
+ } else {
+ // Put the one true definition as the first entry so it
+ // matches first
+ die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
+ } else {
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
}
+ }
+}
+
+void DWARFMappedHash::ExtractTypesFromDIEArray(
+ const DIEInfoArray &die_info_array, uint32_t type_flag_mask,
+ uint32_t type_flag_value, DIEArray &die_offsets) {
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i) {
+ if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
+}
+
+const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) {
+ switch (atom) {
+ case eAtomTypeNULL:
+ return "NULL";
+ case eAtomTypeDIEOffset:
+ return "die-offset";
+ case eAtomTypeCUOffset:
+ return "cu-offset";
+ case eAtomTypeTag:
+ return "die-tag";
+ case eAtomTypeNameFlags:
+ return "name-flags";
+ case eAtomTypeTypeFlags:
+ return "type-flags";
+ case eAtomTypeQualNameHash:
+ return "qualified-name-hash";
+ }
+ return "<invalid>";
+}
+
+DWARFMappedHash::DIEInfo::DIEInfo()
+ : cu_offset(DW_INVALID_OFFSET), offset(DW_INVALID_OFFSET), tag(0),
+ type_flags(0), qualified_name_hash(0) {}
+
+DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t,
+ uint32_t f, uint32_t h)
+ : cu_offset(c), offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
+
+DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
+ : die_base_offset(_die_base_offset), atoms(), atom_mask(0),
+ min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
+ // Define an array of DIE offsets by first defining an array,
+ // and then define the atom type for the array, in this case
+ // we have an array of DIE offsets
+ AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
+}
+
+void DWARFMappedHash::Prologue::ClearAtoms() {
+ hash_data_has_fixed_byte_size = true;
+ min_hash_data_byte_size = 0;
+ atom_mask = 0;
+ atoms.clear();
+}
+
+bool DWARFMappedHash::Prologue::ContainsAtom(AtomType atom_type) const {
+ return (atom_mask & (1u << atom_type)) != 0;
+}
+
+void DWARFMappedHash::Prologue::Clear() {
+ die_base_offset = 0;
+ ClearAtoms();
+}
+
+void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) {
+ atoms.push_back({type, form});
+ atom_mask |= 1u << type;
+ switch (form) {
+ case DW_FORM_indirect:
+ case DW_FORM_exprloc:
+ case DW_FORM_flag_present:
+ case DW_FORM_ref_sig8:
+ assert(!"Unhandled atom form");
+ break;
+
+ case DW_FORM_string:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ 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:
+ hash_data_has_fixed_byte_size = false;
+ LLVM_FALLTHROUGH;
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_sec_offset:
+ min_hash_data_byte_size += 1;
+ break;
+
+ case DW_FORM_block2:
+ hash_data_has_fixed_byte_size = false;
+ LLVM_FALLTHROUGH;
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ min_hash_data_byte_size += 2;
+ break;
+
+ case DW_FORM_block4:
+ hash_data_has_fixed_byte_size = false;
+ LLVM_FALLTHROUGH;
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ case DW_FORM_strp:
+ min_hash_data_byte_size += 4;
+ break;
+
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ min_hash_data_byte_size += 8;
+ break;
+ }
}
-const char *
-DWARFMappedHash::GetAtomTypeName (uint16_t atom)
-{
- switch (atom)
- {
- case eAtomTypeNULL: return "NULL";
- case eAtomTypeDIEOffset: return "die-offset";
- case eAtomTypeCUOffset: return "cu-offset";
- case eAtomTypeTag: return "die-tag";
- case eAtomTypeNameFlags: return "name-flags";
- case eAtomTypeTypeFlags: return "type-flags";
- case eAtomTypeQualNameHash: return "qualified-name-hash";
+lldb::offset_t
+DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
+ lldb::offset_t offset) {
+ ClearAtoms();
+
+ die_base_offset = data.GetU32(&offset);
+
+ const uint32_t atom_count = data.GetU32(&offset);
+ if (atom_count == 0x00060003u) {
+ // Old format, deal with contents of old pre-release format
+ while (data.GetU32(&offset))
+ /* do nothing */;
+
+ // Hardcode to the only known value for now.
+ AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
+ } else {
+ for (uint32_t i = 0; i < atom_count; ++i) {
+ AtomType type = (AtomType)data.GetU16(&offset);
+ dw_form_t form = (dw_form_t)data.GetU16(&offset);
+ AppendAtom(type, form);
}
- return "<invalid>";
+ }
+ return offset;
}
-DWARFMappedHash::DIEInfo::DIEInfo () :
- cu_offset (DW_INVALID_OFFSET),
- offset (DW_INVALID_OFFSET),
- tag (0),
- type_flags (0),
- qualified_name_hash (0)
-{
+size_t DWARFMappedHash::Prologue::GetByteSize() const {
+ // Add an extra count to the atoms size for the zero termination Atom that
+ // gets
+ // written to disk
+ return sizeof(die_base_offset) + sizeof(uint32_t) +
+ atoms.size() * sizeof(Atom);
}
-DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t c,
- dw_offset_t o,
- dw_tag_t t,
- uint32_t f,
- uint32_t h) :
- cu_offset (c),
- offset (o),
- tag (t),
- type_flags (f),
- qualified_name_hash (h)
-{
+size_t DWARFMappedHash::Prologue::GetMinimumHashDataByteSize() const {
+ return min_hash_data_byte_size;
}
-DWARFMappedHash::Prologue::Prologue (dw_offset_t _die_base_offset) :
- die_base_offset (_die_base_offset),
- atoms(),
- atom_mask (0),
- min_hash_data_byte_size(0),
- hash_data_has_fixed_byte_size(true)
-{
- // Define an array of DIE offsets by first defining an array,
- // and then define the atom type for the array, in this case
- // we have an array of DIE offsets
- AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
+bool DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const {
+ return hash_data_has_fixed_byte_size;
}
-void
-DWARFMappedHash::Prologue::ClearAtoms ()
-{
- hash_data_has_fixed_byte_size = true;
- min_hash_data_byte_size = 0;
- atom_mask = 0;
- atoms.clear();
+size_t DWARFMappedHash::Header::GetByteSize(const HeaderData &header_data) {
+ return header_data.GetByteSize();
}
-bool
-DWARFMappedHash::Prologue::ContainsAtom (AtomType atom_type) const
-{
- return (atom_mask & (1u << atom_type)) != 0;
+lldb::offset_t DWARFMappedHash::Header::Read(lldb_private::DataExtractor &data,
+ lldb::offset_t offset) {
+ offset = MappedHash::Header<Prologue>::Read(data, offset);
+ if (offset != UINT32_MAX) {
+ offset = header_data.Read(data, offset);
+ }
+ return offset;
}
-void
-DWARFMappedHash::Prologue::Clear ()
-{
- die_base_offset = 0;
- ClearAtoms ();
-}
+bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ DIEInfo &hash_data) const {
+ const size_t num_atoms = header_data.atoms.size();
+ if (num_atoms == 0)
+ return false;
-void
-DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
-{
- atoms.push_back ({type, form});
- atom_mask |= 1u << type;
- switch (form)
- {
- case DW_FORM_indirect:
- case DW_FORM_exprloc:
- case DW_FORM_flag_present:
- case DW_FORM_ref_sig8:
- assert (!"Unhandled atom form");
- break;
-
- case DW_FORM_string:
- case DW_FORM_block:
- case DW_FORM_block1:
- 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:
- hash_data_has_fixed_byte_size = false;
- LLVM_FALLTHROUGH;
- case DW_FORM_flag:
- case DW_FORM_data1:
- case DW_FORM_ref1:
- case DW_FORM_sec_offset:
- min_hash_data_byte_size += 1;
- break;
-
- case DW_FORM_block2:
- hash_data_has_fixed_byte_size = false;
- LLVM_FALLTHROUGH;
- case DW_FORM_data2:
- case DW_FORM_ref2:
- min_hash_data_byte_size += 2;
- break;
-
- case DW_FORM_block4:
- hash_data_has_fixed_byte_size = false;
- LLVM_FALLTHROUGH;
- case DW_FORM_data4:
- case DW_FORM_ref4:
- case DW_FORM_addr:
- case DW_FORM_ref_addr:
- case DW_FORM_strp:
- min_hash_data_byte_size += 4;
- break;
-
- case DW_FORM_data8:
- case DW_FORM_ref8:
- min_hash_data_byte_size += 8;
- break;
-
- }
-}
+ for (size_t i = 0; i < num_atoms; ++i) {
+ DWARFFormValue form_value(NULL, header_data.atoms[i].form);
-lldb::offset_t
-DWARFMappedHash::Prologue::Read (const lldb_private::DataExtractor &data,
- lldb::offset_t offset)
-{
- ClearAtoms ();
-
- die_base_offset = data.GetU32 (&offset);
-
- const uint32_t atom_count = data.GetU32 (&offset);
- if (atom_count == 0x00060003u)
- {
- // Old format, deal with contents of old pre-release format
- while (data.GetU32(&offset))
- /* do nothing */;
-
- // Hardcode to the only known value for now.
- AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
- }
- else
- {
- for (uint32_t i=0; i<atom_count; ++i)
- {
- AtomType type = (AtomType)data.GetU16 (&offset);
- dw_form_t form = (dw_form_t)data.GetU16 (&offset);
- AppendAtom (type, form);
- }
- }
- return offset;
-}
+ if (!form_value.ExtractValue(data, offset_ptr))
+ return false;
-size_t
-DWARFMappedHash::Prologue::GetByteSize () const
-{
- // Add an extra count to the atoms size for the zero termination Atom that gets
- // written to disk
- return sizeof(die_base_offset) + sizeof(uint32_t) + atoms.size() * sizeof(Atom);
-}
+ 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);
+ break;
-size_t
-DWARFMappedHash::Prologue::GetMinimumHashDataByteSize () const
-{
- return min_hash_data_byte_size;
-}
+ case eAtomTypeTag: // DW_TAG value for the DIE
+ hash_data.tag = (dw_tag_t)form_value.Unsigned();
+ break;
-bool
-DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const
-{
- return hash_data_has_fixed_byte_size;
-}
+ case eAtomTypeTypeFlags: // Flags from enum TypeFlags
+ hash_data.type_flags = (uint32_t)form_value.Unsigned();
+ break;
-size_t
-DWARFMappedHash::Header::GetByteSize (const HeaderData &header_data)
-{
- return header_data.GetByteSize();
-}
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ hash_data.qualified_name_hash = form_value.Unsigned();
+ break;
-lldb::offset_t
-DWARFMappedHash::Header::Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
-{
- offset = MappedHash::Header<Prologue>::Read (data, offset);
- if (offset != UINT32_MAX)
- {
- offset = header_data.Read (data, offset);
+ default:
+ // We can always skip atoms we don't know about
+ break;
}
- return offset;
+ }
+ return true;
}
-bool
-DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr,
- DIEInfo &hash_data) const
-{
- const size_t num_atoms = header_data.atoms.size();
- if (num_atoms == 0)
- return false;
-
- for (size_t i=0; i<num_atoms; ++i)
- {
- DWARFFormValue form_value (NULL, header_data.atoms[i].form);
-
- if (!form_value.ExtractValue(data, offset_ptr))
- return false;
-
- 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);
- break;
-
- case eAtomTypeTag: // DW_TAG value for the DIE
- hash_data.tag = (dw_tag_t)form_value.Unsigned ();
- break;
-
- case eAtomTypeTypeFlags: // Flags from enum TypeFlags
- hash_data.type_flags = (uint32_t)form_value.Unsigned ();
- break;
-
- case eAtomTypeQualNameHash: // Flags from enum TypeFlags
- hash_data.qualified_name_hash = form_value.Unsigned ();
- break;
-
- default:
- // We can always skip atoms we don't know about
- break;
- }
- }
- return true;
-}
+void DWARFMappedHash::Header::Dump(lldb_private::Stream &strm,
+ const DIEInfo &hash_data) const {
+ const size_t num_atoms = header_data.atoms.size();
+ for (size_t i = 0; i < num_atoms; ++i) {
+ if (i > 0)
+ strm.PutCString(", ");
+
+ DWARFFormValue form_value(NULL, header_data.atoms[i].form);
+ switch (header_data.atoms[i].type) {
+ case eAtomTypeDIEOffset: // DIE offset, check form for encoding
+ strm.Printf("{0x%8.8x}", hash_data.offset);
+ break;
-void
-DWARFMappedHash::Header::Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const
-{
- const size_t num_atoms = header_data.atoms.size();
- for (size_t i=0; i<num_atoms; ++i)
+ case eAtomTypeTag: // DW_TAG value for the DIE
{
- if (i > 0)
- strm.PutCString (", ");
-
- DWARFFormValue form_value (NULL, header_data.atoms[i].form);
- switch (header_data.atoms[i].type)
- {
- case eAtomTypeDIEOffset: // DIE offset, check form for encoding
- strm.Printf ("{0x%8.8x}", hash_data.offset);
- break;
-
- case eAtomTypeTag: // DW_TAG value for the DIE
- {
- const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag);
- if (tag_cstr)
- strm.PutCString (tag_cstr);
- else
- strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag);
- }
- break;
-
- case eAtomTypeTypeFlags: // Flags from enum TypeFlags
- strm.Printf ("0x%2.2x", hash_data.type_flags);
- if (hash_data.type_flags)
- {
- strm.PutCString (" (");
- if (hash_data.type_flags & eTypeFlagClassIsImplementation)
- strm.PutCString (" implementation");
- strm.PutCString (" )");
- }
- break;
-
- case eAtomTypeQualNameHash: // Flags from enum TypeFlags
- strm.Printf ("0x%8.8x", hash_data.qualified_name_hash);
- break;
-
- default:
- strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type);
- break;
- }
+ const char *tag_cstr = lldb_private::DW_TAG_value_to_name(hash_data.tag);
+ if (tag_cstr)
+ strm.PutCString(tag_cstr);
+ else
+ strm.Printf("DW_TAG_(0x%4.4x)", hash_data.tag);
+ } break;
+
+ case eAtomTypeTypeFlags: // Flags from enum TypeFlags
+ strm.Printf("0x%2.2x", hash_data.type_flags);
+ if (hash_data.type_flags) {
+ strm.PutCString(" (");
+ if (hash_data.type_flags & eTypeFlagClassIsImplementation)
+ strm.PutCString(" implementation");
+ strm.PutCString(" )");
+ }
+ break;
+
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ strm.Printf("0x%8.8x", hash_data.qualified_name_hash);
+ break;
+
+ default:
+ strm.Printf("AtomType(0x%x)", header_data.atoms[i].type);
+ break;
}
+ }
}
-DWARFMappedHash::MemoryTable::MemoryTable (lldb_private::DWARFDataExtractor &table_data,
- const lldb_private::DWARFDataExtractor &string_table,
- const char *name) :
- MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray> (table_data),
- m_data (table_data),
- m_string_table (string_table),
- m_name (name)
-{
-}
+DWARFMappedHash::MemoryTable::MemoryTable(
+ lldb_private::DWARFDataExtractor &table_data,
+ const lldb_private::DWARFDataExtractor &string_table, const char *name)
+ : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(table_data),
+ m_data(table_data), m_string_table(string_table), m_name(name) {}
const char *
-DWARFMappedHash::MemoryTable::GetStringForKeyType (KeyType key) const
-{
- // The key in the DWARF table is the .debug_str offset for the string
- return m_string_table.PeekCStr (key);
-}
-
-bool
-DWARFMappedHash::MemoryTable::ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const
-{
- lldb::offset_t offset = hash_data_offset;
- offset += 4; // Skip string table offset that contains offset of hash name in .debug_str
- const uint32_t count = m_data.GetU32 (&offset);
- if (count > 0)
- {
- hash_data.resize(count);
- for (uint32_t i=0; i<count; ++i)
- {
- if (!m_header.Read(m_data, &offset, hash_data[i]))
- return false;
- }
+DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const {
+ // The key in the DWARF table is the .debug_str offset for the string
+ return m_string_table.PeekCStr(key);
+}
+
+bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset,
+ HashData &hash_data) const {
+ lldb::offset_t offset = hash_data_offset;
+ offset += 4; // Skip string table offset that contains offset of hash name in
+ // .debug_str
+ const uint32_t count = m_data.GetU32(&offset);
+ if (count > 0) {
+ hash_data.resize(count);
+ for (uint32_t i = 0; i < count; ++i) {
+ if (!m_header.Read(m_data, &offset, hash_data[i]))
+ return false;
}
- else
- hash_data.clear();
- return true;
+ } else
+ hash_data.clear();
+ return true;
}
DWARFMappedHash::MemoryTable::Result
-DWARFMappedHash::MemoryTable::GetHashDataForName (const char *name,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const
-{
- pair.key = m_data.GetU32 (hash_data_offset_ptr);
- pair.value.clear();
-
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
- if (pair.key == 0)
- return eResultEndOfHashData;
-
- // There definitely should be a string for this string offset, if
- // there isn't, there is something wrong, return and error
- const char *strp_cstr = m_string_table.PeekCStr (pair.key);
- if (strp_cstr == NULL)
- {
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
-
- const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
- {
- // We have at least one HashData entry, and we have enough
- // data to parse at least "count" HashData entries.
-
- // First make sure the entire C string matches...
- const bool match = strcmp (name, strp_cstr) == 0;
-
- if (!match && m_header.header_data.HashDataHasFixedByteSize())
- {
- // If the string doesn't match and we have fixed size data,
- // we can just add the total byte size of all HashData objects
- // to the hash data offset and be done...
- *hash_data_offset_ptr += min_total_hash_data_size;
+DWARFMappedHash::MemoryTable::GetHashDataForName(
+ const char *name, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const {
+ pair.key = m_data.GetU32(hash_data_offset_ptr);
+ pair.value.clear();
+
+ // If the key is zero, this terminates our chain of HashData objects
+ // for this hash value.
+ if (pair.key == 0)
+ return eResultEndOfHashData;
+
+ // There definitely should be a string for this string offset, if
+ // there isn't, there is something wrong, return and error
+ const char *strp_cstr = m_string_table.PeekCStr(pair.key);
+ if (strp_cstr == NULL) {
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
+
+ const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
+ const size_t min_total_hash_data_size =
+ count * m_header.header_data.GetMinimumHashDataByteSize();
+ if (count > 0 &&
+ m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
+ // We have at least one HashData entry, and we have enough
+ // data to parse at least "count" HashData entries.
+
+ // First make sure the entire C string matches...
+ const bool match = strcmp(name, strp_cstr) == 0;
+
+ if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
+ // If the string doesn't match and we have fixed size data,
+ // we can just add the total byte size of all HashData objects
+ // to the hash data offset and be done...
+ *hash_data_offset_ptr += min_total_hash_data_size;
+ } else {
+ // If the string does match, or we don't have fixed size data
+ // then we need to read the hash data as a stream. If the
+ // string matches we also append all HashData objects to the
+ // value array.
+ for (uint32_t i = 0; i < count; ++i) {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
+ // Only happened if the HashData of the string matched...
+ if (match)
+ pair.value.push_back(die_info);
+ } else {
+ // Something went wrong while reading the data
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
}
- else
- {
- // If the string does match, or we don't have fixed size data
- // then we need to read the hash data as a stream. If the
- // string matches we also append all HashData objects to the
- // value array.
- for (uint32_t i=0; i<count; ++i)
- {
- DIEInfo die_info;
- if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
- {
- // Only happened if the HashData of the string matched...
- if (match)
- pair.value.push_back (die_info);
- }
- else
- {
- // Something went wrong while reading the data
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
- }
- }
- // Return the correct response depending on if the string matched
- // or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will get called
- // again for the next key/value or the key terminator
- // which in our case is a zero .debug_str offset.
+ }
}
+ // Return the correct response depending on if the string matched
+ // or not...
+ if (match)
+ return eResultKeyMatch; // The key (cstring) matches and we have lookup
+ // results!
else
- {
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
+ return eResultKeyMismatch; // The key doesn't match, this function will
+ // get called
+ // again for the next key/value or the key terminator
+ // which in our case is a zero .debug_str offset.
+ } else {
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
}
DWARFMappedHash::MemoryTable::Result
-DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression (
- const lldb_private::RegularExpression& regex,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const
-{
- pair.key = m_data.GetU32 (hash_data_offset_ptr);
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
- if (pair.key == 0)
- return eResultEndOfHashData;
-
- // There definitely should be a string for this string offset, if
- // there isn't, there is something wrong, return and error
- const char *strp_cstr = m_string_table.PeekCStr (pair.key);
- if (strp_cstr == NULL)
- return eResultError;
-
- const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
- {
- const bool match = regex.Execute(strp_cstr);
-
- if (!match && m_header.header_data.HashDataHasFixedByteSize())
- {
- // If the regex doesn't match and we have fixed size data,
- // we can just add the total byte size of all HashData objects
- // to the hash data offset and be done...
- *hash_data_offset_ptr += min_total_hash_data_size;
- }
- else
- {
- // If the string does match, or we don't have fixed size data
- // then we need to read the hash data as a stream. If the
- // string matches we also append all HashData objects to the
- // value array.
- for (uint32_t i=0; i<count; ++i)
- {
- DIEInfo die_info;
- if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
- {
- // Only happened if the HashData of the string matched...
- if (match)
- pair.value.push_back (die_info);
- }
- else
- {
- // Something went wrong while reading the data
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
- }
+DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
+ const lldb_private::RegularExpression &regex,
+ lldb::offset_t *hash_data_offset_ptr, Pair &pair) const {
+ pair.key = m_data.GetU32(hash_data_offset_ptr);
+ // If the key is zero, this terminates our chain of HashData objects
+ // for this hash value.
+ if (pair.key == 0)
+ return eResultEndOfHashData;
+
+ // There definitely should be a string for this string offset, if
+ // there isn't, there is something wrong, return and error
+ const char *strp_cstr = m_string_table.PeekCStr(pair.key);
+ if (strp_cstr == NULL)
+ return eResultError;
+
+ const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
+ const size_t min_total_hash_data_size =
+ count * m_header.header_data.GetMinimumHashDataByteSize();
+ if (count > 0 &&
+ m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
+ const bool match = regex.Execute(llvm::StringRef(strp_cstr));
+
+ if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
+ // If the regex doesn't match and we have fixed size data,
+ // we can just add the total byte size of all HashData objects
+ // to the hash data offset and be done...
+ *hash_data_offset_ptr += min_total_hash_data_size;
+ } else {
+ // If the string does match, or we don't have fixed size data
+ // then we need to read the hash data as a stream. If the
+ // string matches we also append all HashData objects to the
+ // value array.
+ for (uint32_t i = 0; i < count; ++i) {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
+ // Only happened if the HashData of the string matched...
+ if (match)
+ pair.value.push_back(die_info);
+ } else {
+ // Something went wrong while reading the data
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
}
- // Return the correct response depending on if the string matched
- // or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will get called
- // again for the next key/value or the key terminator
- // which in our case is a zero .debug_str offset.
+ }
}
+ // Return the correct response depending on if the string matched
+ // or not...
+ if (match)
+ return eResultKeyMatch; // The key (cstring) matches and we have lookup
+ // results!
else
- {
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
+ return eResultKeyMismatch; // The key doesn't match, this function will
+ // get called
+ // again for the next key/value or the key terminator
+ // which in our case is a zero .debug_str offset.
+ } else {
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
+}
+
+size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
+ const lldb_private::RegularExpression &regex,
+ DIEInfoArray &die_info_array) const {
+ const uint32_t hash_count = m_header.hashes_count;
+ Pair pair;
+ for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) {
+ lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx);
+ while (hash_data_offset != UINT32_MAX) {
+ const lldb::offset_t prev_hash_data_offset = hash_data_offset;
+ Result hash_result =
+ AppendHashDataForRegularExpression(regex, &hash_data_offset, pair);
+ if (prev_hash_data_offset == hash_data_offset)
+ break;
+
+ // Check the result of getting our hash data
+ switch (hash_result) {
+ case eResultKeyMatch:
+ case eResultKeyMismatch:
+ // Whether we matches or not, it doesn't matter, we
+ // keep looking.
+ break;
+
+ case eResultEndOfHashData:
+ case eResultError:
+ hash_data_offset = UINT32_MAX;
+ break;
+ }
}
-}
-
-size_t
-DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex (
- const lldb_private::RegularExpression& regex,
- DIEInfoArray &die_info_array) const
-{
- const uint32_t hash_count = m_header.hashes_count;
- Pair pair;
- for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
- {
- lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
- while (hash_data_offset != UINT32_MAX)
- {
- const lldb::offset_t prev_hash_data_offset = hash_data_offset;
- Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair);
- if (prev_hash_data_offset == hash_data_offset)
- break;
-
- // Check the result of getting our hash data
- switch (hash_result)
- {
- case eResultKeyMatch:
- case eResultKeyMismatch:
- // Whether we matches or not, it doesn't matter, we
- // keep looking.
- break;
-
- case eResultEndOfHashData:
- case eResultError:
- hash_data_offset = UINT32_MAX;
- break;
- }
+ }
+ die_info_array.swap(pair.value);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
+ const uint32_t die_offset_start, const uint32_t die_offset_end,
+ DIEInfoArray &die_info_array) const {
+ const uint32_t hash_count = m_header.hashes_count;
+ for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) {
+ bool done = false;
+ lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx);
+ while (!done && hash_data_offset != UINT32_MAX) {
+ KeyType key = m_data.GetU32(&hash_data_offset);
+ // If the key is zero, this terminates our chain of HashData objects
+ // for this hash value.
+ if (key == 0)
+ break;
+
+ const uint32_t count = m_data.GetU32(&hash_data_offset);
+ for (uint32_t i = 0; i < count; ++i) {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, &hash_data_offset, die_info)) {
+ if (die_info.offset == 0)
+ done = true;
+ if (die_offset_start <= die_info.offset &&
+ die_info.offset < die_offset_end)
+ die_info_array.push_back(die_info);
}
+ }
}
- die_info_array.swap (pair.value);
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::AppendAllDIEsInRange (const uint32_t die_offset_start,
- const uint32_t die_offset_end,
- DIEInfoArray &die_info_array) const
-{
- const uint32_t hash_count = m_header.hashes_count;
- for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
- {
- bool done = false;
- lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
- while (!done && hash_data_offset != UINT32_MAX)
- {
- KeyType key = m_data.GetU32 (&hash_data_offset);
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
- if (key == 0)
- break;
-
- const uint32_t count = m_data.GetU32 (&hash_data_offset);
- for (uint32_t i=0; i<count; ++i)
- {
- DIEInfo die_info;
- if (m_header.Read(m_data, &hash_data_offset, die_info))
- {
- if (die_info.offset == 0)
- done = true;
- if (die_offset_start <= die_info.offset && die_info.offset < die_offset_end)
- die_info_array.push_back(die_info);
- }
- }
- }
- }
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEArray &die_offsets)
-{
- if (!name || !name[0])
- return 0;
-
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets);
- return die_info_array.size();
+ }
+ return die_info_array.size();
}
-size_t
-DWARFMappedHash::MemoryTable::FindByNameAndTag (const char *name,
- const dw_tag_t tag,
- DIEArray &die_offsets)
-{
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray (die_info_array, tag, die_offsets);
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash (const char *name,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets)
-{
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray (die_info_array, tag, qualified_name_hash, die_offsets);
- return die_info_array.size();
-}
+size_t DWARFMappedHash::MemoryTable::FindByName(const char *name,
+ DIEArray &die_offsets) {
+ if (!name || !name[0])
+ return 0;
-size_t
-DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName (const char *name,
- DIEArray &die_offsets,
- bool must_be_implementation)
-{
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- {
- if (must_be_implementation && GetHeader().header_data.ContainsAtom (eAtomTypeTypeFlags))
- {
- // If we have two atoms, then we have the DIE offset and
- // the type flags so we can find the objective C class
- // efficiently.
- DWARFMappedHash::ExtractTypesFromDIEArray (die_info_array,
- UINT32_MAX,
- eTypeFlagClassIsImplementation,
- die_offsets);
- }
- else
- {
- // We don't only want the one true definition, so try and see
- // what we can find, and only return class or struct DIEs.
- // If we do have the full implementation, then return it alone,
- // else return all possible matches.
- const bool return_implementation_only_if_available = true;
- DWARFMappedHash::ExtractClassOrStructDIEArray (die_info_array,
- return_implementation_only_if_available,
- die_offsets);
- }
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(const char *name,
+ const dw_tag_t tag,
+ DIEArray &die_offsets) {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
+ const char *name, const dw_tag_t tag, const uint32_t qualified_name_hash,
+ DIEArray &die_offsets) {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash,
+ die_offsets);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
+ const char *name, DIEArray &die_offsets, bool must_be_implementation) {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array)) {
+ if (must_be_implementation &&
+ GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) {
+ // If we have two atoms, then we have the DIE offset and
+ // the type flags so we can find the objective C class
+ // efficiently.
+ DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX,
+ eTypeFlagClassIsImplementation,
+ die_offsets);
+ } else {
+ // We don't only want the one true definition, so try and see
+ // what we can find, and only return class or struct DIEs.
+ // If we do have the full implementation, then return it alone,
+ // else return all possible matches.
+ const bool return_implementation_only_if_available = true;
+ DWARFMappedHash::ExtractClassOrStructDIEArray(
+ die_info_array, return_implementation_only_if_available, die_offsets);
}
- return die_offsets.size();
+ }
+ return die_offsets.size();
}
-size_t
-DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEInfoArray &die_info_array)
-{
- if (!name || !name[0])
- return 0;
-
- Pair kv_pair;
- size_t old_size = die_info_array.size();
- if (Find (name, kv_pair))
- {
- die_info_array.swap(kv_pair.value);
- return die_info_array.size() - old_size;
- }
+size_t DWARFMappedHash::MemoryTable::FindByName(const char *name,
+ DIEInfoArray &die_info_array) {
+ if (!name || !name[0])
return 0;
+
+ Pair kv_pair;
+ size_t old_size = die_info_array.size();
+ if (Find(name, kv_pair)) {
+ die_info_array.swap(kv_pair.value);
+ return die_info_array.size() - old_size;
+ }
+ return 0;
}
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index bcde558ae449..c1cb30b60045 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -12,10 +12,10 @@
#include <vector>
-#include "lldb/lldb-defines.h"
-#include "lldb/Core/dwarf.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/MappedHash.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/dwarf.h"
+#include "lldb/lldb-defines.h"
#include "DWARFDefines.h"
#include "DWARFFormValue.h"
@@ -25,195 +25,169 @@ class SymbolFileDWARF;
class DWARFCompileUnit;
class DWARFDebugInfoEntry;
-class DWARFMappedHash
-{
+class DWARFMappedHash {
public:
- enum AtomType : uint16_t
- {
- eAtomTypeNULL = 0u,
- eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
- eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question
- eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
- eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
- eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name (since all hash entries are basename only)
- // For example a type like "std::vector<int>::iterator" would have a name of "iterator"
- // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not have to pull
- // in debug info for a type when we know the fully qualified name.
- };
-
- // Bit definitions for the eAtomTypeTypeFlags flags
- enum TypeFlags
- {
- // Always set for C++, only set for ObjC if this is the
- // @implementation for class
- eTypeFlagClassIsImplementation = ( 1u << 1 )
- };
-
- struct DIEInfo
- {
- dw_offset_t cu_offset;
- dw_offset_t offset; // The DIE offset
- dw_tag_t tag;
- uint32_t type_flags; // Any flags for this DIEInfo
- uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
-
- DIEInfo ();
- DIEInfo (dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
- };
-
- struct Atom
- {
- AtomType type;
- dw_form_t form;
- };
-
- typedef std::vector<DIEInfo> DIEInfoArray;
- typedef std::vector<Atom> AtomArray;
-
- class Prologue
- {
- public:
- Prologue (dw_offset_t _die_base_offset = 0);
-
- void
- ClearAtoms ();
-
- bool
- ContainsAtom (AtomType atom_type) const;
-
- void
- Clear ();
-
- void
- AppendAtom (AtomType type, dw_form_t form);
-
- lldb::offset_t
- Read (const lldb_private::DataExtractor &data, lldb::offset_t offset);
-
- size_t
- GetByteSize () const;
-
- size_t
- GetMinimumHashDataByteSize () const;
-
- bool
- HashDataHasFixedByteSize() const;
-
- // DIE offset base so die offsets in hash_data can be CU relative
- dw_offset_t die_base_offset;
- AtomArray atoms;
- uint32_t atom_mask;
- size_t min_hash_data_byte_size;
- bool hash_data_has_fixed_byte_size;
- };
-
- class Header : public MappedHash::Header<Prologue>
- {
- public:
- size_t
- GetByteSize (const HeaderData &header_data) override;
-
- lldb::offset_t
- Read (lldb_private::DataExtractor &data, lldb::offset_t offset) override;
-
- bool
- Read (const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr,
- DIEInfo &hash_data) const;
-
- void
- Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const;
- };
-
- // A class for reading and using a saved hash table from a block of data
- // in memory
- class MemoryTable : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, DIEInfoArray>
- {
- public:
- MemoryTable (lldb_private::DWARFDataExtractor &table_data,
- const lldb_private::DWARFDataExtractor &string_table,
- const char *name);
-
- const char *
- GetStringForKeyType (KeyType key) const override;
-
- bool
- ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const override;
-
- size_t
- AppendAllDIEsThatMatchingRegex (const lldb_private::RegularExpression& regex,
- DIEInfoArray &die_info_array) const;
-
- size_t
- AppendAllDIEsInRange (const uint32_t die_offset_start,
- const uint32_t die_offset_end,
- DIEInfoArray &die_info_array) const;
-
- size_t
- FindByName (const char *name, DIEArray &die_offsets);
-
- size_t
- FindByNameAndTag (const char *name, const dw_tag_t tag, DIEArray &die_offsets);
-
- size_t
- FindByNameAndTagAndQualifiedNameHash (const char *name,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets);
-
- size_t
- FindCompleteObjCClassByName (const char *name,
- DIEArray &die_offsets,
- bool must_be_implementation);
-
- protected:
- Result
- AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const;
-
- size_t
- FindByName (const char *name, DIEInfoArray &die_info_array);
-
- Result
- GetHashDataForName (const char *name,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const override;
-
- const lldb_private::DWARFDataExtractor &m_data;
- const lldb_private::DWARFDataExtractor &m_string_table;
- std::string m_name;
- };
-
- static void
- ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets);
+ enum AtomType : uint16_t {
+ eAtomTypeNULL = 0u,
+ eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
+ eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that
+ // contains the item in question
+ eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1
+ // (if no tags exceed 255) or DW_FORM_data2
+ eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
+ eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
+ eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name
+ // (since all hash entries are basename only)
+ // For example a type like "std::vector<int>::iterator" would have a name of
+ // "iterator"
+ // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not
+ // have to pull
+ // in debug info for a type when we know the fully qualified name.
+ };
+
+ // Bit definitions for the eAtomTypeTypeFlags flags
+ enum TypeFlags {
+ // Always set for C++, only set for ObjC if this is the
+ // @implementation for class
+ eTypeFlagClassIsImplementation = (1u << 1)
+ };
+
+ struct DIEInfo {
+ dw_offset_t cu_offset;
+ dw_offset_t offset; // The DIE offset
+ dw_tag_t tag;
+ uint32_t type_flags; // Any flags for this DIEInfo
+ uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
+
+ DIEInfo();
+ DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
+ };
+
+ struct Atom {
+ AtomType type;
+ dw_form_t form;
+ };
+
+ typedef std::vector<DIEInfo> DIEInfoArray;
+ typedef std::vector<Atom> AtomArray;
+
+ class Prologue {
+ public:
+ Prologue(dw_offset_t _die_base_offset = 0);
+
+ void ClearAtoms();
+
+ bool ContainsAtom(AtomType atom_type) const;
+
+ void Clear();
+
+ void AppendAtom(AtomType type, dw_form_t form);
+
+ lldb::offset_t Read(const lldb_private::DataExtractor &data,
+ lldb::offset_t offset);
+
+ size_t GetByteSize() const;
+
+ size_t GetMinimumHashDataByteSize() const;
+
+ bool HashDataHasFixedByteSize() const;
+
+ // DIE offset base so die offsets in hash_data can be CU relative
+ dw_offset_t die_base_offset;
+ AtomArray atoms;
+ uint32_t atom_mask;
+ size_t min_hash_data_byte_size;
+ bool hash_data_has_fixed_byte_size;
+ };
+
+ class Header : public MappedHash::Header<Prologue> {
+ public:
+ size_t GetByteSize(const HeaderData &header_data) override;
+
+ lldb::offset_t Read(lldb_private::DataExtractor &data,
+ lldb::offset_t offset) override;
+
+ bool Read(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
+
+ void Dump(lldb_private::Stream &strm, const DIEInfo &hash_data) const;
+ };
+
+ // A class for reading and using a saved hash table from a block of data
+ // in memory
+ class MemoryTable
+ : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header,
+ DIEInfoArray> {
+ public:
+ MemoryTable(lldb_private::DWARFDataExtractor &table_data,
+ const lldb_private::DWARFDataExtractor &string_table,
+ const char *name);
+
+ const char *GetStringForKeyType(KeyType key) const override;
+
+ bool ReadHashData(uint32_t hash_data_offset,
+ HashData &hash_data) const override;
+
+ size_t
+ AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression &regex,
+ DIEInfoArray &die_info_array) const;
+
+ size_t AppendAllDIEsInRange(const uint32_t die_offset_start,
+ const uint32_t die_offset_end,
+ DIEInfoArray &die_info_array) const;
+
+ size_t FindByName(const char *name, DIEArray &die_offsets);
+
+ size_t FindByNameAndTag(const char *name, const dw_tag_t tag,
+ DIEArray &die_offsets);
+
+ size_t
+ FindByNameAndTagAndQualifiedNameHash(const char *name, const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets);
+
+ size_t FindCompleteObjCClassByName(const char *name, DIEArray &die_offsets,
+ bool must_be_implementation);
+
+ protected:
+ Result AppendHashDataForRegularExpression(
+ const lldb_private::RegularExpression &regex,
+ lldb::offset_t *hash_data_offset_ptr, Pair &pair) const;
+
+ size_t FindByName(const char *name, DIEInfoArray &die_info_array);
+
+ Result GetHashDataForName(const char *name,
+ lldb::offset_t *hash_data_offset_ptr,
+ Pair &pair) const override;
+
+ const lldb_private::DWARFDataExtractor &m_data;
+ const lldb_private::DWARFDataExtractor &m_string_table;
+ std::string m_name;
+ };
+
+ static void ExtractDIEArray(const DIEInfoArray &die_info_array,
+ DIEArray &die_offsets);
protected:
- static void
- ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- DIEArray &die_offsets);
-
- static void
- ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets);
-
- static void
- ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
- bool return_implementation_only_if_available,
- DIEArray &die_offsets);
-
- static void
- ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array,
- uint32_t type_flag_mask,
- uint32_t type_flag_value,
+ static void ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag, DIEArray &die_offsets);
+
+ static void ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
DIEArray &die_offsets);
- static const char *
- GetAtomTypeName (uint16_t atom);
+ static void
+ ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array,
+ bool return_implementation_only_if_available,
+ DIEArray &die_offsets);
+
+ static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array,
+ uint32_t type_flag_mask,
+ uint32_t type_flag_value,
+ DIEArray &die_offsets);
+
+ static const char *GetAtomTypeName(uint16_t atom);
};
-#endif // SymbolFileDWARF_HashedNameToDIE_h_
+#endif // SymbolFileDWARF_HashedNameToDIE_h_
diff --git a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
index fbbc03c94625..1385e3dd28de 100644
--- a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
@@ -9,227 +9,195 @@
#include "LogChannelDWARF.h"
-#include "lldb/Interpreter/Args.h"
+#include "SymbolFileDWARF.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
-#include "SymbolFileDWARF.h"
+#include "lldb/Interpreter/Args.h"
using namespace lldb;
using namespace lldb_private;
-
// when the one and only logging channel is enabled, then this will be non NULL.
-static LogChannelDWARF* g_log_channel = NULL;
-
-LogChannelDWARF::LogChannelDWARF () :
- LogChannel ()
-{
-}
-
-LogChannelDWARF::~LogChannelDWARF ()
-{
-}
+static LogChannelDWARF *g_log_channel = NULL;
+LogChannelDWARF::LogChannelDWARF() : LogChannel() {}
-void
-LogChannelDWARF::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- LogChannelDWARF::CreateInstance);
-}
+LogChannelDWARF::~LogChannelDWARF() {}
-void
-LogChannelDWARF::Terminate()
-{
- PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance);
+void LogChannelDWARF::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ LogChannelDWARF::CreateInstance);
}
-LogChannel*
-LogChannelDWARF::CreateInstance ()
-{
- return new LogChannelDWARF ();
+void LogChannelDWARF::Terminate() {
+ PluginManager::UnregisterPlugin(LogChannelDWARF::CreateInstance);
}
-lldb_private::ConstString
-LogChannelDWARF::GetPluginNameStatic()
-{
- return SymbolFileDWARF::GetPluginNameStatic();
-}
+LogChannel *LogChannelDWARF::CreateInstance() { return new LogChannelDWARF(); }
-const char *
-LogChannelDWARF::GetPluginDescriptionStatic()
-{
- return "DWARF log channel for debugging plug-in issues.";
+lldb_private::ConstString LogChannelDWARF::GetPluginNameStatic() {
+ return SymbolFileDWARF::GetPluginNameStatic();
}
-lldb_private::ConstString
-LogChannelDWARF::GetPluginName()
-{
- return GetPluginNameStatic();
+const char *LogChannelDWARF::GetPluginDescriptionStatic() {
+ return "DWARF log channel for debugging plug-in issues.";
}
-uint32_t
-LogChannelDWARF::GetPluginVersion()
-{
- return 1;
-}
-
-
-void
-LogChannelDWARF::Delete ()
-{
- g_log_channel = NULL;
+lldb_private::ConstString LogChannelDWARF::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t LogChannelDWARF::GetPluginVersion() { return 1; }
-void
-LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm)
-{
- if (m_log_ap.get() == NULL)
- return;
-
- uint32_t flag_bits = m_log_ap->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0) flag_bits &= ~DWARF_LOG_ALL;
- else if (::strcasecmp (arg, "info") == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO;
- else if (::strcasecmp (arg, "line") == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE;
- else if (::strcasecmp (arg, "pubnames") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
- else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
- else if (::strcasecmp (arg, "aranges") == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
- else if (::strcasecmp (arg, "lookups") == 0) flag_bits &= ~DWARF_LOG_LOOKUPS;
- else if (::strcasecmp (arg, "map") == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP;
- else if (::strcasecmp (arg, "default") == 0) flag_bits &= ~DWARF_LOG_DEFAULT;
- else if (::strcasecmp (arg, "verbose") == 0) flag_bits &= ~DWARF_LOG_VERBOSE;
- else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListCategories (feedback_strm);
- }
- }
-
- if (flag_bits == 0)
- Delete ();
- else
- m_log_ap->GetMask().Reset (flag_bits);
+void LogChannelDWARF::Delete() { g_log_channel = NULL; }
+void LogChannelDWARF::Disable(const char **categories, Stream *feedback_strm) {
+ if (m_log_ap.get() == NULL)
return;
-}
-bool
-LogChannelDWARF::Enable
-(
- StreamSP &log_stream_sp,
- uint32_t log_options,
- Stream *feedback_strm, // Feedback stream for argument errors etc
- const char **categories // The categories to enable within this logging stream, if empty, enable default set
-)
-{
- Delete ();
-
- if (m_log_ap)
- m_log_ap->SetStream(log_stream_sp);
- else
- m_log_ap.reset(new Log (log_stream_sp));
-
- g_log_channel = this;
- uint32_t flag_bits = 0;
- bool got_unknown_category = false;
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0) flag_bits |= DWARF_LOG_ALL;
- else if (::strcasecmp (arg, "info") == 0) flag_bits |= DWARF_LOG_DEBUG_INFO;
- else if (::strcasecmp (arg, "line") == 0) flag_bits |= DWARF_LOG_DEBUG_LINE;
- else if (::strcasecmp (arg, "pubnames") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
- else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
- else if (::strcasecmp (arg, "aranges") == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES;
- else if (::strcasecmp (arg, "lookups") == 0) flag_bits |= DWARF_LOG_LOOKUPS;
- else if (::strcasecmp (arg, "map") == 0) flag_bits |= DWARF_LOG_DEBUG_MAP;
- else if (::strcasecmp (arg, "default") == 0) flag_bits |= DWARF_LOG_DEFAULT;
- else if (::strcasecmp (arg, "verbose") == 0) flag_bits |= DWARF_LOG_VERBOSE;
- else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListCategories (feedback_strm);
- }
- }
+ uint32_t flag_bits = m_log_ap->GetMask().Get();
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits &= ~DWARF_LOG_ALL;
+ else if (::strcasecmp(arg, "info") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_INFO;
+ else if (::strcasecmp(arg, "line") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_LINE;
+ else if (::strcasecmp(arg, "pubnames") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
+ else if (::strcasecmp(arg, "pubtypes") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
+ else if (::strcasecmp(arg, "aranges") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
+ else if (::strcasecmp(arg, "lookups") == 0)
+ flag_bits &= ~DWARF_LOG_LOOKUPS;
+ else if (::strcasecmp(arg, "map") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_MAP;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits &= ~DWARF_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits &= ~DWARF_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "comp", 4) == 0)
+ flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = DWARF_LOG_DEFAULT;
- m_log_ap->GetMask().Reset(flag_bits);
- m_log_ap->GetOptions().Reset(log_options);
- return m_log_ap.get() != NULL;
-}
-
-void
-LogChannelDWARF::ListCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " info - log the parsing of .debug_info\n"
- " line - log the parsing of .debug_line\n"
- " pubnames - log the parsing of .debug_pubnames\n"
- " pubtypes - log the parsing of .debug_pubtypes\n"
- " aranges - log the parsing of .debug_aranges\n"
- " lookups - log any lookups that happen by name, regex, or address\n"
- " completion - log struct/unions/class type completions\n"
- " map - log insertions of object files into DWARF debug maps\n",
- SymbolFileDWARF::GetPluginNameStatic().GetCString());
-}
-
-Log *
-LogChannelDWARF::GetLog ()
-{
- if (g_log_channel)
- return g_log_channel->m_log_ap.get();
+ }
- return NULL;
-}
+ if (flag_bits == 0)
+ Delete();
+ else
+ m_log_ap->GetMask().Reset(flag_bits);
-Log *
-LogChannelDWARF::GetLogIfAll (uint32_t mask)
-{
- if (g_log_channel && g_log_channel->m_log_ap.get())
- {
- if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
- return g_log_channel->m_log_ap.get();
- }
- return NULL;
+ return;
}
-Log *
-LogChannelDWARF::GetLogIfAny (uint32_t mask)
-{
- if (g_log_channel && g_log_channel->m_log_ap.get())
- {
- if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
- return g_log_channel->m_log_ap.get();
+bool LogChannelDWARF::Enable(
+ StreamSP &log_stream_sp, uint32_t log_options,
+ Stream *feedback_strm, // Feedback stream for argument errors etc
+ const char **categories // The categories to enable within this logging
+ // stream, if empty, enable default set
+ ) {
+ Delete();
+
+ if (m_log_ap)
+ m_log_ap->SetStream(log_stream_sp);
+ else
+ m_log_ap.reset(new Log(log_stream_sp));
+
+ g_log_channel = this;
+ uint32_t flag_bits = 0;
+ bool got_unknown_category = false;
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits |= DWARF_LOG_ALL;
+ else if (::strcasecmp(arg, "info") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_INFO;
+ else if (::strcasecmp(arg, "line") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_LINE;
+ else if (::strcasecmp(arg, "pubnames") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
+ else if (::strcasecmp(arg, "pubtypes") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
+ else if (::strcasecmp(arg, "aranges") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_ARANGES;
+ else if (::strcasecmp(arg, "lookups") == 0)
+ flag_bits |= DWARF_LOG_LOOKUPS;
+ else if (::strcasecmp(arg, "map") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_MAP;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits |= DWARF_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits |= DWARF_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "comp", 4) == 0)
+ flag_bits |= DWARF_LOG_TYPE_COMPLETION;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListCategories(feedback_strm);
+ }
}
- return NULL;
-}
-
-void
-LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...)
-{
- if (g_log_channel)
- {
- Log *log = g_log_channel->m_log_ap.get();
- if (log && log->GetMask().AnySet(mask))
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+ }
+ if (flag_bits == 0)
+ flag_bits = DWARF_LOG_DEFAULT;
+ m_log_ap->GetMask().Reset(flag_bits);
+ m_log_ap->GetOptions().Reset(log_options);
+ return m_log_ap.get() != NULL;
+}
+
+void LogChannelDWARF::ListCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " info - log the parsing of .debug_info\n"
+ " line - log the parsing of .debug_line\n"
+ " pubnames - log the parsing of .debug_pubnames\n"
+ " pubtypes - log the parsing of .debug_pubtypes\n"
+ " aranges - log the parsing of .debug_aranges\n"
+ " lookups - log any lookups that happen by name, regex, or address\n"
+ " completion - log struct/unions/class type completions\n"
+ " map - log insertions of object files into DWARF debug maps\n",
+ SymbolFileDWARF::GetPluginNameStatic().GetCString());
+}
+
+Log *LogChannelDWARF::GetLog() {
+ if (g_log_channel)
+ return g_log_channel->m_log_ap.get();
+
+ return NULL;
+}
+
+Log *LogChannelDWARF::GetLogIfAll(uint32_t mask) {
+ if (g_log_channel && g_log_channel->m_log_ap.get()) {
+ if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
+ return g_log_channel->m_log_ap.get();
+ }
+ return NULL;
+}
+
+Log *LogChannelDWARF::GetLogIfAny(uint32_t mask) {
+ if (g_log_channel && g_log_channel->m_log_ap.get()) {
+ if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
+ return g_log_channel->m_log_ap.get();
+ }
+ return NULL;
+}
+
+void LogChannelDWARF::LogIf(uint32_t mask, const char *format, ...) {
+ if (g_log_channel) {
+ Log *log = g_log_channel->m_log_ap.get();
+ if (log && log->GetMask().AnySet(mask)) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
}
+ }
}
diff --git a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
index 24fa7d148cd3..4802f858f3a1 100644
--- a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
@@ -16,72 +16,59 @@
// Project includes
#include "lldb/Core/Log.h"
-#define DWARF_LOG_VERBOSE (1u << 0)
-#define DWARF_LOG_DEBUG_INFO (1u << 1)
-#define DWARF_LOG_DEBUG_LINE (1u << 2)
-#define DWARF_LOG_DEBUG_PUBNAMES (1u << 3)
-#define DWARF_LOG_DEBUG_PUBTYPES (1u << 4)
-#define DWARF_LOG_DEBUG_ARANGES (1u << 5)
-#define DWARF_LOG_LOOKUPS (1u << 6)
-#define DWARF_LOG_TYPE_COMPLETION (1u << 7)
-#define DWARF_LOG_DEBUG_MAP (1u << 8)
-#define DWARF_LOG_ALL (UINT32_MAX)
-#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
-
-class LogChannelDWARF : public lldb_private::LogChannel
-{
+#define DWARF_LOG_VERBOSE (1u << 0)
+#define DWARF_LOG_DEBUG_INFO (1u << 1)
+#define DWARF_LOG_DEBUG_LINE (1u << 2)
+#define DWARF_LOG_DEBUG_PUBNAMES (1u << 3)
+#define DWARF_LOG_DEBUG_PUBTYPES (1u << 4)
+#define DWARF_LOG_DEBUG_ARANGES (1u << 5)
+#define DWARF_LOG_LOOKUPS (1u << 6)
+#define DWARF_LOG_TYPE_COMPLETION (1u << 7)
+#define DWARF_LOG_DEBUG_MAP (1u << 8)
+#define DWARF_LOG_ALL (UINT32_MAX)
+#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
+
+class LogChannelDWARF : public lldb_private::LogChannel {
public:
- LogChannelDWARF ();
+ LogChannelDWARF();
- ~LogChannelDWARF() override;
+ ~LogChannelDWARF() override;
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::LogChannel *
- CreateInstance ();
+ static lldb_private::LogChannel *CreateInstance();
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- void
- Disable(const char** categories, lldb_private::Stream *feedback_strm) override;
+ void Disable(const char **categories,
+ lldb_private::Stream *feedback_strm) override;
- void
- Delete ();
+ void Delete();
- bool
- Enable(lldb::StreamSP &log_stream_sp,
- uint32_t log_options,
- lldb_private::Stream *feedback_strm, // Feedback stream for argument errors etc
- const char **categories) override; // The categories to enable within this logging stream, if empty, enable default set
+ bool Enable(lldb::StreamSP &log_stream_sp, uint32_t log_options,
+ lldb_private::Stream
+ *feedback_strm, // Feedback stream for argument errors etc
+ const char **categories) override; // The categories to enable
+ // within this logging stream,
+ // if empty, enable default set
- void
- ListCategories(lldb_private::Stream *strm) override;
+ void ListCategories(lldb_private::Stream *strm) override;
- static lldb_private::Log *
- GetLog ();
+ static lldb_private::Log *GetLog();
- static lldb_private::Log *
- GetLogIfAll (uint32_t mask);
-
- static lldb_private::Log *
- GetLogIfAny (uint32_t mask);
-
- static void
- LogIf (uint32_t mask, const char *format, ...);
+ static lldb_private::Log *GetLogIfAll(uint32_t mask);
+
+ static lldb_private::Log *GetLogIfAny(uint32_t mask);
+
+ static void LogIf(uint32_t mask, const char *format, ...);
};
#endif // SymbolFileDWARF_LogChannelDWARF_h_
diff --git a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
index fe02adbb6c87..c3d90d171b79 100644
--- a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -9,9 +9,9 @@
#include "NameToDIE.h"
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Symbol/ObjectFile.h"
#include "DWARFCompileUnit.h"
@@ -22,75 +22,61 @@
using namespace lldb;
using namespace lldb_private;
-void
-NameToDIE::Finalize()
-{
- m_map.Sort ();
- m_map.SizeToFit ();
+void NameToDIE::Finalize() {
+ m_map.Sort();
+ m_map.SizeToFit();
}
-void
-NameToDIE::Insert (const ConstString& name, const DIERef& die_ref)
-{
- m_map.Append(name.GetCString(), die_ref);
+void NameToDIE::Insert(const ConstString &name, const DIERef &die_ref) {
+ m_map.Append(name.GetStringRef(), die_ref);
}
-size_t
-NameToDIE::Find (const ConstString &name, DIEArray &info_array) const
-{
- return m_map.GetValues (name.GetCString(), info_array);
+size_t NameToDIE::Find(const ConstString &name, DIEArray &info_array) const {
+ return m_map.GetValues(name.GetStringRef(), info_array);
}
-size_t
-NameToDIE::Find (const RegularExpression& regex, DIEArray &info_array) const
-{
- return m_map.GetValues (regex, info_array);
+size_t NameToDIE::Find(const RegularExpression &regex,
+ DIEArray &info_array) const {
+ return m_map.GetValues(regex, info_array);
}
-size_t
-NameToDIE::FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const
-{
- const size_t initial_size = info_array.size();
- const uint32_t size = m_map.GetSize();
- for (uint32_t i=0; i<size; ++i)
- {
- const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i);
- if (cu_offset == die_ref.cu_offset)
- info_array.push_back (die_ref);
- }
- return info_array.size() - initial_size;
+size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
+ DIEArray &info_array) const {
+ const size_t initial_size = info_array.size();
+ const uint32_t size = m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
+ if (cu_offset == die_ref.cu_offset)
+ info_array.push_back(die_ref);
+ }
+ return info_array.size() - initial_size;
}
-void
-NameToDIE::Dump (Stream *s)
-{
- const uint32_t size = m_map.GetSize();
- for (uint32_t i=0; i<size; ++i)
- {
- const char *cstr = m_map.GetCStringAtIndex(i);
- const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i);
- s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void*) cstr, die_ref.cu_offset, die_ref.die_offset, cstr);
- }
+void NameToDIE::Dump(Stream *s) {
+ const uint32_t size = m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ llvm::StringRef cstr = m_map.GetCStringAtIndex(i);
+ const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
+ s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr.data(),
+ die_ref.cu_offset, die_ref.die_offset, cstr.str().c_str());
+ }
}
-void
-NameToDIE::ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const
-{
- const uint32_t size = m_map.GetSize();
- for (uint32_t i=0; i<size; ++i)
- {
- if (!callback(m_map.GetCStringAtIndexUnchecked(i), m_map.GetValueAtIndexUnchecked (i)))
- break;
- }
+void NameToDIE::ForEach(
+ std::function<bool(llvm::StringRef name, const DIERef &die_ref)> const
+ &callback) const {
+ const uint32_t size = m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ if (!callback(m_map.GetCStringAtIndexUnchecked(i),
+ m_map.GetValueAtIndexUnchecked(i)))
+ break;
+ }
}
-void
-NameToDIE::Append (const NameToDIE& other)
-{
- const uint32_t size = other.m_map.GetSize();
- for (uint32_t i = 0; i < size; ++i)
- {
- m_map.Append(other.m_map.GetCStringAtIndexUnchecked (i),
- other.m_map.GetValueAtIndexUnchecked (i));
- }
+void NameToDIE::Append(const NameToDIE &other) {
+ const uint32_t size = other.m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ m_map.Append(other.m_map.GetCStringAtIndexUnchecked(i),
+ other.m_map.GetValueAtIndexUnchecked(i));
+ }
}
diff --git a/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/source/Plugins/SymbolFile/DWARF/NameToDIE.h
index 7fc66138f51e..e3fe321338a2 100644
--- a/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -12,51 +12,42 @@
#include <functional>
-#include "lldb/Core/dwarf.h"
+#include "DIERef.h"
#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Core/dwarf.h"
#include "lldb/lldb-defines.h"
-#include "DIERef.h"
class SymbolFileDWARF;
-class NameToDIE
-{
+class NameToDIE {
public:
- NameToDIE () :
- m_map()
- {
- }
+ NameToDIE() : m_map() {}
+
+ ~NameToDIE() {}
- ~NameToDIE ()
- {
- }
+ void Dump(lldb_private::Stream *s);
- void
- Dump (lldb_private::Stream *s);
+ void Insert(const lldb_private::ConstString &name, const DIERef &die_ref);
- void
- Insert (const lldb_private::ConstString& name, const DIERef& die_ref);
+ void Append(const NameToDIE &other);
- void
- Append (const NameToDIE& other);
+ void Finalize();
- void
- Finalize();
+ size_t Find(const lldb_private::ConstString &name,
+ DIEArray &info_array) const;
- size_t
- Find (const lldb_private::ConstString &name, DIEArray &info_array) const;
-
- size_t
- Find (const lldb_private::RegularExpression& regex, DIEArray &info_array) const;
+ size_t Find(const lldb_private::RegularExpression &regex,
+ DIEArray &info_array) const;
- size_t
- FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const;
+ size_t FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
+ DIEArray &info_array) const;
- void
- ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const;
+ void
+ ForEach(std::function<bool(llvm::StringRef name, const DIERef &die_ref)> const
+ &callback) const;
protected:
- lldb_private::UniqueCStringMap<DIERef> m_map;
+ lldb_private::UniqueCStringMap<DIERef> m_map;
};
-#endif // SymbolFileDWARF_NameToDIE_h_
+#endif // SymbolFileDWARF_NameToDIE_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 942a5d62d9b4..5c44ee03b02c 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -88,8 +88,8 @@
using namespace lldb;
using namespace lldb_private;
-//static inline bool
-//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
+// static inline bool
+// child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
//{
// switch (tag)
// {
@@ -108,4713 +108,4174 @@ using namespace lldb_private;
namespace {
- PropertyDefinition
- g_properties[] =
- {
- { "comp-dir-symlink-paths" , OptionValue::eTypeFileSpecList, true, 0 , nullptr, nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time." },
- { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr }
- };
-
- enum
- {
- ePropertySymLinkPaths
- };
-
-
- class PluginProperties : public Properties
- {
- public:
- static ConstString
- GetSettingName()
- {
- return SymbolFileDWARF::GetPluginNameStatic();
- }
+PropertyDefinition g_properties[] = {
+ {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr,
+ nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic "
+ "links will be resolved at DWARF parse time."},
+ {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
+
+enum { ePropertySymLinkPaths };
+
+class PluginProperties : public Properties {
+public:
+ static ConstString GetSettingName() {
+ return SymbolFileDWARF::GetPluginNameStatic();
+ }
+
+ PluginProperties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ FileSpecList &GetSymLinkPaths() {
+ OptionValueFileSpecList *option_value =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
+ nullptr, true, ePropertySymLinkPaths);
+ assert(option_value);
+ return option_value->GetCurrentValue();
+ }
+};
- PluginProperties()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
+typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
- FileSpecList&
- GetSymLinkPaths()
- {
- OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
- assert(option_value);
- return option_value->GetCurrentValue();
- }
+static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() {
+ static const auto g_settings_sp(std::make_shared<PluginProperties>());
+ return g_settings_sp;
+}
- };
+} // anonymous namespace end
- typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
+static const char *removeHostnameFromPathname(const char *path_from_dwarf) {
+ if (!path_from_dwarf || !path_from_dwarf[0]) {
+ return path_from_dwarf;
+ }
- static const SymbolFileDWARFPropertiesSP&
- GetGlobalPluginProperties()
- {
- static const auto g_settings_sp(std::make_shared<PluginProperties>());
- return g_settings_sp;
- }
+ const char *colon_pos = strchr(path_from_dwarf, ':');
+ if (nullptr == colon_pos) {
+ return path_from_dwarf;
+ }
-} // anonymous namespace end
+ const char *slash_pos = strchr(path_from_dwarf, '/');
+ if (slash_pos && (slash_pos < colon_pos)) {
+ return path_from_dwarf;
+ }
+ // check whether we have a windows path, and so the first character
+ // is a drive-letter not a hostname.
+ if (colon_pos == path_from_dwarf + 1 && isalpha(*path_from_dwarf) &&
+ strlen(path_from_dwarf) > 2 && '\\' == path_from_dwarf[2]) {
+ return path_from_dwarf;
+ }
-static const char*
-removeHostnameFromPathname(const char* path_from_dwarf)
-{
- if (!path_from_dwarf || !path_from_dwarf[0])
- {
- return path_from_dwarf;
- }
-
- const char *colon_pos = strchr(path_from_dwarf, ':');
- if (nullptr == colon_pos)
- {
- return path_from_dwarf;
- }
-
- const char *slash_pos = strchr(path_from_dwarf, '/');
- if (slash_pos && (slash_pos < colon_pos))
- {
- return path_from_dwarf;
- }
-
- // check whether we have a windows path, and so the first character
- // is a drive-letter not a hostname.
- if (
- colon_pos == path_from_dwarf + 1 &&
- isalpha(*path_from_dwarf) &&
- strlen(path_from_dwarf) > 2 &&
- '\\' == path_from_dwarf[2])
- {
- return path_from_dwarf;
- }
-
- return colon_pos + 1;
+ return colon_pos + 1;
}
-static const char*
-resolveCompDir(const char* path_from_dwarf)
-{
- if (!path_from_dwarf)
- return nullptr;
+static const char *resolveCompDir(const char *path_from_dwarf) {
+ if (!path_from_dwarf)
+ return nullptr;
- // DWARF2/3 suggests the form hostname:pathname for compilation directory.
- // Remove the host part if present.
- const char* local_path = removeHostnameFromPathname(path_from_dwarf);
- if (!local_path)
- return nullptr;
+ // DWARF2/3 suggests the form hostname:pathname for compilation directory.
+ // Remove the host part if present.
+ const char *local_path = removeHostnameFromPathname(path_from_dwarf);
+ if (!local_path)
+ return nullptr;
- bool is_symlink = false;
- FileSpec local_path_spec(local_path, false);
- const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
- for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
- is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
+ bool is_symlink = false;
+ FileSpec local_path_spec(local_path, false);
+ const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
+ for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
+ is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i),
+ local_path_spec, true);
- if (!is_symlink)
- return local_path;
+ if (!is_symlink)
+ return local_path;
- if (!local_path_spec.IsSymbolicLink())
- return local_path;
+ if (!local_path_spec.IsSymbolicLink())
+ return local_path;
- FileSpec resolved_local_path_spec;
- const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
- if (error.Success())
- return resolved_local_path_spec.GetCString();
+ FileSpec resolved_local_path_spec;
+ const auto error =
+ FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
+ if (error.Success())
+ return resolved_local_path_spec.GetCString();
- return nullptr;
+ return nullptr;
}
-
-void
-SymbolFileDWARF::Initialize()
-{
- LogChannelDWARF::Initialize();
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
+void SymbolFileDWARF::Initialize() {
+ LogChannelDWARF::Initialize();
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
}
-void
-SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
-{
- if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForSymbolFilePlugin(debugger,
- GetGlobalPluginProperties()->GetValueProperties(),
- ConstString ("Properties for the dwarf symbol-file plug-in."),
- is_global_setting);
- }
+void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForSymbolFilePlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForSymbolFilePlugin(
+ debugger, GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString("Properties for the dwarf symbol-file plug-in."),
+ is_global_setting);
+ }
}
-void
-SymbolFileDWARF::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
- LogChannelDWARF::Initialize();
+void SymbolFileDWARF::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+ LogChannelDWARF::Initialize();
}
-
-lldb_private::ConstString
-SymbolFileDWARF::GetPluginNameStatic()
-{
- static ConstString g_name("dwarf");
- return g_name;
+lldb_private::ConstString SymbolFileDWARF::GetPluginNameStatic() {
+ static ConstString g_name("dwarf");
+ return g_name;
}
-const char *
-SymbolFileDWARF::GetPluginDescriptionStatic()
-{
- return "DWARF and DWARF3 debug symbol file reader.";
+const char *SymbolFileDWARF::GetPluginDescriptionStatic() {
+ return "DWARF and DWARF3 debug symbol file reader.";
}
-
-SymbolFile*
-SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
-{
- return new SymbolFileDWARF(obj_file);
+SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileDWARF(obj_file);
}
-TypeList *
-SymbolFileDWARF::GetTypeList ()
-{
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- return debug_map_symfile->GetTypeList();
- else
- return m_obj_file->GetModule()->GetTypeList();
-
+TypeList *SymbolFileDWARF::GetTypeList() {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetTypeList();
+ else
+ return m_obj_file->GetModule()->GetTypeList();
}
-void
-SymbolFileDWARF::GetTypes (const DWARFDIE &die,
- dw_offset_t min_die_offset,
- dw_offset_t max_die_offset,
- uint32_t type_mask,
- TypeSet &type_set)
-{
- if (die)
- {
- const dw_offset_t die_offset = die.GetOffset();
-
- if (die_offset >= max_die_offset)
- return;
-
- if (die_offset >= min_die_offset)
- {
- const dw_tag_t tag = die.Tag();
-
- bool add_type = false;
-
- switch (tag)
- {
- case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
- case DW_TAG_unspecified_type:
- case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
- case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
- case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
- case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
- case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
- case DW_TAG_subroutine_type:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
- case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
- case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
- case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
- }
-
- if (add_type)
- {
- const bool assert_not_being_parsed = true;
- Type *type = ResolveTypeUID (die, assert_not_being_parsed);
- if (type)
- {
- if (type_set.find(type) == type_set.end())
- type_set.insert(type);
- }
- }
- }
-
- for (DWARFDIE child_die = die.GetFirstChild();
- child_die.IsValid();
- child_die = child_die.GetSibling())
- {
- GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
+void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
+ dw_offset_t max_die_offset, uint32_t type_mask,
+ TypeSet &type_set) {
+ if (die) {
+ const dw_offset_t die_offset = die.GetOffset();
+
+ if (die_offset >= max_die_offset)
+ return;
+
+ if (die_offset >= min_die_offset) {
+ const dw_tag_t tag = die.Tag();
+
+ bool add_type = false;
+
+ switch (tag) {
+ case DW_TAG_array_type:
+ add_type = (type_mask & eTypeClassArray) != 0;
+ break;
+ case DW_TAG_unspecified_type:
+ case DW_TAG_base_type:
+ add_type = (type_mask & eTypeClassBuiltin) != 0;
+ break;
+ case DW_TAG_class_type:
+ add_type = (type_mask & eTypeClassClass) != 0;
+ break;
+ case DW_TAG_structure_type:
+ add_type = (type_mask & eTypeClassStruct) != 0;
+ break;
+ case DW_TAG_union_type:
+ add_type = (type_mask & eTypeClassUnion) != 0;
+ break;
+ case DW_TAG_enumeration_type:
+ add_type = (type_mask & eTypeClassEnumeration) != 0;
+ break;
+ case DW_TAG_subroutine_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ add_type = (type_mask & eTypeClassFunction) != 0;
+ break;
+ case DW_TAG_pointer_type:
+ add_type = (type_mask & eTypeClassPointer) != 0;
+ break;
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_reference_type:
+ add_type = (type_mask & eTypeClassReference) != 0;
+ break;
+ case DW_TAG_typedef:
+ add_type = (type_mask & eTypeClassTypedef) != 0;
+ break;
+ case DW_TAG_ptr_to_member_type:
+ add_type = (type_mask & eTypeClassMemberPointer) != 0;
+ break;
+ }
+
+ if (add_type) {
+ const bool assert_not_being_parsed = true;
+ Type *type = ResolveTypeUID(die, assert_not_being_parsed);
+ if (type) {
+ if (type_set.find(type) == type_set.end())
+ type_set.insert(type);
}
+ }
}
+
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
+ child_die = child_die.GetSibling()) {
+ GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
+ }
+ }
}
-size_t
-SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
- uint32_t type_mask,
- TypeList &type_list)
+size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
+ uint32_t type_mask, TypeList &type_list)
{
- TypeSet type_set;
-
- CompileUnit *comp_unit = NULL;
- DWARFCompileUnit* dwarf_cu = NULL;
- if (sc_scope)
- comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
-
- if (comp_unit)
- {
- dwarf_cu = GetDWARFCompileUnit(comp_unit);
- if (dwarf_cu == 0)
- return 0;
- GetTypes (dwarf_cu->DIE(),
- dwarf_cu->GetOffset(),
- dwarf_cu->GetNextCompileUnitOffset(),
- type_mask,
- type_set);
- }
- else
- {
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- const size_t num_cus = info->GetNumCompileUnits();
- for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
- {
- dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- {
- GetTypes (dwarf_cu->DIE(),
- 0,
- UINT32_MAX,
- type_mask,
- type_set);
- }
- }
+ TypeSet type_set;
+
+ CompileUnit *comp_unit = NULL;
+ DWARFCompileUnit *dwarf_cu = NULL;
+ if (sc_scope)
+ comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
+
+ if (comp_unit) {
+ dwarf_cu = GetDWARFCompileUnit(comp_unit);
+ if (dwarf_cu == 0)
+ return 0;
+ GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
+ dwarf_cu->GetNextCompileUnitOffset(), type_mask, type_set);
+ } else {
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ const size_t num_cus = info->GetNumCompileUnits();
+ for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) {
+ dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu) {
+ GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set);
}
+ }
}
-
- std::set<CompilerType> compiler_type_set;
- size_t num_types_added = 0;
- for (Type *type : type_set)
- {
- CompilerType compiler_type = type->GetForwardCompilerType ();
- if (compiler_type_set.find(compiler_type) == compiler_type_set.end())
- {
- compiler_type_set.insert(compiler_type);
- type_list.Insert (type->shared_from_this());
- ++num_types_added;
- }
+ }
+
+ std::set<CompilerType> compiler_type_set;
+ size_t num_types_added = 0;
+ for (Type *type : type_set) {
+ CompilerType compiler_type = type->GetForwardCompilerType();
+ if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
+ compiler_type_set.insert(compiler_type);
+ type_list.Insert(type->shared_from_this());
+ ++num_types_added;
}
- return num_types_added;
+ }
+ return num_types_added;
}
-
//----------------------------------------------------------------------
// Gets the first parent that is a lexical block, function or inlined
// subroutine, or compile unit.
//----------------------------------------------------------------------
DWARFDIE
-SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
-{
- DWARFDIE die;
- for (die = child_die.GetParent(); die; die = die.GetParent())
- {
- dw_tag_t tag = die.Tag();
-
- switch (tag)
- {
- case DW_TAG_compile_unit:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- return die;
- }
+SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
+ DWARFDIE die;
+ for (die = child_die.GetParent(); die; die = die.GetParent()) {
+ dw_tag_t tag = die.Tag();
+
+ switch (tag) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ return die;
}
- return DWARFDIE();
+ }
+ return DWARFDIE();
}
-
-SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
- SymbolFile (objfile),
- UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
- m_debug_map_module_wp (),
- m_debug_map_symfile (NULL),
- m_data_debug_abbrev (),
- m_data_debug_aranges (),
- m_data_debug_frame (),
- m_data_debug_info (),
- m_data_debug_line (),
- m_data_debug_macro (),
- m_data_debug_loc (),
- m_data_debug_ranges (),
- m_data_debug_str (),
- m_data_apple_names (),
- m_data_apple_types (),
- m_data_apple_namespaces (),
- m_abbr(),
- m_info(),
- m_line(),
- m_apple_names_ap (),
- m_apple_types_ap (),
- m_apple_namespaces_ap (),
- m_apple_objc_ap (),
- m_function_basename_index(),
- m_function_fullname_index(),
- m_function_method_index(),
- m_function_selector_index(),
- m_objc_class_selectors_index(),
- m_global_index(),
- m_type_index(),
- m_namespace_index(),
- m_indexed (false),
- m_using_apple_tables (false),
- m_fetched_external_modules (false),
- m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
- m_ranges(),
- m_unique_ast_type_map ()
-{
+SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile)
+ : SymbolFile(objfile), UserID(0), // Used by SymbolFileDWARFDebugMap to when
+ // this class parses .o files to contain
+ // the .o file index/ID
+ m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(),
+ m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(),
+ m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(),
+ m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(),
+ m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(),
+ m_line(), m_apple_names_ap(), m_apple_types_ap(), m_apple_namespaces_ap(),
+ m_apple_objc_ap(), m_function_basename_index(),
+ m_function_fullname_index(), m_function_method_index(),
+ m_function_selector_index(), m_objc_class_selectors_index(),
+ m_global_index(), m_type_index(), m_namespace_index(), m_indexed(false),
+ m_using_apple_tables(false), m_fetched_external_modules(false),
+ m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(),
+ m_unique_ast_type_map() {}
+
+SymbolFileDWARF::~SymbolFileDWARF() {}
+
+static const ConstString &GetDWARFMachOSegmentName() {
+ static ConstString g_dwarf_section_name("__DWARF");
+ return g_dwarf_section_name;
}
-SymbolFileDWARF::~SymbolFileDWARF()
-{
+UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetUniqueDWARFASTTypeMap();
+ else
+ return m_unique_ast_type_map;
}
-static const ConstString &
-GetDWARFMachOSegmentName ()
-{
- static ConstString g_dwarf_section_name ("__DWARF");
- return g_dwarf_section_name;
+TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ TypeSystem *type_system;
+ if (debug_map_symfile) {
+ type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
+ } else {
+ type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system)
+ type_system->SetSymbolFile(this);
+ }
+ return type_system;
}
-UniqueDWARFASTTypeMap &
-SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
-{
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- return debug_map_symfile->GetUniqueDWARFASTTypeMap ();
+void SymbolFileDWARF::InitializeObject() {
+ ModuleSP module_sp(m_obj_file->GetModule());
+ if (module_sp) {
+ const SectionList *section_list = module_sp->GetSectionList();
+ const Section *section =
+ section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
+
+ // Memory map the DWARF mach-o segment so we have everything mmap'ed
+ // to keep our heap memory usage down.
+ if (section)
+ m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
+ }
+
+ get_apple_names_data();
+ if (m_data_apple_names.m_data.GetByteSize() > 0) {
+ m_apple_names_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_names.m_data, get_debug_str_data(), ".apple_names"));
+ if (m_apple_names_ap->IsValid())
+ m_using_apple_tables = true;
else
- return m_unique_ast_type_map;
-}
-
-TypeSystem *
-SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
-{
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- TypeSystem *type_system;
- if (debug_map_symfile)
- {
- type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
- }
+ m_apple_names_ap.reset();
+ }
+ get_apple_types_data();
+ if (m_data_apple_types.m_data.GetByteSize() > 0) {
+ m_apple_types_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_types.m_data, get_debug_str_data(), ".apple_types"));
+ if (m_apple_types_ap->IsValid())
+ m_using_apple_tables = true;
else
- {
- type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- }
- return type_system;
-}
-
-void
-SymbolFileDWARF::InitializeObject()
-{
- ModuleSP module_sp (m_obj_file->GetModule());
- if (module_sp)
- {
- const SectionList *section_list = module_sp->GetSectionList();
- const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
-
- // Memory map the DWARF mach-o segment so we have everything mmap'ed
- // to keep our heap memory usage down.
- if (section)
- m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
- }
-
- get_apple_names_data();
- if (m_data_apple_names.m_data.GetByteSize() > 0)
- {
- m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names.m_data,
- get_debug_str_data(),
- ".apple_names"));
- if (m_apple_names_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_names_ap.reset();
- }
- get_apple_types_data();
- if (m_data_apple_types.m_data.GetByteSize() > 0)
- {
- m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types.m_data,
- get_debug_str_data(),
- ".apple_types"));
- if (m_apple_types_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_types_ap.reset();
- }
-
- get_apple_namespaces_data();
- if (m_data_apple_namespaces.m_data.GetByteSize() > 0)
- {
- m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces.m_data,
- get_debug_str_data(),
- ".apple_namespaces"));
- if (m_apple_namespaces_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_namespaces_ap.reset();
- }
-
- get_apple_objc_data();
- if (m_data_apple_objc.m_data.GetByteSize() > 0)
- {
- m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc.m_data,
- get_debug_str_data(),
- ".apple_objc"));
- if (m_apple_objc_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_objc_ap.reset();
- }
+ m_apple_types_ap.reset();
+ }
+
+ get_apple_namespaces_data();
+ if (m_data_apple_namespaces.m_data.GetByteSize() > 0) {
+ m_apple_namespaces_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_namespaces.m_data, get_debug_str_data(),
+ ".apple_namespaces"));
+ if (m_apple_namespaces_ap->IsValid())
+ m_using_apple_tables = true;
+ else
+ m_apple_namespaces_ap.reset();
+ }
+
+ get_apple_objc_data();
+ if (m_data_apple_objc.m_data.GetByteSize() > 0) {
+ m_apple_objc_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_objc.m_data, get_debug_str_data(), ".apple_objc"));
+ if (m_apple_objc_ap->IsValid())
+ m_using_apple_tables = true;
+ else
+ m_apple_objc_ap.reset();
+ }
}
-bool
-SymbolFileDWARF::SupportedVersion(uint16_t version)
-{
- return version == 2 || version == 3 || version == 4;
+bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
+ return version == 2 || version == 3 || version == 4;
}
-uint32_t
-SymbolFileDWARF::CalculateAbilities ()
-{
- uint32_t abilities = 0;
- if (m_obj_file != NULL)
- {
- const Section* section = NULL;
- const SectionList *section_list = m_obj_file->GetSectionList();
- if (section_list == NULL)
- return 0;
-
- uint64_t debug_abbrev_file_size = 0;
- uint64_t debug_info_file_size = 0;
- uint64_t debug_line_file_size = 0;
-
- section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
-
- if (section)
- section_list = &section->GetChildren ();
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
- if (section != NULL)
- {
- debug_info_file_size = section->GetFileSize();
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
- if (section)
- debug_abbrev_file_size = section->GetFileSize();
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
- if (section)
- debug_line_file_size = section->GetFileSize();
- }
- else
- {
- const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
- if (symfile_dir_cstr)
- {
- if (strcasestr(symfile_dir_cstr, ".dsym"))
- {
- if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
- {
- // We have a dSYM file that didn't have a any debug info.
- // If the string table has a size of 1, then it was made from
- // an executable with no debug info, or from an executable that
- // was stripped.
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
- if (section && section->GetFileSize() == 1)
- {
- m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
- }
- }
- }
+uint32_t SymbolFileDWARF::CalculateAbilities() {
+ uint32_t abilities = 0;
+ if (m_obj_file != NULL) {
+ const Section *section = NULL;
+ const SectionList *section_list = m_obj_file->GetSectionList();
+ if (section_list == NULL)
+ return 0;
+
+ uint64_t debug_abbrev_file_size = 0;
+ uint64_t debug_info_file_size = 0;
+ uint64_t debug_line_file_size = 0;
+
+ section = section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
+
+ if (section)
+ section_list = &section->GetChildren();
+
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get();
+ if (section != NULL) {
+ debug_info_file_size = section->GetFileSize();
+
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugAbbrev, true)
+ .get();
+ if (section)
+ debug_abbrev_file_size = section->GetFileSize();
+
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true)
+ .get();
+ if (section)
+ debug_line_file_size = section->GetFileSize();
+ } else {
+ const char *symfile_dir_cstr =
+ m_obj_file->GetFileSpec().GetDirectory().GetCString();
+ if (symfile_dir_cstr) {
+ if (strcasestr(symfile_dir_cstr, ".dsym")) {
+ if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) {
+ // We have a dSYM file that didn't have a any debug info.
+ // If the string table has a size of 1, then it was made from
+ // an executable with no debug info, or from an executable that
+ // was stripped.
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)
+ .get();
+ if (section && section->GetFileSize() == 1) {
+ m_obj_file->GetModule()->ReportWarning(
+ "empty dSYM file detected, dSYM was created with an "
+ "executable with no debug info.");
}
+ }
}
+ }
+ }
- if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
- abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
+ if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
+ abilities |= CompileUnits | Functions | Blocks | GlobalVariables |
+ LocalVariables | VariableTypes;
- if (debug_line_file_size > 0)
- abilities |= LineTables;
- }
- return abilities;
+ if (debug_line_file_size > 0)
+ abilities |= LineTables;
+ }
+ return abilities;
}
-const DWARFDataExtractor&
-SymbolFileDWARF::GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment)
-{
- std::call_once(data_segment.m_flag,
- &SymbolFileDWARF::LoadSectionData,
- this,
- sect_type,
- std::ref(data_segment.m_data));
- return data_segment.m_data;
+const DWARFDataExtractor &
+SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
+ DWARFDataSegment &data_segment) {
+ std::call_once(data_segment.m_flag, &SymbolFileDWARF::LoadSectionData, this,
+ sect_type, std::ref(data_segment.m_data));
+ return data_segment.m_data;
}
-void
-SymbolFileDWARF::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data)
-{
- ModuleSP module_sp (m_obj_file->GetModule());
- const SectionList *section_list = module_sp->GetSectionList();
- if (section_list)
- {
- SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
- if (section_sp)
- {
- // See if we memory mapped the DWARF segment?
- if (m_dwarf_data.GetByteSize())
- {
- data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize());
- }
- else
- {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
- data.Clear();
- }
- }
+void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
+ DWARFDataExtractor &data) {
+ ModuleSP module_sp(m_obj_file->GetModule());
+ const SectionList *section_list = module_sp->GetSectionList();
+ if (section_list) {
+ SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
+ if (section_sp) {
+ // See if we memory mapped the DWARF segment?
+ if (m_dwarf_data.GetByteSize()) {
+ data.SetData(m_dwarf_data, section_sp->GetOffset(),
+ section_sp->GetFileSize());
+ } else {
+ if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
+ data.Clear();
+ }
}
+ }
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_abbrev_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_abbrev_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugAbbrev,
+ m_data_debug_abbrev);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_addr_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugAddr, m_data_debug_addr);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_addr_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugAddr, m_data_debug_addr);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_aranges_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_aranges_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugAranges,
+ m_data_debug_aranges);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_frame_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugFrame, m_data_debug_frame);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_frame_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_info_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugInfo, m_data_debug_info);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_line_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugLine, m_data_debug_line);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_macro_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugMacro, m_data_debug_macro);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_loc_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_loc_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugLoc, m_data_debug_loc);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_ranges_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugRanges,
+ m_data_debug_ranges);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_str_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugStr, m_data_debug_str);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_str_offsets_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_offsets_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsets,
+ m_data_debug_str_offsets);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_names_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleNames, m_data_apple_names);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_types_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleTypes, m_data_apple_types);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_types_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleTypes, m_data_apple_types);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_namespaces_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_namespaces_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleNamespaces,
+ m_data_apple_namespaces);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_objc_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleObjC, m_data_apple_objc);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_objc_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleObjC, m_data_apple_objc);
}
-
-DWARFDebugAbbrev*
-SymbolFileDWARF::DebugAbbrev()
-{
- if (m_abbr.get() == NULL)
- {
- const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
- if (debug_abbrev_data.GetByteSize() > 0)
- {
- m_abbr.reset(new DWARFDebugAbbrev());
- if (m_abbr.get())
- m_abbr->Parse(debug_abbrev_data);
- }
+DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
+ if (m_abbr.get() == NULL) {
+ const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
+ if (debug_abbrev_data.GetByteSize() > 0) {
+ m_abbr.reset(new DWARFDebugAbbrev());
+ if (m_abbr.get())
+ m_abbr->Parse(debug_abbrev_data);
}
- return m_abbr.get();
+ }
+ return m_abbr.get();
}
-const DWARFDebugAbbrev*
-SymbolFileDWARF::DebugAbbrev() const
-{
- return m_abbr.get();
+const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const {
+ return m_abbr.get();
}
-
-DWARFDebugInfo*
-SymbolFileDWARF::DebugInfo()
-{
- if (m_info.get() == NULL)
- {
- Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
- __PRETTY_FUNCTION__, static_cast<void*>(this));
- if (get_debug_info_data().GetByteSize() > 0)
- {
- m_info.reset(new DWARFDebugInfo());
- if (m_info.get())
- {
- m_info->SetDwarfData(this);
- }
- }
+DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
+ if (m_info.get() == NULL) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p",
+ LLVM_PRETTY_FUNCTION, static_cast<void *>(this));
+ if (get_debug_info_data().GetByteSize() > 0) {
+ m_info.reset(new DWARFDebugInfo());
+ if (m_info.get()) {
+ m_info->SetDwarfData(this);
+ }
}
- return m_info.get();
+ }
+ return m_info.get();
}
-const DWARFDebugInfo*
-SymbolFileDWARF::DebugInfo() const
-{
- return m_info.get();
+const DWARFDebugInfo *SymbolFileDWARF::DebugInfo() const {
+ return m_info.get();
}
-DWARFCompileUnit*
-SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
-{
- if (!comp_unit)
- return nullptr;
-
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- // Just a normal DWARF file whose user ID for the compile unit is
- // the DWARF offset itself
-
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
- if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
- dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
- }
- return NULL;
-}
+DWARFCompileUnit *
+SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
+ if (!comp_unit)
+ return nullptr;
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ // Just a normal DWARF file whose user ID for the compile unit is
+ // the DWARF offset itself
+
+ DWARFCompileUnit *dwarf_cu =
+ info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
+ }
+ return NULL;
+}
-DWARFDebugRanges*
-SymbolFileDWARF::DebugRanges()
-{
- if (m_ranges.get() == NULL)
- {
- Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
- __PRETTY_FUNCTION__, static_cast<void*>(this));
- if (get_debug_ranges_data().GetByteSize() > 0)
- {
- m_ranges.reset(new DWARFDebugRanges());
- if (m_ranges.get())
- m_ranges->Extract(this);
- }
+DWARFDebugRanges *SymbolFileDWARF::DebugRanges() {
+ if (m_ranges.get() == NULL) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p",
+ LLVM_PRETTY_FUNCTION, static_cast<void *>(this));
+ if (get_debug_ranges_data().GetByteSize() > 0) {
+ m_ranges.reset(new DWARFDebugRanges());
+ if (m_ranges.get())
+ m_ranges->Extract(this);
}
- return m_ranges.get();
+ }
+ return m_ranges.get();
}
-const DWARFDebugRanges*
-SymbolFileDWARF::DebugRanges() const
-{
- return m_ranges.get();
+const DWARFDebugRanges *SymbolFileDWARF::DebugRanges() const {
+ return m_ranges.get();
}
-lldb::CompUnitSP
-SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
-{
- CompUnitSP cu_sp;
- if (dwarf_cu)
- {
- CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
- if (comp_unit)
- {
- // We already parsed this compile unit, had out a shared pointer to it
- cu_sp = comp_unit->shared_from_this();
- }
- else
- {
- if (dwarf_cu->GetSymbolFileDWARF() != this)
- {
- return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
- }
- else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile ())
- {
- // Let the debug map create the compile unit
- cu_sp = m_debug_map_symfile->GetCompileUnit(this);
- dwarf_cu->SetUserData(cu_sp.get());
+lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) {
+ CompUnitSP cu_sp;
+ if (dwarf_cu) {
+ CompileUnit *comp_unit = (CompileUnit *)dwarf_cu->GetUserData();
+ if (comp_unit) {
+ // We already parsed this compile unit, had out a shared pointer to it
+ cu_sp = comp_unit->shared_from_this();
+ } else {
+ if (dwarf_cu->GetSymbolFileDWARF() != this) {
+ return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu,
+ cu_idx);
+ } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) {
+ // Let the debug map create the compile unit
+ cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+ dwarf_cu->SetUserData(cu_sp.get());
+ } else {
+ ModuleSP module_sp(m_obj_file->GetModule());
+ if (module_sp) {
+ const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (cu_die) {
+ FileSpec cu_file_spec{cu_die.GetName(), false};
+ if (cu_file_spec) {
+ // If we have a full path to the compile unit, we don't need to
+ // resolve
+ // the file. This can be expensive e.g. when the source files are
+ // NFS mounted.
+ if (cu_file_spec.IsRelative()) {
+ const char *cu_comp_dir{
+ cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
+ cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
+ }
+
+ std::string remapped_file;
+ if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
+ remapped_file))
+ cu_file_spec.SetFile(remapped_file, false);
}
- else
- {
- ModuleSP module_sp (m_obj_file->GetModule());
- if (module_sp)
- {
- const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
- if (cu_die)
- {
- FileSpec cu_file_spec{cu_die.GetName(), false};
- if (cu_file_spec)
- {
- // If we have a full path to the compile unit, we don't need to resolve
- // the file. This can be expensive e.g. when the source files are NFS mounted.
- if (cu_file_spec.IsRelative())
- {
- const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
- cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
- }
-
- std::string remapped_file;
- if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
- cu_file_spec.SetFile(remapped_file, false);
- }
- LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
-
- bool is_optimized = dwarf_cu->GetIsOptimized ();
- cu_sp.reset(new CompileUnit(module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(), cu_language,
- is_optimized ? eLazyBoolYes : eLazyBoolNo));
- if (cu_sp)
- {
- // If we just created a compile unit with an invalid file spec, try and get the
- // first entry in the supports files from the line table as that should be the
- // compile unit.
- if (!cu_file_spec)
- {
- cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
- if (cu_file_spec)
- {
- (FileSpec &)(*cu_sp) = cu_file_spec;
- // Also fix the invalid file spec which was copied from the compile unit.
- cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
- }
- }
-
- dwarf_cu->SetUserData(cu_sp.get());
-
- // Figure out the compile unit index if we weren't given one
- if (cu_idx == UINT32_MAX)
- DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
-
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
- }
- }
+ LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(
+ cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
+
+ bool is_optimized = dwarf_cu->GetIsOptimized();
+ cu_sp.reset(new CompileUnit(
+ module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(),
+ cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo));
+ if (cu_sp) {
+ // If we just created a compile unit with an invalid file spec,
+ // try and get the
+ // first entry in the supports files from the line table as that
+ // should be the
+ // compile unit.
+ if (!cu_file_spec) {
+ cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
+ if (cu_file_spec) {
+ (FileSpec &)(*cu_sp) = cu_file_spec;
+ // Also fix the invalid file spec which was copied from the
+ // compile unit.
+ cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
}
+ }
+
+ dwarf_cu->SetUserData(cu_sp.get());
+
+ // Figure out the compile unit index if we weren't given one
+ if (cu_idx == UINT32_MAX)
+ DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
+
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ cu_idx, cu_sp);
}
+ }
}
+ }
}
- return cu_sp;
+ }
+ return cu_sp;
}
-uint32_t
-SymbolFileDWARF::GetNumCompileUnits()
-{
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- return info->GetNumCompileUnits();
- return 0;
+uint32_t SymbolFileDWARF::GetNumCompileUnits() {
+ DWARFDebugInfo *info = DebugInfo();
+ if (info)
+ return info->GetNumCompileUnits();
+ return 0;
}
-CompUnitSP
-SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
-{
- CompUnitSP cu_sp;
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
- }
- return cu_sp;
+CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
+ CompUnitSP cu_sp;
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu)
+ cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
+ }
+ return cu_sp;
}
-Function *
-SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
-{
- if (die.IsValid())
- {
- TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
-
- if (type_system)
- {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->ParseFunctionFromDWARF(sc, die);
- }
+Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc,
+ const DWARFDIE &die) {
+ if (die.IsValid()) {
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+
+ if (type_system) {
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->ParseFunctionFromDWARF(sc, die);
}
- return nullptr;
+ }
+ return nullptr;
}
-bool
-SymbolFileDWARF::FixupAddress (Address &addr)
-{
- SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- return debug_map_symfile->LinkOSOAddress(addr);
- }
- // This is a normal DWARF file, no address fixups need to happen
- return true;
+bool SymbolFileDWARF::FixupAddress(Address &addr) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ return debug_map_symfile->LinkOSOAddress(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);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- return dwarf_cu->GetLanguageType();
- else
- return eLanguageTypeUnknown;
+SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) {
+ assert(sc.comp_unit);
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.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 functions_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- DWARFDIECollection function_dies;
- const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
- 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))
- ++functions_added;
- }
- }
- //FixupTypes();
+size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) {
+ assert(sc.comp_unit);
+ size_t functions_added = 0;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ DWARFDIECollection function_dies;
+ const size_t num_functions =
+ dwarf_cu->AppendDIEsWithTag(DW_TAG_subprogram, function_dies);
+ 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))
+ ++functions_added;
+ }
}
- return functions_added;
+ // FixupTypes();
+ }
+ return functions_added;
}
-bool
-SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
-{
- assert (sc.comp_unit);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
-
- if (cu_die)
- {
- const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
- const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
- 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);
- return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(),
- get_debug_line_data(),
- cu_comp_dir,
- stmt_list,
- support_files);
- }
- }
+bool SymbolFileDWARF::ParseCompileUnitSupportFiles(
+ const SymbolContext &sc, FileSpecList &support_files) {
+ assert(sc.comp_unit);
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+
+ if (cu_die) {
+ const char *cu_comp_dir = resolveCompDir(
+ cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
+ const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(
+ DW_AT_stmt_list, DW_INVALID_OFFSET);
+ 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);
+ return DWARFDebugLine::ParseSupportFiles(
+ sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir,
+ stmt_list, support_files);
+ }
}
- return false;
+ }
+ return false;
}
-bool
-SymbolFileDWARF::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
-{
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- return dwarf_cu->GetIsOptimized();
- return false;
+bool SymbolFileDWARF::ParseCompileUnitIsOptimized(
+ const lldb_private::SymbolContext &sc) {
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu)
+ return dwarf_cu->GetIsOptimized();
+ return false;
}
-bool
-SymbolFileDWARF::ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules)
-{
- assert (sc.comp_unit);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
- {
- UpdateExternalModuleListIfNeeded();
-
- if (sc.comp_unit)
- {
- const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
-
- if (die)
- {
- for (DWARFDIE child_die = die.GetFirstChild();
- child_die;
- child_die = child_die.GetSibling())
- {
- if (child_die.Tag() == DW_TAG_imported_declaration)
- {
- if (DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import))
- {
- if (module_die.Tag() == DW_TAG_module)
- {
- if (const char *name = module_die.GetAttributeValueAsString(DW_AT_name, nullptr))
- {
- ConstString const_name(name);
- imported_modules.push_back(const_name);
- }
- }
- }
- }
- }
- }
- }
- else
- {
- for (const auto &pair : m_external_type_modules)
- {
- imported_modules.push_back(pair.first);
+bool SymbolFileDWARF::ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) {
+ assert(sc.comp_unit);
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ if (ClangModulesDeclVendor::LanguageSupportsClangModules(
+ sc.comp_unit->GetLanguage())) {
+ UpdateExternalModuleListIfNeeded();
+
+ if (sc.comp_unit) {
+ const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+
+ if (die) {
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die;
+ child_die = child_die.GetSibling()) {
+ if (child_die.Tag() == DW_TAG_imported_declaration) {
+ if (DWARFDIE module_die =
+ child_die.GetReferencedDIE(DW_AT_import)) {
+ if (module_die.Tag() == DW_TAG_module) {
+ if (const char *name = module_die.GetAttributeValueAsString(
+ DW_AT_name, nullptr)) {
+ ConstString const_name(name);
+ imported_modules.push_back(const_name);
+ }
}
+ }
}
+ }
+ }
+ } else {
+ for (const auto &pair : m_external_type_modules) {
+ imported_modules.push_back(pair.first);
}
+ }
}
- return false;
+ }
+ return false;
}
-struct ParseDWARFLineTableCallbackInfo
-{
- LineTable* line_table;
- std::unique_ptr<LineSequence> sequence_ap;
- lldb::addr_t addr_mask;
+struct ParseDWARFLineTableCallbackInfo {
+ LineTable *line_table;
+ std::unique_ptr<LineSequence> sequence_ap;
+ lldb::addr_t addr_mask;
};
//----------------------------------------------------------------------
// ParseStatementTableCallback
//----------------------------------------------------------------------
-static void
-ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
-{
- if (state.row == DWARFDebugLine::State::StartParsingLineTable)
- {
- // Just started parsing the line table
+static void ParseDWARFLineTableCallback(dw_offset_t offset,
+ const DWARFDebugLine::State &state,
+ void *userData) {
+ if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
+ // Just started parsing the line table
+ } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
+ // Done parsing line table, nothing to do for the cleanup
+ } else {
+ ParseDWARFLineTableCallbackInfo *info =
+ (ParseDWARFLineTableCallbackInfo *)userData;
+ LineTable *line_table = info->line_table;
+
+ // If this is our first time here, we need to create a
+ // sequence container.
+ if (!info->sequence_ap.get()) {
+ info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
+ assert(info->sequence_ap.get());
}
- else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
- {
- // Done parsing line table, nothing to do for the cleanup
- }
- else
- {
- ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
- LineTable* line_table = info->line_table;
-
- // If this is our first time here, we need to create a
- // sequence container.
- if (!info->sequence_ap.get())
- {
- info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
- assert(info->sequence_ap.get());
- }
- line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
- state.address & info->addr_mask,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- if (state.end_sequence)
- {
- // First, put the current sequence into the line table.
- line_table->InsertSequence(info->sequence_ap.get());
- // Then, empty it to prepare for the next sequence.
- info->sequence_ap->Clear();
- }
+ line_table->AppendLineEntryToSequence(
+ info->sequence_ap.get(), state.address & info->addr_mask, state.line,
+ state.column, state.file, state.is_stmt, state.basic_block,
+ state.prologue_end, state.epilogue_begin, state.end_sequence);
+ if (state.end_sequence) {
+ // First, put the current sequence into the line table.
+ line_table->InsertSequence(info->sequence_ap.get());
+ // Then, empty it to prepare for the next sequence.
+ info->sequence_ap->Clear();
}
+ }
}
-bool
-SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
-{
- assert (sc.comp_unit);
- if (sc.comp_unit->GetLineTable() != NULL)
- return true;
-
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
- if (dwarf_cu_die)
- {
- const dw_offset_t cu_line_offset = 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));
- if (line_table_ap.get())
- {
- ParseDWARFLineTableCallbackInfo info;
- info.line_table = line_table_ap.get();
-
- /*
- * MIPS:
- * The SymbolContext may not have a valid target, thus we may not be able
- * to call Address::GetOpcodeLoadAddress() which would clear the bit #0
- * for MIPS. Use ArchSpec to clear the bit #0.
- */
- ArchSpec arch;
- GetObjectFile()->GetArchitecture(arch);
- switch (arch.GetMachine())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- info.addr_mask = ~((lldb::addr_t)1);
- break;
- default:
- info.addr_mask = ~((lldb::addr_t)0);
- break;
- }
+bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
+ assert(sc.comp_unit);
+ if (sc.comp_unit->GetLineTable() != NULL)
+ return true;
- lldb::offset_t offset = cu_line_offset;
- DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- // We have an object file that has a line table with addresses
- // that are not linked. We need to link the line table and convert
- // the addresses that are relative to the .o file into addresses
- // for the main executable.
- sc.comp_unit->SetLineTable (debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
- }
- else
- {
- sc.comp_unit->SetLineTable(line_table_ap.release());
- return true;
- }
- }
- }
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (dwarf_cu_die) {
+ const dw_offset_t cu_line_offset =
+ 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));
+ if (line_table_ap.get()) {
+ ParseDWARFLineTableCallbackInfo info;
+ info.line_table = line_table_ap.get();
+
+ /*
+ * MIPS:
+ * The SymbolContext may not have a valid target, thus we may not be
+ * able
+ * to call Address::GetOpcodeLoadAddress() which would clear the bit
+ * #0
+ * for MIPS. Use ArchSpec to clear the bit #0.
+ */
+ ArchSpec arch;
+ GetObjectFile()->GetArchitecture(arch);
+ switch (arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ info.addr_mask = ~((lldb::addr_t)1);
+ break;
+ default:
+ info.addr_mask = ~((lldb::addr_t)0);
+ break;
+ }
+
+ lldb::offset_t offset = cu_line_offset;
+ DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset,
+ ParseDWARFLineTableCallback,
+ &info);
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We have an object file that has a line table with addresses
+ // that are not linked. We need to link the line table and convert
+ // the addresses that are relative to the .o file into addresses
+ // for the main executable.
+ sc.comp_unit->SetLineTable(
+ debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get()));
+ } else {
+ sc.comp_unit->SetLineTable(line_table_ap.release());
+ return true;
+ }
}
+ }
}
- return false;
+ }
+ return false;
}
lldb_private::DebugMacrosSP
-SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset)
-{
- auto iter = m_debug_macros_map.find(*offset);
- if (iter != m_debug_macros_map.end())
- return iter->second;
+SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
+ auto iter = m_debug_macros_map.find(*offset);
+ if (iter != m_debug_macros_map.end())
+ return iter->second;
- const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
- if (debug_macro_data.GetByteSize() == 0)
- return DebugMacrosSP();
+ const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
+ if (debug_macro_data.GetByteSize() == 0)
+ return DebugMacrosSP();
- lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
- m_debug_macros_map[*offset] = debug_macros_sp;
+ lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
+ m_debug_macros_map[*offset] = debug_macros_sp;
- const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
- DWARFDebugMacroEntry::ReadMacroEntries(
- debug_macro_data, get_debug_str_data(), header.OffsetIs64Bit(), offset, this, debug_macros_sp);
+ const DWARFDebugMacroHeader &header =
+ DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
+ DWARFDebugMacroEntry::ReadMacroEntries(debug_macro_data, get_debug_str_data(),
+ header.OffsetIs64Bit(), offset, this,
+ debug_macros_sp);
- return debug_macros_sp;
+ return debug_macros_sp;
}
-bool
-SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext& sc)
-{
- assert (sc.comp_unit);
+bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
+ assert(sc.comp_unit);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu == nullptr)
- return false;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu == nullptr)
+ return false;
- const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
- if (!dwarf_cu_die)
- return false;
+ const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (!dwarf_cu_die)
+ return false;
- lldb::offset_t sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
- if (sect_offset == DW_INVALID_OFFSET)
- sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros, DW_INVALID_OFFSET);
- if (sect_offset == DW_INVALID_OFFSET)
- return false;
+ lldb::offset_t sect_offset =
+ dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
+ if (sect_offset == DW_INVALID_OFFSET)
+ sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros,
+ DW_INVALID_OFFSET);
+ if (sect_offset == DW_INVALID_OFFSET)
+ return false;
- sc.comp_unit->SetDebugMacros(ParseDebugMacros(&sect_offset));
+ sc.comp_unit->SetDebugMacros(ParseDebugMacros(&sect_offset));
- return true;
+ 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 blocks_added = 0;
- DWARFDIE die = orig_die;
- while (die)
- {
- dw_tag_t tag = die.Tag();
-
- switch (tag)
- {
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- {
- Block *block = NULL;
- if (tag == DW_TAG_subprogram)
- {
- // Skip any DW_TAG_subprogram DIEs that are inside
- // of a normal or inlined functions. These will be
- // parsed on their own as separate entities.
-
- if (depth > 0)
- break;
-
- block = parent_block;
- }
- else
- {
- BlockSP block_sp(new Block (die.GetID()));
- parent_block->AddChild(block_sp);
- block = block_sp.get();
- }
- DWARFRangeList ranges;
- const char *name = NULL;
- const char *mangled_name = 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;
- if (die.GetDIENamesAndRanges (name,
- mangled_name,
- ranges,
- decl_file, decl_line, decl_column,
- call_file, call_line, call_column, nullptr))
- {
- if (tag == DW_TAG_subprogram)
- {
- assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
- subprogram_low_pc = ranges.GetMinRangeBase(0);
- }
- else if (tag == DW_TAG_inlined_subroutine)
- {
- // We get called here for inlined subroutines in two ways.
- // The first time is when we are making the Function object
- // for this inlined concrete instance. Since we're creating a top level block at
- // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
- // adjust the containing address.
- // The second time is when we are parsing the blocks inside the function that contains
- // the inlined concrete instance. Since these will be blocks inside the containing "real"
- // function the offset will be for that function.
- if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
- {
- subprogram_low_pc = ranges.GetMinRangeBase(0);
- }
- }
-
- const size_t num_ranges = ranges.GetSize();
- for (size_t i = 0; i<num_ranges; ++i)
- {
- const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
- const addr_t range_base = range.GetRangeBase();
- if (range_base >= subprogram_low_pc)
- block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
- else
- {
- GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
- block->GetID(),
- range_base,
- range.GetRangeEnd(),
- subprogram_low_pc);
- }
- }
- block->FinalizeRanges ();
-
- if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
- {
- 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));
-
- 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),
- call_line, call_column));
+size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
+ 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) {
+ dw_tag_t tag = die.Tag();
+
+ switch (tag) {
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block: {
+ Block *block = NULL;
+ if (tag == DW_TAG_subprogram) {
+ // Skip any DW_TAG_subprogram DIEs that are inside
+ // of a normal or inlined functions. These will be
+ // parsed on their own as separate entities.
+
+ if (depth > 0)
+ break;
+
+ block = parent_block;
+ } else {
+ BlockSP block_sp(new Block(die.GetID()));
+ parent_block->AddChild(block_sp);
+ block = block_sp.get();
+ }
+ DWARFRangeList ranges;
+ const char *name = NULL;
+ const char *mangled_name = 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;
+ if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
+ decl_line, decl_column, call_file, call_line,
+ call_column, nullptr)) {
+ if (tag == DW_TAG_subprogram) {
+ assert(subprogram_low_pc == LLDB_INVALID_ADDRESS);
+ subprogram_low_pc = ranges.GetMinRangeBase(0);
+ } else if (tag == DW_TAG_inlined_subroutine) {
+ // We get called here for inlined subroutines in two ways.
+ // The first time is when we are making the Function object
+ // for this inlined concrete instance. Since we're creating a top
+ // level block at
+ // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we
+ // need to
+ // adjust the containing address.
+ // The second time is when we are parsing the blocks inside the
+ // function that contains
+ // the inlined concrete instance. Since these will be blocks inside
+ // the containing "real"
+ // function the offset will be for that function.
+ if (subprogram_low_pc == LLDB_INVALID_ADDRESS) {
+ subprogram_low_pc = ranges.GetMinRangeBase(0);
+ }
+ }
- block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
- }
+ const size_t num_ranges = ranges.GetSize();
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
+ const addr_t range_base = range.GetRangeBase();
+ if (range_base >= subprogram_low_pc)
+ block->AddRange(Block::Range(range_base - subprogram_low_pc,
+ range.GetByteSize()));
+ else {
+ GetObjectFile()->GetModule()->ReportError(
+ "0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64
+ ") which has a base that is less than the function's low PC "
+ "0x%" PRIx64 ". Please file a bug and attach the file at the "
+ "start of this error message",
+ block->GetID(), range_base, range.GetRangeEnd(),
+ subprogram_low_pc);
+ }
+ }
+ block->FinalizeRanges();
+
+ if (tag != DW_TAG_subprogram &&
+ (name != NULL || mangled_name != NULL)) {
+ 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));
+
+ 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),
+ call_line, call_column));
+
+ block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(),
+ call_ap.get());
+ }
- ++blocks_added;
+ ++blocks_added;
- if (die.HasChildren())
- {
- blocks_added += ParseFunctionBlocks (sc,
- block,
- die.GetFirstChild(),
- subprogram_low_pc,
- depth + 1);
- }
- }
- }
- break;
- default:
- break;
+ if (die.HasChildren()) {
+ blocks_added += ParseFunctionBlocks(sc, block, die.GetFirstChild(),
+ subprogram_low_pc, depth + 1);
}
-
- // Only parse siblings of the block if we are not at depth zero. A depth
- // of zero indicates we are currently parsing the top level
- // DW_TAG_subprogram DIE
-
- if (depth == 0)
- die.Clear();
- else
- die = die.GetSibling();
+ }
+ } break;
+ default:
+ break;
}
- return blocks_added;
+
+ // Only parse siblings of the block if we are not at depth zero. A depth
+ // of zero indicates we are currently parsing the top level
+ // DW_TAG_subprogram DIE
+
+ if (depth == 0)
+ die.Clear();
+ else
+ die = die.GetSibling();
+ }
+ return blocks_added;
}
-bool
-SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
-{
- if (parent_die)
- {
- for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
- {
- dw_tag_t tag = die.Tag();
- bool check_virtuality = false;
- switch (tag)
- {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- check_virtuality = true;
- break;
- default:
- break;
- }
- if (check_virtuality)
- {
- if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
- return true;
- }
- }
+bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
+ if (parent_die) {
+ for (DWARFDIE die = parent_die.GetFirstChild(); die;
+ die = die.GetSibling()) {
+ dw_tag_t tag = die.Tag();
+ bool check_virtuality = false;
+ switch (tag) {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ check_virtuality = true;
+ break;
+ default:
+ break;
+ }
+ if (check_virtuality) {
+ if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-void
-SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
-{
- TypeSystem *type_system = decl_ctx.GetTypeSystem();
- DWARFASTParser *ast_parser = type_system->GetDWARFParser();
- std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
+void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
+ TypeSystem *type_system = decl_ctx.GetTypeSystem();
+ DWARFASTParser *ast_parser = type_system->GetDWARFParser();
+ std::vector<DWARFDIE> decl_ctx_die_list =
+ ast_parser->GetDIEForDeclContext(decl_ctx);
- for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
- for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
- ast_parser->GetDeclForUIDFromDWARF(decl);
+ for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
+ for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl;
+ decl = decl.GetSibling())
+ ast_parser->GetDeclForUIDFromDWARF(decl);
}
-SymbolFileDWARF *
-SymbolFileDWARF::GetDWARFForUID (lldb::user_id_t uid)
-{
- // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
- // we must make sure we use the correct DWARF file when resolving things.
- // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
- // SymbolFileDWARF classes, one for each .o file. We can often end up
- // with references to other DWARF objects and we must be ready to receive
- // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
- // instance.
- SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
- if (debug_map)
- return debug_map->GetSymbolFileByOSOIndex(debug_map->GetOSOIndexFromUserID(uid));
- return this;
+SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
+ if (debug_map)
+ return debug_map->GetSymbolFileByOSOIndex(
+ debug_map->GetOSOIndexFromUserID(uid));
+ return this;
}
DWARFDIE
-SymbolFileDWARF::GetDIEFromUID (lldb::user_id_t uid)
-{
- // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
- // we must make sure we use the correct DWARF file when resolving things.
- // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
- // SymbolFileDWARF classes, one for each .o file. We can often end up
- // with references to other DWARF objects and we must be ready to receive
- // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
- // instance.
- SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
- if (dwarf)
- return dwarf->GetDIE(DIERef(uid, dwarf));
- return DWARFDIE();
+SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
+ if (dwarf)
+ return dwarf->GetDIE(DIERef(uid, dwarf));
+ return DWARFDIE();
}
-CompilerDecl
-SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
- return die.GetDecl();
- return CompilerDecl();
+CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDecl();
+ return CompilerDecl();
}
CompilerDeclContext
-SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
- return die.GetDeclContext();
- return CompilerDeclContext();
+SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDeclContext();
+ return CompilerDeclContext();
}
CompilerDeclContext
-SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
- return die.GetContainingDeclContext();
- return CompilerDeclContext();
+SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetContainingDeclContext();
+ return CompilerDeclContext();
}
-
-Type*
-SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE type_die = GetDIEFromUID(type_uid);
- if (type_die)
- return type_die.ResolveType();
- else
- return nullptr;
+Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE type_die = GetDIEFromUID(type_uid);
+ if (type_die)
+ return type_die.ResolveType();
+ else
+ return nullptr;
}
-Type*
-SymbolFileDWARF::ResolveTypeUID (const DIERef &die_ref)
-{
- return ResolveType (GetDIE(die_ref), true);
+Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) {
+ return ResolveType(GetDIE(die_ref), true);
}
-Type*
-SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
-{
- if (die)
- {
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
-
- // We might be coming in in the middle of a type tree (a class
- // withing a class, an enum within a class), so parse any needed
- // parent DIEs before we get to this one...
- DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
- if (decl_ctx_die)
- {
- if (log)
- {
- switch (decl_ctx_die.Tag())
- {
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- {
- // Get the type, which could be a forward declaration
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName(),
- decl_ctx_die.GetOffset());
- }
- break;
+Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
+ bool assert_not_being_parsed) {
+ if (die) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+
+ // We might be coming in in the middle of a type tree (a class
+ // within a class, an enum within a class), so parse any needed
+ // parent DIEs before we get to this one...
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(die);
+ if (decl_ctx_die) {
+ if (log) {
+ switch (decl_ctx_die.Tag()) {
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type: {
+ // Get the type, which could be a forward declaration
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' "
+ "resolve parent forward type for 0x%8.8x",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName(),
+ decl_ctx_die.GetOffset());
+ } break;
- default:
- break;
- }
- }
+ default:
+ break;
}
- return ResolveType (die);
+ }
}
- return NULL;
+ return ResolveType(die);
+ }
+ return NULL;
}
// This function is used when SymbolFileDWARFDebugMap owns a bunch of
// SymbolFileDWARF objects to detect if this DWARF file is the one that
// can resolve a compiler_type.
-bool
-SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
-{
- CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
- if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
- {
- return true;
- }
- TypeSystem *type_system = compiler_type.GetTypeSystem();
+bool SymbolFileDWARF::HasForwardDeclForClangType(
+ const CompilerType &compiler_type) {
+ CompilerType compiler_type_no_qualifiers =
+ ClangUtil::RemoveFastQualifiers(compiler_type);
+ if (GetForwardDeclClangTypeToDie().count(
+ compiler_type_no_qualifiers.GetOpaqueQualType())) {
+ return true;
+ }
+ TypeSystem *type_system = compiler_type.GetTypeSystem();
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- if (!clang_type_system)
- return false;
- DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
- return ast_parser->GetClangASTImporter().CanImport(compiler_type);
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return false;
+ DWARFASTParserClang *ast_parser =
+ static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ return ast_parser->GetClangASTImporter().CanImport(compiler_type);
}
+bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetObjectFile()->GetModule()->GetMutex());
+
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
+ if (clang_type_system) {
+ DWARFASTParserClang *ast_parser =
+ static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ if (ast_parser &&
+ ast_parser->GetClangASTImporter().CanImport(compiler_type))
+ return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
+ }
+
+ // We have a struct/union/class/enum that needs to be fully resolved.
+ CompilerType compiler_type_no_qualifiers =
+ ClangUtil::RemoveFastQualifiers(compiler_type);
+ auto die_it = GetForwardDeclClangTypeToDie().find(
+ compiler_type_no_qualifiers.GetOpaqueQualType());
+ if (die_it == GetForwardDeclClangTypeToDie().end()) {
+ // We have already resolved this type...
+ return true;
+ }
+
+ DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
+ if (dwarf_die) {
+ // Once we start resolving this type, remove it from the forward declaration
+ // map in case anyone child members or other types require this type to get
+ // resolved.
+ // The type will get resolved when all of the calls to
+ // SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
+ // are done.
+ GetForwardDeclClangTypeToDie().erase(die_it);
+
+ Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
+
+ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO |
+ DWARF_LOG_TYPE_COMPLETION));
+ if (log)
+ GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
+ log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
+ dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
+ type->GetName().AsCString());
+ assert(compiler_type);
+ DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
+ }
+ return false;
+}
-bool
-SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
-{
- std::lock_guard<std::recursive_mutex> guard(GetObjectFile()->GetModule()->GetMutex());
-
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
- if (clang_type_system)
- {
- DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
- if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type))
- return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
- }
-
- // We have a struct/union/class/enum that needs to be fully resolved.
- CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
- auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
- if (die_it == GetForwardDeclClangTypeToDie().end())
- {
- // We have already resolved this type...
- return true;
- }
+Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
+ bool assert_not_being_parsed,
+ bool resolve_function_context) {
+ if (die) {
+ Type *type = GetTypeForDIE(die, resolve_function_context).get();
- DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
- if (dwarf_die)
- {
- // Once we start resolving this type, remove it from the forward declaration
- // map in case anyone child members or other types require this type to get resolved.
- // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
- // are done.
- GetForwardDeclClangTypeToDie().erase (die_it);
-
- Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
-
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
- if (log)
- GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
- "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
- dwarf_die.GetID(),
- dwarf_die.GetTagAsCString(),
- type->GetName().AsCString());
- assert (compiler_type);
- DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
- }
- return false;
-}
+ if (assert_not_being_parsed) {
+ if (type != DIE_IS_BEING_PARSED)
+ return type;
-Type*
-SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context)
-{
- if (die)
- {
- Type *type = GetTypeForDIE (die, resolve_function_context).get();
-
- if (assert_not_being_parsed)
- {
- if (type != DIE_IS_BEING_PARSED)
- return type;
-
- GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
+ GetObjectFile()->GetModule()->ReportError(
+ "Parsing a die that is being parsed die: 0x%8.8x: %s %s",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
- }
- else
- return type;
- }
- return nullptr;
+ } else
+ return type;
+ }
+ return nullptr;
}
-CompileUnit*
-SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
-{
- // Check if the symbol vendor already knows about this compile unit?
- if (dwarf_cu->GetUserData() == NULL)
- {
- // The symbol vendor doesn't know about this compile unit, we
- // need to parse and add it to the symbol vendor object.
- return ParseCompileUnit(dwarf_cu, cu_idx).get();
- }
- return (CompileUnit*)dwarf_cu->GetUserData();
+CompileUnit *
+SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) {
+ // Check if the symbol vendor already knows about this compile unit?
+ if (dwarf_cu->GetUserData() == NULL) {
+ // The symbol vendor doesn't know about this compile unit, we
+ // need to parse and add it to the symbol vendor object.
+ return ParseCompileUnit(dwarf_cu, cu_idx).get();
+ }
+ return (CompileUnit *)dwarf_cu->GetUserData();
}
-size_t
-SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
-{
- method_die_offsets.clear();
- if (m_using_apple_tables)
- {
- if (m_apple_objc_ap.get())
- m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_objc_class_selectors_index.Find (class_name, method_die_offsets);
- }
- return method_die_offsets.size();
+size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
+ DIEArray &method_die_offsets) {
+ method_die_offsets.clear();
+ if (m_using_apple_tables) {
+ if (m_apple_objc_ap.get())
+ m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_objc_class_selectors_index.Find(class_name, method_die_offsets);
+ }
+ return method_die_offsets.size();
}
-bool
-SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
-{
- sc.Clear(false);
+bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
+ sc.Clear(false);
- if (die)
- {
- // Check if the symbol vendor already knows about this compile unit?
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+ if (die) {
+ // Check if the symbol vendor already knows about this compile unit?
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
- sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
- if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, die);
-
- if (sc.function)
- {
- sc.module_sp = sc.function->CalculateSymbolContextModule();
- return true;
- }
+ sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
+ if (sc.function == NULL)
+ sc.function = ParseCompileUnitFunction(sc, die);
+
+ if (sc.function) {
+ sc.module_sp = sc.function->CalculateSymbolContextModule();
+ return true;
}
-
- return false;
+ }
+
+ return false;
}
-lldb::ModuleSP
-SymbolFileDWARF::GetDWOModule (ConstString name)
-{
- UpdateExternalModuleListIfNeeded();
- const auto &pos = m_external_type_modules.find(name);
- if (pos != m_external_type_modules.end())
- return pos->second;
- else
- return lldb::ModuleSP();
+lldb::ModuleSP SymbolFileDWARF::GetDWOModule(ConstString name) {
+ UpdateExternalModuleListIfNeeded();
+ const auto &pos = m_external_type_modules.find(name);
+ if (pos != m_external_type_modules.end())
+ return pos->second;
+ else
+ return lldb::ModuleSP();
}
DWARFDIE
-SymbolFileDWARF::GetDIE (const DIERef &die_ref)
-{
- DWARFDebugInfo * debug_info = DebugInfo();
- if (debug_info)
- return debug_info->GetDIE(die_ref);
- else
- return DWARFDIE();
+SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info)
+ return debug_info->GetDIE(die_ref);
+ else
+ return DWARFDIE();
}
-
std::unique_ptr<SymbolFileDWARFDwo>
-SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
-{
- // If we are using a dSYM file, we never want the standard DWO files since
- // the -gmodule support uses the same DWO machanism to specify full debug
- // info files for modules.
- if (GetDebugMapSymfile())
- return nullptr;
-
- const char *dwo_name = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
- if (!dwo_name)
- return nullptr;
-
- FileSpec dwo_file(dwo_name, true);
- 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);
- dwo_file.AppendPathComponent(dwo_name);
- }
+SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
+ DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) {
+ // If we are using a dSYM file, we never want the standard DWO files since
+ // the -gmodule support uses the same DWO machanism to specify full debug
+ // info files for modules.
+ if (GetDebugMapSymfile())
+ return nullptr;
- if (!dwo_file.Exists())
- return nullptr;
+ const char *dwo_name = cu_die.GetAttributeValueAsString(
+ this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
+ if (!dwo_name)
+ return nullptr;
- const lldb::offset_t file_offset = 0;
- DataBufferSP dwo_file_data_sp;
- 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);
- if (dwo_obj_file == nullptr)
- return nullptr;
+ FileSpec dwo_file(dwo_name, true);
+ if (dwo_file.IsRelative()) {
+ const char *comp_dir = cu_die.GetAttributeValueAsString(
+ this, &dwarf_cu, DW_AT_comp_dir, nullptr);
+ if (!comp_dir)
+ return nullptr;
- return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
-}
+ dwo_file.SetFile(comp_dir, true);
+ dwo_file.AppendPathComponent(dwo_name);
+ }
-void
-SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
-{
- if (m_fetched_external_modules)
- return;
- m_fetched_external_modules = true;
-
- DWARFDebugInfo * debug_info = DebugInfo();
+ if (!dwo_file.Exists())
+ return nullptr;
- const uint32_t num_compile_units = GetNumCompileUnits();
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
-
- const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
- if (die && die.HasChildren() == false)
- {
- const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
-
- if (name)
- {
- ConstString const_name(name);
- if (m_external_type_modules.find(const_name) == m_external_type_modules.end())
- {
- ModuleSP module_sp;
- const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
- if (dwo_path)
- {
- ModuleSpec dwo_module_spec;
- dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
- 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().AppendPathComponent(dwo_path);
- }
- }
- dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
- //printf ("Loading dwo = '%s'\n", dwo_path);
- Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
- if (!module_sp)
- {
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: unable to locate module needed for external types: %s\nerror: %s\nDebugging will be degraded due to missing types. Rebuilding your project will regenerate the needed module files.",
- die.GetOffset(),
- dwo_module_spec.GetFileSpec().GetPath().c_str(),
- error.AsCString("unknown error"));
- }
- }
- m_external_type_modules[const_name] = module_sp;
- }
+ const lldb::offset_t file_offset = 0;
+ DataBufferSP dwo_file_data_sp;
+ 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);
+ if (dwo_obj_file == nullptr)
+ return nullptr;
+
+ return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
+}
+
+void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
+ if (m_fetched_external_modules)
+ return;
+ m_fetched_external_modules = true;
+
+ DWARFDebugInfo *debug_info = DebugInfo();
+
+ const uint32_t num_compile_units = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+
+ const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (die && die.HasChildren() == false) {
+ const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
+
+ if (name) {
+ ConstString const_name(name);
+ if (m_external_type_modules.find(const_name) ==
+ m_external_type_modules.end()) {
+ ModuleSP module_sp;
+ const char *dwo_path =
+ die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
+ if (dwo_path) {
+ ModuleSpec dwo_module_spec;
+ dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
+ 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().AppendPathComponent(dwo_path);
+ }
+ }
+ dwo_module_spec.GetArchitecture() =
+ m_obj_file->GetModule()->GetArchitecture();
+ // printf ("Loading dwo = '%s'\n", dwo_path);
+ Error error = ModuleList::GetSharedModule(
+ dwo_module_spec, module_sp, NULL, NULL, NULL);
+ if (!module_sp) {
+ GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8x: unable to locate module needed for external types: "
+ "%s\nerror: %s\nDebugging will be degraded due to missing "
+ "types. Rebuilding your project will regenerate the needed "
+ "module files.",
+ die.GetOffset(),
+ dwo_module_spec.GetFileSpec().GetPath().c_str(),
+ error.AsCString("unknown error"));
}
+ }
+ m_external_type_modules[const_name] = module_sp;
}
+ }
}
+ }
}
-SymbolFileDWARF::GlobalVariableMap &
-SymbolFileDWARF::GetGlobalAranges()
-{
- if (!m_global_aranges_ap)
- {
- m_global_aranges_ap.reset (new GlobalVariableMap());
-
- ModuleSP module_sp = GetObjectFile()->GetModule();
- if (module_sp)
- {
- const size_t num_cus = module_sp->GetNumCompileUnits();
- for (size_t i = 0; i < num_cus; ++i)
- {
- CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
- if (cu_sp)
- {
- VariableListSP globals_sp = cu_sp->GetVariableList(true);
- if (globals_sp)
- {
- const size_t num_globals = globals_sp->GetSize();
- for (size_t g = 0; g < num_globals; ++g)
- {
- VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
- if (var_sp && !var_sp->GetLocationIsConstantValueData())
- {
- const DWARFExpression &location = var_sp->LocationExpression();
- Value location_result;
- Error error;
- if (location.Evaluate(nullptr, nullptr, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr, location_result, &error))
- {
- if (location_result.GetValueType() == Value::eValueTypeFileAddress)
- {
- lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
- lldb::addr_t byte_size = 1;
- if (var_sp->GetType())
- byte_size = var_sp->GetType()->GetByteSize();
- m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
- }
- }
- }
- }
- }
+SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
+ if (!m_global_aranges_ap) {
+ m_global_aranges_ap.reset(new GlobalVariableMap());
+
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ if (module_sp) {
+ const size_t num_cus = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_cus; ++i) {
+ CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
+ if (cu_sp) {
+ VariableListSP globals_sp = cu_sp->GetVariableList(true);
+ if (globals_sp) {
+ const size_t num_globals = globals_sp->GetSize();
+ for (size_t g = 0; g < num_globals; ++g) {
+ VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
+ if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
+ const DWARFExpression &location = var_sp->LocationExpression();
+ Value location_result;
+ Error error;
+ if (location.Evaluate(nullptr, nullptr, nullptr,
+ LLDB_INVALID_ADDRESS, nullptr, nullptr,
+ location_result, &error)) {
+ if (location_result.GetValueType() ==
+ Value::eValueTypeFileAddress) {
+ lldb::addr_t file_addr =
+ location_result.GetScalar().ULongLong();
+ lldb::addr_t byte_size = 1;
+ if (var_sp->GetType())
+ byte_size = var_sp->GetType()->GetByteSize();
+ m_global_aranges_ap->Append(GlobalVariableMap::Entry(
+ file_addr, byte_size, var_sp.get()));
+ }
}
+ }
}
+ }
}
- m_global_aranges_ap->Sort();
+ }
}
- return *m_global_aranges_ap;
+ m_global_aranges_ap->Sort();
+ }
+ return *m_global_aranges_ap;
}
-
-uint32_t
-SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
-{
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
- static_cast<void*>(so_addr.GetSection().get()),
- so_addr.GetOffset(), resolve_scope);
- uint32_t resolved = 0;
- if (resolve_scope & ( eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextBlock |
- eSymbolContextLineEntry |
- eSymbolContextVariable ))
- {
- lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
-
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
- if (cu_offset == DW_INVALID_OFFSET)
- {
- // Global variables are not in the compile unit address ranges. The only way to
- // currently find global variables is to iterate over the .debug_pubnames or the
- // __apple_names table and find all items in there that point to DW_TAG_variable
- // DIEs and then find the address that matches.
- if (resolve_scope & eSymbolContextVariable)
- {
- GlobalVariableMap &map = GetGlobalAranges();
- const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
- if (entry && entry->data)
- {
- Variable *variable = entry->data;
- SymbolContextScope *scc = variable->GetSymbolContextScope();
- if (scc)
- {
- scc->CalculateSymbolContext(&sc);
- sc.variable = variable;
- }
- return sc.GetResolvedMask();
- }
+uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
+ uint32_t resolve_scope,
+ SymbolContext &sc) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "SymbolFileDWARF::"
+ "ResolveSymbolContext (so_addr = { "
+ "section = %p, offset = 0x%" PRIx64
+ " }, resolve_scope = 0x%8.8x)",
+ static_cast<void *>(so_addr.GetSection().get()),
+ so_addr.GetOffset(), resolve_scope);
+ uint32_t resolved = 0;
+ if (resolve_scope &
+ (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock |
+ eSymbolContextLineEntry | eSymbolContextVariable)) {
+ lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
+
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info) {
+ const dw_offset_t cu_offset =
+ debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
+ if (cu_offset == DW_INVALID_OFFSET) {
+ // Global variables are not in the compile unit address ranges. The only
+ // way to
+ // currently find global variables is to iterate over the
+ // .debug_pubnames or the
+ // __apple_names table and find all items in there that point to
+ // DW_TAG_variable
+ // DIEs and then find the address that matches.
+ if (resolve_scope & eSymbolContextVariable) {
+ GlobalVariableMap &map = GetGlobalAranges();
+ const GlobalVariableMap::Entry *entry =
+ map.FindEntryThatContains(file_vm_addr);
+ if (entry && entry->data) {
+ Variable *variable = entry->data;
+ SymbolContextScope *scc = variable->GetSymbolContextScope();
+ if (scc) {
+ scc->CalculateSymbolContext(&sc);
+ sc.variable = variable;
+ }
+ return sc.GetResolvedMask();
+ }
+ }
+ } else {
+ uint32_t cu_idx = DW_INVALID_INDEX;
+ DWARFCompileUnit *dwarf_cu =
+ debug_info->GetCompileUnit(cu_offset, &cu_idx);
+ if (dwarf_cu) {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+ if (sc.comp_unit) {
+ resolved |= eSymbolContextCompUnit;
+
+ bool force_check_line_table = false;
+ if (resolve_scope &
+ (eSymbolContextFunction | eSymbolContextBlock)) {
+ DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die) {
+ sc.function =
+ sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
+ if (sc.function == NULL)
+ sc.function = ParseCompileUnitFunction(sc, function_die);
+
+ if (sc.function && (resolve_scope & eSymbolContextBlock))
+ block_die = function_die.LookupDeepestBlock(file_vm_addr);
+ } else {
+ // We might have had a compile unit that had discontiguous
+ // address ranges where the gaps are symbols that don't have
+ // any debug info. Discontiguous compile unit address ranges
+ // should only happen when there aren't other functions from
+ // other compile units in these gaps. This helps keep the size
+ // of the aranges down.
+ force_check_line_table = true;
+ }
+
+ if (sc.function != NULL) {
+ resolved |= eSymbolContextFunction;
+
+ if (resolve_scope & eSymbolContextBlock) {
+ Block &block = sc.function->GetBlock(true);
+
+ if (block_die)
+ sc.block = block.FindBlockByID(block_die.GetID());
+ else
+ sc.block = block.FindBlockByID(function_die.GetID());
+ if (sc.block)
+ resolved |= eSymbolContextBlock;
}
+ }
}
- else
- {
- uint32_t cu_idx = DW_INVALID_INDEX;
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
- if (dwarf_cu)
- {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- if (sc.comp_unit)
- {
- resolved |= eSymbolContextCompUnit;
-
- bool force_check_line_table = false;
- if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
- {
- DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
- DWARFDIE block_die;
- if (function_die)
- {
- sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
- if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, function_die);
-
- if (sc.function && (resolve_scope & eSymbolContextBlock))
- block_die = function_die.LookupDeepestBlock(file_vm_addr);
- }
- else
- {
- // We might have had a compile unit that had discontiguous
- // address ranges where the gaps are symbols that don't have
- // any debug info. Discontiguous compile unit address ranges
- // should only happen when there aren't other functions from
- // other compile units in these gaps. This helps keep the size
- // of the aranges down.
- force_check_line_table = true;
- }
-
- if (sc.function != NULL)
- {
- resolved |= eSymbolContextFunction;
-
- if (resolve_scope & eSymbolContextBlock)
- {
- Block& block = sc.function->GetBlock (true);
-
- if (block_die)
- sc.block = block.FindBlockByID (block_die.GetID());
- else
- sc.block = block.FindBlockByID (function_die.GetID());
- if (sc.block)
- resolved |= eSymbolContextBlock;
- }
- }
- }
-
- if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table != NULL)
- {
- // And address that makes it into this function should be in terms
- // of this debug file if there is no debug map, or it will be an
- // address in the .o file which needs to be fixed up to be in terms
- // of the debug map executable. Either way, calling FixupAddress()
- // will work for us.
- Address exe_so_addr (so_addr);
- if (FixupAddress(exe_so_addr))
- {
- if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
- }
- }
- }
-
- if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
- {
- // We might have had a compile unit that had discontiguous
- // address ranges where the gaps are symbols that don't have
- // any debug info. Discontiguous compile unit address ranges
- // should only happen when there aren't other functions from
- // other compile units in these gaps. This helps keep the size
- // of the aranges down.
- sc.comp_unit = NULL;
- resolved &= ~eSymbolContextCompUnit;
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
- cu_offset,
- cu_idx);
- }
+
+ if ((resolve_scope & eSymbolContextLineEntry) ||
+ force_check_line_table) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+ if (line_table != NULL) {
+ // And address that makes it into this function should be in
+ // terms
+ // of this debug file if there is no debug map, or it will be an
+ // address in the .o file which needs to be fixed up to be in
+ // terms
+ // of the debug map executable. Either way, calling
+ // FixupAddress()
+ // will work for us.
+ Address exe_so_addr(so_addr);
+ if (FixupAddress(exe_so_addr)) {
+ if (line_table->FindLineEntryByAddress(exe_so_addr,
+ sc.line_entry)) {
+ resolved |= eSymbolContextLineEntry;
+ }
}
+ }
}
+
+ if (force_check_line_table &&
+ !(resolved & eSymbolContextLineEntry)) {
+ // We might have had a compile unit that had discontiguous
+ // address ranges where the gaps are symbols that don't have
+ // any debug info. Discontiguous compile unit address ranges
+ // should only happen when there aren't other functions from
+ // other compile units in these gaps. This helps keep the size
+ // of the aranges down.
+ sc.comp_unit = NULL;
+ resolved &= ~eSymbolContextCompUnit;
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8x: compile unit %u failed to create a valid "
+ "lldb_private::CompileUnit class.",
+ cu_offset, cu_idx);
+ }
}
+ }
}
- return resolved;
+ }
+ return resolved;
}
+uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList &sc_list) {
+ const uint32_t prev_size = sc_list.GetSize();
+ if (resolve_scope & eSymbolContextCompUnit) {
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info) {
+ uint32_t cu_idx;
+ DWARFCompileUnit *dwarf_cu = NULL;
+
+ for (cu_idx = 0;
+ (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL;
+ ++cu_idx) {
+ CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+ const bool full_match = (bool)file_spec.GetDirectory();
+ bool file_spec_matches_cu_file_spec =
+ dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
+ if (check_inlines || file_spec_matches_cu_file_spec) {
+ SymbolContext sc(m_obj_file->GetModule());
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+ if (sc.comp_unit) {
+ uint32_t file_idx = UINT32_MAX;
+
+ // If we are looking for inline functions only and we don't
+ // find it in the support files, we are done.
+ if (check_inlines) {
+ file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
+ 1, file_spec, true);
+ if (file_idx == UINT32_MAX)
+ continue;
+ }
-
-uint32_t
-SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
-{
- const uint32_t prev_size = sc_list.GetSize();
- if (resolve_scope & eSymbolContextCompUnit)
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- uint32_t cu_idx;
- DWARFCompileUnit* dwarf_cu = NULL;
-
- for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
- {
- CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- const bool full_match = (bool)file_spec.GetDirectory();
- bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
- if (check_inlines || file_spec_matches_cu_file_spec)
- {
- SymbolContext sc (m_obj_file->GetModule());
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- if (sc.comp_unit)
- {
- uint32_t file_idx = UINT32_MAX;
-
- // If we are looking for inline functions only and we don't
- // find it in the support files, we are done.
- if (check_inlines)
- {
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
- if (file_idx == UINT32_MAX)
- continue;
+ if (line != 0) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table != NULL && line != 0) {
+ // We will have already looked up the file index if
+ // we are searching for inline entries.
+ if (!check_inlines)
+ file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
+ 1, file_spec, true);
+
+ if (file_idx != UINT32_MAX) {
+ uint32_t found_line;
+ uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
+ 0, file_idx, line, false, &sc.line_entry);
+ found_line = sc.line_entry.line;
+
+ while (line_idx != UINT32_MAX) {
+ sc.function = NULL;
+ sc.block = NULL;
+ if (resolve_scope &
+ (eSymbolContextFunction | eSymbolContextBlock)) {
+ const lldb::addr_t file_vm_addr =
+ sc.line_entry.range.GetBaseAddress().GetFileAddress();
+ if (file_vm_addr != LLDB_INVALID_ADDRESS) {
+ DWARFDIE function_die =
+ dwarf_cu->LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die) {
+ sc.function =
+ sc.comp_unit
+ ->FindFunctionByUID(function_die.GetID())
+ .get();
+ if (sc.function == NULL)
+ sc.function =
+ ParseCompileUnitFunction(sc, function_die);
+
+ if (sc.function &&
+ (resolve_scope & eSymbolContextBlock))
+ block_die =
+ function_die.LookupDeepestBlock(file_vm_addr);
}
- if (line != 0)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table != NULL && line != 0)
- {
- // We will have already looked up the file index if
- // we are searching for inline entries.
- if (!check_inlines)
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
-
- if (file_idx != UINT32_MAX)
- {
- uint32_t found_line;
- uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
- found_line = sc.line_entry.line;
-
- while (line_idx != UINT32_MAX)
- {
- sc.function = NULL;
- sc.block = NULL;
- if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
- {
- const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
- if (file_vm_addr != LLDB_INVALID_ADDRESS)
- {
- DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
- DWARFDIE block_die;
- if (function_die)
- {
- sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
- if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, function_die);
-
- if (sc.function && (resolve_scope & eSymbolContextBlock))
- block_die = function_die.LookupDeepestBlock(file_vm_addr);
- }
-
- if (sc.function != NULL)
- {
- Block& block = sc.function->GetBlock (true);
-
- if (block_die)
- sc.block = block.FindBlockByID (block_die.GetID());
- else if (function_die)
- sc.block = block.FindBlockByID (function_die.GetID());
- }
- }
- }
-
- sc_list.Append(sc);
- line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
- }
- }
- }
- else if (file_spec_matches_cu_file_spec && !check_inlines)
- {
- // only append the context if we aren't looking for inline call sites
- // by file and line and if the file spec matches that of the compile unit
- sc_list.Append(sc);
- }
- }
- else if (file_spec_matches_cu_file_spec && !check_inlines)
- {
- // only append the context if we aren't looking for inline call sites
- // by file and line and if the file spec matches that of the compile unit
- sc_list.Append(sc);
- }
+ if (sc.function != NULL) {
+ Block &block = sc.function->GetBlock(true);
- if (!check_inlines)
- break;
+ if (block_die)
+ sc.block = block.FindBlockByID(block_die.GetID());
+ else if (function_die)
+ sc.block =
+ block.FindBlockByID(function_die.GetID());
+ }
+ }
}
+
+ sc_list.Append(sc);
+ line_idx = line_table->FindLineEntryIndexByFileIndex(
+ line_idx + 1, file_idx, found_line, true,
+ &sc.line_entry);
+ }
}
+ } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+ // only append the context if we aren't looking for inline call
+ // sites
+ // by file and line and if the file spec matches that of the
+ // compile unit
+ sc_list.Append(sc);
+ }
+ } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+ // only append the context if we aren't looking for inline call
+ // sites
+ // by file and line and if the file spec matches that of the
+ // compile unit
+ sc_list.Append(sc);
}
+
+ if (!check_inlines)
+ break;
+ }
}
+ }
}
- return sc_list.GetSize() - prev_size;
+ }
+ return sc_list.GetSize() - prev_size;
}
-void
-SymbolFileDWARF::Index ()
-{
- if (m_indexed)
- return;
- m_indexed = true;
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolFileDWARF::Index (%s)",
- GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
-
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- const uint32_t num_compile_units = GetNumCompileUnits();
- if (num_compile_units == 0)
- return;
-
- std::vector<NameToDIE> function_basename_index(num_compile_units);
- std::vector<NameToDIE> function_fullname_index(num_compile_units);
- std::vector<NameToDIE> function_method_index(num_compile_units);
- std::vector<NameToDIE> function_selector_index(num_compile_units);
- std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
- std::vector<NameToDIE> global_index(num_compile_units);
- std::vector<NameToDIE> type_index(num_compile_units);
- std::vector<NameToDIE> namespace_index(num_compile_units);
-
- std::vector<bool> clear_cu_dies(num_compile_units, false);
- auto parser_fn = [this,
- debug_info,
- &function_basename_index,
- &function_fullname_index,
- &function_method_index,
- &function_selector_index,
- &objc_class_selectors_index,
- &global_index,
- &type_index,
- &namespace_index](uint32_t cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- {
- dwarf_cu->Index(function_basename_index[cu_idx],
- function_fullname_index[cu_idx],
- function_method_index[cu_idx],
- function_selector_index[cu_idx],
- objc_class_selectors_index[cu_idx],
- global_index[cu_idx],
- type_index[cu_idx],
- namespace_index[cu_idx]);
- }
- return cu_idx;
- };
-
- auto extract_fn = [this,
- debug_info,
- num_compile_units](uint32_t cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- {
- // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
- // DIEs for a compile unit have already been parsed.
- return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
- }
- return std::make_pair(cu_idx, false);
- };
-
- // Create a task runner that extracts dies for each DWARF compile unit in a separate thread
- TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- task_runner_extract.AddTask(extract_fn, cu_idx);
-
- //----------------------------------------------------------------------
- // First figure out which compile units didn't have their DIEs already
- // parsed and remember this. If no DIEs were parsed prior to this index
- // function call, we are going to want to clear the CU dies after we
- // are done indexing to make sure we don't pull in all DWARF dies, but
- // we need to wait until all compile units have been indexed in case
- // a DIE in one compile unit refers to another and the indexes accesses
- // those DIEs.
- //----------------------------------------------------------------------
- while (true)
- {
- auto f = task_runner_extract.WaitForNextCompletedTask();
- if (!f.valid())
- break;
- unsigned cu_idx;
- bool clear;
- std::tie(cu_idx, clear) = f.get();
- clear_cu_dies[cu_idx] = clear;
- }
+void SymbolFileDWARF::Index() {
+ if (m_indexed)
+ return;
+ m_indexed = true;
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION, "SymbolFileDWARF::Index (%s)",
+ GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
- // Now create a task runner that can index each DWARF compile unit in a separate
- // thread so we can index quickly.
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info) {
+ const uint32_t num_compile_units = GetNumCompileUnits();
+ if (num_compile_units == 0)
+ return;
+
+ std::vector<NameToDIE> function_basename_index(num_compile_units);
+ std::vector<NameToDIE> function_fullname_index(num_compile_units);
+ std::vector<NameToDIE> function_method_index(num_compile_units);
+ std::vector<NameToDIE> function_selector_index(num_compile_units);
+ std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
+ std::vector<NameToDIE> global_index(num_compile_units);
+ std::vector<NameToDIE> type_index(num_compile_units);
+ std::vector<NameToDIE> namespace_index(num_compile_units);
+
+ std::vector<bool> clear_cu_dies(num_compile_units, false);
+ auto parser_fn = [this, debug_info, &function_basename_index,
+ &function_fullname_index, &function_method_index,
+ &function_selector_index, &objc_class_selectors_index,
+ &global_index, &type_index,
+ &namespace_index](uint32_t cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu) {
+ dwarf_cu->Index(
+ function_basename_index[cu_idx], function_fullname_index[cu_idx],
+ function_method_index[cu_idx], function_selector_index[cu_idx],
+ objc_class_selectors_index[cu_idx], global_index[cu_idx],
+ type_index[cu_idx], namespace_index[cu_idx]);
+ }
+ return cu_idx;
+ };
- TaskRunner<uint32_t> task_runner;
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- task_runner.AddTask(parser_fn, cu_idx);
+ auto extract_fn = [this, debug_info, num_compile_units](uint32_t cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu) {
+ // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
+ // DIEs for a compile unit have already been parsed.
+ return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
+ }
+ return std::make_pair(cu_idx, false);
+ };
- while (true)
- {
- std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
- if (!f.valid())
- break;
- uint32_t cu_idx = f.get();
-
- m_function_basename_index.Append(function_basename_index[cu_idx]);
- m_function_fullname_index.Append(function_fullname_index[cu_idx]);
- m_function_method_index.Append(function_method_index[cu_idx]);
- m_function_selector_index.Append(function_selector_index[cu_idx]);
- m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
- m_global_index.Append(global_index[cu_idx]);
- m_type_index.Append(type_index[cu_idx]);
- m_namespace_index.Append(namespace_index[cu_idx]);
- }
+ // Create a task runner that extracts dies for each DWARF compile unit in a
+ // separate thread
+ TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner_extract.AddTask(extract_fn, cu_idx);
+
+ //----------------------------------------------------------------------
+ // First figure out which compile units didn't have their DIEs already
+ // parsed and remember this. If no DIEs were parsed prior to this index
+ // function call, we are going to want to clear the CU dies after we
+ // are done indexing to make sure we don't pull in all DWARF dies, but
+ // we need to wait until all compile units have been indexed in case
+ // a DIE in one compile unit refers to another and the indexes accesses
+ // those DIEs.
+ //----------------------------------------------------------------------
+ while (true) {
+ auto f = task_runner_extract.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ unsigned cu_idx;
+ bool clear;
+ std::tie(cu_idx, clear) = f.get();
+ clear_cu_dies[cu_idx] = clear;
+ }
- TaskPool::RunTasks(
- [&]() { m_function_basename_index.Finalize(); },
- [&]() { m_function_fullname_index.Finalize(); },
- [&]() { m_function_method_index.Finalize(); },
- [&]() { m_function_selector_index.Finalize(); },
- [&]() { m_objc_class_selectors_index.Finalize(); },
- [&]() { m_global_index.Finalize(); },
- [&]() { m_type_index.Finalize(); },
- [&]() { m_namespace_index.Finalize(); });
-
- //----------------------------------------------------------------------
- // Keep memory down by clearing DIEs for any compile units if indexing
- // caused us to load the compile unit's DIEs.
- //----------------------------------------------------------------------
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- if (clear_cu_dies[cu_idx])
- debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
- }
+ // Now create a task runner that can index each DWARF compile unit in a
+ // separate
+ // thread so we can index quickly.
-#if defined (ENABLE_DEBUG_PRINTF)
- StreamFile s(stdout, false);
- s.Printf ("DWARF index for '%s':",
- GetObjectFile()->GetFileSpec().GetPath().c_str());
- s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
- s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
- s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
- s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
- s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
- s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
- s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
- s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s);
-#endif
+ TaskRunner<uint32_t> task_runner;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner.AddTask(parser_fn, cu_idx);
+
+ while (true) {
+ std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ uint32_t cu_idx = f.get();
+
+ m_function_basename_index.Append(function_basename_index[cu_idx]);
+ m_function_fullname_index.Append(function_fullname_index[cu_idx]);
+ m_function_method_index.Append(function_method_index[cu_idx]);
+ m_function_selector_index.Append(function_selector_index[cu_idx]);
+ m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
+ m_global_index.Append(global_index[cu_idx]);
+ m_type_index.Append(type_index[cu_idx]);
+ m_namespace_index.Append(namespace_index[cu_idx]);
}
-}
-bool
-SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
-{
- if (decl_ctx == nullptr || !decl_ctx->IsValid())
- {
- // Invalid namespace decl which means we aren't matching only things
- // in this symbol file, so return true to indicate it matches this
- // symbol file.
- return true;
+ TaskPool::RunTasks([&]() { m_function_basename_index.Finalize(); },
+ [&]() { m_function_fullname_index.Finalize(); },
+ [&]() { m_function_method_index.Finalize(); },
+ [&]() { m_function_selector_index.Finalize(); },
+ [&]() { m_objc_class_selectors_index.Finalize(); },
+ [&]() { m_global_index.Finalize(); },
+ [&]() { m_type_index.Finalize(); },
+ [&]() { m_namespace_index.Finalize(); });
+
+ //----------------------------------------------------------------------
+ // Keep memory down by clearing DIEs for any compile units if indexing
+ // caused us to load the compile unit's DIEs.
+ //----------------------------------------------------------------------
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ if (clear_cu_dies[cu_idx])
+ debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
}
- TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
- TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
- return true; // The type systems match, return true
-
- // The namespace AST was valid, and it does not match...
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+#if defined(ENABLE_DEBUG_PRINTF)
+ StreamFile s(stdout, false);
+ s.Printf("DWARF index for '%s':",
+ GetObjectFile()->GetFileSpec().GetPath().c_str());
+ s.Printf("\nFunction basenames:\n");
+ m_function_basename_index.Dump(&s);
+ s.Printf("\nFunction fullnames:\n");
+ m_function_fullname_index.Dump(&s);
+ s.Printf("\nFunction methods:\n");
+ m_function_method_index.Dump(&s);
+ s.Printf("\nFunction selectors:\n");
+ m_function_selector_index.Dump(&s);
+ s.Printf("\nObjective C class selectors:\n");
+ m_objc_class_selectors_index.Dump(&s);
+ s.Printf("\nGlobals and statics:\n");
+ m_global_index.Dump(&s);
+ s.Printf("\nTypes:\n");
+ m_type_index.Dump(&s);
+ s.Printf("\nNamespaces:\n");
+ m_namespace_index.Dump(&s);
+#endif
+ }
+}
- if (log)
- GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
-
- return false;
+bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
+ const lldb_private::CompilerDeclContext *decl_ctx) {
+ if (decl_ctx == nullptr || !decl_ctx->IsValid()) {
+ // Invalid namespace decl which means we aren't matching only things
+ // in this symbol file, so return true to indicate it matches this
+ // symbol file.
+ return true;
+ }
+
+ TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
+ TypeSystem *type_system = GetTypeSystemForLanguage(
+ decl_ctx_type_system->GetMinimumLanguage(nullptr));
+ if (decl_ctx_type_system == type_system)
+ return true; // The type systems match, return true
+
+ // The namespace AST was valid, and it does not match...
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "Valid namespace does not match symbol file");
+
+ return false;
}
-uint32_t
-SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+uint32_t SymbolFileDWARF::FindGlobalVariables(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches, VariableList &variables) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- append, max_matches);
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
+ "parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx), append,
+ max_matches);
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
- DIEArray die_offsets;
+ DIEArray die_offsets;
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
- const char *name_cstr = name.GetCString();
- llvm::StringRef basename;
- llvm::StringRef context;
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ llvm::StringRef basename;
+ llvm::StringRef context;
- if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
- basename = name_cstr;
+ if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
+ basename))
+ basename = name_cstr;
- m_apple_names_ap->FindByName (basename.data(), die_offsets);
- }
+ m_apple_names_ap->FindByName(basename.data(), die_offsets);
}
- else
- {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
+ } else {
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
- m_global_index.Find (name, die_offsets);
- }
+ m_global_index.Find(name, die_offsets);
+ }
- const size_t num_die_matches = die_offsets.size();
- if (num_die_matches)
- {
- SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
- assert (sc.module_sp);
-
- bool done = false;
- for (size_t i=0; i<num_die_matches && !done; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- switch (die.Tag())
- {
- default:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_try_block:
- case DW_TAG_catch_block:
- break;
-
- case DW_TAG_variable:
- {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
-
- if (parent_decl_ctx)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- {
- CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
- if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
- continue;
- }
- }
-
- ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
-
- if (variables.GetSize() - original_size >= max_matches)
- done = true;
- }
- break;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
+ const size_t num_die_matches = die_offsets.size();
+ if (num_die_matches) {
+ SymbolContext sc;
+ sc.module_sp = m_obj_file->GetModule();
+ assert(sc.module_sp);
+
+ bool done = false;
+ for (size_t i = 0; i < num_die_matches && !done; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ switch (die.Tag()) {
+ default:
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_try_block:
+ case DW_TAG_catch_block:
+ break;
+
+ case DW_TAG_variable: {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+
+ if (parent_decl_ctx) {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast) {
+ CompilerDeclContext actual_parent_decl_ctx =
+ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
+ if (!actual_parent_decl_ctx ||
+ actual_parent_decl_ctx != *parent_decl_ctx)
+ continue;
}
- }
- }
+ }
- // Return the number of variable that were appended to the list
- const uint32_t num_matches = variables.GetSize() - original_size;
- if (log && num_matches > 0)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- append, max_matches,
- num_matches);
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false,
+ &variables);
+
+ if (variables.GetSize() - original_size >= max_matches)
+ done = true;
+ } break;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, name.GetCString());
+ }
+ }
}
- return num_matches;
+ }
+
+ // Return the number of variable that were appended to the list
+ const uint32_t num_matches = variables.GetSize() - original_size;
+ if (log && num_matches > 0) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
+ "parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx), append,
+ max_matches, num_matches);
+ }
+ return num_matches;
}
-uint32_t
-SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
+ bool append, uint32_t max_matches,
+ VariableList &variables) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
- regex.GetText(), append,
- max_matches);
- }
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, "
+ "max_matches=%u, variables)",
+ regex.GetText().str().c_str(), append, max_matches);
+ }
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
- DIEArray die_offsets;
+ DIEArray die_offsets;
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
- DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
- }
- }
- else
- {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
-
- m_global_index.Find (regex, die_offsets);
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex(regex,
+ hash_data_array))
+ DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
}
+ } else {
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
- SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
- assert (sc.module_sp);
-
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
-
- ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
-
- if (variables.GetSize() - original_size >= max_matches)
- break;
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
- die_ref.die_offset, regex.GetText());
- }
- }
+ m_global_index.Find(regex, die_offsets);
+ }
+
+ SymbolContext sc;
+ sc.module_sp = m_obj_file->GetModule();
+ assert(sc.module_sp);
+
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
+
+ if (variables.GetSize() - original_size >= max_matches)
+ break;
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for regex '%s')\n",
+ die_ref.die_offset, regex.GetText().str().c_str());
}
+ }
}
+ }
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
+ // Return the number of variable that were appended to the list
+ return variables.GetSize() - original_size;
}
-
-bool
-SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DWARFDIE die = DebugInfo()->GetDIE (die_ref);
- return ResolveFunction (die, include_inlines, sc_list);
+bool SymbolFileDWARF::ResolveFunction(const DIERef &die_ref,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ DWARFDIE die = DebugInfo()->GetDIE(die_ref);
+ return ResolveFunction(die, include_inlines, sc_list);
}
-
-bool
-SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- SymbolContext sc;
+bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ SymbolContext sc;
- if (!orig_die)
- return false;
+ if (!orig_die)
+ return false;
- // If we were passed a die that is not a function, just return false...
- if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
- return false;
+ // If we were passed a die that is not a function, just return false...
+ if (!(orig_die.Tag() == DW_TAG_subprogram ||
+ (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
+ return false;
- DWARFDIE die = orig_die;
- DWARFDIE inlined_die;
- if (die.Tag() == DW_TAG_inlined_subroutine)
- {
- inlined_die = die;
-
- while (1)
- {
- die = die.GetParent();
-
- if (die)
- {
- if (die.Tag() == DW_TAG_subprogram)
- break;
- }
- else
- break;
- }
- }
- assert (die && die.Tag() == DW_TAG_subprogram);
- if (GetFunction (die, sc))
- {
- Address addr;
- // Parse all blocks if needed
- if (inlined_die)
- {
- Block &function_block = sc.function->GetBlock (true);
- 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)
- addr.Clear();
- }
- else
- {
- sc.block = NULL;
- addr = sc.function->GetAddressRange().GetBaseAddress();
- }
+ DWARFDIE die = orig_die;
+ DWARFDIE inlined_die;
+ if (die.Tag() == DW_TAG_inlined_subroutine) {
+ inlined_die = die;
- if (addr.IsValid())
- {
- sc_list.Append(sc);
- return true;
- }
+ while (1) {
+ die = die.GetParent();
+
+ if (die) {
+ if (die.Tag() == DW_TAG_subprogram)
+ break;
+ } else
+ break;
+ }
+ }
+ assert(die && die.Tag() == DW_TAG_subprogram);
+ if (GetFunction(die, sc)) {
+ Address addr;
+ // Parse all blocks if needed
+ if (inlined_die) {
+ Block &function_block = sc.function->GetBlock(true);
+ 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)
+ addr.Clear();
+ } else {
+ sc.block = NULL;
+ addr = sc.function->GetAddressRange().GetBaseAddress();
}
-
- return false;
-}
-void
-SymbolFileDWARF::FindFunctions (const ConstString &name,
- const NameToDIE &name_to_die,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DIEArray die_offsets;
- if (name_to_die.Find (name, die_offsets))
- {
- ParseFunctions (die_offsets, include_inlines, sc_list);
+ if (addr.IsValid()) {
+ sc_list.Append(sc);
+ return true;
}
-}
+ }
+ return false;
+}
-void
-SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
- const NameToDIE &name_to_die,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DIEArray die_offsets;
- if (name_to_die.Find (regex, die_offsets))
- {
- ParseFunctions (die_offsets, include_inlines, sc_list);
- }
+void SymbolFileDWARF::FindFunctions(const ConstString &name,
+ const NameToDIE &name_to_die,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ DIEArray die_offsets;
+ if (name_to_die.Find(name, die_offsets)) {
+ ParseFunctions(die_offsets, include_inlines, sc_list);
+ }
}
+void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
+ const NameToDIE &name_to_die,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ DIEArray die_offsets;
+ if (name_to_die.Find(regex, die_offsets)) {
+ ParseFunctions(die_offsets, include_inlines, sc_list);
+ }
+}
-void
-SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
- const DWARFMappedHash::MemoryTable &memory_table,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DIEArray die_offsets;
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
- {
- DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
- ParseFunctions (die_offsets, include_inlines, sc_list);
- }
+void SymbolFileDWARF::FindFunctions(
+ const RegularExpression &regex,
+ const DWARFMappedHash::MemoryTable &memory_table, bool include_inlines,
+ SymbolContextList &sc_list) {
+ DIEArray die_offsets;
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (memory_table.AppendAllDIEsThatMatchingRegex(regex, hash_data_array)) {
+ DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
+ ParseFunctions(die_offsets, include_inlines, sc_list);
+ }
}
-void
-SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- ResolveFunction (die_offsets[i], include_inlines, sc_list);
- }
+void SymbolFileDWARF::ParseFunctions(const DIEArray &die_offsets,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i)
+ ResolveFunction(die_offsets[i], include_inlines, sc_list);
+ }
}
-bool
-SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
- const DWARFDIE &die)
-{
- // If we have no parent decl context to match this DIE matches, and if the parent
- // decl context isn't valid, we aren't trying to look for any particular decl
- // context so any die matches.
- if (decl_ctx == nullptr || !decl_ctx->IsValid())
- return true;
-
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- {
- CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
- if (actual_decl_ctx)
- return actual_decl_ctx == *decl_ctx;
- }
+bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
+ const DWARFDIE &die) {
+ // If we have no parent decl context to match this DIE matches, and if the
+ // parent
+ // decl context isn't valid, we aren't trying to look for any particular decl
+ // context so any die matches.
+ if (decl_ctx == nullptr || !decl_ctx->IsValid())
+ return true;
+
+ if (die) {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast) {
+ CompilerDeclContext actual_decl_ctx =
+ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
+ if (actual_decl_ctx)
+ return actual_decl_ctx == *decl_ctx;
}
- return false;
+ }
+ 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)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolFileDWARF::FindFunctions (name = '%s')",
- name.AsCString());
-
- // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
- assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
- name.GetCString(),
- name_type_mask,
- append);
- }
+SymbolFileDWARF::FindFunctions(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines,
+ bool append, SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARF::FindFunctions (name = '%s')",
+ name.AsCString());
+
+ // eFunctionNameTypeAuto should be pre-resolved by a call to
+ // Module::LookupInfo::LookupInfo()
+ assert((name_type_mask & eFunctionNameTypeAuto) == 0);
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
+ "name_type_mask=0x%x, append=%u, sc_list)",
+ name.GetCString(), name_type_mask, append);
+ }
+
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ sc_list.Clear();
+
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
-
- // If name is empty then we won't find anything.
- if (name.IsEmpty())
- return 0;
+ // If name is empty then we won't find anything.
+ if (name.IsEmpty())
+ return 0;
- // Remember how many sc_list are in the list before we search in case
- // we are appending the results to a variable list.
+ // Remember how many sc_list are in the list before we search in case
+ // we are appending the results to a variable list.
- const char *name_cstr = name.GetCString();
+ const char *name_cstr = name.GetCString();
- const uint32_t original_size = sc_list.GetSize();
-
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
+ const uint32_t original_size = sc_list.GetSize();
- std::set<const DWARFDebugInfoEntry *> resolved_dies;
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
-
- DIEArray die_offsets;
-
- uint32_t num_matches = 0;
-
- if (name_type_mask & eFunctionNameTypeFull)
- {
- // If they asked for the full name, match what they typed. At some point we may
- // want to canonicalize this (strip double spaces, etc. For now, we just add all the
- // dies that we find by exact match.
- num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
- for (uint32_t i = 0; i < num_matches; i++)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE (die_ref);
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- }
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
- if (name_type_mask & eFunctionNameTypeSelector)
- {
- if (parent_decl_ctx && parent_decl_ctx->IsValid())
- return 0; // no selectors in namespaces
-
- num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
- // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
- // and if it is an ObjC method name, we're good.
-
- for (uint32_t i = 0; i < num_matches; i++)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE (die_ref);
- if (die)
- {
- const char *die_name = die.GetName();
- if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
- {
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- die_offsets.clear();
+ std::set<const DWARFDebugInfoEntry *> resolved_dies;
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+
+ DIEArray die_offsets;
+
+ uint32_t num_matches = 0;
+
+ if (name_type_mask & eFunctionNameTypeFull) {
+ // If they asked for the full name, match what they typed. At some
+ // point we may
+ // want to canonicalize this (strip double spaces, etc. For now, we
+ // just add all the
+ // dies that we find by exact match.
+ num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
+ for (uint32_t i = 0; i < num_matches; i++) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE(die_ref);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
}
-
- if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
- {
- // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
- // extract the base name, look that up, and if there is any other information in the name we were
- // passed in we have to post-filter based on that.
-
- // FIXME: Arrange the logic above so that we don't calculate the base name twice:
- num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
-
- for (uint32_t i = 0; i < num_matches; i++)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE (die_ref);
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
-
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
- {
- bool keep_die = true;
- if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
- {
- // We are looking for either basenames or methods, so we need to
- // trim out the ones we won't want by looking at the type
- SymbolContext sc;
- if (sc_list.GetLastContext(sc))
- {
- if (sc.block)
- {
- // We have an inlined function
- }
- else if (sc.function)
- {
- Type *type = sc.function->GetType();
-
- if (type)
- {
- CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
- if (decl_ctx.IsStructUnionOrClass())
- {
- if (name_type_mask & eFunctionNameTypeBase)
- {
- sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
- keep_die = false;
- }
- }
- else
- {
- if (name_type_mask & eFunctionNameTypeMethod)
- {
- sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
- keep_die = false;
- }
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
- die_ref.die_offset);
- }
- }
- }
- }
- if (keep_die)
- resolved_dies.insert(die.GetDIE());
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- die_offsets.clear();
+ } else {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')",
+ die_ref.die_offset, name_cstr);
+ }
+ }
+ }
+
+ if (name_type_mask & eFunctionNameTypeSelector) {
+ if (parent_decl_ctx && parent_decl_ctx->IsValid())
+ return 0; // no selectors in namespaces
+
+ num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
+ // Now make sure these are actually ObjC methods. In this case we can
+ // simply look up the name,
+ // and if it is an ObjC method name, we're good.
+
+ for (uint32_t i = 0; i < num_matches; i++) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE(die_ref);
+ if (die) {
+ const char *die_name = die.GetName();
+ if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) {
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
+ }
}
+ } else {
+ GetObjectFile()->GetModule()->ReportError(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')",
+ die_ref.die_offset, name_cstr);
+ }
}
- }
- else
- {
-
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
-
- if (name_type_mask & eFunctionNameTypeFull)
- {
- FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
-
- // FIXME Temporary workaround for global/anonymous namespace
- // functions debugging FreeBSD and Linux binaries.
- // If we didn't find any functions in the global namespace try
- // looking in the basename index but ignore any returned
- // functions that have a namespace but keep functions which
- // have an anonymous namespace
- // TODO: The arch in the object file isn't correct for MSVC
- // binaries on windows, we should find a way to make it
- // correct and handle those symbols as well.
- if (sc_list.GetSize() == original_size)
- {
- ArchSpec arch;
- if (!parent_decl_ctx &&
- GetObjectFile()->GetArchitecture(arch) &&
- (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
- arch.GetMachine() == llvm::Triple::hexagon))
- {
- SymbolContextList temp_sc_list;
- FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
- SymbolContext sc;
- for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
- {
- if (temp_sc_list.GetContextAtIndex(i, sc))
- {
- ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
- ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
- // Mangled names on Linux and FreeBSD are of the form:
- // _ZN18function_namespace13function_nameEv.
- if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
- !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
- {
- sc_list.Append(sc);
- }
+ die_offsets.clear();
+ }
+
+ if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) ||
+ name_type_mask & eFunctionNameTypeBase) {
+ // The apple_names table stores just the "base name" of C++ methods in
+ // the table. So we have to
+ // extract the base name, look that up, and if there is any other
+ // information in the name we were
+ // passed in we have to post-filter based on that.
+
+ // FIXME: Arrange the logic above so that we don't calculate the base
+ // name twice:
+ num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
+
+ for (uint32_t i = 0; i < num_matches; i++) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE(die_ref);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ // If we get to here, the die is good, and we should add it:
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() &&
+ ResolveFunction(die, include_inlines, sc_list)) {
+ bool keep_die = true;
+ if ((name_type_mask &
+ (eFunctionNameTypeBase | eFunctionNameTypeMethod)) !=
+ (eFunctionNameTypeBase | eFunctionNameTypeMethod)) {
+ // We are looking for either basenames or methods, so we need to
+ // trim out the ones we won't want by looking at the type
+ SymbolContext sc;
+ if (sc_list.GetLastContext(sc)) {
+ if (sc.block) {
+ // We have an inlined function
+ } else if (sc.function) {
+ Type *type = sc.function->GetType();
+
+ if (type) {
+ CompilerDeclContext decl_ctx =
+ GetDeclContextContainingUID(type->GetID());
+ if (decl_ctx.IsStructUnionOrClass()) {
+ if (name_type_mask & eFunctionNameTypeBase) {
+ sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
+ keep_die = false;
+ }
+ } else {
+ if (name_type_mask & eFunctionNameTypeMethod) {
+ sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
+ keep_die = false;
}
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportWarning(
+ "function at die offset 0x%8.8x had no function type",
+ die_ref.die_offset);
}
+ }
}
+ }
+ if (keep_die)
+ resolved_dies.insert(die.GetDIE());
}
+ } else {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')",
+ die_ref.die_offset, name_cstr);
+ }
}
- DIEArray die_offsets;
- if (name_type_mask & eFunctionNameTypeBase)
- {
- uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
- for (uint32_t i = 0; i < num_base; i++)
- {
- DWARFDIE die = info->GetDIE (die_offsets[i]);
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
+ die_offsets.clear();
+ }
+ }
+ } else {
+
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
+
+ if (name_type_mask & eFunctionNameTypeFull) {
+ FindFunctions(name, m_function_fullname_index, include_inlines, sc_list);
+
+ // FIXME Temporary workaround for global/anonymous namespace
+ // functions debugging FreeBSD and Linux binaries.
+ // If we didn't find any functions in the global namespace try
+ // looking in the basename index but ignore any returned
+ // functions that have a namespace but keep functions which
+ // have an anonymous namespace
+ // TODO: The arch in the object file isn't correct for MSVC
+ // binaries on windows, we should find a way to make it
+ // correct and handle those symbols as well.
+ if (sc_list.GetSize() == original_size) {
+ ArchSpec arch;
+ if (!parent_decl_ctx && GetObjectFile()->GetArchitecture(arch) &&
+ arch.GetTriple().isOSBinFormatELF()) {
+ SymbolContextList temp_sc_list;
+ FindFunctions(name, m_function_basename_index, include_inlines,
+ temp_sc_list);
+ SymbolContext sc;
+ for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) {
+ if (temp_sc_list.GetContextAtIndex(i, sc)) {
+ ConstString mangled_name =
+ sc.GetFunctionName(Mangled::ePreferMangled);
+ ConstString demangled_name =
+ sc.GetFunctionName(Mangled::ePreferDemangled);
+ // Mangled names on Linux and FreeBSD are of the form:
+ // _ZN18function_namespace13function_nameEv.
+ if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
+ !strncmp(demangled_name.GetCString(), "(anonymous namespace)",
+ 21)) {
+ sc_list.Append(sc);
+ }
}
- die_offsets.clear();
+ }
}
-
- if (name_type_mask & eFunctionNameTypeMethod)
- {
- if (parent_decl_ctx && parent_decl_ctx->IsValid())
- return 0; // no methods in namespaces
-
- uint32_t num_base = m_function_method_index.Find(name, die_offsets);
- {
- for (uint32_t i = 0; i < num_base; i++)
- {
- DWARFDIE die = info->GetDIE (die_offsets[i]);
- if (die)
- {
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- }
- }
- die_offsets.clear();
+ }
+ }
+ DIEArray die_offsets;
+ if (name_type_mask & eFunctionNameTypeBase) {
+ uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
+ for (uint32_t i = 0; i < num_base; i++) {
+ DWARFDIE die = info->GetDIE(die_offsets[i]);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ // If we get to here, the die is good, and we should add it:
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
+ }
}
+ }
+ die_offsets.clear();
+ }
- if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
- {
- FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
+ if (name_type_mask & eFunctionNameTypeMethod) {
+ if (parent_decl_ctx && parent_decl_ctx->IsValid())
+ return 0; // no methods in namespaces
+
+ uint32_t num_base = m_function_method_index.Find(name, die_offsets);
+ {
+ for (uint32_t i = 0; i < num_base; i++) {
+ DWARFDIE die = info->GetDIE(die_offsets[i]);
+ if (die) {
+ // If we get to here, the die is good, and we should add it:
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
+ }
+ }
}
-
+ }
+ die_offsets.clear();
}
- // Return the number of variable that were appended to the list
- const uint32_t num_matches = sc_list.GetSize() - original_size;
-
- if (log && num_matches > 0)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
- name.GetCString(),
- name_type_mask,
- include_inlines,
- append,
- num_matches);
+ if ((name_type_mask & eFunctionNameTypeSelector) &&
+ (!parent_decl_ctx || !parent_decl_ctx->IsValid())) {
+ FindFunctions(name, m_function_selector_index, include_inlines, sc_list);
}
- return num_matches;
+ }
+
+ // Return the number of variable that were appended to the list
+ const uint32_t num_matches = sc_list.GetSize() - original_size;
+
+ if (log && num_matches > 0) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
+ "name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => "
+ "%u",
+ name.GetCString(), name_type_mask, include_inlines, append,
+ num_matches);
+ }
+ return num_matches;
}
-uint32_t
-SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolFileDWARF::FindFunctions (regex = '%s')",
- regex.GetText());
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
- regex.GetText(),
- append);
- }
-
-
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
- // Remember how many sc_list are in the list before we search in case
- // we are appending the results to a variable list.
- uint32_t original_size = sc_list.GetSize();
-
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
- }
- else
- {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
-
- FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
-
- FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
- }
-
- // Return the number of variable that were appended to the list
- return sc_list.GetSize() - original_size;
+uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARF::FindFunctions (regex = '%s')",
+ regex.GetText().str().c_str());
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
+ regex.GetText().str().c_str(), append);
+ }
+
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ sc_list.Clear();
+
+ // Remember how many sc_list are in the list before we search in case
+ // we are appending the results to a variable list.
+ uint32_t original_size = sc_list.GetSize();
+
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get())
+ FindFunctions(regex, *m_apple_names_ap, include_inlines, sc_list);
+ } else {
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
+
+ FindFunctions(regex, m_function_basename_index, include_inlines, sc_list);
+
+ FindFunctions(regex, m_function_fullname_index, include_inlines, sc_list);
+ }
+
+ // Return the number of variable that were appended to the list
+ return sc_list.GetSize() - original_size;
}
-void
-SymbolFileDWARF::GetMangledNamesForFunction (const std::string &scope_qualified_name,
- std::vector<ConstString> &mangled_names)
-{
- DWARFDebugInfo* info = DebugInfo();
- uint32_t num_comp_units = 0;
- if (info)
- num_comp_units = info->GetNumCompileUnits();
-
- for (uint32_t i = 0; i < num_comp_units; i++)
- {
- DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i);
- if (cu == nullptr)
- continue;
-
- SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
- if (dwo)
- dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
- }
-
- NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name);
- if (iter == m_function_scope_qualified_name_map.end())
- return;
-
- DIERefSetSP set_sp = (*iter).second;
- std::set<DIERef>::iterator set_iter;
- for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++)
- {
- DWARFDIE die = DebugInfo()->GetDIE (*set_iter);
- mangled_names.push_back(ConstString(die.GetMangledName()));
- }
+void SymbolFileDWARF::GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<ConstString> &mangled_names) {
+ DWARFDebugInfo *info = DebugInfo();
+ uint32_t num_comp_units = 0;
+ if (info)
+ num_comp_units = info->GetNumCompileUnits();
+
+ for (uint32_t i = 0; i < num_comp_units; i++) {
+ DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i);
+ if (cu == nullptr)
+ continue;
+
+ SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
+ if (dwo)
+ dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
+ }
+
+ NameToOffsetMap::iterator iter =
+ m_function_scope_qualified_name_map.find(scope_qualified_name);
+ if (iter == m_function_scope_qualified_name_map.end())
+ return;
+
+ DIERefSetSP set_sp = (*iter).second;
+ std::set<DIERef>::iterator set_iter;
+ for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++) {
+ DWARFDIE die = DebugInfo()->GetDIE(*set_iter);
+ mangled_names.push_back(ConstString(die.GetMangledName()));
+ }
}
+uint32_t SymbolFileDWARF::FindTypes(
+ const SymbolContext &sc, 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
+ if (!append)
+ types.Clear();
+
+ // Make sure we haven't already searched this SymbolFile before...
+ if (searched_symbol_files.count(this))
+ return 0;
+ else
+ searched_symbol_files.insert(this);
-uint32_t
-SymbolFileDWARF::FindTypes (const SymbolContext& sc,
- 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
- if (!append)
- types.Clear();
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
- // Make sure we haven't already searched this SymbolFile before...
- if (searched_symbol_files.count(this))
- return 0;
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ if (parent_decl_ctx)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "%p (\"%s\"), append=%u, max_matches=%u, type_list)",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx),
+ parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches);
else
- searched_symbol_files.insert(this);
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "NULL, append=%u, max_matches=%u, type_list)",
+ name.GetCString(), append, max_matches);
+ }
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+ DIEArray die_offsets;
- if (log)
- {
- if (parent_decl_ctx)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"),
- append, max_matches);
- else
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
- name.GetCString(), append,
- max_matches);
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ m_apple_types_ap->FindByName(name_cstr, die_offsets);
}
-
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
-
- DIEArray die_offsets;
-
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const char *name_cstr = name.GetCString();
- m_apple_types_ap->FindByName (name_cstr, die_offsets);
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_type_index.Find(name, die_offsets);
+ }
+
+ const size_t num_die_matches = die_offsets.size();
+
+ if (num_die_matches) {
+ const uint32_t initial_types_size = types.GetSize();
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ Type *matching_type = ResolveType(die, true, true);
+ if (matching_type) {
+ // We found a type pointer, now find the shared pointer form our type
+ // list
+ types.InsertUnique(matching_type->shared_from_this());
+ if (types.GetSize() >= max_matches)
+ break;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, name.GetCString());
}
+ }
}
- else
- {
- if (!m_indexed)
- Index ();
-
- m_type_index.Find (name, die_offsets);
+ const uint32_t num_matches = types.GetSize() - initial_types_size;
+ if (log && num_matches) {
+ if (parent_decl_ctx) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx),
+ parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches,
+ num_matches);
+ } else {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= NULL, append=%u, max_matches=%u, type_list) => %u",
+ name.GetCString(), append, max_matches, num_matches);
+ }
}
+ return num_matches;
+ } else {
+ UpdateExternalModuleListIfNeeded();
- const size_t num_die_matches = die_offsets.size();
-
- if (num_die_matches)
- {
- const uint32_t initial_types_size = types.GetSize();
- for (size_t i=0; i<num_die_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- Type *matching_type = ResolveType (die, true, true);
- if (matching_type)
- {
- // We found a type pointer, now find the shared pointer form our type list
- types.InsertUnique (matching_type->shared_from_this());
- if (types.GetSize() >= max_matches)
- break;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
- }
-
- }
- const uint32_t num_matches = types.GetSize() - initial_types_size;
- if (log && num_matches)
- {
- if (parent_decl_ctx)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"),
- append, max_matches,
- num_matches);
- }
- else
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(),
- append, max_matches,
- num_matches);
- }
- }
- return num_matches;
- }
- else
- {
- UpdateExternalModuleListIfNeeded();
-
- for (const auto &pair : m_external_type_modules)
- {
- ModuleSP external_module_sp = pair.second;
- if (external_module_sp)
- {
- 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);
- if (num_external_matches)
- return num_external_matches;
- }
- }
+ for (const auto &pair : m_external_type_modules) {
+ ModuleSP external_module_sp = pair.second;
+ if (external_module_sp) {
+ 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);
+ if (num_external_matches)
+ return num_external_matches;
}
+ }
}
+ }
- return 0;
+ return 0;
}
+size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
+ bool append, TypeMap &types) {
+ if (!append)
+ types.Clear();
-size_t
-SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
- bool append,
- TypeMap& types)
-{
- if (!append)
- types.Clear();
-
- if (context.empty())
- return 0;
-
- DIEArray die_offsets;
+ if (context.empty())
+ return 0;
- ConstString name = context.back().name;
+ DIEArray die_offsets;
- if (!name)
- return 0;
+ ConstString name = context.back().name;
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const char *name_cstr = name.GetCString();
- m_apple_types_ap->FindByName (name_cstr, die_offsets);
- }
- }
- else
- {
- if (!m_indexed)
- Index ();
+ if (!name)
+ return 0;
- m_type_index.Find (name, die_offsets);
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ m_apple_types_ap->FindByName(name_cstr, die_offsets);
}
-
- const size_t num_die_matches = die_offsets.size();
-
- if (num_die_matches)
- {
- size_t num_matches = 0;
- for (size_t i=0; i<num_die_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- std::vector<CompilerContext> die_context;
- die.GetDWOContext(die_context);
- if (die_context != context)
- continue;
-
- Type *matching_type = ResolveType (die, true, true);
- if (matching_type)
- {
- // We found a type pointer, now find the shared pointer form our type list
- types.InsertUnique (matching_type->shared_from_this());
- ++num_matches;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
- }
-
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_type_index.Find(name, die_offsets);
+ }
+
+ const size_t num_die_matches = die_offsets.size();
+
+ if (num_die_matches) {
+ size_t num_matches = 0;
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ std::vector<CompilerContext> die_context;
+ die.GetDWOContext(die_context);
+ if (die_context != context)
+ continue;
+
+ Type *matching_type = ResolveType(die, true, true);
+ if (matching_type) {
+ // We found a type pointer, now find the shared pointer form our type
+ // list
+ types.InsertUnique(matching_type->shared_from_this());
+ ++num_matches;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, name.GetCString());
}
- return num_matches;
+ }
}
- return 0;
+ return num_matches;
+ }
+ return 0;
}
-
CompilerDeclContext
-SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
- const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
- name.GetCString());
- }
-
- CompilerDeclContext namespace_decl_ctx;
+SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return namespace_decl_ctx;
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
+ name.GetCString());
+ }
+ CompilerDeclContext namespace_decl_ctx;
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- DIEArray die_offsets;
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return namespace_decl_ctx;
- // Index if we already haven't to make sure the compile units
- // get indexed and make their global DIE index list
- if (m_using_apple_tables)
- {
- if (m_apple_namespaces_ap.get())
- {
- const char *name_cstr = name.GetCString();
- m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
- }
- }
- else
- {
- if (!m_indexed)
- Index ();
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ DIEArray die_offsets;
- m_namespace_index.Find (name, die_offsets);
- }
-
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- if (!DIEInDeclContext (parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- {
- namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
- if (namespace_decl_ctx)
- break;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
- }
+ // Index if we already haven't to make sure the compile units
+ // get indexed and make their global DIE index list
+ if (m_using_apple_tables) {
+ if (m_apple_namespaces_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ m_apple_namespaces_ap->FindByName(name_cstr, die_offsets);
+ }
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_namespace_index.Find(name, die_offsets);
+ }
- }
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast) {
+ namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);
+ if (namespace_decl_ctx)
+ break;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified "
+ "(.apple_namespaces accelerator table had bad die 0x%8.8x for "
+ "'%s')\n",
+ die_ref.die_offset, name.GetCString());
+ }
}
+ }
}
- if (log && namespace_decl_ctx)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
- name.GetCString(),
- static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
- static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
- namespace_decl_ctx.GetName().AsCString("<NULL>"));
- }
-
- return namespace_decl_ctx;
+ }
+ if (log && namespace_decl_ctx) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
+ "CompilerDeclContext(%p/%p) \"%s\"",
+ name.GetCString(),
+ static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),
+ static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),
+ namespace_decl_ctx.GetName().AsCString("<NULL>"));
+ }
+
+ return namespace_decl_ctx;
}
-TypeSP
-SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context)
-{
- TypeSP type_sp;
- if (die)
- {
- Type *type_ptr = GetDIEToType().lookup (die.GetDIE());
- if (type_ptr == NULL)
- {
- CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
- assert (lldb_cu);
- SymbolContext sc(lldb_cu);
- const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE();
- while (parent_die != nullptr)
- {
- if (parent_die->Tag() == DW_TAG_subprogram)
- break;
- parent_die = parent_die->GetParent();
- }
- SymbolContext sc_backup = sc;
- if (resolve_function_context && parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc))
- sc = sc_backup;
-
- type_sp = ParseType(sc, die, NULL);
- }
- else if (type_ptr != DIE_IS_BEING_PARSED)
- {
- // Grab the existing type from the master types lists
- type_sp = type_ptr->shared_from_this();
- }
-
+TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,
+ bool resolve_function_context) {
+ TypeSP type_sp;
+ if (die) {
+ Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
+ if (type_ptr == NULL) {
+ CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
+ assert(lldb_cu);
+ SymbolContext sc(lldb_cu);
+ const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
+ while (parent_die != nullptr) {
+ if (parent_die->Tag() == DW_TAG_subprogram)
+ break;
+ parent_die = parent_die->GetParent();
+ }
+ SymbolContext sc_backup = sc;
+ if (resolve_function_context && parent_die != nullptr &&
+ !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
+ sc = sc_backup;
+
+ type_sp = ParseType(sc, die, NULL);
+ } else if (type_ptr != DIE_IS_BEING_PARSED) {
+ // Grab the existing type from the master types lists
+ type_sp = type_ptr->shared_from_this();
}
- return type_sp;
+ }
+ return type_sp;
}
-
DWARFDIE
-SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
-{
- if (orig_die)
- {
- DWARFDIE die = orig_die;
-
- while (die)
- {
- // If this is the original DIE that we are searching for a declaration
- // for, then don't look in the cache as we don't want our own decl
- // context to be our decl context...
- if (orig_die != die)
- {
- switch (die.Tag())
- {
- case DW_TAG_compile_unit:
- case DW_TAG_namespace:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- case DW_TAG_lexical_block:
- case DW_TAG_subprogram:
- return die;
-
- default:
- break;
- }
- }
-
- DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
- if (spec_die)
- {
- DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
+ if (orig_die) {
+ DWARFDIE die = orig_die;
- DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
- if (abs_die)
- {
- DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+ while (die) {
+ // If this is the original DIE that we are searching for a declaration
+ // for, then don't look in the cache as we don't want our own decl
+ // context to be our decl context...
+ if (orig_die != die) {
+ switch (die.Tag()) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_namespace:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ case DW_TAG_lexical_block:
+ case DW_TAG_subprogram:
+ return die;
- die = die.GetParent();
+ default:
+ break;
}
+ }
+
+ DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
+ if (spec_die) {
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+
+ DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
+ if (abs_die) {
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+
+ die = die.GetParent();
}
- return DWARFDIE();
+ }
+ return DWARFDIE();
}
-
Symbol *
-SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
-{
- Symbol *objc_class_symbol = NULL;
- if (m_obj_file)
- {
- Symtab *symtab = m_obj_file->GetSymtab ();
- if (symtab)
- {
- objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
- eSymbolTypeObjCClass,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
- }
+SymbolFileDWARF::GetObjCClassSymbol(const ConstString &objc_class_name) {
+ Symbol *objc_class_symbol = NULL;
+ if (m_obj_file) {
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
+ objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
}
- return objc_class_symbol;
+ }
+ return objc_class_symbol;
}
-// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
-// then we can end up looking through all class types for a complete type and never find
-// the full definition. We need to know if this attribute is supported, so we determine
-// this here and cache th result. We also need to worry about the debug map DWARF file
+// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If
+// they don't
+// then we can end up looking through all class types for a complete type and
+// never find
+// the full definition. We need to know if this attribute is supported, so we
+// determine
+// this here and cache th result. We also need to worry about the debug map
+// DWARF file
// if we are doing darwin DWARF in .o file debugging.
-bool
-SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
-{
- if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
- if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
- else
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- const uint32_t num_compile_units = GetNumCompileUnits();
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
- break;
- }
- }
+bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
+ DWARFCompileUnit *cu) {
+ if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
+ if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+ else {
+ DWARFDebugInfo *debug_info = DebugInfo();
+ const uint32_t num_compile_units = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu != cu &&
+ dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+ break;
}
- if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
- return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
+ }
}
- return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
+ if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo &&
+ GetDebugMapSymfile())
+ return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type(this);
+ }
+ return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
}
// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
-TypeSP
-SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const ConstString &type_name,
- bool must_be_implementation)
-{
-
- TypeSP type_sp;
-
- if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
- return type_sp;
-
- DIEArray die_offsets;
-
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const char *name_cstr = type_name.GetCString();
- m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
- }
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_type_index.Find (type_name, die_offsets);
+TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const ConstString &type_name,
+ bool must_be_implementation) {
+
+ TypeSP type_sp;
+
+ if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name)))
+ return type_sp;
+
+ DIEArray die_offsets;
+
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const char *name_cstr = type_name.GetCString();
+ m_apple_types_ap->FindCompleteObjCClassByName(name_cstr, die_offsets,
+ must_be_implementation);
}
-
- const size_t num_matches = die_offsets.size();
-
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = GetDIE (die_ref);
-
- if (type_die)
- {
- bool try_resolving_type = false;
-
- // Don't try and resolve the DIE we are looking for with the DIE itself!
- if (type_die != die)
- {
- switch (type_die.Tag())
- {
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- try_resolving_type = true;
- break;
- default:
- break;
- }
- }
-
- if (try_resolving_type)
- {
- if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
- try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
-
- if (try_resolving_type)
- {
- Type *resolved_type = ResolveType (type_die, false, true);
- if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
- {
- DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
- die.GetID(),
- m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
- type_die.GetID(),
- type_cu->GetID());
-
- if (die)
- GetDIEToType()[die.GetDIE()] = resolved_type;
- type_sp = resolved_type->shared_from_this();
- break;
- }
- }
- }
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_type_index.Find(type_name, die_offsets);
+ }
+
+ const size_t num_matches = die_offsets.size();
+
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE type_die = GetDIE(die_ref);
+
+ if (type_die) {
+ bool try_resolving_type = false;
+
+ // Don't try and resolve the DIE we are looking for with the DIE itself!
+ if (type_die != die) {
+ switch (type_die.Tag()) {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ try_resolving_type = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (try_resolving_type) {
+ if (must_be_implementation &&
+ type_die.Supports_DW_AT_APPLE_objc_complete_type())
+ try_resolving_type = type_die.GetAttributeValueAsUnsigned(
+ DW_AT_APPLE_objc_complete_type, 0);
+
+ if (try_resolving_type) {
+ Type *resolved_type = ResolveType(type_die, false, true);
+ if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) {
+ DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
+ " (cu 0x%8.8" PRIx64 ")\n",
+ die.GetID(),
+ m_obj_file->GetFileSpec().GetFilename().AsCString(
+ "<Unknown>"),
+ type_die.GetID(), type_cu->GetID());
+
+ if (die)
+ GetDIEToType()[die.GetDIE()] = resolved_type;
+ type_sp = resolved_type->shared_from_this();
+ break;
}
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, type_name.GetCString());
- }
- }
-
+ }
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, type_name.GetCString());
}
+ }
}
- return type_sp;
+ }
+ return type_sp;
}
-
//----------------------------------------------------------------------
// This function helps to ensure that the declaration contexts match for
-// two different DIEs. Often times debug information will refer to a
+// two different DIEs. Often times debug information will refer to a
// forward declaration of a type (the equivalent of "struct my_struct;".
// There will often be a declaration of that type elsewhere that has the
// full definition. When we go looking for the full type "my_struct", we
// will find one or more matches in the accelerator tables and we will
-// then need to make sure the type was in the same declaration context
+// then need to make sure the type was in the same declaration context
// as the original DIE. This function can efficiently compare two DIEs
// and will return true when the declaration context matches, and false
-// when they don't.
+// when they don't.
//----------------------------------------------------------------------
-bool
-SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
- const DWARFDIE &die2)
-{
- if (die1 == die2)
- return true;
-
- DWARFDIECollection decl_ctx_1;
- DWARFDIECollection decl_ctx_2;
- //The declaration DIE stack is a stack of the declaration context
- // DIEs all the way back to the compile unit. If a type "T" is
- // declared inside a class "B", and class "B" is declared inside
- // a class "A" and class "A" is in a namespace "lldb", and the
- // namespace is in a compile unit, there will be a stack of DIEs:
- //
- // [0] DW_TAG_class_type for "B"
- // [1] DW_TAG_class_type for "A"
- // [2] DW_TAG_namespace for "lldb"
- // [3] DW_TAG_compile_unit for the source file.
- //
- // We grab both contexts and make sure that everything matches
- // all the way back to the compiler unit.
-
- // First lets grab the decl contexts for both DIEs
- die1.GetDeclContextDIEs (decl_ctx_1);
- die2.GetDeclContextDIEs (decl_ctx_2);
- // Make sure the context arrays have the same size, otherwise
- // we are done
- const size_t count1 = decl_ctx_1.Size();
- const size_t count2 = decl_ctx_2.Size();
- if (count1 != count2)
- return false;
-
- // Make sure the DW_TAG values match all the way back up the
- // compile unit. If they don't, then we are done.
- DWARFDIE decl_ctx_die1;
- DWARFDIE decl_ctx_die2;
- size_t i;
- for (i=0; i<count1; i++)
- {
- decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
- decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
- if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
- return false;
- }
+bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
+ const DWARFDIE &die2) {
+ if (die1 == die2)
+ return true;
+
+ DWARFDIECollection decl_ctx_1;
+ DWARFDIECollection decl_ctx_2;
+ // The declaration DIE stack is a stack of the declaration context
+ // DIEs all the way back to the compile unit. If a type "T" is
+ // declared inside a class "B", and class "B" is declared inside
+ // a class "A" and class "A" is in a namespace "lldb", and the
+ // namespace is in a compile unit, there will be a stack of DIEs:
+ //
+ // [0] DW_TAG_class_type for "B"
+ // [1] DW_TAG_class_type for "A"
+ // [2] DW_TAG_namespace for "lldb"
+ // [3] DW_TAG_compile_unit for the source file.
+ //
+ // We grab both contexts and make sure that everything matches
+ // all the way back to the compiler unit.
+
+ // First lets grab the decl contexts for both DIEs
+ die1.GetDeclContextDIEs(decl_ctx_1);
+ die2.GetDeclContextDIEs(decl_ctx_2);
+ // Make sure the context arrays have the same size, otherwise
+ // we are done
+ const size_t count1 = decl_ctx_1.Size();
+ const size_t count2 = decl_ctx_2.Size();
+ if (count1 != count2)
+ return false;
+
+ // Make sure the DW_TAG values match all the way back up the
+ // compile unit. If they don't, then we are done.
+ DWARFDIE decl_ctx_die1;
+ DWARFDIE decl_ctx_die2;
+ size_t i;
+ for (i = 0; i < count1; i++) {
+ decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i);
+ decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i);
+ if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
+ return false;
+ }
#if defined LLDB_CONFIGURATION_DEBUG
- // Make sure the top item in the decl context die array is always
- // DW_TAG_compile_unit. If it isn't then something went wrong in
- // the DWARFDIE::GetDeclContextDIEs() function...
- assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
+ // Make sure the top item in the decl context die array is always
+ // DW_TAG_compile_unit. If it isn't then something went wrong in
+ // the DWARFDIE::GetDeclContextDIEs() function...
+ assert(decl_ctx_1.GetDIEAtIndex(count1 - 1).Tag() == DW_TAG_compile_unit);
#endif
- // Always skip the compile unit when comparing by only iterating up to
- // "count - 1". Here we compare the names as we go.
- for (i=0; i<count1 - 1; i++)
- {
- decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
- decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
- const char *name1 = decl_ctx_die1.GetName();
- const char *name2 = decl_ctx_die2.GetName();
- // If the string was from a DW_FORM_strp, then the pointer will often
- // be the same!
- if (name1 == name2)
- continue;
-
- // Name pointers are not equal, so only compare the strings
- // if both are not NULL.
- if (name1 && name2)
- {
- // If the strings don't compare, we are done...
- if (strcmp(name1, name2) != 0)
- return false;
- }
- else
- {
- // One name was NULL while the other wasn't
- return false;
- }
+ // Always skip the compile unit when comparing by only iterating up to
+ // "count - 1". Here we compare the names as we go.
+ for (i = 0; i < count1 - 1; i++) {
+ decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i);
+ decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i);
+ const char *name1 = decl_ctx_die1.GetName();
+ const char *name2 = decl_ctx_die2.GetName();
+ // If the string was from a DW_FORM_strp, then the pointer will often
+ // be the same!
+ if (name1 == name2)
+ continue;
+
+ // Name pointers are not equal, so only compare the strings
+ // if both are not NULL.
+ if (name1 && name2) {
+ // If the strings don't compare, we are done...
+ if (strcmp(name1, name2) != 0)
+ return false;
+ } else {
+ // One name was NULL while the other wasn't
+ return false;
}
- // We made it through all of the checks and the declaration contexts
- // are equal.
- return true;
+ }
+ // We made it through all of the checks and the declaration contexts
+ // are equal.
+ return true;
}
-
-
-TypeSP
-SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
-{
- TypeSP type_sp;
-
- const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
- if (dwarf_decl_ctx_count > 0)
- {
- const ConstString type_name(dwarf_decl_ctx[0].name);
- const dw_tag_t tag = dwarf_decl_ctx[0].tag;
- if (type_name)
- {
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
+TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &dwarf_decl_ctx) {
+ TypeSP type_sp;
+
+ const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
+ if (dwarf_decl_ctx_count > 0) {
+ const ConstString type_name(dwarf_decl_ctx[0].name);
+ const dw_tag_t tag = dwarf_decl_ctx[0].tag;
+
+ if (type_name) {
+ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS));
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
+ "s, qualified-name='%s')",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName());
+ }
+
+ DIEArray die_offsets;
+
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const bool has_tag =
+ m_apple_types_ap->GetHeader().header_data.ContainsAtom(
+ DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash =
+ m_apple_types_ap->GetHeader().header_data.ContainsAtom(
+ DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash) {
+ const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
+ const uint32_t qualified_name_hash =
+ MappedHash::HashStringUsingDJB(qualified_name);
if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName());
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash(
+ type_name.GetCString(), tag, qualified_name_hash, die_offsets);
+ } else if (has_tag) {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(log,
+ "FindByNameAndTag()");
+ m_apple_types_ap->FindByNameAndTag(type_name.GetCString(), tag,
+ die_offsets);
+ } else {
+ m_apple_types_ap->FindByName(type_name.GetCString(), die_offsets);
+ }
+ }
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_type_index.Find(type_name, die_offsets);
+ }
+
+ const size_t num_matches = die_offsets.size();
+
+ // Get the type system that we are looking to find a type for. We will use
+ // this
+ // to ensure any matches we find are in a language that this type system
+ // supports
+ const LanguageType language = dwarf_decl_ctx.GetLanguage();
+ TypeSystem *type_system = (language == eLanguageTypeUnknown)
+ ? nullptr
+ : GetTypeSystemForLanguage(language);
+
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE type_die = GetDIE(die_ref);
+
+ if (type_die) {
+ // Make sure type_die's langauge matches the type system we are
+ // looking for.
+ // We don't want to find a "Foo" type from Java if we are looking
+ // for a "Foo"
+ // type for C, C++, ObjC, or ObjC++.
+ if (type_system &&
+ !type_system->SupportsLanguage(type_die.GetLanguage()))
+ continue;
+ bool try_resolving_type = false;
+
+ // Don't try and resolve the DIE we are looking for with the DIE
+ // itself!
+ const dw_tag_t type_tag = type_die.Tag();
+ // Make sure the tags match
+ if (type_tag == tag) {
+ // The tags match, lets try resolving this type
+ try_resolving_type = true;
+ } else {
+ // The tags don't match, but we need to watch our for a
+ // forward declaration for a struct and ("struct foo")
+ // ends up being a class ("class foo { ... };") or
+ // vice versa.
+ switch (type_tag) {
+ case DW_TAG_class_type:
+ // We had a "class foo", see if we ended up with a "struct foo {
+ // ... };"
+ try_resolving_type = (tag == DW_TAG_structure_type);
+ break;
+ case DW_TAG_structure_type:
+ // We had a "struct foo", see if we ended up with a "class foo {
+ // ... };"
+ try_resolving_type = (tag == DW_TAG_class_type);
+ break;
+ default:
+ // Tags don't match, don't event try to resolve
+ // using this type whose name matches....
+ break;
+ }
}
-
- DIEArray die_offsets;
-
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
- const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
- if (has_tag && has_qualified_name_hash)
- {
- const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
- const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
- m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
- }
- else if (has_tag)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
- m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
- }
- else
- {
- m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
- }
+
+ if (try_resolving_type) {
+ DWARFDeclContext type_dwarf_decl_ctx;
+ type_die.GetDWARFDeclContext(type_dwarf_decl_ctx);
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') trying die=0x%8.8x (%s)",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
+ type_dwarf_decl_ctx.GetQualifiedName());
+ }
+
+ // Make sure the decl contexts match all the way up
+ if (dwarf_decl_ctx == type_dwarf_decl_ctx) {
+ Type *resolved_type = ResolveType(type_die, false);
+ if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) {
+ type_sp = resolved_type->shared_from_this();
+ break;
}
+ }
+ } else {
+ if (log) {
+ std::string qualified_name;
+ type_die.GetQualifiedName(qualified_name);
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') ignoring die=0x%8.8x (%s)",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
+ qualified_name.c_str());
+ }
}
- else
- {
- if (!m_indexed)
- Index ();
-
- m_type_index.Find (type_name, die_offsets);
- }
-
- const size_t num_matches = die_offsets.size();
-
- // Get the type system that we are looking to find a type for. We will use this
- // to ensure any matches we find are in a language that this type system supports
- const LanguageType language = dwarf_decl_ctx.GetLanguage();
- TypeSystem *type_system = (language == eLanguageTypeUnknown) ? nullptr : GetTypeSystemForLanguage(language);
-
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = GetDIE (die_ref);
-
- if (type_die)
- {
- // Make sure type_die's langauge matches the type system we are looking for.
- // We don't want to find a "Foo" type from Java if we are looking for a "Foo"
- // type for C, C++, ObjC, or ObjC++.
- if (type_system && !type_system->SupportsLanguage(type_die.GetLanguage()))
- continue;
- bool try_resolving_type = false;
-
- // Don't try and resolve the DIE we are looking for with the DIE itself!
- const dw_tag_t type_tag = type_die.Tag();
- // Make sure the tags match
- if (type_tag == tag)
- {
- // The tags match, lets try resolving this type
- try_resolving_type = true;
- }
- else
- {
- // The tags don't match, but we need to watch our for a
- // forward declaration for a struct and ("struct foo")
- // ends up being a class ("class foo { ... };") or
- // vice versa.
- switch (type_tag)
- {
- case DW_TAG_class_type:
- // We had a "class foo", see if we ended up with a "struct foo { ... };"
- try_resolving_type = (tag == DW_TAG_structure_type);
- break;
- case DW_TAG_structure_type:
- // We had a "struct foo", see if we ended up with a "class foo { ... };"
- try_resolving_type = (tag == DW_TAG_class_type);
- break;
- default:
- // Tags don't match, don't event try to resolve
- // using this type whose name matches....
- break;
- }
- }
-
- if (try_resolving_type)
- {
- DWARFDeclContext type_dwarf_decl_ctx;
- type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName(),
- type_die.GetOffset(),
- type_dwarf_decl_ctx.GetQualifiedName());
- }
-
- // Make sure the decl contexts match all the way up
- if (dwarf_decl_ctx == type_dwarf_decl_ctx)
- {
- Type *resolved_type = ResolveType (type_die, false);
- if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
- {
- type_sp = resolved_type->shared_from_this();
- break;
- }
- }
- }
- else
- {
- if (log)
- {
- std::string qualified_name;
- type_die.GetQualifiedName(qualified_name);
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName(),
- type_die.GetOffset(),
- qualified_name.c_str());
- }
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, type_name.GetCString());
- }
- }
-
- }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, type_name.GetCString());
}
+ }
}
+ }
}
- return type_sp;
+ }
+ return type_sp;
}
-TypeSP
-SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
-{
- TypeSP type_sp;
-
- if (die)
- {
- TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
-
- if (type_system)
- {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- {
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
- if (type_sp)
- {
- TypeList* type_list = GetTypeList();
- if (type_list)
- type_list->Insert(type_sp);
-
- if (die.Tag() == DW_TAG_subprogram)
- {
- DIERef die_ref = die.GetDIERef();
- std::string scope_qualified_name(GetDeclContextForUID(die.GetID()).GetScopeQualifiedName().AsCString(""));
- if (scope_qualified_name.size())
- {
- NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name);
- if (iter != m_function_scope_qualified_name_map.end())
- (*iter).second->insert(die_ref);
- else
- {
- DIERefSetSP new_set(new std::set<DIERef>);
- new_set->insert(die_ref);
- m_function_scope_qualified_name_map.emplace(std::make_pair(scope_qualified_name, new_set));
- }
- }
- }
- }
+TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
+ bool *type_is_new_ptr) {
+ TypeSP type_sp;
+
+ if (die) {
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+
+ if (type_system) {
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
+ if (type_sp) {
+ TypeList *type_list = GetTypeList();
+ if (type_list)
+ type_list->Insert(type_sp);
+
+ if (die.Tag() == DW_TAG_subprogram) {
+ DIERef die_ref = die.GetDIERef();
+ std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
+ .GetScopeQualifiedName()
+ .AsCString(""));
+ if (scope_qualified_name.size()) {
+ NameToOffsetMap::iterator iter =
+ m_function_scope_qualified_name_map.find(
+ scope_qualified_name);
+ if (iter != m_function_scope_qualified_name_map.end())
+ (*iter).second->insert(die_ref);
+ else {
+ DIERefSetSP new_set(new std::set<DIERef>);
+ new_set->insert(die_ref);
+ m_function_scope_qualified_name_map.emplace(
+ std::make_pair(scope_qualified_name, new_set));
+ }
}
+ }
}
+ }
}
-
- return type_sp;
-}
+ }
-size_t
-SymbolFileDWARF::ParseTypes
-(
- const SymbolContext& sc,
- const DWARFDIE &orig_die,
- bool parse_siblings,
- bool parse_children
-)
-{
- size_t types_added = 0;
- DWARFDIE die = orig_die;
- while (die)
- {
- bool type_is_new = false;
- if (ParseType(sc, die, &type_is_new).get())
- {
- if (type_is_new)
- ++types_added;
- }
+ return type_sp;
+}
- if (parse_children && die.HasChildren())
- {
- if (die.Tag() == DW_TAG_subprogram)
- {
- SymbolContext child_sc(sc);
- child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
- types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
- }
- else
- types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
- }
+size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
+ const DWARFDIE &orig_die,
+ bool parse_siblings, bool parse_children) {
+ size_t types_added = 0;
+ DWARFDIE die = orig_die;
+ while (die) {
+ bool type_is_new = false;
+ if (ParseType(sc, die, &type_is_new).get()) {
+ if (type_is_new)
+ ++types_added;
+ }
- if (parse_siblings)
- die = die.GetSibling();
- else
- die.Clear();
+ if (parse_children && die.HasChildren()) {
+ if (die.Tag() == DW_TAG_subprogram) {
+ SymbolContext child_sc(sc);
+ child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
+ types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
+ } else
+ types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
}
- return types_added;
-}
+ if (parse_siblings)
+ die = die.GetSibling();
+ else
+ die.Clear();
+ }
+ return types_added;
+}
-size_t
-SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
-{
- assert(sc.comp_unit && sc.function);
- size_t functions_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- 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);
- }
+size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) {
+ assert(sc.comp_unit && sc.function);
+ size_t functions_added = 0;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ 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);
}
+ }
- return functions_added;
+ return functions_added;
}
-
-size_t
-SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
-{
- // At least a compile unit must be valid
- assert(sc.comp_unit);
- size_t types_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- 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);
- }
- }
+size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) {
+ // At least a compile unit must be valid
+ assert(sc.comp_unit);
+ size_t types_added = 0;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ 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);
+ }
}
+ }
- return types_added;
+ return types_added;
}
-size_t
-SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
-{
- if (sc.comp_unit != NULL)
- {
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
-
- if (sc.function)
- {
- DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
-
- const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (func_lo_pc != LLDB_INVALID_ADDRESS)
- {
- const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
-
- // Let all blocks know they have parse all their variables
- sc.function->GetBlock (false).SetDidParseVariables (true, true);
- return num_variables;
+size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
+ if (sc.comp_unit != NULL) {
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
+
+ if (sc.function) {
+ DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
+
+ const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress(
+ DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (func_lo_pc != LLDB_INVALID_ADDRESS) {
+ const size_t num_variables = ParseVariables(
+ sc, function_die.GetFirstChild(), func_lo_pc, true, true);
+
+ // Let all blocks know they have parse all their variables
+ sc.function->GetBlock(false).SetDidParseVariables(true, true);
+ return num_variables;
+ }
+ } else if (sc.comp_unit) {
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
+
+ if (dwarf_cu == NULL)
+ return 0;
+
+ uint32_t vars_added = 0;
+ VariableListSP variables(sc.comp_unit->GetVariableList(false));
+
+ if (variables.get() == NULL) {
+ variables.reset(new VariableList());
+ sc.comp_unit->SetVariableList(variables);
+
+ DIEArray die_offsets;
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (m_apple_names_ap->AppendAllDIEsInRange(
+ dwarf_cu->GetOffset(), dwarf_cu->GetNextCompileUnitOffset(),
+ hash_data_array)) {
+ DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
}
+ }
+ } else {
+ // Index if we already haven't to make sure the compile units
+ // get indexed and make their global DIE index list
+ if (!m_indexed)
+ Index();
+
+ m_global_index.FindAllEntriesForCompileUnit(dwarf_cu->GetOffset(),
+ die_offsets);
}
- else if (sc.comp_unit)
- {
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
-
- if (dwarf_cu == NULL)
- return 0;
-
- uint32_t vars_added = 0;
- VariableListSP variables (sc.comp_unit->GetVariableList(false));
-
- if (variables.get() == NULL)
- {
- variables.reset(new VariableList());
- sc.comp_unit->SetVariableList(variables);
-
- DIEArray die_offsets;
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
- dwarf_cu->GetNextCompileUnitOffset(),
- hash_data_array))
- {
- DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
- }
- }
- }
- else
- {
- // Index if we already haven't to make sure the compile units
- // get indexed and make their global DIE index list
- if (!m_indexed)
- Index ();
-
- m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
- die_offsets);
- }
-
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
- if (die)
- {
- VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
- if (var_sp)
- {
- variables->AddVariableIfUnique (var_sp);
- ++vars_added;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset);
- }
- }
- }
- }
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+ if (die) {
+ VariableSP var_sp(
+ ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
+ if (var_sp) {
+ variables->AddVariableIfUnique(var_sp);
+ ++vars_added;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified "
+ "(.apple_names accelerator table had bad die 0x%8.8x)\n",
+ die_ref.die_offset);
+ }
}
- return vars_added;
+ }
}
+ }
+ return vars_added;
}
- return 0;
+ }
+ return 0;
}
-VariableSP
-SymbolFileDWARF::ParseVariableDIE
-(
- const SymbolContext& sc,
- const DWARFDIE &die,
- const lldb::addr_t func_low_pc
-)
-{
- if (die.GetDWARF() != this)
- return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
+VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
+ const DWARFDIE &die,
+ const lldb::addr_t func_low_pc) {
+ if (die.GetDWARF() != this)
+ return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
- VariableSP var_sp;
- if (!die)
- return var_sp;
+ VariableSP var_sp;
+ if (!die)
+ return var_sp;
- var_sp = GetDIEToVariable()[die.GetDIE()];
- if (var_sp)
- return var_sp; // Already been parsed!
-
- const dw_tag_t tag = die.Tag();
- ModuleSP module = GetObjectFile()->GetModule();
-
- if ((tag == DW_TAG_variable) ||
- (tag == DW_TAG_constant) ||
- (tag == DW_TAG_formal_parameter && sc.function))
- {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- DWARFDIE spec_die;
- if (num_attributes > 0)
- {
- const char *name = NULL;
- const char *mangled = NULL;
- Declaration decl;
- uint32_t i;
- DWARFFormValue type_die_form;
- DWARFExpression location(die.GetCU());
- bool is_external = false;
- bool is_artificial = false;
- bool location_is_const_value_data = false;
- bool has_explicit_location = false;
- DWARFFormValue const_value;
- Variable::RangeList scope_ranges;
- //AccessType accessibility = eAccessNone;
-
- for (i=0; i<num_attributes; ++i)
- {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
-
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name: name = form_value.AsCString(); break;
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
- case DW_AT_type: type_die_form = form_value; break;
- case DW_AT_external: is_external = form_value.Boolean(); break;
- case DW_AT_const_value:
- // If we have already found a DW_AT_location attribute, ignore this attribute.
- if (!has_explicit_location)
- {
- location_is_const_value_data = true;
- // The constant value will be either a block, a data value or a string.
- const DWARFDataExtractor& debug_info_data = get_debug_info_data();
- if (DWARFFormValue::IsBlockForm(form_value.Form()))
- {
- // Retrieve the value as a block expression.
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
- }
- else if (DWARFFormValue::IsDataForm(form_value.Form()))
- {
- // Retrieve the value as a data expression.
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (
- attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
- attributes.CompileUnitAtIndex(i)->IsDWARF64());
- uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
- if (data_length == 0)
- {
- const uint8_t *data_pointer = form_value.BlockData();
- if (data_pointer)
- {
- form_value.Unsigned();
- }
- else if (DWARFFormValue::IsDataForm(form_value.Form()))
- {
- // we need to get the byte size of the type later after we create the variable
- const_value = form_value;
- }
- }
- else
- location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
- }
- else
- {
- // Retrieve the value as a string expression.
- if (form_value.Form() == DW_FORM_strp)
- {
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (
- attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
- attributes.CompileUnitAtIndex(i)->IsDWARF64());
- uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
- location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
- }
- else
- {
- const char *str = form_value.AsCString();
- uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
- uint32_t string_length = strlen(str) + 1;
- location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
- }
- }
- }
- break;
- case DW_AT_location:
- {
- location_is_const_value_data = false;
- has_explicit_location = true;
- if (form_value.BlockData())
- {
- const DWARFDataExtractor& debug_info_data = get_debug_info_data();
-
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
- }
- else
- {
- const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0)
- {
- location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
- assert (func_low_pc != LLDB_INVALID_ADDRESS);
- location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
- }
- }
- }
- break;
- case DW_AT_specification:
- spec_die = GetDIE(DIERef(form_value));
- break;
- 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(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
- // dwarf spec is a bit ambiguous about what is the expected behavior in
- // case the enclosing block have a non coninious address range and the
- // DW_AT_start_scope entry have a form constant.
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_start_scope has unsupported form type (0x%x)\n",
- die.GetID(),
- form_value.Form());
- }
-
- scope_ranges.Sort();
- scope_ranges.CombineConsecutiveRanges();
- }
- break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
- case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_endianity:
- case DW_AT_segment:
- case DW_AT_visibility:
- default:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
+ var_sp = GetDIEToVariable()[die.GetDIE()];
+ if (var_sp)
+ return var_sp; // Already been parsed!
+
+ const dw_tag_t tag = die.Tag();
+ ModuleSP module = GetObjectFile()->GetModule();
+
+ if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
+ (tag == DW_TAG_formal_parameter && sc.function)) {
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ DWARFDIE spec_die;
+ if (num_attributes > 0) {
+ const char *name = NULL;
+ const char *mangled = NULL;
+ Declaration decl;
+ uint32_t i;
+ DWARFFormValue type_die_form;
+ DWARFExpression location(die.GetCU());
+ bool is_external = false;
+ bool is_artificial = false;
+ bool location_is_const_value_data = false;
+ bool has_explicit_location = false;
+ DWARFFormValue const_value;
+ Variable::RangeList scope_ranges;
+ // AccessType accessibility = eAccessNone;
+
+ for (i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ mangled = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_external:
+ is_external = form_value.Boolean();
+ break;
+ case DW_AT_const_value:
+ // If we have already found a DW_AT_location attribute, ignore this
+ // attribute.
+ if (!has_explicit_location) {
+ location_is_const_value_data = true;
+ // The constant value will be either a block, a data value or a
+ // string.
+ const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+ if (DWARFFormValue::IsBlockForm(form_value.Form())) {
+ // Retrieve the value as a block expression.
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ location.CopyOpcodeData(module, debug_info_data, block_offset,
+ block_length);
+ } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
+ // Retrieve the value as a data expression.
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(
+ attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
+ attributes.CompileUnitAtIndex(i)->IsDWARF64());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length =
+ fixed_form_sizes.GetSize(form_value.Form());
+ if (data_length == 0) {
+ const uint8_t *data_pointer = form_value.BlockData();
+ if (data_pointer) {
+ form_value.Unsigned();
+ } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
+ // we need to get the byte size of the type later after we
+ // create the variable
+ const_value = form_value;
+ }
+ } else
+ location.CopyOpcodeData(module, debug_info_data, data_offset,
+ data_length);
+ } else {
+ // Retrieve the value as a string expression.
+ if (form_value.Form() == DW_FORM_strp) {
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(
+ attributes.CompileUnitAtIndex(i)
+ ->GetAddressByteSize(),
+ attributes.CompileUnitAtIndex(i)->IsDWARF64());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length =
+ fixed_form_sizes.GetSize(form_value.Form());
+ location.CopyOpcodeData(module, debug_info_data, data_offset,
+ data_length);
+ } else {
+ const char *str = form_value.AsCString();
+ uint32_t string_offset =
+ str - (const char *)debug_info_data.GetDataStart();
+ uint32_t string_length = strlen(str) + 1;
+ location.CopyOpcodeData(module, debug_info_data,
+ string_offset, string_length);
}
+ }
}
-
- const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
- const dw_tag_t parent_tag = die.GetParent().Tag();
- bool is_static_member = parent_tag == DW_TAG_compile_unit && (parent_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type);
-
- ValueType scope = eValueTypeInvalid;
-
- const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
- SymbolContextScope * symbol_context_scope = NULL;
-
- if (!mangled)
- {
- // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
- // generate fully qualified names of global variables with commands like "frame var j".
- // For example, if j were an int variable holding a value 4 and declared in a namespace
- // B which in turn is contained in a namespace A, the command "frame var j" returns
- // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
- // to generate a fully qualified name from the declaration context.
- if (parent_tag == DW_TAG_compile_unit &&
- Language::LanguageIsCPlusPlus(die.GetLanguage()))
- {
- DWARFDeclContext decl_ctx;
-
- die.GetDWARFDeclContext(decl_ctx);
- mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
- }
+ break;
+ case DW_AT_location: {
+ location_is_const_value_data = false;
+ has_explicit_location = true;
+ if (DWARFFormValue::IsBlockForm(form_value.Form())) {
+ const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ location.CopyOpcodeData(module, get_debug_info_data(),
+ block_offset, block_length);
+ } else {
+ const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
+ const dw_offset_t debug_loc_offset = form_value.Unsigned();
+
+ size_t loc_list_length = DWARFExpression::LocationListSize(
+ die.GetCU(), debug_loc_data, debug_loc_offset);
+ if (loc_list_length > 0) {
+ location.CopyOpcodeData(module, debug_loc_data,
+ debug_loc_offset, loc_list_length);
+ assert(func_low_pc != LLDB_INVALID_ADDRESS);
+ location.SetLocationListSlide(
+ func_low_pc -
+ attributes.CompileUnitAtIndex(i)->GetBaseAddress());
+ }
}
-
- // DWARF doesn't specify if a DW_TAG_variable is a local, global
- // or static variable, so we have to do a little digging by
- // looking at the location of a variable to see if it contains
- // a DW_OP_addr opcode _somewhere_ in the definition. I say
- // somewhere because clang likes to combine small global variables
- // into the same symbol and have locations like:
- // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
- // So if we don't have a DW_TAG_formal_parameter, we can look at
- // the location to see if it contains a DW_OP_addr opcode, and
- // then we can correctly classify our variables.
- if (tag == DW_TAG_formal_parameter)
- scope = eValueTypeVariableArgument;
- else
- {
- bool op_error = false;
- // Check if the location has a DW_OP_addr with any address value...
- lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
- if (!location_is_const_value_data)
- {
- location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
- if (op_error)
- {
- StreamString strm;
- location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
- GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
- }
- }
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
-
- if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
- {
- if (is_external)
- scope = eValueTypeVariableGlobal;
- else
- scope = eValueTypeVariableStatic;
-
- if (debug_map_symfile)
- {
- // When leaving the DWARF in the .o files on darwin,
- // when we have a global variable that wasn't initialized,
- // the .o file might not have allocated a virtual
- // address for the global variable. In this case it will
- // have created a symbol for the global variable
- // that is undefined/data and external and the value will
- // be the byte size of the variable. When we do the
- // address map in SymbolFileDWARFDebugMap we rely on
- // having an address, we need to do some magic here
- // so we can get the correct address for our global
- // variable. The address for all of these entries
- // will be zero, and there will be an undefined symbol
- // in this object file, and the executable will have
- // a matching symbol with a good address. So here we
- // dig up the correct address and replace it in the
- // location for the variable, and set the variable's
- // symbol context scope to be that of the main executable
- // so the file address will resolve correctly.
- bool linked_oso_file_addr = false;
- if (is_external && location_DW_OP_addr == 0)
- {
- // we have a possible uninitialized extern global
- ConstString const_name(mangled ? mangled : name);
- ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
- if (debug_map_objfile)
- {
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
- if (debug_map_symtab)
- {
- Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeData,
- Symtab::eDebugYes,
- Symtab::eVisibilityExtern);
- if (exe_symbol)
- {
- if (exe_symbol->ValueIsAddress())
- {
- const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
- if (exe_file_addr != LLDB_INVALID_ADDRESS)
- {
- if (location.Update_DW_OP_addr (exe_file_addr))
- {
- linked_oso_file_addr = true;
- symbol_context_scope = exe_symbol;
- }
- }
- }
- }
- }
- }
- }
-
- if (!linked_oso_file_addr)
- {
- // The DW_OP_addr is not zero, but it contains a .o file address which
- // needs to be linked up correctly.
- const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
- if (exe_file_addr != LLDB_INVALID_ADDRESS)
- {
- // Update the file address for this variable
- location.Update_DW_OP_addr (exe_file_addr);
- }
- else
- {
- // Variable didn't make it into the final executable
- return var_sp;
- }
- }
- }
- }
- else
- {
- if (location_is_const_value_data)
- scope = eValueTypeVariableStatic;
- else
- {
- scope = eValueTypeVariableLocal;
- if (debug_map_symfile)
- {
- // We need to check for TLS addresses that we need to fixup
- if (location.ContainsThreadLocalStorage())
- {
- location.LinkThreadLocalStorage(
- debug_map_symfile->GetObjectFile()->GetModule(),
- [this, debug_map_symfile](lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
- return debug_map_symfile->LinkOSOFileAddress(this, unlinked_file_addr);
- });
- scope = eValueTypeVariableThreadLocal;
- }
- }
- }
- }
+ } break;
+ case DW_AT_specification:
+ spec_die = GetDIE(DIERef(form_value));
+ break;
+ 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(),
+ 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
+ // dwarf spec is a bit ambiguous about what is the expected
+ // behavior in
+ // case the enclosing block have a non coninious address range and
+ // the
+ // DW_AT_start_scope entry have a form constant.
+ GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64
+ ": DW_AT_start_scope has unsupported form type (0x%x)\n",
+ die.GetID(), form_value.Form());
}
- if (symbol_context_scope == NULL)
- {
- switch (parent_tag)
- {
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- if (sc.function)
- {
- symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
+ scope_ranges.Sort();
+ scope_ranges.CombineConsecutiveRanges();
+ } break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
+ case DW_AT_accessibility:
+ break; // accessibility =
+ // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+ case DW_AT_declaration:
+ case DW_AT_description:
+ case DW_AT_endianity:
+ case DW_AT_segment:
+ case DW_AT_visibility:
+ default:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
+
+ const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
+ const dw_tag_t parent_tag = die.GetParent().Tag();
+ bool is_static_member =
+ parent_tag == DW_TAG_compile_unit &&
+ (parent_context_die.Tag() == DW_TAG_class_type ||
+ parent_context_die.Tag() == DW_TAG_structure_type);
+
+ ValueType scope = eValueTypeInvalid;
+
+ const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
+ SymbolContextScope *symbol_context_scope = NULL;
+
+ bool has_explicit_mangled = mangled != nullptr;
+ if (!mangled) {
+ // LLDB relies on the mangled name (DW_TAG_linkage_name or
+ // DW_AT_MIPS_linkage_name) to
+ // generate fully qualified names of global variables with commands like
+ // "frame var j".
+ // For example, if j were an int variable holding a value 4 and declared
+ // in a namespace
+ // B which in turn is contained in a namespace A, the command "frame var
+ // j" returns
+ // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we
+ // should be able
+ // to generate a fully qualified name from the declaration context.
+ if (parent_tag == DW_TAG_compile_unit &&
+ Language::LanguageIsCPlusPlus(die.GetLanguage())) {
+ DWARFDeclContext decl_ctx;
+
+ die.GetDWARFDeclContext(decl_ctx);
+ mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
+ }
+ }
+
+ if (tag == DW_TAG_formal_parameter)
+ scope = eValueTypeVariableArgument;
+ else {
+ // DWARF doesn't specify if a DW_TAG_variable is a local, global
+ // or static variable, so we have to do a little digging:
+ // 1) DW_AT_linkage_name implies static lifetime (but may be missing)
+ // 2) An empty DW_AT_location is an (optimized-out) static lifetime var.
+ // 3) DW_AT_location containing a DW_OP_addr implies static lifetime.
+ // Clang likes to combine small global variables into the same symbol
+ // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
+ // so we need to look through the whole expression.
+ bool is_static_lifetime =
+ has_explicit_mangled ||
+ (has_explicit_location && !location.IsValid());
+ // Check if the location has a DW_OP_addr with any address value...
+ lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
+ if (!location_is_const_value_data) {
+ bool op_error = false;
+ location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
+ if (op_error) {
+ StreamString strm;
+ location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
+ NULL);
+ GetObjectFile()->GetModule()->ReportError(
+ "0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
+ die.GetTagAsCString(), strm.GetData());
+ }
+ if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
+ is_static_lifetime = true;
+ }
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+
+ if (is_static_lifetime) {
+ if (is_external)
+ scope = eValueTypeVariableGlobal;
+ else
+ scope = eValueTypeVariableStatic;
+
+ if (debug_map_symfile) {
+ // When leaving the DWARF in the .o files on darwin,
+ // when we have a global variable that wasn't initialized,
+ // the .o file might not have allocated a virtual
+ // address for the global variable. In this case it will
+ // have created a symbol for the global variable
+ // that is undefined/data and external and the value will
+ // be the byte size of the variable. When we do the
+ // address map in SymbolFileDWARFDebugMap we rely on
+ // having an address, we need to do some magic here
+ // so we can get the correct address for our global
+ // variable. The address for all of these entries
+ // will be zero, and there will be an undefined symbol
+ // in this object file, and the executable will have
+ // a matching symbol with a good address. So here we
+ // dig up the correct address and replace it in the
+ // location for the variable, and set the variable's
+ // symbol context scope to be that of the main executable
+ // so the file address will resolve correctly.
+ bool linked_oso_file_addr = false;
+ if (is_external && location_DW_OP_addr == 0) {
+ // we have a possible uninitialized extern global
+ ConstString const_name(mangled ? mangled : name);
+ ObjectFile *debug_map_objfile =
+ debug_map_symfile->GetObjectFile();
+ if (debug_map_objfile) {
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+ if (debug_map_symtab) {
+ Symbol *exe_symbol =
+ debug_map_symtab->FindFirstSymbolWithNameAndType(
+ const_name, eSymbolTypeData, Symtab::eDebugYes,
+ Symtab::eVisibilityExtern);
+ if (exe_symbol) {
+ if (exe_symbol->ValueIsAddress()) {
+ const addr_t exe_file_addr =
+ exe_symbol->GetAddressRef().GetFileAddress();
+ if (exe_file_addr != LLDB_INVALID_ADDRESS) {
+ if (location.Update_DW_OP_addr(exe_file_addr)) {
+ linked_oso_file_addr = true;
+ symbol_context_scope = exe_symbol;
+ }
+ }
}
- break;
-
- default:
- symbol_context_scope = sc.comp_unit;
- break;
+ }
}
+ }
}
- if (symbol_context_scope)
- {
- SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
-
- if (const_value.Form() && type_sp && type_sp->GetType())
- location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
-
- var_sp.reset (new Variable (die.GetID(),
- name,
- mangled,
- type_sp,
- scope,
- symbol_context_scope,
- scope_ranges,
- &decl,
- location,
- is_external,
- is_artificial,
- is_static_member));
-
- var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
- }
- else
- {
- // Not ready to parse this variable yet. It might be a global
- // or static variable that is in a function scope and the function
- // in the symbol context wasn't filled in yet
+ if (!linked_oso_file_addr) {
+ // The DW_OP_addr is not zero, but it contains a .o file address
+ // which
+ // needs to be linked up correctly.
+ const lldb::addr_t exe_file_addr =
+ debug_map_symfile->LinkOSOFileAddress(this,
+ location_DW_OP_addr);
+ if (exe_file_addr != LLDB_INVALID_ADDRESS) {
+ // Update the file address for this variable
+ location.Update_DW_OP_addr(exe_file_addr);
+ } else {
+ // Variable didn't make it into the final executable
return var_sp;
+ }
+ }
+ }
+ } else {
+ if (location_is_const_value_data)
+ scope = eValueTypeVariableStatic;
+ else {
+ scope = eValueTypeVariableLocal;
+ if (debug_map_symfile) {
+ // We need to check for TLS addresses that we need to fixup
+ if (location.ContainsThreadLocalStorage()) {
+ location.LinkThreadLocalStorage(
+ debug_map_symfile->GetObjectFile()->GetModule(),
+ [this, debug_map_symfile](
+ lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
+ return debug_map_symfile->LinkOSOFileAddress(
+ this, unlinked_file_addr);
+ });
+ scope = eValueTypeVariableThreadLocal;
+ }
}
+ }
+ }
+ }
+
+ if (symbol_context_scope == NULL) {
+ switch (parent_tag) {
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ if (sc.function) {
+ symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(
+ sc_parent_die.GetID());
+ if (symbol_context_scope == NULL)
+ symbol_context_scope = sc.function;
+ }
+ break;
+
+ default:
+ symbol_context_scope = sc.comp_unit;
+ break;
}
- // Cache var_sp even if NULL (the variable was just a specification or
- // was missing vital information to be able to be displayed in the debugger
- // (missing location due to optimization, etc)) so we don't re-parse
- // this DIE over and over later...
- GetDIEToVariable()[die.GetDIE()] = var_sp;
- if (spec_die)
- GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
+ }
+
+ if (symbol_context_scope) {
+ SymbolFileTypeSP type_sp(
+ new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
+
+ if (const_value.Form() && type_sp && type_sp->GetType())
+ location.CopyOpcodeData(const_value.Unsigned(),
+ type_sp->GetType()->GetByteSize(),
+ die.GetCU()->GetAddressByteSize());
+
+ var_sp.reset(new Variable(die.GetID(), name, mangled, type_sp, scope,
+ symbol_context_scope, scope_ranges, &decl,
+ location, is_external, is_artificial,
+ is_static_member));
+
+ var_sp->SetLocationIsConstantValueData(location_is_const_value_data);
+ } else {
+ // Not ready to parse this variable yet. It might be a global
+ // or static variable that is in a function scope and the function
+ // in the symbol context wasn't filled in yet
+ return var_sp;
+ }
}
- return var_sp;
+ // Cache var_sp even if NULL (the variable was just a specification or
+ // was missing vital information to be able to be displayed in the debugger
+ // (missing location due to optimization, etc)) so we don't re-parse
+ // this DIE over and over later...
+ GetDIEToVariable()[die.GetDIE()] = var_sp;
+ if (spec_die)
+ GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
+ }
+ return var_sp;
}
+DWARFDIE
+SymbolFileDWARF::FindBlockContainingSpecification(
+ const DIERef &func_die_ref, dw_offset_t spec_block_die_offset) {
+ // Give the concrete function die specified by "func_die_offset", find the
+ // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
+ // to "spec_block_die_offset"
+ return FindBlockContainingSpecification(DebugInfo()->GetDIE(func_die_ref),
+ spec_block_die_offset);
+}
DWARFDIE
-SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
- dw_offset_t spec_block_die_offset)
-{
- // Give the concrete function die specified by "func_die_offset", find the
+SymbolFileDWARF::FindBlockContainingSpecification(
+ const DWARFDIE &die, dw_offset_t spec_block_die_offset) {
+ if (die) {
+ switch (die.Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block: {
+ if (die.GetAttributeValueAsReference(
+ DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
+ return die;
+
+ if (die.GetAttributeValueAsReference(DW_AT_abstract_origin,
+ DW_INVALID_OFFSET) ==
+ spec_block_die_offset)
+ return die;
+ } break;
+ }
+
+ // Give the concrete function die specified by "func_die_offset", find the
// concrete block whose DW_AT_specification or DW_AT_abstract_origin points
// to "spec_block_die_offset"
- return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die;
+ child_die = child_die.GetSibling()) {
+ DWARFDIE result_die =
+ FindBlockContainingSpecification(child_die, spec_block_die_offset);
+ if (result_die)
+ return result_die;
+ }
+ }
+
+ return DWARFDIE();
}
+size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
+ const DWARFDIE &orig_die,
+ const lldb::addr_t func_low_pc,
+ bool parse_siblings, bool parse_children,
+ VariableList *cc_variable_list) {
+ if (!orig_die)
+ return 0;
-DWARFDIE
-SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
- dw_offset_t spec_block_die_offset)
-{
- if (die)
- {
- switch (die.Tag())
- {
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- {
- if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
- return die;
+ VariableListSP variable_list_sp;
+
+ size_t vars_added = 0;
+ DWARFDIE die = orig_die;
+ while (die) {
+ dw_tag_t tag = die.Tag();
+
+ // Check to see if we have already parsed this variable or constant?
+ VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
+ if (var_sp) {
+ if (cc_variable_list)
+ cc_variable_list->AddVariableIfUnique(var_sp);
+ } else {
+ // We haven't already parsed it, lets do that now.
+ if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
+ (tag == DW_TAG_formal_parameter && sc.function)) {
+ if (variable_list_sp.get() == NULL) {
+ DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
+ dw_tag_t parent_tag = sc_parent_die.Tag();
+ switch (parent_tag) {
+ case DW_TAG_compile_unit:
+ if (sc.comp_unit != NULL) {
+ variable_list_sp = sc.comp_unit->GetVariableList(false);
+ if (variable_list_sp.get() == NULL) {
+ variable_list_sp.reset(new VariableList());
+ sc.comp_unit->SetVariableList(variable_list_sp);
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportError(
+ "parent 0x%8.8" PRIx64 " %s with no valid compile unit in "
+ "symbol context for 0x%8.8" PRIx64
+ " %s.\n",
+ sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),
+ orig_die.GetID(), orig_die.GetTagAsCString());
+ }
+ break;
- if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
- return die;
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ if (sc.function != NULL) {
+ // Check to see if we already have parsed the variables for the
+ // given scope
+
+ Block *block = sc.function->GetBlock(true).FindBlockByID(
+ sc_parent_die.GetID());
+ if (block == NULL) {
+ // This must be a specification or abstract origin with
+ // a concrete block counterpart in the current function. We need
+ // to find the concrete block so we can correctly add the
+ // variable to it
+ const DWARFDIE concrete_block_die =
+ FindBlockContainingSpecification(
+ DIERef(sc.function->GetID(), this),
+ sc_parent_die.GetOffset());
+ if (concrete_block_die)
+ block = sc.function->GetBlock(true).FindBlockByID(
+ concrete_block_die.GetID());
+ }
+
+ if (block != NULL) {
+ const bool can_create = false;
+ variable_list_sp = block->GetBlockVariableList(can_create);
+ if (variable_list_sp.get() == NULL) {
+ variable_list_sp.reset(new VariableList());
+ block->SetVariableList(variable_list_sp);
+ }
+ }
}
break;
- }
- // Give the concrete function die specified by "func_die_offset", find the
- // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
- // to "spec_block_die_offset"
- for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
- {
- DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
- if (result_die)
- return result_die;
+ default:
+ GetObjectFile()->GetModule()->ReportError(
+ "didn't find appropriate parent DIE for variable list for "
+ "0x%8.8" PRIx64 " %s.\n",
+ orig_die.GetID(), orig_die.GetTagAsCString());
+ break;
+ }
}
- }
-
- return DWARFDIE();
-}
-
-size_t
-SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
- const DWARFDIE &orig_die,
- const lldb::addr_t func_low_pc,
- bool parse_siblings,
- bool parse_children,
- VariableList* cc_variable_list)
-{
- if (!orig_die)
- return 0;
- VariableListSP variable_list_sp;
-
- size_t vars_added = 0;
- DWARFDIE die = orig_die;
- while (die)
- {
- dw_tag_t tag = die.Tag();
-
- // Check to see if we have already parsed this variable or constant?
- VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
- if (var_sp)
- {
+ if (variable_list_sp) {
+ VariableSP var_sp(ParseVariableDIE(sc, die, func_low_pc));
+ if (var_sp) {
+ variable_list_sp->AddVariableIfUnique(var_sp);
if (cc_variable_list)
- cc_variable_list->AddVariableIfUnique (var_sp);
+ cc_variable_list->AddVariableIfUnique(var_sp);
+ ++vars_added;
+ }
}
- else
- {
- // We haven't already parsed it, lets do that now.
- if ((tag == DW_TAG_variable) ||
- (tag == DW_TAG_constant) ||
- (tag == DW_TAG_formal_parameter && sc.function))
- {
- if (variable_list_sp.get() == NULL)
- {
- DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
- dw_tag_t parent_tag = sc_parent_die.Tag();
- switch (parent_tag)
- {
- case DW_TAG_compile_unit:
- if (sc.comp_unit != NULL)
- {
- variable_list_sp = sc.comp_unit->GetVariableList(false);
- if (variable_list_sp.get() == NULL)
- {
- variable_list_sp.reset(new VariableList());
- sc.comp_unit->SetVariableList(variable_list_sp);
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
- sc_parent_die.GetID(),
- sc_parent_die.GetTagAsCString(),
- orig_die.GetID(),
- orig_die.GetTagAsCString());
- }
- break;
-
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- if (sc.function != NULL)
- {
- // Check to see if we already have parsed the variables for the given scope
-
- Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (block == NULL)
- {
- // This must be a specification or abstract origin with
- // a concrete block counterpart in the current function. We need
- // to find the concrete block so we can correctly add the
- // variable to it
- const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID(), this),
- sc_parent_die.GetOffset());
- if (concrete_block_die)
- block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
- }
-
- if (block != NULL)
- {
- const bool can_create = false;
- variable_list_sp = block->GetBlockVariableList (can_create);
- if (variable_list_sp.get() == NULL)
- {
- variable_list_sp.reset(new VariableList());
- block->SetVariableList(variable_list_sp);
- }
- }
- }
- break;
-
- default:
- GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
- orig_die.GetID(),
- orig_die.GetTagAsCString());
- break;
- }
- }
-
- if (variable_list_sp)
- {
- VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
- if (var_sp)
- {
- variable_list_sp->AddVariableIfUnique (var_sp);
- if (cc_variable_list)
- cc_variable_list->AddVariableIfUnique (var_sp);
- ++vars_added;
- }
- }
- }
- }
-
- bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
+ }
+ }
- if (!skip_children && parse_children && die.HasChildren())
- {
- vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
- }
+ bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
- if (parse_siblings)
- die = die.GetSibling();
- else
- die.Clear();
+ if (!skip_children && parse_children && die.HasChildren()) {
+ vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true,
+ true, cc_variable_list);
}
- return vars_added;
+
+ if (parse_siblings)
+ die = die.GetSibling();
+ else
+ die.Clear();
+ }
+ return vars_added;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-SymbolFileDWARF::GetPluginName()
-{
- return GetPluginNameStatic();
+ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
+
+void SymbolFileDWARF::DumpIndexes() {
+ StreamFile s(stdout, false);
+
+ s.Printf(
+ "DWARF index for (%s) '%s':",
+ GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
+ GetObjectFile()->GetFileSpec().GetPath().c_str());
+ s.Printf("\nFunction basenames:\n");
+ m_function_basename_index.Dump(&s);
+ s.Printf("\nFunction fullnames:\n");
+ m_function_fullname_index.Dump(&s);
+ s.Printf("\nFunction methods:\n");
+ m_function_method_index.Dump(&s);
+ s.Printf("\nFunction selectors:\n");
+ m_function_selector_index.Dump(&s);
+ s.Printf("\nObjective C class selectors:\n");
+ m_objc_class_selectors_index.Dump(&s);
+ s.Printf("\nGlobals and statics:\n");
+ m_global_index.Dump(&s);
+ s.Printf("\nTypes:\n");
+ m_type_index.Dump(&s);
+ s.Printf("\nNamespaces:\n");
+ m_namespace_index.Dump(&s);
}
-uint32_t
-SymbolFileDWARF::GetPluginVersion()
-{
- return 1;
-}
-
-void
-SymbolFileDWARF::DumpIndexes ()
-{
- StreamFile s(stdout, false);
-
- s.Printf ("DWARF index for (%s) '%s':",
- GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
- GetObjectFile()->GetFileSpec().GetPath().c_str());
- s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
- s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
- s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
- s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
- s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
- s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
- s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
- s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s);
-}
-
-
-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());
- if (module_sp)
- {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor)
- m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
- }
+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());
+ if (module_sp) {
+ SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
+ if (sym_vendor)
+ m_debug_map_symfile =
+ (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
}
- return m_debug_map_symfile;
+ }
+ return m_debug_map_symfile;
}
DWARFExpression::LocationListFormat
-SymbolFileDWARF::GetLocationListFormat() const
-{
- return DWARFExpression::RegularLocationList;
+SymbolFileDWARF::GetLocationListFormat() const {
+ return DWARFExpression::RegularLocationList;
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 865e58962700..52937697500f 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -22,20 +22,20 @@
// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/dwarf.h"
#include "lldb/Core/Flags.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Core/dwarf.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/DebugMacros.h"
-#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/lldb-private.h"
// Project includes
-#include "DWARFDefines.h"
#include "DWARFDataExtractor.h"
+#include "DWARFDefines.h"
#include "HashedNameToDIE.h"
#include "NameToDIE.h"
#include "UniqueDWARFASTType.h"
@@ -60,543 +60,465 @@ class DWARFFormValue;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARFDwo;
-#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
+#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
-class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID
-{
+class SymbolFileDWARF : public lldb_private::SymbolFile,
+ public lldb_private::UserID {
public:
- friend class SymbolFileDWARFDebugMap;
- friend class SymbolFileDWARFDwo;
- friend class DebugMapModule;
- friend struct DIERef;
- friend class DWARFCompileUnit;
- friend class DWARFDIE;
- friend class DWARFASTParserClang;
- friend class DWARFASTParserGo;
- friend class DWARFASTParserJava;
+ friend class SymbolFileDWARFDebugMap;
+ friend class SymbolFileDWARFDwo;
+ friend class DebugMapModule;
+ friend struct DIERef;
+ friend class DWARFCompileUnit;
+ friend class DWARFDIE;
+ friend class DWARFASTParserClang;
+ friend class DWARFASTParserGo;
+ friend class DWARFASTParserJava;
+ friend class DWARFASTParserOCaml;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ SymbolFileDWARF(lldb_private::ObjectFile *ofile);
- static void
- Terminate();
+ ~SymbolFileDWARF() override;
- static void
- DebuggerInitialize(lldb_private::Debugger &debugger);
+ uint32_t CalculateAbilities() override;
- static lldb_private::ConstString
- GetPluginNameStatic();
+ void InitializeObject() override;
- static const char *
- GetPluginDescriptionStatic();
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
- static lldb_private::SymbolFile*
- CreateInstance (lldb_private::ObjectFile* obj_file);
+ uint32_t GetNumCompileUnits() override;
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- SymbolFileDWARF(lldb_private::ObjectFile* ofile);
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
- ~SymbolFileDWARF() override;
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
- uint32_t
- CalculateAbilities () override;
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
- void
- InitializeObject() override;
+ bool
+ ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
- //------------------------------------------------------------------
- // Compile Unit function calls
- //------------------------------------------------------------------
+ bool ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
- uint32_t
- GetNumCompileUnits() override;
+ bool
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
- lldb::CompUnitSP
- ParseCompileUnitAtIndex(uint32_t index) override;
+ bool ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
- lldb::LanguageType
- ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc) override;
+ size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc) override;
+ size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override;
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitDebugMacros (const lldb_private::SymbolContext& sc) override;
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- bool
- ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc,
- lldb_private::FileSpecList& support_files) override;
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
- bool
- ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
+ lldb_private::Type *ResolveType(const DWARFDIE &die,
+ bool assert_not_being_parsed = true,
+ bool resolve_function_context = false);
- bool
- ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ SymbolFileDWARF *GetDWARFForUID(lldb::user_id_t uid);
- size_t
- ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
-
- size_t
- ParseTypes (const lldb_private::SymbolContext& sc) override;
-
- size_t
- ParseVariablesForContext (const lldb_private::SymbolContext& sc) override;
+ DWARFDIE
+ GetDIEFromUID(lldb::user_id_t uid);
- lldb_private::Type *
- ResolveTypeUID(lldb::user_id_t type_uid) override;
+ lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
- bool
- CompleteType (lldb_private::CompilerType& compiler_type) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
- lldb_private::Type *
- ResolveType (const DWARFDIE &die,
- bool assert_not_being_parsed = true,
- bool resolve_function_context = false);
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
- SymbolFileDWARF *
- GetDWARFForUID (lldb::user_id_t uid);
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
- DWARFDIE
- GetDIEFromUID (lldb::user_id_t uid);
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
- lldb_private::CompilerDecl
- GetDeclForUID (lldb::user_id_t uid) override;
+ uint32_t
+ ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
+ bool check_inlines, uint32_t resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUID (lldb::user_id_t uid) override;
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUID (lldb::user_id_t uid) override;
-
- void
- ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override;
-
+ uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- ResolveSymbolContext (const lldb_private::Address& so_addr,
- uint32_t resolve_scope,
- lldb_private::SymbolContext& sc) override;
+ 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;
- uint32_t
- ResolveSymbolContext (const lldb_private::FileSpec& file_spec,
- uint32_t line,
- bool check_inlines,
- uint32_t resolve_scope,
- 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
- FindGlobalVariables (const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append,
- uint32_t max_matches,
- lldb_private::VariableList& variables) override;
+ void GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) override;
- uint32_t
- FindGlobalVariables (const lldb_private::RegularExpression& regex,
- bool append,
- uint32_t max_matches,
- lldb_private::VariableList& variables) override;
+ uint32_t
+ FindTypes(const lldb_private::SymbolContext &sc,
+ 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;
- 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;
-
- uint32_t
- FindFunctions (const lldb_private::RegularExpression& regex,
- bool include_inlines,
- bool append,
- lldb_private::SymbolContextList& sc_list) override;
-
- void
- GetMangledNamesForFunction (const std::string &scope_qualified_name,
- std::vector<lldb_private::ConstString> &mangled_names) override;
-
- uint32_t
- FindTypes (const lldb_private::SymbolContext& sc,
- 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;
-
- size_t
- FindTypes (const std::vector<lldb_private::CompilerContext> &context,
- bool append,
- lldb_private::TypeMap& types) override;
+ size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
+ bool append, lldb_private::TypeMap &types) override;
- lldb_private::TypeList *
- GetTypeList () override;
+ lldb_private::TypeList *GetTypeList() override;
- size_t
- GetTypes (lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
- lldb_private::TypeList &type_list) override;
+ size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t 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;
+ 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;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- const lldb_private::DWARFDataExtractor& get_debug_abbrev_data ();
- 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 ();
- const lldb_private::DWARFDataExtractor& get_debug_line_data ();
- const lldb_private::DWARFDataExtractor& get_debug_macro_data ();
- const lldb_private::DWARFDataExtractor& get_debug_loc_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_apple_names_data ();
- const lldb_private::DWARFDataExtractor& get_apple_types_data ();
- const lldb_private::DWARFDataExtractor& get_apple_namespaces_data ();
- const lldb_private::DWARFDataExtractor& get_apple_objc_data ();
-
-
- DWARFDebugAbbrev*
- DebugAbbrev();
-
- const DWARFDebugAbbrev*
- DebugAbbrev() const;
-
- DWARFDebugInfo*
- DebugInfo();
-
- const DWARFDebugInfo*
- DebugInfo() const;
-
- DWARFDebugRanges*
- DebugRanges();
-
- const DWARFDebugRanges*
- DebugRanges() const;
-
- static bool
- SupportedVersion(uint16_t version);
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- DWARFDIE
- GetDeclContextDIEContainingDIE (const DWARFDIE &die);
+ uint32_t GetPluginVersion() override;
- bool
- HasForwardDeclForClangType (const lldb_private::CompilerType &compiler_type);
+ const lldb_private::DWARFDataExtractor &get_debug_abbrev_data();
+ 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();
+ const lldb_private::DWARFDataExtractor &get_debug_line_data();
+ const lldb_private::DWARFDataExtractor &get_debug_macro_data();
+ const lldb_private::DWARFDataExtractor &get_debug_loc_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_apple_names_data();
+ const lldb_private::DWARFDataExtractor &get_apple_types_data();
+ const lldb_private::DWARFDataExtractor &get_apple_namespaces_data();
+ const lldb_private::DWARFDataExtractor &get_apple_objc_data();
- lldb_private::CompileUnit*
- GetCompUnitForDWARFCompUnit(DWARFCompileUnit* dwarf_cu,
- uint32_t cu_idx = UINT32_MAX);
+ DWARFDebugAbbrev *DebugAbbrev();
- size_t
- GetObjCMethodDIEOffsets (lldb_private::ConstString class_name,
- DIEArray &method_die_offsets);
+ const DWARFDebugAbbrev *DebugAbbrev() const;
- bool
- Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu);
+ DWARFDebugInfo *DebugInfo();
- lldb_private::DebugMacrosSP
- ParseDebugMacros(lldb::offset_t *offset);
+ const DWARFDebugInfo *DebugInfo() const;
- static DWARFDIE
- GetParentSymbolContextDIE(const DWARFDIE &die);
+ DWARFDebugRanges *DebugRanges();
- virtual lldb::CompUnitSP
- ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx);
+ const DWARFDebugRanges *DebugRanges() const;
- virtual lldb_private::DWARFExpression::LocationListFormat
- GetLocationListFormat() const;
+ static bool SupportedVersion(uint16_t version);
- lldb::ModuleSP
- GetDWOModule (lldb_private::ConstString name);
+ DWARFDIE
+ GetDeclContextDIEContainingDIE(const DWARFDIE &die);
- virtual DWARFDIE
- GetDIE(const DIERef &die_ref);
+ bool
+ HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type);
- virtual std::unique_ptr<SymbolFileDWARFDwo>
- GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die);
+ lldb_private::CompileUnit *
+ GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx = UINT32_MAX);
+
+ size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
+ DIEArray &method_die_offsets);
+
+ bool Supports_DW_AT_APPLE_objc_complete_type(DWARFCompileUnit *cu);
+
+ lldb_private::DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset);
+
+ static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
+
+ virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx);
+
+ virtual lldb_private::DWARFExpression::LocationListFormat
+ GetLocationListFormat() const;
+
+ lldb::ModuleSP GetDWOModule(lldb_private::ConstString name);
+
+ virtual DWARFDIE GetDIE(const DIERef &die_ref);
+
+ virtual std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu,
+ const DWARFDebugInfoEntry &cu_die);
protected:
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::opaque_compiler_type_t> DIEToClangType;
- typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
-
- struct DWARFDataSegment
- {
- std::once_flag m_flag;
- lldb_private::DWARFDataExtractor m_data;
- };
-
- DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF);
-
- const lldb_private::DWARFDataExtractor&
- GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment);
-
- virtual void
- LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data);
-
- bool
- DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx);
-
- bool
- DIEInDeclContext (const lldb_private::CompilerDeclContext *parent_decl_ctx,
- const DWARFDIE &die);
-
- virtual DWARFCompileUnit*
- GetDWARFCompileUnit (lldb_private::CompileUnit *comp_unit);
-
- DWARFCompileUnit*
- GetNextUnparsedDWARFCompileUnit (DWARFCompileUnit* prev_cu);
-
- bool
- GetFunction (const DWARFDIE &die,
- lldb_private::SymbolContext& sc);
-
- lldb_private::Function *
- ParseCompileUnitFunction (const lldb_private::SymbolContext& sc,
- 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
- ParseTypes (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- bool parse_siblings,
- bool parse_children);
-
- lldb::TypeSP
- ParseType (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- bool *type_is_new);
-
- lldb_private::Type *
- ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed);
-
- lldb_private::Type *
- ResolveTypeUID(const DIERef &die_ref);
-
- lldb::VariableSP
- ParseVariableDIE(const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- const lldb::addr_t func_low_pc);
-
- size_t
- ParseVariables (const lldb_private::SymbolContext& sc,
- const DWARFDIE &orig_die,
- const lldb::addr_t func_low_pc,
- bool parse_siblings,
- bool parse_children,
- lldb_private::VariableList* cc_variable_list = NULL);
-
- bool
- ClassOrStructIsVirtual (const DWARFDIE &die);
-
- // Given a die_offset, figure out the symbol context representing that die.
- bool
- ResolveFunction (const DIERef& die_ref,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
+ DIEToTypePtr;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
+ DIEToVariableSP;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
+ lldb::opaque_compiler_type_t>
+ DIEToClangType;
+ typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
+
+ struct DWARFDataSegment {
+ std::once_flag m_flag;
+ lldb_private::DWARFDataExtractor m_data;
+ };
+
+ DISALLOW_COPY_AND_ASSIGN(SymbolFileDWARF);
+
+ const lldb_private::DWARFDataExtractor &
+ GetCachedSectionData(lldb::SectionType sect_type,
+ DWARFDataSegment &data_segment);
+
+ virtual void LoadSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data);
- bool
- ResolveFunction (const DWARFDIE &die,
+ bool DeclContextMatchesThisSymbolFile(
+ const lldb_private::CompilerDeclContext *decl_ctx);
+
+ bool
+ DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const DWARFDIE &die);
+
+ virtual DWARFCompileUnit *
+ GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
+
+ DWARFCompileUnit *GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit *prev_cu);
+
+ bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc);
+
+ lldb_private::Function *
+ ParseCompileUnitFunction(const lldb_private::SymbolContext &sc,
+ 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 ParseTypes(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ bool parse_siblings, bool parse_children);
+
+ lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die, bool *type_is_new);
+
+ lldb_private::Type *ResolveTypeUID(const DWARFDIE &die,
+ bool assert_not_being_parsed);
+
+ lldb_private::Type *ResolveTypeUID(const DIERef &die_ref);
+
+ lldb::VariableSP ParseVariableDIE(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die,
+ const lldb::addr_t func_low_pc);
+
+ size_t ParseVariables(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &orig_die,
+ const lldb::addr_t func_low_pc, bool parse_siblings,
+ bool parse_children,
+ lldb_private::VariableList *cc_variable_list = NULL);
+
+ bool ClassOrStructIsVirtual(const DWARFDIE &die);
+
+ // Given a die_offset, figure out the symbol context representing that die.
+ bool ResolveFunction(const DIERef &die_ref, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ bool ResolveFunction(const DWARFDIE &die, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ void FindFunctions(const lldb_private::ConstString &name,
+ const NameToDIE &name_to_die, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ const NameToDIE &name_to_die, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ const DWARFMappedHash::MemoryTable &memory_table,
bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- void
- FindFunctions(const lldb_private::ConstString &name,
- const NameToDIE &name_to_die,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- void
- FindFunctions (const lldb_private::RegularExpression &regex,
- const NameToDIE &name_to_die,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- void
- FindFunctions (const lldb_private::RegularExpression &regex,
- const DWARFMappedHash::MemoryTable &memory_table,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- virtual lldb::TypeSP
- FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
-
- lldb::TypeSP
- FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const lldb_private::ConstString &type_name,
- bool must_be_implementation);
-
- lldb::TypeSP
- FindCompleteObjCDefinitionType (const lldb_private::ConstString &type_name,
- bool header_definition_ok);
-
- lldb_private::Symbol *
- GetObjCClassSymbol (const lldb_private::ConstString &objc_class_name);
-
- void
- ParseFunctions (const DIEArray &die_offsets,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- lldb::TypeSP
- GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context = false);
-
- void
- Index();
-
- void
- DumpIndexes();
-
- void
- SetDebugMapModule (const lldb::ModuleSP &module_sp)
- {
- m_debug_map_module_wp = module_sp;
- }
-
- SymbolFileDWARFDebugMap *
- GetDebugMapSymfile ();
-
- DWARFDIE
- FindBlockContainingSpecification (const DIERef& func_die_ref, dw_offset_t spec_block_die_offset);
-
- DWARFDIE
- FindBlockContainingSpecification (const DWARFDIE &die, dw_offset_t spec_block_die_offset);
-
- virtual UniqueDWARFASTTypeMap &
- GetUniqueDWARFASTTypeMap ();
-
- bool
- DIEDeclContextsMatch (const DWARFDIE &die1,
- const DWARFDIE &die2);
-
- bool
- ClassContainsSelector (const DWARFDIE &class_die,
- const lldb_private::ConstString &selector);
-
- bool
- FixupAddress (lldb_private::Address &addr);
-
- typedef std::set<lldb_private::Type *> TypeSet;
-
- typedef std::map<lldb_private::ConstString, lldb::ModuleSP> ExternalTypeModuleMap;
-
- void
- GetTypes (const DWARFDIE &die,
- dw_offset_t min_die_offset,
- dw_offset_t max_die_offset,
- uint32_t type_mask,
- TypeSet &type_set);
-
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb_private::Variable *> GlobalVariableMap;
-
- GlobalVariableMap &
- GetGlobalAranges();
-
- void
- UpdateExternalModuleListIfNeeded();
-
- virtual DIEToTypePtr&
- GetDIEToType() { return m_die_to_type; }
-
- virtual DIEToVariableSP&
- GetDIEToVariable() { return m_die_to_variable_sp; }
-
- virtual DIEToClangType&
- GetForwardDeclDieToClangType() { return m_forward_decl_die_to_clang_type; }
-
- virtual ClangTypeToDIE&
- GetForwardDeclClangTypeToDie() { return m_forward_decl_clang_type_to_die; }
-
- lldb::ModuleWP m_debug_map_module_wp;
- SymbolFileDWARFDebugMap * m_debug_map_symfile;
- lldb_private::DWARFDataExtractor m_dwarf_data;
-
- DWARFDataSegment m_data_debug_abbrev;
- DWARFDataSegment m_data_debug_addr;
- DWARFDataSegment m_data_debug_aranges;
- DWARFDataSegment m_data_debug_frame;
- DWARFDataSegment m_data_debug_info;
- DWARFDataSegment m_data_debug_line;
- DWARFDataSegment m_data_debug_macro;
- DWARFDataSegment m_data_debug_loc;
- DWARFDataSegment m_data_debug_ranges;
- DWARFDataSegment m_data_debug_str;
- DWARFDataSegment m_data_debug_str_offsets;
- DWARFDataSegment m_data_apple_names;
- DWARFDataSegment m_data_apple_types;
- DWARFDataSegment m_data_apple_namespaces;
- DWARFDataSegment m_data_apple_objc;
-
- // The unique pointer items below are generated on demand if and when someone accesses
- // them through a non const version of this class.
- std::unique_ptr<DWARFDebugAbbrev> m_abbr;
- std::unique_ptr<DWARFDebugInfo> m_info;
- std::unique_ptr<DWARFDebugLine> m_line;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
- std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
-
- typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP> DebugMacrosMap;
- DebugMacrosMap m_debug_macros_map;
-
- ExternalTypeModuleMap m_external_type_modules;
- NameToDIE m_function_basename_index; // All concrete functions
- NameToDIE m_function_fullname_index; // All concrete functions
- NameToDIE m_function_method_index; // All inlined functions
- NameToDIE m_function_selector_index; // All method names for functions of classes
- NameToDIE m_objc_class_selectors_index; // Given a class name, find all selectors for the class
- NameToDIE m_global_index; // Global and static variables
- NameToDIE m_type_index; // All type DIE offsets
- NameToDIE m_namespace_index; // All type DIE offsets
- bool m_indexed:1,
- m_using_apple_tables:1,
- m_fetched_external_modules:1;
- lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
-
- 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;
- UniqueDWARFASTTypeMap m_unique_ast_type_map;
- DIEToTypePtr m_die_to_type;
- DIEToVariableSP m_die_to_variable_sp;
- DIEToClangType m_forward_decl_die_to_clang_type;
- ClangTypeToDIE m_forward_decl_clang_type_to_die;
+ lldb_private::SymbolContextList &sc_list);
+
+ virtual lldb::TypeSP
+ FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
+
+ lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation);
+
+ lldb::TypeSP
+ FindCompleteObjCDefinitionType(const lldb_private::ConstString &type_name,
+ bool header_definition_ok);
+
+ lldb_private::Symbol *
+ GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
+
+ void ParseFunctions(const DIEArray &die_offsets, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ lldb::TypeSP GetTypeForDIE(const DWARFDIE &die,
+ bool resolve_function_context = false);
+
+ void Index();
+
+ void DumpIndexes();
+
+ void SetDebugMapModule(const lldb::ModuleSP &module_sp) {
+ m_debug_map_module_wp = module_sp;
+ }
+
+ SymbolFileDWARFDebugMap *GetDebugMapSymfile();
+
+ DWARFDIE
+ FindBlockContainingSpecification(const DIERef &func_die_ref,
+ dw_offset_t spec_block_die_offset);
+
+ DWARFDIE
+ FindBlockContainingSpecification(const DWARFDIE &die,
+ dw_offset_t spec_block_die_offset);
+
+ virtual UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap();
+
+ bool DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2);
+
+ bool ClassContainsSelector(const DWARFDIE &class_die,
+ const lldb_private::ConstString &selector);
+
+ bool FixupAddress(lldb_private::Address &addr);
+
+ typedef std::set<lldb_private::Type *> TypeSet;
+
+ typedef std::map<lldb_private::ConstString, lldb::ModuleSP>
+ ExternalTypeModuleMap;
+
+ void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
+ dw_offset_t max_die_offset, uint32_t type_mask,
+ TypeSet &type_set);
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
+ lldb_private::Variable *>
+ GlobalVariableMap;
+
+ GlobalVariableMap &GetGlobalAranges();
+
+ void UpdateExternalModuleListIfNeeded();
+
+ virtual DIEToTypePtr &GetDIEToType() { return m_die_to_type; }
+
+ virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; }
+
+ virtual DIEToClangType &GetForwardDeclDieToClangType() {
+ return m_forward_decl_die_to_clang_type;
+ }
+
+ virtual ClangTypeToDIE &GetForwardDeclClangTypeToDie() {
+ return m_forward_decl_clang_type_to_die;
+ }
+
+ lldb::ModuleWP m_debug_map_module_wp;
+ SymbolFileDWARFDebugMap *m_debug_map_symfile;
+ lldb_private::DWARFDataExtractor m_dwarf_data;
+
+ DWARFDataSegment m_data_debug_abbrev;
+ DWARFDataSegment m_data_debug_addr;
+ DWARFDataSegment m_data_debug_aranges;
+ DWARFDataSegment m_data_debug_frame;
+ DWARFDataSegment m_data_debug_info;
+ DWARFDataSegment m_data_debug_line;
+ DWARFDataSegment m_data_debug_macro;
+ DWARFDataSegment m_data_debug_loc;
+ DWARFDataSegment m_data_debug_ranges;
+ DWARFDataSegment m_data_debug_str;
+ DWARFDataSegment m_data_debug_str_offsets;
+ DWARFDataSegment m_data_apple_names;
+ DWARFDataSegment m_data_apple_types;
+ DWARFDataSegment m_data_apple_namespaces;
+ DWARFDataSegment m_data_apple_objc;
+
+ // The unique pointer items below are generated on demand if and when someone
+ // accesses
+ // them through a non const version of this class.
+ std::unique_ptr<DWARFDebugAbbrev> m_abbr;
+ std::unique_ptr<DWARFDebugInfo> m_info;
+ std::unique_ptr<DWARFDebugLine> m_line;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
+ std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
+
+ typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
+ DebugMacrosMap;
+ DebugMacrosMap m_debug_macros_map;
+
+ ExternalTypeModuleMap m_external_type_modules;
+ NameToDIE m_function_basename_index; // All concrete functions
+ NameToDIE m_function_fullname_index; // All concrete functions
+ NameToDIE m_function_method_index; // All inlined functions
+ NameToDIE
+ m_function_selector_index; // All method names for functions of classes
+ NameToDIE m_objc_class_selectors_index; // Given a class name, find all
+ // selectors for the class
+ NameToDIE m_global_index; // Global and static variables
+ NameToDIE m_type_index; // All type DIE offsets
+ NameToDIE m_namespace_index; // All type DIE offsets
+ bool m_indexed : 1, m_using_apple_tables : 1, m_fetched_external_modules : 1;
+ lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+
+ 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;
+ UniqueDWARFASTTypeMap m_unique_ast_type_map;
+ DIEToTypePtr m_die_to_type;
+ DIEToVariableSP m_die_to_variable_sp;
+ DIEToClangType m_forward_decl_die_to_clang_type;
+ ClangTypeToDIE m_forward_decl_clang_type_to_die;
};
-#endif // SymbolFileDWARF_SymbolFileDWARF_h_
+#endif // SymbolFileDWARF_SymbolFileDWARF_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index ca819624c715..567ac88fdf07 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -15,12 +15,13 @@
#include "DWARFDebugAranges.h"
-#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
#if defined(DEBUG_OSO_DMAP)
@@ -34,6 +35,7 @@
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/VariableList.h"
+#include "llvm/Support/ScopedPrinter.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
@@ -41,1550 +43,1399 @@
using namespace lldb;
using namespace lldb_private;
-// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
-// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
+// Subclass lldb_private::Module so we can intercept the
+// "Module::GetObjectFile()"
+// (so we can fixup the object file sections) and also for
+// "Module::GetSymbolVendor()"
// (so we can fixup the symbol file id.
const SymbolFileDWARFDebugMap::FileRangeMap &
-SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
-{
- if (file_range_map_valid)
- return file_range_map;
-
- file_range_map_valid = true;
-
- Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
- if (!oso_module)
- return file_range_map;
-
- ObjectFile *oso_objfile = oso_module->GetObjectFile();
- if (!oso_objfile)
- return file_range_map;
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- {
- ConstString object_name (oso_module->GetObjectName());
- log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
- static_cast<void*>(this),
- oso_module->GetSpecificationDescription().c_str());
- }
-
- std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
- if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
- {
- for (auto comp_unit_info : cu_infos)
- {
- Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
- ModuleSP oso_module_sp (oso_objfile->GetModule());
- Symtab *oso_symtab = oso_objfile->GetSymtab();
-
- ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
- //SectionList *oso_sections = oso_objfile->Sections();
- // Now we need to make sections that map from zero based object
- // file addresses to where things ended up in the main executable.
-
- assert (comp_unit_info->first_symbol_index != UINT32_MAX);
- // End index is one past the last valid symbol index
- 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)
- {
- Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
- if (exe_symbol)
- {
- if (exe_symbol->IsDebug() == false)
- continue;
-
- switch (exe_symbol->GetType())
- {
- default:
- break;
-
- case eSymbolTypeCode:
- {
- // For each N_FUN, or function that we run into in the debug map
- // we make a new section that we add to the sections found in the
- // .o file. This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable.
-
- // First we find the original symbol in the .o file's symbol table
- Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
- eSymbolTypeCode,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
- if (oso_fun_symbol)
- {
- // Add the inverse OSO file address to debug map entry mapping
- exe_symfile->AddOSOFileRange (this,
- exe_symbol->GetAddressRef().GetFileAddress(),
- exe_symbol->GetByteSize(),
- oso_fun_symbol->GetAddressRef().GetFileAddress(),
- oso_fun_symbol->GetByteSize());
-
- }
- }
- break;
-
- case eSymbolTypeData:
- {
- // For each N_GSYM we remap the address for the global by making
- // a new section that we add to the sections found in the .o file.
- // This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable. We
- // initially set the section size to be 1 byte, but will need to
- // fix up these addresses further after all globals have been
- // parsed to span the gaps, or we can find the global variable
- // sizes from the DWARF info as we are parsing.
-
- // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
- Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
- eSymbolTypeData,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
- if (exe_symbol && oso_gsym_symbol &&
- exe_symbol->ValueIsAddress() &&
- oso_gsym_symbol->ValueIsAddress())
- {
- // Add the inverse OSO file address to debug map entry mapping
- exe_symfile->AddOSOFileRange (this,
- exe_symbol->GetAddressRef().GetFileAddress(),
- exe_symbol->GetByteSize(),
- oso_gsym_symbol->GetAddressRef().GetFileAddress(),
- oso_gsym_symbol->GetByteSize());
- }
- }
- break;
- }
- }
- }
-
- exe_symfile->FinalizeOSOFileRanges (this);
- // We don't need the symbols anymore for the .o files
- oso_objfile->ClearSymtab();
- }
- }
+SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
+ SymbolFileDWARFDebugMap *exe_symfile) {
+ if (file_range_map_valid)
return file_range_map;
-}
-class DebugMapModule : public Module
-{
-public:
- DebugMapModule (const ModuleSP &exe_module_sp,
- uint32_t cu_idx,
- const FileSpec& file_spec,
- const ArchSpec& arch,
- const ConstString *object_name,
- off_t object_offset,
- const TimeValue *object_mod_time_ptr) :
- Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
- m_exe_module_wp (exe_module_sp),
- m_cu_idx (cu_idx)
- {
- }
+ file_range_map_valid = true;
- ~DebugMapModule() override = default;
-
- SymbolVendor*
- GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override
- {
- // Scope for locker
- if (m_symfile_ap.get() || can_create == false)
- return m_symfile_ap.get();
-
- ModuleSP exe_module_sp (m_exe_module_wp.lock());
- if (exe_module_sp)
- {
- // Now get the object file outside of a locking scope
- ObjectFile *oso_objfile = GetObjectFile ();
- if (oso_objfile)
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
- if (symbol_vendor)
- {
- // Set a pointer to this class to set our OSO DWARF file know
- // that the DWARF is being used along with a debug map and that
- // it will have the remapped sections that we do below.
- SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
-
- if (!oso_symfile)
- return NULL;
-
- ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
- SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
-
- if (exe_objfile && exe_sym_vendor)
- {
- oso_symfile->SetDebugMapModule(exe_module_sp);
- // Set the ID of the symbol file DWARF to the index of the OSO
- // shifted left by 32 bits to provide a unique prefix for any
- // UserID's that get created in the symbol file.
- oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
- }
- return symbol_vendor;
- }
- }
- }
- return NULL;
- }
+ Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this);
+ if (!oso_module)
+ return file_range_map;
-protected:
- ModuleWP m_exe_module_wp;
- const uint32_t m_cu_idx;
-};
+ ObjectFile *oso_objfile = oso_module->GetObjectFile();
+ if (!oso_objfile)
+ return file_range_map;
-void
-SymbolFileDWARFDebugMap::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-SymbolFileDWARFDebugMap::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-lldb_private::ConstString
-SymbolFileDWARFDebugMap::GetPluginNameStatic()
-{
- static ConstString g_name("dwarf-debugmap");
- return g_name;
-}
-
-const char *
-SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
-{
- return "DWARF and DWARF3 debug symbol file reader (debug map).";
-}
-
-SymbolFile*
-SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
-{
- return new SymbolFileDWARFDebugMap (obj_file);
-}
-
-SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
- SymbolFile(ofile),
- m_flags(),
- m_compile_unit_infos(),
- m_func_indexes(),
- m_glob_indexes(),
- m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
-{
-}
-
-SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
-{
-}
-
-void
-SymbolFileDWARFDebugMap::InitializeObject()
-{
-}
-
-void
-SymbolFileDWARFDebugMap::InitOSO()
-{
- if (m_flags.test(kHaveInitializedOSOs))
- return;
-
- m_flags.set(kHaveInitializedOSOs);
-
- // If the object file has been stripped, there is no sense in looking further
- // as all of the debug symbols for the debug map will not be available
- if (m_obj_file->IsStripped())
- return;
-
- // Also make sure the file type is some sort of executable. Core files, debug
- // info files (dSYM), object files (.o files), and stub libraries all can
- switch (m_obj_file->GetType())
- {
- case ObjectFile::eTypeInvalid:
- case ObjectFile::eTypeCoreFile:
- case ObjectFile::eTypeDebugInfo:
- case ObjectFile::eTypeObjectFile:
- case ObjectFile::eTypeStubLibrary:
- case ObjectFile::eTypeUnknown:
- case ObjectFile::eTypeJIT:
- return;
-
- case ObjectFile::eTypeExecutable:
- case ObjectFile::eTypeDynamicLinker:
- case ObjectFile::eTypeSharedLibrary:
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ if (log) {
+ ConstString object_name(oso_module->GetObjectName());
+ log->Printf(
+ "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
+ static_cast<void *>(this),
+ oso_module->GetSpecificationDescription().c_str());
+ }
+
+ std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
+ if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
+ for (auto comp_unit_info : cu_infos) {
+ Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
+ ModuleSP oso_module_sp(oso_objfile->GetModule());
+ Symtab *oso_symtab = oso_objfile->GetSymtab();
+
+ /// const uint32_t fun_resolve_flags = SymbolContext::Module |
+ /// eSymbolContextCompUnit | eSymbolContextFunction;
+ // SectionList *oso_sections = oso_objfile->Sections();
+ // Now we need to make sections that map from zero based object
+ // file addresses to where things ended up in the main executable.
+
+ assert(comp_unit_info->first_symbol_index != UINT32_MAX);
+ // End index is one past the last valid symbol index
+ 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) {
+ Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+ if (exe_symbol) {
+ if (exe_symbol->IsDebug() == false)
+ continue;
+
+ switch (exe_symbol->GetType()) {
+ default:
break;
- }
- // In order to get the abilities of this plug-in, we look at the list of
- // N_OSO entries (object files) from the symbol table and make sure that
- // these files exist and also contain valid DWARF. If we get any of that
- // then we return the abilities of the first N_OSO's DWARF.
-
- Symtab* symtab = m_obj_file->GetSymtab();
- if (symtab)
- {
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
-
- std::vector<uint32_t> oso_indexes;
- // When a mach-o symbol is encoded, the n_type field is encoded in bits
- // 23:16, and the n_desc field is encoded in bits 15:0.
- //
- // To find all N_OSO entries that are part of the DWARF + debug map
- // we find only object file symbols with the flags value as follows:
- // bits 23:16 == 0x66 (N_OSO)
- // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
- const uint32_t k_oso_symbol_flags_value = 0x660001u;
-
- const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
-
- if (oso_index_count > 0)
- {
- symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
- symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
-
- symtab->SortSymbolIndexesByValue(m_func_indexes, true);
- symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
-
- for (uint32_t sym_idx : m_func_indexes)
- {
- const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
- lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
- lldb::addr_t byte_size = symbol->GetByteSize();
- DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
- m_debug_map.Append(debug_map_entry);
- }
- for (uint32_t sym_idx : m_glob_indexes)
- {
- const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
- lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
- lldb::addr_t byte_size = symbol->GetByteSize();
- DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
- m_debug_map.Append(debug_map_entry);
+ case eSymbolTypeCode: {
+ // For each N_FUN, or function that we run into in the debug map
+ // we make a new section that we add to the sections found in the
+ // .o file. This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable.
+
+ // First we find the original symbol in the .o file's symbol table
+ Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(
+ exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled),
+ eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
+ if (oso_fun_symbol) {
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange(
+ this, exe_symbol->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
+ oso_fun_symbol->GetAddressRef().GetFileAddress(),
+ oso_fun_symbol->GetByteSize());
}
- m_debug_map.Sort();
-
- m_compile_unit_infos.resize(oso_index_count);
-
- for (uint32_t i=0; i<oso_index_count; ++i)
- {
- const uint32_t so_idx = oso_indexes[i] - 1;
- const uint32_t oso_idx = oso_indexes[i];
- const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
- const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
- if (so_symbol &&
- oso_symbol &&
- so_symbol->GetType() == eSymbolTypeSourceFile &&
- oso_symbol->GetType() == eSymbolTypeObjectFile)
- {
- m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
- m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
- TimeValue oso_mod_time;
- oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
- m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
- uint32_t sibling_idx = so_symbol->GetSiblingIndex();
- // The sibling index can't be less that or equal to the current index "i"
- if (sibling_idx == UINT32_MAX)
- {
- m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
- }
- else
- {
- const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
- m_compile_unit_infos[i].first_symbol_index = so_idx;
- m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
- m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
- m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
-
- if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
- }
- }
- else
- {
- if (oso_symbol == NULL)
- m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
- else if (so_symbol == NULL)
- m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
- else if (so_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
- else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
- }
+ } break;
+
+ case eSymbolTypeData: {
+ // For each N_GSYM we remap the address for the global by making
+ // a new section that we add to the sections found in the .o file.
+ // This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable. We
+ // initially set the section size to be 1 byte, but will need to
+ // fix up these addresses further after all globals have been
+ // parsed to span the gaps, or we can find the global variable
+ // sizes from the DWARF info as we are parsing.
+
+ // Next we find the non-stab entry that corresponds to the N_GSYM in
+ // the .o file
+ Symbol *oso_gsym_symbol =
+ oso_symtab->FindFirstSymbolWithNameAndType(
+ exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled),
+ eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny);
+ if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() &&
+ oso_gsym_symbol->ValueIsAddress()) {
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange(
+ this, exe_symbol->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
+ oso_gsym_symbol->GetAddressRef().GetFileAddress(),
+ oso_gsym_symbol->GetByteSize());
}
+ } break;
+ }
}
+ }
+
+ exe_symfile->FinalizeOSOFileRanges(this);
+ // We don't need the symbols anymore for the .o files
+ oso_objfile->ClearSymtab();
}
+ }
+ return file_range_map;
}
-Module *
-SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
-{
- const uint32_t cu_count = GetNumCompileUnits();
- if (oso_idx < cu_count)
- return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
+class DebugMapModule : public Module {
+public:
+ DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
+ const FileSpec &file_spec, const ArchSpec &arch,
+ const ConstString *object_name, off_t object_offset,
+ const llvm::sys::TimePoint<> object_mod_time)
+ : Module(file_spec, arch, object_name, object_offset, object_mod_time),
+ m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {}
+
+ ~DebugMapModule() override = default;
+
+ SymbolVendor *
+ GetSymbolVendor(bool can_create = true,
+ lldb_private::Stream *feedback_strm = NULL) override {
+ // Scope for locker
+ if (m_symfile_ap.get() || can_create == false)
+ return m_symfile_ap.get();
+
+ ModuleSP exe_module_sp(m_exe_module_wp.lock());
+ if (exe_module_sp) {
+ // Now get the object file outside of a locking scope
+ ObjectFile *oso_objfile = GetObjectFile();
+ if (oso_objfile) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ SymbolVendor *symbol_vendor =
+ Module::GetSymbolVendor(can_create, feedback_strm);
+ if (symbol_vendor) {
+ // Set a pointer to this class to set our OSO DWARF file know
+ // that the DWARF is being used along with a debug map and that
+ // it will have the remapped sections that we do below.
+ SymbolFileDWARF *oso_symfile =
+ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
+ symbol_vendor->GetSymbolFile());
+
+ if (!oso_symfile)
+ return NULL;
+
+ ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
+ SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
+
+ if (exe_objfile && exe_sym_vendor) {
+ oso_symfile->SetDebugMapModule(exe_module_sp);
+ // Set the ID of the symbol file DWARF to the index of the OSO
+ // shifted left by 32 bits to provide a unique prefix for any
+ // UserID's that get created in the symbol file.
+ oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
+ }
+ return symbol_vendor;
+ }
+ }
+ }
return NULL;
-}
+ }
-Module *
-SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
-{
- if (!comp_unit_info->oso_sp)
- {
- auto pos = m_oso_map.find (comp_unit_info->oso_path);
- if (pos != m_oso_map.end())
- {
- comp_unit_info->oso_sp = pos->second;
- }
- else
- {
- ObjectFile *obj_file = GetObjectFile();
- comp_unit_info->oso_sp.reset (new OSOInfo());
- m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
- const char *oso_path = comp_unit_info->oso_path.GetCString();
- FileSpec oso_file (oso_path, false);
- ConstString oso_object;
- if (oso_file.Exists())
- {
- TimeValue oso_mod_time (oso_file.GetModificationTime());
- if (oso_mod_time != comp_unit_info->oso_mod_time)
- {
- obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored",
- oso_file.GetPath().c_str(),
- oso_mod_time.GetAsSecondsSinceJan1_1970(),
- comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
- return NULL;
- }
+protected:
+ ModuleWP m_exe_module_wp;
+ const uint32_t m_cu_idx;
+};
- }
- else
- {
- const bool must_exist = true;
-
- if (!ObjectFile::SplitArchivePathWithObject (oso_path,
- oso_file,
- oso_object,
- must_exist))
- {
- return NULL;
- }
- }
- // Always create a new module for .o files. Why? Because we
- // use the debug map, to add new sections to each .o file and
- // even though a .o file might not have changed, the sections
- // that get added to the .o file can change.
- ArchSpec oso_arch;
- // Only adopt the architecture from the module (not the vendor or OS)
- // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx"
- // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
- // load command...
- oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str());
- comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
- GetCompUnitInfoIndex(comp_unit_info),
- oso_file,
- oso_arch,
- oso_object ? &oso_object : NULL,
- 0,
- oso_object ? &comp_unit_info->oso_mod_time : NULL));
+void SymbolFileDWARFDebugMap::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void SymbolFileDWARFDebugMap::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() {
+ static ConstString g_name("dwarf-debugmap");
+ return g_name;
+}
+
+const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
+ return "DWARF and DWARF3 debug symbol file reader (debug map).";
+}
+
+SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileDWARFDebugMap(obj_file);
+}
+
+SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
+ : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
+ m_glob_indexes(),
+ m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
+
+SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
+
+void SymbolFileDWARFDebugMap::InitializeObject() {}
+
+void SymbolFileDWARFDebugMap::InitOSO() {
+ if (m_flags.test(kHaveInitializedOSOs))
+ return;
+
+ m_flags.set(kHaveInitializedOSOs);
+
+ // If the object file has been stripped, there is no sense in looking further
+ // as all of the debug symbols for the debug map will not be available
+ if (m_obj_file->IsStripped())
+ return;
+
+ // Also make sure the file type is some sort of executable. Core files, debug
+ // info files (dSYM), object files (.o files), and stub libraries all can
+ switch (m_obj_file->GetType()) {
+ case ObjectFile::eTypeInvalid:
+ case ObjectFile::eTypeCoreFile:
+ case ObjectFile::eTypeDebugInfo:
+ case ObjectFile::eTypeObjectFile:
+ case ObjectFile::eTypeStubLibrary:
+ case ObjectFile::eTypeUnknown:
+ case ObjectFile::eTypeJIT:
+ return;
+
+ case ObjectFile::eTypeExecutable:
+ case ObjectFile::eTypeDynamicLinker:
+ case ObjectFile::eTypeSharedLibrary:
+ break;
+ }
+
+ // In order to get the abilities of this plug-in, we look at the list of
+ // N_OSO entries (object files) from the symbol table and make sure that
+ // these files exist and also contain valid DWARF. If we get any of that
+ // then we return the abilities of the first N_OSO's DWARF.
+
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+
+ std::vector<uint32_t> oso_indexes;
+ // When a mach-o symbol is encoded, the n_type field is encoded in bits
+ // 23:16, and the n_desc field is encoded in bits 15:0.
+ //
+ // To find all N_OSO entries that are part of the DWARF + debug map
+ // we find only object file symbols with the flags value as follows:
+ // bits 23:16 == 0x66 (N_OSO)
+ // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
+ const uint32_t k_oso_symbol_flags_value = 0x660001u;
+
+ const uint32_t oso_index_count =
+ symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
+ eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
+
+ if (oso_index_count > 0) {
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes,
+ Symtab::eVisibilityAny,
+ m_func_indexes);
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes,
+ Symtab::eVisibilityAny,
+ m_glob_indexes);
+
+ symtab->SortSymbolIndexesByValue(m_func_indexes, true);
+ symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
+
+ for (uint32_t sym_idx : m_func_indexes) {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(
+ file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ for (uint32_t sym_idx : m_glob_indexes) {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(
+ file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ m_debug_map.Sort();
+
+ m_compile_unit_infos.resize(oso_index_count);
+
+ for (uint32_t i = 0; i < oso_index_count; ++i) {
+ const uint32_t so_idx = oso_indexes[i] - 1;
+ const uint32_t oso_idx = oso_indexes[i];
+ const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
+ const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
+ if (so_symbol && oso_symbol &&
+ so_symbol->GetType() == eSymbolTypeSourceFile &&
+ oso_symbol->GetType() == eSymbolTypeObjectFile) {
+ m_compile_unit_infos[i].so_file.SetFile(
+ so_symbol->GetName().AsCString(), false);
+ 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));
+ uint32_t sibling_idx = so_symbol->GetSiblingIndex();
+ // The sibling index can't be less that or equal to the current index
+ // "i"
+ if (sibling_idx == UINT32_MAX) {
+ m_obj_file->GetModule()->ReportError(
+ "N_SO in symbol with UID %u has invalid sibling in debug map, "
+ "please file a bug and attach the binary listed in this error",
+ so_symbol->GetID());
+ } else {
+ const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
+ m_compile_unit_infos[i].first_symbol_index = so_idx;
+ m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
+ m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
+ m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
+
+ if (log)
+ log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
+ oso_symbol->GetName().GetCString());
+ }
+ } else {
+ if (oso_symbol == NULL)
+ m_obj_file->GetModule()->ReportError(
+ "N_OSO symbol[%u] can't be found, please file a bug and attach "
+ "the binary listed in this error",
+ oso_idx);
+ else if (so_symbol == NULL)
+ m_obj_file->GetModule()->ReportError(
+ "N_SO not found for N_OSO symbol[%u], please file a bug and "
+ "attach the binary listed in this error",
+ oso_idx);
+ else if (so_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError(
+ "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+ "please file a bug and attach the binary listed in this error",
+ so_symbol->GetType(), oso_idx);
+ else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError(
+ "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+ "please file a bug and attach the binary listed in this error",
+ oso_symbol->GetType(), oso_idx);
}
+ }
}
- if (comp_unit_info->oso_sp)
- return comp_unit_info->oso_sp->module_sp.get();
- return NULL;
-}
+ }
+}
+
+Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ if (oso_idx < cu_count)
+ return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
+ return NULL;
+}
+
+Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
+ CompileUnitInfo *comp_unit_info) {
+ if (!comp_unit_info->oso_sp) {
+ auto pos = m_oso_map.find(comp_unit_info->oso_path);
+ if (pos != m_oso_map.end()) {
+ comp_unit_info->oso_sp = pos->second;
+ } else {
+ ObjectFile *obj_file = GetObjectFile();
+ comp_unit_info->oso_sp.reset(new OSOInfo());
+ m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
+ const char *oso_path = comp_unit_info->oso_path.GetCString();
+ FileSpec oso_file(oso_path, false);
+ ConstString oso_object;
+ if (oso_file.Exists()) {
+ auto oso_mod_time = FileSystem::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 "
+ "%s, debug map time is %s"
+ ") since this executable was linked, file will be ignored",
+ oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(),
+ llvm::to_string(comp_unit_info->oso_mod_time).c_str());
+ return NULL;
+ }
+
+ } else {
+ const bool must_exist = true;
-bool
-SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
-{
- if (oso_idx < m_compile_unit_infos.size())
- {
- if (m_compile_unit_infos[oso_idx].so_file)
- {
- file_spec = m_compile_unit_infos[oso_idx].so_file;
- return true;
+ if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file,
+ oso_object, must_exist)) {
+ return NULL;
}
+ }
+ // Always create a new module for .o files. Why? Because we
+ // use the debug map, to add new sections to each .o file and
+ // even though a .o file might not have changed, the sections
+ // that get added to the .o file can change.
+ ArchSpec oso_arch;
+ // Only adopt the architecture from the module (not the vendor or OS)
+ // since .o files for "i386-apple-ios" will historically show up as
+ // "i386-apple-macosx"
+ // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
+ // load command...
+ oso_arch.SetTriple(m_obj_file->GetModule()
+ ->GetArchitecture()
+ .GetTriple()
+ .getArchName()
+ .str()
+ .c_str());
+ comp_unit_info->oso_sp->module_sp.reset(new DebugMapModule(
+ obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
+ oso_arch, oso_object ? &oso_object : NULL, 0,
+ oso_object ? comp_unit_info->oso_mod_time
+ : llvm::sys::TimePoint<>()));
}
- return false;
+ }
+ if (comp_unit_info->oso_sp)
+ return comp_unit_info->oso_sp->module_sp.get();
+ return NULL;
+}
+
+bool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx,
+ FileSpec &file_spec) {
+ if (oso_idx < m_compile_unit_infos.size()) {
+ if (m_compile_unit_infos[oso_idx].so_file) {
+ file_spec = m_compile_unit_infos[oso_idx].so_file;
+ return true;
+ }
+ }
+ return false;
}
-ObjectFile *
-SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
-{
- Module *oso_module = GetModuleByOSOIndex (oso_idx);
- if (oso_module)
- return oso_module->GetObjectFile();
- return NULL;
+ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
+ Module *oso_module = GetModuleByOSOIndex(oso_idx);
+ if (oso_module)
+ return oso_module->GetObjectFile();
+ return NULL;
}
SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
-{
- CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
- if (comp_unit_info)
- return GetSymbolFileByCompUnitInfo (comp_unit_info);
- return NULL;
+SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) {
+ CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc);
+ if (comp_unit_info)
+ return GetSymbolFileByCompUnitInfo(comp_unit_info);
+ return NULL;
}
-ObjectFile *
-SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
-{
- Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
- if (oso_module)
- return oso_module->GetObjectFile();
- return NULL;
+ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
+ CompileUnitInfo *comp_unit_info) {
+ Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
+ if (oso_module)
+ return oso_module->GetObjectFile();
+ return NULL;
}
-uint32_t
-SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
-{
- if (!m_compile_unit_infos.empty())
- {
- const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
- const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
- if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
- return comp_unit_info - first_comp_unit_info;
- }
- return UINT32_MAX;
-}
-
-SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
-{
- if (oso_idx < m_compile_unit_infos.size())
- return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
- return NULL;
+uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
+ const CompileUnitInfo *comp_unit_info) {
+ if (!m_compile_unit_infos.empty()) {
+ const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
+ const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
+ if (first_comp_unit_info <= comp_unit_info &&
+ comp_unit_info <= last_comp_unit_info)
+ return comp_unit_info - first_comp_unit_info;
+ }
+ return UINT32_MAX;
}
SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
-{
- if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
- return (SymbolFileDWARF *)sym_file;
- return NULL;
+SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
+ if (oso_idx < m_compile_unit_infos.size())
+ return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
+ return NULL;
}
SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
-{
- Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
- if (oso_module)
- {
- SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
- if (sym_vendor)
- return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
+SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
+ if (sym_file &&
+ sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
+ return (SymbolFileDWARF *)sym_file;
+ return NULL;
+}
+
+SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
+ CompileUnitInfo *comp_unit_info) {
+ Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
+ if (oso_module) {
+ SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
+ if (sym_vendor)
+ return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
+ }
+ return NULL;
+}
+
+uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
+ // In order to get the abilities of this plug-in, we look at the list of
+ // N_OSO entries (object files) from the symbol table and make sure that
+ // these files exist and also contain valid DWARF. If we get any of that
+ // then we return the abilities of the first N_OSO's DWARF.
+
+ const uint32_t oso_index_count = GetNumCompileUnits();
+ if (oso_index_count > 0) {
+ InitOSO();
+ if (!m_compile_unit_infos.empty()) {
+ return SymbolFile::CompileUnits | SymbolFile::Functions |
+ SymbolFile::Blocks | SymbolFile::GlobalVariables |
+ SymbolFile::LocalVariables | SymbolFile::VariableTypes |
+ SymbolFile::LineTables;
}
- return NULL;
-}
-
-uint32_t
-SymbolFileDWARFDebugMap::CalculateAbilities ()
-{
- // In order to get the abilities of this plug-in, we look at the list of
- // N_OSO entries (object files) from the symbol table and make sure that
- // these files exist and also contain valid DWARF. If we get any of that
- // then we return the abilities of the first N_OSO's DWARF.
-
- const uint32_t oso_index_count = GetNumCompileUnits();
- if (oso_index_count > 0)
- {
- InitOSO();
- if (!m_compile_unit_infos.empty())
- {
- return SymbolFile::CompileUnits |
- SymbolFile::Functions |
- SymbolFile::Blocks |
- SymbolFile::GlobalVariables |
- SymbolFile::LocalVariables |
- SymbolFile::VariableTypes |
- SymbolFile::LineTables ;
- }
- }
- return 0;
-}
-
-uint32_t
-SymbolFileDWARFDebugMap::GetNumCompileUnits()
-{
- InitOSO ();
- return m_compile_unit_infos.size();
-}
-
-CompUnitSP
-SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
-{
- CompUnitSP comp_unit_sp;
- const uint32_t cu_count = GetNumCompileUnits();
-
- if (cu_idx < cu_count)
- {
- Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
- if (oso_module)
- {
- FileSpec so_file_spec;
- if (GetFileSpecForSO (cu_idx, so_file_spec))
- {
- // User zero as the ID to match the compile unit at offset
- // zero in each .o file since each .o file can only have
- // one compile unit for now.
- lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
- m_obj_file->GetModule(), NULL, so_file_spec, cu_id, eLanguageTypeUnknown, eLazyBoolCalculate));
-
- if (m_compile_unit_infos[cu_idx].compile_unit_sp)
- {
- // Let our symbol vendor know about this compile unit
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
- }
- }
+ }
+ return 0;
+}
+
+uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
+ InitOSO();
+ return m_compile_unit_infos.size();
+}
+
+CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
+ CompUnitSP comp_unit_sp;
+ const uint32_t cu_count = GetNumCompileUnits();
+
+ if (cu_idx < cu_count) {
+ Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
+ if (oso_module) {
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO(cu_idx, so_file_spec)) {
+ // User zero as the ID to match the compile unit at offset
+ // zero in each .o file since each .o file can only have
+ // one compile unit for now.
+ lldb::user_id_t cu_id = 0;
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(
+ new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id,
+ eLanguageTypeUnknown, eLazyBoolCalculate));
+
+ if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
+ // Let our symbol vendor know about this compile unit
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
}
- comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
+ }
}
+ comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
+ }
- return comp_unit_sp;
+ return comp_unit_sp;
}
SymbolFileDWARFDebugMap::CompileUnitInfo *
-SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
-{
- 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())
- return &m_compile_unit_infos[i];
- }
- return NULL;
-}
-
-size_t
-SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
-{
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t i=0; i<cu_count; ++i)
- {
- if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
- cu_infos.push_back (&m_compile_unit_infos[i]);
- }
- return cu_infos.size();
+SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) {
+ 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())
+ return &m_compile_unit_infos[i];
+ }
+ return NULL;
+}
+
+size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
+ const lldb_private::Module *module,
+ std::vector<CompileUnitInfo *> &cu_infos) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t i = 0; i < cu_count; ++i) {
+ if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i]))
+ cu_infos.push_back(&m_compile_unit_infos[i]);
+ }
+ return cu_infos.size();
}
lldb::LanguageType
-SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitLanguage (sc);
- return eLanguageTypeUnknown;
+SymbolFileDWARFDebugMap::ParseCompileUnitLanguage(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitLanguage(sc);
+ return eLanguageTypeUnknown;
}
size_t
-SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitFunctions (sc);
- return 0;
+SymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitFunctions(sc);
+ return 0;
}
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitLineTable (sc);
- return false;
+bool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable(
+ const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitLineTable(sc);
+ return false;
}
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitDebugMacros (sc);
- return false;
+bool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros(
+ const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitDebugMacros(sc);
+ return false;
}
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
- return false;
+bool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles(
+ const SymbolContext &sc, FileSpecList &support_files) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files);
+ return false;
}
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitIsOptimized(sc);
- return false;
+bool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(
+ const lldb_private::SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitIsOptimized(sc);
+ return false;
}
-bool
-SymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseImportedModules(sc, imported_modules);
- return false;
+bool SymbolFileDWARFDebugMap::ParseImportedModules(
+ const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseImportedModules(sc, imported_modules);
+ return false;
}
-size_t
-SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseFunctionBlocks (sc);
- return 0;
+size_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseFunctionBlocks(sc);
+ return 0;
}
-size_t
-SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseTypes (sc);
- return 0;
+size_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseTypes(sc);
+ return 0;
}
size_t
-SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseVariablesForContext (sc);
- return 0;
+SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseVariablesForContext(sc);
+ return 0;
}
-Type*
-SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
-{
- const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- return oso_dwarf->ResolveTypeUID (type_uid);
- return NULL;
+Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
+ const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf)
+ return oso_dwarf->ResolveTypeUID(type_uid);
+ return NULL;
}
-bool
-SymbolFileDWARFDebugMap::CompleteType (CompilerType& compiler_type)
-{
- bool success = false;
- if (compiler_type)
- {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- if (oso_dwarf->HasForwardDeclForClangType (compiler_type))
- {
- oso_dwarf->CompleteType (compiler_type);
- success = true;
- return true;
+bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
+ bool success = false;
+ if (compiler_type) {
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) {
+ oso_dwarf->CompleteType(compiler_type);
+ success = true;
+ return true;
+ }
+ return false;
+ });
+ }
+ return success;
+}
+
+uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
+ const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) {
+ uint32_t resolved_flags = 0;
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
+
+ const DebugMap::Entry *debug_map_entry =
+ m_debug_map.FindEntryThatContains(exe_file_addr);
+ if (debug_map_entry) {
+
+ sc.symbol =
+ symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
+
+ if (sc.symbol != NULL) {
+ resolved_flags |= eSymbolContextSymbol;
+
+ uint32_t oso_idx = 0;
+ CompileUnitInfo *comp_unit_info =
+ GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
+ if (comp_unit_info) {
+ comp_unit_info->GetFileRangeMap(this);
+ Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
+ if (oso_module) {
+ lldb::addr_t oso_file_addr =
+ exe_file_addr - debug_map_entry->GetRangeBase() +
+ debug_map_entry->data.GetOSOFileAddress();
+ Address oso_so_addr;
+ if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
+ resolved_flags |=
+ oso_module->GetSymbolVendor()->ResolveSymbolContext(
+ oso_so_addr, resolve_scope, sc);
}
- return false;
- });
+ }
+ }
+ }
+ }
+ }
+ return resolved_flags;
+}
+
+uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
+ const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, SymbolContextList &sc_list) {
+ const uint32_t initial = sc_list.GetSize();
+ const uint32_t cu_count = GetNumCompileUnits();
+
+ for (uint32_t i = 0; i < cu_count; ++i) {
+ // If we are checking for inlines, then we need to look through all
+ // compile units no matter if "file_spec" matches.
+ bool resolve = check_inlines;
+
+ if (!resolve) {
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO(i, so_file_spec)) {
+ // Match the full path if the incoming file_spec has a directory (not
+ // just a basename)
+ const bool full_match = (bool)file_spec.GetDirectory();
+ resolve = FileSpec::Equal(file_spec, so_file_spec, full_match);
+ }
}
- return success;
+ if (resolve) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
+ if (oso_dwarf)
+ oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines,
+ resolve_scope, sc_list);
+ }
+ }
+ return sc_list.GetSize() - initial;
}
-uint32_t
-SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
-{
- uint32_t resolved_flags = 0;
- Symtab* symtab = m_obj_file->GetSymtab();
- if (symtab)
- {
- const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
-
- const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
- if (debug_map_entry)
- {
-
- sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
-
- if (sc.symbol != NULL)
- {
- resolved_flags |= eSymbolContextSymbol;
-
- uint32_t oso_idx = 0;
- CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
- if (comp_unit_info)
- {
- comp_unit_info->GetFileRangeMap(this);
- Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
- if (oso_module)
- {
- lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
- Address oso_so_addr;
- if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
- {
- resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
- }
- }
- }
- }
- }
+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) {
+ const uint32_t original_size = variables.GetSize();
+ const size_t match_count = indexes.size();
+ for (size_t i = 0; i < match_count; ++i) {
+ uint32_t oso_idx;
+ CompileUnitInfo *comp_unit_info =
+ GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx);
+ if (comp_unit_info) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf) {
+ if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true,
+ max_matches, variables))
+ if (variables.GetSize() > max_matches)
+ break;
+ }
}
- return resolved_flags;
+ }
+ return variables.GetSize() - original_size;
}
-uint32_t
-SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
-{
- const uint32_t initial = sc_list.GetSize();
- const uint32_t cu_count = GetNumCompileUnits();
+uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches, VariableList &variables) {
- for (uint32_t i=0; i<cu_count; ++i)
- {
- // If we are checking for inlines, then we need to look through all
- // compile units no matter if "file_spec" matches.
- bool resolve = check_inlines;
-
- if (!resolve)
- {
- FileSpec so_file_spec;
- if (GetFileSpecForSO (i, so_file_spec))
- {
- // Match the full path if the incoming file_spec has a directory (not just a basename)
- const bool full_match = (bool)file_spec.GetDirectory();
- resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
- }
- }
- if (resolve)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
- if (oso_dwarf)
- oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
- }
- }
- return sc_list.GetSize() - initial;
-}
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
-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
-)
-{
- const uint32_t original_size = variables.GetSize();
- const size_t match_count = indexes.size();
- for (size_t i=0; i<match_count; ++i)
- {
- uint32_t oso_idx;
- CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
- if (comp_unit_info)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- {
- if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables))
- if (variables.GetSize() > max_matches)
- break;
- }
- }
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
+
+ uint32_t total_matches = 0;
+
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
+ name, parent_decl_ctx, true, max_matches, variables);
+ if (oso_matches > 0) {
+ total_matches += oso_matches;
+
+ // Are we getting all matches?
+ if (max_matches == UINT32_MAX)
+ return false; // Yep, continue getting everything
+
+ // If we have found enough matches, lets get out
+ if (max_matches >= total_matches)
+ return true;
+
+ // Update the max matches for any subsequent calls to find globals
+ // in any other object files with DWARF
+ max_matches -= oso_matches;
}
- return variables.GetSize() - original_size;
-}
-uint32_t
-SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- bool append,
- uint32_t max_matches,
- VariableList& variables)
-{
-
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
-
- uint32_t total_matches = 0;
-
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
- parent_decl_ctx,
- true,
- max_matches,
- variables);
- if (oso_matches > 0)
- {
- total_matches += oso_matches;
-
- // Are we getting all matches?
- if (max_matches == UINT32_MAX)
- return false; // Yep, continue getting everything
-
- // If we have found enough matches, lets get out
- if (max_matches >= total_matches)
- return true;
-
- // Update the max matches for any subsequent calls to find globals
- // in any other object files with DWARF
- max_matches -= oso_matches;
- }
-
- return false;
- });
+ return false;
+ });
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
+ // Return the number of variable that were appended to the list
+ return variables.GetSize() - original_size;
}
uint32_t
-SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
-{
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
+SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
+ bool append, uint32_t max_matches,
+ VariableList &variables) {
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
+
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
+
+ uint32_t total_matches = 0;
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ const uint32_t oso_matches =
+ oso_dwarf->FindGlobalVariables(regex, true, max_matches, variables);
+ if (oso_matches > 0) {
+ total_matches += oso_matches;
+
+ // Are we getting all matches?
+ if (max_matches == UINT32_MAX)
+ return false; // Yep, continue getting everything
+
+ // If we have found enough matches, lets get out
+ if (max_matches >= total_matches)
+ return true;
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
+ // Update the max matches for any subsequent calls to find globals
+ // in any other object files with DWARF
+ max_matches -= oso_matches;
+ }
- uint32_t total_matches = 0;
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
- true,
- max_matches,
- variables);
- if (oso_matches > 0)
- {
- total_matches += oso_matches;
-
- // Are we getting all matches?
- if (max_matches == UINT32_MAX)
- return false; // Yep, continue getting everything
-
- // If we have found enough matches, lets get out
- if (max_matches >= total_matches)
- return true;
-
- // Update the max matches for any subsequent calls to find globals
- // in any other object files with DWARF
- max_matches -= oso_matches;
- }
-
- return false;
- });
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
+ return false;
+ });
+
+ // Return the number of variable that were appended to the list
+ return variables.GetSize() - original_size;
}
-int
-SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
-{
- const uint32_t symbol_idx = *symbol_idx_ptr;
+int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
+ uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
+ const uint32_t symbol_idx = *symbol_idx_ptr;
- if (symbol_idx < comp_unit_info->first_symbol_index)
- return -1;
+ if (symbol_idx < comp_unit_info->first_symbol_index)
+ return -1;
- if (symbol_idx <= comp_unit_info->last_symbol_index)
- return 0;
+ if (symbol_idx <= comp_unit_info->last_symbol_index)
+ return 0;
- return 1;
+ return 1;
}
-int
-SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
-{
- const user_id_t symbol_id = *symbol_idx_ptr;
+int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID(
+ user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
+ const user_id_t symbol_id = *symbol_idx_ptr;
- if (symbol_id < comp_unit_info->first_symbol_id)
- return -1;
+ if (symbol_id < comp_unit_info->first_symbol_id)
+ return -1;
- if (symbol_id <= comp_unit_info->last_symbol_id)
- return 0;
+ if (symbol_id <= comp_unit_info->last_symbol_id)
+ return 0;
- return 1;
+ return 1;
}
-SymbolFileDWARFDebugMap::CompileUnitInfo*
-SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
-{
- const uint32_t oso_index_count = m_compile_unit_infos.size();
- CompileUnitInfo *comp_unit_info = NULL;
- if (oso_index_count)
- {
- comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
- &m_compile_unit_infos[0],
- m_compile_unit_infos.size(),
- sizeof(CompileUnitInfo),
- (ComparisonFunction)SymbolContainsSymbolWithIndex);
- }
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
+ uint32_t symbol_idx, uint32_t *oso_idx_ptr) {
+ const uint32_t oso_index_count = m_compile_unit_infos.size();
+ CompileUnitInfo *comp_unit_info = NULL;
+ if (oso_index_count) {
+ comp_unit_info = (CompileUnitInfo *)bsearch(
+ &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
+ sizeof(CompileUnitInfo),
+ (ComparisonFunction)SymbolContainsSymbolWithIndex);
+ }
+
+ if (oso_idx_ptr) {
+ if (comp_unit_info != NULL)
+ *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
+ else
+ *oso_idx_ptr = UINT32_MAX;
+ }
+ return comp_unit_info;
+}
- if (oso_idx_ptr)
- {
- if (comp_unit_info != NULL)
- *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
- else
- *oso_idx_ptr = UINT32_MAX;
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
+ user_id_t symbol_id, uint32_t *oso_idx_ptr) {
+ const uint32_t oso_index_count = m_compile_unit_infos.size();
+ CompileUnitInfo *comp_unit_info = NULL;
+ if (oso_index_count) {
+ comp_unit_info = (CompileUnitInfo *)::bsearch(
+ &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
+ sizeof(CompileUnitInfo),
+ (ComparisonFunction)SymbolContainsSymbolWithID);
+ }
+
+ if (oso_idx_ptr) {
+ if (comp_unit_info != NULL)
+ *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
+ else
+ *oso_idx_ptr = UINT32_MAX;
+ }
+ return comp_unit_info;
+}
+
+static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
+ SymbolContextList &sc_list,
+ uint32_t start_idx) {
+ // We found functions in .o files. Not all functions in the .o files
+ // will have made it into the final output file. The ones that did
+ // make it into the final output file will have a section whose module
+ // matches the module from the ObjectFile for this SymbolFile. When
+ // the modules don't match, then we have something that was in a
+ // .o file, but doesn't map to anything in the final executable.
+ uint32_t i = start_idx;
+ while (i < sc_list.GetSize()) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(i, sc);
+ if (sc.function) {
+ const SectionSP section_sp(
+ sc.function->GetAddressRange().GetBaseAddress().GetSection());
+ if (section_sp->GetModule() != module_sp) {
+ sc_list.RemoveContextAtIndex(i);
+ continue;
+ }
}
- return comp_unit_info;
-}
-
-SymbolFileDWARFDebugMap::CompileUnitInfo*
-SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
-{
- const uint32_t oso_index_count = m_compile_unit_infos.size();
- CompileUnitInfo *comp_unit_info = NULL;
- if (oso_index_count)
- {
- comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
- &m_compile_unit_infos[0],
- m_compile_unit_infos.size(),
- sizeof(CompileUnitInfo),
- (ComparisonFunction)SymbolContainsSymbolWithID);
+ ++i;
+ }
+}
+
+uint32_t SymbolFileDWARFDebugMap::FindFunctions(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
+ name.GetCString());
+
+ uint32_t initial_size = 0;
+ if (append)
+ initial_size = sc_list.GetSize();
+ else
+ sc_list.Clear();
+
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ uint32_t sc_idx = sc_list.GetSize();
+ if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
+ include_inlines, true, sc_list)) {
+ RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ sc_idx);
}
+ return false;
+ });
- if (oso_idx_ptr)
- {
- if (comp_unit_info != NULL)
- *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
- else
- *oso_idx_ptr = UINT32_MAX;
- }
- return comp_unit_info;
-}
-
-static void
-RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
-{
- // We found functions in .o files. Not all functions in the .o files
- // will have made it into the final output file. The ones that did
- // make it into the final output file will have a section whose module
- // matches the module from the ObjectFile for this SymbolFile. When
- // the modules don't match, then we have something that was in a
- // .o file, but doesn't map to anything in the final executable.
- uint32_t i=start_idx;
- while (i < sc_list.GetSize())
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(i, sc);
- if (sc.function)
- {
- const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
- if (section_sp->GetModule() != module_sp)
- {
- sc_list.RemoveContextAtIndex(i);
- continue;
- }
- }
- ++i;
- }
+ return sc_list.GetSize() - initial_size;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask,
- bool include_inlines,
- bool append,
- SymbolContextList& sc_list)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
- name.GetCString());
-
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
+uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ bool append,
+ SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
+ regex.GetText().str().c_str());
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list))
- {
- RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
- }
- return false;
- });
+ uint32_t initial_size = 0;
+ if (append)
+ initial_size = sc_list.GetSize();
+ else
+ sc_list.Clear();
- return sc_list.GetSize() - initial_size;
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ uint32_t sc_idx = sc_list.GetSize();
+
+ if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) {
+ RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ sc_idx);
+ }
+ return false;
+ });
+
+ return sc_list.GetSize() - initial_size;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
- regex.GetText());
-
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
+size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ TypeList &type_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
+ type_mask);
+ uint32_t initial_size = type_list.GetSize();
+ SymbolFileDWARF *oso_dwarf = NULL;
+ if (sc_scope) {
+ SymbolContext sc;
+ sc_scope->CalculateSymbolContext(&sc);
+
+ CompileUnitInfo *cu_info = GetCompUnitInfo(sc);
+ if (cu_info) {
+ oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info);
+ if (oso_dwarf)
+ oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
+ }
+ } else {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- uint32_t sc_idx = sc_list.GetSize();
-
- if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
- {
- RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
- }
- return false;
+ oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
+ return false;
});
-
- return sc_list.GetSize() - initial_size;
+ }
+ return type_list.GetSize() - initial_size;
}
-size_t
-SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
- uint32_t type_mask,
- TypeList &type_list)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
- type_mask);
-
- uint32_t initial_size = type_list.GetSize();
- SymbolFileDWARF *oso_dwarf = NULL;
- if (sc_scope)
- {
- SymbolContext sc;
- sc_scope->CalculateSymbolContext(&sc);
-
- CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
- if (cu_info)
- {
- oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
- if (oso_dwarf)
- oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
- }
- }
- else
- {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
- return false;
- });
- }
- return type_list.GetSize() - initial_size;
+TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &die_decl_ctx) {
+ TypeSP type_sp;
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+ return ((bool)type_sp);
+ });
+ return type_sp;
}
-TypeSP
-SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
-{
- TypeSP type_sp;
+bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
+ SymbolFileDWARF *skip_dwarf_oso) {
+ if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
- return ((bool)type_sp);
+ if (skip_dwarf_oso != oso_dwarf &&
+ oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+ return true;
+ }
+ return false;
});
- return type_sp;
-}
-
-bool
-SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
-{
- if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
- return true;
- }
- return false;
- });
- }
- return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
-}
-
-TypeSP
-SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const ConstString &type_name,
- bool must_be_implementation)
-{
- // If we have a debug map, we will have an Objective C symbol whose name is
- // the type name and whose type is eSymbolTypeObjCClass. If we can find that
- // symbol and find its containing parent, we can locate the .o file that will
- // contain the implementation definition since it will be scoped inside the N_SO
- // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
- SymbolFileDWARF *oso_dwarf = NULL;
- TypeSP type_sp;
- ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
- if (module_objfile)
- {
- Symtab *symtab = module_objfile->GetSymtab();
- if (symtab)
- {
- Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
- if (objc_class_symbol)
- {
- // Get the N_SO symbol that contains the objective C class symbol as this
- // should be the .o file that contains the real definition...
- const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
-
- if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
- {
- const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
- if (source_file_symbol_idx != UINT32_MAX)
- {
- CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
- if (compile_unit_info)
- {
- oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
- if (oso_dwarf)
- {
- TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
- if (type_sp)
- {
- return type_sp;
- }
- }
- }
- }
+ }
+ return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
+}
+
+TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const ConstString &type_name,
+ bool must_be_implementation) {
+ // If we have a debug map, we will have an Objective C symbol whose name is
+ // the type name and whose type is eSymbolTypeObjCClass. If we can find that
+ // symbol and find its containing parent, we can locate the .o file that will
+ // contain the implementation definition since it will be scoped inside the
+ // N_SO
+ // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
+ SymbolFileDWARF *oso_dwarf = NULL;
+ TypeSP type_sp;
+ ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
+ if (module_objfile) {
+ Symtab *symtab = module_objfile->GetSymtab();
+ if (symtab) {
+ Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
+ type_name, eSymbolTypeObjCClass, Symtab::eDebugAny,
+ Symtab::eVisibilityAny);
+ if (objc_class_symbol) {
+ // Get the N_SO symbol that contains the objective C class symbol as
+ // this
+ // should be the .o file that contains the real definition...
+ const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
+
+ if (source_file_symbol &&
+ source_file_symbol->GetType() == eSymbolTypeSourceFile) {
+ const uint32_t source_file_symbol_idx =
+ symtab->GetIndexForSymbol(source_file_symbol);
+ if (source_file_symbol_idx != UINT32_MAX) {
+ CompileUnitInfo *compile_unit_info =
+ GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx,
+ NULL);
+ if (compile_unit_info) {
+ oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info);
+ if (oso_dwarf) {
+ TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name, must_be_implementation));
+ if (type_sp) {
+ return type_sp;
}
+ }
}
+ }
}
+ }
}
+ }
+
+ // 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) {
+ TypeSP type_sp;
- // 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)
- {
- TypeSP type_sp;
-
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
- return (bool)type_sp;
- });
-
- return type_sp;
- }
- return TypeSP();
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name, must_be_implementation);
+ return (bool)type_sp;
+ });
+
+ return type_sp;
+ }
+ return TypeSP();
}
-uint32_t
-SymbolFileDWARFDebugMap::FindTypes
-(
- const SymbolContext& sc,
- const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- bool append,
+uint32_t SymbolFileDWARFDebugMap::FindTypes(
+ const SymbolContext &sc, 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;
- });
- }
+ TypeMap &types) {
+ if (!append)
+ types.Clear();
+
+ const uint32_t initial_types_size = types.GetSize();
+ SymbolFileDWARF *oso_dwarf;
- return types.GetSize() - initial_types_size;
+ 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;
+ });
+ }
+
+ return types.GetSize() - initial_types_size;
}
//
-//uint32_t
-//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+// uint32_t
+// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const
+// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding
+// encoding, lldb::user_id_t udt_uid, TypeList& types)
//{
// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
// if (oso_dwarf)
-// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
+// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding,
+// udt_uid, types);
// return 0;
//}
+CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx) {
+ CompilerDeclContext matching_namespace;
+ SymbolFileDWARF *oso_dwarf;
-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);
+ 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);
- return (bool)matching_namespace;
- });
- }
+ return (bool)matching_namespace;
+ });
+ }
- return matching_namespace;
+ return matching_namespace;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-SymbolFileDWARFDebugMap::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-SymbolFileDWARFDebugMap::GetPluginVersion()
-{
- return 1;
-}
+uint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; }
lldb::CompUnitSP
-SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
-{
- if (oso_dwarf)
- {
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
- {
- SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
- if (oso_symfile == oso_dwarf)
- {
- if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
- m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
-
- return m_compile_unit_infos[cu_idx].compile_unit_sp;
- }
- }
+SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) {
+ if (oso_dwarf) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
+ SymbolFileDWARF *oso_symfile =
+ GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf) {
+ if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
+ m_compile_unit_infos[cu_idx].compile_unit_sp =
+ ParseCompileUnitAtIndex(cu_idx);
+
+ return m_compile_unit_infos[cu_idx].compile_unit_sp;
+ }
}
- assert(!"this shouldn't happen");
- return lldb::CompUnitSP();
+ }
+ assert(!"this shouldn't happen");
+ return lldb::CompUnitSP();
}
SymbolFileDWARFDebugMap::CompileUnitInfo *
-SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
-{
- if (oso_dwarf)
- {
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
- {
- SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
- if (oso_symfile == oso_dwarf)
- {
- return &m_compile_unit_infos[cu_idx];
- }
- }
+SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
+ if (oso_dwarf) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
+ SymbolFileDWARF *oso_symfile =
+ GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf) {
+ return &m_compile_unit_infos[cu_idx];
+ }
}
- return NULL;
+ }
+ return NULL;
}
-void
-SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
-{
- if (oso_dwarf)
- {
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
- {
- SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
- if (oso_symfile == oso_dwarf)
- {
- if (m_compile_unit_infos[cu_idx].compile_unit_sp)
- {
- assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
- }
- else
- {
- m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
- }
- }
+void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
+ const CompUnitSP &cu_sp) {
+ if (oso_dwarf) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
+ SymbolFileDWARF *oso_symfile =
+ GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf) {
+ if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
+ assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() ==
+ cu_sp.get());
+ } else {
+ m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ cu_idx, cu_sp);
}
+ }
}
+ }
}
CompilerDeclContext
-SymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid)
-{
- const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- return oso_dwarf->GetDeclContextForUID (type_uid);
- return CompilerDeclContext();
+SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) {
+ const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf)
+ return oso_dwarf->GetDeclContextForUID(type_uid);
+ return CompilerDeclContext();
}
CompilerDeclContext
-SymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid)
-{
- const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- return oso_dwarf->GetDeclContextContainingUID (type_uid);
- return CompilerDeclContext();
-}
-
-void
-SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx)
-{
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->ParseDeclsForContext (decl_ctx);
- return true; // Keep iterating
- });
-}
-
-bool
-SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
- lldb::addr_t exe_file_addr,
- lldb::addr_t exe_byte_size,
- lldb::addr_t oso_file_addr,
- lldb::addr_t oso_byte_size)
-{
- const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
- if (debug_map_idx != UINT32_MAX)
- {
- DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
- debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
- addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
- if (range_size == 0)
- {
- range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
- if (range_size == 0)
- range_size = 1;
- }
- cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
- return true;
+SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
+ const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf)
+ return oso_dwarf->GetDeclContextContainingUID(type_uid);
+ return CompilerDeclContext();
+}
+
+void SymbolFileDWARFDebugMap::ParseDeclsForContext(
+ lldb_private::CompilerDeclContext decl_ctx) {
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ oso_dwarf->ParseDeclsForContext(decl_ctx);
+ return true; // Keep iterating
+ });
+}
+
+bool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t exe_byte_size,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size) {
+ const uint32_t debug_map_idx =
+ m_debug_map.FindEntryIndexThatContains(exe_file_addr);
+ if (debug_map_idx != UINT32_MAX) {
+ DebugMap::Entry *debug_map_entry =
+ m_debug_map.FindEntryThatContains(exe_file_addr);
+ debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
+ addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0) {
+ range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0)
+ range_size = 1;
}
- return false;
+ cu_info->file_range_map.Append(
+ FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
+ return true;
+ }
+ return false;
}
-void
-SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
-{
- cu_info->file_range_map.Sort();
+void SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) {
+ cu_info->file_range_map.Sort();
#if defined(DEBUG_OSO_DMAP)
- const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
- const size_t n = oso_file_range_map.GetSize();
- printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
- cu_info,
- cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
- for (size_t i=0; i<n; ++i)
- {
- const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
- printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
- entry.GetRangeBase(), entry.GetRangeEnd(),
- entry.data, entry.data + entry.GetByteSize());
- }
+ const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
+ const size_t n = oso_file_range_map.GetSize();
+ printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
+ cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
+ for (size_t i = 0; i < n; ++i) {
+ const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
+ printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
+ ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
+ entry.GetRangeBase(), entry.GetRangeEnd(), entry.data,
+ entry.data + entry.GetByteSize());
+ }
#endif
}
lldb::addr_t
-SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
-{
- CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
- if (cu_info)
- {
- const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
- if (oso_range_entry)
- {
- const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
- if (debug_map_entry)
- {
- const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
- const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
- return exe_file_addr;
- }
- }
+SymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
+ lldb::addr_t oso_file_addr) {
+ CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile);
+ if (cu_info) {
+ const FileRangeMap::Entry *oso_range_entry =
+ cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry) {
+ const DebugMap::Entry *debug_map_entry =
+ m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry) {
+ const lldb::addr_t offset =
+ oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr =
+ debug_map_entry->GetRangeBase() + offset;
+ return exe_file_addr;
+ }
}
- return LLDB_INVALID_ADDRESS;
-}
-
-bool
-SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
-{
- // Make sure this address hasn't been fixed already
- Module *exe_module = GetObjectFile()->GetModule().get();
- Module *addr_module = addr.GetModule().get();
- if (addr_module == exe_module)
- return true; // Address is already in terms of the main executable module
-
- CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
- if (cu_info)
- {
- const lldb::addr_t oso_file_addr = addr.GetFileAddress();
- const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
- if (oso_range_entry)
- {
- const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
- if (debug_map_entry)
- {
- const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
- const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
- return exe_module->ResolveFileAddress(exe_file_addr, addr);
- }
- }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
+ // Make sure this address hasn't been fixed already
+ Module *exe_module = GetObjectFile()->GetModule().get();
+ Module *addr_module = addr.GetModule().get();
+ if (addr_module == exe_module)
+ return true; // Address is already in terms of the main executable module
+
+ CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF(
+ addr_module->GetSymbolVendor()->GetSymbolFile()));
+ if (cu_info) {
+ const lldb::addr_t oso_file_addr = addr.GetFileAddress();
+ const FileRangeMap::Entry *oso_range_entry =
+ cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry) {
+ const DebugMap::Entry *debug_map_entry =
+ m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry) {
+ const lldb::addr_t offset =
+ oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr =
+ debug_map_entry->GetRangeBase() + offset;
+ return exe_module->ResolveFileAddress(exe_file_addr, addr);
+ }
}
- return true;
+ }
+ return true;
}
-LineTable *
-SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
-{
- CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
- if (cu_info)
- return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
- return NULL;
+LineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf,
+ LineTable *line_table) {
+ CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf);
+ if (cu_info)
+ return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
+ return NULL;
}
size_t
-SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
-{
- size_t num_line_entries_added = 0;
- if (debug_aranges && dwarf2Data)
- {
- CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
- if (compile_unit_info)
- {
- const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
- for (size_t idx = 0;
- idx < file_range_map.GetSize();
- idx++)
- {
- const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
- if (entry)
- {
- debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
- num_line_entries_added++;
- }
- }
+SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
+ DWARFDebugAranges *debug_aranges) {
+ size_t num_line_entries_added = 0;
+ if (debug_aranges && dwarf2Data) {
+ CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
+ if (compile_unit_info) {
+ const FileRangeMap &file_range_map =
+ compile_unit_info->GetFileRangeMap(this);
+ for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) {
+ const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
+ if (entry) {
+ debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(),
+ entry->GetRangeEnd());
+ num_line_entries_added++;
}
+ }
}
- return num_line_entries_added;
+ }
+ return num_line_entries_added;
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index fcf02975a58f..109da631d771 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -10,12 +10,12 @@
#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
-
-#include <vector>
#include <bitset>
+#include <vector>
#include "lldb/Core/RangeMap.h"
#include "lldb/Symbol/SymbolFile.h"
+#include "llvm/Support/Chrono.h"
#include "UniqueDWARFASTType.h"
@@ -23,398 +23,355 @@ class SymbolFileDWARF;
class DWARFDebugAranges;
class DWARFDeclContext;
-class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile
-{
+class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile {
public:
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::SymbolFile *
- CreateInstance (lldb_private::ObjectFile* obj_file);
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile);
- ~SymbolFileDWARFDebugMap () 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 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;
- 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 ParseVariablesForContext (const lldb_private::SymbolContext& sc) override;
-
- lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid) override;
- lldb_private::CompilerDeclContext GetDeclContextForUID (lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext GetDeclContextContainingUID (lldb::user_id_t uid) override;
- void ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override;
-
- bool CompleteType (lldb_private::CompilerType& compiler_type) override;
- uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t 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, lldb_private::SymbolContextList& sc_list) override;
- uint32_t FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
- uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
- 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;
- 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, 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_private::TypeList &type_list) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFileDWARFDebugMap(lldb_private::ObjectFile *ofile);
+ ~SymbolFileDWARFDebugMap() 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
+ 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;
+ 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
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t 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,
+ lldb_private::SymbolContextList &sc_list) override;
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+ uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+ 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;
+ 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,
+ 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_private::TypeList &type_list) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- enum
- {
- kHaveInitializedOSOs = (1 << 0),
- kNumFlags
- };
-
- friend class DebugMapModule;
- friend struct DIERef;
- friend class DWARFASTParserClang;
- friend class DWARFCompileUnit;
- friend class SymbolFileDWARF;
- struct OSOInfo
- {
- lldb::ModuleSP module_sp;
-
- OSOInfo() :
- module_sp ()
- {
- }
- };
-
- typedef std::shared_ptr<OSOInfo> OSOInfoSP;
-
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
-
- //------------------------------------------------------------------
- // Class specific types
- //------------------------------------------------------------------
- struct CompileUnitInfo
- {
- lldb_private::FileSpec so_file;
- lldb_private::ConstString oso_path;
- lldb_private::TimeValue oso_mod_time;
- OSOInfoSP oso_sp;
- lldb::CompUnitSP compile_unit_sp;
- uint32_t first_symbol_index;
- uint32_t last_symbol_index;
- uint32_t first_symbol_id;
- uint32_t last_symbol_id;
- FileRangeMap file_range_map;
- bool file_range_map_valid;
-
-
- CompileUnitInfo() :
- so_file (),
- oso_path (),
- oso_mod_time (),
- oso_sp (),
- compile_unit_sp (),
- first_symbol_index (UINT32_MAX),
- last_symbol_index (UINT32_MAX),
- first_symbol_id (UINT32_MAX),
- last_symbol_id (UINT32_MAX),
- file_range_map (),
- file_range_map_valid (false)
- {
- }
-
- const FileRangeMap &
- GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
- };
-
- //------------------------------------------------------------------
- // Protected Member Functions
- //------------------------------------------------------------------
- void
- InitOSO ();
-
- static uint32_t
- GetOSOIndexFromUserID (lldb::user_id_t uid)
- {
- return (uint32_t)((uid >> 32ull) - 1ull);
- }
-
- static SymbolFileDWARF *
- GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file);
-
- bool
- GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec);
-
- CompileUnitInfo *
- GetCompUnitInfo (const lldb_private::SymbolContext& sc);
-
- size_t
- GetCompUnitInfosForModule (const lldb_private::Module *oso_module,
- std::vector<CompileUnitInfo *>& cu_infos);
-
- lldb_private::Module *
- GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
-
- lldb_private::Module *
- GetModuleByOSOIndex (uint32_t oso_idx);
-
- lldb_private::ObjectFile *
- GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
-
- lldb_private::ObjectFile *
- GetObjectFileByOSOIndex (uint32_t oso_idx);
-
- uint32_t
- GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info);
-
- SymbolFileDWARF *
- GetSymbolFile (const lldb_private::SymbolContext& sc);
-
- SymbolFileDWARF *
- GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
-
- SymbolFileDWARF *
- GetSymbolFileByOSOIndex (uint32_t oso_idx);
-
- // If closure returns "false", iteration continues. If it returns
- // "true", iteration terminates.
- void
- ForEachSymbolFile (std::function<bool (SymbolFileDWARF *)> closure)
- {
- for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
- oso_idx < num_oso_idxs;
- ++oso_idx)
- {
- if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx))
- {
- if (closure(oso_dwarf))
- return;
- }
- }
+ enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
+
+ friend class DebugMapModule;
+ friend struct DIERef;
+ friend class DWARFASTParserClang;
+ friend class DWARFCompileUnit;
+ friend class SymbolFileDWARF;
+ struct OSOInfo {
+ lldb::ModuleSP module_sp;
+
+ OSOInfo() : module_sp() {}
+ };
+
+ typedef std::shared_ptr<OSOInfo> OSOInfoSP;
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
+ lldb::addr_t>
+ FileRangeMap;
+
+ //------------------------------------------------------------------
+ // Class specific types
+ //------------------------------------------------------------------
+ struct CompileUnitInfo {
+ lldb_private::FileSpec so_file;
+ lldb_private::ConstString oso_path;
+ llvm::sys::TimePoint<> oso_mod_time;
+ OSOInfoSP oso_sp;
+ lldb::CompUnitSP compile_unit_sp;
+ uint32_t first_symbol_index;
+ uint32_t last_symbol_index;
+ uint32_t first_symbol_id;
+ uint32_t last_symbol_id;
+ FileRangeMap file_range_map;
+ bool file_range_map_valid;
+
+ CompileUnitInfo()
+ : so_file(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(),
+ first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX),
+ first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
+ file_range_map(), file_range_map_valid(false) {}
+
+ const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
+ };
+
+ //------------------------------------------------------------------
+ // Protected Member Functions
+ //------------------------------------------------------------------
+ void InitOSO();
+
+ static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
+ return (uint32_t)((uid >> 32ull) - 1ull);
+ }
+
+ static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file);
+
+ bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec);
+
+ CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc);
+
+ size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module,
+ std::vector<CompileUnitInfo *> &cu_infos);
+
+ lldb_private::Module *
+ GetModuleByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+
+ lldb_private::Module *GetModuleByOSOIndex(uint32_t oso_idx);
+
+ lldb_private::ObjectFile *
+ GetObjectFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+
+ lldb_private::ObjectFile *GetObjectFileByOSOIndex(uint32_t oso_idx);
+
+ uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info);
+
+ SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc);
+
+ SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+
+ SymbolFileDWARF *GetSymbolFileByOSOIndex(uint32_t oso_idx);
+
+ // If closure returns "false", iteration continues. If it returns
+ // "true", iteration terminates.
+ void ForEachSymbolFile(std::function<bool(SymbolFileDWARF *)> closure) {
+ for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
+ oso_idx < num_oso_idxs; ++oso_idx) {
+ if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) {
+ if (closure(oso_dwarf))
+ return;
+ }
}
+ }
+
+ CompileUnitInfo *GetCompileUnitInfoForSymbolWithIndex(uint32_t symbol_idx,
+ uint32_t *oso_idx_ptr);
- CompileUnitInfo *
- GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr);
-
- CompileUnitInfo *
- GetCompileUnitInfoForSymbolWithID (lldb::user_id_t symbol_id, uint32_t *oso_idx_ptr);
+ CompileUnitInfo *GetCompileUnitInfoForSymbolWithID(lldb::user_id_t symbol_id,
+ uint32_t *oso_idx_ptr);
- static int
- SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
+ static int
+ SymbolContainsSymbolWithIndex(uint32_t *symbol_idx_ptr,
+ const CompileUnitInfo *comp_unit_info);
- static int
- SymbolContainsSymbolWithID (lldb::user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
+ static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
+ const CompileUnitInfo *comp_unit_info);
- uint32_t
- PrivateFindGlobalVariables (const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- const std::vector<uint32_t> &name_symbol_indexes,
- uint32_t max_matches,
- lldb_private::VariableList& variables);
+ uint32_t PrivateFindGlobalVariables(
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
+ lldb_private::VariableList &variables);
+ void SetCompileUnit(SymbolFileDWARF *oso_dwarf,
+ const lldb::CompUnitSP &cu_sp);
- void
- SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp);
+ lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf);
- lldb::CompUnitSP
- GetCompileUnit (SymbolFileDWARF *oso_dwarf);
-
- CompileUnitInfo *
- GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
+ CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);
- lldb::TypeSP
- FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
+ lldb::TypeSP
+ FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
- bool
- Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso);
+ bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);
- lldb::TypeSP
- FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const lldb_private::ConstString &type_name,
- bool must_be_implementation);
-
+ lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation);
- UniqueDWARFASTTypeMap &
- GetUniqueDWARFASTTypeMap ()
- {
- return m_unique_ast_type_map;
+ UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() {
+ return m_unique_ast_type_map;
+ }
+
+ //------------------------------------------------------------------
+ // OSOEntry
+ //------------------------------------------------------------------
+ class OSOEntry {
+ public:
+ OSOEntry()
+ : m_exe_sym_idx(UINT32_MAX), m_oso_file_addr(LLDB_INVALID_ADDRESS) {}
+
+ OSOEntry(uint32_t exe_sym_idx, lldb::addr_t oso_file_addr)
+ : m_exe_sym_idx(exe_sym_idx), m_oso_file_addr(oso_file_addr) {}
+
+ uint32_t GetExeSymbolIndex() const { return m_exe_sym_idx; }
+
+ bool operator<(const OSOEntry &rhs) const {
+ return m_exe_sym_idx < rhs.m_exe_sym_idx;
}
-
-
- //------------------------------------------------------------------
- // OSOEntry
- //------------------------------------------------------------------
- class OSOEntry
- {
- public:
-
- OSOEntry () :
- m_exe_sym_idx (UINT32_MAX),
- m_oso_file_addr (LLDB_INVALID_ADDRESS)
- {
- }
-
- OSOEntry (uint32_t exe_sym_idx,
- lldb::addr_t oso_file_addr) :
- m_exe_sym_idx (exe_sym_idx),
- m_oso_file_addr (oso_file_addr)
- {
- }
-
- uint32_t
- GetExeSymbolIndex () const
- {
- return m_exe_sym_idx;
- }
-
- bool
- operator < (const OSOEntry &rhs) const
- {
- return m_exe_sym_idx < rhs.m_exe_sym_idx;
- }
-
- lldb::addr_t
- GetOSOFileAddress () const
- {
- return m_oso_file_addr;
- }
-
- void
- SetOSOFileAddress (lldb::addr_t oso_file_addr)
- {
- m_oso_file_addr = oso_file_addr;
- }
- protected:
- uint32_t m_exe_sym_idx;
- lldb::addr_t m_oso_file_addr;
- };
-
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
-
- //------------------------------------------------------------------
- // Member Variables
- //------------------------------------------------------------------
- std::bitset<kNumFlags> m_flags;
- std::vector<CompileUnitInfo> m_compile_unit_infos;
- std::vector<uint32_t> m_func_indexes; // Sorted by address
- std::vector<uint32_t> m_glob_indexes;
- std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
- UniqueDWARFASTTypeMap m_unique_ast_type_map;
- lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
- DebugMap m_debug_map;
-
- //------------------------------------------------------------------
- // When an object file from the debug map gets parsed in
- // SymbolFileDWARF, it needs to tell the debug map about the object
- // files addresses by calling this function once for each N_FUN,
- // N_GSYM and N_STSYM and after all entries in the debug map have
- // been matched up, FinalizeOSOFileRanges() should be called.
- //------------------------------------------------------------------
- bool
- AddOSOFileRange (CompileUnitInfo *cu_info,
- lldb::addr_t exe_file_addr,
- lldb::addr_t exe_byte_size,
- lldb::addr_t oso_file_addr,
- lldb::addr_t oso_byte_size);
-
- //------------------------------------------------------------------
- // Called after calling AddOSOFileRange() for each object file debug
- // map entry to finalize the info for the unlinked compile unit.
- //------------------------------------------------------------------
- void
- FinalizeOSOFileRanges (CompileUnitInfo *cu_info);
-
- //------------------------------------------------------------------
- /// Convert \a addr from a .o file address, to an executable address.
- ///
- /// @param[in] addr
- /// A section offset address from a .o file
- ///
- /// @return
- /// Returns true if \a addr was converted to be an executable
- /// section/offset address, false otherwise.
- //------------------------------------------------------------------
- bool
- LinkOSOAddress (lldb_private::Address &addr);
-
- //------------------------------------------------------------------
- /// Convert a .o file "file address" to an executable "file address".
- ///
- /// @param[in] oso_symfile
- /// The DWARF symbol file that contains \a oso_file_addr
- ///
- /// @param[in] oso_file_addr
- /// A .o file "file address" to convert.
- ///
- /// @return
- /// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
- /// linked executable, otherwise a valid "file address" from the
- /// linked executable that contains the debug map.
- //------------------------------------------------------------------
- lldb::addr_t
- LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr);
-
- //------------------------------------------------------------------
- /// Given a line table full of lines with "file addresses" that are
- /// for a .o file represented by \a oso_symfile, link a new line table
- /// and return it.
- ///
- /// @param[in] oso_symfile
- /// The DWARF symbol file that produced the \a line_table
- ///
- /// @param[in] addr
- /// A section offset address from a .o file
- ///
- /// @return
- /// Returns a valid line table full of linked addresses, or NULL
- /// if none of the line table addresses exist in the main
- /// executable.
- //------------------------------------------------------------------
- lldb_private::LineTable *
- LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
- lldb_private::LineTable *line_table);
-
- size_t
- AddOSOARanges (SymbolFileDWARF* dwarf2Data,
- DWARFDebugAranges* debug_aranges);
+
+ lldb::addr_t GetOSOFileAddress() const { return m_oso_file_addr; }
+
+ void SetOSOFileAddress(lldb::addr_t oso_file_addr) {
+ m_oso_file_addr = oso_file_addr;
+ }
+
+ protected:
+ uint32_t m_exe_sym_idx;
+ lldb::addr_t m_oso_file_addr;
+ };
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry>
+ DebugMap;
+
+ //------------------------------------------------------------------
+ // Member Variables
+ //------------------------------------------------------------------
+ std::bitset<kNumFlags> m_flags;
+ std::vector<CompileUnitInfo> m_compile_unit_infos;
+ std::vector<uint32_t> m_func_indexes; // Sorted by address
+ std::vector<uint32_t> m_glob_indexes;
+ std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
+ UniqueDWARFASTTypeMap m_unique_ast_type_map;
+ lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+ DebugMap m_debug_map;
+
+ //------------------------------------------------------------------
+ // When an object file from the debug map gets parsed in
+ // SymbolFileDWARF, it needs to tell the debug map about the object
+ // files addresses by calling this function once for each N_FUN,
+ // N_GSYM and N_STSYM and after all entries in the debug map have
+ // been matched up, FinalizeOSOFileRanges() should be called.
+ //------------------------------------------------------------------
+ bool AddOSOFileRange(CompileUnitInfo *cu_info, lldb::addr_t exe_file_addr,
+ lldb::addr_t exe_byte_size, lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size);
+
+ //------------------------------------------------------------------
+ // Called after calling AddOSOFileRange() for each object file debug
+ // map entry to finalize the info for the unlinked compile unit.
+ //------------------------------------------------------------------
+ void FinalizeOSOFileRanges(CompileUnitInfo *cu_info);
+
+ //------------------------------------------------------------------
+ /// Convert \a addr from a .o file address, to an executable address.
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns true if \a addr was converted to be an executable
+ /// section/offset address, false otherwise.
+ //------------------------------------------------------------------
+ bool LinkOSOAddress(lldb_private::Address &addr);
+
+ //------------------------------------------------------------------
+ /// Convert a .o file "file address" to an executable "file address".
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that contains \a oso_file_addr
+ ///
+ /// @param[in] oso_file_addr
+ /// A .o file "file address" to convert.
+ ///
+ /// @return
+ /// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
+ /// linked executable, otherwise a valid "file address" from the
+ /// linked executable that contains the debug map.
+ //------------------------------------------------------------------
+ lldb::addr_t LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
+ lldb::addr_t oso_file_addr);
+
+ //------------------------------------------------------------------
+ /// Given a line table full of lines with "file addresses" that are
+ /// for a .o file represented by \a oso_symfile, link a new line table
+ /// and return it.
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that produced the \a line_table
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns a valid line table full of linked addresses, or NULL
+ /// if none of the line table addresses exist in the main
+ /// executable.
+ //------------------------------------------------------------------
+ lldb_private::LineTable *
+ LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
+ lldb_private::LineTable *line_table);
+
+ size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data,
+ DWARFDebugAranges *debug_aranges);
};
#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 14603aa460c9..c14ebd1628be 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -20,120 +20,103 @@
using namespace lldb;
using namespace lldb_private;
-SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu) :
- SymbolFileDWARF(objfile.get()),
- m_obj_file_sp(objfile),
- m_base_dwarf_cu(dwarf_cu)
-{
- SetID(((lldb::user_id_t)dwarf_cu->GetOffset())<<32);
+SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
+ DWARFCompileUnit *dwarf_cu)
+ : SymbolFileDWARF(objfile.get()), m_obj_file_sp(objfile),
+ m_base_dwarf_cu(dwarf_cu) {
+ SetID(((lldb::user_id_t)dwarf_cu->GetOffset()) << 32);
}
-void
-SymbolFileDWARFDwo::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data)
-{
- const SectionList* section_list = m_obj_file->GetSectionList(false /* update_module_section_list */);
- if (section_list)
- {
- SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
- if (section_sp)
- {
- // See if we memory mapped the DWARF segment?
- if (m_dwarf_data.GetByteSize())
- {
- data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize());
- return;
- }
-
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
- return;
-
- data.Clear();
- }
+void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
+ DWARFDataExtractor &data) {
+ const SectionList *section_list =
+ m_obj_file->GetSectionList(false /* update_module_section_list */);
+ if (section_list) {
+ SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
+ if (section_sp) {
+ // See if we memory mapped the DWARF segment?
+ if (m_dwarf_data.GetByteSize()) {
+ data.SetData(m_dwarf_data, section_sp->GetOffset(),
+ section_sp->GetFileSize());
+ return;
+ }
+
+ if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+ return;
+
+ data.Clear();
}
+ }
- SymbolFileDWARF::LoadSectionData(sect_type, data);
+ SymbolFileDWARF::LoadSectionData(sect_type, data);
}
lldb::CompUnitSP
-SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
-{
- assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible compile unit");
- return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX);
+SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) {
+ assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit "
+ "called with incompatible compile "
+ "unit");
+ return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX);
}
-DWARFCompileUnit*
-SymbolFileDWARFDwo::GetCompileUnit()
-{
- // Only dwo files with 1 compile unit is supported
- if (GetNumCompileUnits() == 1)
- return DebugInfo()->GetCompileUnitAtIndex(0);
- else
- return nullptr;
+DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
+ // Only dwo files with 1 compile unit is supported
+ if (GetNumCompileUnits() == 1)
+ return DebugInfo()->GetCompileUnitAtIndex(0);
+ else
+ return nullptr;
}
-DWARFCompileUnit*
-SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
-{
- return GetCompileUnit();
+DWARFCompileUnit *
+SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
+ return GetCompileUnit();
}
-SymbolFileDWARF::DIEToTypePtr&
-SymbolFileDWARFDwo::GetDIEToType()
-{
- return GetBaseSymbolFile()->GetDIEToType();
+SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() {
+ return GetBaseSymbolFile()->GetDIEToType();
}
-SymbolFileDWARF::DIEToVariableSP&
-SymbolFileDWARFDwo::GetDIEToVariable()
-{
- return GetBaseSymbolFile()->GetDIEToVariable();
+SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
+ return GetBaseSymbolFile()->GetDIEToVariable();
}
-SymbolFileDWARF::DIEToClangType&
-SymbolFileDWARFDwo::GetForwardDeclDieToClangType()
-{
- return GetBaseSymbolFile()->GetForwardDeclDieToClangType();
+SymbolFileDWARF::DIEToClangType &
+SymbolFileDWARFDwo::GetForwardDeclDieToClangType() {
+ return GetBaseSymbolFile()->GetForwardDeclDieToClangType();
}
-SymbolFileDWARF::ClangTypeToDIE&
-SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie()
-{
- return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie();
+SymbolFileDWARF::ClangTypeToDIE &
+SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
+ return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie();
}
-UniqueDWARFASTTypeMap&
-SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap()
-{
- return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap();
+UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
+ return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap();
}
-lldb::TypeSP
-SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
-{
- return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &die_decl_ctx) {
+ return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
}
-SymbolFileDWARF*
-SymbolFileDWARFDwo::GetBaseSymbolFile()
-{
- return m_base_dwarf_cu->GetSymbolFileDWARF();
+SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() {
+ return m_base_dwarf_cu->GetSymbolFileDWARF();
}
DWARFExpression::LocationListFormat
-SymbolFileDWARFDwo::GetLocationListFormat() const
-{
- return DWARFExpression::SplitDwarfLocationList;
+SymbolFileDWARFDwo::GetLocationListFormat() const {
+ return DWARFExpression::SplitDwarfLocationList;
}
-TypeSystem*
-SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language)
-{
- return GetBaseSymbolFile()->GetTypeSystemForLanguage(language);
+TypeSystem *
+SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
+ return GetBaseSymbolFile()->GetTypeSystemForLanguage(language);
}
DWARFDIE
-SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref)
-{
- lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset);
- return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset);
+SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
+ lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset);
+ return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset);
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 9391a2824948..8cd67a2b2424 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -16,64 +16,56 @@
// Project includes
#include "SymbolFileDWARF.h"
-class SymbolFileDWARFDwo : public SymbolFileDWARF
-{
+class SymbolFileDWARFDwo : public SymbolFileDWARF {
public:
- SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu);
+ SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit *dwarf_cu);
- ~SymbolFileDWARFDwo() override = default;
-
- lldb::CompUnitSP
- ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) override;
+ ~SymbolFileDWARFDwo() override = default;
- DWARFCompileUnit*
- GetCompileUnit();
+ lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) override;
- DWARFCompileUnit*
- GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
+ DWARFCompileUnit *GetCompileUnit();
- lldb_private::DWARFExpression::LocationListFormat
- GetLocationListFormat() const override;
+ DWARFCompileUnit *
+ GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
- lldb_private::TypeSystem*
- GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ lldb_private::DWARFExpression::LocationListFormat
+ GetLocationListFormat() const override;
- DWARFDIE
- GetDIE(const DIERef &die_ref) override;
+ lldb_private::TypeSystem *
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
- std::unique_ptr<SymbolFileDWARFDwo>
- GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) override
- {
- return nullptr;
- }
+ DWARFDIE
+ GetDIE(const DIERef &die_ref) override;
+
+ std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu,
+ const DWARFDebugInfoEntry &cu_die) override {
+ return nullptr;
+ }
protected:
- void
- LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data) override;
+ void LoadSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data) override;
+
+ DIEToTypePtr &GetDIEToType() override;
- DIEToTypePtr&
- GetDIEToType() override;
+ DIEToVariableSP &GetDIEToVariable() override;
- DIEToVariableSP&
- GetDIEToVariable() override;
-
- DIEToClangType&
- GetForwardDeclDieToClangType() override;
+ DIEToClangType &GetForwardDeclDieToClangType() override;
- ClangTypeToDIE&
- GetForwardDeclClangTypeToDie() override;
+ ClangTypeToDIE &GetForwardDeclClangTypeToDie() override;
- UniqueDWARFASTTypeMap&
- GetUniqueDWARFASTTypeMap() override;
+ UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() override;
- lldb::TypeSP
- FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) override;
+ lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &die_decl_ctx) override;
- SymbolFileDWARF*
- GetBaseSymbolFile();
+ SymbolFileDWARF *GetBaseSymbolFile();
- lldb::ObjectFileSP m_obj_file_sp;
- DWARFCompileUnit* m_base_dwarf_cu;
+ lldb::ObjectFileSP m_obj_file_sp;
+ DWARFCompileUnit *m_base_dwarf_cu;
};
#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 2ca407b9e48a..8697e08dbf86 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -15,73 +15,63 @@
// Project includes
#include "lldb/Symbol/Declaration.h"
-bool
-UniqueDWARFASTTypeList::Find (const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- const int32_t byte_size,
- UniqueDWARFASTType &entry) const
-{
- for (const UniqueDWARFASTType &udt : m_collection)
- {
- // Make sure the tags match
- if (udt.m_die.Tag() == die.Tag())
- {
- // Validate byte sizes of both types only if both are valid.
- if (udt.m_byte_size < 0 || byte_size < 0 || udt.m_byte_size == byte_size)
- {
- // Make sure the file and line match
- if (udt.m_declaration == decl)
+bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
+ const lldb_private::Declaration &decl,
+ const int32_t byte_size,
+ UniqueDWARFASTType &entry) const {
+ for (const UniqueDWARFASTType &udt : m_collection) {
+ // Make sure the tags match
+ if (udt.m_die.Tag() == die.Tag()) {
+ // Validate byte sizes of both types only if both are valid.
+ if (udt.m_byte_size < 0 || byte_size < 0 ||
+ udt.m_byte_size == byte_size) {
+ // Make sure the file and line match
+ if (udt.m_declaration == decl) {
+ // The type has the same name, and was defined on the same
+ // file and line. Now verify all of the parent DIEs match.
+ DWARFDIE parent_arg_die = die.GetParent();
+ DWARFDIE parent_pos_die = udt.m_die.GetParent();
+ bool match = true;
+ bool done = false;
+ while (!done && match && parent_arg_die && parent_pos_die) {
+ const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
+ const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
+ if (parent_arg_tag == parent_pos_tag) {
+ switch (parent_arg_tag) {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_namespace: {
+ const char *parent_arg_die_name = parent_arg_die.GetName();
+ if (parent_arg_die_name ==
+ NULL) // Anonymous (i.e. no-name) struct
{
- // The type has the same name, and was defined on the same
- // file and line. Now verify all of the parent DIEs match.
- DWARFDIE parent_arg_die = die.GetParent();
- DWARFDIE parent_pos_die = udt.m_die.GetParent();
- bool match = true;
- bool done = false;
- while (!done && match && parent_arg_die && parent_pos_die)
- {
- const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
- const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
- if (parent_arg_tag == parent_pos_tag)
- {
- switch (parent_arg_tag)
- {
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_namespace:
- {
- const char *parent_arg_die_name = parent_arg_die.GetName();
- if (parent_arg_die_name == NULL) // Anonymous (i.e. no-name) struct
- {
- match = false;
- }
- else
- {
- const char *parent_pos_die_name = parent_pos_die.GetName();
- if (parent_pos_die_name == NULL || ((parent_arg_die_name != parent_pos_die_name) && strcmp (parent_arg_die_name, parent_pos_die_name)))
- match = false;
- }
- }
- break;
-
- case DW_TAG_compile_unit:
- done = true;
- break;
- }
- }
- parent_arg_die = parent_arg_die.GetParent();
- parent_pos_die = parent_pos_die.GetParent();
- }
-
- if (match)
- {
- entry = udt;
- return true;
- }
+ match = false;
+ } else {
+ const char *parent_pos_die_name = parent_pos_die.GetName();
+ if (parent_pos_die_name == NULL ||
+ ((parent_arg_die_name != parent_pos_die_name) &&
+ strcmp(parent_arg_die_name, parent_pos_die_name)))
+ match = false;
}
+ } break;
+
+ case DW_TAG_compile_unit:
+ done = true;
+ break;
+ }
}
+ parent_arg_die = parent_arg_die.GetParent();
+ parent_pos_die = parent_pos_die.GetParent();
+ }
+
+ if (match) {
+ entry = udt;
+ return true;
+ }
}
+ }
}
- return false;
+ }
+ return false;
}
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index b7b18efd8769..5d51044cbe1a 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -18,139 +18,93 @@
#include "llvm/ADT/DenseMap.h"
// Project includes
-#include "lldb/Symbol/Declaration.h"
#include "DWARFDIE.h"
+#include "lldb/Symbol/Declaration.h"
-class UniqueDWARFASTType
-{
+class UniqueDWARFASTType {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- UniqueDWARFASTType () :
- m_type_sp (),
- m_die (),
- m_declaration (),
- m_byte_size (-1) // Set to negative value to make sure we have a valid value
- {
- }
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ UniqueDWARFASTType()
+ : m_type_sp(), m_die(), m_declaration(),
+ m_byte_size(
+ -1) // Set to negative value to make sure we have a valid value
+ {}
- UniqueDWARFASTType (lldb::TypeSP &type_sp,
- const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- int32_t byte_size) :
- m_type_sp (type_sp),
- m_die (die),
- m_declaration (decl),
- m_byte_size (byte_size)
- {
- }
-
- UniqueDWARFASTType (const UniqueDWARFASTType &rhs) :
- m_type_sp (rhs.m_type_sp),
- m_die (rhs.m_die),
- m_declaration (rhs.m_declaration),
- m_byte_size (rhs.m_byte_size)
- {
- }
+ UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die,
+ const lldb_private::Declaration &decl, int32_t byte_size)
+ : m_type_sp(type_sp), m_die(die), m_declaration(decl),
+ m_byte_size(byte_size) {}
- ~UniqueDWARFASTType()
- {
- }
+ UniqueDWARFASTType(const UniqueDWARFASTType &rhs)
+ : m_type_sp(rhs.m_type_sp), m_die(rhs.m_die),
+ m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {}
+
+ ~UniqueDWARFASTType() {}
- UniqueDWARFASTType &
- operator= (const UniqueDWARFASTType &rhs)
- {
- if (this != &rhs)
- {
- m_type_sp = rhs.m_type_sp;
- m_die = rhs.m_die;
- m_declaration = rhs.m_declaration;
- m_byte_size = rhs.m_byte_size;
- }
- return *this;
+ UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) {
+ if (this != &rhs) {
+ m_type_sp = rhs.m_type_sp;
+ m_die = rhs.m_die;
+ m_declaration = rhs.m_declaration;
+ m_byte_size = rhs.m_byte_size;
}
+ return *this;
+ }
- lldb::TypeSP m_type_sp;
- DWARFDIE m_die;
- lldb_private::Declaration m_declaration;
- int32_t m_byte_size;
+ lldb::TypeSP m_type_sp;
+ DWARFDIE m_die;
+ lldb_private::Declaration m_declaration;
+ int32_t m_byte_size;
};
-class UniqueDWARFASTTypeList
-{
+class UniqueDWARFASTTypeList {
public:
- UniqueDWARFASTTypeList () :
- m_collection()
- {
- }
-
- ~UniqueDWARFASTTypeList ()
- {
- }
-
- uint32_t
- GetSize()
- {
- return (uint32_t)m_collection.size();
- }
-
- void
- Append (const UniqueDWARFASTType &entry)
- {
- m_collection.push_back (entry);
- }
-
- bool
- Find (const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- const int32_t byte_size,
- UniqueDWARFASTType &entry) const;
-
+ UniqueDWARFASTTypeList() : m_collection() {}
+
+ ~UniqueDWARFASTTypeList() {}
+
+ uint32_t GetSize() { return (uint32_t)m_collection.size(); }
+
+ void Append(const UniqueDWARFASTType &entry) {
+ m_collection.push_back(entry);
+ }
+
+ bool Find(const DWARFDIE &die, const lldb_private::Declaration &decl,
+ const int32_t byte_size, UniqueDWARFASTType &entry) const;
+
protected:
- typedef std::vector<UniqueDWARFASTType> collection;
- collection m_collection;
+ typedef std::vector<UniqueDWARFASTType> collection;
+ collection m_collection;
};
-class UniqueDWARFASTTypeMap
-{
+class UniqueDWARFASTTypeMap {
public:
- UniqueDWARFASTTypeMap () :
- m_collection ()
- {
- }
-
- ~UniqueDWARFASTTypeMap ()
- {
- }
+ UniqueDWARFASTTypeMap() : m_collection() {}
- void
- Insert (const lldb_private::ConstString &name,
- const UniqueDWARFASTType &entry)
- {
- m_collection[name.GetCString()].Append (entry);
- }
+ ~UniqueDWARFASTTypeMap() {}
+
+ void Insert(const lldb_private::ConstString &name,
+ const UniqueDWARFASTType &entry) {
+ m_collection[name.GetCString()].Append(entry);
+ }
- bool
- Find (const lldb_private::ConstString &name,
- const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- const int32_t byte_size,
- UniqueDWARFASTType &entry) const
- {
- const char *unique_name_cstr = name.GetCString();
- collection::const_iterator pos = m_collection.find (unique_name_cstr);
- if (pos != m_collection.end())
- {
- return pos->second.Find (die, decl, byte_size, entry);
- }
- return false;
+ bool Find(const lldb_private::ConstString &name, const DWARFDIE &die,
+ const lldb_private::Declaration &decl, const int32_t byte_size,
+ UniqueDWARFASTType &entry) const {
+ const char *unique_name_cstr = name.GetCString();
+ collection::const_iterator pos = m_collection.find(unique_name_cstr);
+ if (pos != m_collection.end()) {
+ return pos->second.Find(die, decl, byte_size, entry);
}
+ return false;
+ }
protected:
- // A unique name string should be used
- typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection;
- collection m_collection;
+ // A unique name string should be used
+ typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection;
+ collection m_collection;
};
-#endif // lldb_UniqueDWARFASTType_h_
+#endif // lldb_UniqueDWARFASTType_h_
diff --git a/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
index 79d8a25d6979..55aaadaf191b 100644
--- a/source/Plugins/SymbolFile/PDB/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_PRIVATE_LINK_COMPONENTS
+set(LLVM_LINK_COMPONENTS
DebugInfoPDB)
add_lldb_library(lldbPluginSymbolFilePDB
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 1e8e040fd47c..b48de2e591e3 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -34,204 +34,199 @@ using namespace lldb_private;
using namespace llvm;
using namespace llvm::pdb;
-namespace
-{
-int
-TranslateUdtKind(PDB_UdtType pdb_kind)
-{
- switch (pdb_kind)
- {
- case PDB_UdtType::Class:
- return clang::TTK_Class;
- case PDB_UdtType::Struct:
- return clang::TTK_Struct;
- case PDB_UdtType::Union:
- return clang::TTK_Union;
- case PDB_UdtType::Interface:
- return clang::TTK_Interface;
- }
+namespace {
+int TranslateUdtKind(PDB_UdtType pdb_kind) {
+ switch (pdb_kind) {
+ case PDB_UdtType::Class:
return clang::TTK_Class;
+ case PDB_UdtType::Struct:
+ return clang::TTK_Struct;
+ case PDB_UdtType::Union:
+ return clang::TTK_Union;
+ case PDB_UdtType::Interface:
+ return clang::TTK_Interface;
+ }
+ return clang::TTK_Class;
}
-lldb::Encoding
-TranslateBuiltinEncoding(PDB_BuiltinType type)
-{
- switch (type)
- {
- case PDB_BuiltinType::Float:
- return lldb::eEncodingIEEE754;
- case PDB_BuiltinType::Int:
- case PDB_BuiltinType::Long:
- case PDB_BuiltinType::Char:
- return lldb::eEncodingSint;
- case PDB_BuiltinType::Bool:
- case PDB_BuiltinType::UInt:
- case PDB_BuiltinType::ULong:
- case PDB_BuiltinType::HResult:
- return lldb::eEncodingUint;
- default:
- return lldb::eEncodingInvalid;
- }
+lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
+ switch (type) {
+ case PDB_BuiltinType::Float:
+ return lldb::eEncodingIEEE754;
+ case PDB_BuiltinType::Int:
+ case PDB_BuiltinType::Long:
+ case PDB_BuiltinType::Char:
+ return lldb::eEncodingSint;
+ case PDB_BuiltinType::Bool:
+ case PDB_BuiltinType::UInt:
+ case PDB_BuiltinType::ULong:
+ case PDB_BuiltinType::HResult:
+ return lldb::eEncodingUint;
+ default:
+ return lldb::eEncodingInvalid;
+ }
}
}
-PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast)
-{
-}
+PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {}
-PDBASTParser::~PDBASTParser()
-{
-}
+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;
-
- if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type))
- {
- AccessType access = lldb::eAccessPublic;
- PDB_UdtType udt_kind = udt->getUdtKind();
-
- if (udt_kind == PDB_UdtType::Class)
- access = lldb::eAccessPrivate;
-
- CompilerType clang_type =
- m_ast.CreateRecordType(tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind),
- lldb::eLanguageTypeC_plus_plus, nullptr);
-
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
-
- return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(udt->getName()),
- udt->getLength(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
- clang_type, Type::eResolveStateForward);
- }
- else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type))
- {
- std::string name = enum_type->getName();
- lldb::Encoding encoding = TranslateBuiltinEncoding(enum_type->getBuiltinType());
- uint64_t bytes = enum_type->getLength();
- CompilerType builtin_type = m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
-
- CompilerType ast_enum = m_ast.CreateEnumerationType(name.c_str(), tu_decl_ctx, decl, builtin_type);
- auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
- while (auto enum_value = enum_values->getNext())
- {
- if (enum_value->getDataKind() != PDB_DataKind::Constant)
- continue;
- AddEnumValue(ast_enum, *enum_value);
- }
-
- return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ast_enum, Type::eResolveStateFull);
+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;
+
+ if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type)) {
+ AccessType access = lldb::eAccessPublic;
+ PDB_UdtType udt_kind = udt->getUdtKind();
+
+ if (udt_kind == PDB_UdtType::Class)
+ access = lldb::eAccessPrivate;
+
+ CompilerType clang_type = m_ast.CreateRecordType(
+ tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind),
+ lldb::eLanguageTypeC_plus_plus, nullptr);
+
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(),
+ ConstString(udt->getName()), udt->getLength(),
+ nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, clang_type,
+ Type::eResolveStateForward);
+ } else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type)) {
+ std::string name = enum_type->getName();
+ lldb::Encoding encoding =
+ TranslateBuiltinEncoding(enum_type->getBuiltinType());
+ uint64_t bytes = enum_type->getLength();
+ CompilerType builtin_type =
+ m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
+
+ CompilerType ast_enum = m_ast.CreateEnumerationType(
+ name.c_str(), tu_decl_ctx, decl, builtin_type);
+ auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
+ while (auto enum_value = enum_values->getNext()) {
+ if (enum_value->getDataKind() != PDB_DataKind::Constant)
+ continue;
+ AddEnumValue(ast_enum, *enum_value);
}
- else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type))
- {
- Type *target_type = m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
- std::string name = type_def->getName();
- uint64_t bytes = type_def->getLength();
- if (!target_type)
- return nullptr;
- CompilerType target_ast_type = target_type->GetFullCompilerType();
- CompilerDeclContext target_decl_ctx = m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
- CompilerType ast_typedef = m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
- return std::make_shared<Type>(type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
- nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl, ast_typedef,
- Type::eResolveStateFull);
- }
- else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type))
- {
- auto arg_enum = func_sig->getArguments();
- uint32_t num_args = arg_enum->getChildCount();
- std::vector<CompilerType> arg_list(num_args);
- while (auto arg = arg_enum->getNext())
- {
- Type *arg_type = m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
- // If there's some error looking up one of the dependent types of this function signature, bail.
- if (!arg_type)
- return nullptr;
- CompilerType arg_ast_type = arg_type->GetFullCompilerType();
- arg_list.push_back(arg_ast_type);
- }
- auto pdb_return_type = func_sig->getReturnType();
- Type *return_type = m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
- // If there's some error looking up one of the dependent types of this function signature, bail.
- if (!return_type)
- return nullptr;
- CompilerType return_ast_type = return_type->GetFullCompilerType();
- uint32_t type_quals = 0;
- if (func_sig->isConstType())
- type_quals |= clang::Qualifiers::Const;
- if (func_sig->isVolatileType())
- type_quals |= clang::Qualifiers::Volatile;
- CompilerType func_sig_ast_type =
- m_ast.CreateFunctionType(return_ast_type, &arg_list[0], num_args, false, type_quals);
-
- return std::make_shared<Type>(func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_sig_ast_type,
- Type::eResolveStateFull);
- }
- else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type))
- {
- uint32_t num_elements = array_type->getCount();
- uint32_t element_uid = array_type->getElementType()->getSymIndexId();
- uint32_t bytes = array_type->getLength();
-
- Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
- CompilerType element_ast_type = element_type->GetFullCompilerType();
- CompilerType array_ast_type = m_ast.CreateArrayType(element_ast_type, num_elements, false);
- return std::make_shared<Type>(array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), bytes, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl, array_ast_type,
- Type::eResolveStateFull);
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(),
+ ConstString(name), bytes, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ ast_enum, Type::eResolveStateFull);
+ } else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type)) {
+ Type *target_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
+ std::string name = type_def->getName();
+ uint64_t bytes = type_def->getLength();
+ if (!target_type)
+ return nullptr;
+ CompilerType target_ast_type = target_type->GetFullCompilerType();
+ CompilerDeclContext target_decl_ctx =
+ m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
+ CompilerType ast_typedef =
+ m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
+ return std::make_shared<Type>(
+ type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
+ bytes, nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl,
+ ast_typedef, Type::eResolveStateFull);
+ } else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
+ auto arg_enum = func_sig->getArguments();
+ uint32_t num_args = arg_enum->getChildCount();
+ std::vector<CompilerType> arg_list(num_args);
+ while (auto arg = arg_enum->getNext()) {
+ Type *arg_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this
+ // function signature, bail.
+ if (!arg_type)
+ return nullptr;
+ CompilerType arg_ast_type = arg_type->GetFullCompilerType();
+ arg_list.push_back(arg_ast_type);
}
- return nullptr;
+ auto pdb_return_type = func_sig->getReturnType();
+ Type *return_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this
+ // function signature, bail.
+ if (!return_type)
+ return nullptr;
+ CompilerType return_ast_type = return_type->GetFullCompilerType();
+ uint32_t type_quals = 0;
+ if (func_sig->isConstType())
+ type_quals |= clang::Qualifiers::Const;
+ if (func_sig->isVolatileType())
+ type_quals |= clang::Qualifiers::Volatile;
+ CompilerType func_sig_ast_type = m_ast.CreateFunctionType(
+ return_ast_type, &arg_list[0], num_args, false, type_quals);
+
+ return std::make_shared<Type>(
+ func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0,
+ nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ func_sig_ast_type, Type::eResolveStateFull);
+ } else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type)) {
+ uint32_t num_elements = array_type->getCount();
+ uint32_t element_uid = array_type->getElementType()->getSymIndexId();
+ uint32_t bytes = array_type->getLength();
+
+ Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+ CompilerType element_ast_type = element_type->GetFullCompilerType();
+ CompilerType array_ast_type =
+ m_ast.CreateArrayType(element_ast_type, num_elements, false);
+ return std::make_shared<Type>(
+ array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
+ bytes, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ array_ast_type, Type::eResolveStateFull);
+ }
+ return nullptr;
}
-bool
-PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) const
-{
- Declaration decl;
- Variant v = enum_value.getValue();
- std::string name = enum_value.getName();
- int64_t raw_value;
- switch (v.Type)
- {
- case PDB_VariantType::Int8:
- raw_value = v.Value.Int8;
- break;
- case PDB_VariantType::Int16:
- raw_value = v.Value.Int16;
- break;
- case PDB_VariantType::Int32:
- raw_value = v.Value.Int32;
- break;
- case PDB_VariantType::Int64:
- raw_value = v.Value.Int64;
- break;
- case PDB_VariantType::UInt8:
- raw_value = v.Value.UInt8;
- break;
- case PDB_VariantType::UInt16:
- raw_value = v.Value.UInt16;
- break;
- case PDB_VariantType::UInt32:
- raw_value = v.Value.UInt32;
- break;
- case PDB_VariantType::UInt64:
- raw_value = v.Value.UInt64;
- break;
- default:
- return false;
- }
- CompilerType underlying_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);
+bool PDBASTParser::AddEnumValue(CompilerType enum_type,
+ const PDBSymbolData &enum_value) const {
+ Declaration decl;
+ Variant v = enum_value.getValue();
+ std::string name = enum_value.getName();
+ int64_t raw_value;
+ switch (v.Type) {
+ case PDB_VariantType::Int8:
+ raw_value = v.Value.Int8;
+ break;
+ case PDB_VariantType::Int16:
+ raw_value = v.Value.Int16;
+ break;
+ case PDB_VariantType::Int32:
+ raw_value = v.Value.Int32;
+ break;
+ case PDB_VariantType::Int64:
+ raw_value = v.Value.Int64;
+ break;
+ case PDB_VariantType::UInt8:
+ raw_value = v.Value.UInt8;
+ break;
+ case PDB_VariantType::UInt16:
+ raw_value = v.Value.UInt16;
+ break;
+ case PDB_VariantType::UInt32:
+ raw_value = v.Value.UInt32;
+ break;
+ case PDB_VariantType::UInt64:
+ raw_value = v.Value.UInt64;
+ break;
+ default:
+ return false;
+ }
+ CompilerType underlying_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);
}
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
index ca425c17c451..e9ff02c0a77e 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.h
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
@@ -14,45 +14,39 @@
#include "lldb/Symbol/ClangASTImporter.h"
-namespace clang
-{
+namespace clang {
class CharUnits;
class CXXRecordDecl;
class FieldDecl;
class RecordDecl;
}
-namespace lldb_private
-{
+namespace lldb_private {
class ClangASTContext;
class CompilerType;
}
-namespace llvm
-{
-namespace pdb
-{
+namespace llvm {
+namespace pdb {
class PDBSymbol;
class PDBSymbolData;
class PDBSymbolTypeBuiltin;
}
}
-class PDBASTParser
-{
+class PDBASTParser {
public:
- PDBASTParser(lldb_private::ClangASTContext &ast);
- ~PDBASTParser();
+ PDBASTParser(lldb_private::ClangASTContext &ast);
+ ~PDBASTParser();
- lldb::TypeSP
- CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
+ lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
private:
- bool
- AddEnumValue(lldb_private::CompilerType enum_type, const llvm::pdb::PDBSymbolData &data) const;
+ bool AddEnumValue(lldb_private::CompilerType enum_type,
+ const llvm::pdb::PDBSymbolData &data) const;
- lldb_private::ClangASTContext &m_ast;
- lldb_private::ClangASTImporter m_ast_importer;
+ lldb_private::ClangASTContext &m_ast;
+ lldb_private::ClangASTImporter m_ast_importer;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index d8092c011acb..cd99493c239a 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -42,692 +42,661 @@
using namespace lldb_private;
using namespace llvm::pdb;
-namespace
-{
-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;
- }
- }
-
- bool
- ShouldAddLine(uint32_t requested_line, uint32_t actual_line, uint32_t addr_length)
- {
- return ((requested_line == 0 || actual_line == requested_line) && addr_length > 0);
- }
+namespace {
+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;
+ }
}
-void
-SymbolFilePDB::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
- DebuggerInitialize);
+bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
+ uint32_t addr_length) {
+ return ((requested_line == 0 || actual_line == requested_line) &&
+ addr_length > 0);
}
-
-void
-SymbolFilePDB::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
}
-void
-SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger)
-{
+void SymbolFilePDB::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
}
-lldb_private::ConstString
-SymbolFilePDB::GetPluginNameStatic()
-{
- static ConstString g_name("pdb");
- return g_name;
+void SymbolFilePDB::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-const char *
-SymbolFilePDB::GetPluginDescriptionStatic()
-{
- return "Microsoft PDB debug symbol file reader.";
-}
+void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
-lldb_private::SymbolFile *
-SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file)
-{
- return new SymbolFilePDB(obj_file);
+lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() {
+ static ConstString g_name("pdb");
+ return g_name;
}
-SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
- : SymbolFile(object_file), m_cached_compile_unit_count(0)
-{
+const char *SymbolFilePDB::GetPluginDescriptionStatic() {
+ return "Microsoft PDB debug symbol file reader.";
}
-SymbolFilePDB::~SymbolFilePDB()
-{
+lldb_private::SymbolFile *
+SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
+ return new SymbolFilePDB(obj_file);
}
-uint32_t
-SymbolFilePDB::CalculateAbilities()
-{
- if (!m_session_up)
- {
- // Lazily load and match the PDB file, but only do this once.
- std::string exePath = m_obj_file->GetFileSpec().GetPath();
- auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), m_session_up);
- if (error)
- {
- llvm::consumeError(std::move(error));
- return 0;
- }
+SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
+ : SymbolFile(object_file), m_cached_compile_unit_count(0) {}
+
+SymbolFilePDB::~SymbolFilePDB() {}
+
+uint32_t SymbolFilePDB::CalculateAbilities() {
+ if (!m_session_up) {
+ // Lazily load and match the PDB file, but only do this once.
+ std::string exePath = m_obj_file->GetFileSpec().GetPath();
+ auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
+ m_session_up);
+ if (error) {
+ llvm::consumeError(std::move(error));
+ return 0;
}
- return CompileUnits | LineTables;
+ }
+ return CompileUnits | LineTables;
}
-void
-SymbolFilePDB::InitializeObject()
-{
- lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
- m_session_up->setLoadAddress(obj_load_address);
+void SymbolFilePDB::InitializeObject() {
+ lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
+ m_session_up->setLoadAddress(obj_load_address);
- TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(type_system, clang_type_system->GetTranslationUnitDecl());
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
+ type_system, clang_type_system->GetTranslationUnitDecl());
}
-uint32_t
-SymbolFilePDB::GetNumCompileUnits()
-{
- if (m_cached_compile_unit_count == 0)
- {
- auto global = m_session_up->getGlobalScope();
- auto compilands = global->findAllChildren<PDBSymbolCompiland>();
- m_cached_compile_unit_count = compilands->getChildCount();
-
- // The linker can inject an additional "dummy" compilation unit into the PDB.
- // Ignore this special compile unit for our purposes, if it is there. It is
- // always the last one.
- auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
- std::string name = last_cu->getName();
- if (name == "* Linker *")
- --m_cached_compile_unit_count;
- }
- return m_cached_compile_unit_count;
-}
-
-lldb::CompUnitSP
-SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index)
-{
+uint32_t SymbolFilePDB::GetNumCompileUnits() {
+ if (m_cached_compile_unit_count == 0) {
auto global = m_session_up->getGlobalScope();
auto compilands = global->findAllChildren<PDBSymbolCompiland>();
- auto cu = compilands->getChildAtIndex(index);
+ m_cached_compile_unit_count = compilands->getChildCount();
+
+ // The linker can inject an additional "dummy" compilation unit into the
+ // PDB.
+ // Ignore this special compile unit for our purposes, if it is there. It is
+ // always the last one.
+ auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
+ std::string name = last_cu->getName();
+ if (name == "* Linker *")
+ --m_cached_compile_unit_count;
+ }
+ return m_cached_compile_unit_count;
+}
- uint32_t id = cu->getSymIndexId();
+lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
+ auto global = m_session_up->getGlobalScope();
+ auto compilands = global->findAllChildren<PDBSymbolCompiland>();
+ auto cu = compilands->getChildAtIndex(index);
- return ParseCompileUnitForSymIndex(id);
+ uint32_t id = cu->getSymIndexId();
+
+ return ParseCompileUnitForSymIndex(id);
}
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 cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
- if (!cu)
- return lldb::eLanguageTypeUnknown;
- auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
- if (!details)
- return lldb::eLanguageTypeUnknown;
- return TranslateLanguage(details->getLanguage());
-}
+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;
-size_t
-SymbolFilePDB::ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
+ sc.comp_unit->GetID());
+ if (!cu)
+ return lldb::eLanguageTypeUnknown;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ return lldb::eLanguageTypeUnknown;
+ return TranslateLanguage(details->getLanguage());
}
-bool
-SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc)
-{
- return ParseCompileUnitLineTable(sc, 0);
+size_t SymbolFilePDB::ParseCompileUnitFunctions(
+ const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
}
-bool
-SymbolFilePDB::ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc)
-{
- // PDB doesn't contain information about macros
- return false;
+bool SymbolFilePDB::ParseCompileUnitLineTable(
+ const lldb_private::SymbolContext &sc) {
+ return ParseCompileUnitLineTable(sc, 0);
}
-bool
-SymbolFilePDB::ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files)
-{
- if (!sc.comp_unit)
- return false;
-
- // In theory this is unnecessary work for us, because all of this information is easily
- // (and quickly) accessible from DebugInfoPDB, so caching it a second time seems like a waste.
- // Unfortunately, there's no good way around this short of a moderate refactor, since SymbolVendor
- // depends on being able to cache this list.
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
- if (!cu)
- return false;
- auto files = m_session_up->getSourceFilesForCompiland(*cu);
- if (!files || files->getChildCount() == 0)
- return false;
-
- while (auto file = files->getNext())
- {
- FileSpec spec(file->getFileName(), false);
- support_files.Append(spec);
- }
- return true;
+bool SymbolFilePDB::ParseCompileUnitDebugMacros(
+ const lldb_private::SymbolContext &sc) {
+ // PDB doesn't contain information about macros
+ return false;
}
-bool
-SymbolFilePDB::ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules)
-{
- // PDB does not yet support module debug info
+bool SymbolFilePDB::ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) {
+ if (!sc.comp_unit)
return false;
-}
-size_t
-SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
+ // In theory this is unnecessary work for us, because all of this information
+ // is easily
+ // (and quickly) accessible from DebugInfoPDB, so caching it a second time
+ // seems like a waste.
+ // Unfortunately, there's no good way around this short of a moderate
+ // refactor, since SymbolVendor
+ // depends on being able to cache this list.
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
+ sc.comp_unit->GetID());
+ if (!cu)
+ return false;
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+ if (!files || files->getChildCount() == 0)
+ return false;
+
+ while (auto file = files->getNext()) {
+ FileSpec spec(file->getFileName(), false);
+ support_files.Append(spec);
+ }
+ return true;
}
-size_t
-SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
+bool SymbolFilePDB::ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) {
+ // PDB does not yet support module debug info
+ return false;
}
size_t
-SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
-}
-
-lldb_private::Type *
-SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid)
-{
- auto find_result = m_types.find(type_uid);
- if (find_result != m_types.end())
- return find_result->second.get();
-
- TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- if (!clang_type_system)
- return nullptr;
- PDBASTParser *pdb = llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
- if (!pdb)
- return nullptr;
-
- auto pdb_type = m_session_up->getSymbolById(type_uid);
- if (pdb_type == nullptr)
- return nullptr;
-
- lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
- m_types.insert(std::make_pair(type_uid, result));
- return result.get();
-}
-
-bool
-SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type)
-{
- // TODO: Implement this
- return false;
+SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
}
-lldb_private::CompilerDecl
-SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid)
-{
- return lldb_private::CompilerDecl();
+size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
}
-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;
+size_t
+SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
}
-lldb_private::CompilerDeclContext
-SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid)
-{
- return *m_tu_decl_ctx_up;
-}
+lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ auto find_result = m_types.find(type_uid);
+ if (find_result != m_types.end())
+ return find_result->second.get();
-void
-SymbolFilePDB::ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)
-{
-}
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return nullptr;
+ PDBASTParser *pdb =
+ llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
+ if (!pdb)
+ return nullptr;
-uint32_t
-SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
- lldb_private::SymbolContext &sc)
-{
- return uint32_t();
-}
+ auto pdb_type = m_session_up->getSymbolById(type_uid);
+ if (pdb_type == nullptr)
+ return nullptr;
-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)
-{
- if (resolve_scope & lldb::eSymbolContextCompUnit)
- {
- // Locate all compilation units with line numbers referencing the specified file. For example, if
- // `file_spec` is <vector>, then this should return all source files and header files that reference
- // <vector>, either directly or indirectly.
- auto compilands =
- m_session_up->findCompilandsForSourceFile(file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
-
- // For each one, either find get its previously parsed data, or parse it afresh and add it to
- // the symbol context list.
- while (auto compiland = compilands->getNext())
- {
- // If we're not checking inlines, then don't add line information for this file unless the FileSpec
- // matches.
- if (!check_inlines)
- {
- // `getSourceFileName` returns the basename of the original source file used to generate this compiland.
- // It does not return the full path. Currently the only way to get that is to do a basename lookup to
- // get the IPDBSourceFile, but this is ambiguous in the case of two source files with the same name
- // contributing to the same compiland. This is a moderately extreme edge case, so we consider this ok
- // for now, although we need to find a long term solution.
- std::string source_file = compiland->getSourceFileName();
- auto pdb_file = m_session_up->findOneSourceFile(compiland.get(), source_file,
- PDB_NameSearchFlags::NS_CaseInsensitive);
- source_file = pdb_file->getFileName();
- FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
- if (!file_spec.FileEquals(this_spec))
- continue;
- }
-
- SymbolContext sc;
- auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
- sc.comp_unit = cu.get();
- sc.module_sp = cu->GetModule();
- sc_list.Append(sc);
-
- // If we were asked to resolve line entries, add all entries to the line table that match the requested
- // line (or all lines if `line` == 0)
- if (resolve_scope & lldb::eSymbolContextLineEntry)
- ParseCompileUnitLineTable(sc, line);
- }
- }
- return sc_list.GetSize();
+ lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
+ m_types.insert(std::make_pair(type_uid, result));
+ return result.get();
}
-uint32_t
-SymbolFilePDB::FindGlobalVariables(const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches, lldb_private::VariableList &variables)
-{
- return uint32_t();
+bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
+ // TODO: Implement this
+ return false;
}
-uint32_t
-SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex, bool append, uint32_t max_matches,
- lldb_private::VariableList &variables)
-{
- return uint32_t();
+lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
+ return lldb_private::CompilerDecl();
}
-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, lldb_private::SymbolContextList &sc_list)
-{
- return uint32_t();
+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;
}
-uint32_t
-SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex, bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list)
-{
- return uint32_t();
+lldb_private::CompilerDeclContext
+SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
+ return *m_tu_decl_ctx_up;
}
-void
-SymbolFilePDB::GetMangledNamesForFunction(const std::string &scope_qualified_name,
- std::vector<lldb_private::ConstString> &mangled_names)
-{
-}
+void SymbolFilePDB::ParseDeclsForContext(
+ lldb_private::CompilerDeclContext decl_ctx) {}
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,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types)
-{
- if (!append)
- types.Clear();
- if (!name)
- return 0;
-
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
-
- std::string name_str = name.AsCString();
-
- // If this might be a regex, we have to return EVERY symbol and process them one by one, which is going
- // to destroy performance on large PDB files. So try really hard not to use a regex match.
- if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
- FindTypesByRegex(name_str, max_matches, types);
- else
- FindTypesByName(name_str, max_matches, types);
- return types.GetSize();
-}
-
-void
-SymbolFilePDB::FindTypesByRegex(const std::string &regex, uint32_t max_matches, lldb_private::TypeMap &types)
-{
- // When searching by regex, we need to go out of our way to limit the search space as much as possible, since
- // the way this is implemented is by searching EVERYTHING in the PDB and manually doing a regex compare. PDB
- // library isn't optimized for regex searches or searches across multiple symbol types at the same time, so the
- // best we can do is to search enums, then typedefs, then classes one by one, and do a regex compare against all
- // of them.
- PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, PDB_SymType::UDT};
- auto global = m_session_up->getGlobalScope();
- std::unique_ptr<IPDBEnumSymbols> results;
-
- std::regex re(regex);
-
- uint32_t matches = 0;
-
- for (auto tag : tags_to_search)
- {
- results = global->findAllChildren(tag);
- while (auto result = results->getNext())
- {
- if (max_matches > 0 && matches >= max_matches)
- break;
-
- std::string type_name;
- if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
- type_name = enum_type->getName();
- else if (auto typedef_type = llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
- type_name = typedef_type->getName();
- else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
- type_name = class_type->getName();
- else
- {
- // We're only looking for types that have names. Skip symbols, as well as
- // unnamed types such as arrays, pointers, etc.
- continue;
- }
-
- if (!std::regex_match(type_name, re))
- continue;
-
- // This should cause the type to get cached and stored in the `m_types` lookup.
- if (!ResolveTypeUID(result->getSymIndexId()))
- continue;
-
- auto iter = m_types.find(result->getSymIndexId());
- if (iter == m_types.end())
- continue;
- types.Insert(iter->second);
- ++matches;
- }
+SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) {
+ return uint32_t();
+}
+
+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) {
+ if (resolve_scope & lldb::eSymbolContextCompUnit) {
+ // Locate all compilation units with line numbers referencing the specified
+ // file. For example, if
+ // `file_spec` is <vector>, then this should return all source files and
+ // header files that reference
+ // <vector>, either directly or indirectly.
+ auto compilands = m_session_up->findCompilandsForSourceFile(
+ file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
+
+ // For each one, either find get its previously parsed data, or parse it
+ // afresh and add it to
+ // the symbol context list.
+ while (auto compiland = compilands->getNext()) {
+ // If we're not checking inlines, then don't add line information for this
+ // file unless the FileSpec
+ // matches.
+ if (!check_inlines) {
+ // `getSourceFileName` returns the basename of the original source file
+ // used to generate this compiland.
+ // It does not return the full path. Currently the only way to get that
+ // is to do a basename lookup to
+ // get the IPDBSourceFile, but this is ambiguous in the case of two
+ // source files with the same name
+ // contributing to the same compiland. This is a moderately extreme
+ // edge case, so we consider this ok
+ // for now, although we need to find a long term solution.
+ std::string source_file = compiland->getSourceFileName();
+ auto pdb_file = m_session_up->findOneSourceFile(
+ compiland.get(), source_file,
+ PDB_NameSearchFlags::NS_CaseInsensitive);
+ source_file = pdb_file->getFileName();
+ FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
+ if (!file_spec.FileEquals(this_spec))
+ continue;
+ }
+
+ SymbolContext sc;
+ auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
+ sc.comp_unit = cu.get();
+ sc.module_sp = cu->GetModule();
+ sc_list.Append(sc);
+
+ // If we were asked to resolve line entries, add all entries to the line
+ // table that match the requested
+ // line (or all lines if `line` == 0)
+ if (resolve_scope & lldb::eSymbolContextLineEntry)
+ ParseCompileUnitLineTable(sc, line);
}
+ }
+ return sc_list.GetSize();
}
-void
-SymbolFilePDB::FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types)
-{
- auto global = m_session_up->getGlobalScope();
- std::unique_ptr<IPDBEnumSymbols> results;
- results = global->findChildren(PDB_SymType::None, name.c_str(), PDB_NameSearchFlags::NS_Default);
-
- uint32_t matches = 0;
-
- while (auto result = results->getNext())
- {
- if (max_matches > 0 && matches >= max_matches)
- break;
- switch (result->getSymTag())
- {
- case PDB_SymType::Enum:
- case PDB_SymType::UDT:
- case PDB_SymType::Typedef:
- break;
- default:
- // We're only looking for types that have names. Skip symbols, as well as
- // unnamed types such as arrays, pointers, etc.
- continue;
- }
+uint32_t SymbolFilePDB::FindGlobalVariables(
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches, lldb_private::VariableList &variables) {
+ return uint32_t();
+}
- // This should cause the type to get cached and stored in the `m_types` lookup.
- if (!ResolveTypeUID(result->getSymIndexId()))
- continue;
+uint32_t
+SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) {
+ return uint32_t();
+}
- auto iter = m_types.find(result->getSymIndexId());
- if (iter == m_types.end())
- continue;
- types.Insert(iter->second);
- ++matches;
- }
+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,
+ lldb_private::SymbolContextList &sc_list) {
+ return uint32_t();
}
-size_t
-SymbolFilePDB::FindTypes(const std::vector<lldb_private::CompilerContext> &contexts, bool append,
- lldb_private::TypeMap &types)
-{
+uint32_t
+SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) {
+ return uint32_t();
+}
+
+void SymbolFilePDB::GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) {}
+
+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,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ lldb_private::TypeMap &types) {
+ if (!append)
+ types.Clear();
+ if (!name)
return 0;
-}
-lldb_private::TypeList *
-SymbolFilePDB::GetTypeList()
-{
- return nullptr;
-}
+ searched_symbol_files.clear();
+ searched_symbol_files.insert(this);
+
+ std::string name_str = name.AsCString();
+
+ // If this might be a regex, we have to return EVERY symbol and process them
+ // one by one, which is going
+ // to destroy performance on large PDB files. So try really hard not to use a
+ // regex match.
+ if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
+ FindTypesByRegex(name_str, max_matches, types);
+ else
+ FindTypesByName(name_str, max_matches, types);
+ return types.GetSize();
+}
+
+void SymbolFilePDB::FindTypesByRegex(const std::string &regex,
+ uint32_t max_matches,
+ lldb_private::TypeMap &types) {
+ // When searching by regex, we need to go out of our way to limit the search
+ // space as much as possible, since
+ // the way this is implemented is by searching EVERYTHING in the PDB and
+ // manually doing a regex compare. PDB
+ // library isn't optimized for regex searches or searches across multiple
+ // symbol types at the same time, so the
+ // best we can do is to search enums, then typedefs, then classes one by one,
+ // and do a regex compare against all
+ // of them.
+ PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
+ PDB_SymType::UDT};
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+
+ std::regex re(regex);
+
+ uint32_t matches = 0;
+
+ for (auto tag : tags_to_search) {
+ results = global->findAllChildren(tag);
+ while (auto result = results->getNext()) {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+
+ std::string type_name;
+ if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
+ type_name = enum_type->getName();
+ else if (auto typedef_type =
+ llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
+ type_name = typedef_type->getName();
+ else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
+ type_name = class_type->getName();
+ else {
+ // We're only looking for types that have names. Skip symbols, as well
+ // as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
+ }
+
+ if (!std::regex_match(type_name, re))
+ continue;
+
+ // This should cause the type to get cached and stored in the `m_types`
+ // lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
+
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
+ }
+ }
+}
+
+void SymbolFilePDB::FindTypesByName(const std::string &name,
+ uint32_t max_matches,
+ lldb_private::TypeMap &types) {
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+ results = global->findChildren(PDB_SymType::None, name,
+ PDB_NameSearchFlags::NS_Default);
+
+ uint32_t matches = 0;
+
+ while (auto result = results->getNext()) {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+ switch (result->getSymTag()) {
+ case PDB_SymType::Enum:
+ case PDB_SymType::UDT:
+ case PDB_SymType::Typedef:
+ break;
+ default:
+ // We're only looking for types that have names. Skip symbols, as well as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
+ }
-size_t
-SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
- lldb_private::TypeList &type_list)
-{
- return size_t();
-}
+ // This should cause the type to get cached and stored in the `m_types`
+ // lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
-lldb_private::TypeSystem *
-SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language)
-{
- auto type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
+ }
}
-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();
+size_t SymbolFilePDB::FindTypes(
+ const std::vector<lldb_private::CompilerContext> &contexts, bool append,
+ lldb_private::TypeMap &types) {
+ return 0;
}
-lldb_private::ConstString
-SymbolFilePDB::GetPluginName()
-{
- static ConstString g_name("pdb");
- return g_name;
+lldb_private::TypeList *SymbolFilePDB::GetTypeList() { return nullptr; }
+
+size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) {
+ return size_t();
}
-uint32_t
-SymbolFilePDB::GetPluginVersion()
-{
- return 1;
-}
-
-IPDBSession &
-SymbolFilePDB::GetPDBSession()
-{
- return *m_session_up;
-}
-
-const IPDBSession &
-SymbolFilePDB::GetPDBSession() const
-{
- return *m_session_up;
-}
-
-lldb::CompUnitSP
-SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id)
-{
- auto found_cu = m_comp_units.find(id);
- if (found_cu != m_comp_units.end())
- return found_cu->second;
-
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
-
- // `getSourceFileName` returns the basename of the original source file used to generate this compiland. It does
- // not return the full path. Currently the only way to get that is to do a basename lookup to get the
- // IPDBSourceFile, but this is ambiguous in the case of two source files with the same name contributing to the
- // same compiland. This is a moderately extreme edge case, so we consider this ok for now, although we need to find
- // a long term solution.
- auto file =
- m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(), PDB_NameSearchFlags::NS_CaseInsensitive);
- std::string path = file->getFileName();
-
- lldb::LanguageType lang;
- auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
- if (!details)
- lang = lldb::eLanguageTypeC_plus_plus;
- else
- lang = TranslateLanguage(details->getLanguage());
-
- // Don't support optimized code for now, DebugInfoPDB does not return this information.
- LazyBool optimized = eLazyBoolNo;
- auto result = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
- m_comp_units.insert(std::make_pair(id, result));
- return result;
-}
-
-bool
-SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line)
-{
- auto global = m_session_up->getGlobalScope();
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
-
- // LineEntry needs the *index* of the file into the list of support files returned by
- // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally unique
- // idenfitifier in the namespace of the PDB. So, we have to do a mapping so that we
- // can hand out indices.
- llvm::DenseMap<uint32_t, uint32_t> index_map;
- BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
- auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
-
- // Find contributions to `cu` from all source and header files.
- std::string path = sc.comp_unit->GetPath();
- auto files = m_session_up->getSourceFilesForCompiland(*cu);
-
- // For each source and header file, create a LineSequence for contributions to the cu
- // from that file, and add the sequence.
- while (auto file = files->getNext())
- {
- std::unique_ptr<LineSequence> sequence(line_table->CreateLineSequenceContainer());
- auto lines = m_session_up->findLineNumbers(*cu, *file);
- int entry_count = lines->getChildCount();
-
- uint64_t prev_addr;
- uint32_t prev_length;
- uint32_t prev_line;
- uint32_t prev_source_idx;
-
- for (int i = 0; i < entry_count; ++i)
- {
- auto line = lines->getChildAtIndex(i);
-
- uint64_t lno = line->getLineNumber();
- uint64_t addr = line->getVirtualAddress();
- uint32_t length = line->getLength();
- uint32_t source_id = line->getSourceFileId();
- uint32_t col = line->getColumnNumber();
- uint32_t source_idx = index_map[source_id];
-
- // There was a gap between the current entry and the previous entry if the addresses don't perfectly line
- // up.
- bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
-
- // Before inserting the current entry, insert a terminal entry at the end of the previous entry's address
- // range if the current entry resulted in a gap from the previous entry.
- if (is_gap && ShouldAddLine(match_line, prev_line, prev_length))
- {
- line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
- prev_source_idx, false, false, false, false, true);
- }
-
- if (ShouldAddLine(match_line, lno, length))
- {
- bool is_statement = line->isStatement();
- bool is_prologue = false;
- bool is_epilogue = false;
- auto func = m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
- if (func)
- {
- auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
- is_prologue = (addr == prologue->getVirtualAddress());
-
- auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
- is_epilogue = (addr == epilogue->getVirtualAddress());
- }
-
- line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, source_idx, is_statement, false,
- is_prologue, is_epilogue, false);
- }
-
- prev_addr = addr;
- prev_length = length;
- prev_line = lno;
- prev_source_idx = source_idx;
+lldb_private::TypeSystem *
+SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
+ auto type_system =
+ m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system)
+ type_system->SetSymbolFile(this);
+ return type_system;
+}
+
+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();
+}
+
+lldb_private::ConstString SymbolFilePDB::GetPluginName() {
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+uint32_t SymbolFilePDB::GetPluginVersion() { return 1; }
+
+IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }
+
+const IPDBSession &SymbolFilePDB::GetPDBSession() const {
+ return *m_session_up;
+}
+
+lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) {
+ auto found_cu = m_comp_units.find(id);
+ if (found_cu != m_comp_units.end())
+ return found_cu->second;
+
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
+
+ // `getSourceFileName` returns the basename of the original source file used
+ // to generate this compiland. It does
+ // not return the full path. Currently the only way to get that is to do a
+ // basename lookup to get the
+ // IPDBSourceFile, but this is ambiguous in the case of two source files with
+ // the same name contributing to the
+ // same compiland. This is a moderately extreme edge case, so we consider this
+ // ok for now, although we need to find
+ // a long term solution.
+ auto file =
+ m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(),
+ PDB_NameSearchFlags::NS_CaseInsensitive);
+ std::string path = file->getFileName();
+
+ lldb::LanguageType lang;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ lang = lldb::eLanguageTypeC_plus_plus;
+ else
+ lang = TranslateLanguage(details->getLanguage());
+
+ // Don't support optimized code for now, DebugInfoPDB does not return this
+ // information.
+ LazyBool optimized = eLazyBoolNo;
+ auto result = std::make_shared<CompileUnit>(
+ m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
+ m_comp_units.insert(std::make_pair(id, result));
+ return result;
+}
+
+bool SymbolFilePDB::ParseCompileUnitLineTable(
+ const lldb_private::SymbolContext &sc, uint32_t match_line) {
+ auto global = m_session_up->getGlobalScope();
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
+ sc.comp_unit->GetID());
+
+ // LineEntry needs the *index* of the file into the list of support files
+ // returned by
+ // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally
+ // unique
+ // idenfitifier in the namespace of the PDB. So, we have to do a mapping so
+ // that we
+ // can hand out indices.
+ llvm::DenseMap<uint32_t, uint32_t> index_map;
+ BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
+ auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
+
+ // Find contributions to `cu` from all source and header files.
+ std::string path = sc.comp_unit->GetPath();
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+
+ // For each source and header file, create a LineSequence for contributions to
+ // the cu
+ // from that file, and add the sequence.
+ while (auto file = files->getNext()) {
+ std::unique_ptr<LineSequence> sequence(
+ line_table->CreateLineSequenceContainer());
+ auto lines = m_session_up->findLineNumbers(*cu, *file);
+ int entry_count = lines->getChildCount();
+
+ uint64_t prev_addr;
+ uint32_t prev_length;
+ uint32_t prev_line;
+ uint32_t prev_source_idx;
+
+ for (int i = 0; i < entry_count; ++i) {
+ auto line = lines->getChildAtIndex(i);
+
+ uint64_t lno = line->getLineNumber();
+ uint64_t addr = line->getVirtualAddress();
+ uint32_t length = line->getLength();
+ uint32_t source_id = line->getSourceFileId();
+ uint32_t col = line->getColumnNumber();
+ uint32_t source_idx = index_map[source_id];
+
+ // There was a gap between the current entry and the previous entry if the
+ // addresses don't perfectly line
+ // up.
+ bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
+
+ // Before inserting the current entry, insert a terminal entry at the end
+ // of the previous entry's address
+ // range if the current entry resulted in a gap from the previous entry.
+ if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {
+ line_table->AppendLineEntryToSequence(
+ sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
+
+ if (ShouldAddLine(match_line, lno, length)) {
+ bool is_statement = line->isStatement();
+ bool is_prologue = false;
+ bool is_epilogue = false;
+ auto func =
+ m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
+ if (func) {
+ auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
+ is_prologue = (addr == prologue->getVirtualAddress());
+
+ auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
+ is_epilogue = (addr == epilogue->getVirtualAddress());
}
- if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length))
- {
- // The end is always a terminal entry, so insert it regardless.
- line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
- prev_source_idx, false, false, false, false, true);
- }
+ line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
+ source_idx, is_statement, false,
+ is_prologue, is_epilogue, false);
+ }
- line_table->InsertSequence(sequence.release());
+ prev_addr = addr;
+ prev_length = length;
+ prev_line = lno;
+ prev_source_idx = source_idx;
}
- sc.comp_unit->SetLineTable(line_table.release());
- return true;
-}
-
-void
-SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(const PDBSymbolCompiland &cu,
- llvm::DenseMap<uint32_t, uint32_t> &index_map) const
-{
- // This is a hack, but we need to convert the source id into an index into the support
- // files array. We don't want to do path comparisons to avoid basename / full path
- // issues that may or may not even be a problem, so we use the globally unique source
- // file identifiers. Ideally we could use the global identifiers everywhere, but LineEntry
- // currently assumes indices.
- auto source_files = m_session_up->getSourceFilesForCompiland(cu);
- int index = 0;
-
- while (auto file = source_files->getNext())
- {
- uint32_t source_id = file->getUniqueId();
- index_map[source_id] = index++;
+ if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {
+ // The end is always a terminal entry, so insert it regardless.
+ line_table->AppendLineEntryToSequence(
+ sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
}
+
+ line_table->InsertSequence(sequence.release());
+ }
+
+ sc.comp_unit->SetLineTable(line_table.release());
+ return true;
+}
+
+void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
+ const PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
+ // This is a hack, but we need to convert the source id into an index into the
+ // support
+ // files array. We don't want to do path comparisons to avoid basename / full
+ // path
+ // issues that may or may not even be a problem, so we use the globally unique
+ // source
+ // file identifiers. Ideally we could use the global identifiers everywhere,
+ // but LineEntry
+ // currently assumes indices.
+ auto source_files = m_session_up->getSourceFilesForCompiland(cu);
+ int index = 0;
+
+ while (auto file = source_files->getNext()) {
+ uint32_t source_id = file->getUniqueId();
+ index_map[source_id] = index++;
+ }
}
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index cf75de8ac78e..2e5918328ff0 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -17,188 +17,174 @@
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDB.h"
-class SymbolFilePDB : public lldb_private::SymbolFile
-{
+class SymbolFilePDB : public lldb_private::SymbolFile {
public:
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static void
- DebuggerInitialize(lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolFilePDB(lldb_private::ObjectFile *ofile);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFilePDB(lldb_private::ObjectFile *ofile);
- ~SymbolFilePDB() override;
+ ~SymbolFilePDB() override;
- uint32_t
- CalculateAbilities() override;
+ uint32_t CalculateAbilities() override;
- void
- InitializeObject() override;
+ void InitializeObject() override;
- //------------------------------------------------------------------
- // Compile Unit function calls
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
- uint32_t
- GetNumCompileUnits() override;
+ uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP
- ParseCompileUnitAtIndex(uint32_t index) override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitDebugMacros(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 ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
- bool
- ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) 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 ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseTypes(const lldb_private::SymbolContext &sc) override;
+ size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
- lldb_private::Type *
- ResolveTypeUID(lldb::user_id_t type_uid) override;
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- bool
- CompleteType(lldb_private::CompilerType &compiler_type) override;
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
- lldb_private::CompilerDecl
- GetDeclForUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
- void
- ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
- lldb_private::SymbolContext &sc) override;
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t 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, lldb_private::SymbolContextList &sc_list) override;
+ uint32_t
+ ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
+ bool check_inlines, uint32_t resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t
- FindGlobalVariables(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches, lldb_private::VariableList &variables) override;
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindGlobalVariables(const lldb_private::RegularExpression &regex, bool append, uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- 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;
+ 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;
- uint32_t
- FindFunctions(const lldb_private::RegularExpression &regex, 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;
- void
- GetMangledNamesForFunction(const std::string &scope_qualified_name,
- std::vector<lldb_private::ConstString> &mangled_names) override;
+ void GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) override;
- uint32_t
- FindTypes(const lldb_private::SymbolContext &sc, 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;
+ uint32_t
+ FindTypes(const lldb_private::SymbolContext &sc,
+ 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;
- size_t
- FindTypes(const std::vector<lldb_private::CompilerContext> &context, bool append,
- lldb_private::TypeMap &types) override;
+ size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
+ bool append, lldb_private::TypeMap &types) override;
- lldb_private::TypeList *
- GetTypeList() override;
+ lldb_private::TypeList *GetTypeList() override;
- size_t
- GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
- lldb_private::TypeList &type_list) override;
+ size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
- lldb_private::TypeSystem *
- GetTypeSystemForLanguage(lldb::LanguageType language) 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;
+ lldb_private::CompilerDeclContext FindNamespace(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- llvm::pdb::IPDBSession &
- GetPDBSession();
+ llvm::pdb::IPDBSession &GetPDBSession();
- const llvm::pdb::IPDBSession &
- GetPDBSession() const;
+ const llvm::pdb::IPDBSession &GetPDBSession() const;
private:
- lldb::CompUnitSP
- ParseCompileUnitForSymIndex(uint32_t id);
+ lldb::CompUnitSP ParseCompileUnitForSymIndex(uint32_t id);
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line);
+ bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc,
+ uint32_t match_line);
- void
- BuildSupportFileIdToSupportFileIndexMap(const llvm::pdb::PDBSymbolCompiland &cu,
- llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
+ void BuildSupportFileIdToSupportFileIndexMap(
+ const llvm::pdb::PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
- void
- FindTypesByRegex(const std::string &regex, uint32_t max_matches, lldb_private::TypeMap &types);
+ void FindTypesByRegex(const std::string &regex, uint32_t max_matches,
+ lldb_private::TypeMap &types);
- void
- FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types);
+ void FindTypesByName(const std::string &name, uint32_t max_matches,
+ lldb_private::TypeMap &types);
- llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
- llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
+ llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
+ llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
- std::vector<lldb::TypeSP> m_builtin_types;
- std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
- uint32_t m_cached_compile_unit_count;
- std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
+ std::vector<lldb::TypeSP> m_builtin_types;
+ std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
+ uint32_t m_cached_compile_unit_count;
+ std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
};
#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 24175079c95f..39073991c32c 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -24,312 +24,251 @@
using namespace lldb;
using namespace lldb_private;
-void
-SymbolFileSymtab::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void SymbolFileSymtab::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-SymbolFileSymtab::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void SymbolFileSymtab::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-SymbolFileSymtab::GetPluginNameStatic()
-{
- static ConstString g_name("symtab");
- return g_name;
+lldb_private::ConstString SymbolFileSymtab::GetPluginNameStatic() {
+ static ConstString g_name("symtab");
+ return g_name;
}
-const char *
-SymbolFileSymtab::GetPluginDescriptionStatic()
-{
- return "Reads debug symbols from an object file's symbol table.";
+const char *SymbolFileSymtab::GetPluginDescriptionStatic() {
+ return "Reads debug symbols from an object file's symbol table.";
}
-
-SymbolFile*
-SymbolFileSymtab::CreateInstance (ObjectFile* obj_file)
-{
- return new SymbolFileSymtab(obj_file);
+SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileSymtab(obj_file);
}
-size_t
-SymbolFileSymtab::GetTypes (SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list)
-{
- return 0;
+size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) {
+ return 0;
}
-SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
- SymbolFile(obj_file),
- m_source_indexes(),
- m_func_indexes(),
- m_code_indexes(),
- m_objc_class_name_to_index ()
-{
-}
+SymbolFileSymtab::SymbolFileSymtab(ObjectFile *obj_file)
+ : SymbolFile(obj_file), m_source_indexes(), m_func_indexes(),
+ m_code_indexes(), m_objc_class_name_to_index() {}
-SymbolFileSymtab::~SymbolFileSymtab()
-{
-}
-
-uint32_t
-SymbolFileSymtab::CalculateAbilities ()
-{
- uint32_t abilities = 0;
- if (m_obj_file)
- {
- const Symtab *symtab = m_obj_file->GetSymtab();
- if (symtab)
- {
- //----------------------------------------------------------------------
- // The snippet of code below will get the indexes the module symbol
- // table entries that are code, data, or function related (debug info),
- // sort them by value (address) and dump the sorted symbols.
- //----------------------------------------------------------------------
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes))
- {
- abilities |= CompileUnits;
- }
-
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes))
- {
- symtab->SortSymbolIndexesByValue(m_func_indexes, true);
- abilities |= Functions;
- }
+SymbolFileSymtab::~SymbolFileSymtab() {}
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes))
- {
- symtab->SortSymbolIndexesByValue(m_code_indexes, true);
- abilities |= Functions;
- }
-
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes))
- {
- symtab->SortSymbolIndexesByValue(m_data_indexes, true);
- abilities |= GlobalVariables;
- }
-
- lldb_private::Symtab::IndexCollection objc_class_indexes;
- if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes))
- {
- symtab->AppendSymbolNamesToMap (objc_class_indexes,
- true,
- true,
- m_objc_class_name_to_index);
- m_objc_class_name_to_index.Sort();
- }
- }
+uint32_t SymbolFileSymtab::CalculateAbilities() {
+ uint32_t abilities = 0;
+ if (m_obj_file) {
+ const Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ //----------------------------------------------------------------------
+ // The snippet of code below will get the indexes the module symbol
+ // table entries that are code, data, or function related (debug info),
+ // sort them by value (address) and dump the sorted symbols.
+ //----------------------------------------------------------------------
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile,
+ m_source_indexes)) {
+ abilities |= CompileUnits;
+ }
+
+ if (symtab->AppendSymbolIndexesWithType(
+ eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny,
+ m_func_indexes)) {
+ symtab->SortSymbolIndexesByValue(m_func_indexes, true);
+ abilities |= Functions;
+ }
+
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo,
+ Symtab::eVisibilityAny,
+ m_code_indexes)) {
+ symtab->SortSymbolIndexesByValue(m_code_indexes, true);
+ abilities |= Functions;
+ }
+
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData,
+ m_data_indexes)) {
+ symtab->SortSymbolIndexesByValue(m_data_indexes, true);
+ abilities |= GlobalVariables;
+ }
+
+ lldb_private::Symtab::IndexCollection objc_class_indexes;
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass,
+ objc_class_indexes)) {
+ symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true,
+ m_objc_class_name_to_index);
+ m_objc_class_name_to_index.Sort();
+ }
}
- return abilities;
+ }
+ return abilities;
}
-uint32_t
-SymbolFileSymtab::GetNumCompileUnits()
-{
- // If we don't have any source file symbols we will just have one compile unit for
- // the entire object file
- if (m_source_indexes.empty())
- return 0;
-
- // If we have any source file symbols we will logically organize the object symbols
- // using these.
- return m_source_indexes.size();
+uint32_t SymbolFileSymtab::GetNumCompileUnits() {
+ // If we don't have any source file symbols we will just have one compile unit
+ // for
+ // the entire object file
+ if (m_source_indexes.empty())
+ return 0;
+
+ // If we have any source file symbols we will logically organize the object
+ // symbols
+ // using these.
+ return m_source_indexes.size();
}
-CompUnitSP
-SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
-{
- CompUnitSP cu_sp;
-
- // If we don't have any source file symbols we will just have one compile unit for
- // the entire object file
- if (idx < m_source_indexes.size())
- {
- const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
- if (cu_symbol)
- cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0,
- eLanguageTypeUnknown, eLazyBoolNo));
- }
- return cu_sp;
+CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
+ CompUnitSP cu_sp;
+
+ // If we don't have any source file symbols we will just have one compile unit
+ // for
+ // the entire object file
+ if (idx < m_source_indexes.size()) {
+ const Symbol *cu_symbol =
+ m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
+ if (cu_symbol)
+ cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL,
+ cu_symbol->GetName().AsCString(), 0,
+ eLanguageTypeUnknown, eLazyBoolNo));
+ }
+ return cu_sp;
}
lldb::LanguageType
-SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc)
-{
- return eLanguageTypeUnknown;
+SymbolFileSymtab::ParseCompileUnitLanguage(const SymbolContext &sc) {
+ return eLanguageTypeUnknown;
}
+size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) {
+ 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;
+ // const char *prefix = m_obj_file->SymbolPrefix();
+ // if (prefix == NULL)
+ // prefix == "";
+ //
+ // const uint32_t prefix_len = strlen(prefix);
+
+ // If we don't have any source file symbols we will just have one compile unit
+ // for
+ // the entire object file
+ if (m_source_indexes.empty()) {
+ // The only time we will have a user ID of zero is when we don't have
+ // and source file symbols and we declare one compile unit for the
+ // entire object file
+ if (!m_func_indexes.empty()) {
+ }
-size_t
-SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
-{
- 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;
-// const char *prefix = m_obj_file->SymbolPrefix();
-// if (prefix == NULL)
-// prefix == "";
-//
-// const uint32_t prefix_len = strlen(prefix);
-
- // If we don't have any source file symbols we will just have one compile unit for
- // the entire object file
- if (m_source_indexes.empty())
- {
- // The only time we will have a user ID of zero is when we don't have
- // and source file symbols and we declare one compile unit for the
- // entire object file
- if (!m_func_indexes.empty())
- {
-
- }
-
- if (!m_code_indexes.empty())
- {
-// StreamFile s(stdout);
-// symtab->Dump(&s, m_code_indexes);
-
- uint32_t idx = 0; // Index into the indexes
- const uint32_t num_indexes = m_code_indexes.size();
- for (idx = 0; idx < num_indexes; ++idx)
- {
- uint32_t symbol_idx = m_code_indexes[idx];
- curr_symbol = symtab->SymbolAtIndex(symbol_idx);
- if (curr_symbol)
- {
- // Union of all ranges in the function DIE (if the function is discontiguous)
- AddressRange func_range(curr_symbol->GetAddress(), 0);
- if (func_range.GetBaseAddress().IsSectionOffset())
- {
- uint32_t symbol_size = curr_symbol->GetByteSize();
- if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
- func_range.SetByteSize(symbol_size);
- else if (idx + 1 < num_indexes)
- {
- next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
- if (next_symbol)
- {
- func_range.SetByteSize(next_symbol->GetAddressRef().GetOffset() - curr_symbol->GetAddressRef().GetOffset());
- }
- }
-
- FunctionSP func_sp(new Function(sc.comp_unit,
- symbol_idx, // UserID is the DIE offset
- LLDB_INVALID_UID, // We don't have any type info for this function
- curr_symbol->GetMangled(), // Linker/mangled name
- NULL, // no return type for a code symbol...
- func_range)); // first address range
-
- if (func_sp.get() != NULL)
- {
- sc.comp_unit->AddFunction(func_sp);
- ++num_added;
- }
- }
- }
+ if (!m_code_indexes.empty()) {
+ // StreamFile s(stdout);
+ // symtab->Dump(&s, m_code_indexes);
+
+ uint32_t idx = 0; // Index into the indexes
+ const uint32_t num_indexes = m_code_indexes.size();
+ for (idx = 0; idx < num_indexes; ++idx) {
+ uint32_t symbol_idx = m_code_indexes[idx];
+ curr_symbol = symtab->SymbolAtIndex(symbol_idx);
+ if (curr_symbol) {
+ // Union of all ranges in the function DIE (if the function is
+ // discontiguous)
+ AddressRange func_range(curr_symbol->GetAddress(), 0);
+ if (func_range.GetBaseAddress().IsSectionOffset()) {
+ uint32_t symbol_size = curr_symbol->GetByteSize();
+ if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
+ func_range.SetByteSize(symbol_size);
+ else if (idx + 1 < num_indexes) {
+ next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
+ if (next_symbol) {
+ func_range.SetByteSize(
+ next_symbol->GetAddressRef().GetOffset() -
+ curr_symbol->GetAddressRef().GetOffset());
+ }
}
+ FunctionSP func_sp(
+ new Function(sc.comp_unit,
+ symbol_idx, // UserID is the DIE offset
+ LLDB_INVALID_UID, // We don't have any type info
+ // for this function
+ curr_symbol->GetMangled(), // Linker/mangled name
+ NULL, // no return type for a code symbol...
+ func_range)); // first address range
+
+ if (func_sp.get() != NULL) {
+ sc.comp_unit->AddFunction(func_sp);
+ ++num_added;
+ }
+ }
}
+ }
}
- else
- {
- // We assume we
- }
- return num_added;
+ } else {
+ // We assume we
+ }
+ return num_added;
}
-bool
-SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
-{
- return false;
+bool SymbolFileSymtab::ParseCompileUnitLineTable(const SymbolContext &sc) {
+ return false;
}
-bool
-SymbolFileSymtab::ParseCompileUnitDebugMacros (const SymbolContext &sc)
-{
- return false;
+bool SymbolFileSymtab::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
+ return false;
}
-bool
-SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
-{
- return false;
+bool SymbolFileSymtab::ParseCompileUnitSupportFiles(
+ const SymbolContext &sc, FileSpecList &support_files) {
+ return false;
}
-bool
-SymbolFileSymtab::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
-{
- return false;
+bool SymbolFileSymtab::ParseImportedModules(
+ const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ return false;
}
-size_t
-SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
-{
- return 0;
+size_t SymbolFileSymtab::ParseFunctionBlocks(const SymbolContext &sc) {
+ return 0;
}
+size_t SymbolFileSymtab::ParseTypes(const SymbolContext &sc) { return 0; }
-size_t
-SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
-{
- return 0;
+size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) {
+ return 0;
}
-
-size_t
-SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
-{
- return 0;
+Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) {
+ return NULL;
}
-Type*
-SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
-{
- return NULL;
+bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
+ return false;
}
-bool
-SymbolFileSymtab::CompleteType (lldb_private::CompilerType& compiler_type)
-{
- return false;
-}
+uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
+ uint32_t resolve_scope,
+ SymbolContext &sc) {
+ if (m_obj_file->GetSymtab() == NULL)
+ return 0;
-uint32_t
-SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
-{
- if (m_obj_file->GetSymtab() == NULL)
- return 0;
-
- uint32_t resolved_flags = 0;
- if (resolve_scope & eSymbolContextSymbol)
- {
- sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
- if (sc.symbol)
- resolved_flags |= eSymbolContextSymbol;
- }
- return resolved_flags;
+ uint32_t resolved_flags = 0;
+ if (resolve_scope & eSymbolContextSymbol) {
+ sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(
+ so_addr.GetFileAddress());
+ if (sc.symbol)
+ resolved_flags |= eSymbolContextSymbol;
+ }
+ return resolved_flags;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-SymbolFileSymtab::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString SymbolFileSymtab::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-SymbolFileSymtab::GetPluginVersion()
-{
- return 1;
-}
+uint32_t SymbolFileSymtab::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index 4648da49cb9f..1945af9a337e 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -19,112 +19,96 @@
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Symtab.h"
-class SymbolFileSymtab : public lldb_private::SymbolFile
-{
+class SymbolFileSymtab : public lldb_private::SymbolFile {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolFileSymtab(lldb_private::ObjectFile* obj_file);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFileSymtab(lldb_private::ObjectFile *obj_file);
- ~SymbolFileSymtab() override;
+ ~SymbolFileSymtab() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SymbolFile*
- CreateInstance (lldb_private::ObjectFile* obj_file);
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
- uint32_t
- CalculateAbilities() override;
+ uint32_t CalculateAbilities() override;
- //------------------------------------------------------------------
- // Compile Unit function calls
- //------------------------------------------------------------------
- uint32_t
- GetNumCompileUnits() override;
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+ uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP
- ParseCompileUnitAtIndex(uint32_t index) override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext& sc) override;
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext& sc) override;
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext& sc) override;
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitDebugMacros(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
- ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ bool ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
- size_t
- ParseFunctionBlocks(const lldb_private::SymbolContext& sc) override;
+ bool ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t
- ParseTypes(const lldb_private::SymbolContext& sc) override;
+ size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseVariablesForContext(const lldb_private::SymbolContext& sc) override;
+ size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
- lldb_private::Type*
- ResolveTypeUID(lldb::user_id_t type_uid) override;
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
- bool
- CompleteType(lldb_private::CompilerType& compiler_type) override;
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::Address& so_addr,
- uint32_t resolve_scope,
- lldb_private::SymbolContext& sc) override;
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
- size_t
- GetTypes(lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
- lldb_private::TypeList &type_list) override;
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
- uint32_t
- GetPluginVersion() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
-
- lldb_private::Symtab::IndexCollection m_source_indexes;
- lldb_private::Symtab::IndexCollection m_func_indexes;
- lldb_private::Symtab::IndexCollection m_code_indexes;
- lldb_private::Symtab::IndexCollection m_data_indexes;
- lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index;
- TypeMap m_objc_class_types;
-
+ typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
+
+ lldb_private::Symtab::IndexCollection m_source_indexes;
+ lldb_private::Symtab::IndexCollection m_func_indexes;
+ lldb_private::Symtab::IndexCollection m_code_indexes;
+ lldb_private::Symtab::IndexCollection m_data_indexes;
+ lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index;
+ TypeMap m_objc_class_types;
+
private:
- DISALLOW_COPY_AND_ASSIGN (SymbolFileSymtab);
+ DISALLOW_COPY_AND_ASSIGN(SymbolFileSymtab);
};
#endif // liblldb_SymbolFileSymtab_h_
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index 3cd1b68d7b0f..4934a80c09ee 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -27,48 +27,33 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// SymbolVendorELF constructor
//----------------------------------------------------------------------
-SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) :
- SymbolVendor (module_sp)
-{
-}
+SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
+ : SymbolVendor(module_sp) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-SymbolVendorELF::~SymbolVendorELF()
-{
-}
+SymbolVendorELF::~SymbolVendorELF() {}
-void
-SymbolVendorELF::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void SymbolVendorELF::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-SymbolVendorELF::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void SymbolVendorELF::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-SymbolVendorELF::GetPluginNameStatic()
-{
- static ConstString g_name("ELF");
- return g_name;
+lldb_private::ConstString SymbolVendorELF::GetPluginNameStatic() {
+ static ConstString g_name("ELF");
+ return g_name;
}
-const char *
-SymbolVendorELF::GetPluginDescriptionStatic()
-{
- return "Symbol vendor for ELF that looks for dSYM files that match executables.";
+const char *SymbolVendorELF::GetPluginDescriptionStatic() {
+ return "Symbol vendor for ELF that looks for dSYM files that match "
+ "executables.";
}
-
-
//----------------------------------------------------------------------
// CreateInstance
//
@@ -76,122 +61,108 @@ SymbolVendorELF::GetPluginDescriptionStatic()
// vendors to allow for complex debug information file setups, and to
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
-SymbolVendor*
-SymbolVendorELF::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
-{
- if (!module_sp)
- return NULL;
-
- ObjectFile *obj_file = module_sp->GetObjectFile();
- if (!obj_file)
- return NULL;
-
- static ConstString obj_file_elf("elf");
- ConstString obj_name = obj_file->GetPluginName();
- if (obj_name != obj_file_elf)
- return NULL;
-
- lldb_private::UUID uuid;
- if (!obj_file->GetUUID (&uuid))
- return NULL;
-
- // Get the .gnu_debuglink file (if specified).
- FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
-
- // If the module specified a filespec, use it first.
- FileSpec debug_symbol_fspec (module_sp->GetSymbolFileFileSpec());
- if (debug_symbol_fspec)
- file_spec_list.Insert (0, debug_symbol_fspec);
-
- // If we have no debug symbol files, then nothing to do.
- if (file_spec_list.IsEmpty())
- return NULL;
-
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolVendorELF::CreateInstance (module = %s)",
- module_sp->GetFileSpec().GetPath().c_str());
-
- for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx)
- {
- ModuleSpec module_spec;
- const FileSpec fspec = file_spec_list.GetFileSpecAtIndex (idx);
-
- module_spec.GetFileSpec() = obj_file->GetFileSpec();
- module_spec.GetFileSpec().ResolvePath();
- 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);
- if (dsym_objfile_sp)
- {
- // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be able
- // to figure this out consistently as the symbol file may not have stripped the
- // code sections, etc.
- dsym_objfile_sp->SetType (ObjectFile::eTypeDebugInfo);
-
- SymbolVendorELF* symbol_vendor = new SymbolVendorELF(module_sp);
- if (symbol_vendor)
- {
- // Get the module unified section list and add our debug sections to that.
- SectionList *module_section_list = module_sp->GetSectionList();
- SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
-
- static const SectionType g_sections[] =
- {
- eSectionTypeDWARFDebugAbbrev,
- eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges,
- eSectionTypeDWARFDebugFrame,
- eSectionTypeDWARFDebugInfo,
- eSectionTypeDWARFDebugLine,
- eSectionTypeDWARFDebugLoc,
- eSectionTypeDWARFDebugMacInfo,
- eSectionTypeDWARFDebugPubNames,
- eSectionTypeDWARFDebugPubTypes,
- eSectionTypeDWARFDebugRanges,
- eSectionTypeDWARFDebugStr,
- eSectionTypeDWARFDebugStrOffsets,
- eSectionTypeELFSymbolTable,
- };
- for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
- {
- SectionType section_type = g_sections[idx];
- SectionSP section_sp (objfile_section_list->FindSectionByType (section_type, true));
- if (section_sp)
- {
- SectionSP module_section_sp (module_section_list->FindSectionByType (section_type, true));
- if (module_section_sp)
- module_section_list->ReplaceSection (module_section_sp->GetID(), section_sp);
- else
- module_section_list->AddSection (section_sp);
- }
- }
-
- symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp);
- return symbol_vendor;
- }
+SymbolVendor *
+SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm) {
+ if (!module_sp)
+ return NULL;
+
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (!obj_file)
+ return NULL;
+
+ static ConstString obj_file_elf("elf");
+ ConstString obj_name = obj_file->GetPluginName();
+ if (obj_name != obj_file_elf)
+ return NULL;
+
+ lldb_private::UUID uuid;
+ if (!obj_file->GetUUID(&uuid))
+ return NULL;
+
+ // Get the .gnu_debuglink file (if specified).
+ FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
+
+ // If the module specified a filespec, use it first.
+ FileSpec debug_symbol_fspec(module_sp->GetSymbolFileFileSpec());
+ if (debug_symbol_fspec)
+ file_spec_list.Insert(0, debug_symbol_fspec);
+
+ // If we have no debug symbol files, then nothing to do.
+ if (file_spec_list.IsEmpty())
+ return NULL;
+
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolVendorELF::CreateInstance (module = %s)",
+ module_sp->GetFileSpec().GetPath().c_str());
+
+ for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) {
+ ModuleSpec module_spec;
+ const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
+
+ module_spec.GetFileSpec() = obj_file->GetFileSpec();
+ module_spec.GetFileSpec().ResolvePath();
+ 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);
+ if (dsym_objfile_sp) {
+ // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be
+ // able
+ // to figure this out consistently as the symbol file may not have
+ // stripped the
+ // code sections, etc.
+ dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
+
+ SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
+ if (symbol_vendor) {
+ // Get the module unified section list and add our debug sections to
+ // that.
+ SectionList *module_section_list = module_sp->GetSectionList();
+ SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
+
+ static const SectionType g_sections[] = {
+ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
+ eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugFrame,
+ eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine,
+ eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugMacInfo,
+ eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
+ eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr,
+ eSectionTypeDWARFDebugStrOffsets, eSectionTypeELFSymbolTable,
+ };
+ for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
+ ++idx) {
+ SectionType section_type = g_sections[idx];
+ SectionSP section_sp(
+ objfile_section_list->FindSectionByType(section_type, true));
+ if (section_sp) {
+ SectionSP module_section_sp(
+ module_section_list->FindSectionByType(section_type, true));
+ if (module_section_sp)
+ module_section_list->ReplaceSection(module_section_sp->GetID(),
+ section_sp);
+ else
+ module_section_list->AddSection(section_sp);
}
+ }
+
+ symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+ return symbol_vendor;
}
+ }
}
- return NULL;
+ }
+ return NULL;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-SymbolVendorELF::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-SymbolVendorELF::GetPluginVersion()
-{
- return 1;
-}
+ConstString SymbolVendorELF::GetPluginName() { return GetPluginNameStatic(); }
+uint32_t SymbolVendorELF::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
index 425ff9efc59c..e7aeebc96b94 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
@@ -14,48 +14,42 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/lldb-private.h"
-class SymbolVendorELF : public lldb_private::SymbolVendor
-{
+class SymbolVendorELF : public lldb_private::SymbolVendor {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolVendorELF (const lldb::ModuleSP &module_sp);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolVendorELF(const lldb::ModuleSP &module_sp);
- ~SymbolVendorELF() override;
+ ~SymbolVendorELF() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SymbolVendor*
- CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);
+ static lldb_private::SymbolVendor *
+ CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm);
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
private:
- DISALLOW_COPY_AND_ASSIGN (SymbolVendorELF);
+ DISALLOW_COPY_AND_ASSIGN(SymbolVendorELF);
};
#endif // liblldb_SymbolVendorELF_h_
diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
index 7d21fbc0ede4..5e1953e03208 100644
--- a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -28,88 +28,69 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// SymbolVendorMacOSX constructor
//----------------------------------------------------------------------
-SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp) :
- SymbolVendor (module_sp)
-{
-}
+SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp)
+ : SymbolVendor(module_sp) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-SymbolVendorMacOSX::~SymbolVendorMacOSX()
-{
-}
+SymbolVendorMacOSX::~SymbolVendorMacOSX() {}
+static bool UUIDsMatch(Module *module, ObjectFile *ofile,
+ lldb_private::Stream *feedback_strm) {
+ if (module && ofile) {
+ // Make sure the UUIDs match
+ lldb_private::UUID dsym_uuid;
-static bool
-UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_strm)
-{
- if (module && ofile)
- {
- // Make sure the UUIDs match
- lldb_private::UUID dsym_uuid;
-
- if (!ofile->GetUUID(&dsym_uuid))
- {
- if (feedback_strm)
- {
- feedback_strm->PutCString("warning: failed to get the uuid for object file: '");
- ofile->GetFileSpec().Dump(feedback_strm);
- feedback_strm->PutCString("\n");
- }
- return false;
- }
+ if (!ofile->GetUUID(&dsym_uuid)) {
+ if (feedback_strm) {
+ feedback_strm->PutCString(
+ "warning: failed to get the uuid for object file: '");
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n");
+ }
+ return false;
+ }
- if (dsym_uuid == module->GetUUID())
- return true;
-
- // Emit some warning messages since the UUIDs do not match!
- if (feedback_strm)
- {
- feedback_strm->PutCString("warning: UUID mismatch detected between modules:\n ");
- module->GetUUID().Dump(feedback_strm);
- feedback_strm->PutChar(' ');
- module->GetFileSpec().Dump(feedback_strm);
- feedback_strm->PutCString("\n ");
- dsym_uuid.Dump(feedback_strm);
- feedback_strm->PutChar(' ');
- ofile->GetFileSpec().Dump(feedback_strm);
- feedback_strm->EOL();
- }
+ if (dsym_uuid == module->GetUUID())
+ return true;
+
+ // Emit some warning messages since the UUIDs do not match!
+ if (feedback_strm) {
+ feedback_strm->PutCString(
+ "warning: UUID mismatch detected between modules:\n ");
+ module->GetUUID().Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ module->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n ");
+ dsym_uuid.Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->EOL();
}
- return false;
+ }
+ return false;
}
-void
-SymbolVendorMacOSX::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void SymbolVendorMacOSX::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-SymbolVendorMacOSX::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void SymbolVendorMacOSX::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-SymbolVendorMacOSX::GetPluginNameStatic()
-{
- static ConstString g_name("macosx");
- return g_name;
+lldb_private::ConstString SymbolVendorMacOSX::GetPluginNameStatic() {
+ static ConstString g_name("macosx");
+ return g_name;
}
-const char *
-SymbolVendorMacOSX::GetPluginDescriptionStatic()
-{
- return "Symbol vendor for MacOSX that looks for dSYM files that match executables.";
+const char *SymbolVendorMacOSX::GetPluginDescriptionStatic() {
+ return "Symbol vendor for MacOSX that looks for dSYM files that match "
+ "executables.";
}
-
-
//----------------------------------------------------------------------
// CreateInstance
//
@@ -117,135 +98,199 @@ SymbolVendorMacOSX::GetPluginDescriptionStatic()
// vendors to allow for complex debug information file setups, and to
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
-SymbolVendor*
-SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
-{
- if (!module_sp)
- return NULL;
-
- ObjectFile * obj_file = module_sp->GetObjectFile();
- if (!obj_file)
- return NULL;
-
- static ConstString obj_file_macho("mach-o");
- ConstString obj_name = obj_file->GetPluginName();
- if (obj_name != obj_file_macho)
- return NULL;
-
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "SymbolVendorMacOSX::CreateInstance (module = %s)",
- module_sp->GetFileSpec().GetPath().c_str());
- SymbolVendorMacOSX* symbol_vendor = new SymbolVendorMacOSX(module_sp);
- if (symbol_vendor)
- {
- char path[PATH_MAX];
- path[0] = '\0';
-
- // Try and locate the dSYM file on Mac OS X
- Timer scoped_timer2 ("SymbolVendorMacOSX::CreateInstance () locate dSYM",
- "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
- module_sp->GetFileSpec().GetPath().c_str());
-
- // First check to see if the module has a symbol file in mind already.
- // If it does, then we MUST use that.
- FileSpec dsym_fspec (module_sp->GetSymbolFileFileSpec());
-
- ObjectFileSP dsym_objfile_sp;
- if (!dsym_fspec)
- {
- // No symbol file was specified in the module, lets try and find
- // one ourselves.
- FileSpec file_spec = obj_file->GetFileSpec();
- if (!file_spec)
- file_spec = module_sp->GetFileSpec();
-
- ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
- module_spec.GetUUID() = module_sp->GetUUID();
- dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
- if (module_spec.GetSourceMappingList().GetSize())
- module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
- }
-
- 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);
- 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())
- {
- char dsym_path[PATH_MAX];
- if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
- {
- lldb_private::UUID dsym_uuid;
- if (dsym_objfile_sp->GetUUID(&dsym_uuid))
- {
- std::string uuid_str = dsym_uuid.GetAsString ();
- if (!uuid_str.empty())
- {
- char *resources = strstr (dsym_path, "/Contents/Resources/");
- if (resources)
- {
- char dsym_uuid_plist_path[PATH_MAX];
- 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())
- {
- ApplePropertyList plist(dsym_uuid_plist_path);
- if (plist)
- {
- std::string DBGBuildSourcePath;
- std::string DBGSourcePath;
-
- plist.GetValueAsString("DBGBuildSourcePath", DBGBuildSourcePath);
- plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty())
- {
- if (DBGSourcePath[0] == '~')
- {
- FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_sp->GetSourceMappingList().Append (ConstString(DBGBuildSourcePath), ConstString(DBGSourcePath), true);
- }
- }
- }
- }
+SymbolVendor *
+SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm) {
+ if (!module_sp)
+ return NULL;
+
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (!obj_file)
+ return NULL;
+
+ static ConstString obj_file_macho("mach-o");
+ ConstString obj_name = obj_file->GetPluginName();
+ if (obj_name != obj_file_macho)
+ return NULL;
+
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolVendorMacOSX::CreateInstance (module = %s)",
+ module_sp->GetFileSpec().GetPath().c_str());
+ SymbolVendorMacOSX *symbol_vendor = new SymbolVendorMacOSX(module_sp);
+ if (symbol_vendor) {
+ char path[PATH_MAX];
+ path[0] = '\0';
+
+ // Try and locate the dSYM file on Mac OS X
+ Timer scoped_timer2(
+ "SymbolVendorMacOSX::CreateInstance () locate dSYM",
+ "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
+ module_sp->GetFileSpec().GetPath().c_str());
+
+ // First check to see if the module has a symbol file in mind already.
+ // If it does, then we MUST use that.
+ FileSpec dsym_fspec(module_sp->GetSymbolFileFileSpec());
+
+ ObjectFileSP dsym_objfile_sp;
+ if (!dsym_fspec) {
+ // No symbol file was specified in the module, lets try and find
+ // one ourselves.
+ FileSpec file_spec = obj_file->GetFileSpec();
+ if (!file_spec)
+ file_spec = module_sp->GetFileSpec();
+
+ ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
+ module_spec.GetUUID() = module_sp->GetUUID();
+ dsym_fspec = Symbols::LocateExecutableSymbolFile(module_spec);
+ if (module_spec.GetSourceMappingList().GetSize())
+ module_sp->GetSourceMappingList().Append(
+ module_spec.GetSourceMappingList(), true);
+ }
+
+ 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);
+ 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()) {
+ char dsym_path[PATH_MAX];
+ if (module_sp->GetSourceMappingList().IsEmpty() &&
+ dsym_fspec.GetPath(dsym_path, sizeof(dsym_path))) {
+ lldb_private::UUID dsym_uuid;
+ if (dsym_objfile_sp->GetUUID(&dsym_uuid)) {
+ std::string uuid_str = dsym_uuid.GetAsString();
+ if (!uuid_str.empty()) {
+ char *resources = strstr(dsym_path, "/Contents/Resources/");
+ if (resources) {
+ char dsym_uuid_plist_path[PATH_MAX];
+ 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()) {
+ ApplePropertyList plist(dsym_uuid_plist_path);
+ if (plist) {
+ std::string DBGBuildSourcePath;
+ std::string DBGSourcePath;
+
+ plist.GetValueAsString("DBGBuildSourcePath",
+ DBGBuildSourcePath);
+ plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
+ if (!DBGBuildSourcePath.empty() &&
+ !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(),
+ true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_sp->GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath),
+ ConstString(DBGSourcePath), true);
+ }
+
+ // DBGSourcePathRemapping is a dictionary in the plist
+ // with
+ // keys which are DBGBuildSourcePath file paths and
+ // values which are DBGSourcePath file paths
+
+ StructuredData::ObjectSP plist_sp =
+ plist.GetStructuredData();
+ if (plist_sp.get() && plist_sp->GetAsDictionary() &&
+ plist_sp->GetAsDictionary()->HasKey(
+ "DBGSourcePathRemapping") &&
+ plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGSourcePathRemapping")
+ ->GetAsDictionary()) {
+
+ // In an early version of DBGSourcePathRemapping, the
+ // DBGSourcePath
+ // values were incorrect. If we have a newer style
+ // DBGSourcePathRemapping, there will be a DBGVersion
+ // key in the plist with version 2 or higher.
+ //
+ // If this is an old style DBGSourcePathRemapping,
+ // ignore the
+ // value half of the key-value remappings and use reuse
+ // the original
+ // gloal DBGSourcePath string.
+ bool new_style_source_remapping_dictionary = false;
+ std::string original_DBGSourcePath_value =
+ DBGSourcePath;
+ if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) {
+ std::string version_string =
+ plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGVersion")
+ ->GetStringValue("");
+ if (!version_string.empty() &&
+ isdigit(version_string[0])) {
+ int version_number = atoi(version_string.c_str());
+ if (version_number > 1) {
+ new_style_source_remapping_dictionary = true;
}
+ }
}
+
+ StructuredData::Dictionary *remappings_dict =
+ plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGSourcePathRemapping")
+ ->GetAsDictionary();
+ remappings_dict->ForEach(
+ [&module_sp, new_style_source_remapping_dictionary,
+ original_DBGSourcePath_value](
+ ConstString key,
+ StructuredData::Object *object) -> bool {
+ if (object && object->GetAsString()) {
+
+ // key is DBGBuildSourcePath
+ // object is DBGSourcePath
+ std::string DBGSourcePath =
+ object->GetStringValue();
+ if (new_style_source_remapping_dictionary ==
+ false &&
+ !original_DBGSourcePath_value.empty()) {
+ DBGSourcePath = original_DBGSourcePath_value;
+ }
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(
+ DBGSourcePath.c_str(), true);
+ DBGSourcePath =
+ resolved_source_path.GetPath();
+ }
+ module_sp->GetSourceMappingList().Append(
+ key, ConstString(DBGSourcePath), true);
+ }
+ return true;
+ });
+ }
}
+ }
}
-
- symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
- return symbol_vendor;
+ }
}
+ }
}
- // Just create our symbol vendor using the current objfile as this is either
- // an executable with no dSYM (that we could locate), an executable with
- // a dSYM that has a UUID that doesn't match.
- symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
+ symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+ return symbol_vendor;
+ }
}
- return symbol_vendor;
-}
-
+ // Just create our symbol vendor using the current objfile as this is either
+ // an executable with no dSYM (that we could locate), an executable with
+ // a dSYM that has a UUID that doesn't match.
+ symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
+ }
+ return symbol_vendor;
+}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-SymbolVendorMacOSX::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-SymbolVendorMacOSX::GetPluginVersion()
-{
- return 1;
+ConstString SymbolVendorMacOSX::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t SymbolVendorMacOSX::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
index 31a842ade86f..53b5291af031 100644
--- a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
+++ b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
@@ -10,49 +10,42 @@
#ifndef liblldb_SymbolVendorMacOSX_h_
#define liblldb_SymbolVendorMacOSX_h_
-#include "lldb/lldb-private.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/lldb-private.h"
-class SymbolVendorMacOSX : public lldb_private::SymbolVendor
-{
+class SymbolVendorMacOSX : public lldb_private::SymbolVendor {
public:
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SymbolVendor*
- CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);
+ static lldb_private::SymbolVendor *
+ CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm);
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolVendorMacOSX (const lldb::ModuleSP &module_sp);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolVendorMacOSX(const lldb::ModuleSP &module_sp);
- virtual
- ~SymbolVendorMacOSX();
+ virtual ~SymbolVendorMacOSX();
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual lldb_private::ConstString
- GetPluginName();
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual lldb_private::ConstString GetPluginName();
- virtual uint32_t
- GetPluginVersion();
+ virtual uint32_t GetPluginVersion();
private:
- DISALLOW_COPY_AND_ASSIGN (SymbolVendorMacOSX);
+ DISALLOW_COPY_AND_ASSIGN(SymbolVendorMacOSX);
};
-#endif // liblldb_SymbolVendorMacOSX_h_
+#endif // liblldb_SymbolVendorMacOSX_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
index 38998469dcbe..dcc532db2021 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -1,4 +1,5 @@
-//===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++ -*-===//
+//===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,8 +33,10 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetItemInfoHandler::g_get_item_info_function_name = "__lldb_backtrace_recording_get_item_info";
-const char *AppleGetItemInfoHandler::g_get_item_info_function_code = " \n\
+const char *AppleGetItemInfoHandler::g_get_item_info_function_name =
+ "__lldb_backtrace_recording_get_item_info";
+const char *AppleGetItemInfoHandler::g_get_item_info_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -97,294 +100,304 @@ extern \"C\"
";
AppleGetItemInfoHandler::AppleGetItemInfoHandler(Process *process)
- : m_process(process),
- m_get_item_info_impl_code(),
+ : m_process(process), m_get_item_info_impl_code(),
m_get_item_info_function_mutex(),
m_get_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_item_info_retbuffer_mutex()
-{
-}
+ m_get_item_info_retbuffer_mutex() {}
-AppleGetItemInfoHandler::~AppleGetItemInfoHandler ()
-{
-}
+AppleGetItemInfoHandler::~AppleGetItemInfoHandler() {}
-void
-AppleGetItemInfoHandler::Detach()
-{
+void AppleGetItemInfoHandler::Detach() {
- if (m_process && m_process->IsAlive() && m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_item_info_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_item_info_return_buffer_addr);
- }
+ if (m_process && m_process->IsAlive() &&
+ m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_item_info_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_item_info_return_buffer_addr);
+ }
}
// Compile our __lldb_backtrace_recording_get_item_info() function (from the
-// source above in g_get_item_info_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// source above in g_get_item_info_function_code) if we don't find that function
+// in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
//
-// Insert the __lldb_backtrace_recording_get_item_info into the inferior process if needed.
+// Insert the __lldb_backtrace_recording_get_item_info into the inferior process
+// if needed.
//
-// Write the get_item_info_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Write the get_item_info_arglist into the inferior's memory space to prepare
+// for the call.
+//
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
-lldb::addr_t
-AppleGetItemInfoHandler::SetupGetItemInfoFunction(Thread &thread, ValueList &get_item_info_arglist)
-{
- ExecutionContext exe_ctx(thread.shared_from_this());
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_item_info_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_item_info_function_mutex);
-
- // First stage is to make the UtilityFunction to hold our injected function:
-
- if (!m_get_item_info_impl_code.get())
- {
- if (g_get_item_info_function_code != NULL)
- {
- Error error;
- m_get_item_info_impl_code.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_item_info_function_code,
- eLanguageTypeObjC,
- g_get_item_info_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get utility function: %s.", error.AsCString());
- return args_addr;
- }
-
- if (!m_get_item_info_impl_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install get-item-info introspection.");
- diagnostics.Dump(log);
- }
- m_get_item_info_impl_code.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- log->Printf("No get-item-info introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Next make the runner function for our implementation utility function.
- Error error;
-
- TypeSystem *type_system = thread.GetProcess()->GetTarget().GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
- CompilerType get_item_info_return_type = type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
-
- get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(get_item_info_return_type,
- get_item_info_arglist,
- thread.shared_from_this(),
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Error Inserting get-item-info function: \"%s\".", error.AsCString());
- return args_addr;
- }
- }
- else
- {
- // If it's already made, then we can just retrieve the caller:
- get_item_info_caller = m_get_item_info_impl_code->GetFunctionCaller();
- if (!get_item_info_caller)
- {
- if (log)
- log->Printf ("Failed to get get-item-info introspection caller.");
- m_get_item_info_impl_code.reset();
- return args_addr;
- }
+lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
+ Thread &thread, ValueList &get_item_info_arglist) {
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_item_info_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_item_info_function_mutex);
+
+ // First stage is to make the UtilityFunction to hold our injected function:
+
+ if (!m_get_item_info_impl_code.get()) {
+ if (g_get_item_info_function_code != NULL) {
+ Error error;
+ m_get_item_info_impl_code.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_item_info_function_code, eLanguageTypeObjC,
+ g_get_item_info_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to get utility function: %s.",
+ error.AsCString());
+ return args_addr;
}
- }
- diagnostics.Clear();
-
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_item_info_caller->WriteFunctionArguments(exe_ctx, args_addr, get_item_info_arglist, diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing get-item-info function arguments.");
+ if (!m_get_item_info_impl_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install get-item-info introspection.");
diagnostics.Dump(log);
+ }
+ m_get_item_info_impl_code.reset();
+ return args_addr;
}
-
+ } else {
+ if (log)
+ log->Printf("No get-item-info introspection code found.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Next make the runner function for our implementation utility function.
+ Error error;
+
+ TypeSystem *type_system =
+ thread.GetProcess()->GetTarget().GetScratchTypeSystemForLanguage(
+ nullptr, eLanguageTypeC);
+ CompilerType get_item_info_return_type =
+ type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
+
+ get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(
+ get_item_info_return_type, get_item_info_arglist,
+ thread.shared_from_this(), error);
+ if (error.Fail() || get_item_info_caller == nullptr) {
+ if (log)
+ log->Printf("Error Inserting get-item-info function: \"%s\".",
+ error.AsCString());
return args_addr;
+ }
+ } else {
+ // If it's already made, then we can just retrieve the caller:
+ get_item_info_caller = m_get_item_info_impl_code->GetFunctionCaller();
+ if (!get_item_info_caller) {
+ if (log)
+ log->Printf("Failed to get get-item-info introspection caller.");
+ m_get_item_info_impl_code.reset();
+ return args_addr;
+ }
}
+ }
- return args_addr;
-}
+ diagnostics.Clear();
-AppleGetItemInfoHandler::GetItemInfoReturnInfo
-AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetItemInfoReturnInfo return_value;
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.item_buffer_size = 0;
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
- error.Clear();
-
- if (thread.SafeToCallFunctions() == false)
- {
- if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
- }
-
- // Set up the arguments for a call to
-
- // struct get_item_info_return_values
- // {
- // uint64_t item_info_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */
- // uint64_t item_info_buffer_size; /* the size of the items buffer from libBacktraceRecording */
- // };
- //
- // void __lldb_backtrace_recording_get_item_info
- // (struct get_item_info_return_values *return_buffer,
- // int debug,
- // uint64_t item,
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value item_value;
- item_value.SetValueType (Value::eValueTypeScalar);
- item_value.SetCompilerType (clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_item_info_retbuffer_mutex);
- if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_item_info_return_buffer_addr = bufaddr;
+ if (!get_item_info_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_item_info_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing get-item-info function arguments.");
+ diagnostics.Dump(log);
}
- ValueList argument_values;
-
- return_buffer_ptr_value.GetScalar() = m_get_item_info_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
+ return args_addr;
+ }
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
+ return args_addr;
+}
- item_value.GetScalar() = item;
- argument_values.PushValue (item_value);
+AppleGetItemInfoHandler::GetItemInfoReturnInfo
+AppleGetItemInfoHandler::GetItemInfo(Thread &thread, uint64_t item,
+ addr_t page_to_free,
+ uint64_t page_to_free_size, Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetItemInfoReturnInfo return_value;
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.item_buffer_size = 0;
+
+ error.Clear();
+
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
+
+ // Set up the arguments for a call to
+
+ // struct get_item_info_return_values
+ // {
+ // uint64_t item_info_buffer_ptr; /* the address of the items buffer
+ // from libBacktraceRecording */
+ // uint64_t item_info_buffer_size; /* the size of the items buffer from
+ // libBacktraceRecording */
+ // };
+ //
+ // void __lldb_backtrace_recording_get_item_info
+ // (struct
+ // get_item_info_return_values
+ // *return_buffer,
+ // int debug,
+ // uint64_t item,
+ // void *page_to_free,
+ // uint64_t page_to_free_size)
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value item_value;
+ item_value.SetValueType(Value::eValueTypeScalar);
+ item_value.SetCompilerType(clang_uint64_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_item_info_retbuffer_mutex);
+ if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
+ }
+ m_get_item_info_return_buffer_addr = bufaddr;
+ }
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
+ ValueList argument_values;
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
+ return_buffer_ptr_value.GetScalar() = m_get_item_info_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
- addr_t args_addr = SetupGetItemInfoFunction(thread, argument_values);
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
+ item_value.GetScalar() = item;
+ argument_values.PushValue(item_value);
- if (!m_get_item_info_impl_code)
- {
- error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_item_get_info");
- return return_value;
- }
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
- ExpressionResults func_call_ret;
- Value results;
- FunctionCaller *func_caller = m_get_item_info_impl_code->GetFunctionCaller();
- if (!func_caller)
- {
- if (log)
- log->Printf ("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
- error.SetErrorString("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
- return return_value;
- }
+ addr_t args_addr = SetupGetItemInfoFunction(thread, argument_values);
- func_call_ret = func_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call __introspection_dispatch_queue_item_get_info(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_item_info() for list of queues");
- return return_value;
- }
+ 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.CalculateExecutionContext(exe_ctx);
- return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ if (!m_get_item_info_impl_code) {
+ error.SetErrorString("Unable to compile function to call "
+ "__introspection_dispatch_queue_item_get_info");
+ return return_value;
+ }
- return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr + 8, 8, 0, error);
+ ExpressionResults func_call_ret;
+ Value results;
+ FunctionCaller *func_caller = m_get_item_info_impl_code->GetFunctionCaller();
+ if (!func_caller) {
+ if (log)
+ log->Printf("Could not retrieve function caller for "
+ "__introspection_dispatch_queue_item_get_info.");
+ error.SetErrorString("Could not retrieve function caller for "
+ "__introspection_dispatch_queue_item_get_info.");
+ return return_value;
+ }
- if (!error.Success())
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ func_call_ret = func_caller->ExecuteFunction(exe_ctx, &args_addr, options,
+ diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
if (log)
- log->Printf ("AppleGetItemInfoHandler called __introspection_dispatch_queue_item_get_info (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64, page_to_free, page_to_free_size, return_value.item_buffer_ptr, return_value.item_buffer_size);
+ log->Printf("Unable to call "
+ "__introspection_dispatch_queue_item_get_info(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call "
+ "__introspection_dispatch_queue_get_item_info() for "
+ "list of queues");
+ return return_value;
+ }
+ return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+ if (!error.Success() ||
+ return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
+ return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_item_info_return_buffer_addr + 8, 8, 0, error);
+
+ if (!error.Success()) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
return return_value;
+ }
+ if (log)
+ log->Printf("AppleGetItemInfoHandler called "
+ "__introspection_dispatch_queue_item_get_info (page_to_free == "
+ "0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64,
+ page_to_free, page_to_free_size, return_value.item_buffer_ptr,
+ return_value.item_buffer_size);
+
+ return return_value;
}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
index dc341d672d6a..c0581576bbf1 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
@@ -18,13 +18,14 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's __introspection_dispatch_queue_item_get_info()
+// calling libBacktraceRecording's
+// __introspection_dispatch_queue_item_get_info()
// function. The function in the inferior will return a struct by value
// with these members:
//
@@ -36,82 +37,83 @@
//
// The item_buffer pointer is an address in the inferior program's address
// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb.
+// lldb.
//
// The AppleGetItemInfoHandler object should persist so that the UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetItemInfoHandler {
public:
-
- AppleGetItemInfoHandler (lldb_private::Process *process);
-
- ~AppleGetItemInfoHandler();
-
- struct GetItemInfoReturnInfo
- {
- lldb::addr_t item_buffer_ptr; /* the address of the item buffer from libBacktraceRecording */
- lldb::addr_t item_buffer_size; /* the size of the item buffer from libBacktraceRecording */
-
- GetItemInfoReturnInfo() :
- item_buffer_ptr(LLDB_INVALID_ADDRESS),
- item_buffer_size(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the information about a work item by calling
- /// __introspection_dispatch_queue_item_get_info. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] item
- /// The introspection_dispatch_item_info_ref value for the item of interest.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the item_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetItemInfoReturnInfo
- GetItemInfo (Thread &thread, lldb::addr_t item, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
-
-
- void
- Detach ();
+ AppleGetItemInfoHandler(lldb_private::Process *process);
+
+ ~AppleGetItemInfoHandler();
+
+ struct GetItemInfoReturnInfo {
+ lldb::addr_t item_buffer_ptr; /* the address of the item buffer from
+ libBacktraceRecording */
+ lldb::addr_t item_buffer_size; /* the size of the item buffer from
+ libBacktraceRecording */
+
+ GetItemInfoReturnInfo()
+ : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the information about a work item by calling
+ /// __introspection_dispatch_queue_item_get_info. If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread
+ /// The thread to run this plan on.
+ ///
+ /// @param [in] item
+ /// The introspection_dispatch_item_info_ref value for the item of
+ /// interest.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the item_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetItemInfoReturnInfo GetItemInfo(Thread &thread, lldb::addr_t item,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
+
+ void Detach();
private:
+ lldb::addr_t SetupGetItemInfoFunction(Thread &thread,
+ ValueList &get_item_info_arglist);
- lldb::addr_t
- SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist);
-
- static const char *g_get_item_info_function_name;
- static const char *g_get_item_info_function_code;
+ static const char *g_get_item_info_function_name;
+ static const char *g_get_item_info_function_code;
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
- std::mutex m_get_item_info_function_mutex;
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
+ std::mutex m_get_item_info_function_mutex;
- lldb::addr_t m_get_item_info_return_buffer_addr;
- std::mutex m_get_item_info_retbuffer_mutex;
+ lldb::addr_t m_get_item_info_return_buffer_addr;
+ std::mutex m_get_item_info_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetItemInfoHandler_h_
+#endif // lldb_AppleGetItemInfoHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
index d311f5fb5f6e..fc91ba47ba18 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
@@ -1,4 +1,5 @@
-//===-- AppleGetPendingItemsHandler.cpp -------------------------------*- C++ -*-===//
+//===-- AppleGetPendingItemsHandler.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,8 +33,10 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetPendingItemsHandler::g_get_pending_items_function_name = "__lldb_backtrace_recording_get_pending_items";
-const char *AppleGetPendingItemsHandler::g_get_pending_items_function_code = " \n\
+const char *AppleGetPendingItemsHandler::g_get_pending_items_function_name =
+ "__lldb_backtrace_recording_get_pending_items";
+const char *AppleGetPendingItemsHandler::g_get_pending_items_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -101,290 +104,310 @@ extern \"C\"
";
AppleGetPendingItemsHandler::AppleGetPendingItemsHandler(Process *process)
- : m_process(process),
- m_get_pending_items_impl_code(),
+ : m_process(process), m_get_pending_items_impl_code(),
m_get_pending_items_function_mutex(),
m_get_pending_items_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_pending_items_retbuffer_mutex()
-{
-}
-
-AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler ()
-{
-}
-
-void
-AppleGetPendingItemsHandler::Detach()
-{
- if (m_process && m_process->IsAlive() && m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_pending_items_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_pending_items_return_buffer_addr);
- }
+ m_get_pending_items_retbuffer_mutex() {}
+
+AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler() {}
+
+void AppleGetPendingItemsHandler::Detach() {
+ if (m_process && m_process->IsAlive() &&
+ m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_pending_items_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_pending_items_return_buffer_addr);
+ }
}
// Compile our __lldb_backtrace_recording_get_pending_items() function (from the
-// source above in g_get_pending_items_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// source above in g_get_pending_items_function_code) if we don't find that
+// function in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
+//
+// Insert the __lldb_backtrace_recording_get_pending_items into the inferior
+// process if needed.
//
-// Insert the __lldb_backtrace_recording_get_pending_items into the inferior process if needed.
+// Write the get_pending_items_arglist into the inferior's memory space to
+// prepare for the call.
//
-// Write the get_pending_items_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
-lldb::addr_t
-AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(Thread &thread, ValueList &get_pending_items_arglist)
-{
- ThreadSP thread_sp (thread.shared_from_this());
- ExecutionContext exe_ctx (thread_sp);
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_pending_items_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_pending_items_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_pending_items_impl_code.get())
- {
- if (g_get_pending_items_function_code != NULL)
- {
- Error error;
- m_get_pending_items_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_pending_items_function_code,
- eLanguageTypeObjC,
- g_get_pending_items_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get UtilityFunction for pending-items introspection: %s.", error.AsCString());
- return args_addr;
- }
-
- if (!m_get_pending_items_impl_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install pending-items introspection.");
- diagnostics.Dump(log);
- }
- m_get_pending_items_impl_code.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- log->Printf("No pending-items introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Next make the runner function for our implementation utility function.
- Error error;
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
- get_pending_items_arglist,
- thread_sp,
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to install pending-items introspection function caller: %s.", error.AsCString());
- m_get_pending_items_impl_code.reset();
- return args_addr;
- }
+lldb::addr_t AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(
+ Thread &thread, ValueList &get_pending_items_arglist) {
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx(thread_sp);
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_pending_items_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_pending_items_function_mutex);
+
+ // First stage is to make the ClangUtility to hold our injected function:
+
+ if (!m_get_pending_items_impl_code.get()) {
+ if (g_get_pending_items_function_code != NULL) {
+ Error error;
+ m_get_pending_items_impl_code.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_pending_items_function_code, eLanguageTypeObjC,
+ g_get_pending_items_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to get UtilityFunction for pending-items "
+ "introspection: %s.",
+ error.AsCString());
+ return args_addr;
}
- }
-
- diagnostics.Clear();
- if (get_pending_items_caller == nullptr)
- {
+ if (!m_get_pending_items_impl_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install pending-items introspection.");
+ diagnostics.Dump(log);
+ }
+ m_get_pending_items_impl_code.reset();
+ return args_addr;
+ }
+ } else {
if (log)
- log->Printf ("Failed to get get_pending_items_caller.");
+ log->Printf("No pending-items introspection code found.");
return LLDB_INVALID_ADDRESS;
+ }
+
+ // Next make the runner function for our implementation utility function.
+ Error error;
+ ClangASTContext *clang_ast_context =
+ thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType get_pending_items_return_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ get_pending_items_caller =
+ m_get_pending_items_impl_code->MakeFunctionCaller(
+ get_pending_items_return_type, get_pending_items_arglist,
+ thread_sp, error);
+ if (error.Fail() || get_pending_items_caller == nullptr) {
+ if (log)
+ log->Printf("Failed to install pending-items introspection function "
+ "caller: %s.",
+ error.AsCString());
+ m_get_pending_items_impl_code.reset();
+ return args_addr;
+ }
}
-
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ }
- if (!get_pending_items_caller->WriteFunctionArguments(exe_ctx, args_addr, get_pending_items_arglist, diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing pending-items function arguments.");
- diagnostics.Dump(log);
- }
+ diagnostics.Clear();
- return args_addr;
+ if (get_pending_items_caller == nullptr) {
+ if (log)
+ log->Printf("Failed to get get_pending_items_caller.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+ if (!get_pending_items_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_pending_items_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing pending-items function arguments.");
+ diagnostics.Dump(log);
}
return args_addr;
+ }
+
+ return args_addr;
}
AppleGetPendingItemsHandler::GetPendingItemsReturnInfo
-AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetPendingItemsReturnInfo return_value;
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.items_buffer_size = 0;
- return_value.count = 0;
-
- error.Clear();
-
- if (thread.SafeToCallFunctions() == false)
- {
- if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
- }
-
- // Set up the arguments for a call to
-
- // struct get_pending_items_return_values
- // {
- // uint64_t pending_items_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */
- // uint64_t pending_items_buffer_size; /* the size of the items buffer from libBacktraceRecording */
- // uint64_t count; /* the number of items included in the queues buffer */
- // };
- //
- // void __lldb_backtrace_recording_get_pending_items
- // (struct get_pending_items_return_values *return_buffer,
- // int debug,
- // uint64_t /* dispatch_queue_t */ queue
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value queue_value;
- queue_value.SetValueType (Value::eValueTypeScalar);
- queue_value.SetCompilerType (clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_pending_items_retbuffer_mutex);
- if (m_get_pending_items_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_pending_items_return_buffer_addr = bufaddr;
+AppleGetPendingItemsHandler::GetPendingItems(Thread &thread, addr_t queue,
+ addr_t page_to_free,
+ uint64_t page_to_free_size,
+ Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetPendingItemsReturnInfo return_value;
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.items_buffer_size = 0;
+ return_value.count = 0;
+
+ error.Clear();
+
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
+
+ // Set up the arguments for a call to
+
+ // struct get_pending_items_return_values
+ // {
+ // uint64_t pending_items_buffer_ptr; /* the address of the items
+ // buffer from libBacktraceRecording */
+ // uint64_t pending_items_buffer_size; /* the size of the items buffer
+ // from libBacktraceRecording */
+ // uint64_t count; /* the number of items included in the
+ // queues buffer */
+ // };
+ //
+ // void __lldb_backtrace_recording_get_pending_items
+ // (struct
+ // get_pending_items_return_values
+ // *return_buffer,
+ // int debug,
+ // uint64_t /* dispatch_queue_t */
+ // queue
+ // void *page_to_free,
+ // uint64_t page_to_free_size)
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value queue_value;
+ queue_value.SetValueType(Value::eValueTypeScalar);
+ queue_value.SetCompilerType(clang_uint64_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_pending_items_retbuffer_mutex);
+ if (m_get_pending_items_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
}
+ m_get_pending_items_return_buffer_addr = bufaddr;
+ }
- ValueList argument_values;
+ ValueList argument_values;
- return_buffer_ptr_value.GetScalar() = m_get_pending_items_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
+ return_buffer_ptr_value.GetScalar() = m_get_pending_items_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
- queue_value.GetScalar() = queue;
- argument_values.PushValue (queue_value);
+ queue_value.GetScalar() = queue;
+ argument_values.PushValue(queue_value);
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
- addr_t args_addr = SetupGetPendingItemsFunction(thread, argument_values);
+ addr_t args_addr = SetupGetPendingItemsFunction(thread, argument_values);
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- FunctionCaller *get_pending_items_caller = m_get_pending_items_impl_code->GetFunctionCaller();
+ DiagnosticManager diagnostics;
+ ExecutionContext exe_ctx;
+ FunctionCaller *get_pending_items_caller =
+ m_get_pending_items_impl_code->GetFunctionCaller();
- EvaluateExpressionOptions options;
- options.SetUnwindOnError (true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(true);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTryAllThreads(false);
+ thread.CalculateExecutionContext(exe_ctx);
- if (get_pending_items_caller == NULL)
- {
- error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_get_pending_items");
- return return_value;
- }
-
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_pending_items_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call __introspection_dispatch_queue_get_pending_items(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_pending_items() for list of queues");
- return return_value;
- }
-
- return_value.items_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.items_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ if (get_pending_items_caller == NULL) {
+ error.SetErrorString("Unable to compile function to call "
+ "__introspection_dispatch_queue_get_pending_items");
+ return return_value;
+ }
- return_value.items_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr + 8, 8, 0, error);
+ ExpressionResults func_call_ret;
+ Value results;
+ func_call_ret = get_pending_items_caller->ExecuteFunction(
+ exe_ctx, &args_addr, options, diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ if (log)
+ log->Printf("Unable to call "
+ "__introspection_dispatch_queue_get_pending_items(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call "
+ "__introspection_dispatch_queue_get_pending_items() "
+ "for list of queues");
+ return return_value;
+ }
- if (!error.Success())
- {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.items_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_pending_items_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+ if (!error.Success() ||
+ return_value.items_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- return_value.count = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr + 16, 8, 0, error);
- if (!error.Success())
- {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.items_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_pending_items_return_buffer_addr + 8, 8, 0, error);
- if (log)
- log->Printf ("AppleGetPendingItemsHandler called __introspection_dispatch_queue_get_pending_items (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64 ", count = %" PRId64, page_to_free, page_to_free_size, return_value.items_buffer_ptr, return_value.items_buffer_size, return_value.count);
+ if (!error.Success()) {
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
+ return_value.count = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_pending_items_return_buffer_addr + 16, 8, 0, error);
+ if (!error.Success()) {
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
return return_value;
+ }
+
+ if (log)
+ log->Printf("AppleGetPendingItemsHandler called "
+ "__introspection_dispatch_queue_get_pending_items "
+ "(page_to_free == 0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64
+ ", count = %" PRId64,
+ page_to_free, page_to_free_size, return_value.items_buffer_ptr,
+ return_value.items_buffer_size, return_value.count);
+
+ return return_value;
}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
index 96fbf4a548c4..824619f5cfe0 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
@@ -1,4 +1,5 @@
-//===-- AppleGetPendingItemsHandler.h ----------------------------*- C++ -*-===//
+//===-- AppleGetPendingItemsHandler.h ----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,12 +19,13 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's __introspection_dispatch_queue_get_pending_items()
+// calling libBacktraceRecording's
+// __introspection_dispatch_queue_get_pending_items()
// function. The function in the inferior will return a struct by value
// with these members:
//
@@ -38,82 +40,85 @@
// space (items_buffer_size in size) which must be mach_vm_deallocate'd by
// lldb. count is the number of items that were stored in the buffer.
//
-// The AppleGetPendingItemsHandler object should persist so that the UtilityFunction
+// The AppleGetPendingItemsHandler object should persist so that the
+// UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetPendingItemsHandler {
public:
+ AppleGetPendingItemsHandler(lldb_private::Process *process);
- AppleGetPendingItemsHandler (lldb_private::Process *process);
-
- ~AppleGetPendingItemsHandler();
-
- struct GetPendingItemsReturnInfo
- {
- lldb::addr_t items_buffer_ptr; /* the address of the pending items buffer from libBacktraceRecording */
- lldb::addr_t items_buffer_size; /* the size of the pending items buffer from libBacktraceRecording */
- uint64_t count; /* the number of pending items included in the buffer */
-
- GetPendingItemsReturnInfo () :
- items_buffer_ptr(LLDB_INVALID_ADDRESS),
- items_buffer_size(0),
- count(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the list of pending items for a given queue via a call to
- /// __introspection_dispatch_queue_get_pending_items. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] queue
- /// The dispatch_queue_t value for the queue of interest.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the items_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetPendingItemsReturnInfo
- GetPendingItems (Thread &thread, lldb::addr_t queue, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
-
-
- void
- Detach ();
-
-private:
+ ~AppleGetPendingItemsHandler();
+ struct GetPendingItemsReturnInfo {
+ lldb::addr_t items_buffer_ptr; /* the address of the pending items buffer
+ from libBacktraceRecording */
lldb::addr_t
- SetupGetPendingItemsFunction (Thread &thread, ValueList &get_pending_items_arglist);
+ items_buffer_size; /* the size of the pending items buffer from
+ libBacktraceRecording */
+ uint64_t count; /* the number of pending items included in the buffer */
+
+ GetPendingItemsReturnInfo()
+ : items_buffer_ptr(LLDB_INVALID_ADDRESS), items_buffer_size(0),
+ count(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the list of pending items for a given queue via a call to
+ /// __introspection_dispatch_queue_get_pending_items. If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread
+ /// The thread to run this plan on.
+ ///
+ /// @param [in] queue
+ /// The dispatch_queue_t value for the queue of interest.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the items_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetPendingItemsReturnInfo GetPendingItems(Thread &thread, lldb::addr_t queue,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
+
+ void Detach();
+
+private:
+ lldb::addr_t
+ SetupGetPendingItemsFunction(Thread &thread,
+ ValueList &get_pending_items_arglist);
- static const char *g_get_pending_items_function_name;
- static const char *g_get_pending_items_function_code;
+ static const char *g_get_pending_items_function_name;
+ static const char *g_get_pending_items_function_code;
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
- std::mutex m_get_pending_items_function_mutex;
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
+ std::mutex m_get_pending_items_function_mutex;
- lldb::addr_t m_get_pending_items_return_buffer_addr;
- std::mutex m_get_pending_items_retbuffer_mutex;
+ lldb::addr_t m_get_pending_items_return_buffer_addr;
+ std::mutex m_get_pending_items_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetPendingItemsHandler_h_
+#endif // lldb_AppleGetPendingItemsHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
index e90fe6d5d17d..ddc56d8feb3c 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
@@ -31,8 +31,10 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetQueuesHandler::g_get_current_queues_function_name = "__lldb_backtrace_recording_get_current_queues";
-const char *AppleGetQueuesHandler::g_get_current_queues_function_code = " \n\
+const char *AppleGetQueuesHandler::g_get_current_queues_function_name =
+ "__lldb_backtrace_recording_get_current_queues";
+const char *AppleGetQueuesHandler::g_get_current_queues_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -97,31 +99,26 @@ extern \"C\"
";
AppleGetQueuesHandler::AppleGetQueuesHandler(Process *process)
- : m_process(process),
- m_get_queues_impl_code_up(),
+ : m_process(process), m_get_queues_impl_code_up(),
m_get_queues_function_mutex(),
m_get_queues_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_queues_retbuffer_mutex()
-{
-}
+ m_get_queues_retbuffer_mutex() {}
-AppleGetQueuesHandler::~AppleGetQueuesHandler ()
-{
-}
+AppleGetQueuesHandler::~AppleGetQueuesHandler() {}
-void
-AppleGetQueuesHandler::Detach()
-{
+void AppleGetQueuesHandler::Detach() {
- if (m_process && m_process->IsAlive() && m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_queues_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_queues_return_buffer_addr);
- }
+ if (m_process && m_process->IsAlive() &&
+ m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_queues_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_queues_return_buffer_addr);
+ }
}
-// Construct a CompilerType for the structure that g_get_current_queues_function_code will return by value
+// Construct a CompilerType for the structure that
+// g_get_current_queues_function_code will return by value
// so we can extract the fields after performing the function call.
// i.e. we are getting this struct returned to us:
//
@@ -132,262 +129,283 @@ AppleGetQueuesHandler::Detach()
// uint64_t count;
// };
-
-// Compile our __lldb_backtrace_recording_get_current_queues() function (from the
-// source above in g_get_current_queues_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// Compile our __lldb_backtrace_recording_get_current_queues() function (from
+// the
+// source above in g_get_current_queues_function_code) if we don't find that
+// function in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
+//
+// Insert the __lldb_backtrace_recording_get_current_queues into the inferior
+// process if needed.
//
-// Insert the __lldb_backtrace_recording_get_current_queues into the inferior process if needed.
+// Write the get_queues_arglist into the inferior's memory space to prepare for
+// the call.
//
-// Write the get_queues_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
lldb::addr_t
-AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist)
-{
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx (thread_sp);
-
- Address impl_code_address;
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
-
- FunctionCaller *get_queues_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_queues_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_queues_impl_code_up.get())
- {
- if (g_get_current_queues_function_code != NULL)
- {
- Error error;
- m_get_queues_impl_code_up.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_current_queues_function_code,
- eLanguageTypeC,
- g_get_current_queues_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get UtilityFunction for queues introspection: %s.", error.AsCString());
- return args_addr;
- }
-
- if (!m_get_queues_impl_code_up->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install queues introspection");
- diagnostics.Dump(log);
- }
- m_get_queues_impl_code_up.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- {
- log->Printf("No queues introspection code found.");
- diagnostics.Dump(log);
- }
- return LLDB_INVALID_ADDRESS;
- }
- }
+AppleGetQueuesHandler::SetupGetQueuesFunction(Thread &thread,
+ ValueList &get_queues_arglist) {
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx(thread_sp);
- // Next make the runner function for our implementation utility function.
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Error error;
- get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
- get_queues_arglist,
- thread_sp,
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Could not get function caller for get-queues function: %s.", error.AsCString());
- return args_addr;
- }
- }
+ Address impl_code_address;
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+ FunctionCaller *get_queues_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_queues_function_mutex);
- diagnostics.Clear();
+ // First stage is to make the ClangUtility to hold our injected function:
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ if (!m_get_queues_impl_code_up.get()) {
+ if (g_get_current_queues_function_code != NULL) {
+ Error error;
+ m_get_queues_impl_code_up.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_current_queues_function_code, eLanguageTypeC,
+ g_get_current_queues_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Failed to get UtilityFunction for queues introspection: %s.",
+ error.AsCString());
+ return args_addr;
+ }
- if (!get_queues_caller->WriteFunctionArguments(exe_ctx, args_addr, get_queues_arglist, diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing get-queues function arguments.");
+ if (!m_get_queues_impl_code_up->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install queues introspection");
diagnostics.Dump(log);
+ }
+ m_get_queues_impl_code_up.reset();
+ return args_addr;
+ }
+ } else {
+ if (log) {
+ log->Printf("No queues introspection code found.");
+ diagnostics.Dump(log);
}
- return args_addr;
+ return LLDB_INVALID_ADDRESS;
+ }
}
- return args_addr;
-}
+ // Next make the runner function for our implementation utility function.
+ ClangASTContext *clang_ast_context =
+ thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType get_queues_return_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Error error;
+ get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller(
+ get_queues_return_type, get_queues_arglist, thread_sp, error);
+ if (error.Fail() || get_queues_caller == nullptr) {
+ if (log)
+ log->Printf(
+ "Could not get function caller for get-queues function: %s.",
+ error.AsCString());
+ return args_addr;
+ }
+ }
-AppleGetQueuesHandler::GetQueuesReturnInfo
-AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetQueuesReturnInfo return_value;
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.queues_buffer_size = 0;
- return_value.count = 0;
+ diagnostics.Clear();
- error.Clear();
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (thread.SafeToCallFunctions() == false)
- {
- if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
+ if (!get_queues_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_queues_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing get-queues function arguments.");
+ diagnostics.Dump(log);
}
+ return args_addr;
+ }
- // Set up the arguments for a call to
-
- // struct get_current_queues_return_values
- // {
- // uint64_t queues_buffer_ptr; /* the address of the queues buffer from libBacktraceRecording */
- // uint64_t queues_buffer_size; /* the size of the queues buffer from libBacktraceRecording */
- // uint64_t count; /* the number of queues included in the queues buffer */
- // };
- //
- // void
- // __lldb_backtrace_recording_get_current_queues
- // (struct get_current_queues_return_values *return_buffer,
- // void *page_to_free,
- // uint64_t page_to_free_size);
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_queues_retbuffer_mutex);
- if (m_get_queues_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_queues_return_buffer_addr = bufaddr;
- }
+ return args_addr;
+}
- ValueList argument_values;
+AppleGetQueuesHandler::GetQueuesReturnInfo
+AppleGetQueuesHandler::GetCurrentQueues(Thread &thread, addr_t page_to_free,
+ uint64_t page_to_free_size,
+ Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetQueuesReturnInfo return_value;
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.queues_buffer_size = 0;
+ return_value.count = 0;
+
+ error.Clear();
+
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
+
+ // Set up the arguments for a call to
+
+ // struct get_current_queues_return_values
+ // {
+ // uint64_t queues_buffer_ptr; /* the address of the queues buffer from
+ // libBacktraceRecording */
+ // uint64_t queues_buffer_size; /* the size of the queues buffer from
+ // libBacktraceRecording */
+ // uint64_t count; /* the number of queues included in the
+ // queues buffer */
+ // };
+ //
+ // void
+ // __lldb_backtrace_recording_get_current_queues
+ // (struct
+ // get_current_queues_return_values
+ // *return_buffer,
+ // void *page_to_free,
+ // uint64_t page_to_free_size);
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_queues_retbuffer_mutex);
+ if (m_get_queues_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
+ }
+ m_get_queues_return_buffer_addr = bufaddr;
+ }
- return_buffer_ptr_value.GetScalar() = m_get_queues_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
+ ValueList argument_values;
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
+ return_buffer_ptr_value.GetScalar() = m_get_queues_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
- addr_t args_addr = SetupGetQueuesFunction (thread, argument_values);
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
- if (!m_get_queues_impl_code_up)
- {
- error.SetErrorString ("Unable to compile __introspection_dispatch_get_queues.");
- return return_value;
- }
-
- FunctionCaller *get_queues_caller = m_get_queues_impl_code_up->GetFunctionCaller();
-
- if (get_queues_caller == NULL)
- {
- error.SetErrorString ("Unable to get caller for call __introspection_dispatch_get_queues");
- return return_value;
- }
+ addr_t args_addr = SetupGetQueuesFunction(thread, argument_values);
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
-
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_queues_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call introspection_get_dispatch_queues(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call introspection_get_dispatch_queues() for list of queues");
- return return_value;
- }
+ if (!m_get_queues_impl_code_up) {
+ error.SetErrorString(
+ "Unable to compile __introspection_dispatch_get_queues.");
+ return return_value;
+ }
- return_value.queues_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.queues_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ FunctionCaller *get_queues_caller =
+ m_get_queues_impl_code_up->GetFunctionCaller();
- return_value.queues_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr + 8, 8, 0, error);
+ if (get_queues_caller == NULL) {
+ error.SetErrorString(
+ "Unable to get caller for call __introspection_dispatch_get_queues");
+ return return_value;
+ }
+
+ 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.CalculateExecutionContext(exe_ctx);
+
+ ExpressionResults func_call_ret;
+ Value results;
+ func_call_ret = get_queues_caller->ExecuteFunction(
+ exe_ctx, &args_addr, options, diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ if (log)
+ log->Printf("Unable to call introspection_get_dispatch_queues(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call introspection_get_dispatch_queues() "
+ "for list of queues");
+ return return_value;
+ }
- if (!error.Success())
- {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.queues_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_queues_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+ if (!error.Success() ||
+ return_value.queues_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- return_value.count = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr + 16, 8, 0, error);
- if (!error.Success())
- {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.queues_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_queues_return_buffer_addr + 8, 8, 0, error);
- if (log)
- log->Printf ("AppleGetQueuesHandler called __introspection_dispatch_get_queues (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64 ", count = %" PRId64, page_to_free, page_to_free_size, return_value.queues_buffer_ptr, return_value.queues_buffer_size, return_value.count);
+ if (!error.Success()) {
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
+ return_value.count = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_queues_return_buffer_addr + 16, 8, 0, error);
+ if (!error.Success()) {
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
return return_value;
+ }
+
+ if (log)
+ log->Printf("AppleGetQueuesHandler called "
+ "__introspection_dispatch_get_queues (page_to_free == "
+ "0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64
+ ", count = %" PRId64,
+ page_to_free, page_to_free_size, return_value.queues_buffer_ptr,
+ return_value.queues_buffer_size, return_value.count);
+
+ return return_value;
}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
index b7ca26dafc30..b3965667bb3e 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
@@ -18,9 +18,9 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
// calling libBacktraceRecording's introspection_get_dispatch_queues()
@@ -41,76 +41,76 @@
// The AppleGetQueuesHandler object should persist so that the UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetQueuesHandler {
public:
-
- AppleGetQueuesHandler (lldb_private::Process *process);
-
- ~AppleGetQueuesHandler();
-
- struct GetQueuesReturnInfo
- {
- lldb::addr_t queues_buffer_ptr; /* the address of the queues buffer from libBacktraceRecording */
- lldb::addr_t queues_buffer_size; /* the size of the queues buffer from libBacktraceRecording */
- uint64_t count; /* the number of queues included in the queues buffer */
-
- GetQueuesReturnInfo() :
- queues_buffer_ptr(LLDB_INVALID_ADDRESS),
- queues_buffer_size(0),
- count(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the list of queues that exist (with any active or pending items) via
- /// a call to introspection_get_dispatch_queues(). If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the queues_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetQueuesReturnInfo
- GetCurrentQueues (Thread &thread, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
-
-
- void
- Detach ();
+ AppleGetQueuesHandler(lldb_private::Process *process);
+
+ ~AppleGetQueuesHandler();
+
+ struct GetQueuesReturnInfo {
+ lldb::addr_t queues_buffer_ptr; /* the address of the queues buffer from
+ libBacktraceRecording */
+ lldb::addr_t queues_buffer_size; /* the size of the queues buffer from
+ libBacktraceRecording */
+ uint64_t count; /* the number of queues included in the queues buffer */
+
+ GetQueuesReturnInfo()
+ : queues_buffer_ptr(LLDB_INVALID_ADDRESS), queues_buffer_size(0),
+ count(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the list of queues that exist (with any active or pending items) via
+ /// a call to introspection_get_dispatch_queues(). If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread
+ /// The thread to run this plan on.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the queues_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetQueuesReturnInfo GetCurrentQueues(Thread &thread,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
+
+ void Detach();
private:
+ lldb::addr_t SetupGetQueuesFunction(Thread &thread,
+ ValueList &get_queues_arglist);
- lldb::addr_t
- SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist);
-
- static const char *g_get_current_queues_function_name;
- static const char *g_get_current_queues_function_code;
+ static const char *g_get_current_queues_function_name;
+ static const char *g_get_current_queues_function_code;
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
- std::mutex m_get_queues_function_mutex;
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
+ std::mutex m_get_queues_function_mutex;
- lldb::addr_t m_get_queues_return_buffer_addr;
- std::mutex m_get_queues_retbuffer_mutex;
+ lldb::addr_t m_get_queues_return_buffer_addr;
+ std::mutex m_get_queues_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetQueuesHandler_h_
+#endif // lldb_AppleGetQueuesHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
index 85ad012c59fc..c05523e0f333 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
@@ -1,4 +1,5 @@
-//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++ -*-===//
+//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -35,8 +36,12 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_name = "__lldb_backtrace_recording_get_thread_item_info";
-const char *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_code = " \n\
+const char
+ *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_name =
+ "__lldb_backtrace_recording_get_thread_item_info";
+const char
+ *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -104,291 +109,311 @@ extern \"C\"
";
AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler(Process *process)
- : m_process(process),
- m_get_thread_item_info_impl_code(),
+ : m_process(process), m_get_thread_item_info_impl_code(),
m_get_thread_item_info_function_mutex(),
m_get_thread_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_thread_item_info_retbuffer_mutex()
-{
-}
+ m_get_thread_item_info_retbuffer_mutex() {}
-AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler ()
-{
-}
+AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler() {}
-void
-AppleGetThreadItemInfoHandler::Detach()
-{
+void AppleGetThreadItemInfoHandler::Detach() {
- if (m_process && m_process->IsAlive() && m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_thread_item_info_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr);
- }
+ if (m_process && m_process->IsAlive() &&
+ m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_thread_item_info_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr);
+ }
}
-// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from the
-// source above in g_get_thread_item_info_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from
+// the
+// source above in g_get_thread_item_info_function_code) if we don't find that
+// function in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
//
-// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior process if needed.
+// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior
+// process if needed.
//
-// Write the get_thread_item_info_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Write the get_thread_item_info_arglist into the inferior's memory space to
+// prepare for the call.
+//
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
-lldb::addr_t
-AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist)
-{
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx (thread_sp);
- Address impl_code_address;
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_thread_item_info_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_thread_item_info_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_thread_item_info_impl_code.get())
- {
- Error error;
- if (g_get_thread_item_info_function_code != NULL)
- {
- m_get_thread_item_info_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_thread_item_info_function_code,
- eLanguageTypeC,
- g_get_thread_item_info_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get UtilityFunction for get-thread-item-info introspection: %s.",
- error.AsCString());
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
-
- if (!m_get_thread_item_info_impl_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install get-thread-item-info introspection.");
- diagnostics.Dump(log);
- }
-
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- log->Printf("No get-thread-item-info introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Also make the FunctionCaller for this UtilityFunction:
-
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_thread_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- get_thread_item_info_caller = m_get_thread_item_info_impl_code->MakeFunctionCaller (get_thread_item_info_return_type,
- get_thread_item_info_arglist,
- thread_sp,
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to install get-thread-item-info introspection caller: %s.", error.AsCString());
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
-
- }
- else
- {
- get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
+lldb::addr_t AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction(
+ Thread &thread, ValueList &get_thread_item_info_arglist) {
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx(thread_sp);
+ Address impl_code_address;
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_thread_item_info_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_thread_item_info_function_mutex);
+
+ // First stage is to make the ClangUtility to hold our injected function:
+
+ if (!m_get_thread_item_info_impl_code.get()) {
+ Error error;
+ if (g_get_thread_item_info_function_code != NULL) {
+ m_get_thread_item_info_impl_code.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_thread_item_info_function_code, eLanguageTypeC,
+ g_get_thread_item_info_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to get UtilityFunction for "
+ "get-thread-item-info introspection: %s.",
+ error.AsCString());
+ m_get_thread_item_info_impl_code.reset();
+ return args_addr;
}
- }
- diagnostics.Clear();
-
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_thread_item_info_caller->WriteFunctionArguments(exe_ctx, args_addr, get_thread_item_info_arglist,
- diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing get-thread-item-info function arguments");
+ if (!m_get_thread_item_info_impl_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf(
+ "Failed to install get-thread-item-info introspection.");
diagnostics.Dump(log);
+ }
+
+ m_get_thread_item_info_impl_code.reset();
+ return args_addr;
}
+ } else {
+ if (log)
+ log->Printf("No get-thread-item-info introspection code found.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Also make the FunctionCaller for this UtilityFunction:
+
+ ClangASTContext *clang_ast_context =
+ thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType get_thread_item_info_return_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ get_thread_item_info_caller =
+ m_get_thread_item_info_impl_code->MakeFunctionCaller(
+ get_thread_item_info_return_type, get_thread_item_info_arglist,
+ thread_sp, error);
+ if (error.Fail() || get_thread_item_info_caller == nullptr) {
+ if (log)
+ log->Printf("Failed to install get-thread-item-info introspection "
+ "caller: %s.",
+ error.AsCString());
+ m_get_thread_item_info_impl_code.reset();
return args_addr;
- }
+ }
- return args_addr;
-}
+ } else {
+ get_thread_item_info_caller =
+ m_get_thread_item_info_impl_code->GetFunctionCaller();
+ }
+ }
-AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo
-AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_id, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetThreadItemInfoReturnInfo return_value;
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.item_buffer_size = 0;
+ diagnostics.Clear();
- error.Clear();
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (thread.SafeToCallFunctions() == false)
- {
- if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
+ if (!get_thread_item_info_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_thread_item_info_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing get-thread-item-info function arguments");
+ diagnostics.Dump(log);
}
+ return args_addr;
+ }
- // Set up the arguments for a call to
-
- // struct get_thread_item_info_return_values
- // {
- // uint64_t item_info_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */
- // uint64_t item_info_buffer_size; /* the size of the items buffer from libBacktraceRecording */
- // };
- //
- // void __lldb_backtrace_recording_get_thread_item_info
- // (struct get_thread_item_info_return_values *return_buffer,
- // int debug,
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value thread_id_value;
- thread_id_value.SetValueType (Value::eValueTypeScalar);
- thread_id_value.SetCompilerType (clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
- if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_thread_item_info_return_buffer_addr = bufaddr;
+ return args_addr;
+}
+
+AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo
+AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
+ tid_t thread_id,
+ addr_t page_to_free,
+ uint64_t page_to_free_size,
+ Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetThreadItemInfoReturnInfo return_value;
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.item_buffer_size = 0;
+
+ error.Clear();
+
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
+
+ // Set up the arguments for a call to
+
+ // struct get_thread_item_info_return_values
+ // {
+ // uint64_t item_info_buffer_ptr; /* the address of the items buffer
+ // from libBacktraceRecording */
+ // uint64_t item_info_buffer_size; /* the size of the items buffer from
+ // libBacktraceRecording */
+ // };
+ //
+ // void __lldb_backtrace_recording_get_thread_item_info
+ // (struct
+ // get_thread_item_info_return_values
+ // *return_buffer,
+ // int debug,
+ // void *page_to_free,
+ // uint64_t page_to_free_size)
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value thread_id_value;
+ thread_id_value.SetValueType(Value::eValueTypeScalar);
+ thread_id_value.SetCompilerType(clang_uint64_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
+ if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
}
+ m_get_thread_item_info_return_buffer_addr = bufaddr;
+ }
- ValueList argument_values;
+ ValueList argument_values;
- return_buffer_ptr_value.GetScalar() = m_get_thread_item_info_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
+ return_buffer_ptr_value.GetScalar() =
+ m_get_thread_item_info_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
- thread_id_value.GetScalar() = thread_id;
- argument_values.PushValue (thread_id_value);
+ thread_id_value.GetScalar() = thread_id;
+ argument_values.PushValue(thread_id_value);
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
- addr_t args_addr = SetupGetThreadItemInfoFunction(thread, argument_values);
+ addr_t args_addr = SetupGetThreadItemInfoFunction(thread, argument_values);
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- FunctionCaller *get_thread_item_info_caller = nullptr;
+ DiagnosticManager diagnostics;
+ ExecutionContext exe_ctx;
+ EvaluateExpressionOptions options;
+ FunctionCaller *get_thread_item_info_caller = nullptr;
- options.SetUnwindOnError (true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(true);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTryAllThreads(false);
+ thread.CalculateExecutionContext(exe_ctx);
- if (!m_get_thread_item_info_impl_code)
- {
- error.SetErrorString ("Unable to compile function to call __introspection_dispatch_thread_get_item_info");
- return return_value;
- }
+ if (!m_get_thread_item_info_impl_code) {
+ error.SetErrorString("Unable to compile function to call "
+ "__introspection_dispatch_thread_get_item_info");
+ return return_value;
+ }
- get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
+ get_thread_item_info_caller =
+ m_get_thread_item_info_impl_code->GetFunctionCaller();
- if (!get_thread_item_info_caller)
- {
- error.SetErrorString ("Unable to compile function caller for __introspection_dispatch_thread_get_item_info");
- return return_value;
- }
+ if (!get_thread_item_info_caller) {
+ error.SetErrorString("Unable to compile function caller for "
+ "__introspection_dispatch_thread_get_item_info");
+ return return_value;
+ }
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_thread_item_info_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call __introspection_dispatch_thread_get_item_info(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call __introspection_dispatch_thread_get_item_info() for list of queues");
- return return_value;
- }
+ ExpressionResults func_call_ret;
+ Value results;
+ func_call_ret = get_thread_item_info_caller->ExecuteFunction(
+ exe_ctx, &args_addr, options, diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ if (log)
+ log->Printf("Unable to call "
+ "__introspection_dispatch_thread_get_item_info(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call "
+ "__introspection_dispatch_thread_get_item_info() for "
+ "list of queues");
+ return return_value;
+ }
- return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_thread_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_thread_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS,
+ error);
+ if (!error.Success() ||
+ return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_thread_item_info_return_buffer_addr + 8, 8, 0, error);
+ return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_thread_item_info_return_buffer_addr + 8, 8, 0, error);
- if (!error.Success())
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ if (!error.Success()) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- if (log)
- log->Printf ("AppleGetThreadItemInfoHandler called __introspection_dispatch_thread_get_item_info (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64, page_to_free, page_to_free_size, return_value.item_buffer_ptr, return_value.item_buffer_size);
+ if (log)
+ log->Printf("AppleGetThreadItemInfoHandler called "
+ "__introspection_dispatch_thread_get_item_info (page_to_free "
+ "== 0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64,
+ page_to_free, page_to_free_size, return_value.item_buffer_ptr,
+ return_value.item_buffer_size);
- return return_value;
+ return return_value;
}
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
index 21a63e8c225a..f7804de40899 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
@@ -1,4 +1,5 @@
-//===-- AppleGetThreadItemInfoHandler.h ----------------------------*- C++ -*-===//
+//===-- AppleGetThreadItemInfoHandler.h ----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,12 +19,13 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's __introspection_dispatch_thread_get_item_info()
+// calling libBacktraceRecording's
+// __introspection_dispatch_thread_get_item_info()
// function. The function in the inferior will return a struct by value
// with these members:
//
@@ -35,79 +37,82 @@
//
// The item_buffer pointer is an address in the inferior program's address
// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb.
+// lldb.
//
-// The AppleGetThreadItemInfoHandler object should persist so that the UtilityFunction
+// The AppleGetThreadItemInfoHandler object should persist so that the
+// UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetThreadItemInfoHandler {
public:
-
- AppleGetThreadItemInfoHandler (lldb_private::Process *process);
-
- ~AppleGetThreadItemInfoHandler();
-
- struct GetThreadItemInfoReturnInfo
- {
- lldb::addr_t item_buffer_ptr; /* the address of the item buffer from libBacktraceRecording */
- lldb::addr_t item_buffer_size; /* the size of the item buffer from libBacktraceRecording */
-
- GetThreadItemInfoReturnInfo() :
- item_buffer_ptr(LLDB_INVALID_ADDRESS),
- item_buffer_size(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the information about a work item by calling
- /// __introspection_dispatch_thread_get_item_info. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread_id
- /// The thread to get the extended backtrace for.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the item_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetThreadItemInfoReturnInfo
- GetThreadItemInfo (Thread &thread, lldb::tid_t thread_id, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
-
-
- void
- Detach ();
+ AppleGetThreadItemInfoHandler(lldb_private::Process *process);
+
+ ~AppleGetThreadItemInfoHandler();
+
+ struct GetThreadItemInfoReturnInfo {
+ lldb::addr_t item_buffer_ptr; /* the address of the item buffer from
+ libBacktraceRecording */
+ lldb::addr_t item_buffer_size; /* the size of the item buffer from
+ libBacktraceRecording */
+
+ GetThreadItemInfoReturnInfo()
+ : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the information about a work item by calling
+ /// __introspection_dispatch_thread_get_item_info. If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread_id
+ /// The thread to get the extended backtrace for.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the item_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetThreadItemInfoReturnInfo GetThreadItemInfo(Thread &thread,
+ lldb::tid_t thread_id,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
+
+ void Detach();
private:
+ lldb::addr_t
+ SetupGetThreadItemInfoFunction(Thread &thread,
+ ValueList &get_thread_item_info_arglist);
- lldb::addr_t
- SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist);
-
- static const char *g_get_thread_item_info_function_name;
- static const char *g_get_thread_item_info_function_code;
+ static const char *g_get_thread_item_info_function_name;
+ static const char *g_get_thread_item_info_function_code;
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
- std::mutex m_get_thread_item_info_function_mutex;
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
+ std::mutex m_get_thread_item_info_function_mutex;
- lldb::addr_t m_get_thread_item_info_return_buffer_addr;
- std::mutex m_get_thread_item_info_retbuffer_mutex;
+ lldb::addr_t m_get_thread_item_info_return_buffer_addr;
+ std::mutex m_get_thread_item_info_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetThreadItemInfoHandler_h_
+#endif // lldb_AppleGetThreadItemInfoHandler_h_
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 9ec36b383af3..ec13dfa7fd78 100644
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -7,26 +7,25 @@
//
//===----------------------------------------------------------------------===//
-
+#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
-#include "Plugins/Process/Utility/HistoryThread.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Queue.h"
#include "lldb/Target/QueueList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/Process.h"
#include "lldb/Utility/ProcessStructReader.h"
#include "SystemRuntimeMacOSX.h"
@@ -39,397 +38,380 @@ using namespace lldb_private;
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-SystemRuntime *
-SystemRuntimeMacOSX::CreateInstance (Process* process)
-{
- bool create = false;
- if (!create)
- {
- create = true;
- Module* exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
+SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
+ bool create = false;
+ if (!create) {
+ create = true;
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataUser);
+ }
+ }
+
+ if (create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ create = triple_ref.getVendor() == llvm::Triple::Apple;
+ break;
+ default:
+ create = false;
+ break;
+ }
}
-
- if (create)
- return new SystemRuntimeMacOSX (process);
- return NULL;
+ }
+
+ if (create)
+ return new SystemRuntimeMacOSX(process);
+ return NULL;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
- : SystemRuntime(process),
- m_break_id(LLDB_INVALID_BREAK_ID),
- m_mutex(),
- m_get_queues_handler(process),
- m_get_pending_items_handler(process),
- m_get_item_info_handler(process),
- m_get_thread_item_info_handler(process),
- m_page_to_free(LLDB_INVALID_ADDRESS),
- m_page_to_free_size(0),
+ : SystemRuntime(process), m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
+ m_get_queues_handler(process), m_get_pending_items_handler(process),
+ m_get_item_info_handler(process), m_get_thread_item_info_handler(process),
+ m_page_to_free(LLDB_INVALID_ADDRESS), m_page_to_free_size(0),
m_lib_backtrace_recording_info(),
m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
m_libdispatch_offsets(),
m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
- m_libpthread_offsets(),
- m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
+ m_libpthread_offsets(), m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
m_libdispatch_tsd_indexes(),
m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
- m_libdispatch_voucher_offsets()
-{
-}
+ m_libdispatch_voucher_offsets() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-SystemRuntimeMacOSX::~SystemRuntimeMacOSX()
-{
- Clear (true);
-}
+SystemRuntimeMacOSX::~SystemRuntimeMacOSX() { Clear(true); }
-void
-SystemRuntimeMacOSX::Detach ()
-{
- m_get_queues_handler.Detach();
- m_get_pending_items_handler.Detach();
- m_get_item_info_handler.Detach();
- m_get_thread_item_info_handler.Detach();
+void SystemRuntimeMacOSX::Detach() {
+ m_get_queues_handler.Detach();
+ m_get_pending_items_handler.Detach();
+ m_get_item_info_handler.Detach();
+ m_get_thread_item_info_handler.Detach();
}
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-SystemRuntimeMacOSX::Clear (bool clear_process)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+void SystemRuntimeMacOSX::Clear(bool clear_process) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
+ if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->ClearBreakpointSiteByID(m_break_id);
- if (clear_process)
- m_process = NULL;
- m_break_id = LLDB_INVALID_BREAK_ID;
+ if (clear_process)
+ m_process = NULL;
+ m_break_id = LLDB_INVALID_BREAK_ID;
}
-
std::string
-SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress (addr_t dispatch_qaddr)
-{
- std::string dispatch_queue_name;
- if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
- return "";
-
- ReadLibdispatchOffsets ();
- if (m_libdispatch_offsets.IsValid ())
- {
- // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
- // deref it to get the address of the dispatch_queue_t structure for this thread's
- // queue.
- Error error;
- addr_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
- if (error.Success())
- {
- if (m_libdispatch_offsets.dqo_version >= 4)
- {
- // libdispatch versions 4+, pointer to dispatch name is in the
- // queue structure.
- addr_t pointer_to_label_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
- addr_t label_addr = m_process->ReadPointerFromMemory (pointer_to_label_address, error);
- if (error.Success())
- {
- m_process->ReadCStringFromMemory (label_addr, dispatch_queue_name, error);
- }
- }
- else
- {
- // libdispatch versions 1-3, dispatch name is a fixed width char array
- // in the queue structure.
- addr_t label_addr = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
- dispatch_queue_name.resize (m_libdispatch_offsets.dqo_label_size, '\0');
- size_t bytes_read = m_process->ReadMemory (label_addr, &dispatch_queue_name[0], m_libdispatch_offsets.dqo_label_size, error);
- if (bytes_read < m_libdispatch_offsets.dqo_label_size)
- dispatch_queue_name.erase (bytes_read);
- }
+SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr) {
+ std::string dispatch_queue_name;
+ if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
+ return "";
+
+ ReadLibdispatchOffsets();
+ if (m_libdispatch_offsets.IsValid()) {
+ // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
+ // thread -
+ // deref it to get the address of the dispatch_queue_t structure for this
+ // thread's
+ // queue.
+ Error error;
+ addr_t dispatch_queue_addr =
+ m_process->ReadPointerFromMemory(dispatch_qaddr, error);
+ if (error.Success()) {
+ if (m_libdispatch_offsets.dqo_version >= 4) {
+ // libdispatch versions 4+, pointer to dispatch name is in the
+ // queue structure.
+ addr_t pointer_to_label_address =
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+ addr_t label_addr =
+ m_process->ReadPointerFromMemory(pointer_to_label_address, error);
+ if (error.Success()) {
+ m_process->ReadCStringFromMemory(label_addr, dispatch_queue_name,
+ error);
}
+ } else {
+ // libdispatch versions 1-3, dispatch name is a fixed width char array
+ // in the queue structure.
+ addr_t label_addr =
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+ dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
+ size_t bytes_read =
+ m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
+ m_libdispatch_offsets.dqo_label_size, error);
+ if (bytes_read < m_libdispatch_offsets.dqo_label_size)
+ dispatch_queue_name.erase(bytes_read);
+ }
}
- return dispatch_queue_name;
+ }
+ return dispatch_queue_name;
}
-lldb::addr_t
-SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress (addr_t dispatch_qaddr)
-{
- addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
+lldb::addr_t SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress(
+ addr_t dispatch_qaddr) {
+ addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
+ Error error;
+ libdispatch_queue_t_address =
+ m_process->ReadPointerFromMemory(dispatch_qaddr, error);
+ if (!error.Success()) {
+ libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
+ }
+ return libdispatch_queue_t_address;
+}
+
+lldb::QueueKind SystemRuntimeMacOSX::GetQueueKind(addr_t dispatch_queue_addr) {
+ if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
+ return eQueueKindUnknown;
+
+ QueueKind kind = eQueueKindUnknown;
+ ReadLibdispatchOffsets();
+ if (m_libdispatch_offsets.IsValid() &&
+ m_libdispatch_offsets.dqo_version >= 4) {
Error error;
- libdispatch_queue_t_address = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
- if (!error.Success())
- {
- libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
+ uint64_t width = m_process->ReadUnsignedIntegerFromMemory(
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_width,
+ m_libdispatch_offsets.dqo_width_size, 0, error);
+ if (error.Success()) {
+ if (width == 1) {
+ kind = eQueueKindSerial;
+ }
+ if (width > 1) {
+ kind = eQueueKindConcurrent;
+ }
}
- return libdispatch_queue_t_address;
+ }
+ return kind;
}
-lldb::QueueKind
-SystemRuntimeMacOSX::GetQueueKind (addr_t dispatch_queue_addr)
-{
- if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
- return eQueueKindUnknown;
-
- QueueKind kind = eQueueKindUnknown;
- ReadLibdispatchOffsets ();
- if (m_libdispatch_offsets.IsValid () && m_libdispatch_offsets.dqo_version >= 4)
- {
- Error error;
- uint64_t width = m_process->ReadUnsignedIntegerFromMemory (dispatch_queue_addr + m_libdispatch_offsets.dqo_width, m_libdispatch_offsets.dqo_width_size, 0, error);
- if (error.Success())
- {
- if (width == 1)
- {
- kind = eQueueKindSerial;
- }
- if (width > 1)
- {
- kind = eQueueKindConcurrent;
- }
- }
+void SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints(
+ lldb_private::StructuredData::ObjectSP dict_sp) {
+ StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
+ if (dict) {
+ ReadLibpthreadOffsets();
+ if (m_libpthread_offsets.IsValid()) {
+ dict->AddIntegerItem("plo_pthread_tsd_base_offset",
+ m_libpthread_offsets.plo_pthread_tsd_base_offset);
+ dict->AddIntegerItem(
+ "plo_pthread_tsd_base_address_offset",
+ m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
+ dict->AddIntegerItem("plo_pthread_tsd_entry_size",
+ m_libpthread_offsets.plo_pthread_tsd_entry_size);
}
- return kind;
-}
-void
-SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints (lldb_private::StructuredData::ObjectSP dict_sp)
-{
- StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
- if (dict)
- {
- ReadLibpthreadOffsets();
- if (m_libpthread_offsets.IsValid())
- {
- dict->AddIntegerItem ("plo_pthread_tsd_base_offset", m_libpthread_offsets.plo_pthread_tsd_base_offset);
- dict->AddIntegerItem ("plo_pthread_tsd_base_address_offset", m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
- dict->AddIntegerItem ("plo_pthread_tsd_entry_size", m_libpthread_offsets.plo_pthread_tsd_entry_size);
- }
-
- ReadLibdispatchTSDIndexes ();
- if (m_libdispatch_tsd_indexes.IsValid())
- {
- dict->AddIntegerItem ("dti_queue_index", m_libdispatch_tsd_indexes.dti_queue_index);
- dict->AddIntegerItem ("dti_voucher_index", m_libdispatch_tsd_indexes.dti_voucher_index);
- dict->AddIntegerItem ("dti_qos_class_index", m_libdispatch_tsd_indexes.dti_qos_class_index);
- }
+ ReadLibdispatchTSDIndexes();
+ if (m_libdispatch_tsd_indexes.IsValid()) {
+ dict->AddIntegerItem("dti_queue_index",
+ m_libdispatch_tsd_indexes.dti_queue_index);
+ dict->AddIntegerItem("dti_voucher_index",
+ m_libdispatch_tsd_indexes.dti_voucher_index);
+ dict->AddIntegerItem("dti_qos_class_index",
+ m_libdispatch_tsd_indexes.dti_qos_class_index);
}
+ }
}
-bool
-SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread (ThreadSP thread_sp)
-{
- if (thread_sp && thread_sp->GetStackFrameCount() > 0 && thread_sp->GetFrameWithConcreteFrameIndex(0))
- {
- const SymbolContext sym_ctx (thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext (eSymbolContextSymbol));
- static ConstString g_select_symbol ("__select");
- if (sym_ctx.GetFunctionName() == g_select_symbol)
- {
- return false;
- }
+bool SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread(ThreadSP thread_sp) {
+ if (thread_sp && thread_sp->GetStackFrameCount() > 0 &&
+ thread_sp->GetFrameWithConcreteFrameIndex(0)) {
+ const SymbolContext sym_ctx(
+ thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext(
+ eSymbolContextSymbol));
+ static ConstString g_select_symbol("__select");
+ if (sym_ctx.GetFunctionName() == g_select_symbol) {
+ return false;
}
- return true;
+ }
+ return true;
}
lldb::queue_id_t
-SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr)
-{
- queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
-
- if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
- return queue_id;
-
- ReadLibdispatchOffsets ();
- if (m_libdispatch_offsets.IsValid ())
- {
- // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
- // deref it to get the address of the dispatch_queue_t structure for this thread's
- // queue.
- Error error;
- uint64_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
- if (error.Success())
- {
- addr_t serialnum_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
- queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory (serialnum_address, m_libdispatch_offsets.dqo_serialnum_size, LLDB_INVALID_QUEUE_ID, error);
- if (error.Success())
- {
- queue_id = serialnum;
- }
- }
- }
+SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
+ queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
+ if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
return queue_id;
-}
-
-void
-SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress ()
-{
- if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
- return;
+ ReadLibdispatchOffsets();
+ if (m_libdispatch_offsets.IsValid()) {
+ // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
+ // thread -
+ // deref it to get the address of the dispatch_queue_t structure for this
+ // thread's
+ // queue.
+ Error error;
+ uint64_t dispatch_queue_addr =
+ m_process->ReadPointerFromMemory(dispatch_qaddr, error);
+ if (error.Success()) {
+ addr_t serialnum_address =
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
+ queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory(
+ serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
+ LLDB_INVALID_QUEUE_ID, error);
+ if (error.Success()) {
+ queue_id = serialnum;
+ }
+ }
+ }
- static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
- const Symbol *dispatch_queue_offsets_symbol = NULL;
+ return queue_id;
+}
- // 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));
- ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule (libSystem_module_spec));
+void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
+ if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
+ return;
+
+ static ConstString g_dispatch_queue_offsets_symbol_name(
+ "dispatch_queue_offsets");
+ const Symbol *dispatch_queue_offsets_symbol = NULL;
+
+ // 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));
+ ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
+ libSystem_module_spec));
+ if (module_sp)
+ dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
+ g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
+
+ // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and
+ // later
+ if (dispatch_queue_offsets_symbol == NULL) {
+ ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib", false));
+ module_sp = m_process->GetTarget().GetImages().FindFirstModule(
+ libdispatch_module_spec);
if (module_sp)
- dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
-
- // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and later
- if (dispatch_queue_offsets_symbol == NULL)
- {
- ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false));
- module_sp = m_process->GetTarget().GetImages().FindFirstModule (libdispatch_module_spec);
- if (module_sp)
- dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
- }
- if (dispatch_queue_offsets_symbol)
- m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
+ dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
+ g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
+ }
+ if (dispatch_queue_offsets_symbol)
+ m_dispatch_queue_offsets_addr =
+ dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
}
-void
-SystemRuntimeMacOSX::ReadLibdispatchOffsets ()
-{
- if (m_libdispatch_offsets.IsValid())
- return;
-
- ReadLibdispatchOffsetsAddress ();
-
- uint8_t memory_buffer[sizeof (struct LibdispatchOffsets)];
- DataExtractor data (memory_buffer,
- sizeof(memory_buffer),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
-
- Error error;
- if (m_process->ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
- {
- lldb::offset_t data_offset = 0;
-
- // The struct LibdispatchOffsets is a series of uint16_t's - extract them all
- // in one big go.
- data.GetU16 (&data_offset, &m_libdispatch_offsets.dqo_version, sizeof (struct LibdispatchOffsets) / sizeof (uint16_t));
- }
+void SystemRuntimeMacOSX::ReadLibdispatchOffsets() {
+ if (m_libdispatch_offsets.IsValid())
+ return;
+
+ ReadLibdispatchOffsetsAddress();
+
+ uint8_t memory_buffer[sizeof(struct LibdispatchOffsets)];
+ DataExtractor data(memory_buffer, sizeof(memory_buffer),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+
+ Error error;
+ if (m_process->ReadMemory(m_dispatch_queue_offsets_addr, memory_buffer,
+ sizeof(memory_buffer),
+ error) == sizeof(memory_buffer)) {
+ lldb::offset_t data_offset = 0;
+
+ // The struct LibdispatchOffsets is a series of uint16_t's - extract them
+ // all
+ // in one big go.
+ data.GetU16(&data_offset, &m_libdispatch_offsets.dqo_version,
+ sizeof(struct LibdispatchOffsets) / sizeof(uint16_t));
+ }
}
-void
-SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress ()
-{
- if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_libpthread_layout_offsets_symbol_name ("pthread_layout_offsets");
- const Symbol *libpthread_layout_offsets_symbol = NULL;
-
- ModuleSpec libpthread_module_spec (FileSpec("libsystem_pthread.dylib", false));
- ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec));
- if (module_sp)
- {
- libpthread_layout_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType
- (g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
- if (libpthread_layout_offsets_symbol)
- {
- m_libpthread_layout_offsets_addr = libpthread_layout_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
- }
+void SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress() {
+ if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
+ return;
+
+ static ConstString g_libpthread_layout_offsets_symbol_name(
+ "pthread_layout_offsets");
+ const Symbol *libpthread_layout_offsets_symbol = NULL;
+
+ ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib", false));
+ ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
+ libpthread_module_spec));
+ if (module_sp) {
+ libpthread_layout_offsets_symbol =
+ module_sp->FindFirstSymbolWithNameAndType(
+ g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
+ if (libpthread_layout_offsets_symbol) {
+ m_libpthread_layout_offsets_addr =
+ libpthread_layout_offsets_symbol->GetLoadAddress(
+ &m_process->GetTarget());
}
+ }
}
-void
-SystemRuntimeMacOSX::ReadLibpthreadOffsets ()
-{
- if (m_libpthread_offsets.IsValid())
- return;
+void SystemRuntimeMacOSX::ReadLibpthreadOffsets() {
+ if (m_libpthread_offsets.IsValid())
+ return;
- ReadLibpthreadOffsetsAddress ();
+ ReadLibpthreadOffsetsAddress();
- if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
- {
- uint8_t memory_buffer[sizeof (struct LibpthreadOffsets)];
- DataExtractor data (memory_buffer,
- sizeof(memory_buffer),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
- Error error;
- if (m_process->ReadMemory (m_libpthread_layout_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
- {
- lldb::offset_t data_offset = 0;
-
- // The struct LibpthreadOffsets is a series of uint16_t's - extract them all
- // in one big go.
- data.GetU16 (&data_offset, &m_libpthread_offsets.plo_version, sizeof (struct LibpthreadOffsets) / sizeof (uint16_t));
- }
+ if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) {
+ uint8_t memory_buffer[sizeof(struct LibpthreadOffsets)];
+ DataExtractor data(memory_buffer, sizeof(memory_buffer),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ Error error;
+ if (m_process->ReadMemory(m_libpthread_layout_offsets_addr, memory_buffer,
+ sizeof(memory_buffer),
+ error) == sizeof(memory_buffer)) {
+ lldb::offset_t data_offset = 0;
+
+ // The struct LibpthreadOffsets is a series of uint16_t's - extract them
+ // all
+ // in one big go.
+ data.GetU16(&data_offset, &m_libpthread_offsets.plo_version,
+ sizeof(struct LibpthreadOffsets) / sizeof(uint16_t));
}
+ }
}
-void
-SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress ()
-{
- if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_libdispatch_tsd_indexes_symbol_name ("dispatch_tsd_indexes");
- const Symbol *libdispatch_tsd_indexes_symbol = NULL;
-
- ModuleSpec libpthread_module_spec (FileSpec("libdispatch.dylib", false));
- ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec));
- if (module_sp)
- {
- libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType
- (g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
- if (libdispatch_tsd_indexes_symbol)
- {
- m_dispatch_tsd_indexes_addr = libdispatch_tsd_indexes_symbol->GetLoadAddress(&m_process->GetTarget());
- }
+void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress() {
+ if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
+ return;
+
+ static ConstString g_libdispatch_tsd_indexes_symbol_name(
+ "dispatch_tsd_indexes");
+ const Symbol *libdispatch_tsd_indexes_symbol = NULL;
+
+ ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib", false));
+ ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
+ libpthread_module_spec));
+ if (module_sp) {
+ libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType(
+ g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
+ if (libdispatch_tsd_indexes_symbol) {
+ m_dispatch_tsd_indexes_addr =
+ libdispatch_tsd_indexes_symbol->GetLoadAddress(
+ &m_process->GetTarget());
}
+ }
}
-void
-SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes ()
-{
- if (m_libdispatch_tsd_indexes.IsValid())
- return;
+void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
+ if (m_libdispatch_tsd_indexes.IsValid())
+ return;
- ReadLibdispatchTSDIndexesAddress ();
+ ReadLibdispatchTSDIndexesAddress();
- if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
- {
+ if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
- // We don't need to check the version number right now, it will be at least 2, but
- // keep this code around to fetch just the version # for the future where we need
- // to fetch alternate versions of the struct.
-# if 0
+// We don't need to check the version number right now, it will be at least 2,
+// but
+// keep this code around to fetch just the version # for the future where we
+// need
+// to fetch alternate versions of the struct.
+#if 0
uint16_t dti_version = 2;
Address dti_struct_addr;
if (m_process->GetTarget().ResolveLoadAddress (m_dispatch_tsd_indexes_addr, dti_struct_addr))
@@ -443,141 +425,171 @@ SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes ()
}
#endif
- ClangASTContext *ast_ctx = m_process->GetTarget().GetScratchClangASTContext();
- if (ast_ctx->getASTContext() && m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
- {
- CompilerType uint16 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize (eEncodingUint, 16);
- CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct, lldb::eLanguageTypeC);
-
- ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_version", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_queue_index", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_voucher_index", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_qos_class_index", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
-
- ProcessStructReader struct_reader (m_process, m_dispatch_tsd_indexes_addr, dispatch_tsd_indexes_s);
-
- m_libdispatch_tsd_indexes.dti_version = struct_reader.GetField<uint16_t>(ConstString("dti_version"));
- m_libdispatch_tsd_indexes.dti_queue_index = struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
- m_libdispatch_tsd_indexes.dti_voucher_index = struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
- m_libdispatch_tsd_indexes.dti_qos_class_index = struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
- }
+ ClangASTContext *ast_ctx =
+ m_process->GetTarget().GetScratchClangASTContext();
+ if (ast_ctx->getASTContext() &&
+ m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
+ CompilerType uint16 =
+ ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
+ CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
+ nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
+ clang::TTK_Struct, lldb::eLanguageTypeC);
+
+ ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_version", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_queue_index", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_voucher_index", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_qos_class_index", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
+
+ ProcessStructReader struct_reader(m_process, m_dispatch_tsd_indexes_addr,
+ dispatch_tsd_indexes_s);
+
+ m_libdispatch_tsd_indexes.dti_version =
+ struct_reader.GetField<uint16_t>(ConstString("dti_version"));
+ m_libdispatch_tsd_indexes.dti_queue_index =
+ struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
+ m_libdispatch_tsd_indexes.dti_voucher_index =
+ struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
+ m_libdispatch_tsd_indexes.dti_qos_class_index =
+ struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
}
+ }
}
+ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread(ThreadSP real_thread,
+ ConstString type) {
+ ThreadSP originating_thread_sp;
+ if (BacktraceRecordingHeadersInitialized() &&
+ type == ConstString("libdispatch")) {
+ Error error;
-ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP real_thread, ConstString type)
-{
- ThreadSP originating_thread_sp;
- if (BacktraceRecordingHeadersInitialized() && type == ConstString ("libdispatch"))
- {
- Error error;
-
- // real_thread is either an actual, live thread (in which case we need to call into
- // libBacktraceRecording to find its originator) or it is an extended backtrace itself,
- // in which case we get the token from it and call into libBacktraceRecording to find
- // the originator of that token.
-
- if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS)
- {
- originating_thread_sp = GetExtendedBacktraceFromItemRef (real_thread->GetExtendedBacktraceToken());
- }
- else
- {
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret = m_get_thread_item_info_handler.GetThreadItemInfo (*cur_thread_sp.get(), real_thread->GetID(), m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
- {
- DataBufferHeap data (ret.item_buffer_size, 0);
- if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer (extractor);
- bool stop_id_is_valid = true;
- if (item.stop_id == 0)
- stop_id_is_valid = false;
- originating_thread_sp.reset (new HistoryThread (*m_process,
- item.enqueuing_thread_id,
- item.enqueuing_callstack,
- item.stop_id,
- stop_id_is_valid));
- originating_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
- originating_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
- originating_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
-// originating_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());
- }
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
+ // real_thread is either an actual, live thread (in which case we need to
+ // call into
+ // libBacktraceRecording to find its originator) or it is an extended
+ // backtrace itself,
+ // in which case we get the token from it and call into
+ // libBacktraceRecording to find
+ // the originator of that token.
+
+ if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS) {
+ originating_thread_sp = GetExtendedBacktraceFromItemRef(
+ real_thread->GetExtendedBacktraceToken());
+ } else {
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret =
+ m_get_thread_item_info_handler.GetThreadItemInfo(
+ *cur_thread_sp.get(), real_thread->GetID(), m_page_to_free,
+ m_page_to_free_size, error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (ret.item_buffer_ptr != 0 &&
+ ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
+ ret.item_buffer_size > 0) {
+ DataBufferHeap data(ret.item_buffer_size, 0);
+ if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
+ ret.item_buffer_size, error) &&
+ error.Success()) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ ItemInfo item = ExtractItemInfoFromBuffer(extractor);
+ bool stop_id_is_valid = true;
+ if (item.stop_id == 0)
+ stop_id_is_valid = false;
+ originating_thread_sp.reset(new HistoryThread(
+ *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
+ item.stop_id, stop_id_is_valid));
+ originating_thread_sp->SetExtendedBacktraceToken(
+ item.item_that_enqueued_this);
+ originating_thread_sp->SetQueueName(
+ item.enqueuing_queue_label.c_str());
+ originating_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
+ // originating_thread_sp->SetThreadName
+ // (item.enqueuing_thread_label.c_str());
}
+ m_page_to_free = ret.item_buffer_ptr;
+ m_page_to_free_size = ret.item_buffer_size;
+ }
}
- return originating_thread_sp;
+ }
+ return originating_thread_sp;
}
ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref)
-{
- ThreadSP return_thread_sp;
-
- AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- Error error;
- ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
- {
- DataBufferHeap data (ret.item_buffer_size, 0);
- if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer (extractor);
- bool stop_id_is_valid = true;
- if (item.stop_id == 0)
- stop_id_is_valid = false;
- return_thread_sp.reset (new HistoryThread (*m_process,
- item.enqueuing_thread_id,
- item.enqueuing_callstack,
- item.stop_id,
- stop_id_is_valid));
- return_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
- return_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
- return_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
-// return_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());
-
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
+SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref) {
+ ThreadSP return_thread_sp;
+
+ AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ Error error;
+ ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
+ m_page_to_free, m_page_to_free_size,
+ error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
+ ret.item_buffer_size > 0) {
+ DataBufferHeap data(ret.item_buffer_size, 0);
+ if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
+ ret.item_buffer_size, error) &&
+ error.Success()) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ ItemInfo item = ExtractItemInfoFromBuffer(extractor);
+ bool stop_id_is_valid = true;
+ if (item.stop_id == 0)
+ stop_id_is_valid = false;
+ return_thread_sp.reset(new HistoryThread(
+ *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
+ item.stop_id, stop_id_is_valid));
+ return_thread_sp->SetExtendedBacktraceToken(item.item_that_enqueued_this);
+ return_thread_sp->SetQueueName(item.enqueuing_queue_label.c_str());
+ return_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
+ // return_thread_sp->SetThreadName
+ // (item.enqueuing_thread_label.c_str());
+
+ m_page_to_free = ret.item_buffer_ptr;
+ m_page_to_free_size = ret.item_buffer_size;
}
- return return_thread_sp;
+ }
+ return return_thread_sp;
}
ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem (QueueItemSP queue_item_sp, ConstString type)
-{
- ThreadSP extended_thread_sp;
- if (type != ConstString("libdispatch"))
- return extended_thread_sp;
-
- bool stop_id_is_valid = true;
- if (queue_item_sp->GetStopID() == 0)
- stop_id_is_valid = false;
-
- extended_thread_sp.reset (new HistoryThread (*m_process,
- queue_item_sp->GetEnqueueingThreadID(),
- queue_item_sp->GetEnqueueingBacktrace(),
- queue_item_sp->GetStopID(),
- stop_id_is_valid));
- extended_thread_sp->SetExtendedBacktraceToken (queue_item_sp->GetItemThatEnqueuedThis());
- extended_thread_sp->SetQueueName (queue_item_sp->GetQueueLabel().c_str());
- extended_thread_sp->SetQueueID (queue_item_sp->GetEnqueueingQueueID());
-// extended_thread_sp->SetThreadName (queue_item_sp->GetThreadLabel().c_str());
-
+SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem(QueueItemSP queue_item_sp,
+ ConstString type) {
+ ThreadSP extended_thread_sp;
+ if (type != ConstString("libdispatch"))
return extended_thread_sp;
+
+ bool stop_id_is_valid = true;
+ if (queue_item_sp->GetStopID() == 0)
+ stop_id_is_valid = false;
+
+ extended_thread_sp.reset(
+ new HistoryThread(*m_process, queue_item_sp->GetEnqueueingThreadID(),
+ queue_item_sp->GetEnqueueingBacktrace(),
+ queue_item_sp->GetStopID(), stop_id_is_valid));
+ extended_thread_sp->SetExtendedBacktraceToken(
+ queue_item_sp->GetItemThatEnqueuedThis());
+ extended_thread_sp->SetQueueName(queue_item_sp->GetQueueLabel().c_str());
+ extended_thread_sp->SetQueueID(queue_item_sp->GetEnqueueingQueueID());
+ // extended_thread_sp->SetThreadName
+ // (queue_item_sp->GetThreadLabel().c_str());
+
+ return extended_thread_sp;
}
/* Returns true if we were able to get the version / offset information
@@ -585,438 +597,439 @@ SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem (QueueItemSP queue_item_sp
* this; the queue_info_version field will be 0.
*/
-bool
-SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized ()
-{
- if (m_lib_backtrace_recording_info.queue_info_version != 0)
- return true;
-
- addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
- addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
- addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
- addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
- Target &target = m_process->GetTarget();
-
-
- static ConstString introspection_dispatch_queue_info_version ("__introspection_dispatch_queue_info_version");
- SymbolContextList sc_list;
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- queue_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_queue_info_data_offset ("__introspection_dispatch_queue_info_data_offset");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_data_offset, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- queue_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_item_info_version ("__introspection_dispatch_item_info_version");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- item_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_item_info_data_offset ("__introspection_dispatch_item_info_data_offset");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_data_offset, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- item_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
+bool SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized() {
+ if (m_lib_backtrace_recording_info.queue_info_version != 0)
+ return true;
- if (queue_info_version_address != LLDB_INVALID_ADDRESS
- && queue_info_data_offset_address != LLDB_INVALID_ADDRESS
- && item_info_version_address != LLDB_INVALID_ADDRESS
- && item_info_data_offset_address != LLDB_INVALID_ADDRESS)
- {
- Error error;
- m_lib_backtrace_recording_info.queue_info_version = m_process->ReadUnsignedIntegerFromMemory (queue_info_version_address, 2, 0, error);
- if (error.Success())
- {
- m_lib_backtrace_recording_info.queue_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (queue_info_data_offset_address, 2, 0, error);
- if (error.Success())
- {
- m_lib_backtrace_recording_info.item_info_version = m_process->ReadUnsignedIntegerFromMemory (item_info_version_address, 2, 0, error);
- if (error.Success())
- {
- m_lib_backtrace_recording_info.item_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (item_info_data_offset_address, 2, 0, error);
- if (!error.Success())
- {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- }
- else
- {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- }
- else
- {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
+ addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
+ addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
+ addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
+ addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
+ Target &target = m_process->GetTarget();
+
+ static ConstString introspection_dispatch_queue_info_version(
+ "__introspection_dispatch_queue_info_version");
+ SymbolContextList sc_list;
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) >
+ 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ queue_info_version_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+ sc_list.Clear();
+
+ static ConstString introspection_dispatch_queue_info_data_offset(
+ "__introspection_dispatch_queue_info_data_offset");
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_queue_info_data_offset, eSymbolTypeData,
+ sc_list) > 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ queue_info_data_offset_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+ sc_list.Clear();
+
+ static ConstString introspection_dispatch_item_info_version(
+ "__introspection_dispatch_item_info_version");
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) >
+ 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ item_info_version_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+ sc_list.Clear();
+
+ static ConstString introspection_dispatch_item_info_data_offset(
+ "__introspection_dispatch_item_info_data_offset");
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_item_info_data_offset, eSymbolTypeData,
+ sc_list) > 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ item_info_data_offset_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+
+ if (queue_info_version_address != LLDB_INVALID_ADDRESS &&
+ queue_info_data_offset_address != LLDB_INVALID_ADDRESS &&
+ item_info_version_address != LLDB_INVALID_ADDRESS &&
+ item_info_data_offset_address != LLDB_INVALID_ADDRESS) {
+ Error error;
+ m_lib_backtrace_recording_info.queue_info_version =
+ m_process->ReadUnsignedIntegerFromMemory(queue_info_version_address, 2,
+ 0, error);
+ if (error.Success()) {
+ m_lib_backtrace_recording_info.queue_info_data_offset =
+ m_process->ReadUnsignedIntegerFromMemory(
+ queue_info_data_offset_address, 2, 0, error);
+ if (error.Success()) {
+ m_lib_backtrace_recording_info.item_info_version =
+ m_process->ReadUnsignedIntegerFromMemory(item_info_version_address,
+ 2, 0, error);
+ if (error.Success()) {
+ m_lib_backtrace_recording_info.item_info_data_offset =
+ m_process->ReadUnsignedIntegerFromMemory(
+ item_info_data_offset_address, 2, 0, error);
+ if (!error.Success()) {
+ m_lib_backtrace_recording_info.queue_info_version = 0;
+ }
+ } else {
+ m_lib_backtrace_recording_info.queue_info_version = 0;
}
+ } else {
+ m_lib_backtrace_recording_info.queue_info_version = 0;
+ }
}
+ }
- return m_lib_backtrace_recording_info.queue_info_version != 0;
+ return m_lib_backtrace_recording_info.queue_info_version != 0;
}
const std::vector<ConstString> &
-SystemRuntimeMacOSX::GetExtendedBacktraceTypes ()
-{
- if (m_types.size () == 0)
- {
- m_types.push_back(ConstString("libdispatch"));
- // We could have pthread as another type in the future if we have a way of
- // gathering that information & it's useful to distinguish between them.
- }
- return m_types;
+SystemRuntimeMacOSX::GetExtendedBacktraceTypes() {
+ if (m_types.size() == 0) {
+ m_types.push_back(ConstString("libdispatch"));
+ // We could have pthread as another type in the future if we have a way of
+ // gathering that information & it's useful to distinguish between them.
+ }
+ return m_types;
}
-void
-SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list)
-{
- if (BacktraceRecordingHeadersInitialized())
- {
- AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- if (cur_thread_sp)
- {
- Error error;
- queue_info_pointer = m_get_queues_handler.GetCurrentQueues (*cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (error.Success())
- {
-
- if (queue_info_pointer.count > 0
- && queue_info_pointer.queues_buffer_size > 0
- && queue_info_pointer.queues_buffer_ptr != 0
- && queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS)
- {
- PopulateQueuesUsingLibBTR (queue_info_pointer.queues_buffer_ptr, queue_info_pointer.queues_buffer_size, queue_info_pointer.count, queue_list);
- }
- }
+void SystemRuntimeMacOSX::PopulateQueueList(
+ lldb_private::QueueList &queue_list) {
+ if (BacktraceRecordingHeadersInitialized()) {
+ AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ if (cur_thread_sp) {
+ Error error;
+ queue_info_pointer = m_get_queues_handler.GetCurrentQueues(
+ *cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (error.Success()) {
+
+ if (queue_info_pointer.count > 0 &&
+ queue_info_pointer.queues_buffer_size > 0 &&
+ queue_info_pointer.queues_buffer_ptr != 0 &&
+ queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS) {
+ PopulateQueuesUsingLibBTR(queue_info_pointer.queues_buffer_ptr,
+ queue_info_pointer.queues_buffer_size,
+ queue_info_pointer.count, queue_list);
}
+ }
}
-
- // We either didn't have libBacktraceRecording (and need to create the queues list based on threads)
- // or we did get the queues list from libBacktraceRecording but some special queues may not be
- // included in its information. This is needed because libBacktraceRecording
- // will only list queues with pending or running items by default - but the magic com.apple.main-thread
- // queue on thread 1 is always around.
-
- for (ThreadSP thread_sp : m_process->Threads())
- {
- if (thread_sp->GetAssociatedWithLibdispatchQueue () != eLazyBoolNo)
- {
- if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID)
- {
- if (queue_list.FindQueueByID (thread_sp->GetQueueID()).get() == NULL)
- {
- QueueSP queue_sp (new Queue(m_process->shared_from_this(), thread_sp->GetQueueID(), thread_sp->GetQueueName()));
- if (thread_sp->ThreadHasQueueInformation ())
- {
- queue_sp->SetKind (thread_sp->GetQueueKind ());
- queue_sp->SetLibdispatchQueueAddress (thread_sp->GetQueueLibdispatchQueueAddress());
- queue_list.AddQueue (queue_sp);
- }
- else
- {
- queue_sp->SetKind (GetQueueKind (thread_sp->GetQueueLibdispatchQueueAddress()));
- queue_sp->SetLibdispatchQueueAddress (thread_sp->GetQueueLibdispatchQueueAddress());
- queue_list.AddQueue (queue_sp);
- }
- }
- }
+ }
+
+ // We either didn't have libBacktraceRecording (and need to create the queues
+ // list based on threads)
+ // or we did get the queues list from libBacktraceRecording but some special
+ // queues may not be
+ // included in its information. This is needed because libBacktraceRecording
+ // will only list queues with pending or running items by default - but the
+ // magic com.apple.main-thread
+ // queue on thread 1 is always around.
+
+ for (ThreadSP thread_sp : m_process->Threads()) {
+ if (thread_sp->GetAssociatedWithLibdispatchQueue() != eLazyBoolNo) {
+ if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) {
+ if (queue_list.FindQueueByID(thread_sp->GetQueueID()).get() == NULL) {
+ QueueSP queue_sp(new Queue(m_process->shared_from_this(),
+ thread_sp->GetQueueID(),
+ thread_sp->GetQueueName()));
+ if (thread_sp->ThreadHasQueueInformation()) {
+ queue_sp->SetKind(thread_sp->GetQueueKind());
+ queue_sp->SetLibdispatchQueueAddress(
+ thread_sp->GetQueueLibdispatchQueueAddress());
+ queue_list.AddQueue(queue_sp);
+ } else {
+ queue_sp->SetKind(
+ GetQueueKind(thread_sp->GetQueueLibdispatchQueueAddress()));
+ queue_sp->SetLibdispatchQueueAddress(
+ thread_sp->GetQueueLibdispatchQueueAddress());
+ queue_list.AddQueue(queue_sp);
+ }
}
+ }
}
+ }
}
-// Returns either an array of introspection_dispatch_item_info_ref's for the pending items on
-// a queue or an array introspection_dispatch_item_info_ref's and code addresses for the
-// pending items on a queue. The information about each of these pending items then needs to
+// Returns either an array of introspection_dispatch_item_info_ref's for the
+// pending items on
+// a queue or an array introspection_dispatch_item_info_ref's and code addresses
+// for the
+// pending items on a queue. The information about each of these pending items
+// then needs to
// be fetched individually by passing the ref to libBacktraceRecording.
SystemRuntimeMacOSX::PendingItemsForQueue
-SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue)
-{
- PendingItemsForQueue pending_item_refs;
- AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- if (cur_thread_sp)
- {
- Error error;
- pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (error.Success())
- {
- if (pending_items_pointer.count > 0
- && pending_items_pointer.items_buffer_size > 0
- && pending_items_pointer.items_buffer_ptr != 0
- && pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS)
- {
- DataBufferHeap data (pending_items_pointer.items_buffer_size, 0);
- if (m_process->ReadMemory (pending_items_pointer.items_buffer_ptr, data.GetBytes(), pending_items_pointer.items_buffer_size, error))
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
-
- // We either have an array of
- // void* item_ref
- // (old style) or we have a structure returned which looks like
- //
- // struct introspection_dispatch_pending_item_info_s {
- // void *item_ref;
- // void *function_or_block;
- // };
- //
- // struct introspection_dispatch_pending_items_array_s {
- // uint32_t version;
- // uint32_t size_of_item_info;
- // introspection_dispatch_pending_item_info_s items[];
- // }
-
- offset_t offset = 0;
- int i = 0;
- uint32_t version = extractor.GetU32(&offset);
- if (version == 1)
- {
- pending_item_refs.new_style = true;
- uint32_t item_size = extractor.GetU32(&offset);
- uint32_t start_of_array_offset = offset;
- while (offset < pending_items_pointer.items_buffer_size &&
- static_cast<size_t>(i) < pending_items_pointer.count)
- {
- offset = start_of_array_offset + (i * item_size);
- ItemRefAndCodeAddress item;
- item.item_ref = extractor.GetPointer (&offset);
- item.code_address = extractor.GetPointer (&offset);
- pending_item_refs.item_refs_and_code_addresses.push_back (item);
- i++;
- }
- }
- else
- {
- offset = 0;
- pending_item_refs.new_style = false;
- while (offset < pending_items_pointer.items_buffer_size &&
- static_cast<size_t>(i) < pending_items_pointer.count)
- {
- ItemRefAndCodeAddress item;
- item.item_ref = extractor.GetPointer (&offset);
- item.code_address = LLDB_INVALID_ADDRESS;
- pending_item_refs.item_refs_and_code_addresses.push_back (item);
- i++;
- }
- }
- }
- m_page_to_free = pending_items_pointer.items_buffer_ptr;
- m_page_to_free_size = pending_items_pointer.items_buffer_size;
+SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) {
+ PendingItemsForQueue pending_item_refs;
+ AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ if (cur_thread_sp) {
+ Error error;
+ pending_items_pointer = m_get_pending_items_handler.GetPendingItems(
+ *cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size,
+ error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (error.Success()) {
+ if (pending_items_pointer.count > 0 &&
+ pending_items_pointer.items_buffer_size > 0 &&
+ pending_items_pointer.items_buffer_ptr != 0 &&
+ pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) {
+ DataBufferHeap data(pending_items_pointer.items_buffer_size, 0);
+ if (m_process->ReadMemory(
+ pending_items_pointer.items_buffer_ptr, data.GetBytes(),
+ pending_items_pointer.items_buffer_size, error)) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+
+ // We either have an array of
+ // void* item_ref
+ // (old style) or we have a structure returned which looks like
+ //
+ // struct introspection_dispatch_pending_item_info_s {
+ // void *item_ref;
+ // void *function_or_block;
+ // };
+ //
+ // struct introspection_dispatch_pending_items_array_s {
+ // uint32_t version;
+ // uint32_t size_of_item_info;
+ // introspection_dispatch_pending_item_info_s items[];
+ // }
+
+ offset_t offset = 0;
+ int i = 0;
+ uint32_t version = extractor.GetU32(&offset);
+ if (version == 1) {
+ pending_item_refs.new_style = true;
+ uint32_t item_size = extractor.GetU32(&offset);
+ uint32_t start_of_array_offset = offset;
+ while (offset < pending_items_pointer.items_buffer_size &&
+ static_cast<size_t>(i) < pending_items_pointer.count) {
+ offset = start_of_array_offset + (i * item_size);
+ ItemRefAndCodeAddress item;
+ item.item_ref = extractor.GetPointer(&offset);
+ item.code_address = extractor.GetPointer(&offset);
+ pending_item_refs.item_refs_and_code_addresses.push_back(item);
+ i++;
+ }
+ } else {
+ offset = 0;
+ pending_item_refs.new_style = false;
+ while (offset < pending_items_pointer.items_buffer_size &&
+ static_cast<size_t>(i) < pending_items_pointer.count) {
+ ItemRefAndCodeAddress item;
+ item.item_ref = extractor.GetPointer(&offset);
+ item.code_address = LLDB_INVALID_ADDRESS;
+ pending_item_refs.item_refs_and_code_addresses.push_back(item);
+ i++;
}
+ }
}
+ m_page_to_free = pending_items_pointer.items_buffer_ptr;
+ m_page_to_free_size = pending_items_pointer.items_buffer_size;
+ }
}
- return pending_item_refs;
+ }
+ return pending_item_refs;
}
-
-
-void
-SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
-{
- if (BacktraceRecordingHeadersInitialized())
- {
- PendingItemsForQueue pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
- for (ItemRefAndCodeAddress pending_item : pending_item_refs.item_refs_and_code_addresses)
- {
- Address addr;
- m_process->GetTarget().ResolveLoadAddress (pending_item.code_address, addr);
- QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this(), m_process->shared_from_this(), pending_item.item_ref, addr));
- queue->PushPendingQueueItem (queue_item_sp);
- }
+void SystemRuntimeMacOSX::PopulatePendingItemsForQueue(Queue *queue) {
+ if (BacktraceRecordingHeadersInitialized()) {
+ PendingItemsForQueue pending_item_refs =
+ GetPendingItemRefsForQueue(queue->GetLibdispatchQueueAddress());
+ for (ItemRefAndCodeAddress pending_item :
+ pending_item_refs.item_refs_and_code_addresses) {
+ Address addr;
+ m_process->GetTarget().ResolveLoadAddress(pending_item.code_address,
+ addr);
+ QueueItemSP queue_item_sp(new QueueItem(queue->shared_from_this(),
+ m_process->shared_from_this(),
+ pending_item.item_ref, addr));
+ queue->PushPendingQueueItem(queue_item_sp);
}
+ }
}
-void
-SystemRuntimeMacOSX::CompleteQueueItem (QueueItem *queue_item, addr_t item_ref)
-{
- AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
-
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- Error error;
- ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
- {
- DataBufferHeap data (ret.item_buffer_size, 0);
- if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer (extractor);
- queue_item->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
- queue_item->SetEnqueueingThreadID (item.enqueuing_thread_id);
- queue_item->SetEnqueueingQueueID (item.enqueuing_queue_serialnum);
- queue_item->SetStopID (item.stop_id);
- queue_item->SetEnqueueingBacktrace (item.enqueuing_callstack);
- queue_item->SetThreadLabel (item.enqueuing_thread_label);
- queue_item->SetQueueLabel (item.enqueuing_queue_label);
- queue_item->SetTargetQueueLabel (item.target_queue_label);
- }
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
+void SystemRuntimeMacOSX::CompleteQueueItem(QueueItem *queue_item,
+ addr_t item_ref) {
+ AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
+
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ Error error;
+ ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
+ m_page_to_free, m_page_to_free_size,
+ error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
+ ret.item_buffer_size > 0) {
+ DataBufferHeap data(ret.item_buffer_size, 0);
+ if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
+ ret.item_buffer_size, error) &&
+ error.Success()) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ ItemInfo item = ExtractItemInfoFromBuffer(extractor);
+ queue_item->SetItemThatEnqueuedThis(item.item_that_enqueued_this);
+ queue_item->SetEnqueueingThreadID(item.enqueuing_thread_id);
+ queue_item->SetEnqueueingQueueID(item.enqueuing_queue_serialnum);
+ queue_item->SetStopID(item.stop_id);
+ queue_item->SetEnqueueingBacktrace(item.enqueuing_callstack);
+ queue_item->SetThreadLabel(item.enqueuing_thread_label);
+ queue_item->SetQueueLabel(item.enqueuing_queue_label);
+ queue_item->SetTargetQueueLabel(item.target_queue_label);
}
+ m_page_to_free = ret.item_buffer_ptr;
+ m_page_to_free_size = ret.item_buffer_size;
+ }
}
-void
-SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size,
- uint64_t count, lldb_private::QueueList &queue_list)
-{
- Error error;
- DataBufferHeap data (queues_buffer_size, 0);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
- if (m_process->ReadMemory (queues_buffer, data.GetBytes(), queues_buffer_size, error) == queues_buffer_size && error.Success())
- {
- // We've read the information out of inferior memory; free it on the next call we make
- m_page_to_free = queues_buffer;
- m_page_to_free_size = queues_buffer_size;
-
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- offset_t offset = 0;
- uint64_t queues_read = 0;
-
- // The information about the queues is stored in this format (v1):
- // typedef struct introspection_dispatch_queue_info_s {
- // uint32_t offset_to_next;
- // dispatch_queue_t queue;
- // uint64_t serialnum; // queue's serialnum in the process, as provided by libdispatch
- // uint32_t running_work_items_count;
- // uint32_t pending_work_items_count;
- //
- // char data[]; // Starting here, we have variable-length data:
- // // char queue_label[];
- // } introspection_dispatch_queue_info_s;
-
- while (queues_read < count && offset < queues_buffer_size)
- {
- offset_t start_of_this_item = offset;
-
- uint32_t offset_to_next = extractor.GetU32 (&offset);
-
- offset += 4; // Skip over the 4 bytes of reserved space
- addr_t queue = extractor.GetPointer (&offset);
- uint64_t serialnum = extractor.GetU64 (&offset);
- uint32_t running_work_items_count = extractor.GetU32 (&offset);
- uint32_t pending_work_items_count = extractor.GetU32 (&offset);
-
- // Read the first field of the variable length data
- offset = start_of_this_item + m_lib_backtrace_recording_info.queue_info_data_offset;
- const char *queue_label = extractor.GetCStr (&offset);
- if (queue_label == NULL)
- queue_label = "";
-
- offset_t start_of_next_item = start_of_this_item + offset_to_next;
- offset = start_of_next_item;
-
- if (log)
- log->Printf ("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added queue with dispatch_queue_t 0x%" PRIx64 ", serial number 0x%" PRIx64 ", running items %d, pending items %d, name '%s'", queue, serialnum, running_work_items_count, pending_work_items_count, queue_label);
-
- QueueSP queue_sp (new Queue (m_process->shared_from_this(), serialnum, queue_label));
- queue_sp->SetNumRunningWorkItems (running_work_items_count);
- queue_sp->SetNumPendingWorkItems (pending_work_items_count);
- queue_sp->SetLibdispatchQueueAddress (queue);
- queue_sp->SetKind (GetQueueKind (queue));
- queue_list.AddQueue (queue_sp);
- queues_read++;
- }
+void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR(
+ lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count,
+ lldb_private::QueueList &queue_list) {
+ Error error;
+ DataBufferHeap data(queues_buffer_size, 0);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ if (m_process->ReadMemory(queues_buffer, data.GetBytes(), queues_buffer_size,
+ error) == queues_buffer_size &&
+ error.Success()) {
+ // We've read the information out of inferior memory; free it on the next
+ // call we make
+ m_page_to_free = queues_buffer;
+ m_page_to_free_size = queues_buffer_size;
+
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ offset_t offset = 0;
+ uint64_t queues_read = 0;
+
+ // The information about the queues is stored in this format (v1):
+ // typedef struct introspection_dispatch_queue_info_s {
+ // uint32_t offset_to_next;
+ // dispatch_queue_t queue;
+ // uint64_t serialnum; // queue's serialnum in the process, as
+ // provided by libdispatch
+ // uint32_t running_work_items_count;
+ // uint32_t pending_work_items_count;
+ //
+ // char data[]; // Starting here, we have variable-length data:
+ // // char queue_label[];
+ // } introspection_dispatch_queue_info_s;
+
+ while (queues_read < count && offset < queues_buffer_size) {
+ offset_t start_of_this_item = offset;
+
+ uint32_t offset_to_next = extractor.GetU32(&offset);
+
+ offset += 4; // Skip over the 4 bytes of reserved space
+ addr_t queue = extractor.GetPointer(&offset);
+ uint64_t serialnum = extractor.GetU64(&offset);
+ uint32_t running_work_items_count = extractor.GetU32(&offset);
+ uint32_t pending_work_items_count = extractor.GetU32(&offset);
+
+ // Read the first field of the variable length data
+ offset = start_of_this_item +
+ m_lib_backtrace_recording_info.queue_info_data_offset;
+ const char *queue_label = extractor.GetCStr(&offset);
+ if (queue_label == NULL)
+ queue_label = "";
+
+ offset_t start_of_next_item = start_of_this_item + offset_to_next;
+ offset = start_of_next_item;
+
+ if (log)
+ log->Printf("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added "
+ "queue with dispatch_queue_t 0x%" PRIx64
+ ", serial number 0x%" PRIx64
+ ", running items %d, pending items %d, name '%s'",
+ queue, serialnum, running_work_items_count,
+ pending_work_items_count, queue_label);
+
+ QueueSP queue_sp(
+ new Queue(m_process->shared_from_this(), serialnum, queue_label));
+ queue_sp->SetNumRunningWorkItems(running_work_items_count);
+ queue_sp->SetNumPendingWorkItems(pending_work_items_count);
+ queue_sp->SetLibdispatchQueueAddress(queue);
+ queue_sp->SetKind(GetQueueKind(queue));
+ queue_list.AddQueue(queue_sp);
+ queues_read++;
}
+ }
}
-SystemRuntimeMacOSX::ItemInfo
-SystemRuntimeMacOSX::ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor)
-{
- ItemInfo item;
+SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer(
+ lldb_private::DataExtractor &extractor) {
+ ItemInfo item;
- offset_t offset = 0;
-
- item.item_that_enqueued_this = extractor.GetPointer (&offset);
- item.function_or_block = extractor.GetPointer (&offset);
- item.enqueuing_thread_id = extractor.GetU64 (&offset);
- item.enqueuing_queue_serialnum = extractor.GetU64 (&offset);
- item.target_queue_serialnum = extractor.GetU64 (&offset);
- item.enqueuing_callstack_frame_count = extractor.GetU32 (&offset);
- item.stop_id = extractor.GetU32 (&offset);
-
- offset = m_lib_backtrace_recording_info.item_info_data_offset;
-
- for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++)
- {
- item.enqueuing_callstack.push_back (extractor.GetPointer (&offset));
- }
- item.enqueuing_thread_label = extractor.GetCStr (&offset);
- item.enqueuing_queue_label = extractor.GetCStr (&offset);
- item.target_queue_label = extractor.GetCStr (&offset);
+ offset_t offset = 0;
- return item;
-}
+ item.item_that_enqueued_this = extractor.GetPointer(&offset);
+ item.function_or_block = extractor.GetPointer(&offset);
+ item.enqueuing_thread_id = extractor.GetU64(&offset);
+ item.enqueuing_queue_serialnum = extractor.GetU64(&offset);
+ item.target_queue_serialnum = extractor.GetU64(&offset);
+ item.enqueuing_callstack_frame_count = extractor.GetU32(&offset);
+ item.stop_id = extractor.GetU32(&offset);
-void
-SystemRuntimeMacOSX::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
+ offset = m_lib_backtrace_recording_info.item_info_data_offset;
-void
-SystemRuntimeMacOSX::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+ for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) {
+ item.enqueuing_callstack.push_back(extractor.GetPointer(&offset));
+ }
+ item.enqueuing_thread_label = extractor.GetCStr(&offset);
+ item.enqueuing_queue_label = extractor.GetCStr(&offset);
+ item.target_queue_label = extractor.GetCStr(&offset);
+
+ return item;
}
+void SystemRuntimeMacOSX::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
-lldb_private::ConstString
-SystemRuntimeMacOSX::GetPluginNameStatic()
-{
- static ConstString g_name("systemruntime-macosx");
- return g_name;
+void SystemRuntimeMacOSX::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-const char *
-SystemRuntimeMacOSX::GetPluginDescriptionStatic()
-{
- return "System runtime plugin for Mac OS X native libraries.";
+lldb_private::ConstString SystemRuntimeMacOSX::GetPluginNameStatic() {
+ static ConstString g_name("systemruntime-macosx");
+ return g_name;
}
+const char *SystemRuntimeMacOSX::GetPluginDescriptionStatic() {
+ return "System runtime plugin for Mac OS X native libraries.";
+}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-SystemRuntimeMacOSX::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString SystemRuntimeMacOSX::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-SystemRuntimeMacOSX::GetPluginVersion()
-{
- return 1;
-}
+uint32_t SystemRuntimeMacOSX::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
index b685a056f5c2..2b98c084161d 100644
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
+++ b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
@@ -18,7 +18,6 @@
// Other libraries and framework include
// Project includes
-#include "lldb/Target/SystemRuntime.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/StructuredData.h"
@@ -26,311 +25,278 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/QueueItem.h"
+#include "lldb/Target/SystemRuntime.h"
#include "AppleGetItemInfoHandler.h"
-#include "AppleGetQueuesHandler.h"
#include "AppleGetPendingItemsHandler.h"
+#include "AppleGetQueuesHandler.h"
#include "AppleGetThreadItemInfoHandler.h"
-class SystemRuntimeMacOSX : public lldb_private::SystemRuntime
-{
+class SystemRuntimeMacOSX : public lldb_private::SystemRuntime {
public:
- SystemRuntimeMacOSX(lldb_private::Process *process);
+ SystemRuntimeMacOSX(lldb_private::Process *process);
- ~SystemRuntimeMacOSX() override;
+ ~SystemRuntimeMacOSX() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SystemRuntime *
- CreateInstance (lldb_private::Process *process);
+ static lldb_private::SystemRuntime *
+ CreateInstance(lldb_private::Process *process);
- //------------------------------------------------------------------
- // instance methods
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // instance methods
+ //------------------------------------------------------------------
- void
- Clear(bool clear_process);
+ void Clear(bool clear_process);
- void
- Detach() override;
+ void Detach() override;
- const std::vector<lldb_private::ConstString> &
- GetExtendedBacktraceTypes() override;
+ const std::vector<lldb_private::ConstString> &
+ GetExtendedBacktraceTypes() override;
- lldb::ThreadSP
- GetExtendedBacktraceThread(lldb::ThreadSP thread, lldb_private::ConstString type) override;
+ lldb::ThreadSP
+ GetExtendedBacktraceThread(lldb::ThreadSP thread,
+ lldb_private::ConstString type) override;
- lldb::ThreadSP
- GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
- lldb_private::ConstString type) override;
+ lldb::ThreadSP
+ GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
+ lldb_private::ConstString type) override;
- lldb::ThreadSP
- GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref);
+ lldb::ThreadSP GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref);
- void
- PopulateQueueList(lldb_private::QueueList &queue_list) override;
+ void PopulateQueueList(lldb_private::QueueList &queue_list) override;
- void
- PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count, lldb_private::QueueList &queue_list);
+ void PopulateQueuesUsingLibBTR(lldb::addr_t queues_buffer,
+ uint64_t queues_buffer_size, uint64_t count,
+ lldb_private::QueueList &queue_list);
- void
- PopulatePendingQueuesUsingLibBTR (lldb::addr_t items_buffer, uint64_t items_buffer_size, uint64_t count, lldb_private::Queue *queue);
+ void PopulatePendingQueuesUsingLibBTR(lldb::addr_t items_buffer,
+ uint64_t items_buffer_size,
+ uint64_t count,
+ lldb_private::Queue *queue);
- std::string
- GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
+ std::string
+ GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
- lldb::queue_id_t
- GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
+ lldb::queue_id_t
+ GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
- lldb::addr_t
- GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
+ lldb::addr_t GetLibdispatchQueueAddressFromThreadQAddress(
+ lldb::addr_t dispatch_qaddr) override;
- void
- PopulatePendingItemsForQueue(lldb_private::Queue *queue) override;
+ void PopulatePendingItemsForQueue(lldb_private::Queue *queue) override;
- void
- CompleteQueueItem(lldb_private::QueueItem *queue_item, lldb::addr_t item_ref) override;
+ void CompleteQueueItem(lldb_private::QueueItem *queue_item,
+ lldb::addr_t item_ref) override;
- lldb::QueueKind
- GetQueueKind (lldb::addr_t dispatch_queue_addr) override;
+ lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_queue_addr) override;
- void
- AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict) override;
+ void AddThreadExtendedInfoPacketHints(
+ lldb_private::StructuredData::ObjectSP dict) override;
- bool
- SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) override;
+ bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
+ lldb::user_id_t m_break_id;
+ mutable std::recursive_mutex m_mutex;
private:
- struct libBacktraceRecording_info {
- uint16_t queue_info_version;
- uint16_t queue_info_data_offset;
- uint16_t item_info_version;
- uint16_t item_info_data_offset;
-
- libBacktraceRecording_info () :
- queue_info_version(0),
- queue_info_data_offset(0),
- item_info_version(0),
- item_info_data_offset(0) {}
- };
-
- // A structure which reflects the data recorded in the
- // libBacktraceRecording introspection_dispatch_item_info_s.
- struct ItemInfo {
- lldb::addr_t item_that_enqueued_this;
- lldb::addr_t function_or_block;
- uint64_t enqueuing_thread_id;
- uint64_t enqueuing_queue_serialnum;
- uint64_t target_queue_serialnum;
- uint32_t enqueuing_callstack_frame_count;
- uint32_t stop_id;
- std::vector<lldb::addr_t> enqueuing_callstack;
- std::string enqueuing_thread_label;
- std::string enqueuing_queue_label;
- std::string target_queue_label;
- };
-
- // The offsets of different fields of the dispatch_queue_t structure in
- // a thread/queue process.
- // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
- // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot be cached.
- // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value that can be cached.
- struct LibdispatchOffsets
- {
- uint16_t dqo_version;
- uint16_t dqo_label;
- uint16_t dqo_label_size;
- uint16_t dqo_flags;
- uint16_t dqo_flags_size;
- uint16_t dqo_serialnum;
- uint16_t dqo_serialnum_size;
- uint16_t dqo_width;
- uint16_t dqo_width_size;
- uint16_t dqo_running;
- uint16_t dqo_running_size;
-
- uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X 10.10/iOS 8
-
- LibdispatchOffsets ()
- {
- dqo_version = UINT16_MAX;
- dqo_flags = UINT16_MAX;
- dqo_serialnum = UINT16_MAX;
- dqo_label = UINT16_MAX;
- dqo_width = UINT16_MAX;
- dqo_running = UINT16_MAX;
- dqo_suspend_cnt = UINT16_MAX;
- dqo_target_queue = UINT16_MAX;
- dqo_target_queue = UINT16_MAX;
- dqo_priority = UINT16_MAX;
- }
-
- bool
- IsValid ()
- {
- return dqo_version != UINT16_MAX;
- }
-
- bool
- LabelIsValid ()
- {
- return dqo_label != UINT16_MAX;
- }
- };
-
- struct LibdispatchVoucherOffsets
- {
- uint16_t vo_version;
- uint16_t vo_activity_ids_count;
- uint16_t vo_activity_ids_count_size;
- uint16_t vo_activity_ids_array;
- uint16_t vo_activity_ids_array_entry_size;
-
- LibdispatchVoucherOffsets () :
- vo_version (UINT16_MAX),
- vo_activity_ids_count (UINT16_MAX),
- vo_activity_ids_count_size (UINT16_MAX),
- vo_activity_ids_array (UINT16_MAX),
- vo_activity_ids_array_entry_size (UINT16_MAX)
- { }
-
- bool IsValid () { return vo_version != UINT16_MAX; }
- };
-
- struct LibdispatchTSDIndexes
- {
- uint16_t dti_version;
- uint64_t dti_queue_index;
- uint64_t dti_voucher_index;
- uint64_t dti_qos_class_index;
-
- LibdispatchTSDIndexes () :
- dti_version (UINT16_MAX),
- dti_queue_index (UINT64_MAX),
- dti_voucher_index (UINT64_MAX),
- dti_qos_class_index (UINT64_MAX)
- { }
-
- bool IsValid () { return dti_version != UINT16_MAX; }
- };
-
- struct LibpthreadOffsets
- {
- uint16_t plo_version;
- uint16_t plo_pthread_tsd_base_offset;
- uint16_t plo_pthread_tsd_base_address_offset;
- uint16_t plo_pthread_tsd_entry_size;
-
- LibpthreadOffsets () :
- plo_version (UINT16_MAX),
- plo_pthread_tsd_base_offset (UINT16_MAX),
- plo_pthread_tsd_base_address_offset (UINT16_MAX),
- plo_pthread_tsd_entry_size (UINT16_MAX)
- {
- }
-
- bool IsValid ()
- {
- return plo_version != UINT16_MAX;
- }
- };
-
- // The libBacktraceRecording function __introspection_dispatch_queue_get_pending_items has
- // two forms. It can either return a simple array of item_refs (void *) size or it can return
- // a header with uint32_t version, a uint32_t size of item, and then an array of item_refs (void*)
- // and code addresses (void*) for all the pending blocks.
-
- struct ItemRefAndCodeAddress {
- lldb::addr_t item_ref;
- lldb::addr_t code_address;
- };
-
- struct PendingItemsForQueue {
- bool new_style; // new-style means both item_refs and code_addresses avail
- // old-style means only item_refs is filled in
- std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses;
- };
-
- bool
- BacktraceRecordingHeadersInitialized ();
-
- void
- ReadLibdispatchOffsetsAddress();
-
- void
- ReadLibdispatchOffsets ();
-
- void
- ReadLibpthreadOffsetsAddress();
-
- void
- ReadLibpthreadOffsets ();
-
- void
- ReadLibdispatchTSDIndexesAddress ();
-
- void
- ReadLibdispatchTSDIndexes ();
-
- PendingItemsForQueue
- GetPendingItemRefsForQueue (lldb::addr_t queue);
-
- ItemInfo
- ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor);
-
- lldb_private::AppleGetQueuesHandler m_get_queues_handler;
- lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler;
- lldb_private::AppleGetItemInfoHandler m_get_item_info_handler;
- lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler;
-
- lldb::addr_t m_page_to_free;
- uint64_t m_page_to_free_size;
- libBacktraceRecording_info m_lib_backtrace_recording_info;
-
- lldb::addr_t m_dispatch_queue_offsets_addr;
- struct LibdispatchOffsets m_libdispatch_offsets;
-
- lldb::addr_t m_libpthread_layout_offsets_addr;
- struct LibpthreadOffsets m_libpthread_offsets;
-
- lldb::addr_t m_dispatch_tsd_indexes_addr;
- struct LibdispatchTSDIndexes m_libdispatch_tsd_indexes;
-
- lldb::addr_t m_dispatch_voucher_offsets_addr;
- struct LibdispatchVoucherOffsets m_libdispatch_voucher_offsets;
-
- DISALLOW_COPY_AND_ASSIGN (SystemRuntimeMacOSX);
+ struct libBacktraceRecording_info {
+ uint16_t queue_info_version;
+ uint16_t queue_info_data_offset;
+ uint16_t item_info_version;
+ uint16_t item_info_data_offset;
+
+ libBacktraceRecording_info()
+ : queue_info_version(0), queue_info_data_offset(0),
+ item_info_version(0), item_info_data_offset(0) {}
+ };
+
+ // A structure which reflects the data recorded in the
+ // libBacktraceRecording introspection_dispatch_item_info_s.
+ struct ItemInfo {
+ lldb::addr_t item_that_enqueued_this;
+ lldb::addr_t function_or_block;
+ uint64_t enqueuing_thread_id;
+ uint64_t enqueuing_queue_serialnum;
+ uint64_t target_queue_serialnum;
+ uint32_t enqueuing_callstack_frame_count;
+ uint32_t stop_id;
+ std::vector<lldb::addr_t> enqueuing_callstack;
+ std::string enqueuing_thread_label;
+ std::string enqueuing_queue_label;
+ std::string target_queue_label;
+ };
+
+ // The offsets of different fields of the dispatch_queue_t structure in
+ // a thread/queue process.
+ // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
+ // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot
+ // be cached.
+ // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value
+ // that can be cached.
+ struct LibdispatchOffsets {
+ uint16_t dqo_version;
+ uint16_t dqo_label;
+ uint16_t dqo_label_size;
+ uint16_t dqo_flags;
+ uint16_t dqo_flags_size;
+ uint16_t dqo_serialnum;
+ uint16_t dqo_serialnum_size;
+ uint16_t dqo_width;
+ uint16_t dqo_width_size;
+ uint16_t dqo_running;
+ uint16_t dqo_running_size;
+
+ uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X
+ // 10.10/iOS 8
+ uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS
+ // X 10.10/iOS 8
+ uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X
+ // 10.10/iOS 8
+ uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS
+ // X 10.10/iOS 8
+ uint16_t
+ dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8
+ uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X
+ // 10.10/iOS 8
+
+ LibdispatchOffsets() {
+ dqo_version = UINT16_MAX;
+ dqo_flags = UINT16_MAX;
+ dqo_serialnum = UINT16_MAX;
+ dqo_label = UINT16_MAX;
+ dqo_width = UINT16_MAX;
+ dqo_running = UINT16_MAX;
+ dqo_suspend_cnt = UINT16_MAX;
+ dqo_target_queue = UINT16_MAX;
+ dqo_target_queue = UINT16_MAX;
+ dqo_priority = UINT16_MAX;
+ }
+
+ bool IsValid() { return dqo_version != UINT16_MAX; }
+
+ bool LabelIsValid() { return dqo_label != UINT16_MAX; }
+ };
+
+ struct LibdispatchVoucherOffsets {
+ uint16_t vo_version;
+ uint16_t vo_activity_ids_count;
+ uint16_t vo_activity_ids_count_size;
+ uint16_t vo_activity_ids_array;
+ uint16_t vo_activity_ids_array_entry_size;
+
+ LibdispatchVoucherOffsets()
+ : vo_version(UINT16_MAX), vo_activity_ids_count(UINT16_MAX),
+ vo_activity_ids_count_size(UINT16_MAX),
+ vo_activity_ids_array(UINT16_MAX),
+ vo_activity_ids_array_entry_size(UINT16_MAX) {}
+
+ bool IsValid() { return vo_version != UINT16_MAX; }
+ };
+
+ struct LibdispatchTSDIndexes {
+ uint16_t dti_version;
+ uint64_t dti_queue_index;
+ uint64_t dti_voucher_index;
+ uint64_t dti_qos_class_index;
+
+ LibdispatchTSDIndexes()
+ : dti_version(UINT16_MAX), dti_queue_index(UINT64_MAX),
+ dti_voucher_index(UINT64_MAX), dti_qos_class_index(UINT64_MAX) {}
+
+ bool IsValid() { return dti_version != UINT16_MAX; }
+ };
+
+ struct LibpthreadOffsets {
+ uint16_t plo_version;
+ uint16_t plo_pthread_tsd_base_offset;
+ uint16_t plo_pthread_tsd_base_address_offset;
+ uint16_t plo_pthread_tsd_entry_size;
+
+ LibpthreadOffsets()
+ : plo_version(UINT16_MAX), plo_pthread_tsd_base_offset(UINT16_MAX),
+ plo_pthread_tsd_base_address_offset(UINT16_MAX),
+ plo_pthread_tsd_entry_size(UINT16_MAX) {}
+
+ bool IsValid() { return plo_version != UINT16_MAX; }
+ };
+
+ // The libBacktraceRecording function
+ // __introspection_dispatch_queue_get_pending_items has
+ // two forms. It can either return a simple array of item_refs (void *) size
+ // or it can return
+ // a header with uint32_t version, a uint32_t size of item, and then an array
+ // of item_refs (void*)
+ // and code addresses (void*) for all the pending blocks.
+
+ struct ItemRefAndCodeAddress {
+ lldb::addr_t item_ref;
+ lldb::addr_t code_address;
+ };
+
+ struct PendingItemsForQueue {
+ bool new_style; // new-style means both item_refs and code_addresses avail
+ // old-style means only item_refs is filled in
+ std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses;
+ };
+
+ bool BacktraceRecordingHeadersInitialized();
+
+ void ReadLibdispatchOffsetsAddress();
+
+ void ReadLibdispatchOffsets();
+
+ void ReadLibpthreadOffsetsAddress();
+
+ void ReadLibpthreadOffsets();
+
+ void ReadLibdispatchTSDIndexesAddress();
+
+ void ReadLibdispatchTSDIndexes();
+
+ PendingItemsForQueue GetPendingItemRefsForQueue(lldb::addr_t queue);
+
+ ItemInfo ExtractItemInfoFromBuffer(lldb_private::DataExtractor &extractor);
+
+ lldb_private::AppleGetQueuesHandler m_get_queues_handler;
+ lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler;
+ lldb_private::AppleGetItemInfoHandler m_get_item_info_handler;
+ lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler;
+
+ lldb::addr_t m_page_to_free;
+ uint64_t m_page_to_free_size;
+ libBacktraceRecording_info m_lib_backtrace_recording_info;
+
+ lldb::addr_t m_dispatch_queue_offsets_addr;
+ struct LibdispatchOffsets m_libdispatch_offsets;
+
+ lldb::addr_t m_libpthread_layout_offsets_addr;
+ struct LibpthreadOffsets m_libpthread_offsets;
+
+ lldb::addr_t m_dispatch_tsd_indexes_addr;
+ struct LibdispatchTSDIndexes m_libdispatch_tsd_indexes;
+
+ lldb::addr_t m_dispatch_voucher_offsets_addr;
+ struct LibdispatchVoucherOffsets m_libdispatch_voucher_offsets;
+
+ DISALLOW_COPY_AND_ASSIGN(SystemRuntimeMacOSX);
};
#endif // liblldb_SystemRuntimeMacOSX_h_
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 72adf7576270..0852f1922034 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -1,4 +1,4 @@
-//===-- UnwindAssemblyInstEmulation.cpp --------------------------*- C++ -*-===//
+//===-- UnwindAssemblyInstEmulation.cpp --------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,658 +21,645 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-
-
//-----------------------------------------------------------------------------------------------
-// UnwindAssemblyInstEmulation method definitions
+// UnwindAssemblyInstEmulation method definitions
//-----------------------------------------------------------------------------------------------
-bool
-UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& range,
- Thread& thread,
- UnwindPlan& unwind_plan)
-{
- if (range.GetByteSize() > 0 &&
- range.GetBaseAddress().IsValid() &&
- m_inst_emulator_ap.get())
- {
-
- // The instruction emulation subclass setup the unwind plan for the
- // first instruction.
- m_inst_emulator_ap->CreateFunctionEntryUnwind (unwind_plan);
-
- // CreateFunctionEntryUnwind should have created the first row. If it
- // doesn't, then we are done.
- if (unwind_plan.GetRowCount() == 0)
- return false;
-
- ExecutionContext exe_ctx;
- thread.CalculateExecutionContext(exe_ctx);
- const bool prefer_file_cache = true;
- DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
- NULL,
- NULL,
- exe_ctx,
- range,
- prefer_file_cache));
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (disasm_sp)
- {
-
- m_range_ptr = &range;
- m_thread_ptr = &thread;
- m_unwind_plan_ptr = &unwind_plan;
-
- const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
- const bool show_address = true;
- const bool show_bytes = true;
- m_inst_emulator_ap->GetRegisterInfo (unwind_plan.GetRegisterKind(),
- unwind_plan.GetInitialCFARegister(),
- m_cfa_reg_info);
-
- m_fp_is_cfa = false;
- m_register_values.clear();
- m_pushed_regs.clear();
-
- // Initialize the CFA with a known value. In the 32 bit case
- // it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
- // We use the address byte size to be safe for any future address sizes
- m_initial_sp = (1ull << ((addr_byte_size * 8) - 1));
- RegisterValue cfa_reg_value;
- cfa_reg_value.SetUInt (m_initial_sp, m_cfa_reg_info.byte_size);
- SetRegisterValue (m_cfa_reg_info, cfa_reg_value);
-
- const InstructionList &inst_list = disasm_sp->GetInstructionList ();
- const size_t num_instructions = inst_list.GetSize();
-
- if (num_instructions > 0)
- {
- Instruction *inst = inst_list.GetInstructionAtIndex (0).get();
- const lldb::addr_t base_addr = inst->GetAddress().GetFileAddress();
-
- // Map for storing the unwind plan row and the value of the registers at a given offset.
- // When we see a forward branch we add a new entry to this map with the actual unwind plan
- // row and register context for the target address of the branch as the current data have
- // to be valid for the target address of the branch too if we are in the same function.
- std::map<lldb::addr_t, std::pair<UnwindPlan::RowSP, RegisterValueMap>> saved_unwind_states;
-
- // Make a copy of the current instruction Row and save it in m_curr_row
- // so we can add updates as we process the instructions.
- UnwindPlan::RowSP last_row = unwind_plan.GetLastRow();
+bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
+ AddressRange &range, Thread &thread, UnwindPlan &unwind_plan) {
+ std::vector<uint8_t> function_text(range.GetByteSize());
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ Error error;
+ const bool prefer_file_cache = true;
+ if (process_sp->GetTarget().ReadMemory(
+ range.GetBaseAddress(), prefer_file_cache, function_text.data(),
+ range.GetByteSize(), error) != range.GetByteSize()) {
+ return false;
+ }
+ }
+ return GetNonCallSiteUnwindPlanFromAssembly(
+ range, function_text.data(), function_text.size(), unwind_plan);
+}
+
+bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
+ AddressRange &range, uint8_t *opcode_data, size_t opcode_size,
+ UnwindPlan &unwind_plan) {
+ if (opcode_data == nullptr || opcode_size == 0)
+ return false;
+
+ if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid() &&
+ m_inst_emulator_ap.get()) {
+
+ // The instruction emulation subclass setup the unwind plan for the
+ // first instruction.
+ m_inst_emulator_ap->CreateFunctionEntryUnwind(unwind_plan);
+
+ // CreateFunctionEntryUnwind should have created the first row. If it
+ // doesn't, then we are done.
+ if (unwind_plan.GetRowCount() == 0)
+ return false;
+
+ const bool prefer_file_cache = true;
+ DisassemblerSP disasm_sp(Disassembler::DisassembleBytes(
+ m_arch, NULL, NULL, range.GetBaseAddress(), opcode_data, opcode_size,
+ 99999, prefer_file_cache));
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (disasm_sp) {
+
+ m_range_ptr = &range;
+ m_unwind_plan_ptr = &unwind_plan;
+
+ const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
+ const bool show_address = true;
+ const bool show_bytes = true;
+ m_inst_emulator_ap->GetRegisterInfo(unwind_plan.GetRegisterKind(),
+ unwind_plan.GetInitialCFARegister(),
+ m_cfa_reg_info);
+
+ m_fp_is_cfa = false;
+ m_register_values.clear();
+ m_pushed_regs.clear();
+
+ // Initialize the CFA with a known value. In the 32 bit case
+ // it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
+ // We use the address byte size to be safe for any future address sizes
+ m_initial_sp = (1ull << ((addr_byte_size * 8) - 1));
+ RegisterValue cfa_reg_value;
+ cfa_reg_value.SetUInt(m_initial_sp, m_cfa_reg_info.byte_size);
+ SetRegisterValue(m_cfa_reg_info, cfa_reg_value);
+
+ const InstructionList &inst_list = disasm_sp->GetInstructionList();
+ const size_t num_instructions = inst_list.GetSize();
+
+ if (num_instructions > 0) {
+ Instruction *inst = inst_list.GetInstructionAtIndex(0).get();
+ const lldb::addr_t base_addr = inst->GetAddress().GetFileAddress();
+
+ // Map for storing the unwind plan row and the value of the registers at
+ // a given offset.
+ // When we see a forward branch we add a new entry to this map with the
+ // actual unwind plan
+ // row and register context for the target address of the branch as the
+ // current data have
+ // to be valid for the target address of the branch too if we are in the
+ // same function.
+ std::map<lldb::addr_t, std::pair<UnwindPlan::RowSP, RegisterValueMap>>
+ saved_unwind_states;
+
+ // Make a copy of the current instruction Row and save it in m_curr_row
+ // so we can add updates as we process the instructions.
+ UnwindPlan::RowSP last_row = unwind_plan.GetLastRow();
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ if (last_row.get())
+ *newrow = *last_row.get();
+ m_curr_row.reset(newrow);
+
+ // Add the initial state to the save list with offset 0.
+ saved_unwind_states.insert({0, {last_row, m_register_values}});
+
+ // cache the pc register number (in whatever register numbering this
+ // UnwindPlan uses) for
+ // quick reference during instruction parsing.
+ RegisterInfo pc_reg_info;
+ m_inst_emulator_ap->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info);
+
+ // cache the return address register number (in whatever register
+ // numbering this UnwindPlan uses) for
+ // quick reference during instruction parsing.
+ RegisterInfo ra_reg_info;
+ m_inst_emulator_ap->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
+
+ // The architecture dependent condition code of the last processed
+ // instruction.
+ EmulateInstruction::InstructionCondition last_condition =
+ EmulateInstruction::UnconditionalCondition;
+ lldb::addr_t condition_block_start_offset = 0;
+
+ for (size_t idx = 0; idx < num_instructions; ++idx) {
+ m_curr_row_modified = false;
+ m_forward_branch_offset = 0;
+
+ inst = inst_list.GetInstructionAtIndex(idx).get();
+ if (inst) {
+ lldb::addr_t current_offset =
+ inst->GetAddress().GetFileAddress() - base_addr;
+ auto it = saved_unwind_states.upper_bound(current_offset);
+ assert(it != saved_unwind_states.begin() &&
+ "Unwind row for the function entry missing");
+ --it; // Move it to the row corresponding to the current offset
+
+ // If the offset of m_curr_row don't match with the offset we see in
+ // saved_unwind_states
+ // then we have to update m_curr_row and m_register_values based on
+ // the saved values. It
+ // is happenning after we processed an epilogue and a return to
+ // caller instruction.
+ if (it->second.first->GetOffset() != m_curr_row->GetOffset()) {
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *it->second.first;
+ m_curr_row.reset(newrow);
+ m_register_values = it->second.second;
+ }
+
+ m_inst_emulator_ap->SetInstruction(inst->GetOpcode(),
+ inst->GetAddress(), nullptr);
+
+ if (last_condition !=
+ m_inst_emulator_ap->GetInstructionCondition()) {
+ if (m_inst_emulator_ap->GetInstructionCondition() !=
+ EmulateInstruction::UnconditionalCondition &&
+ saved_unwind_states.count(current_offset) == 0) {
+ // If we don't have a saved row for the current offset then save
+ // our
+ // current state because we will have to restore it after the
+ // conditional block.
+ auto new_row =
+ std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
+ saved_unwind_states.insert(
+ {current_offset, {new_row, m_register_values}});
+ }
+
+ // If the last instruction was conditional with a different
+ // condition
+ // then the then current condition then restore the condition.
+ if (last_condition !=
+ EmulateInstruction::UnconditionalCondition) {
+ const auto &saved_state =
+ saved_unwind_states.at(condition_block_start_offset);
+ m_curr_row =
+ std::make_shared<UnwindPlan::Row>(*saved_state.first);
+ m_curr_row->SetOffset(current_offset);
+ m_register_values = saved_state.second;
+ bool replace_existing =
+ true; // The last instruction might already
+ // created a row for this offset and
+ // we want to overwrite it.
+ unwind_plan.InsertRow(
+ std::make_shared<UnwindPlan::Row>(*m_curr_row),
+ replace_existing);
+ }
+
+ // We are starting a new conditional block at the catual offset
+ condition_block_start_offset = current_offset;
+ }
+
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+ lldb_private::FormatEntity::Entry format;
+ FormatEntity::Parse("${frame.pc}: ", format);
+ inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize(), show_address,
+ show_bytes, NULL, NULL, NULL, &format, 0);
+ log->PutString(strm.GetString());
+ }
+
+ last_condition = m_inst_emulator_ap->GetInstructionCondition();
+
+ m_inst_emulator_ap->EvaluateInstruction(
+ eEmulateInstructionOptionIgnoreConditions);
+
+ // If the current instruction is a branch forward then save the
+ // current CFI information
+ // for the offset where we are branching.
+ if (m_forward_branch_offset != 0 &&
+ range.ContainsFileAddress(inst->GetAddress().GetFileAddress() +
+ m_forward_branch_offset)) {
+ auto newrow =
+ std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
+ newrow->SetOffset(current_offset + m_forward_branch_offset);
+ saved_unwind_states.insert(
+ {current_offset + m_forward_branch_offset,
+ {newrow, m_register_values}});
+ unwind_plan.InsertRow(newrow);
+ }
+
+ // Were there any changes to the CFI while evaluating this
+ // instruction?
+ if (m_curr_row_modified) {
+ // Save the modified row if we don't already have a CFI row in the
+ // currennt address
+ if (saved_unwind_states.count(
+ current_offset + inst->GetOpcode().GetByteSize()) == 0) {
+ m_curr_row->SetOffset(current_offset +
+ inst->GetOpcode().GetByteSize());
+ unwind_plan.InsertRow(m_curr_row);
+ saved_unwind_states.insert(
+ {current_offset + inst->GetOpcode().GetByteSize(),
+ {m_curr_row, m_register_values}});
+
+ // Allocate a new Row for m_curr_row, copy the current state
+ // into it
UnwindPlan::Row *newrow = new UnwindPlan::Row;
- if (last_row.get())
- *newrow = *last_row.get();
+ *newrow = *m_curr_row.get();
m_curr_row.reset(newrow);
-
- // Add the initial state to the save list with offset 0.
- saved_unwind_states.insert({0, {last_row, m_register_values}});
-
- // cache the pc register number (in whatever register numbering this UnwindPlan uses) for
- // quick reference during instruction parsing.
- RegisterInfo pc_reg_info;
- m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info);
-
- // cache the return address register number (in whatever register numbering this UnwindPlan uses) for
- // quick reference during instruction parsing.
- RegisterInfo ra_reg_info;
- m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
-
- // The architecture dependent condition code of the last processed instruction.
- EmulateInstruction::InstructionCondition last_condition = EmulateInstruction::UnconditionalCondition;
- lldb::addr_t condition_block_start_offset = 0;
-
- for (size_t idx=0; idx<num_instructions; ++idx)
- {
- m_curr_row_modified = false;
- m_forward_branch_offset = 0;
-
- inst = inst_list.GetInstructionAtIndex (idx).get();
- if (inst)
- {
- lldb::addr_t current_offset = inst->GetAddress().GetFileAddress() - base_addr;
- auto it = saved_unwind_states.upper_bound(current_offset);
- assert(it != saved_unwind_states.begin() && "Unwind row for the function entry missing");
- --it; // Move it to the row corresponding to the current offset
-
- // If the offset of m_curr_row don't match with the offset we see in saved_unwind_states
- // then we have to update m_curr_row and m_register_values based on the saved values. It
- // is happenning after we processed an epilogue and a return to caller instruction.
- if (it->second.first->GetOffset() != m_curr_row->GetOffset())
- {
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *it->second.first;
- m_curr_row.reset(newrow);
- m_register_values = it->second.second;
- }
-
- m_inst_emulator_ap->SetInstruction (inst->GetOpcode(),
- inst->GetAddress(),
- exe_ctx.GetTargetPtr());
-
- if (last_condition != m_inst_emulator_ap->GetInstructionCondition())
- {
- if (m_inst_emulator_ap->GetInstructionCondition() != EmulateInstruction::UnconditionalCondition &&
- saved_unwind_states.count(current_offset) == 0)
- {
- // If we don't have a saved row for the current offset then save our
- // current state because we will have to restore it after the
- // conditional block.
- auto new_row = std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
- saved_unwind_states.insert({current_offset, {new_row, m_register_values}});
- }
-
- // If the last instruction was conditional with a different condition
- // then the then current condition then restore the condition.
- if (last_condition != EmulateInstruction::UnconditionalCondition)
- {
- const auto& saved_state = saved_unwind_states.at(condition_block_start_offset);
- m_curr_row = std::make_shared<UnwindPlan::Row>(*saved_state.first);
- m_curr_row->SetOffset(current_offset);
- m_register_values = saved_state.second;
- bool replace_existing = true; // The last instruction might already
- // created a row for this offset and
- // we want to overwrite it.
- unwind_plan.InsertRow(std::make_shared<UnwindPlan::Row>(*m_curr_row), replace_existing);
- }
-
- // We are starting a new conditional block at the catual offset
- condition_block_start_offset = current_offset;
- }
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
- lldb_private::FormatEntity::Entry format;
- FormatEntity::Parse("${frame.pc}: ", format);
- inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, &format, 0);
- log->PutCString (strm.GetData());
- }
-
- last_condition = m_inst_emulator_ap->GetInstructionCondition();
-
- m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
-
- // If the current instruction is a branch forward then save the current CFI information
- // for the offset where we are branching.
- if (m_forward_branch_offset != 0 && range.ContainsFileAddress(inst->GetAddress().GetFileAddress() + m_forward_branch_offset))
- {
- auto newrow = std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
- newrow->SetOffset(current_offset + m_forward_branch_offset);
- saved_unwind_states.insert({current_offset + m_forward_branch_offset, {newrow, m_register_values}});
- unwind_plan.InsertRow(newrow);
- }
-
- // Were there any changes to the CFI while evaluating this instruction?
- if (m_curr_row_modified)
- {
- // Save the modified row if we don't already have a CFI row in the currennt address
- if (saved_unwind_states.count(current_offset + inst->GetOpcode().GetByteSize()) == 0)
- {
- m_curr_row->SetOffset (current_offset + inst->GetOpcode().GetByteSize());
- unwind_plan.InsertRow (m_curr_row);
- saved_unwind_states.insert({current_offset + inst->GetOpcode().GetByteSize(), {m_curr_row, m_register_values}});
-
- // Allocate a new Row for m_curr_row, copy the current state into it
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *m_curr_row.get();
- m_curr_row.reset(newrow);
- }
- }
- }
- }
+ }
}
+ }
}
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
- lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
- strm.Printf ("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):", base_addr, base_addr + range.GetByteSize());
- unwind_plan.Dump(strm, &thread, base_addr);
- log->PutCString (strm.GetData());
- }
- return unwind_plan.GetRowCount() > 0;
+ }
}
- return false;
+
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+ lldb::addr_t base_addr = range.GetBaseAddress().GetFileAddress();
+ strm.Printf("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):",
+ base_addr, base_addr + range.GetByteSize());
+ unwind_plan.Dump(strm, nullptr, base_addr);
+ log->PutString(strm.GetString());
+ }
+ return unwind_plan.GetRowCount() > 0;
+ }
+ return false;
}
-bool
-UnwindAssemblyInstEmulation::AugmentUnwindPlanFromCallSite (AddressRange& func,
- Thread& thread,
- UnwindPlan& unwind_plan)
-{
- return false;
+bool UnwindAssemblyInstEmulation::AugmentUnwindPlanFromCallSite(
+ AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
+ return false;
}
-bool
-UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func,
- Thread& thread,
- UnwindPlan &unwind_plan)
-{
- return false;
+bool UnwindAssemblyInstEmulation::GetFastUnwindPlan(AddressRange &func,
+ Thread &thread,
+ UnwindPlan &unwind_plan) {
+ return false;
}
-bool
-UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func,
- const ExecutionContext &exe_ctx,
- Address& first_non_prologue_insn)
-{
- return false;
+bool UnwindAssemblyInstEmulation::FirstNonPrologueInsn(
+ AddressRange &func, const ExecutionContext &exe_ctx,
+ Address &first_non_prologue_insn) {
+ return false;
}
UnwindAssembly *
-UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch)
-{
- std::unique_ptr<EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL));
- // Make sure that all prologue instructions are handled
- if (inst_emulator_ap.get())
- return new UnwindAssemblyInstEmulation (arch, inst_emulator_ap.release());
- return NULL;
+UnwindAssemblyInstEmulation::CreateInstance(const ArchSpec &arch) {
+ std::unique_ptr<EmulateInstruction> inst_emulator_ap(
+ EmulateInstruction::FindPlugin(arch, eInstructionTypePrologueEpilogue,
+ NULL));
+ // Make sure that all prologue instructions are handled
+ if (inst_emulator_ap.get())
+ return new UnwindAssemblyInstEmulation(arch, inst_emulator_ap.release());
+ return NULL;
}
-
//------------------------------------------------------------------
// PluginInterface protocol in UnwindAssemblyParser_x86
//------------------------------------------------------------------
-ConstString
-UnwindAssemblyInstEmulation::GetPluginName()
-{
- return GetPluginNameStatic();
+ConstString UnwindAssemblyInstEmulation::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-UnwindAssemblyInstEmulation::GetPluginVersion()
-{
- return 1;
-}
+uint32_t UnwindAssemblyInstEmulation::GetPluginVersion() { return 1; }
-void
-UnwindAssemblyInstEmulation::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void UnwindAssemblyInstEmulation::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-UnwindAssemblyInstEmulation::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void UnwindAssemblyInstEmulation::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-ConstString
-UnwindAssemblyInstEmulation::GetPluginNameStatic()
-{
- static ConstString g_name("inst-emulation");
- return g_name;
+ConstString UnwindAssemblyInstEmulation::GetPluginNameStatic() {
+ static ConstString g_name("inst-emulation");
+ return g_name;
}
-const char *
-UnwindAssemblyInstEmulation::GetPluginDescriptionStatic()
-{
- return "Instruction emulation based unwind information.";
+const char *UnwindAssemblyInstEmulation::GetPluginDescriptionStatic() {
+ return "Instruction emulation based unwind information.";
}
-
-uint64_t
-UnwindAssemblyInstEmulation::MakeRegisterKindValuePair (const RegisterInfo &reg_info)
-{
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- if (EmulateInstruction::GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
- return (uint64_t)reg_kind << 24 | reg_num;
- return 0ull;
+uint64_t UnwindAssemblyInstEmulation::MakeRegisterKindValuePair(
+ const RegisterInfo &reg_info) {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ if (EmulateInstruction::GetBestRegisterKindAndNumber(&reg_info, reg_kind,
+ reg_num))
+ return (uint64_t)reg_kind << 24 | reg_num;
+ return 0ull;
}
-void
-UnwindAssemblyInstEmulation::SetRegisterValue (const RegisterInfo &reg_info, const RegisterValue &reg_value)
-{
- m_register_values[MakeRegisterKindValuePair (reg_info)] = reg_value;
+void UnwindAssemblyInstEmulation::SetRegisterValue(
+ const RegisterInfo &reg_info, const RegisterValue &reg_value) {
+ m_register_values[MakeRegisterKindValuePair(reg_info)] = reg_value;
}
-bool
-UnwindAssemblyInstEmulation::GetRegisterValue (const RegisterInfo &reg_info, RegisterValue &reg_value)
-{
- const uint64_t reg_id = MakeRegisterKindValuePair (reg_info);
- RegisterValueMap::const_iterator pos = m_register_values.find(reg_id);
- if (pos != m_register_values.end())
- {
- reg_value = pos->second;
- return true; // We had a real value that comes from an opcode that wrote
- // to it...
- }
- // We are making up a value that is recognizable...
- reg_value.SetUInt(reg_id, reg_info.byte_size);
- return false;
+bool UnwindAssemblyInstEmulation::GetRegisterValue(const RegisterInfo &reg_info,
+ RegisterValue &reg_value) {
+ const uint64_t reg_id = MakeRegisterKindValuePair(reg_info);
+ RegisterValueMap::const_iterator pos = m_register_values.find(reg_id);
+ if (pos != m_register_values.end()) {
+ reg_value = pos->second;
+ return true; // We had a real value that comes from an opcode that wrote
+ // to it...
+ }
+ // We are making up a value that is recognizable...
+ reg_value.SetUInt(reg_id, reg_info.byte_size);
+ return false;
}
-
-size_t
-UnwindAssemblyInstEmulation::ReadMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t dst_len)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16" PRIx64 ", dst = %p, dst_len = %" PRIu64 ", context = ",
- addr,
- dst,
- (uint64_t)dst_len);
- context.Dump(strm, instruction);
- log->PutCString (strm.GetData ());
- }
- memset (dst, 0, dst_len);
- return dst_len;
+size_t UnwindAssemblyInstEmulation::ReadMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
+ size_t dst_len) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+ strm.Printf(
+ "UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16" PRIx64
+ ", dst = %p, dst_len = %" PRIu64 ", context = ",
+ addr, dst, (uint64_t)dst_len);
+ context.Dump(strm, instruction);
+ log->PutString(strm.GetString());
+ }
+ memset(dst, 0, dst_len);
+ return dst_len;
}
-size_t
-UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t dst_len)
-{
- if (baton && dst && dst_len)
- return ((UnwindAssemblyInstEmulation *)baton)->WriteMemory (instruction, context, addr, dst, dst_len);
- return 0;
+size_t UnwindAssemblyInstEmulation::WriteMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr,
+ const void *dst, size_t dst_len) {
+ if (baton && dst && dst_len)
+ return ((UnwindAssemblyInstEmulation *)baton)
+ ->WriteMemory(instruction, context, addr, dst, dst_len);
+ return 0;
}
-size_t
-UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t dst_len)
-{
- DataExtractor data (dst,
- dst_len,
- instruction->GetArchitecture ().GetByteOrder(),
- instruction->GetArchitecture ().GetAddressByteSize());
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
-
- strm.PutCString ("UnwindAssemblyInstEmulation::WriteMemory (");
- data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
- strm.PutCString (", context = ");
- context.Dump(strm, instruction);
- log->PutCString (strm.GetData());
- }
-
- const bool cant_replace = false;
-
- switch (context.type)
- {
- default:
- case EmulateInstruction::eContextInvalid:
- case EmulateInstruction::eContextReadOpcode:
- case EmulateInstruction::eContextImmediate:
- case EmulateInstruction::eContextAdjustBaseRegister:
- case EmulateInstruction::eContextRegisterPlusOffset:
- case EmulateInstruction::eContextAdjustPC:
- case EmulateInstruction::eContextRegisterStore:
- case EmulateInstruction::eContextRegisterLoad:
- case EmulateInstruction::eContextRelativeBranchImmediate:
- case EmulateInstruction::eContextAbsoluteBranchRegister:
- case EmulateInstruction::eContextSupervisorCall:
- case EmulateInstruction::eContextTableBranchReadMemory:
- case EmulateInstruction::eContextWriteRegisterRandomBits:
- case EmulateInstruction::eContextWriteMemoryRandomBits:
- case EmulateInstruction::eContextArithmetic:
- case EmulateInstruction::eContextAdvancePC:
- case EmulateInstruction::eContextReturnFromException:
- case EmulateInstruction::eContextPopRegisterOffStack:
- case EmulateInstruction::eContextAdjustStackPointer:
- break;
-
- case EmulateInstruction::eContextPushRegisterOnStack:
- {
- uint32_t reg_num = LLDB_INVALID_REGNUM;
- uint32_t generic_regnum = LLDB_INVALID_REGNUM;
- if (context.info_type == EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset)
- {
- const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
- reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[unwind_reg_kind];
- generic_regnum = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindGeneric];
- }
- else
- assert (!"unhandled case, add code to handle this!");
-
- if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
- {
- if (m_pushed_regs.find (reg_num) == m_pushed_regs.end())
- {
- m_pushed_regs[reg_num] = addr;
- const int32_t offset = addr - m_initial_sp;
- m_curr_row->SetRegisterLocationToAtCFAPlusOffset (reg_num, offset, cant_replace);
- m_curr_row_modified = true;
- }
- }
- }
- break;
-
+size_t UnwindAssemblyInstEmulation::WriteMemory(
+ EmulateInstruction *instruction, const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t dst_len) {
+ DataExtractor data(dst, dst_len,
+ instruction->GetArchitecture().GetByteOrder(),
+ instruction->GetArchitecture().GetAddressByteSize());
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+
+ strm.PutCString("UnwindAssemblyInstEmulation::WriteMemory (");
+ data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
+ strm.PutCString(", context = ");
+ context.Dump(strm, instruction);
+ log->PutString(strm.GetString());
+ }
+
+ const bool cant_replace = false;
+
+ switch (context.type) {
+ default:
+ case EmulateInstruction::eContextInvalid:
+ case EmulateInstruction::eContextReadOpcode:
+ case EmulateInstruction::eContextImmediate:
+ case EmulateInstruction::eContextAdjustBaseRegister:
+ case EmulateInstruction::eContextRegisterPlusOffset:
+ case EmulateInstruction::eContextAdjustPC:
+ case EmulateInstruction::eContextRegisterStore:
+ case EmulateInstruction::eContextRegisterLoad:
+ case EmulateInstruction::eContextRelativeBranchImmediate:
+ case EmulateInstruction::eContextAbsoluteBranchRegister:
+ case EmulateInstruction::eContextSupervisorCall:
+ case EmulateInstruction::eContextTableBranchReadMemory:
+ case EmulateInstruction::eContextWriteRegisterRandomBits:
+ case EmulateInstruction::eContextWriteMemoryRandomBits:
+ case EmulateInstruction::eContextArithmetic:
+ case EmulateInstruction::eContextAdvancePC:
+ case EmulateInstruction::eContextReturnFromException:
+ case EmulateInstruction::eContextPopRegisterOffStack:
+ case EmulateInstruction::eContextAdjustStackPointer:
+ break;
+
+ case EmulateInstruction::eContextPushRegisterOnStack: {
+ uint32_t reg_num = LLDB_INVALID_REGNUM;
+ uint32_t generic_regnum = LLDB_INVALID_REGNUM;
+ if (context.info_type ==
+ EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset) {
+ const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
+ reg_num = context.info.RegisterToRegisterPlusOffset.data_reg
+ .kinds[unwind_reg_kind];
+ generic_regnum = context.info.RegisterToRegisterPlusOffset.data_reg
+ .kinds[eRegisterKindGeneric];
+ } else
+ assert(!"unhandled case, add code to handle this!");
+
+ if (reg_num != LLDB_INVALID_REGNUM &&
+ generic_regnum != LLDB_REGNUM_GENERIC_SP) {
+ if (m_pushed_regs.find(reg_num) == m_pushed_regs.end()) {
+ m_pushed_regs[reg_num] = addr;
+ const int32_t offset = addr - m_initial_sp;
+ m_curr_row->SetRegisterLocationToAtCFAPlusOffset(reg_num, offset,
+ cant_replace);
+ m_curr_row_modified = true;
+ }
}
+ } break;
+ }
- return dst_len;
+ return dst_len;
}
-bool
-UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
- void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value)
-{
-
- if (baton && reg_info)
- return ((UnwindAssemblyInstEmulation *)baton)->ReadRegister (instruction, reg_info, reg_value);
- return false;
+bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+
+ if (baton && reg_info)
+ return ((UnwindAssemblyInstEmulation *)baton)
+ ->ReadRegister(instruction, reg_info, reg_value);
+ return false;
}
-bool
-UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value)
-{
- bool synthetic = GetRegisterValue (*reg_info, reg_value);
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
-
- StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => synthetic_value = %i, value = ", reg_info->name, synthetic);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
- log->PutCString(strm.GetData());
- }
- return true;
+bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ bool synthetic = GetRegisterValue(*reg_info, reg_value);
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+
+ StreamString strm;
+ strm.Printf("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => "
+ "synthetic_value = %i, value = ",
+ reg_info->name, synthetic);
+ reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ log->PutString(strm.GetString());
+ }
+ return true;
}
-bool
-UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value)
-{
- if (baton && reg_info)
- return ((UnwindAssemblyInstEmulation *)baton)->WriteRegister (instruction, context, reg_info, reg_value);
- return false;
+bool UnwindAssemblyInstEmulation::WriteRegister(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ if (baton && reg_info)
+ return ((UnwindAssemblyInstEmulation *)baton)
+ ->WriteRegister(instruction, context, reg_info, reg_value);
+ return false;
}
-bool
-UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
-
- StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
- strm.PutCString (", context = ");
- context.Dump(strm, instruction);
- log->PutCString(strm.GetData());
+bool UnwindAssemblyInstEmulation::WriteRegister(
+ EmulateInstruction *instruction, const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+
+ StreamString strm;
+ strm.Printf(
+ "UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ",
+ reg_info->name);
+ reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ strm.PutCString(", context = ");
+ context.Dump(strm, instruction);
+ log->PutString(strm.GetString());
+ }
+
+ SetRegisterValue(*reg_info, reg_value);
+
+ switch (context.type) {
+ case EmulateInstruction::eContextInvalid:
+ case EmulateInstruction::eContextReadOpcode:
+ case EmulateInstruction::eContextImmediate:
+ case EmulateInstruction::eContextAdjustBaseRegister:
+ case EmulateInstruction::eContextRegisterPlusOffset:
+ case EmulateInstruction::eContextAdjustPC:
+ case EmulateInstruction::eContextRegisterStore:
+ case EmulateInstruction::eContextSupervisorCall:
+ case EmulateInstruction::eContextTableBranchReadMemory:
+ case EmulateInstruction::eContextWriteRegisterRandomBits:
+ case EmulateInstruction::eContextWriteMemoryRandomBits:
+ case EmulateInstruction::eContextAdvancePC:
+ case EmulateInstruction::eContextReturnFromException:
+ case EmulateInstruction::eContextPushRegisterOnStack:
+ case EmulateInstruction::eContextRegisterLoad:
+ // {
+ // const uint32_t reg_num =
+ // reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ // if (reg_num != LLDB_INVALID_REGNUM)
+ // {
+ // const bool can_replace_only_if_unspecified = true;
+ //
+ // m_curr_row.SetRegisterLocationToUndefined (reg_num,
+ // can_replace_only_if_unspecified,
+ // can_replace_only_if_unspecified);
+ // m_curr_row_modified = true;
+ // }
+ // }
+ break;
+
+ case EmulateInstruction::eContextArithmetic: {
+ // If we adjusted the current frame pointer by a constant then adjust the
+ // CFA offset
+ // with the same amount.
+ lldb::RegisterKind kind = m_unwind_plan_ptr->GetRegisterKind();
+ if (m_fp_is_cfa && reg_info->kinds[kind] == m_cfa_reg_info.kinds[kind] &&
+ context.info_type == EmulateInstruction::eInfoTypeRegisterPlusOffset &&
+ context.info.RegisterPlusOffset.reg.kinds[kind] ==
+ m_cfa_reg_info.kinds[kind]) {
+ const int64_t offset = context.info.RegisterPlusOffset.signed_offset;
+ m_curr_row->GetCFAValue().IncOffset(-1 * offset);
+ m_curr_row_modified = true;
}
-
- SetRegisterValue (*reg_info, reg_value);
-
- switch (context.type)
- {
- case EmulateInstruction::eContextInvalid:
- case EmulateInstruction::eContextReadOpcode:
- case EmulateInstruction::eContextImmediate:
- case EmulateInstruction::eContextAdjustBaseRegister:
- case EmulateInstruction::eContextRegisterPlusOffset:
- case EmulateInstruction::eContextAdjustPC:
- case EmulateInstruction::eContextRegisterStore:
- case EmulateInstruction::eContextSupervisorCall:
- case EmulateInstruction::eContextTableBranchReadMemory:
- case EmulateInstruction::eContextWriteRegisterRandomBits:
- case EmulateInstruction::eContextWriteMemoryRandomBits:
- case EmulateInstruction::eContextAdvancePC:
- case EmulateInstruction::eContextReturnFromException:
- case EmulateInstruction::eContextPushRegisterOnStack:
- case EmulateInstruction::eContextRegisterLoad:
-// {
-// const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
-// if (reg_num != LLDB_INVALID_REGNUM)
-// {
-// const bool can_replace_only_if_unspecified = true;
-//
-// m_curr_row.SetRegisterLocationToUndefined (reg_num,
-// can_replace_only_if_unspecified,
-// can_replace_only_if_unspecified);
-// m_curr_row_modified = true;
-// }
-// }
- break;
-
- case EmulateInstruction::eContextArithmetic:
- {
- // If we adjusted the current frame pointer by a constant then adjust the CFA offset
- // with the same amount.
- lldb::RegisterKind kind = m_unwind_plan_ptr->GetRegisterKind();
- if (m_fp_is_cfa && reg_info->kinds[kind] == m_cfa_reg_info.kinds[kind] &&
- context.info_type == EmulateInstruction::eInfoTypeRegisterPlusOffset &&
- context.info.RegisterPlusOffset.reg.kinds[kind] == m_cfa_reg_info.kinds[kind])
- {
- const int64_t offset = context.info.RegisterPlusOffset.signed_offset;
- m_curr_row->GetCFAValue().IncOffset(-1 * offset);
- m_curr_row_modified = true;
- }
- }
- break;
-
- case EmulateInstruction::eContextAbsoluteBranchRegister:
- case EmulateInstruction::eContextRelativeBranchImmediate:
- {
- if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediate &&
- context.info.ISAAndImmediate.unsigned_data32 > 0)
- {
- m_forward_branch_offset = context.info.ISAAndImmediateSigned.signed_data32;
- }
- else if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediateSigned &&
- context.info.ISAAndImmediateSigned.signed_data32 > 0)
- {
- m_forward_branch_offset = context.info.ISAAndImmediate.unsigned_data32;
- }
- else if (context.info_type == EmulateInstruction::eInfoTypeImmediate &&
- context.info.unsigned_immediate > 0)
- {
- m_forward_branch_offset = context.info.unsigned_immediate;
- }
- else if (context.info_type == EmulateInstruction::eInfoTypeImmediateSigned &&
- context.info.signed_immediate > 0)
- {
- m_forward_branch_offset = context.info.signed_immediate;
- }
- }
- break;
-
- case EmulateInstruction::eContextPopRegisterOffStack:
- {
- const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
- const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
- if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
- {
- switch (context.info_type)
- {
- case EmulateInstruction::eInfoTypeAddress:
- if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() &&
- context.info.address == m_pushed_regs[reg_num])
- {
- m_curr_row->SetRegisterLocationToSame(reg_num,
- false /*must_replace*/);
- m_curr_row_modified = true;
- }
- break;
- case EmulateInstruction::eInfoTypeISA:
- assert((generic_regnum == LLDB_REGNUM_GENERIC_PC ||
- generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
- "eInfoTypeISA used for poping a register other the the PC/FLAGS");
- if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS)
- {
- m_curr_row->SetRegisterLocationToSame(reg_num,
- false /*must_replace*/);
- m_curr_row_modified = true;
- }
- break;
- default:
- assert(false && "unhandled case, add code to handle this!");
- break;
- }
- }
- }
- break;
-
- case EmulateInstruction::eContextSetFramePointer:
- if (!m_fp_is_cfa)
- {
- m_fp_is_cfa = true;
- m_cfa_reg_info = *reg_info;
- const uint32_t cfa_reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
- assert (cfa_reg_num != LLDB_INVALID_REGNUM);
- m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(cfa_reg_num, m_initial_sp -
- reg_value.GetAsUInt64());
- m_curr_row_modified = true;
- }
- break;
-
- case EmulateInstruction::eContextAdjustStackPointer:
- // If we have created a frame using the frame pointer, don't follow
- // subsequent adjustments to the stack pointer.
- if (!m_fp_is_cfa)
- {
- m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
- m_curr_row->GetCFAValue().GetRegisterNumber(),
- m_initial_sp - reg_value.GetAsUInt64());
- m_curr_row_modified = true;
- }
- break;
+ } break;
+
+ case EmulateInstruction::eContextAbsoluteBranchRegister:
+ case EmulateInstruction::eContextRelativeBranchImmediate: {
+ if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediate &&
+ context.info.ISAAndImmediate.unsigned_data32 > 0) {
+ m_forward_branch_offset =
+ context.info.ISAAndImmediateSigned.signed_data32;
+ } else if (context.info_type ==
+ EmulateInstruction::eInfoTypeISAAndImmediateSigned &&
+ context.info.ISAAndImmediateSigned.signed_data32 > 0) {
+ m_forward_branch_offset = context.info.ISAAndImmediate.unsigned_data32;
+ } else if (context.info_type == EmulateInstruction::eInfoTypeImmediate &&
+ context.info.unsigned_immediate > 0) {
+ m_forward_branch_offset = context.info.unsigned_immediate;
+ } else if (context.info_type ==
+ EmulateInstruction::eInfoTypeImmediateSigned &&
+ context.info.signed_immediate > 0) {
+ m_forward_branch_offset = context.info.signed_immediate;
}
- return true;
+ } break;
+
+ case EmulateInstruction::eContextPopRegisterOffStack: {
+ const uint32_t reg_num =
+ reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_num != LLDB_INVALID_REGNUM &&
+ generic_regnum != LLDB_REGNUM_GENERIC_SP) {
+ switch (context.info_type) {
+ case EmulateInstruction::eInfoTypeAddress:
+ if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() &&
+ context.info.address == m_pushed_regs[reg_num]) {
+ m_curr_row->SetRegisterLocationToSame(reg_num,
+ false /*must_replace*/);
+ m_curr_row_modified = true;
+ }
+ break;
+ case EmulateInstruction::eInfoTypeISA:
+ assert(
+ (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+ generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
+ "eInfoTypeISA used for poping a register other the the PC/FLAGS");
+ if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS) {
+ m_curr_row->SetRegisterLocationToSame(reg_num,
+ false /*must_replace*/);
+ m_curr_row_modified = true;
+ }
+ break;
+ default:
+ assert(false && "unhandled case, add code to handle this!");
+ break;
+ }
+ }
+ } break;
+
+ case EmulateInstruction::eContextSetFramePointer:
+ if (!m_fp_is_cfa) {
+ m_fp_is_cfa = true;
+ m_cfa_reg_info = *reg_info;
+ const uint32_t cfa_reg_num =
+ reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ assert(cfa_reg_num != LLDB_INVALID_REGNUM);
+ m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
+ cfa_reg_num, m_initial_sp - reg_value.GetAsUInt64());
+ m_curr_row_modified = true;
+ }
+ break;
+
+ case EmulateInstruction::eContextRestoreStackPointer:
+ if (m_fp_is_cfa) {
+ m_fp_is_cfa = false;
+ m_cfa_reg_info = *reg_info;
+ const uint32_t cfa_reg_num =
+ reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ assert(cfa_reg_num != LLDB_INVALID_REGNUM);
+ m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
+ cfa_reg_num, m_initial_sp - reg_value.GetAsUInt64());
+ m_curr_row_modified = true;
+ }
+ break;
+
+ case EmulateInstruction::eContextAdjustStackPointer:
+ // If we have created a frame using the frame pointer, don't follow
+ // subsequent adjustments to the stack pointer.
+ if (!m_fp_is_cfa) {
+ m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_curr_row->GetCFAValue().GetRegisterNumber(),
+ m_initial_sp - reg_value.GetAsUInt64());
+ m_curr_row_modified = true;
+ }
+ break;
+ }
+ return true;
}
-
-
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
index 61d3ece3f6c3..e587c93b427c 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
@@ -14,172 +14,148 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/lldb-private.h"
-class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
-{
+class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly {
public:
- ~UnwindAssemblyInstEmulation() override = default;
-
- bool
- GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- AugmentUnwindPlanFromCallSite(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- GetFastUnwindPlan(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan &unwind_plan) override;
-
- // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
- bool
- FirstNonPrologueInsn(lldb_private::AddressRange& func,
- const lldb_private::ExecutionContext &exe_ctx,
- lldb_private::Address& first_non_prologue_insn) override;
-
- static lldb_private::UnwindAssembly *
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
+ ~UnwindAssemblyInstEmulation() override = default;
+
+ bool GetNonCallSiteUnwindPlanFromAssembly(
+ lldb_private::AddressRange &func, lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool
+ GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange &func,
+ uint8_t *opcode_data, size_t opcode_size,
+ lldb_private::UnwindPlan &unwind_plan);
+
+ bool
+ AugmentUnwindPlanFromCallSite(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool GetFastUnwindPlan(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ // thread may be NULL in which case we only use the Target (e.g. if this is
+ // called pre-process-launch).
+ bool
+ FirstNonPrologueInsn(lldb_private::AddressRange &func,
+ const lldb_private::ExecutionContext &exe_ctx,
+ lldb_private::Address &first_non_prologue_insn) override;
+
+ static lldb_private::UnwindAssembly *
+ CreateInstance(const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
private:
- // Call CreateInstance to get an instance of this class
- UnwindAssemblyInstEmulation(const lldb_private::ArchSpec &arch,
- lldb_private::EmulateInstruction *inst_emulator) :
- UnwindAssembly (arch),
- m_inst_emulator_ap (inst_emulator),
- m_range_ptr (NULL),
- m_thread_ptr (NULL),
- m_unwind_plan_ptr (NULL),
- m_curr_row (),
- m_cfa_reg_info (),
- m_fp_is_cfa (false),
- m_register_values (),
- m_pushed_regs(),
- m_curr_row_modified (false),
- m_forward_branch_offset (0)
- {
- if (m_inst_emulator_ap.get())
- {
- m_inst_emulator_ap->SetBaton (this);
- m_inst_emulator_ap->SetCallbacks (ReadMemory, WriteMemory, ReadRegister, WriteRegister);
- }
+ // Call CreateInstance to get an instance of this class
+ UnwindAssemblyInstEmulation(const lldb_private::ArchSpec &arch,
+ lldb_private::EmulateInstruction *inst_emulator)
+ : UnwindAssembly(arch), m_inst_emulator_ap(inst_emulator),
+ m_range_ptr(NULL), m_unwind_plan_ptr(NULL), m_curr_row(),
+ m_cfa_reg_info(), m_fp_is_cfa(false), m_register_values(),
+ m_pushed_regs(), m_curr_row_modified(false),
+ m_forward_branch_offset(0) {
+ if (m_inst_emulator_ap.get()) {
+ m_inst_emulator_ap->SetBaton(this);
+ m_inst_emulator_ap->SetCallbacks(ReadMemory, WriteMemory, ReadRegister,
+ WriteRegister);
}
-
- static size_t
- ReadMemory (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length);
-
- static size_t
- WriteMemory (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length);
-
- static bool
- ReadRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value);
-
- static bool
- WriteRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value);
-
-// size_t
-// ReadMemory (lldb_private::EmulateInstruction *instruction,
-// const lldb_private::EmulateInstruction::Context &context,
-// lldb::addr_t addr,
-// void *dst,
-// size_t length);
-
- size_t
- WriteMemory (lldb_private::EmulateInstruction *instruction,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length);
-
- bool
- ReadRegister (lldb_private::EmulateInstruction *instruction,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value);
-
- bool
- WriteRegister (lldb_private::EmulateInstruction *instruction,
- const lldb_private::EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value);
-
- static uint64_t
- MakeRegisterKindValuePair (const lldb_private::RegisterInfo &reg_info);
-
- void
- SetRegisterValue (const lldb_private::RegisterInfo &reg_info,
- const lldb_private::RegisterValue &reg_value);
-
- bool
- GetRegisterValue (const lldb_private::RegisterInfo &reg_info,
- lldb_private::RegisterValue &reg_value);
-
- std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
- lldb_private::AddressRange* m_range_ptr;
- lldb_private::Thread* m_thread_ptr;
- lldb_private::UnwindPlan* m_unwind_plan_ptr;
- lldb_private::UnwindPlan::RowSP m_curr_row;
- typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
- uint64_t m_initial_sp;
- lldb_private::RegisterInfo m_cfa_reg_info;
- bool m_fp_is_cfa;
- typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
- RegisterValueMap m_register_values;
- PushedRegisterToAddrMap m_pushed_regs;
-
- // While processing the instruction stream, we need to communicate some state change
- // information up to the higher level loop that makes decisions about how to push
- // the unwind instructions for the UnwindPlan we're constructing.
-
- // The instruction we're processing updated the UnwindPlan::Row contents
- bool m_curr_row_modified;
- // The instruction is branching forward with the given offset. 0 value means no branching.
- uint32_t m_forward_branch_offset;
+ }
+
+ static size_t
+ ReadMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length);
+
+ static size_t
+ WriteMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t length);
+
+ static bool ReadRegister(lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value);
+
+ static bool
+ WriteRegister(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value);
+
+ // size_t
+ // ReadMemory (lldb_private::EmulateInstruction *instruction,
+ // const lldb_private::EmulateInstruction::Context &context,
+ // lldb::addr_t addr,
+ // void *dst,
+ // size_t length);
+
+ size_t WriteMemory(lldb_private::EmulateInstruction *instruction,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t length);
+
+ bool ReadRegister(lldb_private::EmulateInstruction *instruction,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value);
+
+ bool WriteRegister(lldb_private::EmulateInstruction *instruction,
+ const lldb_private::EmulateInstruction::Context &context,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value);
+
+ static uint64_t
+ MakeRegisterKindValuePair(const lldb_private::RegisterInfo &reg_info);
+
+ void SetRegisterValue(const lldb_private::RegisterInfo &reg_info,
+ const lldb_private::RegisterValue &reg_value);
+
+ bool GetRegisterValue(const lldb_private::RegisterInfo &reg_info,
+ lldb_private::RegisterValue &reg_value);
+
+ std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
+ lldb_private::AddressRange *m_range_ptr;
+ lldb_private::UnwindPlan *m_unwind_plan_ptr;
+ lldb_private::UnwindPlan::RowSP m_curr_row;
+ typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
+ uint64_t m_initial_sp;
+ lldb_private::RegisterInfo m_cfa_reg_info;
+ bool m_fp_is_cfa;
+ typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
+ RegisterValueMap m_register_values;
+ PushedRegisterToAddrMap m_pushed_regs;
+
+ // While processing the instruction stream, we need to communicate some state
+ // change
+ // information up to the higher level loop that makes decisions about how to
+ // push
+ // the unwind instructions for the UnwindPlan we're constructing.
+
+ // The instruction we're processing updated the UnwindPlan::Row contents
+ bool m_curr_row_modified;
+ // The instruction is branching forward with the given offset. 0 value means
+ // no branching.
+ uint32_t m_forward_branch_offset;
};
#endif // liblldb_UnwindAssemblyInstEmulation_h_
diff --git a/source/Plugins/UnwindAssembly/x86/CMakeLists.txt b/source/Plugins/UnwindAssembly/x86/CMakeLists.txt
index 6ae63891bcc3..024b0dab2e2b 100644
--- a/source/Plugins/UnwindAssembly/x86/CMakeLists.txt
+++ b/source/Plugins/UnwindAssembly/x86/CMakeLists.txt
@@ -1,3 +1,4 @@
add_lldb_library(lldbPluginUnwindAssemblyX86
UnwindAssembly-x86.cpp
+ x86AssemblyInspectionEngine.cpp
)
diff --git a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index 76f0b48d69e9..e298b856d395 100644
--- a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -8,1553 +8,272 @@
//===----------------------------------------------------------------------===//
#include "UnwindAssembly-x86.h"
+#include "x86AssemblyInspectionEngine.h"
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/TargetSelect.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Target/UnwindAssembly.h"
#include "lldb/Utility/RegisterNumber.h"
using namespace lldb;
using namespace lldb_private;
-enum CPU
-{
- k_i386,
- k_x86_64
-};
-
-enum i386_register_numbers
-{
- k_machine_eax = 0,
- k_machine_ecx = 1,
- k_machine_edx = 2,
- k_machine_ebx = 3,
- k_machine_esp = 4,
- k_machine_ebp = 5,
- k_machine_esi = 6,
- k_machine_edi = 7,
- k_machine_eip = 8
-};
-
-enum x86_64_register_numbers
-{
- k_machine_rax = 0,
- k_machine_rcx = 1,
- k_machine_rdx = 2,
- k_machine_rbx = 3,
- k_machine_rsp = 4,
- k_machine_rbp = 5,
- k_machine_rsi = 6,
- k_machine_rdi = 7,
- k_machine_r8 = 8,
- k_machine_r9 = 9,
- k_machine_r10 = 10,
- k_machine_r11 = 11,
- k_machine_r12 = 12,
- k_machine_r13 = 13,
- k_machine_r14 = 14,
- k_machine_r15 = 15,
- k_machine_rip = 16
-};
-
-struct regmap_ent
-{
- const char *name;
- int machine_regno;
- int lldb_regno;
-};
-
-static struct regmap_ent i386_register_map[] =
-{
- {"eax", k_machine_eax, -1},
- {"ecx", k_machine_ecx, -1},
- {"edx", k_machine_edx, -1},
- {"ebx", k_machine_ebx, -1},
- {"esp", k_machine_esp, -1},
- {"ebp", k_machine_ebp, -1},
- {"esi", k_machine_esi, -1},
- {"edi", k_machine_edi, -1},
- {"eip", k_machine_eip, -1}
-};
-
-const int size_of_i386_register_map = llvm::array_lengthof (i386_register_map);
-
-static int i386_register_map_initialized = 0;
-
-static struct regmap_ent x86_64_register_map[] =
-{
- {"rax", k_machine_rax, -1},
- {"rcx", k_machine_rcx, -1},
- {"rdx", k_machine_rdx, -1},
- {"rbx", k_machine_rbx, -1},
- {"rsp", k_machine_rsp, -1},
- {"rbp", k_machine_rbp, -1},
- {"rsi", k_machine_rsi, -1},
- {"rdi", k_machine_rdi, -1},
- {"r8", k_machine_r8, -1},
- {"r9", k_machine_r9, -1},
- {"r10", k_machine_r10, -1},
- {"r11", k_machine_r11, -1},
- {"r12", k_machine_r12, -1},
- {"r13", k_machine_r13, -1},
- {"r14", k_machine_r14, -1},
- {"r15", k_machine_r15, -1},
- {"rip", k_machine_rip, -1}
-};
-
-const int size_of_x86_64_register_map = llvm::array_lengthof (x86_64_register_map);
-
-static int x86_64_register_map_initialized = 0;
-
//-----------------------------------------------------------------------------------------------
-// AssemblyParse_x86 local-file class definition & implementation functions
+// UnwindAssemblyParser_x86 method definitions
//-----------------------------------------------------------------------------------------------
-class AssemblyParse_x86
-{
-public:
-
- AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func);
-
- ~AssemblyParse_x86 ();
-
- bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan);
-
- bool augment_unwind_plan_from_call_site (AddressRange& func, UnwindPlan &unwind_plan);
-
- bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan);
+UnwindAssembly_x86::UnwindAssembly_x86(const ArchSpec &arch)
+ : lldb_private::UnwindAssembly(arch),
+ m_assembly_inspection_engine(new x86AssemblyInspectionEngine(arch)) {}
- bool find_first_non_prologue_insn (Address &address);
-
-private:
- enum { kMaxInstructionByteSize = 32 };
-
- bool nonvolatile_reg_p (int machine_regno);
- bool push_rbp_pattern_p ();
- bool push_0_pattern_p ();
- bool mov_rsp_rbp_pattern_p ();
- bool sub_rsp_pattern_p (int& amount);
- bool add_rsp_pattern_p (int& amount);
- bool lea_rsp_pattern_p (int& amount);
- bool push_reg_p (int& regno);
- bool pop_reg_p (int& regno);
- bool push_imm_pattern_p ();
- bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset);
- bool ret_pattern_p ();
- bool pop_rbp_pattern_p ();
- bool leave_pattern_p ();
- bool call_next_insn_pattern_p();
- uint32_t extract_4 (uint8_t *b);
- bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno);
- bool instruction_length (Address addr, int &length);
-
- const ExecutionContext m_exe_ctx;
-
- AddressRange m_func_bounds;
-
- Address m_cur_insn;
- uint8_t m_cur_insn_bytes[kMaxInstructionByteSize];
-
- uint32_t m_machine_ip_regnum;
- uint32_t m_machine_sp_regnum;
- uint32_t m_machine_fp_regnum;
-
- uint32_t m_lldb_ip_regnum;
- uint32_t m_lldb_sp_regnum;
- uint32_t m_lldb_fp_regnum;
-
- int m_wordsize;
- int m_cpu;
- ArchSpec m_arch;
- ::LLVMDisasmContextRef m_disasm_context;
-
- DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86);
-};
-
-AssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func) :
- m_exe_ctx (exe_ctx),
- m_func_bounds(func),
- m_cur_insn (),
- m_machine_ip_regnum (LLDB_INVALID_REGNUM),
- m_machine_sp_regnum (LLDB_INVALID_REGNUM),
- m_machine_fp_regnum (LLDB_INVALID_REGNUM),
- m_lldb_ip_regnum (LLDB_INVALID_REGNUM),
- m_lldb_sp_regnum (LLDB_INVALID_REGNUM),
- m_lldb_fp_regnum (LLDB_INVALID_REGNUM),
- m_wordsize (-1),
- m_cpu(cpu),
- m_arch(arch)
-{
- int *initialized_flag = NULL;
- if (cpu == k_i386)
- {
- m_machine_ip_regnum = k_machine_eip;
- m_machine_sp_regnum = k_machine_esp;
- m_machine_fp_regnum = k_machine_ebp;
- m_wordsize = 4;
- initialized_flag = &i386_register_map_initialized;
- }
- else
- {
- m_machine_ip_regnum = k_machine_rip;
- m_machine_sp_regnum = k_machine_rsp;
- m_machine_fp_regnum = k_machine_rbp;
- m_wordsize = 8;
- initialized_flag = &x86_64_register_map_initialized;
- }
-
- // we only look at prologue - it will be complete earlier than 512 bytes into func
- if (m_func_bounds.GetByteSize() == 0)
- m_func_bounds.SetByteSize(512);
-
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (thread && *initialized_flag == 0)
- {
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- if (reg_ctx)
- {
- struct regmap_ent *ent;
- int count, i;
- if (cpu == k_i386)
- {
- ent = i386_register_map;
- count = size_of_i386_register_map;
- }
- else
- {
- ent = x86_64_register_map;
- count = size_of_x86_64_register_map;
- }
- for (i = 0; i < count; i++, ent++)
- {
- const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name);
- if (ri)
- ent->lldb_regno = ri->kinds[eRegisterKindLLDB];
- }
- *initialized_flag = 1;
- }
- }
-
- // on initial construction we may not have a Thread so these have to remain
- // uninitialized until we can get a RegisterContext to set up the register map table
- if (*initialized_flag == 1)
- {
- uint32_t lldb_regno;
- if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno))
- 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_ip_regnum, lldb_regno))
- m_lldb_ip_regnum = lldb_regno;
- }
-
- m_disasm_context = ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- NULL);
+UnwindAssembly_x86::~UnwindAssembly_x86() {
+ delete m_assembly_inspection_engine;
}
-AssemblyParse_x86::~AssemblyParse_x86 ()
-{
- ::LLVMDisasmDispose(m_disasm_context);
-}
-
-// This function expects an x86 native register number (i.e. the bits stripped out of the
-// actual instruction), not an lldb register number.
-
-bool
-AssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
-{
- if (m_cpu == k_i386)
- {
- switch (machine_regno)
- {
- case k_machine_ebx:
- case k_machine_ebp: // not actually a nonvolatile but often treated as such by convention
- case k_machine_esi:
- case k_machine_edi:
- case k_machine_esp:
- return true;
- default:
- return false;
- }
- }
- if (m_cpu == k_x86_64)
- {
- switch (machine_regno)
- {
- case k_machine_rbx:
- case k_machine_rsp:
- case k_machine_rbp: // not actually a nonvolatile but often treated as such by convention
- case k_machine_r12:
- case k_machine_r13:
- case k_machine_r14:
- case k_machine_r15:
- return true;
- default:
- return false;
- }
- }
- return false;
-}
-
-
-// Macro to detect if this is a REX mode prefix byte.
-#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
-
-// The high bit which should be added to the source register number (the "R" bit)
-#define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2)
-
-// The high bit which should be added to the destination register number (the "B" bit)
-#define REX_W_DSTREG(opcode) ((opcode) & 0x1)
-
-// pushq %rbp [0x55]
-bool
-AssemblyParse_x86::push_rbp_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0x55)
- return true;
- return false;
-}
-
-// pushq $0 ; the first instruction in start() [0x6a 0x00]
-bool
-AssemblyParse_x86::push_0_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0x6a && *(p + 1) == 0x0)
- return true;
- return false;
-}
-
-// pushq $0
-// pushl $0
-bool
-AssemblyParse_x86::push_imm_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0x68 || *p == 0x6a)
- return true;
+bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly(
+ AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
+ if (!func.GetBaseAddress().IsValid() || func.GetByteSize() == 0)
return false;
-}
-
-// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
-// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
-bool
-AssemblyParse_x86::mov_rsp_rbp_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
- if (*(p) == 0x8b && *(p + 1) == 0xec)
- return true;
- if (*(p) == 0x89 && *(p + 1) == 0xe5)
- return true;
+ if (m_assembly_inspection_engine == nullptr)
return false;
-}
-
-// subq $0x20, %rsp
-bool
-AssemblyParse_x86::sub_rsp_pattern_p (int& amount)
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
- // 8-bit immediate operand
- if (*p == 0x83 && *(p + 1) == 0xec)
- {
- amount = (int8_t) *(p + 2);
- return true;
- }
- // 32-bit immediate operand
- if (*p == 0x81 && *(p + 1) == 0xec)
- {
- amount = (int32_t) extract_4 (p + 2);
- return true;
- }
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp.get() == nullptr)
return false;
-}
-
-// addq $0x20, %rsp
-bool
-AssemblyParse_x86::add_rsp_pattern_p (int& amount)
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
- // 8-bit immediate operand
- if (*p == 0x83 && *(p + 1) == 0xc4)
- {
- amount = (int8_t) *(p + 2);
- return true;
- }
- // 32-bit immediate operand
- if (*p == 0x81 && *(p + 1) == 0xc4)
- {
- amount = (int32_t) extract_4 (p + 2);
- return true;
- }
- return false;
-}
-
-// lea esp, [esp - 0x28]
-// lea esp, [esp + 0x28]
-bool
-AssemblyParse_x86::lea_rsp_pattern_p (int& amount)
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
-
- // Check opcode
- if (*p != 0x8d)
- return false;
-
- // 8 bit displacement
- if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0x24)
- {
- amount = (int8_t) *(p + 3);
- return true;
- }
-
- // 32 bit displacement
- if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24)
- {
- amount = (int32_t) extract_4 (p + 3);
- return true;
- }
-
+ const bool prefer_file_cache = true;
+ std::vector<uint8_t> function_text(func.GetByteSize());
+ Error error;
+ if (process_sp->GetTarget().ReadMemory(
+ func.GetBaseAddress(), prefer_file_cache, function_text.data(),
+ func.GetByteSize(), error) == func.GetByteSize()) {
+ RegisterContextSP reg_ctx(thread.GetRegisterContext());
+ m_assembly_inspection_engine->Initialize(reg_ctx);
+ return m_assembly_inspection_engine->GetNonCallSiteUnwindPlanFromAssembly(
+ function_text.data(), func.GetByteSize(), func, unwind_plan);
+ }
+ return false;
+}
+
+bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
+ AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
+ bool do_augment_unwindplan = true;
+
+ UnwindPlan::RowSP first_row = unwind_plan.GetRowForFunctionOffset(0);
+ UnwindPlan::RowSP last_row = unwind_plan.GetRowForFunctionOffset(-1);
+
+ int wordsize = 8;
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp.get() == nullptr)
return false;
-}
-// pushq %rbx
-// pushl %ebx
-bool
-AssemblyParse_x86::push_reg_p (int& regno)
-{
- uint8_t *p = m_cur_insn_bytes;
- int regno_prefix_bit = 0;
- // If we have a rex prefix byte, check to see if a B bit is set
- if (m_wordsize == 8 && *p == 0x41)
- {
- regno_prefix_bit = 1 << 3;
- p++;
- }
- if (*p >= 0x50 && *p <= 0x57)
- {
- regno = (*p - 0x50) | regno_prefix_bit;
- return true;
- }
+ wordsize = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
+
+ RegisterNumber sp_regnum(thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP);
+ RegisterNumber pc_regnum(thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+
+ // Does this UnwindPlan describe the prologue? I want to see that the CFA is
+ // set
+ // in terms of the stack pointer plus an offset, and I want to see that rip is
+ // retrieved at the CFA-wordsize.
+ // If there is no description of the prologue, don't try to augment this
+ // eh_frame
+ // unwinder code, fall back to assembly parsing instead.
+
+ if (first_row->GetCFAValue().GetValueType() !=
+ UnwindPlan::Row::CFAValue::isRegisterPlusOffset ||
+ RegisterNumber(thread, unwind_plan.GetRegisterKind(),
+ first_row->GetCFAValue().GetRegisterNumber()) !=
+ sp_regnum ||
+ first_row->GetCFAValue().GetOffset() != wordsize) {
return false;
-}
-
-// popq %rbx
-// popl %ebx
-bool
-AssemblyParse_x86::pop_reg_p (int& regno)
-{
- uint8_t *p = m_cur_insn_bytes;
- int regno_prefix_bit = 0;
- // If we have a rex prefix byte, check to see if a B bit is set
- if (m_wordsize == 8 && *p == 0x41)
- {
- regno_prefix_bit = 1 << 3;
- p++;
- }
- if (*p >= 0x58 && *p <= 0x5f)
- {
- regno = (*p - 0x58) | regno_prefix_bit;
- return true;
- }
+ }
+ UnwindPlan::Row::RegisterLocation first_row_pc_loc;
+ 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.GetOffset() != -wordsize) {
return false;
-}
-
-// popq %rbp [0x5d]
-// popl %ebp [0x5d]
-bool
-AssemblyParse_x86::pop_rbp_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- return (*p == 0x5d);
-}
-
-// leave [0xc9]
-bool
-AssemblyParse_x86::leave_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- return (*p == 0xc9);
-}
-
-// call $0 [0xe8 0x0 0x0 0x0 0x0]
-bool
-AssemblyParse_x86::call_next_insn_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- return (*p == 0xe8) && (*(p+1) == 0x0) && (*(p+2) == 0x0)
- && (*(p+3) == 0x0) && (*(p+4) == 0x0);
-}
-
-// Look for an instruction sequence storing a nonvolatile register
-// on to the stack frame.
-
-// movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
-// movl %eax, -0xc(%ebp) [0x89 0x45 0xf4]
-
-// The offset value returned in rbp_offset will be positive --
-// but it must be subtraced from the frame base register to get
-// the actual location. The positive value returned for the offset
-// is a convention used elsewhere for CFA offsets et al.
-
-bool
-AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset)
-{
- uint8_t *p = m_cur_insn_bytes;
- int src_reg_prefix_bit = 0;
- int target_reg_prefix_bit = 0;
-
- if (m_wordsize == 8 && REX_W_PREFIX_P (*p))
- {
- src_reg_prefix_bit = REX_W_SRCREG (*p) << 3;
- target_reg_prefix_bit = REX_W_DSTREG (*p) << 3;
- if (target_reg_prefix_bit == 1)
- {
- // rbp/ebp don't need a prefix bit - we know this isn't the
- // reg we care about.
- return false;
+ }
+
+ // It looks like the prologue is described.
+ // Is the epilogue described? If it is, no need to do any augmentation.
+
+ if (first_row != last_row &&
+ first_row->GetOffset() != last_row->GetOffset()) {
+ // The first & last row have the same CFA register
+ // and the same CFA offset value
+ // and the CFA register is esp/rsp (the stack pointer).
+
+ // We're checking that both of them have an unwind rule like "CFA=esp+4" or
+ // CFA+rsp+8".
+
+ if (first_row->GetCFAValue().GetValueType() ==
+ last_row->GetCFAValue().GetValueType() &&
+ first_row->GetCFAValue().GetRegisterNumber() ==
+ last_row->GetCFAValue().GetRegisterNumber() &&
+ first_row->GetCFAValue().GetOffset() ==
+ last_row->GetCFAValue().GetOffset()) {
+ // Get the register locations for eip/rip from the first & last rows.
+ // Are they both CFA plus an offset? Is it the same offset?
+
+ UnwindPlan::Row::RegisterLocation last_row_pc_loc;
+ if (last_row->GetRegisterInfo(
+ pc_regnum.GetAsKind(unwind_plan.GetRegisterKind()),
+ last_row_pc_loc)) {
+ if (last_row_pc_loc.IsAtCFAPlusOffset() &&
+ first_row_pc_loc.GetOffset() == last_row_pc_loc.GetOffset()) {
+
+ // One last sanity check: Is the unwind rule for getting the caller
+ // pc value
+ // "deref the CFA-4" or "deref the CFA-8"?
+
+ // If so, we have an UnwindPlan that already describes the epilogue
+ // and we don't need
+ // to modify it at all.
+
+ if (first_row_pc_loc.GetOffset() == -wordsize) {
+ do_augment_unwindplan = false;
+ }
}
- p++;
+ }
}
+ }
- if (*p == 0x89)
- {
- /* Mask off the 3-5 bits which indicate the destination register
- if this is a ModR/M byte. */
- int opcode_destreg_masked_out = *(p + 1) & (~0x38);
-
- /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
- and three bits between them, e.g. 01nnn101
- We're looking for a destination of ebp-disp8 or ebp-disp32. */
- int immsize;
- if (opcode_destreg_masked_out == 0x45)
- immsize = 2;
- else if (opcode_destreg_masked_out == 0x85)
- immsize = 4;
- else
- return false;
-
- int offset = 0;
- if (immsize == 2)
- offset = (int8_t) *(p + 2);
- if (immsize == 4)
- offset = (uint32_t) extract_4 (p + 2);
- if (offset > 0)
- return false;
-
- regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
- rbp_offset = offset > 0 ? offset : -offset;
- return true;
- }
- return false;
-}
-
-// ret [0xc9] or [0xc2 imm8] or [0xca imm8]
-bool
-AssemblyParse_x86::ret_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
- return true;
- return false;
-}
-
-uint32_t
-AssemblyParse_x86::extract_4 (uint8_t *b)
-{
- uint32_t v = 0;
- for (int i = 3; i >= 0; i--)
- v = (v << 8) | b[i];
- return v;
-}
-
-bool
-AssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno)
-{
- struct regmap_ent *ent;
- int count, i;
- if (m_cpu == k_i386)
- {
- ent = i386_register_map;
- count = size_of_i386_register_map;
- }
- else
- {
- ent = x86_64_register_map;
- count = size_of_x86_64_register_map;
- }
- for (i = 0; i < count; i++, ent++)
- {
- if (ent->machine_regno == machine_regno)
- if (ent->lldb_regno != -1)
- {
- lldb_regno = ent->lldb_regno;
- return true;
- }
- }
- return false;
-}
-
-bool
-AssemblyParse_x86::instruction_length (Address addr, int &length)
-{
- const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
- llvm::SmallVector <uint8_t, 32> opcode_data;
- opcode_data.resize (max_op_byte_size);
-
- if (!addr.IsValid())
- return false;
-
+ if (do_augment_unwindplan) {
+ if (!func.GetBaseAddress().IsValid() || func.GetByteSize() == 0)
+ return false;
+ if (m_assembly_inspection_engine == nullptr)
+ return false;
const bool prefer_file_cache = true;
+ std::vector<uint8_t> function_text(func.GetByteSize());
Error error;
- Target *target = m_exe_ctx.GetTargetPtr();
- if (target->ReadMemory (addr, prefer_file_cache, opcode_data.data(),
- max_op_byte_size, error) == static_cast<size_t>(-1))
- {
- return false;
+ if (process_sp->GetTarget().ReadMemory(
+ func.GetBaseAddress(), prefer_file_cache, function_text.data(),
+ func.GetByteSize(), error) == func.GetByteSize()) {
+ RegisterContextSP reg_ctx(thread.GetRegisterContext());
+ m_assembly_inspection_engine->Initialize(reg_ctx);
+ return m_assembly_inspection_engine->AugmentUnwindPlanFromCallSite(
+ function_text.data(), func.GetByteSize(), func, unwind_plan, reg_ctx);
}
+ }
- char out_string[512];
- const addr_t pc = addr.GetFileAddress();
- const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context,
- opcode_data.data(),
- max_op_byte_size,
- pc, // PC value
- out_string,
- sizeof(out_string));
-
- length = inst_size;
- return true;
+ return false;
}
+bool UnwindAssembly_x86::GetFastUnwindPlan(AddressRange &func, Thread &thread,
+ UnwindPlan &unwind_plan) {
+ // if prologue is
+ // 55 pushl %ebp
+ // 89 e5 movl %esp, %ebp
+ // or
+ // 55 pushq %rbp
+ // 48 89 e5 movq %rsp, %rbp
-bool
-AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
-{
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- m_cur_insn = m_func_bounds.GetBaseAddress ();
- addr_t current_func_text_offset = 0;
- int current_sp_bytes_offset_from_cfa = 0;
- UnwindPlan::Row::RegisterLocation initial_regloc;
- Error error;
-
- if (!m_cur_insn.IsValid())
- {
- return false;
- }
-
- unwind_plan.SetPlanValidAddressRange (m_func_bounds);
- unwind_plan.SetRegisterKind (eRegisterKindLLDB);
-
- // At the start of the function, find the CFA by adding wordsize to the SP register
- row->SetOffset (current_func_text_offset);
- row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
-
- // caller's stack pointer value before the call insn is the CFA address
- initial_regloc.SetIsCFAPlusOffset (0);
- 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);
- row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
+ // We should pull in the ABI architecture default unwind plan and return that
- unwind_plan.AppendRow (row);
-
- // Allocate a new Row, populate it with the existing Row contents.
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- // Track which registers have been saved so far in the prologue.
- // If we see another push of that register, it's not part of the prologue.
- // The register numbers used here are the machine register #'s
- // (i386_register_numbers, x86_64_register_numbers).
- std::vector<bool> saved_registers(32, false);
+ llvm::SmallVector<uint8_t, 4> opcode_data;
+ ProcessSP process_sp = thread.GetProcess();
+ if (process_sp) {
+ Target &target(process_sp->GetTarget());
const bool prefer_file_cache = true;
-
- // Once the prologue has completed we'll save a copy of the unwind instructions
- // If there is an epilogue in the middle of the function, after that epilogue we'll reinstate
- // the unwind setup -- we assume that some code path jumps over the mid-function epilogue
-
- 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
- std::vector<bool> prologue_completed_saved_registers;
-
- Target *target = m_exe_ctx.GetTargetPtr();
- while (m_func_bounds.ContainsFileAddress (m_cur_insn))
- {
- int stack_offset, insn_len;
- int machine_regno; // register numbers masked directly out of instructions
- uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB numbering scheme
-
- bool in_epilogue = false; // we're in the middle of an epilogue sequence
- bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
-
- if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize)
- {
- // An unrecognized/junk instruction
- break;
- }
-
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- insn_len, error) == static_cast<size_t>(-1))
- {
- // Error reading the instruction out of the file, stop scanning
- 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;
- }
-
- else if (mov_rsp_rbp_pattern_p ())
- {
- row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
- row_updated = true;
- }
-
- // 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 --
- // normally the saved pc value is already on the stack by the time the function starts executing.
- else if (push_0_pattern_p ())
- {
- }
-
- else if (push_reg_p (machine_regno))
- {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- // the PUSH instruction has moved the stack pointer - if the CFA is set in terms of the stack pointer,
- // we need to add a new row of instructions.
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
- 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)
- {
- UnwindPlan::Row::RegisterLocation regloc;
- regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
- row->SetRegisterInfo (lldb_regno, regloc);
- saved_registers[machine_regno] = true;
- row_updated = true;
- }
- }
-
- else if (pop_reg_p (machine_regno))
- {
- current_sp_bytes_offset_from_cfa -= 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] = false;
- row->RemoveRegisterInfo (lldb_regno);
-
- if (machine_regno == (int)m_machine_fp_regnum)
- {
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
- }
-
- in_epilogue = true;
- row_updated = true;
- }
-
- // the POP instruction has moved the stack pointer - if the CFA is set in terms of the stack pointer,
- // we need to add a new row of instructions.
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
- row_updated = true;
- }
- }
-
- // The LEAVE instruction moves the value from rbp into rsp and pops
- // a value off the stack into rbp (restoring the caller's rbp value).
- // It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
- else if (leave_pattern_p ())
- {
- // We're going to copy the value in rbp into rsp, so re-set the sp offset
- // based on the CFAValue. Also, adjust it to recognize that we're popping
- // the saved rbp value off the stack.
- 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);
-
- 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] = 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 - 96.
- regloc.SetAtCFAPlusOffset (-(stack_offset + row->GetCFAValue().GetOffset()));
-
- row->SetRegisterInfo (lldb_regno, regloc);
-
- row_updated = true;
- }
-
- 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);
- 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);
- row_updated = true;
- }
- in_epilogue = 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);
- row_updated = true;
- }
- if (stack_offset > 0)
- in_epilogue = true;
- }
-
- else if (ret_pattern_p () && prologue_completed_row.get())
- {
- // Reinstate the saved prologue setup for any instructions
- // that come after the ret instruction
-
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *prologue_completed_row.get();
- row.reset (newrow);
- current_sp_bytes_offset_from_cfa = prologue_completed_sp_bytes_offset_from_cfa;
-
- saved_registers.clear();
- saved_registers.resize(prologue_completed_saved_registers.size(), false);
- for (size_t i = 0; i < prologue_completed_saved_registers.size(); ++i)
- {
- saved_registers[i] = prologue_completed_saved_registers[i];
- }
-
- in_epilogue = true;
- row_updated = true;
- }
-
- // call next instruction
- // call 0
- // => pop %ebx
- // 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);
- row_updated = true;
- }
- }
-
- if (row_updated)
- {
- if (current_func_text_offset + insn_len < m_func_bounds.GetByteSize())
- {
- row->SetOffset (current_func_text_offset + insn_len);
- unwind_plan.AppendRow (row);
- // Allocate a new Row, populate it with the existing Row contents.
- newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
- }
- }
-
- if (in_epilogue == false && row_updated)
- {
- // If we're not in an epilogue sequence, save the updated Row
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- prologue_completed_row.reset (newrow);
-
- prologue_completed_saved_registers.clear();
- prologue_completed_saved_registers.resize(saved_registers.size(), false);
- for (size_t i = 0; i < saved_registers.size(); ++i)
- {
- prologue_completed_saved_registers[i] = saved_registers[i];
- }
- }
-
- // We may change the sp value without adding a new Row necessarily -- keep
- // track of it either way.
- if (in_epilogue == false)
- {
- prologue_completed_sp_bytes_offset_from_cfa = current_sp_bytes_offset_from_cfa;
- }
-
- m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
- current_func_text_offset += insn_len;
- }
-
- unwind_plan.SetSourceName ("assembly insn profiling");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
-
- return true;
-}
-
-bool
-AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, UnwindPlan &unwind_plan)
-{
- // Is func address valid?
- Address addr_start = func.GetBaseAddress();
- if (!addr_start.IsValid())
- return false;
-
- // Is original unwind_plan valid?
- // unwind_plan should have at least one row which is ABI-default (CFA register is sp),
- // and another row in mid-function.
- if (unwind_plan.GetRowCount() < 2)
- return false;
- UnwindPlan::RowSP first_row = unwind_plan.GetRowAtIndex (0);
- if (first_row->GetOffset() != 0)
- return false;
- uint32_t cfa_reg = m_exe_ctx.GetThreadPtr()->GetRegisterContext()
- ->ConvertRegisterKindToRegisterNumber (unwind_plan.GetRegisterKind(),
- first_row->GetCFAValue().GetRegisterNumber());
- if (cfa_reg != m_lldb_sp_regnum || first_row->GetCFAValue().GetOffset() != m_wordsize)
- return false;
-
- UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset (-1);
-
- Target *target = m_exe_ctx.GetTargetPtr();
- m_cur_insn = func.GetBaseAddress();
- uint64_t offset = 0;
- int row_id = 1;
- bool unwind_plan_updated = false;
- UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
-
- // After a mid-function epilogue we will need to re-insert the original unwind rules
- // so unwinds work for the remainder of the function. These aren't common with clang/gcc
- // on x86 but it is possible.
- bool reinstate_unwind_state = false;
-
- while (func.ContainsFileAddress (m_cur_insn))
- {
- int insn_len;
- if (!instruction_length (m_cur_insn, insn_len)
- || insn_len == 0 || insn_len > kMaxInstructionByteSize)
- {
- // An unrecognized/junk instruction.
- break;
- }
- const bool prefer_file_cache = true;
- Error error;
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- insn_len, error) == static_cast<size_t>(-1))
- {
- // Error reading the instruction out of the file, stop scanning.
- break;
- }
-
- // Advance offsets.
- offset += insn_len;
- m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
-
- if (reinstate_unwind_state)
- {
- // that was the last instruction of this function
- if (func.ContainsFileAddress (m_cur_insn) == false)
- continue;
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row());
- *new_row = *original_last_row;
- new_row->SetOffset (offset);
- unwind_plan.AppendRow (new_row);
- row.reset (new UnwindPlan::Row());
- *row = *new_row;
- reinstate_unwind_state = false;
- unwind_plan_updated = true;
- continue;
- }
-
- // If we already have one row for this instruction, we can continue.
- while (row_id < unwind_plan.GetRowCount()
- && unwind_plan.GetRowAtIndex (row_id)->GetOffset() <= offset)
- {
- row_id++;
- }
- UnwindPlan::RowSP original_row = unwind_plan.GetRowAtIndex (row_id - 1);
- if (original_row->GetOffset() == offset)
- {
- *row = *original_row;
- continue;
- }
-
- if (row_id == 0)
- {
- // If we are here, compiler didn't generate CFI for prologue.
- // This won't happen to GCC or clang.
- // In this case, bail out directly.
- return false;
- }
-
- // Inspect the instruction to check if we need a new row for it.
- cfa_reg = m_exe_ctx.GetThreadPtr()->GetRegisterContext()
- ->ConvertRegisterKindToRegisterNumber (unwind_plan.GetRegisterKind(),
- row->GetCFAValue().GetRegisterNumber());
- if (cfa_reg == m_lldb_sp_regnum)
- {
- // CFA register is sp.
-
- // call next instruction
- // call 0
- // => pop %ebx
- if (call_next_insn_pattern_p ())
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // push/pop register
- int regno;
- if (push_reg_p (regno))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
- if (pop_reg_p (regno))
- {
- // Technically, this might be a nonvolatile register recover in epilogue.
- // We should reset RegisterInfo for the register.
- // But in practice, previous rule for the register is still valid...
- // So we ignore this case.
-
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (-m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // push imm
- if (push_imm_pattern_p ())
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (m_wordsize);
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // add/sub %rsp/%esp
- int amount;
- if (add_rsp_pattern_p (amount))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (-amount);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
- if (sub_rsp_pattern_p (amount))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (amount);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // lea %rsp, [%rsp + $offset]
- if (lea_rsp_pattern_p (amount))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (-amount);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- if (ret_pattern_p ())
- {
- reinstate_unwind_state = true;
- continue;
- }
- }
- else if (cfa_reg == m_lldb_fp_regnum)
- {
- // CFA register is fp.
-
- // The only case we care about is epilogue:
- // [0x5d] pop %rbp/%ebp
- // => [0xc3] ret
- if (pop_rbp_pattern_p () || leave_pattern_p ())
- {
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- 1, error) != static_cast<size_t>(-1)
- && ret_pattern_p ())
- {
- row->SetOffset (offset);
- row->GetCFAValue().SetIsRegisterPlusOffset (first_row->GetCFAValue().GetRegisterNumber(),
- m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- reinstate_unwind_state = true;
- continue;
- }
- }
- }
- else
- {
- // CFA register is not sp or fp.
-
- // This must be hand-written assembly.
- // Just trust eh_frame and assume we have finished.
- break;
- }
- }
-
- unwind_plan.SetPlanValidAddressRange (func);
- if (unwind_plan_updated)
- {
- std::string unwind_plan_source (unwind_plan.GetSourceName().AsCString());
- unwind_plan_source += " plus augmentation from assembly parsing";
- unwind_plan.SetSourceName (unwind_plan_source.c_str());
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
- }
- return true;
-}
-
-/* The "fast unwind plan" is valid for functions that follow the usual convention of
- using the frame pointer register (ebp, rbp), i.e. the function prologue looks like
- push %rbp [0x55]
- mov %rsp,%rbp [0x48 0x89 0xe5] (this is a 2-byte insn seq on i386)
-*/
-
-bool
-AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan)
-{
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- UnwindPlan::Row::RegisterLocation pc_reginfo;
- UnwindPlan::Row::RegisterLocation sp_reginfo;
- UnwindPlan::Row::RegisterLocation fp_reginfo;
- unwind_plan.SetRegisterKind (eRegisterKindLLDB);
-
- if (!func.GetBaseAddress().IsValid())
- return false;
-
- Target *target = m_exe_ctx.GetTargetPtr();
-
- uint8_t bytebuf[4];
Error error;
- const bool prefer_file_cache = true;
- if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf,
- sizeof (bytebuf), error) == static_cast<size_t>(-1))
- return false;
-
- uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
- uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
- int prologue_size;
-
- if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0)
- {
- prologue_size = sizeof (i386_prologue);
- }
- else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0)
- {
- prologue_size = sizeof (x86_64_prologue);
- }
- else
- {
- return false;
- }
-
- pc_reginfo.SetAtCFAPlusOffset (-m_wordsize);
- row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
-
- sp_reginfo.SetIsCFAPlusOffset (0);
- row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
-
- // Zero instructions into the function
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, m_wordsize);
- row->SetOffset (0);
- unwind_plan.AppendRow (row);
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- // push %rbp has executed - stack moved, rbp now saved
- row->GetCFAValue().IncOffset (m_wordsize);
- fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
- row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
- row->SetOffset (1);
- unwind_plan.AppendRow (row);
-
- newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- // mov %rsp, %rbp has executed
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_fp_regnum, 2 * m_wordsize);
- row->SetOffset (prologue_size); /// 3 or 4 bytes depending on arch
- unwind_plan.AppendRow (row);
-
- newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- unwind_plan.SetPlanValidAddressRange (func);
- unwind_plan.SetSourceName ("fast unwind assembly profiling");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
-}
+ if (target.ReadMemory(func.GetBaseAddress(), prefer_file_cache,
+ opcode_data.data(), 4, error) == 4) {
+ uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
+ uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
-bool
-AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
-{
- m_cur_insn = m_func_bounds.GetBaseAddress ();
- if (!m_cur_insn.IsValid())
- {
- return false;
- }
-
- const bool prefer_file_cache = true;
- Target *target = m_exe_ctx.GetTargetPtr();
- while (m_func_bounds.ContainsFileAddress (m_cur_insn))
- {
- Error error;
- int insn_len, offset, regno;
- if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0)
- {
- // An error parsing the instruction, i.e. probably data/garbage - stop scanning
- break;
- }
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- insn_len, error) == static_cast<size_t>(-1))
- {
- // Error reading the instruction out of the file, stop scanning
- break;
- }
-
- if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset)
- || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset)
- || (lea_rsp_pattern_p (offset) && offset < 0))
- {
- m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
- continue;
+ if (memcmp(opcode_data.data(), i386_push_mov, sizeof(i386_push_mov)) ==
+ 0 ||
+ memcmp(opcode_data.data(), x86_64_push_mov,
+ sizeof(x86_64_push_mov)) == 0) {
+ ABISP abi_sp = process_sp->GetABI();
+ if (abi_sp) {
+ return abi_sp->CreateDefaultUnwindPlan(unwind_plan);
}
-
- // Unknown non-prologue instruction - stop scanning
- break;
+ }
}
-
- address = m_cur_insn;
- return true;
-}
-
-
-
-
-
-
-//-----------------------------------------------------------------------------------------------
-// UnwindAssemblyParser_x86 method definitions
-//-----------------------------------------------------------------------------------------------
-
-UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
- lldb_private::UnwindAssembly(arch),
- m_cpu(cpu),
- m_arch(arch)
-{
-}
-
-
-UnwindAssembly_x86::~UnwindAssembly_x86 ()
-{
-}
-
-bool
-UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
-{
- ExecutionContext exe_ctx (thread.shared_from_this());
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
- return asm_parse.get_non_call_site_unwind_plan (unwind_plan);
+ }
+ return false;
}
-bool
-UnwindAssembly_x86::AugmentUnwindPlanFromCallSite (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
-{
- bool do_augment_unwindplan = true;
-
- UnwindPlan::RowSP first_row = unwind_plan.GetRowForFunctionOffset (0);
- UnwindPlan::RowSP last_row = unwind_plan.GetRowForFunctionOffset (-1);
-
- int wordsize = 8;
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- wordsize = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
- }
-
- RegisterNumber sp_regnum (thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- RegisterNumber pc_regnum (thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
-
- // Does this UnwindPlan describe the prologue? I want to see that the CFA is set
- // in terms of the stack pointer plus an offset, and I want to see that rip is
- // retrieved at the CFA-wordsize.
- // If there is no description of the prologue, don't try to augment this eh_frame
- // unwinder code, fall back to assembly parsing instead.
-
- if (first_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::isRegisterPlusOffset
- || RegisterNumber (thread, unwind_plan.GetRegisterKind(),
- first_row->GetCFAValue().GetRegisterNumber()) != sp_regnum
- || first_row->GetCFAValue().GetOffset() != wordsize)
- {
- return false;
- }
- UnwindPlan::Row::RegisterLocation first_row_pc_loc;
- 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.GetOffset() != -wordsize)
- {
- return false;
- }
-
-
- // It looks like the prologue is described.
- // Is the epilogue described? If it is, no need to do any augmentation.
-
- if (first_row != last_row && first_row->GetOffset() != last_row->GetOffset())
- {
- // The first & last row have the same CFA register
- // and the same CFA offset value
- // and the CFA register is esp/rsp (the stack pointer).
-
- // We're checking that both of them have an unwind rule like "CFA=esp+4" or CFA+rsp+8".
-
- if (first_row->GetCFAValue().GetValueType() == last_row->GetCFAValue().GetValueType()
- && first_row->GetCFAValue().GetRegisterNumber() == last_row->GetCFAValue().GetRegisterNumber()
- && first_row->GetCFAValue().GetOffset() == last_row->GetCFAValue().GetOffset())
- {
- // Get the register locations for eip/rip from the first & last rows.
- // Are they both CFA plus an offset? Is it the same offset?
-
- UnwindPlan::Row::RegisterLocation last_row_pc_loc;
- if (last_row->GetRegisterInfo (pc_regnum.GetAsKind (unwind_plan.GetRegisterKind()), last_row_pc_loc))
- {
- if (last_row_pc_loc.IsAtCFAPlusOffset()
- && first_row_pc_loc.GetOffset() == last_row_pc_loc.GetOffset())
- {
-
- // One last sanity check: Is the unwind rule for getting the caller pc value
- // "deref the CFA-4" or "deref the CFA-8"?
+bool UnwindAssembly_x86::FirstNonPrologueInsn(
+ AddressRange &func, const ExecutionContext &exe_ctx,
+ Address &first_non_prologue_insn) {
- // If so, we have an UnwindPlan that already describes the epilogue and we don't need
- // to modify it at all.
-
- if (first_row_pc_loc.GetOffset() == -wordsize)
- {
- do_augment_unwindplan = false;
- }
- }
- }
- }
- }
-
- if (do_augment_unwindplan)
- {
- ExecutionContext exe_ctx (thread.shared_from_this());
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
- return asm_parse.augment_unwind_plan_from_call_site (func, unwind_plan);
- }
-
+ if (!func.GetBaseAddress().IsValid())
return false;
-}
-
-bool
-UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
-{
- // if prologue is
- // 55 pushl %ebp
- // 89 e5 movl %esp, %ebp
- // or
- // 55 pushq %rbp
- // 48 89 e5 movq %rsp, %rbp
-
- // We should pull in the ABI architecture default unwind plan and return that
- llvm::SmallVector <uint8_t, 4> opcode_data;
-
- ProcessSP process_sp = thread.GetProcess();
- if (process_sp)
- {
- Target &target (process_sp->GetTarget());
- const bool prefer_file_cache = true;
- Error error;
- if (target.ReadMemory (func.GetBaseAddress (), prefer_file_cache, opcode_data.data(),
- 4, error) == 4)
- {
- uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
- uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target == nullptr)
+ return false;
- if (memcmp (opcode_data.data(), i386_push_mov, sizeof (i386_push_mov)) == 0
- || memcmp (opcode_data.data(), x86_64_push_mov, sizeof (x86_64_push_mov)) == 0)
- {
- ABISP abi_sp = process_sp->GetABI();
- if (abi_sp)
- {
- return abi_sp->CreateDefaultUnwindPlan (unwind_plan);
- }
- }
- }
- }
+ if (m_assembly_inspection_engine == nullptr)
return false;
-}
-bool
-UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn)
-{
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
- return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn);
+ const bool prefer_file_cache = true;
+ std::vector<uint8_t> function_text(func.GetByteSize());
+ Error error;
+ if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache,
+ function_text.data(), func.GetByteSize(),
+ error) == func.GetByteSize()) {
+ size_t offset;
+ if (m_assembly_inspection_engine->FindFirstNonPrologueInstruction(
+ function_text.data(), func.GetByteSize(), offset)) {
+ first_non_prologue_insn = func.GetBaseAddress();
+ first_non_prologue_insn.Slide(offset);
+ }
+ return true;
+ }
+ return false;
}
-UnwindAssembly *
-UnwindAssembly_x86::CreateInstance (const ArchSpec &arch)
-{
- const llvm::Triple::ArchType cpu = arch.GetMachine ();
- if (cpu == llvm::Triple::x86)
- return new UnwindAssembly_x86 (arch, k_i386);
- else if (cpu == llvm::Triple::x86_64)
- return new UnwindAssembly_x86 (arch, k_x86_64);
- return NULL;
+UnwindAssembly *UnwindAssembly_x86::CreateInstance(const ArchSpec &arch) {
+ const llvm::Triple::ArchType cpu = arch.GetMachine();
+ if (cpu == llvm::Triple::x86 || cpu == llvm::Triple::x86_64)
+ return new UnwindAssembly_x86(arch);
+ return NULL;
}
-
//------------------------------------------------------------------
// PluginInterface protocol in UnwindAssemblyParser_x86
//------------------------------------------------------------------
-ConstString
-UnwindAssembly_x86::GetPluginName()
-{
- return GetPluginNameStatic();
+ConstString UnwindAssembly_x86::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t UnwindAssembly_x86::GetPluginVersion() { return 1; }
-uint32_t
-UnwindAssembly_x86::GetPluginVersion()
-{
- return 1;
-}
-
-void
-UnwindAssembly_x86::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void UnwindAssembly_x86::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-UnwindAssembly_x86::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void UnwindAssembly_x86::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-UnwindAssembly_x86::GetPluginNameStatic()
-{
- static ConstString g_name("x86");
- return g_name;
+lldb_private::ConstString UnwindAssembly_x86::GetPluginNameStatic() {
+ static ConstString g_name("x86");
+ return g_name;
}
-const char *
-UnwindAssembly_x86::GetPluginDescriptionStatic()
-{
- return "i386 and x86_64 assembly language profiler plugin.";
+const char *UnwindAssembly_x86::GetPluginDescriptionStatic() {
+ return "i386 and x86_64 assembly language profiler plugin.";
}
diff --git a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
index 4d43a6e02b73..2beaa4a6510a 100644
--- a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
+++ b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
@@ -13,67 +13,60 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "llvm-c/Disassembler.h"
+#include "x86AssemblyInspectionEngine.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/lldb-private.h"
-class UnwindAssembly_x86 : public lldb_private::UnwindAssembly
-{
+class UnwindAssembly_x86 : public lldb_private::UnwindAssembly {
public:
- ~UnwindAssembly_x86() override;
-
- bool
- GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- AugmentUnwindPlanFromCallSite(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- GetFastUnwindPlan(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan &unwind_plan) override;
-
- // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
- bool
- FirstNonPrologueInsn(lldb_private::AddressRange& func,
- const lldb_private::ExecutionContext &exe_ctx,
- lldb_private::Address& first_non_prologue_insn) override;
-
- static lldb_private::UnwindAssembly *
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
+ ~UnwindAssembly_x86() override;
+
+ bool GetNonCallSiteUnwindPlanFromAssembly(
+ lldb_private::AddressRange &func, lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool
+ AugmentUnwindPlanFromCallSite(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool GetFastUnwindPlan(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ // thread may be NULL in which case we only use the Target (e.g. if this is
+ // called pre-process-launch).
+ bool
+ FirstNonPrologueInsn(lldb_private::AddressRange &func,
+ const lldb_private::ExecutionContext &exe_ctx,
+ lldb_private::Address &first_non_prologue_insn) override;
+
+ static lldb_private::UnwindAssembly *
+ CreateInstance(const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
private:
- UnwindAssembly_x86 (const lldb_private::ArchSpec &arch, int cpu);
+ UnwindAssembly_x86(const lldb_private::ArchSpec &arch);
+
+ lldb_private::ArchSpec m_arch;
- int m_cpu;
- lldb_private::ArchSpec m_arch;
+ lldb_private::x86AssemblyInspectionEngine *m_assembly_inspection_engine;
};
#endif // liblldb_UnwindAssembly_x86_h_
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
new file mode 100644
index 000000000000..e731a5a02ab0
--- /dev/null
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -0,0 +1,1203 @@
+//===-- x86AssemblyInspectionEngine.cpp -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "x86AssemblyInspectionEngine.h"
+
+#include "llvm-c/Disassembler.h"
+
+#include "lldb/Core/Address.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/UnwindAssembly.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+x86AssemblyInspectionEngine::x86AssemblyInspectionEngine(const ArchSpec &arch)
+ : m_cur_insn(nullptr), m_machine_ip_regnum(LLDB_INVALID_REGNUM),
+ m_machine_sp_regnum(LLDB_INVALID_REGNUM),
+ m_machine_fp_regnum(LLDB_INVALID_REGNUM),
+ m_lldb_ip_regnum(LLDB_INVALID_REGNUM),
+ m_lldb_sp_regnum(LLDB_INVALID_REGNUM),
+ m_lldb_fp_regnum(LLDB_INVALID_REGNUM),
+
+ m_reg_map(), m_arch(arch), m_cpu(k_cpu_unspecified), m_wordsize(-1),
+ m_register_map_initialized(false), m_disasm_context() {
+ m_disasm_context =
+ ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(), nullptr,
+ /*TagType=*/1, nullptr, nullptr);
+}
+
+x86AssemblyInspectionEngine::~x86AssemblyInspectionEngine() {
+ ::LLVMDisasmDispose(m_disasm_context);
+}
+
+void x86AssemblyInspectionEngine::Initialize(RegisterContextSP &reg_ctx) {
+ m_cpu = k_cpu_unspecified;
+ m_wordsize = -1;
+ m_register_map_initialized = false;
+
+ const llvm::Triple::ArchType cpu = m_arch.GetMachine();
+ if (cpu == llvm::Triple::x86)
+ m_cpu = k_i386;
+ else if (cpu == llvm::Triple::x86_64)
+ m_cpu = k_x86_64;
+
+ if (m_cpu == k_cpu_unspecified)
+ return;
+
+ if (reg_ctx.get() == nullptr)
+ return;
+
+ if (m_cpu == k_i386) {
+ m_machine_ip_regnum = k_machine_eip;
+ m_machine_sp_regnum = k_machine_esp;
+ m_machine_fp_regnum = k_machine_ebp;
+ m_wordsize = 4;
+
+ struct lldb_reg_info reginfo;
+ reginfo.name = "eax";
+ m_reg_map[k_machine_eax] = reginfo;
+ reginfo.name = "edx";
+ m_reg_map[k_machine_edx] = reginfo;
+ reginfo.name = "esp";
+ m_reg_map[k_machine_esp] = reginfo;
+ reginfo.name = "esi";
+ m_reg_map[k_machine_esi] = reginfo;
+ reginfo.name = "eip";
+ m_reg_map[k_machine_eip] = reginfo;
+ reginfo.name = "ecx";
+ m_reg_map[k_machine_ecx] = reginfo;
+ reginfo.name = "ebx";
+ m_reg_map[k_machine_ebx] = reginfo;
+ reginfo.name = "ebp";
+ m_reg_map[k_machine_ebp] = reginfo;
+ reginfo.name = "edi";
+ m_reg_map[k_machine_edi] = reginfo;
+ } else {
+ m_machine_ip_regnum = k_machine_rip;
+ m_machine_sp_regnum = k_machine_rsp;
+ m_machine_fp_regnum = k_machine_rbp;
+ m_wordsize = 8;
+
+ struct lldb_reg_info reginfo;
+ reginfo.name = "rax";
+ m_reg_map[k_machine_rax] = reginfo;
+ reginfo.name = "rdx";
+ m_reg_map[k_machine_rdx] = reginfo;
+ reginfo.name = "rsp";
+ m_reg_map[k_machine_rsp] = reginfo;
+ reginfo.name = "rsi";
+ m_reg_map[k_machine_rsi] = reginfo;
+ reginfo.name = "r8";
+ m_reg_map[k_machine_r8] = reginfo;
+ reginfo.name = "r10";
+ m_reg_map[k_machine_r10] = reginfo;
+ reginfo.name = "r12";
+ m_reg_map[k_machine_r12] = reginfo;
+ reginfo.name = "r14";
+ m_reg_map[k_machine_r14] = reginfo;
+ reginfo.name = "rip";
+ m_reg_map[k_machine_rip] = reginfo;
+ reginfo.name = "rcx";
+ m_reg_map[k_machine_rcx] = reginfo;
+ reginfo.name = "rbx";
+ m_reg_map[k_machine_rbx] = reginfo;
+ reginfo.name = "rbp";
+ m_reg_map[k_machine_rbp] = reginfo;
+ reginfo.name = "rdi";
+ m_reg_map[k_machine_rdi] = reginfo;
+ reginfo.name = "r9";
+ m_reg_map[k_machine_r9] = reginfo;
+ reginfo.name = "r11";
+ m_reg_map[k_machine_r11] = reginfo;
+ reginfo.name = "r13";
+ m_reg_map[k_machine_r13] = reginfo;
+ reginfo.name = "r15";
+ m_reg_map[k_machine_r15] = reginfo;
+ }
+
+ for (MachineRegnumToNameAndLLDBRegnum::iterator it = m_reg_map.begin();
+ it != m_reg_map.end(); ++it) {
+ const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName(it->second.name);
+ if (ri)
+ it->second.lldb_regnum = ri->kinds[eRegisterKindLLDB];
+ }
+
+ uint32_t lldb_regno;
+ if (machine_regno_to_lldb_regno(m_machine_sp_regnum, lldb_regno))
+ 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_ip_regnum, lldb_regno))
+ m_lldb_ip_regnum = lldb_regno;
+
+ m_register_map_initialized = true;
+}
+
+void x86AssemblyInspectionEngine::Initialize(
+ std::vector<lldb_reg_info> &reg_info) {
+ m_cpu = k_cpu_unspecified;
+ m_wordsize = -1;
+ m_register_map_initialized = false;
+
+ const llvm::Triple::ArchType cpu = m_arch.GetMachine();
+ if (cpu == llvm::Triple::x86)
+ m_cpu = k_i386;
+ else if (cpu == llvm::Triple::x86_64)
+ m_cpu = k_x86_64;
+
+ if (m_cpu == k_cpu_unspecified)
+ return;
+
+ if (m_cpu == k_i386) {
+ m_machine_ip_regnum = k_machine_eip;
+ m_machine_sp_regnum = k_machine_esp;
+ m_machine_fp_regnum = k_machine_ebp;
+ m_wordsize = 4;
+
+ struct lldb_reg_info reginfo;
+ reginfo.name = "eax";
+ m_reg_map[k_machine_eax] = reginfo;
+ reginfo.name = "edx";
+ m_reg_map[k_machine_edx] = reginfo;
+ reginfo.name = "esp";
+ m_reg_map[k_machine_esp] = reginfo;
+ reginfo.name = "esi";
+ m_reg_map[k_machine_esi] = reginfo;
+ reginfo.name = "eip";
+ m_reg_map[k_machine_eip] = reginfo;
+ reginfo.name = "ecx";
+ m_reg_map[k_machine_ecx] = reginfo;
+ reginfo.name = "ebx";
+ m_reg_map[k_machine_ebx] = reginfo;
+ reginfo.name = "ebp";
+ m_reg_map[k_machine_ebp] = reginfo;
+ reginfo.name = "edi";
+ m_reg_map[k_machine_edi] = reginfo;
+ } else {
+ m_machine_ip_regnum = k_machine_rip;
+ m_machine_sp_regnum = k_machine_rsp;
+ m_machine_fp_regnum = k_machine_rbp;
+ m_wordsize = 8;
+
+ struct lldb_reg_info reginfo;
+ reginfo.name = "rax";
+ m_reg_map[k_machine_rax] = reginfo;
+ reginfo.name = "rdx";
+ m_reg_map[k_machine_rdx] = reginfo;
+ reginfo.name = "rsp";
+ m_reg_map[k_machine_rsp] = reginfo;
+ reginfo.name = "rsi";
+ m_reg_map[k_machine_rsi] = reginfo;
+ reginfo.name = "r8";
+ m_reg_map[k_machine_r8] = reginfo;
+ reginfo.name = "r10";
+ m_reg_map[k_machine_r10] = reginfo;
+ reginfo.name = "r12";
+ m_reg_map[k_machine_r12] = reginfo;
+ reginfo.name = "r14";
+ m_reg_map[k_machine_r14] = reginfo;
+ reginfo.name = "rip";
+ m_reg_map[k_machine_rip] = reginfo;
+ reginfo.name = "rcx";
+ m_reg_map[k_machine_rcx] = reginfo;
+ reginfo.name = "rbx";
+ m_reg_map[k_machine_rbx] = reginfo;
+ reginfo.name = "rbp";
+ m_reg_map[k_machine_rbp] = reginfo;
+ reginfo.name = "rdi";
+ m_reg_map[k_machine_rdi] = reginfo;
+ reginfo.name = "r9";
+ m_reg_map[k_machine_r9] = reginfo;
+ reginfo.name = "r11";
+ m_reg_map[k_machine_r11] = reginfo;
+ reginfo.name = "r13";
+ m_reg_map[k_machine_r13] = reginfo;
+ reginfo.name = "r15";
+ m_reg_map[k_machine_r15] = reginfo;
+ }
+
+ for (MachineRegnumToNameAndLLDBRegnum::iterator it = m_reg_map.begin();
+ it != m_reg_map.end(); ++it) {
+ for (size_t i = 0; i < reg_info.size(); ++i) {
+ if (::strcmp(reg_info[i].name, it->second.name) == 0) {
+ it->second.lldb_regnum = reg_info[i].lldb_regnum;
+ break;
+ }
+ }
+ }
+
+ uint32_t lldb_regno;
+ if (machine_regno_to_lldb_regno(m_machine_sp_regnum, lldb_regno))
+ 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_ip_regnum, lldb_regno))
+ m_lldb_ip_regnum = lldb_regno;
+
+ m_register_map_initialized = true;
+}
+
+// This function expects an x86 native register number (i.e. the bits stripped
+// out of the
+// actual instruction), not an lldb register number.
+//
+// FIXME: This is ABI dependent, it shouldn't be hardcoded here.
+
+bool x86AssemblyInspectionEngine::nonvolatile_reg_p(int machine_regno) {
+ if (m_cpu == k_i386) {
+ switch (machine_regno) {
+ case k_machine_ebx:
+ case k_machine_ebp: // not actually a nonvolatile but often treated as such
+ // by convention
+ case k_machine_esi:
+ case k_machine_edi:
+ case k_machine_esp:
+ return true;
+ default:
+ return false;
+ }
+ }
+ if (m_cpu == k_x86_64) {
+ switch (machine_regno) {
+ case k_machine_rbx:
+ case k_machine_rsp:
+ case k_machine_rbp: // not actually a nonvolatile but often treated as such
+ // by convention
+ case k_machine_r12:
+ case k_machine_r13:
+ case k_machine_r14:
+ case k_machine_r15:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+// Macro to detect if this is a REX mode prefix byte.
+#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
+
+// The high bit which should be added to the source register number (the "R"
+// bit)
+#define REX_W_SRCREG(opcode) (((opcode)&0x4) >> 2)
+
+// The high bit which should be added to the destination register number (the
+// "B" bit)
+#define REX_W_DSTREG(opcode) ((opcode)&0x1)
+
+// pushq %rbp [0x55]
+bool x86AssemblyInspectionEngine::push_rbp_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ if (*p == 0x55)
+ return true;
+ return false;
+}
+
+// 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;
+}
+
+// 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;
+}
+
+// pushl imm8(%esp)
+//
+// e.g. 0xff 0x74 0x24 0x20 - 'pushl 0x20(%esp)'
+// (same byte pattern for 'pushq 0x20(%rsp)' in an x86_64 program)
+//
+// 0xff (with opcode bits '6' in next byte, PUSH r/m32)
+// 0x74 (ModR/M byte with three bits used to specify the opcode)
+// mod == b01, opcode == b110, R/M == b100
+// "+disp8"
+// 0x24 (SIB byte - scaled index = 0, r32 == esp)
+// 0x20 imm8 value
+
+bool x86AssemblyInspectionEngine::push_extended_pattern_p() {
+ if (*m_cur_insn == 0xff) {
+ // Get the 3 opcode bits from the ModR/M byte
+ uint8_t opcode = (*(m_cur_insn + 1) >> 3) & 7;
+ if (opcode == 6) {
+ // I'm only looking for 0xff /6 here - I
+ // don't really care what value is being pushed,
+ // just that we're pushing a 32/64 bit value on
+ // to the stack is enough.
+ return true;
+ }
+ }
+ return false;
+}
+
+// instructions only valid in 32-bit mode:
+// 0x0e - push cs
+// 0x16 - push ss
+// 0x1e - push ds
+// 0x06 - push es
+bool x86AssemblyInspectionEngine::push_misc_reg_p() {
+ uint8_t p = *m_cur_insn;
+ if (m_wordsize == 4) {
+ if (p == 0x0e || p == 0x16 || p == 0x1e || p == 0x06)
+ return true;
+ }
+ return false;
+}
+
+// pushq %rbx
+// pushl %ebx
+bool x86AssemblyInspectionEngine::push_reg_p(int &regno) {
+ uint8_t *p = m_cur_insn;
+ int regno_prefix_bit = 0;
+ // If we have a rex prefix byte, check to see if a B bit is set
+ if (m_wordsize == 8 && *p == 0x41) {
+ regno_prefix_bit = 1 << 3;
+ p++;
+ }
+ if (*p >= 0x50 && *p <= 0x57) {
+ regno = (*p - 0x50) | regno_prefix_bit;
+ return true;
+ }
+ return false;
+}
+
+// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
+// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
+bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ if (*(p) == 0x8b && *(p + 1) == 0xec)
+ return true;
+ if (*(p) == 0x89 && *(p + 1) == 0xe5)
+ return true;
+ return false;
+}
+
+// subq $0x20, %rsp
+bool x86AssemblyInspectionEngine::sub_rsp_pattern_p(int &amount) {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ // 8-bit immediate operand
+ if (*p == 0x83 && *(p + 1) == 0xec) {
+ amount = (int8_t) * (p + 2);
+ return true;
+ }
+ // 32-bit immediate operand
+ if (*p == 0x81 && *(p + 1) == 0xec) {
+ amount = (int32_t)extract_4(p + 2);
+ return true;
+ }
+ return false;
+}
+
+// addq $0x20, %rsp
+bool x86AssemblyInspectionEngine::add_rsp_pattern_p(int &amount) {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ // 8-bit immediate operand
+ if (*p == 0x83 && *(p + 1) == 0xc4) {
+ amount = (int8_t) * (p + 2);
+ return true;
+ }
+ // 32-bit immediate operand
+ if (*p == 0x81 && *(p + 1) == 0xc4) {
+ amount = (int32_t)extract_4(p + 2);
+ return true;
+ }
+ return false;
+}
+
+// lea esp, [esp - 0x28]
+// lea esp, [esp + 0x28]
+bool x86AssemblyInspectionEngine::lea_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;
+
+ // 8 bit displacement
+ if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0x24) {
+ amount = (int8_t) * (p + 3);
+ return true;
+ }
+
+ // 32 bit displacement
+ if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24) {
+ amount = (int32_t)extract_4(p + 3);
+ return true;
+ }
+
+ return false;
+}
+
+// popq %rbx
+// popl %ebx
+bool x86AssemblyInspectionEngine::pop_reg_p(int &regno) {
+ uint8_t *p = m_cur_insn;
+ int regno_prefix_bit = 0;
+ // If we have a rex prefix byte, check to see if a B bit is set
+ if (m_wordsize == 8 && *p == 0x41) {
+ regno_prefix_bit = 1 << 3;
+ p++;
+ }
+ if (*p >= 0x58 && *p <= 0x5f) {
+ regno = (*p - 0x58) | regno_prefix_bit;
+ return true;
+ }
+ return false;
+}
+
+// popq %rbp [0x5d]
+// popl %ebp [0x5d]
+bool x86AssemblyInspectionEngine::pop_rbp_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ return (*p == 0x5d);
+}
+
+// instructions valid only in 32-bit mode:
+// 0x1f - pop ds
+// 0x07 - pop es
+// 0x17 - pop ss
+bool x86AssemblyInspectionEngine::pop_misc_reg_p() {
+ uint8_t p = *m_cur_insn;
+ if (m_wordsize == 4) {
+ if (p == 0x1f || p == 0x07 || p == 0x17)
+ return true;
+ }
+ return false;
+}
+
+// leave [0xc9]
+bool x86AssemblyInspectionEngine::leave_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ return (*p == 0xc9);
+}
+
+// call $0 [0xe8 0x0 0x0 0x0 0x0]
+bool x86AssemblyInspectionEngine::call_next_insn_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ return (*p == 0xe8) && (*(p + 1) == 0x0) && (*(p + 2) == 0x0) &&
+ (*(p + 3) == 0x0) && (*(p + 4) == 0x0);
+}
+
+// Look for an instruction sequence storing a nonvolatile register
+// on to the stack frame.
+
+// movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
+// movl %eax, -0xc(%ebp) [0x89 0x45 0xf4]
+
+// The offset value returned in rbp_offset will be positive --
+// but it must be subtraced from the frame base register to get
+// the actual location. The positive value returned for the offset
+// is a convention used elsewhere for CFA offsets et al.
+
+bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p(
+ int &regno, int &rbp_offset) {
+ uint8_t *p = m_cur_insn;
+ int src_reg_prefix_bit = 0;
+ int target_reg_prefix_bit = 0;
+
+ if (m_wordsize == 8 && REX_W_PREFIX_P(*p)) {
+ src_reg_prefix_bit = REX_W_SRCREG(*p) << 3;
+ target_reg_prefix_bit = REX_W_DSTREG(*p) << 3;
+ if (target_reg_prefix_bit == 1) {
+ // rbp/ebp don't need a prefix bit - we know this isn't the
+ // reg we care about.
+ return false;
+ }
+ p++;
+ }
+
+ if (*p == 0x89) {
+ /* Mask off the 3-5 bits which indicate the destination register
+ if this is a ModR/M byte. */
+ int opcode_destreg_masked_out = *(p + 1) & (~0x38);
+
+ /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
+ and three bits between them, e.g. 01nnn101
+ We're looking for a destination of ebp-disp8 or ebp-disp32. */
+ int immsize;
+ if (opcode_destreg_masked_out == 0x45)
+ immsize = 2;
+ else if (opcode_destreg_masked_out == 0x85)
+ immsize = 4;
+ else
+ return false;
+
+ int offset = 0;
+ if (immsize == 2)
+ offset = (int8_t) * (p + 2);
+ if (immsize == 4)
+ offset = (uint32_t)extract_4(p + 2);
+ if (offset > 0)
+ return false;
+
+ regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
+ rbp_offset = offset > 0 ? offset : -offset;
+ return true;
+ }
+ return false;
+}
+
+// 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;
+}
+
+uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) {
+ uint32_t v = 0;
+ for (int i = 3; i >= 0; i--)
+ v = (v << 8) | b[i];
+ return v;
+}
+
+bool x86AssemblyInspectionEngine::instruction_length(uint8_t *insn_p,
+ int &length) {
+
+ const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
+ llvm::SmallVector<uint8_t, 32> opcode_data;
+ opcode_data.resize(max_op_byte_size);
+
+ char out_string[512];
+ const size_t inst_size =
+ ::LLVMDisasmInstruction(m_disasm_context, insn_p, max_op_byte_size, 0,
+ out_string, sizeof(out_string));
+
+ length = inst_size;
+ return true;
+}
+
+bool x86AssemblyInspectionEngine::machine_regno_to_lldb_regno(
+ int machine_regno, uint32_t &lldb_regno) {
+ MachineRegnumToNameAndLLDBRegnum::iterator it = m_reg_map.find(machine_regno);
+ if (it != m_reg_map.end()) {
+ lldb_regno = it->second.lldb_regnum;
+ return true;
+ }
+ return false;
+ return false;
+}
+
+bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
+ uint8_t *data, size_t size, AddressRange &func_range,
+ UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+
+ if (data == nullptr || size == 0)
+ return false;
+
+ if (m_register_map_initialized == false)
+ return false;
+
+ addr_t current_func_text_offset = 0;
+ int current_sp_bytes_offset_from_cfa = 0;
+ UnwindPlan::Row::RegisterLocation initial_regloc;
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ unwind_plan.SetPlanValidAddressRange(func_range);
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
+
+ // At the start of the function, find the CFA by adding wordsize to the SP
+ // register
+ row->SetOffset(current_func_text_offset);
+ row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
+
+ // caller's stack pointer value before the call insn is the CFA address
+ initial_regloc.SetIsCFAPlusOffset(0);
+ 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);
+ row->SetRegisterInfo(m_lldb_ip_regnum, initial_regloc);
+
+ unwind_plan.AppendRow(row);
+
+ // Allocate a new Row, populate it with the existing Row contents.
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ row.reset(newrow);
+
+ // Track which registers have been saved so far in the prologue.
+ // If we see another push of that register, it's not part of the prologue.
+ // The register numbers used here are the machine register #'s
+ // (i386_register_numbers, x86_64_register_numbers).
+ std::vector<bool> saved_registers(32, false);
+
+ // Once the prologue has completed we'll save a copy of the unwind
+ // instructions
+ // If there is an epilogue in the middle of the function, after that epilogue
+ // we'll reinstate
+ // the unwind setup -- we assume that some code path jumps over the
+ // mid-function epilogue
+
+ 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
+ std::vector<bool> prologue_completed_saved_registers;
+
+ while (current_func_text_offset < size) {
+ int stack_offset, insn_len;
+ int machine_regno; // register numbers masked directly out of instructions
+ uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB
+ // numbering scheme
+
+ bool in_epilogue = false; // we're in the middle of an epilogue sequence
+ bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
+
+ m_cur_insn = data + current_func_text_offset;
+ if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
+ insn_len > kMaxInstructionByteSize) {
+ // An unrecognized/junk instruction
+ 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;
+ }
+
+ else if (mov_rsp_rbp_pattern_p()) {
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
+ row_updated = true;
+ }
+
+ // 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 --
+ // normally the saved pc value is already on the stack by the time the
+ // function starts executing.
+ else if (push_0_pattern_p()) {
+ }
+
+ else if (push_reg_p(machine_regno)) {
+ current_sp_bytes_offset_from_cfa += m_wordsize;
+ // the PUSH instruction has moved the stack pointer - if the CFA is set in
+ // terms of the stack pointer,
+ // we need to add a new row of instructions.
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ 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) {
+ UnwindPlan::Row::RegisterLocation regloc;
+ regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
+ row->SetRegisterInfo(lldb_regno, regloc);
+ saved_registers[machine_regno] = true;
+ row_updated = true;
+ }
+ }
+
+ else if (pop_reg_p(machine_regno)) {
+ current_sp_bytes_offset_from_cfa -= 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] = false;
+ row->RemoveRegisterInfo(lldb_regno);
+
+ if (machine_regno == (int)m_machine_fp_regnum) {
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
+ }
+
+ in_epilogue = true;
+ row_updated = true;
+ }
+
+ // the POP instruction has moved the stack pointer - if the CFA is set in
+ // terms of the stack pointer,
+ // we need to add a new row of instructions.
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
+ 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);
+ row_updated = true;
+ }
+ }
+
+ // The LEAVE instruction moves the value from rbp into rsp and pops
+ // a value off the stack into rbp (restoring the caller's rbp value).
+ // It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
+ else if (leave_pattern_p()) {
+ // We're going to copy the value in rbp into rsp, so re-set the sp offset
+ // based on the CFAValue. Also, adjust it to recognize that we're popping
+ // the saved rbp value off the stack.
+ 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);
+
+ 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] = 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 - 96.
+ regloc.SetAtCFAPlusOffset(
+ -(stack_offset + row->GetCFAValue().GetOffset()));
+
+ row->SetRegisterInfo(lldb_regno, regloc);
+
+ row_updated = true;
+ }
+
+ 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);
+ 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);
+ row_updated = true;
+ }
+ in_epilogue = true;
+ }
+
+ 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);
+ 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);
+ row_updated = true;
+ }
+ if (stack_offset > 0)
+ in_epilogue = true;
+ }
+
+ else if (ret_pattern_p() && prologue_completed_row.get()) {
+ // Reinstate the saved prologue setup for any instructions
+ // that come after the ret instruction
+
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *prologue_completed_row.get();
+ row.reset(newrow);
+ current_sp_bytes_offset_from_cfa =
+ prologue_completed_sp_bytes_offset_from_cfa;
+
+ saved_registers.clear();
+ saved_registers.resize(prologue_completed_saved_registers.size(), false);
+ for (size_t i = 0; i < prologue_completed_saved_registers.size(); ++i) {
+ saved_registers[i] = prologue_completed_saved_registers[i];
+ }
+
+ in_epilogue = true;
+ row_updated = true;
+ }
+
+ // call next instruction
+ // call 0
+ // => pop %ebx
+ // 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);
+ row_updated = true;
+ }
+ }
+
+ if (row_updated) {
+ if (current_func_text_offset + insn_len < size) {
+ row->SetOffset(current_func_text_offset + insn_len);
+ unwind_plan.AppendRow(row);
+ // Allocate a new Row, populate it with the existing Row contents.
+ newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ row.reset(newrow);
+ }
+ }
+
+ if (in_epilogue == false && row_updated) {
+ // If we're not in an epilogue sequence, save the updated Row
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ prologue_completed_row.reset(newrow);
+
+ prologue_completed_saved_registers.clear();
+ prologue_completed_saved_registers.resize(saved_registers.size(), false);
+ for (size_t i = 0; i < saved_registers.size(); ++i) {
+ prologue_completed_saved_registers[i] = saved_registers[i];
+ }
+ }
+
+ // We may change the sp value without adding a new Row necessarily -- keep
+ // track of it either way.
+ if (in_epilogue == false) {
+ prologue_completed_sp_bytes_offset_from_cfa =
+ current_sp_bytes_offset_from_cfa;
+ }
+
+ m_cur_insn = m_cur_insn + insn_len;
+ current_func_text_offset += insn_len;
+ }
+
+ unwind_plan.SetSourceName("assembly insn profiling");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+
+ return true;
+}
+
+bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
+ uint8_t *data, size_t size, AddressRange &func_range,
+ UnwindPlan &unwind_plan, RegisterContextSP &reg_ctx) {
+ Address addr_start = func_range.GetBaseAddress();
+ if (!addr_start.IsValid())
+ return false;
+
+ // We either need a live RegisterContext, or we need the UnwindPlan to already
+ // be in the lldb register numbering scheme.
+ if (reg_ctx.get() == nullptr &&
+ unwind_plan.GetRegisterKind() != eRegisterKindLLDB)
+ return false;
+
+ // Is original unwind_plan valid?
+ // unwind_plan should have at least one row which is ABI-default (CFA register
+ // is sp),
+ // and another row in mid-function.
+ if (unwind_plan.GetRowCount() < 2)
+ return false;
+
+ UnwindPlan::RowSP first_row = unwind_plan.GetRowAtIndex(0);
+ if (first_row->GetOffset() != 0)
+ return false;
+ uint32_t cfa_reg = first_row->GetCFAValue().GetRegisterNumber();
+ if (unwind_plan.GetRegisterKind() != eRegisterKindLLDB) {
+ cfa_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ unwind_plan.GetRegisterKind(),
+ first_row->GetCFAValue().GetRegisterNumber());
+ }
+ if (cfa_reg != m_lldb_sp_regnum ||
+ first_row->GetCFAValue().GetOffset() != m_wordsize)
+ return false;
+
+ UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset(-1);
+
+ size_t offset = 0;
+ int row_id = 1;
+ bool unwind_plan_updated = false;
+ UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
+ m_cur_insn = data + offset;
+
+ // After a mid-function epilogue we will need to re-insert the original unwind
+ // rules
+ // so unwinds work for the remainder of the function. These aren't common
+ // with clang/gcc
+ // on x86 but it is possible.
+ bool reinstate_unwind_state = false;
+
+ while (offset < size) {
+ m_cur_insn = data + offset;
+ int insn_len;
+ if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
+ insn_len > kMaxInstructionByteSize) {
+ // An unrecognized/junk instruction.
+ break;
+ }
+
+ // Advance offsets.
+ offset += insn_len;
+ m_cur_insn = data + offset;
+
+ if (reinstate_unwind_state) {
+ // that was the last instruction of this function
+ if (offset >= size)
+ continue;
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row());
+ *new_row = *original_last_row;
+ new_row->SetOffset(offset);
+ unwind_plan.AppendRow(new_row);
+ row.reset(new UnwindPlan::Row());
+ *row = *new_row;
+ reinstate_unwind_state = false;
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // If we already have one row for this instruction, we can continue.
+ while (row_id < unwind_plan.GetRowCount() &&
+ unwind_plan.GetRowAtIndex(row_id)->GetOffset() <= offset) {
+ row_id++;
+ }
+ UnwindPlan::RowSP original_row = unwind_plan.GetRowAtIndex(row_id - 1);
+ if (original_row->GetOffset() == offset) {
+ *row = *original_row;
+ continue;
+ }
+
+ if (row_id == 0) {
+ // If we are here, compiler didn't generate CFI for prologue.
+ // This won't happen to GCC or clang.
+ // In this case, bail out directly.
+ return false;
+ }
+
+ // Inspect the instruction to check if we need a new row for it.
+ cfa_reg = row->GetCFAValue().GetRegisterNumber();
+ if (unwind_plan.GetRegisterKind() != eRegisterKindLLDB) {
+ cfa_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ unwind_plan.GetRegisterKind(),
+ row->GetCFAValue().GetRegisterNumber());
+ }
+ if (cfa_reg == m_lldb_sp_regnum) {
+ // CFA register is sp.
+
+ // call next instruction
+ // call 0
+ // => pop %ebx
+ if (call_next_insn_pattern_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // push/pop register
+ int regno;
+ if (push_reg_p(regno)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+ if (pop_reg_p(regno)) {
+ // Technically, this might be a nonvolatile register recover in
+ // epilogue.
+ // We should reset RegisterInfo for the register.
+ // But in practice, previous rule for the register is still valid...
+ // So we ignore this case.
+
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ if (pop_misc_reg_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // push imm
+ if (push_imm_pattern_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(m_wordsize);
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // push extended
+ if (push_extended_pattern_p() || push_misc_reg_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(m_wordsize);
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // add/sub %rsp/%esp
+ int amount;
+ if (add_rsp_pattern_p(amount)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-amount);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+ if (sub_rsp_pattern_p(amount)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(amount);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // lea %rsp, [%rsp + $offset]
+ if (lea_rsp_pattern_p(amount)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-amount);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ if (ret_pattern_p()) {
+ reinstate_unwind_state = true;
+ continue;
+ }
+ } else if (cfa_reg == m_lldb_fp_regnum) {
+ // CFA register is fp.
+
+ // The only case we care about is epilogue:
+ // [0x5d] pop %rbp/%ebp
+ // => [0xc3] ret
+ if (pop_rbp_pattern_p() || leave_pattern_p()) {
+ offset += 1;
+ row->SetOffset(offset);
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ reinstate_unwind_state = true;
+ continue;
+ }
+ } else {
+ // CFA register is not sp or fp.
+
+ // This must be hand-written assembly.
+ // Just trust eh_frame and assume we have finished.
+ break;
+ }
+ }
+
+ unwind_plan.SetPlanValidAddressRange(func_range);
+ if (unwind_plan_updated) {
+ std::string unwind_plan_source(unwind_plan.GetSourceName().AsCString());
+ unwind_plan_source += " plus augmentation from assembly parsing";
+ unwind_plan.SetSourceName(unwind_plan_source.c_str());
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ }
+ return true;
+}
+
+bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction(
+ uint8_t *data, size_t size, size_t &offset) {
+ offset = 0;
+
+ if (m_register_map_initialized == false)
+ return false;
+
+ while (offset < size) {
+ int regno;
+ int insn_len;
+ int scratch;
+
+ m_cur_insn = data + offset;
+ if (!instruction_length(m_cur_insn, insn_len) ||
+ insn_len > kMaxInstructionByteSize || insn_len == 0) {
+ // An error parsing the instruction, i.e. probably data/garbage - stop
+ // scanning
+ break;
+ }
+
+ if (push_rbp_pattern_p() || mov_rsp_rbp_pattern_p() ||
+ sub_rsp_pattern_p(scratch) || push_reg_p(regno) ||
+ mov_reg_to_local_stack_frame_p(regno, scratch) ||
+ (lea_rsp_pattern_p(scratch) && offset == 0)) {
+ offset += insn_len;
+ continue;
+ }
+ //
+ // Unknown non-prologue instruction - stop scanning
+ break;
+ }
+
+ return true;
+}
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
new file mode 100644
index 000000000000..0294f5a0c282
--- /dev/null
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -0,0 +1,181 @@
+//===-- x86AssemblyInspectionEngine.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_x86AssemblyInspectionEngine_h_
+#define liblldb_x86AssemblyInspectionEngine_h_
+
+#include "llvm-c/Disassembler.h"
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ConstString.h"
+
+#include <map>
+#include <vector>
+
+namespace lldb_private {
+
+// x86AssemblyInspectionEngine - a class which will take a buffer of bytes
+// of i386/x86_64 instructions and create an UnwindPlan based on those
+// assembly instructions.
+class x86AssemblyInspectionEngine {
+
+public:
+ /// default ctor
+ x86AssemblyInspectionEngine(const lldb_private::ArchSpec &arch);
+
+ /// default dtor
+ ~x86AssemblyInspectionEngine();
+
+ /// One of the two initialize methods that can be called on this object;
+ /// they must be called before any of the assembly inspection methods
+ /// are called. This one should be used if the caller has access to a
+ /// valid RegisterContext.
+ void Initialize(lldb::RegisterContextSP &reg_ctx);
+
+ /// One of the two initialize methods that can be called on this object;
+ /// they must be called before any of the assembly inspection methods
+ /// are called. This one takes a vector of register name and lldb
+ /// register numbers.
+ struct lldb_reg_info {
+ const char *name;
+ uint32_t lldb_regnum;
+ lldb_reg_info() : name(nullptr), lldb_regnum(LLDB_INVALID_REGNUM) {}
+ };
+ void Initialize(std::vector<lldb_reg_info> &reg_info);
+
+ /// Create an UnwindPlan for a "non-call site" stack frame situation.
+ /// This is usually when this function/method is currently executing, and may
+ /// be at
+ /// a location where exception-handling style unwind information (eh_frame,
+ /// compact unwind info, arm unwind info)
+ /// are not valid.
+ /// \p data is a pointer to the instructions for the function
+ /// \p size is the size of the instruction buffer above
+ /// \p func_range is the start Address and size of the function, to be
+ /// included in the UnwindPlan
+ /// \p unwind_plan is the unwind plan that this method creates
+ /// \returns true if it was able to create an UnwindPlan; false if not.
+ bool
+ GetNonCallSiteUnwindPlanFromAssembly(uint8_t *data, size_t size,
+ lldb_private::AddressRange &func_range,
+ lldb_private::UnwindPlan &unwind_plan);
+
+ /// Take an existing UnwindPlan, probably from eh_frame which may be missing
+ /// description
+ /// of the epilogue instructions, and add the epilogue description to it based
+ /// on the
+ /// instructions in the function.
+ ///
+ /// The \p unwind_plan 's register numbers must be converted into the lldb
+ /// register numbering
+ /// scheme OR a RegisterContext must be provided in \p reg_ctx. If the \p
+ /// unwind_plan
+ /// register numbers are already in lldb register numbering, \p reg_ctx may be
+ /// null.
+ /// \returns true if the \p unwind_plan was updated, false if it was not.
+ bool AugmentUnwindPlanFromCallSite(uint8_t *data, size_t size,
+ lldb_private::AddressRange &func_range,
+ lldb_private::UnwindPlan &unwind_plan,
+ lldb::RegisterContextSP &reg_ctx);
+
+ bool FindFirstNonPrologueInstruction(uint8_t *data, size_t size,
+ size_t &offset);
+
+private:
+ bool nonvolatile_reg_p(int machine_regno);
+ bool push_rbp_pattern_p();
+ bool push_0_pattern_p();
+ bool push_imm_pattern_p();
+ bool push_extended_pattern_p();
+ bool push_misc_reg_p();
+ bool mov_rsp_rbp_pattern_p();
+ bool sub_rsp_pattern_p(int &amount);
+ bool add_rsp_pattern_p(int &amount);
+ bool lea_rsp_pattern_p(int &amount);
+ bool push_reg_p(int &regno);
+ bool pop_reg_p(int &regno);
+ bool pop_rbp_pattern_p();
+ bool pop_misc_reg_p();
+ bool leave_pattern_p();
+ bool call_next_insn_pattern_p();
+ bool mov_reg_to_local_stack_frame_p(int &regno, int &rbp_offset);
+ bool ret_pattern_p();
+ uint32_t extract_4(uint8_t *b);
+
+ bool instruction_length(uint8_t *insn, int &length);
+
+ bool machine_regno_to_lldb_regno(int machine_regno, uint32_t &lldb_regno);
+
+ enum CPU { k_i386, k_x86_64, k_cpu_unspecified };
+
+ enum i386_register_numbers {
+ k_machine_eax = 0,
+ k_machine_ecx = 1,
+ k_machine_edx = 2,
+ k_machine_ebx = 3,
+ k_machine_esp = 4,
+ k_machine_ebp = 5,
+ k_machine_esi = 6,
+ k_machine_edi = 7,
+ k_machine_eip = 8
+ };
+
+ enum x86_64_register_numbers {
+ k_machine_rax = 0,
+ k_machine_rcx = 1,
+ k_machine_rdx = 2,
+ k_machine_rbx = 3,
+ k_machine_rsp = 4,
+ k_machine_rbp = 5,
+ k_machine_rsi = 6,
+ k_machine_rdi = 7,
+ k_machine_r8 = 8,
+ k_machine_r9 = 9,
+ k_machine_r10 = 10,
+ k_machine_r11 = 11,
+ k_machine_r12 = 12,
+ k_machine_r13 = 13,
+ k_machine_r14 = 14,
+ k_machine_r15 = 15,
+ k_machine_rip = 16
+ };
+
+ enum { kMaxInstructionByteSize = 32 };
+
+ uint8_t *m_cur_insn;
+
+ uint32_t m_machine_ip_regnum;
+ uint32_t m_machine_sp_regnum;
+ uint32_t m_machine_fp_regnum;
+ uint32_t m_lldb_ip_regnum;
+ uint32_t m_lldb_sp_regnum;
+ uint32_t m_lldb_fp_regnum;
+
+ typedef std::map<uint32_t, lldb_reg_info> MachineRegnumToNameAndLLDBRegnum;
+
+ MachineRegnumToNameAndLLDBRegnum m_reg_map;
+
+ lldb_private::ArchSpec m_arch;
+ CPU m_cpu;
+ int m_wordsize;
+
+ bool m_register_map_initialized;
+
+ ::LLVMDisasmContextRef m_disasm_context;
+
+ DISALLOW_COPY_AND_ASSIGN(x86AssemblyInspectionEngine);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_x86AssemblyInspectionEngine_h_